Version 2.12.0-106.0.dev

Merge commit '1bfcc2d8da7a5a5f8f5a41dcb346ea1ddbd4191d' into 'dev'
diff --git a/.dart_tool/package_config.json b/.dart_tool/package_config.json
index f616daa..9ecfe27 100644
--- a/.dart_tool/package_config.json
+++ b/.dart_tool/package_config.json
@@ -11,14 +11,14 @@
     "constraint, update this by running tools/generate_package_config.dart."
   ],
   "configVersion": 2,
-  "generated": "2020-11-15T14:18:10.587065",
+  "generated": "2020-11-30T16:23:50.740805",
   "generator": "tools/generate_package_config.dart",
   "packages": [
     {
       "name": "_fe_analyzer_shared",
       "rootUri": "../pkg/_fe_analyzer_shared",
       "packageUri": "lib/",
-      "languageVersion": "2.2"
+      "languageVersion": "2.6"
     },
     {
       "name": "_fe_analyzer_shared_assigned_variables",
@@ -101,7 +101,7 @@
       "name": "args",
       "rootUri": "../third_party/pkg/args",
       "packageUri": "lib/",
-      "languageVersion": "2.3"
+      "languageVersion": "2.12"
     },
     {
       "name": "async",
diff --git a/CHANGELOG.md b/CHANGELOG.md
index b7199e2..b0d0877 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -25,6 +25,11 @@
   constructors, a name which can be associated with the port and displayed in
   tooling.
 
+#### `dart:collection`
+
+* `LinkedList` made it explicit that elements are compared by identity,
+  and updated `contains` to take advantage of this.
+
 ### Dart VM
 
 *   **Breaking Change** [#42312][]: `Dart_WeakPersistentHandle`s will no longer
diff --git a/DEPS b/DEPS
index a5eac9a..7ca29d6 100644
--- a/DEPS
+++ b/DEPS
@@ -68,7 +68,7 @@
   "gperftools_revision": "180bfa10d7cb38e8b3784d60943d50e8fcef0dcb",
 
   # Revisions of /third_party/* dependencies.
-  "args_tag": "1.6.0",
+  "args_rev": "139140125126661fac88c9aa5882165936d01c91",
   "async_rev": "695b3ac280f107c84adf7488743abfdfaaeea68f",
   "bazel_worker_rev": "060c55a933d39798681a4f533b161b81dc48d77e",
   "benchmark_harness_rev": "ec6b646f5443faa871e126ac1ba248c94ca06257",
@@ -301,7 +301,7 @@
       "@" + Var("gperftools_revision"),
 
   Var("dart_root") + "/third_party/pkg/args":
-      Var("dart_git") + "args.git" + "@" + Var("args_tag"),
+      Var("dart_git") + "args.git" + "@" + Var("args_rev"),
   Var("dart_root") + "/third_party/pkg/async":
       Var("dart_git") + "async.git" + "@" + Var("async_rev"),
   Var("dart_root") + "/third_party/pkg/bazel_worker":
diff --git a/pkg/_fe_analyzer_shared/lib/src/base/errors.dart b/pkg/_fe_analyzer_shared/lib/src/base/errors.dart
index 322861f..2e138d8 100644
--- a/pkg/_fe_analyzer_shared/lib/src/base/errors.dart
+++ b/pkg/_fe_analyzer_shared/lib/src/base/errors.dart
@@ -16,6 +16,11 @@
    */
   final String name;
 
+  /**
+   * The unique name of this error code.
+   */
+  final String uniqueName;
+
   final String _message;
 
   final String _correction;
@@ -37,34 +42,34 @@
    * template. The correction associated with the error will be created from the
    * given [correction] template.
    */
-  const ErrorCode(this.name, String message,
-      [String correction, this.hasPublishedDocs = false])
-      : isUnresolvedIdentifier = false,
-        _message = message,
-        _correction = correction;
-
-  /**
-   * Initialize a newly created error code to have the given [name]. The message
-   * associated with the error will be created from the given [message]
-   * template. The correction associated with the error will be created from the
-   * given [correction] template.
-   */
-  const ErrorCode.temporary(this.name, String message,
-      {String correction,
-      this.isUnresolvedIdentifier = false,
-      this.hasPublishedDocs = false})
-      : _message = message,
-        _correction = correction;
-
-  const ErrorCode.temporary2({
+  const ErrorCode({
     String correction,
     this.hasPublishedDocs = false,
-    this.isUnresolvedIdentifier = false,
+    this.isUnresolvedIdentifier: false,
     @required String message,
     @required this.name,
-    @required String uniqueName,
+    @required this.uniqueName,
   })  : _correction = correction,
-        _message = message;
+        _message = message,
+        assert(hasPublishedDocs != null),
+        assert(isUnresolvedIdentifier != null);
+
+  @Deprecated('Use the default constructor')
+  const ErrorCode.temporary2({
+    String correction,
+    bool hasPublishedDocs = false,
+    bool isUnresolvedIdentifier = false,
+    @required String message,
+    @required String name,
+    @required String uniqueName,
+  }) : this(
+          correction: correction,
+          hasPublishedDocs: hasPublishedDocs,
+          isUnresolvedIdentifier: isUnresolvedIdentifier,
+          message: message,
+          name: name,
+          uniqueName: uniqueName,
+        );
 
   /**
    * The template used to create the correction to be displayed for this error,
@@ -94,11 +99,6 @@
   ErrorType get type;
 
   /**
-   * The unique name of this error code.
-   */
-  String get uniqueName => "$runtimeType.$name";
-
-  /**
    * Return a URL that can be used to access documentation for diagnostics with
    * this code, or `null` if there is no published documentation.
    */
diff --git a/pkg/_fe_analyzer_shared/lib/src/scanner/errors.dart b/pkg/_fe_analyzer_shared/lib/src/scanner/errors.dart
index 2d539c0..5e87329 100644
--- a/pkg/_fe_analyzer_shared/lib/src/scanner/errors.dart
+++ b/pkg/_fe_analyzer_shared/lib/src/scanner/errors.dart
@@ -5,94 +5,8 @@
 import '../base/errors.dart';
 import '../messages/codes.dart';
 import 'error_token.dart';
-import 'token_constants.dart';
 import 'token.dart' show Token, TokenType;
-
-/**
- * The error codes used for errors detected by the scanner.
- */
-class ScannerErrorCode extends ErrorCode {
-  /**
-   * Parameters:
-   * 0: the token that was expected but not found
-   */
-  static const ScannerErrorCode EXPECTED_TOKEN =
-      const ScannerErrorCode('EXPECTED_TOKEN', "Expected to find '{0}'.");
-
-  /**
-   * Parameters:
-   * 0: the illegal character
-   */
-  static const ScannerErrorCode ILLEGAL_CHARACTER =
-      const ScannerErrorCode('ILLEGAL_CHARACTER', "Illegal character '{0}'.");
-
-  static const ScannerErrorCode MISSING_DIGIT =
-      const ScannerErrorCode('MISSING_DIGIT', "Decimal digit expected.");
-
-  static const ScannerErrorCode MISSING_HEX_DIGIT = const ScannerErrorCode(
-      'MISSING_HEX_DIGIT', "Hexadecimal digit expected.");
-
-  static const ScannerErrorCode MISSING_IDENTIFIER =
-      const ScannerErrorCode('MISSING_IDENTIFIER', "Expected an identifier.");
-
-  static const ScannerErrorCode MISSING_QUOTE =
-      const ScannerErrorCode('MISSING_QUOTE', "Expected quote (' or \").");
-
-  /**
-   * Parameters:
-   * 0: the path of the file that cannot be read
-   */
-  static const ScannerErrorCode UNABLE_GET_CONTENT = const ScannerErrorCode(
-      'UNABLE_GET_CONTENT', "Unable to get content of '{0}'.");
-
-  static const ScannerErrorCode UNEXPECTED_DOLLAR_IN_STRING =
-      const ScannerErrorCode(
-          'UNEXPECTED_DOLLAR_IN_STRING',
-          "A '\$' has special meaning inside a string, and must be followed by "
-              "an identifier or an expression in curly braces ({}).",
-          correction: "Try adding a backslash (\\) to escape the '\$'.");
-
-  /**
-   * Parameters:
-   * 0: the unsupported operator
-   */
-  static const ScannerErrorCode UNSUPPORTED_OPERATOR = const ScannerErrorCode(
-      'UNSUPPORTED_OPERATOR', "The '{0}' operator is not supported.");
-
-  static const ScannerErrorCode UNTERMINATED_MULTI_LINE_COMMENT =
-      const ScannerErrorCode(
-          'UNTERMINATED_MULTI_LINE_COMMENT', "Unterminated multi-line comment.",
-          correction: "Try terminating the comment with '*/', or "
-              "removing any unbalanced occurrences of '/*'"
-              " (because comments nest in Dart).");
-
-  static const ScannerErrorCode UNTERMINATED_STRING_LITERAL =
-      const ScannerErrorCode(
-          'UNTERMINATED_STRING_LITERAL', "Unterminated string literal.");
-
-  /**
-   * Initialize a newly created error code to have the given [name]. The message
-   * associated with the error will be created from the given [message]
-   * template. The correction associated with the error will be created from the
-   * given [correction] template.
-   */
-  const ScannerErrorCode(String name, String message, {String correction})
-      : super.temporary(name, message, correction: correction);
-
-  @override
-  ErrorSeverity get errorSeverity => ErrorSeverity.ERROR;
-
-  @override
-  ErrorType get type => ErrorType.SYNTACTIC_ERROR;
-}
-
-/**
- * Used to report a scan error at the given offset.
- * The [errorCode] is the error code indicating the nature of the error.
- * The [arguments] are any arguments needed to complete the error message.
- */
-typedef ReportError(
-    ScannerErrorCode errorCode, int offset, List<Object> arguments);
+import 'token_constants.dart';
 
 /**
  *  Translates the given error [token] into an analyzer error and reports it
@@ -190,3 +104,94 @@
     // Otherwise keep looking.
   }
 }
+
+/**
+ * Used to report a scan error at the given offset.
+ * The [errorCode] is the error code indicating the nature of the error.
+ * The [arguments] are any arguments needed to complete the error message.
+ */
+typedef ReportError(
+    ScannerErrorCode errorCode, int offset, List<Object> arguments);
+
+/**
+ * The error codes used for errors detected by the scanner.
+ */
+class ScannerErrorCode extends ErrorCode {
+  /**
+   * Parameters:
+   * 0: the token that was expected but not found
+   */
+  static const ScannerErrorCode EXPECTED_TOKEN =
+      const ScannerErrorCode('EXPECTED_TOKEN', "Expected to find '{0}'.");
+
+  /**
+   * Parameters:
+   * 0: the illegal character
+   */
+  static const ScannerErrorCode ILLEGAL_CHARACTER =
+      const ScannerErrorCode('ILLEGAL_CHARACTER', "Illegal character '{0}'.");
+
+  static const ScannerErrorCode MISSING_DIGIT =
+      const ScannerErrorCode('MISSING_DIGIT', "Decimal digit expected.");
+
+  static const ScannerErrorCode MISSING_HEX_DIGIT = const ScannerErrorCode(
+      'MISSING_HEX_DIGIT', "Hexadecimal digit expected.");
+
+  static const ScannerErrorCode MISSING_IDENTIFIER =
+      const ScannerErrorCode('MISSING_IDENTIFIER', "Expected an identifier.");
+
+  static const ScannerErrorCode MISSING_QUOTE =
+      const ScannerErrorCode('MISSING_QUOTE', "Expected quote (' or \").");
+
+  /**
+   * Parameters:
+   * 0: the path of the file that cannot be read
+   */
+  static const ScannerErrorCode UNABLE_GET_CONTENT = const ScannerErrorCode(
+      'UNABLE_GET_CONTENT', "Unable to get content of '{0}'.");
+
+  static const ScannerErrorCode UNEXPECTED_DOLLAR_IN_STRING =
+      const ScannerErrorCode(
+          'UNEXPECTED_DOLLAR_IN_STRING',
+          "A '\$' has special meaning inside a string, and must be followed by "
+              "an identifier or an expression in curly braces ({}).",
+          correction: "Try adding a backslash (\\) to escape the '\$'.");
+
+  /**
+   * Parameters:
+   * 0: the unsupported operator
+   */
+  static const ScannerErrorCode UNSUPPORTED_OPERATOR = const ScannerErrorCode(
+      'UNSUPPORTED_OPERATOR', "The '{0}' operator is not supported.");
+
+  static const ScannerErrorCode UNTERMINATED_MULTI_LINE_COMMENT =
+      const ScannerErrorCode(
+          'UNTERMINATED_MULTI_LINE_COMMENT', "Unterminated multi-line comment.",
+          correction: "Try terminating the comment with '*/', or "
+              "removing any unbalanced occurrences of '/*'"
+              " (because comments nest in Dart).");
+
+  static const ScannerErrorCode UNTERMINATED_STRING_LITERAL =
+      const ScannerErrorCode(
+          'UNTERMINATED_STRING_LITERAL', "Unterminated string literal.");
+
+  /**
+   * Initialize a newly created error code to have the given [name]. The message
+   * associated with the error will be created from the given [message]
+   * template. The correction associated with the error will be created from the
+   * given [correction] template.
+   */
+  const ScannerErrorCode(String name, String message, {String correction})
+      : super(
+          correction: correction,
+          message: message,
+          name: name,
+          uniqueName: 'ScannerErrorCode.$name',
+        );
+
+  @override
+  ErrorSeverity get errorSeverity => ErrorSeverity.ERROR;
+
+  @override
+  ErrorType get type => ErrorType.SYNTACTIC_ERROR;
+}
diff --git a/pkg/_fe_analyzer_shared/pubspec.yaml b/pkg/_fe_analyzer_shared/pubspec.yaml
index 3ea3d4c..a62ab70 100644
--- a/pkg/_fe_analyzer_shared/pubspec.yaml
+++ b/pkg/_fe_analyzer_shared/pubspec.yaml
@@ -4,7 +4,7 @@
 homepage: https://github.com/dart-lang/sdk/tree/master/pkg/_fe_analyzer_shared
 
 environment:
-  sdk: '>=2.2.2 <3.0.0'
+  sdk: '>=2.6.0 <3.0.0'
 dependencies:
   meta: ^1.0.2
 dev_dependencies:
diff --git a/pkg/_fe_analyzer_shared/test/flow_analysis/flow_analysis_mini_ast.dart b/pkg/_fe_analyzer_shared/test/flow_analysis/flow_analysis_mini_ast.dart
new file mode 100644
index 0000000..c62864d
--- /dev/null
+++ b/pkg/_fe_analyzer_shared/test/flow_analysis/flow_analysis_mini_ast.dart
@@ -0,0 +1,1491 @@
+// Copyright (c) 2020, 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.
+
+/// This file implements the AST of a Dart-like language suitable for testing
+/// flow analysis.  Callers may use the top level methods in this file to create
+/// AST nodes and then feed them to [Harness.run] to run them through flow
+/// analysis testing.
+import 'package:_fe_analyzer_shared/src/flow_analysis/flow_analysis.dart';
+import 'package:meta/meta.dart';
+import 'package:test/test.dart';
+
+const Expression nullLiteral = const _NullLiteral();
+
+Statement assert_(Expression condition, [Expression message]) =>
+    new _Assert(condition, message);
+
+Statement block(List<Statement> statements) => new _Block(statements);
+
+Expression booleanLiteral(bool value) => _BooleanLiteral(value);
+
+/// Wrapper allowing creation of a statement that can be used as the target of
+/// `break` or `continue` statements.  [callback] will be invoked to create the
+/// statement, and it will be passed a [BranchTargetPlaceholder] that can be
+/// passed to [break_] or [continue_].
+Statement branchTarget(Statement Function(BranchTargetPlaceholder) callback) {
+  var branchTargetPlaceholder = BranchTargetPlaceholder._();
+  var stmt = callback(branchTargetPlaceholder);
+  branchTargetPlaceholder._target = stmt;
+  return stmt;
+}
+
+Statement break_(BranchTargetPlaceholder branchTargetPlaceholder) =>
+    new _Break(branchTargetPlaceholder);
+
+SwitchCase case_(List<Statement> body, {bool hasLabel = false}) =>
+    SwitchCase._(hasLabel, body);
+
+CatchClause catch_(
+        {Var exception, Var stackTrace, @required List<Statement> body}) =>
+    CatchClause._(body, exception, stackTrace);
+
+/// Creates a pseudo-statement whose function is to verify that flow analysis
+/// considers [variable]'s assigned state to be [expectedAssignedState].
+Statement checkAssigned(Var variable, bool expectedAssignedState) =>
+    new _CheckAssigned(variable, expectedAssignedState);
+
+/// Creates a pseudo-statement whose function is to verify that flow analysis
+/// considers [variable] to be un-promoted.
+Statement checkNotPromoted(Var variable) => new _CheckPromoted(variable, null);
+
+/// Creates a pseudo-statement whose function is to verify that flow analysis
+/// considers [variable]'s assigned state to be promoted to [expectedTypeStr].
+Statement checkPromoted(Var variable, String expectedTypeStr) =>
+    new _CheckPromoted(variable, expectedTypeStr);
+
+/// Creates a pseudo-statement whose function is to verify that flow analysis
+/// considers the current location's reachability state to be
+/// [expectedReachable].
+Statement checkReachable(bool expectedReachable) =>
+    new _CheckReachable(expectedReachable);
+
+/// Creates a pseudo-statement whose function is to verify that flow analysis
+/// considers [variable]'s unassigned state to be [expectedUnassignedState].
+Statement checkUnassigned(Var variable, bool expectedUnassignedState) =>
+    new _CheckUnassigned(variable, expectedUnassignedState);
+
+Statement continue_(BranchTargetPlaceholder branchTargetPlaceholder) =>
+    new _Continue(branchTargetPlaceholder);
+
+Statement declare(Var variable, {@required bool initialized}) =>
+    new _Declare(variable, initialized);
+
+Statement do_(List<Statement> body, Expression condition) =>
+    _Do(body, condition);
+
+/// Creates a pseudo-expression having type [typeStr] that otherwise has no
+/// effect on flow analysis.
+Expression expr(String typeStr) =>
+    new _PlaceholderExpression(new Type(typeStr));
+
+/// Creates a conventional `for` statement.  Optional boolean [forCollection]
+/// indicates that this `for` statement is actually a collection element, so
+/// `null` should be passed to [for_bodyBegin].
+Statement for_(Statement initializer, Expression condition, Expression updater,
+        List<Statement> body,
+        {bool forCollection = false}) =>
+    new _For(initializer, condition, updater, body, forCollection);
+
+/// Creates a "for each" statement where the identifier being assigned to by the
+/// iteration is not a local variable.
+///
+/// This models code like:
+///     var x; // Top level variable
+///     f(Iterable iterable) {
+///       for (x in iterable) { ... }
+///     }
+Statement forEachWithNonVariable(Expression iterable, List<Statement> body) =>
+    new _ForEach(null, iterable, body, false);
+
+/// Creates a "for each" statement where the identifier being assigned to by the
+/// iteration is a variable that is being declared by the "for each" statement.
+///
+/// This models code like:
+///     f(Iterable iterable) {
+///       for (var x in iterable) { ... }
+///     }
+Statement forEachWithVariableDecl(
+    Var variable, Expression iterable, List<Statement> body) {
+  assert(variable != null);
+  return new _ForEach(variable, iterable, body, true);
+}
+
+/// Creates a "for each" statement where the identifier being assigned to by the
+/// iteration is a local variable that is declared elsewhere in the function.
+///
+/// This models code like:
+///     f(Iterable iterable) {
+///       var x;
+///       for (x in iterable) { ... }
+///     }
+Statement forEachWithVariableSet(
+    Var variable, Expression iterable, List<Statement> body) {
+  assert(variable != null);
+  return new _ForEach(variable, iterable, body, false);
+}
+
+Statement if_(Expression condition, List<Statement> ifTrue,
+        [List<Statement> ifFalse]) =>
+    new _If(condition, ifTrue, ifFalse);
+
+Statement labeled(Statement body) => new _LabeledStatement(body);
+
+Statement localFunction(List<Statement> body) => _LocalFunction(body);
+
+Statement return_() => new _Return();
+
+Statement switch_(Expression expression, List<SwitchCase> cases,
+        {@required bool isExhaustive}) =>
+    new _Switch(expression, cases, isExhaustive);
+
+Statement tryCatch(List<Statement> body, List<CatchClause> catches) =>
+    new _TryCatch(body, catches);
+
+Statement tryFinally(List<Statement> body, List<Statement> finally_) =>
+    new _TryFinally(body, finally_);
+
+Statement while_(Expression condition, List<Statement> body) =>
+    new _While(condition, body);
+
+/// Placeholder used by [branchTarget] to tie `break` and `continue` statements
+/// to their branch targets.
+class BranchTargetPlaceholder {
+  Statement _target;
+
+  /*late*/ BranchTargetPlaceholder._();
+}
+
+/// Representation of a single catch clause in a try/catch statement.  Use
+/// [catch_] to create instances of this class.
+class CatchClause implements _Visitable<void> {
+  final List<Statement> _body;
+  final Var _exception;
+  final Var _stackTrace;
+
+  CatchClause._(this._body, this._exception, this._stackTrace);
+
+  String toString() {
+    String initialPart;
+    if (_stackTrace != null) {
+      initialPart = 'catch (${_exception.name}, ${_stackTrace.name})';
+    } else if (_exception != null) {
+      initialPart = 'catch (${_exception.name})';
+    } else {
+      initialPart = 'on ...';
+    }
+    return '$initialPart ${block(_body)}';
+  }
+
+  void _preVisit(AssignedVariables<Node, Var> assignedVariables) {
+    _body._preVisit(assignedVariables);
+  }
+
+  void _visit(
+      Harness h, FlowAnalysis<Node, Statement, Expression, Var, Type> flow) {
+    flow.tryCatchStatement_catchBegin(_exception, _stackTrace);
+    _body._visit(h, flow);
+    flow.tryCatchStatement_catchEnd();
+  }
+}
+
+/// Representation of an expression in the pseudo-Dart language used for flow
+/// analysis testing.  Methods in this class may be used to create more complex
+/// expressions based on this one.
+abstract class Expression implements _Visitable<Type> {
+  const Expression();
+
+  /// If `this` is an expression `x`, creates the expression `x!`.
+  Expression get nonNullAssert => new _NonNullAssert(this);
+
+  /// If `this` is an expression `x`, creates the expression `(x)`.
+  Expression get parenthesized => new _WrappedExpression(null, this, null);
+
+  /// If `this` is an expression `x`, creates the statement `x;`.
+  Statement get stmt => new _ExpressionStatement(this);
+
+  /// If `this` is an expression `x`, creates the expression `x && other`.
+  Expression and(Expression other) => new _Logical(this, other, isAnd: true);
+
+  /// If `this` is an expression `x`, creates the expression `x as typeStr`.
+  Expression as_(String typeStr) => new _As(this, Type(typeStr));
+
+  /// If `this` is an expression `x`, creates the expression
+  /// `x ? ifTrue : ifFalse`.
+  Expression conditional(Expression ifTrue, Expression ifFalse) =>
+      new _Conditional(this, ifTrue, ifFalse);
+
+  /// If `this` is an expression `x`, creates the expression `x == other`.
+  Expression eq(Expression other) => new _Equal(this, other, false);
+
+  /// If `this` is an expression `x`, creates the expression `x ?? other`.
+  Expression ifNull(Expression other) => new _IfNull(this, other);
+
+  /// If `this` is an expression `x`, creates the expression `x is typeStr`.
+  ///
+  /// With [isInverted] set to `true`, creates the expression `x is! typeStr`.
+  Expression is_(String typeStr, {bool isInverted = false}) =>
+      new _Is(this, Type(typeStr), isInverted);
+
+  /// If `this` is an expression `x`, creates the expression `x is! typeStr`.
+  Expression isNot(String typeStr) => _Is(this, Type(typeStr), true);
+
+  /// If `this` is an expression `x`, creates the expression `x != other`.
+  Expression notEq(Expression other) => _Equal(this, other, true);
+
+  /// If `this` is an expression `x`, creates the expression `x?.other`.
+  ///
+  /// Note that in the real Dart language, the RHS of a null aware access isn't
+  /// strictly speaking an expression.  However for flow analysis it suffices to
+  /// model it as an expression.
+  Expression nullAwareAccess(Expression other, {bool isCascaded = false}) =>
+      _NullAwareAccess(this, other, isCascaded);
+
+  /// If `this` is an expression `x`, creates the expression `x || other`.
+  Expression or(Expression other) => new _Logical(this, other, isAnd: false);
+
+  /// If `this` is an expression `x`, creates a pseudo-expression that models
+  /// evaluation of `x` followed by execution of [stmt].  This can be used to
+  /// test that flow analysis is in the correct state after an expression is
+  /// visited.
+  Expression thenStmt(Statement stmt) =>
+      new _WrappedExpression(null, this, stmt);
+}
+
+/// Test harness for creating flow analysis tests.  This class implements all
+/// the [TypeOperations] needed by flow analysis, as well as other methods
+/// needed for testing.
+class Harness extends TypeOperations<Var, Type> {
+  static const Map<String, bool> _coreSubtypes = const {
+    'double <: Object': true,
+    'double <: num': true,
+    'double <: num?': true,
+    'double <: int': false,
+    'double <: int?': false,
+    'int <: double': false,
+    'int <: int?': true,
+    'int <: Iterable': false,
+    'int <: List': false,
+    'int <: Null': false,
+    'int <: num': true,
+    'int <: num?': true,
+    'int <: num*': true,
+    'int <: Never?': false,
+    'int <: Object': true,
+    'int <: Object?': true,
+    'int <: String': false,
+    'int? <: int': false,
+    'int? <: Null': false,
+    'int? <: num': false,
+    'int? <: num?': true,
+    'int? <: Object': false,
+    'int? <: Object?': true,
+    'Null <: int': false,
+    'Null <: Object': false,
+    'num <: int': false,
+    'num <: Iterable': false,
+    'num <: List': false,
+    'num <: num?': true,
+    'num <: num*': true,
+    'num <: Object': true,
+    'num <: Object?': true,
+    'num? <: int?': false,
+    'num? <: num': false,
+    'num? <: num*': true,
+    'num? <: Object': false,
+    'num? <: Object?': true,
+    'num* <: num': true,
+    'num* <: num?': true,
+    'num* <: Object': true,
+    'num* <: Object?': true,
+    'Iterable <: int': false,
+    'Iterable <: num': false,
+    'Iterable <: Object': true,
+    'Iterable <: Object?': true,
+    'List <: int': false,
+    'List <: Iterable': true,
+    'List <: Object': true,
+    'Never <: int': true,
+    'Never <: int?': true,
+    'Never <: Null': true,
+    'Never? <: int': false,
+    'Never? <: int?': true,
+    'Never? <: num?': true,
+    'Never? <: Object?': true,
+    'Null <: int?': true,
+    'Object <: int': false,
+    'Object <: int?': false,
+    'Object <: List': false,
+    'Object <: num': false,
+    'Object <: num?': false,
+    'Object <: Object?': true,
+    'Object? <: Object': false,
+    'Object? <: int': false,
+    'Object? <: int?': false,
+    'String <: int': false,
+    'String <: int?': false,
+    'String <: num?': false,
+    'String <: Object?': true,
+  };
+
+  static final Map<String, Type> _coreFactors = {
+    'Object? - int': Type('Object?'),
+    'Object? - int?': Type('Object'),
+    'Object? - num?': Type('Object'),
+    'Object? - Object?': Type('Never?'),
+    'Object? - String': Type('Object?'),
+    'Object - int': Type('Object'),
+    'int - Object': Type('Never'),
+    'int - String': Type('int'),
+    'int - int': Type('Never'),
+    'int - int?': Type('Never'),
+    'int? - int': Type('Never?'),
+    'int? - int?': Type('Never'),
+    'int? - String': Type('int?'),
+    'Null - int': Type('Null'),
+    'num - int': Type('num'),
+    'num? - num': Type('Never?'),
+    'num? - int': Type('num?'),
+    'num? - int?': Type('num'),
+    'num? - Object': Type('Never?'),
+    'num? - String': Type('num?'),
+    'Object - int?': Type('Object'),
+    'Object - num': Type('Object'),
+    'Object - num?': Type('Object'),
+    'Object - num*': Type('Object'),
+    'Object - Iterable': Type('Object'),
+    'Object? - Object': Type('Never?'),
+    'Object? - Iterable': Type('Object?'),
+    'Object? - num': Type('Object?'),
+    'Iterable - List': Type('Iterable'),
+    'num* - Object': Type('Never'),
+  };
+
+  final Map<String, bool> _subtypes = Map.of(_coreSubtypes);
+
+  final Map<String, Type> _factorResults = Map.of(_coreFactors);
+
+  Node _currentSwitch;
+
+  /// Updates the harness so that when a [factor] query is invoked on types
+  /// [from] and [what], [result] will be returned.
+  void addFactor(Type from, Type what, Type result) {
+    var query = '$from - $what';
+    _factorResults[query] = result;
+  }
+
+  /// Updates the harness so that when an [isSubtypeOf] query is invoked on
+  /// types [leftType] and [rightType], [isSubtype] will be returned.
+  void addSubtype(Type leftType, Type rightType, bool isSubtype) {
+    var query = '$leftType <: $rightType';
+    _subtypes[query] = isSubtype;
+  }
+
+  @override
+  TypeClassification classifyType(Type type) {
+    if (isSubtypeOf(type, Type('Object'))) {
+      return TypeClassification.nonNullable;
+    } else if (isSubtypeOf(type, Type('Null'))) {
+      return TypeClassification.nullOrEquivalent;
+    } else {
+      return TypeClassification.potentiallyNullable;
+    }
+  }
+
+  @override
+  Type factor(Type from, Type what) {
+    var query = '$from - $what';
+    return _factorResults[query] ?? fail('Unknown factor query: $query');
+  }
+
+  @override
+  bool isNever(Type type) {
+    return type.type == 'Never';
+  }
+
+  @override
+  bool isSameType(Type type1, Type type2) {
+    return type1.type == type2.type;
+  }
+
+  @override
+  bool isSubtypeOf(Type leftType, Type rightType) {
+    if (leftType.type == rightType.type) return true;
+    var query = '$leftType <: $rightType';
+    return _subtypes[query] ?? fail('Unknown subtype query: $query');
+  }
+
+  @override
+  Type promoteToNonNull(Type type) {
+    if (type.type.endsWith('?')) {
+      return Type(type.type.substring(0, type.type.length - 1));
+    } else if (type.type == 'Null') {
+      return Type('Never');
+    } else {
+      return type;
+    }
+  }
+
+  /// Runs the given [statements] through flow analysis, checking any assertions
+  /// they contain.
+  void run(List<Statement> statements) {
+    var assignedVariables = AssignedVariables<Node, Var>();
+    statements._preVisit(assignedVariables);
+    var flow = FlowAnalysis<Node, Statement, Expression, Var, Type>(
+        this, assignedVariables);
+    statements._visit(this, flow);
+    flow.finish();
+  }
+
+  @override
+  Type tryPromoteToType(Type to, Type from) {
+    if (isSubtypeOf(to, from)) {
+      return to;
+    } else {
+      return null;
+    }
+  }
+
+  @override
+  Type variableType(Var variable) {
+    return variable.type;
+  }
+
+  Type _getIteratedType(Type iterableType) {
+    var typeStr = iterableType.type;
+    if (typeStr.startsWith('List<') && typeStr.endsWith('>')) {
+      return Type(typeStr.substring(5, typeStr.length - 1));
+    } else {
+      throw UnimplementedError('TODO(paulberry): getIteratedType($typeStr)');
+    }
+  }
+
+  Type _lub(Type type1, Type type2) {
+    if (isSameType(type1, type2)) {
+      return type1;
+    } else if (isSameType(promoteToNonNull(type1), type2)) {
+      return type1;
+    } else if (isSameType(promoteToNonNull(type2), type1)) {
+      return type2;
+    } else if (type1.type == 'Null' &&
+        !isSameType(promoteToNonNull(type2), type2)) {
+      // type2 is already nullable
+      return type2;
+    } else if (type2.type == 'Null' &&
+        !isSameType(promoteToNonNull(type1), type1)) {
+      // type1 is already nullable
+      return type1;
+    } else {
+      throw UnimplementedError(
+          'TODO(paulberry): least upper bound of $type1 and $type2');
+    }
+  }
+}
+
+/// Representation of an expression or statement in the pseudo-Dart language
+/// used for flow analysis testing.
+class Node {
+  Node._();
+}
+
+/// Representation of a statement in the pseudo-Dart language used for flow
+/// analysis testing.
+abstract class Statement extends Node implements _Visitable<void> {
+  Statement._() : super._();
+
+  /// If `this` is a statement `x`, creates a pseudo-expression that models
+  /// execution of `x` followed by evaluation of [expr].  This can be used to
+  /// test that flow analysis is in the correct state before an expression is
+  /// visited.
+  Expression thenExpr(Expression expr) => _WrappedExpression(this, expr, null);
+}
+
+/// Representation of a single case clause in a switch statement.  Use [case_]
+/// to create instances of this class.
+class SwitchCase implements _Visitable<void> {
+  final bool _hasLabel;
+  final List<Statement> _body;
+
+  SwitchCase._(this._hasLabel, this._body);
+
+  String toString() =>
+      [if (_hasLabel) '<label>:', 'case <value>:', ..._body].join(' ');
+
+  void _preVisit(AssignedVariables<Node, Var> assignedVariables) {
+    _body._preVisit(assignedVariables);
+  }
+
+  void _visit(
+      Harness h, FlowAnalysis<Node, Statement, Expression, Var, Type> flow) {
+    flow.switchStatement_beginCase(_hasLabel, h._currentSwitch);
+    _body._visit(h, flow);
+  }
+}
+
+/// Representation of a type in the pseudo-Dart language used for flow analysis
+/// testing.  This is essentially a thin wrapper around a string representation
+/// of the type.
+class Type {
+  final String type;
+
+  Type(this.type);
+
+  @override
+  bool operator ==(Object other) {
+    // The flow analysis engine should not compare types using operator==.  It
+    // should compare them using TypeOperations.
+    fail('Unexpected use of operator== on types');
+  }
+
+  @override
+  String toString() => type;
+}
+
+/// Representation of a local variable in the pseudo-Dart language used for flow
+/// analysis testing.
+class Var {
+  final String name;
+  final Type type;
+
+  Var(this.name, String typeStr) : type = Type(typeStr);
+
+  /// Creates an expression representing a read of this variable.
+  Expression get read => new _VariableRead(this);
+
+  @override
+  String toString() => '$type $name';
+
+  /// Creates an expression representing a write to this variable.
+  Expression write(Expression value) => new _Write(this, value);
+}
+
+class _As extends Expression {
+  final Expression target;
+  final Type type;
+
+  _As(this.target, this.type);
+
+  @override
+  String toString() => '$target as $type';
+
+  @override
+  void _preVisit(AssignedVariables<Node, Var> assignedVariables) {
+    target._preVisit(assignedVariables);
+  }
+
+  @override
+  Type _visit(
+      Harness h, FlowAnalysis<Node, Statement, Expression, Var, Type> flow) {
+    target._visit(h, flow);
+    flow.asExpression_end(target, type);
+    return type;
+  }
+}
+
+class _Assert extends Statement {
+  final Expression condition;
+  final Expression message;
+
+  _Assert(this.condition, this.message) : super._();
+
+  @override
+  String toString() =>
+      'assert($condition${message == null ? '' : ', $message'});';
+
+  @override
+  void _preVisit(AssignedVariables<Node, Var> assignedVariables) {
+    condition._preVisit(assignedVariables);
+    message?._preVisit(assignedVariables);
+  }
+
+  @override
+  void _visit(
+      Harness h, FlowAnalysis<Node, Statement, Expression, Var, Type> flow) {
+    flow.assert_begin();
+    flow.assert_afterCondition(condition.._visit(h, flow));
+    message?._visit(h, flow);
+    flow.assert_end();
+  }
+}
+
+class _Block extends Statement {
+  final List<Statement> statements;
+
+  _Block(this.statements) : super._();
+
+  @override
+  String toString() =>
+      statements.isEmpty ? '{}' : '{ ${statements.join(' ')} }';
+
+  @override
+  void _preVisit(AssignedVariables<Node, Var> assignedVariables) {
+    statements._preVisit(assignedVariables);
+  }
+
+  @override
+  void _visit(
+      Harness h, FlowAnalysis<Node, Statement, Expression, Var, Type> flow) {
+    statements._visit(h, flow);
+  }
+}
+
+class _BooleanLiteral extends Expression {
+  final bool value;
+
+  _BooleanLiteral(this.value);
+
+  @override
+  String toString() => '$value';
+
+  @override
+  void _preVisit(AssignedVariables<Node, Var> assignedVariables) {}
+
+  @override
+  Type _visit(
+      Harness h, FlowAnalysis<Node, Statement, Expression, Var, Type> flow) {
+    flow.booleanLiteral(this, value);
+    return Type('bool');
+  }
+}
+
+class _Break extends Statement {
+  final BranchTargetPlaceholder branchTargetPlaceholder;
+
+  _Break(this.branchTargetPlaceholder) : super._();
+
+  @override
+  String toString() => 'break;';
+
+  @override
+  void _preVisit(AssignedVariables<Node, Var> assignedVariables) {}
+
+  @override
+  void _visit(
+      Harness h, FlowAnalysis<Node, Statement, Expression, Var, Type> flow) {
+    assert(branchTargetPlaceholder._target != null);
+    flow.handleBreak(branchTargetPlaceholder._target);
+  }
+}
+
+class _CheckAssigned extends Statement {
+  final Var variable;
+  final bool expectedAssignedState;
+
+  _CheckAssigned(this.variable, this.expectedAssignedState) : super._();
+
+  @override
+  String toString() {
+    var verb = expectedAssignedState ? 'is' : 'is not';
+    return 'check $variable $verb definitely assigned;';
+  }
+
+  @override
+  void _preVisit(AssignedVariables<Node, Var> assignedVariables) {}
+
+  @override
+  void _visit(
+      Harness h, FlowAnalysis<Node, Statement, Expression, Var, Type> flow) {
+    expect(flow.isAssigned(variable), expectedAssignedState);
+  }
+}
+
+class _CheckPromoted extends Statement {
+  final Var variable;
+  final String expectedTypeStr;
+
+  _CheckPromoted(this.variable, this.expectedTypeStr) : super._();
+
+  @override
+  String toString() {
+    var predicate = expectedTypeStr == null
+        ? 'not promoted'
+        : 'promoted to $expectedTypeStr';
+    return 'check $variable $predicate;';
+  }
+
+  @override
+  void _preVisit(AssignedVariables<Node, Var> assignedVariables) {}
+
+  @override
+  void _visit(
+      Harness h, FlowAnalysis<Node, Statement, Expression, Var, Type> flow) {
+    var promotedType = flow.promotedType(variable);
+    if (expectedTypeStr == null) {
+      expect(promotedType, isNull);
+    } else {
+      expect(promotedType.type, expectedTypeStr);
+    }
+  }
+}
+
+class _CheckReachable extends Statement {
+  final bool expectedReachable;
+
+  _CheckReachable(this.expectedReachable) : super._();
+
+  @override
+  String toString() => 'check reachable;';
+
+  @override
+  void _preVisit(AssignedVariables<Node, Var> assignedVariables) {}
+
+  @override
+  void _visit(
+      Harness h, FlowAnalysis<Node, Statement, Expression, Var, Type> flow) {
+    expect(flow.isReachable, expectedReachable);
+  }
+}
+
+class _CheckUnassigned extends Statement {
+  final Var variable;
+  final bool expectedUnassignedState;
+
+  _CheckUnassigned(this.variable, this.expectedUnassignedState) : super._();
+
+  @override
+  String toString() {
+    var verb = expectedUnassignedState ? 'is' : 'is not';
+    return 'check $variable $verb definitely unassigned;';
+  }
+
+  @override
+  void _preVisit(AssignedVariables<Node, Var> assignedVariables) {}
+
+  @override
+  void _visit(
+      Harness h, FlowAnalysis<Node, Statement, Expression, Var, Type> flow) {
+    expect(flow.isUnassigned(variable), expectedUnassignedState);
+  }
+}
+
+class _Conditional extends Expression {
+  final Expression condition;
+  final Expression ifTrue;
+  final Expression ifFalse;
+
+  _Conditional(this.condition, this.ifTrue, this.ifFalse);
+
+  @override
+  String toString() => '$condition ? $ifTrue : $ifFalse';
+
+  @override
+  void _preVisit(AssignedVariables<Node, Var> assignedVariables) {
+    condition._preVisit(assignedVariables);
+    ifTrue._preVisit(assignedVariables);
+    ifFalse._preVisit(assignedVariables);
+  }
+
+  @override
+  Type _visit(
+      Harness h, FlowAnalysis<Node, Statement, Expression, Var, Type> flow) {
+    flow.conditional_conditionBegin();
+    flow.conditional_thenBegin(condition.._visit(h, flow));
+    var ifTrueType = ifTrue._visit(h, flow);
+    flow.conditional_elseBegin(ifTrue);
+    var ifFalseType = ifFalse._visit(h, flow);
+    flow.conditional_end(this, ifFalse);
+    return h._lub(ifTrueType, ifFalseType);
+  }
+}
+
+class _Continue extends Statement {
+  final BranchTargetPlaceholder branchTargetPlaceholder;
+
+  _Continue(this.branchTargetPlaceholder) : super._();
+
+  @override
+  String toString() => 'continue;';
+
+  @override
+  void _preVisit(AssignedVariables<Node, Var> assignedVariables) {}
+
+  @override
+  void _visit(
+      Harness h, FlowAnalysis<Node, Statement, Expression, Var, Type> flow) {
+    assert(branchTargetPlaceholder._target != null);
+    flow.handleContinue(branchTargetPlaceholder._target);
+  }
+}
+
+class _Declare extends Statement {
+  final Var variable;
+  final bool initialized;
+
+  _Declare(this.variable, this.initialized) : super._();
+
+  @override
+  String toString() => '$variable${initialized ? ' = ...' : ''};';
+
+  @override
+  void _preVisit(AssignedVariables<Node, Var> assignedVariables) {}
+
+  @override
+  void _visit(
+      Harness h, FlowAnalysis<Node, Statement, Expression, Var, Type> flow) {
+    flow.declare(variable, initialized);
+  }
+}
+
+class _Do extends Statement {
+  final List<Statement> body;
+  final Expression condition;
+
+  _Do(this.body, this.condition) : super._();
+
+  @override
+  String toString() => 'do ${block(body)} while ($condition);';
+
+  @override
+  void _preVisit(AssignedVariables<Node, Var> assignedVariables) {
+    assignedVariables.beginNode();
+    body._preVisit(assignedVariables);
+    condition._preVisit(assignedVariables);
+    assignedVariables.endNode(this);
+  }
+
+  @override
+  void _visit(
+      Harness h, FlowAnalysis<Node, Statement, Expression, Var, Type> flow) {
+    flow.doStatement_bodyBegin(this);
+    body._visit(h, flow);
+    flow.doStatement_conditionBegin();
+    condition._visit(h, flow);
+    flow.doStatement_end(condition);
+  }
+}
+
+class _Equal extends Expression {
+  final Expression lhs;
+  final Expression rhs;
+  final bool isInverted;
+
+  _Equal(this.lhs, this.rhs, this.isInverted);
+
+  @override
+  String toString() => '$lhs ${isInverted ? '!=' : '=='} $rhs';
+
+  @override
+  void _preVisit(AssignedVariables<Node, Var> assignedVariables) {
+    lhs._preVisit(assignedVariables);
+    rhs._preVisit(assignedVariables);
+  }
+
+  @override
+  Type _visit(
+      Harness h, FlowAnalysis<Node, Statement, Expression, Var, Type> flow) {
+    var lhsType = lhs._visit(h, flow);
+    flow.equalityOp_rightBegin(lhs, lhsType);
+    var rhsType = rhs._visit(h, flow);
+    flow.equalityOp_end(this, rhs, rhsType, notEqual: isInverted);
+    return Type('bool');
+  }
+}
+
+class _ExpressionStatement extends Statement {
+  final Expression expr;
+
+  _ExpressionStatement(this.expr) : super._();
+
+  @override
+  String toString() => '$expr;';
+
+  @override
+  void _preVisit(AssignedVariables<Node, Var> assignedVariables) {
+    expr._preVisit(assignedVariables);
+  }
+
+  @override
+  void _visit(
+      Harness h, FlowAnalysis<Node, Statement, Expression, Var, Type> flow) {
+    expr._visit(h, flow);
+  }
+}
+
+class _For extends Statement {
+  final Statement initializer;
+  final Expression condition;
+  final Expression updater;
+  final List<Statement> body;
+  final bool forCollection;
+
+  _For(this.initializer, this.condition, this.updater, this.body,
+      this.forCollection)
+      : super._();
+
+  @override
+  String toString() {
+    var buffer = StringBuffer('for (');
+    if (initializer == null) {
+      buffer.write(';');
+    } else {
+      buffer.write(initializer);
+    }
+    if (condition == null) {
+      buffer.write(';');
+    } else {
+      buffer.write(' $condition;');
+    }
+    if (updater != null) {
+      buffer.write(' $updater');
+    }
+    buffer.write(') ${block(body)}');
+    return buffer.toString();
+  }
+
+  @override
+  void _preVisit(AssignedVariables<Node, Var> assignedVariables) {
+    initializer?._preVisit(assignedVariables);
+    assignedVariables.beginNode();
+    condition?._preVisit(assignedVariables);
+    body._preVisit(assignedVariables);
+    updater?._preVisit(assignedVariables);
+    assignedVariables.endNode(this);
+  }
+
+  @override
+  void _visit(
+      Harness h, FlowAnalysis<Node, Statement, Expression, Var, Type> flow) {
+    initializer?._visit(h, flow);
+    flow.for_conditionBegin(this);
+    condition?._visit(h, flow);
+    flow.for_bodyBegin(forCollection ? null : this, condition);
+    body._visit(h, flow);
+    flow.for_updaterBegin();
+    updater?._visit(h, flow);
+    flow.for_end();
+  }
+}
+
+class _ForEach extends Statement {
+  final Var variable;
+  final Expression iterable;
+  final List<Statement> body;
+  final bool declaresVariable;
+
+  _ForEach(this.variable, this.iterable, this.body, this.declaresVariable)
+      : super._();
+
+  @override
+  String toString() {
+    String declarationPart;
+    if (variable == null) {
+      declarationPart = '<identifier>';
+    } else if (declaresVariable) {
+      declarationPart = variable.toString();
+    } else {
+      declarationPart = variable.name;
+    }
+    return 'for ($declarationPart in $iterable) ${block(body)}';
+  }
+
+  @override
+  void _preVisit(AssignedVariables<Node, Var> assignedVariables) {
+    iterable._preVisit(assignedVariables);
+    if (variable != null) {
+      if (declaresVariable) {
+        assignedVariables.declare(variable);
+      } else {
+        assignedVariables.write(variable);
+      }
+    }
+    assignedVariables.beginNode();
+    body._preVisit(assignedVariables);
+    assignedVariables.endNode(this);
+  }
+
+  @override
+  void _visit(
+      Harness h, FlowAnalysis<Node, Statement, Expression, Var, Type> flow) {
+    var iteratedType = h._getIteratedType(iterable._visit(h, flow));
+    flow.forEach_bodyBegin(this, variable, iteratedType);
+    body._visit(h, flow);
+    flow.forEach_end();
+  }
+}
+
+class _If extends Statement {
+  final Expression condition;
+  final List<Statement> ifTrue;
+  final List<Statement> ifFalse;
+
+  _If(this.condition, this.ifTrue, this.ifFalse) : super._();
+
+  @override
+  String toString() =>
+      'if ($condition) ${block(ifTrue)}' +
+      (ifFalse == null ? '' : 'else ${block(ifFalse)}');
+
+  @override
+  void _preVisit(AssignedVariables<Node, Var> assignedVariables) {
+    condition._preVisit(assignedVariables);
+    ifTrue._preVisit(assignedVariables);
+    ifFalse?._preVisit(assignedVariables);
+  }
+
+  @override
+  void _visit(
+      Harness h, FlowAnalysis<Node, Statement, Expression, Var, Type> flow) {
+    flow.ifStatement_conditionBegin();
+    flow.ifStatement_thenBegin(condition.._visit(h, flow));
+    ifTrue._visit(h, flow);
+    if (ifFalse == null) {
+      flow.ifStatement_end(false);
+    } else {
+      flow.ifStatement_elseBegin();
+      ifFalse._visit(h, flow);
+      flow.ifStatement_end(true);
+    }
+  }
+}
+
+class _IfNull extends Expression {
+  final Expression lhs;
+  final Expression rhs;
+
+  _IfNull(this.lhs, this.rhs);
+
+  @override
+  String toString() => '$lhs ?? $rhs';
+
+  @override
+  void _preVisit(AssignedVariables<Node, Var> assignedVariables) {
+    lhs._preVisit(assignedVariables);
+    rhs._preVisit(assignedVariables);
+  }
+
+  @override
+  Type _visit(
+      Harness h, FlowAnalysis<Node, Statement, Expression, Var, Type> flow) {
+    var lhsType = lhs._visit(h, flow);
+    flow.ifNullExpression_rightBegin(lhs, lhsType);
+    var rhsType = rhs._visit(h, flow);
+    flow.ifNullExpression_end();
+    return h._lub(h.promoteToNonNull(lhsType), rhsType);
+  }
+}
+
+class _Is extends Expression {
+  final Expression target;
+  final Type type;
+  final bool isInverted;
+
+  _Is(this.target, this.type, this.isInverted);
+
+  @override
+  String toString() => '$target is${isInverted ? '!' : ''} $type';
+
+  @override
+  void _preVisit(AssignedVariables<Node, Var> assignedVariables) {
+    target._preVisit(assignedVariables);
+  }
+
+  @override
+  Type _visit(
+      Harness h, FlowAnalysis<Node, Statement, Expression, Var, Type> flow) {
+    flow.isExpression_end(this, target.._visit(h, flow), isInverted, type);
+    return Type('bool');
+  }
+}
+
+class _LabeledStatement extends Statement {
+  final Statement body;
+
+  _LabeledStatement(this.body) : super._();
+
+  @override
+  String toString() => 'labeled: $body';
+
+  @override
+  void _preVisit(AssignedVariables<Node, Var> assignedVariables) {
+    body._preVisit(assignedVariables);
+  }
+
+  @override
+  void _visit(
+      Harness h, FlowAnalysis<Node, Statement, Expression, Var, Type> flow) {
+    flow.labeledStatement_begin(this);
+    body._visit(h, flow);
+    flow.labeledStatement_end();
+  }
+}
+
+class _LocalFunction extends Statement {
+  final List<Statement> body;
+
+  _LocalFunction(this.body) : super._();
+
+  @override
+  String toString() => '() ${block(body)}';
+
+  @override
+  void _preVisit(AssignedVariables<Node, Var> assignedVariables) {
+    assignedVariables.beginNode();
+    body._preVisit(assignedVariables);
+    assignedVariables.endNode(this, isClosureOrLateVariableInitializer: true);
+  }
+
+  @override
+  void _visit(
+      Harness h, FlowAnalysis<Node, Statement, Expression, Var, Type> flow) {
+    flow.functionExpression_begin(this);
+    body._visit(h, flow);
+    flow.functionExpression_end();
+  }
+}
+
+class _Logical extends Expression {
+  final Expression lhs;
+  final Expression rhs;
+  final bool isAnd;
+
+  _Logical(this.lhs, this.rhs, {@required this.isAnd});
+
+  @override
+  String toString() => '$lhs ${isAnd ? '&&' : '||'} $rhs';
+
+  @override
+  void _preVisit(AssignedVariables<Node, Var> assignedVariables) {
+    lhs._preVisit(assignedVariables);
+    rhs._preVisit(assignedVariables);
+  }
+
+  @override
+  Type _visit(
+      Harness h, FlowAnalysis<Node, Statement, Expression, Var, Type> flow) {
+    flow.logicalBinaryOp_begin();
+    flow.logicalBinaryOp_rightBegin(lhs.._visit(h, flow), isAnd: isAnd);
+    flow.logicalBinaryOp_end(this, rhs.._visit(h, flow), isAnd: isAnd);
+    return Type('bool');
+  }
+}
+
+class _NonNullAssert extends Expression {
+  final Expression operand;
+
+  _NonNullAssert(this.operand);
+
+  @override
+  String toString() => '$operand!';
+
+  @override
+  void _preVisit(AssignedVariables<Node, Var> assignedVariables) {
+    operand._preVisit(assignedVariables);
+  }
+
+  @override
+  Type _visit(
+      Harness h, FlowAnalysis<Node, Statement, Expression, Var, Type> flow) {
+    var type = operand._visit(h, flow);
+    flow.nonNullAssert_end(operand);
+    return h.promoteToNonNull(type);
+  }
+}
+
+class _NullAwareAccess extends Expression {
+  final Expression lhs;
+  final Expression rhs;
+  final bool isCascaded;
+
+  _NullAwareAccess(this.lhs, this.rhs, this.isCascaded);
+
+  @override
+  String toString() => '$lhs?.${isCascaded ? '.' : ''}($rhs)';
+
+  @override
+  void _preVisit(AssignedVariables<Node, Var> assignedVariables) {
+    lhs._preVisit(assignedVariables);
+    rhs._preVisit(assignedVariables);
+  }
+
+  @override
+  Type _visit(
+      Harness h, FlowAnalysis<Node, Statement, Expression, Var, Type> flow) {
+    var lhsType = lhs._visit(h, flow);
+    flow.nullAwareAccess_rightBegin(isCascaded ? null : lhs, lhsType);
+    var rhsType = rhs._visit(h, flow);
+    flow.nullAwareAccess_end();
+    return h._lub(rhsType, Type('Null'));
+  }
+}
+
+class _NullLiteral extends Expression {
+  const _NullLiteral();
+
+  @override
+  String toString() => 'null';
+
+  @override
+  void _preVisit(AssignedVariables<Node, Var> assignedVariables) {}
+
+  @override
+  Type _visit(
+      Harness h, FlowAnalysis<Node, Statement, Expression, Var, Type> flow) {
+    flow.nullLiteral(this);
+    return Type('Null');
+  }
+}
+
+class _PlaceholderExpression extends Expression {
+  final Type type;
+
+  _PlaceholderExpression(this.type);
+
+  @override
+  String toString() => '(expr with type $type)';
+
+  @override
+  void _preVisit(AssignedVariables<Node, Var> assignedVariables) {}
+
+  @override
+  Type _visit(Harness h,
+          FlowAnalysis<Node, Statement, Expression, Var, Type> flow) =>
+      type;
+}
+
+class _Return extends Statement {
+  _Return() : super._();
+
+  @override
+  String toString() => 'return;';
+
+  @override
+  void _preVisit(AssignedVariables<Node, Var> assignedVariables) {}
+
+  @override
+  void _visit(
+      Harness h, FlowAnalysis<Node, Statement, Expression, Var, Type> flow) {
+    flow.handleExit();
+  }
+}
+
+class _Switch extends Statement {
+  final Expression expression;
+  final List<SwitchCase> cases;
+  final bool isExhaustive;
+
+  _Switch(this.expression, this.cases, this.isExhaustive) : super._();
+
+  @override
+  String toString() {
+    var exhaustiveness = isExhaustive ? 'exhaustive' : 'non-exhaustive';
+    String body;
+    if (cases.isEmpty) {
+      body = '{}';
+    } else {
+      var contents = cases.join(' ');
+      body = '{ $contents }';
+    }
+    return 'switch<$exhaustiveness> ($expression) $body';
+  }
+
+  @override
+  void _preVisit(AssignedVariables<Node, Var> assignedVariables) {
+    expression._preVisit(assignedVariables);
+    assignedVariables.beginNode();
+    cases._preVisit(assignedVariables);
+    assignedVariables.endNode(this);
+  }
+
+  @override
+  void _visit(
+      Harness h, FlowAnalysis<Node, Statement, Expression, Var, Type> flow) {
+    expression._visit(h, flow);
+    flow.switchStatement_expressionEnd(this);
+    var oldSwitch = h._currentSwitch;
+    h._currentSwitch = this;
+    cases._visit(h, flow);
+    h._currentSwitch = oldSwitch;
+    flow.switchStatement_end(isExhaustive);
+  }
+}
+
+class _TryCatch extends Statement {
+  final List<Statement> body;
+  final List<CatchClause> catches;
+
+  _TryCatch(this.body, this.catches) : super._();
+
+  @override
+  String toString() => 'try ${block(body)} ${catches.join(' ')}';
+
+  @override
+  void _preVisit(AssignedVariables<Node, Var> assignedVariables) {
+    assignedVariables.beginNode();
+    body._preVisit(assignedVariables);
+    assignedVariables.endNode(this);
+    catches._preVisit(assignedVariables);
+  }
+
+  @override
+  void _visit(
+      Harness h, FlowAnalysis<Node, Statement, Expression, Var, Type> flow) {
+    flow.tryCatchStatement_bodyBegin();
+    body._visit(h, flow);
+    flow.tryCatchStatement_bodyEnd(this);
+    catches._visit(h, flow);
+    flow.tryCatchStatement_end();
+  }
+}
+
+class _TryFinally extends Statement {
+  final List<Statement> body;
+  final List<Statement> finally_;
+  final Node _bodyNode = Node._();
+  final Node _finallyNode = Node._();
+
+  _TryFinally(this.body, this.finally_) : super._();
+
+  @override
+  String toString() => 'try ${block(body)} finally ${block(finally_)}';
+
+  @override
+  void _preVisit(AssignedVariables<Node, Var> assignedVariables) {
+    assignedVariables.beginNode();
+    body._preVisit(assignedVariables);
+    assignedVariables.endNode(_bodyNode);
+    assignedVariables.beginNode();
+    finally_._preVisit(assignedVariables);
+    assignedVariables.endNode(_finallyNode);
+  }
+
+  @override
+  void _visit(
+      Harness h, FlowAnalysis<Node, Statement, Expression, Var, Type> flow) {
+    flow.tryFinallyStatement_bodyBegin();
+    body._visit(h, flow);
+    flow.tryFinallyStatement_finallyBegin(_bodyNode);
+    finally_._visit(h, flow);
+    flow.tryFinallyStatement_end(_finallyNode);
+  }
+}
+
+class _VariableRead extends Expression {
+  final Var variable;
+
+  _VariableRead(this.variable);
+
+  @override
+  String toString() => variable.name;
+
+  @override
+  void _preVisit(AssignedVariables<Node, Var> assignedVariables) {}
+
+  @override
+  Type _visit(
+      Harness h, FlowAnalysis<Node, Statement, Expression, Var, Type> flow) {
+    return flow.variableRead(this, variable) ?? variable.type;
+  }
+}
+
+abstract class _Visitable<T> {
+  void _preVisit(AssignedVariables<Node, Var> assignedVariables);
+
+  T _visit(
+      Harness h, FlowAnalysis<Node, Statement, Expression, Var, Type> flow);
+}
+
+class _While extends Statement {
+  final Expression condition;
+  final List<Statement> body;
+
+  _While(this.condition, this.body) : super._();
+
+  @override
+  String toString() => 'while ($condition) ${block(body)}';
+
+  @override
+  void _preVisit(AssignedVariables<Node, Var> assignedVariables) {
+    assignedVariables.beginNode();
+    condition?._preVisit(assignedVariables);
+    body._preVisit(assignedVariables);
+    assignedVariables.endNode(this);
+  }
+
+  @override
+  void _visit(
+      Harness h, FlowAnalysis<Node, Statement, Expression, Var, Type> flow) {
+    flow.whileStatement_conditionBegin(this);
+    condition?._visit(h, flow);
+    flow.whileStatement_bodyBegin(this, condition);
+    body._visit(h, flow);
+    flow.whileStatement_end();
+  }
+}
+
+class _WrappedExpression extends Expression {
+  final Statement before;
+  final Expression expr;
+  final Statement after;
+
+  _WrappedExpression(this.before, this.expr, this.after);
+
+  @override
+  String toString() {
+    var s = StringBuffer('(');
+    if (before != null) {
+      s.write('($before) ');
+    }
+    s.write(expr);
+    if (after != null) {
+      s.write(' ($after)');
+    }
+    s.write(')');
+    return s.toString();
+  }
+
+  @override
+  void _preVisit(AssignedVariables<Node, Var> assignedVariables) {
+    before?._preVisit(assignedVariables);
+    expr._preVisit(assignedVariables);
+    after?._preVisit(assignedVariables);
+  }
+
+  @override
+  Type _visit(
+      Harness h, FlowAnalysis<Node, Statement, Expression, Var, Type> flow) {
+    before?._visit(h, flow);
+    var type = expr._visit(h, flow);
+    after?._visit(h, flow);
+    flow.forwardExpression(this, expr);
+    return type;
+  }
+}
+
+class _Write extends Expression {
+  final Var variable;
+  final Expression rhs;
+
+  _Write(this.variable, this.rhs);
+
+  @override
+  String toString() => '${variable.name} = $rhs';
+
+  @override
+  void _preVisit(AssignedVariables<Node, Var> assignedVariables) {
+    assignedVariables.write(variable);
+    rhs._preVisit(assignedVariables);
+  }
+
+  @override
+  Type _visit(
+      Harness h, FlowAnalysis<Node, Statement, Expression, Var, Type> flow) {
+    var type = rhs._visit(h, flow);
+    flow.write(variable, type);
+    return type;
+  }
+}
+
+extension on List<_Visitable<void>> {
+  void _preVisit(AssignedVariables<Node, Var> assignedVariables) {
+    for (var element in this) {
+      element._preVisit(assignedVariables);
+    }
+  }
+
+  void _visit(
+      Harness h, FlowAnalysis<Node, Statement, Expression, Var, Type> flow) {
+    for (var element in this) {
+      element._visit(h, flow);
+    }
+  }
+}
diff --git a/pkg/_fe_analyzer_shared/test/flow_analysis/flow_analysis_test.dart b/pkg/_fe_analyzer_shared/test/flow_analysis/flow_analysis_test.dart
index 02d3307..b7e5b8e 100644
--- a/pkg/_fe_analyzer_shared/test/flow_analysis/flow_analysis_test.dart
+++ b/pkg/_fe_analyzer_shared/test/flow_analysis/flow_analysis_test.dart
@@ -3,152 +3,139 @@
 // BSD-style license that can be found in the LICENSE file.
 
 import 'package:_fe_analyzer_shared/src/flow_analysis/flow_analysis.dart';
-import 'package:meta/meta.dart';
 import 'package:test/test.dart';
 
+import 'flow_analysis_mini_ast.dart';
+
 main() {
   group('API', () {
     test('asExpression_end promotes variables', () {
-      var h = _Harness();
-      var x = h.addVar('x', 'int?');
-      h.run((flow) {
-        h.declare(x, initialized: true);
-        var expr = _Expression();
-        flow.variableRead(expr, x);
-        flow.asExpression_end(expr, _Type('int'));
-        expect(flow.promotedType(x).type, 'int');
-      });
+      var h = Harness();
+      var x = Var('x', 'int?');
+      h.run([
+        declare(x, initialized: true),
+        x.read.as_('int').stmt,
+        checkPromoted(x, 'int'),
+      ]);
     });
 
     test('asExpression_end handles other expressions', () {
-      var h = _Harness();
-      h.run((flow) {
-        var expr = _Expression();
-        flow.asExpression_end(expr, _Type('int'));
-      });
+      var h = Harness();
+      h.run([
+        expr('Object').as_('int').stmt,
+      ]);
     });
 
     test('assert_afterCondition promotes', () {
-      var h = _Harness();
-      var x = h.addVar('x', 'int?');
-      h.run((flow) {
-        flow.assert_begin();
-        var expr = h.eqNull(x, _Type('int?'))();
-        flow.assert_afterCondition(expr);
-        expect(flow.promotedType(x).type, 'int');
-        flow.assert_end();
-      });
+      var h = Harness();
+      var x = Var('x', 'int?');
+      h.run([
+        assert_(x.read.eq(nullLiteral),
+            checkPromoted(x, 'int').thenExpr(expr('String'))),
+      ]);
     });
 
     test('assert_end joins previous and ifTrue states', () {
-      var h = _Harness();
-      var x = h.addVar('x', 'int?');
-      var y = h.addVar('x', 'int?');
-      var z = h.addVar('x', 'int?');
-      h.assignedVariables((vars) {
-        vars.write(x);
-        vars.write(z);
-      });
-      h.run((flow) {
-        h.promote(x, 'int');
-        h.promote(z, 'int');
-        flow.assert_begin();
-        flow.write(x, _Type('int?'));
-        flow.write(z, _Type('int?'));
-        var expr =
-            h.and(h.notNull(x, _Type('int?')), h.notNull(y, _Type('int?')))();
-        flow.assert_afterCondition(expr);
-        flow.assert_end();
+      var h = Harness();
+      var x = Var('x', 'int?');
+      var y = Var('x', 'int?');
+      var z = Var('x', 'int?');
+      h.run([
+        x.read.as_('int').stmt,
+        z.read.as_('int').stmt,
+        assert_(block([
+          x.write(expr('int?')).stmt,
+          z.write(expr('int?')).stmt,
+        ]).thenExpr(x.read.notEq(nullLiteral).and(y.read.notEq(nullLiteral)))),
         // x should be promoted because it was promoted before the assert, and
         // it is re-promoted within the assert (if it passes)
-        expect(flow.promotedType(x).type, 'int');
+        checkPromoted(x, 'int'),
         // y should not be promoted because it was not promoted before the
         // assert.
-        expect(flow.promotedType(y), null);
+        checkNotPromoted(y),
         // z should not be promoted because it is demoted in the assert
         // condition.
-        expect(flow.promotedType(z), null);
-      });
+        checkNotPromoted(z),
+      ]);
     });
 
     test('conditional_thenBegin promotes true branch', () {
-      var h = _Harness();
-      var x = h.addVar('x', 'int?');
-      h.run((flow) {
-        h.declare(x, initialized: true);
-        flow.conditional_conditionBegin();
-        flow.conditional_thenBegin(h.notNull(x, _Type('int?'))());
-        expect(flow.promotedType(x).type, 'int');
-        flow.conditional_elseBegin(_Expression());
-        expect(flow.promotedType(x), isNull);
-        flow.conditional_end(_Expression(), _Expression());
-        expect(flow.promotedType(x), isNull);
-      });
+      var h = Harness();
+      var x = Var('x', 'int?');
+      h.run([
+        declare(x, initialized: true),
+        x.read
+            .notEq(nullLiteral)
+            .conditional(checkPromoted(x, 'int').thenExpr(expr('int')),
+                checkNotPromoted(x).thenExpr(expr('int')))
+            .stmt,
+        checkNotPromoted(x),
+      ]);
     });
 
     test('conditional_elseBegin promotes false branch', () {
-      var h = _Harness();
-      var x = h.addVar('x', 'int?');
-      h.run((flow) {
-        h.declare(x, initialized: true);
-        flow.conditional_conditionBegin();
-        flow.conditional_thenBegin(h.eqNull(x, _Type('int?'))());
-        expect(flow.promotedType(x), isNull);
-        flow.conditional_elseBegin(_Expression());
-        expect(flow.promotedType(x).type, 'int');
-        flow.conditional_end(_Expression(), _Expression());
-        expect(flow.promotedType(x), isNull);
-      });
+      var h = Harness();
+      var x = Var('x', 'int?');
+      h.run([
+        declare(x, initialized: true),
+        x.read
+            .eq(nullLiteral)
+            .conditional(checkNotPromoted(x).thenExpr(expr('Null')),
+                checkPromoted(x, 'int').thenExpr(expr('Null')))
+            .stmt,
+        checkNotPromoted(x),
+      ]);
     });
 
     test('conditional_end keeps promotions common to true and false branches',
         () {
-      var h = _Harness();
-      var x = h.addVar('x', 'int?');
-      var y = h.addVar('y', 'int?');
-      var z = h.addVar('z', 'int?');
-      h.run((flow) {
-        h.declare(x, initialized: true);
-        h.declare(y, initialized: true);
-        h.declare(z, initialized: true);
-        flow.conditional_conditionBegin();
-        flow.conditional_thenBegin(_Expression());
-        h.promote(x, 'int');
-        h.promote(y, 'int');
-        flow.conditional_elseBegin(_Expression());
-        h.promote(x, 'int');
-        h.promote(z, 'int');
-        flow.conditional_end(_Expression(), _Expression());
-        expect(flow.promotedType(x).type, 'int');
-        expect(flow.promotedType(y), isNull);
-        expect(flow.promotedType(z), isNull);
-      });
+      var h = Harness();
+      var x = Var('x', 'int?');
+      var y = Var('y', 'int?');
+      var z = Var('z', 'int?');
+      h.run([
+        declare(x, initialized: true),
+        declare(y, initialized: true),
+        declare(z, initialized: true),
+        expr('bool')
+            .conditional(
+                block([
+                  x.read.as_('int').stmt,
+                  y.read.as_('int').stmt,
+                ]).thenExpr(expr('Null')),
+                block([
+                  x.read.as_('int').stmt,
+                  z.read.as_('int').stmt,
+                ]).thenExpr(expr('Null')))
+            .stmt,
+        checkPromoted(x, 'int'),
+        checkNotPromoted(y),
+        checkNotPromoted(z),
+      ]);
     });
 
     test('conditional joins true states', () {
       // if (... ? (x != null && y != null) : (x != null && z != null)) {
       //   promotes x, but not y or z
       // }
-      var h = _Harness();
-      var x = h.addVar('x', 'int?');
-      var y = h.addVar('y', 'int?');
-      var z = h.addVar('z', 'int?');
-      h.run((flow) {
-        h.declare(x, initialized: true);
-        h.declare(y, initialized: true);
-        h.declare(z, initialized: true);
-        h.if_(
-            h.conditional(
-                h.expr,
-                h.and(h.notNull(x, _Type('int?')), h.notNull(y, _Type('int?'))),
-                h.and(
-                    h.notNull(x, _Type('int?')), h.notNull(z, _Type('int?')))),
-            () {
-          expect(flow.promotedType(x).type, 'int');
-          expect(flow.promotedType(y), isNull);
-          expect(flow.promotedType(z), isNull);
-        });
-      });
+      var h = Harness();
+      var x = Var('x', 'int?');
+      var y = Var('y', 'int?');
+      var z = Var('z', 'int?');
+      h.run([
+        declare(x, initialized: true),
+        declare(y, initialized: true),
+        declare(z, initialized: true),
+        if_(
+            expr('bool').conditional(
+                x.read.notEq(nullLiteral).and(y.read.notEq(nullLiteral)),
+                x.read.notEq(nullLiteral).and(z.read.notEq(nullLiteral))),
+            [
+              checkPromoted(x, 'int'),
+              checkNotPromoted(y),
+              checkNotPromoted(z),
+            ]),
+      ]);
     });
 
     test('conditional joins false states', () {
@@ -156,1087 +143,845 @@
       // } else {
       //   promotes x, but not y or z
       // }
-      var h = _Harness();
-      var x = h.addVar('x', 'int?');
-      var y = h.addVar('y', 'int?');
-      var z = h.addVar('z', 'int?');
-      h.run((flow) {
-        h.declare(x, initialized: true);
-        h.declare(y, initialized: true);
-        h.declare(z, initialized: true);
-        h.ifElse(
-            h.conditional(
-                h.expr,
-                h.or(h.eqNull(x, _Type('int?')), h.eqNull(y, _Type('int?'))),
-                h.or(h.eqNull(x, _Type('int?')), h.eqNull(z, _Type('int?')))),
-            () {}, () {
-          expect(flow.promotedType(x).type, 'int');
-          expect(flow.promotedType(y), isNull);
-          expect(flow.promotedType(z), isNull);
-        });
-      });
+      var h = Harness();
+      var x = Var('x', 'int?');
+      var y = Var('y', 'int?');
+      var z = Var('z', 'int?');
+      h.run([
+        declare(x, initialized: true),
+        declare(y, initialized: true),
+        declare(z, initialized: true),
+        if_(
+            expr('bool').conditional(
+                x.read.eq(nullLiteral).or(y.read.eq(nullLiteral)),
+                x.read.eq(nullLiteral).or(z.read.eq(nullLiteral))),
+            [],
+            [
+              checkPromoted(x, 'int'),
+              checkNotPromoted(y),
+              checkNotPromoted(z),
+            ]),
+      ]);
     });
 
     test('equalityOp(x != null) promotes true branch', () {
-      var h = _Harness();
-      var x = h.addVar('x', 'int?');
-      h.run((flow) {
-        h.declare(x, initialized: true);
-        flow.ifStatement_conditionBegin();
-        var varExpr = _Expression();
-        flow.variableRead(varExpr, x);
-        flow.equalityOp_rightBegin(varExpr, _Type('int?'));
-        var nullExpr = _Expression();
-        flow.nullLiteral(nullExpr);
-        var expr = _Expression();
-        flow.equalityOp_end(expr, nullExpr, _Type('Null'), notEqual: true);
-        flow.ifStatement_thenBegin(expr);
-        expect(flow.isReachable, true);
-        expect(flow.promotedType(x).type, 'int');
-        flow.ifStatement_elseBegin();
-        expect(flow.isReachable, true);
-        expect(flow.promotedType(x), isNull);
-        flow.ifStatement_end(true);
-      });
+      var h = Harness();
+      var x = Var('x', 'int?');
+      h.run([
+        declare(x, initialized: true),
+        if_(x.read.notEq(nullLiteral), [
+          checkReachable(true),
+          checkPromoted(x, 'int'),
+        ], [
+          checkReachable(true),
+          checkNotPromoted(x),
+        ]),
+      ]);
     });
 
     test('equalityOp(x != null) when x is non-nullable', () {
-      var h = _Harness();
-      var x = h.addVar('x', 'int');
-      h.run((flow) {
-        h.declare(x, initialized: true);
-        flow.ifStatement_conditionBegin();
-        var varExpr = _Expression();
-        flow.variableRead(varExpr, x);
-        flow.equalityOp_rightBegin(varExpr, _Type('int'));
-        var nullExpr = _Expression();
-        flow.nullLiteral(nullExpr);
-        var expr = _Expression();
-        flow.equalityOp_end(expr, nullExpr, _Type('Null'), notEqual: true);
-        flow.ifStatement_thenBegin(expr);
-        expect(flow.isReachable, true);
-        expect(flow.promotedType(x), isNull);
-        flow.ifStatement_elseBegin();
-        expect(flow.isReachable, true);
-        expect(flow.promotedType(x), isNull);
-        flow.ifStatement_end(true);
-      });
+      var h = Harness();
+      var x = Var('x', 'int');
+      h.run([
+        declare(x, initialized: true),
+        if_(x.read.notEq(nullLiteral), [
+          checkReachable(true),
+          checkNotPromoted(x),
+        ], [
+          checkReachable(true),
+          checkNotPromoted(x),
+        ])
+      ]);
     });
 
     test('equalityOp(<expr> == <expr>) has no special effect', () {
-      var h = _Harness();
-      h.run((flow) {
-        flow.ifStatement_conditionBegin();
-        flow.equalityOp_rightBegin(_Expression(), _Type('int?'));
-        var expr = _Expression();
-        flow.equalityOp_end(expr, _Expression(), _Type('int?'),
-            notEqual: false);
-        flow.ifStatement_thenBegin(expr);
-        expect(flow.isReachable, true);
-        flow.ifStatement_elseBegin();
-        expect(flow.isReachable, true);
-        flow.ifStatement_end(true);
-      });
+      var h = Harness();
+      h.run([
+        if_(expr('int?').eq(expr('int?')), [
+          checkReachable(true),
+        ], [
+          checkReachable(true),
+        ]),
+      ]);
     });
 
     test('equalityOp(<expr> != <expr>) has no special effect', () {
-      var h = _Harness();
-      h.run((flow) {
-        flow.ifStatement_conditionBegin();
-        flow.equalityOp_rightBegin(_Expression(), _Type('int?'));
-        var expr = _Expression();
-        flow.equalityOp_end(expr, _Expression(), _Type('int?'), notEqual: true);
-        flow.ifStatement_thenBegin(expr);
-        expect(flow.isReachable, true);
-        flow.ifStatement_elseBegin();
-        expect(flow.isReachable, true);
-        flow.ifStatement_end(true);
-      });
+      var h = Harness();
+      h.run([
+        if_(expr('int?').notEq(expr('int?')), [
+          checkReachable(true),
+        ], [
+          checkReachable(true),
+        ]),
+      ]);
     });
 
     test('equalityOp(x != <null expr>) does not promote', () {
-      var h = _Harness();
-      var x = h.addVar('x', 'int?');
-      h.run((flow) {
-        h.declare(x, initialized: true);
-        flow.ifStatement_conditionBegin();
-        var varExpr = _Expression();
-        flow.variableRead(varExpr, x);
-        flow.equalityOp_rightBegin(varExpr, _Type('int?'));
-        var nullExpr = _Expression();
-        var expr = _Expression();
-        flow.equalityOp_end(expr, nullExpr, _Type('Null'), notEqual: true);
-        flow.ifStatement_thenBegin(expr);
-        expect(flow.promotedType(x), isNull);
-        flow.ifStatement_elseBegin();
-        expect(flow.promotedType(x), isNull);
-        flow.ifStatement_end(true);
-      });
+      var h = Harness();
+      var x = Var('x', 'int?');
+      h.run([
+        declare(x, initialized: true),
+        if_(x.read.notEq(expr('Null')), [
+          checkNotPromoted(x),
+        ], [
+          checkNotPromoted(x),
+        ]),
+      ]);
     });
 
     test('equalityOp(x == null) promotes false branch', () {
-      var h = _Harness();
-      var x = h.addVar('x', 'int?');
-      h.run((flow) {
-        h.declare(x, initialized: true);
-        flow.ifStatement_conditionBegin();
-        var varExpr = _Expression();
-        flow.variableRead(varExpr, x);
-        flow.equalityOp_rightBegin(varExpr, _Type('int?'));
-        var nullExpr = _Expression();
-        flow.nullLiteral(nullExpr);
-        var expr = _Expression();
-        flow.equalityOp_end(expr, nullExpr, _Type('Null'), notEqual: false);
-        flow.ifStatement_thenBegin(expr);
-        expect(flow.isReachable, true);
-        expect(flow.promotedType(x), isNull);
-        flow.ifStatement_elseBegin();
-        expect(flow.isReachable, true);
-        expect(flow.promotedType(x).type, 'int');
-        flow.ifStatement_end(true);
-      });
+      var h = Harness();
+      var x = Var('x', 'int?');
+      h.run([
+        declare(x, initialized: true),
+        if_(x.read.eq(nullLiteral), [
+          checkReachable(true),
+          checkNotPromoted(x),
+        ], [
+          checkReachable(true),
+          checkPromoted(x, 'int'),
+        ]),
+      ]);
     });
 
     test('equalityOp(x == null) when x is non-nullable', () {
-      var h = _Harness();
-      var x = h.addVar('x', 'int');
-      h.run((flow) {
-        h.declare(x, initialized: true);
-        flow.ifStatement_conditionBegin();
-        var varExpr = _Expression();
-        flow.variableRead(varExpr, x);
-        flow.equalityOp_rightBegin(varExpr, _Type('int'));
-        var nullExpr = _Expression();
-        flow.nullLiteral(nullExpr);
-        var expr = _Expression();
-        flow.equalityOp_end(expr, nullExpr, _Type('Null'), notEqual: false);
-        flow.ifStatement_thenBegin(expr);
-        expect(flow.isReachable, true);
-        expect(flow.promotedType(x), isNull);
-        flow.ifStatement_elseBegin();
-        expect(flow.isReachable, true);
-        expect(flow.promotedType(x), isNull);
-        flow.ifStatement_end(true);
-      });
+      var h = Harness();
+      var x = Var('x', 'int');
+      h.run([
+        declare(x, initialized: true),
+        if_(x.read.eq(nullLiteral), [
+          checkReachable(true),
+          checkNotPromoted(x),
+        ], [
+          checkReachable(true),
+          checkNotPromoted(x),
+        ])
+      ]);
     });
 
     test('equalityOp(null != x) promotes true branch', () {
-      var h = _Harness();
-      var x = h.addVar('x', 'int?');
-      h.run((flow) {
-        h.declare(x, initialized: true);
-        flow.ifStatement_conditionBegin();
-        var nullExpr = _Expression();
-        flow.nullLiteral(nullExpr);
-        flow.equalityOp_rightBegin(nullExpr, _Type('Null'));
-        var varExpr = _Expression();
-        flow.variableRead(varExpr, x);
-        var expr = _Expression();
-        flow.equalityOp_end(expr, varExpr, _Type('int?'), notEqual: true);
-        flow.ifStatement_thenBegin(expr);
-        expect(flow.promotedType(x).type, 'int');
-        flow.ifStatement_elseBegin();
-        expect(flow.promotedType(x), isNull);
-        flow.ifStatement_end(true);
-      });
+      var h = Harness();
+      var x = Var('x', 'int?');
+      h.run([
+        declare(x, initialized: true),
+        if_(nullLiteral.notEq(x.read), [
+          checkPromoted(x, 'int'),
+        ], [
+          checkNotPromoted(x),
+        ]),
+      ]);
     });
 
     test('equalityOp(<null expr> != x) does not promote', () {
-      var h = _Harness();
-      var x = h.addVar('x', 'int?');
-      h.run((flow) {
-        h.declare(x, initialized: true);
-        flow.ifStatement_conditionBegin();
-        var nullExpr = _Expression();
-        flow.equalityOp_rightBegin(nullExpr, _Type('Null'));
-        var varExpr = _Expression();
-        flow.variableRead(varExpr, x);
-        var expr = _Expression();
-        flow.equalityOp_end(expr, varExpr, _Type('int?'), notEqual: true);
-        flow.ifStatement_thenBegin(expr);
-        expect(flow.promotedType(x), isNull);
-        flow.ifStatement_elseBegin();
-        expect(flow.promotedType(x), isNull);
-        flow.ifStatement_end(true);
-      });
+      var h = Harness();
+      var x = Var('x', 'int?');
+      h.run([
+        declare(x, initialized: true),
+        if_(expr('Null').notEq(x.read), [
+          checkNotPromoted(x),
+        ], [
+          checkNotPromoted(x),
+        ]),
+      ]);
     });
 
     test('equalityOp(null == x) promotes false branch', () {
-      var h = _Harness();
-      var x = h.addVar('x', 'int?');
-      h.run((flow) {
-        h.declare(x, initialized: true);
-        flow.ifStatement_conditionBegin();
-        var nullExpr = _Expression();
-        flow.nullLiteral(nullExpr);
-        flow.equalityOp_rightBegin(nullExpr, _Type('Null'));
-        var varExpr = _Expression();
-        flow.variableRead(varExpr, x);
-        var expr = _Expression();
-        flow.equalityOp_end(expr, varExpr, _Type('int?'), notEqual: false);
-        flow.ifStatement_thenBegin(expr);
-        expect(flow.promotedType(x), isNull);
-        flow.ifStatement_elseBegin();
-        expect(flow.promotedType(x).type, 'int');
-        flow.ifStatement_end(true);
-      });
+      var h = Harness();
+      var x = Var('x', 'int?');
+      h.run([
+        declare(x, initialized: true),
+        if_(nullLiteral.eq(x.read), [
+          checkNotPromoted(x),
+        ], [
+          checkPromoted(x, 'int'),
+        ]),
+      ]);
     });
 
     test('equalityOp(null == null) equivalent to true', () {
-      var h = _Harness();
-      h.run((flow) {
-        flow.ifStatement_conditionBegin();
-        var null1 = _Expression();
-        flow.equalityOp_rightBegin(null1, _Type('Null'));
-        var null2 = _Expression();
-        var expr = _Expression();
-        flow.equalityOp_end(expr, null2, _Type('Null'));
-        flow.ifStatement_thenBegin(expr);
-        expect(flow.isReachable, true);
-        flow.ifStatement_elseBegin();
-        expect(flow.isReachable, false);
-        flow.ifStatement_end(true);
-      });
+      var h = Harness();
+      h.run([
+        if_(expr('Null').eq(expr('Null')), [
+          checkReachable(true),
+        ], [
+          checkReachable(false),
+        ]),
+      ]);
     });
 
     test('equalityOp(null != null) equivalent to false', () {
-      var h = _Harness();
-      h.run((flow) {
-        flow.ifStatement_conditionBegin();
-        var null1 = _Expression();
-        flow.equalityOp_rightBegin(null1, _Type('Null'));
-        var null2 = _Expression();
-        var expr = _Expression();
-        flow.equalityOp_end(expr, null2, _Type('Null'), notEqual: true);
-        flow.ifStatement_thenBegin(expr);
-        expect(flow.isReachable, false);
-        flow.ifStatement_elseBegin();
-        expect(flow.isReachable, true);
-        flow.ifStatement_end(true);
-      });
+      var h = Harness();
+      h.run([
+        if_(expr('Null').notEq(expr('Null')), [
+          checkReachable(false),
+        ], [
+          checkReachable(true),
+        ]),
+      ]);
     });
 
     test('equalityOp(null == non-null) is not equivalent to false', () {
-      var h = _Harness();
-      h.run((flow) {
-        flow.ifStatement_conditionBegin();
-        var null1 = _Expression();
-        flow.equalityOp_rightBegin(null1, _Type('Null'));
-        var null2 = _Expression();
-        var expr = _Expression();
-        flow.equalityOp_end(expr, null2, _Type('int'));
-        flow.ifStatement_thenBegin(expr);
-        expect(flow.isReachable, true);
-        flow.ifStatement_elseBegin();
-        expect(flow.isReachable, true);
-        flow.ifStatement_end(true);
-      });
+      var h = Harness();
+      h.run([
+        if_(expr('Null').eq(expr('int')), [
+          checkReachable(true),
+        ], [
+          checkReachable(true),
+        ]),
+      ]);
     });
 
     test('equalityOp(null != non-null) is not equivalent to true', () {
-      var h = _Harness();
-      h.run((flow) {
-        flow.ifStatement_conditionBegin();
-        var null1 = _Expression();
-        flow.equalityOp_rightBegin(null1, _Type('Null'));
-        var null2 = _Expression();
-        var expr = _Expression();
-        flow.equalityOp_end(expr, null2, _Type('int'), notEqual: true);
-        flow.ifStatement_thenBegin(expr);
-        expect(flow.isReachable, true);
-        flow.ifStatement_elseBegin();
-        expect(flow.isReachable, true);
-        flow.ifStatement_end(true);
-      });
+      var h = Harness();
+      h.run([
+        if_(expr('Null').notEq(expr('int')), [
+          checkReachable(true),
+        ], [
+          checkReachable(true),
+        ]),
+      ]);
     });
 
     test('equalityOp(non-null == null) is not equivalent to false', () {
-      var h = _Harness();
-      h.run((flow) {
-        flow.ifStatement_conditionBegin();
-        var null1 = _Expression();
-        flow.equalityOp_rightBegin(null1, _Type('int'));
-        var null2 = _Expression();
-        var expr = _Expression();
-        flow.equalityOp_end(expr, null2, _Type('Null'));
-        flow.ifStatement_thenBegin(expr);
-        expect(flow.isReachable, true);
-        flow.ifStatement_elseBegin();
-        expect(flow.isReachable, true);
-        flow.ifStatement_end(true);
-      });
+      var h = Harness();
+      h.run([
+        if_(expr('int').eq(expr('Null')), [
+          checkReachable(true),
+        ], [
+          checkReachable(true),
+        ]),
+      ]);
     });
 
     test('equalityOp(non-null != null) is not equivalent to true', () {
-      var h = _Harness();
-      h.run((flow) {
-        flow.ifStatement_conditionBegin();
-        var null1 = _Expression();
-        flow.equalityOp_rightBegin(null1, _Type('int'));
-        var null2 = _Expression();
-        var expr = _Expression();
-        flow.equalityOp_end(expr, null2, _Type('Null'), notEqual: true);
-        flow.ifStatement_thenBegin(expr);
-        expect(flow.isReachable, true);
-        flow.ifStatement_elseBegin();
-        expect(flow.isReachable, true);
-        flow.ifStatement_end(true);
-      });
+      var h = Harness();
+      h.run([
+        if_(expr('int').notEq(expr('Null')), [
+          checkReachable(true),
+        ], [
+          checkReachable(true),
+        ]),
+      ]);
     });
 
     test('conditionEqNull() does not promote write-captured vars', () {
-      var h = _Harness();
-      var x = h.addVar('x', 'int?');
-      var functionNode = _Node();
-      h.assignedVariables(
-          (vars) => vars.function(functionNode, () => vars.write(x)));
-      h.run((flow) {
-        h.declare(x, initialized: true);
-        h.if_(h.notNull(x, _Type('int?')), () {
-          expect(flow.promotedType(x).type, 'int');
-        });
-        h.function(functionNode, () {
-          flow.write(x, _Type('int?'));
-        });
-        h.if_(h.notNull(x, _Type('int?')), () {
-          expect(flow.promotedType(x), isNull);
-        });
-      });
+      var h = Harness();
+      var x = Var('x', 'int?');
+      h.run([
+        declare(x, initialized: true),
+        if_(x.read.notEq(nullLiteral), [
+          checkPromoted(x, 'int'),
+        ]),
+        localFunction([
+          x.write(expr('int?')).stmt,
+        ]),
+        if_(x.read.notEq(nullLiteral), [
+          checkNotPromoted(x),
+        ]),
+      ]);
     });
 
     test('doStatement_bodyBegin() un-promotes', () {
-      var h = _Harness();
-      var x = h.addVar('x', 'int?');
-      var doStatement = _Statement();
-      h.assignedVariables(
-          (vars) => vars.nest(doStatement, () => vars.write(x)));
-      h.run((flow) {
-        h.declare(x, initialized: true);
-        h.promote(x, 'int');
-        expect(flow.promotedType(x).type, 'int');
-        flow.doStatement_bodyBegin(doStatement);
-        expect(flow.promotedType(x), isNull);
-        flow.doStatement_conditionBegin();
-        flow.doStatement_end(_Expression());
-      });
+      var h = Harness();
+      var x = Var('x', 'int?');
+      h.run([
+        declare(x, initialized: true),
+        x.read.as_('int').stmt,
+        checkPromoted(x, 'int'),
+        branchTarget((t) => do_([
+              checkNotPromoted(x),
+              x.write(expr('Null')).stmt,
+            ], expr('bool'))),
+      ]);
     });
 
     test('doStatement_bodyBegin() handles write captures in the loop', () {
-      var h = _Harness();
-      var x = h.addVar('x', 'int?');
-      var doStatement = _Statement();
-      var functionNode = _Node();
-      h.assignedVariables((vars) => vars.nest(
-          doStatement, () => vars.function(functionNode, () => vars.write(x))));
-      h.run((flow) {
-        h.declare(x, initialized: true);
-        flow.doStatement_bodyBegin(doStatement);
-        h.promote(x, 'int');
-        // The promotion should have no effect, because the second time through
-        // the loop, x has been write-captured.
-        expect(flow.promotedType(x), isNull);
-        h.function(functionNode, () {
-          flow.write(x, _Type('int?'));
-        });
-        flow.doStatement_conditionBegin();
-        flow.doStatement_end(_Expression());
-      });
+      var h = Harness();
+      var x = Var('x', 'int?');
+      h.run([
+        declare(x, initialized: true),
+        do_([
+          x.read.as_('int').stmt,
+          // The promotion should have no effect, because the second time
+          // through the loop, x has been write-captured.
+          checkNotPromoted(x),
+          localFunction([
+            x.write(expr('int?')).stmt,
+          ]),
+        ], expr('bool')),
+      ]);
     });
 
     test('doStatement_conditionBegin() joins continue state', () {
-      var h = _Harness();
-      var x = h.addVar('x', 'int?');
-      var stmt = _Statement();
-      h.assignedVariables((vars) => vars.nest(stmt, () {}));
-      h.run((flow) {
-        h.declare(x, initialized: true);
-        flow.doStatement_bodyBegin(stmt);
-        h.if_(h.notNull(x, _Type('int?')), () {
-          flow.handleContinue(stmt);
-        });
-        flow.handleExit();
-        expect(flow.isReachable, false);
-        expect(flow.promotedType(x), isNull);
-        flow.doStatement_conditionBegin();
-        expect(flow.isReachable, true);
-        expect(flow.promotedType(x).type, 'int');
-        flow.doStatement_end(_Expression());
-      });
+      var h = Harness();
+      var x = Var('x', 'int?');
+      h.run([
+        declare(x, initialized: true),
+        branchTarget((t) => do_(
+                [
+                  if_(x.read.notEq(nullLiteral), [
+                    continue_(t),
+                  ]),
+                  return_(),
+                  checkReachable(false),
+                  checkNotPromoted(x),
+                ],
+                block([
+                  checkReachable(true),
+                  checkPromoted(x, 'int'),
+                ]).thenExpr(expr('bool')))),
+      ]);
     });
 
     test('doStatement_end() promotes', () {
-      var h = _Harness();
-      var x = h.addVar('x', 'int?');
-      var stmt = _Statement();
-      h.assignedVariables((vars) => vars.nest(stmt, () {}));
-      h.run((flow) {
-        h.declare(x, initialized: true);
-        flow.doStatement_bodyBegin(stmt);
-        flow.doStatement_conditionBegin();
-        expect(flow.promotedType(x), isNull);
-        flow.doStatement_end(h.eqNull(x, _Type('int?'))());
-        expect(flow.promotedType(x).type, 'int');
-      });
+      var h = Harness();
+      var x = Var('x', 'int?');
+      h.run([
+        declare(x, initialized: true),
+        branchTarget((t) =>
+            do_([], checkNotPromoted(x).thenExpr(x.read.eq(nullLiteral)))),
+        checkPromoted(x, 'int'),
+      ]);
     });
 
     test('finish checks proper nesting', () {
-      var h = _Harness();
-      var expr = _Expression();
-      var flow = h.createFlow();
+      var h = Harness();
+      var e = expr('Null');
+      var flow = FlowAnalysis<Node, Statement, Expression, Var, Type>(
+          h, AssignedVariables<Node, Var>());
       flow.ifStatement_conditionBegin();
-      flow.ifStatement_thenBegin(expr);
+      flow.ifStatement_thenBegin(e);
       expect(() => flow.finish(), _asserts);
     });
 
     test('for_conditionBegin() un-promotes', () {
-      var h = _Harness();
-      var x = h.addVar('x', 'int?');
-      var forStatement = _Statement();
-      h.assignedVariables(
-          (vars) => vars.nest(forStatement, () => vars.write(x)));
-      h.run((flow) {
-        h.declare(x, initialized: true);
-        h.promote(x, 'int');
-        expect(flow.promotedType(x).type, 'int');
-        flow.for_conditionBegin(forStatement);
-        expect(flow.promotedType(x), isNull);
-        flow.for_bodyBegin(_Statement(), _Expression());
-        flow.write(x, _Type('int?'));
-        flow.for_updaterBegin();
-        flow.for_end();
-      });
+      var h = Harness();
+      var x = Var('x', 'int?');
+      h.run([
+        declare(x, initialized: true),
+        x.read.as_('int').stmt,
+        checkPromoted(x, 'int'),
+        for_(null, checkNotPromoted(x).thenExpr(expr('bool')), null, [
+          x.write(expr('int?')).stmt,
+        ]),
+      ]);
     });
 
     test('for_conditionBegin() handles write captures in the loop', () {
-      var h = _Harness();
-      var x = h.addVar('x', 'int?');
-      var forStatement = _Statement();
-      var functionNode = _Node();
-      h.assignedVariables((vars) => vars.nest(forStatement,
-          () => vars.function(functionNode, () => vars.write(x))));
-      h.run((flow) {
-        h.declare(x, initialized: true);
-        h.promote(x, 'int');
-        expect(flow.promotedType(x).type, 'int');
-        flow.for_conditionBegin(forStatement);
-        h.promote(x, 'int');
-        expect(flow.promotedType(x), isNull);
-        h.function(functionNode, () {
-          flow.write(x, _Type('int?'));
-        });
-        flow.for_bodyBegin(_Statement(), _Expression());
-        flow.for_updaterBegin();
-        flow.for_end();
-      });
+      var h = Harness();
+      var x = Var('x', 'int?');
+      h.run([
+        declare(x, initialized: true),
+        x.read.as_('int').stmt,
+        checkPromoted(x, 'int'),
+        for_(
+            null,
+            block([
+              x.read.as_('int').stmt,
+              checkNotPromoted(x),
+              localFunction([
+                x.write(expr('int?')).stmt,
+              ]),
+            ]).thenExpr(expr('bool')),
+            null,
+            []),
+      ]);
     });
 
     test('for_conditionBegin() handles not-yet-seen variables', () {
-      var h = _Harness();
-      var x = h.addVar('x', 'int?');
-      var y = h.addVar('y', 'int?');
-      var forStatement = _Statement();
-      h.assignedVariables(
-          (vars) => vars.nest(forStatement, () => vars.write(x)));
-      h.run((flow) {
-        h.declare(y, initialized: true);
-        h.promote(y, 'int');
-        flow.for_conditionBegin(forStatement);
-        flow.declare(x, true);
-        flow.for_bodyBegin(_Statement(), _Expression());
-        flow.for_updaterBegin();
-        flow.for_end();
-      });
+      var h = Harness();
+      var x = Var('x', 'int?');
+      var y = Var('y', 'int?');
+      h.run([
+        declare(y, initialized: true),
+        y.read.as_('int').stmt,
+        for_(null, declare(x, initialized: true).thenExpr(expr('bool')), null, [
+          x.write(expr('Null')).stmt,
+        ]),
+      ]);
     });
 
     test('for_bodyBegin() handles empty condition', () {
-      var h = _Harness();
-      var stmt = _Statement();
-      h.assignedVariables((vars) => vars.nest(stmt, () {}));
-      h.run((flow) {
-        flow.for_conditionBegin(stmt);
-        flow.for_bodyBegin(stmt, null);
-        flow.for_updaterBegin();
-        expect(flow.isReachable, isTrue);
-        flow.for_end();
-        expect(flow.isReachable, isFalse);
-      });
+      var h = Harness();
+      h.run([
+        for_(null, null, checkReachable(true).thenExpr(expr('Null')), []),
+        checkReachable(false),
+      ]);
     });
 
     test('for_bodyBegin() promotes', () {
-      var h = _Harness();
-      var x = h.addVar('x', 'int?');
-      var stmt = _Statement();
-      h.assignedVariables((vars) => vars.nest(stmt, () {}));
-      h.run((flow) {
-        h.declare(x, initialized: true);
-        flow.for_conditionBegin(stmt);
-        flow.for_bodyBegin(stmt, h.notNull(x, _Type('int?'))());
-        expect(flow.promotedType(x).type, 'int');
-        flow.for_updaterBegin();
-        flow.for_end();
-      });
+      var h = Harness();
+      var x = Var('x', 'int?');
+      h.run([
+        for_(declare(x, initialized: true), x.read.notEq(nullLiteral), null, [
+          checkPromoted(x, 'int'),
+        ]),
+      ]);
     });
 
     test('for_bodyBegin() can be used with a null statement', () {
       // This is needed for collection elements that are for-loops.
-      var h = _Harness();
-      var x = h.addVar('x', 'int?');
-      var node = _Node();
-      h.assignedVariables((vars) => vars.nest(node, () {}));
-      h.run((flow) {
-        h.declare(x, initialized: true);
-        flow.for_conditionBegin(node);
-        flow.for_bodyBegin(null, h.notNull(x, _Type('int?'))());
-        flow.for_updaterBegin();
-        flow.for_end();
-      });
+      var h = Harness();
+      var x = Var('x', 'int?');
+      h.run([
+        for_(declare(x, initialized: true), x.read.notEq(nullLiteral), null, [],
+            forCollection: true),
+      ]);
     });
 
     test('for_updaterBegin() joins current and continue states', () {
       // To test that the states are properly joined, we have three variables:
       // x, y, and z.  We promote x and y in the continue path, and x and z in
       // the current path.  Inside the updater, only x should be promoted.
-      var h = _Harness();
-      var x = h.addVar('x', 'int?');
-      var y = h.addVar('y', 'int?');
-      var z = h.addVar('z', 'int?');
-      var stmt = _Statement();
-      h.assignedVariables((vars) => vars.nest(stmt, () {}));
-      h.run((flow) {
-        h.declare(x, initialized: true);
-        h.declare(y, initialized: true);
-        h.declare(z, initialized: true);
-        flow.for_conditionBegin(stmt);
-        flow.for_bodyBegin(stmt, h.expr());
-        h.if_(h.expr, () {
-          h.promote(x, 'int');
-          h.promote(y, 'int');
-          flow.handleContinue(stmt);
-        });
-        h.promote(x, 'int');
-        h.promote(z, 'int');
-        flow.for_updaterBegin();
-        expect(flow.promotedType(x).type, 'int');
-        expect(flow.promotedType(y), isNull);
-        expect(flow.promotedType(z), isNull);
-        flow.for_end();
-      });
+      var h = Harness();
+      var x = Var('x', 'int?');
+      var y = Var('y', 'int?');
+      var z = Var('z', 'int?');
+      h.run([
+        declare(x, initialized: true),
+        declare(y, initialized: true),
+        declare(z, initialized: true),
+        branchTarget((t) => for_(
+                null,
+                expr('bool'),
+                block([
+                  checkPromoted(x, 'int'),
+                  checkNotPromoted(y),
+                  checkNotPromoted(z),
+                ]).thenExpr(expr('Null')),
+                [
+                  if_(expr('bool'), [
+                    x.read.as_('int').stmt,
+                    y.read.as_('int').stmt,
+                    continue_(t),
+                  ]),
+                  x.read.as_('int').stmt,
+                  z.read.as_('int').stmt,
+                ])),
+      ]);
     });
 
     test('for_end() joins break and condition-false states', () {
       // To test that the states are properly joined, we have three variables:
       // x, y, and z.  We promote x and y in the break path, and x and z in the
       // condition-false path.  After the loop, only x should be promoted.
-      var h = _Harness();
-      var x = h.addVar('x', 'int?');
-      var y = h.addVar('y', 'int?');
-      var z = h.addVar('z', 'int?');
-      var stmt = _Statement();
-      h.assignedVariables((vars) => vars.nest(stmt, () {}));
-      h.run((flow) {
-        h.declare(x, initialized: true);
-        h.declare(y, initialized: true);
-        h.declare(z, initialized: true);
-        flow.for_conditionBegin(stmt);
-        flow.for_bodyBegin(stmt,
-            h.or(h.eqNull(x, _Type('int?')), h.eqNull(z, _Type('int?')))());
-        h.if_(h.expr, () {
-          h.promote(x, 'int');
-          h.promote(y, 'int');
-          flow.handleBreak(stmt);
-        });
-        flow.for_updaterBegin();
-        flow.for_end();
-        expect(flow.promotedType(x).type, 'int');
-        expect(flow.promotedType(y), isNull);
-        expect(flow.promotedType(z), isNull);
-      });
+      var h = Harness();
+      var x = Var('x', 'int?');
+      var y = Var('y', 'int?');
+      var z = Var('z', 'int?');
+      h.run([
+        declare(x, initialized: true),
+        declare(y, initialized: true),
+        declare(z, initialized: true),
+        branchTarget((t) => for_(
+                null, x.read.eq(nullLiteral).or(z.read.eq(nullLiteral)), null, [
+              if_(expr('bool'), [
+                x.read.as_('int').stmt,
+                y.read.as_('int').stmt,
+                break_(t),
+              ]),
+            ])),
+        checkPromoted(x, 'int'),
+        checkNotPromoted(y),
+        checkNotPromoted(z),
+      ]);
     });
 
     test('forEach_bodyBegin() un-promotes', () {
-      var h = _Harness();
-      var x = h.addVar('x', 'int?');
-      var forStatement = _Statement();
-      h.assignedVariables(
-          (vars) => vars.nest(forStatement, () => vars.write(x)));
-      h.run((flow) {
-        h.declare(x, initialized: true);
-        h.promote(x, 'int');
-        expect(flow.promotedType(x).type, 'int');
-        flow.forEach_bodyBegin(forStatement, null, _Type('int?'));
-        expect(flow.promotedType(x), isNull);
-        flow.write(x, _Type('int?'));
-        flow.forEach_end();
-      });
+      var h = Harness();
+      var x = Var('x', 'int?');
+      h.run([
+        declare(x, initialized: true),
+        x.read.as_('int').stmt,
+        checkPromoted(x, 'int'),
+        forEachWithNonVariable(expr('List<int?>'), [
+          checkNotPromoted(x),
+          x.write(expr('int?')).stmt,
+        ]),
+      ]);
     });
 
     test('forEach_bodyBegin() handles write captures in the loop', () {
-      var h = _Harness();
-      var x = h.addVar('x', 'int?');
-      var forStatement = _Statement();
-      var functionNode = _Node();
-      h.assignedVariables((vars) => vars.nest(forStatement,
-          () => vars.function(functionNode, () => vars.write(x))));
-      h.run((flow) {
-        h.declare(x, initialized: true);
-        h.promote(x, 'int');
-        expect(flow.promotedType(x).type, 'int');
-        flow.forEach_bodyBegin(forStatement, null, _Type('int?'));
-        h.promote(x, 'int');
-        expect(flow.promotedType(x), isNull);
-        h.function(functionNode, () {
-          flow.write(x, _Type('int?'));
-        });
-        flow.forEach_end();
-      });
+      var h = Harness();
+      var x = Var('x', 'int?');
+      h.run([
+        declare(x, initialized: true),
+        x.read.as_('int').stmt,
+        checkPromoted(x, 'int'),
+        forEachWithNonVariable(expr('List<int?>'), [
+          x.read.as_('int').stmt,
+          checkNotPromoted(x),
+          localFunction([
+            x.write(expr('int?')).stmt,
+          ]),
+        ]),
+      ]);
     });
 
     test('forEach_bodyBegin() writes to loop variable', () {
-      var h = _Harness();
-      var x = h.addVar('x', 'int?');
-      var forStatement = _Statement();
-      h.assignedVariables(
-          (vars) => vars.nest(forStatement, () => vars.write(x)));
-      h.run((flow) {
-        h.declare(x, initialized: false);
-        expect(flow.isAssigned(x), false);
-        flow.forEach_bodyBegin(forStatement, x, _Type('int?'));
-        expect(flow.isAssigned(x), true);
-        flow.forEach_end();
-        expect(flow.isAssigned(x), false);
-      });
+      var h = Harness();
+      var x = Var('x', 'int?');
+      h.run([
+        declare(x, initialized: false),
+        checkAssigned(x, false),
+        forEachWithVariableSet(x, expr('List<int?>'), [
+          checkAssigned(x, true),
+        ]),
+        checkAssigned(x, false),
+      ]);
     });
 
     test('forEach_bodyBegin() pushes conservative join state', () {
-      var h = _Harness();
-      var x = h.addVar('x', 'int');
-      var forStatement = _Statement();
-      h.assignedVariables(
-          (vars) => vars.nest(forStatement, () => vars.write(x)));
-      h.run((flow) {
-        h.declare(x, initialized: false);
-        expect(flow.isUnassigned(x), true);
-        flow.forEach_bodyBegin(forStatement, null, _Type('int'));
-        // Since a write to x occurs somewhere in the loop, x should no longer
-        // be considered unassigned.
-        expect(flow.isUnassigned(x), false);
-        flow.handleBreak(forStatement);
-        flow.write(x, _Type('int'));
-        flow.forEach_end();
+      var h = Harness();
+      var x = Var('x', 'int');
+      h.run([
+        declare(x, initialized: false),
+        checkUnassigned(x, true),
+        branchTarget((t) => forEachWithNonVariable(expr('List<int>'), [
+              // Since a write to x occurs somewhere in the loop, x should no
+              // longer be considered unassigned.
+              checkUnassigned(x, false),
+              break_(t), x.write(expr('int')).stmt,
+            ])),
         // Even though the write to x is unreachable (since it occurs after a
         // break), x should still be considered "possibly assigned" because of
         // the conservative join done at the top of the loop.
-        expect(flow.isUnassigned(x), false);
-      });
+        checkUnassigned(x, false),
+      ]);
     });
 
     test('forEach_end() restores state before loop', () {
-      var h = _Harness();
-      var x = h.addVar('x', 'int?');
-      var stmt = _Statement();
-      h.assignedVariables((vars) => vars.nest(stmt, () {}));
-      h.run((flow) {
-        h.declare(x, initialized: true);
-        flow.forEach_bodyBegin(stmt, null, _Type('int?'));
-        h.promote(x, 'int');
-        expect(flow.promotedType(x).type, 'int');
-        flow.forEach_end();
-        expect(flow.promotedType(x), isNull);
-      });
+      var h = Harness();
+      var x = Var('x', 'int?');
+      h.run([
+        declare(x, initialized: true),
+        forEachWithNonVariable(expr('List<int?>'), [
+          x.read.as_('int').stmt,
+          checkPromoted(x, 'int'),
+        ]),
+        checkNotPromoted(x),
+      ]);
     });
 
     test('functionExpression_begin() cancels promotions of self-captured vars',
         () {
-      var h = _Harness();
-      var x = h.addVar('x', 'int?');
-      var y = h.addVar('y', 'int?');
-      var functionNode = _Node();
-      h.assignedVariables(
-          (vars) => vars.function(functionNode, () => vars.write(x)));
-      h.run((flow) {
-        h.declare(x, initialized: true);
-        h.declare(y, initialized: true);
-        h.promote(x, 'int');
-        h.promote(y, 'int');
-        expect(flow.promotedType(x).type, 'int');
-        expect(flow.promotedType(y).type, 'int');
-        flow.functionExpression_begin(functionNode);
-        // x is unpromoted within the local function
-        expect(flow.promotedType(x), isNull);
-        expect(flow.promotedType(y).type, 'int');
-        flow.write(x, _Type('int?'));
-        h.promote(x, 'int');
-        flow.functionExpression_end();
+      var h = Harness();
+      var x = Var('x', 'int?');
+      var y = Var('y', 'int?');
+      h.run([
+        declare(x, initialized: true),
+        declare(y, initialized: true),
+        x.read.as_('int').stmt,
+        y.read.as_('int').stmt,
+        checkPromoted(x, 'int'),
+        checkPromoted(y, 'int'),
+        localFunction([
+          // x is unpromoted within the local function
+          checkNotPromoted(x), checkPromoted(y, 'int'),
+          x.write(expr('int?')).stmt, x.read.as_('int').stmt,
+        ]),
         // x is unpromoted after the local function too
-        expect(flow.promotedType(x), isNull);
-        expect(flow.promotedType(y).type, 'int');
-      });
+        checkNotPromoted(x), checkPromoted(y, 'int'),
+      ]);
     });
 
     test('functionExpression_begin() cancels promotions of other-captured vars',
         () {
-      var h = _Harness();
-      var x = h.addVar('x', 'int?');
-      var y = h.addVar('y', 'int?');
-      var functionNode1 = _Node();
-      var functionNode2 = _Node();
-      h.assignedVariables((vars) {
-        vars.function(functionNode1, () {});
-        vars.function(functionNode2, () => vars.write(x));
-      });
-      h.run((flow) {
-        h.declare(x, initialized: true);
-        h.declare(y, initialized: true);
-        h.promote(x, 'int');
-        h.promote(y, 'int');
-        expect(flow.promotedType(x).type, 'int');
-        expect(flow.promotedType(y).type, 'int');
-        flow.functionExpression_begin(functionNode1);
-        // x is unpromoted within the local function, because the write
-        // might have been captured by the time the local function executes.
-        expect(flow.promotedType(x), isNull);
-        expect(flow.promotedType(y).type, 'int');
-        // And any effort to promote x fails, because there is no way of knowing
-        // when the captured write might occur.
-        h.promote(x, 'int');
-        expect(flow.promotedType(x), isNull);
-        expect(flow.promotedType(y).type, 'int');
-        flow.functionExpression_end();
+      var h = Harness();
+      var x = Var('x', 'int?');
+      var y = Var('y', 'int?');
+      h.run([
+        declare(x, initialized: true), declare(y, initialized: true),
+        x.read.as_('int').stmt, y.read.as_('int').stmt,
+        checkPromoted(x, 'int'), checkPromoted(y, 'int'),
+        localFunction([
+          // x is unpromoted within the local function, because the write
+          // might have been captured by the time the local function executes.
+          checkNotPromoted(x), checkPromoted(y, 'int'),
+          // And any effort to promote x fails, because there is no way of
+          // knowing when the captured write might occur.
+          x.read.as_('int').stmt,
+          checkNotPromoted(x), checkPromoted(y, 'int'),
+        ]),
         // x is still promoted after the local function, though, because the
         // write hasn't been captured yet.
-        expect(flow.promotedType(x).type, 'int');
-        expect(flow.promotedType(y).type, 'int');
-        flow.functionExpression_begin(functionNode2);
-        // x is unpromoted inside this local function too.
-        expect(flow.promotedType(x), isNull);
-        expect(flow.promotedType(y).type, 'int');
-        flow.write(x, _Type('int?'));
-        flow.functionExpression_end();
+        checkPromoted(x, 'int'), checkPromoted(y, 'int'),
+        localFunction([
+          // x is unpromoted inside this local function too.
+          checkNotPromoted(x), checkPromoted(y, 'int'),
+          x.write(expr('int?')).stmt,
+        ]),
         // And since the second local function captured x, it remains
         // unpromoted.
-        expect(flow.promotedType(x), isNull);
-        expect(flow.promotedType(y).type, 'int');
-      });
+        checkNotPromoted(x), checkPromoted(y, 'int'),
+      ]);
     });
 
     test('functionExpression_begin() cancels promotions of written vars', () {
-      var h = _Harness();
-      var x = h.addVar('x', 'int?');
-      var y = h.addVar('y', 'int?');
-      var node = _Node();
-      h.assignedVariables((vars) {
-        vars.function(node, () {});
-        vars.write(x);
-      });
-      h.run((flow) {
-        h.declare(x, initialized: true);
-        h.declare(y, initialized: true);
-        h.promote(x, 'int');
-        h.promote(y, 'int');
-        expect(flow.promotedType(x).type, 'int');
-        expect(flow.promotedType(y).type, 'int');
-        flow.functionExpression_begin(node);
-        // x is unpromoted within the local function, because the write
-        // might have happened by the time the local function executes.
-        expect(flow.promotedType(x), isNull);
-        expect(flow.promotedType(y).type, 'int');
-        // But it can be re-promoted because the write isn't captured.
-        h.promote(x, 'int');
-        expect(flow.promotedType(x).type, 'int');
-        expect(flow.promotedType(y).type, 'int');
-        flow.functionExpression_end();
+      var h = Harness();
+      var x = Var('x', 'int?');
+      var y = Var('y', 'int?');
+      h.run([
+        declare(x, initialized: true), declare(y, initialized: true),
+        x.read.as_('int').stmt, y.read.as_('int').stmt,
+        checkPromoted(x, 'int'), checkPromoted(y, 'int'),
+        localFunction([
+          // x is unpromoted within the local function, because the write
+          // might have happened by the time the local function executes.
+          checkNotPromoted(x), checkPromoted(y, 'int'),
+          // But it can be re-promoted because the write isn't captured.
+          x.read.as_('int').stmt,
+          checkPromoted(x, 'int'), checkPromoted(y, 'int'),
+        ]),
         // x is still promoted after the local function, though, because the
         // write hasn't occurred yet.
-        expect(flow.promotedType(x).type, 'int');
-        expect(flow.promotedType(y).type, 'int');
-        flow.write(x, _Type('int?'));
+        checkPromoted(x, 'int'), checkPromoted(y, 'int'),
+        x.write(expr('int?')).stmt,
         // x is unpromoted now.
-        expect(flow.promotedType(x), isNull);
-        expect(flow.promotedType(y).type, 'int');
-      });
+        checkNotPromoted(x), checkPromoted(y, 'int'),
+      ]);
     });
 
     test('functionExpression_begin() handles not-yet-seen variables', () {
-      var h = _Harness();
-      var x = h.addVar('x', 'int?');
-      var functionNode = _Node();
-      h.assignedVariables(
-          (vars) => vars.function(functionNode, () => vars.write(x)));
-      h.run((flow) {
-        flow.functionExpression_begin(functionNode);
-        flow.functionExpression_end();
+      var h = Harness();
+      var x = Var('x', 'int?');
+      h.run([
+        localFunction([]),
         // x is declared after the local function, so the local function
         // cannot possibly write to x.
-        h.declare(x, initialized: true);
-        h.promote(x, 'int');
-        expect(flow.promotedType(x).type, 'int');
-      });
+        declare(x, initialized: true), x.read.as_('int').stmt,
+        checkPromoted(x, 'int'), x.write(expr('Null')).stmt,
+      ]);
     });
 
     test('functionExpression_begin() handles not-yet-seen write-captured vars',
         () {
-      var h = _Harness();
-      var x = h.addVar('x', 'int?');
-      var y = h.addVar('y', 'int?');
-      var functionNode1 = _Node();
-      var functionNode2 = _Node();
-      h.assignedVariables((vars) {
-        vars.function(functionNode1, () {});
-        vars.function(functionNode2, () => vars.write(x));
-      });
-      h.run((flow) {
-        h.declare(y, initialized: true);
-        h.promote(y, 'int');
-        flow.functionExpression_begin(functionNode1);
-        h.promote(x, 'int');
-        // Promotion should not occur, because x might be write-captured by the
-        // time this code is reached.
-        expect(flow.promotedType(x), isNull);
-        flow.functionExpression_end();
-        flow.functionExpression_begin(functionNode2);
-        h.declare(x, initialized: true);
-        flow.functionExpression_end();
-      });
+      var h = Harness();
+      var x = Var('x', 'int?');
+      var y = Var('y', 'int?');
+      h.run([
+        declare(y, initialized: true),
+        y.read.as_('int').stmt,
+        localFunction([
+          x.read.as_('int').stmt,
+          // Promotion should not occur, because x might be write-captured by
+          // the time this code is reached.
+          checkNotPromoted(x),
+        ]),
+        localFunction([
+          declare(x, initialized: true),
+          x.write(expr('Null')).stmt,
+        ]),
+      ]);
     });
 
     test(
         'functionExpression_end does not propagate "definitely unassigned" '
         'data', () {
-      var h = _Harness();
-      var x = h.addVar('x', 'int');
-      var functionNode = _Node();
-      h.assignedVariables((vars) {
-        vars.function(functionNode, () {});
-        vars.write(x);
-      });
-      h.run((flow) {
-        flow.declare(x, false);
-        expect(flow.isUnassigned(x), true);
-        flow.functionExpression_begin(functionNode);
-        // The function expression could be called at any time, so x might be
-        // assigned now.
-        expect(flow.isUnassigned(x), false);
-        flow.functionExpression_end();
+      var h = Harness();
+      var x = Var('x', 'int');
+      h.run([
+        declare(x, initialized: false),
+        checkUnassigned(x, true),
+        localFunction([
+          // The function expression could be called at any time, so x might
+          // be assigned now.
+          checkUnassigned(x, false),
+        ]),
         // But now that we are back outside the function expression, we once
         // again know that x is unassigned.
-        expect(flow.isUnassigned(x), true);
-        flow.write(x, _Type('int'));
-        expect(flow.isUnassigned(x), false);
-      });
+        checkUnassigned(x, true),
+        x.write(expr('int')).stmt,
+        checkUnassigned(x, false),
+      ]);
     });
 
     test('handleBreak handles deep nesting', () {
-      var h = _Harness();
-      var whileStatement = _Statement();
-      h.assignedVariables((vars) {
-        vars.nest(whileStatement, () {});
-      });
-      h.run((flow) {
-        flow.whileStatement_conditionBegin(whileStatement);
-        flow.whileStatement_bodyBegin(whileStatement, h.booleanLiteral(true)());
-        h.if_(h.expr, () {
-          h.if_(h.expr, () {
-            flow.handleBreak(whileStatement);
-          });
-        });
-        flow.handleExit();
-        expect(flow.isReachable, false);
-        flow.whileStatement_end();
-        expect(flow.isReachable, true);
-      });
+      var h = Harness();
+      h.run([
+        branchTarget((t) => while_(booleanLiteral(true), [
+              if_(expr('bool'), [
+                if_(expr('bool'), [
+                  break_(t),
+                ]),
+              ]),
+              return_(),
+              checkReachable(false),
+            ])),
+        checkReachable(true),
+      ]);
     });
 
     test('handleBreak handles mixed nesting', () {
-      var h = _Harness();
-      var whileStatement = _Statement();
-      h.assignedVariables((vars) {
-        vars.nest(whileStatement, () {});
-      });
-      h.run((flow) {
-        flow.whileStatement_conditionBegin(whileStatement);
-        flow.whileStatement_bodyBegin(whileStatement, h.booleanLiteral(true)());
-        h.if_(h.expr, () {
-          h.if_(h.expr, () {
-            flow.handleBreak(whileStatement);
-          });
-          flow.handleBreak(whileStatement);
-        });
-        flow.handleBreak(whileStatement);
-        expect(flow.isReachable, false);
-        flow.whileStatement_end();
-        expect(flow.isReachable, true);
-      });
+      var h = Harness();
+      h.run([
+        branchTarget((t) => while_(booleanLiteral(true), [
+              if_(expr('bool'), [
+                if_(expr('bool'), [
+                  break_(t),
+                ]),
+                break_(t),
+              ]),
+              break_(t),
+              checkReachable(false),
+            ])),
+        checkReachable(true),
+      ]);
     });
 
     test('handleContinue handles deep nesting', () {
-      var h = _Harness();
-      var doStatement = _Statement();
-      h.assignedVariables((vars) {
-        vars.nest(doStatement, () {});
-      });
-      h.run((flow) {
-        flow.doStatement_bodyBegin(doStatement);
-        h.if_(h.expr, () {
-          h.if_(h.expr, () {
-            flow.handleContinue(doStatement);
-          });
-        });
-        flow.handleExit();
-        expect(flow.isReachable, false);
-        flow.doStatement_conditionBegin();
-        expect(flow.isReachable, true);
-        flow.doStatement_end(h.booleanLiteral(true)());
-        expect(flow.isReachable, false);
-      });
+      var h = Harness();
+      h.run([
+        branchTarget((t) => do_([
+              if_(expr('bool'), [
+                if_(expr('bool'), [
+                  continue_(t),
+                ]),
+              ]),
+              return_(),
+              checkReachable(false),
+            ], checkReachable(true).thenExpr(booleanLiteral(true)))),
+        checkReachable(false),
+      ]);
     });
 
     test('handleContinue handles mixed nesting', () {
-      var h = _Harness();
-      var doStatement = _Statement();
-      h.assignedVariables((vars) {
-        vars.nest(doStatement, () {});
-      });
-      h.run((flow) {
-        flow.doStatement_bodyBegin(doStatement);
-        h.if_(h.expr, () {
-          h.if_(h.expr, () {
-            flow.handleContinue(doStatement);
-          });
-          flow.handleContinue(doStatement);
-        });
-        flow.handleContinue(doStatement);
-        expect(flow.isReachable, false);
-        flow.doStatement_conditionBegin();
-        expect(flow.isReachable, true);
-        flow.doStatement_end(h.booleanLiteral(true)());
-        expect(flow.isReachable, false);
-      });
+      var h = Harness();
+      h.run([
+        branchTarget((t) => do_([
+              if_(expr('bool'), [
+                if_(expr('bool'), [
+                  continue_(t),
+                ]),
+                continue_(t),
+              ]),
+              continue_(t),
+              checkReachable(false),
+            ], checkReachable(true).thenExpr(booleanLiteral(true)))),
+        checkReachable(false),
+      ]);
     });
 
     test('ifNullExpression allows ensure guarding', () {
-      var h = _Harness();
-      var x = h.addVar('x', 'int?');
-      h.assignedVariables((vars) => vars.write(x));
-      h.run((flow) {
-        h.declare(x, initialized: true);
-        flow.ifNullExpression_rightBegin(h.variableRead(x)(), _Type('int?'));
-        expect(flow.isReachable, true);
-        flow.write(x, _Type('int'));
-        expect(flow.promotedType(x).type, 'int');
-        flow.ifNullExpression_end();
-        expect(flow.isReachable, true);
-        expect(flow.promotedType(x).type, 'int');
-      });
+      var h = Harness();
+      var x = Var('x', 'int?');
+      h.run([
+        declare(x, initialized: true),
+        x.read
+            .ifNull(block([
+              checkReachable(true),
+              x.write(expr('int')).stmt,
+              checkPromoted(x, 'int'),
+            ]).thenExpr(expr('int?')))
+            .thenStmt(block([
+              checkReachable(true),
+              checkPromoted(x, 'int'),
+            ]))
+            .stmt,
+      ]);
     });
 
     test('ifNullExpression allows promotion of tested var', () {
-      var h = _Harness();
-      var x = h.addVar('x', 'int?');
-      h.run((flow) {
-        h.declare(x, initialized: true);
-        flow.ifNullExpression_rightBegin(h.variableRead(x)(), _Type('int?'));
-        expect(flow.isReachable, true);
-        h.promote(x, 'int');
-        expect(flow.promotedType(x).type, 'int');
-        flow.ifNullExpression_end();
-        expect(flow.isReachable, true);
-        expect(flow.promotedType(x).type, 'int');
-      });
+      var h = Harness();
+      var x = Var('x', 'int?');
+      h.run([
+        declare(x, initialized: true),
+        x.read
+            .ifNull(block([
+              checkReachable(true),
+              x.read.as_('int').stmt,
+              checkPromoted(x, 'int'),
+            ]).thenExpr(expr('int?')))
+            .thenStmt(block([
+              checkReachable(true),
+              checkPromoted(x, 'int'),
+            ]))
+            .stmt,
+      ]);
     });
 
     test('ifNullExpression discards promotions unrelated to tested expr', () {
-      var h = _Harness();
-      var x = h.addVar('x', 'int?');
-      h.run((flow) {
-        h.declare(x, initialized: true);
-        flow.ifNullExpression_rightBegin(h.expr(), _Type('int?'));
-        expect(flow.isReachable, true);
-        h.promote(x, 'int');
-        expect(flow.promotedType(x).type, 'int');
-        flow.ifNullExpression_end();
-        expect(flow.isReachable, true);
-        expect(flow.promotedType(x), null);
-      });
+      var h = Harness();
+      var x = Var('x', 'int?');
+      h.run([
+        declare(x, initialized: true),
+        expr('int?')
+            .ifNull(block([
+              checkReachable(true),
+              x.read.as_('int').stmt,
+              checkPromoted(x, 'int'),
+            ]).thenExpr(expr('int?')))
+            .thenStmt(block([
+              checkReachable(true),
+              checkNotPromoted(x),
+            ]))
+            .stmt,
+      ]);
     });
 
     test('ifNullExpression does not detect when RHS is unreachable', () {
-      var h = _Harness();
-      h.run((flow) {
-        flow.ifNullExpression_rightBegin(h.expr(), _Type('int'));
-        expect(flow.isReachable, true);
-        flow.ifNullExpression_end();
-        expect(flow.isReachable, true);
-      });
+      var h = Harness();
+      h.run([
+        expr('int')
+            .ifNull(checkReachable(true).thenExpr(expr('int')))
+            .thenStmt(checkReachable(true))
+            .stmt,
+      ]);
     });
 
     test('ifNullExpression determines reachability correctly for `Null` type',
         () {
-      var h = _Harness();
-      h.run((flow) {
-        flow.ifNullExpression_rightBegin(h.expr(), _Type('Null'));
-        expect(flow.isReachable, true);
-        flow.ifNullExpression_end();
-        expect(flow.isReachable, true);
-      });
+      var h = Harness();
+      h.run([
+        expr('Null')
+            .ifNull(checkReachable(true).thenExpr(expr('Null')))
+            .thenStmt(checkReachable(true))
+            .stmt,
+      ]);
     });
 
     test('ifStatement with early exit promotes in unreachable code', () {
-      var h = _Harness();
-      var x = h.addVar('x', 'int?');
-      h.run((flow) {
-        h.declare(x, initialized: true);
-        flow.handleExit();
-        expect(flow.isReachable, false);
-        flow.ifStatement_conditionBegin();
-        flow.ifStatement_thenBegin(h.eqNull(x, _Type('int?'))());
-        flow.handleExit();
-        flow.ifStatement_end(false);
-        expect(flow.isReachable, false);
-        expect(flow.promotedType(x).type, 'int');
-      });
+      var h = Harness();
+      var x = Var('x', 'int?');
+      h.run([
+        declare(x, initialized: true),
+        return_(),
+        checkReachable(false),
+        if_(x.read.eq(nullLiteral), [
+          return_(),
+        ]),
+        checkReachable(false),
+        checkPromoted(x, 'int'),
+      ]);
     });
 
     test('ifStatement_end(false) keeps else branch if then branch exits', () {
-      var h = _Harness();
-      var x = h.addVar('x', 'int?');
-      h.run((flow) {
-        h.declare(x, initialized: true);
-        flow.ifStatement_conditionBegin();
-        flow.ifStatement_thenBegin(h.eqNull(x, _Type('int?'))());
-        flow.handleExit();
-        flow.ifStatement_end(false);
-        expect(flow.promotedType(x).type, 'int');
-      });
+      var h = Harness();
+      var x = Var('x', 'int?');
+      h.run([
+        declare(x, initialized: true),
+        if_(x.read.eq(nullLiteral), [
+          return_(),
+        ]),
+        checkPromoted(x, 'int'),
+      ]);
     });
 
     void _checkIs(String declaredType, String tryPromoteType,
         String expectedPromotedTypeThen, String expectedPromotedTypeElse,
         {bool inverted = false}) {
-      var h = _Harness();
-      var x = h.addVar('x', declaredType);
-      h.run((flow) {
-        h.declare(x, initialized: true);
-        flow.ifStatement_conditionBegin();
-        var read = _Expression();
-        flow.variableRead(read, x);
-        var expr = _Expression();
-        flow.isExpression_end(expr, read, inverted, _Type(tryPromoteType));
-        flow.ifStatement_thenBegin(expr);
-        expect(flow.isReachable, true);
-        if (expectedPromotedTypeThen == null) {
-          expect(flow.promotedType(x), isNull);
-        } else {
-          expect(flow.promotedType(x).type, expectedPromotedTypeThen);
-        }
-        flow.ifStatement_elseBegin();
-        expect(flow.isReachable, true);
-        if (expectedPromotedTypeElse == null) {
-          expect(flow.promotedType(x), isNull);
-        } else {
-          expect(flow.promotedType(x).type, expectedPromotedTypeElse);
-        }
-        flow.ifStatement_end(true);
-      });
+      var h = Harness();
+      var x = Var('x', declaredType);
+      h.run([
+        declare(x, initialized: true),
+        if_(x.read.is_(tryPromoteType, isInverted: inverted), [
+          checkReachable(true),
+          checkPromoted(x, expectedPromotedTypeThen),
+        ], [
+          checkReachable(true),
+          checkPromoted(x, expectedPromotedTypeElse),
+        ])
+      ]);
     }
 
     test('isExpression_end promotes to a subtype', () {
@@ -1265,755 +1010,681 @@
     });
 
     test('isExpression_end does nothing if applied to a non-variable', () {
-      var h = _Harness();
-      h.run((flow) {
-        flow.ifStatement_conditionBegin();
-        var subExpr = _Expression();
-        var expr = _Expression();
-        flow.isExpression_end(expr, subExpr, false, _Type('int'));
-        flow.ifStatement_thenBegin(expr);
-        expect(flow.isReachable, true);
-        flow.ifStatement_elseBegin();
-        expect(flow.isReachable, true);
-        flow.ifStatement_end(true);
-      });
+      var h = Harness();
+      h.run([
+        if_(expr('Null').is_('int'), [
+          checkReachable(true),
+        ], [
+          checkReachable(true),
+        ]),
+      ]);
     });
 
     test('isExpression_end does nothing if applied to a non-variable, inverted',
         () {
-      var h = _Harness();
-      h.run((flow) {
-        flow.ifStatement_conditionBegin();
-        var subExpr = _Expression();
-        var expr = _Expression();
-        flow.isExpression_end(expr, subExpr, true, _Type('int'));
-        flow.ifStatement_thenBegin(expr);
-        expect(flow.isReachable, true);
-        flow.ifStatement_elseBegin();
-        expect(flow.isReachable, true);
-        flow.ifStatement_end(true);
-      });
+      var h = Harness();
+      h.run([
+        if_(expr('Null').isNot('int'), [
+          checkReachable(true),
+        ], [
+          checkReachable(true),
+        ]),
+      ]);
     });
 
     test('isExpression_end() does not promote write-captured vars', () {
-      var h = _Harness();
-      var x = h.addVar('x', 'int?');
-      var functionNode = _Node();
-      h.assignedVariables(
-          (vars) => vars.function(functionNode, () => vars.write(x)));
-      h.run((flow) {
-        h.declare(x, initialized: true);
-        h.if_(h.isType(h.variableRead(x), 'int'), () {
-          expect(flow.promotedType(x).type, 'int');
-        });
-        h.function(functionNode, () {
-          flow.write(x, _Type('int?'));
-        });
-        h.if_(h.isType(h.variableRead(x), 'int'), () {
-          expect(flow.promotedType(x), isNull);
-        });
-      });
+      var h = Harness();
+      var x = Var('x', 'int?');
+      h.run([
+        declare(x, initialized: true),
+        if_(x.read.is_('int'), [
+          checkPromoted(x, 'int'),
+        ]),
+        localFunction([
+          x.write(expr('int?')).stmt,
+        ]),
+        if_(x.read.is_('int'), [
+          checkNotPromoted(x),
+        ]),
+      ]);
     });
 
     test('isExpression_end() handles not-yet-seen variables', () {
-      var h = _Harness();
-      var x = h.addVar('x', 'int?');
-      h.assignedVariables(
-          (vars) => vars.function(_Node(), () => vars.write(x)));
-      h.run((flow) {
-        h.if_(h.isType(h.variableRead(x), 'int'), () {
-          expect(flow.promotedType(x).type, 'int');
-        });
-        h.declare(x, initialized: true);
-      });
+      var h = Harness();
+      var x = Var('x', 'int?');
+      h.run([
+        if_(x.read.is_('int'), [
+          checkPromoted(x, 'int'),
+        ]),
+        declare(x, initialized: true),
+        localFunction([
+          x.write(expr('Null')).stmt,
+        ]),
+      ]);
     });
 
     test('labeledBlock without break', () {
-      var h = _Harness();
-      var x = h.addVar('x', 'int?');
-      var block = _Statement();
-      h.run((flow) {
-        h.declare(x, initialized: true);
-
-        h.ifIsNotType(x, 'int', () {
-          h.labeledBlock(block, () {
-            flow.handleExit();
-          });
-        });
-        expect(flow.promotedType(x).type, 'int');
-      });
+      var h = Harness();
+      var x = Var('x', 'int?');
+      h.run([
+        declare(x, initialized: true),
+        if_(x.read.isNot('int'), [
+          labeled(return_()),
+        ]),
+        checkPromoted(x, 'int'),
+      ]);
     });
 
     test('labeledBlock with break joins', () {
-      var h = _Harness();
-      var x = h.addVar('x', 'int?');
-      var block = _Statement();
-      h.run((flow) {
-        h.declare(x, initialized: true);
-
-        h.ifIsNotType(x, 'int', () {
-          h.labeledBlock(block, () {
-            h.if_(h.expr, () {
-              flow.handleBreak(block);
-            });
-            flow.handleExit();
-          });
-        });
-        expect(flow.promotedType(x), isNull);
-      });
+      var h = Harness();
+      var x = Var('x', 'int?');
+      h.run([
+        declare(x, initialized: true),
+        if_(x.read.isNot('int'), [
+          branchTarget((t) => labeled(block([
+                if_(expr('bool'), [
+                  break_(t),
+                ]),
+                return_(),
+              ]))),
+        ]),
+        checkNotPromoted(x),
+      ]);
     });
 
     test('logicalBinaryOp_rightBegin(isAnd: true) promotes in RHS', () {
-      var h = _Harness();
-      var x = h.addVar('x', 'int?');
-      h.run((flow) {
-        h.declare(x, initialized: true);
-        flow.logicalBinaryOp_begin();
-        flow.logicalBinaryOp_rightBegin(h.notNull(x, _Type('int?'))(),
-            isAnd: true);
-        expect(flow.promotedType(x).type, 'int');
-        flow.logicalBinaryOp_end(_Expression(), _Expression(), isAnd: true);
-      });
+      var h = Harness();
+      var x = Var('x', 'int?');
+      h.run([
+        declare(x, initialized: true),
+        x.read
+            .notEq(nullLiteral)
+            .and(checkPromoted(x, 'int').thenExpr(expr('bool')))
+            .stmt,
+      ]);
     });
 
     test('logicalBinaryOp_rightEnd(isAnd: true) keeps promotions from RHS', () {
-      var h = _Harness();
-      var x = h.addVar('x', 'int?');
-      h.run((flow) {
-        h.declare(x, initialized: true);
-        flow.ifStatement_conditionBegin();
-        flow.logicalBinaryOp_begin();
-        flow.logicalBinaryOp_rightBegin(_Expression(), isAnd: true);
-        var wholeExpr = _Expression();
-        flow.logicalBinaryOp_end(wholeExpr, h.notNull(x, _Type('int?'))(),
-            isAnd: true);
-        flow.ifStatement_thenBegin(wholeExpr);
-        expect(flow.promotedType(x).type, 'int');
-        flow.ifStatement_end(false);
-      });
+      var h = Harness();
+      var x = Var('x', 'int?');
+      h.run([
+        declare(x, initialized: true),
+        if_(expr('bool').and(x.read.notEq(nullLiteral)), [
+          checkPromoted(x, 'int'),
+        ]),
+      ]);
     });
 
     test('logicalBinaryOp_rightEnd(isAnd: false) keeps promotions from RHS',
         () {
-      var h = _Harness();
-      var x = h.addVar('x', 'int?');
-      h.run((flow) {
-        h.declare(x, initialized: true);
-        flow.ifStatement_conditionBegin();
-        flow.logicalBinaryOp_begin();
-        flow.logicalBinaryOp_rightBegin(_Expression(), isAnd: false);
-        var wholeExpr = _Expression();
-        flow.logicalBinaryOp_end(wholeExpr, h.eqNull(x, _Type('int?'))(),
-            isAnd: false);
-        flow.ifStatement_thenBegin(wholeExpr);
-        flow.ifStatement_elseBegin();
-        expect(flow.promotedType(x).type, 'int');
-        flow.ifStatement_end(true);
-      });
+      var h = Harness();
+      var x = Var('x', 'int?');
+      h.run([
+        declare(x, initialized: true),
+        if_(expr('bool').or(x.read.eq(nullLiteral)), [], [
+          checkPromoted(x, 'int'),
+        ]),
+      ]);
     });
 
     test('logicalBinaryOp_rightBegin(isAnd: false) promotes in RHS', () {
-      var h = _Harness();
-      var x = h.addVar('x', 'int?');
-      h.run((flow) {
-        h.declare(x, initialized: true);
-        flow.logicalBinaryOp_begin();
-        flow.logicalBinaryOp_rightBegin(h.eqNull(x, _Type('int?'))(),
-            isAnd: false);
-        expect(flow.promotedType(x).type, 'int');
-        flow.logicalBinaryOp_end(_Expression(), _Expression(), isAnd: false);
-      });
+      var h = Harness();
+      var x = Var('x', 'int?');
+      h.run([
+        declare(x, initialized: true),
+        x.read
+            .eq(nullLiteral)
+            .or(checkPromoted(x, 'int').thenExpr(expr('bool')))
+            .stmt,
+      ]);
     });
 
     test('logicalBinaryOp(isAnd: true) joins promotions', () {
       // if (x != null && y != null) {
       //   promotes x and y
       // }
-      var h = _Harness();
-      var x = h.addVar('x', 'int?');
-      var y = h.addVar('y', 'int?');
-      h.run((flow) {
-        h.declare(x, initialized: true);
-        h.declare(y, initialized: true);
-        h.if_(h.and(h.notNull(x, _Type('int?')), h.notNull(y, _Type('int?'))),
-            () {
-          expect(flow.promotedType(x).type, 'int');
-          expect(flow.promotedType(y).type, 'int');
-        });
-      });
+      var h = Harness();
+      var x = Var('x', 'int?');
+      var y = Var('y', 'int?');
+      h.run([
+        declare(x, initialized: true),
+        declare(y, initialized: true),
+        if_(x.read.notEq(nullLiteral).and(y.read.notEq(nullLiteral)), [
+          checkPromoted(x, 'int'),
+          checkPromoted(y, 'int'),
+        ]),
+      ]);
     });
 
     test('logicalBinaryOp(isAnd: false) joins promotions', () {
       // if (x == null || y == null) {} else {
       //   promotes x and y
       // }
-      var h = _Harness();
-      var x = h.addVar('x', 'int?');
-      var y = h.addVar('y', 'int?');
-      h.run((flow) {
-        h.declare(x, initialized: true);
-        h.declare(y, initialized: true);
-        h.ifElse(
-            h.or(h.eqNull(x, _Type('int?')), h.eqNull(y, _Type('int?'))), () {},
-            () {
-          expect(flow.promotedType(x).type, 'int');
-          expect(flow.promotedType(y).type, 'int');
-        });
-      });
+      var h = Harness();
+      var x = Var('x', 'int?');
+      var y = Var('y', 'int?');
+      h.run([
+        declare(x, initialized: true),
+        declare(y, initialized: true),
+        if_(x.read.eq(nullLiteral).or(y.read.eq(nullLiteral)), [], [
+          checkPromoted(x, 'int'),
+          checkPromoted(y, 'int'),
+        ]),
+      ]);
     });
 
     test('nonNullAssert_end(x) promotes', () {
-      var h = _Harness();
-      var x = h.addVar('x', 'int?');
-      h.run((flow) {
-        h.declare(x, initialized: true);
-        var varExpr = _Expression();
-        flow.variableRead(varExpr, x);
-        flow.nonNullAssert_end(varExpr);
-        expect(flow.promotedType(x).type, 'int');
-      });
+      var h = Harness();
+      var x = Var('x', 'int?');
+      h.run([
+        declare(x, initialized: true),
+        x.read.nonNullAssert.stmt,
+        checkPromoted(x, 'int'),
+      ]);
     });
 
     test('nullAwareAccess temporarily promotes', () {
-      var h = _Harness();
-      var x = h.addVar('x', 'int?');
-      h.run((flow) {
-        h.declare(x, initialized: true);
-        var varExpr = _Expression();
-        flow.variableRead(varExpr, x);
-        flow.nullAwareAccess_rightBegin(varExpr, _Type('int?'));
-        expect(flow.isReachable, true);
-        expect(flow.promotedType(x).type, 'int');
-        flow.nullAwareAccess_end();
-        expect(flow.promotedType(x), isNull);
-      });
+      var h = Harness();
+      var x = Var('x', 'int?');
+      h.run([
+        declare(x, initialized: true),
+        x.read
+            .nullAwareAccess(block([
+              checkReachable(true),
+              checkPromoted(x, 'int'),
+            ]).thenExpr(expr('Null')))
+            .stmt,
+        checkNotPromoted(x),
+      ]);
     });
 
     test('nullAwareAccess does not promote the target of a cascade', () {
-      var h = _Harness();
-      var x = h.addVar('x', 'int?');
-      h.run((flow) {
-        h.declare(x, initialized: true);
-        var varExpr = _Expression();
-        flow.variableRead(varExpr, x);
-        flow.nullAwareAccess_rightBegin(null, _Type('int?'));
-        expect(flow.isReachable, true);
-        expect(flow.promotedType(x), isNull);
-        flow.nullAwareAccess_end();
-      });
+      var h = Harness();
+      var x = Var('x', 'int?');
+      h.run([
+        declare(x, initialized: true),
+        x.read
+            .nullAwareAccess(
+                block([
+                  checkReachable(true),
+                  checkNotPromoted(x),
+                ]).thenExpr(expr('Null')),
+                isCascaded: true)
+            .stmt,
+      ]);
     });
 
     test('nullAwareAccess preserves demotions', () {
-      var h = _Harness();
-      var x = h.addVar('x', 'int?');
-      h.assignedVariables((vars) => vars.write(x));
-      h.run((flow) {
-        h.declare(x, initialized: true);
-        h.promote(x, 'int');
-        var lhs = _Expression();
-        flow.nullAwareAccess_rightBegin(lhs, _Type('int'));
-        expect(flow.isReachable, true);
-        expect(flow.promotedType(x).type, 'int');
-        flow.write(x, _Type('int?'));
-        expect(flow.promotedType(x), isNull);
-        flow.nullAwareAccess_end();
-        expect(flow.promotedType(x), isNull);
-      });
+      var h = Harness();
+      var x = Var('x', 'int?');
+      h.run([
+        declare(x, initialized: true),
+        x.read.as_('int').stmt,
+        expr('int')
+            .nullAwareAccess(block([
+              checkReachable(true),
+              checkPromoted(x, 'int'),
+            ]).thenExpr(x.write(expr('int?'))).thenStmt(checkNotPromoted(x)))
+            .stmt,
+        checkNotPromoted(x),
+      ]);
     });
 
     test('nullAwareAccess_end ignores shorting if target is non-nullable', () {
-      var h = _Harness();
-      var x = h.addVar('x', 'int?');
-      h.run((flow) {
-        h.declare(x, initialized: true);
-        flow.nullAwareAccess_rightBegin(_Expression(), _Type('int'));
-        expect(flow.isReachable, true);
-        h.promote(x, 'int');
-        expect(flow.promotedType(x).type, 'int');
-        flow.nullAwareAccess_end();
+      var h = Harness();
+      var x = Var('x', 'int?');
+      h.run([
+        declare(x, initialized: true),
+        expr('int')
+            .nullAwareAccess(block([
+              checkReachable(true),
+              x.read.as_('int').stmt,
+              checkPromoted(x, 'int'),
+            ]).thenExpr(expr('Null')))
+            .stmt,
         // Since the null-shorting path was reachable, promotion of `x` should
         // be cancelled.
-        expect(flow.promotedType(x), isNull);
-      });
+        checkNotPromoted(x),
+      ]);
     });
 
     test('parenthesizedExpression preserves promotion behaviors', () {
-      var h = _Harness();
-      var x = h.addVar('x', 'int?');
-      h.run((flow) {
-        h.if_(
-            h.parenthesized(h.notEqual(
-                h.parenthesized(h.variableRead(x)),
-                _Type('int?'),
-                h.parenthesized(h.nullLiteral),
-                _Type('Null'))), () {
-          expect(flow.promotedType(x).type, 'int');
-        });
-      });
+      var h = Harness();
+      var x = Var('x', 'int?');
+      h.run([
+        if_(
+            x.read.parenthesized.notEq(nullLiteral.parenthesized).parenthesized,
+            [
+              checkPromoted(x, 'int'),
+            ]),
+      ]);
     });
 
     test('promote promotes to a subtype and sets type of interest', () {
-      var h = _Harness();
-      var x = h.addVar('x', 'num?');
-      h.assignedVariables((vars) {
-        vars.write(x);
-      });
-      h.run((flow) {
-        flow.declare(x, true);
-        expect(flow.promotedType(x), isNull);
-        flow.promote(x, _Type('num'));
-        expect(flow.promotedType(x).type, 'num');
+      var h = Harness();
+      var x = Var('x', 'num?');
+      h.run([
+        declare(x, initialized: true),
+        checkNotPromoted(x),
+        x.read.as_('num').stmt,
+        checkPromoted(x, 'num'),
         // Check that it's a type of interest by promoting and de-promoting.
-        h.if_(h.isType(h.variableRead(x), 'int'), () {
-          expect(flow.promotedType(x).type, 'int');
-          flow.write(x, _Type('num'));
-          expect(flow.promotedType(x).type, 'num');
-        });
-      });
+        if_(x.read.is_('int'), [
+          checkPromoted(x, 'int'),
+          x.write(expr('num')).stmt,
+          checkPromoted(x, 'num'),
+        ]),
+      ]);
     });
 
     test('promote does not promote to a non-subtype', () {
-      var h = _Harness();
-      var x = h.addVar('x', 'num?');
-      h.run((flow) {
-        flow.declare(x, true);
-        expect(flow.promotedType(x), isNull);
-        flow.promote(x, _Type('String'));
-        expect(flow.promotedType(x), isNull);
-      });
+      var h = Harness();
+      var x = Var('x', 'num?');
+      h.run([
+        declare(x, initialized: true),
+        checkNotPromoted(x),
+        x.read.as_('String').stmt,
+        checkNotPromoted(x),
+      ]);
     });
 
     test('promote does not promote if variable is write-captured', () {
-      var h = _Harness();
-      var x = h.addVar('x', 'num?');
-      var functionNode = _Node();
-      h.assignedVariables(
-          (vars) => vars.function(functionNode, () => vars.write(x)));
-      h.run((flow) {
-        flow.declare(x, true);
-        expect(flow.promotedType(x), isNull);
-        flow.functionExpression_begin(functionNode);
-        flow.write(x, _Type('num'));
-        flow.functionExpression_end();
-        flow.promote(x, _Type('num'));
-        expect(flow.promotedType(x), isNull);
-      });
+      var h = Harness();
+      var x = Var('x', 'num?');
+      h.run([
+        declare(x, initialized: true),
+        checkNotPromoted(x),
+        localFunction([
+          x.write(expr('num')).stmt,
+        ]),
+        x.read.as_('num').stmt,
+        checkNotPromoted(x),
+      ]);
     });
 
     test('promotedType handles not-yet-seen variables', () {
       // Note: this is needed for error recovery in the analyzer.
-      var h = _Harness();
-      var x = h.addVar('x', 'int');
-      h.run((flow) {
-        expect(flow.promotedType(x), isNull);
-        h.declare(x, initialized: true);
-      });
+      var h = Harness();
+      var x = Var('x', 'int');
+      h.run([
+        checkNotPromoted(x),
+        declare(x, initialized: true),
+      ]);
     });
 
     test('switchStatement_beginCase(false) restores previous promotions', () {
-      var h = _Harness();
-      var x = h.addVar('x', 'int?');
-      var switchStatement = _Statement();
-      h.assignedVariables(
-          (vars) => vars.nest(switchStatement, () => vars.write(x)));
-      h.run((flow) {
-        h.declare(x, initialized: true);
-        h.promote(x, 'int');
-        flow.switchStatement_expressionEnd(_Statement());
-        flow.switchStatement_beginCase(false, switchStatement);
-        expect(flow.promotedType(x).type, 'int');
-        flow.write(x, _Type('int?'));
-        expect(flow.promotedType(x), isNull);
-        flow.switchStatement_beginCase(false, switchStatement);
-        expect(flow.promotedType(x).type, 'int');
-        flow.write(x, _Type('int?'));
-        expect(flow.promotedType(x), isNull);
-        flow.switchStatement_end(false);
-      });
+      var h = Harness();
+      var x = Var('x', 'int?');
+      h.run([
+        declare(x, initialized: true),
+        x.read.as_('int').stmt,
+        switch_(
+            expr('Null'),
+            [
+              case_([
+                checkPromoted(x, 'int'),
+                x.write(expr('int?')).stmt,
+                checkNotPromoted(x),
+              ]),
+              case_([
+                checkPromoted(x, 'int'),
+                x.write(expr('int?')).stmt,
+                checkNotPromoted(x),
+              ]),
+            ],
+            isExhaustive: false),
+      ]);
     });
 
     test('switchStatement_beginCase(false) does not un-promote', () {
-      var h = _Harness();
-      var x = h.addVar('x', 'int?');
-      var switchStatement = _Statement();
-      h.assignedVariables(
-          (vars) => vars.nest(switchStatement, () => vars.write(x)));
-      h.run((flow) {
-        h.declare(x, initialized: true);
-        h.promote(x, 'int');
-        flow.switchStatement_expressionEnd(_Statement());
-        flow.switchStatement_beginCase(false, switchStatement);
-        expect(flow.promotedType(x).type, 'int');
-        flow.write(x, _Type('int?'));
-        expect(flow.promotedType(x), isNull);
-        flow.switchStatement_end(false);
-      });
+      var h = Harness();
+      var x = Var('x', 'int?');
+      h.run([
+        declare(x, initialized: true),
+        x.read.as_('int').stmt,
+        switch_(
+            expr('Null'),
+            [
+              case_([
+                checkPromoted(x, 'int'),
+                x.write(expr('int?')).stmt,
+                checkNotPromoted(x),
+              ])
+            ],
+            isExhaustive: false),
+      ]);
     });
 
     test('switchStatement_beginCase(false) handles write captures in cases',
         () {
-      var h = _Harness();
-      var x = h.addVar('x', 'int?');
-      var switchStatement = _Statement();
-      var functionNode = _Node();
-      h.assignedVariables((vars) => vars.nest(switchStatement,
-          () => vars.function(functionNode, () => vars.write(x))));
-      h.run((flow) {
-        h.declare(x, initialized: true);
-        h.promote(x, 'int');
-        flow.switchStatement_expressionEnd(_Statement());
-        flow.switchStatement_beginCase(false, switchStatement);
-        expect(flow.promotedType(x).type, 'int');
-        h.function(functionNode, () {
-          flow.write(x, _Type('int?'));
-        });
-        expect(flow.promotedType(x), isNull);
-        flow.switchStatement_end(false);
-      });
+      var h = Harness();
+      var x = Var('x', 'int?');
+      h.run([
+        declare(x, initialized: true),
+        x.read.as_('int').stmt,
+        switch_(
+            expr('Null'),
+            [
+              case_([
+                checkPromoted(x, 'int'),
+                localFunction([
+                  x.write(expr('int?')).stmt,
+                ]),
+                checkNotPromoted(x),
+              ]),
+            ],
+            isExhaustive: false),
+      ]);
     });
 
     test('switchStatement_beginCase(true) un-promotes', () {
-      var h = _Harness();
-      var x = h.addVar('x', 'int?');
-      var switchStatement = _Statement();
-      h.assignedVariables(
-          (vars) => vars.nest(switchStatement, () => vars.write(x)));
-      h.run((flow) {
-        h.declare(x, initialized: true);
-        h.promote(x, 'int');
-        flow.switchStatement_expressionEnd(_Statement());
-        flow.switchStatement_beginCase(true, switchStatement);
-        expect(flow.promotedType(x), isNull);
-        flow.write(x, _Type('int?'));
-        expect(flow.promotedType(x), isNull);
-        flow.switchStatement_end(false);
-      });
+      var h = Harness();
+      var x = Var('x', 'int?');
+      h.run([
+        declare(x, initialized: true),
+        x.read.as_('int').stmt,
+        switch_(
+            expr('Null'),
+            [
+              case_([
+                checkNotPromoted(x),
+                x.write(expr('int?')).stmt,
+                checkNotPromoted(x),
+              ], hasLabel: true),
+            ],
+            isExhaustive: false),
+      ]);
     });
 
     test('switchStatement_beginCase(true) handles write captures in cases', () {
-      var h = _Harness();
-      var x = h.addVar('x', 'int?');
-      var switchStatement = _Statement();
-      var functionNode = _Node();
-      h.assignedVariables((vars) => vars.nest(switchStatement,
-          () => vars.function(functionNode, () => vars.write(x))));
-      h.run((flow) {
-        h.declare(x, initialized: true);
-        h.promote(x, 'int');
-        flow.switchStatement_expressionEnd(_Statement());
-        flow.switchStatement_beginCase(true, switchStatement);
-        h.promote(x, 'int');
-        expect(flow.promotedType(x), isNull);
-        h.function(functionNode, () {
-          flow.write(x, _Type('int?'));
-        });
-        expect(flow.promotedType(x), isNull);
-        flow.switchStatement_end(false);
-      });
+      var h = Harness();
+      var x = Var('x', 'int?');
+      h.run([
+        declare(x, initialized: true),
+        x.read.as_('int').stmt,
+        switch_(
+            expr('Null'),
+            [
+              case_([
+                x.read.as_('int').stmt,
+                checkNotPromoted(x),
+                localFunction([
+                  x.write(expr('int?')).stmt,
+                ]),
+                checkNotPromoted(x),
+              ], hasLabel: true),
+            ],
+            isExhaustive: false),
+      ]);
     });
 
     test('switchStatement_end(false) joins break and default', () {
-      var h = _Harness();
-      var x = h.addVar('x', 'int?');
-      var y = h.addVar('y', 'int?');
-      var z = h.addVar('z', 'int?');
-      var switchStatement = _Statement();
-      h.assignedVariables(
-          (vars) => vars.nest(switchStatement, () => vars.write(y)));
-      h.run((flow) {
-        h.declare(x, initialized: true);
-        h.declare(y, initialized: true);
-        h.declare(z, initialized: true);
-        h.promote(y, 'int');
-        h.promote(z, 'int');
-        var stmt = _Statement();
-        flow.switchStatement_expressionEnd(stmt);
-        flow.switchStatement_beginCase(false, switchStatement);
-        h.promote(x, 'int');
-        flow.write(y, _Type('int?'));
-        flow.handleBreak(stmt);
-        flow.switchStatement_end(false);
-        expect(flow.promotedType(x), isNull);
-        expect(flow.promotedType(y), isNull);
-        expect(flow.promotedType(z).type, 'int');
-      });
+      var h = Harness();
+      var x = Var('x', 'int?');
+      var y = Var('y', 'int?');
+      var z = Var('z', 'int?');
+      h.run([
+        declare(x, initialized: true),
+        declare(y, initialized: true),
+        declare(z, initialized: true),
+        y.read.as_('int').stmt,
+        z.read.as_('int').stmt,
+        branchTarget((t) => switch_(
+            expr('Null'),
+            [
+              case_([
+                x.read.as_('int').stmt,
+                y.write(expr('int?')).stmt,
+                break_(t),
+              ]),
+            ],
+            isExhaustive: false)),
+        checkNotPromoted(x),
+        checkNotPromoted(y),
+        checkPromoted(z, 'int'),
+      ]);
     });
 
     test('switchStatement_end(true) joins breaks', () {
-      var h = _Harness();
-      var w = h.addVar('w', 'int?');
-      var x = h.addVar('x', 'int?');
-      var y = h.addVar('y', 'int?');
-      var z = h.addVar('z', 'int?');
-      var switchStatement = _Statement();
-      h.assignedVariables((vars) => vars.nest(switchStatement, () {
-            vars.write(x);
-            vars.write(y);
-          }));
-      h.run((flow) {
-        h.declare(w, initialized: true);
-        h.declare(x, initialized: true);
-        h.declare(y, initialized: true);
-        h.declare(z, initialized: true);
-        h.promote(x, 'int');
-        h.promote(y, 'int');
-        h.promote(z, 'int');
-        var stmt = _Statement();
-        flow.switchStatement_expressionEnd(stmt);
-        flow.switchStatement_beginCase(false, switchStatement);
-        h.promote(w, 'int');
-        h.promote(y, 'int');
-        flow.write(x, _Type('int?'));
-        flow.handleBreak(stmt);
-        flow.switchStatement_beginCase(false, switchStatement);
-        h.promote(w, 'int');
-        h.promote(x, 'int');
-        flow.write(y, _Type('int?'));
-        flow.handleBreak(stmt);
-        flow.switchStatement_end(true);
-        expect(flow.promotedType(w).type, 'int');
-        expect(flow.promotedType(x), isNull);
-        expect(flow.promotedType(y), isNull);
-        expect(flow.promotedType(z).type, 'int');
-      });
+      var h = Harness();
+      var w = Var('w', 'int?');
+      var x = Var('x', 'int?');
+      var y = Var('y', 'int?');
+      var z = Var('z', 'int?');
+      h.run([
+        declare(w, initialized: true),
+        declare(x, initialized: true),
+        declare(y, initialized: true),
+        declare(z, initialized: true),
+        x.read.as_('int').stmt,
+        y.read.as_('int').stmt,
+        z.read.as_('int').stmt,
+        branchTarget((t) => switch_(
+            expr('Null'),
+            [
+              case_([
+                w.read.as_('int').stmt,
+                y.read.as_('int').stmt,
+                x.write(expr('int?')).stmt,
+                break_(t),
+              ]),
+              case_([
+                w.read.as_('int').stmt,
+                x.read.as_('int').stmt,
+                y.write(expr('int?')).stmt,
+                break_(t),
+              ]),
+            ],
+            isExhaustive: true)),
+        checkPromoted(w, 'int'),
+        checkNotPromoted(x),
+        checkNotPromoted(y),
+        checkPromoted(z, 'int'),
+      ]);
     });
 
     test('switchStatement_end(true) allows fall-through of last case', () {
-      var h = _Harness();
-      var x = h.addVar('x', 'int?');
-      var stmt = _Statement();
-      h.assignedVariables((vars) => vars.nest(stmt, () {}));
-      h.run((flow) {
-        h.declare(x, initialized: true);
-        flow.switchStatement_expressionEnd(stmt);
-        flow.switchStatement_beginCase(false, stmt);
-        h.promote(x, 'int');
-        flow.handleBreak(stmt);
-        flow.switchStatement_beginCase(false, stmt);
-        flow.switchStatement_end(true);
-        expect(flow.promotedType(x), isNull);
-      });
+      var h = Harness();
+      var x = Var('x', 'int?');
+      h.run([
+        declare(x, initialized: true),
+        branchTarget((t) => switch_(
+            expr('Null'),
+            [
+              case_([
+                x.read.as_('int').stmt,
+                break_(t),
+              ]),
+              case_([]),
+            ],
+            isExhaustive: true)),
+        checkNotPromoted(x),
+      ]);
     });
 
     test('tryCatchStatement_bodyEnd() restores pre-try state', () {
-      var h = _Harness();
-      var x = h.addVar('x', 'int?');
-      var y = h.addVar('y', 'int?');
-      var stmt = _Statement();
-      h.assignedVariables((vars) => vars.nest(stmt, () {}));
-      h.run((flow) {
-        h.declare(x, initialized: true);
-        h.declare(y, initialized: true);
-        h.promote(y, 'int');
-        flow.tryCatchStatement_bodyBegin();
-        h.promote(x, 'int');
-        expect(flow.promotedType(x).type, 'int');
-        expect(flow.promotedType(y).type, 'int');
-        flow.tryCatchStatement_bodyEnd(stmt);
-        flow.tryCatchStatement_catchBegin(null, null);
-        expect(flow.promotedType(x), isNull);
-        expect(flow.promotedType(y).type, 'int');
-        flow.tryCatchStatement_catchEnd();
-        flow.tryCatchStatement_end();
-      });
+      var h = Harness();
+      var x = Var('x', 'int?');
+      var y = Var('y', 'int?');
+      h.run([
+        declare(x, initialized: true),
+        declare(y, initialized: true),
+        y.read.as_('int').stmt,
+        tryCatch([
+          x.read.as_('int').stmt,
+          checkPromoted(x, 'int'),
+          checkPromoted(y, 'int'),
+        ], [
+          catch_(body: [
+            checkNotPromoted(x),
+            checkPromoted(y, 'int'),
+          ])
+        ]),
+      ]);
     });
 
     test('tryCatchStatement_bodyEnd() un-promotes variables assigned in body',
         () {
-      var h = _Harness();
-      var x = h.addVar('x', 'int?');
-      var body = _Statement();
-      h.assignedVariables((vars) => vars.nest(body, () => vars.write(x)));
-      h.run((flow) {
-        h.declare(x, initialized: true);
-        h.promote(x, 'int');
-        expect(flow.promotedType(x).type, 'int');
-        flow.tryCatchStatement_bodyBegin();
-        flow.write(x, _Type('int?'));
-        h.promote(x, 'int');
-        expect(flow.promotedType(x).type, 'int');
-        flow.tryCatchStatement_bodyEnd(body);
-        flow.tryCatchStatement_catchBegin(null, null);
-        expect(flow.promotedType(x), isNull);
-        flow.tryCatchStatement_catchEnd();
-        flow.tryCatchStatement_end();
-      });
+      var h = Harness();
+      var x = Var('x', 'int?');
+      h.run([
+        declare(x, initialized: true),
+        x.read.as_('int').stmt,
+        checkPromoted(x, 'int'),
+        tryCatch([
+          x.write(expr('int?')).stmt,
+          x.read.as_('int').stmt,
+          checkPromoted(x, 'int'),
+        ], [
+          catch_(body: [
+            checkNotPromoted(x),
+          ]),
+        ]),
+      ]);
     });
 
     test('tryCatchStatement_bodyEnd() preserves write captures in body', () {
       // Note: it's not necessary for the write capture to survive to the end of
       // the try body, because an exception could occur at any time.  We check
       // this by putting an exit in the try body.
-      var h = _Harness();
-      var x = h.addVar('x', 'int?');
-      var body = _Statement();
-      var functionNode = _Node();
-      h.assignedVariables((vars) => vars.nest(
-          body, () => vars.function(functionNode, () => vars.write(x))));
-      h.run((flow) {
-        h.declare(x, initialized: true);
-        h.promote(x, 'int');
-        expect(flow.promotedType(x).type, 'int');
-        flow.tryCatchStatement_bodyBegin();
-        h.function(functionNode, () {
-          flow.write(x, _Type('int?'));
-        });
-        flow.handleExit();
-        flow.tryCatchStatement_bodyEnd(body);
-        flow.tryCatchStatement_catchBegin(null, null);
-        h.promote(x, 'int');
-        expect(flow.promotedType(x), isNull);
-        flow.tryCatchStatement_catchEnd();
-        flow.tryCatchStatement_end();
-      });
+      var h = Harness();
+      var x = Var('x', 'int?');
+      h.run([
+        declare(x, initialized: true),
+        x.read.as_('int').stmt,
+        checkPromoted(x, 'int'),
+        tryCatch([
+          localFunction([
+            x.write(expr('int?')).stmt,
+          ]),
+          return_(),
+        ], [
+          catch_(body: [
+            x.read.as_('int').stmt,
+            checkNotPromoted(x),
+          ])
+        ]),
+      ]);
     });
 
     test('tryCatchStatement_catchBegin() restores previous post-body state',
         () {
-      var h = _Harness();
-      var x = h.addVar('x', 'int?');
-      var stmt = _Statement();
-      h.assignedVariables((vars) => vars.nest(stmt, () {}));
-      h.run((flow) {
-        h.declare(x, initialized: true);
-        flow.tryCatchStatement_bodyBegin();
-        flow.tryCatchStatement_bodyEnd(stmt);
-        flow.tryCatchStatement_catchBegin(null, null);
-        h.promote(x, 'int');
-        expect(flow.promotedType(x).type, 'int');
-        flow.tryCatchStatement_catchEnd();
-        flow.tryCatchStatement_catchBegin(null, null);
-        expect(flow.promotedType(x), isNull);
-        flow.tryCatchStatement_catchEnd();
-        flow.tryCatchStatement_end();
-      });
+      var h = Harness();
+      var x = Var('x', 'int?');
+      h.run([
+        declare(x, initialized: true),
+        tryCatch([], [
+          catch_(body: [
+            x.read.as_('int').stmt,
+            checkPromoted(x, 'int'),
+          ]),
+          catch_(body: [
+            checkNotPromoted(x),
+          ]),
+        ]),
+      ]);
     });
 
     test('tryCatchStatement_catchBegin() initializes vars', () {
-      var h = _Harness();
-      var e = h.addVar('e', 'int');
-      var st = h.addVar('st', 'StackTrace');
-      var stmt = _Statement();
-      h.assignedVariables((vars) => vars.nest(stmt, () {}));
-      h.run((flow) {
-        flow.tryCatchStatement_bodyBegin();
-        flow.tryCatchStatement_bodyEnd(stmt);
-        flow.tryCatchStatement_catchBegin(e, st);
-        expect(flow.isAssigned(e), true);
-        expect(flow.isAssigned(st), true);
-        flow.tryCatchStatement_catchEnd();
-        flow.tryCatchStatement_end();
-      });
+      var h = Harness();
+      var e = Var('e', 'int');
+      var st = Var('st', 'StackTrace');
+      h.run([
+        tryCatch([], [
+          catch_(exception: e, stackTrace: st, body: [
+            checkAssigned(e, true),
+            checkAssigned(st, true),
+          ]),
+        ]),
+      ]);
     });
 
     test('tryCatchStatement_catchEnd() joins catch state with after-try state',
         () {
-      var h = _Harness();
-      var x = h.addVar('x', 'int?');
-      var y = h.addVar('y', 'int?');
-      var z = h.addVar('z', 'int?');
-      var stmt = _Statement();
-      h.assignedVariables((vars) => vars.nest(stmt, () {}));
-      h.run((flow) {
-        h.declare(x, initialized: true);
-        h.declare(y, initialized: true);
-        h.declare(z, initialized: true);
-        flow.tryCatchStatement_bodyBegin();
-        h.promote(x, 'int');
-        h.promote(y, 'int');
-        flow.tryCatchStatement_bodyEnd(stmt);
-        flow.tryCatchStatement_catchBegin(null, null);
-        h.promote(x, 'int');
-        h.promote(z, 'int');
-        flow.tryCatchStatement_catchEnd();
-        flow.tryCatchStatement_end();
+      var h = Harness();
+      var x = Var('x', 'int?');
+      var y = Var('y', 'int?');
+      var z = Var('z', 'int?');
+      h.run([
+        declare(x, initialized: true), declare(y, initialized: true),
+        declare(z, initialized: true),
+        tryCatch([
+          x.read.as_('int').stmt,
+          y.read.as_('int').stmt,
+        ], [
+          catch_(body: [
+            x.read.as_('int').stmt,
+            z.read.as_('int').stmt,
+          ]),
+        ]),
         // Only x should be promoted, because it's the only variable
         // promoted in both the try body and the catch handler.
-        expect(flow.promotedType(x).type, 'int');
-        expect(flow.promotedType(y), isNull);
-        expect(flow.promotedType(z), isNull);
-      });
+        checkPromoted(x, 'int'), checkNotPromoted(y), checkNotPromoted(z),
+      ]);
     });
 
     test('tryCatchStatement_catchEnd() joins catch states', () {
-      var h = _Harness();
-      var x = h.addVar('x', 'int?');
-      var y = h.addVar('y', 'int?');
-      var z = h.addVar('z', 'int?');
-      var stmt = _Statement();
-      h.assignedVariables((vars) => vars.nest(stmt, () {}));
-      h.run((flow) {
-        h.declare(x, initialized: true);
-        h.declare(y, initialized: true);
-        h.declare(z, initialized: true);
-        flow.tryCatchStatement_bodyBegin();
-        flow.handleExit();
-        flow.tryCatchStatement_bodyEnd(stmt);
-        flow.tryCatchStatement_catchBegin(null, null);
-        h.promote(x, 'int');
-        h.promote(y, 'int');
-        flow.tryCatchStatement_catchEnd();
-        flow.tryCatchStatement_catchBegin(null, null);
-        h.promote(x, 'int');
-        h.promote(z, 'int');
-        flow.tryCatchStatement_catchEnd();
-        flow.tryCatchStatement_end();
+      var h = Harness();
+      var x = Var('x', 'int?');
+      var y = Var('y', 'int?');
+      var z = Var('z', 'int?');
+      h.run([
+        declare(x, initialized: true), declare(y, initialized: true),
+        declare(z, initialized: true),
+        tryCatch([
+          return_(),
+        ], [
+          catch_(body: [
+            x.read.as_('int').stmt,
+            y.read.as_('int').stmt,
+          ]),
+          catch_(body: [
+            x.read.as_('int').stmt,
+            z.read.as_('int').stmt,
+          ]),
+        ]),
         // Only x should be promoted, because it's the only variable promoted
         // in both catch handlers.
-        expect(flow.promotedType(x).type, 'int');
-        expect(flow.promotedType(y), isNull);
-        expect(flow.promotedType(z), isNull);
-      });
+        checkPromoted(x, 'int'), checkNotPromoted(y), checkNotPromoted(z),
+      ]);
     });
 
     test('tryFinallyStatement_finallyBegin() restores pre-try state', () {
-      var h = _Harness();
-      var x = h.addVar('x', 'int?');
-      var y = h.addVar('y', 'int?');
-      var body = _Node();
-      var finallyBlock = _Node();
-      h.assignedVariables((vars) {
-        vars.nest(body, () {});
-        vars.nest(finallyBlock, () {});
-      });
-      h.run((flow) {
-        h.declare(x, initialized: true);
-        h.declare(y, initialized: true);
-        h.promote(y, 'int');
-        flow.tryFinallyStatement_bodyBegin();
-        h.promote(x, 'int');
-        expect(flow.promotedType(x).type, 'int');
-        expect(flow.promotedType(y).type, 'int');
-        flow.tryFinallyStatement_finallyBegin(body);
-        expect(flow.promotedType(x), isNull);
-        expect(flow.promotedType(y).type, 'int');
-        flow.tryFinallyStatement_end(finallyBlock);
-      });
+      var h = Harness();
+      var x = Var('x', 'int?');
+      var y = Var('y', 'int?');
+      h.run([
+        declare(x, initialized: true),
+        declare(y, initialized: true),
+        y.read.as_('int').stmt,
+        tryFinally([
+          x.read.as_('int').stmt,
+          checkPromoted(x, 'int'),
+          checkPromoted(y, 'int'),
+        ], [
+          checkNotPromoted(x),
+          checkPromoted(y, 'int'),
+        ]),
+      ]);
     });
 
     test(
         'tryFinallyStatement_finallyBegin() un-promotes variables assigned in '
         'body', () {
-      var h = _Harness();
-      var x = h.addVar('x', 'int?');
-      var body = _Node();
-      var finallyBlock = _Node();
-      h.assignedVariables((vars) {
-        vars.nest(body, () => vars.write(x));
-        vars.nest(finallyBlock, () {});
-      });
-      h.run((flow) {
-        h.declare(x, initialized: true);
-        h.promote(x, 'int');
-        expect(flow.promotedType(x).type, 'int');
-        flow.tryFinallyStatement_bodyBegin();
-        flow.write(x, _Type('int?'));
-        h.promote(x, 'int');
-        expect(flow.promotedType(x).type, 'int');
-        flow.tryFinallyStatement_finallyBegin(body);
-        expect(flow.promotedType(x), isNull);
-        flow.tryFinallyStatement_end(finallyBlock);
-      });
+      var h = Harness();
+      var x = Var('x', 'int?');
+      h.run([
+        declare(x, initialized: true),
+        x.read.as_('int').stmt,
+        checkPromoted(x, 'int'),
+        tryFinally([
+          x.write(expr('int?')).stmt,
+          x.read.as_('int').stmt,
+          checkPromoted(x, 'int'),
+        ], [
+          checkNotPromoted(x),
+        ]),
+      ]);
     });
 
     test('tryFinallyStatement_finallyBegin() preserves write captures in body',
@@ -2021,262 +1692,206 @@
       // Note: it's not necessary for the write capture to survive to the end of
       // the try body, because an exception could occur at any time.  We check
       // this by putting an exit in the try body.
-      var h = _Harness();
-      var x = h.addVar('x', 'int?');
-      var body = _Statement();
-      var functionNode = _Node();
-      var finallyBlock = _Node();
-      h.assignedVariables((vars) => vars.nest(body, () {
-            vars.function(functionNode, () => vars.write(x));
-            vars.nest(finallyBlock, () {});
-          }));
-      h.run((flow) {
-        h.declare(x, initialized: true);
-        flow.tryFinallyStatement_bodyBegin();
-        h.function(functionNode, () {
-          flow.write(x, _Type('int?'));
-        });
-        flow.handleExit();
-        flow.tryFinallyStatement_finallyBegin(body);
-        h.promote(x, 'int');
-        expect(flow.promotedType(x), isNull);
-        flow.tryFinallyStatement_end(finallyBlock);
-      });
+      var h = Harness();
+      var x = Var('x', 'int?');
+      h.run([
+        declare(x, initialized: true),
+        tryFinally([
+          localFunction([
+            x.write(expr('int?')).stmt,
+          ]),
+          return_(),
+        ], [
+          x.read.as_('int').stmt,
+          checkNotPromoted(x),
+        ]),
+      ]);
     });
 
     test('tryFinallyStatement_end() restores promotions from try body', () {
-      var h = _Harness();
-      var x = h.addVar('x', 'int?');
-      var y = h.addVar('y', 'int?');
-      var body = _Statement();
-      var finallyBlock = _Node();
-      h.assignedVariables((vars) => vars.nest(body, () {
-            vars.nest(body, () {});
-            vars.nest(finallyBlock, () {});
-          }));
-      h.run((flow) {
-        h.declare(x, initialized: true);
-        h.declare(y, initialized: true);
-        flow.tryFinallyStatement_bodyBegin();
-        h.promote(x, 'int');
-        expect(flow.promotedType(x).type, 'int');
-        flow.tryFinallyStatement_finallyBegin(body);
-        expect(flow.promotedType(x), isNull);
-        h.promote(y, 'int');
-        expect(flow.promotedType(y).type, 'int');
-        flow.tryFinallyStatement_end(finallyBlock);
+      var h = Harness();
+      var x = Var('x', 'int?');
+      var y = Var('y', 'int?');
+      h.run([
+        declare(x, initialized: true), declare(y, initialized: true),
+        tryFinally([
+          x.read.as_('int').stmt,
+          checkPromoted(x, 'int'),
+        ], [
+          checkNotPromoted(x),
+          y.read.as_('int').stmt,
+          checkPromoted(y, 'int'),
+        ]),
         // Both x and y should now be promoted.
-        expect(flow.promotedType(x).type, 'int');
-        expect(flow.promotedType(y).type, 'int');
-      });
+        checkPromoted(x, 'int'), checkPromoted(y, 'int'),
+      ]);
     });
 
     test(
         'tryFinallyStatement_end() does not restore try body promotions for '
         'variables assigned in finally', () {
-      var h = _Harness();
-      var x = h.addVar('x', 'int?');
-      var y = h.addVar('y', 'int?');
-      var body = _Node();
-      var finallyBlock = _Node();
-      h.assignedVariables((vars) {
-        vars.nest(body, () {});
-        vars.nest(finallyBlock, () {
-          vars.write(x);
-          vars.write(y);
-        });
-      });
-      h.run((flow) {
-        h.declare(x, initialized: true);
-        h.declare(y, initialized: true);
-        flow.tryFinallyStatement_bodyBegin();
-        h.promote(x, 'int');
-        expect(flow.promotedType(x).type, 'int');
-        flow.tryFinallyStatement_finallyBegin(body);
-        expect(flow.promotedType(x), isNull);
-        flow.write(x, _Type('int?'));
-        flow.write(y, _Type('int?'));
-        h.promote(y, 'int');
-        expect(flow.promotedType(y).type, 'int');
-        flow.tryFinallyStatement_end(finallyBlock);
+      var h = Harness();
+      var x = Var('x', 'int?');
+      var y = Var('y', 'int?');
+      h.run([
+        declare(x, initialized: true), declare(y, initialized: true),
+        tryFinally([
+          x.read.as_('int').stmt,
+          checkPromoted(x, 'int'),
+        ], [
+          checkNotPromoted(x),
+          x.write(expr('int?')).stmt,
+          y.write(expr('int?')).stmt,
+          y.read.as_('int').stmt,
+          checkPromoted(y, 'int'),
+        ]),
         // x should not be re-promoted, because it might have been assigned a
         // non-promoted value in the "finally" block.  But y's promotion still
         // stands, because y was promoted in the finally block.
-        expect(flow.promotedType(x), isNull);
-        expect(flow.promotedType(y).type, 'int');
-      });
+        checkNotPromoted(x), checkPromoted(y, 'int'),
+      ]);
     });
 
     test('whileStatement_conditionBegin() un-promotes', () {
-      var h = _Harness();
-      var x = h.addVar('x', 'int?');
-      var whileStatement = _Statement();
-      h.assignedVariables(
-          (vars) => vars.nest(whileStatement, () => vars.write(x)));
-      h.run((flow) {
-        h.declare(x, initialized: true);
-        h.promote(x, 'int');
-        expect(flow.promotedType(x).type, 'int');
-        flow.whileStatement_conditionBegin(whileStatement);
-        expect(flow.promotedType(x), isNull);
-        flow.whileStatement_bodyBegin(_Statement(), _Expression());
-        flow.whileStatement_end();
-      });
+      var h = Harness();
+      var x = Var('x', 'int?');
+      h.run([
+        declare(x, initialized: true),
+        x.read.as_('int').stmt,
+        checkPromoted(x, 'int'),
+        while_(checkNotPromoted(x).thenExpr(expr('bool')), [
+          x.write(expr('Null')).stmt,
+        ]),
+      ]);
     });
 
     test('whileStatement_conditionBegin() handles write captures in the loop',
         () {
-      var h = _Harness();
-      var x = h.addVar('x', 'int?');
-      var whileStatement = _Statement();
-      var functionNode = _Node();
-      h.assignedVariables((vars) => vars.nest(whileStatement,
-          () => vars.function(functionNode, () => vars.write(x))));
-      h.run((flow) {
-        h.declare(x, initialized: true);
-        h.promote(x, 'int');
-        expect(flow.promotedType(x).type, 'int');
-        flow.whileStatement_conditionBegin(whileStatement);
-        h.promote(x, 'int');
-        expect(flow.promotedType(x), isNull);
-        h.function(functionNode, () {
-          flow.write(x, _Type('int?'));
-        });
-        flow.whileStatement_bodyBegin(_Statement(), _Expression());
-        flow.whileStatement_end();
-      });
+      var h = Harness();
+      var x = Var('x', 'int?');
+      h.run([
+        declare(x, initialized: true),
+        x.read.as_('int').stmt,
+        checkPromoted(x, 'int'),
+        while_(
+            block([
+              x.read.as_('int').stmt,
+              checkNotPromoted(x),
+              localFunction([
+                x.write(expr('int?')).stmt,
+              ]),
+            ]).thenExpr(expr('bool')),
+            []),
+      ]);
     });
 
     test('whileStatement_conditionBegin() handles not-yet-seen variables', () {
-      var h = _Harness();
-      var x = h.addVar('x', 'int?');
-      var y = h.addVar('y', 'int?');
-      var whileStatement = _Statement();
-      h.assignedVariables(
-          (vars) => vars.nest(whileStatement, () => vars.write(x)));
-      h.run((flow) {
-        h.declare(y, initialized: true);
-        h.promote(y, 'int');
-        flow.whileStatement_conditionBegin(whileStatement);
-        flow.declare(x, true);
-        flow.whileStatement_bodyBegin(_Statement(), _Expression());
-        flow.whileStatement_end();
-      });
+      var h = Harness();
+      var x = Var('x', 'int?');
+      var y = Var('y', 'int?');
+      h.run([
+        declare(y, initialized: true),
+        y.read.as_('int').stmt,
+        while_(declare(x, initialized: true).thenExpr(expr('bool')), [
+          x.write(expr('Null')).stmt,
+        ]),
+      ]);
     });
 
     test('whileStatement_bodyBegin() promotes', () {
-      var h = _Harness();
-      var x = h.addVar('x', 'int?');
-      var stmt = _Statement();
-      h.assignedVariables((vars) => vars.nest(stmt, () {}));
-      h.run((flow) {
-        h.declare(x, initialized: true);
-        flow.whileStatement_conditionBegin(stmt);
-        flow.whileStatement_bodyBegin(stmt, h.notNull(x, _Type('int?'))());
-        expect(flow.promotedType(x).type, 'int');
-        flow.whileStatement_end();
-      });
+      var h = Harness();
+      var x = Var('x', 'int?');
+      h.run([
+        declare(x, initialized: true),
+        while_(x.read.notEq(nullLiteral), [
+          checkPromoted(x, 'int'),
+        ]),
+      ]);
     });
 
     test('whileStatement_end() joins break and condition-false states', () {
       // To test that the states are properly joined, we have three variables:
       // x, y, and z.  We promote x and y in the break path, and x and z in the
       // condition-false path.  After the loop, only x should be promoted.
-      var h = _Harness();
-      var x = h.addVar('x', 'int?');
-      var y = h.addVar('y', 'int?');
-      var z = h.addVar('z', 'int?');
-      var stmt = _Statement();
-      h.assignedVariables((vars) => vars.nest(stmt, () {}));
-      h.run((flow) {
-        h.declare(x, initialized: true);
-        h.declare(y, initialized: true);
-        h.declare(z, initialized: true);
-        flow.whileStatement_conditionBegin(stmt);
-        flow.whileStatement_bodyBegin(stmt,
-            h.or(h.eqNull(x, _Type('int?')), h.eqNull(z, _Type('int?')))());
-        h.if_(h.expr, () {
-          h.promote(x, 'int');
-          h.promote(y, 'int');
-          flow.handleBreak(stmt);
-        });
-        flow.whileStatement_end();
-        expect(flow.promotedType(x).type, 'int');
-        expect(flow.promotedType(y), isNull);
-        expect(flow.promotedType(z), isNull);
-      });
+      var h = Harness();
+      var x = Var('x', 'int?');
+      var y = Var('y', 'int?');
+      var z = Var('z', 'int?');
+      h.run([
+        declare(x, initialized: true),
+        declare(y, initialized: true),
+        declare(z, initialized: true),
+        branchTarget(
+            (t) => while_(x.read.eq(nullLiteral).or(z.read.eq(nullLiteral)), [
+                  if_(expr('bool'), [
+                    x.read.as_('int').stmt,
+                    y.read.as_('int').stmt,
+                    break_(t),
+                  ]),
+                ])),
+        checkPromoted(x, 'int'),
+        checkNotPromoted(y),
+        checkNotPromoted(z),
+      ]);
     });
 
     test('Infinite loop does not implicitly assign variables', () {
-      var h = _Harness();
-      var x = h.addVar('x', 'int');
-      var whileStatement = _Statement();
-      h.assignedVariables(
-          (vars) => vars.nest(whileStatement, () => vars.write(x)));
-      h.run((flow) {
-        h.declare(x, initialized: false);
-        var trueCondition = _Expression();
-        flow.whileStatement_conditionBegin(whileStatement);
-        flow.booleanLiteral(trueCondition, true);
-        flow.whileStatement_bodyBegin(whileStatement, trueCondition);
-        flow.whileStatement_end();
-        expect(flow.isAssigned(x), false);
-      });
+      var h = Harness();
+      var x = Var('x', 'int');
+      h.run([
+        declare(x, initialized: false),
+        while_(booleanLiteral(true), [
+          x.write(expr('Null')).stmt,
+        ]),
+        checkAssigned(x, false),
+      ]);
     });
 
     test('If(false) does not discard promotions', () {
-      var h = _Harness();
-      var x = h.addVar('x', 'Object');
-      h.run((flow) {
-        h.declare(x, initialized: true);
-        h.promote(x, 'int');
-        expect(flow.promotedType(x).type, 'int');
-        // if (false) {
-        flow.ifStatement_conditionBegin();
-        var falseExpression = _Expression();
-        flow.booleanLiteral(falseExpression, false);
-        flow.ifStatement_thenBegin(falseExpression);
-        expect(flow.promotedType(x).type, 'int');
-        flow.ifStatement_end(false);
-      });
+      var h = Harness();
+      var x = Var('x', 'Object');
+      h.run([
+        declare(x, initialized: true),
+        x.read.as_('int').stmt,
+        checkPromoted(x, 'int'),
+        if_(booleanLiteral(false), [
+          checkPromoted(x, 'int'),
+        ]),
+      ]);
     });
 
     test('Promotions do not occur when a variable is write-captured', () {
-      var h = _Harness();
-      var x = h.addVar('x', 'Object');
-      var functionNode = _Node();
-      h.assignedVariables(
-          (vars) => vars.function(functionNode, () => vars.write(x)));
-      h.run((flow) {
-        h.declare(x, initialized: true);
-        h.function(functionNode, () {});
-        h.promote(x, 'int');
-        expect(flow.promotedType(x), isNull);
-      });
+      var h = Harness();
+      var x = Var('x', 'Object');
+      h.run([
+        declare(x, initialized: true),
+        localFunction([
+          x.write(expr('Object')).stmt,
+        ]),
+        x.read.as_('int').stmt,
+        checkNotPromoted(x),
+      ]);
     });
 
     test('Promotion cancellation of write-captured vars survives join', () {
-      var h = _Harness();
-      var x = h.addVar('x', 'Object');
-      var functionNode = _Node();
-      h.assignedVariables(
-          (vars) => vars.function(functionNode, () => vars.write(x)));
-      h.run((flow) {
-        h.declare(x, initialized: true);
-        h.ifElse(h.expr, () {
-          h.function(functionNode, () {});
-        }, () {
+      var h = Harness();
+      var x = Var('x', 'Object');
+      h.run([
+        declare(x, initialized: true),
+        if_(expr('bool'), [
+          localFunction([
+            x.write(expr('Object')).stmt,
+          ]),
+        ], [
           // Promotion should work here because the write capture is in the
           // other branch.
-          h.promote(x, 'int');
-          expect(flow.promotedType(x).type, 'int');
-        });
+          x.read.as_('int').stmt, checkPromoted(x, 'int'),
+        ]),
         // But the promotion should be cancelled now, after the join.
-        expect(flow.promotedType(x), isNull);
+        checkNotPromoted(x),
         // And further attempts to promote should fail due to the write capture.
-        h.promote(x, 'int');
-        expect(flow.promotedType(x), isNull);
-      });
+        x.read.as_('int').stmt, checkNotPromoted(x),
+      ]);
     });
   });
 
@@ -2362,20 +1977,20 @@
   });
 
   group('State', () {
-    var intVar = _Var('x', _Type('int'));
-    var intQVar = _Var('x', _Type('int?'));
-    var objectQVar = _Var('x', _Type('Object?'));
-    var nullVar = _Var('x', _Type('Null'));
+    var intVar = Var('x', 'int');
+    var intQVar = Var('x', 'int?');
+    var objectQVar = Var('x', 'Object?');
+    var nullVar = Var('x', 'Null');
     group('setUnreachable', () {
       var unreachable =
-          FlowModel<_Var, _Type>(Reachability.initial.setUnreachable());
-      var reachable = FlowModel<_Var, _Type>(Reachability.initial);
+          FlowModel<Var, Type>(Reachability.initial.setUnreachable());
+      var reachable = FlowModel<Var, Type>(Reachability.initial);
       test('unchanged', () {
         expect(unreachable.setUnreachable(), same(unreachable));
       });
 
       test('changed', () {
-        void _check(FlowModel<_Var, _Type> initial) {
+        void _check(FlowModel<Var, Type> initial) {
           var s = initial.setUnreachable();
           expect(s, isNot(same(initial)));
           expect(s.reachable.overallReachable, false);
@@ -2387,33 +2002,33 @@
     });
 
     test('split', () {
-      var s1 = FlowModel<_Var, _Type>(Reachability.initial);
+      var s1 = FlowModel<Var, Type>(Reachability.initial);
       var s2 = s1.split();
       expect(s2.reachable.parent, same(s1.reachable));
     });
 
     test('unsplit', () {
-      var s1 = FlowModel<_Var, _Type>(Reachability.initial.split());
+      var s1 = FlowModel<Var, Type>(Reachability.initial.split());
       var s2 = s1.unsplit();
       expect(s2.reachable, same(Reachability.initial));
     });
 
     group('unsplitTo', () {
       test('no change', () {
-        var s1 = FlowModel<_Var, _Type>(Reachability.initial.split());
+        var s1 = FlowModel<Var, Type>(Reachability.initial.split());
         var result = s1.unsplitTo(s1.reachable.parent);
         expect(result, same(s1));
       });
 
       test('unsplit once, reachable', () {
-        var s1 = FlowModel<_Var, _Type>(Reachability.initial.split());
+        var s1 = FlowModel<Var, Type>(Reachability.initial.split());
         var s2 = s1.split();
         var result = s2.unsplitTo(s1.reachable.parent);
         expect(result.reachable, same(s1.reachable));
       });
 
       test('unsplit once, unreachable', () {
-        var s1 = FlowModel<_Var, _Type>(Reachability.initial.split());
+        var s1 = FlowModel<Var, Type>(Reachability.initial.split());
         var s2 = s1.split().setUnreachable();
         var result = s2.unsplitTo(s1.reachable.parent);
         expect(result.reachable.locallyReachable, false);
@@ -2421,7 +2036,7 @@
       });
 
       test('unsplit twice, reachable', () {
-        var s1 = FlowModel<_Var, _Type>(Reachability.initial.split());
+        var s1 = FlowModel<Var, Type>(Reachability.initial.split());
         var s2 = s1.split();
         var s3 = s2.split();
         var result = s3.unsplitTo(s1.reachable.parent);
@@ -2429,7 +2044,7 @@
       });
 
       test('unsplit twice, top unreachable', () {
-        var s1 = FlowModel<_Var, _Type>(Reachability.initial.split());
+        var s1 = FlowModel<Var, Type>(Reachability.initial.split());
         var s2 = s1.split();
         var s3 = s2.split().setUnreachable();
         var result = s3.unsplitTo(s1.reachable.parent);
@@ -2438,7 +2053,7 @@
       });
 
       test('unsplit twice, previous unreachable', () {
-        var s1 = FlowModel<_Var, _Type>(Reachability.initial.split());
+        var s1 = FlowModel<Var, Type>(Reachability.initial.split());
         var s2 = s1.split().setUnreachable();
         var s3 = s2.split();
         var result = s3.unsplitTo(s1.reachable.parent);
@@ -2449,30 +2064,30 @@
 
     group('tryPromoteForTypeCheck', () {
       test('unpromoted -> unchanged (same)', () {
-        var h = _Harness();
-        var s1 = FlowModel<_Var, _Type>(Reachability.initial);
-        var s2 = s1.tryPromoteForTypeCheck(h, intVar, _Type('int')).ifTrue;
+        var h = Harness();
+        var s1 = FlowModel<Var, Type>(Reachability.initial);
+        var s2 = s1.tryPromoteForTypeCheck(h, intVar, Type('int')).ifTrue;
         expect(s2, same(s1));
       });
 
       test('unpromoted -> unchanged (supertype)', () {
-        var h = _Harness();
-        var s1 = FlowModel<_Var, _Type>(Reachability.initial);
-        var s2 = s1.tryPromoteForTypeCheck(h, intVar, _Type('Object')).ifTrue;
+        var h = Harness();
+        var s1 = FlowModel<Var, Type>(Reachability.initial);
+        var s2 = s1.tryPromoteForTypeCheck(h, intVar, Type('Object')).ifTrue;
         expect(s2, same(s1));
       });
 
       test('unpromoted -> unchanged (unrelated)', () {
-        var h = _Harness();
-        var s1 = FlowModel<_Var, _Type>(Reachability.initial);
-        var s2 = s1.tryPromoteForTypeCheck(h, intVar, _Type('String')).ifTrue;
+        var h = Harness();
+        var s1 = FlowModel<Var, Type>(Reachability.initial);
+        var s2 = s1.tryPromoteForTypeCheck(h, intVar, Type('String')).ifTrue;
         expect(s2, same(s1));
       });
 
       test('unpromoted -> subtype', () {
-        var h = _Harness();
-        var s1 = FlowModel<_Var, _Type>(Reachability.initial);
-        var s2 = s1.tryPromoteForTypeCheck(h, intQVar, _Type('int')).ifTrue;
+        var h = Harness();
+        var s1 = FlowModel<Var, Type>(Reachability.initial);
+        var s2 = s1.tryPromoteForTypeCheck(h, intQVar, Type('int')).ifTrue;
         expect(s2.reachable.overallReachable, true);
         expect(s2.variableInfo, {
           intQVar: _matchVariableModel(chain: ['int'], ofInterest: ['int'])
@@ -2480,40 +2095,40 @@
       });
 
       test('promoted -> unchanged (same)', () {
-        var h = _Harness();
-        var s1 = FlowModel<_Var, _Type>(Reachability.initial)
-            .tryPromoteForTypeCheck(h, objectQVar, _Type('int'))
+        var h = Harness();
+        var s1 = FlowModel<Var, Type>(Reachability.initial)
+            .tryPromoteForTypeCheck(h, objectQVar, Type('int'))
             .ifTrue;
-        var s2 = s1.tryPromoteForTypeCheck(h, objectQVar, _Type('int')).ifTrue;
+        var s2 = s1.tryPromoteForTypeCheck(h, objectQVar, Type('int')).ifTrue;
         expect(s2, same(s1));
       });
 
       test('promoted -> unchanged (supertype)', () {
-        var h = _Harness();
-        var s1 = FlowModel<_Var, _Type>(Reachability.initial)
-            .tryPromoteForTypeCheck(h, objectQVar, _Type('int'))
+        var h = Harness();
+        var s1 = FlowModel<Var, Type>(Reachability.initial)
+            .tryPromoteForTypeCheck(h, objectQVar, Type('int'))
             .ifTrue;
         var s2 =
-            s1.tryPromoteForTypeCheck(h, objectQVar, _Type('Object')).ifTrue;
+            s1.tryPromoteForTypeCheck(h, objectQVar, Type('Object')).ifTrue;
         expect(s2, same(s1));
       });
 
       test('promoted -> unchanged (unrelated)', () {
-        var h = _Harness();
-        var s1 = FlowModel<_Var, _Type>(Reachability.initial)
-            .tryPromoteForTypeCheck(h, objectQVar, _Type('int'))
+        var h = Harness();
+        var s1 = FlowModel<Var, Type>(Reachability.initial)
+            .tryPromoteForTypeCheck(h, objectQVar, Type('int'))
             .ifTrue;
         var s2 =
-            s1.tryPromoteForTypeCheck(h, objectQVar, _Type('String')).ifTrue;
+            s1.tryPromoteForTypeCheck(h, objectQVar, Type('String')).ifTrue;
         expect(s2, same(s1));
       });
 
       test('promoted -> subtype', () {
-        var h = _Harness();
-        var s1 = FlowModel<_Var, _Type>(Reachability.initial)
-            .tryPromoteForTypeCheck(h, objectQVar, _Type('int?'))
+        var h = Harness();
+        var s1 = FlowModel<Var, Type>(Reachability.initial)
+            .tryPromoteForTypeCheck(h, objectQVar, Type('int?'))
             .ifTrue;
-        var s2 = s1.tryPromoteForTypeCheck(h, objectQVar, _Type('int')).ifTrue;
+        var s2 = s1.tryPromoteForTypeCheck(h, objectQVar, Type('int')).ifTrue;
         expect(s2.reachable.overallReachable, true);
         expect(s2.variableInfo, {
           objectQVar: _matchVariableModel(
@@ -2523,29 +2138,29 @@
     });
 
     group('write', () {
-      var objectQVar = _Var('x', _Type('Object?'));
+      var objectQVar = Var('x', 'Object?');
 
       test('without declaration', () {
         // This should not happen in valid code, but test that we don't crash.
-        var h = _Harness();
-        var s = FlowModel<_Var, _Type>(Reachability.initial)
-            .write(objectQVar, _Type('Object?'), h);
+        var h = Harness();
+        var s = FlowModel<Var, Type>(Reachability.initial)
+            .write(objectQVar, Type('Object?'), h);
         expect(s.variableInfo[objectQVar], isNull);
       });
 
       test('unchanged', () {
-        var h = _Harness();
-        var s1 = FlowModel<_Var, _Type>(Reachability.initial)
+        var h = Harness();
+        var s1 = FlowModel<Var, Type>(Reachability.initial)
             .declare(objectQVar, true);
-        var s2 = s1.write(objectQVar, _Type('Object?'), h);
+        var s2 = s1.write(objectQVar, Type('Object?'), h);
         expect(s2, same(s1));
       });
 
       test('marks as assigned', () {
-        var h = _Harness();
-        var s1 = FlowModel<_Var, _Type>(Reachability.initial)
+        var h = Harness();
+        var s1 = FlowModel<Var, Type>(Reachability.initial)
             .declare(objectQVar, false);
-        var s2 = s1.write(objectQVar, _Type('int?'), h);
+        var s2 = s1.write(objectQVar, Type('int?'), h);
         expect(s2.reachable.overallReachable, true);
         expect(
             s2.infoFor(objectQVar),
@@ -2557,13 +2172,13 @@
       });
 
       test('un-promotes fully', () {
-        var h = _Harness();
-        var s1 = FlowModel<_Var, _Type>(Reachability.initial)
+        var h = Harness();
+        var s1 = FlowModel<Var, Type>(Reachability.initial)
             .declare(objectQVar, true)
-            .tryPromoteForTypeCheck(h, objectQVar, _Type('int'))
+            .tryPromoteForTypeCheck(h, objectQVar, Type('int'))
             .ifTrue;
         expect(s1.variableInfo, contains(objectQVar));
-        var s2 = s1.write(objectQVar, _Type('int?'), h);
+        var s2 = s1.write(objectQVar, Type('int?'), h);
         expect(s2.reachable.overallReachable, true);
         expect(s2.variableInfo, {
           objectQVar: _matchVariableModel(
@@ -2575,12 +2190,12 @@
       });
 
       test('un-promotes partially, when no exact match', () {
-        var h = _Harness();
-        var s1 = FlowModel<_Var, _Type>(Reachability.initial)
+        var h = Harness();
+        var s1 = FlowModel<Var, Type>(Reachability.initial)
             .declare(objectQVar, true)
-            .tryPromoteForTypeCheck(h, objectQVar, _Type('num?'))
+            .tryPromoteForTypeCheck(h, objectQVar, Type('num?'))
             .ifTrue
-            .tryPromoteForTypeCheck(h, objectQVar, _Type('int'))
+            .tryPromoteForTypeCheck(h, objectQVar, Type('int'))
             .ifTrue;
         expect(s1.variableInfo, {
           objectQVar: _matchVariableModel(
@@ -2589,7 +2204,7 @@
               assigned: true,
               unassigned: false)
         });
-        var s2 = s1.write(objectQVar, _Type('num'), h);
+        var s2 = s1.write(objectQVar, Type('num'), h);
         expect(s2.reachable.overallReachable, true);
         expect(s2.variableInfo, {
           objectQVar: _matchVariableModel(
@@ -2601,14 +2216,14 @@
       });
 
       test('un-promotes partially, when exact match', () {
-        var h = _Harness();
-        var s1 = FlowModel<_Var, _Type>(Reachability.initial)
+        var h = Harness();
+        var s1 = FlowModel<Var, Type>(Reachability.initial)
             .declare(objectQVar, true)
-            .tryPromoteForTypeCheck(h, objectQVar, _Type('num?'))
+            .tryPromoteForTypeCheck(h, objectQVar, Type('num?'))
             .ifTrue
-            .tryPromoteForTypeCheck(h, objectQVar, _Type('num'))
+            .tryPromoteForTypeCheck(h, objectQVar, Type('num'))
             .ifTrue
-            .tryPromoteForTypeCheck(h, objectQVar, _Type('int'))
+            .tryPromoteForTypeCheck(h, objectQVar, Type('int'))
             .ifTrue;
         expect(s1.variableInfo, {
           objectQVar: _matchVariableModel(
@@ -2617,7 +2232,7 @@
               assigned: true,
               unassigned: false)
         });
-        var s2 = s1.write(objectQVar, _Type('num'), h);
+        var s2 = s1.write(objectQVar, Type('num'), h);
         expect(s2.reachable.overallReachable, true);
         expect(s2.variableInfo, {
           objectQVar: _matchVariableModel(
@@ -2629,12 +2244,12 @@
       });
 
       test('leaves promoted, when exact match', () {
-        var h = _Harness();
-        var s1 = FlowModel<_Var, _Type>(Reachability.initial)
+        var h = Harness();
+        var s1 = FlowModel<Var, Type>(Reachability.initial)
             .declare(objectQVar, true)
-            .tryPromoteForTypeCheck(h, objectQVar, _Type('num?'))
+            .tryPromoteForTypeCheck(h, objectQVar, Type('num?'))
             .ifTrue
-            .tryPromoteForTypeCheck(h, objectQVar, _Type('num'))
+            .tryPromoteForTypeCheck(h, objectQVar, Type('num'))
             .ifTrue;
         expect(s1.variableInfo, {
           objectQVar: _matchVariableModel(
@@ -2643,18 +2258,18 @@
               assigned: true,
               unassigned: false)
         });
-        var s2 = s1.write(objectQVar, _Type('num'), h);
+        var s2 = s1.write(objectQVar, Type('num'), h);
         expect(s2.reachable.overallReachable, true);
         expect(s2.variableInfo, same(s1.variableInfo));
       });
 
       test('leaves promoted, when writing a subtype', () {
-        var h = _Harness();
-        var s1 = FlowModel<_Var, _Type>(Reachability.initial)
+        var h = Harness();
+        var s1 = FlowModel<Var, Type>(Reachability.initial)
             .declare(objectQVar, true)
-            .tryPromoteForTypeCheck(h, objectQVar, _Type('num?'))
+            .tryPromoteForTypeCheck(h, objectQVar, Type('num?'))
             .ifTrue
-            .tryPromoteForTypeCheck(h, objectQVar, _Type('num'))
+            .tryPromoteForTypeCheck(h, objectQVar, Type('num'))
             .ifTrue;
         expect(s1.variableInfo, {
           objectQVar: _matchVariableModel(
@@ -2663,34 +2278,32 @@
               assigned: true,
               unassigned: false)
         });
-        var s2 = s1.write(objectQVar, _Type('int'), h);
+        var s2 = s1.write(objectQVar, Type('int'), h);
         expect(s2.reachable.overallReachable, true);
         expect(s2.variableInfo, same(s1.variableInfo));
       });
 
       group('Promotes to NonNull of a type of interest', () {
         test('when declared type', () {
-          var h = _Harness();
-          var x = _Var('x', _Type('int?'));
+          var h = Harness();
+          var x = Var('x', 'int?');
 
-          var s1 =
-              FlowModel<_Var, _Type>(Reachability.initial).declare(x, true);
+          var s1 = FlowModel<Var, Type>(Reachability.initial).declare(x, true);
           expect(s1.variableInfo, {
             x: _matchVariableModel(chain: null),
           });
 
-          var s2 = s1.write(x, _Type('int'), h);
+          var s2 = s1.write(x, Type('int'), h);
           expect(s2.variableInfo, {
             x: _matchVariableModel(chain: ['int']),
           });
         });
 
         test('when declared type, if write-captured', () {
-          var h = _Harness();
-          var x = h.addVar('x', 'int?');
+          var h = Harness();
+          var x = Var('x', 'int?');
 
-          var s1 =
-              FlowModel<_Var, _Type>(Reachability.initial).declare(x, true);
+          var s1 = FlowModel<Var, Type>(Reachability.initial).declare(x, true);
           expect(s1.variableInfo, {
             x: _matchVariableModel(chain: null),
           });
@@ -2701,17 +2314,17 @@
           });
 
           // 'x' is write-captured, so not promoted
-          var s3 = s2.write(x, _Type('int'), h);
+          var s3 = s2.write(x, Type('int'), h);
           expect(s3.variableInfo, {
             x: _matchVariableModel(chain: null, writeCaptured: true),
           });
         });
 
         test('when promoted', () {
-          var h = _Harness();
-          var s1 = FlowModel<_Var, _Type>(Reachability.initial)
+          var h = Harness();
+          var s1 = FlowModel<Var, Type>(Reachability.initial)
               .declare(objectQVar, true)
-              .tryPromoteForTypeCheck(h, objectQVar, _Type('int?'))
+              .tryPromoteForTypeCheck(h, objectQVar, Type('int?'))
               .ifTrue;
           expect(s1.variableInfo, {
             objectQVar: _matchVariableModel(
@@ -2719,7 +2332,7 @@
               ofInterest: ['int?'],
             ),
           });
-          var s2 = s1.write(objectQVar, _Type('int'), h);
+          var s2 = s1.write(objectQVar, Type('int'), h);
           expect(s2.variableInfo, {
             objectQVar: _matchVariableModel(
               chain: ['int?', 'int'],
@@ -2729,10 +2342,10 @@
         });
 
         test('when not promoted', () {
-          var h = _Harness();
-          var s1 = FlowModel<_Var, _Type>(Reachability.initial)
+          var h = Harness();
+          var s1 = FlowModel<Var, Type>(Reachability.initial)
               .declare(objectQVar, true)
-              .tryPromoteForTypeCheck(h, objectQVar, _Type('int?'))
+              .tryPromoteForTypeCheck(h, objectQVar, Type('int?'))
               .ifFalse;
           expect(s1.variableInfo, {
             objectQVar: _matchVariableModel(
@@ -2740,7 +2353,7 @@
               ofInterest: ['int?'],
             ),
           });
-          var s2 = s1.write(objectQVar, _Type('int'), h);
+          var s2 = s1.write(objectQVar, Type('int'), h);
           expect(s2.variableInfo, {
             objectQVar: _matchVariableModel(
               chain: ['Object', 'int'],
@@ -2751,10 +2364,10 @@
       });
 
       test('Promotes to type of interest when not previously promoted', () {
-        var h = _Harness();
-        var s1 = FlowModel<_Var, _Type>(Reachability.initial)
+        var h = Harness();
+        var s1 = FlowModel<Var, Type>(Reachability.initial)
             .declare(objectQVar, true)
-            .tryPromoteForTypeCheck(h, objectQVar, _Type('num?'))
+            .tryPromoteForTypeCheck(h, objectQVar, Type('num?'))
             .ifFalse;
         expect(s1.variableInfo, {
           objectQVar: _matchVariableModel(
@@ -2762,7 +2375,7 @@
             ofInterest: ['num?'],
           ),
         });
-        var s2 = s1.write(objectQVar, _Type('num?'), h);
+        var s2 = s1.write(objectQVar, Type('num?'), h);
         expect(s2.variableInfo, {
           objectQVar: _matchVariableModel(
             chain: ['num?'],
@@ -2772,12 +2385,12 @@
       });
 
       test('Promotes to type of interest when previously promoted', () {
-        var h = _Harness();
-        var s1 = FlowModel<_Var, _Type>(Reachability.initial)
+        var h = Harness();
+        var s1 = FlowModel<Var, Type>(Reachability.initial)
             .declare(objectQVar, true)
-            .tryPromoteForTypeCheck(h, objectQVar, _Type('num?'))
+            .tryPromoteForTypeCheck(h, objectQVar, Type('num?'))
             .ifTrue
-            .tryPromoteForTypeCheck(h, objectQVar, _Type('int?'))
+            .tryPromoteForTypeCheck(h, objectQVar, Type('int?'))
             .ifFalse;
         expect(s1.variableInfo, {
           objectQVar: _matchVariableModel(
@@ -2785,7 +2398,7 @@
             ofInterest: ['num?', 'int?'],
           ),
         });
-        var s2 = s1.write(objectQVar, _Type('int?'), h);
+        var s2 = s1.write(objectQVar, Type('int?'), h);
         expect(s2.variableInfo, {
           objectQVar: _matchVariableModel(
             chain: ['num?', 'int?'],
@@ -2796,56 +2409,56 @@
 
       group('Multiple candidate types of interest', () {
         group('; choose most specific', () {
-          _Harness h;
+          Harness h;
 
           setUp(() {
-            h = _Harness();
+            h = Harness();
 
             // class A {}
             // class B extends A {}
             // class C extends B {}
-            h.addSubtype(_Type('Object'), _Type('A'), false);
-            h.addSubtype(_Type('Object'), _Type('A?'), false);
-            h.addSubtype(_Type('Object'), _Type('B?'), false);
-            h.addSubtype(_Type('A'), _Type('Object'), true);
-            h.addSubtype(_Type('A'), _Type('Object?'), true);
-            h.addSubtype(_Type('A'), _Type('A?'), true);
-            h.addSubtype(_Type('A'), _Type('B'), false);
-            h.addSubtype(_Type('A'), _Type('B?'), false);
-            h.addSubtype(_Type('A?'), _Type('Object'), false);
-            h.addSubtype(_Type('A?'), _Type('Object?'), true);
-            h.addSubtype(_Type('A?'), _Type('A'), false);
-            h.addSubtype(_Type('A?'), _Type('B?'), false);
-            h.addSubtype(_Type('B'), _Type('Object'), true);
-            h.addSubtype(_Type('B'), _Type('A'), true);
-            h.addSubtype(_Type('B'), _Type('A?'), true);
-            h.addSubtype(_Type('B'), _Type('B?'), true);
-            h.addSubtype(_Type('B?'), _Type('Object'), false);
-            h.addSubtype(_Type('B?'), _Type('Object?'), true);
-            h.addSubtype(_Type('B?'), _Type('A'), false);
-            h.addSubtype(_Type('B?'), _Type('A?'), true);
-            h.addSubtype(_Type('B?'), _Type('B'), false);
-            h.addSubtype(_Type('C'), _Type('Object'), true);
-            h.addSubtype(_Type('C'), _Type('A'), true);
-            h.addSubtype(_Type('C'), _Type('A?'), true);
-            h.addSubtype(_Type('C'), _Type('B'), true);
-            h.addSubtype(_Type('C'), _Type('B?'), true);
+            h.addSubtype(Type('Object'), Type('A'), false);
+            h.addSubtype(Type('Object'), Type('A?'), false);
+            h.addSubtype(Type('Object'), Type('B?'), false);
+            h.addSubtype(Type('A'), Type('Object'), true);
+            h.addSubtype(Type('A'), Type('Object?'), true);
+            h.addSubtype(Type('A'), Type('A?'), true);
+            h.addSubtype(Type('A'), Type('B'), false);
+            h.addSubtype(Type('A'), Type('B?'), false);
+            h.addSubtype(Type('A?'), Type('Object'), false);
+            h.addSubtype(Type('A?'), Type('Object?'), true);
+            h.addSubtype(Type('A?'), Type('A'), false);
+            h.addSubtype(Type('A?'), Type('B?'), false);
+            h.addSubtype(Type('B'), Type('Object'), true);
+            h.addSubtype(Type('B'), Type('A'), true);
+            h.addSubtype(Type('B'), Type('A?'), true);
+            h.addSubtype(Type('B'), Type('B?'), true);
+            h.addSubtype(Type('B?'), Type('Object'), false);
+            h.addSubtype(Type('B?'), Type('Object?'), true);
+            h.addSubtype(Type('B?'), Type('A'), false);
+            h.addSubtype(Type('B?'), Type('A?'), true);
+            h.addSubtype(Type('B?'), Type('B'), false);
+            h.addSubtype(Type('C'), Type('Object'), true);
+            h.addSubtype(Type('C'), Type('A'), true);
+            h.addSubtype(Type('C'), Type('A?'), true);
+            h.addSubtype(Type('C'), Type('B'), true);
+            h.addSubtype(Type('C'), Type('B?'), true);
 
-            h.addFactor(_Type('Object'), _Type('A?'), _Type('Object'));
-            h.addFactor(_Type('Object'), _Type('B?'), _Type('Object'));
-            h.addFactor(_Type('Object?'), _Type('A'), _Type('Object?'));
-            h.addFactor(_Type('Object?'), _Type('A?'), _Type('Object'));
-            h.addFactor(_Type('Object?'), _Type('B?'), _Type('Object'));
+            h.addFactor(Type('Object'), Type('A?'), Type('Object'));
+            h.addFactor(Type('Object'), Type('B?'), Type('Object'));
+            h.addFactor(Type('Object?'), Type('A'), Type('Object?'));
+            h.addFactor(Type('Object?'), Type('A?'), Type('Object'));
+            h.addFactor(Type('Object?'), Type('B?'), Type('Object'));
           });
 
           test('; first', () {
-            var x = _Var('x', _Type('Object?'));
+            var x = Var('x', 'Object?');
 
-            var s1 = FlowModel<_Var, _Type>(Reachability.initial)
+            var s1 = FlowModel<Var, Type>(Reachability.initial)
                 .declare(x, true)
-                .tryPromoteForTypeCheck(h, x, _Type('B?'))
+                .tryPromoteForTypeCheck(h, x, Type('B?'))
                 .ifFalse
-                .tryPromoteForTypeCheck(h, x, _Type('A?'))
+                .tryPromoteForTypeCheck(h, x, Type('A?'))
                 .ifFalse;
             expect(s1.variableInfo, {
               x: _matchVariableModel(
@@ -2854,7 +2467,7 @@
               ),
             });
 
-            var s2 = s1.write(x, _Type('C'), h);
+            var s2 = s1.write(x, Type('C'), h);
             expect(s2.variableInfo, {
               x: _matchVariableModel(
                 chain: ['Object', 'B'],
@@ -2864,13 +2477,13 @@
           });
 
           test('; second', () {
-            var x = _Var('x', _Type('Object?'));
+            var x = Var('x', 'Object?');
 
-            var s1 = FlowModel<_Var, _Type>(Reachability.initial)
+            var s1 = FlowModel<Var, Type>(Reachability.initial)
                 .declare(x, true)
-                .tryPromoteForTypeCheck(h, x, _Type('A?'))
+                .tryPromoteForTypeCheck(h, x, Type('A?'))
                 .ifFalse
-                .tryPromoteForTypeCheck(h, x, _Type('B?'))
+                .tryPromoteForTypeCheck(h, x, Type('B?'))
                 .ifFalse;
             expect(s1.variableInfo, {
               x: _matchVariableModel(
@@ -2879,7 +2492,7 @@
               ),
             });
 
-            var s2 = s1.write(x, _Type('C'), h);
+            var s2 = s1.write(x, Type('C'), h);
             expect(s2.variableInfo, {
               x: _matchVariableModel(
                 chain: ['Object', 'B'],
@@ -2889,13 +2502,13 @@
           });
 
           test('; nullable and non-nullable', () {
-            var x = _Var('x', _Type('Object?'));
+            var x = Var('x', 'Object?');
 
-            var s1 = FlowModel<_Var, _Type>(Reachability.initial)
+            var s1 = FlowModel<Var, Type>(Reachability.initial)
                 .declare(x, true)
-                .tryPromoteForTypeCheck(h, x, _Type('A'))
+                .tryPromoteForTypeCheck(h, x, Type('A'))
                 .ifFalse
-                .tryPromoteForTypeCheck(h, x, _Type('A?'))
+                .tryPromoteForTypeCheck(h, x, Type('A?'))
                 .ifFalse;
             expect(s1.variableInfo, {
               x: _matchVariableModel(
@@ -2904,7 +2517,7 @@
               ),
             });
 
-            var s2 = s1.write(x, _Type('B'), h);
+            var s2 = s1.write(x, Type('B'), h);
             expect(s2.variableInfo, {
               x: _matchVariableModel(
                 chain: ['Object', 'A'],
@@ -2916,12 +2529,12 @@
 
         group('; ambiguous', () {
           test('; no promotion', () {
-            var h = _Harness();
-            var s1 = FlowModel<_Var, _Type>(Reachability.initial)
+            var h = Harness();
+            var s1 = FlowModel<Var, Type>(Reachability.initial)
                 .declare(objectQVar, true)
-                .tryPromoteForTypeCheck(h, objectQVar, _Type('num?'))
+                .tryPromoteForTypeCheck(h, objectQVar, Type('num?'))
                 .ifFalse
-                .tryPromoteForTypeCheck(h, objectQVar, _Type('num*'))
+                .tryPromoteForTypeCheck(h, objectQVar, Type('num*'))
                 .ifFalse;
             expect(s1.variableInfo, {
               objectQVar: _matchVariableModel(
@@ -2929,7 +2542,7 @@
                 ofInterest: ['num?', 'num*'],
               ),
             });
-            var s2 = s1.write(objectQVar, _Type('int'), h);
+            var s2 = s1.write(objectQVar, Type('int'), h);
             // It's ambiguous whether to promote to num? or num*, so we don't
             // promote.
             expect(s2, same(s1));
@@ -2937,12 +2550,12 @@
         });
 
         test('exact match', () {
-          var h = _Harness();
-          var s1 = FlowModel<_Var, _Type>(Reachability.initial)
+          var h = Harness();
+          var s1 = FlowModel<Var, Type>(Reachability.initial)
               .declare(objectQVar, true)
-              .tryPromoteForTypeCheck(h, objectQVar, _Type('num?'))
+              .tryPromoteForTypeCheck(h, objectQVar, Type('num?'))
               .ifFalse
-              .tryPromoteForTypeCheck(h, objectQVar, _Type('num*'))
+              .tryPromoteForTypeCheck(h, objectQVar, Type('num*'))
               .ifFalse;
           expect(s1.variableInfo, {
             objectQVar: _matchVariableModel(
@@ -2950,7 +2563,7 @@
               ofInterest: ['num?', 'num*'],
             ),
           });
-          var s2 = s1.write(objectQVar, _Type('num?'), h);
+          var s2 = s1.write(objectQVar, Type('num?'), h);
           // It's ambiguous whether to promote to num? or num*, but since the
           // written type is exactly num?, we use that.
           expect(s2.variableInfo, {
@@ -2965,15 +2578,15 @@
 
     group('demotion, to NonNull', () {
       test('when promoted via test', () {
-        var x = _Var('x', _Type('Object?'));
+        var x = Var('x', 'Object?');
 
-        var h = _Harness();
+        var h = Harness();
 
-        var s1 = FlowModel<_Var, _Type>(Reachability.initial)
+        var s1 = FlowModel<Var, Type>(Reachability.initial)
             .declare(x, true)
-            .tryPromoteForTypeCheck(h, x, _Type('num?'))
+            .tryPromoteForTypeCheck(h, x, Type('num?'))
             .ifTrue
-            .tryPromoteForTypeCheck(h, x, _Type('int?'))
+            .tryPromoteForTypeCheck(h, x, Type('int?'))
             .ifTrue;
         expect(s1.variableInfo, {
           x: _matchVariableModel(
@@ -2982,7 +2595,7 @@
           ),
         });
 
-        var s2 = s1.write(x, _Type('double'), h);
+        var s2 = s1.write(x, Type('double'), h);
         expect(s2.variableInfo, {
           x: _matchVariableModel(
             chain: ['num?', 'num'],
@@ -2993,10 +2606,10 @@
     });
 
     group('declare', () {
-      var objectQVar = _Var('x', _Type('Object?'));
+      var objectQVar = Var('x', 'Object?');
 
       test('initialized', () {
-        var s = FlowModel<_Var, _Type>(Reachability.initial)
+        var s = FlowModel<Var, Type>(Reachability.initial)
             .declare(objectQVar, true);
         expect(s.variableInfo, {
           objectQVar: _matchVariableModel(assigned: true, unassigned: false),
@@ -3004,7 +2617,7 @@
       });
 
       test('not initialized', () {
-        var s = FlowModel<_Var, _Type>(Reachability.initial)
+        var s = FlowModel<Var, Type>(Reachability.initial)
             .declare(objectQVar, false);
         expect(s.variableInfo, {
           objectQVar: _matchVariableModel(assigned: false, unassigned: true),
@@ -3014,15 +2627,15 @@
 
     group('markNonNullable', () {
       test('unpromoted -> unchanged', () {
-        var h = _Harness();
-        var s1 = FlowModel<_Var, _Type>(Reachability.initial);
+        var h = Harness();
+        var s1 = FlowModel<Var, Type>(Reachability.initial);
         var s2 = s1.tryMarkNonNullable(h, intVar).ifTrue;
         expect(s2, same(s1));
       });
 
       test('unpromoted -> promoted', () {
-        var h = _Harness();
-        var s1 = FlowModel<_Var, _Type>(Reachability.initial);
+        var h = Harness();
+        var s1 = FlowModel<Var, Type>(Reachability.initial);
         var s2 = s1.tryMarkNonNullable(h, intQVar).ifTrue;
         expect(s2.reachable.overallReachable, true);
         expect(s2.infoFor(intQVar),
@@ -3030,18 +2643,18 @@
       });
 
       test('promoted -> unchanged', () {
-        var h = _Harness();
-        var s1 = FlowModel<_Var, _Type>(Reachability.initial)
-            .tryPromoteForTypeCheck(h, objectQVar, _Type('int'))
+        var h = Harness();
+        var s1 = FlowModel<Var, Type>(Reachability.initial)
+            .tryPromoteForTypeCheck(h, objectQVar, Type('int'))
             .ifTrue;
         var s2 = s1.tryMarkNonNullable(h, objectQVar).ifTrue;
         expect(s2, same(s1));
       });
 
       test('promoted -> re-promoted', () {
-        var h = _Harness();
-        var s1 = FlowModel<_Var, _Type>(Reachability.initial)
-            .tryPromoteForTypeCheck(h, objectQVar, _Type('int?'))
+        var h = Harness();
+        var s1 = FlowModel<Var, Type>(Reachability.initial)
+            .tryPromoteForTypeCheck(h, objectQVar, Type('int?'))
             .ifTrue;
         var s2 = s1.tryMarkNonNullable(h, objectQVar).ifTrue;
         expect(s2.reachable.overallReachable, true);
@@ -3052,8 +2665,8 @@
       });
 
       test('promote to Never', () {
-        var h = _Harness();
-        var s1 = FlowModel<_Var, _Type>(Reachability.initial);
+        var h = Harness();
+        var s1 = FlowModel<Var, Type>(Reachability.initial);
         var s2 = s1.tryMarkNonNullable(h, nullVar).ifTrue;
         expect(s2.reachable.overallReachable, false);
         expect(s2.infoFor(nullVar),
@@ -3064,21 +2677,21 @@
     group('joinUnassigned', () {
       group('other', () {
         test('unchanged', () {
-          var h = _Harness();
+          var h = Harness();
 
-          var a = _Var('a', _Type('int'));
-          var b = _Var('b', _Type('int'));
+          var a = Var('a', 'int');
+          var b = Var('b', 'int');
 
-          var s1 = FlowModel<_Var, _Type>(Reachability.initial)
+          var s1 = FlowModel<Var, Type>(Reachability.initial)
               .declare(a, false)
               .declare(b, false)
-              .write(a, _Type('int'), h);
+              .write(a, Type('int'), h);
           expect(s1.variableInfo, {
             a: _matchVariableModel(assigned: true, unassigned: false),
             b: _matchVariableModel(assigned: false, unassigned: true),
           });
 
-          var s2 = s1.write(a, _Type('int'), h);
+          var s2 = s1.write(a, Type('int'), h);
           expect(s2.variableInfo, {
             a: _matchVariableModel(assigned: true, unassigned: false),
             b: _matchVariableModel(assigned: false, unassigned: true),
@@ -3089,24 +2702,24 @@
         });
 
         test('changed', () {
-          var h = _Harness();
+          var h = Harness();
 
-          var a = _Var('a', _Type('int'));
-          var b = _Var('b', _Type('int'));
-          var c = _Var('c', _Type('int'));
+          var a = Var('a', 'int');
+          var b = Var('b', 'int');
+          var c = Var('c', 'int');
 
-          var s1 = FlowModel<_Var, _Type>(Reachability.initial)
+          var s1 = FlowModel<Var, Type>(Reachability.initial)
               .declare(a, false)
               .declare(b, false)
               .declare(c, false)
-              .write(a, _Type('int'), h);
+              .write(a, Type('int'), h);
           expect(s1.variableInfo, {
             a: _matchVariableModel(assigned: true, unassigned: false),
             b: _matchVariableModel(assigned: false, unassigned: true),
             c: _matchVariableModel(assigned: false, unassigned: true),
           });
 
-          var s2 = s1.write(b, _Type('int'), h);
+          var s2 = s1.write(b, Type('int'), h);
           expect(s2.variableInfo, {
             a: _matchVariableModel(assigned: true, unassigned: false),
             b: _matchVariableModel(assigned: true, unassigned: false),
@@ -3125,21 +2738,21 @@
 
     group('conservativeJoin', () {
       test('unchanged', () {
-        var h = _Harness();
-        var s1 = FlowModel<_Var, _Type>(Reachability.initial)
+        var h = Harness();
+        var s1 = FlowModel<Var, Type>(Reachability.initial)
             .declare(intQVar, true)
-            .tryPromoteForTypeCheck(h, objectQVar, _Type('int'))
+            .tryPromoteForTypeCheck(h, objectQVar, Type('int'))
             .ifTrue;
         var s2 = s1.conservativeJoin([intQVar], []);
         expect(s2, same(s1));
       });
 
       test('written', () {
-        var h = _Harness();
-        var s1 = FlowModel<_Var, _Type>(Reachability.initial)
-            .tryPromoteForTypeCheck(h, objectQVar, _Type('int'))
+        var h = Harness();
+        var s1 = FlowModel<Var, Type>(Reachability.initial)
+            .tryPromoteForTypeCheck(h, objectQVar, Type('int'))
             .ifTrue
-            .tryPromoteForTypeCheck(h, intQVar, _Type('int'))
+            .tryPromoteForTypeCheck(h, intQVar, Type('int'))
             .ifTrue;
         var s2 = s1.conservativeJoin([intQVar], []);
         expect(s2.reachable.overallReachable, true);
@@ -3150,11 +2763,11 @@
       });
 
       test('write captured', () {
-        var h = _Harness();
-        var s1 = FlowModel<_Var, _Type>(Reachability.initial)
-            .tryPromoteForTypeCheck(h, objectQVar, _Type('int'))
+        var h = Harness();
+        var s1 = FlowModel<Var, Type>(Reachability.initial)
+            .tryPromoteForTypeCheck(h, objectQVar, Type('int'))
             .ifTrue
-            .tryPromoteForTypeCheck(h, intQVar, _Type('int'))
+            .tryPromoteForTypeCheck(h, intQVar, Type('int'))
             .ifTrue;
         var s2 = s1.conservativeJoin([], [intQVar]);
         expect(s2.reachable.overallReachable, true);
@@ -3168,8 +2781,8 @@
 
     group('restrict', () {
       test('reachability', () {
-        var h = _Harness();
-        var reachable = FlowModel<_Var, _Type>(Reachability.initial);
+        var h = Harness();
+        var reachable = FlowModel<Var, Type>(Reachability.initial);
         var unreachable = reachable.setUnreachable();
         expect(reachable.restrict(h, reachable, Set()), same(reachable));
         expect(reachable.restrict(h, unreachable, Set()), same(unreachable));
@@ -3178,18 +2791,18 @@
       });
 
       test('assignments', () {
-        var h = _Harness();
-        var a = _Var('a', _Type('int'));
-        var b = _Var('b', _Type('int'));
-        var c = _Var('c', _Type('int'));
-        var d = _Var('d', _Type('int'));
-        var s0 = FlowModel<_Var, _Type>(Reachability.initial)
+        var h = Harness();
+        var a = Var('a', 'int');
+        var b = Var('b', 'int');
+        var c = Var('c', 'int');
+        var d = Var('d', 'int');
+        var s0 = FlowModel<Var, Type>(Reachability.initial)
             .declare(a, false)
             .declare(b, false)
             .declare(c, false)
             .declare(d, false);
-        var s1 = s0.write(a, _Type('int'), h).write(b, _Type('int'), h);
-        var s2 = s1.write(a, _Type('int'), h).write(c, _Type('int'), h);
+        var s1 = s0.write(a, Type('int'), h).write(b, Type('int'), h);
+        var s2 = s1.write(a, Type('int'), h).write(c, Type('int'), h);
         var result = s2.restrict(h, s1, Set());
         expect(result.infoFor(a).assigned, true);
         expect(result.infoFor(b).assigned, true);
@@ -3198,12 +2811,12 @@
       });
 
       test('write captured', () {
-        var h = _Harness();
-        var a = _Var('a', _Type('int'));
-        var b = _Var('b', _Type('int'));
-        var c = _Var('c', _Type('int'));
-        var d = _Var('d', _Type('int'));
-        var s0 = FlowModel<_Var, _Type>(Reachability.initial)
+        var h = Harness();
+        var a = Var('a', 'int');
+        var b = Var('b', 'int');
+        var c = Var('c', 'int');
+        var d = Var('d', 'int');
+        var s0 = FlowModel<Var, Type>(Reachability.initial)
             .declare(a, false)
             .declare(b, false)
             .declare(c, false)
@@ -3233,16 +2846,15 @@
       test('promotion', () {
         void _check(String thisType, String otherType, bool unsafe,
             List<String> expectedChain) {
-          var h = _Harness();
-          var x = _Var('x', _Type('Object?'));
-          var s0 =
-              FlowModel<_Var, _Type>(Reachability.initial).declare(x, true);
+          var h = Harness();
+          var x = Var('x', 'Object?');
+          var s0 = FlowModel<Var, Type>(Reachability.initial).declare(x, true);
           var s1 = thisType == null
               ? s0
-              : s0.tryPromoteForTypeCheck(h, x, _Type(thisType)).ifTrue;
+              : s0.tryPromoteForTypeCheck(h, x, Type(thisType)).ifTrue;
           var s2 = otherType == null
               ? s0
-              : s0.tryPromoteForTypeCheck(h, x, _Type(otherType)).ifTrue;
+              : s0.tryPromoteForTypeCheck(h, x, Type(otherType)).ifTrue;
           var result = s1.restrict(h, s2, unsafe ? [x].toSet() : Set());
           if (expectedChain == null) {
             expect(result.variableInfo, contains(x));
@@ -3270,8 +2882,8 @@
       test('promotion chains', () {
         // Verify that the given promotion chain matches the expected list of
         // strings.
-        void _checkChain(List<_Type> chain, List<String> expected) {
-          var strings = (chain ?? <_Type>[]).map((t) => t.type).toList();
+        void _checkChain(List<Type> chain, List<String> expected) {
+          var strings = (chain ?? <Type>[]).map((t) => t.type).toList();
           expect(strings, expected);
         }
 
@@ -3286,25 +2898,25 @@
         //   block, the expected promotion chain is [expectedResult].
         void _check(List<String> before, List<String> inTry,
             List<String> inFinally, List<String> expectedResult) {
-          var h = _Harness();
-          var x = _Var('x', _Type('Object?'));
+          var h = Harness();
+          var x = Var('x', 'Object?');
           var initialModel =
-              FlowModel<_Var, _Type>(Reachability.initial).declare(x, true);
+              FlowModel<Var, Type>(Reachability.initial).declare(x, true);
           for (var t in before) {
             initialModel =
-                initialModel.tryPromoteForTypeCheck(h, x, _Type(t)).ifTrue;
+                initialModel.tryPromoteForTypeCheck(h, x, Type(t)).ifTrue;
           }
           _checkChain(initialModel.infoFor(x).promotedTypes, before);
           var tryModel = initialModel;
           for (var t in inTry) {
-            tryModel = tryModel.tryPromoteForTypeCheck(h, x, _Type(t)).ifTrue;
+            tryModel = tryModel.tryPromoteForTypeCheck(h, x, Type(t)).ifTrue;
           }
           var expectedTryChain = before.toList()..addAll(inTry);
           _checkChain(tryModel.infoFor(x).promotedTypes, expectedTryChain);
           var finallyModel = initialModel;
           for (var t in inFinally) {
             finallyModel =
-                finallyModel.tryPromoteForTypeCheck(h, x, _Type(t)).ifTrue;
+                finallyModel.tryPromoteForTypeCheck(h, x, Type(t)).ifTrue;
           }
           var expectedFinallyChain = before.toList()..addAll(inFinally);
           _checkChain(
@@ -3340,9 +2952,9 @@
       });
 
       test('variable present in one state but not the other', () {
-        var h = _Harness();
-        var x = _Var('x', _Type('Object?'));
-        var s0 = FlowModel<_Var, _Type>(Reachability.initial);
+        var h = Harness();
+        var x = Var('x', 'Object?');
+        var s0 = FlowModel<Var, Type>(Reachability.initial);
         var s1 = s0.declare(x, true);
         expect(s0.restrict(h, s1, {}), same(s0));
         expect(s0.restrict(h, s1, {x}), same(s0));
@@ -3353,25 +2965,25 @@
   });
 
   group('joinPromotionChains', () {
-    var doubleType = _Type('double');
-    var intType = _Type('int');
-    var numType = _Type('num');
-    var objectType = _Type('Object');
+    var doubleType = Type('double');
+    var intType = Type('int');
+    var numType = Type('num');
+    var objectType = Type('Object');
 
     test('should handle nulls', () {
-      var h = _Harness();
+      var h = Harness();
       expect(VariableModel.joinPromotedTypes(null, null, h), null);
       expect(VariableModel.joinPromotedTypes(null, [intType], h), null);
       expect(VariableModel.joinPromotedTypes([intType], null, h), null);
     });
 
     test('should return null if there are no common types', () {
-      var h = _Harness();
+      var h = Harness();
       expect(VariableModel.joinPromotedTypes([intType], [doubleType], h), null);
     });
 
     test('should return common prefix if there are common types', () {
-      var h = _Harness();
+      var h = Harness();
       expect(
           VariableModel.joinPromotedTypes(
               [objectType, intType], [objectType, doubleType], h),
@@ -3383,7 +2995,7 @@
     });
 
     test('should return an input if it is a prefix of the other', () {
-      var h = _Harness();
+      var h = Harness();
       var prefix = [objectType, numType];
       var largerChain = [objectType, numType, intType];
       expect(VariableModel.joinPromotedTypes(prefix, largerChain, h),
@@ -3394,15 +3006,15 @@
     });
 
     test('should intersect', () {
-      var h = _Harness();
+      var h = Harness();
 
       // F <: E <: D <: C <: B <: A
-      var A = _Type('A');
-      var B = _Type('B');
-      var C = _Type('C');
-      var D = _Type('D');
-      var E = _Type('E');
-      var F = _Type('F');
+      var A = Type('A');
+      var B = Type('B');
+      var C = Type('C');
+      var D = Type('D');
+      var E = Type('E');
+      var F = Type('F');
       h.addSubtype(A, B, false);
       h.addSubtype(B, A, true);
       h.addSubtype(B, C, false);
@@ -3420,7 +3032,7 @@
       h.addSubtype(F, D, true);
       h.addSubtype(F, E, true);
 
-      void check(List<_Type> chain1, List<_Type> chain2, Matcher matcher) {
+      void check(List<Type> chain1, List<Type> chain2, Matcher matcher) {
         expect(
           VariableModel.joinPromotedTypes(chain1, chain2, h),
           matcher,
@@ -3471,11 +3083,11 @@
   });
 
   group('joinTypesOfInterest', () {
-    List<_Type> _makeTypes(List<String> typeNames) =>
-        typeNames.map((t) => _Type(t)).toList();
+    List<Type> _makeTypes(List<String> typeNames) =>
+        typeNames.map((t) => Type(t)).toList();
 
     test('simple prefix', () {
-      var h = _Harness();
+      var h = Harness();
       var s1 = _makeTypes(['double', 'int']);
       var s2 = _makeTypes(['double', 'int', 'bool']);
       var expected = _matchOfInterestSet(['double', 'int', 'bool']);
@@ -3484,7 +3096,7 @@
     });
 
     test('common prefix', () {
-      var h = _Harness();
+      var h = Harness();
       var s1 = _makeTypes(['double', 'int', 'String']);
       var s2 = _makeTypes(['double', 'int', 'bool']);
       var expected = _matchOfInterestSet(['double', 'int', 'String', 'bool']);
@@ -3493,7 +3105,7 @@
     });
 
     test('order mismatch', () {
-      var h = _Harness();
+      var h = Harness();
       var s1 = _makeTypes(['double', 'int']);
       var s2 = _makeTypes(['int', 'double']);
       var expected = _matchOfInterestSet(['double', 'int']);
@@ -3502,7 +3114,7 @@
     });
 
     test('small common prefix', () {
-      var h = _Harness();
+      var h = Harness();
       var s1 = _makeTypes(['int', 'double', 'String', 'bool']);
       var s2 = _makeTypes(['int', 'List', 'bool', 'Future']);
       var expected = _matchOfInterestSet(
@@ -3513,18 +3125,18 @@
   });
 
   group('join', () {
-    var x = _Var('x', _Type('Object?'));
-    var y = _Var('y', _Type('Object?'));
-    var z = _Var('z', _Type('Object?'));
-    var w = _Var('w', _Type('Object?'));
-    var intType = _Type('int');
-    var intQType = _Type('int?');
-    var stringType = _Type('String');
-    const emptyMap = const <_Var, VariableModel<_Var, _Type>>{};
+    var x = Var('x', 'Object?');
+    var y = Var('y', 'Object?');
+    var z = Var('z', 'Object?');
+    var w = Var('w', 'Object?');
+    var intType = Type('int');
+    var intQType = Type('int?');
+    var stringType = Type('String');
+    const emptyMap = const <Var, VariableModel<Var, Type>>{};
 
-    VariableModel<_Var, _Type> model(List<_Type> promotionChain,
-            {List<_Type> typesOfInterest, bool assigned = false}) =>
-        VariableModel<_Var, _Type>(
+    VariableModel<Var, Type> model(List<Type> promotionChain,
+            {List<Type> typesOfInterest, bool assigned = false}) =>
+        VariableModel<Var, Type>(
           promotionChain,
           typesOfInterest ?? promotionChain ?? [],
           assigned,
@@ -3534,7 +3146,7 @@
 
     group('without input reuse', () {
       test('promoted with unpromoted', () {
-        var h = _Harness();
+        var h = Harness();
         var p1 = {
           x: model([intType]),
           y: model(null)
@@ -3551,7 +3163,7 @@
     });
     group('should re-use an input if possible', () {
       test('identical inputs', () {
-        var h = _Harness();
+        var h = Harness();
         var p = {
           x: model([intType]),
           y: model([stringType])
@@ -3560,18 +3172,18 @@
       });
 
       test('one input empty', () {
-        var h = _Harness();
+        var h = Harness();
         var p1 = {
           x: model([intType]),
           y: model([stringType])
         };
-        var p2 = <_Var, VariableModel<_Var, _Type>>{};
+        var p2 = <Var, VariableModel<Var, Type>>{};
         expect(FlowModel.joinVariableInfo(h, p1, p2, emptyMap), same(emptyMap));
         expect(FlowModel.joinVariableInfo(h, p2, p1, emptyMap), same(emptyMap));
       });
 
       test('promoted with unpromoted', () {
-        var h = _Harness();
+        var h = Harness();
         var p1 = {
           x: model([intType])
         };
@@ -3584,7 +3196,7 @@
       });
 
       test('related type chains', () {
-        var h = _Harness();
+        var h = Harness();
         var p1 = {
           x: model([intQType, intType])
         };
@@ -3599,7 +3211,7 @@
       });
 
       test('unrelated type chains', () {
-        var h = _Harness();
+        var h = Harness();
         var p1 = {
           x: model([intType])
         };
@@ -3614,7 +3226,7 @@
       });
 
       test('sub-map', () {
-        var h = _Harness();
+        var h = Harness();
         var xModel = model([intType]);
         var p1 = {
           x: xModel,
@@ -3626,7 +3238,7 @@
       });
 
       test('sub-map with matched subtype', () {
-        var h = _Harness();
+        var h = Harness();
         var p1 = {
           x: model([intQType, intType]),
           y: model([stringType])
@@ -3642,7 +3254,7 @@
       });
 
       test('sub-map with mismatched subtype', () {
-        var h = _Harness();
+        var h = Harness();
         var p1 = {
           x: model([intQType]),
           y: model([stringType])
@@ -3658,7 +3270,7 @@
       });
 
       test('assigned', () {
-        var h = _Harness();
+        var h = Harness();
         var unassigned = model(null, assigned: false);
         var assigned = model(null, assigned: true);
         var p1 = {x: assigned, y: assigned, z: unassigned, w: unassigned};
@@ -3675,7 +3287,7 @@
       });
 
       test('write captured', () {
-        var h = _Harness();
+        var h = Harness();
         var intQModel = model([intQType]);
         var writeCapturedModel = intQModel.writeCapture();
         var p1 = {
@@ -3702,14 +3314,14 @@
   });
 
   group('merge', () {
-    var x = _Var('x', _Type('Object?'));
-    var intType = _Type('int');
-    var stringType = _Type('String');
-    const emptyMap = const <_Var, VariableModel<_Var, _Type>>{};
+    var x = Var('x', 'Object?');
+    var intType = Type('int');
+    var stringType = Type('String');
+    const emptyMap = const <Var, VariableModel<Var, Type>>{};
 
-    VariableModel<_Var, _Type> varModel(List<_Type> promotionChain,
+    VariableModel<Var, Type> varModel(List<Type> promotionChain,
             {bool assigned = false}) =>
-        VariableModel<_Var, _Type>(
+        VariableModel<Var, Type>(
           promotionChain,
           promotionChain ?? [],
           assigned,
@@ -3718,14 +3330,14 @@
         );
 
     test('first is null', () {
-      var h = _Harness();
+      var h = Harness();
       var s1 = FlowModel.withInfo(Reachability.initial.split(), {});
       var result = FlowModel.merge(h, null, s1, emptyMap);
       expect(result.reachable, same(Reachability.initial));
     });
 
     test('second is null', () {
-      var h = _Harness();
+      var h = Harness();
       var splitPoint = Reachability.initial.split();
       var afterSplit = splitPoint.split();
       var s1 = FlowModel.withInfo(afterSplit, {});
@@ -3734,7 +3346,7 @@
     });
 
     test('both are reachable', () {
-      var h = _Harness();
+      var h = Harness();
       var splitPoint = Reachability.initial.split();
       var afterSplit = splitPoint.split();
       var s1 = FlowModel.withInfo(afterSplit, {
@@ -3749,7 +3361,7 @@
     });
 
     test('first is unreachable', () {
-      var h = _Harness();
+      var h = Harness();
       var splitPoint = Reachability.initial.split();
       var afterSplit = splitPoint.split();
       var s1 = FlowModel.withInfo(afterSplit.setUnreachable(), {
@@ -3764,7 +3376,7 @@
     });
 
     test('second is unreachable', () {
-      var h = _Harness();
+      var h = Harness();
       var splitPoint = Reachability.initial.split();
       var afterSplit = splitPoint.split();
       var s1 = FlowModel.withInfo(afterSplit, {
@@ -3779,7 +3391,7 @@
     });
 
     test('both are unreachable', () {
-      var h = _Harness();
+      var h = Harness();
       var splitPoint = Reachability.initial.split();
       var afterSplit = splitPoint.split();
       var s1 = FlowModel.withInfo(afterSplit.setUnreachable(), {
@@ -3796,16 +3408,16 @@
   });
 
   group('inheritTested', () {
-    var x = _Var('x', _Type('Object?'));
-    var intType = _Type('int');
-    var stringType = _Type('String');
-    const emptyMap = const <_Var, VariableModel<_Var, _Type>>{};
+    var x = Var('x', 'Object?');
+    var intType = Type('int');
+    var stringType = Type('String');
+    const emptyMap = const <Var, VariableModel<Var, Type>>{};
 
-    VariableModel<_Var, _Type> model(List<_Type> typesOfInterest) =>
-        VariableModel<_Var, _Type>(null, typesOfInterest, true, false, false);
+    VariableModel<Var, Type> model(List<Type> typesOfInterest) =>
+        VariableModel<Var, Type>(null, typesOfInterest, true, false, false);
 
     test('inherits types of interest from other', () {
-      var h = _Harness();
+      var h = Harness();
       var m1 = FlowModel.withInfo(Reachability.initial, {
         x: model([intType])
       });
@@ -3817,7 +3429,7 @@
     });
 
     test('handles variable missing from other', () {
-      var h = _Harness();
+      var h = Harness();
       var m1 = FlowModel.withInfo(Reachability.initial, {
         x: model([intType])
       });
@@ -3826,7 +3438,7 @@
     });
 
     test('returns identical model when no changes', () {
-      var h = _Harness();
+      var h = Harness();
       var m1 = FlowModel.withInfo(Reachability.initial, {
         x: model([intType])
       });
@@ -3858,7 +3470,7 @@
 
 Matcher _matchOfInterestSet(List<String> expectedTypes) {
   return predicate(
-      (List<_Type> x) => unorderedEquals(expectedTypes)
+      (List<Type> x) => unorderedEquals(expectedTypes)
           .matches(x.map((t) => t.type).toList(), {}),
       'interest set $expectedTypes');
 }
@@ -3866,7 +3478,7 @@
 Matcher _matchPromotionChain(List<String> expectedTypes) {
   if (expectedTypes == null) return isNull;
   return predicate(
-      (List<_Type> x) =>
+      (List<Type> x) =>
           equals(expectedTypes).matches(x.map((t) => t.type).toList(), {}),
       'promotion chain $expectedTypes');
 }
@@ -3885,7 +3497,7 @@
   Matcher assignedMatcher = wrapMatcher(assigned);
   Matcher unassignedMatcher = wrapMatcher(unassigned);
   Matcher writeCapturedMatcher = wrapMatcher(writeCaptured);
-  return predicate((VariableModel<_Var, _Type> model) {
+  return predicate((VariableModel<Var, Type> model) {
     if (!chainMatcher.matches(model.promotedTypes, {})) return false;
     if (!ofInterestMatcher.matches(model.tested, {})) return false;
     if (!assignedMatcher.matches(model.assigned, {})) return false;
@@ -3899,459 +3511,3 @@
       'unassigned: ${_describeMatcher(unassignedMatcher)}, '
       'writeCaptured: ${_describeMatcher(writeCapturedMatcher)})');
 }
-
-/// Representation of an expression to be visited by the test harness.  Calling
-/// the function causes the expression to be "visited" (in other words, the
-/// appropriate methods in [FlowAnalysis] are called in the appropriate order),
-/// and the [_Expression] object representing the whole expression is returned.
-///
-/// This is used by methods in [_Harness] as a lightweight way of building up
-/// complex sequences of calls to [FlowAnalysis] that represent large
-/// expressions.
-typedef _Expression LazyExpression();
-
-class _AssignedVariablesHarness {
-  final AssignedVariables<_Node, _Var> _assignedVariables;
-
-  _AssignedVariablesHarness(this._assignedVariables);
-
-  void function(_Node node, void Function() callback) {
-    _assignedVariables.beginNode();
-    callback();
-    _assignedVariables.endNode(node, isClosureOrLateVariableInitializer: true);
-  }
-
-  void nest(_Node node, void Function() callback) {
-    _assignedVariables.beginNode();
-    callback();
-    _assignedVariables.endNode(node);
-  }
-
-  void write(_Var v) {
-    _assignedVariables.write(v);
-  }
-}
-
-class _Expression {
-  static int _idCounter = 0;
-
-  final int _id = _idCounter++;
-
-  @override
-  String toString() => 'E$_id';
-}
-
-class _Harness extends TypeOperations<_Var, _Type> {
-  static const Map<String, bool> _coreSubtypes = const {
-    'double <: Object': true,
-    'double <: num': true,
-    'double <: num?': true,
-    'double <: int': false,
-    'double <: int?': false,
-    'int <: double': false,
-    'int <: int?': true,
-    'int <: Iterable': false,
-    'int <: List': false,
-    'int <: Null': false,
-    'int <: num': true,
-    'int <: num?': true,
-    'int <: num*': true,
-    'int <: Never?': false,
-    'int <: Object': true,
-    'int <: Object?': true,
-    'int <: String': false,
-    'int? <: int': false,
-    'int? <: Null': false,
-    'int? <: num': false,
-    'int? <: num?': true,
-    'int? <: Object': false,
-    'int? <: Object?': true,
-    'Null <: int': false,
-    'Null <: Object': false,
-    'num <: int': false,
-    'num <: Iterable': false,
-    'num <: List': false,
-    'num <: num?': true,
-    'num <: num*': true,
-    'num <: Object': true,
-    'num <: Object?': true,
-    'num? <: int?': false,
-    'num? <: num': false,
-    'num? <: num*': true,
-    'num? <: Object': false,
-    'num? <: Object?': true,
-    'num* <: num': true,
-    'num* <: num?': true,
-    'num* <: Object': true,
-    'num* <: Object?': true,
-    'Iterable <: int': false,
-    'Iterable <: num': false,
-    'Iterable <: Object': true,
-    'Iterable <: Object?': true,
-    'List <: int': false,
-    'List <: Iterable': true,
-    'List <: Object': true,
-    'Never <: int': true,
-    'Never <: int?': true,
-    'Never <: Null': true,
-    'Never? <: int': false,
-    'Never? <: int?': true,
-    'Never? <: num?': true,
-    'Never? <: Object?': true,
-    'Null <: int?': true,
-    'Object <: int': false,
-    'Object <: int?': false,
-    'Object <: List': false,
-    'Object <: num': false,
-    'Object <: num?': false,
-    'Object <: Object?': true,
-    'Object? <: Object': false,
-    'Object? <: int': false,
-    'Object? <: int?': false,
-    'String <: int': false,
-    'String <: int?': false,
-    'String <: num?': false,
-    'String <: Object?': true,
-  };
-
-  static final Map<String, _Type> _coreFactors = {
-    'Object? - int': _Type('Object?'),
-    'Object? - int?': _Type('Object'),
-    'Object? - num?': _Type('Object'),
-    'Object? - Object?': _Type('Never?'),
-    'Object? - String': _Type('Object?'),
-    'Object - int': _Type('Object'),
-    'int - Object': _Type('Never'),
-    'int - String': _Type('int'),
-    'int - int': _Type('Never'),
-    'int - int?': _Type('Never'),
-    'int? - int': _Type('Never?'),
-    'int? - int?': _Type('Never'),
-    'int? - String': _Type('int?'),
-    'Null - int': _Type('Null'),
-    'num - int': _Type('num'),
-    'num? - num': _Type('Never?'),
-    'num? - int': _Type('num?'),
-    'num? - int?': _Type('num'),
-    'num? - Object': _Type('Never?'),
-    'num? - String': _Type('num?'),
-    'Object - int?': _Type('Object'),
-    'Object - num': _Type('Object'),
-    'Object - num?': _Type('Object'),
-    'Object - num*': _Type('Object'),
-    'Object - Iterable': _Type('Object'),
-    'Object? - Object': _Type('Never?'),
-    'Object? - Iterable': _Type('Object?'),
-    'Object? - num': _Type('Object?'),
-    'Iterable - List': _Type('Iterable'),
-    'num* - Object': _Type('Never'),
-  };
-
-  final Map<String, bool> _subtypes = Map.of(_coreSubtypes);
-
-  final Map<String, _Type> _factorResults = Map.of(_coreFactors);
-
-  FlowAnalysis<_Node, _Statement, _Expression, _Var, _Type> _flow;
-
-  final _assignedVariables = AssignedVariables<_Node, _Var>();
-
-  /// Returns a [LazyExpression] representing an expression with now special
-  /// flow analysis semantics.
-  LazyExpression get expr => () => _Expression();
-
-  LazyExpression get nullLiteral => () {
-        var expr = _Expression();
-        _flow.nullLiteral(expr);
-        return expr;
-      };
-
-  void addFactor(_Type from, _Type what, _Type result) {
-    var query = '$from - $what';
-    _factorResults[query] = result;
-  }
-
-  void addSubtype(_Type leftType, _Type rightType, bool isSubtype) {
-    var query = '$leftType <: $rightType';
-    _subtypes[query] = isSubtype;
-  }
-
-  _Var addVar(String name, String type) {
-    assert(_flow == null);
-    return _Var(name, _Type(type));
-  }
-
-  /// Given two [LazyExpression]s, produces a new [LazyExpression] representing
-  /// the result of combining them with `&&`.
-  LazyExpression and(LazyExpression lhs, LazyExpression rhs) {
-    return () {
-      var expr = _Expression();
-      _flow.logicalBinaryOp_begin();
-      _flow.logicalBinaryOp_rightBegin(lhs(), isAnd: true);
-      _flow.logicalBinaryOp_end(expr, rhs(), isAnd: true);
-      return expr;
-    };
-  }
-
-  void assignedVariables(void Function(_AssignedVariablesHarness) callback) {
-    callback(_AssignedVariablesHarness(_assignedVariables));
-  }
-
-  LazyExpression booleanLiteral(bool value) => () {
-        var expr = _Expression();
-        _flow.booleanLiteral(expr, value);
-        return expr;
-      };
-
-  @override
-  TypeClassification classifyType(_Type type) {
-    if (isSubtypeOf(type, _Type('Object'))) {
-      return TypeClassification.nonNullable;
-    } else if (isSubtypeOf(type, _Type('Null'))) {
-      return TypeClassification.nullOrEquivalent;
-    } else {
-      return TypeClassification.potentiallyNullable;
-    }
-  }
-
-  /// Given three [LazyExpression]s, produces a new [LazyExpression]
-  /// representing the result of combining them with `?` and `:`.
-  LazyExpression conditional(
-      LazyExpression cond, LazyExpression ifTrue, LazyExpression ifFalse) {
-    return () {
-      var expr = _Expression();
-      _flow.conditional_conditionBegin();
-      _flow.conditional_thenBegin(cond());
-      _flow.conditional_elseBegin(ifTrue());
-      _flow.conditional_end(expr, ifFalse());
-      return expr;
-    };
-  }
-
-  FlowAnalysis<_Node, _Statement, _Expression, _Var, _Type> createFlow() =>
-      FlowAnalysis<_Node, _Statement, _Expression, _Var, _Type>(
-          this, _assignedVariables);
-
-  void declare(_Var v, {@required bool initialized}) {
-    _flow.declare(v, initialized);
-  }
-
-  /// Creates a [LazyExpression] representing an `== null` check performed on
-  /// [variable].
-  LazyExpression eqNull(_Var variable, _Type type) {
-    return () {
-      var varExpr = _Expression();
-      _flow.variableRead(varExpr, variable);
-      _flow.equalityOp_rightBegin(varExpr, type);
-      var nullExpr = _Expression();
-      _flow.nullLiteral(nullExpr);
-      var expr = _Expression();
-      _flow.equalityOp_end(expr, nullExpr, _Type('Null'), notEqual: false);
-      return expr;
-    };
-  }
-
-  @override
-  _Type factor(_Type from, _Type what) {
-    var query = '$from - $what';
-    return _factorResults[query] ?? fail('Unknown factor query: $query');
-  }
-
-  /// Invokes flow analysis of a nested function.
-  void function(_Node node, void body()) {
-    _flow.functionExpression_begin(node);
-    body();
-    _flow.functionExpression_end();
-  }
-
-  /// Invokes flow analysis of an `if` statement with no `else` part.
-  void if_(LazyExpression cond, void ifTrue()) {
-    _flow.ifStatement_conditionBegin();
-    _flow.ifStatement_thenBegin(cond());
-    ifTrue();
-    _flow.ifStatement_end(false);
-  }
-
-  /// Invokes flow analysis of an `if` statement with an `else` part.
-  void ifElse(LazyExpression cond, void ifTrue(), void ifFalse()) {
-    _flow.ifStatement_conditionBegin();
-    _flow.ifStatement_thenBegin(cond());
-    ifTrue();
-    _flow.ifStatement_elseBegin();
-    ifFalse();
-    _flow.ifStatement_end(true);
-  }
-
-  /// Equivalent for `if (variable is! type) { ifTrue; }`
-  void ifIsNotType(_Var variable, String type, void ifTrue()) {
-    if_(isNotType(variableRead(variable), type), ifTrue);
-  }
-
-  @override
-  bool isNever(_Type type) {
-    return type.type == 'Never';
-  }
-
-  /// Creates a [LazyExpression] representing an `is!` check, checking whether
-  /// [subExpression] has the given [type].
-  LazyExpression isNotType(LazyExpression subExpression, String type) {
-    return () {
-      var expr = _Expression();
-      _flow.isExpression_end(expr, subExpression(), true, _Type(type));
-      return expr;
-    };
-  }
-
-  @override
-  bool isSameType(_Type type1, _Type type2) {
-    return type1.type == type2.type;
-  }
-
-  @override
-  bool isSubtypeOf(_Type leftType, _Type rightType) {
-    if (leftType.type == rightType.type) return true;
-    var query = '$leftType <: $rightType';
-    return _subtypes[query] ?? fail('Unknown subtype query: $query');
-  }
-
-  /// Creates a [LazyExpression] representing an `is` check, checking whether
-  /// [subExpression] has the given [type].
-  LazyExpression isType(LazyExpression subExpression, String type) {
-    return () {
-      var expr = _Expression();
-      _flow.isExpression_end(expr, subExpression(), false, _Type(type));
-      return expr;
-    };
-  }
-
-  /// Invokes flow analysis of a labeled block.
-  void labeledBlock(_Statement node, void body()) {
-    _flow.labeledStatement_begin(node);
-    body();
-    _flow.labeledStatement_end();
-  }
-
-  /// Creates a [LazyExpression] representing an equality check between two
-  /// other expressions.
-  LazyExpression notEqual(
-      LazyExpression lhs, _Type lhsType, LazyExpression rhs, _Type rhsType) {
-    return () {
-      var expr = _Expression();
-      _flow.equalityOp_rightBegin(lhs(), lhsType);
-      _flow.equalityOp_end(expr, rhs(), rhsType, notEqual: true);
-      return expr;
-    };
-  }
-
-  /// Creates a [LazyExpression] representing a `!= null` check performed on
-  /// [variable].
-  LazyExpression notNull(_Var variable, _Type type) {
-    return () {
-      var varExpr = _Expression();
-      _flow.variableRead(varExpr, variable);
-      _flow.equalityOp_rightBegin(varExpr, type);
-      var nullExpr = _Expression();
-      _flow.nullLiteral(nullExpr);
-      var expr = _Expression();
-      _flow.equalityOp_end(expr, nullExpr, _Type('Null'), notEqual: true);
-      return expr;
-    };
-  }
-
-  /// Given two [LazyExpression]s, produces a new [LazyExpression] representing
-  /// the result of combining them with `||`.
-  LazyExpression or(LazyExpression lhs, LazyExpression rhs) {
-    return () {
-      var expr = _Expression();
-      _flow.logicalBinaryOp_begin();
-      _flow.logicalBinaryOp_rightBegin(lhs(), isAnd: false);
-      _flow.logicalBinaryOp_end(expr, rhs(), isAnd: false);
-      return expr;
-    };
-  }
-
-  /// Creates a [LazyExpression] representing a parenthesized subexpression.
-  LazyExpression parenthesized(LazyExpression inner) {
-    return () {
-      var expr = _Expression();
-      _flow.parenthesizedExpression(expr, inner());
-      return expr;
-    };
-  }
-
-  /// Causes [variable] to be promoted to [type].
-  void promote(_Var variable, String type) {
-    ifIsNotType(variable, type, _flow.handleExit);
-  }
-
-  @override
-  _Type promoteToNonNull(_Type type) {
-    if (type.type.endsWith('?')) {
-      return _Type(type.type.substring(0, type.type.length - 1));
-    } else if (type.type == 'Null') {
-      return _Type('Never');
-    } else {
-      return type;
-    }
-  }
-
-  void run(
-      void callback(
-          FlowAnalysis<_Node, _Statement, _Expression, _Var, _Type> flow)) {
-    assert(_flow == null);
-    _flow = createFlow();
-    callback(_flow);
-    _flow.finish();
-  }
-
-  @override
-  _Type tryPromoteToType(_Type to, _Type from) {
-    if (isSubtypeOf(to, from)) {
-      return to;
-    } else {
-      return null;
-    }
-  }
-
-  LazyExpression variableRead(_Var variable) {
-    return () {
-      var expr = _Expression();
-      _flow.variableRead(expr, variable);
-      return expr;
-    };
-  }
-
-  @override
-  _Type variableType(_Var variable) {
-    return variable.type;
-  }
-}
-
-class _Node {}
-
-class _Statement extends _Node {}
-
-class _Type {
-  final String type;
-
-  _Type(this.type);
-
-  @override
-  bool operator ==(Object other) {
-    // The flow analysis engine should not compare types using operator==.  It
-    // should compare them using TypeOperations.
-    fail('Unexpected use of operator== on types');
-  }
-
-  @override
-  String toString() => type;
-}
-
-class _Var {
-  final String name;
-  final _Type type;
-
-  _Var(this.name, this.type);
-
-  @override
-  String toString() => '$type $name';
-}
diff --git a/pkg/analysis_server/lib/src/services/correction/fix/data_driven/modify_parameters.dart b/pkg/analysis_server/lib/src/services/correction/fix/data_driven/modify_parameters.dart
index 78ae593..b73a574 100644
--- a/pkg/analysis_server/lib/src/services/correction/fix/data_driven/modify_parameters.dart
+++ b/pkg/analysis_server/lib/src/services/correction/fix/data_driven/modify_parameters.dart
@@ -59,6 +59,7 @@
     var argumentList = data.argumentList;
     var arguments = argumentList.arguments;
     var argumentCount = arguments.length;
+    var templateContext = TemplateContext(argumentList.parent, fix.utils);
     var newNamed = <AddParameter>[];
     var indexToNewArgumentMap = <int, AddParameter>{};
     var argumentsToInsert = <int>[];
@@ -72,6 +73,13 @@
           argumentsToInsert.add(index);
         } else if (modification.isRequired) {
           newNamed.add(modification);
+        } else {
+          var requiredIfCondition =
+              modification.argumentValue?.requiredIfCondition;
+          if (requiredIfCondition != null &&
+              requiredIfCondition.evaluateIn(templateContext)) {
+            newNamed.add(modification);
+          }
         }
       } else if (modification is RemoveParameter) {
         var argument = modification.parameter.argumentFrom(argumentList);
@@ -95,8 +103,7 @@
         builder.write(parameter.name);
         builder.write(': ');
       }
-      parameter.argumentValue
-          .writeOn(builder, TemplateContext(argumentList.parent, fix.utils));
+      parameter.argumentValue.writeOn(builder, templateContext);
     }
 
     var insertionRanges = argumentsToInsert.contiguousSubRanges.toList();
diff --git a/pkg/analysis_server/lib/src/services/correction/fix/data_driven/transform_set_error_code.dart b/pkg/analysis_server/lib/src/services/correction/fix/data_driven/transform_set_error_code.dart
index 231b44c..508635c 100644
--- a/pkg/analysis_server/lib/src/services/correction/fix/data_driven/transform_set_error_code.dart
+++ b/pkg/analysis_server/lib/src/services/correction/fix/data_driven/transform_set_error_code.dart
@@ -155,10 +155,18 @@
       TransformSetErrorCode('yaml_syntax_error', "Parse error: {0}");
 
   /// Initialize a newly created error code.
-  const TransformSetErrorCode(String name, String message,
-      {String correction, bool hasPublishedDocs = false})
-      : super.temporary(name, message,
-            correction: correction, hasPublishedDocs: hasPublishedDocs);
+  const TransformSetErrorCode(
+    String name,
+    String message, {
+    String correction,
+    bool hasPublishedDocs = false,
+  }) : super(
+          correction: correction,
+          hasPublishedDocs: hasPublishedDocs,
+          message: message,
+          name: name,
+          uniqueName: 'TransformSetErrorCode.$name',
+        );
 
   @override
   ErrorSeverity get errorSeverity => ErrorSeverity.ERROR;
diff --git a/pkg/analysis_server/test/src/services/correction/fix/data_driven/flutter_use_case_test.dart b/pkg/analysis_server/test/src/services/correction/fix/data_driven/flutter_use_case_test.dart
index ee53183..7932354 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/data_driven/flutter_use_case_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/data_driven/flutter_use_case_test.dart
@@ -599,6 +599,264 @@
 ''');
   }
 
+  Future<void>
+      test_material_InputDecoration_defaultConstructor_matchFirstCase_deprecated() async {
+    setPackageContent('''
+class InputDecoration {
+  InputDecoration({
+    @deprecated bool hasFloatingPlaceholder: true,
+    FloatingLabelBehavior floatingLabelBehavior: FloatingLabelBehavior.auto,
+  });
+}
+enum FloatingLabelBehavior {always, auto, never}
+''');
+    addPackageDataFile('''
+version: 1
+transforms:
+  - title: 'Rename to floatingLabelBehavior'
+    date: 2020-09-24
+    element:
+      uris: ['$importUri']
+      constructor: ''
+      inClass: 'InputDecoration'
+    oneOf:
+      - if: "hasFloatingPlaceholder == 'true'"
+        changes:
+          - kind: 'addParameter'
+            index: 14
+            name: 'floatingLabelBehavior'
+            style: optional_named
+            argumentValue:
+              expression: '{% FloatingLabelBehavior %}.auto'
+              requiredIf: "hasFloatingPlaceholder == 'true'"
+              variables:
+                FloatingLabelBehavior:
+                  kind: 'import'
+                  uris: ['$importUri']
+                  name: 'FloatingLabelBehavior'
+          - kind: 'removeParameter'
+            name: 'hasFloatingPlaceholder'
+      - if: "hasFloatingPlaceholder == 'false'"
+        changes:
+          - kind: 'addParameter'
+            index: 14
+            name: 'floatingLabelBehavior'
+            style: optional_named
+            argumentValue:
+              expression: '{% FloatingLabelBehavior %}.never'
+              requiredIf: "hasFloatingPlaceholder == 'false'"
+              variables:
+                FloatingLabelBehavior:
+                  kind: 'import'
+                  uris: ['$importUri']
+                  name: 'FloatingLabelBehavior'
+          - kind: 'removeParameter'
+            name: 'hasFloatingPlaceholder'
+      - if: "hasFloatingPlaceholder != 'true' && hasFloatingPlaceholder != 'false'"
+        changes:
+          - kind: 'addParameter'
+            index: 14
+            name: 'floatingLabelBehavior'
+            style: optional_named
+            argumentValue:
+              expression: '{% hasFloatingPlaceholder %} ? {% FloatingLabelBehavior %}.auto : {% FloatingLabelBehavior %}.never'
+              requiredIf: "hasFloatingPlaceholder != 'true' && hasFloatingPlaceholder != 'false'"
+              variables:
+                FloatingLabelBehavior:
+                  kind: 'import'
+                  uris: ['$importUri']
+                  name: 'FloatingLabelBehavior'
+          - kind: 'removeParameter'
+            name: 'hasFloatingPlaceholder'
+    variables:
+      hasFloatingPlaceholder:
+        kind: 'fragment'
+        value: 'arguments[hasFloatingPlaceholder]'
+''');
+    await resolveTestCode('''
+import '$importUri';
+
+InputDecoration f(bool b) => InputDecoration(hasFloatingPlaceholder: true);
+''');
+    await assertHasFix('''
+import '$importUri';
+
+InputDecoration f(bool b) => InputDecoration(floatingLabelBehavior: FloatingLabelBehavior.auto);
+''');
+  }
+
+  Future<void>
+      test_material_InputDecoration_defaultConstructor_matchSecondCase_deprecated() async {
+    setPackageContent('''
+class InputDecoration {
+  InputDecoration({
+    @deprecated bool hasFloatingPlaceholder: true,
+    FloatingLabelBehavior floatingLabelBehavior: FloatingLabelBehavior.auto,
+  });
+}
+enum FloatingLabelBehavior {always, auto, never}
+''');
+    addPackageDataFile('''
+version: 1
+transforms:
+  - title: 'Rename to floatingLabelBehavior'
+    date: 2020-09-24
+    element:
+      uris: ['$importUri']
+      constructor: ''
+      inClass: 'InputDecoration'
+    oneOf:
+      - if: "hasFloatingPlaceholder == 'true'"
+        changes:
+          - kind: 'addParameter'
+            index: 14
+            name: 'floatingLabelBehavior'
+            style: optional_named
+            argumentValue:
+              expression: '{% FloatingLabelBehavior %}.auto'
+              requiredIf: "hasFloatingPlaceholder == 'true'"
+              variables:
+                FloatingLabelBehavior:
+                  kind: 'import'
+                  uris: ['$importUri']
+                  name: 'FloatingLabelBehavior'
+          - kind: 'removeParameter'
+            name: 'hasFloatingPlaceholder'
+      - if: "hasFloatingPlaceholder == 'false'"
+        changes:
+          - kind: 'addParameter'
+            index: 14
+            name: 'floatingLabelBehavior'
+            style: optional_named
+            argumentValue:
+              expression: '{% FloatingLabelBehavior %}.never'
+              requiredIf: "hasFloatingPlaceholder == 'false'"
+              variables:
+                FloatingLabelBehavior:
+                  kind: 'import'
+                  uris: ['$importUri']
+                  name: 'FloatingLabelBehavior'
+          - kind: 'removeParameter'
+            name: 'hasFloatingPlaceholder'
+      - if: "hasFloatingPlaceholder != 'true' && hasFloatingPlaceholder != 'false'"
+        changes:
+          - kind: 'addParameter'
+            index: 14
+            name: 'floatingLabelBehavior'
+            style: optional_named
+            argumentValue:
+              expression: '{% hasFloatingPlaceholder %} ? {% FloatingLabelBehavior %}.auto : {% FloatingLabelBehavior %}.never'
+              requiredIf: "hasFloatingPlaceholder != 'true' && hasFloatingPlaceholder != 'false'"
+              variables:
+                FloatingLabelBehavior:
+                  kind: 'import'
+                  uris: ['$importUri']
+                  name: 'FloatingLabelBehavior'
+          - kind: 'removeParameter'
+            name: 'hasFloatingPlaceholder'
+    variables:
+      hasFloatingPlaceholder:
+        kind: 'fragment'
+        value: 'arguments[hasFloatingPlaceholder]'
+''');
+    await resolveTestCode('''
+import '$importUri';
+
+InputDecoration f(bool b) => InputDecoration(hasFloatingPlaceholder: false);
+''');
+    await assertHasFix('''
+import '$importUri';
+
+InputDecoration f(bool b) => InputDecoration(floatingLabelBehavior: FloatingLabelBehavior.never);
+''');
+  }
+
+  Future<void>
+      test_material_InputDecoration_defaultConstructor_matchThirdCase_deprecated() async {
+    setPackageContent('''
+class InputDecoration {
+  InputDecoration({
+    @deprecated bool hasFloatingPlaceholder: true,
+    FloatingLabelBehavior floatingLabelBehavior: FloatingLabelBehavior.auto,
+  });
+}
+enum FloatingLabelBehavior {always, auto, never}
+''');
+    addPackageDataFile('''
+version: 1
+transforms:
+  - title: 'Rename to floatingLabelBehavior'
+    date: 2020-09-24
+    element:
+      uris: ['$importUri']
+      constructor: ''
+      inClass: 'InputDecoration'
+    oneOf:
+      - if: "hasFloatingPlaceholder == 'true'"
+        changes:
+          - kind: 'addParameter'
+            index: 14
+            name: 'floatingLabelBehavior'
+            style: optional_named
+            argumentValue:
+              expression: '{% FloatingLabelBehavior %}.auto'
+              requiredIf: "hasFloatingPlaceholder == 'true'"
+              variables:
+                FloatingLabelBehavior:
+                  kind: 'import'
+                  uris: ['$importUri']
+                  name: 'FloatingLabelBehavior'
+          - kind: 'removeParameter'
+            name: 'hasFloatingPlaceholder'
+      - if: "hasFloatingPlaceholder == 'false'"
+        changes:
+          - kind: 'addParameter'
+            index: 14
+            name: 'floatingLabelBehavior'
+            style: optional_named
+            argumentValue:
+              expression: '{% FloatingLabelBehavior %}.never'
+              requiredIf: "hasFloatingPlaceholder == 'false'"
+              variables:
+                FloatingLabelBehavior:
+                  kind: 'import'
+                  uris: ['$importUri']
+                  name: 'FloatingLabelBehavior'
+          - kind: 'removeParameter'
+            name: 'hasFloatingPlaceholder'
+      - if: "hasFloatingPlaceholder != 'true' && hasFloatingPlaceholder != 'false'"
+        changes:
+          - kind: 'addParameter'
+            index: 14
+            name: 'floatingLabelBehavior'
+            style: optional_named
+            argumentValue:
+              expression: '{% hasFloatingPlaceholder %} ? {% FloatingLabelBehavior %}.auto : {% FloatingLabelBehavior %}.never'
+              requiredIf: "hasFloatingPlaceholder != 'true' && hasFloatingPlaceholder != 'false'"
+              variables:
+                FloatingLabelBehavior:
+                  kind: 'import'
+                  uris: ['$importUri']
+                  name: 'FloatingLabelBehavior'
+          - kind: 'removeParameter'
+            name: 'hasFloatingPlaceholder'
+    variables:
+      hasFloatingPlaceholder:
+        kind: 'fragment'
+        value: 'arguments[hasFloatingPlaceholder]'
+''');
+    await resolveTestCode('''
+import '$importUri';
+
+InputDecoration f(bool b) => InputDecoration(hasFloatingPlaceholder: b);
+''');
+    await assertHasFix('''
+import '$importUri';
+
+InputDecoration f(bool b) => InputDecoration(floatingLabelBehavior: b ? FloatingLabelBehavior.auto : FloatingLabelBehavior.never);
+''');
+  }
+
   Future<void> test_material_Scaffold_of_matchFirstCase() async {
     setPackageContent('''
 class Scaffold {
@@ -817,10 +1075,7 @@
 ''');
   }
 
-  @failingTest
   Future<void> test_material_showDialog_deprecated() async {
-    // This test is failing because there is no way to specify that if a `child`
-    // was previously provided that a `builder` should be provided.
     setPackageContent('''
 void showDialog({
   @deprecated Widget child,
@@ -844,10 +1099,11 @@
         style: optional_named
         argumentValue:
           expression: '(context) => {% widget %}'
+          requiredIf: "widget != ''"
           variables:
             widget:
-              kind: argument
-              name: 'child'
+              kind: fragment
+              value: 'arguments[child]'
       - kind: 'removeParameter'
         name: 'child'
 ''');
@@ -867,10 +1123,7 @@
 ''');
   }
 
-  @failingTest
   Future<void> test_material_showDialog_removed() async {
-    // This test is failing because there is no way to specify that if a `child`
-    // was previously provided that a `builder` should be provided.
     setPackageContent('''
 void showDialog({
   @deprecated Widget child,
@@ -894,10 +1147,11 @@
         style: optional_named
         argumentValue:
           expression: '(context) => {% widget %}'
+          requiredIf: "widget != ''"
           variables:
             widget:
-              kind: argument
-              name: 'child'
+              kind: fragment
+              value: 'arguments[child]'
       - kind: 'removeParameter'
         name: 'child'
 ''');
diff --git a/pkg/analyzer/doc/design/summaries.md b/pkg/analyzer/doc/design/summaries.md
new file mode 100644
index 0000000..3b3d623
--- /dev/null
+++ b/pkg/analyzer/doc/design/summaries.md
@@ -0,0 +1,103 @@
+# Summaries in Dart analyzer
+
+The purpose of this document is to provide a high-level overview of the summaries linking, storage format, and reading
+in Dart analyzer.
+
+## Design Considerations
+
+There are a couple of considerations to keep in mind when discussing the design.
+
+**We want the linking to be done using AST.** Default values, constructor initializers, and field initializers should be
+stored in their resolved state, with elements and type, because we need them to perform constant evaluation.
+
+**We want separation between AST and resolution.** Files change rarely, usually the user changes just one file, and this
+affects resolution of this file and a multiple other files. But only the resolution, not AST. So, we want to keep pieces
+that are not affected by the change.
+
+**We want to read only as much as necessary to do resolution.** Libraries often have many classes, but when we resolve a
+file, we don’t need all these classes, only those that are actually referenced. So, we want the format to support
+loading individual classes, functions, etc.
+
+## High level view
+
+When the analyzer needs to resolve a file, it works in the following way:
+
+1. Find the library cycle that contains this file, and library cycles of its dependencies, down to SDK.
+
+2. Link these library cycles from SDK up to the target cycle.
+
+3. Add linked bundles to `LinkedElementFactory`.
+
+4. When we need a specific element, we call `LinkedElementFactory.elementOfReference`. It will request parent elements,
+   and eventually load the containing library, the containing class, method, etc.
+
+## Lazy loading
+
+We try to load only libraries that are necessary. When a `PackageBundleReader` is created, it decodes only the header of
+the bundle - with the list of library URIs contained in the bundle, and creates `LibraryReader`s.
+
+When `LinkedElementFactory.createLibraryElementForReading` is invoked, the corresponding `LibraryReader` is asked to
+load units, which are `UnitReader`s. Each `UnitReader` keeps track of the location of its AST and resolution portions
+in `astReader` and `resolutionReader`. When `UnitReader` is created, it reads the index of top-level declarations, and
+fills `Reference` subtree. For each `Reference` we set its `nodeAccessor`, a pointer to the `_UnitMemberReader`, which
+can be used to load the corresponding AST node. This is a way to present the index of the unit to `LinkedElementFactory`
+.
+
+To support lazy loading the package bundle has the index of libraries, the library has the index of units, the unit has
+the index of top-level declarations, the class / extension / mixin has the index of members.
+
+Any time when we need the element for a `Reference`, we call `elementOfReference` of `LinkedElementFactory`, which
+asks `Reference.nodeAccessor` for the AST node, and then creates the corresponding `Element` wrapper around it, and
+stores into `Reference.element`. For example for `ClassDeclaration` it will create `ClassElement`. No resolution is
+required yet.
+
+When `Reference.element` is already set, we just return it, we have already done loading AST node and creating the
+element for this `Reference`.
+
+When we link libraries, we don’t use `LinkedElementFactory` to read nodes and create elements, because we already have
+full ASTs, and we can create elements for all nodes in advance, and put them into corresponding `Reference` children.
+
+We say that we need the element for a `Reference` because resolution stores elements as such references - a pair of the
+name, and the parent reference. So, we may have an empty `Reference` first, without `element` and `nodeAccessor`, then
+when `elementOfReference` is invoked, it will fill both for a `Reference`. But its siblings will stay unfilled.
+
+When we ask an `Element` anything that requires resolution, we apply resolution to the whole AST node of the element.
+For example, when we ask `ClassElement` for `supertype`, we apply resolution to the `ClassDeclaration` header (but not
+to any member of the `ClassDeclaration`) - supertype, mixins, interfaces. We do this by calling `applyResolution`
+of `AstLinkedContext`. We get `AstLinkedContext` from the node, which implements `HasAstLinkedContext`.
+
+`AstBinaryWriter` writes two streams of information at once - the AST itself, and resolution. In the future we might
+split writing AST and resolution into separate writers.
+
+Resolution information is just a sequence of elements and types, which is stored when we visit the resolved AST
+in `AstBinaryWriter`. We use the helper `_ResolutionSink` to encode elements and types into bytes.
+
+Resolution is applied to unresolved AST using `ApplyResolutionVisitor`, which visits AST nodes in the same sequence
+as `AstBinaryWriter`, and takes either elements or types from the same (untyped, unmarked in any way) stream of
+resolution bytes. `LinkedResolutionReader` corresponds to `_ResolutionSink` - it decodes elements and types from bytes.
+
+Each raw element is represented by an integer, an index in the reference table. This table is collected during writing
+in `_BundleWriterReferences`, and stored by `BundleWriterResolution` during `BundleWriter.finish()`. During
+loading `BundleReader` creates `_ReferenceReader`, which lazily converts names and parent references into `Reference`
+instances in the given `LinkedElementFactory` (from which we just take `rootReference`, not actually any elements). Once
+we have `Reference` for the element that we need to decode, we actually ask `LinkedResolutionReader` for the element,
+see above.
+
+In addition to raw elements, there are “members” (which is not the best name) - which might be `Element`s which we want
+to convert to legacy because they are declared in a null safe library, but we want their legacy types; or actually
+members of a class with type parameters and with some `Substitution` applied to them; or both.
+
+Strings are encoded as integers, during writing using `StringIndexer`, and during loading using `_StringTable`. We
+use `SummaryDataReader` to load primitive types, and also strings.
+
+## Known limitations
+
+Currently `LibraryScope` and its basis `_LibraryImportScope` and `PrefixScope` - they all work by asking all elements
+from the imported libraries. Which means that we load all top-level nodes of these libraries (and all libraries that
+they export). Fortunately we don’t apply resolution to these elements until we try to access some property of these
+elements, e.g. the return type of a getter. But still, we probably don’t actually use all the imported elements, and we
+potentially could avoid loading all these AST nodes. A solution could be to work with `Reference`s instead.
+
+Similarly `InheritanceManager3` builds the whole interface of a class, and loads all members of the class and all
+members of all its superinterfaces. But again, we might only call a few methods, and might not need any superinterfaces.
+A solution might be to fill class interfaces on demand.
diff --git a/pkg/analyzer/lib/dart/sdk/build_sdk_summary.dart b/pkg/analyzer/lib/dart/sdk/build_sdk_summary.dart
index f3c9a79..1caa015 100644
--- a/pkg/analyzer/lib/dart/sdk/build_sdk_summary.dart
+++ b/pkg/analyzer/lib/dart/sdk/build_sdk_summary.dart
@@ -17,10 +17,9 @@
 import 'package:analyzer/src/dart/sdk/sdk.dart';
 import 'package:analyzer/src/generated/engine.dart';
 import 'package:analyzer/src/generated/source.dart';
-import 'package:analyzer/src/summary/format.dart';
-import 'package:analyzer/src/summary/summarize_elements.dart';
 import 'package:analyzer/src/summary2/link.dart';
 import 'package:analyzer/src/summary2/linked_element_factory.dart';
+import 'package:analyzer/src/summary2/package_bundle_format.dart';
 import 'package:analyzer/src/summary2/reference.dart';
 import 'package:meta/meta.dart';
 import 'package:pub_semver/pub_semver.dart';
@@ -85,7 +84,6 @@
 
   AllowedExperiments allowedExperiments;
   Version languageVersion;
-  final PackageBundleAssembler bundleAssembler = PackageBundleAssembler();
 
   _Builder(
     this.context,
@@ -106,21 +104,24 @@
       Reference.root(),
     );
 
-    var linkResult = link(elementFactory, inputLibraries);
-    bundleAssembler.setBundle2(linkResult.bundle);
+    var linkResult = link(elementFactory, inputLibraries, false);
 
-    var buffer = PackageBundleBuilder(
-      bundle2: linkResult.bundle,
-      sdk: PackageBundleSdkBuilder(
+    var bundleBuilder = PackageBundleBuilder();
+    for (var library in inputLibraries) {
+      bundleBuilder.addLibrary(
+        library.uriStr,
+        library.units.map((e) => e.uriStr).toList(),
+      );
+    }
+    return bundleBuilder.finish(
+      astBytes: linkResult.astBytes,
+      resolutionBytes: linkResult.resolutionBytes,
+      sdk: PackageBundleSdk(
+        languageVersionMajor: languageVersion.major,
+        languageVersionMinor: languageVersion.minor,
         allowedExperimentsJson: allowedExperimentsJson,
-        languageVersion: LinkedLanguageVersionBuilder(
-          major: languageVersion.major,
-          minor: languageVersion.minor,
-        ),
       ),
-    ).toBuffer();
-
-    return buffer is Uint8List ? buffer : Uint8List.fromList(buffer);
+    );
   }
 
   void _addLibrary(Source source) {
diff --git a/pkg/analyzer/lib/error/error.dart b/pkg/analyzer/lib/error/error.dart
index 38b3ce4..2357561 100644
--- a/pkg/analyzer/lib/error/error.dart
+++ b/pkg/analyzer/lib/error/error.dart
@@ -148,6 +148,7 @@
   CompileTimeErrorCode.DUPLICATE_CONSTRUCTOR_DEFAULT,
   CompileTimeErrorCode.DUPLICATE_CONSTRUCTOR_NAME,
   CompileTimeErrorCode.DUPLICATE_DEFINITION,
+  CompileTimeErrorCode.DUPLICATE_FIELD_FORMAL_PARAMETER,
   CompileTimeErrorCode.DUPLICATE_NAMED_ARGUMENT,
   CompileTimeErrorCode.DUPLICATE_PART,
   CompileTimeErrorCode.ENUM_CONSTANT_SAME_NAME_AS_ENCLOSING,
diff --git a/pkg/analyzer/lib/src/analysis_options/error/option_codes.dart b/pkg/analyzer/lib/src/analysis_options/error/option_codes.dart
index 43ae068..b67961f 100644
--- a/pkg/analyzer/lib/src/analysis_options/error/option_codes.dart
+++ b/pkg/analyzer/lib/src/analysis_options/error/option_codes.dart
@@ -31,7 +31,12 @@
   /// Initialize a newly created error code to have the given [name].
   const AnalysisOptionsErrorCode(String name, String message,
       {String correction})
-      : super.temporary(name, message, correction: correction);
+      : super(
+          correction: correction,
+          message: message,
+          name: name,
+          uniqueName: 'AnalysisOptionsErrorCode.$name',
+        );
 
   @override
   ErrorSeverity get errorSeverity => ErrorSeverity.ERROR;
@@ -78,7 +83,12 @@
   /// Initialize a newly created hint code to have the given [name].
   const AnalysisOptionsHintCode(String name, String message,
       {String correction})
-      : super.temporary(name, message, correction: correction);
+      : super(
+          correction: correction,
+          message: message,
+          name: name,
+          uniqueName: 'AnalysisOptionsHintCode.$name',
+        );
 
   @override
   ErrorSeverity get errorSeverity => ErrorSeverity.INFO;
@@ -200,7 +210,12 @@
   /// Initialize a newly created warning code to have the given [name].
   const AnalysisOptionsWarningCode(String name, String message,
       {String correction})
-      : super.temporary(name, message, correction: correction);
+      : super(
+          correction: correction,
+          message: message,
+          name: name,
+          uniqueName: 'AnalysisOptionsWarningCode.$name',
+        );
 
   @override
   ErrorSeverity get errorSeverity => ErrorSeverity.WARNING;
diff --git a/pkg/analyzer/lib/src/dart/analysis/driver.dart b/pkg/analyzer/lib/src/dart/analysis/driver.dart
index 57c4895..38952f2 100644
--- a/pkg/analyzer/lib/src/dart/analysis/driver.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/driver.dart
@@ -85,7 +85,7 @@
 /// TODO(scheglov) Clean up the list of implicitly analyzed files.
 class AnalysisDriver implements AnalysisDriverGeneric {
   /// The version of data format, should be incremented on every format change.
-  static const int DATA_VERSION = 113;
+  static const int DATA_VERSION = 114;
 
   /// The length of the list returned by [_computeDeclaredVariablesSignature].
   static const int _declaredVariablesSignatureLength = 4;
diff --git a/pkg/analyzer/lib/src/dart/analysis/file_state.dart b/pkg/analyzer/lib/src/dart/analysis/file_state.dart
index 7a5926e..aa961ed 100644
--- a/pkg/analyzer/lib/src/dart/analysis/file_state.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/file_state.dart
@@ -35,7 +35,6 @@
 import 'package:analyzer/src/summary/format.dart';
 import 'package:analyzer/src/summary/idl.dart';
 import 'package:analyzer/src/summary/package_bundle_reader.dart';
-import 'package:analyzer/src/summary2/informative_data.dart';
 import 'package:analyzer/src/workspace/workspace.dart';
 import 'package:convert/convert.dart';
 import 'package:crypto/crypto.dart';
@@ -43,6 +42,7 @@
 import 'package:pub_semver/pub_semver.dart';
 
 var counterFileStateRefresh = 0;
+var counterUnlinkedBytes = 0;
 var counterUnlinkedLinkedBytes = 0;
 int fileObjectId = 0;
 var timerFileStateRefresh = Stopwatch();
@@ -125,6 +125,7 @@
   Set<String> _definedClassMemberNames;
   Set<String> _definedTopLevelNames;
   Set<String> _referencedNames;
+  List<int> _unlinkedSignature;
   String _unlinkedKey;
   AnalysisDriverUnlinkedUnit _driverUnlinkedUnit;
   List<int> _apiSignature;
@@ -356,6 +357,9 @@
   /// The [UnlinkedUnit2] of the file.
   UnlinkedUnit2 get unlinked2 => _unlinked2;
 
+  /// The MD5 signature based on the content, feature sets, language version.
+  List<int> get unlinkedSignature => _unlinkedSignature;
+
   /// Return the [uri] string.
   String get uriStr => uri.toString();
 
@@ -414,7 +418,6 @@
     }
 
     // Prepare the unlinked bundle key.
-    List<int> contentSignature;
     {
       var signature = ApiSignature();
       signature.addUint32List(_fsState._saltForUnlinked);
@@ -422,8 +425,8 @@
       signature.addLanguageVersion(packageLanguageVersion);
       signature.addString(_contentHash);
       signature.addBool(_exists);
-      contentSignature = signature.toByteList();
-      _unlinkedKey = '${hex.encode(contentSignature)}.unlinked2';
+      _unlinkedSignature = signature.toByteList();
+      _unlinkedKey = '${hex.encode(_unlinkedSignature)}.unlinked2';
     }
 
     // Prepare bytes of the unlinked bundle - existing or new.
@@ -445,6 +448,8 @@
             subtypedNames: subtypedNames,
           ).toBuffer();
           _fsState._byteStore.put(_unlinkedKey, bytes);
+          counterUnlinkedBytes += bytes.length;
+          counterUnlinkedLinkedBytes += bytes.length;
         });
       }
     }
@@ -671,7 +676,6 @@
         ),
       );
     }
-    var informativeData = createInformativeData(unit);
     return UnlinkedUnit2Builder(
       apiSignature: computeUnlinkedApiSignature(unit),
       exports: exports,
@@ -680,7 +684,6 @@
       hasLibraryDirective: hasLibraryDirective,
       hasPartOfDirective: hasPartOfDirective,
       lineStarts: unit.lineInfo.lineStarts,
-      informativeData: informativeData,
     );
   }
 
@@ -820,6 +823,7 @@
   FileSystemStateTestView get test => _testView;
 
   /// Return the [FileState] instance that correspond to an unresolved URI.
+  /// TODO(scheglov) Remove it.
   FileState get unresolvedFile {
     if (_unresolvedFile == null) {
       var featureSet = FeatureSet.latestLanguageVersion();
diff --git a/pkg/analyzer/lib/src/dart/analysis/library_context.dart b/pkg/analyzer/lib/src/dart/analysis/library_context.dart
index 1402523..dae3c73 100644
--- a/pkg/analyzer/lib/src/dart/analysis/library_context.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/library_context.dart
@@ -16,17 +16,17 @@
 import 'package:analyzer/src/generated/engine.dart'
     show AnalysisContext, AnalysisOptions;
 import 'package:analyzer/src/generated/source.dart';
-import 'package:analyzer/src/summary/idl.dart';
+import 'package:analyzer/src/summary/api_signature.dart';
 import 'package:analyzer/src/summary/package_bundle_reader.dart';
+import 'package:analyzer/src/summary2/bundle_reader.dart';
 import 'package:analyzer/src/summary2/link.dart' as link2;
-import 'package:analyzer/src/summary2/linked_bundle_context.dart';
 import 'package:analyzer/src/summary2/linked_element_factory.dart';
 import 'package:analyzer/src/summary2/reference.dart';
 import 'package:meta/meta.dart';
 
 var counterLinkedLibraries = 0;
 var counterLoadedLibraries = 0;
-var timerBundleToBytes = Stopwatch();
+var timerBundleToBytes = Stopwatch(); // TODO(scheglov) use
 var timerInputLibraries = Stopwatch();
 var timerLinking = Stopwatch();
 var timerLoad2 = Stopwatch();
@@ -100,8 +100,6 @@
   /// Load data required to access elements of the given [targetLibrary].
   void load2(FileState targetLibrary) {
     timerLoad2.start();
-    var inputBundles = <LinkedNodeBundle>[];
-
     var librariesTotal = 0;
     var librariesLoaded = 0;
     var librariesLinked = 0;
@@ -119,14 +117,31 @@
 
       librariesTotal += cycle.libraries.length;
 
+      if (cycle.isUnresolvedFile) {
+        return;
+      }
+
       cycle.directDependencies.forEach(
         (e) => loadBundle(e, '$debugPrefix  '),
       );
 
-      var key = cycle.transitiveSignature + '.linked_bundle';
-      var bytes = byteStore.get(key);
+      String astKey;
+      {
+        var signature = ApiSignature();
+        for (var library in cycle.libraries) {
+          for (var file in library.libraryFiles) {
+            signature.addBytes(file.unlinkedSignature);
+          }
+        }
+        astKey = '${signature.toHex()}.ast';
+      }
 
-      if (bytes == null) {
+      var resolutionKey = cycle.transitiveSignature + '.linked_bundle';
+
+      var astBytes = byteStore.get(astKey);
+      var resolutionBytes = byteStore.get(resolutionKey);
+
+      if (astBytes == null || resolutionBytes == null) {
         librariesLinkedTimer.start();
 
         testView.linkedCycles.add(
@@ -212,49 +227,39 @@
         link2.LinkResult linkResult;
         try {
           timerLinking.start();
-          linkResult = link2.link(elementFactory, inputLibraries);
+          linkResult = link2.link(elementFactory, inputLibraries, true);
           librariesLinked += cycle.libraries.length;
-          counterLinkedLibraries += linkResult.bundle.libraries.length;
+          counterLinkedLibraries += inputLibraries.length;
           timerLinking.stop();
         } catch (exception, stackTrace) {
           _throwLibraryCycleLinkException(cycle, exception, stackTrace);
         }
 
-        timerBundleToBytes.start();
-        bytes = linkResult.bundle.toBuffer();
-        timerBundleToBytes.stop();
+        astBytes = linkResult.astBytes;
+        resolutionBytes = linkResult.resolutionBytes;
 
-        byteStore.put(key, bytes);
-        bytesPut += bytes.length;
-        counterUnlinkedLinkedBytes += bytes.length;
+        byteStore.put(astKey, astBytes);
+        byteStore.put(resolutionKey, resolutionBytes);
+        bytesPut += astBytes.length;
+        bytesPut += resolutionBytes.length;
+        counterUnlinkedLinkedBytes += astBytes.length;
+        counterUnlinkedLinkedBytes += resolutionBytes.length;
 
         librariesLinkedTimer.stop();
       } else {
         // TODO(scheglov) Take / clear parsed units in files.
-        bytesGet += bytes.length;
+        bytesGet += astBytes.length;
+        bytesGet += resolutionBytes.length;
         librariesLoaded += cycle.libraries.length;
       }
 
-      var bundle = LinkedNodeBundle.fromBuffer(bytes);
-      inputBundles.add(bundle);
       elementFactory.addBundle(
-        LinkedBundleContext(elementFactory, bundle),
+        BundleReader(
+          elementFactory: elementFactory,
+          astBytes: astBytes,
+          resolutionBytes: resolutionBytes,
+        ),
       );
-      counterLoadedLibraries += bundle.libraries.length;
-
-      // Set informative data.
-      for (var libraryFile in cycle.libraries) {
-        for (var unitFile in libraryFile.libraryFiles) {
-          elementFactory.setInformativeData(
-            libraryFile.uriStr,
-            unitFile.uriStr,
-            unitFile.unlinked2.informativeData,
-          );
-        }
-      }
-
-      // We might have just linked dart:core, ensure the type provider.
-      _createElementFactoryTypeProvider();
     }
 
     logger.run('Prepare linked bundles', () {
@@ -296,7 +301,11 @@
     if (externalSummaries != null) {
       for (var bundle in externalSummaries.bundles) {
         elementFactory.addBundle(
-          LinkedBundleContext(elementFactory, bundle.bundle2),
+          BundleReader(
+            elementFactory: elementFactory,
+            astBytes: bundle.astBytes,
+            resolutionBytes: bundle.resolutionBytes,
+          ),
         );
       }
     }
diff --git a/pkg/analyzer/lib/src/dart/analysis/library_graph.dart b/pkg/analyzer/lib/src/dart/analysis/library_graph.dart
index dfcfb0d..bb04579 100644
--- a/pkg/analyzer/lib/src/dart/analysis/library_graph.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/library_graph.dart
@@ -51,6 +51,10 @@
 
   LibraryCycle.external() : transitiveSignature = '<external>';
 
+  bool get isUnresolvedFile {
+    return libraries.length == 1 && libraries[0].isUnresolved;
+  }
+
   /// Invalidate this cycle and any cycles that directly or indirectly use it.
   ///
   /// Practically invalidation means that we clear the library cycle in all the
diff --git a/pkg/analyzer/lib/src/dart/ast/ast.dart b/pkg/analyzer/lib/src/dart/ast/ast.dart
index 961a12e..c906376 100644
--- a/pkg/analyzer/lib/src/dart/ast/ast.dart
+++ b/pkg/analyzer/lib/src/dart/ast/ast.dart
@@ -21,6 +21,7 @@
 import 'package:analyzer/src/generated/java_engine.dart';
 import 'package:analyzer/src/generated/source.dart' show LineInfo, Source;
 import 'package:analyzer/src/generated/utilities_dart.dart';
+import 'package:analyzer/src/summary2/linked_unit_context.dart';
 
 /// Two or more string literals that are implicitly concatenated because of
 /// being adjacent (separated only by whitespace).
@@ -724,6 +725,18 @@
       identical(child, _leftHandSide);
 }
 
+abstract class AstLinkedContext {
+  List<ClassMember> get classMembers;
+  int get codeLength;
+  int get codeOffset;
+  bool get isClassWithConstConstructor;
+  List<Directive> get unitDirectives;
+  void applyResolution(LinkedUnitContext unitContext);
+  int getVariableDeclarationCodeLength(VariableDeclaration node);
+  int getVariableDeclarationCodeOffset(VariableDeclaration node);
+  void readDocumentationComment();
+}
+
 /// A node in the AST structure for a Dart program.
 abstract class AstNodeImpl implements AstNode {
   /// The parent of the node, or `null` if the node is the root of an AST
@@ -1418,6 +1431,7 @@
 ///        [ImplementsClause]?
 ///        '{' [ClassMember]* '}'
 class ClassDeclarationImpl extends ClassOrMixinDeclarationImpl
+    with HasAstLinkedContext
     implements ClassDeclaration {
   /// The 'abstract' keyword, or `null` if the keyword was absent.
   @override
@@ -1666,7 +1680,9 @@
 ///
 ///    mixinApplication ::=
 ///        [TypeName] [WithClause] [ImplementsClause]? ';'
-class ClassTypeAliasImpl extends TypeAliasImpl implements ClassTypeAlias {
+class ClassTypeAliasImpl extends TypeAliasImpl
+    with HasAstLinkedContext
+    implements ClassTypeAlias {
   /// The type parameters for the class, or `null` if the class does not have
   /// any type parameters.
   TypeParameterListImpl _typeParameters;
@@ -2019,6 +2035,11 @@
   @override
   final FeatureSet featureSet;
 
+  /// Data that is read during loading this node from summary, but is not
+  /// fully applied yet. For example in many cases we don't need the
+  /// documentation comment, and it is expensive to decode strings.
+  Object summaryData;
+
   /// Initialize a newly created compilation unit to have the given directives
   /// and declarations. The [scriptTag] can be `null` if there is no script tag
   /// in the compilation unit. The list of [directives] can be `null` if there
@@ -2370,6 +2391,7 @@
 ///    initializerList ::=
 ///        ':' [ConstructorInitializer] (',' [ConstructorInitializer])*
 class ConstructorDeclarationImpl extends ClassMemberImpl
+    with HasAstLinkedContext
     implements ConstructorDeclaration {
   /// The token for the 'external' keyword, or `null` if the constructor is not
   /// external.
@@ -3246,6 +3268,7 @@
 
 /// The declaration of an enum constant.
 class EnumConstantDeclarationImpl extends DeclarationImpl
+    with HasAstLinkedContext
     implements EnumConstantDeclaration {
   /// The name of the constant.
   SimpleIdentifierImpl _name;
@@ -3298,6 +3321,7 @@
 ///        metadata 'enum' [SimpleIdentifier] '{' [SimpleIdentifier]
 ///        (',' [SimpleIdentifier])* (',')? '}'
 class EnumDeclarationImpl extends NamedCompilationUnitMemberImpl
+    with HasAstLinkedContext
     implements EnumDeclaration {
   /// The 'enum' keyword.
   @override
@@ -3376,6 +3400,7 @@
 ///    exportDirective ::=
 ///        [Annotation] 'export' [StringLiteral] [Combinator]* ';'
 class ExportDirectiveImpl extends NamespaceDirectiveImpl
+    with HasAstLinkedContext
     implements ExportDirective {
   /// Initialize a newly created export directive. Either or both of the
   /// [comment] and [metadata] can be `null` if the directive does not have the
@@ -3708,6 +3733,7 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class ExtensionDeclarationImpl extends CompilationUnitMemberImpl
+    with HasAstLinkedContext
     implements ExtensionDeclaration {
   @override
   Token extensionKeyword;
@@ -3911,7 +3937,9 @@
 ///
 ///    fieldDeclaration ::=
 ///        'static'? [VariableDeclarationList] ';'
-class FieldDeclarationImpl extends ClassMemberImpl implements FieldDeclaration {
+class FieldDeclarationImpl extends ClassMemberImpl
+    with HasAstLinkedContext
+    implements FieldDeclaration {
   @override
   Token abstractKeyword;
 
@@ -4305,6 +4333,11 @@
 ///      | [DefaultFormalParameter]
 abstract class FormalParameterImpl extends AstNodeImpl
     implements FormalParameter {
+  /// Data that is read during loading this node from summary, but is not
+  /// fully applied yet. For example in many cases we don't need the
+  /// documentation comment, and it is expensive to decode strings.
+  Object summaryData;
+
   @override
   ParameterElement get declaredElement {
     SimpleIdentifier identifier = this.identifier;
@@ -4740,6 +4773,7 @@
 ///    functionSignature ::=
 ///        [Type]? ('get' | 'set')? [SimpleIdentifier] [FormalParameterList]
 class FunctionDeclarationImpl extends NamedCompilationUnitMemberImpl
+    with HasAstLinkedContext
     implements FunctionDeclaration {
   /// The token representing the 'external' keyword, or `null` if this is not an
   /// external function.
@@ -5049,7 +5083,9 @@
 ///
 ///    functionPrefix ::=
 ///        [TypeName]? [SimpleIdentifier]
-class FunctionTypeAliasImpl extends TypeAliasImpl implements FunctionTypeAlias {
+class FunctionTypeAliasImpl extends TypeAliasImpl
+    with HasAstLinkedContext
+    implements FunctionTypeAlias {
   /// The name of the return type of the function type being defined, or `null`
   /// if no return type was given.
   TypeAnnotationImpl _returnType;
@@ -5363,7 +5399,9 @@
 ///    functionTypeAlias ::=
 ///        metadata 'typedef' [SimpleIdentifier] [TypeParameterList]? =
 ///        [FunctionType] ';'
-class GenericTypeAliasImpl extends TypeAliasImpl implements GenericTypeAlias {
+class GenericTypeAliasImpl extends TypeAliasImpl
+    with HasAstLinkedContext
+    implements GenericTypeAlias {
   /// The type being defined by the alias.
   TypeAnnotationImpl _type;
 
@@ -5450,6 +5488,10 @@
   }
 }
 
+mixin HasAstLinkedContext {
+  AstLinkedContext linkedContext;
+}
+
 /// A combinator that restricts the names being imported to those that are not
 /// in a given list.
 ///
@@ -5719,6 +5761,7 @@
 ///      | [Annotation] 'import' [StringLiteral] 'deferred' 'as' identifier
 //         [Combinator]* ';'
 class ImportDirectiveImpl extends NamespaceDirectiveImpl
+    with HasAstLinkedContext
     implements ImportDirective {
   /// The token representing the 'deferred' keyword, or `null` if the imported
   /// is not deferred.
@@ -6543,6 +6586,11 @@
   @override
   Token semicolon;
 
+  /// Data that is read during loading this node from summary, but is not
+  /// fully applied yet. For example in many cases we don't need the
+  /// documentation comment, and it is expensive to decode strings.
+  Object summaryData;
+
   /// Initialize a newly created library directive. Either or both of the
   /// [comment] and [metadata] can be `null` if the directive does not have the
   /// corresponding attribute.
@@ -6815,6 +6863,7 @@
 ///        [SimpleIdentifier]
 ///      | 'operator' [SimpleIdentifier]
 class MethodDeclarationImpl extends ClassMemberImpl
+    with HasAstLinkedContext
     implements MethodDeclaration {
   /// The token for the 'external' keyword, or `null` if the constructor is not
   /// external.
@@ -7154,6 +7203,7 @@
 ///        metadata? 'mixin' [SimpleIdentifier] [TypeParameterList]?
 ///        [RequiresClause]? [ImplementsClause]? '{' [ClassMember]* '}'
 class MixinDeclarationImpl extends ClassOrMixinDeclarationImpl
+    with HasAstLinkedContext
     implements MixinDeclaration {
   @override
   Token mixinKeyword;
@@ -9807,6 +9857,7 @@
 ///        ('final' | 'const') type? staticFinalDeclarationList ';'
 ///      | variableDeclaration ';'
 class TopLevelVariableDeclarationImpl extends CompilationUnitMemberImpl
+    with HasAstLinkedContext
     implements TopLevelVariableDeclaration {
   /// The top-level variables being declared.
   VariableDeclarationListImpl _variableList;
@@ -10188,6 +10239,11 @@
   /// explicit upper bound.
   TypeAnnotationImpl _bound;
 
+  /// Data that is read during loading this node from summary, but is not
+  /// fully applied yet. For example in many cases we don't need the
+  /// documentation comment, and it is expensive to decode strings.
+  Object summaryData;
+
   /// Initialize a newly created type parameter. Either or both of the [comment]
   /// and [metadata] can be `null` if the parameter does not have the
   /// corresponding attribute. The [extendsKeyword] and [bound] can be `null` if
@@ -10412,6 +10468,12 @@
   /// `null` if the initial value was not specified.
   ExpressionImpl _initializer;
 
+  /// When this node is read as a part of summaries, we usually don't want
+  /// to read the [initializer], but we need to know if there is one in
+  /// the code. So, this flag might be set to `true` even though
+  /// [initializer] is `null`.
+  bool hasInitializer = false;
+
   /// Initialize a newly created variable declaration. The [equals] and
   /// [initializer] can be `null` if there is no initializer.
   VariableDeclarationImpl(
diff --git a/pkg/analyzer/lib/src/dart/element/element.dart b/pkg/analyzer/lib/src/dart/element/element.dart
index 2aebe9f..5b33ad7 100644
--- a/pkg/analyzer/lib/src/dart/element/element.dart
+++ b/pkg/analyzer/lib/src/dart/element/element.dart
@@ -41,9 +41,9 @@
 import 'package:analyzer/src/generated/utilities_collection.dart';
 import 'package:analyzer/src/generated/utilities_dart.dart';
 import 'package:analyzer/src/generated/utilities_general.dart';
-import 'package:analyzer/src/summary/idl.dart';
 import 'package:analyzer/src/summary2/linked_unit_context.dart';
 import 'package:analyzer/src/summary2/reference.dart';
+import 'package:analyzer/src/task/inference_error.dart';
 import 'package:analyzer/src/util/comment.dart';
 import 'package:meta/meta.dart';
 
@@ -464,11 +464,14 @@
 
   /// A flag indicating whether the types associated with the instance members
   /// of this class have been inferred.
-  bool _hasBeenInferred = false;
+  bool hasBeenInferred = false;
 
   /// This callback is set during mixins inference to handle reentrant calls.
   List<InterfaceType> Function(ClassElementImpl) linkedMixinInferenceCallback;
 
+  /// TODO(scheglov) implement as modifier
+  bool _isSimplyBounded = true;
+
   /// Initialize a newly created class element to have the given [name] at the
   /// given [offset] in the file that contains the declaration of this element.
   ClassElementImpl(String name, int offset) : super(name, offset);
@@ -481,6 +484,7 @@
     } else if (linkedNode is ClassTypeAlias) {
       linkedNode.name.staticElement = this;
     }
+    hasBeenInferred = !linkedContext.isLinking;
   }
 
   @override
@@ -533,6 +537,7 @@
     }
 
     if (linkedNode != null) {
+      linkedContext.applyResolution(linkedNode);
       var context = enclosingUnit.linkedContext;
       var containerRef = reference.getChild('@constructor');
       _constructors = context.getConstructors(linkedNode).map((node) {
@@ -594,6 +599,7 @@
 
     if (linkedNode != null) {
       if (linkedNode is ClassOrMixinDeclaration) {
+        linkedContext.applyResolution(linkedNode);
         _createPropertiesAndAccessors();
         assert(_fields != null);
         return _fields;
@@ -605,20 +611,6 @@
     return _fields ?? const <FieldElement>[];
   }
 
-  bool get hasBeenInferred {
-    if (linkedNode != null) {
-      return linkedContext.hasOverrideInferenceDone(linkedNode);
-    }
-    return _hasBeenInferred;
-  }
-
-  set hasBeenInferred(bool hasBeenInferred) {
-    if (linkedNode != null) {
-      return linkedContext.setOverrideInferenceDone(linkedNode);
-    }
-    _hasBeenInferred = hasBeenInferred;
-  }
-
   @override
   bool get hasNonFinalField {
     List<ClassElement> classesToVisit = <ClassElement>[];
@@ -694,6 +686,7 @@
     }
 
     if (linkedNode != null) {
+      linkedContext.applyResolution(linkedNode);
       var context = enclosingUnit.linkedContext;
       var implementsClause = context.getImplementsClause(linkedNode);
       if (implementsClause != null) {
@@ -738,12 +731,18 @@
     setModifier(Modifier.MIXIN_APPLICATION, isMixinApplication);
   }
 
+  /// TODO(scheglov) implement as modifier
   @override
   bool get isSimplyBounded {
     if (linkedNode != null) {
-      return linkedContext.isSimplyBounded(linkedNode);
+      linkedContext.applyResolution(linkedNode);
     }
-    return super.isSimplyBounded;
+    return _isSimplyBounded;
+  }
+
+  /// TODO(scheglov) implement as modifier
+  set isSimplyBounded(bool isSimplyBounded) {
+    _isSimplyBounded = isSimplyBounded;
   }
 
   @override
@@ -769,6 +768,7 @@
     }
 
     if (linkedNode != null) {
+      linkedContext.applyResolution(linkedNode);
       var context = enclosingUnit.linkedContext;
       var containerRef = reference.getChild('@method');
       return _methods = context
@@ -805,6 +805,7 @@
     }
 
     if (linkedNode != null) {
+      linkedContext.applyResolution(linkedNode);
       var context = enclosingUnit.linkedContext;
       var withClause = context.getWithClause(linkedNode);
       if (withClause != null) {
@@ -854,6 +855,7 @@
     }
 
     if (linkedNode != null) {
+      linkedContext.applyResolution(linkedNode);
       var type = linkedContext.getSuperclass(linkedNode)?.type;
       if (_isInterfaceTypeClass(type)) {
         return _supertype = type;
@@ -1055,11 +1057,9 @@
     var fields = context.getFields(linkedNode);
     for (var field in fields) {
       var name = field.name.name;
-      var fieldElement = FieldElementImpl.forLinkedNodeFactory(
-        this,
-        reference.getChild('@field').getChild(name),
-        field,
-      );
+      var fieldElement = field.declaredElement as FieldElementImpl;
+      fieldElement ??= FieldElementImpl.forLinkedNodeFactory(
+          this, reference.getChild('@field').getChild(name), field);
       fieldList.add(fieldElement);
 
       accessorList.add(fieldElement.getter);
@@ -1079,11 +1079,10 @@
           ? reference.getChild('@getter')
           : reference.getChild('@setter');
 
-      var accessorElement = PropertyAccessorElementImpl.forLinkedNode(
-        this,
-        containerRef.getChild(name),
-        method,
-      );
+      var accessorElement =
+          method.declaredElement as PropertyAccessorElementImpl;
+      accessorElement ??= PropertyAccessorElementImpl.forLinkedNode(
+          this, containerRef.getChild(name), method);
       accessorList.add(accessorElement);
 
       var fieldRef = reference.getChild('@field').getChild(name);
@@ -1324,9 +1323,13 @@
       CompilationUnit linkedNode = this.linkedNode;
       var containerRef = reference.getChild('@extension');
       _extensions = <ExtensionElement>[];
+      var nextUnnamedExtensionId = 0;
       for (var node in linkedNode.declarations) {
         if (node is ExtensionDeclaration) {
-          var refName = linkedContext.getExtensionRefName(node);
+          var nameIdentifier = node.name;
+          var refName = nameIdentifier != null
+              ? nameIdentifier.name
+              : 'extension-${nextUnnamedExtensionId++}';
           var reference = containerRef.getChild(refName);
           var element = node.declaredElement;
           element ??= ExtensionElementImpl.forLinkedNode(this, reference, node);
@@ -1352,9 +1355,8 @@
     if (_functions != null) return _functions;
 
     if (linkedNode != null) {
-      CompilationUnit linkedNode = this.linkedNode;
       var containerRef = reference.getChild('@function');
-      return _functions = linkedNode.declarations
+      return _functions = linkedContext.unit_withDeclarations.declarations
           .whereType<FunctionDeclaration>()
           .where((node) => !node.isGetter && !node.isSetter)
           .map((node) {
@@ -1382,10 +1384,9 @@
     if (_typeAliases != null) return _typeAliases;
 
     if (linkedNode != null) {
-      CompilationUnit linkedNode = this.linkedNode;
       var containerRef = reference.getChild('@typeAlias');
       _typeAliases = <FunctionTypeAliasElement>[];
-      for (var node in linkedNode.declarations) {
+      for (var node in linkedContext.unit_withDeclarations.declarations) {
         String name;
         if (node is FunctionTypeAlias) {
           name = node.name.name;
@@ -1464,12 +1465,14 @@
 
   @override
   List<TopLevelVariableElement> get topLevelVariables {
+    if (_variables != null) return _variables;
+
     if (linkedNode != null) {
-      if (_variables != null) return _variables;
       _createPropertiesAndAccessors(this);
       assert(_variables != null);
       return _variables;
     }
+
     return _variables ?? const <TopLevelVariableElement>[];
   }
 
@@ -1499,10 +1502,9 @@
     if (_types != null) return _types;
 
     if (linkedNode != null) {
-      CompilationUnit linkedNode = this.linkedNode;
       var containerRef = reference.getChild('@class');
       _types = <ClassElement>[];
-      for (var node in linkedNode.declarations) {
+      for (var node in linkedContext.unit_withDeclarations.declarations) {
         if (node is ClassDeclaration) {
           var name = node.name.name;
           var reference = containerRef.getChild(name);
@@ -1647,18 +1649,20 @@
       var variableList = <TopLevelVariableElement>[];
       variableMap[unit] = variableList;
 
-      var unitNode = unit.linkedContext.unit_withDeclarations;
+      // TODO(scheglov) Bad, we want to read only functions / variables.
+      var unitNode = context.unit_withDeclarations;
       var unitDeclarations = unitNode.declarations;
 
       var variables = context.topLevelVariables(unitNode);
       for (var variable in variables) {
-        var name = variable.name.name;
-        var reference = unit.reference.getChild('@variable').getChild(name);
-        var variableElement = TopLevelVariableElementImpl.forLinkedNodeFactory(
-          unit,
-          reference,
-          variable,
-        );
+        var variableElement =
+            variable.declaredElement as TopLevelVariableElementImpl;
+        if (variableElement == null) {
+          var name = variable.name.name;
+          var reference = unit.reference.getChild('@variable').getChild(name);
+          variableElement = TopLevelVariableElementImpl.forLinkedNodeFactory(
+              unit, reference, variable);
+        }
         variableList.add(variableElement);
 
         accessorList.add(variableElement.getter);
@@ -1678,14 +1682,13 @@
               ? unit.reference.getChild('@getter')
               : unit.reference.getChild('@setter');
 
-          var accessorElement = PropertyAccessorElementImpl.forLinkedNode(
-            unit,
-            containerRef.getChild(name),
-            node,
-          );
+          var accessorElement =
+              node.declaredElement as PropertyAccessorElementImpl;
+          accessorElement ??= PropertyAccessorElementImpl.forLinkedNode(
+              unit, containerRef.getChild(name), node);
           accessorList.add(accessorElement);
 
-          var fieldRef = unit.reference.getChild('@field').getChild(name);
+          var fieldRef = unit.reference.getChild('@variable').getChild(name);
           TopLevelVariableElementImpl field = fieldRef.element;
           if (field == null) {
             field = TopLevelVariableElementImpl(name, -1);
@@ -1953,6 +1956,7 @@
     if (_constantInitializers != null) return _constantInitializers;
 
     if (linkedNode != null) {
+      linkedContext.applyResolution(linkedNode);
       return _constantInitializers = linkedContext.getConstructorInitializers(
         linkedNode,
       );
@@ -2069,6 +2073,7 @@
     if (_redirectedConstructor != null) return _redirectedConstructor;
 
     if (linkedNode != null) {
+      linkedContext.applyResolution(linkedNode);
       var context = enclosingUnit.linkedContext;
       if (isFactory) {
         var node = context.getConstructorRedirected(linkedNode);
@@ -2203,8 +2208,8 @@
     if (_constantInitializer != null) return _constantInitializer;
 
     if (linkedNode != null) {
-      var context = enclosingUnit.linkedContext;
-      return _constantInitializer = context.readInitializer(linkedNode);
+      linkedContext.applyResolution(linkedNode);
+      return _constantInitializer = linkedContext.getInitializer(linkedNode);
     }
 
     return _constantInitializer;
@@ -2967,11 +2972,14 @@
 
   @override
   List<ElementAnnotation> get metadata {
+    if (_metadata != null) return _metadata;
+
     if (linkedNode != null) {
-      if (_metadata != null) return _metadata;
+      linkedContext.applyResolution(linkedNode);
       var metadata = linkedContext.getMetadata(linkedNode);
       return _metadata = _buildAnnotations2(enclosingUnit, metadata);
     }
+
     return _metadata ?? const <ElementAnnotation>[];
   }
 
@@ -3686,6 +3694,7 @@
     if (_parameters != null) return _parameters;
 
     if (linkedNode != null) {
+      linkedContext.applyResolution(linkedNode);
       var context = enclosingUnit.linkedContext;
       var containerRef = reference.getChild('@parameter');
       var formalParameters = context.getFormalParameters(linkedNode);
@@ -3705,9 +3714,6 @@
       ElementTypeProvider.current.getExecutableReturnType(this);
 
   set returnType(DartType returnType) {
-    if (linkedNode != null) {
-      linkedContext.setReturnType(linkedNode, returnType);
-    }
     _returnType = returnType;
     // We do this because of return type inference. At the moment when we
     // create a local function element we don't know yet its return type,
@@ -3724,8 +3730,8 @@
     if (_returnType != null) return _returnType;
 
     if (linkedNode != null) {
-      var context = enclosingUnit.linkedContext;
-      return _returnType = context.getReturnType(linkedNode);
+      linkedContext.applyResolution(linkedNode);
+      return _returnType;
     }
     return _returnType;
   }
@@ -3799,7 +3805,9 @@
 
   ExportElementImpl.forLinkedNode(
       LibraryElementImpl enclosing, ExportDirective linkedNode)
-      : super.forLinkedNode(enclosing, null, linkedNode);
+      : super.forLinkedNode(enclosing, null, linkedNode) {
+    linkedNode.element = this;
+  }
 
   @override
   List<NamespaceCombinator> get combinators {
@@ -3831,7 +3839,7 @@
     if (_exportedLibrary != null) return _exportedLibrary;
 
     if (linkedNode != null) {
-      return _exportedLibrary = linkedContext.directiveLibrary(linkedNode);
+      linkedContext.applyResolution(linkedNode);
     }
 
     return _exportedLibrary;
@@ -3971,7 +3979,8 @@
     if (_extendedType != null) return _extendedType;
 
     if (linkedNode != null) {
-      return _extendedType = linkedContext.getExtendedType(linkedNode).type;
+      var linkedNode = this.linkedNode as ExtensionDeclaration;
+      return _extendedType = linkedNode.extendedType.type;
     }
 
     return _extendedType;
@@ -4135,11 +4144,9 @@
     var fields = context.getFields(linkedNode);
     for (var field in fields) {
       var name = field.name.name;
-      var fieldElement = FieldElementImpl.forLinkedNodeFactory(
-        this,
-        reference.getChild('@field').getChild(name),
-        field,
-      );
+      var fieldElement = field.declaredElement as FieldElementImpl;
+      fieldElement ??= FieldElementImpl.forLinkedNodeFactory(
+          this, reference.getChild('@field').getChild(name), field);
       fieldList.add(fieldElement);
 
       accessorList.add(fieldElement.getter);
@@ -4159,11 +4166,10 @@
           ? reference.getChild('@getter')
           : reference.getChild('@setter');
 
-      var accessorElement = PropertyAccessorElementImpl.forLinkedNode(
-        this,
-        containerRef.getChild(name),
-        method,
-      );
+      var accessorElement =
+          method.declaredElement as PropertyAccessorElementImpl;
+      accessorElement ??= PropertyAccessorElementImpl.forLinkedNode(
+          this, containerRef.getChild(name), method);
       accessorList.add(accessorElement);
 
       var fieldRef = reference.getChild('@field').getChild(name);
@@ -4198,6 +4204,10 @@
 /// A concrete implementation of a [FieldElement].
 class FieldElementImpl extends PropertyInducingElementImpl
     implements FieldElement {
+  /// True if this field inherits from a covariant parameter. This happens
+  /// when it overrides a field in a supertype that is covariant.
+  bool inheritsCovariant = false;
+
   /// Initialize a newly created synthetic field element to have the given
   /// [name] at the given [offset].
   FieldElementImpl(String name, int offset) : super(name, offset);
@@ -4205,6 +4215,9 @@
   FieldElementImpl.forLinkedNode(
       ElementImpl enclosing, Reference reference, AstNode linkedNode)
       : super.forLinkedNode(enclosing, reference, linkedNode) {
+    if (linkedNode is VariableDeclaration) {
+      linkedNode.name.staticElement = this;
+    }
     if (!linkedNode.isSynthetic) {
       var enclosingRef = enclosing.reference;
 
@@ -4430,6 +4443,14 @@
   /// The element representing the generic function type.
   GenericFunctionTypeElementImpl _function;
 
+  /// TODO(scheglov) implement as modifier
+  @override
+  bool isSimplyBounded = true;
+
+  /// Is `true` if the element has direct or indirect reference to itself
+  /// from anywhere except a class element or type parameter bounds.
+  bool hasSelfReference = false;
+
   /// Initialize a newly created type alias element to have the given [name].
   FunctionTypeAliasElementImpl(String name, int offset) : super(name, offset);
 
@@ -4486,28 +4507,32 @@
   GenericFunctionTypeElementImpl get function {
     if (_function != null) return _function;
 
+    var linkedNode = this.linkedNode;
     if (linkedNode != null) {
       if (linkedNode is GenericTypeAlias) {
-        var context = enclosingUnit.linkedContext;
-        var function = context.getGeneticTypeAliasFunction(linkedNode);
+        var function = linkedNode.functionType as GenericFunctionTypeImpl;
         if (function != null) {
-          var reference = context.getGenericFunctionTypeReference(function);
-          _function = reference.element;
-          encloseElement(_function);
-          return _function;
+          _function = function.declaredElement;
+          _function ??= GenericFunctionTypeElementImpl.forLinkedNode(
+            this,
+            reference.getChild('@function'),
+            function,
+          );
         } else {
-          return _function = GenericFunctionTypeElementImpl.forOffset(-1)
+          _function = GenericFunctionTypeElementImpl.forOffset(-1)
             ..typeParameters = const <TypeParameterElement>[]
             ..parameters = const <ParameterElement>[]
             ..returnType = DynamicTypeImpl.instance;
         }
       } else {
-        return _function = GenericFunctionTypeElementImpl.forLinkedNode(
+        _function = GenericFunctionTypeElementImpl.forLinkedNode(
           this,
           reference.getChild('@function'),
           linkedNode,
         );
       }
+      linkedContext.applyResolution(linkedNode);
+      return _function;
     }
 
     return _function;
@@ -4522,23 +4547,6 @@
     _function = function;
   }
 
-  /// Return `true` if the element has direct or indirect reference to itself
-  /// from anywhere except a class element or type parameter bounds.
-  bool get hasSelfReference {
-    if (linkedNode != null) {
-      return linkedContext.getHasTypedefSelfReference(linkedNode);
-    }
-    return false;
-  }
-
-  @override
-  bool get isSimplyBounded {
-    if (linkedNode != null) {
-      return linkedContext.isSimplyBounded(linkedNode);
-    }
-    return super.isSimplyBounded;
-  }
-
   @override
   ElementKind get kind => ElementKind.FUNCTION_TYPE_ALIAS;
 
@@ -4658,7 +4666,11 @@
 
   GenericFunctionTypeElementImpl.forLinkedNode(
       ElementImpl enclosingElement, Reference reference, AstNode linkedNode)
-      : super.forLinkedNode(enclosingElement, reference, linkedNode);
+      : super.forLinkedNode(enclosingElement, reference, linkedNode) {
+    if (linkedNode is GenericFunctionTypeImpl) {
+      linkedNode.declaredElement = this;
+    }
+  }
 
   /// Initialize a newly created function element to have no name and the given
   /// [nameOffset]. This is used for function expressions, that have no name.
@@ -4695,7 +4707,7 @@
         return _parameters = ParameterElementImpl.forLinkedNodeList(
           this,
           context,
-          reference.getChild('@parameter'),
+          null,
           context.getFormalParameters(linkedNode),
         );
       }
@@ -4867,7 +4879,9 @@
 
   ImportElementImpl.forLinkedNode(
       LibraryElementImpl enclosing, ImportDirective linkedNode)
-      : super.forLinkedNode(enclosing, null, linkedNode);
+      : super.forLinkedNode(enclosing, null, linkedNode) {
+    linkedNode.element = this;
+  }
 
   @override
   List<NamespaceCombinator> get combinators {
@@ -4902,7 +4916,7 @@
     if (_importedLibrary != null) return _importedLibrary;
 
     if (linkedNode != null) {
-      return _importedLibrary = linkedContext.directiveLibrary(linkedNode);
+      linkedContext.applyResolution(linkedNode);
     }
 
     return _importedLibrary;
@@ -5179,7 +5193,7 @@
   @override
   String get documentationComment {
     if (linkedNode != null) {
-      var comment = linkedContext.getLibraryDocumentationComment(linkedNode);
+      var comment = linkedContext.getLibraryDocumentationComment();
       return getCommentNodeRawText(comment);
     }
     return super.documentationComment;
@@ -5222,7 +5236,7 @@
     if (_exportNamespace != null) return _exportNamespace;
 
     if (linkedNode != null) {
-      var elements = linkedContext.bundleContext.elementFactory;
+      var elements = linkedContext.elementFactory;
       return _exportNamespace = elements.buildExportNamespace(source.uri);
     }
 
@@ -5241,7 +5255,7 @@
       var unit = linkedContext.unit_withDirectives;
       return _exports = unit.directives
           .whereType<ExportDirective>()
-          .map((node) => ExportElementImpl.forLinkedNode(this, node))
+          .map((node) => node.element)
           .toList();
     }
 
@@ -5263,9 +5277,12 @@
       var unit = linkedContext.unit_withDirectives;
       for (var import in unit.directives) {
         if (import is ImportDirective) {
-          var uriStr = linkedContext.getSelectedUri(import);
-          if (DartUriResolver.isDartExtUri(uriStr)) {
-            return true;
+          var uriLiteral = import.uri;
+          if (uriLiteral is SimpleStringLiteral) {
+            var uriStr = uriLiteral.value;
+            if (DartUriResolver.isDartExtUri(uriStr)) {
+              return true;
+            }
           }
         }
       }
@@ -5316,13 +5333,13 @@
       var unit = linkedContext.unit_withDirectives;
       _imports = unit.directives
           .whereType<ImportDirective>()
-          .map((node) => ImportElementImpl.forLinkedNode(this, node))
+          .map((node) => node.element)
           .toList();
       var hasCore = _imports.any((import) {
         return import.importedLibrary?.isDartCore ?? false;
       });
       if (!hasCore) {
-        var elements = linkedContext.bundleContext.elementFactory;
+        var elements = linkedContext.elementFactory;
         _imports.add(
           ImportElementImpl(-1)
             ..importedLibrary = elements.libraryOfUri('dart:core')
@@ -5444,7 +5461,7 @@
     if (_metadata != null) return _metadata;
 
     if (linkedNode != null) {
-      var metadata = linkedContext.getLibraryMetadata(linkedNode);
+      var metadata = linkedContext.getLibraryMetadata();
       return _metadata = _buildAnnotations2(definingCompilationUnit, metadata);
     }
 
@@ -5682,6 +5699,15 @@
 
 /// A concrete implementation of a [MethodElement].
 class MethodElementImpl extends ExecutableElementImpl implements MethodElement {
+  /// Is `true` if this method is `operator==`, and there is no explicit
+  /// type specified for its formal parameter, in this method or in any
+  /// overridden methods other than the one declared in `Object`.
+  bool isOperatorEqualWithParameterTypeFromObject = false;
+
+  /// The error reported during type inference for this variable, or `null` if
+  /// this variable is not a subject of type inference, or there was no error.
+  TopLevelInferenceError typeInferenceError;
+
   /// Initialize a newly created method element to have the given [name] at the
   /// given [offset].
   MethodElementImpl(String name, int offset) : super(name, offset);
@@ -5722,23 +5748,6 @@
         first == 0x24);
   }
 
-  /// Return `true` if this method is `operator==`, and there is no explicit
-  /// type specified for its formal parameter, in this method or in any
-  /// overridden methods other than the one declared in `Object`.
-  bool get isOperatorEqualWithParameterTypeFromObject {
-    if (linkedNode != null) {
-      return linkedContext.hasOperatorEqualParameterTypeFromObject(linkedNode);
-    }
-    return false;
-  }
-
-  /// See [isOperatorEqualWithParameterTypeFromObject].
-  set isOperatorEqualWithParameterTypeFromObject(bool value) {
-    if (linkedNode != null) {
-      linkedContext.setOperatorEqualParameterTypeFromObject(linkedNode, value);
-    }
-  }
-
   @override
   bool get isStatic {
     if (linkedNode != null) {
@@ -5764,18 +5773,6 @@
     return super.name;
   }
 
-  /// Return the error reported during type inference for this method, or
-  /// `null` if this method is not a subject of type inference, or there was
-  /// no error.
-  TopLevelInferenceError get typeInferenceError {
-    if (linkedNode != null) {
-      return linkedContext.getTypeInferenceError(linkedNode);
-    }
-
-    // We don't support type inference errors without linking.
-    return null;
-  }
-
   @override
   T accept<T>(ElementVisitor<T> visitor) => visitor.visitMethodElement(this);
 }
@@ -5790,10 +5787,8 @@
   /// the mixin.
   List<InterfaceType> _superclassConstraints;
 
-  /// Names of methods, getters, setters, and operators that this mixin
-  /// declaration super-invokes.  For setters this includes the trailing "=".
-  /// The list will be empty if this class is not a mixin declaration.
-  List<String> _superInvokedNames;
+  @override
+  List<String> superInvokedNames;
 
   /// Initialize a newly created class element to have the given [name] at the
   /// given [offset] in the file that contains the declaration of this element.
@@ -5818,9 +5813,11 @@
   List<InterfaceType> get superclassConstraints {
     if (_superclassConstraints != null) return _superclassConstraints;
 
-    if (linkedNode != null) {
+    var linkedNode = this.linkedNode;
+    if (linkedNode is MixinDeclaration) {
+      linkedContext.applyResolution(linkedNode);
       List<InterfaceType> constraints;
-      var onClause = enclosingUnit.linkedContext.getOnClause(linkedNode);
+      var onClause = linkedNode.onClause;
       if (onClause != null) {
         constraints = onClause.superclassConstraints
             .map((node) => node.type)
@@ -5842,22 +5839,6 @@
   }
 
   @override
-  List<String> get superInvokedNames {
-    if (_superInvokedNames != null) return _superInvokedNames;
-
-    if (linkedNode != null) {
-      return _superInvokedNames =
-          linkedContext.getMixinSuperInvokedNames(linkedNode);
-    }
-
-    return _superInvokedNames ?? const <String>[];
-  }
-
-  set superInvokedNames(List<String> superInvokedNames) {
-    _superInvokedNames = superInvokedNames;
-  }
-
-  @override
   InterfaceType get supertype => null;
 
   @override
@@ -6288,9 +6269,6 @@
 
   @override
   set type(DartType type) {
-    if (linkedNode != null) {
-      return linkedContext.setVariableType(linkedNode, type);
-    }
     _type = type;
   }
 }
@@ -6315,7 +6293,10 @@
   /// The Dart code of the default value.
   String _defaultValueCode;
 
-  bool _inheritsCovariant = false;
+  /// True if this parameter inherits from a covariant parameter. This happens
+  /// when it overrides a method in a supertype that has a corresponding
+  /// covariant parameter.
+  bool inheritsCovariant = false;
 
   /// Initialize a newly created parameter element to have the given [name] and
   /// [nameOffset].
@@ -6324,6 +6305,7 @@
   ParameterElementImpl.forLinkedNode(
       ElementImpl enclosing, Reference reference, FormalParameter linkedNode)
       : super.forLinkedNode(enclosing, reference, linkedNode) {
+    assert(linkedNode.isNamed || reference == null);
     FormalParameterImpl.setDeclaredElement(linkedNode, this);
   }
 
@@ -6354,28 +6336,13 @@
   }
 
   @override
-  int get codeLength {
-    if (linkedNode != null) {
-      return linkedContext.getCodeLength(linkedNode);
-    }
-    return super.codeLength;
-  }
-
-  @override
-  int get codeOffset {
-    if (linkedNode != null) {
-      return linkedContext.getCodeOffset(linkedNode);
-    }
-    return super.codeOffset;
-  }
-
-  @override
   ParameterElement get declaration => this;
 
   @override
   String get defaultValueCode {
-    if (linkedNode != null) {
-      return linkedContext.getDefaultValueCode(linkedNode);
+    var linkedNode = this.linkedNode;
+    if (linkedNode is DefaultFormalParameter) {
+      return linkedNode.defaultValue?.toSource();
     }
 
     return _defaultValueCode;
@@ -6399,25 +6366,6 @@
     return super.hasImplicitType;
   }
 
-  /// True if this parameter inherits from a covariant parameter. This happens
-  /// when it overrides a method in a supertype that has a corresponding
-  /// covariant parameter.
-  bool get inheritsCovariant {
-    if (linkedNode != null) {
-      return linkedContext.getInheritsCovariant(linkedNode);
-    }
-    return _inheritsCovariant;
-  }
-
-  /// Record whether or not this parameter inherits from a covariant parameter.
-  set inheritsCovariant(bool value) {
-    if (linkedNode != null) {
-      linkedContext.setInheritsCovariant(linkedNode, value);
-      return;
-    }
-    _inheritsCovariant = value;
-  }
-
   @override
   bool get isCovariant {
     if (isExplicitlyCovariant || inheritsCovariant) {
@@ -6461,7 +6409,7 @@
   @override
   String get name {
     if (linkedNode != null) {
-      return reference.name;
+      return linkedContext.getFormalParameterName(linkedNode);
     }
     return super.name;
   }
@@ -6498,11 +6446,10 @@
       var context = enclosingUnit.linkedContext;
       var formalParameters = context.getFormalParameters(linkedNode);
       if (formalParameters != null) {
-        var containerRef = reference.getChild('@parameter');
         return _parameters = ParameterElementImpl.forLinkedNodeList(
           this,
           context,
-          containerRef,
+          null,
           formalParameters,
         );
       } else {
@@ -6523,19 +6470,6 @@
   }
 
   @override
-  DartType get type => ElementTypeProvider.current.getVariableType(this);
-
-  @override
-  DartType get typeInternal {
-    if (linkedNode != null) {
-      if (_type != null) return _type;
-      var context = enclosingUnit.linkedContext;
-      return _type = context.getType(linkedNode);
-    }
-    return super.typeInternal;
-  }
-
-  @override
   List<TypeParameterElement> get typeParameters {
     if (_typeParameters != null) return _typeParameters;
 
@@ -6544,13 +6478,10 @@
       if (typeParameters == null) {
         return _typeParameters = const [];
       }
-      var containerRef = reference.getChild('@typeParameter');
       return _typeParameters =
           typeParameters.typeParameters.map<TypeParameterElement>((node) {
-        var reference = containerRef.getChild(node.name.name);
         var element = node.declaredElement;
-        element ??=
-            TypeParameterElementImpl.forLinkedNode(this, reference, node);
+        element ??= TypeParameterElementImpl.forLinkedNode(this, node);
         return element;
       }).toList();
     }
@@ -6581,6 +6512,9 @@
     safelyVisitChildren(parameters, visitor);
   }
 
+  /// TODO(scheglov) Do we need this method at all?
+  /// We should create all parameter elements during applying resolution.
+  /// Or when we build elements before linking.
   static List<ParameterElement> forLinkedNodeList(
       ElementImpl enclosing,
       LinkedUnitContext context,
@@ -6598,9 +6532,12 @@
 
       if (node is DefaultFormalParameter) {
         NormalFormalParameter parameterNode = node.parameter;
-        var name = parameterNode.identifier?.name ?? '';
-        var reference = containerRef.getChild(name);
-        reference.node = node;
+        Reference reference;
+        if (node.isNamed) {
+          var name = parameterNode.identifier?.name ?? '';
+          reference = containerRef?.getChild(name);
+          reference?.node = node;
+        }
         if (parameterNode is FieldFormalParameter) {
           return DefaultFieldFormalParameterElementImpl.forLinkedNode(
             enclosing,
@@ -6615,24 +6552,7 @@
           );
         }
       } else {
-        if (node.identifier == null) {
-          return ParameterElementImpl.forLinkedNodeFactory(
-            enclosing,
-            containerRef.getChild(''),
-            node,
-          );
-        } else {
-          var name = node.identifier.name;
-          var reference = containerRef.getChild(name);
-          if (reference.hasElementFor(node)) {
-            return reference.element as ParameterElement;
-          }
-          return ParameterElementImpl.forLinkedNodeFactory(
-            enclosing,
-            reference,
-            node,
-          );
-        }
+        return ParameterElementImpl.forLinkedNodeFactory(enclosing, null, node);
       }
     }).toList();
   }
@@ -6655,10 +6575,7 @@
   bool get inheritsCovariant {
     PropertyInducingElement variable = setter.variable;
     if (variable is FieldElementImpl) {
-      if (variable.linkedNode != null) {
-        var context = variable.linkedContext;
-        return context.getInheritsCovariant(variable.linkedNode);
-      }
+      return variable.inheritsCovariant;
     }
     return false;
   }
@@ -6667,10 +6584,7 @@
   set inheritsCovariant(bool value) {
     PropertyInducingElement variable = setter.variable;
     if (variable is FieldElementImpl) {
-      if (variable.linkedNode != null) {
-        var context = variable.linkedContext;
-        return context.setInheritsCovariant(variable.linkedNode, value);
-      }
+      variable.inheritsCovariant = value;
     }
   }
 
@@ -6946,6 +6860,7 @@
       : super.forVariable(property, reference: reference) {
     property.getter = this;
     enclosingElement = property.enclosingElement;
+    reference?.element = this;
   }
 
   @override
@@ -7083,6 +6998,10 @@
   /// this property. After linking this field is always `null`.
   PropertyInducingElementTypeInference typeInference;
 
+  /// The error reported during type inference for this variable, or `null` if
+  /// this variable is not a subject of type inference, or there was no error.
+  TopLevelInferenceError typeInferenceError;
+
   /// Initialize a newly created synthetic element to have the given [name] and
   /// [offset].
   PropertyInducingElementImpl(String name, int offset) : super(name, offset);
@@ -7091,6 +7010,8 @@
       ElementImpl enclosing, Reference reference, AstNode linkedNode)
       : super.forLinkedNode(enclosing, reference, linkedNode);
 
+  bool get hasTypeInferred => _type != null;
+
   @override
   bool get isConstantEvaluated => true;
 
@@ -7105,23 +7026,12 @@
   @override
   DartType get type => ElementTypeProvider.current.getFieldType(this);
 
-  /// Return the error reported during type inference for this variable, or
-  /// `null` if this variable is not a subject of type inference, or there was
-  /// no error.
-  TopLevelInferenceError get typeInferenceError {
-    if (linkedNode != null) {
-      return linkedContext.getTypeInferenceError(linkedNode);
-    }
-
-    // We don't support type inference errors without linking.
-    return null;
-  }
-
   @override
   DartType get typeInternal {
+    if (_type != null) return _type;
+
     if (linkedNode != null) {
-      if (_type != null) return _type;
-      _type = linkedContext.getType(linkedNode);
+      linkedContext.applyResolution(linkedNode);
 
       // While performing inference during linking, the first step is to collect
       // dependencies. During this step we resolve the expression, but we might
@@ -7195,7 +7105,7 @@
   @override
   int get end {
     if (linkedNode != null) {
-      return linkedContext.getCombinatorEnd(linkedNode);
+      return linkedNode.end;
     }
     return _end;
   }
@@ -7256,6 +7166,9 @@
   TopLevelVariableElementImpl.forLinkedNode(
       ElementImpl enclosing, Reference reference, AstNode linkedNode)
       : super.forLinkedNode(enclosing, reference, linkedNode) {
+    if (linkedNode is VariableDeclaration) {
+      linkedNode.name.staticElement = this;
+    }
     if (!linkedNode.isSynthetic) {
       var enclosingRef = enclosing.reference;
 
@@ -7317,7 +7230,7 @@
   /// The default value of the type parameter. It is used to provide the
   /// corresponding missing type argument in type annotations and as the
   /// fall-back type value in type inference.
-  DartType _defaultType;
+  DartType defaultType;
 
   /// The type representing the bound associated with this parameter, or `null`
   /// if this parameter does not have an explicit bound.
@@ -7332,8 +7245,8 @@
   TypeParameterElementImpl(String name, int offset) : super(name, offset);
 
   TypeParameterElementImpl.forLinkedNode(
-      ElementImpl enclosing, Reference reference, TypeParameter linkedNode)
-      : super.forLinkedNode(enclosing, reference, linkedNode) {
+      ElementImpl enclosing, TypeParameter linkedNode)
+      : super.forLinkedNode(enclosing, null, linkedNode) {
     linkedNode.name.staticElement = this;
   }
 
@@ -7353,9 +7266,9 @@
   DartType get boundInternal {
     if (_bound != null) return _bound;
 
-    if (linkedNode != null) {
-      var context = enclosingUnit.linkedContext;
-      return _bound = context.getTypeParameterBound(linkedNode)?.type;
+    var linkedNode = this.linkedNode;
+    if (linkedNode is TypeParameter) {
+      return _bound = linkedNode.bound?.type;
     }
 
     return _bound;
@@ -7380,29 +7293,10 @@
   @override
   TypeParameterElement get declaration => this;
 
-  /// The default value of the type parameter. It is used to provide the
-  /// corresponding missing type argument in type annotations and as the
-  /// fall-back type value in type inference.
-  DartType get defaultType {
-    if (_defaultType != null) return _defaultType;
-
-    if (linkedNode != null) {
-      return _defaultType = linkedContext.getDefaultType(linkedNode);
-    }
-    return null;
-  }
-
-  set defaultType(DartType defaultType) {
-    _defaultType = defaultType;
-  }
-
   @override
   String get displayName => name;
 
   bool get isLegacyCovariant {
-    if (linkedNode != null) {
-      return linkedContext.getTypeParameterVariance(linkedNode) == null;
-    }
     return _variance == null;
   }
 
@@ -7428,12 +7322,6 @@
   }
 
   Variance get variance {
-    if (_variance != null) return _variance;
-
-    if (linkedNode != null) {
-      _variance = linkedContext.getTypeParameterVariance(linkedNode);
-    }
-
     return _variance ?? Variance.covariant;
   }
 
@@ -7489,18 +7377,16 @@
     if (_typeParameterElements != null) return _typeParameterElements;
 
     if (linkedNode != null) {
+      linkedContext.applyResolution(linkedNode);
       var typeParameters = linkedContext.getTypeParameters2(linkedNode);
       if (typeParameters == null) {
         return _typeParameterElements = const [];
       }
-      var containerRef = reference.getChild('@typeParameter');
       return _typeParameterElements =
           typeParameters.typeParameters.map<TypeParameterElement>((node) {
-        var reference = containerRef.getChild(node.name.name);
-        if (reference.hasElementFor(node)) {
-          return reference.element as TypeParameterElement /*!*/;
-        }
-        return TypeParameterElementImpl.forLinkedNode(this, reference, node);
+        var element = node.declaredElement;
+        element ??= TypeParameterElementImpl.forLinkedNode(this, node);
+        return element;
       }).toList();
     }
 
@@ -7655,9 +7541,6 @@
   DartType get type => ElementTypeProvider.current.getVariableType(this);
 
   set type(DartType type) {
-    if (linkedNode != null) {
-      return linkedContext.setVariableType(linkedNode, type);
-    }
     _type = type;
   }
 
diff --git a/pkg/analyzer/lib/src/dart/element/replacement_visitor.dart b/pkg/analyzer/lib/src/dart/element/replacement_visitor.dart
index c90174a..87503e9 100644
--- a/pkg/analyzer/lib/src/dart/element/replacement_visitor.dart
+++ b/pkg/analyzer/lib/src/dart/element/replacement_visitor.dart
@@ -162,7 +162,7 @@
       var typeParameter = node.typeFormals[i];
       var bound = typeParameter.bound;
       if (bound != null) {
-        var newBound = bound.accept(this);
+        var newBound = visitTypeParameterBound(bound);
         if (newBound != null) {
           newTypeParameters ??= node.typeFormals.toList(growable: false);
           newTypeParameters[i] = TypeParameterElementImpl.synthetic(
@@ -258,7 +258,7 @@
       var typeParameter = node.typeFormals[i];
       var bound = typeParameter.bound;
       if (bound != null) {
-        var newBound = bound.accept(this);
+        var newBound = visitTypeParameterBound(bound);
         if (newBound != null) {
           newTypeParameters ??= node.typeFormals.toList(growable: false);
           newTypeParameters[i] = TypeParameterElementImpl.synthetic(
@@ -394,6 +394,10 @@
     return argument.accept(this);
   }
 
+  DartType visitTypeParameterBound(DartType type) {
+    return type.accept(this);
+  }
+
   @override
   DartType visitTypeParameterType(TypeParameterType type) {
     var newNullability = visitNullability(type);
diff --git a/pkg/analyzer/lib/src/dart/element/type_system.dart b/pkg/analyzer/lib/src/dart/element/type_system.dart
index c38172a..d81326c 100644
--- a/pkg/analyzer/lib/src/dart/element/type_system.dart
+++ b/pkg/analyzer/lib/src/dart/element/type_system.dart
@@ -20,6 +20,7 @@
 import 'package:analyzer/src/dart/element/normalize.dart';
 import 'package:analyzer/src/dart/element/nullability_eliminator.dart';
 import 'package:analyzer/src/dart/element/replace_top_bottom_visitor.dart';
+import 'package:analyzer/src/dart/element/replacement_visitor.dart';
 import 'package:analyzer/src/dart/element/runtime_type_equality.dart';
 import 'package:analyzer/src/dart/element/subtype.dart';
 import 'package:analyzer/src/dart/element/top_merge.dart';
@@ -597,6 +598,8 @@
           if (type is FunctionType) {
             appendParameters(type.returnType);
             type.parameters.map((p) => p.type).forEach(appendParameters);
+            // TODO(scheglov) https://github.com/dart-lang/sdk/issues/44218
+            type.typeArguments.forEach(appendParameters);
           } else if (type is InterfaceType) {
             type.typeArguments.forEach(appendParameters);
           }
@@ -1230,6 +1233,8 @@
       typeParameters,
       considerExtendsClause: false,
     );
+    inferredTypes =
+        inferredTypes.map(_removeBoundsOfGenericFunctionTypes).toList();
     var substitution = Substitution.fromPairs(typeParameters, inferredTypes);
 
     for (int i = 0; i < srcTypes.length; i++) {
@@ -1785,6 +1790,15 @@
     return currentType;
   }
 
+  DartType _removeBoundsOfGenericFunctionTypes(DartType type) {
+    return _RemoveBoundsOfGenericFunctionTypeVisitor.run(
+      bottomType: isNonNullableByDefault
+          ? NeverTypeImpl.instance
+          : typeProvider.nullType,
+      type: type,
+    );
+  }
+
   /// Starting from the given [type], search its class hierarchy for types of
   /// the form Future<R>, and return a list of the resulting R's.
   List<DartType> _searchTypeHierarchyForFutureTypeParameters(DartType type) {
@@ -1810,6 +1824,27 @@
   }
 }
 
+/// TODO(scheglov) Ask the language team how to deal with it.
+class _RemoveBoundsOfGenericFunctionTypeVisitor extends ReplacementVisitor {
+  final DartType _bottomType;
+
+  _RemoveBoundsOfGenericFunctionTypeVisitor._(this._bottomType);
+
+  @override
+  DartType visitTypeParameterBound(DartType type) {
+    return _bottomType;
+  }
+
+  static DartType run({
+    @required DartType bottomType,
+    @required DartType type,
+  }) {
+    var visitor = _RemoveBoundsOfGenericFunctionTypeVisitor._(bottomType);
+    var result = type.accept(visitor);
+    return result ?? type;
+  }
+}
+
 class _TypeVariableEliminator extends Substitution {
   final DartType _topType;
   final DartType _bottomType;
diff --git a/pkg/analyzer/lib/src/dart/error/ffi_code.dart b/pkg/analyzer/lib/src/dart/error/ffi_code.dart
index f2711d9..eda16d1 100644
--- a/pkg/analyzer/lib/src/dart/error/ffi_code.dart
+++ b/pkg/analyzer/lib/src/dart/error/ffi_code.dart
@@ -170,10 +170,11 @@
    * 1: the name of the class being extended, implemented, or mixed in
    */
   static const FfiCode SUBTYPE_OF_FFI_CLASS_IN_EXTENDS = FfiCode(
-      name: 'SUBTYPE_OF_FFI_CLASS',
-      uniqueName: 'SUBTYPE_OF_FFI_CLASS_IN_EXTENDS',
-      message: "The class '{0}' can't extend '{1}'.",
-      correction: "Try extending 'Struct'.");
+    name: 'SUBTYPE_OF_FFI_CLASS',
+    message: "The class '{0}' can't extend '{1}'.",
+    correction: "Try extending 'Struct'.",
+    uniqueName: 'SUBTYPE_OF_FFI_CLASS_IN_EXTENDS',
+  );
 
   /**
    * Parameters:
@@ -181,10 +182,11 @@
    * 1: the name of the class being extended, implemented, or mixed in
    */
   static const FfiCode SUBTYPE_OF_FFI_CLASS_IN_IMPLEMENTS = FfiCode(
-      name: 'SUBTYPE_OF_FFI_CLASS',
-      uniqueName: 'SUBTYPE_OF_FFI_CLASS_IN_IMPLEMENTS',
-      message: "The class '{0}' can't implement '{1}'.",
-      correction: "Try extending 'Struct'.");
+    name: 'SUBTYPE_OF_FFI_CLASS',
+    message: "The class '{0}' can't implement '{1}'.",
+    correction: "Try extending 'Struct'.",
+    uniqueName: 'SUBTYPE_OF_FFI_CLASS_IN_IMPLEMENTS',
+  );
 
   /**
    * Parameters:
@@ -192,10 +194,11 @@
    * 1: the name of the class being extended, implemented, or mixed in
    */
   static const FfiCode SUBTYPE_OF_FFI_CLASS_IN_WITH = FfiCode(
-      name: 'SUBTYPE_OF_FFI_CLASS',
-      uniqueName: 'SUBTYPE_OF_FFI_CLASS_IN_WITH',
-      message: "The class '{0}' can't mix in '{1}'.",
-      correction: "Try extending 'Struct'.");
+    name: 'SUBTYPE_OF_FFI_CLASS',
+    message: "The class '{0}' can't mix in '{1}'.",
+    correction: "Try extending 'Struct'.",
+    uniqueName: 'SUBTYPE_OF_FFI_CLASS_IN_WITH',
+  );
 
   /**
    * Parameters:
@@ -203,12 +206,12 @@
    * 1: the name of the class being extended, implemented, or mixed in
    */
   static const FfiCode SUBTYPE_OF_STRUCT_CLASS_IN_EXTENDS = FfiCode(
-      name: 'SUBTYPE_OF_STRUCT_CLASS',
-      uniqueName: 'SUBTYPE_OF_STRUCT_CLASS_IN_EXTENDS',
-      message:
-          "The class '{0}' can't extend '{1}' because '{1}' is a subtype of "
-          "'Struct'.",
-      correction: "Try extending 'Struct' directly.");
+    name: 'SUBTYPE_OF_STRUCT_CLASS',
+    message: "The class '{0}' can't extend '{1}' because '{1}' is a subtype of "
+        "'Struct'.",
+    correction: "Try extending 'Struct' directly.",
+    uniqueName: 'SUBTYPE_OF_STRUCT_CLASS_IN_EXTENDS',
+  );
 
   /**
    * Parameters:
@@ -216,12 +219,13 @@
    * 1: the name of the class being extended, implemented, or mixed in
    */
   static const FfiCode SUBTYPE_OF_STRUCT_CLASS_IN_IMPLEMENTS = FfiCode(
-      name: 'SUBTYPE_OF_STRUCT_CLASS',
-      uniqueName: 'SUBTYPE_OF_STRUCT_CLASS_IN_IMPLEMENTS',
-      message:
-          "The class '{0}' can't implement '{1}' because '{1}' is a subtype of "
-          "'Struct'.",
-      correction: "Try extending 'Struct' directly.");
+    name: 'SUBTYPE_OF_STRUCT_CLASS',
+    message:
+        "The class '{0}' can't implement '{1}' because '{1}' is a subtype of "
+        "'Struct'.",
+    correction: "Try extending 'Struct' directly.",
+    uniqueName: 'SUBTYPE_OF_STRUCT_CLASS_IN_IMPLEMENTS',
+  );
 
   /**
    * Parameters:
@@ -229,15 +233,12 @@
    * 1: the name of the class being extended, implemented, or mixed in
    */
   static const FfiCode SUBTYPE_OF_STRUCT_CLASS_IN_WITH = FfiCode(
-      name: 'SUBTYPE_OF_STRUCT_CLASS',
-      uniqueName: 'SUBTYPE_OF_STRUCT_CLASS_IN_WITH',
-      message:
-          "The class '{0}' can't mix in '{1}' because '{1}' is a subtype of "
-          "'Struct'.",
-      correction: "Try extending 'Struct' directly.");
-
-  @override
-  final String uniqueName;
+    name: 'SUBTYPE_OF_STRUCT_CLASS',
+    message: "The class '{0}' can't mix in '{1}' because '{1}' is a subtype of "
+        "'Struct'.",
+    correction: "Try extending 'Struct' directly.",
+    uniqueName: 'SUBTYPE_OF_STRUCT_CLASS_IN_WITH',
+  );
 
   /// Initialize a newly created error code to have the given [name]. If
   /// [uniqueName] is provided, then it will be used to construct the unique
@@ -249,16 +250,19 @@
   /// created from the given [correction] template.
   ///
   /// If [hasPublishedDocs] is `true` then a URL for the docs will be generated.
-  const FfiCode(
-      {@required String message,
-      @required String name,
-      String correction,
-      bool hasPublishedDocs,
-      String uniqueName})
-      : uniqueName =
-            uniqueName == null ? 'FfiCode.$name' : 'FfiCode.$uniqueName',
-        super.temporary(name, message,
-            correction: correction, hasPublishedDocs: hasPublishedDocs);
+  const FfiCode({
+    String correction,
+    bool hasPublishedDocs = false,
+    @required String message,
+    @required String name,
+    String uniqueName,
+  }) : super(
+          correction: correction,
+          hasPublishedDocs: hasPublishedDocs,
+          message: message,
+          name: name,
+          uniqueName: uniqueName ?? 'FfiCode.$name',
+        );
 
   @override
   ErrorSeverity get errorSeverity => type.severity;
diff --git a/pkg/analyzer/lib/src/dart/error/hint_codes.dart b/pkg/analyzer/lib/src/dart/error/hint_codes.dart
index c72f379..402b9c7 100644
--- a/pkg/analyzer/lib/src/dart/error/hint_codes.dart
+++ b/pkg/analyzer/lib/src/dart/error/hint_codes.dart
@@ -293,27 +293,28 @@
    * 1: message details
    */
   static const HintCode DEPRECATED_MEMBER_USE_FROM_SAME_PACKAGE_WITH_MESSAGE =
-      HintCodeWithUniqueName(
-          'DEPRECATED_MEMBER_USE_FROM_SAME_PACKAGE',
-          'HintCode.DEPRECATED_MEMBER_USE_FROM_SAME_PACKAGE_WITH_MESSAGE',
-          "'{0}' is deprecated and shouldn't be used. {1}.",
-          correction: "Try replacing the use of the deprecated member with the "
-              "replacement.",
-          hasPublishedDocs: true);
+      HintCode(
+    'DEPRECATED_MEMBER_USE_FROM_SAME_PACKAGE',
+    "'{0}' is deprecated and shouldn't be used. {1}.",
+    correction: "Try replacing the use of the deprecated member with the "
+        "replacement.",
+    hasPublishedDocs: true,
+    uniqueName: 'HintCode.DEPRECATED_MEMBER_USE_FROM_SAME_PACKAGE_WITH_MESSAGE',
+  );
 
   /**
    * Parameters:
    * 0: the name of the member
    * 1: message details
    */
-  static const HintCode DEPRECATED_MEMBER_USE_WITH_MESSAGE =
-      HintCodeWithUniqueName(
-          'DEPRECATED_MEMBER_USE',
-          'HintCode.DEPRECATED_MEMBER_USE_WITH_MESSAGE',
-          "'{0}' is deprecated and shouldn't be used. {1}.",
-          correction: "Try replacing the use of the deprecated member with the "
-              "replacement.",
-          hasPublishedDocs: true);
+  static const HintCode DEPRECATED_MEMBER_USE_WITH_MESSAGE = HintCode(
+    'DEPRECATED_MEMBER_USE',
+    "'{0}' is deprecated and shouldn't be used. {1}.",
+    correction: "Try replacing the use of the deprecated member with the "
+        "replacement.",
+    hasPublishedDocs: true,
+    uniqueName: 'HintCode.DEPRECATED_MEMBER_USE_WITH_MESSAGE',
+  );
 
   /**
    * `Function` should not be mixed in anymore.
@@ -721,13 +722,13 @@
   /// valid language version override comment, it is reported.
   ///
   /// [1] https://github.com/dart-lang/language/blob/master/accepted/future-releases/language-versioning/feature-specification.md#individual-library-language-version-override
-  static const HintCode INVALID_LANGUAGE_VERSION_OVERRIDE_AT_SIGN =
-      HintCodeWithUniqueName(
-          'INVALID_LANGUAGE_VERSION_OVERRIDE',
-          'HintCode.INVALID_LANGUAGE_VERSION_OVERRIDE_AT_SIGN',
-          "The Dart language version override number must begin with '@dart'",
-          correction: "Specify a Dart language version override with a comment "
-              "like '// @dart = 2.0'.");
+  static const HintCode INVALID_LANGUAGE_VERSION_OVERRIDE_AT_SIGN = HintCode(
+    'INVALID_LANGUAGE_VERSION_OVERRIDE',
+    "The Dart language version override number must begin with '@dart'",
+    correction: "Specify a Dart language version override with a comment "
+        "like '// @dart = 2.0'.",
+    uniqueName: 'HintCode.INVALID_LANGUAGE_VERSION_OVERRIDE_AT_SIGN',
+  );
 
   /// Invalid Dart language version comments don't follow the specification [1].
   /// If a comment begins with "@dart" or "dart" (letters in any case),
@@ -739,32 +740,30 @@
   /// valid language version override comment, it is reported.
   ///
   /// [1] https://github.com/dart-lang/language/blob/master/accepted/future-releases/language-versioning/feature-specification.md#individual-library-language-version-override
-  static const HintCode INVALID_LANGUAGE_VERSION_OVERRIDE_EQUALS =
-      HintCodeWithUniqueName(
-          'INVALID_LANGUAGE_VERSION_OVERRIDE',
-          'HintCode.INVALID_LANGUAGE_VERSION_OVERRIDE_EQUALS',
-          "The Dart language version override comment must be specified with "
-              "an '=' character",
-          correction: "Specify a Dart language version override with a comment "
-              "like '// @dart = 2.0'.");
-
-  static const HintCode INVALID_LANGUAGE_VERSION_OVERRIDE_GREATER =
-      HintCodeWithUniqueName(
+  static const HintCode INVALID_LANGUAGE_VERSION_OVERRIDE_EQUALS = HintCode(
     'INVALID_LANGUAGE_VERSION_OVERRIDE',
-    'INVALID_LANGUAGE_VERSION_OVERRIDE_GREATER',
+    "The Dart language version override comment must be specified with "
+        "an '=' character",
+    correction: "Specify a Dart language version override with a comment "
+        "like '// @dart = 2.0'.",
+    uniqueName: 'HintCode.INVALID_LANGUAGE_VERSION_OVERRIDE_EQUALS',
+  );
+
+  static const HintCode INVALID_LANGUAGE_VERSION_OVERRIDE_GREATER = HintCode(
+    'INVALID_LANGUAGE_VERSION_OVERRIDE',
     "The language version override can't specify a version greater than the "
         "latest known language version: {0}.{1}",
     correction: "Try removing the language version override.",
+    uniqueName: 'INVALID_LANGUAGE_VERSION_OVERRIDE_GREATER',
   );
 
-  static const HintCode INVALID_LANGUAGE_VERSION_OVERRIDE_LOCATION =
-      HintCodeWithUniqueName(
+  static const HintCode INVALID_LANGUAGE_VERSION_OVERRIDE_LOCATION = HintCode(
     'INVALID_LANGUAGE_VERSION_OVERRIDE',
-    'INVALID_LANGUAGE_VERSION_OVERRIDE_LOCATION',
     "The language version override must be before any declaration or "
         "directive.",
     correction:
         "Try moving the language version override to the top of the file.",
+    uniqueName: 'INVALID_LANGUAGE_VERSION_OVERRIDE_LOCATION',
   );
 
   /// Invalid Dart language version comments don't follow the specification [1].
@@ -777,14 +776,14 @@
   /// valid language version override comment, it is reported.
   ///
   /// [1] https://github.com/dart-lang/language/blob/master/accepted/future-releases/language-versioning/feature-specification.md#individual-library-language-version-override
-  static const HintCode INVALID_LANGUAGE_VERSION_OVERRIDE_LOWER_CASE =
-      HintCodeWithUniqueName(
-          'INVALID_LANGUAGE_VERSION_OVERRIDE',
-          'HintCode.INVALID_LANGUAGE_VERSION_OVERRIDE_LOWER_CASE',
-          "The Dart language version override comment must be specified with "
-              "the word 'dart' in all lower case",
-          correction: "Specify a Dart language version override with a comment "
-              "like '// @dart = 2.0'.");
+  static const HintCode INVALID_LANGUAGE_VERSION_OVERRIDE_LOWER_CASE = HintCode(
+    'INVALID_LANGUAGE_VERSION_OVERRIDE',
+    "The Dart language version override comment must be specified with "
+        "the word 'dart' in all lower case",
+    correction: "Specify a Dart language version override with a comment "
+        "like '// @dart = 2.0'.",
+    uniqueName: 'HintCode.INVALID_LANGUAGE_VERSION_OVERRIDE_LOWER_CASE',
+  );
 
   /// Invalid Dart language version comments don't follow the specification [1].
   /// If a comment begins with "@dart" or "dart" (letters in any case),
@@ -796,14 +795,14 @@
   /// valid language version override comment, it is reported.
   ///
   /// [1] https://github.com/dart-lang/language/blob/master/accepted/future-releases/language-versioning/feature-specification.md#individual-library-language-version-override
-  static const HintCode INVALID_LANGUAGE_VERSION_OVERRIDE_NUMBER =
-      HintCodeWithUniqueName(
-          'INVALID_LANGUAGE_VERSION_OVERRIDE',
-          'HintCode.INVALID_LANGUAGE_VERSION_OVERRIDE_NUMBER',
-          "The Dart language version override comment must be specified with a "
-              "version number, like '2.0', after the '=' character.",
-          correction: "Specify a Dart language version override with a comment "
-              "like '// @dart = 2.0'.");
+  static const HintCode INVALID_LANGUAGE_VERSION_OVERRIDE_NUMBER = HintCode(
+    'INVALID_LANGUAGE_VERSION_OVERRIDE',
+    "The Dart language version override comment must be specified with a "
+        "version number, like '2.0', after the '=' character.",
+    correction: "Specify a Dart language version override with a comment "
+        "like '// @dart = 2.0'.",
+    uniqueName: 'HintCode.INVALID_LANGUAGE_VERSION_OVERRIDE_NUMBER',
+  );
 
   /// Invalid Dart language version comments don't follow the specification [1].
   /// If a comment begins with "@dart" or "dart" (letters in any case),
@@ -815,14 +814,14 @@
   /// valid language version override comment, it is reported.
   ///
   /// [1] https://github.com/dart-lang/language/blob/master/accepted/future-releases/language-versioning/feature-specification.md#individual-library-language-version-override
-  static const HintCode INVALID_LANGUAGE_VERSION_OVERRIDE_PREFIX =
-      HintCodeWithUniqueName(
-          'INVALID_LANGUAGE_VERSION_OVERRIDE',
-          'HintCode.INVALID_LANGUAGE_VERSION_OVERRIDE_PREFIX',
-          "The Dart language version override number can't be prefixed with "
-              "a letter",
-          correction: "Specify a Dart language version override with a comment "
-              "like '// @dart = 2.0'.");
+  static const HintCode INVALID_LANGUAGE_VERSION_OVERRIDE_PREFIX = HintCode(
+    'INVALID_LANGUAGE_VERSION_OVERRIDE',
+    "The Dart language version override number can't be prefixed with "
+        "a letter",
+    correction: "Specify a Dart language version override with a comment "
+        "like '// @dart = 2.0'.",
+    uniqueName: 'HintCode.INVALID_LANGUAGE_VERSION_OVERRIDE_PREFIX',
+  );
 
   /// Invalid Dart language version comments don't follow the specification [1].
   /// If a comment begins with "@dart" or "dart" (letters in any case),
@@ -835,13 +834,15 @@
   ///
   /// [1] https://github.com/dart-lang/language/blob/master/accepted/future-releases/language-versioning/feature-specification.md#individual-library-language-version-override
   static const HintCode INVALID_LANGUAGE_VERSION_OVERRIDE_TRAILING_CHARACTERS =
-      HintCodeWithUniqueName(
-          'INVALID_LANGUAGE_VERSION_OVERRIDE',
-          'HintCode.INVALID_LANGUAGE_VERSION_OVERRIDE_TRAILING_CHARACTERS',
-          "The Dart language version override comment can't be followed by "
-              "any non-whitespace characters",
-          correction: "Specify a Dart language version override with a comment "
-              "like '// @dart = 2.0'.");
+      HintCode(
+    'INVALID_LANGUAGE_VERSION_OVERRIDE',
+    "The Dart language version override comment can't be followed by "
+        "any non-whitespace characters",
+    correction: "Specify a Dart language version override with a comment "
+        "like '// @dart = 2.0'.",
+    uniqueName:
+        'HintCode.INVALID_LANGUAGE_VERSION_OVERRIDE_TRAILING_CHARACTERS',
+  );
 
   /// Invalid Dart language version comments don't follow the specification [1].
   /// If a comment begins with "@dart" or "dart" (letters in any case),
@@ -854,13 +855,14 @@
   ///
   /// [1] https://github.com/dart-lang/language/blob/master/accepted/future-releases/language-versioning/feature-specification.md#individual-library-language-version-override
   static const HintCode INVALID_LANGUAGE_VERSION_OVERRIDE_TWO_SLASHES =
-      HintCodeWithUniqueName(
-          'INVALID_LANGUAGE_VERSION_OVERRIDE',
-          'HintCode.INVALID_LANGUAGE_VERSION_OVERRIDE_TWO_SLASHES',
-          'The Dart language version override comment must be specified with '
-              'exactly two slashes.',
-          correction: "Specify a Dart language version override with a comment "
-              "like '// @dart = 2.0'.");
+      HintCode(
+    'INVALID_LANGUAGE_VERSION_OVERRIDE',
+    'The Dart language version override comment must be specified with '
+        'exactly two slashes.',
+    correction: "Specify a Dart language version override with a comment "
+        "like '// @dart = 2.0'.",
+    uniqueName: 'HintCode.INVALID_LANGUAGE_VERSION_OVERRIDE_TWO_SLASHES',
+  );
 
   /**
    * No parameters.
@@ -1186,12 +1188,12 @@
    * 0: the name of the parameter
    * 1: message details
    */
-  static const HintCode MISSING_REQUIRED_PARAM_WITH_DETAILS =
-      HintCodeWithUniqueName(
-          'MISSING_REQUIRED_PARAM',
-          'HintCode.MISSING_REQUIRED_PARAM_WITH_DETAILS',
-          "The parameter '{0}' is required. {1}.",
-          hasPublishedDocs: true);
+  static const HintCode MISSING_REQUIRED_PARAM_WITH_DETAILS = HintCode(
+    'MISSING_REQUIRED_PARAM',
+    "The parameter '{0}' is required. {1}.",
+    hasPublishedDocs: true,
+    uniqueName: 'HintCode.MISSING_REQUIRED_PARAM_WITH_DETAILS',
+  );
 
   /**
    * Parameters:
@@ -1453,13 +1455,14 @@
    * 0: the name of the class defining the annotated constructor
    */
   static const HintCode NON_CONST_CALL_TO_LITERAL_CONSTRUCTOR_USING_NEW =
-      HintCodeWithUniqueName(
-          'NON_CONST_CALL_TO_LITERAL_CONSTRUCTOR',
-          'HintCode.NON_CONST_CALL_TO_LITERAL_CONSTRUCTOR_USING_NEW',
-          "This instance creation must be 'const', because the {0} constructor "
-              "is marked as '@literal'.",
-          correction: "Try replacing the 'new' keyword with 'const'.",
-          hasPublishedDocs: true);
+      HintCode(
+    'NON_CONST_CALL_TO_LITERAL_CONSTRUCTOR',
+    "This instance creation must be 'const', because the {0} constructor "
+        "is marked as '@literal'.",
+    correction: "Try replacing the 'new' keyword with 'const'.",
+    hasPublishedDocs: true,
+    uniqueName: 'HintCode.NON_CONST_CALL_TO_LITERAL_CONSTRUCTOR_USING_NEW',
+  );
 
   /**
    * When the left operand of a binary expression uses '?.' operator, it can be
@@ -1560,28 +1563,28 @@
    *
    * No parameters.
    */
-  static const HintCode OVERRIDE_ON_NON_OVERRIDING_FIELD =
-      HintCodeWithUniqueName(
-          'OVERRIDE_ON_NON_OVERRIDING_MEMBER',
-          'HintCode.OVERRIDE_ON_NON_OVERRIDING_FIELD',
-          "The field doesn't override an inherited getter or setter.",
-          correction: "Try updating this class to match the superclass, or "
-              "removing the override annotation.",
-          hasPublishedDocs: true);
+  static const HintCode OVERRIDE_ON_NON_OVERRIDING_FIELD = HintCode(
+    'OVERRIDE_ON_NON_OVERRIDING_MEMBER',
+    "The field doesn't override an inherited getter or setter.",
+    correction: "Try updating this class to match the superclass, or "
+        "removing the override annotation.",
+    hasPublishedDocs: true,
+    uniqueName: 'HintCode.OVERRIDE_ON_NON_OVERRIDING_FIELD',
+  );
 
   /**
    * A getter with the override annotation does not override an existing getter.
    *
    * No parameters.
    */
-  static const HintCode OVERRIDE_ON_NON_OVERRIDING_GETTER =
-      HintCodeWithUniqueName(
-          'OVERRIDE_ON_NON_OVERRIDING_MEMBER',
-          'HintCode.OVERRIDE_ON_NON_OVERRIDING_GETTER',
-          "The getter doesn't override an inherited getter.",
-          correction: "Try updating this class to match the superclass, or "
-              "removing the override annotation.",
-          hasPublishedDocs: true);
+  static const HintCode OVERRIDE_ON_NON_OVERRIDING_GETTER = HintCode(
+    'OVERRIDE_ON_NON_OVERRIDING_MEMBER',
+    "The getter doesn't override an inherited getter.",
+    correction: "Try updating this class to match the superclass, or "
+        "removing the override annotation.",
+    hasPublishedDocs: true,
+    uniqueName: 'HintCode.OVERRIDE_ON_NON_OVERRIDING_GETTER',
+  );
 
   /**
    * A method with the override annotation does not override an existing method.
@@ -1622,28 +1625,28 @@
   // superclass, then consider removing the member from the subclass.
   //
   // If the member can't be removed, then remove the annotation.
-  static const HintCode OVERRIDE_ON_NON_OVERRIDING_METHOD =
-      HintCodeWithUniqueName(
-          'OVERRIDE_ON_NON_OVERRIDING_MEMBER',
-          'HintCode.OVERRIDE_ON_NON_OVERRIDING_METHOD',
-          "The method doesn't override an inherited method.",
-          correction: "Try updating this class to match the superclass, or "
-              "removing the override annotation.",
-          hasPublishedDocs: true);
+  static const HintCode OVERRIDE_ON_NON_OVERRIDING_METHOD = HintCode(
+    'OVERRIDE_ON_NON_OVERRIDING_MEMBER',
+    "The method doesn't override an inherited method.",
+    correction: "Try updating this class to match the superclass, or "
+        "removing the override annotation.",
+    hasPublishedDocs: true,
+    uniqueName: 'HintCode.OVERRIDE_ON_NON_OVERRIDING_METHOD',
+  );
 
   /**
    * A setter with the override annotation does not override an existing setter.
    *
    * No parameters.
    */
-  static const HintCode OVERRIDE_ON_NON_OVERRIDING_SETTER =
-      HintCodeWithUniqueName(
-          'OVERRIDE_ON_NON_OVERRIDING_MEMBER',
-          'HintCode.OVERRIDE_ON_NON_OVERRIDING_SETTER',
-          "The setter doesn't override an inherited setter.",
-          correction: "Try updating this class to match the superclass, or "
-              "removing the override annotation.",
-          hasPublishedDocs: true);
+  static const HintCode OVERRIDE_ON_NON_OVERRIDING_SETTER = HintCode(
+    'OVERRIDE_ON_NON_OVERRIDING_MEMBER',
+    "The setter doesn't override an inherited setter.",
+    correction: "Try updating this class to match the superclass, or "
+        "removing the override annotation.",
+    hasPublishedDocs: true,
+    uniqueName: 'HintCode.OVERRIDE_ON_NON_OVERRIDING_SETTER',
+  );
 
   /**
    * It is a bad practice for a package import to reference anything outside the
@@ -2544,47 +2547,49 @@
   //   print(x);
   // }
   // ```
-  static const HintCode UNNECESSARY_NULL_COMPARISON_FALSE =
-      HintCodeWithUniqueName(
-          'UNNECESSARY_NULL_COMPARISON',
-          'UNNECESSARY_NULL_COMPARISON_FALSE',
-          "The operand can't be null, so the condition is always false.",
-          correction: "Try removing the condition, an enclosing condition, "
-              "or the whole conditional statement.",
-          hasPublishedDocs: true);
+  static const HintCode UNNECESSARY_NULL_COMPARISON_FALSE = HintCode(
+    'UNNECESSARY_NULL_COMPARISON',
+    "The operand can't be null, so the condition is always false.",
+    correction: "Try removing the condition, an enclosing condition, "
+        "or the whole conditional statement.",
+    hasPublishedDocs: true,
+    uniqueName: 'UNNECESSARY_NULL_COMPARISON_FALSE',
+  );
 
   /**
    * No parameters.
    */
-  static const HintCode UNNECESSARY_NULL_COMPARISON_TRUE =
-      HintCodeWithUniqueName(
-          'UNNECESSARY_NULL_COMPARISON',
-          'UNNECESSARY_NULL_COMPARISON_TRUE',
-          "The operand can't be null, so the condition is always true.",
-          correction: "Remove the condition.",
-          hasPublishedDocs: true);
+  static const HintCode UNNECESSARY_NULL_COMPARISON_TRUE = HintCode(
+    'UNNECESSARY_NULL_COMPARISON',
+    "The operand can't be null, so the condition is always true.",
+    correction: "Remove the condition.",
+    hasPublishedDocs: true,
+    uniqueName: 'UNNECESSARY_NULL_COMPARISON_TRUE',
+  );
 
   /**
    * Unnecessary type checks, the result is always false.
    *
    * No parameters.
    */
-  static const HintCode UNNECESSARY_TYPE_CHECK_FALSE = HintCodeWithUniqueName(
-      'UNNECESSARY_TYPE_CHECK',
-      'UNNECESSARY_TYPE_CHECK_FALSE',
-      "Unnecessary type check, the result is always false.",
-      correction: "Try correcting the type check, or removing the type check.");
+  static const HintCode UNNECESSARY_TYPE_CHECK_FALSE = HintCode(
+    'UNNECESSARY_TYPE_CHECK',
+    "Unnecessary type check, the result is always false.",
+    correction: "Try correcting the type check, or removing the type check.",
+    uniqueName: 'UNNECESSARY_TYPE_CHECK_FALSE',
+  );
 
   /**
    * Unnecessary type checks, the result is always true.
    *
    * No parameters.
    */
-  static const HintCode UNNECESSARY_TYPE_CHECK_TRUE = HintCodeWithUniqueName(
-      'UNNECESSARY_TYPE_CHECK',
-      'UNNECESSARY_TYPE_CHECK_TRUE',
-      "Unnecessary type check, the result is always true.",
-      correction: "Try correcting the type check, or removing the type check.");
+  static const HintCode UNNECESSARY_TYPE_CHECK_TRUE = HintCode(
+    'UNNECESSARY_TYPE_CHECK',
+    "Unnecessary type check, the result is always true.",
+    correction: "Try correcting the type check, or removing the type check.",
+    uniqueName: 'UNNECESSARY_TYPE_CHECK_TRUE',
+  );
 
   /**
    * Parameters:
@@ -2734,12 +2739,13 @@
    * Parameters:
    * 0: the name of the parameter that is declared but not used
    */
-  static const HintCode UNUSED_ELEMENT_PARAMETER = HintCodeWithUniqueName(
-      'UNUSED_ELEMENT',
-      'HintCode.UNUSED_ELEMENT_PARAMETER',
-      "A value for optional parameter '{0}' isn't ever given.",
-      correction: "Try removing the unused parameter.",
-      hasPublishedDocs: true);
+  static const HintCode UNUSED_ELEMENT_PARAMETER = HintCode(
+    'UNUSED_ELEMENT',
+    "A value for optional parameter '{0}' isn't ever given.",
+    correction: "Try removing the unused parameter.",
+    hasPublishedDocs: true,
+    uniqueName: 'HintCode.UNUSED_ELEMENT_PARAMETER',
+  );
 
   /**
    * Parameters:
@@ -2926,10 +2932,19 @@
    * template. The correction associated with the error will be created from the
    * given [correction] template.
    */
-  const HintCode(String name, String message,
-      {String correction, bool hasPublishedDocs})
-      : super.temporary(name, message,
-            correction: correction, hasPublishedDocs: hasPublishedDocs);
+  const HintCode(
+    String name,
+    String message, {
+    String correction,
+    bool hasPublishedDocs = false,
+    String uniqueName,
+  }) : super(
+          correction: correction,
+          hasPublishedDocs: hasPublishedDocs,
+          message: message,
+          name: name,
+          uniqueName: uniqueName ?? 'HintCode.$name',
+        );
 
   @override
   ErrorSeverity get errorSeverity => ErrorType.HINT.severity;
@@ -2937,15 +2952,3 @@
   @override
   ErrorType get type => ErrorType.HINT;
 }
-
-/// A [HintCode] class in which a [uniqueName] can be given which is not just
-/// derived from [name].
-class HintCodeWithUniqueName extends HintCode {
-  @override
-  final String uniqueName;
-
-  const HintCodeWithUniqueName(String name, this.uniqueName, String message,
-      {String correction, bool hasPublishedDocs})
-      : super(name, message,
-            correction: correction, hasPublishedDocs: hasPublishedDocs);
-}
diff --git a/pkg/analyzer/lib/src/dart/error/lint_codes.dart b/pkg/analyzer/lib/src/dart/error/lint_codes.dart
index 5b5e320..cc1f0c2 100644
--- a/pkg/analyzer/lib/src/dart/error/lint_codes.dart
+++ b/pkg/analyzer/lib/src/dart/error/lint_codes.dart
@@ -10,8 +10,17 @@
 /// compiler, lint recommendations focus on matters of style and practices that
 /// might aggregated to define a project's style guide.
 class LintCode extends ErrorCode {
-  const LintCode(String name, String message, {String correction})
-      : super.temporary(name, message, correction: correction);
+  const LintCode(
+    String name,
+    String message, {
+    String correction,
+    String uniqueName,
+  }) : super(
+          correction: correction,
+          message: message,
+          name: name,
+          uniqueName: uniqueName ?? 'LintCode.$name',
+        );
 
   @override
   ErrorSeverity get errorSeverity => ErrorSeverity.INFO;
@@ -22,12 +31,6 @@
   @override
   ErrorType get type => ErrorType.LINT;
 
-  /// Overridden so that [LintCode] and its subclasses share the same uniqueName
-  /// pattern (we know how to identify a lint even if we don't know the specific
-  /// subclass the lint's code is defined in.
-  @override
-  String get uniqueName => "LintCode.$name";
-
   @override
   String get url => 'https://dart-lang.github.io/linter/lints/$name.html';
 
@@ -36,13 +39,11 @@
       other is LintCode && uniqueName == other.uniqueName;
 }
 
+@Deprecated('Use SecurityLintCode and its uniqueName')
 class LintCodeWithUniqueName extends LintCode {
-  @override
-  final String uniqueName;
-
-  const LintCodeWithUniqueName(String name, this.uniqueName, String message,
+  const LintCodeWithUniqueName(String name, String uniqueName, String message,
       {String correction})
-      : super(name, message, correction: correction);
+      : super(name, message, uniqueName: uniqueName, correction: correction);
 }
 
 /// Defines security-related best practice recommendations.
@@ -50,19 +51,19 @@
 /// The primary difference from [LintCode]s is that these codes cannot be
 /// suppressed with `// ignore:` or `// ignore_for_file:` comments.
 class SecurityLintCode extends LintCode {
-  const SecurityLintCode(String name, String message, {String correction})
-      : super(name, message, correction: correction);
+  const SecurityLintCode(String name, String message,
+      {String uniqueName, String correction})
+      : super(name, message,
+            uniqueName: uniqueName ?? 'LintCode.$name', correction: correction);
 
   @override
   bool get isIgnorable => false;
 }
 
+@Deprecated('Use SecurityLintCode and its uniqueName')
 class SecurityLintCodeWithUniqueName extends SecurityLintCode {
-  @override
-  final String uniqueName;
-
   const SecurityLintCodeWithUniqueName(
-      String name, this.uniqueName, String message,
+      String name, String uniqueName, String message,
       {String correction})
-      : super(name, message, correction: correction);
+      : super(name, message, uniqueName: uniqueName, correction: correction);
 }
diff --git a/pkg/analyzer/lib/src/dart/error/syntactic_errors.dart b/pkg/analyzer/lib/src/dart/error/syntactic_errors.dart
index d2d3c6c..8472e01 100644
--- a/pkg/analyzer/lib/src/dart/error/syntactic_errors.dart
+++ b/pkg/analyzer/lib/src/dart/error/syntactic_errors.dart
@@ -924,11 +924,19 @@
    * template. The correction associated with the error will be created from the
    * given [correction] template.
    */
-  const ParserErrorCode(String name, String message,
-      {String correction, bool hasPublishedDocs})
-      : super.temporary(name, message,
-            correction: correction,
-            hasPublishedDocs: hasPublishedDocs ?? false);
+  const ParserErrorCode(
+    String name,
+    String message, {
+    String correction,
+    bool hasPublishedDocs = false,
+    String uniqueName,
+  }) : super(
+          correction: correction,
+          hasPublishedDocs: hasPublishedDocs,
+          message: message,
+          name: name,
+          uniqueName: uniqueName ?? 'ParserErrorCode.$name',
+        );
 
   @override
   ErrorSeverity get errorSeverity => ErrorSeverity.ERROR;
diff --git a/pkg/analyzer/lib/src/dart/error/todo_codes.dart b/pkg/analyzer/lib/src/dart/error/todo_codes.dart
index fe6ed97..15db063 100644
--- a/pkg/analyzer/lib/src/dart/error/todo_codes.dart
+++ b/pkg/analyzer/lib/src/dart/error/todo_codes.dart
@@ -37,7 +37,12 @@
   /**
    * Initialize a newly created error code to have the given [name].
    */
-  const TodoCode(String name) : super.temporary(name, "{0}");
+  const TodoCode(String name)
+      : super(
+          message: "{0}",
+          name: name,
+          uniqueName: 'TodoCode.$name',
+        );
 
   @override
   ErrorSeverity get errorSeverity => ErrorSeverity.INFO;
diff --git a/pkg/analyzer/lib/src/dart/micro/library_graph.dart b/pkg/analyzer/lib/src/dart/micro/library_graph.dart
index b9b4b8e..26887ce 100644
--- a/pkg/analyzer/lib/src/dart/micro/library_graph.dart
+++ b/pkg/analyzer/lib/src/dart/micro/library_graph.dart
@@ -29,7 +29,6 @@
 import 'package:analyzer/src/summary/idl.dart';
 import 'package:analyzer/src/summary/link.dart' as graph
     show DependencyWalker, Node;
-import 'package:analyzer/src/summary2/informative_data.dart';
 import 'package:analyzer/src/util/performance/operation_performance.dart';
 import 'package:analyzer/src/workspace/workspace.dart';
 import 'package:collection/collection.dart';
@@ -425,7 +424,6 @@
         ),
       );
     }
-    var informativeData = createInformativeData(unit);
     var unlinkedBuilder = UnlinkedUnit2Builder(
       apiSignature: computeUnlinkedApiSignature(unit),
       exports: exports,
@@ -435,7 +433,6 @@
       hasPartOfDirective: hasPartOfDirective,
       partOfUri: partOfUriStr,
       lineStarts: unit.lineInfo.lineStarts,
-      informativeData: informativeData,
     );
     return CiderUnlinkedUnitBuilder(
         contentDigest: digest, unlinkedUnit: unlinkedBuilder);
@@ -708,8 +705,11 @@
   /// The hash of all the paths of the files in this cycle.
   String cyclePathsHash;
 
-  /// id of the cache entry.
-  int id;
+  /// id of the ast cache entry.
+  int astId;
+
+  /// id of the resolution cache entry.
+  int resolutionId;
 
   LibraryCycle();
 
diff --git a/pkg/analyzer/lib/src/dart/micro/resolve_file.dart b/pkg/analyzer/lib/src/dart/micro/resolve_file.dart
index 82e250c..29516e9 100644
--- a/pkg/analyzer/lib/src/dart/micro/resolve_file.dart
+++ b/pkg/analyzer/lib/src/dart/micro/resolve_file.dart
@@ -29,8 +29,8 @@
 import 'package:analyzer/src/summary/api_signature.dart';
 import 'package:analyzer/src/summary/format.dart';
 import 'package:analyzer/src/summary/idl.dart';
+import 'package:analyzer/src/summary2/bundle_reader.dart';
 import 'package:analyzer/src/summary2/link.dart' as link2;
-import 'package:analyzer/src/summary2/linked_bundle_context.dart';
 import 'package:analyzer/src/summary2/linked_element_factory.dart';
 import 'package:analyzer/src/summary2/reference.dart';
 import 'package:analyzer/src/task/options.dart';
@@ -641,9 +641,13 @@
   /// Clears all the loaded libraries. Returns the cache ids for the removed
   /// artifacts.
   Set<int> collectSharedDataIdentifiers() {
-    var ids = loadedBundles.map((cycle) => cycle.id).toSet();
+    var idSet = <int>{};
+    for (var cycle in loadedBundles) {
+      idSet.add(cycle.astId);
+      idSet.add(cycle.resolutionId);
+    }
     loadedBundles.clear();
-    return ids;
+    return idSet;
   }
 
   /// Load data required to access elements of the given [targetLibrary].
@@ -651,8 +655,6 @@
     @required FileState targetLibrary,
     @required OperationPerformanceImpl performance,
   }) {
-    var inputBundles = <LinkedNodeBundle>[];
-
     var librariesLinked = 0;
     var librariesLinkedTimer = Stopwatch();
     var inputsTimer = Stopwatch();
@@ -665,11 +667,14 @@
 
       cycle.directDependencies.forEach(loadBundle);
 
-      var key = cycle.cyclePathsHash;
-      var data = byteStore.get(key, cycle.signature);
-      var bytes = data?.bytes;
+      var astKey = '${cycle.cyclePathsHash}.ast';
+      var resolutionKey = '${cycle.cyclePathsHash}.resolution';
+      var astData = byteStore.get(astKey, cycle.signature);
+      var resolutionData = byteStore.get(resolutionKey, cycle.signature);
+      var astBytes = astData?.bytes;
+      var resolutionBytes = resolutionData?.bytes;
 
-      if (bytes == null) {
+      if (astBytes == null || resolutionBytes == null) {
         librariesLinkedTimer.start();
 
         inputsTimer.start();
@@ -714,39 +719,38 @@
         }
         inputsTimer.stop();
 
-        var linkResult = link2.link(elementFactory, inputLibraries);
+        var linkResult = link2.link(elementFactory, inputLibraries, true);
         librariesLinked += cycle.libraries.length;
 
-        bytes = serializeBundle(cycle.signature, linkResult).toBuffer();
+        astBytes = linkResult.astBytes;
+        resolutionBytes = linkResult.resolutionBytes;
 
-        data = byteStore.putGet(key, cycle.signature, bytes);
-        bytes = data.bytes;
-        performance.getDataInt('bytesPut').add(bytes.length);
+        astData = byteStore.putGet(astKey, cycle.signature, astBytes);
+        astBytes = astData.bytes;
+        performance.getDataInt('bytesPut').add(astBytes.length);
+
+        resolutionData =
+            byteStore.putGet(resolutionKey, cycle.signature, resolutionBytes);
+        resolutionBytes = resolutionData.bytes;
+        performance.getDataInt('bytesPut').add(resolutionBytes.length);
 
         librariesLinkedTimer.stop();
       } else {
-        performance.getDataInt('bytesGet').add(bytes.length);
+        performance.getDataInt('bytesGet').add(astBytes.length);
+        performance.getDataInt('bytesGet').add(resolutionBytes.length);
         performance.getDataInt('libraryLoadCount').add(cycle.libraries.length);
       }
-      cycle.id = data.id;
+      cycle.astId = astData.id;
+      cycle.resolutionId = resolutionData.id;
 
-      var cBundle = CiderLinkedLibraryCycle.fromBuffer(bytes);
-      inputBundles.add(cBundle.bundle);
       elementFactory.addBundle(
-        LinkedBundleContext(elementFactory, cBundle.bundle),
+        BundleReader(
+          elementFactory: elementFactory,
+          astBytes: astBytes,
+          resolutionBytes: resolutionBytes,
+        ),
       );
 
-      // Set informative data.
-      for (var libraryFile in cycle.libraries) {
-        for (var unitFile in libraryFile.libraryFiles) {
-          elementFactory.setInformativeData(
-            libraryFile.uriStr,
-            unitFile.uriStr,
-            unitFile.unlinked2.informativeData,
-          );
-        }
-      }
-
       // We might have just linked dart:core, ensure the type provider.
       _createElementFactoryTypeProvider();
     }
@@ -772,7 +776,8 @@
     var removedSet = removed.toSet();
     loadedBundles.removeWhere((cycle) {
       if (cycle.libraries.any(removedSet.contains)) {
-        removedIds.add(cycle.id);
+        removedIds.add(cycle.astId);
+        removedIds.add(cycle.resolutionId);
         return true;
       }
       return false;
@@ -788,12 +793,4 @@
       elementFactory.createTypeProviders(dartCore, dartAsync);
     }
   }
-
-  static CiderLinkedLibraryCycleBuilder serializeBundle(
-      List<int> signature, link2.LinkResult linkResult) {
-    return CiderLinkedLibraryCycleBuilder(
-      signature: signature,
-      bundle: linkResult.bundle,
-    );
-  }
 }
diff --git a/pkg/analyzer/lib/src/error/analyzer_error_code.dart b/pkg/analyzer/lib/src/error/analyzer_error_code.dart
index f8cb42d..a3543a2 100644
--- a/pkg/analyzer/lib/src/error/analyzer_error_code.dart
+++ b/pkg/analyzer/lib/src/error/analyzer_error_code.dart
@@ -3,14 +3,24 @@
 // BSD-style license that can be found in the LICENSE file.
 
 import 'package:analyzer/error/error.dart';
+import 'package:meta/meta.dart';
 
 /// A superclass for error codes that can have a url associated with them.
 abstract class AnalyzerErrorCode extends ErrorCode {
   /// Initialize a newly created error code.
-  const AnalyzerErrorCode.temporary(String name, String message,
-      {String correction, bool hasPublishedDocs, bool isUnresolvedIdentifier})
-      : super.temporary(name, message,
-            correction: correction,
-            hasPublishedDocs: hasPublishedDocs ?? false,
-            isUnresolvedIdentifier: isUnresolvedIdentifier ?? false);
+  const AnalyzerErrorCode({
+    String correction,
+    bool hasPublishedDocs = false,
+    bool isUnresolvedIdentifier = false,
+    @required String message,
+    @required String name,
+    @required String uniqueName,
+  }) : super(
+          correction: correction,
+          hasPublishedDocs: hasPublishedDocs,
+          isUnresolvedIdentifier: isUnresolvedIdentifier,
+          message: message,
+          name: name,
+          uniqueName: uniqueName,
+        );
 }
diff --git a/pkg/analyzer/lib/src/error/codes.dart b/pkg/analyzer/lib/src/error/codes.dart
index f12b3a7..fc6bb66 100644
--- a/pkg/analyzer/lib/src/error/codes.dart
+++ b/pkg/analyzer/lib/src/error/codes.dart
@@ -70,13 +70,13 @@
   // }
   // ```
   static const CompileTimeErrorCode ABSTRACT_FIELD_CONSTRUCTOR_INITIALIZER =
-      CompileTimeErrorCodeWithUniqueName(
-          'ABSTRACT_FIELD_INITIALIZER',
-          'ABSTRACT_FIELD_CONSTRUCTOR_INITIALIZER',
-          "Abstract fields can't have initializers.",
-          correction:
-              "Try removing the field initializer or the 'abstract' keyword "
-              "from the field declaration.");
+      CompileTimeErrorCode(
+    'ABSTRACT_FIELD_INITIALIZER',
+    "Abstract fields can't have initializers.",
+    correction: "Try removing the field initializer or the 'abstract' keyword "
+        "from the field declaration.",
+    uniqueName: 'ABSTRACT_FIELD_CONSTRUCTOR_INITIALIZER',
+  );
 
   /**
    * No parameters.
@@ -1444,12 +1444,13 @@
    * 0: the name of the type variable
    */
   static const CompileTimeErrorCode CONFLICTING_TYPE_VARIABLE_AND_CLASS =
-      CompileTimeErrorCodeWithUniqueName(
-          'CONFLICTING_TYPE_VARIABLE_AND_CONTAINER',
-          'CONFLICTING_TYPE_VARIABLE_AND_CLASS',
-          "'{0}' can't be used to name both a type variable and the class in "
-              "which the type variable is defined.",
-          correction: "Try renaming either the type variable or the class.");
+      CompileTimeErrorCode(
+    'CONFLICTING_TYPE_VARIABLE_AND_CONTAINER',
+    "'{0}' can't be used to name both a type variable and the class in "
+        "which the type variable is defined.",
+    correction: "Try renaming either the type variable or the class.",
+    uniqueName: 'CONFLICTING_TYPE_VARIABLE_AND_CLASS',
+  );
 
   /**
    * It is a compile time error if an extension declares a type parameter with
@@ -1459,13 +1460,13 @@
    * 0: the name of the type variable
    */
   static const CompileTimeErrorCode CONFLICTING_TYPE_VARIABLE_AND_EXTENSION =
-      CompileTimeErrorCodeWithUniqueName(
-          'CONFLICTING_TYPE_VARIABLE_AND_CONTAINER',
-          'CONFLICTING_TYPE_VARIABLE_AND_EXTENSION',
-          "'{0}' can't be used to name both a type variable and the extension "
-              "in which the type variable is defined.",
-          correction:
-              "Try renaming either the type variable or the extension.");
+      CompileTimeErrorCode(
+    'CONFLICTING_TYPE_VARIABLE_AND_CONTAINER',
+    "'{0}' can't be used to name both a type variable and the extension "
+        "in which the type variable is defined.",
+    correction: "Try renaming either the type variable or the extension.",
+    uniqueName: 'CONFLICTING_TYPE_VARIABLE_AND_EXTENSION',
+  );
 
   /**
    * 7. Classes: It is a compile time error if a generic class declares a type
@@ -1476,25 +1477,26 @@
    * 0: the name of the type variable
    */
   static const CompileTimeErrorCode CONFLICTING_TYPE_VARIABLE_AND_MEMBER_CLASS =
-      CompileTimeErrorCodeWithUniqueName(
-          'CONFLICTING_TYPE_VARIABLE_AND_MEMBER',
-          'CONFLICTING_TYPE_VARIABLE_AND_MEMBER_CLASS',
-          "'{0}' can't be used to name both a type variable and a member in "
-              "this class.",
-          correction: "Try renaming either the type variable or the member.");
+      CompileTimeErrorCode(
+    'CONFLICTING_TYPE_VARIABLE_AND_MEMBER',
+    "'{0}' can't be used to name both a type variable and a member in "
+        "this class.",
+    correction: "Try renaming either the type variable or the member.",
+    uniqueName: 'CONFLICTING_TYPE_VARIABLE_AND_MEMBER_CLASS',
+  );
 
   /**
    * It is a compile time error if a generic extension declares a member with
    * the same basename as the name of any of the extension's type parameters.
    */
   static const CompileTimeErrorCode
-      CONFLICTING_TYPE_VARIABLE_AND_MEMBER_EXTENSION =
-      CompileTimeErrorCodeWithUniqueName(
-          'CONFLICTING_TYPE_VARIABLE_AND_MEMBER',
-          'CONFLICTING_TYPE_VARIABLE_AND_MEMBER_EXTENSION',
-          "'{0}' can't be used to name both a type variable and a member in "
-              "this extension.",
-          correction: "Try renaming either the type variable or the member.");
+      CONFLICTING_TYPE_VARIABLE_AND_MEMBER_EXTENSION = CompileTimeErrorCode(
+    'CONFLICTING_TYPE_VARIABLE_AND_MEMBER',
+    "'{0}' can't be used to name both a type variable and a member in "
+        "this extension.",
+    correction: "Try renaming either the type variable or the member.",
+    uniqueName: 'CONFLICTING_TYPE_VARIABLE_AND_MEMBER_EXTENSION',
+  );
 
   /**
    * 16.12.2 Const: It is a compile-time error if evaluation of a constant
@@ -1640,14 +1642,15 @@
    * 0: the name of the instance field.
    */
   static const CompileTimeErrorCode CONST_CONSTRUCTOR_WITH_MIXIN_WITH_FIELD =
-      CompileTimeErrorCodeWithUniqueName(
-          'CONST_CONSTRUCTOR_WITH_MIXIN_WITH_FIELD',
-          'CONST_CONSTRUCTOR_WITH_MIXIN_WITH_FIELD',
-          "This constructor can't be declared 'const' because a mixin adds the "
-              "instance field: {0}.",
-          correction: "Try removing the 'const' keyword or removing the 'with' "
-              "clause from the class declaration, or removing the field from "
-              "the mixin class.");
+      CompileTimeErrorCode(
+    'CONST_CONSTRUCTOR_WITH_MIXIN_WITH_FIELD',
+    "This constructor can't be declared 'const' because a mixin adds the "
+        "instance field: {0}.",
+    correction: "Try removing the 'const' keyword or removing the 'with' "
+        "clause from the class declaration, or removing the field from "
+        "the mixin class.",
+    uniqueName: 'CONST_CONSTRUCTOR_WITH_MIXIN_WITH_FIELD',
+  );
 
   /**
    * 7.6.3 Constant Constructors: The superinitializer that appears, explicitly
@@ -1664,14 +1667,15 @@
    * 0: the names of the instance fields.
    */
   static const CompileTimeErrorCode CONST_CONSTRUCTOR_WITH_MIXIN_WITH_FIELDS =
-      CompileTimeErrorCodeWithUniqueName(
-          'CONST_CONSTRUCTOR_WITH_MIXIN_WITH_FIELD',
-          'CONST_CONSTRUCTOR_WITH_MIXIN_WITH_FIELDS',
-          "This constructor can't be declared 'const' because the mixins add "
-              "the instance fields: {0}.",
-          correction: "Try removing the 'const' keyword or removing the 'with' "
-              "clause from the class declaration, or removing the fields from "
-              "the mixin classes.");
+      CompileTimeErrorCode(
+    'CONST_CONSTRUCTOR_WITH_MIXIN_WITH_FIELD',
+    "This constructor can't be declared 'const' because the mixins add "
+        "the instance fields: {0}.",
+    correction: "Try removing the 'const' keyword or removing the 'with' "
+        "clause from the class declaration, or removing the fields from "
+        "the mixin classes.",
+    uniqueName: 'CONST_CONSTRUCTOR_WITH_MIXIN_WITH_FIELDS',
+  );
 
   /**
    * 7.6.3 Constant Constructors: The superinitializer that appears, explicitly
@@ -1831,13 +1835,14 @@
    * 1: the name of the type of the field
    */
   static const CompileTimeErrorCode CONST_FIELD_INITIALIZER_NOT_ASSIGNABLE =
-      CompileTimeErrorCodeWithUniqueName(
-          'FIELD_INITIALIZER_NOT_ASSIGNABLE',
-          'CONST_FIELD_INITIALIZER_NOT_ASSIGNABLE',
-          "The initializer type '{0}' can't be assigned to the field type "
-              "'{1}' in a const constructor.",
-          correction: "Try using a subtype, or removing the 'const' keyword",
-          hasPublishedDocs: true);
+      CompileTimeErrorCode(
+    'FIELD_INITIALIZER_NOT_ASSIGNABLE',
+    "The initializer type '{0}' can't be assigned to the field type "
+        "'{1}' in a const constructor.",
+    correction: "Try using a subtype, or removing the 'const' keyword",
+    hasPublishedDocs: true,
+    uniqueName: 'CONST_FIELD_INITIALIZER_NOT_ASSIGNABLE',
+  );
 
   /**
    * No parameters.
@@ -2162,12 +2167,14 @@
    * Parameters:
    * 0: the name of the non-type element
    */
-  static const CompileTimeErrorCode CONST_WITH_NON_TYPE =
-      CompileTimeErrorCodeWithUniqueName('CREATION_WITH_NON_TYPE',
-          'CONST_WITH_NON_TYPE', "The name '{0}' isn't a class.",
-          correction: "Try correcting the name to match an existing class.",
-          hasPublishedDocs: true,
-          isUnresolvedIdentifier: true);
+  static const CompileTimeErrorCode CONST_WITH_NON_TYPE = CompileTimeErrorCode(
+    'CREATION_WITH_NON_TYPE',
+    "The name '{0}' isn't a class.",
+    correction: "Try correcting the name to match an existing class.",
+    hasPublishedDocs: true,
+    isUnresolvedIdentifier: true,
+    uniqueName: 'CONST_WITH_NON_TYPE',
+  );
 
   /**
    * No parameters.
@@ -2475,24 +2482,26 @@
   // }
   // ```
   static const CompileTimeErrorCode DUPLICATE_CONSTRUCTOR_DEFAULT =
-      CompileTimeErrorCodeWithUniqueName(
-          'DUPLICATE_CONSTRUCTOR',
-          'DUPLICATE_CONSTRUCTOR_DEFAULT',
-          "The default constructor is already defined.",
-          correction: "Try giving one of the constructors a name.",
-          hasPublishedDocs: true);
+      CompileTimeErrorCode(
+    'DUPLICATE_CONSTRUCTOR',
+    "The default constructor is already defined.",
+    correction: "Try giving one of the constructors a name.",
+    hasPublishedDocs: true,
+    uniqueName: 'DUPLICATE_CONSTRUCTOR_DEFAULT',
+  );
 
   /**
    * Parameters:
    * 0: the name of the duplicate entity
    */
   static const CompileTimeErrorCode DUPLICATE_CONSTRUCTOR_NAME =
-      CompileTimeErrorCodeWithUniqueName(
-          'DUPLICATE_CONSTRUCTOR',
-          'DUPLICATE_CONSTRUCTOR_NAME',
-          "The constructor with name '{0}' is already defined.",
-          correction: "Try renaming one of the constructors.",
-          hasPublishedDocs: true);
+      CompileTimeErrorCode(
+    'DUPLICATE_CONSTRUCTOR',
+    "The constructor with name '{0}' is already defined.",
+    correction: "Try renaming one of the constructors.",
+    hasPublishedDocs: true,
+    uniqueName: 'DUPLICATE_CONSTRUCTOR_NAME',
+  );
 
   /**
    * Parameters:
@@ -2526,6 +2535,14 @@
       correction: "Try renaming one of the declarations.",
       hasPublishedDocs: true);
 
+  static const CompileTimeErrorCode DUPLICATE_FIELD_FORMAL_PARAMETER =
+      CompileTimeErrorCode(
+          'DUPLICATE_FIELD_FORMAL_PARAMETER',
+          "The field '{0}' can't be referenced in multiple initializing "
+              "parameters in the same constructor.",
+          correction: "Try removing one of the parameters, or "
+              "using different fields.");
+
   /**
    * Parameters:
    * 0: the name of the parameter that was duplicated
@@ -3010,11 +3027,14 @@
   static const CompileTimeErrorCode EXTENDS_DISALLOWED_CLASS =
       // TODO(scheglov) We might want to restore specific code with FrontEnd.
       //  https://github.com/dart-lang/sdk/issues/31821
-      CompileTimeErrorCodeWithUniqueName('SUBTYPE_OF_DISALLOWED_TYPE',
-          'EXTENDS_DISALLOWED_CLASS', "Classes can't extend '{0}'.",
-          correction: "Try specifying a different superclass, or "
-              "removing the extends clause.",
-          hasPublishedDocs: true);
+      CompileTimeErrorCode(
+    'SUBTYPE_OF_DISALLOWED_TYPE',
+    "Classes can't extend '{0}'.",
+    correction: "Try specifying a different superclass, or "
+        "removing the extends clause.",
+    hasPublishedDocs: true,
+    uniqueName: 'EXTENDS_DISALLOWED_CLASS',
+  );
 
   /**
    * Parameters:
@@ -3851,12 +3871,13 @@
   // }
   // ```
   static const CompileTimeErrorCode FINAL_NOT_INITIALIZED_CONSTRUCTOR_1 =
-      CompileTimeErrorCodeWithUniqueName(
-          'FINAL_NOT_INITIALIZED_CONSTRUCTOR',
-          'FINAL_NOT_INITIALIZED_CONSTRUCTOR_1',
-          "All final variables must be initialized, but '{0}' isn't.",
-          correction: "Try adding an initializer for the field.",
-          hasPublishedDocs: true);
+      CompileTimeErrorCode(
+    'FINAL_NOT_INITIALIZED_CONSTRUCTOR',
+    "All final variables must be initialized, but '{0}' isn't.",
+    correction: "Try adding an initializer for the field.",
+    hasPublishedDocs: true,
+    uniqueName: 'FINAL_NOT_INITIALIZED_CONSTRUCTOR_1',
+  );
 
   /**
    * Parameters:
@@ -3864,13 +3885,14 @@
    * 1: the name of the uninitialized final variable
    */
   static const CompileTimeErrorCode FINAL_NOT_INITIALIZED_CONSTRUCTOR_2 =
-      CompileTimeErrorCodeWithUniqueName(
-          'FINAL_NOT_INITIALIZED_CONSTRUCTOR',
-          'FINAL_NOT_INITIALIZED_CONSTRUCTOR_2',
-          "All final variables must be initialized, but '{0}' and '{1}' "
-              "aren't.",
-          correction: "Try adding initializers for the fields.",
-          hasPublishedDocs: true);
+      CompileTimeErrorCode(
+    'FINAL_NOT_INITIALIZED_CONSTRUCTOR',
+    "All final variables must be initialized, but '{0}' and '{1}' "
+        "aren't.",
+    correction: "Try adding initializers for the fields.",
+    hasPublishedDocs: true,
+    uniqueName: 'FINAL_NOT_INITIALIZED_CONSTRUCTOR_2',
+  );
 
   /**
    * Parameters:
@@ -3879,13 +3901,14 @@
    * 2: the number of additional not initialized variables that aren't listed
    */
   static const CompileTimeErrorCode FINAL_NOT_INITIALIZED_CONSTRUCTOR_3_PLUS =
-      CompileTimeErrorCodeWithUniqueName(
-          'FINAL_NOT_INITIALIZED_CONSTRUCTOR',
-          'FINAL_NOT_INITIALIZED_CONSTRUCTOR_3',
-          "All final variables must be initialized, but '{0}', '{1}', and {2} "
-              "others aren't.",
-          correction: "Try adding initializers for the fields.",
-          hasPublishedDocs: true);
+      CompileTimeErrorCode(
+    'FINAL_NOT_INITIALIZED_CONSTRUCTOR',
+    "All final variables must be initialized, but '{0}', '{1}', and {2} "
+        "others aren't.",
+    correction: "Try adding initializers for the fields.",
+    hasPublishedDocs: true,
+    uniqueName: 'FINAL_NOT_INITIALIZED_CONSTRUCTOR_3',
+  );
 
   /**
    * 17.6.2 For-in. It the iterable expression does not implement Iterable with
@@ -4201,13 +4224,14 @@
    * 0: The name of the disallowed type
    */
   static const CompileTimeErrorCode IMPLEMENTS_DISALLOWED_CLASS =
-      CompileTimeErrorCodeWithUniqueName(
-          'SUBTYPE_OF_DISALLOWED_TYPE',
-          'IMPLEMENTS_DISALLOWED_CLASS',
-          "Classes and mixins can't implement '{0}'.",
-          correction: "Try specifying a different interface, or "
-              "remove the class from the list.",
-          hasPublishedDocs: true);
+      CompileTimeErrorCode(
+    'SUBTYPE_OF_DISALLOWED_TYPE',
+    "Classes and mixins can't implement '{0}'.",
+    correction: "Try specifying a different interface, or "
+        "remove the class from the list.",
+    hasPublishedDocs: true,
+    uniqueName: 'IMPLEMENTS_DISALLOWED_CLASS',
+  );
 
   /**
    * Parameters:
@@ -5043,10 +5067,13 @@
    * No parameters.
    */
   static const CompileTimeErrorCode INVALID_ANNOTATION_GETTER =
-      CompileTimeErrorCodeWithUniqueName('INVALID_ANNOTATION',
-          'INVALID_ANNOTATION_GETTER', "Getters can't be used as annotations.",
-          correction: "Try using a top-level variable or a field.",
-          hasPublishedDocs: true);
+      CompileTimeErrorCode(
+    'INVALID_ANNOTATION',
+    "Getters can't be used as annotations.",
+    correction: "Try using a top-level variable or a field.",
+    hasPublishedDocs: true,
+    uniqueName: 'INVALID_ANNOTATION_GETTER',
+  );
 
   /**
    * Parameters:
@@ -5549,39 +5576,39 @@
   // List<T> newList<T>() => <T>[];
   // ```
   static const CompileTimeErrorCode INVALID_TYPE_ARGUMENT_IN_CONST_LIST =
-      CompileTimeErrorCodeWithUniqueName(
-          'INVALID_TYPE_ARGUMENT_IN_CONST_LITERAL',
-          'INVALID_TYPE_ARGUMENT_IN_CONST_LIST',
-          "Constant list literals can't include a type parameter as a type "
-              "argument, such as '{0}'.",
-          correction:
-              "Try replacing the type parameter with a different type.");
+      CompileTimeErrorCode(
+    'INVALID_TYPE_ARGUMENT_IN_CONST_LITERAL',
+    "Constant list literals can't include a type parameter as a type "
+        "argument, such as '{0}'.",
+    correction: "Try replacing the type parameter with a different type.",
+    uniqueName: 'INVALID_TYPE_ARGUMENT_IN_CONST_LIST',
+  );
 
   /**
    * Parameters:
    * 0: the name of the type parameter
    */
   static const CompileTimeErrorCode INVALID_TYPE_ARGUMENT_IN_CONST_MAP =
-      CompileTimeErrorCodeWithUniqueName(
-          'INVALID_TYPE_ARGUMENT_IN_CONST_LITERAL',
-          'INVALID_TYPE_ARGUMENT_IN_CONST_MAP',
-          "Constant map literals can't include a type parameter as a type "
-              "argument, such as '{0}'.",
-          correction:
-              "Try replacing the type parameter with a different type.");
+      CompileTimeErrorCode(
+    'INVALID_TYPE_ARGUMENT_IN_CONST_LITERAL',
+    "Constant map literals can't include a type parameter as a type "
+        "argument, such as '{0}'.",
+    correction: "Try replacing the type parameter with a different type.",
+    uniqueName: 'INVALID_TYPE_ARGUMENT_IN_CONST_MAP',
+  );
 
   /**
    * Parameters:
    * 0: the name of the type parameter
    */
   static const CompileTimeErrorCode INVALID_TYPE_ARGUMENT_IN_CONST_SET =
-      CompileTimeErrorCodeWithUniqueName(
-          'INVALID_TYPE_ARGUMENT_IN_CONST_LITERAL',
-          'INVALID_TYPE_ARGUMENT_IN_CONST_SET',
-          "Constant set literals can't include a type parameter as a type "
-              "argument, such as '{0}'.",
-          correction:
-              "Try replacing the type parameter with a different type.");
+      CompileTimeErrorCode(
+    'INVALID_TYPE_ARGUMENT_IN_CONST_LITERAL',
+    "Constant set literals can't include a type parameter as a type "
+        "argument, such as '{0}'.",
+    correction: "Try replacing the type parameter with a different type.",
+    uniqueName: 'INVALID_TYPE_ARGUMENT_IN_CONST_SET',
+  );
 
   /**
    * Parameters:
@@ -6476,11 +6503,14 @@
    * 0: The name of the disallowed type
    */
   static const CompileTimeErrorCode MIXIN_OF_DISALLOWED_CLASS =
-      CompileTimeErrorCodeWithUniqueName('SUBTYPE_OF_DISALLOWED_TYPE',
-          'MIXIN_OF_DISALLOWED_CLASS', "Classes can't mixin '{0}'.",
-          correction: "Try specifying a different class or mixin, or "
-              "remove the class or mixin from the list.",
-          hasPublishedDocs: true);
+      CompileTimeErrorCode(
+    'SUBTYPE_OF_DISALLOWED_TYPE',
+    "Classes can't mixin '{0}'.",
+    correction: "Try specifying a different class or mixin, or "
+        "remove the class or mixin from the list.",
+    hasPublishedDocs: true,
+    uniqueName: 'MIXIN_OF_DISALLOWED_CLASS',
+  );
 
   /**
    * No parameters.
@@ -6529,14 +6559,14 @@
    * 0: The name of the disallowed type
    */
   static const CompileTimeErrorCode
-      MIXIN_SUPER_CLASS_CONSTRAINT_DISALLOWED_CLASS =
-      CompileTimeErrorCodeWithUniqueName(
-          'SUBTYPE_OF_DISALLOWED_TYPE',
-          'MIXIN_SUPER_CLASS_CONSTRAINT_DISALLOWED_CLASS',
-          "''{0}' can't be used as a superclass constraint.",
-          correction: "Try specifying a different super-class constraint, or "
-              "remove the 'on' clause.",
-          hasPublishedDocs: true);
+      MIXIN_SUPER_CLASS_CONSTRAINT_DISALLOWED_CLASS = CompileTimeErrorCode(
+    'SUBTYPE_OF_DISALLOWED_TYPE',
+    "''{0}' can't be used as a superclass constraint.",
+    correction: "Try specifying a different super-class constraint, or "
+        "remove the 'on' clause.",
+    hasPublishedDocs: true,
+    uniqueName: 'MIXIN_SUPER_CLASS_CONSTRAINT_DISALLOWED_CLASS',
+  );
 
   /**
    * No parameters.
@@ -6653,12 +6683,14 @@
   //   f();
   // }
   // ```
-  static const CompileTimeErrorCode NEW_WITH_NON_TYPE =
-      CompileTimeErrorCodeWithUniqueName('CREATION_WITH_NON_TYPE',
-          'NEW_WITH_NON_TYPE', "The name '{0}' isn't a class.",
-          correction: "Try correcting the name to match an existing class.",
-          hasPublishedDocs: true,
-          isUnresolvedIdentifier: true);
+  static const CompileTimeErrorCode NEW_WITH_NON_TYPE = CompileTimeErrorCode(
+    'CREATION_WITH_NON_TYPE',
+    "The name '{0}' isn't a class.",
+    correction: "Try correcting the name to match an existing class.",
+    hasPublishedDocs: true,
+    isUnresolvedIdentifier: true,
+    uniqueName: 'NEW_WITH_NON_TYPE',
+  );
 
   /**
    * 12.11.1 New: If <i>T</i> is a class or parameterized type accessible in the
@@ -6844,12 +6876,13 @@
    *    constructor
    */
   static const CompileTimeErrorCode NO_DEFAULT_SUPER_CONSTRUCTOR_EXPLICIT =
-      CompileTimeErrorCodeWithUniqueName(
-          'NO_DEFAULT_SUPER_CONSTRUCTOR',
-          'NO_DEFAULT_SUPER_CONSTRUCTOR_EXPLICIT',
-          "The superclass '{0}' doesn't have a zero argument constructor.",
-          correction: "Try declaring a zero argument constructor in '{0}', or "
-              "explicitly invoking a different constructor in '{0}'.");
+      CompileTimeErrorCode(
+    'NO_DEFAULT_SUPER_CONSTRUCTOR',
+    "The superclass '{0}' doesn't have a zero argument constructor.",
+    correction: "Try declaring a zero argument constructor in '{0}', or "
+        "explicitly invoking a different constructor in '{0}'.",
+    uniqueName: 'NO_DEFAULT_SUPER_CONSTRUCTOR_EXPLICIT',
+  );
 
   /**
    * User friendly specialized error for [NON_GENERATIVE_CONSTRUCTOR]. This
@@ -6873,13 +6906,14 @@
    * 1: the name of the subclass that does not contain any explicit constructors
    */
   static const CompileTimeErrorCode NO_DEFAULT_SUPER_CONSTRUCTOR_IMPLICIT =
-      CompileTimeErrorCodeWithUniqueName(
-          'NO_DEFAULT_SUPER_CONSTRUCTOR',
-          'NO_DEFAULT_SUPER_CONSTRUCTOR_IMPLICIT',
-          "The superclass '{0}' doesn't have a zero argument constructor.",
-          correction: "Try declaring a zero argument constructor in '{0}', or "
-              "declaring a constructor in {1} that explicitly invokes a "
-              "constructor in '{0}'.");
+      CompileTimeErrorCode(
+    'NO_DEFAULT_SUPER_CONSTRUCTOR',
+    "The superclass '{0}' doesn't have a zero argument constructor.",
+    correction: "Try declaring a zero argument constructor in '{0}', or "
+        "declaring a constructor in {1} that explicitly invokes a "
+        "constructor in '{0}'.",
+    uniqueName: 'NO_DEFAULT_SUPER_CONSTRUCTOR_IMPLICIT',
+  );
 
   /**
    * Parameters:
@@ -6891,14 +6925,15 @@
    */
   static const CompileTimeErrorCode
       NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_FIVE_PLUS =
-      CompileTimeErrorCodeWithUniqueName(
-          'NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER',
-          'NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_FIVE_PLUS',
-          "Missing concrete implementations of '{0}', '{1}', '{2}', '{3}', and "
-              "{4} more.",
-          correction: "Try implementing the missing methods, or make the class "
-              "abstract.",
-          hasPublishedDocs: true);
+      CompileTimeErrorCode(
+    'NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER',
+    "Missing concrete implementations of '{0}', '{1}', '{2}', '{3}', and "
+        "{4} more.",
+    correction: "Try implementing the missing methods, or make the class "
+        "abstract.",
+    hasPublishedDocs: true,
+    uniqueName: 'NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_FIVE_PLUS',
+  );
 
   /**
    * Parameters:
@@ -6908,14 +6943,14 @@
    * 3: the name of the fourth member
    */
   static const CompileTimeErrorCode
-      NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_FOUR =
-      CompileTimeErrorCodeWithUniqueName(
-          'NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER',
-          'NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_FOUR',
-          "Missing concrete implementations of '{0}', '{1}', '{2}', and '{3}'.",
-          correction: "Try implementing the missing methods, or make the class "
-              "abstract.",
-          hasPublishedDocs: true);
+      NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_FOUR = CompileTimeErrorCode(
+    'NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER',
+    "Missing concrete implementations of '{0}', '{1}', '{2}', and '{3}'.",
+    correction: "Try implementing the missing methods, or make the class "
+        "abstract.",
+    hasPublishedDocs: true,
+    uniqueName: 'NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_FOUR',
+  );
 
   /**
    * Parameters:
@@ -6981,14 +7016,14 @@
   // abstract class B extends A {}
   // ```
   static const CompileTimeErrorCode
-      NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_ONE =
-      CompileTimeErrorCodeWithUniqueName(
-          'NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER',
-          'NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_ONE',
-          "Missing concrete implementation of '{0}'.",
-          correction: "Try implementing the missing method, or make the class "
-              "abstract.",
-          hasPublishedDocs: true);
+      NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_ONE = CompileTimeErrorCode(
+    'NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER',
+    "Missing concrete implementation of '{0}'.",
+    correction: "Try implementing the missing method, or make the class "
+        "abstract.",
+    hasPublishedDocs: true,
+    uniqueName: 'NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_ONE',
+  );
 
   /**
    * Parameters:
@@ -6997,14 +7032,14 @@
    * 2: the name of the third member
    */
   static const CompileTimeErrorCode
-      NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_THREE =
-      CompileTimeErrorCodeWithUniqueName(
-          'NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER',
-          'NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_THREE',
-          "Missing concrete implementations of '{0}', '{1}', and '{2}'.",
-          correction: "Try implementing the missing methods, or make the class "
-              "abstract.",
-          hasPublishedDocs: true);
+      NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_THREE = CompileTimeErrorCode(
+    'NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER',
+    "Missing concrete implementations of '{0}', '{1}', and '{2}'.",
+    correction: "Try implementing the missing methods, or make the class "
+        "abstract.",
+    hasPublishedDocs: true,
+    uniqueName: 'NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_THREE',
+  );
 
   /**
    * Parameters:
@@ -7012,14 +7047,14 @@
    * 1: the name of the second member
    */
   static const CompileTimeErrorCode
-      NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_TWO =
-      CompileTimeErrorCodeWithUniqueName(
-          'NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER',
-          'NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_TWO',
-          "Missing concrete implementations of '{0}' and '{1}'.",
-          correction: "Try implementing the missing methods, or make the class "
-              "abstract.",
-          hasPublishedDocs: true);
+      NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_TWO = CompileTimeErrorCode(
+    'NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER',
+    "Missing concrete implementations of '{0}' and '{1}'.",
+    correction: "Try implementing the missing methods, or make the class "
+        "abstract.",
+    hasPublishedDocs: true,
+    uniqueName: 'NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_TWO',
+  );
 
   /**
    * No parameters.
@@ -8013,14 +8048,15 @@
    */
   static const CompileTimeErrorCode
       NOT_INITIALIZED_NON_NULLABLE_INSTANCE_FIELD_CONSTRUCTOR =
-      CompileTimeErrorCodeWithUniqueName(
-          'NOT_INITIALIZED_NON_NULLABLE_INSTANCE_FIELD',
-          'NOT_INITIALIZED_NON_NULLABLE_INSTANCE_FIELD_CONSTRUCTOR',
-          "Non-nullable instance field '{0}' must be initialized.",
-          correction: "Try adding an initializer expression, "
-              "or add a field initializer in this constructor, "
-              "or mark it 'late'.",
-          hasPublishedDocs: true);
+      CompileTimeErrorCode(
+    'NOT_INITIALIZED_NON_NULLABLE_INSTANCE_FIELD',
+    "Non-nullable instance field '{0}' must be initialized.",
+    correction: "Try adding an initializer expression, "
+        "or add a field initializer in this constructor, "
+        "or mark it 'late'.",
+    hasPublishedDocs: true,
+    uniqueName: 'NOT_INITIALIZED_NON_NULLABLE_INSTANCE_FIELD_CONSTRUCTOR',
+  );
 
   /**
    * Parameters:
@@ -9141,12 +9177,13 @@
    * 2: the name of the constructor
    */
   static const CompileTimeErrorCode RETURN_OF_INVALID_TYPE_FROM_CONSTRUCTOR =
-      CompileTimeErrorCodeWithUniqueName(
-          'RETURN_OF_INVALID_TYPE',
-          'RETURN_OF_INVALID_TYPE_FROM_CONSTRUCTOR',
-          "A value of type '{0}' can't be returned from constructor '{2}' "
-              "because it has a return type of '{1}'.",
-          hasPublishedDocs: true);
+      CompileTimeErrorCode(
+    'RETURN_OF_INVALID_TYPE',
+    "A value of type '{0}' can't be returned from constructor '{2}' "
+        "because it has a return type of '{1}'.",
+    hasPublishedDocs: true,
+    uniqueName: 'RETURN_OF_INVALID_TYPE_FROM_CONSTRUCTOR',
+  );
 
   /**
    * Parameters:
@@ -9183,12 +9220,13 @@
   // int f() => 3;
   // ```
   static const CompileTimeErrorCode RETURN_OF_INVALID_TYPE_FROM_FUNCTION =
-      CompileTimeErrorCodeWithUniqueName(
-          'RETURN_OF_INVALID_TYPE',
-          'RETURN_OF_INVALID_TYPE_FROM_FUNCTION',
-          "A value of type '{0}' can't be returned from function '{2}' because "
-              "it has a return type of '{1}'.",
-          hasPublishedDocs: true);
+      CompileTimeErrorCode(
+    'RETURN_OF_INVALID_TYPE',
+    "A value of type '{0}' can't be returned from function '{2}' because "
+        "it has a return type of '{1}'.",
+    hasPublishedDocs: true,
+    uniqueName: 'RETURN_OF_INVALID_TYPE_FROM_FUNCTION',
+  );
 
   /**
    * Parameters:
@@ -9197,12 +9235,13 @@
    * 2: the name of the method
    */
   static const CompileTimeErrorCode RETURN_OF_INVALID_TYPE_FROM_METHOD =
-      CompileTimeErrorCodeWithUniqueName(
-          'RETURN_OF_INVALID_TYPE',
-          'RETURN_OF_INVALID_TYPE_FROM_METHOD',
-          "A value of type '{0}' can't be returned from method '{2}' because "
-              "it has a return type of '{1}'.",
-          hasPublishedDocs: true);
+      CompileTimeErrorCode(
+    'RETURN_OF_INVALID_TYPE',
+    "A value of type '{0}' can't be returned from method '{2}' because "
+        "it has a return type of '{1}'.",
+    hasPublishedDocs: true,
+    uniqueName: 'RETURN_OF_INVALID_TYPE_FROM_METHOD',
+  );
 
   /**
    * No parameters.
@@ -9911,13 +9950,13 @@
    * 0: the name of the superclass that does not define the invoked constructor
    */
   static const CompileTimeErrorCode
-      UNDEFINED_CONSTRUCTOR_IN_INITIALIZER_DEFAULT =
-      CompileTimeErrorCodeWithUniqueName(
-          'UNDEFINED_CONSTRUCTOR_IN_INITIALIZER',
-          'UNDEFINED_CONSTRUCTOR_IN_INITIALIZER_DEFAULT',
-          "The class '{0}' doesn't have an unnamed constructor.",
-          correction: "Try defining an unnamed constructor in '{0}', or "
-              "invoking a different constructor.");
+      UNDEFINED_CONSTRUCTOR_IN_INITIALIZER_DEFAULT = CompileTimeErrorCode(
+    'UNDEFINED_CONSTRUCTOR_IN_INITIALIZER',
+    "The class '{0}' doesn't have an unnamed constructor.",
+    correction: "Try defining an unnamed constructor in '{0}', or "
+        "invoking a different constructor.",
+    uniqueName: 'UNDEFINED_CONSTRUCTOR_IN_INITIALIZER_DEFAULT',
+  );
 
   /**
    * Parameters:
@@ -10684,14 +10723,14 @@
    * 1: the name of the enclosing type where the getter is being looked for
    */
   static const CompileTimeErrorCode UNDEFINED_SUPER_GETTER =
-      CompileTimeErrorCodeWithUniqueName(
-          'UNDEFINED_SUPER_MEMBER',
-          'UNDEFINED_SUPER_GETTER',
-          "The getter '{0}' isn't defined in a superclass of '{1}'.",
-          correction:
-              "Try correcting the name to the name of an existing getter, or "
-              "defining a getter or field named '{0}' in a superclass.",
-          hasPublishedDocs: true);
+      CompileTimeErrorCode(
+    'UNDEFINED_SUPER_MEMBER',
+    "The getter '{0}' isn't defined in a superclass of '{1}'.",
+    correction: "Try correcting the name to the name of an existing getter, or "
+        "defining a getter or field named '{0}' in a superclass.",
+    hasPublishedDocs: true,
+    uniqueName: 'UNDEFINED_SUPER_GETTER',
+  );
 
   /**
    * Parameters:
@@ -10739,14 +10778,14 @@
   // If the member isn’t defined, then either add the member to one of the
   // superclasses or remove the invocation.
   static const CompileTimeErrorCode UNDEFINED_SUPER_METHOD =
-      CompileTimeErrorCodeWithUniqueName(
-          'UNDEFINED_SUPER_MEMBER',
-          'UNDEFINED_SUPER_METHOD',
-          "The method '{0}' isn't defined in a superclass of '{1}'.",
-          correction:
-              "Try correcting the name to the name of an existing method, or "
-              "defining a method named '{0}' in a superclass.",
-          hasPublishedDocs: true);
+      CompileTimeErrorCode(
+    'UNDEFINED_SUPER_MEMBER',
+    "The method '{0}' isn't defined in a superclass of '{1}'.",
+    correction: "Try correcting the name to the name of an existing method, or "
+        "defining a method named '{0}' in a superclass.",
+    hasPublishedDocs: true,
+    uniqueName: 'UNDEFINED_SUPER_METHOD',
+  );
 
   /**
    * Parameters:
@@ -10754,12 +10793,13 @@
    * 1: the name of the enclosing type where the operator is being looked for
    */
   static const CompileTimeErrorCode UNDEFINED_SUPER_OPERATOR =
-      CompileTimeErrorCodeWithUniqueName(
-          'UNDEFINED_SUPER_MEMBER',
-          'UNDEFINED_SUPER_OPERATOR',
-          "The operator '{0}' isn't defined in a superclass of '{1}'.",
-          correction: "Try defining the operator '{0}' in a superclass.",
-          hasPublishedDocs: true);
+      CompileTimeErrorCode(
+    'UNDEFINED_SUPER_MEMBER',
+    "The operator '{0}' isn't defined in a superclass of '{1}'.",
+    correction: "Try defining the operator '{0}' in a superclass.",
+    hasPublishedDocs: true,
+    uniqueName: 'UNDEFINED_SUPER_OPERATOR',
+  );
 
   /**
    * Parameters:
@@ -10767,14 +10807,14 @@
    * 1: the name of the enclosing type where the setter is being looked for
    */
   static const CompileTimeErrorCode UNDEFINED_SUPER_SETTER =
-      CompileTimeErrorCodeWithUniqueName(
-          'UNDEFINED_SUPER_MEMBER',
-          'UNDEFINED_SUPER_SETTER',
-          "The setter '{0}' isn't defined in a superclass of '{1}'.",
-          correction:
-              "Try correcting the name to the name of an existing setter, or "
-              "defining a setter or field named '{0}' in a superclass.",
-          hasPublishedDocs: true);
+      CompileTimeErrorCode(
+    'UNDEFINED_SUPER_MEMBER',
+    "The setter '{0}' isn't defined in a superclass of '{1}'.",
+    correction: "Try correcting the name to the name of an existing setter, or "
+        "defining a setter or field named '{0}' in a superclass.",
+    hasPublishedDocs: true,
+    uniqueName: 'UNDEFINED_SUPER_SETTER',
+  );
 
   /**
    * 12.15.1 Ordinary Invocation: It is a static type warning if <i>T</i> does
@@ -11391,14 +11431,21 @@
    * template. The correction associated with the error will be created from the
    * given [correction] template.
    */
-  const CompileTimeErrorCode(String name, String message,
-      {String correction,
-      bool hasPublishedDocs,
-      bool isUnresolvedIdentifier = false})
-      : super.temporary(name, message,
-            correction: correction,
-            hasPublishedDocs: hasPublishedDocs,
-            isUnresolvedIdentifier: isUnresolvedIdentifier);
+  const CompileTimeErrorCode(
+    String name,
+    String message, {
+    String correction,
+    bool hasPublishedDocs = false,
+    bool isUnresolvedIdentifier = false,
+    String uniqueName,
+  }) : super(
+          correction: correction,
+          hasPublishedDocs: hasPublishedDocs,
+          isUnresolvedIdentifier: isUnresolvedIdentifier,
+          message: message,
+          name: name,
+          uniqueName: uniqueName ?? 'CompileTimeErrorCode.$name',
+        );
 
   @override
   ErrorSeverity get errorSeverity => ErrorType.COMPILE_TIME_ERROR.severity;
@@ -11407,21 +11454,6 @@
   ErrorType get type => ErrorType.COMPILE_TIME_ERROR;
 }
 
-class CompileTimeErrorCodeWithUniqueName extends CompileTimeErrorCode {
-  @override
-  final String uniqueName;
-
-  const CompileTimeErrorCodeWithUniqueName(
-      String name, this.uniqueName, String message,
-      {String correction,
-      bool hasPublishedDocs,
-      bool isUnresolvedIdentifier = false})
-      : super(name, message,
-            correction: correction,
-            hasPublishedDocs: hasPublishedDocs,
-            isUnresolvedIdentifier: isUnresolvedIdentifier);
-}
-
 /**
  * This class has experimental Language-specific codes.
  *
@@ -11495,10 +11527,14 @@
    * created from the optional [correction] template.
    */
   const LanguageCode(String name, String message,
-      {String correction, bool hasPublishedDocs})
-      : super.temporary(name, message,
-            correction: correction,
-            hasPublishedDocs: hasPublishedDocs ?? false);
+      {String correction, bool hasPublishedDocs = false})
+      : super(
+          correction: correction,
+          hasPublishedDocs: hasPublishedDocs,
+          message: message,
+          name: name,
+          uniqueName: 'LanguageCode.$name',
+        );
 
   @override
   ErrorSeverity get errorSeverity => type.severity;
@@ -11666,14 +11702,14 @@
    * 1: The non-null-aware operator that can replace the invalid operator
    */
   static const StaticWarningCode
-      INVALID_NULL_AWARE_OPERATOR_AFTER_SHORT_CIRCUIT =
-      StaticWarningCodeWithUniqueName(
-          'INVALID_NULL_AWARE_OPERATOR',
-          'INVALID_NULL_AWARE_OPERATOR_AFTER_SHORT_CIRCUIT',
-          "The receiver can't be null because of short-circuiting, so the "
-              "null-aware operator '{0}' can't be used.",
-          correction: "Try replacing the operator '{0}' with '{1}'.",
-          hasPublishedDocs: true);
+      INVALID_NULL_AWARE_OPERATOR_AFTER_SHORT_CIRCUIT = StaticWarningCode(
+    'INVALID_NULL_AWARE_OPERATOR',
+    "The receiver can't be null because of short-circuiting, so the "
+        "null-aware operator '{0}' can't be used.",
+    correction: "Try replacing the operator '{0}' with '{1}'.",
+    hasPublishedDocs: true,
+    uniqueName: 'INVALID_NULL_AWARE_OPERATOR_AFTER_SHORT_CIRCUIT',
+  );
 
   /**
    * 7.1 Instance Methods: It is a static warning if an instance method
@@ -11812,14 +11848,21 @@
    * template. The correction associated with the error will be created from the
    * given [correction] template.
    */
-  const StaticWarningCode(String name, String message,
-      {String correction,
-      bool hasPublishedDocs,
-      bool isUnresolvedIdentifier = false})
-      : super.temporary(name, message,
-            correction: correction,
-            hasPublishedDocs: hasPublishedDocs,
-            isUnresolvedIdentifier: isUnresolvedIdentifier);
+  const StaticWarningCode(
+    String name,
+    String message, {
+    String correction,
+    bool hasPublishedDocs = false,
+    bool isUnresolvedIdentifier = false,
+    String uniqueName,
+  }) : super(
+          correction: correction,
+          hasPublishedDocs: hasPublishedDocs,
+          isUnresolvedIdentifier: isUnresolvedIdentifier,
+          message: message,
+          name: name,
+          uniqueName: uniqueName ?? 'StaticWarningCode.$name',
+        );
 
   @override
   ErrorSeverity get errorSeverity => ErrorSeverity.WARNING;
@@ -11828,21 +11871,6 @@
   ErrorType get type => ErrorType.STATIC_WARNING;
 }
 
-class StaticWarningCodeWithUniqueName extends StaticWarningCode {
-  @override
-  final String uniqueName;
-
-  const StaticWarningCodeWithUniqueName(
-      String name, this.uniqueName, String message,
-      {String correction,
-      bool hasPublishedDocs,
-      bool isUnresolvedIdentifier = false})
-      : super(name, message,
-            correction: correction,
-            hasPublishedDocs: hasPublishedDocs,
-            isUnresolvedIdentifier: isUnresolvedIdentifier);
-}
-
 /**
  * This class has Strong Mode specific error codes.
  *
@@ -11903,11 +11931,15 @@
    * created from the optional [correction] template.
    */
   const StrongModeCode(ErrorType type, String name, String message,
-      {String correction, bool hasPublishedDocs})
+      {String correction, bool hasPublishedDocs = false})
       : type = type,
-        super.temporary(name, message,
-            correction: correction,
-            hasPublishedDocs: hasPublishedDocs ?? false);
+        super(
+          correction: correction,
+          hasPublishedDocs: hasPublishedDocs,
+          message: message,
+          name: name,
+          uniqueName: 'StrongModeCode.$name',
+        );
 
   @override
   ErrorSeverity get errorSeverity => type.severity;
diff --git a/pkg/analyzer/lib/src/error/duplicate_definition_verifier.dart b/pkg/analyzer/lib/src/error/duplicate_definition_verifier.dart
index e90e5de..0b5e1f1 100644
--- a/pkg/analyzer/lib/src/error/duplicate_definition_verifier.dart
+++ b/pkg/analyzer/lib/src/error/duplicate_definition_verifier.dart
@@ -367,7 +367,10 @@
     }
 
     ErrorCode getError(Element previous, Element current) {
-      if (previous is PrefixElement) {
+      if (previous is FieldFormalParameterElement &&
+          current is FieldFormalParameterElement) {
+        return CompileTimeErrorCode.DUPLICATE_FIELD_FORMAL_PARAMETER;
+      } else if (previous is PrefixElement) {
         return CompileTimeErrorCode.PREFIX_COLLIDES_WITH_TOP_LEVEL_MEMBER;
       }
       return CompileTimeErrorCode.DUPLICATE_DEFINITION;
@@ -383,7 +386,9 @@
       if (_isGetterSetterPair(element, previous)) {
         // OK
       } else if (element is FieldFormalParameterElement &&
-          previous is FieldFormalParameterElement) {
+          previous is FieldFormalParameterElement &&
+          element.field != null &&
+          element.field.isFinal) {
         // Reported as CompileTimeErrorCode.FINAL_INITIALIZED_MULTIPLE_TIMES.
       } else {
         _errorReporter.reportErrorForNode(
diff --git a/pkg/analyzer/lib/src/error/inheritance_override.dart b/pkg/analyzer/lib/src/error/inheritance_override.dart
index 159b36d..d3d43e6 100644
--- a/pkg/analyzer/lib/src/error/inheritance_override.dart
+++ b/pkg/analyzer/lib/src/error/inheritance_override.dart
@@ -17,7 +17,7 @@
 import 'package:analyzer/src/error/codes.dart';
 import 'package:analyzer/src/error/correct_override.dart';
 import 'package:analyzer/src/error/getter_setter_types_verifier.dart';
-import 'package:analyzer/src/summary/idl.dart';
+import 'package:analyzer/src/task/inference_error.dart';
 import 'package:meta/meta.dart';
 
 class InheritanceOverrideVerifier {
diff --git a/pkg/analyzer/lib/src/manifest/manifest_warning_code.dart b/pkg/analyzer/lib/src/manifest/manifest_warning_code.dart
index f4d5b8f..1d2955b 100644
--- a/pkg/analyzer/lib/src/manifest/manifest_warning_code.dart
+++ b/pkg/analyzer/lib/src/manifest/manifest_warning_code.dart
@@ -81,7 +81,12 @@
   /// Initialize a newly created warning code to have the given [name],
   /// [message] and [correction].
   const ManifestWarningCode(String name, String message, {String correction})
-      : super.temporary(name, message, correction: correction);
+      : super(
+          correction: correction,
+          message: message,
+          name: name,
+          uniqueName: 'ManifestWarningCode.$name',
+        );
 
   @override
   ErrorSeverity get errorSeverity => ErrorSeverity.WARNING;
diff --git a/pkg/analyzer/lib/src/pubspec/pubspec_validator.dart b/pkg/analyzer/lib/src/pubspec/pubspec_validator.dart
index fd22ea0..b47fb44 100644
--- a/pkg/analyzer/lib/src/pubspec/pubspec_validator.dart
+++ b/pkg/analyzer/lib/src/pubspec/pubspec_validator.dart
@@ -249,6 +249,12 @@
       if (pathEntry != null) {
         YamlNode pathKey() => getKey(dependency, PATH_FIELD);
         YamlNode pathValue() => getValue(dependency, PATH_FIELD);
+
+        if (pathEntry.contains(r'\')) {
+          _reportErrorForNode(reporter, pathValue(),
+              PubspecWarningCode.PATH_NOT_POSIX, [pathEntry]);
+          return;
+        }
         var context = provider.pathContext;
         var normalizedPath = context.joinAll(path.posix.split(pathEntry));
         var packageRoot = context.dirname(source.fullName);
diff --git a/pkg/analyzer/lib/src/pubspec/pubspec_warning_code.dart b/pkg/analyzer/lib/src/pubspec/pubspec_warning_code.dart
index a93cca0..9fb2b1c 100644
--- a/pkg/analyzer/lib/src/pubspec/pubspec_warning_code.dart
+++ b/pkg/analyzer/lib/src/pubspec/pubspec_warning_code.dart
@@ -83,6 +83,14 @@
       correction:
           "Try creating the referenced path or using a path that exists.");
 
+  /// A code indicating that a path value is not is not posix-style.
+  ///
+  /// Parameters:
+  /// 0: the path as given in the file.
+  static const PubspecWarningCode PATH_NOT_POSIX = PubspecWarningCode(
+      'PATH_NOT_POSIX', "The path {0} is not posix.",
+      correction: "Try converting the value to a posix-style path.");
+
   /// A code indicating that a specified path dependency points to a directory
   /// that does not contain a pubspec.
   ///
@@ -109,7 +117,12 @@
   /// Initialize a newly created warning code to have the given [name],
   /// [message] and [correction].
   const PubspecWarningCode(String name, String message, {String correction})
-      : super.temporary(name, message, correction: correction);
+      : super(
+          correction: correction,
+          message: message,
+          name: name,
+          uniqueName: 'PubspecWarningCode.$name',
+        );
 
   @override
   ErrorSeverity get errorSeverity => ErrorSeverity.WARNING;
diff --git a/pkg/analyzer/lib/src/summary/format.dart b/pkg/analyzer/lib/src/summary/format.dart
index cddf91d..aa37cf6 100644
--- a/pkg/analyzer/lib/src/summary/format.dart
+++ b/pkg/analyzer/lib/src/summary/format.dart
@@ -35,22 +35,6 @@
   }
 }
 
-class _EntityRefNullabilitySuffixReader
-    extends fb.Reader<idl.EntityRefNullabilitySuffix> {
-  const _EntityRefNullabilitySuffixReader() : super();
-
-  @override
-  int get size => 1;
-
-  @override
-  idl.EntityRefNullabilitySuffix read(fb.BufferContext bc, int offset) {
-    int index = const fb.Uint8Reader().read(bc, offset);
-    return index < idl.EntityRefNullabilitySuffix.values.length
-        ? idl.EntityRefNullabilitySuffix.values[index]
-        : idl.EntityRefNullabilitySuffix.starOrIrrelevant;
-  }
-}
-
 class _IndexRelationKindReader extends fb.Reader<idl.IndexRelationKind> {
   const _IndexRelationKindReader() : super();
 
@@ -82,99 +66,6 @@
   }
 }
 
-class _LinkedNodeCommentTypeReader
-    extends fb.Reader<idl.LinkedNodeCommentType> {
-  const _LinkedNodeCommentTypeReader() : super();
-
-  @override
-  int get size => 1;
-
-  @override
-  idl.LinkedNodeCommentType read(fb.BufferContext bc, int offset) {
-    int index = const fb.Uint8Reader().read(bc, offset);
-    return index < idl.LinkedNodeCommentType.values.length
-        ? idl.LinkedNodeCommentType.values[index]
-        : idl.LinkedNodeCommentType.block;
-  }
-}
-
-class _LinkedNodeFormalParameterKindReader
-    extends fb.Reader<idl.LinkedNodeFormalParameterKind> {
-  const _LinkedNodeFormalParameterKindReader() : super();
-
-  @override
-  int get size => 1;
-
-  @override
-  idl.LinkedNodeFormalParameterKind read(fb.BufferContext bc, int offset) {
-    int index = const fb.Uint8Reader().read(bc, offset);
-    return index < idl.LinkedNodeFormalParameterKind.values.length
-        ? idl.LinkedNodeFormalParameterKind.values[index]
-        : idl.LinkedNodeFormalParameterKind.requiredPositional;
-  }
-}
-
-class _LinkedNodeKindReader extends fb.Reader<idl.LinkedNodeKind> {
-  const _LinkedNodeKindReader() : super();
-
-  @override
-  int get size => 1;
-
-  @override
-  idl.LinkedNodeKind read(fb.BufferContext bc, int offset) {
-    int index = const fb.Uint8Reader().read(bc, offset);
-    return index < idl.LinkedNodeKind.values.length
-        ? idl.LinkedNodeKind.values[index]
-        : idl.LinkedNodeKind.adjacentStrings;
-  }
-}
-
-class _LinkedNodeTypeKindReader extends fb.Reader<idl.LinkedNodeTypeKind> {
-  const _LinkedNodeTypeKindReader() : super();
-
-  @override
-  int get size => 1;
-
-  @override
-  idl.LinkedNodeTypeKind read(fb.BufferContext bc, int offset) {
-    int index = const fb.Uint8Reader().read(bc, offset);
-    return index < idl.LinkedNodeTypeKind.values.length
-        ? idl.LinkedNodeTypeKind.values[index]
-        : idl.LinkedNodeTypeKind.dynamic_;
-  }
-}
-
-class _TopLevelInferenceErrorKindReader
-    extends fb.Reader<idl.TopLevelInferenceErrorKind> {
-  const _TopLevelInferenceErrorKindReader() : super();
-
-  @override
-  int get size => 1;
-
-  @override
-  idl.TopLevelInferenceErrorKind read(fb.BufferContext bc, int offset) {
-    int index = const fb.Uint8Reader().read(bc, offset);
-    return index < idl.TopLevelInferenceErrorKind.values.length
-        ? idl.TopLevelInferenceErrorKind.values[index]
-        : idl.TopLevelInferenceErrorKind.assignment;
-  }
-}
-
-class _UnlinkedTokenTypeReader extends fb.Reader<idl.UnlinkedTokenType> {
-  const _UnlinkedTokenTypeReader() : super();
-
-  @override
-  int get size => 1;
-
-  @override
-  idl.UnlinkedTokenType read(fb.BufferContext bc, int offset) {
-    int index = const fb.Uint8Reader().read(bc, offset);
-    return index < idl.UnlinkedTokenType.values.length
-        ? idl.UnlinkedTokenType.values[index]
-        : idl.UnlinkedTokenType.NOTHING;
-  }
-}
-
 class AnalysisDriverExceptionContextBuilder extends Object
     with _AnalysisDriverExceptionContextMixin
     implements idl.AnalysisDriverExceptionContext {
@@ -3511,143 +3402,6 @@
   String toString() => convert.json.encode(toJson());
 }
 
-class CiderLinkedLibraryCycleBuilder extends Object
-    with _CiderLinkedLibraryCycleMixin
-    implements idl.CiderLinkedLibraryCycle {
-  LinkedNodeBundleBuilder _bundle;
-  List<int> _signature;
-
-  @override
-  LinkedNodeBundleBuilder get bundle => _bundle;
-
-  set bundle(LinkedNodeBundleBuilder value) {
-    this._bundle = value;
-  }
-
-  @override
-  List<int> get signature => _signature ??= <int>[];
-
-  /// The hash signature for this linked cycle. It depends of API signatures
-  /// of all files in the cycle, and on the signatures of the transitive
-  /// closure of the cycle dependencies.
-  set signature(List<int> value) {
-    assert(value == null || value.every((e) => e >= 0));
-    this._signature = value;
-  }
-
-  CiderLinkedLibraryCycleBuilder(
-      {LinkedNodeBundleBuilder bundle, List<int> signature})
-      : _bundle = bundle,
-        _signature = signature;
-
-  /// Flush [informative] data recursively.
-  void flushInformative() {
-    _bundle?.flushInformative();
-  }
-
-  /// Accumulate non-[informative] data into [signature].
-  void collectApiSignature(api_sig.ApiSignature signature) {
-    if (this._signature == null) {
-      signature.addInt(0);
-    } else {
-      signature.addInt(this._signature.length);
-      for (var x in this._signature) {
-        signature.addInt(x);
-      }
-    }
-    signature.addBool(this._bundle != null);
-    this._bundle?.collectApiSignature(signature);
-  }
-
-  List<int> toBuffer() {
-    fb.Builder fbBuilder = fb.Builder();
-    return fbBuilder.finish(finish(fbBuilder), "CLNB");
-  }
-
-  fb.Offset finish(fb.Builder fbBuilder) {
-    fb.Offset offset_bundle;
-    fb.Offset offset_signature;
-    if (_bundle != null) {
-      offset_bundle = _bundle.finish(fbBuilder);
-    }
-    if (!(_signature == null || _signature.isEmpty)) {
-      offset_signature = fbBuilder.writeListUint32(_signature);
-    }
-    fbBuilder.startTable();
-    if (offset_bundle != null) {
-      fbBuilder.addOffset(1, offset_bundle);
-    }
-    if (offset_signature != null) {
-      fbBuilder.addOffset(0, offset_signature);
-    }
-    return fbBuilder.endTable();
-  }
-}
-
-idl.CiderLinkedLibraryCycle readCiderLinkedLibraryCycle(List<int> buffer) {
-  fb.BufferContext rootRef = fb.BufferContext.fromBytes(buffer);
-  return const _CiderLinkedLibraryCycleReader().read(rootRef, 0);
-}
-
-class _CiderLinkedLibraryCycleReader
-    extends fb.TableReader<_CiderLinkedLibraryCycleImpl> {
-  const _CiderLinkedLibraryCycleReader();
-
-  @override
-  _CiderLinkedLibraryCycleImpl createObject(fb.BufferContext bc, int offset) =>
-      _CiderLinkedLibraryCycleImpl(bc, offset);
-}
-
-class _CiderLinkedLibraryCycleImpl extends Object
-    with _CiderLinkedLibraryCycleMixin
-    implements idl.CiderLinkedLibraryCycle {
-  final fb.BufferContext _bc;
-  final int _bcOffset;
-
-  _CiderLinkedLibraryCycleImpl(this._bc, this._bcOffset);
-
-  idl.LinkedNodeBundle _bundle;
-  List<int> _signature;
-
-  @override
-  idl.LinkedNodeBundle get bundle {
-    _bundle ??=
-        const _LinkedNodeBundleReader().vTableGet(_bc, _bcOffset, 1, null);
-    return _bundle;
-  }
-
-  @override
-  List<int> get signature {
-    _signature ??=
-        const fb.Uint32ListReader().vTableGet(_bc, _bcOffset, 0, const <int>[]);
-    return _signature;
-  }
-}
-
-abstract class _CiderLinkedLibraryCycleMixin
-    implements idl.CiderLinkedLibraryCycle {
-  @override
-  Map<String, Object> toJson() {
-    Map<String, Object> _result = <String, Object>{};
-    if (bundle != null) {
-      _result["bundle"] = bundle.toJson();
-    }
-    if (signature.isNotEmpty) {
-      _result["signature"] = signature;
-    }
-    return _result;
-  }
-
-  @override
-  Map<String, Object> toMap() => {
-        "bundle": bundle,
-        "signature": signature,
-      };
-
-  @override
-  String toString() => convert.json.encode(toJson());
-}
-
 class CiderUnitErrorsBuilder extends Object
     with _CiderUnitErrorsMixin
     implements idl.CiderUnitErrors {
@@ -4217,13505 +3971,28 @@
   String toString() => convert.json.encode(toJson());
 }
 
-class LinkedLanguageVersionBuilder extends Object
-    with _LinkedLanguageVersionMixin
-    implements idl.LinkedLanguageVersion {
-  int _major;
-  int _minor;
-
-  @override
-  int get major => _major ??= 0;
-
-  set major(int value) {
-    assert(value == null || value >= 0);
-    this._major = value;
-  }
-
-  @override
-  int get minor => _minor ??= 0;
-
-  set minor(int value) {
-    assert(value == null || value >= 0);
-    this._minor = value;
-  }
-
-  LinkedLanguageVersionBuilder({int major, int minor})
-      : _major = major,
-        _minor = minor;
-
-  /// Flush [informative] data recursively.
-  void flushInformative() {}
-
-  /// Accumulate non-[informative] data into [signature].
-  void collectApiSignature(api_sig.ApiSignature signature) {
-    signature.addInt(this._major ?? 0);
-    signature.addInt(this._minor ?? 0);
-  }
-
-  fb.Offset finish(fb.Builder fbBuilder) {
-    fbBuilder.startTable();
-    if (_major != null && _major != 0) {
-      fbBuilder.addUint32(0, _major);
-    }
-    if (_minor != null && _minor != 0) {
-      fbBuilder.addUint32(1, _minor);
-    }
-    return fbBuilder.endTable();
-  }
-}
-
-class _LinkedLanguageVersionReader
-    extends fb.TableReader<_LinkedLanguageVersionImpl> {
-  const _LinkedLanguageVersionReader();
-
-  @override
-  _LinkedLanguageVersionImpl createObject(fb.BufferContext bc, int offset) =>
-      _LinkedLanguageVersionImpl(bc, offset);
-}
-
-class _LinkedLanguageVersionImpl extends Object
-    with _LinkedLanguageVersionMixin
-    implements idl.LinkedLanguageVersion {
-  final fb.BufferContext _bc;
-  final int _bcOffset;
-
-  _LinkedLanguageVersionImpl(this._bc, this._bcOffset);
-
-  int _major;
-  int _minor;
-
-  @override
-  int get major {
-    _major ??= const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 0, 0);
-    return _major;
-  }
-
-  @override
-  int get minor {
-    _minor ??= const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 1, 0);
-    return _minor;
-  }
-}
-
-abstract class _LinkedLanguageVersionMixin
-    implements idl.LinkedLanguageVersion {
-  @override
-  Map<String, Object> toJson() {
-    Map<String, Object> _result = <String, Object>{};
-    if (major != 0) {
-      _result["major"] = major;
-    }
-    if (minor != 0) {
-      _result["minor"] = minor;
-    }
-    return _result;
-  }
-
-  @override
-  Map<String, Object> toMap() => {
-        "major": major,
-        "minor": minor,
-      };
-
-  @override
-  String toString() => convert.json.encode(toJson());
-}
-
-class LinkedLibraryLanguageVersionBuilder extends Object
-    with _LinkedLibraryLanguageVersionMixin
-    implements idl.LinkedLibraryLanguageVersion {
-  LinkedLanguageVersionBuilder _override2;
-  LinkedLanguageVersionBuilder _package;
-
-  @override
-  LinkedLanguageVersionBuilder get override2 => _override2;
-
-  set override2(LinkedLanguageVersionBuilder value) {
-    this._override2 = value;
-  }
-
-  @override
-  LinkedLanguageVersionBuilder get package => _package;
-
-  set package(LinkedLanguageVersionBuilder value) {
-    this._package = value;
-  }
-
-  LinkedLibraryLanguageVersionBuilder(
-      {LinkedLanguageVersionBuilder override2,
-      LinkedLanguageVersionBuilder package})
-      : _override2 = override2,
-        _package = package;
-
-  /// Flush [informative] data recursively.
-  void flushInformative() {
-    _override2?.flushInformative();
-    _package?.flushInformative();
-  }
-
-  /// Accumulate non-[informative] data into [signature].
-  void collectApiSignature(api_sig.ApiSignature signature) {
-    signature.addBool(this._package != null);
-    this._package?.collectApiSignature(signature);
-    signature.addBool(this._override2 != null);
-    this._override2?.collectApiSignature(signature);
-  }
-
-  fb.Offset finish(fb.Builder fbBuilder) {
-    fb.Offset offset_override2;
-    fb.Offset offset_package;
-    if (_override2 != null) {
-      offset_override2 = _override2.finish(fbBuilder);
-    }
-    if (_package != null) {
-      offset_package = _package.finish(fbBuilder);
-    }
-    fbBuilder.startTable();
-    if (offset_override2 != null) {
-      fbBuilder.addOffset(1, offset_override2);
-    }
-    if (offset_package != null) {
-      fbBuilder.addOffset(0, offset_package);
-    }
-    return fbBuilder.endTable();
-  }
-}
-
-class _LinkedLibraryLanguageVersionReader
-    extends fb.TableReader<_LinkedLibraryLanguageVersionImpl> {
-  const _LinkedLibraryLanguageVersionReader();
-
-  @override
-  _LinkedLibraryLanguageVersionImpl createObject(
-          fb.BufferContext bc, int offset) =>
-      _LinkedLibraryLanguageVersionImpl(bc, offset);
-}
-
-class _LinkedLibraryLanguageVersionImpl extends Object
-    with _LinkedLibraryLanguageVersionMixin
-    implements idl.LinkedLibraryLanguageVersion {
-  final fb.BufferContext _bc;
-  final int _bcOffset;
-
-  _LinkedLibraryLanguageVersionImpl(this._bc, this._bcOffset);
-
-  idl.LinkedLanguageVersion _override2;
-  idl.LinkedLanguageVersion _package;
-
-  @override
-  idl.LinkedLanguageVersion get override2 {
-    _override2 ??=
-        const _LinkedLanguageVersionReader().vTableGet(_bc, _bcOffset, 1, null);
-    return _override2;
-  }
-
-  @override
-  idl.LinkedLanguageVersion get package {
-    _package ??=
-        const _LinkedLanguageVersionReader().vTableGet(_bc, _bcOffset, 0, null);
-    return _package;
-  }
-}
-
-abstract class _LinkedLibraryLanguageVersionMixin
-    implements idl.LinkedLibraryLanguageVersion {
-  @override
-  Map<String, Object> toJson() {
-    Map<String, Object> _result = <String, Object>{};
-    if (override2 != null) {
-      _result["override2"] = override2.toJson();
-    }
-    if (package != null) {
-      _result["package"] = package.toJson();
-    }
-    return _result;
-  }
-
-  @override
-  Map<String, Object> toMap() => {
-        "override2": override2,
-        "package": package,
-      };
-
-  @override
-  String toString() => convert.json.encode(toJson());
-}
-
-class LinkedNodeBuilder extends Object
-    with _LinkedNodeMixin
-    implements idl.LinkedNode {
-  LinkedNodeTypeBuilder _variantField_24;
-  List<LinkedNodeBuilder> _variantField_2;
-  List<LinkedNodeBuilder> _variantField_4;
-  LinkedNodeBuilder _variantField_6;
-  LinkedNodeBuilder _variantField_7;
-  int _variantField_17;
-  LinkedNodeBuilder _variantField_8;
-  LinkedNodeTypeSubstitutionBuilder _variantField_38;
-  int _variantField_15;
-  idl.UnlinkedTokenType _variantField_28;
-  bool _variantField_27;
-  LinkedNodeBuilder _variantField_9;
-  LinkedNodeBuilder _variantField_12;
-  List<LinkedNodeBuilder> _variantField_5;
-  LinkedNodeBuilder _variantField_13;
-  List<String> _variantField_33;
-  idl.LinkedNodeCommentType _variantField_29;
-  List<LinkedNodeBuilder> _variantField_3;
-  List<int> _variantField_41;
-  LinkedLibraryLanguageVersionBuilder _variantField_40;
-  LinkedNodeBuilder _variantField_10;
-  idl.LinkedNodeFormalParameterKind _variantField_26;
-  double _variantField_21;
-  LinkedNodeTypeBuilder _variantField_25;
-  String _variantField_20;
-  List<LinkedNodeTypeBuilder> _variantField_39;
-  int _flags;
-  String _variantField_1;
-  int _variantField_36;
-  int _variantField_16;
-  String _variantField_30;
-  LinkedNodeBuilder _variantField_14;
-  idl.LinkedNodeKind _kind;
-  bool _variantField_31;
-  List<String> _variantField_34;
-  String _name;
-  idl.UnlinkedTokenType _variantField_35;
-  TopLevelInferenceErrorBuilder _variantField_32;
-  LinkedNodeTypeBuilder _variantField_23;
-  LinkedNodeBuilder _variantField_11;
-  String _variantField_22;
-  int _variantField_19;
-
-  @override
-  LinkedNodeTypeBuilder get actualReturnType {
-    assert(kind == idl.LinkedNodeKind.functionDeclaration ||
-        kind == idl.LinkedNodeKind.functionExpression ||
-        kind == idl.LinkedNodeKind.functionTypeAlias ||
-        kind == idl.LinkedNodeKind.genericFunctionType ||
-        kind == idl.LinkedNodeKind.methodDeclaration);
-    return _variantField_24;
-  }
-
-  @override
-  LinkedNodeTypeBuilder get actualType {
-    assert(kind == idl.LinkedNodeKind.fieldFormalParameter ||
-        kind == idl.LinkedNodeKind.functionTypedFormalParameter ||
-        kind == idl.LinkedNodeKind.simpleFormalParameter ||
-        kind == idl.LinkedNodeKind.variableDeclaration);
-    return _variantField_24;
-  }
-
-  @override
-  LinkedNodeTypeBuilder get binaryExpression_invokeType {
-    assert(kind == idl.LinkedNodeKind.binaryExpression);
-    return _variantField_24;
-  }
-
-  @override
-  LinkedNodeTypeBuilder get extensionOverride_extendedType {
-    assert(kind == idl.LinkedNodeKind.extensionOverride);
-    return _variantField_24;
-  }
-
-  @override
-  LinkedNodeTypeBuilder get invocationExpression_invokeType {
-    assert(kind == idl.LinkedNodeKind.functionExpressionInvocation ||
-        kind == idl.LinkedNodeKind.methodInvocation);
-    return _variantField_24;
-  }
-
-  /// The explicit or inferred return type of a function typed node.
-  set actualReturnType(LinkedNodeTypeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.functionDeclaration ||
-        kind == idl.LinkedNodeKind.functionExpression ||
-        kind == idl.LinkedNodeKind.functionTypeAlias ||
-        kind == idl.LinkedNodeKind.genericFunctionType ||
-        kind == idl.LinkedNodeKind.methodDeclaration);
-    _variantField_24 = value;
-  }
-
-  set actualType(LinkedNodeTypeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.fieldFormalParameter ||
-        kind == idl.LinkedNodeKind.functionTypedFormalParameter ||
-        kind == idl.LinkedNodeKind.simpleFormalParameter ||
-        kind == idl.LinkedNodeKind.variableDeclaration);
-    _variantField_24 = value;
-  }
-
-  set binaryExpression_invokeType(LinkedNodeTypeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.binaryExpression);
-    _variantField_24 = value;
-  }
-
-  set extensionOverride_extendedType(LinkedNodeTypeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.extensionOverride);
-    _variantField_24 = value;
-  }
-
-  set invocationExpression_invokeType(LinkedNodeTypeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.functionExpressionInvocation ||
-        kind == idl.LinkedNodeKind.methodInvocation);
-    _variantField_24 = value;
-  }
-
-  @override
-  List<LinkedNodeBuilder> get adjacentStrings_strings {
-    assert(kind == idl.LinkedNodeKind.adjacentStrings);
-    return _variantField_2 ??= <LinkedNodeBuilder>[];
-  }
-
-  @override
-  List<LinkedNodeBuilder> get argumentList_arguments {
-    assert(kind == idl.LinkedNodeKind.argumentList);
-    return _variantField_2 ??= <LinkedNodeBuilder>[];
-  }
-
-  @override
-  List<LinkedNodeBuilder> get block_statements {
-    assert(kind == idl.LinkedNodeKind.block);
-    return _variantField_2 ??= <LinkedNodeBuilder>[];
-  }
-
-  @override
-  List<LinkedNodeBuilder> get cascadeExpression_sections {
-    assert(kind == idl.LinkedNodeKind.cascadeExpression);
-    return _variantField_2 ??= <LinkedNodeBuilder>[];
-  }
-
-  @override
-  List<LinkedNodeBuilder> get comment_references {
-    assert(kind == idl.LinkedNodeKind.comment);
-    return _variantField_2 ??= <LinkedNodeBuilder>[];
-  }
-
-  @override
-  List<LinkedNodeBuilder> get compilationUnit_declarations {
-    assert(kind == idl.LinkedNodeKind.compilationUnit);
-    return _variantField_2 ??= <LinkedNodeBuilder>[];
-  }
-
-  @override
-  List<LinkedNodeBuilder> get constructorDeclaration_initializers {
-    assert(kind == idl.LinkedNodeKind.constructorDeclaration);
-    return _variantField_2 ??= <LinkedNodeBuilder>[];
-  }
-
-  @override
-  List<LinkedNodeBuilder> get dottedName_components {
-    assert(kind == idl.LinkedNodeKind.dottedName);
-    return _variantField_2 ??= <LinkedNodeBuilder>[];
-  }
-
-  @override
-  List<LinkedNodeBuilder> get enumDeclaration_constants {
-    assert(kind == idl.LinkedNodeKind.enumDeclaration);
-    return _variantField_2 ??= <LinkedNodeBuilder>[];
-  }
-
-  @override
-  List<LinkedNodeBuilder> get extensionOverride_arguments {
-    assert(kind == idl.LinkedNodeKind.extensionOverride);
-    return _variantField_2 ??= <LinkedNodeBuilder>[];
-  }
-
-  @override
-  List<LinkedNodeBuilder> get formalParameterList_parameters {
-    assert(kind == idl.LinkedNodeKind.formalParameterList);
-    return _variantField_2 ??= <LinkedNodeBuilder>[];
-  }
-
-  @override
-  List<LinkedNodeBuilder> get implementsClause_interfaces {
-    assert(kind == idl.LinkedNodeKind.implementsClause);
-    return _variantField_2 ??= <LinkedNodeBuilder>[];
-  }
-
-  @override
-  List<LinkedNodeBuilder> get instanceCreationExpression_arguments {
-    assert(kind == idl.LinkedNodeKind.instanceCreationExpression);
-    return _variantField_2 ??= <LinkedNodeBuilder>[];
-  }
-
-  @override
-  List<LinkedNodeBuilder> get labeledStatement_labels {
-    assert(kind == idl.LinkedNodeKind.labeledStatement);
-    return _variantField_2 ??= <LinkedNodeBuilder>[];
-  }
-
-  @override
-  List<LinkedNodeBuilder> get libraryIdentifier_components {
-    assert(kind == idl.LinkedNodeKind.libraryIdentifier);
-    return _variantField_2 ??= <LinkedNodeBuilder>[];
-  }
-
-  @override
-  List<LinkedNodeBuilder> get namespaceDirective_combinators {
-    assert(kind == idl.LinkedNodeKind.exportDirective ||
-        kind == idl.LinkedNodeKind.importDirective);
-    return _variantField_2 ??= <LinkedNodeBuilder>[];
-  }
-
-  @override
-  List<LinkedNodeBuilder> get onClause_superclassConstraints {
-    assert(kind == idl.LinkedNodeKind.onClause);
-    return _variantField_2 ??= <LinkedNodeBuilder>[];
-  }
-
-  @override
-  List<LinkedNodeBuilder> get stringInterpolation_elements {
-    assert(kind == idl.LinkedNodeKind.stringInterpolation);
-    return _variantField_2 ??= <LinkedNodeBuilder>[];
-  }
-
-  @override
-  List<LinkedNodeBuilder> get switchStatement_members {
-    assert(kind == idl.LinkedNodeKind.switchStatement);
-    return _variantField_2 ??= <LinkedNodeBuilder>[];
-  }
-
-  @override
-  List<LinkedNodeBuilder> get tryStatement_catchClauses {
-    assert(kind == idl.LinkedNodeKind.tryStatement);
-    return _variantField_2 ??= <LinkedNodeBuilder>[];
-  }
-
-  @override
-  List<LinkedNodeBuilder> get typeArgumentList_arguments {
-    assert(kind == idl.LinkedNodeKind.typeArgumentList);
-    return _variantField_2 ??= <LinkedNodeBuilder>[];
-  }
-
-  @override
-  List<LinkedNodeBuilder> get typedLiteral_typeArguments {
-    assert(kind == idl.LinkedNodeKind.listLiteral ||
-        kind == idl.LinkedNodeKind.setOrMapLiteral);
-    return _variantField_2 ??= <LinkedNodeBuilder>[];
-  }
-
-  @override
-  List<LinkedNodeBuilder> get typeName_typeArguments {
-    assert(kind == idl.LinkedNodeKind.typeName);
-    return _variantField_2 ??= <LinkedNodeBuilder>[];
-  }
-
-  @override
-  List<LinkedNodeBuilder> get typeParameterList_typeParameters {
-    assert(kind == idl.LinkedNodeKind.typeParameterList);
-    return _variantField_2 ??= <LinkedNodeBuilder>[];
-  }
-
-  @override
-  List<LinkedNodeBuilder> get variableDeclarationList_variables {
-    assert(kind == idl.LinkedNodeKind.variableDeclarationList);
-    return _variantField_2 ??= <LinkedNodeBuilder>[];
-  }
-
-  @override
-  List<LinkedNodeBuilder> get withClause_mixinTypes {
-    assert(kind == idl.LinkedNodeKind.withClause);
-    return _variantField_2 ??= <LinkedNodeBuilder>[];
-  }
-
-  set adjacentStrings_strings(List<LinkedNodeBuilder> value) {
-    assert(kind == idl.LinkedNodeKind.adjacentStrings);
-    _variantField_2 = value;
-  }
-
-  set argumentList_arguments(List<LinkedNodeBuilder> value) {
-    assert(kind == idl.LinkedNodeKind.argumentList);
-    _variantField_2 = value;
-  }
-
-  set block_statements(List<LinkedNodeBuilder> value) {
-    assert(kind == idl.LinkedNodeKind.block);
-    _variantField_2 = value;
-  }
-
-  set cascadeExpression_sections(List<LinkedNodeBuilder> value) {
-    assert(kind == idl.LinkedNodeKind.cascadeExpression);
-    _variantField_2 = value;
-  }
-
-  set comment_references(List<LinkedNodeBuilder> value) {
-    assert(kind == idl.LinkedNodeKind.comment);
-    _variantField_2 = value;
-  }
-
-  set compilationUnit_declarations(List<LinkedNodeBuilder> value) {
-    assert(kind == idl.LinkedNodeKind.compilationUnit);
-    _variantField_2 = value;
-  }
-
-  set constructorDeclaration_initializers(List<LinkedNodeBuilder> value) {
-    assert(kind == idl.LinkedNodeKind.constructorDeclaration);
-    _variantField_2 = value;
-  }
-
-  set dottedName_components(List<LinkedNodeBuilder> value) {
-    assert(kind == idl.LinkedNodeKind.dottedName);
-    _variantField_2 = value;
-  }
-
-  set enumDeclaration_constants(List<LinkedNodeBuilder> value) {
-    assert(kind == idl.LinkedNodeKind.enumDeclaration);
-    _variantField_2 = value;
-  }
-
-  set extensionOverride_arguments(List<LinkedNodeBuilder> value) {
-    assert(kind == idl.LinkedNodeKind.extensionOverride);
-    _variantField_2 = value;
-  }
-
-  set formalParameterList_parameters(List<LinkedNodeBuilder> value) {
-    assert(kind == idl.LinkedNodeKind.formalParameterList);
-    _variantField_2 = value;
-  }
-
-  set implementsClause_interfaces(List<LinkedNodeBuilder> value) {
-    assert(kind == idl.LinkedNodeKind.implementsClause);
-    _variantField_2 = value;
-  }
-
-  set instanceCreationExpression_arguments(List<LinkedNodeBuilder> value) {
-    assert(kind == idl.LinkedNodeKind.instanceCreationExpression);
-    _variantField_2 = value;
-  }
-
-  set labeledStatement_labels(List<LinkedNodeBuilder> value) {
-    assert(kind == idl.LinkedNodeKind.labeledStatement);
-    _variantField_2 = value;
-  }
-
-  set libraryIdentifier_components(List<LinkedNodeBuilder> value) {
-    assert(kind == idl.LinkedNodeKind.libraryIdentifier);
-    _variantField_2 = value;
-  }
-
-  set namespaceDirective_combinators(List<LinkedNodeBuilder> value) {
-    assert(kind == idl.LinkedNodeKind.exportDirective ||
-        kind == idl.LinkedNodeKind.importDirective);
-    _variantField_2 = value;
-  }
-
-  set onClause_superclassConstraints(List<LinkedNodeBuilder> value) {
-    assert(kind == idl.LinkedNodeKind.onClause);
-    _variantField_2 = value;
-  }
-
-  set stringInterpolation_elements(List<LinkedNodeBuilder> value) {
-    assert(kind == idl.LinkedNodeKind.stringInterpolation);
-    _variantField_2 = value;
-  }
-
-  set switchStatement_members(List<LinkedNodeBuilder> value) {
-    assert(kind == idl.LinkedNodeKind.switchStatement);
-    _variantField_2 = value;
-  }
-
-  set tryStatement_catchClauses(List<LinkedNodeBuilder> value) {
-    assert(kind == idl.LinkedNodeKind.tryStatement);
-    _variantField_2 = value;
-  }
-
-  set typeArgumentList_arguments(List<LinkedNodeBuilder> value) {
-    assert(kind == idl.LinkedNodeKind.typeArgumentList);
-    _variantField_2 = value;
-  }
-
-  set typedLiteral_typeArguments(List<LinkedNodeBuilder> value) {
-    assert(kind == idl.LinkedNodeKind.listLiteral ||
-        kind == idl.LinkedNodeKind.setOrMapLiteral);
-    _variantField_2 = value;
-  }
-
-  set typeName_typeArguments(List<LinkedNodeBuilder> value) {
-    assert(kind == idl.LinkedNodeKind.typeName);
-    _variantField_2 = value;
-  }
-
-  set typeParameterList_typeParameters(List<LinkedNodeBuilder> value) {
-    assert(kind == idl.LinkedNodeKind.typeParameterList);
-    _variantField_2 = value;
-  }
-
-  set variableDeclarationList_variables(List<LinkedNodeBuilder> value) {
-    assert(kind == idl.LinkedNodeKind.variableDeclarationList);
-    _variantField_2 = value;
-  }
-
-  set withClause_mixinTypes(List<LinkedNodeBuilder> value) {
-    assert(kind == idl.LinkedNodeKind.withClause);
-    _variantField_2 = value;
-  }
-
-  @override
-  List<LinkedNodeBuilder> get annotatedNode_metadata {
-    assert(kind == idl.LinkedNodeKind.classDeclaration ||
-        kind == idl.LinkedNodeKind.classTypeAlias ||
-        kind == idl.LinkedNodeKind.constructorDeclaration ||
-        kind == idl.LinkedNodeKind.declaredIdentifier ||
-        kind == idl.LinkedNodeKind.enumDeclaration ||
-        kind == idl.LinkedNodeKind.enumConstantDeclaration ||
-        kind == idl.LinkedNodeKind.exportDirective ||
-        kind == idl.LinkedNodeKind.extensionDeclaration ||
-        kind == idl.LinkedNodeKind.fieldDeclaration ||
-        kind == idl.LinkedNodeKind.functionDeclaration ||
-        kind == idl.LinkedNodeKind.functionTypeAlias ||
-        kind == idl.LinkedNodeKind.genericTypeAlias ||
-        kind == idl.LinkedNodeKind.importDirective ||
-        kind == idl.LinkedNodeKind.libraryDirective ||
-        kind == idl.LinkedNodeKind.methodDeclaration ||
-        kind == idl.LinkedNodeKind.mixinDeclaration ||
-        kind == idl.LinkedNodeKind.partDirective ||
-        kind == idl.LinkedNodeKind.partOfDirective ||
-        kind == idl.LinkedNodeKind.topLevelVariableDeclaration ||
-        kind == idl.LinkedNodeKind.typeParameter ||
-        kind == idl.LinkedNodeKind.variableDeclaration ||
-        kind == idl.LinkedNodeKind.variableDeclarationList);
-    return _variantField_4 ??= <LinkedNodeBuilder>[];
-  }
-
-  @override
-  List<LinkedNodeBuilder> get normalFormalParameter_metadata {
-    assert(kind == idl.LinkedNodeKind.fieldFormalParameter ||
-        kind == idl.LinkedNodeKind.functionTypedFormalParameter ||
-        kind == idl.LinkedNodeKind.simpleFormalParameter);
-    return _variantField_4 ??= <LinkedNodeBuilder>[];
-  }
-
-  @override
-  List<LinkedNodeBuilder> get switchMember_statements {
-    assert(kind == idl.LinkedNodeKind.switchCase ||
-        kind == idl.LinkedNodeKind.switchDefault);
-    return _variantField_4 ??= <LinkedNodeBuilder>[];
-  }
-
-  set annotatedNode_metadata(List<LinkedNodeBuilder> value) {
-    assert(kind == idl.LinkedNodeKind.classDeclaration ||
-        kind == idl.LinkedNodeKind.classTypeAlias ||
-        kind == idl.LinkedNodeKind.constructorDeclaration ||
-        kind == idl.LinkedNodeKind.declaredIdentifier ||
-        kind == idl.LinkedNodeKind.enumDeclaration ||
-        kind == idl.LinkedNodeKind.enumConstantDeclaration ||
-        kind == idl.LinkedNodeKind.exportDirective ||
-        kind == idl.LinkedNodeKind.extensionDeclaration ||
-        kind == idl.LinkedNodeKind.fieldDeclaration ||
-        kind == idl.LinkedNodeKind.functionDeclaration ||
-        kind == idl.LinkedNodeKind.functionTypeAlias ||
-        kind == idl.LinkedNodeKind.genericTypeAlias ||
-        kind == idl.LinkedNodeKind.importDirective ||
-        kind == idl.LinkedNodeKind.libraryDirective ||
-        kind == idl.LinkedNodeKind.methodDeclaration ||
-        kind == idl.LinkedNodeKind.mixinDeclaration ||
-        kind == idl.LinkedNodeKind.partDirective ||
-        kind == idl.LinkedNodeKind.partOfDirective ||
-        kind == idl.LinkedNodeKind.topLevelVariableDeclaration ||
-        kind == idl.LinkedNodeKind.typeParameter ||
-        kind == idl.LinkedNodeKind.variableDeclaration ||
-        kind == idl.LinkedNodeKind.variableDeclarationList);
-    _variantField_4 = value;
-  }
-
-  set normalFormalParameter_metadata(List<LinkedNodeBuilder> value) {
-    assert(kind == idl.LinkedNodeKind.fieldFormalParameter ||
-        kind == idl.LinkedNodeKind.functionTypedFormalParameter ||
-        kind == idl.LinkedNodeKind.simpleFormalParameter);
-    _variantField_4 = value;
-  }
-
-  set switchMember_statements(List<LinkedNodeBuilder> value) {
-    assert(kind == idl.LinkedNodeKind.switchCase ||
-        kind == idl.LinkedNodeKind.switchDefault);
-    _variantField_4 = value;
-  }
-
-  @override
-  LinkedNodeBuilder get annotation_arguments {
-    assert(kind == idl.LinkedNodeKind.annotation);
-    return _variantField_6;
-  }
-
-  @override
-  LinkedNodeBuilder get asExpression_expression {
-    assert(kind == idl.LinkedNodeKind.asExpression);
-    return _variantField_6;
-  }
-
-  @override
-  LinkedNodeBuilder get assertInitializer_condition {
-    assert(kind == idl.LinkedNodeKind.assertInitializer);
-    return _variantField_6;
-  }
-
-  @override
-  LinkedNodeBuilder get assertStatement_condition {
-    assert(kind == idl.LinkedNodeKind.assertStatement);
-    return _variantField_6;
-  }
-
-  @override
-  LinkedNodeBuilder get assignmentExpression_leftHandSide {
-    assert(kind == idl.LinkedNodeKind.assignmentExpression);
-    return _variantField_6;
-  }
-
-  @override
-  LinkedNodeBuilder get awaitExpression_expression {
-    assert(kind == idl.LinkedNodeKind.awaitExpression);
-    return _variantField_6;
-  }
-
-  @override
-  LinkedNodeBuilder get binaryExpression_leftOperand {
-    assert(kind == idl.LinkedNodeKind.binaryExpression);
-    return _variantField_6;
-  }
-
-  @override
-  LinkedNodeBuilder get blockFunctionBody_block {
-    assert(kind == idl.LinkedNodeKind.blockFunctionBody);
-    return _variantField_6;
-  }
-
-  @override
-  LinkedNodeBuilder get breakStatement_label {
-    assert(kind == idl.LinkedNodeKind.breakStatement);
-    return _variantField_6;
-  }
-
-  @override
-  LinkedNodeBuilder get cascadeExpression_target {
-    assert(kind == idl.LinkedNodeKind.cascadeExpression);
-    return _variantField_6;
-  }
-
-  @override
-  LinkedNodeBuilder get catchClause_body {
-    assert(kind == idl.LinkedNodeKind.catchClause);
-    return _variantField_6;
-  }
-
-  @override
-  LinkedNodeBuilder get classDeclaration_extendsClause {
-    assert(kind == idl.LinkedNodeKind.classDeclaration);
-    return _variantField_6;
-  }
-
-  @override
-  LinkedNodeBuilder get classTypeAlias_typeParameters {
-    assert(kind == idl.LinkedNodeKind.classTypeAlias);
-    return _variantField_6;
-  }
-
-  @override
-  LinkedNodeBuilder get commentReference_identifier {
-    assert(kind == idl.LinkedNodeKind.commentReference);
-    return _variantField_6;
-  }
-
-  @override
-  LinkedNodeBuilder get compilationUnit_scriptTag {
-    assert(kind == idl.LinkedNodeKind.compilationUnit);
-    return _variantField_6;
-  }
-
-  @override
-  LinkedNodeBuilder get conditionalExpression_condition {
-    assert(kind == idl.LinkedNodeKind.conditionalExpression);
-    return _variantField_6;
-  }
-
-  @override
-  LinkedNodeBuilder get configuration_name {
-    assert(kind == idl.LinkedNodeKind.configuration);
-    return _variantField_6;
-  }
-
-  @override
-  LinkedNodeBuilder get constructorDeclaration_body {
-    assert(kind == idl.LinkedNodeKind.constructorDeclaration);
-    return _variantField_6;
-  }
-
-  @override
-  LinkedNodeBuilder get constructorFieldInitializer_expression {
-    assert(kind == idl.LinkedNodeKind.constructorFieldInitializer);
-    return _variantField_6;
-  }
-
-  @override
-  LinkedNodeBuilder get constructorName_name {
-    assert(kind == idl.LinkedNodeKind.constructorName);
-    return _variantField_6;
-  }
-
-  @override
-  LinkedNodeBuilder get continueStatement_label {
-    assert(kind == idl.LinkedNodeKind.continueStatement);
-    return _variantField_6;
-  }
-
-  @override
-  LinkedNodeBuilder get declaredIdentifier_identifier {
-    assert(kind == idl.LinkedNodeKind.declaredIdentifier);
-    return _variantField_6;
-  }
-
-  @override
-  LinkedNodeBuilder get defaultFormalParameter_defaultValue {
-    assert(kind == idl.LinkedNodeKind.defaultFormalParameter);
-    return _variantField_6;
-  }
-
-  @override
-  LinkedNodeBuilder get doStatement_body {
-    assert(kind == idl.LinkedNodeKind.doStatement);
-    return _variantField_6;
-  }
-
-  @override
-  LinkedNodeBuilder get expressionFunctionBody_expression {
-    assert(kind == idl.LinkedNodeKind.expressionFunctionBody);
-    return _variantField_6;
-  }
-
-  @override
-  LinkedNodeBuilder get expressionStatement_expression {
-    assert(kind == idl.LinkedNodeKind.expressionStatement);
-    return _variantField_6;
-  }
-
-  @override
-  LinkedNodeBuilder get extendsClause_superclass {
-    assert(kind == idl.LinkedNodeKind.extendsClause);
-    return _variantField_6;
-  }
-
-  @override
-  LinkedNodeBuilder get extensionDeclaration_typeParameters {
-    assert(kind == idl.LinkedNodeKind.extensionDeclaration);
-    return _variantField_6;
-  }
-
-  @override
-  LinkedNodeBuilder get fieldDeclaration_fields {
-    assert(kind == idl.LinkedNodeKind.fieldDeclaration);
-    return _variantField_6;
-  }
-
-  @override
-  LinkedNodeBuilder get fieldFormalParameter_type {
-    assert(kind == idl.LinkedNodeKind.fieldFormalParameter);
-    return _variantField_6;
-  }
-
-  @override
-  LinkedNodeBuilder get forEachParts_iterable {
-    assert(kind == idl.LinkedNodeKind.forEachPartsWithDeclaration ||
-        kind == idl.LinkedNodeKind.forEachPartsWithIdentifier);
-    return _variantField_6;
-  }
-
-  @override
-  LinkedNodeBuilder get forMixin_forLoopParts {
-    assert(kind == idl.LinkedNodeKind.forElement ||
-        kind == idl.LinkedNodeKind.forStatement);
-    return _variantField_6;
-  }
-
-  @override
-  LinkedNodeBuilder get forParts_condition {
-    assert(kind == idl.LinkedNodeKind.forPartsWithDeclarations ||
-        kind == idl.LinkedNodeKind.forPartsWithExpression);
-    return _variantField_6;
-  }
-
-  @override
-  LinkedNodeBuilder get functionDeclaration_functionExpression {
-    assert(kind == idl.LinkedNodeKind.functionDeclaration);
-    return _variantField_6;
-  }
-
-  @override
-  LinkedNodeBuilder get functionDeclarationStatement_functionDeclaration {
-    assert(kind == idl.LinkedNodeKind.functionDeclarationStatement);
-    return _variantField_6;
-  }
-
-  @override
-  LinkedNodeBuilder get functionExpression_body {
-    assert(kind == idl.LinkedNodeKind.functionExpression);
-    return _variantField_6;
-  }
-
-  @override
-  LinkedNodeBuilder get functionExpressionInvocation_function {
-    assert(kind == idl.LinkedNodeKind.functionExpressionInvocation);
-    return _variantField_6;
-  }
-
-  @override
-  LinkedNodeBuilder get functionTypeAlias_formalParameters {
-    assert(kind == idl.LinkedNodeKind.functionTypeAlias);
-    return _variantField_6;
-  }
-
-  @override
-  LinkedNodeBuilder get functionTypedFormalParameter_formalParameters {
-    assert(kind == idl.LinkedNodeKind.functionTypedFormalParameter);
-    return _variantField_6;
-  }
-
-  @override
-  LinkedNodeBuilder get genericFunctionType_typeParameters {
-    assert(kind == idl.LinkedNodeKind.genericFunctionType);
-    return _variantField_6;
-  }
-
-  @override
-  LinkedNodeBuilder get genericTypeAlias_typeParameters {
-    assert(kind == idl.LinkedNodeKind.genericTypeAlias);
-    return _variantField_6;
-  }
-
-  @override
-  LinkedNodeBuilder get ifMixin_condition {
-    assert(kind == idl.LinkedNodeKind.ifElement ||
-        kind == idl.LinkedNodeKind.ifStatement);
-    return _variantField_6;
-  }
-
-  @override
-  LinkedNodeBuilder get indexExpression_index {
-    assert(kind == idl.LinkedNodeKind.indexExpression);
-    return _variantField_6;
-  }
-
-  @override
-  LinkedNodeBuilder get interpolationExpression_expression {
-    assert(kind == idl.LinkedNodeKind.interpolationExpression);
-    return _variantField_6;
-  }
-
-  @override
-  LinkedNodeBuilder get isExpression_expression {
-    assert(kind == idl.LinkedNodeKind.isExpression);
-    return _variantField_6;
-  }
-
-  @override
-  LinkedNodeBuilder get label_label {
-    assert(kind == idl.LinkedNodeKind.label);
-    return _variantField_6;
-  }
-
-  @override
-  LinkedNodeBuilder get labeledStatement_statement {
-    assert(kind == idl.LinkedNodeKind.labeledStatement);
-    return _variantField_6;
-  }
-
-  @override
-  LinkedNodeBuilder get libraryDirective_name {
-    assert(kind == idl.LinkedNodeKind.libraryDirective);
-    return _variantField_6;
-  }
-
-  @override
-  LinkedNodeBuilder get mapLiteralEntry_key {
-    assert(kind == idl.LinkedNodeKind.mapLiteralEntry);
-    return _variantField_6;
-  }
-
-  @override
-  LinkedNodeBuilder get methodDeclaration_body {
-    assert(kind == idl.LinkedNodeKind.methodDeclaration);
-    return _variantField_6;
-  }
-
-  @override
-  LinkedNodeBuilder get methodInvocation_methodName {
-    assert(kind == idl.LinkedNodeKind.methodInvocation);
-    return _variantField_6;
-  }
-
-  @override
-  LinkedNodeBuilder get mixinDeclaration_onClause {
-    assert(kind == idl.LinkedNodeKind.mixinDeclaration);
-    return _variantField_6;
-  }
-
-  @override
-  LinkedNodeBuilder get namedExpression_expression {
-    assert(kind == idl.LinkedNodeKind.namedExpression);
-    return _variantField_6;
-  }
-
-  @override
-  LinkedNodeBuilder get nativeClause_name {
-    assert(kind == idl.LinkedNodeKind.nativeClause);
-    return _variantField_6;
-  }
-
-  @override
-  LinkedNodeBuilder get nativeFunctionBody_stringLiteral {
-    assert(kind == idl.LinkedNodeKind.nativeFunctionBody);
-    return _variantField_6;
-  }
-
-  @override
-  LinkedNodeBuilder get parenthesizedExpression_expression {
-    assert(kind == idl.LinkedNodeKind.parenthesizedExpression);
-    return _variantField_6;
-  }
-
-  @override
-  LinkedNodeBuilder get partOfDirective_libraryName {
-    assert(kind == idl.LinkedNodeKind.partOfDirective);
-    return _variantField_6;
-  }
-
-  @override
-  LinkedNodeBuilder get postfixExpression_operand {
-    assert(kind == idl.LinkedNodeKind.postfixExpression);
-    return _variantField_6;
-  }
-
-  @override
-  LinkedNodeBuilder get prefixedIdentifier_identifier {
-    assert(kind == idl.LinkedNodeKind.prefixedIdentifier);
-    return _variantField_6;
-  }
-
-  @override
-  LinkedNodeBuilder get prefixExpression_operand {
-    assert(kind == idl.LinkedNodeKind.prefixExpression);
-    return _variantField_6;
-  }
-
-  @override
-  LinkedNodeBuilder get propertyAccess_propertyName {
-    assert(kind == idl.LinkedNodeKind.propertyAccess);
-    return _variantField_6;
-  }
-
-  @override
-  LinkedNodeBuilder get redirectingConstructorInvocation_arguments {
-    assert(kind == idl.LinkedNodeKind.redirectingConstructorInvocation);
-    return _variantField_6;
-  }
-
-  @override
-  LinkedNodeBuilder get returnStatement_expression {
-    assert(kind == idl.LinkedNodeKind.returnStatement);
-    return _variantField_6;
-  }
-
-  @override
-  LinkedNodeBuilder get simpleFormalParameter_type {
-    assert(kind == idl.LinkedNodeKind.simpleFormalParameter);
-    return _variantField_6;
-  }
-
-  @override
-  LinkedNodeBuilder get spreadElement_expression {
-    assert(kind == idl.LinkedNodeKind.spreadElement);
-    return _variantField_6;
-  }
-
-  @override
-  LinkedNodeBuilder get superConstructorInvocation_arguments {
-    assert(kind == idl.LinkedNodeKind.superConstructorInvocation);
-    return _variantField_6;
-  }
-
-  @override
-  LinkedNodeBuilder get switchCase_expression {
-    assert(kind == idl.LinkedNodeKind.switchCase);
-    return _variantField_6;
-  }
-
-  @override
-  LinkedNodeBuilder get throwExpression_expression {
-    assert(kind == idl.LinkedNodeKind.throwExpression);
-    return _variantField_6;
-  }
-
-  @override
-  LinkedNodeBuilder get topLevelVariableDeclaration_variableList {
-    assert(kind == idl.LinkedNodeKind.topLevelVariableDeclaration);
-    return _variantField_6;
-  }
-
-  @override
-  LinkedNodeBuilder get tryStatement_body {
-    assert(kind == idl.LinkedNodeKind.tryStatement);
-    return _variantField_6;
-  }
-
-  @override
-  LinkedNodeBuilder get typeName_name {
-    assert(kind == idl.LinkedNodeKind.typeName);
-    return _variantField_6;
-  }
-
-  @override
-  LinkedNodeBuilder get typeParameter_bound {
-    assert(kind == idl.LinkedNodeKind.typeParameter);
-    return _variantField_6;
-  }
-
-  @override
-  LinkedNodeBuilder get variableDeclaration_initializer {
-    assert(kind == idl.LinkedNodeKind.variableDeclaration);
-    return _variantField_6;
-  }
-
-  @override
-  LinkedNodeBuilder get variableDeclarationList_type {
-    assert(kind == idl.LinkedNodeKind.variableDeclarationList);
-    return _variantField_6;
-  }
-
-  @override
-  LinkedNodeBuilder get variableDeclarationStatement_variables {
-    assert(kind == idl.LinkedNodeKind.variableDeclarationStatement);
-    return _variantField_6;
-  }
-
-  @override
-  LinkedNodeBuilder get whileStatement_body {
-    assert(kind == idl.LinkedNodeKind.whileStatement);
-    return _variantField_6;
-  }
-
-  @override
-  LinkedNodeBuilder get yieldStatement_expression {
-    assert(kind == idl.LinkedNodeKind.yieldStatement);
-    return _variantField_6;
-  }
-
-  set annotation_arguments(LinkedNodeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.annotation);
-    _variantField_6 = value;
-  }
-
-  set asExpression_expression(LinkedNodeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.asExpression);
-    _variantField_6 = value;
-  }
-
-  set assertInitializer_condition(LinkedNodeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.assertInitializer);
-    _variantField_6 = value;
-  }
-
-  set assertStatement_condition(LinkedNodeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.assertStatement);
-    _variantField_6 = value;
-  }
-
-  set assignmentExpression_leftHandSide(LinkedNodeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.assignmentExpression);
-    _variantField_6 = value;
-  }
-
-  set awaitExpression_expression(LinkedNodeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.awaitExpression);
-    _variantField_6 = value;
-  }
-
-  set binaryExpression_leftOperand(LinkedNodeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.binaryExpression);
-    _variantField_6 = value;
-  }
-
-  set blockFunctionBody_block(LinkedNodeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.blockFunctionBody);
-    _variantField_6 = value;
-  }
-
-  set breakStatement_label(LinkedNodeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.breakStatement);
-    _variantField_6 = value;
-  }
-
-  set cascadeExpression_target(LinkedNodeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.cascadeExpression);
-    _variantField_6 = value;
-  }
-
-  set catchClause_body(LinkedNodeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.catchClause);
-    _variantField_6 = value;
-  }
-
-  set classDeclaration_extendsClause(LinkedNodeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.classDeclaration);
-    _variantField_6 = value;
-  }
-
-  set classTypeAlias_typeParameters(LinkedNodeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.classTypeAlias);
-    _variantField_6 = value;
-  }
-
-  set commentReference_identifier(LinkedNodeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.commentReference);
-    _variantField_6 = value;
-  }
-
-  set compilationUnit_scriptTag(LinkedNodeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.compilationUnit);
-    _variantField_6 = value;
-  }
-
-  set conditionalExpression_condition(LinkedNodeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.conditionalExpression);
-    _variantField_6 = value;
-  }
-
-  set configuration_name(LinkedNodeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.configuration);
-    _variantField_6 = value;
-  }
-
-  set constructorDeclaration_body(LinkedNodeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.constructorDeclaration);
-    _variantField_6 = value;
-  }
-
-  set constructorFieldInitializer_expression(LinkedNodeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.constructorFieldInitializer);
-    _variantField_6 = value;
-  }
-
-  set constructorName_name(LinkedNodeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.constructorName);
-    _variantField_6 = value;
-  }
-
-  set continueStatement_label(LinkedNodeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.continueStatement);
-    _variantField_6 = value;
-  }
-
-  set declaredIdentifier_identifier(LinkedNodeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.declaredIdentifier);
-    _variantField_6 = value;
-  }
-
-  set defaultFormalParameter_defaultValue(LinkedNodeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.defaultFormalParameter);
-    _variantField_6 = value;
-  }
-
-  set doStatement_body(LinkedNodeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.doStatement);
-    _variantField_6 = value;
-  }
-
-  set expressionFunctionBody_expression(LinkedNodeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.expressionFunctionBody);
-    _variantField_6 = value;
-  }
-
-  set expressionStatement_expression(LinkedNodeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.expressionStatement);
-    _variantField_6 = value;
-  }
-
-  set extendsClause_superclass(LinkedNodeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.extendsClause);
-    _variantField_6 = value;
-  }
-
-  set extensionDeclaration_typeParameters(LinkedNodeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.extensionDeclaration);
-    _variantField_6 = value;
-  }
-
-  set fieldDeclaration_fields(LinkedNodeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.fieldDeclaration);
-    _variantField_6 = value;
-  }
-
-  set fieldFormalParameter_type(LinkedNodeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.fieldFormalParameter);
-    _variantField_6 = value;
-  }
-
-  set forEachParts_iterable(LinkedNodeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.forEachPartsWithDeclaration ||
-        kind == idl.LinkedNodeKind.forEachPartsWithIdentifier);
-    _variantField_6 = value;
-  }
-
-  set forMixin_forLoopParts(LinkedNodeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.forElement ||
-        kind == idl.LinkedNodeKind.forStatement);
-    _variantField_6 = value;
-  }
-
-  set forParts_condition(LinkedNodeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.forPartsWithDeclarations ||
-        kind == idl.LinkedNodeKind.forPartsWithExpression);
-    _variantField_6 = value;
-  }
-
-  set functionDeclaration_functionExpression(LinkedNodeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.functionDeclaration);
-    _variantField_6 = value;
-  }
-
-  set functionDeclarationStatement_functionDeclaration(
-      LinkedNodeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.functionDeclarationStatement);
-    _variantField_6 = value;
-  }
-
-  set functionExpression_body(LinkedNodeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.functionExpression);
-    _variantField_6 = value;
-  }
-
-  set functionExpressionInvocation_function(LinkedNodeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.functionExpressionInvocation);
-    _variantField_6 = value;
-  }
-
-  set functionTypeAlias_formalParameters(LinkedNodeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.functionTypeAlias);
-    _variantField_6 = value;
-  }
-
-  set functionTypedFormalParameter_formalParameters(LinkedNodeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.functionTypedFormalParameter);
-    _variantField_6 = value;
-  }
-
-  set genericFunctionType_typeParameters(LinkedNodeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.genericFunctionType);
-    _variantField_6 = value;
-  }
-
-  set genericTypeAlias_typeParameters(LinkedNodeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.genericTypeAlias);
-    _variantField_6 = value;
-  }
-
-  set ifMixin_condition(LinkedNodeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.ifElement ||
-        kind == idl.LinkedNodeKind.ifStatement);
-    _variantField_6 = value;
-  }
-
-  set indexExpression_index(LinkedNodeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.indexExpression);
-    _variantField_6 = value;
-  }
-
-  set interpolationExpression_expression(LinkedNodeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.interpolationExpression);
-    _variantField_6 = value;
-  }
-
-  set isExpression_expression(LinkedNodeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.isExpression);
-    _variantField_6 = value;
-  }
-
-  set label_label(LinkedNodeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.label);
-    _variantField_6 = value;
-  }
-
-  set labeledStatement_statement(LinkedNodeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.labeledStatement);
-    _variantField_6 = value;
-  }
-
-  set libraryDirective_name(LinkedNodeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.libraryDirective);
-    _variantField_6 = value;
-  }
-
-  set mapLiteralEntry_key(LinkedNodeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.mapLiteralEntry);
-    _variantField_6 = value;
-  }
-
-  set methodDeclaration_body(LinkedNodeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.methodDeclaration);
-    _variantField_6 = value;
-  }
-
-  set methodInvocation_methodName(LinkedNodeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.methodInvocation);
-    _variantField_6 = value;
-  }
-
-  set mixinDeclaration_onClause(LinkedNodeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.mixinDeclaration);
-    _variantField_6 = value;
-  }
-
-  set namedExpression_expression(LinkedNodeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.namedExpression);
-    _variantField_6 = value;
-  }
-
-  set nativeClause_name(LinkedNodeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.nativeClause);
-    _variantField_6 = value;
-  }
-
-  set nativeFunctionBody_stringLiteral(LinkedNodeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.nativeFunctionBody);
-    _variantField_6 = value;
-  }
-
-  set parenthesizedExpression_expression(LinkedNodeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.parenthesizedExpression);
-    _variantField_6 = value;
-  }
-
-  set partOfDirective_libraryName(LinkedNodeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.partOfDirective);
-    _variantField_6 = value;
-  }
-
-  set postfixExpression_operand(LinkedNodeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.postfixExpression);
-    _variantField_6 = value;
-  }
-
-  set prefixedIdentifier_identifier(LinkedNodeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.prefixedIdentifier);
-    _variantField_6 = value;
-  }
-
-  set prefixExpression_operand(LinkedNodeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.prefixExpression);
-    _variantField_6 = value;
-  }
-
-  set propertyAccess_propertyName(LinkedNodeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.propertyAccess);
-    _variantField_6 = value;
-  }
-
-  set redirectingConstructorInvocation_arguments(LinkedNodeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.redirectingConstructorInvocation);
-    _variantField_6 = value;
-  }
-
-  set returnStatement_expression(LinkedNodeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.returnStatement);
-    _variantField_6 = value;
-  }
-
-  set simpleFormalParameter_type(LinkedNodeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.simpleFormalParameter);
-    _variantField_6 = value;
-  }
-
-  set spreadElement_expression(LinkedNodeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.spreadElement);
-    _variantField_6 = value;
-  }
-
-  set superConstructorInvocation_arguments(LinkedNodeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.superConstructorInvocation);
-    _variantField_6 = value;
-  }
-
-  set switchCase_expression(LinkedNodeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.switchCase);
-    _variantField_6 = value;
-  }
-
-  set throwExpression_expression(LinkedNodeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.throwExpression);
-    _variantField_6 = value;
-  }
-
-  set topLevelVariableDeclaration_variableList(LinkedNodeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.topLevelVariableDeclaration);
-    _variantField_6 = value;
-  }
-
-  set tryStatement_body(LinkedNodeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.tryStatement);
-    _variantField_6 = value;
-  }
-
-  set typeName_name(LinkedNodeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.typeName);
-    _variantField_6 = value;
-  }
-
-  set typeParameter_bound(LinkedNodeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.typeParameter);
-    _variantField_6 = value;
-  }
-
-  set variableDeclaration_initializer(LinkedNodeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.variableDeclaration);
-    _variantField_6 = value;
-  }
-
-  set variableDeclarationList_type(LinkedNodeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.variableDeclarationList);
-    _variantField_6 = value;
-  }
-
-  set variableDeclarationStatement_variables(LinkedNodeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.variableDeclarationStatement);
-    _variantField_6 = value;
-  }
-
-  set whileStatement_body(LinkedNodeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.whileStatement);
-    _variantField_6 = value;
-  }
-
-  set yieldStatement_expression(LinkedNodeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.yieldStatement);
-    _variantField_6 = value;
-  }
-
-  @override
-  LinkedNodeBuilder get annotation_constructorName {
-    assert(kind == idl.LinkedNodeKind.annotation);
-    return _variantField_7;
-  }
-
-  @override
-  LinkedNodeBuilder get asExpression_type {
-    assert(kind == idl.LinkedNodeKind.asExpression);
-    return _variantField_7;
-  }
-
-  @override
-  LinkedNodeBuilder get assertInitializer_message {
-    assert(kind == idl.LinkedNodeKind.assertInitializer);
-    return _variantField_7;
-  }
-
-  @override
-  LinkedNodeBuilder get assertStatement_message {
-    assert(kind == idl.LinkedNodeKind.assertStatement);
-    return _variantField_7;
-  }
-
-  @override
-  LinkedNodeBuilder get assignmentExpression_rightHandSide {
-    assert(kind == idl.LinkedNodeKind.assignmentExpression);
-    return _variantField_7;
-  }
-
-  @override
-  LinkedNodeBuilder get binaryExpression_rightOperand {
-    assert(kind == idl.LinkedNodeKind.binaryExpression);
-    return _variantField_7;
-  }
-
-  @override
-  LinkedNodeBuilder get catchClause_exceptionParameter {
-    assert(kind == idl.LinkedNodeKind.catchClause);
-    return _variantField_7;
-  }
-
-  @override
-  LinkedNodeBuilder get classDeclaration_withClause {
-    assert(kind == idl.LinkedNodeKind.classDeclaration);
-    return _variantField_7;
-  }
-
-  @override
-  LinkedNodeBuilder get classTypeAlias_superclass {
-    assert(kind == idl.LinkedNodeKind.classTypeAlias);
-    return _variantField_7;
-  }
-
-  @override
-  LinkedNodeBuilder get conditionalExpression_elseExpression {
-    assert(kind == idl.LinkedNodeKind.conditionalExpression);
-    return _variantField_7;
-  }
-
-  @override
-  LinkedNodeBuilder get configuration_value {
-    assert(kind == idl.LinkedNodeKind.configuration);
-    return _variantField_7;
-  }
-
-  @override
-  LinkedNodeBuilder get constructorFieldInitializer_fieldName {
-    assert(kind == idl.LinkedNodeKind.constructorFieldInitializer);
-    return _variantField_7;
-  }
-
-  @override
-  LinkedNodeBuilder get constructorName_type {
-    assert(kind == idl.LinkedNodeKind.constructorName);
-    return _variantField_7;
-  }
-
-  @override
-  LinkedNodeBuilder get declaredIdentifier_type {
-    assert(kind == idl.LinkedNodeKind.declaredIdentifier);
-    return _variantField_7;
-  }
-
-  @override
-  LinkedNodeBuilder get defaultFormalParameter_parameter {
-    assert(kind == idl.LinkedNodeKind.defaultFormalParameter);
-    return _variantField_7;
-  }
-
-  @override
-  LinkedNodeBuilder get doStatement_condition {
-    assert(kind == idl.LinkedNodeKind.doStatement);
-    return _variantField_7;
-  }
-
-  @override
-  LinkedNodeBuilder get extensionDeclaration_extendedType {
-    assert(kind == idl.LinkedNodeKind.extensionDeclaration);
-    return _variantField_7;
-  }
-
-  @override
-  LinkedNodeBuilder get extensionOverride_extensionName {
-    assert(kind == idl.LinkedNodeKind.extensionOverride);
-    return _variantField_7;
-  }
-
-  @override
-  LinkedNodeBuilder get fieldFormalParameter_typeParameters {
-    assert(kind == idl.LinkedNodeKind.fieldFormalParameter);
-    return _variantField_7;
-  }
-
-  @override
-  LinkedNodeBuilder get forEachPartsWithDeclaration_loopVariable {
-    assert(kind == idl.LinkedNodeKind.forEachPartsWithDeclaration);
-    return _variantField_7;
-  }
-
-  @override
-  LinkedNodeBuilder get forEachPartsWithIdentifier_identifier {
-    assert(kind == idl.LinkedNodeKind.forEachPartsWithIdentifier);
-    return _variantField_7;
-  }
-
-  @override
-  LinkedNodeBuilder get forElement_body {
-    assert(kind == idl.LinkedNodeKind.forElement);
-    return _variantField_7;
-  }
-
-  @override
-  LinkedNodeBuilder get forPartsWithDeclarations_variables {
-    assert(kind == idl.LinkedNodeKind.forPartsWithDeclarations);
-    return _variantField_7;
-  }
-
-  @override
-  LinkedNodeBuilder get forPartsWithExpression_initialization {
-    assert(kind == idl.LinkedNodeKind.forPartsWithExpression);
-    return _variantField_7;
-  }
-
-  @override
-  LinkedNodeBuilder get forStatement_body {
-    assert(kind == idl.LinkedNodeKind.forStatement);
-    return _variantField_7;
-  }
-
-  @override
-  LinkedNodeBuilder get functionDeclaration_returnType {
-    assert(kind == idl.LinkedNodeKind.functionDeclaration);
-    return _variantField_7;
-  }
-
-  @override
-  LinkedNodeBuilder get functionExpression_formalParameters {
-    assert(kind == idl.LinkedNodeKind.functionExpression);
-    return _variantField_7;
-  }
-
-  @override
-  LinkedNodeBuilder get functionTypeAlias_returnType {
-    assert(kind == idl.LinkedNodeKind.functionTypeAlias);
-    return _variantField_7;
-  }
-
-  @override
-  LinkedNodeBuilder get functionTypedFormalParameter_returnType {
-    assert(kind == idl.LinkedNodeKind.functionTypedFormalParameter);
-    return _variantField_7;
-  }
-
-  @override
-  LinkedNodeBuilder get genericFunctionType_returnType {
-    assert(kind == idl.LinkedNodeKind.genericFunctionType);
-    return _variantField_7;
-  }
-
-  @override
-  LinkedNodeBuilder get genericTypeAlias_functionType {
-    assert(kind == idl.LinkedNodeKind.genericTypeAlias);
-    return _variantField_7;
-  }
-
-  @override
-  LinkedNodeBuilder get ifStatement_elseStatement {
-    assert(kind == idl.LinkedNodeKind.ifStatement);
-    return _variantField_7;
-  }
-
-  @override
-  LinkedNodeBuilder get indexExpression_target {
-    assert(kind == idl.LinkedNodeKind.indexExpression);
-    return _variantField_7;
-  }
-
-  @override
-  LinkedNodeBuilder get instanceCreationExpression_constructorName {
-    assert(kind == idl.LinkedNodeKind.instanceCreationExpression);
-    return _variantField_7;
-  }
-
-  @override
-  LinkedNodeBuilder get isExpression_type {
-    assert(kind == idl.LinkedNodeKind.isExpression);
-    return _variantField_7;
-  }
-
-  @override
-  LinkedNodeBuilder get mapLiteralEntry_value {
-    assert(kind == idl.LinkedNodeKind.mapLiteralEntry);
-    return _variantField_7;
-  }
-
-  @override
-  LinkedNodeBuilder get methodDeclaration_formalParameters {
-    assert(kind == idl.LinkedNodeKind.methodDeclaration);
-    return _variantField_7;
-  }
-
-  @override
-  LinkedNodeBuilder get methodInvocation_target {
-    assert(kind == idl.LinkedNodeKind.methodInvocation);
-    return _variantField_7;
-  }
-
-  @override
-  LinkedNodeBuilder get namedExpression_name {
-    assert(kind == idl.LinkedNodeKind.namedExpression);
-    return _variantField_7;
-  }
-
-  @override
-  LinkedNodeBuilder get partOfDirective_uri {
-    assert(kind == idl.LinkedNodeKind.partOfDirective);
-    return _variantField_7;
-  }
-
-  @override
-  LinkedNodeBuilder get prefixedIdentifier_prefix {
-    assert(kind == idl.LinkedNodeKind.prefixedIdentifier);
-    return _variantField_7;
-  }
-
-  @override
-  LinkedNodeBuilder get propertyAccess_target {
-    assert(kind == idl.LinkedNodeKind.propertyAccess);
-    return _variantField_7;
-  }
-
-  @override
-  LinkedNodeBuilder get redirectingConstructorInvocation_constructorName {
-    assert(kind == idl.LinkedNodeKind.redirectingConstructorInvocation);
-    return _variantField_7;
-  }
-
-  @override
-  LinkedNodeBuilder get superConstructorInvocation_constructorName {
-    assert(kind == idl.LinkedNodeKind.superConstructorInvocation);
-    return _variantField_7;
-  }
-
-  @override
-  LinkedNodeBuilder get switchStatement_expression {
-    assert(kind == idl.LinkedNodeKind.switchStatement);
-    return _variantField_7;
-  }
-
-  @override
-  LinkedNodeBuilder get tryStatement_finallyBlock {
-    assert(kind == idl.LinkedNodeKind.tryStatement);
-    return _variantField_7;
-  }
-
-  @override
-  LinkedNodeBuilder get whileStatement_condition {
-    assert(kind == idl.LinkedNodeKind.whileStatement);
-    return _variantField_7;
-  }
-
-  set annotation_constructorName(LinkedNodeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.annotation);
-    _variantField_7 = value;
-  }
-
-  set asExpression_type(LinkedNodeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.asExpression);
-    _variantField_7 = value;
-  }
-
-  set assertInitializer_message(LinkedNodeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.assertInitializer);
-    _variantField_7 = value;
-  }
-
-  set assertStatement_message(LinkedNodeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.assertStatement);
-    _variantField_7 = value;
-  }
-
-  set assignmentExpression_rightHandSide(LinkedNodeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.assignmentExpression);
-    _variantField_7 = value;
-  }
-
-  set binaryExpression_rightOperand(LinkedNodeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.binaryExpression);
-    _variantField_7 = value;
-  }
-
-  set catchClause_exceptionParameter(LinkedNodeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.catchClause);
-    _variantField_7 = value;
-  }
-
-  set classDeclaration_withClause(LinkedNodeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.classDeclaration);
-    _variantField_7 = value;
-  }
-
-  set classTypeAlias_superclass(LinkedNodeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.classTypeAlias);
-    _variantField_7 = value;
-  }
-
-  set conditionalExpression_elseExpression(LinkedNodeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.conditionalExpression);
-    _variantField_7 = value;
-  }
-
-  set configuration_value(LinkedNodeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.configuration);
-    _variantField_7 = value;
-  }
-
-  set constructorFieldInitializer_fieldName(LinkedNodeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.constructorFieldInitializer);
-    _variantField_7 = value;
-  }
-
-  set constructorName_type(LinkedNodeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.constructorName);
-    _variantField_7 = value;
-  }
-
-  set declaredIdentifier_type(LinkedNodeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.declaredIdentifier);
-    _variantField_7 = value;
-  }
-
-  set defaultFormalParameter_parameter(LinkedNodeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.defaultFormalParameter);
-    _variantField_7 = value;
-  }
-
-  set doStatement_condition(LinkedNodeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.doStatement);
-    _variantField_7 = value;
-  }
-
-  set extensionDeclaration_extendedType(LinkedNodeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.extensionDeclaration);
-    _variantField_7 = value;
-  }
-
-  set extensionOverride_extensionName(LinkedNodeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.extensionOverride);
-    _variantField_7 = value;
-  }
-
-  set fieldFormalParameter_typeParameters(LinkedNodeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.fieldFormalParameter);
-    _variantField_7 = value;
-  }
-
-  set forEachPartsWithDeclaration_loopVariable(LinkedNodeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.forEachPartsWithDeclaration);
-    _variantField_7 = value;
-  }
-
-  set forEachPartsWithIdentifier_identifier(LinkedNodeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.forEachPartsWithIdentifier);
-    _variantField_7 = value;
-  }
-
-  set forElement_body(LinkedNodeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.forElement);
-    _variantField_7 = value;
-  }
-
-  set forPartsWithDeclarations_variables(LinkedNodeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.forPartsWithDeclarations);
-    _variantField_7 = value;
-  }
-
-  set forPartsWithExpression_initialization(LinkedNodeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.forPartsWithExpression);
-    _variantField_7 = value;
-  }
-
-  set forStatement_body(LinkedNodeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.forStatement);
-    _variantField_7 = value;
-  }
-
-  set functionDeclaration_returnType(LinkedNodeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.functionDeclaration);
-    _variantField_7 = value;
-  }
-
-  set functionExpression_formalParameters(LinkedNodeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.functionExpression);
-    _variantField_7 = value;
-  }
-
-  set functionTypeAlias_returnType(LinkedNodeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.functionTypeAlias);
-    _variantField_7 = value;
-  }
-
-  set functionTypedFormalParameter_returnType(LinkedNodeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.functionTypedFormalParameter);
-    _variantField_7 = value;
-  }
-
-  set genericFunctionType_returnType(LinkedNodeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.genericFunctionType);
-    _variantField_7 = value;
-  }
-
-  set genericTypeAlias_functionType(LinkedNodeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.genericTypeAlias);
-    _variantField_7 = value;
-  }
-
-  set ifStatement_elseStatement(LinkedNodeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.ifStatement);
-    _variantField_7 = value;
-  }
-
-  set indexExpression_target(LinkedNodeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.indexExpression);
-    _variantField_7 = value;
-  }
-
-  set instanceCreationExpression_constructorName(LinkedNodeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.instanceCreationExpression);
-    _variantField_7 = value;
-  }
-
-  set isExpression_type(LinkedNodeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.isExpression);
-    _variantField_7 = value;
-  }
-
-  set mapLiteralEntry_value(LinkedNodeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.mapLiteralEntry);
-    _variantField_7 = value;
-  }
-
-  set methodDeclaration_formalParameters(LinkedNodeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.methodDeclaration);
-    _variantField_7 = value;
-  }
-
-  set methodInvocation_target(LinkedNodeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.methodInvocation);
-    _variantField_7 = value;
-  }
-
-  set namedExpression_name(LinkedNodeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.namedExpression);
-    _variantField_7 = value;
-  }
-
-  set partOfDirective_uri(LinkedNodeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.partOfDirective);
-    _variantField_7 = value;
-  }
-
-  set prefixedIdentifier_prefix(LinkedNodeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.prefixedIdentifier);
-    _variantField_7 = value;
-  }
-
-  set propertyAccess_target(LinkedNodeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.propertyAccess);
-    _variantField_7 = value;
-  }
-
-  set redirectingConstructorInvocation_constructorName(
-      LinkedNodeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.redirectingConstructorInvocation);
-    _variantField_7 = value;
-  }
-
-  set superConstructorInvocation_constructorName(LinkedNodeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.superConstructorInvocation);
-    _variantField_7 = value;
-  }
-
-  set switchStatement_expression(LinkedNodeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.switchStatement);
-    _variantField_7 = value;
-  }
-
-  set tryStatement_finallyBlock(LinkedNodeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.tryStatement);
-    _variantField_7 = value;
-  }
-
-  set whileStatement_condition(LinkedNodeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.whileStatement);
-    _variantField_7 = value;
-  }
-
-  @override
-  int get annotation_element {
-    assert(kind == idl.LinkedNodeKind.annotation);
-    return _variantField_17 ??= 0;
-  }
-
-  @override
-  int get genericFunctionType_id {
-    assert(kind == idl.LinkedNodeKind.genericFunctionType);
-    return _variantField_17 ??= 0;
-  }
-
-  set annotation_element(int value) {
-    assert(kind == idl.LinkedNodeKind.annotation);
-    assert(value == null || value >= 0);
-    _variantField_17 = value;
-  }
-
-  set genericFunctionType_id(int value) {
-    assert(kind == idl.LinkedNodeKind.genericFunctionType);
-    assert(value == null || value >= 0);
-    _variantField_17 = value;
-  }
-
-  @override
-  LinkedNodeBuilder get annotation_name {
-    assert(kind == idl.LinkedNodeKind.annotation);
-    return _variantField_8;
-  }
-
-  @override
-  LinkedNodeBuilder get catchClause_exceptionType {
-    assert(kind == idl.LinkedNodeKind.catchClause);
-    return _variantField_8;
-  }
-
-  @override
-  LinkedNodeBuilder get classDeclaration_nativeClause {
-    assert(kind == idl.LinkedNodeKind.classDeclaration);
-    return _variantField_8;
-  }
-
-  @override
-  LinkedNodeBuilder get classTypeAlias_withClause {
-    assert(kind == idl.LinkedNodeKind.classTypeAlias);
-    return _variantField_8;
-  }
-
-  @override
-  LinkedNodeBuilder get conditionalExpression_thenExpression {
-    assert(kind == idl.LinkedNodeKind.conditionalExpression);
-    return _variantField_8;
-  }
-
-  @override
-  LinkedNodeBuilder get configuration_uri {
-    assert(kind == idl.LinkedNodeKind.configuration);
-    return _variantField_8;
-  }
-
-  @override
-  LinkedNodeBuilder get constructorDeclaration_parameters {
-    assert(kind == idl.LinkedNodeKind.constructorDeclaration);
-    return _variantField_8;
-  }
-
-  @override
-  LinkedNodeBuilder get extensionOverride_typeArguments {
-    assert(kind == idl.LinkedNodeKind.extensionOverride);
-    return _variantField_8;
-  }
-
-  @override
-  LinkedNodeBuilder get fieldFormalParameter_formalParameters {
-    assert(kind == idl.LinkedNodeKind.fieldFormalParameter);
-    return _variantField_8;
-  }
-
-  @override
-  LinkedNodeBuilder get functionExpression_typeParameters {
-    assert(kind == idl.LinkedNodeKind.functionExpression);
-    return _variantField_8;
-  }
-
-  @override
-  LinkedNodeBuilder get functionTypeAlias_typeParameters {
-    assert(kind == idl.LinkedNodeKind.functionTypeAlias);
-    return _variantField_8;
-  }
-
-  @override
-  LinkedNodeBuilder get functionTypedFormalParameter_typeParameters {
-    assert(kind == idl.LinkedNodeKind.functionTypedFormalParameter);
-    return _variantField_8;
-  }
-
-  @override
-  LinkedNodeBuilder get genericFunctionType_formalParameters {
-    assert(kind == idl.LinkedNodeKind.genericFunctionType);
-    return _variantField_8;
-  }
-
-  @override
-  LinkedNodeBuilder get ifElement_thenElement {
-    assert(kind == idl.LinkedNodeKind.ifElement);
-    return _variantField_8;
-  }
-
-  @override
-  LinkedNodeBuilder get ifStatement_thenStatement {
-    assert(kind == idl.LinkedNodeKind.ifStatement);
-    return _variantField_8;
-  }
-
-  @override
-  LinkedNodeBuilder get instanceCreationExpression_typeArguments {
-    assert(kind == idl.LinkedNodeKind.instanceCreationExpression);
-    return _variantField_8;
-  }
-
-  @override
-  LinkedNodeBuilder get methodDeclaration_returnType {
-    assert(kind == idl.LinkedNodeKind.methodDeclaration);
-    return _variantField_8;
-  }
-
-  set annotation_name(LinkedNodeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.annotation);
-    _variantField_8 = value;
-  }
-
-  set catchClause_exceptionType(LinkedNodeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.catchClause);
-    _variantField_8 = value;
-  }
-
-  set classDeclaration_nativeClause(LinkedNodeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.classDeclaration);
-    _variantField_8 = value;
-  }
-
-  set classTypeAlias_withClause(LinkedNodeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.classTypeAlias);
-    _variantField_8 = value;
-  }
-
-  set conditionalExpression_thenExpression(LinkedNodeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.conditionalExpression);
-    _variantField_8 = value;
-  }
-
-  set configuration_uri(LinkedNodeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.configuration);
-    _variantField_8 = value;
-  }
-
-  set constructorDeclaration_parameters(LinkedNodeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.constructorDeclaration);
-    _variantField_8 = value;
-  }
-
-  set extensionOverride_typeArguments(LinkedNodeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.extensionOverride);
-    _variantField_8 = value;
-  }
-
-  set fieldFormalParameter_formalParameters(LinkedNodeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.fieldFormalParameter);
-    _variantField_8 = value;
-  }
-
-  set functionExpression_typeParameters(LinkedNodeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.functionExpression);
-    _variantField_8 = value;
-  }
-
-  set functionTypeAlias_typeParameters(LinkedNodeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.functionTypeAlias);
-    _variantField_8 = value;
-  }
-
-  set functionTypedFormalParameter_typeParameters(LinkedNodeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.functionTypedFormalParameter);
-    _variantField_8 = value;
-  }
-
-  set genericFunctionType_formalParameters(LinkedNodeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.genericFunctionType);
-    _variantField_8 = value;
-  }
-
-  set ifElement_thenElement(LinkedNodeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.ifElement);
-    _variantField_8 = value;
-  }
-
-  set ifStatement_thenStatement(LinkedNodeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.ifStatement);
-    _variantField_8 = value;
-  }
-
-  set instanceCreationExpression_typeArguments(LinkedNodeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.instanceCreationExpression);
-    _variantField_8 = value;
-  }
-
-  set methodDeclaration_returnType(LinkedNodeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.methodDeclaration);
-    _variantField_8 = value;
-  }
-
-  @override
-  LinkedNodeTypeSubstitutionBuilder get annotation_substitution {
-    assert(kind == idl.LinkedNodeKind.annotation);
-    return _variantField_38;
-  }
-
-  @override
-  LinkedNodeTypeSubstitutionBuilder get assignmentExpression_substitution {
-    assert(kind == idl.LinkedNodeKind.assignmentExpression);
-    return _variantField_38;
-  }
-
-  @override
-  LinkedNodeTypeSubstitutionBuilder get binaryExpression_substitution {
-    assert(kind == idl.LinkedNodeKind.binaryExpression);
-    return _variantField_38;
-  }
-
-  @override
-  LinkedNodeTypeSubstitutionBuilder get constructorName_substitution {
-    assert(kind == idl.LinkedNodeKind.constructorName);
-    return _variantField_38;
-  }
-
-  @override
-  LinkedNodeTypeSubstitutionBuilder get indexExpression_substitution {
-    assert(kind == idl.LinkedNodeKind.indexExpression);
-    return _variantField_38;
-  }
-
-  @override
-  LinkedNodeTypeSubstitutionBuilder get postfixExpression_substitution {
-    assert(kind == idl.LinkedNodeKind.postfixExpression);
-    return _variantField_38;
-  }
-
-  @override
-  LinkedNodeTypeSubstitutionBuilder get prefixExpression_substitution {
-    assert(kind == idl.LinkedNodeKind.prefixExpression);
-    return _variantField_38;
-  }
-
-  @override
-  LinkedNodeTypeSubstitutionBuilder
-      get redirectingConstructorInvocation_substitution {
-    assert(kind == idl.LinkedNodeKind.redirectingConstructorInvocation);
-    return _variantField_38;
-  }
-
-  @override
-  LinkedNodeTypeSubstitutionBuilder get simpleIdentifier_substitution {
-    assert(kind == idl.LinkedNodeKind.simpleIdentifier);
-    return _variantField_38;
-  }
-
-  @override
-  LinkedNodeTypeSubstitutionBuilder
-      get superConstructorInvocation_substitution {
-    assert(kind == idl.LinkedNodeKind.superConstructorInvocation);
-    return _variantField_38;
-  }
-
-  set annotation_substitution(LinkedNodeTypeSubstitutionBuilder value) {
-    assert(kind == idl.LinkedNodeKind.annotation);
-    _variantField_38 = value;
-  }
-
-  set assignmentExpression_substitution(
-      LinkedNodeTypeSubstitutionBuilder value) {
-    assert(kind == idl.LinkedNodeKind.assignmentExpression);
-    _variantField_38 = value;
-  }
-
-  set binaryExpression_substitution(LinkedNodeTypeSubstitutionBuilder value) {
-    assert(kind == idl.LinkedNodeKind.binaryExpression);
-    _variantField_38 = value;
-  }
-
-  set constructorName_substitution(LinkedNodeTypeSubstitutionBuilder value) {
-    assert(kind == idl.LinkedNodeKind.constructorName);
-    _variantField_38 = value;
-  }
-
-  set indexExpression_substitution(LinkedNodeTypeSubstitutionBuilder value) {
-    assert(kind == idl.LinkedNodeKind.indexExpression);
-    _variantField_38 = value;
-  }
-
-  set postfixExpression_substitution(LinkedNodeTypeSubstitutionBuilder value) {
-    assert(kind == idl.LinkedNodeKind.postfixExpression);
-    _variantField_38 = value;
-  }
-
-  set prefixExpression_substitution(LinkedNodeTypeSubstitutionBuilder value) {
-    assert(kind == idl.LinkedNodeKind.prefixExpression);
-    _variantField_38 = value;
-  }
-
-  set redirectingConstructorInvocation_substitution(
-      LinkedNodeTypeSubstitutionBuilder value) {
-    assert(kind == idl.LinkedNodeKind.redirectingConstructorInvocation);
-    _variantField_38 = value;
-  }
-
-  set simpleIdentifier_substitution(LinkedNodeTypeSubstitutionBuilder value) {
-    assert(kind == idl.LinkedNodeKind.simpleIdentifier);
-    _variantField_38 = value;
-  }
-
-  set superConstructorInvocation_substitution(
-      LinkedNodeTypeSubstitutionBuilder value) {
-    assert(kind == idl.LinkedNodeKind.superConstructorInvocation);
-    _variantField_38 = value;
-  }
-
-  @override
-  int get assignmentExpression_element {
-    assert(kind == idl.LinkedNodeKind.assignmentExpression);
-    return _variantField_15 ??= 0;
-  }
-
-  @override
-  int get binaryExpression_element {
-    assert(kind == idl.LinkedNodeKind.binaryExpression);
-    return _variantField_15 ??= 0;
-  }
-
-  @override
-  int get constructorName_element {
-    assert(kind == idl.LinkedNodeKind.constructorName);
-    return _variantField_15 ??= 0;
-  }
-
-  @override
-  int get emptyFunctionBody_fake {
-    assert(kind == idl.LinkedNodeKind.emptyFunctionBody);
-    return _variantField_15 ??= 0;
-  }
-
-  @override
-  int get emptyStatement_fake {
-    assert(kind == idl.LinkedNodeKind.emptyStatement);
-    return _variantField_15 ??= 0;
-  }
-
-  @override
-  int get indexExpression_element {
-    assert(kind == idl.LinkedNodeKind.indexExpression);
-    return _variantField_15 ??= 0;
-  }
-
-  @override
-  int get nullLiteral_fake {
-    assert(kind == idl.LinkedNodeKind.nullLiteral);
-    return _variantField_15 ??= 0;
-  }
-
-  @override
-  int get postfixExpression_element {
-    assert(kind == idl.LinkedNodeKind.postfixExpression);
-    return _variantField_15 ??= 0;
-  }
-
-  @override
-  int get prefixExpression_element {
-    assert(kind == idl.LinkedNodeKind.prefixExpression);
-    return _variantField_15 ??= 0;
-  }
-
-  @override
-  int get redirectingConstructorInvocation_element {
-    assert(kind == idl.LinkedNodeKind.redirectingConstructorInvocation);
-    return _variantField_15 ??= 0;
-  }
-
-  @override
-  int get simpleIdentifier_element {
-    assert(kind == idl.LinkedNodeKind.simpleIdentifier);
-    return _variantField_15 ??= 0;
-  }
-
-  @override
-  int get superConstructorInvocation_element {
-    assert(kind == idl.LinkedNodeKind.superConstructorInvocation);
-    return _variantField_15 ??= 0;
-  }
-
-  @override
-  int get typeParameter_variance {
-    assert(kind == idl.LinkedNodeKind.typeParameter);
-    return _variantField_15 ??= 0;
-  }
-
-  set assignmentExpression_element(int value) {
-    assert(kind == idl.LinkedNodeKind.assignmentExpression);
-    assert(value == null || value >= 0);
-    _variantField_15 = value;
-  }
-
-  set binaryExpression_element(int value) {
-    assert(kind == idl.LinkedNodeKind.binaryExpression);
-    assert(value == null || value >= 0);
-    _variantField_15 = value;
-  }
-
-  set constructorName_element(int value) {
-    assert(kind == idl.LinkedNodeKind.constructorName);
-    assert(value == null || value >= 0);
-    _variantField_15 = value;
-  }
-
-  set emptyFunctionBody_fake(int value) {
-    assert(kind == idl.LinkedNodeKind.emptyFunctionBody);
-    assert(value == null || value >= 0);
-    _variantField_15 = value;
-  }
-
-  set emptyStatement_fake(int value) {
-    assert(kind == idl.LinkedNodeKind.emptyStatement);
-    assert(value == null || value >= 0);
-    _variantField_15 = value;
-  }
-
-  set indexExpression_element(int value) {
-    assert(kind == idl.LinkedNodeKind.indexExpression);
-    assert(value == null || value >= 0);
-    _variantField_15 = value;
-  }
-
-  set nullLiteral_fake(int value) {
-    assert(kind == idl.LinkedNodeKind.nullLiteral);
-    assert(value == null || value >= 0);
-    _variantField_15 = value;
-  }
-
-  set postfixExpression_element(int value) {
-    assert(kind == idl.LinkedNodeKind.postfixExpression);
-    assert(value == null || value >= 0);
-    _variantField_15 = value;
-  }
-
-  set prefixExpression_element(int value) {
-    assert(kind == idl.LinkedNodeKind.prefixExpression);
-    assert(value == null || value >= 0);
-    _variantField_15 = value;
-  }
-
-  set redirectingConstructorInvocation_element(int value) {
-    assert(kind == idl.LinkedNodeKind.redirectingConstructorInvocation);
-    assert(value == null || value >= 0);
-    _variantField_15 = value;
-  }
-
-  set simpleIdentifier_element(int value) {
-    assert(kind == idl.LinkedNodeKind.simpleIdentifier);
-    assert(value == null || value >= 0);
-    _variantField_15 = value;
-  }
-
-  set superConstructorInvocation_element(int value) {
-    assert(kind == idl.LinkedNodeKind.superConstructorInvocation);
-    assert(value == null || value >= 0);
-    _variantField_15 = value;
-  }
-
-  set typeParameter_variance(int value) {
-    assert(kind == idl.LinkedNodeKind.typeParameter);
-    assert(value == null || value >= 0);
-    _variantField_15 = value;
-  }
-
-  @override
-  idl.UnlinkedTokenType get assignmentExpression_operator {
-    assert(kind == idl.LinkedNodeKind.assignmentExpression);
-    return _variantField_28 ??= idl.UnlinkedTokenType.NOTHING;
-  }
-
-  @override
-  idl.UnlinkedTokenType get binaryExpression_operator {
-    assert(kind == idl.LinkedNodeKind.binaryExpression);
-    return _variantField_28 ??= idl.UnlinkedTokenType.NOTHING;
-  }
-
-  @override
-  idl.UnlinkedTokenType get postfixExpression_operator {
-    assert(kind == idl.LinkedNodeKind.postfixExpression);
-    return _variantField_28 ??= idl.UnlinkedTokenType.NOTHING;
-  }
-
-  @override
-  idl.UnlinkedTokenType get prefixExpression_operator {
-    assert(kind == idl.LinkedNodeKind.prefixExpression);
-    return _variantField_28 ??= idl.UnlinkedTokenType.NOTHING;
-  }
-
-  @override
-  idl.UnlinkedTokenType get propertyAccess_operator {
-    assert(kind == idl.LinkedNodeKind.propertyAccess);
-    return _variantField_28 ??= idl.UnlinkedTokenType.NOTHING;
-  }
-
-  set assignmentExpression_operator(idl.UnlinkedTokenType value) {
-    assert(kind == idl.LinkedNodeKind.assignmentExpression);
-    _variantField_28 = value;
-  }
-
-  set binaryExpression_operator(idl.UnlinkedTokenType value) {
-    assert(kind == idl.LinkedNodeKind.binaryExpression);
-    _variantField_28 = value;
-  }
-
-  set postfixExpression_operator(idl.UnlinkedTokenType value) {
-    assert(kind == idl.LinkedNodeKind.postfixExpression);
-    _variantField_28 = value;
-  }
-
-  set prefixExpression_operator(idl.UnlinkedTokenType value) {
-    assert(kind == idl.LinkedNodeKind.prefixExpression);
-    _variantField_28 = value;
-  }
-
-  set propertyAccess_operator(idl.UnlinkedTokenType value) {
-    assert(kind == idl.LinkedNodeKind.propertyAccess);
-    _variantField_28 = value;
-  }
-
-  @override
-  bool get booleanLiteral_value {
-    assert(kind == idl.LinkedNodeKind.booleanLiteral);
-    return _variantField_27 ??= false;
-  }
-
-  @override
-  bool get classDeclaration_isDartObject {
-    assert(kind == idl.LinkedNodeKind.classDeclaration);
-    return _variantField_27 ??= false;
-  }
-
-  @override
-  bool get inheritsCovariant {
-    assert(kind == idl.LinkedNodeKind.fieldFormalParameter ||
-        kind == idl.LinkedNodeKind.functionTypedFormalParameter ||
-        kind == idl.LinkedNodeKind.simpleFormalParameter ||
-        kind == idl.LinkedNodeKind.variableDeclaration);
-    return _variantField_27 ??= false;
-  }
-
-  @override
-  bool get typeAlias_hasSelfReference {
-    assert(kind == idl.LinkedNodeKind.functionTypeAlias ||
-        kind == idl.LinkedNodeKind.genericTypeAlias);
-    return _variantField_27 ??= false;
-  }
-
-  set booleanLiteral_value(bool value) {
-    assert(kind == idl.LinkedNodeKind.booleanLiteral);
-    _variantField_27 = value;
-  }
-
-  set classDeclaration_isDartObject(bool value) {
-    assert(kind == idl.LinkedNodeKind.classDeclaration);
-    _variantField_27 = value;
-  }
-
-  set inheritsCovariant(bool value) {
-    assert(kind == idl.LinkedNodeKind.fieldFormalParameter ||
-        kind == idl.LinkedNodeKind.functionTypedFormalParameter ||
-        kind == idl.LinkedNodeKind.simpleFormalParameter ||
-        kind == idl.LinkedNodeKind.variableDeclaration);
-    _variantField_27 = value;
-  }
-
-  set typeAlias_hasSelfReference(bool value) {
-    assert(kind == idl.LinkedNodeKind.functionTypeAlias ||
-        kind == idl.LinkedNodeKind.genericTypeAlias);
-    _variantField_27 = value;
-  }
-
-  @override
-  LinkedNodeBuilder get catchClause_stackTraceParameter {
-    assert(kind == idl.LinkedNodeKind.catchClause);
-    return _variantField_9;
-  }
-
-  @override
-  LinkedNodeBuilder get classTypeAlias_implementsClause {
-    assert(kind == idl.LinkedNodeKind.classTypeAlias);
-    return _variantField_9;
-  }
-
-  @override
-  LinkedNodeBuilder get constructorDeclaration_redirectedConstructor {
-    assert(kind == idl.LinkedNodeKind.constructorDeclaration);
-    return _variantField_9;
-  }
-
-  @override
-  LinkedNodeBuilder get ifElement_elseElement {
-    assert(kind == idl.LinkedNodeKind.ifElement);
-    return _variantField_9;
-  }
-
-  @override
-  LinkedNodeBuilder get methodDeclaration_typeParameters {
-    assert(kind == idl.LinkedNodeKind.methodDeclaration);
-    return _variantField_9;
-  }
-
-  set catchClause_stackTraceParameter(LinkedNodeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.catchClause);
-    _variantField_9 = value;
-  }
-
-  set classTypeAlias_implementsClause(LinkedNodeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.classTypeAlias);
-    _variantField_9 = value;
-  }
-
-  set constructorDeclaration_redirectedConstructor(LinkedNodeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.constructorDeclaration);
-    _variantField_9 = value;
-  }
-
-  set ifElement_elseElement(LinkedNodeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.ifElement);
-    _variantField_9 = value;
-  }
-
-  set methodDeclaration_typeParameters(LinkedNodeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.methodDeclaration);
-    _variantField_9 = value;
-  }
-
-  @override
-  LinkedNodeBuilder get classOrMixinDeclaration_implementsClause {
-    assert(kind == idl.LinkedNodeKind.classDeclaration ||
-        kind == idl.LinkedNodeKind.mixinDeclaration);
-    return _variantField_12;
-  }
-
-  @override
-  LinkedNodeBuilder get invocationExpression_typeArguments {
-    assert(kind == idl.LinkedNodeKind.functionExpressionInvocation ||
-        kind == idl.LinkedNodeKind.methodInvocation);
-    return _variantField_12;
-  }
-
-  set classOrMixinDeclaration_implementsClause(LinkedNodeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.classDeclaration ||
-        kind == idl.LinkedNodeKind.mixinDeclaration);
-    _variantField_12 = value;
-  }
-
-  set invocationExpression_typeArguments(LinkedNodeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.functionExpressionInvocation ||
-        kind == idl.LinkedNodeKind.methodInvocation);
-    _variantField_12 = value;
-  }
-
-  @override
-  List<LinkedNodeBuilder> get classOrMixinDeclaration_members {
-    assert(kind == idl.LinkedNodeKind.classDeclaration ||
-        kind == idl.LinkedNodeKind.mixinDeclaration);
-    return _variantField_5 ??= <LinkedNodeBuilder>[];
-  }
-
-  @override
-  List<LinkedNodeBuilder> get extensionDeclaration_members {
-    assert(kind == idl.LinkedNodeKind.extensionDeclaration);
-    return _variantField_5 ??= <LinkedNodeBuilder>[];
-  }
-
-  @override
-  List<LinkedNodeBuilder> get forParts_updaters {
-    assert(kind == idl.LinkedNodeKind.forPartsWithDeclarations ||
-        kind == idl.LinkedNodeKind.forPartsWithExpression);
-    return _variantField_5 ??= <LinkedNodeBuilder>[];
-  }
-
-  set classOrMixinDeclaration_members(List<LinkedNodeBuilder> value) {
-    assert(kind == idl.LinkedNodeKind.classDeclaration ||
-        kind == idl.LinkedNodeKind.mixinDeclaration);
-    _variantField_5 = value;
-  }
-
-  set extensionDeclaration_members(List<LinkedNodeBuilder> value) {
-    assert(kind == idl.LinkedNodeKind.extensionDeclaration);
-    _variantField_5 = value;
-  }
-
-  set forParts_updaters(List<LinkedNodeBuilder> value) {
-    assert(kind == idl.LinkedNodeKind.forPartsWithDeclarations ||
-        kind == idl.LinkedNodeKind.forPartsWithExpression);
-    _variantField_5 = value;
-  }
-
-  @override
-  LinkedNodeBuilder get classOrMixinDeclaration_typeParameters {
-    assert(kind == idl.LinkedNodeKind.classDeclaration ||
-        kind == idl.LinkedNodeKind.mixinDeclaration);
-    return _variantField_13;
-  }
-
-  set classOrMixinDeclaration_typeParameters(LinkedNodeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.classDeclaration ||
-        kind == idl.LinkedNodeKind.mixinDeclaration);
-    _variantField_13 = value;
-  }
-
-  @override
-  List<String> get comment_tokens {
-    assert(kind == idl.LinkedNodeKind.comment);
-    return _variantField_33 ??= <String>[];
-  }
-
-  set comment_tokens(List<String> value) {
-    assert(kind == idl.LinkedNodeKind.comment);
-    _variantField_33 = value;
-  }
-
-  @override
-  idl.LinkedNodeCommentType get comment_type {
-    assert(kind == idl.LinkedNodeKind.comment);
-    return _variantField_29 ??= idl.LinkedNodeCommentType.block;
-  }
-
-  set comment_type(idl.LinkedNodeCommentType value) {
-    assert(kind == idl.LinkedNodeKind.comment);
-    _variantField_29 = value;
-  }
-
-  @override
-  List<LinkedNodeBuilder> get compilationUnit_directives {
-    assert(kind == idl.LinkedNodeKind.compilationUnit);
-    return _variantField_3 ??= <LinkedNodeBuilder>[];
-  }
-
-  @override
-  List<LinkedNodeBuilder> get listLiteral_elements {
-    assert(kind == idl.LinkedNodeKind.listLiteral);
-    return _variantField_3 ??= <LinkedNodeBuilder>[];
-  }
-
-  @override
-  List<LinkedNodeBuilder> get namespaceDirective_configurations {
-    assert(kind == idl.LinkedNodeKind.exportDirective ||
-        kind == idl.LinkedNodeKind.importDirective);
-    return _variantField_3 ??= <LinkedNodeBuilder>[];
-  }
-
-  @override
-  List<LinkedNodeBuilder> get setOrMapLiteral_elements {
-    assert(kind == idl.LinkedNodeKind.setOrMapLiteral);
-    return _variantField_3 ??= <LinkedNodeBuilder>[];
-  }
-
-  @override
-  List<LinkedNodeBuilder> get switchMember_labels {
-    assert(kind == idl.LinkedNodeKind.switchCase ||
-        kind == idl.LinkedNodeKind.switchDefault);
-    return _variantField_3 ??= <LinkedNodeBuilder>[];
-  }
-
-  set compilationUnit_directives(List<LinkedNodeBuilder> value) {
-    assert(kind == idl.LinkedNodeKind.compilationUnit);
-    _variantField_3 = value;
-  }
-
-  set listLiteral_elements(List<LinkedNodeBuilder> value) {
-    assert(kind == idl.LinkedNodeKind.listLiteral);
-    _variantField_3 = value;
-  }
-
-  set namespaceDirective_configurations(List<LinkedNodeBuilder> value) {
-    assert(kind == idl.LinkedNodeKind.exportDirective ||
-        kind == idl.LinkedNodeKind.importDirective);
-    _variantField_3 = value;
-  }
-
-  set setOrMapLiteral_elements(List<LinkedNodeBuilder> value) {
-    assert(kind == idl.LinkedNodeKind.setOrMapLiteral);
-    _variantField_3 = value;
-  }
-
-  set switchMember_labels(List<LinkedNodeBuilder> value) {
-    assert(kind == idl.LinkedNodeKind.switchCase ||
-        kind == idl.LinkedNodeKind.switchDefault);
-    _variantField_3 = value;
-  }
-
-  @override
-  List<int> get compilationUnit_featureSet {
-    assert(kind == idl.LinkedNodeKind.compilationUnit);
-    return _variantField_41 ??= <int>[];
-  }
-
-  set compilationUnit_featureSet(List<int> value) {
-    assert(kind == idl.LinkedNodeKind.compilationUnit);
-    assert(value == null || value.every((e) => e >= 0));
-    _variantField_41 = value;
-  }
-
-  @override
-  LinkedLibraryLanguageVersionBuilder get compilationUnit_languageVersion {
-    assert(kind == idl.LinkedNodeKind.compilationUnit);
-    return _variantField_40;
-  }
-
-  /// The language version information.
-  set compilationUnit_languageVersion(
-      LinkedLibraryLanguageVersionBuilder value) {
-    assert(kind == idl.LinkedNodeKind.compilationUnit);
-    _variantField_40 = value;
-  }
-
-  @override
-  LinkedNodeBuilder get constructorDeclaration_returnType {
-    assert(kind == idl.LinkedNodeKind.constructorDeclaration);
-    return _variantField_10;
-  }
-
-  set constructorDeclaration_returnType(LinkedNodeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.constructorDeclaration);
-    _variantField_10 = value;
-  }
-
-  @override
-  idl.LinkedNodeFormalParameterKind get defaultFormalParameter_kind {
-    assert(kind == idl.LinkedNodeKind.defaultFormalParameter);
-    return _variantField_26 ??=
-        idl.LinkedNodeFormalParameterKind.requiredPositional;
-  }
-
-  set defaultFormalParameter_kind(idl.LinkedNodeFormalParameterKind value) {
-    assert(kind == idl.LinkedNodeKind.defaultFormalParameter);
-    _variantField_26 = value;
-  }
-
-  @override
-  double get doubleLiteral_value {
-    assert(kind == idl.LinkedNodeKind.doubleLiteral);
-    return _variantField_21 ??= 0.0;
-  }
-
-  set doubleLiteral_value(double value) {
-    assert(kind == idl.LinkedNodeKind.doubleLiteral);
-    _variantField_21 = value;
-  }
-
-  @override
-  LinkedNodeTypeBuilder get expression_type {
-    assert(kind == idl.LinkedNodeKind.assignmentExpression ||
-        kind == idl.LinkedNodeKind.asExpression ||
-        kind == idl.LinkedNodeKind.awaitExpression ||
-        kind == idl.LinkedNodeKind.binaryExpression ||
-        kind == idl.LinkedNodeKind.cascadeExpression ||
-        kind == idl.LinkedNodeKind.conditionalExpression ||
-        kind == idl.LinkedNodeKind.functionExpressionInvocation ||
-        kind == idl.LinkedNodeKind.indexExpression ||
-        kind == idl.LinkedNodeKind.instanceCreationExpression ||
-        kind == idl.LinkedNodeKind.integerLiteral ||
-        kind == idl.LinkedNodeKind.listLiteral ||
-        kind == idl.LinkedNodeKind.methodInvocation ||
-        kind == idl.LinkedNodeKind.nullLiteral ||
-        kind == idl.LinkedNodeKind.parenthesizedExpression ||
-        kind == idl.LinkedNodeKind.prefixExpression ||
-        kind == idl.LinkedNodeKind.prefixedIdentifier ||
-        kind == idl.LinkedNodeKind.propertyAccess ||
-        kind == idl.LinkedNodeKind.postfixExpression ||
-        kind == idl.LinkedNodeKind.rethrowExpression ||
-        kind == idl.LinkedNodeKind.setOrMapLiteral ||
-        kind == idl.LinkedNodeKind.simpleIdentifier ||
-        kind == idl.LinkedNodeKind.superExpression ||
-        kind == idl.LinkedNodeKind.symbolLiteral ||
-        kind == idl.LinkedNodeKind.thisExpression ||
-        kind == idl.LinkedNodeKind.throwExpression);
-    return _variantField_25;
-  }
-
-  @override
-  LinkedNodeTypeBuilder get genericFunctionType_type {
-    assert(kind == idl.LinkedNodeKind.genericFunctionType);
-    return _variantField_25;
-  }
-
-  set expression_type(LinkedNodeTypeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.assignmentExpression ||
-        kind == idl.LinkedNodeKind.asExpression ||
-        kind == idl.LinkedNodeKind.awaitExpression ||
-        kind == idl.LinkedNodeKind.binaryExpression ||
-        kind == idl.LinkedNodeKind.cascadeExpression ||
-        kind == idl.LinkedNodeKind.conditionalExpression ||
-        kind == idl.LinkedNodeKind.functionExpressionInvocation ||
-        kind == idl.LinkedNodeKind.indexExpression ||
-        kind == idl.LinkedNodeKind.instanceCreationExpression ||
-        kind == idl.LinkedNodeKind.integerLiteral ||
-        kind == idl.LinkedNodeKind.listLiteral ||
-        kind == idl.LinkedNodeKind.methodInvocation ||
-        kind == idl.LinkedNodeKind.nullLiteral ||
-        kind == idl.LinkedNodeKind.parenthesizedExpression ||
-        kind == idl.LinkedNodeKind.prefixExpression ||
-        kind == idl.LinkedNodeKind.prefixedIdentifier ||
-        kind == idl.LinkedNodeKind.propertyAccess ||
-        kind == idl.LinkedNodeKind.postfixExpression ||
-        kind == idl.LinkedNodeKind.rethrowExpression ||
-        kind == idl.LinkedNodeKind.setOrMapLiteral ||
-        kind == idl.LinkedNodeKind.simpleIdentifier ||
-        kind == idl.LinkedNodeKind.superExpression ||
-        kind == idl.LinkedNodeKind.symbolLiteral ||
-        kind == idl.LinkedNodeKind.thisExpression ||
-        kind == idl.LinkedNodeKind.throwExpression);
-    _variantField_25 = value;
-  }
-
-  set genericFunctionType_type(LinkedNodeTypeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.genericFunctionType);
-    _variantField_25 = value;
-  }
-
-  @override
-  String get extensionDeclaration_refName {
-    assert(kind == idl.LinkedNodeKind.extensionDeclaration);
-    return _variantField_20 ??= '';
-  }
-
-  @override
-  String get namespaceDirective_selectedUri {
-    assert(kind == idl.LinkedNodeKind.exportDirective ||
-        kind == idl.LinkedNodeKind.importDirective);
-    return _variantField_20 ??= '';
-  }
-
-  @override
-  String get simpleStringLiteral_value {
-    assert(kind == idl.LinkedNodeKind.simpleStringLiteral);
-    return _variantField_20 ??= '';
-  }
-
-  set extensionDeclaration_refName(String value) {
-    assert(kind == idl.LinkedNodeKind.extensionDeclaration);
-    _variantField_20 = value;
-  }
-
-  set namespaceDirective_selectedUri(String value) {
-    assert(kind == idl.LinkedNodeKind.exportDirective ||
-        kind == idl.LinkedNodeKind.importDirective);
-    _variantField_20 = value;
-  }
-
-  set simpleStringLiteral_value(String value) {
-    assert(kind == idl.LinkedNodeKind.simpleStringLiteral);
-    _variantField_20 = value;
-  }
-
-  @override
-  List<LinkedNodeTypeBuilder> get extensionOverride_typeArgumentTypes {
-    assert(kind == idl.LinkedNodeKind.extensionOverride);
-    return _variantField_39 ??= <LinkedNodeTypeBuilder>[];
-  }
-
-  set extensionOverride_typeArgumentTypes(List<LinkedNodeTypeBuilder> value) {
-    assert(kind == idl.LinkedNodeKind.extensionOverride);
-    _variantField_39 = value;
-  }
-
-  @override
-  int get flags => _flags ??= 0;
-
-  set flags(int value) {
-    assert(value == null || value >= 0);
-    this._flags = value;
-  }
-
-  @override
-  String get importDirective_prefix {
-    assert(kind == idl.LinkedNodeKind.importDirective);
-    return _variantField_1 ??= '';
-  }
-
-  set importDirective_prefix(String value) {
-    assert(kind == idl.LinkedNodeKind.importDirective);
-    _variantField_1 = value;
-  }
-
-  @override
-  int get informativeId {
-    assert(kind == idl.LinkedNodeKind.classDeclaration ||
-        kind == idl.LinkedNodeKind.classTypeAlias ||
-        kind == idl.LinkedNodeKind.compilationUnit ||
-        kind == idl.LinkedNodeKind.compilationUnit ||
-        kind == idl.LinkedNodeKind.constructorDeclaration ||
-        kind == idl.LinkedNodeKind.defaultFormalParameter ||
-        kind == idl.LinkedNodeKind.enumConstantDeclaration ||
-        kind == idl.LinkedNodeKind.enumDeclaration ||
-        kind == idl.LinkedNodeKind.exportDirective ||
-        kind == idl.LinkedNodeKind.extensionDeclaration ||
-        kind == idl.LinkedNodeKind.fieldDeclaration ||
-        kind == idl.LinkedNodeKind.fieldFormalParameter ||
-        kind == idl.LinkedNodeKind.functionDeclaration ||
-        kind == idl.LinkedNodeKind.functionTypedFormalParameter ||
-        kind == idl.LinkedNodeKind.functionTypeAlias ||
-        kind == idl.LinkedNodeKind.genericTypeAlias ||
-        kind == idl.LinkedNodeKind.hideCombinator ||
-        kind == idl.LinkedNodeKind.importDirective ||
-        kind == idl.LinkedNodeKind.libraryDirective ||
-        kind == idl.LinkedNodeKind.methodDeclaration ||
-        kind == idl.LinkedNodeKind.mixinDeclaration ||
-        kind == idl.LinkedNodeKind.partDirective ||
-        kind == idl.LinkedNodeKind.partOfDirective ||
-        kind == idl.LinkedNodeKind.showCombinator ||
-        kind == idl.LinkedNodeKind.simpleFormalParameter ||
-        kind == idl.LinkedNodeKind.topLevelVariableDeclaration ||
-        kind == idl.LinkedNodeKind.typeParameter ||
-        kind == idl.LinkedNodeKind.variableDeclaration ||
-        kind == idl.LinkedNodeKind.variableDeclarationList);
-    return _variantField_36 ??= 0;
-  }
-
-  set informativeId(int value) {
-    assert(kind == idl.LinkedNodeKind.classDeclaration ||
-        kind == idl.LinkedNodeKind.classTypeAlias ||
-        kind == idl.LinkedNodeKind.compilationUnit ||
-        kind == idl.LinkedNodeKind.compilationUnit ||
-        kind == idl.LinkedNodeKind.constructorDeclaration ||
-        kind == idl.LinkedNodeKind.defaultFormalParameter ||
-        kind == idl.LinkedNodeKind.enumConstantDeclaration ||
-        kind == idl.LinkedNodeKind.enumDeclaration ||
-        kind == idl.LinkedNodeKind.exportDirective ||
-        kind == idl.LinkedNodeKind.extensionDeclaration ||
-        kind == idl.LinkedNodeKind.fieldDeclaration ||
-        kind == idl.LinkedNodeKind.fieldFormalParameter ||
-        kind == idl.LinkedNodeKind.functionDeclaration ||
-        kind == idl.LinkedNodeKind.functionTypedFormalParameter ||
-        kind == idl.LinkedNodeKind.functionTypeAlias ||
-        kind == idl.LinkedNodeKind.genericTypeAlias ||
-        kind == idl.LinkedNodeKind.hideCombinator ||
-        kind == idl.LinkedNodeKind.importDirective ||
-        kind == idl.LinkedNodeKind.libraryDirective ||
-        kind == idl.LinkedNodeKind.methodDeclaration ||
-        kind == idl.LinkedNodeKind.mixinDeclaration ||
-        kind == idl.LinkedNodeKind.partDirective ||
-        kind == idl.LinkedNodeKind.partOfDirective ||
-        kind == idl.LinkedNodeKind.showCombinator ||
-        kind == idl.LinkedNodeKind.simpleFormalParameter ||
-        kind == idl.LinkedNodeKind.topLevelVariableDeclaration ||
-        kind == idl.LinkedNodeKind.typeParameter ||
-        kind == idl.LinkedNodeKind.variableDeclaration ||
-        kind == idl.LinkedNodeKind.variableDeclarationList);
-    assert(value == null || value >= 0);
-    _variantField_36 = value;
-  }
-
-  @override
-  int get integerLiteral_value {
-    assert(kind == idl.LinkedNodeKind.integerLiteral);
-    return _variantField_16 ??= 0;
-  }
-
-  set integerLiteral_value(int value) {
-    assert(kind == idl.LinkedNodeKind.integerLiteral);
-    assert(value == null || value >= 0);
-    _variantField_16 = value;
-  }
-
-  @override
-  String get interpolationString_value {
-    assert(kind == idl.LinkedNodeKind.interpolationString);
-    return _variantField_30 ??= '';
-  }
-
-  set interpolationString_value(String value) {
-    assert(kind == idl.LinkedNodeKind.interpolationString);
-    _variantField_30 = value;
-  }
-
-  @override
-  LinkedNodeBuilder get invocationExpression_arguments {
-    assert(kind == idl.LinkedNodeKind.functionExpressionInvocation ||
-        kind == idl.LinkedNodeKind.methodInvocation);
-    return _variantField_14;
-  }
-
-  @override
-  LinkedNodeBuilder get uriBasedDirective_uri {
-    assert(kind == idl.LinkedNodeKind.exportDirective ||
-        kind == idl.LinkedNodeKind.importDirective ||
-        kind == idl.LinkedNodeKind.partDirective);
-    return _variantField_14;
-  }
-
-  set invocationExpression_arguments(LinkedNodeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.functionExpressionInvocation ||
-        kind == idl.LinkedNodeKind.methodInvocation);
-    _variantField_14 = value;
-  }
-
-  set uriBasedDirective_uri(LinkedNodeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.exportDirective ||
-        kind == idl.LinkedNodeKind.importDirective ||
-        kind == idl.LinkedNodeKind.partDirective);
-    _variantField_14 = value;
-  }
-
-  @override
-  idl.LinkedNodeKind get kind => _kind ??= idl.LinkedNodeKind.adjacentStrings;
-
-  set kind(idl.LinkedNodeKind value) {
-    this._kind = value;
-  }
-
-  @override
-  bool get methodDeclaration_hasOperatorEqualWithParameterTypeFromObject {
-    assert(kind == idl.LinkedNodeKind.methodDeclaration);
-    return _variantField_31 ??= false;
-  }
-
-  @override
-  bool get simplyBoundable_isSimplyBounded {
-    assert(kind == idl.LinkedNodeKind.classDeclaration ||
-        kind == idl.LinkedNodeKind.classTypeAlias ||
-        kind == idl.LinkedNodeKind.functionTypeAlias ||
-        kind == idl.LinkedNodeKind.genericTypeAlias ||
-        kind == idl.LinkedNodeKind.mixinDeclaration);
-    return _variantField_31 ??= false;
-  }
-
-  set methodDeclaration_hasOperatorEqualWithParameterTypeFromObject(
-      bool value) {
-    assert(kind == idl.LinkedNodeKind.methodDeclaration);
-    _variantField_31 = value;
-  }
-
-  set simplyBoundable_isSimplyBounded(bool value) {
-    assert(kind == idl.LinkedNodeKind.classDeclaration ||
-        kind == idl.LinkedNodeKind.classTypeAlias ||
-        kind == idl.LinkedNodeKind.functionTypeAlias ||
-        kind == idl.LinkedNodeKind.genericTypeAlias ||
-        kind == idl.LinkedNodeKind.mixinDeclaration);
-    _variantField_31 = value;
-  }
-
-  @override
-  List<String> get mixinDeclaration_superInvokedNames {
-    assert(kind == idl.LinkedNodeKind.mixinDeclaration);
-    return _variantField_34 ??= <String>[];
-  }
-
-  @override
-  List<String> get names {
-    assert(kind == idl.LinkedNodeKind.hideCombinator ||
-        kind == idl.LinkedNodeKind.showCombinator ||
-        kind == idl.LinkedNodeKind.symbolLiteral);
-    return _variantField_34 ??= <String>[];
-  }
-
-  set mixinDeclaration_superInvokedNames(List<String> value) {
-    assert(kind == idl.LinkedNodeKind.mixinDeclaration);
-    _variantField_34 = value;
-  }
-
-  set names(List<String> value) {
-    assert(kind == idl.LinkedNodeKind.hideCombinator ||
-        kind == idl.LinkedNodeKind.showCombinator ||
-        kind == idl.LinkedNodeKind.symbolLiteral);
-    _variantField_34 = value;
-  }
-
-  @override
-  String get name => _name ??= '';
-
-  set name(String value) {
-    this._name = value;
-  }
-
-  @override
-  idl.UnlinkedTokenType get spreadElement_spreadOperator {
-    assert(kind == idl.LinkedNodeKind.spreadElement);
-    return _variantField_35 ??= idl.UnlinkedTokenType.NOTHING;
-  }
-
-  set spreadElement_spreadOperator(idl.UnlinkedTokenType value) {
-    assert(kind == idl.LinkedNodeKind.spreadElement);
-    _variantField_35 = value;
-  }
-
-  @override
-  TopLevelInferenceErrorBuilder get topLevelTypeInferenceError {
-    assert(kind == idl.LinkedNodeKind.methodDeclaration ||
-        kind == idl.LinkedNodeKind.simpleFormalParameter ||
-        kind == idl.LinkedNodeKind.variableDeclaration);
-    return _variantField_32;
-  }
-
-  set topLevelTypeInferenceError(TopLevelInferenceErrorBuilder value) {
-    assert(kind == idl.LinkedNodeKind.methodDeclaration ||
-        kind == idl.LinkedNodeKind.simpleFormalParameter ||
-        kind == idl.LinkedNodeKind.variableDeclaration);
-    _variantField_32 = value;
-  }
-
-  @override
-  LinkedNodeTypeBuilder get typeName_type {
-    assert(kind == idl.LinkedNodeKind.typeName);
-    return _variantField_23;
-  }
-
-  @override
-  LinkedNodeTypeBuilder get typeParameter_defaultType {
-    assert(kind == idl.LinkedNodeKind.typeParameter);
-    return _variantField_23;
-  }
-
-  set typeName_type(LinkedNodeTypeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.typeName);
-    _variantField_23 = value;
-  }
-
-  set typeParameter_defaultType(LinkedNodeTypeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.typeParameter);
-    _variantField_23 = value;
-  }
-
-  @override
-  LinkedNodeBuilder get unused11 {
-    assert(kind == idl.LinkedNodeKind.classDeclaration);
-    return _variantField_11;
-  }
-
-  set unused11(LinkedNodeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.classDeclaration);
-    _variantField_11 = value;
-  }
-
-  @override
-  String get uriBasedDirective_uriContent {
-    assert(kind == idl.LinkedNodeKind.exportDirective ||
-        kind == idl.LinkedNodeKind.importDirective ||
-        kind == idl.LinkedNodeKind.partDirective);
-    return _variantField_22 ??= '';
-  }
-
-  set uriBasedDirective_uriContent(String value) {
-    assert(kind == idl.LinkedNodeKind.exportDirective ||
-        kind == idl.LinkedNodeKind.importDirective ||
-        kind == idl.LinkedNodeKind.partDirective);
-    _variantField_22 = value;
-  }
-
-  @override
-  int get uriBasedDirective_uriElement {
-    assert(kind == idl.LinkedNodeKind.exportDirective ||
-        kind == idl.LinkedNodeKind.importDirective ||
-        kind == idl.LinkedNodeKind.partDirective);
-    return _variantField_19 ??= 0;
-  }
-
-  set uriBasedDirective_uriElement(int value) {
-    assert(kind == idl.LinkedNodeKind.exportDirective ||
-        kind == idl.LinkedNodeKind.importDirective ||
-        kind == idl.LinkedNodeKind.partDirective);
-    assert(value == null || value >= 0);
-    _variantField_19 = value;
-  }
-
-  LinkedNodeBuilder.adjacentStrings({
-    List<LinkedNodeBuilder> adjacentStrings_strings,
-  })  : _kind = idl.LinkedNodeKind.adjacentStrings,
-        _variantField_2 = adjacentStrings_strings;
-
-  LinkedNodeBuilder.annotation({
-    LinkedNodeBuilder annotation_arguments,
-    LinkedNodeBuilder annotation_constructorName,
-    int annotation_element,
-    LinkedNodeBuilder annotation_name,
-    LinkedNodeTypeSubstitutionBuilder annotation_substitution,
-  })  : _kind = idl.LinkedNodeKind.annotation,
-        _variantField_6 = annotation_arguments,
-        _variantField_7 = annotation_constructorName,
-        _variantField_17 = annotation_element,
-        _variantField_8 = annotation_name,
-        _variantField_38 = annotation_substitution;
-
-  LinkedNodeBuilder.argumentList({
-    List<LinkedNodeBuilder> argumentList_arguments,
-  })  : _kind = idl.LinkedNodeKind.argumentList,
-        _variantField_2 = argumentList_arguments;
-
-  LinkedNodeBuilder.asExpression({
-    LinkedNodeBuilder asExpression_expression,
-    LinkedNodeBuilder asExpression_type,
-    LinkedNodeTypeBuilder expression_type,
-  })  : _kind = idl.LinkedNodeKind.asExpression,
-        _variantField_6 = asExpression_expression,
-        _variantField_7 = asExpression_type,
-        _variantField_25 = expression_type;
-
-  LinkedNodeBuilder.assertInitializer({
-    LinkedNodeBuilder assertInitializer_condition,
-    LinkedNodeBuilder assertInitializer_message,
-  })  : _kind = idl.LinkedNodeKind.assertInitializer,
-        _variantField_6 = assertInitializer_condition,
-        _variantField_7 = assertInitializer_message;
-
-  LinkedNodeBuilder.assertStatement({
-    LinkedNodeBuilder assertStatement_condition,
-    LinkedNodeBuilder assertStatement_message,
-  })  : _kind = idl.LinkedNodeKind.assertStatement,
-        _variantField_6 = assertStatement_condition,
-        _variantField_7 = assertStatement_message;
-
-  LinkedNodeBuilder.assignmentExpression({
-    LinkedNodeBuilder assignmentExpression_leftHandSide,
-    LinkedNodeBuilder assignmentExpression_rightHandSide,
-    LinkedNodeTypeSubstitutionBuilder assignmentExpression_substitution,
-    int assignmentExpression_element,
-    idl.UnlinkedTokenType assignmentExpression_operator,
-    LinkedNodeTypeBuilder expression_type,
-  })  : _kind = idl.LinkedNodeKind.assignmentExpression,
-        _variantField_6 = assignmentExpression_leftHandSide,
-        _variantField_7 = assignmentExpression_rightHandSide,
-        _variantField_38 = assignmentExpression_substitution,
-        _variantField_15 = assignmentExpression_element,
-        _variantField_28 = assignmentExpression_operator,
-        _variantField_25 = expression_type;
-
-  LinkedNodeBuilder.awaitExpression({
-    LinkedNodeBuilder awaitExpression_expression,
-    LinkedNodeTypeBuilder expression_type,
-  })  : _kind = idl.LinkedNodeKind.awaitExpression,
-        _variantField_6 = awaitExpression_expression,
-        _variantField_25 = expression_type;
-
-  LinkedNodeBuilder.binaryExpression({
-    LinkedNodeTypeBuilder binaryExpression_invokeType,
-    LinkedNodeBuilder binaryExpression_leftOperand,
-    LinkedNodeBuilder binaryExpression_rightOperand,
-    LinkedNodeTypeSubstitutionBuilder binaryExpression_substitution,
-    int binaryExpression_element,
-    idl.UnlinkedTokenType binaryExpression_operator,
-    LinkedNodeTypeBuilder expression_type,
-  })  : _kind = idl.LinkedNodeKind.binaryExpression,
-        _variantField_24 = binaryExpression_invokeType,
-        _variantField_6 = binaryExpression_leftOperand,
-        _variantField_7 = binaryExpression_rightOperand,
-        _variantField_38 = binaryExpression_substitution,
-        _variantField_15 = binaryExpression_element,
-        _variantField_28 = binaryExpression_operator,
-        _variantField_25 = expression_type;
-
-  LinkedNodeBuilder.block({
-    List<LinkedNodeBuilder> block_statements,
-  })  : _kind = idl.LinkedNodeKind.block,
-        _variantField_2 = block_statements;
-
-  LinkedNodeBuilder.blockFunctionBody({
-    LinkedNodeBuilder blockFunctionBody_block,
-  })  : _kind = idl.LinkedNodeKind.blockFunctionBody,
-        _variantField_6 = blockFunctionBody_block;
-
-  LinkedNodeBuilder.booleanLiteral({
-    bool booleanLiteral_value,
-  })  : _kind = idl.LinkedNodeKind.booleanLiteral,
-        _variantField_27 = booleanLiteral_value;
-
-  LinkedNodeBuilder.breakStatement({
-    LinkedNodeBuilder breakStatement_label,
-  })  : _kind = idl.LinkedNodeKind.breakStatement,
-        _variantField_6 = breakStatement_label;
-
-  LinkedNodeBuilder.cascadeExpression({
-    List<LinkedNodeBuilder> cascadeExpression_sections,
-    LinkedNodeBuilder cascadeExpression_target,
-    LinkedNodeTypeBuilder expression_type,
-  })  : _kind = idl.LinkedNodeKind.cascadeExpression,
-        _variantField_2 = cascadeExpression_sections,
-        _variantField_6 = cascadeExpression_target,
-        _variantField_25 = expression_type;
-
-  LinkedNodeBuilder.catchClause({
-    LinkedNodeBuilder catchClause_body,
-    LinkedNodeBuilder catchClause_exceptionParameter,
-    LinkedNodeBuilder catchClause_exceptionType,
-    LinkedNodeBuilder catchClause_stackTraceParameter,
-  })  : _kind = idl.LinkedNodeKind.catchClause,
-        _variantField_6 = catchClause_body,
-        _variantField_7 = catchClause_exceptionParameter,
-        _variantField_8 = catchClause_exceptionType,
-        _variantField_9 = catchClause_stackTraceParameter;
-
-  LinkedNodeBuilder.classDeclaration({
-    List<LinkedNodeBuilder> annotatedNode_metadata,
-    LinkedNodeBuilder classDeclaration_extendsClause,
-    LinkedNodeBuilder classDeclaration_withClause,
-    LinkedNodeBuilder classDeclaration_nativeClause,
-    bool classDeclaration_isDartObject,
-    LinkedNodeBuilder classOrMixinDeclaration_implementsClause,
-    List<LinkedNodeBuilder> classOrMixinDeclaration_members,
-    LinkedNodeBuilder classOrMixinDeclaration_typeParameters,
-    int informativeId,
-    bool simplyBoundable_isSimplyBounded,
-    LinkedNodeBuilder unused11,
-  })  : _kind = idl.LinkedNodeKind.classDeclaration,
-        _variantField_4 = annotatedNode_metadata,
-        _variantField_6 = classDeclaration_extendsClause,
-        _variantField_7 = classDeclaration_withClause,
-        _variantField_8 = classDeclaration_nativeClause,
-        _variantField_27 = classDeclaration_isDartObject,
-        _variantField_12 = classOrMixinDeclaration_implementsClause,
-        _variantField_5 = classOrMixinDeclaration_members,
-        _variantField_13 = classOrMixinDeclaration_typeParameters,
-        _variantField_36 = informativeId,
-        _variantField_31 = simplyBoundable_isSimplyBounded,
-        _variantField_11 = unused11;
-
-  LinkedNodeBuilder.classTypeAlias({
-    List<LinkedNodeBuilder> annotatedNode_metadata,
-    LinkedNodeBuilder classTypeAlias_typeParameters,
-    LinkedNodeBuilder classTypeAlias_superclass,
-    LinkedNodeBuilder classTypeAlias_withClause,
-    LinkedNodeBuilder classTypeAlias_implementsClause,
-    int informativeId,
-    bool simplyBoundable_isSimplyBounded,
-  })  : _kind = idl.LinkedNodeKind.classTypeAlias,
-        _variantField_4 = annotatedNode_metadata,
-        _variantField_6 = classTypeAlias_typeParameters,
-        _variantField_7 = classTypeAlias_superclass,
-        _variantField_8 = classTypeAlias_withClause,
-        _variantField_9 = classTypeAlias_implementsClause,
-        _variantField_36 = informativeId,
-        _variantField_31 = simplyBoundable_isSimplyBounded;
-
-  LinkedNodeBuilder.comment({
-    List<LinkedNodeBuilder> comment_references,
-    List<String> comment_tokens,
-    idl.LinkedNodeCommentType comment_type,
-  })  : _kind = idl.LinkedNodeKind.comment,
-        _variantField_2 = comment_references,
-        _variantField_33 = comment_tokens,
-        _variantField_29 = comment_type;
-
-  LinkedNodeBuilder.commentReference({
-    LinkedNodeBuilder commentReference_identifier,
-  })  : _kind = idl.LinkedNodeKind.commentReference,
-        _variantField_6 = commentReference_identifier;
-
-  LinkedNodeBuilder.compilationUnit({
-    List<LinkedNodeBuilder> compilationUnit_declarations,
-    LinkedNodeBuilder compilationUnit_scriptTag,
-    List<LinkedNodeBuilder> compilationUnit_directives,
-    List<int> compilationUnit_featureSet,
-    LinkedLibraryLanguageVersionBuilder compilationUnit_languageVersion,
-    int informativeId,
-  })  : _kind = idl.LinkedNodeKind.compilationUnit,
-        _variantField_2 = compilationUnit_declarations,
-        _variantField_6 = compilationUnit_scriptTag,
-        _variantField_3 = compilationUnit_directives,
-        _variantField_41 = compilationUnit_featureSet,
-        _variantField_40 = compilationUnit_languageVersion,
-        _variantField_36 = informativeId;
-
-  LinkedNodeBuilder.conditionalExpression({
-    LinkedNodeBuilder conditionalExpression_condition,
-    LinkedNodeBuilder conditionalExpression_elseExpression,
-    LinkedNodeBuilder conditionalExpression_thenExpression,
-    LinkedNodeTypeBuilder expression_type,
-  })  : _kind = idl.LinkedNodeKind.conditionalExpression,
-        _variantField_6 = conditionalExpression_condition,
-        _variantField_7 = conditionalExpression_elseExpression,
-        _variantField_8 = conditionalExpression_thenExpression,
-        _variantField_25 = expression_type;
-
-  LinkedNodeBuilder.configuration({
-    LinkedNodeBuilder configuration_name,
-    LinkedNodeBuilder configuration_value,
-    LinkedNodeBuilder configuration_uri,
-  })  : _kind = idl.LinkedNodeKind.configuration,
-        _variantField_6 = configuration_name,
-        _variantField_7 = configuration_value,
-        _variantField_8 = configuration_uri;
-
-  LinkedNodeBuilder.constructorDeclaration({
-    List<LinkedNodeBuilder> constructorDeclaration_initializers,
-    List<LinkedNodeBuilder> annotatedNode_metadata,
-    LinkedNodeBuilder constructorDeclaration_body,
-    LinkedNodeBuilder constructorDeclaration_parameters,
-    LinkedNodeBuilder constructorDeclaration_redirectedConstructor,
-    LinkedNodeBuilder constructorDeclaration_returnType,
-    int informativeId,
-  })  : _kind = idl.LinkedNodeKind.constructorDeclaration,
-        _variantField_2 = constructorDeclaration_initializers,
-        _variantField_4 = annotatedNode_metadata,
-        _variantField_6 = constructorDeclaration_body,
-        _variantField_8 = constructorDeclaration_parameters,
-        _variantField_9 = constructorDeclaration_redirectedConstructor,
-        _variantField_10 = constructorDeclaration_returnType,
-        _variantField_36 = informativeId;
-
-  LinkedNodeBuilder.constructorFieldInitializer({
-    LinkedNodeBuilder constructorFieldInitializer_expression,
-    LinkedNodeBuilder constructorFieldInitializer_fieldName,
-  })  : _kind = idl.LinkedNodeKind.constructorFieldInitializer,
-        _variantField_6 = constructorFieldInitializer_expression,
-        _variantField_7 = constructorFieldInitializer_fieldName;
-
-  LinkedNodeBuilder.constructorName({
-    LinkedNodeBuilder constructorName_name,
-    LinkedNodeBuilder constructorName_type,
-    LinkedNodeTypeSubstitutionBuilder constructorName_substitution,
-    int constructorName_element,
-  })  : _kind = idl.LinkedNodeKind.constructorName,
-        _variantField_6 = constructorName_name,
-        _variantField_7 = constructorName_type,
-        _variantField_38 = constructorName_substitution,
-        _variantField_15 = constructorName_element;
-
-  LinkedNodeBuilder.continueStatement({
-    LinkedNodeBuilder continueStatement_label,
-  })  : _kind = idl.LinkedNodeKind.continueStatement,
-        _variantField_6 = continueStatement_label;
-
-  LinkedNodeBuilder.declaredIdentifier({
-    List<LinkedNodeBuilder> annotatedNode_metadata,
-    LinkedNodeBuilder declaredIdentifier_identifier,
-    LinkedNodeBuilder declaredIdentifier_type,
-  })  : _kind = idl.LinkedNodeKind.declaredIdentifier,
-        _variantField_4 = annotatedNode_metadata,
-        _variantField_6 = declaredIdentifier_identifier,
-        _variantField_7 = declaredIdentifier_type;
-
-  LinkedNodeBuilder.defaultFormalParameter({
-    LinkedNodeBuilder defaultFormalParameter_defaultValue,
-    LinkedNodeBuilder defaultFormalParameter_parameter,
-    idl.LinkedNodeFormalParameterKind defaultFormalParameter_kind,
-    int informativeId,
-  })  : _kind = idl.LinkedNodeKind.defaultFormalParameter,
-        _variantField_6 = defaultFormalParameter_defaultValue,
-        _variantField_7 = defaultFormalParameter_parameter,
-        _variantField_26 = defaultFormalParameter_kind,
-        _variantField_36 = informativeId;
-
-  LinkedNodeBuilder.doStatement({
-    LinkedNodeBuilder doStatement_body,
-    LinkedNodeBuilder doStatement_condition,
-  })  : _kind = idl.LinkedNodeKind.doStatement,
-        _variantField_6 = doStatement_body,
-        _variantField_7 = doStatement_condition;
-
-  LinkedNodeBuilder.dottedName({
-    List<LinkedNodeBuilder> dottedName_components,
-  })  : _kind = idl.LinkedNodeKind.dottedName,
-        _variantField_2 = dottedName_components;
-
-  LinkedNodeBuilder.doubleLiteral({
-    double doubleLiteral_value,
-  })  : _kind = idl.LinkedNodeKind.doubleLiteral,
-        _variantField_21 = doubleLiteral_value;
-
-  LinkedNodeBuilder.emptyFunctionBody({
-    int emptyFunctionBody_fake,
-  })  : _kind = idl.LinkedNodeKind.emptyFunctionBody,
-        _variantField_15 = emptyFunctionBody_fake;
-
-  LinkedNodeBuilder.emptyStatement({
-    int emptyStatement_fake,
-  })  : _kind = idl.LinkedNodeKind.emptyStatement,
-        _variantField_15 = emptyStatement_fake;
-
-  LinkedNodeBuilder.enumConstantDeclaration({
-    List<LinkedNodeBuilder> annotatedNode_metadata,
-    int informativeId,
-  })  : _kind = idl.LinkedNodeKind.enumConstantDeclaration,
-        _variantField_4 = annotatedNode_metadata,
-        _variantField_36 = informativeId;
-
-  LinkedNodeBuilder.enumDeclaration({
-    List<LinkedNodeBuilder> enumDeclaration_constants,
-    List<LinkedNodeBuilder> annotatedNode_metadata,
-    int informativeId,
-  })  : _kind = idl.LinkedNodeKind.enumDeclaration,
-        _variantField_2 = enumDeclaration_constants,
-        _variantField_4 = annotatedNode_metadata,
-        _variantField_36 = informativeId;
-
-  LinkedNodeBuilder.exportDirective({
-    List<LinkedNodeBuilder> namespaceDirective_combinators,
-    List<LinkedNodeBuilder> annotatedNode_metadata,
-    List<LinkedNodeBuilder> namespaceDirective_configurations,
-    String namespaceDirective_selectedUri,
-    int informativeId,
-    LinkedNodeBuilder uriBasedDirective_uri,
-    String uriBasedDirective_uriContent,
-    int uriBasedDirective_uriElement,
-  })  : _kind = idl.LinkedNodeKind.exportDirective,
-        _variantField_2 = namespaceDirective_combinators,
-        _variantField_4 = annotatedNode_metadata,
-        _variantField_3 = namespaceDirective_configurations,
-        _variantField_20 = namespaceDirective_selectedUri,
-        _variantField_36 = informativeId,
-        _variantField_14 = uriBasedDirective_uri,
-        _variantField_22 = uriBasedDirective_uriContent,
-        _variantField_19 = uriBasedDirective_uriElement;
-
-  LinkedNodeBuilder.expressionFunctionBody({
-    LinkedNodeBuilder expressionFunctionBody_expression,
-  })  : _kind = idl.LinkedNodeKind.expressionFunctionBody,
-        _variantField_6 = expressionFunctionBody_expression;
-
-  LinkedNodeBuilder.expressionStatement({
-    LinkedNodeBuilder expressionStatement_expression,
-  })  : _kind = idl.LinkedNodeKind.expressionStatement,
-        _variantField_6 = expressionStatement_expression;
-
-  LinkedNodeBuilder.extendsClause({
-    LinkedNodeBuilder extendsClause_superclass,
-  })  : _kind = idl.LinkedNodeKind.extendsClause,
-        _variantField_6 = extendsClause_superclass;
-
-  LinkedNodeBuilder.extensionDeclaration({
-    List<LinkedNodeBuilder> annotatedNode_metadata,
-    LinkedNodeBuilder extensionDeclaration_typeParameters,
-    LinkedNodeBuilder extensionDeclaration_extendedType,
-    List<LinkedNodeBuilder> extensionDeclaration_members,
-    String extensionDeclaration_refName,
-    int informativeId,
-  })  : _kind = idl.LinkedNodeKind.extensionDeclaration,
-        _variantField_4 = annotatedNode_metadata,
-        _variantField_6 = extensionDeclaration_typeParameters,
-        _variantField_7 = extensionDeclaration_extendedType,
-        _variantField_5 = extensionDeclaration_members,
-        _variantField_20 = extensionDeclaration_refName,
-        _variantField_36 = informativeId;
-
-  LinkedNodeBuilder.extensionOverride({
-    LinkedNodeTypeBuilder extensionOverride_extendedType,
-    List<LinkedNodeBuilder> extensionOverride_arguments,
-    LinkedNodeBuilder extensionOverride_extensionName,
-    LinkedNodeBuilder extensionOverride_typeArguments,
-    List<LinkedNodeTypeBuilder> extensionOverride_typeArgumentTypes,
-  })  : _kind = idl.LinkedNodeKind.extensionOverride,
-        _variantField_24 = extensionOverride_extendedType,
-        _variantField_2 = extensionOverride_arguments,
-        _variantField_7 = extensionOverride_extensionName,
-        _variantField_8 = extensionOverride_typeArguments,
-        _variantField_39 = extensionOverride_typeArgumentTypes;
-
-  LinkedNodeBuilder.fieldDeclaration({
-    List<LinkedNodeBuilder> annotatedNode_metadata,
-    LinkedNodeBuilder fieldDeclaration_fields,
-    int informativeId,
-  })  : _kind = idl.LinkedNodeKind.fieldDeclaration,
-        _variantField_4 = annotatedNode_metadata,
-        _variantField_6 = fieldDeclaration_fields,
-        _variantField_36 = informativeId;
-
-  LinkedNodeBuilder.fieldFormalParameter({
-    LinkedNodeTypeBuilder actualType,
-    List<LinkedNodeBuilder> normalFormalParameter_metadata,
-    LinkedNodeBuilder fieldFormalParameter_type,
-    LinkedNodeBuilder fieldFormalParameter_typeParameters,
-    LinkedNodeBuilder fieldFormalParameter_formalParameters,
-    bool inheritsCovariant,
-    int informativeId,
-  })  : _kind = idl.LinkedNodeKind.fieldFormalParameter,
-        _variantField_24 = actualType,
-        _variantField_4 = normalFormalParameter_metadata,
-        _variantField_6 = fieldFormalParameter_type,
-        _variantField_7 = fieldFormalParameter_typeParameters,
-        _variantField_8 = fieldFormalParameter_formalParameters,
-        _variantField_27 = inheritsCovariant,
-        _variantField_36 = informativeId;
-
-  LinkedNodeBuilder.forEachPartsWithDeclaration({
-    LinkedNodeBuilder forEachParts_iterable,
-    LinkedNodeBuilder forEachPartsWithDeclaration_loopVariable,
-  })  : _kind = idl.LinkedNodeKind.forEachPartsWithDeclaration,
-        _variantField_6 = forEachParts_iterable,
-        _variantField_7 = forEachPartsWithDeclaration_loopVariable;
-
-  LinkedNodeBuilder.forEachPartsWithIdentifier({
-    LinkedNodeBuilder forEachParts_iterable,
-    LinkedNodeBuilder forEachPartsWithIdentifier_identifier,
-  })  : _kind = idl.LinkedNodeKind.forEachPartsWithIdentifier,
-        _variantField_6 = forEachParts_iterable,
-        _variantField_7 = forEachPartsWithIdentifier_identifier;
-
-  LinkedNodeBuilder.forElement({
-    LinkedNodeBuilder forMixin_forLoopParts,
-    LinkedNodeBuilder forElement_body,
-  })  : _kind = idl.LinkedNodeKind.forElement,
-        _variantField_6 = forMixin_forLoopParts,
-        _variantField_7 = forElement_body;
-
-  LinkedNodeBuilder.forPartsWithDeclarations({
-    LinkedNodeBuilder forParts_condition,
-    LinkedNodeBuilder forPartsWithDeclarations_variables,
-    List<LinkedNodeBuilder> forParts_updaters,
-  })  : _kind = idl.LinkedNodeKind.forPartsWithDeclarations,
-        _variantField_6 = forParts_condition,
-        _variantField_7 = forPartsWithDeclarations_variables,
-        _variantField_5 = forParts_updaters;
-
-  LinkedNodeBuilder.forPartsWithExpression({
-    LinkedNodeBuilder forParts_condition,
-    LinkedNodeBuilder forPartsWithExpression_initialization,
-    List<LinkedNodeBuilder> forParts_updaters,
-  })  : _kind = idl.LinkedNodeKind.forPartsWithExpression,
-        _variantField_6 = forParts_condition,
-        _variantField_7 = forPartsWithExpression_initialization,
-        _variantField_5 = forParts_updaters;
-
-  LinkedNodeBuilder.forStatement({
-    LinkedNodeBuilder forMixin_forLoopParts,
-    LinkedNodeBuilder forStatement_body,
-  })  : _kind = idl.LinkedNodeKind.forStatement,
-        _variantField_6 = forMixin_forLoopParts,
-        _variantField_7 = forStatement_body;
-
-  LinkedNodeBuilder.formalParameterList({
-    List<LinkedNodeBuilder> formalParameterList_parameters,
-  })  : _kind = idl.LinkedNodeKind.formalParameterList,
-        _variantField_2 = formalParameterList_parameters;
-
-  LinkedNodeBuilder.functionDeclaration({
-    LinkedNodeTypeBuilder actualReturnType,
-    List<LinkedNodeBuilder> annotatedNode_metadata,
-    LinkedNodeBuilder functionDeclaration_functionExpression,
-    LinkedNodeBuilder functionDeclaration_returnType,
-    int informativeId,
-  })  : _kind = idl.LinkedNodeKind.functionDeclaration,
-        _variantField_24 = actualReturnType,
-        _variantField_4 = annotatedNode_metadata,
-        _variantField_6 = functionDeclaration_functionExpression,
-        _variantField_7 = functionDeclaration_returnType,
-        _variantField_36 = informativeId;
-
-  LinkedNodeBuilder.functionDeclarationStatement({
-    LinkedNodeBuilder functionDeclarationStatement_functionDeclaration,
-  })  : _kind = idl.LinkedNodeKind.functionDeclarationStatement,
-        _variantField_6 = functionDeclarationStatement_functionDeclaration;
-
-  LinkedNodeBuilder.functionExpression({
-    LinkedNodeTypeBuilder actualReturnType,
-    LinkedNodeBuilder functionExpression_body,
-    LinkedNodeBuilder functionExpression_formalParameters,
-    LinkedNodeBuilder functionExpression_typeParameters,
-  })  : _kind = idl.LinkedNodeKind.functionExpression,
-        _variantField_24 = actualReturnType,
-        _variantField_6 = functionExpression_body,
-        _variantField_7 = functionExpression_formalParameters,
-        _variantField_8 = functionExpression_typeParameters;
-
-  LinkedNodeBuilder.functionExpressionInvocation({
-    LinkedNodeTypeBuilder invocationExpression_invokeType,
-    LinkedNodeBuilder functionExpressionInvocation_function,
-    LinkedNodeBuilder invocationExpression_typeArguments,
-    LinkedNodeTypeBuilder expression_type,
-    LinkedNodeBuilder invocationExpression_arguments,
-  })  : _kind = idl.LinkedNodeKind.functionExpressionInvocation,
-        _variantField_24 = invocationExpression_invokeType,
-        _variantField_6 = functionExpressionInvocation_function,
-        _variantField_12 = invocationExpression_typeArguments,
-        _variantField_25 = expression_type,
-        _variantField_14 = invocationExpression_arguments;
-
-  LinkedNodeBuilder.functionTypeAlias({
-    LinkedNodeTypeBuilder actualReturnType,
-    List<LinkedNodeBuilder> annotatedNode_metadata,
-    LinkedNodeBuilder functionTypeAlias_formalParameters,
-    LinkedNodeBuilder functionTypeAlias_returnType,
-    LinkedNodeBuilder functionTypeAlias_typeParameters,
-    bool typeAlias_hasSelfReference,
-    int informativeId,
-    bool simplyBoundable_isSimplyBounded,
-  })  : _kind = idl.LinkedNodeKind.functionTypeAlias,
-        _variantField_24 = actualReturnType,
-        _variantField_4 = annotatedNode_metadata,
-        _variantField_6 = functionTypeAlias_formalParameters,
-        _variantField_7 = functionTypeAlias_returnType,
-        _variantField_8 = functionTypeAlias_typeParameters,
-        _variantField_27 = typeAlias_hasSelfReference,
-        _variantField_36 = informativeId,
-        _variantField_31 = simplyBoundable_isSimplyBounded;
-
-  LinkedNodeBuilder.functionTypedFormalParameter({
-    LinkedNodeTypeBuilder actualType,
-    List<LinkedNodeBuilder> normalFormalParameter_metadata,
-    LinkedNodeBuilder functionTypedFormalParameter_formalParameters,
-    LinkedNodeBuilder functionTypedFormalParameter_returnType,
-    LinkedNodeBuilder functionTypedFormalParameter_typeParameters,
-    bool inheritsCovariant,
-    int informativeId,
-  })  : _kind = idl.LinkedNodeKind.functionTypedFormalParameter,
-        _variantField_24 = actualType,
-        _variantField_4 = normalFormalParameter_metadata,
-        _variantField_6 = functionTypedFormalParameter_formalParameters,
-        _variantField_7 = functionTypedFormalParameter_returnType,
-        _variantField_8 = functionTypedFormalParameter_typeParameters,
-        _variantField_27 = inheritsCovariant,
-        _variantField_36 = informativeId;
-
-  LinkedNodeBuilder.genericFunctionType({
-    LinkedNodeTypeBuilder actualReturnType,
-    LinkedNodeBuilder genericFunctionType_typeParameters,
-    LinkedNodeBuilder genericFunctionType_returnType,
-    int genericFunctionType_id,
-    LinkedNodeBuilder genericFunctionType_formalParameters,
-    LinkedNodeTypeBuilder genericFunctionType_type,
-  })  : _kind = idl.LinkedNodeKind.genericFunctionType,
-        _variantField_24 = actualReturnType,
-        _variantField_6 = genericFunctionType_typeParameters,
-        _variantField_7 = genericFunctionType_returnType,
-        _variantField_17 = genericFunctionType_id,
-        _variantField_8 = genericFunctionType_formalParameters,
-        _variantField_25 = genericFunctionType_type;
-
-  LinkedNodeBuilder.genericTypeAlias({
-    List<LinkedNodeBuilder> annotatedNode_metadata,
-    LinkedNodeBuilder genericTypeAlias_typeParameters,
-    LinkedNodeBuilder genericTypeAlias_functionType,
-    bool typeAlias_hasSelfReference,
-    int informativeId,
-    bool simplyBoundable_isSimplyBounded,
-  })  : _kind = idl.LinkedNodeKind.genericTypeAlias,
-        _variantField_4 = annotatedNode_metadata,
-        _variantField_6 = genericTypeAlias_typeParameters,
-        _variantField_7 = genericTypeAlias_functionType,
-        _variantField_27 = typeAlias_hasSelfReference,
-        _variantField_36 = informativeId,
-        _variantField_31 = simplyBoundable_isSimplyBounded;
-
-  LinkedNodeBuilder.hideCombinator({
-    int informativeId,
-    List<String> names,
-  })  : _kind = idl.LinkedNodeKind.hideCombinator,
-        _variantField_36 = informativeId,
-        _variantField_34 = names;
-
-  LinkedNodeBuilder.ifElement({
-    LinkedNodeBuilder ifMixin_condition,
-    LinkedNodeBuilder ifElement_thenElement,
-    LinkedNodeBuilder ifElement_elseElement,
-  })  : _kind = idl.LinkedNodeKind.ifElement,
-        _variantField_6 = ifMixin_condition,
-        _variantField_8 = ifElement_thenElement,
-        _variantField_9 = ifElement_elseElement;
-
-  LinkedNodeBuilder.ifStatement({
-    LinkedNodeBuilder ifMixin_condition,
-    LinkedNodeBuilder ifStatement_elseStatement,
-    LinkedNodeBuilder ifStatement_thenStatement,
-  })  : _kind = idl.LinkedNodeKind.ifStatement,
-        _variantField_6 = ifMixin_condition,
-        _variantField_7 = ifStatement_elseStatement,
-        _variantField_8 = ifStatement_thenStatement;
-
-  LinkedNodeBuilder.implementsClause({
-    List<LinkedNodeBuilder> implementsClause_interfaces,
-  })  : _kind = idl.LinkedNodeKind.implementsClause,
-        _variantField_2 = implementsClause_interfaces;
-
-  LinkedNodeBuilder.importDirective({
-    List<LinkedNodeBuilder> namespaceDirective_combinators,
-    List<LinkedNodeBuilder> annotatedNode_metadata,
-    List<LinkedNodeBuilder> namespaceDirective_configurations,
-    String namespaceDirective_selectedUri,
-    String importDirective_prefix,
-    int informativeId,
-    LinkedNodeBuilder uriBasedDirective_uri,
-    String uriBasedDirective_uriContent,
-    int uriBasedDirective_uriElement,
-  })  : _kind = idl.LinkedNodeKind.importDirective,
-        _variantField_2 = namespaceDirective_combinators,
-        _variantField_4 = annotatedNode_metadata,
-        _variantField_3 = namespaceDirective_configurations,
-        _variantField_20 = namespaceDirective_selectedUri,
-        _variantField_1 = importDirective_prefix,
-        _variantField_36 = informativeId,
-        _variantField_14 = uriBasedDirective_uri,
-        _variantField_22 = uriBasedDirective_uriContent,
-        _variantField_19 = uriBasedDirective_uriElement;
-
-  LinkedNodeBuilder.indexExpression({
-    LinkedNodeBuilder indexExpression_index,
-    LinkedNodeBuilder indexExpression_target,
-    LinkedNodeTypeSubstitutionBuilder indexExpression_substitution,
-    int indexExpression_element,
-    LinkedNodeTypeBuilder expression_type,
-  })  : _kind = idl.LinkedNodeKind.indexExpression,
-        _variantField_6 = indexExpression_index,
-        _variantField_7 = indexExpression_target,
-        _variantField_38 = indexExpression_substitution,
-        _variantField_15 = indexExpression_element,
-        _variantField_25 = expression_type;
-
-  LinkedNodeBuilder.instanceCreationExpression({
-    List<LinkedNodeBuilder> instanceCreationExpression_arguments,
-    LinkedNodeBuilder instanceCreationExpression_constructorName,
-    LinkedNodeBuilder instanceCreationExpression_typeArguments,
-    LinkedNodeTypeBuilder expression_type,
-  })  : _kind = idl.LinkedNodeKind.instanceCreationExpression,
-        _variantField_2 = instanceCreationExpression_arguments,
-        _variantField_7 = instanceCreationExpression_constructorName,
-        _variantField_8 = instanceCreationExpression_typeArguments,
-        _variantField_25 = expression_type;
-
-  LinkedNodeBuilder.integerLiteral({
-    LinkedNodeTypeBuilder expression_type,
-    int integerLiteral_value,
-  })  : _kind = idl.LinkedNodeKind.integerLiteral,
-        _variantField_25 = expression_type,
-        _variantField_16 = integerLiteral_value;
-
-  LinkedNodeBuilder.interpolationExpression({
-    LinkedNodeBuilder interpolationExpression_expression,
-  })  : _kind = idl.LinkedNodeKind.interpolationExpression,
-        _variantField_6 = interpolationExpression_expression;
-
-  LinkedNodeBuilder.interpolationString({
-    String interpolationString_value,
-  })  : _kind = idl.LinkedNodeKind.interpolationString,
-        _variantField_30 = interpolationString_value;
-
-  LinkedNodeBuilder.isExpression({
-    LinkedNodeBuilder isExpression_expression,
-    LinkedNodeBuilder isExpression_type,
-  })  : _kind = idl.LinkedNodeKind.isExpression,
-        _variantField_6 = isExpression_expression,
-        _variantField_7 = isExpression_type;
-
-  LinkedNodeBuilder.label({
-    LinkedNodeBuilder label_label,
-  })  : _kind = idl.LinkedNodeKind.label,
-        _variantField_6 = label_label;
-
-  LinkedNodeBuilder.labeledStatement({
-    List<LinkedNodeBuilder> labeledStatement_labels,
-    LinkedNodeBuilder labeledStatement_statement,
-  })  : _kind = idl.LinkedNodeKind.labeledStatement,
-        _variantField_2 = labeledStatement_labels,
-        _variantField_6 = labeledStatement_statement;
-
-  LinkedNodeBuilder.libraryDirective({
-    List<LinkedNodeBuilder> annotatedNode_metadata,
-    LinkedNodeBuilder libraryDirective_name,
-    int informativeId,
-  })  : _kind = idl.LinkedNodeKind.libraryDirective,
-        _variantField_4 = annotatedNode_metadata,
-        _variantField_6 = libraryDirective_name,
-        _variantField_36 = informativeId;
-
-  LinkedNodeBuilder.libraryIdentifier({
-    List<LinkedNodeBuilder> libraryIdentifier_components,
-  })  : _kind = idl.LinkedNodeKind.libraryIdentifier,
-        _variantField_2 = libraryIdentifier_components;
-
-  LinkedNodeBuilder.listLiteral({
-    List<LinkedNodeBuilder> typedLiteral_typeArguments,
-    List<LinkedNodeBuilder> listLiteral_elements,
-    LinkedNodeTypeBuilder expression_type,
-  })  : _kind = idl.LinkedNodeKind.listLiteral,
-        _variantField_2 = typedLiteral_typeArguments,
-        _variantField_3 = listLiteral_elements,
-        _variantField_25 = expression_type;
-
-  LinkedNodeBuilder.mapLiteralEntry({
-    LinkedNodeBuilder mapLiteralEntry_key,
-    LinkedNodeBuilder mapLiteralEntry_value,
-  })  : _kind = idl.LinkedNodeKind.mapLiteralEntry,
-        _variantField_6 = mapLiteralEntry_key,
-        _variantField_7 = mapLiteralEntry_value;
-
-  LinkedNodeBuilder.methodDeclaration({
-    LinkedNodeTypeBuilder actualReturnType,
-    List<LinkedNodeBuilder> annotatedNode_metadata,
-    LinkedNodeBuilder methodDeclaration_body,
-    LinkedNodeBuilder methodDeclaration_formalParameters,
-    LinkedNodeBuilder methodDeclaration_returnType,
-    LinkedNodeBuilder methodDeclaration_typeParameters,
-    int informativeId,
-    bool methodDeclaration_hasOperatorEqualWithParameterTypeFromObject,
-    TopLevelInferenceErrorBuilder topLevelTypeInferenceError,
-  })  : _kind = idl.LinkedNodeKind.methodDeclaration,
-        _variantField_24 = actualReturnType,
-        _variantField_4 = annotatedNode_metadata,
-        _variantField_6 = methodDeclaration_body,
-        _variantField_7 = methodDeclaration_formalParameters,
-        _variantField_8 = methodDeclaration_returnType,
-        _variantField_9 = methodDeclaration_typeParameters,
-        _variantField_36 = informativeId,
-        _variantField_31 =
-            methodDeclaration_hasOperatorEqualWithParameterTypeFromObject,
-        _variantField_32 = topLevelTypeInferenceError;
-
-  LinkedNodeBuilder.methodInvocation({
-    LinkedNodeTypeBuilder invocationExpression_invokeType,
-    LinkedNodeBuilder methodInvocation_methodName,
-    LinkedNodeBuilder methodInvocation_target,
-    LinkedNodeBuilder invocationExpression_typeArguments,
-    LinkedNodeTypeBuilder expression_type,
-    LinkedNodeBuilder invocationExpression_arguments,
-  })  : _kind = idl.LinkedNodeKind.methodInvocation,
-        _variantField_24 = invocationExpression_invokeType,
-        _variantField_6 = methodInvocation_methodName,
-        _variantField_7 = methodInvocation_target,
-        _variantField_12 = invocationExpression_typeArguments,
-        _variantField_25 = expression_type,
-        _variantField_14 = invocationExpression_arguments;
-
-  LinkedNodeBuilder.mixinDeclaration({
-    List<LinkedNodeBuilder> annotatedNode_metadata,
-    LinkedNodeBuilder mixinDeclaration_onClause,
-    LinkedNodeBuilder classOrMixinDeclaration_implementsClause,
-    List<LinkedNodeBuilder> classOrMixinDeclaration_members,
-    LinkedNodeBuilder classOrMixinDeclaration_typeParameters,
-    int informativeId,
-    bool simplyBoundable_isSimplyBounded,
-    List<String> mixinDeclaration_superInvokedNames,
-  })  : _kind = idl.LinkedNodeKind.mixinDeclaration,
-        _variantField_4 = annotatedNode_metadata,
-        _variantField_6 = mixinDeclaration_onClause,
-        _variantField_12 = classOrMixinDeclaration_implementsClause,
-        _variantField_5 = classOrMixinDeclaration_members,
-        _variantField_13 = classOrMixinDeclaration_typeParameters,
-        _variantField_36 = informativeId,
-        _variantField_31 = simplyBoundable_isSimplyBounded,
-        _variantField_34 = mixinDeclaration_superInvokedNames;
-
-  LinkedNodeBuilder.namedExpression({
-    LinkedNodeBuilder namedExpression_expression,
-    LinkedNodeBuilder namedExpression_name,
-  })  : _kind = idl.LinkedNodeKind.namedExpression,
-        _variantField_6 = namedExpression_expression,
-        _variantField_7 = namedExpression_name;
-
-  LinkedNodeBuilder.nativeClause({
-    LinkedNodeBuilder nativeClause_name,
-  })  : _kind = idl.LinkedNodeKind.nativeClause,
-        _variantField_6 = nativeClause_name;
-
-  LinkedNodeBuilder.nativeFunctionBody({
-    LinkedNodeBuilder nativeFunctionBody_stringLiteral,
-  })  : _kind = idl.LinkedNodeKind.nativeFunctionBody,
-        _variantField_6 = nativeFunctionBody_stringLiteral;
-
-  LinkedNodeBuilder.nullLiteral({
-    int nullLiteral_fake,
-    LinkedNodeTypeBuilder expression_type,
-  })  : _kind = idl.LinkedNodeKind.nullLiteral,
-        _variantField_15 = nullLiteral_fake,
-        _variantField_25 = expression_type;
-
-  LinkedNodeBuilder.onClause({
-    List<LinkedNodeBuilder> onClause_superclassConstraints,
-  })  : _kind = idl.LinkedNodeKind.onClause,
-        _variantField_2 = onClause_superclassConstraints;
-
-  LinkedNodeBuilder.parenthesizedExpression({
-    LinkedNodeBuilder parenthesizedExpression_expression,
-    LinkedNodeTypeBuilder expression_type,
-  })  : _kind = idl.LinkedNodeKind.parenthesizedExpression,
-        _variantField_6 = parenthesizedExpression_expression,
-        _variantField_25 = expression_type;
-
-  LinkedNodeBuilder.partDirective({
-    List<LinkedNodeBuilder> annotatedNode_metadata,
-    int informativeId,
-    LinkedNodeBuilder uriBasedDirective_uri,
-    String uriBasedDirective_uriContent,
-    int uriBasedDirective_uriElement,
-  })  : _kind = idl.LinkedNodeKind.partDirective,
-        _variantField_4 = annotatedNode_metadata,
-        _variantField_36 = informativeId,
-        _variantField_14 = uriBasedDirective_uri,
-        _variantField_22 = uriBasedDirective_uriContent,
-        _variantField_19 = uriBasedDirective_uriElement;
-
-  LinkedNodeBuilder.partOfDirective({
-    List<LinkedNodeBuilder> annotatedNode_metadata,
-    LinkedNodeBuilder partOfDirective_libraryName,
-    LinkedNodeBuilder partOfDirective_uri,
-    int informativeId,
-  })  : _kind = idl.LinkedNodeKind.partOfDirective,
-        _variantField_4 = annotatedNode_metadata,
-        _variantField_6 = partOfDirective_libraryName,
-        _variantField_7 = partOfDirective_uri,
-        _variantField_36 = informativeId;
-
-  LinkedNodeBuilder.postfixExpression({
-    LinkedNodeBuilder postfixExpression_operand,
-    LinkedNodeTypeSubstitutionBuilder postfixExpression_substitution,
-    int postfixExpression_element,
-    idl.UnlinkedTokenType postfixExpression_operator,
-    LinkedNodeTypeBuilder expression_type,
-  })  : _kind = idl.LinkedNodeKind.postfixExpression,
-        _variantField_6 = postfixExpression_operand,
-        _variantField_38 = postfixExpression_substitution,
-        _variantField_15 = postfixExpression_element,
-        _variantField_28 = postfixExpression_operator,
-        _variantField_25 = expression_type;
-
-  LinkedNodeBuilder.prefixExpression({
-    LinkedNodeBuilder prefixExpression_operand,
-    LinkedNodeTypeSubstitutionBuilder prefixExpression_substitution,
-    int prefixExpression_element,
-    idl.UnlinkedTokenType prefixExpression_operator,
-    LinkedNodeTypeBuilder expression_type,
-  })  : _kind = idl.LinkedNodeKind.prefixExpression,
-        _variantField_6 = prefixExpression_operand,
-        _variantField_38 = prefixExpression_substitution,
-        _variantField_15 = prefixExpression_element,
-        _variantField_28 = prefixExpression_operator,
-        _variantField_25 = expression_type;
-
-  LinkedNodeBuilder.prefixedIdentifier({
-    LinkedNodeBuilder prefixedIdentifier_identifier,
-    LinkedNodeBuilder prefixedIdentifier_prefix,
-    LinkedNodeTypeBuilder expression_type,
-  })  : _kind = idl.LinkedNodeKind.prefixedIdentifier,
-        _variantField_6 = prefixedIdentifier_identifier,
-        _variantField_7 = prefixedIdentifier_prefix,
-        _variantField_25 = expression_type;
-
-  LinkedNodeBuilder.propertyAccess({
-    LinkedNodeBuilder propertyAccess_propertyName,
-    LinkedNodeBuilder propertyAccess_target,
-    idl.UnlinkedTokenType propertyAccess_operator,
-    LinkedNodeTypeBuilder expression_type,
-  })  : _kind = idl.LinkedNodeKind.propertyAccess,
-        _variantField_6 = propertyAccess_propertyName,
-        _variantField_7 = propertyAccess_target,
-        _variantField_28 = propertyAccess_operator,
-        _variantField_25 = expression_type;
-
-  LinkedNodeBuilder.redirectingConstructorInvocation({
-    LinkedNodeBuilder redirectingConstructorInvocation_arguments,
-    LinkedNodeBuilder redirectingConstructorInvocation_constructorName,
-    LinkedNodeTypeSubstitutionBuilder
-        redirectingConstructorInvocation_substitution,
-    int redirectingConstructorInvocation_element,
-  })  : _kind = idl.LinkedNodeKind.redirectingConstructorInvocation,
-        _variantField_6 = redirectingConstructorInvocation_arguments,
-        _variantField_7 = redirectingConstructorInvocation_constructorName,
-        _variantField_38 = redirectingConstructorInvocation_substitution,
-        _variantField_15 = redirectingConstructorInvocation_element;
-
-  LinkedNodeBuilder.rethrowExpression({
-    LinkedNodeTypeBuilder expression_type,
-  })  : _kind = idl.LinkedNodeKind.rethrowExpression,
-        _variantField_25 = expression_type;
-
-  LinkedNodeBuilder.returnStatement({
-    LinkedNodeBuilder returnStatement_expression,
-  })  : _kind = idl.LinkedNodeKind.returnStatement,
-        _variantField_6 = returnStatement_expression;
-
-  LinkedNodeBuilder.setOrMapLiteral({
-    List<LinkedNodeBuilder> typedLiteral_typeArguments,
-    List<LinkedNodeBuilder> setOrMapLiteral_elements,
-    LinkedNodeTypeBuilder expression_type,
-  })  : _kind = idl.LinkedNodeKind.setOrMapLiteral,
-        _variantField_2 = typedLiteral_typeArguments,
-        _variantField_3 = setOrMapLiteral_elements,
-        _variantField_25 = expression_type;
-
-  LinkedNodeBuilder.showCombinator({
-    int informativeId,
-    List<String> names,
-  })  : _kind = idl.LinkedNodeKind.showCombinator,
-        _variantField_36 = informativeId,
-        _variantField_34 = names;
-
-  LinkedNodeBuilder.simpleFormalParameter({
-    LinkedNodeTypeBuilder actualType,
-    List<LinkedNodeBuilder> normalFormalParameter_metadata,
-    LinkedNodeBuilder simpleFormalParameter_type,
-    bool inheritsCovariant,
-    int informativeId,
-    TopLevelInferenceErrorBuilder topLevelTypeInferenceError,
-  })  : _kind = idl.LinkedNodeKind.simpleFormalParameter,
-        _variantField_24 = actualType,
-        _variantField_4 = normalFormalParameter_metadata,
-        _variantField_6 = simpleFormalParameter_type,
-        _variantField_27 = inheritsCovariant,
-        _variantField_36 = informativeId,
-        _variantField_32 = topLevelTypeInferenceError;
-
-  LinkedNodeBuilder.simpleIdentifier({
-    LinkedNodeTypeSubstitutionBuilder simpleIdentifier_substitution,
-    int simpleIdentifier_element,
-    LinkedNodeTypeBuilder expression_type,
-  })  : _kind = idl.LinkedNodeKind.simpleIdentifier,
-        _variantField_38 = simpleIdentifier_substitution,
-        _variantField_15 = simpleIdentifier_element,
-        _variantField_25 = expression_type;
-
-  LinkedNodeBuilder.simpleStringLiteral({
-    String simpleStringLiteral_value,
-  })  : _kind = idl.LinkedNodeKind.simpleStringLiteral,
-        _variantField_20 = simpleStringLiteral_value;
-
-  LinkedNodeBuilder.spreadElement({
-    LinkedNodeBuilder spreadElement_expression,
-    idl.UnlinkedTokenType spreadElement_spreadOperator,
-  })  : _kind = idl.LinkedNodeKind.spreadElement,
-        _variantField_6 = spreadElement_expression,
-        _variantField_35 = spreadElement_spreadOperator;
-
-  LinkedNodeBuilder.stringInterpolation({
-    List<LinkedNodeBuilder> stringInterpolation_elements,
-  })  : _kind = idl.LinkedNodeKind.stringInterpolation,
-        _variantField_2 = stringInterpolation_elements;
-
-  LinkedNodeBuilder.superConstructorInvocation({
-    LinkedNodeBuilder superConstructorInvocation_arguments,
-    LinkedNodeBuilder superConstructorInvocation_constructorName,
-    LinkedNodeTypeSubstitutionBuilder superConstructorInvocation_substitution,
-    int superConstructorInvocation_element,
-  })  : _kind = idl.LinkedNodeKind.superConstructorInvocation,
-        _variantField_6 = superConstructorInvocation_arguments,
-        _variantField_7 = superConstructorInvocation_constructorName,
-        _variantField_38 = superConstructorInvocation_substitution,
-        _variantField_15 = superConstructorInvocation_element;
-
-  LinkedNodeBuilder.superExpression({
-    LinkedNodeTypeBuilder expression_type,
-  })  : _kind = idl.LinkedNodeKind.superExpression,
-        _variantField_25 = expression_type;
-
-  LinkedNodeBuilder.switchCase({
-    List<LinkedNodeBuilder> switchMember_statements,
-    LinkedNodeBuilder switchCase_expression,
-    List<LinkedNodeBuilder> switchMember_labels,
-  })  : _kind = idl.LinkedNodeKind.switchCase,
-        _variantField_4 = switchMember_statements,
-        _variantField_6 = switchCase_expression,
-        _variantField_3 = switchMember_labels;
-
-  LinkedNodeBuilder.switchDefault({
-    List<LinkedNodeBuilder> switchMember_statements,
-    List<LinkedNodeBuilder> switchMember_labels,
-  })  : _kind = idl.LinkedNodeKind.switchDefault,
-        _variantField_4 = switchMember_statements,
-        _variantField_3 = switchMember_labels;
-
-  LinkedNodeBuilder.switchStatement({
-    List<LinkedNodeBuilder> switchStatement_members,
-    LinkedNodeBuilder switchStatement_expression,
-  })  : _kind = idl.LinkedNodeKind.switchStatement,
-        _variantField_2 = switchStatement_members,
-        _variantField_7 = switchStatement_expression;
-
-  LinkedNodeBuilder.symbolLiteral({
-    LinkedNodeTypeBuilder expression_type,
-    List<String> names,
-  })  : _kind = idl.LinkedNodeKind.symbolLiteral,
-        _variantField_25 = expression_type,
-        _variantField_34 = names;
-
-  LinkedNodeBuilder.thisExpression({
-    LinkedNodeTypeBuilder expression_type,
-  })  : _kind = idl.LinkedNodeKind.thisExpression,
-        _variantField_25 = expression_type;
-
-  LinkedNodeBuilder.throwExpression({
-    LinkedNodeBuilder throwExpression_expression,
-    LinkedNodeTypeBuilder expression_type,
-  })  : _kind = idl.LinkedNodeKind.throwExpression,
-        _variantField_6 = throwExpression_expression,
-        _variantField_25 = expression_type;
-
-  LinkedNodeBuilder.topLevelVariableDeclaration({
-    List<LinkedNodeBuilder> annotatedNode_metadata,
-    LinkedNodeBuilder topLevelVariableDeclaration_variableList,
-    int informativeId,
-  })  : _kind = idl.LinkedNodeKind.topLevelVariableDeclaration,
-        _variantField_4 = annotatedNode_metadata,
-        _variantField_6 = topLevelVariableDeclaration_variableList,
-        _variantField_36 = informativeId;
-
-  LinkedNodeBuilder.tryStatement({
-    List<LinkedNodeBuilder> tryStatement_catchClauses,
-    LinkedNodeBuilder tryStatement_body,
-    LinkedNodeBuilder tryStatement_finallyBlock,
-  })  : _kind = idl.LinkedNodeKind.tryStatement,
-        _variantField_2 = tryStatement_catchClauses,
-        _variantField_6 = tryStatement_body,
-        _variantField_7 = tryStatement_finallyBlock;
-
-  LinkedNodeBuilder.typeArgumentList({
-    List<LinkedNodeBuilder> typeArgumentList_arguments,
-  })  : _kind = idl.LinkedNodeKind.typeArgumentList,
-        _variantField_2 = typeArgumentList_arguments;
-
-  LinkedNodeBuilder.typeName({
-    List<LinkedNodeBuilder> typeName_typeArguments,
-    LinkedNodeBuilder typeName_name,
-    LinkedNodeTypeBuilder typeName_type,
-  })  : _kind = idl.LinkedNodeKind.typeName,
-        _variantField_2 = typeName_typeArguments,
-        _variantField_6 = typeName_name,
-        _variantField_23 = typeName_type;
-
-  LinkedNodeBuilder.typeParameter({
-    List<LinkedNodeBuilder> annotatedNode_metadata,
-    LinkedNodeBuilder typeParameter_bound,
-    int typeParameter_variance,
-    int informativeId,
-    LinkedNodeTypeBuilder typeParameter_defaultType,
-  })  : _kind = idl.LinkedNodeKind.typeParameter,
-        _variantField_4 = annotatedNode_metadata,
-        _variantField_6 = typeParameter_bound,
-        _variantField_15 = typeParameter_variance,
-        _variantField_36 = informativeId,
-        _variantField_23 = typeParameter_defaultType;
-
-  LinkedNodeBuilder.typeParameterList({
-    List<LinkedNodeBuilder> typeParameterList_typeParameters,
-  })  : _kind = idl.LinkedNodeKind.typeParameterList,
-        _variantField_2 = typeParameterList_typeParameters;
-
-  LinkedNodeBuilder.variableDeclaration({
-    LinkedNodeTypeBuilder actualType,
-    List<LinkedNodeBuilder> annotatedNode_metadata,
-    LinkedNodeBuilder variableDeclaration_initializer,
-    bool inheritsCovariant,
-    int informativeId,
-    TopLevelInferenceErrorBuilder topLevelTypeInferenceError,
-  })  : _kind = idl.LinkedNodeKind.variableDeclaration,
-        _variantField_24 = actualType,
-        _variantField_4 = annotatedNode_metadata,
-        _variantField_6 = variableDeclaration_initializer,
-        _variantField_27 = inheritsCovariant,
-        _variantField_36 = informativeId,
-        _variantField_32 = topLevelTypeInferenceError;
-
-  LinkedNodeBuilder.variableDeclarationList({
-    List<LinkedNodeBuilder> variableDeclarationList_variables,
-    List<LinkedNodeBuilder> annotatedNode_metadata,
-    LinkedNodeBuilder variableDeclarationList_type,
-    int informativeId,
-  })  : _kind = idl.LinkedNodeKind.variableDeclarationList,
-        _variantField_2 = variableDeclarationList_variables,
-        _variantField_4 = annotatedNode_metadata,
-        _variantField_6 = variableDeclarationList_type,
-        _variantField_36 = informativeId;
-
-  LinkedNodeBuilder.variableDeclarationStatement({
-    LinkedNodeBuilder variableDeclarationStatement_variables,
-  })  : _kind = idl.LinkedNodeKind.variableDeclarationStatement,
-        _variantField_6 = variableDeclarationStatement_variables;
-
-  LinkedNodeBuilder.whileStatement({
-    LinkedNodeBuilder whileStatement_body,
-    LinkedNodeBuilder whileStatement_condition,
-  })  : _kind = idl.LinkedNodeKind.whileStatement,
-        _variantField_6 = whileStatement_body,
-        _variantField_7 = whileStatement_condition;
-
-  LinkedNodeBuilder.withClause({
-    List<LinkedNodeBuilder> withClause_mixinTypes,
-  })  : _kind = idl.LinkedNodeKind.withClause,
-        _variantField_2 = withClause_mixinTypes;
-
-  LinkedNodeBuilder.yieldStatement({
-    LinkedNodeBuilder yieldStatement_expression,
-  })  : _kind = idl.LinkedNodeKind.yieldStatement,
-        _variantField_6 = yieldStatement_expression;
-
-  /// Flush [informative] data recursively.
-  void flushInformative() {
-    if (kind == idl.LinkedNodeKind.adjacentStrings) {
-      adjacentStrings_strings?.forEach((b) => b.flushInformative());
-    } else if (kind == idl.LinkedNodeKind.annotation) {
-      annotation_arguments?.flushInformative();
-      annotation_constructorName?.flushInformative();
-      annotation_name?.flushInformative();
-      annotation_substitution?.flushInformative();
-    } else if (kind == idl.LinkedNodeKind.argumentList) {
-      argumentList_arguments?.forEach((b) => b.flushInformative());
-    } else if (kind == idl.LinkedNodeKind.asExpression) {
-      asExpression_expression?.flushInformative();
-      asExpression_type?.flushInformative();
-      expression_type?.flushInformative();
-    } else if (kind == idl.LinkedNodeKind.assertInitializer) {
-      assertInitializer_condition?.flushInformative();
-      assertInitializer_message?.flushInformative();
-    } else if (kind == idl.LinkedNodeKind.assertStatement) {
-      assertStatement_condition?.flushInformative();
-      assertStatement_message?.flushInformative();
-    } else if (kind == idl.LinkedNodeKind.assignmentExpression) {
-      assignmentExpression_leftHandSide?.flushInformative();
-      assignmentExpression_rightHandSide?.flushInformative();
-      assignmentExpression_substitution?.flushInformative();
-      expression_type?.flushInformative();
-    } else if (kind == idl.LinkedNodeKind.awaitExpression) {
-      awaitExpression_expression?.flushInformative();
-      expression_type?.flushInformative();
-    } else if (kind == idl.LinkedNodeKind.binaryExpression) {
-      binaryExpression_invokeType?.flushInformative();
-      binaryExpression_leftOperand?.flushInformative();
-      binaryExpression_rightOperand?.flushInformative();
-      binaryExpression_substitution?.flushInformative();
-      expression_type?.flushInformative();
-    } else if (kind == idl.LinkedNodeKind.block) {
-      block_statements?.forEach((b) => b.flushInformative());
-    } else if (kind == idl.LinkedNodeKind.blockFunctionBody) {
-      blockFunctionBody_block?.flushInformative();
-    } else if (kind == idl.LinkedNodeKind.booleanLiteral) {
-    } else if (kind == idl.LinkedNodeKind.breakStatement) {
-      breakStatement_label?.flushInformative();
-    } else if (kind == idl.LinkedNodeKind.cascadeExpression) {
-      cascadeExpression_sections?.forEach((b) => b.flushInformative());
-      cascadeExpression_target?.flushInformative();
-      expression_type?.flushInformative();
-    } else if (kind == idl.LinkedNodeKind.catchClause) {
-      catchClause_body?.flushInformative();
-      catchClause_exceptionParameter?.flushInformative();
-      catchClause_exceptionType?.flushInformative();
-      catchClause_stackTraceParameter?.flushInformative();
-    } else if (kind == idl.LinkedNodeKind.classDeclaration) {
-      annotatedNode_metadata?.forEach((b) => b.flushInformative());
-      classDeclaration_extendsClause?.flushInformative();
-      classDeclaration_withClause?.flushInformative();
-      classDeclaration_nativeClause?.flushInformative();
-      classOrMixinDeclaration_implementsClause?.flushInformative();
-      classOrMixinDeclaration_members?.forEach((b) => b.flushInformative());
-      classOrMixinDeclaration_typeParameters?.flushInformative();
-      informativeId = null;
-      unused11?.flushInformative();
-    } else if (kind == idl.LinkedNodeKind.classTypeAlias) {
-      annotatedNode_metadata?.forEach((b) => b.flushInformative());
-      classTypeAlias_typeParameters?.flushInformative();
-      classTypeAlias_superclass?.flushInformative();
-      classTypeAlias_withClause?.flushInformative();
-      classTypeAlias_implementsClause?.flushInformative();
-      informativeId = null;
-    } else if (kind == idl.LinkedNodeKind.comment) {
-      comment_references?.forEach((b) => b.flushInformative());
-    } else if (kind == idl.LinkedNodeKind.commentReference) {
-      commentReference_identifier?.flushInformative();
-    } else if (kind == idl.LinkedNodeKind.compilationUnit) {
-      compilationUnit_declarations?.forEach((b) => b.flushInformative());
-      compilationUnit_scriptTag?.flushInformative();
-      compilationUnit_directives?.forEach((b) => b.flushInformative());
-      compilationUnit_languageVersion?.flushInformative();
-      informativeId = null;
-    } else if (kind == idl.LinkedNodeKind.conditionalExpression) {
-      conditionalExpression_condition?.flushInformative();
-      conditionalExpression_elseExpression?.flushInformative();
-      conditionalExpression_thenExpression?.flushInformative();
-      expression_type?.flushInformative();
-    } else if (kind == idl.LinkedNodeKind.configuration) {
-      configuration_name?.flushInformative();
-      configuration_value?.flushInformative();
-      configuration_uri?.flushInformative();
-    } else if (kind == idl.LinkedNodeKind.constructorDeclaration) {
-      constructorDeclaration_initializers?.forEach((b) => b.flushInformative());
-      annotatedNode_metadata?.forEach((b) => b.flushInformative());
-      constructorDeclaration_body?.flushInformative();
-      constructorDeclaration_parameters?.flushInformative();
-      constructorDeclaration_redirectedConstructor?.flushInformative();
-      constructorDeclaration_returnType?.flushInformative();
-      informativeId = null;
-    } else if (kind == idl.LinkedNodeKind.constructorFieldInitializer) {
-      constructorFieldInitializer_expression?.flushInformative();
-      constructorFieldInitializer_fieldName?.flushInformative();
-    } else if (kind == idl.LinkedNodeKind.constructorName) {
-      constructorName_name?.flushInformative();
-      constructorName_type?.flushInformative();
-      constructorName_substitution?.flushInformative();
-    } else if (kind == idl.LinkedNodeKind.continueStatement) {
-      continueStatement_label?.flushInformative();
-    } else if (kind == idl.LinkedNodeKind.declaredIdentifier) {
-      annotatedNode_metadata?.forEach((b) => b.flushInformative());
-      declaredIdentifier_identifier?.flushInformative();
-      declaredIdentifier_type?.flushInformative();
-    } else if (kind == idl.LinkedNodeKind.defaultFormalParameter) {
-      defaultFormalParameter_defaultValue?.flushInformative();
-      defaultFormalParameter_parameter?.flushInformative();
-      informativeId = null;
-    } else if (kind == idl.LinkedNodeKind.doStatement) {
-      doStatement_body?.flushInformative();
-      doStatement_condition?.flushInformative();
-    } else if (kind == idl.LinkedNodeKind.dottedName) {
-      dottedName_components?.forEach((b) => b.flushInformative());
-    } else if (kind == idl.LinkedNodeKind.doubleLiteral) {
-    } else if (kind == idl.LinkedNodeKind.emptyFunctionBody) {
-    } else if (kind == idl.LinkedNodeKind.emptyStatement) {
-    } else if (kind == idl.LinkedNodeKind.enumConstantDeclaration) {
-      annotatedNode_metadata?.forEach((b) => b.flushInformative());
-      informativeId = null;
-    } else if (kind == idl.LinkedNodeKind.enumDeclaration) {
-      enumDeclaration_constants?.forEach((b) => b.flushInformative());
-      annotatedNode_metadata?.forEach((b) => b.flushInformative());
-      informativeId = null;
-    } else if (kind == idl.LinkedNodeKind.exportDirective) {
-      namespaceDirective_combinators?.forEach((b) => b.flushInformative());
-      annotatedNode_metadata?.forEach((b) => b.flushInformative());
-      namespaceDirective_configurations?.forEach((b) => b.flushInformative());
-      informativeId = null;
-      uriBasedDirective_uri?.flushInformative();
-    } else if (kind == idl.LinkedNodeKind.expressionFunctionBody) {
-      expressionFunctionBody_expression?.flushInformative();
-    } else if (kind == idl.LinkedNodeKind.expressionStatement) {
-      expressionStatement_expression?.flushInformative();
-    } else if (kind == idl.LinkedNodeKind.extendsClause) {
-      extendsClause_superclass?.flushInformative();
-    } else if (kind == idl.LinkedNodeKind.extensionDeclaration) {
-      annotatedNode_metadata?.forEach((b) => b.flushInformative());
-      extensionDeclaration_typeParameters?.flushInformative();
-      extensionDeclaration_extendedType?.flushInformative();
-      extensionDeclaration_members?.forEach((b) => b.flushInformative());
-      informativeId = null;
-    } else if (kind == idl.LinkedNodeKind.extensionOverride) {
-      extensionOverride_extendedType?.flushInformative();
-      extensionOverride_arguments?.forEach((b) => b.flushInformative());
-      extensionOverride_extensionName?.flushInformative();
-      extensionOverride_typeArguments?.flushInformative();
-      extensionOverride_typeArgumentTypes?.forEach((b) => b.flushInformative());
-    } else if (kind == idl.LinkedNodeKind.fieldDeclaration) {
-      annotatedNode_metadata?.forEach((b) => b.flushInformative());
-      fieldDeclaration_fields?.flushInformative();
-      informativeId = null;
-    } else if (kind == idl.LinkedNodeKind.fieldFormalParameter) {
-      actualType?.flushInformative();
-      normalFormalParameter_metadata?.forEach((b) => b.flushInformative());
-      fieldFormalParameter_type?.flushInformative();
-      fieldFormalParameter_typeParameters?.flushInformative();
-      fieldFormalParameter_formalParameters?.flushInformative();
-      informativeId = null;
-    } else if (kind == idl.LinkedNodeKind.forEachPartsWithDeclaration) {
-      forEachParts_iterable?.flushInformative();
-      forEachPartsWithDeclaration_loopVariable?.flushInformative();
-    } else if (kind == idl.LinkedNodeKind.forEachPartsWithIdentifier) {
-      forEachParts_iterable?.flushInformative();
-      forEachPartsWithIdentifier_identifier?.flushInformative();
-    } else if (kind == idl.LinkedNodeKind.forElement) {
-      forMixin_forLoopParts?.flushInformative();
-      forElement_body?.flushInformative();
-    } else if (kind == idl.LinkedNodeKind.forPartsWithDeclarations) {
-      forParts_condition?.flushInformative();
-      forPartsWithDeclarations_variables?.flushInformative();
-      forParts_updaters?.forEach((b) => b.flushInformative());
-    } else if (kind == idl.LinkedNodeKind.forPartsWithExpression) {
-      forParts_condition?.flushInformative();
-      forPartsWithExpression_initialization?.flushInformative();
-      forParts_updaters?.forEach((b) => b.flushInformative());
-    } else if (kind == idl.LinkedNodeKind.forStatement) {
-      forMixin_forLoopParts?.flushInformative();
-      forStatement_body?.flushInformative();
-    } else if (kind == idl.LinkedNodeKind.formalParameterList) {
-      formalParameterList_parameters?.forEach((b) => b.flushInformative());
-    } else if (kind == idl.LinkedNodeKind.functionDeclaration) {
-      actualReturnType?.flushInformative();
-      annotatedNode_metadata?.forEach((b) => b.flushInformative());
-      functionDeclaration_functionExpression?.flushInformative();
-      functionDeclaration_returnType?.flushInformative();
-      informativeId = null;
-    } else if (kind == idl.LinkedNodeKind.functionDeclarationStatement) {
-      functionDeclarationStatement_functionDeclaration?.flushInformative();
-    } else if (kind == idl.LinkedNodeKind.functionExpression) {
-      actualReturnType?.flushInformative();
-      functionExpression_body?.flushInformative();
-      functionExpression_formalParameters?.flushInformative();
-      functionExpression_typeParameters?.flushInformative();
-    } else if (kind == idl.LinkedNodeKind.functionExpressionInvocation) {
-      invocationExpression_invokeType?.flushInformative();
-      functionExpressionInvocation_function?.flushInformative();
-      invocationExpression_typeArguments?.flushInformative();
-      expression_type?.flushInformative();
-      invocationExpression_arguments?.flushInformative();
-    } else if (kind == idl.LinkedNodeKind.functionTypeAlias) {
-      actualReturnType?.flushInformative();
-      annotatedNode_metadata?.forEach((b) => b.flushInformative());
-      functionTypeAlias_formalParameters?.flushInformative();
-      functionTypeAlias_returnType?.flushInformative();
-      functionTypeAlias_typeParameters?.flushInformative();
-      informativeId = null;
-    } else if (kind == idl.LinkedNodeKind.functionTypedFormalParameter) {
-      actualType?.flushInformative();
-      normalFormalParameter_metadata?.forEach((b) => b.flushInformative());
-      functionTypedFormalParameter_formalParameters?.flushInformative();
-      functionTypedFormalParameter_returnType?.flushInformative();
-      functionTypedFormalParameter_typeParameters?.flushInformative();
-      informativeId = null;
-    } else if (kind == idl.LinkedNodeKind.genericFunctionType) {
-      actualReturnType?.flushInformative();
-      genericFunctionType_typeParameters?.flushInformative();
-      genericFunctionType_returnType?.flushInformative();
-      genericFunctionType_formalParameters?.flushInformative();
-      genericFunctionType_type?.flushInformative();
-    } else if (kind == idl.LinkedNodeKind.genericTypeAlias) {
-      annotatedNode_metadata?.forEach((b) => b.flushInformative());
-      genericTypeAlias_typeParameters?.flushInformative();
-      genericTypeAlias_functionType?.flushInformative();
-      informativeId = null;
-    } else if (kind == idl.LinkedNodeKind.hideCombinator) {
-      informativeId = null;
-    } else if (kind == idl.LinkedNodeKind.ifElement) {
-      ifMixin_condition?.flushInformative();
-      ifElement_thenElement?.flushInformative();
-      ifElement_elseElement?.flushInformative();
-    } else if (kind == idl.LinkedNodeKind.ifStatement) {
-      ifMixin_condition?.flushInformative();
-      ifStatement_elseStatement?.flushInformative();
-      ifStatement_thenStatement?.flushInformative();
-    } else if (kind == idl.LinkedNodeKind.implementsClause) {
-      implementsClause_interfaces?.forEach((b) => b.flushInformative());
-    } else if (kind == idl.LinkedNodeKind.importDirective) {
-      namespaceDirective_combinators?.forEach((b) => b.flushInformative());
-      annotatedNode_metadata?.forEach((b) => b.flushInformative());
-      namespaceDirective_configurations?.forEach((b) => b.flushInformative());
-      informativeId = null;
-      uriBasedDirective_uri?.flushInformative();
-    } else if (kind == idl.LinkedNodeKind.indexExpression) {
-      indexExpression_index?.flushInformative();
-      indexExpression_target?.flushInformative();
-      indexExpression_substitution?.flushInformative();
-      expression_type?.flushInformative();
-    } else if (kind == idl.LinkedNodeKind.instanceCreationExpression) {
-      instanceCreationExpression_arguments
-          ?.forEach((b) => b.flushInformative());
-      instanceCreationExpression_constructorName?.flushInformative();
-      instanceCreationExpression_typeArguments?.flushInformative();
-      expression_type?.flushInformative();
-    } else if (kind == idl.LinkedNodeKind.integerLiteral) {
-      expression_type?.flushInformative();
-    } else if (kind == idl.LinkedNodeKind.interpolationExpression) {
-      interpolationExpression_expression?.flushInformative();
-    } else if (kind == idl.LinkedNodeKind.interpolationString) {
-    } else if (kind == idl.LinkedNodeKind.isExpression) {
-      isExpression_expression?.flushInformative();
-      isExpression_type?.flushInformative();
-    } else if (kind == idl.LinkedNodeKind.label) {
-      label_label?.flushInformative();
-    } else if (kind == idl.LinkedNodeKind.labeledStatement) {
-      labeledStatement_labels?.forEach((b) => b.flushInformative());
-      labeledStatement_statement?.flushInformative();
-    } else if (kind == idl.LinkedNodeKind.libraryDirective) {
-      annotatedNode_metadata?.forEach((b) => b.flushInformative());
-      libraryDirective_name?.flushInformative();
-      informativeId = null;
-    } else if (kind == idl.LinkedNodeKind.libraryIdentifier) {
-      libraryIdentifier_components?.forEach((b) => b.flushInformative());
-    } else if (kind == idl.LinkedNodeKind.listLiteral) {
-      typedLiteral_typeArguments?.forEach((b) => b.flushInformative());
-      listLiteral_elements?.forEach((b) => b.flushInformative());
-      expression_type?.flushInformative();
-    } else if (kind == idl.LinkedNodeKind.mapLiteralEntry) {
-      mapLiteralEntry_key?.flushInformative();
-      mapLiteralEntry_value?.flushInformative();
-    } else if (kind == idl.LinkedNodeKind.methodDeclaration) {
-      actualReturnType?.flushInformative();
-      annotatedNode_metadata?.forEach((b) => b.flushInformative());
-      methodDeclaration_body?.flushInformative();
-      methodDeclaration_formalParameters?.flushInformative();
-      methodDeclaration_returnType?.flushInformative();
-      methodDeclaration_typeParameters?.flushInformative();
-      informativeId = null;
-      topLevelTypeInferenceError?.flushInformative();
-    } else if (kind == idl.LinkedNodeKind.methodInvocation) {
-      invocationExpression_invokeType?.flushInformative();
-      methodInvocation_methodName?.flushInformative();
-      methodInvocation_target?.flushInformative();
-      invocationExpression_typeArguments?.flushInformative();
-      expression_type?.flushInformative();
-      invocationExpression_arguments?.flushInformative();
-    } else if (kind == idl.LinkedNodeKind.mixinDeclaration) {
-      annotatedNode_metadata?.forEach((b) => b.flushInformative());
-      mixinDeclaration_onClause?.flushInformative();
-      classOrMixinDeclaration_implementsClause?.flushInformative();
-      classOrMixinDeclaration_members?.forEach((b) => b.flushInformative());
-      classOrMixinDeclaration_typeParameters?.flushInformative();
-      informativeId = null;
-    } else if (kind == idl.LinkedNodeKind.namedExpression) {
-      namedExpression_expression?.flushInformative();
-      namedExpression_name?.flushInformative();
-    } else if (kind == idl.LinkedNodeKind.nativeClause) {
-      nativeClause_name?.flushInformative();
-    } else if (kind == idl.LinkedNodeKind.nativeFunctionBody) {
-      nativeFunctionBody_stringLiteral?.flushInformative();
-    } else if (kind == idl.LinkedNodeKind.nullLiteral) {
-      expression_type?.flushInformative();
-    } else if (kind == idl.LinkedNodeKind.onClause) {
-      onClause_superclassConstraints?.forEach((b) => b.flushInformative());
-    } else if (kind == idl.LinkedNodeKind.parenthesizedExpression) {
-      parenthesizedExpression_expression?.flushInformative();
-      expression_type?.flushInformative();
-    } else if (kind == idl.LinkedNodeKind.partDirective) {
-      annotatedNode_metadata?.forEach((b) => b.flushInformative());
-      informativeId = null;
-      uriBasedDirective_uri?.flushInformative();
-    } else if (kind == idl.LinkedNodeKind.partOfDirective) {
-      annotatedNode_metadata?.forEach((b) => b.flushInformative());
-      partOfDirective_libraryName?.flushInformative();
-      partOfDirective_uri?.flushInformative();
-      informativeId = null;
-    } else if (kind == idl.LinkedNodeKind.postfixExpression) {
-      postfixExpression_operand?.flushInformative();
-      postfixExpression_substitution?.flushInformative();
-      expression_type?.flushInformative();
-    } else if (kind == idl.LinkedNodeKind.prefixExpression) {
-      prefixExpression_operand?.flushInformative();
-      prefixExpression_substitution?.flushInformative();
-      expression_type?.flushInformative();
-    } else if (kind == idl.LinkedNodeKind.prefixedIdentifier) {
-      prefixedIdentifier_identifier?.flushInformative();
-      prefixedIdentifier_prefix?.flushInformative();
-      expression_type?.flushInformative();
-    } else if (kind == idl.LinkedNodeKind.propertyAccess) {
-      propertyAccess_propertyName?.flushInformative();
-      propertyAccess_target?.flushInformative();
-      expression_type?.flushInformative();
-    } else if (kind == idl.LinkedNodeKind.redirectingConstructorInvocation) {
-      redirectingConstructorInvocation_arguments?.flushInformative();
-      redirectingConstructorInvocation_constructorName?.flushInformative();
-      redirectingConstructorInvocation_substitution?.flushInformative();
-    } else if (kind == idl.LinkedNodeKind.rethrowExpression) {
-      expression_type?.flushInformative();
-    } else if (kind == idl.LinkedNodeKind.returnStatement) {
-      returnStatement_expression?.flushInformative();
-    } else if (kind == idl.LinkedNodeKind.setOrMapLiteral) {
-      typedLiteral_typeArguments?.forEach((b) => b.flushInformative());
-      setOrMapLiteral_elements?.forEach((b) => b.flushInformative());
-      expression_type?.flushInformative();
-    } else if (kind == idl.LinkedNodeKind.showCombinator) {
-      informativeId = null;
-    } else if (kind == idl.LinkedNodeKind.simpleFormalParameter) {
-      actualType?.flushInformative();
-      normalFormalParameter_metadata?.forEach((b) => b.flushInformative());
-      simpleFormalParameter_type?.flushInformative();
-      informativeId = null;
-      topLevelTypeInferenceError?.flushInformative();
-    } else if (kind == idl.LinkedNodeKind.simpleIdentifier) {
-      simpleIdentifier_substitution?.flushInformative();
-      expression_type?.flushInformative();
-    } else if (kind == idl.LinkedNodeKind.simpleStringLiteral) {
-    } else if (kind == idl.LinkedNodeKind.spreadElement) {
-      spreadElement_expression?.flushInformative();
-    } else if (kind == idl.LinkedNodeKind.stringInterpolation) {
-      stringInterpolation_elements?.forEach((b) => b.flushInformative());
-    } else if (kind == idl.LinkedNodeKind.superConstructorInvocation) {
-      superConstructorInvocation_arguments?.flushInformative();
-      superConstructorInvocation_constructorName?.flushInformative();
-      superConstructorInvocation_substitution?.flushInformative();
-    } else if (kind == idl.LinkedNodeKind.superExpression) {
-      expression_type?.flushInformative();
-    } else if (kind == idl.LinkedNodeKind.switchCase) {
-      switchMember_statements?.forEach((b) => b.flushInformative());
-      switchCase_expression?.flushInformative();
-      switchMember_labels?.forEach((b) => b.flushInformative());
-    } else if (kind == idl.LinkedNodeKind.switchDefault) {
-      switchMember_statements?.forEach((b) => b.flushInformative());
-      switchMember_labels?.forEach((b) => b.flushInformative());
-    } else if (kind == idl.LinkedNodeKind.switchStatement) {
-      switchStatement_members?.forEach((b) => b.flushInformative());
-      switchStatement_expression?.flushInformative();
-    } else if (kind == idl.LinkedNodeKind.symbolLiteral) {
-      expression_type?.flushInformative();
-    } else if (kind == idl.LinkedNodeKind.thisExpression) {
-      expression_type?.flushInformative();
-    } else if (kind == idl.LinkedNodeKind.throwExpression) {
-      throwExpression_expression?.flushInformative();
-      expression_type?.flushInformative();
-    } else if (kind == idl.LinkedNodeKind.topLevelVariableDeclaration) {
-      annotatedNode_metadata?.forEach((b) => b.flushInformative());
-      topLevelVariableDeclaration_variableList?.flushInformative();
-      informativeId = null;
-    } else if (kind == idl.LinkedNodeKind.tryStatement) {
-      tryStatement_catchClauses?.forEach((b) => b.flushInformative());
-      tryStatement_body?.flushInformative();
-      tryStatement_finallyBlock?.flushInformative();
-    } else if (kind == idl.LinkedNodeKind.typeArgumentList) {
-      typeArgumentList_arguments?.forEach((b) => b.flushInformative());
-    } else if (kind == idl.LinkedNodeKind.typeName) {
-      typeName_typeArguments?.forEach((b) => b.flushInformative());
-      typeName_name?.flushInformative();
-      typeName_type?.flushInformative();
-    } else if (kind == idl.LinkedNodeKind.typeParameter) {
-      annotatedNode_metadata?.forEach((b) => b.flushInformative());
-      typeParameter_bound?.flushInformative();
-      informativeId = null;
-      typeParameter_defaultType?.flushInformative();
-    } else if (kind == idl.LinkedNodeKind.typeParameterList) {
-      typeParameterList_typeParameters?.forEach((b) => b.flushInformative());
-    } else if (kind == idl.LinkedNodeKind.variableDeclaration) {
-      actualType?.flushInformative();
-      annotatedNode_metadata?.forEach((b) => b.flushInformative());
-      variableDeclaration_initializer?.flushInformative();
-      informativeId = null;
-      topLevelTypeInferenceError?.flushInformative();
-    } else if (kind == idl.LinkedNodeKind.variableDeclarationList) {
-      variableDeclarationList_variables?.forEach((b) => b.flushInformative());
-      annotatedNode_metadata?.forEach((b) => b.flushInformative());
-      variableDeclarationList_type?.flushInformative();
-      informativeId = null;
-    } else if (kind == idl.LinkedNodeKind.variableDeclarationStatement) {
-      variableDeclarationStatement_variables?.flushInformative();
-    } else if (kind == idl.LinkedNodeKind.whileStatement) {
-      whileStatement_body?.flushInformative();
-      whileStatement_condition?.flushInformative();
-    } else if (kind == idl.LinkedNodeKind.withClause) {
-      withClause_mixinTypes?.forEach((b) => b.flushInformative());
-    } else if (kind == idl.LinkedNodeKind.yieldStatement) {
-      yieldStatement_expression?.flushInformative();
-    }
-  }
-
-  /// Accumulate non-[informative] data into [signature].
-  void collectApiSignature(api_sig.ApiSignature signature) {
-    if (kind == idl.LinkedNodeKind.adjacentStrings) {
-      signature.addInt(this.kind == null ? 0 : this.kind.index);
-      if (this.adjacentStrings_strings == null) {
-        signature.addInt(0);
-      } else {
-        signature.addInt(this.adjacentStrings_strings.length);
-        for (var x in this.adjacentStrings_strings) {
-          x?.collectApiSignature(signature);
-        }
-      }
-      signature.addInt(this.flags ?? 0);
-      signature.addString(this.name ?? '');
-    } else if (kind == idl.LinkedNodeKind.annotation) {
-      signature.addInt(this.kind == null ? 0 : this.kind.index);
-      signature.addBool(this.annotation_arguments != null);
-      this.annotation_arguments?.collectApiSignature(signature);
-      signature.addBool(this.annotation_constructorName != null);
-      this.annotation_constructorName?.collectApiSignature(signature);
-      signature.addBool(this.annotation_name != null);
-      this.annotation_name?.collectApiSignature(signature);
-      signature.addInt(this.annotation_element ?? 0);
-      signature.addInt(this.flags ?? 0);
-      signature.addString(this.name ?? '');
-      signature.addBool(this.annotation_substitution != null);
-      this.annotation_substitution?.collectApiSignature(signature);
-    } else if (kind == idl.LinkedNodeKind.argumentList) {
-      signature.addInt(this.kind == null ? 0 : this.kind.index);
-      if (this.argumentList_arguments == null) {
-        signature.addInt(0);
-      } else {
-        signature.addInt(this.argumentList_arguments.length);
-        for (var x in this.argumentList_arguments) {
-          x?.collectApiSignature(signature);
-        }
-      }
-      signature.addInt(this.flags ?? 0);
-      signature.addString(this.name ?? '');
-    } else if (kind == idl.LinkedNodeKind.asExpression) {
-      signature.addInt(this.kind == null ? 0 : this.kind.index);
-      signature.addBool(this.asExpression_expression != null);
-      this.asExpression_expression?.collectApiSignature(signature);
-      signature.addBool(this.asExpression_type != null);
-      this.asExpression_type?.collectApiSignature(signature);
-      signature.addInt(this.flags ?? 0);
-      signature.addBool(this.expression_type != null);
-      this.expression_type?.collectApiSignature(signature);
-      signature.addString(this.name ?? '');
-    } else if (kind == idl.LinkedNodeKind.assertInitializer) {
-      signature.addInt(this.kind == null ? 0 : this.kind.index);
-      signature.addBool(this.assertInitializer_condition != null);
-      this.assertInitializer_condition?.collectApiSignature(signature);
-      signature.addBool(this.assertInitializer_message != null);
-      this.assertInitializer_message?.collectApiSignature(signature);
-      signature.addInt(this.flags ?? 0);
-      signature.addString(this.name ?? '');
-    } else if (kind == idl.LinkedNodeKind.assertStatement) {
-      signature.addInt(this.kind == null ? 0 : this.kind.index);
-      signature.addBool(this.assertStatement_condition != null);
-      this.assertStatement_condition?.collectApiSignature(signature);
-      signature.addBool(this.assertStatement_message != null);
-      this.assertStatement_message?.collectApiSignature(signature);
-      signature.addInt(this.flags ?? 0);
-      signature.addString(this.name ?? '');
-    } else if (kind == idl.LinkedNodeKind.assignmentExpression) {
-      signature.addInt(this.kind == null ? 0 : this.kind.index);
-      signature.addBool(this.assignmentExpression_leftHandSide != null);
-      this.assignmentExpression_leftHandSide?.collectApiSignature(signature);
-      signature.addBool(this.assignmentExpression_rightHandSide != null);
-      this.assignmentExpression_rightHandSide?.collectApiSignature(signature);
-      signature.addInt(this.assignmentExpression_element ?? 0);
-      signature.addInt(this.flags ?? 0);
-      signature.addBool(this.expression_type != null);
-      this.expression_type?.collectApiSignature(signature);
-      signature.addInt(this.assignmentExpression_operator == null
-          ? 0
-          : this.assignmentExpression_operator.index);
-      signature.addString(this.name ?? '');
-      signature.addBool(this.assignmentExpression_substitution != null);
-      this.assignmentExpression_substitution?.collectApiSignature(signature);
-    } else if (kind == idl.LinkedNodeKind.awaitExpression) {
-      signature.addInt(this.kind == null ? 0 : this.kind.index);
-      signature.addBool(this.awaitExpression_expression != null);
-      this.awaitExpression_expression?.collectApiSignature(signature);
-      signature.addInt(this.flags ?? 0);
-      signature.addBool(this.expression_type != null);
-      this.expression_type?.collectApiSignature(signature);
-      signature.addString(this.name ?? '');
-    } else if (kind == idl.LinkedNodeKind.binaryExpression) {
-      signature.addInt(this.kind == null ? 0 : this.kind.index);
-      signature.addBool(this.binaryExpression_leftOperand != null);
-      this.binaryExpression_leftOperand?.collectApiSignature(signature);
-      signature.addBool(this.binaryExpression_rightOperand != null);
-      this.binaryExpression_rightOperand?.collectApiSignature(signature);
-      signature.addInt(this.binaryExpression_element ?? 0);
-      signature.addInt(this.flags ?? 0);
-      signature.addBool(this.binaryExpression_invokeType != null);
-      this.binaryExpression_invokeType?.collectApiSignature(signature);
-      signature.addBool(this.expression_type != null);
-      this.expression_type?.collectApiSignature(signature);
-      signature.addInt(this.binaryExpression_operator == null
-          ? 0
-          : this.binaryExpression_operator.index);
-      signature.addString(this.name ?? '');
-      signature.addBool(this.binaryExpression_substitution != null);
-      this.binaryExpression_substitution?.collectApiSignature(signature);
-    } else if (kind == idl.LinkedNodeKind.block) {
-      signature.addInt(this.kind == null ? 0 : this.kind.index);
-      if (this.block_statements == null) {
-        signature.addInt(0);
-      } else {
-        signature.addInt(this.block_statements.length);
-        for (var x in this.block_statements) {
-          x?.collectApiSignature(signature);
-        }
-      }
-      signature.addInt(this.flags ?? 0);
-      signature.addString(this.name ?? '');
-    } else if (kind == idl.LinkedNodeKind.blockFunctionBody) {
-      signature.addInt(this.kind == null ? 0 : this.kind.index);
-      signature.addBool(this.blockFunctionBody_block != null);
-      this.blockFunctionBody_block?.collectApiSignature(signature);
-      signature.addInt(this.flags ?? 0);
-      signature.addString(this.name ?? '');
-    } else if (kind == idl.LinkedNodeKind.booleanLiteral) {
-      signature.addInt(this.kind == null ? 0 : this.kind.index);
-      signature.addInt(this.flags ?? 0);
-      signature.addBool(this.booleanLiteral_value == true);
-      signature.addString(this.name ?? '');
-    } else if (kind == idl.LinkedNodeKind.breakStatement) {
-      signature.addInt(this.kind == null ? 0 : this.kind.index);
-      signature.addBool(this.breakStatement_label != null);
-      this.breakStatement_label?.collectApiSignature(signature);
-      signature.addInt(this.flags ?? 0);
-      signature.addString(this.name ?? '');
-    } else if (kind == idl.LinkedNodeKind.cascadeExpression) {
-      signature.addInt(this.kind == null ? 0 : this.kind.index);
-      if (this.cascadeExpression_sections == null) {
-        signature.addInt(0);
-      } else {
-        signature.addInt(this.cascadeExpression_sections.length);
-        for (var x in this.cascadeExpression_sections) {
-          x?.collectApiSignature(signature);
-        }
-      }
-      signature.addBool(this.cascadeExpression_target != null);
-      this.cascadeExpression_target?.collectApiSignature(signature);
-      signature.addInt(this.flags ?? 0);
-      signature.addBool(this.expression_type != null);
-      this.expression_type?.collectApiSignature(signature);
-      signature.addString(this.name ?? '');
-    } else if (kind == idl.LinkedNodeKind.catchClause) {
-      signature.addInt(this.kind == null ? 0 : this.kind.index);
-      signature.addBool(this.catchClause_body != null);
-      this.catchClause_body?.collectApiSignature(signature);
-      signature.addBool(this.catchClause_exceptionParameter != null);
-      this.catchClause_exceptionParameter?.collectApiSignature(signature);
-      signature.addBool(this.catchClause_exceptionType != null);
-      this.catchClause_exceptionType?.collectApiSignature(signature);
-      signature.addBool(this.catchClause_stackTraceParameter != null);
-      this.catchClause_stackTraceParameter?.collectApiSignature(signature);
-      signature.addInt(this.flags ?? 0);
-      signature.addString(this.name ?? '');
-    } else if (kind == idl.LinkedNodeKind.classDeclaration) {
-      signature.addInt(this.kind == null ? 0 : this.kind.index);
-      if (this.annotatedNode_metadata == null) {
-        signature.addInt(0);
-      } else {
-        signature.addInt(this.annotatedNode_metadata.length);
-        for (var x in this.annotatedNode_metadata) {
-          x?.collectApiSignature(signature);
-        }
-      }
-      if (this.classOrMixinDeclaration_members == null) {
-        signature.addInt(0);
-      } else {
-        signature.addInt(this.classOrMixinDeclaration_members.length);
-        for (var x in this.classOrMixinDeclaration_members) {
-          x?.collectApiSignature(signature);
-        }
-      }
-      signature.addBool(this.classDeclaration_extendsClause != null);
-      this.classDeclaration_extendsClause?.collectApiSignature(signature);
-      signature.addBool(this.classDeclaration_withClause != null);
-      this.classDeclaration_withClause?.collectApiSignature(signature);
-      signature.addBool(this.classDeclaration_nativeClause != null);
-      this.classDeclaration_nativeClause?.collectApiSignature(signature);
-      signature.addBool(this.unused11 != null);
-      this.unused11?.collectApiSignature(signature);
-      signature.addBool(this.classOrMixinDeclaration_implementsClause != null);
-      this
-          .classOrMixinDeclaration_implementsClause
-          ?.collectApiSignature(signature);
-      signature.addBool(this.classOrMixinDeclaration_typeParameters != null);
-      this
-          .classOrMixinDeclaration_typeParameters
-          ?.collectApiSignature(signature);
-      signature.addInt(this.flags ?? 0);
-      signature.addBool(this.classDeclaration_isDartObject == true);
-      signature.addBool(this.simplyBoundable_isSimplyBounded == true);
-      signature.addString(this.name ?? '');
-    } else if (kind == idl.LinkedNodeKind.classTypeAlias) {
-      signature.addInt(this.kind == null ? 0 : this.kind.index);
-      if (this.annotatedNode_metadata == null) {
-        signature.addInt(0);
-      } else {
-        signature.addInt(this.annotatedNode_metadata.length);
-        for (var x in this.annotatedNode_metadata) {
-          x?.collectApiSignature(signature);
-        }
-      }
-      signature.addBool(this.classTypeAlias_typeParameters != null);
-      this.classTypeAlias_typeParameters?.collectApiSignature(signature);
-      signature.addBool(this.classTypeAlias_superclass != null);
-      this.classTypeAlias_superclass?.collectApiSignature(signature);
-      signature.addBool(this.classTypeAlias_withClause != null);
-      this.classTypeAlias_withClause?.collectApiSignature(signature);
-      signature.addBool(this.classTypeAlias_implementsClause != null);
-      this.classTypeAlias_implementsClause?.collectApiSignature(signature);
-      signature.addInt(this.flags ?? 0);
-      signature.addBool(this.simplyBoundable_isSimplyBounded == true);
-      signature.addString(this.name ?? '');
-    } else if (kind == idl.LinkedNodeKind.comment) {
-      signature.addInt(this.kind == null ? 0 : this.kind.index);
-      if (this.comment_references == null) {
-        signature.addInt(0);
-      } else {
-        signature.addInt(this.comment_references.length);
-        for (var x in this.comment_references) {
-          x?.collectApiSignature(signature);
-        }
-      }
-      signature.addInt(this.flags ?? 0);
-      signature.addInt(this.comment_type == null ? 0 : this.comment_type.index);
-      if (this.comment_tokens == null) {
-        signature.addInt(0);
-      } else {
-        signature.addInt(this.comment_tokens.length);
-        for (var x in this.comment_tokens) {
-          signature.addString(x);
-        }
-      }
-      signature.addString(this.name ?? '');
-    } else if (kind == idl.LinkedNodeKind.commentReference) {
-      signature.addInt(this.kind == null ? 0 : this.kind.index);
-      signature.addBool(this.commentReference_identifier != null);
-      this.commentReference_identifier?.collectApiSignature(signature);
-      signature.addInt(this.flags ?? 0);
-      signature.addString(this.name ?? '');
-    } else if (kind == idl.LinkedNodeKind.compilationUnit) {
-      signature.addInt(this.kind == null ? 0 : this.kind.index);
-      if (this.compilationUnit_declarations == null) {
-        signature.addInt(0);
-      } else {
-        signature.addInt(this.compilationUnit_declarations.length);
-        for (var x in this.compilationUnit_declarations) {
-          x?.collectApiSignature(signature);
-        }
-      }
-      if (this.compilationUnit_directives == null) {
-        signature.addInt(0);
-      } else {
-        signature.addInt(this.compilationUnit_directives.length);
-        for (var x in this.compilationUnit_directives) {
-          x?.collectApiSignature(signature);
-        }
-      }
-      signature.addBool(this.compilationUnit_scriptTag != null);
-      this.compilationUnit_scriptTag?.collectApiSignature(signature);
-      signature.addInt(this.flags ?? 0);
-      signature.addString(this.name ?? '');
-      signature.addBool(this.compilationUnit_languageVersion != null);
-      this.compilationUnit_languageVersion?.collectApiSignature(signature);
-      if (this.compilationUnit_featureSet == null) {
-        signature.addInt(0);
-      } else {
-        signature.addInt(this.compilationUnit_featureSet.length);
-        for (var x in this.compilationUnit_featureSet) {
-          signature.addInt(x);
-        }
-      }
-    } else if (kind == idl.LinkedNodeKind.conditionalExpression) {
-      signature.addInt(this.kind == null ? 0 : this.kind.index);
-      signature.addBool(this.conditionalExpression_condition != null);
-      this.conditionalExpression_condition?.collectApiSignature(signature);
-      signature.addBool(this.conditionalExpression_elseExpression != null);
-      this.conditionalExpression_elseExpression?.collectApiSignature(signature);
-      signature.addBool(this.conditionalExpression_thenExpression != null);
-      this.conditionalExpression_thenExpression?.collectApiSignature(signature);
-      signature.addInt(this.flags ?? 0);
-      signature.addBool(this.expression_type != null);
-      this.expression_type?.collectApiSignature(signature);
-      signature.addString(this.name ?? '');
-    } else if (kind == idl.LinkedNodeKind.configuration) {
-      signature.addInt(this.kind == null ? 0 : this.kind.index);
-      signature.addBool(this.configuration_name != null);
-      this.configuration_name?.collectApiSignature(signature);
-      signature.addBool(this.configuration_value != null);
-      this.configuration_value?.collectApiSignature(signature);
-      signature.addBool(this.configuration_uri != null);
-      this.configuration_uri?.collectApiSignature(signature);
-      signature.addInt(this.flags ?? 0);
-      signature.addString(this.name ?? '');
-    } else if (kind == idl.LinkedNodeKind.constructorDeclaration) {
-      signature.addInt(this.kind == null ? 0 : this.kind.index);
-      if (this.constructorDeclaration_initializers == null) {
-        signature.addInt(0);
-      } else {
-        signature.addInt(this.constructorDeclaration_initializers.length);
-        for (var x in this.constructorDeclaration_initializers) {
-          x?.collectApiSignature(signature);
-        }
-      }
-      if (this.annotatedNode_metadata == null) {
-        signature.addInt(0);
-      } else {
-        signature.addInt(this.annotatedNode_metadata.length);
-        for (var x in this.annotatedNode_metadata) {
-          x?.collectApiSignature(signature);
-        }
-      }
-      signature.addBool(this.constructorDeclaration_body != null);
-      this.constructorDeclaration_body?.collectApiSignature(signature);
-      signature.addBool(this.constructorDeclaration_parameters != null);
-      this.constructorDeclaration_parameters?.collectApiSignature(signature);
-      signature
-          .addBool(this.constructorDeclaration_redirectedConstructor != null);
-      this
-          .constructorDeclaration_redirectedConstructor
-          ?.collectApiSignature(signature);
-      signature.addBool(this.constructorDeclaration_returnType != null);
-      this.constructorDeclaration_returnType?.collectApiSignature(signature);
-      signature.addInt(this.flags ?? 0);
-      signature.addString(this.name ?? '');
-    } else if (kind == idl.LinkedNodeKind.constructorFieldInitializer) {
-      signature.addInt(this.kind == null ? 0 : this.kind.index);
-      signature.addBool(this.constructorFieldInitializer_expression != null);
-      this
-          .constructorFieldInitializer_expression
-          ?.collectApiSignature(signature);
-      signature.addBool(this.constructorFieldInitializer_fieldName != null);
-      this
-          .constructorFieldInitializer_fieldName
-          ?.collectApiSignature(signature);
-      signature.addInt(this.flags ?? 0);
-      signature.addString(this.name ?? '');
-    } else if (kind == idl.LinkedNodeKind.constructorName) {
-      signature.addInt(this.kind == null ? 0 : this.kind.index);
-      signature.addBool(this.constructorName_name != null);
-      this.constructorName_name?.collectApiSignature(signature);
-      signature.addBool(this.constructorName_type != null);
-      this.constructorName_type?.collectApiSignature(signature);
-      signature.addInt(this.constructorName_element ?? 0);
-      signature.addInt(this.flags ?? 0);
-      signature.addString(this.name ?? '');
-      signature.addBool(this.constructorName_substitution != null);
-      this.constructorName_substitution?.collectApiSignature(signature);
-    } else if (kind == idl.LinkedNodeKind.continueStatement) {
-      signature.addInt(this.kind == null ? 0 : this.kind.index);
-      signature.addBool(this.continueStatement_label != null);
-      this.continueStatement_label?.collectApiSignature(signature);
-      signature.addInt(this.flags ?? 0);
-      signature.addString(this.name ?? '');
-    } else if (kind == idl.LinkedNodeKind.declaredIdentifier) {
-      signature.addInt(this.kind == null ? 0 : this.kind.index);
-      if (this.annotatedNode_metadata == null) {
-        signature.addInt(0);
-      } else {
-        signature.addInt(this.annotatedNode_metadata.length);
-        for (var x in this.annotatedNode_metadata) {
-          x?.collectApiSignature(signature);
-        }
-      }
-      signature.addBool(this.declaredIdentifier_identifier != null);
-      this.declaredIdentifier_identifier?.collectApiSignature(signature);
-      signature.addBool(this.declaredIdentifier_type != null);
-      this.declaredIdentifier_type?.collectApiSignature(signature);
-      signature.addInt(this.flags ?? 0);
-      signature.addString(this.name ?? '');
-    } else if (kind == idl.LinkedNodeKind.defaultFormalParameter) {
-      signature.addInt(this.kind == null ? 0 : this.kind.index);
-      signature.addBool(this.defaultFormalParameter_defaultValue != null);
-      this.defaultFormalParameter_defaultValue?.collectApiSignature(signature);
-      signature.addBool(this.defaultFormalParameter_parameter != null);
-      this.defaultFormalParameter_parameter?.collectApiSignature(signature);
-      signature.addInt(this.flags ?? 0);
-      signature.addInt(this.defaultFormalParameter_kind == null
-          ? 0
-          : this.defaultFormalParameter_kind.index);
-      signature.addString(this.name ?? '');
-    } else if (kind == idl.LinkedNodeKind.doStatement) {
-      signature.addInt(this.kind == null ? 0 : this.kind.index);
-      signature.addBool(this.doStatement_body != null);
-      this.doStatement_body?.collectApiSignature(signature);
-      signature.addBool(this.doStatement_condition != null);
-      this.doStatement_condition?.collectApiSignature(signature);
-      signature.addInt(this.flags ?? 0);
-      signature.addString(this.name ?? '');
-    } else if (kind == idl.LinkedNodeKind.dottedName) {
-      signature.addInt(this.kind == null ? 0 : this.kind.index);
-      if (this.dottedName_components == null) {
-        signature.addInt(0);
-      } else {
-        signature.addInt(this.dottedName_components.length);
-        for (var x in this.dottedName_components) {
-          x?.collectApiSignature(signature);
-        }
-      }
-      signature.addInt(this.flags ?? 0);
-      signature.addString(this.name ?? '');
-    } else if (kind == idl.LinkedNodeKind.doubleLiteral) {
-      signature.addInt(this.kind == null ? 0 : this.kind.index);
-      signature.addInt(this.flags ?? 0);
-      signature.addDouble(this.doubleLiteral_value ?? 0.0);
-      signature.addString(this.name ?? '');
-    } else if (kind == idl.LinkedNodeKind.emptyFunctionBody) {
-      signature.addInt(this.kind == null ? 0 : this.kind.index);
-      signature.addInt(this.emptyFunctionBody_fake ?? 0);
-      signature.addInt(this.flags ?? 0);
-      signature.addString(this.name ?? '');
-    } else if (kind == idl.LinkedNodeKind.emptyStatement) {
-      signature.addInt(this.kind == null ? 0 : this.kind.index);
-      signature.addInt(this.emptyStatement_fake ?? 0);
-      signature.addInt(this.flags ?? 0);
-      signature.addString(this.name ?? '');
-    } else if (kind == idl.LinkedNodeKind.enumConstantDeclaration) {
-      signature.addInt(this.kind == null ? 0 : this.kind.index);
-      if (this.annotatedNode_metadata == null) {
-        signature.addInt(0);
-      } else {
-        signature.addInt(this.annotatedNode_metadata.length);
-        for (var x in this.annotatedNode_metadata) {
-          x?.collectApiSignature(signature);
-        }
-      }
-      signature.addInt(this.flags ?? 0);
-      signature.addString(this.name ?? '');
-    } else if (kind == idl.LinkedNodeKind.enumDeclaration) {
-      signature.addInt(this.kind == null ? 0 : this.kind.index);
-      if (this.enumDeclaration_constants == null) {
-        signature.addInt(0);
-      } else {
-        signature.addInt(this.enumDeclaration_constants.length);
-        for (var x in this.enumDeclaration_constants) {
-          x?.collectApiSignature(signature);
-        }
-      }
-      if (this.annotatedNode_metadata == null) {
-        signature.addInt(0);
-      } else {
-        signature.addInt(this.annotatedNode_metadata.length);
-        for (var x in this.annotatedNode_metadata) {
-          x?.collectApiSignature(signature);
-        }
-      }
-      signature.addInt(this.flags ?? 0);
-      signature.addString(this.name ?? '');
-    } else if (kind == idl.LinkedNodeKind.exportDirective) {
-      signature.addInt(this.kind == null ? 0 : this.kind.index);
-      if (this.namespaceDirective_combinators == null) {
-        signature.addInt(0);
-      } else {
-        signature.addInt(this.namespaceDirective_combinators.length);
-        for (var x in this.namespaceDirective_combinators) {
-          x?.collectApiSignature(signature);
-        }
-      }
-      if (this.namespaceDirective_configurations == null) {
-        signature.addInt(0);
-      } else {
-        signature.addInt(this.namespaceDirective_configurations.length);
-        for (var x in this.namespaceDirective_configurations) {
-          x?.collectApiSignature(signature);
-        }
-      }
-      if (this.annotatedNode_metadata == null) {
-        signature.addInt(0);
-      } else {
-        signature.addInt(this.annotatedNode_metadata.length);
-        for (var x in this.annotatedNode_metadata) {
-          x?.collectApiSignature(signature);
-        }
-      }
-      signature.addBool(this.uriBasedDirective_uri != null);
-      this.uriBasedDirective_uri?.collectApiSignature(signature);
-      signature.addInt(this.flags ?? 0);
-      signature.addInt(this.uriBasedDirective_uriElement ?? 0);
-      signature.addString(this.namespaceDirective_selectedUri ?? '');
-      signature.addString(this.uriBasedDirective_uriContent ?? '');
-      signature.addString(this.name ?? '');
-    } else if (kind == idl.LinkedNodeKind.expressionFunctionBody) {
-      signature.addInt(this.kind == null ? 0 : this.kind.index);
-      signature.addBool(this.expressionFunctionBody_expression != null);
-      this.expressionFunctionBody_expression?.collectApiSignature(signature);
-      signature.addInt(this.flags ?? 0);
-      signature.addString(this.name ?? '');
-    } else if (kind == idl.LinkedNodeKind.expressionStatement) {
-      signature.addInt(this.kind == null ? 0 : this.kind.index);
-      signature.addBool(this.expressionStatement_expression != null);
-      this.expressionStatement_expression?.collectApiSignature(signature);
-      signature.addInt(this.flags ?? 0);
-      signature.addString(this.name ?? '');
-    } else if (kind == idl.LinkedNodeKind.extendsClause) {
-      signature.addInt(this.kind == null ? 0 : this.kind.index);
-      signature.addBool(this.extendsClause_superclass != null);
-      this.extendsClause_superclass?.collectApiSignature(signature);
-      signature.addInt(this.flags ?? 0);
-      signature.addString(this.name ?? '');
-    } else if (kind == idl.LinkedNodeKind.extensionDeclaration) {
-      signature.addInt(this.kind == null ? 0 : this.kind.index);
-      if (this.annotatedNode_metadata == null) {
-        signature.addInt(0);
-      } else {
-        signature.addInt(this.annotatedNode_metadata.length);
-        for (var x in this.annotatedNode_metadata) {
-          x?.collectApiSignature(signature);
-        }
-      }
-      if (this.extensionDeclaration_members == null) {
-        signature.addInt(0);
-      } else {
-        signature.addInt(this.extensionDeclaration_members.length);
-        for (var x in this.extensionDeclaration_members) {
-          x?.collectApiSignature(signature);
-        }
-      }
-      signature.addBool(this.extensionDeclaration_typeParameters != null);
-      this.extensionDeclaration_typeParameters?.collectApiSignature(signature);
-      signature.addBool(this.extensionDeclaration_extendedType != null);
-      this.extensionDeclaration_extendedType?.collectApiSignature(signature);
-      signature.addInt(this.flags ?? 0);
-      signature.addString(this.extensionDeclaration_refName ?? '');
-      signature.addString(this.name ?? '');
-    } else if (kind == idl.LinkedNodeKind.extensionOverride) {
-      signature.addInt(this.kind == null ? 0 : this.kind.index);
-      if (this.extensionOverride_arguments == null) {
-        signature.addInt(0);
-      } else {
-        signature.addInt(this.extensionOverride_arguments.length);
-        for (var x in this.extensionOverride_arguments) {
-          x?.collectApiSignature(signature);
-        }
-      }
-      signature.addBool(this.extensionOverride_extensionName != null);
-      this.extensionOverride_extensionName?.collectApiSignature(signature);
-      signature.addBool(this.extensionOverride_typeArguments != null);
-      this.extensionOverride_typeArguments?.collectApiSignature(signature);
-      signature.addInt(this.flags ?? 0);
-      signature.addBool(this.extensionOverride_extendedType != null);
-      this.extensionOverride_extendedType?.collectApiSignature(signature);
-      signature.addString(this.name ?? '');
-      if (this.extensionOverride_typeArgumentTypes == null) {
-        signature.addInt(0);
-      } else {
-        signature.addInt(this.extensionOverride_typeArgumentTypes.length);
-        for (var x in this.extensionOverride_typeArgumentTypes) {
-          x?.collectApiSignature(signature);
-        }
-      }
-    } else if (kind == idl.LinkedNodeKind.fieldDeclaration) {
-      signature.addInt(this.kind == null ? 0 : this.kind.index);
-      if (this.annotatedNode_metadata == null) {
-        signature.addInt(0);
-      } else {
-        signature.addInt(this.annotatedNode_metadata.length);
-        for (var x in this.annotatedNode_metadata) {
-          x?.collectApiSignature(signature);
-        }
-      }
-      signature.addBool(this.fieldDeclaration_fields != null);
-      this.fieldDeclaration_fields?.collectApiSignature(signature);
-      signature.addInt(this.flags ?? 0);
-      signature.addString(this.name ?? '');
-    } else if (kind == idl.LinkedNodeKind.fieldFormalParameter) {
-      signature.addInt(this.kind == null ? 0 : this.kind.index);
-      if (this.normalFormalParameter_metadata == null) {
-        signature.addInt(0);
-      } else {
-        signature.addInt(this.normalFormalParameter_metadata.length);
-        for (var x in this.normalFormalParameter_metadata) {
-          x?.collectApiSignature(signature);
-        }
-      }
-      signature.addBool(this.fieldFormalParameter_type != null);
-      this.fieldFormalParameter_type?.collectApiSignature(signature);
-      signature.addBool(this.fieldFormalParameter_typeParameters != null);
-      this.fieldFormalParameter_typeParameters?.collectApiSignature(signature);
-      signature.addBool(this.fieldFormalParameter_formalParameters != null);
-      this
-          .fieldFormalParameter_formalParameters
-          ?.collectApiSignature(signature);
-      signature.addInt(this.flags ?? 0);
-      signature.addBool(this.actualType != null);
-      this.actualType?.collectApiSignature(signature);
-      signature.addBool(this.inheritsCovariant == true);
-      signature.addString(this.name ?? '');
-    } else if (kind == idl.LinkedNodeKind.forEachPartsWithDeclaration) {
-      signature.addInt(this.kind == null ? 0 : this.kind.index);
-      signature.addBool(this.forEachParts_iterable != null);
-      this.forEachParts_iterable?.collectApiSignature(signature);
-      signature.addBool(this.forEachPartsWithDeclaration_loopVariable != null);
-      this
-          .forEachPartsWithDeclaration_loopVariable
-          ?.collectApiSignature(signature);
-      signature.addInt(this.flags ?? 0);
-      signature.addString(this.name ?? '');
-    } else if (kind == idl.LinkedNodeKind.forEachPartsWithIdentifier) {
-      signature.addInt(this.kind == null ? 0 : this.kind.index);
-      signature.addBool(this.forEachParts_iterable != null);
-      this.forEachParts_iterable?.collectApiSignature(signature);
-      signature.addBool(this.forEachPartsWithIdentifier_identifier != null);
-      this
-          .forEachPartsWithIdentifier_identifier
-          ?.collectApiSignature(signature);
-      signature.addInt(this.flags ?? 0);
-      signature.addString(this.name ?? '');
-    } else if (kind == idl.LinkedNodeKind.forElement) {
-      signature.addInt(this.kind == null ? 0 : this.kind.index);
-      signature.addBool(this.forMixin_forLoopParts != null);
-      this.forMixin_forLoopParts?.collectApiSignature(signature);
-      signature.addBool(this.forElement_body != null);
-      this.forElement_body?.collectApiSignature(signature);
-      signature.addInt(this.flags ?? 0);
-      signature.addString(this.name ?? '');
-    } else if (kind == idl.LinkedNodeKind.forPartsWithDeclarations) {
-      signature.addInt(this.kind == null ? 0 : this.kind.index);
-      if (this.forParts_updaters == null) {
-        signature.addInt(0);
-      } else {
-        signature.addInt(this.forParts_updaters.length);
-        for (var x in this.forParts_updaters) {
-          x?.collectApiSignature(signature);
-        }
-      }
-      signature.addBool(this.forParts_condition != null);
-      this.forParts_condition?.collectApiSignature(signature);
-      signature.addBool(this.forPartsWithDeclarations_variables != null);
-      this.forPartsWithDeclarations_variables?.collectApiSignature(signature);
-      signature.addInt(this.flags ?? 0);
-      signature.addString(this.name ?? '');
-    } else if (kind == idl.LinkedNodeKind.forPartsWithExpression) {
-      signature.addInt(this.kind == null ? 0 : this.kind.index);
-      if (this.forParts_updaters == null) {
-        signature.addInt(0);
-      } else {
-        signature.addInt(this.forParts_updaters.length);
-        for (var x in this.forParts_updaters) {
-          x?.collectApiSignature(signature);
-        }
-      }
-      signature.addBool(this.forParts_condition != null);
-      this.forParts_condition?.collectApiSignature(signature);
-      signature.addBool(this.forPartsWithExpression_initialization != null);
-      this
-          .forPartsWithExpression_initialization
-          ?.collectApiSignature(signature);
-      signature.addInt(this.flags ?? 0);
-      signature.addString(this.name ?? '');
-    } else if (kind == idl.LinkedNodeKind.forStatement) {
-      signature.addInt(this.kind == null ? 0 : this.kind.index);
-      signature.addBool(this.forMixin_forLoopParts != null);
-      this.forMixin_forLoopParts?.collectApiSignature(signature);
-      signature.addBool(this.forStatement_body != null);
-      this.forStatement_body?.collectApiSignature(signature);
-      signature.addInt(this.flags ?? 0);
-      signature.addString(this.name ?? '');
-    } else if (kind == idl.LinkedNodeKind.formalParameterList) {
-      signature.addInt(this.kind == null ? 0 : this.kind.index);
-      if (this.formalParameterList_parameters == null) {
-        signature.addInt(0);
-      } else {
-        signature.addInt(this.formalParameterList_parameters.length);
-        for (var x in this.formalParameterList_parameters) {
-          x?.collectApiSignature(signature);
-        }
-      }
-      signature.addInt(this.flags ?? 0);
-      signature.addString(this.name ?? '');
-    } else if (kind == idl.LinkedNodeKind.functionDeclaration) {
-      signature.addInt(this.kind == null ? 0 : this.kind.index);
-      if (this.annotatedNode_metadata == null) {
-        signature.addInt(0);
-      } else {
-        signature.addInt(this.annotatedNode_metadata.length);
-        for (var x in this.annotatedNode_metadata) {
-          x?.collectApiSignature(signature);
-        }
-      }
-      signature.addBool(this.functionDeclaration_functionExpression != null);
-      this
-          .functionDeclaration_functionExpression
-          ?.collectApiSignature(signature);
-      signature.addBool(this.functionDeclaration_returnType != null);
-      this.functionDeclaration_returnType?.collectApiSignature(signature);
-      signature.addInt(this.flags ?? 0);
-      signature.addBool(this.actualReturnType != null);
-      this.actualReturnType?.collectApiSignature(signature);
-      signature.addString(this.name ?? '');
-    } else if (kind == idl.LinkedNodeKind.functionDeclarationStatement) {
-      signature.addInt(this.kind == null ? 0 : this.kind.index);
-      signature.addBool(
-          this.functionDeclarationStatement_functionDeclaration != null);
-      this
-          .functionDeclarationStatement_functionDeclaration
-          ?.collectApiSignature(signature);
-      signature.addInt(this.flags ?? 0);
-      signature.addString(this.name ?? '');
-    } else if (kind == idl.LinkedNodeKind.functionExpression) {
-      signature.addInt(this.kind == null ? 0 : this.kind.index);
-      signature.addBool(this.functionExpression_body != null);
-      this.functionExpression_body?.collectApiSignature(signature);
-      signature.addBool(this.functionExpression_formalParameters != null);
-      this.functionExpression_formalParameters?.collectApiSignature(signature);
-      signature.addBool(this.functionExpression_typeParameters != null);
-      this.functionExpression_typeParameters?.collectApiSignature(signature);
-      signature.addInt(this.flags ?? 0);
-      signature.addBool(this.actualReturnType != null);
-      this.actualReturnType?.collectApiSignature(signature);
-      signature.addString(this.name ?? '');
-    } else if (kind == idl.LinkedNodeKind.functionExpressionInvocation) {
-      signature.addInt(this.kind == null ? 0 : this.kind.index);
-      signature.addBool(this.functionExpressionInvocation_function != null);
-      this
-          .functionExpressionInvocation_function
-          ?.collectApiSignature(signature);
-      signature.addBool(this.invocationExpression_typeArguments != null);
-      this.invocationExpression_typeArguments?.collectApiSignature(signature);
-      signature.addBool(this.invocationExpression_arguments != null);
-      this.invocationExpression_arguments?.collectApiSignature(signature);
-      signature.addInt(this.flags ?? 0);
-      signature.addBool(this.invocationExpression_invokeType != null);
-      this.invocationExpression_invokeType?.collectApiSignature(signature);
-      signature.addBool(this.expression_type != null);
-      this.expression_type?.collectApiSignature(signature);
-      signature.addString(this.name ?? '');
-    } else if (kind == idl.LinkedNodeKind.functionTypeAlias) {
-      signature.addInt(this.kind == null ? 0 : this.kind.index);
-      if (this.annotatedNode_metadata == null) {
-        signature.addInt(0);
-      } else {
-        signature.addInt(this.annotatedNode_metadata.length);
-        for (var x in this.annotatedNode_metadata) {
-          x?.collectApiSignature(signature);
-        }
-      }
-      signature.addBool(this.functionTypeAlias_formalParameters != null);
-      this.functionTypeAlias_formalParameters?.collectApiSignature(signature);
-      signature.addBool(this.functionTypeAlias_returnType != null);
-      this.functionTypeAlias_returnType?.collectApiSignature(signature);
-      signature.addBool(this.functionTypeAlias_typeParameters != null);
-      this.functionTypeAlias_typeParameters?.collectApiSignature(signature);
-      signature.addInt(this.flags ?? 0);
-      signature.addBool(this.actualReturnType != null);
-      this.actualReturnType?.collectApiSignature(signature);
-      signature.addBool(this.typeAlias_hasSelfReference == true);
-      signature.addBool(this.simplyBoundable_isSimplyBounded == true);
-      signature.addString(this.name ?? '');
-    } else if (kind == idl.LinkedNodeKind.functionTypedFormalParameter) {
-      signature.addInt(this.kind == null ? 0 : this.kind.index);
-      if (this.normalFormalParameter_metadata == null) {
-        signature.addInt(0);
-      } else {
-        signature.addInt(this.normalFormalParameter_metadata.length);
-        for (var x in this.normalFormalParameter_metadata) {
-          x?.collectApiSignature(signature);
-        }
-      }
-      signature
-          .addBool(this.functionTypedFormalParameter_formalParameters != null);
-      this
-          .functionTypedFormalParameter_formalParameters
-          ?.collectApiSignature(signature);
-      signature.addBool(this.functionTypedFormalParameter_returnType != null);
-      this
-          .functionTypedFormalParameter_returnType
-          ?.collectApiSignature(signature);
-      signature
-          .addBool(this.functionTypedFormalParameter_typeParameters != null);
-      this
-          .functionTypedFormalParameter_typeParameters
-          ?.collectApiSignature(signature);
-      signature.addInt(this.flags ?? 0);
-      signature.addBool(this.actualType != null);
-      this.actualType?.collectApiSignature(signature);
-      signature.addBool(this.inheritsCovariant == true);
-      signature.addString(this.name ?? '');
-    } else if (kind == idl.LinkedNodeKind.genericFunctionType) {
-      signature.addInt(this.kind == null ? 0 : this.kind.index);
-      signature.addBool(this.genericFunctionType_typeParameters != null);
-      this.genericFunctionType_typeParameters?.collectApiSignature(signature);
-      signature.addBool(this.genericFunctionType_returnType != null);
-      this.genericFunctionType_returnType?.collectApiSignature(signature);
-      signature.addBool(this.genericFunctionType_formalParameters != null);
-      this.genericFunctionType_formalParameters?.collectApiSignature(signature);
-      signature.addInt(this.genericFunctionType_id ?? 0);
-      signature.addInt(this.flags ?? 0);
-      signature.addBool(this.actualReturnType != null);
-      this.actualReturnType?.collectApiSignature(signature);
-      signature.addBool(this.genericFunctionType_type != null);
-      this.genericFunctionType_type?.collectApiSignature(signature);
-      signature.addString(this.name ?? '');
-    } else if (kind == idl.LinkedNodeKind.genericTypeAlias) {
-      signature.addInt(this.kind == null ? 0 : this.kind.index);
-      if (this.annotatedNode_metadata == null) {
-        signature.addInt(0);
-      } else {
-        signature.addInt(this.annotatedNode_metadata.length);
-        for (var x in this.annotatedNode_metadata) {
-          x?.collectApiSignature(signature);
-        }
-      }
-      signature.addBool(this.genericTypeAlias_typeParameters != null);
-      this.genericTypeAlias_typeParameters?.collectApiSignature(signature);
-      signature.addBool(this.genericTypeAlias_functionType != null);
-      this.genericTypeAlias_functionType?.collectApiSignature(signature);
-      signature.addInt(this.flags ?? 0);
-      signature.addBool(this.typeAlias_hasSelfReference == true);
-      signature.addBool(this.simplyBoundable_isSimplyBounded == true);
-      signature.addString(this.name ?? '');
-    } else if (kind == idl.LinkedNodeKind.hideCombinator) {
-      signature.addInt(this.kind == null ? 0 : this.kind.index);
-      signature.addInt(this.flags ?? 0);
-      if (this.names == null) {
-        signature.addInt(0);
-      } else {
-        signature.addInt(this.names.length);
-        for (var x in this.names) {
-          signature.addString(x);
-        }
-      }
-      signature.addString(this.name ?? '');
-    } else if (kind == idl.LinkedNodeKind.ifElement) {
-      signature.addInt(this.kind == null ? 0 : this.kind.index);
-      signature.addBool(this.ifMixin_condition != null);
-      this.ifMixin_condition?.collectApiSignature(signature);
-      signature.addBool(this.ifElement_thenElement != null);
-      this.ifElement_thenElement?.collectApiSignature(signature);
-      signature.addBool(this.ifElement_elseElement != null);
-      this.ifElement_elseElement?.collectApiSignature(signature);
-      signature.addInt(this.flags ?? 0);
-      signature.addString(this.name ?? '');
-    } else if (kind == idl.LinkedNodeKind.ifStatement) {
-      signature.addInt(this.kind == null ? 0 : this.kind.index);
-      signature.addBool(this.ifMixin_condition != null);
-      this.ifMixin_condition?.collectApiSignature(signature);
-      signature.addBool(this.ifStatement_elseStatement != null);
-      this.ifStatement_elseStatement?.collectApiSignature(signature);
-      signature.addBool(this.ifStatement_thenStatement != null);
-      this.ifStatement_thenStatement?.collectApiSignature(signature);
-      signature.addInt(this.flags ?? 0);
-      signature.addString(this.name ?? '');
-    } else if (kind == idl.LinkedNodeKind.implementsClause) {
-      signature.addInt(this.kind == null ? 0 : this.kind.index);
-      if (this.implementsClause_interfaces == null) {
-        signature.addInt(0);
-      } else {
-        signature.addInt(this.implementsClause_interfaces.length);
-        for (var x in this.implementsClause_interfaces) {
-          x?.collectApiSignature(signature);
-        }
-      }
-      signature.addInt(this.flags ?? 0);
-      signature.addString(this.name ?? '');
-    } else if (kind == idl.LinkedNodeKind.importDirective) {
-      signature.addInt(this.kind == null ? 0 : this.kind.index);
-      signature.addString(this.importDirective_prefix ?? '');
-      if (this.namespaceDirective_combinators == null) {
-        signature.addInt(0);
-      } else {
-        signature.addInt(this.namespaceDirective_combinators.length);
-        for (var x in this.namespaceDirective_combinators) {
-          x?.collectApiSignature(signature);
-        }
-      }
-      if (this.namespaceDirective_configurations == null) {
-        signature.addInt(0);
-      } else {
-        signature.addInt(this.namespaceDirective_configurations.length);
-        for (var x in this.namespaceDirective_configurations) {
-          x?.collectApiSignature(signature);
-        }
-      }
-      if (this.annotatedNode_metadata == null) {
-        signature.addInt(0);
-      } else {
-        signature.addInt(this.annotatedNode_metadata.length);
-        for (var x in this.annotatedNode_metadata) {
-          x?.collectApiSignature(signature);
-        }
-      }
-      signature.addBool(this.uriBasedDirective_uri != null);
-      this.uriBasedDirective_uri?.collectApiSignature(signature);
-      signature.addInt(this.flags ?? 0);
-      signature.addInt(this.uriBasedDirective_uriElement ?? 0);
-      signature.addString(this.namespaceDirective_selectedUri ?? '');
-      signature.addString(this.uriBasedDirective_uriContent ?? '');
-      signature.addString(this.name ?? '');
-    } else if (kind == idl.LinkedNodeKind.indexExpression) {
-      signature.addInt(this.kind == null ? 0 : this.kind.index);
-      signature.addBool(this.indexExpression_index != null);
-      this.indexExpression_index?.collectApiSignature(signature);
-      signature.addBool(this.indexExpression_target != null);
-      this.indexExpression_target?.collectApiSignature(signature);
-      signature.addInt(this.indexExpression_element ?? 0);
-      signature.addInt(this.flags ?? 0);
-      signature.addBool(this.expression_type != null);
-      this.expression_type?.collectApiSignature(signature);
-      signature.addString(this.name ?? '');
-      signature.addBool(this.indexExpression_substitution != null);
-      this.indexExpression_substitution?.collectApiSignature(signature);
-    } else if (kind == idl.LinkedNodeKind.instanceCreationExpression) {
-      signature.addInt(this.kind == null ? 0 : this.kind.index);
-      if (this.instanceCreationExpression_arguments == null) {
-        signature.addInt(0);
-      } else {
-        signature.addInt(this.instanceCreationExpression_arguments.length);
-        for (var x in this.instanceCreationExpression_arguments) {
-          x?.collectApiSignature(signature);
-        }
-      }
-      signature
-          .addBool(this.instanceCreationExpression_constructorName != null);
-      this
-          .instanceCreationExpression_constructorName
-          ?.collectApiSignature(signature);
-      signature.addBool(this.instanceCreationExpression_typeArguments != null);
-      this
-          .instanceCreationExpression_typeArguments
-          ?.collectApiSignature(signature);
-      signature.addInt(this.flags ?? 0);
-      signature.addBool(this.expression_type != null);
-      this.expression_type?.collectApiSignature(signature);
-      signature.addString(this.name ?? '');
-    } else if (kind == idl.LinkedNodeKind.integerLiteral) {
-      signature.addInt(this.kind == null ? 0 : this.kind.index);
-      signature.addInt(this.integerLiteral_value ?? 0);
-      signature.addInt(this.flags ?? 0);
-      signature.addBool(this.expression_type != null);
-      this.expression_type?.collectApiSignature(signature);
-      signature.addString(this.name ?? '');
-    } else if (kind == idl.LinkedNodeKind.interpolationExpression) {
-      signature.addInt(this.kind == null ? 0 : this.kind.index);
-      signature.addBool(this.interpolationExpression_expression != null);
-      this.interpolationExpression_expression?.collectApiSignature(signature);
-      signature.addInt(this.flags ?? 0);
-      signature.addString(this.name ?? '');
-    } else if (kind == idl.LinkedNodeKind.interpolationString) {
-      signature.addInt(this.kind == null ? 0 : this.kind.index);
-      signature.addInt(this.flags ?? 0);
-      signature.addString(this.interpolationString_value ?? '');
-      signature.addString(this.name ?? '');
-    } else if (kind == idl.LinkedNodeKind.isExpression) {
-      signature.addInt(this.kind == null ? 0 : this.kind.index);
-      signature.addBool(this.isExpression_expression != null);
-      this.isExpression_expression?.collectApiSignature(signature);
-      signature.addBool(this.isExpression_type != null);
-      this.isExpression_type?.collectApiSignature(signature);
-      signature.addInt(this.flags ?? 0);
-      signature.addString(this.name ?? '');
-    } else if (kind == idl.LinkedNodeKind.label) {
-      signature.addInt(this.kind == null ? 0 : this.kind.index);
-      signature.addBool(this.label_label != null);
-      this.label_label?.collectApiSignature(signature);
-      signature.addInt(this.flags ?? 0);
-      signature.addString(this.name ?? '');
-    } else if (kind == idl.LinkedNodeKind.labeledStatement) {
-      signature.addInt(this.kind == null ? 0 : this.kind.index);
-      if (this.labeledStatement_labels == null) {
-        signature.addInt(0);
-      } else {
-        signature.addInt(this.labeledStatement_labels.length);
-        for (var x in this.labeledStatement_labels) {
-          x?.collectApiSignature(signature);
-        }
-      }
-      signature.addBool(this.labeledStatement_statement != null);
-      this.labeledStatement_statement?.collectApiSignature(signature);
-      signature.addInt(this.flags ?? 0);
-      signature.addString(this.name ?? '');
-    } else if (kind == idl.LinkedNodeKind.libraryDirective) {
-      signature.addInt(this.kind == null ? 0 : this.kind.index);
-      if (this.annotatedNode_metadata == null) {
-        signature.addInt(0);
-      } else {
-        signature.addInt(this.annotatedNode_metadata.length);
-        for (var x in this.annotatedNode_metadata) {
-          x?.collectApiSignature(signature);
-        }
-      }
-      signature.addBool(this.libraryDirective_name != null);
-      this.libraryDirective_name?.collectApiSignature(signature);
-      signature.addInt(this.flags ?? 0);
-      signature.addString(this.name ?? '');
-    } else if (kind == idl.LinkedNodeKind.libraryIdentifier) {
-      signature.addInt(this.kind == null ? 0 : this.kind.index);
-      if (this.libraryIdentifier_components == null) {
-        signature.addInt(0);
-      } else {
-        signature.addInt(this.libraryIdentifier_components.length);
-        for (var x in this.libraryIdentifier_components) {
-          x?.collectApiSignature(signature);
-        }
-      }
-      signature.addInt(this.flags ?? 0);
-      signature.addString(this.name ?? '');
-    } else if (kind == idl.LinkedNodeKind.listLiteral) {
-      signature.addInt(this.kind == null ? 0 : this.kind.index);
-      if (this.typedLiteral_typeArguments == null) {
-        signature.addInt(0);
-      } else {
-        signature.addInt(this.typedLiteral_typeArguments.length);
-        for (var x in this.typedLiteral_typeArguments) {
-          x?.collectApiSignature(signature);
-        }
-      }
-      if (this.listLiteral_elements == null) {
-        signature.addInt(0);
-      } else {
-        signature.addInt(this.listLiteral_elements.length);
-        for (var x in this.listLiteral_elements) {
-          x?.collectApiSignature(signature);
-        }
-      }
-      signature.addInt(this.flags ?? 0);
-      signature.addBool(this.expression_type != null);
-      this.expression_type?.collectApiSignature(signature);
-      signature.addString(this.name ?? '');
-    } else if (kind == idl.LinkedNodeKind.mapLiteralEntry) {
-      signature.addInt(this.kind == null ? 0 : this.kind.index);
-      signature.addBool(this.mapLiteralEntry_key != null);
-      this.mapLiteralEntry_key?.collectApiSignature(signature);
-      signature.addBool(this.mapLiteralEntry_value != null);
-      this.mapLiteralEntry_value?.collectApiSignature(signature);
-      signature.addInt(this.flags ?? 0);
-      signature.addString(this.name ?? '');
-    } else if (kind == idl.LinkedNodeKind.methodDeclaration) {
-      signature.addInt(this.kind == null ? 0 : this.kind.index);
-      if (this.annotatedNode_metadata == null) {
-        signature.addInt(0);
-      } else {
-        signature.addInt(this.annotatedNode_metadata.length);
-        for (var x in this.annotatedNode_metadata) {
-          x?.collectApiSignature(signature);
-        }
-      }
-      signature.addBool(this.methodDeclaration_body != null);
-      this.methodDeclaration_body?.collectApiSignature(signature);
-      signature.addBool(this.methodDeclaration_formalParameters != null);
-      this.methodDeclaration_formalParameters?.collectApiSignature(signature);
-      signature.addBool(this.methodDeclaration_returnType != null);
-      this.methodDeclaration_returnType?.collectApiSignature(signature);
-      signature.addBool(this.methodDeclaration_typeParameters != null);
-      this.methodDeclaration_typeParameters?.collectApiSignature(signature);
-      signature.addInt(this.flags ?? 0);
-      signature.addBool(this.actualReturnType != null);
-      this.actualReturnType?.collectApiSignature(signature);
-      signature.addBool(
-          this.methodDeclaration_hasOperatorEqualWithParameterTypeFromObject ==
-              true);
-      signature.addBool(this.topLevelTypeInferenceError != null);
-      this.topLevelTypeInferenceError?.collectApiSignature(signature);
-      signature.addString(this.name ?? '');
-    } else if (kind == idl.LinkedNodeKind.methodInvocation) {
-      signature.addInt(this.kind == null ? 0 : this.kind.index);
-      signature.addBool(this.methodInvocation_methodName != null);
-      this.methodInvocation_methodName?.collectApiSignature(signature);
-      signature.addBool(this.methodInvocation_target != null);
-      this.methodInvocation_target?.collectApiSignature(signature);
-      signature.addBool(this.invocationExpression_typeArguments != null);
-      this.invocationExpression_typeArguments?.collectApiSignature(signature);
-      signature.addBool(this.invocationExpression_arguments != null);
-      this.invocationExpression_arguments?.collectApiSignature(signature);
-      signature.addInt(this.flags ?? 0);
-      signature.addBool(this.invocationExpression_invokeType != null);
-      this.invocationExpression_invokeType?.collectApiSignature(signature);
-      signature.addBool(this.expression_type != null);
-      this.expression_type?.collectApiSignature(signature);
-      signature.addString(this.name ?? '');
-    } else if (kind == idl.LinkedNodeKind.mixinDeclaration) {
-      signature.addInt(this.kind == null ? 0 : this.kind.index);
-      if (this.annotatedNode_metadata == null) {
-        signature.addInt(0);
-      } else {
-        signature.addInt(this.annotatedNode_metadata.length);
-        for (var x in this.annotatedNode_metadata) {
-          x?.collectApiSignature(signature);
-        }
-      }
-      if (this.classOrMixinDeclaration_members == null) {
-        signature.addInt(0);
-      } else {
-        signature.addInt(this.classOrMixinDeclaration_members.length);
-        for (var x in this.classOrMixinDeclaration_members) {
-          x?.collectApiSignature(signature);
-        }
-      }
-      signature.addBool(this.mixinDeclaration_onClause != null);
-      this.mixinDeclaration_onClause?.collectApiSignature(signature);
-      signature.addBool(this.classOrMixinDeclaration_implementsClause != null);
-      this
-          .classOrMixinDeclaration_implementsClause
-          ?.collectApiSignature(signature);
-      signature.addBool(this.classOrMixinDeclaration_typeParameters != null);
-      this
-          .classOrMixinDeclaration_typeParameters
-          ?.collectApiSignature(signature);
-      signature.addInt(this.flags ?? 0);
-      signature.addBool(this.simplyBoundable_isSimplyBounded == true);
-      if (this.mixinDeclaration_superInvokedNames == null) {
-        signature.addInt(0);
-      } else {
-        signature.addInt(this.mixinDeclaration_superInvokedNames.length);
-        for (var x in this.mixinDeclaration_superInvokedNames) {
-          signature.addString(x);
-        }
-      }
-      signature.addString(this.name ?? '');
-    } else if (kind == idl.LinkedNodeKind.namedExpression) {
-      signature.addInt(this.kind == null ? 0 : this.kind.index);
-      signature.addBool(this.namedExpression_expression != null);
-      this.namedExpression_expression?.collectApiSignature(signature);
-      signature.addBool(this.namedExpression_name != null);
-      this.namedExpression_name?.collectApiSignature(signature);
-      signature.addInt(this.flags ?? 0);
-      signature.addString(this.name ?? '');
-    } else if (kind == idl.LinkedNodeKind.nativeClause) {
-      signature.addInt(this.kind == null ? 0 : this.kind.index);
-      signature.addBool(this.nativeClause_name != null);
-      this.nativeClause_name?.collectApiSignature(signature);
-      signature.addInt(this.flags ?? 0);
-      signature.addString(this.name ?? '');
-    } else if (kind == idl.LinkedNodeKind.nativeFunctionBody) {
-      signature.addInt(this.kind == null ? 0 : this.kind.index);
-      signature.addBool(this.nativeFunctionBody_stringLiteral != null);
-      this.nativeFunctionBody_stringLiteral?.collectApiSignature(signature);
-      signature.addInt(this.flags ?? 0);
-      signature.addString(this.name ?? '');
-    } else if (kind == idl.LinkedNodeKind.nullLiteral) {
-      signature.addInt(this.kind == null ? 0 : this.kind.index);
-      signature.addInt(this.nullLiteral_fake ?? 0);
-      signature.addInt(this.flags ?? 0);
-      signature.addBool(this.expression_type != null);
-      this.expression_type?.collectApiSignature(signature);
-      signature.addString(this.name ?? '');
-    } else if (kind == idl.LinkedNodeKind.onClause) {
-      signature.addInt(this.kind == null ? 0 : this.kind.index);
-      if (this.onClause_superclassConstraints == null) {
-        signature.addInt(0);
-      } else {
-        signature.addInt(this.onClause_superclassConstraints.length);
-        for (var x in this.onClause_superclassConstraints) {
-          x?.collectApiSignature(signature);
-        }
-      }
-      signature.addInt(this.flags ?? 0);
-      signature.addString(this.name ?? '');
-    } else if (kind == idl.LinkedNodeKind.parenthesizedExpression) {
-      signature.addInt(this.kind == null ? 0 : this.kind.index);
-      signature.addBool(this.parenthesizedExpression_expression != null);
-      this.parenthesizedExpression_expression?.collectApiSignature(signature);
-      signature.addInt(this.flags ?? 0);
-      signature.addBool(this.expression_type != null);
-      this.expression_type?.collectApiSignature(signature);
-      signature.addString(this.name ?? '');
-    } else if (kind == idl.LinkedNodeKind.partDirective) {
-      signature.addInt(this.kind == null ? 0 : this.kind.index);
-      if (this.annotatedNode_metadata == null) {
-        signature.addInt(0);
-      } else {
-        signature.addInt(this.annotatedNode_metadata.length);
-        for (var x in this.annotatedNode_metadata) {
-          x?.collectApiSignature(signature);
-        }
-      }
-      signature.addBool(this.uriBasedDirective_uri != null);
-      this.uriBasedDirective_uri?.collectApiSignature(signature);
-      signature.addInt(this.flags ?? 0);
-      signature.addInt(this.uriBasedDirective_uriElement ?? 0);
-      signature.addString(this.uriBasedDirective_uriContent ?? '');
-      signature.addString(this.name ?? '');
-    } else if (kind == idl.LinkedNodeKind.partOfDirective) {
-      signature.addInt(this.kind == null ? 0 : this.kind.index);
-      if (this.annotatedNode_metadata == null) {
-        signature.addInt(0);
-      } else {
-        signature.addInt(this.annotatedNode_metadata.length);
-        for (var x in this.annotatedNode_metadata) {
-          x?.collectApiSignature(signature);
-        }
-      }
-      signature.addBool(this.partOfDirective_libraryName != null);
-      this.partOfDirective_libraryName?.collectApiSignature(signature);
-      signature.addBool(this.partOfDirective_uri != null);
-      this.partOfDirective_uri?.collectApiSignature(signature);
-      signature.addInt(this.flags ?? 0);
-      signature.addString(this.name ?? '');
-    } else if (kind == idl.LinkedNodeKind.postfixExpression) {
-      signature.addInt(this.kind == null ? 0 : this.kind.index);
-      signature.addBool(this.postfixExpression_operand != null);
-      this.postfixExpression_operand?.collectApiSignature(signature);
-      signature.addInt(this.postfixExpression_element ?? 0);
-      signature.addInt(this.flags ?? 0);
-      signature.addBool(this.expression_type != null);
-      this.expression_type?.collectApiSignature(signature);
-      signature.addInt(this.postfixExpression_operator == null
-          ? 0
-          : this.postfixExpression_operator.index);
-      signature.addString(this.name ?? '');
-      signature.addBool(this.postfixExpression_substitution != null);
-      this.postfixExpression_substitution?.collectApiSignature(signature);
-    } else if (kind == idl.LinkedNodeKind.prefixExpression) {
-      signature.addInt(this.kind == null ? 0 : this.kind.index);
-      signature.addBool(this.prefixExpression_operand != null);
-      this.prefixExpression_operand?.collectApiSignature(signature);
-      signature.addInt(this.prefixExpression_element ?? 0);
-      signature.addInt(this.flags ?? 0);
-      signature.addBool(this.expression_type != null);
-      this.expression_type?.collectApiSignature(signature);
-      signature.addInt(this.prefixExpression_operator == null
-          ? 0
-          : this.prefixExpression_operator.index);
-      signature.addString(this.name ?? '');
-      signature.addBool(this.prefixExpression_substitution != null);
-      this.prefixExpression_substitution?.collectApiSignature(signature);
-    } else if (kind == idl.LinkedNodeKind.prefixedIdentifier) {
-      signature.addInt(this.kind == null ? 0 : this.kind.index);
-      signature.addBool(this.prefixedIdentifier_identifier != null);
-      this.prefixedIdentifier_identifier?.collectApiSignature(signature);
-      signature.addBool(this.prefixedIdentifier_prefix != null);
-      this.prefixedIdentifier_prefix?.collectApiSignature(signature);
-      signature.addInt(this.flags ?? 0);
-      signature.addBool(this.expression_type != null);
-      this.expression_type?.collectApiSignature(signature);
-      signature.addString(this.name ?? '');
-    } else if (kind == idl.LinkedNodeKind.propertyAccess) {
-      signature.addInt(this.kind == null ? 0 : this.kind.index);
-      signature.addBool(this.propertyAccess_propertyName != null);
-      this.propertyAccess_propertyName?.collectApiSignature(signature);
-      signature.addBool(this.propertyAccess_target != null);
-      this.propertyAccess_target?.collectApiSignature(signature);
-      signature.addInt(this.flags ?? 0);
-      signature.addBool(this.expression_type != null);
-      this.expression_type?.collectApiSignature(signature);
-      signature.addInt(this.propertyAccess_operator == null
-          ? 0
-          : this.propertyAccess_operator.index);
-      signature.addString(this.name ?? '');
-    } else if (kind == idl.LinkedNodeKind.redirectingConstructorInvocation) {
-      signature.addInt(this.kind == null ? 0 : this.kind.index);
-      signature
-          .addBool(this.redirectingConstructorInvocation_arguments != null);
-      this
-          .redirectingConstructorInvocation_arguments
-          ?.collectApiSignature(signature);
-      signature.addBool(
-          this.redirectingConstructorInvocation_constructorName != null);
-      this
-          .redirectingConstructorInvocation_constructorName
-          ?.collectApiSignature(signature);
-      signature.addInt(this.redirectingConstructorInvocation_element ?? 0);
-      signature.addInt(this.flags ?? 0);
-      signature.addString(this.name ?? '');
-      signature
-          .addBool(this.redirectingConstructorInvocation_substitution != null);
-      this
-          .redirectingConstructorInvocation_substitution
-          ?.collectApiSignature(signature);
-    } else if (kind == idl.LinkedNodeKind.rethrowExpression) {
-      signature.addInt(this.kind == null ? 0 : this.kind.index);
-      signature.addInt(this.flags ?? 0);
-      signature.addBool(this.expression_type != null);
-      this.expression_type?.collectApiSignature(signature);
-      signature.addString(this.name ?? '');
-    } else if (kind == idl.LinkedNodeKind.returnStatement) {
-      signature.addInt(this.kind == null ? 0 : this.kind.index);
-      signature.addBool(this.returnStatement_expression != null);
-      this.returnStatement_expression?.collectApiSignature(signature);
-      signature.addInt(this.flags ?? 0);
-      signature.addString(this.name ?? '');
-    } else if (kind == idl.LinkedNodeKind.setOrMapLiteral) {
-      signature.addInt(this.kind == null ? 0 : this.kind.index);
-      if (this.typedLiteral_typeArguments == null) {
-        signature.addInt(0);
-      } else {
-        signature.addInt(this.typedLiteral_typeArguments.length);
-        for (var x in this.typedLiteral_typeArguments) {
-          x?.collectApiSignature(signature);
-        }
-      }
-      if (this.setOrMapLiteral_elements == null) {
-        signature.addInt(0);
-      } else {
-        signature.addInt(this.setOrMapLiteral_elements.length);
-        for (var x in this.setOrMapLiteral_elements) {
-          x?.collectApiSignature(signature);
-        }
-      }
-      signature.addInt(this.flags ?? 0);
-      signature.addBool(this.expression_type != null);
-      this.expression_type?.collectApiSignature(signature);
-      signature.addString(this.name ?? '');
-    } else if (kind == idl.LinkedNodeKind.showCombinator) {
-      signature.addInt(this.kind == null ? 0 : this.kind.index);
-      signature.addInt(this.flags ?? 0);
-      if (this.names == null) {
-        signature.addInt(0);
-      } else {
-        signature.addInt(this.names.length);
-        for (var x in this.names) {
-          signature.addString(x);
-        }
-      }
-      signature.addString(this.name ?? '');
-    } else if (kind == idl.LinkedNodeKind.simpleFormalParameter) {
-      signature.addInt(this.kind == null ? 0 : this.kind.index);
-      if (this.normalFormalParameter_metadata == null) {
-        signature.addInt(0);
-      } else {
-        signature.addInt(this.normalFormalParameter_metadata.length);
-        for (var x in this.normalFormalParameter_metadata) {
-          x?.collectApiSignature(signature);
-        }
-      }
-      signature.addBool(this.simpleFormalParameter_type != null);
-      this.simpleFormalParameter_type?.collectApiSignature(signature);
-      signature.addInt(this.flags ?? 0);
-      signature.addBool(this.actualType != null);
-      this.actualType?.collectApiSignature(signature);
-      signature.addBool(this.inheritsCovariant == true);
-      signature.addBool(this.topLevelTypeInferenceError != null);
-      this.topLevelTypeInferenceError?.collectApiSignature(signature);
-      signature.addString(this.name ?? '');
-    } else if (kind == idl.LinkedNodeKind.simpleIdentifier) {
-      signature.addInt(this.kind == null ? 0 : this.kind.index);
-      signature.addInt(this.simpleIdentifier_element ?? 0);
-      signature.addInt(this.flags ?? 0);
-      signature.addBool(this.expression_type != null);
-      this.expression_type?.collectApiSignature(signature);
-      signature.addString(this.name ?? '');
-      signature.addBool(this.simpleIdentifier_substitution != null);
-      this.simpleIdentifier_substitution?.collectApiSignature(signature);
-    } else if (kind == idl.LinkedNodeKind.simpleStringLiteral) {
-      signature.addInt(this.kind == null ? 0 : this.kind.index);
-      signature.addInt(this.flags ?? 0);
-      signature.addString(this.simpleStringLiteral_value ?? '');
-      signature.addString(this.name ?? '');
-    } else if (kind == idl.LinkedNodeKind.spreadElement) {
-      signature.addInt(this.kind == null ? 0 : this.kind.index);
-      signature.addBool(this.spreadElement_expression != null);
-      this.spreadElement_expression?.collectApiSignature(signature);
-      signature.addInt(this.flags ?? 0);
-      signature.addInt(this.spreadElement_spreadOperator == null
-          ? 0
-          : this.spreadElement_spreadOperator.index);
-      signature.addString(this.name ?? '');
-    } else if (kind == idl.LinkedNodeKind.stringInterpolation) {
-      signature.addInt(this.kind == null ? 0 : this.kind.index);
-      if (this.stringInterpolation_elements == null) {
-        signature.addInt(0);
-      } else {
-        signature.addInt(this.stringInterpolation_elements.length);
-        for (var x in this.stringInterpolation_elements) {
-          x?.collectApiSignature(signature);
-        }
-      }
-      signature.addInt(this.flags ?? 0);
-      signature.addString(this.name ?? '');
-    } else if (kind == idl.LinkedNodeKind.superConstructorInvocation) {
-      signature.addInt(this.kind == null ? 0 : this.kind.index);
-      signature.addBool(this.superConstructorInvocation_arguments != null);
-      this.superConstructorInvocation_arguments?.collectApiSignature(signature);
-      signature
-          .addBool(this.superConstructorInvocation_constructorName != null);
-      this
-          .superConstructorInvocation_constructorName
-          ?.collectApiSignature(signature);
-      signature.addInt(this.superConstructorInvocation_element ?? 0);
-      signature.addInt(this.flags ?? 0);
-      signature.addString(this.name ?? '');
-      signature.addBool(this.superConstructorInvocation_substitution != null);
-      this
-          .superConstructorInvocation_substitution
-          ?.collectApiSignature(signature);
-    } else if (kind == idl.LinkedNodeKind.superExpression) {
-      signature.addInt(this.kind == null ? 0 : this.kind.index);
-      signature.addInt(this.flags ?? 0);
-      signature.addBool(this.expression_type != null);
-      this.expression_type?.collectApiSignature(signature);
-      signature.addString(this.name ?? '');
-    } else if (kind == idl.LinkedNodeKind.switchCase) {
-      signature.addInt(this.kind == null ? 0 : this.kind.index);
-      if (this.switchMember_labels == null) {
-        signature.addInt(0);
-      } else {
-        signature.addInt(this.switchMember_labels.length);
-        for (var x in this.switchMember_labels) {
-          x?.collectApiSignature(signature);
-        }
-      }
-      if (this.switchMember_statements == null) {
-        signature.addInt(0);
-      } else {
-        signature.addInt(this.switchMember_statements.length);
-        for (var x in this.switchMember_statements) {
-          x?.collectApiSignature(signature);
-        }
-      }
-      signature.addBool(this.switchCase_expression != null);
-      this.switchCase_expression?.collectApiSignature(signature);
-      signature.addInt(this.flags ?? 0);
-      signature.addString(this.name ?? '');
-    } else if (kind == idl.LinkedNodeKind.switchDefault) {
-      signature.addInt(this.kind == null ? 0 : this.kind.index);
-      if (this.switchMember_labels == null) {
-        signature.addInt(0);
-      } else {
-        signature.addInt(this.switchMember_labels.length);
-        for (var x in this.switchMember_labels) {
-          x?.collectApiSignature(signature);
-        }
-      }
-      if (this.switchMember_statements == null) {
-        signature.addInt(0);
-      } else {
-        signature.addInt(this.switchMember_statements.length);
-        for (var x in this.switchMember_statements) {
-          x?.collectApiSignature(signature);
-        }
-      }
-      signature.addInt(this.flags ?? 0);
-      signature.addString(this.name ?? '');
-    } else if (kind == idl.LinkedNodeKind.switchStatement) {
-      signature.addInt(this.kind == null ? 0 : this.kind.index);
-      if (this.switchStatement_members == null) {
-        signature.addInt(0);
-      } else {
-        signature.addInt(this.switchStatement_members.length);
-        for (var x in this.switchStatement_members) {
-          x?.collectApiSignature(signature);
-        }
-      }
-      signature.addBool(this.switchStatement_expression != null);
-      this.switchStatement_expression?.collectApiSignature(signature);
-      signature.addInt(this.flags ?? 0);
-      signature.addString(this.name ?? '');
-    } else if (kind == idl.LinkedNodeKind.symbolLiteral) {
-      signature.addInt(this.kind == null ? 0 : this.kind.index);
-      signature.addInt(this.flags ?? 0);
-      signature.addBool(this.expression_type != null);
-      this.expression_type?.collectApiSignature(signature);
-      if (this.names == null) {
-        signature.addInt(0);
-      } else {
-        signature.addInt(this.names.length);
-        for (var x in this.names) {
-          signature.addString(x);
-        }
-      }
-      signature.addString(this.name ?? '');
-    } else if (kind == idl.LinkedNodeKind.thisExpression) {
-      signature.addInt(this.kind == null ? 0 : this.kind.index);
-      signature.addInt(this.flags ?? 0);
-      signature.addBool(this.expression_type != null);
-      this.expression_type?.collectApiSignature(signature);
-      signature.addString(this.name ?? '');
-    } else if (kind == idl.LinkedNodeKind.throwExpression) {
-      signature.addInt(this.kind == null ? 0 : this.kind.index);
-      signature.addBool(this.throwExpression_expression != null);
-      this.throwExpression_expression?.collectApiSignature(signature);
-      signature.addInt(this.flags ?? 0);
-      signature.addBool(this.expression_type != null);
-      this.expression_type?.collectApiSignature(signature);
-      signature.addString(this.name ?? '');
-    } else if (kind == idl.LinkedNodeKind.topLevelVariableDeclaration) {
-      signature.addInt(this.kind == null ? 0 : this.kind.index);
-      if (this.annotatedNode_metadata == null) {
-        signature.addInt(0);
-      } else {
-        signature.addInt(this.annotatedNode_metadata.length);
-        for (var x in this.annotatedNode_metadata) {
-          x?.collectApiSignature(signature);
-        }
-      }
-      signature.addBool(this.topLevelVariableDeclaration_variableList != null);
-      this
-          .topLevelVariableDeclaration_variableList
-          ?.collectApiSignature(signature);
-      signature.addInt(this.flags ?? 0);
-      signature.addString(this.name ?? '');
-    } else if (kind == idl.LinkedNodeKind.tryStatement) {
-      signature.addInt(this.kind == null ? 0 : this.kind.index);
-      if (this.tryStatement_catchClauses == null) {
-        signature.addInt(0);
-      } else {
-        signature.addInt(this.tryStatement_catchClauses.length);
-        for (var x in this.tryStatement_catchClauses) {
-          x?.collectApiSignature(signature);
-        }
-      }
-      signature.addBool(this.tryStatement_body != null);
-      this.tryStatement_body?.collectApiSignature(signature);
-      signature.addBool(this.tryStatement_finallyBlock != null);
-      this.tryStatement_finallyBlock?.collectApiSignature(signature);
-      signature.addInt(this.flags ?? 0);
-      signature.addString(this.name ?? '');
-    } else if (kind == idl.LinkedNodeKind.typeArgumentList) {
-      signature.addInt(this.kind == null ? 0 : this.kind.index);
-      if (this.typeArgumentList_arguments == null) {
-        signature.addInt(0);
-      } else {
-        signature.addInt(this.typeArgumentList_arguments.length);
-        for (var x in this.typeArgumentList_arguments) {
-          x?.collectApiSignature(signature);
-        }
-      }
-      signature.addInt(this.flags ?? 0);
-      signature.addString(this.name ?? '');
-    } else if (kind == idl.LinkedNodeKind.typeName) {
-      signature.addInt(this.kind == null ? 0 : this.kind.index);
-      if (this.typeName_typeArguments == null) {
-        signature.addInt(0);
-      } else {
-        signature.addInt(this.typeName_typeArguments.length);
-        for (var x in this.typeName_typeArguments) {
-          x?.collectApiSignature(signature);
-        }
-      }
-      signature.addBool(this.typeName_name != null);
-      this.typeName_name?.collectApiSignature(signature);
-      signature.addInt(this.flags ?? 0);
-      signature.addBool(this.typeName_type != null);
-      this.typeName_type?.collectApiSignature(signature);
-      signature.addString(this.name ?? '');
-    } else if (kind == idl.LinkedNodeKind.typeParameter) {
-      signature.addInt(this.kind == null ? 0 : this.kind.index);
-      if (this.annotatedNode_metadata == null) {
-        signature.addInt(0);
-      } else {
-        signature.addInt(this.annotatedNode_metadata.length);
-        for (var x in this.annotatedNode_metadata) {
-          x?.collectApiSignature(signature);
-        }
-      }
-      signature.addBool(this.typeParameter_bound != null);
-      this.typeParameter_bound?.collectApiSignature(signature);
-      signature.addInt(this.typeParameter_variance ?? 0);
-      signature.addInt(this.flags ?? 0);
-      signature.addBool(this.typeParameter_defaultType != null);
-      this.typeParameter_defaultType?.collectApiSignature(signature);
-      signature.addString(this.name ?? '');
-    } else if (kind == idl.LinkedNodeKind.typeParameterList) {
-      signature.addInt(this.kind == null ? 0 : this.kind.index);
-      if (this.typeParameterList_typeParameters == null) {
-        signature.addInt(0);
-      } else {
-        signature.addInt(this.typeParameterList_typeParameters.length);
-        for (var x in this.typeParameterList_typeParameters) {
-          x?.collectApiSignature(signature);
-        }
-      }
-      signature.addInt(this.flags ?? 0);
-      signature.addString(this.name ?? '');
-    } else if (kind == idl.LinkedNodeKind.variableDeclaration) {
-      signature.addInt(this.kind == null ? 0 : this.kind.index);
-      if (this.annotatedNode_metadata == null) {
-        signature.addInt(0);
-      } else {
-        signature.addInt(this.annotatedNode_metadata.length);
-        for (var x in this.annotatedNode_metadata) {
-          x?.collectApiSignature(signature);
-        }
-      }
-      signature.addBool(this.variableDeclaration_initializer != null);
-      this.variableDeclaration_initializer?.collectApiSignature(signature);
-      signature.addInt(this.flags ?? 0);
-      signature.addBool(this.actualType != null);
-      this.actualType?.collectApiSignature(signature);
-      signature.addBool(this.inheritsCovariant == true);
-      signature.addBool(this.topLevelTypeInferenceError != null);
-      this.topLevelTypeInferenceError?.collectApiSignature(signature);
-      signature.addString(this.name ?? '');
-    } else if (kind == idl.LinkedNodeKind.variableDeclarationList) {
-      signature.addInt(this.kind == null ? 0 : this.kind.index);
-      if (this.variableDeclarationList_variables == null) {
-        signature.addInt(0);
-      } else {
-        signature.addInt(this.variableDeclarationList_variables.length);
-        for (var x in this.variableDeclarationList_variables) {
-          x?.collectApiSignature(signature);
-        }
-      }
-      if (this.annotatedNode_metadata == null) {
-        signature.addInt(0);
-      } else {
-        signature.addInt(this.annotatedNode_metadata.length);
-        for (var x in this.annotatedNode_metadata) {
-          x?.collectApiSignature(signature);
-        }
-      }
-      signature.addBool(this.variableDeclarationList_type != null);
-      this.variableDeclarationList_type?.collectApiSignature(signature);
-      signature.addInt(this.flags ?? 0);
-      signature.addString(this.name ?? '');
-    } else if (kind == idl.LinkedNodeKind.variableDeclarationStatement) {
-      signature.addInt(this.kind == null ? 0 : this.kind.index);
-      signature.addBool(this.variableDeclarationStatement_variables != null);
-      this
-          .variableDeclarationStatement_variables
-          ?.collectApiSignature(signature);
-      signature.addInt(this.flags ?? 0);
-      signature.addString(this.name ?? '');
-    } else if (kind == idl.LinkedNodeKind.whileStatement) {
-      signature.addInt(this.kind == null ? 0 : this.kind.index);
-      signature.addBool(this.whileStatement_body != null);
-      this.whileStatement_body?.collectApiSignature(signature);
-      signature.addBool(this.whileStatement_condition != null);
-      this.whileStatement_condition?.collectApiSignature(signature);
-      signature.addInt(this.flags ?? 0);
-      signature.addString(this.name ?? '');
-    } else if (kind == idl.LinkedNodeKind.withClause) {
-      signature.addInt(this.kind == null ? 0 : this.kind.index);
-      if (this.withClause_mixinTypes == null) {
-        signature.addInt(0);
-      } else {
-        signature.addInt(this.withClause_mixinTypes.length);
-        for (var x in this.withClause_mixinTypes) {
-          x?.collectApiSignature(signature);
-        }
-      }
-      signature.addInt(this.flags ?? 0);
-      signature.addString(this.name ?? '');
-    } else if (kind == idl.LinkedNodeKind.yieldStatement) {
-      signature.addInt(this.kind == null ? 0 : this.kind.index);
-      signature.addBool(this.yieldStatement_expression != null);
-      this.yieldStatement_expression?.collectApiSignature(signature);
-      signature.addInt(this.flags ?? 0);
-      signature.addString(this.name ?? '');
-    }
-  }
-
-  fb.Offset finish(fb.Builder fbBuilder) {
-    fb.Offset offset_variantField_24;
-    fb.Offset offset_variantField_2;
-    fb.Offset offset_variantField_4;
-    fb.Offset offset_variantField_6;
-    fb.Offset offset_variantField_7;
-    fb.Offset offset_variantField_8;
-    fb.Offset offset_variantField_38;
-    fb.Offset offset_variantField_9;
-    fb.Offset offset_variantField_12;
-    fb.Offset offset_variantField_5;
-    fb.Offset offset_variantField_13;
-    fb.Offset offset_variantField_33;
-    fb.Offset offset_variantField_3;
-    fb.Offset offset_variantField_41;
-    fb.Offset offset_variantField_40;
-    fb.Offset offset_variantField_10;
-    fb.Offset offset_variantField_25;
-    fb.Offset offset_variantField_20;
-    fb.Offset offset_variantField_39;
-    fb.Offset offset_variantField_1;
-    fb.Offset offset_variantField_30;
-    fb.Offset offset_variantField_14;
-    fb.Offset offset_variantField_34;
-    fb.Offset offset_name;
-    fb.Offset offset_variantField_32;
-    fb.Offset offset_variantField_23;
-    fb.Offset offset_variantField_11;
-    fb.Offset offset_variantField_22;
-    if (_variantField_24 != null) {
-      offset_variantField_24 = _variantField_24.finish(fbBuilder);
-    }
-    if (!(_variantField_2 == null || _variantField_2.isEmpty)) {
-      offset_variantField_2 = fbBuilder
-          .writeList(_variantField_2.map((b) => b.finish(fbBuilder)).toList());
-    }
-    if (!(_variantField_4 == null || _variantField_4.isEmpty)) {
-      offset_variantField_4 = fbBuilder
-          .writeList(_variantField_4.map((b) => b.finish(fbBuilder)).toList());
-    }
-    if (_variantField_6 != null) {
-      offset_variantField_6 = _variantField_6.finish(fbBuilder);
-    }
-    if (_variantField_7 != null) {
-      offset_variantField_7 = _variantField_7.finish(fbBuilder);
-    }
-    if (_variantField_8 != null) {
-      offset_variantField_8 = _variantField_8.finish(fbBuilder);
-    }
-    if (_variantField_38 != null) {
-      offset_variantField_38 = _variantField_38.finish(fbBuilder);
-    }
-    if (_variantField_9 != null) {
-      offset_variantField_9 = _variantField_9.finish(fbBuilder);
-    }
-    if (_variantField_12 != null) {
-      offset_variantField_12 = _variantField_12.finish(fbBuilder);
-    }
-    if (!(_variantField_5 == null || _variantField_5.isEmpty)) {
-      offset_variantField_5 = fbBuilder
-          .writeList(_variantField_5.map((b) => b.finish(fbBuilder)).toList());
-    }
-    if (_variantField_13 != null) {
-      offset_variantField_13 = _variantField_13.finish(fbBuilder);
-    }
-    if (!(_variantField_33 == null || _variantField_33.isEmpty)) {
-      offset_variantField_33 = fbBuilder.writeList(
-          _variantField_33.map((b) => fbBuilder.writeString(b)).toList());
-    }
-    if (!(_variantField_3 == null || _variantField_3.isEmpty)) {
-      offset_variantField_3 = fbBuilder
-          .writeList(_variantField_3.map((b) => b.finish(fbBuilder)).toList());
-    }
-    if (!(_variantField_41 == null || _variantField_41.isEmpty)) {
-      offset_variantField_41 = fbBuilder.writeListUint32(_variantField_41);
-    }
-    if (_variantField_40 != null) {
-      offset_variantField_40 = _variantField_40.finish(fbBuilder);
-    }
-    if (_variantField_10 != null) {
-      offset_variantField_10 = _variantField_10.finish(fbBuilder);
-    }
-    if (_variantField_25 != null) {
-      offset_variantField_25 = _variantField_25.finish(fbBuilder);
-    }
-    if (_variantField_20 != null) {
-      offset_variantField_20 = fbBuilder.writeString(_variantField_20);
-    }
-    if (!(_variantField_39 == null || _variantField_39.isEmpty)) {
-      offset_variantField_39 = fbBuilder
-          .writeList(_variantField_39.map((b) => b.finish(fbBuilder)).toList());
-    }
-    if (_variantField_1 != null) {
-      offset_variantField_1 = fbBuilder.writeString(_variantField_1);
-    }
-    if (_variantField_30 != null) {
-      offset_variantField_30 = fbBuilder.writeString(_variantField_30);
-    }
-    if (_variantField_14 != null) {
-      offset_variantField_14 = _variantField_14.finish(fbBuilder);
-    }
-    if (!(_variantField_34 == null || _variantField_34.isEmpty)) {
-      offset_variantField_34 = fbBuilder.writeList(
-          _variantField_34.map((b) => fbBuilder.writeString(b)).toList());
-    }
-    if (_name != null) {
-      offset_name = fbBuilder.writeString(_name);
-    }
-    if (_variantField_32 != null) {
-      offset_variantField_32 = _variantField_32.finish(fbBuilder);
-    }
-    if (_variantField_23 != null) {
-      offset_variantField_23 = _variantField_23.finish(fbBuilder);
-    }
-    if (_variantField_11 != null) {
-      offset_variantField_11 = _variantField_11.finish(fbBuilder);
-    }
-    if (_variantField_22 != null) {
-      offset_variantField_22 = fbBuilder.writeString(_variantField_22);
-    }
-    fbBuilder.startTable();
-    if (offset_variantField_24 != null) {
-      fbBuilder.addOffset(24, offset_variantField_24);
-    }
-    if (offset_variantField_2 != null) {
-      fbBuilder.addOffset(2, offset_variantField_2);
-    }
-    if (offset_variantField_4 != null) {
-      fbBuilder.addOffset(4, offset_variantField_4);
-    }
-    if (offset_variantField_6 != null) {
-      fbBuilder.addOffset(6, offset_variantField_6);
-    }
-    if (offset_variantField_7 != null) {
-      fbBuilder.addOffset(7, offset_variantField_7);
-    }
-    if (_variantField_17 != null && _variantField_17 != 0) {
-      fbBuilder.addUint32(17, _variantField_17);
-    }
-    if (offset_variantField_8 != null) {
-      fbBuilder.addOffset(8, offset_variantField_8);
-    }
-    if (offset_variantField_38 != null) {
-      fbBuilder.addOffset(38, offset_variantField_38);
-    }
-    if (_variantField_15 != null && _variantField_15 != 0) {
-      fbBuilder.addUint32(15, _variantField_15);
-    }
-    if (_variantField_28 != null &&
-        _variantField_28 != idl.UnlinkedTokenType.NOTHING) {
-      fbBuilder.addUint8(28, _variantField_28.index);
-    }
-    if (_variantField_27 == true) {
-      fbBuilder.addBool(27, true);
-    }
-    if (offset_variantField_9 != null) {
-      fbBuilder.addOffset(9, offset_variantField_9);
-    }
-    if (offset_variantField_12 != null) {
-      fbBuilder.addOffset(12, offset_variantField_12);
-    }
-    if (offset_variantField_5 != null) {
-      fbBuilder.addOffset(5, offset_variantField_5);
-    }
-    if (offset_variantField_13 != null) {
-      fbBuilder.addOffset(13, offset_variantField_13);
-    }
-    if (offset_variantField_33 != null) {
-      fbBuilder.addOffset(33, offset_variantField_33);
-    }
-    if (_variantField_29 != null &&
-        _variantField_29 != idl.LinkedNodeCommentType.block) {
-      fbBuilder.addUint8(29, _variantField_29.index);
-    }
-    if (offset_variantField_3 != null) {
-      fbBuilder.addOffset(3, offset_variantField_3);
-    }
-    if (offset_variantField_41 != null) {
-      fbBuilder.addOffset(41, offset_variantField_41);
-    }
-    if (offset_variantField_40 != null) {
-      fbBuilder.addOffset(40, offset_variantField_40);
-    }
-    if (offset_variantField_10 != null) {
-      fbBuilder.addOffset(10, offset_variantField_10);
-    }
-    if (_variantField_26 != null &&
-        _variantField_26 !=
-            idl.LinkedNodeFormalParameterKind.requiredPositional) {
-      fbBuilder.addUint8(26, _variantField_26.index);
-    }
-    if (_variantField_21 != null && _variantField_21 != 0.0) {
-      fbBuilder.addFloat64(21, _variantField_21);
-    }
-    if (offset_variantField_25 != null) {
-      fbBuilder.addOffset(25, offset_variantField_25);
-    }
-    if (offset_variantField_20 != null) {
-      fbBuilder.addOffset(20, offset_variantField_20);
-    }
-    if (offset_variantField_39 != null) {
-      fbBuilder.addOffset(39, offset_variantField_39);
-    }
-    if (_flags != null && _flags != 0) {
-      fbBuilder.addUint32(18, _flags);
-    }
-    if (offset_variantField_1 != null) {
-      fbBuilder.addOffset(1, offset_variantField_1);
-    }
-    if (_variantField_36 != null && _variantField_36 != 0) {
-      fbBuilder.addUint32(36, _variantField_36);
-    }
-    if (_variantField_16 != null && _variantField_16 != 0) {
-      fbBuilder.addUint32(16, _variantField_16);
-    }
-    if (offset_variantField_30 != null) {
-      fbBuilder.addOffset(30, offset_variantField_30);
-    }
-    if (offset_variantField_14 != null) {
-      fbBuilder.addOffset(14, offset_variantField_14);
-    }
-    if (_kind != null && _kind != idl.LinkedNodeKind.adjacentStrings) {
-      fbBuilder.addUint8(0, _kind.index);
-    }
-    if (_variantField_31 == true) {
-      fbBuilder.addBool(31, true);
-    }
-    if (offset_variantField_34 != null) {
-      fbBuilder.addOffset(34, offset_variantField_34);
-    }
-    if (offset_name != null) {
-      fbBuilder.addOffset(37, offset_name);
-    }
-    if (_variantField_35 != null &&
-        _variantField_35 != idl.UnlinkedTokenType.NOTHING) {
-      fbBuilder.addUint8(35, _variantField_35.index);
-    }
-    if (offset_variantField_32 != null) {
-      fbBuilder.addOffset(32, offset_variantField_32);
-    }
-    if (offset_variantField_23 != null) {
-      fbBuilder.addOffset(23, offset_variantField_23);
-    }
-    if (offset_variantField_11 != null) {
-      fbBuilder.addOffset(11, offset_variantField_11);
-    }
-    if (offset_variantField_22 != null) {
-      fbBuilder.addOffset(22, offset_variantField_22);
-    }
-    if (_variantField_19 != null && _variantField_19 != 0) {
-      fbBuilder.addUint32(19, _variantField_19);
-    }
-    return fbBuilder.endTable();
-  }
-}
-
-class _LinkedNodeReader extends fb.TableReader<_LinkedNodeImpl> {
-  const _LinkedNodeReader();
-
-  @override
-  _LinkedNodeImpl createObject(fb.BufferContext bc, int offset) =>
-      _LinkedNodeImpl(bc, offset);
-}
-
-class _LinkedNodeImpl extends Object
-    with _LinkedNodeMixin
-    implements idl.LinkedNode {
-  final fb.BufferContext _bc;
-  final int _bcOffset;
-
-  _LinkedNodeImpl(this._bc, this._bcOffset);
-
-  idl.LinkedNodeType _variantField_24;
-  List<idl.LinkedNode> _variantField_2;
-  List<idl.LinkedNode> _variantField_4;
-  idl.LinkedNode _variantField_6;
-  idl.LinkedNode _variantField_7;
-  int _variantField_17;
-  idl.LinkedNode _variantField_8;
-  idl.LinkedNodeTypeSubstitution _variantField_38;
-  int _variantField_15;
-  idl.UnlinkedTokenType _variantField_28;
-  bool _variantField_27;
-  idl.LinkedNode _variantField_9;
-  idl.LinkedNode _variantField_12;
-  List<idl.LinkedNode> _variantField_5;
-  idl.LinkedNode _variantField_13;
-  List<String> _variantField_33;
-  idl.LinkedNodeCommentType _variantField_29;
-  List<idl.LinkedNode> _variantField_3;
-  List<int> _variantField_41;
-  idl.LinkedLibraryLanguageVersion _variantField_40;
-  idl.LinkedNode _variantField_10;
-  idl.LinkedNodeFormalParameterKind _variantField_26;
-  double _variantField_21;
-  idl.LinkedNodeType _variantField_25;
-  String _variantField_20;
-  List<idl.LinkedNodeType> _variantField_39;
-  int _flags;
-  String _variantField_1;
-  int _variantField_36;
-  int _variantField_16;
-  String _variantField_30;
-  idl.LinkedNode _variantField_14;
-  idl.LinkedNodeKind _kind;
-  bool _variantField_31;
-  List<String> _variantField_34;
-  String _name;
-  idl.UnlinkedTokenType _variantField_35;
-  idl.TopLevelInferenceError _variantField_32;
-  idl.LinkedNodeType _variantField_23;
-  idl.LinkedNode _variantField_11;
-  String _variantField_22;
-  int _variantField_19;
-
-  @override
-  idl.LinkedNodeType get actualReturnType {
-    assert(kind == idl.LinkedNodeKind.functionDeclaration ||
-        kind == idl.LinkedNodeKind.functionExpression ||
-        kind == idl.LinkedNodeKind.functionTypeAlias ||
-        kind == idl.LinkedNodeKind.genericFunctionType ||
-        kind == idl.LinkedNodeKind.methodDeclaration);
-    _variantField_24 ??=
-        const _LinkedNodeTypeReader().vTableGet(_bc, _bcOffset, 24, null);
-    return _variantField_24;
-  }
-
-  @override
-  idl.LinkedNodeType get actualType {
-    assert(kind == idl.LinkedNodeKind.fieldFormalParameter ||
-        kind == idl.LinkedNodeKind.functionTypedFormalParameter ||
-        kind == idl.LinkedNodeKind.simpleFormalParameter ||
-        kind == idl.LinkedNodeKind.variableDeclaration);
-    _variantField_24 ??=
-        const _LinkedNodeTypeReader().vTableGet(_bc, _bcOffset, 24, null);
-    return _variantField_24;
-  }
-
-  @override
-  idl.LinkedNodeType get binaryExpression_invokeType {
-    assert(kind == idl.LinkedNodeKind.binaryExpression);
-    _variantField_24 ??=
-        const _LinkedNodeTypeReader().vTableGet(_bc, _bcOffset, 24, null);
-    return _variantField_24;
-  }
-
-  @override
-  idl.LinkedNodeType get extensionOverride_extendedType {
-    assert(kind == idl.LinkedNodeKind.extensionOverride);
-    _variantField_24 ??=
-        const _LinkedNodeTypeReader().vTableGet(_bc, _bcOffset, 24, null);
-    return _variantField_24;
-  }
-
-  @override
-  idl.LinkedNodeType get invocationExpression_invokeType {
-    assert(kind == idl.LinkedNodeKind.functionExpressionInvocation ||
-        kind == idl.LinkedNodeKind.methodInvocation);
-    _variantField_24 ??=
-        const _LinkedNodeTypeReader().vTableGet(_bc, _bcOffset, 24, null);
-    return _variantField_24;
-  }
-
-  @override
-  List<idl.LinkedNode> get adjacentStrings_strings {
-    assert(kind == idl.LinkedNodeKind.adjacentStrings);
-    _variantField_2 ??= const fb.ListReader<idl.LinkedNode>(_LinkedNodeReader())
-        .vTableGet(_bc, _bcOffset, 2, const <idl.LinkedNode>[]);
-    return _variantField_2;
-  }
-
-  @override
-  List<idl.LinkedNode> get argumentList_arguments {
-    assert(kind == idl.LinkedNodeKind.argumentList);
-    _variantField_2 ??= const fb.ListReader<idl.LinkedNode>(_LinkedNodeReader())
-        .vTableGet(_bc, _bcOffset, 2, const <idl.LinkedNode>[]);
-    return _variantField_2;
-  }
-
-  @override
-  List<idl.LinkedNode> get block_statements {
-    assert(kind == idl.LinkedNodeKind.block);
-    _variantField_2 ??= const fb.ListReader<idl.LinkedNode>(_LinkedNodeReader())
-        .vTableGet(_bc, _bcOffset, 2, const <idl.LinkedNode>[]);
-    return _variantField_2;
-  }
-
-  @override
-  List<idl.LinkedNode> get cascadeExpression_sections {
-    assert(kind == idl.LinkedNodeKind.cascadeExpression);
-    _variantField_2 ??= const fb.ListReader<idl.LinkedNode>(_LinkedNodeReader())
-        .vTableGet(_bc, _bcOffset, 2, const <idl.LinkedNode>[]);
-    return _variantField_2;
-  }
-
-  @override
-  List<idl.LinkedNode> get comment_references {
-    assert(kind == idl.LinkedNodeKind.comment);
-    _variantField_2 ??= const fb.ListReader<idl.LinkedNode>(_LinkedNodeReader())
-        .vTableGet(_bc, _bcOffset, 2, const <idl.LinkedNode>[]);
-    return _variantField_2;
-  }
-
-  @override
-  List<idl.LinkedNode> get compilationUnit_declarations {
-    assert(kind == idl.LinkedNodeKind.compilationUnit);
-    _variantField_2 ??= const fb.ListReader<idl.LinkedNode>(_LinkedNodeReader())
-        .vTableGet(_bc, _bcOffset, 2, const <idl.LinkedNode>[]);
-    return _variantField_2;
-  }
-
-  @override
-  List<idl.LinkedNode> get constructorDeclaration_initializers {
-    assert(kind == idl.LinkedNodeKind.constructorDeclaration);
-    _variantField_2 ??= const fb.ListReader<idl.LinkedNode>(_LinkedNodeReader())
-        .vTableGet(_bc, _bcOffset, 2, const <idl.LinkedNode>[]);
-    return _variantField_2;
-  }
-
-  @override
-  List<idl.LinkedNode> get dottedName_components {
-    assert(kind == idl.LinkedNodeKind.dottedName);
-    _variantField_2 ??= const fb.ListReader<idl.LinkedNode>(_LinkedNodeReader())
-        .vTableGet(_bc, _bcOffset, 2, const <idl.LinkedNode>[]);
-    return _variantField_2;
-  }
-
-  @override
-  List<idl.LinkedNode> get enumDeclaration_constants {
-    assert(kind == idl.LinkedNodeKind.enumDeclaration);
-    _variantField_2 ??= const fb.ListReader<idl.LinkedNode>(_LinkedNodeReader())
-        .vTableGet(_bc, _bcOffset, 2, const <idl.LinkedNode>[]);
-    return _variantField_2;
-  }
-
-  @override
-  List<idl.LinkedNode> get extensionOverride_arguments {
-    assert(kind == idl.LinkedNodeKind.extensionOverride);
-    _variantField_2 ??= const fb.ListReader<idl.LinkedNode>(_LinkedNodeReader())
-        .vTableGet(_bc, _bcOffset, 2, const <idl.LinkedNode>[]);
-    return _variantField_2;
-  }
-
-  @override
-  List<idl.LinkedNode> get formalParameterList_parameters {
-    assert(kind == idl.LinkedNodeKind.formalParameterList);
-    _variantField_2 ??= const fb.ListReader<idl.LinkedNode>(_LinkedNodeReader())
-        .vTableGet(_bc, _bcOffset, 2, const <idl.LinkedNode>[]);
-    return _variantField_2;
-  }
-
-  @override
-  List<idl.LinkedNode> get implementsClause_interfaces {
-    assert(kind == idl.LinkedNodeKind.implementsClause);
-    _variantField_2 ??= const fb.ListReader<idl.LinkedNode>(_LinkedNodeReader())
-        .vTableGet(_bc, _bcOffset, 2, const <idl.LinkedNode>[]);
-    return _variantField_2;
-  }
-
-  @override
-  List<idl.LinkedNode> get instanceCreationExpression_arguments {
-    assert(kind == idl.LinkedNodeKind.instanceCreationExpression);
-    _variantField_2 ??= const fb.ListReader<idl.LinkedNode>(_LinkedNodeReader())
-        .vTableGet(_bc, _bcOffset, 2, const <idl.LinkedNode>[]);
-    return _variantField_2;
-  }
-
-  @override
-  List<idl.LinkedNode> get labeledStatement_labels {
-    assert(kind == idl.LinkedNodeKind.labeledStatement);
-    _variantField_2 ??= const fb.ListReader<idl.LinkedNode>(_LinkedNodeReader())
-        .vTableGet(_bc, _bcOffset, 2, const <idl.LinkedNode>[]);
-    return _variantField_2;
-  }
-
-  @override
-  List<idl.LinkedNode> get libraryIdentifier_components {
-    assert(kind == idl.LinkedNodeKind.libraryIdentifier);
-    _variantField_2 ??= const fb.ListReader<idl.LinkedNode>(_LinkedNodeReader())
-        .vTableGet(_bc, _bcOffset, 2, const <idl.LinkedNode>[]);
-    return _variantField_2;
-  }
-
-  @override
-  List<idl.LinkedNode> get namespaceDirective_combinators {
-    assert(kind == idl.LinkedNodeKind.exportDirective ||
-        kind == idl.LinkedNodeKind.importDirective);
-    _variantField_2 ??= const fb.ListReader<idl.LinkedNode>(_LinkedNodeReader())
-        .vTableGet(_bc, _bcOffset, 2, const <idl.LinkedNode>[]);
-    return _variantField_2;
-  }
-
-  @override
-  List<idl.LinkedNode> get onClause_superclassConstraints {
-    assert(kind == idl.LinkedNodeKind.onClause);
-    _variantField_2 ??= const fb.ListReader<idl.LinkedNode>(_LinkedNodeReader())
-        .vTableGet(_bc, _bcOffset, 2, const <idl.LinkedNode>[]);
-    return _variantField_2;
-  }
-
-  @override
-  List<idl.LinkedNode> get stringInterpolation_elements {
-    assert(kind == idl.LinkedNodeKind.stringInterpolation);
-    _variantField_2 ??= const fb.ListReader<idl.LinkedNode>(_LinkedNodeReader())
-        .vTableGet(_bc, _bcOffset, 2, const <idl.LinkedNode>[]);
-    return _variantField_2;
-  }
-
-  @override
-  List<idl.LinkedNode> get switchStatement_members {
-    assert(kind == idl.LinkedNodeKind.switchStatement);
-    _variantField_2 ??= const fb.ListReader<idl.LinkedNode>(_LinkedNodeReader())
-        .vTableGet(_bc, _bcOffset, 2, const <idl.LinkedNode>[]);
-    return _variantField_2;
-  }
-
-  @override
-  List<idl.LinkedNode> get tryStatement_catchClauses {
-    assert(kind == idl.LinkedNodeKind.tryStatement);
-    _variantField_2 ??= const fb.ListReader<idl.LinkedNode>(_LinkedNodeReader())
-        .vTableGet(_bc, _bcOffset, 2, const <idl.LinkedNode>[]);
-    return _variantField_2;
-  }
-
-  @override
-  List<idl.LinkedNode> get typeArgumentList_arguments {
-    assert(kind == idl.LinkedNodeKind.typeArgumentList);
-    _variantField_2 ??= const fb.ListReader<idl.LinkedNode>(_LinkedNodeReader())
-        .vTableGet(_bc, _bcOffset, 2, const <idl.LinkedNode>[]);
-    return _variantField_2;
-  }
-
-  @override
-  List<idl.LinkedNode> get typedLiteral_typeArguments {
-    assert(kind == idl.LinkedNodeKind.listLiteral ||
-        kind == idl.LinkedNodeKind.setOrMapLiteral);
-    _variantField_2 ??= const fb.ListReader<idl.LinkedNode>(_LinkedNodeReader())
-        .vTableGet(_bc, _bcOffset, 2, const <idl.LinkedNode>[]);
-    return _variantField_2;
-  }
-
-  @override
-  List<idl.LinkedNode> get typeName_typeArguments {
-    assert(kind == idl.LinkedNodeKind.typeName);
-    _variantField_2 ??= const fb.ListReader<idl.LinkedNode>(_LinkedNodeReader())
-        .vTableGet(_bc, _bcOffset, 2, const <idl.LinkedNode>[]);
-    return _variantField_2;
-  }
-
-  @override
-  List<idl.LinkedNode> get typeParameterList_typeParameters {
-    assert(kind == idl.LinkedNodeKind.typeParameterList);
-    _variantField_2 ??= const fb.ListReader<idl.LinkedNode>(_LinkedNodeReader())
-        .vTableGet(_bc, _bcOffset, 2, const <idl.LinkedNode>[]);
-    return _variantField_2;
-  }
-
-  @override
-  List<idl.LinkedNode> get variableDeclarationList_variables {
-    assert(kind == idl.LinkedNodeKind.variableDeclarationList);
-    _variantField_2 ??= const fb.ListReader<idl.LinkedNode>(_LinkedNodeReader())
-        .vTableGet(_bc, _bcOffset, 2, const <idl.LinkedNode>[]);
-    return _variantField_2;
-  }
-
-  @override
-  List<idl.LinkedNode> get withClause_mixinTypes {
-    assert(kind == idl.LinkedNodeKind.withClause);
-    _variantField_2 ??= const fb.ListReader<idl.LinkedNode>(_LinkedNodeReader())
-        .vTableGet(_bc, _bcOffset, 2, const <idl.LinkedNode>[]);
-    return _variantField_2;
-  }
-
-  @override
-  List<idl.LinkedNode> get annotatedNode_metadata {
-    assert(kind == idl.LinkedNodeKind.classDeclaration ||
-        kind == idl.LinkedNodeKind.classTypeAlias ||
-        kind == idl.LinkedNodeKind.constructorDeclaration ||
-        kind == idl.LinkedNodeKind.declaredIdentifier ||
-        kind == idl.LinkedNodeKind.enumDeclaration ||
-        kind == idl.LinkedNodeKind.enumConstantDeclaration ||
-        kind == idl.LinkedNodeKind.exportDirective ||
-        kind == idl.LinkedNodeKind.extensionDeclaration ||
-        kind == idl.LinkedNodeKind.fieldDeclaration ||
-        kind == idl.LinkedNodeKind.functionDeclaration ||
-        kind == idl.LinkedNodeKind.functionTypeAlias ||
-        kind == idl.LinkedNodeKind.genericTypeAlias ||
-        kind == idl.LinkedNodeKind.importDirective ||
-        kind == idl.LinkedNodeKind.libraryDirective ||
-        kind == idl.LinkedNodeKind.methodDeclaration ||
-        kind == idl.LinkedNodeKind.mixinDeclaration ||
-        kind == idl.LinkedNodeKind.partDirective ||
-        kind == idl.LinkedNodeKind.partOfDirective ||
-        kind == idl.LinkedNodeKind.topLevelVariableDeclaration ||
-        kind == idl.LinkedNodeKind.typeParameter ||
-        kind == idl.LinkedNodeKind.variableDeclaration ||
-        kind == idl.LinkedNodeKind.variableDeclarationList);
-    _variantField_4 ??= const fb.ListReader<idl.LinkedNode>(_LinkedNodeReader())
-        .vTableGet(_bc, _bcOffset, 4, const <idl.LinkedNode>[]);
-    return _variantField_4;
-  }
-
-  @override
-  List<idl.LinkedNode> get normalFormalParameter_metadata {
-    assert(kind == idl.LinkedNodeKind.fieldFormalParameter ||
-        kind == idl.LinkedNodeKind.functionTypedFormalParameter ||
-        kind == idl.LinkedNodeKind.simpleFormalParameter);
-    _variantField_4 ??= const fb.ListReader<idl.LinkedNode>(_LinkedNodeReader())
-        .vTableGet(_bc, _bcOffset, 4, const <idl.LinkedNode>[]);
-    return _variantField_4;
-  }
-
-  @override
-  List<idl.LinkedNode> get switchMember_statements {
-    assert(kind == idl.LinkedNodeKind.switchCase ||
-        kind == idl.LinkedNodeKind.switchDefault);
-    _variantField_4 ??= const fb.ListReader<idl.LinkedNode>(_LinkedNodeReader())
-        .vTableGet(_bc, _bcOffset, 4, const <idl.LinkedNode>[]);
-    return _variantField_4;
-  }
-
-  @override
-  idl.LinkedNode get annotation_arguments {
-    assert(kind == idl.LinkedNodeKind.annotation);
-    _variantField_6 ??=
-        const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 6, null);
-    return _variantField_6;
-  }
-
-  @override
-  idl.LinkedNode get asExpression_expression {
-    assert(kind == idl.LinkedNodeKind.asExpression);
-    _variantField_6 ??=
-        const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 6, null);
-    return _variantField_6;
-  }
-
-  @override
-  idl.LinkedNode get assertInitializer_condition {
-    assert(kind == idl.LinkedNodeKind.assertInitializer);
-    _variantField_6 ??=
-        const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 6, null);
-    return _variantField_6;
-  }
-
-  @override
-  idl.LinkedNode get assertStatement_condition {
-    assert(kind == idl.LinkedNodeKind.assertStatement);
-    _variantField_6 ??=
-        const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 6, null);
-    return _variantField_6;
-  }
-
-  @override
-  idl.LinkedNode get assignmentExpression_leftHandSide {
-    assert(kind == idl.LinkedNodeKind.assignmentExpression);
-    _variantField_6 ??=
-        const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 6, null);
-    return _variantField_6;
-  }
-
-  @override
-  idl.LinkedNode get awaitExpression_expression {
-    assert(kind == idl.LinkedNodeKind.awaitExpression);
-    _variantField_6 ??=
-        const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 6, null);
-    return _variantField_6;
-  }
-
-  @override
-  idl.LinkedNode get binaryExpression_leftOperand {
-    assert(kind == idl.LinkedNodeKind.binaryExpression);
-    _variantField_6 ??=
-        const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 6, null);
-    return _variantField_6;
-  }
-
-  @override
-  idl.LinkedNode get blockFunctionBody_block {
-    assert(kind == idl.LinkedNodeKind.blockFunctionBody);
-    _variantField_6 ??=
-        const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 6, null);
-    return _variantField_6;
-  }
-
-  @override
-  idl.LinkedNode get breakStatement_label {
-    assert(kind == idl.LinkedNodeKind.breakStatement);
-    _variantField_6 ??=
-        const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 6, null);
-    return _variantField_6;
-  }
-
-  @override
-  idl.LinkedNode get cascadeExpression_target {
-    assert(kind == idl.LinkedNodeKind.cascadeExpression);
-    _variantField_6 ??=
-        const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 6, null);
-    return _variantField_6;
-  }
-
-  @override
-  idl.LinkedNode get catchClause_body {
-    assert(kind == idl.LinkedNodeKind.catchClause);
-    _variantField_6 ??=
-        const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 6, null);
-    return _variantField_6;
-  }
-
-  @override
-  idl.LinkedNode get classDeclaration_extendsClause {
-    assert(kind == idl.LinkedNodeKind.classDeclaration);
-    _variantField_6 ??=
-        const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 6, null);
-    return _variantField_6;
-  }
-
-  @override
-  idl.LinkedNode get classTypeAlias_typeParameters {
-    assert(kind == idl.LinkedNodeKind.classTypeAlias);
-    _variantField_6 ??=
-        const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 6, null);
-    return _variantField_6;
-  }
-
-  @override
-  idl.LinkedNode get commentReference_identifier {
-    assert(kind == idl.LinkedNodeKind.commentReference);
-    _variantField_6 ??=
-        const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 6, null);
-    return _variantField_6;
-  }
-
-  @override
-  idl.LinkedNode get compilationUnit_scriptTag {
-    assert(kind == idl.LinkedNodeKind.compilationUnit);
-    _variantField_6 ??=
-        const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 6, null);
-    return _variantField_6;
-  }
-
-  @override
-  idl.LinkedNode get conditionalExpression_condition {
-    assert(kind == idl.LinkedNodeKind.conditionalExpression);
-    _variantField_6 ??=
-        const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 6, null);
-    return _variantField_6;
-  }
-
-  @override
-  idl.LinkedNode get configuration_name {
-    assert(kind == idl.LinkedNodeKind.configuration);
-    _variantField_6 ??=
-        const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 6, null);
-    return _variantField_6;
-  }
-
-  @override
-  idl.LinkedNode get constructorDeclaration_body {
-    assert(kind == idl.LinkedNodeKind.constructorDeclaration);
-    _variantField_6 ??=
-        const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 6, null);
-    return _variantField_6;
-  }
-
-  @override
-  idl.LinkedNode get constructorFieldInitializer_expression {
-    assert(kind == idl.LinkedNodeKind.constructorFieldInitializer);
-    _variantField_6 ??=
-        const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 6, null);
-    return _variantField_6;
-  }
-
-  @override
-  idl.LinkedNode get constructorName_name {
-    assert(kind == idl.LinkedNodeKind.constructorName);
-    _variantField_6 ??=
-        const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 6, null);
-    return _variantField_6;
-  }
-
-  @override
-  idl.LinkedNode get continueStatement_label {
-    assert(kind == idl.LinkedNodeKind.continueStatement);
-    _variantField_6 ??=
-        const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 6, null);
-    return _variantField_6;
-  }
-
-  @override
-  idl.LinkedNode get declaredIdentifier_identifier {
-    assert(kind == idl.LinkedNodeKind.declaredIdentifier);
-    _variantField_6 ??=
-        const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 6, null);
-    return _variantField_6;
-  }
-
-  @override
-  idl.LinkedNode get defaultFormalParameter_defaultValue {
-    assert(kind == idl.LinkedNodeKind.defaultFormalParameter);
-    _variantField_6 ??=
-        const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 6, null);
-    return _variantField_6;
-  }
-
-  @override
-  idl.LinkedNode get doStatement_body {
-    assert(kind == idl.LinkedNodeKind.doStatement);
-    _variantField_6 ??=
-        const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 6, null);
-    return _variantField_6;
-  }
-
-  @override
-  idl.LinkedNode get expressionFunctionBody_expression {
-    assert(kind == idl.LinkedNodeKind.expressionFunctionBody);
-    _variantField_6 ??=
-        const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 6, null);
-    return _variantField_6;
-  }
-
-  @override
-  idl.LinkedNode get expressionStatement_expression {
-    assert(kind == idl.LinkedNodeKind.expressionStatement);
-    _variantField_6 ??=
-        const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 6, null);
-    return _variantField_6;
-  }
-
-  @override
-  idl.LinkedNode get extendsClause_superclass {
-    assert(kind == idl.LinkedNodeKind.extendsClause);
-    _variantField_6 ??=
-        const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 6, null);
-    return _variantField_6;
-  }
-
-  @override
-  idl.LinkedNode get extensionDeclaration_typeParameters {
-    assert(kind == idl.LinkedNodeKind.extensionDeclaration);
-    _variantField_6 ??=
-        const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 6, null);
-    return _variantField_6;
-  }
-
-  @override
-  idl.LinkedNode get fieldDeclaration_fields {
-    assert(kind == idl.LinkedNodeKind.fieldDeclaration);
-    _variantField_6 ??=
-        const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 6, null);
-    return _variantField_6;
-  }
-
-  @override
-  idl.LinkedNode get fieldFormalParameter_type {
-    assert(kind == idl.LinkedNodeKind.fieldFormalParameter);
-    _variantField_6 ??=
-        const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 6, null);
-    return _variantField_6;
-  }
-
-  @override
-  idl.LinkedNode get forEachParts_iterable {
-    assert(kind == idl.LinkedNodeKind.forEachPartsWithDeclaration ||
-        kind == idl.LinkedNodeKind.forEachPartsWithIdentifier);
-    _variantField_6 ??=
-        const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 6, null);
-    return _variantField_6;
-  }
-
-  @override
-  idl.LinkedNode get forMixin_forLoopParts {
-    assert(kind == idl.LinkedNodeKind.forElement ||
-        kind == idl.LinkedNodeKind.forStatement);
-    _variantField_6 ??=
-        const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 6, null);
-    return _variantField_6;
-  }
-
-  @override
-  idl.LinkedNode get forParts_condition {
-    assert(kind == idl.LinkedNodeKind.forPartsWithDeclarations ||
-        kind == idl.LinkedNodeKind.forPartsWithExpression);
-    _variantField_6 ??=
-        const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 6, null);
-    return _variantField_6;
-  }
-
-  @override
-  idl.LinkedNode get functionDeclaration_functionExpression {
-    assert(kind == idl.LinkedNodeKind.functionDeclaration);
-    _variantField_6 ??=
-        const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 6, null);
-    return _variantField_6;
-  }
-
-  @override
-  idl.LinkedNode get functionDeclarationStatement_functionDeclaration {
-    assert(kind == idl.LinkedNodeKind.functionDeclarationStatement);
-    _variantField_6 ??=
-        const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 6, null);
-    return _variantField_6;
-  }
-
-  @override
-  idl.LinkedNode get functionExpression_body {
-    assert(kind == idl.LinkedNodeKind.functionExpression);
-    _variantField_6 ??=
-        const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 6, null);
-    return _variantField_6;
-  }
-
-  @override
-  idl.LinkedNode get functionExpressionInvocation_function {
-    assert(kind == idl.LinkedNodeKind.functionExpressionInvocation);
-    _variantField_6 ??=
-        const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 6, null);
-    return _variantField_6;
-  }
-
-  @override
-  idl.LinkedNode get functionTypeAlias_formalParameters {
-    assert(kind == idl.LinkedNodeKind.functionTypeAlias);
-    _variantField_6 ??=
-        const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 6, null);
-    return _variantField_6;
-  }
-
-  @override
-  idl.LinkedNode get functionTypedFormalParameter_formalParameters {
-    assert(kind == idl.LinkedNodeKind.functionTypedFormalParameter);
-    _variantField_6 ??=
-        const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 6, null);
-    return _variantField_6;
-  }
-
-  @override
-  idl.LinkedNode get genericFunctionType_typeParameters {
-    assert(kind == idl.LinkedNodeKind.genericFunctionType);
-    _variantField_6 ??=
-        const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 6, null);
-    return _variantField_6;
-  }
-
-  @override
-  idl.LinkedNode get genericTypeAlias_typeParameters {
-    assert(kind == idl.LinkedNodeKind.genericTypeAlias);
-    _variantField_6 ??=
-        const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 6, null);
-    return _variantField_6;
-  }
-
-  @override
-  idl.LinkedNode get ifMixin_condition {
-    assert(kind == idl.LinkedNodeKind.ifElement ||
-        kind == idl.LinkedNodeKind.ifStatement);
-    _variantField_6 ??=
-        const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 6, null);
-    return _variantField_6;
-  }
-
-  @override
-  idl.LinkedNode get indexExpression_index {
-    assert(kind == idl.LinkedNodeKind.indexExpression);
-    _variantField_6 ??=
-        const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 6, null);
-    return _variantField_6;
-  }
-
-  @override
-  idl.LinkedNode get interpolationExpression_expression {
-    assert(kind == idl.LinkedNodeKind.interpolationExpression);
-    _variantField_6 ??=
-        const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 6, null);
-    return _variantField_6;
-  }
-
-  @override
-  idl.LinkedNode get isExpression_expression {
-    assert(kind == idl.LinkedNodeKind.isExpression);
-    _variantField_6 ??=
-        const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 6, null);
-    return _variantField_6;
-  }
-
-  @override
-  idl.LinkedNode get label_label {
-    assert(kind == idl.LinkedNodeKind.label);
-    _variantField_6 ??=
-        const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 6, null);
-    return _variantField_6;
-  }
-
-  @override
-  idl.LinkedNode get labeledStatement_statement {
-    assert(kind == idl.LinkedNodeKind.labeledStatement);
-    _variantField_6 ??=
-        const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 6, null);
-    return _variantField_6;
-  }
-
-  @override
-  idl.LinkedNode get libraryDirective_name {
-    assert(kind == idl.LinkedNodeKind.libraryDirective);
-    _variantField_6 ??=
-        const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 6, null);
-    return _variantField_6;
-  }
-
-  @override
-  idl.LinkedNode get mapLiteralEntry_key {
-    assert(kind == idl.LinkedNodeKind.mapLiteralEntry);
-    _variantField_6 ??=
-        const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 6, null);
-    return _variantField_6;
-  }
-
-  @override
-  idl.LinkedNode get methodDeclaration_body {
-    assert(kind == idl.LinkedNodeKind.methodDeclaration);
-    _variantField_6 ??=
-        const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 6, null);
-    return _variantField_6;
-  }
-
-  @override
-  idl.LinkedNode get methodInvocation_methodName {
-    assert(kind == idl.LinkedNodeKind.methodInvocation);
-    _variantField_6 ??=
-        const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 6, null);
-    return _variantField_6;
-  }
-
-  @override
-  idl.LinkedNode get mixinDeclaration_onClause {
-    assert(kind == idl.LinkedNodeKind.mixinDeclaration);
-    _variantField_6 ??=
-        const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 6, null);
-    return _variantField_6;
-  }
-
-  @override
-  idl.LinkedNode get namedExpression_expression {
-    assert(kind == idl.LinkedNodeKind.namedExpression);
-    _variantField_6 ??=
-        const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 6, null);
-    return _variantField_6;
-  }
-
-  @override
-  idl.LinkedNode get nativeClause_name {
-    assert(kind == idl.LinkedNodeKind.nativeClause);
-    _variantField_6 ??=
-        const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 6, null);
-    return _variantField_6;
-  }
-
-  @override
-  idl.LinkedNode get nativeFunctionBody_stringLiteral {
-    assert(kind == idl.LinkedNodeKind.nativeFunctionBody);
-    _variantField_6 ??=
-        const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 6, null);
-    return _variantField_6;
-  }
-
-  @override
-  idl.LinkedNode get parenthesizedExpression_expression {
-    assert(kind == idl.LinkedNodeKind.parenthesizedExpression);
-    _variantField_6 ??=
-        const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 6, null);
-    return _variantField_6;
-  }
-
-  @override
-  idl.LinkedNode get partOfDirective_libraryName {
-    assert(kind == idl.LinkedNodeKind.partOfDirective);
-    _variantField_6 ??=
-        const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 6, null);
-    return _variantField_6;
-  }
-
-  @override
-  idl.LinkedNode get postfixExpression_operand {
-    assert(kind == idl.LinkedNodeKind.postfixExpression);
-    _variantField_6 ??=
-        const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 6, null);
-    return _variantField_6;
-  }
-
-  @override
-  idl.LinkedNode get prefixedIdentifier_identifier {
-    assert(kind == idl.LinkedNodeKind.prefixedIdentifier);
-    _variantField_6 ??=
-        const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 6, null);
-    return _variantField_6;
-  }
-
-  @override
-  idl.LinkedNode get prefixExpression_operand {
-    assert(kind == idl.LinkedNodeKind.prefixExpression);
-    _variantField_6 ??=
-        const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 6, null);
-    return _variantField_6;
-  }
-
-  @override
-  idl.LinkedNode get propertyAccess_propertyName {
-    assert(kind == idl.LinkedNodeKind.propertyAccess);
-    _variantField_6 ??=
-        const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 6, null);
-    return _variantField_6;
-  }
-
-  @override
-  idl.LinkedNode get redirectingConstructorInvocation_arguments {
-    assert(kind == idl.LinkedNodeKind.redirectingConstructorInvocation);
-    _variantField_6 ??=
-        const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 6, null);
-    return _variantField_6;
-  }
-
-  @override
-  idl.LinkedNode get returnStatement_expression {
-    assert(kind == idl.LinkedNodeKind.returnStatement);
-    _variantField_6 ??=
-        const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 6, null);
-    return _variantField_6;
-  }
-
-  @override
-  idl.LinkedNode get simpleFormalParameter_type {
-    assert(kind == idl.LinkedNodeKind.simpleFormalParameter);
-    _variantField_6 ??=
-        const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 6, null);
-    return _variantField_6;
-  }
-
-  @override
-  idl.LinkedNode get spreadElement_expression {
-    assert(kind == idl.LinkedNodeKind.spreadElement);
-    _variantField_6 ??=
-        const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 6, null);
-    return _variantField_6;
-  }
-
-  @override
-  idl.LinkedNode get superConstructorInvocation_arguments {
-    assert(kind == idl.LinkedNodeKind.superConstructorInvocation);
-    _variantField_6 ??=
-        const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 6, null);
-    return _variantField_6;
-  }
-
-  @override
-  idl.LinkedNode get switchCase_expression {
-    assert(kind == idl.LinkedNodeKind.switchCase);
-    _variantField_6 ??=
-        const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 6, null);
-    return _variantField_6;
-  }
-
-  @override
-  idl.LinkedNode get throwExpression_expression {
-    assert(kind == idl.LinkedNodeKind.throwExpression);
-    _variantField_6 ??=
-        const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 6, null);
-    return _variantField_6;
-  }
-
-  @override
-  idl.LinkedNode get topLevelVariableDeclaration_variableList {
-    assert(kind == idl.LinkedNodeKind.topLevelVariableDeclaration);
-    _variantField_6 ??=
-        const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 6, null);
-    return _variantField_6;
-  }
-
-  @override
-  idl.LinkedNode get tryStatement_body {
-    assert(kind == idl.LinkedNodeKind.tryStatement);
-    _variantField_6 ??=
-        const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 6, null);
-    return _variantField_6;
-  }
-
-  @override
-  idl.LinkedNode get typeName_name {
-    assert(kind == idl.LinkedNodeKind.typeName);
-    _variantField_6 ??=
-        const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 6, null);
-    return _variantField_6;
-  }
-
-  @override
-  idl.LinkedNode get typeParameter_bound {
-    assert(kind == idl.LinkedNodeKind.typeParameter);
-    _variantField_6 ??=
-        const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 6, null);
-    return _variantField_6;
-  }
-
-  @override
-  idl.LinkedNode get variableDeclaration_initializer {
-    assert(kind == idl.LinkedNodeKind.variableDeclaration);
-    _variantField_6 ??=
-        const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 6, null);
-    return _variantField_6;
-  }
-
-  @override
-  idl.LinkedNode get variableDeclarationList_type {
-    assert(kind == idl.LinkedNodeKind.variableDeclarationList);
-    _variantField_6 ??=
-        const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 6, null);
-    return _variantField_6;
-  }
-
-  @override
-  idl.LinkedNode get variableDeclarationStatement_variables {
-    assert(kind == idl.LinkedNodeKind.variableDeclarationStatement);
-    _variantField_6 ??=
-        const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 6, null);
-    return _variantField_6;
-  }
-
-  @override
-  idl.LinkedNode get whileStatement_body {
-    assert(kind == idl.LinkedNodeKind.whileStatement);
-    _variantField_6 ??=
-        const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 6, null);
-    return _variantField_6;
-  }
-
-  @override
-  idl.LinkedNode get yieldStatement_expression {
-    assert(kind == idl.LinkedNodeKind.yieldStatement);
-    _variantField_6 ??=
-        const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 6, null);
-    return _variantField_6;
-  }
-
-  @override
-  idl.LinkedNode get annotation_constructorName {
-    assert(kind == idl.LinkedNodeKind.annotation);
-    _variantField_7 ??=
-        const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 7, null);
-    return _variantField_7;
-  }
-
-  @override
-  idl.LinkedNode get asExpression_type {
-    assert(kind == idl.LinkedNodeKind.asExpression);
-    _variantField_7 ??=
-        const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 7, null);
-    return _variantField_7;
-  }
-
-  @override
-  idl.LinkedNode get assertInitializer_message {
-    assert(kind == idl.LinkedNodeKind.assertInitializer);
-    _variantField_7 ??=
-        const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 7, null);
-    return _variantField_7;
-  }
-
-  @override
-  idl.LinkedNode get assertStatement_message {
-    assert(kind == idl.LinkedNodeKind.assertStatement);
-    _variantField_7 ??=
-        const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 7, null);
-    return _variantField_7;
-  }
-
-  @override
-  idl.LinkedNode get assignmentExpression_rightHandSide {
-    assert(kind == idl.LinkedNodeKind.assignmentExpression);
-    _variantField_7 ??=
-        const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 7, null);
-    return _variantField_7;
-  }
-
-  @override
-  idl.LinkedNode get binaryExpression_rightOperand {
-    assert(kind == idl.LinkedNodeKind.binaryExpression);
-    _variantField_7 ??=
-        const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 7, null);
-    return _variantField_7;
-  }
-
-  @override
-  idl.LinkedNode get catchClause_exceptionParameter {
-    assert(kind == idl.LinkedNodeKind.catchClause);
-    _variantField_7 ??=
-        const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 7, null);
-    return _variantField_7;
-  }
-
-  @override
-  idl.LinkedNode get classDeclaration_withClause {
-    assert(kind == idl.LinkedNodeKind.classDeclaration);
-    _variantField_7 ??=
-        const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 7, null);
-    return _variantField_7;
-  }
-
-  @override
-  idl.LinkedNode get classTypeAlias_superclass {
-    assert(kind == idl.LinkedNodeKind.classTypeAlias);
-    _variantField_7 ??=
-        const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 7, null);
-    return _variantField_7;
-  }
-
-  @override
-  idl.LinkedNode get conditionalExpression_elseExpression {
-    assert(kind == idl.LinkedNodeKind.conditionalExpression);
-    _variantField_7 ??=
-        const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 7, null);
-    return _variantField_7;
-  }
-
-  @override
-  idl.LinkedNode get configuration_value {
-    assert(kind == idl.LinkedNodeKind.configuration);
-    _variantField_7 ??=
-        const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 7, null);
-    return _variantField_7;
-  }
-
-  @override
-  idl.LinkedNode get constructorFieldInitializer_fieldName {
-    assert(kind == idl.LinkedNodeKind.constructorFieldInitializer);
-    _variantField_7 ??=
-        const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 7, null);
-    return _variantField_7;
-  }
-
-  @override
-  idl.LinkedNode get constructorName_type {
-    assert(kind == idl.LinkedNodeKind.constructorName);
-    _variantField_7 ??=
-        const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 7, null);
-    return _variantField_7;
-  }
-
-  @override
-  idl.LinkedNode get declaredIdentifier_type {
-    assert(kind == idl.LinkedNodeKind.declaredIdentifier);
-    _variantField_7 ??=
-        const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 7, null);
-    return _variantField_7;
-  }
-
-  @override
-  idl.LinkedNode get defaultFormalParameter_parameter {
-    assert(kind == idl.LinkedNodeKind.defaultFormalParameter);
-    _variantField_7 ??=
-        const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 7, null);
-    return _variantField_7;
-  }
-
-  @override
-  idl.LinkedNode get doStatement_condition {
-    assert(kind == idl.LinkedNodeKind.doStatement);
-    _variantField_7 ??=
-        const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 7, null);
-    return _variantField_7;
-  }
-
-  @override
-  idl.LinkedNode get extensionDeclaration_extendedType {
-    assert(kind == idl.LinkedNodeKind.extensionDeclaration);
-    _variantField_7 ??=
-        const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 7, null);
-    return _variantField_7;
-  }
-
-  @override
-  idl.LinkedNode get extensionOverride_extensionName {
-    assert(kind == idl.LinkedNodeKind.extensionOverride);
-    _variantField_7 ??=
-        const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 7, null);
-    return _variantField_7;
-  }
-
-  @override
-  idl.LinkedNode get fieldFormalParameter_typeParameters {
-    assert(kind == idl.LinkedNodeKind.fieldFormalParameter);
-    _variantField_7 ??=
-        const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 7, null);
-    return _variantField_7;
-  }
-
-  @override
-  idl.LinkedNode get forEachPartsWithDeclaration_loopVariable {
-    assert(kind == idl.LinkedNodeKind.forEachPartsWithDeclaration);
-    _variantField_7 ??=
-        const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 7, null);
-    return _variantField_7;
-  }
-
-  @override
-  idl.LinkedNode get forEachPartsWithIdentifier_identifier {
-    assert(kind == idl.LinkedNodeKind.forEachPartsWithIdentifier);
-    _variantField_7 ??=
-        const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 7, null);
-    return _variantField_7;
-  }
-
-  @override
-  idl.LinkedNode get forElement_body {
-    assert(kind == idl.LinkedNodeKind.forElement);
-    _variantField_7 ??=
-        const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 7, null);
-    return _variantField_7;
-  }
-
-  @override
-  idl.LinkedNode get forPartsWithDeclarations_variables {
-    assert(kind == idl.LinkedNodeKind.forPartsWithDeclarations);
-    _variantField_7 ??=
-        const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 7, null);
-    return _variantField_7;
-  }
-
-  @override
-  idl.LinkedNode get forPartsWithExpression_initialization {
-    assert(kind == idl.LinkedNodeKind.forPartsWithExpression);
-    _variantField_7 ??=
-        const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 7, null);
-    return _variantField_7;
-  }
-
-  @override
-  idl.LinkedNode get forStatement_body {
-    assert(kind == idl.LinkedNodeKind.forStatement);
-    _variantField_7 ??=
-        const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 7, null);
-    return _variantField_7;
-  }
-
-  @override
-  idl.LinkedNode get functionDeclaration_returnType {
-    assert(kind == idl.LinkedNodeKind.functionDeclaration);
-    _variantField_7 ??=
-        const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 7, null);
-    return _variantField_7;
-  }
-
-  @override
-  idl.LinkedNode get functionExpression_formalParameters {
-    assert(kind == idl.LinkedNodeKind.functionExpression);
-    _variantField_7 ??=
-        const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 7, null);
-    return _variantField_7;
-  }
-
-  @override
-  idl.LinkedNode get functionTypeAlias_returnType {
-    assert(kind == idl.LinkedNodeKind.functionTypeAlias);
-    _variantField_7 ??=
-        const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 7, null);
-    return _variantField_7;
-  }
-
-  @override
-  idl.LinkedNode get functionTypedFormalParameter_returnType {
-    assert(kind == idl.LinkedNodeKind.functionTypedFormalParameter);
-    _variantField_7 ??=
-        const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 7, null);
-    return _variantField_7;
-  }
-
-  @override
-  idl.LinkedNode get genericFunctionType_returnType {
-    assert(kind == idl.LinkedNodeKind.genericFunctionType);
-    _variantField_7 ??=
-        const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 7, null);
-    return _variantField_7;
-  }
-
-  @override
-  idl.LinkedNode get genericTypeAlias_functionType {
-    assert(kind == idl.LinkedNodeKind.genericTypeAlias);
-    _variantField_7 ??=
-        const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 7, null);
-    return _variantField_7;
-  }
-
-  @override
-  idl.LinkedNode get ifStatement_elseStatement {
-    assert(kind == idl.LinkedNodeKind.ifStatement);
-    _variantField_7 ??=
-        const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 7, null);
-    return _variantField_7;
-  }
-
-  @override
-  idl.LinkedNode get indexExpression_target {
-    assert(kind == idl.LinkedNodeKind.indexExpression);
-    _variantField_7 ??=
-        const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 7, null);
-    return _variantField_7;
-  }
-
-  @override
-  idl.LinkedNode get instanceCreationExpression_constructorName {
-    assert(kind == idl.LinkedNodeKind.instanceCreationExpression);
-    _variantField_7 ??=
-        const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 7, null);
-    return _variantField_7;
-  }
-
-  @override
-  idl.LinkedNode get isExpression_type {
-    assert(kind == idl.LinkedNodeKind.isExpression);
-    _variantField_7 ??=
-        const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 7, null);
-    return _variantField_7;
-  }
-
-  @override
-  idl.LinkedNode get mapLiteralEntry_value {
-    assert(kind == idl.LinkedNodeKind.mapLiteralEntry);
-    _variantField_7 ??=
-        const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 7, null);
-    return _variantField_7;
-  }
-
-  @override
-  idl.LinkedNode get methodDeclaration_formalParameters {
-    assert(kind == idl.LinkedNodeKind.methodDeclaration);
-    _variantField_7 ??=
-        const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 7, null);
-    return _variantField_7;
-  }
-
-  @override
-  idl.LinkedNode get methodInvocation_target {
-    assert(kind == idl.LinkedNodeKind.methodInvocation);
-    _variantField_7 ??=
-        const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 7, null);
-    return _variantField_7;
-  }
-
-  @override
-  idl.LinkedNode get namedExpression_name {
-    assert(kind == idl.LinkedNodeKind.namedExpression);
-    _variantField_7 ??=
-        const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 7, null);
-    return _variantField_7;
-  }
-
-  @override
-  idl.LinkedNode get partOfDirective_uri {
-    assert(kind == idl.LinkedNodeKind.partOfDirective);
-    _variantField_7 ??=
-        const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 7, null);
-    return _variantField_7;
-  }
-
-  @override
-  idl.LinkedNode get prefixedIdentifier_prefix {
-    assert(kind == idl.LinkedNodeKind.prefixedIdentifier);
-    _variantField_7 ??=
-        const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 7, null);
-    return _variantField_7;
-  }
-
-  @override
-  idl.LinkedNode get propertyAccess_target {
-    assert(kind == idl.LinkedNodeKind.propertyAccess);
-    _variantField_7 ??=
-        const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 7, null);
-    return _variantField_7;
-  }
-
-  @override
-  idl.LinkedNode get redirectingConstructorInvocation_constructorName {
-    assert(kind == idl.LinkedNodeKind.redirectingConstructorInvocation);
-    _variantField_7 ??=
-        const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 7, null);
-    return _variantField_7;
-  }
-
-  @override
-  idl.LinkedNode get superConstructorInvocation_constructorName {
-    assert(kind == idl.LinkedNodeKind.superConstructorInvocation);
-    _variantField_7 ??=
-        const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 7, null);
-    return _variantField_7;
-  }
-
-  @override
-  idl.LinkedNode get switchStatement_expression {
-    assert(kind == idl.LinkedNodeKind.switchStatement);
-    _variantField_7 ??=
-        const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 7, null);
-    return _variantField_7;
-  }
-
-  @override
-  idl.LinkedNode get tryStatement_finallyBlock {
-    assert(kind == idl.LinkedNodeKind.tryStatement);
-    _variantField_7 ??=
-        const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 7, null);
-    return _variantField_7;
-  }
-
-  @override
-  idl.LinkedNode get whileStatement_condition {
-    assert(kind == idl.LinkedNodeKind.whileStatement);
-    _variantField_7 ??=
-        const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 7, null);
-    return _variantField_7;
-  }
-
-  @override
-  int get annotation_element {
-    assert(kind == idl.LinkedNodeKind.annotation);
-    _variantField_17 ??=
-        const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 17, 0);
-    return _variantField_17;
-  }
-
-  @override
-  int get genericFunctionType_id {
-    assert(kind == idl.LinkedNodeKind.genericFunctionType);
-    _variantField_17 ??=
-        const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 17, 0);
-    return _variantField_17;
-  }
-
-  @override
-  idl.LinkedNode get annotation_name {
-    assert(kind == idl.LinkedNodeKind.annotation);
-    _variantField_8 ??=
-        const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 8, null);
-    return _variantField_8;
-  }
-
-  @override
-  idl.LinkedNode get catchClause_exceptionType {
-    assert(kind == idl.LinkedNodeKind.catchClause);
-    _variantField_8 ??=
-        const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 8, null);
-    return _variantField_8;
-  }
-
-  @override
-  idl.LinkedNode get classDeclaration_nativeClause {
-    assert(kind == idl.LinkedNodeKind.classDeclaration);
-    _variantField_8 ??=
-        const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 8, null);
-    return _variantField_8;
-  }
-
-  @override
-  idl.LinkedNode get classTypeAlias_withClause {
-    assert(kind == idl.LinkedNodeKind.classTypeAlias);
-    _variantField_8 ??=
-        const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 8, null);
-    return _variantField_8;
-  }
-
-  @override
-  idl.LinkedNode get conditionalExpression_thenExpression {
-    assert(kind == idl.LinkedNodeKind.conditionalExpression);
-    _variantField_8 ??=
-        const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 8, null);
-    return _variantField_8;
-  }
-
-  @override
-  idl.LinkedNode get configuration_uri {
-    assert(kind == idl.LinkedNodeKind.configuration);
-    _variantField_8 ??=
-        const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 8, null);
-    return _variantField_8;
-  }
-
-  @override
-  idl.LinkedNode get constructorDeclaration_parameters {
-    assert(kind == idl.LinkedNodeKind.constructorDeclaration);
-    _variantField_8 ??=
-        const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 8, null);
-    return _variantField_8;
-  }
-
-  @override
-  idl.LinkedNode get extensionOverride_typeArguments {
-    assert(kind == idl.LinkedNodeKind.extensionOverride);
-    _variantField_8 ??=
-        const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 8, null);
-    return _variantField_8;
-  }
-
-  @override
-  idl.LinkedNode get fieldFormalParameter_formalParameters {
-    assert(kind == idl.LinkedNodeKind.fieldFormalParameter);
-    _variantField_8 ??=
-        const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 8, null);
-    return _variantField_8;
-  }
-
-  @override
-  idl.LinkedNode get functionExpression_typeParameters {
-    assert(kind == idl.LinkedNodeKind.functionExpression);
-    _variantField_8 ??=
-        const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 8, null);
-    return _variantField_8;
-  }
-
-  @override
-  idl.LinkedNode get functionTypeAlias_typeParameters {
-    assert(kind == idl.LinkedNodeKind.functionTypeAlias);
-    _variantField_8 ??=
-        const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 8, null);
-    return _variantField_8;
-  }
-
-  @override
-  idl.LinkedNode get functionTypedFormalParameter_typeParameters {
-    assert(kind == idl.LinkedNodeKind.functionTypedFormalParameter);
-    _variantField_8 ??=
-        const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 8, null);
-    return _variantField_8;
-  }
-
-  @override
-  idl.LinkedNode get genericFunctionType_formalParameters {
-    assert(kind == idl.LinkedNodeKind.genericFunctionType);
-    _variantField_8 ??=
-        const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 8, null);
-    return _variantField_8;
-  }
-
-  @override
-  idl.LinkedNode get ifElement_thenElement {
-    assert(kind == idl.LinkedNodeKind.ifElement);
-    _variantField_8 ??=
-        const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 8, null);
-    return _variantField_8;
-  }
-
-  @override
-  idl.LinkedNode get ifStatement_thenStatement {
-    assert(kind == idl.LinkedNodeKind.ifStatement);
-    _variantField_8 ??=
-        const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 8, null);
-    return _variantField_8;
-  }
-
-  @override
-  idl.LinkedNode get instanceCreationExpression_typeArguments {
-    assert(kind == idl.LinkedNodeKind.instanceCreationExpression);
-    _variantField_8 ??=
-        const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 8, null);
-    return _variantField_8;
-  }
-
-  @override
-  idl.LinkedNode get methodDeclaration_returnType {
-    assert(kind == idl.LinkedNodeKind.methodDeclaration);
-    _variantField_8 ??=
-        const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 8, null);
-    return _variantField_8;
-  }
-
-  @override
-  idl.LinkedNodeTypeSubstitution get annotation_substitution {
-    assert(kind == idl.LinkedNodeKind.annotation);
-    _variantField_38 ??= const _LinkedNodeTypeSubstitutionReader()
-        .vTableGet(_bc, _bcOffset, 38, null);
-    return _variantField_38;
-  }
-
-  @override
-  idl.LinkedNodeTypeSubstitution get assignmentExpression_substitution {
-    assert(kind == idl.LinkedNodeKind.assignmentExpression);
-    _variantField_38 ??= const _LinkedNodeTypeSubstitutionReader()
-        .vTableGet(_bc, _bcOffset, 38, null);
-    return _variantField_38;
-  }
-
-  @override
-  idl.LinkedNodeTypeSubstitution get binaryExpression_substitution {
-    assert(kind == idl.LinkedNodeKind.binaryExpression);
-    _variantField_38 ??= const _LinkedNodeTypeSubstitutionReader()
-        .vTableGet(_bc, _bcOffset, 38, null);
-    return _variantField_38;
-  }
-
-  @override
-  idl.LinkedNodeTypeSubstitution get constructorName_substitution {
-    assert(kind == idl.LinkedNodeKind.constructorName);
-    _variantField_38 ??= const _LinkedNodeTypeSubstitutionReader()
-        .vTableGet(_bc, _bcOffset, 38, null);
-    return _variantField_38;
-  }
-
-  @override
-  idl.LinkedNodeTypeSubstitution get indexExpression_substitution {
-    assert(kind == idl.LinkedNodeKind.indexExpression);
-    _variantField_38 ??= const _LinkedNodeTypeSubstitutionReader()
-        .vTableGet(_bc, _bcOffset, 38, null);
-    return _variantField_38;
-  }
-
-  @override
-  idl.LinkedNodeTypeSubstitution get postfixExpression_substitution {
-    assert(kind == idl.LinkedNodeKind.postfixExpression);
-    _variantField_38 ??= const _LinkedNodeTypeSubstitutionReader()
-        .vTableGet(_bc, _bcOffset, 38, null);
-    return _variantField_38;
-  }
-
-  @override
-  idl.LinkedNodeTypeSubstitution get prefixExpression_substitution {
-    assert(kind == idl.LinkedNodeKind.prefixExpression);
-    _variantField_38 ??= const _LinkedNodeTypeSubstitutionReader()
-        .vTableGet(_bc, _bcOffset, 38, null);
-    return _variantField_38;
-  }
-
-  @override
-  idl.LinkedNodeTypeSubstitution
-      get redirectingConstructorInvocation_substitution {
-    assert(kind == idl.LinkedNodeKind.redirectingConstructorInvocation);
-    _variantField_38 ??= const _LinkedNodeTypeSubstitutionReader()
-        .vTableGet(_bc, _bcOffset, 38, null);
-    return _variantField_38;
-  }
-
-  @override
-  idl.LinkedNodeTypeSubstitution get simpleIdentifier_substitution {
-    assert(kind == idl.LinkedNodeKind.simpleIdentifier);
-    _variantField_38 ??= const _LinkedNodeTypeSubstitutionReader()
-        .vTableGet(_bc, _bcOffset, 38, null);
-    return _variantField_38;
-  }
-
-  @override
-  idl.LinkedNodeTypeSubstitution get superConstructorInvocation_substitution {
-    assert(kind == idl.LinkedNodeKind.superConstructorInvocation);
-    _variantField_38 ??= const _LinkedNodeTypeSubstitutionReader()
-        .vTableGet(_bc, _bcOffset, 38, null);
-    return _variantField_38;
-  }
-
-  @override
-  int get assignmentExpression_element {
-    assert(kind == idl.LinkedNodeKind.assignmentExpression);
-    _variantField_15 ??=
-        const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 15, 0);
-    return _variantField_15;
-  }
-
-  @override
-  int get binaryExpression_element {
-    assert(kind == idl.LinkedNodeKind.binaryExpression);
-    _variantField_15 ??=
-        const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 15, 0);
-    return _variantField_15;
-  }
-
-  @override
-  int get constructorName_element {
-    assert(kind == idl.LinkedNodeKind.constructorName);
-    _variantField_15 ??=
-        const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 15, 0);
-    return _variantField_15;
-  }
-
-  @override
-  int get emptyFunctionBody_fake {
-    assert(kind == idl.LinkedNodeKind.emptyFunctionBody);
-    _variantField_15 ??=
-        const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 15, 0);
-    return _variantField_15;
-  }
-
-  @override
-  int get emptyStatement_fake {
-    assert(kind == idl.LinkedNodeKind.emptyStatement);
-    _variantField_15 ??=
-        const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 15, 0);
-    return _variantField_15;
-  }
-
-  @override
-  int get indexExpression_element {
-    assert(kind == idl.LinkedNodeKind.indexExpression);
-    _variantField_15 ??=
-        const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 15, 0);
-    return _variantField_15;
-  }
-
-  @override
-  int get nullLiteral_fake {
-    assert(kind == idl.LinkedNodeKind.nullLiteral);
-    _variantField_15 ??=
-        const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 15, 0);
-    return _variantField_15;
-  }
-
-  @override
-  int get postfixExpression_element {
-    assert(kind == idl.LinkedNodeKind.postfixExpression);
-    _variantField_15 ??=
-        const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 15, 0);
-    return _variantField_15;
-  }
-
-  @override
-  int get prefixExpression_element {
-    assert(kind == idl.LinkedNodeKind.prefixExpression);
-    _variantField_15 ??=
-        const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 15, 0);
-    return _variantField_15;
-  }
-
-  @override
-  int get redirectingConstructorInvocation_element {
-    assert(kind == idl.LinkedNodeKind.redirectingConstructorInvocation);
-    _variantField_15 ??=
-        const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 15, 0);
-    return _variantField_15;
-  }
-
-  @override
-  int get simpleIdentifier_element {
-    assert(kind == idl.LinkedNodeKind.simpleIdentifier);
-    _variantField_15 ??=
-        const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 15, 0);
-    return _variantField_15;
-  }
-
-  @override
-  int get superConstructorInvocation_element {
-    assert(kind == idl.LinkedNodeKind.superConstructorInvocation);
-    _variantField_15 ??=
-        const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 15, 0);
-    return _variantField_15;
-  }
-
-  @override
-  int get typeParameter_variance {
-    assert(kind == idl.LinkedNodeKind.typeParameter);
-    _variantField_15 ??=
-        const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 15, 0);
-    return _variantField_15;
-  }
-
-  @override
-  idl.UnlinkedTokenType get assignmentExpression_operator {
-    assert(kind == idl.LinkedNodeKind.assignmentExpression);
-    _variantField_28 ??= const _UnlinkedTokenTypeReader()
-        .vTableGet(_bc, _bcOffset, 28, idl.UnlinkedTokenType.NOTHING);
-    return _variantField_28;
-  }
-
-  @override
-  idl.UnlinkedTokenType get binaryExpression_operator {
-    assert(kind == idl.LinkedNodeKind.binaryExpression);
-    _variantField_28 ??= const _UnlinkedTokenTypeReader()
-        .vTableGet(_bc, _bcOffset, 28, idl.UnlinkedTokenType.NOTHING);
-    return _variantField_28;
-  }
-
-  @override
-  idl.UnlinkedTokenType get postfixExpression_operator {
-    assert(kind == idl.LinkedNodeKind.postfixExpression);
-    _variantField_28 ??= const _UnlinkedTokenTypeReader()
-        .vTableGet(_bc, _bcOffset, 28, idl.UnlinkedTokenType.NOTHING);
-    return _variantField_28;
-  }
-
-  @override
-  idl.UnlinkedTokenType get prefixExpression_operator {
-    assert(kind == idl.LinkedNodeKind.prefixExpression);
-    _variantField_28 ??= const _UnlinkedTokenTypeReader()
-        .vTableGet(_bc, _bcOffset, 28, idl.UnlinkedTokenType.NOTHING);
-    return _variantField_28;
-  }
-
-  @override
-  idl.UnlinkedTokenType get propertyAccess_operator {
-    assert(kind == idl.LinkedNodeKind.propertyAccess);
-    _variantField_28 ??= const _UnlinkedTokenTypeReader()
-        .vTableGet(_bc, _bcOffset, 28, idl.UnlinkedTokenType.NOTHING);
-    return _variantField_28;
-  }
-
-  @override
-  bool get booleanLiteral_value {
-    assert(kind == idl.LinkedNodeKind.booleanLiteral);
-    _variantField_27 ??=
-        const fb.BoolReader().vTableGet(_bc, _bcOffset, 27, false);
-    return _variantField_27;
-  }
-
-  @override
-  bool get classDeclaration_isDartObject {
-    assert(kind == idl.LinkedNodeKind.classDeclaration);
-    _variantField_27 ??=
-        const fb.BoolReader().vTableGet(_bc, _bcOffset, 27, false);
-    return _variantField_27;
-  }
-
-  @override
-  bool get inheritsCovariant {
-    assert(kind == idl.LinkedNodeKind.fieldFormalParameter ||
-        kind == idl.LinkedNodeKind.functionTypedFormalParameter ||
-        kind == idl.LinkedNodeKind.simpleFormalParameter ||
-        kind == idl.LinkedNodeKind.variableDeclaration);
-    _variantField_27 ??=
-        const fb.BoolReader().vTableGet(_bc, _bcOffset, 27, false);
-    return _variantField_27;
-  }
-
-  @override
-  bool get typeAlias_hasSelfReference {
-    assert(kind == idl.LinkedNodeKind.functionTypeAlias ||
-        kind == idl.LinkedNodeKind.genericTypeAlias);
-    _variantField_27 ??=
-        const fb.BoolReader().vTableGet(_bc, _bcOffset, 27, false);
-    return _variantField_27;
-  }
-
-  @override
-  idl.LinkedNode get catchClause_stackTraceParameter {
-    assert(kind == idl.LinkedNodeKind.catchClause);
-    _variantField_9 ??=
-        const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 9, null);
-    return _variantField_9;
-  }
-
-  @override
-  idl.LinkedNode get classTypeAlias_implementsClause {
-    assert(kind == idl.LinkedNodeKind.classTypeAlias);
-    _variantField_9 ??=
-        const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 9, null);
-    return _variantField_9;
-  }
-
-  @override
-  idl.LinkedNode get constructorDeclaration_redirectedConstructor {
-    assert(kind == idl.LinkedNodeKind.constructorDeclaration);
-    _variantField_9 ??=
-        const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 9, null);
-    return _variantField_9;
-  }
-
-  @override
-  idl.LinkedNode get ifElement_elseElement {
-    assert(kind == idl.LinkedNodeKind.ifElement);
-    _variantField_9 ??=
-        const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 9, null);
-    return _variantField_9;
-  }
-
-  @override
-  idl.LinkedNode get methodDeclaration_typeParameters {
-    assert(kind == idl.LinkedNodeKind.methodDeclaration);
-    _variantField_9 ??=
-        const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 9, null);
-    return _variantField_9;
-  }
-
-  @override
-  idl.LinkedNode get classOrMixinDeclaration_implementsClause {
-    assert(kind == idl.LinkedNodeKind.classDeclaration ||
-        kind == idl.LinkedNodeKind.mixinDeclaration);
-    _variantField_12 ??=
-        const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 12, null);
-    return _variantField_12;
-  }
-
-  @override
-  idl.LinkedNode get invocationExpression_typeArguments {
-    assert(kind == idl.LinkedNodeKind.functionExpressionInvocation ||
-        kind == idl.LinkedNodeKind.methodInvocation);
-    _variantField_12 ??=
-        const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 12, null);
-    return _variantField_12;
-  }
-
-  @override
-  List<idl.LinkedNode> get classOrMixinDeclaration_members {
-    assert(kind == idl.LinkedNodeKind.classDeclaration ||
-        kind == idl.LinkedNodeKind.mixinDeclaration);
-    _variantField_5 ??= const fb.ListReader<idl.LinkedNode>(_LinkedNodeReader())
-        .vTableGet(_bc, _bcOffset, 5, const <idl.LinkedNode>[]);
-    return _variantField_5;
-  }
-
-  @override
-  List<idl.LinkedNode> get extensionDeclaration_members {
-    assert(kind == idl.LinkedNodeKind.extensionDeclaration);
-    _variantField_5 ??= const fb.ListReader<idl.LinkedNode>(_LinkedNodeReader())
-        .vTableGet(_bc, _bcOffset, 5, const <idl.LinkedNode>[]);
-    return _variantField_5;
-  }
-
-  @override
-  List<idl.LinkedNode> get forParts_updaters {
-    assert(kind == idl.LinkedNodeKind.forPartsWithDeclarations ||
-        kind == idl.LinkedNodeKind.forPartsWithExpression);
-    _variantField_5 ??= const fb.ListReader<idl.LinkedNode>(_LinkedNodeReader())
-        .vTableGet(_bc, _bcOffset, 5, const <idl.LinkedNode>[]);
-    return _variantField_5;
-  }
-
-  @override
-  idl.LinkedNode get classOrMixinDeclaration_typeParameters {
-    assert(kind == idl.LinkedNodeKind.classDeclaration ||
-        kind == idl.LinkedNodeKind.mixinDeclaration);
-    _variantField_13 ??=
-        const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 13, null);
-    return _variantField_13;
-  }
-
-  @override
-  List<String> get comment_tokens {
-    assert(kind == idl.LinkedNodeKind.comment);
-    _variantField_33 ??= const fb.ListReader<String>(fb.StringReader())
-        .vTableGet(_bc, _bcOffset, 33, const <String>[]);
-    return _variantField_33;
-  }
-
-  @override
-  idl.LinkedNodeCommentType get comment_type {
-    assert(kind == idl.LinkedNodeKind.comment);
-    _variantField_29 ??= const _LinkedNodeCommentTypeReader()
-        .vTableGet(_bc, _bcOffset, 29, idl.LinkedNodeCommentType.block);
-    return _variantField_29;
-  }
-
-  @override
-  List<idl.LinkedNode> get compilationUnit_directives {
-    assert(kind == idl.LinkedNodeKind.compilationUnit);
-    _variantField_3 ??= const fb.ListReader<idl.LinkedNode>(_LinkedNodeReader())
-        .vTableGet(_bc, _bcOffset, 3, const <idl.LinkedNode>[]);
-    return _variantField_3;
-  }
-
-  @override
-  List<idl.LinkedNode> get listLiteral_elements {
-    assert(kind == idl.LinkedNodeKind.listLiteral);
-    _variantField_3 ??= const fb.ListReader<idl.LinkedNode>(_LinkedNodeReader())
-        .vTableGet(_bc, _bcOffset, 3, const <idl.LinkedNode>[]);
-    return _variantField_3;
-  }
-
-  @override
-  List<idl.LinkedNode> get namespaceDirective_configurations {
-    assert(kind == idl.LinkedNodeKind.exportDirective ||
-        kind == idl.LinkedNodeKind.importDirective);
-    _variantField_3 ??= const fb.ListReader<idl.LinkedNode>(_LinkedNodeReader())
-        .vTableGet(_bc, _bcOffset, 3, const <idl.LinkedNode>[]);
-    return _variantField_3;
-  }
-
-  @override
-  List<idl.LinkedNode> get setOrMapLiteral_elements {
-    assert(kind == idl.LinkedNodeKind.setOrMapLiteral);
-    _variantField_3 ??= const fb.ListReader<idl.LinkedNode>(_LinkedNodeReader())
-        .vTableGet(_bc, _bcOffset, 3, const <idl.LinkedNode>[]);
-    return _variantField_3;
-  }
-
-  @override
-  List<idl.LinkedNode> get switchMember_labels {
-    assert(kind == idl.LinkedNodeKind.switchCase ||
-        kind == idl.LinkedNodeKind.switchDefault);
-    _variantField_3 ??= const fb.ListReader<idl.LinkedNode>(_LinkedNodeReader())
-        .vTableGet(_bc, _bcOffset, 3, const <idl.LinkedNode>[]);
-    return _variantField_3;
-  }
-
-  @override
-  List<int> get compilationUnit_featureSet {
-    assert(kind == idl.LinkedNodeKind.compilationUnit);
-    _variantField_41 ??= const fb.Uint32ListReader()
-        .vTableGet(_bc, _bcOffset, 41, const <int>[]);
-    return _variantField_41;
-  }
-
-  @override
-  idl.LinkedLibraryLanguageVersion get compilationUnit_languageVersion {
-    assert(kind == idl.LinkedNodeKind.compilationUnit);
-    _variantField_40 ??= const _LinkedLibraryLanguageVersionReader()
-        .vTableGet(_bc, _bcOffset, 40, null);
-    return _variantField_40;
-  }
-
-  @override
-  idl.LinkedNode get constructorDeclaration_returnType {
-    assert(kind == idl.LinkedNodeKind.constructorDeclaration);
-    _variantField_10 ??=
-        const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 10, null);
-    return _variantField_10;
-  }
-
-  @override
-  idl.LinkedNodeFormalParameterKind get defaultFormalParameter_kind {
-    assert(kind == idl.LinkedNodeKind.defaultFormalParameter);
-    _variantField_26 ??= const _LinkedNodeFormalParameterKindReader().vTableGet(
-        _bc,
-        _bcOffset,
-        26,
-        idl.LinkedNodeFormalParameterKind.requiredPositional);
-    return _variantField_26;
-  }
-
-  @override
-  double get doubleLiteral_value {
-    assert(kind == idl.LinkedNodeKind.doubleLiteral);
-    _variantField_21 ??=
-        const fb.Float64Reader().vTableGet(_bc, _bcOffset, 21, 0.0);
-    return _variantField_21;
-  }
-
-  @override
-  idl.LinkedNodeType get expression_type {
-    assert(kind == idl.LinkedNodeKind.assignmentExpression ||
-        kind == idl.LinkedNodeKind.asExpression ||
-        kind == idl.LinkedNodeKind.awaitExpression ||
-        kind == idl.LinkedNodeKind.binaryExpression ||
-        kind == idl.LinkedNodeKind.cascadeExpression ||
-        kind == idl.LinkedNodeKind.conditionalExpression ||
-        kind == idl.LinkedNodeKind.functionExpressionInvocation ||
-        kind == idl.LinkedNodeKind.indexExpression ||
-        kind == idl.LinkedNodeKind.instanceCreationExpression ||
-        kind == idl.LinkedNodeKind.integerLiteral ||
-        kind == idl.LinkedNodeKind.listLiteral ||
-        kind == idl.LinkedNodeKind.methodInvocation ||
-        kind == idl.LinkedNodeKind.nullLiteral ||
-        kind == idl.LinkedNodeKind.parenthesizedExpression ||
-        kind == idl.LinkedNodeKind.prefixExpression ||
-        kind == idl.LinkedNodeKind.prefixedIdentifier ||
-        kind == idl.LinkedNodeKind.propertyAccess ||
-        kind == idl.LinkedNodeKind.postfixExpression ||
-        kind == idl.LinkedNodeKind.rethrowExpression ||
-        kind == idl.LinkedNodeKind.setOrMapLiteral ||
-        kind == idl.LinkedNodeKind.simpleIdentifier ||
-        kind == idl.LinkedNodeKind.superExpression ||
-        kind == idl.LinkedNodeKind.symbolLiteral ||
-        kind == idl.LinkedNodeKind.thisExpression ||
-        kind == idl.LinkedNodeKind.throwExpression);
-    _variantField_25 ??=
-        const _LinkedNodeTypeReader().vTableGet(_bc, _bcOffset, 25, null);
-    return _variantField_25;
-  }
-
-  @override
-  idl.LinkedNodeType get genericFunctionType_type {
-    assert(kind == idl.LinkedNodeKind.genericFunctionType);
-    _variantField_25 ??=
-        const _LinkedNodeTypeReader().vTableGet(_bc, _bcOffset, 25, null);
-    return _variantField_25;
-  }
-
-  @override
-  String get extensionDeclaration_refName {
-    assert(kind == idl.LinkedNodeKind.extensionDeclaration);
-    _variantField_20 ??=
-        const fb.StringReader().vTableGet(_bc, _bcOffset, 20, '');
-    return _variantField_20;
-  }
-
-  @override
-  String get namespaceDirective_selectedUri {
-    assert(kind == idl.LinkedNodeKind.exportDirective ||
-        kind == idl.LinkedNodeKind.importDirective);
-    _variantField_20 ??=
-        const fb.StringReader().vTableGet(_bc, _bcOffset, 20, '');
-    return _variantField_20;
-  }
-
-  @override
-  String get simpleStringLiteral_value {
-    assert(kind == idl.LinkedNodeKind.simpleStringLiteral);
-    _variantField_20 ??=
-        const fb.StringReader().vTableGet(_bc, _bcOffset, 20, '');
-    return _variantField_20;
-  }
-
-  @override
-  List<idl.LinkedNodeType> get extensionOverride_typeArgumentTypes {
-    assert(kind == idl.LinkedNodeKind.extensionOverride);
-    _variantField_39 ??=
-        const fb.ListReader<idl.LinkedNodeType>(_LinkedNodeTypeReader())
-            .vTableGet(_bc, _bcOffset, 39, const <idl.LinkedNodeType>[]);
-    return _variantField_39;
-  }
-
-  @override
-  int get flags {
-    _flags ??= const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 18, 0);
-    return _flags;
-  }
-
-  @override
-  String get importDirective_prefix {
-    assert(kind == idl.LinkedNodeKind.importDirective);
-    _variantField_1 ??=
-        const fb.StringReader().vTableGet(_bc, _bcOffset, 1, '');
-    return _variantField_1;
-  }
-
-  @override
-  int get informativeId {
-    assert(kind == idl.LinkedNodeKind.classDeclaration ||
-        kind == idl.LinkedNodeKind.classTypeAlias ||
-        kind == idl.LinkedNodeKind.compilationUnit ||
-        kind == idl.LinkedNodeKind.compilationUnit ||
-        kind == idl.LinkedNodeKind.constructorDeclaration ||
-        kind == idl.LinkedNodeKind.defaultFormalParameter ||
-        kind == idl.LinkedNodeKind.enumConstantDeclaration ||
-        kind == idl.LinkedNodeKind.enumDeclaration ||
-        kind == idl.LinkedNodeKind.exportDirective ||
-        kind == idl.LinkedNodeKind.extensionDeclaration ||
-        kind == idl.LinkedNodeKind.fieldDeclaration ||
-        kind == idl.LinkedNodeKind.fieldFormalParameter ||
-        kind == idl.LinkedNodeKind.functionDeclaration ||
-        kind == idl.LinkedNodeKind.functionTypedFormalParameter ||
-        kind == idl.LinkedNodeKind.functionTypeAlias ||
-        kind == idl.LinkedNodeKind.genericTypeAlias ||
-        kind == idl.LinkedNodeKind.hideCombinator ||
-        kind == idl.LinkedNodeKind.importDirective ||
-        kind == idl.LinkedNodeKind.libraryDirective ||
-        kind == idl.LinkedNodeKind.methodDeclaration ||
-        kind == idl.LinkedNodeKind.mixinDeclaration ||
-        kind == idl.LinkedNodeKind.partDirective ||
-        kind == idl.LinkedNodeKind.partOfDirective ||
-        kind == idl.LinkedNodeKind.showCombinator ||
-        kind == idl.LinkedNodeKind.simpleFormalParameter ||
-        kind == idl.LinkedNodeKind.topLevelVariableDeclaration ||
-        kind == idl.LinkedNodeKind.typeParameter ||
-        kind == idl.LinkedNodeKind.variableDeclaration ||
-        kind == idl.LinkedNodeKind.variableDeclarationList);
-    _variantField_36 ??=
-        const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 36, 0);
-    return _variantField_36;
-  }
-
-  @override
-  int get integerLiteral_value {
-    assert(kind == idl.LinkedNodeKind.integerLiteral);
-    _variantField_16 ??=
-        const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 16, 0);
-    return _variantField_16;
-  }
-
-  @override
-  String get interpolationString_value {
-    assert(kind == idl.LinkedNodeKind.interpolationString);
-    _variantField_30 ??=
-        const fb.StringReader().vTableGet(_bc, _bcOffset, 30, '');
-    return _variantField_30;
-  }
-
-  @override
-  idl.LinkedNode get invocationExpression_arguments {
-    assert(kind == idl.LinkedNodeKind.functionExpressionInvocation ||
-        kind == idl.LinkedNodeKind.methodInvocation);
-    _variantField_14 ??=
-        const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 14, null);
-    return _variantField_14;
-  }
-
-  @override
-  idl.LinkedNode get uriBasedDirective_uri {
-    assert(kind == idl.LinkedNodeKind.exportDirective ||
-        kind == idl.LinkedNodeKind.importDirective ||
-        kind == idl.LinkedNodeKind.partDirective);
-    _variantField_14 ??=
-        const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 14, null);
-    return _variantField_14;
-  }
-
-  @override
-  idl.LinkedNodeKind get kind {
-    _kind ??= const _LinkedNodeKindReader()
-        .vTableGet(_bc, _bcOffset, 0, idl.LinkedNodeKind.adjacentStrings);
-    return _kind;
-  }
-
-  @override
-  bool get methodDeclaration_hasOperatorEqualWithParameterTypeFromObject {
-    assert(kind == idl.LinkedNodeKind.methodDeclaration);
-    _variantField_31 ??=
-        const fb.BoolReader().vTableGet(_bc, _bcOffset, 31, false);
-    return _variantField_31;
-  }
-
-  @override
-  bool get simplyBoundable_isSimplyBounded {
-    assert(kind == idl.LinkedNodeKind.classDeclaration ||
-        kind == idl.LinkedNodeKind.classTypeAlias ||
-        kind == idl.LinkedNodeKind.functionTypeAlias ||
-        kind == idl.LinkedNodeKind.genericTypeAlias ||
-        kind == idl.LinkedNodeKind.mixinDeclaration);
-    _variantField_31 ??=
-        const fb.BoolReader().vTableGet(_bc, _bcOffset, 31, false);
-    return _variantField_31;
-  }
-
-  @override
-  List<String> get mixinDeclaration_superInvokedNames {
-    assert(kind == idl.LinkedNodeKind.mixinDeclaration);
-    _variantField_34 ??= const fb.ListReader<String>(fb.StringReader())
-        .vTableGet(_bc, _bcOffset, 34, const <String>[]);
-    return _variantField_34;
-  }
-
-  @override
-  List<String> get names {
-    assert(kind == idl.LinkedNodeKind.hideCombinator ||
-        kind == idl.LinkedNodeKind.showCombinator ||
-        kind == idl.LinkedNodeKind.symbolLiteral);
-    _variantField_34 ??= const fb.ListReader<String>(fb.StringReader())
-        .vTableGet(_bc, _bcOffset, 34, const <String>[]);
-    return _variantField_34;
-  }
-
-  @override
-  String get name {
-    _name ??= const fb.StringReader().vTableGet(_bc, _bcOffset, 37, '');
-    return _name;
-  }
-
-  @override
-  idl.UnlinkedTokenType get spreadElement_spreadOperator {
-    assert(kind == idl.LinkedNodeKind.spreadElement);
-    _variantField_35 ??= const _UnlinkedTokenTypeReader()
-        .vTableGet(_bc, _bcOffset, 35, idl.UnlinkedTokenType.NOTHING);
-    return _variantField_35;
-  }
-
-  @override
-  idl.TopLevelInferenceError get topLevelTypeInferenceError {
-    assert(kind == idl.LinkedNodeKind.methodDeclaration ||
-        kind == idl.LinkedNodeKind.simpleFormalParameter ||
-        kind == idl.LinkedNodeKind.variableDeclaration);
-    _variantField_32 ??= const _TopLevelInferenceErrorReader()
-        .vTableGet(_bc, _bcOffset, 32, null);
-    return _variantField_32;
-  }
-
-  @override
-  idl.LinkedNodeType get typeName_type {
-    assert(kind == idl.LinkedNodeKind.typeName);
-    _variantField_23 ??=
-        const _LinkedNodeTypeReader().vTableGet(_bc, _bcOffset, 23, null);
-    return _variantField_23;
-  }
-
-  @override
-  idl.LinkedNodeType get typeParameter_defaultType {
-    assert(kind == idl.LinkedNodeKind.typeParameter);
-    _variantField_23 ??=
-        const _LinkedNodeTypeReader().vTableGet(_bc, _bcOffset, 23, null);
-    return _variantField_23;
-  }
-
-  @override
-  idl.LinkedNode get unused11 {
-    assert(kind == idl.LinkedNodeKind.classDeclaration);
-    _variantField_11 ??=
-        const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 11, null);
-    return _variantField_11;
-  }
-
-  @override
-  String get uriBasedDirective_uriContent {
-    assert(kind == idl.LinkedNodeKind.exportDirective ||
-        kind == idl.LinkedNodeKind.importDirective ||
-        kind == idl.LinkedNodeKind.partDirective);
-    _variantField_22 ??=
-        const fb.StringReader().vTableGet(_bc, _bcOffset, 22, '');
-    return _variantField_22;
-  }
-
-  @override
-  int get uriBasedDirective_uriElement {
-    assert(kind == idl.LinkedNodeKind.exportDirective ||
-        kind == idl.LinkedNodeKind.importDirective ||
-        kind == idl.LinkedNodeKind.partDirective);
-    _variantField_19 ??=
-        const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 19, 0);
-    return _variantField_19;
-  }
-}
-
-abstract class _LinkedNodeMixin implements idl.LinkedNode {
-  @override
-  Map<String, Object> toJson() {
-    Map<String, Object> _result = <String, Object>{};
-    if (flags != 0) {
-      _result["flags"] = flags;
-    }
-    if (kind != idl.LinkedNodeKind.adjacentStrings) {
-      _result["kind"] = kind.toString().split('.')[1];
-    }
-    if (name != '') {
-      _result["name"] = name;
-    }
-    if (kind == idl.LinkedNodeKind.adjacentStrings) {
-      if (adjacentStrings_strings.isNotEmpty) {
-        _result["adjacentStrings_strings"] =
-            adjacentStrings_strings.map((_value) => _value.toJson()).toList();
-      }
-    }
-    if (kind == idl.LinkedNodeKind.annotation) {
-      if (annotation_arguments != null) {
-        _result["annotation_arguments"] = annotation_arguments.toJson();
-      }
-      if (annotation_constructorName != null) {
-        _result["annotation_constructorName"] =
-            annotation_constructorName.toJson();
-      }
-      if (annotation_element != 0) {
-        _result["annotation_element"] = annotation_element;
-      }
-      if (annotation_name != null) {
-        _result["annotation_name"] = annotation_name.toJson();
-      }
-      if (annotation_substitution != null) {
-        _result["annotation_substitution"] = annotation_substitution.toJson();
-      }
-    }
-    if (kind == idl.LinkedNodeKind.argumentList) {
-      if (argumentList_arguments.isNotEmpty) {
-        _result["argumentList_arguments"] =
-            argumentList_arguments.map((_value) => _value.toJson()).toList();
-      }
-    }
-    if (kind == idl.LinkedNodeKind.asExpression) {
-      if (asExpression_expression != null) {
-        _result["asExpression_expression"] = asExpression_expression.toJson();
-      }
-      if (asExpression_type != null) {
-        _result["asExpression_type"] = asExpression_type.toJson();
-      }
-      if (expression_type != null) {
-        _result["expression_type"] = expression_type.toJson();
-      }
-    }
-    if (kind == idl.LinkedNodeKind.assertInitializer) {
-      if (assertInitializer_condition != null) {
-        _result["assertInitializer_condition"] =
-            assertInitializer_condition.toJson();
-      }
-      if (assertInitializer_message != null) {
-        _result["assertInitializer_message"] =
-            assertInitializer_message.toJson();
-      }
-    }
-    if (kind == idl.LinkedNodeKind.assertStatement) {
-      if (assertStatement_condition != null) {
-        _result["assertStatement_condition"] =
-            assertStatement_condition.toJson();
-      }
-      if (assertStatement_message != null) {
-        _result["assertStatement_message"] = assertStatement_message.toJson();
-      }
-    }
-    if (kind == idl.LinkedNodeKind.assignmentExpression) {
-      if (assignmentExpression_leftHandSide != null) {
-        _result["assignmentExpression_leftHandSide"] =
-            assignmentExpression_leftHandSide.toJson();
-      }
-      if (assignmentExpression_rightHandSide != null) {
-        _result["assignmentExpression_rightHandSide"] =
-            assignmentExpression_rightHandSide.toJson();
-      }
-      if (assignmentExpression_substitution != null) {
-        _result["assignmentExpression_substitution"] =
-            assignmentExpression_substitution.toJson();
-      }
-      if (assignmentExpression_element != 0) {
-        _result["assignmentExpression_element"] = assignmentExpression_element;
-      }
-      if (assignmentExpression_operator != idl.UnlinkedTokenType.NOTHING) {
-        _result["assignmentExpression_operator"] =
-            assignmentExpression_operator.toString().split('.')[1];
-      }
-      if (expression_type != null) {
-        _result["expression_type"] = expression_type.toJson();
-      }
-    }
-    if (kind == idl.LinkedNodeKind.awaitExpression) {
-      if (awaitExpression_expression != null) {
-        _result["awaitExpression_expression"] =
-            awaitExpression_expression.toJson();
-      }
-      if (expression_type != null) {
-        _result["expression_type"] = expression_type.toJson();
-      }
-    }
-    if (kind == idl.LinkedNodeKind.binaryExpression) {
-      if (binaryExpression_invokeType != null) {
-        _result["binaryExpression_invokeType"] =
-            binaryExpression_invokeType.toJson();
-      }
-      if (binaryExpression_leftOperand != null) {
-        _result["binaryExpression_leftOperand"] =
-            binaryExpression_leftOperand.toJson();
-      }
-      if (binaryExpression_rightOperand != null) {
-        _result["binaryExpression_rightOperand"] =
-            binaryExpression_rightOperand.toJson();
-      }
-      if (binaryExpression_substitution != null) {
-        _result["binaryExpression_substitution"] =
-            binaryExpression_substitution.toJson();
-      }
-      if (binaryExpression_element != 0) {
-        _result["binaryExpression_element"] = binaryExpression_element;
-      }
-      if (binaryExpression_operator != idl.UnlinkedTokenType.NOTHING) {
-        _result["binaryExpression_operator"] =
-            binaryExpression_operator.toString().split('.')[1];
-      }
-      if (expression_type != null) {
-        _result["expression_type"] = expression_type.toJson();
-      }
-    }
-    if (kind == idl.LinkedNodeKind.block) {
-      if (block_statements.isNotEmpty) {
-        _result["block_statements"] =
-            block_statements.map((_value) => _value.toJson()).toList();
-      }
-    }
-    if (kind == idl.LinkedNodeKind.blockFunctionBody) {
-      if (blockFunctionBody_block != null) {
-        _result["blockFunctionBody_block"] = blockFunctionBody_block.toJson();
-      }
-    }
-    if (kind == idl.LinkedNodeKind.booleanLiteral) {
-      if (booleanLiteral_value != false) {
-        _result["booleanLiteral_value"] = booleanLiteral_value;
-      }
-    }
-    if (kind == idl.LinkedNodeKind.breakStatement) {
-      if (breakStatement_label != null) {
-        _result["breakStatement_label"] = breakStatement_label.toJson();
-      }
-    }
-    if (kind == idl.LinkedNodeKind.cascadeExpression) {
-      if (cascadeExpression_sections.isNotEmpty) {
-        _result["cascadeExpression_sections"] = cascadeExpression_sections
-            .map((_value) => _value.toJson())
-            .toList();
-      }
-      if (cascadeExpression_target != null) {
-        _result["cascadeExpression_target"] = cascadeExpression_target.toJson();
-      }
-      if (expression_type != null) {
-        _result["expression_type"] = expression_type.toJson();
-      }
-    }
-    if (kind == idl.LinkedNodeKind.catchClause) {
-      if (catchClause_body != null) {
-        _result["catchClause_body"] = catchClause_body.toJson();
-      }
-      if (catchClause_exceptionParameter != null) {
-        _result["catchClause_exceptionParameter"] =
-            catchClause_exceptionParameter.toJson();
-      }
-      if (catchClause_exceptionType != null) {
-        _result["catchClause_exceptionType"] =
-            catchClause_exceptionType.toJson();
-      }
-      if (catchClause_stackTraceParameter != null) {
-        _result["catchClause_stackTraceParameter"] =
-            catchClause_stackTraceParameter.toJson();
-      }
-    }
-    if (kind == idl.LinkedNodeKind.classDeclaration) {
-      if (annotatedNode_metadata.isNotEmpty) {
-        _result["annotatedNode_metadata"] =
-            annotatedNode_metadata.map((_value) => _value.toJson()).toList();
-      }
-      if (classDeclaration_extendsClause != null) {
-        _result["classDeclaration_extendsClause"] =
-            classDeclaration_extendsClause.toJson();
-      }
-      if (classDeclaration_withClause != null) {
-        _result["classDeclaration_withClause"] =
-            classDeclaration_withClause.toJson();
-      }
-      if (classDeclaration_nativeClause != null) {
-        _result["classDeclaration_nativeClause"] =
-            classDeclaration_nativeClause.toJson();
-      }
-      if (classDeclaration_isDartObject != false) {
-        _result["classDeclaration_isDartObject"] =
-            classDeclaration_isDartObject;
-      }
-      if (classOrMixinDeclaration_implementsClause != null) {
-        _result["classOrMixinDeclaration_implementsClause"] =
-            classOrMixinDeclaration_implementsClause.toJson();
-      }
-      if (classOrMixinDeclaration_members.isNotEmpty) {
-        _result["classOrMixinDeclaration_members"] =
-            classOrMixinDeclaration_members
-                .map((_value) => _value.toJson())
-                .toList();
-      }
-      if (classOrMixinDeclaration_typeParameters != null) {
-        _result["classOrMixinDeclaration_typeParameters"] =
-            classOrMixinDeclaration_typeParameters.toJson();
-      }
-      if (informativeId != 0) {
-        _result["informativeId"] = informativeId;
-      }
-      if (simplyBoundable_isSimplyBounded != false) {
-        _result["simplyBoundable_isSimplyBounded"] =
-            simplyBoundable_isSimplyBounded;
-      }
-      if (unused11 != null) {
-        _result["unused11"] = unused11.toJson();
-      }
-    }
-    if (kind == idl.LinkedNodeKind.classTypeAlias) {
-      if (annotatedNode_metadata.isNotEmpty) {
-        _result["annotatedNode_metadata"] =
-            annotatedNode_metadata.map((_value) => _value.toJson()).toList();
-      }
-      if (classTypeAlias_typeParameters != null) {
-        _result["classTypeAlias_typeParameters"] =
-            classTypeAlias_typeParameters.toJson();
-      }
-      if (classTypeAlias_superclass != null) {
-        _result["classTypeAlias_superclass"] =
-            classTypeAlias_superclass.toJson();
-      }
-      if (classTypeAlias_withClause != null) {
-        _result["classTypeAlias_withClause"] =
-            classTypeAlias_withClause.toJson();
-      }
-      if (classTypeAlias_implementsClause != null) {
-        _result["classTypeAlias_implementsClause"] =
-            classTypeAlias_implementsClause.toJson();
-      }
-      if (informativeId != 0) {
-        _result["informativeId"] = informativeId;
-      }
-      if (simplyBoundable_isSimplyBounded != false) {
-        _result["simplyBoundable_isSimplyBounded"] =
-            simplyBoundable_isSimplyBounded;
-      }
-    }
-    if (kind == idl.LinkedNodeKind.comment) {
-      if (comment_references.isNotEmpty) {
-        _result["comment_references"] =
-            comment_references.map((_value) => _value.toJson()).toList();
-      }
-      if (comment_tokens.isNotEmpty) {
-        _result["comment_tokens"] = comment_tokens;
-      }
-      if (comment_type != idl.LinkedNodeCommentType.block) {
-        _result["comment_type"] = comment_type.toString().split('.')[1];
-      }
-    }
-    if (kind == idl.LinkedNodeKind.commentReference) {
-      if (commentReference_identifier != null) {
-        _result["commentReference_identifier"] =
-            commentReference_identifier.toJson();
-      }
-    }
-    if (kind == idl.LinkedNodeKind.compilationUnit) {
-      if (compilationUnit_declarations.isNotEmpty) {
-        _result["compilationUnit_declarations"] = compilationUnit_declarations
-            .map((_value) => _value.toJson())
-            .toList();
-      }
-      if (compilationUnit_scriptTag != null) {
-        _result["compilationUnit_scriptTag"] =
-            compilationUnit_scriptTag.toJson();
-      }
-      if (compilationUnit_directives.isNotEmpty) {
-        _result["compilationUnit_directives"] = compilationUnit_directives
-            .map((_value) => _value.toJson())
-            .toList();
-      }
-      if (compilationUnit_featureSet.isNotEmpty) {
-        _result["compilationUnit_featureSet"] = compilationUnit_featureSet;
-      }
-      if (compilationUnit_languageVersion != null) {
-        _result["compilationUnit_languageVersion"] =
-            compilationUnit_languageVersion.toJson();
-      }
-      if (informativeId != 0) {
-        _result["informativeId"] = informativeId;
-      }
-    }
-    if (kind == idl.LinkedNodeKind.conditionalExpression) {
-      if (conditionalExpression_condition != null) {
-        _result["conditionalExpression_condition"] =
-            conditionalExpression_condition.toJson();
-      }
-      if (conditionalExpression_elseExpression != null) {
-        _result["conditionalExpression_elseExpression"] =
-            conditionalExpression_elseExpression.toJson();
-      }
-      if (conditionalExpression_thenExpression != null) {
-        _result["conditionalExpression_thenExpression"] =
-            conditionalExpression_thenExpression.toJson();
-      }
-      if (expression_type != null) {
-        _result["expression_type"] = expression_type.toJson();
-      }
-    }
-    if (kind == idl.LinkedNodeKind.configuration) {
-      if (configuration_name != null) {
-        _result["configuration_name"] = configuration_name.toJson();
-      }
-      if (configuration_value != null) {
-        _result["configuration_value"] = configuration_value.toJson();
-      }
-      if (configuration_uri != null) {
-        _result["configuration_uri"] = configuration_uri.toJson();
-      }
-    }
-    if (kind == idl.LinkedNodeKind.constructorDeclaration) {
-      if (constructorDeclaration_initializers.isNotEmpty) {
-        _result["constructorDeclaration_initializers"] =
-            constructorDeclaration_initializers
-                .map((_value) => _value.toJson())
-                .toList();
-      }
-      if (annotatedNode_metadata.isNotEmpty) {
-        _result["annotatedNode_metadata"] =
-            annotatedNode_metadata.map((_value) => _value.toJson()).toList();
-      }
-      if (constructorDeclaration_body != null) {
-        _result["constructorDeclaration_body"] =
-            constructorDeclaration_body.toJson();
-      }
-      if (constructorDeclaration_parameters != null) {
-        _result["constructorDeclaration_parameters"] =
-            constructorDeclaration_parameters.toJson();
-      }
-      if (constructorDeclaration_redirectedConstructor != null) {
-        _result["constructorDeclaration_redirectedConstructor"] =
-            constructorDeclaration_redirectedConstructor.toJson();
-      }
-      if (constructorDeclaration_returnType != null) {
-        _result["constructorDeclaration_returnType"] =
-            constructorDeclaration_returnType.toJson();
-      }
-      if (informativeId != 0) {
-        _result["informativeId"] = informativeId;
-      }
-    }
-    if (kind == idl.LinkedNodeKind.constructorFieldInitializer) {
-      if (constructorFieldInitializer_expression != null) {
-        _result["constructorFieldInitializer_expression"] =
-            constructorFieldInitializer_expression.toJson();
-      }
-      if (constructorFieldInitializer_fieldName != null) {
-        _result["constructorFieldInitializer_fieldName"] =
-            constructorFieldInitializer_fieldName.toJson();
-      }
-    }
-    if (kind == idl.LinkedNodeKind.constructorName) {
-      if (constructorName_name != null) {
-        _result["constructorName_name"] = constructorName_name.toJson();
-      }
-      if (constructorName_type != null) {
-        _result["constructorName_type"] = constructorName_type.toJson();
-      }
-      if (constructorName_substitution != null) {
-        _result["constructorName_substitution"] =
-            constructorName_substitution.toJson();
-      }
-      if (constructorName_element != 0) {
-        _result["constructorName_element"] = constructorName_element;
-      }
-    }
-    if (kind == idl.LinkedNodeKind.continueStatement) {
-      if (continueStatement_label != null) {
-        _result["continueStatement_label"] = continueStatement_label.toJson();
-      }
-    }
-    if (kind == idl.LinkedNodeKind.declaredIdentifier) {
-      if (annotatedNode_metadata.isNotEmpty) {
-        _result["annotatedNode_metadata"] =
-            annotatedNode_metadata.map((_value) => _value.toJson()).toList();
-      }
-      if (declaredIdentifier_identifier != null) {
-        _result["declaredIdentifier_identifier"] =
-            declaredIdentifier_identifier.toJson();
-      }
-      if (declaredIdentifier_type != null) {
-        _result["declaredIdentifier_type"] = declaredIdentifier_type.toJson();
-      }
-    }
-    if (kind == idl.LinkedNodeKind.defaultFormalParameter) {
-      if (defaultFormalParameter_defaultValue != null) {
-        _result["defaultFormalParameter_defaultValue"] =
-            defaultFormalParameter_defaultValue.toJson();
-      }
-      if (defaultFormalParameter_parameter != null) {
-        _result["defaultFormalParameter_parameter"] =
-            defaultFormalParameter_parameter.toJson();
-      }
-      if (defaultFormalParameter_kind !=
-          idl.LinkedNodeFormalParameterKind.requiredPositional) {
-        _result["defaultFormalParameter_kind"] =
-            defaultFormalParameter_kind.toString().split('.')[1];
-      }
-      if (informativeId != 0) {
-        _result["informativeId"] = informativeId;
-      }
-    }
-    if (kind == idl.LinkedNodeKind.doStatement) {
-      if (doStatement_body != null) {
-        _result["doStatement_body"] = doStatement_body.toJson();
-      }
-      if (doStatement_condition != null) {
-        _result["doStatement_condition"] = doStatement_condition.toJson();
-      }
-    }
-    if (kind == idl.LinkedNodeKind.dottedName) {
-      if (dottedName_components.isNotEmpty) {
-        _result["dottedName_components"] =
-            dottedName_components.map((_value) => _value.toJson()).toList();
-      }
-    }
-    if (kind == idl.LinkedNodeKind.doubleLiteral) {
-      if (doubleLiteral_value != 0.0) {
-        _result["doubleLiteral_value"] = doubleLiteral_value.isFinite
-            ? doubleLiteral_value
-            : doubleLiteral_value.toString();
-      }
-    }
-    if (kind == idl.LinkedNodeKind.emptyFunctionBody) {
-      if (emptyFunctionBody_fake != 0) {
-        _result["emptyFunctionBody_fake"] = emptyFunctionBody_fake;
-      }
-    }
-    if (kind == idl.LinkedNodeKind.emptyStatement) {
-      if (emptyStatement_fake != 0) {
-        _result["emptyStatement_fake"] = emptyStatement_fake;
-      }
-    }
-    if (kind == idl.LinkedNodeKind.enumConstantDeclaration) {
-      if (annotatedNode_metadata.isNotEmpty) {
-        _result["annotatedNode_metadata"] =
-            annotatedNode_metadata.map((_value) => _value.toJson()).toList();
-      }
-      if (informativeId != 0) {
-        _result["informativeId"] = informativeId;
-      }
-    }
-    if (kind == idl.LinkedNodeKind.enumDeclaration) {
-      if (enumDeclaration_constants.isNotEmpty) {
-        _result["enumDeclaration_constants"] =
-            enumDeclaration_constants.map((_value) => _value.toJson()).toList();
-      }
-      if (annotatedNode_metadata.isNotEmpty) {
-        _result["annotatedNode_metadata"] =
-            annotatedNode_metadata.map((_value) => _value.toJson()).toList();
-      }
-      if (informativeId != 0) {
-        _result["informativeId"] = informativeId;
-      }
-    }
-    if (kind == idl.LinkedNodeKind.exportDirective) {
-      if (namespaceDirective_combinators.isNotEmpty) {
-        _result["namespaceDirective_combinators"] =
-            namespaceDirective_combinators
-                .map((_value) => _value.toJson())
-                .toList();
-      }
-      if (annotatedNode_metadata.isNotEmpty) {
-        _result["annotatedNode_metadata"] =
-            annotatedNode_metadata.map((_value) => _value.toJson()).toList();
-      }
-      if (namespaceDirective_configurations.isNotEmpty) {
-        _result["namespaceDirective_configurations"] =
-            namespaceDirective_configurations
-                .map((_value) => _value.toJson())
-                .toList();
-      }
-      if (namespaceDirective_selectedUri != '') {
-        _result["namespaceDirective_selectedUri"] =
-            namespaceDirective_selectedUri;
-      }
-      if (informativeId != 0) {
-        _result["informativeId"] = informativeId;
-      }
-      if (uriBasedDirective_uri != null) {
-        _result["uriBasedDirective_uri"] = uriBasedDirective_uri.toJson();
-      }
-      if (uriBasedDirective_uriContent != '') {
-        _result["uriBasedDirective_uriContent"] = uriBasedDirective_uriContent;
-      }
-      if (uriBasedDirective_uriElement != 0) {
-        _result["uriBasedDirective_uriElement"] = uriBasedDirective_uriElement;
-      }
-    }
-    if (kind == idl.LinkedNodeKind.expressionFunctionBody) {
-      if (expressionFunctionBody_expression != null) {
-        _result["expressionFunctionBody_expression"] =
-            expressionFunctionBody_expression.toJson();
-      }
-    }
-    if (kind == idl.LinkedNodeKind.expressionStatement) {
-      if (expressionStatement_expression != null) {
-        _result["expressionStatement_expression"] =
-            expressionStatement_expression.toJson();
-      }
-    }
-    if (kind == idl.LinkedNodeKind.extendsClause) {
-      if (extendsClause_superclass != null) {
-        _result["extendsClause_superclass"] = extendsClause_superclass.toJson();
-      }
-    }
-    if (kind == idl.LinkedNodeKind.extensionDeclaration) {
-      if (annotatedNode_metadata.isNotEmpty) {
-        _result["annotatedNode_metadata"] =
-            annotatedNode_metadata.map((_value) => _value.toJson()).toList();
-      }
-      if (extensionDeclaration_typeParameters != null) {
-        _result["extensionDeclaration_typeParameters"] =
-            extensionDeclaration_typeParameters.toJson();
-      }
-      if (extensionDeclaration_extendedType != null) {
-        _result["extensionDeclaration_extendedType"] =
-            extensionDeclaration_extendedType.toJson();
-      }
-      if (extensionDeclaration_members.isNotEmpty) {
-        _result["extensionDeclaration_members"] = extensionDeclaration_members
-            .map((_value) => _value.toJson())
-            .toList();
-      }
-      if (extensionDeclaration_refName != '') {
-        _result["extensionDeclaration_refName"] = extensionDeclaration_refName;
-      }
-      if (informativeId != 0) {
-        _result["informativeId"] = informativeId;
-      }
-    }
-    if (kind == idl.LinkedNodeKind.extensionOverride) {
-      if (extensionOverride_extendedType != null) {
-        _result["extensionOverride_extendedType"] =
-            extensionOverride_extendedType.toJson();
-      }
-      if (extensionOverride_arguments.isNotEmpty) {
-        _result["extensionOverride_arguments"] = extensionOverride_arguments
-            .map((_value) => _value.toJson())
-            .toList();
-      }
-      if (extensionOverride_extensionName != null) {
-        _result["extensionOverride_extensionName"] =
-            extensionOverride_extensionName.toJson();
-      }
-      if (extensionOverride_typeArguments != null) {
-        _result["extensionOverride_typeArguments"] =
-            extensionOverride_typeArguments.toJson();
-      }
-      if (extensionOverride_typeArgumentTypes.isNotEmpty) {
-        _result["extensionOverride_typeArgumentTypes"] =
-            extensionOverride_typeArgumentTypes
-                .map((_value) => _value.toJson())
-                .toList();
-      }
-    }
-    if (kind == idl.LinkedNodeKind.fieldDeclaration) {
-      if (annotatedNode_metadata.isNotEmpty) {
-        _result["annotatedNode_metadata"] =
-            annotatedNode_metadata.map((_value) => _value.toJson()).toList();
-      }
-      if (fieldDeclaration_fields != null) {
-        _result["fieldDeclaration_fields"] = fieldDeclaration_fields.toJson();
-      }
-      if (informativeId != 0) {
-        _result["informativeId"] = informativeId;
-      }
-    }
-    if (kind == idl.LinkedNodeKind.fieldFormalParameter) {
-      if (actualType != null) {
-        _result["actualType"] = actualType.toJson();
-      }
-      if (normalFormalParameter_metadata.isNotEmpty) {
-        _result["normalFormalParameter_metadata"] =
-            normalFormalParameter_metadata
-                .map((_value) => _value.toJson())
-                .toList();
-      }
-      if (fieldFormalParameter_type != null) {
-        _result["fieldFormalParameter_type"] =
-            fieldFormalParameter_type.toJson();
-      }
-      if (fieldFormalParameter_typeParameters != null) {
-        _result["fieldFormalParameter_typeParameters"] =
-            fieldFormalParameter_typeParameters.toJson();
-      }
-      if (fieldFormalParameter_formalParameters != null) {
-        _result["fieldFormalParameter_formalParameters"] =
-            fieldFormalParameter_formalParameters.toJson();
-      }
-      if (inheritsCovariant != false) {
-        _result["inheritsCovariant"] = inheritsCovariant;
-      }
-      if (informativeId != 0) {
-        _result["informativeId"] = informativeId;
-      }
-    }
-    if (kind == idl.LinkedNodeKind.forEachPartsWithDeclaration) {
-      if (forEachParts_iterable != null) {
-        _result["forEachParts_iterable"] = forEachParts_iterable.toJson();
-      }
-      if (forEachPartsWithDeclaration_loopVariable != null) {
-        _result["forEachPartsWithDeclaration_loopVariable"] =
-            forEachPartsWithDeclaration_loopVariable.toJson();
-      }
-    }
-    if (kind == idl.LinkedNodeKind.forEachPartsWithIdentifier) {
-      if (forEachParts_iterable != null) {
-        _result["forEachParts_iterable"] = forEachParts_iterable.toJson();
-      }
-      if (forEachPartsWithIdentifier_identifier != null) {
-        _result["forEachPartsWithIdentifier_identifier"] =
-            forEachPartsWithIdentifier_identifier.toJson();
-      }
-    }
-    if (kind == idl.LinkedNodeKind.forElement) {
-      if (forMixin_forLoopParts != null) {
-        _result["forMixin_forLoopParts"] = forMixin_forLoopParts.toJson();
-      }
-      if (forElement_body != null) {
-        _result["forElement_body"] = forElement_body.toJson();
-      }
-    }
-    if (kind == idl.LinkedNodeKind.forPartsWithDeclarations) {
-      if (forParts_condition != null) {
-        _result["forParts_condition"] = forParts_condition.toJson();
-      }
-      if (forPartsWithDeclarations_variables != null) {
-        _result["forPartsWithDeclarations_variables"] =
-            forPartsWithDeclarations_variables.toJson();
-      }
-      if (forParts_updaters.isNotEmpty) {
-        _result["forParts_updaters"] =
-            forParts_updaters.map((_value) => _value.toJson()).toList();
-      }
-    }
-    if (kind == idl.LinkedNodeKind.forPartsWithExpression) {
-      if (forParts_condition != null) {
-        _result["forParts_condition"] = forParts_condition.toJson();
-      }
-      if (forPartsWithExpression_initialization != null) {
-        _result["forPartsWithExpression_initialization"] =
-            forPartsWithExpression_initialization.toJson();
-      }
-      if (forParts_updaters.isNotEmpty) {
-        _result["forParts_updaters"] =
-            forParts_updaters.map((_value) => _value.toJson()).toList();
-      }
-    }
-    if (kind == idl.LinkedNodeKind.forStatement) {
-      if (forMixin_forLoopParts != null) {
-        _result["forMixin_forLoopParts"] = forMixin_forLoopParts.toJson();
-      }
-      if (forStatement_body != null) {
-        _result["forStatement_body"] = forStatement_body.toJson();
-      }
-    }
-    if (kind == idl.LinkedNodeKind.formalParameterList) {
-      if (formalParameterList_parameters.isNotEmpty) {
-        _result["formalParameterList_parameters"] =
-            formalParameterList_parameters
-                .map((_value) => _value.toJson())
-                .toList();
-      }
-    }
-    if (kind == idl.LinkedNodeKind.functionDeclaration) {
-      if (actualReturnType != null) {
-        _result["actualReturnType"] = actualReturnType.toJson();
-      }
-      if (annotatedNode_metadata.isNotEmpty) {
-        _result["annotatedNode_metadata"] =
-            annotatedNode_metadata.map((_value) => _value.toJson()).toList();
-      }
-      if (functionDeclaration_functionExpression != null) {
-        _result["functionDeclaration_functionExpression"] =
-            functionDeclaration_functionExpression.toJson();
-      }
-      if (functionDeclaration_returnType != null) {
-        _result["functionDeclaration_returnType"] =
-            functionDeclaration_returnType.toJson();
-      }
-      if (informativeId != 0) {
-        _result["informativeId"] = informativeId;
-      }
-    }
-    if (kind == idl.LinkedNodeKind.functionDeclarationStatement) {
-      if (functionDeclarationStatement_functionDeclaration != null) {
-        _result["functionDeclarationStatement_functionDeclaration"] =
-            functionDeclarationStatement_functionDeclaration.toJson();
-      }
-    }
-    if (kind == idl.LinkedNodeKind.functionExpression) {
-      if (actualReturnType != null) {
-        _result["actualReturnType"] = actualReturnType.toJson();
-      }
-      if (functionExpression_body != null) {
-        _result["functionExpression_body"] = functionExpression_body.toJson();
-      }
-      if (functionExpression_formalParameters != null) {
-        _result["functionExpression_formalParameters"] =
-            functionExpression_formalParameters.toJson();
-      }
-      if (functionExpression_typeParameters != null) {
-        _result["functionExpression_typeParameters"] =
-            functionExpression_typeParameters.toJson();
-      }
-    }
-    if (kind == idl.LinkedNodeKind.functionExpressionInvocation) {
-      if (invocationExpression_invokeType != null) {
-        _result["invocationExpression_invokeType"] =
-            invocationExpression_invokeType.toJson();
-      }
-      if (functionExpressionInvocation_function != null) {
-        _result["functionExpressionInvocation_function"] =
-            functionExpressionInvocation_function.toJson();
-      }
-      if (invocationExpression_typeArguments != null) {
-        _result["invocationExpression_typeArguments"] =
-            invocationExpression_typeArguments.toJson();
-      }
-      if (expression_type != null) {
-        _result["expression_type"] = expression_type.toJson();
-      }
-      if (invocationExpression_arguments != null) {
-        _result["invocationExpression_arguments"] =
-            invocationExpression_arguments.toJson();
-      }
-    }
-    if (kind == idl.LinkedNodeKind.functionTypeAlias) {
-      if (actualReturnType != null) {
-        _result["actualReturnType"] = actualReturnType.toJson();
-      }
-      if (annotatedNode_metadata.isNotEmpty) {
-        _result["annotatedNode_metadata"] =
-            annotatedNode_metadata.map((_value) => _value.toJson()).toList();
-      }
-      if (functionTypeAlias_formalParameters != null) {
-        _result["functionTypeAlias_formalParameters"] =
-            functionTypeAlias_formalParameters.toJson();
-      }
-      if (functionTypeAlias_returnType != null) {
-        _result["functionTypeAlias_returnType"] =
-            functionTypeAlias_returnType.toJson();
-      }
-      if (functionTypeAlias_typeParameters != null) {
-        _result["functionTypeAlias_typeParameters"] =
-            functionTypeAlias_typeParameters.toJson();
-      }
-      if (typeAlias_hasSelfReference != false) {
-        _result["typeAlias_hasSelfReference"] = typeAlias_hasSelfReference;
-      }
-      if (informativeId != 0) {
-        _result["informativeId"] = informativeId;
-      }
-      if (simplyBoundable_isSimplyBounded != false) {
-        _result["simplyBoundable_isSimplyBounded"] =
-            simplyBoundable_isSimplyBounded;
-      }
-    }
-    if (kind == idl.LinkedNodeKind.functionTypedFormalParameter) {
-      if (actualType != null) {
-        _result["actualType"] = actualType.toJson();
-      }
-      if (normalFormalParameter_metadata.isNotEmpty) {
-        _result["normalFormalParameter_metadata"] =
-            normalFormalParameter_metadata
-                .map((_value) => _value.toJson())
-                .toList();
-      }
-      if (functionTypedFormalParameter_formalParameters != null) {
-        _result["functionTypedFormalParameter_formalParameters"] =
-            functionTypedFormalParameter_formalParameters.toJson();
-      }
-      if (functionTypedFormalParameter_returnType != null) {
-        _result["functionTypedFormalParameter_returnType"] =
-            functionTypedFormalParameter_returnType.toJson();
-      }
-      if (functionTypedFormalParameter_typeParameters != null) {
-        _result["functionTypedFormalParameter_typeParameters"] =
-            functionTypedFormalParameter_typeParameters.toJson();
-      }
-      if (inheritsCovariant != false) {
-        _result["inheritsCovariant"] = inheritsCovariant;
-      }
-      if (informativeId != 0) {
-        _result["informativeId"] = informativeId;
-      }
-    }
-    if (kind == idl.LinkedNodeKind.genericFunctionType) {
-      if (actualReturnType != null) {
-        _result["actualReturnType"] = actualReturnType.toJson();
-      }
-      if (genericFunctionType_typeParameters != null) {
-        _result["genericFunctionType_typeParameters"] =
-            genericFunctionType_typeParameters.toJson();
-      }
-      if (genericFunctionType_returnType != null) {
-        _result["genericFunctionType_returnType"] =
-            genericFunctionType_returnType.toJson();
-      }
-      if (genericFunctionType_id != 0) {
-        _result["genericFunctionType_id"] = genericFunctionType_id;
-      }
-      if (genericFunctionType_formalParameters != null) {
-        _result["genericFunctionType_formalParameters"] =
-            genericFunctionType_formalParameters.toJson();
-      }
-      if (genericFunctionType_type != null) {
-        _result["genericFunctionType_type"] = genericFunctionType_type.toJson();
-      }
-    }
-    if (kind == idl.LinkedNodeKind.genericTypeAlias) {
-      if (annotatedNode_metadata.isNotEmpty) {
-        _result["annotatedNode_metadata"] =
-            annotatedNode_metadata.map((_value) => _value.toJson()).toList();
-      }
-      if (genericTypeAlias_typeParameters != null) {
-        _result["genericTypeAlias_typeParameters"] =
-            genericTypeAlias_typeParameters.toJson();
-      }
-      if (genericTypeAlias_functionType != null) {
-        _result["genericTypeAlias_functionType"] =
-            genericTypeAlias_functionType.toJson();
-      }
-      if (typeAlias_hasSelfReference != false) {
-        _result["typeAlias_hasSelfReference"] = typeAlias_hasSelfReference;
-      }
-      if (informativeId != 0) {
-        _result["informativeId"] = informativeId;
-      }
-      if (simplyBoundable_isSimplyBounded != false) {
-        _result["simplyBoundable_isSimplyBounded"] =
-            simplyBoundable_isSimplyBounded;
-      }
-    }
-    if (kind == idl.LinkedNodeKind.hideCombinator) {
-      if (informativeId != 0) {
-        _result["informativeId"] = informativeId;
-      }
-      if (names.isNotEmpty) {
-        _result["names"] = names;
-      }
-    }
-    if (kind == idl.LinkedNodeKind.ifElement) {
-      if (ifMixin_condition != null) {
-        _result["ifMixin_condition"] = ifMixin_condition.toJson();
-      }
-      if (ifElement_thenElement != null) {
-        _result["ifElement_thenElement"] = ifElement_thenElement.toJson();
-      }
-      if (ifElement_elseElement != null) {
-        _result["ifElement_elseElement"] = ifElement_elseElement.toJson();
-      }
-    }
-    if (kind == idl.LinkedNodeKind.ifStatement) {
-      if (ifMixin_condition != null) {
-        _result["ifMixin_condition"] = ifMixin_condition.toJson();
-      }
-      if (ifStatement_elseStatement != null) {
-        _result["ifStatement_elseStatement"] =
-            ifStatement_elseStatement.toJson();
-      }
-      if (ifStatement_thenStatement != null) {
-        _result["ifStatement_thenStatement"] =
-            ifStatement_thenStatement.toJson();
-      }
-    }
-    if (kind == idl.LinkedNodeKind.implementsClause) {
-      if (implementsClause_interfaces.isNotEmpty) {
-        _result["implementsClause_interfaces"] = implementsClause_interfaces
-            .map((_value) => _value.toJson())
-            .toList();
-      }
-    }
-    if (kind == idl.LinkedNodeKind.importDirective) {
-      if (namespaceDirective_combinators.isNotEmpty) {
-        _result["namespaceDirective_combinators"] =
-            namespaceDirective_combinators
-                .map((_value) => _value.toJson())
-                .toList();
-      }
-      if (annotatedNode_metadata.isNotEmpty) {
-        _result["annotatedNode_metadata"] =
-            annotatedNode_metadata.map((_value) => _value.toJson()).toList();
-      }
-      if (namespaceDirective_configurations.isNotEmpty) {
-        _result["namespaceDirective_configurations"] =
-            namespaceDirective_configurations
-                .map((_value) => _value.toJson())
-                .toList();
-      }
-      if (namespaceDirective_selectedUri != '') {
-        _result["namespaceDirective_selectedUri"] =
-            namespaceDirective_selectedUri;
-      }
-      if (importDirective_prefix != '') {
-        _result["importDirective_prefix"] = importDirective_prefix;
-      }
-      if (informativeId != 0) {
-        _result["informativeId"] = informativeId;
-      }
-      if (uriBasedDirective_uri != null) {
-        _result["uriBasedDirective_uri"] = uriBasedDirective_uri.toJson();
-      }
-      if (uriBasedDirective_uriContent != '') {
-        _result["uriBasedDirective_uriContent"] = uriBasedDirective_uriContent;
-      }
-      if (uriBasedDirective_uriElement != 0) {
-        _result["uriBasedDirective_uriElement"] = uriBasedDirective_uriElement;
-      }
-    }
-    if (kind == idl.LinkedNodeKind.indexExpression) {
-      if (indexExpression_index != null) {
-        _result["indexExpression_index"] = indexExpression_index.toJson();
-      }
-      if (indexExpression_target != null) {
-        _result["indexExpression_target"] = indexExpression_target.toJson();
-      }
-      if (indexExpression_substitution != null) {
-        _result["indexExpression_substitution"] =
-            indexExpression_substitution.toJson();
-      }
-      if (indexExpression_element != 0) {
-        _result["indexExpression_element"] = indexExpression_element;
-      }
-      if (expression_type != null) {
-        _result["expression_type"] = expression_type.toJson();
-      }
-    }
-    if (kind == idl.LinkedNodeKind.instanceCreationExpression) {
-      if (instanceCreationExpression_arguments.isNotEmpty) {
-        _result["instanceCreationExpression_arguments"] =
-            instanceCreationExpression_arguments
-                .map((_value) => _value.toJson())
-                .toList();
-      }
-      if (instanceCreationExpression_constructorName != null) {
-        _result["instanceCreationExpression_constructorName"] =
-            instanceCreationExpression_constructorName.toJson();
-      }
-      if (instanceCreationExpression_typeArguments != null) {
-        _result["instanceCreationExpression_typeArguments"] =
-            instanceCreationExpression_typeArguments.toJson();
-      }
-      if (expression_type != null) {
-        _result["expression_type"] = expression_type.toJson();
-      }
-    }
-    if (kind == idl.LinkedNodeKind.integerLiteral) {
-      if (expression_type != null) {
-        _result["expression_type"] = expression_type.toJson();
-      }
-      if (integerLiteral_value != 0) {
-        _result["integerLiteral_value"] = integerLiteral_value;
-      }
-    }
-    if (kind == idl.LinkedNodeKind.interpolationExpression) {
-      if (interpolationExpression_expression != null) {
-        _result["interpolationExpression_expression"] =
-            interpolationExpression_expression.toJson();
-      }
-    }
-    if (kind == idl.LinkedNodeKind.interpolationString) {
-      if (interpolationString_value != '') {
-        _result["interpolationString_value"] = interpolationString_value;
-      }
-    }
-    if (kind == idl.LinkedNodeKind.isExpression) {
-      if (isExpression_expression != null) {
-        _result["isExpression_expression"] = isExpression_expression.toJson();
-      }
-      if (isExpression_type != null) {
-        _result["isExpression_type"] = isExpression_type.toJson();
-      }
-    }
-    if (kind == idl.LinkedNodeKind.label) {
-      if (label_label != null) {
-        _result["label_label"] = label_label.toJson();
-      }
-    }
-    if (kind == idl.LinkedNodeKind.labeledStatement) {
-      if (labeledStatement_labels.isNotEmpty) {
-        _result["labeledStatement_labels"] =
-            labeledStatement_labels.map((_value) => _value.toJson()).toList();
-      }
-      if (labeledStatement_statement != null) {
-        _result["labeledStatement_statement"] =
-            labeledStatement_statement.toJson();
-      }
-    }
-    if (kind == idl.LinkedNodeKind.libraryDirective) {
-      if (annotatedNode_metadata.isNotEmpty) {
-        _result["annotatedNode_metadata"] =
-            annotatedNode_metadata.map((_value) => _value.toJson()).toList();
-      }
-      if (libraryDirective_name != null) {
-        _result["libraryDirective_name"] = libraryDirective_name.toJson();
-      }
-      if (informativeId != 0) {
-        _result["informativeId"] = informativeId;
-      }
-    }
-    if (kind == idl.LinkedNodeKind.libraryIdentifier) {
-      if (libraryIdentifier_components.isNotEmpty) {
-        _result["libraryIdentifier_components"] = libraryIdentifier_components
-            .map((_value) => _value.toJson())
-            .toList();
-      }
-    }
-    if (kind == idl.LinkedNodeKind.listLiteral) {
-      if (typedLiteral_typeArguments.isNotEmpty) {
-        _result["typedLiteral_typeArguments"] = typedLiteral_typeArguments
-            .map((_value) => _value.toJson())
-            .toList();
-      }
-      if (listLiteral_elements.isNotEmpty) {
-        _result["listLiteral_elements"] =
-            listLiteral_elements.map((_value) => _value.toJson()).toList();
-      }
-      if (expression_type != null) {
-        _result["expression_type"] = expression_type.toJson();
-      }
-    }
-    if (kind == idl.LinkedNodeKind.mapLiteralEntry) {
-      if (mapLiteralEntry_key != null) {
-        _result["mapLiteralEntry_key"] = mapLiteralEntry_key.toJson();
-      }
-      if (mapLiteralEntry_value != null) {
-        _result["mapLiteralEntry_value"] = mapLiteralEntry_value.toJson();
-      }
-    }
-    if (kind == idl.LinkedNodeKind.methodDeclaration) {
-      if (actualReturnType != null) {
-        _result["actualReturnType"] = actualReturnType.toJson();
-      }
-      if (annotatedNode_metadata.isNotEmpty) {
-        _result["annotatedNode_metadata"] =
-            annotatedNode_metadata.map((_value) => _value.toJson()).toList();
-      }
-      if (methodDeclaration_body != null) {
-        _result["methodDeclaration_body"] = methodDeclaration_body.toJson();
-      }
-      if (methodDeclaration_formalParameters != null) {
-        _result["methodDeclaration_formalParameters"] =
-            methodDeclaration_formalParameters.toJson();
-      }
-      if (methodDeclaration_returnType != null) {
-        _result["methodDeclaration_returnType"] =
-            methodDeclaration_returnType.toJson();
-      }
-      if (methodDeclaration_typeParameters != null) {
-        _result["methodDeclaration_typeParameters"] =
-            methodDeclaration_typeParameters.toJson();
-      }
-      if (informativeId != 0) {
-        _result["informativeId"] = informativeId;
-      }
-      if (methodDeclaration_hasOperatorEqualWithParameterTypeFromObject !=
-          false) {
-        _result["methodDeclaration_hasOperatorEqualWithParameterTypeFromObject"] =
-            methodDeclaration_hasOperatorEqualWithParameterTypeFromObject;
-      }
-      if (topLevelTypeInferenceError != null) {
-        _result["topLevelTypeInferenceError"] =
-            topLevelTypeInferenceError.toJson();
-      }
-    }
-    if (kind == idl.LinkedNodeKind.methodInvocation) {
-      if (invocationExpression_invokeType != null) {
-        _result["invocationExpression_invokeType"] =
-            invocationExpression_invokeType.toJson();
-      }
-      if (methodInvocation_methodName != null) {
-        _result["methodInvocation_methodName"] =
-            methodInvocation_methodName.toJson();
-      }
-      if (methodInvocation_target != null) {
-        _result["methodInvocation_target"] = methodInvocation_target.toJson();
-      }
-      if (invocationExpression_typeArguments != null) {
-        _result["invocationExpression_typeArguments"] =
-            invocationExpression_typeArguments.toJson();
-      }
-      if (expression_type != null) {
-        _result["expression_type"] = expression_type.toJson();
-      }
-      if (invocationExpression_arguments != null) {
-        _result["invocationExpression_arguments"] =
-            invocationExpression_arguments.toJson();
-      }
-    }
-    if (kind == idl.LinkedNodeKind.mixinDeclaration) {
-      if (annotatedNode_metadata.isNotEmpty) {
-        _result["annotatedNode_metadata"] =
-            annotatedNode_metadata.map((_value) => _value.toJson()).toList();
-      }
-      if (mixinDeclaration_onClause != null) {
-        _result["mixinDeclaration_onClause"] =
-            mixinDeclaration_onClause.toJson();
-      }
-      if (classOrMixinDeclaration_implementsClause != null) {
-        _result["classOrMixinDeclaration_implementsClause"] =
-            classOrMixinDeclaration_implementsClause.toJson();
-      }
-      if (classOrMixinDeclaration_members.isNotEmpty) {
-        _result["classOrMixinDeclaration_members"] =
-            classOrMixinDeclaration_members
-                .map((_value) => _value.toJson())
-                .toList();
-      }
-      if (classOrMixinDeclaration_typeParameters != null) {
-        _result["classOrMixinDeclaration_typeParameters"] =
-            classOrMixinDeclaration_typeParameters.toJson();
-      }
-      if (informativeId != 0) {
-        _result["informativeId"] = informativeId;
-      }
-      if (simplyBoundable_isSimplyBounded != false) {
-        _result["simplyBoundable_isSimplyBounded"] =
-            simplyBoundable_isSimplyBounded;
-      }
-      if (mixinDeclaration_superInvokedNames.isNotEmpty) {
-        _result["mixinDeclaration_superInvokedNames"] =
-            mixinDeclaration_superInvokedNames;
-      }
-    }
-    if (kind == idl.LinkedNodeKind.namedExpression) {
-      if (namedExpression_expression != null) {
-        _result["namedExpression_expression"] =
-            namedExpression_expression.toJson();
-      }
-      if (namedExpression_name != null) {
-        _result["namedExpression_name"] = namedExpression_name.toJson();
-      }
-    }
-    if (kind == idl.LinkedNodeKind.nativeClause) {
-      if (nativeClause_name != null) {
-        _result["nativeClause_name"] = nativeClause_name.toJson();
-      }
-    }
-    if (kind == idl.LinkedNodeKind.nativeFunctionBody) {
-      if (nativeFunctionBody_stringLiteral != null) {
-        _result["nativeFunctionBody_stringLiteral"] =
-            nativeFunctionBody_stringLiteral.toJson();
-      }
-    }
-    if (kind == idl.LinkedNodeKind.nullLiteral) {
-      if (nullLiteral_fake != 0) {
-        _result["nullLiteral_fake"] = nullLiteral_fake;
-      }
-      if (expression_type != null) {
-        _result["expression_type"] = expression_type.toJson();
-      }
-    }
-    if (kind == idl.LinkedNodeKind.onClause) {
-      if (onClause_superclassConstraints.isNotEmpty) {
-        _result["onClause_superclassConstraints"] =
-            onClause_superclassConstraints
-                .map((_value) => _value.toJson())
-                .toList();
-      }
-    }
-    if (kind == idl.LinkedNodeKind.parenthesizedExpression) {
-      if (parenthesizedExpression_expression != null) {
-        _result["parenthesizedExpression_expression"] =
-            parenthesizedExpression_expression.toJson();
-      }
-      if (expression_type != null) {
-        _result["expression_type"] = expression_type.toJson();
-      }
-    }
-    if (kind == idl.LinkedNodeKind.partDirective) {
-      if (annotatedNode_metadata.isNotEmpty) {
-        _result["annotatedNode_metadata"] =
-            annotatedNode_metadata.map((_value) => _value.toJson()).toList();
-      }
-      if (informativeId != 0) {
-        _result["informativeId"] = informativeId;
-      }
-      if (uriBasedDirective_uri != null) {
-        _result["uriBasedDirective_uri"] = uriBasedDirective_uri.toJson();
-      }
-      if (uriBasedDirective_uriContent != '') {
-        _result["uriBasedDirective_uriContent"] = uriBasedDirective_uriContent;
-      }
-      if (uriBasedDirective_uriElement != 0) {
-        _result["uriBasedDirective_uriElement"] = uriBasedDirective_uriElement;
-      }
-    }
-    if (kind == idl.LinkedNodeKind.partOfDirective) {
-      if (annotatedNode_metadata.isNotEmpty) {
-        _result["annotatedNode_metadata"] =
-            annotatedNode_metadata.map((_value) => _value.toJson()).toList();
-      }
-      if (partOfDirective_libraryName != null) {
-        _result["partOfDirective_libraryName"] =
-            partOfDirective_libraryName.toJson();
-      }
-      if (partOfDirective_uri != null) {
-        _result["partOfDirective_uri"] = partOfDirective_uri.toJson();
-      }
-      if (informativeId != 0) {
-        _result["informativeId"] = informativeId;
-      }
-    }
-    if (kind == idl.LinkedNodeKind.postfixExpression) {
-      if (postfixExpression_operand != null) {
-        _result["postfixExpression_operand"] =
-            postfixExpression_operand.toJson();
-      }
-      if (postfixExpression_substitution != null) {
-        _result["postfixExpression_substitution"] =
-            postfixExpression_substitution.toJson();
-      }
-      if (postfixExpression_element != 0) {
-        _result["postfixExpression_element"] = postfixExpression_element;
-      }
-      if (postfixExpression_operator != idl.UnlinkedTokenType.NOTHING) {
-        _result["postfixExpression_operator"] =
-            postfixExpression_operator.toString().split('.')[1];
-      }
-      if (expression_type != null) {
-        _result["expression_type"] = expression_type.toJson();
-      }
-    }
-    if (kind == idl.LinkedNodeKind.prefixExpression) {
-      if (prefixExpression_operand != null) {
-        _result["prefixExpression_operand"] = prefixExpression_operand.toJson();
-      }
-      if (prefixExpression_substitution != null) {
-        _result["prefixExpression_substitution"] =
-            prefixExpression_substitution.toJson();
-      }
-      if (prefixExpression_element != 0) {
-        _result["prefixExpression_element"] = prefixExpression_element;
-      }
-      if (prefixExpression_operator != idl.UnlinkedTokenType.NOTHING) {
-        _result["prefixExpression_operator"] =
-            prefixExpression_operator.toString().split('.')[1];
-      }
-      if (expression_type != null) {
-        _result["expression_type"] = expression_type.toJson();
-      }
-    }
-    if (kind == idl.LinkedNodeKind.prefixedIdentifier) {
-      if (prefixedIdentifier_identifier != null) {
-        _result["prefixedIdentifier_identifier"] =
-            prefixedIdentifier_identifier.toJson();
-      }
-      if (prefixedIdentifier_prefix != null) {
-        _result["prefixedIdentifier_prefix"] =
-            prefixedIdentifier_prefix.toJson();
-      }
-      if (expression_type != null) {
-        _result["expression_type"] = expression_type.toJson();
-      }
-    }
-    if (kind == idl.LinkedNodeKind.propertyAccess) {
-      if (propertyAccess_propertyName != null) {
-        _result["propertyAccess_propertyName"] =
-            propertyAccess_propertyName.toJson();
-      }
-      if (propertyAccess_target != null) {
-        _result["propertyAccess_target"] = propertyAccess_target.toJson();
-      }
-      if (propertyAccess_operator != idl.UnlinkedTokenType.NOTHING) {
-        _result["propertyAccess_operator"] =
-            propertyAccess_operator.toString().split('.')[1];
-      }
-      if (expression_type != null) {
-        _result["expression_type"] = expression_type.toJson();
-      }
-    }
-    if (kind == idl.LinkedNodeKind.redirectingConstructorInvocation) {
-      if (redirectingConstructorInvocation_arguments != null) {
-        _result["redirectingConstructorInvocation_arguments"] =
-            redirectingConstructorInvocation_arguments.toJson();
-      }
-      if (redirectingConstructorInvocation_constructorName != null) {
-        _result["redirectingConstructorInvocation_constructorName"] =
-            redirectingConstructorInvocation_constructorName.toJson();
-      }
-      if (redirectingConstructorInvocation_substitution != null) {
-        _result["redirectingConstructorInvocation_substitution"] =
-            redirectingConstructorInvocation_substitution.toJson();
-      }
-      if (redirectingConstructorInvocation_element != 0) {
-        _result["redirectingConstructorInvocation_element"] =
-            redirectingConstructorInvocation_element;
-      }
-    }
-    if (kind == idl.LinkedNodeKind.rethrowExpression) {
-      if (expression_type != null) {
-        _result["expression_type"] = expression_type.toJson();
-      }
-    }
-    if (kind == idl.LinkedNodeKind.returnStatement) {
-      if (returnStatement_expression != null) {
-        _result["returnStatement_expression"] =
-            returnStatement_expression.toJson();
-      }
-    }
-    if (kind == idl.LinkedNodeKind.setOrMapLiteral) {
-      if (typedLiteral_typeArguments.isNotEmpty) {
-        _result["typedLiteral_typeArguments"] = typedLiteral_typeArguments
-            .map((_value) => _value.toJson())
-            .toList();
-      }
-      if (setOrMapLiteral_elements.isNotEmpty) {
-        _result["setOrMapLiteral_elements"] =
-            setOrMapLiteral_elements.map((_value) => _value.toJson()).toList();
-      }
-      if (expression_type != null) {
-        _result["expression_type"] = expression_type.toJson();
-      }
-    }
-    if (kind == idl.LinkedNodeKind.showCombinator) {
-      if (informativeId != 0) {
-        _result["informativeId"] = informativeId;
-      }
-      if (names.isNotEmpty) {
-        _result["names"] = names;
-      }
-    }
-    if (kind == idl.LinkedNodeKind.simpleFormalParameter) {
-      if (actualType != null) {
-        _result["actualType"] = actualType.toJson();
-      }
-      if (normalFormalParameter_metadata.isNotEmpty) {
-        _result["normalFormalParameter_metadata"] =
-            normalFormalParameter_metadata
-                .map((_value) => _value.toJson())
-                .toList();
-      }
-      if (simpleFormalParameter_type != null) {
-        _result["simpleFormalParameter_type"] =
-            simpleFormalParameter_type.toJson();
-      }
-      if (inheritsCovariant != false) {
-        _result["inheritsCovariant"] = inheritsCovariant;
-      }
-      if (informativeId != 0) {
-        _result["informativeId"] = informativeId;
-      }
-      if (topLevelTypeInferenceError != null) {
-        _result["topLevelTypeInferenceError"] =
-            topLevelTypeInferenceError.toJson();
-      }
-    }
-    if (kind == idl.LinkedNodeKind.simpleIdentifier) {
-      if (simpleIdentifier_substitution != null) {
-        _result["simpleIdentifier_substitution"] =
-            simpleIdentifier_substitution.toJson();
-      }
-      if (simpleIdentifier_element != 0) {
-        _result["simpleIdentifier_element"] = simpleIdentifier_element;
-      }
-      if (expression_type != null) {
-        _result["expression_type"] = expression_type.toJson();
-      }
-    }
-    if (kind == idl.LinkedNodeKind.simpleStringLiteral) {
-      if (simpleStringLiteral_value != '') {
-        _result["simpleStringLiteral_value"] = simpleStringLiteral_value;
-      }
-    }
-    if (kind == idl.LinkedNodeKind.spreadElement) {
-      if (spreadElement_expression != null) {
-        _result["spreadElement_expression"] = spreadElement_expression.toJson();
-      }
-      if (spreadElement_spreadOperator != idl.UnlinkedTokenType.NOTHING) {
-        _result["spreadElement_spreadOperator"] =
-            spreadElement_spreadOperator.toString().split('.')[1];
-      }
-    }
-    if (kind == idl.LinkedNodeKind.stringInterpolation) {
-      if (stringInterpolation_elements.isNotEmpty) {
-        _result["stringInterpolation_elements"] = stringInterpolation_elements
-            .map((_value) => _value.toJson())
-            .toList();
-      }
-    }
-    if (kind == idl.LinkedNodeKind.superConstructorInvocation) {
-      if (superConstructorInvocation_arguments != null) {
-        _result["superConstructorInvocation_arguments"] =
-            superConstructorInvocation_arguments.toJson();
-      }
-      if (superConstructorInvocation_constructorName != null) {
-        _result["superConstructorInvocation_constructorName"] =
-            superConstructorInvocation_constructorName.toJson();
-      }
-      if (superConstructorInvocation_substitution != null) {
-        _result["superConstructorInvocation_substitution"] =
-            superConstructorInvocation_substitution.toJson();
-      }
-      if (superConstructorInvocation_element != 0) {
-        _result["superConstructorInvocation_element"] =
-            superConstructorInvocation_element;
-      }
-    }
-    if (kind == idl.LinkedNodeKind.superExpression) {
-      if (expression_type != null) {
-        _result["expression_type"] = expression_type.toJson();
-      }
-    }
-    if (kind == idl.LinkedNodeKind.switchCase) {
-      if (switchMember_statements.isNotEmpty) {
-        _result["switchMember_statements"] =
-            switchMember_statements.map((_value) => _value.toJson()).toList();
-      }
-      if (switchCase_expression != null) {
-        _result["switchCase_expression"] = switchCase_expression.toJson();
-      }
-      if (switchMember_labels.isNotEmpty) {
-        _result["switchMember_labels"] =
-            switchMember_labels.map((_value) => _value.toJson()).toList();
-      }
-    }
-    if (kind == idl.LinkedNodeKind.switchDefault) {
-      if (switchMember_statements.isNotEmpty) {
-        _result["switchMember_statements"] =
-            switchMember_statements.map((_value) => _value.toJson()).toList();
-      }
-      if (switchMember_labels.isNotEmpty) {
-        _result["switchMember_labels"] =
-            switchMember_labels.map((_value) => _value.toJson()).toList();
-      }
-    }
-    if (kind == idl.LinkedNodeKind.switchStatement) {
-      if (switchStatement_members.isNotEmpty) {
-        _result["switchStatement_members"] =
-            switchStatement_members.map((_value) => _value.toJson()).toList();
-      }
-      if (switchStatement_expression != null) {
-        _result["switchStatement_expression"] =
-            switchStatement_expression.toJson();
-      }
-    }
-    if (kind == idl.LinkedNodeKind.symbolLiteral) {
-      if (expression_type != null) {
-        _result["expression_type"] = expression_type.toJson();
-      }
-      if (names.isNotEmpty) {
-        _result["names"] = names;
-      }
-    }
-    if (kind == idl.LinkedNodeKind.thisExpression) {
-      if (expression_type != null) {
-        _result["expression_type"] = expression_type.toJson();
-      }
-    }
-    if (kind == idl.LinkedNodeKind.throwExpression) {
-      if (throwExpression_expression != null) {
-        _result["throwExpression_expression"] =
-            throwExpression_expression.toJson();
-      }
-      if (expression_type != null) {
-        _result["expression_type"] = expression_type.toJson();
-      }
-    }
-    if (kind == idl.LinkedNodeKind.topLevelVariableDeclaration) {
-      if (annotatedNode_metadata.isNotEmpty) {
-        _result["annotatedNode_metadata"] =
-            annotatedNode_metadata.map((_value) => _value.toJson()).toList();
-      }
-      if (topLevelVariableDeclaration_variableList != null) {
-        _result["topLevelVariableDeclaration_variableList"] =
-            topLevelVariableDeclaration_variableList.toJson();
-      }
-      if (informativeId != 0) {
-        _result["informativeId"] = informativeId;
-      }
-    }
-    if (kind == idl.LinkedNodeKind.tryStatement) {
-      if (tryStatement_catchClauses.isNotEmpty) {
-        _result["tryStatement_catchClauses"] =
-            tryStatement_catchClauses.map((_value) => _value.toJson()).toList();
-      }
-      if (tryStatement_body != null) {
-        _result["tryStatement_body"] = tryStatement_body.toJson();
-      }
-      if (tryStatement_finallyBlock != null) {
-        _result["tryStatement_finallyBlock"] =
-            tryStatement_finallyBlock.toJson();
-      }
-    }
-    if (kind == idl.LinkedNodeKind.typeArgumentList) {
-      if (typeArgumentList_arguments.isNotEmpty) {
-        _result["typeArgumentList_arguments"] = typeArgumentList_arguments
-            .map((_value) => _value.toJson())
-            .toList();
-      }
-    }
-    if (kind == idl.LinkedNodeKind.typeName) {
-      if (typeName_typeArguments.isNotEmpty) {
-        _result["typeName_typeArguments"] =
-            typeName_typeArguments.map((_value) => _value.toJson()).toList();
-      }
-      if (typeName_name != null) {
-        _result["typeName_name"] = typeName_name.toJson();
-      }
-      if (typeName_type != null) {
-        _result["typeName_type"] = typeName_type.toJson();
-      }
-    }
-    if (kind == idl.LinkedNodeKind.typeParameter) {
-      if (annotatedNode_metadata.isNotEmpty) {
-        _result["annotatedNode_metadata"] =
-            annotatedNode_metadata.map((_value) => _value.toJson()).toList();
-      }
-      if (typeParameter_bound != null) {
-        _result["typeParameter_bound"] = typeParameter_bound.toJson();
-      }
-      if (typeParameter_variance != 0) {
-        _result["typeParameter_variance"] = typeParameter_variance;
-      }
-      if (informativeId != 0) {
-        _result["informativeId"] = informativeId;
-      }
-      if (typeParameter_defaultType != null) {
-        _result["typeParameter_defaultType"] =
-            typeParameter_defaultType.toJson();
-      }
-    }
-    if (kind == idl.LinkedNodeKind.typeParameterList) {
-      if (typeParameterList_typeParameters.isNotEmpty) {
-        _result["typeParameterList_typeParameters"] =
-            typeParameterList_typeParameters
-                .map((_value) => _value.toJson())
-                .toList();
-      }
-    }
-    if (kind == idl.LinkedNodeKind.variableDeclaration) {
-      if (actualType != null) {
-        _result["actualType"] = actualType.toJson();
-      }
-      if (annotatedNode_metadata.isNotEmpty) {
-        _result["annotatedNode_metadata"] =
-            annotatedNode_metadata.map((_value) => _value.toJson()).toList();
-      }
-      if (variableDeclaration_initializer != null) {
-        _result["variableDeclaration_initializer"] =
-            variableDeclaration_initializer.toJson();
-      }
-      if (inheritsCovariant != false) {
-        _result["inheritsCovariant"] = inheritsCovariant;
-      }
-      if (informativeId != 0) {
-        _result["informativeId"] = informativeId;
-      }
-      if (topLevelTypeInferenceError != null) {
-        _result["topLevelTypeInferenceError"] =
-            topLevelTypeInferenceError.toJson();
-      }
-    }
-    if (kind == idl.LinkedNodeKind.variableDeclarationList) {
-      if (variableDeclarationList_variables.isNotEmpty) {
-        _result["variableDeclarationList_variables"] =
-            variableDeclarationList_variables
-                .map((_value) => _value.toJson())
-                .toList();
-      }
-      if (annotatedNode_metadata.isNotEmpty) {
-        _result["annotatedNode_metadata"] =
-            annotatedNode_metadata.map((_value) => _value.toJson()).toList();
-      }
-      if (variableDeclarationList_type != null) {
-        _result["variableDeclarationList_type"] =
-            variableDeclarationList_type.toJson();
-      }
-      if (informativeId != 0) {
-        _result["informativeId"] = informativeId;
-      }
-    }
-    if (kind == idl.LinkedNodeKind.variableDeclarationStatement) {
-      if (variableDeclarationStatement_variables != null) {
-        _result["variableDeclarationStatement_variables"] =
-            variableDeclarationStatement_variables.toJson();
-      }
-    }
-    if (kind == idl.LinkedNodeKind.whileStatement) {
-      if (whileStatement_body != null) {
-        _result["whileStatement_body"] = whileStatement_body.toJson();
-      }
-      if (whileStatement_condition != null) {
-        _result["whileStatement_condition"] = whileStatement_condition.toJson();
-      }
-    }
-    if (kind == idl.LinkedNodeKind.withClause) {
-      if (withClause_mixinTypes.isNotEmpty) {
-        _result["withClause_mixinTypes"] =
-            withClause_mixinTypes.map((_value) => _value.toJson()).toList();
-      }
-    }
-    if (kind == idl.LinkedNodeKind.yieldStatement) {
-      if (yieldStatement_expression != null) {
-        _result["yieldStatement_expression"] =
-            yieldStatement_expression.toJson();
-      }
-    }
-    return _result;
-  }
-
-  @override
-  Map<String, Object> toMap() {
-    if (kind == idl.LinkedNodeKind.adjacentStrings) {
-      return {
-        "adjacentStrings_strings": adjacentStrings_strings,
-        "flags": flags,
-        "kind": kind,
-        "name": name,
-      };
-    }
-    if (kind == idl.LinkedNodeKind.annotation) {
-      return {
-        "annotation_arguments": annotation_arguments,
-        "annotation_constructorName": annotation_constructorName,
-        "annotation_element": annotation_element,
-        "annotation_name": annotation_name,
-        "annotation_substitution": annotation_substitution,
-        "flags": flags,
-        "kind": kind,
-        "name": name,
-      };
-    }
-    if (kind == idl.LinkedNodeKind.argumentList) {
-      return {
-        "argumentList_arguments": argumentList_arguments,
-        "flags": flags,
-        "kind": kind,
-        "name": name,
-      };
-    }
-    if (kind == idl.LinkedNodeKind.asExpression) {
-      return {
-        "asExpression_expression": asExpression_expression,
-        "asExpression_type": asExpression_type,
-        "expression_type": expression_type,
-        "flags": flags,
-        "kind": kind,
-        "name": name,
-      };
-    }
-    if (kind == idl.LinkedNodeKind.assertInitializer) {
-      return {
-        "assertInitializer_condition": assertInitializer_condition,
-        "assertInitializer_message": assertInitializer_message,
-        "flags": flags,
-        "kind": kind,
-        "name": name,
-      };
-    }
-    if (kind == idl.LinkedNodeKind.assertStatement) {
-      return {
-        "assertStatement_condition": assertStatement_condition,
-        "assertStatement_message": assertStatement_message,
-        "flags": flags,
-        "kind": kind,
-        "name": name,
-      };
-    }
-    if (kind == idl.LinkedNodeKind.assignmentExpression) {
-      return {
-        "assignmentExpression_leftHandSide": assignmentExpression_leftHandSide,
-        "assignmentExpression_rightHandSide":
-            assignmentExpression_rightHandSide,
-        "assignmentExpression_substitution": assignmentExpression_substitution,
-        "assignmentExpression_element": assignmentExpression_element,
-        "assignmentExpression_operator": assignmentExpression_operator,
-        "expression_type": expression_type,
-        "flags": flags,
-        "kind": kind,
-        "name": name,
-      };
-    }
-    if (kind == idl.LinkedNodeKind.awaitExpression) {
-      return {
-        "awaitExpression_expression": awaitExpression_expression,
-        "expression_type": expression_type,
-        "flags": flags,
-        "kind": kind,
-        "name": name,
-      };
-    }
-    if (kind == idl.LinkedNodeKind.binaryExpression) {
-      return {
-        "binaryExpression_invokeType": binaryExpression_invokeType,
-        "binaryExpression_leftOperand": binaryExpression_leftOperand,
-        "binaryExpression_rightOperand": binaryExpression_rightOperand,
-        "binaryExpression_substitution": binaryExpression_substitution,
-        "binaryExpression_element": binaryExpression_element,
-        "binaryExpression_operator": binaryExpression_operator,
-        "expression_type": expression_type,
-        "flags": flags,
-        "kind": kind,
-        "name": name,
-      };
-    }
-    if (kind == idl.LinkedNodeKind.block) {
-      return {
-        "block_statements": block_statements,
-        "flags": flags,
-        "kind": kind,
-        "name": name,
-      };
-    }
-    if (kind == idl.LinkedNodeKind.blockFunctionBody) {
-      return {
-        "blockFunctionBody_block": blockFunctionBody_block,
-        "flags": flags,
-        "kind": kind,
-        "name": name,
-      };
-    }
-    if (kind == idl.LinkedNodeKind.booleanLiteral) {
-      return {
-        "booleanLiteral_value": booleanLiteral_value,
-        "flags": flags,
-        "kind": kind,
-        "name": name,
-      };
-    }
-    if (kind == idl.LinkedNodeKind.breakStatement) {
-      return {
-        "breakStatement_label": breakStatement_label,
-        "flags": flags,
-        "kind": kind,
-        "name": name,
-      };
-    }
-    if (kind == idl.LinkedNodeKind.cascadeExpression) {
-      return {
-        "cascadeExpression_sections": cascadeExpression_sections,
-        "cascadeExpression_target": cascadeExpression_target,
-        "expression_type": expression_type,
-        "flags": flags,
-        "kind": kind,
-        "name": name,
-      };
-    }
-    if (kind == idl.LinkedNodeKind.catchClause) {
-      return {
-        "catchClause_body": catchClause_body,
-        "catchClause_exceptionParameter": catchClause_exceptionParameter,
-        "catchClause_exceptionType": catchClause_exceptionType,
-        "catchClause_stackTraceParameter": catchClause_stackTraceParameter,
-        "flags": flags,
-        "kind": kind,
-        "name": name,
-      };
-    }
-    if (kind == idl.LinkedNodeKind.classDeclaration) {
-      return {
-        "annotatedNode_metadata": annotatedNode_metadata,
-        "classDeclaration_extendsClause": classDeclaration_extendsClause,
-        "classDeclaration_withClause": classDeclaration_withClause,
-        "classDeclaration_nativeClause": classDeclaration_nativeClause,
-        "classDeclaration_isDartObject": classDeclaration_isDartObject,
-        "classOrMixinDeclaration_implementsClause":
-            classOrMixinDeclaration_implementsClause,
-        "classOrMixinDeclaration_members": classOrMixinDeclaration_members,
-        "classOrMixinDeclaration_typeParameters":
-            classOrMixinDeclaration_typeParameters,
-        "flags": flags,
-        "informativeId": informativeId,
-        "kind": kind,
-        "simplyBoundable_isSimplyBounded": simplyBoundable_isSimplyBounded,
-        "name": name,
-        "unused11": unused11,
-      };
-    }
-    if (kind == idl.LinkedNodeKind.classTypeAlias) {
-      return {
-        "annotatedNode_metadata": annotatedNode_metadata,
-        "classTypeAlias_typeParameters": classTypeAlias_typeParameters,
-        "classTypeAlias_superclass": classTypeAlias_superclass,
-        "classTypeAlias_withClause": classTypeAlias_withClause,
-        "classTypeAlias_implementsClause": classTypeAlias_implementsClause,
-        "flags": flags,
-        "informativeId": informativeId,
-        "kind": kind,
-        "simplyBoundable_isSimplyBounded": simplyBoundable_isSimplyBounded,
-        "name": name,
-      };
-    }
-    if (kind == idl.LinkedNodeKind.comment) {
-      return {
-        "comment_references": comment_references,
-        "comment_tokens": comment_tokens,
-        "comment_type": comment_type,
-        "flags": flags,
-        "kind": kind,
-        "name": name,
-      };
-    }
-    if (kind == idl.LinkedNodeKind.commentReference) {
-      return {
-        "commentReference_identifier": commentReference_identifier,
-        "flags": flags,
-        "kind": kind,
-        "name": name,
-      };
-    }
-    if (kind == idl.LinkedNodeKind.compilationUnit) {
-      return {
-        "compilationUnit_declarations": compilationUnit_declarations,
-        "compilationUnit_scriptTag": compilationUnit_scriptTag,
-        "compilationUnit_directives": compilationUnit_directives,
-        "compilationUnit_featureSet": compilationUnit_featureSet,
-        "compilationUnit_languageVersion": compilationUnit_languageVersion,
-        "flags": flags,
-        "informativeId": informativeId,
-        "kind": kind,
-        "name": name,
-      };
-    }
-    if (kind == idl.LinkedNodeKind.conditionalExpression) {
-      return {
-        "conditionalExpression_condition": conditionalExpression_condition,
-        "conditionalExpression_elseExpression":
-            conditionalExpression_elseExpression,
-        "conditionalExpression_thenExpression":
-            conditionalExpression_thenExpression,
-        "expression_type": expression_type,
-        "flags": flags,
-        "kind": kind,
-        "name": name,
-      };
-    }
-    if (kind == idl.LinkedNodeKind.configuration) {
-      return {
-        "configuration_name": configuration_name,
-        "configuration_value": configuration_value,
-        "configuration_uri": configuration_uri,
-        "flags": flags,
-        "kind": kind,
-        "name": name,
-      };
-    }
-    if (kind == idl.LinkedNodeKind.constructorDeclaration) {
-      return {
-        "constructorDeclaration_initializers":
-            constructorDeclaration_initializers,
-        "annotatedNode_metadata": annotatedNode_metadata,
-        "constructorDeclaration_body": constructorDeclaration_body,
-        "constructorDeclaration_parameters": constructorDeclaration_parameters,
-        "constructorDeclaration_redirectedConstructor":
-            constructorDeclaration_redirectedConstructor,
-        "constructorDeclaration_returnType": constructorDeclaration_returnType,
-        "flags": flags,
-        "informativeId": informativeId,
-        "kind": kind,
-        "name": name,
-      };
-    }
-    if (kind == idl.LinkedNodeKind.constructorFieldInitializer) {
-      return {
-        "constructorFieldInitializer_expression":
-            constructorFieldInitializer_expression,
-        "constructorFieldInitializer_fieldName":
-            constructorFieldInitializer_fieldName,
-        "flags": flags,
-        "kind": kind,
-        "name": name,
-      };
-    }
-    if (kind == idl.LinkedNodeKind.constructorName) {
-      return {
-        "constructorName_name": constructorName_name,
-        "constructorName_type": constructorName_type,
-        "constructorName_substitution": constructorName_substitution,
-        "constructorName_element": constructorName_element,
-        "flags": flags,
-        "kind": kind,
-        "name": name,
-      };
-    }
-    if (kind == idl.LinkedNodeKind.continueStatement) {
-      return {
-        "continueStatement_label": continueStatement_label,
-        "flags": flags,
-        "kind": kind,
-        "name": name,
-      };
-    }
-    if (kind == idl.LinkedNodeKind.declaredIdentifier) {
-      return {
-        "annotatedNode_metadata": annotatedNode_metadata,
-        "declaredIdentifier_identifier": declaredIdentifier_identifier,
-        "declaredIdentifier_type": declaredIdentifier_type,
-        "flags": flags,
-        "kind": kind,
-        "name": name,
-      };
-    }
-    if (kind == idl.LinkedNodeKind.defaultFormalParameter) {
-      return {
-        "defaultFormalParameter_defaultValue":
-            defaultFormalParameter_defaultValue,
-        "defaultFormalParameter_parameter": defaultFormalParameter_parameter,
-        "defaultFormalParameter_kind": defaultFormalParameter_kind,
-        "flags": flags,
-        "informativeId": informativeId,
-        "kind": kind,
-        "name": name,
-      };
-    }
-    if (kind == idl.LinkedNodeKind.doStatement) {
-      return {
-        "doStatement_body": doStatement_body,
-        "doStatement_condition": doStatement_condition,
-        "flags": flags,
-        "kind": kind,
-        "name": name,
-      };
-    }
-    if (kind == idl.LinkedNodeKind.dottedName) {
-      return {
-        "dottedName_components": dottedName_components,
-        "flags": flags,
-        "kind": kind,
-        "name": name,
-      };
-    }
-    if (kind == idl.LinkedNodeKind.doubleLiteral) {
-      return {
-        "doubleLiteral_value": doubleLiteral_value,
-        "flags": flags,
-        "kind": kind,
-        "name": name,
-      };
-    }
-    if (kind == idl.LinkedNodeKind.emptyFunctionBody) {
-      return {
-        "emptyFunctionBody_fake": emptyFunctionBody_fake,
-        "flags": flags,
-        "kind": kind,
-        "name": name,
-      };
-    }
-    if (kind == idl.LinkedNodeKind.emptyStatement) {
-      return {
-        "emptyStatement_fake": emptyStatement_fake,
-        "flags": flags,
-        "kind": kind,
-        "name": name,
-      };
-    }
-    if (kind == idl.LinkedNodeKind.enumConstantDeclaration) {
-      return {
-        "annotatedNode_metadata": annotatedNode_metadata,
-        "flags": flags,
-        "informativeId": informativeId,
-        "kind": kind,
-        "name": name,
-      };
-    }
-    if (kind == idl.LinkedNodeKind.enumDeclaration) {
-      return {
-        "enumDeclaration_constants": enumDeclaration_constants,
-        "annotatedNode_metadata": annotatedNode_metadata,
-        "flags": flags,
-        "informativeId": informativeId,
-        "kind": kind,
-        "name": name,
-      };
-    }
-    if (kind == idl.LinkedNodeKind.exportDirective) {
-      return {
-        "namespaceDirective_combinators": namespaceDirective_combinators,
-        "annotatedNode_metadata": annotatedNode_metadata,
-        "namespaceDirective_configurations": namespaceDirective_configurations,
-        "namespaceDirective_selectedUri": namespaceDirective_selectedUri,
-        "flags": flags,
-        "informativeId": informativeId,
-        "uriBasedDirective_uri": uriBasedDirective_uri,
-        "kind": kind,
-        "name": name,
-        "uriBasedDirective_uriContent": uriBasedDirective_uriContent,
-        "uriBasedDirective_uriElement": uriBasedDirective_uriElement,
-      };
-    }
-    if (kind == idl.LinkedNodeKind.expressionFunctionBody) {
-      return {
-        "expressionFunctionBody_expression": expressionFunctionBody_expression,
-        "flags": flags,
-        "kind": kind,
-        "name": name,
-      };
-    }
-    if (kind == idl.LinkedNodeKind.expressionStatement) {
-      return {
-        "expressionStatement_expression": expressionStatement_expression,
-        "flags": flags,
-        "kind": kind,
-        "name": name,
-      };
-    }
-    if (kind == idl.LinkedNodeKind.extendsClause) {
-      return {
-        "extendsClause_superclass": extendsClause_superclass,
-        "flags": flags,
-        "kind": kind,
-        "name": name,
-      };
-    }
-    if (kind == idl.LinkedNodeKind.extensionDeclaration) {
-      return {
-        "annotatedNode_metadata": annotatedNode_metadata,
-        "extensionDeclaration_typeParameters":
-            extensionDeclaration_typeParameters,
-        "extensionDeclaration_extendedType": extensionDeclaration_extendedType,
-        "extensionDeclaration_members": extensionDeclaration_members,
-        "extensionDeclaration_refName": extensionDeclaration_refName,
-        "flags": flags,
-        "informativeId": informativeId,
-        "kind": kind,
-        "name": name,
-      };
-    }
-    if (kind == idl.LinkedNodeKind.extensionOverride) {
-      return {
-        "extensionOverride_extendedType": extensionOverride_extendedType,
-        "extensionOverride_arguments": extensionOverride_arguments,
-        "extensionOverride_extensionName": extensionOverride_extensionName,
-        "extensionOverride_typeArguments": extensionOverride_typeArguments,
-        "extensionOverride_typeArgumentTypes":
-            extensionOverride_typeArgumentTypes,
-        "flags": flags,
-        "kind": kind,
-        "name": name,
-      };
-    }
-    if (kind == idl.LinkedNodeKind.fieldDeclaration) {
-      return {
-        "annotatedNode_metadata": annotatedNode_metadata,
-        "fieldDeclaration_fields": fieldDeclaration_fields,
-        "flags": flags,
-        "informativeId": informativeId,
-        "kind": kind,
-        "name": name,
-      };
-    }
-    if (kind == idl.LinkedNodeKind.fieldFormalParameter) {
-      return {
-        "actualType": actualType,
-        "normalFormalParameter_metadata": normalFormalParameter_metadata,
-        "fieldFormalParameter_type": fieldFormalParameter_type,
-        "fieldFormalParameter_typeParameters":
-            fieldFormalParameter_typeParameters,
-        "fieldFormalParameter_formalParameters":
-            fieldFormalParameter_formalParameters,
-        "inheritsCovariant": inheritsCovariant,
-        "flags": flags,
-        "informativeId": informativeId,
-        "kind": kind,
-        "name": name,
-      };
-    }
-    if (kind == idl.LinkedNodeKind.forEachPartsWithDeclaration) {
-      return {
-        "forEachParts_iterable": forEachParts_iterable,
-        "forEachPartsWithDeclaration_loopVariable":
-            forEachPartsWithDeclaration_loopVariable,
-        "flags": flags,
-        "kind": kind,
-        "name": name,
-      };
-    }
-    if (kind == idl.LinkedNodeKind.forEachPartsWithIdentifier) {
-      return {
-        "forEachParts_iterable": forEachParts_iterable,
-        "forEachPartsWithIdentifier_identifier":
-            forEachPartsWithIdentifier_identifier,
-        "flags": flags,
-        "kind": kind,
-        "name": name,
-      };
-    }
-    if (kind == idl.LinkedNodeKind.forElement) {
-      return {
-        "forMixin_forLoopParts": forMixin_forLoopParts,
-        "forElement_body": forElement_body,
-        "flags": flags,
-        "kind": kind,
-        "name": name,
-      };
-    }
-    if (kind == idl.LinkedNodeKind.forPartsWithDeclarations) {
-      return {
-        "forParts_condition": forParts_condition,
-        "forPartsWithDeclarations_variables":
-            forPartsWithDeclarations_variables,
-        "forParts_updaters": forParts_updaters,
-        "flags": flags,
-        "kind": kind,
-        "name": name,
-      };
-    }
-    if (kind == idl.LinkedNodeKind.forPartsWithExpression) {
-      return {
-        "forParts_condition": forParts_condition,
-        "forPartsWithExpression_initialization":
-            forPartsWithExpression_initialization,
-        "forParts_updaters": forParts_updaters,
-        "flags": flags,
-        "kind": kind,
-        "name": name,
-      };
-    }
-    if (kind == idl.LinkedNodeKind.forStatement) {
-      return {
-        "forMixin_forLoopParts": forMixin_forLoopParts,
-        "forStatement_body": forStatement_body,
-        "flags": flags,
-        "kind": kind,
-        "name": name,
-      };
-    }
-    if (kind == idl.LinkedNodeKind.formalParameterList) {
-      return {
-        "formalParameterList_parameters": formalParameterList_parameters,
-        "flags": flags,
-        "kind": kind,
-        "name": name,
-      };
-    }
-    if (kind == idl.LinkedNodeKind.functionDeclaration) {
-      return {
-        "actualReturnType": actualReturnType,
-        "annotatedNode_metadata": annotatedNode_metadata,
-        "functionDeclaration_functionExpression":
-            functionDeclaration_functionExpression,
-        "functionDeclaration_returnType": functionDeclaration_returnType,
-        "flags": flags,
-        "informativeId": informativeId,
-        "kind": kind,
-        "name": name,
-      };
-    }
-    if (kind == idl.LinkedNodeKind.functionDeclarationStatement) {
-      return {
-        "functionDeclarationStatement_functionDeclaration":
-            functionDeclarationStatement_functionDeclaration,
-        "flags": flags,
-        "kind": kind,
-        "name": name,
-      };
-    }
-    if (kind == idl.LinkedNodeKind.functionExpression) {
-      return {
-        "actualReturnType": actualReturnType,
-        "functionExpression_body": functionExpression_body,
-        "functionExpression_formalParameters":
-            functionExpression_formalParameters,
-        "functionExpression_typeParameters": functionExpression_typeParameters,
-        "flags": flags,
-        "kind": kind,
-        "name": name,
-      };
-    }
-    if (kind == idl.LinkedNodeKind.functionExpressionInvocation) {
-      return {
-        "invocationExpression_invokeType": invocationExpression_invokeType,
-        "functionExpressionInvocation_function":
-            functionExpressionInvocation_function,
-        "invocationExpression_typeArguments":
-            invocationExpression_typeArguments,
-        "expression_type": expression_type,
-        "flags": flags,
-        "invocationExpression_arguments": invocationExpression_arguments,
-        "kind": kind,
-        "name": name,
-      };
-    }
-    if (kind == idl.LinkedNodeKind.functionTypeAlias) {
-      return {
-        "actualReturnType": actualReturnType,
-        "annotatedNode_metadata": annotatedNode_metadata,
-        "functionTypeAlias_formalParameters":
-            functionTypeAlias_formalParameters,
-        "functionTypeAlias_returnType": functionTypeAlias_returnType,
-        "functionTypeAlias_typeParameters": functionTypeAlias_typeParameters,
-        "typeAlias_hasSelfReference": typeAlias_hasSelfReference,
-        "flags": flags,
-        "informativeId": informativeId,
-        "kind": kind,
-        "simplyBoundable_isSimplyBounded": simplyBoundable_isSimplyBounded,
-        "name": name,
-      };
-    }
-    if (kind == idl.LinkedNodeKind.functionTypedFormalParameter) {
-      return {
-        "actualType": actualType,
-        "normalFormalParameter_metadata": normalFormalParameter_metadata,
-        "functionTypedFormalParameter_formalParameters":
-            functionTypedFormalParameter_formalParameters,
-        "functionTypedFormalParameter_returnType":
-            functionTypedFormalParameter_returnType,
-        "functionTypedFormalParameter_typeParameters":
-            functionTypedFormalParameter_typeParameters,
-        "inheritsCovariant": inheritsCovariant,
-        "flags": flags,
-        "informativeId": informativeId,
-        "kind": kind,
-        "name": name,
-      };
-    }
-    if (kind == idl.LinkedNodeKind.genericFunctionType) {
-      return {
-        "actualReturnType": actualReturnType,
-        "genericFunctionType_typeParameters":
-            genericFunctionType_typeParameters,
-        "genericFunctionType_returnType": genericFunctionType_returnType,
-        "genericFunctionType_id": genericFunctionType_id,
-        "genericFunctionType_formalParameters":
-            genericFunctionType_formalParameters,
-        "genericFunctionType_type": genericFunctionType_type,
-        "flags": flags,
-        "kind": kind,
-        "name": name,
-      };
-    }
-    if (kind == idl.LinkedNodeKind.genericTypeAlias) {
-      return {
-        "annotatedNode_metadata": annotatedNode_metadata,
-        "genericTypeAlias_typeParameters": genericTypeAlias_typeParameters,
-        "genericTypeAlias_functionType": genericTypeAlias_functionType,
-        "typeAlias_hasSelfReference": typeAlias_hasSelfReference,
-        "flags": flags,
-        "informativeId": informativeId,
-        "kind": kind,
-        "simplyBoundable_isSimplyBounded": simplyBoundable_isSimplyBounded,
-        "name": name,
-      };
-    }
-    if (kind == idl.LinkedNodeKind.hideCombinator) {
-      return {
-        "flags": flags,
-        "informativeId": informativeId,
-        "kind": kind,
-        "names": names,
-        "name": name,
-      };
-    }
-    if (kind == idl.LinkedNodeKind.ifElement) {
-      return {
-        "ifMixin_condition": ifMixin_condition,
-        "ifElement_thenElement": ifElement_thenElement,
-        "ifElement_elseElement": ifElement_elseElement,
-        "flags": flags,
-        "kind": kind,
-        "name": name,
-      };
-    }
-    if (kind == idl.LinkedNodeKind.ifStatement) {
-      return {
-        "ifMixin_condition": ifMixin_condition,
-        "ifStatement_elseStatement": ifStatement_elseStatement,
-        "ifStatement_thenStatement": ifStatement_thenStatement,
-        "flags": flags,
-        "kind": kind,
-        "name": name,
-      };
-    }
-    if (kind == idl.LinkedNodeKind.implementsClause) {
-      return {
-        "implementsClause_interfaces": implementsClause_interfaces,
-        "flags": flags,
-        "kind": kind,
-        "name": name,
-      };
-    }
-    if (kind == idl.LinkedNodeKind.importDirective) {
-      return {
-        "namespaceDirective_combinators": namespaceDirective_combinators,
-        "annotatedNode_metadata": annotatedNode_metadata,
-        "namespaceDirective_configurations": namespaceDirective_configurations,
-        "namespaceDirective_selectedUri": namespaceDirective_selectedUri,
-        "flags": flags,
-        "importDirective_prefix": importDirective_prefix,
-        "informativeId": informativeId,
-        "uriBasedDirective_uri": uriBasedDirective_uri,
-        "kind": kind,
-        "name": name,
-        "uriBasedDirective_uriContent": uriBasedDirective_uriContent,
-        "uriBasedDirective_uriElement": uriBasedDirective_uriElement,
-      };
-    }
-    if (kind == idl.LinkedNodeKind.indexExpression) {
-      return {
-        "indexExpression_index": indexExpression_index,
-        "indexExpression_target": indexExpression_target,
-        "indexExpression_substitution": indexExpression_substitution,
-        "indexExpression_element": indexExpression_element,
-        "expression_type": expression_type,
-        "flags": flags,
-        "kind": kind,
-        "name": name,
-      };
-    }
-    if (kind == idl.LinkedNodeKind.instanceCreationExpression) {
-      return {
-        "instanceCreationExpression_arguments":
-            instanceCreationExpression_arguments,
-        "instanceCreationExpression_constructorName":
-            instanceCreationExpression_constructorName,
-        "instanceCreationExpression_typeArguments":
-            instanceCreationExpression_typeArguments,
-        "expression_type": expression_type,
-        "flags": flags,
-        "kind": kind,
-        "name": name,
-      };
-    }
-    if (kind == idl.LinkedNodeKind.integerLiteral) {
-      return {
-        "expression_type": expression_type,
-        "flags": flags,
-        "integerLiteral_value": integerLiteral_value,
-        "kind": kind,
-        "name": name,
-      };
-    }
-    if (kind == idl.LinkedNodeKind.interpolationExpression) {
-      return {
-        "interpolationExpression_expression":
-            interpolationExpression_expression,
-        "flags": flags,
-        "kind": kind,
-        "name": name,
-      };
-    }
-    if (kind == idl.LinkedNodeKind.interpolationString) {
-      return {
-        "flags": flags,
-        "interpolationString_value": interpolationString_value,
-        "kind": kind,
-        "name": name,
-      };
-    }
-    if (kind == idl.LinkedNodeKind.isExpression) {
-      return {
-        "isExpression_expression": isExpression_expression,
-        "isExpression_type": isExpression_type,
-        "flags": flags,
-        "kind": kind,
-        "name": name,
-      };
-    }
-    if (kind == idl.LinkedNodeKind.label) {
-      return {
-        "label_label": label_label,
-        "flags": flags,
-        "kind": kind,
-        "name": name,
-      };
-    }
-    if (kind == idl.LinkedNodeKind.labeledStatement) {
-      return {
-        "labeledStatement_labels": labeledStatement_labels,
-        "labeledStatement_statement": labeledStatement_statement,
-        "flags": flags,
-        "kind": kind,
-        "name": name,
-      };
-    }
-    if (kind == idl.LinkedNodeKind.libraryDirective) {
-      return {
-        "annotatedNode_metadata": annotatedNode_metadata,
-        "libraryDirective_name": libraryDirective_name,
-        "flags": flags,
-        "informativeId": informativeId,
-        "kind": kind,
-        "name": name,
-      };
-    }
-    if (kind == idl.LinkedNodeKind.libraryIdentifier) {
-      return {
-        "libraryIdentifier_components": libraryIdentifier_components,
-        "flags": flags,
-        "kind": kind,
-        "name": name,
-      };
-    }
-    if (kind == idl.LinkedNodeKind.listLiteral) {
-      return {
-        "typedLiteral_typeArguments": typedLiteral_typeArguments,
-        "listLiteral_elements": listLiteral_elements,
-        "expression_type": expression_type,
-        "flags": flags,
-        "kind": kind,
-        "name": name,
-      };
-    }
-    if (kind == idl.LinkedNodeKind.mapLiteralEntry) {
-      return {
-        "mapLiteralEntry_key": mapLiteralEntry_key,
-        "mapLiteralEntry_value": mapLiteralEntry_value,
-        "flags": flags,
-        "kind": kind,
-        "name": name,
-      };
-    }
-    if (kind == idl.LinkedNodeKind.methodDeclaration) {
-      return {
-        "actualReturnType": actualReturnType,
-        "annotatedNode_metadata": annotatedNode_metadata,
-        "methodDeclaration_body": methodDeclaration_body,
-        "methodDeclaration_formalParameters":
-            methodDeclaration_formalParameters,
-        "methodDeclaration_returnType": methodDeclaration_returnType,
-        "methodDeclaration_typeParameters": methodDeclaration_typeParameters,
-        "flags": flags,
-        "informativeId": informativeId,
-        "kind": kind,
-        "methodDeclaration_hasOperatorEqualWithParameterTypeFromObject":
-            methodDeclaration_hasOperatorEqualWithParameterTypeFromObject,
-        "name": name,
-        "topLevelTypeInferenceError": topLevelTypeInferenceError,
-      };
-    }
-    if (kind == idl.LinkedNodeKind.methodInvocation) {
-      return {
-        "invocationExpression_invokeType": invocationExpression_invokeType,
-        "methodInvocation_methodName": methodInvocation_methodName,
-        "methodInvocation_target": methodInvocation_target,
-        "invocationExpression_typeArguments":
-            invocationExpression_typeArguments,
-        "expression_type": expression_type,
-        "flags": flags,
-        "invocationExpression_arguments": invocationExpression_arguments,
-        "kind": kind,
-        "name": name,
-      };
-    }
-    if (kind == idl.LinkedNodeKind.mixinDeclaration) {
-      return {
-        "annotatedNode_metadata": annotatedNode_metadata,
-        "mixinDeclaration_onClause": mixinDeclaration_onClause,
-        "classOrMixinDeclaration_implementsClause":
-            classOrMixinDeclaration_implementsClause,
-        "classOrMixinDeclaration_members": classOrMixinDeclaration_members,
-        "classOrMixinDeclaration_typeParameters":
-            classOrMixinDeclaration_typeParameters,
-        "flags": flags,
-        "informativeId": informativeId,
-        "kind": kind,
-        "simplyBoundable_isSimplyBounded": simplyBoundable_isSimplyBounded,
-        "mixinDeclaration_superInvokedNames":
-            mixinDeclaration_superInvokedNames,
-        "name": name,
-      };
-    }
-    if (kind == idl.LinkedNodeKind.namedExpression) {
-      return {
-        "namedExpression_expression": namedExpression_expression,
-        "namedExpression_name": namedExpression_name,
-        "flags": flags,
-        "kind": kind,
-        "name": name,
-      };
-    }
-    if (kind == idl.LinkedNodeKind.nativeClause) {
-      return {
-        "nativeClause_name": nativeClause_name,
-        "flags": flags,
-        "kind": kind,
-        "name": name,
-      };
-    }
-    if (kind == idl.LinkedNodeKind.nativeFunctionBody) {
-      return {
-        "nativeFunctionBody_stringLiteral": nativeFunctionBody_stringLiteral,
-        "flags": flags,
-        "kind": kind,
-        "name": name,
-      };
-    }
-    if (kind == idl.LinkedNodeKind.nullLiteral) {
-      return {
-        "nullLiteral_fake": nullLiteral_fake,
-        "expression_type": expression_type,
-        "flags": flags,
-        "kind": kind,
-        "name": name,
-      };
-    }
-    if (kind == idl.LinkedNodeKind.onClause) {
-      return {
-        "onClause_superclassConstraints": onClause_superclassConstraints,
-        "flags": flags,
-        "kind": kind,
-        "name": name,
-      };
-    }
-    if (kind == idl.LinkedNodeKind.parenthesizedExpression) {
-      return {
-        "parenthesizedExpression_expression":
-            parenthesizedExpression_expression,
-        "expression_type": expression_type,
-        "flags": flags,
-        "kind": kind,
-        "name": name,
-      };
-    }
-    if (kind == idl.LinkedNodeKind.partDirective) {
-      return {
-        "annotatedNode_metadata": annotatedNode_metadata,
-        "flags": flags,
-        "informativeId": informativeId,
-        "uriBasedDirective_uri": uriBasedDirective_uri,
-        "kind": kind,
-        "name": name,
-        "uriBasedDirective_uriContent": uriBasedDirective_uriContent,
-        "uriBasedDirective_uriElement": uriBasedDirective_uriElement,
-      };
-    }
-    if (kind == idl.LinkedNodeKind.partOfDirective) {
-      return {
-        "annotatedNode_metadata": annotatedNode_metadata,
-        "partOfDirective_libraryName": partOfDirective_libraryName,
-        "partOfDirective_uri": partOfDirective_uri,
-        "flags": flags,
-        "informativeId": informativeId,
-        "kind": kind,
-        "name": name,
-      };
-    }
-    if (kind == idl.LinkedNodeKind.postfixExpression) {
-      return {
-        "postfixExpression_operand": postfixExpression_operand,
-        "postfixExpression_substitution": postfixExpression_substitution,
-        "postfixExpression_element": postfixExpression_element,
-        "postfixExpression_operator": postfixExpression_operator,
-        "expression_type": expression_type,
-        "flags": flags,
-        "kind": kind,
-        "name": name,
-      };
-    }
-    if (kind == idl.LinkedNodeKind.prefixExpression) {
-      return {
-        "prefixExpression_operand": prefixExpression_operand,
-        "prefixExpression_substitution": prefixExpression_substitution,
-        "prefixExpression_element": prefixExpression_element,
-        "prefixExpression_operator": prefixExpression_operator,
-        "expression_type": expression_type,
-        "flags": flags,
-        "kind": kind,
-        "name": name,
-      };
-    }
-    if (kind == idl.LinkedNodeKind.prefixedIdentifier) {
-      return {
-        "prefixedIdentifier_identifier": prefixedIdentifier_identifier,
-        "prefixedIdentifier_prefix": prefixedIdentifier_prefix,
-        "expression_type": expression_type,
-        "flags": flags,
-        "kind": kind,
-        "name": name,
-      };
-    }
-    if (kind == idl.LinkedNodeKind.propertyAccess) {
-      return {
-        "propertyAccess_propertyName": propertyAccess_propertyName,
-        "propertyAccess_target": propertyAccess_target,
-        "propertyAccess_operator": propertyAccess_operator,
-        "expression_type": expression_type,
-        "flags": flags,
-        "kind": kind,
-        "name": name,
-      };
-    }
-    if (kind == idl.LinkedNodeKind.redirectingConstructorInvocation) {
-      return {
-        "redirectingConstructorInvocation_arguments":
-            redirectingConstructorInvocation_arguments,
-        "redirectingConstructorInvocation_constructorName":
-            redirectingConstructorInvocation_constructorName,
-        "redirectingConstructorInvocation_substitution":
-            redirectingConstructorInvocation_substitution,
-        "redirectingConstructorInvocation_element":
-            redirectingConstructorInvocation_element,
-        "flags": flags,
-        "kind": kind,
-        "name": name,
-      };
-    }
-    if (kind == idl.LinkedNodeKind.rethrowExpression) {
-      return {
-        "expression_type": expression_type,
-        "flags": flags,
-        "kind": kind,
-        "name": name,
-      };
-    }
-    if (kind == idl.LinkedNodeKind.returnStatement) {
-      return {
-        "returnStatement_expression": returnStatement_expression,
-        "flags": flags,
-        "kind": kind,
-        "name": name,
-      };
-    }
-    if (kind == idl.LinkedNodeKind.setOrMapLiteral) {
-      return {
-        "typedLiteral_typeArguments": typedLiteral_typeArguments,
-        "setOrMapLiteral_elements": setOrMapLiteral_elements,
-        "expression_type": expression_type,
-        "flags": flags,
-        "kind": kind,
-        "name": name,
-      };
-    }
-    if (kind == idl.LinkedNodeKind.showCombinator) {
-      return {
-        "flags": flags,
-        "informativeId": informativeId,
-        "kind": kind,
-        "names": names,
-        "name": name,
-      };
-    }
-    if (kind == idl.LinkedNodeKind.simpleFormalParameter) {
-      return {
-        "actualType": actualType,
-        "normalFormalParameter_metadata": normalFormalParameter_metadata,
-        "simpleFormalParameter_type": simpleFormalParameter_type,
-        "inheritsCovariant": inheritsCovariant,
-        "flags": flags,
-        "informativeId": informativeId,
-        "kind": kind,
-        "name": name,
-        "topLevelTypeInferenceError": topLevelTypeInferenceError,
-      };
-    }
-    if (kind == idl.LinkedNodeKind.simpleIdentifier) {
-      return {
-        "simpleIdentifier_substitution": simpleIdentifier_substitution,
-        "simpleIdentifier_element": simpleIdentifier_element,
-        "expression_type": expression_type,
-        "flags": flags,
-        "kind": kind,
-        "name": name,
-      };
-    }
-    if (kind == idl.LinkedNodeKind.simpleStringLiteral) {
-      return {
-        "simpleStringLiteral_value": simpleStringLiteral_value,
-        "flags": flags,
-        "kind": kind,
-        "name": name,
-      };
-    }
-    if (kind == idl.LinkedNodeKind.spreadElement) {
-      return {
-        "spreadElement_expression": spreadElement_expression,
-        "flags": flags,
-        "kind": kind,
-        "name": name,
-        "spreadElement_spreadOperator": spreadElement_spreadOperator,
-      };
-    }
-    if (kind == idl.LinkedNodeKind.stringInterpolation) {
-      return {
-        "stringInterpolation_elements": stringInterpolation_elements,
-        "flags": flags,
-        "kind": kind,
-        "name": name,
-      };
-    }
-    if (kind == idl.LinkedNodeKind.superConstructorInvocation) {
-      return {
-        "superConstructorInvocation_arguments":
-            superConstructorInvocation_arguments,
-        "superConstructorInvocation_constructorName":
-            superConstructorInvocation_constructorName,
-        "superConstructorInvocation_substitution":
-            superConstructorInvocation_substitution,
-        "superConstructorInvocation_element":
-            superConstructorInvocation_element,
-        "flags": flags,
-        "kind": kind,
-        "name": name,
-      };
-    }
-    if (kind == idl.LinkedNodeKind.superExpression) {
-      return {
-        "expression_type": expression_type,
-        "flags": flags,
-        "kind": kind,
-        "name": name,
-      };
-    }
-    if (kind == idl.LinkedNodeKind.switchCase) {
-      return {
-        "switchMember_statements": switchMember_statements,
-        "switchCase_expression": switchCase_expression,
-        "switchMember_labels": switchMember_labels,
-        "flags": flags,
-        "kind": kind,
-        "name": name,
-      };
-    }
-    if (kind == idl.LinkedNodeKind.switchDefault) {
-      return {
-        "switchMember_statements": switchMember_statements,
-        "switchMember_labels": switchMember_labels,
-        "flags": flags,
-        "kind": kind,
-        "name": name,
-      };
-    }
-    if (kind == idl.LinkedNodeKind.switchStatement) {
-      return {
-        "switchStatement_members": switchStatement_members,
-        "switchStatement_expression": switchStatement_expression,
-        "flags": flags,
-        "kind": kind,
-        "name": name,
-      };
-    }
-    if (kind == idl.LinkedNodeKind.symbolLiteral) {
-      return {
-        "expression_type": expression_type,
-        "flags": flags,
-        "kind": kind,
-        "names": names,
-        "name": name,
-      };
-    }
-    if (kind == idl.LinkedNodeKind.thisExpression) {
-      return {
-        "expression_type": expression_type,
-        "flags": flags,
-        "kind": kind,
-        "name": name,
-      };
-    }
-    if (kind == idl.LinkedNodeKind.throwExpression) {
-      return {
-        "throwExpression_expression": throwExpression_expression,
-        "expression_type": expression_type,
-        "flags": flags,
-        "kind": kind,
-        "name": name,
-      };
-    }
-    if (kind == idl.LinkedNodeKind.topLevelVariableDeclaration) {
-      return {
-        "annotatedNode_metadata": annotatedNode_metadata,
-        "topLevelVariableDeclaration_variableList":
-            topLevelVariableDeclaration_variableList,
-        "flags": flags,
-        "informativeId": informativeId,
-        "kind": kind,
-        "name": name,
-      };
-    }
-    if (kind == idl.LinkedNodeKind.tryStatement) {
-      return {
-        "tryStatement_catchClauses": tryStatement_catchClauses,
-        "tryStatement_body": tryStatement_body,
-        "tryStatement_finallyBlock": tryStatement_finallyBlock,
-        "flags": flags,
-        "kind": kind,
-        "name": name,
-      };
-    }
-    if (kind == idl.LinkedNodeKind.typeArgumentList) {
-      return {
-        "typeArgumentList_arguments": typeArgumentList_arguments,
-        "flags": flags,
-        "kind": kind,
-        "name": name,
-      };
-    }
-    if (kind == idl.LinkedNodeKind.typeName) {
-      return {
-        "typeName_typeArguments": typeName_typeArguments,
-        "typeName_name": typeName_name,
-        "flags": flags,
-        "kind": kind,
-        "name": name,
-        "typeName_type": typeName_type,
-      };
-    }
-    if (kind == idl.LinkedNodeKind.typeParameter) {
-      return {
-        "annotatedNode_metadata": annotatedNode_metadata,
-        "typeParameter_bound": typeParameter_bound,
-        "typeParameter_variance": typeParameter_variance,
-        "flags": flags,
-        "informativeId": informativeId,
-        "kind": kind,
-        "name": name,
-        "typeParameter_defaultType": typeParameter_defaultType,
-      };
-    }
-    if (kind == idl.LinkedNodeKind.typeParameterList) {
-      return {
-        "typeParameterList_typeParameters": typeParameterList_typeParameters,
-        "flags": flags,
-        "kind": kind,
-        "name": name,
-      };
-    }
-    if (kind == idl.LinkedNodeKind.variableDeclaration) {
-      return {
-        "actualType": actualType,
-        "annotatedNode_metadata": annotatedNode_metadata,
-        "variableDeclaration_initializer": variableDeclaration_initializer,
-        "inheritsCovariant": inheritsCovariant,
-        "flags": flags,
-        "informativeId": informativeId,
-        "kind": kind,
-        "name": name,
-        "topLevelTypeInferenceError": topLevelTypeInferenceError,
-      };
-    }
-    if (kind == idl.LinkedNodeKind.variableDeclarationList) {
-      return {
-        "variableDeclarationList_variables": variableDeclarationList_variables,
-        "annotatedNode_metadata": annotatedNode_metadata,
-        "variableDeclarationList_type": variableDeclarationList_type,
-        "flags": flags,
-        "informativeId": informativeId,
-        "kind": kind,
-        "name": name,
-      };
-    }
-    if (kind == idl.LinkedNodeKind.variableDeclarationStatement) {
-      return {
-        "variableDeclarationStatement_variables":
-            variableDeclarationStatement_variables,
-        "flags": flags,
-        "kind": kind,
-        "name": name,
-      };
-    }
-    if (kind == idl.LinkedNodeKind.whileStatement) {
-      return {
-        "whileStatement_body": whileStatement_body,
-        "whileStatement_condition": whileStatement_condition,
-        "flags": flags,
-        "kind": kind,
-        "name": name,
-      };
-    }
-    if (kind == idl.LinkedNodeKind.withClause) {
-      return {
-        "withClause_mixinTypes": withClause_mixinTypes,
-        "flags": flags,
-        "kind": kind,
-        "name": name,
-      };
-    }
-    if (kind == idl.LinkedNodeKind.yieldStatement) {
-      return {
-        "yieldStatement_expression": yieldStatement_expression,
-        "flags": flags,
-        "kind": kind,
-        "name": name,
-      };
-    }
-    throw StateError("Unexpected $kind");
-  }
-
-  @override
-  String toString() => convert.json.encode(toJson());
-}
-
-class LinkedNodeBundleBuilder extends Object
-    with _LinkedNodeBundleMixin
-    implements idl.LinkedNodeBundle {
-  List<LinkedNodeLibraryBuilder> _libraries;
-  LinkedNodeReferencesBuilder _references;
-
-  @override
-  List<LinkedNodeLibraryBuilder> get libraries =>
-      _libraries ??= <LinkedNodeLibraryBuilder>[];
-
-  set libraries(List<LinkedNodeLibraryBuilder> value) {
-    this._libraries = value;
-  }
-
-  @override
-  LinkedNodeReferencesBuilder get references => _references;
-
-  /// The shared list of references used in the [libraries].
-  set references(LinkedNodeReferencesBuilder value) {
-    this._references = value;
-  }
-
-  LinkedNodeBundleBuilder(
-      {List<LinkedNodeLibraryBuilder> libraries,
-      LinkedNodeReferencesBuilder references})
-      : _libraries = libraries,
-        _references = references;
-
-  /// Flush [informative] data recursively.
-  void flushInformative() {
-    _libraries?.forEach((b) => b.flushInformative());
-    _references?.flushInformative();
-  }
-
-  /// Accumulate non-[informative] data into [signature].
-  void collectApiSignature(api_sig.ApiSignature signature) {
-    signature.addBool(this._references != null);
-    this._references?.collectApiSignature(signature);
-    if (this._libraries == null) {
-      signature.addInt(0);
-    } else {
-      signature.addInt(this._libraries.length);
-      for (var x in this._libraries) {
-        x?.collectApiSignature(signature);
-      }
-    }
-  }
-
-  List<int> toBuffer() {
-    fb.Builder fbBuilder = fb.Builder();
-    return fbBuilder.finish(finish(fbBuilder), "LNBn");
-  }
-
-  fb.Offset finish(fb.Builder fbBuilder) {
-    fb.Offset offset_libraries;
-    fb.Offset offset_references;
-    if (!(_libraries == null || _libraries.isEmpty)) {
-      offset_libraries = fbBuilder
-          .writeList(_libraries.map((b) => b.finish(fbBuilder)).toList());
-    }
-    if (_references != null) {
-      offset_references = _references.finish(fbBuilder);
-    }
-    fbBuilder.startTable();
-    if (offset_libraries != null) {
-      fbBuilder.addOffset(1, offset_libraries);
-    }
-    if (offset_references != null) {
-      fbBuilder.addOffset(0, offset_references);
-    }
-    return fbBuilder.endTable();
-  }
-}
-
-idl.LinkedNodeBundle readLinkedNodeBundle(List<int> buffer) {
-  fb.BufferContext rootRef = fb.BufferContext.fromBytes(buffer);
-  return const _LinkedNodeBundleReader().read(rootRef, 0);
-}
-
-class _LinkedNodeBundleReader extends fb.TableReader<_LinkedNodeBundleImpl> {
-  const _LinkedNodeBundleReader();
-
-  @override
-  _LinkedNodeBundleImpl createObject(fb.BufferContext bc, int offset) =>
-      _LinkedNodeBundleImpl(bc, offset);
-}
-
-class _LinkedNodeBundleImpl extends Object
-    with _LinkedNodeBundleMixin
-    implements idl.LinkedNodeBundle {
-  final fb.BufferContext _bc;
-  final int _bcOffset;
-
-  _LinkedNodeBundleImpl(this._bc, this._bcOffset);
-
-  List<idl.LinkedNodeLibrary> _libraries;
-  idl.LinkedNodeReferences _references;
-
-  @override
-  List<idl.LinkedNodeLibrary> get libraries {
-    _libraries ??=
-        const fb.ListReader<idl.LinkedNodeLibrary>(_LinkedNodeLibraryReader())
-            .vTableGet(_bc, _bcOffset, 1, const <idl.LinkedNodeLibrary>[]);
-    return _libraries;
-  }
-
-  @override
-  idl.LinkedNodeReferences get references {
-    _references ??=
-        const _LinkedNodeReferencesReader().vTableGet(_bc, _bcOffset, 0, null);
-    return _references;
-  }
-}
-
-abstract class _LinkedNodeBundleMixin implements idl.LinkedNodeBundle {
-  @override
-  Map<String, Object> toJson() {
-    Map<String, Object> _result = <String, Object>{};
-    if (libraries.isNotEmpty) {
-      _result["libraries"] =
-          libraries.map((_value) => _value.toJson()).toList();
-    }
-    if (references != null) {
-      _result["references"] = references.toJson();
-    }
-    return _result;
-  }
-
-  @override
-  Map<String, Object> toMap() => {
-        "libraries": libraries,
-        "references": references,
-      };
-
-  @override
-  String toString() => convert.json.encode(toJson());
-}
-
-class LinkedNodeLibraryBuilder extends Object
-    with _LinkedNodeLibraryMixin
-    implements idl.LinkedNodeLibrary {
-  List<int> _exports;
-  String _name;
-  int _nameLength;
-  int _nameOffset;
-  List<LinkedNodeUnitBuilder> _units;
-  String _uriStr;
-
-  @override
-  List<int> get exports => _exports ??= <int>[];
-
-  set exports(List<int> value) {
-    assert(value == null || value.every((e) => e >= 0));
-    this._exports = value;
-  }
-
-  @override
-  String get name => _name ??= '';
-
-  set name(String value) {
-    this._name = value;
-  }
-
-  @override
-  int get nameLength => _nameLength ??= 0;
-
-  set nameLength(int value) {
-    assert(value == null || value >= 0);
-    this._nameLength = value;
-  }
-
-  @override
-  int get nameOffset => _nameOffset ??= 0;
-
-  set nameOffset(int value) {
-    assert(value == null || value >= 0);
-    this._nameOffset = value;
-  }
-
-  @override
-  List<LinkedNodeUnitBuilder> get units => _units ??= <LinkedNodeUnitBuilder>[];
-
-  set units(List<LinkedNodeUnitBuilder> value) {
-    this._units = value;
-  }
-
-  @override
-  String get uriStr => _uriStr ??= '';
-
-  set uriStr(String value) {
-    this._uriStr = value;
-  }
-
-  LinkedNodeLibraryBuilder(
-      {List<int> exports,
-      String name,
-      int nameLength,
-      int nameOffset,
-      List<LinkedNodeUnitBuilder> units,
-      String uriStr})
-      : _exports = exports,
-        _name = name,
-        _nameLength = nameLength,
-        _nameOffset = nameOffset,
-        _units = units,
-        _uriStr = uriStr;
-
-  /// Flush [informative] data recursively.
-  void flushInformative() {
-    _units?.forEach((b) => b.flushInformative());
-  }
-
-  /// Accumulate non-[informative] data into [signature].
-  void collectApiSignature(api_sig.ApiSignature signature) {
-    signature.addString(this._uriStr ?? '');
-    if (this._units == null) {
-      signature.addInt(0);
-    } else {
-      signature.addInt(this._units.length);
-      for (var x in this._units) {
-        x?.collectApiSignature(signature);
-      }
-    }
-    if (this._exports == null) {
-      signature.addInt(0);
-    } else {
-      signature.addInt(this._exports.length);
-      for (var x in this._exports) {
-        signature.addInt(x);
-      }
-    }
-    signature.addString(this._name ?? '');
-    signature.addInt(this._nameOffset ?? 0);
-    signature.addInt(this._nameLength ?? 0);
-  }
-
-  fb.Offset finish(fb.Builder fbBuilder) {
-    fb.Offset offset_exports;
-    fb.Offset offset_name;
-    fb.Offset offset_units;
-    fb.Offset offset_uriStr;
-    if (!(_exports == null || _exports.isEmpty)) {
-      offset_exports = fbBuilder.writeListUint32(_exports);
-    }
-    if (_name != null) {
-      offset_name = fbBuilder.writeString(_name);
-    }
-    if (!(_units == null || _units.isEmpty)) {
-      offset_units =
-          fbBuilder.writeList(_units.map((b) => b.finish(fbBuilder)).toList());
-    }
-    if (_uriStr != null) {
-      offset_uriStr = fbBuilder.writeString(_uriStr);
-    }
-    fbBuilder.startTable();
-    if (offset_exports != null) {
-      fbBuilder.addOffset(2, offset_exports);
-    }
-    if (offset_name != null) {
-      fbBuilder.addOffset(3, offset_name);
-    }
-    if (_nameLength != null && _nameLength != 0) {
-      fbBuilder.addUint32(5, _nameLength);
-    }
-    if (_nameOffset != null && _nameOffset != 0) {
-      fbBuilder.addUint32(4, _nameOffset);
-    }
-    if (offset_units != null) {
-      fbBuilder.addOffset(1, offset_units);
-    }
-    if (offset_uriStr != null) {
-      fbBuilder.addOffset(0, offset_uriStr);
-    }
-    return fbBuilder.endTable();
-  }
-}
-
-class _LinkedNodeLibraryReader extends fb.TableReader<_LinkedNodeLibraryImpl> {
-  const _LinkedNodeLibraryReader();
-
-  @override
-  _LinkedNodeLibraryImpl createObject(fb.BufferContext bc, int offset) =>
-      _LinkedNodeLibraryImpl(bc, offset);
-}
-
-class _LinkedNodeLibraryImpl extends Object
-    with _LinkedNodeLibraryMixin
-    implements idl.LinkedNodeLibrary {
-  final fb.BufferContext _bc;
-  final int _bcOffset;
-
-  _LinkedNodeLibraryImpl(this._bc, this._bcOffset);
-
-  List<int> _exports;
-  String _name;
-  int _nameLength;
-  int _nameOffset;
-  List<idl.LinkedNodeUnit> _units;
-  String _uriStr;
-
-  @override
-  List<int> get exports {
-    _exports ??=
-        const fb.Uint32ListReader().vTableGet(_bc, _bcOffset, 2, const <int>[]);
-    return _exports;
-  }
-
-  @override
-  String get name {
-    _name ??= const fb.StringReader().vTableGet(_bc, _bcOffset, 3, '');
-    return _name;
-  }
-
-  @override
-  int get nameLength {
-    _nameLength ??= const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 5, 0);
-    return _nameLength;
-  }
-
-  @override
-  int get nameOffset {
-    _nameOffset ??= const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 4, 0);
-    return _nameOffset;
-  }
-
-  @override
-  List<idl.LinkedNodeUnit> get units {
-    _units ??= const fb.ListReader<idl.LinkedNodeUnit>(_LinkedNodeUnitReader())
-        .vTableGet(_bc, _bcOffset, 1, const <idl.LinkedNodeUnit>[]);
-    return _units;
-  }
-
-  @override
-  String get uriStr {
-    _uriStr ??= const fb.StringReader().vTableGet(_bc, _bcOffset, 0, '');
-    return _uriStr;
-  }
-}
-
-abstract class _LinkedNodeLibraryMixin implements idl.LinkedNodeLibrary {
-  @override
-  Map<String, Object> toJson() {
-    Map<String, Object> _result = <String, Object>{};
-    if (exports.isNotEmpty) {
-      _result["exports"] = exports;
-    }
-    if (name != '') {
-      _result["name"] = name;
-    }
-    if (nameLength != 0) {
-      _result["nameLength"] = nameLength;
-    }
-    if (nameOffset != 0) {
-      _result["nameOffset"] = nameOffset;
-    }
-    if (units.isNotEmpty) {
-      _result["units"] = units.map((_value) => _value.toJson()).toList();
-    }
-    if (uriStr != '') {
-      _result["uriStr"] = uriStr;
-    }
-    return _result;
-  }
-
-  @override
-  Map<String, Object> toMap() => {
-        "exports": exports,
-        "name": name,
-        "nameLength": nameLength,
-        "nameOffset": nameOffset,
-        "units": units,
-        "uriStr": uriStr,
-      };
-
-  @override
-  String toString() => convert.json.encode(toJson());
-}
-
-class LinkedNodeReferencesBuilder extends Object
-    with _LinkedNodeReferencesMixin
-    implements idl.LinkedNodeReferences {
-  List<String> _name;
-  List<int> _parent;
-
-  @override
-  List<String> get name => _name ??= <String>[];
-
-  set name(List<String> value) {
-    this._name = value;
-  }
-
-  @override
-  List<int> get parent => _parent ??= <int>[];
-
-  set parent(List<int> value) {
-    assert(value == null || value.every((e) => e >= 0));
-    this._parent = value;
-  }
-
-  LinkedNodeReferencesBuilder({List<String> name, List<int> parent})
-      : _name = name,
-        _parent = parent;
-
-  /// Flush [informative] data recursively.
-  void flushInformative() {}
-
-  /// Accumulate non-[informative] data into [signature].
-  void collectApiSignature(api_sig.ApiSignature signature) {
-    if (this._parent == null) {
-      signature.addInt(0);
-    } else {
-      signature.addInt(this._parent.length);
-      for (var x in this._parent) {
-        signature.addInt(x);
-      }
-    }
-    if (this._name == null) {
-      signature.addInt(0);
-    } else {
-      signature.addInt(this._name.length);
-      for (var x in this._name) {
-        signature.addString(x);
-      }
-    }
-  }
-
-  fb.Offset finish(fb.Builder fbBuilder) {
-    fb.Offset offset_name;
-    fb.Offset offset_parent;
-    if (!(_name == null || _name.isEmpty)) {
-      offset_name = fbBuilder
-          .writeList(_name.map((b) => fbBuilder.writeString(b)).toList());
-    }
-    if (!(_parent == null || _parent.isEmpty)) {
-      offset_parent = fbBuilder.writeListUint32(_parent);
-    }
-    fbBuilder.startTable();
-    if (offset_name != null) {
-      fbBuilder.addOffset(1, offset_name);
-    }
-    if (offset_parent != null) {
-      fbBuilder.addOffset(0, offset_parent);
-    }
-    return fbBuilder.endTable();
-  }
-}
-
-class _LinkedNodeReferencesReader
-    extends fb.TableReader<_LinkedNodeReferencesImpl> {
-  const _LinkedNodeReferencesReader();
-
-  @override
-  _LinkedNodeReferencesImpl createObject(fb.BufferContext bc, int offset) =>
-      _LinkedNodeReferencesImpl(bc, offset);
-}
-
-class _LinkedNodeReferencesImpl extends Object
-    with _LinkedNodeReferencesMixin
-    implements idl.LinkedNodeReferences {
-  final fb.BufferContext _bc;
-  final int _bcOffset;
-
-  _LinkedNodeReferencesImpl(this._bc, this._bcOffset);
-
-  List<String> _name;
-  List<int> _parent;
-
-  @override
-  List<String> get name {
-    _name ??= const fb.ListReader<String>(fb.StringReader())
-        .vTableGet(_bc, _bcOffset, 1, const <String>[]);
-    return _name;
-  }
-
-  @override
-  List<int> get parent {
-    _parent ??=
-        const fb.Uint32ListReader().vTableGet(_bc, _bcOffset, 0, const <int>[]);
-    return _parent;
-  }
-}
-
-abstract class _LinkedNodeReferencesMixin implements idl.LinkedNodeReferences {
-  @override
-  Map<String, Object> toJson() {
-    Map<String, Object> _result = <String, Object>{};
-    if (name.isNotEmpty) {
-      _result["name"] = name;
-    }
-    if (parent.isNotEmpty) {
-      _result["parent"] = parent;
-    }
-    return _result;
-  }
-
-  @override
-  Map<String, Object> toMap() => {
-        "name": name,
-        "parent": parent,
-      };
-
-  @override
-  String toString() => convert.json.encode(toJson());
-}
-
-class LinkedNodeTypeBuilder extends Object
-    with _LinkedNodeTypeMixin
-    implements idl.LinkedNodeType {
-  List<LinkedNodeTypeFormalParameterBuilder> _functionFormalParameters;
-  LinkedNodeTypeBuilder _functionReturnType;
-  int _functionTypedef;
-  List<LinkedNodeTypeBuilder> _functionTypedefTypeArguments;
-  List<LinkedNodeTypeTypeParameterBuilder> _functionTypeParameters;
-  int _interfaceClass;
-  List<LinkedNodeTypeBuilder> _interfaceTypeArguments;
-  idl.LinkedNodeTypeKind _kind;
-  idl.EntityRefNullabilitySuffix _nullabilitySuffix;
-  int _typeParameterElement;
-  int _typeParameterId;
-
-  @override
-  List<LinkedNodeTypeFormalParameterBuilder> get functionFormalParameters =>
-      _functionFormalParameters ??= <LinkedNodeTypeFormalParameterBuilder>[];
-
-  set functionFormalParameters(
-      List<LinkedNodeTypeFormalParameterBuilder> value) {
-    this._functionFormalParameters = value;
-  }
-
-  @override
-  LinkedNodeTypeBuilder get functionReturnType => _functionReturnType;
-
-  set functionReturnType(LinkedNodeTypeBuilder value) {
-    this._functionReturnType = value;
-  }
-
-  @override
-  int get functionTypedef => _functionTypedef ??= 0;
-
-  /// The typedef this function type is created for.
-  set functionTypedef(int value) {
-    assert(value == null || value >= 0);
-    this._functionTypedef = value;
-  }
-
-  @override
-  List<LinkedNodeTypeBuilder> get functionTypedefTypeArguments =>
-      _functionTypedefTypeArguments ??= <LinkedNodeTypeBuilder>[];
-
-  set functionTypedefTypeArguments(List<LinkedNodeTypeBuilder> value) {
-    this._functionTypedefTypeArguments = value;
-  }
-
-  @override
-  List<LinkedNodeTypeTypeParameterBuilder> get functionTypeParameters =>
-      _functionTypeParameters ??= <LinkedNodeTypeTypeParameterBuilder>[];
-
-  set functionTypeParameters(List<LinkedNodeTypeTypeParameterBuilder> value) {
-    this._functionTypeParameters = value;
-  }
-
-  @override
-  int get interfaceClass => _interfaceClass ??= 0;
-
-  /// Reference to a [LinkedNodeReferences].
-  set interfaceClass(int value) {
-    assert(value == null || value >= 0);
-    this._interfaceClass = value;
-  }
-
-  @override
-  List<LinkedNodeTypeBuilder> get interfaceTypeArguments =>
-      _interfaceTypeArguments ??= <LinkedNodeTypeBuilder>[];
-
-  set interfaceTypeArguments(List<LinkedNodeTypeBuilder> value) {
-    this._interfaceTypeArguments = value;
-  }
-
-  @override
-  idl.LinkedNodeTypeKind get kind => _kind ??= idl.LinkedNodeTypeKind.dynamic_;
-
-  set kind(idl.LinkedNodeTypeKind value) {
-    this._kind = value;
-  }
-
-  @override
-  idl.EntityRefNullabilitySuffix get nullabilitySuffix =>
-      _nullabilitySuffix ??= idl.EntityRefNullabilitySuffix.starOrIrrelevant;
-
-  set nullabilitySuffix(idl.EntityRefNullabilitySuffix value) {
-    this._nullabilitySuffix = value;
-  }
-
-  @override
-  int get typeParameterElement => _typeParameterElement ??= 0;
-
-  set typeParameterElement(int value) {
-    assert(value == null || value >= 0);
-    this._typeParameterElement = value;
-  }
-
-  @override
-  int get typeParameterId => _typeParameterId ??= 0;
-
-  set typeParameterId(int value) {
-    assert(value == null || value >= 0);
-    this._typeParameterId = value;
-  }
-
-  LinkedNodeTypeBuilder(
-      {List<LinkedNodeTypeFormalParameterBuilder> functionFormalParameters,
-      LinkedNodeTypeBuilder functionReturnType,
-      int functionTypedef,
-      List<LinkedNodeTypeBuilder> functionTypedefTypeArguments,
-      List<LinkedNodeTypeTypeParameterBuilder> functionTypeParameters,
-      int interfaceClass,
-      List<LinkedNodeTypeBuilder> interfaceTypeArguments,
-      idl.LinkedNodeTypeKind kind,
-      idl.EntityRefNullabilitySuffix nullabilitySuffix,
-      int typeParameterElement,
-      int typeParameterId})
-      : _functionFormalParameters = functionFormalParameters,
-        _functionReturnType = functionReturnType,
-        _functionTypedef = functionTypedef,
-        _functionTypedefTypeArguments = functionTypedefTypeArguments,
-        _functionTypeParameters = functionTypeParameters,
-        _interfaceClass = interfaceClass,
-        _interfaceTypeArguments = interfaceTypeArguments,
-        _kind = kind,
-        _nullabilitySuffix = nullabilitySuffix,
-        _typeParameterElement = typeParameterElement,
-        _typeParameterId = typeParameterId;
-
-  /// Flush [informative] data recursively.
-  void flushInformative() {
-    _functionFormalParameters?.forEach((b) => b.flushInformative());
-    _functionReturnType?.flushInformative();
-    _functionTypedefTypeArguments?.forEach((b) => b.flushInformative());
-    _functionTypeParameters?.forEach((b) => b.flushInformative());
-    _interfaceTypeArguments?.forEach((b) => b.flushInformative());
-  }
-
-  /// Accumulate non-[informative] data into [signature].
-  void collectApiSignature(api_sig.ApiSignature signature) {
-    if (this._functionFormalParameters == null) {
-      signature.addInt(0);
-    } else {
-      signature.addInt(this._functionFormalParameters.length);
-      for (var x in this._functionFormalParameters) {
-        x?.collectApiSignature(signature);
-      }
-    }
-    signature.addBool(this._functionReturnType != null);
-    this._functionReturnType?.collectApiSignature(signature);
-    if (this._functionTypeParameters == null) {
-      signature.addInt(0);
-    } else {
-      signature.addInt(this._functionTypeParameters.length);
-      for (var x in this._functionTypeParameters) {
-        x?.collectApiSignature(signature);
-      }
-    }
-    signature.addInt(this._interfaceClass ?? 0);
-    if (this._interfaceTypeArguments == null) {
-      signature.addInt(0);
-    } else {
-      signature.addInt(this._interfaceTypeArguments.length);
-      for (var x in this._interfaceTypeArguments) {
-        x?.collectApiSignature(signature);
-      }
-    }
-    signature.addInt(this._kind == null ? 0 : this._kind.index);
-    signature.addInt(this._typeParameterElement ?? 0);
-    signature.addInt(this._typeParameterId ?? 0);
-    signature.addInt(
-        this._nullabilitySuffix == null ? 0 : this._nullabilitySuffix.index);
-    signature.addInt(this._functionTypedef ?? 0);
-    if (this._functionTypedefTypeArguments == null) {
-      signature.addInt(0);
-    } else {
-      signature.addInt(this._functionTypedefTypeArguments.length);
-      for (var x in this._functionTypedefTypeArguments) {
-        x?.collectApiSignature(signature);
-      }
-    }
-  }
-
-  fb.Offset finish(fb.Builder fbBuilder) {
-    fb.Offset offset_functionFormalParameters;
-    fb.Offset offset_functionReturnType;
-    fb.Offset offset_functionTypedefTypeArguments;
-    fb.Offset offset_functionTypeParameters;
-    fb.Offset offset_interfaceTypeArguments;
-    if (!(_functionFormalParameters == null ||
-        _functionFormalParameters.isEmpty)) {
-      offset_functionFormalParameters = fbBuilder.writeList(
-          _functionFormalParameters.map((b) => b.finish(fbBuilder)).toList());
-    }
-    if (_functionReturnType != null) {
-      offset_functionReturnType = _functionReturnType.finish(fbBuilder);
-    }
-    if (!(_functionTypedefTypeArguments == null ||
-        _functionTypedefTypeArguments.isEmpty)) {
-      offset_functionTypedefTypeArguments = fbBuilder.writeList(
-          _functionTypedefTypeArguments
-              .map((b) => b.finish(fbBuilder))
-              .toList());
-    }
-    if (!(_functionTypeParameters == null || _functionTypeParameters.isEmpty)) {
-      offset_functionTypeParameters = fbBuilder.writeList(
-          _functionTypeParameters.map((b) => b.finish(fbBuilder)).toList());
-    }
-    if (!(_interfaceTypeArguments == null || _interfaceTypeArguments.isEmpty)) {
-      offset_interfaceTypeArguments = fbBuilder.writeList(
-          _interfaceTypeArguments.map((b) => b.finish(fbBuilder)).toList());
-    }
-    fbBuilder.startTable();
-    if (offset_functionFormalParameters != null) {
-      fbBuilder.addOffset(0, offset_functionFormalParameters);
-    }
-    if (offset_functionReturnType != null) {
-      fbBuilder.addOffset(1, offset_functionReturnType);
-    }
-    if (_functionTypedef != null && _functionTypedef != 0) {
-      fbBuilder.addUint32(9, _functionTypedef);
-    }
-    if (offset_functionTypedefTypeArguments != null) {
-      fbBuilder.addOffset(10, offset_functionTypedefTypeArguments);
-    }
-    if (offset_functionTypeParameters != null) {
-      fbBuilder.addOffset(2, offset_functionTypeParameters);
-    }
-    if (_interfaceClass != null && _interfaceClass != 0) {
-      fbBuilder.addUint32(3, _interfaceClass);
-    }
-    if (offset_interfaceTypeArguments != null) {
-      fbBuilder.addOffset(4, offset_interfaceTypeArguments);
-    }
-    if (_kind != null && _kind != idl.LinkedNodeTypeKind.dynamic_) {
-      fbBuilder.addUint8(5, _kind.index);
-    }
-    if (_nullabilitySuffix != null &&
-        _nullabilitySuffix != idl.EntityRefNullabilitySuffix.starOrIrrelevant) {
-      fbBuilder.addUint8(8, _nullabilitySuffix.index);
-    }
-    if (_typeParameterElement != null && _typeParameterElement != 0) {
-      fbBuilder.addUint32(6, _typeParameterElement);
-    }
-    if (_typeParameterId != null && _typeParameterId != 0) {
-      fbBuilder.addUint32(7, _typeParameterId);
-    }
-    return fbBuilder.endTable();
-  }
-}
-
-class _LinkedNodeTypeReader extends fb.TableReader<_LinkedNodeTypeImpl> {
-  const _LinkedNodeTypeReader();
-
-  @override
-  _LinkedNodeTypeImpl createObject(fb.BufferContext bc, int offset) =>
-      _LinkedNodeTypeImpl(bc, offset);
-}
-
-class _LinkedNodeTypeImpl extends Object
-    with _LinkedNodeTypeMixin
-    implements idl.LinkedNodeType {
-  final fb.BufferContext _bc;
-  final int _bcOffset;
-
-  _LinkedNodeTypeImpl(this._bc, this._bcOffset);
-
-  List<idl.LinkedNodeTypeFormalParameter> _functionFormalParameters;
-  idl.LinkedNodeType _functionReturnType;
-  int _functionTypedef;
-  List<idl.LinkedNodeType> _functionTypedefTypeArguments;
-  List<idl.LinkedNodeTypeTypeParameter> _functionTypeParameters;
-  int _interfaceClass;
-  List<idl.LinkedNodeType> _interfaceTypeArguments;
-  idl.LinkedNodeTypeKind _kind;
-  idl.EntityRefNullabilitySuffix _nullabilitySuffix;
-  int _typeParameterElement;
-  int _typeParameterId;
-
-  @override
-  List<idl.LinkedNodeTypeFormalParameter> get functionFormalParameters {
-    _functionFormalParameters ??=
-        const fb.ListReader<idl.LinkedNodeTypeFormalParameter>(
-                _LinkedNodeTypeFormalParameterReader())
-            .vTableGet(
-                _bc, _bcOffset, 0, const <idl.LinkedNodeTypeFormalParameter>[]);
-    return _functionFormalParameters;
-  }
-
-  @override
-  idl.LinkedNodeType get functionReturnType {
-    _functionReturnType ??=
-        const _LinkedNodeTypeReader().vTableGet(_bc, _bcOffset, 1, null);
-    return _functionReturnType;
-  }
-
-  @override
-  int get functionTypedef {
-    _functionTypedef ??=
-        const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 9, 0);
-    return _functionTypedef;
-  }
-
-  @override
-  List<idl.LinkedNodeType> get functionTypedefTypeArguments {
-    _functionTypedefTypeArguments ??=
-        const fb.ListReader<idl.LinkedNodeType>(_LinkedNodeTypeReader())
-            .vTableGet(_bc, _bcOffset, 10, const <idl.LinkedNodeType>[]);
-    return _functionTypedefTypeArguments;
-  }
-
-  @override
-  List<idl.LinkedNodeTypeTypeParameter> get functionTypeParameters {
-    _functionTypeParameters ??=
-        const fb.ListReader<idl.LinkedNodeTypeTypeParameter>(
-                _LinkedNodeTypeTypeParameterReader())
-            .vTableGet(
-                _bc, _bcOffset, 2, const <idl.LinkedNodeTypeTypeParameter>[]);
-    return _functionTypeParameters;
-  }
-
-  @override
-  int get interfaceClass {
-    _interfaceClass ??= const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 3, 0);
-    return _interfaceClass;
-  }
-
-  @override
-  List<idl.LinkedNodeType> get interfaceTypeArguments {
-    _interfaceTypeArguments ??=
-        const fb.ListReader<idl.LinkedNodeType>(_LinkedNodeTypeReader())
-            .vTableGet(_bc, _bcOffset, 4, const <idl.LinkedNodeType>[]);
-    return _interfaceTypeArguments;
-  }
-
-  @override
-  idl.LinkedNodeTypeKind get kind {
-    _kind ??= const _LinkedNodeTypeKindReader()
-        .vTableGet(_bc, _bcOffset, 5, idl.LinkedNodeTypeKind.dynamic_);
-    return _kind;
-  }
-
-  @override
-  idl.EntityRefNullabilitySuffix get nullabilitySuffix {
-    _nullabilitySuffix ??= const _EntityRefNullabilitySuffixReader().vTableGet(
-        _bc, _bcOffset, 8, idl.EntityRefNullabilitySuffix.starOrIrrelevant);
-    return _nullabilitySuffix;
-  }
-
-  @override
-  int get typeParameterElement {
-    _typeParameterElement ??=
-        const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 6, 0);
-    return _typeParameterElement;
-  }
-
-  @override
-  int get typeParameterId {
-    _typeParameterId ??=
-        const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 7, 0);
-    return _typeParameterId;
-  }
-}
-
-abstract class _LinkedNodeTypeMixin implements idl.LinkedNodeType {
-  @override
-  Map<String, Object> toJson() {
-    Map<String, Object> _result = <String, Object>{};
-    if (functionFormalParameters.isNotEmpty) {
-      _result["functionFormalParameters"] =
-          functionFormalParameters.map((_value) => _value.toJson()).toList();
-    }
-    if (functionReturnType != null) {
-      _result["functionReturnType"] = functionReturnType.toJson();
-    }
-    if (functionTypedef != 0) {
-      _result["functionTypedef"] = functionTypedef;
-    }
-    if (functionTypedefTypeArguments.isNotEmpty) {
-      _result["functionTypedefTypeArguments"] = functionTypedefTypeArguments
-          .map((_value) => _value.toJson())
-          .toList();
-    }
-    if (functionTypeParameters.isNotEmpty) {
-      _result["functionTypeParameters"] =
-          functionTypeParameters.map((_value) => _value.toJson()).toList();
-    }
-    if (interfaceClass != 0) {
-      _result["interfaceClass"] = interfaceClass;
-    }
-    if (interfaceTypeArguments.isNotEmpty) {
-      _result["interfaceTypeArguments"] =
-          interfaceTypeArguments.map((_value) => _value.toJson()).toList();
-    }
-    if (kind != idl.LinkedNodeTypeKind.dynamic_) {
-      _result["kind"] = kind.toString().split('.')[1];
-    }
-    if (nullabilitySuffix != idl.EntityRefNullabilitySuffix.starOrIrrelevant) {
-      _result["nullabilitySuffix"] = nullabilitySuffix.toString().split('.')[1];
-    }
-    if (typeParameterElement != 0) {
-      _result["typeParameterElement"] = typeParameterElement;
-    }
-    if (typeParameterId != 0) {
-      _result["typeParameterId"] = typeParameterId;
-    }
-    return _result;
-  }
-
-  @override
-  Map<String, Object> toMap() => {
-        "functionFormalParameters": functionFormalParameters,
-        "functionReturnType": functionReturnType,
-        "functionTypedef": functionTypedef,
-        "functionTypedefTypeArguments": functionTypedefTypeArguments,
-        "functionTypeParameters": functionTypeParameters,
-        "interfaceClass": interfaceClass,
-        "interfaceTypeArguments": interfaceTypeArguments,
-        "kind": kind,
-        "nullabilitySuffix": nullabilitySuffix,
-        "typeParameterElement": typeParameterElement,
-        "typeParameterId": typeParameterId,
-      };
-
-  @override
-  String toString() => convert.json.encode(toJson());
-}
-
-class LinkedNodeTypeFormalParameterBuilder extends Object
-    with _LinkedNodeTypeFormalParameterMixin
-    implements idl.LinkedNodeTypeFormalParameter {
-  idl.LinkedNodeFormalParameterKind _kind;
-  String _name;
-  LinkedNodeTypeBuilder _type;
-
-  @override
-  idl.LinkedNodeFormalParameterKind get kind =>
-      _kind ??= idl.LinkedNodeFormalParameterKind.requiredPositional;
-
-  set kind(idl.LinkedNodeFormalParameterKind value) {
-    this._kind = value;
-  }
-
-  @override
-  String get name => _name ??= '';
-
-  set name(String value) {
-    this._name = value;
-  }
-
-  @override
-  LinkedNodeTypeBuilder get type => _type;
-
-  set type(LinkedNodeTypeBuilder value) {
-    this._type = value;
-  }
-
-  LinkedNodeTypeFormalParameterBuilder(
-      {idl.LinkedNodeFormalParameterKind kind,
-      String name,
-      LinkedNodeTypeBuilder type})
-      : _kind = kind,
-        _name = name,
-        _type = type;
-
-  /// Flush [informative] data recursively.
-  void flushInformative() {
-    _type?.flushInformative();
-  }
-
-  /// Accumulate non-[informative] data into [signature].
-  void collectApiSignature(api_sig.ApiSignature signature) {
-    signature.addInt(this._kind == null ? 0 : this._kind.index);
-    signature.addString(this._name ?? '');
-    signature.addBool(this._type != null);
-    this._type?.collectApiSignature(signature);
-  }
-
-  fb.Offset finish(fb.Builder fbBuilder) {
-    fb.Offset offset_name;
-    fb.Offset offset_type;
-    if (_name != null) {
-      offset_name = fbBuilder.writeString(_name);
-    }
-    if (_type != null) {
-      offset_type = _type.finish(fbBuilder);
-    }
-    fbBuilder.startTable();
-    if (_kind != null &&
-        _kind != idl.LinkedNodeFormalParameterKind.requiredPositional) {
-      fbBuilder.addUint8(0, _kind.index);
-    }
-    if (offset_name != null) {
-      fbBuilder.addOffset(1, offset_name);
-    }
-    if (offset_type != null) {
-      fbBuilder.addOffset(2, offset_type);
-    }
-    return fbBuilder.endTable();
-  }
-}
-
-class _LinkedNodeTypeFormalParameterReader
-    extends fb.TableReader<_LinkedNodeTypeFormalParameterImpl> {
-  const _LinkedNodeTypeFormalParameterReader();
-
-  @override
-  _LinkedNodeTypeFormalParameterImpl createObject(
-          fb.BufferContext bc, int offset) =>
-      _LinkedNodeTypeFormalParameterImpl(bc, offset);
-}
-
-class _LinkedNodeTypeFormalParameterImpl extends Object
-    with _LinkedNodeTypeFormalParameterMixin
-    implements idl.LinkedNodeTypeFormalParameter {
-  final fb.BufferContext _bc;
-  final int _bcOffset;
-
-  _LinkedNodeTypeFormalParameterImpl(this._bc, this._bcOffset);
-
-  idl.LinkedNodeFormalParameterKind _kind;
-  String _name;
-  idl.LinkedNodeType _type;
-
-  @override
-  idl.LinkedNodeFormalParameterKind get kind {
-    _kind ??= const _LinkedNodeFormalParameterKindReader().vTableGet(_bc,
-        _bcOffset, 0, idl.LinkedNodeFormalParameterKind.requiredPositional);
-    return _kind;
-  }
-
-  @override
-  String get name {
-    _name ??= const fb.StringReader().vTableGet(_bc, _bcOffset, 1, '');
-    return _name;
-  }
-
-  @override
-  idl.LinkedNodeType get type {
-    _type ??= const _LinkedNodeTypeReader().vTableGet(_bc, _bcOffset, 2, null);
-    return _type;
-  }
-}
-
-abstract class _LinkedNodeTypeFormalParameterMixin
-    implements idl.LinkedNodeTypeFormalParameter {
-  @override
-  Map<String, Object> toJson() {
-    Map<String, Object> _result = <String, Object>{};
-    if (kind != idl.LinkedNodeFormalParameterKind.requiredPositional) {
-      _result["kind"] = kind.toString().split('.')[1];
-    }
-    if (name != '') {
-      _result["name"] = name;
-    }
-    if (type != null) {
-      _result["type"] = type.toJson();
-    }
-    return _result;
-  }
-
-  @override
-  Map<String, Object> toMap() => {
-        "kind": kind,
-        "name": name,
-        "type": type,
-      };
-
-  @override
-  String toString() => convert.json.encode(toJson());
-}
-
-class LinkedNodeTypeSubstitutionBuilder extends Object
-    with _LinkedNodeTypeSubstitutionMixin
-    implements idl.LinkedNodeTypeSubstitution {
-  bool _isLegacy;
-  List<LinkedNodeTypeBuilder> _typeArguments;
-  List<int> _typeParameters;
-
-  @override
-  bool get isLegacy => _isLegacy ??= false;
-
-  set isLegacy(bool value) {
-    this._isLegacy = value;
-  }
-
-  @override
-  List<LinkedNodeTypeBuilder> get typeArguments =>
-      _typeArguments ??= <LinkedNodeTypeBuilder>[];
-
-  set typeArguments(List<LinkedNodeTypeBuilder> value) {
-    this._typeArguments = value;
-  }
-
-  @override
-  List<int> get typeParameters => _typeParameters ??= <int>[];
-
-  set typeParameters(List<int> value) {
-    assert(value == null || value.every((e) => e >= 0));
-    this._typeParameters = value;
-  }
-
-  LinkedNodeTypeSubstitutionBuilder(
-      {bool isLegacy,
-      List<LinkedNodeTypeBuilder> typeArguments,
-      List<int> typeParameters})
-      : _isLegacy = isLegacy,
-        _typeArguments = typeArguments,
-        _typeParameters = typeParameters;
-
-  /// Flush [informative] data recursively.
-  void flushInformative() {
-    _typeArguments?.forEach((b) => b.flushInformative());
-  }
-
-  /// Accumulate non-[informative] data into [signature].
-  void collectApiSignature(api_sig.ApiSignature signature) {
-    if (this._typeParameters == null) {
-      signature.addInt(0);
-    } else {
-      signature.addInt(this._typeParameters.length);
-      for (var x in this._typeParameters) {
-        signature.addInt(x);
-      }
-    }
-    if (this._typeArguments == null) {
-      signature.addInt(0);
-    } else {
-      signature.addInt(this._typeArguments.length);
-      for (var x in this._typeArguments) {
-        x?.collectApiSignature(signature);
-      }
-    }
-    signature.addBool(this._isLegacy == true);
-  }
-
-  fb.Offset finish(fb.Builder fbBuilder) {
-    fb.Offset offset_typeArguments;
-    fb.Offset offset_typeParameters;
-    if (!(_typeArguments == null || _typeArguments.isEmpty)) {
-      offset_typeArguments = fbBuilder
-          .writeList(_typeArguments.map((b) => b.finish(fbBuilder)).toList());
-    }
-    if (!(_typeParameters == null || _typeParameters.isEmpty)) {
-      offset_typeParameters = fbBuilder.writeListUint32(_typeParameters);
-    }
-    fbBuilder.startTable();
-    if (_isLegacy == true) {
-      fbBuilder.addBool(2, true);
-    }
-    if (offset_typeArguments != null) {
-      fbBuilder.addOffset(1, offset_typeArguments);
-    }
-    if (offset_typeParameters != null) {
-      fbBuilder.addOffset(0, offset_typeParameters);
-    }
-    return fbBuilder.endTable();
-  }
-}
-
-class _LinkedNodeTypeSubstitutionReader
-    extends fb.TableReader<_LinkedNodeTypeSubstitutionImpl> {
-  const _LinkedNodeTypeSubstitutionReader();
-
-  @override
-  _LinkedNodeTypeSubstitutionImpl createObject(
-          fb.BufferContext bc, int offset) =>
-      _LinkedNodeTypeSubstitutionImpl(bc, offset);
-}
-
-class _LinkedNodeTypeSubstitutionImpl extends Object
-    with _LinkedNodeTypeSubstitutionMixin
-    implements idl.LinkedNodeTypeSubstitution {
-  final fb.BufferContext _bc;
-  final int _bcOffset;
-
-  _LinkedNodeTypeSubstitutionImpl(this._bc, this._bcOffset);
-
-  bool _isLegacy;
-  List<idl.LinkedNodeType> _typeArguments;
-  List<int> _typeParameters;
-
-  @override
-  bool get isLegacy {
-    _isLegacy ??= const fb.BoolReader().vTableGet(_bc, _bcOffset, 2, false);
-    return _isLegacy;
-  }
-
-  @override
-  List<idl.LinkedNodeType> get typeArguments {
-    _typeArguments ??=
-        const fb.ListReader<idl.LinkedNodeType>(_LinkedNodeTypeReader())
-            .vTableGet(_bc, _bcOffset, 1, const <idl.LinkedNodeType>[]);
-    return _typeArguments;
-  }
-
-  @override
-  List<int> get typeParameters {
-    _typeParameters ??=
-        const fb.Uint32ListReader().vTableGet(_bc, _bcOffset, 0, const <int>[]);
-    return _typeParameters;
-  }
-}
-
-abstract class _LinkedNodeTypeSubstitutionMixin
-    implements idl.LinkedNodeTypeSubstitution {
-  @override
-  Map<String, Object> toJson() {
-    Map<String, Object> _result = <String, Object>{};
-    if (isLegacy != false) {
-      _result["isLegacy"] = isLegacy;
-    }
-    if (typeArguments.isNotEmpty) {
-      _result["typeArguments"] =
-          typeArguments.map((_value) => _value.toJson()).toList();
-    }
-    if (typeParameters.isNotEmpty) {
-      _result["typeParameters"] = typeParameters;
-    }
-    return _result;
-  }
-
-  @override
-  Map<String, Object> toMap() => {
-        "isLegacy": isLegacy,
-        "typeArguments": typeArguments,
-        "typeParameters": typeParameters,
-      };
-
-  @override
-  String toString() => convert.json.encode(toJson());
-}
-
-class LinkedNodeTypeTypeParameterBuilder extends Object
-    with _LinkedNodeTypeTypeParameterMixin
-    implements idl.LinkedNodeTypeTypeParameter {
-  LinkedNodeTypeBuilder _bound;
-  String _name;
-
-  @override
-  LinkedNodeTypeBuilder get bound => _bound;
-
-  set bound(LinkedNodeTypeBuilder value) {
-    this._bound = value;
-  }
-
-  @override
-  String get name => _name ??= '';
-
-  set name(String value) {
-    this._name = value;
-  }
-
-  LinkedNodeTypeTypeParameterBuilder({LinkedNodeTypeBuilder bound, String name})
-      : _bound = bound,
-        _name = name;
-
-  /// Flush [informative] data recursively.
-  void flushInformative() {
-    _bound?.flushInformative();
-  }
-
-  /// Accumulate non-[informative] data into [signature].
-  void collectApiSignature(api_sig.ApiSignature signature) {
-    signature.addString(this._name ?? '');
-    signature.addBool(this._bound != null);
-    this._bound?.collectApiSignature(signature);
-  }
-
-  fb.Offset finish(fb.Builder fbBuilder) {
-    fb.Offset offset_bound;
-    fb.Offset offset_name;
-    if (_bound != null) {
-      offset_bound = _bound.finish(fbBuilder);
-    }
-    if (_name != null) {
-      offset_name = fbBuilder.writeString(_name);
-    }
-    fbBuilder.startTable();
-    if (offset_bound != null) {
-      fbBuilder.addOffset(1, offset_bound);
-    }
-    if (offset_name != null) {
-      fbBuilder.addOffset(0, offset_name);
-    }
-    return fbBuilder.endTable();
-  }
-}
-
-class _LinkedNodeTypeTypeParameterReader
-    extends fb.TableReader<_LinkedNodeTypeTypeParameterImpl> {
-  const _LinkedNodeTypeTypeParameterReader();
-
-  @override
-  _LinkedNodeTypeTypeParameterImpl createObject(
-          fb.BufferContext bc, int offset) =>
-      _LinkedNodeTypeTypeParameterImpl(bc, offset);
-}
-
-class _LinkedNodeTypeTypeParameterImpl extends Object
-    with _LinkedNodeTypeTypeParameterMixin
-    implements idl.LinkedNodeTypeTypeParameter {
-  final fb.BufferContext _bc;
-  final int _bcOffset;
-
-  _LinkedNodeTypeTypeParameterImpl(this._bc, this._bcOffset);
-
-  idl.LinkedNodeType _bound;
-  String _name;
-
-  @override
-  idl.LinkedNodeType get bound {
-    _bound ??= const _LinkedNodeTypeReader().vTableGet(_bc, _bcOffset, 1, null);
-    return _bound;
-  }
-
-  @override
-  String get name {
-    _name ??= const fb.StringReader().vTableGet(_bc, _bcOffset, 0, '');
-    return _name;
-  }
-}
-
-abstract class _LinkedNodeTypeTypeParameterMixin
-    implements idl.LinkedNodeTypeTypeParameter {
-  @override
-  Map<String, Object> toJson() {
-    Map<String, Object> _result = <String, Object>{};
-    if (bound != null) {
-      _result["bound"] = bound.toJson();
-    }
-    if (name != '') {
-      _result["name"] = name;
-    }
-    return _result;
-  }
-
-  @override
-  Map<String, Object> toMap() => {
-        "bound": bound,
-        "name": name,
-      };
-
-  @override
-  String toString() => convert.json.encode(toJson());
-}
-
-class LinkedNodeUnitBuilder extends Object
-    with _LinkedNodeUnitMixin
-    implements idl.LinkedNodeUnit {
-  bool _isSynthetic;
-  LinkedNodeBuilder _node;
-  String _partUriStr;
-  String _uriStr;
-
-  @override
-  bool get isSynthetic => _isSynthetic ??= false;
-
-  set isSynthetic(bool value) {
-    this._isSynthetic = value;
-  }
-
-  @override
-  LinkedNodeBuilder get node => _node;
-
-  set node(LinkedNodeBuilder value) {
-    this._node = value;
-  }
-
-  @override
-  String get partUriStr => _partUriStr ??= '';
-
-  /// If the unit is a part, the URI specified in the `part` directive.
-  /// Otherwise empty.
-  set partUriStr(String value) {
-    this._partUriStr = value;
-  }
-
-  @override
-  String get uriStr => _uriStr ??= '';
-
-  /// The absolute URI.
-  set uriStr(String value) {
-    this._uriStr = value;
-  }
-
-  LinkedNodeUnitBuilder(
-      {bool isSynthetic,
-      LinkedNodeBuilder node,
-      String partUriStr,
-      String uriStr})
-      : _isSynthetic = isSynthetic,
-        _node = node,
-        _partUriStr = partUriStr,
-        _uriStr = uriStr;
-
-  /// Flush [informative] data recursively.
-  void flushInformative() {
-    _node?.flushInformative();
-  }
-
-  /// Accumulate non-[informative] data into [signature].
-  void collectApiSignature(api_sig.ApiSignature signature) {
-    signature.addString(this._uriStr ?? '');
-    signature.addBool(this._node != null);
-    this._node?.collectApiSignature(signature);
-    signature.addBool(this._isSynthetic == true);
-    signature.addString(this._partUriStr ?? '');
-  }
-
-  fb.Offset finish(fb.Builder fbBuilder) {
-    fb.Offset offset_node;
-    fb.Offset offset_partUriStr;
-    fb.Offset offset_uriStr;
-    if (_node != null) {
-      offset_node = _node.finish(fbBuilder);
-    }
-    if (_partUriStr != null) {
-      offset_partUriStr = fbBuilder.writeString(_partUriStr);
-    }
-    if (_uriStr != null) {
-      offset_uriStr = fbBuilder.writeString(_uriStr);
-    }
-    fbBuilder.startTable();
-    if (_isSynthetic == true) {
-      fbBuilder.addBool(2, true);
-    }
-    if (offset_node != null) {
-      fbBuilder.addOffset(1, offset_node);
-    }
-    if (offset_partUriStr != null) {
-      fbBuilder.addOffset(3, offset_partUriStr);
-    }
-    if (offset_uriStr != null) {
-      fbBuilder.addOffset(0, offset_uriStr);
-    }
-    return fbBuilder.endTable();
-  }
-}
-
-class _LinkedNodeUnitReader extends fb.TableReader<_LinkedNodeUnitImpl> {
-  const _LinkedNodeUnitReader();
-
-  @override
-  _LinkedNodeUnitImpl createObject(fb.BufferContext bc, int offset) =>
-      _LinkedNodeUnitImpl(bc, offset);
-}
-
-class _LinkedNodeUnitImpl extends Object
-    with _LinkedNodeUnitMixin
-    implements idl.LinkedNodeUnit {
-  final fb.BufferContext _bc;
-  final int _bcOffset;
-
-  _LinkedNodeUnitImpl(this._bc, this._bcOffset);
-
-  bool _isSynthetic;
-  idl.LinkedNode _node;
-  String _partUriStr;
-  String _uriStr;
-
-  @override
-  bool get isSynthetic {
-    _isSynthetic ??= const fb.BoolReader().vTableGet(_bc, _bcOffset, 2, false);
-    return _isSynthetic;
-  }
-
-  @override
-  idl.LinkedNode get node {
-    _node ??= const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 1, null);
-    return _node;
-  }
-
-  @override
-  String get partUriStr {
-    _partUriStr ??= const fb.StringReader().vTableGet(_bc, _bcOffset, 3, '');
-    return _partUriStr;
-  }
-
-  @override
-  String get uriStr {
-    _uriStr ??= const fb.StringReader().vTableGet(_bc, _bcOffset, 0, '');
-    return _uriStr;
-  }
-}
-
-abstract class _LinkedNodeUnitMixin implements idl.LinkedNodeUnit {
-  @override
-  Map<String, Object> toJson() {
-    Map<String, Object> _result = <String, Object>{};
-    if (isSynthetic != false) {
-      _result["isSynthetic"] = isSynthetic;
-    }
-    if (node != null) {
-      _result["node"] = node.toJson();
-    }
-    if (partUriStr != '') {
-      _result["partUriStr"] = partUriStr;
-    }
-    if (uriStr != '') {
-      _result["uriStr"] = uriStr;
-    }
-    return _result;
-  }
-
-  @override
-  Map<String, Object> toMap() => {
-        "isSynthetic": isSynthetic,
-        "node": node,
-        "partUriStr": partUriStr,
-        "uriStr": uriStr,
-      };
-
-  @override
-  String toString() => convert.json.encode(toJson());
-}
-
 class PackageBundleBuilder extends Object
     with _PackageBundleMixin
     implements idl.PackageBundle {
-  LinkedNodeBundleBuilder _bundle2;
-  PackageBundleSdkBuilder _sdk;
+  int _fake;
 
   @override
-  LinkedNodeBundleBuilder get bundle2 => _bundle2;
+  int get fake => _fake ??= 0;
 
   /// The version 2 of the summary.
-  set bundle2(LinkedNodeBundleBuilder value) {
-    this._bundle2 = value;
+  set fake(int value) {
+    assert(value == null || value >= 0);
+    this._fake = value;
   }
 
-  @override
-  PackageBundleSdkBuilder get sdk => _sdk;
-
-  /// The SDK specific data, if this bundle is for SDK.
-  set sdk(PackageBundleSdkBuilder value) {
-    this._sdk = value;
-  }
-
-  PackageBundleBuilder(
-      {LinkedNodeBundleBuilder bundle2, PackageBundleSdkBuilder sdk})
-      : _bundle2 = bundle2,
-        _sdk = sdk;
+  PackageBundleBuilder({int fake}) : _fake = fake;
 
   /// Flush [informative] data recursively.
-  void flushInformative() {
-    _bundle2?.flushInformative();
-    _sdk?.flushInformative();
-  }
+  void flushInformative() {}
 
   /// Accumulate non-[informative] data into [signature].
   void collectApiSignature(api_sig.ApiSignature signature) {
-    signature.addBool(this._bundle2 != null);
-    this._bundle2?.collectApiSignature(signature);
-    signature.addBool(this._sdk != null);
-    this._sdk?.collectApiSignature(signature);
+    signature.addInt(this._fake ?? 0);
   }
 
   List<int> toBuffer() {
@@ -17724,20 +4001,9 @@
   }
 
   fb.Offset finish(fb.Builder fbBuilder) {
-    fb.Offset offset_bundle2;
-    fb.Offset offset_sdk;
-    if (_bundle2 != null) {
-      offset_bundle2 = _bundle2.finish(fbBuilder);
-    }
-    if (_sdk != null) {
-      offset_sdk = _sdk.finish(fbBuilder);
-    }
     fbBuilder.startTable();
-    if (offset_bundle2 != null) {
-      fbBuilder.addOffset(0, offset_bundle2);
-    }
-    if (offset_sdk != null) {
-      fbBuilder.addOffset(1, offset_sdk);
+    if (_fake != null && _fake != 0) {
+      fbBuilder.addUint32(0, _fake);
     }
     return fbBuilder.endTable();
   }
@@ -17764,20 +4030,12 @@
 
   _PackageBundleImpl(this._bc, this._bcOffset);
 
-  idl.LinkedNodeBundle _bundle2;
-  idl.PackageBundleSdk _sdk;
+  int _fake;
 
   @override
-  idl.LinkedNodeBundle get bundle2 {
-    _bundle2 ??=
-        const _LinkedNodeBundleReader().vTableGet(_bc, _bcOffset, 0, null);
-    return _bundle2;
-  }
-
-  @override
-  idl.PackageBundleSdk get sdk {
-    _sdk ??= const _PackageBundleSdkReader().vTableGet(_bc, _bcOffset, 1, null);
-    return _sdk;
+  int get fake {
+    _fake ??= const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 0, 0);
+    return _fake;
   }
 }
 
@@ -17785,1862 +4043,21 @@
   @override
   Map<String, Object> toJson() {
     Map<String, Object> _result = <String, Object>{};
-    if (bundle2 != null) {
-      _result["bundle2"] = bundle2.toJson();
-    }
-    if (sdk != null) {
-      _result["sdk"] = sdk.toJson();
+    if (fake != 0) {
+      _result["fake"] = fake;
     }
     return _result;
   }
 
   @override
   Map<String, Object> toMap() => {
-        "bundle2": bundle2,
-        "sdk": sdk,
+        "fake": fake,
       };
 
   @override
   String toString() => convert.json.encode(toJson());
 }
 
-class PackageBundleSdkBuilder extends Object
-    with _PackageBundleSdkMixin
-    implements idl.PackageBundleSdk {
-  String _allowedExperimentsJson;
-  LinkedLanguageVersionBuilder _languageVersion;
-
-  @override
-  String get allowedExperimentsJson => _allowedExperimentsJson ??= '';
-
-  /// The content of the `allowed_experiments.json` from SDK.
-  set allowedExperimentsJson(String value) {
-    this._allowedExperimentsJson = value;
-  }
-
-  @override
-  LinkedLanguageVersionBuilder get languageVersion => _languageVersion;
-
-  /// The language version of the SDK.
-  set languageVersion(LinkedLanguageVersionBuilder value) {
-    this._languageVersion = value;
-  }
-
-  PackageBundleSdkBuilder(
-      {String allowedExperimentsJson,
-      LinkedLanguageVersionBuilder languageVersion})
-      : _allowedExperimentsJson = allowedExperimentsJson,
-        _languageVersion = languageVersion;
-
-  /// Flush [informative] data recursively.
-  void flushInformative() {
-    _languageVersion?.flushInformative();
-  }
-
-  /// Accumulate non-[informative] data into [signature].
-  void collectApiSignature(api_sig.ApiSignature signature) {
-    signature.addString(this._allowedExperimentsJson ?? '');
-    signature.addBool(this._languageVersion != null);
-    this._languageVersion?.collectApiSignature(signature);
-  }
-
-  fb.Offset finish(fb.Builder fbBuilder) {
-    fb.Offset offset_allowedExperimentsJson;
-    fb.Offset offset_languageVersion;
-    if (_allowedExperimentsJson != null) {
-      offset_allowedExperimentsJson =
-          fbBuilder.writeString(_allowedExperimentsJson);
-    }
-    if (_languageVersion != null) {
-      offset_languageVersion = _languageVersion.finish(fbBuilder);
-    }
-    fbBuilder.startTable();
-    if (offset_allowedExperimentsJson != null) {
-      fbBuilder.addOffset(0, offset_allowedExperimentsJson);
-    }
-    if (offset_languageVersion != null) {
-      fbBuilder.addOffset(1, offset_languageVersion);
-    }
-    return fbBuilder.endTable();
-  }
-}
-
-class _PackageBundleSdkReader extends fb.TableReader<_PackageBundleSdkImpl> {
-  const _PackageBundleSdkReader();
-
-  @override
-  _PackageBundleSdkImpl createObject(fb.BufferContext bc, int offset) =>
-      _PackageBundleSdkImpl(bc, offset);
-}
-
-class _PackageBundleSdkImpl extends Object
-    with _PackageBundleSdkMixin
-    implements idl.PackageBundleSdk {
-  final fb.BufferContext _bc;
-  final int _bcOffset;
-
-  _PackageBundleSdkImpl(this._bc, this._bcOffset);
-
-  String _allowedExperimentsJson;
-  idl.LinkedLanguageVersion _languageVersion;
-
-  @override
-  String get allowedExperimentsJson {
-    _allowedExperimentsJson ??=
-        const fb.StringReader().vTableGet(_bc, _bcOffset, 0, '');
-    return _allowedExperimentsJson;
-  }
-
-  @override
-  idl.LinkedLanguageVersion get languageVersion {
-    _languageVersion ??=
-        const _LinkedLanguageVersionReader().vTableGet(_bc, _bcOffset, 1, null);
-    return _languageVersion;
-  }
-}
-
-abstract class _PackageBundleSdkMixin implements idl.PackageBundleSdk {
-  @override
-  Map<String, Object> toJson() {
-    Map<String, Object> _result = <String, Object>{};
-    if (allowedExperimentsJson != '') {
-      _result["allowedExperimentsJson"] = allowedExperimentsJson;
-    }
-    if (languageVersion != null) {
-      _result["languageVersion"] = languageVersion.toJson();
-    }
-    return _result;
-  }
-
-  @override
-  Map<String, Object> toMap() => {
-        "allowedExperimentsJson": allowedExperimentsJson,
-        "languageVersion": languageVersion,
-      };
-
-  @override
-  String toString() => convert.json.encode(toJson());
-}
-
-class TopLevelInferenceErrorBuilder extends Object
-    with _TopLevelInferenceErrorMixin
-    implements idl.TopLevelInferenceError {
-  List<String> _arguments;
-  idl.TopLevelInferenceErrorKind _kind;
-
-  @override
-  List<String> get arguments => _arguments ??= <String>[];
-
-  /// The [kind] specific arguments.
-  set arguments(List<String> value) {
-    this._arguments = value;
-  }
-
-  @override
-  idl.TopLevelInferenceErrorKind get kind =>
-      _kind ??= idl.TopLevelInferenceErrorKind.assignment;
-
-  /// The kind of the error.
-  set kind(idl.TopLevelInferenceErrorKind value) {
-    this._kind = value;
-  }
-
-  TopLevelInferenceErrorBuilder(
-      {List<String> arguments, idl.TopLevelInferenceErrorKind kind})
-      : _arguments = arguments,
-        _kind = kind;
-
-  /// Flush [informative] data recursively.
-  void flushInformative() {}
-
-  /// Accumulate non-[informative] data into [signature].
-  void collectApiSignature(api_sig.ApiSignature signature) {
-    signature.addInt(this._kind == null ? 0 : this._kind.index);
-    if (this._arguments == null) {
-      signature.addInt(0);
-    } else {
-      signature.addInt(this._arguments.length);
-      for (var x in this._arguments) {
-        signature.addString(x);
-      }
-    }
-  }
-
-  fb.Offset finish(fb.Builder fbBuilder) {
-    fb.Offset offset_arguments;
-    if (!(_arguments == null || _arguments.isEmpty)) {
-      offset_arguments = fbBuilder
-          .writeList(_arguments.map((b) => fbBuilder.writeString(b)).toList());
-    }
-    fbBuilder.startTable();
-    if (offset_arguments != null) {
-      fbBuilder.addOffset(1, offset_arguments);
-    }
-    if (_kind != null && _kind != idl.TopLevelInferenceErrorKind.assignment) {
-      fbBuilder.addUint8(0, _kind.index);
-    }
-    return fbBuilder.endTable();
-  }
-}
-
-class _TopLevelInferenceErrorReader
-    extends fb.TableReader<_TopLevelInferenceErrorImpl> {
-  const _TopLevelInferenceErrorReader();
-
-  @override
-  _TopLevelInferenceErrorImpl createObject(fb.BufferContext bc, int offset) =>
-      _TopLevelInferenceErrorImpl(bc, offset);
-}
-
-class _TopLevelInferenceErrorImpl extends Object
-    with _TopLevelInferenceErrorMixin
-    implements idl.TopLevelInferenceError {
-  final fb.BufferContext _bc;
-  final int _bcOffset;
-
-  _TopLevelInferenceErrorImpl(this._bc, this._bcOffset);
-
-  List<String> _arguments;
-  idl.TopLevelInferenceErrorKind _kind;
-
-  @override
-  List<String> get arguments {
-    _arguments ??= const fb.ListReader<String>(fb.StringReader())
-        .vTableGet(_bc, _bcOffset, 1, const <String>[]);
-    return _arguments;
-  }
-
-  @override
-  idl.TopLevelInferenceErrorKind get kind {
-    _kind ??= const _TopLevelInferenceErrorKindReader().vTableGet(
-        _bc, _bcOffset, 0, idl.TopLevelInferenceErrorKind.assignment);
-    return _kind;
-  }
-}
-
-abstract class _TopLevelInferenceErrorMixin
-    implements idl.TopLevelInferenceError {
-  @override
-  Map<String, Object> toJson() {
-    Map<String, Object> _result = <String, Object>{};
-    if (arguments.isNotEmpty) {
-      _result["arguments"] = arguments;
-    }
-    if (kind != idl.TopLevelInferenceErrorKind.assignment) {
-      _result["kind"] = kind.toString().split('.')[1];
-    }
-    return _result;
-  }
-
-  @override
-  Map<String, Object> toMap() => {
-        "arguments": arguments,
-        "kind": kind,
-      };
-
-  @override
-  String toString() => convert.json.encode(toJson());
-}
-
-class UnlinkedInformativeDataBuilder extends Object
-    with _UnlinkedInformativeDataMixin
-    implements idl.UnlinkedInformativeData {
-  int _variantField_2;
-  int _variantField_3;
-  int _variantField_9;
-  int _variantField_8;
-  List<int> _variantField_7;
-  int _variantField_6;
-  int _variantField_5;
-  String _variantField_10;
-  int _variantField_1;
-  List<String> _variantField_4;
-  idl.LinkedNodeKind _kind;
-
-  @override
-  int get codeLength {
-    assert(kind == idl.LinkedNodeKind.classDeclaration ||
-        kind == idl.LinkedNodeKind.classTypeAlias ||
-        kind == idl.LinkedNodeKind.compilationUnit ||
-        kind == idl.LinkedNodeKind.constructorDeclaration ||
-        kind == idl.LinkedNodeKind.defaultFormalParameter ||
-        kind == idl.LinkedNodeKind.enumConstantDeclaration ||
-        kind == idl.LinkedNodeKind.enumDeclaration ||
-        kind == idl.LinkedNodeKind.extensionDeclaration ||
-        kind == idl.LinkedNodeKind.fieldFormalParameter ||
-        kind == idl.LinkedNodeKind.functionDeclaration ||
-        kind == idl.LinkedNodeKind.functionTypeAlias ||
-        kind == idl.LinkedNodeKind.functionTypedFormalParameter ||
-        kind == idl.LinkedNodeKind.genericTypeAlias ||
-        kind == idl.LinkedNodeKind.methodDeclaration ||
-        kind == idl.LinkedNodeKind.mixinDeclaration ||
-        kind == idl.LinkedNodeKind.simpleFormalParameter ||
-        kind == idl.LinkedNodeKind.typeParameter ||
-        kind == idl.LinkedNodeKind.variableDeclaration);
-    return _variantField_2 ??= 0;
-  }
-
-  set codeLength(int value) {
-    assert(kind == idl.LinkedNodeKind.classDeclaration ||
-        kind == idl.LinkedNodeKind.classTypeAlias ||
-        kind == idl.LinkedNodeKind.compilationUnit ||
-        kind == idl.LinkedNodeKind.constructorDeclaration ||
-        kind == idl.LinkedNodeKind.defaultFormalParameter ||
-        kind == idl.LinkedNodeKind.enumConstantDeclaration ||
-        kind == idl.LinkedNodeKind.enumDeclaration ||
-        kind == idl.LinkedNodeKind.extensionDeclaration ||
-        kind == idl.LinkedNodeKind.fieldFormalParameter ||
-        kind == idl.LinkedNodeKind.functionDeclaration ||
-        kind == idl.LinkedNodeKind.functionTypeAlias ||
-        kind == idl.LinkedNodeKind.functionTypedFormalParameter ||
-        kind == idl.LinkedNodeKind.genericTypeAlias ||
-        kind == idl.LinkedNodeKind.methodDeclaration ||
-        kind == idl.LinkedNodeKind.mixinDeclaration ||
-        kind == idl.LinkedNodeKind.simpleFormalParameter ||
-        kind == idl.LinkedNodeKind.typeParameter ||
-        kind == idl.LinkedNodeKind.variableDeclaration);
-    assert(value == null || value >= 0);
-    _variantField_2 = value;
-  }
-
-  @override
-  int get codeOffset {
-    assert(kind == idl.LinkedNodeKind.classDeclaration ||
-        kind == idl.LinkedNodeKind.classTypeAlias ||
-        kind == idl.LinkedNodeKind.compilationUnit ||
-        kind == idl.LinkedNodeKind.constructorDeclaration ||
-        kind == idl.LinkedNodeKind.defaultFormalParameter ||
-        kind == idl.LinkedNodeKind.enumConstantDeclaration ||
-        kind == idl.LinkedNodeKind.enumDeclaration ||
-        kind == idl.LinkedNodeKind.extensionDeclaration ||
-        kind == idl.LinkedNodeKind.fieldFormalParameter ||
-        kind == idl.LinkedNodeKind.functionDeclaration ||
-        kind == idl.LinkedNodeKind.functionTypeAlias ||
-        kind == idl.LinkedNodeKind.functionTypedFormalParameter ||
-        kind == idl.LinkedNodeKind.genericTypeAlias ||
-        kind == idl.LinkedNodeKind.methodDeclaration ||
-        kind == idl.LinkedNodeKind.mixinDeclaration ||
-        kind == idl.LinkedNodeKind.simpleFormalParameter ||
-        kind == idl.LinkedNodeKind.typeParameter ||
-        kind == idl.LinkedNodeKind.variableDeclaration);
-    return _variantField_3 ??= 0;
-  }
-
-  set codeOffset(int value) {
-    assert(kind == idl.LinkedNodeKind.classDeclaration ||
-        kind == idl.LinkedNodeKind.classTypeAlias ||
-        kind == idl.LinkedNodeKind.compilationUnit ||
-        kind == idl.LinkedNodeKind.constructorDeclaration ||
-        kind == idl.LinkedNodeKind.defaultFormalParameter ||
-        kind == idl.LinkedNodeKind.enumConstantDeclaration ||
-        kind == idl.LinkedNodeKind.enumDeclaration ||
-        kind == idl.LinkedNodeKind.extensionDeclaration ||
-        kind == idl.LinkedNodeKind.fieldFormalParameter ||
-        kind == idl.LinkedNodeKind.functionDeclaration ||
-        kind == idl.LinkedNodeKind.functionTypeAlias ||
-        kind == idl.LinkedNodeKind.functionTypedFormalParameter ||
-        kind == idl.LinkedNodeKind.genericTypeAlias ||
-        kind == idl.LinkedNodeKind.methodDeclaration ||
-        kind == idl.LinkedNodeKind.mixinDeclaration ||
-        kind == idl.LinkedNodeKind.simpleFormalParameter ||
-        kind == idl.LinkedNodeKind.typeParameter ||
-        kind == idl.LinkedNodeKind.variableDeclaration);
-    assert(value == null || value >= 0);
-    _variantField_3 = value;
-  }
-
-  @override
-  int get combinatorEnd {
-    assert(kind == idl.LinkedNodeKind.hideCombinator ||
-        kind == idl.LinkedNodeKind.showCombinator);
-    return _variantField_9 ??= 0;
-  }
-
-  set combinatorEnd(int value) {
-    assert(kind == idl.LinkedNodeKind.hideCombinator ||
-        kind == idl.LinkedNodeKind.showCombinator);
-    assert(value == null || value >= 0);
-    _variantField_9 = value;
-  }
-
-  @override
-  int get combinatorKeywordOffset {
-    assert(kind == idl.LinkedNodeKind.hideCombinator ||
-        kind == idl.LinkedNodeKind.showCombinator);
-    return _variantField_8 ??= 0;
-  }
-
-  @override
-  int get importDirective_prefixOffset {
-    assert(kind == idl.LinkedNodeKind.importDirective);
-    return _variantField_8 ??= 0;
-  }
-
-  set combinatorKeywordOffset(int value) {
-    assert(kind == idl.LinkedNodeKind.hideCombinator ||
-        kind == idl.LinkedNodeKind.showCombinator);
-    assert(value == null || value >= 0);
-    _variantField_8 = value;
-  }
-
-  set importDirective_prefixOffset(int value) {
-    assert(kind == idl.LinkedNodeKind.importDirective);
-    assert(value == null || value >= 0);
-    _variantField_8 = value;
-  }
-
-  @override
-  List<int> get compilationUnit_lineStarts {
-    assert(kind == idl.LinkedNodeKind.compilationUnit);
-    return _variantField_7 ??= <int>[];
-  }
-
-  /// Offsets of the first character of each line in the source code.
-  set compilationUnit_lineStarts(List<int> value) {
-    assert(kind == idl.LinkedNodeKind.compilationUnit);
-    assert(value == null || value.every((e) => e >= 0));
-    _variantField_7 = value;
-  }
-
-  @override
-  int get constructorDeclaration_periodOffset {
-    assert(kind == idl.LinkedNodeKind.constructorDeclaration);
-    return _variantField_6 ??= 0;
-  }
-
-  set constructorDeclaration_periodOffset(int value) {
-    assert(kind == idl.LinkedNodeKind.constructorDeclaration);
-    assert(value == null || value >= 0);
-    _variantField_6 = value;
-  }
-
-  @override
-  int get constructorDeclaration_returnTypeOffset {
-    assert(kind == idl.LinkedNodeKind.constructorDeclaration);
-    return _variantField_5 ??= 0;
-  }
-
-  set constructorDeclaration_returnTypeOffset(int value) {
-    assert(kind == idl.LinkedNodeKind.constructorDeclaration);
-    assert(value == null || value >= 0);
-    _variantField_5 = value;
-  }
-
-  @override
-  String get defaultFormalParameter_defaultValueCode {
-    assert(kind == idl.LinkedNodeKind.defaultFormalParameter);
-    return _variantField_10 ??= '';
-  }
-
-  /// If the parameter has a default value, the source text of the constant
-  /// expression in the default value.  Otherwise the empty string.
-  set defaultFormalParameter_defaultValueCode(String value) {
-    assert(kind == idl.LinkedNodeKind.defaultFormalParameter);
-    _variantField_10 = value;
-  }
-
-  @override
-  int get directiveKeywordOffset {
-    assert(kind == idl.LinkedNodeKind.exportDirective ||
-        kind == idl.LinkedNodeKind.importDirective ||
-        kind == idl.LinkedNodeKind.libraryDirective ||
-        kind == idl.LinkedNodeKind.partDirective ||
-        kind == idl.LinkedNodeKind.partOfDirective);
-    return _variantField_1 ??= 0;
-  }
-
-  @override
-  int get nameOffset {
-    assert(kind == idl.LinkedNodeKind.classDeclaration ||
-        kind == idl.LinkedNodeKind.classTypeAlias ||
-        kind == idl.LinkedNodeKind.constructorDeclaration ||
-        kind == idl.LinkedNodeKind.enumConstantDeclaration ||
-        kind == idl.LinkedNodeKind.enumDeclaration ||
-        kind == idl.LinkedNodeKind.extensionDeclaration ||
-        kind == idl.LinkedNodeKind.fieldFormalParameter ||
-        kind == idl.LinkedNodeKind.functionDeclaration ||
-        kind == idl.LinkedNodeKind.functionTypedFormalParameter ||
-        kind == idl.LinkedNodeKind.functionTypeAlias ||
-        kind == idl.LinkedNodeKind.genericTypeAlias ||
-        kind == idl.LinkedNodeKind.methodDeclaration ||
-        kind == idl.LinkedNodeKind.mixinDeclaration ||
-        kind == idl.LinkedNodeKind.simpleFormalParameter ||
-        kind == idl.LinkedNodeKind.typeParameter ||
-        kind == idl.LinkedNodeKind.variableDeclaration);
-    return _variantField_1 ??= 0;
-  }
-
-  set directiveKeywordOffset(int value) {
-    assert(kind == idl.LinkedNodeKind.exportDirective ||
-        kind == idl.LinkedNodeKind.importDirective ||
-        kind == idl.LinkedNodeKind.libraryDirective ||
-        kind == idl.LinkedNodeKind.partDirective ||
-        kind == idl.LinkedNodeKind.partOfDirective);
-    assert(value == null || value >= 0);
-    _variantField_1 = value;
-  }
-
-  set nameOffset(int value) {
-    assert(kind == idl.LinkedNodeKind.classDeclaration ||
-        kind == idl.LinkedNodeKind.classTypeAlias ||
-        kind == idl.LinkedNodeKind.constructorDeclaration ||
-        kind == idl.LinkedNodeKind.enumConstantDeclaration ||
-        kind == idl.LinkedNodeKind.enumDeclaration ||
-        kind == idl.LinkedNodeKind.extensionDeclaration ||
-        kind == idl.LinkedNodeKind.fieldFormalParameter ||
-        kind == idl.LinkedNodeKind.functionDeclaration ||
-        kind == idl.LinkedNodeKind.functionTypedFormalParameter ||
-        kind == idl.LinkedNodeKind.functionTypeAlias ||
-        kind == idl.LinkedNodeKind.genericTypeAlias ||
-        kind == idl.LinkedNodeKind.methodDeclaration ||
-        kind == idl.LinkedNodeKind.mixinDeclaration ||
-        kind == idl.LinkedNodeKind.simpleFormalParameter ||
-        kind == idl.LinkedNodeKind.typeParameter ||
-        kind == idl.LinkedNodeKind.variableDeclaration);
-    assert(value == null || value >= 0);
-    _variantField_1 = value;
-  }
-
-  @override
-  List<String> get documentationComment_tokens {
-    assert(kind == idl.LinkedNodeKind.classDeclaration ||
-        kind == idl.LinkedNodeKind.classTypeAlias ||
-        kind == idl.LinkedNodeKind.constructorDeclaration ||
-        kind == idl.LinkedNodeKind.enumDeclaration ||
-        kind == idl.LinkedNodeKind.enumConstantDeclaration ||
-        kind == idl.LinkedNodeKind.extensionDeclaration ||
-        kind == idl.LinkedNodeKind.fieldDeclaration ||
-        kind == idl.LinkedNodeKind.functionDeclaration ||
-        kind == idl.LinkedNodeKind.functionTypeAlias ||
-        kind == idl.LinkedNodeKind.genericTypeAlias ||
-        kind == idl.LinkedNodeKind.libraryDirective ||
-        kind == idl.LinkedNodeKind.methodDeclaration ||
-        kind == idl.LinkedNodeKind.mixinDeclaration ||
-        kind == idl.LinkedNodeKind.topLevelVariableDeclaration);
-    return _variantField_4 ??= <String>[];
-  }
-
-  set documentationComment_tokens(List<String> value) {
-    assert(kind == idl.LinkedNodeKind.classDeclaration ||
-        kind == idl.LinkedNodeKind.classTypeAlias ||
-        kind == idl.LinkedNodeKind.constructorDeclaration ||
-        kind == idl.LinkedNodeKind.enumDeclaration ||
-        kind == idl.LinkedNodeKind.enumConstantDeclaration ||
-        kind == idl.LinkedNodeKind.extensionDeclaration ||
-        kind == idl.LinkedNodeKind.fieldDeclaration ||
-        kind == idl.LinkedNodeKind.functionDeclaration ||
-        kind == idl.LinkedNodeKind.functionTypeAlias ||
-        kind == idl.LinkedNodeKind.genericTypeAlias ||
-        kind == idl.LinkedNodeKind.libraryDirective ||
-        kind == idl.LinkedNodeKind.methodDeclaration ||
-        kind == idl.LinkedNodeKind.mixinDeclaration ||
-        kind == idl.LinkedNodeKind.topLevelVariableDeclaration);
-    _variantField_4 = value;
-  }
-
-  @override
-  idl.LinkedNodeKind get kind => _kind ??= idl.LinkedNodeKind.adjacentStrings;
-
-  /// The kind of the node.
-  set kind(idl.LinkedNodeKind value) {
-    this._kind = value;
-  }
-
-  UnlinkedInformativeDataBuilder.classDeclaration({
-    int codeLength,
-    int codeOffset,
-    int nameOffset,
-    List<String> documentationComment_tokens,
-  })  : _kind = idl.LinkedNodeKind.classDeclaration,
-        _variantField_2 = codeLength,
-        _variantField_3 = codeOffset,
-        _variantField_1 = nameOffset,
-        _variantField_4 = documentationComment_tokens;
-
-  UnlinkedInformativeDataBuilder.classTypeAlias({
-    int codeLength,
-    int codeOffset,
-    int nameOffset,
-    List<String> documentationComment_tokens,
-  })  : _kind = idl.LinkedNodeKind.classTypeAlias,
-        _variantField_2 = codeLength,
-        _variantField_3 = codeOffset,
-        _variantField_1 = nameOffset,
-        _variantField_4 = documentationComment_tokens;
-
-  UnlinkedInformativeDataBuilder.compilationUnit({
-    int codeLength,
-    int codeOffset,
-    List<int> compilationUnit_lineStarts,
-  })  : _kind = idl.LinkedNodeKind.compilationUnit,
-        _variantField_2 = codeLength,
-        _variantField_3 = codeOffset,
-        _variantField_7 = compilationUnit_lineStarts;
-
-  UnlinkedInformativeDataBuilder.constructorDeclaration({
-    int codeLength,
-    int codeOffset,
-    int constructorDeclaration_periodOffset,
-    int constructorDeclaration_returnTypeOffset,
-    int nameOffset,
-    List<String> documentationComment_tokens,
-  })  : _kind = idl.LinkedNodeKind.constructorDeclaration,
-        _variantField_2 = codeLength,
-        _variantField_3 = codeOffset,
-        _variantField_6 = constructorDeclaration_periodOffset,
-        _variantField_5 = constructorDeclaration_returnTypeOffset,
-        _variantField_1 = nameOffset,
-        _variantField_4 = documentationComment_tokens;
-
-  UnlinkedInformativeDataBuilder.defaultFormalParameter({
-    int codeLength,
-    int codeOffset,
-    String defaultFormalParameter_defaultValueCode,
-  })  : _kind = idl.LinkedNodeKind.defaultFormalParameter,
-        _variantField_2 = codeLength,
-        _variantField_3 = codeOffset,
-        _variantField_10 = defaultFormalParameter_defaultValueCode;
-
-  UnlinkedInformativeDataBuilder.enumConstantDeclaration({
-    int codeLength,
-    int codeOffset,
-    int nameOffset,
-    List<String> documentationComment_tokens,
-  })  : _kind = idl.LinkedNodeKind.enumConstantDeclaration,
-        _variantField_2 = codeLength,
-        _variantField_3 = codeOffset,
-        _variantField_1 = nameOffset,
-        _variantField_4 = documentationComment_tokens;
-
-  UnlinkedInformativeDataBuilder.enumDeclaration({
-    int codeLength,
-    int codeOffset,
-    int nameOffset,
-    List<String> documentationComment_tokens,
-  })  : _kind = idl.LinkedNodeKind.enumDeclaration,
-        _variantField_2 = codeLength,
-        _variantField_3 = codeOffset,
-        _variantField_1 = nameOffset,
-        _variantField_4 = documentationComment_tokens;
-
-  UnlinkedInformativeDataBuilder.exportDirective({
-    int directiveKeywordOffset,
-  })  : _kind = idl.LinkedNodeKind.exportDirective,
-        _variantField_1 = directiveKeywordOffset;
-
-  UnlinkedInformativeDataBuilder.extensionDeclaration({
-    int codeLength,
-    int codeOffset,
-    int nameOffset,
-    List<String> documentationComment_tokens,
-  })  : _kind = idl.LinkedNodeKind.extensionDeclaration,
-        _variantField_2 = codeLength,
-        _variantField_3 = codeOffset,
-        _variantField_1 = nameOffset,
-        _variantField_4 = documentationComment_tokens;
-
-  UnlinkedInformativeDataBuilder.fieldDeclaration({
-    List<String> documentationComment_tokens,
-  })  : _kind = idl.LinkedNodeKind.fieldDeclaration,
-        _variantField_4 = documentationComment_tokens;
-
-  UnlinkedInformativeDataBuilder.fieldFormalParameter({
-    int codeLength,
-    int codeOffset,
-    int nameOffset,
-  })  : _kind = idl.LinkedNodeKind.fieldFormalParameter,
-        _variantField_2 = codeLength,
-        _variantField_3 = codeOffset,
-        _variantField_1 = nameOffset;
-
-  UnlinkedInformativeDataBuilder.functionDeclaration({
-    int codeLength,
-    int codeOffset,
-    int nameOffset,
-    List<String> documentationComment_tokens,
-  })  : _kind = idl.LinkedNodeKind.functionDeclaration,
-        _variantField_2 = codeLength,
-        _variantField_3 = codeOffset,
-        _variantField_1 = nameOffset,
-        _variantField_4 = documentationComment_tokens;
-
-  UnlinkedInformativeDataBuilder.functionTypeAlias({
-    int codeLength,
-    int codeOffset,
-    int nameOffset,
-    List<String> documentationComment_tokens,
-  })  : _kind = idl.LinkedNodeKind.functionTypeAlias,
-        _variantField_2 = codeLength,
-        _variantField_3 = codeOffset,
-        _variantField_1 = nameOffset,
-        _variantField_4 = documentationComment_tokens;
-
-  UnlinkedInformativeDataBuilder.functionTypedFormalParameter({
-    int codeLength,
-    int codeOffset,
-    int nameOffset,
-  })  : _kind = idl.LinkedNodeKind.functionTypedFormalParameter,
-        _variantField_2 = codeLength,
-        _variantField_3 = codeOffset,
-        _variantField_1 = nameOffset;
-
-  UnlinkedInformativeDataBuilder.genericTypeAlias({
-    int codeLength,
-    int codeOffset,
-    int nameOffset,
-    List<String> documentationComment_tokens,
-  })  : _kind = idl.LinkedNodeKind.genericTypeAlias,
-        _variantField_2 = codeLength,
-        _variantField_3 = codeOffset,
-        _variantField_1 = nameOffset,
-        _variantField_4 = documentationComment_tokens;
-
-  UnlinkedInformativeDataBuilder.hideCombinator({
-    int combinatorEnd,
-    int combinatorKeywordOffset,
-  })  : _kind = idl.LinkedNodeKind.hideCombinator,
-        _variantField_9 = combinatorEnd,
-        _variantField_8 = combinatorKeywordOffset;
-
-  UnlinkedInformativeDataBuilder.importDirective({
-    int importDirective_prefixOffset,
-    int directiveKeywordOffset,
-  })  : _kind = idl.LinkedNodeKind.importDirective,
-        _variantField_8 = importDirective_prefixOffset,
-        _variantField_1 = directiveKeywordOffset;
-
-  UnlinkedInformativeDataBuilder.libraryDirective({
-    int directiveKeywordOffset,
-    List<String> documentationComment_tokens,
-  })  : _kind = idl.LinkedNodeKind.libraryDirective,
-        _variantField_1 = directiveKeywordOffset,
-        _variantField_4 = documentationComment_tokens;
-
-  UnlinkedInformativeDataBuilder.methodDeclaration({
-    int codeLength,
-    int codeOffset,
-    int nameOffset,
-    List<String> documentationComment_tokens,
-  })  : _kind = idl.LinkedNodeKind.methodDeclaration,
-        _variantField_2 = codeLength,
-        _variantField_3 = codeOffset,
-        _variantField_1 = nameOffset,
-        _variantField_4 = documentationComment_tokens;
-
-  UnlinkedInformativeDataBuilder.mixinDeclaration({
-    int codeLength,
-    int codeOffset,
-    int nameOffset,
-    List<String> documentationComment_tokens,
-  })  : _kind = idl.LinkedNodeKind.mixinDeclaration,
-        _variantField_2 = codeLength,
-        _variantField_3 = codeOffset,
-        _variantField_1 = nameOffset,
-        _variantField_4 = documentationComment_tokens;
-
-  UnlinkedInformativeDataBuilder.partDirective({
-    int directiveKeywordOffset,
-  })  : _kind = idl.LinkedNodeKind.partDirective,
-        _variantField_1 = directiveKeywordOffset;
-
-  UnlinkedInformativeDataBuilder.partOfDirective({
-    int directiveKeywordOffset,
-  })  : _kind = idl.LinkedNodeKind.partOfDirective,
-        _variantField_1 = directiveKeywordOffset;
-
-  UnlinkedInformativeDataBuilder.showCombinator({
-    int combinatorEnd,
-    int combinatorKeywordOffset,
-  })  : _kind = idl.LinkedNodeKind.showCombinator,
-        _variantField_9 = combinatorEnd,
-        _variantField_8 = combinatorKeywordOffset;
-
-  UnlinkedInformativeDataBuilder.simpleFormalParameter({
-    int codeLength,
-    int codeOffset,
-    int nameOffset,
-  })  : _kind = idl.LinkedNodeKind.simpleFormalParameter,
-        _variantField_2 = codeLength,
-        _variantField_3 = codeOffset,
-        _variantField_1 = nameOffset;
-
-  UnlinkedInformativeDataBuilder.topLevelVariableDeclaration({
-    List<String> documentationComment_tokens,
-  })  : _kind = idl.LinkedNodeKind.topLevelVariableDeclaration,
-        _variantField_4 = documentationComment_tokens;
-
-  UnlinkedInformativeDataBuilder.typeParameter({
-    int codeLength,
-    int codeOffset,
-    int nameOffset,
-  })  : _kind = idl.LinkedNodeKind.typeParameter,
-        _variantField_2 = codeLength,
-        _variantField_3 = codeOffset,
-        _variantField_1 = nameOffset;
-
-  UnlinkedInformativeDataBuilder.variableDeclaration({
-    int codeLength,
-    int codeOffset,
-    int nameOffset,
-  })  : _kind = idl.LinkedNodeKind.variableDeclaration,
-        _variantField_2 = codeLength,
-        _variantField_3 = codeOffset,
-        _variantField_1 = nameOffset;
-
-  /// Flush [informative] data recursively.
-  void flushInformative() {
-    if (kind == idl.LinkedNodeKind.classDeclaration) {
-    } else if (kind == idl.LinkedNodeKind.classTypeAlias) {
-    } else if (kind == idl.LinkedNodeKind.compilationUnit) {
-    } else if (kind == idl.LinkedNodeKind.constructorDeclaration) {
-    } else if (kind == idl.LinkedNodeKind.defaultFormalParameter) {
-    } else if (kind == idl.LinkedNodeKind.enumConstantDeclaration) {
-    } else if (kind == idl.LinkedNodeKind.enumDeclaration) {
-    } else if (kind == idl.LinkedNodeKind.exportDirective) {
-    } else if (kind == idl.LinkedNodeKind.extensionDeclaration) {
-    } else if (kind == idl.LinkedNodeKind.fieldDeclaration) {
-    } else if (kind == idl.LinkedNodeKind.fieldFormalParameter) {
-    } else if (kind == idl.LinkedNodeKind.functionDeclaration) {
-    } else if (kind == idl.LinkedNodeKind.functionTypeAlias) {
-    } else if (kind == idl.LinkedNodeKind.functionTypedFormalParameter) {
-    } else if (kind == idl.LinkedNodeKind.genericTypeAlias) {
-    } else if (kind == idl.LinkedNodeKind.hideCombinator) {
-    } else if (kind == idl.LinkedNodeKind.importDirective) {
-    } else if (kind == idl.LinkedNodeKind.libraryDirective) {
-    } else if (kind == idl.LinkedNodeKind.methodDeclaration) {
-    } else if (kind == idl.LinkedNodeKind.mixinDeclaration) {
-    } else if (kind == idl.LinkedNodeKind.partDirective) {
-    } else if (kind == idl.LinkedNodeKind.partOfDirective) {
-    } else if (kind == idl.LinkedNodeKind.showCombinator) {
-    } else if (kind == idl.LinkedNodeKind.simpleFormalParameter) {
-    } else if (kind == idl.LinkedNodeKind.topLevelVariableDeclaration) {
-    } else if (kind == idl.LinkedNodeKind.typeParameter) {
-    } else if (kind == idl.LinkedNodeKind.variableDeclaration) {}
-  }
-
-  /// Accumulate non-[informative] data into [signature].
-  void collectApiSignature(api_sig.ApiSignature signature) {
-    if (kind == idl.LinkedNodeKind.classDeclaration) {
-      signature.addInt(this.kind == null ? 0 : this.kind.index);
-      signature.addInt(this.nameOffset ?? 0);
-      signature.addInt(this.codeLength ?? 0);
-      signature.addInt(this.codeOffset ?? 0);
-      if (this.documentationComment_tokens == null) {
-        signature.addInt(0);
-      } else {
-        signature.addInt(this.documentationComment_tokens.length);
-        for (var x in this.documentationComment_tokens) {
-          signature.addString(x);
-        }
-      }
-    } else if (kind == idl.LinkedNodeKind.classTypeAlias) {
-      signature.addInt(this.kind == null ? 0 : this.kind.index);
-      signature.addInt(this.nameOffset ?? 0);
-      signature.addInt(this.codeLength ?? 0);
-      signature.addInt(this.codeOffset ?? 0);
-      if (this.documentationComment_tokens == null) {
-        signature.addInt(0);
-      } else {
-        signature.addInt(this.documentationComment_tokens.length);
-        for (var x in this.documentationComment_tokens) {
-          signature.addString(x);
-        }
-      }
-    } else if (kind == idl.LinkedNodeKind.compilationUnit) {
-      signature.addInt(this.kind == null ? 0 : this.kind.index);
-      signature.addInt(this.codeLength ?? 0);
-      signature.addInt(this.codeOffset ?? 0);
-      if (this.compilationUnit_lineStarts == null) {
-        signature.addInt(0);
-      } else {
-        signature.addInt(this.compilationUnit_lineStarts.length);
-        for (var x in this.compilationUnit_lineStarts) {
-          signature.addInt(x);
-        }
-      }
-    } else if (kind == idl.LinkedNodeKind.constructorDeclaration) {
-      signature.addInt(this.kind == null ? 0 : this.kind.index);
-      signature.addInt(this.nameOffset ?? 0);
-      signature.addInt(this.codeLength ?? 0);
-      signature.addInt(this.codeOffset ?? 0);
-      if (this.documentationComment_tokens == null) {
-        signature.addInt(0);
-      } else {
-        signature.addInt(this.documentationComment_tokens.length);
-        for (var x in this.documentationComment_tokens) {
-          signature.addString(x);
-        }
-      }
-      signature.addInt(this.constructorDeclaration_returnTypeOffset ?? 0);
-      signature.addInt(this.constructorDeclaration_periodOffset ?? 0);
-    } else if (kind == idl.LinkedNodeKind.defaultFormalParameter) {
-      signature.addInt(this.kind == null ? 0 : this.kind.index);
-      signature.addInt(this.codeLength ?? 0);
-      signature.addInt(this.codeOffset ?? 0);
-      signature.addString(this.defaultFormalParameter_defaultValueCode ?? '');
-    } else if (kind == idl.LinkedNodeKind.enumConstantDeclaration) {
-      signature.addInt(this.kind == null ? 0 : this.kind.index);
-      signature.addInt(this.nameOffset ?? 0);
-      signature.addInt(this.codeLength ?? 0);
-      signature.addInt(this.codeOffset ?? 0);
-      if (this.documentationComment_tokens == null) {
-        signature.addInt(0);
-      } else {
-        signature.addInt(this.documentationComment_tokens.length);
-        for (var x in this.documentationComment_tokens) {
-          signature.addString(x);
-        }
-      }
-    } else if (kind == idl.LinkedNodeKind.enumDeclaration) {
-      signature.addInt(this.kind == null ? 0 : this.kind.index);
-      signature.addInt(this.nameOffset ?? 0);
-      signature.addInt(this.codeLength ?? 0);
-      signature.addInt(this.codeOffset ?? 0);
-      if (this.documentationComment_tokens == null) {
-        signature.addInt(0);
-      } else {
-        signature.addInt(this.documentationComment_tokens.length);
-        for (var x in this.documentationComment_tokens) {
-          signature.addString(x);
-        }
-      }
-    } else if (kind == idl.LinkedNodeKind.exportDirective) {
-      signature.addInt(this.kind == null ? 0 : this.kind.index);
-      signature.addInt(this.directiveKeywordOffset ?? 0);
-    } else if (kind == idl.LinkedNodeKind.extensionDeclaration) {
-      signature.addInt(this.kind == null ? 0 : this.kind.index);
-      signature.addInt(this.nameOffset ?? 0);
-      signature.addInt(this.codeLength ?? 0);
-      signature.addInt(this.codeOffset ?? 0);
-      if (this.documentationComment_tokens == null) {
-        signature.addInt(0);
-      } else {
-        signature.addInt(this.documentationComment_tokens.length);
-        for (var x in this.documentationComment_tokens) {
-          signature.addString(x);
-        }
-      }
-    } else if (kind == idl.LinkedNodeKind.fieldDeclaration) {
-      signature.addInt(this.kind == null ? 0 : this.kind.index);
-      if (this.documentationComment_tokens == null) {
-        signature.addInt(0);
-      } else {
-        signature.addInt(this.documentationComment_tokens.length);
-        for (var x in this.documentationComment_tokens) {
-          signature.addString(x);
-        }
-      }
-    } else if (kind == idl.LinkedNodeKind.fieldFormalParameter) {
-      signature.addInt(this.kind == null ? 0 : this.kind.index);
-      signature.addInt(this.nameOffset ?? 0);
-      signature.addInt(this.codeLength ?? 0);
-      signature.addInt(this.codeOffset ?? 0);
-    } else if (kind == idl.LinkedNodeKind.functionDeclaration) {
-      signature.addInt(this.kind == null ? 0 : this.kind.index);
-      signature.addInt(this.nameOffset ?? 0);
-      signature.addInt(this.codeLength ?? 0);
-      signature.addInt(this.codeOffset ?? 0);
-      if (this.documentationComment_tokens == null) {
-        signature.addInt(0);
-      } else {
-        signature.addInt(this.documentationComment_tokens.length);
-        for (var x in this.documentationComment_tokens) {
-          signature.addString(x);
-        }
-      }
-    } else if (kind == idl.LinkedNodeKind.functionTypeAlias) {
-      signature.addInt(this.kind == null ? 0 : this.kind.index);
-      signature.addInt(this.nameOffset ?? 0);
-      signature.addInt(this.codeLength ?? 0);
-      signature.addInt(this.codeOffset ?? 0);
-      if (this.documentationComment_tokens == null) {
-        signature.addInt(0);
-      } else {
-        signature.addInt(this.documentationComment_tokens.length);
-        for (var x in this.documentationComment_tokens) {
-          signature.addString(x);
-        }
-      }
-    } else if (kind == idl.LinkedNodeKind.functionTypedFormalParameter) {
-      signature.addInt(this.kind == null ? 0 : this.kind.index);
-      signature.addInt(this.nameOffset ?? 0);
-      signature.addInt(this.codeLength ?? 0);
-      signature.addInt(this.codeOffset ?? 0);
-    } else if (kind == idl.LinkedNodeKind.genericTypeAlias) {
-      signature.addInt(this.kind == null ? 0 : this.kind.index);
-      signature.addInt(this.nameOffset ?? 0);
-      signature.addInt(this.codeLength ?? 0);
-      signature.addInt(this.codeOffset ?? 0);
-      if (this.documentationComment_tokens == null) {
-        signature.addInt(0);
-      } else {
-        signature.addInt(this.documentationComment_tokens.length);
-        for (var x in this.documentationComment_tokens) {
-          signature.addString(x);
-        }
-      }
-    } else if (kind == idl.LinkedNodeKind.hideCombinator) {
-      signature.addInt(this.kind == null ? 0 : this.kind.index);
-      signature.addInt(this.combinatorKeywordOffset ?? 0);
-      signature.addInt(this.combinatorEnd ?? 0);
-    } else if (kind == idl.LinkedNodeKind.importDirective) {
-      signature.addInt(this.kind == null ? 0 : this.kind.index);
-      signature.addInt(this.directiveKeywordOffset ?? 0);
-      signature.addInt(this.importDirective_prefixOffset ?? 0);
-    } else if (kind == idl.LinkedNodeKind.libraryDirective) {
-      signature.addInt(this.kind == null ? 0 : this.kind.index);
-      signature.addInt(this.directiveKeywordOffset ?? 0);
-      if (this.documentationComment_tokens == null) {
-        signature.addInt(0);
-      } else {
-        signature.addInt(this.documentationComment_tokens.length);
-        for (var x in this.documentationComment_tokens) {
-          signature.addString(x);
-        }
-      }
-    } else if (kind == idl.LinkedNodeKind.methodDeclaration) {
-      signature.addInt(this.kind == null ? 0 : this.kind.index);
-      signature.addInt(this.nameOffset ?? 0);
-      signature.addInt(this.codeLength ?? 0);
-      signature.addInt(this.codeOffset ?? 0);
-      if (this.documentationComment_tokens == null) {
-        signature.addInt(0);
-      } else {
-        signature.addInt(this.documentationComment_tokens.length);
-        for (var x in this.documentationComment_tokens) {
-          signature.addString(x);
-        }
-      }
-    } else if (kind == idl.LinkedNodeKind.mixinDeclaration) {
-      signature.addInt(this.kind == null ? 0 : this.kind.index);
-      signature.addInt(this.nameOffset ?? 0);
-      signature.addInt(this.codeLength ?? 0);
-      signature.addInt(this.codeOffset ?? 0);
-      if (this.documentationComment_tokens == null) {
-        signature.addInt(0);
-      } else {
-        signature.addInt(this.documentationComment_tokens.length);
-        for (var x in this.documentationComment_tokens) {
-          signature.addString(x);
-        }
-      }
-    } else if (kind == idl.LinkedNodeKind.partDirective) {
-      signature.addInt(this.kind == null ? 0 : this.kind.index);
-      signature.addInt(this.directiveKeywordOffset ?? 0);
-    } else if (kind == idl.LinkedNodeKind.partOfDirective) {
-      signature.addInt(this.kind == null ? 0 : this.kind.index);
-      signature.addInt(this.directiveKeywordOffset ?? 0);
-    } else if (kind == idl.LinkedNodeKind.showCombinator) {
-      signature.addInt(this.kind == null ? 0 : this.kind.index);
-      signature.addInt(this.combinatorKeywordOffset ?? 0);
-      signature.addInt(this.combinatorEnd ?? 0);
-    } else if (kind == idl.LinkedNodeKind.simpleFormalParameter) {
-      signature.addInt(this.kind == null ? 0 : this.kind.index);
-      signature.addInt(this.nameOffset ?? 0);
-      signature.addInt(this.codeLength ?? 0);
-      signature.addInt(this.codeOffset ?? 0);
-    } else if (kind == idl.LinkedNodeKind.topLevelVariableDeclaration) {
-      signature.addInt(this.kind == null ? 0 : this.kind.index);
-      if (this.documentationComment_tokens == null) {
-        signature.addInt(0);
-      } else {
-        signature.addInt(this.documentationComment_tokens.length);
-        for (var x in this.documentationComment_tokens) {
-          signature.addString(x);
-        }
-      }
-    } else if (kind == idl.LinkedNodeKind.typeParameter) {
-      signature.addInt(this.kind == null ? 0 : this.kind.index);
-      signature.addInt(this.nameOffset ?? 0);
-      signature.addInt(this.codeLength ?? 0);
-      signature.addInt(this.codeOffset ?? 0);
-    } else if (kind == idl.LinkedNodeKind.variableDeclaration) {
-      signature.addInt(this.kind == null ? 0 : this.kind.index);
-      signature.addInt(this.nameOffset ?? 0);
-      signature.addInt(this.codeLength ?? 0);
-      signature.addInt(this.codeOffset ?? 0);
-    }
-  }
-
-  fb.Offset finish(fb.Builder fbBuilder) {
-    fb.Offset offset_variantField_7;
-    fb.Offset offset_variantField_10;
-    fb.Offset offset_variantField_4;
-    if (!(_variantField_7 == null || _variantField_7.isEmpty)) {
-      offset_variantField_7 = fbBuilder.writeListUint32(_variantField_7);
-    }
-    if (_variantField_10 != null) {
-      offset_variantField_10 = fbBuilder.writeString(_variantField_10);
-    }
-    if (!(_variantField_4 == null || _variantField_4.isEmpty)) {
-      offset_variantField_4 = fbBuilder.writeList(
-          _variantField_4.map((b) => fbBuilder.writeString(b)).toList());
-    }
-    fbBuilder.startTable();
-    if (_variantField_2 != null && _variantField_2 != 0) {
-      fbBuilder.addUint32(2, _variantField_2);
-    }
-    if (_variantField_3 != null && _variantField_3 != 0) {
-      fbBuilder.addUint32(3, _variantField_3);
-    }
-    if (_variantField_9 != null && _variantField_9 != 0) {
-      fbBuilder.addUint32(9, _variantField_9);
-    }
-    if (_variantField_8 != null && _variantField_8 != 0) {
-      fbBuilder.addUint32(8, _variantField_8);
-    }
-    if (offset_variantField_7 != null) {
-      fbBuilder.addOffset(7, offset_variantField_7);
-    }
-    if (_variantField_6 != null && _variantField_6 != 0) {
-      fbBuilder.addUint32(6, _variantField_6);
-    }
-    if (_variantField_5 != null && _variantField_5 != 0) {
-      fbBuilder.addUint32(5, _variantField_5);
-    }
-    if (offset_variantField_10 != null) {
-      fbBuilder.addOffset(10, offset_variantField_10);
-    }
-    if (_variantField_1 != null && _variantField_1 != 0) {
-      fbBuilder.addUint32(1, _variantField_1);
-    }
-    if (offset_variantField_4 != null) {
-      fbBuilder.addOffset(4, offset_variantField_4);
-    }
-    if (_kind != null && _kind != idl.LinkedNodeKind.adjacentStrings) {
-      fbBuilder.addUint8(0, _kind.index);
-    }
-    return fbBuilder.endTable();
-  }
-}
-
-class _UnlinkedInformativeDataReader
-    extends fb.TableReader<_UnlinkedInformativeDataImpl> {
-  const _UnlinkedInformativeDataReader();
-
-  @override
-  _UnlinkedInformativeDataImpl createObject(fb.BufferContext bc, int offset) =>
-      _UnlinkedInformativeDataImpl(bc, offset);
-}
-
-class _UnlinkedInformativeDataImpl extends Object
-    with _UnlinkedInformativeDataMixin
-    implements idl.UnlinkedInformativeData {
-  final fb.BufferContext _bc;
-  final int _bcOffset;
-
-  _UnlinkedInformativeDataImpl(this._bc, this._bcOffset);
-
-  int _variantField_2;
-  int _variantField_3;
-  int _variantField_9;
-  int _variantField_8;
-  List<int> _variantField_7;
-  int _variantField_6;
-  int _variantField_5;
-  String _variantField_10;
-  int _variantField_1;
-  List<String> _variantField_4;
-  idl.LinkedNodeKind _kind;
-
-  @override
-  int get codeLength {
-    assert(kind == idl.LinkedNodeKind.classDeclaration ||
-        kind == idl.LinkedNodeKind.classTypeAlias ||
-        kind == idl.LinkedNodeKind.compilationUnit ||
-        kind == idl.LinkedNodeKind.constructorDeclaration ||
-        kind == idl.LinkedNodeKind.defaultFormalParameter ||
-        kind == idl.LinkedNodeKind.enumConstantDeclaration ||
-        kind == idl.LinkedNodeKind.enumDeclaration ||
-        kind == idl.LinkedNodeKind.extensionDeclaration ||
-        kind == idl.LinkedNodeKind.fieldFormalParameter ||
-        kind == idl.LinkedNodeKind.functionDeclaration ||
-        kind == idl.LinkedNodeKind.functionTypeAlias ||
-        kind == idl.LinkedNodeKind.functionTypedFormalParameter ||
-        kind == idl.LinkedNodeKind.genericTypeAlias ||
-        kind == idl.LinkedNodeKind.methodDeclaration ||
-        kind == idl.LinkedNodeKind.mixinDeclaration ||
-        kind == idl.LinkedNodeKind.simpleFormalParameter ||
-        kind == idl.LinkedNodeKind.typeParameter ||
-        kind == idl.LinkedNodeKind.variableDeclaration);
-    _variantField_2 ??= const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 2, 0);
-    return _variantField_2;
-  }
-
-  @override
-  int get codeOffset {
-    assert(kind == idl.LinkedNodeKind.classDeclaration ||
-        kind == idl.LinkedNodeKind.classTypeAlias ||
-        kind == idl.LinkedNodeKind.compilationUnit ||
-        kind == idl.LinkedNodeKind.constructorDeclaration ||
-        kind == idl.LinkedNodeKind.defaultFormalParameter ||
-        kind == idl.LinkedNodeKind.enumConstantDeclaration ||
-        kind == idl.LinkedNodeKind.enumDeclaration ||
-        kind == idl.LinkedNodeKind.extensionDeclaration ||
-        kind == idl.LinkedNodeKind.fieldFormalParameter ||
-        kind == idl.LinkedNodeKind.functionDeclaration ||
-        kind == idl.LinkedNodeKind.functionTypeAlias ||
-        kind == idl.LinkedNodeKind.functionTypedFormalParameter ||
-        kind == idl.LinkedNodeKind.genericTypeAlias ||
-        kind == idl.LinkedNodeKind.methodDeclaration ||
-        kind == idl.LinkedNodeKind.mixinDeclaration ||
-        kind == idl.LinkedNodeKind.simpleFormalParameter ||
-        kind == idl.LinkedNodeKind.typeParameter ||
-        kind == idl.LinkedNodeKind.variableDeclaration);
-    _variantField_3 ??= const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 3, 0);
-    return _variantField_3;
-  }
-
-  @override
-  int get combinatorEnd {
-    assert(kind == idl.LinkedNodeKind.hideCombinator ||
-        kind == idl.LinkedNodeKind.showCombinator);
-    _variantField_9 ??= const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 9, 0);
-    return _variantField_9;
-  }
-
-  @override
-  int get combinatorKeywordOffset {
-    assert(kind == idl.LinkedNodeKind.hideCombinator ||
-        kind == idl.LinkedNodeKind.showCombinator);
-    _variantField_8 ??= const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 8, 0);
-    return _variantField_8;
-  }
-
-  @override
-  int get importDirective_prefixOffset {
-    assert(kind == idl.LinkedNodeKind.importDirective);
-    _variantField_8 ??= const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 8, 0);
-    return _variantField_8;
-  }
-
-  @override
-  List<int> get compilationUnit_lineStarts {
-    assert(kind == idl.LinkedNodeKind.compilationUnit);
-    _variantField_7 ??=
-        const fb.Uint32ListReader().vTableGet(_bc, _bcOffset, 7, const <int>[]);
-    return _variantField_7;
-  }
-
-  @override
-  int get constructorDeclaration_periodOffset {
-    assert(kind == idl.LinkedNodeKind.constructorDeclaration);
-    _variantField_6 ??= const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 6, 0);
-    return _variantField_6;
-  }
-
-  @override
-  int get constructorDeclaration_returnTypeOffset {
-    assert(kind == idl.LinkedNodeKind.constructorDeclaration);
-    _variantField_5 ??= const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 5, 0);
-    return _variantField_5;
-  }
-
-  @override
-  String get defaultFormalParameter_defaultValueCode {
-    assert(kind == idl.LinkedNodeKind.defaultFormalParameter);
-    _variantField_10 ??=
-        const fb.StringReader().vTableGet(_bc, _bcOffset, 10, '');
-    return _variantField_10;
-  }
-
-  @override
-  int get directiveKeywordOffset {
-    assert(kind == idl.LinkedNodeKind.exportDirective ||
-        kind == idl.LinkedNodeKind.importDirective ||
-        kind == idl.LinkedNodeKind.libraryDirective ||
-        kind == idl.LinkedNodeKind.partDirective ||
-        kind == idl.LinkedNodeKind.partOfDirective);
-    _variantField_1 ??= const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 1, 0);
-    return _variantField_1;
-  }
-
-  @override
-  int get nameOffset {
-    assert(kind == idl.LinkedNodeKind.classDeclaration ||
-        kind == idl.LinkedNodeKind.classTypeAlias ||
-        kind == idl.LinkedNodeKind.constructorDeclaration ||
-        kind == idl.LinkedNodeKind.enumConstantDeclaration ||
-        kind == idl.LinkedNodeKind.enumDeclaration ||
-        kind == idl.LinkedNodeKind.extensionDeclaration ||
-        kind == idl.LinkedNodeKind.fieldFormalParameter ||
-        kind == idl.LinkedNodeKind.functionDeclaration ||
-        kind == idl.LinkedNodeKind.functionTypedFormalParameter ||
-        kind == idl.LinkedNodeKind.functionTypeAlias ||
-        kind == idl.LinkedNodeKind.genericTypeAlias ||
-        kind == idl.LinkedNodeKind.methodDeclaration ||
-        kind == idl.LinkedNodeKind.mixinDeclaration ||
-        kind == idl.LinkedNodeKind.simpleFormalParameter ||
-        kind == idl.LinkedNodeKind.typeParameter ||
-        kind == idl.LinkedNodeKind.variableDeclaration);
-    _variantField_1 ??= const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 1, 0);
-    return _variantField_1;
-  }
-
-  @override
-  List<String> get documentationComment_tokens {
-    assert(kind == idl.LinkedNodeKind.classDeclaration ||
-        kind == idl.LinkedNodeKind.classTypeAlias ||
-        kind == idl.LinkedNodeKind.constructorDeclaration ||
-        kind == idl.LinkedNodeKind.enumDeclaration ||
-        kind == idl.LinkedNodeKind.enumConstantDeclaration ||
-        kind == idl.LinkedNodeKind.extensionDeclaration ||
-        kind == idl.LinkedNodeKind.fieldDeclaration ||
-        kind == idl.LinkedNodeKind.functionDeclaration ||
-        kind == idl.LinkedNodeKind.functionTypeAlias ||
-        kind == idl.LinkedNodeKind.genericTypeAlias ||
-        kind == idl.LinkedNodeKind.libraryDirective ||
-        kind == idl.LinkedNodeKind.methodDeclaration ||
-        kind == idl.LinkedNodeKind.mixinDeclaration ||
-        kind == idl.LinkedNodeKind.topLevelVariableDeclaration);
-    _variantField_4 ??= const fb.ListReader<String>(fb.StringReader())
-        .vTableGet(_bc, _bcOffset, 4, const <String>[]);
-    return _variantField_4;
-  }
-
-  @override
-  idl.LinkedNodeKind get kind {
-    _kind ??= const _LinkedNodeKindReader()
-        .vTableGet(_bc, _bcOffset, 0, idl.LinkedNodeKind.adjacentStrings);
-    return _kind;
-  }
-}
-
-abstract class _UnlinkedInformativeDataMixin
-    implements idl.UnlinkedInformativeData {
-  @override
-  Map<String, Object> toJson() {
-    Map<String, Object> _result = <String, Object>{};
-    if (kind != idl.LinkedNodeKind.adjacentStrings) {
-      _result["kind"] = kind.toString().split('.')[1];
-    }
-    if (kind == idl.LinkedNodeKind.classDeclaration) {
-      if (codeLength != 0) {
-        _result["codeLength"] = codeLength;
-      }
-      if (codeOffset != 0) {
-        _result["codeOffset"] = codeOffset;
-      }
-      if (nameOffset != 0) {
-        _result["nameOffset"] = nameOffset;
-      }
-      if (documentationComment_tokens.isNotEmpty) {
-        _result["documentationComment_tokens"] = documentationComment_tokens;
-      }
-    }
-    if (kind == idl.LinkedNodeKind.classTypeAlias) {
-      if (codeLength != 0) {
-        _result["codeLength"] = codeLength;
-      }
-      if (codeOffset != 0) {
-        _result["codeOffset"] = codeOffset;
-      }
-      if (nameOffset != 0) {
-        _result["nameOffset"] = nameOffset;
-      }
-      if (documentationComment_tokens.isNotEmpty) {
-        _result["documentationComment_tokens"] = documentationComment_tokens;
-      }
-    }
-    if (kind == idl.LinkedNodeKind.compilationUnit) {
-      if (codeLength != 0) {
-        _result["codeLength"] = codeLength;
-      }
-      if (codeOffset != 0) {
-        _result["codeOffset"] = codeOffset;
-      }
-      if (compilationUnit_lineStarts.isNotEmpty) {
-        _result["compilationUnit_lineStarts"] = compilationUnit_lineStarts;
-      }
-    }
-    if (kind == idl.LinkedNodeKind.constructorDeclaration) {
-      if (codeLength != 0) {
-        _result["codeLength"] = codeLength;
-      }
-      if (codeOffset != 0) {
-        _result["codeOffset"] = codeOffset;
-      }
-      if (constructorDeclaration_periodOffset != 0) {
-        _result["constructorDeclaration_periodOffset"] =
-            constructorDeclaration_periodOffset;
-      }
-      if (constructorDeclaration_returnTypeOffset != 0) {
-        _result["constructorDeclaration_returnTypeOffset"] =
-            constructorDeclaration_returnTypeOffset;
-      }
-      if (nameOffset != 0) {
-        _result["nameOffset"] = nameOffset;
-      }
-      if (documentationComment_tokens.isNotEmpty) {
-        _result["documentationComment_tokens"] = documentationComment_tokens;
-      }
-    }
-    if (kind == idl.LinkedNodeKind.defaultFormalParameter) {
-      if (codeLength != 0) {
-        _result["codeLength"] = codeLength;
-      }
-      if (codeOffset != 0) {
-        _result["codeOffset"] = codeOffset;
-      }
-      if (defaultFormalParameter_defaultValueCode != '') {
-        _result["defaultFormalParameter_defaultValueCode"] =
-            defaultFormalParameter_defaultValueCode;
-      }
-    }
-    if (kind == idl.LinkedNodeKind.enumConstantDeclaration) {
-      if (codeLength != 0) {
-        _result["codeLength"] = codeLength;
-      }
-      if (codeOffset != 0) {
-        _result["codeOffset"] = codeOffset;
-      }
-      if (nameOffset != 0) {
-        _result["nameOffset"] = nameOffset;
-      }
-      if (documentationComment_tokens.isNotEmpty) {
-        _result["documentationComment_tokens"] = documentationComment_tokens;
-      }
-    }
-    if (kind == idl.LinkedNodeKind.enumDeclaration) {
-      if (codeLength != 0) {
-        _result["codeLength"] = codeLength;
-      }
-      if (codeOffset != 0) {
-        _result["codeOffset"] = codeOffset;
-      }
-      if (nameOffset != 0) {
-        _result["nameOffset"] = nameOffset;
-      }
-      if (documentationComment_tokens.isNotEmpty) {
-        _result["documentationComment_tokens"] = documentationComment_tokens;
-      }
-    }
-    if (kind == idl.LinkedNodeKind.exportDirective) {
-      if (directiveKeywordOffset != 0) {
-        _result["directiveKeywordOffset"] = directiveKeywordOffset;
-      }
-    }
-    if (kind == idl.LinkedNodeKind.extensionDeclaration) {
-      if (codeLength != 0) {
-        _result["codeLength"] = codeLength;
-      }
-      if (codeOffset != 0) {
-        _result["codeOffset"] = codeOffset;
-      }
-      if (nameOffset != 0) {
-        _result["nameOffset"] = nameOffset;
-      }
-      if (documentationComment_tokens.isNotEmpty) {
-        _result["documentationComment_tokens"] = documentationComment_tokens;
-      }
-    }
-    if (kind == idl.LinkedNodeKind.fieldDeclaration) {
-      if (documentationComment_tokens.isNotEmpty) {
-        _result["documentationComment_tokens"] = documentationComment_tokens;
-      }
-    }
-    if (kind == idl.LinkedNodeKind.fieldFormalParameter) {
-      if (codeLength != 0) {
-        _result["codeLength"] = codeLength;
-      }
-      if (codeOffset != 0) {
-        _result["codeOffset"] = codeOffset;
-      }
-      if (nameOffset != 0) {
-        _result["nameOffset"] = nameOffset;
-      }
-    }
-    if (kind == idl.LinkedNodeKind.functionDeclaration) {
-      if (codeLength != 0) {
-        _result["codeLength"] = codeLength;
-      }
-      if (codeOffset != 0) {
-        _result["codeOffset"] = codeOffset;
-      }
-      if (nameOffset != 0) {
-        _result["nameOffset"] = nameOffset;
-      }
-      if (documentationComment_tokens.isNotEmpty) {
-        _result["documentationComment_tokens"] = documentationComment_tokens;
-      }
-    }
-    if (kind == idl.LinkedNodeKind.functionTypeAlias) {
-      if (codeLength != 0) {
-        _result["codeLength"] = codeLength;
-      }
-      if (codeOffset != 0) {
-        _result["codeOffset"] = codeOffset;
-      }
-      if (nameOffset != 0) {
-        _result["nameOffset"] = nameOffset;
-      }
-      if (documentationComment_tokens.isNotEmpty) {
-        _result["documentationComment_tokens"] = documentationComment_tokens;
-      }
-    }
-    if (kind == idl.LinkedNodeKind.functionTypedFormalParameter) {
-      if (codeLength != 0) {
-        _result["codeLength"] = codeLength;
-      }
-      if (codeOffset != 0) {
-        _result["codeOffset"] = codeOffset;
-      }
-      if (nameOffset != 0) {
-        _result["nameOffset"] = nameOffset;
-      }
-    }
-    if (kind == idl.LinkedNodeKind.genericTypeAlias) {
-      if (codeLength != 0) {
-        _result["codeLength"] = codeLength;
-      }
-      if (codeOffset != 0) {
-        _result["codeOffset"] = codeOffset;
-      }
-      if (nameOffset != 0) {
-        _result["nameOffset"] = nameOffset;
-      }
-      if (documentationComment_tokens.isNotEmpty) {
-        _result["documentationComment_tokens"] = documentationComment_tokens;
-      }
-    }
-    if (kind == idl.LinkedNodeKind.hideCombinator) {
-      if (combinatorEnd != 0) {
-        _result["combinatorEnd"] = combinatorEnd;
-      }
-      if (combinatorKeywordOffset != 0) {
-        _result["combinatorKeywordOffset"] = combinatorKeywordOffset;
-      }
-    }
-    if (kind == idl.LinkedNodeKind.importDirective) {
-      if (importDirective_prefixOffset != 0) {
-        _result["importDirective_prefixOffset"] = importDirective_prefixOffset;
-      }
-      if (directiveKeywordOffset != 0) {
-        _result["directiveKeywordOffset"] = directiveKeywordOffset;
-      }
-    }
-    if (kind == idl.LinkedNodeKind.libraryDirective) {
-      if (directiveKeywordOffset != 0) {
-        _result["directiveKeywordOffset"] = directiveKeywordOffset;
-      }
-      if (documentationComment_tokens.isNotEmpty) {
-        _result["documentationComment_tokens"] = documentationComment_tokens;
-      }
-    }
-    if (kind == idl.LinkedNodeKind.methodDeclaration) {
-      if (codeLength != 0) {
-        _result["codeLength"] = codeLength;
-      }
-      if (codeOffset != 0) {
-        _result["codeOffset"] = codeOffset;
-      }
-      if (nameOffset != 0) {
-        _result["nameOffset"] = nameOffset;
-      }
-      if (documentationComment_tokens.isNotEmpty) {
-        _result["documentationComment_tokens"] = documentationComment_tokens;
-      }
-    }
-    if (kind == idl.LinkedNodeKind.mixinDeclaration) {
-      if (codeLength != 0) {
-        _result["codeLength"] = codeLength;
-      }
-      if (codeOffset != 0) {
-        _result["codeOffset"] = codeOffset;
-      }
-      if (nameOffset != 0) {
-        _result["nameOffset"] = nameOffset;
-      }
-      if (documentationComment_tokens.isNotEmpty) {
-        _result["documentationComment_tokens"] = documentationComment_tokens;
-      }
-    }
-    if (kind == idl.LinkedNodeKind.partDirective) {
-      if (directiveKeywordOffset != 0) {
-        _result["directiveKeywordOffset"] = directiveKeywordOffset;
-      }
-    }
-    if (kind == idl.LinkedNodeKind.partOfDirective) {
-      if (directiveKeywordOffset != 0) {
-        _result["directiveKeywordOffset"] = directiveKeywordOffset;
-      }
-    }
-    if (kind == idl.LinkedNodeKind.showCombinator) {
-      if (combinatorEnd != 0) {
-        _result["combinatorEnd"] = combinatorEnd;
-      }
-      if (combinatorKeywordOffset != 0) {
-        _result["combinatorKeywordOffset"] = combinatorKeywordOffset;
-      }
-    }
-    if (kind == idl.LinkedNodeKind.simpleFormalParameter) {
-      if (codeLength != 0) {
-        _result["codeLength"] = codeLength;
-      }
-      if (codeOffset != 0) {
-        _result["codeOffset"] = codeOffset;
-      }
-      if (nameOffset != 0) {
-        _result["nameOffset"] = nameOffset;
-      }
-    }
-    if (kind == idl.LinkedNodeKind.topLevelVariableDeclaration) {
-      if (documentationComment_tokens.isNotEmpty) {
-        _result["documentationComment_tokens"] = documentationComment_tokens;
-      }
-    }
-    if (kind == idl.LinkedNodeKind.typeParameter) {
-      if (codeLength != 0) {
-        _result["codeLength"] = codeLength;
-      }
-      if (codeOffset != 0) {
-        _result["codeOffset"] = codeOffset;
-      }
-      if (nameOffset != 0) {
-        _result["nameOffset"] = nameOffset;
-      }
-    }
-    if (kind == idl.LinkedNodeKind.variableDeclaration) {
-      if (codeLength != 0) {
-        _result["codeLength"] = codeLength;
-      }
-      if (codeOffset != 0) {
-        _result["codeOffset"] = codeOffset;
-      }
-      if (nameOffset != 0) {
-        _result["nameOffset"] = nameOffset;
-      }
-    }
-    return _result;
-  }
-
-  @override
-  Map<String, Object> toMap() {
-    if (kind == idl.LinkedNodeKind.classDeclaration) {
-      return {
-        "codeLength": codeLength,
-        "codeOffset": codeOffset,
-        "nameOffset": nameOffset,
-        "documentationComment_tokens": documentationComment_tokens,
-        "kind": kind,
-      };
-    }
-    if (kind == idl.LinkedNodeKind.classTypeAlias) {
-      return {
-        "codeLength": codeLength,
-        "codeOffset": codeOffset,
-        "nameOffset": nameOffset,
-        "documentationComment_tokens": documentationComment_tokens,
-        "kind": kind,
-      };
-    }
-    if (kind == idl.LinkedNodeKind.compilationUnit) {
-      return {
-        "codeLength": codeLength,
-        "codeOffset": codeOffset,
-        "compilationUnit_lineStarts": compilationUnit_lineStarts,
-        "kind": kind,
-      };
-    }
-    if (kind == idl.LinkedNodeKind.constructorDeclaration) {
-      return {
-        "codeLength": codeLength,
-        "codeOffset": codeOffset,
-        "constructorDeclaration_periodOffset":
-            constructorDeclaration_periodOffset,
-        "constructorDeclaration_returnTypeOffset":
-            constructorDeclaration_returnTypeOffset,
-        "nameOffset": nameOffset,
-        "documentationComment_tokens": documentationComment_tokens,
-        "kind": kind,
-      };
-    }
-    if (kind == idl.LinkedNodeKind.defaultFormalParameter) {
-      return {
-        "codeLength": codeLength,
-        "codeOffset": codeOffset,
-        "defaultFormalParameter_defaultValueCode":
-            defaultFormalParameter_defaultValueCode,
-        "kind": kind,
-      };
-    }
-    if (kind == idl.LinkedNodeKind.enumConstantDeclaration) {
-      return {
-        "codeLength": codeLength,
-        "codeOffset": codeOffset,
-        "nameOffset": nameOffset,
-        "documentationComment_tokens": documentationComment_tokens,
-        "kind": kind,
-      };
-    }
-    if (kind == idl.LinkedNodeKind.enumDeclaration) {
-      return {
-        "codeLength": codeLength,
-        "codeOffset": codeOffset,
-        "nameOffset": nameOffset,
-        "documentationComment_tokens": documentationComment_tokens,
-        "kind": kind,
-      };
-    }
-    if (kind == idl.LinkedNodeKind.exportDirective) {
-      return {
-        "directiveKeywordOffset": directiveKeywordOffset,
-        "kind": kind,
-      };
-    }
-    if (kind == idl.LinkedNodeKind.extensionDeclaration) {
-      return {
-        "codeLength": codeLength,
-        "codeOffset": codeOffset,
-        "nameOffset": nameOffset,
-        "documentationComment_tokens": documentationComment_tokens,
-        "kind": kind,
-      };
-    }
-    if (kind == idl.LinkedNodeKind.fieldDeclaration) {
-      return {
-        "documentationComment_tokens": documentationComment_tokens,
-        "kind": kind,
-      };
-    }
-    if (kind == idl.LinkedNodeKind.fieldFormalParameter) {
-      return {
-        "codeLength": codeLength,
-        "codeOffset": codeOffset,
-        "nameOffset": nameOffset,
-        "kind": kind,
-      };
-    }
-    if (kind == idl.LinkedNodeKind.functionDeclaration) {
-      return {
-        "codeLength": codeLength,
-        "codeOffset": codeOffset,
-        "nameOffset": nameOffset,
-        "documentationComment_tokens": documentationComment_tokens,
-        "kind": kind,
-      };
-    }
-    if (kind == idl.LinkedNodeKind.functionTypeAlias) {
-      return {
-        "codeLength": codeLength,
-        "codeOffset": codeOffset,
-        "nameOffset": nameOffset,
-        "documentationComment_tokens": documentationComment_tokens,
-        "kind": kind,
-      };
-    }
-    if (kind == idl.LinkedNodeKind.functionTypedFormalParameter) {
-      return {
-        "codeLength": codeLength,
-        "codeOffset": codeOffset,
-        "nameOffset": nameOffset,
-        "kind": kind,
-      };
-    }
-    if (kind == idl.LinkedNodeKind.genericTypeAlias) {
-      return {
-        "codeLength": codeLength,
-        "codeOffset": codeOffset,
-        "nameOffset": nameOffset,
-        "documentationComment_tokens": documentationComment_tokens,
-        "kind": kind,
-      };
-    }
-    if (kind == idl.LinkedNodeKind.hideCombinator) {
-      return {
-        "combinatorEnd": combinatorEnd,
-        "combinatorKeywordOffset": combinatorKeywordOffset,
-        "kind": kind,
-      };
-    }
-    if (kind == idl.LinkedNodeKind.importDirective) {
-      return {
-        "importDirective_prefixOffset": importDirective_prefixOffset,
-        "directiveKeywordOffset": directiveKeywordOffset,
-        "kind": kind,
-      };
-    }
-    if (kind == idl.LinkedNodeKind.libraryDirective) {
-      return {
-        "directiveKeywordOffset": directiveKeywordOffset,
-        "documentationComment_tokens": documentationComment_tokens,
-        "kind": kind,
-      };
-    }
-    if (kind == idl.LinkedNodeKind.methodDeclaration) {
-      return {
-        "codeLength": codeLength,
-        "codeOffset": codeOffset,
-        "nameOffset": nameOffset,
-        "documentationComment_tokens": documentationComment_tokens,
-        "kind": kind,
-      };
-    }
-    if (kind == idl.LinkedNodeKind.mixinDeclaration) {
-      return {
-        "codeLength": codeLength,
-        "codeOffset": codeOffset,
-        "nameOffset": nameOffset,
-        "documentationComment_tokens": documentationComment_tokens,
-        "kind": kind,
-      };
-    }
-    if (kind == idl.LinkedNodeKind.partDirective) {
-      return {
-        "directiveKeywordOffset": directiveKeywordOffset,
-        "kind": kind,
-      };
-    }
-    if (kind == idl.LinkedNodeKind.partOfDirective) {
-      return {
-        "directiveKeywordOffset": directiveKeywordOffset,
-        "kind": kind,
-      };
-    }
-    if (kind == idl.LinkedNodeKind.showCombinator) {
-      return {
-        "combinatorEnd": combinatorEnd,
-        "combinatorKeywordOffset": combinatorKeywordOffset,
-        "kind": kind,
-      };
-    }
-    if (kind == idl.LinkedNodeKind.simpleFormalParameter) {
-      return {
-        "codeLength": codeLength,
-        "codeOffset": codeOffset,
-        "nameOffset": nameOffset,
-        "kind": kind,
-      };
-    }
-    if (kind == idl.LinkedNodeKind.topLevelVariableDeclaration) {
-      return {
-        "documentationComment_tokens": documentationComment_tokens,
-        "kind": kind,
-      };
-    }
-    if (kind == idl.LinkedNodeKind.typeParameter) {
-      return {
-        "codeLength": codeLength,
-        "codeOffset": codeOffset,
-        "nameOffset": nameOffset,
-        "kind": kind,
-      };
-    }
-    if (kind == idl.LinkedNodeKind.variableDeclaration) {
-      return {
-        "codeLength": codeLength,
-        "codeOffset": codeOffset,
-        "nameOffset": nameOffset,
-        "kind": kind,
-      };
-    }
-    throw StateError("Unexpected $kind");
-  }
-
-  @override
-  String toString() => convert.json.encode(toJson());
-}
-
 class UnlinkedNamespaceDirectiveBuilder extends Object
     with _UnlinkedNamespaceDirectiveMixin
     implements idl.UnlinkedNamespaceDirective {
@@ -19926,7 +4343,6 @@
   bool _hasLibraryDirective;
   bool _hasPartOfDirective;
   List<UnlinkedNamespaceDirectiveBuilder> _imports;
-  List<UnlinkedInformativeDataBuilder> _informativeData;
   List<int> _lineStarts;
   String _partOfUri;
   List<String> _parts;
@@ -19976,14 +4392,6 @@
   }
 
   @override
-  List<UnlinkedInformativeDataBuilder> get informativeData =>
-      _informativeData ??= <UnlinkedInformativeDataBuilder>[];
-
-  set informativeData(List<UnlinkedInformativeDataBuilder> value) {
-    this._informativeData = value;
-  }
-
-  @override
   List<int> get lineStarts => _lineStarts ??= <int>[];
 
   /// Offsets of the first character of each line in the source code.
@@ -20014,7 +4422,6 @@
       bool hasLibraryDirective,
       bool hasPartOfDirective,
       List<UnlinkedNamespaceDirectiveBuilder> imports,
-      List<UnlinkedInformativeDataBuilder> informativeData,
       List<int> lineStarts,
       String partOfUri,
       List<String> parts})
@@ -20023,7 +4430,6 @@
         _hasLibraryDirective = hasLibraryDirective,
         _hasPartOfDirective = hasPartOfDirective,
         _imports = imports,
-        _informativeData = informativeData,
         _lineStarts = lineStarts,
         _partOfUri = partOfUri,
         _parts = parts;
@@ -20032,7 +4438,6 @@
   void flushInformative() {
     _exports?.forEach((b) => b.flushInformative());
     _imports?.forEach((b) => b.flushInformative());
-    _informativeData?.forEach((b) => b.flushInformative());
     _lineStarts = null;
   }
 
@@ -20072,14 +4477,6 @@
       }
     }
     signature.addBool(this._hasLibraryDirective == true);
-    if (this._informativeData == null) {
-      signature.addInt(0);
-    } else {
-      signature.addInt(this._informativeData.length);
-      for (var x in this._informativeData) {
-        x?.collectApiSignature(signature);
-      }
-    }
     signature.addString(this._partOfUri ?? '');
   }
 
@@ -20092,7 +4489,6 @@
     fb.Offset offset_apiSignature;
     fb.Offset offset_exports;
     fb.Offset offset_imports;
-    fb.Offset offset_informativeData;
     fb.Offset offset_lineStarts;
     fb.Offset offset_partOfUri;
     fb.Offset offset_parts;
@@ -20107,10 +4503,6 @@
       offset_imports = fbBuilder
           .writeList(_imports.map((b) => b.finish(fbBuilder)).toList());
     }
-    if (!(_informativeData == null || _informativeData.isEmpty)) {
-      offset_informativeData = fbBuilder
-          .writeList(_informativeData.map((b) => b.finish(fbBuilder)).toList());
-    }
     if (!(_lineStarts == null || _lineStarts.isEmpty)) {
       offset_lineStarts = fbBuilder.writeListUint32(_lineStarts);
     }
@@ -20137,14 +4529,11 @@
     if (offset_imports != null) {
       fbBuilder.addOffset(2, offset_imports);
     }
-    if (offset_informativeData != null) {
-      fbBuilder.addOffset(7, offset_informativeData);
-    }
     if (offset_lineStarts != null) {
       fbBuilder.addOffset(5, offset_lineStarts);
     }
     if (offset_partOfUri != null) {
-      fbBuilder.addOffset(8, offset_partOfUri);
+      fbBuilder.addOffset(7, offset_partOfUri);
     }
     if (offset_parts != null) {
       fbBuilder.addOffset(4, offset_parts);
@@ -20179,7 +4568,6 @@
   bool _hasLibraryDirective;
   bool _hasPartOfDirective;
   List<idl.UnlinkedNamespaceDirective> _imports;
-  List<idl.UnlinkedInformativeData> _informativeData;
   List<int> _lineStarts;
   String _partOfUri;
   List<String> _parts;
@@ -20222,14 +4610,6 @@
   }
 
   @override
-  List<idl.UnlinkedInformativeData> get informativeData {
-    _informativeData ??= const fb.ListReader<idl.UnlinkedInformativeData>(
-            _UnlinkedInformativeDataReader())
-        .vTableGet(_bc, _bcOffset, 7, const <idl.UnlinkedInformativeData>[]);
-    return _informativeData;
-  }
-
-  @override
   List<int> get lineStarts {
     _lineStarts ??=
         const fb.Uint32ListReader().vTableGet(_bc, _bcOffset, 5, const <int>[]);
@@ -20238,7 +4618,7 @@
 
   @override
   String get partOfUri {
-    _partOfUri ??= const fb.StringReader().vTableGet(_bc, _bcOffset, 8, '');
+    _partOfUri ??= const fb.StringReader().vTableGet(_bc, _bcOffset, 7, '');
     return _partOfUri;
   }
 
@@ -20269,10 +4649,6 @@
     if (imports.isNotEmpty) {
       _result["imports"] = imports.map((_value) => _value.toJson()).toList();
     }
-    if (informativeData.isNotEmpty) {
-      _result["informativeData"] =
-          informativeData.map((_value) => _value.toJson()).toList();
-    }
     if (lineStarts.isNotEmpty) {
       _result["lineStarts"] = lineStarts;
     }
@@ -20292,7 +4668,6 @@
         "hasLibraryDirective": hasLibraryDirective,
         "hasPartOfDirective": hasPartOfDirective,
         "imports": imports,
-        "informativeData": informativeData,
         "lineStarts": lineStarts,
         "partOfUri": partOfUri,
         "parts": parts,
diff --git a/pkg/analyzer/lib/src/summary/format.fbs b/pkg/analyzer/lib/src/summary/format.fbs
index e9c6fe6..bdce0bf 100644
--- a/pkg/analyzer/lib/src/summary/format.fbs
+++ b/pkg/analyzer/lib/src/summary/format.fbs
@@ -39,30 +39,6 @@
   VARIABLE
 }
 
-/// Enum representing nullability suffixes in summaries.
-///
-/// This enum is similar to [NullabilitySuffix], but the order is different so
-/// that [EntityRefNullabilitySuffix.starOrIrrelevant] can be the default.
-enum EntityRefNullabilitySuffix : byte {
-  /// An indication that the canonical representation of the type under
-  /// consideration ends with `*`.  Types having this nullability suffix are
-  /// called "legacy types"; it has not yet been determined whether they should
-  /// be unioned with the Null type.
-  ///
-  /// Also used in circumstances where no nullability suffix information is
-  /// needed.
-  starOrIrrelevant,
-
-  /// An indication that the canonical representation of the type under
-  /// consideration ends with `?`.  Types having this nullability suffix should
-  /// be interpreted as being unioned with the Null type.
-  question,
-
-  /// An indication that the canonical representation of the type under
-  /// consideration does not end with either `?` or `*`.
-  none
-}
-
 /// Enum used to indicate the kind of an index relation.
 enum IndexRelationKind : byte {
   /// Left: class.
@@ -149,586 +125,6 @@
   unit
 }
 
-/// Types of comments.
-enum LinkedNodeCommentType : byte {
-  block,
-
-  documentation,
-
-  endOfLine
-}
-
-/// Kinds of formal parameters.
-enum LinkedNodeFormalParameterKind : byte {
-  requiredPositional,
-
-  optionalPositional,
-
-  optionalNamed,
-
-  requiredNamed
-}
-
-/// Kinds of [LinkedNode].
-enum LinkedNodeKind : byte {
-  adjacentStrings,
-
-  annotation,
-
-  argumentList,
-
-  asExpression,
-
-  assertInitializer,
-
-  assertStatement,
-
-  assignmentExpression,
-
-  awaitExpression,
-
-  binaryExpression,
-
-  block,
-
-  blockFunctionBody,
-
-  booleanLiteral,
-
-  breakStatement,
-
-  cascadeExpression,
-
-  catchClause,
-
-  classDeclaration,
-
-  classTypeAlias,
-
-  comment,
-
-  commentReference,
-
-  compilationUnit,
-
-  conditionalExpression,
-
-  configuration,
-
-  constructorDeclaration,
-
-  constructorFieldInitializer,
-
-  constructorName,
-
-  continueStatement,
-
-  declaredIdentifier,
-
-  defaultFormalParameter,
-
-  doubleLiteral,
-
-  doStatement,
-
-  dottedName,
-
-  emptyFunctionBody,
-
-  emptyStatement,
-
-  enumConstantDeclaration,
-
-  enumDeclaration,
-
-  exportDirective,
-
-  expressionFunctionBody,
-
-  expressionStatement,
-
-  extendsClause,
-
-  extensionDeclaration,
-
-  fieldDeclaration,
-
-  fieldFormalParameter,
-
-  formalParameterList,
-
-  forEachPartsWithDeclaration,
-
-  forEachPartsWithIdentifier,
-
-  forElement,
-
-  forPartsWithDeclarations,
-
-  forPartsWithExpression,
-
-  forStatement,
-
-  functionDeclaration,
-
-  functionDeclarationStatement,
-
-  functionExpression,
-
-  functionExpressionInvocation,
-
-  functionTypeAlias,
-
-  functionTypedFormalParameter,
-
-  genericFunctionType,
-
-  genericTypeAlias,
-
-  hideCombinator,
-
-  ifElement,
-
-  ifStatement,
-
-  implementsClause,
-
-  importDirective,
-
-  instanceCreationExpression,
-
-  indexExpression,
-
-  integerLiteral,
-
-  interpolationExpression,
-
-  interpolationString,
-
-  isExpression,
-
-  label,
-
-  labeledStatement,
-
-  libraryDirective,
-
-  libraryIdentifier,
-
-  listLiteral,
-
-  mapLiteralEntry,
-
-  methodDeclaration,
-
-  methodInvocation,
-
-  mixinDeclaration,
-
-  namedExpression,
-
-  nativeClause,
-
-  nativeFunctionBody,
-
-  nullLiteral,
-
-  onClause,
-
-  parenthesizedExpression,
-
-  partDirective,
-
-  partOfDirective,
-
-  postfixExpression,
-
-  prefixExpression,
-
-  prefixedIdentifier,
-
-  propertyAccess,
-
-  redirectingConstructorInvocation,
-
-  rethrowExpression,
-
-  returnStatement,
-
-  setOrMapLiteral,
-
-  showCombinator,
-
-  simpleFormalParameter,
-
-  simpleIdentifier,
-
-  simpleStringLiteral,
-
-  spreadElement,
-
-  stringInterpolation,
-
-  superConstructorInvocation,
-
-  superExpression,
-
-  switchCase,
-
-  switchDefault,
-
-  switchStatement,
-
-  symbolLiteral,
-
-  thisExpression,
-
-  throwExpression,
-
-  topLevelVariableDeclaration,
-
-  tryStatement,
-
-  typeArgumentList,
-
-  typeName,
-
-  typeParameter,
-
-  typeParameterList,
-
-  variableDeclaration,
-
-  variableDeclarationList,
-
-  variableDeclarationStatement,
-
-  whileStatement,
-
-  withClause,
-
-  yieldStatement,
-
-  extensionOverride
-}
-
-/// Kinds of [LinkedNodeType]s.
-enum LinkedNodeTypeKind : byte {
-  dynamic_,
-
-  function,
-
-  interface,
-
-  never,
-
-  typeParameter,
-
-  void_
-}
-
-/// Enum used to indicate the kind of the error during top-level inference.
-enum TopLevelInferenceErrorKind : byte {
-  assignment,
-
-  instanceGetter,
-
-  dependencyCycle,
-
-  overrideConflictFieldType,
-
-  overrideNoCombinedSuperSignature
-}
-
-/// Enum of token types, corresponding to AST token types.
-enum UnlinkedTokenType : byte {
-  NOTHING,
-
-  ABSTRACT,
-
-  AMPERSAND,
-
-  AMPERSAND_AMPERSAND,
-
-  AMPERSAND_EQ,
-
-  AS,
-
-  ASSERT,
-
-  ASYNC,
-
-  AT,
-
-  AWAIT,
-
-  BACKPING,
-
-  BACKSLASH,
-
-  BANG,
-
-  BANG_EQ,
-
-  BANG_EQ_EQ,
-
-  BAR,
-
-  BAR_BAR,
-
-  BAR_EQ,
-
-  BREAK,
-
-  CARET,
-
-  CARET_EQ,
-
-  CASE,
-
-  CATCH,
-
-  CLASS,
-
-  CLOSE_CURLY_BRACKET,
-
-  CLOSE_PAREN,
-
-  CLOSE_SQUARE_BRACKET,
-
-  COLON,
-
-  COMMA,
-
-  CONST,
-
-  CONTINUE,
-
-  COVARIANT,
-
-  DEFAULT,
-
-  DEFERRED,
-
-  DO,
-
-  DOUBLE,
-
-  DYNAMIC,
-
-  ELSE,
-
-  ENUM,
-
-  EOF,
-
-  EQ,
-
-  EQ_EQ,
-
-  EQ_EQ_EQ,
-
-  EXPORT,
-
-  EXTENDS,
-
-  EXTERNAL,
-
-  FACTORY,
-
-  FALSE,
-
-  FINAL,
-
-  FINALLY,
-
-  FOR,
-
-  FUNCTION,
-
-  FUNCTION_KEYWORD,
-
-  GET,
-
-  GT,
-
-  GT_EQ,
-
-  GT_GT,
-
-  GT_GT_EQ,
-
-  GT_GT_GT,
-
-  GT_GT_GT_EQ,
-
-  HASH,
-
-  HEXADECIMAL,
-
-  HIDE,
-
-  IDENTIFIER,
-
-  IF,
-
-  IMPLEMENTS,
-
-  IMPORT,
-
-  IN,
-
-  INDEX,
-
-  INDEX_EQ,
-
-  INT,
-
-  INTERFACE,
-
-  IS,
-
-  LATE,
-
-  LIBRARY,
-
-  LT,
-
-  LT_EQ,
-
-  LT_LT,
-
-  LT_LT_EQ,
-
-  MINUS,
-
-  MINUS_EQ,
-
-  MINUS_MINUS,
-
-  MIXIN,
-
-  MULTI_LINE_COMMENT,
-
-  NATIVE,
-
-  NEW,
-
-  NULL,
-
-  OF,
-
-  ON,
-
-  OPEN_CURLY_BRACKET,
-
-  OPEN_PAREN,
-
-  OPEN_SQUARE_BRACKET,
-
-  OPERATOR,
-
-  PART,
-
-  PATCH,
-
-  PERCENT,
-
-  PERCENT_EQ,
-
-  PERIOD,
-
-  PERIOD_PERIOD,
-
-  PERIOD_PERIOD_PERIOD,
-
-  PERIOD_PERIOD_PERIOD_QUESTION,
-
-  PLUS,
-
-  PLUS_EQ,
-
-  PLUS_PLUS,
-
-  QUESTION,
-
-  QUESTION_PERIOD,
-
-  QUESTION_QUESTION,
-
-  QUESTION_QUESTION_EQ,
-
-  REQUIRED,
-
-  RETHROW,
-
-  RETURN,
-
-  SCRIPT_TAG,
-
-  SEMICOLON,
-
-  SET,
-
-  SHOW,
-
-  SINGLE_LINE_COMMENT,
-
-  SLASH,
-
-  SLASH_EQ,
-
-  SOURCE,
-
-  STAR,
-
-  STAR_EQ,
-
-  STATIC,
-
-  STRING,
-
-  STRING_INTERPOLATION_EXPRESSION,
-
-  STRING_INTERPOLATION_IDENTIFIER,
-
-  SUPER,
-
-  SWITCH,
-
-  SYNC,
-
-  THIS,
-
-  THROW,
-
-  TILDE,
-
-  TILDE_SLASH,
-
-  TILDE_SLASH_EQ,
-
-  TRUE,
-
-  TRY,
-
-  TYPEDEF,
-
-  VAR,
-
-  VOID,
-
-  WHILE,
-
-  WITH,
-
-  YIELD,
-
-  INOUT,
-
-  OUT
-}
-
 /// Information about the context of an exception in analysis driver.
 table AnalysisDriverExceptionContext {
   /// The exception string.
@@ -1010,17 +406,6 @@
   shows:[string] (id: 0);
 }
 
-/// Information about linked libraries, a group of libraries that form
-/// a library cycle.
-table CiderLinkedLibraryCycle {
-  bundle:LinkedNodeBundle (id: 1);
-
-  /// The hash signature for this linked cycle. It depends of API signatures
-  /// of all files in the cycle, and on the signatures of the transitive
-  /// closure of the cycle dependencies.
-  signature:[uint] (id: 0);
-}
-
 /// Errors for a single unit.
 table CiderUnitErrors {
   errors:[AnalysisDriverUnitError] (id: 1);
@@ -1063,257 +448,10 @@
   templateValues:[string] (id: 1);
 }
 
-table LinkedLanguageVersion {
-  major:uint (id: 0);
-
-  minor:uint (id: 1);
-}
-
-table LinkedLibraryLanguageVersion {
-  override2:LinkedLanguageVersion (id: 1);
-
-  package:LinkedLanguageVersion (id: 0);
-}
-
-/// Information about a linked AST node.
-table LinkedNode {
-  /// The explicit or inferred return type of a function typed node.
-  variantField_24:LinkedNodeType (id: 24);
-
-  variantField_2:[LinkedNode] (id: 2);
-
-  variantField_4:[LinkedNode] (id: 4);
-
-  variantField_6:LinkedNode (id: 6);
-
-  variantField_7:LinkedNode (id: 7);
-
-  variantField_17:uint (id: 17);
-
-  variantField_8:LinkedNode (id: 8);
-
-  variantField_38:LinkedNodeTypeSubstitution (id: 38);
-
-  variantField_15:uint (id: 15);
-
-  variantField_28:UnlinkedTokenType (id: 28);
-
-  variantField_27:bool (id: 27);
-
-  variantField_9:LinkedNode (id: 9);
-
-  variantField_12:LinkedNode (id: 12);
-
-  variantField_5:[LinkedNode] (id: 5);
-
-  variantField_13:LinkedNode (id: 13);
-
-  variantField_33:[string] (id: 33);
-
-  variantField_29:LinkedNodeCommentType (id: 29);
-
-  variantField_3:[LinkedNode] (id: 3);
-
-  variantField_41:[uint] (id: 41);
-
-  /// The language version information.
-  variantField_40:LinkedLibraryLanguageVersion (id: 40);
-
-  variantField_10:LinkedNode (id: 10);
-
-  variantField_26:LinkedNodeFormalParameterKind (id: 26);
-
-  variantField_21:double (id: 21);
-
-  variantField_25:LinkedNodeType (id: 25);
-
-  variantField_20:string (id: 20);
-
-  variantField_39:[LinkedNodeType] (id: 39);
-
-  flags:uint (id: 18);
-
-  variantField_1:string (id: 1);
-
-  variantField_36:uint (id: 36);
-
-  variantField_16:uint (id: 16);
-
-  variantField_30:string (id: 30);
-
-  variantField_14:LinkedNode (id: 14);
-
-  kind:LinkedNodeKind (id: 0);
-
-  variantField_31:bool (id: 31);
-
-  variantField_34:[string] (id: 34);
-
-  name:string (id: 37);
-
-  variantField_35:UnlinkedTokenType (id: 35);
-
-  variantField_32:TopLevelInferenceError (id: 32);
-
-  variantField_23:LinkedNodeType (id: 23);
-
-  variantField_11:LinkedNode (id: 11);
-
-  variantField_22:string (id: 22);
-
-  variantField_19:uint (id: 19);
-}
-
-/// Information about a group of libraries linked together, for example because
-/// they form a single cycle, or because they represent a single build artifact.
-table LinkedNodeBundle {
-  libraries:[LinkedNodeLibrary] (id: 1);
-
-  /// The shared list of references used in the [libraries].
-  references:LinkedNodeReferences (id: 0);
-}
-
-/// Information about a single library in a [LinkedNodeBundle].
-table LinkedNodeLibrary {
-  exports:[uint] (id: 2);
-
-  name:string (id: 3);
-
-  nameLength:uint (id: 5);
-
-  nameOffset:uint (id: 4);
-
-  units:[LinkedNodeUnit] (id: 1);
-
-  uriStr:string (id: 0);
-}
-
-/// Flattened tree of declarations referenced from [LinkedNode]s.
-table LinkedNodeReferences {
-  name:[string] (id: 1);
-
-  parent:[uint] (id: 0);
-}
-
-/// Information about a Dart type.
-table LinkedNodeType {
-  functionFormalParameters:[LinkedNodeTypeFormalParameter] (id: 0);
-
-  functionReturnType:LinkedNodeType (id: 1);
-
-  /// The typedef this function type is created for.
-  functionTypedef:uint (id: 9);
-
-  functionTypedefTypeArguments:[LinkedNodeType] (id: 10);
-
-  functionTypeParameters:[LinkedNodeTypeTypeParameter] (id: 2);
-
-  /// Reference to a [LinkedNodeReferences].
-  interfaceClass:uint (id: 3);
-
-  interfaceTypeArguments:[LinkedNodeType] (id: 4);
-
-  kind:LinkedNodeTypeKind (id: 5);
-
-  nullabilitySuffix:EntityRefNullabilitySuffix (id: 8);
-
-  typeParameterElement:uint (id: 6);
-
-  typeParameterId:uint (id: 7);
-}
-
-/// Information about a formal parameter in a function type.
-table LinkedNodeTypeFormalParameter {
-  kind:LinkedNodeFormalParameterKind (id: 0);
-
-  name:string (id: 1);
-
-  type:LinkedNodeType (id: 2);
-}
-
-/// Information about a type substitution.
-table LinkedNodeTypeSubstitution {
-  isLegacy:bool (id: 2);
-
-  typeArguments:[LinkedNodeType] (id: 1);
-
-  typeParameters:[uint] (id: 0);
-}
-
-/// Information about a type parameter in a function type.
-table LinkedNodeTypeTypeParameter {
-  bound:LinkedNodeType (id: 1);
-
-  name:string (id: 0);
-}
-
-/// Information about a single library in a [LinkedNodeLibrary].
-table LinkedNodeUnit {
-  isSynthetic:bool (id: 2);
-
-  node:LinkedNode (id: 1);
-
-  /// If the unit is a part, the URI specified in the `part` directive.
-  /// Otherwise empty.
-  partUriStr:string (id: 3);
-
-  /// The absolute URI.
-  uriStr:string (id: 0);
-}
-
 /// Summary information about a package.
 table PackageBundle {
   /// The version 2 of the summary.
-  bundle2:LinkedNodeBundle (id: 0);
-
-  /// The SDK specific data, if this bundle is for SDK.
-  sdk:PackageBundleSdk (id: 1);
-}
-
-/// Summary information about a package.
-table PackageBundleSdk {
-  /// The content of the `allowed_experiments.json` from SDK.
-  allowedExperimentsJson:string (id: 0);
-
-  /// The language version of the SDK.
-  languageVersion:LinkedLanguageVersion (id: 1);
-}
-
-/// Summary information about a top-level type inference error.
-table TopLevelInferenceError {
-  /// The [kind] specific arguments.
-  arguments:[string] (id: 1);
-
-  /// The kind of the error.
-  kind:TopLevelInferenceErrorKind (id: 0);
-}
-
-table UnlinkedInformativeData {
-  variantField_2:uint (id: 2);
-
-  variantField_3:uint (id: 3);
-
-  variantField_9:uint (id: 9);
-
-  variantField_8:uint (id: 8);
-
-  /// Offsets of the first character of each line in the source code.
-  variantField_7:[uint] (id: 7);
-
-  variantField_6:uint (id: 6);
-
-  variantField_5:uint (id: 5);
-
-  /// If the parameter has a default value, the source text of the constant
-  /// expression in the default value.  Otherwise the empty string.
-  variantField_10:string (id: 10);
-
-  variantField_1:uint (id: 1);
-
-  variantField_4:[string] (id: 4);
-
-  /// The kind of the node.
-  kind:LinkedNodeKind (id: 0);
+  fake:uint (id: 0);
 }
 
 /// Unlinked summary information about a namespace directive.
@@ -1357,13 +495,11 @@
   /// URIs of `import` directives.
   imports:[UnlinkedNamespaceDirective] (id: 2);
 
-  informativeData:[UnlinkedInformativeData] (id: 7);
-
   /// Offsets of the first character of each line in the source code.
   lineStarts:[uint] (id: 5);
 
   /// URI of the `part of` directive.
-  partOfUri:string (id: 8);
+  partOfUri:string (id: 7);
 
   /// URIs of `part` directives.
   parts:[string] (id: 4);
diff --git a/pkg/analyzer/lib/src/summary/idl.dart b/pkg/analyzer/lib/src/summary/idl.dart
index 4b84de9..bd9d540 100644
--- a/pkg/analyzer/lib/src/summary/idl.dart
+++ b/pkg/analyzer/lib/src/summary/idl.dart
@@ -40,7 +40,7 @@
 /// Except as otherwise noted, synthetic elements are not stored in the summary;
 /// they are re-synthesized at the time the summary is read.
 import 'base.dart' as base;
-import 'base.dart' show Id, TopLevel, Variant, VariantId;
+import 'base.dart' show Id, TopLevel;
 import 'format.dart' as generated;
 
 /// Annotation describing information which is not part of Dart semantics; in
@@ -448,23 +448,6 @@
   List<String> get shows;
 }
 
-/// Information about linked libraries, a group of libraries that form
-/// a library cycle.
-@TopLevel('CLNB')
-abstract class CiderLinkedLibraryCycle extends base.SummaryClass {
-  factory CiderLinkedLibraryCycle.fromBuffer(List<int> buffer) =>
-      generated.readCiderLinkedLibraryCycle(buffer);
-
-  @Id(1)
-  LinkedNodeBundle get bundle;
-
-  /// The hash signature for this linked cycle. It depends of API signatures
-  /// of all files in the cycle, and on the signatures of the transitive
-  /// closure of the cycle dependencies.
-  @Id(0)
-  List<int> get signature;
-}
-
 /// Errors for a single unit.
 @TopLevel('CUEr')
 abstract class CiderUnitErrors extends base.SummaryClass {
@@ -525,30 +508,6 @@
   List<String> get templateValues;
 }
 
-/// Enum representing nullability suffixes in summaries.
-///
-/// This enum is similar to [NullabilitySuffix], but the order is different so
-/// that [EntityRefNullabilitySuffix.starOrIrrelevant] can be the default.
-enum EntityRefNullabilitySuffix {
-  /// An indication that the canonical representation of the type under
-  /// consideration ends with `*`.  Types having this nullability suffix are
-  /// called "legacy types"; it has not yet been determined whether they should
-  /// be unioned with the Null type.
-  ///
-  /// Also used in circumstances where no nullability suffix information is
-  /// needed.
-  starOrIrrelevant,
-
-  /// An indication that the canonical representation of the type under
-  /// consideration ends with `?`.  Types having this nullability suffix should
-  /// be interpreted as being unioned with the Null type.
-  question,
-
-  /// An indication that the canonical representation of the type under
-  /// consideration does not end with either `?` or `*`.
-  none,
-}
-
 /// Enum used to indicate the kind of an index relation.
 enum IndexRelationKind {
   /// Left: class.
@@ -635,1263 +594,6 @@
   unit
 }
 
-abstract class LinkedLanguageVersion extends base.SummaryClass {
-  @Id(0)
-  int get major;
-
-  @Id(1)
-  int get minor;
-}
-
-abstract class LinkedLibraryLanguageVersion extends base.SummaryClass {
-  @Id(1)
-  LinkedLanguageVersion get override2;
-
-  @Id(0)
-  LinkedLanguageVersion get package;
-}
-
-/// Information about a linked AST node.
-@Variant('kind')
-abstract class LinkedNode extends base.SummaryClass {
-  /// The explicit or inferred return type of a function typed node.
-  @VariantId(24, variantList: [
-    LinkedNodeKind.functionDeclaration,
-    LinkedNodeKind.functionExpression,
-    LinkedNodeKind.functionTypeAlias,
-    LinkedNodeKind.genericFunctionType,
-    LinkedNodeKind.methodDeclaration,
-  ])
-  LinkedNodeType get actualReturnType;
-
-  /// The explicit or inferred type of a variable.
-  @VariantId(24, variantList: [
-    LinkedNodeKind.fieldFormalParameter,
-    LinkedNodeKind.functionTypedFormalParameter,
-    LinkedNodeKind.simpleFormalParameter,
-    LinkedNodeKind.variableDeclaration,
-  ])
-  LinkedNodeType get actualType;
-
-  @VariantId(2, variant: LinkedNodeKind.adjacentStrings)
-  List<LinkedNode> get adjacentStrings_strings;
-
-  @VariantId(4, variantList: [
-    LinkedNodeKind.classDeclaration,
-    LinkedNodeKind.classTypeAlias,
-    LinkedNodeKind.constructorDeclaration,
-    LinkedNodeKind.declaredIdentifier,
-    LinkedNodeKind.enumDeclaration,
-    LinkedNodeKind.enumConstantDeclaration,
-    LinkedNodeKind.exportDirective,
-    LinkedNodeKind.extensionDeclaration,
-    LinkedNodeKind.fieldDeclaration,
-    LinkedNodeKind.functionDeclaration,
-    LinkedNodeKind.functionTypeAlias,
-    LinkedNodeKind.genericTypeAlias,
-    LinkedNodeKind.importDirective,
-    LinkedNodeKind.libraryDirective,
-    LinkedNodeKind.methodDeclaration,
-    LinkedNodeKind.mixinDeclaration,
-    LinkedNodeKind.partDirective,
-    LinkedNodeKind.partOfDirective,
-    LinkedNodeKind.topLevelVariableDeclaration,
-    LinkedNodeKind.typeParameter,
-    LinkedNodeKind.variableDeclaration,
-    LinkedNodeKind.variableDeclarationList,
-  ])
-  List<LinkedNode> get annotatedNode_metadata;
-
-  @VariantId(6, variant: LinkedNodeKind.annotation)
-  LinkedNode get annotation_arguments;
-
-  @VariantId(7, variant: LinkedNodeKind.annotation)
-  LinkedNode get annotation_constructorName;
-
-  @VariantId(17, variant: LinkedNodeKind.annotation)
-  int get annotation_element;
-
-  @VariantId(8, variant: LinkedNodeKind.annotation)
-  LinkedNode get annotation_name;
-
-  @VariantId(38, variant: LinkedNodeKind.annotation)
-  LinkedNodeTypeSubstitution get annotation_substitution;
-
-  @VariantId(2, variant: LinkedNodeKind.argumentList)
-  List<LinkedNode> get argumentList_arguments;
-
-  @VariantId(6, variant: LinkedNodeKind.asExpression)
-  LinkedNode get asExpression_expression;
-
-  @VariantId(7, variant: LinkedNodeKind.asExpression)
-  LinkedNode get asExpression_type;
-
-  @VariantId(6, variant: LinkedNodeKind.assertInitializer)
-  LinkedNode get assertInitializer_condition;
-
-  @VariantId(7, variant: LinkedNodeKind.assertInitializer)
-  LinkedNode get assertInitializer_message;
-
-  @VariantId(6, variant: LinkedNodeKind.assertStatement)
-  LinkedNode get assertStatement_condition;
-
-  @VariantId(7, variant: LinkedNodeKind.assertStatement)
-  LinkedNode get assertStatement_message;
-
-  @VariantId(15, variant: LinkedNodeKind.assignmentExpression)
-  int get assignmentExpression_element;
-
-  @VariantId(6, variant: LinkedNodeKind.assignmentExpression)
-  LinkedNode get assignmentExpression_leftHandSide;
-
-  @VariantId(28, variant: LinkedNodeKind.assignmentExpression)
-  UnlinkedTokenType get assignmentExpression_operator;
-
-  @VariantId(7, variant: LinkedNodeKind.assignmentExpression)
-  LinkedNode get assignmentExpression_rightHandSide;
-
-  @VariantId(38, variant: LinkedNodeKind.assignmentExpression)
-  LinkedNodeTypeSubstitution get assignmentExpression_substitution;
-
-  @VariantId(6, variant: LinkedNodeKind.awaitExpression)
-  LinkedNode get awaitExpression_expression;
-
-  @VariantId(15, variant: LinkedNodeKind.binaryExpression)
-  int get binaryExpression_element;
-
-  @VariantId(24, variant: LinkedNodeKind.binaryExpression)
-  LinkedNodeType get binaryExpression_invokeType;
-
-  @VariantId(6, variant: LinkedNodeKind.binaryExpression)
-  LinkedNode get binaryExpression_leftOperand;
-
-  @VariantId(28, variant: LinkedNodeKind.binaryExpression)
-  UnlinkedTokenType get binaryExpression_operator;
-
-  @VariantId(7, variant: LinkedNodeKind.binaryExpression)
-  LinkedNode get binaryExpression_rightOperand;
-
-  @VariantId(38, variant: LinkedNodeKind.binaryExpression)
-  LinkedNodeTypeSubstitution get binaryExpression_substitution;
-
-  @VariantId(2, variant: LinkedNodeKind.block)
-  List<LinkedNode> get block_statements;
-
-  @VariantId(6, variant: LinkedNodeKind.blockFunctionBody)
-  LinkedNode get blockFunctionBody_block;
-
-  @VariantId(27, variant: LinkedNodeKind.booleanLiteral)
-  bool get booleanLiteral_value;
-
-  @VariantId(6, variant: LinkedNodeKind.breakStatement)
-  LinkedNode get breakStatement_label;
-
-  @VariantId(2, variant: LinkedNodeKind.cascadeExpression)
-  List<LinkedNode> get cascadeExpression_sections;
-
-  @VariantId(6, variant: LinkedNodeKind.cascadeExpression)
-  LinkedNode get cascadeExpression_target;
-
-  @VariantId(6, variant: LinkedNodeKind.catchClause)
-  LinkedNode get catchClause_body;
-
-  @VariantId(7, variant: LinkedNodeKind.catchClause)
-  LinkedNode get catchClause_exceptionParameter;
-
-  @VariantId(8, variant: LinkedNodeKind.catchClause)
-  LinkedNode get catchClause_exceptionType;
-
-  @VariantId(9, variant: LinkedNodeKind.catchClause)
-  LinkedNode get catchClause_stackTraceParameter;
-
-  @VariantId(6, variant: LinkedNodeKind.classDeclaration)
-  LinkedNode get classDeclaration_extendsClause;
-
-  @VariantId(27, variant: LinkedNodeKind.classDeclaration)
-  bool get classDeclaration_isDartObject;
-
-  @VariantId(8, variant: LinkedNodeKind.classDeclaration)
-  LinkedNode get classDeclaration_nativeClause;
-
-  @VariantId(7, variant: LinkedNodeKind.classDeclaration)
-  LinkedNode get classDeclaration_withClause;
-
-  @VariantId(12, variantList: [
-    LinkedNodeKind.classDeclaration,
-    LinkedNodeKind.mixinDeclaration,
-  ])
-  LinkedNode get classOrMixinDeclaration_implementsClause;
-
-  @VariantId(5, variantList: [
-    LinkedNodeKind.classDeclaration,
-    LinkedNodeKind.mixinDeclaration,
-  ])
-  List<LinkedNode> get classOrMixinDeclaration_members;
-
-  @VariantId(13, variantList: [
-    LinkedNodeKind.classDeclaration,
-    LinkedNodeKind.mixinDeclaration,
-  ])
-  LinkedNode get classOrMixinDeclaration_typeParameters;
-
-  @VariantId(9, variant: LinkedNodeKind.classTypeAlias)
-  LinkedNode get classTypeAlias_implementsClause;
-
-  @VariantId(7, variant: LinkedNodeKind.classTypeAlias)
-  LinkedNode get classTypeAlias_superclass;
-
-  @VariantId(6, variant: LinkedNodeKind.classTypeAlias)
-  LinkedNode get classTypeAlias_typeParameters;
-
-  @VariantId(8, variant: LinkedNodeKind.classTypeAlias)
-  LinkedNode get classTypeAlias_withClause;
-
-  @VariantId(2, variant: LinkedNodeKind.comment)
-  List<LinkedNode> get comment_references;
-
-  @VariantId(33, variant: LinkedNodeKind.comment)
-  List<String> get comment_tokens;
-
-  @VariantId(29, variant: LinkedNodeKind.comment)
-  LinkedNodeCommentType get comment_type;
-
-  @VariantId(6, variant: LinkedNodeKind.commentReference)
-  LinkedNode get commentReference_identifier;
-
-  @VariantId(2, variant: LinkedNodeKind.compilationUnit)
-  List<LinkedNode> get compilationUnit_declarations;
-
-  @VariantId(3, variant: LinkedNodeKind.compilationUnit)
-  List<LinkedNode> get compilationUnit_directives;
-
-  @VariantId(41, variant: LinkedNodeKind.compilationUnit)
-  List<int> get compilationUnit_featureSet;
-
-  /// The language version information.
-  @VariantId(40, variant: LinkedNodeKind.compilationUnit)
-  LinkedLibraryLanguageVersion get compilationUnit_languageVersion;
-
-  @VariantId(6, variant: LinkedNodeKind.compilationUnit)
-  LinkedNode get compilationUnit_scriptTag;
-
-  @VariantId(6, variant: LinkedNodeKind.conditionalExpression)
-  LinkedNode get conditionalExpression_condition;
-
-  @VariantId(7, variant: LinkedNodeKind.conditionalExpression)
-  LinkedNode get conditionalExpression_elseExpression;
-
-  @VariantId(8, variant: LinkedNodeKind.conditionalExpression)
-  LinkedNode get conditionalExpression_thenExpression;
-
-  @VariantId(6, variant: LinkedNodeKind.configuration)
-  LinkedNode get configuration_name;
-
-  @VariantId(8, variant: LinkedNodeKind.configuration)
-  LinkedNode get configuration_uri;
-
-  @VariantId(7, variant: LinkedNodeKind.configuration)
-  LinkedNode get configuration_value;
-
-  @VariantId(6, variant: LinkedNodeKind.constructorDeclaration)
-  LinkedNode get constructorDeclaration_body;
-
-  @VariantId(2, variant: LinkedNodeKind.constructorDeclaration)
-  List<LinkedNode> get constructorDeclaration_initializers;
-
-  @VariantId(8, variant: LinkedNodeKind.constructorDeclaration)
-  LinkedNode get constructorDeclaration_parameters;
-
-  @VariantId(9, variant: LinkedNodeKind.constructorDeclaration)
-  LinkedNode get constructorDeclaration_redirectedConstructor;
-
-  @VariantId(10, variant: LinkedNodeKind.constructorDeclaration)
-  LinkedNode get constructorDeclaration_returnType;
-
-  @VariantId(6, variant: LinkedNodeKind.constructorFieldInitializer)
-  LinkedNode get constructorFieldInitializer_expression;
-
-  @VariantId(7, variant: LinkedNodeKind.constructorFieldInitializer)
-  LinkedNode get constructorFieldInitializer_fieldName;
-
-  @VariantId(15, variant: LinkedNodeKind.constructorName)
-  int get constructorName_element;
-
-  @VariantId(6, variant: LinkedNodeKind.constructorName)
-  LinkedNode get constructorName_name;
-
-  @VariantId(38, variant: LinkedNodeKind.constructorName)
-  LinkedNodeTypeSubstitution get constructorName_substitution;
-
-  @VariantId(7, variant: LinkedNodeKind.constructorName)
-  LinkedNode get constructorName_type;
-
-  @VariantId(6, variant: LinkedNodeKind.continueStatement)
-  LinkedNode get continueStatement_label;
-
-  @VariantId(6, variant: LinkedNodeKind.declaredIdentifier)
-  LinkedNode get declaredIdentifier_identifier;
-
-  @VariantId(7, variant: LinkedNodeKind.declaredIdentifier)
-  LinkedNode get declaredIdentifier_type;
-
-  @VariantId(6, variant: LinkedNodeKind.defaultFormalParameter)
-  LinkedNode get defaultFormalParameter_defaultValue;
-
-  @VariantId(26, variant: LinkedNodeKind.defaultFormalParameter)
-  LinkedNodeFormalParameterKind get defaultFormalParameter_kind;
-
-  @VariantId(7, variant: LinkedNodeKind.defaultFormalParameter)
-  LinkedNode get defaultFormalParameter_parameter;
-
-  @VariantId(6, variant: LinkedNodeKind.doStatement)
-  LinkedNode get doStatement_body;
-
-  @VariantId(7, variant: LinkedNodeKind.doStatement)
-  LinkedNode get doStatement_condition;
-
-  @VariantId(2, variant: LinkedNodeKind.dottedName)
-  List<LinkedNode> get dottedName_components;
-
-  @VariantId(21, variant: LinkedNodeKind.doubleLiteral)
-  double get doubleLiteral_value;
-
-  @VariantId(15, variant: LinkedNodeKind.emptyFunctionBody)
-  int get emptyFunctionBody_fake;
-
-  @VariantId(15, variant: LinkedNodeKind.emptyStatement)
-  int get emptyStatement_fake;
-
-  @VariantId(2, variant: LinkedNodeKind.enumDeclaration)
-  List<LinkedNode> get enumDeclaration_constants;
-
-  @VariantId(25, variantList: [
-    LinkedNodeKind.assignmentExpression,
-    LinkedNodeKind.asExpression,
-    LinkedNodeKind.awaitExpression,
-    LinkedNodeKind.binaryExpression,
-    LinkedNodeKind.cascadeExpression,
-    LinkedNodeKind.conditionalExpression,
-    LinkedNodeKind.functionExpressionInvocation,
-    LinkedNodeKind.indexExpression,
-    LinkedNodeKind.instanceCreationExpression,
-    LinkedNodeKind.integerLiteral,
-    LinkedNodeKind.listLiteral,
-    LinkedNodeKind.methodInvocation,
-    LinkedNodeKind.nullLiteral,
-    LinkedNodeKind.parenthesizedExpression,
-    LinkedNodeKind.prefixExpression,
-    LinkedNodeKind.prefixedIdentifier,
-    LinkedNodeKind.propertyAccess,
-    LinkedNodeKind.postfixExpression,
-    LinkedNodeKind.rethrowExpression,
-    LinkedNodeKind.setOrMapLiteral,
-    LinkedNodeKind.simpleIdentifier,
-    LinkedNodeKind.superExpression,
-    LinkedNodeKind.symbolLiteral,
-    LinkedNodeKind.thisExpression,
-    LinkedNodeKind.throwExpression,
-  ])
-  LinkedNodeType get expression_type;
-
-  @VariantId(6, variant: LinkedNodeKind.expressionFunctionBody)
-  LinkedNode get expressionFunctionBody_expression;
-
-  @VariantId(6, variant: LinkedNodeKind.expressionStatement)
-  LinkedNode get expressionStatement_expression;
-
-  @VariantId(6, variant: LinkedNodeKind.extendsClause)
-  LinkedNode get extendsClause_superclass;
-
-  @VariantId(7, variant: LinkedNodeKind.extensionDeclaration)
-  LinkedNode get extensionDeclaration_extendedType;
-
-  @VariantId(5, variant: LinkedNodeKind.extensionDeclaration)
-  List<LinkedNode> get extensionDeclaration_members;
-
-  @VariantId(20, variant: LinkedNodeKind.extensionDeclaration)
-  String get extensionDeclaration_refName;
-
-  @VariantId(6, variant: LinkedNodeKind.extensionDeclaration)
-  LinkedNode get extensionDeclaration_typeParameters;
-
-  @VariantId(2, variant: LinkedNodeKind.extensionOverride)
-  List<LinkedNode> get extensionOverride_arguments;
-
-  @VariantId(24, variant: LinkedNodeKind.extensionOverride)
-  LinkedNodeType get extensionOverride_extendedType;
-
-  @VariantId(7, variant: LinkedNodeKind.extensionOverride)
-  LinkedNode get extensionOverride_extensionName;
-
-  @VariantId(8, variant: LinkedNodeKind.extensionOverride)
-  LinkedNode get extensionOverride_typeArguments;
-
-  @VariantId(39, variant: LinkedNodeKind.extensionOverride)
-  List<LinkedNodeType> get extensionOverride_typeArgumentTypes;
-
-  @VariantId(6, variant: LinkedNodeKind.fieldDeclaration)
-  LinkedNode get fieldDeclaration_fields;
-
-  @VariantId(8, variant: LinkedNodeKind.fieldFormalParameter)
-  LinkedNode get fieldFormalParameter_formalParameters;
-
-  @VariantId(6, variant: LinkedNodeKind.fieldFormalParameter)
-  LinkedNode get fieldFormalParameter_type;
-
-  @VariantId(7, variant: LinkedNodeKind.fieldFormalParameter)
-  LinkedNode get fieldFormalParameter_typeParameters;
-
-  @Id(18)
-  int get flags;
-
-  @VariantId(6, variantList: [
-    LinkedNodeKind.forEachPartsWithDeclaration,
-    LinkedNodeKind.forEachPartsWithIdentifier,
-  ])
-  LinkedNode get forEachParts_iterable;
-
-  @VariantId(7, variant: LinkedNodeKind.forEachPartsWithDeclaration)
-  LinkedNode get forEachPartsWithDeclaration_loopVariable;
-
-  @VariantId(7, variant: LinkedNodeKind.forEachPartsWithIdentifier)
-  LinkedNode get forEachPartsWithIdentifier_identifier;
-
-  @VariantId(7, variant: LinkedNodeKind.forElement)
-  LinkedNode get forElement_body;
-
-  @VariantId(2, variant: LinkedNodeKind.formalParameterList)
-  List<LinkedNode> get formalParameterList_parameters;
-
-  @VariantId(6, variantList: [
-    LinkedNodeKind.forElement,
-    LinkedNodeKind.forStatement,
-  ])
-  LinkedNode get forMixin_forLoopParts;
-
-  @VariantId(6, variantList: [
-    LinkedNodeKind.forPartsWithDeclarations,
-    LinkedNodeKind.forPartsWithExpression,
-  ])
-  LinkedNode get forParts_condition;
-
-  @VariantId(5, variantList: [
-    LinkedNodeKind.forPartsWithDeclarations,
-    LinkedNodeKind.forPartsWithExpression,
-  ])
-  List<LinkedNode> get forParts_updaters;
-
-  @VariantId(7, variant: LinkedNodeKind.forPartsWithDeclarations)
-  LinkedNode get forPartsWithDeclarations_variables;
-
-  @VariantId(7, variant: LinkedNodeKind.forPartsWithExpression)
-  LinkedNode get forPartsWithExpression_initialization;
-
-  @VariantId(7, variant: LinkedNodeKind.forStatement)
-  LinkedNode get forStatement_body;
-
-  @VariantId(6, variant: LinkedNodeKind.functionDeclaration)
-  LinkedNode get functionDeclaration_functionExpression;
-
-  @VariantId(7, variant: LinkedNodeKind.functionDeclaration)
-  LinkedNode get functionDeclaration_returnType;
-
-  @VariantId(6, variant: LinkedNodeKind.functionDeclarationStatement)
-  LinkedNode get functionDeclarationStatement_functionDeclaration;
-
-  @VariantId(6, variant: LinkedNodeKind.functionExpression)
-  LinkedNode get functionExpression_body;
-
-  @VariantId(7, variant: LinkedNodeKind.functionExpression)
-  LinkedNode get functionExpression_formalParameters;
-
-  @VariantId(8, variant: LinkedNodeKind.functionExpression)
-  LinkedNode get functionExpression_typeParameters;
-
-  @VariantId(6, variant: LinkedNodeKind.functionExpressionInvocation)
-  LinkedNode get functionExpressionInvocation_function;
-
-  @VariantId(6, variant: LinkedNodeKind.functionTypeAlias)
-  LinkedNode get functionTypeAlias_formalParameters;
-
-  @VariantId(7, variant: LinkedNodeKind.functionTypeAlias)
-  LinkedNode get functionTypeAlias_returnType;
-
-  @VariantId(8, variant: LinkedNodeKind.functionTypeAlias)
-  LinkedNode get functionTypeAlias_typeParameters;
-
-  @VariantId(6, variant: LinkedNodeKind.functionTypedFormalParameter)
-  LinkedNode get functionTypedFormalParameter_formalParameters;
-
-  @VariantId(7, variant: LinkedNodeKind.functionTypedFormalParameter)
-  LinkedNode get functionTypedFormalParameter_returnType;
-
-  @VariantId(8, variant: LinkedNodeKind.functionTypedFormalParameter)
-  LinkedNode get functionTypedFormalParameter_typeParameters;
-
-  @VariantId(8, variant: LinkedNodeKind.genericFunctionType)
-  LinkedNode get genericFunctionType_formalParameters;
-
-  @VariantId(17, variant: LinkedNodeKind.genericFunctionType)
-  int get genericFunctionType_id;
-
-  @VariantId(7, variant: LinkedNodeKind.genericFunctionType)
-  LinkedNode get genericFunctionType_returnType;
-
-  @VariantId(25, variant: LinkedNodeKind.genericFunctionType)
-  LinkedNodeType get genericFunctionType_type;
-
-  @VariantId(6, variant: LinkedNodeKind.genericFunctionType)
-  LinkedNode get genericFunctionType_typeParameters;
-
-  @VariantId(7, variant: LinkedNodeKind.genericTypeAlias)
-  LinkedNode get genericTypeAlias_functionType;
-
-  @VariantId(6, variant: LinkedNodeKind.genericTypeAlias)
-  LinkedNode get genericTypeAlias_typeParameters;
-
-  @VariantId(9, variant: LinkedNodeKind.ifElement)
-  LinkedNode get ifElement_elseElement;
-
-  @VariantId(8, variant: LinkedNodeKind.ifElement)
-  LinkedNode get ifElement_thenElement;
-
-  @VariantId(6, variantList: [
-    LinkedNodeKind.ifElement,
-    LinkedNodeKind.ifStatement,
-  ])
-  LinkedNode get ifMixin_condition;
-
-  @VariantId(7, variant: LinkedNodeKind.ifStatement)
-  LinkedNode get ifStatement_elseStatement;
-
-  @VariantId(8, variant: LinkedNodeKind.ifStatement)
-  LinkedNode get ifStatement_thenStatement;
-
-  @VariantId(2, variant: LinkedNodeKind.implementsClause)
-  List<LinkedNode> get implementsClause_interfaces;
-
-  @VariantId(1, variant: LinkedNodeKind.importDirective)
-  String get importDirective_prefix;
-
-  @VariantId(15, variant: LinkedNodeKind.indexExpression)
-  int get indexExpression_element;
-
-  @VariantId(6, variant: LinkedNodeKind.indexExpression)
-  LinkedNode get indexExpression_index;
-
-  @VariantId(38, variant: LinkedNodeKind.indexExpression)
-  LinkedNodeTypeSubstitution get indexExpression_substitution;
-
-  @VariantId(7, variant: LinkedNodeKind.indexExpression)
-  LinkedNode get indexExpression_target;
-
-  @VariantId(36, variantList: [
-    LinkedNodeKind.classDeclaration,
-    LinkedNodeKind.classTypeAlias,
-    LinkedNodeKind.compilationUnit,
-    LinkedNodeKind.compilationUnit,
-    LinkedNodeKind.constructorDeclaration,
-    LinkedNodeKind.defaultFormalParameter,
-    LinkedNodeKind.enumConstantDeclaration,
-    LinkedNodeKind.enumDeclaration,
-    LinkedNodeKind.exportDirective,
-    LinkedNodeKind.extensionDeclaration,
-    LinkedNodeKind.fieldDeclaration,
-    LinkedNodeKind.fieldFormalParameter,
-    LinkedNodeKind.functionDeclaration,
-    LinkedNodeKind.functionTypedFormalParameter,
-    LinkedNodeKind.functionTypeAlias,
-    LinkedNodeKind.genericTypeAlias,
-    LinkedNodeKind.hideCombinator,
-    LinkedNodeKind.importDirective,
-    LinkedNodeKind.libraryDirective,
-    LinkedNodeKind.methodDeclaration,
-    LinkedNodeKind.mixinDeclaration,
-    LinkedNodeKind.partDirective,
-    LinkedNodeKind.partOfDirective,
-    LinkedNodeKind.showCombinator,
-    LinkedNodeKind.simpleFormalParameter,
-    LinkedNodeKind.topLevelVariableDeclaration,
-    LinkedNodeKind.typeParameter,
-    LinkedNodeKind.variableDeclaration,
-    LinkedNodeKind.variableDeclarationList,
-  ])
-  @informative
-  int get informativeId;
-
-  @VariantId(27, variantList: [
-    LinkedNodeKind.fieldFormalParameter,
-    LinkedNodeKind.functionTypedFormalParameter,
-    LinkedNodeKind.simpleFormalParameter,
-    LinkedNodeKind.variableDeclaration,
-  ])
-  bool get inheritsCovariant;
-
-  @VariantId(2, variant: LinkedNodeKind.instanceCreationExpression)
-  List<LinkedNode> get instanceCreationExpression_arguments;
-
-  @VariantId(7, variant: LinkedNodeKind.instanceCreationExpression)
-  LinkedNode get instanceCreationExpression_constructorName;
-
-  @VariantId(8, variant: LinkedNodeKind.instanceCreationExpression)
-  LinkedNode get instanceCreationExpression_typeArguments;
-
-  @VariantId(16, variant: LinkedNodeKind.integerLiteral)
-  int get integerLiteral_value;
-
-  @VariantId(6, variant: LinkedNodeKind.interpolationExpression)
-  LinkedNode get interpolationExpression_expression;
-
-  @VariantId(30, variant: LinkedNodeKind.interpolationString)
-  String get interpolationString_value;
-
-  @VariantId(14, variantList: [
-    LinkedNodeKind.functionExpressionInvocation,
-    LinkedNodeKind.methodInvocation,
-  ])
-  LinkedNode get invocationExpression_arguments;
-
-  @VariantId(24, variantList: [
-    LinkedNodeKind.functionExpressionInvocation,
-    LinkedNodeKind.methodInvocation,
-  ])
-  LinkedNodeType get invocationExpression_invokeType;
-
-  @VariantId(12, variantList: [
-    LinkedNodeKind.functionExpressionInvocation,
-    LinkedNodeKind.methodInvocation,
-  ])
-  LinkedNode get invocationExpression_typeArguments;
-
-  @VariantId(6, variant: LinkedNodeKind.isExpression)
-  LinkedNode get isExpression_expression;
-
-  @VariantId(7, variant: LinkedNodeKind.isExpression)
-  LinkedNode get isExpression_type;
-
-  @Id(0)
-  LinkedNodeKind get kind;
-
-  @VariantId(6, variant: LinkedNodeKind.label)
-  LinkedNode get label_label;
-
-  @VariantId(2, variant: LinkedNodeKind.labeledStatement)
-  List<LinkedNode> get labeledStatement_labels;
-
-  @VariantId(6, variant: LinkedNodeKind.labeledStatement)
-  LinkedNode get labeledStatement_statement;
-
-  @VariantId(6, variant: LinkedNodeKind.libraryDirective)
-  LinkedNode get libraryDirective_name;
-
-  @VariantId(2, variant: LinkedNodeKind.libraryIdentifier)
-  List<LinkedNode> get libraryIdentifier_components;
-
-  @VariantId(3, variant: LinkedNodeKind.listLiteral)
-  List<LinkedNode> get listLiteral_elements;
-
-  @VariantId(6, variant: LinkedNodeKind.mapLiteralEntry)
-  LinkedNode get mapLiteralEntry_key;
-
-  @VariantId(7, variant: LinkedNodeKind.mapLiteralEntry)
-  LinkedNode get mapLiteralEntry_value;
-
-  @VariantId(6, variant: LinkedNodeKind.methodDeclaration)
-  LinkedNode get methodDeclaration_body;
-
-  @VariantId(7, variant: LinkedNodeKind.methodDeclaration)
-  LinkedNode get methodDeclaration_formalParameters;
-
-  @VariantId(31, variant: LinkedNodeKind.methodDeclaration)
-  bool get methodDeclaration_hasOperatorEqualWithParameterTypeFromObject;
-
-  @VariantId(8, variant: LinkedNodeKind.methodDeclaration)
-  LinkedNode get methodDeclaration_returnType;
-
-  @VariantId(9, variant: LinkedNodeKind.methodDeclaration)
-  LinkedNode get methodDeclaration_typeParameters;
-
-  @VariantId(6, variant: LinkedNodeKind.methodInvocation)
-  LinkedNode get methodInvocation_methodName;
-
-  @VariantId(7, variant: LinkedNodeKind.methodInvocation)
-  LinkedNode get methodInvocation_target;
-
-  @VariantId(6, variant: LinkedNodeKind.mixinDeclaration)
-  LinkedNode get mixinDeclaration_onClause;
-
-  @VariantId(34, variant: LinkedNodeKind.mixinDeclaration)
-  List<String> get mixinDeclaration_superInvokedNames;
-
-  @Id(37)
-  String get name;
-
-  @VariantId(6, variant: LinkedNodeKind.namedExpression)
-  LinkedNode get namedExpression_expression;
-
-  @VariantId(7, variant: LinkedNodeKind.namedExpression)
-  LinkedNode get namedExpression_name;
-
-  @VariantId(34, variantList: [
-    LinkedNodeKind.hideCombinator,
-    LinkedNodeKind.showCombinator,
-    LinkedNodeKind.symbolLiteral,
-  ])
-  List<String> get names;
-
-  @VariantId(2, variantList: [
-    LinkedNodeKind.exportDirective,
-    LinkedNodeKind.importDirective,
-  ])
-  List<LinkedNode> get namespaceDirective_combinators;
-
-  @VariantId(3, variantList: [
-    LinkedNodeKind.exportDirective,
-    LinkedNodeKind.importDirective,
-  ])
-  List<LinkedNode> get namespaceDirective_configurations;
-
-  @VariantId(20, variantList: [
-    LinkedNodeKind.exportDirective,
-    LinkedNodeKind.importDirective,
-  ])
-  String get namespaceDirective_selectedUri;
-
-  @VariantId(6, variant: LinkedNodeKind.nativeClause)
-  LinkedNode get nativeClause_name;
-
-  @VariantId(6, variant: LinkedNodeKind.nativeFunctionBody)
-  LinkedNode get nativeFunctionBody_stringLiteral;
-
-  @VariantId(4, variantList: [
-    LinkedNodeKind.fieldFormalParameter,
-    LinkedNodeKind.functionTypedFormalParameter,
-    LinkedNodeKind.simpleFormalParameter,
-  ])
-  List<LinkedNode> get normalFormalParameter_metadata;
-
-  @VariantId(15, variant: LinkedNodeKind.nullLiteral)
-  int get nullLiteral_fake;
-
-  @VariantId(2, variant: LinkedNodeKind.onClause)
-  List<LinkedNode> get onClause_superclassConstraints;
-
-  @VariantId(6, variant: LinkedNodeKind.parenthesizedExpression)
-  LinkedNode get parenthesizedExpression_expression;
-
-  @VariantId(6, variant: LinkedNodeKind.partOfDirective)
-  LinkedNode get partOfDirective_libraryName;
-
-  @VariantId(7, variant: LinkedNodeKind.partOfDirective)
-  LinkedNode get partOfDirective_uri;
-
-  @VariantId(15, variant: LinkedNodeKind.postfixExpression)
-  int get postfixExpression_element;
-
-  @VariantId(6, variant: LinkedNodeKind.postfixExpression)
-  LinkedNode get postfixExpression_operand;
-
-  @VariantId(28, variant: LinkedNodeKind.postfixExpression)
-  UnlinkedTokenType get postfixExpression_operator;
-
-  @VariantId(38, variant: LinkedNodeKind.postfixExpression)
-  LinkedNodeTypeSubstitution get postfixExpression_substitution;
-
-  @VariantId(6, variant: LinkedNodeKind.prefixedIdentifier)
-  LinkedNode get prefixedIdentifier_identifier;
-
-  @VariantId(7, variant: LinkedNodeKind.prefixedIdentifier)
-  LinkedNode get prefixedIdentifier_prefix;
-
-  @VariantId(15, variant: LinkedNodeKind.prefixExpression)
-  int get prefixExpression_element;
-
-  @VariantId(6, variant: LinkedNodeKind.prefixExpression)
-  LinkedNode get prefixExpression_operand;
-
-  @VariantId(28, variant: LinkedNodeKind.prefixExpression)
-  UnlinkedTokenType get prefixExpression_operator;
-
-  @VariantId(38, variant: LinkedNodeKind.prefixExpression)
-  LinkedNodeTypeSubstitution get prefixExpression_substitution;
-
-  @VariantId(28, variant: LinkedNodeKind.propertyAccess)
-  UnlinkedTokenType get propertyAccess_operator;
-
-  @VariantId(6, variant: LinkedNodeKind.propertyAccess)
-  LinkedNode get propertyAccess_propertyName;
-
-  @VariantId(7, variant: LinkedNodeKind.propertyAccess)
-  LinkedNode get propertyAccess_target;
-
-  @VariantId(6, variant: LinkedNodeKind.redirectingConstructorInvocation)
-  LinkedNode get redirectingConstructorInvocation_arguments;
-
-  @VariantId(7, variant: LinkedNodeKind.redirectingConstructorInvocation)
-  LinkedNode get redirectingConstructorInvocation_constructorName;
-
-  @VariantId(15, variant: LinkedNodeKind.redirectingConstructorInvocation)
-  int get redirectingConstructorInvocation_element;
-
-  @VariantId(38, variant: LinkedNodeKind.redirectingConstructorInvocation)
-  LinkedNodeTypeSubstitution get redirectingConstructorInvocation_substitution;
-
-  @VariantId(6, variant: LinkedNodeKind.returnStatement)
-  LinkedNode get returnStatement_expression;
-
-  @VariantId(3, variant: LinkedNodeKind.setOrMapLiteral)
-  List<LinkedNode> get setOrMapLiteral_elements;
-
-  @VariantId(6, variant: LinkedNodeKind.simpleFormalParameter)
-  LinkedNode get simpleFormalParameter_type;
-
-  @VariantId(15, variant: LinkedNodeKind.simpleIdentifier)
-  int get simpleIdentifier_element;
-
-  @VariantId(38, variant: LinkedNodeKind.simpleIdentifier)
-  LinkedNodeTypeSubstitution get simpleIdentifier_substitution;
-
-  @VariantId(20, variant: LinkedNodeKind.simpleStringLiteral)
-  String get simpleStringLiteral_value;
-
-  @VariantId(31, variantList: [
-    LinkedNodeKind.classDeclaration,
-    LinkedNodeKind.classTypeAlias,
-    LinkedNodeKind.functionTypeAlias,
-    LinkedNodeKind.genericTypeAlias,
-    LinkedNodeKind.mixinDeclaration,
-  ])
-  bool get simplyBoundable_isSimplyBounded;
-
-  @VariantId(6, variant: LinkedNodeKind.spreadElement)
-  LinkedNode get spreadElement_expression;
-
-  @VariantId(35, variant: LinkedNodeKind.spreadElement)
-  UnlinkedTokenType get spreadElement_spreadOperator;
-
-  @VariantId(2, variant: LinkedNodeKind.stringInterpolation)
-  List<LinkedNode> get stringInterpolation_elements;
-
-  @VariantId(6, variant: LinkedNodeKind.superConstructorInvocation)
-  LinkedNode get superConstructorInvocation_arguments;
-
-  @VariantId(7, variant: LinkedNodeKind.superConstructorInvocation)
-  LinkedNode get superConstructorInvocation_constructorName;
-
-  @VariantId(15, variant: LinkedNodeKind.superConstructorInvocation)
-  int get superConstructorInvocation_element;
-
-  @VariantId(38, variant: LinkedNodeKind.superConstructorInvocation)
-  LinkedNodeTypeSubstitution get superConstructorInvocation_substitution;
-
-  @VariantId(6, variant: LinkedNodeKind.switchCase)
-  LinkedNode get switchCase_expression;
-
-  @VariantId(3, variantList: [
-    LinkedNodeKind.switchCase,
-    LinkedNodeKind.switchDefault,
-  ])
-  List<LinkedNode> get switchMember_labels;
-
-  @VariantId(4, variantList: [
-    LinkedNodeKind.switchCase,
-    LinkedNodeKind.switchDefault,
-  ])
-  List<LinkedNode> get switchMember_statements;
-
-  @VariantId(7, variant: LinkedNodeKind.switchStatement)
-  LinkedNode get switchStatement_expression;
-
-  @VariantId(2, variant: LinkedNodeKind.switchStatement)
-  List<LinkedNode> get switchStatement_members;
-
-  @VariantId(6, variant: LinkedNodeKind.throwExpression)
-  LinkedNode get throwExpression_expression;
-
-  @VariantId(32, variantList: [
-    LinkedNodeKind.methodDeclaration,
-    LinkedNodeKind.simpleFormalParameter,
-    LinkedNodeKind.variableDeclaration,
-  ])
-  TopLevelInferenceError get topLevelTypeInferenceError;
-
-  @VariantId(6, variant: LinkedNodeKind.topLevelVariableDeclaration)
-  LinkedNode get topLevelVariableDeclaration_variableList;
-
-  @VariantId(6, variant: LinkedNodeKind.tryStatement)
-  LinkedNode get tryStatement_body;
-
-  @VariantId(2, variant: LinkedNodeKind.tryStatement)
-  List<LinkedNode> get tryStatement_catchClauses;
-
-  @VariantId(7, variant: LinkedNodeKind.tryStatement)
-  LinkedNode get tryStatement_finallyBlock;
-
-  @VariantId(27, variantList: [
-    LinkedNodeKind.functionTypeAlias,
-    LinkedNodeKind.genericTypeAlias,
-  ])
-  bool get typeAlias_hasSelfReference;
-
-  @VariantId(2, variant: LinkedNodeKind.typeArgumentList)
-  List<LinkedNode> get typeArgumentList_arguments;
-
-  @VariantId(2, variantList: [
-    LinkedNodeKind.listLiteral,
-    LinkedNodeKind.setOrMapLiteral,
-  ])
-  List<LinkedNode> get typedLiteral_typeArguments;
-
-  @VariantId(6, variant: LinkedNodeKind.typeName)
-  LinkedNode get typeName_name;
-
-  @VariantId(23, variant: LinkedNodeKind.typeName)
-  LinkedNodeType get typeName_type;
-
-  @VariantId(2, variant: LinkedNodeKind.typeName)
-  List<LinkedNode> get typeName_typeArguments;
-
-  @VariantId(6, variant: LinkedNodeKind.typeParameter)
-  LinkedNode get typeParameter_bound;
-
-  @VariantId(23, variant: LinkedNodeKind.typeParameter)
-  LinkedNodeType get typeParameter_defaultType;
-
-  @VariantId(15, variant: LinkedNodeKind.typeParameter)
-  int get typeParameter_variance;
-
-  @VariantId(2, variant: LinkedNodeKind.typeParameterList)
-  List<LinkedNode> get typeParameterList_typeParameters;
-
-  @VariantId(11, variantList: [
-    LinkedNodeKind.classDeclaration,
-  ])
-  LinkedNode get unused11;
-
-  @VariantId(14, variantList: [
-    LinkedNodeKind.exportDirective,
-    LinkedNodeKind.importDirective,
-    LinkedNodeKind.partDirective,
-  ])
-  LinkedNode get uriBasedDirective_uri;
-
-  @VariantId(22, variantList: [
-    LinkedNodeKind.exportDirective,
-    LinkedNodeKind.importDirective,
-    LinkedNodeKind.partDirective,
-  ])
-  String get uriBasedDirective_uriContent;
-
-  @VariantId(19, variantList: [
-    LinkedNodeKind.exportDirective,
-    LinkedNodeKind.importDirective,
-    LinkedNodeKind.partDirective,
-  ])
-  int get uriBasedDirective_uriElement;
-
-  @VariantId(6, variant: LinkedNodeKind.variableDeclaration)
-  LinkedNode get variableDeclaration_initializer;
-
-  @VariantId(6, variant: LinkedNodeKind.variableDeclarationList)
-  LinkedNode get variableDeclarationList_type;
-
-  @VariantId(2, variant: LinkedNodeKind.variableDeclarationList)
-  List<LinkedNode> get variableDeclarationList_variables;
-
-  @VariantId(6, variant: LinkedNodeKind.variableDeclarationStatement)
-  LinkedNode get variableDeclarationStatement_variables;
-
-  @VariantId(6, variant: LinkedNodeKind.whileStatement)
-  LinkedNode get whileStatement_body;
-
-  @VariantId(7, variant: LinkedNodeKind.whileStatement)
-  LinkedNode get whileStatement_condition;
-
-  @VariantId(2, variant: LinkedNodeKind.withClause)
-  List<LinkedNode> get withClause_mixinTypes;
-
-  @VariantId(6, variant: LinkedNodeKind.yieldStatement)
-  LinkedNode get yieldStatement_expression;
-}
-
-/// Information about a group of libraries linked together, for example because
-/// they form a single cycle, or because they represent a single build artifact.
-@TopLevel('LNBn')
-abstract class LinkedNodeBundle extends base.SummaryClass {
-  factory LinkedNodeBundle.fromBuffer(List<int> buffer) =>
-      generated.readLinkedNodeBundle(buffer);
-  @Id(1)
-  List<LinkedNodeLibrary> get libraries;
-
-  /// The shared list of references used in the [libraries].
-  @Id(0)
-  LinkedNodeReferences get references;
-}
-
-/// Types of comments.
-enum LinkedNodeCommentType { block, documentation, endOfLine }
-
-/// Kinds of formal parameters.
-enum LinkedNodeFormalParameterKind {
-  requiredPositional,
-  optionalPositional,
-  optionalNamed,
-  requiredNamed
-}
-
-/// Kinds of [LinkedNode].
-enum LinkedNodeKind {
-  adjacentStrings,
-  annotation,
-  argumentList,
-  asExpression,
-  assertInitializer,
-  assertStatement,
-  assignmentExpression,
-  awaitExpression,
-  binaryExpression,
-  block,
-  blockFunctionBody,
-  booleanLiteral,
-  breakStatement,
-  cascadeExpression,
-  catchClause,
-  classDeclaration,
-  classTypeAlias,
-  comment,
-  commentReference,
-  compilationUnit,
-  conditionalExpression,
-  configuration,
-  constructorDeclaration,
-  constructorFieldInitializer,
-  constructorName,
-  continueStatement,
-  declaredIdentifier,
-  defaultFormalParameter,
-  doubleLiteral,
-  doStatement,
-  dottedName,
-  emptyFunctionBody,
-  emptyStatement,
-  enumConstantDeclaration,
-  enumDeclaration,
-  exportDirective,
-  expressionFunctionBody,
-  expressionStatement,
-  extendsClause,
-  extensionDeclaration,
-  fieldDeclaration,
-  fieldFormalParameter,
-  formalParameterList,
-  forEachPartsWithDeclaration,
-  forEachPartsWithIdentifier,
-  forElement,
-  forPartsWithDeclarations,
-  forPartsWithExpression,
-  forStatement,
-  functionDeclaration,
-  functionDeclarationStatement,
-  functionExpression,
-  functionExpressionInvocation,
-  functionTypeAlias,
-  functionTypedFormalParameter,
-  genericFunctionType,
-  genericTypeAlias,
-  hideCombinator,
-  ifElement,
-  ifStatement,
-  implementsClause,
-  importDirective,
-  instanceCreationExpression,
-  indexExpression,
-  integerLiteral,
-  interpolationExpression,
-  interpolationString,
-  isExpression,
-  label,
-  labeledStatement,
-  libraryDirective,
-  libraryIdentifier,
-  listLiteral,
-  mapLiteralEntry,
-  methodDeclaration,
-  methodInvocation,
-  mixinDeclaration,
-  namedExpression,
-  nativeClause,
-  nativeFunctionBody,
-  nullLiteral,
-  onClause,
-  parenthesizedExpression,
-  partDirective,
-  partOfDirective,
-  postfixExpression,
-  prefixExpression,
-  prefixedIdentifier,
-  propertyAccess,
-  redirectingConstructorInvocation,
-  rethrowExpression,
-  returnStatement,
-  setOrMapLiteral,
-  showCombinator,
-  simpleFormalParameter,
-  simpleIdentifier,
-  simpleStringLiteral,
-  spreadElement,
-  stringInterpolation,
-  superConstructorInvocation,
-  superExpression,
-  switchCase,
-  switchDefault,
-  switchStatement,
-  symbolLiteral,
-  thisExpression,
-  throwExpression,
-  topLevelVariableDeclaration,
-  tryStatement,
-  typeArgumentList,
-  typeName,
-  typeParameter,
-  typeParameterList,
-  variableDeclaration,
-  variableDeclarationList,
-  variableDeclarationStatement,
-  whileStatement,
-  withClause,
-  yieldStatement,
-  extensionOverride,
-}
-
-/// Information about a single library in a [LinkedNodeBundle].
-abstract class LinkedNodeLibrary extends base.SummaryClass {
-  @Id(2)
-  List<int> get exports;
-
-  @Id(3)
-  String get name;
-
-  @Id(5)
-  int get nameLength;
-
-  @Id(4)
-  int get nameOffset;
-
-  @Id(1)
-  List<LinkedNodeUnit> get units;
-
-  @Id(0)
-  String get uriStr;
-}
-
-/// Flattened tree of declarations referenced from [LinkedNode]s.
-abstract class LinkedNodeReferences extends base.SummaryClass {
-  @Id(1)
-  List<String> get name;
-
-  @Id(0)
-  List<int> get parent;
-}
-
-/// Information about a Dart type.
-abstract class LinkedNodeType extends base.SummaryClass {
-  @Id(0)
-  List<LinkedNodeTypeFormalParameter> get functionFormalParameters;
-
-  @Id(1)
-  LinkedNodeType get functionReturnType;
-
-  /// The typedef this function type is created for.
-  @Id(9)
-  int get functionTypedef;
-
-  @Id(10)
-  List<LinkedNodeType> get functionTypedefTypeArguments;
-
-  @Id(2)
-  List<LinkedNodeTypeTypeParameter> get functionTypeParameters;
-
-  /// Reference to a [LinkedNodeReferences].
-  @Id(3)
-  int get interfaceClass;
-
-  @Id(4)
-  List<LinkedNodeType> get interfaceTypeArguments;
-
-  @Id(5)
-  LinkedNodeTypeKind get kind;
-
-  @Id(8)
-  EntityRefNullabilitySuffix get nullabilitySuffix;
-
-  @Id(6)
-  int get typeParameterElement;
-
-  @Id(7)
-  int get typeParameterId;
-}
-
-/// Information about a formal parameter in a function type.
-abstract class LinkedNodeTypeFormalParameter extends base.SummaryClass {
-  @Id(0)
-  LinkedNodeFormalParameterKind get kind;
-
-  @Id(1)
-  String get name;
-
-  @Id(2)
-  LinkedNodeType get type;
-}
-
-/// Kinds of [LinkedNodeType]s.
-enum LinkedNodeTypeKind {
-  dynamic_,
-  function,
-  interface,
-  never,
-  typeParameter,
-  void_
-}
-
-/// Information about a type substitution.
-abstract class LinkedNodeTypeSubstitution extends base.SummaryClass {
-  @Id(2)
-  bool get isLegacy;
-
-  @Id(1)
-  List<LinkedNodeType> get typeArguments;
-
-  @Id(0)
-  List<int> get typeParameters;
-}
-
-/// Information about a type parameter in a function type.
-abstract class LinkedNodeTypeTypeParameter extends base.SummaryClass {
-  @Id(1)
-  LinkedNodeType get bound;
-
-  @Id(0)
-  String get name;
-}
-
-/// Information about a single library in a [LinkedNodeLibrary].
-abstract class LinkedNodeUnit extends base.SummaryClass {
-  @Id(2)
-  bool get isSynthetic;
-
-  @Id(1)
-  LinkedNode get node;
-
-  /// If the unit is a part, the URI specified in the `part` directive.
-  /// Otherwise empty.
-  @Id(3)
-  String get partUriStr;
-
-  /// The absolute URI.
-  @Id(0)
-  String get uriStr;
-}
-
 /// Summary information about a package.
 @TopLevel('PBdl')
 abstract class PackageBundle extends base.SummaryClass {
@@ -1900,170 +602,7 @@
 
   /// The version 2 of the summary.
   @Id(0)
-  LinkedNodeBundle get bundle2;
-
-  /// The SDK specific data, if this bundle is for SDK.
-  @Id(1)
-  PackageBundleSdk get sdk;
-}
-
-/// Summary information about a package.
-abstract class PackageBundleSdk extends base.SummaryClass {
-  /// The content of the `allowed_experiments.json` from SDK.
-  @Id(0)
-  String get allowedExperimentsJson;
-
-  /// The language version of the SDK.
-  @Id(1)
-  LinkedLanguageVersion get languageVersion;
-}
-
-/// Summary information about a top-level type inference error.
-abstract class TopLevelInferenceError extends base.SummaryClass {
-  /// The [kind] specific arguments.
-  @Id(1)
-  List<String> get arguments;
-
-  /// The kind of the error.
-  @Id(0)
-  TopLevelInferenceErrorKind get kind;
-}
-
-/// Enum used to indicate the kind of the error during top-level inference.
-enum TopLevelInferenceErrorKind {
-  assignment,
-  instanceGetter,
-  dependencyCycle,
-  overrideConflictFieldType,
-  overrideNoCombinedSuperSignature,
-}
-
-@Variant('kind')
-abstract class UnlinkedInformativeData extends base.SummaryClass {
-  @VariantId(2, variantList: [
-    LinkedNodeKind.classDeclaration,
-    LinkedNodeKind.classTypeAlias,
-    LinkedNodeKind.compilationUnit,
-    LinkedNodeKind.constructorDeclaration,
-    LinkedNodeKind.defaultFormalParameter,
-    LinkedNodeKind.enumConstantDeclaration,
-    LinkedNodeKind.enumDeclaration,
-    LinkedNodeKind.extensionDeclaration,
-    LinkedNodeKind.fieldFormalParameter,
-    LinkedNodeKind.functionDeclaration,
-    LinkedNodeKind.functionTypeAlias,
-    LinkedNodeKind.functionTypedFormalParameter,
-    LinkedNodeKind.genericTypeAlias,
-    LinkedNodeKind.methodDeclaration,
-    LinkedNodeKind.mixinDeclaration,
-    LinkedNodeKind.simpleFormalParameter,
-    LinkedNodeKind.typeParameter,
-    LinkedNodeKind.variableDeclaration,
-  ])
-  int get codeLength;
-
-  @VariantId(3, variantList: [
-    LinkedNodeKind.classDeclaration,
-    LinkedNodeKind.classTypeAlias,
-    LinkedNodeKind.compilationUnit,
-    LinkedNodeKind.constructorDeclaration,
-    LinkedNodeKind.defaultFormalParameter,
-    LinkedNodeKind.enumConstantDeclaration,
-    LinkedNodeKind.enumDeclaration,
-    LinkedNodeKind.extensionDeclaration,
-    LinkedNodeKind.fieldFormalParameter,
-    LinkedNodeKind.functionDeclaration,
-    LinkedNodeKind.functionTypeAlias,
-    LinkedNodeKind.functionTypedFormalParameter,
-    LinkedNodeKind.genericTypeAlias,
-    LinkedNodeKind.methodDeclaration,
-    LinkedNodeKind.mixinDeclaration,
-    LinkedNodeKind.simpleFormalParameter,
-    LinkedNodeKind.typeParameter,
-    LinkedNodeKind.variableDeclaration,
-  ])
-  int get codeOffset;
-
-  @VariantId(9, variantList: [
-    LinkedNodeKind.hideCombinator,
-    LinkedNodeKind.showCombinator,
-  ])
-  int get combinatorEnd;
-
-  @VariantId(8, variantList: [
-    LinkedNodeKind.hideCombinator,
-    LinkedNodeKind.showCombinator,
-  ])
-  int get combinatorKeywordOffset;
-
-  /// Offsets of the first character of each line in the source code.
-  @VariantId(7, variant: LinkedNodeKind.compilationUnit)
-  List<int> get compilationUnit_lineStarts;
-
-  @VariantId(6, variant: LinkedNodeKind.constructorDeclaration)
-  int get constructorDeclaration_periodOffset;
-
-  @VariantId(5, variant: LinkedNodeKind.constructorDeclaration)
-  int get constructorDeclaration_returnTypeOffset;
-
-  /// If the parameter has a default value, the source text of the constant
-  /// expression in the default value.  Otherwise the empty string.
-  @VariantId(10, variant: LinkedNodeKind.defaultFormalParameter)
-  String get defaultFormalParameter_defaultValueCode;
-
-  @VariantId(1, variantList: [
-    LinkedNodeKind.exportDirective,
-    LinkedNodeKind.importDirective,
-    LinkedNodeKind.libraryDirective,
-    LinkedNodeKind.partDirective,
-    LinkedNodeKind.partOfDirective,
-  ])
-  int get directiveKeywordOffset;
-
-  @VariantId(4, variantList: [
-    LinkedNodeKind.classDeclaration,
-    LinkedNodeKind.classTypeAlias,
-    LinkedNodeKind.constructorDeclaration,
-    LinkedNodeKind.enumDeclaration,
-    LinkedNodeKind.enumConstantDeclaration,
-    LinkedNodeKind.extensionDeclaration,
-    LinkedNodeKind.fieldDeclaration,
-    LinkedNodeKind.functionDeclaration,
-    LinkedNodeKind.functionTypeAlias,
-    LinkedNodeKind.genericTypeAlias,
-    LinkedNodeKind.libraryDirective,
-    LinkedNodeKind.methodDeclaration,
-    LinkedNodeKind.mixinDeclaration,
-    LinkedNodeKind.topLevelVariableDeclaration,
-  ])
-  List<String> get documentationComment_tokens;
-
-  @VariantId(8, variant: LinkedNodeKind.importDirective)
-  int get importDirective_prefixOffset;
-
-  /// The kind of the node.
-  @Id(0)
-  LinkedNodeKind get kind;
-
-  @VariantId(1, variantList: [
-    LinkedNodeKind.classDeclaration,
-    LinkedNodeKind.classTypeAlias,
-    LinkedNodeKind.constructorDeclaration,
-    LinkedNodeKind.enumConstantDeclaration,
-    LinkedNodeKind.enumDeclaration,
-    LinkedNodeKind.extensionDeclaration,
-    LinkedNodeKind.fieldFormalParameter,
-    LinkedNodeKind.functionDeclaration,
-    LinkedNodeKind.functionTypedFormalParameter,
-    LinkedNodeKind.functionTypeAlias,
-    LinkedNodeKind.genericTypeAlias,
-    LinkedNodeKind.methodDeclaration,
-    LinkedNodeKind.mixinDeclaration,
-    LinkedNodeKind.simpleFormalParameter,
-    LinkedNodeKind.typeParameter,
-    LinkedNodeKind.variableDeclaration,
-  ])
-  int get nameOffset;
+  int get fake;
 }
 
 /// Unlinked summary information about a namespace directive.
@@ -2095,153 +634,6 @@
   String get value;
 }
 
-/// Enum of token types, corresponding to AST token types.
-enum UnlinkedTokenType {
-  NOTHING,
-  ABSTRACT,
-  AMPERSAND,
-  AMPERSAND_AMPERSAND,
-  AMPERSAND_EQ,
-  AS,
-  ASSERT,
-  ASYNC,
-  AT,
-  AWAIT,
-  BACKPING,
-  BACKSLASH,
-  BANG,
-  BANG_EQ,
-  BANG_EQ_EQ,
-  BAR,
-  BAR_BAR,
-  BAR_EQ,
-  BREAK,
-  CARET,
-  CARET_EQ,
-  CASE,
-  CATCH,
-  CLASS,
-  CLOSE_CURLY_BRACKET,
-  CLOSE_PAREN,
-  CLOSE_SQUARE_BRACKET,
-  COLON,
-  COMMA,
-  CONST,
-  CONTINUE,
-  COVARIANT,
-  DEFAULT,
-  DEFERRED,
-  DO,
-  DOUBLE,
-  DYNAMIC,
-  ELSE,
-  ENUM,
-  EOF,
-  EQ,
-  EQ_EQ,
-  EQ_EQ_EQ,
-  EXPORT,
-  EXTENDS,
-  EXTERNAL,
-  FACTORY,
-  FALSE,
-  FINAL,
-  FINALLY,
-  FOR,
-  FUNCTION,
-  FUNCTION_KEYWORD,
-  GET,
-  GT,
-  GT_EQ,
-  GT_GT,
-  GT_GT_EQ,
-  GT_GT_GT,
-  GT_GT_GT_EQ,
-  HASH,
-  HEXADECIMAL,
-  HIDE,
-  IDENTIFIER,
-  IF,
-  IMPLEMENTS,
-  IMPORT,
-  IN,
-  INDEX,
-  INDEX_EQ,
-  INT,
-  INTERFACE,
-  IS,
-  LATE,
-  LIBRARY,
-  LT,
-  LT_EQ,
-  LT_LT,
-  LT_LT_EQ,
-  MINUS,
-  MINUS_EQ,
-  MINUS_MINUS,
-  MIXIN,
-  MULTI_LINE_COMMENT,
-  NATIVE,
-  NEW,
-  NULL,
-  OF,
-  ON,
-  OPEN_CURLY_BRACKET,
-  OPEN_PAREN,
-  OPEN_SQUARE_BRACKET,
-  OPERATOR,
-  PART,
-  PATCH,
-  PERCENT,
-  PERCENT_EQ,
-  PERIOD,
-  PERIOD_PERIOD,
-  PERIOD_PERIOD_PERIOD,
-  PERIOD_PERIOD_PERIOD_QUESTION,
-  PLUS,
-  PLUS_EQ,
-  PLUS_PLUS,
-  QUESTION,
-  QUESTION_PERIOD,
-  QUESTION_QUESTION,
-  QUESTION_QUESTION_EQ,
-  REQUIRED,
-  RETHROW,
-  RETURN,
-  SCRIPT_TAG,
-  SEMICOLON,
-  SET,
-  SHOW,
-  SINGLE_LINE_COMMENT,
-  SLASH,
-  SLASH_EQ,
-  SOURCE,
-  STAR,
-  STAR_EQ,
-  STATIC,
-  STRING,
-  STRING_INTERPOLATION_EXPRESSION,
-  STRING_INTERPOLATION_IDENTIFIER,
-  SUPER,
-  SWITCH,
-  SYNC,
-  THIS,
-  THROW,
-  TILDE,
-  TILDE_SLASH,
-  TILDE_SLASH_EQ,
-  TRUE,
-  TRY,
-  TYPEDEF,
-  VAR,
-  VOID,
-  WHILE,
-  WITH,
-  YIELD,
-  INOUT,
-  OUT,
-}
-
 /// Unlinked summary information about a compilation unit.
 @TopLevel('UUN2')
 abstract class UnlinkedUnit2 extends base.SummaryClass {
@@ -2269,16 +661,13 @@
   @Id(2)
   List<UnlinkedNamespaceDirective> get imports;
 
-  @Id(7)
-  List<UnlinkedInformativeData> get informativeData;
-
   /// Offsets of the first character of each line in the source code.
   @informative
   @Id(5)
   List<int> get lineStarts;
 
   /// URI of the `part of` directive.
-  @Id(8)
+  @Id(7)
   String get partOfUri;
 
   /// URIs of `part` directives.
diff --git a/pkg/analyzer/lib/src/summary/package_bundle_reader.dart b/pkg/analyzer/lib/src/summary/package_bundle_reader.dart
index 0aa30cd..b206f48 100644
--- a/pkg/analyzer/lib/src/summary/package_bundle_reader.dart
+++ b/pkg/analyzer/lib/src/summary/package_bundle_reader.dart
@@ -9,7 +9,7 @@
 import 'package:analyzer/src/generated/engine.dart';
 import 'package:analyzer/src/generated/source.dart';
 import 'package:analyzer/src/generated/source_io.dart';
-import 'package:analyzer/src/summary/idl.dart';
+import 'package:analyzer/src/summary2/package_bundle_format.dart';
 
 /// A [ConflictingSummaryException] indicates that two different summaries
 /// provided to a [SummaryDataStore] conflict.
@@ -109,8 +109,8 @@
 /// summary package bundles.  It contains maps which can be used to find linked
 /// and unlinked summaries by URI.
 class SummaryDataStore {
-  /// List of all [PackageBundle]s.
-  final List<PackageBundle> bundles = <PackageBundle>[];
+  /// List of all [PackageBundleReader]s.
+  final List<PackageBundleReader> bundles = [];
 
   /// Map from the URI of a unit to the summary path that contained it.
   final Map<String, String> uriToSummaryPath = <String, String>{};
@@ -126,19 +126,17 @@
   }
 
   /// Add the given [bundle] loaded from the file with the given [path].
-  void addBundle(String path, PackageBundle bundle) {
+  void addBundle(String path, PackageBundleReader bundle) {
     bundles.add(bundle);
 
-    if (bundle.bundle2 != null) {
-      for (var library in bundle.bundle2.libraries) {
-        var libraryUri = library.uriStr;
-        _libraryUris.add(libraryUri);
-        for (var unit in library.units) {
-          var unitUri = unit.uriStr;
-          uriToSummaryPath[unitUri] = path;
-          if (unitUri != libraryUri) {
-            _partUris.add(unitUri);
-          }
+    for (var library in bundle.libraries) {
+      var libraryUri = library.uriStr;
+      _libraryUris.add(libraryUri);
+      for (var unit in library.units) {
+        var unitUri = unit.uriStr;
+        uriToSummaryPath[unitUri] = path;
+        if (unitUri != libraryUri) {
+          _partUris.add(unitUri);
         }
       }
     }
@@ -162,15 +160,15 @@
   }
 
   void _fillMaps(String path, ResourceProvider resourceProvider) {
-    List<int> buffer;
+    List<int> bytes;
     if (resourceProvider != null) {
       var file = resourceProvider.getFile(path);
-      buffer = file.readAsBytesSync();
+      bytes = file.readAsBytesSync();
     } else {
       io.File file = io.File(path);
-      buffer = file.readAsBytesSync();
+      bytes = file.readAsBytesSync();
     }
-    PackageBundle bundle = PackageBundle.fromBuffer(buffer);
+    var bundle = PackageBundleReader(bytes);
     addBundle(path, bundle);
   }
 }
diff --git a/pkg/analyzer/lib/src/summary/summarize_elements.dart b/pkg/analyzer/lib/src/summary/summarize_elements.dart
deleted file mode 100644
index 1c5a27b..0000000
--- a/pkg/analyzer/lib/src/summary/summarize_elements.dart
+++ /dev/null
@@ -1,23 +0,0 @@
-// Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'package:analyzer/src/summary/format.dart';
-
-/// Object that gathers information uses it to assemble a new
-/// [PackageBundleBuilder].
-class PackageBundleAssembler {
-  LinkedNodeBundleBuilder _bundle2;
-
-  /// Assemble a new [PackageBundleBuilder] using the gathered information.
-  PackageBundleBuilder assemble() {
-    return PackageBundleBuilder(bundle2: _bundle2);
-  }
-
-  void setBundle2(LinkedNodeBundleBuilder bundle2) {
-    if (_bundle2 != null) {
-      throw StateError('Bundle2 may be set only once.');
-    }
-    _bundle2 = bundle2;
-  }
-}
diff --git a/pkg/analyzer/lib/src/summary/summary_sdk.dart b/pkg/analyzer/lib/src/summary/summary_sdk.dart
index 809db0f..2d0bd29 100644
--- a/pkg/analyzer/lib/src/summary/summary_sdk.dart
+++ b/pkg/analyzer/lib/src/summary/summary_sdk.dart
@@ -5,8 +5,8 @@
 import 'package:analyzer/file_system/file_system.dart' show ResourceProvider;
 import 'package:analyzer/src/generated/sdk.dart';
 import 'package:analyzer/src/generated/source.dart' show Source;
-import 'package:analyzer/src/summary/idl.dart';
 import 'package:analyzer/src/summary/package_bundle_reader.dart';
+import 'package:analyzer/src/summary2/package_bundle_format.dart';
 import 'package:pub_semver/pub_semver.dart';
 
 /// An implementation of [DartSdk] which provides analysis results for `dart:`
@@ -16,7 +16,7 @@
 class SummaryBasedDartSdk implements DartSdk {
   SummaryDataStore _dataStore;
   InSummaryUriResolver _uriResolver;
-  PackageBundle _bundle;
+  PackageBundleReader _bundle;
   ResourceProvider resourceProvider;
 
   SummaryBasedDartSdk(String summaryPath, bool _, {this.resourceProvider}) {
@@ -26,26 +26,21 @@
     _bundle = _dataStore.bundles.single;
   }
 
-  SummaryBasedDartSdk.fromBundle(bool _, PackageBundle bundle,
-      {this.resourceProvider}) {
-    _dataStore = SummaryDataStore([], resourceProvider: resourceProvider);
-    _dataStore.addBundle('dart_sdk.sum', bundle);
-    _uriResolver = InSummaryUriResolver(resourceProvider, _dataStore);
-    _bundle = bundle;
-  }
-
   @override
   String get allowedExperimentsJson {
     return _bundle.sdk.allowedExperimentsJson;
   }
 
-  /// Return the [PackageBundle] for this SDK, not `null`.
-  PackageBundle get bundle => _bundle;
+  /// Return the [PackageBundleReader] for this SDK, not `null`.
+  PackageBundleReader get bundle => _bundle;
 
   @override
   Version get languageVersion {
-    var version = _bundle.sdk.languageVersion;
-    return Version(version.major, version.minor, 0);
+    return Version(
+      _bundle.sdk.languageVersionMajor,
+      _bundle.sdk.languageVersionMinor,
+      0,
+    );
   }
 
   @override
diff --git a/pkg/analyzer/lib/src/summary2/apply_resolution.dart b/pkg/analyzer/lib/src/summary2/apply_resolution.dart
new file mode 100644
index 0000000..dfbdab2
--- /dev/null
+++ b/pkg/analyzer/lib/src/summary2/apply_resolution.dart
@@ -0,0 +1,1059 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:analyzer/dart/ast/ast.dart';
+import 'package:analyzer/dart/ast/visitor.dart';
+import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/dart/element/type.dart';
+import 'package:analyzer/src/dart/ast/ast.dart';
+import 'package:analyzer/src/dart/element/element.dart';
+import 'package:analyzer/src/dart/resolver/variance.dart';
+import 'package:analyzer/src/summary2/bundle_reader.dart';
+import 'package:analyzer/src/summary2/linked_unit_context.dart';
+import 'package:analyzer/src/task/inference_error.dart';
+
+class ApplyResolutionVisitor extends ThrowingAstVisitor<void> {
+  final LinkedUnitContext _unitContext;
+  final LinkedResolutionReader _resolution;
+
+  /// The stack of [TypeParameterElement]s and [ParameterElement] that are
+  /// available in the scope of [_nextElement] and [_nextType].
+  ///
+  /// This stack is shared with [_resolution].
+  final List<Element> _localElements;
+
+  final List<ElementImpl> _enclosingElements = [];
+
+  ApplyResolutionVisitor(
+    this._unitContext,
+    this._localElements,
+    this._resolution,
+  ) {
+    _enclosingElements.add(_unitContext.unit.declaredElement as ElementImpl);
+  }
+
+  /// TODO(scheglov) make private
+  void addParentTypeParameters(AstNode node) {
+    var enclosing = node.parent;
+    if (enclosing is ClassOrMixinDeclaration) {
+      var typeParameterList = enclosing.typeParameters;
+      if (typeParameterList == null) return;
+
+      for (var typeParameter in typeParameterList.typeParameters) {
+        var element = typeParameter.declaredElement;
+        _localElements.add(element);
+      }
+    } else if (enclosing is ExtensionDeclaration) {
+      var typeParameterList = enclosing.typeParameters;
+      if (typeParameterList == null) return;
+
+      for (var typeParameter in typeParameterList.typeParameters) {
+        var element = typeParameter.declaredElement;
+        _localElements.add(element);
+      }
+    } else if (enclosing is VariableDeclarationList) {
+      var enclosing2 = enclosing.parent;
+      if (enclosing2 is FieldDeclaration) {
+        return addParentTypeParameters(enclosing2);
+      } else if (enclosing2 is TopLevelVariableDeclaration) {
+        return;
+      } else {
+        throw UnimplementedError('${enclosing2.runtimeType}');
+      }
+    } else {
+      throw UnimplementedError('${enclosing.runtimeType}');
+    }
+  }
+
+  @override
+  void visitAdjacentStrings(AdjacentStrings node) {
+    node.strings.accept(this);
+    // TODO(scheglov) type?
+  }
+
+  @override
+  void visitAnnotation(Annotation node) {
+    node.name.accept(this);
+    node.constructorName?.accept(this);
+    node.arguments?.accept(this);
+    node.element = _nextElement();
+  }
+
+  @override
+  void visitArgumentList(ArgumentList node) {
+    node.arguments.accept(this);
+  }
+
+  @override
+  void visitAsExpression(AsExpression node) {
+    node.expression.accept(this);
+    node.type.accept(this);
+    _expression(node);
+  }
+
+  @override
+  void visitAssertInitializer(AssertInitializer node) {
+    node.condition.accept(this);
+    node.message?.accept(this);
+  }
+
+  @override
+  void visitAssignmentExpression(AssignmentExpression node) {
+    var nodeImpl = node as AssignmentExpressionImpl;
+    node.leftHandSide.accept(this);
+    node.rightHandSide.accept(this);
+    node.staticElement = _nextElement();
+    nodeImpl.readElement = _nextElement();
+    nodeImpl.readType = _nextType();
+    nodeImpl.writeElement = _nextElement();
+    nodeImpl.writeType = _nextType();
+    _expression(node);
+  }
+
+  @override
+  void visitBinaryExpression(BinaryExpression node) {
+    node.leftOperand.accept(this);
+    node.rightOperand.accept(this);
+
+    node.staticElement = _nextElement();
+    node.staticType = _nextType();
+  }
+
+  @override
+  void visitBooleanLiteral(BooleanLiteral node) {
+    node.staticType = _nextType();
+  }
+
+  @override
+  void visitCascadeExpression(CascadeExpression node) {
+    node.target.accept(this);
+    node.cascadeSections.accept(this);
+    node.staticType = node.target.staticType;
+  }
+
+  @override
+  visitClassDeclaration(ClassDeclaration node) {
+    _assertNoLocalElements();
+
+    var element = node.declaredElement as ClassElementImpl;
+    element.isSimplyBounded = _resolution.readByte() != 0;
+    _enclosingElements.add(element);
+
+    node.typeParameters?.accept(this);
+    node.extendsClause?.accept(this);
+    node.nativeClause?.accept(this);
+    node.withClause?.accept(this);
+    node.implementsClause?.accept(this);
+    _namedCompilationUnitMember(node);
+
+    _enclosingElements.removeLast();
+  }
+
+  @override
+  void visitClassTypeAlias(ClassTypeAlias node) {
+    _assertNoLocalElements();
+    var element = node.declaredElement as ClassElementImpl;
+    _enclosingElements.add(element);
+
+    element.isSimplyBounded = _resolution.readByte() != 0;
+    node.typeParameters?.accept(this);
+    node.superclass?.accept(this);
+    node.withClause?.accept(this);
+    node.implementsClause?.accept(this);
+    node.metadata?.accept(this);
+
+    _enclosingElements.removeLast();
+  }
+
+  @override
+  void visitConditionalExpression(ConditionalExpression node) {
+    node.condition.accept(this);
+    node.thenExpression.accept(this);
+    node.elseExpression.accept(this);
+    node.staticType = _nextType();
+  }
+
+  @override
+  void visitConfiguration(Configuration node) {
+    node.name?.accept(this);
+    node.value?.accept(this);
+    node.uri?.accept(this);
+  }
+
+  @override
+  void visitConstructorDeclaration(ConstructorDeclaration node) {
+    _assertNoLocalElements();
+    _pushEnclosingClassTypeParameters(node);
+
+    var element = node.declaredElement as ConstructorElementImpl;
+    _enclosingElements.add(element.enclosingElement);
+    _enclosingElements.add(element);
+
+    node.returnType?.accept(this);
+    node.parameters?.accept(this);
+
+    for (var parameter in node.parameters.parameters) {
+      _localElements.add(parameter.declaredElement);
+    }
+
+    node.initializers?.accept(this);
+    node.redirectedConstructor?.accept(this);
+    node.metadata?.accept(this);
+
+    _enclosingElements.removeLast();
+    _enclosingElements.removeLast();
+  }
+
+  @override
+  void visitConstructorFieldInitializer(ConstructorFieldInitializer node) {
+    node.fieldName.accept(this);
+    node.expression.accept(this);
+  }
+
+  @override
+  void visitConstructorName(ConstructorName node) {
+    node.type.accept(this);
+    node.name?.accept(this);
+    node.staticElement = _nextElement();
+  }
+
+  @override
+  void visitDeclaredIdentifier(DeclaredIdentifier node) {
+    node.type?.accept(this);
+    // node.identifier.accept(this);
+    _declaration(node);
+  }
+
+  @override
+  visitDefaultFormalParameter(DefaultFormalParameter node) {
+    var nodeImpl = node as DefaultFormalParameterImpl;
+
+    var enclosing = _enclosingElements.last;
+    var name = node.identifier?.name ?? '';
+    var reference = node.isNamed && enclosing.reference != null
+        ? enclosing.reference.getChild('@parameter').getChild(name)
+        : null;
+    ParameterElementImpl element;
+    if (node.parameter is FieldFormalParameter) {
+      element = DefaultFieldFormalParameterElementImpl.forLinkedNode(
+          enclosing, reference, node);
+    } else {
+      element =
+          DefaultParameterElementImpl.forLinkedNode(enclosing, reference, node);
+    }
+
+    var summaryData = nodeImpl.summaryData as SummaryDataForFormalParameter;
+    element.setCodeRange(summaryData.codeOffset, summaryData.codeLength);
+
+    node.parameter.accept(this);
+    node.defaultValue?.accept(this);
+  }
+
+  @override
+  void visitDottedName(DottedName node) {
+    node.components.accept(this);
+  }
+
+  @override
+  void visitDoubleLiteral(DoubleLiteral node) {
+    // TODO(scheglov) type?
+  }
+
+  @override
+  void visitEnumConstantDeclaration(EnumConstantDeclaration node) {
+    node.metadata?.accept(this);
+  }
+
+  @override
+  void visitEnumDeclaration(EnumDeclaration node) {
+    node.constants.accept(this);
+    node.metadata?.accept(this);
+  }
+
+  @override
+  void visitExportDirective(ExportDirective node) {
+    _namespaceDirective(node);
+    (node.element as ExportElementImpl).exportedLibrary = _nextElement();
+  }
+
+  @override
+  void visitExpressionFunctionBody(ExpressionFunctionBody node) {
+    node.expression.accept(this);
+  }
+
+  @override
+  visitExtendsClause(ExtendsClause node) {
+    node.superclass.accept(this);
+  }
+
+  @override
+  void visitExtensionDeclaration(ExtensionDeclaration node) {
+    _assertNoLocalElements();
+
+    var element = node.declaredElement as ExtensionElementImpl;
+    _enclosingElements.add(element);
+
+    node.typeParameters?.accept(this);
+    node.extendedType?.accept(this);
+    node.metadata?.accept(this);
+
+    _enclosingElements.removeLast();
+  }
+
+  @override
+  void visitExtensionOverride(ExtensionOverride node) {
+    node.extensionName.accept(this);
+    node.typeArguments?.accept(this);
+    node.argumentList.accept(this);
+    (node as ExtensionOverrideImpl).extendedType = _nextType();
+    // TODO(scheglov) typeArgumentTypes?
+  }
+
+  @override
+  void visitFieldDeclaration(FieldDeclaration node) {
+    _assertNoLocalElements();
+    _pushEnclosingClassTypeParameters(node);
+
+    node.fields.accept(this);
+    node.metadata?.accept(this);
+  }
+
+  @override
+  void visitFieldFormalParameter(FieldFormalParameter node) {
+    ParameterElement element;
+    if (node.parent is! DefaultFormalParameter) {
+      var enclosing = _enclosingElements.last;
+      element =
+          FieldFormalParameterElementImpl.forLinkedNode(enclosing, null, node);
+    }
+
+    var localElementsLength = _localElements.length;
+
+    node.typeParameters?.accept(this);
+    node.type?.accept(this);
+    node.parameters?.accept(this);
+    _normalFormalParameter(node, element);
+
+    _localElements.length = localElementsLength;
+  }
+
+  @override
+  void visitForEachPartsWithDeclaration(ForEachPartsWithDeclaration node) {
+    node.loopVariable.accept(this);
+    _forEachParts(node);
+  }
+
+  @override
+  void visitForElement(ForElement node) {
+    node.body.accept(this);
+    node.forLoopParts.accept(this);
+  }
+
+  @override
+  visitFormalParameterList(FormalParameterList node) {
+    node.parameters.accept(this);
+  }
+
+  @override
+  void visitForPartsWithDeclarations(ForPartsWithDeclarations node) {
+    for (var variable in node.variables.variables) {
+      var nameNode = variable.name;
+      nameNode.staticElement = LocalVariableElementImpl(
+        nameNode.name,
+        nameNode.offset,
+      );
+    }
+    node.variables.accept(this);
+    _forParts(node);
+  }
+
+  @override
+  void visitFunctionDeclaration(FunctionDeclaration node) {
+    _assertNoLocalElements();
+
+    var element = node.declaredElement as ExecutableElementImpl;
+    assert(element != null);
+
+    _enclosingElements.add(element);
+
+    node.functionExpression.accept(this);
+    node.returnType?.accept(this);
+
+    node.metadata?.accept(this);
+    element.returnType = _nextType();
+  }
+
+  @override
+  void visitFunctionExpression(FunctionExpression node) {
+    node.typeParameters?.accept(this);
+    node.parameters?.accept(this);
+  }
+
+  @override
+  void visitFunctionExpressionInvocation(FunctionExpressionInvocation node) {
+    node.function.accept(this);
+    _invocationExpression(node);
+  }
+
+  @override
+  void visitFunctionTypeAlias(FunctionTypeAlias node) {
+    _assertNoLocalElements();
+
+    var element = node.declaredElement as FunctionTypeAliasElementImpl;
+    _enclosingElements.add(element);
+
+    node.typeParameters?.accept(this);
+
+    _enclosingElements.add(element.function);
+    node.returnType?.accept(this);
+    node.parameters?.accept(this);
+    _enclosingElements.removeLast();
+
+    node.metadata?.accept(this);
+
+    element.function.returnType = _nextType();
+    element.isSimplyBounded = _resolution.readByte() != 0;
+    element.hasSelfReference = _resolution.readByte() != 0;
+
+    _enclosingElements.removeLast();
+  }
+
+  @override
+  void visitFunctionTypedFormalParameter(FunctionTypedFormalParameter node) {
+    var element = node.declaredElement;
+    if (node.parent is! DefaultFormalParameter) {
+      var enclosing = _enclosingElements.last;
+      element =
+          ParameterElementImpl.forLinkedNodeFactory(enclosing, null, node);
+    }
+
+    var localElementsLength = _localElements.length;
+
+    node.typeParameters?.accept(this);
+    node.returnType?.accept(this);
+    node.parameters?.accept(this);
+    _normalFormalParameter(node, element);
+
+    _localElements.length = localElementsLength;
+  }
+
+  @override
+  void visitGenericFunctionType(GenericFunctionType node) {
+    var nodeImpl = node as GenericFunctionTypeImpl;
+    var localElementsLength = _localElements.length;
+
+    var element = nodeImpl.declaredElement as GenericFunctionTypeElementImpl;
+    element ??= GenericFunctionTypeElementImpl.forLinkedNode(
+        _enclosingElements.last, null, node);
+    _enclosingElements.add(element);
+
+    node.typeParameters?.accept(this);
+    node.returnType?.accept(this);
+    node.parameters?.accept(this);
+    nodeImpl.type = _nextType();
+
+    _localElements.length = localElementsLength;
+    _enclosingElements.removeLast();
+  }
+
+  @override
+  void visitGenericTypeAlias(GenericTypeAlias node) {
+    _assertNoLocalElements();
+
+    var element = node.declaredElement as FunctionTypeAliasElementImpl;
+    assert(element != null);
+
+    _enclosingElements.add(element);
+
+    node.typeParameters?.accept(this);
+    node.functionType?.accept(this);
+    node.metadata?.accept(this);
+    element.isSimplyBounded = _resolution.readByte() != 0;
+    element.hasSelfReference = _resolution.readByte() != 0;
+
+    _enclosingElements.removeLast();
+  }
+
+  @override
+  void visitHideCombinator(HideCombinator node) {
+    node.hiddenNames.accept(this);
+  }
+
+  @override
+  void visitIfElement(IfElement node) {
+    node.condition.accept(this);
+    node.thenElement.accept(this);
+    node.elseElement?.accept(this);
+  }
+
+  @override
+  visitImplementsClause(ImplementsClause node) {
+    node.interfaces.accept(this);
+  }
+
+  @override
+  void visitImportDirective(ImportDirective node) {
+    _namespaceDirective(node);
+
+    var element = node.element as ImportElementImpl;
+    element.importedLibrary = _nextElement();
+  }
+
+  @override
+  void visitIndexExpression(IndexExpression node) {
+    node.target?.accept(this);
+    node.index.accept(this);
+    node.staticElement = _nextElement();
+    _expression(node);
+  }
+
+  @override
+  void visitInstanceCreationExpression(InstanceCreationExpression node) {
+    node.constructorName.accept(this);
+    (node as InstanceCreationExpressionImpl).typeArguments?.accept(this);
+    node.argumentList.accept(this);
+    node.staticType = _nextType();
+    _resolveNamedExpressions(
+      node.constructorName.staticElement,
+      node.argumentList,
+    );
+  }
+
+  @override
+  void visitIntegerLiteral(IntegerLiteral node) {
+    node.staticType = _nextType();
+  }
+
+  @override
+  void visitInterpolationExpression(InterpolationExpression node) {
+    node.expression.accept(this);
+  }
+
+  @override
+  void visitInterpolationString(InterpolationString node) {
+    // TODO(scheglov) type?
+  }
+
+  @override
+  void visitIsExpression(IsExpression node) {
+    node.expression.accept(this);
+    node.type.accept(this);
+    _expression(node);
+  }
+
+  @override
+  void visitLibraryDirective(LibraryDirective node) {
+    node.name.accept(this);
+    _directive(node);
+  }
+
+  @override
+  void visitLibraryIdentifier(LibraryIdentifier node) {
+    node.components.accept(this);
+  }
+
+  @override
+  void visitListLiteral(ListLiteral node) {
+    node.typeArguments?.accept(this);
+    node.elements.accept(this);
+    node.staticType = _nextType();
+  }
+
+  @override
+  void visitMapLiteralEntry(MapLiteralEntry node) {
+    node.key.accept(this);
+    node.value.accept(this);
+  }
+
+  @override
+  visitMethodDeclaration(MethodDeclaration node) {
+    _assertNoLocalElements();
+    _pushEnclosingClassTypeParameters(node);
+
+    var element = node.declaredElement as ExecutableElementImpl;
+    _enclosingElements.add(element.enclosingElement);
+    _enclosingElements.add(element);
+
+    node.typeParameters?.accept(this);
+    node.returnType?.accept(this);
+    node.parameters?.accept(this);
+    node.metadata?.accept(this);
+
+    element.returnType = _nextType();
+    _setTopLevelInferenceError(element);
+    if (element is MethodElementImpl) {
+      element.isOperatorEqualWithParameterTypeFromObject =
+          _resolution.readByte() != 0;
+    }
+
+    _enclosingElements.removeLast();
+    _enclosingElements.removeLast();
+  }
+
+  @override
+  void visitMethodInvocation(MethodInvocation node) {
+    node.target?.accept(this);
+    node.methodName.accept(this);
+    _invocationExpression(node);
+  }
+
+  @override
+  void visitMixinDeclaration(MixinDeclaration node) {
+    _assertNoLocalElements();
+    var element = node.declaredElement as MixinElementImpl;
+    element.isSimplyBounded = _resolution.readByte() != 0;
+    element.superInvokedNames = _resolution.readStringList();
+    _enclosingElements.add(element);
+
+    node.typeParameters?.accept(this);
+    node.onClause?.accept(this);
+    node.implementsClause?.accept(this);
+    node.metadata?.accept(this);
+
+    _enclosingElements.removeLast();
+  }
+
+  @override
+  void visitNamedExpression(NamedExpression node) {
+    node.expression.accept(this);
+  }
+
+  @override
+  void visitNativeClause(NativeClause node) {
+    node.name.accept(this);
+  }
+
+  @override
+  void visitNullLiteral(NullLiteral node) {
+    // TODO(scheglov) type?
+  }
+
+  @override
+  void visitOnClause(OnClause node) {
+    node.superclassConstraints.accept(this);
+  }
+
+  @override
+  void visitParenthesizedExpression(ParenthesizedExpression node) {
+    node.expression.accept(this);
+    node.staticType = _nextType();
+  }
+
+  @override
+  void visitPartDirective(PartDirective node) {
+    _uriBasedDirective(node);
+  }
+
+  @override
+  void visitPartOfDirective(PartOfDirective node) {
+    node.uri?.accept(this);
+    _directive(node);
+  }
+
+  @override
+  void visitPostfixExpression(PostfixExpression node) {
+    var nodeImpl = node as PostfixExpressionImpl;
+    node.operand.accept(this);
+    node.staticElement = _nextElement();
+    if (node.operator.type.isIncrementOperator) {
+      nodeImpl.readElement = _nextElement();
+      nodeImpl.readType = _nextType();
+      nodeImpl.writeElement = _nextElement();
+      nodeImpl.writeType = _nextType();
+    }
+    _expression(node);
+  }
+
+  @override
+  void visitPrefixedIdentifier(PrefixedIdentifier node) {
+    node.prefix.accept(this);
+    node.identifier.accept(this);
+    _expression(node);
+  }
+
+  @override
+  void visitPrefixExpression(PrefixExpression node) {
+    var nodeImpl = node as PrefixExpressionImpl;
+    node.operand.accept(this);
+    node.staticElement = _nextElement();
+    if (node.operator.type.isIncrementOperator) {
+      nodeImpl.readElement = _nextElement();
+      nodeImpl.readType = _nextType();
+      nodeImpl.writeElement = _nextElement();
+      nodeImpl.writeType = _nextType();
+    }
+    _expression(node);
+  }
+
+  @override
+  void visitPropertyAccess(PropertyAccess node) {
+    node.target?.accept(this);
+    node.propertyName.accept(this);
+
+    node.staticType = _nextType();
+  }
+
+  @override
+  void visitRedirectingConstructorInvocation(
+      RedirectingConstructorInvocation node) {
+    node.constructorName?.accept(this);
+    node.argumentList.accept(this);
+    node.staticElement = _nextElement();
+    _resolveNamedExpressions(node.staticElement, node.argumentList);
+  }
+
+  @override
+  void visitSetOrMapLiteral(SetOrMapLiteral node) {
+    node.typeArguments?.accept(this);
+    node.elements.accept(this);
+    node.staticType = _nextType();
+  }
+
+  @override
+  void visitShowCombinator(ShowCombinator node) {
+    node.shownNames.accept(this);
+  }
+
+  @override
+  visitSimpleFormalParameter(SimpleFormalParameter node) {
+    var element = node.declaredElement as ParameterElementImpl;
+    if (node.parent is! DefaultFormalParameter) {
+      var enclosing = _enclosingElements.last;
+      element =
+          ParameterElementImpl.forLinkedNodeFactory(enclosing, null, node);
+    }
+
+    node.type?.accept(this);
+    _normalFormalParameter(node, element);
+
+    element.inheritsCovariant = _resolution.readByte() != 0;
+  }
+
+  @override
+  visitSimpleIdentifier(SimpleIdentifier node) {
+    node.staticElement = _nextElement();
+    node.staticType = _nextType();
+  }
+
+  @override
+  void visitSimpleStringLiteral(SimpleStringLiteral node) {
+    // TODO(scheglov) type?
+  }
+
+  @override
+  void visitSpreadElement(SpreadElement node) {
+    node.expression.accept(this);
+  }
+
+  @override
+  void visitStringInterpolation(StringInterpolation node) {
+    node.elements.accept(this);
+    // TODO(scheglov) type?
+  }
+
+  @override
+  void visitSuperConstructorInvocation(SuperConstructorInvocation node) {
+    node.constructorName?.accept(this);
+    node.argumentList.accept(this);
+    node.staticElement = _nextElement();
+    _resolveNamedExpressions(node.staticElement, node.argumentList);
+  }
+
+  @override
+  void visitSuperExpression(SuperExpression node) {
+    node.staticType = _nextType();
+  }
+
+  @override
+  void visitSymbolLiteral(SymbolLiteral node) {
+    node.staticType = _nextType();
+  }
+
+  @override
+  void visitThisExpression(ThisExpression node) {
+    node.staticType = _nextType();
+  }
+
+  @override
+  void visitThrowExpression(ThrowExpression node) {
+    node.expression.accept(this);
+    node.staticType = _nextType();
+  }
+
+  @override
+  void visitTopLevelVariableDeclaration(TopLevelVariableDeclaration node) {
+    node.variables.accept(this);
+    node.metadata?.accept(this);
+  }
+
+  @override
+  visitTypeArgumentList(TypeArgumentList node) {
+    node.arguments?.accept(this);
+  }
+
+  @override
+  visitTypeName(TypeName node) {
+    node.name.accept(this);
+    node.typeArguments?.accept(this);
+
+    node.type = _nextType();
+  }
+
+  @override
+  visitTypeParameterList(TypeParameterList node) {
+    for (var typeParameter in node.typeParameters) {
+      var element = TypeParameterElementImpl.forLinkedNode(
+        _enclosingElements.last,
+        typeParameter,
+      );
+      _localElements.add(element);
+    }
+
+    for (var node in node.typeParameters) {
+      var nodeImpl = node as TypeParameterImpl;
+      var element = node.declaredElement as TypeParameterElementImpl;
+
+      var summaryData = nodeImpl.summaryData as SummaryDataForTypeParameter;
+      element.setCodeRange(summaryData.codeOffset, summaryData.codeLength);
+
+      node.bound?.accept(this);
+      element.bound = node.bound?.type;
+
+      node.metadata.accept(this);
+      element.metadata = _buildAnnotations2(
+        _unitContext.reference.element,
+        node.metadata,
+      );
+
+      element.variance = _decodeVariance(_resolution.readByte());
+      element.defaultType = _nextType();
+
+      // TODO(scheglov) We used to do this with the previous elements impl.
+      // We probably still do this.
+      // But the code below is bad and incomplete.
+      // And why does this affect MethodMember(s)?
+      {
+        var parent = node.parent;
+        if (parent is ClassDeclaration) {
+          (parent.declaredElement as ElementImpl).encloseElement(element);
+        } else if (parent is ClassTypeAlias) {
+          (parent.declaredElement as ElementImpl).encloseElement(element);
+        } else if (parent is ExtensionDeclaration) {
+          (parent.declaredElement as ElementImpl).encloseElement(element);
+        } else if (parent is FunctionExpression) {
+          var parent2 = parent.parent;
+          if (parent2 is FunctionDeclaration) {
+            (parent2.declaredElement as ElementImpl).encloseElement(element);
+          }
+        } else if (parent is FunctionTypeAlias) {
+          (parent.declaredElement as ElementImpl).encloseElement(element);
+        } else if (parent is GenericTypeAlias) {
+          (parent.declaredElement as ElementImpl).encloseElement(element);
+        } else if (parent is MethodDeclaration) {
+          (parent.declaredElement as ElementImpl).encloseElement(element);
+        } else if (parent is MixinDeclaration) {
+          (parent.declaredElement as ElementImpl).encloseElement(element);
+        }
+      }
+    }
+  }
+
+  @override
+  void visitVariableDeclaration(VariableDeclaration node) {
+    var element = node.declaredElement as VariableElementImpl;
+    element.type = _nextType();
+    _setTopLevelInferenceError(element);
+    if (element is FieldElementImpl) {
+      element.inheritsCovariant = _resolution.readByte() != 0;
+    }
+
+    node.initializer?.accept(this);
+  }
+
+  @override
+  void visitVariableDeclarationList(VariableDeclarationList node) {
+    node.type?.accept(this);
+    node.variables.accept(this);
+    node.metadata?.accept(this);
+  }
+
+  @override
+  void visitWithClause(WithClause node) {
+    node.mixinTypes.accept(this);
+  }
+
+  void _annotatedNode(AnnotatedNode node) {
+    node.metadata?.accept(this);
+  }
+
+  void _assertNoLocalElements() {
+    assert(_localElements.isEmpty);
+    assert(_enclosingElements.length == 1 &&
+        _enclosingElements.first is CompilationUnitElement);
+  }
+
+  /// Return annotations for the given [nodeList] in the [unit].
+  List<ElementAnnotation> _buildAnnotations2(
+      CompilationUnitElementImpl unit, List<Annotation> nodeList) {
+    var length = nodeList.length;
+    if (length == 0) {
+      return const <ElementAnnotation>[];
+    }
+
+    var annotations = List<ElementAnnotation>(length);
+    for (int i = 0; i < length; i++) {
+      var ast = nodeList[i];
+      annotations[i] = ElementAnnotationImpl(unit)
+        ..annotationAst = ast
+        ..element = ast.element;
+    }
+    return annotations;
+  }
+
+  void _compilationUnitMember(CompilationUnitMember node) {
+    _declaration(node);
+  }
+
+  void _declaration(Declaration node) {
+    _annotatedNode(node);
+  }
+
+  void _directive(Directive node) {
+    node.metadata?.accept(this);
+  }
+
+  void _expression(Expression node) {
+    node.staticType = _nextType();
+  }
+
+  void _forEachParts(ForEachParts node) {
+    _forLoopParts(node);
+    node.iterable.accept(this);
+  }
+
+  void _forLoopParts(ForLoopParts node) {}
+
+  void _formalParameter(FormalParameter node) {
+    (node.declaredElement as ParameterElementImpl).type = _nextType();
+  }
+
+  void _forParts(ForParts node) {
+    node.condition?.accept(this);
+    node.updaters.accept(this);
+    _forLoopParts(node);
+  }
+
+  void _invocationExpression(InvocationExpression node) {
+    node.typeArguments?.accept(this);
+    node.argumentList.accept(this);
+    _expression(node);
+    // TODO(scheglov) typeArgumentTypes and staticInvokeType?
+    var nodeImpl = node as InvocationExpressionImpl;
+    nodeImpl.typeArgumentTypes = [];
+  }
+
+  void _namedCompilationUnitMember(NamedCompilationUnitMember node) {
+    _compilationUnitMember(node);
+  }
+
+  void _namespaceDirective(NamespaceDirective node) {
+    node.combinators?.accept(this);
+    node.configurations?.accept(this);
+    _uriBasedDirective(node);
+  }
+
+  Element _nextElement() {
+    return _resolution.nextElement();
+  }
+
+  DartType _nextType() {
+    return _resolution.nextType();
+  }
+
+  void _normalFormalParameter(
+    NormalFormalParameter node,
+    ParameterElementImpl element,
+  ) {
+    if (node.parent is! DefaultFormalParameter) {
+      var nodeImpl = node as NormalFormalParameterImpl;
+      var summaryData = nodeImpl.summaryData as SummaryDataForFormalParameter;
+      element.setCodeRange(summaryData.codeOffset, summaryData.codeLength);
+    }
+
+    node.metadata?.accept(this);
+    _formalParameter(node);
+  }
+
+  /// TODO(scheglov) also enclosing elements
+  void _pushEnclosingClassTypeParameters(ClassMember node) {
+    var parent = node.parent;
+    if (parent is ClassOrMixinDeclaration) {
+      var classElement = parent.declaredElement;
+      _localElements.addAll(classElement.typeParameters);
+    } else {
+      var extension = parent as ExtensionDeclaration;
+      var classElement = extension.declaredElement;
+      _localElements.addAll(classElement.typeParameters);
+    }
+  }
+
+  TopLevelInferenceError _readTopLevelInferenceError() {
+    var kindIndex = _resolution.readByte();
+    var kind = TopLevelInferenceErrorKind.values[kindIndex];
+    if (kind == TopLevelInferenceErrorKind.none) {
+      return null;
+    }
+    return TopLevelInferenceError(
+      kind: kind,
+      arguments: _resolution.readStringList(),
+    );
+  }
+
+  void _resolveNamedExpressions(
+    Element executable,
+    ArgumentList argumentList,
+  ) {
+    for (var argument in argumentList.arguments) {
+      if (argument is NamedExpression) {
+        var nameNode = argument.name.label;
+        if (executable is ExecutableElement) {
+          var parameters = executable.parameters;
+          var name = nameNode.name;
+          nameNode.staticElement = parameters.firstWhere((e) {
+            return e.name == name;
+          }, orElse: () => null);
+        }
+      }
+    }
+  }
+
+  void _setTopLevelInferenceError(ElementImpl element) {
+    if (element is MethodElementImpl) {
+      element.typeInferenceError = _readTopLevelInferenceError();
+    } else if (element is PropertyInducingElementImpl) {
+      element.typeInferenceError = _readTopLevelInferenceError();
+    }
+  }
+
+  void _uriBasedDirective(UriBasedDirective node) {
+    _directive(node);
+    node.uri.accept(this);
+  }
+
+  static Variance _decodeVariance(int encoding) {
+    if (encoding == 0) {
+      return null;
+    } else if (encoding == 1) {
+      return Variance.unrelated;
+    } else if (encoding == 2) {
+      return Variance.covariant;
+    } else if (encoding == 3) {
+      return Variance.contravariant;
+    } else if (encoding == 4) {
+      return Variance.invariant;
+    } else {
+      throw UnimplementedError('encoding: $encoding');
+    }
+  }
+}
diff --git a/pkg/analyzer/lib/src/summary2/ast_binary_flags.dart b/pkg/analyzer/lib/src/summary2/ast_binary_flags.dart
index beac780..e911fea 100644
--- a/pkg/analyzer/lib/src/summary2/ast_binary_flags.dart
+++ b/pkg/analyzer/lib/src/summary2/ast_binary_flags.dart
@@ -13,13 +13,18 @@
     ForStatement,
   );
 
+  static final _hasConstConstructor = _checkBit(
+    0,
+    ClassDeclaration,
+  );
+
   static final _hasEqual = _checkBit(
     0,
     Configuration,
   );
 
   static final _hasInitializer = _checkBit(
-    0,
+    2,
     DefaultFormalParameter,
     VariableDeclaration,
   );
@@ -27,6 +32,9 @@
   static final _hasName = _checkBit(
     5,
     ConstructorDeclaration,
+    FieldFormalParameter,
+    FunctionTypedFormalParameter,
+    SimpleFormalParameter,
   );
 
   static final _hasNot = _checkBit(
@@ -34,6 +42,11 @@
     IsExpression,
   );
 
+  static final _hasPrefix = _checkBit(
+    1,
+    ImportDirective,
+  );
+
   static final _hasPeriod = _checkBit(
     0,
     IndexExpression,
@@ -183,8 +196,14 @@
     MethodDeclaration,
   );
 
+  static final _isPositional = _checkBit(
+    1,
+    DefaultFormalParameter,
+  );
+
   static final _isRequired = _checkBit(
     0,
+    DefaultFormalParameter,
     NormalFormalParameter,
   );
 
@@ -227,12 +246,14 @@
 
   static int encode({
     bool hasAwait = false,
+    bool hasConstConstructor = false,
     bool hasEqual = false,
     bool hasInitializer = false,
     bool hasName = false,
     bool hasNot = false,
     bool hasPeriod = false,
     bool hasPeriod2 = false,
+    bool hasPrefix = false,
     bool hasQuestion = false,
     bool hasSeparatorColon = false,
     bool hasSeparatorEquals = false,
@@ -256,6 +277,7 @@
     bool isNative = false,
     bool isNew = false,
     bool isOperator = false,
+    bool isPositional = false,
     bool isRequired = false,
     bool isSet = false,
     bool isStar = false,
@@ -268,6 +290,9 @@
     if (hasAwait) {
       result |= _hasAwait;
     }
+    if (hasConstConstructor) {
+      result |= _hasConstConstructor;
+    }
     if (hasEqual) {
       result |= _hasEqual;
     }
@@ -286,6 +311,9 @@
     if (hasPeriod2) {
       result |= _hasPeriod2;
     }
+    if (hasPrefix) {
+      result |= _hasPrefix;
+    }
     if (hasQuestion) {
       result |= _hasQuestion;
     }
@@ -355,6 +383,9 @@
     if (isOperator) {
       result |= _isOperator;
     }
+    if (isPositional) {
+      result |= _isPositional;
+    }
     if (isRequired) {
       result |= _isRequired;
     }
@@ -383,6 +414,10 @@
     return (flags & _hasAwait) != 0;
   }
 
+  static bool hasConstConstructor(int flags) {
+    return (flags & _hasConstConstructor) != 0;
+  }
+
   static bool hasEqual(int flags) {
     return (flags & _hasEqual) != 0;
   }
@@ -407,6 +442,10 @@
     return (flags & _hasPeriod2) != 0;
   }
 
+  static bool hasPrefix(int flags) {
+    return (flags & _hasPrefix) != 0;
+  }
+
   static bool hasQuestion(int flags) {
     return (flags & _hasQuestion) != 0;
   }
@@ -499,6 +538,10 @@
     return (flags & _isOperator) != 0;
   }
 
+  static bool isPositional(int flags) {
+    return (flags & _isPositional) != 0;
+  }
+
   static bool isRequired(int flags) {
     return (flags & _isRequired) != 0;
   }
diff --git a/pkg/analyzer/lib/src/summary2/ast_binary_reader.dart b/pkg/analyzer/lib/src/summary2/ast_binary_reader.dart
index 4df499f..c84049b 100644
--- a/pkg/analyzer/lib/src/summary2/ast_binary_reader.dart
+++ b/pkg/analyzer/lib/src/summary2/ast_binary_reader.dart
@@ -2,2099 +2,1799 @@
 // 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:typed_data';
+
 import 'package:analyzer/dart/ast/ast.dart';
 import 'package:analyzer/dart/ast/standard_ast_factory.dart';
 import 'package:analyzer/dart/ast/token.dart';
-import 'package:analyzer/dart/element/element.dart';
-import 'package:analyzer/dart/element/type.dart';
-import 'package:analyzer/src/dart/analysis/experiments.dart';
 import 'package:analyzer/src/dart/ast/ast.dart';
-import 'package:analyzer/src/dart/ast/ast_factory.dart';
-import 'package:analyzer/src/dart/element/member.dart';
-import 'package:analyzer/src/dart/element/type_algebra.dart';
-import 'package:analyzer/src/dart/resolver/variance.dart';
+import 'package:analyzer/src/dart/ast/token.dart';
 import 'package:analyzer/src/generated/testing/ast_test_factory.dart';
 import 'package:analyzer/src/generated/testing/token_factory.dart';
 import 'package:analyzer/src/generated/utilities_dart.dart';
-import 'package:analyzer/src/summary/idl.dart';
 import 'package:analyzer/src/summary2/ast_binary_flags.dart';
-import 'package:analyzer/src/summary2/lazy_ast.dart';
-import 'package:analyzer/src/summary2/linked_unit_context.dart';
-import 'package:analyzer/src/summary2/tokens_context.dart';
+import 'package:analyzer/src/summary2/ast_binary_tag.dart';
+import 'package:analyzer/src/summary2/ast_binary_tokens.dart';
+import 'package:analyzer/src/summary2/bundle_reader.dart';
+import 'package:analyzer/src/summary2/unlinked_token_type.dart';
+import 'package:meta/meta.dart';
 
-var timerAstBinaryReader = Stopwatch();
-var timerAstBinaryReaderClass = Stopwatch();
-var timerAstBinaryReaderDirective = Stopwatch();
-var timerAstBinaryReaderFunctionBody = Stopwatch();
-var timerAstBinaryReaderFunctionDeclaration = Stopwatch();
-var timerAstBinaryReaderMixin = Stopwatch();
-var timerAstBinaryReaderTopLevelVar = Stopwatch();
-
-/// Deserializer of fully resolved ASTs from flat buffers.
+/// Deserializer of ASTs.
 class AstBinaryReader {
-  final LinkedUnitContext _unitContext;
+  static final _noDocumentationComment = Uint32List(0);
 
-  /// Set to `true` when this reader is used to lazily read its unit.
-  bool isLazy = false;
+  final UnitReader _unitReader;
+  final bool _withInformative;
 
-  /// Whether we are reading a directive.
-  ///
-  /// [StringLiteral]s in directives are not actual expressions, and don't need
-  /// a type. Moreover, when we are reading `dart:core` imports, the type
-  /// provider is not ready yet, so we cannot access type `String`.
-  bool _isReadingDirective = false;
+  AstBinaryReader({
+    @required UnitReader reader,
+  })  : _unitReader = reader,
+        _withInformative = reader.withInformative;
 
-  AstBinaryReader(this._unitContext);
-
-  InterfaceType get _boolType => _unitContext.typeProvider.boolType;
-
-  InterfaceType get _doubleType => _unitContext.typeProvider.doubleType;
-
-  InterfaceType get _intType => _unitContext.typeProvider.intType;
-
-  DartType get _nullType => _unitContext.typeProvider.nullType;
-
-  InterfaceType get _stringType => _unitContext.typeProvider.stringType;
-
-  AstNode readNode(LinkedNode data) {
-    timerAstBinaryReader.start();
-    try {
-      return _readNode(data);
-    } finally {
-      timerAstBinaryReader.stop();
-    }
-  }
-
-  DartType readType(LinkedNodeType data) {
-    return _readType(data);
-  }
-
-  Token _combinatorKeyword(LinkedNode data, Keyword keyword, Token def) {
-    var informativeData = _unitContext.getInformativeData(data);
-    if (informativeData != null) {
-      return TokenFactory.tokenFromKeyword(keyword)
-        ..offset = informativeData.combinatorKeywordOffset;
-    }
-    return def;
-  }
-
-  SimpleIdentifier _declaredIdentifier(LinkedNode data) {
-    var informativeData = _unitContext.getInformativeData(data);
-    var offset = informativeData?.nameOffset ?? 0;
-    return astFactory.simpleIdentifier(
-      TokenFactory.tokenFromString(data.name)..offset = offset,
-      isDeclaration: true,
-    );
-  }
-
-  Token _directiveKeyword(LinkedNode data, Keyword keyword, Token def) {
-    var informativeData = _unitContext.getInformativeData(data);
-    if (informativeData != null) {
-      return TokenFactory.tokenFromKeyword(keyword)
-        ..offset = informativeData.directiveKeywordOffset;
-    }
-    return def;
-  }
-
-  Element _elementOfComponents(
-    int rawElementIndex,
-    LinkedNodeTypeSubstitution substitutionNode,
-  ) {
-    var element = _getElement(rawElementIndex);
-    if (substitutionNode == null) return element;
-
-    var typeParameters = substitutionNode.typeParameters
-        .map<TypeParameterElement>(_getElement)
-        .toList();
-    var typeArguments = substitutionNode.typeArguments.map(_readType).toList();
-    var substitution = Substitution.fromPairs(typeParameters, typeArguments);
-
-    var member = ExecutableMember.from2(element, substitution);
-    if (substitutionNode.isLegacy) {
-      member = Member.legacy(member);
-    }
-
-    return member;
-  }
-
-  T _getElement<T extends Element>(int index) {
-    var bundleContext = _unitContext.bundleContext;
-    return bundleContext.elementOfIndex(index);
-  }
-
-  AdjacentStrings _read_adjacentStrings(LinkedNode data) {
-    var node = astFactory.adjacentStrings(
-      _readNodeList(data.adjacentStrings_strings),
-    );
-    if (!_isReadingDirective) {
-      node.staticType = _stringType;
-    }
-    return node;
-  }
-
-  Annotation _read_annotation(LinkedNode data) {
-    return astFactory.annotation(
-      _Tokens.AT,
-      _readNode(data.annotation_name),
-      _Tokens.PERIOD,
-      _readNode(data.annotation_constructorName),
-      _readNode(data.annotation_arguments),
-    )..element = _elementOfComponents(
-        data.annotation_element,
-        data.annotation_substitution,
-      );
-  }
-
-  ArgumentList _read_argumentList(LinkedNode data) {
-    return astFactory.argumentList(
-      _Tokens.OPEN_PAREN,
-      _readNodeList(data.argumentList_arguments),
-      _Tokens.CLOSE_PAREN,
-    );
-  }
-
-  AsExpression _read_asExpression(LinkedNode data) {
-    return astFactory.asExpression(
-      _readNode(data.asExpression_expression),
-      _Tokens.AS,
-      _readNode(data.asExpression_type),
-    )..staticType = _readType(data.expression_type);
-  }
-
-  AssertInitializer _read_assertInitializer(LinkedNode data) {
-    return astFactory.assertInitializer(
-      _Tokens.ASSERT,
-      _Tokens.OPEN_PAREN,
-      _readNode(data.assertInitializer_condition),
-      _Tokens.COMMA,
-      _readNode(data.assertInitializer_message),
-      _Tokens.CLOSE_PAREN,
-    );
-  }
-
-  AssertStatement _read_assertStatement(LinkedNode data) {
-    return astFactory.assertStatement(
-      _Tokens.AS,
-      _Tokens.OPEN_PAREN,
-      _readNode(data.assertStatement_condition),
-      _Tokens.COMMA,
-      _readNode(data.assertStatement_message),
-      _Tokens.CLOSE_PAREN,
-      _Tokens.SEMICOLON,
-    );
-  }
-
-  AssignmentExpression _read_assignmentExpression(LinkedNode data) {
-    return astFactory.assignmentExpression(
-      _readNode(data.assignmentExpression_leftHandSide),
-      _Tokens.fromType(data.assignmentExpression_operator),
-      _readNode(data.assignmentExpression_rightHandSide),
-    )
-      ..staticElement = _elementOfComponents(
-        data.assignmentExpression_element,
-        data.assignmentExpression_substitution,
-      )
-      ..staticType = _readType(data.expression_type);
-  }
-
-  AwaitExpression _read_awaitExpression(LinkedNode data) {
-    return astFactory.awaitExpression(
-      _Tokens.AWAIT,
-      _readNode(data.awaitExpression_expression),
-    )..staticType = _readType(data.expression_type);
-  }
-
-  BinaryExpression _read_binaryExpression(LinkedNode data) {
-    return astFactory.binaryExpression(
-      _readNode(data.binaryExpression_leftOperand),
-      _Tokens.fromType(data.binaryExpression_operator),
-      _readNode(data.binaryExpression_rightOperand),
-    )
-      ..staticElement = _elementOfComponents(
-        data.binaryExpression_element,
-        data.binaryExpression_substitution,
-      )
-      ..staticType = _readType(data.expression_type);
-  }
-
-  Block _read_block(LinkedNode data) {
-    return astFactory.block(
-      _Tokens.OPEN_CURLY_BRACKET,
-      _readNodeList(data.block_statements),
-      _Tokens.CLOSE_CURLY_BRACKET,
-    );
-  }
-
-  BlockFunctionBody _read_blockFunctionBody(LinkedNode data) {
-    timerAstBinaryReaderFunctionBody.start();
-    try {
-      return astFactory.blockFunctionBody(
-        _Tokens.choose(
-          AstBinaryFlags.isAsync(data.flags),
-          _Tokens.ASYNC,
-          AstBinaryFlags.isSync(data.flags),
-          _Tokens.SYNC,
-        ),
-        AstBinaryFlags.isStar(data.flags) ? _Tokens.STAR : null,
-        _readNode(data.blockFunctionBody_block),
-      );
-    } finally {
-      timerAstBinaryReaderFunctionBody.stop();
-    }
-  }
-
-  BooleanLiteral _read_booleanLiteral(LinkedNode data) {
-    return AstTestFactory.booleanLiteral(data.booleanLiteral_value)
-      ..staticType = _boolType;
-  }
-
-  BreakStatement _read_breakStatement(LinkedNode data) {
-    return astFactory.breakStatement(
-      _Tokens.BREAK,
-      _readNode(data.breakStatement_label),
-      _Tokens.SEMICOLON,
-    );
-  }
-
-  CascadeExpression _read_cascadeExpression(LinkedNode data) {
-    return astFactory.cascadeExpression(
-      _readNode(data.cascadeExpression_target),
-      _readNodeList(data.cascadeExpression_sections),
-    )..staticType = _readType(data.expression_type);
-  }
-
-  CatchClause _read_catchClause(LinkedNode data) {
-    var exceptionType = _readNode(data.catchClause_exceptionType);
-    var exceptionParameter = _readNode(data.catchClause_exceptionParameter);
-    var stackTraceParameter = _readNode(data.catchClause_stackTraceParameter);
-    return astFactory.catchClause(
-      exceptionType != null ? _Tokens.ON : null,
-      exceptionType,
-      exceptionParameter != null ? _Tokens.CATCH : null,
-      exceptionParameter != null ? _Tokens.OPEN_PAREN : null,
-      exceptionParameter,
-      stackTraceParameter != null ? _Tokens.COMMA : null,
-      stackTraceParameter,
-      exceptionParameter != null ? _Tokens.CLOSE_PAREN : null,
-      _readNode(data.catchClause_body),
-    );
-  }
-
-  ClassDeclaration _read_classDeclaration(LinkedNode data) {
-    timerAstBinaryReaderClass.start();
-    try {
-      var node = astFactory.classDeclaration(
-        _readDocumentationComment(data),
-        _readNodeListLazy(data.annotatedNode_metadata),
-        AstBinaryFlags.isAbstract(data.flags) ? _Tokens.ABSTRACT : null,
-        _Tokens.CLASS,
-        _declaredIdentifier(data),
-        _readNode(data.classOrMixinDeclaration_typeParameters),
-        _readNodeLazy(data.classDeclaration_extendsClause),
-        _readNodeLazy(data.classDeclaration_withClause),
-        _readNodeLazy(data.classOrMixinDeclaration_implementsClause),
-        _Tokens.OPEN_CURLY_BRACKET,
-        _readNodeListLazy(data.classOrMixinDeclaration_members),
-        _Tokens.CLOSE_CURLY_BRACKET,
-      );
-      node.nativeClause = _readNodeLazy(data.classDeclaration_nativeClause);
-      LazyClassDeclaration.setData(node, data);
-      return node;
-    } finally {
-      timerAstBinaryReaderClass.stop();
-    }
-  }
-
-  ClassTypeAlias _read_classTypeAlias(LinkedNode data) {
-    timerAstBinaryReaderClass.start();
-    try {
-      var node = astFactory.classTypeAlias(
-        _readDocumentationComment(data),
-        _readNodeListLazy(data.annotatedNode_metadata),
-        _Tokens.CLASS,
-        _declaredIdentifier(data),
-        _readNode(data.classTypeAlias_typeParameters),
-        _Tokens.EQ,
-        AstBinaryFlags.isAbstract(data.flags) ? _Tokens.ABSTRACT : null,
-        _readNodeLazy(data.classTypeAlias_superclass),
-        _readNodeLazy(data.classTypeAlias_withClause),
-        _readNodeLazy(data.classTypeAlias_implementsClause),
-        _Tokens.SEMICOLON,
-      );
-      LazyClassTypeAlias.setData(node, data);
-      return node;
-    } finally {
-      timerAstBinaryReaderClass.stop();
-    }
-  }
-
-  Comment _read_comment(LinkedNode data) {
-    var tokens = data.comment_tokens
-        .map((lexeme) => TokenFactory.tokenFromString(lexeme))
-        .toList();
-    switch (data.comment_type) {
-      case LinkedNodeCommentType.block:
-        return astFactory.endOfLineComment(
-          tokens,
-        );
-      case LinkedNodeCommentType.documentation:
-        return astFactory.documentationComment(
-          tokens,
-          _readNodeList(data.comment_references),
-        );
-      case LinkedNodeCommentType.endOfLine:
-        return astFactory.endOfLineComment(
-          tokens,
-        );
+  AstNode readNode() {
+    var tag = _readByte();
+    switch (tag) {
+      case Tag.AdjacentStrings:
+        return _readAdjacentStrings();
+      case Tag.Annotation:
+        return _readAnnotation();
+      case Tag.ArgumentList:
+        return _readArgumentList();
+      case Tag.AsExpression:
+        return _readAsExpression();
+      case Tag.AssertInitializer:
+        return _readAssertInitializer();
+      case Tag.AssignmentExpression:
+        return _readAssignmentExpression();
+      case Tag.BinaryExpression:
+        return _readBinaryExpression();
+      case Tag.BooleanLiteral:
+        return _readBooleanLiteral();
+      case Tag.CascadeExpression:
+        return _readCascadeExpression();
+      case Tag.Class:
+        return _readClassDeclaration();
+      case Tag.ClassTypeAlias:
+        return _readClassTypeAlias();
+      case Tag.ConditionalExpression:
+        return _readConditionalExpression();
+      case Tag.Configuration:
+        return _readConfiguration();
+      case Tag.ConstructorDeclaration:
+        return _readConstructorDeclaration();
+      case Tag.ConstructorFieldInitializer:
+        return _readConstructorFieldInitializer();
+      case Tag.ConstructorName:
+        return _readConstructorName();
+      case Tag.DeclaredIdentifier:
+        return _readDeclaredIdentifier();
+      case Tag.DefaultFormalParameter:
+        return _readDefaultFormalParameter();
+      case Tag.DottedName:
+        return _readDottedName();
+      case Tag.DoubleLiteral:
+        return _readDoubleLiteral();
+      case Tag.EnumConstantDeclaration:
+        return _readEnumConstantDeclaration();
+      case Tag.EnumDeclaration:
+        return _readEnumDeclaration();
+      case Tag.ExportDirective:
+        return _readExportDirective();
+      case Tag.ExtendsClause:
+        return _readExtendsClause();
+      case Tag.ExtensionDeclaration:
+        return _readExtensionDeclaration();
+      case Tag.ExtensionOverride:
+        return _readExtensionOverride();
+      case Tag.FieldDeclaration:
+        return _readFieldDeclaration();
+      case Tag.ForEachPartsWithDeclaration:
+        return _readForEachPartsWithDeclaration();
+      case Tag.ForElement:
+        return _readForElement();
+      case Tag.ForPartsWithDeclarations:
+        return _readForPartsWithDeclarations();
+      case Tag.FieldFormalParameter:
+        return _readFieldFormalParameter();
+      case Tag.FormalParameterList:
+        return _readFormalParameterList();
+      case Tag.FunctionDeclaration:
+        return _readFunctionDeclaration();
+      case Tag.FunctionExpression:
+        return _readFunctionExpression();
+      case Tag.FunctionExpressionInvocation:
+        return _readFunctionExpressionInvocation();
+      case Tag.FunctionTypeAlias:
+        return _readFunctionTypeAlias();
+      case Tag.FunctionTypedFormalParameter:
+        return _readFunctionTypedFormalParameter();
+      case Tag.GenericFunctionType:
+        return _readGenericFunctionType();
+      case Tag.GenericTypeAlias:
+        return _readGenericTypeAlias();
+      case Tag.HideCombinator:
+        return _readHideCombinator();
+      case Tag.IfElement:
+        return _readIfElement();
+      case Tag.ImplementsClause:
+        return _readImplementsClause();
+      case Tag.IndexExpression:
+        return _readIndexExpression();
+      case Tag.IntegerLiteralNegative1:
+        return _readIntegerLiteralNegative1();
+      case Tag.IntegerLiteralNull:
+        return _readIntegerLiteralNull();
+      case Tag.IntegerLiteralPositive1:
+        return _readIntegerLiteralPositive1();
+      case Tag.IntegerLiteralPositive:
+        return _readIntegerLiteralPositive();
+      case Tag.IntegerLiteralNegative:
+        return _readIntegerLiteralNegative();
+      case Tag.InterpolationExpression:
+        return _readInterpolationExpression();
+      case Tag.InterpolationString:
+        return _readInterpolationString();
+      case Tag.IsExpression:
+        return _readIsExpression();
+      case Tag.LibraryDirective:
+        return _readLibraryDirective();
+      case Tag.LibraryIdentifier:
+        return _readLibraryIdentifier();
+      case Tag.ListLiteral:
+        return _readListLiteral();
+      case Tag.MapLiteralEntry:
+        return _readMapLiteralEntry();
+      case Tag.MethodDeclaration:
+        return _readMethodDeclaration();
+      case Tag.MixinDeclaration:
+        return _readMixinDeclaration();
+      case Tag.MethodInvocation:
+        return _readMethodInvocation();
+      case Tag.NamedExpression:
+        return _readNamedExpression();
+      case Tag.NativeClause:
+        return _readNativeClause();
+      case Tag.NullLiteral:
+        return _readNullLiteral();
+      case Tag.OnClause:
+        return _readOnClause();
+      case Tag.ImportDirective:
+        return _readImportDirective();
+      case Tag.InstanceCreationExpression:
+        return _readInstanceCreationExpression();
+      case Tag.ParenthesizedExpression:
+        return _readParenthesizedExpression();
+      case Tag.PartDirective:
+        return _readPartDirective();
+      case Tag.PartOfDirective:
+        return _readPartOfDirective();
+      case Tag.PostfixExpression:
+        return _readPostfixExpression();
+      case Tag.PrefixExpression:
+        return _readPrefixExpression();
+      case Tag.PrefixedIdentifier:
+        return _readPrefixedIdentifier();
+      case Tag.PropertyAccess:
+        return _readPropertyAccess();
+      case Tag.RedirectingConstructorInvocation:
+        return _readRedirectingConstructorInvocation();
+      case Tag.SetOrMapLiteral:
+        return _readSetOrMapLiteral();
+      case Tag.ShowCombinator:
+        return _readShowCombinator();
+      case Tag.SimpleFormalParameter:
+        return _readSimpleFormalParameter();
+      case Tag.SimpleIdentifier:
+        return _readSimpleIdentifier();
+      case Tag.SimpleStringLiteral:
+        return _readSimpleStringLiteral();
+      case Tag.SpreadElement:
+        return _readSpreadElement();
+      case Tag.StringInterpolation:
+        return _readStringInterpolation();
+      case Tag.SuperConstructorInvocation:
+        return _readSuperConstructorInvocation();
+      case Tag.SuperExpression:
+        return _readSuperExpression();
+      case Tag.SymbolLiteral:
+        return _readSymbolLiteral();
+      case Tag.ThisExpression:
+        return _readThisExpression();
+      case Tag.ThrowExpression:
+        return _readThrowExpression();
+      case Tag.TypeArgumentList:
+        return _readTypeArgumentList();
+      case Tag.TypeName:
+        return _readTypeName();
+      case Tag.TypeParameter:
+        return _readTypeParameter();
+      case Tag.TypeParameterList:
+        return _readTypeParameterList();
+      case Tag.TopLevelVariableDeclaration:
+        return _readTopLevelVariableDeclaration();
+      case Tag.VariableDeclaration:
+        return _readVariableDeclaration();
+      case Tag.VariableDeclarationList:
+        return _readVariableDeclarationList();
+      case Tag.WithClause:
+        return _readWithClause();
       default:
-        throw StateError('${data.comment_type}');
+        throw UnimplementedError('Unexpected tag: $tag');
     }
   }
 
-  CommentReference _read_commentReference(LinkedNode data) {
-    return astFactory.commentReference(
-      AstBinaryFlags.isNew(data.flags) ? _Tokens.NEW : null,
-      _readNode(data.commentReference_identifier),
+  IntegerLiteral _createIntegerLiteral(int value) {
+    // TODO(scheglov) Write token?
+    return astFactory.integerLiteral(
+      TokenFactory.tokenFromTypeAndString(TokenType.INT, '$value'),
+      value,
     );
   }
 
-  CompilationUnit _read_compilationUnit(LinkedNode data) {
-    var node = astFactory.compilationUnit(
-      beginToken: null,
-      scriptTag: _readNode(data.compilationUnit_scriptTag),
-      directives: _readNodeList(data.compilationUnit_directives),
-      declarations: _readNodeList(data.compilationUnit_declarations),
-      endToken: null,
-      featureSet: ExperimentStatus.fromStorage(
-        data.compilationUnit_featureSet,
-      ),
+  FunctionBody _functionBodyForFlags(int flags) {
+    if (AstBinaryFlags.isNative(flags)) {
+      return AstTestFactory.nativeFunctionBody('');
+    } else if (AstBinaryFlags.isAbstract(flags)) {
+      return AstTestFactory.emptyFunctionBody();
+    } else {
+      return astFactory.blockFunctionBody(
+        AstBinaryFlags.isAsync(flags) ? Tokens.ASYNC : null,
+        AstBinaryFlags.isGenerator(flags) ? Tokens.STAR : null,
+        astFactory.block(
+          Tokens.OPEN_CURLY_BRACKET,
+          const <Statement>[],
+          Tokens.CLOSE_CURLY_BRACKET,
+        ),
+      );
+    }
+  }
+
+  AdjacentStrings _readAdjacentStrings() {
+    var components = _readNodeList<StringLiteral>();
+    return astFactory.adjacentStrings(components);
+  }
+
+  Annotation _readAnnotation() {
+    var name = _readOptionalNode() as Identifier;
+    var constructorName = _readOptionalNode() as SimpleIdentifier;
+    var arguments = _readOptionalNode() as ArgumentList;
+    return astFactory.annotation(
+      Tokens.AT,
+      name,
+      Tokens.PERIOD,
+      constructorName,
+      arguments,
     );
-    LazyCompilationUnit(node, data);
+  }
+
+  ArgumentList _readArgumentList() {
+    var arguments = _readNodeList<Expression>();
+
+    return astFactory.argumentList(
+      Tokens.OPEN_PAREN,
+      arguments,
+      Tokens.CLOSE_PAREN,
+    );
+  }
+
+  AsExpression _readAsExpression() {
+    var expression = readNode() as Expression;
+    var type = readNode() as TypeAnnotation;
+    return astFactory.asExpression(expression, Tokens.AS, type);
+  }
+
+  AssertInitializer _readAssertInitializer() {
+    var condition = readNode() as Expression;
+    var message = _readOptionalNode() as Expression;
+    return astFactory.assertInitializer(
+      Tokens.ASSERT,
+      Tokens.OPEN_PAREN,
+      condition,
+      Tokens.COMMA,
+      message,
+      Tokens.CLOSE_PAREN,
+    );
+  }
+
+  AssignmentExpression _readAssignmentExpression() {
+    var leftHandSide = readNode() as Expression;
+    var rightHandSide = readNode() as Expression;
+    var operatorType = UnlinkedTokenType.values[_readByte()];
+    return astFactory.assignmentExpression(
+      leftHandSide,
+      Tokens.fromType(operatorType),
+      rightHandSide,
+    );
+  }
+
+  BinaryExpression _readBinaryExpression() {
+    var leftOperand = readNode() as Expression;
+    var rightOperand = readNode() as Expression;
+    var operatorType = UnlinkedTokenType.values[_readByte()];
+    return astFactory.binaryExpression(
+      leftOperand,
+      Tokens.fromType(operatorType),
+      rightOperand,
+    );
+  }
+
+  BooleanLiteral _readBooleanLiteral() {
+    var value = _readByte() == 1;
+    // TODO(scheglov) type?
+    return AstTestFactory.booleanLiteral(value);
+  }
+
+  int _readByte() {
+    return _unitReader.astReader.readByte();
+  }
+
+  CascadeExpression _readCascadeExpression() {
+    var target = readNode() as Expression;
+    var sections = _readNodeList<Expression>();
+    return astFactory.cascadeExpression(target, sections);
+  }
+
+  ClassDeclaration _readClassDeclaration() {
+    var flags = _readByte();
+
+    var codeOffset = _readInformativeUint30();
+    var codeLength = _readInformativeUint30();
+    var documentationTokenIndexList = _readUint30List();
+
+    var typeParameters = _readOptionalNode() as TypeParameterList;
+    var extendsClause = _readOptionalNode() as ExtendsClause;
+    var withClause = _readOptionalNode() as WithClause;
+    var implementsClause = _readOptionalNode() as ImplementsClause;
+    var nativeClause = _readOptionalNode() as NativeClause;
+    var name = readNode() as SimpleIdentifier;
+    var metadata = _readNodeList<Annotation>();
+
+    var node = astFactory.classDeclaration(
+      null,
+      metadata,
+      AstBinaryFlags.isAbstract(flags) ? Tokens.ABSTRACT : null,
+      Tokens.CLASS,
+      name,
+      typeParameters,
+      extendsClause,
+      withClause,
+      implementsClause,
+      Tokens.OPEN_CURLY_BRACKET,
+      const <ClassMember>[],
+      Tokens.CLOSE_CURLY_BRACKET,
+    ) as ClassDeclarationImpl;
+    node.nativeClause = nativeClause;
+
+    node.linkedContext = LinkedContext(
+      _unitReader,
+      node,
+      codeOffset: codeOffset,
+      codeLength: codeLength,
+      isClassWithConstConstructor: AstBinaryFlags.hasConstConstructor(flags),
+      resolutionIndex: _readUInt30(),
+      documentationTokenIndexList: documentationTokenIndexList,
+    );
+
     return node;
   }
 
-  ConditionalExpression _read_conditionalExpression(LinkedNode data) {
+  ClassTypeAlias _readClassTypeAlias() {
+    var flags = _readByte();
+
+    var codeOffset = _readInformativeUint30();
+    var codeLength = _readInformativeUint30();
+
+    var typeParameters = _readOptionalNode() as TypeParameterList;
+    var superClass = readNode() as TypeName;
+    var withClause = readNode() as WithClause;
+    var implementsClause = _readOptionalNode() as ImplementsClause;
+    var name = readNode() as SimpleIdentifier;
+    var metadata = _readNodeList<Annotation>();
+    var documentationTokenIndexList = _readUint30List();
+
+    var node = astFactory.classTypeAlias(
+      null,
+      metadata,
+      Tokens.CLASS,
+      name,
+      typeParameters,
+      Tokens.EQ,
+      AstBinaryFlags.isAbstract(flags) ? Tokens.ABSTRACT : null,
+      superClass,
+      withClause,
+      implementsClause,
+      Tokens.SEMICOLON,
+    ) as ClassTypeAliasImpl;
+
+    node.linkedContext = LinkedContext(
+      _unitReader,
+      node,
+      codeOffset: codeOffset,
+      codeLength: codeLength,
+      resolutionIndex: _readUInt30(),
+      documentationTokenIndexList: documentationTokenIndexList,
+    );
+
+    return node;
+  }
+
+  ConditionalExpression _readConditionalExpression() {
+    var condition = readNode() as Expression;
+    var thenExpression = readNode() as Expression;
+    var elseExpression = readNode() as Expression;
     return astFactory.conditionalExpression(
-      _readNode(data.conditionalExpression_condition),
-      _Tokens.QUESTION,
-      _readNode(data.conditionalExpression_thenExpression),
-      _Tokens.COLON,
-      _readNode(data.conditionalExpression_elseExpression),
-    )..staticType = _readType(data.expression_type);
+      condition,
+      Tokens.QUESTION,
+      thenExpression,
+      Tokens.COLON,
+      elseExpression,
+    );
   }
 
-  Configuration _read_configuration(LinkedNode data) {
+  Configuration _readConfiguration() {
+    var flags = _readByte();
+    var name = readNode() as DottedName;
+    var value = _readOptionalNode() as StringLiteral;
+    var uri = readNode() as StringLiteral;
     return astFactory.configuration(
-      _Tokens.IF,
-      _Tokens.OPEN_PAREN,
-      _readNode(data.configuration_name),
-      AstBinaryFlags.hasEqual(data.flags) ? _Tokens.EQ : null,
-      _readNode(data.configuration_value),
-      _Tokens.CLOSE_PAREN,
-      _readNode(data.configuration_uri),
+      Tokens.IF,
+      Tokens.OPEN_PAREN,
+      name,
+      AstBinaryFlags.hasEqual(flags) ? Tokens.EQ : null,
+      value,
+      Tokens.CLOSE_PAREN,
+      uri,
     );
   }
 
-  ConstructorDeclaration _read_constructorDeclaration(LinkedNode data) {
-    SimpleIdentifier returnType = _readNode(
-      data.constructorDeclaration_returnType,
-    );
+  ConstructorDeclaration _readConstructorDeclaration() {
+    var flags = _readByte();
 
-    var informativeData = _unitContext.getInformativeData(data);
-    returnType.token.offset =
-        informativeData?.constructorDeclaration_returnTypeOffset ?? 0;
+    var codeOffset = _readInformativeUint30();
+    var codeLength = _readInformativeUint30();
+    var documentationTokenIndexList = _readUint30List();
 
-    Token periodToken;
-    SimpleIdentifier nameIdentifier;
-    if (AstBinaryFlags.hasName(data.flags)) {
-      periodToken = Token(
-        TokenType.PERIOD,
-        informativeData?.constructorDeclaration_periodOffset ?? 0,
-      );
-      nameIdentifier = _declaredIdentifier(data);
+    var returnType = readNode() as SimpleIdentifier;
+
+    Token period;
+    SimpleIdentifier name;
+    if (AstBinaryFlags.hasName(flags)) {
+      var periodOffset = _readInformativeUint30();
+      period = Token(TokenType.PERIOD, periodOffset);
+      name = readNode() as SimpleIdentifier;
     }
 
+    var parameters = readNode() as FormalParameterList;
+    var initializers = _readNodeList<ConstructorInitializer>();
+    var redirectedConstructor = _readOptionalNode() as ConstructorName;
+    var metadata = _readNodeList<Annotation>();
+
     var node = astFactory.constructorDeclaration(
-      _readDocumentationComment(data),
-      _readNodeListLazy(data.annotatedNode_metadata),
-      AstBinaryFlags.isExternal(data.flags) ? _Tokens.EXTERNAL : null,
-      AstBinaryFlags.isConst(data.flags) ? _Tokens.CONST : null,
-      AstBinaryFlags.isFactory(data.flags) ? _Tokens.FACTORY : null,
+      null,
+      metadata,
+      AstBinaryFlags.isExternal(flags) ? Tokens.EXTERNAL : null,
+      AstBinaryFlags.isConst(flags) ? Tokens.CONST : null,
+      AstBinaryFlags.isFactory(flags) ? Tokens.FACTORY : null,
       returnType,
-      periodToken,
-      nameIdentifier,
-      _readNodeLazy(data.constructorDeclaration_parameters),
-      _Tokens.choose(
-        AstBinaryFlags.hasSeparatorColon(data.flags),
-        _Tokens.COLON,
-        AstBinaryFlags.hasSeparatorEquals(data.flags),
-        _Tokens.EQ,
+      period,
+      name,
+      parameters,
+      Tokens.choose(
+        AstBinaryFlags.hasSeparatorColon(flags),
+        Tokens.COLON,
+        AstBinaryFlags.hasSeparatorEquals(flags),
+        Tokens.EQ,
       ),
-      _readNodeListLazy(data.constructorDeclaration_initializers),
-      _readNodeLazy(data.constructorDeclaration_redirectedConstructor),
-      _readNodeLazy(data.constructorDeclaration_body),
+      initializers,
+      redirectedConstructor,
+      null,
+    ) as ConstructorDeclarationImpl;
+
+    node.linkedContext = LinkedContext(
+      _unitReader,
+      node,
+      codeOffset: codeOffset,
+      codeLength: codeLength,
+      resolutionIndex: _readUInt30(),
+      documentationTokenIndexList: documentationTokenIndexList,
     );
-    LazyConstructorDeclaration.setData(node, data);
+
     return node;
   }
 
-  ConstructorFieldInitializer _read_constructorFieldInitializer(
-      LinkedNode data) {
-    var hasThis = AstBinaryFlags.hasThis(data.flags);
+  ConstructorFieldInitializer _readConstructorFieldInitializer() {
+    var flags = _readByte();
+    var fieldName = readNode() as SimpleIdentifier;
+    var expression = readNode() as Expression;
+    var hasThis = AstBinaryFlags.hasThis(flags);
     return astFactory.constructorFieldInitializer(
-      hasThis ? _Tokens.THIS : null,
-      hasThis ? _Tokens.PERIOD : null,
-      _readNode(data.constructorFieldInitializer_fieldName),
-      _Tokens.EQ,
-      _readNode(data.constructorFieldInitializer_expression),
+      hasThis ? Tokens.THIS : null,
+      hasThis ? Tokens.PERIOD : null,
+      fieldName,
+      Tokens.EQ,
+      expression,
     );
   }
 
-  ConstructorName _read_constructorName(LinkedNode data) {
+  ConstructorName _readConstructorName() {
+    var type = readNode() as TypeName;
+    var name = _readOptionalNode() as SimpleIdentifier;
+
     return astFactory.constructorName(
-      _readNode(data.constructorName_type),
-      data.constructorName_name != null ? _Tokens.PERIOD : null,
-      _readNode(data.constructorName_name),
-    )..staticElement = _elementOfComponents(
-        data.constructorName_element,
-        data.constructorName_substitution,
-      );
-  }
-
-  ContinueStatement _read_continueStatement(LinkedNode data) {
-    return astFactory.continueStatement(
-      _Tokens.CONTINUE,
-      _readNode(data.continueStatement_label),
-      _Tokens.SEMICOLON,
+      type,
+      name != null ? Tokens.PERIOD : null,
+      name,
     );
   }
 
-  DeclaredIdentifier _read_declaredIdentifier(LinkedNode data) {
+  DeclaredIdentifier _readDeclaredIdentifier() {
+    var flags = _readByte();
+    var type = _readOptionalNode() as TypeAnnotation;
+    var identifier = readNode() as SimpleIdentifier;
+    var metadata = _readNodeList<Annotation>();
     return astFactory.declaredIdentifier(
-      _readDocumentationComment(data),
-      _readNodeList(data.annotatedNode_metadata),
-      _Tokens.choose(
-        AstBinaryFlags.isConst(data.flags),
-        _Tokens.CONST,
-        AstBinaryFlags.isFinal(data.flags),
-        _Tokens.FINAL,
-        AstBinaryFlags.isVar(data.flags),
-        _Tokens.VAR,
-      ),
-      _readNode(data.declaredIdentifier_type),
-      _readNode(data.declaredIdentifier_identifier),
-    );
-  }
-
-  DefaultFormalParameter _read_defaultFormalParameter(LinkedNode data) {
-    var node = astFactory.defaultFormalParameter(
-      _readNode(data.defaultFormalParameter_parameter),
-      _toParameterKind(data.defaultFormalParameter_kind),
-      data.defaultFormalParameter_defaultValue != null ? _Tokens.COLON : null,
-      _readNodeLazy(data.defaultFormalParameter_defaultValue),
-    );
-    LazyFormalParameter.setData(node, data);
-    return node;
-  }
-
-  DoStatement _read_doStatement(LinkedNode data) {
-    return astFactory.doStatement(
-      _Tokens.DO,
-      _readNode(data.doStatement_body),
-      _Tokens.WHILE,
-      _Tokens.OPEN_PAREN,
-      _readNode(data.doStatement_condition),
-      _Tokens.CLOSE_PAREN,
-      _Tokens.SEMICOLON,
-    );
-  }
-
-  DottedName _read_dottedName(LinkedNode data) {
-    return astFactory.dottedName(
-      _readNodeList(data.dottedName_components),
-    );
-  }
-
-  DoubleLiteral _read_doubleLiteral(LinkedNode data) {
-    return AstTestFactory.doubleLiteral(data.doubleLiteral_value)
-      ..staticType = _doubleType;
-  }
-
-  EmptyFunctionBody _read_emptyFunctionBody(LinkedNode data) {
-    return astFactory.emptyFunctionBody(
-      _Tokens.SEMICOLON,
-    );
-  }
-
-  EmptyStatement _read_emptyStatement(LinkedNode data) {
-    return astFactory.emptyStatement(
-      _Tokens.SEMICOLON,
-    );
-  }
-
-  EnumConstantDeclaration _read_enumConstantDeclaration(LinkedNode data) {
-    var node = astFactory.enumConstantDeclaration(
-      _readDocumentationComment(data),
-      _readNodeListLazy(data.annotatedNode_metadata),
-      _declaredIdentifier(data),
-    );
-    LazyEnumConstantDeclaration.setData(node, data);
-    return node;
-  }
-
-  EnumDeclaration _read_enumDeclaration(LinkedNode data) {
-    var node = astFactory.enumDeclaration(
-      _readDocumentationComment(data),
-      _readNodeListLazy(data.annotatedNode_metadata),
-      _Tokens.ENUM,
-      _declaredIdentifier(data),
-      _Tokens.OPEN_CURLY_BRACKET,
-      _readNodeListLazy(data.enumDeclaration_constants),
-      _Tokens.CLOSE_CURLY_BRACKET,
-    );
-    LazyEnumDeclaration.setData(node, data);
-    return node;
-  }
-
-  ExportDirective _read_exportDirective(LinkedNode data) {
-    timerAstBinaryReaderDirective.start();
-    _isReadingDirective = true;
-    try {
-      var node = astFactory.exportDirective(
-        _readDocumentationComment(data),
-        _readNodeListLazy(data.annotatedNode_metadata),
-        _directiveKeyword(data, Keyword.EXPORT, _Tokens.EXPORT),
-        _readNode(data.uriBasedDirective_uri),
-        _readNodeList(data.namespaceDirective_configurations),
-        _readNodeList(data.namespaceDirective_combinators),
-        _Tokens.SEMICOLON,
-      );
-      LazyDirective.setData(node, data);
-      return node;
-    } finally {
-      _isReadingDirective = false;
-      timerAstBinaryReaderDirective.stop();
-    }
-  }
-
-  ExpressionFunctionBody _read_expressionFunctionBody(LinkedNode data) {
-    timerAstBinaryReaderFunctionBody.start();
-    try {
-      return astFactory.expressionFunctionBody(
-        _Tokens.choose(
-          AstBinaryFlags.isAsync(data.flags),
-          _Tokens.ASYNC,
-          AstBinaryFlags.isSync(data.flags),
-          _Tokens.SYNC,
-        ),
-        _Tokens.ARROW,
-        _readNode(data.expressionFunctionBody_expression),
-        _Tokens.SEMICOLON,
-      );
-    } finally {
-      timerAstBinaryReaderFunctionBody.stop();
-    }
-  }
-
-  ExpressionStatement _read_expressionStatement(LinkedNode data) {
-    return astFactory.expressionStatement(
-      _readNode(data.expressionStatement_expression),
-      _Tokens.SEMICOLON,
-    );
-  }
-
-  ExtendsClause _read_extendsClause(LinkedNode data) {
-    return astFactory.extendsClause(
-      _Tokens.EXTENDS,
-      _readNode(data.extendsClause_superclass),
-    );
-  }
-
-  ExtensionDeclaration _read_extensionDeclaration(LinkedNode data) {
-    timerAstBinaryReaderClass.start();
-    try {
-      var node = astFactory.extensionDeclaration(
-        comment: _readDocumentationComment(data),
-        metadata: _readNodeListLazy(data.annotatedNode_metadata),
-        extensionKeyword: _Tokens.EXTENSION,
-        name: data.name.isNotEmpty ? _declaredIdentifier(data) : null,
-        typeParameters: _readNode(data.extensionDeclaration_typeParameters),
-        onKeyword: _Tokens.ON,
-        extendedType: _readNodeLazy(data.extensionDeclaration_extendedType),
-        leftBracket: _Tokens.OPEN_CURLY_BRACKET,
-        members: _readNodeListLazy(data.extensionDeclaration_members),
-        rightBracket: _Tokens.CLOSE_CURLY_BRACKET,
-      );
-      LazyExtensionDeclaration(node, data);
-      return node;
-    } finally {
-      timerAstBinaryReaderClass.stop();
-    }
-  }
-
-  ExtensionOverride _read_extensionOverride(LinkedNode data) {
-    var node = astFactory.extensionOverride(
-      extensionName: _readNode(data.extensionOverride_extensionName),
-      argumentList: astFactory.argumentList(
-        _Tokens.OPEN_PAREN,
-        _readNodeList(
-          data.extensionOverride_arguments,
-        ),
-        _Tokens.CLOSE_PAREN,
-      ),
-      typeArguments: _readNode(data.extensionOverride_typeArguments),
-    ) as ExtensionOverrideImpl;
-    node.extendedType = _readType(data.extensionOverride_extendedType);
-    node.typeArgumentTypes =
-        data.extensionOverride_typeArgumentTypes.map(_readType).toList();
-    return node;
-  }
-
-  FieldDeclaration _read_fieldDeclaration(LinkedNode data) {
-    var node = astFactory.fieldDeclaration2(
-      comment: _readDocumentationComment(data),
-      abstractKeyword:
-          AstBinaryFlags.isAbstract(data.flags) ? _Tokens.ABSTRACT : null,
-      covariantKeyword:
-          AstBinaryFlags.isCovariant(data.flags) ? _Tokens.COVARIANT : null,
-      externalKeyword:
-          AstBinaryFlags.isExternal(data.flags) ? _Tokens.EXTERNAL : null,
-      fieldList: _readNode(data.fieldDeclaration_fields),
-      metadata: _readNodeListLazy(data.annotatedNode_metadata),
-      semicolon: _Tokens.SEMICOLON,
-      staticKeyword:
-          AstBinaryFlags.isStatic(data.flags) ? _Tokens.STATIC : null,
-    );
-    LazyFieldDeclaration.setData(node, data);
-    return node;
-  }
-
-  FieldFormalParameter _read_fieldFormalParameter(LinkedNode data) {
-    var node = astFactory.fieldFormalParameter2(
-      identifier: _declaredIdentifier(data),
-      period: _Tokens.PERIOD,
-      thisKeyword: _Tokens.THIS,
-      covariantKeyword:
-          AstBinaryFlags.isCovariant(data.flags) ? _Tokens.COVARIANT : null,
-      typeParameters: _readNode(data.fieldFormalParameter_typeParameters),
-      keyword: _Tokens.choose(
-        AstBinaryFlags.isConst(data.flags),
-        _Tokens.CONST,
-        AstBinaryFlags.isFinal(data.flags),
-        _Tokens.FINAL,
-        AstBinaryFlags.isVar(data.flags),
-        _Tokens.VAR,
-      ),
-      metadata: _readNodeList(data.normalFormalParameter_metadata),
-      comment: _readDocumentationComment(data),
-      type: _readNodeLazy(data.fieldFormalParameter_type),
-      parameters: _readNodeLazy(data.fieldFormalParameter_formalParameters),
-      question:
-          AstBinaryFlags.hasQuestion(data.flags) ? _Tokens.QUESTION : null,
-      requiredKeyword:
-          AstBinaryFlags.isRequired(data.flags) ? _Tokens.REQUIRED : null,
-    );
-    LazyFormalParameter.setData(node, data);
-    return node;
-  }
-
-  ForEachPartsWithDeclaration _read_forEachPartsWithDeclaration(
-      LinkedNode data) {
-    return astFactory.forEachPartsWithDeclaration(
-      inKeyword: _Tokens.IN,
-      iterable: _readNode(data.forEachParts_iterable),
-      loopVariable: _readNode(data.forEachPartsWithDeclaration_loopVariable),
-    );
-  }
-
-  ForEachPartsWithIdentifier _read_forEachPartsWithIdentifier(LinkedNode data) {
-    return astFactory.forEachPartsWithIdentifier(
-      inKeyword: _Tokens.IN,
-      iterable: _readNode(data.forEachParts_iterable),
-      identifier: _readNode(data.forEachPartsWithIdentifier_identifier),
-    );
-  }
-
-  ForElement _read_forElement(LinkedNode data) {
-    return astFactory.forElement(
-      awaitKeyword: AstBinaryFlags.hasAwait(data.flags) ? _Tokens.AWAIT : null,
-      body: _readNode(data.forElement_body),
-      forKeyword: _Tokens.FOR,
-      forLoopParts: _readNode(data.forMixin_forLoopParts),
-      leftParenthesis: _Tokens.OPEN_PAREN,
-      rightParenthesis: _Tokens.CLOSE_PAREN,
-    );
-  }
-
-  FormalParameterList _read_formalParameterList(LinkedNode data) {
-    return astFactory.formalParameterList(
-      _Tokens.OPEN_PAREN,
-      _readNodeList(data.formalParameterList_parameters),
-      _Tokens.choose(
-        AstBinaryFlags.isDelimiterCurly(data.flags),
-        _Tokens.OPEN_CURLY_BRACKET,
-        AstBinaryFlags.isDelimiterSquare(data.flags),
-        _Tokens.OPEN_SQUARE_BRACKET,
-      ),
-      _Tokens.choose(
-        AstBinaryFlags.isDelimiterCurly(data.flags),
-        _Tokens.CLOSE_CURLY_BRACKET,
-        AstBinaryFlags.isDelimiterSquare(data.flags),
-        _Tokens.CLOSE_SQUARE_BRACKET,
-      ),
-      _Tokens.CLOSE_PAREN,
-    );
-  }
-
-  ForPartsWithDeclarations _read_forPartsWithDeclarations(LinkedNode data) {
-    return astFactory.forPartsWithDeclarations(
-      condition: _readNode(data.forParts_condition),
-      leftSeparator: _Tokens.SEMICOLON,
-      rightSeparator: _Tokens.SEMICOLON,
-      updaters: _readNodeList(data.forParts_updaters),
-      variables: _readNode(data.forPartsWithDeclarations_variables),
-    );
-  }
-
-  ForPartsWithExpression _read_forPartsWithExpression(LinkedNode data) {
-    return astFactory.forPartsWithExpression(
-      condition: _readNode(data.forParts_condition),
-      initialization: _readNode(data.forPartsWithExpression_initialization),
-      leftSeparator: _Tokens.SEMICOLON,
-      rightSeparator: _Tokens.SEMICOLON,
-      updaters: _readNodeList(data.forParts_updaters),
-    );
-  }
-
-  ForStatement _read_forStatement(LinkedNode data) {
-    return astFactory.forStatement(
-      awaitKeyword: AstBinaryFlags.hasAwait(data.flags) ? _Tokens.AWAIT : null,
-      forKeyword: _Tokens.FOR,
-      leftParenthesis: _Tokens.OPEN_PAREN,
-      forLoopParts: _readNode(data.forMixin_forLoopParts),
-      rightParenthesis: _Tokens.CLOSE_PAREN,
-      body: _readNode(data.forStatement_body),
-    );
-  }
-
-  FunctionDeclaration _read_functionDeclaration(LinkedNode data) {
-    timerAstBinaryReaderFunctionDeclaration.start();
-    try {
-      var node = astFactory.functionDeclaration(
-        _readDocumentationComment(data),
-        _readNodeListLazy(data.annotatedNode_metadata),
-        AstBinaryFlags.isExternal(data.flags) ? _Tokens.EXTERNAL : null,
-        _readNodeLazy(data.functionDeclaration_returnType),
-        _Tokens.choose(
-          AstBinaryFlags.isGet(data.flags),
-          _Tokens.GET,
-          AstBinaryFlags.isSet(data.flags),
-          _Tokens.SET,
-        ),
-        _declaredIdentifier(data),
-        _readNodeLazy(data.functionDeclaration_functionExpression),
-      );
-      LazyFunctionDeclaration.setData(node, data);
-      return node;
-    } finally {
-      timerAstBinaryReaderFunctionDeclaration.stop();
-    }
-  }
-
-  FunctionDeclarationStatement _read_functionDeclarationStatement(
-      LinkedNode data) {
-    return astFactory.functionDeclarationStatement(
-      _readNode(data.functionDeclarationStatement_functionDeclaration),
-    );
-  }
-
-  FunctionExpression _read_functionExpression(LinkedNode data) {
-    var node = astFactory.functionExpression(
-      _readNode(data.functionExpression_typeParameters),
-      _readNodeLazy(data.functionExpression_formalParameters),
-      _readNodeLazy(data.functionExpression_body),
-    );
-    LazyFunctionExpression.setData(node, data);
-    return node;
-  }
-
-  FunctionExpressionInvocation _read_functionExpressionInvocation(
-      LinkedNode data) {
-    return astFactory.functionExpressionInvocation(
-      _readNode(data.functionExpressionInvocation_function),
-      _readNode(data.invocationExpression_typeArguments),
-      _readNode(data.invocationExpression_arguments),
-    )..staticInvokeType = _readType(data.invocationExpression_invokeType);
-  }
-
-  FunctionTypeAlias _read_functionTypeAlias(LinkedNode data) {
-    var node = astFactory.functionTypeAlias(
-      _readDocumentationComment(data),
-      _readNodeListLazy(data.annotatedNode_metadata),
-      _Tokens.TYPEDEF,
-      _readNodeLazy(data.functionTypeAlias_returnType),
-      _declaredIdentifier(data),
-      _readNode(data.functionTypeAlias_typeParameters),
-      _readNodeLazy(data.functionTypeAlias_formalParameters),
-      _Tokens.SEMICOLON,
-    );
-    LazyFunctionTypeAlias.setData(node, data);
-    LazyFunctionTypeAlias.setHasSelfReference(
-      node,
-      data.typeAlias_hasSelfReference,
-    );
-    return node;
-  }
-
-  FunctionTypedFormalParameter _read_functionTypedFormalParameter(
-      LinkedNode data) {
-    var node = astFactory.functionTypedFormalParameter2(
-      comment: _readDocumentationComment(data),
-      covariantKeyword:
-          AstBinaryFlags.isCovariant(data.flags) ? _Tokens.COVARIANT : null,
-      identifier: _declaredIdentifier(data),
-      metadata: _readNodeListLazy(data.normalFormalParameter_metadata),
-      parameters: _readNodeLazy(
-        data.functionTypedFormalParameter_formalParameters,
-      ),
-      requiredKeyword:
-          AstBinaryFlags.isRequired(data.flags) ? _Tokens.REQUIRED : null,
-      returnType: _readNodeLazy(data.functionTypedFormalParameter_returnType),
-      typeParameters: _readNode(
-        data.functionTypedFormalParameter_typeParameters,
-      ),
-    );
-    LazyFormalParameter.setData(node, data);
-    return node;
-  }
-
-  GenericFunctionType _read_genericFunctionType(LinkedNode data) {
-    var id = data.genericFunctionType_id;
-
-    // Read type parameters, without bounds, to avoid forward references.
-    TypeParameterList typeParameterList;
-    var typeParameterListData = data.genericFunctionType_typeParameters;
-    if (typeParameterListData != null) {
-      var dataList = typeParameterListData.typeParameterList_typeParameters;
-      var typeParameters = List<TypeParameter>(dataList.length);
-      for (var i = 0; i < dataList.length; ++i) {
-        var data = dataList[i];
-        typeParameters[i] = astFactory.typeParameter(
-          _readDocumentationComment(data),
-          _readNodeList(data.annotatedNode_metadata),
-          _declaredIdentifier(data),
-          data.typeParameter_bound != null ? _Tokens.EXTENDS : null,
-          null,
-        );
-      }
-      typeParameterList = astFactory.typeParameterList(
-        _Tokens.LT,
-        typeParameters,
-        _Tokens.GT,
-      );
-    }
-
-    GenericFunctionTypeImpl node = astFactory.genericFunctionType(
       null,
-      _Tokens.FUNCTION,
-      typeParameterList,
-      null,
-      question:
-          AstBinaryFlags.hasQuestion(data.flags) ? _Tokens.QUESTION : null,
-    );
-
-    // Create the node element, so now type parameter elements are available.
-    LazyAst.setGenericFunctionTypeId(node, id);
-    _unitContext.createGenericFunctionTypeElement(id, node);
-
-    // Finish reading.
-    if (typeParameterListData != null) {
-      var dataList = typeParameterListData.typeParameterList_typeParameters;
-      var typeParameters = typeParameterList.typeParameters;
-      for (var i = 0; i < dataList.length; ++i) {
-        var data = dataList[i];
-        var node = typeParameters[i];
-        node.bound = _readNode(data.typeParameter_bound);
-      }
-    }
-    node.returnType = readNode(data.genericFunctionType_returnType);
-    node.parameters = _readNode(data.genericFunctionType_formalParameters);
-    node.type = _readType(data.genericFunctionType_type);
-
-    return node;
-  }
-
-  GenericTypeAlias _read_genericTypeAlias(LinkedNode data) {
-    var node = astFactory.genericTypeAlias(
-      _readDocumentationComment(data),
-      _readNodeListLazy(data.annotatedNode_metadata),
-      _Tokens.TYPEDEF,
-      _declaredIdentifier(data),
-      _readNode(data.genericTypeAlias_typeParameters),
-      _Tokens.EQ,
-      _readNodeLazy(data.genericTypeAlias_functionType),
-      _Tokens.SEMICOLON,
-    );
-    LazyGenericTypeAlias.setData(node, data);
-    LazyGenericTypeAlias.setHasSelfReference(
-      node,
-      data.typeAlias_hasSelfReference,
-    );
-    return node;
-  }
-
-  HideCombinator _read_hideCombinator(LinkedNode data) {
-    var node = astFactory.hideCombinator(
-      _combinatorKeyword(data, Keyword.HIDE, _Tokens.HIDE),
-      data.names.map((name) => AstTestFactory.identifier3(name)).toList(),
-    );
-    LazyCombinator(node, data);
-    return node;
-  }
-
-  IfElement _read_ifElement(LinkedNode data) {
-    var elseElement = _readNode(data.ifElement_elseElement);
-    return astFactory.ifElement(
-      condition: _readNode(data.ifMixin_condition),
-      elseElement: elseElement,
-      elseKeyword: elseElement != null ? _Tokens.ELSE : null,
-      ifKeyword: _Tokens.IF,
-      leftParenthesis: _Tokens.OPEN_PAREN,
-      rightParenthesis: _Tokens.CLOSE_PAREN,
-      thenElement: _readNode(data.ifElement_thenElement),
-    );
-  }
-
-  IfStatement _read_ifStatement(LinkedNode data) {
-    var elseStatement = _readNode(data.ifStatement_elseStatement);
-    return astFactory.ifStatement(
-      _Tokens.IF,
-      _Tokens.OPEN_PAREN,
-      _readNode(data.ifMixin_condition),
-      _Tokens.CLOSE_PAREN,
-      _readNode(data.ifStatement_thenStatement),
-      elseStatement != null ? _Tokens.ELSE : null,
-      elseStatement,
-    );
-  }
-
-  ImplementsClause _read_implementsClause(LinkedNode data) {
-    return astFactory.implementsClause(
-      _Tokens.IMPLEMENTS,
-      _readNodeList(data.implementsClause_interfaces),
-    );
-  }
-
-  ImportDirective _read_importDirective(LinkedNode data) {
-    timerAstBinaryReaderDirective.start();
-    _isReadingDirective = true;
-    try {
-      SimpleIdentifier prefix;
-      if (data.importDirective_prefix.isNotEmpty) {
-        prefix = astFactory.simpleIdentifier(
-          TokenFactory.tokenFromString(data.importDirective_prefix),
-        );
-
-        var informativeData = _unitContext.getInformativeData(data);
-        prefix.token.offset =
-            informativeData?.importDirective_prefixOffset ?? 0;
-      }
-
-      var node = astFactory.importDirective(
-        _readDocumentationComment(data),
-        _readNodeListLazy(data.annotatedNode_metadata),
-        _directiveKeyword(data, Keyword.IMPORT, _Tokens.IMPORT),
-        _readNode(data.uriBasedDirective_uri),
-        _readNodeList(data.namespaceDirective_configurations),
-        AstBinaryFlags.isDeferred(data.flags) ? _Tokens.DEFERRED : null,
-        _Tokens.AS,
-        prefix,
-        _readNodeList(data.namespaceDirective_combinators),
-        _Tokens.SEMICOLON,
-      );
-      LazyDirective.setData(node, data);
-      return node;
-    } finally {
-      _isReadingDirective = false;
-      timerAstBinaryReaderDirective.stop();
-    }
-  }
-
-  IndexExpression _read_indexExpression(LinkedNode data) {
-    return astFactory.indexExpressionForTarget2(
-      target: _readNode(data.indexExpression_target),
-      question:
-          AstBinaryFlags.hasQuestion(data.flags) ? _Tokens.QUESTION : null,
-      leftBracket: _Tokens.OPEN_SQUARE_BRACKET,
-      index: _readNode(data.indexExpression_index),
-      rightBracket: _Tokens.CLOSE_SQUARE_BRACKET,
-    )
-      ..period =
-          AstBinaryFlags.hasPeriod(data.flags) ? _Tokens.PERIOD_PERIOD : null
-      ..staticElement = _elementOfComponents(
-        data.indexExpression_element,
-        data.indexExpression_substitution,
-      )
-      ..staticType = _readType(data.expression_type);
-  }
-
-  InstanceCreationExpression _read_instanceCreationExpression(LinkedNode data) {
-    var node = astFactory.instanceCreationExpression(
-      _Tokens.choose(
-        AstBinaryFlags.isConst(data.flags),
-        _Tokens.CONST,
-        AstBinaryFlags.isNew(data.flags),
-        _Tokens.NEW,
+      metadata,
+      Tokens.choose(
+        AstBinaryFlags.isConst(flags),
+        Tokens.CONST,
+        AstBinaryFlags.isFinal(flags),
+        Tokens.FINAL,
+        AstBinaryFlags.isVar(flags),
+        Tokens.VAR,
       ),
-      _readNode(data.instanceCreationExpression_constructorName),
-      astFactory.argumentList(
-        _Tokens.OPEN_PAREN,
-        _readNodeList(
-          data.instanceCreationExpression_arguments,
-        ),
-        _Tokens.CLOSE_PAREN,
-      ),
-      typeArguments: _readNode(data.instanceCreationExpression_typeArguments),
-    );
-    node.staticType = _readType(data.expression_type);
-    return node;
-  }
-
-  IntegerLiteral _read_integerLiteral(LinkedNode data) {
-    // TODO(scheglov) Remove `?? _intType` after internal SDK roll.
-    return AstTestFactory.integer(data.integerLiteral_value)
-      ..staticType = _readType(data.expression_type) ?? _intType;
-  }
-
-  InterpolationExpression _read_interpolationExpression(LinkedNode data) {
-    var isIdentifier =
-        AstBinaryFlags.isStringInterpolationIdentifier(data.flags);
-    return astFactory.interpolationExpression(
-      isIdentifier
-          ? _Tokens.OPEN_CURLY_BRACKET
-          : _Tokens.STRING_INTERPOLATION_EXPRESSION,
-      _readNode(data.interpolationExpression_expression),
-      isIdentifier ? null : _Tokens.CLOSE_CURLY_BRACKET,
+      type,
+      identifier,
     );
   }
 
-  InterpolationString _read_interpolationString(LinkedNode data) {
-    return astFactory.interpolationString(
-      TokenFactory.tokenFromString(data.interpolationString_value),
-      data.interpolationString_value,
-    );
-  }
+  DefaultFormalParameter _readDefaultFormalParameter() {
+    var flags = _readByte();
+    var codeOffset = _readInformativeUint30();
+    var codeLength = _readInformativeUint30();
+    var parameter = readNode() as NormalFormalParameter;
+    var defaultValue = _readOptionalNode() as Expression;
 
-  IsExpression _read_isExpression(LinkedNode data) {
-    return astFactory.isExpression(
-      _readNode(data.isExpression_expression),
-      _Tokens.IS,
-      AstBinaryFlags.hasNot(data.flags) ? _Tokens.BANG : null,
-      _readNode(data.isExpression_type),
-    )..staticType = _boolType;
-  }
-
-  Label _read_label(LinkedNode data) {
-    return astFactory.label(
-      _readNode(data.label_label),
-      _Tokens.COLON,
-    );
-  }
-
-  LabeledStatement _read_labeledStatement(LinkedNode data) {
-    return astFactory.labeledStatement(
-      _readNodeList(data.labeledStatement_labels),
-      _readNode(data.labeledStatement_statement),
-    );
-  }
-
-  LibraryDirective _read_libraryDirective(LinkedNode data) {
-    timerAstBinaryReaderDirective.start();
-    _isReadingDirective = true;
-    try {
-      var node = astFactory.libraryDirective(
-        _unitContext.createComment(data),
-        _readNodeListLazy(data.annotatedNode_metadata),
-        _Tokens.LIBRARY,
-        _readNode(data.libraryDirective_name),
-        _Tokens.SEMICOLON,
-      );
-      LazyDirective.setData(node, data);
-      return node;
-    } finally {
-      _isReadingDirective = false;
-      timerAstBinaryReaderDirective.stop();
-    }
-  }
-
-  LibraryIdentifier _read_libraryIdentifier(LinkedNode data) {
-    return astFactory.libraryIdentifier(
-      _readNodeList(data.libraryIdentifier_components),
-    );
-  }
-
-  ListLiteral _read_listLiteral(LinkedNode data) {
-    return astFactory.listLiteral(
-      AstBinaryFlags.isConst(data.flags) ? _Tokens.CONST : null,
-      AstBinaryFlags.hasTypeArguments(data.flags)
-          ? astFactory.typeArgumentList(
-              _Tokens.LT,
-              _readNodeList(data.typedLiteral_typeArguments),
-              _Tokens.GT,
-            )
-          : null,
-      _Tokens.OPEN_SQUARE_BRACKET,
-      _readNodeList(data.listLiteral_elements),
-      _Tokens.CLOSE_SQUARE_BRACKET,
-    )..staticType = _readType(data.expression_type);
-  }
-
-  MapLiteralEntry _read_mapLiteralEntry(LinkedNode data) {
-    return astFactory.mapLiteralEntry(
-      _readNode(data.mapLiteralEntry_key),
-      _Tokens.COLON,
-      _readNode(data.mapLiteralEntry_value),
-    );
-  }
-
-  MethodDeclaration _read_methodDeclaration(LinkedNode data) {
-    FunctionBody body;
-    if (AstBinaryFlags.isNative(data.flags)) {
-      body = AstTestFactory.nativeFunctionBody('');
-    } else if (AstBinaryFlags.isAbstract(data.flags)) {
-      body = AstTestFactory.emptyFunctionBody();
+    ParameterKind kind;
+    if (AstBinaryFlags.isPositional(flags)) {
+      kind = AstBinaryFlags.isRequired(flags)
+          ? ParameterKind.REQUIRED
+          : ParameterKind.POSITIONAL;
     } else {
-      body = AstTestFactory.blockFunctionBody(AstTestFactory.block());
+      kind = AstBinaryFlags.isRequired(flags)
+          ? ParameterKind.NAMED_REQUIRED
+          : ParameterKind.NAMED;
     }
 
-    var node = astFactory.methodDeclaration(
-      _readDocumentationComment(data),
-      _readNodeListLazy(data.annotatedNode_metadata),
-      AstBinaryFlags.isExternal(data.flags) ? _Tokens.EXTERNAL : null,
-      AstBinaryFlags.isStatic(data.flags) ? _Tokens.STATIC : null,
-      _readNodeLazy(data.methodDeclaration_returnType),
-      _Tokens.choose(
-        AstBinaryFlags.isGet(data.flags),
-        _Tokens.GET,
-        AstBinaryFlags.isSet(data.flags),
-        _Tokens.SET,
+    var node = astFactory.defaultFormalParameter(
+      parameter,
+      kind,
+      AstBinaryFlags.hasInitializer(flags) ? Tokens.COLON : null,
+      defaultValue,
+    ) as DefaultFormalParameterImpl;
+    node.summaryData = SummaryDataForFormalParameter(
+      codeOffset: codeOffset,
+      codeLength: codeLength,
+    );
+
+    return node;
+  }
+
+  DottedName _readDottedName() {
+    var components = _readNodeList<SimpleIdentifier>();
+    return astFactory.dottedName(components);
+  }
+
+  DoubleLiteral _readDoubleLiteral() {
+    var value = _unitReader.astReader.readDouble();
+    return AstTestFactory.doubleLiteral(value);
+  }
+
+  EnumConstantDeclaration _readEnumConstantDeclaration() {
+    var codeOffset = _readInformativeUint30();
+    var codeLength = _readInformativeUint30();
+    var documentationTokenIndexList = _readUint30List();
+
+    var name = readNode() as SimpleIdentifier;
+    var metadata = _readNodeList<Annotation>();
+
+    var node = astFactory.enumConstantDeclaration(null, metadata, name)
+        as EnumConstantDeclarationImpl;
+
+    node.linkedContext = LinkedContext(
+      _unitReader,
+      node,
+      codeOffset: codeOffset,
+      codeLength: codeLength,
+      resolutionIndex: -1,
+      documentationTokenIndexList: documentationTokenIndexList,
+    );
+
+    return node;
+  }
+
+  EnumDeclaration _readEnumDeclaration() {
+    var codeOffset = _readInformativeUint30();
+    var codeLength = _readInformativeUint30();
+    var documentationTokenIndexList = _readUint30List();
+
+    var constants = _readNodeList<EnumConstantDeclaration>();
+    var name = readNode() as SimpleIdentifier;
+    var metadata = _readNodeList<Annotation>();
+
+    var node = astFactory.enumDeclaration(
+      null,
+      metadata,
+      Tokens.ENUM,
+      name,
+      Tokens.OPEN_CURLY_BRACKET,
+      constants,
+      Tokens.CLOSE_CURLY_BRACKET,
+    ) as EnumDeclarationImpl;
+
+    node.linkedContext = LinkedContext(
+      _unitReader,
+      node,
+      codeOffset: codeOffset,
+      codeLength: codeLength,
+      resolutionIndex: _readUInt30(),
+      documentationTokenIndexList: documentationTokenIndexList,
+    );
+
+    return node;
+  }
+
+  ExportDirective _readExportDirective() {
+    var combinators = _readNodeList<Combinator>();
+    var configurations = _readNodeList<Configuration>();
+    var uri = readNode();
+    var keywordOffset = _readInformativeUint30();
+    var metadata = _readNodeList<Annotation>();
+
+    var node = astFactory.exportDirective(
+      null,
+      metadata,
+      KeywordToken(Keyword.EXPORT, keywordOffset),
+      uri,
+      configurations,
+      combinators,
+      Tokens.SEMICOLON,
+    ) as ExportDirectiveImpl;
+
+    node.linkedContext = LinkedContext(
+      _unitReader,
+      node,
+      codeOffset: -1,
+      codeLength: 0,
+      documentationTokenIndexList: _noDocumentationComment,
+      resolutionIndex: _readUInt30(),
+    );
+
+    return node;
+  }
+
+  ExtendsClause _readExtendsClause() {
+    var type = readNode() as TypeName;
+    return astFactory.extendsClause(Tokens.EXTENDS, type);
+  }
+
+  ExtensionDeclaration _readExtensionDeclaration() {
+    var codeOffset = _readInformativeUint30();
+    var codeLength = _readInformativeUint30();
+    var documentationTokenIndexList = _readUint30List();
+
+    var typeParameters = _readOptionalNode() as TypeParameterList;
+    var extendedType = readNode() as TypeAnnotation;
+    var name = _readOptionalNode() as SimpleIdentifier;
+    var metadata = _readNodeList<Annotation>();
+
+    var node = astFactory.extensionDeclaration(
+      comment: null,
+      metadata: metadata,
+      extensionKeyword: Tokens.EXTENSION,
+      name: name,
+      typeParameters: typeParameters,
+      onKeyword: Tokens.ON,
+      extendedType: extendedType,
+      leftBracket: Tokens.OPEN_CURLY_BRACKET,
+      members: const <ClassMember>[],
+      rightBracket: Tokens.CLOSE_CURLY_BRACKET,
+    ) as ExtensionDeclarationImpl;
+
+    node.linkedContext = LinkedContext(
+      _unitReader,
+      node,
+      codeOffset: codeOffset,
+      codeLength: codeLength,
+      resolutionIndex: _readUInt30(),
+      documentationTokenIndexList: documentationTokenIndexList,
+    );
+
+    return node;
+  }
+
+  ExtensionOverride _readExtensionOverride() {
+    var extensionName = readNode() as Identifier;
+    var typeArguments = _readOptionalNode() as TypeArgumentList;
+    var argumentList = readNode() as ArgumentList;
+    return astFactory.extensionOverride(
+      extensionName: extensionName,
+      argumentList: argumentList,
+      typeArguments: typeArguments,
+    );
+  }
+
+  FieldDeclaration _readFieldDeclaration() {
+    var flags = _readByte();
+    var codeOffsetLengthList = _readInformativeUint30List();
+    var documentationTokenIndexList = _readUint30List();
+    var fields = readNode() as VariableDeclarationList;
+    var metadata = _readNodeList<Annotation>();
+
+    var node = astFactory.fieldDeclaration2(
+      comment: null,
+      abstractKeyword:
+          AstBinaryFlags.isAbstract(flags) ? Tokens.ABSTRACT : null,
+      covariantKeyword:
+          AstBinaryFlags.isCovariant(flags) ? Tokens.COVARIANT : null,
+      externalKeyword:
+          AstBinaryFlags.isExternal(flags) ? Tokens.EXTERNAL : null,
+      fieldList: fields,
+      metadata: metadata,
+      semicolon: Tokens.SEMICOLON,
+      staticKeyword: AstBinaryFlags.isStatic(flags) ? Tokens.STATIC : null,
+    ) as FieldDeclarationImpl;
+
+    node.linkedContext = LinkedContext(
+      _unitReader,
+      node,
+      codeOffset: -1,
+      codeLength: 0,
+      codeOffsetLengthList: codeOffsetLengthList,
+      resolutionIndex: _readUInt30(),
+      documentationTokenIndexList: documentationTokenIndexList,
+    );
+
+    return node;
+  }
+
+  FieldFormalParameter _readFieldFormalParameter() {
+    var typeParameters = _readOptionalNode() as TypeParameterList;
+    var type = _readOptionalNode() as TypeAnnotation;
+    var formalParameters = _readOptionalNode() as FormalParameterList;
+    var flags = _readByte();
+    var codeOffset = _readInformativeUint30();
+    var codeLength = _readInformativeUint30();
+    var metadata = _readNodeList<Annotation>();
+    var identifier = readNode() as SimpleIdentifier;
+    var node = astFactory.fieldFormalParameter2(
+      identifier: identifier,
+      period: Tokens.PERIOD,
+      thisKeyword: Tokens.THIS,
+      covariantKeyword:
+          AstBinaryFlags.isCovariant(flags) ? Tokens.COVARIANT : null,
+      typeParameters: typeParameters,
+      keyword: Tokens.choose(
+        AstBinaryFlags.isConst(flags),
+        Tokens.CONST,
+        AstBinaryFlags.isFinal(flags),
+        Tokens.FINAL,
+        AstBinaryFlags.isVar(flags),
+        Tokens.VAR,
       ),
-      AstBinaryFlags.isOperator(data.flags) ? _Tokens.OPERATOR : null,
-      _declaredIdentifier(data),
-      _readNode(data.methodDeclaration_typeParameters),
-      _readNodeLazy(data.methodDeclaration_formalParameters),
+      metadata: metadata,
+      comment: null,
+      type: type,
+      parameters: formalParameters,
+      question: AstBinaryFlags.hasQuestion(flags) ? Tokens.QUESTION : null,
+      requiredKeyword:
+          AstBinaryFlags.isRequired(flags) ? Tokens.REQUIRED : null,
+    ) as FieldFormalParameterImpl;
+    node.summaryData = SummaryDataForFormalParameter(
+      codeOffset: codeOffset,
+      codeLength: codeLength,
+    );
+    return node;
+  }
+
+  ForEachPartsWithDeclaration _readForEachPartsWithDeclaration() {
+    var loopVariable = readNode() as DeclaredIdentifier;
+    var iterable = readNode() as Expression;
+    return astFactory.forEachPartsWithDeclaration(
+      inKeyword: Tokens.IN,
+      iterable: iterable,
+      loopVariable: loopVariable,
+    );
+  }
+
+  ForElement _readForElement() {
+    var body = readNode() as CollectionElement;
+    var flags = _readByte();
+    var forLoopParts = readNode() as ForLoopParts;
+    return astFactory.forElement(
+      awaitKeyword: AstBinaryFlags.hasAwait(flags) ? Tokens.AWAIT : null,
+      body: body,
+      forKeyword: Tokens.FOR,
+      forLoopParts: forLoopParts,
+      leftParenthesis: Tokens.OPEN_PAREN,
+      rightParenthesis: Tokens.CLOSE_PAREN,
+    );
+  }
+
+  FormalParameterList _readFormalParameterList() {
+    var flags = _readByte();
+    var parameters = _readNodeList<FormalParameter>();
+
+    return astFactory.formalParameterList(
+      Tokens.OPEN_PAREN,
+      parameters,
+      Tokens.choose(
+        AstBinaryFlags.isDelimiterCurly(flags),
+        Tokens.OPEN_CURLY_BRACKET,
+        AstBinaryFlags.isDelimiterSquare(flags),
+        Tokens.OPEN_SQUARE_BRACKET,
+      ),
+      Tokens.choose(
+        AstBinaryFlags.isDelimiterCurly(flags),
+        Tokens.CLOSE_CURLY_BRACKET,
+        AstBinaryFlags.isDelimiterSquare(flags),
+        Tokens.CLOSE_SQUARE_BRACKET,
+      ),
+      Tokens.CLOSE_PAREN,
+    );
+  }
+
+  ForPartsWithDeclarations _readForPartsWithDeclarations() {
+    var variables = readNode() as VariableDeclarationList;
+    var condition = _readOptionalNode() as Expression;
+    var updaters = _readNodeList<Expression>();
+    return astFactory.forPartsWithDeclarations(
+      condition: condition,
+      leftSeparator: Tokens.SEMICOLON,
+      rightSeparator: Tokens.SEMICOLON,
+      updaters: updaters,
+      variables: variables,
+    );
+  }
+
+  FunctionDeclaration _readFunctionDeclaration() {
+    var flags = _readByte();
+    var codeOffset = _readInformativeUint30();
+    var codeLength = _readInformativeUint30();
+    var documentationTokenIndexList = _readUint30List();
+    var functionExpression = readNode() as FunctionExpression;
+    var returnType = _readOptionalNode() as TypeAnnotation;
+    var name = readNode() as SimpleIdentifier;
+    var metadata = _readNodeList<Annotation>();
+
+    var node = astFactory.functionDeclaration(
+      null,
+      metadata,
+      AstBinaryFlags.isExternal(flags) ? Tokens.EXTERNAL : null,
+      returnType,
+      Tokens.choose(
+        AstBinaryFlags.isGet(flags),
+        Tokens.GET,
+        AstBinaryFlags.isSet(flags),
+        Tokens.SET,
+      ),
+      name,
+      functionExpression,
+    ) as FunctionDeclarationImpl;
+
+    node.linkedContext = LinkedContext(
+      _unitReader,
+      node,
+      codeOffset: codeOffset,
+      codeLength: codeLength,
+      resolutionIndex: _readUInt30(),
+      documentationTokenIndexList: documentationTokenIndexList,
+    );
+
+    return node;
+  }
+
+  FunctionExpression _readFunctionExpression() {
+    var flags = _readByte();
+    var typeParameters = _readOptionalNode() as TypeParameterList;
+    var formalParameters = _readOptionalNode() as FormalParameterList;
+    var body = _functionBodyForFlags(flags);
+
+    return astFactory.functionExpression(
+      typeParameters,
+      formalParameters,
       body,
     );
-    LazyMethodDeclaration.setData(node, data);
-    LazyAst.setOperatorEqualParameterTypeFromObject(
+  }
+
+  FunctionExpressionInvocation _readFunctionExpressionInvocation() {
+    var function = readNode() as Expression;
+    var typeArguments = _readOptionalNode() as TypeArgumentList;
+    var arguments = readNode() as ArgumentList;
+    return astFactory.functionExpressionInvocation(
+      function,
+      typeArguments,
+      arguments,
+    );
+  }
+
+  FunctionTypeAlias _readFunctionTypeAlias() {
+    var codeOffset = _readInformativeUint30();
+    var codeLength = _readInformativeUint30();
+    var documentationTokenIndexList = _readUint30List();
+
+    var typeParameters = _readOptionalNode() as TypeParameterList;
+    var returnType = _readOptionalNode() as TypeAnnotation;
+    var formalParameters = readNode() as FormalParameterList;
+    var name = readNode() as SimpleIdentifier;
+    var metadata = _readNodeList<Annotation>();
+
+    var node = astFactory.functionTypeAlias(
+      null,
+      metadata,
+      Tokens.TYPEDEF,
+      returnType,
+      name,
+      typeParameters,
+      formalParameters,
+      Tokens.SEMICOLON,
+    ) as FunctionTypeAliasImpl;
+
+    node.linkedContext = LinkedContext(
+      _unitReader,
       node,
-      data.methodDeclaration_hasOperatorEqualWithParameterTypeFromObject,
+      codeOffset: codeOffset,
+      codeLength: codeLength,
+      resolutionIndex: _readUInt30(),
+      documentationTokenIndexList: documentationTokenIndexList,
+    );
+
+    return node;
+  }
+
+  FunctionTypedFormalParameter _readFunctionTypedFormalParameter() {
+    var typeParameters = _readOptionalNode() as TypeParameterList;
+    var returnType = _readOptionalNode() as TypeAnnotation;
+    var formalParameters = readNode() as FormalParameterList;
+    var flags = _readByte();
+    var codeOffset = _readInformativeUint30();
+    var codeLength = _readInformativeUint30();
+    var metadata = _readNodeList<Annotation>();
+    var identifier = readNode() as SimpleIdentifier;
+    var node = astFactory.functionTypedFormalParameter2(
+      comment: null,
+      covariantKeyword:
+          AstBinaryFlags.isCovariant(flags) ? Tokens.COVARIANT : null,
+      identifier: identifier,
+      metadata: metadata,
+      parameters: formalParameters,
+      requiredKeyword:
+          AstBinaryFlags.isRequired(flags) ? Tokens.REQUIRED : null,
+      returnType: returnType,
+      typeParameters: typeParameters,
+    ) as FunctionTypedFormalParameterImpl;
+    node.summaryData = SummaryDataForFormalParameter(
+      codeOffset: codeOffset,
+      codeLength: codeLength,
     );
     return node;
   }
 
-  MethodInvocation _read_methodInvocation(LinkedNode data) {
-    return astFactory.methodInvocation(
-      _readNode(data.methodInvocation_target),
-      _Tokens.choose(
-        AstBinaryFlags.hasPeriod(data.flags),
-        _Tokens.PERIOD,
-        AstBinaryFlags.hasPeriod2(data.flags),
-        _Tokens.PERIOD_PERIOD,
+  GenericFunctionType _readGenericFunctionType() {
+    var flags = _readByte();
+    var typeParameters = _readOptionalNode() as TypeParameterList;
+    var returnType = _readOptionalNode() as TypeAnnotation;
+    var formalParameters = readNode() as FormalParameterList;
+
+    return astFactory.genericFunctionType(
+      returnType,
+      Tokens.FUNCTION,
+      typeParameters,
+      formalParameters,
+      question: AstBinaryFlags.hasQuestion(flags) ? Tokens.QUESTION : null,
+    );
+  }
+
+  GenericTypeAlias _readGenericTypeAlias() {
+    var codeOffset = _readInformativeUint30();
+    var codeLength = _readInformativeUint30();
+    var documentationTokenIndexList = _readUint30List();
+
+    var typeParameters = _readOptionalNode() as TypeParameterList;
+    var functionType = _readOptionalNode();
+    var name = readNode() as SimpleIdentifier;
+    var metadata = _readNodeList<Annotation>();
+
+    var node = astFactory.genericTypeAlias(
+      null,
+      metadata,
+      Tokens.TYPEDEF,
+      name,
+      typeParameters,
+      Tokens.EQ,
+      functionType,
+      Tokens.SEMICOLON,
+    ) as GenericTypeAliasImpl;
+
+    node.linkedContext = LinkedContext(
+      _unitReader,
+      node,
+      codeOffset: codeOffset,
+      codeLength: codeLength,
+      resolutionIndex: _readUInt30(),
+      documentationTokenIndexList: documentationTokenIndexList,
+    );
+
+    return node;
+  }
+
+  HideCombinator _readHideCombinator() {
+    var keywordOffset = _readInformativeUint30();
+    return astFactory.hideCombinator(
+      KeywordToken(Keyword.HIDE, keywordOffset),
+      _readNodeList<SimpleIdentifier>(),
+    );
+  }
+
+  IfElement _readIfElement() {
+    var condition = readNode() as Expression;
+    var thenElement = readNode() as CollectionElement;
+    var elseElement = _readOptionalNode() as CollectionElement;
+    return astFactory.ifElement(
+      condition: condition,
+      elseElement: elseElement,
+      elseKeyword: elseElement != null ? Tokens.ELSE : null,
+      ifKeyword: Tokens.IF,
+      leftParenthesis: Tokens.OPEN_PAREN,
+      rightParenthesis: Tokens.CLOSE_PAREN,
+      thenElement: thenElement,
+    );
+  }
+
+  ImplementsClause _readImplementsClause() {
+    var interfaces = _readNodeList<TypeName>();
+    return astFactory.implementsClause(Tokens.IMPLEMENTS, interfaces);
+  }
+
+  ImportDirective _readImportDirective() {
+    var flags = _readByte();
+
+    SimpleIdentifier prefixIdentifier;
+    if (AstBinaryFlags.hasPrefix(flags)) {
+      var prefixName = _readStringReference();
+      var prefixOffset = _readInformativeUint30();
+      prefixIdentifier = astFactory.simpleIdentifier(
+        StringToken(TokenType.STRING, prefixName, prefixOffset),
+      );
+    }
+
+    var combinators = _readNodeList<Combinator>();
+    var configurations = _readNodeList<Configuration>();
+    var uri = readNode();
+    var keywordOffset = _readInformativeUint30();
+    var metadata = _readNodeList<Annotation>();
+
+    var node = astFactory.importDirective(
+      null,
+      metadata,
+      KeywordToken(Keyword.IMPORT, keywordOffset),
+      uri,
+      configurations,
+      AstBinaryFlags.isDeferred(flags) ? Tokens.DEFERRED : null,
+      Tokens.AS,
+      prefixIdentifier,
+      combinators,
+      Tokens.SEMICOLON,
+    ) as ImportDirectiveImpl;
+
+    node.linkedContext = LinkedContext(
+      _unitReader,
+      node,
+      codeOffset: -1,
+      codeLength: 0,
+      documentationTokenIndexList: _noDocumentationComment,
+      resolutionIndex: _readUInt30(),
+    );
+
+    return node;
+  }
+
+  IndexExpression _readIndexExpression() {
+    var flags = _readByte();
+    var target = _readOptionalNode() as Expression;
+    var index = readNode() as Expression;
+    return astFactory.indexExpressionForTarget2(
+      target: target,
+      question: AstBinaryFlags.hasQuestion(flags) ? Tokens.QUESTION : null,
+      leftBracket: Tokens.OPEN_SQUARE_BRACKET,
+      index: index,
+      rightBracket: Tokens.CLOSE_SQUARE_BRACKET,
+    )..period = AstBinaryFlags.hasPeriod(flags) ? Tokens.PERIOD_PERIOD : null;
+  }
+
+  int _readInformativeUint30() {
+    if (_withInformative) {
+      return _readUInt30();
+    }
+    return 0;
+  }
+
+  Uint32List _readInformativeUint30List() {
+    if (_withInformative) {
+      return _readUint30List();
+    }
+    return null;
+  }
+
+  InstanceCreationExpression _readInstanceCreationExpression() {
+    var flags = _readByte();
+    var constructorName = readNode() as ConstructorName;
+    var argumentList = readNode() as ArgumentList;
+
+    return astFactory.instanceCreationExpression(
+      Tokens.choose(
+        AstBinaryFlags.isConst(flags),
+        Tokens.CONST,
+        AstBinaryFlags.isNew(flags),
+        Tokens.NEW,
       ),
-      _readNode(data.methodInvocation_methodName),
-      _readNode(data.invocationExpression_typeArguments),
-      _readNode(data.invocationExpression_arguments),
-    )..staticInvokeType = _readType(data.invocationExpression_invokeType);
+      constructorName,
+      argumentList,
+    );
   }
 
-  MixinDeclaration _read_mixinDeclaration(LinkedNode data) {
-    timerAstBinaryReaderMixin.start();
-    try {
-      var node = astFactory.mixinDeclaration(
-        _readDocumentationComment(data),
-        _readNodeListLazy(data.annotatedNode_metadata),
-        _Tokens.MIXIN,
-        _declaredIdentifier(data),
-        _readNode(data.classOrMixinDeclaration_typeParameters),
-        _readNodeLazy(data.mixinDeclaration_onClause),
-        _readNodeLazy(data.classOrMixinDeclaration_implementsClause),
-        _Tokens.OPEN_CURLY_BRACKET,
-        _readNodeListLazy(data.classOrMixinDeclaration_members),
-        _Tokens.CLOSE_CURLY_BRACKET,
-      );
-      LazyMixinDeclaration(node, data);
-      return node;
-    } finally {
-      timerAstBinaryReaderMixin.stop();
-    }
+  IntegerLiteral _readIntegerLiteralNegative() {
+    var value = (_readUint32() << 32) | _readUint32();
+    return _createIntegerLiteral(-value);
   }
 
-  NamedExpression _read_namedExpression(LinkedNode data) {
-    Expression expression = _readNode(data.namedExpression_expression);
-    return astFactory.namedExpression(
-      _readNode(data.namedExpression_name),
+  IntegerLiteral _readIntegerLiteralNegative1() {
+    var value = _readByte();
+    return _createIntegerLiteral(-value);
+  }
+
+  IntegerLiteral _readIntegerLiteralNull() {
+    var lexeme = _readStringReference();
+    return astFactory.integerLiteral(
+      TokenFactory.tokenFromTypeAndString(TokenType.INT, lexeme),
+      null,
+    );
+  }
+
+  IntegerLiteral _readIntegerLiteralPositive() {
+    var value = (_readUint32() << 32) | _readUint32();
+    return _createIntegerLiteral(value);
+  }
+
+  IntegerLiteral _readIntegerLiteralPositive1() {
+    var value = _readByte();
+    return _createIntegerLiteral(value);
+  }
+
+  InterpolationExpression _readInterpolationExpression() {
+    var flags = _readByte();
+    var expression = readNode() as Expression;
+    var isIdentifier = AstBinaryFlags.isStringInterpolationIdentifier(flags);
+    return astFactory.interpolationExpression(
+      isIdentifier
+          ? Tokens.OPEN_CURLY_BRACKET
+          : Tokens.STRING_INTERPOLATION_EXPRESSION,
       expression,
-    )..staticType = expression.staticType;
-  }
-
-  NativeClause _read_nativeClause(LinkedNode data) {
-    return astFactory.nativeClause(
-      _Tokens.NATIVE,
-      _readNode(data.nativeClause_name),
+      isIdentifier ? null : Tokens.CLOSE_CURLY_BRACKET,
     );
   }
 
-  NativeFunctionBody _read_nativeFunctionBody(LinkedNode data) {
-    return astFactory.nativeFunctionBody(
-      _Tokens.NATIVE,
-      _readNode(data.nativeFunctionBody_stringLiteral),
-      _Tokens.SEMICOLON,
+  InterpolationString _readInterpolationString() {
+    var value = _readStringReference();
+    return astFactory.interpolationString(
+      TokenFactory.tokenFromString(value),
+      value,
     );
   }
 
-  NullLiteral _read_nullLiteral(LinkedNode data) {
+  IsExpression _readIsExpression() {
+    var flags = _readByte();
+    var expression = readNode() as Expression;
+    var type = readNode() as TypeAnnotation;
+    return astFactory.isExpression(
+      expression,
+      Tokens.IS,
+      AstBinaryFlags.hasNot(flags) ? Tokens.BANG : null,
+      type,
+    );
+  }
+
+  LibraryDirective _readLibraryDirective() {
+    var documentationTokenIndexList = _readUint30List();
+    var name = readNode();
+    var keywordOffset = _readInformativeUint30();
+    var metadata = _readNodeList<Annotation>();
+
+    var node = astFactory.libraryDirective(
+      null,
+      metadata,
+      KeywordToken(Keyword.LIBRARY, keywordOffset),
+      name,
+      Tokens.SEMICOLON,
+    );
+    SummaryDataForLibraryDirective(
+      _unitReader,
+      node,
+      documentationTokenIndexList: documentationTokenIndexList,
+    );
+    return node;
+  }
+
+  LibraryIdentifier _readLibraryIdentifier() {
+    var components = _readNodeList<SimpleIdentifier>();
+    return astFactory.libraryIdentifier(
+      components,
+    );
+  }
+
+  ListLiteral _readListLiteral() {
+    var flags = _readByte();
+    var typeArguments = _readOptionalNode();
+    var elements = _readNodeList<CollectionElement>();
+
+    return astFactory.listLiteral(
+      AstBinaryFlags.isConst(flags) ? Tokens.CONST : null,
+      typeArguments,
+      Tokens.OPEN_SQUARE_BRACKET,
+      elements,
+      Tokens.CLOSE_SQUARE_BRACKET,
+    );
+  }
+
+  MapLiteralEntry _readMapLiteralEntry() {
+    var key = readNode() as Expression;
+    var value = readNode() as Expression;
+    return astFactory.mapLiteralEntry(key, Tokens.COLON, value);
+  }
+
+  MethodDeclaration _readMethodDeclaration() {
+    var flags = _readUInt30();
+
+    var codeOffset = _readInformativeUint30();
+    var codeLength = _readInformativeUint30();
+    var documentationTokenIndexList = _readUint30List();
+
+    var name = readNode() as SimpleIdentifier;
+    var typeParameters = _readOptionalNode() as TypeParameterList;
+    var returnType = _readOptionalNode() as TypeAnnotation;
+    var formalParameters = _readOptionalNode() as FormalParameterList;
+    var metadata = _readNodeList<Annotation>();
+    var body = _functionBodyForFlags(flags);
+
+    var node = astFactory.methodDeclaration(
+      null,
+      metadata,
+      AstBinaryFlags.isExternal(flags) ? Tokens.EXTERNAL : null,
+      AstBinaryFlags.isStatic(flags) ? Tokens.STATIC : null,
+      returnType,
+      Tokens.choose(
+        AstBinaryFlags.isGet(flags),
+        Tokens.GET,
+        AstBinaryFlags.isSet(flags),
+        Tokens.SET,
+      ),
+      AstBinaryFlags.isOperator(flags) ? Tokens.OPERATOR : null,
+      name,
+      typeParameters,
+      formalParameters,
+      body,
+    ) as MethodDeclarationImpl;
+
+    node.linkedContext = LinkedContext(
+      _unitReader,
+      node,
+      codeOffset: codeOffset,
+      codeLength: codeLength,
+      resolutionIndex: _readUInt30(),
+      documentationTokenIndexList: documentationTokenIndexList,
+    );
+
+    return node;
+  }
+
+  MethodInvocation _readMethodInvocation() {
+    var flags = _readByte();
+    var target = _readOptionalNode() as Expression;
+    var methodName = readNode() as SimpleIdentifier;
+    var typeArguments = _readOptionalNode() as TypeArgumentList;
+    var arguments = readNode() as ArgumentList;
+
+    return astFactory.methodInvocation(
+      target,
+      Tokens.choose(
+        AstBinaryFlags.hasPeriod(flags),
+        Tokens.PERIOD,
+        AstBinaryFlags.hasPeriod2(flags),
+        Tokens.PERIOD_PERIOD,
+      ),
+      methodName,
+      typeArguments,
+      arguments,
+    );
+  }
+
+  MixinDeclaration _readMixinDeclaration() {
+    var codeOffset = _readInformativeUint30();
+    var codeLength = _readInformativeUint30();
+    var documentationTokenIndexList = _readUint30List();
+
+    var typeParameters = _readOptionalNode() as TypeParameterList;
+    var onClause = _readOptionalNode() as OnClause;
+    var implementsClause = _readOptionalNode() as ImplementsClause;
+    var name = readNode() as SimpleIdentifier;
+    var metadata = _readNodeList<Annotation>();
+
+    var node = astFactory.mixinDeclaration(
+      null,
+      metadata,
+      Tokens.MIXIN,
+      name,
+      typeParameters,
+      onClause,
+      implementsClause,
+      Tokens.OPEN_CURLY_BRACKET,
+      const <ClassMember>[],
+      Tokens.CLOSE_CURLY_BRACKET,
+    ) as MixinDeclarationImpl;
+
+    node.linkedContext = LinkedContext(
+      _unitReader,
+      node,
+      codeOffset: codeOffset,
+      codeLength: codeLength,
+      resolutionIndex: _readUInt30(),
+      documentationTokenIndexList: documentationTokenIndexList,
+    );
+
+    return node;
+  }
+
+  NamedExpression _readNamedExpression() {
+    var name = _readStringReference();
+    var offset = _readInformativeUint30();
+    var nameNode = astFactory.label(
+      astFactory.simpleIdentifier(
+        StringToken(TokenType.STRING, name, offset),
+      ),
+      Tokens.COLON,
+    );
+
+    var expression = readNode() as Expression;
+    return astFactory.namedExpression(nameNode, expression);
+  }
+
+  NativeClause _readNativeClause() {
+    var name = readNode();
+    return astFactory.nativeClause(Tokens.NATIVE, name);
+  }
+
+  List<T> _readNodeList<T>() {
+    var length = _readUInt30();
+    // TODO(scheglov) This will not work for null safety, rewrite.
+    var result = List<T>.filled(length, null);
+    for (var i = 0; i < length; ++i) {
+      result[i] = readNode() as T;
+    }
+    return result;
+  }
+
+  NullLiteral _readNullLiteral() {
     return astFactory.nullLiteral(
-      _Tokens.NULL,
-    )..staticType = _nullType;
-  }
-
-  OnClause _read_onClause(LinkedNode data) {
-    return astFactory.onClause(
-      _Tokens.ON,
-      _readNodeList(data.onClause_superclassConstraints),
+      Tokens.NULL,
     );
   }
 
-  ParenthesizedExpression _read_parenthesizedExpression(LinkedNode data) {
+  OnClause _readOnClause() {
+    var superclassConstraints = _readNodeList<TypeName>();
+    return astFactory.onClause(Tokens.ON, superclassConstraints);
+  }
+
+  AstNode _readOptionalNode() {
+    if (_readOptionTag()) {
+      return readNode();
+    } else {
+      return null;
+    }
+  }
+
+  bool _readOptionTag() {
+    var tag = _readByte();
+    if (tag == Tag.Nothing) {
+      return false;
+    } else if (tag == Tag.Something) {
+      return true;
+    } else {
+      throw UnimplementedError('Unexpected option tag: $tag');
+    }
+  }
+
+  ParenthesizedExpression _readParenthesizedExpression() {
+    var expression = readNode() as Expression;
     return astFactory.parenthesizedExpression(
-      _Tokens.OPEN_PAREN,
-      _readNode(data.parenthesizedExpression_expression),
-      _Tokens.CLOSE_PAREN,
-    )..staticType = _readType(data.expression_type);
-  }
-
-  PartDirective _read_partDirective(LinkedNode data) {
-    timerAstBinaryReaderDirective.start();
-    _isReadingDirective = true;
-    try {
-      var node = astFactory.partDirective(
-        _readDocumentationComment(data),
-        _readNodeListLazy(data.annotatedNode_metadata),
-        _Tokens.PART,
-        _readNode(data.uriBasedDirective_uri),
-        _Tokens.SEMICOLON,
-      );
-      LazyDirective.setData(node, data);
-      return node;
-    } finally {
-      _isReadingDirective = false;
-      timerAstBinaryReaderDirective.stop();
-    }
-  }
-
-  PartOfDirective _read_partOfDirective(LinkedNode data) {
-    timerAstBinaryReaderDirective.start();
-    _isReadingDirective = true;
-    try {
-      var node = astFactory.partOfDirective(
-        _readDocumentationComment(data),
-        _readNodeListLazy(data.annotatedNode_metadata),
-        _Tokens.PART,
-        _Tokens.OF,
-        _readNode(data.partOfDirective_uri),
-        _readNode(data.partOfDirective_libraryName),
-        _Tokens.SEMICOLON,
-      );
-      LazyDirective.setData(node, data);
-      return node;
-    } finally {
-      _isReadingDirective = false;
-      timerAstBinaryReaderDirective.stop();
-    }
-  }
-
-  PostfixExpression _read_postfixExpression(LinkedNode data) {
-    return astFactory.postfixExpression(
-      _readNode(data.postfixExpression_operand),
-      _Tokens.fromType(data.postfixExpression_operator),
-    )
-      ..staticElement = _elementOfComponents(
-        data.postfixExpression_element,
-        data.postfixExpression_substitution,
-      )
-      ..staticType = _readType(data.expression_type);
-  }
-
-  PrefixedIdentifier _read_prefixedIdentifier(LinkedNode data) {
-    return astFactory.prefixedIdentifier(
-      _readNode(data.prefixedIdentifier_prefix),
-      _Tokens.PERIOD,
-      _readNode(data.prefixedIdentifier_identifier),
-    )..staticType = _readType(data.expression_type);
-  }
-
-  PrefixExpression _read_prefixExpression(LinkedNode data) {
-    return astFactory.prefixExpression(
-      _Tokens.fromType(data.prefixExpression_operator),
-      _readNode(data.prefixExpression_operand),
-    )
-      ..staticElement = _elementOfComponents(
-        data.prefixExpression_element,
-        data.prefixExpression_substitution,
-      )
-      ..staticType = _readType(data.expression_type);
-  }
-
-  PropertyAccess _read_propertyAccess(LinkedNode data) {
-    return astFactory.propertyAccess(
-      _readNode(data.propertyAccess_target),
-      _Tokens.fromType(data.propertyAccess_operator),
-      _readNode(data.propertyAccess_propertyName),
-    )..staticType = _readType(data.expression_type);
-  }
-
-  RedirectingConstructorInvocation _read_redirectingConstructorInvocation(
-      LinkedNode data) {
-    var hasThis = AstBinaryFlags.hasThis(data.flags);
-    return astFactory.redirectingConstructorInvocation(
-      hasThis ? _Tokens.THIS : null,
-      hasThis ? _Tokens.PERIOD : null,
-      _readNode(data.redirectingConstructorInvocation_constructorName),
-      _readNode(data.redirectingConstructorInvocation_arguments),
-    )..staticElement = _elementOfComponents(
-        data.redirectingConstructorInvocation_element,
-        data.redirectingConstructorInvocation_substitution,
-      );
-  }
-
-  RethrowExpression _read_rethrowExpression(LinkedNode data) {
-    return astFactory.rethrowExpression(
-      _Tokens.RETHROW,
-    )..staticType = _readType(data.expression_type);
-  }
-
-  ReturnStatement _read_returnStatement(LinkedNode data) {
-    return astFactory.returnStatement(
-      _Tokens.RETURN,
-      _readNode(data.returnStatement_expression),
-      _Tokens.SEMICOLON,
+      Tokens.OPEN_PAREN,
+      expression,
+      Tokens.CLOSE_PAREN,
     );
   }
 
-  SetOrMapLiteral _read_setOrMapLiteral(LinkedNode data) {
-    SetOrMapLiteralImpl node = astFactory.setOrMapLiteral(
-      constKeyword: AstBinaryFlags.isConst(data.flags) ? _Tokens.CONST : null,
-      elements: _readNodeList(data.setOrMapLiteral_elements),
-      leftBracket: _Tokens.OPEN_CURLY_BRACKET,
-      typeArguments: AstBinaryFlags.hasTypeArguments(data.flags)
-          ? astFactory.typeArgumentList(
-              _Tokens.LT,
-              _readNodeList(data.typedLiteral_typeArguments),
-              _Tokens.GT,
-            )
-          : null,
-      rightBracket: _Tokens.CLOSE_CURLY_BRACKET,
-    )..staticType = _readType(data.expression_type);
-    if (AstBinaryFlags.isMap(data.flags)) {
+  PartDirective _readPartDirective() {
+    var uri = readNode();
+    var keywordOffset = _readInformativeUint30();
+    var metadata = _readNodeList<Annotation>();
+
+    return astFactory.partDirective(
+      null,
+      metadata,
+      KeywordToken(Keyword.PART, keywordOffset),
+      uri,
+      Tokens.SEMICOLON,
+    );
+  }
+
+  PartOfDirective _readPartOfDirective() {
+    var libraryName = _readOptionalNode() as LibraryIdentifier;
+    var uri = _readOptionalNode() as StringLiteral;
+    var keywordOffset = _readInformativeUint30();
+    var metadata = _readNodeList<Annotation>();
+
+    return astFactory.partOfDirective(
+      null,
+      metadata,
+      KeywordToken(Keyword.PART, keywordOffset),
+      Tokens.OF,
+      uri,
+      libraryName,
+      Tokens.SEMICOLON,
+    );
+  }
+
+  PostfixExpression _readPostfixExpression() {
+    var operand = readNode() as Expression;
+    var operatorType = UnlinkedTokenType.values[_readByte()];
+    return astFactory.postfixExpression(
+      operand,
+      Tokens.fromType(operatorType),
+    );
+  }
+
+  PrefixedIdentifier _readPrefixedIdentifier() {
+    var prefix = readNode() as SimpleIdentifier;
+    var identifier = readNode() as SimpleIdentifier;
+    return astFactory.prefixedIdentifier(
+      prefix,
+      Tokens.PERIOD,
+      identifier,
+    );
+  }
+
+  PrefixExpression _readPrefixExpression() {
+    var operatorType = UnlinkedTokenType.values[_readByte()];
+    var operand = readNode() as Expression;
+    return astFactory.prefixExpression(
+      Tokens.fromType(operatorType),
+      operand,
+    );
+  }
+
+  PropertyAccess _readPropertyAccess() {
+    var flags = _readByte();
+    var target = _readOptionalNode() as Expression;
+    var propertyName = readNode() as SimpleIdentifier;
+    return astFactory.propertyAccess(
+      target,
+      Tokens.choose(
+        AstBinaryFlags.hasPeriod(flags),
+        Tokens.PERIOD,
+        AstBinaryFlags.hasPeriod2(flags),
+        Tokens.PERIOD_PERIOD,
+      ),
+      propertyName,
+    );
+  }
+
+  RedirectingConstructorInvocation _readRedirectingConstructorInvocation() {
+    var flags = _readByte();
+    var constructorName = _readOptionalNode() as SimpleIdentifier;
+    var argumentList = readNode() as ArgumentList;
+    var hasThis = AstBinaryFlags.hasThis(flags);
+    return astFactory.redirectingConstructorInvocation(
+      hasThis ? Tokens.THIS : null,
+      hasThis ? Tokens.PERIOD : null,
+      constructorName,
+      argumentList,
+    );
+  }
+
+  SetOrMapLiteral _readSetOrMapLiteral() {
+    var flags = _readByte();
+    var typeArguments = _readOptionalNode() as TypeArgumentList;
+    var elements = _readNodeList<CollectionElement>();
+    var node = astFactory.setOrMapLiteral(
+      constKeyword: AstBinaryFlags.isConst(flags) ? Tokens.CONST : null,
+      elements: elements,
+      leftBracket: Tokens.OPEN_CURLY_BRACKET,
+      typeArguments: typeArguments,
+      rightBracket: Tokens.CLOSE_CURLY_BRACKET,
+    ) as SetOrMapLiteralImpl;
+    if (AstBinaryFlags.isMap(flags)) {
       node.becomeMap();
-    } else if (AstBinaryFlags.isSet(data.flags)) {
+    } else if (AstBinaryFlags.isSet(flags)) {
       node.becomeSet();
     }
     return node;
   }
 
-  ShowCombinator _read_showCombinator(LinkedNode data) {
-    var node = astFactory.showCombinator(
-      _combinatorKeyword(data, Keyword.SHOW, _Tokens.SHOW),
-      data.names.map((name) => AstTestFactory.identifier3(name)).toList(),
+  ShowCombinator _readShowCombinator() {
+    var keywordOffset = _readInformativeUint30();
+    return astFactory.showCombinator(
+      KeywordToken(Keyword.SHOW, keywordOffset),
+      _readNodeList<SimpleIdentifier>(),
     );
-    LazyCombinator(node, data);
-    return node;
   }
 
-  SimpleFormalParameter _read_simpleFormalParameter(LinkedNode data) {
-    SimpleFormalParameterImpl node = astFactory.simpleFormalParameter2(
-      identifier: _declaredIdentifier(data),
-      type: _readNode(data.simpleFormalParameter_type),
+  SimpleFormalParameter _readSimpleFormalParameter() {
+    var type = _readOptionalNode() as TypeAnnotation;
+    var flags = _readByte();
+    var codeOffset = _readInformativeUint30();
+    var codeLength = _readInformativeUint30();
+    var metadata = _readNodeList<Annotation>();
+    var identifier =
+        AstBinaryFlags.hasName(flags) ? readNode() as SimpleIdentifier : null;
+
+    var node = astFactory.simpleFormalParameter2(
+      identifier: identifier,
+      type: type,
       covariantKeyword:
-          AstBinaryFlags.isCovariant(data.flags) ? _Tokens.COVARIANT : null,
-      comment: _readDocumentationComment(data),
-      metadata: _readNodeList(data.normalFormalParameter_metadata),
-      keyword: _Tokens.choose(
-        AstBinaryFlags.isConst(data.flags),
-        _Tokens.CONST,
-        AstBinaryFlags.isFinal(data.flags),
-        _Tokens.FINAL,
-        AstBinaryFlags.isVar(data.flags),
-        _Tokens.VAR,
+          AstBinaryFlags.isCovariant(flags) ? Tokens.COVARIANT : null,
+      comment: null,
+      metadata: metadata,
+      keyword: Tokens.choose(
+        AstBinaryFlags.isConst(flags),
+        Tokens.CONST,
+        AstBinaryFlags.isFinal(flags),
+        Tokens.FINAL,
+        AstBinaryFlags.isVar(flags),
+        Tokens.VAR,
       ),
       requiredKeyword:
-          AstBinaryFlags.isRequired(data.flags) ? _Tokens.REQUIRED : null,
+          AstBinaryFlags.isRequired(flags) ? Tokens.REQUIRED : null,
+    ) as SimpleFormalParameterImpl;
+    node.summaryData = SummaryDataForFormalParameter(
+      codeOffset: codeOffset,
+      codeLength: codeLength,
     );
-    LazyFormalParameter.setData(node, data);
-    LazyAst.setInheritsCovariant(node, data.inheritsCovariant);
     return node;
   }
 
-  SimpleIdentifier _read_simpleIdentifier(LinkedNode data) {
+  SimpleIdentifier _readSimpleIdentifier() {
+    var name = _readStringReference();
+    var offset = _readInformativeUint30();
     return astFactory.simpleIdentifier(
-      TokenFactory.tokenFromString(data.name),
-      isDeclaration: AstBinaryFlags.isDeclaration(data.flags),
-    )
-      ..staticElement = _elementOfComponents(
-        data.simpleIdentifier_element,
-        data.simpleIdentifier_substitution,
-      )
-      ..staticType = _readType(data.expression_type);
+      StringToken(TokenType.STRING, name, offset),
+    );
   }
 
-  SimpleStringLiteral _read_simpleStringLiteral(LinkedNode data) {
-    var node = AstTestFactory.string2(data.simpleStringLiteral_value);
-    if (!_isReadingDirective) {
-      node.staticType = _stringType;
-    }
-    return node;
+  SimpleStringLiteral _readSimpleStringLiteral() {
+    var lexeme = _readStringReference();
+    var value = _readStringReference();
+
+    return astFactory.simpleStringLiteral(
+      TokenFactory.tokenFromString(lexeme),
+      value,
+    );
   }
 
-  SpreadElement _read_spreadElement(LinkedNode data) {
+  SpreadElement _readSpreadElement() {
+    var flags = _readByte();
+    var expression = readNode() as Expression;
     return astFactory.spreadElement(
-      spreadOperator: _Tokens.fromType(data.spreadElement_spreadOperator),
-      expression: _readNode(data.spreadElement_expression),
+      spreadOperator: AstBinaryFlags.hasQuestion(flags)
+          ? Tokens.PERIOD_PERIOD_PERIOD_QUESTION
+          : Tokens.PERIOD_PERIOD_PERIOD,
+      expression: expression,
     );
   }
 
-  StringInterpolation _read_stringInterpolation(LinkedNode data) {
-    var node = astFactory.stringInterpolation(
-      _readNodeList(data.stringInterpolation_elements),
-    );
-    if (!_isReadingDirective) {
-      node.staticType = _stringType;
-    }
-    return node;
+  StringInterpolation _readStringInterpolation() {
+    var elements = _readNodeList<InterpolationElement>();
+    return astFactory.stringInterpolation(elements);
   }
 
-  SuperConstructorInvocation _read_superConstructorInvocation(LinkedNode data) {
+  String _readStringReference() {
+    return _unitReader.astReader.readStringReference();
+  }
+
+  SuperConstructorInvocation _readSuperConstructorInvocation() {
+    var constructorName = _readOptionalNode() as SimpleIdentifier;
+    var argumentList = readNode() as ArgumentList;
     return astFactory.superConstructorInvocation(
-      _Tokens.SUPER,
-      _Tokens.PERIOD,
-      _readNode(data.superConstructorInvocation_constructorName),
-      _readNode(data.superConstructorInvocation_arguments),
-    )..staticElement = _elementOfComponents(
-        data.superConstructorInvocation_element,
-        data.superConstructorInvocation_substitution,
-      );
-  }
-
-  SuperExpression _read_superExpression(LinkedNode data) {
-    return astFactory.superExpression(
-      _Tokens.SUPER,
-    )..staticType = _readType(data.expression_type);
-  }
-
-  SwitchCase _read_switchCase(LinkedNode data) {
-    return astFactory.switchCase(
-      _readNodeList(data.switchMember_labels),
-      _Tokens.CASE,
-      _readNode(data.switchCase_expression),
-      _Tokens.COLON,
-      _readNodeList(data.switchMember_statements),
+      Tokens.SUPER,
+      Tokens.PERIOD,
+      constructorName,
+      argumentList,
     );
   }
 
-  SwitchDefault _read_switchDefault(LinkedNode data) {
-    return astFactory.switchDefault(
-      _readNodeList(data.switchMember_labels),
-      _Tokens.DEFAULT,
-      _Tokens.COLON,
-      _readNodeList(data.switchMember_statements),
-    );
+  SuperExpression _readSuperExpression() {
+    return astFactory.superExpression(Tokens.SUPER);
   }
 
-  SwitchStatement _read_switchStatement(LinkedNode data) {
-    return astFactory.switchStatement(
-      _Tokens.SWITCH,
-      _Tokens.OPEN_PAREN,
-      _readNode(data.switchStatement_expression),
-      _Tokens.CLOSE_PAREN,
-      _Tokens.OPEN_CURLY_BRACKET,
-      _readNodeList(data.switchStatement_members),
-      _Tokens.CLOSE_CURLY_BRACKET,
-    );
-  }
-
-  SymbolLiteral _read_symbolLiteral(LinkedNode data) {
-    return astFactory.symbolLiteral(
-      _Tokens.HASH,
-      data.names.map((lexeme) => TokenFactory.tokenFromString(lexeme)).toList(),
-    )..staticType = _readType(data.expression_type);
-  }
-
-  ThisExpression _read_thisExpression(LinkedNode data) {
-    return astFactory.thisExpression(
-      _Tokens.THIS,
-    )..staticType = _readType(data.expression_type);
-  }
-
-  ThrowExpression _read_throwExpression(LinkedNode data) {
-    return astFactory.throwExpression(
-      _Tokens.THROW,
-      _readNode(data.throwExpression_expression),
-    )..staticType = _readType(data.expression_type);
-  }
-
-  TopLevelVariableDeclaration _read_topLevelVariableDeclaration(
-      LinkedNode data) {
-    timerAstBinaryReaderTopLevelVar.start();
-    try {
-      var node = astFactory.topLevelVariableDeclaration(
-        _readDocumentationComment(data),
-        _readNodeListLazy(data.annotatedNode_metadata),
-        _readNode(data.topLevelVariableDeclaration_variableList),
-        _Tokens.SEMICOLON,
-        externalKeyword:
-            AstBinaryFlags.isExternal(data.flags) ? _Tokens.EXTERNAL : null,
-      );
-      LazyTopLevelVariableDeclaration.setData(node, data);
-      return node;
-    } finally {
-      timerAstBinaryReaderTopLevelVar.stop();
+  SymbolLiteral _readSymbolLiteral() {
+    var components = <Token>[];
+    var length = _readUInt30();
+    for (var i = 0; i < length; i++) {
+      var lexeme = _readStringReference();
+      var token = TokenFactory.tokenFromString(lexeme);
+      components.add(token);
     }
+    return astFactory.symbolLiteral(Tokens.HASH, components);
   }
 
-  TryStatement _read_tryStatement(LinkedNode data) {
-    return astFactory.tryStatement(
-      _Tokens.TRY,
-      _readNode(data.tryStatement_body),
-      _readNodeList(data.tryStatement_catchClauses),
-      _Tokens.FINALLY,
-      _readNode(data.tryStatement_finallyBlock),
+  ThisExpression _readThisExpression() {
+    return astFactory.thisExpression(Tokens.THIS);
+  }
+
+  ThrowExpression _readThrowExpression() {
+    var expression = readNode() as Expression;
+    return astFactory.throwExpression(Tokens.THROW, expression);
+  }
+
+  TopLevelVariableDeclaration _readTopLevelVariableDeclaration() {
+    var flags = _readByte();
+    var codeOffsetLengthList = _readInformativeUint30List();
+    var documentationTokenIndexList = _readUint30List();
+    var variableList = readNode() as VariableDeclarationList;
+    var metadata = _readNodeList<Annotation>();
+
+    var node = astFactory.topLevelVariableDeclaration(
+      null,
+      metadata,
+      variableList,
+      Tokens.SEMICOLON,
+      externalKeyword:
+          AstBinaryFlags.isExternal(flags) ? Tokens.EXTERNAL : null,
+    ) as TopLevelVariableDeclarationImpl;
+
+    node.linkedContext = LinkedContext(
+      _unitReader,
+      node,
+      codeOffset: -1,
+      codeLength: 0,
+      codeOffsetLengthList: codeOffsetLengthList,
+      resolutionIndex: _readUInt30(),
+      documentationTokenIndexList: documentationTokenIndexList,
     );
+
+    return node;
   }
 
-  TypeArgumentList _read_typeArgumentList(LinkedNode data) {
-    return astFactory.typeArgumentList(
-      _Tokens.LT,
-      _readNodeList(data.typeArgumentList_arguments),
-      _Tokens.GT,
-    );
+  TypeArgumentList _readTypeArgumentList() {
+    var arguments = _readNodeList<TypeAnnotation>();
+    return astFactory.typeArgumentList(Tokens.LT, arguments, Tokens.GT);
   }
 
-  TypeName _read_typeName(LinkedNode data) {
+  TypeName _readTypeName() {
+    var flags = _readByte();
+    var name = readNode() as Identifier;
+    var typeArguments = _readOptionalNode() as TypeArgumentList;
+
     return astFactory.typeName(
-      _readNode(data.typeName_name),
-      AstBinaryFlags.hasTypeArguments(data.flags)
-          ? astFactory.typeArgumentList(
-              _Tokens.LT,
-              _readNodeList(data.typeName_typeArguments),
-              _Tokens.GT,
-            )
-          : null,
-      question:
-          AstBinaryFlags.hasQuestion(data.flags) ? _Tokens.QUESTION : null,
-    )..type = _readType(data.typeName_type);
+      name,
+      typeArguments,
+      question: AstBinaryFlags.hasQuestion(flags) ? Tokens.QUESTION : null,
+    );
   }
 
-  TypeParameter _read_typeParameter(LinkedNode data) {
-    // TODO (kallentu) : Clean up AstFactoryImpl casting once variance is
-    // added to the interface.
-    var node = (astFactory as AstFactoryImpl).typeParameter2(
-      comment: _readDocumentationComment(data),
-      metadata: _readNodeListLazy(data.annotatedNode_metadata),
-      name: _declaredIdentifier(data),
-      extendsKeyword: _Tokens.EXTENDS,
-      bound: _readNodeLazy(data.typeParameter_bound),
+  TypeParameter _readTypeParameter() {
+    var codeOffset = _readInformativeUint30();
+    var codeLength = _readInformativeUint30();
+    var name = readNode() as Identifier;
+    var bound = _readOptionalNode() as TypeAnnotation;
+    var metadata = _readNodeList<Annotation>();
+
+    var node = astFactory.typeParameter(
+      null,
+      metadata,
+      name,
+      bound != null ? Tokens.EXTENDS : null,
+      bound,
+    ) as TypeParameterImpl;
+    node.summaryData = SummaryDataForTypeParameter(
+      codeOffset: codeOffset,
+      codeLength: codeLength,
     );
-    LazyAst.setVariance(node, _decodeVariance(data.typeParameter_variance));
-    LazyTypeParameter.setData(node, data);
+
     return node;
   }
 
-  TypeParameterList _read_typeParameterList(LinkedNode data) {
+  TypeParameterList _readTypeParameterList() {
+    var typeParameters = _readNodeList<TypeParameter>();
     return astFactory.typeParameterList(
-      _Tokens.LT,
-      _readNodeList(data.typeParameterList_typeParameters),
-      _Tokens.GT,
+      Tokens.LT,
+      typeParameters,
+      Tokens.GT,
     );
   }
 
-  VariableDeclaration _read_variableDeclaration(LinkedNode data) {
-    var node = astFactory.variableDeclaration(
-      _declaredIdentifier(data),
-      _Tokens.EQ,
-      _readNodeLazy(data.variableDeclaration_initializer),
-    );
-    LazyVariableDeclaration.setData(node, data);
-    LazyAst.setInheritsCovariant(node, data.inheritsCovariant);
-    return node;
-  }
-
-  VariableDeclarationList _read_variableDeclarationList(LinkedNode data) {
-    var node = astFactory.variableDeclarationList2(
-      comment: _readDocumentationComment(data),
-      keyword: _Tokens.choose(
-        AstBinaryFlags.isConst(data.flags),
-        _Tokens.CONST,
-        AstBinaryFlags.isFinal(data.flags),
-        _Tokens.FINAL,
-        AstBinaryFlags.isVar(data.flags),
-        _Tokens.VAR,
-      ),
-      lateKeyword: AstBinaryFlags.isLate(data.flags) ? _Tokens.LATE : null,
-      metadata: _readNodeListLazy(data.annotatedNode_metadata),
-      type: _readNodeLazy(data.variableDeclarationList_type),
-      variables: _readNodeList(data.variableDeclarationList_variables),
-    );
-    LazyVariableDeclarationList.setData(node, data);
-    return node;
-  }
-
-  VariableDeclarationStatement _read_variableDeclarationStatement(
-      LinkedNode data) {
-    return astFactory.variableDeclarationStatement(
-      _readNode(data.variableDeclarationStatement_variables),
-      _Tokens.SEMICOLON,
-    );
-  }
-
-  WhileStatement _read_whileStatement(LinkedNode data) {
-    return astFactory.whileStatement(
-      _Tokens.WHILE,
-      _Tokens.OPEN_PAREN,
-      _readNode(data.whileStatement_condition),
-      _Tokens.CLOSE_PAREN,
-      _readNode(data.whileStatement_body),
-    );
-  }
-
-  WithClause _read_withClause(LinkedNode data) {
-    return astFactory.withClause(
-      _Tokens.WITH,
-      _readNodeList(data.withClause_mixinTypes),
-    );
-  }
-
-  YieldStatement _read_yieldStatement(LinkedNode data) {
-    return astFactory.yieldStatement(
-      _Tokens.YIELD,
-      AstBinaryFlags.isStar(data.flags) ? _Tokens.STAR : null,
-      _readNode(data.yieldStatement_expression),
-      _Tokens.SEMICOLON,
-    );
-  }
-
-  Comment _readDocumentationComment(LinkedNode data) {
-    return null;
-  }
-
-  AstNode _readNode(LinkedNode data) {
-    if (data == null) return null;
-
-    switch (data.kind) {
-      case LinkedNodeKind.adjacentStrings:
-        return _read_adjacentStrings(data);
-      case LinkedNodeKind.annotation:
-        return _read_annotation(data);
-      case LinkedNodeKind.argumentList:
-        return _read_argumentList(data);
-      case LinkedNodeKind.asExpression:
-        return _read_asExpression(data);
-      case LinkedNodeKind.assertInitializer:
-        return _read_assertInitializer(data);
-      case LinkedNodeKind.assertStatement:
-        return _read_assertStatement(data);
-      case LinkedNodeKind.assignmentExpression:
-        return _read_assignmentExpression(data);
-      case LinkedNodeKind.awaitExpression:
-        return _read_awaitExpression(data);
-      case LinkedNodeKind.binaryExpression:
-        return _read_binaryExpression(data);
-      case LinkedNodeKind.block:
-        return _read_block(data);
-      case LinkedNodeKind.blockFunctionBody:
-        return _read_blockFunctionBody(data);
-      case LinkedNodeKind.booleanLiteral:
-        return _read_booleanLiteral(data);
-      case LinkedNodeKind.breakStatement:
-        return _read_breakStatement(data);
-      case LinkedNodeKind.cascadeExpression:
-        return _read_cascadeExpression(data);
-      case LinkedNodeKind.catchClause:
-        return _read_catchClause(data);
-      case LinkedNodeKind.classDeclaration:
-        return _read_classDeclaration(data);
-      case LinkedNodeKind.classTypeAlias:
-        return _read_classTypeAlias(data);
-      case LinkedNodeKind.comment:
-        return _read_comment(data);
-      case LinkedNodeKind.commentReference:
-        return _read_commentReference(data);
-      case LinkedNodeKind.compilationUnit:
-        return _read_compilationUnit(data);
-      case LinkedNodeKind.conditionalExpression:
-        return _read_conditionalExpression(data);
-      case LinkedNodeKind.configuration:
-        return _read_configuration(data);
-      case LinkedNodeKind.constructorDeclaration:
-        return _read_constructorDeclaration(data);
-      case LinkedNodeKind.constructorFieldInitializer:
-        return _read_constructorFieldInitializer(data);
-      case LinkedNodeKind.constructorName:
-        return _read_constructorName(data);
-      case LinkedNodeKind.continueStatement:
-        return _read_continueStatement(data);
-      case LinkedNodeKind.declaredIdentifier:
-        return _read_declaredIdentifier(data);
-      case LinkedNodeKind.defaultFormalParameter:
-        return _read_defaultFormalParameter(data);
-      case LinkedNodeKind.doStatement:
-        return _read_doStatement(data);
-      case LinkedNodeKind.dottedName:
-        return _read_dottedName(data);
-      case LinkedNodeKind.doubleLiteral:
-        return _read_doubleLiteral(data);
-      case LinkedNodeKind.emptyFunctionBody:
-        return _read_emptyFunctionBody(data);
-      case LinkedNodeKind.emptyStatement:
-        return _read_emptyStatement(data);
-      case LinkedNodeKind.enumConstantDeclaration:
-        return _read_enumConstantDeclaration(data);
-      case LinkedNodeKind.enumDeclaration:
-        return _read_enumDeclaration(data);
-      case LinkedNodeKind.exportDirective:
-        return _read_exportDirective(data);
-      case LinkedNodeKind.expressionFunctionBody:
-        return _read_expressionFunctionBody(data);
-      case LinkedNodeKind.expressionStatement:
-        return _read_expressionStatement(data);
-      case LinkedNodeKind.extendsClause:
-        return _read_extendsClause(data);
-      case LinkedNodeKind.extensionDeclaration:
-        return _read_extensionDeclaration(data);
-      case LinkedNodeKind.extensionOverride:
-        return _read_extensionOverride(data);
-      case LinkedNodeKind.fieldDeclaration:
-        return _read_fieldDeclaration(data);
-      case LinkedNodeKind.fieldFormalParameter:
-        return _read_fieldFormalParameter(data);
-      case LinkedNodeKind.forEachPartsWithDeclaration:
-        return _read_forEachPartsWithDeclaration(data);
-      case LinkedNodeKind.forEachPartsWithIdentifier:
-        return _read_forEachPartsWithIdentifier(data);
-      case LinkedNodeKind.forElement:
-        return _read_forElement(data);
-      case LinkedNodeKind.forPartsWithExpression:
-        return _read_forPartsWithExpression(data);
-      case LinkedNodeKind.forPartsWithDeclarations:
-        return _read_forPartsWithDeclarations(data);
-      case LinkedNodeKind.forStatement:
-        return _read_forStatement(data);
-      case LinkedNodeKind.formalParameterList:
-        return _read_formalParameterList(data);
-      case LinkedNodeKind.functionDeclaration:
-        return _read_functionDeclaration(data);
-      case LinkedNodeKind.functionDeclarationStatement:
-        return _read_functionDeclarationStatement(data);
-      case LinkedNodeKind.functionExpression:
-        return _read_functionExpression(data);
-      case LinkedNodeKind.functionExpressionInvocation:
-        return _read_functionExpressionInvocation(data);
-      case LinkedNodeKind.functionTypeAlias:
-        return _read_functionTypeAlias(data);
-      case LinkedNodeKind.functionTypedFormalParameter:
-        return _read_functionTypedFormalParameter(data);
-      case LinkedNodeKind.genericFunctionType:
-        return _read_genericFunctionType(data);
-      case LinkedNodeKind.genericTypeAlias:
-        return _read_genericTypeAlias(data);
-      case LinkedNodeKind.hideCombinator:
-        return _read_hideCombinator(data);
-      case LinkedNodeKind.ifElement:
-        return _read_ifElement(data);
-      case LinkedNodeKind.ifStatement:
-        return _read_ifStatement(data);
-      case LinkedNodeKind.implementsClause:
-        return _read_implementsClause(data);
-      case LinkedNodeKind.importDirective:
-        return _read_importDirective(data);
-      case LinkedNodeKind.indexExpression:
-        return _read_indexExpression(data);
-      case LinkedNodeKind.instanceCreationExpression:
-        return _read_instanceCreationExpression(data);
-      case LinkedNodeKind.integerLiteral:
-        return _read_integerLiteral(data);
-      case LinkedNodeKind.interpolationString:
-        return _read_interpolationString(data);
-      case LinkedNodeKind.interpolationExpression:
-        return _read_interpolationExpression(data);
-      case LinkedNodeKind.isExpression:
-        return _read_isExpression(data);
-      case LinkedNodeKind.label:
-        return _read_label(data);
-      case LinkedNodeKind.labeledStatement:
-        return _read_labeledStatement(data);
-      case LinkedNodeKind.libraryDirective:
-        return _read_libraryDirective(data);
-      case LinkedNodeKind.libraryIdentifier:
-        return _read_libraryIdentifier(data);
-      case LinkedNodeKind.listLiteral:
-        return _read_listLiteral(data);
-      case LinkedNodeKind.mapLiteralEntry:
-        return _read_mapLiteralEntry(data);
-      case LinkedNodeKind.methodDeclaration:
-        return _read_methodDeclaration(data);
-      case LinkedNodeKind.methodInvocation:
-        return _read_methodInvocation(data);
-      case LinkedNodeKind.mixinDeclaration:
-        return _read_mixinDeclaration(data);
-      case LinkedNodeKind.namedExpression:
-        return _read_namedExpression(data);
-      case LinkedNodeKind.nativeClause:
-        return _read_nativeClause(data);
-      case LinkedNodeKind.nativeFunctionBody:
-        return _read_nativeFunctionBody(data);
-      case LinkedNodeKind.nullLiteral:
-        return _read_nullLiteral(data);
-      case LinkedNodeKind.onClause:
-        return _read_onClause(data);
-      case LinkedNodeKind.parenthesizedExpression:
-        return _read_parenthesizedExpression(data);
-      case LinkedNodeKind.partDirective:
-        return _read_partDirective(data);
-      case LinkedNodeKind.partOfDirective:
-        return _read_partOfDirective(data);
-      case LinkedNodeKind.postfixExpression:
-        return _read_postfixExpression(data);
-      case LinkedNodeKind.prefixExpression:
-        return _read_prefixExpression(data);
-      case LinkedNodeKind.propertyAccess:
-        return _read_propertyAccess(data);
-      case LinkedNodeKind.prefixedIdentifier:
-        return _read_prefixedIdentifier(data);
-      case LinkedNodeKind.redirectingConstructorInvocation:
-        return _read_redirectingConstructorInvocation(data);
-      case LinkedNodeKind.rethrowExpression:
-        return _read_rethrowExpression(data);
-      case LinkedNodeKind.returnStatement:
-        return _read_returnStatement(data);
-      case LinkedNodeKind.setOrMapLiteral:
-        return _read_setOrMapLiteral(data);
-      case LinkedNodeKind.showCombinator:
-        return _read_showCombinator(data);
-      case LinkedNodeKind.simpleFormalParameter:
-        return _read_simpleFormalParameter(data);
-      case LinkedNodeKind.simpleIdentifier:
-        return _read_simpleIdentifier(data);
-      case LinkedNodeKind.simpleStringLiteral:
-        return _read_simpleStringLiteral(data);
-      case LinkedNodeKind.spreadElement:
-        return _read_spreadElement(data);
-      case LinkedNodeKind.stringInterpolation:
-        return _read_stringInterpolation(data);
-      case LinkedNodeKind.superConstructorInvocation:
-        return _read_superConstructorInvocation(data);
-      case LinkedNodeKind.superExpression:
-        return _read_superExpression(data);
-      case LinkedNodeKind.switchCase:
-        return _read_switchCase(data);
-      case LinkedNodeKind.switchDefault:
-        return _read_switchDefault(data);
-      case LinkedNodeKind.switchStatement:
-        return _read_switchStatement(data);
-      case LinkedNodeKind.symbolLiteral:
-        return _read_symbolLiteral(data);
-      case LinkedNodeKind.thisExpression:
-        return _read_thisExpression(data);
-      case LinkedNodeKind.throwExpression:
-        return _read_throwExpression(data);
-      case LinkedNodeKind.topLevelVariableDeclaration:
-        return _read_topLevelVariableDeclaration(data);
-      case LinkedNodeKind.tryStatement:
-        return _read_tryStatement(data);
-      case LinkedNodeKind.typeArgumentList:
-        return _read_typeArgumentList(data);
-      case LinkedNodeKind.typeName:
-        return _read_typeName(data);
-      case LinkedNodeKind.typeParameter:
-        return _read_typeParameter(data);
-      case LinkedNodeKind.typeParameterList:
-        return _read_typeParameterList(data);
-      case LinkedNodeKind.variableDeclaration:
-        return _read_variableDeclaration(data);
-      case LinkedNodeKind.variableDeclarationList:
-        return _read_variableDeclarationList(data);
-      case LinkedNodeKind.variableDeclarationStatement:
-        return _read_variableDeclarationStatement(data);
-      case LinkedNodeKind.whileStatement:
-        return _read_whileStatement(data);
-      case LinkedNodeKind.withClause:
-        return _read_withClause(data);
-      case LinkedNodeKind.yieldStatement:
-        return _read_yieldStatement(data);
-      default:
-        throw UnimplementedError('Expression kind: ${data.kind}');
+  int _readUInt30() {
+    var byte = _readByte();
+    if (byte & 0x80 == 0) {
+      // 0xxxxxxx
+      return byte;
+    } else if (byte & 0x40 == 0) {
+      // 10xxxxxx
+      return ((byte & 0x3F) << 8) | _readByte();
+    } else {
+      // 11xxxxxx
+      return ((byte & 0x3F) << 24) |
+          (_readByte() << 16) |
+          (_readByte() << 8) |
+          _readByte();
     }
   }
 
-  AstNode _readNodeLazy(LinkedNode data) {
-    if (isLazy) return null;
-    return _readNode(data);
-  }
-
-  List<T> _readNodeList<T>(List<LinkedNode> nodeList) {
-    var result = List<T>.filled(nodeList.length, null);
-    for (var i = 0; i < nodeList.length; ++i) {
-      var linkedNode = nodeList[i];
-      result[i] = _readNode(linkedNode) as T;
+  Uint32List _readUint30List() {
+    var length = _readUInt30();
+    var result = Uint32List(length);
+    for (var i = 0; i < length; ++i) {
+      result[i] = _readUInt30();
     }
     return result;
   }
 
-  List<T> _readNodeListLazy<T>(List<LinkedNode> nodeList) {
-    if (isLazy) {
-      return List<T>.filled(nodeList.length, null);
-    }
-    return _readNodeList(nodeList);
+  int _readUint32() {
+    return (_readByte() << 24) |
+        (_readByte() << 16) |
+        (_readByte() << 8) |
+        _readByte();
   }
 
-  DartType _readType(LinkedNodeType data) {
-    return _unitContext.readType(data);
+  VariableDeclaration _readVariableDeclaration() {
+    var flags = _readByte();
+    var name = readNode() as SimpleIdentifier;
+    var initializer = _readOptionalNode() as Expression;
+
+    var node = astFactory.variableDeclaration(
+      name,
+      Tokens.EQ,
+      initializer,
+    ) as VariableDeclarationImpl;
+
+    node.hasInitializer = AstBinaryFlags.hasInitializer(flags);
+
+    return node;
   }
 
-  static Variance _decodeVariance(int encoding) {
-    if (encoding == 0) {
-      return null;
-    } else if (encoding == 1) {
-      return Variance.unrelated;
-    } else if (encoding == 2) {
-      return Variance.covariant;
-    } else if (encoding == 3) {
-      return Variance.contravariant;
-    } else if (encoding == 4) {
-      return Variance.invariant;
-    } else {
-      throw UnimplementedError('encoding: $encoding');
-    }
-  }
+  VariableDeclarationList _readVariableDeclarationList() {
+    var flags = _readByte();
+    var type = _readOptionalNode() as TypeAnnotation;
+    var variables = _readNodeList<VariableDeclaration>();
+    var metadata = _readNodeList<Annotation>();
 
-  static ParameterKind _toParameterKind(LinkedNodeFormalParameterKind kind) {
-    switch (kind) {
-      case LinkedNodeFormalParameterKind.requiredPositional:
-        return ParameterKind.REQUIRED;
-      case LinkedNodeFormalParameterKind.requiredNamed:
-        return ParameterKind.NAMED_REQUIRED;
-        break;
-      case LinkedNodeFormalParameterKind.optionalPositional:
-        return ParameterKind.POSITIONAL;
-        break;
-      case LinkedNodeFormalParameterKind.optionalNamed:
-        return ParameterKind.NAMED;
-      default:
-        throw StateError('Unexpected: $kind');
-    }
-  }
-}
-
-class _Tokens {
-  static final ABSTRACT = TokenFactory.tokenFromKeyword(Keyword.ABSTRACT);
-  static final ARROW = TokenFactory.tokenFromType(TokenType.FUNCTION);
-  static final AS = TokenFactory.tokenFromKeyword(Keyword.AS);
-  static final ASSERT = TokenFactory.tokenFromKeyword(Keyword.ASSERT);
-  static final AT = TokenFactory.tokenFromType(TokenType.AT);
-  static final ASYNC = TokenFactory.tokenFromKeyword(Keyword.ASYNC);
-  static final AWAIT = TokenFactory.tokenFromKeyword(Keyword.AWAIT);
-  static final BANG = TokenFactory.tokenFromType(TokenType.BANG);
-  static final BREAK = TokenFactory.tokenFromKeyword(Keyword.BREAK);
-  static final CASE = TokenFactory.tokenFromKeyword(Keyword.CASE);
-  static final CATCH = TokenFactory.tokenFromKeyword(Keyword.CATCH);
-  static final CLASS = TokenFactory.tokenFromKeyword(Keyword.CLASS);
-  static final CLOSE_CURLY_BRACKET =
-      TokenFactory.tokenFromType(TokenType.CLOSE_CURLY_BRACKET);
-  static final CLOSE_PAREN = TokenFactory.tokenFromType(TokenType.CLOSE_PAREN);
-  static final CLOSE_SQUARE_BRACKET =
-      TokenFactory.tokenFromType(TokenType.CLOSE_SQUARE_BRACKET);
-  static final COLON = TokenFactory.tokenFromType(TokenType.COLON);
-  static final COMMA = TokenFactory.tokenFromType(TokenType.COMMA);
-  static final CONST = TokenFactory.tokenFromKeyword(Keyword.CONST);
-  static final CONTINUE = TokenFactory.tokenFromKeyword(Keyword.CONTINUE);
-  static final COVARIANT = TokenFactory.tokenFromKeyword(Keyword.COVARIANT);
-  static final DEFERRED = TokenFactory.tokenFromKeyword(Keyword.DEFERRED);
-  static final ELSE = TokenFactory.tokenFromKeyword(Keyword.ELSE);
-  static final EXTERNAL = TokenFactory.tokenFromKeyword(Keyword.EXTERNAL);
-  static final FACTORY = TokenFactory.tokenFromKeyword(Keyword.FACTORY);
-  static final DEFAULT = TokenFactory.tokenFromKeyword(Keyword.DEFAULT);
-  static final DO = TokenFactory.tokenFromKeyword(Keyword.DO);
-  static final ENUM = TokenFactory.tokenFromKeyword(Keyword.ENUM);
-  static final EQ = TokenFactory.tokenFromType(TokenType.EQ);
-  static final EXPORT = TokenFactory.tokenFromKeyword(Keyword.EXPORT);
-  static final EXTENDS = TokenFactory.tokenFromKeyword(Keyword.EXTENDS);
-  static final EXTENSION = TokenFactory.tokenFromKeyword(Keyword.EXTENSION);
-  static final FINAL = TokenFactory.tokenFromKeyword(Keyword.FINAL);
-  static final FINALLY = TokenFactory.tokenFromKeyword(Keyword.FINALLY);
-  static final FOR = TokenFactory.tokenFromKeyword(Keyword.FOR);
-  static final FUNCTION = TokenFactory.tokenFromKeyword(Keyword.FUNCTION);
-  static final GET = TokenFactory.tokenFromKeyword(Keyword.GET);
-  static final GT = TokenFactory.tokenFromType(TokenType.GT);
-  static final HASH = TokenFactory.tokenFromType(TokenType.HASH);
-  static final HIDE = TokenFactory.tokenFromKeyword(Keyword.HIDE);
-  static final IF = TokenFactory.tokenFromKeyword(Keyword.IF);
-  static final IMPLEMENTS = TokenFactory.tokenFromKeyword(Keyword.IMPORT);
-  static final IMPORT = TokenFactory.tokenFromKeyword(Keyword.IMPLEMENTS);
-  static final IN = TokenFactory.tokenFromKeyword(Keyword.IN);
-  static final IS = TokenFactory.tokenFromKeyword(Keyword.IS);
-  static final LATE = TokenFactory.tokenFromKeyword(Keyword.LATE);
-  static final LIBRARY = TokenFactory.tokenFromKeyword(Keyword.LIBRARY);
-  static final LT = TokenFactory.tokenFromType(TokenType.LT);
-  static final MIXIN = TokenFactory.tokenFromKeyword(Keyword.MIXIN);
-  static final NATIVE = TokenFactory.tokenFromKeyword(Keyword.NATIVE);
-  static final NEW = TokenFactory.tokenFromKeyword(Keyword.NEW);
-  static final NULL = TokenFactory.tokenFromKeyword(Keyword.NULL);
-  static final OF = TokenFactory.tokenFromKeyword(Keyword.OF);
-  static final ON = TokenFactory.tokenFromKeyword(Keyword.ON);
-  static final OPEN_CURLY_BRACKET =
-      TokenFactory.tokenFromType(TokenType.OPEN_CURLY_BRACKET);
-  static final OPEN_PAREN = TokenFactory.tokenFromType(TokenType.OPEN_PAREN);
-  static final OPEN_SQUARE_BRACKET =
-      TokenFactory.tokenFromType(TokenType.OPEN_SQUARE_BRACKET);
-  static final OPERATOR = TokenFactory.tokenFromKeyword(Keyword.OPERATOR);
-  static final PART = TokenFactory.tokenFromKeyword(Keyword.PART);
-  static final PERIOD = TokenFactory.tokenFromType(TokenType.PERIOD);
-  static final PERIOD_PERIOD =
-      TokenFactory.tokenFromType(TokenType.PERIOD_PERIOD);
-  static final QUESTION = TokenFactory.tokenFromType(TokenType.QUESTION);
-  static final REQUIRED = TokenFactory.tokenFromKeyword(Keyword.REQUIRED);
-  static final RETHROW = TokenFactory.tokenFromKeyword(Keyword.RETHROW);
-  static final RETURN = TokenFactory.tokenFromKeyword(Keyword.RETURN);
-  static final SEMICOLON = TokenFactory.tokenFromType(TokenType.SEMICOLON);
-  static final SET = TokenFactory.tokenFromKeyword(Keyword.SET);
-  static final SHOW = TokenFactory.tokenFromKeyword(Keyword.SHOW);
-  static final STAR = TokenFactory.tokenFromType(TokenType.STAR);
-  static final STATIC = TokenFactory.tokenFromKeyword(Keyword.STATIC);
-  static final STRING_INTERPOLATION_EXPRESSION =
-      TokenFactory.tokenFromType(TokenType.STRING_INTERPOLATION_EXPRESSION);
-  static final SUPER = TokenFactory.tokenFromKeyword(Keyword.SUPER);
-  static final SWITCH = TokenFactory.tokenFromKeyword(Keyword.SWITCH);
-  static final SYNC = TokenFactory.tokenFromKeyword(Keyword.SYNC);
-  static final THIS = TokenFactory.tokenFromKeyword(Keyword.THIS);
-  static final THROW = TokenFactory.tokenFromKeyword(Keyword.THROW);
-  static final TRY = TokenFactory.tokenFromKeyword(Keyword.TRY);
-  static final TYPEDEF = TokenFactory.tokenFromKeyword(Keyword.TYPEDEF);
-  static final VAR = TokenFactory.tokenFromKeyword(Keyword.VAR);
-  static final WITH = TokenFactory.tokenFromKeyword(Keyword.WITH);
-  static final WHILE = TokenFactory.tokenFromKeyword(Keyword.WHILE);
-  static final YIELD = TokenFactory.tokenFromKeyword(Keyword.YIELD);
-
-  static Token choose(bool if1, Token then1, bool if2, Token then2,
-      [bool if3, Token then3]) {
-    if (if1) return then1;
-    if (if2) return then2;
-    if (if2 == true) return then3;
-    return null;
-  }
-
-  static Token fromType(UnlinkedTokenType type) {
-    return TokenFactory.tokenFromType(
-      TokensContext.binaryToAstTokenType(type),
+    return astFactory.variableDeclarationList2(
+      comment: null,
+      keyword: Tokens.choose(
+        AstBinaryFlags.isConst(flags),
+        Tokens.CONST,
+        AstBinaryFlags.isFinal(flags),
+        Tokens.FINAL,
+        AstBinaryFlags.isVar(flags),
+        Tokens.VAR,
+      ),
+      lateKeyword: AstBinaryFlags.isLate(flags) ? Tokens.LATE : null,
+      metadata: metadata,
+      type: type,
+      variables: variables,
     );
   }
+
+  WithClause _readWithClause() {
+    var mixins = _readNodeList<TypeName>();
+    return astFactory.withClause(Tokens.WITH, mixins);
+  }
 }
diff --git a/pkg/analyzer/lib/src/summary2/ast_binary_tag.dart b/pkg/analyzer/lib/src/summary2/ast_binary_tag.dart
new file mode 100644
index 0000000..3c31999
--- /dev/null
+++ b/pkg/analyzer/lib/src/summary2/ast_binary_tag.dart
@@ -0,0 +1,124 @@
+// Copyright (c) 2020, 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.
+
+class Tag {
+  static const int Nothing = 0;
+  static const int Something = 1;
+
+  static const int AdjacentStrings = 75;
+  static const int Annotation = 2;
+  static const int ArgumentList = 3;
+  static const int AsExpression = 84;
+  static const int AssertInitializer = 82;
+  static const int AssignmentExpression = 96;
+  static const int BinaryExpression = 52;
+  static const int BooleanLiteral = 4;
+  static const int CascadeExpression = 95;
+  static const int Class = 5;
+  static const int ClassTypeAlias = 44;
+  static const int ConditionalExpression = 51;
+  static const int Configuration = 46;
+  static const int ConstructorDeclaration = 6;
+  static const int ConstructorFieldInitializer = 50;
+  static const int ConstructorName = 7;
+  static const int DeclaredIdentifier = 90;
+  static const int DefaultFormalParameter = 8;
+  static const int DottedName = 47;
+  static const int DoubleLiteral = 9;
+  static const int EnumConstantDeclaration = 10;
+  static const int EnumDeclaration = 11;
+  static const int ExportDirective = 12;
+  static const int ExtendsClause = 13;
+  static const int ExtensionDeclaration = 14;
+  static const int ExtensionOverride = 87;
+  static const int FieldDeclaration = 15;
+  static const int FieldFormalParameter = 16;
+  static const int ForEachPartsWithDeclaration = 89;
+  static const int ForElement = 88;
+  static const int ForPartsWithDeclarations = 91;
+  static const int FormalParameterList = 17;
+  static const int FunctionDeclaration = 18;
+  static const int FunctionDeclaration_getter = 57;
+  static const int FunctionDeclaration_setter = 58;
+  static const int FunctionExpression = 19;
+  static const int FunctionExpressionInvocation = 93;
+  static const int FunctionTypeAlias = 55;
+  static const int FunctionTypedFormalParameter = 20;
+  static const int GenericFunctionType = 21;
+  static const int GenericTypeAlias = 22;
+  static const int HideCombinator = 48;
+  static const int IfElement = 63;
+  static const int ImplementsClause = 23;
+  static const int ImportDirective = 24;
+  static const int IndexExpression = 98;
+  static const int InstanceCreationExpression = 25;
+  static const int IntegerLiteralNegative = 73;
+  static const int IntegerLiteralNegative1 = 71;
+  static const int IntegerLiteralNull = 97;
+  static const int IntegerLiteralPositive = 72;
+  static const int IntegerLiteralPositive1 = 26;
+  static const int InterpolationExpression = 77;
+  static const int InterpolationString = 78;
+  static const int IsExpression = 83;
+  static const int Label = 61;
+  static const int LibraryDirective = 27;
+  static const int LibraryIdentifier = 28;
+  static const int ListLiteral = 56;
+  static const int MapLiteralEntry = 66;
+  static const int MethodDeclaration = 29;
+  static const int MethodDeclaration_getter = 85;
+  static const int MethodDeclaration_setter = 86;
+  static const int MethodInvocation = 59;
+  static const int MixinDeclaration = 67;
+  static const int NamedExpression = 60;
+  static const int NativeClause = 92;
+  static const int OnClause = 68;
+  static const int NullLiteral = 49;
+  static const int ParenthesizedExpression = 53;
+  static const int PartDirective = 30;
+  static const int PartOfDirective = 31;
+  static const int PostfixExpression = 94;
+  static const int PrefixExpression = 79;
+  static const int PrefixedIdentifier = 32;
+  static const int PropertyAccess = 62;
+  static const int RedirectingConstructorInvocation = 54;
+  static const int SetOrMapLiteral = 65;
+  static const int ShowCombinator = 33;
+  static const int SimpleFormalParameter = 34;
+  static const int SimpleIdentifier = 35;
+  static const int SimpleStringLiteral = 36;
+  static const int SpreadElement = 64;
+  static const int StringInterpolation = 76;
+  static const int SuperConstructorInvocation = 69;
+  static const int SuperExpression = 80;
+  static const int SymbolLiteral = 74;
+  static const int ThisExpression = 70;
+  static const int ThrowExpression = 81;
+  static const int TopLevelVariableDeclaration = 37;
+  static const int TypeArgumentList = 38;
+  static const int TypeName = 39;
+  static const int TypeParameter = 40;
+  static const int TypeParameterList = 41;
+  static const int VariableDeclaration = 42;
+  static const int VariableDeclarationList = 43;
+  static const int WithClause = 45;
+
+  static const int RawElement = 0;
+  static const int MemberLegacyWithoutTypeArguments = 1;
+  static const int MemberLegacyWithTypeArguments = 2;
+  static const int MemberWithTypeArguments = 3;
+
+  static const int ParameterKindRequiredPositional = 1;
+  static const int ParameterKindOptionalPositional = 2;
+  static const int ParameterKindRequiredNamed = 3;
+  static const int ParameterKindOptionalNamed = 4;
+
+  static const int NullType = 2;
+  static const int DynamicType = 3;
+  static const int FunctionType = 4;
+  static const int NeverType = 5;
+  static const int InterfaceType = 6;
+  static const int TypeParameterType = 7;
+  static const int VoidType = 8;
+}
diff --git a/pkg/analyzer/lib/src/summary2/ast_binary_tokens.dart b/pkg/analyzer/lib/src/summary2/ast_binary_tokens.dart
new file mode 100644
index 0000000..a9a8a69
--- /dev/null
+++ b/pkg/analyzer/lib/src/summary2/ast_binary_tokens.dart
@@ -0,0 +1,116 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:analyzer/dart/ast/token.dart';
+import 'package:analyzer/src/generated/testing/token_factory.dart';
+import 'package:analyzer/src/summary2/tokens_context.dart';
+import 'package:analyzer/src/summary2/unlinked_token_type.dart';
+
+class Tokens {
+  static final ABSTRACT = TokenFactory.tokenFromKeyword(Keyword.ABSTRACT);
+  static final ARROW = TokenFactory.tokenFromType(TokenType.FUNCTION);
+  static final AS = TokenFactory.tokenFromKeyword(Keyword.AS);
+  static final ASSERT = TokenFactory.tokenFromKeyword(Keyword.ASSERT);
+  static final AT = TokenFactory.tokenFromType(TokenType.AT);
+  static final ASYNC = TokenFactory.tokenFromKeyword(Keyword.ASYNC);
+  static final AWAIT = TokenFactory.tokenFromKeyword(Keyword.AWAIT);
+  static final BANG = TokenFactory.tokenFromType(TokenType.BANG);
+  static final BREAK = TokenFactory.tokenFromKeyword(Keyword.BREAK);
+  static final CASE = TokenFactory.tokenFromKeyword(Keyword.CASE);
+  static final CATCH = TokenFactory.tokenFromKeyword(Keyword.CATCH);
+  static final CLASS = TokenFactory.tokenFromKeyword(Keyword.CLASS);
+  static final CLOSE_CURLY_BRACKET =
+      TokenFactory.tokenFromType(TokenType.CLOSE_CURLY_BRACKET);
+  static final CLOSE_PAREN = TokenFactory.tokenFromType(TokenType.CLOSE_PAREN);
+  static final CLOSE_SQUARE_BRACKET =
+      TokenFactory.tokenFromType(TokenType.CLOSE_SQUARE_BRACKET);
+  static final COLON = TokenFactory.tokenFromType(TokenType.COLON);
+  static final COMMA = TokenFactory.tokenFromType(TokenType.COMMA);
+  static final CONST = TokenFactory.tokenFromKeyword(Keyword.CONST);
+  static final CONTINUE = TokenFactory.tokenFromKeyword(Keyword.CONTINUE);
+  static final COVARIANT = TokenFactory.tokenFromKeyword(Keyword.COVARIANT);
+  static final DEFERRED = TokenFactory.tokenFromKeyword(Keyword.DEFERRED);
+  static final ELSE = TokenFactory.tokenFromKeyword(Keyword.ELSE);
+  static final EXTERNAL = TokenFactory.tokenFromKeyword(Keyword.EXTERNAL);
+  static final FACTORY = TokenFactory.tokenFromKeyword(Keyword.FACTORY);
+  static final DEFAULT = TokenFactory.tokenFromKeyword(Keyword.DEFAULT);
+  static final DO = TokenFactory.tokenFromKeyword(Keyword.DO);
+  static final ENUM = TokenFactory.tokenFromKeyword(Keyword.ENUM);
+  static final EQ = TokenFactory.tokenFromType(TokenType.EQ);
+  static final EXPORT = TokenFactory.tokenFromKeyword(Keyword.EXPORT);
+  static final EXTENDS = TokenFactory.tokenFromKeyword(Keyword.EXTENDS);
+  static final EXTENSION = TokenFactory.tokenFromKeyword(Keyword.EXTENSION);
+  static final FINAL = TokenFactory.tokenFromKeyword(Keyword.FINAL);
+  static final FINALLY = TokenFactory.tokenFromKeyword(Keyword.FINALLY);
+  static final FOR = TokenFactory.tokenFromKeyword(Keyword.FOR);
+  static final FUNCTION = TokenFactory.tokenFromKeyword(Keyword.FUNCTION);
+  static final GET = TokenFactory.tokenFromKeyword(Keyword.GET);
+  static final GT = TokenFactory.tokenFromType(TokenType.GT);
+  static final HASH = TokenFactory.tokenFromType(TokenType.HASH);
+  static final HIDE = TokenFactory.tokenFromKeyword(Keyword.HIDE);
+  static final IF = TokenFactory.tokenFromKeyword(Keyword.IF);
+  static final IMPLEMENTS = TokenFactory.tokenFromKeyword(Keyword.IMPORT);
+  static final IMPORT = TokenFactory.tokenFromKeyword(Keyword.IMPLEMENTS);
+  static final IN = TokenFactory.tokenFromKeyword(Keyword.IN);
+  static final IS = TokenFactory.tokenFromKeyword(Keyword.IS);
+  static final LATE = TokenFactory.tokenFromKeyword(Keyword.LATE);
+  static final LIBRARY = TokenFactory.tokenFromKeyword(Keyword.LIBRARY);
+  static final LT = TokenFactory.tokenFromType(TokenType.LT);
+  static final MIXIN = TokenFactory.tokenFromKeyword(Keyword.MIXIN);
+  static final NATIVE = TokenFactory.tokenFromKeyword(Keyword.NATIVE);
+  static final NEW = TokenFactory.tokenFromKeyword(Keyword.NEW);
+  static final NULL = TokenFactory.tokenFromKeyword(Keyword.NULL);
+  static final OF = TokenFactory.tokenFromKeyword(Keyword.OF);
+  static final ON = TokenFactory.tokenFromKeyword(Keyword.ON);
+  static final OPEN_CURLY_BRACKET =
+      TokenFactory.tokenFromType(TokenType.OPEN_CURLY_BRACKET);
+  static final OPEN_PAREN = TokenFactory.tokenFromType(TokenType.OPEN_PAREN);
+  static final OPEN_SQUARE_BRACKET =
+      TokenFactory.tokenFromType(TokenType.OPEN_SQUARE_BRACKET);
+  static final OPERATOR = TokenFactory.tokenFromKeyword(Keyword.OPERATOR);
+  static final PART = TokenFactory.tokenFromKeyword(Keyword.PART);
+  static final PERIOD = TokenFactory.tokenFromType(TokenType.PERIOD);
+  static final PERIOD_PERIOD =
+      TokenFactory.tokenFromType(TokenType.PERIOD_PERIOD);
+  static final PERIOD_PERIOD_PERIOD =
+      TokenFactory.tokenFromType(TokenType.PERIOD_PERIOD_PERIOD);
+  static final PERIOD_PERIOD_PERIOD_QUESTION =
+      TokenFactory.tokenFromType(TokenType.PERIOD_PERIOD_PERIOD_QUESTION);
+  static final QUESTION = TokenFactory.tokenFromType(TokenType.QUESTION);
+  static final REQUIRED = TokenFactory.tokenFromKeyword(Keyword.REQUIRED);
+  static final RETHROW = TokenFactory.tokenFromKeyword(Keyword.RETHROW);
+  static final RETURN = TokenFactory.tokenFromKeyword(Keyword.RETURN);
+  static final SEMICOLON = TokenFactory.tokenFromType(TokenType.SEMICOLON);
+  static final SET = TokenFactory.tokenFromKeyword(Keyword.SET);
+  static final SHOW = TokenFactory.tokenFromKeyword(Keyword.SHOW);
+  static final STAR = TokenFactory.tokenFromType(TokenType.STAR);
+  static final STATIC = TokenFactory.tokenFromKeyword(Keyword.STATIC);
+  static final STRING_INTERPOLATION_EXPRESSION =
+      TokenFactory.tokenFromType(TokenType.STRING_INTERPOLATION_EXPRESSION);
+  static final SUPER = TokenFactory.tokenFromKeyword(Keyword.SUPER);
+  static final SWITCH = TokenFactory.tokenFromKeyword(Keyword.SWITCH);
+  static final SYNC = TokenFactory.tokenFromKeyword(Keyword.SYNC);
+  static final THIS = TokenFactory.tokenFromKeyword(Keyword.THIS);
+  static final THROW = TokenFactory.tokenFromKeyword(Keyword.THROW);
+  static final TRY = TokenFactory.tokenFromKeyword(Keyword.TRY);
+  static final TYPEDEF = TokenFactory.tokenFromKeyword(Keyword.TYPEDEF);
+  static final VAR = TokenFactory.tokenFromKeyword(Keyword.VAR);
+  static final WITH = TokenFactory.tokenFromKeyword(Keyword.WITH);
+  static final WHILE = TokenFactory.tokenFromKeyword(Keyword.WHILE);
+  static final YIELD = TokenFactory.tokenFromKeyword(Keyword.YIELD);
+
+  static Token choose(bool if1, Token then1, bool if2, Token then2,
+      [bool if3, Token then3]) {
+    if (if1) return then1;
+    if (if2) return then2;
+    if (if2 == true) return then3;
+    return null;
+  }
+
+  static Token fromType(UnlinkedTokenType type) {
+    return TokenFactory.tokenFromType(
+      TokensContext.binaryToAstTokenType(type),
+    );
+  }
+}
diff --git a/pkg/analyzer/lib/src/summary2/ast_binary_writer.dart b/pkg/analyzer/lib/src/summary2/ast_binary_writer.dart
index 0035dd8..9d2b3df 100644
--- a/pkg/analyzer/lib/src/summary2/ast_binary_writer.dart
+++ b/pkg/analyzer/lib/src/summary2/ast_binary_writer.dart
@@ -2,1712 +2,1748 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
+import 'package:analyzer/dart/analysis/features.dart';
 import 'package:analyzer/dart/ast/ast.dart';
 import 'package:analyzer/dart/ast/token.dart';
 import 'package:analyzer/dart/ast/visitor.dart';
 import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/dart/element/type.dart';
+import 'package:analyzer/source/line_info.dart';
 import 'package:analyzer/src/dart/analysis/experiments.dart';
 import 'package:analyzer/src/dart/ast/ast.dart';
-import 'package:analyzer/src/dart/element/member.dart';
+import 'package:analyzer/src/dart/element/element.dart';
 import 'package:analyzer/src/dart/resolver/variance.dart';
-import 'package:analyzer/src/summary/format.dart';
-import 'package:analyzer/src/summary/idl.dart';
 import 'package:analyzer/src/summary2/ast_binary_flags.dart';
-import 'package:analyzer/src/summary2/informative_data.dart';
-import 'package:analyzer/src/summary2/lazy_ast.dart';
-import 'package:analyzer/src/summary2/linking_bundle_context.dart';
+import 'package:analyzer/src/summary2/ast_binary_tag.dart';
+import 'package:analyzer/src/summary2/bundle_writer.dart';
+import 'package:analyzer/src/summary2/data_writer.dart';
 import 'package:analyzer/src/summary2/tokens_writer.dart';
+import 'package:analyzer/src/task/inference_error.dart';
+import 'package:meta/meta.dart';
 
-var timerAstBinaryWriter = Stopwatch();
-var timerAstBinaryWriterClass = Stopwatch();
-var timerAstBinaryWriterDirective = Stopwatch();
-var timerAstBinaryWriterFunctionBody = Stopwatch();
-var timerAstBinaryWriterMixin = Stopwatch();
-var timerAstBinaryWriterTopVar = Stopwatch();
-var timerAstBinaryWriterTypedef = Stopwatch();
+/// Serializer of fully resolved ASTs.
+class AstBinaryWriter extends ThrowingAstVisitor<void> {
+  final bool _withInformative;
+  final BufferedSink _sink;
+  final StringIndexer _stringIndexer;
+  final ResolutionUnit _resolutionUnit;
+  final ResolutionSink _resolutionSink;
 
-/// Serializer of fully resolved ASTs into flat buffers.
-class AstBinaryWriter extends ThrowingAstVisitor<LinkedNodeBuilder> {
-  final LinkingBundleContext _linkingContext;
-
-  /// Is `true` if the current [ClassDeclaration] has a const constructor,
-  /// so initializers of final fields should be written.
+  /// TODO(scheglov) Keep it private, and write here, similarly as we do
+  /// for [_classMemberIndexItems]?
+  final List<_UnitMemberIndexItem> unitMemberIndexItems = [];
+  final List<_ClassMemberIndexItem> _classMemberIndexItems = [];
+  bool _isConstField = false;
+  bool _isFinalField = false;
+  bool _isConstTopLevelVariable = false;
   bool _hasConstConstructor = false;
+  int _nextUnnamedExtensionId = 0;
 
-  AstBinaryWriter(this._linkingContext);
+  AstBinaryWriter({
+    @required BundleWriterAst bundleWriterAst,
+    @required ResolutionUnit resolutionUnit,
+  })  : _withInformative = bundleWriterAst.withInformative,
+        _sink = bundleWriterAst.sink,
+        _stringIndexer = bundleWriterAst.stringIndexer,
+        _resolutionUnit = resolutionUnit,
+        _resolutionSink = resolutionUnit.library.sink;
 
   @override
-  LinkedNodeBuilder visitAdjacentStrings(AdjacentStrings node) {
-    return LinkedNodeBuilder.adjacentStrings(
-      adjacentStrings_strings: _writeNodeList(node.strings),
-    );
+  void visitAdjacentStrings(AdjacentStrings node) {
+    _writeByte(Tag.AdjacentStrings);
+    _writeNodeList(node.strings);
   }
 
   @override
-  LinkedNodeBuilder visitAnnotation(Annotation node) {
-    var elementComponents = _componentsOfElement(node.element);
+  void visitAnnotation(Annotation node) {
+    _writeByte(Tag.Annotation);
 
-    LinkedNodeBuilder storedArguments;
+    _writeOptionalNode(node.name);
+    _writeOptionalNode(node.constructorName);
+
     var arguments = node.arguments;
     if (arguments != null) {
-      if (arguments.arguments.every(_isSerializableExpression)) {
-        storedArguments = arguments.accept(this);
-      } else {
-        storedArguments = LinkedNodeBuilder.argumentList();
+      if (!arguments.arguments.every(_isSerializableExpression)) {
+        arguments = null;
+      }
+    }
+    _writeOptionalNode(arguments);
+
+    _resolutionSink.writeElement(node.element);
+  }
+
+  @override
+  void visitArgumentList(ArgumentList node) {
+    _writeByte(Tag.ArgumentList);
+    _writeNodeList(node.arguments);
+  }
+
+  @override
+  void visitAsExpression(AsExpression node) {
+    _writeByte(Tag.AsExpression);
+    _writeNode(node.expression);
+    _writeNode(node.type);
+    _storeExpression(node);
+  }
+
+  @override
+  void visitAssertInitializer(AssertInitializer node) {
+    _writeByte(Tag.AssertInitializer);
+    _writeNode(node.condition);
+    _writeOptionalNode(node.message);
+  }
+
+  @override
+  void visitAssignmentExpression(AssignmentExpression node) {
+    _writeByte(Tag.AssignmentExpression);
+
+    _writeNode(node.leftHandSide);
+    _writeNode(node.rightHandSide);
+
+    var operatorToken = node.operator.type;
+    var binaryToken = TokensWriter.astToBinaryTokenType(operatorToken);
+    _writeByte(binaryToken.index);
+
+    _resolutionSink.writeElement(node.staticElement);
+    _resolutionSink.writeElement(node.readElement);
+    _resolutionSink.writeType(node.readType);
+    _resolutionSink.writeElement(node.writeElement);
+    _resolutionSink.writeType(node.writeType);
+    _storeExpression(node);
+  }
+
+  @override
+  void visitBinaryExpression(BinaryExpression node) {
+    _writeByte(Tag.BinaryExpression);
+
+    _writeNode(node.leftOperand);
+    _writeNode(node.rightOperand);
+
+    var operatorToken = node.operator.type;
+    var binaryToken = TokensWriter.astToBinaryTokenType(operatorToken);
+    _writeByte(binaryToken.index);
+
+    _resolutionSink?.writeElement(node.staticElement);
+    _resolutionSink?.writeType(node.staticType);
+  }
+
+  @override
+  void visitBooleanLiteral(BooleanLiteral node) {
+    _writeByte(Tag.BooleanLiteral);
+    _writeByte(node.value ? 1 : 0);
+    // TODO(scheglov) Dont write type?
+    _resolutionSink?.writeType(node.staticType);
+  }
+
+  @override
+  void visitCascadeExpression(CascadeExpression node) {
+    _writeByte(Tag.CascadeExpression);
+    _writeNode(node.target);
+    _writeNodeList(node.cascadeSections);
+  }
+
+  @override
+  void visitClassDeclaration(ClassDeclaration node) {
+    var classOffset = _sink.offset;
+    var resolutionIndex = _resolutionUnit.enterDeclaration();
+
+    _hasConstConstructor = false;
+    for (var member in node.members) {
+      if (member is ConstructorDeclaration && member.constKeyword != null) {
+        _hasConstConstructor = true;
+        break;
       }
     }
 
-    return LinkedNodeBuilder.annotation(
-      annotation_arguments: storedArguments,
-      annotation_constructorName: node.constructorName?.accept(this),
-      annotation_element: elementComponents.rawElement,
-      annotation_substitution: elementComponents.substitution,
-      annotation_name: node.name?.accept(this),
-    );
-  }
-
-  @override
-  LinkedNodeBuilder visitArgumentList(ArgumentList node) {
-    return LinkedNodeBuilder.argumentList(
-      argumentList_arguments: _writeNodeList(node.arguments),
-    );
-  }
-
-  @override
-  LinkedNodeBuilder visitAsExpression(AsExpression node) {
-    return LinkedNodeBuilder.asExpression(
-      asExpression_expression: node.expression.accept(this),
-      asExpression_type: node.type.accept(this),
-    );
-  }
-
-  @override
-  LinkedNodeBuilder visitAssertInitializer(AssertInitializer node) {
-    return LinkedNodeBuilder.assertInitializer(
-      assertInitializer_condition: node.condition.accept(this),
-      assertInitializer_message: node.message?.accept(this),
-    );
-  }
-
-  @override
-  LinkedNodeBuilder visitAssertStatement(AssertStatement node) {
-    var builder = LinkedNodeBuilder.assertStatement(
-      assertStatement_condition: node.condition.accept(this),
-      assertStatement_message: node.message?.accept(this),
-    );
-    _storeStatement(builder, node);
-    return builder;
-  }
-
-  @override
-  LinkedNodeBuilder visitAssignmentExpression(AssignmentExpression node) {
-    var elementComponents = _componentsOfElement(node.staticElement);
-    return LinkedNodeBuilder.assignmentExpression(
-      assignmentExpression_element: elementComponents.rawElement,
-      assignmentExpression_substitution: elementComponents.substitution,
-      assignmentExpression_leftHandSide: node.leftHandSide.accept(this),
-      assignmentExpression_operator: TokensWriter.astToBinaryTokenType(
-        node.operator.type,
-      ),
-      assignmentExpression_rightHandSide: node.rightHandSide.accept(this),
-      expression_type: _writeType(node.staticType),
-    );
-  }
-
-  @override
-  LinkedNodeBuilder visitAwaitExpression(AwaitExpression node) {
-    return LinkedNodeBuilder.awaitExpression(
-      awaitExpression_expression: node.expression.accept(this),
-      expression_type: _writeType(node.staticType),
-    );
-  }
-
-  @override
-  LinkedNodeBuilder visitBinaryExpression(BinaryExpression node) {
-    var elementComponents = _componentsOfElement(node.staticElement);
-    return LinkedNodeBuilder.binaryExpression(
-      binaryExpression_element: elementComponents.rawElement,
-      binaryExpression_substitution: elementComponents.substitution,
-      binaryExpression_leftOperand: node.leftOperand.accept(this),
-      binaryExpression_operator: TokensWriter.astToBinaryTokenType(
-        node.operator.type,
-      ),
-      binaryExpression_rightOperand: node.rightOperand.accept(this),
-      expression_type: _writeType(node.staticType),
-    );
-  }
-
-  @override
-  LinkedNodeBuilder visitBlock(Block node) {
-    return LinkedNodeBuilder.block(
-      block_statements: _writeNodeList(node.statements),
-    );
-  }
-
-  @override
-  LinkedNodeBuilder visitBlockFunctionBody(BlockFunctionBody node) {
-    timerAstBinaryWriterFunctionBody.start();
-    try {
-      var builder = LinkedNodeBuilder.blockFunctionBody(
-        blockFunctionBody_block: node.block.accept(this),
-      );
-      builder.flags = AstBinaryFlags.encode(
-        isAsync: node.keyword?.keyword == Keyword.ASYNC,
-        isStar: node.star != null,
-        isSync: node.keyword?.keyword == Keyword.SYNC,
-      );
-      return builder;
-    } finally {
-      timerAstBinaryWriterFunctionBody.stop();
-    }
-  }
-
-  @override
-  LinkedNodeBuilder visitBooleanLiteral(BooleanLiteral node) {
-    return LinkedNodeBuilder.booleanLiteral(
-      booleanLiteral_value: node.value,
-    );
-  }
-
-  @override
-  LinkedNodeBuilder visitBreakStatement(BreakStatement node) {
-    var builder = LinkedNodeBuilder.breakStatement(
-      breakStatement_label: node.label?.accept(this),
-    );
-    _storeStatement(builder, node);
-    return builder;
-  }
-
-  @override
-  LinkedNodeBuilder visitCascadeExpression(CascadeExpression node) {
-    var builder = LinkedNodeBuilder.cascadeExpression(
-      cascadeExpression_target: node.target.accept(this),
-      cascadeExpression_sections: _writeNodeList(node.cascadeSections),
-    );
-    _storeExpression(builder, node);
-    return builder;
-  }
-
-  @override
-  LinkedNodeBuilder visitCatchClause(CatchClause node) {
-    return LinkedNodeBuilder.catchClause(
-      catchClause_body: node.body.accept(this),
-      catchClause_exceptionParameter: node.exceptionParameter?.accept(this),
-      catchClause_exceptionType: node.exceptionType?.accept(this),
-      catchClause_stackTraceParameter: node.stackTraceParameter?.accept(this),
-    );
-  }
-
-  @override
-  LinkedNodeBuilder visitClassDeclaration(ClassDeclaration node) {
-    try {
-      timerAstBinaryWriterClass.start();
-
-      _hasConstConstructor = false;
-      for (var member in node.members) {
-        if (member is ConstructorDeclaration && member.constKeyword != null) {
-          _hasConstConstructor = true;
-          break;
-        }
-      }
-
-      var builder = LinkedNodeBuilder.classDeclaration(
-        classDeclaration_extendsClause: node.extendsClause?.accept(this),
-        classDeclaration_nativeClause: node.nativeClause?.accept(this),
-        classDeclaration_withClause: node.withClause?.accept(this),
-      );
-      builder.flags = AstBinaryFlags.encode(
+    _writeByte(Tag.Class);
+    _writeByte(
+      AstBinaryFlags.encode(
+        hasConstConstructor: _hasConstConstructor,
         isAbstract: node.abstractKeyword != null,
-      );
-      _storeClassOrMixinDeclaration(builder, node);
-      return builder;
-    } finally {
-      timerAstBinaryWriterClass.stop();
-    }
-  }
+      ),
+    );
+    _resolutionSink.writeByte(node.declaredElement.isSimplyBounded ? 1 : 0);
 
-  @override
-  LinkedNodeBuilder visitClassTypeAlias(ClassTypeAlias node) {
-    timerAstBinaryWriterClass.start();
-    try {
-      var builder = LinkedNodeBuilder.classTypeAlias(
-        classTypeAlias_implementsClause: node.implementsClause?.accept(this),
-        classTypeAlias_superclass: node.superclass.accept(this),
-        classTypeAlias_typeParameters: node.typeParameters?.accept(this),
-        classTypeAlias_withClause: node.withClause.accept(this),
-      );
-      builder.flags = AstBinaryFlags.encode(
-        isAbstract: node.abstractKeyword != null,
-      );
-      _storeTypeAlias(builder, node);
-      _storeIsSimpleBounded(builder, node);
-      return builder;
-    } finally {
-      timerAstBinaryWriterClass.stop();
-    }
-  }
+    _writeInformativeUint30(node.offset);
+    _writeInformativeUint30(node.length);
+    _writeDocumentationCommentString(node.documentationComment);
 
-  @override
-  LinkedNodeBuilder visitComment(Comment node) {
-    LinkedNodeCommentType type;
-    if (node.isBlock) {
-      type = LinkedNodeCommentType.block;
-    } else if (node.isDocumentation) {
-      type = LinkedNodeCommentType.documentation;
-    } else if (node.isEndOfLine) {
-      type = LinkedNodeCommentType.endOfLine;
-    }
+    _pushScopeTypeParameters(node.typeParameters);
 
-    return LinkedNodeBuilder.comment(
-      comment_tokens: node.tokens.map((t) => t.lexeme).toList(),
-      comment_type: type,
-      // TODO(scheglov) restore
-//      comment_references: _writeNodeList(node.references),
+    _writeOptionalNode(node.typeParameters);
+    _writeOptionalNode(node.extendsClause);
+    _writeOptionalNode(node.withClause);
+    _writeOptionalNode(node.implementsClause);
+    _writeOptionalNode(node.nativeClause);
+    _storeNamedCompilationUnitMember(node);
+    _writeUInt30(resolutionIndex);
+
+    _classMemberIndexItems.clear();
+    _writeNodeList(node.members);
+    _hasConstConstructor = false;
+
+    _resolutionSink.localElements.popScope();
+
+    // TODO(scheglov) write member index
+    var classIndexOffset = _sink.offset;
+    _writeClassMemberIndex();
+
+    unitMemberIndexItems.add(
+      _UnitMemberIndexItem(
+        offset: classOffset,
+        tag: Tag.Class,
+        name: node.name.name,
+        classIndexOffset: classIndexOffset,
+      ),
     );
   }
 
   @override
-  LinkedNodeBuilder visitCommentReference(CommentReference node) {
-//    var identifier = node.identifier;
-//    _tokensWriter.writeTokens(
-//      node.newKeyword ?? identifier.beginToken,
-//      identifier.endToken,
-//    );
-//
-//    return LinkedNodeBuilder.commentReference(
-//      commentReference_identifier: identifier.accept(this),
-//      commentReference_newKeyword: _getToken(node.newKeyword),
-//    );
-    return null;
+  void visitClassTypeAlias(ClassTypeAlias node) {
+    unitMemberIndexItems.add(
+      _UnitMemberIndexItem(
+        offset: _sink.offset,
+        tag: Tag.ClassTypeAlias,
+        name: node.name.name,
+      ),
+    );
+
+    var resolutionIndex = _resolutionUnit.enterDeclaration();
+
+    _writeByte(Tag.ClassTypeAlias);
+    _writeByte(
+      AstBinaryFlags.encode(
+        isAbstract: node.abstractKeyword != null,
+      ),
+    );
+    _resolutionSink.writeByte(node.declaredElement.isSimplyBounded ? 1 : 0);
+    _writeInformativeUint30(node.offset);
+    _writeInformativeUint30(node.length);
+    _pushScopeTypeParameters(node.typeParameters);
+    _writeOptionalNode(node.typeParameters);
+    _writeNode(node.superclass);
+    _writeNode(node.withClause);
+    _writeOptionalNode(node.implementsClause);
+    _storeTypeAlias(node);
+    _writeDocumentationCommentString(node.documentationComment);
+    _writeUInt30(resolutionIndex);
+    _resolutionSink.localElements.popScope();
   }
 
   @override
-  LinkedNodeBuilder visitCompilationUnit(CompilationUnit node) {
+  void visitCompilationUnit(CompilationUnit node) {
     var nodeImpl = node as CompilationUnitImpl;
-    var builder = LinkedNodeBuilder.compilationUnit(
-      compilationUnit_declarations: _writeNodeList(node.declarations),
-      compilationUnit_directives: _writeNodeList(node.directives),
-      compilationUnit_featureSet:
-          (node.featureSet as ExperimentStatus).toStorage(),
-      compilationUnit_languageVersion: LinkedLibraryLanguageVersionBuilder(
-        package: LinkedLanguageVersionBuilder(
-          major: nodeImpl.languageVersion.package.major,
-          minor: nodeImpl.languageVersion.package.minor,
-        ),
-        override2: nodeImpl.languageVersion.override != null
-            ? LinkedLanguageVersionBuilder(
-                major: nodeImpl.languageVersion.override.major,
-                minor: nodeImpl.languageVersion.override.minor,
-              )
-            : null,
+    _writeLanguageVersion(nodeImpl.languageVersion);
+    _writeFeatureSet(node.featureSet);
+    _writeLineInfo(node.lineInfo);
+    _writeUInt30(_withInformative ? node.length : 0);
+    _writeNodeList(node.directives);
+    for (var declaration in node.declarations) {
+      declaration.accept(this);
+    }
+  }
+
+  @override
+  void visitConditionalExpression(ConditionalExpression node) {
+    _writeByte(Tag.ConditionalExpression);
+    _writeNode(node.condition);
+    _writeNode(node.thenExpression);
+    _writeNode(node.elseExpression);
+    _storeExpression(node);
+  }
+
+  @override
+  void visitConfiguration(Configuration node) {
+    _writeByte(Tag.Configuration);
+
+    _writeByte(
+      AstBinaryFlags.encode(
+        hasEqual: node.equalToken != null,
       ),
-      compilationUnit_scriptTag: node.scriptTag?.accept(this),
-      informativeId: getInformativeId(node),
     );
-    return builder;
+
+    _writeNode(node.name);
+    _writeOptionalNode(node.value);
+    _writeNode(node.uri);
   }
 
   @override
-  LinkedNodeBuilder visitConditionalExpression(ConditionalExpression node) {
-    var builder = LinkedNodeBuilder.conditionalExpression(
-      conditionalExpression_condition: node.condition.accept(this),
-      conditionalExpression_elseExpression: node.elseExpression.accept(this),
-      conditionalExpression_thenExpression: node.thenExpression.accept(this),
+  void visitConstructorDeclaration(ConstructorDeclaration node) {
+    _classMemberIndexItems.add(
+      _ClassMemberIndexItem(
+        offset: _sink.offset,
+        tag: Tag.ConstructorDeclaration,
+        name: node.name?.name ?? '',
+      ),
     );
-    _storeExpression(builder, node);
-    return builder;
+
+    _writeByte(Tag.ConstructorDeclaration);
+
+    _writeByte(
+      AstBinaryFlags.encode(
+        hasName: node.name != null,
+        hasSeparatorColon: node.separator?.type == TokenType.COLON,
+        hasSeparatorEquals: node.separator?.type == TokenType.EQ,
+        isAbstract: node.body is EmptyFunctionBody,
+        isConst: node.constKeyword != null,
+        isExternal: node.externalKeyword != null,
+        isFactory: node.factoryKeyword != null,
+      ),
+    );
+
+    _writeInformativeUint30(node.offset);
+    _writeInformativeUint30(node.length);
+    _writeDocumentationCommentString(node.documentationComment);
+
+    var resolutionIndex = _resolutionUnit.enterDeclaration();
+    _writeNode(node.returnType);
+    if (node.period != null) {
+      _writeInformativeUint30(node.period.offset);
+      _writeDeclarationName(node.name);
+    }
+    _writeNode(node.parameters);
+
+    _resolutionSink.localElements.pushScope();
+    for (var parameter in node.parameters.parameters) {
+      _resolutionSink.localElements.declare(parameter.declaredElement);
+    }
+    _writeNodeList(node.initializers);
+    _resolutionSink.localElements.popScope();
+
+    _writeOptionalNode(node.redirectedConstructor);
+    _storeClassMember(node);
+    _writeUInt30(resolutionIndex);
   }
 
   @override
-  LinkedNodeBuilder visitConfiguration(Configuration node) {
-    var builder = LinkedNodeBuilder.configuration(
-      configuration_name: node.name?.accept(this),
-      configuration_value: node.value?.accept(this),
-      configuration_uri: node.uri?.accept(this),
+  void visitConstructorFieldInitializer(ConstructorFieldInitializer node) {
+    _writeByte(Tag.ConstructorFieldInitializer);
+
+    _writeByte(
+      AstBinaryFlags.encode(
+        hasThis: node.thisKeyword != null,
+      ),
     );
-    builder.flags = AstBinaryFlags.encode(
-      hasEqual: node.equalToken != null,
-    );
-    return builder;
+
+    _writeNode(node.fieldName);
+    _writeNode(node.expression);
+    _storeConstructorInitializer(node);
   }
 
   @override
-  LinkedNodeBuilder visitConstructorDeclaration(ConstructorDeclaration node) {
-    var builder = LinkedNodeBuilder.constructorDeclaration(
-      constructorDeclaration_initializers: _writeNodeList(node.initializers),
-      constructorDeclaration_parameters: node.parameters.accept(this),
-      constructorDeclaration_redirectedConstructor:
-          node.redirectedConstructor?.accept(this),
-      constructorDeclaration_returnType: node.returnType.accept(this),
-      informativeId: getInformativeId(node),
-    );
-    builder.flags = AstBinaryFlags.encode(
-      hasName: node.name != null,
-      hasSeparatorColon: node.separator?.type == TokenType.COLON,
-      hasSeparatorEquals: node.separator?.type == TokenType.EQ,
-      isAbstract: node.body is EmptyFunctionBody,
-      isConst: node.constKeyword != null,
-      isExternal: node.externalKeyword != null,
-      isFactory: node.factoryKeyword != null,
-    );
-    builder.name = node.name?.name;
-    _storeClassMember(builder, node);
-    return builder;
+  void visitConstructorName(ConstructorName node) {
+    _writeByte(Tag.ConstructorName);
+    _writeNode(node.type);
+    _writeOptionalNode(node.name);
+    _resolutionSink?.writeElement(node.staticElement);
   }
 
   @override
-  LinkedNodeBuilder visitConstructorFieldInitializer(
-      ConstructorFieldInitializer node) {
-    var builder = LinkedNodeBuilder.constructorFieldInitializer(
-      constructorFieldInitializer_expression: node.expression.accept(this),
-      constructorFieldInitializer_fieldName: node.fieldName.accept(this),
+  void visitDeclaredIdentifier(DeclaredIdentifier node) {
+    _writeByte(Tag.DeclaredIdentifier);
+    _writeByte(
+      AstBinaryFlags.encode(
+        isConst: node.keyword?.keyword == Keyword.CONST,
+        isFinal: node.keyword?.keyword == Keyword.FINAL,
+        isVar: node.keyword?.keyword == Keyword.VAR,
+      ),
     );
-    builder.flags = AstBinaryFlags.encode(
-      hasThis: node.thisKeyword != null,
-    );
-    _storeConstructorInitializer(builder, node);
-    return builder;
+    _writeOptionalNode(node.type);
+    _writeDeclarationName(node.identifier);
+    _storeDeclaration(node);
   }
 
   @override
-  LinkedNodeBuilder visitConstructorName(ConstructorName node) {
-    var elementComponents = _componentsOfElement(node.staticElement);
-    return LinkedNodeBuilder.constructorName(
-      constructorName_element: elementComponents.rawElement,
-      constructorName_substitution: elementComponents.substitution,
-      constructorName_name: node.name?.accept(this),
-      constructorName_type: node.type.accept(this),
-    );
-  }
+  void visitDefaultFormalParameter(DefaultFormalParameter node) {
+    _writeByte(Tag.DefaultFormalParameter);
 
-  @override
-  LinkedNodeBuilder visitContinueStatement(ContinueStatement node) {
-    var builder = LinkedNodeBuilder.continueStatement(
-      continueStatement_label: node.label?.accept(this),
+    _writeByte(
+      AstBinaryFlags.encode(
+        hasInitializer: node.defaultValue != null,
+        isPositional: node.isPositional,
+        isRequired: node.isRequired,
+      ),
     );
-    _storeStatement(builder, node);
-    return builder;
-  }
 
-  @override
-  LinkedNodeBuilder visitDeclaredIdentifier(DeclaredIdentifier node) {
-    var builder = LinkedNodeBuilder.declaredIdentifier(
-      declaredIdentifier_identifier: node.identifier.accept(this),
-      declaredIdentifier_type: node.type?.accept(this),
-    );
-    builder.flags = AstBinaryFlags.encode(
-      isConst: node.keyword?.keyword == Keyword.CONST,
-      isFinal: node.keyword?.keyword == Keyword.FINAL,
-      isVar: node.keyword?.keyword == Keyword.VAR,
-    );
-    _storeDeclaration(builder, node);
-    return builder;
-  }
+    _writeInformativeUint30(node.offset);
+    _writeInformativeUint30(node.length);
 
-  @override
-  LinkedNodeBuilder visitDefaultFormalParameter(DefaultFormalParameter node) {
+    _writeNode(node.parameter);
+
     var defaultValue = node.defaultValue;
     if (!_isSerializableExpression(defaultValue)) {
       defaultValue = null;
     }
-
-    var builder = LinkedNodeBuilder.defaultFormalParameter(
-      defaultFormalParameter_defaultValue: defaultValue?.accept(this),
-      defaultFormalParameter_kind: _toParameterKind(node),
-      defaultFormalParameter_parameter: node.parameter.accept(this),
-      informativeId: getInformativeId(node),
-    );
-    builder.flags = AstBinaryFlags.encode(
-      hasInitializer: node.defaultValue != null,
-    );
-    return builder;
+    _writeOptionalNode(defaultValue);
   }
 
   @override
-  LinkedNodeBuilder visitDoStatement(DoStatement node) {
-    return LinkedNodeBuilder.doStatement(
-      doStatement_body: node.body.accept(this),
-      doStatement_condition: node.condition.accept(this),
-    );
+  void visitDottedName(DottedName node) {
+    _writeByte(Tag.DottedName);
+    _writeNodeList(node.components);
   }
 
   @override
-  LinkedNodeBuilder visitDottedName(DottedName node) {
-    return LinkedNodeBuilder.dottedName(
-      dottedName_components: _writeNodeList(node.components),
-    );
+  void visitDoubleLiteral(DoubleLiteral node) {
+    _writeByte(Tag.DoubleLiteral);
+    _writeDouble(node.value);
   }
 
   @override
-  LinkedNodeBuilder visitDoubleLiteral(DoubleLiteral node) {
-    return LinkedNodeBuilder.doubleLiteral(
-      doubleLiteral_value: node.value,
-    );
+  void visitEnumConstantDeclaration(EnumConstantDeclaration node) {
+    _writeByte(Tag.EnumConstantDeclaration);
+
+    _writeInformativeUint30(node.offset);
+    _writeInformativeUint30(node.length);
+    _writeDocumentationCommentString(node.documentationComment);
+
+    _writeDeclarationName(node.name);
+    _storeDeclaration(node);
   }
 
   @override
-  LinkedNodeBuilder visitEmptyFunctionBody(EmptyFunctionBody node) {
-    var builder = LinkedNodeBuilder.emptyFunctionBody();
-    _storeFunctionBody(builder, node);
-    return builder;
-  }
-
-  @override
-  LinkedNodeBuilder visitEmptyStatement(EmptyStatement node) {
-    return LinkedNodeBuilder.emptyStatement();
-  }
-
-  @override
-  LinkedNodeBuilder visitEnumConstantDeclaration(EnumConstantDeclaration node) {
-    var builder = LinkedNodeBuilder.enumConstantDeclaration(
-      informativeId: getInformativeId(node),
-    );
-    builder..name = node.name.name;
-    _storeDeclaration(builder, node);
-    return builder;
-  }
-
-  @override
-  LinkedNodeBuilder visitEnumDeclaration(EnumDeclaration node) {
-    var builder = LinkedNodeBuilder.enumDeclaration(
-      enumDeclaration_constants: _writeNodeList(node.constants),
-    );
-    _storeNamedCompilationUnitMember(builder, node);
-    return builder;
-  }
-
-  @override
-  LinkedNodeBuilder visitExportDirective(ExportDirective node) {
-    timerAstBinaryWriterDirective.start();
-    try {
-      var builder = LinkedNodeBuilder.exportDirective();
-      _storeNamespaceDirective(builder, node);
-      return builder;
-    } finally {
-      timerAstBinaryWriterDirective.stop();
-    }
-  }
-
-  @override
-  LinkedNodeBuilder visitExpressionFunctionBody(ExpressionFunctionBody node) {
-    timerAstBinaryWriterFunctionBody.start();
-    try {
-      var builder = LinkedNodeBuilder.expressionFunctionBody(
-        expressionFunctionBody_expression: node.expression.accept(this),
-      );
-      builder.flags = AstBinaryFlags.encode(
-        isAsync: node.keyword?.keyword == Keyword.ASYNC,
-        isSync: node.keyword?.keyword == Keyword.SYNC,
-      );
-      return builder;
-    } finally {
-      timerAstBinaryWriterFunctionBody.stop();
-    }
-  }
-
-  @override
-  LinkedNodeBuilder visitExpressionStatement(ExpressionStatement node) {
-    return LinkedNodeBuilder.expressionStatement(
-      expressionStatement_expression: node.expression.accept(this),
-    );
-  }
-
-  @override
-  LinkedNodeBuilder visitExtendsClause(ExtendsClause node) {
-    return LinkedNodeBuilder.extendsClause(
-      extendsClause_superclass: node.superclass.accept(this),
-    );
-  }
-
-  @override
-  LinkedNodeBuilder visitExtensionDeclaration(ExtensionDeclaration node) {
-    var builder = LinkedNodeBuilder.extensionDeclaration(
-      extensionDeclaration_extendedType: node.extendedType.accept(this),
-      extensionDeclaration_members: _writeNodeList(node.members),
-      extensionDeclaration_typeParameters: node.typeParameters?.accept(this),
-    );
-
-    _storeCompilationUnitMember(builder, node);
-    _storeInformativeId(builder, node);
-    builder.name = node.name?.name;
-    LazyExtensionDeclaration.get(node).put(builder);
-
-    return builder;
-  }
-
-  @override
-  LinkedNodeBuilder visitExtensionOverride(ExtensionOverride node) {
-    var builder = LinkedNodeBuilder.extensionOverride(
-      extensionOverride_arguments: _writeNodeList(
-        node.argumentList.arguments,
+  void visitEnumDeclaration(EnumDeclaration node) {
+    var resolutionIndex = _resolutionUnit.enterDeclaration();
+    unitMemberIndexItems.add(
+      _UnitMemberIndexItem(
+        offset: _sink.offset,
+        tag: Tag.EnumDeclaration,
+        name: node.name.name,
       ),
-      extensionOverride_extensionName: node.extensionName.accept(this),
-      extensionOverride_typeArguments: node.typeArguments?.accept(this),
-      extensionOverride_typeArgumentTypes:
-          node.typeArgumentTypes.map(_writeType).toList(),
-      extensionOverride_extendedType: _writeType(node.extendedType),
     );
-    return builder;
+
+    _writeByte(Tag.EnumDeclaration);
+
+    _writeInformativeUint30(node.offset);
+    _writeInformativeUint30(node.length);
+    _writeDocumentationCommentString(node.documentationComment);
+
+    _writeNodeList(node.constants);
+    _storeNamedCompilationUnitMember(node);
+    _writeUInt30(resolutionIndex);
   }
 
   @override
-  LinkedNodeBuilder visitFieldDeclaration(FieldDeclaration node) {
-    var builder = LinkedNodeBuilder.fieldDeclaration(
-      fieldDeclaration_fields: node.fields.accept(this),
-      informativeId: getInformativeId(node),
-    );
-    builder.flags = AstBinaryFlags.encode(
-      isAbstract: node.abstractKeyword != null,
-      isCovariant: node.covariantKeyword != null,
-      isExternal: node.externalKeyword != null,
-      isStatic: node.staticKeyword != null,
-    );
-    _storeClassMember(builder, node);
+  void visitExportDirective(ExportDirective node) {
+    var resolutionIndex = _resolutionUnit.enterDeclaration();
 
-    return builder;
-  }
+    _writeByte(Tag.ExportDirective);
+    _storeNamespaceDirective(node);
+    _writeUInt30(resolutionIndex);
 
-  @override
-  LinkedNodeBuilder visitFieldFormalParameter(FieldFormalParameter node) {
-    var builder = LinkedNodeBuilder.fieldFormalParameter(
-      fieldFormalParameter_formalParameters: node.parameters?.accept(this),
-      fieldFormalParameter_type: node.type?.accept(this),
-      fieldFormalParameter_typeParameters: node.typeParameters?.accept(this),
-    );
-    _storeNormalFormalParameter(builder, node, node.keyword);
-    builder.flags |= AstBinaryFlags.encode(hasQuestion: node.question != null);
-    return builder;
-  }
-
-  @override
-  LinkedNodeBuilder visitForEachPartsWithDeclaration(
-      ForEachPartsWithDeclaration node) {
-    var builder = LinkedNodeBuilder.forEachPartsWithDeclaration(
-      forEachPartsWithDeclaration_loopVariable: node.loopVariable.accept(this),
-    );
-    _storeForEachParts(builder, node);
-    return builder;
-  }
-
-  @override
-  LinkedNodeBuilder visitForEachPartsWithIdentifier(
-      ForEachPartsWithIdentifier node) {
-    var builder = LinkedNodeBuilder.forEachPartsWithIdentifier(
-      forEachPartsWithIdentifier_identifier: node.identifier.accept(this),
-    );
-    _storeForEachParts(builder, node);
-    return builder;
-  }
-
-  @override
-  LinkedNodeBuilder visitForElement(ForElement node) {
-    var builder = LinkedNodeBuilder.forElement(
-      forElement_body: node.body.accept(this),
-    );
-    _storeForMixin(builder, node as ForElementImpl);
-    return builder;
-  }
-
-  @override
-  LinkedNodeBuilder visitFormalParameterList(FormalParameterList node) {
-    var builder = LinkedNodeBuilder.formalParameterList(
-      formalParameterList_parameters: _writeNodeList(node.parameters),
-    );
-    builder.flags = AstBinaryFlags.encode(
-      isDelimiterCurly:
-          node.leftDelimiter?.type == TokenType.OPEN_CURLY_BRACKET,
-      isDelimiterSquare:
-          node.leftDelimiter?.type == TokenType.OPEN_SQUARE_BRACKET,
-    );
-    return builder;
-  }
-
-  @override
-  LinkedNodeBuilder visitForPartsWithDeclarations(
-      ForPartsWithDeclarations node) {
-    var builder = LinkedNodeBuilder.forPartsWithDeclarations(
-      forPartsWithDeclarations_variables: node.variables.accept(this),
-    );
-    _storeForParts(builder, node);
-    return builder;
-  }
-
-  @override
-  LinkedNodeBuilder visitForPartsWithExpression(ForPartsWithExpression node) {
-    var builder = LinkedNodeBuilder.forPartsWithExpression(
-      forPartsWithExpression_initialization: node.initialization?.accept(this),
-    );
-    _storeForParts(builder, node);
-    return builder;
-  }
-
-  @override
-  LinkedNodeBuilder visitForStatement(ForStatement node) {
-    var builder = LinkedNodeBuilder.forStatement(
-      forStatement_body: node.body.accept(this),
-    );
-    _storeForMixin(builder, node as ForStatementImpl);
-    return builder;
-  }
-
-  @override
-  LinkedNodeBuilder visitFunctionDeclaration(FunctionDeclaration node) {
-    var builder = LinkedNodeBuilder.functionDeclaration(
-      functionDeclaration_returnType: node.returnType?.accept(this),
-      functionDeclaration_functionExpression:
-          node.functionExpression?.accept(this),
-    );
-    builder.flags = AstBinaryFlags.encode(
-      isExternal: node.externalKeyword != null,
-      isGet: node.isGetter,
-      isSet: node.isSetter,
-    );
-    _storeNamedCompilationUnitMember(builder, node);
-    _writeActualReturnType(builder, node);
-    return builder;
-  }
-
-  @override
-  LinkedNodeBuilder visitFunctionDeclarationStatement(
-      FunctionDeclarationStatement node) {
-    return LinkedNodeBuilder.functionDeclarationStatement(
-      functionDeclarationStatement_functionDeclaration:
-          node.functionDeclaration.accept(this),
+    _resolutionSink?.writeElement(
+      (node.element as ExportElementImpl).exportedLibrary,
     );
   }
 
   @override
-  LinkedNodeBuilder visitFunctionExpression(FunctionExpression node) {
-    var bodyToStore = node.body;
-    if (node.parent.parent is CompilationUnit) {
-      bodyToStore = null;
-    }
-    var builder = LinkedNodeBuilder.functionExpression(
-      functionExpression_typeParameters: node.typeParameters?.accept(this),
-      functionExpression_formalParameters: node.parameters?.accept(this),
-      functionExpression_body: bodyToStore?.accept(this),
-    );
-    builder.flags = AstBinaryFlags.encode(
-      isAsync: node.body?.isAsynchronous ?? false,
-      isGenerator: node.body?.isGenerator ?? false,
-    );
-    return builder;
+  void visitExtendsClause(ExtendsClause node) {
+    _writeByte(Tag.ExtendsClause);
+    _writeNode(node.superclass);
   }
 
   @override
-  LinkedNodeBuilder visitFunctionExpressionInvocation(
-      FunctionExpressionInvocation node) {
-    var builder = LinkedNodeBuilder.functionExpressionInvocation(
-      functionExpressionInvocation_function: node.function?.accept(this),
+  void visitExtensionDeclaration(ExtensionDeclaration node) {
+    var classOffset = _sink.offset;
+    var resolutionIndex = _resolutionUnit.enterDeclaration();
+
+    _writeByte(Tag.ExtensionDeclaration);
+
+    _writeInformativeUint30(node.offset);
+    _writeInformativeUint30(node.length);
+    _writeDocumentationCommentString(node.documentationComment);
+
+    _pushScopeTypeParameters(node.typeParameters);
+    _writeOptionalNode(node.typeParameters);
+    _writeNode(node.extendedType);
+    _writeOptionalDeclarationName(node.name);
+    _storeCompilationUnitMember(node);
+    _writeUInt30(resolutionIndex);
+
+    _classMemberIndexItems.clear();
+    _writeNodeList(node.members);
+
+    _resolutionSink.localElements.popScope();
+
+    // TODO(scheglov) write member index
+    var classIndexOffset = _sink.offset;
+    _writeClassMemberIndex();
+
+    var nameIdentifier = node.name;
+    var indexName = nameIdentifier != null
+        ? nameIdentifier.name
+        : 'extension-${_nextUnnamedExtensionId++}';
+    unitMemberIndexItems.add(
+      _UnitMemberIndexItem(
+        offset: classOffset,
+        tag: Tag.ExtensionDeclaration,
+        name: indexName,
+        classIndexOffset: classIndexOffset,
+      ),
     );
-    _storeInvocationExpression(builder, node);
-    return builder;
   }
 
   @override
-  LinkedNodeBuilder visitFunctionTypeAlias(FunctionTypeAlias node) {
-    timerAstBinaryWriterTypedef.start();
+  void visitExtensionOverride(ExtensionOverride node) {
+    _writeByte(Tag.ExtensionOverride);
+    _writeNode(node.extensionName);
+    _writeOptionalNode(node.typeArguments);
+    _writeNode(node.argumentList);
+    _resolutionSink.writeType(node.extendedType);
+    // TODO(scheglov) typeArgumentTypes?
+  }
+
+  @override
+  void visitFieldDeclaration(FieldDeclaration node) {
+    _classMemberIndexItems.add(
+      _ClassMemberIndexItem(
+        offset: _sink.offset,
+        tag: Tag.FieldDeclaration,
+        fieldNames: node.fields.variables.map((e) => e.name.name).toList(),
+      ),
+    );
+
+    _writeByte(Tag.FieldDeclaration);
+    _writeByte(
+      AstBinaryFlags.encode(
+        isAbstract: node.abstractKeyword != null,
+        isCovariant: node.covariantKeyword != null,
+        isExternal: node.externalKeyword != null,
+        isStatic: node.staticKeyword != null,
+      ),
+    );
+
+    _writeInformativeVariableCodeRanges(node.offset, node.fields);
+    _writeDocumentationCommentString(node.documentationComment);
+
+    var resolutionIndex = _resolutionUnit.enterDeclaration();
+
+    _isConstField = node.fields.isConst;
+    _isFinalField = node.fields.isFinal;
     try {
-      var builder = LinkedNodeBuilder.functionTypeAlias(
-        functionTypeAlias_formalParameters: node.parameters.accept(this),
-        functionTypeAlias_returnType: node.returnType?.accept(this),
-        functionTypeAlias_typeParameters: node.typeParameters?.accept(this),
-        typeAlias_hasSelfReference:
-            LazyFunctionTypeAlias.getHasSelfReference(node),
-      );
-      _storeTypeAlias(builder, node);
-      _writeActualReturnType(builder, node);
-      _storeIsSimpleBounded(builder, node);
-      return builder;
+      _writeNode(node.fields);
     } finally {
-      timerAstBinaryWriterTypedef.stop();
+      _isConstField = false;
+      _isFinalField = false;
     }
+
+    _storeClassMember(node);
+
+    _writeUInt30(resolutionIndex);
   }
 
   @override
-  LinkedNodeBuilder visitFunctionTypedFormalParameter(
-      FunctionTypedFormalParameter node) {
-    var builder = LinkedNodeBuilder.functionTypedFormalParameter(
-      functionTypedFormalParameter_formalParameters:
-          node.parameters.accept(this),
-      functionTypedFormalParameter_returnType: node.returnType?.accept(this),
-      functionTypedFormalParameter_typeParameters:
-          node.typeParameters?.accept(this),
-    );
-    _storeNormalFormalParameter(builder, node, null);
-    return builder;
-  }
+  void visitFieldFormalParameter(FieldFormalParameter node) {
+    _writeByte(Tag.FieldFormalParameter);
 
-  @override
-  LinkedNodeBuilder visitGenericFunctionType(GenericFunctionType node) {
-    var id = LazyAst.getGenericFunctionTypeId(node);
-    assert(id != null);
-
-    var builder = LinkedNodeBuilder.genericFunctionType(
-      genericFunctionType_id: id,
-      genericFunctionType_returnType: node.returnType?.accept(this),
-      genericFunctionType_typeParameters: node.typeParameters?.accept(this),
-      genericFunctionType_formalParameters: node.parameters.accept(this),
-      genericFunctionType_type: _writeType(node.type),
-    );
-    builder.flags = AstBinaryFlags.encode(
+    _pushScopeTypeParameters(node.typeParameters);
+    _writeOptionalNode(node.typeParameters);
+    _writeOptionalNode(node.type);
+    _writeOptionalNode(node.parameters);
+    _storeNormalFormalParameter(
+      node,
+      node.keyword,
       hasQuestion: node.question != null,
     );
-    _writeActualReturnType(builder, node);
-
-    return builder;
+    _resolutionSink.localElements.popScope();
   }
 
   @override
-  LinkedNodeBuilder visitGenericTypeAlias(GenericTypeAlias node) {
-    timerAstBinaryWriterTypedef.start();
-    try {
-      var builder = LinkedNodeBuilder.genericTypeAlias(
-        genericTypeAlias_typeParameters: node.typeParameters?.accept(this),
-        genericTypeAlias_functionType: node.functionType?.accept(this),
-        typeAlias_hasSelfReference:
-            LazyGenericTypeAlias.getHasSelfReference(node),
-      );
-      _storeTypeAlias(builder, node);
-      _storeIsSimpleBounded(builder, node);
-      return builder;
-    } finally {
-      timerAstBinaryWriterTypedef.stop();
+  void visitForEachPartsWithDeclaration(ForEachPartsWithDeclaration node) {
+    _writeByte(Tag.ForEachPartsWithDeclaration);
+    _writeNode(node.loopVariable);
+    _storeForEachParts(node);
+  }
+
+  @override
+  void visitForElement(ForElement node) {
+    _writeByte(Tag.ForElement);
+    _writeNode(node.body);
+    _storeForMixin(node as ForElementImpl);
+  }
+
+  @override
+  void visitFormalParameterList(FormalParameterList node) {
+    _writeByte(Tag.FormalParameterList);
+
+    var leftDelimiter = node.leftDelimiter?.type;
+    _writeByte(
+      AstBinaryFlags.encode(
+        isDelimiterCurly: leftDelimiter == TokenType.OPEN_CURLY_BRACKET,
+        isDelimiterSquare: leftDelimiter == TokenType.OPEN_SQUARE_BRACKET,
+      ),
+    );
+
+    _writeNodeList(node.parameters);
+  }
+
+  @override
+  void visitForPartsWithDeclarations(ForPartsWithDeclarations node) {
+    _writeByte(Tag.ForPartsWithDeclarations);
+    _writeNode(node.variables);
+    _storeForParts(node);
+  }
+
+  @override
+  void visitFunctionDeclaration(FunctionDeclaration node) {
+    var indexTag = Tag.FunctionDeclaration;
+    if (node.isGetter) {
+      indexTag = Tag.FunctionDeclaration_getter;
+    } else if (node.isSetter) {
+      indexTag = Tag.FunctionDeclaration_setter;
     }
-  }
-
-  @override
-  LinkedNodeBuilder visitHideCombinator(HideCombinator node) {
-    var builder = LinkedNodeBuilder.hideCombinator(
-      names: node.hiddenNames.map((id) => id.name).toList(),
+    unitMemberIndexItems.add(
+      _UnitMemberIndexItem(
+        offset: _sink.offset,
+        tag: indexTag,
+        name: node.name.name,
+        variableNames: null,
+      ),
     );
-    _storeInformativeId(builder, node);
-    return builder;
-  }
 
-  @override
-  LinkedNodeBuilder visitIfElement(IfElement node) {
-    var builder = LinkedNodeBuilder.ifElement(
-      ifMixin_condition: node.condition.accept(this),
-      ifElement_elseElement: node.elseElement?.accept(this),
-      ifElement_thenElement: node.thenElement.accept(this),
+    _writeByte(Tag.FunctionDeclaration);
+
+    _writeByte(
+      AstBinaryFlags.encode(
+        isExternal: node.externalKeyword != null,
+        isGet: node.isGetter,
+        isSet: node.isSetter,
+      ),
     );
-    return builder;
+
+    _writeInformativeUint30(node.offset);
+    _writeInformativeUint30(node.length);
+    _writeDocumentationCommentString(node.documentationComment);
+
+    var resolutionIndex = _resolutionUnit.enterDeclaration();
+
+    _pushScopeTypeParameters(node.functionExpression.typeParameters);
+
+    _writeNode(node.functionExpression);
+    _writeOptionalNode(node.returnType);
+    _storeNamedCompilationUnitMember(node);
+    _writeActualReturnType(node.declaredElement.returnType);
+
+    _resolutionSink.localElements.popScope();
+
+    _writeUInt30(resolutionIndex);
   }
 
   @override
-  LinkedNodeBuilder visitIfStatement(IfStatement node) {
-    var builder = LinkedNodeBuilder.ifStatement(
-      ifMixin_condition: node.condition.accept(this),
-      ifStatement_elseStatement: node.elseStatement?.accept(this),
-      ifStatement_thenStatement: node.thenStatement.accept(this),
+  void visitFunctionExpression(FunctionExpression node) {
+    _writeByte(Tag.FunctionExpression);
+
+    var body = node.body;
+    _writeByte(
+      AstBinaryFlags.encode(
+        isAsync: body?.isAsynchronous ?? false,
+        isGenerator: body?.isGenerator ?? false,
+      ),
     );
-    return builder;
+
+    _writeOptionalNode(node.typeParameters);
+    _writeOptionalNode(node.parameters);
   }
 
   @override
-  LinkedNodeBuilder visitImplementsClause(ImplementsClause node) {
-    return LinkedNodeBuilder.implementsClause(
-      implementsClause_interfaces: _writeNodeList(node.interfaces),
+  void visitFunctionExpressionInvocation(FunctionExpressionInvocation node) {
+    _writeByte(Tag.FunctionExpressionInvocation);
+    _writeNode(node.function);
+    _storeInvocationExpression(node);
+  }
+
+  @override
+  void visitFunctionTypeAlias(FunctionTypeAlias node) {
+    unitMemberIndexItems.add(
+      _UnitMemberIndexItem(
+        offset: _sink.offset,
+        tag: Tag.FunctionTypeAlias,
+        name: node.name.name,
+        variableNames: null,
+      ),
     );
+
+    _writeByte(Tag.FunctionTypeAlias);
+
+    _writeInformativeUint30(node.offset);
+    _writeInformativeUint30(node.length);
+    _writeDocumentationCommentString(node.documentationComment);
+
+    var resolutionIndex = _resolutionUnit.enterDeclaration();
+
+    _pushScopeTypeParameters(node.typeParameters);
+
+    _writeOptionalNode(node.typeParameters);
+    _writeOptionalNode(node.returnType);
+    _writeNode(node.parameters);
+
+    _storeTypeAlias(node);
+
+    var element = node.declaredElement as FunctionTypeAliasElementImpl;
+    _writeActualReturnType(element.function.returnType);
+    // TODO(scheglov) pack into one byte
+    _resolutionSink.writeByte(element.isSimplyBounded ? 1 : 0);
+    _resolutionSink.writeByte(element.hasSelfReference ? 1 : 0);
+
+    _resolutionSink.localElements.popScope();
+
+    _writeUInt30(resolutionIndex);
   }
 
   @override
-  LinkedNodeBuilder visitImportDirective(ImportDirective node) {
-    timerAstBinaryWriterDirective.start();
-    try {
-      var builder = LinkedNodeBuilder.importDirective(
-        importDirective_prefix: node.prefix?.name,
-      );
-      builder.flags = AstBinaryFlags.encode(
+  void visitFunctionTypedFormalParameter(FunctionTypedFormalParameter node) {
+    _writeByte(Tag.FunctionTypedFormalParameter);
+
+    _pushScopeTypeParameters(node.typeParameters);
+    _writeOptionalNode(node.typeParameters);
+    _writeOptionalNode(node.returnType);
+    _writeNode(node.parameters);
+    _storeNormalFormalParameter(node, null);
+    _resolutionSink.localElements.popScope();
+  }
+
+  @override
+  void visitGenericFunctionType(GenericFunctionType node) {
+    _writeByte(Tag.GenericFunctionType);
+
+    _writeByte(
+      AstBinaryFlags.encode(
+        hasQuestion: node.question != null,
+      ),
+    );
+
+    _pushScopeTypeParameters(node.typeParameters);
+
+    _writeOptionalNode(node.typeParameters);
+    _writeOptionalNode(node.returnType);
+    _writeNode(node.parameters);
+    _resolutionSink?.writeType(node.type);
+
+    _resolutionSink.localElements.popScope();
+  }
+
+  @override
+  void visitGenericTypeAlias(GenericTypeAlias node) {
+    unitMemberIndexItems.add(
+      _UnitMemberIndexItem(
+        offset: _sink.offset,
+        tag: Tag.GenericTypeAlias,
+        name: node.name.name,
+      ),
+    );
+
+    _writeByte(Tag.GenericTypeAlias);
+
+    _writeInformativeUint30(node.offset);
+    _writeInformativeUint30(node.length);
+    _writeDocumentationCommentString(node.documentationComment);
+
+    var resolutionIndex = _resolutionUnit.enterDeclaration();
+
+    _pushScopeTypeParameters(node.typeParameters);
+
+    _writeOptionalNode(node.typeParameters);
+    _writeOptionalNode(node.functionType);
+    _storeTypeAlias(node);
+
+    var element = node.declaredElement as FunctionTypeAliasElementImpl;
+    // TODO(scheglov) pack into one byte
+    _resolutionSink.writeByte(element.isSimplyBounded ? 1 : 0);
+    _resolutionSink.writeByte(element.hasSelfReference ? 1 : 0);
+
+    _resolutionSink.localElements.popScope();
+
+    _writeUInt30(resolutionIndex);
+  }
+
+  @override
+  void visitHideCombinator(HideCombinator node) {
+    _writeByte(Tag.HideCombinator);
+    _writeInformativeUint30(node.keyword.offset);
+    _writeNodeList(node.hiddenNames);
+  }
+
+  @override
+  void visitIfElement(IfElement node) {
+    _writeByte(Tag.IfElement);
+    _writeNode(node.condition);
+    _writeNode(node.thenElement);
+    _writeOptionalNode(node.elseElement);
+  }
+
+  @override
+  void visitImplementsClause(ImplementsClause node) {
+    _writeByte(Tag.ImplementsClause);
+    _writeNodeList(node.interfaces);
+  }
+
+  @override
+  void visitImportDirective(ImportDirective node) {
+    var resolutionIndex = _resolutionUnit.enterDeclaration();
+
+    _writeByte(Tag.ImportDirective);
+
+    var prefix = node.prefix;
+    _writeByte(
+      AstBinaryFlags.encode(
+        hasPrefix: prefix != null,
         isDeferred: node.deferredKeyword != null,
-      );
-      _storeNamespaceDirective(builder, node);
-      return builder;
-    } finally {
-      timerAstBinaryWriterDirective.stop();
-    }
-  }
-
-  @override
-  LinkedNodeBuilder visitIndexExpression(IndexExpression node) {
-    var elementComponents = _componentsOfElement(node.staticElement);
-    var builder = LinkedNodeBuilder.indexExpression(
-      indexExpression_element: elementComponents.rawElement,
-      indexExpression_substitution: elementComponents.substitution,
-      indexExpression_index: node.index.accept(this),
-      indexExpression_target: node.target?.accept(this),
-      expression_type: _writeType(node.staticType),
-    );
-    builder.flags = AstBinaryFlags.encode(
-      hasPeriod: node.period != null,
-      hasQuestion: node.question != null,
-    );
-    return builder;
-  }
-
-  @override
-  LinkedNodeBuilder visitInstanceCreationExpression(
-      InstanceCreationExpression node) {
-    InstanceCreationExpressionImpl nodeImpl = node;
-    var builder = LinkedNodeBuilder.instanceCreationExpression(
-      instanceCreationExpression_arguments: _writeNodeList(
-        node.argumentList.arguments,
       ),
-      instanceCreationExpression_constructorName:
-          node.constructorName.accept(this),
-      instanceCreationExpression_typeArguments:
-          nodeImpl.typeArguments?.accept(this),
-      expression_type: _writeType(node.staticType),
     );
-    builder.flags = AstBinaryFlags.encode(
-      isConst: node.keyword?.type == Keyword.CONST,
-      isNew: node.keyword?.type == Keyword.NEW,
-    );
-    return builder;
+
+    if (prefix != null) {
+      _writeStringReference(prefix.name);
+      _writeInformativeUint30(prefix.offset);
+    }
+
+    _storeNamespaceDirective(node);
+    _writeUInt30(resolutionIndex);
+
+    var element = node.element as ImportElementImpl;
+    _resolutionSink?.writeElement(element.importedLibrary);
   }
 
   @override
-  LinkedNodeBuilder visitIntegerLiteral(IntegerLiteral node) {
-    return LinkedNodeBuilder.integerLiteral(
-      expression_type: _writeType(node.staticType),
-      integerLiteral_value: node.value,
+  void visitIndexExpression(IndexExpression node) {
+    _writeByte(Tag.IndexExpression);
+    _writeByte(
+      AstBinaryFlags.encode(
+        hasPeriod: node.period != null,
+        hasQuestion: node.question != null,
+      ),
     );
+    _writeOptionalNode(node.target);
+    _writeNode(node.index);
+    _resolutionSink.writeElement(node.staticElement);
+    _storeExpression(node);
   }
 
   @override
-  LinkedNodeBuilder visitInterpolationExpression(InterpolationExpression node) {
-    return LinkedNodeBuilder.interpolationExpression(
-      interpolationExpression_expression: node.expression.accept(this),
-    )..flags = AstBinaryFlags.encode(
+  void visitInstanceCreationExpression(InstanceCreationExpression node) {
+    _writeByte(Tag.InstanceCreationExpression);
+
+    _writeByte(
+      AstBinaryFlags.encode(
+        isConst: node.keyword?.type == Keyword.CONST,
+        isNew: node.keyword?.type == Keyword.NEW,
+      ),
+    );
+
+    _writeNode(node.constructorName);
+    _writeNode(node.argumentList);
+    _storeExpression(node);
+  }
+
+  @override
+  void visitIntegerLiteral(IntegerLiteral node) {
+    var value = node.value;
+
+    if (value == null) {
+      _writeByte(Tag.IntegerLiteralNull);
+      _writeStringReference(node.literal.lexeme);
+    } else {
+      var isPositive = value >= 0;
+      if (!isPositive) {
+        value = -value;
+      }
+
+      if (value & 0xFF == value) {
+        _writeByte(
+          isPositive
+              ? Tag.IntegerLiteralPositive1
+              : Tag.IntegerLiteralNegative1,
+        );
+        _writeByte(value);
+      } else {
+        _writeByte(
+          isPositive ? Tag.IntegerLiteralPositive : Tag.IntegerLiteralNegative,
+        );
+        _writeUInt32(value >> 32);
+        _writeUInt32(value & 0xFFFFFFFF);
+      }
+    }
+
+    // TODO(scheglov) Dont write type, AKA separate true `int` and `double`?
+    _resolutionSink?.writeType(node.staticType);
+  }
+
+  @override
+  void visitInterpolationExpression(InterpolationExpression node) {
+    _writeByte(Tag.InterpolationExpression);
+    _writeByte(
+      AstBinaryFlags.encode(
         isStringInterpolationIdentifier:
             node.leftBracket.type == TokenType.STRING_INTERPOLATION_IDENTIFIER,
-      );
-  }
-
-  @override
-  LinkedNodeBuilder visitInterpolationString(InterpolationString node) {
-    return LinkedNodeBuilder.interpolationString(
-      interpolationString_value: node.value,
-    );
-  }
-
-  @override
-  LinkedNodeBuilder visitIsExpression(IsExpression node) {
-    var builder = LinkedNodeBuilder.isExpression(
-      isExpression_expression: node.expression.accept(this),
-      isExpression_type: node.type.accept(this),
-    );
-    builder.flags = AstBinaryFlags.encode(
-      hasNot: node.notOperator != null,
-    );
-    return builder;
-  }
-
-  @override
-  LinkedNodeBuilder visitLabel(Label node) {
-    return LinkedNodeBuilder.label(
-      label_label: node.label.accept(this),
-    );
-  }
-
-  @override
-  LinkedNodeBuilder visitLabeledStatement(LabeledStatement node) {
-    return LinkedNodeBuilder.labeledStatement(
-      labeledStatement_labels: _writeNodeList(node.labels),
-      labeledStatement_statement: node.statement.accept(this),
-    );
-  }
-
-  @override
-  LinkedNodeBuilder visitLibraryDirective(LibraryDirective node) {
-    timerAstBinaryWriterDirective.start();
-    try {
-      var builder = LinkedNodeBuilder.libraryDirective(
-        informativeId: getInformativeId(node),
-        libraryDirective_name: node.name.accept(this),
-      );
-      _storeDirective(builder, node);
-      return builder;
-    } finally {
-      timerAstBinaryWriterDirective.stop();
-    }
-  }
-
-  @override
-  LinkedNodeBuilder visitLibraryIdentifier(LibraryIdentifier node) {
-    return LinkedNodeBuilder.libraryIdentifier(
-      libraryIdentifier_components: _writeNodeList(node.components),
-    );
-  }
-
-  @override
-  LinkedNodeBuilder visitListLiteral(ListLiteral node) {
-    var builder = LinkedNodeBuilder.listLiteral(
-      listLiteral_elements: _writeNodeList(node.elements),
-    );
-    _storeTypedLiteral(builder, node);
-    return builder;
-  }
-
-  @override
-  LinkedNodeBuilder visitMapLiteralEntry(MapLiteralEntry node) {
-    return LinkedNodeBuilder.mapLiteralEntry(
-      mapLiteralEntry_key: node.key.accept(this),
-      mapLiteralEntry_value: node.value.accept(this),
-    );
-  }
-
-  @override
-  LinkedNodeBuilder visitMethodDeclaration(MethodDeclaration node) {
-    var builder = LinkedNodeBuilder.methodDeclaration(
-      methodDeclaration_returnType: node.returnType?.accept(this),
-      methodDeclaration_typeParameters: node.typeParameters?.accept(this),
-      methodDeclaration_formalParameters: node.parameters?.accept(this),
-      methodDeclaration_hasOperatorEqualWithParameterTypeFromObject:
-          LazyAst.hasOperatorEqualParameterTypeFromObject(node),
-    );
-    builder.name = node.name.name;
-    builder.flags = AstBinaryFlags.encode(
-      isAbstract: node.body is EmptyFunctionBody,
-      isAsync: node.body?.isAsynchronous ?? false,
-      isExternal: node.externalKeyword != null,
-      isGenerator: node.body?.isGenerator ?? false,
-      isGet: node.isGetter,
-      isNative: node.body is NativeFunctionBody,
-      isOperator: node.operatorKeyword != null,
-      isSet: node.isSetter,
-      isStatic: node.isStatic,
-    );
-    builder.topLevelTypeInferenceError = LazyAst.getTypeInferenceError(node);
-    _storeClassMember(builder, node);
-    _storeInformativeId(builder, node);
-    _writeActualReturnType(builder, node);
-    return builder;
-  }
-
-  @override
-  LinkedNodeBuilder visitMethodInvocation(MethodInvocation node) {
-    var builder = LinkedNodeBuilder.methodInvocation(
-      methodInvocation_methodName: node.methodName?.accept(this),
-      methodInvocation_target: node.target?.accept(this),
-    );
-    builder.flags = AstBinaryFlags.encode(
-      hasPeriod: node.operator?.type == TokenType.PERIOD,
-      hasPeriod2: node.operator?.type == TokenType.PERIOD_PERIOD,
-    );
-    _storeInvocationExpression(builder, node);
-    return builder;
-  }
-
-  @override
-  LinkedNodeBuilder visitMixinDeclaration(MixinDeclaration node) {
-    timerAstBinaryWriterMixin.start();
-    try {
-      var builder = LinkedNodeBuilder.mixinDeclaration(
-        mixinDeclaration_onClause: node.onClause?.accept(this),
-      );
-      _storeClassOrMixinDeclaration(builder, node);
-      LazyMixinDeclaration.get(node).put(builder);
-      return builder;
-    } finally {
-      timerAstBinaryWriterMixin.stop();
-    }
-  }
-
-  @override
-  LinkedNodeBuilder visitNamedExpression(NamedExpression node) {
-    return LinkedNodeBuilder.namedExpression(
-      namedExpression_expression: node.expression.accept(this),
-      namedExpression_name: node.name.accept(this),
-    );
-  }
-
-  @override
-  LinkedNodeBuilder visitNativeClause(NativeClause node) {
-    return LinkedNodeBuilder.nativeClause(
-      nativeClause_name: node.name.accept(this),
-    );
-  }
-
-  @override
-  LinkedNodeBuilder visitNativeFunctionBody(NativeFunctionBody node) {
-    return LinkedNodeBuilder.nativeFunctionBody(
-      nativeFunctionBody_stringLiteral: node.stringLiteral?.accept(this),
-    );
-  }
-
-  @override
-  LinkedNodeBuilder visitNullLiteral(NullLiteral node) {
-    return LinkedNodeBuilder.nullLiteral();
-  }
-
-  @override
-  LinkedNodeBuilder visitOnClause(OnClause node) {
-    return LinkedNodeBuilder.onClause(
-      onClause_superclassConstraints:
-          _writeNodeList(node.superclassConstraints),
-    );
-  }
-
-  @override
-  LinkedNodeBuilder visitParenthesizedExpression(ParenthesizedExpression node) {
-    var builder = LinkedNodeBuilder.parenthesizedExpression(
-      parenthesizedExpression_expression: node.expression.accept(this),
-    );
-    _storeExpression(builder, node);
-    return builder;
-  }
-
-  @override
-  LinkedNodeBuilder visitPartDirective(PartDirective node) {
-    timerAstBinaryWriterDirective.start();
-    try {
-      var builder = LinkedNodeBuilder.partDirective();
-      _storeUriBasedDirective(builder, node);
-      return builder;
-    } finally {
-      timerAstBinaryWriterDirective.stop();
-    }
-  }
-
-  @override
-  LinkedNodeBuilder visitPartOfDirective(PartOfDirective node) {
-    timerAstBinaryWriterDirective.start();
-    try {
-      var builder = LinkedNodeBuilder.partOfDirective(
-        partOfDirective_libraryName: node.libraryName?.accept(this),
-        partOfDirective_uri: node.uri?.accept(this),
-      );
-      _storeDirective(builder, node);
-      return builder;
-    } finally {
-      timerAstBinaryWriterDirective.stop();
-    }
-  }
-
-  @override
-  LinkedNodeBuilder visitPostfixExpression(PostfixExpression node) {
-    var elementComponents = _componentsOfElement(node.staticElement);
-    return LinkedNodeBuilder.postfixExpression(
-      expression_type: _writeType(node.staticType),
-      postfixExpression_element: elementComponents.rawElement,
-      postfixExpression_substitution: elementComponents.substitution,
-      postfixExpression_operand: node.operand.accept(this),
-      postfixExpression_operator: TokensWriter.astToBinaryTokenType(
-        node.operator.type,
       ),
     );
+    _writeNode(node.expression);
   }
 
   @override
-  LinkedNodeBuilder visitPrefixedIdentifier(PrefixedIdentifier node) {
-    return LinkedNodeBuilder.prefixedIdentifier(
-      prefixedIdentifier_identifier: node.identifier.accept(this),
-      prefixedIdentifier_prefix: node.prefix.accept(this),
-      expression_type: _writeType(node.staticType),
-    );
+  void visitInterpolationString(InterpolationString node) {
+    _writeByte(Tag.InterpolationString);
+    _writeStringReference(node.value);
   }
 
   @override
-  LinkedNodeBuilder visitPrefixExpression(PrefixExpression node) {
-    var elementComponents = _componentsOfElement(node.staticElement);
-    return LinkedNodeBuilder.prefixExpression(
-      expression_type: _writeType(node.staticType),
-      prefixExpression_element: elementComponents.rawElement,
-      prefixExpression_substitution: elementComponents.substitution,
-      prefixExpression_operand: node.operand.accept(this),
-      prefixExpression_operator: TokensWriter.astToBinaryTokenType(
-        node.operator.type,
+  void visitIsExpression(IsExpression node) {
+    _writeByte(Tag.IsExpression);
+    _writeByte(
+      AstBinaryFlags.encode(
+        hasNot: node.notOperator != null,
       ),
     );
+    _writeNode(node.expression);
+    _writeNode(node.type);
+    _storeExpression(node);
   }
 
   @override
-  LinkedNodeBuilder visitPropertyAccess(PropertyAccess node) {
-    var builder = LinkedNodeBuilder.propertyAccess(
-      propertyAccess_operator: TokensWriter.astToBinaryTokenType(
-        node.operator.type,
+  void visitLibraryDirective(LibraryDirective node) {
+    _writeByte(Tag.LibraryDirective);
+    _writeDocumentationCommentString(node.documentationComment);
+    visitLibraryIdentifier(node.name);
+    _storeDirective(node);
+  }
+
+  @override
+  void visitLibraryIdentifier(LibraryIdentifier node) {
+    _writeByte(Tag.LibraryIdentifier);
+    _writeNodeList(node.components);
+  }
+
+  @override
+  void visitListLiteral(ListLiteral node) {
+    _writeByte(Tag.ListLiteral);
+
+    _writeByte(
+      AstBinaryFlags.encode(
+        isConst: node.constKeyword != null,
       ),
-      propertyAccess_propertyName: node.propertyName.accept(this),
-      propertyAccess_target: node.target?.accept(this),
     );
-    _storeExpression(builder, node);
-    return builder;
+
+    _writeOptionalNode(node.typeArguments);
+    _writeNodeList(node.elements);
+
+    _storeExpression(node);
   }
 
   @override
-  LinkedNodeBuilder visitRedirectingConstructorInvocation(
-      RedirectingConstructorInvocation node) {
-    var elementComponents = _componentsOfElement(node.staticElement);
-    var builder = LinkedNodeBuilder.redirectingConstructorInvocation(
-      redirectingConstructorInvocation_arguments:
-          node.argumentList.accept(this),
-      redirectingConstructorInvocation_constructorName:
-          node.constructorName?.accept(this),
-      redirectingConstructorInvocation_element: elementComponents.rawElement,
-      redirectingConstructorInvocation_substitution:
-          elementComponents.substitution,
-    );
-    builder.flags = AstBinaryFlags.encode(
-      hasThis: node.thisKeyword != null,
-    );
-    _storeConstructorInitializer(builder, node);
-    return builder;
+  void visitMapLiteralEntry(MapLiteralEntry node) {
+    _writeByte(Tag.MapLiteralEntry);
+    _writeNode(node.key);
+    _writeNode(node.value);
   }
 
   @override
-  LinkedNodeBuilder visitRethrowExpression(RethrowExpression node) {
-    return LinkedNodeBuilder.rethrowExpression(
-      expression_type: _writeType(node.staticType),
-    );
-  }
-
-  @override
-  LinkedNodeBuilder visitReturnStatement(ReturnStatement node) {
-    return LinkedNodeBuilder.returnStatement(
-      returnStatement_expression: node.expression?.accept(this),
-    );
-  }
-
-  @override
-  LinkedNodeBuilder visitScriptTag(ScriptTag node) {
-    return null;
-  }
-
-  @override
-  LinkedNodeBuilder visitSetOrMapLiteral(SetOrMapLiteral node) {
-    var builder = LinkedNodeBuilder.setOrMapLiteral(
-      setOrMapLiteral_elements: _writeNodeList(node.elements),
-    );
-    _storeTypedLiteral(builder, node, isMap: node.isMap, isSet: node.isSet);
-    return builder;
-  }
-
-  @override
-  LinkedNodeBuilder visitShowCombinator(ShowCombinator node) {
-    var builder = LinkedNodeBuilder.showCombinator(
-      names: node.shownNames.map((id) => id.name).toList(),
-    );
-    _storeInformativeId(builder, node);
-    return builder;
-  }
-
-  @override
-  LinkedNodeBuilder visitSimpleFormalParameter(SimpleFormalParameter node) {
-    var builder = LinkedNodeBuilder.simpleFormalParameter(
-      simpleFormalParameter_type: node.type?.accept(this),
-    );
-    builder.topLevelTypeInferenceError = LazyAst.getTypeInferenceError(node);
-    _storeNormalFormalParameter(builder, node, node.keyword);
-    _storeInheritsCovariant(builder, node);
-    return builder;
-  }
-
-  @override
-  LinkedNodeBuilder visitSimpleIdentifier(SimpleIdentifier node) {
-    Element element;
-    if (!node.inDeclarationContext()) {
-      element = node.staticElement;
-      if (element is MultiplyDefinedElement) {
-        element = null;
-      }
+  void visitMethodDeclaration(MethodDeclaration node) {
+    var indexTag = Tag.MethodDeclaration;
+    if (node.isGetter) {
+      indexTag = Tag.MethodDeclaration_getter;
+    } else if (node.isSetter) {
+      indexTag = Tag.MethodDeclaration_setter;
     }
-
-    var elementComponents = _componentsOfElement(element);
-    var builder = LinkedNodeBuilder.simpleIdentifier(
-      simpleIdentifier_element: elementComponents.rawElement,
-      simpleIdentifier_substitution: elementComponents.substitution,
-      expression_type: _writeType(node.staticType),
-    );
-    builder.flags = AstBinaryFlags.encode(
-      isDeclaration: node is DeclaredSimpleIdentifier,
-    );
-    builder.name = node.name;
-    return builder;
-  }
-
-  @override
-  LinkedNodeBuilder visitSimpleStringLiteral(SimpleStringLiteral node) {
-    var builder = LinkedNodeBuilder.simpleStringLiteral(
-      simpleStringLiteral_value: node.value,
-    );
-    return builder;
-  }
-
-  @override
-  LinkedNodeBuilder visitSpreadElement(SpreadElement node) {
-    return LinkedNodeBuilder.spreadElement(
-      spreadElement_expression: node.expression.accept(this),
-      spreadElement_spreadOperator: TokensWriter.astToBinaryTokenType(
-        node.spreadOperator.type,
+    _classMemberIndexItems.add(
+      _ClassMemberIndexItem(
+        offset: _sink.offset,
+        tag: indexTag,
+        name: node.name.name,
       ),
     );
-  }
 
-  @override
-  LinkedNodeBuilder visitStringInterpolation(StringInterpolation node) {
-    return LinkedNodeBuilder.stringInterpolation(
-      stringInterpolation_elements: _writeNodeList(node.elements),
-    );
-  }
+    _writeByte(Tag.MethodDeclaration);
 
-  @override
-  LinkedNodeBuilder visitSuperConstructorInvocation(
-      SuperConstructorInvocation node) {
-    var elementComponents = _componentsOfElement(node.staticElement);
-    var builder = LinkedNodeBuilder.superConstructorInvocation(
-      superConstructorInvocation_arguments: node.argumentList.accept(this),
-      superConstructorInvocation_constructorName:
-          node.constructorName?.accept(this),
-      superConstructorInvocation_element: elementComponents.rawElement,
-      superConstructorInvocation_substitution: elementComponents.substitution,
-    );
-    _storeConstructorInitializer(builder, node);
-    return builder;
-  }
-
-  @override
-  LinkedNodeBuilder visitSuperExpression(SuperExpression node) {
-    var builder = LinkedNodeBuilder.superExpression();
-    _storeExpression(builder, node);
-    return builder;
-  }
-
-  @override
-  LinkedNodeBuilder visitSwitchCase(SwitchCase node) {
-    var builder = LinkedNodeBuilder.switchCase(
-      switchCase_expression: node.expression.accept(this),
-    );
-    _storeSwitchMember(builder, node);
-    return builder;
-  }
-
-  @override
-  LinkedNodeBuilder visitSwitchDefault(SwitchDefault node) {
-    var builder = LinkedNodeBuilder.switchDefault();
-    _storeSwitchMember(builder, node);
-    return builder;
-  }
-
-  @override
-  LinkedNodeBuilder visitSwitchStatement(SwitchStatement node) {
-    return LinkedNodeBuilder.switchStatement(
-      switchStatement_expression: node.expression.accept(this),
-      switchStatement_members: _writeNodeList(node.members),
-    );
-  }
-
-  @override
-  LinkedNodeBuilder visitSymbolLiteral(SymbolLiteral node) {
-    var builder = LinkedNodeBuilder.symbolLiteral(
-      names: node.components.map((t) => t.lexeme).toList(),
-    );
-    _storeExpression(builder, node);
-    return builder;
-  }
-
-  @override
-  LinkedNodeBuilder visitThisExpression(ThisExpression node) {
-    var builder = LinkedNodeBuilder.thisExpression();
-    _storeExpression(builder, node);
-    return builder;
-  }
-
-  @override
-  LinkedNodeBuilder visitThrowExpression(ThrowExpression node) {
-    return LinkedNodeBuilder.throwExpression(
-      throwExpression_expression: node.expression.accept(this),
-      expression_type: _writeType(node.staticType),
-    );
-  }
-
-  @override
-  LinkedNodeBuilder visitTopLevelVariableDeclaration(
-      TopLevelVariableDeclaration node) {
-    timerAstBinaryWriterTopVar.start();
-    try {
-      var builder = LinkedNodeBuilder.topLevelVariableDeclaration(
-        informativeId: getInformativeId(node),
-        topLevelVariableDeclaration_variableList: node.variables?.accept(this),
-      );
-      builder.flags = AstBinaryFlags.encode(
+    _writeUInt30(
+      AstBinaryFlags.encode(
+        isAbstract: node.body is EmptyFunctionBody,
+        isAsync: node.body?.isAsynchronous ?? false,
         isExternal: node.externalKeyword != null,
-      );
-      _storeCompilationUnitMember(builder, node);
-
-      return builder;
-    } finally {
-      timerAstBinaryWriterTopVar.stop();
-    }
-  }
-
-  @override
-  LinkedNodeBuilder visitTryStatement(TryStatement node) {
-    return LinkedNodeBuilder.tryStatement(
-      tryStatement_body: node.body.accept(this),
-      tryStatement_catchClauses: _writeNodeList(node.catchClauses),
-      tryStatement_finallyBlock: node.finallyBlock?.accept(this),
-    );
-  }
-
-  @override
-  LinkedNodeBuilder visitTypeArgumentList(TypeArgumentList node) {
-    return LinkedNodeBuilder.typeArgumentList(
-      typeArgumentList_arguments: _writeNodeList(node.arguments),
-    );
-  }
-
-  @override
-  LinkedNodeBuilder visitTypeName(TypeName node) {
-    return LinkedNodeBuilder.typeName(
-      typeName_name: node.name.accept(this),
-      typeName_type: _writeType(node.type),
-      typeName_typeArguments: _writeNodeList(
-        node.typeArguments?.arguments,
+        isGenerator: node.body?.isGenerator ?? false,
+        isGet: node.isGetter,
+        isNative: node.body is NativeFunctionBody,
+        isOperator: node.operatorKeyword != null,
+        isSet: node.isSetter,
+        isStatic: node.isStatic,
       ),
-    )..flags = AstBinaryFlags.encode(
+    );
+
+    _writeInformativeUint30(node.offset);
+    _writeInformativeUint30(node.length);
+    _writeDocumentationCommentString(node.documentationComment);
+
+    var resolutionIndex = _resolutionUnit.enterDeclaration();
+
+    _pushScopeTypeParameters(node.typeParameters);
+
+    _writeDeclarationName(node.name);
+    _writeOptionalNode(node.typeParameters);
+    _writeOptionalNode(node.returnType);
+    _writeOptionalNode(node.parameters);
+
+    _storeClassMember(node);
+
+    _writeUInt30(resolutionIndex);
+
+    var element = node.declaredElement as ExecutableElementImpl;
+    _writeActualReturnType(element.returnType);
+    _writeTopLevelInferenceError(element);
+    // TODO(scheglov) move this flag into ClassElementImpl?
+    if (element is MethodElementImpl) {
+      _resolutionSink.writeByte(
+        element.isOperatorEqualWithParameterTypeFromObject ? 1 : 0,
+      );
+    }
+
+    _resolutionSink.localElements.popScope();
+  }
+
+  @override
+  void visitMethodInvocation(MethodInvocation node) {
+    _writeByte(Tag.MethodInvocation);
+    _writeByte(
+      AstBinaryFlags.encode(
+        hasPeriod: node.operator?.type == TokenType.PERIOD,
+        hasPeriod2: node.operator?.type == TokenType.PERIOD_PERIOD,
+      ),
+    );
+    _writeOptionalNode(node.target);
+    _writeNode(node.methodName);
+    _storeInvocationExpression(node);
+  }
+
+  @override
+  void visitMixinDeclaration(MixinDeclaration node) {
+    var classOffset = _sink.offset;
+    var resolutionIndex = _resolutionUnit.enterDeclaration();
+
+    _writeByte(Tag.MixinDeclaration);
+
+    var element = node.declaredElement as MixinElementImpl;
+    _resolutionSink.writeByte(element.isSimplyBounded ? 1 : 0);
+    _resolutionSink.writeStringList(element.superInvokedNames);
+
+    _writeInformativeUint30(node.offset);
+    _writeInformativeUint30(node.length);
+    _writeDocumentationCommentString(node.documentationComment);
+
+    _pushScopeTypeParameters(node.typeParameters);
+
+    _writeOptionalNode(node.typeParameters);
+    _writeOptionalNode(node.onClause);
+    _writeOptionalNode(node.implementsClause);
+    _storeNamedCompilationUnitMember(node);
+    _writeUInt30(resolutionIndex);
+
+    _classMemberIndexItems.clear();
+    _writeNodeList(node.members);
+    _hasConstConstructor = false;
+
+    _resolutionSink.localElements.popScope();
+
+    // TODO(scheglov) write member index
+    var classIndexOffset = _sink.offset;
+    _writeClassMemberIndex();
+
+    unitMemberIndexItems.add(
+      _UnitMemberIndexItem(
+        offset: classOffset,
+        tag: Tag.MixinDeclaration,
+        name: node.name.name,
+        classIndexOffset: classIndexOffset,
+      ),
+    );
+  }
+
+  @override
+  void visitNamedExpression(NamedExpression node) {
+    _writeByte(Tag.NamedExpression);
+
+    var nameNode = node.name.label;
+    _writeStringReference(nameNode.name);
+    _writeInformativeUint30(nameNode.offset);
+
+    _writeNode(node.expression);
+  }
+
+  @override
+  void visitNativeClause(NativeClause node) {
+    _writeByte(Tag.NativeClause);
+    _writeNode(node.name);
+  }
+
+  @override
+  void visitNullLiteral(NullLiteral node) {
+    _writeByte(Tag.NullLiteral);
+  }
+
+  @override
+  void visitOnClause(OnClause node) {
+    _writeByte(Tag.OnClause);
+    _writeNodeList(node.superclassConstraints);
+  }
+
+  @override
+  void visitParenthesizedExpression(ParenthesizedExpression node) {
+    _writeByte(Tag.ParenthesizedExpression);
+    _writeNode(node.expression);
+    _storeExpression(node);
+  }
+
+  @override
+  void visitPartDirective(PartDirective node) {
+    _writeByte(Tag.PartDirective);
+    _storeUriBasedDirective(node);
+  }
+
+  @override
+  void visitPartOfDirective(PartOfDirective node) {
+    _writeByte(Tag.PartOfDirective);
+    _writeOptionalNode(node.libraryName);
+    _writeOptionalNode(node.uri);
+    _storeDirective(node);
+  }
+
+  @override
+  void visitPostfixExpression(PostfixExpression node) {
+    _writeByte(Tag.PostfixExpression);
+
+    _writeNode(node.operand);
+
+    var operatorToken = node.operator.type;
+    var binaryToken = TokensWriter.astToBinaryTokenType(operatorToken);
+    _writeByte(binaryToken.index);
+
+    _resolutionSink.writeElement(node.staticElement);
+    if (operatorToken.isIncrementOperator) {
+      _resolutionSink.writeElement(node.readElement);
+      _resolutionSink.writeType(node.readType);
+      _resolutionSink.writeElement(node.writeElement);
+      _resolutionSink.writeType(node.writeType);
+    }
+    _storeExpression(node);
+  }
+
+  @override
+  void visitPrefixedIdentifier(PrefixedIdentifier node) {
+    _writeByte(Tag.PrefixedIdentifier);
+    _writeNode(node.prefix);
+    _writeNode(node.identifier);
+
+    // TODO(scheglov) In actual prefixed identifier, the type of the identifier.
+    _resolutionSink?.writeType(node.staticType);
+  }
+
+  @override
+  void visitPrefixExpression(PrefixExpression node) {
+    _writeByte(Tag.PrefixExpression);
+
+    var operatorToken = node.operator.type;
+    var binaryToken = TokensWriter.astToBinaryTokenType(operatorToken);
+    _writeByte(binaryToken.index);
+
+    _writeNode(node.operand);
+
+    _resolutionSink?.writeElement(node.staticElement);
+    if (operatorToken.isIncrementOperator) {
+      _resolutionSink.writeElement(node.readElement);
+      _resolutionSink.writeType(node.readType);
+      _resolutionSink.writeElement(node.writeElement);
+      _resolutionSink.writeType(node.writeType);
+    }
+    _storeExpression(node);
+  }
+
+  @override
+  void visitPropertyAccess(PropertyAccess node) {
+    _writeByte(Tag.PropertyAccess);
+    _writeByte(
+      AstBinaryFlags.encode(
+        hasPeriod: node.operator?.type == TokenType.PERIOD,
+        hasPeriod2: node.operator?.type == TokenType.PERIOD_PERIOD,
+      ),
+    );
+    _writeOptionalNode(node.target);
+    _writeNode(node.propertyName);
+    // TODO(scheglov) Get from the property?
+    _storeExpression(node);
+  }
+
+  @override
+  void visitRedirectingConstructorInvocation(
+      RedirectingConstructorInvocation node) {
+    _writeByte(Tag.RedirectingConstructorInvocation);
+
+    _writeByte(
+      AstBinaryFlags.encode(
+        hasThis: node.thisKeyword != null,
+      ),
+    );
+
+    _writeOptionalNode(node.constructorName);
+    _writeNode(node.argumentList);
+    _resolutionSink?.writeElement(node.staticElement);
+    _storeConstructorInitializer(node);
+  }
+
+  @override
+  void visitSetOrMapLiteral(SetOrMapLiteral node) {
+    _writeByte(Tag.SetOrMapLiteral);
+
+    // TODO(scheglov) isMap/isSet is resolution data
+    _writeByte(
+      AstBinaryFlags.encode(
+        isConst: node.constKeyword != null,
+        isMap: node.isMap,
+        isSet: node.isSet,
+      ),
+    );
+
+    _writeOptionalNode(node.typeArguments);
+    _writeNodeList(node.elements);
+
+    _storeExpression(node);
+  }
+
+  @override
+  void visitShowCombinator(ShowCombinator node) {
+    _writeByte(Tag.ShowCombinator);
+    _writeInformativeUint30(node.keyword.offset);
+    _writeNodeList(node.shownNames);
+  }
+
+  @override
+  void visitSimpleFormalParameter(SimpleFormalParameter node) {
+    _writeByte(Tag.SimpleFormalParameter);
+
+    _writeOptionalNode(node.type);
+    _storeNormalFormalParameter(node, node.keyword);
+
+    var element = node.declaredElement as ParameterElementImpl;
+    _resolutionSink.writeByte(element.inheritsCovariant ? 1 : 0);
+  }
+
+  @override
+  void visitSimpleIdentifier(SimpleIdentifier node) {
+    _writeByte(Tag.SimpleIdentifier);
+    _writeStringReference(node.name);
+    _writeInformativeUint30(node.offset);
+    _resolutionSink?.writeElement(node.staticElement);
+    // TODO(scheglov) It is inefficient to write many null types.
+    _resolutionSink?.writeType(node.staticType);
+  }
+
+  @override
+  void visitSimpleStringLiteral(SimpleStringLiteral node) {
+    _writeByte(Tag.SimpleStringLiteral);
+    _writeStringReference(node.literal.lexeme);
+    _writeStringReference(node.value);
+  }
+
+  @override
+  void visitSpreadElement(SpreadElement node) {
+    _writeByte(Tag.SpreadElement);
+    _writeByte(
+      AstBinaryFlags.encode(
+        hasQuestion:
+            node.spreadOperator.type == TokenType.PERIOD_PERIOD_PERIOD_QUESTION,
+      ),
+    );
+    _writeNode(node.expression);
+  }
+
+  @override
+  void visitStringInterpolation(StringInterpolation node) {
+    _writeByte(Tag.StringInterpolation);
+    _writeNodeList(node.elements);
+  }
+
+  @override
+  void visitSuperConstructorInvocation(SuperConstructorInvocation node) {
+    _writeByte(Tag.SuperConstructorInvocation);
+
+    _writeOptionalNode(node.constructorName);
+    _writeNode(node.argumentList);
+    _resolutionSink?.writeElement(node.staticElement);
+    _storeConstructorInitializer(node);
+  }
+
+  @override
+  void visitSuperExpression(SuperExpression node) {
+    _writeByte(Tag.SuperExpression);
+    _storeExpression(node);
+  }
+
+  @override
+  void visitSymbolLiteral(SymbolLiteral node) {
+    _writeByte(Tag.SymbolLiteral);
+
+    var components = node.components;
+    _writeUInt30(components.length);
+    for (var token in components) {
+      _writeStringReference(token.lexeme);
+    }
+    _storeExpression(node);
+  }
+
+  @override
+  void visitThisExpression(ThisExpression node) {
+    _writeByte(Tag.ThisExpression);
+    _storeExpression(node);
+  }
+
+  @override
+  void visitThrowExpression(ThrowExpression node) {
+    _writeByte(Tag.ThrowExpression);
+    _writeNode(node.expression);
+    _storeExpression(node);
+  }
+
+  @override
+  void visitTopLevelVariableDeclaration(TopLevelVariableDeclaration node) {
+    unitMemberIndexItems.add(
+      _UnitMemberIndexItem(
+        offset: _sink.offset,
+        tag: Tag.TopLevelVariableDeclaration,
+        variableNames: node.variables.variables
+            .map((variable) => variable.name.name)
+            .toList(),
+      ),
+    );
+
+    _writeByte(Tag.TopLevelVariableDeclaration);
+    _writeByte(
+      AstBinaryFlags.encode(
+        isExternal: node.externalKeyword != null,
+      ),
+    );
+
+    _writeInformativeVariableCodeRanges(node.offset, node.variables);
+    _writeDocumentationCommentString(node.documentationComment);
+
+    var resolutionIndex = _resolutionUnit.enterDeclaration();
+
+    _isConstTopLevelVariable = node.variables.isConst;
+    try {
+      _writeNode(node.variables);
+    } finally {
+      _isConstTopLevelVariable = false;
+    }
+
+    _storeCompilationUnitMember(node);
+
+    _writeUInt30(resolutionIndex);
+  }
+
+  @override
+  void visitTypeArgumentList(TypeArgumentList node) {
+    _writeByte(Tag.TypeArgumentList);
+    _writeNodeList(node.arguments);
+  }
+
+  @override
+  void visitTypeName(TypeName node) {
+    _writeByte(Tag.TypeName);
+
+    _writeByte(
+      AstBinaryFlags.encode(
         hasQuestion: node.question != null,
         hasTypeArguments: node.typeArguments != null,
-      );
-  }
-
-  @override
-  LinkedNodeBuilder visitTypeParameter(TypeParameter node) {
-    var builder = LinkedNodeBuilder.typeParameter(
-      typeParameter_bound: node.bound?.accept(this),
-      typeParameter_defaultType: _writeType(LazyAst.getDefaultType(node)),
-      typeParameter_variance: _encodeVariance(LazyAst.getVariance(node)),
-      informativeId: getInformativeId(node),
+      ),
     );
-    builder.name = node.name.name;
-    _storeDeclaration(builder, node);
-    return builder;
+
+    _writeNode(node.name);
+    _writeOptionalNode(node.typeArguments);
+
+    _resolutionSink.writeType(node.type);
   }
 
   @override
-  LinkedNodeBuilder visitTypeParameterList(TypeParameterList node) {
-    return LinkedNodeBuilder.typeParameterList(
-      typeParameterList_typeParameters: _writeNodeList(node.typeParameters),
+  void visitTypeParameter(TypeParameter node) {
+    _writeByte(Tag.TypeParameter);
+    _writeInformativeUint30(node.offset);
+    _writeInformativeUint30(node.length);
+    _writeDeclarationName(node.name);
+    _writeOptionalNode(node.bound);
+    _storeDeclaration(node);
+
+    var element = node.declaredElement as TypeParameterElementImpl;
+    _resolutionSink.writeByte(
+      _encodeVariance(element),
     );
+    _resolutionSink.writeType(element.defaultType);
   }
 
   @override
-  LinkedNodeBuilder visitVariableDeclaration(VariableDeclaration node) {
-    var initializer = node.initializer;
-    var declarationList = node.parent as VariableDeclarationList;
-    var declaration = declarationList.parent;
-    if (declaration is TopLevelVariableDeclaration) {
-      if (!declarationList.isConst) {
-        initializer = null;
-      }
-    } else if (declaration is FieldDeclaration) {
-      if (!(declarationList.isConst ||
-          !declaration.isStatic &&
-              declarationList.isFinal &&
-              _hasConstConstructor)) {
-        initializer = null;
+  void visitTypeParameterList(TypeParameterList node) {
+    _writeByte(Tag.TypeParameterList);
+    _writeNodeList(node.typeParameters);
+  }
+
+  @override
+  void visitVariableDeclaration(VariableDeclaration node) {
+    _writeByte(Tag.VariableDeclaration);
+    _writeByte(
+      AstBinaryFlags.encode(
+        hasInitializer: node.initializer != null,
+      ),
+    );
+    _writeDeclarationName(node.name);
+
+    // TODO(scheglov) Enforce not null, remove `?` in `?.type` below.
+    var element = node.declaredElement as VariableElementImpl;
+    _writeActualType(element?.type);
+    _writeTopLevelInferenceError(element);
+    if (element is FieldElementImpl) {
+      _resolutionSink.writeByte(element.inheritsCovariant ? 1 : 0);
+    }
+
+    Expression initializerToWrite;
+    if (_isConstField ||
+        _hasConstConstructor && _isFinalField ||
+        _isConstTopLevelVariable) {
+      var initializer = node.initializer;
+      if (_isSerializableExpression(initializer)) {
+        initializerToWrite = initializer;
       }
     }
+    _writeOptionalNode(initializerToWrite);
+  }
 
-    if (!_isSerializableExpression(initializer)) {
-      initializer = null;
+  @override
+  void visitVariableDeclarationList(VariableDeclarationList node) {
+    _writeByte(Tag.VariableDeclarationList);
+    _writeByte(
+      AstBinaryFlags.encode(
+        isConst: node.isConst,
+        isFinal: node.isFinal,
+        isLate: node.lateKeyword != null,
+        isVar: node.keyword?.keyword == Keyword.VAR,
+      ),
+    );
+    _writeOptionalNode(node.type);
+    _writeNodeList(node.variables);
+    _storeAnnotatedNode(node);
+  }
+
+  @override
+  void visitWithClause(WithClause node) {
+    _writeByte(Tag.WithClause);
+    _writeNodeList(node.mixinTypes);
+  }
+
+  void _pushScopeTypeParameters(TypeParameterList node) {
+    _resolutionSink.localElements.pushScope();
+
+    if (node == null) {
+      return;
     }
 
-    var builder = LinkedNodeBuilder.variableDeclaration(
-      informativeId: getInformativeId(node),
-      variableDeclaration_initializer: initializer?.accept(this),
-    );
-    builder.flags = AstBinaryFlags.encode(
-      hasInitializer: node.initializer != null,
-    );
-    builder.name = node.name.name;
-    builder.topLevelTypeInferenceError = LazyAst.getTypeInferenceError(node);
-    _writeActualType(builder, node);
-    _storeInheritsCovariant(builder, node);
-    return builder;
-  }
-
-  @override
-  LinkedNodeBuilder visitVariableDeclarationList(VariableDeclarationList node) {
-    var builder = LinkedNodeBuilder.variableDeclarationList(
-      variableDeclarationList_type: node.type?.accept(this),
-      variableDeclarationList_variables: _writeNodeList(node.variables),
-    );
-    builder.flags = AstBinaryFlags.encode(
-      isConst: node.isConst,
-      isFinal: node.isFinal,
-      isLate: node.lateKeyword != null,
-      isVar: node.keyword?.keyword == Keyword.VAR,
-    );
-    _storeAnnotatedNode(builder, node);
-    return builder;
-  }
-
-  @override
-  LinkedNodeBuilder visitVariableDeclarationStatement(
-      VariableDeclarationStatement node) {
-    return LinkedNodeBuilder.variableDeclarationStatement(
-      variableDeclarationStatement_variables: node.variables.accept(this),
-    );
-  }
-
-  @override
-  LinkedNodeBuilder visitWhileStatement(WhileStatement node) {
-    return LinkedNodeBuilder.whileStatement(
-      whileStatement_body: node.body.accept(this),
-      whileStatement_condition: node.condition.accept(this),
-    );
-  }
-
-  @override
-  LinkedNodeBuilder visitWithClause(WithClause node) {
-    return LinkedNodeBuilder.withClause(
-      withClause_mixinTypes: _writeNodeList(node.mixinTypes),
-    );
-  }
-
-  @override
-  LinkedNodeBuilder visitYieldStatement(YieldStatement node) {
-    var builder = LinkedNodeBuilder.yieldStatement(
-      yieldStatement_expression: node.expression.accept(this),
-    );
-    builder.flags = AstBinaryFlags.encode(
-      isStar: node.star != null,
-    );
-    _storeStatement(builder, node);
-    return builder;
-  }
-
-  LinkedNodeBuilder writeUnit(CompilationUnit unit) {
-    timerAstBinaryWriter.start();
-    try {
-      return unit.accept(this);
-    } finally {
-      timerAstBinaryWriter.stop();
+    for (var typeParameter in node.typeParameters) {
+      _resolutionSink.localElements.declare(typeParameter.declaredElement);
     }
   }
 
-  _ElementComponents _componentsOfElement(Element element) {
-    if (element is ParameterMember) {
-      element = element.declaration;
-    }
-
-    if (element is Member) {
-      var elementIndex = _indexOfElement(element.declaration);
-      var substitution = element.substitution.map;
-      var substitutionBuilder = LinkedNodeTypeSubstitutionBuilder(
-        isLegacy: element.isLegacy,
-        typeParameters: substitution.keys.map(_indexOfElement).toList(),
-        typeArguments: substitution.values.map(_writeType).toList(),
-      );
-      return _ElementComponents(elementIndex, substitutionBuilder);
-    }
-
-    var elementIndex = _indexOfElement(element);
-    return _ElementComponents(elementIndex, null);
+  void _storeAnnotatedNode(AnnotatedNode node) {
+    _writeNodeList(node.metadata);
   }
 
-  int _indexOfElement(Element element) {
-    return _linkingContext.indexOfElement(element);
+  void _storeClassMember(ClassMember node) {
+    _storeDeclaration(node);
   }
 
-  void _storeAnnotatedNode(LinkedNodeBuilder builder, AnnotatedNode node) {
-    builder.annotatedNode_metadata = _writeNodeList(node.metadata);
+  void _storeCompilationUnitMember(CompilationUnitMember node) {
+    _storeDeclaration(node);
   }
 
-  void _storeClassMember(LinkedNodeBuilder builder, ClassMember node) {
-    _storeDeclaration(builder, node);
+  void _storeConstructorInitializer(ConstructorInitializer node) {}
+
+  void _storeDeclaration(Declaration node) {
+    _storeAnnotatedNode(node);
   }
 
-  void _storeClassOrMixinDeclaration(
-      LinkedNodeBuilder builder, ClassOrMixinDeclaration node) {
-    builder
-      ..classOrMixinDeclaration_implementsClause =
-          node.implementsClause?.accept(this)
-      ..classOrMixinDeclaration_members = _writeNodeList(node.members)
-      ..classOrMixinDeclaration_typeParameters =
-          node.typeParameters?.accept(this);
-    _storeNamedCompilationUnitMember(builder, node);
-    _storeIsSimpleBounded(builder, node);
+  void _storeDirective(Directive node) {
+    _writeInformativeUint30(node.keyword.offset);
+    _storeAnnotatedNode(node);
   }
 
-  void _storeCompilationUnitMember(
-      LinkedNodeBuilder builder, CompilationUnitMember node) {
-    _storeDeclaration(builder, node);
+  void _storeExpression(Expression node) {
+    _resolutionSink?.writeType(node.staticType);
   }
 
-  void _storeConstructorInitializer(
-      LinkedNodeBuilder builder, ConstructorInitializer node) {}
-
-  void _storeDeclaration(LinkedNodeBuilder builder, Declaration node) {
-    _storeAnnotatedNode(builder, node);
+  void _storeForEachParts(ForEachParts node) {
+    _writeNode(node.iterable);
+    _storeForLoopParts(node);
   }
 
-  void _storeDirective(LinkedNodeBuilder builder, Directive node) {
-    _storeAnnotatedNode(builder, node);
-    _storeInformativeId(builder, node);
+  void _storeForLoopParts(ForLoopParts node) {}
+
+  void _storeFormalParameter(FormalParameter node) {
+    _writeActualType(node.declaredElement.type);
   }
 
-  void _storeExpression(LinkedNodeBuilder builder, Expression node) {
-    builder.expression_type = _writeType(node.staticType);
-  }
-
-  void _storeForEachParts(LinkedNodeBuilder builder, ForEachParts node) {
-    _storeForLoopParts(builder, node);
-    builder..forEachParts_iterable = node.iterable?.accept(this);
-  }
-
-  void _storeForLoopParts(LinkedNodeBuilder builder, ForLoopParts node) {}
-
-  void _storeFormalParameter(LinkedNodeBuilder builder, FormalParameter node) {
-    _writeActualType(builder, node);
-  }
-
-  void _storeForMixin(LinkedNodeBuilder builder, ForMixin node) {
-    builder.flags = AstBinaryFlags.encode(
-      hasAwait: node.awaitKeyword != null,
+  void _storeForMixin(ForMixin node) {
+    _writeByte(
+      AstBinaryFlags.encode(
+        hasAwait: node.awaitKeyword != null,
+      ),
     );
-    builder..forMixin_forLoopParts = node.forLoopParts.accept(this);
+    _writeNode(node.forLoopParts);
   }
 
-  void _storeForParts(LinkedNodeBuilder builder, ForParts node) {
-    _storeForLoopParts(builder, node);
-    builder
-      ..forParts_condition = node.condition?.accept(this)
-      ..forParts_updaters = _writeNodeList(node.updaters);
+  void _storeForParts(ForParts node) {
+    _writeOptionalNode(node.condition);
+    _writeNodeList(node.updaters);
+    _storeForLoopParts(node);
   }
 
-  void _storeFunctionBody(LinkedNodeBuilder builder, FunctionBody node) {}
-
-  void _storeInformativeId(LinkedNodeBuilder builder, AstNode node) {
-    builder.informativeId = getInformativeId(node);
+  void _storeInvocationExpression(InvocationExpression node) {
+    _writeOptionalNode(node.typeArguments);
+    _writeNode(node.argumentList);
+    _storeExpression(node);
+    // TODO(scheglov) typeArgumentTypes and staticInvokeType?
   }
 
-  void _storeInheritsCovariant(LinkedNodeBuilder builder, AstNode node) {
-    var value = LazyAst.getInheritsCovariant(node);
-    builder.inheritsCovariant = value;
+  void _storeNamedCompilationUnitMember(NamedCompilationUnitMember node) {
+    _writeDeclarationName(node.name);
+    _storeCompilationUnitMember(node);
   }
 
-  void _storeInvocationExpression(
-      LinkedNodeBuilder builder, InvocationExpression node) {
-    _storeExpression(builder, node);
-    builder
-      ..invocationExpression_arguments = node.argumentList.accept(this)
-      ..invocationExpression_invokeType = _writeType(node.staticInvokeType)
-      ..invocationExpression_typeArguments = node.typeArguments?.accept(this);
-  }
-
-  void _storeIsSimpleBounded(LinkedNodeBuilder builder, AstNode node) {
-    var flag = LazyAst.isSimplyBounded(node);
-    // TODO(scheglov) Check for `null` when writing resolved AST.
-    builder.simplyBoundable_isSimplyBounded = flag;
-  }
-
-  void _storeNamedCompilationUnitMember(
-      LinkedNodeBuilder builder, NamedCompilationUnitMember node) {
-    _storeCompilationUnitMember(builder, node);
-    _storeInformativeId(builder, node);
-    builder.name = node.name.name;
-  }
-
-  void _storeNamespaceDirective(
-      LinkedNodeBuilder builder, NamespaceDirective node) {
-    _storeUriBasedDirective(builder, node);
-    builder
-      ..namespaceDirective_combinators = _writeNodeList(node.combinators)
-      ..namespaceDirective_configurations = _writeNodeList(node.configurations)
-      ..namespaceDirective_selectedUri = LazyDirective.getSelectedUri(node);
+  void _storeNamespaceDirective(NamespaceDirective node) {
+    _writeNodeList(node.combinators);
+    _writeNodeList(node.configurations);
+    _storeUriBasedDirective(node);
   }
 
   void _storeNormalFormalParameter(
-      LinkedNodeBuilder builder, NormalFormalParameter node, Token keyword) {
-    _storeFormalParameter(builder, node);
-    builder
-      ..flags = AstBinaryFlags.encode(
+    NormalFormalParameter node,
+    Token keyword, {
+    bool hasQuestion = false,
+  }) {
+    _writeByte(
+      AstBinaryFlags.encode(
+        hasName: node.identifier != null,
+        hasQuestion: hasQuestion,
         isConst: keyword?.type == Keyword.CONST,
         isCovariant: node.covariantKeyword != null,
         isFinal: keyword?.type == Keyword.FINAL,
         isRequired: node.requiredKeyword != null,
         isVar: keyword?.type == Keyword.VAR,
-      )
-      ..informativeId = getInformativeId(node)
-      ..name = node.identifier?.name
-      ..normalFormalParameter_metadata = _writeNodeList(node.metadata);
-  }
-
-  void _storeStatement(LinkedNodeBuilder builder, Statement node) {}
-
-  void _storeSwitchMember(LinkedNodeBuilder builder, SwitchMember node) {
-    builder.switchMember_labels = _writeNodeList(node.labels);
-    builder.switchMember_statements = _writeNodeList(node.statements);
-  }
-
-  void _storeTypeAlias(LinkedNodeBuilder builder, TypeAlias node) {
-    _storeNamedCompilationUnitMember(builder, node);
-  }
-
-  void _storeTypedLiteral(LinkedNodeBuilder builder, TypedLiteral node,
-      {bool isMap = false, bool isSet = false}) {
-    _storeExpression(builder, node);
-    builder
-      ..flags = AstBinaryFlags.encode(
-        hasTypeArguments: node.typeArguments != null,
-        isConst: node.constKeyword != null,
-        isMap: isMap,
-        isSet: isSet,
-      )
-      ..typedLiteral_typeArguments = _writeNodeList(
-        node.typeArguments?.arguments,
-      );
-  }
-
-  void _storeUriBasedDirective(
-      LinkedNodeBuilder builder, UriBasedDirective node) {
-    _storeDirective(builder, node);
-    builder
-      ..uriBasedDirective_uri = node.uri.accept(this)
-      ..uriBasedDirective_uriContent = node.uriContent
-      ..uriBasedDirective_uriElement = _indexOfElement(node.uriElement);
-  }
-
-  void _writeActualReturnType(LinkedNodeBuilder builder, AstNode node) {
-    var type = LazyAst.getReturnType(node);
-    // TODO(scheglov) Check for `null` when writing resolved AST.
-    builder.actualReturnType = _writeType(type);
-  }
-
-  void _writeActualType(LinkedNodeBuilder builder, AstNode node) {
-    var type = LazyAst.getType(node);
-    // TODO(scheglov) Check for `null` when writing resolved AST.
-    builder.actualType = _writeType(type);
-  }
-
-  List<LinkedNodeBuilder> _writeNodeList(List<AstNode> nodeList) {
-    if (nodeList == null) {
-      return const <LinkedNodeBuilder>[];
-    }
-
-    var result = List<LinkedNodeBuilder>.filled(
-      nodeList.length,
-      null,
-      growable: true,
+      ),
     );
-    for (var i = 0; i < nodeList.length; ++i) {
-      result[i] = nodeList[i].accept(this);
+
+    // TODO(scheglov) Don't store when in DefaultFormalParameter?
+    _writeInformativeUint30(node.offset);
+    _writeInformativeUint30(node.length);
+
+    _writeNodeList(node.metadata);
+    if (node.identifier != null) {
+      _writeDeclarationName(node.identifier);
     }
-    return result;
+    _storeFormalParameter(node);
   }
 
-  LinkedNodeTypeBuilder _writeType(DartType type) {
-    return _linkingContext.writeType(type);
+  void _storeTypeAlias(TypeAlias node) {
+    _storeNamedCompilationUnitMember(node);
   }
 
-  static int _encodeVariance(Variance variance) {
-    if (variance == null) {
+  void _storeUriBasedDirective(UriBasedDirective node) {
+    _writeNode(node.uri);
+    _storeDirective(node);
+  }
+
+  void _writeActualReturnType(DartType type) {
+    // TODO(scheglov) Check for `null` when writing resolved AST.
+    _resolutionSink?.writeType(type);
+  }
+
+  void _writeActualType(DartType type) {
+    // TODO(scheglov) Check for `null` when writing resolved AST.
+    _resolutionSink?.writeType(type);
+  }
+
+  void _writeByte(int byte) {
+    assert((byte & 0xFF) == byte);
+    _sink.addByte(byte);
+  }
+
+  void _writeClassMemberIndex() {
+    _writeUInt30(_classMemberIndexItems.length);
+    for (var declaration in _classMemberIndexItems) {
+      _writeUInt30(declaration.offset);
+      _writeByte(declaration.tag);
+      if (declaration.name != null) {
+        _writeStringReference(declaration.name);
+      } else {
+        _writeUInt30(declaration.fieldNames.length);
+        for (var name in declaration.fieldNames) {
+          _writeStringReference(name);
+        }
+      }
+    }
+  }
+
+  void _writeDeclarationName(SimpleIdentifier node) {
+    _writeByte(Tag.SimpleIdentifier);
+    _writeStringReference(node.name);
+    _writeInformativeUint30(node.offset);
+  }
+
+  /// We write tokens as a list, so this must be the last entity written.
+  void _writeDocumentationCommentString(Comment node) {
+    if (node != null && _withInformative) {
+      var tokens = node.tokens;
+      _writeUInt30(tokens.length);
+      for (var token in tokens) {
+        _writeStringReference(token.lexeme);
+      }
+    } else {
+      _writeUInt30(0);
+    }
+  }
+
+  _writeDouble(double value) {
+    _sink.addDouble(value);
+  }
+
+  /// TODO(scheglov) Optimize the encoding format.
+  void _writeFeatureSet(FeatureSet featureSet) {
+    var experimentStatus = featureSet as ExperimentStatus;
+    var encoded = experimentStatus.toStorage();
+    _writeUint32List(encoded);
+  }
+
+  void _writeInformativeUint30(int value) {
+    if (_withInformative) {
+      _writeUInt30(value);
+    }
+  }
+
+  void _writeInformativeVariableCodeRanges(
+    int firstOffset,
+    VariableDeclarationList node,
+  ) {
+    if (_withInformative) {
+      var variables = node.variables;
+      _writeUInt30(variables.length * 2);
+      var isFirst = true;
+      for (var variable in variables) {
+        var offset = isFirst ? firstOffset : variable.offset;
+        var end = variable.end;
+        _writeUInt30(offset);
+        _writeUInt30(end - offset);
+        isFirst = false;
+      }
+    }
+  }
+
+  void _writeLanguageVersion(LibraryLanguageVersion languageVersion) {
+    _writeUInt30(languageVersion.package.major);
+    _writeUInt30(languageVersion.package.minor);
+
+    var override = languageVersion.override;
+    if (override != null) {
+      _writeUInt30(override.major + 1);
+      _writeUInt30(override.minor + 1);
+    } else {
+      _writeUInt30(0);
+      _writeUInt30(0);
+    }
+  }
+
+  void _writeLineInfo(LineInfo lineInfo) {
+    if (_withInformative) {
+      _writeUint30List(lineInfo.lineStarts);
+    } else {
+      _writeUint30List(const <int>[0]);
+    }
+  }
+
+  void _writeNode(AstNode node) {
+    node.accept(this);
+  }
+
+  void _writeNodeList(List<AstNode> nodeList) {
+    _writeUInt30(nodeList.length);
+    for (var i = 0; i < nodeList.length; ++i) {
+      nodeList[i].accept(this);
+    }
+  }
+
+  void _writeOptionalDeclarationName(SimpleIdentifier node) {
+    if (node == null) {
+      _writeByte(Tag.Nothing);
+    } else {
+      _writeByte(Tag.Something);
+      _writeDeclarationName(node);
+    }
+  }
+
+  void _writeOptionalNode(AstNode node) {
+    if (node == null) {
+      _writeByte(Tag.Nothing);
+    } else {
+      _writeByte(Tag.Something);
+      _writeNode(node);
+    }
+  }
+
+  void _writeStringReference(String string) {
+    assert(string != null);
+    var index = _stringIndexer[string];
+    _writeUInt30(index);
+  }
+
+  void _writeTopLevelInferenceError(ElementImpl element) {
+    TopLevelInferenceError error;
+    if (element is MethodElementImpl) {
+      error = element.typeInferenceError;
+    } else if (element is PropertyInducingElementImpl) {
+      error = element.typeInferenceError;
+    } else {
+      return;
+    }
+
+    if (error != null) {
+      _resolutionSink.writeByte(error.kind.index);
+      _resolutionSink.writeStringList(error.arguments);
+    } else {
+      _resolutionSink.writeByte(TopLevelInferenceErrorKind.none.index);
+    }
+  }
+
+  @pragma("vm:prefer-inline")
+  void _writeUInt30(int value) {
+    _sink.writeUInt30(value);
+  }
+
+  void _writeUint30List(List<int> values) {
+    var length = values.length;
+    _writeUInt30(length);
+    for (var i = 0; i < length; i++) {
+      _writeUInt30(values[i]);
+    }
+  }
+
+  void _writeUInt32(int value) {
+    _sink.addByte4((value >> 24) & 0xFF, (value >> 16) & 0xFF,
+        (value >> 8) & 0xFF, value & 0xFF);
+  }
+
+  void _writeUint32List(List<int> values) {
+    var length = values.length;
+    _writeUInt32(length);
+    for (var i = 0; i < length; i++) {
+      _writeUInt32(values[i]);
+    }
+  }
+
+  static int _encodeVariance(TypeParameterElementImpl element) {
+    if (element.isLegacyCovariant) {
       return 0;
-    } else if (variance == Variance.unrelated) {
+    }
+
+    var variance = element.variance;
+    if (variance == Variance.unrelated) {
       return 1;
     } else if (variance == Variance.covariant) {
       return 2;
@@ -1733,28 +1769,21 @@
     node.accept(visitor);
     return visitor.result;
   }
-
-  static LinkedNodeFormalParameterKind _toParameterKind(FormalParameter node) {
-    if (node.isRequiredPositional) {
-      return LinkedNodeFormalParameterKind.requiredPositional;
-    } else if (node.isRequiredNamed) {
-      return LinkedNodeFormalParameterKind.requiredNamed;
-    } else if (node.isOptionalPositional) {
-      return LinkedNodeFormalParameterKind.optionalPositional;
-    } else if (node.isOptionalNamed) {
-      return LinkedNodeFormalParameterKind.optionalNamed;
-    } else {
-      throw StateError('Unknown kind of parameter');
-    }
-  }
 }
 
-/// Components of a [Member] - the raw element, and the substitution.
-class _ElementComponents {
-  final int rawElement;
-  final LinkedNodeTypeSubstitutionBuilder substitution;
+/// An item in the class index, used to read only requested class members.
+class _ClassMemberIndexItem {
+  final int offset;
+  final int tag;
+  final String name;
+  final List<String> fieldNames;
 
-  _ElementComponents(this.rawElement, this.substitution);
+  _ClassMemberIndexItem({
+    @required this.offset,
+    @required this.tag,
+    this.name,
+    this.fieldNames,
+  });
 }
 
 class _IsSerializableExpressionVisitor extends RecursiveAstVisitor<void> {
@@ -1765,3 +1794,22 @@
     result = false;
   }
 }
+
+/// An item in the unit index, used to read only requested unit members.
+class _UnitMemberIndexItem {
+  final int offset;
+  final int tag;
+  final String name;
+  final List<String> variableNames;
+
+  /// The absolute offset of the index of class members, `0` if not a class.
+  final int classIndexOffset;
+
+  _UnitMemberIndexItem({
+    @required this.offset,
+    @required this.tag,
+    this.name,
+    this.variableNames,
+    this.classIndexOffset = 0,
+  });
+}
diff --git a/pkg/analyzer/lib/src/summary2/binary_format_doc.dart b/pkg/analyzer/lib/src/summary2/binary_format_doc.dart
new file mode 100644
index 0000000..646328e
--- /dev/null
+++ b/pkg/analyzer/lib/src/summary2/binary_format_doc.dart
@@ -0,0 +1,188 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:analyzer/src/summary2/ast_binary_tag.dart';
+
+class AstBundle {
+  /// The blob with libraries.
+  ///
+  /// Items of [libraryOffsets] point here.
+  List<AstLibrary> libraries;
+
+  /// Pointers to libraries in the [libraries] blob.
+  ///
+  /// We need these offsets because we read [ResolutionLibrary] only
+  /// partially - URI, offsets of units, but nothing about units. So,
+  /// we don't know where one library ends, and another starts.
+  ///
+  /// TODO(scheglov) too complicated? Read all?
+  List<Uint30> libraryOffsets;
+
+  /// [stringTableOffset] points here.
+  StringTableFormat stringTable;
+
+  /// We record `uint32` to know exactly the location of this field.
+  /// It is always at the end of the byte buffer `-4`.
+  Uint32 librariesOffset;
+
+  /// We record `uint32` to know exactly the location of this field.
+  /// It is always at the end of the byte buffer `-0`.
+  Uint32 stringTableOffset;
+}
+
+class AstLibrary {
+  /// The name from the `library` directive, might be the empty string.
+  StringRef name;
+
+  /// The offset `+1` of the name in the `library` directive.
+  /// So, `0` if absent, decoded then into `-1`.
+  Uint30 nameOffset;
+
+  /// The length of the name in the `library` directive, `0` if absent.
+  Uint30 nameLength;
+
+  /// Offsets pointing at [AstUnitFormat.headerOffset].
+  List<Uint30> unitOffsets;
+}
+
+class AstUnitFormat {
+  /// The header of the unit, read when create the reader.
+  /// [headerOffset] points here.
+  AstUnitHeader header;
+
+  /// [AstUnitIndexItem.offset] from [indexOfMembers] points into here.
+  Object declarations;
+
+  /// The offset of [header].
+  Uint30 headerOffset;
+
+  /// The index of declarations in the unit.
+  List<AstUnitIndexItem> indexOfMembers;
+}
+
+class AstUnitHeader {
+  /// Four elements: package major/minor, override major/minor.
+  /// The override is `+1`, if `0` then no override.
+  FormatUint32List languageVersion;
+
+  /// Encoded feature set.
+  FormatUint32List featureSet;
+}
+
+class AstUnitIndexItem {
+  /// The offset in [AstUnitFormat.declarations].
+  Uint30 offset;
+
+  /// The tag of the declaration from [Tag].
+  Byte tag;
+
+  /// If not [Tag.TopLevelVariableDeclaration], the name of the declaration.
+  /// Otherwise absent, [topLevelVariableNames] instead.
+  StringRef name;
+
+  /// If [Tag.TopLevelVariableDeclaration], the names of the variables.
+  /// Otherwise absent, [name] instead.
+  List<StringRef> topLevelVariableNames;
+}
+
+class Byte {}
+
+class FormatUint32List {}
+
+class ResolutionBundle {
+  /// The blob with libraries.
+  ///
+  /// [libraryOffsets] points here.
+  List<ResolutionLibrary> libraries;
+
+  /// Pointers to libraries in the [libraries] blob.
+  ///
+  /// We need these offsets because we read [ResolutionLibrary] only
+  /// partially - URI, offsets of units, but nothing about units. So,
+  /// we don't know where one library ends, and another starts.
+  ///
+  /// TODO(scheglov) too complicated? Read all?
+  List<Uint30> libraryOffsets;
+
+  /// The index of the parent reference, so we can add its name from
+  /// the [referenceNames]. Is `0` for the root.
+  ///
+  /// [referencesOffset] points here.
+  List<Uint30> referenceParents;
+
+  /// The name of this component of a reference, e.g. `String` or `@class`.
+  /// Is the empty string for the root.
+  List<StringRef> referenceNames;
+
+  /// We record `uint32` to know exactly the location of this field.
+  /// It is always at the end of the byte buffer `-8`.
+  Uint32 librariesOffset;
+
+  /// We record `uint32` to know exactly the location of this field.
+  /// It is always at the end of the byte buffer `-4`.
+  ///
+  /// Points at [referenceParents].
+  Uint32 referencesOffset;
+
+  /// We record `uint32` to know exactly the location of this field.
+  /// It is always at the end of the byte buffer `-0`.
+  Uint32 stringTableOffset;
+}
+
+class ResolutionLibrary {
+  /// The blob with units.
+  List<ResolutionUnitFormat> units;
+
+  /// [ResolutionBundle.libraryOffsets] points here.
+  StringRef uriStr;
+
+  /// Indexes of exported elements in [ResolutionBundle.referenceNames].
+  List<Uint30> exportedReferences;
+
+  /// Absolute offsets pointing at [ResolutionUnitFormat.uriStr].
+  List<Uint30> unitOffsets;
+}
+
+class ResolutionUnitFormat {
+  /// [ResolutionLibrary.unitOffsets] points here.
+  StringRef uriStr;
+
+  Byte isSynthetic;
+
+  Byte isPart;
+
+  /// If [isPart], the URI that is used in the `part` directive.
+  /// The empty string for the defining unit.
+  StringRef partUriStr;
+
+  /// The offset of the resolution information for directives.
+  /// For example resolution of metadata.
+  Uint30 directivesResolutionOffset;
+
+  /// Offsets of the resolution information for each declaration.
+  List<Uint30> declarationOffsets;
+}
+
+/// The reference to a [String], in form of [Uint30].
+class StringRef {}
+
+/// Any string is witten as [Uint30] and is an index into the string table.
+/// So, we can write each unique string only once.
+class StringTableFormat {
+  /// The blob with WTF8 encoded strings.
+  Object strings;
+
+  /// The length of [strings] in bytes. So, we know how much to go back in
+  /// the byte buffer from here to start reading strings.
+  Uint30 lengthInBytes;
+
+  /// The length of each string in bytes inside [strings].
+  ///
+  /// This allows us to read strings lazily as they are requested.
+  List<Uint30> lengths;
+}
+
+class Uint30 {}
+
+class Uint32 {}
diff --git a/pkg/analyzer/lib/src/summary2/bundle_reader.dart b/pkg/analyzer/lib/src/summary2/bundle_reader.dart
new file mode 100644
index 0000000..c2d6a9a
--- /dev/null
+++ b/pkg/analyzer/lib/src/summary2/bundle_reader.dart
@@ -0,0 +1,1112 @@
+// Copyright (c) 2020, 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:typed_data';
+
+import 'package:analyzer/dart/ast/ast.dart';
+import 'package:analyzer/dart/ast/standard_ast_factory.dart';
+import 'package:analyzer/dart/ast/token.dart';
+import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/dart/element/nullability_suffix.dart';
+import 'package:analyzer/dart/element/type.dart';
+import 'package:analyzer/source/line_info.dart';
+import 'package:analyzer/src/dart/analysis/experiments.dart';
+import 'package:analyzer/src/dart/ast/ast.dart';
+import 'package:analyzer/src/dart/element/element.dart';
+import 'package:analyzer/src/dart/element/member.dart';
+import 'package:analyzer/src/dart/element/type.dart';
+import 'package:analyzer/src/dart/element/type_algebra.dart';
+import 'package:analyzer/src/generated/testing/token_factory.dart';
+import 'package:analyzer/src/generated/utilities_dart.dart';
+import 'package:analyzer/src/summary2/apply_resolution.dart';
+import 'package:analyzer/src/summary2/ast_binary_reader.dart';
+import 'package:analyzer/src/summary2/ast_binary_tag.dart';
+import 'package:analyzer/src/summary2/data_reader.dart';
+import 'package:analyzer/src/summary2/linked_element_factory.dart';
+import 'package:analyzer/src/summary2/linked_unit_context.dart';
+import 'package:analyzer/src/summary2/reference.dart';
+import 'package:meta/meta.dart';
+import 'package:pub_semver/pub_semver.dart';
+
+class BundleReader {
+  final LinkedElementFactory elementFactory;
+
+  final SummaryDataReader _astReader;
+  final SummaryDataReader _resolutionReader;
+
+  bool withInformative = false;
+
+  final Map<String, LibraryReader> libraryMap = {};
+
+  BundleReader({
+    @required LinkedElementFactory elementFactory,
+    @required Uint8List astBytes,
+    @required Uint8List resolutionBytes,
+  })  : elementFactory = elementFactory,
+        _astReader = SummaryDataReader(astBytes),
+        _resolutionReader = SummaryDataReader(resolutionBytes) {
+    _astReader.offset = 0;
+    withInformative = _astReader.readByte() == 1;
+
+    _astReader.offset = _astReader.bytes.length - 4 * 2;
+    var astLibrariesOffset = _astReader.readUint32();
+    var astStringsOffset = _astReader.readUint32();
+    _astReader.createStringTable(astStringsOffset);
+
+    _resolutionReader.offset = _resolutionReader.bytes.length - 4 * 3;
+    var resolutionLibrariesOffset = _resolutionReader.readUint32();
+    var resolutionReferencesOffset = _resolutionReader.readUint32();
+    var resolutionStringsOffset = _resolutionReader.readUint32();
+    _resolutionReader.createStringTable(resolutionStringsOffset);
+
+    var referenceReader = _ReferenceReader(
+      elementFactory,
+      _resolutionReader,
+      resolutionReferencesOffset,
+    );
+
+    _astReader.offset = astLibrariesOffset;
+    var astLibraryOffsets = _astReader.readUint30List();
+
+    _resolutionReader.offset = resolutionLibrariesOffset;
+    var resolutionLibraryOffsets = _resolutionReader.readUint30List();
+
+    assert(astLibraryOffsets.length == resolutionLibraryOffsets.length);
+
+    for (var i = 0; i < astLibraryOffsets.length; i++) {
+      _astReader.offset = astLibraryOffsets[i];
+      var name = _astReader.readStringReference();
+      var nameOffset = _astReader.readUInt30() - 1;
+      var nameLength = _astReader.readUInt30();
+      var hasPartOfDirective = _astReader.readByte() != 0;
+      var astUnitOffsets = _astReader.readUint30List();
+
+      _resolutionReader.offset = resolutionLibraryOffsets[i];
+      var libraryUriStr = _resolutionReader.readStringReference();
+      var resolutionUnitOffsets = _resolutionReader.readUint30List();
+      assert(astUnitOffsets.length == resolutionUnitOffsets.length);
+      var exportsIndexList = _resolutionReader.readUint30List();
+
+      var reference = elementFactory.rootReference.getChild(libraryUriStr);
+      var libraryReader = LibraryReader._(
+        elementFactory,
+        withInformative,
+        _astReader,
+        _resolutionReader,
+        referenceReader,
+        reference,
+        name,
+        nameOffset,
+        nameLength,
+        hasPartOfDirective,
+        astUnitOffsets,
+        resolutionUnitOffsets,
+        exportsIndexList,
+      );
+      libraryMap[libraryUriStr] = libraryReader;
+    }
+  }
+
+  LibraryReader getLibrary(String uriStr) {
+    return libraryMap[uriStr];
+  }
+}
+
+class ClassReader {
+  final int membersOffset;
+
+  ClassReader(this.membersOffset);
+}
+
+class LibraryReader {
+  final LinkedElementFactory elementFactory;
+  final bool withInformative;
+  final SummaryDataReader astReader;
+  final SummaryDataReader resolutionReader;
+  final _ReferenceReader referenceReader;
+  final Reference reference;
+
+  final String name;
+  final int nameOffset;
+  final int nameLength;
+
+  /// Is `true` if the defining unit has [PartOfDirective].
+  final bool hasPartOfDirective;
+
+  final Uint32List astUnitOffsets;
+  final Uint32List resolutionUnitOffsets;
+  final Uint32List exportsIndexList;
+  List<Reference> _exports;
+
+  List<UnitReader> _units;
+
+  LibraryReader._(
+    this.elementFactory,
+    this.withInformative,
+    this.astReader,
+    this.resolutionReader,
+    this.referenceReader,
+    this.reference,
+    this.name,
+    this.nameOffset,
+    this.nameLength,
+    this.hasPartOfDirective,
+    this.astUnitOffsets,
+    this.resolutionUnitOffsets,
+    this.exportsIndexList,
+  ) {
+    assert(astUnitOffsets.length == resolutionUnitOffsets.length);
+  }
+
+  List<Reference> get exports {
+    if (_exports == null) {
+      var length = exportsIndexList.length;
+      _exports = List.filled(length, null, growable: false);
+      for (var i = 0; i < length; i++) {
+        var index = exportsIndexList[i];
+        var reference = referenceReader.referenceOfIndex(index);
+        _exports[i] = reference;
+      }
+    }
+    return _exports;
+  }
+
+  List<UnitReader> get units {
+    if (_units == null) {
+      _units = [];
+      for (var i = 0; i < astUnitOffsets.length; i++) {
+        var astUnitOffset = astUnitOffsets[i];
+        var resolutionUnitOffset = resolutionUnitOffsets[i];
+
+        astReader.offset = astUnitOffset;
+        var headerOffset = astReader.readUInt30();
+        var indexOffset = astReader.offset;
+
+        resolutionReader.offset = resolutionUnitOffset;
+        var unitUriStr = resolutionReader.readStringReference();
+        var isSynthetic = resolutionReader.readByte() != 0;
+        var isPart = resolutionReader.readByte() != 0;
+        var partUriStr = resolutionReader.readStringReference();
+        if (!isPart) {
+          partUriStr = null;
+        }
+        var resolutionDirectivesOffset = resolutionReader.readUInt30();
+        var resolutionDeclarationOffsets = resolutionReader.readUint30List();
+
+        _units.add(
+          UnitReader._(
+            this,
+            resolutionDirectivesOffset,
+            resolutionDeclarationOffsets,
+            reference.getChild('@unit').getChild(unitUriStr),
+            isSynthetic,
+            partUriStr,
+            headerOffset,
+            indexOffset,
+          ),
+        );
+      }
+    }
+    return _units;
+  }
+}
+
+class LinkedContext implements AstLinkedContext {
+  final UnitReader _unitReader;
+  final AstNode _node;
+  final int _resolutionIndex;
+  final Uint32List _codeOffsetLengthList;
+  final Uint32List _documentationTokenIndexList;
+
+  @override
+  final int codeOffset;
+
+  @override
+  final int codeLength;
+
+  @override
+  final bool isClassWithConstConstructor;
+
+  bool _isApplied = false;
+
+  bool _hasDocumentationComment = false;
+
+  _UnitMemberReader _reader;
+
+  LinkedContext(
+    this._unitReader,
+    this._node, {
+    @required this.codeOffset,
+    @required this.codeLength,
+    this.isClassWithConstConstructor = false,
+    Uint32List codeOffsetLengthList,
+    @required int resolutionIndex,
+    @required Uint32List documentationTokenIndexList,
+  })  : _resolutionIndex = resolutionIndex,
+        _codeOffsetLengthList = codeOffsetLengthList,
+        _documentationTokenIndexList = documentationTokenIndexList;
+
+  @override
+  List<ClassMember> get classMembers {
+    var reader = _reader;
+    if (reader is _ClassReader) {
+      return reader.classMembers;
+    } else if (_node is ClassTypeAlias) {
+      return const <ClassMember>[];
+    } else {
+      throw UnimplementedError();
+    }
+  }
+
+  @override
+  // TODO: implement unitDirectives
+  List<Directive> get unitDirectives => throw UnimplementedError();
+
+  @override
+  void applyResolution(LinkedUnitContext unitContext) {
+    if (_isApplied) {
+      return;
+    }
+    _isApplied = true;
+
+    // EnumConstantDeclaration has no separate resolution.
+    // Its metadata is resolved during EnumDeclaration resolution.
+    if (_resolutionIndex == -1) {
+      return;
+    }
+
+    var localElements = <Element>[];
+    var resolutionReader = LinkedResolutionReader(
+      _unitReader,
+      localElements,
+      _unitReader._resolutionDeclarationsOffset[_resolutionIndex],
+    );
+    _node.accept(
+      ApplyResolutionVisitor(
+        unitContext,
+        localElements,
+        resolutionReader,
+      ),
+    );
+  }
+
+  @override
+  int getVariableDeclarationCodeLength(VariableDeclaration node) {
+    var variableList = node.parent as VariableDeclarationList;
+    var variables = variableList.variables;
+    for (var i = 0; i < variables.length; i++) {
+      if (identical(variables[i], node)) {
+        return _codeOffsetLengthList[2 * i + 1];
+      }
+    }
+    throw StateError('No |$node| in: $variableList');
+  }
+
+  @override
+  int getVariableDeclarationCodeOffset(VariableDeclaration node) {
+    var variableList = node.parent as VariableDeclarationList;
+    var variables = variableList.variables;
+    for (var i = 0; i < variables.length; i++) {
+      if (identical(variables[i], node)) {
+        return _codeOffsetLengthList[2 * i + 0];
+      }
+    }
+    throw StateError('No |$node| in: $variableList');
+  }
+
+  @override
+  void readDocumentationComment() {
+    if (_hasDocumentationComment) {
+      return;
+    }
+    _hasDocumentationComment = true;
+
+    if (_documentationTokenIndexList.isEmpty) {
+      return;
+    }
+
+    var tokens = <Token>[];
+    for (var lexemeIndex in _documentationTokenIndexList) {
+      var lexeme = _unitReader.astReader.stringOfIndex(lexemeIndex);
+      var token = TokenFactory.tokenFromString(lexeme);
+      tokens.add(token);
+    }
+
+    var comment = astFactory.documentationComment(tokens);
+    (_node as AnnotatedNodeImpl).documentationComment = comment;
+  }
+}
+
+/// Helper for reading elements and types from their binary encoding.
+class LinkedResolutionReader {
+  final UnitReader _unitReader;
+
+  /// The stack of [TypeParameterElement]s and [ParameterElement] that are
+  /// available in the scope of [nextElement] and [nextType].
+  ///
+  /// This stack is shared with the client of the reader, and update mostly
+  /// by the client. However it is also updated during [_readFunctionType].
+  final List<Element> _localElements;
+
+  /// The offset in [_Reader.bytes] from which we read resolution now.
+  int _byteOffset = 0;
+
+  LinkedResolutionReader(
+    this._unitReader,
+    this._localElements,
+    this._byteOffset,
+  );
+
+  Element nextElement() {
+    var memberFlags = readByte();
+    var element = _readRawElement();
+
+    if (memberFlags == Tag.RawElement) {
+      return element;
+    }
+
+    if (memberFlags == Tag.MemberLegacyWithTypeArguments ||
+        memberFlags == Tag.MemberWithTypeArguments) {
+      var arguments = _readTypeList();
+      // TODO(scheglov) why to check for empty? If we have this flags.
+      if (arguments.isNotEmpty) {
+        var typeParameters =
+            (element.enclosingElement as TypeParameterizedElement)
+                .typeParameters;
+        var substitution = Substitution.fromPairs(typeParameters, arguments);
+        element = ExecutableMember.from2(element, substitution);
+      }
+    }
+
+    if (memberFlags == Tag.MemberLegacyWithTypeArguments) {
+      return Member.legacy(element);
+    }
+
+    if (memberFlags == Tag.MemberWithTypeArguments) {
+      return element;
+    }
+
+    throw UnimplementedError('memberFlags: $memberFlags');
+  }
+
+  String nextString() {
+    var index = _readUInt30();
+    return _unitReader._resolutionReader.stringOfIndex(index);
+  }
+
+  DartType nextType() {
+    var tag = readByte();
+    if (tag == Tag.NullType) {
+      return null;
+    } else if (tag == Tag.DynamicType) {
+      return DynamicTypeImpl.instance;
+    } else if (tag == Tag.FunctionType) {
+      return _readFunctionType();
+    } else if (tag == Tag.InterfaceType) {
+      var element = nextElement();
+      var length = _readUInt30();
+      var typeArguments = List<DartType>.filled(length, null);
+      for (var i = 0; i < length; i++) {
+        typeArguments[i] = nextType();
+      }
+      var nullability = _readNullability();
+      return InterfaceTypeImpl(
+        element: element,
+        typeArguments: typeArguments,
+        nullabilitySuffix: nullability,
+      );
+    } else if (tag == Tag.NeverType) {
+      var nullability = _readNullability();
+      return NeverTypeImpl.instance.withNullability(nullability);
+    } else if (tag == Tag.TypeParameterType) {
+      var element = nextElement();
+      var nullability = _readNullability();
+      return TypeParameterTypeImpl(
+        element: element,
+        nullabilitySuffix: nullability,
+      );
+    } else if (tag == Tag.VoidType) {
+      return VoidTypeImpl.instance;
+    } else {
+      throw UnimplementedError('$tag');
+    }
+  }
+
+  int readByte() {
+    return _unitReader._resolutionReader.bytes[_byteOffset++];
+  }
+
+  List<String> readStringList() {
+    var values = <String>[];
+    var length = _readUInt30();
+    for (var i = 0; i < length; i++) {
+      var value = _readStringReference();
+      values.add(value);
+    }
+    return values;
+  }
+
+  int readUInt30() {
+    var byte = readByte();
+    if (byte & 0x80 == 0) {
+      // 0xxxxxxx
+      return byte;
+    } else if (byte & 0x40 == 0) {
+      // 10xxxxxx
+      return ((byte & 0x3F) << 8) | readByte();
+    } else {
+      // 11xxxxxx
+      return ((byte & 0x3F) << 24) |
+          (readByte() << 16) |
+          (readByte() << 8) |
+          readByte();
+    }
+  }
+
+  /// TODO(scheglov) Optimize for write/read of types without type parameters.
+  FunctionType _readFunctionType() {
+    var typeParameters = <TypeParameterElement>[];
+    var typeParametersLength = _readUInt30();
+    for (var i = 0; i < typeParametersLength; i++) {
+      var name = _readStringReference();
+      var element = TypeParameterElementImpl.synthetic(name);
+      typeParameters.add(element);
+      _localElements.add(element);
+    }
+    for (var i = 0; i < typeParametersLength; i++) {
+      var element = typeParameters[i] as TypeParameterElementImpl;
+      var bound = nextType();
+      element.bound = bound;
+    }
+
+    var typedefElement = nextElement();
+    var typeArguments = _readTypeList();
+
+    var returnType = nextType();
+
+    var formalParameters = <ParameterElement>[];
+    var formalParametersLength = _readUInt30();
+    for (var i = 0; i < formalParametersLength; i++) {
+      var kindIndex = readByte();
+      var type = nextType();
+      var name = nextString();
+      formalParameters.add(
+        ParameterElementImpl.synthetic(
+          name,
+          type,
+          _formalParameterKind(kindIndex),
+        ),
+      );
+    }
+
+    var nullability = _readNullability();
+
+    _localElements.length -= typeParametersLength;
+
+    return FunctionTypeImpl(
+      typeFormals: typeParameters,
+      parameters: formalParameters,
+      returnType: returnType,
+      nullabilitySuffix: nullability,
+      element: typedefElement,
+      typeArguments: typeArguments,
+    );
+  }
+
+  NullabilitySuffix _readNullability() {
+    var index = readByte();
+    return NullabilitySuffix.values[index];
+  }
+
+  Element _readRawElement() {
+    var index = _readUInt30();
+
+    if ((index & 0x1) == 0x1) {
+      return _localElements[index >> 1];
+    }
+
+    var referenceIndex = index >> 1;
+    var referenceReader = _unitReader._referenceReader;
+    var reference = referenceReader.referenceOfIndex(referenceIndex);
+
+    var elementFactory = _unitReader.elementFactory;
+    return elementFactory.elementOfReference(reference);
+  }
+
+  String _readStringReference() {
+    var index = _readUInt30();
+    return _unitReader._resolutionReader.stringOfIndex(index);
+  }
+
+  List<DartType> _readTypeList() {
+    var types = <DartType>[];
+    var length = _readUInt30();
+    for (var i = 0; i < length; i++) {
+      var argument = nextType();
+      types.add(argument);
+    }
+    return types;
+  }
+
+  int _readUInt30() {
+    var byte = readByte();
+    if (byte & 0x80 == 0) {
+      // 0xxxxxxx
+      return byte;
+    } else if (byte & 0x40 == 0) {
+      // 10xxxxxx
+      return ((byte & 0x3F) << 8) | readByte();
+    } else {
+      // 11xxxxxx
+      return ((byte & 0x3F) << 24) |
+          (readByte() << 16) |
+          (readByte() << 8) |
+          readByte();
+    }
+  }
+
+  static ParameterKind _formalParameterKind(int encoding) {
+    if (encoding == Tag.ParameterKindRequiredPositional) {
+      return ParameterKind.REQUIRED;
+    } else if (encoding == Tag.ParameterKindOptionalPositional) {
+      return ParameterKind.POSITIONAL;
+    } else if (encoding == Tag.ParameterKindRequiredNamed) {
+      return ParameterKind.NAMED_REQUIRED;
+    } else if (encoding == Tag.ParameterKindOptionalNamed) {
+      return ParameterKind.NAMED;
+    } else {
+      throw StateError('Unexpected parameter kind encoding: $encoding');
+    }
+  }
+}
+
+class SummaryDataForCompilationUnit {
+  final int codeLength;
+
+  SummaryDataForCompilationUnit(this.codeLength);
+}
+
+class SummaryDataForFormalParameter {
+  final int codeOffset;
+  final int codeLength;
+
+  SummaryDataForFormalParameter({
+    @required this.codeOffset,
+    @required this.codeLength,
+  });
+}
+
+class SummaryDataForLibraryDirective {
+  final UnitReader _unitReader;
+  final LibraryDirectiveImpl _node;
+  final Uint32List _documentationTokenIndexList;
+  bool _hasDocumentationComment = false;
+
+  SummaryDataForLibraryDirective(
+    this._unitReader,
+    this._node, {
+    @required Uint32List documentationTokenIndexList,
+  }) : _documentationTokenIndexList = documentationTokenIndexList {
+    _node.summaryData = this;
+  }
+
+  void readDocumentationComment() {
+    if (_hasDocumentationComment) {
+      return;
+    }
+    _hasDocumentationComment = true;
+
+    if (_documentationTokenIndexList.isEmpty) {
+      return;
+    }
+
+    var tokens = <Token>[];
+    for (var lexemeIndex in _documentationTokenIndexList) {
+      var lexeme = _unitReader.astReader.stringOfIndex(lexemeIndex);
+      var token = TokenFactory.tokenFromString(lexeme);
+      tokens.add(token);
+    }
+
+    var comment = astFactory.documentationComment(tokens);
+    _node.documentationComment = comment;
+  }
+}
+
+class SummaryDataForTypeParameter {
+  final int codeOffset;
+  final int codeLength;
+
+  SummaryDataForTypeParameter({
+    @required this.codeOffset,
+    @required this.codeLength,
+  });
+}
+
+class UnitReader implements ReferenceNodeAccessor {
+  final LibraryReader libraryReader;
+  final Reference reference;
+
+  final bool isSynthetic;
+
+  /// If a part, the URI that is used in the [PartDirective].
+  /// Or `null` for the defining unit.
+  final String partUriStr;
+
+  final int _directivesResolutionOffset;
+  bool _isDirectivesResolutionApplied = false;
+
+  final Uint32List _resolutionDeclarationsOffset;
+
+  int _directivesOffset;
+  final List<_UnitMemberReader> _memberReaders = [];
+
+  CompilationUnitImpl _unit;
+  bool _hasDirectives = false;
+  bool _hasDeclarations = false;
+
+  UnitReader._(
+    this.libraryReader,
+    this._directivesResolutionOffset,
+    this._resolutionDeclarationsOffset,
+    this.reference,
+    this.isSynthetic,
+    this.partUriStr,
+    int headerOffset,
+    int indexOffset,
+  ) {
+    reference.nodeAccessor = this;
+
+    astReader.offset = headerOffset;
+    var languageVersion = _readLanguageVersion();
+    var featureSetEncoded = astReader.readUint32List();
+    var lineInfo = _readLineInfo();
+    var codeLength = astReader.readUInt30();
+    var featureSet = ExperimentStatus.fromStorage(featureSetEncoded);
+    _directivesOffset = astReader.offset;
+
+    _unit = astFactory.compilationUnit(
+      beginToken: null,
+      // TODO(scheglov)
+      // scriptTag: _readNode(data.compilationUnit_scriptTag),
+      directives: [],
+      declarations: [],
+      endToken: null,
+      featureSet: featureSet,
+    );
+    _unit.languageVersion = languageVersion;
+    _unit.lineInfo = lineInfo;
+    _unit.summaryData = SummaryDataForCompilationUnit(codeLength);
+
+    astReader.offset = indexOffset;
+    _readIndex2();
+  }
+
+  SummaryDataReader get astReader => libraryReader.astReader;
+
+  LinkedElementFactory get elementFactory => libraryReader.elementFactory;
+
+  /// TODO(scheglov)
+  /// This methods breaks lazy loading, and loads everything eagerly.
+  /// We use it because of `unitElement.types` for example, when we are
+  /// explicitly asked for all [ClassDeclaration]s and [ClassTypeAlias]s.
+  @Deprecated('review it')
+  @override
+  CompilationUnit get node {
+    readDirectives();
+    readDeclarations();
+    return _unit;
+  }
+
+  CompilationUnit get unit => _unit;
+
+  String get uriStr => reference.name;
+
+  bool get withInformative => libraryReader.withInformative;
+
+  _ReferenceReader get _referenceReader => libraryReader.referenceReader;
+
+  SummaryDataReader get _resolutionReader => libraryReader.resolutionReader;
+
+  /// Apply resolution to directives.
+  void applyDirectivesResolution(LinkedUnitContext unitContext) {
+    if (_isDirectivesResolutionApplied) {
+      return;
+    }
+    _isDirectivesResolutionApplied = true;
+
+    var localElements = <Element>[];
+    var resolutionReader = LinkedResolutionReader(
+      this,
+      localElements,
+      _directivesResolutionOffset,
+    );
+    for (var directive in _unit.directives) {
+      directive.accept(
+        ApplyResolutionVisitor(
+          unitContext,
+          localElements,
+          resolutionReader,
+        ),
+      );
+    }
+  }
+
+  void readDeclarations() {
+    if (!_hasDeclarations) {
+      _hasDeclarations = true;
+      for (var reader in _memberReaders) {
+        reader.node;
+      }
+    }
+  }
+
+  /// Ensure that directives are read in this unit.
+  void readDirectives() {
+    if (!_hasDirectives) {
+      _hasDirectives = true;
+      astReader.offset = _directivesOffset;
+      var length = astReader.readUInt30();
+      for (var i = 0; i < length; i++) {
+        var astReader = AstBinaryReader(
+          reader: this,
+        );
+        var directive = astReader.readNode() as Directive;
+        _unit.directives.add(directive);
+      }
+    }
+  }
+
+  @override
+  void readIndex() {}
+
+  /// Read the index of declarations in this unit, and add `null`s into
+  /// [CompilationUnit.declarations] as placeholders.
+  ///
+  /// TODO(scheglov) we don't need both this method, and [readIndex].
+  void _readIndex2() {
+    var unitReference = reference;
+    var length = astReader.readUInt30();
+    for (var i = 0; i < length; i++) {
+      var offset = astReader.readUInt30();
+      var tag = astReader.readByte();
+      if (tag == Tag.Class) {
+        var name = astReader.readStringReference();
+        var indexOffset = astReader.readUInt30();
+        var reference = unitReference.getChild('@class').getChild(name);
+        _memberReaders.add(
+          _ClassReader(
+            unitReader: this,
+            reference: reference,
+            offset: offset,
+            unit: _unit,
+            indexOffset: indexOffset,
+          ),
+        );
+      } else if (tag == Tag.ClassTypeAlias) {
+        var name = astReader.readStringReference();
+        var reader = _UnitMemberReader(this, offset, _unit);
+        _memberReaders.add(reader);
+        unitReference.getChild('@class').getChild(name).nodeAccessor = reader;
+      } else if (tag == Tag.EnumDeclaration) {
+        var name = astReader.readStringReference();
+        var reader = _UnitMemberReader(this, offset, _unit);
+        _memberReaders.add(reader);
+        unitReference.getChild('@enum').getChild(name).nodeAccessor = reader;
+      } else if (tag == Tag.ExtensionDeclaration) {
+        var name = astReader.readStringReference();
+        var indexOffset = astReader.readUInt30();
+        var reference = unitReference.getChild('@extension').getChild(name);
+        _memberReaders.add(
+          _ClassReader(
+            unitReader: this,
+            reference: reference,
+            offset: offset,
+            unit: _unit,
+            indexOffset: indexOffset,
+          ),
+        );
+      } else if (tag == Tag.FunctionDeclaration) {
+        var name = astReader.readStringReference();
+        var reader = _UnitMemberReader(this, offset, _unit);
+        _memberReaders.add(reader);
+        var containerRef = unitReference.getChild('@function');
+        containerRef.getChild(name).nodeAccessor = reader;
+      } else if (tag == Tag.FunctionDeclaration_getter) {
+        var name = astReader.readStringReference();
+        var reader = _UnitMemberReader(this, offset, _unit);
+        _memberReaders.add(reader);
+        var getterRef = unitReference.getChild('@getter');
+        getterRef.getChild(name).nodeAccessor = reader;
+        var variableRef = unitReference.getChild('@variable');
+        variableRef.getChild(name).nodeAccessor ??= reader;
+      } else if (tag == Tag.FunctionDeclaration_setter) {
+        var name = astReader.readStringReference();
+        var reader = _UnitMemberReader(this, offset, _unit);
+        _memberReaders.add(reader);
+        var setterRef = unitReference.getChild('@setter');
+        setterRef.getChild(name).nodeAccessor = reader;
+        var variableRef = unitReference.getChild('@variable');
+        variableRef.getChild(name).nodeAccessor ??= reader;
+      } else if (tag == Tag.GenericTypeAlias) {
+        var name = astReader.readStringReference();
+        var reader = _UnitMemberReader(this, offset, _unit);
+        _memberReaders.add(reader);
+        unitReference.getChild('@typeAlias').getChild(name).nodeAccessor =
+            reader;
+      } else if (tag == Tag.FunctionTypeAlias) {
+        var name = astReader.readStringReference();
+        var reader = _UnitMemberReader(this, offset, _unit);
+        _memberReaders.add(reader);
+        unitReference.getChild('@typeAlias').getChild(name).nodeAccessor =
+            reader;
+      } else if (tag == Tag.MixinDeclaration) {
+        var name = astReader.readStringReference();
+        var indexOffset = astReader.readUInt30();
+        var reference = unitReference.getChild('@mixin').getChild(name);
+        _memberReaders.add(
+          _ClassReader(
+            unitReader: this,
+            reference: reference,
+            offset: offset,
+            unit: _unit,
+            indexOffset: indexOffset,
+          ),
+        );
+      } else if (tag == Tag.TopLevelVariableDeclaration) {
+        var reader = _UnitMemberReader(this, offset, _unit);
+        var length = astReader.readUInt30();
+        for (var i = 0; i < length; i++) {
+          var name = astReader.readStringReference();
+          _memberReaders.add(reader);
+          unitReference.getChild('@getter').getChild(name).nodeAccessor =
+              reader;
+          // TODO(scheglov) only if not final/const
+          // Crash in language_2/export/local_export_test.dart
+          unitReference.getChild('@setter').getChild(name).nodeAccessor =
+              reader;
+        }
+      } else {
+        // TODO(scheglov) implement
+      }
+    }
+  }
+
+  LibraryLanguageVersion _readLanguageVersion() {
+    var packageMajor = astReader.readUInt30();
+    var packageMinor = astReader.readUInt30();
+    var overrideMajor = astReader.readUInt30();
+    var overrideMinor = astReader.readUInt30();
+    return LibraryLanguageVersion(
+      package: Version(packageMajor, packageMinor, 0),
+      override: overrideMajor > 0
+          ? Version(overrideMajor - 1, overrideMinor - 1, 0)
+          : null,
+    );
+  }
+
+  LineInfo _readLineInfo() {
+    var lineStarts = astReader.readUint30List();
+    return LineInfo(lineStarts);
+  }
+}
+
+class _ClassMemberReader implements ReferenceNodeAccessor {
+  final UnitReader unitReader;
+  final int offset;
+  final NodeListImpl<ClassMember> _members;
+  final int _membersIndex;
+  ClassMemberImpl _node;
+
+  _ClassMemberReader(this.unitReader, this.offset, this._members)
+      : _membersIndex = _members.length {
+    _members.add(null);
+  }
+
+  @override
+  AstNode get node {
+    if (_node == null) {
+      var astReader = AstBinaryReader(
+        reader: unitReader,
+      );
+      unitReader.astReader.offset = offset;
+      _node = astReader.readNode() as ClassMemberImpl;
+      _members[_membersIndex] = _node;
+    }
+    return _node;
+  }
+
+  @override
+  void readIndex() {}
+}
+
+class _ClassReader extends _UnitMemberReader {
+  final Reference reference;
+  final int indexOffset;
+
+  bool _hasIndex = false;
+  final List<_ClassMemberReader> _classMemberReaders = [];
+  List<ClassMember> _classMembers;
+
+  _ClassReader({
+    @required this.reference,
+    @required UnitReader unitReader,
+    @required int offset,
+    @required CompilationUnit unit,
+    @required this.indexOffset,
+  }) : super(unitReader, offset, unit) {
+    reference.nodeAccessor ??= this;
+  }
+
+  List<_ClassMemberReader> get classMemberReaders {
+    readIndex();
+    return _classMemberReaders;
+  }
+
+  List<ClassMember> get classMembers {
+    return classMemberReaders.map((e) => e.node as ClassMember).toList();
+  }
+
+  @override
+  void readIndex() {
+    if (_hasIndex) return;
+    _hasIndex = true;
+
+    var node = _node;
+    if (node == null) {
+      throw StateError('The class node must be read before reading members.');
+    }
+
+    if (node is ClassDeclarationImpl) {
+      _classMembers = node.members;
+    } else if (node is ExtensionDeclarationImpl) {
+      _classMembers = node.members;
+    } else if (node is MixinDeclarationImpl) {
+      _classMembers = node.members;
+    } else {
+      throw StateError('(${node.runtimeType}) $node');
+    }
+
+    unitReader.astReader.offset = indexOffset;
+
+    var length = unitReader.astReader.readUInt30();
+    for (var i = 0; i < length; i++) {
+      var offset = unitReader.astReader.readUInt30();
+      var tag = unitReader.astReader.readByte();
+      if (tag == Tag.ConstructorDeclaration) {
+        var reader = _ClassMemberReader(unitReader, offset, _classMembers);
+        _classMemberReaders.add(reader);
+        var name = unitReader.astReader.readStringReference();
+        var reference = this.reference.getChild('@constructor').getChild(name);
+        reference.nodeAccessor ??= reader;
+      } else if (tag == Tag.MethodDeclaration) {
+        var reader = _ClassMemberReader(unitReader, offset, _classMembers);
+        _classMemberReaders.add(reader);
+        var name = unitReader.astReader.readStringReference();
+        var reference = this.reference.getChild('@method').getChild(name);
+        reference.nodeAccessor ??= reader;
+      } else if (tag == Tag.MethodDeclaration_getter) {
+        var reader = _ClassMemberReader(unitReader, offset, _classMembers);
+        _classMemberReaders.add(reader);
+        var name = unitReader.astReader.readStringReference();
+        var reference = this.reference.getChild('@getter').getChild(name);
+        reference.nodeAccessor ??= reader;
+      } else if (tag == Tag.MethodDeclaration_setter) {
+        var reader = _ClassMemberReader(unitReader, offset, _classMembers);
+        _classMemberReaders.add(reader);
+        var name = unitReader.astReader.readStringReference();
+        var reference = this.reference.getChild('@setter').getChild(name);
+        reference.nodeAccessor ??= reader;
+      } else if (tag == Tag.FieldDeclaration) {
+        var reader = _ClassMemberReader(unitReader, offset, _classMembers);
+        _classMemberReaders.add(reader);
+        var length = unitReader.astReader.readUInt30();
+        for (var i = 0; i < length; i++) {
+          var name = unitReader.astReader.readStringReference();
+          var fieldRef = reference.getChild('@field').getChild(name);
+          fieldRef.nodeAccessor ??= reader;
+          var getterRef = reference.getChild('@getter').getChild(name);
+          getterRef.nodeAccessor ??= reader;
+          var setterRef = reference.getChild('@setter').getChild(name);
+          setterRef.nodeAccessor ??= reader;
+        }
+      } else {
+        throw UnimplementedError('tag: $tag');
+      }
+    }
+  }
+}
+
+class _ReferenceReader {
+  final LinkedElementFactory elementFactory;
+  final SummaryDataReader _reader;
+  Uint32List _parents;
+  Uint32List _names;
+  List<Reference> _references;
+
+  _ReferenceReader(this.elementFactory, this._reader, int offset) {
+    _reader.offset = offset;
+    _parents = _reader.readUint30List();
+    _names = _reader.readUint30List();
+    assert(_parents.length == _names.length);
+
+    _references = List.filled(_names.length, null);
+  }
+
+  Reference referenceOfIndex(int index) {
+    var reference = _references[index];
+    if (reference != null) {
+      return reference;
+    }
+
+    if (index == 0) {
+      reference = elementFactory.rootReference;
+      _references[index] = reference;
+      return reference;
+    }
+
+    var nameIndex = _names[index];
+    var name = _reader.stringOfIndex(nameIndex);
+
+    var parentIndex = _parents[index];
+    var parent = referenceOfIndex(parentIndex);
+
+    reference = parent.getChild(name);
+    _references[index] = reference;
+
+    return reference;
+  }
+}
+
+class _UnitMemberReader implements ReferenceNodeAccessor {
+  final UnitReader unitReader;
+  final int offset;
+  final CompilationUnit _unit;
+  final int _index;
+  CompilationUnitMemberImpl _node;
+
+  _UnitMemberReader(this.unitReader, this.offset, this._unit)
+      : _index = _unit.declarations.length {
+    _unit.declarations.add(null);
+  }
+
+  @override
+  AstNode get node {
+    if (_node == null) {
+      var astReader = AstBinaryReader(
+        reader: unitReader,
+      );
+      unitReader.astReader.offset = offset;
+      _node = astReader.readNode() as CompilationUnitMember;
+      _unit.declarations[_index] = _node;
+
+      var hasLinkedContext = _node as HasAstLinkedContext;
+      var linkedContext = hasLinkedContext.linkedContext as LinkedContext;
+      linkedContext._reader = this;
+    }
+    return _node;
+  }
+
+  @override
+  void readIndex() {}
+}
diff --git a/pkg/analyzer/lib/src/summary2/bundle_writer.dart b/pkg/analyzer/lib/src/summary2/bundle_writer.dart
new file mode 100644
index 0000000..0da35249
--- /dev/null
+++ b/pkg/analyzer/lib/src/summary2/bundle_writer.dart
@@ -0,0 +1,698 @@
+// Copyright (c) 2020, 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:typed_data';
+
+import 'package:analyzer/dart/ast/ast.dart';
+import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/dart/element/nullability_suffix.dart';
+import 'package:analyzer/dart/element/type.dart';
+import 'package:analyzer/src/dart/element/element.dart';
+import 'package:analyzer/src/dart/element/member.dart';
+import 'package:analyzer/src/dart/element/type_algebra.dart';
+import 'package:analyzer/src/summary2/ast_binary_tag.dart';
+import 'package:analyzer/src/summary2/ast_binary_writer.dart';
+import 'package:analyzer/src/summary2/binary_format_doc.dart';
+import 'package:analyzer/src/summary2/data_writer.dart';
+import 'package:analyzer/src/summary2/reference.dart';
+import 'package:meta/meta.dart';
+
+class BundleWriter {
+  final bool withInformative;
+  BundleWriterAst _astWriter;
+  BundleWriterResolution _resolutionWriter;
+
+  BundleWriter(this.withInformative, Reference dynamicReference) {
+    _astWriter = BundleWriterAst(withInformative);
+    _resolutionWriter = BundleWriterResolution(dynamicReference);
+  }
+
+  void addLibrary(LibraryToWrite library) {
+    var resolutionLibrary = _resolutionWriter.enterLibrary(library);
+
+    var astUnitOffsets = <int>[];
+    for (var unit in library.units) {
+      var resolutionUnit = resolutionLibrary.enterUnit(unit);
+      var offset = _astWriter.writeUnit(unit.node, resolutionUnit);
+      astUnitOffsets.add(offset);
+    }
+
+    _astWriter.writeLibrary(library.units[0].node, astUnitOffsets);
+  }
+
+  BundleWriterResult finish() {
+    var astBytes = _astWriter.finish();
+    var resolutionBytes = _resolutionWriter.finish();
+    return BundleWriterResult(
+      astBytes: astBytes,
+      resolutionBytes: resolutionBytes,
+    );
+  }
+}
+
+class BundleWriterAst {
+  final bool withInformative;
+  final ByteSink _byteSink = ByteSink();
+  BufferedSink sink;
+  final StringIndexer stringIndexer = StringIndexer();
+
+  final List<int> _libraryOffsets = [];
+
+  BundleWriterAst(this.withInformative) {
+    sink = BufferedSink(_byteSink);
+    sink.writeByte(withInformative ? 1 : 0);
+  }
+
+  Uint8List finish() {
+    var librariesOffset = sink.offset;
+    sink.writeUint30List(_libraryOffsets);
+
+    var stringTableOffset = stringIndexer.write(sink);
+
+    sink.writeUInt32(librariesOffset);
+    sink.writeUInt32(stringTableOffset);
+
+    sink.flushAndDestroy();
+    return _byteSink.builder.takeBytes();
+  }
+
+  /// Write the library name and offset, and pointers to [unitOffsets].
+  void writeLibrary(CompilationUnit definingUnit, List<int> unitOffsets) {
+    _libraryOffsets.add(sink.offset);
+
+    var name = '';
+    var nameOffset = -1;
+    var nameLength = 0;
+    for (var directive in definingUnit.directives) {
+      if (directive is LibraryDirective) {
+        name = directive.name.components.map((e) => e.name).join('.');
+        nameOffset = directive.name.offset;
+        nameLength = directive.name.length;
+        break;
+      }
+    }
+
+    var hasPartOfDirective = false;
+    for (var directive in definingUnit.directives) {
+      if (directive is PartOfDirective) {
+        hasPartOfDirective = true;
+        break;
+      }
+    }
+
+    _writeStringReference(name);
+    sink.writeUInt30(1 + nameOffset);
+    sink.writeUInt30(nameLength);
+    sink.writeByte(hasPartOfDirective ? 1 : 0);
+    sink.writeUint30List(unitOffsets);
+  }
+
+  /// Write the [node] into the [sink].
+  /// While visiting AST, store the resolution into [resolutionUnit].
+  ///
+  /// Return the pointer at [AstUnitFormat.headerOffset].
+  int writeUnit(CompilationUnit node, ResolutionUnit resolutionUnit) {
+    var headerOffset = sink.offset;
+
+    var unitWriter = AstBinaryWriter(
+      bundleWriterAst: this,
+      resolutionUnit: resolutionUnit,
+    );
+    node.accept(unitWriter);
+
+    var indexOffset = sink.offset;
+    sink.writeUInt30(headerOffset);
+
+    sink.writeUInt30(unitWriter.unitMemberIndexItems.length);
+    for (var declaration in unitWriter.unitMemberIndexItems) {
+      sink.writeUInt30(declaration.offset);
+      sink.writeByte(declaration.tag);
+      if (declaration.name != null) {
+        _writeStringReference(declaration.name);
+      } else {
+        sink.writeList(declaration.variableNames, _writeStringReference);
+      }
+      if (declaration.classIndexOffset != 0) {
+        sink.writeUInt30(declaration.classIndexOffset);
+      }
+    }
+
+    return indexOffset;
+  }
+
+  void _writeStringReference(String string) {
+    var index = stringIndexer[string];
+    sink.writeUInt30(index);
+  }
+}
+
+class BundleWriterResolution {
+  _BundleWriterReferences _references;
+  final ByteSink _byteSink = ByteSink();
+  BufferedSink _sink;
+  ResolutionSink _resolutionSink;
+
+  final StringIndexer _stringIndexer = StringIndexer();
+
+  final List<_ResolutionLibrary> _libraries = [];
+
+  BundleWriterResolution(Reference dynamicReference) {
+    _references = _BundleWriterReferences(dynamicReference);
+
+    _sink = BufferedSink(_byteSink);
+    _resolutionSink = ResolutionSink(
+      stringIndexer: _stringIndexer,
+      sink: _sink,
+      references: _references,
+    );
+  }
+
+  _ResolutionLibrary enterLibrary(LibraryToWrite libraryToWrite) {
+    var library = _ResolutionLibrary(
+      sink: _resolutionSink,
+      library: libraryToWrite,
+    );
+    _libraries.add(library);
+    return library;
+  }
+
+  Uint8List finish() {
+    var libraryOffsets = <int>[];
+    for (var library in _libraries) {
+      var unitOffsets = <int>[];
+      for (var unit in library.units) {
+        unitOffsets.add(_sink.offset);
+        _writeStringReference(unit.unit.uriStr);
+        _sink.writeByte(unit.unit.isSynthetic ? 1 : 0);
+        _sink.writeByte(unit.unit.partUriStr != null ? 1 : 0);
+        _writeStringReference(unit.unit.partUriStr ?? '');
+        _sink.writeUInt30(unit.directivesOffset);
+        _sink.writeUint30List(unit.offsets);
+      }
+      libraryOffsets.add(_sink.offset);
+      _writeStringReference(library.library.uriStr);
+      _sink.writeUint30List(unitOffsets);
+      _writeReferences(library.library.exports);
+    }
+
+    _references._clearIndexes();
+
+    var librariesOffset = _sink.offset;
+    _sink.writeUint30List(libraryOffsets);
+
+    var referencesOffset = _sink.offset;
+    _sink.writeUint30List(_references._referenceParents);
+    _writeStringList(_references._referenceNames);
+
+    var stringTableOffset = _stringIndexer.write(_sink);
+
+    // Write as Uint32 so that we know where it is.
+    _sink.writeUInt32(librariesOffset);
+    _sink.writeUInt32(referencesOffset);
+    _sink.writeUInt32(stringTableOffset);
+
+    _sink.flushAndDestroy();
+    return _byteSink.builder.takeBytes();
+  }
+
+  void _writeReferences(List<Reference> references) {
+    var length = references.length;
+    _sink.writeUInt30(length);
+
+    for (var reference in references) {
+      var index = _references._indexOfReference(reference);
+      _sink.writeUInt30(index);
+    }
+  }
+
+  void _writeStringList(List<String> values) {
+    _sink.writeUInt30(values.length);
+    for (var value in values) {
+      _writeStringReference(value);
+    }
+  }
+
+  void _writeStringReference(String string) {
+    var index = _stringIndexer[string];
+    _sink.writeUInt30(index);
+  }
+}
+
+class BundleWriterResult {
+  final Uint8List astBytes;
+  final Uint8List resolutionBytes;
+
+  BundleWriterResult({
+    @required this.astBytes,
+    @required this.resolutionBytes,
+  });
+}
+
+class LibraryToWrite {
+  final String uriStr;
+  final List<Reference> exports;
+  final List<UnitToWrite> units;
+
+  LibraryToWrite({
+    @required this.uriStr,
+    @required this.exports,
+    @required this.units,
+  });
+}
+
+class ResolutionSink {
+  final StringIndexer _stringIndexer;
+  final BufferedSink _sink;
+  final _BundleWriterReferences _references2;
+  final _LocalElementIndexer localElements = _LocalElementIndexer();
+
+  ResolutionSink({
+    @required StringIndexer stringIndexer,
+    @required BufferedSink sink,
+    @required _BundleWriterReferences references,
+  })  : _stringIndexer = stringIndexer,
+        _sink = sink,
+        _references2 = references;
+
+  int get offset => _sink.offset;
+
+  void writeByte(int byte) {
+    assert((byte & 0xFF) == byte);
+    _sink.addByte(byte);
+  }
+
+  /// TODO(scheglov) Triage places where we write elements.
+  /// Some of then cannot be members, e.g. type names.
+  void writeElement(Element element) {
+    if (element is Member) {
+      var declaration = element.declaration;
+      var isLegacy = element.isLegacy;
+
+      var typeArguments = _enclosingClassTypeArguments(
+        declaration,
+        element.substitution.map,
+      );
+
+      writeByte(
+        isLegacy
+            ? Tag.MemberLegacyWithTypeArguments
+            : Tag.MemberWithTypeArguments,
+      );
+
+      writeElement0(declaration);
+      _writeTypeList(typeArguments);
+    } else {
+      writeByte(Tag.RawElement);
+      writeElement0(element);
+    }
+  }
+
+  void writeElement0(Element element) {
+    assert(element is! Member, 'Use writeMemberOrElement()');
+    var elementIndex = _indexOfElement(element);
+    _sink.writeUInt30(elementIndex);
+  }
+
+  void writeStringList(List<String> values) {
+    _sink.writeUInt30(values.length);
+    for (var value in values) {
+      _writeStringReference(value);
+    }
+  }
+
+  void writeType(DartType type) {
+    if (type == null) {
+      writeByte(Tag.NullType);
+    } else if (type is DynamicType) {
+      writeByte(Tag.DynamicType);
+    } else if (type is FunctionType) {
+      _writeFunctionType(type);
+    } else if (type is InterfaceType) {
+      writeByte(Tag.InterfaceType);
+      // TODO(scheglov) Write raw
+      writeElement(type.element);
+      var typeArguments = type.typeArguments;
+      _sink.writeUInt30(typeArguments.length);
+      for (var i = 0; i < typeArguments.length; ++i) {
+        writeType(typeArguments[i]);
+      }
+      _writeNullabilitySuffix(type.nullabilitySuffix);
+    } else if (type is NeverType) {
+      writeByte(Tag.NeverType);
+      _writeNullabilitySuffix(type.nullabilitySuffix);
+    } else if (type is TypeParameterType) {
+      writeByte(Tag.TypeParameterType);
+      writeElement(type.element);
+      _writeNullabilitySuffix(type.nullabilitySuffix);
+    } else if (type is VoidType) {
+      writeByte(Tag.VoidType);
+    } else {
+      // TODO
+      throw UnimplementedError('${type.runtimeType}');
+    }
+  }
+
+  int _indexOfElement(Element element) {
+    if (element == null) return 0;
+    if (element is MultiplyDefinedElement) return 0;
+    assert(element is! Member);
+
+    // Positional parameters cannot be referenced outside of their scope,
+    // so don't have a reference, so are stored as local elements.
+    if (element is ParameterElementImpl && element.reference == null) {
+      return localElements[element] << 1 | 0x1;
+    }
+
+    // Type parameters cannot be referenced outside of their scope,
+    // so don't have a reference, so are stored as local elements.
+    if (element is TypeParameterElement) {
+      return localElements[element] << 1 | 0x1;
+    }
+
+    if (identical(element, DynamicElementImpl.instance)) {
+      return _references2._indexOfReference(_references2.dynamicReference) << 1;
+    }
+
+    var reference = (element as ElementImpl).reference;
+    return _references2._indexOfReference(reference) << 1;
+  }
+
+  void _writeFormalParameterKind(ParameterElement p) {
+    if (p.isRequiredPositional) {
+      writeByte(Tag.ParameterKindRequiredPositional);
+    } else if (p.isOptionalPositional) {
+      writeByte(Tag.ParameterKindOptionalPositional);
+    } else if (p.isRequiredNamed) {
+      writeByte(Tag.ParameterKindRequiredNamed);
+    } else if (p.isOptionalNamed) {
+      writeByte(Tag.ParameterKindOptionalNamed);
+    } else {
+      throw StateError('Unexpected parameter kind: $p');
+    }
+  }
+
+  void _writeFunctionType(FunctionType type) {
+    type = _toSyntheticFunctionType(type);
+
+    writeByte(Tag.FunctionType);
+
+    localElements.pushScope();
+
+    var typeParameters = type.typeFormals;
+    for (var typeParameter in type.typeFormals) {
+      localElements.declare(typeParameter);
+    }
+
+    _sink.writeUInt30(typeParameters.length);
+    for (var typeParameter in type.typeFormals) {
+      _writeStringReference(typeParameter.name);
+    }
+    for (var typeParameter in type.typeFormals) {
+      writeType(typeParameter.bound);
+    }
+
+    Element typedefElement;
+    List<DartType> typedefTypeArguments = const <DartType>[];
+    if (type.element is FunctionTypeAliasElement) {
+      typedefElement = type.element;
+      typedefTypeArguments = type.typeArguments;
+    }
+    // TODO(scheglov) Cleanup to always use FunctionTypeAliasElement.
+    if (type.element is GenericFunctionTypeElement &&
+        type.element.enclosingElement is FunctionTypeAliasElement) {
+      typedefElement = type.element.enclosingElement;
+      typedefTypeArguments = type.typeArguments;
+    }
+
+    writeElement(typedefElement);
+    _writeTypeList(typedefTypeArguments);
+
+    writeType(type.returnType);
+
+    var parameters = type.parameters;
+    _sink.writeUInt30(parameters.length);
+    for (var parameter in parameters) {
+      _writeFormalParameterKind(parameter);
+      assert(parameter.type != null);
+      writeType(parameter.type);
+      // TODO(scheglov) Don't write names of positional parameters
+      _writeStringReference(parameter.name);
+    }
+
+    _writeNullabilitySuffix(type.nullabilitySuffix);
+
+    localElements.popScope();
+  }
+
+  void _writeNullabilitySuffix(NullabilitySuffix suffix) {
+    writeByte(suffix.index);
+  }
+
+  void _writeStringReference(String string) {
+    var index = _stringIndexer[string];
+    _sink.writeUInt30(index);
+  }
+
+  void _writeTypeList(List<DartType> types) {
+    _sink.writeUInt30(types.length);
+    for (var type in types) {
+      writeType(type);
+    }
+  }
+
+  static List<DartType> _enclosingClassTypeArguments(
+    Element declaration,
+    Map<TypeParameterElement, DartType> substitution,
+  ) {
+    var enclosing = declaration.enclosingElement;
+    if (enclosing is TypeParameterizedElement) {
+      if (enclosing is! ClassElement && enclosing is! ExtensionElement) {
+        return const <DartType>[];
+      }
+
+      var typeParameters = enclosing.typeParameters;
+      if (typeParameters.isEmpty) {
+        return const <DartType>[];
+      }
+
+      return typeParameters
+          .map((typeParameter) => substitution[typeParameter])
+          .toList(growable: false);
+    }
+
+    return const <DartType>[];
+  }
+
+  static FunctionType _toSyntheticFunctionType(FunctionType type) {
+    var typeParameters = type.typeFormals;
+
+    if (typeParameters.isEmpty) return type;
+
+    var onlySyntheticTypeParameters = typeParameters.every((e) {
+      return e is TypeParameterElementImpl && e.linkedNode == null;
+    });
+    if (onlySyntheticTypeParameters) return type;
+
+    var parameters = getFreshTypeParameters(typeParameters);
+    return parameters.applyToFunctionType(type);
+  }
+}
+
+class ResolutionUnit {
+  final _ResolutionLibrary library;
+  final UnitToWrite unit;
+
+  /// The offset of the resolution data for directives.
+  final int directivesOffset;
+
+  /// The offsets of resolution data for each declaration - class, method, etc.
+  final List<int> offsets = [];
+
+  ResolutionUnit({
+    @required this.library,
+    @required this.unit,
+    @required this.directivesOffset,
+  });
+
+  /// Should be called on enter into a new declaration on which level
+  /// resolution is stored, e.g. [ClassDeclaration] (header), or
+  /// [MethodDeclaration] (header), or [FieldDeclaration] (all).
+  int enterDeclaration() {
+    var index = offsets.length;
+    offsets.add(library.sink.offset);
+    return index;
+  }
+}
+
+class StringIndexer {
+  final Map<String, int> _index = {};
+
+  int operator [](String string) {
+    var result = _index[string];
+
+    if (result == null) {
+      result = _index.length;
+      _index[string] = result;
+    }
+
+    return result;
+  }
+
+  int write(BufferedSink sink) {
+    var bytesOffset = sink.offset;
+
+    var length = _index.length;
+    var lengths = Uint32List(length);
+    var lengthsIndex = 0;
+    for (var key in _index.keys) {
+      var stringStart = sink.offset;
+      _writeWtf8(sink, key);
+      lengths[lengthsIndex++] = sink.offset - stringStart;
+    }
+
+    var resultOffset = sink.offset;
+
+    var lengthOfBytes = sink.offset - bytesOffset;
+    sink.writeUInt30(lengthOfBytes);
+    sink.writeUint30List(lengths);
+
+    return resultOffset;
+  }
+
+  /// Write [source] string into [sink].
+  static void _writeWtf8(BufferedSink sink, String source) {
+    var end = source.length;
+    if (end == 0) {
+      return;
+    }
+
+    int i = 0;
+    do {
+      var codeUnit = source.codeUnitAt(i++);
+      if (codeUnit < 128) {
+        // ASCII.
+        sink.addByte(codeUnit);
+      } else if (codeUnit < 0x800) {
+        // Two-byte sequence (11-bit unicode value).
+        sink.addByte(0xC0 | (codeUnit >> 6));
+        sink.addByte(0x80 | (codeUnit & 0x3f));
+      } else if ((codeUnit & 0xFC00) == 0xD800 &&
+          i < end &&
+          (source.codeUnitAt(i) & 0xFC00) == 0xDC00) {
+        // Surrogate pair -> four-byte sequence (non-BMP unicode value).
+        int codeUnit2 = source.codeUnitAt(i++);
+        int unicode =
+            0x10000 + ((codeUnit & 0x3FF) << 10) + (codeUnit2 & 0x3FF);
+        sink.addByte(0xF0 | (unicode >> 18));
+        sink.addByte(0x80 | ((unicode >> 12) & 0x3F));
+        sink.addByte(0x80 | ((unicode >> 6) & 0x3F));
+        sink.addByte(0x80 | (unicode & 0x3F));
+      } else {
+        // Three-byte sequence (16-bit unicode value), including lone
+        // surrogates.
+        sink.addByte(0xE0 | (codeUnit >> 12));
+        sink.addByte(0x80 | ((codeUnit >> 6) & 0x3f));
+        sink.addByte(0x80 | (codeUnit & 0x3f));
+      }
+    } while (i < end);
+  }
+}
+
+class UnitToWrite {
+  final String uriStr;
+  final String partUriStr;
+  final CompilationUnit node;
+  final bool isSynthetic;
+
+  UnitToWrite({
+    @required this.uriStr,
+    @required this.partUriStr,
+    @required this.node,
+    @required this.isSynthetic,
+  });
+}
+
+class _BundleWriterReferences {
+  /// The `dynamic` class is declared in `dart:core`, but is not a class.
+  /// Also, it is static, so we cannot set `reference` for it.
+  /// So, we have to push it in a separate way.
+  final Reference dynamicReference;
+
+  /// References used in all libraries being linked.
+  /// Element references in nodes are indexes in this list.
+  final List<Reference> references = [null];
+
+  final List<int> _referenceParents = [0];
+  final List<String> _referenceNames = [''];
+
+  _BundleWriterReferences(this.dynamicReference);
+
+  /// We need indexes for references during linking, but once we are done,
+  /// we must clear indexes to make references ready for linking a next bundle.
+  void _clearIndexes() {
+    for (var reference in references) {
+      if (reference != null) {
+        reference.index = null;
+      }
+    }
+  }
+
+  int _indexOfReference(Reference reference) {
+    if (reference == null) return 0;
+    if (reference.parent == null) return 0;
+    if (reference.index != null) return reference.index;
+
+    var parentIndex = _indexOfReference(reference.parent);
+    _referenceParents.add(parentIndex);
+    _referenceNames.add(reference.name);
+
+    reference.index = references.length;
+    references.add(reference);
+    return reference.index;
+  }
+}
+
+class _LocalElementIndexer {
+  final Map<Element, int> _index = Map.identity();
+  final List<int> _scopes = [];
+  int _stackHeight = 0;
+
+  int operator [](Element element) {
+    return _index[element] ??
+        (throw ArgumentError('Unexpectedly not indexed: $element'));
+  }
+
+  void declare(Element element) {
+    _index[element] = _stackHeight++;
+  }
+
+  void popScope() {
+    _stackHeight = _scopes.removeLast();
+  }
+
+  void pushScope() {
+    _scopes.add(_stackHeight);
+  }
+}
+
+class _ResolutionLibrary {
+  final ResolutionSink sink;
+  final LibraryToWrite library;
+  final List<ResolutionUnit> units = [];
+
+  _ResolutionLibrary({
+    @required this.sink,
+    @required this.library,
+  });
+
+  ResolutionUnit enterUnit(UnitToWrite unitToWrite) {
+    var unit = ResolutionUnit(
+      library: this,
+      unit: unitToWrite,
+      directivesOffset: sink.offset,
+    );
+    units.add(unit);
+    return unit;
+  }
+}
diff --git a/pkg/analyzer/lib/src/summary2/data_reader.dart b/pkg/analyzer/lib/src/summary2/data_reader.dart
new file mode 100644
index 0000000..143685b
--- /dev/null
+++ b/pkg/analyzer/lib/src/summary2/data_reader.dart
@@ -0,0 +1,225 @@
+// Copyright (c) 2020, 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';
+import 'dart:typed_data';
+
+import 'package:meta/meta.dart';
+
+/// Helper for reading primitive types from bytes.
+class SummaryDataReader {
+  final Uint8List bytes;
+  int offset = 0;
+
+  _StringTable _stringTable;
+
+  final Float64List _doubleBuffer = Float64List(1);
+  Uint8List _doubleBufferUint8;
+
+  SummaryDataReader(this.bytes);
+
+  void createStringTable(int offset) {
+    _stringTable = _StringTable(bytes: bytes, startOffset: offset);
+  }
+
+  @pragma("vm:prefer-inline")
+  int readByte() {
+    return bytes[offset++];
+  }
+
+  double readDouble() {
+    _doubleBufferUint8 ??= _doubleBuffer.buffer.asUint8List();
+    _doubleBufferUint8[0] = readByte();
+    _doubleBufferUint8[1] = readByte();
+    _doubleBufferUint8[2] = readByte();
+    _doubleBufferUint8[3] = readByte();
+    _doubleBufferUint8[4] = readByte();
+    _doubleBufferUint8[5] = readByte();
+    _doubleBufferUint8[6] = readByte();
+    _doubleBufferUint8[7] = readByte();
+    return _doubleBuffer[0];
+  }
+
+  String readStringReference() {
+    return _stringTable[readUInt30()];
+  }
+
+  String readStringUtf8() {
+    var bytes = readUint8List();
+    return utf8.decode(bytes);
+  }
+
+  int readUInt30() {
+    var byte = readByte();
+    if (byte & 0x80 == 0) {
+      // 0xxxxxxx
+      return byte;
+    } else if (byte & 0x40 == 0) {
+      // 10xxxxxx
+      return ((byte & 0x3F) << 8) | readByte();
+    } else {
+      // 11xxxxxx
+      return ((byte & 0x3F) << 24) |
+          (readByte() << 16) |
+          (readByte() << 8) |
+          readByte();
+    }
+  }
+
+  Uint32List readUint30List() {
+    var length = readUInt30();
+    var result = Uint32List(length);
+    for (var i = 0; i < length; ++i) {
+      result[i] = readUInt30();
+    }
+    return result;
+  }
+
+  int readUint32() {
+    return (readByte() << 24) |
+        (readByte() << 16) |
+        (readByte() << 8) |
+        readByte();
+  }
+
+  Uint32List readUint32List() {
+    var length = readUint32();
+    var result = Uint32List(length);
+    for (var i = 0; i < length; ++i) {
+      result[i] = readUint32();
+    }
+    return result;
+  }
+
+  Uint8List readUint8List() {
+    var length = readUInt30();
+    var result = Uint8List.sublistView(bytes, offset, offset + length);
+    offset += length;
+    return result;
+  }
+
+  String stringOfIndex(int index) {
+    return _stringTable[index];
+  }
+}
+
+class _StringTable {
+  final Uint8List _bytes;
+  int _byteOffset;
+
+  Uint32List _offsets;
+  Uint32List _lengths;
+  List<String> _strings;
+
+  /// The structure of the table:
+  ///   <bytes with encoded strings>
+  ///   <the length of the bytes> <-- [startOffset]
+  ///   <the number strings>
+  ///   <the array of lengths of individual strings>
+  _StringTable({
+    @required Uint8List bytes,
+    @required int startOffset,
+  }) : _bytes = bytes {
+    _byteOffset = startOffset;
+
+    var offset = startOffset - _readUInt();
+    var length = _readUInt();
+
+    _offsets = Uint32List(length);
+    _lengths = Uint32List(length);
+    for (var i = 0; i < length; i++) {
+      var stringLength = _readUInt();
+      _offsets[i] = offset;
+      _lengths[i] = stringLength;
+      offset += stringLength;
+    }
+
+    _strings = List.filled(length, null, growable: false);
+  }
+
+  String operator [](int index) {
+    var result = _strings[index];
+
+    if (result == null) {
+      result = _readStringEntry(_offsets[index], _lengths[index]);
+      _strings[index] = result;
+    }
+
+    return result;
+  }
+
+  int _readByte() {
+    return _bytes[_byteOffset++];
+  }
+
+  String _readStringEntry(int start, int numBytes) {
+    var end = start + numBytes;
+    for (var i = start; i < end; i++) {
+      if (_bytes[i] > 127) {
+        return _decodeWtf8(_bytes, start, end);
+      }
+    }
+    return String.fromCharCodes(_bytes, start, end);
+  }
+
+  int _readUInt() {
+    var byte = _readByte();
+    if (byte & 0x80 == 0) {
+      // 0xxxxxxx
+      return byte;
+    } else if (byte & 0x40 == 0) {
+      // 10xxxxxx
+      return ((byte & 0x3F) << 8) | _readByte();
+    } else {
+      // 11xxxxxx
+      return ((byte & 0x3F) << 24) |
+          (_readByte() << 16) |
+          (_readByte() << 8) |
+          _readByte();
+    }
+  }
+
+  static String _decodeWtf8(Uint8List _bytes, int start, int end) {
+    // WTF-8 decoder that trusts its input, meaning that the correctness of
+    // the code depends on the bytes from start to end being valid and
+    // complete WTF-8. Instead of masking off the control bits from every
+    // byte, it simply xor's the byte values together at their appropriate
+    // bit shifts, and then xor's out all of the control bits at once.
+    Uint16List charCodes = Uint16List(end - start);
+    int i = start;
+    int j = 0;
+    while (i < end) {
+      int byte = _bytes[i++];
+      if (byte < 0x80) {
+        // ASCII.
+        charCodes[j++] = byte;
+      } else if (byte < 0xE0) {
+        // Two-byte sequence (11-bit unicode value).
+        int byte2 = _bytes[i++];
+        int value = (byte << 6) ^ byte2 ^ 0x3080;
+        assert(value >= 0x80 && value < 0x800);
+        charCodes[j++] = value;
+      } else if (byte < 0xF0) {
+        // Three-byte sequence (16-bit unicode value).
+        int byte2 = _bytes[i++];
+        int byte3 = _bytes[i++];
+        int value = (byte << 12) ^ (byte2 << 6) ^ byte3 ^ 0xE2080;
+        assert(value >= 0x800 && value < 0x10000);
+        charCodes[j++] = value;
+      } else {
+        // Four-byte sequence (non-BMP unicode value).
+        int byte2 = _bytes[i++];
+        int byte3 = _bytes[i++];
+        int byte4 = _bytes[i++];
+        int value =
+            (byte << 18) ^ (byte2 << 12) ^ (byte3 << 6) ^ byte4 ^ 0x3C82080;
+        assert(value >= 0x10000 && value < 0x110000);
+        charCodes[j++] = 0xD7C0 + (value >> 10);
+        charCodes[j++] = 0xDC00 + (value & 0x3FF);
+      }
+    }
+    assert(i == end);
+    return String.fromCharCodes(charCodes, 0, j);
+  }
+}
diff --git a/pkg/analyzer/lib/src/summary2/data_writer.dart b/pkg/analyzer/lib/src/summary2/data_writer.dart
new file mode 100644
index 0000000..5428e5b
--- /dev/null
+++ b/pkg/analyzer/lib/src/summary2/data_writer.dart
@@ -0,0 +1,173 @@
+// Copyright (c) 2020, 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';
+import 'dart:typed_data';
+
+/// Puts a buffer in front of a [Sink<List<int>>].
+class BufferedSink {
+  static const int SIZE = 100000;
+  static const int SAFE_SIZE = SIZE - 5;
+  static const int SMALL = 10000;
+
+  final Sink<List<int>> _sink;
+
+  int flushedLength = 0;
+
+  Uint8List _buffer = Uint8List(SIZE);
+  int length = 0;
+
+  final Float64List _doubleBuffer = Float64List(1);
+  Uint8List _doubleBufferUint8;
+
+  BufferedSink(this._sink);
+
+  int get offset => flushedLength + length;
+
+  @pragma("vm:prefer-inline")
+  void addByte(int byte) {
+    _buffer[length++] = byte;
+    if (length == SIZE) {
+      _sink.add(_buffer);
+      _buffer = Uint8List(SIZE);
+      length = 0;
+      flushedLength += SIZE;
+    }
+  }
+
+  @pragma("vm:prefer-inline")
+  void addByte2(int byte1, int byte2) {
+    if (length < SAFE_SIZE) {
+      _buffer[length++] = byte1;
+      _buffer[length++] = byte2;
+    } else {
+      addByte(byte1);
+      addByte(byte2);
+    }
+  }
+
+  @pragma("vm:prefer-inline")
+  void addByte4(int byte1, int byte2, int byte3, int byte4) {
+    if (length < SAFE_SIZE) {
+      _buffer[length++] = byte1;
+      _buffer[length++] = byte2;
+      _buffer[length++] = byte3;
+      _buffer[length++] = byte4;
+    } else {
+      addByte(byte1);
+      addByte(byte2);
+      addByte(byte3);
+      addByte(byte4);
+    }
+  }
+
+  void addBytes(Uint8List bytes) {
+    // Avoid copying a large buffer into the another large buffer. Also, if
+    // the bytes buffer is too large to fit in our own buffer, just emit both.
+    if (length + bytes.length < SIZE &&
+        (bytes.length < SMALL || length < SMALL)) {
+      _buffer.setRange(length, length + bytes.length, bytes);
+      length += bytes.length;
+    } else if (bytes.length < SMALL) {
+      // Flush as much as we can in the current buffer.
+      _buffer.setRange(length, SIZE, bytes);
+      _sink.add(_buffer);
+      // Copy over the remainder into a new buffer. It is guaranteed to fit
+      // because the input byte array is small.
+      int alreadyEmitted = SIZE - length;
+      int remainder = bytes.length - alreadyEmitted;
+      _buffer = Uint8List(SIZE);
+      _buffer.setRange(0, remainder, bytes, alreadyEmitted);
+      length = remainder;
+      flushedLength += SIZE;
+    } else {
+      flush();
+      _sink.add(bytes);
+      flushedLength += bytes.length;
+    }
+  }
+
+  void addDouble(double value) {
+    _doubleBufferUint8 ??= _doubleBuffer.buffer.asUint8List();
+    _doubleBuffer[0] = value;
+    addByte4(_doubleBufferUint8[0], _doubleBufferUint8[1],
+        _doubleBufferUint8[2], _doubleBufferUint8[3]);
+    addByte4(_doubleBufferUint8[4], _doubleBufferUint8[5],
+        _doubleBufferUint8[6], _doubleBufferUint8[7]);
+  }
+
+  void flush() {
+    _sink.add(_buffer.sublist(0, length));
+    _buffer = Uint8List(SIZE);
+    flushedLength += length;
+    length = 0;
+  }
+
+  void flushAndDestroy() {
+    _sink.add(_buffer.sublist(0, length));
+  }
+
+  @pragma("vm:prefer-inline")
+  void writeByte(int byte) {
+    assert((byte & 0xFF) == byte);
+    addByte(byte);
+  }
+
+  void writeList<T>(List<T> items, void Function(T x) writeItem) {
+    writeUInt30(items.length);
+    for (var i = 0; i < items.length; i++) {
+      writeItem(items[i]);
+    }
+  }
+
+  /// Write the [value] as UTF8 encoded byte array.
+  void writeStringUtf8(String value) {
+    var bytes = utf8.encode(value);
+    writeUint8List(bytes);
+  }
+
+  @pragma("vm:prefer-inline")
+  void writeUInt30(int value) {
+    assert(value >= 0 && value >> 30 == 0);
+    if (value < 0x80) {
+      addByte(value);
+    } else if (value < 0x4000) {
+      addByte2((value >> 8) | 0x80, value & 0xFF);
+    } else {
+      addByte4((value >> 24) | 0xC0, (value >> 16) & 0xFF, (value >> 8) & 0xFF,
+          value & 0xFF);
+    }
+  }
+
+  void writeUint30List(List<int> values) {
+    var length = values.length;
+    writeUInt30(length);
+    for (var i = 0; i < length; i++) {
+      writeUInt30(values[i]);
+    }
+  }
+
+  void writeUInt32(int value) {
+    addByte4((value >> 24) & 0xFF, (value >> 16) & 0xFF, (value >> 8) & 0xFF,
+        value & 0xFF);
+  }
+
+  void writeUint8List(Uint8List bytes) {
+    writeUInt30(bytes.length);
+    addBytes(bytes);
+  }
+}
+
+/// A [Sink] that directly writes data into a byte builder.
+class ByteSink implements Sink<List<int>> {
+  final BytesBuilder builder = BytesBuilder(copy: false);
+
+  @override
+  void add(List<int> data) {
+    builder.add(data);
+  }
+
+  @override
+  void close() {}
+}
diff --git a/pkg/analyzer/lib/src/summary2/default_types_builder.dart b/pkg/analyzer/lib/src/summary2/default_types_builder.dart
index 4a8d0c5..ad8c510 100644
--- a/pkg/analyzer/lib/src/summary2/default_types_builder.dart
+++ b/pkg/analyzer/lib/src/summary2/default_types_builder.dart
@@ -10,7 +10,6 @@
 import 'package:analyzer/src/dart/element/type.dart';
 import 'package:analyzer/src/dart/resolver/variance.dart';
 import 'package:analyzer/src/summary2/function_type_builder.dart';
-import 'package:analyzer/src/summary2/lazy_ast.dart';
 import 'package:analyzer/src/summary2/named_type_builder.dart';
 import 'package:analyzer/src/summary2/type_builder.dart';
 import 'package:analyzer/src/util/graph.dart';
@@ -137,10 +136,11 @@
     if (parameterList == null) return;
 
     for (var parameter in parameterList.typeParameters) {
-      var defaultType = LazyAst.getDefaultType(parameter);
+      var element = parameter.declaredElement as TypeParameterElementImpl;
+      var defaultType = element.defaultType;
       if (defaultType is TypeBuilder) {
         var builtType = defaultType.build();
-        LazyAst.setDefaultType(parameter, builtType);
+        element.defaultType = builtType;
       }
     }
   }
@@ -211,7 +211,8 @@
 
     // Set computed TypeBuilder(s) as default types.
     for (var i = 0; i < length; i++) {
-      LazyAst.setDefaultType(nodes[i], bounds[i]);
+      var element = nodes[i].declaredElement as TypeParameterElementImpl;
+      element.defaultType = bounds[i];
     }
   }
 
@@ -235,6 +236,7 @@
           void recurseParameters(List<TypeParameterElement> parameters) {
             for (TypeParameterElementImpl parameter in parameters) {
               TypeParameter parameterNode = parameter.linkedNode;
+              // TODO(scheglov) How to we skip already linked?
               var bound = parameterNode.bound;
               if (bound != null) {
                 var tails = _findRawTypePathsToDeclaration(
diff --git a/pkg/analyzer/lib/src/summary2/function_type_builder.dart b/pkg/analyzer/lib/src/summary2/function_type_builder.dart
index a4c8987..4fd730d 100644
--- a/pkg/analyzer/lib/src/summary2/function_type_builder.dart
+++ b/pkg/analyzer/lib/src/summary2/function_type_builder.dart
@@ -12,7 +12,6 @@
 import 'package:analyzer/src/dart/element/element.dart';
 import 'package:analyzer/src/dart/element/type.dart';
 import 'package:analyzer/src/dart/element/type_visitor.dart';
-import 'package:analyzer/src/summary2/lazy_ast.dart';
 import 'package:analyzer/src/summary2/type_builder.dart';
 
 /// The type builder for a [GenericFunctionType].
@@ -97,7 +96,6 @@
 
     if (node != null) {
       node.type = _type;
-      LazyAst.setReturnType(node, builtReturnType ?? _dynamicType);
     }
 
     return _type;
diff --git a/pkg/analyzer/lib/src/summary2/informative_data.dart b/pkg/analyzer/lib/src/summary2/informative_data.dart
deleted file mode 100644
index acb0fa8..0000000
--- a/pkg/analyzer/lib/src/summary2/informative_data.dart
+++ /dev/null
@@ -1,436 +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 'package:analyzer/dart/ast/ast.dart';
-import 'package:analyzer/dart/ast/visitor.dart';
-import 'package:analyzer/src/summary/format.dart';
-
-/// Create informative data for nodes that need it, and set IDs of this
-/// data to the nodes.
-List<UnlinkedInformativeDataBuilder> createInformativeData(
-    CompilationUnit unit) {
-  var visitor = _SetInformativeId();
-  unit.accept(visitor);
-  return visitor.dataList;
-}
-
-/// If [createInformativeData] set the informative data identifier for the
-/// [node], return it, otherwise return zero.
-int getInformativeId(AstNode node) {
-  int id = node.getProperty(_SetInformativeId.ID);
-  return id ?? 0;
-}
-
-class _SetInformativeId extends SimpleAstVisitor<void> {
-  static final String ID = 'informativeId';
-
-  final List<UnlinkedInformativeDataBuilder> dataList = [];
-
-  void setData(AstNode node, UnlinkedInformativeDataBuilder data) {
-    var id = 1 + dataList.length;
-    node.setProperty(ID, id);
-    dataList.add(data);
-  }
-
-  @override
-  void visitClassDeclaration(ClassDeclaration node) {
-    setData(
-      node,
-      UnlinkedInformativeDataBuilder.classDeclaration(
-        codeOffset: node.offset,
-        codeLength: node.length,
-        documentationComment_tokens: _nodeCommentTokens(node),
-        nameOffset: node.name.offset,
-      ),
-    );
-
-    node.typeParameters?.accept(this);
-    node.members.accept(this);
-  }
-
-  @override
-  void visitClassTypeAlias(ClassTypeAlias node) {
-    setData(
-      node,
-      UnlinkedInformativeDataBuilder.classTypeAlias(
-        codeOffset: node.offset,
-        codeLength: node.length,
-        documentationComment_tokens: _nodeCommentTokens(node),
-        nameOffset: node.name.offset,
-      ),
-    );
-
-    node.typeParameters?.accept(this);
-  }
-
-  @override
-  void visitCompilationUnit(CompilationUnit node) {
-    setData(
-      node,
-      UnlinkedInformativeDataBuilder.compilationUnit(
-        codeOffset: node.offset,
-        codeLength: node.length,
-        compilationUnit_lineStarts: node.lineInfo.lineStarts,
-      ),
-    );
-
-    node.directives.accept(this);
-    node.declarations.accept(this);
-  }
-
-  @override
-  void visitConstructorDeclaration(ConstructorDeclaration node) {
-    setData(
-      node,
-      UnlinkedInformativeDataBuilder.constructorDeclaration(
-        codeOffset: node.offset,
-        codeLength: node.length,
-        documentationComment_tokens: _nodeCommentTokens(node),
-        nameOffset: node.name?.offset ?? 0,
-        constructorDeclaration_periodOffset: node.period?.offset ?? 0,
-        constructorDeclaration_returnTypeOffset: node.returnType.offset,
-      ),
-    );
-
-    node.parameters?.accept(this);
-  }
-
-  @override
-  void visitDefaultFormalParameter(DefaultFormalParameter node) {
-    var defaultValueCode = node.defaultValue?.toSource();
-    setData(
-      node,
-      UnlinkedInformativeDataBuilder.defaultFormalParameter(
-        codeOffset: node.offset,
-        codeLength: node.length,
-        defaultFormalParameter_defaultValueCode: defaultValueCode,
-      ),
-    );
-
-    node.parameter.accept(this);
-  }
-
-  @override
-  void visitEnumConstantDeclaration(EnumConstantDeclaration node) {
-    setData(
-      node,
-      UnlinkedInformativeDataBuilder.enumConstantDeclaration(
-        codeOffset: node.offset,
-        codeLength: node.length,
-        documentationComment_tokens: _nodeCommentTokens(node),
-        nameOffset: node.name.offset,
-      ),
-    );
-  }
-
-  @override
-  void visitEnumDeclaration(EnumDeclaration node) {
-    setData(
-      node,
-      UnlinkedInformativeDataBuilder.enumDeclaration(
-        codeOffset: node.offset,
-        codeLength: node.length,
-        documentationComment_tokens: _nodeCommentTokens(node),
-        nameOffset: node.name.offset,
-      ),
-    );
-
-    node.constants.accept(this);
-  }
-
-  @override
-  void visitExportDirective(ExportDirective node) {
-    setData(
-      node,
-      UnlinkedInformativeDataBuilder.exportDirective(
-        directiveKeywordOffset: node.keyword.offset,
-      ),
-    );
-    node.combinators.accept(this);
-  }
-
-  @override
-  void visitExtensionDeclaration(ExtensionDeclaration node) {
-    setData(
-      node,
-      UnlinkedInformativeDataBuilder.extensionDeclaration(
-        codeOffset: node.offset,
-        codeLength: node.length,
-        documentationComment_tokens: _nodeCommentTokens(node),
-        nameOffset: node.name?.offset ?? 0,
-      ),
-    );
-
-    node.typeParameters?.accept(this);
-    node.members.accept(this);
-  }
-
-  @override
-  void visitFieldDeclaration(FieldDeclaration node) {
-    setData(
-      node,
-      UnlinkedInformativeDataBuilder.fieldDeclaration(
-        documentationComment_tokens: _nodeCommentTokens(node),
-      ),
-    );
-
-    node.fields.accept(this);
-  }
-
-  @override
-  void visitFieldFormalParameter(FieldFormalParameter node) {
-    setData(
-      node,
-      UnlinkedInformativeDataBuilder.fieldFormalParameter(
-        codeOffset: node.offset,
-        codeLength: node.length,
-        nameOffset: node.identifier.offset,
-      ),
-    );
-  }
-
-  @override
-  void visitFormalParameterList(FormalParameterList node) {
-    node.parameters.accept(this);
-  }
-
-  @override
-  void visitFunctionDeclaration(FunctionDeclaration node) {
-    setData(
-      node,
-      UnlinkedInformativeDataBuilder.functionDeclaration(
-        codeOffset: node.offset,
-        codeLength: node.length,
-        documentationComment_tokens: _nodeCommentTokens(node),
-        nameOffset: node.name.offset,
-      ),
-    );
-
-    node.functionExpression.accept(this);
-  }
-
-  @override
-  void visitFunctionExpression(FunctionExpression node) {
-    node.typeParameters?.accept(this);
-    node.parameters?.accept(this);
-  }
-
-  @override
-  void visitFunctionTypeAlias(FunctionTypeAlias node) {
-    setData(
-      node,
-      UnlinkedInformativeDataBuilder.functionTypeAlias(
-        codeOffset: node.offset,
-        codeLength: node.length,
-        documentationComment_tokens: _nodeCommentTokens(node),
-        nameOffset: node.name.offset,
-      ),
-    );
-
-    node.typeParameters?.accept(this);
-    node.parameters.accept(this);
-  }
-
-  @override
-  void visitFunctionTypedFormalParameter(FunctionTypedFormalParameter node) {
-    setData(
-      node,
-      UnlinkedInformativeDataBuilder.functionTypedFormalParameter(
-        codeOffset: node.offset,
-        codeLength: node.length,
-        nameOffset: node.identifier.offset,
-      ),
-    );
-  }
-
-  @override
-  void visitGenericFunctionType(GenericFunctionType node) {
-    node.typeParameters?.accept(this);
-    node.parameters.accept(this);
-  }
-
-  @override
-  void visitGenericTypeAlias(GenericTypeAlias node) {
-    setData(
-      node,
-      UnlinkedInformativeDataBuilder.genericTypeAlias(
-        codeOffset: node.offset,
-        codeLength: node.length,
-        documentationComment_tokens: _nodeCommentTokens(node),
-        nameOffset: node.name.offset,
-      ),
-    );
-
-    node.typeParameters?.accept(this);
-    node.type?.accept(this);
-  }
-
-  @override
-  void visitHideCombinator(HideCombinator node) {
-    setData(
-      node,
-      UnlinkedInformativeDataBuilder.hideCombinator(
-        combinatorEnd: node.end,
-        combinatorKeywordOffset: node.offset,
-      ),
-    );
-  }
-
-  @override
-  void visitImportDirective(ImportDirective node) {
-    setData(
-      node,
-      UnlinkedInformativeDataBuilder.importDirective(
-        directiveKeywordOffset: node.keyword.offset,
-        importDirective_prefixOffset: node.prefix?.offset ?? 0,
-      ),
-    );
-    node.combinators.accept(this);
-  }
-
-  @override
-  void visitLibraryDirective(LibraryDirective node) {
-    setData(
-      node,
-      UnlinkedInformativeDataBuilder.libraryDirective(
-        documentationComment_tokens: _nodeCommentTokens(node),
-      ),
-    );
-  }
-
-  @override
-  void visitMethodDeclaration(MethodDeclaration node) {
-    setData(
-      node,
-      UnlinkedInformativeDataBuilder.methodDeclaration(
-        codeOffset: node.offset,
-        codeLength: node.length,
-        documentationComment_tokens: _nodeCommentTokens(node),
-        nameOffset: node.name.offset,
-      ),
-    );
-
-    node.typeParameters?.accept(this);
-    node.parameters?.accept(this);
-  }
-
-  @override
-  void visitMixinDeclaration(MixinDeclaration node) {
-    setData(
-      node,
-      UnlinkedInformativeDataBuilder.mixinDeclaration(
-        codeOffset: node.offset,
-        codeLength: node.length,
-        documentationComment_tokens: _nodeCommentTokens(node),
-        nameOffset: node.name.offset,
-      ),
-    );
-
-    node.typeParameters?.accept(this);
-    node.members.accept(this);
-  }
-
-  @override
-  void visitPartDirective(PartDirective node) {
-    setData(
-      node,
-      UnlinkedInformativeDataBuilder.partDirective(
-        directiveKeywordOffset: node.keyword.offset,
-      ),
-    );
-  }
-
-  @override
-  void visitPartOfDirective(PartOfDirective node) {
-    setData(
-      node,
-      UnlinkedInformativeDataBuilder.partDirective(
-        directiveKeywordOffset: node.keyword.offset,
-      ),
-    );
-  }
-
-  @override
-  void visitShowCombinator(ShowCombinator node) {
-    setData(
-      node,
-      UnlinkedInformativeDataBuilder.showCombinator(
-        combinatorEnd: node.end,
-        combinatorKeywordOffset: node.offset,
-      ),
-    );
-  }
-
-  @override
-  void visitSimpleFormalParameter(SimpleFormalParameter node) {
-    setData(
-      node,
-      UnlinkedInformativeDataBuilder.simpleFormalParameter(
-        codeOffset: node.offset,
-        codeLength: node.length,
-        nameOffset: node.identifier?.offset ?? 0,
-      ),
-    );
-  }
-
-  @override
-  void visitTopLevelVariableDeclaration(TopLevelVariableDeclaration node) {
-    setData(
-      node,
-      UnlinkedInformativeDataBuilder.topLevelVariableDeclaration(
-        documentationComment_tokens: _nodeCommentTokens(node),
-      ),
-    );
-
-    node.variables.accept(this);
-  }
-
-  @override
-  void visitTypeParameter(TypeParameter node) {
-    setData(
-      node,
-      UnlinkedInformativeDataBuilder.typeParameter(
-        codeOffset: node.offset,
-        codeLength: node.length,
-        nameOffset: node.name.offset,
-      ),
-    );
-  }
-
-  @override
-  void visitTypeParameterList(TypeParameterList node) {
-    node.typeParameters.accept(this);
-  }
-
-  @override
-  void visitVariableDeclaration(VariableDeclaration node) {
-    var variableList = node.parent as VariableDeclarationList;
-    var isFirst = identical(variableList.variables[0], node);
-    var codeOffset = (isFirst ? variableList.parent : node).offset;
-    var codeLength = node.end - codeOffset;
-
-    setData(
-      node,
-      UnlinkedInformativeDataBuilder.variableDeclaration(
-        codeOffset: codeOffset,
-        codeLength: codeLength,
-        nameOffset: node.name.offset,
-      ),
-    );
-  }
-
-  @override
-  void visitVariableDeclarationList(VariableDeclarationList node) {
-    node.variables.accept(this);
-  }
-
-  static List<String> _commentTokens(Comment comment) {
-    if (comment == null) return null;
-    return comment.tokens.map((token) => token.lexeme).toList();
-  }
-
-  static List<String> _nodeCommentTokens(AnnotatedNode node) {
-    return _commentTokens(node.documentationComment);
-  }
-}
diff --git a/pkg/analyzer/lib/src/summary2/lazy_ast.dart b/pkg/analyzer/lib/src/summary2/lazy_ast.dart
deleted file mode 100644
index dea4fa9..0000000
--- a/pkg/analyzer/lib/src/summary2/lazy_ast.dart
+++ /dev/null
@@ -1,1974 +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 'package:analyzer/dart/ast/ast.dart';
-import 'package:analyzer/dart/element/element.dart';
-import 'package:analyzer/dart/element/type.dart';
-import 'package:analyzer/src/dart/ast/ast.dart';
-import 'package:analyzer/src/dart/resolver/variance.dart';
-import 'package:analyzer/src/summary/format.dart';
-import 'package:analyzer/src/summary/idl.dart';
-import 'package:analyzer/src/summary2/ast_binary_flags.dart';
-import 'package:analyzer/src/summary2/ast_binary_reader.dart';
-import 'package:analyzer/src/summary2/linked_unit_context.dart';
-import 'package:pub_semver/pub_semver.dart';
-
-/// Accessor for reading AST lazily, or read data that is stored in IDL, but
-/// cannot be stored in AST, like inferred types.
-class LazyAst {
-  static const _defaultTypeKey = 'lazyAst_defaultType';
-  static const _genericFunctionTypeIdKey = 'lazyAst_genericFunctionTypeId';
-  static const _hasOverrideInferenceKey = 'lazyAst_hasOverrideInference';
-  static const _inheritsCovariantKey = 'lazyAst_isCovariant';
-  static const _isSimplyBoundedKey = 'lazyAst_simplyBounded';
-  static const _isOperatorEqualParameterTypeFromObjectKey =
-      'lazyAst_isOperatorEqualParameterTypeFromObject';
-  static const _rawFunctionTypeKey = 'lazyAst_rawFunctionType';
-  static const _returnTypeKey = 'lazyAst_returnType';
-  static const _typeInferenceErrorKey = 'lazyAst_typeInferenceError';
-  static const _typeKey = 'lazyAst_type';
-  static const _varianceKey = 'lazyAst_variance';
-
-  final LinkedNode data;
-
-  LazyAst(this.data);
-
-  static DartType getDefaultType(TypeParameter node) {
-    return node.getProperty(_defaultTypeKey);
-  }
-
-  static int getGenericFunctionTypeId(GenericFunctionType node) {
-    return node.getProperty(_genericFunctionTypeIdKey);
-  }
-
-  static bool getInheritsCovariant(AstNode node) {
-    return node.getProperty(_inheritsCovariantKey) ?? false;
-  }
-
-  static DartType getRawFunctionType(AstNode node) {
-    return node.getProperty(_rawFunctionTypeKey);
-  }
-
-  static DartType getReturnType(AstNode node) {
-    return node.getProperty(_returnTypeKey);
-  }
-
-  static DartType getType(AstNode node) {
-    return node.getProperty(_typeKey);
-  }
-
-  static TopLevelInferenceError getTypeInferenceError(AstNode node) {
-    return node.getProperty(_typeInferenceErrorKey);
-  }
-
-  static Variance getVariance(TypeParameter node) {
-    return node.getProperty(_varianceKey);
-  }
-
-  static bool hasOperatorEqualParameterTypeFromObject(AstNode node) {
-    return node.getProperty(_isOperatorEqualParameterTypeFromObjectKey) ??
-        false;
-  }
-
-  static bool hasOverrideInferenceDone(AstNode node) {
-    return node.getProperty(_hasOverrideInferenceKey) ?? false;
-  }
-
-  static bool isSimplyBounded(AstNode node) {
-    return node.getProperty(_isSimplyBoundedKey);
-  }
-
-  static void setDefaultType(TypeParameter node, DartType type) {
-    node.setProperty(_defaultTypeKey, type);
-  }
-
-  static void setGenericFunctionTypeId(GenericFunctionType node, int id) {
-    node.setProperty(_genericFunctionTypeIdKey, id);
-  }
-
-  static void setInheritsCovariant(AstNode node, bool value) {
-    node.setProperty(_inheritsCovariantKey, value);
-  }
-
-  static void setOperatorEqualParameterTypeFromObject(AstNode node, bool b) {
-    node.setProperty(_isOperatorEqualParameterTypeFromObjectKey, b);
-  }
-
-  static void setOverrideInferenceDone(AstNode node) {
-    node.setProperty(_hasOverrideInferenceKey, true);
-  }
-
-  static void setRawFunctionType(AstNode node, DartType type) {
-    node.setProperty(_rawFunctionTypeKey, type);
-  }
-
-  static void setReturnType(AstNode node, DartType type) {
-    node.setProperty(_returnTypeKey, type);
-  }
-
-  static void setSimplyBounded(AstNode node, bool simplyBounded) {
-    node.setProperty(_isSimplyBoundedKey, simplyBounded);
-  }
-
-  static void setType(AstNode node, DartType type) {
-    node.setProperty(_typeKey, type);
-  }
-
-  static void setTypeInferenceError(
-      AstNode node, TopLevelInferenceError error) {
-    node.setProperty(_typeInferenceErrorKey, error);
-  }
-
-  static void setVariance(TypeParameter node, Variance variance) {
-    return node.setProperty(_varianceKey, variance);
-  }
-}
-
-class LazyClassDeclaration {
-  static const _key = 'lazyAst';
-
-  final LinkedNode data;
-
-  bool _hasDocumentationComment = false;
-  bool _hasExtendsClause = false;
-  bool _hasImplementsClause = false;
-  bool _hasMembers = false;
-  bool _hasMetadata = false;
-  bool _hasWithClause = false;
-
-  LazyClassDeclaration(this.data);
-
-  static LazyClassDeclaration get(ClassDeclaration node) {
-    return node.getProperty(_key);
-  }
-
-  static int getCodeLength(
-    LinkedUnitContext context,
-    ClassDeclaration node,
-  ) {
-    var lazy = get(node);
-    if (lazy != null) {
-      return context.getInformativeData(lazy.data)?.codeLength ?? 0;
-    }
-    return node.length;
-  }
-
-  static int getCodeOffset(
-    LinkedUnitContext context,
-    ClassDeclaration node,
-  ) {
-    var lazy = get(node);
-    if (lazy != null) {
-      return context.getInformativeData(lazy.data)?.codeOffset ?? 0;
-    }
-    return node.offset;
-  }
-
-  static void readDocumentationComment(
-    LinkedUnitContext context,
-    ClassDeclaration node,
-  ) {
-    var lazy = get(node);
-    if (lazy != null && !lazy._hasDocumentationComment) {
-      node.documentationComment = context.createComment(lazy.data);
-      lazy._hasDocumentationComment = true;
-    }
-  }
-
-  static void readExtendsClause(
-    AstBinaryReader reader,
-    ClassDeclaration node,
-  ) {
-    var lazy = get(node);
-    if (lazy != null && !lazy._hasExtendsClause) {
-      node.extendsClause = reader.readNode(
-        lazy.data.classDeclaration_extendsClause,
-      );
-      lazy._hasExtendsClause = true;
-    }
-  }
-
-  static void readImplementsClause(
-    AstBinaryReader reader,
-    ClassDeclaration node,
-  ) {
-    var lazy = get(node);
-    if (lazy != null && !lazy._hasImplementsClause) {
-      node.implementsClause = reader.readNode(
-        lazy.data.classOrMixinDeclaration_implementsClause,
-      );
-      lazy._hasImplementsClause = true;
-    }
-  }
-
-  static void readMembers(
-    AstBinaryReader reader,
-    ClassDeclaration node,
-  ) {
-    var lazy = get(node);
-    if (lazy != null && !lazy._hasMembers) {
-      var dataList = lazy.data.classOrMixinDeclaration_members;
-      for (var i = 0; i < dataList.length; ++i) {
-        var data = dataList[i];
-        node.members[i] = reader.readNode(data);
-      }
-      lazy._hasMembers = true;
-    }
-  }
-
-  static void readMetadata(
-    AstBinaryReader reader,
-    ClassDeclaration node,
-  ) {
-    var lazy = get(node);
-    if (lazy != null && !lazy._hasMetadata) {
-      var dataList = lazy.data.annotatedNode_metadata;
-      for (var i = 0; i < dataList.length; ++i) {
-        var data = dataList[i];
-        node.metadata[i] = reader.readNode(data);
-      }
-      lazy._hasMetadata = true;
-    }
-  }
-
-  static void readWithClause(
-    AstBinaryReader reader,
-    ClassDeclaration node,
-  ) {
-    var lazy = get(node);
-    if (lazy != null && !lazy._hasWithClause) {
-      node.withClause = reader.readNode(
-        lazy.data.classDeclaration_withClause,
-      );
-      lazy._hasWithClause = true;
-    }
-  }
-
-  static void setData(ClassDeclaration node, LinkedNode data) {
-    node.setProperty(_key, LazyClassDeclaration(data));
-    LazyAst.setSimplyBounded(node, data.simplyBoundable_isSimplyBounded);
-  }
-}
-
-class LazyClassTypeAlias {
-  static const _key = 'lazyAst';
-
-  final LinkedNode data;
-
-  bool _hasDocumentationComment = false;
-  bool _hasImplementsClause = false;
-  bool _hasMetadata = false;
-  bool _hasSuperclass = false;
-  bool _hasWithClause = false;
-
-  LazyClassTypeAlias(this.data);
-
-  static LazyClassTypeAlias get(ClassTypeAlias node) {
-    return node.getProperty(_key);
-  }
-
-  static int getCodeLength(
-    LinkedUnitContext context,
-    ClassTypeAlias node,
-  ) {
-    var lazy = get(node);
-    if (lazy != null) {
-      return context.getInformativeData(lazy.data)?.codeLength ?? 0;
-    }
-    return node.length;
-  }
-
-  static int getCodeOffset(
-    LinkedUnitContext context,
-    ClassTypeAlias node,
-  ) {
-    var lazy = get(node);
-    if (lazy != null) {
-      return context.getInformativeData(lazy.data)?.codeOffset ?? 0;
-    }
-    return node.offset;
-  }
-
-  static void readDocumentationComment(
-    LinkedUnitContext context,
-    ClassTypeAlias node,
-  ) {
-    var lazy = get(node);
-    if (lazy != null && !lazy._hasDocumentationComment) {
-      node.documentationComment = context.createComment(lazy.data);
-      lazy._hasDocumentationComment = true;
-    }
-  }
-
-  static void readImplementsClause(
-    AstBinaryReader reader,
-    ClassTypeAlias node,
-  ) {
-    var lazy = get(node);
-    if (lazy != null && !lazy._hasImplementsClause) {
-      node.implementsClause = reader.readNode(
-        lazy.data.classTypeAlias_implementsClause,
-      );
-      lazy._hasImplementsClause = true;
-    }
-  }
-
-  static void readMetadata(
-    AstBinaryReader reader,
-    ClassTypeAlias node,
-  ) {
-    var lazy = get(node);
-    if (lazy != null && !lazy._hasMetadata) {
-      var dataList = lazy.data.annotatedNode_metadata;
-      for (var i = 0; i < dataList.length; ++i) {
-        var data = dataList[i];
-        node.metadata[i] = reader.readNode(data);
-      }
-      lazy._hasMetadata = true;
-    }
-  }
-
-  static void readSuperclass(
-    AstBinaryReader reader,
-    ClassTypeAlias node,
-  ) {
-    var lazy = get(node);
-    if (lazy != null && !lazy._hasSuperclass) {
-      node.superclass = reader.readNode(
-        lazy.data.classTypeAlias_superclass,
-      );
-      lazy._hasSuperclass = true;
-    }
-  }
-
-  static void readWithClause(
-    AstBinaryReader reader,
-    ClassTypeAlias node,
-  ) {
-    var lazy = get(node);
-    if (lazy != null && !lazy._hasWithClause) {
-      node.withClause = reader.readNode(
-        lazy.data.classTypeAlias_withClause,
-      );
-      lazy._hasWithClause = true;
-    }
-  }
-
-  static void setData(ClassTypeAlias node, LinkedNode data) {
-    node.setProperty(_key, LazyClassTypeAlias(data));
-    LazyAst.setSimplyBounded(node, data.simplyBoundable_isSimplyBounded);
-  }
-}
-
-class LazyCombinator {
-  static const _key = 'lazyAst';
-
-  final LinkedNode data;
-
-  LazyCombinator(Combinator node, this.data) {
-    node.setProperty(_key, this);
-  }
-
-  static LazyCombinator get(Combinator node) {
-    return node.getProperty(_key);
-  }
-
-  static int getEnd(
-    LinkedUnitContext context,
-    Combinator node,
-  ) {
-    var lazy = get(node);
-    if (lazy != null) {
-      var informativeData = context.getInformativeData(lazy.data);
-      return informativeData?.combinatorEnd ?? 0;
-    }
-    return node.end;
-  }
-}
-
-class LazyCompilationUnit {
-  static const _key = 'lazyAst';
-
-  final LinkedNode data;
-
-  LazyCompilationUnit(CompilationUnit node, this.data) {
-    node.setProperty(_key, this);
-  }
-
-  static LazyCompilationUnit get(CompilationUnit node) {
-    return node.getProperty(_key);
-  }
-
-  static LibraryLanguageVersion getLanguageVersion(CompilationUnit node) {
-    var lazy = get(node);
-    if (lazy != null) {
-      var package = lazy.data.compilationUnit_languageVersion.package;
-      var override = lazy.data.compilationUnit_languageVersion.override2;
-      return LibraryLanguageVersion(
-        package: Version(package.major, package.minor, 0),
-        override: override != null
-            ? Version(override.major, override.minor, 0)
-            : null,
-      );
-    }
-    return (node as CompilationUnitImpl).languageVersion;
-  }
-}
-
-class LazyConstructorDeclaration {
-  static const _key = 'lazyAst';
-
-  final LinkedNode data;
-
-  bool _hasBody = false;
-  bool _hasDocumentationComment = false;
-  bool _hasFormalParameters = false;
-  bool _hasInitializers = false;
-  bool _hasMetadata = false;
-  bool _hasRedirectedConstructor = false;
-
-  LazyConstructorDeclaration(this.data);
-
-  static LazyConstructorDeclaration get(ConstructorDeclaration node) {
-    return node.getProperty(_key);
-  }
-
-  static int getCodeLength(
-    LinkedUnitContext context,
-    ConstructorDeclaration node,
-  ) {
-    var lazy = get(node);
-    if (lazy != null) {
-      return context.getInformativeData(lazy.data)?.codeLength ?? 0;
-    }
-    return node.length;
-  }
-
-  static int getCodeOffset(
-    LinkedUnitContext context,
-    ConstructorDeclaration node,
-  ) {
-    var lazy = get(node);
-    if (lazy != null) {
-      return context.getInformativeData(lazy.data)?.codeOffset ?? 0;
-    }
-    return node.offset;
-  }
-
-  static void readBody(
-    AstBinaryReader reader,
-    ConstructorDeclaration node,
-  ) {
-    var lazy = get(node);
-    if (lazy != null && !lazy._hasBody) {
-      node.body = reader.readNode(
-        lazy.data.constructorDeclaration_body,
-      );
-      lazy._hasBody = true;
-    }
-  }
-
-  static void readDocumentationComment(
-    LinkedUnitContext context,
-    ConstructorDeclaration node,
-  ) {
-    var lazy = get(node);
-    if (lazy != null && !lazy._hasDocumentationComment) {
-      node.documentationComment = context.createComment(lazy.data);
-      lazy._hasDocumentationComment = true;
-    }
-  }
-
-  static void readFormalParameters(
-    AstBinaryReader reader,
-    ConstructorDeclaration node,
-  ) {
-    var lazy = get(node);
-    if (lazy != null && !lazy._hasFormalParameters) {
-      node.parameters = reader.readNode(
-        lazy.data.constructorDeclaration_parameters,
-      );
-      lazy._hasFormalParameters = true;
-    }
-  }
-
-  static void readInitializers(
-    AstBinaryReader reader,
-    ConstructorDeclaration node,
-  ) {
-    var lazy = get(node);
-    if (lazy != null && !lazy._hasInitializers) {
-      var dataList = lazy.data.constructorDeclaration_initializers;
-      for (var i = 0; i < dataList.length; ++i) {
-        var data = dataList[i];
-        node.initializers[i] = reader.readNode(data);
-      }
-      lazy._hasInitializers = true;
-    }
-  }
-
-  static void readMetadata(
-    AstBinaryReader reader,
-    ConstructorDeclaration node,
-  ) {
-    var lazy = get(node);
-    if (lazy != null && !lazy._hasMetadata) {
-      var dataList = lazy.data.annotatedNode_metadata;
-      for (var i = 0; i < dataList.length; ++i) {
-        var data = dataList[i];
-        node.metadata[i] = reader.readNode(data);
-      }
-      lazy._hasMetadata = true;
-    }
-  }
-
-  static void readRedirectedConstructor(
-    AstBinaryReader reader,
-    ConstructorDeclaration node,
-  ) {
-    var lazy = get(node);
-    if (lazy != null && !lazy._hasRedirectedConstructor) {
-      node.redirectedConstructor = reader.readNode(
-        lazy.data.constructorDeclaration_redirectedConstructor,
-      );
-      lazy._hasRedirectedConstructor = true;
-    }
-  }
-
-  static void setData(ConstructorDeclaration node, LinkedNode data) {
-    node.setProperty(_key, LazyConstructorDeclaration(data));
-  }
-}
-
-class LazyDirective {
-  static const _key = 'lazyAst';
-  static const _uriKey = 'lazyAst_selectedUri';
-
-  final LinkedNode data;
-
-  bool _hasMetadata = false;
-
-  LazyDirective(this.data);
-
-  static LazyDirective get(Directive node) {
-    return node.getProperty(_key);
-  }
-
-  static String getSelectedUri(UriBasedDirective node) {
-    return node.getProperty(_uriKey);
-  }
-
-  static void readMetadata(AstBinaryReader reader, Directive node) {
-    var lazy = get(node);
-    if (lazy != null && !lazy._hasMetadata) {
-      var dataList = lazy.data.annotatedNode_metadata;
-      for (var i = 0; i < dataList.length; ++i) {
-        var data = dataList[i];
-        node.metadata[i] = reader.readNode(data);
-      }
-      lazy._hasMetadata = true;
-    }
-  }
-
-  static void setData(Directive node, LinkedNode data) {
-    node.setProperty(_key, LazyDirective(data));
-    if (node is NamespaceDirective) {
-      node.setProperty(_uriKey, data.namespaceDirective_selectedUri);
-    }
-  }
-
-  static void setSelectedUri(UriBasedDirective node, String uriStr) {
-    node.setProperty(_uriKey, uriStr);
-  }
-}
-
-class LazyEnumConstantDeclaration {
-  static const _key = 'lazyAst';
-
-  final LinkedNode data;
-
-  bool _hasDocumentationComment = false;
-  bool _hasMetadata = false;
-
-  LazyEnumConstantDeclaration(this.data);
-
-  static LazyEnumConstantDeclaration get(EnumConstantDeclaration node) {
-    return node.getProperty(_key);
-  }
-
-  static int getCodeLength(
-    LinkedUnitContext context,
-    EnumConstantDeclaration node,
-  ) {
-    var lazy = get(node);
-    if (lazy != null) {
-      return context.getInformativeData(lazy.data)?.codeLength ?? 0;
-    }
-    return node.length;
-  }
-
-  static int getCodeOffset(
-    LinkedUnitContext context,
-    EnumConstantDeclaration node,
-  ) {
-    var lazy = get(node);
-    if (lazy != null) {
-      return context.getInformativeData(lazy.data)?.codeOffset ?? 0;
-    }
-    return node.offset;
-  }
-
-  static void readDocumentationComment(
-    LinkedUnitContext context,
-    EnumConstantDeclaration node,
-  ) {
-    var lazy = get(node);
-    if (lazy != null && !lazy._hasDocumentationComment) {
-      node.documentationComment = context.createComment(lazy.data);
-      lazy._hasDocumentationComment = true;
-    }
-  }
-
-  static void readMetadata(
-    AstBinaryReader reader,
-    EnumConstantDeclaration node,
-  ) {
-    var lazy = get(node);
-    if (lazy != null && !lazy._hasMetadata) {
-      var dataList = lazy.data.annotatedNode_metadata;
-      for (var i = 0; i < dataList.length; ++i) {
-        var data = dataList[i];
-        node.metadata[i] = reader.readNode(data);
-      }
-      lazy._hasMetadata = true;
-    }
-  }
-
-  static void setData(EnumConstantDeclaration node, LinkedNode data) {
-    node.setProperty(_key, LazyEnumConstantDeclaration(data));
-  }
-}
-
-class LazyEnumDeclaration {
-  static const _key = 'lazyAst';
-
-  final LinkedNode data;
-
-  bool _hasConstants = false;
-  bool _hasDocumentationComment = false;
-  bool _hasMetadata = false;
-
-  LazyEnumDeclaration(this.data);
-
-  static LazyEnumDeclaration get(EnumDeclaration node) {
-    return node.getProperty(_key);
-  }
-
-  static int getCodeLength(
-    LinkedUnitContext context,
-    EnumDeclaration node,
-  ) {
-    var lazy = get(node);
-    if (lazy != null) {
-      return context.getInformativeData(lazy.data)?.codeLength ?? 0;
-    }
-    return node.length;
-  }
-
-  static int getCodeOffset(
-    LinkedUnitContext context,
-    EnumDeclaration node,
-  ) {
-    var lazy = get(node);
-    if (lazy != null) {
-      return context.getInformativeData(lazy.data)?.codeOffset ?? 0;
-    }
-    return node.offset;
-  }
-
-  static void readConstants(
-    AstBinaryReader reader,
-    EnumDeclaration node,
-  ) {
-    var lazy = get(node);
-    if (lazy != null && !lazy._hasConstants) {
-      var dataList = lazy.data.enumDeclaration_constants;
-      for (var i = 0; i < dataList.length; ++i) {
-        var data = dataList[i];
-        node.constants[i] = reader.readNode(data);
-      }
-      lazy._hasConstants = true;
-    }
-  }
-
-  static void readDocumentationComment(
-    LinkedUnitContext context,
-    EnumDeclaration node,
-  ) {
-    var lazy = get(node);
-    if (lazy != null && !lazy._hasDocumentationComment) {
-      node.documentationComment = context.createComment(lazy.data);
-      lazy._hasDocumentationComment = true;
-    }
-  }
-
-  static void readMetadata(
-    AstBinaryReader reader,
-    EnumDeclaration node,
-  ) {
-    var lazy = get(node);
-    if (lazy != null && !lazy._hasMetadata) {
-      var dataList = lazy.data.annotatedNode_metadata;
-      for (var i = 0; i < dataList.length; ++i) {
-        var data = dataList[i];
-        node.metadata[i] = reader.readNode(data);
-      }
-      lazy._hasMetadata = true;
-    }
-  }
-
-  static void setData(EnumDeclaration node, LinkedNode data) {
-    node.setProperty(_key, LazyEnumDeclaration(data));
-  }
-}
-
-class LazyExtensionDeclaration {
-  static const _key = 'lazyAst';
-
-  final LinkedNode data;
-
-  bool _hasDocumentationComment = false;
-  bool _hasExtendedType = false;
-  bool _hasMembers = false;
-  bool _hasMetadata = false;
-
-  /// The name for use in `Reference`. If the extension is named, the name
-  /// of the extension. If the extension is unnamed, a synthetic name.
-  String _refName;
-
-  LazyExtensionDeclaration(ExtensionDeclaration node, this.data) {
-    node.setProperty(_key, this);
-    if (data != null) {
-      _refName = data.extensionDeclaration_refName;
-    }
-  }
-
-  String get refName => _refName;
-
-  void put(LinkedNodeBuilder builder) {
-    assert(_refName != null);
-    builder.extensionDeclaration_refName = _refName;
-  }
-
-  void setRefName(String referenceName) {
-    _refName = referenceName;
-  }
-
-  static LazyExtensionDeclaration get(ExtensionDeclaration node) {
-    LazyExtensionDeclaration lazy = node.getProperty(_key);
-    if (lazy == null) {
-      return LazyExtensionDeclaration(node, null);
-    }
-    return lazy;
-  }
-
-  static int getCodeLength(
-    LinkedUnitContext context,
-    ExtensionDeclaration node,
-  ) {
-    var lazy = get(node);
-    if (lazy?.data != null) {
-      return context.getInformativeData(lazy.data)?.codeLength ?? 0;
-    }
-    return node.length;
-  }
-
-  static int getCodeOffset(
-    LinkedUnitContext context,
-    ExtensionDeclaration node,
-  ) {
-    var lazy = get(node);
-    if (lazy?.data != null) {
-      return context.getInformativeData(lazy.data)?.codeOffset ?? 0;
-    }
-    return node.offset;
-  }
-
-  static void readDocumentationComment(
-    LinkedUnitContext context,
-    ExtensionDeclaration node,
-  ) {
-    var lazy = get(node);
-    if (lazy?.data != null && !lazy._hasDocumentationComment) {
-      node.documentationComment = context.createComment(lazy.data);
-      lazy._hasDocumentationComment = true;
-    }
-  }
-
-  static void readExtendedType(
-    AstBinaryReader reader,
-    ExtensionDeclaration node,
-  ) {
-    var lazy = get(node);
-    if (lazy?.data != null && !lazy._hasExtendedType) {
-      (node as ExtensionDeclarationImpl).extendedType = reader.readNode(
-        lazy.data.extensionDeclaration_extendedType,
-      );
-      lazy._hasExtendedType = true;
-    }
-  }
-
-  static void readMembers(
-    AstBinaryReader reader,
-    ExtensionDeclaration node,
-  ) {
-    var lazy = get(node);
-    if (lazy?.data != null && !lazy._hasMembers) {
-      var dataList = lazy.data.extensionDeclaration_members;
-      for (var i = 0; i < dataList.length; ++i) {
-        var data = dataList[i];
-        node.members[i] = reader.readNode(data);
-      }
-      lazy._hasMembers = true;
-    }
-  }
-
-  static void readMetadata(
-    AstBinaryReader reader,
-    ExtensionDeclaration node,
-  ) {
-    var lazy = get(node);
-    if (lazy?.data != null && !lazy._hasMetadata) {
-      var dataList = lazy.data.annotatedNode_metadata;
-      for (var i = 0; i < dataList.length; ++i) {
-        var data = dataList[i];
-        node.metadata[i] = reader.readNode(data);
-      }
-      lazy._hasMetadata = true;
-    }
-  }
-}
-
-class LazyFieldDeclaration {
-  static const _key = 'lazyAst';
-
-  final LinkedNode data;
-
-  bool _hasDocumentationComment = false;
-  bool _hasMetadata = false;
-
-  LazyFieldDeclaration(this.data);
-
-  static LazyFieldDeclaration get(FieldDeclaration node) {
-    return node.getProperty(_key);
-  }
-
-  static void readDocumentationComment(
-    LinkedUnitContext context,
-    FieldDeclaration node,
-  ) {
-    var lazy = get(node);
-    if (lazy != null && !lazy._hasDocumentationComment) {
-      node.documentationComment = context.createComment(lazy.data);
-      lazy._hasDocumentationComment = true;
-    }
-  }
-
-  static void readMetadata(
-    AstBinaryReader reader,
-    FieldDeclaration node,
-  ) {
-    var lazy = get(node);
-    if (lazy != null && !lazy._hasMetadata) {
-      var dataList = lazy.data.annotatedNode_metadata;
-      for (var i = 0; i < dataList.length; ++i) {
-        var data = dataList[i];
-        node.metadata[i] = reader.readNode(data);
-      }
-      lazy._hasMetadata = true;
-    }
-  }
-
-  static void setData(FieldDeclaration node, LinkedNode data) {
-    node.setProperty(_key, LazyFieldDeclaration(data));
-  }
-}
-
-class LazyFormalParameter {
-  static const _key = 'lazyAst';
-
-  final LinkedNode data;
-
-  bool _hasDefaultValue = false;
-  bool _hasFormalParameters = false;
-  bool _hasMetadata = false;
-  bool _hasType = false;
-  bool _hasTypeInferenceError = false;
-  bool _hasTypeNode = false;
-
-  LazyFormalParameter(this.data);
-
-  static LazyFormalParameter get(FormalParameter node) {
-    return node.getProperty(_key);
-  }
-
-  static int getCodeLength(
-    LinkedUnitContext context,
-    FormalParameter node,
-  ) {
-    var lazy = get(node);
-    if (lazy != null) {
-      return context.getInformativeData(lazy.data)?.codeLength ?? 0;
-    }
-    return node.length;
-  }
-
-  static int getCodeOffset(
-    LinkedUnitContext context,
-    FormalParameter node,
-  ) {
-    var lazy = get(node);
-    if (lazy != null) {
-      return context.getInformativeData(lazy.data)?.codeOffset ?? 0;
-    }
-    return node.offset;
-  }
-
-  static String getDefaultValueCode(
-    LinkedUnitContext context,
-    DefaultFormalParameter node,
-  ) {
-    var lazy = get(node);
-    if (lazy != null) {
-      if (lazy.data.defaultFormalParameter_defaultValue == null) {
-        return null;
-      }
-      return context.getDefaultValueCodeData(lazy.data);
-    } else {
-      return node.defaultValue?.toSource();
-    }
-  }
-
-  static DartType getType(
-    AstBinaryReader reader,
-    FormalParameter node,
-  ) {
-    var lazy = get(node);
-    if (lazy != null && !lazy._hasType) {
-      var type = reader.readType(lazy.data.actualType);
-      LazyAst.setType(node, type);
-      lazy._hasType = true;
-    }
-    return LazyAst.getType(node);
-  }
-
-  static TopLevelInferenceError getTypeInferenceError(FormalParameter node) {
-    var lazy = get(node);
-    if (lazy != null && !lazy._hasTypeInferenceError) {
-      var error = lazy.data.topLevelTypeInferenceError;
-      LazyAst.setTypeInferenceError(node, error);
-      lazy._hasTypeInferenceError = true;
-    }
-    return LazyAst.getTypeInferenceError(node);
-  }
-
-  static bool hasDefaultValue(DefaultFormalParameter node) {
-    var lazy = get(node);
-    if (lazy != null) {
-      return AstBinaryFlags.hasInitializer(lazy.data.flags);
-    } else {
-      return node.defaultValue != null;
-    }
-  }
-
-  static void readDefaultValue(
-    AstBinaryReader reader,
-    DefaultFormalParameter node,
-  ) {
-    var lazy = get(node);
-    if (lazy != null && !lazy._hasDefaultValue) {
-      node.defaultValue = reader.readNode(
-        lazy.data.defaultFormalParameter_defaultValue,
-      );
-      lazy._hasDefaultValue = true;
-    }
-  }
-
-  static void readFormalParameters(
-    AstBinaryReader reader,
-    FormalParameter node,
-  ) {
-    var lazy = get(node);
-    if (lazy != null && !lazy._hasFormalParameters) {
-      if (node is FunctionTypedFormalParameter) {
-        node.parameters = reader.readNode(
-          lazy.data.functionTypedFormalParameter_formalParameters,
-        );
-      } else if (node is FieldFormalParameter) {
-        node.parameters = reader.readNode(
-          lazy.data.fieldFormalParameter_formalParameters,
-        );
-      }
-      lazy._hasFormalParameters = true;
-    }
-  }
-
-  static void readMetadata(
-    AstBinaryReader reader,
-    FormalParameter node,
-  ) {
-    var lazy = get(node);
-    if (lazy != null && !lazy._hasMetadata) {
-      var dataList = lazy.data.normalFormalParameter_metadata;
-      for (var i = 0; i < dataList.length; ++i) {
-        var data = dataList[i];
-        node.metadata[i] = reader.readNode(data);
-      }
-      lazy._hasMetadata = true;
-    }
-  }
-
-  static void readTypeNode(
-    AstBinaryReader reader,
-    FormalParameter node,
-  ) {
-    var lazy = get(node);
-    if (lazy != null && !lazy._hasTypeNode) {
-      if (node is SimpleFormalParameter) {
-        node.type = reader.readNode(
-          lazy.data.simpleFormalParameter_type,
-        );
-      }
-      lazy._hasTypeNode = true;
-    }
-  }
-
-  static void setData(FormalParameter node, LinkedNode data) {
-    node.setProperty(_key, LazyFormalParameter(data));
-  }
-}
-
-class LazyFunctionDeclaration {
-  static const _key = 'lazyAst';
-
-  final LinkedNode data;
-
-  bool _hasDocumentationComment = false;
-  bool _hasMetadata = false;
-  bool _hasReturnType = false;
-  bool _hasReturnTypeNode = false;
-
-  LazyFunctionDeclaration(this.data);
-
-  static LazyFunctionDeclaration get(FunctionDeclaration node) {
-    return node.getProperty(_key);
-  }
-
-  static int getCodeLength(
-    LinkedUnitContext context,
-    FunctionDeclaration node,
-  ) {
-    var lazy = get(node);
-    if (lazy != null) {
-      return context.getInformativeData(lazy.data)?.codeLength ?? 0;
-    }
-    return node.length;
-  }
-
-  static int getCodeOffset(
-    LinkedUnitContext context,
-    FunctionDeclaration node,
-  ) {
-    var lazy = get(node);
-    if (lazy != null) {
-      return context.getInformativeData(lazy.data)?.codeOffset ?? 0;
-    }
-    return node.offset;
-  }
-
-  static DartType getReturnType(
-    AstBinaryReader reader,
-    FunctionDeclaration node,
-  ) {
-    readFunctionExpression(reader, node);
-
-    var lazy = get(node);
-    if (lazy != null && !lazy._hasReturnType) {
-      var type = reader.readType(lazy.data.actualReturnType);
-      LazyAst.setReturnType(node, type);
-      lazy._hasReturnType = true;
-    }
-
-    return LazyAst.getReturnType(node);
-  }
-
-  static void readDocumentationComment(
-    LinkedUnitContext context,
-    FunctionDeclaration node,
-  ) {
-    var lazy = get(node);
-    if (lazy != null && !lazy._hasDocumentationComment) {
-      node.documentationComment = context.createComment(lazy.data);
-      lazy._hasDocumentationComment = true;
-    }
-  }
-
-  static void readFunctionExpression(
-    AstBinaryReader reader,
-    FunctionDeclaration node,
-  ) {
-    if (node.functionExpression == null) {
-      var lazy = get(node);
-      node.functionExpression = reader.readNode(
-        lazy.data.functionDeclaration_functionExpression,
-      );
-    }
-  }
-
-  static void readMetadata(
-    AstBinaryReader reader,
-    FunctionDeclaration node,
-  ) {
-    var lazy = get(node);
-    if (lazy != null && !lazy._hasMetadata) {
-      var dataList = lazy.data.annotatedNode_metadata;
-      for (var i = 0; i < dataList.length; ++i) {
-        var data = dataList[i];
-        node.metadata[i] = reader.readNode(data);
-      }
-      lazy._hasMetadata = true;
-    }
-  }
-
-  static void readReturnTypeNode(
-    AstBinaryReader reader,
-    FunctionDeclaration node,
-  ) {
-    var lazy = get(node);
-    if (lazy != null && !lazy._hasReturnTypeNode) {
-      node.returnType = reader.readNode(
-        lazy.data.functionDeclaration_returnType,
-      );
-      lazy._hasReturnTypeNode = true;
-    }
-  }
-
-  static void setData(FunctionDeclaration node, LinkedNode data) {
-    node.setProperty(_key, LazyFunctionDeclaration(data));
-  }
-}
-
-class LazyFunctionExpression {
-  static const _key = 'lazyAst';
-
-  final LinkedNode data;
-
-  bool _hasBody = false;
-  bool _hasFormalParameters = false;
-
-  LazyFunctionExpression(this.data);
-
-  static LazyFunctionExpression get(FunctionExpression node) {
-    return node.getProperty(_key);
-  }
-
-  static bool isAsynchronous(FunctionExpression node) {
-    var lazy = get(node);
-    if (lazy != null) {
-      return AstBinaryFlags.isAsync(lazy.data.flags);
-    } else {
-      return node.body.isAsynchronous;
-    }
-  }
-
-  static bool isGenerator(FunctionExpression node) {
-    var lazy = get(node);
-    if (lazy != null) {
-      return AstBinaryFlags.isGenerator(lazy.data.flags);
-    } else {
-      return node.body.isGenerator;
-    }
-  }
-
-  static void readBody(
-    AstBinaryReader reader,
-    FunctionExpression node,
-  ) {
-    var lazy = get(node);
-    if (lazy != null && !lazy._hasBody) {
-      node.body = reader.readNode(
-        lazy.data.functionExpression_body,
-      );
-      lazy._hasBody = true;
-    }
-  }
-
-  static void readFormalParameters(
-    AstBinaryReader reader,
-    FunctionExpression node,
-  ) {
-    var lazy = get(node);
-    if (lazy != null && !lazy._hasFormalParameters) {
-      node.parameters = reader.readNode(
-        lazy.data.functionExpression_formalParameters,
-      );
-      lazy._hasFormalParameters = true;
-    }
-  }
-
-  static void setData(FunctionExpression node, LinkedNode data) {
-    node.setProperty(_key, LazyFunctionExpression(data));
-  }
-}
-
-class LazyFunctionTypeAlias {
-  static const _key = 'lazyAst';
-  static const _hasSelfReferenceKey = 'lazyAst_hasSelfReferenceKey';
-
-  final LinkedNode data;
-
-  bool _hasDocumentationComment = false;
-  bool _hasFormalParameters = false;
-  bool _hasMetadata = false;
-  bool _hasReturnType = false;
-  bool _hasReturnTypeNode = false;
-
-  LazyFunctionTypeAlias(this.data);
-
-  static LazyFunctionTypeAlias get(FunctionTypeAlias node) {
-    return node.getProperty(_key);
-  }
-
-  static int getCodeLength(
-    LinkedUnitContext context,
-    FunctionTypeAlias node,
-  ) {
-    var lazy = get(node);
-    if (lazy != null) {
-      return context.getInformativeData(lazy.data)?.codeLength ?? 0;
-    }
-    return node.length;
-  }
-
-  static int getCodeOffset(
-    LinkedUnitContext context,
-    FunctionTypeAlias node,
-  ) {
-    var lazy = get(node);
-    if (lazy != null) {
-      return context.getInformativeData(lazy.data)?.codeOffset ?? 0;
-    }
-    return node.offset;
-  }
-
-  static bool getHasSelfReference(FunctionTypeAlias node) {
-    return node.getProperty(_hasSelfReferenceKey);
-  }
-
-  static DartType getReturnType(
-    AstBinaryReader reader,
-    FunctionTypeAlias node,
-  ) {
-    var lazy = get(node);
-    if (lazy != null && !lazy._hasReturnType) {
-      var type = reader.readType(lazy.data.actualReturnType);
-      LazyAst.setReturnType(node, type);
-      lazy._hasReturnType = true;
-    }
-    return LazyAst.getReturnType(node);
-  }
-
-  static void readDocumentationComment(
-    LinkedUnitContext context,
-    FunctionTypeAlias node,
-  ) {
-    var lazy = get(node);
-    if (lazy != null && !lazy._hasDocumentationComment) {
-      node.documentationComment = context.createComment(lazy.data);
-      lazy._hasDocumentationComment = true;
-    }
-  }
-
-  static void readFormalParameters(
-    AstBinaryReader reader,
-    FunctionTypeAlias node,
-  ) {
-    var lazy = get(node);
-    if (lazy != null && !lazy._hasFormalParameters) {
-      node.parameters = reader.readNode(
-        lazy.data.functionTypeAlias_formalParameters,
-      );
-      lazy._hasFormalParameters = true;
-    }
-  }
-
-  static void readMetadata(
-    AstBinaryReader reader,
-    FunctionTypeAlias node,
-  ) {
-    var lazy = get(node);
-    if (lazy != null && !lazy._hasMetadata) {
-      var dataList = lazy.data.annotatedNode_metadata;
-      for (var i = 0; i < dataList.length; ++i) {
-        var data = dataList[i];
-        node.metadata[i] = reader.readNode(data);
-      }
-      lazy._hasMetadata = true;
-    }
-  }
-
-  static void readReturnTypeNode(
-    AstBinaryReader reader,
-    FunctionTypeAlias node,
-  ) {
-    var lazy = get(node);
-    if (lazy != null && !lazy._hasReturnTypeNode) {
-      node.returnType = reader.readNode(
-        lazy.data.functionTypeAlias_returnType,
-      );
-      lazy._hasReturnTypeNode = true;
-    }
-  }
-
-  static void setData(FunctionTypeAlias node, LinkedNode data) {
-    node.setProperty(_key, LazyFunctionTypeAlias(data));
-    LazyAst.setSimplyBounded(node, data.simplyBoundable_isSimplyBounded);
-  }
-
-  static void setHasSelfReference(FunctionTypeAlias node, bool value) {
-    node.setProperty(_hasSelfReferenceKey, value);
-  }
-}
-
-class LazyGenericTypeAlias {
-  static const _key = 'lazyAst';
-  static const _hasSelfReferenceKey = 'lazyAst_hasSelfReferenceKey';
-
-  final LinkedNode data;
-
-  bool _hasDocumentationComment = false;
-  bool _hasFunction = false;
-  bool _hasMetadata = false;
-
-  LazyGenericTypeAlias(this.data);
-
-  static LazyGenericTypeAlias get(GenericTypeAlias node) {
-    return node.getProperty(_key);
-  }
-
-  static int getCodeLength(
-    LinkedUnitContext context,
-    GenericTypeAlias node,
-  ) {
-    var lazy = get(node);
-    if (lazy != null) {
-      return context.getInformativeData(lazy.data)?.codeLength ?? 0;
-    }
-    return node.length;
-  }
-
-  static int getCodeOffset(
-    LinkedUnitContext context,
-    GenericTypeAlias node,
-  ) {
-    var lazy = get(node);
-    if (lazy != null) {
-      return context.getInformativeData(lazy.data)?.codeOffset ?? 0;
-    }
-    return node.offset;
-  }
-
-  static bool getHasSelfReference(GenericTypeAlias node) {
-    return node.getProperty(_hasSelfReferenceKey);
-  }
-
-  static void readDocumentationComment(
-    LinkedUnitContext context,
-    GenericTypeAlias node,
-  ) {
-    var lazy = get(node);
-    if (lazy != null && !lazy._hasDocumentationComment) {
-      node.documentationComment = context.createComment(lazy.data);
-      lazy._hasDocumentationComment = true;
-    }
-  }
-
-  static void readFunctionType(
-    AstBinaryReader reader,
-    GenericTypeAlias node,
-  ) {
-    var lazy = get(node);
-    if (lazy != null && !lazy._hasFunction) {
-      node.functionType = reader.readNode(
-        lazy.data.genericTypeAlias_functionType,
-      );
-      lazy._hasFunction = true;
-    }
-  }
-
-  static void readMetadata(
-    AstBinaryReader reader,
-    GenericTypeAlias node,
-  ) {
-    var lazy = get(node);
-    if (lazy != null && !lazy._hasMetadata) {
-      var dataList = lazy.data.annotatedNode_metadata;
-      for (var i = 0; i < dataList.length; ++i) {
-        var data = dataList[i];
-        node.metadata[i] = reader.readNode(data);
-      }
-      lazy._hasMetadata = true;
-    }
-  }
-
-  static void setData(GenericTypeAlias node, LinkedNode data) {
-    node.setProperty(_key, LazyGenericTypeAlias(data));
-    LazyAst.setSimplyBounded(node, data.simplyBoundable_isSimplyBounded);
-  }
-
-  static void setHasSelfReference(GenericTypeAlias node, bool value) {
-    node.setProperty(_hasSelfReferenceKey, value);
-  }
-}
-
-class LazyMethodDeclaration {
-  static const _key = 'lazyAst';
-
-  final LinkedNode data;
-
-  bool _hasBody = false;
-  bool _hasDocumentationComment = false;
-  bool _hasFormalParameters = false;
-  bool _hasMetadata = false;
-  bool _hasReturnType = false;
-  bool _hasReturnTypeNode = false;
-  bool _hasTypeInferenceError = false;
-
-  LazyMethodDeclaration(this.data);
-
-  static LazyMethodDeclaration get(MethodDeclaration node) {
-    return node.getProperty(_key);
-  }
-
-  static int getCodeLength(
-    LinkedUnitContext context,
-    MethodDeclaration node,
-  ) {
-    var lazy = get(node);
-    if (lazy != null) {
-      return context.getInformativeData(lazy.data)?.codeLength ?? 0;
-    }
-    return node.length;
-  }
-
-  static int getCodeOffset(
-    LinkedUnitContext context,
-    MethodDeclaration node,
-  ) {
-    var lazy = get(node);
-    if (lazy != null) {
-      return context.getInformativeData(lazy.data)?.codeOffset ?? 0;
-    }
-    return node.offset;
-  }
-
-  static DartType getReturnType(
-    AstBinaryReader reader,
-    MethodDeclaration node,
-  ) {
-    var lazy = get(node);
-    if (lazy != null && !lazy._hasReturnType) {
-      var type = reader.readType(lazy.data.actualReturnType);
-      LazyAst.setReturnType(node, type);
-      lazy._hasReturnType = true;
-    }
-    return LazyAst.getReturnType(node);
-  }
-
-  static TopLevelInferenceError getTypeInferenceError(MethodDeclaration node) {
-    var lazy = get(node);
-    if (lazy != null && !lazy._hasTypeInferenceError) {
-      var error = lazy.data.topLevelTypeInferenceError;
-      LazyAst.setTypeInferenceError(node, error);
-      lazy._hasTypeInferenceError = true;
-    }
-    return LazyAst.getTypeInferenceError(node);
-  }
-
-  static bool isAbstract(MethodDeclaration node) {
-    var lazy = get(node);
-    if (lazy != null) {
-      return AstBinaryFlags.isAbstract(lazy.data.flags);
-    } else {
-      return node.isAbstract;
-    }
-  }
-
-  static bool isAsynchronous(MethodDeclaration node) {
-    var lazy = get(node);
-    if (lazy != null) {
-      return AstBinaryFlags.isAsync(lazy.data.flags);
-    } else {
-      return node.body.isAsynchronous;
-    }
-  }
-
-  static bool isGenerator(MethodDeclaration node) {
-    var lazy = get(node);
-    if (lazy != null) {
-      return AstBinaryFlags.isGenerator(lazy.data.flags);
-    } else {
-      return node.body.isGenerator;
-    }
-  }
-
-  static void readBody(
-    AstBinaryReader reader,
-    MethodDeclaration node,
-  ) {
-    var lazy = get(node);
-    if (lazy != null && !lazy._hasBody) {
-      node.body = reader.readNode(
-        lazy.data.methodDeclaration_body,
-      );
-      lazy._hasBody = true;
-    }
-  }
-
-  static void readDocumentationComment(
-    LinkedUnitContext context,
-    MethodDeclaration node,
-  ) {
-    var lazy = get(node);
-    if (lazy != null && !lazy._hasDocumentationComment) {
-      node.documentationComment = context.createComment(lazy.data);
-      lazy._hasDocumentationComment = true;
-    }
-  }
-
-  static void readFormalParameters(
-    AstBinaryReader reader,
-    MethodDeclaration node,
-  ) {
-    var lazy = get(node);
-    if (lazy != null && !lazy._hasFormalParameters) {
-      node.parameters = reader.readNode(
-        lazy.data.methodDeclaration_formalParameters,
-      );
-      lazy._hasFormalParameters = true;
-    }
-  }
-
-  static void readMetadata(
-    AstBinaryReader reader,
-    MethodDeclaration node,
-  ) {
-    var lazy = get(node);
-    if (lazy != null && !lazy._hasMetadata) {
-      var dataList = lazy.data.annotatedNode_metadata;
-      for (var i = 0; i < dataList.length; ++i) {
-        var data = dataList[i];
-        node.metadata[i] = reader.readNode(data);
-      }
-      lazy._hasMetadata = true;
-    }
-  }
-
-  static void readReturnTypeNode(
-    AstBinaryReader reader,
-    MethodDeclaration node,
-  ) {
-    var lazy = get(node);
-    if (lazy != null && !lazy._hasReturnTypeNode) {
-      node.returnType = reader.readNode(
-        lazy.data.methodDeclaration_returnType,
-      );
-      lazy._hasReturnTypeNode = true;
-    }
-  }
-
-  static void setData(MethodDeclaration node, LinkedNode data) {
-    node.setProperty(_key, LazyMethodDeclaration(data));
-  }
-}
-
-class LazyMixinDeclaration {
-  static const _key = 'lazyAst';
-
-  final LinkedNode data;
-
-  bool _hasDocumentationComment = false;
-  bool _hasOnClause = false;
-  bool _hasImplementsClause = false;
-  bool _hasMembers = false;
-  bool _hasMetadata = false;
-
-  List<String> _superInvokedNames;
-
-  LazyMixinDeclaration(MixinDeclaration node, this.data) {
-    node.setProperty(_key, this);
-    if (data != null) {
-      LazyAst.setSimplyBounded(node, data.simplyBoundable_isSimplyBounded);
-    }
-  }
-
-  List<String> getSuperInvokedNames() {
-    return _superInvokedNames ??= data.mixinDeclaration_superInvokedNames;
-  }
-
-  void put(LinkedNodeBuilder builder) {
-    builder.mixinDeclaration_superInvokedNames = _superInvokedNames ?? [];
-  }
-
-  void setSuperInvokedNames(List<String> value) {
-    _superInvokedNames = value;
-  }
-
-  static LazyMixinDeclaration get(MixinDeclaration node) {
-    LazyMixinDeclaration lazy = node.getProperty(_key);
-    if (lazy == null) {
-      return LazyMixinDeclaration(node, null);
-    }
-    return lazy;
-  }
-
-  static int getCodeLength(
-    LinkedUnitContext context,
-    MixinDeclaration node,
-  ) {
-    var lazy = get(node);
-    if (lazy != null) {
-      return context.getInformativeData(lazy.data)?.codeLength ?? 0;
-    }
-    return node.length;
-  }
-
-  static int getCodeOffset(
-    LinkedUnitContext context,
-    MixinDeclaration node,
-  ) {
-    var lazy = get(node);
-    if (lazy != null) {
-      return context.getInformativeData(lazy.data)?.codeOffset ?? 0;
-    }
-    return node.offset;
-  }
-
-  static void readDocumentationComment(
-    LinkedUnitContext context,
-    MixinDeclaration node,
-  ) {
-    var lazy = get(node);
-    if (lazy.data != null && !lazy._hasDocumentationComment) {
-      node.documentationComment = context.createComment(lazy.data);
-      lazy._hasDocumentationComment = true;
-    }
-  }
-
-  static void readImplementsClause(
-    AstBinaryReader reader,
-    MixinDeclarationImpl node,
-  ) {
-    var lazy = get(node);
-    if (lazy.data != null && !lazy._hasImplementsClause) {
-      node.implementsClause = reader.readNode(
-        lazy.data.classOrMixinDeclaration_implementsClause,
-      );
-      lazy._hasImplementsClause = true;
-    }
-  }
-
-  static void readMembers(
-    AstBinaryReader reader,
-    MixinDeclaration node,
-  ) {
-    var lazy = get(node);
-    if (lazy.data != null && !lazy._hasMembers) {
-      var dataList = lazy.data.classOrMixinDeclaration_members;
-      for (var i = 0; i < dataList.length; ++i) {
-        var data = dataList[i];
-        node.members[i] = reader.readNode(data);
-      }
-      lazy._hasMembers = true;
-    }
-  }
-
-  static void readMetadata(
-    AstBinaryReader reader,
-    MixinDeclaration node,
-  ) {
-    var lazy = get(node);
-    if (lazy.data != null && !lazy._hasMetadata) {
-      var dataList = lazy.data.annotatedNode_metadata;
-      for (var i = 0; i < dataList.length; ++i) {
-        var data = dataList[i];
-        node.metadata[i] = reader.readNode(data);
-      }
-      lazy._hasMetadata = true;
-    }
-  }
-
-  static void readOnClause(
-    AstBinaryReader reader,
-    MixinDeclarationImpl node,
-  ) {
-    var lazy = get(node);
-    if (lazy.data != null && !lazy._hasOnClause) {
-      node.onClause = reader.readNode(
-        lazy.data.mixinDeclaration_onClause,
-      );
-      lazy._hasOnClause = true;
-    }
-  }
-}
-
-class LazyTopLevelVariableDeclaration {
-  static const _key = 'lazyAst';
-
-  final LinkedNode data;
-
-  bool _hasDocumentationComment = false;
-  bool _hasMetadata = false;
-
-  LazyTopLevelVariableDeclaration(this.data);
-
-  static LazyTopLevelVariableDeclaration get(TopLevelVariableDeclaration node) {
-    return node.getProperty(_key);
-  }
-
-  static void readDocumentationComment(
-    LinkedUnitContext context,
-    TopLevelVariableDeclaration node,
-  ) {
-    var lazy = get(node);
-    if (lazy != null && !lazy._hasDocumentationComment) {
-      node.documentationComment = context.createComment(lazy.data);
-      lazy._hasDocumentationComment = true;
-    }
-  }
-
-  static void readMetadata(
-    AstBinaryReader reader,
-    TopLevelVariableDeclaration node,
-  ) {
-    var lazy = get(node);
-    if (lazy != null && !lazy._hasMetadata) {
-      var dataList = lazy.data.annotatedNode_metadata;
-      for (var i = 0; i < dataList.length; ++i) {
-        var data = dataList[i];
-        node.metadata[i] = reader.readNode(data);
-      }
-      lazy._hasMetadata = true;
-    }
-  }
-
-  static void setData(TopLevelVariableDeclaration node, LinkedNode data) {
-    node.setProperty(_key, LazyTopLevelVariableDeclaration(data));
-  }
-}
-
-class LazyTypeParameter {
-  static const _key = 'lazyAst';
-
-  final LinkedNode data;
-
-  bool _hasBound = false;
-  bool _hasDefaultType = false;
-  bool _hasMetadata = false;
-
-  LazyTypeParameter(this.data);
-
-  static LazyTypeParameter get(TypeParameter node) {
-    return node.getProperty(_key);
-  }
-
-  static int getCodeLength(
-    LinkedUnitContext context,
-    TypeParameter node,
-  ) {
-    var lazy = get(node);
-    if (lazy != null) {
-      return context.getInformativeData(lazy.data)?.codeLength ?? 0;
-    }
-    return node.length;
-  }
-
-  static int getCodeOffset(
-    LinkedUnitContext context,
-    TypeParameter node,
-  ) {
-    var lazy = get(node);
-    if (lazy != null) {
-      return context.getInformativeData(lazy.data)?.codeOffset ?? 0;
-    }
-    return node.offset;
-  }
-
-  static DartType getDefaultType(AstBinaryReader reader, TypeParameter node) {
-    var lazy = get(node);
-    if (lazy != null && !lazy._hasDefaultType) {
-      lazy._hasDefaultType = true;
-      var type = reader.readType(lazy.data.typeParameter_defaultType);
-      LazyAst.setDefaultType(node, type);
-      return type;
-    }
-    return LazyAst.getDefaultType(node);
-  }
-
-  static void readBound(AstBinaryReader reader, TypeParameter node) {
-    var lazy = get(node);
-    if (lazy != null && !lazy._hasBound) {
-      node.bound = reader.readNode(lazy.data.typeParameter_bound);
-      lazy._hasBound = true;
-    }
-  }
-
-  static void readMetadata(
-    AstBinaryReader reader,
-    TypeParameter node,
-  ) {
-    var lazy = get(node);
-    if (lazy != null && !lazy._hasMetadata) {
-      var dataList = lazy.data.annotatedNode_metadata;
-      for (var i = 0; i < dataList.length; ++i) {
-        var data = dataList[i];
-        node.metadata[i] = reader.readNode(data);
-      }
-      lazy._hasMetadata = true;
-    }
-  }
-
-  static void setData(TypeParameter node, LinkedNode data) {
-    node.setProperty(_key, LazyTypeParameter(data));
-  }
-}
-
-class LazyVariableDeclaration {
-  static const _key = 'lazyAst';
-
-  final LinkedNode data;
-
-  bool _hasInitializer = false;
-  bool _hasType = false;
-  bool _hasTypeInferenceError = false;
-
-  LazyVariableDeclaration(this.data);
-
-  static LazyVariableDeclaration get(VariableDeclaration node) {
-    return node.getProperty(_key);
-  }
-
-  static int getCodeLength(
-    LinkedUnitContext context,
-    VariableDeclaration node,
-  ) {
-    var lazy = get(node);
-    if (lazy != null) {
-      return context.getInformativeData(lazy.data)?.codeLength ?? 0;
-    }
-    VariableDeclarationList parent = node.parent;
-    if (parent.variables[0] == node) {
-      return node.end - parent.offset;
-    } else {
-      return node.end - node.offset;
-    }
-  }
-
-  static int getCodeOffset(
-    LinkedUnitContext context,
-    VariableDeclaration node,
-  ) {
-    var lazy = get(node);
-    if (lazy != null) {
-      return context.getInformativeData(lazy.data)?.codeOffset ?? 0;
-    }
-    VariableDeclarationList parent = node.parent;
-    if (parent.variables[0] == node) {
-      return parent.offset;
-    } else {
-      return node.offset;
-    }
-  }
-
-  static DartType getType(
-    AstBinaryReader reader,
-    VariableDeclaration node,
-  ) {
-    var lazy = get(node);
-    if (lazy != null && !lazy._hasType) {
-      var type = reader.readType(lazy.data.actualType);
-      LazyAst.setType(node, type);
-      lazy._hasType = true;
-    }
-    return LazyAst.getType(node);
-  }
-
-  static TopLevelInferenceError getTypeInferenceError(
-      VariableDeclaration node) {
-    var lazy = get(node);
-    if (lazy != null && !lazy._hasTypeInferenceError) {
-      var error = lazy.data.topLevelTypeInferenceError;
-      LazyAst.setTypeInferenceError(node, error);
-      lazy._hasTypeInferenceError = true;
-    }
-    return LazyAst.getTypeInferenceError(node);
-  }
-
-  static bool hasInitializer(VariableDeclaration node) {
-    var lazy = get(node);
-    if (lazy != null) {
-      return AstBinaryFlags.hasInitializer(lazy.data.flags);
-    } else {
-      return node.initializer != null;
-    }
-  }
-
-  static void readInitializer(
-    AstBinaryReader reader,
-    VariableDeclaration node,
-  ) {
-    var lazy = get(node);
-    if (lazy != null && !lazy._hasInitializer) {
-      node.initializer = reader.readNode(
-        lazy.data.variableDeclaration_initializer,
-      );
-      lazy._hasInitializer = true;
-    }
-  }
-
-  static void setData(VariableDeclaration node, LinkedNode data) {
-    node.setProperty(_key, LazyVariableDeclaration(data));
-  }
-}
-
-class LazyVariableDeclarationList {
-  static const _key = 'lazyAst';
-
-  final LinkedNode data;
-
-  bool _hasTypeNode = false;
-
-  LazyVariableDeclarationList(this.data);
-
-  static LazyVariableDeclarationList get(VariableDeclarationList node) {
-    return node.getProperty(_key);
-  }
-
-  static void readTypeNode(
-    AstBinaryReader reader,
-    VariableDeclarationList node,
-  ) {
-    var lazy = get(node);
-    if (lazy != null && !lazy._hasTypeNode) {
-      node.type = reader.readNode(
-        lazy.data.variableDeclarationList_type,
-      );
-      lazy._hasTypeNode = true;
-    }
-  }
-
-  static void setData(VariableDeclarationList node, LinkedNode data) {
-    node.setProperty(_key, LazyVariableDeclarationList(data));
-  }
-}
diff --git a/pkg/analyzer/lib/src/summary2/library_builder.dart b/pkg/analyzer/lib/src/summary2/library_builder.dart
index 14ab9ad3..63b7c10 100644
--- a/pkg/analyzer/lib/src/summary2/library_builder.dart
+++ b/pkg/analyzer/lib/src/summary2/library_builder.dart
@@ -4,19 +4,17 @@
 
 import 'package:analyzer/dart/analysis/features.dart';
 import 'package:analyzer/dart/ast/ast.dart' as ast;
+import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/src/dart/ast/mixin_super_invoked_names.dart';
 import 'package:analyzer/src/dart/element/element.dart';
 import 'package:analyzer/src/dart/element/scope.dart';
 import 'package:analyzer/src/generated/utilities_dart.dart';
-import 'package:analyzer/src/summary/format.dart';
-import 'package:analyzer/src/summary/idl.dart';
 import 'package:analyzer/src/summary2/combinator.dart';
 import 'package:analyzer/src/summary2/constructor_initializer_resolver.dart';
 import 'package:analyzer/src/summary2/default_value_resolver.dart';
 import 'package:analyzer/src/summary2/export.dart';
-import 'package:analyzer/src/summary2/lazy_ast.dart';
 import 'package:analyzer/src/summary2/link.dart';
-import 'package:analyzer/src/summary2/linked_bundle_context.dart';
+import 'package:analyzer/src/summary2/linked_library_context.dart';
 import 'package:analyzer/src/summary2/linked_unit_context.dart';
 import 'package:analyzer/src/summary2/metadata_resolver.dart';
 import 'package:analyzer/src/summary2/reference.dart';
@@ -28,7 +26,7 @@
   final Linker linker;
   final Uri uri;
   final Reference reference;
-  final LinkedNodeLibraryBuilder node;
+  List<Reference> exports;
 
   LinkedLibraryContext context;
 
@@ -43,11 +41,11 @@
 
   final List<Export> exporters = [];
 
-  LibraryBuilder(this.linker, this.uri, this.reference, this.node);
+  LibraryBuilder._(this.linker, this.uri, this.reference);
 
   void addExporters() {
-    var unitContext = context.units[0];
-    for (var directive in unitContext.unit_withDirectives.directives) {
+    var unitContext = context.definingUnit;
+    for (var directive in unitContext.unit.directives) {
       if (directive is ast.ExportDirective) {
         Uri uri;
         try {
@@ -89,8 +87,8 @@
 
   /// Add top-level declaration of the library units to the local scope.
   void addLocalDeclarations() {
-    for (var unitContext in context.units) {
-      var unitRef = reference.getChild('@unit').getChild(unitContext.uriStr);
+    for (var linkingUnit in context.units) {
+      var unitRef = reference.getChild('@unit').getChild(linkingUnit.uriStr);
       var classRef = unitRef.getChild('@class');
       var enumRef = unitRef.getChild('@enum');
       var extensionRef = unitRef.getChild('@extension');
@@ -101,26 +99,34 @@
       var setterRef = unitRef.getChild('@setter');
       var variableRef = unitRef.getChild('@variable');
       var nextUnnamedExtensionId = 0;
-      for (var node in unitContext.unit.declarations) {
+      for (var node in linkingUnit.unit.declarations) {
         if (node is ast.ClassDeclaration) {
           var name = node.name.name;
           var reference = classRef.getChild(name);
           reference.node ??= node;
           localScope.declare(name, reference);
+
+          ClassElementImpl.forLinkedNode(
+              linkingUnit.reference.element, reference, node);
         } else if (node is ast.ClassTypeAlias) {
           var name = node.name.name;
           var reference = classRef.getChild(name);
           reference.node ??= node;
           localScope.declare(name, reference);
+
+          ClassElementImpl.forLinkedNode(
+              linkingUnit.reference.element, reference, node);
         } else if (node is ast.EnumDeclaration) {
           var name = node.name.name;
           var reference = enumRef.getChild(name);
           reference.node ??= node;
           localScope.declare(name, reference);
+
+          EnumElementImpl.forLinkedNode(
+              linkingUnit.reference.element, reference, node);
         } else if (node is ast.ExtensionDeclaration) {
           var name = node.name?.name;
           var refName = name ?? 'extension-${nextUnnamedExtensionId++}';
-          LazyExtensionDeclaration.get(node).setRefName(refName);
 
           var reference = extensionRef.getChild(refName);
           reference.node ??= node;
@@ -128,19 +134,27 @@
           if (name != null) {
             localScope.declare(name, reference);
           }
+
+          ExtensionElementImpl.forLinkedNode(
+              linkingUnit.reference.element, reference, node);
         } else if (node is ast.FunctionDeclaration) {
           var name = node.name.name;
 
-          Reference containerRef;
+          Reference reference;
           if (node.isGetter) {
-            containerRef = getterRef;
+            reference = getterRef.getChild(name);
+            PropertyAccessorElementImpl.forLinkedNode(
+                linkingUnit.reference.element, reference, node);
           } else if (node.isSetter) {
-            containerRef = setterRef;
+            reference = setterRef.getChild(name);
+            PropertyAccessorElementImpl.forLinkedNode(
+                linkingUnit.reference.element, reference, node);
           } else {
-            containerRef = functionRef;
+            reference = functionRef.getChild(name);
+            FunctionElementImpl.forLinkedNode(
+                linkingUnit.reference.element, reference, node);
           }
 
-          var reference = containerRef.getChild(name);
           reference.node ??= node;
 
           if (node.isSetter) {
@@ -152,19 +166,27 @@
           var name = node.name.name;
           var reference = typeAliasRef.getChild(name);
           reference.node ??= node;
-
           localScope.declare(name, reference);
+
+          FunctionTypeAliasElementImpl.forLinkedNode(
+              linkingUnit.reference.element, reference, node);
         } else if (node is ast.GenericTypeAlias) {
           var name = node.name.name;
           var reference = typeAliasRef.getChild(name);
-          reference.node = node;
+          reference.node ??= node;
 
           localScope.declare(name, reference);
+
+          FunctionTypeAliasElementImpl.forLinkedNode(
+              linkingUnit.reference.element, reference, node);
         } else if (node is ast.MixinDeclaration) {
           var name = node.name.name;
           var reference = mixinRef.getChild(name);
           reference.node ??= node;
           localScope.declare(name, reference);
+
+          MixinElementImpl.forLinkedNode(
+              linkingUnit.reference.element, reference, node);
         } else if (node is ast.TopLevelVariableDeclaration) {
           for (var variable in node.variables.variables) {
             var name = variable.name.name;
@@ -172,6 +194,9 @@
             var reference = variableRef.getChild(name);
             reference.node ??= node;
 
+            TopLevelVariableElementImpl.forLinkedNode(
+                linkingUnit.reference.element, reference, variable);
+
             var getter = getterRef.getChild(name);
             localScope.declare(name, getter);
 
@@ -181,7 +206,6 @@
             }
           }
         } else {
-          // TODO(scheglov) implement
           throw UnimplementedError('${node.runtimeType}');
         }
       }
@@ -207,9 +231,50 @@
     return true;
   }
 
+  void buildDirectives() {
+    var exports = <ExportElement>[];
+    var imports = <ImportElement>[];
+    var hasCoreImport = false;
+
+    // Build elements directives in all units.
+    // Store elements only for the defining unit of the library.
+    var isDefiningUnit = true;
+    for (var unitContext in context.units) {
+      for (var node in unitContext.unit.directives) {
+        if (node is ast.ExportDirective) {
+          var exportElement = ExportElementImpl.forLinkedNode(element, node);
+          if (isDefiningUnit) {
+            exports.add(exportElement);
+          }
+        } else if (node is ast.ImportDirective) {
+          var importElement = ImportElementImpl.forLinkedNode(element, node);
+          if (isDefiningUnit) {
+            imports.add(importElement);
+            hasCoreImport |= importElement.importedLibrary?.isDartCore ?? false;
+          }
+        }
+      }
+      isDefiningUnit = false;
+    }
+
+    element.exports = exports;
+
+    if (!hasCoreImport) {
+      var dartCore = linker.elementFactory.libraryOfUri('dart:core');
+      imports.add(
+        ImportElementImpl(-1)
+          ..importedLibrary = dartCore
+          ..isSynthetic = true
+          ..uri = 'dart:core',
+      );
+    }
+    element.imports = imports;
+  }
+
   void buildElement() {
-    element = linker.elementFactory.libraryOfUri('$uri');
-    scope = element.scope;
+    linker.elementFactory.createLibraryElementForLinking(context);
+    element = reference.element;
+    assert(element != null);
   }
 
   void buildInitialExportScope() {
@@ -218,6 +283,10 @@
     });
   }
 
+  void buildScope() {
+    scope = element.scope;
+  }
+
   void collectMixinSuperInvokedNames() {
     for (var unitContext in context.units) {
       for (var declaration in unitContext.unit.declarations) {
@@ -229,8 +298,8 @@
               executable.body.accept(collector);
             }
           }
-          var lazy = LazyMixinDeclaration.get(declaration);
-          lazy.setSuperInvokedNames(names.toList());
+          var element = declaration.declaredElement as MixinElementImpl;
+          element.superInvokedNames = names.toList();
         }
       }
     }
@@ -274,7 +343,14 @@
         try {
           var uri = _selectAbsoluteUri(directive);
           if (uri != null) {
-            LazyDirective.setSelectedUri(directive, '$uri');
+            var library = linker.elementFactory.libraryOfUri('$uri');
+            if (directive is ast.ExportDirective) {
+              var exportElement = directive.element as ExportElementImpl;
+              exportElement.exportedLibrary = library;
+            } else if (directive is ast.ImportDirective) {
+              var importElement = directive.element as ImportElementImpl;
+              importElement.importedLibrary = library;
+            }
           }
         } on FormatException {
           // ignored
@@ -284,11 +360,14 @@
   }
 
   void storeExportScope() {
-    var linkingBundleContext = linker.linkingBundleContext;
-    for (var reference in exportScope.map.values) {
-      var index = linkingBundleContext.indexOfReference(reference);
-      node.exports.add(index);
-    }
+    exports = exportScope.map.values.toList();
+    linker.elementFactory.linkingExports['$uri'] = exports;
+
+    // TODO(scheglov) store for serialization
+    // for (var reference in exportScope.map.values) {
+    //   var index = linkingBundleContext.indexOfReference(reference);
+    //   context.exports.add(index);
+    // }
   }
 
   Uri _selectAbsoluteUri(ast.NamespaceDirective directive) {
@@ -318,45 +397,34 @@
   }
 
   static void build(Linker linker, LinkInputLibrary inputLibrary) {
-    var libraryUri = inputLibrary.source.uri;
-    var libraryUriStr = '$libraryUri';
-    var libraryReference = linker.rootReference.getChild(libraryUriStr);
+    var uriStr = inputLibrary.uriStr;
+    var reference = linker.rootReference.getChild(uriStr);
 
-    var libraryNode = LinkedNodeLibraryBuilder(
-      uriStr: libraryUriStr,
-    );
+    var elementFactory = linker.elementFactory;
+    var context = LinkedLibraryContext(elementFactory, uriStr, reference);
 
-    var definingUnit = inputLibrary.units[0].unit;
-    for (var directive in definingUnit.directives) {
-      if (directive is ast.LibraryDirective) {
-        var name = directive.name;
-        libraryNode.name = name.components.map((id) => id.name).join('.');
-        libraryNode.nameOffset = name.offset;
-        libraryNode.nameLength = name.length;
-        break;
-      }
+    var unitRef = reference.getChild('@unit');
+    var unitIndex = 0;
+    for (var inputUnit in inputLibrary.units) {
+      var source = inputUnit.source;
+      var uriStr = source != null ? '${source.uri}' : '';
+      var reference = unitRef.getChild(uriStr);
+      context.units.add(
+        LinkedUnitContext(
+          context,
+          unitIndex++,
+          inputUnit.partUriStr,
+          uriStr,
+          reference,
+          inputUnit.isSynthetic,
+          unit: inputUnit.unit,
+          unitReader: null,
+        ),
+      );
     }
 
-    var builder = LibraryBuilder(
-      linker,
-      libraryUri,
-      libraryReference,
-      libraryNode,
-    );
+    var builder = LibraryBuilder._(linker, inputLibrary.uri, reference);
     linker.builders[builder.uri] = builder;
-
-    builder.context = linker.bundleContext.addLinkingLibrary(
-      libraryUriStr,
-      libraryNode,
-      inputLibrary,
-    );
+    builder.context = context;
   }
 }
-
-class UnitBuilder {
-  final Uri uri;
-  final LinkedUnitContext context;
-  final LinkedNode node;
-
-  UnitBuilder(this.uri, this.context, this.node);
-}
diff --git a/pkg/analyzer/lib/src/summary2/link.dart b/pkg/analyzer/lib/src/summary2/link.dart
index 281f0dc..9295a32 100644
--- a/pkg/analyzer/lib/src/summary2/link.dart
+++ b/pkg/analyzer/lib/src/summary2/link.dart
@@ -2,24 +2,24 @@
 // 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:typed_data';
+
 import 'package:analyzer/dart/analysis/declared_variables.dart';
 import 'package:analyzer/dart/ast/ast.dart' show CompilationUnit;
 import 'package:analyzer/src/context/context.dart';
 import 'package:analyzer/src/dart/element/inheritance_manager3.dart';
 import 'package:analyzer/src/generated/constant.dart';
 import 'package:analyzer/src/generated/source.dart';
-import 'package:analyzer/src/summary/format.dart';
-import 'package:analyzer/src/summary2/ast_binary_writer.dart';
+import 'package:analyzer/src/summary2/bundle_writer.dart';
 import 'package:analyzer/src/summary2/library_builder.dart';
-import 'package:analyzer/src/summary2/linked_bundle_context.dart';
 import 'package:analyzer/src/summary2/linked_element_factory.dart';
-import 'package:analyzer/src/summary2/linking_bundle_context.dart';
 import 'package:analyzer/src/summary2/reference.dart';
 import 'package:analyzer/src/summary2/simply_bounded.dart';
 import 'package:analyzer/src/summary2/top_level_inference.dart';
 import 'package:analyzer/src/summary2/type_alias.dart';
 import 'package:analyzer/src/summary2/types_builder.dart';
 import 'package:analyzer/src/summary2/variance_builder.dart';
+import 'package:meta/meta.dart';
 
 var timerLinkingLinkingBundle = Stopwatch();
 var timerLinkingRemoveBundle = Stopwatch();
@@ -27,34 +27,29 @@
 LinkResult link(
   LinkedElementFactory elementFactory,
   List<LinkInputLibrary> inputLibraries,
+  bool withInformative,
 ) {
-  var linker = Linker(elementFactory);
+  var linker = Linker(elementFactory, withInformative);
   linker.link(inputLibraries);
-  return LinkResult(linker.linkingBundle);
+  return LinkResult(
+    astBytes: linker.astBytes,
+    resolutionBytes: linker.resolutionBytes,
+  );
 }
 
 class Linker {
   final LinkedElementFactory elementFactory;
-
-  LinkedNodeBundleBuilder linkingBundle;
-  LinkedBundleContext bundleContext;
-  LinkingBundleContext linkingBundleContext;
+  final bool withInformative;
 
   /// Libraries that are being linked.
   final Map<Uri, LibraryBuilder> builders = {};
 
   InheritanceManager3 inheritance; // TODO(scheglov) cache it
 
-  Linker(this.elementFactory) {
-    linkingBundleContext = LinkingBundleContext(
-      elementFactory.dynamicRef,
-    );
+  Uint8List astBytes;
+  Uint8List resolutionBytes;
 
-    bundleContext = LinkedBundleContext.forAst(
-      elementFactory,
-      linkingBundleContext.references,
-    );
-  }
+  Linker(this.elementFactory, this.withInformative);
 
   AnalysisContextImpl get analysisContext {
     return elementFactory.analysisContext;
@@ -70,8 +65,6 @@
     for (var inputLibrary in inputLibraries) {
       LibraryBuilder.build(this, inputLibrary);
     }
-    // TODO(scheglov) do in build() ?
-    elementFactory.addBundle(bundleContext);
 
     _buildOutlines();
 
@@ -80,13 +73,13 @@
     timerLinkingLinkingBundle.stop();
 
     timerLinkingRemoveBundle.start();
-    linkingBundleContext.clearIndexes();
-    elementFactory.removeBundle(bundleContext);
+    elementFactory.removeBundle(
+      inputLibraries.map((e) => e.uriStr).toSet(),
+    );
     timerLinkingRemoveBundle.stop();
   }
 
   void _buildOutlines() {
-    _resolveUriDirectives();
     _computeLibraryScopes();
     _createTypeSystem();
     _resolveTypes();
@@ -107,10 +100,19 @@
 
   void _computeLibraryScopes() {
     for (var library in builders.values) {
+      library.buildElement();
+    }
+
+    for (var library in builders.values) {
+      library.buildDirectives();
       library.addLocalDeclarations();
     }
 
     for (var library in builders.values) {
+      library.resolveUriDirectives();
+    }
+
+    for (var library in builders.values) {
       library.buildInitialExportScope();
     }
 
@@ -159,34 +161,47 @@
     }
 
     for (var library in builders.values) {
-      library.buildElement();
+      library.buildScope();
     }
   }
 
   void _createLinkingBundle() {
-    var linkingLibraries = <LinkedNodeLibraryBuilder>[];
-    for (var builder in builders.values) {
-      linkingLibraries.add(builder.node);
-
-      for (var unitContext in builder.context.units) {
-        var unit = unitContext.unit;
-
-        var writer = AstBinaryWriter(linkingBundleContext);
-        var unitLinkedNode = writer.writeUnit(unit);
-        builder.node.units.add(
-          LinkedNodeUnitBuilder(
-            isSynthetic: unitContext.isSynthetic,
-            partUriStr: unitContext.partUriStr,
-            uriStr: unitContext.uriStr,
-            node: unitLinkedNode,
-          ),
-        );
-      }
-    }
-    linkingBundle = LinkedNodeBundleBuilder(
-      references: linkingBundleContext.referencesBuilder,
-      libraries: linkingLibraries,
+    var bundleWriter2 = BundleWriter(
+      withInformative,
+      elementFactory.dynamicRef,
     );
+    var bundleWriterTimer = Stopwatch();
+
+    for (var builder in builders.values) {
+      bundleWriterTimer.start();
+      bundleWriter2.addLibrary(
+        LibraryToWrite(
+          uriStr: '${builder.uri}',
+          exports: builder.exports,
+          units: builder.context.units.map((e) {
+            return UnitToWrite(
+              uriStr: e.uriStr,
+              partUriStr: e.partUriStr,
+              node: e.unit,
+              isSynthetic: e.isSynthetic,
+            );
+          }).toList(),
+        ),
+      );
+      bundleWriterTimer.stop();
+    }
+
+    bundleWriterTimer.start();
+    var writeWriterResult = bundleWriter2.finish();
+    astBytes = writeWriterResult.astBytes;
+    resolutionBytes = writeWriterResult.resolutionBytes;
+    bundleWriterTimer.stop();
+    // print(
+    //   '[bytes: ${astBytes.length + resolutionBytes.length}]'
+    //   '[astBytes: ${astBytes.length}]'
+    //   '[resolutionBytes: ${resolutionBytes.length}]'
+    //   '[time: ${bundleWriterTimer.elapsedMilliseconds} ms]',
+    // );
   }
 
   void _createTypeSystem() {
@@ -229,15 +244,9 @@
       library.resolveTypes(nodesToBuildType);
     }
     VarianceBuilder().perform(this);
-    computeSimplyBounded(bundleContext, builders.values);
+    computeSimplyBounded(builders.values);
     TypesBuilder().build(nodesToBuildType);
   }
-
-  void _resolveUriDirectives() {
-    for (var library in builders.values) {
-      library.resolveUriDirectives();
-    }
-  }
 }
 
 class LinkInputLibrary {
@@ -245,6 +254,10 @@
   final List<LinkInputUnit> units;
 
   LinkInputLibrary(this.source, this.units);
+
+  Uri get uri => source.uri;
+
+  String get uriStr => '$uri';
 }
 
 class LinkInputUnit {
@@ -259,10 +272,21 @@
     this.isSynthetic,
     this.unit,
   );
+
+  String get uriStr {
+    if (source == null) {
+      return '';
+    }
+    return '${source.uri}';
+  }
 }
 
 class LinkResult {
-  final LinkedNodeBundleBuilder bundle;
+  final Uint8List astBytes;
+  final Uint8List resolutionBytes;
 
-  LinkResult(this.bundle);
+  LinkResult({
+    @required this.astBytes,
+    @required this.resolutionBytes,
+  });
 }
diff --git a/pkg/analyzer/lib/src/summary2/linked_bundle_context.dart b/pkg/analyzer/lib/src/summary2/linked_bundle_context.dart
deleted file mode 100644
index 7047fb0..0000000
--- a/pkg/analyzer/lib/src/summary2/linked_bundle_context.dart
+++ /dev/null
@@ -1,140 +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 'package:analyzer/dart/element/element.dart';
-import 'package:analyzer/src/summary/format.dart';
-import 'package:analyzer/src/summary/idl.dart';
-import 'package:analyzer/src/summary2/informative_data.dart';
-import 'package:analyzer/src/summary2/link.dart';
-import 'package:analyzer/src/summary2/linked_element_factory.dart';
-import 'package:analyzer/src/summary2/linked_unit_context.dart';
-import 'package:analyzer/src/summary2/reference.dart';
-
-/// The context of a linked bundle, with shared references.
-class LinkedBundleContext {
-  final LinkedElementFactory elementFactory;
-  final LinkedNodeBundle _bundle;
-  final List<Reference> _references;
-  final Map<String, LinkedLibraryContext> libraryMap = {};
-
-  LinkedBundleContext(this.elementFactory, this._bundle)
-      : _references = List<Reference>(_bundle.references.name.length) {
-    for (var library in _bundle.libraries) {
-      var uriStr = library.uriStr;
-      var reference = elementFactory.rootReference.getChild(uriStr);
-      var libraryContext = LinkedLibraryContext(
-        this,
-        uriStr,
-        reference,
-        library,
-      );
-      libraryMap[uriStr] = libraryContext;
-
-      var unitRef = reference.getChild('@unit');
-      var units = library.units;
-      for (var unitIndex = 0; unitIndex < units.length; ++unitIndex) {
-        var unit = units[unitIndex];
-        var uriStr = unit.uriStr;
-        var reference = unitRef.getChild(uriStr);
-        var unitContext = LinkedUnitContext(
-          this,
-          libraryContext,
-          unitIndex,
-          unit.partUriStr,
-          uriStr,
-          reference,
-          unit.isSynthetic,
-          unit,
-        );
-        libraryContext.units.add(unitContext);
-      }
-    }
-  }
-
-  LinkedBundleContext.forAst(this.elementFactory, this._references)
-      : _bundle = null;
-
-  /// Return `true` if this bundle is being linked.
-  bool get isLinking => _bundle == null;
-
-  LinkedLibraryContext addLinkingLibrary(
-    String uriStr,
-    LinkedNodeLibraryBuilder data,
-    LinkInputLibrary inputLibrary,
-  ) {
-    var uriStr = data.uriStr;
-    var reference = elementFactory.rootReference.getChild(uriStr);
-    var libraryContext = LinkedLibraryContext(this, uriStr, reference, data);
-    libraryMap[uriStr] = libraryContext;
-
-    var unitRef = reference.getChild('@unit');
-    var unitIndex = 0;
-    for (var inputUnit in inputLibrary.units) {
-      var source = inputUnit.source;
-      var uriStr = source != null ? '${source.uri}' : '';
-      var reference = unitRef.getChild(uriStr);
-      createInformativeData(inputUnit.unit);
-      libraryContext.units.add(
-        LinkedUnitContext(
-          this,
-          libraryContext,
-          unitIndex++,
-          inputUnit.partUriStr,
-          uriStr,
-          reference,
-          inputUnit.isSynthetic,
-          null,
-          unit: inputUnit.unit,
-        ),
-      );
-    }
-    return libraryContext;
-  }
-
-  T elementOfIndex<T extends Element>(int index) {
-    var reference = referenceOfIndex(index);
-    return elementFactory.elementOfReference(reference);
-  }
-
-  List<T> elementsOfIndexes<T extends Element>(List<int> indexList) {
-    var result = List<T>(indexList.length);
-    for (var i = 0; i < indexList.length; ++i) {
-      var index = indexList[i];
-      result[i] = elementOfIndex(index);
-    }
-    return result;
-  }
-
-  Reference referenceOfIndex(int index) {
-    var reference = _references[index];
-    if (reference != null) return reference;
-
-    if (index == 0) {
-      reference = elementFactory.rootReference;
-      _references[index] = reference;
-      return reference;
-    }
-
-    var parentIndex = _bundle.references.parent[index];
-    var parent = referenceOfIndex(parentIndex);
-
-    var name = _bundle.references.name[index];
-    reference = parent.getChild(name);
-    _references[index] = reference;
-
-    return reference;
-  }
-}
-
-class LinkedLibraryContext {
-  final LinkedBundleContext context;
-  final String uriStr;
-  final Reference reference;
-  final LinkedNodeLibrary node;
-  final List<LinkedUnitContext> units = [];
-
-  LinkedLibraryContext(this.context, this.uriStr, this.reference, this.node);
-
-  LinkedUnitContext get definingUnit => units.first;
-}
diff --git a/pkg/analyzer/lib/src/summary2/linked_element_factory.dart b/pkg/analyzer/lib/src/summary2/linked_element_factory.dart
index abfaeec..58ca7e9 100644
--- a/pkg/analyzer/lib/src/summary2/linked_element_factory.dart
+++ b/pkg/analyzer/lib/src/summary2/linked_element_factory.dart
@@ -9,9 +9,8 @@
 import 'package:analyzer/src/dart/element/element.dart';
 import 'package:analyzer/src/dart/element/type_provider.dart';
 import 'package:analyzer/src/dart/resolver/scope.dart';
-import 'package:analyzer/src/summary/idl.dart';
-import 'package:analyzer/src/summary2/lazy_ast.dart';
-import 'package:analyzer/src/summary2/linked_bundle_context.dart';
+import 'package:analyzer/src/summary2/bundle_reader.dart';
+import 'package:analyzer/src/summary2/linked_library_context.dart';
 import 'package:analyzer/src/summary2/linked_unit_context.dart';
 import 'package:analyzer/src/summary2/reference.dart';
 
@@ -19,7 +18,8 @@
   final AnalysisContextImpl analysisContext;
   final AnalysisSessionImpl analysisSession;
   final Reference rootReference;
-  final Map<String, LinkedLibraryContext> libraryMap = {};
+  final Map<String, List<Reference>> linkingExports = {};
+  final Map<String, LibraryReader> libraryReaders = {};
 
   LinkedElementFactory(
     this.analysisContext,
@@ -36,11 +36,11 @@
   }
 
   bool get hasDartCore {
-    return libraryMap.containsKey('dart:core');
+    return libraryReaders.containsKey('dart:core');
   }
 
-  void addBundle(LinkedBundleContext context) {
-    libraryMap.addAll(context.libraryMap);
+  void addBundle(BundleReader bundle) {
+    libraryReaders.addAll(bundle.libraryMap);
   }
 
   Namespace buildExportNamespace(Uri uri) {
@@ -64,6 +64,147 @@
     return Namespace(exportedNames);
   }
 
+  LibraryElementImpl createLibraryElementForLinking(
+    LinkedLibraryContext libraryContext,
+  ) {
+    var sourceFactory = analysisContext.sourceFactory;
+    var libraryUriStr = libraryContext.uriStr;
+    var librarySource = sourceFactory.forUri(libraryUriStr);
+
+    // The URI cannot be resolved, we don't know the library.
+    if (librarySource == null) return null;
+
+    var definingUnitContext = libraryContext.units[0];
+    var definingUnitNode = definingUnitContext.unit;
+
+    // TODO(scheglov) Do we need this?
+    var name = '';
+    var nameOffset = -1;
+    var nameLength = 0;
+    for (var directive in definingUnitNode.directives) {
+      if (directive is LibraryDirective) {
+        name = directive.name.components.map((e) => e.name).join('.');
+        nameOffset = directive.name.offset;
+        nameLength = directive.name.length;
+        break;
+      }
+    }
+
+    var libraryElement = LibraryElementImpl.forLinkedNode(
+      analysisContext,
+      analysisSession,
+      name,
+      nameOffset,
+      nameLength,
+      definingUnitContext,
+      libraryContext.reference,
+      definingUnitNode,
+    );
+    _setLibraryTypeSystem(libraryElement);
+
+    var units = <CompilationUnitElementImpl>[];
+    var unitContainerRef = libraryContext.reference.getChild('@unit');
+    for (var unitContext in libraryContext.units) {
+      var unitNode = unitContext.unit;
+
+      var unitSource = sourceFactory.forUri(unitContext.uriStr);
+      var unitElement = CompilationUnitElementImpl.forLinkedNode(
+        libraryElement,
+        unitContext,
+        unitContext.reference,
+        unitNode,
+      );
+      unitElement.lineInfo = unitNode.lineInfo;
+      unitElement.source = unitSource;
+      unitElement.librarySource = librarySource;
+      unitElement.uri = unitContext.partUriStr;
+      units.add(unitElement);
+      unitContainerRef.getChild(unitContext.uriStr).element = unitElement;
+    }
+
+    libraryElement.definingCompilationUnit = units[0];
+    libraryElement.parts = units.skip(1).toList();
+    libraryContext.reference.element = libraryElement;
+
+    return libraryElement;
+  }
+
+  LibraryElementImpl createLibraryElementForReading(String uriStr) {
+    var sourceFactory = analysisContext.sourceFactory;
+    var librarySource = sourceFactory.forUri(uriStr);
+
+    // The URI cannot be resolved, we don't know the library.
+    if (librarySource == null) return null;
+
+    var reader = libraryReaders[uriStr];
+    if (reader == null) {
+      throw ArgumentError(
+        'Missing library: $uriStr\n'
+        'Available libraries: ${libraryReaders.keys.toList()}',
+      );
+    }
+
+    var libraryContext = LinkedLibraryContext(this, uriStr, reader.reference);
+    var unitContainerRef = reader.reference.getChild('@unit');
+
+    var unitContexts = <LinkedUnitContext>[];
+    var indexInLibrary = 0;
+    var unitReaders = reader.units;
+    for (var unitReader in unitReaders) {
+      var unitReference = unitContainerRef.getChild(unitReader.uriStr);
+      var unitContext = LinkedUnitContext(
+        libraryContext,
+        indexInLibrary++,
+        unitReader.partUriStr,
+        unitReader.uriStr,
+        unitReference,
+        unitReader.isSynthetic,
+        unit: unitReader.unit,
+        unitReader: unitReader,
+      );
+      unitContexts.add(unitContext);
+      libraryContext.units.add(unitContext);
+    }
+
+    var definingUnitContext = unitContexts[0];
+    var libraryElement = LibraryElementImpl.forLinkedNode(
+      analysisContext,
+      analysisSession,
+      reader.name,
+      reader.nameOffset,
+      reader.nameLength,
+      definingUnitContext,
+      reader.reference,
+      unitReaders.first.unit,
+    );
+    _setLibraryTypeSystem(libraryElement);
+
+    var units = <CompilationUnitElementImpl>[];
+    for (var unitContext in unitContexts) {
+      var unitNode = unitContext.unit;
+
+      var unitSource = sourceFactory.forUri(unitContext.uriStr);
+      var unitElement = CompilationUnitElementImpl.forLinkedNode(
+        libraryElement,
+        unitContext,
+        unitContext.reference,
+        unitNode,
+      );
+      unitElement.lineInfo = unitNode.lineInfo;
+      unitElement.source = unitSource;
+      unitElement.librarySource = librarySource;
+      unitElement.uri = unitContext.partUriStr;
+      units.add(unitElement);
+      unitContainerRef.getChild(unitContext.uriStr).element = unitElement;
+    }
+
+    libraryElement.definingCompilationUnit = units[0];
+    libraryElement.parts = units.skip(1).toList();
+    reader.reference.element = libraryElement;
+
+    return libraryElement;
+  }
+
   void createTypeProviders(
     LibraryElementImpl dartCore,
     LibraryElementImpl dartAsync,
@@ -103,34 +244,143 @@
       return null;
     }
 
-    return _ElementRequest(this, reference).elementOfReference(reference);
+    if (reference.isLibrary) {
+      var uriStr = reference.name;
+      return createLibraryElementForReading(uriStr);
+    }
+
+    var parent = reference.parent.parent;
+    var parentElement = elementOfReference(parent);
+
+    // Named formal parameters are created when we apply resolution to the
+    // executable declaration, e.g. a constructor, or a method.
+    if (reference.isParameter) {
+      (parentElement as ExecutableElement).parameters;
+      assert(reference.element != null);
+      return reference.element;
+    }
+
+    // The default constructor might be synthetic, and has no node.
+    // TODO(scheglov) We resynthesize all constructors here.
+    if (reference.isConstructor && reference.name == '') {
+      return (parentElement as ClassElement).unnamedConstructor;
+    }
+
+    if (parentElement is EnumElementImpl) {
+      parentElement.constants;
+      assert(reference.element != null);
+      return reference.element;
+    }
+
+    if (reference.element != null) {
+      return reference.element;
+    }
+
+    if (reference.isUnit) {
+      assert(reference.element != null);
+      return reference.element;
+    }
+
+    if (reference.isPrefix) {
+      (parentElement as LibraryElement).prefixes;
+      assert(reference.element != null);
+      return reference.element;
+    }
+
+    // For class, mixin, extension - index members.
+    parent.nodeAccessor.readIndex();
+
+    // For any element - class, method, etc - read the node.
+    var node = reference.nodeAccessor.node;
+
+    if (node is ClassDeclaration) {
+      ClassElementImpl.forLinkedNode(parentElement, reference, node);
+      assert(reference.element != null);
+      return reference.element;
+    } else if (node is ClassTypeAlias) {
+      ClassElementImpl.forLinkedNode(parentElement, reference, node);
+      assert(reference.element != null);
+      return reference.element;
+    } else if (node is ConstructorDeclaration) {
+      ConstructorElementImpl.forLinkedNode(parentElement, reference, node);
+      var element = reference.element as ConstructorElementImpl;
+      assert(element != null);
+      return element;
+    } else if (node is EnumDeclaration) {
+      EnumElementImpl.forLinkedNode(parentElement, reference, node);
+      assert(reference.element != null);
+      return reference.element;
+    } else if (node is ExtensionDeclaration) {
+      ExtensionElementImpl.forLinkedNode(parentElement, reference, node);
+      assert(reference.element != null);
+      return reference.element;
+    } else if (node is FieldDeclaration) {
+      var variable = _variableDeclaration(node.fields, reference.name);
+      if (variable.isConst) {
+        ConstFieldElementImpl.forLinkedNode(parentElement, reference, variable);
+      } else {
+        FieldElementImpl.forLinkedNodeFactory(
+            parentElement, reference, variable);
+      }
+      assert(reference.element != null);
+      return reference.element;
+    } else if (node is FunctionDeclaration) {
+      if (node.propertyKeyword != null) {
+        _topLevelPropertyAccessor(parent, parentElement, reference, node);
+      } else {
+        FunctionElementImpl.forLinkedNode(parentElement, reference, node);
+      }
+      assert(reference.element != null);
+      return reference.element;
+    } else if (node is FunctionTypeAlias || node is GenericTypeAlias) {
+      FunctionTypeAliasElementImpl.forLinkedNode(
+          parentElement, reference, node);
+      assert(reference.element != null);
+      return reference.element;
+    } else if (node is MethodDeclaration) {
+      if (node.propertyKeyword != null) {
+        PropertyAccessorElementImpl.forLinkedNode(
+            parentElement, reference, node);
+      } else {
+        MethodElementImpl.forLinkedNode(parentElement, reference, node);
+      }
+      assert(reference.element != null);
+      return reference.element;
+    } else if (node is MixinDeclaration) {
+      MixinElementImpl.forLinkedNode(parentElement, reference, node);
+      assert(reference.element != null);
+      return reference.element;
+    } else if (node is TopLevelVariableDeclaration) {
+      var variable = _variableDeclaration(node.variables, reference.name);
+      if (variable.isConst) {
+        ConstTopLevelVariableElementImpl.forLinkedNode(
+            parentElement, reference, variable);
+      } else {
+        TopLevelVariableElementImpl.forLinkedNode(
+            parentElement, reference, variable);
+      }
+      assert(reference.element != null);
+      return reference.element;
+    }
+
+    throw UnimplementedError('$reference');
   }
 
   List<Reference> exportsOfLibrary(String uriStr) {
-    var library = libraryMap[uriStr];
+    var linkingExportedReferences = linkingExports[uriStr];
+    if (linkingExportedReferences != null) {
+      return linkingExportedReferences;
+    }
+
+    var library = libraryReaders[uriStr];
     if (library == null) return const [];
 
-    // Ask for source to trigger dependency tracking.
-    //
-    // Usually we record a dependency because we request an element from a
-    // library, so we build its library element, so request its source.
-    // However if a library is just exported, and the exporting library is not
-    // imported itself, we just copy references, without computing elements.
-    analysisContext.sourceFactory.forUri(uriStr);
-
-    var exportIndexList = library.node.exports;
-    var exportReferences = List<Reference>(exportIndexList.length);
-    for (var i = 0; i < exportIndexList.length; ++i) {
-      var index = exportIndexList[i];
-      var reference = library.context.referenceOfIndex(index);
-      exportReferences[i] = reference;
-    }
-    return exportReferences;
+    return library.exports;
   }
 
   bool isLibraryUri(String uriStr) {
-    var libraryContext = libraryMap[uriStr];
-    return !libraryContext.definingUnit.hasPartOfDirective;
+    var libraryContext = libraryReaders[uriStr];
+    return !libraryContext.hasPartOfDirective;
   }
 
   LibraryElementImpl libraryOfUri(String uriStr) {
@@ -140,8 +390,7 @@
 
   /// We have linked the bundle, and need to disconnect its libraries, so
   /// that the client can re-add the bundle, this time read from bytes.
-  void removeBundle(LinkedBundleContext context) {
-    var uriStrSet = context.libraryMap.keys.toSet();
+  void removeBundle(Set<String> uriStrSet) {
     removeLibraries(uriStrSet);
 
     // This is the bundle with dart:core and dart:async, based on full ASTs.
@@ -154,10 +403,10 @@
           '${uriStrSet.toList()}',
         );
       }
-      if (libraryMap.isNotEmpty) {
+      if (libraryReaders.isNotEmpty) {
         throw StateError(
           'Expected to link dart:core and dart:async first: '
-          '${libraryMap.keys.toList()}',
+          '${libraryReaders.keys.toList()}',
         );
       }
       analysisContext.clearTypeProvider();
@@ -169,7 +418,8 @@
   /// any session level caches.
   void removeLibraries(Set<String> uriStrSet) {
     for (var uriStr in uriStrSet) {
-      libraryMap.remove(uriStr);
+      libraryReaders.remove(uriStr);
+      linkingExports.remove(uriStr);
       rootReference.removeChild(uriStr);
     }
 
@@ -177,23 +427,6 @@
     analysisSession.inheritanceManager.removeOfLibraries(uriStrSet);
   }
 
-  /// Set optional informative data for the unit.
-  void setInformativeData(
-    String libraryUriStr,
-    String unitUriStr,
-    List<UnlinkedInformativeData> informativeData,
-  ) {
-    var libraryContext = libraryMap[libraryUriStr];
-    if (libraryContext != null) {
-      for (var unitContext in libraryContext.units) {
-        if (unitContext.uriStr == unitUriStr) {
-          unitContext.informativeData = informativeData;
-          return;
-        }
-      }
-    }
-  }
-
   void _declareDartCoreDynamicNever() {
     var dartCoreRef = rootReference.getChild('dart:core');
     dartCoreRef.getChild('dynamic').element = DynamicElementImpl.instance;
@@ -218,341 +451,49 @@
 
     libraryElement.createLoadLibraryFunction();
   }
-}
 
-class _ElementRequest {
-  final LinkedElementFactory elementFactory;
-  final Reference input;
-
-  _ElementRequest(this.elementFactory, this.input);
-
-  ElementImpl elementOfReference(Reference reference) {
-    if (reference.element != null) {
-      return reference.element;
-    }
-
-    var parent2 = reference.parent.parent;
-    if (parent2 == null) {
-      return _createLibraryElement(reference);
-    }
-
-    var parentName = reference.parent.name;
-
-    if (parentName == '@class') {
-      var unit = elementOfReference(parent2);
-      return _class(unit, reference);
-    }
-
-    if (parentName == '@constructor') {
-      var class_ = elementOfReference(parent2);
-      return _constructor(class_, reference);
-    }
-
-    if (parentName == '@enum') {
-      var unit = elementOfReference(parent2);
-      return _enum(unit, reference);
-    }
-
-    if (parentName == '@extension') {
-      var unit = elementOfReference(parent2);
-      return _extension(unit, reference);
-    }
-
-    if (parentName == '@field') {
-      var enclosing = elementOfReference(parent2);
-      return _field(enclosing, reference);
-    }
-
-    if (parentName == '@function') {
-      CompilationUnitElementImpl enclosing = elementOfReference(parent2);
-      return _function(enclosing, reference);
-    }
-
-    if (parentName == '@getter' || parentName == '@setter') {
-      var enclosing = elementOfReference(parent2);
-      return _accessor(enclosing, reference);
-    }
-
-    if (parentName == '@method') {
-      var enclosing = elementOfReference(parent2);
-      return _method(enclosing, reference);
-    }
-
-    if (parentName == '@mixin') {
-      var unit = elementOfReference(parent2);
-      return _mixin(unit, reference);
-    }
-
-    if (parentName == '@parameter') {
-      ExecutableElementImpl enclosing = elementOfReference(parent2);
-      return _parameter(enclosing, reference);
-    }
-
-    if (parentName == '@prefix') {
-      LibraryElementImpl enclosing = elementOfReference(parent2);
-      return _prefix(enclosing, reference);
-    }
-
-    if (parentName == '@typeAlias') {
-      var unit = elementOfReference(parent2);
-      return _typeAlias(unit, reference);
-    }
-
-    if (parentName == '@typeParameter') {
-      var enclosing = elementOfReference(parent2);
-      if (enclosing is ParameterElement) {
-        (enclosing as ParameterElement).typeParameters;
-      } else {
-        (enclosing as TypeParameterizedElement).typeParameters;
-      }
-      assert(reference.element != null);
-      return reference.element;
-    }
-
-    if (parentName == '@unit') {
-      elementOfReference(parent2);
-      // Creating a library fills all its units.
-      assert(reference.element != null);
-      return reference.element;
-    }
-
-    if (reference.name == '@function' && parent2.name == '@typeAlias') {
-      var parent = reference.parent;
-      FunctionTypeAliasElementImpl alias = elementOfReference(parent);
-      return alias.function;
-    }
-
-    throw StateError('Not found: $input');
-  }
-
-  PropertyAccessorElementImpl _accessor(
-      ElementImpl enclosing, Reference reference) {
-    if (enclosing is ClassElementImpl) {
-      enclosing.accessors;
-    } else if (enclosing is CompilationUnitElementImpl) {
-      enclosing.accessors;
-    } else if (enclosing is EnumElementImpl) {
-      enclosing.accessors;
-    } else if (enclosing is ExtensionElementImpl) {
-      enclosing.accessors;
-    } else {
-      throw StateError('${enclosing.runtimeType}');
-    }
-    // Requesting accessors sets elements for accessors and variables.
-    assert(reference.element != null);
-    return reference.element;
-  }
-
-  ClassElementImpl _class(
-      CompilationUnitElementImpl unit, Reference reference) {
-    if (reference.node == null) {
-      _indexUnitElementDeclarations(unit);
-      assert(reference.node != null, '$reference');
-    }
-    ClassElementImpl.forLinkedNode(unit, reference, reference.node);
-    return reference.element;
-  }
-
-  ConstructorElementImpl _constructor(
-      ClassElementImpl enclosing, Reference reference) {
-    enclosing.constructors;
-    // Requesting constructors sets elements for all of them.
-    assert(reference.element != null);
-    return reference.element;
-  }
-
-  LibraryElementImpl _createLibraryElement(Reference reference) {
-    var uriStr = reference.name;
-
-    var sourceFactory = elementFactory.analysisContext.sourceFactory;
-    var librarySource = sourceFactory.forUri(uriStr);
-
-    // The URI cannot be resolved, we don't know the library.
-    if (librarySource == null) return null;
-
-    var libraryContext = elementFactory.libraryMap[uriStr];
-    if (libraryContext == null) {
-      throw ArgumentError(
-        'Missing library: $uriStr\n'
-        'Available libraries: ${elementFactory.libraryMap.keys.toList()}',
-      );
-    }
-    var libraryNode = libraryContext.node;
-    var hasName = libraryNode.name.isNotEmpty;
-
-    var definingUnitContext = libraryContext.definingUnit;
-
-    var libraryElement = LibraryElementImpl.forLinkedNode(
-      elementFactory.analysisContext,
-      elementFactory.analysisSession,
-      libraryNode.name,
-      hasName ? libraryNode.nameOffset : -1,
-      libraryNode.nameLength,
-      definingUnitContext,
-      reference,
-      definingUnitContext.unit_withDeclarations,
-    );
-    elementFactory._setLibraryTypeSystem(libraryElement);
-
-    var units = <CompilationUnitElementImpl>[];
-    var unitContainerRef = reference.getChild('@unit');
-    for (var unitContext in libraryContext.units) {
-      var unitNode = unitContext.unit_withDeclarations;
-
-      var unitSource = sourceFactory.forUri(unitContext.uriStr);
-      var unitElement = CompilationUnitElementImpl.forLinkedNode(
-        libraryElement,
-        unitContext,
-        unitContext.reference,
-        unitNode,
-      );
-      unitElement.lineInfo = unitNode.lineInfo;
-      unitElement.source = unitSource;
-      unitElement.librarySource = librarySource;
-      unitElement.uri = unitContext.partUriStr;
-      units.add(unitElement);
-      unitContainerRef.getChild(unitContext.uriStr).element = unitElement;
-    }
-
-    libraryElement.definingCompilationUnit = units[0];
-    libraryElement.parts = units.skip(1).toList();
-    reference.element = libraryElement;
-
-    return libraryElement;
-  }
-
-  EnumElementImpl _enum(CompilationUnitElementImpl unit, Reference reference) {
-    if (reference.node == null) {
-      _indexUnitElementDeclarations(unit);
-      assert(reference.node != null, '$reference');
-    }
-    EnumElementImpl.forLinkedNode(unit, reference, reference.node);
-    return reference.element;
-  }
-
-  ExtensionElementImpl _extension(
-      CompilationUnitElementImpl unit, Reference reference) {
-    if (reference.node == null) {
-      _indexUnitElementDeclarations(unit);
-      assert(reference.node != null, '$reference');
-    }
-    ExtensionElementImpl.forLinkedNode(unit, reference, reference.node);
-    return reference.element;
-  }
-
-  FieldElementImpl _field(ClassElementImpl enclosing, Reference reference) {
-    enclosing.fields;
-    // Requesting fields sets elements for all fields.
-    assert(reference.element != null);
-    return reference.element;
-  }
-
-  Element _function(CompilationUnitElementImpl enclosing, Reference reference) {
-    enclosing.functions;
-    assert(reference.element != null);
-    return reference.element;
-  }
-
-  void _indexUnitElementDeclarations(CompilationUnitElementImpl unit) {
-    var unitContext = unit.linkedContext;
-    var unitRef = unit.reference;
-    var unitNode = unit.linkedNode;
-    _indexUnitDeclarations(unitContext, unitRef, unitNode);
-  }
-
-  MethodElementImpl _method(ElementImpl enclosing, Reference reference) {
-    if (enclosing is ClassElementImpl) {
-      enclosing.methods;
-    } else if (enclosing is ExtensionElementImpl) {
-      enclosing.methods;
-    } else {
-      throw StateError('${enclosing.runtimeType}');
-    }
-    // Requesting methods sets elements for all of them.
-    assert(reference.element != null);
-    return reference.element;
-  }
-
-  MixinElementImpl _mixin(
-      CompilationUnitElementImpl unit, Reference reference) {
-    if (reference.node == null) {
-      _indexUnitElementDeclarations(unit);
-      assert(reference.node != null, '$reference');
-    }
-    MixinElementImpl.forLinkedNode(unit, reference, reference.node);
-    return reference.element;
-  }
-
-  Element _parameter(ExecutableElementImpl enclosing, Reference reference) {
-    enclosing.parameters;
-    assert(reference.element != null);
-    return reference.element;
-  }
-
-  PrefixElementImpl _prefix(LibraryElementImpl library, Reference reference) {
-    for (var import in library.imports) {
-      import.prefix;
-    }
-    assert(reference.element != null);
-    return reference.element;
-  }
-
-  FunctionTypeAliasElementImpl _typeAlias(
-      CompilationUnitElementImpl unit, Reference reference) {
-    if (reference.node == null) {
-      _indexUnitElementDeclarations(unit);
-      assert(reference.node != null, '$reference');
-    }
-    FunctionTypeAliasElementImpl.forLinkedNode(unit, reference, reference.node);
-    return reference.element;
-  }
-
-  /// Index nodes for which we choose to create elements individually,
-  /// for example [ClassDeclaration], so that its [Reference] has the node,
-  /// and we can call the [ClassElementImpl] constructor.
-  static void _indexUnitDeclarations(
-    LinkedUnitContext unitContext,
-    Reference unitRef,
-    CompilationUnit unitNode,
+  void _topLevelPropertyAccessor(
+    Reference parentReference,
+    CompilationUnitElementImpl parentElement,
+    Reference reference,
+    FunctionDeclaration node,
   ) {
-    var classRef = unitRef.getChild('@class');
-    var enumRef = unitRef.getChild('@enum');
-    var extensionRef = unitRef.getChild('@extension');
-    var functionRef = unitRef.getChild('@function');
-    var mixinRef = unitRef.getChild('@mixin');
-    var typeAliasRef = unitRef.getChild('@typeAlias');
-    var variableRef = unitRef.getChild('@variable');
-    for (var declaration in unitNode.declarations) {
-      if (declaration is ClassDeclaration) {
-        var name = declaration.name.name;
-        classRef.getChild(name).node = declaration;
-      } else if (declaration is ClassTypeAlias) {
-        var name = declaration.name.name;
-        classRef.getChild(name).node = declaration;
-      } else if (declaration is ExtensionDeclaration) {
-        var refName = LazyExtensionDeclaration.get(declaration).refName;
-        extensionRef.getChild(refName).node = declaration;
-      } else if (declaration is EnumDeclaration) {
-        var name = declaration.name.name;
-        enumRef.getChild(name).node = declaration;
-      } else if (declaration is FunctionDeclaration) {
-        var name = declaration.name.name;
-        functionRef.getChild(name).node = declaration;
-      } else if (declaration is FunctionTypeAlias) {
-        var name = declaration.name.name;
-        typeAliasRef.getChild(name).node = declaration;
-      } else if (declaration is GenericTypeAlias) {
-        var name = declaration.name.name;
-        typeAliasRef.getChild(name).node = declaration;
-      } else if (declaration is MixinDeclaration) {
-        var name = declaration.name.name;
-        mixinRef.getChild(name).node = declaration;
-      } else if (declaration is TopLevelVariableDeclaration) {
-        for (var variable in declaration.variables.variables) {
-          var name = variable.name.name;
-          variableRef.getChild(name).node = declaration;
-        }
+    var accessor = PropertyAccessorElementImpl.forLinkedNode(
+        parentElement, reference, node);
+
+    var name = reference.name;
+    var fieldRef = parentReference.getChild('@field').getChild(name);
+    var field = fieldRef.element as TopLevelVariableElementImpl;
+    if (field == null) {
+      field = TopLevelVariableElementImpl(name, -1);
+      fieldRef.element = field;
+      field.enclosingElement = parentElement;
+      field.isFinal = true;
+      field.isSynthetic = true;
+    }
+
+    var isSetter = node.isSetter;
+    if (isSetter) {
+      field.isFinal = false;
+    }
+
+    accessor.variable = field;
+    if (isSetter) {
+      field.setter = accessor;
+    } else {
+      field.getter = accessor;
+    }
+  }
+
+  static VariableDeclaration _variableDeclaration(
+    VariableDeclarationList variableList,
+    String name,
+  ) {
+    for (var variable in variableList.variables) {
+      if (variable.name.name == name) {
+        return variable;
       }
     }
+    throw StateError('No "$name" in: $variableList');
   }
 }
diff --git a/pkg/analyzer/lib/src/summary2/linked_library_context.dart b/pkg/analyzer/lib/src/summary2/linked_library_context.dart
new file mode 100644
index 0000000..e9c7e77
--- /dev/null
+++ b/pkg/analyzer/lib/src/summary2/linked_library_context.dart
@@ -0,0 +1,18 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:analyzer/src/summary2/linked_element_factory.dart';
+import 'package:analyzer/src/summary2/linked_unit_context.dart';
+import 'package:analyzer/src/summary2/reference.dart';
+
+class LinkedLibraryContext {
+  final LinkedElementFactory elementFactory;
+  final String uriStr;
+  final Reference reference;
+  final List<LinkedUnitContext> units = [];
+
+  LinkedLibraryContext(this.elementFactory, this.uriStr, this.reference);
+
+  LinkedUnitContext get definingUnit => units.first;
+}
diff --git a/pkg/analyzer/lib/src/summary2/linked_unit_context.dart b/pkg/analyzer/lib/src/summary2/linked_unit_context.dart
index ff54b07..b9d9dea 100644
--- a/pkg/analyzer/lib/src/summary2/linked_unit_context.dart
+++ b/pkg/analyzer/lib/src/summary2/linked_unit_context.dart
@@ -3,68 +3,36 @@
 // BSD-style license that can be found in the LICENSE file.
 
 import 'package:analyzer/dart/ast/ast.dart';
-import 'package:analyzer/dart/ast/standard_ast_factory.dart';
 import 'package:analyzer/dart/element/element.dart';
-import 'package:analyzer/dart/element/nullability_suffix.dart';
 import 'package:analyzer/dart/element/type.dart';
 import 'package:analyzer/dart/element/type_provider.dart';
-import 'package:analyzer/source/line_info.dart';
 import 'package:analyzer/src/dart/ast/ast.dart';
 import 'package:analyzer/src/dart/element/element.dart';
 import 'package:analyzer/src/dart/element/type.dart';
-import 'package:analyzer/src/dart/resolver/variance.dart';
-import 'package:analyzer/src/generated/testing/token_factory.dart';
-import 'package:analyzer/src/generated/utilities_dart.dart';
-import 'package:analyzer/src/summary/idl.dart';
-import 'package:analyzer/src/summary2/ast_binary_reader.dart';
-import 'package:analyzer/src/summary2/lazy_ast.dart';
-import 'package:analyzer/src/summary2/linked_bundle_context.dart';
+import 'package:analyzer/src/summary2/bundle_reader.dart';
+import 'package:analyzer/src/summary2/linked_element_factory.dart';
+import 'package:analyzer/src/summary2/linked_library_context.dart';
 import 'package:analyzer/src/summary2/reference.dart';
-import 'package:analyzer/src/summary2/type_builder.dart';
+import 'package:meta/meta.dart';
 
 /// The context of a unit - the context of the bundle, and the unit tokens.
 class LinkedUnitContext {
-  final LinkedBundleContext bundleContext;
   final LinkedLibraryContext libraryContext;
   final int indexInLibrary;
   final String partUriStr;
   final String uriStr;
   final Reference reference;
   final bool isSynthetic;
-  final LinkedNodeUnit data;
+  final CompilationUnit unit;
+  final UnitReader unitReader;
 
-  /// Optional informative data for the unit.
-  List<UnlinkedInformativeData> informativeData;
-
-  AstBinaryReader _astReader;
-
-  CompilationUnit _unit;
   bool _hasDirectivesRead = false;
 
-  /// Mapping from identifiers to synthetic type parameters.
-  ///
-  /// Synthetic type parameters are added when [readType] begins reading a
-  /// [FunctionType], and removed when reading is done.
-  final Map<int, TypeParameterElementImpl> _typeParameters = {};
+  LinkedUnitContext(this.libraryContext, this.indexInLibrary, this.partUriStr,
+      this.uriStr, this.reference, this.isSynthetic,
+      {@required this.unit, @required this.unitReader});
 
-  int _nextSyntheticTypeParameterId = 0x10000;
-
-  LinkedUnitContext(
-      this.bundleContext,
-      this.libraryContext,
-      this.indexInLibrary,
-      this.partUriStr,
-      this.uriStr,
-      this.reference,
-      this.isSynthetic,
-      this.data,
-      {CompilationUnit unit}) {
-    _astReader = AstBinaryReader(this);
-    _astReader.isLazy = unit == null;
-
-    _unit = unit;
-    _hasDirectivesRead = _unit != null;
-  }
+  LinkedElementFactory get elementFactory => libraryContext.elementFactory;
 
   bool get hasPartOfDirective {
     for (var directive in unit_withDirectives.directives) {
@@ -76,7 +44,7 @@
   }
 
   /// Return `true` if this unit is a part of a bundle that is being linked.
-  bool get isLinking => bundleContext.isLinking;
+  bool get isLinking => unitReader == null;
 
   TypeProvider get typeProvider {
     var libraryReference = libraryContext.reference;
@@ -84,37 +52,43 @@
     return libraryElement.typeProvider;
   }
 
-  CompilationUnit get unit => _unit;
-
   CompilationUnit get unit_withDeclarations {
-    _ensureUnitWithDeclarations();
-    return _unit;
+    unitReader?.readDeclarations();
+    return unit;
   }
 
+  /// Ensure that [unit] has directives ready (because we are linking,
+  /// and so always have full AST, or, if we are reading, we make sure
+  /// that we have them read).
   CompilationUnit get unit_withDirectives {
-    _ensureUnitWithDeclarations();
-    if (!_hasDirectivesRead) {
-      var directiveDataList = data.node.compilationUnit_directives;
-      for (var i = 0; i < directiveDataList.length; ++i) {
-        var directiveData = directiveDataList[i];
-        _unit.directives[i] = _astReader.readNode(directiveData);
-      }
+    if (unitReader != null && !_hasDirectivesRead) {
       _hasDirectivesRead = true;
+      unitReader.readDirectives();
+      var libraryElement = libraryContext.reference.element;
+      for (var directive in unit.directives) {
+        if (directive is ExportDirective) {
+          if (directive.element == null) {
+            ExportElementImpl.forLinkedNode(libraryElement, directive);
+          }
+        } else if (directive is ImportDirective) {
+          if (directive.element == null) {
+            ImportElementImpl.forLinkedNode(libraryElement, directive);
+          }
+        }
+      }
     }
-    return _unit;
+    return unit;
   }
 
-  Comment createComment(LinkedNode data) {
-    var informativeData = getInformativeData(data);
-    var tokenStringList = informativeData?.documentationComment_tokens;
-    if (tokenStringList == null || tokenStringList.isEmpty) {
-      return null;
+  /// TODO(scheglov) make it static
+  void applyResolution(AstNode node) {
+    if (node is VariableDeclaration) {
+      node = node.parent.parent;
     }
-
-    var tokens = tokenStringList
-        .map((lexeme) => TokenFactory.tokenFromString(lexeme))
-        .toList();
-    return astFactory.documentationComment(tokens);
+    if (node is HasAstLinkedContext) {
+      var astLinkedContext = (node as HasAstLinkedContext).linkedContext;
+      astLinkedContext?.applyResolution(this);
+    }
   }
 
   void createGenericFunctionTypeElement(int id, GenericFunctionTypeImpl node) {
@@ -128,133 +102,72 @@
     node.declaredElement = element;
   }
 
-  /// Return the [LibraryElement] referenced in the [node].
-  LibraryElement directiveLibrary(UriBasedDirective node) {
-    var uriStr = LazyDirective.getSelectedUri(node);
-    if (uriStr == null) return null;
-    return bundleContext.elementFactory.libraryOfUri(uriStr);
-  }
-
   int getCodeLength(AstNode node) {
-    if (node is ClassDeclaration) {
-      return LazyClassDeclaration.getCodeLength(this, node);
-    } else if (node is ClassTypeAlias) {
-      return LazyClassTypeAlias.getCodeLength(this, node);
-    } else if (node is CompilationUnit) {
+    if (node is HasAstLinkedContext) {
+      var linked = (node as HasAstLinkedContext).linkedContext;
+      return linked != null ? linked.codeLength : node.length;
+    }
+
+    if (node is CompilationUnitImpl) {
+      var data = node.summaryData as SummaryDataForCompilationUnit;
       if (data != null) {
-        return getInformativeData(data.node)?.codeLength ?? 0;
+        return data.codeLength;
       } else {
         return node.length;
       }
-    } else if (node is ConstructorDeclaration) {
-      return LazyConstructorDeclaration.getCodeLength(this, node);
     } else if (node is EnumConstantDeclaration) {
-      return LazyEnumConstantDeclaration.getCodeLength(this, node);
-    } else if (node is EnumDeclaration) {
-      return LazyEnumDeclaration.getCodeLength(this, node);
-    } else if (node is ExtensionDeclaration) {
-      return LazyExtensionDeclaration.getCodeLength(this, node);
+      return node.length;
     } else if (node is FormalParameter) {
-      return LazyFormalParameter.getCodeLength(this, node);
-    } else if (node is FunctionDeclaration) {
-      return LazyFunctionDeclaration.getCodeLength(this, node);
-    } else if (node is FunctionTypeAliasImpl) {
-      return LazyFunctionTypeAlias.getCodeLength(this, node);
-    } else if (node is GenericTypeAlias) {
-      return LazyGenericTypeAlias.getCodeLength(this, node);
-    } else if (node is MethodDeclaration) {
-      return LazyMethodDeclaration.getCodeLength(this, node);
-    } else if (node is MixinDeclaration) {
-      return LazyMixinDeclaration.getCodeLength(this, node);
+      return node.length;
     } else if (node is TypeParameter) {
-      return LazyTypeParameter.getCodeLength(this, node);
+      return node.length;
     } else if (node is VariableDeclaration) {
-      return LazyVariableDeclaration.getCodeLength(this, node);
+      var parent2 = node.parent.parent;
+      var linked = (parent2 as HasAstLinkedContext).linkedContext;
+      return linked.getVariableDeclarationCodeLength(node);
     }
     throw UnimplementedError('${node.runtimeType}');
   }
 
   int getCodeOffset(AstNode node) {
-    if (node is ClassDeclaration) {
-      return LazyClassDeclaration.getCodeOffset(this, node);
-    } else if (node is ClassTypeAlias) {
-      return LazyClassTypeAlias.getCodeOffset(this, node);
-    } else if (node is CompilationUnit) {
+    if (node is HasAstLinkedContext) {
+      var linked = (node as HasAstLinkedContext).linkedContext;
+      return linked != null ? linked.codeOffset : node.offset;
+    }
+
+    if (node is CompilationUnit) {
       return 0;
-    } else if (node is ConstructorDeclaration) {
-      return LazyConstructorDeclaration.getCodeOffset(this, node);
     } else if (node is EnumConstantDeclaration) {
-      return LazyEnumConstantDeclaration.getCodeOffset(this, node);
-    } else if (node is EnumDeclaration) {
-      return LazyEnumDeclaration.getCodeOffset(this, node);
-    } else if (node is ExtensionDeclaration) {
-      return LazyExtensionDeclaration.getCodeOffset(this, node);
+      return node.offset;
     } else if (node is FormalParameter) {
-      return LazyFormalParameter.getCodeOffset(this, node);
-    } else if (node is FunctionDeclaration) {
-      return LazyFunctionDeclaration.getCodeOffset(this, node);
-    } else if (node is FunctionTypeAliasImpl) {
-      return LazyFunctionTypeAlias.getCodeOffset(this, node);
-    } else if (node is GenericTypeAlias) {
-      return LazyGenericTypeAlias.getCodeOffset(this, node);
-    } else if (node is MethodDeclaration) {
-      return LazyMethodDeclaration.getCodeOffset(this, node);
-    } else if (node is MixinDeclaration) {
-      return LazyMixinDeclaration.getCodeOffset(this, node);
+      return node.offset;
     } else if (node is TypeParameter) {
-      return LazyTypeParameter.getCodeOffset(this, node);
+      return node.offset;
     } else if (node is VariableDeclaration) {
-      return LazyVariableDeclaration.getCodeOffset(this, node);
+      var parent2 = node.parent.parent;
+      var linked = (parent2 as HasAstLinkedContext).linkedContext;
+      return linked.getVariableDeclarationCodeOffset(node);
     }
     throw UnimplementedError('${node.runtimeType}');
   }
 
-  int getCombinatorEnd(ShowCombinator node) {
-    return LazyCombinator.getEnd(this, node);
-  }
-
   List<ConstructorInitializer> getConstructorInitializers(
     ConstructorDeclaration node,
   ) {
-    LazyConstructorDeclaration.readInitializers(_astReader, node);
     return node.initializers;
   }
 
   ConstructorName getConstructorRedirected(ConstructorDeclaration node) {
-    LazyConstructorDeclaration.readRedirectedConstructor(_astReader, node);
     return node.redirectedConstructor;
   }
 
-  Iterable<ConstructorDeclaration> getConstructors(AstNode node) sync* {
+  List<ConstructorDeclaration> getConstructors(AstNode node) {
     if (node is ClassOrMixinDeclaration) {
-      var members = _getClassOrExtensionOrMixinMembers(node);
-      for (var member in members) {
-        if (member is ConstructorDeclaration) {
-          yield member;
-        }
-      }
+      return _getClassOrExtensionOrMixinMembers(node)
+          .whereType<ConstructorDeclaration>()
+          .toList();
     }
-  }
-
-  DartType getDefaultType(TypeParameter node) {
-    var type = LazyTypeParameter.getDefaultType(_astReader, node);
-    if (type is TypeBuilder) {
-      type = (type as TypeBuilder).build();
-      LazyAst.setDefaultType(node, type);
-    }
-    return type;
-  }
-
-  String getDefaultValueCode(AstNode node) {
-    if (node is DefaultFormalParameter) {
-      return LazyFormalParameter.getDefaultValueCode(this, node);
-    }
-    return null;
-  }
-
-  String getDefaultValueCodeData(LinkedNode data) {
-    var informativeData = getInformativeData(data);
-    return informativeData?.defaultFormalParameter_defaultValueCode;
+    return const <ConstructorDeclaration>[];
   }
 
   int getDirectiveOffset(Directive node) {
@@ -262,72 +175,22 @@
   }
 
   Comment getDocumentationComment(AstNode node) {
-    if (node is ClassDeclaration) {
-      LazyClassDeclaration.readDocumentationComment(this, node);
-      return node.documentationComment;
-    } else if (node is ClassTypeAlias) {
-      LazyClassTypeAlias.readDocumentationComment(this, node);
-      return node.documentationComment;
-    } else if (node is ConstructorDeclaration) {
-      LazyConstructorDeclaration.readDocumentationComment(this, node);
-      return node.documentationComment;
-    } else if (node is EnumConstantDeclaration) {
-      LazyEnumConstantDeclaration.readDocumentationComment(this, node);
-      return node.documentationComment;
-    } else if (node is EnumDeclaration) {
-      LazyEnumDeclaration.readDocumentationComment(this, node);
-      return node.documentationComment;
-    } else if (node is ExtensionDeclaration) {
-      LazyExtensionDeclaration.readDocumentationComment(this, node);
-      return node.documentationComment;
-    } else if (node is FunctionDeclaration) {
-      LazyFunctionDeclaration.readDocumentationComment(this, node);
-      return node.documentationComment;
-    } else if (node is FunctionTypeAlias) {
-      LazyFunctionTypeAlias.readDocumentationComment(this, node);
-      return node.documentationComment;
-    } else if (node is GenericTypeAlias) {
-      LazyGenericTypeAlias.readDocumentationComment(this, node);
-      return node.documentationComment;
-    } else if (node is MethodDeclaration) {
-      LazyMethodDeclaration.readDocumentationComment(this, node);
-      return node.documentationComment;
-    } else if (node is MixinDeclaration) {
-      LazyMixinDeclaration.readDocumentationComment(this, node);
-      return node.documentationComment;
+    if (node is HasAstLinkedContext) {
+      var linkedContext = (node as HasAstLinkedContext).linkedContext;
+      linkedContext?.readDocumentationComment();
+      return (node as AnnotatedNode).documentationComment;
     } else if (node is VariableDeclaration) {
-      var parent2 = node.parent.parent;
-      if (parent2 is FieldDeclaration) {
-        LazyFieldDeclaration.readDocumentationComment(this, parent2);
-        return parent2.documentationComment;
-      } else if (parent2 is TopLevelVariableDeclaration) {
-        LazyTopLevelVariableDeclaration.readDocumentationComment(
-          this,
-          parent2,
-        );
-        return parent2.documentationComment;
-      } else {
-        throw UnimplementedError('${parent2.runtimeType}');
-      }
+      return getDocumentationComment(node.parent.parent);
     } else {
       throw UnimplementedError('${node.runtimeType}');
     }
   }
 
+  /// TODO(scheglov) inline
   List<EnumConstantDeclaration> getEnumConstants(EnumDeclaration node) {
-    LazyEnumDeclaration.readConstants(_astReader, node);
     return node.constants;
   }
 
-  TypeAnnotation getExtendedType(ExtensionDeclaration node) {
-    LazyExtensionDeclaration.readExtendedType(_astReader, node);
-    return node.extendedType;
-  }
-
-  String getExtensionRefName(ExtensionDeclaration node) {
-    return LazyExtensionDeclaration.get(node).refName;
-  }
-
   String getFieldFormalParameterName(AstNode node) {
     if (node is DefaultFormalParameter) {
       return getFieldFormalParameterName(node.parameter);
@@ -338,125 +201,97 @@
     }
   }
 
-  Iterable<VariableDeclaration> getFields(CompilationUnitMember node) sync* {
+  List<VariableDeclaration> getFields(CompilationUnitMember node) {
+    var fields = <VariableDeclaration>[];
     var members = _getClassOrExtensionOrMixinMembers(node);
     for (var member in members) {
       if (member is FieldDeclaration) {
-        for (var field in member.fields.variables) {
-          yield field;
-        }
+        fields.addAll(member.fields.variables);
       }
     }
+    return fields;
+  }
+
+  String getFormalParameterName(FormalParameter node) {
+    if (node is DefaultFormalParameter) {
+      return getFormalParameterName(node.parameter);
+    } else if (node is NormalFormalParameter) {
+      return node.identifier?.name ?? '';
+    }
+    return null;
   }
 
   List<FormalParameter> getFormalParameters(AstNode node) {
     if (node is ConstructorDeclaration) {
-      LazyConstructorDeclaration.readFormalParameters(_astReader, node);
       return node.parameters.parameters;
     } else if (node is FunctionDeclaration) {
-      LazyFunctionDeclaration.readFunctionExpression(_astReader, node);
       return getFormalParameters(node.functionExpression);
     } else if (node is FunctionExpression) {
-      LazyFunctionExpression.readFormalParameters(_astReader, node);
       return node.parameters?.parameters;
     } else if (node is FormalParameter) {
       if (node is DefaultFormalParameter) {
         return getFormalParameters(node.parameter);
       } else if (node is FieldFormalParameter) {
-        LazyFormalParameter.readFormalParameters(_astReader, node);
         return node.parameters?.parameters;
       } else if (node is FunctionTypedFormalParameter) {
-        LazyFormalParameter.readFormalParameters(_astReader, node);
         return node.parameters.parameters;
       } else {
         return null;
       }
     } else if (node is FunctionTypeAlias) {
-      LazyFunctionTypeAlias.readFormalParameters(_astReader, node);
       return node.parameters.parameters;
     } else if (node is GenericFunctionType) {
       return node.parameters.parameters;
     } else if (node is MethodDeclaration) {
-      LazyMethodDeclaration.readFormalParameters(_astReader, node);
       return node.parameters?.parameters;
     } else {
       throw UnimplementedError('${node.runtimeType}');
     }
   }
 
-  Reference getGenericFunctionTypeReference(GenericFunctionType node) {
-    var containerRef = reference.getChild('@genericFunctionType');
-    var id = LazyAst.getGenericFunctionTypeId(node);
-    return containerRef.getChild('$id');
-  }
-
-  GenericFunctionType getGeneticTypeAliasFunction(GenericTypeAlias node) {
-    LazyGenericTypeAlias.readFunctionType(_astReader, node);
-    return node.functionType;
-  }
-
-  bool getHasTypedefSelfReference(AstNode node) {
-    if (node is FunctionTypeAlias) {
-      return LazyFunctionTypeAlias.getHasSelfReference(node);
-    } else if (node is GenericTypeAlias) {
-      return LazyGenericTypeAlias.getHasSelfReference(node);
-    }
-    return false;
-  }
-
   ImplementsClause getImplementsClause(AstNode node) {
     if (node is ClassDeclaration) {
-      LazyClassDeclaration.readImplementsClause(_astReader, node);
       return node.implementsClause;
     } else if (node is ClassTypeAlias) {
-      LazyClassTypeAlias.readImplementsClause(_astReader, node);
       return node.implementsClause;
     } else if (node is MixinDeclaration) {
-      LazyMixinDeclaration.readImplementsClause(_astReader, node);
       return node.implementsClause;
     } else {
       throw UnimplementedError('${node.runtimeType}');
     }
   }
 
-  UnlinkedInformativeData getInformativeData(LinkedNode data) {
-    if (informativeData == null) return null;
-
-    var id = data.informativeId;
-    if (id == 0) return null;
-
-    return informativeData[id - 1];
-  }
-
-  bool getInheritsCovariant(AstNode node) {
+  Expression getInitializer(AstNode node) {
     if (node is DefaultFormalParameter) {
-      return getInheritsCovariant(node.parameter);
-    } else if (node is FormalParameter) {
-      return LazyAst.getInheritsCovariant(node);
+      return node.defaultValue;
     } else if (node is VariableDeclaration) {
-      return LazyAst.getInheritsCovariant(node);
+      return node.initializer;
     } else {
       throw StateError('${node.runtimeType}');
     }
   }
 
   LibraryLanguageVersion getLanguageVersion(CompilationUnit node) {
-    return LazyCompilationUnit.getLanguageVersion(node);
+    return (node as CompilationUnitImpl).languageVersion;
   }
 
-  Comment getLibraryDocumentationComment(CompilationUnit unit) {
-    for (var directive in unit.directives) {
-      if (directive is LibraryDirective) {
+  Comment getLibraryDocumentationComment() {
+    for (var directive in unit_withDirectives.directives) {
+      if (directive is LibraryDirectiveImpl) {
+        var data = directive.summaryData as SummaryDataForLibraryDirective;
+        data.readDocumentationComment();
         return directive.documentationComment;
       }
     }
     return null;
   }
 
-  List<Annotation> getLibraryMetadata(CompilationUnit unit) {
+  List<Annotation> getLibraryMetadata() {
+    unit_withDirectives;
+    unitReader.applyDirectivesResolution(this);
     for (var directive in unit.directives) {
       if (directive is LibraryDirective) {
-        return getMetadata(directive);
+        return directive.metadata;
       }
     }
     return const <Annotation>[];
@@ -464,80 +299,57 @@
 
   List<Annotation> getMetadata(AstNode node) {
     if (node is ClassDeclaration) {
-      LazyClassDeclaration.readMetadata(_astReader, node);
       return node.metadata;
     } else if (node is ClassTypeAlias) {
-      LazyClassTypeAlias.readMetadata(_astReader, node);
       return node.metadata;
     } else if (node is CompilationUnit) {
-      assert(node == _unit);
+      assert(node == unit);
       if (indexInLibrary != 0) {
         return _getPartDirectiveAnnotation();
       } else {
         return const <Annotation>[];
       }
     } else if (node is ConstructorDeclaration) {
-      LazyConstructorDeclaration.readMetadata(_astReader, node);
       return node.metadata;
     } else if (node is DefaultFormalParameter) {
       return getMetadata(node.parameter);
     } else if (node is Directive) {
-      LazyDirective.readMetadata(_astReader, node);
       return node.metadata;
     } else if (node is EnumConstantDeclaration) {
-      LazyEnumConstantDeclaration.readMetadata(_astReader, node);
       return node.metadata;
     } else if (node is EnumDeclaration) {
-      LazyEnumDeclaration.readMetadata(_astReader, node);
       return node.metadata;
     } else if (node is ExtensionDeclaration) {
-      LazyExtensionDeclaration.readMetadata(_astReader, node);
       return node.metadata;
     } else if (node is FormalParameter) {
-      LazyFormalParameter.readMetadata(_astReader, node);
       return node.metadata;
     } else if (node is FunctionDeclaration) {
-      LazyFunctionDeclaration.readMetadata(_astReader, node);
       return node.metadata;
     } else if (node is FunctionTypeAlias) {
-      LazyFunctionTypeAlias.readMetadata(_astReader, node);
       return node.metadata;
     } else if (node is GenericTypeAlias) {
-      LazyGenericTypeAlias.readMetadata(_astReader, node);
       return node.metadata;
     } else if (node is MethodDeclaration) {
-      LazyMethodDeclaration.readMetadata(_astReader, node);
       return node.metadata;
     } else if (node is MixinDeclaration) {
-      LazyMixinDeclaration.readMetadata(_astReader, node);
       return node.metadata;
     } else if (node is TypeParameter) {
-      LazyTypeParameter.readMetadata(_astReader, node);
       return node.metadata;
     } else if (node is VariableDeclaration) {
       var parent2 = node.parent.parent;
       if (parent2 is FieldDeclaration) {
-        LazyFieldDeclaration.readMetadata(_astReader, parent2);
         return parent2.metadata;
       } else if (parent2 is TopLevelVariableDeclaration) {
-        LazyTopLevelVariableDeclaration.readMetadata(_astReader, parent2);
         return parent2.metadata;
       }
     }
     return const <Annotation>[];
   }
 
-  Iterable<MethodDeclaration> getMethods(CompilationUnitMember node) sync* {
-    var members = _getClassOrExtensionOrMixinMembers(node);
-    for (var member in members) {
-      if (member is MethodDeclaration) {
-        yield member;
-      }
-    }
-  }
-
-  List<String> getMixinSuperInvokedNames(MixinDeclaration node) {
-    return LazyMixinDeclaration.get(node).getSuperInvokedNames();
+  List<MethodDeclaration> getMethods(CompilationUnitMember node) {
+    return _getClassOrExtensionOrMixinMembers(node)
+        .whereType<MethodDeclaration>()
+        .toList();
   }
 
   int getNameOffset(AstNode node) {
@@ -565,87 +377,24 @@
     throw UnimplementedError('${node.runtimeType}');
   }
 
-  OnClause getOnClause(MixinDeclaration node) {
-    LazyMixinDeclaration.readOnClause(_astReader, node);
-    return node.onClause;
-  }
-
   /// Return the actual return type for the [node] - explicit or inferred.
   DartType getReturnType(AstNode node) {
-    if (node is FunctionDeclaration) {
-      return LazyFunctionDeclaration.getReturnType(_astReader, node);
-    } else if (node is FunctionTypeAlias) {
-      return LazyFunctionTypeAlias.getReturnType(_astReader, node);
-    } else if (node is GenericFunctionType) {
+    if (node is GenericFunctionType) {
       return node.returnType?.type ?? DynamicTypeImpl.instance;
-    } else if (node is MethodDeclaration) {
-      return LazyMethodDeclaration.getReturnType(_astReader, node);
-    } else {
-      throw UnimplementedError('${node.runtimeType}');
     }
-  }
-
-  TypeAnnotation getReturnTypeNode(AstNode node) {
-    if (node is FunctionTypeAlias) {
-      LazyFunctionTypeAlias.readReturnTypeNode(_astReader, node);
-      return node.returnType;
-    } else if (node is GenericFunctionType) {
-      return node.returnType;
-    } else if (node is FunctionDeclaration) {
-      LazyFunctionDeclaration.readReturnTypeNode(_astReader, node);
-      return node.returnType;
-    } else if (node is MethodDeclaration) {
-      LazyMethodDeclaration.readReturnTypeNode(_astReader, node);
-      return node.returnType;
-    } else {
-      throw UnimplementedError('${node.runtimeType}');
-    }
-  }
-
-  String getSelectedUri(UriBasedDirective node) {
-    return LazyDirective.getSelectedUri(node);
+    throw UnimplementedError('${node.runtimeType}');
   }
 
   TypeName getSuperclass(AstNode node) {
     if (node is ClassDeclaration) {
-      LazyClassDeclaration.readExtendsClause(_astReader, node);
       return node.extendsClause?.superclass;
     } else if (node is ClassTypeAlias) {
-      LazyClassTypeAlias.readSuperclass(_astReader, node);
       return node.superclass;
     } else {
       throw StateError('${node.runtimeType}');
     }
   }
 
-  /// Return the actual type for the [node] - explicit or inferred.
-  DartType getType(AstNode node) {
-    if (node is DefaultFormalParameter) {
-      return getType(node.parameter);
-    } else if (node is FormalParameter) {
-      return LazyFormalParameter.getType(_astReader, node);
-    } else if (node is VariableDeclaration) {
-      return LazyVariableDeclaration.getType(_astReader, node);
-    } else {
-      throw UnimplementedError('${node.runtimeType}');
-    }
-  }
-
-  TopLevelInferenceError getTypeInferenceError(AstNode node) {
-    if (node is MethodDeclaration) {
-      return LazyMethodDeclaration.getTypeInferenceError(node);
-    } else if (node is VariableDeclaration) {
-      return LazyVariableDeclaration.getTypeInferenceError(node);
-    } else {
-      return null;
-    }
-  }
-
-  TypeAnnotation getTypeParameterBound(TypeParameter node) {
-    LazyTypeParameter.readBound(_astReader, node);
-    return node.bound;
-  }
-
   TypeParameterList getTypeParameters2(AstNode node) {
     if (node is ClassDeclaration) {
       return node.typeParameters;
@@ -660,7 +409,6 @@
     } else if (node is FieldFormalParameter) {
       return node.typeParameters;
     } else if (node is FunctionDeclaration) {
-      LazyFunctionDeclaration.readFunctionExpression(_astReader, node);
       return getTypeParameters2(node.functionExpression);
     } else if (node is FunctionExpression) {
       return node.typeParameters;
@@ -683,36 +431,21 @@
     }
   }
 
-  Variance getTypeParameterVariance(TypeParameter node) {
-    return LazyAst.getVariance(node);
-  }
-
   WithClause getWithClause(AstNode node) {
     if (node is ClassDeclaration) {
-      LazyClassDeclaration.readWithClause(_astReader, node);
       return node.withClause;
     } else if (node is ClassTypeAlias) {
-      LazyClassTypeAlias.readWithClause(_astReader, node);
       return node.withClause;
     } else {
       throw UnimplementedError('${node.runtimeType}');
     }
   }
 
-  bool hasDefaultValue(FormalParameter node) {
-    if (node is DefaultFormalParameter) {
-      return LazyFormalParameter.hasDefaultValue(node);
-    }
-    return false;
-  }
-
   bool hasImplicitReturnType(AstNode node) {
     if (node is FunctionDeclaration) {
-      LazyFunctionDeclaration.readReturnTypeNode(_astReader, node);
       return node.returnType == null;
     }
     if (node is MethodDeclaration) {
-      LazyMethodDeclaration.readReturnTypeNode(_astReader, node);
       return node.returnType == null;
     }
     return false;
@@ -725,38 +458,26 @@
       return node.type == null;
     } else if (node is VariableDeclaration) {
       VariableDeclarationList parent = node.parent;
-      LazyVariableDeclarationList.readTypeNode(_astReader, parent);
       return parent.type == null;
     }
     return false;
   }
 
-  bool hasInitializer(VariableDeclaration node) {
-    return LazyVariableDeclaration.hasInitializer(node);
-  }
-
-  bool hasOperatorEqualParameterTypeFromObject(MethodDeclaration node) {
-    return LazyAst.hasOperatorEqualParameterTypeFromObject(node);
-  }
-
-  bool hasOverrideInferenceDone(AstNode node) {
-    // Only nodes in the libraries being linked might be not inferred yet.
-    if (_astReader.isLazy) return true;
-
-    return LazyAst.hasOverrideInferenceDone(node);
+  bool hasInitializer(VariableDeclarationImpl node) {
+    return node.initializer != null || node.hasInitializer;
   }
 
   bool isAbstract(AstNode node) {
     if (node is ClassDeclaration) {
-      return node.abstractKeyword != null;
+      return node.isAbstract;
     } else if (node is ClassTypeAlias) {
-      return node.abstractKeyword != null;
+      return node.isAbstract;
     } else if (node is ConstructorDeclaration) {
       return false;
     } else if (node is FunctionDeclaration) {
       return false;
     } else if (node is MethodDeclaration) {
-      return LazyMethodDeclaration.isAbstract(node);
+      return node.isAbstract;
     } else if (node is VariableDeclaration) {
       var parent = node.parent;
       if (parent is VariableDeclarationList) {
@@ -779,12 +500,11 @@
     if (node is ConstructorDeclaration) {
       return false;
     } else if (node is FunctionDeclaration) {
-      LazyFunctionDeclaration.readFunctionExpression(_astReader, node);
       return isAsynchronous(node.functionExpression);
     } else if (node is FunctionExpression) {
-      return LazyFunctionExpression.isAsynchronous(node);
+      return node.body.isAsynchronous;
     } else if (node is MethodDeclaration) {
-      return LazyMethodDeclaration.isAsynchronous(node);
+      return node.body.isAsynchronous;
     } else {
       throw UnimplementedError('${node.runtimeType}');
     }
@@ -859,12 +579,11 @@
     if (node is ConstructorDeclaration) {
       return false;
     } else if (node is FunctionDeclaration) {
-      LazyFunctionDeclaration.readFunctionExpression(_astReader, node);
       return isGenerator(node.functionExpression);
     } else if (node is FunctionExpression) {
-      return LazyFunctionExpression.isGenerator(node);
+      return node.body.isGenerator;
     } else if (node is MethodDeclaration) {
-      return LazyMethodDeclaration.isGenerator(node);
+      return node.body.isGenerator;
     } else {
       throw UnimplementedError('${node.runtimeType}');
     }
@@ -908,10 +627,6 @@
     }
   }
 
-  bool isSimplyBounded(AstNode node) {
-    return LazyAst.isSimplyBounded(node);
-  }
-
   bool isStatic(AstNode node) {
     if (node is FunctionDeclaration) {
       return true;
@@ -924,141 +639,6 @@
     throw UnimplementedError('${node.runtimeType}');
   }
 
-  Expression readInitializer(AstNode node) {
-    if (node is DefaultFormalParameter) {
-      LazyFormalParameter.readDefaultValue(_astReader, node);
-      return node.defaultValue;
-    } else if (node is VariableDeclaration) {
-      LazyVariableDeclaration.readInitializer(_astReader, node);
-      return node.initializer;
-    } else {
-      throw StateError('${node.runtimeType}');
-    }
-  }
-
-  DartType readType(LinkedNodeType linkedType) {
-    if (linkedType == null) return null;
-
-    var kind = linkedType.kind;
-    if (kind == LinkedNodeTypeKind.dynamic_) {
-      return DynamicTypeImpl.instance;
-    } else if (kind == LinkedNodeTypeKind.function) {
-      var typeParameterDataList = linkedType.functionTypeParameters;
-
-      var typeParametersLength = typeParameterDataList.length;
-      var typeParameters = List<TypeParameterElement>(typeParametersLength);
-      for (var i = 0; i < typeParametersLength; ++i) {
-        var typeParameterData = typeParameterDataList[i];
-        var element = TypeParameterElementImpl(typeParameterData.name, -1);
-        typeParameters[i] = element;
-        _typeParameters[_nextSyntheticTypeParameterId++] = element;
-      }
-
-      // Type parameters might use each other in bounds, including forward
-      // references. So, we read bounds after reading all type parameters.
-      for (var i = 0; i < typeParametersLength; ++i) {
-        var typeParameterData = typeParameterDataList[i];
-        TypeParameterElementImpl element = typeParameters[i];
-        element.bound = readType(typeParameterData.bound);
-      }
-
-      var returnType = readType(linkedType.functionReturnType);
-      var formalParameters = linkedType.functionFormalParameters.map((p) {
-        var type = readType(p.type);
-        var kind = _formalParameterKind(p.kind);
-        return ParameterElementImpl.synthetic(p.name, type, kind);
-      }).toList();
-
-      for (var i = 0; i < typeParametersLength; ++i) {
-        _typeParameters.remove(--_nextSyntheticTypeParameterId);
-      }
-
-      FunctionTypeAliasElement typedefElement;
-      List<DartType> typedefTypeArguments = const <DartType>[];
-      if (linkedType.functionTypedef != 0) {
-        typedefElement =
-            bundleContext.elementOfIndex(linkedType.functionTypedef);
-        typedefTypeArguments =
-            linkedType.functionTypedefTypeArguments.map(readType).toList();
-      }
-
-      var nullabilitySuffix = _nullabilitySuffix(linkedType.nullabilitySuffix);
-
-      return FunctionTypeImpl(
-        typeFormals: typeParameters,
-        parameters: formalParameters,
-        returnType: returnType,
-        nullabilitySuffix: nullabilitySuffix,
-        element: typedefElement,
-        typeArguments: typedefTypeArguments,
-      );
-    } else if (kind == LinkedNodeTypeKind.interface) {
-      var element = bundleContext.elementOfIndex(linkedType.interfaceClass);
-      var nullabilitySuffix = _nullabilitySuffix(linkedType.nullabilitySuffix);
-      return InterfaceTypeImpl(
-        element: element,
-        typeArguments: linkedType.interfaceTypeArguments.map(readType).toList(),
-        nullabilitySuffix: nullabilitySuffix,
-      );
-    } else if (kind == LinkedNodeTypeKind.never) {
-      var nullabilitySuffix = _nullabilitySuffix(linkedType.nullabilitySuffix);
-      return NeverTypeImpl.instance.withNullability(nullabilitySuffix);
-    } else if (kind == LinkedNodeTypeKind.typeParameter) {
-      TypeParameterElement element;
-      var id = linkedType.typeParameterId;
-      if (id != 0) {
-        element = _typeParameters[id];
-        assert(element != null);
-      } else {
-        var index = linkedType.typeParameterElement;
-        element = bundleContext.elementOfIndex(index);
-      }
-      var nullabilitySuffix = _nullabilitySuffix(linkedType.nullabilitySuffix);
-      return TypeParameterTypeImpl(
-        element: element,
-        nullabilitySuffix: nullabilitySuffix,
-      );
-    } else if (kind == LinkedNodeTypeKind.void_) {
-      return VoidTypeImpl.instance;
-    } else {
-      throw UnimplementedError('$kind');
-    }
-  }
-
-  void setInheritsCovariant(AstNode node, bool value) {
-    if (node is DefaultFormalParameter) {
-      setInheritsCovariant(node.parameter, value);
-    } else if (node is FormalParameter) {
-      LazyAst.setInheritsCovariant(node, value);
-    } else if (node is VariableDeclaration) {
-      LazyAst.setInheritsCovariant(node, value);
-    } else {
-      throw StateError('${node.runtimeType}');
-    }
-  }
-
-  void setOperatorEqualParameterTypeFromObject(AstNode node, bool value) {
-    LazyAst.setOperatorEqualParameterTypeFromObject(node, value);
-  }
-
-  void setOverrideInferenceDone(AstNode node) {
-    // TODO(scheglov) This assert fails, check how to avoid this.
-//    assert(!_astReader.isLazy);
-    LazyAst.setOverrideInferenceDone(node);
-  }
-
-  void setReturnType(AstNode node, DartType type) {
-    LazyAst.setReturnType(node, type);
-  }
-
-  void setVariableType(AstNode node, DartType type) {
-    if (node is DefaultFormalParameter) {
-      setVariableType(node.parameter, type);
-    } else {
-      LazyAst.setType(node, type);
-    }
-  }
-
   bool shouldBeConstFieldElement(AstNode node) {
     if (node is VariableDeclaration) {
       VariableDeclarationList variableList = node.parent;
@@ -1069,11 +649,19 @@
 
       if (variableList.isFinal) {
         var class_ = fieldDeclaration.parent;
-        if (class_ is ClassOrMixinDeclaration) {
-          for (var member in class_.members) {
-            if (member is ConstructorDeclaration &&
-                member.constKeyword != null) {
-              return true;
+        if (class_ is ClassDeclaration) {
+          var hasLinkedContext = class_ as HasAstLinkedContext;
+          var linkedContext = hasLinkedContext.linkedContext;
+          // TODO(scheglov) Get rid of this check, exists only for linking.
+          // Maybe we should pre-create all elements before linking.
+          if (linkedContext != null) {
+            return linkedContext.isClassWithConstConstructor;
+          } else {
+            for (var member in class_.members) {
+              if (member is ConstructorDeclaration &&
+                  member.constKeyword != null) {
+                return true;
+              }
             }
           }
         }
@@ -1082,85 +670,49 @@
     return false;
   }
 
-  Iterable<VariableDeclaration> topLevelVariables(CompilationUnit unit) sync* {
+  List<VariableDeclaration> topLevelVariables(CompilationUnit unit) {
+    var variables = <VariableDeclaration>[];
     for (var declaration in unit.declarations) {
       if (declaration is TopLevelVariableDeclaration) {
-        for (var variable in declaration.variables.variables) {
-          yield variable;
-        }
+        variables.addAll(declaration.variables.variables);
       }
     }
-  }
-
-  void _ensureUnitWithDeclarations() {
-    if (_unit == null) {
-      _unit = _astReader.readNode(data.node);
-
-      var informativeData = getInformativeData(data.node);
-      var lineStarts = informativeData?.compilationUnit_lineStarts ?? [];
-      if (lineStarts.isEmpty) {
-        lineStarts = [0];
-      }
-      _unit.lineInfo = LineInfo(lineStarts);
-    }
-  }
-
-  ParameterKind _formalParameterKind(LinkedNodeFormalParameterKind kind) {
-    if (kind == LinkedNodeFormalParameterKind.optionalNamed) {
-      return ParameterKind.NAMED;
-    } else if (kind == LinkedNodeFormalParameterKind.optionalPositional) {
-      return ParameterKind.POSITIONAL;
-    } else if (kind == LinkedNodeFormalParameterKind.requiredNamed) {
-      return ParameterKind.NAMED_REQUIRED;
-    }
-    return ParameterKind.REQUIRED;
+    return variables;
   }
 
   List<ClassMember> _getClassOrExtensionOrMixinMembers(
     CompilationUnitMember node,
   ) {
-    if (node is ClassDeclaration) {
-      LazyClassDeclaration.readMembers(_astReader, node);
-      return node.members;
-    } else if (node is ClassTypeAlias) {
-      return <ClassMember>[];
-    } else if (node is ExtensionDeclaration) {
-      LazyExtensionDeclaration.readMembers(_astReader, node);
-      return node.members;
-    } else if (node is MixinDeclaration) {
-      LazyMixinDeclaration.readMembers(_astReader, node);
-      return node.members;
+    var linkedContext = (node as HasAstLinkedContext).linkedContext;
+    if (linkedContext != null) {
+      return linkedContext.classMembers;
     } else {
-      throw StateError('${node.runtimeType}');
+      if (node is ClassDeclaration) {
+        return node.members;
+      } else if (node is ClassTypeAlias) {
+        return <ClassMember>[];
+      } else if (node is ExtensionDeclaration) {
+        return node.members;
+      } else if (node is MixinDeclaration) {
+        return node.members;
+      } else {
+        throw StateError('${node.runtimeType}');
+      }
     }
   }
 
   NodeList<Annotation> _getPartDirectiveAnnotation() {
     var definingContext = libraryContext.definingUnit;
-    var unit = definingContext.unit;
+    var definingUnit = definingContext.unit_withDirectives;
     var partDirectiveIndex = 0;
-    for (var directive in unit.directives) {
+    for (var directive in definingUnit.directives) {
       if (directive is PartDirective) {
         partDirectiveIndex++;
         if (partDirectiveIndex == indexInLibrary) {
-          LazyDirective.readMetadata(definingContext._astReader, directive);
           return directive.metadata;
         }
       }
     }
     throw StateError('Expected to find $indexInLibrary part directive.');
   }
-
-  static NullabilitySuffix _nullabilitySuffix(EntityRefNullabilitySuffix data) {
-    switch (data) {
-      case EntityRefNullabilitySuffix.starOrIrrelevant:
-        return NullabilitySuffix.star;
-      case EntityRefNullabilitySuffix.question:
-        return NullabilitySuffix.question;
-      case EntityRefNullabilitySuffix.none:
-        return NullabilitySuffix.none;
-      default:
-        throw StateError('$data');
-    }
-  }
 }
diff --git a/pkg/analyzer/lib/src/summary2/linking_bundle_context.dart b/pkg/analyzer/lib/src/summary2/linking_bundle_context.dart
deleted file mode 100644
index 81cf9c2b..0000000
--- a/pkg/analyzer/lib/src/summary2/linking_bundle_context.dart
+++ /dev/null
@@ -1,223 +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 'package:analyzer/dart/element/element.dart';
-import 'package:analyzer/dart/element/nullability_suffix.dart';
-import 'package:analyzer/dart/element/type.dart';
-import 'package:analyzer/src/dart/element/element.dart';
-import 'package:analyzer/src/dart/element/member.dart';
-import 'package:analyzer/src/dart/element/type_algebra.dart';
-import 'package:analyzer/src/summary/format.dart';
-import 'package:analyzer/src/summary/idl.dart';
-import 'package:analyzer/src/summary2/reference.dart';
-
-class LinkingBundleContext {
-  /// The `dynamic` class is declared in `dart:core`, but is not a class.
-  /// Also, it is static, so we cannot set `reference` for it.
-  /// So, we have to push it in a separate way.
-  final Reference dynamicReference;
-
-  /// References used in all libraries being linked.
-  /// Element references in nodes are indexes in this list.
-  final List<Reference> references = [null];
-
-  /// Data about [references].
-  final LinkedNodeReferencesBuilder referencesBuilder =
-      LinkedNodeReferencesBuilder(
-    parent: [0],
-    name: [''],
-  );
-
-  final Map<TypeParameterElement, int> _typeParameters = Map.identity();
-  int _nextSyntheticTypeParameterId = 0x10000;
-
-  LinkingBundleContext(this.dynamicReference);
-
-  /// We need indexes for references during linking, but once we are done,
-  /// we must clear indexes to make references ready for linking a next bundle.
-  void clearIndexes() {
-    for (var reference in references) {
-      if (reference != null) {
-        reference.index = null;
-      }
-    }
-  }
-
-  int idOfTypeParameter(TypeParameterElement element) {
-    return _typeParameters[element];
-  }
-
-  int indexOfElement(Element element) {
-    if (element == null) return 0;
-    if (element is MultiplyDefinedElement) return 0;
-    assert(element is! Member);
-
-    if (identical(element, DynamicElementImpl.instance)) {
-      return indexOfReference(dynamicReference);
-    }
-
-    var reference = (element as ElementImpl).reference;
-    return indexOfReference(reference);
-  }
-
-  int indexOfReference(Reference reference) {
-    if (reference == null) return 0;
-    if (reference.parent == null) return 0;
-    if (reference.index != null) return reference.index;
-
-    var parentIndex = indexOfReference(reference.parent);
-    referencesBuilder.parent.add(parentIndex);
-    referencesBuilder.name.add(reference.name);
-
-    reference.index = references.length;
-    references.add(reference);
-    return reference.index;
-  }
-
-  LinkedNodeTypeBuilder writeType(DartType type) {
-    if (type == null) return null;
-
-    if (type.isDynamic) {
-      return LinkedNodeTypeBuilder(
-        kind: LinkedNodeTypeKind.dynamic_,
-      );
-    } else if (type is FunctionType) {
-      return _writeFunctionType(type);
-    } else if (type is InterfaceType) {
-      return LinkedNodeTypeBuilder(
-        kind: LinkedNodeTypeKind.interface,
-        interfaceClass: indexOfElement(type.element),
-        interfaceTypeArguments: type.typeArguments.map(writeType).toList(),
-        nullabilitySuffix: _nullabilitySuffix(type),
-      );
-    } else if (type is NeverType) {
-      return LinkedNodeTypeBuilder(
-        kind: LinkedNodeTypeKind.never,
-        nullabilitySuffix: _nullabilitySuffix(type),
-      );
-    } else if (type is TypeParameterType) {
-      TypeParameterElementImpl element = type.element;
-      var id = _typeParameters[element];
-      if (id != null) {
-        return LinkedNodeTypeBuilder(
-          kind: LinkedNodeTypeKind.typeParameter,
-          nullabilitySuffix: _nullabilitySuffix(type),
-          typeParameterId: id,
-        );
-      } else {
-        var index = indexOfElement(element);
-        return LinkedNodeTypeBuilder(
-          kind: LinkedNodeTypeKind.typeParameter,
-          nullabilitySuffix: _nullabilitySuffix(type),
-          typeParameterElement: index,
-        );
-      }
-    } else if (type is VoidType) {
-      return LinkedNodeTypeBuilder(
-        kind: LinkedNodeTypeKind.void_,
-      );
-    } else {
-      throw UnimplementedError('(${type.runtimeType}) $type');
-    }
-  }
-
-  LinkedNodeFormalParameterKind _formalParameterKind(ParameterElement p) {
-    if (p.isRequiredPositional) {
-      return LinkedNodeFormalParameterKind.requiredPositional;
-    } else if (p.isRequiredNamed) {
-      return LinkedNodeFormalParameterKind.requiredNamed;
-    } else if (p.isOptionalPositional) {
-      return LinkedNodeFormalParameterKind.optionalPositional;
-    } else if (p.isOptionalNamed) {
-      return LinkedNodeFormalParameterKind.optionalNamed;
-    } else {
-      throw StateError('Unexpected parameter kind: $p');
-    }
-  }
-
-  FunctionType _toSyntheticFunctionType(FunctionType type) {
-    var typeParameters = type.typeFormals;
-
-    if (typeParameters.isEmpty) return type;
-
-    var onlySyntheticTypeParameters = typeParameters.every((e) {
-      return e is TypeParameterElementImpl && e.linkedNode == null;
-    });
-    if (onlySyntheticTypeParameters) return type;
-
-    var parameters = getFreshTypeParameters(typeParameters);
-    return parameters.applyToFunctionType(type);
-  }
-
-  LinkedNodeTypeBuilder _writeFunctionType(FunctionType type) {
-    type = _toSyntheticFunctionType(type);
-
-    var typeParameterBuilders = <LinkedNodeTypeTypeParameterBuilder>[];
-
-    var typeParameters = type.typeFormals;
-    for (var i = 0; i < typeParameters.length; ++i) {
-      var typeParameter = typeParameters[i];
-      _typeParameters[typeParameter] = _nextSyntheticTypeParameterId++;
-      typeParameterBuilders.add(
-        LinkedNodeTypeTypeParameterBuilder(name: typeParameter.name),
-      );
-    }
-
-    for (var i = 0; i < typeParameters.length; ++i) {
-      var typeParameter = typeParameters[i];
-      typeParameterBuilders[i].bound = writeType(typeParameter.bound);
-    }
-
-    Element typedefElement;
-    List<DartType> typedefTypeArguments = const <DartType>[];
-    if (type.element is FunctionTypeAliasElement) {
-      typedefElement = type.element;
-      typedefTypeArguments = type.typeArguments;
-    }
-    // TODO(scheglov) Cleanup to always use FunctionTypeAliasElement.
-    if (type.element is GenericFunctionTypeElement &&
-        type.element.enclosingElement is FunctionTypeAliasElement) {
-      typedefElement = type.element.enclosingElement;
-      typedefTypeArguments = type.typeArguments;
-    }
-
-    var result = LinkedNodeTypeBuilder(
-      kind: LinkedNodeTypeKind.function,
-      functionFormalParameters: type.parameters
-          .map((p) => LinkedNodeTypeFormalParameterBuilder(
-                kind: _formalParameterKind(p),
-                name: p.name,
-                type: writeType(p.type),
-              ))
-          .toList(),
-      functionReturnType: writeType(type.returnType),
-      functionTypeParameters: typeParameterBuilders,
-      functionTypedef: indexOfElement(typedefElement),
-      functionTypedefTypeArguments:
-          typedefTypeArguments.map(writeType).toList(),
-      nullabilitySuffix: _nullabilitySuffix(type),
-    );
-
-    for (var typeParameter in typeParameters) {
-      _typeParameters.remove(typeParameter);
-      --_nextSyntheticTypeParameterId;
-    }
-
-    return result;
-  }
-
-  static EntityRefNullabilitySuffix _nullabilitySuffix(DartType type) {
-    var nullabilitySuffix = type.nullabilitySuffix;
-    switch (nullabilitySuffix) {
-      case NullabilitySuffix.question:
-        return EntityRefNullabilitySuffix.question;
-      case NullabilitySuffix.star:
-        return EntityRefNullabilitySuffix.starOrIrrelevant;
-      case NullabilitySuffix.none:
-        return EntityRefNullabilitySuffix.none;
-      default:
-        throw StateError('$nullabilitySuffix');
-    }
-  }
-}
diff --git a/pkg/analyzer/lib/src/summary2/named_type_builder.dart b/pkg/analyzer/lib/src/summary2/named_type_builder.dart
index fdf0073..0b037aa 100644
--- a/pkg/analyzer/lib/src/summary2/named_type_builder.dart
+++ b/pkg/analyzer/lib/src/summary2/named_type_builder.dart
@@ -13,12 +13,13 @@
 import 'package:analyzer/src/dart/element/type_algebra.dart';
 import 'package:analyzer/src/dart/element/type_system.dart';
 import 'package:analyzer/src/dart/element/type_visitor.dart';
-import 'package:analyzer/src/summary2/lazy_ast.dart';
 import 'package:analyzer/src/summary2/type_builder.dart';
 import 'package:meta/meta.dart';
 
 /// The type builder for a [TypeName].
 class NamedTypeBuilder extends TypeBuilder {
+  /// TODO(scheglov) Replace with `DartType` in `TypeAliasElementImpl`.
+  static const _rawFunctionTypeKey = '_rawFunctionType';
   static DynamicTypeImpl get _dynamicType => DynamicTypeImpl.instance;
 
   /// The type system of the library with the type name.
@@ -266,11 +267,11 @@
     var typedefNode = element.linkedNode;
 
     // Break a possible recursion.
-    var existing = LazyAst.getRawFunctionType(typedefNode);
+    var existing = typedefNode.getProperty(_rawFunctionTypeKey) as DartType;
     if (existing != null) {
       return existing;
     } else {
-      LazyAst.setRawFunctionType(typedefNode, _dynamicType);
+      _setRawFunctionType(typedefNode, _dynamicType);
     }
 
     if (typedefNode is FunctionTypeAlias) {
@@ -280,12 +281,12 @@
         parameterList: typedefNode.parameters,
         hasQuestion: false,
       );
-      LazyAst.setRawFunctionType(typedefNode, result);
+      _setRawFunctionType(typedefNode, result);
       return result;
     } else if (typedefNode is GenericTypeAlias) {
       var functionNode = typedefNode.functionType;
       var functionType = _buildGenericFunctionType(functionNode);
-      LazyAst.setRawFunctionType(typedefNode, functionType);
+      _setRawFunctionType(typedefNode, functionType);
       return functionType;
     } else {
       throw StateError('(${element.runtimeType}) $element');
@@ -305,6 +306,10 @@
     return List<DartType>.filled(length, _dynamicType);
   }
 
+  static void _setRawFunctionType(AstNode node, DartType type) {
+    node.setProperty(_rawFunctionTypeKey, type);
+  }
+
   static List<TypeParameterElement> _typeParameters(TypeParameterList node) {
     if (node != null) {
       return node.typeParameters
diff --git a/pkg/analyzer/lib/src/summary2/package_bundle_format.dart b/pkg/analyzer/lib/src/summary2/package_bundle_format.dart
new file mode 100644
index 0000000..cb47263
--- /dev/null
+++ b/pkg/analyzer/lib/src/summary2/package_bundle_format.dart
@@ -0,0 +1,133 @@
+// Copyright (c) 2020, 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:typed_data';
+
+import 'package:analyzer/src/summary2/data_reader.dart';
+import 'package:analyzer/src/summary2/data_writer.dart';
+import 'package:meta/meta.dart';
+
+class PackageBundleBuilder {
+  final List<PackageBundleLibrary> _libraries = [];
+
+  void addLibrary(String uriStr, List<String> unitUriStrList) {
+    _libraries.add(
+      PackageBundleLibrary(
+        uriStr,
+        unitUriStrList.map((e) => PackageBundleUnit(e)).toList(),
+      ),
+    );
+  }
+
+  Uint8List finish({
+    @required Uint8List astBytes,
+    @required Uint8List resolutionBytes,
+    PackageBundleSdk sdk,
+  }) {
+    var byteSink = ByteSink();
+    var sink = BufferedSink(byteSink);
+
+    if (sdk != null) {
+      sink.writeByte(1);
+      sdk._write(sink);
+    } else {
+      sink.writeByte(0);
+    }
+
+    sink.writeList(_libraries, (PackageBundleLibrary library) {
+      sink.writeStringUtf8(library.uriStr);
+      sink.writeList(
+        library.units,
+        (PackageBundleUnit unit) => sink.writeStringUtf8(unit.uriStr),
+      );
+    });
+
+    sink.writeUint8List(astBytes);
+    sink.writeUint8List(resolutionBytes);
+
+    sink.flushAndDestroy();
+    return byteSink.builder.takeBytes();
+  }
+}
+
+@internal
+class PackageBundleLibrary {
+  final String uriStr;
+  final List<PackageBundleUnit> units;
+
+  PackageBundleLibrary(this.uriStr, this.units);
+}
+
+class PackageBundleReader {
+  final List<PackageBundleLibrary> libraries = [];
+  PackageBundleSdk _sdk;
+  Uint8List _astBytes;
+  Uint8List _resolutionBytes;
+
+  PackageBundleReader(Uint8List bytes) {
+    var reader = SummaryDataReader(bytes);
+
+    var hasSdk = reader.readByte() != 0;
+    if (hasSdk) {
+      _sdk = PackageBundleSdk._fromReader(reader);
+    }
+
+    var librariesLength = reader.readUInt30();
+    for (var i = 0; i < librariesLength; i++) {
+      var uriStr = reader.readStringUtf8();
+      var unitsLength = reader.readUInt30();
+      var units = List.generate(unitsLength, (_) {
+        var uriStr = reader.readStringUtf8();
+        return PackageBundleUnit(uriStr);
+      });
+      libraries.add(
+        PackageBundleLibrary(uriStr, units),
+      );
+    }
+
+    _astBytes = reader.readUint8List();
+    _resolutionBytes = reader.readUint8List();
+  }
+
+  Uint8List get astBytes => _astBytes;
+
+  Uint8List get resolutionBytes => _resolutionBytes;
+
+  PackageBundleSdk get sdk => _sdk;
+}
+
+class PackageBundleSdk {
+  final int languageVersionMajor;
+  final int languageVersionMinor;
+
+  /// The content of the `allowed_experiments.json` from SDK.
+  final String allowedExperimentsJson;
+
+  PackageBundleSdk({
+    @required this.languageVersionMajor,
+    @required this.languageVersionMinor,
+    @required this.allowedExperimentsJson,
+  });
+
+  factory PackageBundleSdk._fromReader(SummaryDataReader reader) {
+    return PackageBundleSdk(
+      languageVersionMajor: reader.readUInt30(),
+      languageVersionMinor: reader.readUInt30(),
+      allowedExperimentsJson: reader.readStringUtf8(),
+    );
+  }
+
+  void _write(BufferedSink sink) {
+    sink.writeUInt30(languageVersionMajor);
+    sink.writeUInt30(languageVersionMinor);
+    sink.writeStringUtf8(allowedExperimentsJson);
+  }
+}
+
+@internal
+class PackageBundleUnit {
+  final String uriStr;
+
+  PackageBundleUnit(this.uriStr);
+}
diff --git a/pkg/analyzer/lib/src/summary2/package_bundle_reader.dart b/pkg/analyzer/lib/src/summary2/package_bundle_reader.dart
index 234ee2c..ec05912 100644
--- a/pkg/analyzer/lib/src/summary2/package_bundle_reader.dart
+++ b/pkg/analyzer/lib/src/summary2/package_bundle_reader.dart
@@ -2,4 +2,10 @@
 // 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.
 
-export 'package:analyzer/src/summary/idl.dart' show PackageBundle;
+import 'dart:typed_data';
+
+import 'package:analyzer/src/summary2/package_bundle_format.dart';
+
+class PackageBundle extends PackageBundleReader {
+  PackageBundle.fromBuffer(Uint8List bytes) : super(bytes);
+}
diff --git a/pkg/analyzer/lib/src/summary2/reference.dart b/pkg/analyzer/lib/src/summary2/reference.dart
index 7eb7f68..6cd096b 100644
--- a/pkg/analyzer/lib/src/summary2/reference.dart
+++ b/pkg/analyzer/lib/src/summary2/reference.dart
@@ -32,6 +32,10 @@
   /// The simple name of the reference in its [parent].
   final String name;
 
+  /// The node accessor, used to read nodes lazily.
+  /// Or `null` if a named container.
+  ReferenceNodeAccessor nodeAccessor;
+
   /// The corresponding [AstNode], or `null` if a named container.
   AstNode node;
 
@@ -59,16 +63,28 @@
 
   bool get isClass => parent != null && parent.name == '@class';
 
+  bool get isConstructor => parent != null && parent.name == '@constructor';
+
   bool get isDynamic => name == 'dynamic' && parent?.name == 'dart:core';
 
   bool get isEnum => parent != null && parent.name == '@enum';
 
+  bool get isGetter => parent != null && parent.name == '@getter';
+
+  bool get isLibrary => parent != null && parent.isRoot;
+
+  bool get isParameter => parent != null && parent.name == '@parameter';
+
   bool get isPrefix => parent != null && parent.name == '@prefix';
 
+  bool get isRoot => parent == null;
+
   bool get isSetter => parent != null && parent.name == '@setter';
 
   bool get isTypeAlias => parent != null && parent.name == '@typeAlias';
 
+  bool get isUnit => parent != null && parent.name == '@unit';
+
   /// Return the child with the given name, or `null` if does not exist.
   Reference operator [](String name) {
     return _children != null ? _children[name] : null;
@@ -102,3 +118,13 @@
   @override
   String toString() => parent == null ? 'root' : '$parent::$name';
 }
+
+abstract class ReferenceNodeAccessor {
+  /// Return the node that corresponds to this [Reference], read it if not yet.
+  AstNode get node;
+
+  /// Fill [Reference.nodeAccessor] for children.
+  ///
+  /// TODO(scheglov) only class reader has a meaningful implementation.
+  void readIndex();
+}
diff --git a/pkg/analyzer/lib/src/summary2/reference_resolver.dart b/pkg/analyzer/lib/src/summary2/reference_resolver.dart
index 4083b28..d6f67f5 100644
--- a/pkg/analyzer/lib/src/summary2/reference_resolver.dart
+++ b/pkg/analyzer/lib/src/summary2/reference_resolver.dart
@@ -12,9 +12,7 @@
 import 'package:analyzer/src/dart/element/scope.dart';
 import 'package:analyzer/src/dart/element/type.dart';
 import 'package:analyzer/src/dart/element/type_system.dart';
-import 'package:analyzer/src/summary/idl.dart';
 import 'package:analyzer/src/summary2/function_type_builder.dart';
-import 'package:analyzer/src/summary2/lazy_ast.dart';
 import 'package:analyzer/src/summary2/linked_element_factory.dart';
 import 'package:analyzer/src/summary2/linking_node_scope.dart';
 import 'package:analyzer/src/summary2/named_type_builder.dart';
@@ -45,9 +43,6 @@
   Reference reference;
   Scope scope;
 
-  /// Is `true` if the current [ClassDeclaration] has a const constructor.
-  bool _hasConstConstructor = false;
-
   ReferenceResolver(
     this.nodesToBuildType,
     this.elementFactory,
@@ -72,7 +67,7 @@
     element.constructors; // create elements
     element.methods; // create elements
 
-    _createTypeParameterElements(node.typeParameters);
+    _createTypeParameterElements(element, node.typeParameters);
     scope = TypeParameterScope(scope, element.typeParameters);
 
     node.typeParameters?.accept(this);
@@ -83,14 +78,6 @@
     scope = ClassScope(scope, element);
     LinkingNodeContext(node, scope);
 
-    _hasConstConstructor = false;
-    for (var member in node.members) {
-      if (member is ConstructorDeclaration && member.constKeyword != null) {
-        _hasConstConstructor = true;
-        break;
-      }
-    }
-
     node.members.accept(this);
     nodesToBuildType.addDeclaration(node);
 
@@ -106,7 +93,7 @@
     var element = node.declaredElement as ClassElementImpl;
     reference = element.reference;
 
-    _createTypeParameterElements(node.typeParameters);
+    _createTypeParameterElements(element, node.typeParameters);
     scope = TypeParameterScope(scope, element.typeParameters);
     LinkingNodeContext(node, scope);
 
@@ -139,9 +126,6 @@
     LinkingNodeContext(node, scope);
 
     node.parameters?.accept(this);
-    node.initializers.accept(
-      _SetGenericFunctionTypeIdVisitor(this),
-    );
 
     scope = outerScope;
     reference = outerReference;
@@ -150,9 +134,6 @@
   @override
   void visitDefaultFormalParameter(DefaultFormalParameter node) {
     node.parameter.accept(this);
-    node.defaultValue?.accept(
-      _SetGenericFunctionTypeIdVisitor(this),
-    );
   }
 
   @override
@@ -174,7 +155,7 @@
     var element = node.declaredElement as ExtensionElementImpl;
     reference = element.reference;
 
-    _createTypeParameterElements(node.typeParameters);
+    _createTypeParameterElements(element, node.typeParameters);
     scope = TypeParameterScope(scope, element.typeParameters);
 
     node.typeParameters?.accept(this);
@@ -193,12 +174,6 @@
   @override
   void visitFieldDeclaration(FieldDeclaration node) {
     node.fields.accept(this);
-
-    if (node.fields.isConst ||
-        !node.isStatic && node.fields.isFinal && _hasConstConstructor) {
-      var visitor = _SetGenericFunctionTypeIdVisitor(this);
-      node.fields.variables.accept(visitor);
-    }
   }
 
   @override
@@ -210,7 +185,7 @@
     reference = element.reference;
     element.parameters; // create elements
 
-    _createTypeParameterElements(node.typeParameters);
+    _createTypeParameterElements(element, node.typeParameters);
     scope = TypeParameterScope(scope, element.typeParameters);
 
     node.type?.accept(this);
@@ -236,7 +211,10 @@
     reference = element.reference;
     element.parameters; // create elements
 
-    _createTypeParameterElements(node.functionExpression.typeParameters);
+    _createTypeParameterElements(
+      element,
+      node.functionExpression.typeParameters,
+    );
     scope = TypeParameterScope(outerScope, element.typeParameters);
     LinkingNodeContext(node, scope);
 
@@ -262,7 +240,7 @@
     var element = node.declaredElement as FunctionTypeAliasElementImpl;
     reference = element.reference;
 
-    _createTypeParameterElements(node.typeParameters);
+    _createTypeParameterElements(element, node.typeParameters);
     scope = TypeParameterScope(outerScope, element.typeParameters);
 
     node.returnType?.accept(this);
@@ -288,7 +266,7 @@
     reference = element.reference;
     element.parameters; // create elements
 
-    _createTypeParameterElements(node.typeParameters);
+    _createTypeParameterElements(element, node.typeParameters);
     scope = TypeParameterScope(scope, element.typeParameters);
 
     node.returnType?.accept(this);
@@ -305,9 +283,8 @@
     var outerScope = scope;
     var outerReference = reference;
 
+    // TODO(scheglov) remove reference
     var id = _nextGenericFunctionTypeId++;
-    LazyAst.setGenericFunctionTypeId(node, id);
-
     var containerRef = unitReference.getChild('@genericFunctionType');
     reference = containerRef.getChild('$id');
 
@@ -316,10 +293,9 @@
       reference,
       node,
     );
-    (node as GenericFunctionTypeImpl).declaredElement = element;
     element.parameters; // create elements
 
-    _createTypeParameterElements(node.typeParameters);
+    _createTypeParameterElements(element, node.typeParameters);
     scope = TypeParameterScope(outerScope, element.typeParameters);
 
     node.returnType?.accept(this);
@@ -343,13 +319,20 @@
     var element = node.declaredElement as FunctionTypeAliasElementImpl;
     reference = element.reference;
 
-    _createTypeParameterElements(node.typeParameters);
+    _createTypeParameterElements(element, node.typeParameters);
     scope = TypeParameterScope(outerScope, element.typeParameters);
 
     node.typeParameters?.accept(this);
     node.type?.accept(this);
     nodesToBuildType.addDeclaration(node);
 
+    var aliasedType = node.type;
+    if (aliasedType is GenericFunctionTypeImpl) {
+      element.encloseElement(
+        aliasedType.declaredElement as GenericFunctionTypeElementImpl,
+      );
+    }
+
     scope = outerScope;
     reference = outerReference;
   }
@@ -368,7 +351,7 @@
     reference = element.reference;
     element.parameters; // create elements
 
-    _createTypeParameterElements(node.typeParameters);
+    _createTypeParameterElements(element, node.typeParameters);
 
     scope = TypeParameterScope(scope, element.typeParameters);
     LinkingNodeContext(node, scope);
@@ -393,7 +376,7 @@
     element.constructors; // create elements
     element.methods; // create elements
 
-    _createTypeParameterElements(node.typeParameters);
+    _createTypeParameterElements(element, node.typeParameters);
     scope = TypeParameterScope(scope, element.typeParameters);
 
     node.typeParameters?.accept(this);
@@ -424,10 +407,6 @@
   @override
   void visitTopLevelVariableDeclaration(TopLevelVariableDeclaration node) {
     node.variables.accept(this);
-    if (node.variables.isConst) {
-      var visitor = _SetGenericFunctionTypeIdVisitor(this);
-      node.variables.variables.accept(visitor);
-    }
   }
 
   @override
@@ -507,25 +486,25 @@
     node.mixinTypes.accept(this);
   }
 
-  void _createTypeParameterElement(TypeParameter node) {
-    var outerReference = this.reference;
-    var containerRef = outerReference.getChild('@typeParameter');
-    var reference = containerRef.getChild(node.name.name);
-    reference.node = node;
-
+  void _createTypeParameterElement(
+    ElementImpl enclosingElement,
+    TypeParameter node,
+  ) {
     var element = TypeParameterElementImpl.forLinkedNode(
-      outerReference.element,
-      reference,
+      enclosingElement,
       node,
     );
     node.name.staticElement = element;
   }
 
-  void _createTypeParameterElements(TypeParameterList typeParameterList) {
+  void _createTypeParameterElements(
+    ElementImpl enclosingElement,
+    TypeParameterList typeParameterList,
+  ) {
     if (typeParameterList == null) return;
 
     for (var typeParameter in typeParameterList.typeParameters) {
-      _createTypeParameterElement(typeParameter);
+      _createTypeParameterElement(enclosingElement, typeParameter);
     }
   }
 
@@ -541,20 +520,3 @@
     }
   }
 }
-
-/// For consistency we set identifiers for [GenericFunctionType]s in constant
-/// variable initializers, and instance final fields of classes with constant
-/// constructors.
-class _SetGenericFunctionTypeIdVisitor extends RecursiveAstVisitor<void> {
-  final ReferenceResolver resolver;
-
-  _SetGenericFunctionTypeIdVisitor(this.resolver);
-
-  @override
-  void visitGenericFunctionType(GenericFunctionType node) {
-    var id = resolver._nextGenericFunctionTypeId++;
-    LazyAst.setGenericFunctionTypeId(node, id);
-
-    super.visitGenericFunctionType(node);
-  }
-}
diff --git a/pkg/analyzer/lib/src/summary2/simply_bounded.dart b/pkg/analyzer/lib/src/summary2/simply_bounded.dart
index aa7d95f..8053556 100644
--- a/pkg/analyzer/lib/src/summary2/simply_bounded.dart
+++ b/pkg/analyzer/lib/src/summary2/simply_bounded.dart
@@ -7,18 +7,15 @@
 import 'package:analyzer/src/dart/element/element.dart';
 import 'package:analyzer/src/summary/link.dart' as graph
     show DependencyWalker, Node;
-import 'package:analyzer/src/summary2/lazy_ast.dart';
 import 'package:analyzer/src/summary2/library_builder.dart';
-import 'package:analyzer/src/summary2/linked_bundle_context.dart';
 
 /// Compute simple-boundedness for all classes and generic types aliases in
 /// the source [libraryBuilders].  There might be dependencies between them,
 /// so they all should be processed simultaneously.
 void computeSimplyBounded(
-  LinkedBundleContext bundleContext,
   Iterable<LibraryBuilder> libraryBuilders,
 ) {
-  var walker = SimplyBoundedDependencyWalker(bundleContext);
+  var walker = SimplyBoundedDependencyWalker();
   var nodes = <SimplyBoundedNode>[];
   for (var libraryBuilder in libraryBuilders) {
     for (var unit in libraryBuilder.element.units) {
@@ -41,18 +38,30 @@
     if (!node.isEvaluated) {
       walker.walk(node);
     }
-    LazyAst.setSimplyBounded(node._node, node.isSimplyBounded);
+    var node2 = node._node;
+    if (node2 is ClassOrMixinDeclaration) {
+      var element = node2.declaredElement as ClassElementImpl;
+      element.isSimplyBounded = node.isSimplyBounded;
+    } else if (node2 is ClassTypeAlias) {
+      var element = node2.declaredElement as ClassElementImpl;
+      element.isSimplyBounded = node.isSimplyBounded;
+    } else if (node2 is GenericTypeAlias) {
+      var element = node2.declaredElement as FunctionTypeAliasElementImpl;
+      element.isSimplyBounded = node.isSimplyBounded;
+    } else if (node2 is FunctionTypeAlias) {
+      var element = node2.declaredElement as FunctionTypeAliasElementImpl;
+      element.isSimplyBounded = node.isSimplyBounded;
+    } else {
+      throw UnimplementedError('${node2.runtimeType}');
+    }
   }
 }
 
 /// The graph walker for evaluating whether types are simply bounded.
 class SimplyBoundedDependencyWalker
     extends graph.DependencyWalker<SimplyBoundedNode> {
-  final LinkedBundleContext bundleContext;
   final Map<Element, SimplyBoundedNode> nodeMap = Map.identity();
 
-  SimplyBoundedDependencyWalker(this.bundleContext);
-
   @override
   void evaluate(SimplyBoundedNode v) {
     v._evaluate();
diff --git a/pkg/analyzer/lib/src/summary2/tokens_context.dart b/pkg/analyzer/lib/src/summary2/tokens_context.dart
index ab8ad17..95fd9c6 100644
--- a/pkg/analyzer/lib/src/summary2/tokens_context.dart
+++ b/pkg/analyzer/lib/src/summary2/tokens_context.dart
@@ -3,7 +3,7 @@
 // BSD-style license that can be found in the LICENSE file.
 
 import 'package:analyzer/dart/ast/token.dart';
-import 'package:analyzer/src/summary/idl.dart';
+import 'package:analyzer/src/summary2/unlinked_token_type.dart';
 
 /// The context for reading tokens.
 class TokensContext {
diff --git a/pkg/analyzer/lib/src/summary2/tokens_writer.dart b/pkg/analyzer/lib/src/summary2/tokens_writer.dart
index 3e8bc74..e115141 100644
--- a/pkg/analyzer/lib/src/summary2/tokens_writer.dart
+++ b/pkg/analyzer/lib/src/summary2/tokens_writer.dart
@@ -3,7 +3,7 @@
 // BSD-style license that can be found in the LICENSE file.
 
 import 'package:analyzer/dart/ast/token.dart';
-import 'package:analyzer/src/summary/idl.dart';
+import 'package:analyzer/src/summary2/unlinked_token_type.dart';
 
 class TokensWriter {
   static UnlinkedTokenType astToBinaryTokenType(TokenType type) {
diff --git a/pkg/analyzer/lib/src/summary2/top_level_inference.dart b/pkg/analyzer/lib/src/summary2/top_level_inference.dart
index 6639055..cafca28 100644
--- a/pkg/analyzer/lib/src/summary2/top_level_inference.dart
+++ b/pkg/analyzer/lib/src/summary2/top_level_inference.dart
@@ -11,14 +11,12 @@
 import 'package:analyzer/src/dart/element/type.dart';
 import 'package:analyzer/src/dart/element/type_system.dart';
 import 'package:analyzer/src/generated/resolver.dart';
-import 'package:analyzer/src/summary/format.dart';
-import 'package:analyzer/src/summary/idl.dart';
 import 'package:analyzer/src/summary/link.dart' as graph
     show DependencyWalker, Node;
 import 'package:analyzer/src/summary2/ast_resolver.dart';
-import 'package:analyzer/src/summary2/lazy_ast.dart';
 import 'package:analyzer/src/summary2/link.dart';
 import 'package:analyzer/src/summary2/linking_node_scope.dart';
+import 'package:analyzer/src/task/inference_error.dart';
 import 'package:analyzer/src/task/strong_mode.dart';
 import 'package:meta/meta.dart';
 
@@ -159,7 +157,8 @@
             _parameters.add(parameterNode);
             _fields.add(fieldElement);
           } else {
-            LazyAst.setType(parameterNode, DynamicTypeImpl.instance);
+            (parameterElement as ParameterElementImpl).type =
+                DynamicTypeImpl.instance;
           }
         }
       }
@@ -179,7 +178,6 @@
     for (var i = 0; i < _parameters.length; ++i) {
       var parameter = _parameters[i];
       var type = _fields[i].type;
-      LazyAst.setType(parameter, type);
       (parameter.declaredElement as ParameterElementImpl).type = type;
     }
     isEvaluated = true;
@@ -189,7 +187,8 @@
   void markCircular(List<_InferenceNode> cycle) {
     for (var i = 0; i < _parameters.length; ++i) {
       var parameterNode = _parameters[i];
-      LazyAst.setType(parameterNode, DynamicTypeImpl.instance);
+      (parameterNode.declaredElement as ParameterElementImpl).type =
+          DynamicTypeImpl.instance;
     }
     isEvaluated = true;
   }
@@ -322,8 +321,11 @@
   void _addVariableNode(PropertyInducingElement element) {
     if (element.isSynthetic) return;
 
-    VariableDeclaration node = _getLinkedNode(element);
-    if (LazyAst.getType(node) != null) return;
+    var node = _getLinkedNode(element) as VariableDeclaration;
+    var variableList = node.parent as VariableDeclarationList;
+    if (variableList.type != null) {
+      return;
+    }
 
     if (node.initializer != null) {
       var inferenceNode =
@@ -332,7 +334,7 @@
       (element as PropertyInducingElementImpl).typeInference =
           _PropertyInducingElementTypeInference(inferenceNode);
     } else {
-      LazyAst.setType(node, DynamicTypeImpl.instance);
+      (element as PropertyInducingElementImpl).type = DynamicTypeImpl.instance;
     }
   }
 }
@@ -382,6 +384,10 @@
     return false;
   }
 
+  PropertyInducingElementImpl get _elementImpl {
+    return _node.declaredElement as PropertyInducingElementImpl;
+  }
+
   @override
   List<_InferenceNode> computeDependencies() {
     _resolveInitializer(forDependencies: true);
@@ -401,7 +407,7 @@
     for (var node in dependencies) {
       if (node is _VariableInferenceNode &&
           node.isImplicitlyTypedInstanceField) {
-        LazyAst.setType(_node, DynamicTypeImpl.instance);
+        _elementImpl.type = DynamicTypeImpl.instance;
         isEvaluated = true;
         return const <_InferenceNode>[];
       }
@@ -414,10 +420,10 @@
   void evaluate() {
     _resolveInitializer(forDependencies: false);
 
-    if (LazyAst.getType(_node) == null) {
+    if (!_elementImpl.hasTypeInferred) {
       var initializerType = _node.initializer.staticType;
       initializerType = _refineType(initializerType);
-      LazyAst.setType(_node, initializerType);
+      _elementImpl.type = initializerType;
     }
 
     isEvaluated = true;
@@ -425,19 +431,16 @@
 
   @override
   void markCircular(List<_InferenceNode> cycle) {
-    LazyAst.setType(_node, DynamicTypeImpl.instance);
+    _elementImpl.type = DynamicTypeImpl.instance;
 
     var cycleNames = <String>{};
     for (var inferenceNode in cycle) {
       cycleNames.add(inferenceNode.displayName);
     }
 
-    LazyAst.setTypeInferenceError(
-      _node,
-      TopLevelInferenceErrorBuilder(
-        kind: TopLevelInferenceErrorKind.dependencyCycle,
-        arguments: cycleNames.toList(),
-      ),
+    _elementImpl.typeInferenceError = TopLevelInferenceError(
+      kind: TopLevelInferenceErrorKind.dependencyCycle,
+      arguments: cycleNames.toList(),
     );
 
     isEvaluated = true;
diff --git a/pkg/analyzer/lib/src/summary2/type_alias.dart b/pkg/analyzer/lib/src/summary2/type_alias.dart
index 0ee7be4..5fe9298 100644
--- a/pkg/analyzer/lib/src/summary2/type_alias.dart
+++ b/pkg/analyzer/lib/src/summary2/type_alias.dart
@@ -8,7 +8,6 @@
 import 'package:analyzer/src/dart/ast/ast.dart';
 import 'package:analyzer/src/dart/element/element.dart';
 import 'package:analyzer/src/dart/element/type.dart';
-import 'package:analyzer/src/summary2/lazy_ast.dart';
 import 'package:analyzer/src/summary2/link.dart';
 
 class TypeAliasSelfReferenceFinder {
@@ -26,20 +25,16 @@
           if (node is FunctionTypeAlias) {
             var finder = _Finder(node);
             finder.functionTypeAlias(node);
-            LazyFunctionTypeAlias.setHasSelfReference(
-              node,
-              finder.hasSelfReference,
-            );
+            var element = node.declaredElement as FunctionTypeAliasElementImpl;
+            element.hasSelfReference = finder.hasSelfReference;
           } else if (node is GenericTypeAlias) {
             var finder = _Finder(node);
             finder.genericTypeAlias(node);
-            LazyGenericTypeAlias.setHasSelfReference(
-              node,
-              finder.hasSelfReference,
-            );
             if (finder.hasSelfReference) {
               _sanitizeGenericTypeAlias(node);
             }
+            var element = node.declaredElement as FunctionTypeAliasElementImpl;
+            element.hasSelfReference = finder.hasSelfReference;
           }
         }
       }
diff --git a/pkg/analyzer/lib/src/summary2/types_builder.dart b/pkg/analyzer/lib/src/summary2/types_builder.dart
index 249c4eb..9ad85a2 100644
--- a/pkg/analyzer/lib/src/summary2/types_builder.dart
+++ b/pkg/analyzer/lib/src/summary2/types_builder.dart
@@ -14,7 +14,6 @@
 import 'package:analyzer/src/dart/element/type.dart';
 import 'package:analyzer/src/dart/element/type_system.dart';
 import 'package:analyzer/src/summary2/default_types_builder.dart';
-import 'package:analyzer/src/summary2/lazy_ast.dart';
 import 'package:analyzer/src/summary2/type_builder.dart';
 
 class NodesToBuildType {
@@ -90,7 +89,8 @@
           returnType = _dynamicType;
         }
       }
-      LazyAst.setReturnType(node, returnType);
+      var element = node.declaredElement as ExecutableElementImpl;
+      element.returnType = returnType;
     } else if (node is FunctionTypeAlias) {
       _functionTypeAlias(node);
     } else if (node is FunctionTypedFormalParameter) {
@@ -108,16 +108,18 @@
           returnType = _dynamicType;
         }
       }
-      LazyAst.setReturnType(node, returnType);
+      var element = node.declaredElement as ExecutableElementImpl;
+      element.returnType = returnType;
     } else if (node is MixinDeclaration) {
       // TODO(scheglov) ???
     } else if (node is SimpleFormalParameter) {
-      LazyAst.setType(node, node.type?.type ?? _dynamicType);
+      var element = node.declaredElement as ParameterElementImpl;
+      element.type = node.type?.type ?? _dynamicType;
     } else if (node is VariableDeclarationList) {
       var type = node.type?.type;
       if (type != null) {
         for (var variable in node.variables) {
-          LazyAst.setType(variable, type);
+          (variable.declaredElement as VariableElementImpl).type = type;
         }
       }
     } else {
@@ -136,25 +138,24 @@
         parameterList,
         _nullability(node, node.question != null),
       );
-      LazyAst.setType(node, type);
+      var element = node.declaredElement as ParameterElementImpl;
+      element.type = type;
     } else {
-      LazyAst.setType(node, node.type?.type ?? _dynamicType);
+      var element = node.declaredElement as ParameterElementImpl;
+      element.type = node.type?.type ?? _dynamicType;
     }
   }
 
-  List<ParameterElementImpl> _formalParameters(FormalParameterList node) {
+  List<ParameterElement> _formalParameters(FormalParameterList node) {
     return node.parameters.asImpl.map((parameter) {
-      return ParameterElementImpl.synthetic(
-        parameter.identifier?.name ?? '',
-        _getType(parameter),
-        parameter.kind,
-      );
+      return parameter.declaredElement;
     }).toList();
   }
 
   void _functionTypeAlias(FunctionTypeAlias node) {
     var returnTypeNode = node.returnType;
-    LazyAst.setReturnType(node, returnTypeNode?.type ?? _dynamicType);
+    var element = node.declaredElement as FunctionTypeAliasElementImpl;
+    element.function.returnType = returnTypeNode?.type ?? _dynamicType;
   }
 
   void _functionTypedFormalParameter(FunctionTypedFormalParameter node) {
@@ -164,7 +165,8 @@
       node.parameters,
       _nullability(node, node.question != null),
     );
-    LazyAst.setType(node, type);
+    var element = node.declaredElement as ParameterElementImpl;
+    element.type = type;
   }
 
   bool _isNonNullableByDefault(AstNode node) {
@@ -193,13 +195,6 @@
         .map<TypeParameterElement>((p) => p.declaredElement)
         .toList();
   }
-
-  static DartType _getType(FormalParameter node) {
-    if (node is DefaultFormalParameter) {
-      return _getType(node.parameter);
-    }
-    return LazyAst.getType(node);
-  }
 }
 
 /// Performs mixins inference in a [ClassDeclaration].
diff --git a/pkg/analyzer/lib/src/summary2/unlinked_token_type.dart b/pkg/analyzer/lib/src/summary2/unlinked_token_type.dart
new file mode 100644
index 0000000..e11b1e0
--- /dev/null
+++ b/pkg/analyzer/lib/src/summary2/unlinked_token_type.dart
@@ -0,0 +1,146 @@
+/// Enum of token types, corresponding to AST token types.
+enum UnlinkedTokenType {
+  NOTHING,
+  ABSTRACT,
+  AMPERSAND,
+  AMPERSAND_AMPERSAND,
+  AMPERSAND_EQ,
+  AS,
+  ASSERT,
+  ASYNC,
+  AT,
+  AWAIT,
+  BACKPING,
+  BACKSLASH,
+  BANG,
+  BANG_EQ,
+  BANG_EQ_EQ,
+  BAR,
+  BAR_BAR,
+  BAR_EQ,
+  BREAK,
+  CARET,
+  CARET_EQ,
+  CASE,
+  CATCH,
+  CLASS,
+  CLOSE_CURLY_BRACKET,
+  CLOSE_PAREN,
+  CLOSE_SQUARE_BRACKET,
+  COLON,
+  COMMA,
+  CONST,
+  CONTINUE,
+  COVARIANT,
+  DEFAULT,
+  DEFERRED,
+  DO,
+  DOUBLE,
+  DYNAMIC,
+  ELSE,
+  ENUM,
+  EOF,
+  EQ,
+  EQ_EQ,
+  EQ_EQ_EQ,
+  EXPORT,
+  EXTENDS,
+  EXTERNAL,
+  FACTORY,
+  FALSE,
+  FINAL,
+  FINALLY,
+  FOR,
+  FUNCTION,
+  FUNCTION_KEYWORD,
+  GET,
+  GT,
+  GT_EQ,
+  GT_GT,
+  GT_GT_EQ,
+  GT_GT_GT,
+  GT_GT_GT_EQ,
+  HASH,
+  HEXADECIMAL,
+  HIDE,
+  IDENTIFIER,
+  IF,
+  IMPLEMENTS,
+  IMPORT,
+  IN,
+  INDEX,
+  INDEX_EQ,
+  INT,
+  INTERFACE,
+  IS,
+  LATE,
+  LIBRARY,
+  LT,
+  LT_EQ,
+  LT_LT,
+  LT_LT_EQ,
+  MINUS,
+  MINUS_EQ,
+  MINUS_MINUS,
+  MIXIN,
+  MULTI_LINE_COMMENT,
+  NATIVE,
+  NEW,
+  NULL,
+  OF,
+  ON,
+  OPEN_CURLY_BRACKET,
+  OPEN_PAREN,
+  OPEN_SQUARE_BRACKET,
+  OPERATOR,
+  PART,
+  PATCH,
+  PERCENT,
+  PERCENT_EQ,
+  PERIOD,
+  PERIOD_PERIOD,
+  PERIOD_PERIOD_PERIOD,
+  PERIOD_PERIOD_PERIOD_QUESTION,
+  PLUS,
+  PLUS_EQ,
+  PLUS_PLUS,
+  QUESTION,
+  QUESTION_PERIOD,
+  QUESTION_QUESTION,
+  QUESTION_QUESTION_EQ,
+  REQUIRED,
+  RETHROW,
+  RETURN,
+  SCRIPT_TAG,
+  SEMICOLON,
+  SET,
+  SHOW,
+  SINGLE_LINE_COMMENT,
+  SLASH,
+  SLASH_EQ,
+  SOURCE,
+  STAR,
+  STAR_EQ,
+  STATIC,
+  STRING,
+  STRING_INTERPOLATION_EXPRESSION,
+  STRING_INTERPOLATION_IDENTIFIER,
+  SUPER,
+  SWITCH,
+  SYNC,
+  THIS,
+  THROW,
+  TILDE,
+  TILDE_SLASH,
+  TILDE_SLASH_EQ,
+  TRUE,
+  TRY,
+  TYPEDEF,
+  VAR,
+  VOID,
+  WHILE,
+  WITH,
+  YIELD,
+  INOUT,
+  OUT,
+}
diff --git a/pkg/analyzer/lib/src/summary2/variance_builder.dart b/pkg/analyzer/lib/src/summary2/variance_builder.dart
index 51d0100..1ee6e95 100644
--- a/pkg/analyzer/lib/src/summary2/variance_builder.dart
+++ b/pkg/analyzer/lib/src/summary2/variance_builder.dart
@@ -9,7 +9,6 @@
 import 'package:analyzer/src/dart/element/element.dart';
 import 'package:analyzer/src/dart/resolver/variance.dart';
 import 'package:analyzer/src/summary2/function_type_builder.dart';
-import 'package:analyzer/src/summary2/lazy_ast.dart';
 import 'package:analyzer/src/summary2/link.dart';
 import 'package:analyzer/src/summary2/named_type_builder.dart';
 import 'package:meta/meta.dart';
@@ -149,7 +148,7 @@
     // Recursion detected, recover.
     if (_visit.contains(node)) {
       for (var parameter in parameterList.typeParameters) {
-        LazyAst.setVariance(parameter, Variance.covariant);
+        _setVariance(parameter, Variance.covariant);
       }
       return;
     }
@@ -171,7 +170,7 @@
             node.parameters,
           ),
         );
-        LazyAst.setVariance(parameter, variance);
+        _setVariance(parameter, variance);
       }
     } finally {
       _visit.remove(node);
@@ -198,7 +197,7 @@
     // Recursion detected, recover.
     if (_visit.contains(node)) {
       for (var parameter in parameterList.typeParameters) {
-        LazyAst.setVariance(parameter, Variance.covariant);
+        _setVariance(parameter, Variance.covariant);
       }
       return;
     }
@@ -213,7 +212,7 @@
     // Not a function type, recover.
     if (type == null) {
       for (var parameter in parameterList.typeParameters) {
-        LazyAst.setVariance(parameter, Variance.covariant);
+        _setVariance(parameter, Variance.covariant);
       }
     }
 
@@ -221,7 +220,7 @@
     try {
       for (var parameter in parameterList.typeParameters) {
         var variance = _compute(parameter.declaredElement, type);
-        LazyAst.setVariance(parameter, variance);
+        _setVariance(parameter, variance);
       }
     } finally {
       _visit.remove(node);
@@ -238,8 +237,13 @@
       var varianceKeyword = parameterImpl.varianceKeyword;
       if (varianceKeyword != null) {
         var variance = Variance.fromKeywordString(varianceKeyword.lexeme);
-        LazyAst.setVariance(parameter, variance);
+        _setVariance(parameter, variance);
       }
     }
   }
+
+  static void _setVariance(TypeParameter node, Variance variance) {
+    var element = node.declaredElement as TypeParameterElementImpl;
+    element.variance = variance;
+  }
 }
diff --git a/pkg/analyzer/lib/src/task/inference_error.dart b/pkg/analyzer/lib/src/task/inference_error.dart
new file mode 100644
index 0000000..4a686ff
--- /dev/null
+++ b/pkg/analyzer/lib/src/task/inference_error.dart
@@ -0,0 +1,29 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:meta/meta.dart';
+
+/// The top-level type inference error.
+class TopLevelInferenceError {
+  /// The kind of the error.
+  final TopLevelInferenceErrorKind kind;
+
+  /// The [kind] specific arguments.
+  final List<String> arguments;
+
+  TopLevelInferenceError({
+    @required this.kind,
+    @required this.arguments,
+  });
+}
+
+/// Enum used to indicate the kind of the error during top-level inference.
+enum TopLevelInferenceErrorKind {
+  none,
+  assignment,
+  instanceGetter,
+  dependencyCycle,
+  overrideConflictFieldType,
+  overrideNoCombinedSuperSignature,
+}
diff --git a/pkg/analyzer/lib/src/task/strong/checker.dart b/pkg/analyzer/lib/src/task/strong/checker.dart
index 7db1cf7..7e57d0c 100644
--- a/pkg/analyzer/lib/src/task/strong/checker.dart
+++ b/pkg/analyzer/lib/src/task/strong/checker.dart
@@ -20,7 +20,7 @@
 import 'package:analyzer/src/dart/element/type_system.dart';
 import 'package:analyzer/src/error/codes.dart'
     show CompileTimeErrorCode, StrongModeCode;
-import 'package:analyzer/src/summary/idl.dart';
+import 'package:analyzer/src/task/inference_error.dart';
 import 'package:meta/meta.dart';
 
 DartType _elementType(Element e) {
diff --git a/pkg/analyzer/lib/src/task/strong_mode.dart b/pkg/analyzer/lib/src/task/strong_mode.dart
index e6a5f7c..b303bf0 100644
--- a/pkg/analyzer/lib/src/task/strong_mode.dart
+++ b/pkg/analyzer/lib/src/task/strong_mode.dart
@@ -11,9 +11,7 @@
 import 'package:analyzer/src/dart/element/type.dart';
 import 'package:analyzer/src/dart/element/type_algebra.dart';
 import 'package:analyzer/src/dart/element/type_system.dart';
-import 'package:analyzer/src/summary/format.dart';
-import 'package:analyzer/src/summary/idl.dart';
-import 'package:analyzer/src/summary2/lazy_ast.dart';
+import 'package:analyzer/src/task/inference_error.dart';
 
 /// An object used to infer the type of instance fields and the return types of
 /// instance methods within a single compilation unit.
@@ -287,11 +285,9 @@
             type = typeSystem.nonNullifyLegacy(type);
             field.type = type;
           } else {
-            LazyAst.setTypeInferenceError(
-              field.linkedNode,
-              TopLevelInferenceErrorBuilder(
-                kind: TopLevelInferenceErrorKind.overrideConflictFieldType,
-              ),
+            field.typeInferenceError = TopLevelInferenceError(
+              kind: TopLevelInferenceErrorKind.overrideConflictFieldType,
+              arguments: const <String>[],
             );
           }
           return;
@@ -429,12 +425,9 @@
           }
         }
 
-        LazyAst.setTypeInferenceError(
-          element.linkedNode,
-          TopLevelInferenceErrorBuilder(
-            kind: TopLevelInferenceErrorKind.overrideNoCombinedSuperSignature,
-            arguments: [conflictExplanation],
-          ),
+        element.typeInferenceError = TopLevelInferenceError(
+          kind: TopLevelInferenceErrorKind.overrideNoCombinedSuperSignature,
+          arguments: [conflictExplanation],
         );
       }
     }
diff --git a/pkg/analyzer/test/generated/error_suppression_test.dart b/pkg/analyzer/test/generated/error_suppression_test.dart
index 7c6e3d9..07a3c23 100644
--- a/pkg/analyzer/test/generated/error_suppression_test.dart
+++ b/pkg/analyzer/test/generated/error_suppression_test.dart
@@ -81,7 +81,7 @@
 
   test_ignore_for_file_whitespace_variant() async {
     await assertNoErrorsInCode('''
-//ignore_for_file:   $ignoredCode , unnecessary_cast
+//ignore_for_file:   unused_element , unnecessary_cast
 int x = (0 as int);  //UNNECESSARY_CAST
 String _foo; //UNUSED_ELEMENT
 ''');
@@ -97,7 +97,7 @@
     await assertErrorsInCode('''
 //UNNECESSARY_CAST
 int x = (0 as int);
-// ignore: $ignoredCode
+// ignore: unused_element
 String _foo; //UNUSED_ELEMENT
 ''', [
       error(HintCode.UNNECESSARY_CAST, 28, 8),
diff --git a/pkg/analyzer/test/generated/invalid_code_test.dart b/pkg/analyzer/test/generated/invalid_code_test.dart
index a116216..6ae242a 100644
--- a/pkg/analyzer/test/generated/invalid_code_test.dart
+++ b/pkg/analyzer/test/generated/invalid_code_test.dart
@@ -196,11 +196,11 @@
 ''');
   }
 
-  @failingTest
   test_fuzz_12() async {
     // This code crashed with summary2 because usually AST reader is lazy,
     // so we did not read metadata `@b` for `c`. But default values must be
     // read fully.
+    // Fixed 2020-11-12.
     await _assertCanBeAnalyzed(r'''
 void f({a = [for (@b c = 0;;)]}) {}
 ''');
@@ -337,6 +337,12 @@
 ''');
   }
 
+  test_syntheticImportPrefix() async {
+    await _assertCanBeAnalyzed('''
+import 'dart:math' as;
+''');
+  }
+
   test_typeBeforeAnnotation() async {
     await _assertCanBeAnalyzed('''
 class A {
diff --git a/pkg/analyzer/test/src/dart/resolution/method_declaration_test.dart b/pkg/analyzer/test/src/dart/resolution/method_declaration_test.dart
index 9f18387..d7f3f98 100644
--- a/pkg/analyzer/test/src/dart/resolution/method_declaration_test.dart
+++ b/pkg/analyzer/test/src/dart/resolution/method_declaration_test.dart
@@ -13,7 +13,8 @@
 }
 
 @reflectiveTest
-class MethodDeclarationResolutionTest extends PubPackageResolutionTest {
+class MethodDeclarationResolutionTest extends PubPackageResolutionTest
+    with WithNullSafetyMixin {
   test_formalParameterScope_defaultValue() async {
     await assertNoErrorsInCode('''
 class A {
diff --git a/pkg/analyzer/test/src/diagnostics/assignment_of_do_not_store_test.dart b/pkg/analyzer/test/src/diagnostics/assignment_of_do_not_store_test.dart
index 664891c..e72359b 100644
--- a/pkg/analyzer/test/src/diagnostics/assignment_of_do_not_store_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/assignment_of_do_not_store_test.dart
@@ -238,7 +238,6 @@
   }
 
   test_topLevelVariable_libraryAnnotation() async {
-    testFilePath;
     newFile('$testPackageLibPath/library.dart', content: '''
 @doNotStore
 library lib;
diff --git a/pkg/analyzer/test/src/diagnostics/duplicate_field_formal_parameter_test.dart b/pkg/analyzer/test/src/diagnostics/duplicate_field_formal_parameter_test.dart
new file mode 100644
index 0000000..60961c5
--- /dev/null
+++ b/pkg/analyzer/test/src/diagnostics/duplicate_field_formal_parameter_test.dart
@@ -0,0 +1,62 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:analyzer/src/error/codes.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import '../dart/resolution/context_collection_resolution.dart';
+
+main() {
+  defineReflectiveSuite(() {
+    defineReflectiveTests(DuplicateFieldFormalParameterTest);
+  });
+}
+
+@reflectiveTest
+class DuplicateFieldFormalParameterTest extends PubPackageResolutionTest
+    with WithNullSafetyMixin {
+  test_optional_named() async {
+    await assertErrorsInCode(r'''
+class A {
+  int a;
+  A({this.a = 0, this.a = 1});
+}
+''', [
+      error(CompileTimeErrorCode.DUPLICATE_FIELD_FORMAL_PARAMETER, 41, 1),
+    ]);
+  }
+
+  test_optional_positional() async {
+    await assertErrorsInCode(r'''
+class A {
+  int a;
+  A([this.a = 0, this.a = 1]);
+}
+''', [
+      error(CompileTimeErrorCode.DUPLICATE_FIELD_FORMAL_PARAMETER, 41, 1),
+    ]);
+  }
+
+  test_required_named() async {
+    await assertErrorsInCode(r'''
+class A {
+  int a;
+  A({required this.a, required this.a});
+}
+''', [
+      error(CompileTimeErrorCode.DUPLICATE_FIELD_FORMAL_PARAMETER, 55, 1),
+    ]);
+  }
+
+  test_required_positional() async {
+    await assertErrorsInCode(r'''
+class A {
+  int a;
+  A(this.a, this.a);
+}
+''', [
+      error(CompileTimeErrorCode.DUPLICATE_FIELD_FORMAL_PARAMETER, 36, 1),
+    ]);
+  }
+}
diff --git a/pkg/analyzer/test/src/diagnostics/test_all.dart b/pkg/analyzer/test/src/diagnostics/test_all.dart
index 3d1585b..05d7fb0 100644
--- a/pkg/analyzer/test/src/diagnostics/test_all.dart
+++ b/pkg/analyzer/test/src/diagnostics/test_all.dart
@@ -126,6 +126,8 @@
 import 'deprecated_mixin_function_test.dart' as deprecated_mixin_function;
 import 'division_optimization_test.dart' as division_optimization;
 import 'duplicate_definition_test.dart' as duplicate_definition;
+import 'duplicate_field_formal_parameter_test.dart'
+    as duplicate_field_formal_parameter;
 import 'duplicate_hidden_name_test.dart' as duplicate_hidden_name;
 import 'duplicate_ignore_test.dart' as duplicate_ignore;
 import 'duplicate_import_test.dart' as duplicate_import;
@@ -742,6 +744,7 @@
     deprecated_mixin_function.main();
     division_optimization.main();
     duplicate_definition.main();
+    duplicate_field_formal_parameter.main();
     duplicate_hidden_name.main();
     duplicate_ignore.main();
     duplicate_import.main();
diff --git a/pkg/analyzer/test/src/pubspec/pubspec_validator_test.dart b/pkg/analyzer/test/src/pubspec/pubspec_validator_test.dart
index 8e8944a..e815d5e 100644
--- a/pkg/analyzer/test/src/pubspec/pubspec_validator_test.dart
+++ b/pkg/analyzer/test/src/pubspec/pubspec_validator_test.dart
@@ -505,6 +505,23 @@
 ''');
   }
 
+  test_pathNotPosix_error() {
+    newFolder('/foo');
+    newFile('/foo/pubspec.yaml', content: '''
+name: foo
+''');
+    assertErrors(r'''
+name: sample
+version: 0.1.0
+publish_to: none
+dependencies:
+  foo:
+    path: \foo
+''', [
+      PubspecWarningCode.PATH_NOT_POSIX,
+    ]);
+  }
+
   test_unnecessaryDevDependency_error() {
     assertErrors('''
 name: sample
diff --git a/pkg/analyzer/test/src/summary/element_text.dart b/pkg/analyzer/test/src/summary/element_text.dart
index 45d46f2..721eb3c 100644
--- a/pkg/analyzer/test/src/summary/element_text.dart
+++ b/pkg/analyzer/test/src/summary/element_text.dart
@@ -11,7 +11,7 @@
 import 'package:analyzer/src/dart/element/element.dart';
 import 'package:analyzer/src/dart/element/type.dart';
 import 'package:analyzer/src/generated/source.dart';
-import 'package:analyzer/src/summary/idl.dart';
+import 'package:analyzer/src/task/inference_error.dart';
 import 'package:meta/meta.dart';
 import 'package:test/test.dart';
 
@@ -465,6 +465,12 @@
       e.combinators.forEach(writeNamespaceCombinator);
 
       buffer.writeln(';');
+
+      if (withFullyResolvedAst) {
+        _withIndent(() {
+          _writeResolvedMetadata(e.metadata);
+        });
+      }
     }
   }
 
@@ -605,6 +611,10 @@
         writeList('(', ')', e.arguments.arguments, ', ', writeNode,
             includeEmpty: true);
       }
+    } else if (e is AsExpression) {
+      writeNode(e.expression);
+      buffer.write(' as ');
+      writeNode(e.type);
     } else if (e is AssertInitializer) {
       buffer.write('assert(');
       writeNode(e.condition);
@@ -669,6 +679,10 @@
       buffer.write(r'}');
     } else if (e is InterpolationString) {
       buffer.write(e.value.replaceAll("'", r"\'"));
+    } else if (e is IsExpression) {
+      writeNode(e.expression);
+      buffer.write(e.notOperator == null ? ' is ' : ' is! ');
+      writeNode(e.type);
     } else if (e is ListLiteral) {
       if (e.constKeyword != null) {
         buffer.write('const ');
@@ -1203,6 +1217,7 @@
         selfUriStr: selfUriStr,
         sink: buffer,
         indent: indent,
+        withNullability: annotateNullability,
       ),
     );
   }
diff --git a/pkg/analyzer/test/src/summary/resolved_ast_printer.dart b/pkg/analyzer/test/src/summary/resolved_ast_printer.dart
index af3b5a9..b8eaf24 100644
--- a/pkg/analyzer/test/src/summary/resolved_ast_printer.dart
+++ b/pkg/analyzer/test/src/summary/resolved_ast_printer.dart
@@ -34,6 +34,9 @@
   /// The optional provider for code lines, might be `null`.
   final CodeLinesProvider _codeLinesProvider;
 
+  /// If `true`, types should be printed with nullability suffixes.
+  final bool _withNullability;
+
   String _indent = '';
 
   ResolvedAstPrinter({
@@ -41,9 +44,11 @@
     @required StringSink sink,
     @required String indent,
     CodeLinesProvider codeLinesProvider,
+    bool withNullability = false,
   })  : _selfUriStr = selfUriStr,
         _sink = sink,
         _codeLinesProvider = codeLinesProvider,
+        _withNullability = withNullability,
         _indent = indent;
 
   @override
@@ -126,6 +131,10 @@
       properties.addNode('leftHandSide', node.leftHandSide);
       properties.addToken('operator', node.operator);
       properties.addNode('rightHandSide', node.rightHandSide);
+      properties.addElement('readElement', node.readElement);
+      properties.addType('readType', node.readType);
+      properties.addElement('writeElement', node.writeElement);
+      properties.addType('writeType', node.writeType);
       _addExpression(properties, node);
       _addMethodReferenceExpression(properties, node);
       _writeProperties(properties);
@@ -1030,6 +1039,12 @@
       var properties = _Properties();
       properties.addNode('operand', node.operand);
       properties.addToken('operator', node.operator);
+      if (node.operator.type.isIncrementOperator) {
+        properties.addElement('readElement', node.readElement);
+        properties.addType('readType', node.readType);
+        properties.addElement('writeElement', node.writeElement);
+        properties.addType('writeType', node.writeType);
+      }
       _addExpression(properties, node);
       _addMethodReferenceExpression(properties, node);
       _writeProperties(properties);
@@ -1058,6 +1073,12 @@
       var properties = _Properties();
       properties.addNode('operand', node.operand);
       properties.addToken('operator', node.operator);
+      if (node.operator.type.isIncrementOperator) {
+        properties.addElement('readElement', node.readElement);
+        properties.addType('readType', node.readType);
+        properties.addElement('writeElement', node.writeElement);
+        properties.addType('writeType', node.writeType);
+      }
       _addExpression(properties, node);
       _addMethodReferenceExpression(properties, node);
       _writeProperties(properties);
@@ -1666,7 +1687,7 @@
   }
 
   String _typeStr(DartType type) {
-    return type?.getDisplayString(withNullability: false);
+    return type?.getDisplayString(withNullability: _withNullability);
   }
 
   void _withIndent(void Function() f) {
diff --git a/pkg/analyzer/test/src/summary/resynthesize_ast2_test.dart b/pkg/analyzer/test/src/summary/resynthesize_ast2_test.dart
index 7b6be4a..7da23eb 100644
--- a/pkg/analyzer/test/src/summary/resynthesize_ast2_test.dart
+++ b/pkg/analyzer/test/src/summary/resynthesize_ast2_test.dart
@@ -2,6 +2,8 @@
 // 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:typed_data';
+
 import 'package:analyzer/dart/analysis/features.dart';
 import 'package:analyzer/dart/ast/ast.dart';
 import 'package:analyzer/dart/element/null_safety_understanding_flag.dart';
@@ -12,12 +14,11 @@
 import 'package:analyzer/src/dart/element/inheritance_manager3.dart';
 import 'package:analyzer/src/generated/engine.dart';
 import 'package:analyzer/src/generated/source.dart';
-import 'package:analyzer/src/summary/idl.dart';
-import 'package:analyzer/src/summary2/informative_data.dart';
+import 'package:analyzer/src/summary2/bundle_reader.dart';
 import 'package:analyzer/src/summary2/link.dart';
-import 'package:analyzer/src/summary2/linked_bundle_context.dart';
 import 'package:analyzer/src/summary2/linked_element_factory.dart';
 import 'package:analyzer/src/summary2/reference.dart';
+import 'package:meta/meta.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
 import 'resynthesize_common.dart';
@@ -33,15 +34,15 @@
 class ResynthesizeAst2Test extends ResynthesizeTestStrategyTwoPhase
     with ResynthesizeTestCases {
   /// The shared SDK bundle, computed once and shared among test invocations.
-  static LinkedNodeBundle _sdkBundleNnbd;
+  static _SdkBundle _sdkBundleNullSafe;
 
   /// The shared SDK bundle, computed once and shared among test invocations.
-  static LinkedNodeBundle _sdkBundleLegacy;
+  static _SdkBundle _sdkBundleLegacy;
 
-  LinkedNodeBundle get sdkBundle {
+  _SdkBundle get sdkBundle {
     if (featureSet.isEnabled(Feature.non_nullable)) {
-      if (_sdkBundleNnbd != null) {
-        return _sdkBundleNnbd;
+      if (_sdkBundleNullSafe != null) {
+        return _sdkBundleNullSafe;
       }
     } else {
       if (_sdkBundleLegacy != null) {
@@ -74,14 +75,18 @@
       Reference.root(),
     );
 
-    var sdkLinkResult = link(elementFactory, inputLibraries);
+    var sdkLinkResult = link(elementFactory, inputLibraries, true);
 
-    var bytes = sdkLinkResult.bundle.toBuffer();
-    var sdkBundle = LinkedNodeBundle.fromBuffer(bytes);
     if (featureSet.isEnabled(Feature.non_nullable)) {
-      return _sdkBundleNnbd = sdkBundle;
+      return _sdkBundleNullSafe = _SdkBundle(
+        astBytes: sdkLinkResult.astBytes,
+        resolutionBytes: sdkLinkResult.resolutionBytes,
+      );
     } else {
-      return _sdkBundleLegacy = sdkBundle;
+      return _sdkBundleLegacy = _SdkBundle(
+        astBytes: sdkLinkResult.astBytes,
+        resolutionBytes: sdkLinkResult.resolutionBytes,
+      );
     }
   }
 
@@ -107,39 +112,27 @@
       Reference.root(),
     );
     elementFactory.addBundle(
-      LinkedBundleContext(elementFactory, sdkBundle),
+      BundleReader(
+        elementFactory: elementFactory,
+        astBytes: sdkBundle.astBytes,
+        resolutionBytes: sdkBundle.resolutionBytes,
+      ),
     );
 
     var linkResult = NullSafetyUnderstandingFlag.enableNullSafetyTypes(
       () {
-        return link(
-          elementFactory,
-          inputLibraries,
-        );
+        return link(elementFactory, inputLibraries, true);
       },
     );
 
     elementFactory.addBundle(
-      LinkedBundleContext(elementFactory, linkResult.bundle),
+      BundleReader(
+        elementFactory: elementFactory,
+        astBytes: linkResult.astBytes,
+        resolutionBytes: linkResult.resolutionBytes,
+      ),
     );
 
-    // Set informative data.
-    for (var inputLibrary in inputLibraries) {
-      var libraryUriStr = '${inputLibrary.source.uri}';
-      for (var inputUnit in inputLibrary.units) {
-        var unitSource = inputUnit.source;
-        if (unitSource != null) {
-          var unitUriStr = '${unitSource.uri}';
-          var informativeData = createInformativeData(inputUnit.unit);
-          elementFactory.setInformativeData(
-            libraryUriStr,
-            unitUriStr,
-            informativeData,
-          );
-        }
-      }
-    }
-
     return elementFactory.libraryOfUri('${source.uri}');
   }
 
@@ -232,3 +225,13 @@
   @override
   noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
 }
+
+class _SdkBundle {
+  final Uint8List astBytes;
+  final Uint8List resolutionBytes;
+
+  _SdkBundle({
+    @required this.astBytes,
+    @required this.resolutionBytes,
+  });
+}
diff --git a/pkg/analyzer/test/src/summary/resynthesize_common.dart b/pkg/analyzer/test/src/summary/resynthesize_common.dart
index 701ebb6..157bfc3 100644
--- a/pkg/analyzer/test/src/summary/resynthesize_common.dart
+++ b/pkg/analyzer/test/src/summary/resynthesize_common.dart
@@ -2719,6 +2719,97 @@
     expect(library.isNonNullableByDefault, isTrue);
   }
 
+  test_const_asExpression() async {
+    featureSet = enableNnbd;
+    var library = await checkLibrary('''
+const num a = 0;
+const b = a as int;
+''');
+    checkElementText(library, '''
+const num a = 0;
+const int b =
+        a/*location: test.dart;a?*/ as
+        int/*location: dart:core;int*/;
+''');
+  }
+
+  test_const_assignmentExpression() async {
+    featureSet = enableNnbd;
+    var library = await checkLibrary(r'''
+const a = 0;
+const b = (a += 1);
+''');
+    checkElementText(
+      library,
+      r'''
+const int a;
+  constantInitializer
+    IntegerLiteral
+      literal: 0
+      staticType: int
+const int b;
+  constantInitializer
+    ParenthesizedExpression
+      expression: AssignmentExpression
+        leftHandSide: SimpleIdentifier
+          staticElement: <null>
+          staticType: null
+          token: a
+        operator: +=
+        readElement: self::@getter::a
+        readType: int
+        rightHandSide: IntegerLiteral
+          literal: 1
+          staticType: int
+        staticElement: dart:core::@class::num::@method::+
+        staticType: int
+        writeElement: self::@getter::a
+        writeType: dynamic
+      staticType: int
+''',
+      annotateNullability: true,
+      withFullyResolvedAst: true,
+    );
+  }
+
+  test_const_cascadeExpression() async {
+    featureSet = enableNnbd;
+    var library = await checkLibrary(r'''
+const a = 0..isEven..abs();
+''');
+    checkElementText(
+      library,
+      r'''
+const int a;
+  constantInitializer
+    CascadeExpression
+      cascadeSections
+        PropertyAccess
+          operator: ..
+          propertyName: SimpleIdentifier
+            staticElement: dart:core::@class::int::@getter::isEven
+            staticType: bool
+            token: isEven
+          staticType: bool
+        MethodInvocation
+          argumentList: ArgumentList
+          methodName: SimpleIdentifier
+            staticElement: dart:core::@class::int::@method::abs
+            staticType: int Function()
+            token: abs
+          operator: ..
+          staticInvokeType: null
+          staticType: int
+      staticType: int
+      target: IntegerLiteral
+        literal: 0
+        staticType: int
+''',
+      annotateNullability: true,
+      withFullyResolvedAst: true,
+    );
+  }
+
   test_const_classField() async {
     var library = await checkLibrary(r'''
 class C {
@@ -2791,6 +2882,50 @@
 ''');
   }
 
+  test_const_indexExpression() async {
+    featureSet = enableNnbd;
+    var library = await checkLibrary(r'''
+const a = [0];
+const b = 0;
+const c = a[b];
+''');
+    checkElementText(
+      library,
+      r'''
+const List<int> a;
+  constantInitializer
+    ListLiteral
+      elements
+        IntegerLiteral
+          literal: 0
+          staticType: int
+      staticType: List<int>
+const int b;
+  constantInitializer
+    IntegerLiteral
+      literal: 0
+      staticType: int
+const int c;
+  constantInitializer
+    IndexExpression
+      index: SimpleIdentifier
+        staticElement: self::@getter::b
+        staticType: int
+        token: b
+      staticElement: MethodMember
+        base: dart:core::@class::List::@method::[]
+        substitution: {E: int}
+      staticType: int
+      target: SimpleIdentifier
+        staticElement: self::@getter::a
+        staticType: List<int>
+        token: a
+''',
+      annotateNullability: true,
+      withFullyResolvedAst: true,
+    );
+  }
+
   test_const_inference_downward_list() async {
     var library = await checkLibrary('''
 class P<T> {
@@ -3253,6 +3388,20 @@
 ''');
   }
 
+  test_const_isExpression() async {
+    featureSet = enableNnbd;
+    var library = await checkLibrary('''
+const a = 0;
+const b = a is int;
+''');
+    checkElementText(library, '''
+const int a = 0;
+const bool b =
+        a/*location: test.dart;a?*/ is
+        int/*location: dart:core;int*/;
+''');
+  }
+
   test_const_length_ofClassConstField() async {
     var library = await checkLibrary(r'''
 class C {
@@ -3527,6 +3676,44 @@
         withTypes: true);
   }
 
+  test_const_methodInvocation() async {
+    featureSet = enableNnbd;
+    var library = await checkLibrary(r'''
+T f<T>(T a) => a;
+const b = f<int>(0);
+''');
+    checkElementText(
+      library,
+      r'''
+const int b;
+  constantInitializer
+    MethodInvocation
+      argumentList: ArgumentList
+        arguments
+          IntegerLiteral
+            literal: 0
+            staticType: int
+      methodName: SimpleIdentifier
+        staticElement: self::@function::f
+        staticType: T Function<T>(T)
+        token: f
+      staticInvokeType: null
+      staticType: int
+      typeArguments: TypeArgumentList
+        arguments
+          TypeName
+            name: SimpleIdentifier
+              staticElement: dart:core::@class::int
+              staticType: null
+              token: int
+            type: int
+T f(T a) {}
+''',
+      annotateNullability: true,
+      withFullyResolvedAst: true,
+    );
+  }
+
   test_const_parameterDefaultValue_initializingFormal_functionTyped() async {
     var library = await checkLibrary(r'''
 class C {
@@ -3598,6 +3785,104 @@
 ''');
   }
 
+  test_const_postfixExpression_increment() async {
+    featureSet = enableNnbd;
+    var library = await checkLibrary(r'''
+const a = 0;
+const b = a++;
+''');
+    checkElementText(
+      library,
+      r'''
+const int a;
+  constantInitializer
+    IntegerLiteral
+      literal: 0
+      staticType: int
+const int b;
+  constantInitializer
+    PostfixExpression
+      operand: SimpleIdentifier
+        staticElement: <null>
+        staticType: null
+        token: a
+      operator: ++
+      readElement: self::@getter::a
+      readType: int
+      staticElement: dart:core::@class::num::@method::+
+      staticType: int
+      writeElement: self::@getter::a
+      writeType: dynamic
+''',
+      annotateNullability: true,
+      withFullyResolvedAst: true,
+    );
+  }
+
+  test_const_postfixExpression_nullCheck() async {
+    featureSet = enableNnbd;
+    var library = await checkLibrary(r'''
+const int? a = 0;
+const b = a!;
+''');
+    checkElementText(
+      library,
+      r'''
+const int? a;
+  constantInitializer
+    IntegerLiteral
+      literal: 0
+      staticType: int
+const int b;
+  constantInitializer
+    PostfixExpression
+      operand: SimpleIdentifier
+        staticElement: self::@getter::a
+        staticType: int?
+        token: a
+      operator: !
+      staticElement: <null>
+      staticType: int
+''',
+      annotateNullability: true,
+      withFullyResolvedAst: true,
+    );
+  }
+
+  test_const_prefixExpression_increment() async {
+    featureSet = enableNnbd;
+    var library = await checkLibrary(r'''
+const a = 0;
+const b = ++a;
+''');
+    checkElementText(
+      library,
+      r'''
+const int a;
+  constantInitializer
+    IntegerLiteral
+      literal: 0
+      staticType: int
+const int b;
+  constantInitializer
+    PrefixExpression
+      operand: SimpleIdentifier
+        staticElement: <null>
+        staticType: null
+        token: a
+      operator: ++
+      readElement: self::@getter::a
+      readType: int
+      staticElement: dart:core::@class::num::@method::+
+      staticType: int
+      writeElement: self::@getter::a
+      writeType: dynamic
+''',
+      annotateNullability: true,
+      withFullyResolvedAst: true,
+    );
+  }
+
   test_const_reference_staticField() async {
     var library = await checkLibrary(r'''
 class C {
@@ -4131,9 +4416,11 @@
 const vNull = null;
 const vBoolFalse = false;
 const vBoolTrue = true;
-const vInt = 1;
+const vIntPositive = 1;
+const vIntNegative = -2;
 const vIntLong1 = 0x7FFFFFFFFFFFFFFF;
 const vIntLong2 = 0xFFFFFFFFFFFFFFFF;
+const vIntLong3 = 0x8000000000000000;
 const vDouble = 2.3;
 const vString = 'abc';
 const vStringConcat = 'aaa' 'bbb';
@@ -4144,9 +4431,11 @@
 const dynamic vNull = null;
 const bool vBoolFalse = false;
 const bool vBoolTrue = true;
-const int vInt = 1;
+const int vIntPositive = 1;
+const int vIntNegative = -2;
 const int vIntLong1 = 9223372036854775807;
 const int vIntLong2 = -1;
+const int vIntLong3 = -9223372036854775808;
 const double vDouble = 2.3;
 const String vString = 'abc';
 const String vStringConcat = 'aaabbb';
@@ -4517,6 +4806,35 @@
 ''');
   }
 
+  test_constructor_initializers_field_optionalPositionalParameter() async {
+    var library = await checkLibrary('''
+class A {
+  final int _f;
+  const A([int f = 0]) : _f = f;
+}
+''');
+    checkElementText(
+        library,
+        r'''
+class A {
+  final int _f;
+  const A([int f = 0]);
+    constantInitializers
+      ConstructorFieldInitializer
+        equals: =
+        expression: SimpleIdentifier
+          staticElement: f@41
+          staticType: int
+          token: f
+        fieldName: SimpleIdentifier
+          staticElement: self::@class::A::@field::_f
+          staticType: null
+          token: _f
+}
+''',
+        withFullyResolvedAst: true);
+  }
+
   test_constructor_initializers_field_withParameter() async {
     var library = await checkLibrary('''
 class C {
@@ -6355,6 +6673,46 @@
 ''');
   }
 
+  test_field_inferred_type_nonStatic_inherited_resolveInitializer() async {
+    var library = await checkLibrary(r'''
+const a = 0;
+abstract class A {
+  const A();
+  List<int> get f;
+}
+class B extends A {
+  const B();
+  final f = [a];
+}
+''');
+    checkElementText(
+        library,
+        r'''
+abstract class A {
+  List<int> get f;
+  const A();
+}
+class B extends A {
+  final List<int> f;
+    constantInitializer
+      ListLiteral
+        elements
+          SimpleIdentifier
+            staticElement: self::@getter::a
+            staticType: int
+            token: a
+        staticType: List<int>
+  const B();
+}
+const int a;
+  constantInitializer
+    IntegerLiteral
+      literal: 0
+      staticType: int
+''',
+        withFullyResolvedAst: true);
+  }
+
   test_field_inferred_type_static_implicit_initialized() async {
     var library = await checkLibrary('class C { static var v = 0; }');
     checkElementText(library, r'''
@@ -6747,6 +7105,38 @@
 ''');
   }
 
+  test_functionTypeAlias_enclosingElements() async {
+    var library = await checkLibrary(r'''
+typedef void F<T>(int a);
+''');
+    var unit = library.definingCompilationUnit;
+
+    var F = unit.functionTypeAliases[0];
+    expect(F.name, 'F');
+
+    var T = F.typeParameters[0];
+    expect(T.name, 'T');
+    expect(T.enclosingElement, same(F));
+
+    var function = F.function;
+    expect(function.enclosingElement, same(F));
+
+    var a = function.parameters[0];
+    expect(a.name, 'a');
+    expect(a.enclosingElement, same(function));
+  }
+
+  test_functionTypeAlias_type_element() async {
+    var library = await checkLibrary(r'''
+typedef T F<T>();
+F<int> a;
+''');
+    var unit = library.definingCompilationUnit;
+    var type = unit.topLevelVariables[0].type as FunctionType;
+    expect(type.element.enclosingElement, same(unit.functionTypeAliases[0]));
+    _assertTypeStrings(type.typeArguments, ['int*']);
+  }
+
   test_functionTypeAlias_typeParameters_variance_contravariant() async {
     var library = await checkLibrary(r'''
 typedef void F<T>(T a);
@@ -7050,6 +7440,31 @@
 ''');
   }
 
+  test_genericTypeAlias_enclosingElements() async {
+    var library = await checkLibrary(r'''
+typedef F<T> = void Function<U>(int a);
+''');
+    var unit = library.definingCompilationUnit;
+
+    var F = unit.functionTypeAliases[0];
+    expect(F.name, 'F');
+
+    var T = F.typeParameters[0];
+    expect(T.name, 'T');
+    expect(T.enclosingElement, same(F));
+
+    var function = F.function;
+    expect(function.enclosingElement, same(F));
+
+    var U = function.typeParameters[0];
+    expect(U.name, 'U');
+    expect(U.enclosingElement, same(function));
+
+    var a = function.parameters[0];
+    expect(a.name, 'a');
+    expect(a.enclosingElement, same(function));
+  }
+
   test_genericTypeAlias_recursive() async {
     var library = await checkLibrary('''
 typedef F<X extends F> = Function(F);
@@ -7511,6 +7926,16 @@
 ''');
   }
 
+  test_import_show_offsetEnd() async {
+    var library = await checkLibrary('''
+import "dart:math" show e, pi;
+''');
+    var import = library.imports[0];
+    var combinator = import.combinators[0] as ShowElementCombinator;
+    expect(combinator.offset, 19);
+    expect(combinator.end, 29);
+  }
+
   test_import_uri() async {
     allowMissingFiles = true;
     var library = await checkLibrary('''
@@ -9367,15 +9792,54 @@
   }
 
   test_metadata_importDirective() async {
-    addLibrarySource('/foo.dart', 'const b = null;');
+    addLibrarySource('/foo.dart', 'const b = 0;');
     var library = await checkLibrary('@a import "foo.dart"; const a = b;');
-    checkElementText(library, r'''
-@
-        a/*location: test.dart;a?*/
+    checkElementText(
+        library,
+        '''
 import 'foo.dart';
-const dynamic a =
-        b/*location: foo.dart;b?*/;
+  metadata
+    Annotation
+      element: self::@getter::a
+      name: SimpleIdentifier
+        staticElement: self::@getter::a
+        staticType: null
+        token: a
+const int a;
+  constantInitializer
+    SimpleIdentifier
+      staticElement: ${toUriStr('/foo.dart')}::@getter::b
+      staticType: int
+      token: b
+''',
+        withFullyResolvedAst: true);
+  }
+
+  test_metadata_importDirective_hasShow() async {
+    var library = await checkLibrary(r'''
+@a
+import "dart:math" show Random;
+
+const a = 0;
 ''');
+    checkElementText(
+        library,
+        r'''
+import 'dart:math' show Random;
+  metadata
+    Annotation
+      element: self::@getter::a
+      name: SimpleIdentifier
+        staticElement: self::@getter::a
+        staticType: null
+        token: a
+const int a;
+  constantInitializer
+    IntegerLiteral
+      literal: 0
+      staticType: int
+''',
+        withFullyResolvedAst: true);
   }
 
   test_metadata_invalid_classDeclaration() async {
@@ -9570,6 +10034,23 @@
 ''');
   }
 
+  test_metadata_partDirective2() async {
+    addSource('/a.dart', r'''
+part of 'test.dart';
+''');
+    addSource('/b.dart', r'''
+part of 'test.dart';
+''');
+    var library = await checkLibrary('''
+part 'a.dart';
+part 'b.dart';
+''');
+
+    // The difference with the test above is that we ask the part first.
+    // There was a bug that we were not loading library directives.
+    expect(library.parts[0].metadata, isEmpty);
+  }
+
   test_metadata_prefixed_variable() async {
     addLibrarySource('/a.dart', 'const b = null;');
     var library = await checkLibrary('import "a.dart" as a; @a.b class C {}');
@@ -12084,6 +12565,21 @@
 ''');
   }
 
+  test_variable_implicit() async {
+    var library = await checkLibrary('int get x => 0;');
+
+    // We intentionally don't check the text, because we want to test
+    // requesting individual elements, not all accessors/variables at once.
+    var getter = _elementOfDefiningUnit(library, '@getter', 'x')
+        as PropertyAccessorElementImpl;
+    var variable = getter.variable as TopLevelVariableElementImpl;
+    expect(variable, isNotNull);
+    expect(variable.isFinal, isTrue);
+    expect(variable.getter, same(getter));
+    expect('${variable.type}', 'int*');
+    expect(variable, same(_elementOfDefiningUnit(library, '@field', 'x')));
+  }
+
   test_variable_implicit_type() async {
     var library = await checkLibrary('var x;');
     checkElementText(library, r'''
@@ -12345,11 +12841,32 @@
     var typeStr = type.getDisplayString(withNullability: false);
     expect(typeStr, expected);
   }
+
+  void _assertTypeStrings(List<DartType> types, List<String> expected) {
+    var typeStringList = types.map((e) {
+      return e.getDisplayString(withNullability: true);
+    }).toList();
+    expect(typeStringList, expected);
+  }
+
+  Element _elementOfDefiningUnit(LibraryElementImpl library,
+      [String name1, String name2, String name3]) {
+    var unit = library.definingCompilationUnit as CompilationUnitElementImpl;
+    var reference = unit.reference;
+
+    [name1, name2, name3].takeWhile((e) => e != null).forEach((name) {
+      reference = reference.getChild(name);
+    });
+
+    var elementFactory = unit.linkedContext.elementFactory;
+    return elementFactory.elementOfReference(reference);
+  }
 }
 
 /// Mixin containing helper methods for testing summary resynthesis.  Intended
 /// to be applied to a class implementing [ResynthesizeTestStrategy].
-mixin ResynthesizeTestHelpers implements ResynthesizeTestStrategy {
+mixin ResynthesizeTestHelpers
+    implements ResynthesizeTestStrategy, ResourceProviderMixin {
   Future<LibraryElementImpl /*!*/ > checkLibrary(String text,
       {bool allowErrors = false, bool dumpSummaries = false}) async {
     throw 42;
diff --git a/pkg/analyzer/test/src/summary/test_strategies.dart b/pkg/analyzer/test/src/summary/test_strategies.dart
index 8ec7cc3..9fab0f2 100644
--- a/pkg/analyzer/test/src/summary/test_strategies.dart
+++ b/pkg/analyzer/test/src/summary/test_strategies.dart
@@ -15,7 +15,6 @@
 import 'package:analyzer/src/dart/scanner/scanner.dart';
 import 'package:analyzer/src/generated/parser.dart';
 import 'package:analyzer/src/generated/source.dart';
-import 'package:analyzer/src/summary/summarize_elements.dart';
 
 import 'resynthesize_common.dart';
 
@@ -88,6 +87,4 @@
   FeatureSet featureSet = FeatureSet.forTesting(sdkVersion: '2.7.0');
 
   final Set<Source> serializedSources = <Source>{};
-
-  PackageBundleAssembler bundleAssembler = PackageBundleAssembler();
 }
diff --git a/pkg/analyzer/test/src/task/options_test.dart b/pkg/analyzer/test/src/task/options_test.dart
index 9188c8c..73d9ac2 100644
--- a/pkg/analyzer/test/src/task/options_test.dart
+++ b/pkg/analyzer/test/src/task/options_test.dart
@@ -152,9 +152,6 @@
     var errorTypeMap = <Type, List<ErrorCode>>{};
     for (ErrorCode code in errorCodeValues) {
       Type type = code.runtimeType;
-      if (type == HintCodeWithUniqueName) {
-        type = HintCode;
-      }
       errorTypeMap.putIfAbsent(type, () => <ErrorCode>[]).add(code);
     }
 
diff --git a/pkg/analyzer_cli/lib/src/build_mode.dart b/pkg/analyzer_cli/lib/src/build_mode.dart
index 3098758..f022eeb 100644
--- a/pkg/analyzer_cli/lib/src/build_mode.dart
+++ b/pkg/analyzer_cli/lib/src/build_mode.dart
@@ -4,6 +4,7 @@
 
 import 'dart:io' as io;
 import 'dart:isolate';
+import 'dart:typed_data';
 
 import 'package:analyzer/dart/analysis/context_locator.dart' as api;
 import 'package:analyzer/dart/analysis/declared_variables.dart';
@@ -20,18 +21,17 @@
 import 'package:analyzer/src/dart/analysis/file_state.dart';
 import 'package:analyzer/src/dart/analysis/performance_logger.dart';
 import 'package:analyzer/src/dart/analysis/session.dart';
-import 'package:analyzer/src/generated/engine.dart' show AnalysisOptionsImpl;
 import 'package:analyzer/src/generated/engine.dart';
 import 'package:analyzer/src/generated/source.dart';
 import 'package:analyzer/src/generated/source_io.dart';
 import 'package:analyzer/src/source/source_resource.dart';
-import 'package:analyzer/src/summary/idl.dart';
 import 'package:analyzer/src/summary/package_bundle_reader.dart';
-import 'package:analyzer/src/summary/summarize_elements.dart';
 import 'package:analyzer/src/summary/summary_sdk.dart' show SummaryBasedDartSdk;
+import 'package:analyzer/src/summary2/bundle_reader.dart';
 import 'package:analyzer/src/summary2/link.dart' as summary2;
-import 'package:analyzer/src/summary2/linked_bundle_context.dart' as summary2;
 import 'package:analyzer/src/summary2/linked_element_factory.dart' as summary2;
+import 'package:analyzer/src/summary2/linked_library_context.dart' as summary2;
+import 'package:analyzer/src/summary2/package_bundle_format.dart';
 import 'package:analyzer/src/summary2/reference.dart' as summary2;
 import 'package:analyzer_cli/src/context_cache.dart';
 import 'package:analyzer_cli/src/driver.dart';
@@ -170,14 +170,11 @@
   AnalysisOptionsImpl analysisOptions;
   Map<Uri, File> uriToFileMap;
   final List<Source> explicitSources = <Source>[];
-  final List<PackageBundle> unlinkedBundles = <PackageBundle>[];
 
   SourceFactory sourceFactory;
   DeclaredVariables declaredVariables;
   AnalysisDriver analysisDriver;
 
-  PackageBundleAssembler assembler;
-
   summary2.LinkedElementFactory elementFactory;
 
   // May be null.
@@ -244,24 +241,20 @@
       }
 
       // Write summary.
-      assembler = PackageBundleAssembler();
       if (_shouldOutputSummary) {
         await logger.runAsync('Build and write output summary', () async {
           // Build and assemble linked libraries.
-          _computeLinkedLibraries2();
+          var bytes = _computeLinkedLibraries2();
 
           // Write the whole package bundle.
-          var bundle = assembler.assemble();
+          // TODO(scheglov) Remove support for `buildSummaryOutput`.
           if (options.buildSummaryOutput != null) {
             var file = io.File(options.buildSummaryOutput);
-            file.writeAsBytesSync(bundle.toBuffer(),
-                mode: io.FileMode.writeOnly);
+            file.writeAsBytesSync(bytes, mode: io.FileMode.writeOnly);
           }
           if (options.buildSummaryOutputSemantic != null) {
-            bundle.flushInformative();
             var file = io.File(options.buildSummaryOutputSemantic);
-            file.writeAsBytesSync(bundle.toBuffer(),
-                mode: io.FileMode.writeOnly);
+            file.writeAsBytesSync(bytes, mode: io.FileMode.writeOnly);
           }
         });
       } else {
@@ -290,9 +283,9 @@
   }
 
   /// Use [elementFactory] filled with input summaries, and link libraries
-  /// in [explicitSources] to produce linked libraries in [assembler].
-  void _computeLinkedLibraries2() {
-    logger.run('Link output summary2', () {
+  /// in [explicitSources] to produce linked summary bytes.
+  Uint8List _computeLinkedLibraries2() {
+    return logger.run('Link output summary2', () {
       var inputLibraries = <summary2.LinkInputLibrary>[];
 
       for (var librarySource in explicitSources) {
@@ -349,8 +342,19 @@
         );
       }
 
-      var linkResult = summary2.link(elementFactory, inputLibraries);
-      assembler.setBundle2(linkResult.bundle);
+      var linkResult = summary2.link(elementFactory, inputLibraries, false);
+
+      var bundleBuilder = PackageBundleBuilder();
+      for (var library in inputLibraries) {
+        bundleBuilder.addLibrary(
+          library.uriStr,
+          library.units.map((e) => e.uriStr).toList(),
+        );
+      }
+      return bundleBuilder.finish(
+        astBytes: linkResult.astBytes,
+        resolutionBytes: linkResult.resolutionBytes,
+      );
     });
   }
 
@@ -376,7 +380,7 @@
     summaryDataStore = SummaryDataStore(<String>[]);
 
     // Adds a bundle at `path` to `summaryDataStore`.
-    PackageBundle addBundle(String path) {
+    PackageBundleReader addBundle(String path) {
       var bundle = packageBundleProvider.get(path);
       summaryDataStore.addBundle(path, bundle);
       return bundle;
@@ -449,7 +453,11 @@
 
     for (var bundle in summaryDataStore.bundles) {
       elementFactory.addBundle(
-        summary2.LinkedBundleContext(elementFactory, bundle.bundle2),
+        BundleReader(
+          elementFactory: elementFactory,
+          astBytes: bundle.astBytes,
+          resolutionBytes: bundle.resolutionBytes,
+        ),
       );
     }
   }
@@ -567,9 +575,9 @@
   DirectPackageBundleProvider(this.resourceProvider);
 
   @override
-  PackageBundle get(String path) {
+  PackageBundleReader get(String path) {
     var bytes = io.File(path).readAsBytesSync();
-    return PackageBundle.fromBuffer(bytes);
+    return PackageBundleReader(bytes);
   }
 }
 
@@ -610,10 +618,10 @@
   }
 }
 
-/// Provider for [PackageBundle]s by file paths.
+/// Provider for [PackageBundleReader]s by file paths.
 abstract class PackageBundleProvider {
-  /// Return the [PackageBundle] for the file with the given [path].
-  PackageBundle get(String path);
+  /// Return the [PackageBundleReader] for the file with the given [path].
+  PackageBundleReader get(String path);
 }
 
 /// Wrapper for [InSummaryUriResolver] that tracks accesses to summaries.
@@ -667,7 +675,7 @@
 /// Value object for [WorkerPackageBundleCache].
 class WorkerPackageBundle {
   final List<int> bytes;
-  final PackageBundle bundle;
+  final PackageBundleReader bundle;
 
   WorkerPackageBundle(this.bytes, this.bundle);
 
@@ -675,7 +683,7 @@
   int get size => bytes.length * 3;
 }
 
-/// Cache of [PackageBundle]s.
+/// Cache of [PackageBundleReader]s.
 class WorkerPackageBundleCache {
   final ResourceProvider resourceProvider;
   final PerformanceLog logger;
@@ -685,23 +693,25 @@
       : _cache = Cache<WorkerInput, WorkerPackageBundle>(
             maxSizeBytes, (value) => value.size);
 
-  /// Get the [PackageBundle] from the file with the given [path] in the context
+  /// Get the [PackageBundleReader] from the file with the given [path] in the context
   /// of the given worker [inputs].
-  PackageBundle get(Map<String, WorkerInput> inputs, String path) {
+  PackageBundleReader get(Map<String, WorkerInput> inputs, String path) {
     var input = inputs[path];
 
     // The input must be not null, otherwise we're not expected to read
     // this file, but we check anyway to be safe.
     if (input == null) {
       logger.writeln('Read $path outside of the inputs.');
-      var bytes = resourceProvider.getFile(path).readAsBytesSync();
-      return PackageBundle.fromBuffer(bytes);
+      var file = resourceProvider.getFile(path);
+      var bytes = file.readAsBytesSync() as Uint8List;
+      return PackageBundleReader(bytes);
     }
 
     return _cache.get(input, () {
       logger.writeln('Read $input.');
-      var bytes = resourceProvider.getFile(path).readAsBytesSync();
-      var bundle = PackageBundle.fromBuffer(bytes);
+      var file = resourceProvider.getFile(path);
+      var bytes = file.readAsBytesSync() as Uint8List;
+      var bundle = PackageBundleReader(bytes);
       return WorkerPackageBundle(bytes, bundle);
     }).bundle;
   }
@@ -716,7 +726,7 @@
   WorkerPackageBundleProvider(this.cache, this.inputs);
 
   @override
-  PackageBundle get(String path) {
+  PackageBundleReader get(String path) {
     return cache.get(inputs, path);
   }
 }
diff --git a/pkg/analyzer_cli/test/driver_test.dart b/pkg/analyzer_cli/test/driver_test.dart
index 33f0529..0ec7a94 100644
--- a/pkg/analyzer_cli/test/driver_test.dart
+++ b/pkg/analyzer_cli/test/driver_test.dart
@@ -10,7 +10,7 @@
 import 'package:analyzer/src/error/codes.dart';
 import 'package:analyzer/src/generated/engine.dart';
 import 'package:analyzer/src/generated/source.dart';
-import 'package:analyzer/src/summary/idl.dart';
+import 'package:analyzer/src/summary2/package_bundle_format.dart';
 import 'package:analyzer/src/util/sdk.dart';
 import 'package:analyzer_cli/src/ansi.dart' as ansi;
 import 'package:analyzer_cli/src/driver.dart';
@@ -248,39 +248,25 @@
   Future<void> test_import2_usedAsSupertype() async {
     await _withTempDir(() async {
       var a = await _buildPackage('a', [], 'class A {}');
-      var b = await _buildPackage('b', [a], '''
+      var b = await _buildPackage('b', [], 'class B {}');
+      var c = await _buildPackage('c', [a], '''
 import 'package:a/a.dart';
-class B extends A {}
+import 'package:b/b.dart';
+class C1 extends A {}
+class C2 extends B {}
 ''');
 
-      // We don't invoke anything on class `B`, so don't ask its supertype.
-      // So, no dependency on "a".
-      await _assertDependencies('c', [a, b], '''
-import 'package:b/b.dart';
-B x;
-''', [b]);
-
-      // We infer the type of `x` to `B`.
-      // But we don't ask `B` for its supertype.
-      // So, no dependency on "a".
-      await _assertDependencies('c', [a, b], '''
-import 'package:b/b.dart';
-var x = B();
-''', [b]);
-
-      // We perform full analysis, and check that `new B()` is assignable
-      // to `B x`. This is trivially true, we don't need the supertype of `B`.
-      // So, no dependency on "a".
-      await _assertDependencies(
-        'c',
-        [a, b],
-        '''
-import 'package:b/b.dart';
-var x = B();
-''',
-        [b],
-        summaryOnly: false,
-      );
+      // When we instantiate `C1`, we ask `C1` for its type parameters.
+      // So, we apply resolution to the whole `C1` header (not members).
+      // So, we request `A` that is the superclass of `C1`.
+      // So, dependency on "a".
+      //
+      // But we don't access `C2`, so don't use its supertype `B`.
+      // So, no dependency on "b".
+      await _assertDependencies('d', [a, b, c], '''
+import 'package:c/c.dart';
+C1 x;
+''', [a, c]);
     });
   }
 
@@ -442,13 +428,12 @@
       ]);
       var output = File(outputPath);
       expect(output.existsSync(), isTrue);
-      var bundle = PackageBundle.fromBuffer(await output.readAsBytes());
+      var bundle = PackageBundleReader(await output.readAsBytes());
       var testFileUri = 'file:///test_file.dart';
 
-      var bundle2 = bundle.bundle2;
-      expect(_linkedLibraryUriList(bundle2), [testFileUri]);
+      expect(_linkedLibraryUriList(bundle), [testFileUri]);
       expect(
-        _linkedLibraryUnitUriList(bundle2, testFileUri),
+        _linkedLibraryUnitUriList(bundle, testFileUri),
         [testFileUri],
       );
 
@@ -472,10 +457,9 @@
           fileUri: aUri, additionalArgs: ['--build-summary-output=$aSum']);
       expect(exitCode, ErrorSeverity.ERROR.ordinal);
       var bytes = File(aSum).readAsBytesSync();
-      var bundle = PackageBundle.fromBuffer(bytes);
-      var bundle2 = bundle.bundle2;
-      expect(_linkedLibraryUriList(bundle2), [aUri]);
-      expect(_linkedLibraryUnitUriList(bundle2, aUri), [aUri, '']);
+      var bundle = PackageBundleReader(bytes);
+      expect(_linkedLibraryUriList(bundle), [aUri]);
+      expect(_linkedLibraryUnitUriList(bundle, aUri), [aUri, '']);
     });
   }
 
@@ -522,10 +506,9 @@
             fileUri: aUri, additionalArgs: ['--build-summary-output=$aSum']);
         expect(exitCode, 0);
         var bytes = File(aSum).readAsBytesSync();
-        var bundle = PackageBundle.fromBuffer(bytes);
-        var bundle2 = bundle.bundle2;
-        expect(_linkedLibraryUriList(bundle2), [aUri]);
-        expect(_linkedLibraryUnitUriList(bundle2, aUri), [aUri]);
+        var bundle = PackageBundleReader(bytes);
+        expect(_linkedLibraryUriList(bundle), [aUri]);
+        expect(_linkedLibraryUnitUriList(bundle, aUri), [aUri]);
       }
 
       // Analyze package:bbb/b.dart and compute summary.
@@ -536,10 +519,9 @@
         ]);
         expect(exitCode, 0);
         var bytes = File(bSum).readAsBytesSync();
-        var bundle = PackageBundle.fromBuffer(bytes);
-        var bundle2 = bundle.bundle2;
-        expect(_linkedLibraryUriList(bundle2), [bUri]);
-        expect(_linkedLibraryUnitUriList(bundle2, bUri), [bUri]);
+        var bundle = PackageBundleReader(bytes);
+        expect(_linkedLibraryUriList(bundle), [bUri]);
+        expect(_linkedLibraryUnitUriList(bundle, bUri), [bUri]);
       }
 
       // Analyze package:ccc/c.dart and compute summary.
@@ -550,10 +532,9 @@
         ]);
         expect(exitCode, 0);
         var bytes = File(cSum).readAsBytesSync();
-        var bundle = PackageBundle.fromBuffer(bytes);
-        var bundle2 = bundle.bundle2;
-        expect(_linkedLibraryUriList(bundle2), [cUri]);
-        expect(_linkedLibraryUnitUriList(bundle2, cUri), [cUri]);
+        var bundle = PackageBundleReader(bytes);
+        expect(_linkedLibraryUriList(bundle), [cUri]);
+        expect(_linkedLibraryUnitUriList(bundle, cUri), [cUri]);
       }
     });
   }
@@ -715,16 +696,16 @@
   }
 
   Iterable<String> _linkedLibraryUnitUriList(
-    LinkedNodeBundle bundle2,
+    PackageBundleReader bundle,
     String libraryUriStr,
   ) {
-    var libraries = bundle2.libraries;
+    var libraries = bundle.libraries;
     var library = libraries.singleWhere((l) => l.uriStr == libraryUriStr);
     return library.units.map((u) => u.uriStr).toList();
   }
 
-  Iterable<String> _linkedLibraryUriList(LinkedNodeBundle bundle2) {
-    var libraries = bundle2.libraries;
+  Iterable<String> _linkedLibraryUriList(PackageBundleReader bundle) {
+    var libraries = bundle.libraries;
     return libraries.map((l) => l.uriStr).toList();
   }
 }
diff --git a/pkg/compiler/lib/src/inferrer/list_tracer.dart b/pkg/compiler/lib/src/inferrer/list_tracer.dart
index db86752..17bb7ed 100644
--- a/pkg/compiler/lib/src/inferrer/list_tracer.dart
+++ b/pkg/compiler/lib/src/inferrer/list_tracer.dart
@@ -6,6 +6,7 @@
 
 import '../common/names.dart';
 import '../elements/entities.dart';
+import '../native/behavior.dart';
 import '../universe/selector.dart' show Selector;
 import '../util/util.dart' show Setlet;
 import 'node_tracer.dart';
@@ -162,10 +163,16 @@
   @override
   visitStaticCallSiteTypeInformation(StaticCallSiteTypeInformation info) {
     super.visitStaticCallSiteTypeInformation(info);
+    final commonElements = inferrer.closedWorld.commonElements;
     MemberEntity called = info.calledElement;
-    if (inferrer.closedWorld.commonElements.isForeign(called) &&
-        called.name == Identifiers.JS) {
-      bailout('Used in JS ${info.debugName}');
+    if (commonElements.isForeign(called) && called.name == Identifiers.JS) {
+      NativeBehavior nativeBehavior = inferrer.closedWorld.elementMap
+          .getNativeBehaviorForJsCall(info.invocationNode);
+      // Assume side-effects means that the list has escaped to some unknown
+      // location.
+      if (nativeBehavior.sideEffects.hasSideEffects()) {
+        bailout('Used in JS ${info.debugName}');
+      }
     }
   }
 
diff --git a/pkg/compiler/lib/src/inferrer/type_graph_nodes.dart b/pkg/compiler/lib/src/inferrer/type_graph_nodes.dart
index 365500e..78664eb 100644
--- a/pkg/compiler/lib/src/inferrer/type_graph_nodes.dart
+++ b/pkg/compiler/lib/src/inferrer/type_graph_nodes.dart
@@ -968,6 +968,8 @@
       : super(abstractValueDomain, context, call, enclosing, selector,
             arguments, inLoop);
 
+  ir.StaticInvocation get invocationNode => _call as ir.StaticInvocation;
+
   MemberTypeInformation _getCalledTypeInfo(InferrerEngine inferrer) {
     return inferrer.types.getInferredTypeOfMember(calledElement);
   }
diff --git a/pkg/compiler/test/inference/data/closure_tracer.dart b/pkg/compiler/test/inference/data/closure_tracer.dart
index 08105f7..edccdb3 100644
--- a/pkg/compiler/test/inference/data/closure_tracer.dart
+++ b/pkg/compiler/test/inference/data/closure_tracer.dart
@@ -51,22 +51,22 @@
   return res;
 }
 
-/*member: testStoredInMapOfList:[null|subclass=Object]*/
+/*member: testStoredInMapOfList:[null|exact=JSUInt31]*/
 testStoredInMapOfList() {
   var res;
-  /*[null|subclass=Object]*/ closure(/*[null|subclass=Object]*/ a) => res = a;
+  /*[exact=JSUInt31]*/ closure(/*[exact=JSUInt31]*/ a) => res = a;
   dynamic a = <dynamic>[closure];
   dynamic b = <dynamic, dynamic>{'foo': 1};
 
   b
-      /*update: Dictionary([subclass=JsLinkedHashMap], key: [exact=JSString], value: Union(null, [exact=JSExtendableArray], [exact=JSUInt31]), map: {foo: [exact=JSUInt31], bar: Container([null|exact=JSExtendableArray], element: [null|subclass=Object], length: null)})*/
+      /*update: Dictionary([subclass=JsLinkedHashMap], key: [exact=JSString], value: Union(null, [exact=JSExtendableArray], [exact=JSUInt31]), map: {foo: [exact=JSUInt31], bar: Container([null|exact=JSExtendableArray], element: [subclass=Closure], length: 1)})*/
       ['bar'] = a;
 
   b
-          /*Dictionary([subclass=JsLinkedHashMap], key: [exact=JSString], value: Union(null, [exact=JSExtendableArray], [exact=JSUInt31]), map: {foo: [exact=JSUInt31], bar: Container([null|exact=JSExtendableArray], element: [null|subclass=Object], length: null)})*/
+          /*Dictionary([subclass=JsLinkedHashMap], key: [exact=JSString], value: Union(null, [exact=JSExtendableArray], [exact=JSUInt31]), map: {foo: [exact=JSUInt31], bar: Container([null|exact=JSExtendableArray], element: [subclass=Closure], length: 1)})*/
           ['bar']
 
-      /*Container([null|exact=JSExtendableArray], element: [null|subclass=Object], length: null)*/
+      /*Container([null|exact=JSExtendableArray], element: [subclass=Closure], length: 1)*/
       [0](42);
   return res;
 }
diff --git a/pkg/compiler/test/inference/data/list_js.dart b/pkg/compiler/test/inference/data/list_js.dart
new file mode 100644
index 0000000..9b64060
--- /dev/null
+++ b/pkg/compiler/test/inference/data/list_js.dart
@@ -0,0 +1,60 @@
+// Copyright (c) 2020, 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.
+
+// Test effect of NativeBehavior on list tracing.
+
+/// ignore: IMPORT_INTERNAL_LIBRARY
+import 'dart:_foreign_helper' show JS;
+
+/*member: main:[null]*/
+main() {
+  test1();
+  test2();
+  test3();
+  test4();
+}
+
+/*member: test1:[null]*/
+test1() {
+  var list = [42];
+  JS('', '#', list); // '#' is by default a no-op.
+  witness1(list);
+}
+
+/*member: witness1:[null]*/
+witness1(
+    /*Container([exact=JSExtendableArray], element: [exact=JSUInt31], length: 1)*/ x) {}
+
+/*member: test2:[null]*/
+test2() {
+  var list = [42];
+  JS('effects:all;depends:all', '#', list);
+  witness2(list);
+}
+
+/*member: witness2:[null]*/
+witness2(
+    /*Container([exact=JSExtendableArray], element: [null|subclass=Object], length: null)*/ x) {}
+
+/*member: test3:[null]*/
+test3() {
+  var list = [42];
+  JS('', '#.slice(0)', list);
+  witness3(list);
+}
+
+/*member: witness3:[null]*/
+witness3(
+    /*Container([exact=JSExtendableArray], element: [null|subclass=Object], length: null)*/ x) {}
+
+/*member: test4:[null]*/
+test4() {
+  var list = [42];
+  JS('effects:none;depends:all', '#.slice(0)', list);
+  witness4(list);
+}
+
+/*member: witness4:[null]*/
+witness4(
+    /*Container([exact=JSExtendableArray], element: [exact=JSUInt31], length: 1)*/ x) {}
diff --git a/pkg/compiler/test/inference/data/map_tracer_keys.dart b/pkg/compiler/test/inference/data/map_tracer_keys.dart
index 20e469e..3f183a6 100644
--- a/pkg/compiler/test/inference/data/map_tracer_keys.dart
+++ b/pkg/compiler/test/inference/data/map_tracer_keys.dart
@@ -79,28 +79,28 @@
 /*member: aDouble3:Union(null, [exact=JSDouble], [exact=JSExtendableArray])*/
 dynamic aDouble3 = 42.5;
 
-/*member: aList3:Container([exact=JSExtendableArray], element: [null|subclass=Object], length: null)*/
+/*member: aList3:Container([exact=JSExtendableArray], element: [exact=JSUInt31], length: 1)*/
 dynamic aList3 = [42];
 
-/*member: consume3:Container([exact=JSExtendableArray], element: [null|subclass=Object], length: null)*/
+/*member: consume3:Container([exact=JSExtendableArray], element: [exact=JSUInt31], length: 1)*/
 consume3(
-        /*Container([exact=JSExtendableArray], element: [null|subclass=Object], length: null)*/ x) =>
+        /*Container([exact=JSExtendableArray], element: [exact=JSUInt31], length: 1)*/ x) =>
     x;
 
 /*member: test3:[null]*/
 test3() {
   dynamic theMap = <dynamic, dynamic>{'a': 2.2, 'b': 3.3, 'c': 4.4};
   theMap
-      /*update: Dictionary([subclass=JsLinkedHashMap], key: [exact=JSString], value: Union(null, [exact=JSDouble], [exact=JSExtendableArray]), map: {a: [exact=JSDouble], b: [exact=JSDouble], c: [exact=JSDouble], d: Container([null|exact=JSExtendableArray], element: [null|subclass=Object], length: null)})*/
+      /*update: Dictionary([subclass=JsLinkedHashMap], key: [exact=JSString], value: Union(null, [exact=JSDouble], [exact=JSExtendableArray]), map: {a: [exact=JSDouble], b: [exact=JSDouble], c: [exact=JSDouble], d: Container([null|exact=JSExtendableArray], element: [exact=JSUInt31], length: 1)})*/
       ['d'] = aList3;
   /*iterator: [exact=LinkedHashMapKeyIterable]*/
   /*current: [exact=LinkedHashMapKeyIterator]*/
   /*moveNext: [exact=LinkedHashMapKeyIterator]*/
   for (var key in theMap.
-      /*Dictionary([subclass=JsLinkedHashMap], key: [exact=JSString], value: Union(null, [exact=JSDouble], [exact=JSExtendableArray]), map: {a: [exact=JSDouble], b: [exact=JSDouble], c: [exact=JSDouble], d: Container([null|exact=JSExtendableArray], element: [null|subclass=Object], length: null)})*/
+      /*Dictionary([subclass=JsLinkedHashMap], key: [exact=JSString], value: Union(null, [exact=JSDouble], [exact=JSExtendableArray]), map: {a: [exact=JSDouble], b: [exact=JSDouble], c: [exact=JSDouble], d: Container([null|exact=JSExtendableArray], element: [exact=JSUInt31], length: 1)})*/
       keys) {
     aDouble3 = theMap
-        /*Dictionary([subclass=JsLinkedHashMap], key: [exact=JSString], value: Union(null, [exact=JSDouble], [exact=JSExtendableArray]), map: {a: [exact=JSDouble], b: [exact=JSDouble], c: [exact=JSDouble], d: Container([null|exact=JSExtendableArray], element: [null|subclass=Object], length: null)})*/
+        /*Dictionary([subclass=JsLinkedHashMap], key: [exact=JSString], value: Union(null, [exact=JSDouble], [exact=JSExtendableArray]), map: {a: [exact=JSDouble], b: [exact=JSDouble], c: [exact=JSDouble], d: Container([null|exact=JSExtendableArray], element: [exact=JSUInt31], length: 1)})*/
         [key];
   }
   // We have to reference it somewhere, so that it always gets resolved.
diff --git a/pkg/compiler/test/inference/list_tracer_test.dart b/pkg/compiler/test/inference/list_tracer_test.dart
index 9658374..4e23f1b 100644
--- a/pkg/compiler/test/inference/list_tracer_test.dart
+++ b/pkg/compiler/test/inference/list_tracer_test.dart
@@ -237,9 +237,7 @@
   checkType('listEscapingInSetterValue', commonMasks.numType);
   checkType('listEscapingInIndex', commonMasks.numType);
   checkType('listEscapingInIndexSet', commonMasks.uint31Type);
-  // TODO(johnniwinther): Since Iterable.iterableToString is part of the closed
-  // world we find the `dynamicType` instead of `numType`.
-  checkType('listEscapingTwiceInIndexSet', commonMasks.dynamicType);
+  checkType('listEscapingTwiceInIndexSet', commonMasks.numType);
   checkType('listSetInNonFinalField', commonMasks.numType);
   checkType('listWithChangedLength', commonMasks.uint31Type.nullable());
 
diff --git a/pkg/front_end/lib/src/api_prototype/lowering_predicates.dart b/pkg/front_end/lib/src/api_prototype/lowering_predicates.dart
index c208be1..1d521a5 100644
--- a/pkg/front_end/lib/src/api_prototype/lowering_predicates.dart
+++ b/pkg/front_end/lib/src/api_prototype/lowering_predicates.dart
@@ -128,3 +128,160 @@
   }
   return false;
 }
+
+/// Returns `true` if [node] is the local variable holding the value of a
+/// lowered late variable.
+///
+/// For instance
+///
+///    late int local;
+///
+/// is lowered to (simplified):
+///
+///    int? #local = null;
+///    int #local#get() => #local != null ? #local : throw 'Uninitialized';
+///    void #local#set(int value) {
+///      #local = value;
+///    }
+///
+/// where '#local' is the local variable holding that value.
+///
+/// The default value of this variable is `null`.
+// TODO(johnniwinther): Enable these if the name of late locals is changed
+//  to  '${lateLocalPrefix}${name}'. See
+// backends can benefit from identifying late locals.
+/*bool isLateLoweredLocal(VariableDeclaration node) {
+  return node.name != null && isLateLoweredLocalName(node.name);
+}
+
+/// Returns `true` if [name] is the name of a local variable holding the value
+/// of a lowered late variable.
+bool isLateLoweredLocalName(String name) {
+  return name.startsWith(lateLocalPrefix) &&
+      !(name.endsWith(lateIsSetSuffix) ||
+          name.endsWith(lateLocalGetterSuffix) ||
+          name.endsWith(lateLocalSetterSuffix));
+}
+
+/// Returns the name of the original late local variable from the [name] of the
+/// local variable holding the value of the lowered late variable.
+///
+/// This method assumes that `isLateLoweredLocalName(name)` is `true`.
+String extractLateLoweredLocalNameFrom(String name) {
+  return name.substring(lateLocalPrefix.length);
+}*/
+
+/// Returns `true` if [node] is the local variable holding the marker for
+/// whether a lowered late local variable has been set or not.
+///
+/// For instance
+///
+///    late int? local;
+///
+/// is lowered to (simplified):
+///
+///    bool #local#isSet = false;
+///    int? #local = null;
+///    int #local#get() => _#field#isSet ? #local : throw 'Uninitialized';
+///    void #local#set(int value) {
+///      #local = value;
+///      #local#isSet = true;
+///    }
+///
+/// where '#local#isSet' is the local variable holding the marker.
+///
+/// The default value of this variable is `false`.
+bool isLateLoweredIsSetLocal(VariableDeclaration node) {
+  return node.name != null && isLateLoweredIsSetName(node.name);
+}
+
+/// Returns `true` if [name] is the name of a local variable holding the marker
+/// for whether a lowered late local variable has been set or not.
+bool isLateLoweredIsSetName(String name) {
+  return name.startsWith(lateLocalPrefix) && name.endsWith(lateIsSetSuffix);
+}
+
+/// Returns the name of the original late local variable from the [name] of the
+/// local variable holding the marker for whether the lowered late local
+/// variable has been set or not.
+///
+/// This method assumes that `isLateLoweredIsSetName(name)` is `true`.
+String extractLocalNameFromLateLoweredIsSet(String name) {
+  return name.substring(
+      lateLocalPrefix.length, name.length - lateIsSetSuffix.length);
+}
+
+/// Returns `true` if [node] is the local variable for the local function for
+/// reading the value of a lowered late variable.
+///
+/// For instance
+///
+///    late int local;
+///
+/// is lowered to (simplified):
+///
+///    int? #local = null;
+///    int #local#get() => #local != null ? #local : throw 'Uninitialized';
+///    void #local#set(int value) {
+///      #local = value;
+///    }
+///
+/// where '#local#get' is the local function for reading the variable.
+bool isLateLoweredLocalGetter(VariableDeclaration node) {
+  return node.name != null && isLateLoweredGetterName(node.name);
+}
+
+/// Returns `true` if [name] is the name of the local variable for the local
+/// function for reading the value of a lowered late variable.
+bool isLateLoweredGetterName(String name) {
+  return name.startsWith(lateLocalPrefix) &&
+      name.endsWith(lateLocalGetterSuffix);
+}
+
+/// Returns the name of the original late local variable from the [name] of the
+/// local variable for the local function for reading the value of the lowered
+/// late variable.
+///
+/// This method assumes that `isLateLoweredGetterName(name)` is `true`.
+String extractLocalNameFromLateLoweredGetter(String name) {
+  return name.substring(
+      lateLocalPrefix.length, name.length - lateLocalGetterSuffix.length);
+}
+
+/// Returns `true` if [node] is the local variable for the local function for
+/// setting the value of a lowered late variable.
+///
+/// For instance
+///
+///    late int local;
+///
+/// is lowered to (simplified):
+///
+///    int? #local = null;
+///    int #local#get() => #local != null ? #local : throw 'Uninitialized';
+///    void #local#set(int value) {
+///      #local = value;
+///    }
+///
+/// where '#local#set' is the local function for setting the value of the
+/// variable.
+bool isLateLoweredLocalSetter(VariableDeclaration node) {
+  return node.name != null && isLateLoweredSetterName(node.name);
+}
+
+/// Returns `true` if [name] is the name of the local variable for the local
+/// function for setting the value of a lowered late variable.
+bool isLateLoweredSetterName(String name) {
+  return name.startsWith(lateLocalPrefix) &&
+      name.endsWith(lateLocalSetterSuffix);
+}
+
+/// Returns the name of the original late local variable from the [name] of the
+/// local variable for the local function for setting the value of the lowered
+/// late variable.
+///
+/// This method assumes that `isLateLoweredSetterName(name)` is `true`.
+String extractLocalNameFromLateLoweredSetter(String name) {
+  return name.substring(
+      lateLocalPrefix.length, name.length - lateLocalSetterSuffix.length);
+}
diff --git a/pkg/front_end/lib/src/fasta/kernel/inference_visitor.dart b/pkg/front_end/lib/src/fasta/kernel/inference_visitor.dart
index 7e91837..c2d9461 100644
--- a/pkg/front_end/lib/src/fasta/kernel/inference_visitor.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/inference_visitor.dart
@@ -5803,9 +5803,7 @@
       VariableDeclaration isSetVariable;
       if (isSetEncoding == late_lowering.IsSetEncoding.useIsSetField) {
         isSetVariable = new VariableDeclaration(
-            '${late_lowering.lateLocalPrefix}'
-            '${node.name}'
-            '${late_lowering.lateIsSetSuffix}',
+            late_lowering.computeLateLocalIsSetName(node.name),
             initializer: new BoolLiteral(false)..fileOffset = fileOffset,
             type: inferrer.coreTypes.boolRawType(inferrer.library.nonNullable))
           ..fileOffset = fileOffset;
@@ -5827,11 +5825,9 @@
       Expression createIsSetWrite(Expression value) =>
           new VariableSet(isSetVariable, value);
 
-      VariableDeclaration getVariable =
-          new VariableDeclaration('${late_lowering.lateLocalPrefix}'
-              '${node.name}'
-              '${late_lowering.lateLocalGetterSuffix}')
-            ..fileOffset = fileOffset;
+      VariableDeclaration getVariable = new VariableDeclaration(
+          late_lowering.computeLateLocalGetterName(node.name))
+        ..fileOffset = fileOffset;
       FunctionDeclaration getter = new FunctionDeclaration(
           getVariable,
           new FunctionNode(
@@ -5863,11 +5859,9 @@
       if (!node.isFinal || node.initializer == null) {
         node.isLateFinalWithoutInitializer =
             node.isFinal && node.initializer == null;
-        VariableDeclaration setVariable =
-            new VariableDeclaration('${late_lowering.lateLocalPrefix}'
-                '${node.name}'
-                '${late_lowering.lateLocalSetterSuffix}')
-              ..fileOffset = fileOffset;
+        VariableDeclaration setVariable = new VariableDeclaration(
+            late_lowering.computeLateLocalSetterName(node.name))
+          ..fileOffset = fileOffset;
         VariableDeclaration setterParameter =
             new VariableDeclaration(null, type: node.type)
               ..fileOffset = fileOffset;
@@ -5917,6 +5911,8 @@
         node.initializer = null;
       }
       node.type = inferrer.computeNullable(node.type);
+      node.lateName = node.name;
+      node.name = late_lowering.computeLateLocalName(node.name);
 
       return new StatementInferenceResult.multiple(node.fileOffset, result);
     }
@@ -5989,14 +5985,14 @@
             declaredOrInferredType is! InvalidType) {
           if (variable.isLate || variable.lateGetter != null) {
             if (isDefinitelyUnassigned) {
+              String name = variable.lateName ?? variable.name;
               return new ExpressionInferenceResult(
                   resultType,
                   inferrer.helper.wrapInProblem(
                       resultExpression,
-                      templateLateDefinitelyUnassignedError
-                          .withArguments(node.variable.name),
+                      templateLateDefinitelyUnassignedError.withArguments(name),
                       node.fileOffset,
-                      node.variable.name.length));
+                      name.length));
             }
           } else {
             if (isUnassigned) {
diff --git a/pkg/front_end/lib/src/fasta/kernel/internal_ast.dart b/pkg/front_end/lib/src/fasta/kernel/internal_ast.dart
index 05f9955..b7c839b 100644
--- a/pkg/front_end/lib/src/fasta/kernel/internal_ast.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/internal_ast.dart
@@ -1484,6 +1484,12 @@
   // lowering is enabled.
   DartType lateType;
 
+  // The original name of a lowered late variable.
+  //
+  // This is set in `InferenceVisitor.visitVariableDeclaration` when late
+  // lowering is enabled.
+  String lateName;
+
   @override
   bool get isAssignable {
     if (isStaticLate) return true;
diff --git a/pkg/front_end/lib/src/fasta/kernel/late_lowering.dart b/pkg/front_end/lib/src/fasta/kernel/late_lowering.dart
index 74ca5c1..a2c6f50 100644
--- a/pkg/front_end/lib/src/fasta/kernel/late_lowering.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/late_lowering.dart
@@ -592,3 +592,29 @@
   }
   throw new UnsupportedError("Unexpected IsSetStrategy $isSetStrategy");
 }
+
+/// Returns the name used for the variable that holds the value of a late
+/// lowered local by the given [name].
+String computeLateLocalName(String name) {
+  // TODO(johnniwinther): Change this to '${lateLocalPrefix}${name}' if
+  // backends can benefit from identifying late locals.
+  return name;
+}
+
+/// Returns the name used for the 'isSet' variable of a late lowered local by
+/// the given [name].
+String computeLateLocalIsSetName(String name) {
+  return '${lateLocalPrefix}${name}${lateIsSetSuffix}';
+}
+
+/// Returns the name used for the getter function of a late lowered local by
+/// the given [name].
+String computeLateLocalGetterName(String name) {
+  return '${lateLocalPrefix}${name}${lateLocalGetterSuffix}';
+}
+
+/// Returns the name used for the setter function of a late lowered local by
+/// the given [name].
+String computeLateLocalSetterName(String name) {
+  return '${lateLocalPrefix}${name}${lateLocalSetterSuffix}';
+}
diff --git a/pkg/front_end/lib/src/fasta/util/direct_parser_ast.dart b/pkg/front_end/lib/src/fasta/util/direct_parser_ast.dart
index aa4bc82..9f2c1ae 100644
--- a/pkg/front_end/lib/src/fasta/util/direct_parser_ast.dart
+++ b/pkg/front_end/lib/src/fasta/util/direct_parser_ast.dart
@@ -6,6 +6,9 @@
 
 import 'dart:io' show File;
 
+import 'package:_fe_analyzer_shared/src/scanner/scanner.dart'
+    show ScannerConfiguration;
+
 import 'package:_fe_analyzer_shared/src/parser/parser.dart'
     show ClassMemberParser, Parser;
 
@@ -17,12 +20,21 @@
 import 'package:front_end/src/fasta/util/direct_parser_ast_helper.dart';
 
 DirectParserASTContentCompilationUnitEnd getAST(List<int> rawBytes,
-    {bool includeBody: true, bool includeComments: false}) {
+    {bool includeBody: true,
+    bool includeComments: false,
+    bool enableExtensionMethods: false,
+    bool enableNonNullable: false,
+    bool enableTripleShift: false}) {
   Uint8List bytes = new Uint8List(rawBytes.length + 1);
   bytes.setRange(0, rawBytes.length, rawBytes);
 
-  Utf8BytesScanner scanner =
-      new Utf8BytesScanner(bytes, includeComments: includeComments);
+  ScannerConfiguration scannerConfiguration = new ScannerConfiguration(
+      enableExtensionMethods: enableExtensionMethods,
+      enableNonNullable: enableNonNullable,
+      enableTripleShift: enableTripleShift);
+
+  Utf8BytesScanner scanner = new Utf8BytesScanner(bytes,
+      includeComments: includeComments, configuration: scannerConfiguration);
   Token firstToken = scanner.tokenize();
   if (firstToken == null) {
     throw "firstToken is null";
@@ -55,6 +67,331 @@
     return true;
   }
 
+  DirectParserASTContentClassDeclarationEnd asClass() {
+    if (!isClass()) throw "Not class";
+    return children.last;
+  }
+
+  bool isImport() {
+    if (this is! DirectParserASTContentTopLevelDeclarationEnd) {
+      return false;
+    }
+    if (children.first
+        is! DirectParserASTContentUncategorizedTopLevelDeclarationBegin) {
+      return false;
+    }
+    if (children.last is! DirectParserASTContentImportEnd) {
+      return false;
+    }
+
+    return true;
+  }
+
+  DirectParserASTContentImportEnd asImport() {
+    if (!isImport()) throw "Not import";
+    return children.last;
+  }
+
+  bool isExport() {
+    if (this is! DirectParserASTContentTopLevelDeclarationEnd) {
+      return false;
+    }
+    if (children.first
+        is! DirectParserASTContentUncategorizedTopLevelDeclarationBegin) {
+      return false;
+    }
+    if (children.last is! DirectParserASTContentExportEnd) {
+      return false;
+    }
+
+    return true;
+  }
+
+  DirectParserASTContentExportEnd asExport() {
+    if (!isExport()) throw "Not export";
+    return children.last;
+  }
+
+  bool isEnum() {
+    if (this is! DirectParserASTContentTopLevelDeclarationEnd) {
+      return false;
+    }
+    if (children.first
+        is! DirectParserASTContentUncategorizedTopLevelDeclarationBegin) {
+      return false;
+    }
+    if (children.last is! DirectParserASTContentEnumEnd) {
+      return false;
+    }
+
+    return true;
+  }
+
+  DirectParserASTContentEnumEnd asEnum() {
+    if (!isEnum()) throw "Not enum";
+    return children.last;
+  }
+
+  bool isTypedef() {
+    if (this is! DirectParserASTContentTopLevelDeclarationEnd) {
+      return false;
+    }
+    if (children.first
+        is! DirectParserASTContentUncategorizedTopLevelDeclarationBegin) {
+      return false;
+    }
+    if (children.last is! DirectParserASTContentFunctionTypeAliasEnd) {
+      return false;
+    }
+
+    return true;
+  }
+
+  DirectParserASTContentFunctionTypeAliasEnd asTypedef() {
+    if (!isTypedef()) throw "Not typedef";
+    return children.last;
+  }
+
+  bool isScript() {
+    if (this is! DirectParserASTContentScriptHandle) {
+      return false;
+    }
+    return true;
+  }
+
+  DirectParserASTContentScriptHandle asScript() {
+    if (!isScript()) throw "Not script";
+    return this;
+  }
+
+  bool isExtension() {
+    if (this is! DirectParserASTContentTopLevelDeclarationEnd) {
+      return false;
+    }
+    if (children.first
+        is! DirectParserASTContentExtensionDeclarationPreludeBegin) {
+      return false;
+    }
+    if (children.last is! DirectParserASTContentExtensionDeclarationEnd) {
+      return false;
+    }
+
+    return true;
+  }
+
+  DirectParserASTContentExtensionDeclarationEnd asExtension() {
+    if (!isExtension()) throw "Not extension";
+    return children.last;
+  }
+
+  bool isInvalidTopLevelDeclaration() {
+    if (this is! DirectParserASTContentTopLevelDeclarationEnd) {
+      return false;
+    }
+    if (children.first is! DirectParserASTContentTopLevelMemberBegin) {
+      return false;
+    }
+    if (children.last
+        is! DirectParserASTContentInvalidTopLevelDeclarationHandle) {
+      return false;
+    }
+
+    return true;
+  }
+
+  bool isRecoverableError() {
+    if (this is! DirectParserASTContentTopLevelDeclarationEnd) {
+      return false;
+    }
+    if (children.first
+        is! DirectParserASTContentUncategorizedTopLevelDeclarationBegin) {
+      return false;
+    }
+    if (children.last is! DirectParserASTContentRecoverableErrorHandle) {
+      return false;
+    }
+
+    return true;
+  }
+
+  bool isRecoverImport() {
+    if (this is! DirectParserASTContentTopLevelDeclarationEnd) {
+      return false;
+    }
+    if (children.first
+        is! DirectParserASTContentUncategorizedTopLevelDeclarationBegin) {
+      return false;
+    }
+    if (children.last is! DirectParserASTContentRecoverImportHandle) {
+      return false;
+    }
+
+    return true;
+  }
+
+  bool isMixinDeclaration() {
+    if (this is! DirectParserASTContentTopLevelDeclarationEnd) {
+      return false;
+    }
+    if (children.first
+        is! DirectParserASTContentClassOrNamedMixinApplicationPreludeBegin) {
+      return false;
+    }
+    if (children.last is! DirectParserASTContentMixinDeclarationEnd) {
+      return false;
+    }
+
+    return true;
+  }
+
+  DirectParserASTContentMixinDeclarationEnd asMixinDeclaration() {
+    if (!isMixinDeclaration()) throw "Not mixin declaration";
+    return children.last;
+  }
+
+  bool isNamedMixinDeclaration() {
+    if (this is! DirectParserASTContentTopLevelDeclarationEnd) {
+      return false;
+    }
+    if (children.first
+        is! DirectParserASTContentClassOrNamedMixinApplicationPreludeBegin) {
+      return false;
+    }
+    if (children.last is! DirectParserASTContentNamedMixinApplicationEnd) {
+      return false;
+    }
+
+    return true;
+  }
+
+  DirectParserASTContentNamedMixinApplicationEnd asNamedMixinDeclaration() {
+    if (!isNamedMixinDeclaration()) throw "Not named mixin declaration";
+    return children.last;
+  }
+
+  bool isTopLevelMethod() {
+    if (this is! DirectParserASTContentTopLevelDeclarationEnd) {
+      return false;
+    }
+    if (children.first is! DirectParserASTContentTopLevelMemberBegin) {
+      return false;
+    }
+    if (children.last is! DirectParserASTContentTopLevelMethodEnd) {
+      return false;
+    }
+
+    return true;
+  }
+
+  DirectParserASTContentTopLevelMethodEnd asTopLevelMethod() {
+    if (!isTopLevelMethod()) throw "Not top level method";
+    return children.last;
+  }
+
+  bool isTopLevelFields() {
+    if (this is! DirectParserASTContentTopLevelDeclarationEnd) {
+      return false;
+    }
+    if (children.first is! DirectParserASTContentTopLevelMemberBegin) {
+      return false;
+    }
+    if (children.last is! DirectParserASTContentTopLevelFieldsEnd) {
+      return false;
+    }
+
+    return true;
+  }
+
+  DirectParserASTContentTopLevelFieldsEnd asTopLevelFields() {
+    if (!isTopLevelFields()) throw "Not top level fields";
+    return children.last;
+  }
+
+  bool isLibraryName() {
+    if (this is! DirectParserASTContentTopLevelDeclarationEnd) {
+      return false;
+    }
+    if (children.first
+        is! DirectParserASTContentUncategorizedTopLevelDeclarationBegin) {
+      return false;
+    }
+    if (children.last is! DirectParserASTContentLibraryNameEnd) {
+      return false;
+    }
+
+    return true;
+  }
+
+  DirectParserASTContentLibraryNameEnd asLibraryName() {
+    if (!isLibraryName()) throw "Not library name";
+    return children.last;
+  }
+
+  bool isPart() {
+    if (this is! DirectParserASTContentTopLevelDeclarationEnd) {
+      return false;
+    }
+    if (children.first
+        is! DirectParserASTContentUncategorizedTopLevelDeclarationBegin) {
+      return false;
+    }
+    if (children.last is! DirectParserASTContentPartEnd) {
+      return false;
+    }
+
+    return true;
+  }
+
+  DirectParserASTContentPartEnd asPart() {
+    if (!isPart()) throw "Not part";
+    return children.last;
+  }
+
+  bool isPartOf() {
+    if (this is! DirectParserASTContentTopLevelDeclarationEnd) {
+      return false;
+    }
+    if (children.first
+        is! DirectParserASTContentUncategorizedTopLevelDeclarationBegin) {
+      return false;
+    }
+    if (children.last is! DirectParserASTContentPartOfEnd) {
+      return false;
+    }
+
+    return true;
+  }
+
+  DirectParserASTContentPartOfEnd asPartOf() {
+    if (!isPartOf()) throw "Not part of";
+    return children.last;
+  }
+
+  bool isMetadata() {
+    if (this is! DirectParserASTContentMetadataStarEnd) {
+      return false;
+    }
+    if (children.first is! DirectParserASTContentMetadataStarBegin) {
+      return false;
+    }
+    return true;
+  }
+
+  DirectParserASTContentMetadataStarEnd asMetadata() {
+    if (!isMetadata()) throw "Not metadata";
+    return this;
+  }
+
+  bool isFunctionBody() {
+    if (this is DirectParserASTContentBlockFunctionBodyEnd) return true;
+    return false;
+  }
+
+  DirectParserASTContentBlockFunctionBodyEnd asFunctionBody() {
+    if (!isFunctionBody()) throw "Not function body";
+    return this;
+  }
+
   List<E> recursivelyFind<E extends DirectParserASTContent>() {
     Set<E> result = {};
     _recursivelyFindInternal(this, result);
@@ -72,6 +409,26 @@
       _recursivelyFindInternal(child, result);
     }
   }
+
+  void debugDumpNodeRecursively({String indent = ""}) {
+    print("$indent${runtimeType} (${what}) "
+        "(${deprecatedArguments})");
+    if (children == null) return;
+    for (DirectParserASTContent child in children) {
+      child.debugDumpNodeRecursively(indent: "  $indent");
+    }
+  }
+}
+
+extension MetadataStarExtension on DirectParserASTContentMetadataStarEnd {
+  List<DirectParserASTContentMetadataEnd> getMetadataEntries() {
+    List<DirectParserASTContentMetadataEnd> result = [];
+    for (DirectParserASTContent topLevel in children) {
+      if (topLevel is! DirectParserASTContentMetadataEnd) continue;
+      result.add(topLevel);
+    }
+    return result;
+  }
 }
 
 extension CompilationUnitExtension on DirectParserASTContentCompilationUnitEnd {
@@ -84,6 +441,78 @@
     return result;
   }
 
+  List<DirectParserASTContentTopLevelDeclarationEnd> getMixinDeclarations() {
+    List<DirectParserASTContentTopLevelDeclarationEnd> result = [];
+    for (DirectParserASTContent topLevel in children) {
+      if (!topLevel.isMixinDeclaration()) continue;
+      result.add(topLevel);
+    }
+    return result;
+  }
+
+  List<DirectParserASTContentImportEnd> getImports() {
+    List<DirectParserASTContentImportEnd> result = [];
+    for (DirectParserASTContent topLevel in children) {
+      if (!topLevel.isImport()) continue;
+      result.add(topLevel.children.last);
+    }
+    return result;
+  }
+
+  List<DirectParserASTContentExportEnd> getExports() {
+    List<DirectParserASTContentExportEnd> result = [];
+    for (DirectParserASTContent topLevel in children) {
+      if (!topLevel.isExport()) continue;
+      result.add(topLevel.children.last);
+    }
+    return result;
+  }
+
+  // List<DirectParserASTContentMetadataStarEnd> getMetadata() {
+  //   List<DirectParserASTContentMetadataStarEnd> result = [];
+  //   for (DirectParserASTContent topLevel in children) {
+  //     if (!topLevel.isMetadata()) continue;
+  //     result.add(topLevel);
+  //   }
+  //   return result;
+  // }
+
+  // List<DirectParserASTContentEnumEnd> getEnums() {
+  //   List<DirectParserASTContentEnumEnd> result = [];
+  //   for (DirectParserASTContent topLevel in children) {
+  //     if (!topLevel.isEnum()) continue;
+  //     result.add(topLevel.children.last);
+  //   }
+  //   return result;
+  // }
+
+  // List<DirectParserASTContentFunctionTypeAliasEnd> getTypedefs() {
+  //   List<DirectParserASTContentFunctionTypeAliasEnd> result = [];
+  //   for (DirectParserASTContent topLevel in children) {
+  //     if (!topLevel.isTypedef()) continue;
+  //     result.add(topLevel.children.last);
+  //   }
+  //   return result;
+  // }
+
+  // List<DirectParserASTContentMixinDeclarationEnd> getMixinDeclarations() {
+  //   List<DirectParserASTContentMixinDeclarationEnd> result = [];
+  //   for (DirectParserASTContent topLevel in children) {
+  //     if (!topLevel.isMixinDeclaration()) continue;
+  //     result.add(topLevel.children.last);
+  //   }
+  //   return result;
+  // }
+
+  // List<DirectParserASTContentTopLevelMethodEnd> getTopLevelMethods() {
+  //   List<DirectParserASTContentTopLevelMethodEnd> result = [];
+  //   for (DirectParserASTContent topLevel in children) {
+  //     if (!topLevel.isTopLevelMethod()) continue;
+  //     result.add(topLevel.children.last);
+  //   }
+  //   return result;
+  // }
+
   DirectParserASTContentCompilationUnitBegin getBegin() {
     return children.first;
   }
@@ -91,10 +520,7 @@
 
 extension TopLevelDeclarationExtension
     on DirectParserASTContentTopLevelDeclarationEnd {
-  DirectParserASTContentIdentifierHandle getClassIdentifier() {
-    if (!isClass()) {
-      throw "Not a class";
-    }
+  DirectParserASTContentIdentifierHandle getIdentifier() {
     for (DirectParserASTContent child in children) {
       if (child is DirectParserASTContentIdentifierHandle) return child;
     }
@@ -114,7 +540,18 @@
   }
 }
 
-extension ClassDeclaration on DirectParserASTContentClassDeclarationEnd {
+extension MixinDeclarationExtension
+    on DirectParserASTContentMixinDeclarationEnd {
+  DirectParserASTContentClassOrMixinBodyEnd getClassOrMixinBody() {
+    for (DirectParserASTContent child in children) {
+      if (child is DirectParserASTContentClassOrMixinBodyEnd) return child;
+    }
+    throw "Not found.";
+  }
+}
+
+extension ClassDeclarationExtension
+    on DirectParserASTContentClassDeclarationEnd {
   DirectParserASTContentClassOrMixinBodyEnd getClassOrMixinBody() {
     for (DirectParserASTContent child in children) {
       if (child is DirectParserASTContentClassOrMixinBodyEnd) return child;
@@ -128,6 +565,24 @@
     }
     throw "Not found.";
   }
+
+  DirectParserASTContentClassOrMixinImplementsHandle getClassImplements() {
+    for (DirectParserASTContent child in children) {
+      if (child is DirectParserASTContentClassOrMixinImplementsHandle) {
+        return child;
+      }
+    }
+    throw "Not found.";
+  }
+
+  DirectParserASTContentClassWithClauseHandle getClassWithClause() {
+    for (DirectParserASTContent child in children) {
+      if (child is DirectParserASTContentClassWithClauseHandle) {
+        return child;
+      }
+    }
+    return null;
+  }
 }
 
 extension ClassOrMixinBodyExtension
@@ -156,6 +611,18 @@
     throw "Not found";
   }
 
+  bool isClassFactoryMethod() {
+    DirectParserASTContent child = children[1];
+    if (child is DirectParserASTContentClassFactoryMethodEnd) return true;
+    return false;
+  }
+
+  DirectParserASTContentClassFactoryMethodEnd getClassFactoryMethod() {
+    DirectParserASTContent child = children[1];
+    if (child is DirectParserASTContentClassFactoryMethodEnd) return child;
+    throw "Not found";
+  }
+
   bool isClassFields() {
     DirectParserASTContent child = children[1];
     if (child is DirectParserASTContentClassFieldsEnd) return true;
@@ -167,6 +634,72 @@
     if (child is DirectParserASTContentClassFieldsEnd) return child;
     throw "Not found";
   }
+
+  bool isMixinFields() {
+    DirectParserASTContent child = children[1];
+    if (child is DirectParserASTContentMixinFieldsEnd) return true;
+    return false;
+  }
+
+  DirectParserASTContentMixinFieldsEnd getMixinFields() {
+    DirectParserASTContent child = children[1];
+    if (child is DirectParserASTContentMixinFieldsEnd) return child;
+    throw "Not found";
+  }
+
+  bool isMixinMethod() {
+    DirectParserASTContent child = children[1];
+    if (child is DirectParserASTContentMixinMethodEnd) return true;
+    return false;
+  }
+
+  DirectParserASTContentMixinMethodEnd getMixinMethod() {
+    DirectParserASTContent child = children[1];
+    if (child is DirectParserASTContentMixinMethodEnd) return child;
+    throw "Not found";
+  }
+
+  bool isMixinFactoryMethod() {
+    DirectParserASTContent child = children[1];
+    if (child is DirectParserASTContentMixinFactoryMethodEnd) return true;
+    return false;
+  }
+
+  DirectParserASTContentMixinFactoryMethodEnd getMixinFactoryMethod() {
+    DirectParserASTContent child = children[1];
+    if (child is DirectParserASTContentMixinFactoryMethodEnd) return child;
+    throw "Not found";
+  }
+
+  bool isMixinConstructor() {
+    DirectParserASTContent child = children[1];
+    if (child is DirectParserASTContentMixinConstructorEnd) return true;
+    return false;
+  }
+
+  DirectParserASTContentMixinConstructorEnd getMixinConstructor() {
+    DirectParserASTContent child = children[1];
+    if (child is DirectParserASTContentMixinConstructorEnd) return child;
+    throw "Not found";
+  }
+
+  bool isClassMethod() {
+    DirectParserASTContent child = children[1];
+    if (child is DirectParserASTContentClassMethodEnd) return true;
+    return false;
+  }
+
+  DirectParserASTContentClassMethodEnd getClassMethod() {
+    DirectParserASTContent child = children[1];
+    if (child is DirectParserASTContentClassMethodEnd) return child;
+    throw "Not found";
+  }
+
+  bool isClassRecoverableError() {
+    DirectParserASTContent child = children[1];
+    if (child is DirectParserASTContentRecoverableErrorHandle) return true;
+    return false;
+  }
 }
 
 extension ClassFieldsExtension on DirectParserASTContentClassFieldsEnd {
@@ -203,6 +736,17 @@
   }
 }
 
+extension ClassMethodExtension on DirectParserASTContentClassMethodEnd {
+  DirectParserASTContentBlockFunctionBodyEnd getBlockFunctionBody() {
+    for (DirectParserASTContent child in children) {
+      if (child is DirectParserASTContentBlockFunctionBodyEnd) {
+        return child;
+      }
+    }
+    return null;
+  }
+}
+
 extension ClassConstructorExtension
     on DirectParserASTContentClassConstructorEnd {
   DirectParserASTContentFormalParametersEnd getFormalParameters() {
diff --git a/pkg/front_end/lib/src/testing/id_extractor.dart b/pkg/front_end/lib/src/testing/id_extractor.dart
index d63f675..f9fcbd3 100644
--- a/pkg/front_end/lib/src/testing/id_extractor.dart
+++ b/pkg/front_end/lib/src/testing/id_extractor.dart
@@ -4,6 +4,7 @@
 
 import 'package:_fe_analyzer_shared/src/testing/id.dart';
 import 'package:kernel/ast.dart';
+import '../api_prototype/lowering_predicates.dart';
 
 /// Compute a canonical [Id] for kernel-based nodes.
 Id computeMemberId(Member node) {
@@ -246,7 +247,12 @@
 
   @override
   visitFunctionDeclaration(FunctionDeclaration node) {
-    computeForNode(node, computeDefaultNodeId(node));
+    computeForNode(
+        node,
+        computeDefaultNodeId(node,
+            // TODO(johnniwinther): Remove this when late lowered setter
+            //  functions can have an offset.
+            skipNodeWithNoOffset: isLateLoweredLocalSetter(node.variable)));
     super.visitFunctionDeclaration(node);
   }
 
diff --git a/pkg/front_end/test/fasta/util/direct_parser_ast_test.dart b/pkg/front_end/test/fasta/util/direct_parser_ast_test.dart
new file mode 100644
index 0000000..4f2c82f
--- /dev/null
+++ b/pkg/front_end/test/fasta/util/direct_parser_ast_test.dart
@@ -0,0 +1,472 @@
+import 'dart:convert';
+import 'dart:io';
+
+import 'package:front_end/src/fasta/util/direct_parser_ast.dart';
+import 'package:front_end/src/fasta/util/direct_parser_ast_helper.dart';
+
+Uri base;
+
+main(List<String> args) {
+  File script = new File.fromUri(Platform.script);
+  base = script.parent.uri;
+
+  testTopLevelStuff();
+  testClassStuff();
+  testMixinStuff();
+
+  if (!args.contains("--fast")) {
+    canParseTopLevelIshOfAllFrontendFiles();
+  }
+}
+
+void canParseTopLevelIshOfAllFrontendFiles() {
+  Directory directory = new Directory.fromUri(base.resolve("../../../"));
+  int processed = 0;
+  int errors = 0;
+  for (FileSystemEntity entry in directory.listSync(recursive: true)) {
+    if (entry is File) {
+      if (!entry.path.endsWith(".dart")) continue;
+      try {
+        processed++;
+        List<int> data = entry.readAsBytesSync();
+        DirectParserASTContentCompilationUnitEnd ast = getAST(data,
+            includeBody: true,
+            includeComments: true,
+            enableExtensionMethods: true,
+            enableNonNullable: false);
+        splitIntoChunks(ast, data);
+        for (DirectParserASTContent child in ast.children) {
+          if (child.isClass()) {
+            splitIntoChunks(child.asClass().getClassOrMixinBody(), data);
+          } else if (child.isMixinDeclaration()) {
+            splitIntoChunks(
+                child.asMixinDeclaration().getClassOrMixinBody(), data);
+          }
+        }
+      } catch (e, st) {
+        print("Failure on $entry:\n$e\n\n$st\n\n--------------\n\n");
+        errors++;
+      }
+    }
+  }
+  print("Processed $processed files in $directory. "
+      "Encountered $errors errors.");
+}
+
+void testTopLevelStuff() {
+  File file = new File.fromUri(
+      base.resolve("direct_parser_ast_test_data/top_level_stuff.txt"));
+  List<int> data = file.readAsBytesSync();
+  DirectParserASTContentCompilationUnitEnd ast = getAST(data,
+      includeBody: true,
+      includeComments: true,
+      enableExtensionMethods: true,
+      enableNonNullable: false);
+  expect(2, ast.getImports().length);
+  expect(2, ast.getExports().length);
+
+  List<String> foundChunks = splitIntoChunks(ast, data);
+  expect(22, foundChunks.length);
+  expect("library top_level_stuff;", foundChunks[0]);
+  expect('import "top_level_stuff_helper.dart";', foundChunks[1]);
+  expect('export "top_level_stuff_helper.dart";', foundChunks[2]);
+  expect(
+      'import "top_level_stuff_helper.dart" show a, b, '
+      'c hide d, e, f show foo;',
+      foundChunks[3]);
+  expect(
+      'export "top_level_stuff_helper.dart" show a, b, '
+      'c hide d, e, f show foo;',
+      foundChunks[4]);
+  expect("part 'top_level_stuff_helper.dart';", foundChunks[5]);
+  expect('@metadataOneOnThisOne("bla")\n', foundChunks[6]);
+  expect("@metadataTwoOnThisOne\n", foundChunks[7]);
+  expect("""void toplevelMethod() {
+  // no content
+}""", foundChunks[8]);
+  expect("""List<E> anotherTopLevelMethod<E>() {
+  return null;
+}""", foundChunks[9]);
+  expect("enum FooEnum { A, B, Bla }", foundChunks[10]);
+  expect("""class FooClass {
+  // no content.
+}""", foundChunks[11]);
+  expect("""mixin FooMixin {
+  // no content.
+}""", foundChunks[12]);
+  expect("""class A<T> {
+  // no content.
+}""", foundChunks[13]);
+  expect("typedef B = Function();", foundChunks[14]);
+  expect("""mixin C<T> on A<T> {
+  // no content.
+}""", foundChunks[15]);
+  expect("""extension D<T> on A<T> {
+  // no content.
+}""", foundChunks[16]);
+  expect("class E = A with FooClass;", foundChunks[17]);
+  expect("int field1;", foundChunks[18]);
+  expect("int field2, field3;", foundChunks[19]);
+  expect("int field4 = 42;", foundChunks[20]);
+  expect("@AnnotationAtEOF", foundChunks[21]);
+
+  file = new File.fromUri(
+      base.resolve("direct_parser_ast_test_data/top_level_stuff_helper.txt"));
+  data = file.readAsBytesSync();
+  ast = getAST(data,
+      includeBody: true,
+      includeComments: true,
+      enableExtensionMethods: true,
+      enableNonNullable: false);
+  foundChunks = splitIntoChunks(ast, data);
+  expect(1, foundChunks.length);
+  expect("part of 'top_level_stuff.txt';", foundChunks[0]);
+
+  file = new File.fromUri(
+      base.resolve("direct_parser_ast_test_data/script_handle.txt"));
+  data = file.readAsBytesSync();
+  ast = getAST(data,
+      includeBody: true,
+      includeComments: true,
+      enableExtensionMethods: true,
+      enableNonNullable: false);
+  foundChunks = splitIntoChunks(ast, data);
+  expect(1, foundChunks.length);
+  expect("#!/usr/bin/env dart -c", foundChunks[0]);
+}
+
+void testClassStuff() {
+  File file =
+      new File.fromUri(base.resolve("direct_parser_ast_test_data/class.txt"));
+  List<int> data = file.readAsBytesSync();
+  DirectParserASTContentCompilationUnitEnd ast = getAST(data,
+      includeBody: true,
+      includeComments: true,
+      enableExtensionMethods: true,
+      enableNonNullable: false);
+  List<DirectParserASTContentTopLevelDeclarationEnd> classes = ast.getClasses();
+  expect(2, classes.length);
+
+  DirectParserASTContentTopLevelDeclarationEnd decl = classes[0];
+  DirectParserASTContentClassDeclarationEnd cls = decl.asClass();
+  expect("Foo", decl.getIdentifier().token.lexeme);
+  DirectParserASTContentClassExtendsHandle extendsDecl = cls.getClassExtends();
+  expect("extends", extendsDecl.extendsKeyword?.lexeme);
+  DirectParserASTContentClassOrMixinImplementsHandle implementsDecl =
+      cls.getClassImplements();
+  expect("implements", implementsDecl.implementsKeyword?.lexeme);
+  DirectParserASTContentClassWithClauseHandle withClauseDecl =
+      cls.getClassWithClause();
+  expect(null, withClauseDecl);
+  List<DirectParserASTContentMemberEnd> members =
+      cls.getClassOrMixinBody().getMembers();
+  expect(5, members.length);
+  expect(members[0].isClassConstructor(), true);
+  expect(members[1].isClassFactoryMethod(), true);
+  expect(members[2].isClassMethod(), true);
+  expect(members[3].isClassMethod(), true);
+  expect(members[4].isClassFields(), true);
+
+  List<String> chunks = splitIntoChunks(cls.getClassOrMixinBody(), data);
+  expect(5, chunks.length);
+  expect("""Foo() {
+    // Constructor
+  }""", chunks[0]);
+  expect("factory Foo.factory() => Foo();", chunks[1]);
+  expect("""void method() {
+    // instance method.
+  }""", chunks[2]);
+  expect("""static void staticMethod() {
+    // static method.
+  }""", chunks[3]);
+  expect("int field1, field2 = 42;", chunks[4]);
+
+  chunks = processItem(
+      members[0].getClassConstructor().getBlockFunctionBody(), data);
+  expect(1, chunks.length);
+  expect("""{
+    // Constructor
+  }""", chunks[0]);
+  chunks =
+      processItem(members[2].getClassMethod().getBlockFunctionBody(), data);
+  expect(1, chunks.length);
+  expect("""{
+    // instance method.
+  }""", chunks[0]);
+  chunks =
+      processItem(members[3].getClassMethod().getBlockFunctionBody(), data);
+  expect(1, chunks.length);
+  expect("""{
+    // static method.
+  }""", chunks[0]);
+
+  // TODO: Move (something like) this into the check-all-files-thing.
+  for (DirectParserASTContentMemberEnd member
+      in cls.getClassOrMixinBody().getMembers()) {
+    if (member.isClassConstructor()) continue;
+    if (member.isClassFactoryMethod()) continue;
+    if (member.isClassFields()) continue;
+    if (member.isClassMethod()) continue;
+    throw "$member --- ${member.children}";
+  }
+
+  decl = classes[1];
+  cls = decl.asClass();
+  expect("Foo2", decl.getIdentifier().token.lexeme);
+  extendsDecl = cls.getClassExtends();
+  expect(null, extendsDecl.extendsKeyword?.lexeme);
+  implementsDecl = cls.getClassImplements();
+  expect(null, implementsDecl.implementsKeyword?.lexeme);
+  withClauseDecl = cls.getClassWithClause();
+  expect("with", withClauseDecl.withKeyword.lexeme);
+  members = cls.getClassOrMixinBody().getMembers();
+  expect(0, members.length);
+}
+
+void testMixinStuff() {
+  File file =
+      new File.fromUri(base.resolve("direct_parser_ast_test_data/mixin.txt"));
+  List<int> data = file.readAsBytesSync();
+  DirectParserASTContentCompilationUnitEnd ast = getAST(data,
+      includeBody: true,
+      includeComments: true,
+      enableExtensionMethods: true,
+      enableNonNullable: false);
+  List<DirectParserASTContentTopLevelDeclarationEnd> mixins =
+      ast.getMixinDeclarations();
+  expect(mixins.length, 1);
+
+  DirectParserASTContentTopLevelDeclarationEnd decl = mixins[0];
+  DirectParserASTContentMixinDeclarationEnd mxn = decl.asMixinDeclaration();
+  expect("B", decl.getIdentifier().token.lexeme);
+
+  List<DirectParserASTContentMemberEnd> members =
+      mxn.getClassOrMixinBody().getMembers();
+  expect(4, members.length);
+  expect(members[0].isMixinFields(), true);
+  expect(members[1].isMixinMethod(), true);
+  expect(members[2].isMixinFactoryMethod(), true);
+  expect(members[3].isMixinConstructor(), true);
+
+  List<String> chunks = splitIntoChunks(mxn.getClassOrMixinBody(), data);
+  expect(4, chunks.length);
+  expect("static int staticField = 0;", chunks[0]);
+  expect("""void foo() {
+    // empty
+  }""", chunks[1]);
+  expect("""factory B() {
+    // empty
+  }""", chunks[2]);
+  expect("""B.foo() {
+    // empty
+  }""", chunks[3]);
+}
+
+void expect<E>(E expect, E actual) {
+  if (expect != actual) throw "Expected '$expect' but got '$actual'";
+}
+
+List<String> splitIntoChunks(DirectParserASTContent ast, List<int> data) {
+  List<String> foundChunks = [];
+  for (DirectParserASTContent child in ast.children) {
+    foundChunks.addAll(processItem(child, data));
+  }
+  return foundChunks;
+}
+
+List<String> processItem(DirectParserASTContent item, List<int> data) {
+  if (item.isClass()) {
+    DirectParserASTContentClassDeclarationEnd cls = item.asClass();
+    return [
+      getCutContent(data, cls.beginToken.offset,
+          cls.endToken.offset + cls.endToken.length)
+    ];
+  } else if (item.isMetadata()) {
+    DirectParserASTContentMetadataStarEnd metadataStar = item.asMetadata();
+    List<DirectParserASTContentMetadataEnd> entries =
+        metadataStar.getMetadataEntries();
+    if (entries.isNotEmpty) {
+      List<String> chunks = [];
+      for (DirectParserASTContentMetadataEnd metadata in entries) {
+        chunks.add(getCutContent(
+            data, metadata.beginToken.offset, metadata.endToken.offset));
+      }
+      return chunks;
+    }
+    return const [];
+  } else if (item.isImport()) {
+    DirectParserASTContentImportEnd import = item.asImport();
+    return [
+      getCutContent(data, import.importKeyword.offset,
+          import.semicolon.offset + import.semicolon.length)
+    ];
+  } else if (item.isExport()) {
+    DirectParserASTContentExportEnd export = item.asExport();
+    return [
+      getCutContent(data, export.exportKeyword.offset,
+          export.semicolon.offset + export.semicolon.length)
+    ];
+  } else if (item.isLibraryName()) {
+    DirectParserASTContentLibraryNameEnd name = item.asLibraryName();
+    return [
+      getCutContent(data, name.libraryKeyword.offset,
+          name.semicolon.offset + name.semicolon.length)
+    ];
+  } else if (item.isPart()) {
+    DirectParserASTContentPartEnd part = item.asPart();
+    return [
+      getCutContent(data, part.partKeyword.offset,
+          part.semicolon.offset + part.semicolon.length)
+    ];
+  } else if (item.isPartOf()) {
+    DirectParserASTContentPartOfEnd partOf = item.asPartOf();
+    return [
+      getCutContent(data, partOf.partKeyword.offset,
+          partOf.semicolon.offset + partOf.semicolon.length)
+    ];
+  } else if (item.isTopLevelMethod()) {
+    DirectParserASTContentTopLevelMethodEnd method = item.asTopLevelMethod();
+    return [
+      getCutContent(data, method.beginToken.offset,
+          method.endToken.offset + method.endToken.length)
+    ];
+  } else if (item.isTopLevelFields()) {
+    DirectParserASTContentTopLevelFieldsEnd fields = item.asTopLevelFields();
+    return [
+      getCutContent(data, fields.beginToken.offset,
+          fields.endToken.offset + fields.endToken.length)
+    ];
+  } else if (item.isEnum()) {
+    DirectParserASTContentEnumEnd enm = item.asEnum();
+    return [
+      getCutContent(data, enm.enumKeyword.offset,
+          enm.leftBrace.endGroup.offset + enm.leftBrace.endGroup.length)
+    ];
+  } else if (item.isMixinDeclaration()) {
+    DirectParserASTContentMixinDeclarationEnd mixinDecl =
+        item.asMixinDeclaration();
+    return [
+      getCutContent(data, mixinDecl.mixinKeyword.offset,
+          mixinDecl.endToken.offset + mixinDecl.endToken.length)
+    ];
+  } else if (item.isNamedMixinDeclaration()) {
+    DirectParserASTContentNamedMixinApplicationEnd namedMixinDecl =
+        item.asNamedMixinDeclaration();
+    return [
+      getCutContent(data, namedMixinDecl.begin.offset,
+          namedMixinDecl.endToken.offset + namedMixinDecl.endToken.length)
+    ];
+  } else if (item.isTypedef()) {
+    DirectParserASTContentFunctionTypeAliasEnd typedefDecl = item.asTypedef();
+    return [
+      getCutContent(data, typedefDecl.typedefKeyword.offset,
+          typedefDecl.endToken.offset + typedefDecl.endToken.length)
+    ];
+  } else if (item.isExtension()) {
+    DirectParserASTContentExtensionDeclarationEnd extensionDecl =
+        item.asExtension();
+    return [
+      getCutContent(data, extensionDecl.extensionKeyword.offset,
+          extensionDecl.endToken.offset + extensionDecl.endToken.length)
+    ];
+  } else if (item.isScript()) {
+    DirectParserASTContentScriptHandle script = item.asScript();
+    return [
+      getCutContent(
+          data, script.token.offset, script.token.offset + script.token.length)
+    ];
+  } else if (item is DirectParserASTContentMemberEnd) {
+    if (item.isClassConstructor()) {
+      DirectParserASTContentClassConstructorEnd decl =
+          item.getClassConstructor();
+      return [
+        getCutContent(data, decl.beginToken.offset,
+            decl.endToken.offset + decl.endToken.length)
+      ];
+    } else if (item.isClassFactoryMethod()) {
+      DirectParserASTContentClassFactoryMethodEnd decl =
+          item.getClassFactoryMethod();
+      return [
+        getCutContent(data, decl.beginToken.offset,
+            decl.endToken.offset + decl.endToken.length)
+      ];
+    } else if (item.isClassMethod()) {
+      DirectParserASTContentClassMethodEnd decl = item.getClassMethod();
+      return [
+        getCutContent(data, decl.beginToken.offset,
+            decl.endToken.offset + decl.endToken.length)
+      ];
+    } else if (item.isClassFields()) {
+      DirectParserASTContentClassFieldsEnd decl = item.getClassFields();
+      return [
+        getCutContent(data, decl.beginToken.offset,
+            decl.endToken.offset + decl.endToken.length)
+      ];
+    } else if (item.isClassFields()) {
+      DirectParserASTContentClassFieldsEnd decl = item.getClassFields();
+      return [
+        getCutContent(data, decl.beginToken.offset,
+            decl.endToken.offset + decl.endToken.length)
+      ];
+    } else if (item.isMixinFields()) {
+      DirectParserASTContentMixinFieldsEnd decl = item.getMixinFields();
+      return [
+        getCutContent(data, decl.beginToken.offset,
+            decl.endToken.offset + decl.endToken.length)
+      ];
+    } else if (item.isMixinMethod()) {
+      DirectParserASTContentMixinMethodEnd decl = item.getMixinMethod();
+      return [
+        getCutContent(data, decl.beginToken.offset,
+            decl.endToken.offset + decl.endToken.length)
+      ];
+    } else if (item.isMixinFactoryMethod()) {
+      DirectParserASTContentMixinFactoryMethodEnd decl =
+          item.getMixinFactoryMethod();
+      return [
+        getCutContent(data, decl.beginToken.offset,
+            decl.endToken.offset + decl.endToken.length)
+      ];
+    } else if (item.isMixinConstructor()) {
+      DirectParserASTContentMixinConstructorEnd decl =
+          item.getMixinConstructor();
+      return [
+        getCutContent(data, decl.beginToken.offset,
+            decl.endToken.offset + decl.endToken.length)
+      ];
+    } else {
+      if (item.type == DirectParserASTType.BEGIN) return const [];
+      if (item.type == DirectParserASTType.HANDLE) return const [];
+      if (item.isClassRecoverableError()) return const [];
+      if (item.isRecoverableError()) return const [];
+      if (item.isRecoverImport()) return const [];
+      throw "Unknown: $item --- ${item.children}";
+    }
+  } else if (item.isFunctionBody()) {
+    DirectParserASTContentBlockFunctionBodyEnd decl = item.asFunctionBody();
+    return [
+      getCutContent(data, decl.beginToken.offset,
+          decl.endToken.offset + decl.endToken.length)
+    ];
+  } else {
+    if (item.type == DirectParserASTType.BEGIN) return const [];
+    if (item.type == DirectParserASTType.HANDLE) return const [];
+    if (item.isInvalidTopLevelDeclaration()) return const [];
+    if (item.isRecoverableError()) return const [];
+    if (item.isRecoverImport()) return const [];
+
+    throw "Unknown: $item --- ${item.children}";
+  }
+}
+
+List<int> _contentCache;
+String _contentCacheString;
+String getCutContent(List<int> content, int from, int to) {
+  if (identical(content, _contentCache)) {
+    // cache up to date.
+  } else {
+    _contentCache = content;
+    _contentCacheString = utf8.decode(content);
+  }
+  return _contentCacheString.substring(from, to);
+}
diff --git a/pkg/front_end/test/fasta/util/direct_parser_ast_test_data/class.txt b/pkg/front_end/test/fasta/util/direct_parser_ast_test_data/class.txt
new file mode 100644
index 0000000..a6784da
--- /dev/null
+++ b/pkg/front_end/test/fasta/util/direct_parser_ast_test_data/class.txt
@@ -0,0 +1,21 @@
+class Foo extends Bar implements Baz {
+  Foo() {
+    // Constructor
+  }
+
+  factory Foo.factory() => Foo();
+
+  void method() {
+    // instance method.
+  }
+
+  static void staticMethod() {
+    // static method.
+  }
+
+  int field1, field2 = 42;
+}
+
+class Foo2 with Bar2 {
+  // empty
+}
\ No newline at end of file
diff --git a/pkg/front_end/test/fasta/util/direct_parser_ast_test_data/mixin.txt b/pkg/front_end/test/fasta/util/direct_parser_ast_test_data/mixin.txt
new file mode 100644
index 0000000..031ace0
--- /dev/null
+++ b/pkg/front_end/test/fasta/util/direct_parser_ast_test_data/mixin.txt
@@ -0,0 +1,15 @@
+mixin B {
+  static int staticField = 0;
+  void foo() {
+    // empty
+  }
+
+  // Mixins cannot have constructors (or members with same name as mixin).
+  factory B() {
+    // empty
+  }
+
+  B.foo() {
+    // empty
+  }
+}
\ No newline at end of file
diff --git a/pkg/front_end/test/fasta/util/direct_parser_ast_test_data/script_handle.txt b/pkg/front_end/test/fasta/util/direct_parser_ast_test_data/script_handle.txt
new file mode 100644
index 0000000..8e731aa
--- /dev/null
+++ b/pkg/front_end/test/fasta/util/direct_parser_ast_test_data/script_handle.txt
@@ -0,0 +1 @@
+#!/usr/bin/env dart -c
diff --git a/pkg/front_end/test/fasta/util/direct_parser_ast_test_data/top_level_stuff.txt b/pkg/front_end/test/fasta/util/direct_parser_ast_test_data/top_level_stuff.txt
new file mode 100644
index 0000000..3cd024b
--- /dev/null
+++ b/pkg/front_end/test/fasta/util/direct_parser_ast_test_data/top_level_stuff.txt
@@ -0,0 +1,53 @@
+// Top level comment of sorts. With utf8 stuff → in it so offsets aren't byte
+// offset!
+
+library top_level_stuff;
+
+import "top_level_stuff_helper.dart";
+export "top_level_stuff_helper.dart";
+import "top_level_stuff_helper.dart" show a, b, c hide d, e, f show foo;
+export "top_level_stuff_helper.dart" show a, b, c hide d, e, f show foo;
+
+part 'top_level_stuff_helper.dart';
+
+@metadataOneOnThisOne("bla")
+@metadataTwoOnThisOne
+void toplevelMethod() {
+  // no content
+}
+
+List<E> anotherTopLevelMethod<E>() {
+  return null;
+}
+
+enum FooEnum { A, B, Bla }
+
+class FooClass {
+  // no content.
+}
+
+mixin FooMixin {
+  // no content.
+}
+
+class A<T> {
+  // no content.
+}
+
+typedef B = Function();
+
+mixin C<T> on A<T> {
+  // no content.
+}
+
+extension D<T> on A<T> {
+  // no content.
+}
+
+class E = A with FooClass;
+
+int field1;
+int field2, field3;
+int field4 = 42;
+
+@AnnotationAtEOF
\ No newline at end of file
diff --git a/pkg/front_end/test/fasta/util/direct_parser_ast_test_data/top_level_stuff_helper.txt b/pkg/front_end/test/fasta/util/direct_parser_ast_test_data/top_level_stuff_helper.txt
new file mode 100644
index 0000000..b2c46c8
--- /dev/null
+++ b/pkg/front_end/test/fasta/util/direct_parser_ast_test_data/top_level_stuff_helper.txt
@@ -0,0 +1 @@
+part of 'top_level_stuff.txt';
\ No newline at end of file
diff --git a/pkg/front_end/test/predicates/data/late.dart b/pkg/front_end/test/predicates/data/late.dart
index 3218974..ebf80a8 100644
--- a/pkg/front_end/test/predicates/data/late.dart
+++ b/pkg/front_end/test/predicates/data/late.dart
@@ -120,3 +120,54 @@
   /*member: Class.finalStaticNullableWithInitializer:lateFieldGetter*/
   static late final int? finalStaticNullableWithInitializer = 0;
 }
+
+method() {
+  late int /*
+   lateIsSetLocal,
+   lateLocalGetter,
+   lateLocalSetter
+  */
+      localNonNullableWithoutInitializer;
+  late final int
+      /*
+   lateIsSetLocal,
+   lateLocalGetter,
+   lateLocalSetter
+  */
+      finalLocalNonNullableWithoutInitializer;
+  late int? /*
+   lateIsSetLocal,
+   lateLocalGetter,
+   lateLocalSetter
+  */
+      localNullableWithoutInitializer;
+  late final int?
+      /*
+   lateIsSetLocal,
+   lateLocalGetter,
+   lateLocalSetter
+  */
+      finalLocalNullableWithoutInitializer;
+  late int /*
+   lateIsSetLocal,
+   lateLocalGetter,
+   lateLocalSetter
+  */
+      localNonNullableWithInitializer = 0;
+  late final int /*
+   lateIsSetLocal,
+   lateLocalGetter
+  */
+      finalLocalNonNullableWithInitializer = 0;
+  late int? /*
+   lateIsSetLocal,
+   lateLocalGetter,
+   lateLocalSetter
+  */
+      localNullableWithInitializer = 0;
+  late final int? /*
+   lateIsSetLocal,
+   lateLocalGetter
+  */
+      finalLocalNullableWithInitializer = 0;
+}
diff --git a/pkg/front_end/test/predicates/predicate_test.dart b/pkg/front_end/test/predicates/predicate_test.dart
index d2143dd..2f45e4e 100644
--- a/pkg/front_end/test/predicates/predicate_test.dart
+++ b/pkg/front_end/test/predicates/predicate_test.dart
@@ -9,6 +9,7 @@
 import 'package:_fe_analyzer_shared/src/testing/id_testing.dart';
 import 'package:_fe_analyzer_shared/src/testing/features.dart';
 import 'package:front_end/src/api_prototype/experimental_flags.dart';
+import 'package:front_end/src/testing/id_extractor.dart';
 import 'package:front_end/src/testing/id_testing_helper.dart';
 import 'package:front_end/src/api_prototype/lowering_predicates.dart';
 import 'package:kernel/ast.dart';
@@ -74,6 +75,9 @@
 }
 
 class PredicateDataExtractor extends CfeDataExtractor<Features> {
+  Map<String, Features> featureMap = {};
+  Map<String, NodeId> nodeIdMap = {};
+
   PredicateDataExtractor(InternalCompilerResult compilerResult,
       Map<Id, ActualData<Features>> actualMap)
       : super(compilerResult, actualMap);
@@ -107,4 +111,45 @@
     }
     return null;
   }
+
+  void visitProcedure(Procedure node) {
+    super.visitProcedure(node);
+    nodeIdMap.forEach((String name, NodeId id) {
+      Features features = featureMap[name];
+      if (features != null) {
+        TreeNode nodeWithOffset = computeTreeNodeWithOffset(node);
+        registerValue(
+            nodeWithOffset.location.file, id.value, id, features, name);
+      }
+    });
+    nodeIdMap.clear();
+    featureMap.clear();
+  }
+
+  void visitVariableDeclaration(VariableDeclaration node) {
+    String name;
+    String tag;
+    if (isLateLoweredIsSetLocal(node)) {
+      name = extractLocalNameFromLateLoweredIsSet(node.name);
+      tag = Tags.lateIsSetLocal;
+    } else if (isLateLoweredLocalGetter(node)) {
+      name = extractLocalNameFromLateLoweredGetter(node.name);
+      tag = Tags.lateLocalGetter;
+    } else if (isLateLoweredLocalSetter(node)) {
+      name = extractLocalNameFromLateLoweredSetter(node.name);
+      tag = Tags.lateLocalSetter;
+    } else if (node.name != null) {
+      name = node.name;
+    }
+    if (name != null) {
+      if (node.fileOffset != TreeNode.noOffset) {
+        nodeIdMap[name] ??= new NodeId(node.fileOffset, IdKind.node);
+      }
+      if (tag != null) {
+        Features features = featureMap[name] ??= new Features();
+        features.add(tag);
+      }
+    }
+    super.visitVariableDeclaration(node);
+  }
 }
diff --git a/pkg/front_end/test/spell_checking_list_tests.txt b/pkg/front_end/test/spell_checking_list_tests.txt
index d9ac336..d67f2a8 100644
--- a/pkg/front_end/test/spell_checking_list_tests.txt
+++ b/pkg/front_end/test/spell_checking_list_tests.txt
@@ -223,6 +223,7 @@
 edits
 elapse
 ell
+enm
 entrypoint
 entrypoints
 eoo
@@ -372,6 +373,7 @@
 invocation7d
 invocation7e
 ioo
+ish
 isolate
 isolates
 issue41210b
@@ -461,6 +463,7 @@
 moo
 mul
 mx
+mxn
 mysdk
 naively
 naturally
diff --git a/pkg/front_end/tool/kernel_ast_file_rewriter.dart b/pkg/front_end/tool/kernel_ast_file_rewriter.dart
index 35c5daa..bdefeae 100644
--- a/pkg/front_end/tool/kernel_ast_file_rewriter.dart
+++ b/pkg/front_end/tool/kernel_ast_file_rewriter.dart
@@ -22,8 +22,7 @@
       getAST(bytes, includeBody: true, includeComments: true);
   Map<String, DirectParserASTContentTopLevelDeclarationEnd> classes = {};
   for (DirectParserASTContentTopLevelDeclarationEnd cls in ast.getClasses()) {
-    DirectParserASTContentIdentifierHandle identifier =
-        cls.getClassIdentifier();
+    DirectParserASTContentIdentifierHandle identifier = cls.getIdentifier();
     assert(classes[identifier.token] == null);
     classes[identifier.token.toString()] = cls;
   }
diff --git a/pkg/native_stack_traces/bin/decode.dart b/pkg/native_stack_traces/bin/decode.dart
index 9a7aee0..4ced1ca 100644
--- a/pkg/native_stack_traces/bin/decode.dart
+++ b/pkg/native_stack_traces/bin/decode.dart
@@ -300,12 +300,12 @@
   if (options['help']) return print(_usages[options.command?.name]);
   if (options.command == null) return errorWithUsage('no command provided');
 
-  switch (options.command.name) {
+  switch (options.command!.name) {
     case 'help':
-      return help(options.command);
+      return help(options.command!);
     case 'find':
-      return find(options.command);
+      return find(options.command!);
     case 'translate':
-      return await translate(options.command);
+      return await translate(options.command!);
   }
 }
diff --git a/pkg/nnbd_migration/lib/src/edge_builder.dart b/pkg/nnbd_migration/lib/src/edge_builder.dart
index 7003df0..b348db7 100644
--- a/pkg/nnbd_migration/lib/src/edge_builder.dart
+++ b/pkg/nnbd_migration/lib/src/edge_builder.dart
@@ -2659,21 +2659,23 @@
           node is Statement ? node : null, parts.condition);
     } else if (parts is ForEachParts) {
       Element lhsElement;
+      DecoratedType lhsType;
       if (parts is ForEachPartsWithDeclaration) {
         var variableElement = parts.loopVariable.declaredElement;
         _flowAnalysis.declare(variableElement, true);
         lhsElement = variableElement;
         _dispatch(parts.loopVariable?.type);
+        lhsType = _variables.decoratedElementType(lhsElement);
       } else if (parts is ForEachPartsWithIdentifier) {
         lhsElement = parts.identifier.staticElement;
+        lhsType = _dispatch(parts.identifier);
       } else {
         throw StateError(
             'Unexpected ForEachParts subtype: ${parts.runtimeType}');
       }
       var iterableType = _checkExpressionNotNull(parts.iterable);
       DecoratedType elementType;
-      if (lhsElement != null) {
-        DecoratedType lhsType = _variables.decoratedElementType(lhsElement);
+      if (lhsType != null) {
         var iterableTypeType = iterableType.type;
         if (_typeSystem.isSubtypeOf(
             iterableTypeType, typeProvider.iterableDynamicType)) {
diff --git a/pkg/nnbd_migration/lib/src/fix_builder.dart b/pkg/nnbd_migration/lib/src/fix_builder.dart
index ae77229..1d4748f 100644
--- a/pkg/nnbd_migration/lib/src/fix_builder.dart
+++ b/pkg/nnbd_migration/lib/src/fix_builder.dart
@@ -464,6 +464,15 @@
           // correct post-migration type.
           return variable.typeInternal;
         }
+        if (variable is ParameterElement) {
+          var enclosingElement = variable.enclosingElement;
+          if (enclosingElement is PropertyAccessorElement &&
+              enclosingElement.isSynthetic) {
+            // This is the parameter of a synthetic getter, so it has the same
+            // type as the corresponding variable.
+            return _fixBuilder._computeMigratedType(enclosingElement.variable);
+          }
+        }
         return _fixBuilder._computeMigratedType(variable);
       });
 
diff --git a/pkg/nnbd_migration/lib/src/front_end/navigation_tree_renderer.dart b/pkg/nnbd_migration/lib/src/front_end/navigation_tree_renderer.dart
index eac183f..290f96e 100644
--- a/pkg/nnbd_migration/lib/src/front_end/navigation_tree_renderer.dart
+++ b/pkg/nnbd_migration/lib/src/front_end/navigation_tree_renderer.dart
@@ -56,7 +56,8 @@
       for (var entry in linksGroupedByDirectory.entries)
         NavigationTreeDirectoryNode(
           name: entry.key,
-          path: pathContext.joinAll(entry.value.first.pathParts),
+          path: pathContext
+              .dirname(pathContext.joinAll(entry.value.first.pathParts)),
           subtree: _renderNavigationSubtree(entry.value, depth + 1),
         )..setSubtreeParents(),
       for (var link in links.where((link) => link.depth == depth))
diff --git a/pkg/nnbd_migration/lib/src/front_end/non_nullable_fix.dart b/pkg/nnbd_migration/lib/src/front_end/non_nullable_fix.dart
index 136711e..6ec0a2e 100644
--- a/pkg/nnbd_migration/lib/src/front_end/non_nullable_fix.dart
+++ b/pkg/nnbd_migration/lib/src/front_end/non_nullable_fix.dart
@@ -510,7 +510,7 @@
   void reportException(
       Source source, AstNode node, Object exception, StackTrace stackTrace) {
     listener.client.onException('''
-$exception
+$exception at offset ${node.offset} in $source ($node)
 
 $stackTrace''');
   }
diff --git a/pkg/nnbd_migration/lib/src/front_end/resources/index.html b/pkg/nnbd_migration/lib/src/front_end/resources/index.html
index c30f9ae..f56877d 100644
--- a/pkg/nnbd_migration/lib/src/front_end/resources/index.html
+++ b/pkg/nnbd_migration/lib/src/front_end/resources/index.html
@@ -25,7 +25,6 @@
     <h1>Dart</h1>
     <h2 class="before-apply">Proposed null safety changes</h2>
     <h2 class="after-apply">&#10003; Null safety migration applied</h2>
-    <h3 id="unit-name">&nbsp;</h3>
     <a target="_blank"
        href="https://goo.gle/dart-null-safety-migration-tool">
       <button class="action-button">
@@ -63,16 +62,26 @@
             <div class="nav-tree"></div>
         </div><!-- /nav-inner -->
     </div><!-- /nav -->
-    <div class="content">
-        <div class="regions">
-            <!-- The regions overlay code copy of the content to provide -->
-            <!-- tooltips for modified regions. -->
-        </div><!-- /regions -->
-        <div class="code">
-            <!-- Compilation unit content is written here. -->
-            <p class="welcome">
-                Select a source file on the left to preview the proposed edits.
-            </p>
+    <div class="file">
+        <div class="title-bar">
+            <h3 id="unit-name">&nbsp;</h3>
+            <span id="migrate-unit-status-icon-label">Migrate
+                <span
+                    class="material-icons status-icon migrating"
+                    id="migrate-unit-status-icon">check_box</span>
+            </span>
+        </div>
+        <div class="content">
+            <div class="regions">
+                <!-- The regions overlay code copy of the content to provide -->
+                <!-- tooltips for modified regions. -->
+            </div><!-- /regions -->
+            <div class="code">
+                <!-- Compilation unit content is written here. -->
+                <p class="welcome">
+                    Select a source file on the left to preview the proposed edits.
+                </p>
+            </div>
         </div>
     </div><!-- /content -->
     <div class="info-panel">
diff --git a/pkg/nnbd_migration/lib/src/front_end/resources/migration.css b/pkg/nnbd_migration/lib/src/front_end/resources/migration.css
index 556103b..257cfef 100644
--- a/pkg/nnbd_migration/lib/src/front_end/resources/migration.css
+++ b/pkg/nnbd_migration/lib/src/front_end/resources/migration.css
@@ -93,8 +93,7 @@
 }
 
 header h1,
-header h2,
-header h3 {
+header h2 {
   display: inline-block;
   font-family: "Google Sans","Roboto",sans-serif;
   font-weight: 400;
@@ -113,13 +112,6 @@
   top: -2px;
 }
 
-header h3 {
-  /* Shift text up */
-  position: relative;
-  top: -2px;
-}
-
-
 header .action-button, header a {
   right: 0px;
   float: right;
@@ -222,23 +214,23 @@
   color: #676767; /* $secondary-color */
 }
 
-.nav-tree .status-icon.already-migrated {
+.status-icon.already-migrated {
   color: #007a27; /* $light-green */
 }
 
-.nav-tree .status-icon.opted-out {
+.status-icon.opted-out {
   color: #676767; /* $secondary-color */
 }
 
-.nav-tree .status-icon.opted-out:hover {
+.status-icon.opted-out:hover {
   color: #ffffff;
 }
 
-.nav-tree .status-icon.migrating {
+.status-icon.migrating {
   color: #51c686; /* $dark-green */
 }
 
-.nav-tree .status-icon.migrating:hover {
+.status-icon.migrating:hover {
   color: #ffffff;
 }
 
@@ -300,14 +292,41 @@
   line-height: 1em;
 }
 
-.content {
+.file {
   flex: 4 300px;
+  font-family: "Google Sans","Roboto",sans-serif;
   background: #12202f;
-  font-family: "Roboto Mono", monospace;
-  margin: 0 6px;
+  margin: 6px;
+  overflow: scroll;
+}
+
+.title-bar h3 {
+  display: inline-block;
+  font-weight: 400;
+  /* This aligns the title text with the content text, accounting for the width
+   * of the line numbers.
+   */
+  margin: 0.5em 24px 0.5em 63px;
+}
+
+.title-bar #migrate-unit-status-icon-label {
+  display: none;
+  user-select: none;
+}
+
+.title-bar #migrate-unit-status-icon-label.visible {
+  /* Change to 'inline' to enable the incremental migration feature. */
+  display: none;
+}
+
+.title-bar #migrate-unit-status-icon {
+  vertical-align: text-bottom;
+}
+
+.content {
+  font-family: "Roboto Mono",monospace;
   position: relative;
   white-space: pre;
-  overflow: scroll;
 }
 
 .code {
@@ -659,7 +678,7 @@
  * Adjustments to align material icons in the toolbar buttons.
 */
 .action-button > span {
-  position:relative;
+  position: relative;
   top: -3px;
 }
 
diff --git a/pkg/nnbd_migration/lib/src/front_end/resources/resources.g.dart b/pkg/nnbd_migration/lib/src/front_end/resources/resources.g.dart
index 6088d7e..b03dfe6 100644
--- a/pkg/nnbd_migration/lib/src/front_end/resources/resources.g.dart
+++ b/pkg/nnbd_migration/lib/src/front_end/resources/resources.g.dart
@@ -7422,7 +7422,7 @@
 ''';
 
 String _index_html;
-// index_html md5 is 'f17972e91adf7afeeed745126e359ffb'
+// index_html md5 is '4dc4d54418f267d0f9189690626e0f2a'
 String _index_html_base64 = '''
 PGh0bWw+CjxoZWFkPgogICAgPHRpdGxlPk51bGwgU2FmZXR5IFByZXZpZXc8L3RpdGxlPgogICAgPHNj
 cmlwdCBzcmM9Int7IGhpZ2hsaWdodEpzUGF0aCB9fSI+PC9zY3JpcHQ+CiAgICA8c2NyaXB0Pnt7IGRh
@@ -7443,51 +7443,57 @@
 YWx0PSJEYXJ0UGFkIExvZ28iIGNsYXNzPSJsb2dvIi8+CiAgICA8aDE+RGFydDwvaDE+CiAgICA8aDIg
 Y2xhc3M9ImJlZm9yZS1hcHBseSI+UHJvcG9zZWQgbnVsbCBzYWZldHkgY2hhbmdlczwvaDI+CiAgICA8
 aDIgY2xhc3M9ImFmdGVyLWFwcGx5Ij4mIzEwMDAzOyBOdWxsIHNhZmV0eSBtaWdyYXRpb24gYXBwbGll
-ZDwvaDI+CiAgICA8aDMgaWQ9InVuaXQtbmFtZSI+Jm5ic3A7PC9oMz4KICAgIDxhIHRhcmdldD0iX2Js
-YW5rIgogICAgICAgaHJlZj0iaHR0cHM6Ly9nb28uZ2xlL2RhcnQtbnVsbC1zYWZldHktbWlncmF0aW9u
-LXRvb2wiPgogICAgICA8YnV0dG9uIGNsYXNzPSJhY3Rpb24tYnV0dG9uIj4KICAgICAgICA8aSBjbGFz
-cz0ibWF0ZXJpYWwtaWNvbnMiPmxhdW5jaDwvaT4KICAgICAgICA8c3Bhbj5IZWxwPC9zcGFuPgogICAg
-ICA8L2J1dHRvbj4KICAgIDwvYT4KICAgIDxidXR0b24gY2xhc3M9ImFjdGlvbi1idXR0b24gYXBwbHkt
-bWlncmF0aW9uIj4KICAgICAgICA8aSBjbGFzcz0ibWF0ZXJpYWwtaWNvbnMiPmVkaXQ8L2k+CiAgICAg
-ICAgPHNwYW4gY2xhc3M9ImxhYmVsIj4KICAgICAgICAgIEFwcGx5IE1pZ3JhdGlvbgogICAgICAgIDwv
-c3Bhbj4KICAgIDwvYnV0dG9uPgogICAgPGJ1dHRvbiBjbGFzcz0iYWN0aW9uLWJ1dHRvbiBhcHBseS1t
-aWdyYXRpb24iIGRpc2FibGVkPgogICAgICAgIDxpIGNsYXNzPSJtYXRlcmlhbC1pY29ucyI+ZWRpdDwv
-aT4KICAgICAgICA8c3BhbiBjbGFzcz0ibGFiZWwiPgogICAgICAgICAgQXBwbHkgTWlncmF0aW9uCiAg
-ICAgICAgPC9zcGFuPgogICAgPC9idXR0b24+CiAgICA8YnV0dG9uIGNsYXNzPSJhY3Rpb24tYnV0dG9u
-IHJlcnVuLW1pZ3JhdGlvbiBiZWZvcmUtYXBwbHkiPgogICAgICA8c3BhbiBjbGFzcz0ib3B0aW9uYWwi
-PgogICAgICAgIDxpIGNsYXNzPSJtYXRlcmlhbC1pY29ucyI+cmVwbGF5PC9pPgogICAgICAgIFJlcnVu
-IEZyb20gU291cmNlcwogICAgICA8L3NwYW4+CiAgICAgIDxzcGFuIGNsYXNzPSJyZXF1aXJlZCI+CiAg
-ICAgICAgPGkgY2xhc3M9Im1hdGVyaWFsLWljb25zIj53YXJuaW5nPC9pPgogICAgICAgIFJlcnVuIFdp
-dGggQ2hhbmdlcwogICAgICA8L3NwYW4+CiAgICA8L2J1dHRvbj4KPC9oZWFkZXI+CjxkaXYgY2xhc3M9
-InBhbmVscyBob3Jpem9udGFsIj4KICAgIDxkaXYgY2xhc3M9Im5hdi1wYW5lbCI+CiAgICAgICAgPGRp
-diBjbGFzcz0ibmF2LWlubmVyIj4KICAgICAgICAgICAgPGRpdiBjbGFzcz0icGFuZWwtaGVhZGluZyI+
-UHJvamVjdCBGaWxlczwvZGl2PgogICAgICAgICAgICA8ZGl2IGNsYXNzPSJuYXYtdHJlZSI+PC9kaXY+
-CiAgICAgICAgPC9kaXY+PCEtLSAvbmF2LWlubmVyIC0tPgogICAgPC9kaXY+PCEtLSAvbmF2IC0tPgog
-ICAgPGRpdiBjbGFzcz0iY29udGVudCI+CiAgICAgICAgPGRpdiBjbGFzcz0icmVnaW9ucyI+CiAgICAg
-ICAgICAgIDwhLS0gVGhlIHJlZ2lvbnMgb3ZlcmxheSBjb2RlIGNvcHkgb2YgdGhlIGNvbnRlbnQgdG8g
-cHJvdmlkZSAtLT4KICAgICAgICAgICAgPCEtLSB0b29sdGlwcyBmb3IgbW9kaWZpZWQgcmVnaW9ucy4g
-LS0+CiAgICAgICAgPC9kaXY+PCEtLSAvcmVnaW9ucyAtLT4KICAgICAgICA8ZGl2IGNsYXNzPSJjb2Rl
-Ij4KICAgICAgICAgICAgPCEtLSBDb21waWxhdGlvbiB1bml0IGNvbnRlbnQgaXMgd3JpdHRlbiBoZXJl
-LiAtLT4KICAgICAgICAgICAgPHAgY2xhc3M9IndlbGNvbWUiPgogICAgICAgICAgICAgICAgU2VsZWN0
-IGEgc291cmNlIGZpbGUgb24gdGhlIGxlZnQgdG8gcHJldmlldyB0aGUgcHJvcG9zZWQgZWRpdHMuCiAg
-ICAgICAgICAgIDwvcD4KICAgICAgICA8L2Rpdj4KICAgIDwvZGl2PjwhLS0gL2NvbnRlbnQgLS0+CiAg
-ICA8ZGl2IGNsYXNzPSJpbmZvLXBhbmVsIj4KICAgICAgICA8ZGl2IGNsYXNzPSJlZGl0LWxpc3QiPgog
-ICAgICAgICAgICA8ZGl2IGNsYXNzPSJwYW5lbC1oZWFkaW5nIj5Qcm9wb3NlZCBFZGl0czwvZGl2Pgog
-ICAgICAgICAgICA8ZGl2IGNsYXNzPSJwYW5lbC1jb250ZW50Ij48L2Rpdj4KICAgICAgICA8L2Rpdj48
-IS0tIC9lZGl0LWxpc3QgLS0+CiAgICAgICAgPGRpdiBjbGFzcz0iZWRpdC1wYW5lbCI+CiAgICAgICAg
-ICAgIDxkaXYgY2xhc3M9InBhbmVsLWhlYWRpbmciPkVkaXQgRGV0YWlsczwvZGl2PgogICAgICAgICAg
-ICA8ZGl2IGNsYXNzPSJwYW5lbC1jb250ZW50Ij4KICAgICAgICAgICAgICAgIDxwIGNsYXNzPSJwbGFj
-ZWhvbGRlciI+U2VlIGRldGFpbHMgYWJvdXQgYSBwcm9wb3NlZCBlZGl0LjwvcD4KICAgICAgICAgICAg
-PC9kaXY+PCEtLSAvcGFuZWwtY29udGVudCAtLT4KICAgICAgICA8L2Rpdj48IS0tIC9lZGl0LXBhbmVs
-IC0tPgogICAgPC9kaXY+PCEtLSAvaW5mby1wYW5lbCAtLT4KPC9kaXY+PCEtLSAvcGFuZWxzIC0tPgo8
-Zm9vdGVyPgogIDxidXR0b24gY2xhc3M9InJlcG9ydC1wcm9ibGVtIj5TZW5kIEZlZWRiYWNrPC9idXR0
-b24+CiAgICA8c3BhbiBjbGFzcz0id2lkZSI+IDwvc3Bhbj4KICAgIDxkaXYgY2xhc3M9InNkay12ZXJz
-aW9uIj5CYXNlZCBvbiA8c3BhbiBpZD0ic2RrLXZlcnNpb24iPnt7IHNka1ZlcnNpb24gfX08L3NwYW4+
-PC9kaXY+CjwvZm9vdGVyPgo8L2JvZHk+CjwvaHRtbD4K
+ZDwvaDI+CiAgICA8YSB0YXJnZXQ9Il9ibGFuayIKICAgICAgIGhyZWY9Imh0dHBzOi8vZ29vLmdsZS9k
+YXJ0LW51bGwtc2FmZXR5LW1pZ3JhdGlvbi10b29sIj4KICAgICAgPGJ1dHRvbiBjbGFzcz0iYWN0aW9u
+LWJ1dHRvbiI+CiAgICAgICAgPGkgY2xhc3M9Im1hdGVyaWFsLWljb25zIj5sYXVuY2g8L2k+CiAgICAg
+ICAgPHNwYW4+SGVscDwvc3Bhbj4KICAgICAgPC9idXR0b24+CiAgICA8L2E+CiAgICA8YnV0dG9uIGNs
+YXNzPSJhY3Rpb24tYnV0dG9uIGFwcGx5LW1pZ3JhdGlvbiI+CiAgICAgICAgPGkgY2xhc3M9Im1hdGVy
+aWFsLWljb25zIj5lZGl0PC9pPgogICAgICAgIDxzcGFuIGNsYXNzPSJsYWJlbCI+CiAgICAgICAgICBB
+cHBseSBNaWdyYXRpb24KICAgICAgICA8L3NwYW4+CiAgICA8L2J1dHRvbj4KICAgIDxidXR0b24gY2xh
+c3M9ImFjdGlvbi1idXR0b24gYXBwbHktbWlncmF0aW9uIiBkaXNhYmxlZD4KICAgICAgICA8aSBjbGFz
+cz0ibWF0ZXJpYWwtaWNvbnMiPmVkaXQ8L2k+CiAgICAgICAgPHNwYW4gY2xhc3M9ImxhYmVsIj4KICAg
+ICAgICAgIEFwcGx5IE1pZ3JhdGlvbgogICAgICAgIDwvc3Bhbj4KICAgIDwvYnV0dG9uPgogICAgPGJ1
+dHRvbiBjbGFzcz0iYWN0aW9uLWJ1dHRvbiByZXJ1bi1taWdyYXRpb24gYmVmb3JlLWFwcGx5Ij4KICAg
+ICAgPHNwYW4gY2xhc3M9Im9wdGlvbmFsIj4KICAgICAgICA8aSBjbGFzcz0ibWF0ZXJpYWwtaWNvbnMi
+PnJlcGxheTwvaT4KICAgICAgICBSZXJ1biBGcm9tIFNvdXJjZXMKICAgICAgPC9zcGFuPgogICAgICA8
+c3BhbiBjbGFzcz0icmVxdWlyZWQiPgogICAgICAgIDxpIGNsYXNzPSJtYXRlcmlhbC1pY29ucyI+d2Fy
+bmluZzwvaT4KICAgICAgICBSZXJ1biBXaXRoIENoYW5nZXMKICAgICAgPC9zcGFuPgogICAgPC9idXR0
+b24+CjwvaGVhZGVyPgo8ZGl2IGNsYXNzPSJwYW5lbHMgaG9yaXpvbnRhbCI+CiAgICA8ZGl2IGNsYXNz
+PSJuYXYtcGFuZWwiPgogICAgICAgIDxkaXYgY2xhc3M9Im5hdi1pbm5lciI+CiAgICAgICAgICAgIDxk
+aXYgY2xhc3M9InBhbmVsLWhlYWRpbmciPlByb2plY3QgRmlsZXM8L2Rpdj4KICAgICAgICAgICAgPGRp
+diBjbGFzcz0ibmF2LXRyZWUiPjwvZGl2PgogICAgICAgIDwvZGl2PjwhLS0gL25hdi1pbm5lciAtLT4K
+ICAgIDwvZGl2PjwhLS0gL25hdiAtLT4KICAgIDxkaXYgY2xhc3M9ImZpbGUiPgogICAgICAgIDxkaXYg
+Y2xhc3M9InRpdGxlLWJhciI+CiAgICAgICAgICAgIDxoMyBpZD0idW5pdC1uYW1lIj4mbmJzcDs8L2gz
+PgogICAgICAgICAgICA8c3BhbiBpZD0ibWlncmF0ZS11bml0LXN0YXR1cy1pY29uLWxhYmVsIj5NaWdy
+YXRlCiAgICAgICAgICAgICAgICA8c3BhbgogICAgICAgICAgICAgICAgICAgIGNsYXNzPSJtYXRlcmlh
+bC1pY29ucyBzdGF0dXMtaWNvbiBtaWdyYXRpbmciCiAgICAgICAgICAgICAgICAgICAgaWQ9Im1pZ3Jh
+dGUtdW5pdC1zdGF0dXMtaWNvbiI+Y2hlY2tfYm94PC9zcGFuPgogICAgICAgICAgICA8L3NwYW4+CiAg
+ICAgICAgPC9kaXY+CiAgICAgICAgPGRpdiBjbGFzcz0iY29udGVudCI+CiAgICAgICAgICAgIDxkaXYg
+Y2xhc3M9InJlZ2lvbnMiPgogICAgICAgICAgICAgICAgPCEtLSBUaGUgcmVnaW9ucyBvdmVybGF5IGNv
+ZGUgY29weSBvZiB0aGUgY29udGVudCB0byBwcm92aWRlIC0tPgogICAgICAgICAgICAgICAgPCEtLSB0
+b29sdGlwcyBmb3IgbW9kaWZpZWQgcmVnaW9ucy4gLS0+CiAgICAgICAgICAgIDwvZGl2PjwhLS0gL3Jl
+Z2lvbnMgLS0+CiAgICAgICAgICAgIDxkaXYgY2xhc3M9ImNvZGUiPgogICAgICAgICAgICAgICAgPCEt
+LSBDb21waWxhdGlvbiB1bml0IGNvbnRlbnQgaXMgd3JpdHRlbiBoZXJlLiAtLT4KICAgICAgICAgICAg
+ICAgIDxwIGNsYXNzPSJ3ZWxjb21lIj4KICAgICAgICAgICAgICAgICAgICBTZWxlY3QgYSBzb3VyY2Ug
+ZmlsZSBvbiB0aGUgbGVmdCB0byBwcmV2aWV3IHRoZSBwcm9wb3NlZCBlZGl0cy4KICAgICAgICAgICAg
+ICAgIDwvcD4KICAgICAgICAgICAgPC9kaXY+CiAgICAgICAgPC9kaXY+CiAgICA8L2Rpdj48IS0tIC9j
+b250ZW50IC0tPgogICAgPGRpdiBjbGFzcz0iaW5mby1wYW5lbCI+CiAgICAgICAgPGRpdiBjbGFzcz0i
+ZWRpdC1saXN0Ij4KICAgICAgICAgICAgPGRpdiBjbGFzcz0icGFuZWwtaGVhZGluZyI+UHJvcG9zZWQg
+RWRpdHM8L2Rpdj4KICAgICAgICAgICAgPGRpdiBjbGFzcz0icGFuZWwtY29udGVudCI+PC9kaXY+CiAg
+ICAgICAgPC9kaXY+PCEtLSAvZWRpdC1saXN0IC0tPgogICAgICAgIDxkaXYgY2xhc3M9ImVkaXQtcGFu
+ZWwiPgogICAgICAgICAgICA8ZGl2IGNsYXNzPSJwYW5lbC1oZWFkaW5nIj5FZGl0IERldGFpbHM8L2Rp
+dj4KICAgICAgICAgICAgPGRpdiBjbGFzcz0icGFuZWwtY29udGVudCI+CiAgICAgICAgICAgICAgICA8
+cCBjbGFzcz0icGxhY2Vob2xkZXIiPlNlZSBkZXRhaWxzIGFib3V0IGEgcHJvcG9zZWQgZWRpdC48L3A+
+CiAgICAgICAgICAgIDwvZGl2PjwhLS0gL3BhbmVsLWNvbnRlbnQgLS0+CiAgICAgICAgPC9kaXY+PCEt
+LSAvZWRpdC1wYW5lbCAtLT4KICAgIDwvZGl2PjwhLS0gL2luZm8tcGFuZWwgLS0+CjwvZGl2PjwhLS0g
+L3BhbmVscyAtLT4KPGZvb3Rlcj4KICA8YnV0dG9uIGNsYXNzPSJyZXBvcnQtcHJvYmxlbSI+U2VuZCBG
+ZWVkYmFjazwvYnV0dG9uPgogICAgPHNwYW4gY2xhc3M9IndpZGUiPiA8L3NwYW4+CiAgICA8ZGl2IGNs
+YXNzPSJzZGstdmVyc2lvbiI+QmFzZWQgb24gPHNwYW4gaWQ9InNkay12ZXJzaW9uIj57eyBzZGtWZXJz
+aW9uIH19PC9zcGFuPjwvZGl2Pgo8L2Zvb3Rlcj4KPC9ib2R5Pgo8L2h0bWw+Cg==
 ''';
 
 String _migration_css;
-// migration_css md5 is '21f8c4df3ccf665d538de0d63b257763'
+// migration_css md5 is 'cb4dfc4d6f9dd25370605e3a5e35ace6'
 String _migration_css_base64 = '''
 LyogQ29weXJpZ2h0IChjKSAyMDE5LCB0aGUgRGFydCBwcm9qZWN0IGF1dGhvcnMuIFBsZWFzZSBzZWUg
 dGhlIEFVVEhPUlMgZmlsZSAgKi8KLyogZm9yIGRldGFpbHMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuIFVz
@@ -7523,178 +7529,185 @@
 IGRpc3BsYXk6IG5vbmU7Cn0KCi5wcm9wb3NlZDpub3QoLm5lZWRzLXJlcnVuKSAuYXBwbHktbWlncmF0
 aW9uW2Rpc2FibGVkXSB7CiAgZGlzcGxheTogbm9uZTsKfQoKaGVhZGVyIHsKICBiYWNrZ3JvdW5kLWNv
 bG9yOiAjMWMyODM0OwogIGhlaWdodDogNDhweDsKICBwYWRkaW5nLWxlZnQ6IDI0cHg7CiAgYWxpZ24t
-aXRlbXM6IGNlbnRlcjsKICB6LWluZGV4OiA0Owp9CgpoZWFkZXIgaDEsCmhlYWRlciBoMiwKaGVhZGVy
-IGgzIHsKICBkaXNwbGF5OiBpbmxpbmUtYmxvY2s7CiAgZm9udC1mYW1pbHk6ICJHb29nbGUgU2FucyIs
-IlJvYm90byIsc2Fucy1zZXJpZjsKICBmb250LXdlaWdodDogNDAwOwogIG1hcmdpbi1yaWdodDogMjRw
-eDsKfQoKaDEgewogIGZvbnQtc2l6ZTogMS41ZW07Cn0KCmhlYWRlciBoMiB7CiAgZm9udC1zaXplOiAx
-LjJlbTsKCiAgLyogU2hpZnQgdGV4dCB1cCAqLwogIHBvc2l0aW9uOiByZWxhdGl2ZTsKICB0b3A6IC0y
-cHg7Cn0KCmhlYWRlciBoMyB7CiAgLyogU2hpZnQgdGV4dCB1cCAqLwogIHBvc2l0aW9uOiByZWxhdGl2
-ZTsKICB0b3A6IC0ycHg7Cn0KCgpoZWFkZXIgLmFjdGlvbi1idXR0b24sIGhlYWRlciBhIHsKICByaWdo
-dDogMHB4OwogIGZsb2F0OiByaWdodDsKICBtYXJnaW46IDEwcHg7Cn0KCmhlYWRlciBpbWcubG9nbyB7
-CiAgaGVpZ2h0OiAyNHB4OwogIHdpZHRoOiAyNHB4OwogIG1hcmdpbi1yaWdodDogOHB4OwogIHBvc2l0
-aW9uOiByZWxhdGl2ZTsKICB0b3A6IDRweDsKfQoKZm9vdGVyIC5yZXBvcnQtcHJvYmxlbSB7CiAgcmln
-aHQ6IDBweDsKICBtYXJnaW46IDRweCA4cHg7Cn0KCi5yZXJ1bi1taWdyYXRpb24gLnJlcXVpcmVkIHsK
-ICBkaXNwbGF5OiBub25lOwp9CgoubmVlZHMtcmVydW4gLnJlcnVuLW1pZ3JhdGlvbiAucmVxdWlyZWQg
-ewogIGRpc3BsYXk6IGluaXRpYWw7Cn0KCi5uZWVkcy1yZXJ1biAucmVydW4tbWlncmF0aW9uIC5vcHRp
-b25hbCB7CiAgZGlzcGxheTpub25lOwp9Cgpmb290ZXIgewogIGNvbG9yOiAjY2NjOwogIGJhY2tncm91
-bmQtY29sb3I6ICMyNzMyM2E7CiAgZGlzcGxheTogZmxleDsKICBmbGV4LWRpcmVjdGlvbjogcm93Owog
-IGFsaWduLWl0ZW1zOiBjZW50ZXI7CiAgcGFkZGluZzogOHB4IDAgOHB4IDI0cHg7Cn0KCmZvb3RlciAu
-d2lkZSB7CiAgZmxleDogMTsKfQoKZm9vdGVyIC5zZGstdmVyc2lvbiB7CiAgbWFyZ2luLXJpZ2h0OiAz
-MnB4Owp9CgouaG9yaXpvbnRhbCB7CiAgZGlzcGxheTogZmxleDsKfQoKLnBhbmVscyB7CiAgYmFja2dy
-b3VuZC1jb2xvcjogIzEyMWEyNTsKICBmbGV4OiAxOwogIG92ZXJmbG93OiBoaWRkZW47Cn0KCi5wYW5l
-bC1oZWFkaW5nIHsKICBjb2xvcjogIzY3Njc2NzsKICBtYXJnaW46IDhweDsKfQoKLm5hdi1saW5rLAou
-cmVnaW9uIHsKICBjdXJzb3I6IHBvaW50ZXI7Cn0KCi5uYXYtcGFuZWwgewogIGJhY2tncm91bmQtY29s
-b3I6ICMxMjIwMmY7CiAgZmxleDogMSAyMDBweDsKICBtYXJnaW46IDA7CiAgb3ZlcmZsb3c6IHNjcm9s
-bDsKICB1c2VyLXNlbGVjdDogbm9uZTsKfQoKLm5hdi1pbm5lciB7CiAgcGFkZGluZzogMCAwIDdweCA3
-cHg7Cn0KCi5maXhlZCB7CiAgcG9zaXRpb246IGZpeGVkOwogIHRvcDogMDsKfQoKLnJvb3QgewogIG1h
-cmdpbjogMDsKICBkaXNwbGF5OiBub25lOwp9CgoubmF2LXRyZWUgPiB1bCB7CiAgcGFkZGluZy1sZWZ0
-OiA2cHg7Cn0KCi5uYXYtdHJlZSAubWF0ZXJpYWwtaWNvbnMgewogIGZvbnQtc2l6ZTogMjBweDsKICBw
-b3NpdGlvbjogcmVsYXRpdmU7CiAgdG9wOiA1cHg7CiAgbWFyZ2luLXJpZ2h0OiA4cHg7CiAgY29sb3I6
-ICM2NzY3Njc7IC8qICRzZWNvbmRhcnktY29sb3IgKi8KfQoKLm5hdi10cmVlIC5zdGF0dXMtaWNvbi5h
-bHJlYWR5LW1pZ3JhdGVkIHsKICBjb2xvcjogIzAwN2EyNzsgLyogJGxpZ2h0LWdyZWVuICovCn0KCi5u
-YXYtdHJlZSAuc3RhdHVzLWljb24ub3B0ZWQtb3V0IHsKICBjb2xvcjogIzY3Njc2NzsgLyogJHNlY29u
-ZGFyeS1jb2xvciAqLwp9CgoubmF2LXRyZWUgLnN0YXR1cy1pY29uLm9wdGVkLW91dDpob3ZlciB7CiAg
-Y29sb3I6ICNmZmZmZmY7Cn0KCi5uYXYtdHJlZSAuc3RhdHVzLWljb24ubWlncmF0aW5nIHsKICBjb2xv
-cjogIzUxYzY4NjsgLyogJGRhcmstZ3JlZW4gKi8KfQoKLm5hdi10cmVlIC5zdGF0dXMtaWNvbi5taWdy
-YXRpbmc6aG92ZXIgewogIGNvbG9yOiAjZmZmZmZmOwp9CgoubmF2LWlubmVyIHVsIHsKICBwYWRkaW5n
-LWxlZnQ6IDEycHg7CiAgbWFyZ2luOiAwOwp9CgoubmF2LWlubmVyIGxpIHsKICBsaXN0LXN0eWxlLXR5
-cGU6IG5vbmU7CiAgd2hpdGUtc3BhY2U6IG5vd3JhcDsKfQoKLm5hdi1pbm5lciBsaTpub3QoLmRpcikg
-ewogIG1hcmdpbi1sZWZ0OiAyMHB4OwogIG1hcmdpbi1ib3R0b206IDNweDsKfQoKLm5hdi1pbm5lciBs
-aS5kaXIgLmFycm93IHsKICBjdXJzb3I6IHBvaW50ZXI7CiAgZGlzcGxheTogaW5saW5lLWJsb2NrOwog
-IGZvbnQtc2l6ZTogMTBweDsKICBtYXJnaW4tcmlnaHQ6IDRweDsKICB0cmFuc2l0aW9uOiB0cmFuc2Zv
-cm0gMC41cyBlYXNlLW91dDsKfQoKLm5hdi1pbm5lciBsaS5kaXIgLmFycm93LmNvbGxhcHNlZCB7CiAg
-dHJhbnNmb3JtOiByb3RhdGUoLTkwZGVnKTsKfQoKLm5hdi1pbm5lciB1bCB7CiAgLyogYSBtYXgtaGVp
-Z2h0IGlzIGFkZGVkIHRvIGVhY2ggZWxlbWVudCBhdCBydW50aW1lLiAqLwogIHRyYW5zaXRpb246IG1h
-eC1oZWlnaHQgMC41cyBlYXNlLW91dDsKfQoKLm5hdi1pbm5lciB1bC5jb2xsYXBzZWQgewogIG1heC1o
-ZWlnaHQ6IDAgIWltcG9ydGFudDsKICBvdmVyZmxvdzogaGlkZGVuOwp9CgoubmF2LWlubmVyIC5zZWxl
-Y3RlZC1maWxlIHsKICBjb2xvcjogd2hpdGU7CiAgY3Vyc29yOiBpbmhlcml0OwogIGZvbnQtd2VpZ2h0
-OiA2MDA7CiAgdGV4dC1kZWNvcmF0aW9uOiBub25lOwp9CgouZWRpdC1jb3VudCB7CiAgYmFja2dyb3Vu
-ZC1jb2xvcjogIzY3Njc2NzsKICBib3JkZXItcmFkaXVzOiAxMHB4OwogIGNvbG9yOiAjZmZmOwogIGRp
-c3BsYXk6IGlubGluZS1ibG9jazsKICBmb250LXNpemU6IDExcHg7CiAgZm9udC13ZWlnaHQ6IDYwMDsK
-ICBtYXJnaW4tbGVmdDogNXB4OwogIG1pbi13aWR0aDogMjVweDsKICBwYWRkaW5nOiA0cHggMCAycHgg
-MDsKICB0ZXh0LWFsaWduOiBjZW50ZXI7CiAgbGluZS1oZWlnaHQ6IDFlbTsKfQoKLmNvbnRlbnQgewog
-IGZsZXg6IDQgMzAwcHg7CiAgYmFja2dyb3VuZDogIzEyMjAyZjsKICBmb250LWZhbWlseTogIlJvYm90
-byBNb25vIiwgbW9ub3NwYWNlOwogIG1hcmdpbjogMCA2cHg7CiAgcG9zaXRpb246IHJlbGF0aXZlOwog
-IHdoaXRlLXNwYWNlOiBwcmU7CiAgb3ZlcmZsb3c6IHNjcm9sbDsKfQoKLmNvZGUgewogIHBhZGRpbmc6
-IDAuNWVtOwogIHBvc2l0aW9uOiBhYnNvbHV0ZTsKICBsZWZ0OiAwOwogIHRvcDogMDsKICBtYXJnaW4t
-bGVmdDogNTZweDsKfQoKLmNvZGUgLndlbGNvbWUgewogIGZvbnQtZmFtaWx5OiAiR29vZ2xlIFNhbnMi
-LCJSb2JvdG8iLHNhbnMtc2VyaWY7CiAgZm9udC1zaXplOiAxOHB4OwogIG1hcmdpbi1yaWdodDogNjJw
-eDsKICBjb2xvcjogIzc3NzsKfQoKLmNvZGUgLm5hdi1saW5rIHsKICBjb2xvcjogIzE2YWRjYTsKICB0
-ZXh0LWRlY29yYXRpb24tbGluZTogbm9uZTsKfQoKLmNvZGUgLm5hdi1saW5rOnZpc2l0ZWQgewogIGNv
-bG9yOiAjMTM5YmI1OyAvKiAjMTZhZGNhIGRhcmtlbmVkIDEwJSAqLwogIHRleHQtZGVjb3JhdGlvbi1s
-aW5lOiBub25lOwp9CgouY29kZSAubmF2LWxpbms6aG92ZXIgewogIHRleHQtZGVjb3JhdGlvbi1saW5l
-OiB1bmRlcmxpbmU7CiAgZm9udC13ZWlnaHQ6IDYwMDsKfQoKLnJlZ2lvbnMgewogIHBhZGRpbmc6IDAu
-NWVtOwogIHBvc2l0aW9uOiBhYnNvbHV0ZTsKICBsZWZ0OiAwOwogIHRvcDogMDsKfQoKLnJlZ2lvbnMg
-dGFibGUgewogIGJvcmRlci1zcGFjaW5nOiAwOwogIGZvbnQtc2l6ZTogaW5oZXJpdDsKfQoKLnJlZ2lv
-bnMgdGQgewogIGJvcmRlcjogbm9uZTsKICAvKiBUaGUgY29udGVudCBvZiB0aGUgcmVnaW9ucyBpcyBu
-b3QgdmlzaWJsZTsgdGhlIHVzZXIgaW5zdGVhZCB3aWxsIHNlZSB0aGUKICAgKiBoaWdobGlnaHRlZCBj
-b3B5IG9mIHRoZSBjb250ZW50LiAqLwogIGNvbG9yOiByZ2JhKDI1NSwgMjU1LCAyNTUsIDApOwogIHBh
-ZGRpbmc6IDA7CiAgd2hpdGUtc3BhY2U6IHByZTsKfQoKLnJlZ2lvbnMgdGQ6ZW1wdHk6YWZ0ZXIgewog
-IGNvbnRlbnQ6ICJcMDBhMCI7Cn0KCi5yZWdpb25zIHRyLmhpZ2hsaWdodCB0ZDpsYXN0LWNoaWxkIHsK
-ICBiYWNrZ3JvdW5kLWNvbG9yOiAjNDQ0NDQ0OwogIGNvbG9yOiB3aGl0ZTsKfQoKLnJlZ2lvbnMgdGQu
-bGluZS1ubyB7CiAgYm9yZGVyLXJpZ2h0OiBzb2xpZCAjMTIyMDJmIDJweDsKICBjb2xvcjogIzk5OTk5
-OTsKICBwYWRkaW5nLXJpZ2h0OiA0cHg7CiAgdGV4dC1hbGlnbjogcmlnaHQ7CiAgdmlzaWJpbGl0eTog
-dmlzaWJsZTsKICB3aWR0aDogNTBweDsKICBkaXNwbGF5OiBpbmxpbmUtYmxvY2s7Cn0KCi5yZWdpb25z
-IHRyLmhpZ2hsaWdodCB0ZC5saW5lLW5vIHsKICBib3JkZXItcmlnaHQ6IHNvbGlkICNjY2MgMnB4Owp9
-CgoucmVnaW9uIHsKICBkaXNwbGF5OiBpbmxpbmUtYmxvY2s7CiAgcG9zaXRpb246IHJlbGF0aXZlOwog
-IHZpc2liaWxpdHk6IHZpc2libGU7CiAgei1pbmRleDogMjAwOwp9CgoucmVnaW9uLmFkZGVkLXJlZ2lv
-biB7CiAgYmFja2dyb3VuZC1jb2xvcjogIzE3OGFmZDsKICBjb2xvcjogI2ZmZjsKfQoKLnJlZ2lvbi5y
-ZW1vdmVkLXJlZ2lvbiB7CiAgYmFja2dyb3VuZC1jb2xvcjogI0ZBNTU3ZDsgLyogJGRhcmstcGluayAq
-LwogIGNvbG9yOiAjZmZmOwp9CgoucmVnaW9uLmluZm9ybWF0aXZlLXJlZ2lvbiB7CiAgYmFja2dyb3Vu
-ZC1jb2xvcjogIzI2Mzk1MjsKICBjb2xvcjogI2ZmZjsKICBkaXNwbGF5OiBpbmxpbmUtYmxvY2s7CiAg
-aGVpZ2h0OiAxNXB4OwogIHBvc2l0aW9uOiByZWxhdGl2ZTsKfQoKLnRhcmdldCB7CiAgYmFja2dyb3Vu
-ZC1jb2xvcjogIzQ0NDsKICBwb3NpdGlvbjogcmVsYXRpdmU7CiAgdmlzaWJpbGl0eTogdmlzaWJsZTsK
-ICBmb250LXdlaWdodDogNjAwOwp9CgouaW5mby1wYW5lbCB7CiAgZmxleDogMSAyMDBweDsKICBtYXJn
-aW46IDA7CiAgaGVpZ2h0OiAxMDAlOwogIGRpc3BsYXk6IGZsZXg7CiAgZmxleC1kaXJlY3Rpb246IGNv
-bHVtbjsKfQoKLmluZm8tcGFuZWwgLmVkaXQtcGFuZWwgewogIGJhY2tncm91bmQtY29sb3I6ICMxMjIw
-MmY7CiAgb3ZlcmZsb3c6IGF1dG87Cn0KCi5pbmZvLXBhbmVsIC5wYW5lbC1jb250ZW50IHsKICBwYWRk
-aW5nOiA3cHg7Cn0KCi5pbmZvLXBhbmVsIC5wYW5lbC1jb250ZW50PiA6Zmlyc3QtY2hpbGQgewogIG1h
-cmdpbi10b3A6IDA7Cn0KCi5pbmZvLXBhbmVsIC5ub3dyYXAgewogIHdoaXRlLXNwYWNlOiBub3dyYXA7
-Cn0KCi5pbmZvLXBhbmVsIHVsLAouaW5mby1wYW5lbCBvbCB7CiAgcGFkZGluZy1sZWZ0OiAyMHB4Owp9
-CgouaW5mby1wYW5lbCBsaSB7CiAgbWFyZ2luOiAwIDAgNXB4IDA7Cn0KCi5pbmZvLXBhbmVsIGEgewog
-IGNvbG9yOiAjMTM5YmI1Owp9CgouaW5mby1wYW5lbCBhOmhvdmVyIHsKICBjb2xvcjogIzFlYzdlNzsg
-LyogIzEzOWJiNSBsaWdodGVuZWQgMjAlICovCn0KCi5pbmZvLXBhbmVsIC5lZGl0LWxpc3QgewogIGJh
-Y2tncm91bmQtY29sb3I6ICMxMjIwMmY7CiAgb3ZlcmZsb3c6IGF1dG87Cn0KCi5lZGl0LXBhbmVsIHsK
-ICBtYXJnaW4tdG9wOiA2cHg7CiAgZmxleDogMSAxMDBweDsKfQoKLmVkaXQtbGlzdCB7CiAgZmxleDog
-MiAxMDBweDsKfQoKLmVkaXQtbGlzdCAuZWRpdCB7CiAgbWFyZ2luOiAzcHggMDsKfQoKLmVkaXQtbGlz
-dCAuZWRpdC1saW5rIHsKICBjdXJzb3I6IHBvaW50ZXI7Cn0KCi5wb3B1cC1wYW5lIHsKICBkaXNwbGF5
-OiBub25lOwogIHBvc2l0aW9uOiBmaXhlZDsKICB0b3A6IDE1MHB4OwogIGxlZnQ6IDE1MHB4OwogIHJp
-Z2h0OiAxNTBweDsKICBib3R0b206IDE1MHB4OwogIGJvcmRlcjogMXB4IHNvbGlkIGJsYWNrOwogIGJv
-cmRlci10b3A6IDJweCBzb2xpZCBibGFjazsKICBib3JkZXItcmFkaXVzOiA3cHg7CiAgYm94LXNoYWRv
-dzogMHB4IDBweCAyMHB4IDJweCAjYjRiZmNiMjI7CiAgei1pbmRleDogNDAwOwogIGJhY2tncm91bmQ6
-ICMyYjMwMzY7CiAgcGFkZGluZzogMjBweDsKfQoKLnBvcHVwLXBhbmUgLmNsb3NlIHsKICBwb3NpdGlv
-bjogYWJzb2x1dGU7CiAgcmlnaHQ6IDEwcHg7CiAgdG9wOiAxMHB4OwogIGN1cnNvcjogcG9pbnRlcjsK
-ICB0ZXh0LXNoYWRvdzogMXB4IDFweCAycHggIzg4ODsKICBib3gtc2hhZG93OiAxcHggMXB4IDJweCAj
-MTExOwp9CgoucG9wdXAtcGFuZSBoMiB7CiAgcGFkZGluZzogMjFweDsKICBoZWlnaHQ6IDEwJTsKICBt
-YXJnaW46IDBweDsKICBib3gtc2l6aW5nOiBib3JkZXItYm94Owp9CgoucG9wdXAtcGFuZSBwIHsKICBo
-ZWlnaHQ6IDEwJTsKICBib3gtc2l6aW5nOiBib3JkZXItYm94OwogIHBhZGRpbmc6IDBweCAyMHB4Owp9
-CgoucG9wdXAtcGFuZSBwcmUgewogIGJhY2tncm91bmQ6ICMxMjIwMmY7CiAgcGFkZGluZzogMjBweDsK
-ICBib3R0b206IDBweDsKICBvdmVyZmxvdzogYXV0byBzY3JvbGw7CiAgaGVpZ2h0OiA2NSU7CiAgbWFy
-Z2luOiAwcHg7CiAgYm94LXNpemluZzogYm9yZGVyLWJveDsKfQoKLnBvcHVwLXBhbmUgLmJ1dHRvbi5i
-b3R0b20gewogIG1hcmdpbjogMjBweCAwcHg7CiAgZGlzcGxheTogYmxvY2s7CiAgdGV4dC1hbGlnbjog
-Y2VudGVyOwp9CgoucmVydW5uaW5nLXBhbmUgewogIGRpc3BsYXk6IG5vbmU7Cn0KCmJvZHkucmVydW5u
-aW5nIC5yZXJ1bm5pbmctcGFuZSB7CiAgZGlzcGxheTogYmxvY2s7CiAgcG9zaXRpb246IGZpeGVkOwog
-IHRvcDogMHB4OwogIGJvdHRvbTogMHB4OwogIGxlZnQ6IDBweDsKICByaWdodDogMHB4OwogIGJhY2tn
-cm91bmQtY29sb3I6ICMwMDAwMDBBQTsgLyogdHJhbnNsdWNlbnQgYmxhY2sgKi8KICB6LWluZGV4OiA0
-MDA7Cn0KCi5yZXJ1bm5pbmctcGFuZSBoMSB7CiAgcG9zaXRpb246IGFic29sdXRlOwogIHRvcDogNTAl
-OwogIGxlZnQ6IDUwJTsKICB0cmFuc2Zvcm06IHRyYW5zbGF0ZSgtNTAlLCAtNTAlKTsKfQoKLmVkaXQt
-cGFuZWwgLnR5cGUtZGVzY3JpcHRpb24gewogIC8qIEZyb20gRGFydFBhZCAkZGFyay1vcmFuZ2UgKi8K
-ICBjb2xvcjogI2ZmOTE2ZTsKICBmb250LWZhbWlseTogbW9ub3NwYWNlOwp9Cgp1bC50cmFjZSB7CiAg
-Zm9udC1zaXplOiAxM3B4OwogIGxpc3Qtc3R5bGUtdHlwZTogbm9uZTsKICBwYWRkaW5nLWxlZnQ6IDBw
-eDsKfQoKdWwudHJhY2UgbGkgewogIGNvbG9yOiB3aGl0ZTsKfQoKdWwudHJhY2UgbGkgLmZ1bmN0aW9u
-IHsKICAvKiBmcm9tIC5obGpzLXZhcmlhYmxlICovCiAgY29sb3I6ICMxNmFkY2E7CiAgZm9udC1mYW1p
-bHk6IG1vbm9zcGFjZTsKICBmb250LXdlaWdodDogNjAwOwp9Cgp1bC50cmFjZSBsaSBwLmRyYXdlciB7
-CiAgbWFyZ2luOiAzcHggMHB4OwogIHBhZGRpbmc6IDBweCAwcHggMHB4IDE0cHg7Cn0KCnVsLnRyYWNl
-IGxpIHAuZHJhd2VyIGJ1dHRvbiB7CiAgbWFyZ2luLXJpZ2h0OiAzcHg7Cn0KCi5lbGV2YXRpb24tejQg
-ewogIGJveC1zaGFkb3c6IDBweCAycHggNHB4IC0xcHggcmdiYSgwLCAwLCAwLCAwLjIpLAogICAgICAw
-cHggNHB4IDVweCAwcHggcmdiYSgwLCAwLCAwLCAwLjE0KSwKICAgICAgMHB4IDFweCAxMHB4IDBweCBy
-Z2JhKDAsIDAsIDAsIC4xMik7Cn0KCmEgewogIGNvbG9yOiAjY2NjOwogIGZpbGw6ICNjY2M7CiAgdGV4
-dC1kZWNvcmF0aW9uOiBub25lOwp9CgphOmhvdmVyIHsKICBjb2xvcjogI2RiZGJkYjsgLyogI2NjYyBs
-aWdodGVudGVkIDMwJSovCiAgZmlsbDogI2ZmZjsKfQoKLmFkZC1oaW50LWxpbmsgewogIGRpc3BsYXk6
-IGlubGluZS1ibG9jazsKICBtYXJnaW46IDNweDsKfQoKLmFkZC1oaW50LWxpbms6aG92ZXIgewogIGNv
-bG9yOiAjZmZmOwp9CgpoZWFkZXIgYnV0dG9uIHsKICB0ZXh0LXRyYW5zZm9ybTogdXBwZXJjYXNlOwp9
-CgpoZWFkZXIgYSB7CiAgbWFyZ2luOiAwOwp9CgovKiBDYXJlZnVsIGhlcmUuIGBhLmJ1dHRvbmAgaXMg
-cmVwZXRpdGl2ZSBidXQgcmVxdWlyZWQgdG8gZ2V0IGNvcnJlY3QKICogc3BlY2lmaWNpdHkgKi8KYnV0
-dG9uLCAuYnV0dG9uLCBhLmJ1dHRvbiB7CiAgYmFja2dyb3VuZC1jb2xvcjogcmdiYSgyMiwgMTM4LCAy
-NTMsIDAuMTUpOwogIGJvcmRlcjogbm9uZTsKICBib3JkZXItcmFkaXVzOiAzcHg7CiAgcGFkZGluZzog
-M3B4IDEwcHg7CiAgZm9udC13ZWlnaHQ6IDUwMDsKICBmb250LWZvbnQ6IFJvYm90bywgc2Fucy1zZXJp
-ZjsKICBjb2xvcjogI2ZmZjsKfQoKYnV0dG9uOmhvdmVyLCAuYnV0dG9uOmhvdmVyIHsKICBiYWNrZ3Jv
-dW5kLWNvbG9yOiByZ2JhKDIyLCAxMzgsIDI1MywgMC4yOSk7CiAgY3Vyc29yOiBwb2ludGVyOwp9Cgpi
-dXR0b25bZGlzYWJsZWRdIHsKICBiYWNrZ3JvdW5kLWNvbG9yOiByZ2JhKDI1NSwyNTUsMjU1LC4xMik7
-CiAgY29sb3I6IHJnYmEoMjU1LDI1NSwyNTUsLjM3KTsKICBjdXJzb3I6IG5vdC1hbGxvd2VkOwp9Cgov
-KiBDaGFuZ2UgZWRpdCBwYW5lbCBidXR0b24gY29sb3JzICovCi5lZGl0LXBhbmVsIC5idXR0b24sIC5l
-ZGl0LXBhbmVsIGJ1dHRvbiB7CiAgYmFja2dyb3VuZC1jb2xvcjogcmdiYSg2MywgMTA0LCAxNDgsIDAu
-Nik7CiAgY29sb3I6IHdoaXRlOwp9Ci5lZGl0LXBhbmVsIC5idXR0b246aG92ZXIsIC5lZGl0LXBhbmVs
-IGJ1dHRvbjpob3ZlciB7CiAgYmFja2dyb3VuZC1jb2xvcjogcmdiYSgxMDEsIDE1MywgMjA4LCAwLjYp
-OwogIGNvbG9yOiB3aGl0ZTsKfQoKLyoKICogQWRqdXN0bWVudHMgdG8gYWxpZ24gbWF0ZXJpYWwgaWNv
-bnMgaW4gdGhlIHRvb2xiYXIgYnV0dG9ucy4KKi8KLmFjdGlvbi1idXR0b24gPiBzcGFuIHsKICBwb3Np
-dGlvbjpyZWxhdGl2ZTsKICB0b3A6IC0zcHg7Cn0KCi5hY3Rpb24tYnV0dG9uIC5tYXRlcmlhbC1pY29u
-cyB7CiAgdG9wOiA0cHg7Cn0KCi8qIERvbid0IHNoaWZ0IHRoZSBpY29uIHdoZW4gaXQncyBhIGRpcmVj
-dCBjaGlsZCBvZiB0aGUgYnV0dG9uICovCi5hY3Rpb24tYnV0dG9uID4gLm1hdGVyaWFsLWljb25zIHsK
-ICB0b3A6IDFweDsKfQoKLyogU2hpZnQgdGhlIHRleHQgdG8gY2VudGVyIHdpdGggdGhlIGljb24uICov
-Ci5hY3Rpb24tYnV0dG9uID4gc3Bhbi5sYWJlbCB7CiAgcG9zaXRpb246cmVsYXRpdmU7CiAgdG9wOiAt
-NHB4Owp9CgouYWN0aW9uLWJ1dHRvbiAubWF0ZXJpYWwtaWNvbnMgewogIGZvbnQtc2l6ZTogMjBweDsK
-ICBwb3NpdGlvbjogcmVsYXRpdmU7Cn0KCi5wbGFjZWhvbGRlciB7CiAgY29sb3I6ICM3Nzc7CiAgdGV4
-dC1hbGlnbjogY2VudGVyOwogIG1hcmdpbi10b3A6IDNlbSAhaW1wb3J0YW50Owp9CgovKioKICogSExK
-UyBPdmVycmlkZXMKICovCi5obGpzIHsKICBiYWNrZ3JvdW5kLWNvbG9yOiAjMTIyMDJmOyAvKiAkZGFy
-ay1jb2RlLWJhY2tncm91bmQtY29sb3IgKi8KICBjb2xvcjogI2MwYzJjNTsgLyogJGRhcmstZWRpdG9y
-LXRleHQgKi8KICBkaXNwbGF5OiBibG9jazsKICBvdmVyZmxvdy14OiBhdXRvOwogIHBhZGRpbmc6IDAu
-NWVtOwogIC8qKgogICAqIFRoaXMgYWxsb3dzIHRoZSBwZXItbGluZSBoaWdobGlnaHRzIHRvIHNob3cu
-CiAgICovCiAgYmFja2dyb3VuZDogbm9uZTsKfQoKLmhsanMta2V5d29yZCwKLmhsanMtc2VsZWN0b3It
-dGFnLAouaGxqcy1kZWxldGlvbiB7CiAgY29sb3I6ICM1MWM2ODY7IC8qIGNtLWtleXdvcmQgKi8KfQoK
-LmhsanMtbnVtYmVyIHsKICBjb2xvcjogIzYyNzk3ODsgLyogY20tbnVtYmVyICovCn0KCi5obGpzLWNv
-bW1lbnQgewogIGNvbG9yOiAjOTE5OGI0OyAvKiBjbS1jb21tZW50ICovCn0KCi5obGpzLWxpdGVyYWwg
-ewogIGNvbG9yOiAjZWU4NjY2OyAvKiBjbS1hdG9tICovCn0KCi5obGpzLXN0cmluZyB7CiAgY29sb3I6
-ICNlNTUwNzQ7IC8qIGNtLXN0cmluZyAqLwp9CgouaGxqcy12YXJpYWJsZSB7CiAgY29sb3I6ICMxNmFk
-Y2E7IC8qIGNtLXZhcmlhYmxlICovCn0KCi5obGpzLWxpbmsgewogIGNvbG9yOiAjZTU1MDc0OyAvKiBj
-bS1zdHJpbmcgKi8KfQouaGxqcy1zZWN0aW9uLAouaGxqcy10eXBlLAouaGxqcy1idWlsdF9pbiwKLmhs
-anMtdGl0bGUgewogIGNvbG9yOiAjZWU4NjY2OyAvKiBjbS12YXJpYWJsZS0yICovCn0KCi5obGpzLWFk
-ZGl0aW9uIHsKICBjb2xvcjogIzI2Mzk1MjsgLyogJGRhcmstc2VsZWN0aW9uLWNvbG9yICovCn0KCi5o
-bGpzLW1ldGEgewogIGNvbG9yOiAjNjI3OTc4Owp9Cg==
+aXRlbXM6IGNlbnRlcjsKICB6LWluZGV4OiA0Owp9CgpoZWFkZXIgaDEsCmhlYWRlciBoMiB7CiAgZGlz
+cGxheTogaW5saW5lLWJsb2NrOwogIGZvbnQtZmFtaWx5OiAiR29vZ2xlIFNhbnMiLCJSb2JvdG8iLHNh
+bnMtc2VyaWY7CiAgZm9udC13ZWlnaHQ6IDQwMDsKICBtYXJnaW4tcmlnaHQ6IDI0cHg7Cn0KCmgxIHsK
+ICBmb250LXNpemU6IDEuNWVtOwp9CgpoZWFkZXIgaDIgewogIGZvbnQtc2l6ZTogMS4yZW07CgogIC8q
+IFNoaWZ0IHRleHQgdXAgKi8KICBwb3NpdGlvbjogcmVsYXRpdmU7CiAgdG9wOiAtMnB4Owp9CgpoZWFk
+ZXIgLmFjdGlvbi1idXR0b24sIGhlYWRlciBhIHsKICByaWdodDogMHB4OwogIGZsb2F0OiByaWdodDsK
+ICBtYXJnaW46IDEwcHg7Cn0KCmhlYWRlciBpbWcubG9nbyB7CiAgaGVpZ2h0OiAyNHB4OwogIHdpZHRo
+OiAyNHB4OwogIG1hcmdpbi1yaWdodDogOHB4OwogIHBvc2l0aW9uOiByZWxhdGl2ZTsKICB0b3A6IDRw
+eDsKfQoKZm9vdGVyIC5yZXBvcnQtcHJvYmxlbSB7CiAgcmlnaHQ6IDBweDsKICBtYXJnaW46IDRweCA4
+cHg7Cn0KCi5yZXJ1bi1taWdyYXRpb24gLnJlcXVpcmVkIHsKICBkaXNwbGF5OiBub25lOwp9CgoubmVl
+ZHMtcmVydW4gLnJlcnVuLW1pZ3JhdGlvbiAucmVxdWlyZWQgewogIGRpc3BsYXk6IGluaXRpYWw7Cn0K
+Ci5uZWVkcy1yZXJ1biAucmVydW4tbWlncmF0aW9uIC5vcHRpb25hbCB7CiAgZGlzcGxheTpub25lOwp9
+Cgpmb290ZXIgewogIGNvbG9yOiAjY2NjOwogIGJhY2tncm91bmQtY29sb3I6ICMyNzMyM2E7CiAgZGlz
+cGxheTogZmxleDsKICBmbGV4LWRpcmVjdGlvbjogcm93OwogIGFsaWduLWl0ZW1zOiBjZW50ZXI7CiAg
+cGFkZGluZzogOHB4IDAgOHB4IDI0cHg7Cn0KCmZvb3RlciAud2lkZSB7CiAgZmxleDogMTsKfQoKZm9v
+dGVyIC5zZGstdmVyc2lvbiB7CiAgbWFyZ2luLXJpZ2h0OiAzMnB4Owp9CgouaG9yaXpvbnRhbCB7CiAg
+ZGlzcGxheTogZmxleDsKfQoKLnBhbmVscyB7CiAgYmFja2dyb3VuZC1jb2xvcjogIzEyMWEyNTsKICBm
+bGV4OiAxOwogIG92ZXJmbG93OiBoaWRkZW47Cn0KCi5wYW5lbC1oZWFkaW5nIHsKICBjb2xvcjogIzY3
+Njc2NzsKICBtYXJnaW46IDhweDsKfQoKLm5hdi1saW5rLAoucmVnaW9uIHsKICBjdXJzb3I6IHBvaW50
+ZXI7Cn0KCi5uYXYtcGFuZWwgewogIGJhY2tncm91bmQtY29sb3I6ICMxMjIwMmY7CiAgZmxleDogMSAy
+MDBweDsKICBtYXJnaW46IDA7CiAgb3ZlcmZsb3c6IHNjcm9sbDsKICB1c2VyLXNlbGVjdDogbm9uZTsK
+fQoKLm5hdi1pbm5lciB7CiAgcGFkZGluZzogMCAwIDdweCA3cHg7Cn0KCi5maXhlZCB7CiAgcG9zaXRp
+b246IGZpeGVkOwogIHRvcDogMDsKfQoKLnJvb3QgewogIG1hcmdpbjogMDsKICBkaXNwbGF5OiBub25l
+Owp9CgoubmF2LXRyZWUgPiB1bCB7CiAgcGFkZGluZy1sZWZ0OiA2cHg7Cn0KCi5uYXYtdHJlZSAubWF0
+ZXJpYWwtaWNvbnMgewogIGZvbnQtc2l6ZTogMjBweDsKICBwb3NpdGlvbjogcmVsYXRpdmU7CiAgdG9w
+OiA1cHg7CiAgbWFyZ2luLXJpZ2h0OiA4cHg7CiAgY29sb3I6ICM2NzY3Njc7IC8qICRzZWNvbmRhcnkt
+Y29sb3IgKi8KfQoKLnN0YXR1cy1pY29uLmFscmVhZHktbWlncmF0ZWQgewogIGNvbG9yOiAjMDA3YTI3
+OyAvKiAkbGlnaHQtZ3JlZW4gKi8KfQoKLnN0YXR1cy1pY29uLm9wdGVkLW91dCB7CiAgY29sb3I6ICM2
+NzY3Njc7IC8qICRzZWNvbmRhcnktY29sb3IgKi8KfQoKLnN0YXR1cy1pY29uLm9wdGVkLW91dDpob3Zl
+ciB7CiAgY29sb3I6ICNmZmZmZmY7Cn0KCi5zdGF0dXMtaWNvbi5taWdyYXRpbmcgewogIGNvbG9yOiAj
+NTFjNjg2OyAvKiAkZGFyay1ncmVlbiAqLwp9Cgouc3RhdHVzLWljb24ubWlncmF0aW5nOmhvdmVyIHsK
+ICBjb2xvcjogI2ZmZmZmZjsKfQoKLm5hdi1pbm5lciB1bCB7CiAgcGFkZGluZy1sZWZ0OiAxMnB4Owog
+IG1hcmdpbjogMDsKfQoKLm5hdi1pbm5lciBsaSB7CiAgbGlzdC1zdHlsZS10eXBlOiBub25lOwogIHdo
+aXRlLXNwYWNlOiBub3dyYXA7Cn0KCi5uYXYtaW5uZXIgbGk6bm90KC5kaXIpIHsKICBtYXJnaW4tbGVm
+dDogMjBweDsKICBtYXJnaW4tYm90dG9tOiAzcHg7Cn0KCi5uYXYtaW5uZXIgbGkuZGlyIC5hcnJvdyB7
+CiAgY3Vyc29yOiBwb2ludGVyOwogIGRpc3BsYXk6IGlubGluZS1ibG9jazsKICBmb250LXNpemU6IDEw
+cHg7CiAgbWFyZ2luLXJpZ2h0OiA0cHg7CiAgdHJhbnNpdGlvbjogdHJhbnNmb3JtIDAuNXMgZWFzZS1v
+dXQ7Cn0KCi5uYXYtaW5uZXIgbGkuZGlyIC5hcnJvdy5jb2xsYXBzZWQgewogIHRyYW5zZm9ybTogcm90
+YXRlKC05MGRlZyk7Cn0KCi5uYXYtaW5uZXIgdWwgewogIC8qIGEgbWF4LWhlaWdodCBpcyBhZGRlZCB0
+byBlYWNoIGVsZW1lbnQgYXQgcnVudGltZS4gKi8KICB0cmFuc2l0aW9uOiBtYXgtaGVpZ2h0IDAuNXMg
+ZWFzZS1vdXQ7Cn0KCi5uYXYtaW5uZXIgdWwuY29sbGFwc2VkIHsKICBtYXgtaGVpZ2h0OiAwICFpbXBv
+cnRhbnQ7CiAgb3ZlcmZsb3c6IGhpZGRlbjsKfQoKLm5hdi1pbm5lciAuc2VsZWN0ZWQtZmlsZSB7CiAg
+Y29sb3I6IHdoaXRlOwogIGN1cnNvcjogaW5oZXJpdDsKICBmb250LXdlaWdodDogNjAwOwogIHRleHQt
+ZGVjb3JhdGlvbjogbm9uZTsKfQoKLmVkaXQtY291bnQgewogIGJhY2tncm91bmQtY29sb3I6ICM2NzY3
+Njc7CiAgYm9yZGVyLXJhZGl1czogMTBweDsKICBjb2xvcjogI2ZmZjsKICBkaXNwbGF5OiBpbmxpbmUt
+YmxvY2s7CiAgZm9udC1zaXplOiAxMXB4OwogIGZvbnQtd2VpZ2h0OiA2MDA7CiAgbWFyZ2luLWxlZnQ6
+IDVweDsKICBtaW4td2lkdGg6IDI1cHg7CiAgcGFkZGluZzogNHB4IDAgMnB4IDA7CiAgdGV4dC1hbGln
+bjogY2VudGVyOwogIGxpbmUtaGVpZ2h0OiAxZW07Cn0KCi5maWxlIHsKICBmbGV4OiA0IDMwMHB4Owog
+IGZvbnQtZmFtaWx5OiAiR29vZ2xlIFNhbnMiLCJSb2JvdG8iLHNhbnMtc2VyaWY7CiAgYmFja2dyb3Vu
+ZDogIzEyMjAyZjsKICBtYXJnaW46IDZweDsKICBvdmVyZmxvdzogc2Nyb2xsOwp9CgoudGl0bGUtYmFy
+IGgzIHsKICBkaXNwbGF5OiBpbmxpbmUtYmxvY2s7CiAgZm9udC13ZWlnaHQ6IDQwMDsKICAvKiBUaGlz
+IGFsaWducyB0aGUgdGl0bGUgdGV4dCB3aXRoIHRoZSBjb250ZW50IHRleHQsIGFjY291bnRpbmcgZm9y
+IHRoZSB3aWR0aAogICAqIG9mIHRoZSBsaW5lIG51bWJlcnMuCiAgICovCiAgbWFyZ2luOiAwLjVlbSAy
+NHB4IDAuNWVtIDYzcHg7Cn0KCi50aXRsZS1iYXIgI21pZ3JhdGUtdW5pdC1zdGF0dXMtaWNvbi1sYWJl
+bCB7CiAgZGlzcGxheTogbm9uZTsKICB1c2VyLXNlbGVjdDogbm9uZTsKfQoKLnRpdGxlLWJhciAjbWln
+cmF0ZS11bml0LXN0YXR1cy1pY29uLWxhYmVsLnZpc2libGUgewogIC8qIENoYW5nZSB0byAnaW5saW5l
+JyB0byBlbmFibGUgdGhlIGluY3JlbWVudGFsIG1pZ3JhdGlvbiBmZWF0dXJlLiAqLwogIGRpc3BsYXk6
+IG5vbmU7Cn0KCi50aXRsZS1iYXIgI21pZ3JhdGUtdW5pdC1zdGF0dXMtaWNvbiB7CiAgdmVydGljYWwt
+YWxpZ246IHRleHQtYm90dG9tOwp9CgouY29udGVudCB7CiAgZm9udC1mYW1pbHk6ICJSb2JvdG8gTW9u
+byIsbW9ub3NwYWNlOwogIHBvc2l0aW9uOiByZWxhdGl2ZTsKICB3aGl0ZS1zcGFjZTogcHJlOwp9Cgou
+Y29kZSB7CiAgcGFkZGluZzogMC41ZW07CiAgcG9zaXRpb246IGFic29sdXRlOwogIGxlZnQ6IDA7CiAg
+dG9wOiAwOwogIG1hcmdpbi1sZWZ0OiA1NnB4Owp9CgouY29kZSAud2VsY29tZSB7CiAgZm9udC1mYW1p
+bHk6ICJHb29nbGUgU2FucyIsIlJvYm90byIsc2Fucy1zZXJpZjsKICBmb250LXNpemU6IDE4cHg7CiAg
+bWFyZ2luLXJpZ2h0OiA2MnB4OwogIGNvbG9yOiAjNzc3Owp9CgouY29kZSAubmF2LWxpbmsgewogIGNv
+bG9yOiAjMTZhZGNhOwogIHRleHQtZGVjb3JhdGlvbi1saW5lOiBub25lOwp9CgouY29kZSAubmF2LWxp
+bms6dmlzaXRlZCB7CiAgY29sb3I6ICMxMzliYjU7IC8qICMxNmFkY2EgZGFya2VuZWQgMTAlICovCiAg
+dGV4dC1kZWNvcmF0aW9uLWxpbmU6IG5vbmU7Cn0KCi5jb2RlIC5uYXYtbGluazpob3ZlciB7CiAgdGV4
+dC1kZWNvcmF0aW9uLWxpbmU6IHVuZGVybGluZTsKICBmb250LXdlaWdodDogNjAwOwp9CgoucmVnaW9u
+cyB7CiAgcGFkZGluZzogMC41ZW07CiAgcG9zaXRpb246IGFic29sdXRlOwogIGxlZnQ6IDA7CiAgdG9w
+OiAwOwp9CgoucmVnaW9ucyB0YWJsZSB7CiAgYm9yZGVyLXNwYWNpbmc6IDA7CiAgZm9udC1zaXplOiBp
+bmhlcml0Owp9CgoucmVnaW9ucyB0ZCB7CiAgYm9yZGVyOiBub25lOwogIC8qIFRoZSBjb250ZW50IG9m
+IHRoZSByZWdpb25zIGlzIG5vdCB2aXNpYmxlOyB0aGUgdXNlciBpbnN0ZWFkIHdpbGwgc2VlIHRoZQog
+ICAqIGhpZ2hsaWdodGVkIGNvcHkgb2YgdGhlIGNvbnRlbnQuICovCiAgY29sb3I6IHJnYmEoMjU1LCAy
+NTUsIDI1NSwgMCk7CiAgcGFkZGluZzogMDsKICB3aGl0ZS1zcGFjZTogcHJlOwp9CgoucmVnaW9ucyB0
+ZDplbXB0eTphZnRlciB7CiAgY29udGVudDogIlwwMGEwIjsKfQoKLnJlZ2lvbnMgdHIuaGlnaGxpZ2h0
+IHRkOmxhc3QtY2hpbGQgewogIGJhY2tncm91bmQtY29sb3I6ICM0NDQ0NDQ7CiAgY29sb3I6IHdoaXRl
+Owp9CgoucmVnaW9ucyB0ZC5saW5lLW5vIHsKICBib3JkZXItcmlnaHQ6IHNvbGlkICMxMjIwMmYgMnB4
+OwogIGNvbG9yOiAjOTk5OTk5OwogIHBhZGRpbmctcmlnaHQ6IDRweDsKICB0ZXh0LWFsaWduOiByaWdo
+dDsKICB2aXNpYmlsaXR5OiB2aXNpYmxlOwogIHdpZHRoOiA1MHB4OwogIGRpc3BsYXk6IGlubGluZS1i
+bG9jazsKfQoKLnJlZ2lvbnMgdHIuaGlnaGxpZ2h0IHRkLmxpbmUtbm8gewogIGJvcmRlci1yaWdodDog
+c29saWQgI2NjYyAycHg7Cn0KCi5yZWdpb24gewogIGRpc3BsYXk6IGlubGluZS1ibG9jazsKICBwb3Np
+dGlvbjogcmVsYXRpdmU7CiAgdmlzaWJpbGl0eTogdmlzaWJsZTsKICB6LWluZGV4OiAyMDA7Cn0KCi5y
+ZWdpb24uYWRkZWQtcmVnaW9uIHsKICBiYWNrZ3JvdW5kLWNvbG9yOiAjMTc4YWZkOwogIGNvbG9yOiAj
+ZmZmOwp9CgoucmVnaW9uLnJlbW92ZWQtcmVnaW9uIHsKICBiYWNrZ3JvdW5kLWNvbG9yOiAjRkE1NTdk
+OyAvKiAkZGFyay1waW5rICovCiAgY29sb3I6ICNmZmY7Cn0KCi5yZWdpb24uaW5mb3JtYXRpdmUtcmVn
+aW9uIHsKICBiYWNrZ3JvdW5kLWNvbG9yOiAjMjYzOTUyOwogIGNvbG9yOiAjZmZmOwogIGRpc3BsYXk6
+IGlubGluZS1ibG9jazsKICBoZWlnaHQ6IDE1cHg7CiAgcG9zaXRpb246IHJlbGF0aXZlOwp9CgoudGFy
+Z2V0IHsKICBiYWNrZ3JvdW5kLWNvbG9yOiAjNDQ0OwogIHBvc2l0aW9uOiByZWxhdGl2ZTsKICB2aXNp
+YmlsaXR5OiB2aXNpYmxlOwogIGZvbnQtd2VpZ2h0OiA2MDA7Cn0KCi5pbmZvLXBhbmVsIHsKICBmbGV4
+OiAxIDIwMHB4OwogIG1hcmdpbjogMDsKICBoZWlnaHQ6IDEwMCU7CiAgZGlzcGxheTogZmxleDsKICBm
+bGV4LWRpcmVjdGlvbjogY29sdW1uOwp9CgouaW5mby1wYW5lbCAuZWRpdC1wYW5lbCB7CiAgYmFja2dy
+b3VuZC1jb2xvcjogIzEyMjAyZjsKICBvdmVyZmxvdzogYXV0bzsKfQoKLmluZm8tcGFuZWwgLnBhbmVs
+LWNvbnRlbnQgewogIHBhZGRpbmc6IDdweDsKfQoKLmluZm8tcGFuZWwgLnBhbmVsLWNvbnRlbnQ+IDpm
+aXJzdC1jaGlsZCB7CiAgbWFyZ2luLXRvcDogMDsKfQoKLmluZm8tcGFuZWwgLm5vd3JhcCB7CiAgd2hp
+dGUtc3BhY2U6IG5vd3JhcDsKfQoKLmluZm8tcGFuZWwgdWwsCi5pbmZvLXBhbmVsIG9sIHsKICBwYWRk
+aW5nLWxlZnQ6IDIwcHg7Cn0KCi5pbmZvLXBhbmVsIGxpIHsKICBtYXJnaW46IDAgMCA1cHggMDsKfQoK
+LmluZm8tcGFuZWwgYSB7CiAgY29sb3I6ICMxMzliYjU7Cn0KCi5pbmZvLXBhbmVsIGE6aG92ZXIgewog
+IGNvbG9yOiAjMWVjN2U3OyAvKiAjMTM5YmI1IGxpZ2h0ZW5lZCAyMCUgKi8KfQoKLmluZm8tcGFuZWwg
+LmVkaXQtbGlzdCB7CiAgYmFja2dyb3VuZC1jb2xvcjogIzEyMjAyZjsKICBvdmVyZmxvdzogYXV0bzsK
+fQoKLmVkaXQtcGFuZWwgewogIG1hcmdpbi10b3A6IDZweDsKICBmbGV4OiAxIDEwMHB4Owp9CgouZWRp
+dC1saXN0IHsKICBmbGV4OiAyIDEwMHB4Owp9CgouZWRpdC1saXN0IC5lZGl0IHsKICBtYXJnaW46IDNw
+eCAwOwp9CgouZWRpdC1saXN0IC5lZGl0LWxpbmsgewogIGN1cnNvcjogcG9pbnRlcjsKfQoKLnBvcHVw
+LXBhbmUgewogIGRpc3BsYXk6IG5vbmU7CiAgcG9zaXRpb246IGZpeGVkOwogIHRvcDogMTUwcHg7CiAg
+bGVmdDogMTUwcHg7CiAgcmlnaHQ6IDE1MHB4OwogIGJvdHRvbTogMTUwcHg7CiAgYm9yZGVyOiAxcHgg
+c29saWQgYmxhY2s7CiAgYm9yZGVyLXRvcDogMnB4IHNvbGlkIGJsYWNrOwogIGJvcmRlci1yYWRpdXM6
+IDdweDsKICBib3gtc2hhZG93OiAwcHggMHB4IDIwcHggMnB4ICNiNGJmY2IyMjsKICB6LWluZGV4OiA0
+MDA7CiAgYmFja2dyb3VuZDogIzJiMzAzNjsKICBwYWRkaW5nOiAyMHB4Owp9CgoucG9wdXAtcGFuZSAu
+Y2xvc2UgewogIHBvc2l0aW9uOiBhYnNvbHV0ZTsKICByaWdodDogMTBweDsKICB0b3A6IDEwcHg7CiAg
+Y3Vyc29yOiBwb2ludGVyOwogIHRleHQtc2hhZG93OiAxcHggMXB4IDJweCAjODg4OwogIGJveC1zaGFk
+b3c6IDFweCAxcHggMnB4ICMxMTE7Cn0KCi5wb3B1cC1wYW5lIGgyIHsKICBwYWRkaW5nOiAyMXB4Owog
+IGhlaWdodDogMTAlOwogIG1hcmdpbjogMHB4OwogIGJveC1zaXppbmc6IGJvcmRlci1ib3g7Cn0KCi5w
+b3B1cC1wYW5lIHAgewogIGhlaWdodDogMTAlOwogIGJveC1zaXppbmc6IGJvcmRlci1ib3g7CiAgcGFk
+ZGluZzogMHB4IDIwcHg7Cn0KCi5wb3B1cC1wYW5lIHByZSB7CiAgYmFja2dyb3VuZDogIzEyMjAyZjsK
+ICBwYWRkaW5nOiAyMHB4OwogIGJvdHRvbTogMHB4OwogIG92ZXJmbG93OiBhdXRvIHNjcm9sbDsKICBo
+ZWlnaHQ6IDY1JTsKICBtYXJnaW46IDBweDsKICBib3gtc2l6aW5nOiBib3JkZXItYm94Owp9CgoucG9w
+dXAtcGFuZSAuYnV0dG9uLmJvdHRvbSB7CiAgbWFyZ2luOiAyMHB4IDBweDsKICBkaXNwbGF5OiBibG9j
+azsKICB0ZXh0LWFsaWduOiBjZW50ZXI7Cn0KCi5yZXJ1bm5pbmctcGFuZSB7CiAgZGlzcGxheTogbm9u
+ZTsKfQoKYm9keS5yZXJ1bm5pbmcgLnJlcnVubmluZy1wYW5lIHsKICBkaXNwbGF5OiBibG9jazsKICBw
+b3NpdGlvbjogZml4ZWQ7CiAgdG9wOiAwcHg7CiAgYm90dG9tOiAwcHg7CiAgbGVmdDogMHB4OwogIHJp
+Z2h0OiAwcHg7CiAgYmFja2dyb3VuZC1jb2xvcjogIzAwMDAwMEFBOyAvKiB0cmFuc2x1Y2VudCBibGFj
+ayAqLwogIHotaW5kZXg6IDQwMDsKfQoKLnJlcnVubmluZy1wYW5lIGgxIHsKICBwb3NpdGlvbjogYWJz
+b2x1dGU7CiAgdG9wOiA1MCU7CiAgbGVmdDogNTAlOwogIHRyYW5zZm9ybTogdHJhbnNsYXRlKC01MCUs
+IC01MCUpOwp9CgouZWRpdC1wYW5lbCAudHlwZS1kZXNjcmlwdGlvbiB7CiAgLyogRnJvbSBEYXJ0UGFk
+ICRkYXJrLW9yYW5nZSAqLwogIGNvbG9yOiAjZmY5MTZlOwogIGZvbnQtZmFtaWx5OiBtb25vc3BhY2U7
+Cn0KCnVsLnRyYWNlIHsKICBmb250LXNpemU6IDEzcHg7CiAgbGlzdC1zdHlsZS10eXBlOiBub25lOwog
+IHBhZGRpbmctbGVmdDogMHB4Owp9Cgp1bC50cmFjZSBsaSB7CiAgY29sb3I6IHdoaXRlOwp9Cgp1bC50
+cmFjZSBsaSAuZnVuY3Rpb24gewogIC8qIGZyb20gLmhsanMtdmFyaWFibGUgKi8KICBjb2xvcjogIzE2
+YWRjYTsKICBmb250LWZhbWlseTogbW9ub3NwYWNlOwogIGZvbnQtd2VpZ2h0OiA2MDA7Cn0KCnVsLnRy
+YWNlIGxpIHAuZHJhd2VyIHsKICBtYXJnaW46IDNweCAwcHg7CiAgcGFkZGluZzogMHB4IDBweCAwcHgg
+MTRweDsKfQoKdWwudHJhY2UgbGkgcC5kcmF3ZXIgYnV0dG9uIHsKICBtYXJnaW4tcmlnaHQ6IDNweDsK
+fQoKLmVsZXZhdGlvbi16NCB7CiAgYm94LXNoYWRvdzogMHB4IDJweCA0cHggLTFweCByZ2JhKDAsIDAs
+IDAsIDAuMiksCiAgICAgIDBweCA0cHggNXB4IDBweCByZ2JhKDAsIDAsIDAsIDAuMTQpLAogICAgICAw
+cHggMXB4IDEwcHggMHB4IHJnYmEoMCwgMCwgMCwgLjEyKTsKfQoKYSB7CiAgY29sb3I6ICNjY2M7CiAg
+ZmlsbDogI2NjYzsKICB0ZXh0LWRlY29yYXRpb246IG5vbmU7Cn0KCmE6aG92ZXIgewogIGNvbG9yOiAj
+ZGJkYmRiOyAvKiAjY2NjIGxpZ2h0ZW50ZWQgMzAlKi8KICBmaWxsOiAjZmZmOwp9CgouYWRkLWhpbnQt
+bGluayB7CiAgZGlzcGxheTogaW5saW5lLWJsb2NrOwogIG1hcmdpbjogM3B4Owp9CgouYWRkLWhpbnQt
+bGluazpob3ZlciB7CiAgY29sb3I6ICNmZmY7Cn0KCmhlYWRlciBidXR0b24gewogIHRleHQtdHJhbnNm
+b3JtOiB1cHBlcmNhc2U7Cn0KCmhlYWRlciBhIHsKICBtYXJnaW46IDA7Cn0KCi8qIENhcmVmdWwgaGVy
+ZS4gYGEuYnV0dG9uYCBpcyByZXBldGl0aXZlIGJ1dCByZXF1aXJlZCB0byBnZXQgY29ycmVjdAogKiBz
+cGVjaWZpY2l0eSAqLwpidXR0b24sIC5idXR0b24sIGEuYnV0dG9uIHsKICBiYWNrZ3JvdW5kLWNvbG9y
+OiByZ2JhKDIyLCAxMzgsIDI1MywgMC4xNSk7CiAgYm9yZGVyOiBub25lOwogIGJvcmRlci1yYWRpdXM6
+IDNweDsKICBwYWRkaW5nOiAzcHggMTBweDsKICBmb250LXdlaWdodDogNTAwOwogIGZvbnQtZm9udDog
+Um9ib3RvLCBzYW5zLXNlcmlmOwogIGNvbG9yOiAjZmZmOwp9CgpidXR0b246aG92ZXIsIC5idXR0b246
+aG92ZXIgewogIGJhY2tncm91bmQtY29sb3I6IHJnYmEoMjIsIDEzOCwgMjUzLCAwLjI5KTsKICBjdXJz
+b3I6IHBvaW50ZXI7Cn0KCmJ1dHRvbltkaXNhYmxlZF0gewogIGJhY2tncm91bmQtY29sb3I6IHJnYmEo
+MjU1LDI1NSwyNTUsLjEyKTsKICBjb2xvcjogcmdiYSgyNTUsMjU1LDI1NSwuMzcpOwogIGN1cnNvcjog
+bm90LWFsbG93ZWQ7Cn0KCi8qIENoYW5nZSBlZGl0IHBhbmVsIGJ1dHRvbiBjb2xvcnMgKi8KLmVkaXQt
+cGFuZWwgLmJ1dHRvbiwgLmVkaXQtcGFuZWwgYnV0dG9uIHsKICBiYWNrZ3JvdW5kLWNvbG9yOiByZ2Jh
+KDYzLCAxMDQsIDE0OCwgMC42KTsKICBjb2xvcjogd2hpdGU7Cn0KLmVkaXQtcGFuZWwgLmJ1dHRvbjpo
+b3ZlciwgLmVkaXQtcGFuZWwgYnV0dG9uOmhvdmVyIHsKICBiYWNrZ3JvdW5kLWNvbG9yOiByZ2JhKDEw
+MSwgMTUzLCAyMDgsIDAuNik7CiAgY29sb3I6IHdoaXRlOwp9CgovKgogKiBBZGp1c3RtZW50cyB0byBh
+bGlnbiBtYXRlcmlhbCBpY29ucyBpbiB0aGUgdG9vbGJhciBidXR0b25zLgoqLwouYWN0aW9uLWJ1dHRv
+biA+IHNwYW4gewogIHBvc2l0aW9uOiByZWxhdGl2ZTsKICB0b3A6IC0zcHg7Cn0KCi5hY3Rpb24tYnV0
+dG9uIC5tYXRlcmlhbC1pY29ucyB7CiAgdG9wOiA0cHg7Cn0KCi8qIERvbid0IHNoaWZ0IHRoZSBpY29u
+IHdoZW4gaXQncyBhIGRpcmVjdCBjaGlsZCBvZiB0aGUgYnV0dG9uICovCi5hY3Rpb24tYnV0dG9uID4g
+Lm1hdGVyaWFsLWljb25zIHsKICB0b3A6IDFweDsKfQoKLyogU2hpZnQgdGhlIHRleHQgdG8gY2VudGVy
+IHdpdGggdGhlIGljb24uICovCi5hY3Rpb24tYnV0dG9uID4gc3Bhbi5sYWJlbCB7CiAgcG9zaXRpb246
+cmVsYXRpdmU7CiAgdG9wOiAtNHB4Owp9CgouYWN0aW9uLWJ1dHRvbiAubWF0ZXJpYWwtaWNvbnMgewog
+IGZvbnQtc2l6ZTogMjBweDsKICBwb3NpdGlvbjogcmVsYXRpdmU7Cn0KCi5wbGFjZWhvbGRlciB7CiAg
+Y29sb3I6ICM3Nzc7CiAgdGV4dC1hbGlnbjogY2VudGVyOwogIG1hcmdpbi10b3A6IDNlbSAhaW1wb3J0
+YW50Owp9CgovKioKICogSExKUyBPdmVycmlkZXMKICovCi5obGpzIHsKICBiYWNrZ3JvdW5kLWNvbG9y
+OiAjMTIyMDJmOyAvKiAkZGFyay1jb2RlLWJhY2tncm91bmQtY29sb3IgKi8KICBjb2xvcjogI2MwYzJj
+NTsgLyogJGRhcmstZWRpdG9yLXRleHQgKi8KICBkaXNwbGF5OiBibG9jazsKICBvdmVyZmxvdy14OiBh
+dXRvOwogIHBhZGRpbmc6IDAuNWVtOwogIC8qKgogICAqIFRoaXMgYWxsb3dzIHRoZSBwZXItbGluZSBo
+aWdobGlnaHRzIHRvIHNob3cuCiAgICovCiAgYmFja2dyb3VuZDogbm9uZTsKfQoKLmhsanMta2V5d29y
+ZCwKLmhsanMtc2VsZWN0b3ItdGFnLAouaGxqcy1kZWxldGlvbiB7CiAgY29sb3I6ICM1MWM2ODY7IC8q
+IGNtLWtleXdvcmQgKi8KfQoKLmhsanMtbnVtYmVyIHsKICBjb2xvcjogIzYyNzk3ODsgLyogY20tbnVt
+YmVyICovCn0KCi5obGpzLWNvbW1lbnQgewogIGNvbG9yOiAjOTE5OGI0OyAvKiBjbS1jb21tZW50ICov
+Cn0KCi5obGpzLWxpdGVyYWwgewogIGNvbG9yOiAjZWU4NjY2OyAvKiBjbS1hdG9tICovCn0KCi5obGpz
+LXN0cmluZyB7CiAgY29sb3I6ICNlNTUwNzQ7IC8qIGNtLXN0cmluZyAqLwp9CgouaGxqcy12YXJpYWJs
+ZSB7CiAgY29sb3I6ICMxNmFkY2E7IC8qIGNtLXZhcmlhYmxlICovCn0KCi5obGpzLWxpbmsgewogIGNv
+bG9yOiAjZTU1MDc0OyAvKiBjbS1zdHJpbmcgKi8KfQouaGxqcy1zZWN0aW9uLAouaGxqcy10eXBlLAou
+aGxqcy1idWlsdF9pbiwKLmhsanMtdGl0bGUgewogIGNvbG9yOiAjZWU4NjY2OyAvKiBjbS12YXJpYWJs
+ZS0yICovCn0KCi5obGpzLWFkZGl0aW9uIHsKICBjb2xvcjogIzI2Mzk1MjsgLyogJGRhcmstc2VsZWN0
+aW9uLWNvbG9yICovCn0KCi5obGpzLW1ldGEgewogIGNvbG9yOiAjNjI3OTc4Owp9Cg==
 ''';
 
 String _migration_js;
-// migration_dart md5 is 'd3aab70422b08e7815a20fda6689a30f'
+// migration_dart md5 is 'fd54888536280a9cc3c222ccaf1597fa'
 String _migration_js_base64 = '''
 KGZ1bmN0aW9uIGRhcnRQcm9ncmFtKCl7ZnVuY3Rpb24gY29weVByb3BlcnRpZXMoYSxiKXt2YXIgcz1P
 YmplY3Qua2V5cyhhKQpmb3IodmFyIHI9MDtyPHMubGVuZ3RoO3IrKyl7dmFyIHE9c1tyXQpiW3FdPWFb
@@ -7946,2807 +7959,2830 @@
 OmZ1bmN0aW9uKGEpe3ZhciBzCmlmKGEgaW5zdGFuY2VvZiBILmJxKXJldHVybiBhLmIKaWYoYT09bnVs
 bClyZXR1cm4gbmV3IEguWE8oYSkKcz1hLiRjYWNoZWRUcmFjZQppZihzIT1udWxsKXJldHVybiBzCnJl
 dHVybiBhLiRjYWNoZWRUcmFjZT1uZXcgSC5YTyhhKX0sCkI3OmZ1bmN0aW9uKGEsYil7dmFyIHMscixx
-LHA9YS5sZW5ndGgKZm9yKHM9MDtzPHA7cz1xKXtyPXMrMQpxPXIrMQpiLlkoMCxhW3NdLGFbcl0pfXJl
-dHVybiBifSwKZnQ6ZnVuY3Rpb24oYSxiLGMsZCxlLGYpe3QuWS5hKGEpCnN3aXRjaChILnVQKGIpKXtj
-YXNlIDA6cmV0dXJuIGEuJDAoKQpjYXNlIDE6cmV0dXJuIGEuJDEoYykKY2FzZSAyOnJldHVybiBhLiQy
-KGMsZCkKY2FzZSAzOnJldHVybiBhLiQzKGMsZCxlKQpjYXNlIDQ6cmV0dXJuIGEuJDQoYyxkLGUsZil9
-dGhyb3cgSC5iKG5ldyBQLkNEKCJVbnN1cHBvcnRlZCBudW1iZXIgb2YgYXJndW1lbnRzIGZvciB3cmFw
-cGVkIGNsb3N1cmUiKSl9LAp0UjpmdW5jdGlvbihhLGIpe3ZhciBzCmlmKGE9PW51bGwpcmV0dXJuIG51
-bGwKcz1hLiRpZGVudGl0eQppZighIXMpcmV0dXJuIHMKcz1mdW5jdGlvbihjLGQsZSl7cmV0dXJuIGZ1
-bmN0aW9uKGYsZyxoLGkpe3JldHVybiBlKGMsZCxmLGcsaCxpKX19KGEsYixILmZ0KQphLiRpZGVudGl0
-eT1zCnJldHVybiBzfSwKaUE6ZnVuY3Rpb24oYSxiLGMsZCxlLGYsZyl7dmFyIHMscixxLHAsbyxuLG0s
-bD1iWzBdLGs9bC4kY2FsbE5hbWUsaj1lP09iamVjdC5jcmVhdGUobmV3IEguengoKS5jb25zdHJ1Y3Rv
-ci5wcm90b3R5cGUpOk9iamVjdC5jcmVhdGUobmV3IEguclQobnVsbCxudWxsLG51bGwsIiIpLmNvbnN0
-cnVjdG9yLnByb3RvdHlwZSkKai4kaW5pdGlhbGl6ZT1qLmNvbnN0cnVjdG9yCmlmKGUpcz1mdW5jdGlv
-biBzdGF0aWNfdGVhcl9vZmYoKXt0aGlzLiRpbml0aWFsaXplKCl9CmVsc2V7cj0kLnlqCmlmKHR5cGVv
-ZiByIT09Im51bWJlciIpcmV0dXJuIHIuaCgpCiQueWo9cisxCnI9bmV3IEZ1bmN0aW9uKCJhLGIsYyxk
-IityLCJ0aGlzLiRpbml0aWFsaXplKGEsYixjLGQiK3IrIikiKQpzPXJ9ai5jb25zdHJ1Y3Rvcj1zCnMu
-cHJvdG90eXBlPWoKaWYoIWUpe3E9SC5ieChhLGwsZikKcS4kcmVmbGVjdGlvbkluZm89ZH1lbHNle2ou
-JHN0YXRpY19uYW1lPWcKcT1sfWouJFM9SC5pbShkLGUsZikKaltrXT1xCmZvcihwPXEsbz0xO288Yi5s
-ZW5ndGg7KytvKXtuPWJbb10KbT1uLiRjYWxsTmFtZQppZihtIT1udWxsKXtuPWU/bjpILmJ4KGEsbixm
-KQpqW21dPW59aWYobz09PWMpe24uJHJlZmxlY3Rpb25JbmZvPWQKcD1ufX1qLiRDPXAKai4kUj1sLiRS
-CmouJEQ9bC4kRApyZXR1cm4gc30sCmltOmZ1bmN0aW9uKGEsYixjKXt2YXIgcwppZih0eXBlb2YgYT09
-Im51bWJlciIpcmV0dXJuIGZ1bmN0aW9uKGQsZSl7cmV0dXJuIGZ1bmN0aW9uKCl7cmV0dXJuIGQoZSl9
-fShILkJwLGEpCmlmKHR5cGVvZiBhPT0ic3RyaW5nIil7aWYoYil0aHJvdyBILmIoIkNhbm5vdCBjb21w
-dXRlIHNpZ25hdHVyZSBmb3Igc3RhdGljIHRlYXJvZmYuIikKcz1jP0guUFc6SC5UbgpyZXR1cm4gZnVu
-Y3Rpb24oZCxlKXtyZXR1cm4gZnVuY3Rpb24oKXtyZXR1cm4gZSh0aGlzLGQpfX0oYSxzKX10aHJvdyBI
-LmIoIkVycm9yIGluIGZ1bmN0aW9uVHlwZSBvZiB0ZWFyb2ZmIil9LAp2cTpmdW5jdGlvbihhLGIsYyxk
-KXt2YXIgcz1ILkRWCnN3aXRjaChiPy0xOmEpe2Nhc2UgMDpyZXR1cm4gZnVuY3Rpb24oZSxmKXtyZXR1
-cm4gZnVuY3Rpb24oKXtyZXR1cm4gZih0aGlzKVtlXSgpfX0oYyxzKQpjYXNlIDE6cmV0dXJuIGZ1bmN0
-aW9uKGUsZil7cmV0dXJuIGZ1bmN0aW9uKGcpe3JldHVybiBmKHRoaXMpW2VdKGcpfX0oYyxzKQpjYXNl
-IDI6cmV0dXJuIGZ1bmN0aW9uKGUsZil7cmV0dXJuIGZ1bmN0aW9uKGcsaCl7cmV0dXJuIGYodGhpcylb
-ZV0oZyxoKX19KGMscykKY2FzZSAzOnJldHVybiBmdW5jdGlvbihlLGYpe3JldHVybiBmdW5jdGlvbihn
-LGgsaSl7cmV0dXJuIGYodGhpcylbZV0oZyxoLGkpfX0oYyxzKQpjYXNlIDQ6cmV0dXJuIGZ1bmN0aW9u
-KGUsZil7cmV0dXJuIGZ1bmN0aW9uKGcsaCxpLGope3JldHVybiBmKHRoaXMpW2VdKGcsaCxpLGopfX0o
-YyxzKQpjYXNlIDU6cmV0dXJuIGZ1bmN0aW9uKGUsZil7cmV0dXJuIGZ1bmN0aW9uKGcsaCxpLGosayl7
-cmV0dXJuIGYodGhpcylbZV0oZyxoLGksaixrKX19KGMscykKZGVmYXVsdDpyZXR1cm4gZnVuY3Rpb24o
-ZSxmKXtyZXR1cm4gZnVuY3Rpb24oKXtyZXR1cm4gZS5hcHBseShmKHRoaXMpLGFyZ3VtZW50cyl9fShk
-LHMpfX0sCmJ4OmZ1bmN0aW9uKGEsYixjKXt2YXIgcyxyLHEscCxvLG4sbQppZihjKXJldHVybiBILkhm
-KGEsYikKcz1iLiRzdHViTmFtZQpyPWIubGVuZ3RoCnE9YVtzXQpwPWI9PW51bGw/cT09bnVsbDpiPT09
-cQpvPSFwfHxyPj0yNwppZihvKXJldHVybiBILnZxKHIsIXAscyxiKQppZihyPT09MCl7cD0kLnlqCmlm
-KHR5cGVvZiBwIT09Im51bWJlciIpcmV0dXJuIHAuaCgpCiQueWo9cCsxCm49InNlbGYiK3AKcmV0dXJu
-IG5ldyBGdW5jdGlvbigicmV0dXJuIGZ1bmN0aW9uKCl7dmFyICIrbisiID0gdGhpcy4iK0guRWooSC5v
-TigpKSsiO3JldHVybiAiK24rIi4iK0guRWoocykrIigpO30iKSgpfW09ImFiY2RlZmdoaWprbG1ub3Bx
-cnN0dXZ3eHl6Ii5zcGxpdCgiIikuc3BsaWNlKDAscikuam9pbigiLCIpCnA9JC55agppZih0eXBlb2Yg
-cCE9PSJudW1iZXIiKXJldHVybiBwLmgoKQokLnlqPXArMQptKz1wCnJldHVybiBuZXcgRnVuY3Rpb24o
-InJldHVybiBmdW5jdGlvbigiK20rIil7cmV0dXJuIHRoaXMuIitILkVqKEgub04oKSkrIi4iK0guRWoo
-cykrIigiK20rIik7fSIpKCl9LApaNDpmdW5jdGlvbihhLGIsYyxkKXt2YXIgcz1ILkRWLHI9SC55Uwpz
-d2l0Y2goYj8tMTphKXtjYXNlIDA6dGhyb3cgSC5iKG5ldyBILkVxKCJJbnRlcmNlcHRlZCBmdW5jdGlv
-biB3aXRoIG5vIGFyZ3VtZW50cy4iKSkKY2FzZSAxOnJldHVybiBmdW5jdGlvbihlLGYsZyl7cmV0dXJu
-IGZ1bmN0aW9uKCl7cmV0dXJuIGYodGhpcylbZV0oZyh0aGlzKSl9fShjLHMscikKY2FzZSAyOnJldHVy
-biBmdW5jdGlvbihlLGYsZyl7cmV0dXJuIGZ1bmN0aW9uKGgpe3JldHVybiBmKHRoaXMpW2VdKGcodGhp
-cyksaCl9fShjLHMscikKY2FzZSAzOnJldHVybiBmdW5jdGlvbihlLGYsZyl7cmV0dXJuIGZ1bmN0aW9u
-KGgsaSl7cmV0dXJuIGYodGhpcylbZV0oZyh0aGlzKSxoLGkpfX0oYyxzLHIpCmNhc2UgNDpyZXR1cm4g
-ZnVuY3Rpb24oZSxmLGcpe3JldHVybiBmdW5jdGlvbihoLGksail7cmV0dXJuIGYodGhpcylbZV0oZyh0
-aGlzKSxoLGksail9fShjLHMscikKY2FzZSA1OnJldHVybiBmdW5jdGlvbihlLGYsZyl7cmV0dXJuIGZ1
-bmN0aW9uKGgsaSxqLGspe3JldHVybiBmKHRoaXMpW2VdKGcodGhpcyksaCxpLGosayl9fShjLHMscikK
-Y2FzZSA2OnJldHVybiBmdW5jdGlvbihlLGYsZyl7cmV0dXJuIGZ1bmN0aW9uKGgsaSxqLGssbCl7cmV0
-dXJuIGYodGhpcylbZV0oZyh0aGlzKSxoLGksaixrLGwpfX0oYyxzLHIpCmRlZmF1bHQ6cmV0dXJuIGZ1
-bmN0aW9uKGUsZixnLGgpe3JldHVybiBmdW5jdGlvbigpe2g9W2codGhpcyldCkFycmF5LnByb3RvdHlw
-ZS5wdXNoLmFwcGx5KGgsYXJndW1lbnRzKQpyZXR1cm4gZS5hcHBseShmKHRoaXMpLGgpfX0oZCxzLHIp
-fX0sCkhmOmZ1bmN0aW9uKGEsYil7dmFyIHMscixxLHAsbyxuLG09SC5vTigpLGw9JC5QNAppZihsPT1u
-dWxsKWw9JC5QND1ILkUyKCJyZWNlaXZlciIpCnM9Yi4kc3R1Yk5hbWUKcj1iLmxlbmd0aApxPWFbc10K
-cD1iPT1udWxsP3E9PW51bGw6Yj09PXEKbz0hcHx8cj49MjgKaWYobylyZXR1cm4gSC5aNChyLCFwLHMs
-YikKaWYocj09PTEpe3A9InJldHVybiBmdW5jdGlvbigpe3JldHVybiB0aGlzLiIrSC5FaihtKSsiLiIr
-SC5FaihzKSsiKHRoaXMuIitsKyIpOyIKbz0kLnlqCmlmKHR5cGVvZiBvIT09Im51bWJlciIpcmV0dXJu
-IG8uaCgpCiQueWo9bysxCnJldHVybiBuZXcgRnVuY3Rpb24ocCtvKyJ9IikoKX1uPSJhYmNkZWZnaGlq
-a2xtbm9wcXJzdHV2d3h5eiIuc3BsaXQoIiIpLnNwbGljZSgwLHItMSkuam9pbigiLCIpCnA9InJldHVy
-biBmdW5jdGlvbigiK24rIil7cmV0dXJuIHRoaXMuIitILkVqKG0pKyIuIitILkVqKHMpKyIodGhpcy4i
-K2wrIiwgIituKyIpOyIKbz0kLnlqCmlmKHR5cGVvZiBvIT09Im51bWJlciIpcmV0dXJuIG8uaCgpCiQu
-eWo9bysxCnJldHVybiBuZXcgRnVuY3Rpb24ocCtvKyJ9IikoKX0sCktxOmZ1bmN0aW9uKGEsYixjLGQs
-ZSxmLGcpe3JldHVybiBILmlBKGEsYixjLGQsISFlLCEhZixnKX0sClRuOmZ1bmN0aW9uKGEsYil7cmV0
-dXJuIEguY0Uodi50eXBlVW5pdmVyc2UsSC56KGEuYSksYil9LApQVzpmdW5jdGlvbihhLGIpe3JldHVy
-biBILmNFKHYudHlwZVVuaXZlcnNlLEgueihhLmMpLGIpfSwKRFY6ZnVuY3Rpb24oYSl7cmV0dXJuIGEu
-YX0sCnlTOmZ1bmN0aW9uKGEpe3JldHVybiBhLmN9LApvTjpmdW5jdGlvbigpe3ZhciBzPSQubUoKcmV0
-dXJuIHM9PW51bGw/JC5tSj1ILkUyKCJzZWxmIik6c30sCkUyOmZ1bmN0aW9uKGEpe3ZhciBzLHIscSxw
-PW5ldyBILnJUKCJzZWxmIiwidGFyZ2V0IiwicmVjZWl2ZXIiLCJuYW1lIiksbz1KLkVwKE9iamVjdC5n
-ZXRPd25Qcm9wZXJ0eU5hbWVzKHApLHQuVykKZm9yKHM9by5sZW5ndGgscj0wO3I8czsrK3Ipe3E9b1ty
-XQppZihwW3FdPT09YSlyZXR1cm4gcX10aHJvdyBILmIoUC54WSgiRmllbGQgbmFtZSAiK2ErIiBub3Qg
-Zm91bmQuIikpfSwKb1Q6ZnVuY3Rpb24oYSl7aWYoYT09bnVsbClILmZPKCJib29sZWFuIGV4cHJlc3Np
-b24gbXVzdCBub3QgYmUgbnVsbCIpCnJldHVybiBhfSwKZk86ZnVuY3Rpb24oYSl7dGhyb3cgSC5iKG5l
-dyBILmtZKGEpKX0sCmFnOmZ1bmN0aW9uKGEpe3Rocm93IEguYihuZXcgUC5jKGEpKX0sCllnOmZ1bmN0
-aW9uKGEpe3JldHVybiB2LmdldElzb2xhdGVUYWcoYSl9LApCbzpmdW5jdGlvbihhKXtyZXR1cm4gSC52
-KG5ldyBILm4oYSkpfSwKaXc6ZnVuY3Rpb24oYSxiLGMpe09iamVjdC5kZWZpbmVQcm9wZXJ0eShhLGIs
-e3ZhbHVlOmMsZW51bWVyYWJsZTpmYWxzZSx3cml0YWJsZTp0cnVlLGNvbmZpZ3VyYWJsZTp0cnVlfSl9
-LAp3MzpmdW5jdGlvbihhKXt2YXIgcyxyLHEscCxvLG49SC5oKCQuTkYuJDEoYSkpLG09JC5ud1tuXQpp
+LHA9YS5sZW5ndGgKZm9yKHM9MDtzPHA7cz1xKXtyPXMrMQpxPXIrMQpiLlk1KDAsYVtzXSxhW3JdKX1y
+ZXR1cm4gYn0sCmZ0OmZ1bmN0aW9uKGEsYixjLGQsZSxmKXt0LlkuYShhKQpzd2l0Y2goSC51UChiKSl7
+Y2FzZSAwOnJldHVybiBhLiQwKCkKY2FzZSAxOnJldHVybiBhLiQxKGMpCmNhc2UgMjpyZXR1cm4gYS4k
+MihjLGQpCmNhc2UgMzpyZXR1cm4gYS4kMyhjLGQsZSkKY2FzZSA0OnJldHVybiBhLiQ0KGMsZCxlLGYp
+fXRocm93IEguYihuZXcgUC5DRCgiVW5zdXBwb3J0ZWQgbnVtYmVyIG9mIGFyZ3VtZW50cyBmb3Igd3Jh
+cHBlZCBjbG9zdXJlIikpfSwKdFI6ZnVuY3Rpb24oYSxiKXt2YXIgcwppZihhPT1udWxsKXJldHVybiBu
+dWxsCnM9YS4kaWRlbnRpdHkKaWYoISFzKXJldHVybiBzCnM9ZnVuY3Rpb24oYyxkLGUpe3JldHVybiBm
+dW5jdGlvbihmLGcsaCxpKXtyZXR1cm4gZShjLGQsZixnLGgsaSl9fShhLGIsSC5mdCkKYS4kaWRlbnRp
+dHk9cwpyZXR1cm4gc30sCmlBOmZ1bmN0aW9uKGEsYixjLGQsZSxmLGcpe3ZhciBzLHIscSxwLG8sbixt
+LGw9YlswXSxrPWwuJGNhbGxOYW1lLGo9ZT9PYmplY3QuY3JlYXRlKG5ldyBILnp4KCkuY29uc3RydWN0
+b3IucHJvdG90eXBlKTpPYmplY3QuY3JlYXRlKG5ldyBILnJUKG51bGwsbnVsbCxudWxsLCIiKS5jb25z
+dHJ1Y3Rvci5wcm90b3R5cGUpCmouJGluaXRpYWxpemU9ai5jb25zdHJ1Y3RvcgppZihlKXM9ZnVuY3Rp
+b24gc3RhdGljX3RlYXJfb2ZmKCl7dGhpcy4kaW5pdGlhbGl6ZSgpfQplbHNle3I9JC55agppZih0eXBl
+b2YgciE9PSJudW1iZXIiKXJldHVybiByLmgoKQokLnlqPXIrMQpyPW5ldyBGdW5jdGlvbigiYSxiLGMs
+ZCIrciwidGhpcy4kaW5pdGlhbGl6ZShhLGIsYyxkIityKyIpIikKcz1yfWouY29uc3RydWN0b3I9cwpz
+LnByb3RvdHlwZT1qCmlmKCFlKXtxPUguYngoYSxsLGYpCnEuJHJlZmxlY3Rpb25JbmZvPWR9ZWxzZXtq
+LiRzdGF0aWNfbmFtZT1nCnE9bH1qLiRTPUguaW0oZCxlLGYpCmpba109cQpmb3IocD1xLG89MTtvPGIu
+bGVuZ3RoOysrbyl7bj1iW29dCm09bi4kY2FsbE5hbWUKaWYobSE9bnVsbCl7bj1lP246SC5ieChhLG4s
+ZikKalttXT1ufWlmKG89PT1jKXtuLiRyZWZsZWN0aW9uSW5mbz1kCnA9bn19ai4kQz1wCmouJFI9bC4k
+UgpqLiREPWwuJEQKcmV0dXJuIHN9LAppbTpmdW5jdGlvbihhLGIsYyl7dmFyIHMKaWYodHlwZW9mIGE9
+PSJudW1iZXIiKXJldHVybiBmdW5jdGlvbihkLGUpe3JldHVybiBmdW5jdGlvbigpe3JldHVybiBkKGUp
+fX0oSC5CcCxhKQppZih0eXBlb2YgYT09InN0cmluZyIpe2lmKGIpdGhyb3cgSC5iKCJDYW5ub3QgY29t
+cHV0ZSBzaWduYXR1cmUgZm9yIHN0YXRpYyB0ZWFyb2ZmLiIpCnM9Yz9ILlBXOkguVG4KcmV0dXJuIGZ1
+bmN0aW9uKGQsZSl7cmV0dXJuIGZ1bmN0aW9uKCl7cmV0dXJuIGUodGhpcyxkKX19KGEscyl9dGhyb3cg
+SC5iKCJFcnJvciBpbiBmdW5jdGlvblR5cGUgb2YgdGVhcm9mZiIpfSwKdnE6ZnVuY3Rpb24oYSxiLGMs
+ZCl7dmFyIHM9SC5EVgpzd2l0Y2goYj8tMTphKXtjYXNlIDA6cmV0dXJuIGZ1bmN0aW9uKGUsZil7cmV0
+dXJuIGZ1bmN0aW9uKCl7cmV0dXJuIGYodGhpcylbZV0oKX19KGMscykKY2FzZSAxOnJldHVybiBmdW5j
+dGlvbihlLGYpe3JldHVybiBmdW5jdGlvbihnKXtyZXR1cm4gZih0aGlzKVtlXShnKX19KGMscykKY2Fz
+ZSAyOnJldHVybiBmdW5jdGlvbihlLGYpe3JldHVybiBmdW5jdGlvbihnLGgpe3JldHVybiBmKHRoaXMp
+W2VdKGcsaCl9fShjLHMpCmNhc2UgMzpyZXR1cm4gZnVuY3Rpb24oZSxmKXtyZXR1cm4gZnVuY3Rpb24o
+ZyxoLGkpe3JldHVybiBmKHRoaXMpW2VdKGcsaCxpKX19KGMscykKY2FzZSA0OnJldHVybiBmdW5jdGlv
+bihlLGYpe3JldHVybiBmdW5jdGlvbihnLGgsaSxqKXtyZXR1cm4gZih0aGlzKVtlXShnLGgsaSxqKX19
+KGMscykKY2FzZSA1OnJldHVybiBmdW5jdGlvbihlLGYpe3JldHVybiBmdW5jdGlvbihnLGgsaSxqLGsp
+e3JldHVybiBmKHRoaXMpW2VdKGcsaCxpLGosayl9fShjLHMpCmRlZmF1bHQ6cmV0dXJuIGZ1bmN0aW9u
+KGUsZil7cmV0dXJuIGZ1bmN0aW9uKCl7cmV0dXJuIGUuYXBwbHkoZih0aGlzKSxhcmd1bWVudHMpfX0o
+ZCxzKX19LApieDpmdW5jdGlvbihhLGIsYyl7dmFyIHMscixxLHAsbyxuLG0KaWYoYylyZXR1cm4gSC5I
+ZihhLGIpCnM9Yi4kc3R1Yk5hbWUKcj1iLmxlbmd0aApxPWFbc10KcD1iPT1udWxsP3E9PW51bGw6Yj09
+PXEKbz0hcHx8cj49MjcKaWYobylyZXR1cm4gSC52cShyLCFwLHMsYikKaWYocj09PTApe3A9JC55agpp
+Zih0eXBlb2YgcCE9PSJudW1iZXIiKXJldHVybiBwLmgoKQokLnlqPXArMQpuPSJzZWxmIitwCnJldHVy
+biBuZXcgRnVuY3Rpb24oInJldHVybiBmdW5jdGlvbigpe3ZhciAiK24rIiA9IHRoaXMuIitILkVqKEgu
+b04oKSkrIjtyZXR1cm4gIituKyIuIitILkVqKHMpKyIoKTt9IikoKX1tPSJhYmNkZWZnaGlqa2xtbm9w
+cXJzdHV2d3h5eiIuc3BsaXQoIiIpLnNwbGljZSgwLHIpLmpvaW4oIiwiKQpwPSQueWoKaWYodHlwZW9m
+IHAhPT0ibnVtYmVyIilyZXR1cm4gcC5oKCkKJC55aj1wKzEKbSs9cApyZXR1cm4gbmV3IEZ1bmN0aW9u
+KCJyZXR1cm4gZnVuY3Rpb24oIittKyIpe3JldHVybiB0aGlzLiIrSC5FaihILm9OKCkpKyIuIitILkVq
+KHMpKyIoIittKyIpO30iKSgpfSwKWjQ6ZnVuY3Rpb24oYSxiLGMsZCl7dmFyIHM9SC5EVixyPUgueVMK
+c3dpdGNoKGI/LTE6YSl7Y2FzZSAwOnRocm93IEguYihuZXcgSC5FcSgiSW50ZXJjZXB0ZWQgZnVuY3Rp
+b24gd2l0aCBubyBhcmd1bWVudHMuIikpCmNhc2UgMTpyZXR1cm4gZnVuY3Rpb24oZSxmLGcpe3JldHVy
+biBmdW5jdGlvbigpe3JldHVybiBmKHRoaXMpW2VdKGcodGhpcykpfX0oYyxzLHIpCmNhc2UgMjpyZXR1
+cm4gZnVuY3Rpb24oZSxmLGcpe3JldHVybiBmdW5jdGlvbihoKXtyZXR1cm4gZih0aGlzKVtlXShnKHRo
+aXMpLGgpfX0oYyxzLHIpCmNhc2UgMzpyZXR1cm4gZnVuY3Rpb24oZSxmLGcpe3JldHVybiBmdW5jdGlv
+bihoLGkpe3JldHVybiBmKHRoaXMpW2VdKGcodGhpcyksaCxpKX19KGMscyxyKQpjYXNlIDQ6cmV0dXJu
+IGZ1bmN0aW9uKGUsZixnKXtyZXR1cm4gZnVuY3Rpb24oaCxpLGope3JldHVybiBmKHRoaXMpW2VdKGco
+dGhpcyksaCxpLGopfX0oYyxzLHIpCmNhc2UgNTpyZXR1cm4gZnVuY3Rpb24oZSxmLGcpe3JldHVybiBm
+dW5jdGlvbihoLGksaixrKXtyZXR1cm4gZih0aGlzKVtlXShnKHRoaXMpLGgsaSxqLGspfX0oYyxzLHIp
+CmNhc2UgNjpyZXR1cm4gZnVuY3Rpb24oZSxmLGcpe3JldHVybiBmdW5jdGlvbihoLGksaixrLGwpe3Jl
+dHVybiBmKHRoaXMpW2VdKGcodGhpcyksaCxpLGosayxsKX19KGMscyxyKQpkZWZhdWx0OnJldHVybiBm
+dW5jdGlvbihlLGYsZyxoKXtyZXR1cm4gZnVuY3Rpb24oKXtoPVtnKHRoaXMpXQpBcnJheS5wcm90b3R5
+cGUucHVzaC5hcHBseShoLGFyZ3VtZW50cykKcmV0dXJuIGUuYXBwbHkoZih0aGlzKSxoKX19KGQscyxy
+KX19LApIZjpmdW5jdGlvbihhLGIpe3ZhciBzLHIscSxwLG8sbixtPUgub04oKSxsPSQuUDQKaWYobD09
+bnVsbClsPSQuUDQ9SC5FMigicmVjZWl2ZXIiKQpzPWIuJHN0dWJOYW1lCnI9Yi5sZW5ndGgKcT1hW3Nd
+CnA9Yj09bnVsbD9xPT1udWxsOmI9PT1xCm89IXB8fHI+PTI4CmlmKG8pcmV0dXJuIEguWjQociwhcCxz
+LGIpCmlmKHI9PT0xKXtwPSJyZXR1cm4gZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy4iK0guRWoobSkrIi4i
+K0guRWoocykrIih0aGlzLiIrbCsiKTsiCm89JC55agppZih0eXBlb2YgbyE9PSJudW1iZXIiKXJldHVy
+biBvLmgoKQokLnlqPW8rMQpyZXR1cm4gbmV3IEZ1bmN0aW9uKHArbysifSIpKCl9bj0iYWJjZGVmZ2hp
+amtsbW5vcHFyc3R1dnd4eXoiLnNwbGl0KCIiKS5zcGxpY2UoMCxyLTEpLmpvaW4oIiwiKQpwPSJyZXR1
+cm4gZnVuY3Rpb24oIituKyIpe3JldHVybiB0aGlzLiIrSC5FaihtKSsiLiIrSC5FaihzKSsiKHRoaXMu
+IitsKyIsICIrbisiKTsiCm89JC55agppZih0eXBlb2YgbyE9PSJudW1iZXIiKXJldHVybiBvLmgoKQok
+LnlqPW8rMQpyZXR1cm4gbmV3IEZ1bmN0aW9uKHArbysifSIpKCl9LApLcTpmdW5jdGlvbihhLGIsYyxk
+LGUsZixnKXtyZXR1cm4gSC5pQShhLGIsYyxkLCEhZSwhIWYsZyl9LApUbjpmdW5jdGlvbihhLGIpe3Jl
+dHVybiBILmNFKHYudHlwZVVuaXZlcnNlLEgueihhLmEpLGIpfSwKUFc6ZnVuY3Rpb24oYSxiKXtyZXR1
+cm4gSC5jRSh2LnR5cGVVbml2ZXJzZSxILnooYS5jKSxiKX0sCkRWOmZ1bmN0aW9uKGEpe3JldHVybiBh
+LmF9LAp5UzpmdW5jdGlvbihhKXtyZXR1cm4gYS5jfSwKb046ZnVuY3Rpb24oKXt2YXIgcz0kLm1KCnJl
+dHVybiBzPT1udWxsPyQubUo9SC5FMigic2VsZiIpOnN9LApFMjpmdW5jdGlvbihhKXt2YXIgcyxyLHEs
+cD1uZXcgSC5yVCgic2VsZiIsInRhcmdldCIsInJlY2VpdmVyIiwibmFtZSIpLG89Si5FcChPYmplY3Qu
+Z2V0T3duUHJvcGVydHlOYW1lcyhwKSx0LlcpCmZvcihzPW8ubGVuZ3RoLHI9MDtyPHM7KytyKXtxPW9b
+cl0KaWYocFtxXT09PWEpcmV0dXJuIHF9dGhyb3cgSC5iKFAueFkoIkZpZWxkIG5hbWUgIithKyIgbm90
+IGZvdW5kLiIpKX0sCm9UOmZ1bmN0aW9uKGEpe2lmKGE9PW51bGwpSC5mTygiYm9vbGVhbiBleHByZXNz
+aW9uIG11c3Qgbm90IGJlIG51bGwiKQpyZXR1cm4gYX0sCmZPOmZ1bmN0aW9uKGEpe3Rocm93IEguYihu
+ZXcgSC5rWShhKSl9LAphZzpmdW5jdGlvbihhKXt0aHJvdyBILmIobmV3IFAuYyhhKSl9LApZZzpmdW5j
+dGlvbihhKXtyZXR1cm4gdi5nZXRJc29sYXRlVGFnKGEpfSwKQm86ZnVuY3Rpb24oYSl7cmV0dXJuIEgu
+dihuZXcgSC5uKGEpKX0sCml3OmZ1bmN0aW9uKGEsYixjKXtPYmplY3QuZGVmaW5lUHJvcGVydHkoYSxi
+LHt2YWx1ZTpjLGVudW1lcmFibGU6ZmFsc2Usd3JpdGFibGU6dHJ1ZSxjb25maWd1cmFibGU6dHJ1ZX0p
+fSwKdzM6ZnVuY3Rpb24oYSl7dmFyIHMscixxLHAsbyxuPUguaCgkLk5GLiQxKGEpKSxtPSQubndbbl0K
+aWYobSE9bnVsbCl7T2JqZWN0LmRlZmluZVByb3BlcnR5KGEsdi5kaXNwYXRjaFByb3BlcnR5TmFtZSx7
+dmFsdWU6bSxlbnVtZXJhYmxlOmZhbHNlLHdyaXRhYmxlOnRydWUsY29uZmlndXJhYmxlOnRydWV9KQpy
+ZXR1cm4gbS5pfXM9JC52dltuXQppZihzIT1udWxsKXJldHVybiBzCnI9di5pbnRlcmNlcHRvcnNCeVRh
+Z1tuXQppZihyPT1udWxsKXtxPUguaygkLlRYLiQyKGEsbikpCmlmKHEhPW51bGwpe209JC5ud1txXQpp
 ZihtIT1udWxsKXtPYmplY3QuZGVmaW5lUHJvcGVydHkoYSx2LmRpc3BhdGNoUHJvcGVydHlOYW1lLHt2
 YWx1ZTptLGVudW1lcmFibGU6ZmFsc2Usd3JpdGFibGU6dHJ1ZSxjb25maWd1cmFibGU6dHJ1ZX0pCnJl
-dHVybiBtLml9cz0kLnZ2W25dCmlmKHMhPW51bGwpcmV0dXJuIHMKcj12LmludGVyY2VwdG9yc0J5VGFn
-W25dCmlmKHI9PW51bGwpe3E9SC5rKCQuVFguJDIoYSxuKSkKaWYocSE9bnVsbCl7bT0kLm53W3FdCmlm
-KG0hPW51bGwpe09iamVjdC5kZWZpbmVQcm9wZXJ0eShhLHYuZGlzcGF0Y2hQcm9wZXJ0eU5hbWUse3Zh
-bHVlOm0sZW51bWVyYWJsZTpmYWxzZSx3cml0YWJsZTp0cnVlLGNvbmZpZ3VyYWJsZTp0cnVlfSkKcmV0
-dXJuIG0uaX1zPSQudnZbcV0KaWYocyE9bnVsbClyZXR1cm4gcwpyPXYuaW50ZXJjZXB0b3JzQnlUYWdb
-cV0Kbj1xfX1pZihyPT1udWxsKXJldHVybiBudWxsCnM9ci5wcm90b3R5cGUKcD1uWzBdCmlmKHA9PT0i
-ISIpe209SC5WYShzKQokLm53W25dPW0KT2JqZWN0LmRlZmluZVByb3BlcnR5KGEsdi5kaXNwYXRjaFBy
-b3BlcnR5TmFtZSx7dmFsdWU6bSxlbnVtZXJhYmxlOmZhbHNlLHdyaXRhYmxlOnRydWUsY29uZmlndXJh
-YmxlOnRydWV9KQpyZXR1cm4gbS5pfWlmKHA9PT0ifiIpeyQudnZbbl09cwpyZXR1cm4gc31pZihwPT09
-Ii0iKXtvPUguVmEocykKT2JqZWN0LmRlZmluZVByb3BlcnR5KE9iamVjdC5nZXRQcm90b3R5cGVPZihh
-KSx2LmRpc3BhdGNoUHJvcGVydHlOYW1lLHt2YWx1ZTpvLGVudW1lcmFibGU6ZmFsc2Usd3JpdGFibGU6
-dHJ1ZSxjb25maWd1cmFibGU6dHJ1ZX0pCnJldHVybiBvLml9aWYocD09PSIrIilyZXR1cm4gSC5MYyhh
-LHMpCmlmKHA9PT0iKiIpdGhyb3cgSC5iKFAuU1kobikpCmlmKHYubGVhZlRhZ3Nbbl09PT10cnVlKXtv
-PUguVmEocykKT2JqZWN0LmRlZmluZVByb3BlcnR5KE9iamVjdC5nZXRQcm90b3R5cGVPZihhKSx2LmRp
-c3BhdGNoUHJvcGVydHlOYW1lLHt2YWx1ZTpvLGVudW1lcmFibGU6ZmFsc2Usd3JpdGFibGU6dHJ1ZSxj
-b25maWd1cmFibGU6dHJ1ZX0pCnJldHVybiBvLml9ZWxzZSByZXR1cm4gSC5MYyhhLHMpfSwKTGM6ZnVu
-Y3Rpb24oYSxiKXt2YXIgcz1PYmplY3QuZ2V0UHJvdG90eXBlT2YoYSkKT2JqZWN0LmRlZmluZVByb3Bl
-cnR5KHMsdi5kaXNwYXRjaFByb3BlcnR5TmFtZSx7dmFsdWU6Si5RdShiLHMsbnVsbCxudWxsKSxlbnVt
-ZXJhYmxlOmZhbHNlLHdyaXRhYmxlOnRydWUsY29uZmlndXJhYmxlOnRydWV9KQpyZXR1cm4gYn0sClZh
-OmZ1bmN0aW9uKGEpe3JldHVybiBKLlF1KGEsITEsbnVsbCwhIWEuJGlYail9LApWRjpmdW5jdGlvbihh
-LGIsYyl7dmFyIHM9Yi5wcm90b3R5cGUKaWYodi5sZWFmVGFnc1thXT09PXRydWUpcmV0dXJuIEguVmEo
-cykKZWxzZSByZXR1cm4gSi5RdShzLGMsbnVsbCxudWxsKX0sClhEOmZ1bmN0aW9uKCl7aWYoITA9PT0k
-LkJ2KXJldHVybgokLkJ2PSEwCkguWjEoKX0sCloxOmZ1bmN0aW9uKCl7dmFyIHMscixxLHAsbyxuLG0s
-bAokLm53PU9iamVjdC5jcmVhdGUobnVsbCkKJC52dj1PYmplY3QuY3JlYXRlKG51bGwpCkgua08oKQpz
-PXYuaW50ZXJjZXB0b3JzQnlUYWcKcj1PYmplY3QuZ2V0T3duUHJvcGVydHlOYW1lcyhzKQppZih0eXBl
-b2Ygd2luZG93IT0idW5kZWZpbmVkIil7d2luZG93CnE9ZnVuY3Rpb24oKXt9CmZvcihwPTA7cDxyLmxl
-bmd0aDsrK3Ape289cltwXQpuPSQueDcuJDEobykKaWYobiE9bnVsbCl7bT1ILlZGKG8sc1tvXSxuKQpp
-ZihtIT1udWxsKXtPYmplY3QuZGVmaW5lUHJvcGVydHkobix2LmRpc3BhdGNoUHJvcGVydHlOYW1lLHt2
-YWx1ZTptLGVudW1lcmFibGU6ZmFsc2Usd3JpdGFibGU6dHJ1ZSxjb25maWd1cmFibGU6dHJ1ZX0pCnEu
-cHJvdG90eXBlPW59fX19Zm9yKHA9MDtwPHIubGVuZ3RoOysrcCl7bz1yW3BdCmlmKC9eW0EtWmEtel9d
-Ly50ZXN0KG8pKXtsPXNbb10Kc1siISIrb109bApzWyJ+IitvXT1sCnNbIi0iK29dPWwKc1siKyIrb109
-bApzWyIqIitvXT1sfX19LAprTzpmdW5jdGlvbigpe3ZhciBzLHIscSxwLG8sbixtPUMuWXEoKQptPUgu
-dWQoQy5LVSxILnVkKEMuZlEsSC51ZChDLmk3LEgudWQoQy5pNyxILnVkKEMueGksSC51ZChDLmRrLEgu
-dWQoQy53YihDLk80KSxtKSkpKSkpKQppZih0eXBlb2YgZGFydE5hdGl2ZURpc3BhdGNoSG9va3NUcmFu
-c2Zvcm1lciE9InVuZGVmaW5lZCIpe3M9ZGFydE5hdGl2ZURpc3BhdGNoSG9va3NUcmFuc2Zvcm1lcgpp
-Zih0eXBlb2Ygcz09ImZ1bmN0aW9uIilzPVtzXQppZihzLmNvbnN0cnVjdG9yPT1BcnJheSlmb3Iocj0w
-O3I8cy5sZW5ndGg7KytyKXtxPXNbcl0KaWYodHlwZW9mIHE9PSJmdW5jdGlvbiIpbT1xKG0pfHxtfX1w
-PW0uZ2V0VGFnCm89bS5nZXRVbmtub3duVGFnCm49bS5wcm90b3R5cGVGb3JUYWcKJC5ORj1uZXcgSC5k
-QyhwKQokLlRYPW5ldyBILndOKG8pCiQueDc9bmV3IEguVlgobil9LAp1ZDpmdW5jdGlvbihhLGIpe3Jl
-dHVybiBhKGIpfHxifSwKdjQ6ZnVuY3Rpb24oYSxiLGMsZCxlLGYpe3ZhciBzPWI/Im0iOiIiLHI9Yz8i
-IjoiaSIscT1kPyJ1IjoiIixwPWU/InMiOiIiLG89Zj8iZyI6IiIsbj1mdW5jdGlvbihnLGgpe3RyeXty
-ZXR1cm4gbmV3IFJlZ0V4cChnLGgpfWNhdGNoKG0pe3JldHVybiBtfX0oYSxzK3IrcStwK28pCmlmKG4g
-aW5zdGFuY2VvZiBSZWdFeHApcmV0dXJuIG4KdGhyb3cgSC5iKFAucnIoIklsbGVnYWwgUmVnRXhwIHBh
-dHRlcm4gKCIrU3RyaW5nKG4pKyIpIixhLG51bGwpKX0sClNROmZ1bmN0aW9uKGEsYixjKXt2YXIgcwpp
-Zih0eXBlb2YgYj09InN0cmluZyIpcmV0dXJuIGEuaW5kZXhPZihiLGMpPj0wCmVsc2UgaWYoYiBpbnN0
-YW5jZW9mIEguVlIpe3M9Qy54Qi5HKGEsYykKcmV0dXJuIGIuYi50ZXN0KHMpfWVsc2V7cz1KLkZMKGIs
-Qy54Qi5HKGEsYykpCnJldHVybiFzLmdsMChzKX19LApBNDpmdW5jdGlvbihhKXtpZihhLmluZGV4T2Yo
-IiQiLDApPj0wKXJldHVybiBhLnJlcGxhY2UoL1wkL2csIiQkJCQiKQpyZXR1cm4gYX0sCmVBOmZ1bmN0
-aW9uKGEpe2lmKC9bW1xde30oKSorPy5cXF4kfF0vLnRlc3QoYSkpcmV0dXJuIGEucmVwbGFjZSgvW1tc
-XXt9KCkqKz8uXFxeJHxdL2csIlxcJCYiKQpyZXR1cm4gYX0sCnlzOmZ1bmN0aW9uKGEsYixjKXt2YXIg
-cz1ILm5NKGEsYixjKQpyZXR1cm4gc30sCm5NOmZ1bmN0aW9uKGEsYixjKXt2YXIgcyxyLHEscAppZihi
-PT09IiIpe2lmKGE9PT0iIilyZXR1cm4gYwpzPWEubGVuZ3RoCmZvcihyPWMscT0wO3E8czsrK3Epcj1y
-K2FbcV0rYwpyZXR1cm4gci5jaGFyQ29kZUF0KDApPT0wP3I6cn1wPWEuaW5kZXhPZihiLDApCmlmKHA8
-MClyZXR1cm4gYQppZihhLmxlbmd0aDw1MDB8fGMuaW5kZXhPZigiJCIsMCk+PTApcmV0dXJuIGEuc3Bs
-aXQoYikuam9pbihjKQpyZXR1cm4gYS5yZXBsYWNlKG5ldyBSZWdFeHAoSC5lQShiKSwnZycpLEguQTQo
-YykpfSwKUEQ6ZnVuY3Rpb24gUEQoYSxiKXt0aGlzLmE9YQp0aGlzLiR0aT1ifSwKV1U6ZnVuY3Rpb24g
-V1UoKXt9LApMUDpmdW5jdGlvbiBMUChhLGIsYyxkKXt2YXIgXz10aGlzCl8uYT1hCl8uYj1iCl8uYz1j
-Cl8uJHRpPWR9LApYUjpmdW5jdGlvbiBYUihhLGIpe3RoaXMuYT1hCnRoaXMuJHRpPWJ9LApMSTpmdW5j
-dGlvbiBMSShhLGIsYyxkLGUpe3ZhciBfPXRoaXMKXy5hPWEKXy5jPWIKXy5kPWMKXy5lPWQKXy5mPWV9
-LApDajpmdW5jdGlvbiBDaihhLGIsYyl7dGhpcy5hPWEKdGhpcy5iPWIKdGhpcy5jPWN9LApmOTpmdW5j
-dGlvbiBmOShhLGIsYyxkLGUsZil7dmFyIF89dGhpcwpfLmE9YQpfLmI9YgpfLmM9YwpfLmQ9ZApfLmU9
-ZQpfLmY9Zn0sClcwOmZ1bmN0aW9uIFcwKGEsYil7dGhpcy5hPWEKdGhpcy5iPWJ9LAphejpmdW5jdGlv
-biBheihhLGIsYyl7dGhpcy5hPWEKdGhpcy5iPWIKdGhpcy5jPWN9LAp2VjpmdW5jdGlvbiB2VihhKXt0
-aGlzLmE9YX0sCnRlOmZ1bmN0aW9uIHRlKGEpe3RoaXMuYT1hfSwKYnE6ZnVuY3Rpb24gYnEoYSxiKXt0
-aGlzLmE9YQp0aGlzLmI9Yn0sClhPOmZ1bmN0aW9uIFhPKGEpe3RoaXMuYT1hCnRoaXMuYj1udWxsfSwK
-VHA6ZnVuY3Rpb24gVHAoKXt9LApsYzpmdW5jdGlvbiBsYygpe30sCnp4OmZ1bmN0aW9uIHp4KCl7fSwK
-clQ6ZnVuY3Rpb24gclQoYSxiLGMsZCl7dmFyIF89dGhpcwpfLmE9YQpfLmI9YgpfLmM9YwpfLmQ9ZH0s
-CkVxOmZ1bmN0aW9uIEVxKGEpe3RoaXMuYT1hfSwKa1k6ZnVuY3Rpb24ga1koYSl7dGhpcy5hPWF9LApr
-cjpmdW5jdGlvbiBrcigpe30sCk41OmZ1bmN0aW9uIE41KGEpe3ZhciBfPXRoaXMKXy5hPTAKXy5mPV8u
-ZT1fLmQ9Xy5jPV8uYj1udWxsCl8ucj0wCl8uJHRpPWF9LAp2aDpmdW5jdGlvbiB2aChhLGIpe3ZhciBf
-PXRoaXMKXy5hPWEKXy5iPWIKXy5kPV8uYz1udWxsfSwKaTU6ZnVuY3Rpb24gaTUoYSxiKXt0aGlzLmE9
-YQp0aGlzLiR0aT1ifSwKTjY6ZnVuY3Rpb24gTjYoYSxiLGMpe3ZhciBfPXRoaXMKXy5hPWEKXy5iPWIK
-Xy5kPV8uYz1udWxsCl8uJHRpPWN9LApkQzpmdW5jdGlvbiBkQyhhKXt0aGlzLmE9YX0sCndOOmZ1bmN0
-aW9uIHdOKGEpe3RoaXMuYT1hfSwKVlg6ZnVuY3Rpb24gVlgoYSl7dGhpcy5hPWF9LApWUjpmdW5jdGlv
-biBWUihhLGIpe3ZhciBfPXRoaXMKXy5hPWEKXy5iPWIKXy5kPV8uYz1udWxsfSwKRUs6ZnVuY3Rpb24g
-RUsoYSl7dGhpcy5iPWF9LApLVzpmdW5jdGlvbiBLVyhhLGIsYyl7dGhpcy5hPWEKdGhpcy5iPWIKdGhp
-cy5jPWN9LApQYjpmdW5jdGlvbiBQYihhLGIsYyl7dmFyIF89dGhpcwpfLmE9YQpfLmI9YgpfLmM9Ywpf
-LmQ9bnVsbH0sCnRROmZ1bmN0aW9uIHRRKGEsYil7dGhpcy5hPWEKdGhpcy5jPWJ9LAp1bjpmdW5jdGlv
-biB1bihhLGIsYyl7dGhpcy5hPWEKdGhpcy5iPWIKdGhpcy5jPWN9LApTZDpmdW5jdGlvbiBTZChhLGIs
-Yyl7dmFyIF89dGhpcwpfLmE9YQpfLmI9YgpfLmM9YwpfLmQ9bnVsbH0sClhGOmZ1bmN0aW9uKGEpe3Jl
-dHVybiBhfSwKb2Q6ZnVuY3Rpb24oYSxiLGMpe2lmKGE+Pj4wIT09YXx8YT49Yyl0aHJvdyBILmIoSC5I
-WShiLGEpKX0sCnJNOmZ1bmN0aW9uKGEsYixjKXt2YXIgcwppZighKGE+Pj4wIT09YSkpcz1iPj4+MCE9
-PWJ8fGE+Ynx8Yj5jCmVsc2Ugcz0hMAppZihzKXRocm93IEguYihILmF1KGEsYixjKSkKcmV0dXJuIGJ9
-LApFVDpmdW5jdGlvbiBFVCgpe30sCkxaOmZ1bmN0aW9uIExaKCl7fSwKRGc6ZnVuY3Rpb24gRGcoKXt9
-LApQZzpmdW5jdGlvbiBQZygpe30sCnhqOmZ1bmN0aW9uIHhqKCl7fSwKZEU6ZnVuY3Rpb24gZEUoKXt9
-LApaQTpmdW5jdGlvbiBaQSgpe30sCmRUOmZ1bmN0aW9uIGRUKCl7fSwKUHE6ZnVuY3Rpb24gUHEoKXt9
-LAplRTpmdW5jdGlvbiBlRSgpe30sClY2OmZ1bmN0aW9uIFY2KCl7fSwKUkc6ZnVuY3Rpb24gUkcoKXt9
-LApWUDpmdW5jdGlvbiBWUCgpe30sCldCOmZ1bmN0aW9uIFdCKCl7fSwKWkc6ZnVuY3Rpb24gWkcoKXt9
-LApjejpmdW5jdGlvbihhLGIpe3ZhciBzPWIuYwpyZXR1cm4gcz09bnVsbD9iLmM9SC5CKGEsYi56LCEw
-KTpzfSwKeFo6ZnVuY3Rpb24oYSxiKXt2YXIgcz1iLmMKcmV0dXJuIHM9PW51bGw/Yi5jPUguSihhLCJi
-OCIsW2Iuel0pOnN9LApRMTpmdW5jdGlvbihhKXt2YXIgcz1hLnkKaWYocz09PTZ8fHM9PT03fHxzPT09
-OClyZXR1cm4gSC5RMShhLnopCnJldHVybiBzPT09MTF8fHM9PT0xMn0sCm1EOmZ1bmN0aW9uKGEpe3Jl
-dHVybiBhLmN5fSwKTjA6ZnVuY3Rpb24oYSl7cmV0dXJuIEguRSh2LnR5cGVVbml2ZXJzZSxhLCExKX0s
-ClBMOmZ1bmN0aW9uKGEsYixhMCxhMSl7dmFyIHMscixxLHAsbyxuLG0sbCxrLGosaSxoLGcsZixlLGQs
-Yz1iLnkKc3dpdGNoKGMpe2Nhc2UgNTpjYXNlIDE6Y2FzZSAyOmNhc2UgMzpjYXNlIDQ6cmV0dXJuIGIK
-Y2FzZSA2OnM9Yi56CnI9SC5QTChhLHMsYTAsYTEpCmlmKHI9PT1zKXJldHVybiBiCnJldHVybiBILkMo
-YSxyLCEwKQpjYXNlIDc6cz1iLnoKcj1ILlBMKGEscyxhMCxhMSkKaWYocj09PXMpcmV0dXJuIGIKcmV0
-dXJuIEguQihhLHIsITApCmNhc2UgODpzPWIuegpyPUguUEwoYSxzLGEwLGExKQppZihyPT09cylyZXR1
-cm4gYgpyZXR1cm4gSC5mKGEsciwhMCkKY2FzZSA5OnE9Yi5RCnA9SC5iWihhLHEsYTAsYTEpCmlmKHA9
-PT1xKXJldHVybiBiCnJldHVybiBILkooYSxiLnoscCkKY2FzZSAxMDpvPWIuegpuPUguUEwoYSxvLGEw
-LGExKQptPWIuUQpsPUguYlooYSxtLGEwLGExKQppZihuPT09byYmbD09PW0pcmV0dXJuIGIKcmV0dXJu
-IEguYShhLG4sbCkKY2FzZSAxMTprPWIuegpqPUguUEwoYSxrLGEwLGExKQppPWIuUQpoPUgucVQoYSxp
-LGEwLGExKQppZihqPT09ayYmaD09PWkpcmV0dXJuIGIKcmV0dXJuIEguZChhLGosaCkKY2FzZSAxMjpn
-PWIuUQphMSs9Zy5sZW5ndGgKZj1ILmJaKGEsZyxhMCxhMSkKbz1iLnoKbj1ILlBMKGEsbyxhMCxhMSkK
-aWYoZj09PWcmJm49PT1vKXJldHVybiBiCnJldHVybiBILkQoYSxuLGYsITApCmNhc2UgMTM6ZT1iLnoK
-aWYoZTxhMSlyZXR1cm4gYgpkPWEwW2UtYTFdCmlmKGQ9PW51bGwpcmV0dXJuIGIKcmV0dXJuIGQKZGVm
-YXVsdDp0aHJvdyBILmIoUC5oVigiQXR0ZW1wdGVkIHRvIHN1YnN0aXR1dGUgdW5leHBlY3RlZCBSVEkg
-a2luZCAiK2MpKX19LApiWjpmdW5jdGlvbihhLGIsYyxkKXt2YXIgcyxyLHEscCxvPWIubGVuZ3RoLG49
-W10KZm9yKHM9ITEscj0wO3I8bzsrK3Ipe3E9YltyXQpwPUguUEwoYSxxLGMsZCkKaWYocCE9PXEpcz0h
-MApuLnB1c2gocCl9cmV0dXJuIHM/bjpifSwKdk86ZnVuY3Rpb24oYSxiLGMsZCl7dmFyIHMscixxLHAs
-byxuLG09Yi5sZW5ndGgsbD1bXQpmb3Iocz0hMSxyPTA7cjxtO3IrPTMpe3E9YltyXQpwPWJbcisxXQpv
-PWJbcisyXQpuPUguUEwoYSxvLGMsZCkKaWYobiE9PW8pcz0hMApsLnB1c2gocSkKbC5wdXNoKHApCmwu
-cHVzaChuKX1yZXR1cm4gcz9sOmJ9LApxVDpmdW5jdGlvbihhLGIsYyxkKXt2YXIgcyxyPWIuYSxxPUgu
-YlooYSxyLGMsZCkscD1iLmIsbz1ILmJaKGEscCxjLGQpLG49Yi5jLG09SC52TyhhLG4sYyxkKQppZihx
-PT09ciYmbz09PXAmJm09PT1uKXJldHVybiBiCnM9bmV3IEguRygpCnMuYT1xCnMuYj1vCnMuYz1tCnJl
-dHVybiBzfSwKVk06ZnVuY3Rpb24oYSxiKXthW3YuYXJyYXlSdGldPWIKcmV0dXJuIGF9LApKUzpmdW5j
-dGlvbihhKXt2YXIgcz1hLiRTCmlmKHMhPW51bGwpe2lmKHR5cGVvZiBzPT0ibnVtYmVyIilyZXR1cm4g
-SC5CcChzKQpyZXR1cm4gYS4kUygpfXJldHVybiBudWxsfSwKVWU6ZnVuY3Rpb24oYSxiKXt2YXIgcwpp
-ZihILlExKGIpKWlmKGEgaW5zdGFuY2VvZiBILlRwKXtzPUguSlMoYSkKaWYocyE9bnVsbClyZXR1cm4g
-c31yZXR1cm4gSC56KGEpfSwKejpmdW5jdGlvbihhKXt2YXIgcwppZihhIGluc3RhbmNlb2YgUC5NaCl7
-cz1hLiR0aQpyZXR1cm4gcyE9bnVsbD9zOkguVlUoYSl9aWYoQXJyYXkuaXNBcnJheShhKSlyZXR1cm4g
-SC50NihhKQpyZXR1cm4gSC5WVShKLmlhKGEpKX0sCnQ2OmZ1bmN0aW9uKGEpe3ZhciBzPWFbdi5hcnJh
-eVJ0aV0scj10LngKaWYocz09bnVsbClyZXR1cm4gcgppZihzLmNvbnN0cnVjdG9yIT09ci5jb25zdHJ1
-Y3RvcilyZXR1cm4gcgpyZXR1cm4gc30sCkxoOmZ1bmN0aW9uKGEpe3ZhciBzPWEuJHRpCnJldHVybiBz
-IT1udWxsP3M6SC5WVShhKX0sClZVOmZ1bmN0aW9uKGEpe3ZhciBzPWEuY29uc3RydWN0b3Iscj1zLiRj
-Y2FjaGUKaWYociE9bnVsbClyZXR1cm4gcgpyZXR1cm4gSC5yOShhLHMpfSwKcjk6ZnVuY3Rpb24oYSxi
-KXt2YXIgcz1hIGluc3RhbmNlb2YgSC5UcD9hLl9fcHJvdG9fXy5fX3Byb3RvX18uY29uc3RydWN0b3I6
-YixyPUguYWkodi50eXBlVW5pdmVyc2Uscy5uYW1lKQpiLiRjY2FjaGU9cgpyZXR1cm4gcn0sCkJwOmZ1
-bmN0aW9uKGEpe3ZhciBzLHIscQpILnVQKGEpCnM9di50eXBlcwpyPXNbYV0KaWYodHlwZW9mIHI9PSJz
-dHJpbmciKXtxPUguRSh2LnR5cGVVbml2ZXJzZSxyLCExKQpzW2FdPXEKcmV0dXJuIHF9cmV0dXJuIHJ9
-LApLeDpmdW5jdGlvbihhKXt2YXIgcyxyLHEscD1hLngKaWYocCE9bnVsbClyZXR1cm4gcApzPWEuY3kK
-cj1zLnJlcGxhY2UoL1wqL2csIiIpCmlmKHI9PT1zKXJldHVybiBhLng9bmV3IEgubFkoYSkKcT1ILkUo
-di50eXBlVW5pdmVyc2UsciwhMCkKcD1xLngKcmV0dXJuIGEueD1wPT1udWxsP3EueD1uZXcgSC5sWShx
-KTpwfSwKSko6ZnVuY3Rpb24oYSl7dmFyIHMscixxPXRoaXMscD10LksKaWYocT09PXApcmV0dXJuIEgu
-UkUocSxhLEgua2UpCmlmKCFILkE4KHEpKWlmKCEocT09PXQuXykpcD1xPT09cAplbHNlIHA9ITAKZWxz
-ZSBwPSEwCmlmKHApcmV0dXJuIEguUkUocSxhLEguSXcpCnA9cS55CnM9cD09PTY/cS56OnEKaWYocz09
-PXQuUylyPUgub2sKZWxzZSBpZihzPT09dC5nUnx8cz09PXQuZGkpcj1ILktICmVsc2UgaWYocz09PXQu
-TilyPUguTU0KZWxzZSByPXM9PT10Lnk/SC5sOm51bGwKaWYociE9bnVsbClyZXR1cm4gSC5SRShxLGEs
-cikKaWYocy55PT09OSl7cD1zLnoKaWYocy5RLmV2ZXJ5KEguY2MpKXtxLnI9IiRpIitwCnJldHVybiBI
-LlJFKHEsYSxILnQ0KX19ZWxzZSBpZihwPT09NylyZXR1cm4gSC5SRShxLGEsSC5BUSkKcmV0dXJuIEgu
-UkUocSxhLEguWU8pfSwKUkU6ZnVuY3Rpb24oYSxiLGMpe2EuYj1jCnJldHVybiBhLmIoYil9LApBdTpm
-dW5jdGlvbihhKXt2YXIgcyxyLHE9dGhpcwppZighSC5BOChxKSlpZighKHE9PT10Ll8pKXM9cT09PXQu
-SwplbHNlIHM9ITAKZWxzZSBzPSEwCmlmKHMpcj1ILmhuCmVsc2UgaWYocT09PXQuSylyPUguVGkKZWxz
-ZSByPUgubDQKcS5hPXIKcmV0dXJuIHEuYShhKX0sClFqOmZ1bmN0aW9uKGEpe3ZhciBzLHI9YS55Cmlm
-KCFILkE4KGEpKWlmKCEoYT09PXQuXykpaWYoIShhPT09dC5jRikpaWYociE9PTcpcz1yPT09OCYmSC5R
-aihhLnopfHxhPT09dC5QfHxhPT09dC5UCmVsc2Ugcz0hMAplbHNlIHM9ITAKZWxzZSBzPSEwCmVsc2Ug
-cz0hMApyZXR1cm4gc30sCllPOmZ1bmN0aW9uKGEpe3ZhciBzPXRoaXMKaWYoYT09bnVsbClyZXR1cm4g
-SC5RaihzKQpyZXR1cm4gSC5XZSh2LnR5cGVVbml2ZXJzZSxILlVlKGEscyksbnVsbCxzLG51bGwpfSwK
-QVE6ZnVuY3Rpb24oYSl7aWYoYT09bnVsbClyZXR1cm4hMApyZXR1cm4gdGhpcy56LmIoYSl9LAp0NDpm
-dW5jdGlvbihhKXt2YXIgcyxyPXRoaXMKaWYoYT09bnVsbClyZXR1cm4gSC5RaihyKQpzPXIucgppZihh
-IGluc3RhbmNlb2YgUC5NaClyZXR1cm4hIWFbc10KcmV0dXJuISFKLmlhKGEpW3NdfSwKT3o6ZnVuY3Rp
-b24oYSl7dmFyIHM9dGhpcwppZihhPT1udWxsKXJldHVybiBhCmVsc2UgaWYocy5iKGEpKXJldHVybiBh
-CkgubTQoYSxzKX0sCmw0OmZ1bmN0aW9uKGEpe3ZhciBzPXRoaXMKaWYoYT09bnVsbClyZXR1cm4gYQpl
-bHNlIGlmKHMuYihhKSlyZXR1cm4gYQpILm00KGEscyl9LAptNDpmdW5jdGlvbihhLGIpe3Rocm93IEgu
-YihILlpjKEguV0soYSxILlVlKGEsYiksSC5kbShiLG51bGwpKSkpfSwKRGg6ZnVuY3Rpb24oYSxiLGMs
-ZCl7dmFyIHM9bnVsbAppZihILldlKHYudHlwZVVuaXZlcnNlLGEscyxiLHMpKXJldHVybiBhCnRocm93
-IEguYihILlpjKCJUaGUgdHlwZSBhcmd1bWVudCAnIitILkVqKEguZG0oYSxzKSkrIicgaXMgbm90IGEg
-c3VidHlwZSBvZiB0aGUgdHlwZSB2YXJpYWJsZSBib3VuZCAnIitILkVqKEguZG0oYixzKSkrIicgb2Yg
-dHlwZSB2YXJpYWJsZSAnIitILkVqKGMpKyInIGluICciK0guRWooZCkrIicuIikpfSwKV0s6ZnVuY3Rp
-b24oYSxiLGMpe3ZhciBzPVAucChhKSxyPUguZG0oYj09bnVsbD9ILnooYSk6YixudWxsKQpyZXR1cm4g
-cysiOiB0eXBlICciK0guRWoocikrIicgaXMgbm90IGEgc3VidHlwZSBvZiB0eXBlICciK0guRWooYykr
-IicifSwKWmM6ZnVuY3Rpb24oYSl7cmV0dXJuIG5ldyBILmlNKCJUeXBlRXJyb3I6ICIrYSl9LApxOmZ1
-bmN0aW9uKGEsYil7cmV0dXJuIG5ldyBILmlNKCJUeXBlRXJyb3I6ICIrSC5XSyhhLG51bGwsYikpfSwK
-a2U6ZnVuY3Rpb24oYSl7cmV0dXJuIGEhPW51bGx9LApUaTpmdW5jdGlvbihhKXtyZXR1cm4gYX0sCkl3
-OmZ1bmN0aW9uKGEpe3JldHVybiEwfSwKaG46ZnVuY3Rpb24oYSl7cmV0dXJuIGF9LApsOmZ1bmN0aW9u
-KGEpe3JldHVybiEwPT09YXx8ITE9PT1hfSwKcDg6ZnVuY3Rpb24oYSl7aWYoITA9PT1hKXJldHVybiEw
-CmlmKCExPT09YSlyZXR1cm4hMQp0aHJvdyBILmIoSC5xKGEsImJvb2wiKSl9LAp5ODpmdW5jdGlvbihh
-KXtpZighMD09PWEpcmV0dXJuITAKaWYoITE9PT1hKXJldHVybiExCmlmKGE9PW51bGwpcmV0dXJuIGEK
-dGhyb3cgSC5iKEgucShhLCJib29sIikpfSwKZHA6ZnVuY3Rpb24oYSl7aWYoITA9PT1hKXJldHVybiEw
-CmlmKCExPT09YSlyZXR1cm4hMQppZihhPT1udWxsKXJldHVybiBhCnRocm93IEguYihILnEoYSwiYm9v
-bD8iKSl9LApGRzpmdW5jdGlvbihhKXtpZih0eXBlb2YgYT09Im51bWJlciIpcmV0dXJuIGEKdGhyb3cg
-SC5iKEgucShhLCJkb3VibGUiKSl9LApHSDpmdW5jdGlvbihhKXtpZih0eXBlb2YgYT09Im51bWJlciIp
-cmV0dXJuIGEKaWYoYT09bnVsbClyZXR1cm4gYQp0aHJvdyBILmIoSC5xKGEsImRvdWJsZSIpKX0sClFr
-OmZ1bmN0aW9uKGEpe2lmKHR5cGVvZiBhPT0ibnVtYmVyIilyZXR1cm4gYQppZihhPT1udWxsKXJldHVy
-biBhCnRocm93IEguYihILnEoYSwiZG91YmxlPyIpKX0sCm9rOmZ1bmN0aW9uKGEpe3JldHVybiB0eXBl
-b2YgYT09Im51bWJlciImJk1hdGguZmxvb3IoYSk9PT1hfSwKSVo6ZnVuY3Rpb24oYSl7aWYodHlwZW9m
-IGE9PSJudW1iZXIiJiZNYXRoLmZsb29yKGEpPT09YSlyZXR1cm4gYQp0aHJvdyBILmIoSC5xKGEsImlu
-dCIpKX0sCnVQOmZ1bmN0aW9uKGEpe2lmKHR5cGVvZiBhPT0ibnVtYmVyIiYmTWF0aC5mbG9vcihhKT09
-PWEpcmV0dXJuIGEKaWYoYT09bnVsbClyZXR1cm4gYQp0aHJvdyBILmIoSC5xKGEsImludCIpKX0sClVj
-OmZ1bmN0aW9uKGEpe2lmKHR5cGVvZiBhPT0ibnVtYmVyIiYmTWF0aC5mbG9vcihhKT09PWEpcmV0dXJu
-IGEKaWYoYT09bnVsbClyZXR1cm4gYQp0aHJvdyBILmIoSC5xKGEsImludD8iKSl9LApLSDpmdW5jdGlv
-bihhKXtyZXR1cm4gdHlwZW9mIGE9PSJudW1iZXIifSwKejU6ZnVuY3Rpb24oYSl7aWYodHlwZW9mIGE9
-PSJudW1iZXIiKXJldHVybiBhCnRocm93IEguYihILnEoYSwibnVtIikpfSwKVzE6ZnVuY3Rpb24oYSl7
-aWYodHlwZW9mIGE9PSJudW1iZXIiKXJldHVybiBhCmlmKGE9PW51bGwpcmV0dXJuIGEKdGhyb3cgSC5i
-KEgucShhLCJudW0iKSl9LApjVTpmdW5jdGlvbihhKXtpZih0eXBlb2YgYT09Im51bWJlciIpcmV0dXJu
-IGEKaWYoYT09bnVsbClyZXR1cm4gYQp0aHJvdyBILmIoSC5xKGEsIm51bT8iKSl9LApNTTpmdW5jdGlv
-bihhKXtyZXR1cm4gdHlwZW9mIGE9PSJzdHJpbmcifSwKQnQ6ZnVuY3Rpb24oYSl7aWYodHlwZW9mIGE9
-PSJzdHJpbmciKXJldHVybiBhCnRocm93IEguYihILnEoYSwiU3RyaW5nIikpfSwKaDpmdW5jdGlvbihh
-KXtpZih0eXBlb2YgYT09InN0cmluZyIpcmV0dXJuIGEKaWYoYT09bnVsbClyZXR1cm4gYQp0aHJvdyBI
-LmIoSC5xKGEsIlN0cmluZyIpKX0sCms6ZnVuY3Rpb24oYSl7aWYodHlwZW9mIGE9PSJzdHJpbmciKXJl
-dHVybiBhCmlmKGE9PW51bGwpcmV0dXJuIGEKdGhyb3cgSC5iKEgucShhLCJTdHJpbmc/IikpfSwKaW86
-ZnVuY3Rpb24oYSxiKXt2YXIgcyxyLHEKZm9yKHM9IiIscj0iIixxPTA7cTxhLmxlbmd0aDsrK3Escj0i
-LCAiKXMrPUMueEIuaChyLEguZG0oYVtxXSxiKSkKcmV0dXJuIHN9LApiSTpmdW5jdGlvbihhNSxhNixh
-Nyl7dmFyIHMscixxLHAsbyxuLG0sbCxrLGosaSxoLGcsZixlLGQsYyxiLGEsYTAsYTEsYTIsYTMsYTQ9
-IiwgIgppZihhNyE9bnVsbCl7cz1hNy5sZW5ndGgKaWYoYTY9PW51bGwpe2E2PUguVk0oW10sdC5zKQpy
-PW51bGx9ZWxzZSByPWE2Lmxlbmd0aApxPWE2Lmxlbmd0aApmb3IocD1zO3A+MDstLXApQy5ObS5pKGE2
-LCJUIisocStwKSkKZm9yKG89dC5XLG49dC5fLG09dC5LLGw9IjwiLGs9IiIscD0wO3A8czsrK3Asaz1h
-NCl7bCs9awpqPWE2Lmxlbmd0aAppPWotMS1wCmlmKGk8MClyZXR1cm4gSC5PSChhNixpKQpsPUMueEIu
-aChsLGE2W2ldKQpoPWE3W3BdCmc9aC55CmlmKCEoZz09PTJ8fGc9PT0zfHxnPT09NHx8Zz09PTV8fGg9
-PT1vKSlpZighKGg9PT1uKSlqPWg9PT1tCmVsc2Ugaj0hMAplbHNlIGo9ITAKaWYoIWopbCs9Qy54Qi5o
-KCIgZXh0ZW5kcyAiLEguZG0oaCxhNikpfWwrPSI+In1lbHNle2w9IiIKcj1udWxsfW89YTUuegpmPWE1
-LlEKZT1mLmEKZD1lLmxlbmd0aApjPWYuYgpiPWMubGVuZ3RoCmE9Zi5jCmEwPWEubGVuZ3RoCmExPUgu
-ZG0obyxhNikKZm9yKGEyPSIiLGEzPSIiLHA9MDtwPGQ7KytwLGEzPWE0KWEyKz1DLnhCLmgoYTMsSC5k
-bShlW3BdLGE2KSkKaWYoYj4wKXthMis9YTMrIlsiCmZvcihhMz0iIixwPTA7cDxiOysrcCxhMz1hNClh
-Mis9Qy54Qi5oKGEzLEguZG0oY1twXSxhNikpCmEyKz0iXSJ9aWYoYTA+MCl7YTIrPWEzKyJ7Igpmb3Io
-YTM9IiIscD0wO3A8YTA7cCs9MyxhMz1hNCl7YTIrPWEzCmlmKGFbcCsxXSlhMis9InJlcXVpcmVkICIK
-YTIrPUouYmIoSC5kbShhW3ArMl0sYTYpLCIgIikrYVtwXX1hMis9In0ifWlmKHIhPW51bGwpe2E2LnRv
-U3RyaW5nCmE2Lmxlbmd0aD1yfXJldHVybiBsKyIoIithMisiKSA9PiAiK0guRWooYTEpfSwKZG06ZnVu
-Y3Rpb24oYSxiKXt2YXIgcyxyLHEscCxvLG4sbSxsPWEueQppZihsPT09NSlyZXR1cm4iZXJhc2VkIgpp
-ZihsPT09MilyZXR1cm4iZHluYW1pYyIKaWYobD09PTMpcmV0dXJuInZvaWQiCmlmKGw9PT0xKXJldHVy
-biJOZXZlciIKaWYobD09PTQpcmV0dXJuImFueSIKaWYobD09PTYpe3M9SC5kbShhLnosYikKcmV0dXJu
-IHN9aWYobD09PTcpe3I9YS56CnM9SC5kbShyLGIpCnE9ci55CnJldHVybiBKLmJiKHE9PT0xMXx8cT09
-PTEyP0MueEIuaCgiKCIscykrIikiOnMsIj8iKX1pZihsPT09OClyZXR1cm4iRnV0dXJlT3I8IitILkVq
-KEguZG0oYS56LGIpKSsiPiIKaWYobD09PTkpe3A9SC5vMyhhLnopCm89YS5RCnJldHVybiBvLmxlbmd0
-aCE9PTA/cCsoIjwiK0guaW8obyxiKSsiPiIpOnB9aWYobD09PTExKXJldHVybiBILmJJKGEsYixudWxs
-KQppZihsPT09MTIpcmV0dXJuIEguYkkoYS56LGIsYS5RKQppZihsPT09MTMpe2IudG9TdHJpbmcKbj1h
-LnoKbT1iLmxlbmd0aApuPW0tMS1uCmlmKG48MHx8bj49bSlyZXR1cm4gSC5PSChiLG4pCnJldHVybiBi
-W25dfXJldHVybiI/In0sCm8zOmZ1bmN0aW9uKGEpe3ZhciBzLHI9SC5KZyhhKQppZihyIT1udWxsKXJl
-dHVybiByCnM9Im1pbmlmaWVkOiIrYQpyZXR1cm4gc30sClFvOmZ1bmN0aW9uKGEsYil7dmFyIHM9YS50
-UltiXQpmb3IoO3R5cGVvZiBzPT0ic3RyaW5nIjspcz1hLnRSW3NdCnJldHVybiBzfSwKYWk6ZnVuY3Rp
-b24oYSxiKXt2YXIgcyxyLHEscCxvLG49YS5lVCxtPW5bYl0KaWYobT09bnVsbClyZXR1cm4gSC5FKGEs
-YiwhMSkKZWxzZSBpZih0eXBlb2YgbT09Im51bWJlciIpe3M9bQpyPUgubShhLDUsIiMiKQpxPVtdCmZv
-cihwPTA7cDxzOysrcClxLnB1c2gocikKbz1ILkooYSxiLHEpCm5bYl09bwpyZXR1cm4gb31lbHNlIHJl
-dHVybiBtfSwKeGI6ZnVuY3Rpb24oYSxiKXtyZXR1cm4gSC5JeChhLnRSLGIpfSwKRkY6ZnVuY3Rpb24o
-YSxiKXtyZXR1cm4gSC5JeChhLmVULGIpfSwKRTpmdW5jdGlvbihhLGIsYyl7dmFyIHMscj1hLmVDLHE9
-ci5nZXQoYikKaWYocSE9bnVsbClyZXR1cm4gcQpzPUguaShILm8oYSxudWxsLGIsYykpCnIuc2V0KGIs
-cykKcmV0dXJuIHN9LApjRTpmdW5jdGlvbihhLGIsYyl7dmFyIHMscixxPWIuY2gKaWYocT09bnVsbClx
-PWIuY2g9bmV3IE1hcCgpCnM9cS5nZXQoYykKaWYocyE9bnVsbClyZXR1cm4gcwpyPUguaShILm8oYSxi
-LGMsITApKQpxLnNldChjLHIpCnJldHVybiByfSwKdjU6ZnVuY3Rpb24oYSxiLGMpe3ZhciBzLHIscSxw
-PWIuY3gKaWYocD09bnVsbClwPWIuY3g9bmV3IE1hcCgpCnM9Yy5jeQpyPXAuZ2V0KHMpCmlmKHIhPW51
-bGwpcmV0dXJuIHIKcT1ILmEoYSxiLGMueT09PTEwP2MuUTpbY10pCnAuc2V0KHMscSkKcmV0dXJuIHF9
-LApCRDpmdW5jdGlvbihhLGIpe2IuYT1ILkF1CmIuYj1ILkpKCnJldHVybiBifSwKbTpmdW5jdGlvbihh
-LGIsYyl7dmFyIHMscixxPWEuZUMuZ2V0KGMpCmlmKHEhPW51bGwpcmV0dXJuIHEKcz1uZXcgSC5KYyhu
-dWxsLG51bGwpCnMueT1iCnMuY3k9YwpyPUguQkQoYSxzKQphLmVDLnNldChjLHIpCnJldHVybiByfSwK
-QzpmdW5jdGlvbihhLGIsYyl7dmFyIHMscj1iLmN5KyIqIixxPWEuZUMuZ2V0KHIpCmlmKHEhPW51bGwp
-cmV0dXJuIHEKcz1ILlo3KGEsYixyLGMpCmEuZUMuc2V0KHIscykKcmV0dXJuIHN9LApaNzpmdW5jdGlv
-bihhLGIsYyxkKXt2YXIgcyxyLHEKaWYoZCl7cz1iLnkKaWYoIUguQTgoYikpcj1iPT09dC5QfHxiPT09
-dC5UfHxzPT09N3x8cz09PTYKZWxzZSByPSEwCmlmKHIpcmV0dXJuIGJ9cT1uZXcgSC5KYyhudWxsLG51
-bGwpCnEueT02CnEuej1iCnEuY3k9YwpyZXR1cm4gSC5CRChhLHEpfSwKQjpmdW5jdGlvbihhLGIsYyl7
-dmFyIHMscj1iLmN5KyI/IixxPWEuZUMuZ2V0KHIpCmlmKHEhPW51bGwpcmV0dXJuIHEKcz1ILmxsKGEs
-YixyLGMpCmEuZUMuc2V0KHIscykKcmV0dXJuIHN9LApsbDpmdW5jdGlvbihhLGIsYyxkKXt2YXIgcyxy
-LHEscAppZihkKXtzPWIueQppZighSC5BOChiKSlpZighKGI9PT10LlB8fGI9PT10LlQpKWlmKHMhPT03
-KXI9cz09PTgmJkgubFIoYi56KQplbHNlIHI9ITAKZWxzZSByPSEwCmVsc2Ugcj0hMAppZihyKXJldHVy
-biBiCmVsc2UgaWYocz09PTF8fGI9PT10LmNGKXJldHVybiB0LlAKZWxzZSBpZihzPT09Nil7cT1iLnoK
-aWYocS55PT09OCYmSC5sUihxLnopKXJldHVybiBxCmVsc2UgcmV0dXJuIEguY3ooYSxiKX19cD1uZXcg
-SC5KYyhudWxsLG51bGwpCnAueT03CnAuej1iCnAuY3k9YwpyZXR1cm4gSC5CRChhLHApfSwKZjpmdW5j
-dGlvbihhLGIsYyl7dmFyIHMscj1iLmN5KyIvIixxPWEuZUMuZ2V0KHIpCmlmKHEhPW51bGwpcmV0dXJu
-IHEKcz1ILmVWKGEsYixyLGMpCmEuZUMuc2V0KHIscykKcmV0dXJuIHN9LAplVjpmdW5jdGlvbihhLGIs
-YyxkKXt2YXIgcyxyLHEKaWYoZCl7cz1iLnkKaWYoIUguQTgoYikpaWYoIShiPT09dC5fKSlyPWI9PT10
-LksKZWxzZSByPSEwCmVsc2Ugcj0hMAppZihyfHxiPT09dC5LKXJldHVybiBiCmVsc2UgaWYocz09PTEp
-cmV0dXJuIEguSihhLCJiOCIsW2JdKQplbHNlIGlmKGI9PT10LlB8fGI9PT10LlQpcmV0dXJuIHQuYkd9
-cT1uZXcgSC5KYyhudWxsLG51bGwpCnEueT04CnEuej1iCnEuY3k9YwpyZXR1cm4gSC5CRChhLHEpfSwK
-SDpmdW5jdGlvbihhLGIpe3ZhciBzLHIscT0iIitiKyJeIixwPWEuZUMuZ2V0KHEpCmlmKHAhPW51bGwp
-cmV0dXJuIHAKcz1uZXcgSC5KYyhudWxsLG51bGwpCnMueT0xMwpzLno9YgpzLmN5PXEKcj1ILkJEKGEs
-cykKYS5lQy5zZXQocSxyKQpyZXR1cm4gcn0sClV4OmZ1bmN0aW9uKGEpe3ZhciBzLHIscSxwPWEubGVu
-Z3RoCmZvcihzPSIiLHI9IiIscT0wO3E8cDsrK3Escj0iLCIpcys9cithW3FdLmN5CnJldHVybiBzfSwK
-UzQ6ZnVuY3Rpb24oYSl7dmFyIHMscixxLHAsbyxuLG09YS5sZW5ndGgKZm9yKHM9IiIscj0iIixxPTA7
-cTxtO3ErPTMscj0iLCIpe3A9YVtxXQpvPWFbcSsxXT8iISI6IjoiCm49YVtxKzJdLmN5CnMrPXIrcCtv
-K259cmV0dXJuIHN9LApKOmZ1bmN0aW9uKGEsYixjKXt2YXIgcyxyLHEscD1iCmlmKGMubGVuZ3RoIT09
-MClwKz0iPCIrSC5VeChjKSsiPiIKcz1hLmVDLmdldChwKQppZihzIT1udWxsKXJldHVybiBzCnI9bmV3
-IEguSmMobnVsbCxudWxsKQpyLnk9OQpyLno9YgpyLlE9YwppZihjLmxlbmd0aD4wKXIuYz1jWzBdCnIu
-Y3k9cApxPUguQkQoYSxyKQphLmVDLnNldChwLHEpCnJldHVybiBxfSwKYTpmdW5jdGlvbihhLGIsYyl7
-dmFyIHMscixxLHAsbyxuCmlmKGIueT09PTEwKXtzPWIuegpyPWIuUS5jb25jYXQoYyl9ZWxzZXtyPWMK
-cz1ifXE9cy5jeSsoIjs8IitILlV4KHIpKyI+IikKcD1hLmVDLmdldChxKQppZihwIT1udWxsKXJldHVy
-biBwCm89bmV3IEguSmMobnVsbCxudWxsKQpvLnk9MTAKby56PXMKby5RPXIKby5jeT1xCm49SC5CRChh
-LG8pCmEuZUMuc2V0KHEsbikKcmV0dXJuIG59LApkOmZ1bmN0aW9uKGEsYixjKXt2YXIgcyxyLHEscCxv
-LG49Yi5jeSxtPWMuYSxsPW0ubGVuZ3RoLGs9Yy5iLGo9ay5sZW5ndGgsaT1jLmMsaD1pLmxlbmd0aCxn
-PSIoIitILlV4KG0pCmlmKGo+MCl7cz1sPjA/IiwiOiIiCnI9SC5VeChrKQpnKz1zKyJbIityKyJdIn1p
-ZihoPjApe3M9bD4wPyIsIjoiIgpyPUguUzQoaSkKZys9cysieyIrcisifSJ9cT1uKyhnKyIpIikKcD1h
-LmVDLmdldChxKQppZihwIT1udWxsKXJldHVybiBwCm89bmV3IEguSmMobnVsbCxudWxsKQpvLnk9MTEK
-by56PWIKby5RPWMKby5jeT1xCnI9SC5CRChhLG8pCmEuZUMuc2V0KHEscikKcmV0dXJuIHJ9LApEOmZ1
-bmN0aW9uKGEsYixjLGQpe3ZhciBzLHI9Yi5jeSsoIjwiK0guVXgoYykrIj4iKSxxPWEuZUMuZ2V0KHIp
-CmlmKHEhPW51bGwpcmV0dXJuIHEKcz1ILmh3KGEsYixjLHIsZCkKYS5lQy5zZXQocixzKQpyZXR1cm4g
-c30sCmh3OmZ1bmN0aW9uKGEsYixjLGQsZSl7dmFyIHMscixxLHAsbyxuLG0sbAppZihlKXtzPWMubGVu
-Z3RoCnI9bmV3IEFycmF5KHMpCmZvcihxPTAscD0wO3A8czsrK3Ape289Y1twXQppZihvLnk9PT0xKXty
-W3BdPW87KytxfX1pZihxPjApe249SC5QTChhLGIsciwwKQptPUguYlooYSxjLHIsMCkKcmV0dXJuIEgu
-RChhLG4sbSxjIT09bSl9fWw9bmV3IEguSmMobnVsbCxudWxsKQpsLnk9MTIKbC56PWIKbC5RPWMKbC5j
-eT1kCnJldHVybiBILkJEKGEsbCl9LApvOmZ1bmN0aW9uKGEsYixjLGQpe3JldHVybnt1OmEsZTpiLHI6
-YyxzOltdLHA6MCxuOmR9fSwKaTpmdW5jdGlvbihhKXt2YXIgcyxyLHEscCxvLG4sbSxsLGssaixpLGgs
-Zz1hLnIsZj1hLnMKZm9yKHM9Zy5sZW5ndGgscj0wO3I8czspe3E9Zy5jaGFyQ29kZUF0KHIpCmlmKHE+
-PTQ4JiZxPD01NylyPUguQShyKzEscSxnLGYpCmVsc2UgaWYoKCgocXwzMik+Pj4wKS05NyY2NTUzNSk8
-MjZ8fHE9PT05NXx8cT09PTM2KXI9SC50KGEscixnLGYsITEpCmVsc2UgaWYocT09PTQ2KXI9SC50KGEs
-cixnLGYsITApCmVsc2V7KytyCnN3aXRjaChxKXtjYXNlIDQ0OmJyZWFrCmNhc2UgNTg6Zi5wdXNoKCEx
-KQpicmVhawpjYXNlIDMzOmYucHVzaCghMCkKYnJlYWsKY2FzZSA1OTpmLnB1c2goSC5LKGEudSxhLmUs
-Zi5wb3AoKSkpCmJyZWFrCmNhc2UgOTQ6Zi5wdXNoKEguSChhLnUsZi5wb3AoKSkpCmJyZWFrCmNhc2Ug
-MzU6Zi5wdXNoKEgubShhLnUsNSwiIyIpKQpicmVhawpjYXNlIDY0OmYucHVzaChILm0oYS51LDIsIkAi
-KSkKYnJlYWsKY2FzZSAxMjY6Zi5wdXNoKEgubShhLnUsMywifiIpKQpicmVhawpjYXNlIDYwOmYucHVz
-aChhLnApCmEucD1mLmxlbmd0aApicmVhawpjYXNlIDYyOnA9YS51Cm89Zi5zcGxpY2UoYS5wKQpILnIo
-YS51LGEuZSxvKQphLnA9Zi5wb3AoKQpuPWYucG9wKCkKaWYodHlwZW9mIG49PSJzdHJpbmciKWYucHVz
-aChILkoocCxuLG8pKQplbHNle209SC5LKHAsYS5lLG4pCnN3aXRjaChtLnkpe2Nhc2UgMTE6Zi5wdXNo
-KEguRChwLG0sbyxhLm4pKQpicmVhawpkZWZhdWx0OmYucHVzaChILmEocCxtLG8pKQpicmVha319YnJl
-YWsKY2FzZSAzODpILkkoYSxmKQpicmVhawpjYXNlIDQyOmw9YS51CmYucHVzaChILkMobCxILksobCxh
-LmUsZi5wb3AoKSksYS5uKSkKYnJlYWsKY2FzZSA2MzpsPWEudQpmLnB1c2goSC5CKGwsSC5LKGwsYS5l
-LGYucG9wKCkpLGEubikpCmJyZWFrCmNhc2UgNDc6bD1hLnUKZi5wdXNoKEguZihsLEguSyhsLGEuZSxm
-LnBvcCgpKSxhLm4pKQpicmVhawpjYXNlIDQwOmYucHVzaChhLnApCmEucD1mLmxlbmd0aApicmVhawpj
-YXNlIDQxOnA9YS51Cms9bmV3IEguRygpCmo9cC5zRUEKaT1wLnNFQQpuPWYucG9wKCkKaWYodHlwZW9m
-IG49PSJudW1iZXIiKXN3aXRjaChuKXtjYXNlLTE6aj1mLnBvcCgpCmJyZWFrCmNhc2UtMjppPWYucG9w
-KCkKYnJlYWsKZGVmYXVsdDpmLnB1c2gobikKYnJlYWt9ZWxzZSBmLnB1c2gobikKbz1mLnNwbGljZShh
-LnApCkgucihhLnUsYS5lLG8pCmEucD1mLnBvcCgpCmsuYT1vCmsuYj1qCmsuYz1pCmYucHVzaChILmQo
-cCxILksocCxhLmUsZi5wb3AoKSksaykpCmJyZWFrCmNhc2UgOTE6Zi5wdXNoKGEucCkKYS5wPWYubGVu
-Z3RoCmJyZWFrCmNhc2UgOTM6bz1mLnNwbGljZShhLnApCkgucihhLnUsYS5lLG8pCmEucD1mLnBvcCgp
-CmYucHVzaChvKQpmLnB1c2goLTEpCmJyZWFrCmNhc2UgMTIzOmYucHVzaChhLnApCmEucD1mLmxlbmd0
-aApicmVhawpjYXNlIDEyNTpvPWYuc3BsaWNlKGEucCkKSC55KGEudSxhLmUsbykKYS5wPWYucG9wKCkK
-Zi5wdXNoKG8pCmYucHVzaCgtMikKYnJlYWsKZGVmYXVsdDp0aHJvdyJCYWQgY2hhcmFjdGVyICIrcX19
-fWg9Zi5wb3AoKQpyZXR1cm4gSC5LKGEudSxhLmUsaCl9LApBOmZ1bmN0aW9uKGEsYixjLGQpe3ZhciBz
-LHIscT1iLTQ4CmZvcihzPWMubGVuZ3RoO2E8czsrK2Epe3I9Yy5jaGFyQ29kZUF0KGEpCmlmKCEocj49
-NDgmJnI8PTU3KSlicmVhawpxPXEqMTArKHItNDgpfWQucHVzaChxKQpyZXR1cm4gYX0sCnQ6ZnVuY3Rp
-b24oYSxiLGMsZCxlKXt2YXIgcyxyLHEscCxvLG4sbT1iKzEKZm9yKHM9Yy5sZW5ndGg7bTxzOysrbSl7
-cj1jLmNoYXJDb2RlQXQobSkKaWYocj09PTQ2KXtpZihlKWJyZWFrCmU9ITB9ZWxzZXtpZighKCgoKHJ8
-MzIpPj4+MCktOTcmNjU1MzUpPDI2fHxyPT09OTV8fHI9PT0zNikpcT1yPj00OCYmcjw9NTcKZWxzZSBx
-PSEwCmlmKCFxKWJyZWFrfX1wPWMuc3Vic3RyaW5nKGIsbSkKaWYoZSl7cz1hLnUKbz1hLmUKaWYoby55
-PT09MTApbz1vLnoKbj1ILlFvKHMsby56KVtwXQppZihuPT1udWxsKUgudignTm8gIicrcCsnIiBpbiAi
-JytILm1EKG8pKyciJykKZC5wdXNoKEguY0UocyxvLG4pKX1lbHNlIGQucHVzaChwKQpyZXR1cm4gbX0s
-Ckk6ZnVuY3Rpb24oYSxiKXt2YXIgcz1iLnBvcCgpCmlmKDA9PT1zKXtiLnB1c2goSC5tKGEudSwxLCIw
-JiIpKQpyZXR1cm59aWYoMT09PXMpe2IucHVzaChILm0oYS51LDQsIjEmIikpCnJldHVybn10aHJvdyBI
-LmIoUC5oVigiVW5leHBlY3RlZCBleHRlbmRlZCBvcGVyYXRpb24gIitILkVqKHMpKSl9LApLOmZ1bmN0
-aW9uKGEsYixjKXtpZih0eXBlb2YgYz09InN0cmluZyIpcmV0dXJuIEguSihhLGMsYS5zRUEpCmVsc2Ug
-aWYodHlwZW9mIGM9PSJudW1iZXIiKXJldHVybiBILlRWKGEsYixjKQplbHNlIHJldHVybiBjfSwKcjpm
-dW5jdGlvbihhLGIsYyl7dmFyIHMscj1jLmxlbmd0aApmb3Iocz0wO3M8cjsrK3MpY1tzXT1ILksoYSxi
-LGNbc10pfSwKeTpmdW5jdGlvbihhLGIsYyl7dmFyIHMscj1jLmxlbmd0aApmb3Iocz0yO3M8cjtzKz0z
-KWNbc109SC5LKGEsYixjW3NdKX0sClRWOmZ1bmN0aW9uKGEsYixjKXt2YXIgcyxyLHE9Yi55CmlmKHE9
-PT0xMCl7aWYoYz09PTApcmV0dXJuIGIuegpzPWIuUQpyPXMubGVuZ3RoCmlmKGM8PXIpcmV0dXJuIHNb
-Yy0xXQpjLT1yCmI9Yi56CnE9Yi55fWVsc2UgaWYoYz09PTApcmV0dXJuIGIKaWYocSE9PTkpdGhyb3cg
-SC5iKFAuaFYoIkluZGV4ZWQgYmFzZSBtdXN0IGJlIGFuIGludGVyZmFjZSB0eXBlIikpCnM9Yi5RCmlm
-KGM8PXMubGVuZ3RoKXJldHVybiBzW2MtMV0KdGhyb3cgSC5iKFAuaFYoIkJhZCBpbmRleCAiK2MrIiBm
-b3IgIitiLncoMCkpKX0sCldlOmZ1bmN0aW9uKGEsYixjLGQsZSl7dmFyIHMscixxLHAsbyxuLG0sbCxr
-LGoKaWYoYj09PWQpcmV0dXJuITAKaWYoIUguQTgoZCkpaWYoIShkPT09dC5fKSlzPWQ9PT10LksKZWxz
-ZSBzPSEwCmVsc2Ugcz0hMAppZihzKXJldHVybiEwCnI9Yi55CmlmKHI9PT00KXJldHVybiEwCmlmKEgu
-QTgoYikpcmV0dXJuITEKaWYoYi55IT09MSlzPWI9PT10LlB8fGI9PT10LlQKZWxzZSBzPSEwCmlmKHMp
-cmV0dXJuITAKcT1yPT09MTMKaWYocSlpZihILldlKGEsY1tiLnpdLGMsZCxlKSlyZXR1cm4hMApwPWQu
-eQppZihyPT09NilyZXR1cm4gSC5XZShhLGIueixjLGQsZSkKaWYocD09PTYpe3M9ZC56CnJldHVybiBI
-LldlKGEsYixjLHMsZSl9aWYocj09PTgpe2lmKCFILldlKGEsYi56LGMsZCxlKSlyZXR1cm4hMQpyZXR1
-cm4gSC5XZShhLEgueFooYSxiKSxjLGQsZSl9aWYocj09PTcpe3M9SC5XZShhLGIueixjLGQsZSkKcmV0
-dXJuIHN9aWYocD09PTgpe2lmKEguV2UoYSxiLGMsZC56LGUpKXJldHVybiEwCnJldHVybiBILldlKGEs
-YixjLEgueFooYSxkKSxlKX1pZihwPT09Nyl7cz1ILldlKGEsYixjLGQueixlKQpyZXR1cm4gc31pZihx
-KXJldHVybiExCnM9ciE9PTExCmlmKCghc3x8cj09PTEyKSYmZD09PXQuWSlyZXR1cm4hMAppZihwPT09
-MTIpe2lmKGI9PT10LkQpcmV0dXJuITAKaWYociE9PTEyKXJldHVybiExCm89Yi5RCm49ZC5RCm09by5s
-ZW5ndGgKaWYobSE9PW4ubGVuZ3RoKXJldHVybiExCmM9Yz09bnVsbD9vOm8uY29uY2F0KGMpCmU9ZT09
-bnVsbD9uOm4uY29uY2F0KGUpCmZvcihsPTA7bDxtOysrbCl7az1vW2xdCmo9bltsXQppZighSC5XZShh
-LGssYyxqLGUpfHwhSC5XZShhLGosZSxrLGMpKXJldHVybiExfXJldHVybiBILmJPKGEsYi56LGMsZC56
-LGUpfWlmKHA9PT0xMSl7aWYoYj09PXQuRClyZXR1cm4hMAppZihzKXJldHVybiExCnJldHVybiBILmJP
-KGEsYixjLGQsZSl9aWYocj09PTkpe2lmKHAhPT05KXJldHVybiExCnJldHVybiBILnBHKGEsYixjLGQs
-ZSl9cmV0dXJuITF9LApiTzpmdW5jdGlvbihhMixhMyxhNCxhNSxhNil7dmFyIHMscixxLHAsbyxuLG0s
-bCxrLGosaSxoLGcsZixlLGQsYyxiLGEsYTAsYTEKaWYoIUguV2UoYTIsYTMueixhNCxhNS56LGE2KSly
-ZXR1cm4hMQpzPWEzLlEKcj1hNS5RCnE9cy5hCnA9ci5hCm89cS5sZW5ndGgKbj1wLmxlbmd0aAppZihv
-Pm4pcmV0dXJuITEKbT1uLW8KbD1zLmIKaz1yLmIKaj1sLmxlbmd0aAppPWsubGVuZ3RoCmlmKG8rajxu
-K2kpcmV0dXJuITEKZm9yKGg9MDtoPG87KytoKXtnPXFbaF0KaWYoIUguV2UoYTIscFtoXSxhNixnLGE0
-KSlyZXR1cm4hMX1mb3IoaD0wO2g8bTsrK2gpe2c9bFtoXQppZighSC5XZShhMixwW28raF0sYTYsZyxh
-NCkpcmV0dXJuITF9Zm9yKGg9MDtoPGk7KytoKXtnPWxbbStoXQppZighSC5XZShhMixrW2hdLGE2LGcs
-YTQpKXJldHVybiExfWY9cy5jCmU9ci5jCmQ9Zi5sZW5ndGgKYz1lLmxlbmd0aApmb3IoYj0wLGE9MDth
-PGM7YSs9Myl7YTA9ZVthXQpmb3IoOyEwOyl7aWYoYj49ZClyZXR1cm4hMQphMT1mW2JdCmIrPTMKaWYo
-YTA8YTEpcmV0dXJuITEKaWYoYTE8YTApY29udGludWUKZz1mW2ItMV0KaWYoIUguV2UoYTIsZVthKzJd
-LGE2LGcsYTQpKXJldHVybiExCmJyZWFrfX1yZXR1cm4hMH0sCnBHOmZ1bmN0aW9uKGEsYixjLGQsZSl7
-dmFyIHMscixxLHAsbyxuLG0sbCxrPWIueixqPWQuegppZihrPT09ail7cz1iLlEKcj1kLlEKcT1zLmxl
-bmd0aApmb3IocD0wO3A8cTsrK3Ape289c1twXQpuPXJbcF0KaWYoIUguV2UoYSxvLGMsbixlKSlyZXR1
-cm4hMX1yZXR1cm4hMH1pZihkPT09dC5LKXJldHVybiEwCm09SC5RbyhhLGspCmlmKG09PW51bGwpcmV0
-dXJuITEKbD1tW2pdCmlmKGw9PW51bGwpcmV0dXJuITEKcT1sLmxlbmd0aApyPWQuUQpmb3IocD0wO3A8
-cTsrK3ApaWYoIUguV2UoYSxILmNFKGEsYixsW3BdKSxjLHJbcF0sZSkpcmV0dXJuITEKcmV0dXJuITB9
-LApsUjpmdW5jdGlvbihhKXt2YXIgcyxyPWEueQppZighKGE9PT10LlB8fGE9PT10LlQpKWlmKCFILkE4
-KGEpKWlmKHIhPT03KWlmKCEocj09PTYmJkgubFIoYS56KSkpcz1yPT09OCYmSC5sUihhLnopCmVsc2Ug
-cz0hMAplbHNlIHM9ITAKZWxzZSBzPSEwCmVsc2Ugcz0hMApyZXR1cm4gc30sCmNjOmZ1bmN0aW9uKGEp
-e3ZhciBzCmlmKCFILkE4KGEpKWlmKCEoYT09PXQuXykpcz1hPT09dC5LCmVsc2Ugcz0hMAplbHNlIHM9
-ITAKcmV0dXJuIHN9LApBODpmdW5jdGlvbihhKXt2YXIgcz1hLnkKcmV0dXJuIHM9PT0yfHxzPT09M3x8
-cz09PTR8fHM9PT01fHxhPT09dC5XfSwKSXg6ZnVuY3Rpb24oYSxiKXt2YXIgcyxyLHE9T2JqZWN0Lmtl
-eXMoYikscD1xLmxlbmd0aApmb3Iocz0wO3M8cDsrK3Mpe3I9cVtzXQphW3JdPWJbcl19fSwKSmM6ZnVu
-Y3Rpb24gSmMoYSxiKXt2YXIgXz10aGlzCl8uYT1hCl8uYj1iCl8ueD1fLnI9Xy5jPW51bGwKXy55PTAK
-Xy5jeT1fLmN4PV8uY2g9Xy5RPV8uej1udWxsfSwKRzpmdW5jdGlvbiBHKCl7dGhpcy5jPXRoaXMuYj10
-aGlzLmE9bnVsbH0sCmxZOmZ1bmN0aW9uIGxZKGEpe3RoaXMuYT1hfSwKa1M6ZnVuY3Rpb24ga1MoKXt9
-LAppTTpmdW5jdGlvbiBpTShhKXt0aGlzLmE9YX0sClI5OmZ1bmN0aW9uKGEpe3JldHVybiB0LncuYihh
-KXx8dC5CLmIoYSl8fHQuZHouYihhKXx8dC5JLmIoYSl8fHQuQS5iKGEpfHx0Lmc0LmIoYSl8fHQuZzIu
-YihhKX0sCkpnOmZ1bmN0aW9uKGEpe3JldHVybiB2Lm1hbmdsZWRHbG9iYWxOYW1lc1thXX19LEo9ewpR
-dTpmdW5jdGlvbihhLGIsYyxkKXtyZXR1cm57aTphLHA6YixlOmMseDpkfX0sCmtzOmZ1bmN0aW9uKGEp
-e3ZhciBzLHIscSxwLG89YVt2LmRpc3BhdGNoUHJvcGVydHlOYW1lXQppZihvPT1udWxsKWlmKCQuQnY9
-PW51bGwpe0guWEQoKQpvPWFbdi5kaXNwYXRjaFByb3BlcnR5TmFtZV19aWYobyE9bnVsbCl7cz1vLnAK
-aWYoITE9PT1zKXJldHVybiBvLmkKaWYoITA9PT1zKXJldHVybiBhCnI9T2JqZWN0LmdldFByb3RvdHlw
-ZU9mKGEpCmlmKHM9PT1yKXJldHVybiBvLmkKaWYoby5lPT09cil0aHJvdyBILmIoUC5TWSgiUmV0dXJu
-IGludGVyY2VwdG9yIGZvciAiK0guRWoocyhhLG8pKSkpfXE9YS5jb25zdHJ1Y3RvcgpwPXE9PW51bGw/
-bnVsbDpxW0ouUlAoKV0KaWYocCE9bnVsbClyZXR1cm4gcApwPUgudzMoYSkKaWYocCE9bnVsbClyZXR1
-cm4gcAppZih0eXBlb2YgYT09ImZ1bmN0aW9uIilyZXR1cm4gQy5ERwpzPU9iamVjdC5nZXRQcm90b3R5
-cGVPZihhKQppZihzPT1udWxsKXJldHVybiBDLlpRCmlmKHM9PT1PYmplY3QucHJvdG90eXBlKXJldHVy
-biBDLlpRCmlmKHR5cGVvZiBxPT0iZnVuY3Rpb24iKXtPYmplY3QuZGVmaW5lUHJvcGVydHkocSxKLlJQ
-KCkse3ZhbHVlOkMudkIsZW51bWVyYWJsZTpmYWxzZSx3cml0YWJsZTp0cnVlLGNvbmZpZ3VyYWJsZTp0
-cnVlfSkKcmV0dXJuIEMudkJ9cmV0dXJuIEMudkJ9LApSUDpmdW5jdGlvbigpe3ZhciBzPSQuem0KcmV0
-dXJuIHM9PW51bGw/JC56bT12LmdldElzb2xhdGVUYWcoIl8kZGFydF9qcyIpOnN9LApRaTpmdW5jdGlv
-bihhLGIpe2lmKGE8MHx8YT40Mjk0OTY3Mjk1KXRocm93IEguYihQLlRFKGEsMCw0Mjk0OTY3Mjk1LCJs
-ZW5ndGgiLG51bGwpKQpyZXR1cm4gSi5weShuZXcgQXJyYXkoYSksYil9LApLaDpmdW5jdGlvbihhLGIp
-e2lmKGE8MCl0aHJvdyBILmIoUC54WSgiTGVuZ3RoIG11c3QgYmUgYSBub24tbmVnYXRpdmUgaW50ZWdl
-cjogIithKSkKcmV0dXJuIEguVk0obmV3IEFycmF5KGEpLGIuQygiamQ8MD4iKSl9LApweTpmdW5jdGlv
-bihhLGIpe3JldHVybiBKLkVwKEguVk0oYSxiLkMoImpkPDA+IikpLGIpfSwKRXA6ZnVuY3Rpb24oYSxi
-KXthLmZpeGVkJGxlbmd0aD1BcnJheQpyZXR1cm4gYX0sCnpDOmZ1bmN0aW9uKGEpe2EuZml4ZWQkbGVu
-Z3RoPUFycmF5CmEuaW1tdXRhYmxlJGxpc3Q9QXJyYXkKcmV0dXJuIGF9LApHYTpmdW5jdGlvbihhKXtp
-ZihhPDI1Nilzd2l0Y2goYSl7Y2FzZSA5OmNhc2UgMTA6Y2FzZSAxMTpjYXNlIDEyOmNhc2UgMTM6Y2Fz
-ZSAzMjpjYXNlIDEzMzpjYXNlIDE2MDpyZXR1cm4hMApkZWZhdWx0OnJldHVybiExfXN3aXRjaChhKXtj
-YXNlIDU3NjA6Y2FzZSA4MTkyOmNhc2UgODE5MzpjYXNlIDgxOTQ6Y2FzZSA4MTk1OmNhc2UgODE5Njpj
-YXNlIDgxOTc6Y2FzZSA4MTk4OmNhc2UgODE5OTpjYXNlIDgyMDA6Y2FzZSA4MjAxOmNhc2UgODIwMjpj
-YXNlIDgyMzI6Y2FzZSA4MjMzOmNhc2UgODIzOTpjYXNlIDgyODc6Y2FzZSAxMjI4ODpjYXNlIDY1Mjc5
-OnJldHVybiEwCmRlZmF1bHQ6cmV0dXJuITF9fSwKbW06ZnVuY3Rpb24oYSxiKXt2YXIgcyxyCmZvcihz
-PWEubGVuZ3RoO2I8czspe3I9Qy54Qi5XKGEsYikKaWYociE9PTMyJiZyIT09MTMmJiFKLkdhKHIpKWJy
-ZWFrOysrYn1yZXR1cm4gYn0sCmMxOmZ1bmN0aW9uKGEsYil7dmFyIHMscgpmb3IoO2I+MDtiPXMpe3M9
-Yi0xCnI9Qy54Qi5PMihhLHMpCmlmKHIhPT0zMiYmciE9PTEzJiYhSi5HYShyKSlicmVha31yZXR1cm4g
-Yn0sClRKOmZ1bmN0aW9uKGEpe2lmKHR5cGVvZiBhPT0ibnVtYmVyIilyZXR1cm4gSi5xSS5wcm90b3R5
-cGUKaWYodHlwZW9mIGE9PSJzdHJpbmciKXJldHVybiBKLkRyLnByb3RvdHlwZQppZihhPT1udWxsKXJl
-dHVybiBhCmlmKGEuY29uc3RydWN0b3I9PUFycmF5KXJldHVybiBKLmpkLnByb3RvdHlwZQppZih0eXBl
-b2YgYSE9Im9iamVjdCIpe2lmKHR5cGVvZiBhPT0iZnVuY3Rpb24iKXJldHVybiBKLmM1LnByb3RvdHlw
-ZQpyZXR1cm4gYX1pZihhIGluc3RhbmNlb2YgUC5NaClyZXR1cm4gYQpyZXR1cm4gSi5rcyhhKX0sClU2
-OmZ1bmN0aW9uKGEpe2lmKHR5cGVvZiBhPT0ic3RyaW5nIilyZXR1cm4gSi5Eci5wcm90b3R5cGUKaWYo
-YT09bnVsbClyZXR1cm4gYQppZihhLmNvbnN0cnVjdG9yPT1BcnJheSlyZXR1cm4gSi5qZC5wcm90b3R5
-cGUKaWYodHlwZW9mIGEhPSJvYmplY3QiKXtpZih0eXBlb2YgYT09ImZ1bmN0aW9uIilyZXR1cm4gSi5j
-NS5wcm90b3R5cGUKcmV0dXJuIGF9aWYoYSBpbnN0YW5jZW9mIFAuTWgpcmV0dXJuIGEKcmV0dXJuIEou
-a3MoYSl9LApZRTpmdW5jdGlvbihhKXtpZihhPT1udWxsKXJldHVybiBhCmlmKHR5cGVvZiBhIT0ib2Jq
-ZWN0Iil7aWYodHlwZW9mIGE9PSJmdW5jdGlvbiIpcmV0dXJuIEouYzUucHJvdG90eXBlCnJldHVybiBh
-fWlmKGEgaW5zdGFuY2VvZiBQLk1oKXJldHVybiBhCnJldHVybiBKLmtzKGEpfSwKaWE6ZnVuY3Rpb24o
-YSl7aWYodHlwZW9mIGE9PSJudW1iZXIiKXtpZihNYXRoLmZsb29yKGEpPT1hKXJldHVybiBKLmJVLnBy
-b3RvdHlwZQpyZXR1cm4gSi5WQS5wcm90b3R5cGV9aWYodHlwZW9mIGE9PSJzdHJpbmciKXJldHVybiBK
-LkRyLnByb3RvdHlwZQppZihhPT1udWxsKXJldHVybiBKLndlLnByb3RvdHlwZQppZih0eXBlb2YgYT09
-ImJvb2xlYW4iKXJldHVybiBKLnlFLnByb3RvdHlwZQppZihhLmNvbnN0cnVjdG9yPT1BcnJheSlyZXR1
-cm4gSi5qZC5wcm90b3R5cGUKaWYodHlwZW9mIGEhPSJvYmplY3QiKXtpZih0eXBlb2YgYT09ImZ1bmN0
-aW9uIilyZXR1cm4gSi5jNS5wcm90b3R5cGUKcmV0dXJuIGF9aWYoYSBpbnN0YW5jZW9mIFAuTWgpcmV0
-dXJuIGEKcmV0dXJuIEoua3MoYSl9LApyWTpmdW5jdGlvbihhKXtpZih0eXBlb2YgYT09InN0cmluZyIp
-cmV0dXJuIEouRHIucHJvdG90eXBlCmlmKGE9PW51bGwpcmV0dXJuIGEKaWYoIShhIGluc3RhbmNlb2Yg
-UC5NaCkpcmV0dXJuIEoua2QucHJvdG90eXBlCnJldHVybiBhfSwKdmQ6ZnVuY3Rpb24oYSl7aWYodHlw
-ZW9mIGE9PSJudW1iZXIiKXJldHVybiBKLnFJLnByb3RvdHlwZQppZihhPT1udWxsKXJldHVybiBhCmlm
-KCEoYSBpbnN0YW5jZW9mIFAuTWgpKXJldHVybiBKLmtkLnByb3RvdHlwZQpyZXR1cm4gYX0sCncxOmZ1
-bmN0aW9uKGEpe2lmKGE9PW51bGwpcmV0dXJuIGEKaWYoYS5jb25zdHJ1Y3Rvcj09QXJyYXkpcmV0dXJu
-IEouamQucHJvdG90eXBlCmlmKHR5cGVvZiBhIT0ib2JqZWN0Iil7aWYodHlwZW9mIGE9PSJmdW5jdGlv
-biIpcmV0dXJuIEouYzUucHJvdG90eXBlCnJldHVybiBhfWlmKGEgaW5zdGFuY2VvZiBQLk1oKXJldHVy
-biBhCnJldHVybiBKLmtzKGEpfSwKQTU6ZnVuY3Rpb24oYSxiKXtyZXR1cm4gSi53MShhKS5lUihhLGIp
-fSwKRWg6ZnVuY3Rpb24oYSxiLGMpe3JldHVybiBKLllFKGEpLm1LKGEsYixjKX0sCkVsOmZ1bmN0aW9u
-KGEsYil7cmV0dXJuIEoudzEoYSkuZHIoYSxiKX0sCkY3OmZ1bmN0aW9uKGEpe3JldHVybiBKLlU2KGEp
-LmdvcihhKX0sCkZMOmZ1bmN0aW9uKGEsYil7cmV0dXJuIEouclkoYSkuZGQoYSxiKX0sCkdBOmZ1bmN0
-aW9uKGEsYil7cmV0dXJuIEoudzEoYSkuRShhLGIpfSwKSG06ZnVuY3Rpb24oYSl7cmV0dXJuIEouVTYo
-YSkuZ0EoYSl9LApJVDpmdW5jdGlvbihhKXtyZXR1cm4gSi53MShhKS5nbShhKX0sCkp5OmZ1bmN0aW9u
-KGEsYil7cmV0dXJuIEouaWEoYSkuZTcoYSxiKX0sCktWOmZ1bmN0aW9uKGEsYil7cmV0dXJuIEouclko
-YSkuRyhhLGIpfSwKTHQ6ZnVuY3Rpb24oYSl7cmV0dXJuIEouWUUoYSkud2coYSl9LApNMTpmdW5jdGlv
-bihhLGIsYyl7cmV0dXJuIEoudzEoYSkuRTIoYSxiLGMpfSwKTXU6ZnVuY3Rpb24oYSxiKXtyZXR1cm4g
-Si5ZRShhKS5zRChhLGIpfSwKUXo6ZnVuY3Rpb24oYSxiKXtyZXR1cm4gSi5yWShhKS5XKGEsYil9LApS
-TTpmdW5jdGlvbihhLGIpe2lmKGE9PW51bGwpcmV0dXJuIGI9PW51bGwKaWYodHlwZW9mIGEhPSJvYmpl
-Y3QiKXJldHVybiBiIT1udWxsJiZhPT09YgpyZXR1cm4gSi5pYShhKS5ETihhLGIpfSwKUlg6ZnVuY3Rp
-b24oYSl7cmV0dXJuIEoudzEoYSkuYnIoYSl9LApUMDpmdW5jdGlvbihhKXtyZXR1cm4gSi5yWShhKS5i
-UyhhKX0sClZ1OmZ1bmN0aW9uKGEpe3JldHVybiBKLnZkKGEpLnpRKGEpfSwKYTY6ZnVuY3Rpb24oYSxi
-KXtyZXR1cm4gSi5yWShhKS5PMihhLGIpfSwKYlQ6ZnVuY3Rpb24oYSl7cmV0dXJuIEouWUUoYSkuRDQo
-YSl9LApiYjpmdW5jdGlvbihhLGIpe2lmKHR5cGVvZiBhPT0ibnVtYmVyIiYmdHlwZW9mIGI9PSJudW1i
-ZXIiKXJldHVybiBhK2IKcmV0dXJuIEouVEooYSkuaChhLGIpfSwKY0g6ZnVuY3Rpb24oYSl7cmV0dXJu
-IEouclkoYSkuaGMoYSl9LApkUjpmdW5jdGlvbihhKXtyZXR1cm4gSi5ZRShhKS5nRChhKX0sCmRaOmZ1
-bmN0aW9uKGEsYixjLGQpe3JldHVybiBKLllFKGEpLk9uKGEsYixjLGQpfSwKZGc6ZnVuY3Rpb24oYSxi
-LGMsZCl7cmV0dXJuIEouclkoYSkuaTcoYSxiLGMsZCl9LApkaDpmdW5jdGlvbihhKXtyZXR1cm4gSi5Z
-RShhKS5GRihhKX0sCmRyOmZ1bmN0aW9uKGEsYil7cmV0dXJuIEouWUUoYSkuc2E0KGEsYil9LApoZjpm
-dW5jdGlvbihhKXtyZXR1cm4gSi5pYShhKS5naU8oYSl9LAppZzpmdW5jdGlvbihhKXtyZXR1cm4gSi5Z
-RShhKS5nUWcoYSl9LApqOmZ1bmN0aW9uKGEpe3JldHVybiBKLmlhKGEpLncoYSl9LApsNTpmdW5jdGlv
-bihhLGIpe3JldHVybiBKLllFKGEpLnNoZihhLGIpfSwKbGQ6ZnVuY3Rpb24oYSxiLGMpe3JldHVybiBK
-LnJZKGEpLk5qKGEsYixjKX0sCnA0OmZ1bmN0aW9uKGEsYil7cmV0dXJuIEouclkoYSkuVGMoYSxiKX0s
-CnEwOmZ1bmN0aW9uKGEsYixjKXtyZXR1cm4gSi5yWShhKS5RaShhLGIsYyl9LApxRjpmdW5jdGlvbihh
-KXtyZXR1cm4gSi5ZRShhKS5nVmwoYSl9LAp0SDpmdW5jdGlvbihhLGIsYyl7cmV0dXJuIEouWUUoYSku
-cGsoYSxiLGMpfSwKdTk6ZnVuY3Rpb24oYSxiLGMpe3JldHVybiBKLncxKGEpLlkoYSxiLGMpfSwKdVU6
-ZnVuY3Rpb24oYSl7cmV0dXJuIEouVTYoYSkuZ2wwKGEpfSwKd2Y6ZnVuY3Rpb24oYSxiKXtyZXR1cm4g
-Si5ZRShhKS5zUk4oYSxiKX0sCng5OmZ1bmN0aW9uKGEsYil7aWYodHlwZW9mIGI9PT0ibnVtYmVyIilp
-ZihhLmNvbnN0cnVjdG9yPT1BcnJheXx8dHlwZW9mIGE9PSJzdHJpbmcifHxILndWKGEsYVt2LmRpc3Bh
-dGNoUHJvcGVydHlOYW1lXSkpaWYoYj4+PjA9PT1iJiZiPGEubGVuZ3RoKXJldHVybiBhW2JdCnJldHVy
-biBKLlU2KGEpLnEoYSxiKX0sCnpsOmZ1bmN0aW9uKGEsYil7cmV0dXJuIEouVTYoYSkudGcoYSxiKX0s
-Ckd2OmZ1bmN0aW9uIEd2KCl7fSwKeUU6ZnVuY3Rpb24geUUoKXt9LAp3ZTpmdW5jdGlvbiB3ZSgpe30s
-Ck1GOmZ1bmN0aW9uIE1GKCl7fSwKaUM6ZnVuY3Rpb24gaUMoKXt9LAprZDpmdW5jdGlvbiBrZCgpe30s
-CmM1OmZ1bmN0aW9uIGM1KCl7fSwKamQ6ZnVuY3Rpb24gamQoYSl7dGhpcy4kdGk9YX0sClBvOmZ1bmN0
-aW9uIFBvKGEpe3RoaXMuJHRpPWF9LAptMTpmdW5jdGlvbiBtMShhLGIsYyl7dmFyIF89dGhpcwpfLmE9
-YQpfLmI9YgpfLmM9MApfLmQ9bnVsbApfLiR0aT1jfSwKcUk6ZnVuY3Rpb24gcUkoKXt9LApiVTpmdW5j
-dGlvbiBiVSgpe30sClZBOmZ1bmN0aW9uIFZBKCl7fSwKRHI6ZnVuY3Rpb24gRHIoKXt9fSxQPXsKT2o6
-ZnVuY3Rpb24oKXt2YXIgcyxyLHE9e30KaWYoc2VsZi5zY2hlZHVsZUltbWVkaWF0ZSE9bnVsbClyZXR1
-cm4gUC5FWCgpCmlmKHNlbGYuTXV0YXRpb25PYnNlcnZlciE9bnVsbCYmc2VsZi5kb2N1bWVudCE9bnVs
-bCl7cz1zZWxmLmRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoImRpdiIpCnI9c2VsZi5kb2N1bWVudC5jcmVh
-dGVFbGVtZW50KCJzcGFuIikKcS5hPW51bGwKbmV3IHNlbGYuTXV0YXRpb25PYnNlcnZlcihILnRSKG5l
-dyBQLnRoKHEpLDEpKS5vYnNlcnZlKHMse2NoaWxkTGlzdDp0cnVlfSkKcmV0dXJuIG5ldyBQLmhhKHEs
-cyxyKX1lbHNlIGlmKHNlbGYuc2V0SW1tZWRpYXRlIT1udWxsKXJldHVybiBQLnl0KCkKcmV0dXJuIFAu
-cVcoKX0sClpWOmZ1bmN0aW9uKGEpe3NlbGYuc2NoZWR1bGVJbW1lZGlhdGUoSC50UihuZXcgUC5Wcyh0
-Lk0uYShhKSksMCkpfSwKb0E6ZnVuY3Rpb24oYSl7c2VsZi5zZXRJbW1lZGlhdGUoSC50UihuZXcgUC5G
-dCh0Lk0uYShhKSksMCkpfSwKQno6ZnVuY3Rpb24oYSl7dC5NLmEoYSkKUC5RTigwLGEpfSwKUU46ZnVu
-Y3Rpb24oYSxiKXt2YXIgcz1uZXcgUC5XMygpCnMuQ1koYSxiKQpyZXR1cm4gc30sCkZYOmZ1bmN0aW9u
-KGEpe3JldHVybiBuZXcgUC5paChuZXcgUC52cygkLlgzLGEuQygidnM8MD4iKSksYS5DKCJpaDwwPiIp
-KX0sCkRJOmZ1bmN0aW9uKGEsYil7YS4kMigwLG51bGwpCmIuYj0hMApyZXR1cm4gYi5hfSwKalE6ZnVu
-Y3Rpb24oYSxiKXtQLkplKGEsYil9LAp5QzpmdW5jdGlvbihhLGIpe2IuYU0oMCxhKX0sCmYzOmZ1bmN0
-aW9uKGEsYil7Yi53MChILlJ1KGEpLEgudHMoYSkpfSwKSmU6ZnVuY3Rpb24oYSxiKXt2YXIgcyxyLHE9
-bmV3IFAuV00oYikscD1uZXcgUC5TWChiKQppZihhIGluc3RhbmNlb2YgUC52cylhLlFkKHEscCx0Lnop
-CmVsc2V7cz10LnoKaWYodC5kLmIoYSkpYS5TcShxLHAscykKZWxzZXtyPW5ldyBQLnZzKCQuWDMsdC5j
-KQpyLmE9NApyLmM9YQpyLlFkKHEscCxzKX19fSwKbHo6ZnVuY3Rpb24oYSl7dmFyIHM9ZnVuY3Rpb24o
-YixjKXtyZXR1cm4gZnVuY3Rpb24oZCxlKXt3aGlsZSh0cnVlKXRyeXtiKGQsZSkKYnJlYWt9Y2F0Y2go
-cil7ZT1yCmQ9Y319fShhLDEpCnJldHVybiAkLlgzLkxqKG5ldyBQLkdzKHMpLHQuSCx0LlMsdC56KX0s
-CklHOmZ1bmN0aW9uKGEpe3JldHVybiBuZXcgUC5GeShhLDEpfSwKVGg6ZnVuY3Rpb24oKXtyZXR1cm4g
-Qy53UX0sClltOmZ1bmN0aW9uKGEpe3JldHVybiBuZXcgUC5GeShhLDMpfSwKbDA6ZnVuY3Rpb24oYSxi
-KXtyZXR1cm4gbmV3IFAucTQoYSxiLkMoInE0PDA+IikpfSwKazM6ZnVuY3Rpb24oYSxiKXt2YXIgcyxy
-LHEKYi5hPTEKdHJ5e2EuU3EobmV3IFAucFYoYiksbmV3IFAuVTcoYiksdC5QKX1jYXRjaChxKXtzPUgu
-UnUocSkKcj1ILnRzKHEpClAucmIobmV3IFAudnIoYixzLHIpKX19LApBOTpmdW5jdGlvbihhLGIpe3Zh
-ciBzLHIscQpmb3Iocz10LmM7cj1hLmEscj09PTI7KWE9cy5hKGEuYykKaWYocj49NCl7cT1iLmFoKCkK
-Yi5hPWEuYQpiLmM9YS5jClAuSFooYixxKX1lbHNle3E9dC5GLmEoYi5jKQpiLmE9MgpiLmM9YQphLmpR
-KHEpfX0sCkhaOmZ1bmN0aW9uKGEwLGExKXt2YXIgcyxyLHEscCxvLG4sbSxsLGssaixpLGgsZyxmLGUs
-ZCxjPW51bGwsYj17fSxhPWIuYT1hMApmb3Iocz10Lm4scj10LkYscT10LmQ7ITA7KXtwPXt9Cm89YS5h
-PT09OAppZihhMT09bnVsbCl7aWYobyl7bj1zLmEoYS5jKQpQLkwyKGMsYyxhLmIsbi5hLG4uYil9cmV0
-dXJufXAuYT1hMQptPWExLmEKZm9yKGE9YTE7bSE9bnVsbDthPW0sbT1sKXthLmE9bnVsbApQLkhaKGIu
-YSxhKQpwLmE9bQpsPW0uYX1rPWIuYQpqPWsuYwpwLmI9bwpwLmM9agppPSFvCmlmKGkpe2g9YS5jCmg9
-KGgmMSkhPT0wfHwoaCYxNSk9PT04fWVsc2UgaD0hMAppZihoKXtnPWEuYi5iCmlmKG8pe2g9ay5iPT09
-ZwpoPSEoaHx8aCl9ZWxzZSBoPSExCmlmKGgpe3MuYShqKQpQLkwyKGMsYyxrLmIsai5hLGouYikKcmV0
-dXJufWY9JC5YMwppZihmIT09ZykkLlgzPWcKZWxzZSBmPWMKYT1hLmMKaWYoKGEmMTUpPT09OCluZXcg
-UC5SVChwLGIsbykuJDAoKQplbHNlIGlmKGkpe2lmKChhJjEpIT09MCluZXcgUC5ycShwLGopLiQwKCl9
-ZWxzZSBpZigoYSYyKSE9PTApbmV3IFAuUlcoYixwKS4kMCgpCmlmKGYhPW51bGwpJC5YMz1mCmE9cC5j
-CmlmKHEuYihhKSl7ZT1wLmEuYgppZihhLmE+PTQpe2Q9ci5hKGUuYykKZS5jPW51bGwKYTE9ZS5OOChk
-KQplLmE9YS5hCmUuYz1hLmMKYi5hPWEKY29udGludWV9ZWxzZSBQLkE5KGEsZSkKcmV0dXJufX1lPXAu
-YS5iCmQ9ci5hKGUuYykKZS5jPW51bGwKYTE9ZS5OOChkKQphPXAuYgprPXAuYwppZighYSl7ZS4kdGku
-Yy5hKGspCmUuYT00CmUuYz1rfWVsc2V7cy5hKGspCmUuYT04CmUuYz1rfWIuYT1lCmE9ZX19LApWSDpm
-dW5jdGlvbihhLGIpe3ZhciBzCmlmKHQuYWcuYihhKSlyZXR1cm4gYi5MaihhLHQueix0LkssdC5sKQpz
-PXQuYkkKaWYocy5iKGEpKXJldHVybiBzLmEoYSkKdGhyb3cgSC5iKFAuTDMoYSwib25FcnJvciIsIkVy
-cm9yIGhhbmRsZXIgbXVzdCBhY2NlcHQgb25lIE9iamVjdCBvciBvbmUgT2JqZWN0IGFuZCBhIFN0YWNr
-VHJhY2UgYXMgYXJndW1lbnRzLCBhbmQgcmV0dXJuIGEgYSB2YWxpZCByZXN1bHQiKSl9LApwdTpmdW5j
-dGlvbigpe3ZhciBzLHIKZm9yKHM9JC5TNjtzIT1udWxsO3M9JC5TNil7JC5tZz1udWxsCnI9cy5iCiQu
-UzY9cgppZihyPT1udWxsKSQuazg9bnVsbApzLmEuJDAoKX19LAplTjpmdW5jdGlvbigpeyQuVUQ9ITAK
-dHJ5e1AucHUoKX1maW5hbGx5eyQubWc9bnVsbAokLlVEPSExCmlmKCQuUzYhPW51bGwpJC51dCgpLiQx
-KFAuVUkoKSl9fSwKZVc6ZnVuY3Rpb24oYSl7dmFyIHM9bmV3IFAuT00oYSkscj0kLms4CmlmKHI9PW51
-bGwpeyQuUzY9JC5rOD1zCmlmKCEkLlVEKSQudXQoKS4kMShQLlVJKCkpfWVsc2UgJC5rOD1yLmI9c30s
-CnJSOmZ1bmN0aW9uKGEpe3ZhciBzLHIscSxwPSQuUzYKaWYocD09bnVsbCl7UC5lVyhhKQokLm1nPSQu
-azgKcmV0dXJufXM9bmV3IFAuT00oYSkKcj0kLm1nCmlmKHI9PW51bGwpe3MuYj1wCiQuUzY9JC5tZz1z
-fWVsc2V7cT1yLmIKcy5iPXEKJC5tZz1yLmI9cwppZihxPT1udWxsKSQuazg9c319LApyYjpmdW5jdGlv
-bihhKXt2YXIgcz1udWxsLHI9JC5YMwppZihDLk5VPT09cil7UC5UayhzLHMsQy5OVSxhKQpyZXR1cm59
-UC5UayhzLHMscix0Lk0uYShyLkdZKGEpKSl9LApRdzpmdW5jdGlvbihhLGIpe0guY2IoYSwic3RyZWFt
-Iix0LkspCnJldHVybiBuZXcgUC54SShiLkMoInhJPDA+IikpfSwKVGw6ZnVuY3Rpb24oYSxiKXt2YXIg
-cz1ILmNiKGEsImVycm9yIix0LkspCnJldHVybiBuZXcgUC5DdyhzLGI9PW51bGw/UC52MChhKTpiKX0s
-CnYwOmZ1bmN0aW9uKGEpe3ZhciBzCmlmKHQuci5iKGEpKXtzPWEuZ0lJKCkKaWYocyE9bnVsbClyZXR1
-cm4gc31yZXR1cm4gQy5wZH0sCkwyOmZ1bmN0aW9uKGEsYixjLGQsZSl7UC5yUihuZXcgUC5wSyhkLGUp
-KX0sClQ4OmZ1bmN0aW9uKGEsYixjLGQsZSl7dmFyIHMscj0kLlgzCmlmKHI9PT1jKXJldHVybiBkLiQw
-KCkKJC5YMz1jCnM9cgp0cnl7cj1kLiQwKCkKcmV0dXJuIHJ9ZmluYWxseXskLlgzPXN9fSwKeXY6ZnVu
-Y3Rpb24oYSxiLGMsZCxlLGYsZyl7dmFyIHMscj0kLlgzCmlmKHI9PT1jKXJldHVybiBkLiQxKGUpCiQu
-WDM9YwpzPXIKdHJ5e3I9ZC4kMShlKQpyZXR1cm4gcn1maW5hbGx5eyQuWDM9c319LApReDpmdW5jdGlv
-bihhLGIsYyxkLGUsZixnLGgsaSl7dmFyIHMscj0kLlgzCmlmKHI9PT1jKXJldHVybiBkLiQyKGUsZikK
-JC5YMz1jCnM9cgp0cnl7cj1kLiQyKGUsZikKcmV0dXJuIHJ9ZmluYWxseXskLlgzPXN9fSwKVGs6ZnVu
-Y3Rpb24oYSxiLGMsZCl7dmFyIHMKdC5NLmEoZCkKcz1DLk5VIT09YwppZihzKWQ9ISghc3x8ITEpP2Mu
-R1koZCk6Yy5SVChkLHQuSCkKUC5lVyhkKX0sCnRoOmZ1bmN0aW9uIHRoKGEpe3RoaXMuYT1hfSwKaGE6
-ZnVuY3Rpb24gaGEoYSxiLGMpe3RoaXMuYT1hCnRoaXMuYj1iCnRoaXMuYz1jfSwKVnM6ZnVuY3Rpb24g
-VnMoYSl7dGhpcy5hPWF9LApGdDpmdW5jdGlvbiBGdChhKXt0aGlzLmE9YX0sClczOmZ1bmN0aW9uIFcz
-KCl7fSwKeUg6ZnVuY3Rpb24geUgoYSxiKXt0aGlzLmE9YQp0aGlzLmI9Yn0sCmloOmZ1bmN0aW9uIGlo
-KGEsYil7dGhpcy5hPWEKdGhpcy5iPSExCnRoaXMuJHRpPWJ9LApXTTpmdW5jdGlvbiBXTShhKXt0aGlz
-LmE9YX0sClNYOmZ1bmN0aW9uIFNYKGEpe3RoaXMuYT1hfSwKR3M6ZnVuY3Rpb24gR3MoYSl7dGhpcy5h
-PWF9LApGeTpmdW5jdGlvbiBGeShhLGIpe3RoaXMuYT1hCnRoaXMuYj1ifSwKR1Y6ZnVuY3Rpb24gR1Yo
-YSxiKXt2YXIgXz10aGlzCl8uYT1hCl8uZD1fLmM9Xy5iPW51bGwKXy4kdGk9Yn0sCnE0OmZ1bmN0aW9u
-IHE0KGEsYil7dGhpcy5hPWEKdGhpcy4kdGk9Yn0sClBmOmZ1bmN0aW9uIFBmKCl7fSwKWmY6ZnVuY3Rp
-b24gWmYoYSxiKXt0aGlzLmE9YQp0aGlzLiR0aT1ifSwKRmU6ZnVuY3Rpb24gRmUoYSxiLGMsZCxlKXt2
-YXIgXz10aGlzCl8uYT1udWxsCl8uYj1hCl8uYz1iCl8uZD1jCl8uZT1kCl8uJHRpPWV9LAp2czpmdW5j
-dGlvbiB2cyhhLGIpe3ZhciBfPXRoaXMKXy5hPTAKXy5iPWEKXy5jPW51bGwKXy4kdGk9Yn0sCmRhOmZ1
-bmN0aW9uIGRhKGEsYil7dGhpcy5hPWEKdGhpcy5iPWJ9LApvUTpmdW5jdGlvbiBvUShhLGIpe3RoaXMu
-YT1hCnRoaXMuYj1ifSwKcFY6ZnVuY3Rpb24gcFYoYSl7dGhpcy5hPWF9LApVNzpmdW5jdGlvbiBVNyhh
-KXt0aGlzLmE9YX0sCnZyOmZ1bmN0aW9uIHZyKGEsYixjKXt0aGlzLmE9YQp0aGlzLmI9Ygp0aGlzLmM9
-Y30sCnJ0OmZ1bmN0aW9uIHJ0KGEsYil7dGhpcy5hPWEKdGhpcy5iPWJ9LApLRjpmdW5jdGlvbiBLRihh
-LGIpe3RoaXMuYT1hCnRoaXMuYj1ifSwKWkw6ZnVuY3Rpb24gWkwoYSxiLGMpe3RoaXMuYT1hCnRoaXMu
-Yj1iCnRoaXMuYz1jfSwKUlQ6ZnVuY3Rpb24gUlQoYSxiLGMpe3RoaXMuYT1hCnRoaXMuYj1iCnRoaXMu
-Yz1jfSwKalo6ZnVuY3Rpb24galooYSl7dGhpcy5hPWF9LApycTpmdW5jdGlvbiBycShhLGIpe3RoaXMu
-YT1hCnRoaXMuYj1ifSwKUlc6ZnVuY3Rpb24gUlcoYSxiKXt0aGlzLmE9YQp0aGlzLmI9Yn0sCk9NOmZ1
-bmN0aW9uIE9NKGEpe3RoaXMuYT1hCnRoaXMuYj1udWxsfSwKcWg6ZnVuY3Rpb24gcWgoKXt9LApCNTpm
-dW5jdGlvbiBCNShhLGIpe3RoaXMuYT1hCnRoaXMuYj1ifSwKdU86ZnVuY3Rpb24gdU8oYSxiKXt0aGlz
-LmE9YQp0aGlzLmI9Yn0sCk1POmZ1bmN0aW9uIE1PKCl7fSwKa1Q6ZnVuY3Rpb24ga1QoKXt9LAp4STpm
-dW5jdGlvbiB4SShhKXt0aGlzLiR0aT1hfSwKQ3c6ZnVuY3Rpb24gQ3coYSxiKXt0aGlzLmE9YQp0aGlz
-LmI9Yn0sCm0wOmZ1bmN0aW9uIG0wKCl7fSwKcEs6ZnVuY3Rpb24gcEsoYSxiKXt0aGlzLmE9YQp0aGlz
-LmI9Yn0sCkppOmZ1bmN0aW9uIEppKCl7fSwKaGo6ZnVuY3Rpb24gaGooYSxiLGMpe3RoaXMuYT1hCnRo
-aXMuYj1iCnRoaXMuYz1jfSwKVnA6ZnVuY3Rpb24gVnAoYSxiKXt0aGlzLmE9YQp0aGlzLmI9Yn0sCk9S
-OmZ1bmN0aW9uIE9SKGEsYixjKXt0aGlzLmE9YQp0aGlzLmI9Ygp0aGlzLmM9Y30sCkVGOmZ1bmN0aW9u
-KGEsYixjKXtyZXR1cm4gYi5DKCJAPDA+IikuS3EoYykuQygiRm88MSwyPiIpLmEoSC5CNyhhLG5ldyBI
-Lk41KGIuQygiQDwwPiIpLktxKGMpLkMoIk41PDEsMj4iKSkpKX0sCkZsOmZ1bmN0aW9uKGEsYil7cmV0
-dXJuIG5ldyBILk41KGEuQygiQDwwPiIpLktxKGIpLkMoIk41PDEsMj4iKSl9LApMczpmdW5jdGlvbihh
-KXtyZXR1cm4gbmV3IFAuYjYoYS5DKCJiNjwwPiIpKX0sClQyOmZ1bmN0aW9uKCl7dmFyIHM9T2JqZWN0
-LmNyZWF0ZShudWxsKQpzWyI8bm9uLWlkZW50aWZpZXIta2V5PiJdPXMKZGVsZXRlIHNbIjxub24taWRl
-bnRpZmllci1rZXk+Il0KcmV0dXJuIHN9LApyajpmdW5jdGlvbihhLGIsYyl7dmFyIHM9bmV3IFAubG0o
-YSxiLGMuQygibG08MD4iKSkKcy5jPWEuZQpyZXR1cm4gc30sCkVQOmZ1bmN0aW9uKGEsYixjKXt2YXIg
-cyxyCmlmKFAuaEIoYSkpe2lmKGI9PT0iKCImJmM9PT0iKSIpcmV0dXJuIiguLi4pIgpyZXR1cm4gYisi
-Li4uIitjfXM9SC5WTShbXSx0LnMpCkMuTm0uaSgkLnhnLGEpCnRyeXtQLlZyKGEscyl9ZmluYWxseXtp
-ZigwPj0kLnhnLmxlbmd0aClyZXR1cm4gSC5PSCgkLnhnLC0xKQokLnhnLnBvcCgpfXI9UC52ZyhiLHQu
-dS5hKHMpLCIsICIpK2MKcmV0dXJuIHIuY2hhckNvZGVBdCgwKT09MD9yOnJ9LApXRTpmdW5jdGlvbihh
-LGIsYyl7dmFyIHMscgppZihQLmhCKGEpKXJldHVybiBiKyIuLi4iK2MKcz1uZXcgUC5SbihiKQpDLk5t
-LmkoJC54ZyxhKQp0cnl7cj1zCnIuYT1QLnZnKHIuYSxhLCIsICIpfWZpbmFsbHl7aWYoMD49JC54Zy5s
-ZW5ndGgpcmV0dXJuIEguT0goJC54ZywtMSkKJC54Zy5wb3AoKX1zLmErPWMKcj1zLmEKcmV0dXJuIHIu
-Y2hhckNvZGVBdCgwKT09MD9yOnJ9LApoQjpmdW5jdGlvbihhKXt2YXIgcyxyCmZvcihzPSQueGcubGVu
-Z3RoLHI9MDtyPHM7KytyKWlmKGE9PT0kLnhnW3JdKXJldHVybiEwCnJldHVybiExfSwKVnI6ZnVuY3Rp
-b24oYSxiKXt2YXIgcyxyLHEscCxvLG4sbSxsPWEuZ20oYSksaz0wLGo9MAp3aGlsZSghMCl7aWYoIShr
-PDgwfHxqPDMpKWJyZWFrCmlmKCFsLkYoKSlyZXR1cm4Kcz1ILkVqKGwuZ2woKSkKQy5ObS5pKGIscykK
-ays9cy5sZW5ndGgrMjsrK2p9aWYoIWwuRigpKXtpZihqPD01KXJldHVybgppZigwPj1iLmxlbmd0aCly
-ZXR1cm4gSC5PSChiLC0xKQpyPWIucG9wKCkKaWYoMD49Yi5sZW5ndGgpcmV0dXJuIEguT0goYiwtMSkK
-cT1iLnBvcCgpfWVsc2V7cD1sLmdsKCk7KytqCmlmKCFsLkYoKSl7aWYoajw9NCl7Qy5ObS5pKGIsSC5F
-aihwKSkKcmV0dXJufXI9SC5FaihwKQppZigwPj1iLmxlbmd0aClyZXR1cm4gSC5PSChiLC0xKQpxPWIu
-cG9wKCkKays9ci5sZW5ndGgrMn1lbHNle289bC5nbCgpOysragpmb3IoO2wuRigpO3A9byxvPW4pe249
-bC5nbCgpOysragppZihqPjEwMCl7d2hpbGUoITApe2lmKCEoaz43NSYmaj4zKSlicmVhawppZigwPj1i
-Lmxlbmd0aClyZXR1cm4gSC5PSChiLC0xKQprLT1iLnBvcCgpLmxlbmd0aCsyOy0tan1DLk5tLmkoYiwi
-Li4uIikKcmV0dXJufX1xPUguRWoocCkKcj1ILkVqKG8pCmsrPXIubGVuZ3RoK3EubGVuZ3RoKzR9fWlm
-KGo+Yi5sZW5ndGgrMil7ays9NQptPSIuLi4ifWVsc2UgbT1udWxsCndoaWxlKCEwKXtpZighKGs+ODAm
-JmIubGVuZ3RoPjMpKWJyZWFrCmlmKDA+PWIubGVuZ3RoKXJldHVybiBILk9IKGIsLTEpCmstPWIucG9w
-KCkubGVuZ3RoKzIKaWYobT09bnVsbCl7ays9NQptPSIuLi4ifX1pZihtIT1udWxsKUMuTm0uaShiLG0p
-CkMuTm0uaShiLHEpCkMuTm0uaShiLHIpfSwKdE06ZnVuY3Rpb24oYSxiKXt2YXIgcyxyLHE9UC5Mcyhi
-KQpmb3Iocz1hLmxlbmd0aCxyPTA7cjxhLmxlbmd0aDthLmxlbmd0aD09PXN8fCgwLEgubGspKGEpLCsr
-cilxLmkoMCxiLmEoYVtyXSkpCnJldHVybiBxfSwKbk86ZnVuY3Rpb24oYSl7dmFyIHMscj17fQppZihQ
-LmhCKGEpKXJldHVybiJ7Li4ufSIKcz1uZXcgUC5SbigiIikKdHJ5e0MuTm0uaSgkLnhnLGEpCnMuYSs9
-InsiCnIuYT0hMAphLksoMCxuZXcgUC5yYShyLHMpKQpzLmErPSJ9In1maW5hbGx5e2lmKDA+PSQueGcu
-bGVuZ3RoKXJldHVybiBILk9IKCQueGcsLTEpCiQueGcucG9wKCl9cj1zLmEKcmV0dXJuIHIuY2hhckNv
-ZGVBdCgwKT09MD9yOnJ9LApiNjpmdW5jdGlvbiBiNihhKXt2YXIgXz10aGlzCl8uYT0wCl8uZj1fLmU9
-Xy5kPV8uYz1fLmI9bnVsbApfLnI9MApfLiR0aT1hfSwKYm46ZnVuY3Rpb24gYm4oYSl7dGhpcy5hPWEK
-dGhpcy5jPXRoaXMuYj1udWxsfSwKbG06ZnVuY3Rpb24gbG0oYSxiLGMpe3ZhciBfPXRoaXMKXy5hPWEK
-Xy5iPWIKXy5kPV8uYz1udWxsCl8uJHRpPWN9LAptVzpmdW5jdGlvbiBtVygpe30sCnV5OmZ1bmN0aW9u
-IHV5KCl7fSwKbEQ6ZnVuY3Rpb24gbEQoKXt9LAppbDpmdW5jdGlvbiBpbCgpe30sCnJhOmZ1bmN0aW9u
-IHJhKGEsYil7dGhpcy5hPWEKdGhpcy5iPWJ9LApZazpmdW5jdGlvbiBZaygpe30sCnlROmZ1bmN0aW9u
-IHlRKGEpe3RoaXMuYT1hfSwKS1A6ZnVuY3Rpb24gS1AoKXt9LApQbjpmdW5jdGlvbiBQbigpe30sCkdq
-OmZ1bmN0aW9uIEdqKGEsYil7dGhpcy5hPWEKdGhpcy4kdGk9Yn0sCmxmOmZ1bmN0aW9uIGxmKCl7fSwK
-Vmo6ZnVuY3Rpb24gVmooKXt9LApYdjpmdW5jdGlvbiBYdigpe30sCm5ZOmZ1bmN0aW9uIG5ZKCl7fSwK
-V1k6ZnVuY3Rpb24gV1koKXt9LApSVTpmdW5jdGlvbiBSVSgpe30sCnBSOmZ1bmN0aW9uIHBSKCl7fSwK
-QlM6ZnVuY3Rpb24oYSxiKXt2YXIgcyxyLHEscAppZih0eXBlb2YgYSE9InN0cmluZyIpdGhyb3cgSC5i
-KEgudEwoYSkpCnM9bnVsbAp0cnl7cz1KU09OLnBhcnNlKGEpfWNhdGNoKHEpe3I9SC5SdShxKQpwPVAu
-cnIoU3RyaW5nKHIpLG51bGwsbnVsbCkKdGhyb3cgSC5iKHApfXA9UC5RZShzKQpyZXR1cm4gcH0sClFl
-OmZ1bmN0aW9uKGEpe3ZhciBzCmlmKGE9PW51bGwpcmV0dXJuIG51bGwKaWYodHlwZW9mIGEhPSJvYmpl
-Y3QiKXJldHVybiBhCmlmKE9iamVjdC5nZXRQcm90b3R5cGVPZihhKSE9PUFycmF5LnByb3RvdHlwZSly
-ZXR1cm4gbmV3IFAudXcoYSxPYmplY3QuY3JlYXRlKG51bGwpKQpmb3Iocz0wO3M8YS5sZW5ndGg7Kytz
-KWFbc109UC5RZShhW3NdKQpyZXR1cm4gYX0sCmt5OmZ1bmN0aW9uKGEsYixjLGQpe3ZhciBzLHIKaWYo
-YiBpbnN0YW5jZW9mIFVpbnQ4QXJyYXkpe3M9YgpkPXMubGVuZ3RoCmlmKGQtYzwxNSlyZXR1cm4gbnVs
-bApyPVAuQ0coYSxzLGMsZCkKaWYociE9bnVsbCYmYSlpZihyLmluZGV4T2YoIlx1ZmZmZCIpPj0wKXJl
-dHVybiBudWxsCnJldHVybiByfXJldHVybiBudWxsfSwKQ0c6ZnVuY3Rpb24oYSxiLGMsZCl7dmFyIHM9
-YT8kLkhHKCk6JC5yZigpCmlmKHM9PW51bGwpcmV0dXJuIG51bGwKaWYoMD09PWMmJmQ9PT1iLmxlbmd0
-aClyZXR1cm4gUC5SYihzLGIpCnJldHVybiBQLlJiKHMsYi5zdWJhcnJheShjLFAuakIoYyxkLGIubGVu
-Z3RoKSkpfSwKUmI6ZnVuY3Rpb24oYSxiKXt2YXIgcyxyCnRyeXtzPWEuZGVjb2RlKGIpCnJldHVybiBz
-fWNhdGNoKHIpe0guUnUocil9cmV0dXJuIG51bGx9LAp4TTpmdW5jdGlvbihhLGIsYyxkLGUsZil7aWYo
-Qy5qbi56WShmLDQpIT09MCl0aHJvdyBILmIoUC5ycigiSW52YWxpZCBiYXNlNjQgcGFkZGluZywgcGFk
-ZGVkIGxlbmd0aCBtdXN0IGJlIG11bHRpcGxlIG9mIGZvdXIsIGlzICIrZixhLGMpKQppZihkK2UhPT1m
-KXRocm93IEguYihQLnJyKCJJbnZhbGlkIGJhc2U2NCBwYWRkaW5nLCAnPScgbm90IGF0IHRoZSBlbmQi
-LGEsYikpCmlmKGU+Mil0aHJvdyBILmIoUC5ycigiSW52YWxpZCBiYXNlNjQgcGFkZGluZywgbW9yZSB0
-aGFuIHR3byAnPScgY2hhcmFjdGVycyIsYSxiKSl9LApHeTpmdW5jdGlvbihhLGIsYyl7cmV0dXJuIG5l
-dyBQLlVkKGEsYil9LApOQzpmdW5jdGlvbihhKXtyZXR1cm4gYS5MdCgpfSwKVWc6ZnVuY3Rpb24oYSxi
-KXtyZXR1cm4gbmV3IFAudHUoYSxbXSxQLkN5KCkpfSwKdVg6ZnVuY3Rpb24oYSxiLGMpe3ZhciBzLHI9
-bmV3IFAuUm4oIiIpLHE9UC5VZyhyLGIpCnEuaVUoYSkKcz1yLmEKcmV0dXJuIHMuY2hhckNvZGVBdCgw
-KT09MD9zOnN9LApqNDpmdW5jdGlvbihhKXtzd2l0Y2goYSl7Y2FzZSA2NTpyZXR1cm4iTWlzc2luZyBl
-eHRlbnNpb24gYnl0ZSIKY2FzZSA2NzpyZXR1cm4iVW5leHBlY3RlZCBleHRlbnNpb24gYnl0ZSIKY2Fz
-ZSA2OTpyZXR1cm4iSW52YWxpZCBVVEYtOCBieXRlIgpjYXNlIDcxOnJldHVybiJPdmVybG9uZyBlbmNv
-ZGluZyIKY2FzZSA3MzpyZXR1cm4iT3V0IG9mIHVuaWNvZGUgcmFuZ2UiCmNhc2UgNzU6cmV0dXJuIkVu
-Y29kZWQgc3Vycm9nYXRlIgpjYXNlIDc3OnJldHVybiJVbmZpbmlzaGVkIFVURi04IG9jdGV0IHNlcXVl
-bmNlIgpkZWZhdWx0OnJldHVybiIifX0sCmp5OmZ1bmN0aW9uKGEsYixjKXt2YXIgcyxyLHEscD1jLWIs
-bz1uZXcgVWludDhBcnJheShwKQpmb3Iocz1KLlU2KGEpLHI9MDtyPHA7KytyKXtxPXMucShhLGIrcikK
-aWYodHlwZW9mIHEhPT0ibnVtYmVyIilyZXR1cm4gcS56TSgpCmlmKChxJjQyOTQ5NjcwNDApPj4+MCE9
-PTApcT0yNTUKaWYocj49cClyZXR1cm4gSC5PSChvLHIpCm9bcl09cX1yZXR1cm4gb30sCnV3OmZ1bmN0
-aW9uIHV3KGEsYil7dGhpcy5hPWEKdGhpcy5iPWIKdGhpcy5jPW51bGx9LAppODpmdW5jdGlvbiBpOChh
-KXt0aGlzLmE9YX0sCnBnOmZ1bmN0aW9uIHBnKCl7fSwKYzI6ZnVuY3Rpb24gYzIoKXt9LApDVjpmdW5j
-dGlvbiBDVigpe30sClU4OmZ1bmN0aW9uIFU4KCl7fSwKVWs6ZnVuY3Rpb24gVWsoKXt9LAp3STpmdW5j
-dGlvbiB3SSgpe30sClppOmZ1bmN0aW9uIFppKCl7fSwKVWQ6ZnVuY3Rpb24gVWQoYSxiKXt0aGlzLmE9
-YQp0aGlzLmI9Yn0sCks4OmZ1bmN0aW9uIEs4KGEsYil7dGhpcy5hPWEKdGhpcy5iPWJ9LApieTpmdW5j
-dGlvbiBieSgpe30sCm9qOmZ1bmN0aW9uIG9qKGEpe3RoaXMuYj1hfSwKTXg6ZnVuY3Rpb24gTXgoYSl7
-dGhpcy5hPWF9LApTaDpmdW5jdGlvbiBTaCgpe30sCnRpOmZ1bmN0aW9uIHRpKGEsYil7dGhpcy5hPWEK
-dGhpcy5iPWJ9LAp0dTpmdW5jdGlvbiB0dShhLGIsYyl7dGhpcy5jPWEKdGhpcy5hPWIKdGhpcy5iPWN9
-LAp1NTpmdW5jdGlvbiB1NSgpe30sCkUzOmZ1bmN0aW9uIEUzKCl7fSwKUnc6ZnVuY3Rpb24gUncoYSl7
-dGhpcy5iPTAKdGhpcy5jPWF9LApHWTpmdW5jdGlvbiBHWShhKXt0aGlzLmE9YX0sCmJ6OmZ1bmN0aW9u
-IGJ6KGEpe3RoaXMuYT1hCnRoaXMuYj0xNgp0aGlzLmM9MH0sClFBOmZ1bmN0aW9uKGEsYil7dmFyIHM9
-SC5IcChhLGIpCmlmKHMhPW51bGwpcmV0dXJuIHMKdGhyb3cgSC5iKFAucnIoYSxudWxsLG51bGwpKX0s
-Cm9zOmZ1bmN0aW9uKGEpe2lmKGEgaW5zdGFuY2VvZiBILlRwKXJldHVybiBhLncoMCkKcmV0dXJuIklu
-c3RhbmNlIG9mICciK0guRWooSC5NKGEpKSsiJyJ9LApPODpmdW5jdGlvbihhLGIsYyxkKXt2YXIgcyxy
-PWM/Si5LaChhLGQpOkouUWkoYSxkKQppZihhIT09MCYmYiE9bnVsbClmb3Iocz0wO3M8ci5sZW5ndGg7
-KytzKXJbc109YgpyZXR1cm4gcn0sCkNIOmZ1bmN0aW9uKGEsYixjKXt2YXIgcyxyPUguVk0oW10sYy5D
-KCJqZDwwPiIpKQpmb3Iocz1KLklUKGEpO3MuRigpOylDLk5tLmkocixjLmEocy5nbCgpKSkKaWYoYily
-ZXR1cm4gcgpyZXR1cm4gSi5FcChyLGMpfSwKWTE6ZnVuY3Rpb24oYSxiLGMpe3ZhciBzCmlmKGIpcmV0
-dXJuIFAuZXYoYSxjKQpzPUouRXAoUC5ldihhLGMpLGMpCnJldHVybiBzfSwKZXY6ZnVuY3Rpb24oYSxi
-KXt2YXIgcyxyPUguVk0oW10sYi5DKCJqZDwwPiIpKQpmb3Iocz1KLklUKGEpO3MuRigpOylDLk5tLmko
-cixzLmdsKCkpCnJldHVybiByfSwKQUY6ZnVuY3Rpb24oYSxiKXtyZXR1cm4gSi56QyhQLkNIKGEsITEs
-YikpfSwKSE06ZnVuY3Rpb24oYSxiLGMpe2lmKHQuYm0uYihhKSlyZXR1cm4gSC5mdyhhLGIsUC5qQihi
-LGMsYS5sZW5ndGgpKQpyZXR1cm4gUC5idyhhLGIsYyl9LApPbzpmdW5jdGlvbihhKXtyZXR1cm4gSC5M
-dyhhKX0sCmJ3OmZ1bmN0aW9uKGEsYixjKXt2YXIgcyxyLHEscCxvPW51bGwKaWYoYjwwKXRocm93IEgu
-YihQLlRFKGIsMCxhLmxlbmd0aCxvLG8pKQpzPWM9PW51bGwKaWYoIXMmJmM8Yil0aHJvdyBILmIoUC5U
-RShjLGIsYS5sZW5ndGgsbyxvKSkKcj1uZXcgSC5hNyhhLGEubGVuZ3RoLEgueihhKS5DKCJhNzxsRC5F
-PiIpKQpmb3IocT0wO3E8YjsrK3EpaWYoIXIuRigpKXRocm93IEguYihQLlRFKGIsMCxxLG8sbykpCnA9
-W10KaWYocylmb3IoO3IuRigpOylwLnB1c2goci5kKQplbHNlIGZvcihxPWI7cTxjOysrcSl7aWYoIXIu
-RigpKXRocm93IEguYihQLlRFKGMsYixxLG8sbykpCnAucHVzaChyLmQpfXJldHVybiBILmVUKHApfSwK
-bnU6ZnVuY3Rpb24oYSl7cmV0dXJuIG5ldyBILlZSKGEsSC52NChhLCExLCEwLCExLCExLCExKSl9LAp2
-ZzpmdW5jdGlvbihhLGIsYyl7dmFyIHM9Si5JVChiKQppZighcy5GKCkpcmV0dXJuIGEKaWYoYy5sZW5n
-dGg9PT0wKXtkbyBhKz1ILkVqKHMuZ2woKSkKd2hpbGUocy5GKCkpfWVsc2V7YSs9SC5FaihzLmdsKCkp
-CmZvcig7cy5GKCk7KWE9YStjK0guRWoocy5nbCgpKX1yZXR1cm4gYX0sCmxyOmZ1bmN0aW9uKGEsYixj
-LGQpe3JldHVybiBuZXcgUC5tcChhLGIsYyxkKX0sCnVvOmZ1bmN0aW9uKCl7dmFyIHM9SC5NMCgpCmlm
-KHMhPW51bGwpcmV0dXJuIFAuaEsocykKdGhyb3cgSC5iKFAuTDQoIidVcmkuYmFzZScgaXMgbm90IHN1
-cHBvcnRlZCIpKX0sCmVQOmZ1bmN0aW9uKGEsYixjLGQpe3ZhciBzLHIscSxwLG8sbixtPSIwMTIzNDU2
-Nzg5QUJDREVGIgppZihjPT09Qy54TSl7cz0kLno0KCkuYgppZih0eXBlb2YgYiE9InN0cmluZyIpSC52
-KEgudEwoYikpCnM9cy50ZXN0KGIpfWVsc2Ugcz0hMQppZihzKXJldHVybiBiCkguTGgoYykuQygiVWsu
-UyIpLmEoYikKcj1jLmdaRSgpLldKKGIpCmZvcihzPXIubGVuZ3RoLHE9MCxwPSIiO3E8czsrK3Epe289
-cltxXQppZihvPDEyOCl7bj1vPj4+NAppZihuPj04KXJldHVybiBILk9IKGEsbikKbj0oYVtuXSYxPDwo
-byYxNSkpIT09MH1lbHNlIG49ITEKaWYobilwKz1ILkx3KG8pCmVsc2UgcD1kJiZvPT09MzI/cCsiKyI6
-cCsiJSIrbVtvPj4+NCYxNV0rbVtvJjE1XX1yZXR1cm4gcC5jaGFyQ29kZUF0KDApPT0wP3A6cH0sCkdx
-OmZ1bmN0aW9uKGEpe3ZhciBzPU1hdGguYWJzKGEpLHI9YTwwPyItIjoiIgppZihzPj0xMDAwKXJldHVy
-biIiK2EKaWYocz49MTAwKXJldHVybiByKyIwIitzCmlmKHM+PTEwKXJldHVybiByKyIwMCIrcwpyZXR1
-cm4gcisiMDAwIitzfSwKVng6ZnVuY3Rpb24oYSl7aWYoYT49MTAwKXJldHVybiIiK2EKaWYoYT49MTAp
-cmV0dXJuIjAiK2EKcmV0dXJuIjAwIithfSwKaDA6ZnVuY3Rpb24oYSl7aWYoYT49MTApcmV0dXJuIiIr
-YQpyZXR1cm4iMCIrYX0sCnA6ZnVuY3Rpb24oYSl7aWYodHlwZW9mIGE9PSJudW1iZXIifHxILmwoYSl8
-fG51bGw9PWEpcmV0dXJuIEouaihhKQppZih0eXBlb2YgYT09InN0cmluZyIpcmV0dXJuIEpTT04uc3Ry
-aW5naWZ5KGEpCnJldHVybiBQLm9zKGEpfSwKaFY6ZnVuY3Rpb24oYSl7cmV0dXJuIG5ldyBQLkM2KGEp
-fSwKeFk6ZnVuY3Rpb24oYSl7cmV0dXJuIG5ldyBQLnUoITEsbnVsbCxudWxsLGEpfSwKTDM6ZnVuY3Rp
-b24oYSxiLGMpe3JldHVybiBuZXcgUC51KCEwLGEsYixjKX0sCk1SOmZ1bmN0aW9uKGEsYixjKXtyZXR1
-cm4gYX0sCk83OmZ1bmN0aW9uKGEsYil7cmV0dXJuIG5ldyBQLmJKKG51bGwsbnVsbCwhMCxhLGIsIlZh
-bHVlIG5vdCBpbiByYW5nZSIpfSwKVEU6ZnVuY3Rpb24oYSxiLGMsZCxlKXtyZXR1cm4gbmV3IFAuYkoo
-YixjLCEwLGEsZCwiSW52YWxpZCB2YWx1ZSIpfSwKd0E6ZnVuY3Rpb24oYSxiLGMsZCl7aWYoYTxifHxh
-PmMpdGhyb3cgSC5iKFAuVEUoYSxiLGMsZCxudWxsKSkKcmV0dXJuIGF9LApqQjpmdW5jdGlvbihhLGIs
-Yyl7aWYoMD5hfHxhPmMpdGhyb3cgSC5iKFAuVEUoYSwwLGMsInN0YXJ0IixudWxsKSkKaWYoYiE9bnVs
-bCl7aWYoYT5ifHxiPmMpdGhyb3cgSC5iKFAuVEUoYixhLGMsImVuZCIsbnVsbCkpCnJldHVybiBifXJl
-dHVybiBjfSwKazE6ZnVuY3Rpb24oYSxiKXtpZihhPDApdGhyb3cgSC5iKFAuVEUoYSwwLG51bGwsYixu
-dWxsKSkKcmV0dXJuIGF9LApDZjpmdW5jdGlvbihhLGIsYyxkLGUpe3ZhciBzPUgudVAoZT09bnVsbD9K
-LkhtKGIpOmUpCnJldHVybiBuZXcgUC5lWShzLCEwLGEsYywiSW5kZXggb3V0IG9mIHJhbmdlIil9LApM
-NDpmdW5jdGlvbihhKXtyZXR1cm4gbmV3IFAudWIoYSl9LApTWTpmdW5jdGlvbihhKXtyZXR1cm4gbmV3
-IFAuZHMoYSl9LApQVjpmdW5jdGlvbihhKXtyZXR1cm4gbmV3IFAubGooYSl9LAphNDpmdW5jdGlvbihh
-KXtyZXR1cm4gbmV3IFAuVVYoYSl9LApycjpmdW5jdGlvbihhLGIsYyl7cmV0dXJuIG5ldyBQLmFFKGEs
-YixjKX0sCmhLOmZ1bmN0aW9uKGE1KXt2YXIgcyxyLHEscCxvLG4sbSxsLGssaixpLGgsZyxmLGUsZCxj
-LGIsYSxhMCxhMSxhMixhMz1udWxsLGE0PWE1Lmxlbmd0aAppZihhND49NSl7cz0oKEouUXooYTUsNCle
-NTgpKjN8Qy54Qi5XKGE1LDApXjEwMHxDLnhCLlcoYTUsMSleOTd8Qy54Qi5XKGE1LDIpXjExNnxDLnhC
-LlcoYTUsMyleOTcpPj4+MAppZihzPT09MClyZXR1cm4gUC5LRChhNDxhND9DLnhCLk5qKGE1LDAsYTQp
-OmE1LDUsYTMpLmdsUigpCmVsc2UgaWYocz09PTMyKXJldHVybiBQLktEKEMueEIuTmooYTUsNSxhNCks
-MCxhMykuZ2xSKCl9cj1QLk84KDgsMCwhMSx0LlMpCkMuTm0uWShyLDAsMCkKQy5ObS5ZKHIsMSwtMSkK
-Qy5ObS5ZKHIsMiwtMSkKQy5ObS5ZKHIsNywtMSkKQy5ObS5ZKHIsMywwKQpDLk5tLlkociw0LDApCkMu
-Tm0uWShyLDUsYTQpCkMuTm0uWShyLDYsYTQpCmlmKFAuVUIoYTUsMCxhNCwwLHIpPj0xNClDLk5tLlko
-ciw3LGE0KQpxPXJbMV0KaWYocT49MClpZihQLlVCKGE1LDAscSwyMCxyKT09PTIwKXJbN109cQpwPXJb
-Ml0rMQpvPXJbM10Kbj1yWzRdCm09cls1XQpsPXJbNl0KaWYobDxtKW09bAppZihuPHApbj1tCmVsc2Ug
-aWYobjw9cSluPXErMQppZihvPHApbz1uCms9cls3XTwwCmlmKGspaWYocD5xKzMpe2o9YTMKaz0hMX1l
-bHNle2k9bz4wCmlmKGkmJm8rMT09PW4pe2o9YTMKaz0hMX1lbHNle2lmKCEobTxhNCYmbT09PW4rMiYm
-Si5xMChhNSwiLi4iLG4pKSloPW0+bisyJiZKLnEwKGE1LCIvLi4iLG0tMykKZWxzZSBoPSEwCmlmKGgp
-e2o9YTMKaz0hMX1lbHNle2lmKHE9PT00KWlmKEoucTAoYTUsImZpbGUiLDApKXtpZihwPD0wKXtpZigh
-Qy54Qi5RaShhNSwiLyIsbikpe2c9ImZpbGU6Ly8vIgpzPTN9ZWxzZXtnPSJmaWxlOi8vIgpzPTJ9YTU9
-ZytDLnhCLk5qKGE1LG4sYTQpCnEtPTAKaT1zLTAKbSs9aQpsKz1pCmE0PWE1Lmxlbmd0aApwPTcKbz03
-Cm49N31lbHNlIGlmKG49PT1tKXsrK2wKZj1tKzEKYTU9Qy54Qi5pNyhhNSxuLG0sIi8iKTsrK2E0Cm09
-Zn1qPSJmaWxlIn1lbHNlIGlmKEMueEIuUWkoYTUsImh0dHAiLDApKXtpZihpJiZvKzM9PT1uJiZDLnhC
-LlFpKGE1LCI4MCIsbysxKSl7bC09MwplPW4tMwptLT0zCmE1PUMueEIuaTcoYTUsbyxuLCIiKQphNC09
-MwpuPWV9aj0iaHR0cCJ9ZWxzZSBqPWEzCmVsc2UgaWYocT09PTUmJkoucTAoYTUsImh0dHBzIiwwKSl7
-aWYoaSYmbys0PT09biYmSi5xMChhNSwiNDQzIixvKzEpKXtsLT00CmU9bi00Cm0tPTQKYTU9Si5kZyhh
-NSxvLG4sIiIpCmE0LT0zCm49ZX1qPSJodHRwcyJ9ZWxzZSBqPWEzCms9ITB9fX1lbHNlIGo9YTMKaWYo
-ayl7aT1hNS5sZW5ndGgKaWYoYTQ8aSl7YTU9Si5sZChhNSwwLGE0KQpxLT0wCnAtPTAKby09MApuLT0w
-Cm0tPTAKbC09MH1yZXR1cm4gbmV3IFAuVWYoYTUscSxwLG8sbixtLGwsail9aWYoaj09bnVsbClpZihx
-PjApaj1QLlBpKGE1LDAscSkKZWxzZXtpZihxPT09MCl7UC5SMyhhNSwwLCJJbnZhbGlkIGVtcHR5IHNj
-aGVtZSIpCkguQmkodS5nKX1qPSIifWlmKHA+MCl7ZD1xKzMKYz1kPHA/UC56UihhNSxkLHAtMSk6IiIK
-Yj1QLk9lKGE1LHAsbywhMSkKaT1vKzEKaWYoaTxuKXthPUguSHAoSi5sZChhNSxpLG4pLGEzKQphMD1Q
-LndCKGE9PW51bGw/SC52KFAucnIoIkludmFsaWQgcG9ydCIsYTUsaSkpOmEsail9ZWxzZSBhMD1hM31l
-bHNle2EwPWEzCmI9YTAKYz0iIn1hMT1QLmthKGE1LG4sbSxhMyxqLGIhPW51bGwpCmEyPW08bD9QLmxl
-KGE1LG0rMSxsLGEzKTphMwpyZXR1cm4gbmV3IFAuRG4oaixjLGIsYTAsYTEsYTIsbDxhND9QLnRHKGE1
-LGwrMSxhNCk6YTMpfSwKTXQ6ZnVuY3Rpb24oYSl7SC5oKGEpCnJldHVybiBQLmt1KGEsMCxhLmxlbmd0
-aCxDLnhNLCExKX0sCldYOmZ1bmN0aW9uKGEpe3ZhciBzPXQuTgpyZXR1cm4gQy5ObS5OMChILlZNKGEu
-c3BsaXQoIiYiKSx0LnMpLFAuRmwocyxzKSxuZXcgUC5uMShDLnhNKSx0LkopfSwKSGg6ZnVuY3Rpb24o
-YSxiLGMpe3ZhciBzLHIscSxwLG8sbixtPSJJUHY0IGFkZHJlc3Mgc2hvdWxkIGNvbnRhaW4gZXhhY3Rs
-eSA0IHBhcnRzIixsPSJlYWNoIHBhcnQgbXVzdCBiZSBpbiB0aGUgcmFuZ2UgMC4uMjU1IixrPW5ldyBQ
-LmNTKGEpLGo9bmV3IFVpbnQ4QXJyYXkoNCkKZm9yKHM9YixyPXMscT0wO3M8YzsrK3Mpe3A9Qy54Qi5P
-MihhLHMpCmlmKHAhPT00Nil7aWYoKHBeNDgpPjkpay4kMigiaW52YWxpZCBjaGFyYWN0ZXIiLHMpfWVs
-c2V7aWYocT09PTMpay4kMihtLHMpCm89UC5RQShDLnhCLk5qKGEscixzKSxudWxsKQppZihvPjI1NSlr
-LiQyKGwscikKbj1xKzEKaWYocT49NClyZXR1cm4gSC5PSChqLHEpCmpbcV09bwpyPXMrMQpxPW59fWlm
-KHEhPT0zKWsuJDIobSxjKQpvPVAuUUEoQy54Qi5OaihhLHIsYyksbnVsbCkKaWYobz4yNTUpay4kMihs
-LHIpCmlmKHE+PTQpcmV0dXJuIEguT0goaixxKQpqW3FdPW8KcmV0dXJuIGp9LAplZzpmdW5jdGlvbihh
-LGIsYTApe3ZhciBzLHIscSxwLG8sbixtLGwsayxqLGksaCxnLGYsZSxkPW5ldyBQLlZDKGEpLGM9bmV3
-IFAuSlQoZCxhKQppZihhLmxlbmd0aDwyKWQuJDEoImFkZHJlc3MgaXMgdG9vIHNob3J0IikKcz1ILlZN
-KFtdLHQuYSkKZm9yKHI9YixxPXIscD0hMSxvPSExO3I8YTA7KytyKXtuPUMueEIuTzIoYSxyKQppZihu
-PT09NTgpe2lmKHI9PT1iKXsrK3IKaWYoQy54Qi5PMihhLHIpIT09NTgpZC4kMigiaW52YWxpZCBzdGFy
-dCBjb2xvbi4iLHIpCnE9cn1pZihyPT09cSl7aWYocClkLiQyKCJvbmx5IG9uZSB3aWxkY2FyZCBgOjpg
-IGlzIGFsbG93ZWQiLHIpCkMuTm0uaShzLC0xKQpwPSEwfWVsc2UgQy5ObS5pKHMsYy4kMihxLHIpKQpx
-PXIrMX1lbHNlIGlmKG49PT00NilvPSEwfWlmKHMubGVuZ3RoPT09MClkLiQxKCJ0b28gZmV3IHBhcnRz
-IikKbT1xPT09YTAKbD1DLk5tLmdyWihzKQppZihtJiZsIT09LTEpZC4kMigiZXhwZWN0ZWQgYSBwYXJ0
-IGFmdGVyIGxhc3QgYDpgIixhMCkKaWYoIW0paWYoIW8pQy5ObS5pKHMsYy4kMihxLGEwKSkKZWxzZXtr
-PVAuSGgoYSxxLGEwKQpDLk5tLmkocywoa1swXTw8OHxrWzFdKT4+PjApCkMuTm0uaShzLChrWzJdPDw4
-fGtbM10pPj4+MCl9aWYocCl7aWYocy5sZW5ndGg+NylkLiQxKCJhbiBhZGRyZXNzIHdpdGggYSB3aWxk
-Y2FyZCBtdXN0IGhhdmUgbGVzcyB0aGFuIDcgcGFydHMiKX1lbHNlIGlmKHMubGVuZ3RoIT09OClkLiQx
-KCJhbiBhZGRyZXNzIHdpdGhvdXQgYSB3aWxkY2FyZCBtdXN0IGNvbnRhaW4gZXhhY3RseSA4IHBhcnRz
-IikKaj1uZXcgVWludDhBcnJheSgxNikKZm9yKGw9cy5sZW5ndGgsaT05LWwscj0wLGg9MDtyPGw7Kyty
-KXtnPXNbcl0KaWYoZz09PS0xKWZvcihmPTA7ZjxpOysrZil7aWYoaDwwfHxoPj0xNilyZXR1cm4gSC5P
-SChqLGgpCmpbaF09MAplPWgrMQppZihlPj0xNilyZXR1cm4gSC5PSChqLGUpCmpbZV09MApoKz0yfWVs
-c2V7ZT1DLmpuLndHKGcsOCkKaWYoaDwwfHxoPj0xNilyZXR1cm4gSC5PSChqLGgpCmpbaF09ZQplPWgr
-MQppZihlPj0xNilyZXR1cm4gSC5PSChqLGUpCmpbZV09ZyYyNTUKaCs9Mn19cmV0dXJuIGp9LApLTDpm
-dW5jdGlvbihhLGIsYyxkLGUsZixnKXt2YXIgcyxyLHEscCxvLG4KZj1mPT1udWxsPyIiOlAuUGkoZiww
-LGYubGVuZ3RoKQpnPVAuelIoZywwLGc9PW51bGw/MDpnLmxlbmd0aCkKYT1QLk9lKGEsMCxhPT1udWxs
-PzA6YS5sZW5ndGgsITEpCnM9UC5sZShudWxsLDAsMCxlKQpyPVAudEcobnVsbCwwLDApCmQ9UC53Qihk
-LGYpCnE9Zj09PSJmaWxlIgppZihhPT1udWxsKXA9Zy5sZW5ndGghPT0wfHxkIT1udWxsfHxxCmVsc2Ug
-cD0hMQppZihwKWE9IiIKcD1hPT1udWxsCm89IXAKYj1QLmthKGIsMCxiPT1udWxsPzA6Yi5sZW5ndGgs
-YyxmLG8pCm49Zi5sZW5ndGg9PT0wCmlmKG4mJnAmJiFDLnhCLm4oYiwiLyIpKWI9UC53RihiLCFufHxv
-KQplbHNlIGI9UC54ZShiKQpyZXR1cm4gbmV3IFAuRG4oZixnLHAmJkMueEIubihiLCIvLyIpPyIiOmEs
-ZCxiLHMscil9LAp3SzpmdW5jdGlvbihhKXtpZihhPT09Imh0dHAiKXJldHVybiA4MAppZihhPT09Imh0
-dHBzIilyZXR1cm4gNDQzCnJldHVybiAwfSwKUjM6ZnVuY3Rpb24oYSxiLGMpe3Rocm93IEguYihQLnJy
-KGMsYSxiKSl9LApYZDpmdW5jdGlvbihhLGIsYyxkKXt2YXIgcyxyLHEscCxvLG4sbSxsLGssaixpLGg9
-bnVsbCxnPWIubGVuZ3RoCmlmKGchPT0wKXtxPTAKd2hpbGUoITApe2lmKCEocTxnKSl7cz0iIgpyPTAK
-YnJlYWt9aWYoQy54Qi5XKGIscSk9PT02NCl7cz1DLnhCLk5qKGIsMCxxKQpyPXErMQpicmVha30rK3F9
-aWYocjxnJiZDLnhCLlcoYixyKT09PTkxKXtmb3IocD1yLG89LTE7cDxnOysrcCl7bj1DLnhCLlcoYixw
-KQppZihuPT09MzcmJm88MCl7bT1DLnhCLlFpKGIsIjI1IixwKzEpP3ArMjpwCm89cApwPW19ZWxzZSBp
-ZihuPT09OTMpYnJlYWt9aWYocD09PWcpdGhyb3cgSC5iKFAucnIoIkludmFsaWQgSVB2NiBob3N0IGVu
-dHJ5LiIsYixyKSkKbD1vPDA/cDpvClAuZWcoYixyKzEsbCk7KytwCmlmKHAhPT1nJiZDLnhCLlcoYixw
-KSE9PTU4KXRocm93IEguYihQLnJyKCJJbnZhbGlkIGVuZCBvZiBhdXRob3JpdHkiLGIscCkpfWVsc2Ug
-cD1yCndoaWxlKCEwKXtpZighKHA8Zykpe2s9aApicmVha31pZihDLnhCLlcoYixwKT09PTU4KXtqPUMu
-eEIuRyhiLHArMSkKaz1qLmxlbmd0aCE9PTA/UC5RQShqLGgpOmgKYnJlYWt9KytwfWk9Qy54Qi5Oaihi
-LHIscCl9ZWxzZXtrPWgKaT1rCnM9IiJ9cmV0dXJuIFAuS0woaSxoLEguVk0oYy5zcGxpdCgiLyIpLHQu
-cyksayxkLGEscyl9LAprRTpmdW5jdGlvbihhLGIpe3ZhciBzLHIscSxwLG8KZm9yKHM9YS5sZW5ndGgs
-cj0wO3I8czsrK3Ipe3E9YVtyXQpxLnRvU3RyaW5nCnA9Si5VNihxKQpvPXAuZ0EocSkKaWYoMD5vKUgu
-dihQLlRFKDAsMCxwLmdBKHEpLG51bGwsbnVsbCkpCmlmKEguU1EocSwiLyIsMCkpe3M9UC5MNCgiSWxs
-ZWdhbCBwYXRoIGNoYXJhY3RlciAiK0guRWoocSkpCnRocm93IEguYihzKX19fSwKSE46ZnVuY3Rpb24o
-YSxiLGMpe3ZhciBzLHIscQpmb3Iocz1ILnFDKGEsYyxudWxsLEgudDYoYSkuYykscz1uZXcgSC5hNyhz
-LHMuZ0Eocykscy4kdGkuQygiYTc8YUwuRT4iKSk7cy5GKCk7KXtyPXMuZApxPVAubnUoJ1siKi86PD4/
-XFxcXHxdJykKci50b1N0cmluZwppZihILlNRKHIscSwwKSl7cz1QLkw0KCJJbGxlZ2FsIGNoYXJhY3Rl
-ciBpbiBwYXRoOiAiK3IpCnRocm93IEguYihzKX19fSwKcmc6ZnVuY3Rpb24oYSxiKXt2YXIgcwppZigh
-KDY1PD1hJiZhPD05MCkpcz05Nzw9YSYmYTw9MTIyCmVsc2Ugcz0hMAppZihzKXJldHVybgpzPVAuTDQo
-IklsbGVnYWwgZHJpdmUgbGV0dGVyICIrUC5PbyhhKSkKdGhyb3cgSC5iKHMpfSwKd0I6ZnVuY3Rpb24o
-YSxiKXtpZihhIT1udWxsJiZhPT09UC53SyhiKSlyZXR1cm4gbnVsbApyZXR1cm4gYX0sCk9lOmZ1bmN0
-aW9uKGEsYixjLGQpe3ZhciBzLHIscSxwLG8sbgppZihhPT1udWxsKXJldHVybiBudWxsCmlmKGI9PT1j
-KXJldHVybiIiCmlmKEMueEIuTzIoYSxiKT09PTkxKXtzPWMtMQppZihDLnhCLk8yKGEscykhPT05Myl7
-UC5SMyhhLGIsIk1pc3NpbmcgZW5kIGBdYCB0byBtYXRjaCBgW2AgaW4gaG9zdCIpCkguQmkodS5nKX1y
-PWIrMQpxPVAudG8oYSxyLHMpCmlmKHE8cyl7cD1xKzEKbz1QLk9BKGEsQy54Qi5RaShhLCIyNSIscCk/
-cSszOnAscywiJTI1Iil9ZWxzZSBvPSIiClAuZWcoYSxyLHEpCnJldHVybiBDLnhCLk5qKGEsYixxKS50
-b0xvd2VyQ2FzZSgpK28rIl0ifWZvcihuPWI7bjxjOysrbilpZihDLnhCLk8yKGEsbik9PT01OCl7cT1D
-LnhCLlhVKGEsIiUiLGIpCnE9cT49YiYmcTxjP3E6YwppZihxPGMpe3A9cSsxCm89UC5PQShhLEMueEIu
-UWkoYSwiMjUiLHApP3ErMzpwLGMsIiUyNSIpfWVsc2Ugbz0iIgpQLmVnKGEsYixxKQpyZXR1cm4iWyIr
-Qy54Qi5OaihhLGIscSkrbysiXSJ9cmV0dXJuIFAuT0woYSxiLGMpfSwKdG86ZnVuY3Rpb24oYSxiLGMp
-e3ZhciBzPUMueEIuWFUoYSwiJSIsYikKcmV0dXJuIHM+PWImJnM8Yz9zOmN9LApPQTpmdW5jdGlvbihh
-LGIsYyxkKXt2YXIgcyxyLHEscCxvLG4sbSxsLGssaixpPWQhPT0iIj9uZXcgUC5SbihkKTpudWxsCmZv
-cihzPWIscj1zLHE9ITA7czxjOyl7cD1DLnhCLk8yKGEscykKaWYocD09PTM3KXtvPVAucnYoYSxzLCEw
-KQpuPW89PW51bGwKaWYobiYmcSl7cys9Mwpjb250aW51ZX1pZihpPT1udWxsKWk9bmV3IFAuUm4oIiIp
-Cm09aS5hKz1DLnhCLk5qKGEscixzKQppZihuKW89Qy54Qi5OaihhLHMscyszKQplbHNlIGlmKG89PT0i
-JSIpe1AuUjMoYSxzLCJab25lSUQgc2hvdWxkIG5vdCBjb250YWluICUgYW55bW9yZSIpCkguQmkodS5n
-KX1pLmE9bStvCnMrPTMKcj1zCnE9ITB9ZWxzZXtpZihwPDEyNyl7bj1wPj4+NAppZihuPj04KXJldHVy
-biBILk9IKEMuRjMsbikKbj0oQy5GM1tuXSYxPDwocCYxNSkpIT09MH1lbHNlIG49ITEKaWYobil7aWYo
-cSYmNjU8PXAmJjkwPj1wKXtpZihpPT1udWxsKWk9bmV3IFAuUm4oIiIpCmlmKHI8cyl7aS5hKz1DLnhC
-Lk5qKGEscixzKQpyPXN9cT0hMX0rK3N9ZWxzZXtpZigocCY2NDUxMik9PT01NTI5NiYmcysxPGMpe2w9
-Qy54Qi5PMihhLHMrMSkKaWYoKGwmNjQ1MTIpPT09NTYzMjApe3A9KHAmMTAyMyk8PDEwfGwmMTAyM3w2
-NTUzNgprPTJ9ZWxzZSBrPTF9ZWxzZSBrPTEKaj1DLnhCLk5qKGEscixzKQppZihpPT1udWxsKXtpPW5l
-dyBQLlJuKCIiKQpuPWl9ZWxzZSBuPWkKbi5hKz1qCm4uYSs9UC56WChwKQpzKz1rCnI9c319fWlmKGk9
-PW51bGwpcmV0dXJuIEMueEIuTmooYSxiLGMpCmlmKHI8YylpLmErPUMueEIuTmooYSxyLGMpCm49aS5h
-CnJldHVybiBuLmNoYXJDb2RlQXQoMCk9PTA/bjpufSwKT0w6ZnVuY3Rpb24oYSxiLGMpe3ZhciBzLHIs
-cSxwLG8sbixtLGwsayxqLGkKZm9yKHM9YixyPXMscT1udWxsLHA9ITA7czxjOyl7bz1DLnhCLk8yKGEs
-cykKaWYobz09PTM3KXtuPVAucnYoYSxzLCEwKQptPW49PW51bGwKaWYobSYmcCl7cys9Mwpjb250aW51
-ZX1pZihxPT1udWxsKXE9bmV3IFAuUm4oIiIpCmw9Qy54Qi5OaihhLHIscykKaz1xLmErPSFwP2wudG9M
-b3dlckNhc2UoKTpsCmlmKG0pe249Qy54Qi5OaihhLHMscyszKQpqPTN9ZWxzZSBpZihuPT09IiUiKXtu
-PSIlMjUiCmo9MX1lbHNlIGo9MwpxLmE9aytuCnMrPWoKcj1zCnA9ITB9ZWxzZXtpZihvPDEyNyl7bT1v
-Pj4+NAppZihtPj04KXJldHVybiBILk9IKEMuZWEsbSkKbT0oQy5lYVttXSYxPDwobyYxNSkpIT09MH1l
-bHNlIG09ITEKaWYobSl7aWYocCYmNjU8PW8mJjkwPj1vKXtpZihxPT1udWxsKXE9bmV3IFAuUm4oIiIp
-CmlmKHI8cyl7cS5hKz1DLnhCLk5qKGEscixzKQpyPXN9cD0hMX0rK3N9ZWxzZXtpZihvPD05Myl7bT1v
-Pj4+NAppZihtPj04KXJldHVybiBILk9IKEMuYWssbSkKbT0oQy5ha1ttXSYxPDwobyYxNSkpIT09MH1l
-bHNlIG09ITEKaWYobSl7UC5SMyhhLHMsIkludmFsaWQgY2hhcmFjdGVyIikKSC5CaSh1LmcpfWVsc2V7
-aWYoKG8mNjQ1MTIpPT09NTUyOTYmJnMrMTxjKXtpPUMueEIuTzIoYSxzKzEpCmlmKChpJjY0NTEyKT09
-PTU2MzIwKXtvPShvJjEwMjMpPDwxMHxpJjEwMjN8NjU1MzYKaj0yfWVsc2Ugaj0xfWVsc2Ugaj0xCmw9
-Qy54Qi5OaihhLHIscykKaWYoIXApbD1sLnRvTG93ZXJDYXNlKCkKaWYocT09bnVsbCl7cT1uZXcgUC5S
-bigiIikKbT1xfWVsc2UgbT1xCm0uYSs9bAptLmErPVAuelgobykKcys9agpyPXN9fX19aWYocT09bnVs
-bClyZXR1cm4gQy54Qi5OaihhLGIsYykKaWYocjxjKXtsPUMueEIuTmooYSxyLGMpCnEuYSs9IXA/bC50
-b0xvd2VyQ2FzZSgpOmx9bT1xLmEKcmV0dXJuIG0uY2hhckNvZGVBdCgwKT09MD9tOm19LApQaTpmdW5j
-dGlvbihhLGIsYyl7dmFyIHMscixxLHAsbz11LmcKaWYoYj09PWMpcmV0dXJuIiIKaWYoIVAuRXQoSi5y
-WShhKS5XKGEsYikpKXtQLlIzKGEsYiwiU2NoZW1lIG5vdCBzdGFydGluZyB3aXRoIGFscGhhYmV0aWMg
-Y2hhcmFjdGVyIikKSC5CaShvKX1mb3Iocz1iLHI9ITE7czxjOysrcyl7cT1DLnhCLlcoYSxzKQppZihx
-PDEyOCl7cD1xPj4+NAppZihwPj04KXJldHVybiBILk9IKEMubUsscCkKcD0oQy5tS1twXSYxPDwocSYx
-NSkpIT09MH1lbHNlIHA9ITEKaWYoIXApe1AuUjMoYSxzLCJJbGxlZ2FsIHNjaGVtZSBjaGFyYWN0ZXIi
-KQpILkJpKG8pfWlmKDY1PD1xJiZxPD05MClyPSEwfWE9Qy54Qi5OaihhLGIsYykKcmV0dXJuIFAuWWEo
-cj9hLnRvTG93ZXJDYXNlKCk6YSl9LApZYTpmdW5jdGlvbihhKXtpZihhPT09Imh0dHAiKXJldHVybiJo
-dHRwIgppZihhPT09ImZpbGUiKXJldHVybiJmaWxlIgppZihhPT09Imh0dHBzIilyZXR1cm4iaHR0cHMi
-CmlmKGE9PT0icGFja2FnZSIpcmV0dXJuInBhY2thZ2UiCnJldHVybiBhfSwKelI6ZnVuY3Rpb24oYSxi
-LGMpe2lmKGE9PW51bGwpcmV0dXJuIiIKcmV0dXJuIFAuUEkoYSxiLGMsQy50bywhMSl9LAprYTpmdW5j
-dGlvbihhLGIsYyxkLGUsZil7dmFyIHMscixxPWU9PT0iZmlsZSIscD1xfHxmCmlmKGE9PW51bGwpe2lm
-KGQ9PW51bGwpcmV0dXJuIHE/Ii8iOiIiCnM9SC50NihkKQpyPW5ldyBILmxKKGQscy5DKCJxVSgxKSIp
-LmEobmV3IFAuUlooKSkscy5DKCJsSjwxLHFVPiIpKS5IKDAsIi8iKX1lbHNlIGlmKGQhPW51bGwpdGhy
-b3cgSC5iKFAueFkoIkJvdGggcGF0aCBhbmQgcGF0aFNlZ21lbnRzIHNwZWNpZmllZCIpKQplbHNlIHI9
-UC5QSShhLGIsYyxDLldkLCEwKQppZihyLmxlbmd0aD09PTApe2lmKHEpcmV0dXJuIi8ifWVsc2UgaWYo
-cCYmIUMueEIubihyLCIvIikpcj0iLyIrcgpyZXR1cm4gUC5KcihyLGUsZil9LApKcjpmdW5jdGlvbihh
-LGIsYyl7dmFyIHM9Yi5sZW5ndGg9PT0wCmlmKHMmJiFjJiYhQy54Qi5uKGEsIi8iKSlyZXR1cm4gUC53
-RihhLCFzfHxjKQpyZXR1cm4gUC54ZShhKX0sCmxlOmZ1bmN0aW9uKGEsYixjLGQpe3ZhciBzLHI9e30K
-aWYoYSE9bnVsbCl7aWYoZCE9bnVsbCl0aHJvdyBILmIoUC54WSgiQm90aCBxdWVyeSBhbmQgcXVlcnlQ
-YXJhbWV0ZXJzIHNwZWNpZmllZCIpKQpyZXR1cm4gUC5QSShhLGIsYyxDLlZDLCEwKX1pZihkPT1udWxs
-KXJldHVybiBudWxsCnM9bmV3IFAuUm4oIiIpCnIuYT0iIgpkLksoMCxuZXcgUC55NShuZXcgUC5NRShy
-LHMpKSkKcj1zLmEKcmV0dXJuIHIuY2hhckNvZGVBdCgwKT09MD9yOnJ9LAp0RzpmdW5jdGlvbihhLGIs
-Yyl7aWYoYT09bnVsbClyZXR1cm4gbnVsbApyZXR1cm4gUC5QSShhLGIsYyxDLlZDLCEwKX0sCnJ2OmZ1
-bmN0aW9uKGEsYixjKXt2YXIgcyxyLHEscCxvLG49YisyCmlmKG4+PWEubGVuZ3RoKXJldHVybiIlIgpz
-PUMueEIuTzIoYSxiKzEpCnI9Qy54Qi5PMihhLG4pCnE9SC5vbyhzKQpwPUgub28ocikKaWYocTwwfHxw
-PDApcmV0dXJuIiUiCm89cSoxNitwCmlmKG88MTI3KXtuPUMuam4ud0cobyw0KQppZihuPj04KXJldHVy
-biBILk9IKEMuRjMsbikKbj0oQy5GM1tuXSYxPDwobyYxNSkpIT09MH1lbHNlIG49ITEKaWYobilyZXR1
-cm4gSC5MdyhjJiY2NTw9byYmOTA+PW8/KG98MzIpPj4+MDpvKQppZihzPj05N3x8cj49OTcpcmV0dXJu
-IEMueEIuTmooYSxiLGIrMykudG9VcHBlckNhc2UoKQpyZXR1cm4gbnVsbH0sCnpYOmZ1bmN0aW9uKGEp
-e3ZhciBzLHIscSxwLG8sbixtLGwsaz0iMDEyMzQ1Njc4OUFCQ0RFRiIKaWYoYTwxMjgpe3M9bmV3IFVp
-bnQ4QXJyYXkoMykKc1swXT0zNwpzWzFdPUMueEIuVyhrLGE+Pj40KQpzWzJdPUMueEIuVyhrLGEmMTUp
-fWVsc2V7aWYoYT4yMDQ3KWlmKGE+NjU1MzUpe3I9MjQwCnE9NH1lbHNle3I9MjI0CnE9M31lbHNle3I9
-MTkyCnE9Mn1wPTMqcQpzPW5ldyBVaW50OEFycmF5KHApCmZvcihvPTA7LS1xLHE+PTA7cj0xMjgpe249
-Qy5qbi5iZihhLDYqcSkmNjN8cgppZihvPj1wKXJldHVybiBILk9IKHMsbykKc1tvXT0zNwptPW8rMQps
-PUMueEIuVyhrLG4+Pj40KQppZihtPj1wKXJldHVybiBILk9IKHMsbSkKc1ttXT1sCmw9bysyCm09Qy54
-Qi5XKGssbiYxNSkKaWYobD49cClyZXR1cm4gSC5PSChzLGwpCnNbbF09bQpvKz0zfX1yZXR1cm4gUC5I
-TShzLDAsbnVsbCl9LApQSTpmdW5jdGlvbihhLGIsYyxkLGUpe3ZhciBzPVAuVWwoYSxiLGMsZCxlKQpy
-ZXR1cm4gcz09bnVsbD9DLnhCLk5qKGEsYixjKTpzfSwKVWw6ZnVuY3Rpb24oYSxiLGMsZCxlKXt2YXIg
-cyxyLHEscCxvLG4sbSxsLGssaj1udWxsCmZvcihzPSFlLHI9YixxPXIscD1qO3I8Yzspe289Qy54Qi5P
-MihhLHIpCmlmKG88MTI3KXtuPW8+Pj40CmlmKG4+PTgpcmV0dXJuIEguT0goZCxuKQpuPShkW25dJjE8
-PChvJjE1KSkhPT0wfWVsc2Ugbj0hMQppZihuKSsrcgplbHNle2lmKG89PT0zNyl7bT1QLnJ2KGEsciwh
-MSkKaWYobT09bnVsbCl7cis9Mwpjb250aW51ZX1pZigiJSI9PT1tKXttPSIlMjUiCmw9MX1lbHNlIGw9
-M31lbHNle2lmKHMpaWYobzw9OTMpe249bz4+PjQKaWYobj49OClyZXR1cm4gSC5PSChDLmFrLG4pCm49
-KEMuYWtbbl0mMTw8KG8mMTUpKSE9PTB9ZWxzZSBuPSExCmVsc2Ugbj0hMQppZihuKXtQLlIzKGEsciwi
-SW52YWxpZCBjaGFyYWN0ZXIiKQpILkJpKHUuZykKbD1qCm09bH1lbHNle2lmKChvJjY0NTEyKT09PTU1
-Mjk2KXtuPXIrMQppZihuPGMpe2s9Qy54Qi5PMihhLG4pCmlmKChrJjY0NTEyKT09PTU2MzIwKXtvPShv
-JjEwMjMpPDwxMHxrJjEwMjN8NjU1MzYKbD0yfWVsc2UgbD0xfWVsc2UgbD0xfWVsc2UgbD0xCm09UC56
-WChvKX19aWYocD09bnVsbCl7cD1uZXcgUC5SbigiIikKbj1wfWVsc2Ugbj1wCm4uYSs9Qy54Qi5Oaihh
-LHEscikKbi5hKz1ILkVqKG0pCmlmKHR5cGVvZiBsIT09Im51bWJlciIpcmV0dXJuIEgucFkobCkKcis9
-bApxPXJ9fWlmKHA9PW51bGwpcmV0dXJuIGoKaWYocTxjKXAuYSs9Qy54Qi5OaihhLHEsYykKcz1wLmEK
-cmV0dXJuIHMuY2hhckNvZGVBdCgwKT09MD9zOnN9LAp5QjpmdW5jdGlvbihhKXtpZihDLnhCLm4oYSwi
-LiIpKXJldHVybiEwCnJldHVybiBDLnhCLk9ZKGEsIi8uIikhPT0tMX0sCnhlOmZ1bmN0aW9uKGEpe3Zh
-ciBzLHIscSxwLG8sbixtCmlmKCFQLnlCKGEpKXJldHVybiBhCnM9SC5WTShbXSx0LnMpCmZvcihyPWEu
-c3BsaXQoIi8iKSxxPXIubGVuZ3RoLHA9ITEsbz0wO288cTsrK28pe249cltvXQppZihKLlJNKG4sIi4u
-Iikpe209cy5sZW5ndGgKaWYobSE9PTApe2lmKDA+PW0pcmV0dXJuIEguT0gocywtMSkKcy5wb3AoKQpp
-ZihzLmxlbmd0aD09PTApQy5ObS5pKHMsIiIpfXA9ITB9ZWxzZSBpZigiLiI9PT1uKXA9ITAKZWxzZXtD
-Lk5tLmkocyxuKQpwPSExfX1pZihwKUMuTm0uaShzLCIiKQpyZXR1cm4gQy5ObS5IKHMsIi8iKX0sCndG
-OmZ1bmN0aW9uKGEsYil7dmFyIHMscixxLHAsbyxuCmlmKCFQLnlCKGEpKXJldHVybiFiP1AuQzEoYSk6
-YQpzPUguVk0oW10sdC5zKQpmb3Iocj1hLnNwbGl0KCIvIikscT1yLmxlbmd0aCxwPSExLG89MDtvPHE7
-KytvKXtuPXJbb10KaWYoIi4uIj09PW4paWYocy5sZW5ndGghPT0wJiZDLk5tLmdyWihzKSE9PSIuLiIp
-e2lmKDA+PXMubGVuZ3RoKXJldHVybiBILk9IKHMsLTEpCnMucG9wKCkKcD0hMH1lbHNle0MuTm0uaShz
-LCIuLiIpCnA9ITF9ZWxzZSBpZigiLiI9PT1uKXA9ITAKZWxzZXtDLk5tLmkocyxuKQpwPSExfX1yPXMu
-bGVuZ3RoCmlmKHIhPT0wKWlmKHI9PT0xKXtpZigwPj1yKXJldHVybiBILk9IKHMsMCkKcj1zWzBdLmxl
-bmd0aD09PTB9ZWxzZSByPSExCmVsc2Ugcj0hMAppZihyKXJldHVybiIuLyIKaWYocHx8Qy5ObS5ncloo
-cyk9PT0iLi4iKUMuTm0uaShzLCIiKQppZighYil7aWYoMD49cy5sZW5ndGgpcmV0dXJuIEguT0gocyww
-KQpDLk5tLlkocywwLFAuQzEoc1swXSkpfXJldHVybiBDLk5tLkgocywiLyIpfSwKQzE6ZnVuY3Rpb24o
-YSl7dmFyIHMscixxLHA9YS5sZW5ndGgKaWYocD49MiYmUC5FdChKLlF6KGEsMCkpKWZvcihzPTE7czxw
-Oysrcyl7cj1DLnhCLlcoYSxzKQppZihyPT09NTgpcmV0dXJuIEMueEIuTmooYSwwLHMpKyIlM0EiK0Mu
-eEIuRyhhLHMrMSkKaWYocjw9MTI3KXtxPXI+Pj40CmlmKHE+PTgpcmV0dXJuIEguT0goQy5tSyxxKQpx
-PShDLm1LW3FdJjE8PChyJjE1KSk9PT0wfWVsc2UgcT0hMAppZihxKWJyZWFrfXJldHVybiBhfSwKbW46
-ZnVuY3Rpb24oYSl7dmFyIHMscixxLHA9YS5nRmooKSxvPXAubGVuZ3RoCmlmKG8+MCYmSi5IbShwWzBd
-KT09PTImJkouYTYocFswXSwxKT09PTU4KXtpZigwPj1vKXJldHVybiBILk9IKHAsMCkKUC5yZyhKLmE2
-KHBbMF0sMCksITEpClAuSE4ocCwhMSwxKQpzPSEwfWVsc2V7UC5ITihwLCExLDApCnM9ITF9cj1hLmd0
-VCgpJiYhcz8iXFwiOiIiCmlmKGEuZ2NqKCkpe3E9YS5nSmYoYSkKaWYocS5sZW5ndGghPT0wKXI9cisi
-XFwiK3ErIlxcIn1yPVAudmcocixwLCJcXCIpCm89cyYmbz09PTE/cisiXFwiOnIKcmV0dXJuIG8uY2hh
-ckNvZGVBdCgwKT09MD9vOm99LApJaDpmdW5jdGlvbihhLGIpe3ZhciBzLHIscQpmb3Iocz0wLHI9MDty
-PDI7KytyKXtxPUMueEIuVyhhLGIrcikKaWYoNDg8PXEmJnE8PTU3KXM9cyoxNitxLTQ4CmVsc2V7cXw9
-MzIKaWYoOTc8PXEmJnE8PTEwMilzPXMqMTYrcS04NwplbHNlIHRocm93IEguYihQLnhZKCJJbnZhbGlk
-IFVSTCBlbmNvZGluZyIpKX19cmV0dXJuIHN9LAprdTpmdW5jdGlvbihhLGIsYyxkLGUpe3ZhciBzLHIs
-cSxwLG89Si5yWShhKSxuPWIKd2hpbGUoITApe2lmKCEobjxjKSl7cz0hMApicmVha31yPW8uVyhhLG4p
-CmlmKHI8PTEyNylpZihyIT09MzcpcT1lJiZyPT09NDMKZWxzZSBxPSEwCmVsc2UgcT0hMAppZihxKXtz
-PSExCmJyZWFrfSsrbn1pZihzKXtpZihDLnhNIT09ZClxPSExCmVsc2UgcT0hMAppZihxKXJldHVybiBv
-Lk5qKGEsYixjKQplbHNlIHA9bmV3IEgucWooby5OaihhLGIsYykpfWVsc2V7cD1ILlZNKFtdLHQuYSkK
-Zm9yKG49YjtuPGM7KytuKXtyPW8uVyhhLG4pCmlmKHI+MTI3KXRocm93IEguYihQLnhZKCJJbGxlZ2Fs
-IHBlcmNlbnQgZW5jb2RpbmcgaW4gVVJJIikpCmlmKHI9PT0zNyl7aWYobiszPmEubGVuZ3RoKXRocm93
-IEguYihQLnhZKCJUcnVuY2F0ZWQgVVJJIikpCkMuTm0uaShwLFAuSWgoYSxuKzEpKQpuKz0yfWVsc2Ug
-aWYoZSYmcj09PTQzKUMuTm0uaShwLDMyKQplbHNlIEMuTm0uaShwLHIpfX10LkwuYShwKQpyZXR1cm4g
-Qy5vRS5XSihwKX0sCkV0OmZ1bmN0aW9uKGEpe3ZhciBzPWF8MzIKcmV0dXJuIDk3PD1zJiZzPD0xMjJ9
-LApLRDpmdW5jdGlvbihhLGIsYyl7dmFyIHMscixxLHAsbyxuLG0sbCxrPSJJbnZhbGlkIE1JTUUgdHlw
-ZSIsaj1ILlZNKFtiLTFdLHQuYSkKZm9yKHM9YS5sZW5ndGgscj1iLHE9LTEscD1udWxsO3I8czsrK3Ip
-e3A9Qy54Qi5XKGEscikKaWYocD09PTQ0fHxwPT09NTkpYnJlYWsKaWYocD09PTQ3KXtpZihxPDApe3E9
-cgpjb250aW51ZX10aHJvdyBILmIoUC5ycihrLGEscikpfX1pZihxPDAmJnI+Yil0aHJvdyBILmIoUC5y
-cihrLGEscikpCmZvcig7cCE9PTQ0Oyl7Qy5ObS5pKGoscik7KytyCmZvcihvPS0xO3I8czsrK3Ipe3A9
-Qy54Qi5XKGEscikKaWYocD09PTYxKXtpZihvPDApbz1yfWVsc2UgaWYocD09PTU5fHxwPT09NDQpYnJl
-YWt9aWYobz49MClDLk5tLmkoaixvKQplbHNle249Qy5ObS5nclooaikKaWYocCE9PTQ0fHxyIT09bis3
-fHwhQy54Qi5RaShhLCJiYXNlNjQiLG4rMSkpdGhyb3cgSC5iKFAucnIoIkV4cGVjdGluZyAnPSciLGEs
-cikpCmJyZWFrfX1DLk5tLmkoaixyKQptPXIrMQppZigoai5sZW5ndGgmMSk9PT0xKWE9Qy5oOS55cihh
-LG0scykKZWxzZXtsPVAuVWwoYSxtLHMsQy5WQywhMCkKaWYobCE9bnVsbClhPUMueEIuaTcoYSxtLHMs
-bCl9cmV0dXJuIG5ldyBQLlBFKGEsaixjKX0sCktOOmZ1bmN0aW9uKCl7dmFyIHMscixxLHAsbyxuLG09
-IjAxMjM0NTY3ODlBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWmFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3
-eHl6LS5ffiEkJicoKSorLDs9IixsPSIuIixrPSI6IixqPSIvIixpPSI/IixoPSIjIixnPUguVk0obmV3
-IEFycmF5KDIyKSx0LmdOKQpmb3Iocz0wO3M8MjI7KytzKWdbc109bmV3IFVpbnQ4QXJyYXkoOTYpCnI9
-bmV3IFAueUkoZykKcT1uZXcgUC5jNigpCnA9bmV3IFAucWQoKQpvPXQuZ2MKbj1vLmEoci4kMigwLDIy
-NSkpCnEuJDMobixtLDEpCnEuJDMobixsLDE0KQpxLiQzKG4saywzNCkKcS4kMyhuLGosMykKcS4kMyhu
-LGksMTcyKQpxLiQzKG4saCwyMDUpCm49by5hKHIuJDIoMTQsMjI1KSkKcS4kMyhuLG0sMSkKcS4kMyhu
-LGwsMTUpCnEuJDMobixrLDM0KQpxLiQzKG4saiwyMzQpCnEuJDMobixpLDE3MikKcS4kMyhuLGgsMjA1
-KQpuPW8uYShyLiQyKDE1LDIyNSkpCnEuJDMobixtLDEpCnEuJDMobiwiJSIsMjI1KQpxLiQzKG4saywz
-NCkKcS4kMyhuLGosOSkKcS4kMyhuLGksMTcyKQpxLiQzKG4saCwyMDUpCm49by5hKHIuJDIoMSwyMjUp
-KQpxLiQzKG4sbSwxKQpxLiQzKG4saywzNCkKcS4kMyhuLGosMTApCnEuJDMobixpLDE3MikKcS4kMyhu
-LGgsMjA1KQpuPW8uYShyLiQyKDIsMjM1KSkKcS4kMyhuLG0sMTM5KQpxLiQzKG4saiwxMzEpCnEuJDMo
-bixsLDE0NikKcS4kMyhuLGksMTcyKQpxLiQzKG4saCwyMDUpCm49by5hKHIuJDIoMywyMzUpKQpxLiQz
-KG4sbSwxMSkKcS4kMyhuLGosNjgpCnEuJDMobixsLDE4KQpxLiQzKG4saSwxNzIpCnEuJDMobixoLDIw
-NSkKbj1vLmEoci4kMig0LDIyOSkpCnEuJDMobixtLDUpCnAuJDMobiwiQVoiLDIyOSkKcS4kMyhuLGss
-MTAyKQpxLiQzKG4sIkAiLDY4KQpxLiQzKG4sIlsiLDIzMikKcS4kMyhuLGosMTM4KQpxLiQzKG4saSwx
-NzIpCnEuJDMobixoLDIwNSkKbj1vLmEoci4kMig1LDIyOSkpCnEuJDMobixtLDUpCnAuJDMobiwiQVoi
-LDIyOSkKcS4kMyhuLGssMTAyKQpxLiQzKG4sIkAiLDY4KQpxLiQzKG4saiwxMzgpCnEuJDMobixpLDE3
-MikKcS4kMyhuLGgsMjA1KQpuPW8uYShyLiQyKDYsMjMxKSkKcC4kMyhuLCIxOSIsNykKcS4kMyhuLCJA
-Iiw2OCkKcS4kMyhuLGosMTM4KQpxLiQzKG4saSwxNzIpCnEuJDMobixoLDIwNSkKbj1vLmEoci4kMig3
-LDIzMSkpCnAuJDMobiwiMDkiLDcpCnEuJDMobiwiQCIsNjgpCnEuJDMobixqLDEzOCkKcS4kMyhuLGks
-MTcyKQpxLiQzKG4saCwyMDUpCnEuJDMoby5hKHIuJDIoOCw4KSksIl0iLDUpCm49by5hKHIuJDIoOSwy
-MzUpKQpxLiQzKG4sbSwxMSkKcS4kMyhuLGwsMTYpCnEuJDMobixqLDIzNCkKcS4kMyhuLGksMTcyKQpx
-LiQzKG4saCwyMDUpCm49by5hKHIuJDIoMTYsMjM1KSkKcS4kMyhuLG0sMTEpCnEuJDMobixsLDE3KQpx
-LiQzKG4saiwyMzQpCnEuJDMobixpLDE3MikKcS4kMyhuLGgsMjA1KQpuPW8uYShyLiQyKDE3LDIzNSkp
-CnEuJDMobixtLDExKQpxLiQzKG4saiw5KQpxLiQzKG4saSwxNzIpCnEuJDMobixoLDIwNSkKbj1vLmEo
-ci4kMigxMCwyMzUpKQpxLiQzKG4sbSwxMSkKcS4kMyhuLGwsMTgpCnEuJDMobixqLDIzNCkKcS4kMyhu
-LGksMTcyKQpxLiQzKG4saCwyMDUpCm49by5hKHIuJDIoMTgsMjM1KSkKcS4kMyhuLG0sMTEpCnEuJDMo
-bixsLDE5KQpxLiQzKG4saiwyMzQpCnEuJDMobixpLDE3MikKcS4kMyhuLGgsMjA1KQpuPW8uYShyLiQy
-KDE5LDIzNSkpCnEuJDMobixtLDExKQpxLiQzKG4saiwyMzQpCnEuJDMobixpLDE3MikKcS4kMyhuLGgs
-MjA1KQpuPW8uYShyLiQyKDExLDIzNSkpCnEuJDMobixtLDExKQpxLiQzKG4saiwxMCkKcS4kMyhuLGks
-MTcyKQpxLiQzKG4saCwyMDUpCm49by5hKHIuJDIoMTIsMjM2KSkKcS4kMyhuLG0sMTIpCnEuJDMobixp
-LDEyKQpxLiQzKG4saCwyMDUpCm49by5hKHIuJDIoMTMsMjM3KSkKcS4kMyhuLG0sMTMpCnEuJDMobixp
-LDEzKQpwLiQzKG8uYShyLiQyKDIwLDI0NSkpLCJheiIsMjEpCnI9by5hKHIuJDIoMjEsMjQ1KSkKcC4k
-MyhyLCJheiIsMjEpCnAuJDMociwiMDkiLDIxKQpxLiQzKHIsIistLiIsMjEpCnJldHVybiBnfSwKVUI6
-ZnVuY3Rpb24oYSxiLGMsZCxlKXt2YXIgcyxyLHEscCxvLG49JC52WigpCmZvcihzPUouclkoYSkscj1i
-O3I8YzsrK3Ipe2lmKGQ8MHx8ZD49bi5sZW5ndGgpcmV0dXJuIEguT0gobixkKQpxPW5bZF0KcD1zLlco
-YSxyKV45NgpvPXFbcD45NT8zMTpwXQpkPW8mMzEKQy5ObS5ZKGUsbz4+PjUscil9cmV0dXJuIGR9LApX
-RjpmdW5jdGlvbiBXRihhLGIpe3RoaXMuYT1hCnRoaXMuYj1ifSwKaVA6ZnVuY3Rpb24gaVAoYSxiKXt0
-aGlzLmE9YQp0aGlzLmI9Yn0sClhTOmZ1bmN0aW9uIFhTKCl7fSwKQzY6ZnVuY3Rpb24gQzYoYSl7dGhp
-cy5hPWF9LApFejpmdW5jdGlvbiBFeigpe30sCkY6ZnVuY3Rpb24gRigpe30sCnU6ZnVuY3Rpb24gdShh
-LGIsYyxkKXt2YXIgXz10aGlzCl8uYT1hCl8uYj1iCl8uYz1jCl8uZD1kfSwKYko6ZnVuY3Rpb24gYkoo
-YSxiLGMsZCxlLGYpe3ZhciBfPXRoaXMKXy5lPWEKXy5mPWIKXy5hPWMKXy5iPWQKXy5jPWUKXy5kPWZ9
-LAplWTpmdW5jdGlvbiBlWShhLGIsYyxkLGUpe3ZhciBfPXRoaXMKXy5mPWEKXy5hPWIKXy5iPWMKXy5j
-PWQKXy5kPWV9LAptcDpmdW5jdGlvbiBtcChhLGIsYyxkKXt2YXIgXz10aGlzCl8uYT1hCl8uYj1iCl8u
-Yz1jCl8uZD1kfSwKdWI6ZnVuY3Rpb24gdWIoYSl7dGhpcy5hPWF9LApkczpmdW5jdGlvbiBkcyhhKXt0
-aGlzLmE9YX0sCmxqOmZ1bmN0aW9uIGxqKGEpe3RoaXMuYT1hfSwKVVY6ZnVuY3Rpb24gVVYoYSl7dGhp
-cy5hPWF9LAprNTpmdW5jdGlvbiBrNSgpe30sCktZOmZ1bmN0aW9uIEtZKCl7fSwKYzpmdW5jdGlvbiBj
-KGEpe3RoaXMuYT1hfSwKQ0Q6ZnVuY3Rpb24gQ0QoYSl7dGhpcy5hPWF9LAphRTpmdW5jdGlvbiBhRShh
-LGIsYyl7dGhpcy5hPWEKdGhpcy5iPWIKdGhpcy5jPWN9LApjWDpmdW5jdGlvbiBjWCgpe30sCkFuOmZ1
-bmN0aW9uIEFuKCl7fSwKTjM6ZnVuY3Rpb24gTjMoYSxiLGMpe3RoaXMuYT1hCnRoaXMuYj1iCnRoaXMu
-JHRpPWN9LApjODpmdW5jdGlvbiBjOCgpe30sCk1oOmZ1bmN0aW9uIE1oKCl7fSwKWmQ6ZnVuY3Rpb24g
-WmQoKXt9LApSbjpmdW5jdGlvbiBSbihhKXt0aGlzLmE9YX0sCm4xOmZ1bmN0aW9uIG4xKGEpe3RoaXMu
-YT1hfSwKY1M6ZnVuY3Rpb24gY1MoYSl7dGhpcy5hPWF9LApWQzpmdW5jdGlvbiBWQyhhKXt0aGlzLmE9
-YX0sCkpUOmZ1bmN0aW9uIEpUKGEsYil7dGhpcy5hPWEKdGhpcy5iPWJ9LApEbjpmdW5jdGlvbiBEbihh
-LGIsYyxkLGUsZixnKXt2YXIgXz10aGlzCl8uYT1hCl8uYj1iCl8uYz1jCl8uZD1kCl8uZT1lCl8uZj1m
-Cl8ucj1nCl8ueD1udWxsCl8ueT0hMQpfLno9bnVsbApfLlE9ITEKXy5jaD1udWxsCl8uY3g9ITEKXy5j
-eT1udWxsCl8uZGI9ITF9LApSWjpmdW5jdGlvbiBSWigpe30sCk1FOmZ1bmN0aW9uIE1FKGEsYil7dGhp
-cy5hPWEKdGhpcy5iPWJ9LAp5NTpmdW5jdGlvbiB5NShhKXt0aGlzLmE9YX0sClBFOmZ1bmN0aW9uIFBF
-KGEsYixjKXt0aGlzLmE9YQp0aGlzLmI9Ygp0aGlzLmM9Y30sCnlJOmZ1bmN0aW9uIHlJKGEpe3RoaXMu
-YT1hfSwKYzY6ZnVuY3Rpb24gYzYoKXt9LApxZDpmdW5jdGlvbiBxZCgpe30sClVmOmZ1bmN0aW9uIFVm
-KGEsYixjLGQsZSxmLGcsaCl7dmFyIF89dGhpcwpfLmE9YQpfLmI9YgpfLmM9YwpfLmQ9ZApfLmU9ZQpf
-LmY9ZgpfLnI9ZwpfLng9aApfLnk9bnVsbH0sCnFlOmZ1bmN0aW9uIHFlKGEsYixjLGQsZSxmLGcpe3Zh
-ciBfPXRoaXMKXy5hPWEKXy5iPWIKXy5jPWMKXy5kPWQKXy5lPWUKXy5mPWYKXy5yPWcKXy54PW51bGwK
-Xy55PSExCl8uej1udWxsCl8uUT0hMQpfLmNoPW51bGwKXy5jeD0hMQpfLmN5PW51bGwKXy5kYj0hMX0s
-CmlKOmZ1bmN0aW9uIGlKKCl7fSwKamc6ZnVuY3Rpb24gamcoYSxiKXt0aGlzLmE9YQp0aGlzLmI9Yn0s
-ClRhOmZ1bmN0aW9uIFRhKGEsYil7dGhpcy5hPWEKdGhpcy5iPWJ9LApCZjpmdW5jdGlvbiBCZihhLGIp
-e3RoaXMuYT1hCnRoaXMuYj1ifSwKQXM6ZnVuY3Rpb24gQXMoKXt9LApHRTpmdW5jdGlvbiBHRShhKXt0
-aGlzLmE9YX0sCk43OmZ1bmN0aW9uIE43KGEsYil7dGhpcy5hPWEKdGhpcy5iPWJ9LAp1UTpmdW5jdGlv
-biB1USgpe30sCmhGOmZ1bmN0aW9uIGhGKCl7fSwKUjQ6ZnVuY3Rpb24oYSxiLGMsZCl7dmFyIHMscixx
-CkgueTgoYikKdC5qLmEoZCkKaWYoSC5vVChiKSl7cz1bY10KQy5ObS5GVihzLGQpCmQ9c31yPXQuegpx
-PVAuQ0goSi5NMShkLFAudzAoKSxyKSwhMCxyKQp0LlkuYShhKQpyZXR1cm4gUC53WShILkVrKGEscSxu
-dWxsKSl9LApEbTpmdW5jdGlvbihhLGIsYyl7dmFyIHMKdHJ5e2lmKE9iamVjdC5pc0V4dGVuc2libGUo
-YSkmJiFPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwoYSxiKSl7T2JqZWN0LmRlZmlu
-ZVByb3BlcnR5KGEsYix7dmFsdWU6Y30pCnJldHVybiEwfX1jYXRjaChzKXtILlJ1KHMpfXJldHVybiEx
-fSwKT206ZnVuY3Rpb24oYSxiKXtpZihPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwo
-YSxiKSlyZXR1cm4gYVtiXQpyZXR1cm4gbnVsbH0sCndZOmZ1bmN0aW9uKGEpe2lmKGE9PW51bGx8fHR5
-cGVvZiBhPT0ic3RyaW5nInx8dHlwZW9mIGE9PSJudW1iZXIifHxILmwoYSkpcmV0dXJuIGEKaWYoYSBp
-bnN0YW5jZW9mIFAuRTQpcmV0dXJuIGEuYQppZihILlI5KGEpKXJldHVybiBhCmlmKHQuYWsuYihhKSly
-ZXR1cm4gYQppZihhIGluc3RhbmNlb2YgUC5pUClyZXR1cm4gSC5vMihhKQppZih0LlkuYihhKSlyZXR1
-cm4gUC5oRShhLCIkZGFydF9qc0Z1bmN0aW9uIixuZXcgUC5QQygpKQpyZXR1cm4gUC5oRShhLCJfJGRh
-cnRfanNPYmplY3QiLG5ldyBQLm10KCQua0koKSkpfSwKaEU6ZnVuY3Rpb24oYSxiLGMpe3ZhciBzPVAu
-T20oYSxiKQppZihzPT1udWxsKXtzPWMuJDEoYSkKUC5EbShhLGIscyl9cmV0dXJuIHN9LApkVTpmdW5j
-dGlvbihhKXt2YXIgcyxyCmlmKGE9PW51bGx8fHR5cGVvZiBhPT0ic3RyaW5nInx8dHlwZW9mIGE9PSJu
-dW1iZXIifHx0eXBlb2YgYT09ImJvb2xlYW4iKXJldHVybiBhCmVsc2UgaWYoYSBpbnN0YW5jZW9mIE9i
-amVjdCYmSC5SOShhKSlyZXR1cm4gYQplbHNlIGlmKGEgaW5zdGFuY2VvZiBPYmplY3QmJnQuYWsuYihh
-KSlyZXR1cm4gYQplbHNlIGlmKGEgaW5zdGFuY2VvZiBEYXRlKXtzPUgudVAoYS5nZXRUaW1lKCkpCmlm
-KE1hdGguYWJzKHMpPD04NjRlMTMpcj0hMQplbHNlIHI9ITAKaWYocilILnYoUC54WSgiRGF0ZVRpbWUg
-aXMgb3V0c2lkZSB2YWxpZCByYW5nZTogIitzKSkKSC5jYighMSwiaXNVdGMiLHQueSkKcmV0dXJuIG5l
-dyBQLmlQKHMsITEpfWVsc2UgaWYoYS5jb25zdHJ1Y3Rvcj09PSQua0koKSlyZXR1cm4gYS5vCmVsc2Ug
-cmV0dXJuIFAuTkQoYSl9LApORDpmdW5jdGlvbihhKXtpZih0eXBlb2YgYT09ImZ1bmN0aW9uIilyZXR1
-cm4gUC5pUShhLCQudygpLG5ldyBQLk56KCkpCmlmKGEgaW5zdGFuY2VvZiBBcnJheSlyZXR1cm4gUC5p
-UShhLCQuUjgoKSxuZXcgUC5RUygpKQpyZXR1cm4gUC5pUShhLCQuUjgoKSxuZXcgUC5ucCgpKX0sCmlR
-OmZ1bmN0aW9uKGEsYixjKXt2YXIgcz1QLk9tKGEsYikKaWYocz09bnVsbHx8IShhIGluc3RhbmNlb2Yg
-T2JqZWN0KSl7cz1jLiQxKGEpClAuRG0oYSxiLHMpfXJldHVybiBzfSwKUEM6ZnVuY3Rpb24gUEMoKXt9
-LAptdDpmdW5jdGlvbiBtdChhKXt0aGlzLmE9YX0sCk56OmZ1bmN0aW9uIE56KCl7fSwKUVM6ZnVuY3Rp
-b24gUVMoKXt9LApucDpmdW5jdGlvbiBucCgpe30sCkU0OmZ1bmN0aW9uIEU0KGEpe3RoaXMuYT1hfSwK
-cjc6ZnVuY3Rpb24gcjcoYSl7dGhpcy5hPWF9LApUejpmdW5jdGlvbiBUeihhLGIpe3RoaXMuYT1hCnRo
-aXMuJHRpPWJ9LApjbzpmdW5jdGlvbiBjbygpe30sCm5kOmZ1bmN0aW9uIG5kKCl7fSwKS2U6ZnVuY3Rp
-b24gS2UoYSl7dGhpcy5hPWF9LApoaTpmdW5jdGlvbiBoaSgpe319LFc9ewp4MzpmdW5jdGlvbigpe3Jl
-dHVybiB3aW5kb3d9LApacjpmdW5jdGlvbigpe3JldHVybiBkb2N1bWVudH0sCko2OmZ1bmN0aW9uKGEp
-e3ZhciBzPWRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoImEiKQppZihhIT1udWxsKUMueG4uc0xVKHMsYSkK
-cmV0dXJuIHN9LApVOTpmdW5jdGlvbihhLGIsYyl7dmFyIHMscj1kb2N1bWVudC5ib2R5CnIudG9TdHJp
-bmcKcz1DLlJZLnI2KHIsYSxiLGMpCnMudG9TdHJpbmcKcj10LmFjCnI9bmV3IEguVTUobmV3IFcuZTco
-cyksci5DKCJhMihsRC5FKSIpLmEobmV3IFcuQ3YoKSksci5DKCJVNTxsRC5FPiIpKQpyZXR1cm4gdC5o
-LmEoci5ncjgocikpfSwKclM6ZnVuY3Rpb24oYSl7dmFyIHMscixxPSJlbGVtZW50IHRhZyB1bmF2YWls
-YWJsZSIKdHJ5e3M9Si5ZRShhKQppZih0eXBlb2Ygcy5nbnMoYSk9PSJzdHJpbmciKXE9cy5nbnMoYSl9
-Y2F0Y2gocil7SC5SdShyKX1yZXR1cm4gcX0sCkMwOmZ1bmN0aW9uKGEsYil7YT1hK2ImNTM2ODcwOTEx
-CmE9YSsoKGEmNTI0Mjg3KTw8MTApJjUzNjg3MDkxMQpyZXR1cm4gYV5hPj4+Nn0sCnJFOmZ1bmN0aW9u
-KGEsYixjLGQpe3ZhciBzPVcuQzAoVy5DMChXLkMwKFcuQzAoMCxhKSxiKSxjKSxkKSxyPXMrKChzJjY3
-MTA4ODYzKTw8MykmNTM2ODcwOTExCnJePXI+Pj4xMQpyZXR1cm4gcisoKHImMTYzODMpPDwxNSkmNTM2
-ODcwOTExfSwKVE46ZnVuY3Rpb24oYSxiKXt2YXIgcyxyLHE9YS5jbGFzc0xpc3QKZm9yKHM9Yi5sZW5n
-dGgscj0wO3I8Yi5sZW5ndGg7Yi5sZW5ndGg9PT1zfHwoMCxILmxrKShiKSwrK3IpcS5hZGQoYltyXSl9
-LApKRTpmdW5jdGlvbihhLGIsYyxkLGUpe3ZhciBzPVcuYUYobmV3IFcudk4oYyksdC5CKQppZihzIT1u
-dWxsJiYhMClKLmRaKGEsYixzLCExKQpyZXR1cm4gbmV3IFcueEMoYSxiLHMsITEsZS5DKCJ4QzwwPiIp
-KX0sClR3OmZ1bmN0aW9uKGEpe3ZhciBzPVcuSjYobnVsbCkscj13aW5kb3cubG9jYXRpb24Kcz1uZXcg
-Vy5KUShuZXcgVy5tayhzLHIpKQpzLkNZKGEpCnJldHVybiBzfSwKcUQ6ZnVuY3Rpb24oYSxiLGMsZCl7
-dC5oLmEoYSkKSC5oKGIpCkguaChjKQp0LmNyLmEoZCkKcmV0dXJuITB9LApRVzpmdW5jdGlvbihhLGIs
-YyxkKXt2YXIgcyxyLHEKdC5oLmEoYSkKSC5oKGIpCkguaChjKQpzPXQuY3IuYShkKS5hCnI9cy5hCkMu
-eG4uc0xVKHIsYykKcT1yLmhvc3RuYW1lCnM9cy5iCmlmKCEocT09cy5ob3N0bmFtZSYmci5wb3J0PT1z
-LnBvcnQmJnIucHJvdG9jb2w9PXMucHJvdG9jb2wpKWlmKHE9PT0iIilpZihyLnBvcnQ9PT0iIil7cz1y
-LnByb3RvY29sCnM9cz09PSI6Inx8cz09PSIifWVsc2Ugcz0hMQplbHNlIHM9ITEKZWxzZSBzPSEwCnJl
-dHVybiBzfSwKQmw6ZnVuY3Rpb24oKXt2YXIgcz10Lk4scj1QLnRNKEMuUXgscykscT10LmQwLmEobmV3
-IFcuSUEoKSkscD1ILlZNKFsiVEVNUExBVEUiXSx0LnMpCnM9bmV3IFcuY3QocixQLkxzKHMpLFAuTHMo
-cyksUC5McyhzKSxudWxsKQpzLkNZKG51bGwsbmV3IEgubEooQy5ReCxxLHQuZmopLHAsbnVsbCkKcmV0
-dXJuIHN9LApxYzpmdW5jdGlvbihhKXt2YXIgcwppZihhPT1udWxsKXJldHVybiBudWxsCmlmKCJwb3N0
-TWVzc2FnZSIgaW4gYSl7cz1XLlAxKGEpCmlmKHQuYVMuYihzKSlyZXR1cm4gcwpyZXR1cm4gbnVsbH1l
-bHNlIHJldHVybiB0LmNoLmEoYSl9LApQMTpmdW5jdGlvbihhKXtpZihhPT09d2luZG93KXJldHVybiB0
-LmNpLmEoYSkKZWxzZSByZXR1cm4gbmV3IFcuZFcoKX0sCmFGOmZ1bmN0aW9uKGEsYil7dmFyIHM9JC5Y
-MwppZihzPT09Qy5OVSlyZXR1cm4gYQpyZXR1cm4gcy5QeShhLGIpfSwKcUU6ZnVuY3Rpb24gcUUoKXt9
-LApHaDpmdW5jdGlvbiBHaCgpe30sCmZZOmZ1bmN0aW9uIGZZKCl7fSwKbkI6ZnVuY3Rpb24gbkIoKXt9
-LApBejpmdW5jdGlvbiBBeigpe30sClFQOmZ1bmN0aW9uIFFQKCl7fSwKbng6ZnVuY3Rpb24gbngoKXt9
-LApvSjpmdW5jdGlvbiBvSigpe30sCmlkOmZ1bmN0aW9uIGlkKCl7fSwKUUY6ZnVuY3Rpb24gUUYoKXt9
-LApOaDpmdW5jdGlvbiBOaCgpe30sCmFlOmZ1bmN0aW9uIGFlKCl7fSwKSUI6ZnVuY3Rpb24gSUIoKXt9
-LApuNzpmdW5jdGlvbiBuNygpe30sCnd6OmZ1bmN0aW9uIHd6KGEsYil7dGhpcy5hPWEKdGhpcy4kdGk9
-Yn0sCmN2OmZ1bmN0aW9uIGN2KCl7fSwKQ3Y6ZnVuY3Rpb24gQ3YoKXt9LAplYTpmdW5jdGlvbiBlYSgp
-e30sCkQwOmZ1bmN0aW9uIEQwKCl7fSwKaEg6ZnVuY3Rpb24gaEgoKXt9LApoNDpmdW5jdGlvbiBoNCgp
-e30sCmJyOmZ1bmN0aW9uIGJyKCl7fSwKVmI6ZnVuY3Rpb24gVmIoKXt9LApmSjpmdW5jdGlvbiBmSigp
-e30sCndhOmZ1bmN0aW9uIHdhKCl7fSwKU2c6ZnVuY3Rpb24gU2coKXt9LAp1ODpmdW5jdGlvbiB1OCgp
-e30sCkFqOmZ1bmN0aW9uIEFqKCl7fSwKZTc6ZnVuY3Rpb24gZTcoYSl7dGhpcy5hPWF9LAp1SDpmdW5j
-dGlvbiB1SCgpe30sCkJIOmZ1bmN0aW9uIEJIKCl7fSwKU046ZnVuY3Rpb24gU04oKXt9LApldzpmdW5j
-dGlvbiBldygpe30sCmxwOmZ1bmN0aW9uIGxwKCl7fSwKVGI6ZnVuY3Rpb24gVGIoKXt9LApJdjpmdW5j
-dGlvbiBJdigpe30sCldQOmZ1bmN0aW9uIFdQKCl7fSwKeVk6ZnVuY3Rpb24geVkoKXt9LAp3NjpmdW5j
-dGlvbiB3Nigpe30sCks1OmZ1bmN0aW9uIEs1KCl7fSwKQ206ZnVuY3Rpb24gQ20oKXt9LApDUTpmdW5j
-dGlvbiBDUSgpe30sCnc0OmZ1bmN0aW9uIHc0KCl7fSwKcmg6ZnVuY3Rpb24gcmgoKXt9LApjZjpmdW5j
-dGlvbiBjZigpe30sCmk3OmZ1bmN0aW9uIGk3KGEpe3RoaXMuYT1hfSwKU3k6ZnVuY3Rpb24gU3koYSl7
-dGhpcy5hPWF9LApLUzpmdW5jdGlvbiBLUyhhLGIpe3RoaXMuYT1hCnRoaXMuYj1ifSwKQTM6ZnVuY3Rp
-b24gQTMoYSxiKXt0aGlzLmE9YQp0aGlzLmI9Yn0sCkk0OmZ1bmN0aW9uIEk0KGEpe3RoaXMuYT1hfSwK
-Rms6ZnVuY3Rpb24gRmsoYSxiKXt0aGlzLmE9YQp0aGlzLiR0aT1ifSwKUk86ZnVuY3Rpb24gUk8oYSxi
-LGMsZCl7dmFyIF89dGhpcwpfLmE9YQpfLmI9YgpfLmM9YwpfLiR0aT1kfSwKZXU6ZnVuY3Rpb24gZXUo
-YSxiLGMsZCl7dmFyIF89dGhpcwpfLmE9YQpfLmI9YgpfLmM9YwpfLiR0aT1kfSwKeEM6ZnVuY3Rpb24g
-eEMoYSxiLGMsZCxlKXt2YXIgXz10aGlzCl8uYj1hCl8uYz1iCl8uZD1jCl8uZT1kCl8uJHRpPWV9LAp2
-TjpmdW5jdGlvbiB2TihhKXt0aGlzLmE9YX0sCkpROmZ1bmN0aW9uIEpRKGEpe3RoaXMuYT1hfSwKR206
-ZnVuY3Rpb24gR20oKXt9LAp2RDpmdW5jdGlvbiB2RChhKXt0aGlzLmE9YX0sClV2OmZ1bmN0aW9uIFV2
-KGEpe3RoaXMuYT1hfSwKRWc6ZnVuY3Rpb24gRWcoYSxiLGMpe3RoaXMuYT1hCnRoaXMuYj1iCnRoaXMu
-Yz1jfSwKbTY6ZnVuY3Rpb24gbTYoKXt9LApFbzpmdW5jdGlvbiBFbygpe30sCldrOmZ1bmN0aW9uIFdr
-KCl7fSwKY3Q6ZnVuY3Rpb24gY3QoYSxiLGMsZCxlKXt2YXIgXz10aGlzCl8uZT1hCl8uYT1iCl8uYj1j
-Cl8uYz1kCl8uZD1lfSwKSUE6ZnVuY3Rpb24gSUEoKXt9LApPdzpmdW5jdGlvbiBPdygpe30sClc5OmZ1
-bmN0aW9uIFc5KGEsYixjKXt2YXIgXz10aGlzCl8uYT1hCl8uYj1iCl8uYz0tMQpfLmQ9bnVsbApfLiR0
-aT1jfSwKZFc6ZnVuY3Rpb24gZFcoKXt9LAptazpmdW5jdGlvbiBtayhhLGIpe3RoaXMuYT1hCnRoaXMu
-Yj1ifSwKS286ZnVuY3Rpb24gS28oYSl7dGhpcy5hPWEKdGhpcy5iPSExfSwKZm06ZnVuY3Rpb24gZm0o
-YSl7dGhpcy5hPWF9LApMZTpmdW5jdGlvbiBMZSgpe30sCks3OmZ1bmN0aW9uIEs3KCl7fSwKckI6ZnVu
-Y3Rpb24gckIoKXt9LApYVzpmdW5jdGlvbiBYVygpe30sCm9hOmZ1bmN0aW9uIG9hKCl7fX0sTT17Ck9Y
-OmZ1bmN0aW9uKGEpe3N3aXRjaChhKXtjYXNlIEMuQWQ6cmV0dXJuIkFkZCAvKj8qLyBoaW50IgpjYXNl
-IEMubmU6cmV0dXJuIkFkZCAvKiEqLyBoaW50IgpjYXNlIEMud1Y6cmV0dXJuIlJlbW92ZSAvKj8qLyBo
-aW50IgpjYXNlIEMuZlI6cmV0dXJuIlJlbW92ZSAvKiEqLyBoaW50IgpjYXNlIEMubXk6cmV0dXJuIkNo
-YW5nZSB0byAvKj8qLyBoaW50IgpjYXNlIEMucng6cmV0dXJuIkNoYW5nZSB0byAvKiEqLyBoaW50In1y
-ZXR1cm4gbnVsbH0sCkg3OmZ1bmN0aW9uIEg3KGEsYil7dGhpcy5hPWEKdGhpcy5iPWJ9LApZRjpmdW5j
-dGlvbihhLGIpe3ZhciBzLHIscSxwLG8sbixtLGwKZm9yKHM9Yi5sZW5ndGgscj0xO3I8czsrK3Ipe2lm
-KGJbcl09PW51bGx8fGJbci0xXSE9bnVsbCljb250aW51ZQpmb3IoO3M+PTE7cz1xKXtxPXMtMQppZihi
-W3FdIT1udWxsKWJyZWFrfXA9bmV3IFAuUm4oIiIpCm89YSsiKCIKcC5hPW8Kbj1ILnQ2KGIpCm09bi5D
-KCJuSDwxPiIpCmw9bmV3IEgubkgoYiwwLHMsbSkKbC5IZChiLDAscyxuLmMpCm09bytuZXcgSC5sSihs
-LG0uQygicVUoYUwuRSkiKS5hKG5ldyBNLk5vKCkpLG0uQygibEo8YUwuRSxxVT4iKSkuSCgwLCIsICIp
-CnAuYT1tCnAuYT1tKygiKTogcGFydCAiKyhyLTEpKyIgd2FzIG51bGwsIGJ1dCBwYXJ0ICIrcisiIHdh
-cyBub3QuIikKdGhyb3cgSC5iKFAueFkocC53KDApKSl9fSwKbEk6ZnVuY3Rpb24gbEkoYSl7dGhpcy5h
-PWF9LApxNzpmdW5jdGlvbiBxNygpe30sCk5vOmZ1bmN0aW9uIE5vKCl7fX0sVT17Cm56OmZ1bmN0aW9u
-KGEpe3ZhciBzPUgudVAoYS5xKDAsIm5vZGVJZCIpKQpyZXR1cm4gbmV3IFUuTEwoQy5ObS5IdChDLnJr
-LG5ldyBVLk1EKGEpKSxzKX0sCkxMOmZ1bmN0aW9uIExMKGEsYil7dGhpcy5hPWEKdGhpcy5iPWJ9LApN
-RDpmdW5jdGlvbiBNRChhKXt0aGlzLmE9YX0sCmpmOmZ1bmN0aW9uKGEpe3ZhciBzLHIscSxwCmlmKGE9
-PW51bGwpcz1udWxsCmVsc2V7cz1ILlZNKFtdLHQuZDcpCmZvcihyPUouSVQodC5VLmEoYSkpO3IuRigp
-Oyl7cT1yLmdsKCkKcD1KLlU2KHEpCnMucHVzaChuZXcgVS5TZShILmgocC5xKHEsImRlc2NyaXB0aW9u
-IikpLEguaChwLnEocSwiaHJlZiIpKSkpfX1yZXR1cm4gc30sCk5kOmZ1bmN0aW9uKGEpe3ZhciBzLHIK
-aWYoYT09bnVsbClzPW51bGwKZWxzZXtzPUguVk0oW10sdC5hQSkKZm9yKHI9Si5JVCh0LlUuYShhKSk7
-ci5GKCk7KXMucHVzaChVLk5mKHIuZ2woKSkpfXJldHVybiBzfSwKTmY6ZnVuY3Rpb24oYSl7dmFyIHM9
-Si5VNihhKSxyPUguaChzLnEoYSwiZGVzY3JpcHRpb24iKSkscT1ILlZNKFtdLHQuYUopCmZvcihzPUou
-SVQodC5VLmEocy5xKGEsImVudHJpZXMiKSkpO3MuRigpOylxLnB1c2goVS5SaihzLmdsKCkpKQpyZXR1
-cm4gbmV3IFUueUQocixxKX0sClJqOmZ1bmN0aW9uKGEpe3ZhciBzLHI9Si5VNihhKSxxPUguaChyLnEo
-YSwiZGVzY3JpcHRpb24iKSkscD1ILmgoci5xKGEsImZ1bmN0aW9uIikpLG89ci5xKGEsImxpbmsiKQpp
-ZihvPT1udWxsKW89bnVsbAplbHNle3M9Si5VNihvKQpvPW5ldyBVLk1sKEguaChzLnEobywiaHJlZiIp
-KSxILnVQKHMucShvLCJsaW5lIikpLEguaChzLnEobywicGF0aCIpKSl9cj10LmZLLmEoci5xKGEsImhp
-bnRBY3Rpb25zIikpCnI9cj09bnVsbD9udWxsOkouTTEocixuZXcgVS5hTigpLHQuYVgpCnI9cj09bnVs
-bD9udWxsOnIuYnIoMCkKcmV0dXJuIG5ldyBVLndiKHEscCxvLHI9PW51bGw/Qy5kbjpyKX0sCmQyOmZ1
-bmN0aW9uIGQyKGEsYixjLGQsZSxmKXt2YXIgXz10aGlzCl8uYT1hCl8uYj1iCl8uYz1jCl8uZD1kCl8u
-ZT1lCl8uZj1mfSwKU2U6ZnVuY3Rpb24gU2UoYSxiKXt0aGlzLmE9YQp0aGlzLmI9Yn0sCk1sOmZ1bmN0
-aW9uIE1sKGEsYixjKXt0aGlzLmE9YQp0aGlzLmI9Ygp0aGlzLmM9Y30sCnlEOmZ1bmN0aW9uIHlEKGEs
-Yil7dGhpcy5hPWEKdGhpcy5iPWJ9LAp3YjpmdW5jdGlvbiB3YihhLGIsYyxkKXt2YXIgXz10aGlzCl8u
-YT1hCl8uYj1iCl8uYz1jCl8uZD1kfSwKYU46ZnVuY3Rpb24gYU4oKXt9LApiMDpmdW5jdGlvbiBiMCgp
-e319LEI9ewp3UjpmdW5jdGlvbigpe3JldHVybiBuZXcgQi5xcCgiIiwiIiwiIixDLkR4KX0sCllmOmZ1
-bmN0aW9uKGEpe3ZhciBzLHIscSxwLG8sbixtLGwsaz1ILmgoYS5xKDAsInJlZ2lvbnMiKSksaj1ILmgo
-YS5xKDAsIm5hdmlnYXRpb25Db250ZW50IikpLGk9SC5oKGEucSgwLCJzb3VyY2VDb2RlIikpLGg9UC5G
-bCh0LlgsdC5kXykKZm9yKHM9dC50LmEoYS5xKDAsImVkaXRzIikpLHM9cy5nUHUocykscz1zLmdtKHMp
-LHI9dC5VLHE9dC5oNDtzLkYoKTspe3A9cy5nbCgpCm89cC5hCm49SC5WTShbXSxxKQpmb3IocD1KLklU
-KHIuYShwLmIpKTtwLkYoKTspe209cC5nbCgpCmw9Si5VNihtKQpuLnB1c2gobmV3IEIuajgoSC51UChs
-LnEobSwibGluZSIpKSxILmgobC5xKG0sImV4cGxhbmF0aW9uIikpLEgudVAobC5xKG0sIm9mZnNldCIp
-KSkpfWguWSgwLG8sbil9cmV0dXJuIG5ldyBCLnFwKGssaixpLGgpfSwKajg6ZnVuY3Rpb24gajgoYSxi
-LGMpe3RoaXMuYT1hCnRoaXMuYj1iCnRoaXMuYz1jfSwKcXA6ZnVuY3Rpb24gcXAoYSxiLGMsZCl7dmFy
-IF89dGhpcwpfLmE9YQpfLmI9YgpfLmM9YwpfLmQ9ZH0sCmZ2OmZ1bmN0aW9uIGZ2KCl7fSwKT1M6ZnVu
-Y3Rpb24oYSl7dmFyIHMKaWYoIShhPj02NSYmYTw9OTApKXM9YT49OTcmJmE8PTEyMgplbHNlIHM9ITAK
-cmV0dXJuIHN9LApZdTpmdW5jdGlvbihhLGIpe3ZhciBzPWEubGVuZ3RoLHI9YisyCmlmKHM8cilyZXR1
-cm4hMQppZighQi5PUyhDLnhCLk8yKGEsYikpKXJldHVybiExCmlmKEMueEIuTzIoYSxiKzEpIT09NTgp
-cmV0dXJuITEKaWYocz09PXIpcmV0dXJuITAKcmV0dXJuIEMueEIuTzIoYSxyKT09PTQ3fX0sVD17bVE6
-ZnVuY3Rpb24gbVEoKXt9fSxMPXsKSXE6ZnVuY3Rpb24oKXtDLkJaLkIoZG9jdW1lbnQsIkRPTUNvbnRl
-bnRMb2FkZWQiLG5ldyBMLmUoKSkKQy5vbC5CKHdpbmRvdywicG9wc3RhdGUiLG5ldyBMLkwoKSl9LApr
-ejpmdW5jdGlvbihhKXt2YXIgcyxyPXQuZy5hKGEucGFyZW50Tm9kZSkucXVlcnlTZWxlY3RvcigiOnNj
-b3BlID4gdWwiKSxxPXIuc3R5bGUscD0iIitDLkNELnpRKHIub2Zmc2V0SGVpZ2h0KSoyKyJweCIKcS5t
-YXhIZWlnaHQ9cApxPUoucUYoYSkKcD1xLiR0aQpzPXAuQygifigxKT8iKS5hKG5ldyBMLld4KHIsYSkp
-CnQuWi5hKG51bGwpClcuSkUocS5hLHEuYixzLCExLHAuYyl9LAp5WDpmdW5jdGlvbihhLGIpe3ZhciBz
-LHIscSxwLG8sbixtPSJxdWVyeVNlbGVjdG9yQWxsIixsPWRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoYSks
-az10LmcKbC50b1N0cmluZwpzPXQuaApILkRoKGsscywiVCIsbSkKcj10LlIKcT1uZXcgVy53eihsLnF1
-ZXJ5U2VsZWN0b3JBbGwoIi5uYXYtbGluayIpLHIpCnEuSyhxLG5ldyBMLkFPKGIpKQpILkRoKGsscywi
-VCIsbSkKcD1uZXcgVy53eihsLnF1ZXJ5U2VsZWN0b3JBbGwoIi5yZWdpb24iKSxyKQppZighcC5nbDAo
-cCkpe289bC5xdWVyeVNlbGVjdG9yKCJ0YWJsZVtkYXRhLXBhdGhdIikKby50b1N0cmluZwpwLksocCxu
-ZXcgTC5IbyhvLmdldEF0dHJpYnV0ZSgiZGF0YS0iK25ldyBXLlN5KG5ldyBXLmk3KG8pKS5PKCJwYXRo
-IikpKSl9SC5EaChrLHMsIlQiLG0pCm49bmV3IFcud3oobC5xdWVyeVNlbGVjdG9yQWxsKCIuYWRkLWhp
-bnQtbGluayIpLHIpCm4uSyhuLG5ldyBMLklDKCkpfSwKUTY6ZnVuY3Rpb24oYSxiLGMpe3ZhciBzPW5l
-dyBYTUxIdHRwUmVxdWVzdCgpCkMuRHQuZW8ocywiR0VUIixMLlE0KGEsYiksITApCnMuc2V0UmVxdWVz
-dEhlYWRlcigiQ29udGVudC1UeXBlIiwiYXBwbGljYXRpb24vanNvbjsgY2hhcnNldD1VVEYtOCIpCnJl
-dHVybiBMLkxVKHMsbnVsbCxjLkMoIjAqIikpfSwKdHk6ZnVuY3Rpb24oYSxiKXt2YXIgcz1uZXcgWE1M
-SHR0cFJlcXVlc3QoKSxyPXQuWApDLkR0LmVvKHMsIlBPU1QiLEwuUTQoYSxQLkZsKHIscikpLCEwKQpz
-LnNldFJlcXVlc3RIZWFkZXIoIkNvbnRlbnQtVHlwZSIsImFwcGxpY2F0aW9uL2pzb247IGNoYXJzZXQ9
-VVRGLTgiKQpyZXR1cm4gTC5MVShzLGIsdC50KX0sCkxVOmZ1bmN0aW9uKGEsYixjKXtyZXR1cm4gTC5U
-ZyhhLGIsYyxjLkMoIjAqIikpfSwKVGc6ZnVuY3Rpb24oYSxiLGMsZCl7dmFyIHM9MCxyPVAuRlgoZCks
-cSxwPTIsbyxuPVtdLG0sbCxrLGosaSxoLGcsZgp2YXIgJGFzeW5jJExVPVAubHooZnVuY3Rpb24oZSxh
-MCl7aWYoZT09PTEpe289YTAKcz1wfXdoaWxlKHRydWUpc3dpdGNoKHMpe2Nhc2UgMDppPW5ldyBQLlpm
-KG5ldyBQLnZzKCQuWDMsdC5nViksdC5iQykKaD10LmViCmc9aC5hKG5ldyBMLmZDKGksYSkpCnQuWi5h
-KG51bGwpCmw9dC5lUQpXLkpFKGEsImxvYWQiLGcsITEsbCkKVy5KRShhLCJlcnJvciIsaC5hKGkuZ1lK
-KCkpLCExLGwpCmEuc2VuZChiPT1udWxsP251bGw6Qy5DdC5PQihiLG51bGwpKQpwPTQKcz03CnJldHVy
-biBQLmpRKGkuYSwkYXN5bmMkTFUpCmNhc2UgNzpwPTIKcz02CmJyZWFrCmNhc2UgNDpwPTMKZj1vCkgu
-UnUoZikKbT1ILnRzKGYpCmg9UC5UbCgiRXJyb3IgcmVhY2hpbmcgbWlncmF0aW9uIHByZXZpZXcgc2Vy
-dmVyLiIsbSkKdGhyb3cgSC5iKGgpCnM9NgpicmVhawpjYXNlIDM6cz0yCmJyZWFrCmNhc2UgNjpqPUMu
-Q3QucFcoMCxhLnJlc3BvbnNlVGV4dCxudWxsKQppZihhLnN0YXR1cz09PTIwMCl7cT1jLkMoIjAqIiku
-YShqKQpzPTEKYnJlYWt9ZWxzZSB0aHJvdyBILmIoaikKY2FzZSAxOnJldHVybiBQLnlDKHEscikKY2Fz
-ZSAyOnJldHVybiBQLmYzKG8scil9fSkKcmV0dXJuIFAuREkoJGFzeW5jJExVLHIpfSwKYUs6ZnVuY3Rp
-b24oYSl7dmFyIHM9UC5oSyhhKS5naFkoKS5xKDAsImxpbmUiKQpyZXR1cm4gcz09bnVsbD9udWxsOkgu
-SHAocyxudWxsKX0sCkc2OmZ1bmN0aW9uKGEpe3ZhciBzPVAuaEsoYSkuZ2hZKCkucSgwLCJvZmZzZXQi
-KQpyZXR1cm4gcz09bnVsbD9udWxsOkguSHAocyxudWxsKX0sCmk2OmZ1bmN0aW9uKGEpe3JldHVybiBM
-Lm5XKHQuTy5hKGEpKX0sCm5XOmZ1bmN0aW9uKGEpe3ZhciBzPTAscj1QLkZYKHQueikscT0xLHAsbz1b
-XSxuLG0sbCxrLGosaSxoCnZhciAkYXN5bmMkaTY9UC5seihmdW5jdGlvbihiLGMpe2lmKGI9PT0xKXtw
-PWMKcz1xfXdoaWxlKHRydWUpc3dpdGNoKHMpe2Nhc2UgMDppPXQuZy5hKFcucWMoYS5jdXJyZW50VGFy
-Z2V0KSkuZ2V0QXR0cmlidXRlKCJocmVmIikKYS5wcmV2ZW50RGVmYXVsdCgpCnE9MwprPWRvY3VtZW50
-Cm49Qy5DRC56UShrLnF1ZXJ5U2VsZWN0b3IoIi5jb250ZW50Iikuc2Nyb2xsVG9wKQpzPTYKcmV0dXJu
-IFAualEoTC50eShpLG51bGwpLCRhc3luYyRpNikKY2FzZSA2OnM9NwpyZXR1cm4gUC5qUShMLkc3KHdp
-bmRvdy5sb2NhdGlvbi5wYXRobmFtZSxudWxsLG51bGwsITEsbnVsbCksJGFzeW5jJGk2KQpjYXNlIDc6
-az1rLnF1ZXJ5U2VsZWN0b3IoIi5jb250ZW50IikKay50b1N0cmluZwprLnNjcm9sbFRvcD1KLlZ1KG4p
-CnE9MQpzPTUKYnJlYWsKY2FzZSAzOnE9MgpoPXAKbT1ILlJ1KGgpCmw9SC50cyhoKQpMLkMyKCJDb3Vs
-ZCBub3QgYWRkL3JlbW92ZSBoaW50IixtLGwpCnM9NQpicmVhawpjYXNlIDI6cz0xCmJyZWFrCmNhc2Ug
-NTpyZXR1cm4gUC55QyhudWxsLHIpCmNhc2UgMTpyZXR1cm4gUC5mMyhwLHIpfX0pCnJldHVybiBQLkRJ
-KCRhc3luYyRpNixyKX0sCkMyOmZ1bmN0aW9uKGEsYixjKXt2YXIgcyxyLHEscD0iZXhjZXB0aW9uIixv
-PSJzdGFja1RyYWNlIixuPXQudC5iKGIpJiZKLlJNKGIucSgwLCJzdWNjZXNzIiksITEpJiZiLng0KHAp
-JiZiLng0KG8pLG09Si5pYShiKQppZihuKXtzPUguaChtLnEoYixwKSkKYz1tLnEoYixvKX1lbHNlIHM9
-bS53KGIpCm49ZG9jdW1lbnQKcj1uLnF1ZXJ5U2VsZWN0b3IoIi5wb3B1cC1wYW5lIikKci5xdWVyeVNl
-bGVjdG9yKCJoMiIpLmlubmVyVGV4dD1hCnIucXVlcnlTZWxlY3RvcigicCIpLmlubmVyVGV4dD1zCnIu
-cXVlcnlTZWxlY3RvcigicHJlIikuaW5uZXJUZXh0PUouaihjKQpxPXQuZGQuYShyLnF1ZXJ5U2VsZWN0
-b3IoImEuYm90dG9tIikpCm09dC5YOyhxJiZDLnhuKS5zTFUocSxQLlhkKCJodHRwcyIsImdpdGh1Yi5j
-b20iLCJkYXJ0LWxhbmcvc2RrL2lzc3Vlcy9uZXciLFAuRUYoWyJ0aXRsZSIsIkN1c3RvbWVyLXJlcG9y
-dGVkIGlzc3VlIHdpdGggTk5CRCBtaWdyYXRpb24gdG9vbDogIithLCJsYWJlbHMiLHUuZCwiYm9keSIs
-YSsiXG5cbkVycm9yOiAiK0guRWoocykrIlxuXG5QbGVhc2UgZmlsbCBpbiB0aGUgZm9sbG93aW5nOlxu
-XG4qKk5hbWUgb2YgcGFja2FnZSBiZWluZyBtaWdyYXRlZCAoaWYgcHVibGljKSoqOlxuKipXaGF0IEkg
-d2FzIGRvaW5nIHdoZW4gdGhpcyBpc3N1ZSBvY2N1cnJlZCoqOlxuKipJcyBpdCBwb3NzaWJsZSB0byB3
-b3JrIGFyb3VuZCB0aGlzIGlzc3VlKio6XG4qKkhhcyB0aGlzIGlzc3VlIGhhcHBlbmVkIGJlZm9yZSwg
-YW5kIGlmIHNvLCBob3cgb2Z0ZW4qKjpcbioqRGFydCBTREsgdmVyc2lvbioqOiAiK0guRWoobi5nZXRF
-bGVtZW50QnlJZCgic2RrLXZlcnNpb24iKS50ZXh0Q29udGVudCkrIlxuKipBZGRpdGlvbmFsIGRldGFp
-bHMqKjpcblxuVGhhbmtzIGZvciBmaWxpbmchXG5cblN0YWNrdHJhY2U6IF9hdXRvIHBvcHVsYXRlZCBi
-eSBtaWdyYXRpb24gcHJldmlldyB0b29sLl9cblxuYGBgXG4iK0guRWooYykrIlxuYGBgXG4iXSxtLG0p
-KS5nbkQoKSkKbT1xLnN0eWxlCm0uZGlzcGxheT0iaW5pdGlhbCIKbj1yLnN0eWxlCm4uZGlzcGxheT0i
-aW5pdGlhbCIKbj1hKyI6ICIrSC5FaihiKQp3aW5kb3cKaWYodHlwZW9mIGNvbnNvbGUhPSJ1bmRlZmlu
-ZWQiKXdpbmRvdy5jb25zb2xlLmVycm9yKG4pCndpbmRvdwpuPUguRWooYykKaWYodHlwZW9mIGNvbnNv
-bGUhPSJ1bmRlZmluZWQiKXdpbmRvdy5jb25zb2xlLmVycm9yKG4pfSwKdDI6ZnVuY3Rpb24oYSxiLGMp
-e3ZhciBzLHIscSxwLG89dC5nLmEoVy5xYyhhLmN1cnJlbnRUYXJnZXQpKQphLnByZXZlbnREZWZhdWx0
-KCkKcz1vLmdldEF0dHJpYnV0ZSgiaHJlZiIpCnI9TC5VcyhzKQpxPUwuRzYocykKcD1MLmFLKHMpCmlm
-KHEhPW51bGwpTC5hZihyLHEscCxiLG5ldyBMLm5UKHIscSxwKSkKZWxzZSBMLmFmKHIsbnVsbCxudWxs
-LGIsbmV3IEwuTlkocikpfSwKSzA6ZnVuY3Rpb24oYSl7dmFyIHMscixxLHA9ZG9jdW1lbnQucXVlcnlT
-ZWxlY3RvcigiLnBvcHVwLXBhbmUiKQpwLnF1ZXJ5U2VsZWN0b3IoImgyIikuaW5uZXJUZXh0PSJGYWls
-ZWQgdG8gcmVydW4gZnJvbSBzb3VyY2VzIgpwLnF1ZXJ5U2VsZWN0b3IoInAiKS5pbm5lclRleHQ9IlNv
-dXJjZXMgY29udGFpbiBzdGF0aWMgYW5hbHlzaXMgZXJyb3JzOiIKcz1wLnF1ZXJ5U2VsZWN0b3IoInBy
-ZSIpCnI9Si5FbChhLHQuYXcpCnE9SC5MaChyKQpzLmlubmVyVGV4dD1uZXcgSC5sSihyLHEuQygicVUq
-KGxELkUpIikuYShuZXcgTC51ZSgpKSxxLkMoImxKPGxELkUscVUqPiIpKS5IKDAsIlxuIikKcT1wLnF1
-ZXJ5U2VsZWN0b3IoImEuYm90dG9tIikuc3R5bGUKcS5kaXNwbGF5PSJub25lIgpzPXAuc3R5bGUKcy5k
-aXNwbGF5PSJpbml0aWFsIn0sCnZVOmZ1bmN0aW9uKCl7dmFyIHM9ZG9jdW1lbnQKSC5EaCh0LmcsdC5o
-LCJUIiwicXVlcnlTZWxlY3RvckFsbCIpCnM9bmV3IFcud3oocy5xdWVyeVNlbGVjdG9yQWxsKCIuY29k
-ZSIpLHQuUikKcy5LKHMsbmV3IEwuZVgoKSl9LApoWDpmdW5jdGlvbihhLGIsYyl7cmV0dXJuIEwuWXco
-YSxiLGMpfSwKWXc6ZnVuY3Rpb24oYSxiLGMpe3ZhciBzPTAscj1QLkZYKHQueikscT0xLHAsbz1bXSxu
-LG0sbCxrLGosaSxoLGcKdmFyICRhc3luYyRoWD1QLmx6KGZ1bmN0aW9uKGQsZSl7aWYoZD09PTEpe3A9
-ZQpzPXF9d2hpbGUodHJ1ZSlzd2l0Y2gocyl7Y2FzZSAwOnE9MwpqPXQuWApzPTYKcmV0dXJuIFAualEo
-TC5RNihhLFAuRUYoWyJyZWdpb24iLCJyZWdpb24iLCJvZmZzZXQiLEguRWooYildLGosaiksdC50KSwk
-YXN5bmMkaFgpCmNhc2UgNjpuPWUKaj1uCmk9Si5VNihqKQptPW5ldyBVLmQyKFUuamYoaS5xKGosImVk
-aXRzIikpLEguaChpLnEoaiwiZXhwbGFuYXRpb24iKSksSC51UChpLnEoaiwibGluZSIpKSxILmgoaS5x
-KGosImRpc3BsYXlQYXRoIikpLEguaChpLnEoaiwidXJpUGF0aCIpKSxVLk5kKGkucShqLCJ0cmFjZXMi
-KSkpCkwuVDEobSkKTC5GcihhLGIsYykKTC55WCgiLmVkaXQtcGFuZWwgLnBhbmVsLWNvbnRlbnQiLCEx
-KQpxPTEKcz01CmJyZWFrCmNhc2UgMzpxPTIKZz1wCmw9SC5SdShnKQprPUgudHMoZykKTC5DMigiQ291
-bGQgbm90IGxvYWQgZWRpdCBkZXRhaWxzIixsLGspCnM9NQpicmVhawpjYXNlIDI6cz0xCmJyZWFrCmNh
-c2UgNTpyZXR1cm4gUC55QyhudWxsLHIpCmNhc2UgMTpyZXR1cm4gUC5mMyhwLHIpfX0pCnJldHVybiBQ
-LkRJKCRhc3luYyRoWCxyKX0sCkc3OmZ1bmN0aW9uKGEsYixjLGQsZSl7cmV0dXJuIEwuTDUoYSxiLGMs
-ZCxlKX0sCkw1OmZ1bmN0aW9uKGEsYixjLGQsZSl7dmFyIHM9MCxyPVAuRlgodC5IKSxxLHA9MixvLG49
-W10sbSxsLGssaixpLGgsZwp2YXIgJGFzeW5jJEc3PVAubHooZnVuY3Rpb24oZixhMCl7aWYoZj09PTEp
-e289YTAKcz1wfXdoaWxlKHRydWUpc3dpdGNoKHMpe2Nhc2UgMDppZighSi5wNChhLCIuZGFydCIpKXtM
-LkJFKGEsQi53UigpLGQpCkwuQlgoYSxudWxsKQppZihlIT1udWxsKWUuJDAoKQpzPTEKYnJlYWt9cD00
-Cmk9dC5YCnM9NwpyZXR1cm4gUC5qUShMLlE2KGEsUC5FRihbImlubGluZSIsInRydWUiXSxpLGkpLHQu
-dCksJGFzeW5jJEc3KQpjYXNlIDc6bT1hMApMLkJFKGEsQi5ZZihtKSxkKQpMLmZHKGIsYykKbD1MLlVz
-KGEpCkwuQlgobCxiKQppZihlIT1udWxsKWUuJDAoKQpwPTIKcz02CmJyZWFrCmNhc2UgNDpwPTMKZz1v
-Cms9SC5SdShnKQpqPUgudHMoZykKTC5DMigiQ291bGQgbm90IGxvYWQgZGFydCBmaWxlICIrYSxrLGop
-CnM9NgpicmVhawpjYXNlIDM6cz0yCmJyZWFrCmNhc2UgNjpjYXNlIDE6cmV0dXJuIFAueUMocSxyKQpj
-YXNlIDI6cmV0dXJuIFAuZjMobyxyKX19KQpyZXR1cm4gUC5ESSgkYXN5bmMkRzcscil9LApHZTpmdW5j
-dGlvbigpe3ZhciBzPTAscj1QLkZYKHQueikscT0xLHAsbz1bXSxuLG0sbCxrLGosaSxoCnZhciAkYXN5
-bmMkR2U9UC5seihmdW5jdGlvbihhLGIpe2lmKGE9PT0xKXtwPWIKcz1xfXdoaWxlKHRydWUpc3dpdGNo
-KHMpe2Nhc2UgMDppPSIvX3ByZXZpZXcvbmF2aWdhdGlvblRyZWUuanNvbiIKcT0zCnM9NgpyZXR1cm4g
-UC5qUShMLlE2KGksQy5DTSx0Lm0pLCRhc3luYyRHZSkKY2FzZSA2Om49YgptPWRvY3VtZW50LnF1ZXJ5
-U2VsZWN0b3IoIi5uYXYtdHJlZSIpCkoubDUobSwiIikKTC50WChtLEwubUsobiksITEpCnE9MQpzPTUK
-YnJlYWsKY2FzZSAzOnE9MgpoPXAKbD1ILlJ1KGgpCms9SC50cyhoKQpMLkMyKCJDb3VsZCBub3QgbG9h
-ZCBuYXZpZ2F0aW9uIHRyZWUiLGwsaykKcz01CmJyZWFrCmNhc2UgMjpzPTEKYnJlYWsKY2FzZSA1OnJl
-dHVybiBQLnlDKG51bGwscikKY2FzZSAxOnJldHVybiBQLmYzKHAscil9fSkKcmV0dXJuIFAuREkoJGFz
-eW5jJEdlLHIpfSwKcU86ZnVuY3Rpb24oYSl7dmFyIHMscj1hLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgp
-LHE9Qy5DRC56USgkLmZpKCkub2Zmc2V0SGVpZ2h0KSxwPXdpbmRvdy5pbm5lckhlaWdodCxvPUMuQ0Qu
-elEoJC5EVygpLm9mZnNldEhlaWdodCkKaWYodHlwZW9mIHAhPT0ibnVtYmVyIilyZXR1cm4gcC5ITigp
-CnM9ci5ib3R0b20Kcy50b1N0cmluZwppZihzPnAtKG8rMTQpKUouZGgoYSkKZWxzZXtwPXIudG9wCnAu
-dG9TdHJpbmcKaWYocDxxKzE0KUouZGgoYSl9fSwKZkc6ZnVuY3Rpb24oYSxiKXt2YXIgcyxyLHEscCxv
-CmlmKGEhPW51bGwpe3M9ZG9jdW1lbnQKcj1zLmdldEVsZW1lbnRCeUlkKCJvIitILkVqKGEpKQpxPXMu
-cXVlcnlTZWxlY3RvcigiLmxpbmUtIitILkVqKGIpKQppZihyIT1udWxsKXtMLnFPKHIpCkouZFIociku
-aSgwLCJ0YXJnZXQiKX1lbHNlIGlmKHEhPW51bGwpTC5xTyhxLnBhcmVudEVsZW1lbnQpCmlmKHEhPW51
-bGwpSi5kUih0LmcuYShxLnBhcmVudE5vZGUpKS5pKDAsImhpZ2hsaWdodCIpfWVsc2V7cz1kb2N1bWVu
-dApwPXQuZwpILkRoKHAsdC5oLCJUIiwicXVlcnlTZWxlY3RvckFsbCIpCnM9cy5xdWVyeVNlbGVjdG9y
-QWxsKCIubGluZS1ubyIpCm89bmV3IFcud3oocyx0LlIpCmlmKG8uZ0Eobyk9PT0wKXJldHVybgpMLnFP
-KHAuYShDLnQ1Lmd0SChzKSkpfX0sCmFmOmZ1bmN0aW9uKGEsYixjLGQsZSl7dmFyIHMscixxPUwuRzYo
-d2luZG93LmxvY2F0aW9uLmhyZWYpLHA9TC5hSyh3aW5kb3cubG9jYXRpb24uaHJlZikKaWYocSE9bnVs
-bCl7cz1kb2N1bWVudC5nZXRFbGVtZW50QnlJZCgibyIrSC5FaihxKSkKaWYocyE9bnVsbClKLmRSKHMp
-LlIoMCwidGFyZ2V0Iil9aWYocCE9bnVsbCl7cj1kb2N1bWVudC5xdWVyeVNlbGVjdG9yKCIubGluZS0i
-K0guRWoocCkpCmlmKHIhPW51bGwpSi5kUihyLnBhcmVudEVsZW1lbnQpLlIoMCwiaGlnaGxpZ2h0Iil9
-aWYoYT09d2luZG93LmxvY2F0aW9uLnBhdGhuYW1lKXtMLmZHKGIsYykKZS4kMCgpfWVsc2UgTC5HNyhh
-LGIsYyxkLGUpfSwKUTQ6ZnVuY3Rpb24oYSxiKXt2YXIgcyxyLHE9UC5oSyhhKSxwPXQuWApwPVAuRmwo
-cCxwKQpmb3Iocz1xLmdoWSgpLHM9cy5nUHUocykscz1zLmdtKHMpO3MuRigpOyl7cj1zLmdsKCkKcC5Z
-KDAsci5hLHIuYil9Zm9yKHM9Yi5nUHUoYikscz1zLmdtKHMpO3MuRigpOyl7cj1zLmdsKCkKcC5ZKDAs
-ci5hLHIuYil9cC5ZKDAsImF1dGhUb2tlbiIsJC5VRSgpKQpyZXR1cm4gcS5ubSgwLHApLmduRCgpfSwK
-VDE6ZnVuY3Rpb24oYSl7dmFyIHMscixxLHAsbyxuLG0sbCxrLGo9JC5oTCgpCkoubDUoaiwiIikKaWYo
-YT09bnVsbCl7cz1kb2N1bWVudC5jcmVhdGVFbGVtZW50KCJwIikKQy5MdC5zYTQocywiU2VlIGRldGFp
-bHMgYWJvdXQgYSBwcm9wb3NlZCBlZGl0LiIpCkMuTHQuc0QocyxILlZNKFsicGxhY2Vob2xkZXIiXSx0
-LmkpKQpqLmFwcGVuZENoaWxkKHMpCkMuTHQuRkYocykKcmV0dXJufXI9YS5kCnE9JC5uVSgpCnA9cS56
-ZihyKQpvPWEuYgpuPWRvY3VtZW50Cm09cS5IUChyLEouVDAobi5xdWVyeVNlbGVjdG9yKCIucm9vdCIp
-LnRleHRDb250ZW50KSkKbD1hLmMKaz1uLmNyZWF0ZUVsZW1lbnQoInAiKQpqLmFwcGVuZENoaWxkKGsp
-CmsuYXBwZW5kQ2hpbGQobi5jcmVhdGVUZXh0Tm9kZShILkVqKG8pKyIgYXQgIikpCnE9dC5YCnE9Vy5K
-NihMLlE0KGEuZSxQLkVGKFsibGluZSIsSi5qKGwpXSxxLHEpKSkKcS5hcHBlbmRDaGlsZChuLmNyZWF0
-ZVRleHROb2RlKEguRWoobSkrIjoiK0guRWoobCkrIi4iKSkKay5hcHBlbmRDaGlsZChxKQpKLmRoKGsp
-CkwuQ0MoYSxqLHApCkwuRnooYSxqKX0sCkxIOmZ1bmN0aW9uKGEsYixjKXt2YXIgcyxyLHEscCxvLG4s
-bSxsLGssaixpLGgsZyxmLGU9JC55UCgpCkoubDUoZSwiIikKaWYoYi5nQShiKT09PTApe3M9ZG9jdW1l
-bnQKcj1zLmNyZWF0ZUVsZW1lbnQoInAiKQplLmFwcGVuZENoaWxkKHIpCnIuYXBwZW5kQ2hpbGQocy5j
-cmVhdGVUZXh0Tm9kZSgiTm8gcHJvcG9zZWQgZWRpdHMiKSl9ZWxzZSBmb3IoZT1iLmdQdShiKSxlPWUu
-Z20oZSkscz10LlgscT10LmsscD1xLkMoIn4oMSk/Iiksbz10LloscT1xLmM7ZS5GKCk7KXtuPWUuZ2wo
-KQptPWRvY3VtZW50CnI9bS5jcmVhdGVFbGVtZW50KCJwIikKbD0kLnlQKCkKbC5hcHBlbmRDaGlsZChy
-KQpyLmFwcGVuZENoaWxkKG0uY3JlYXRlVGV4dE5vZGUoSC5FaihuLmEpKyI6IikpCms9bS5jcmVhdGVF
-bGVtZW50KCJ1bCIpCmwuYXBwZW5kQ2hpbGQoaykKZm9yKG49Si5JVChuLmIpO24uRigpOyl7bD1uLmds
-KCkKaj1tLmNyZWF0ZUVsZW1lbnQoImxpIikKay5hcHBlbmRDaGlsZChqKQpKLmRSKGopLmkoMCwiZWRp
-dCIpCmk9bS5jcmVhdGVFbGVtZW50KCJhIikKai5hcHBlbmRDaGlsZChpKQppLmNsYXNzTGlzdC5hZGQo
-ImVkaXQtbGluayIpCmg9bC5jCmc9SC5FaihoKQppLnNldEF0dHJpYnV0ZSgiZGF0YS0iK25ldyBXLlN5
-KG5ldyBXLmk3KGkpKS5PKCJvZmZzZXQiKSxnKQpmPWwuYQpnPUguRWooZikKaS5zZXRBdHRyaWJ1dGUo
-ImRhdGEtIituZXcgVy5TeShuZXcgVy5pNyhpKSkuTygibGluZSIpLGcpCmkuYXBwZW5kQ2hpbGQobS5j
-cmVhdGVUZXh0Tm9kZSgibGluZSAiK0guRWooZikpKQppLnNldEF0dHJpYnV0ZSgiaHJlZiIsTC5RNCh3
-aW5kb3cubG9jYXRpb24ucGF0aG5hbWUsUC5FRihbImxpbmUiLEguRWooZiksIm9mZnNldCIsSC5Faiho
-KV0scyxzKSkpCmc9cC5hKG5ldyBMLkVFKGgsZixhKSkKby5hKG51bGwpClcuSkUoaSwiY2xpY2siLGcs
-ITEscSkKai5hcHBlbmRDaGlsZChtLmNyZWF0ZVRleHROb2RlKCI6ICIrSC5FaihsLmIpKSl9fWlmKGMp
-TC5UMShudWxsKX0sCkZyOmZ1bmN0aW9uKGEsYixjKXt2YXIgcyxyLHE9d2luZG93LmxvY2F0aW9uLHA9
-UC5oSygocSYmQy5FeCkuZ0RyKHEpK0guRWooYSkpCnE9dC5YCnE9UC5GbChxLHEpCmlmKGIhPW51bGwp
-cS5ZKDAsIm9mZnNldCIsSC5FaihiKSkKaWYoYyE9bnVsbClxLlkoMCwibGluZSIsSC5FaihjKSkKcS5Z
-KDAsImF1dGhUb2tlbiIsJC5VRSgpKQpwPXAubm0oMCxxKQpxPXdpbmRvdy5oaXN0b3J5CnM9dC56CnI9
-cC5nbkQoKQpxLnRvU3RyaW5nCnEucHVzaFN0YXRlKG5ldyBQLkJmKFtdLFtdKS5QdihQLkZsKHMscykp
-LCIiLHIpfSwKRW46ZnVuY3Rpb24oYSl7dmFyIHM9Si5iYihkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCIu
-cm9vdCIpLnRleHRDb250ZW50LCIvIikKaWYoQy54Qi5uKGEscykpcmV0dXJuIEMueEIuRyhhLHMubGVu
-Z3RoKQplbHNlIHJldHVybiBhfSwKQlg6ZnVuY3Rpb24oYSxiKXt2YXIgcyxyPXt9CnIuYT1hCmE9TC5F
-bihhKQpyLmE9YQpKLmRyKCQuRDkoKSxhKQpzPWRvY3VtZW50CkguRGgodC5nLHQuaCwiVCIsInF1ZXJ5
-U2VsZWN0b3JBbGwiKQpzPW5ldyBXLnd6KHMucXVlcnlTZWxlY3RvckFsbCgiLm5hdi1wYW5lbCAubmF2
-LWxpbmsiKSx0LlIpCnMuSyhzLG5ldyBMLlZTKHIpKX0sCkJFOmZ1bmN0aW9uKGEsYixjKXt2YXIgcz0i
-LnJlZ2lvbnMiLHI9ZG9jdW1lbnQscT1yLnF1ZXJ5U2VsZWN0b3IocykscD1yLnF1ZXJ5U2VsZWN0b3Io
-Ii5jb2RlIikKSi50SChxLGIuYSwkLktHKCkpCkoudEgocCxiLmIsJC5LRygpKQpMLkxIKGEsYi5kLGMp
-CmlmKGIuYy5sZW5ndGg8MmU1KUwudlUoKQpMLnlYKCIuY29kZSIsITApCkwueVgocywhMCl9LAp0WDpm
-dW5jdGlvbihhLGIsYTApe3ZhciBzLHIscSxwLG8sbixtLGwsayxqLGksaCxnLGYsZT0ibWF0ZXJpYWwt
-aWNvbnMiLGQ9ZG9jdW1lbnQsYz1kLmNyZWF0ZUVsZW1lbnQoInVsIikKYS5hcHBlbmRDaGlsZChjKQpm
-b3Iocz1iLmxlbmd0aCxyPXQuWCxxPXQuWixwPTA7cDxiLmxlbmd0aDtiLmxlbmd0aD09PXN8fCgwLEgu
-bGspKGIpLCsrcCl7bz1iW3BdCm49ZC5jcmVhdGVFbGVtZW50KCJsaSIpCmMuYXBwZW5kQ2hpbGQobikK
-aWYobyBpbnN0YW5jZW9mIEwudnQpe0ouZFIobikuaSgwLCJkaXIiKQpuLnNldEF0dHJpYnV0ZSgiZGF0
-YS0iK25ldyBXLlN5KG5ldyBXLmk3KG4pKS5PKCJuYW1lIiksby5jKQptPWQuY3JlYXRlRWxlbWVudCgi
-c3BhbiIpCm4uYXBwZW5kQ2hpbGQobSkKbD1KLllFKG0pCmwuZ0QobSkuaSgwLCJhcnJvdyIpCmwuc2hm
-KG0sIiYjeDI1QkM7IikKaz1kLmNyZWF0ZUVsZW1lbnQoInNwYW4iKQpKLmRSKGspLmkoMCxlKQprLmlu
-bmVyVGV4dD0iZm9sZGVyX29wZW4iCm4uYXBwZW5kQ2hpbGQoaykKbi5hcHBlbmRDaGlsZChkLmNyZWF0
-ZVRleHROb2RlKG8uYSkpCkwudFgobixvLmQsITEpCkwua3oobSl9ZWxzZSBpZihvIGluc3RhbmNlb2Yg
-TC5jRCl7bD1kLmNyZWF0ZUVsZW1lbnQoInNwYW4iKQpKLmRSKGwpLmkoMCxlKQpsLmlubmVyVGV4dD0i
-aW5zZXJ0X2RyaXZlX2ZpbGUiCm4uYXBwZW5kQ2hpbGQobCkKaj1kLmNyZWF0ZUVsZW1lbnQoImEiKQpu
-LmFwcGVuZENoaWxkKGopCmw9Si5ZRShqKQpsLmdEKGopLmkoMCwibmF2LWxpbmsiKQpqLnNldEF0dHJp
-YnV0ZSgiZGF0YS0iK25ldyBXLlN5KG5ldyBXLmk3KGopKS5PKCJuYW1lIiksby5jKQpqLnNldEF0dHJp
-YnV0ZSgiaHJlZiIsTC5RNChvLmQsUC5GbChyLHIpKSkKai5hcHBlbmRDaGlsZChkLmNyZWF0ZVRleHRO
-b2RlKG8uYSkpCmw9bC5nVmwoaikKaT1sLiR0aQpoPWkuQygifigxKT8iKS5hKG5ldyBMLlREKCkpCnEu
-YShudWxsKQpXLkpFKGwuYSxsLmIsaCwhMSxpLmMpCmc9by5lCmlmKHR5cGVvZiBnIT09Im51bWJlciIp
-cmV0dXJuIGcub3MoKQppZihnPjApe2Y9ZC5jcmVhdGVFbGVtZW50KCJzcGFuIikKbi5hcHBlbmRDaGls
-ZChmKQpKLmRSKGYpLmkoMCwiZWRpdC1jb3VudCIpCmw9IiIrZysiICIKaWYoZz09PTEpaT0icHJvcG9z
-ZWQgZWRpdCIKZWxzZSBpPSJwcm9wb3NlZCBlZGl0cyIKZi5zZXRBdHRyaWJ1dGUoInRpdGxlIixsK2kp
-CmYuYXBwZW5kQ2hpbGQoZC5jcmVhdGVUZXh0Tm9kZShDLmpuLncoZykpKX19fX0sCnV6OmZ1bmN0aW9u
-KGEsYixjKXt2YXIgcz1kb2N1bWVudCxyPXMuY3JlYXRlRWxlbWVudCgiYnV0dG9uIikscT10LmsscD1x
-LkMoIn4oMSk/IikuYShuZXcgTC5tMihhLGMpKQp0LlouYShudWxsKQpXLkpFKHIsImNsaWNrIixwLCEx
-LHEuYykKci5hcHBlbmRDaGlsZChzLmNyZWF0ZVRleHROb2RlKE0uT1goYS5hKSkpCmIuYXBwZW5kQ2hp
-bGQocil9LApGejpmdW5jdGlvbihhLGIpe3ZhciBzLHIscSxwLG8sbixtLGwsayxqLGksaD1hLmEKaWYo
-aD09bnVsbClyZXR1cm4Kcz1kb2N1bWVudApyPXMuY3JlYXRlRWxlbWVudCgicCIpCnE9Yi5hcHBlbmRD
-aGlsZChyKQpyPXMuY3JlYXRlRWxlbWVudCgic3BhbiIpCnA9dC5pCkouTXUocixILlZNKFsidHlwZS1k
-ZXNjcmlwdGlvbiJdLHApKQpyLmFwcGVuZENoaWxkKHMuY3JlYXRlVGV4dE5vZGUoIkFjdGlvbnMiKSkK
-cS5hcHBlbmRDaGlsZChyKQpxLmFwcGVuZENoaWxkKHMuY3JlYXRlVGV4dE5vZGUoIjoiKSkKbz1zLmNy
-ZWF0ZUVsZW1lbnQoInAiKQpiLmFwcGVuZENoaWxkKG8pCmZvcihyPWgubGVuZ3RoLG49dC5RLG09MDtt
-PGgubGVuZ3RoO2gubGVuZ3RoPT09cnx8KDAsSC5saykoaCksKyttKXtsPWhbbV0Kaz1zLmNyZWF0ZUVs
-ZW1lbnQoImEiKQpvLmFwcGVuZENoaWxkKGspCmsuYXBwZW5kQ2hpbGQocy5jcmVhdGVUZXh0Tm9kZShs
-LmEpKQprLnNldEF0dHJpYnV0ZSgiaHJlZiIsbC5iKQpqPW4uYShILlZNKFsiYWRkLWhpbnQtbGluayIs
-ImJlZm9yZS1hcHBseSIsImJ1dHRvbiJdLHApKQppPUouZFIoaykKaS5WMSgwKQppLkZWKDAsail9fSwK
-Q0M6ZnVuY3Rpb24oYTQsYTUsYTYpe3ZhciBzLHIscSxwLG8sbixtLGwsayxqLGksaCxnLGYsZSxkLGMs
-YixhLGEwLGExLGEyLGEzCmZvcihzPWE0LmYscj1zLmxlbmd0aCxxPXQuaSxwPXQuUSxvPTA7bzxzLmxl
-bmd0aDtzLmxlbmd0aD09PXJ8fCgwLEgubGspKHMpLCsrbyl7bj1zW29dCm09ZG9jdW1lbnQKbD1tLmNy
-ZWF0ZUVsZW1lbnQoInAiKQprPXAuYShILlZNKFsidHJhY2UiXSxxKSkKaj1KLmRSKGwpCmouVjEoMCkK
-ai5GVigwLGspCmk9YTUuYXBwZW5kQ2hpbGQobCkKbD1tLmNyZWF0ZUVsZW1lbnQoInNwYW4iKQprPXAu
-YShILlZNKFsidHlwZS1kZXNjcmlwdGlvbiJdLHEpKQpqPUouZFIobCkKai5WMSgwKQpqLkZWKDAsaykK
-bC5hcHBlbmRDaGlsZChtLmNyZWF0ZVRleHROb2RlKG4uYSkpCmkuYXBwZW5kQ2hpbGQobCkKaS5hcHBl
-bmRDaGlsZChtLmNyZWF0ZVRleHROb2RlKCI6IikpCmw9bS5jcmVhdGVFbGVtZW50KCJ1bCIpCms9cC5h
-KEguVk0oWyJ0cmFjZSJdLHEpKQpqPUouZFIobCkKai5WMSgwKQpqLkZWKDAsaykKaD1pLmFwcGVuZENo
-aWxkKGwpCmZvcihsPW4uYixrPWwubGVuZ3RoLGc9MDtnPGwubGVuZ3RoO2wubGVuZ3RoPT09a3x8KDAs
-SC5saykobCksKytnKXtmPWxbZ10KZT1tLmNyZWF0ZUVsZW1lbnQoImxpIikKaC5hcHBlbmRDaGlsZChl
-KQpkPW0uY3JlYXRlRWxlbWVudCgic3BhbiIpCmM9cC5hKEguVk0oWyJmdW5jdGlvbiJdLHEpKQpqPUou
-ZFIoZCkKai5WMSgwKQpqLkZWKDAsYykKYz1mLmIKTC5rRChkLGM9PW51bGw/InVua25vd24iOmMpCmUu
-YXBwZW5kQ2hpbGQoZCkKYj1mLmMKaWYoYiE9bnVsbCl7ZS5hcHBlbmRDaGlsZChtLmNyZWF0ZVRleHRO
-b2RlKCIgKCIpKQphPWIuYgphMD1tLmNyZWF0ZUVsZW1lbnQoImEiKQphMC5hcHBlbmRDaGlsZChtLmNy
-ZWF0ZVRleHROb2RlKEguRWooYi5jKSsiOiIrSC5FaihhKSkpCmEwLnNldEF0dHJpYnV0ZSgiaHJlZiIs
-Yi5hKQphMC5jbGFzc0xpc3QuYWRkKCJuYXYtbGluayIpCmUuYXBwZW5kQ2hpbGQoYTApCmUuYXBwZW5k
-Q2hpbGQobS5jcmVhdGVUZXh0Tm9kZSgiKSIpKX1lLmFwcGVuZENoaWxkKG0uY3JlYXRlVGV4dE5vZGUo
-IjogIikpCmQ9Zi5hCkwua0QoZSxkPT1udWxsPyJ1bmtub3duIjpkKQpkPWYuZAppZihkLmxlbmd0aCE9
-PTApe2M9bS5jcmVhdGVFbGVtZW50KCJwIikKYTE9cC5hKEguVk0oWyJkcmF3ZXIiLCJiZWZvcmUtYXBw
-bHkiXSxxKSkKaj1KLmRSKGMpCmouVjEoMCkKai5GVigwLGExKQphMj1lLmFwcGVuZENoaWxkKGMpCmZv
-cihjPWQubGVuZ3RoLGEzPTA7YTM8ZC5sZW5ndGg7ZC5sZW5ndGg9PT1jfHwoMCxILmxrKShkKSwrK2Ez
-KUwudXooZFthM10sYTIsYil9fX19LApVczpmdW5jdGlvbihhKXtyZXR1cm4gSi5VNihhKS50ZyhhLCI/
-Iik/Qy54Qi5OaihhLDAsQy54Qi5PWShhLCI/IikpOmF9LAprRDpmdW5jdGlvbihhLGIpe3ZhciBzLHIs
-cT1ILlZNKGIuc3BsaXQoIi4iKSx0LnMpLHA9Qy5ObS5ndEgocSksbz1kb2N1bWVudAphLmFwcGVuZENo
-aWxkKG8uY3JlYXRlVGV4dE5vZGUocCkpCmZvcihwPUgucUMocSwxLG51bGwsdC5OKSxwPW5ldyBILmE3
-KHAscC5nQShwKSxwLiR0aS5DKCJhNzxhTC5FPiIpKSxzPUouWUUoYSk7cC5GKCk7KXtyPXAuZApzLm56
-KGEsImJlZm9yZWVuZCIsIiYjODIwMzsuIixudWxsLG51bGwpCmEuYXBwZW5kQ2hpbGQoby5jcmVhdGVU
-ZXh0Tm9kZShyKSl9fSwKZTpmdW5jdGlvbiBlKCl7fSwKVlc6ZnVuY3Rpb24gVlcoYSxiLGMpe3RoaXMu
-YT1hCnRoaXMuYj1iCnRoaXMuYz1jfSwKb1o6ZnVuY3Rpb24gb1ooKXt9LApqcjpmdW5jdGlvbiBqcigp
-e30sCnFsOmZ1bmN0aW9uIHFsKCl7fSwKSGk6ZnVuY3Rpb24gSGkoKXt9LApCVDpmdW5jdGlvbiBCVCgp
-e30sClBZOmZ1bmN0aW9uIFBZKCl7fSwKTDpmdW5jdGlvbiBMKCl7fSwKV3g6ZnVuY3Rpb24gV3goYSxi
-KXt0aGlzLmE9YQp0aGlzLmI9Yn0sCkFPOmZ1bmN0aW9uIEFPKGEpe3RoaXMuYT1hfSwKZE46ZnVuY3Rp
-b24gZE4oYSl7dGhpcy5hPWF9LApIbzpmdW5jdGlvbiBIbyhhKXt0aGlzLmE9YX0sCnh6OmZ1bmN0aW9u
-IHh6KGEsYil7dGhpcy5hPWEKdGhpcy5iPWJ9LApJQzpmdW5jdGlvbiBJQygpe30sCmZDOmZ1bmN0aW9u
-IGZDKGEsYil7dGhpcy5hPWEKdGhpcy5iPWJ9LApuVDpmdW5jdGlvbiBuVChhLGIsYyl7dGhpcy5hPWEK
-dGhpcy5iPWIKdGhpcy5jPWN9LApOWTpmdW5jdGlvbiBOWShhKXt0aGlzLmE9YX0sCnVlOmZ1bmN0aW9u
-IHVlKCl7fSwKZVg6ZnVuY3Rpb24gZVgoKXt9LApFRTpmdW5jdGlvbiBFRShhLGIsYyl7dGhpcy5hPWEK
-dGhpcy5iPWIKdGhpcy5jPWN9LApRTDpmdW5jdGlvbiBRTChhLGIpe3RoaXMuYT1hCnRoaXMuYj1ifSwK
-VlM6ZnVuY3Rpb24gVlMoYSl7dGhpcy5hPWF9LApURDpmdW5jdGlvbiBURCgpe30sCm0yOmZ1bmN0aW9u
-IG0yKGEsYil7dGhpcy5hPWEKdGhpcy5iPWJ9LApYQTpmdW5jdGlvbiBYQSgpe30sClpzOmZ1bmN0aW9u
-KGEpe3ZhciBzLHIscT1KLlU2KGEpCmlmKEwucDIoSC5oKHEucShhLCJ0eXBlIikpKT09PUMuWTIpe3M9
-SC5oKHEucShhLCJuYW1lIikpCnI9SC5oKHEucShhLCJwYXRoIikpCnE9cS5xKGEsInN1YnRyZWUiKQpx
-PW5ldyBMLnZ0KHE9PW51bGw/bnVsbDpMLm1LKHEpLHMscikKcS5MVigpCnJldHVybiBxfWVsc2V7cz1I
-LmgocS5xKGEsIm5hbWUiKSkKcj1ILmgocS5xKGEsInBhdGgiKSkKcmV0dXJuIG5ldyBMLmNEKEguaChx
-LnEoYSwiaHJlZiIpKSxILnVQKHEucShhLCJlZGl0Q291bnQiKSksSC55OChxLnEoYSwid2FzRXhwbGlj
-aXRseU9wdGVkT3V0IikpLEwudkIoSC51UChxLnEoYSwibWlncmF0aW9uU3RhdHVzIikpKSxzLHIpfX0s
-Cm1LOmZ1bmN0aW9uKGEpe3ZhciBzLHI9SC5WTShbXSx0LmNRKQpmb3Iocz1KLklUKHQuVS5hKGEpKTtz
-LkYoKTspci5wdXNoKEwuWnMocy5nbCgpKSkKcmV0dXJuIHJ9LApWRDpmdW5jdGlvbihhKXt2YXIgcyxy
-LHE9SC5WTShbXSx0LkcpCmZvcihzPWEubGVuZ3RoLHI9MDtyPGEubGVuZ3RoO2EubGVuZ3RoPT09c3x8
-KDAsSC5saykoYSksKytyKXEucHVzaChhW3JdLkx0KCkpCnJldHVybiBxfSwKdkI6ZnVuY3Rpb24oYSl7
-aWYoYT09bnVsbClyZXR1cm4gbnVsbAppZihhPj4+MCE9PWF8fGE+PTQpcmV0dXJuIEguT0goQy5sMCxh
-KQpyZXR1cm4gQy5sMFthXX0sCnAyOmZ1bmN0aW9uKGEpe3N3aXRjaChhKXtjYXNlImRpcmVjdG9yeSI6
-cmV0dXJuIEMuWTIKY2FzZSJmaWxlIjpyZXR1cm4gQy5yZgpkZWZhdWx0OnRocm93IEguYihQLlBWKCJV
-bnJlY29nbml6ZWQgbmF2aWdhdGlvbiB0cmVlIG5vZGUgdHlwZTogIitILkVqKGEpKSl9fSwKdnQ6ZnVu
-Y3Rpb24gdnQoYSxiLGMpe3ZhciBfPXRoaXMKXy5kPWEKXy5hPWIKXy5iPW51bGwKXy5jPWN9LApjRDpm
-dW5jdGlvbiBjRChhLGIsYyxkLGUsZil7dmFyIF89dGhpcwpfLmQ9YQpfLmU9YgpfLmY9YwpfLnI9ZApf
-LmE9ZQpfLmI9bnVsbApfLmM9Zn0sCkQ4OmZ1bmN0aW9uIEQ4KCl7fSwKTzk6ZnVuY3Rpb24gTzkoYSl7
-dGhpcy5iPWF9LApHYjpmdW5jdGlvbiBHYihhLGIpe3RoaXMuYT1hCnRoaXMuYj1ifSwKSVY6ZnVuY3Rp
-b24gSVYoYSxiLGMsZCl7dmFyIF89dGhpcwpfLmQ9YQpfLmU9YgpfLmY9YwpfLnI9ZH19LFg9ewpDTDpm
-dW5jdGlvbihhLGIpe3ZhciBzLHIscSxwLG8sbj1iLnhaKGEpCmIuaEsoYSkKaWYobiE9bnVsbClhPUou
-S1YoYSxuLmxlbmd0aCkKcz10LnMKcj1ILlZNKFtdLHMpCnE9SC5WTShbXSxzKQpzPWEubGVuZ3RoCmlm
-KHMhPT0wJiZiLnI0KEMueEIuVyhhLDApKSl7aWYoMD49cylyZXR1cm4gSC5PSChhLDApCkMuTm0uaShx
-LGFbMF0pCnA9MX1lbHNle0MuTm0uaShxLCIiKQpwPTB9Zm9yKG89cDtvPHM7KytvKWlmKGIucjQoQy54
-Qi5XKGEsbykpKXtDLk5tLmkocixDLnhCLk5qKGEscCxvKSkKQy5ObS5pKHEsYVtvXSkKcD1vKzF9aWYo
-cDxzKXtDLk5tLmkocixDLnhCLkcoYSxwKSkKQy5ObS5pKHEsIiIpfXJldHVybiBuZXcgWC5XRChiLG4s
-cixxKX0sCldEOmZ1bmN0aW9uIFdEKGEsYixjLGQpe3ZhciBfPXRoaXMKXy5hPWEKXy5iPWIKXy5kPWMK
-Xy5lPWR9LApJNzpmdW5jdGlvbihhKXtyZXR1cm4gbmV3IFguZHYoYSl9LApkdjpmdW5jdGlvbiBkdihh
-KXt0aGlzLmE9YX19LE89ewpSaDpmdW5jdGlvbigpe3ZhciBzLHI9bnVsbAppZihQLnVvKCkuZ0ZpKCkh
-PT0iZmlsZSIpcmV0dXJuICQuRWIoKQpzPVAudW8oKQppZighQy54Qi5UYyhzLmdJaShzKSwiLyIpKXJl
-dHVybiAkLkViKCkKaWYoUC5LTChyLCJhL2IiLHIscixyLHIscikudDQoKT09PSJhXFxiIilyZXR1cm4g
-JC5LaygpCnJldHVybiAkLmJEKCl9LAp6TDpmdW5jdGlvbiB6TCgpe319LEU9e09GOmZ1bmN0aW9uIE9G
-KGEsYixjKXt0aGlzLmQ9YQp0aGlzLmU9Ygp0aGlzLmY9Y319LEY9e3J1OmZ1bmN0aW9uIHJ1KGEsYixj
-LGQpe3ZhciBfPXRoaXMKXy5kPWEKXy5lPWIKXy5mPWMKXy5yPWR9fSxEPXsKYWI6ZnVuY3Rpb24oKXt2
-YXIgcyxyLHEscCxvPW51bGwKdHJ5e289UC51bygpfWNhdGNoKHMpe2lmKHQuZzguYihILlJ1KHMpKSl7
-cj0kLkZmCmlmKHIhPW51bGwpcmV0dXJuIHIKdGhyb3cgc31lbHNlIHRocm93IHN9aWYoSi5STShvLCQu
-STYpKXtyPSQuRmYKci50b1N0cmluZwpyZXR1cm4gcn0kLkk2PW8KaWYoJC5IaygpPT0kLkViKCkpcj0k
-LkZmPW8uWkkoIi4iKS53KDApCmVsc2V7cT1vLnQ0KCkKcD1xLmxlbmd0aC0xCnI9JC5GZj1wPT09MD9x
-OkMueEIuTmoocSwwLHApfXIudG9TdHJpbmcKcmV0dXJuIHJ9fQp2YXIgdz1bQyxILEosUCxXLE0sVSxC
-LFQsTCxYLE8sRSxGLERdCmh1bmtIZWxwZXJzLnNldEZ1bmN0aW9uTmFtZXNJZk5lY2Vzc2FyeSh3KQp2
-YXIgJD17fQpILkZLLnByb3RvdHlwZT17fQpKLkd2LnByb3RvdHlwZT17CkROOmZ1bmN0aW9uKGEsYil7
-cmV0dXJuIGE9PT1ifSwKZ2lPOmZ1bmN0aW9uKGEpe3JldHVybiBILmVRKGEpfSwKdzpmdW5jdGlvbihh
-KXtyZXR1cm4iSW5zdGFuY2Ugb2YgJyIrSC5FaihILk0oYSkpKyInIn0sCmU3OmZ1bmN0aW9uKGEsYil7
-dC5vLmEoYikKdGhyb3cgSC5iKFAubHIoYSxiLmdXYSgpLGIuZ25kKCksYi5nVm0oKSkpfX0KSi55RS5w
-cm90b3R5cGU9ewp3OmZ1bmN0aW9uKGEpe3JldHVybiBTdHJpbmcoYSl9LApnaU86ZnVuY3Rpb24oYSl7
-cmV0dXJuIGE/NTE5MDE4OjIxODE1OX0sCiRpYTI6MX0KSi53ZS5wcm90b3R5cGU9ewpETjpmdW5jdGlv
-bihhLGIpe3JldHVybiBudWxsPT1ifSwKdzpmdW5jdGlvbihhKXtyZXR1cm4ibnVsbCJ9LApnaU86ZnVu
-Y3Rpb24oYSl7cmV0dXJuIDB9LAplNzpmdW5jdGlvbihhLGIpe3JldHVybiB0aGlzLlNqKGEsdC5vLmEo
-YikpfSwKJGljODoxfQpKLk1GLnByb3RvdHlwZT17CmdpTzpmdW5jdGlvbihhKXtyZXR1cm4gMH0sCnc6
-ZnVuY3Rpb24oYSl7cmV0dXJuIFN0cmluZyhhKX0sCiRpdm06MX0KSi5pQy5wcm90b3R5cGU9e30KSi5r
-ZC5wcm90b3R5cGU9e30KSi5jNS5wcm90b3R5cGU9ewp3OmZ1bmN0aW9uKGEpe3ZhciBzPWFbJC53KCld
-CmlmKHM9PW51bGwpcmV0dXJuIHRoaXMudChhKQpyZXR1cm4iSmF2YVNjcmlwdCBmdW5jdGlvbiBmb3Ig
-IitILkVqKEouaihzKSl9LAokaUVIOjF9CkouamQucHJvdG90eXBlPXsKZHI6ZnVuY3Rpb24oYSxiKXty
-ZXR1cm4gbmV3IEgualYoYSxILnQ2KGEpLkMoIkA8MT4iKS5LcShiKS5DKCJqVjwxLDI+IikpfSwKaTpm
-dW5jdGlvbihhLGIpe0gudDYoYSkuYy5hKGIpCmlmKCEhYS5maXhlZCRsZW5ndGgpSC52KFAuTDQoImFk
-ZCIpKQphLnB1c2goYil9LApXNDpmdW5jdGlvbihhLGIpe3ZhciBzCmlmKCEhYS5maXhlZCRsZW5ndGgp
-SC52KFAuTDQoInJlbW92ZUF0IikpCnM9YS5sZW5ndGgKaWYoYj49cyl0aHJvdyBILmIoUC5PNyhiLG51
-bGwpKQpyZXR1cm4gYS5zcGxpY2UoYiwxKVswXX0sClVHOmZ1bmN0aW9uKGEsYixjKXt2YXIgcyxyCkgu
-dDYoYSkuQygiY1g8MT4iKS5hKGMpCmlmKCEhYS5maXhlZCRsZW5ndGgpSC52KFAuTDQoImluc2VydEFs
-bCIpKQpQLndBKGIsMCxhLmxlbmd0aCwiaW5kZXgiKQppZighdC5iLmIoYykpYz1KLlJYKGMpCnM9Si5I
-bShjKQphLmxlbmd0aD1hLmxlbmd0aCtzCnI9YitzCnRoaXMuWVcoYSxyLGEubGVuZ3RoLGEsYikKdGhp
-cy52ZyhhLGIscixjKX0sCkZWOmZ1bmN0aW9uKGEsYil7dmFyIHMKSC50NihhKS5DKCJjWDwxPiIpLmEo
-YikKaWYoISFhLmZpeGVkJGxlbmd0aClILnYoUC5MNCgiYWRkQWxsIikpCmZvcihzPUouSVQoYik7cy5G
-KCk7KWEucHVzaChzLmdsKCkpfSwKRTI6ZnVuY3Rpb24oYSxiLGMpe3ZhciBzPUgudDYoYSkKcmV0dXJu
-IG5ldyBILmxKKGEscy5LcShjKS5DKCIxKDIpIikuYShiKSxzLkMoIkA8MT4iKS5LcShjKS5DKCJsSjwx
-LDI+IikpfSwKSDpmdW5jdGlvbihhLGIpe3ZhciBzLHI9UC5POChhLmxlbmd0aCwiIiwhMSx0Lk4pCmZv
-cihzPTA7czxhLmxlbmd0aDsrK3MpdGhpcy5ZKHIscyxILkVqKGFbc10pKQpyZXR1cm4gci5qb2luKGIp
-fSwKZVI6ZnVuY3Rpb24oYSxiKXtyZXR1cm4gSC5xQyhhLGIsbnVsbCxILnQ2KGEpLmMpfSwKTjA6ZnVu
-Y3Rpb24oYSxiLGMsZCl7dmFyIHMscixxCmQuYShiKQpILnQ2KGEpLktxKGQpLkMoIjEoMSwyKSIpLmEo
-YykKcz1hLmxlbmd0aApmb3Iocj1iLHE9MDtxPHM7KytxKXtyPWMuJDIocixhW3FdKQppZihhLmxlbmd0
-aCE9PXMpdGhyb3cgSC5iKFAuYTQoYSkpfXJldHVybiByfSwKSHQ6ZnVuY3Rpb24oYSxiKXt2YXIgcyxy
-LHEscCxvCkgudDYoYSkuQygiYTIoMSkiKS5hKGIpCnM9YS5sZW5ndGgKZm9yKHI9bnVsbCxxPSExLHA9
-MDtwPHM7KytwKXtvPWFbcF0KaWYoSC5vVChiLiQxKG8pKSl7aWYocSl0aHJvdyBILmIoSC5BbSgpKQpy
-PW8KcT0hMH1pZihzIT09YS5sZW5ndGgpdGhyb3cgSC5iKFAuYTQoYSkpfWlmKHEpcmV0dXJuIHIKdGhy
-b3cgSC5iKEguV3AoKSl9LApFOmZ1bmN0aW9uKGEsYil7aWYoYjwwfHxiPj1hLmxlbmd0aClyZXR1cm4g
-SC5PSChhLGIpCnJldHVybiBhW2JdfSwKZ3RIOmZ1bmN0aW9uKGEpe2lmKGEubGVuZ3RoPjApcmV0dXJu
-IGFbMF0KdGhyb3cgSC5iKEguV3AoKSl9LApnclo6ZnVuY3Rpb24oYSl7dmFyIHM9YS5sZW5ndGgKaWYo
-cz4wKXJldHVybiBhW3MtMV0KdGhyb3cgSC5iKEguV3AoKSl9LApZVzpmdW5jdGlvbihhLGIsYyxkLGUp
-e3ZhciBzLHIscSxwLG8KSC50NihhKS5DKCJjWDwxPiIpLmEoZCkKaWYoISFhLmltbXV0YWJsZSRsaXN0
-KUgudihQLkw0KCJzZXRSYW5nZSIpKQpQLmpCKGIsYyxhLmxlbmd0aCkKcz1jLWIKaWYocz09PTApcmV0
-dXJuClAuazEoZSwic2tpcENvdW50IikKaWYodC5qLmIoZCkpe3I9ZApxPWV9ZWxzZXtyPUouQTUoZCxl
-KS50dCgwLCExKQpxPTB9cD1KLlU2KHIpCmlmKHErcz5wLmdBKHIpKXRocm93IEguYihILmFyKCkpCmlm
-KHE8Yilmb3Iobz1zLTE7bz49MDstLW8pYVtiK29dPXAucShyLHErbykKZWxzZSBmb3Iobz0wO288czsr
-K28pYVtiK29dPXAucShyLHErbyl9LAp2ZzpmdW5jdGlvbihhLGIsYyxkKXtyZXR1cm4gdGhpcy5ZVyhh
-LGIsYyxkLDApfSwKVnI6ZnVuY3Rpb24oYSxiKXt2YXIgcyxyCkgudDYoYSkuQygiYTIoMSkiKS5hKGIp
-CnM9YS5sZW5ndGgKZm9yKHI9MDtyPHM7KytyKXtpZihILm9UKGIuJDEoYVtyXSkpKXJldHVybiEwCmlm
-KGEubGVuZ3RoIT09cyl0aHJvdyBILmIoUC5hNChhKSl9cmV0dXJuITF9LAp0ZzpmdW5jdGlvbihhLGIp
-e3ZhciBzCmZvcihzPTA7czxhLmxlbmd0aDsrK3MpaWYoSi5STShhW3NdLGIpKXJldHVybiEwCnJldHVy
-biExfSwKZ2wwOmZ1bmN0aW9uKGEpe3JldHVybiBhLmxlbmd0aD09PTB9LApnb3I6ZnVuY3Rpb24oYSl7
-cmV0dXJuIGEubGVuZ3RoIT09MH0sCnc6ZnVuY3Rpb24oYSl7cmV0dXJuIFAuV0UoYSwiWyIsIl0iKX0s
-CnR0OmZ1bmN0aW9uKGEsYil7dmFyIHM9SC5WTShhLnNsaWNlKDApLEgudDYoYSkpCnJldHVybiBzfSwK
-YnI6ZnVuY3Rpb24oYSl7cmV0dXJuIHRoaXMudHQoYSwhMCl9LApnbTpmdW5jdGlvbihhKXtyZXR1cm4g
-bmV3IEoubTEoYSxhLmxlbmd0aCxILnQ2KGEpLkMoIm0xPDE+IikpfSwKZ2lPOmZ1bmN0aW9uKGEpe3Jl
-dHVybiBILmVRKGEpfSwKZ0E6ZnVuY3Rpb24oYSl7cmV0dXJuIGEubGVuZ3RofSwKc0E6ZnVuY3Rpb24o
-YSxiKXtpZighIWEuZml4ZWQkbGVuZ3RoKUgudihQLkw0KCJzZXQgbGVuZ3RoIikpCmlmKGI8MCl0aHJv
-dyBILmIoUC5URShiLDAsbnVsbCwibmV3TGVuZ3RoIixudWxsKSkKYS5sZW5ndGg9Yn0sCnE6ZnVuY3Rp
-b24oYSxiKXtILnVQKGIpCmlmKGI+PWEubGVuZ3RofHxiPDApdGhyb3cgSC5iKEguSFkoYSxiKSkKcmV0
-dXJuIGFbYl19LApZOmZ1bmN0aW9uKGEsYixjKXtILnQ2KGEpLmMuYShjKQppZighIWEuaW1tdXRhYmxl
-JGxpc3QpSC52KFAuTDQoImluZGV4ZWQgc2V0IikpCmlmKGI+PWEubGVuZ3RofHxiPDApdGhyb3cgSC5i
-KEguSFkoYSxiKSkKYVtiXT1jfSwKJGliUToxLAokaWNYOjEsCiRpek06MX0KSi5Qby5wcm90b3R5cGU9
-e30KSi5tMS5wcm90b3R5cGU9ewpnbDpmdW5jdGlvbigpe3JldHVybiB0aGlzLmR9LApGOmZ1bmN0aW9u
-KCl7dmFyIHMscj10aGlzLHE9ci5hLHA9cS5sZW5ndGgKaWYoci5iIT09cCl0aHJvdyBILmIoSC5sayhx
-KSkKcz1yLmMKaWYocz49cCl7ci5zTShudWxsKQpyZXR1cm4hMX1yLnNNKHFbc10pOysrci5jCnJldHVy
-biEwfSwKc006ZnVuY3Rpb24oYSl7dGhpcy5kPXRoaXMuJHRpLkMoIjE/IikuYShhKX0sCiRpQW46MX0K
-Si5xSS5wcm90b3R5cGU9ewp6UTpmdW5jdGlvbihhKXtpZihhPjApe2lmKGEhPT0xLzApcmV0dXJuIE1h
-dGgucm91bmQoYSl9ZWxzZSBpZihhPi0xLzApcmV0dXJuIDAtTWF0aC5yb3VuZCgwLWEpCnRocm93IEgu
-YihQLkw0KCIiK2ErIi5yb3VuZCgpIikpfSwKdzpmdW5jdGlvbihhKXtpZihhPT09MCYmMS9hPDApcmV0
-dXJuIi0wLjAiCmVsc2UgcmV0dXJuIiIrYX0sCmdpTzpmdW5jdGlvbihhKXt2YXIgcyxyLHEscCxvPWF8
-MAppZihhPT09bylyZXR1cm4gbyY1MzY4NzA5MTEKcz1NYXRoLmFicyhhKQpyPU1hdGgubG9nKHMpLzAu
-NjkzMTQ3MTgwNTU5OTQ1M3wwCnE9TWF0aC5wb3coMixyKQpwPXM8MT9zL3E6cS9zCnJldHVybigocCo5
-MDA3MTk5MjU0NzQwOTkyfDApKyhwKjM1NDIyNDMxODExNzY1MjF8MCkpKjU5OTE5NytyKjEyNTkmNTM2
-ODcwOTExfSwKelk6ZnVuY3Rpb24oYSxiKXt2YXIgcz1hJWIKaWYocz09PTApcmV0dXJuIDAKaWYocz4w
-KXJldHVybiBzCmlmKGI8MClyZXR1cm4gcy1iCmVsc2UgcmV0dXJuIHMrYn0sCkJVOmZ1bmN0aW9uKGEs
-Yil7cmV0dXJuKGF8MCk9PT1hP2EvYnwwOnRoaXMuREooYSxiKX0sCkRKOmZ1bmN0aW9uKGEsYil7dmFy
-IHM9YS9iCmlmKHM+PS0yMTQ3NDgzNjQ4JiZzPD0yMTQ3NDgzNjQ3KXJldHVybiBzfDAKaWYocz4wKXtp
-ZihzIT09MS8wKXJldHVybiBNYXRoLmZsb29yKHMpfWVsc2UgaWYocz4tMS8wKXJldHVybiBNYXRoLmNl
-aWwocykKdGhyb3cgSC5iKFAuTDQoIlJlc3VsdCBvZiB0cnVuY2F0aW5nIGRpdmlzaW9uIGlzICIrSC5F
-aihzKSsiOiAiK0guRWooYSkrIiB+LyAiK2IpKX0sCndHOmZ1bmN0aW9uKGEsYil7dmFyIHMKaWYoYT4w
-KXM9dGhpcy5wMyhhLGIpCmVsc2V7cz1iPjMxPzMxOmIKcz1hPj5zPj4+MH1yZXR1cm4gc30sCmJmOmZ1
-bmN0aW9uKGEsYil7aWYoYjwwKXRocm93IEguYihILnRMKGIpKQpyZXR1cm4gdGhpcy5wMyhhLGIpfSwK
-cDM6ZnVuY3Rpb24oYSxiKXtyZXR1cm4gYj4zMT8wOmE+Pj5ifSwKJGlDUDoxLAokaVpaOjF9CkouYlUu
-cHJvdG90eXBlPXskaUlmOjF9CkouVkEucHJvdG90eXBlPXt9CkouRHIucHJvdG90eXBlPXsKTzI6ZnVu
-Y3Rpb24oYSxiKXtpZihiPDApdGhyb3cgSC5iKEguSFkoYSxiKSkKaWYoYj49YS5sZW5ndGgpSC52KEgu
-SFkoYSxiKSkKcmV0dXJuIGEuY2hhckNvZGVBdChiKX0sClc6ZnVuY3Rpb24oYSxiKXtpZihiPj1hLmxl
-bmd0aCl0aHJvdyBILmIoSC5IWShhLGIpKQpyZXR1cm4gYS5jaGFyQ29kZUF0KGIpfSwKZGQ6ZnVuY3Rp
-b24oYSxiKXtyZXR1cm4gbmV3IEgudW4oYixhLDApfSwKaDpmdW5jdGlvbihhLGIpe2lmKHR5cGVvZiBi
-IT0ic3RyaW5nIil0aHJvdyBILmIoUC5MMyhiLG51bGwsbnVsbCkpCnJldHVybiBhK2J9LApUYzpmdW5j
-dGlvbihhLGIpe3ZhciBzPWIubGVuZ3RoLHI9YS5sZW5ndGgKaWYocz5yKXJldHVybiExCnJldHVybiBi
-PT09dGhpcy5HKGEsci1zKX0sCmk3OmZ1bmN0aW9uKGEsYixjLGQpe3ZhciBzPVAuakIoYixjLGEubGVu
-Z3RoKSxyPWEuc3Vic3RyaW5nKDAsYikscT1hLnN1YnN0cmluZyhzKQpyZXR1cm4gcitkK3F9LApRaTpm
-dW5jdGlvbihhLGIsYyl7dmFyIHMKaWYoYzwwfHxjPmEubGVuZ3RoKXRocm93IEguYihQLlRFKGMsMCxh
-Lmxlbmd0aCxudWxsLG51bGwpKQpzPWMrYi5sZW5ndGgKaWYocz5hLmxlbmd0aClyZXR1cm4hMQpyZXR1
-cm4gYj09PWEuc3Vic3RyaW5nKGMscyl9LApuOmZ1bmN0aW9uKGEsYil7cmV0dXJuIHRoaXMuUWkoYSxi
-LDApfSwKTmo6ZnVuY3Rpb24oYSxiLGMpe2lmKGM9PW51bGwpYz1hLmxlbmd0aAppZihiPDApdGhyb3cg
-SC5iKFAuTzcoYixudWxsKSkKaWYoYj5jKXRocm93IEguYihQLk83KGIsbnVsbCkpCmlmKGM+YS5sZW5n
-dGgpdGhyb3cgSC5iKFAuTzcoYyxudWxsKSkKcmV0dXJuIGEuc3Vic3RyaW5nKGIsYyl9LApHOmZ1bmN0
-aW9uKGEsYil7cmV0dXJuIHRoaXMuTmooYSxiLG51bGwpfSwKaGM6ZnVuY3Rpb24oYSl7cmV0dXJuIGEu
-dG9Mb3dlckNhc2UoKX0sCmJTOmZ1bmN0aW9uKGEpe3ZhciBzLHIscSxwPWEudHJpbSgpLG89cC5sZW5n
-dGgKaWYobz09PTApcmV0dXJuIHAKaWYodGhpcy5XKHAsMCk9PT0xMzMpe3M9Si5tbShwLDEpCmlmKHM9
-PT1vKXJldHVybiIifWVsc2Ugcz0wCnI9by0xCnE9dGhpcy5PMihwLHIpPT09MTMzP0ouYzEocCxyKTpv
-CmlmKHM9PT0wJiZxPT09bylyZXR1cm4gcApyZXR1cm4gcC5zdWJzdHJpbmcocyxxKX0sCkl4OmZ1bmN0
-aW9uKGEsYil7dmFyIHMscgppZigwPj1iKXJldHVybiIiCmlmKGI9PT0xfHxhLmxlbmd0aD09PTApcmV0
-dXJuIGEKaWYoYiE9PWI+Pj4wKXRocm93IEguYihDLkVxKQpmb3Iocz1hLHI9IiI7ITA7KXtpZigoYiYx
-KT09PTEpcj1zK3IKYj1iPj4+MQppZihiPT09MClicmVhawpzKz1zfXJldHVybiByfSwKWFU6ZnVuY3Rp
-b24oYSxiLGMpe3ZhciBzCmlmKGM8MHx8Yz5hLmxlbmd0aCl0aHJvdyBILmIoUC5URShjLDAsYS5sZW5n
-dGgsbnVsbCxudWxsKSkKcz1hLmluZGV4T2YoYixjKQpyZXR1cm4gc30sCk9ZOmZ1bmN0aW9uKGEsYil7
-cmV0dXJuIHRoaXMuWFUoYSxiLDApfSwKUGs6ZnVuY3Rpb24oYSxiLGMpe3ZhciBzLHIKaWYoYz09bnVs
-bCljPWEubGVuZ3RoCmVsc2UgaWYoYzwwfHxjPmEubGVuZ3RoKXRocm93IEguYihQLlRFKGMsMCxhLmxl
-bmd0aCxudWxsLG51bGwpKQpzPWIubGVuZ3RoCnI9YS5sZW5ndGgKaWYoYytzPnIpYz1yLXMKcmV0dXJu
-IGEubGFzdEluZGV4T2YoYixjKX0sCmNuOmZ1bmN0aW9uKGEsYil7cmV0dXJuIHRoaXMuUGsoYSxiLG51
-bGwpfSwKSXM6ZnVuY3Rpb24oYSxiLGMpe3ZhciBzPWEubGVuZ3RoCmlmKGM+cyl0aHJvdyBILmIoUC5U
-RShjLDAscyxudWxsLG51bGwpKQpyZXR1cm4gSC5TUShhLGIsYyl9LAp0ZzpmdW5jdGlvbihhLGIpe3Jl
-dHVybiB0aGlzLklzKGEsYiwwKX0sCnc6ZnVuY3Rpb24oYSl7cmV0dXJuIGF9LApnaU86ZnVuY3Rpb24o
-YSl7dmFyIHMscixxCmZvcihzPWEubGVuZ3RoLHI9MCxxPTA7cTxzOysrcSl7cj1yK2EuY2hhckNvZGVB
-dChxKSY1MzY4NzA5MTEKcj1yKygociY1MjQyODcpPDwxMCkmNTM2ODcwOTExCnJePXI+PjZ9cj1yKygo
-ciY2NzEwODg2Myk8PDMpJjUzNjg3MDkxMQpyXj1yPj4xMQpyZXR1cm4gcisoKHImMTYzODMpPDwxNSkm
-NTM2ODcwOTExfSwKZ0E6ZnVuY3Rpb24oYSl7cmV0dXJuIGEubGVuZ3RofSwKcTpmdW5jdGlvbihhLGIp
-e0gudVAoYikKaWYoYj49YS5sZW5ndGh8fCExKXRocm93IEguYihILkhZKGEsYikpCnJldHVybiBhW2Jd
-fSwKJGl2WDoxLAokaXFVOjF9CkguQlIucHJvdG90eXBlPXsKZ206ZnVuY3Rpb24oYSl7dmFyIHM9SC5M
-aCh0aGlzKQpyZXR1cm4gbmV3IEguRTcoSi5JVCh0aGlzLmdPTigpKSxzLkMoIkA8MT4iKS5LcShzLlFb
-MV0pLkMoIkU3PDEsMj4iKSl9LApnQTpmdW5jdGlvbihhKXtyZXR1cm4gSi5IbSh0aGlzLmdPTigpKX0s
-CmdsMDpmdW5jdGlvbihhKXtyZXR1cm4gSi51VSh0aGlzLmdPTigpKX0sCmdvcjpmdW5jdGlvbihhKXty
-ZXR1cm4gSi5GNyh0aGlzLmdPTigpKX0sCmVSOmZ1bmN0aW9uKGEsYil7dmFyIHM9SC5MaCh0aGlzKQpy
-ZXR1cm4gSC5HSihKLkE1KHRoaXMuZ09OKCksYikscy5jLHMuUVsxXSl9LApFOmZ1bmN0aW9uKGEsYil7
-cmV0dXJuIEguTGgodGhpcykuUVsxXS5hKEouR0EodGhpcy5nT04oKSxiKSl9LAp3OmZ1bmN0aW9uKGEp
-e3JldHVybiBKLmoodGhpcy5nT04oKSl9fQpILkU3LnByb3RvdHlwZT17CkY6ZnVuY3Rpb24oKXtyZXR1
-cm4gdGhpcy5hLkYoKX0sCmdsOmZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMuJHRpLlFbMV0uYSh0aGlzLmEu
-Z2woKSl9LAokaUFuOjF9CkguWnkucHJvdG90eXBlPXsKZ09OOmZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMu
-YX19Ckgub2wucHJvdG90eXBlPXskaWJROjF9CkguVXEucHJvdG90eXBlPXsKcTpmdW5jdGlvbihhLGIp
-e3JldHVybiB0aGlzLiR0aS5RWzFdLmEoSi54OSh0aGlzLmEsSC51UChiKSkpfSwKWTpmdW5jdGlvbihh
-LGIsYyl7dmFyIHM9dGhpcy4kdGkKSi51OSh0aGlzLmEsYixzLmMuYShzLlFbMV0uYShjKSkpfSwKJGli
-UToxLAokaXpNOjF9CkgualYucHJvdG90eXBlPXsKZHI6ZnVuY3Rpb24oYSxiKXtyZXR1cm4gbmV3IEgu
-alYodGhpcy5hLHRoaXMuJHRpLkMoIkA8MT4iKS5LcShiKS5DKCJqVjwxLDI+IikpfSwKZ09OOmZ1bmN0
-aW9uKCl7cmV0dXJuIHRoaXMuYX19Ckgubi5wcm90b3R5cGU9ewp3OmZ1bmN0aW9uKGEpe3ZhciBzPXRo
-aXMuYQpyZXR1cm4gcyE9bnVsbD8iTGF0ZUluaXRpYWxpemF0aW9uRXJyb3I6ICIrczoiTGF0ZUluaXRp
-YWxpemF0aW9uRXJyb3IifX0KSC5yMy5wcm90b3R5cGU9ewp3OmZ1bmN0aW9uKGEpe3ZhciBzPSJSZWFj
-aGFiaWxpdHlFcnJvcjogIit0aGlzLmEKcmV0dXJuIHN9fQpILnFqLnByb3RvdHlwZT17CmdBOmZ1bmN0
-aW9uKGEpe3JldHVybiB0aGlzLmEubGVuZ3RofSwKcTpmdW5jdGlvbihhLGIpe3JldHVybiBDLnhCLk8y
-KHRoaXMuYSxILnVQKGIpKX19CkguR00ucHJvdG90eXBlPXsKdzpmdW5jdGlvbihhKXtyZXR1cm4iTnVs
-bCBpcyBub3QgYSB2YWxpZCB2YWx1ZSBmb3IgdGhlIHBhcmFtZXRlciAnIit0aGlzLmErIicgb2YgdHlw
-ZSAnIitILkt4KHRoaXMuJHRpLmMpLncoMCkrIicifX0KSC5iUS5wcm90b3R5cGU9e30KSC5hTC5wcm90
-b3R5cGU9ewpnbTpmdW5jdGlvbihhKXt2YXIgcz10aGlzCnJldHVybiBuZXcgSC5hNyhzLHMuZ0Eocyks
-SC5MaChzKS5DKCJhNzxhTC5FPiIpKX0sCmdsMDpmdW5jdGlvbihhKXtyZXR1cm4gdGhpcy5nQSh0aGlz
-KT09PTB9LApIOmZ1bmN0aW9uKGEsYil7dmFyIHMscixxLHA9dGhpcyxvPXAuZ0EocCkKaWYoYi5sZW5n
-dGghPT0wKXtpZihvPT09MClyZXR1cm4iIgpzPUguRWoocC5FKDAsMCkpCmlmKG8hPT1wLmdBKHApKXRo
-cm93IEguYihQLmE0KHApKQpmb3Iocj1zLHE9MTtxPG87KytxKXtyPXIrYitILkVqKHAuRSgwLHEpKQpp
-ZihvIT09cC5nQShwKSl0aHJvdyBILmIoUC5hNChwKSl9cmV0dXJuIHIuY2hhckNvZGVBdCgwKT09MD9y
-OnJ9ZWxzZXtmb3IocT0wLHI9IiI7cTxvOysrcSl7cis9SC5FaihwLkUoMCxxKSkKaWYobyE9PXAuZ0Eo
-cCkpdGhyb3cgSC5iKFAuYTQocCkpfXJldHVybiByLmNoYXJDb2RlQXQoMCk9PTA/cjpyfX0sCmV2OmZ1
-bmN0aW9uKGEsYil7cmV0dXJuIHRoaXMuR0coMCxILkxoKHRoaXMpLkMoImEyKGFMLkUpIikuYShiKSl9
-LApFMjpmdW5jdGlvbihhLGIsYyl7dmFyIHM9SC5MaCh0aGlzKQpyZXR1cm4gbmV3IEgubEoodGhpcyxz
-LktxKGMpLkMoIjEoYUwuRSkiKS5hKGIpLHMuQygiQDxhTC5FPiIpLktxKGMpLkMoImxKPDEsMj4iKSl9
-LAplUjpmdW5jdGlvbihhLGIpe3JldHVybiBILnFDKHRoaXMsYixudWxsLEguTGgodGhpcykuQygiYUwu
-RSIpKX0sCnR0OmZ1bmN0aW9uKGEsYil7cmV0dXJuIFAuWTEodGhpcywhMCxILkxoKHRoaXMpLkMoImFM
-LkUiKSl9LApicjpmdW5jdGlvbihhKXtyZXR1cm4gdGhpcy50dChhLCEwKX19CkgubkgucHJvdG90eXBl
-PXsKSGQ6ZnVuY3Rpb24oYSxiLGMsZCl7dmFyIHMscj10aGlzLmIKUC5rMShyLCJzdGFydCIpCnM9dGhp
-cy5jCmlmKHMhPW51bGwpe1AuazEocywiZW5kIikKaWYocj5zKXRocm93IEguYihQLlRFKHIsMCxzLCJz
-dGFydCIsbnVsbCkpfX0sCmdVRDpmdW5jdGlvbigpe3ZhciBzPUouSG0odGhpcy5hKSxyPXRoaXMuYwpp
-ZihyPT1udWxsfHxyPnMpcmV0dXJuIHMKcmV0dXJuIHJ9LApnQXM6ZnVuY3Rpb24oKXt2YXIgcz1KLkht
-KHRoaXMuYSkscj10aGlzLmIKaWYocj5zKXJldHVybiBzCnJldHVybiByfSwKZ0E6ZnVuY3Rpb24oYSl7
-dmFyIHMscj1KLkhtKHRoaXMuYSkscT10aGlzLmIKaWYocT49cilyZXR1cm4gMApzPXRoaXMuYwppZihz
-PT1udWxsfHxzPj1yKXJldHVybiByLXEKaWYodHlwZW9mIHMhPT0ibnVtYmVyIilyZXR1cm4gcy5ITigp
-CnJldHVybiBzLXF9LApFOmZ1bmN0aW9uKGEsYil7dmFyIHM9dGhpcyxyPXMuZ0FzKCkrYgppZihiPDB8
-fHI+PXMuZ1VEKCkpdGhyb3cgSC5iKFAuQ2YoYixzLCJpbmRleCIsbnVsbCxudWxsKSkKcmV0dXJuIEou
-R0Eocy5hLHIpfSwKZVI6ZnVuY3Rpb24oYSxiKXt2YXIgcyxyLHE9dGhpcwpQLmsxKGIsImNvdW50IikK
-cz1xLmIrYgpyPXEuYwppZihyIT1udWxsJiZzPj1yKXJldHVybiBuZXcgSC5NQihxLiR0aS5DKCJNQjwx
-PiIpKQpyZXR1cm4gSC5xQyhxLmEscyxyLHEuJHRpLmMpfSwKdHQ6ZnVuY3Rpb24oYSxiKXt2YXIgcyxy
-LHEscD10aGlzLG89cC5iLG49cC5hLG09Si5VNihuKSxsPW0uZ0Eobiksaz1wLmMKaWYoayE9bnVsbCYm
-azxsKWw9awppZih0eXBlb2YgbCE9PSJudW1iZXIiKXJldHVybiBsLkhOKCkKcz1sLW8KaWYoczw9MCl7
-bj1KLlFpKDAscC4kdGkuYykKcmV0dXJuIG59cj1QLk84KHMsbS5FKG4sbyksITEscC4kdGkuYykKZm9y
-KHE9MTtxPHM7KytxKXtDLk5tLlkocixxLG0uRShuLG8rcSkpCmlmKG0uZ0Eobik8bCl0aHJvdyBILmIo
-UC5hNChwKSl9cmV0dXJuIHJ9fQpILmE3LnByb3RvdHlwZT17CmdsOmZ1bmN0aW9uKCl7cmV0dXJuIHRo
-aXMuZH0sCkY6ZnVuY3Rpb24oKXt2YXIgcyxyPXRoaXMscT1yLmEscD1KLlU2KHEpLG89cC5nQShxKQpp
-ZihyLmIhPT1vKXRocm93IEguYihQLmE0KHEpKQpzPXIuYwppZihzPj1vKXtyLnNJKG51bGwpCnJldHVy
-biExfXIuc0kocC5FKHEscykpOysrci5jCnJldHVybiEwfSwKc0k6ZnVuY3Rpb24oYSl7dGhpcy5kPXRo
-aXMuJHRpLkMoIjE/IikuYShhKX0sCiRpQW46MX0KSC5pMS5wcm90b3R5cGU9ewpnbTpmdW5jdGlvbihh
-KXt2YXIgcz1ILkxoKHRoaXMpCnJldHVybiBuZXcgSC5NSChKLklUKHRoaXMuYSksdGhpcy5iLHMuQygi
-QDwxPiIpLktxKHMuUVsxXSkuQygiTUg8MSwyPiIpKX0sCmdBOmZ1bmN0aW9uKGEpe3JldHVybiBKLkht
-KHRoaXMuYSl9LApnbDA6ZnVuY3Rpb24oYSl7cmV0dXJuIEoudVUodGhpcy5hKX0sCkU6ZnVuY3Rpb24o
-YSxiKXtyZXR1cm4gdGhpcy5iLiQxKEouR0EodGhpcy5hLGIpKX19CkgueHkucHJvdG90eXBlPXskaWJR
-OjF9CkguTUgucHJvdG90eXBlPXsKRjpmdW5jdGlvbigpe3ZhciBzPXRoaXMscj1zLmIKaWYoci5GKCkp
-e3Muc0kocy5jLiQxKHIuZ2woKSkpCnJldHVybiEwfXMuc0kobnVsbCkKcmV0dXJuITF9LApnbDpmdW5j
-dGlvbigpe3JldHVybiB0aGlzLmF9LApzSTpmdW5jdGlvbihhKXt0aGlzLmE9dGhpcy4kdGkuQygiMj8i
-KS5hKGEpfX0KSC5sSi5wcm90b3R5cGU9ewpnQTpmdW5jdGlvbihhKXtyZXR1cm4gSi5IbSh0aGlzLmEp
-fSwKRTpmdW5jdGlvbihhLGIpe3JldHVybiB0aGlzLmIuJDEoSi5HQSh0aGlzLmEsYikpfX0KSC5VNS5w
-cm90b3R5cGU9ewpnbTpmdW5jdGlvbihhKXtyZXR1cm4gbmV3IEguU08oSi5JVCh0aGlzLmEpLHRoaXMu
-Yix0aGlzLiR0aS5DKCJTTzwxPiIpKX19CkguU08ucHJvdG90eXBlPXsKRjpmdW5jdGlvbigpe3ZhciBz
-LHIKZm9yKHM9dGhpcy5hLHI9dGhpcy5iO3MuRigpOylpZihILm9UKHIuJDEocy5nbCgpKSkpcmV0dXJu
-ITAKcmV0dXJuITF9LApnbDpmdW5jdGlvbigpe3JldHVybiB0aGlzLmEuZ2woKX19CkguQU0ucHJvdG90
-eXBlPXsKZVI6ZnVuY3Rpb24oYSxiKXtQLk1SKGIsImNvdW50Iix0LlMpClAuazEoYiwiY291bnQiKQpy
-ZXR1cm4gbmV3IEguQU0odGhpcy5hLHRoaXMuYitiLEguTGgodGhpcykuQygiQU08MT4iKSl9LApnbTpm
-dW5jdGlvbihhKXtyZXR1cm4gbmV3IEguVTEoSi5JVCh0aGlzLmEpLHRoaXMuYixILkxoKHRoaXMpLkMo
-IlUxPDE+IikpfX0KSC5kNS5wcm90b3R5cGU9ewpnQTpmdW5jdGlvbihhKXt2YXIgcz1KLkhtKHRoaXMu
-YSktdGhpcy5iCmlmKHM+PTApcmV0dXJuIHMKcmV0dXJuIDB9LAplUjpmdW5jdGlvbihhLGIpe1AuTVIo
-YiwiY291bnQiLHQuUykKUC5rMShiLCJjb3VudCIpCnJldHVybiBuZXcgSC5kNSh0aGlzLmEsdGhpcy5i
-K2IsdGhpcy4kdGkpfSwKJGliUToxfQpILlUxLnByb3RvdHlwZT17CkY6ZnVuY3Rpb24oKXt2YXIgcyxy
-CmZvcihzPXRoaXMuYSxyPTA7cjx0aGlzLmI7KytyKXMuRigpCnRoaXMuYj0wCnJldHVybiBzLkYoKX0s
-CmdsOmZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMuYS5nbCgpfX0KSC5NQi5wcm90b3R5cGU9ewpnbTpmdW5j
-dGlvbihhKXtyZXR1cm4gQy5Hd30sCmdsMDpmdW5jdGlvbihhKXtyZXR1cm4hMH0sCmdBOmZ1bmN0aW9u
-KGEpe3JldHVybiAwfSwKRTpmdW5jdGlvbihhLGIpe3Rocm93IEguYihQLlRFKGIsMCwwLCJpbmRleCIs
-bnVsbCkpfSwKZVI6ZnVuY3Rpb24oYSxiKXtQLmsxKGIsImNvdW50IikKcmV0dXJuIHRoaXN9fQpILkZ1
-LnByb3RvdHlwZT17CkY6ZnVuY3Rpb24oKXtyZXR1cm4hMX0sCmdsOmZ1bmN0aW9uKCl7dGhyb3cgSC5i
-KEguV3AoKSl9LAokaUFuOjF9CkgudTYucHJvdG90eXBlPXsKZ206ZnVuY3Rpb24oYSl7cmV0dXJuIG5l
-dyBILkpCKEouSVQodGhpcy5hKSx0aGlzLiR0aS5DKCJKQjwxPiIpKX19CkguSkIucHJvdG90eXBlPXsK
-RjpmdW5jdGlvbigpe3ZhciBzLHIKZm9yKHM9dGhpcy5hLHI9dGhpcy4kdGkuYztzLkYoKTspaWYoci5i
-KHMuZ2woKSkpcmV0dXJuITAKcmV0dXJuITF9LApnbDpmdW5jdGlvbigpe3JldHVybiB0aGlzLiR0aS5j
-LmEodGhpcy5hLmdsKCkpfSwKJGlBbjoxfQpILlNVLnByb3RvdHlwZT17fQpILlJlLnByb3RvdHlwZT17
-Clk6ZnVuY3Rpb24oYSxiLGMpe0guTGgodGhpcykuQygiUmUuRSIpLmEoYykKdGhyb3cgSC5iKFAuTDQo
-IkNhbm5vdCBtb2RpZnkgYW4gdW5tb2RpZmlhYmxlIGxpc3QiKSl9fQpILncyLnByb3RvdHlwZT17fQpI
-Lnd2LnByb3RvdHlwZT17CmdpTzpmdW5jdGlvbihhKXt2YXIgcz10aGlzLl9oYXNoQ29kZQppZihzIT1u
-dWxsKXJldHVybiBzCnM9NjY0NTk3KkouaGYodGhpcy5hKSY1MzY4NzA5MTEKdGhpcy5faGFzaENvZGU9
-cwpyZXR1cm4gc30sCnc6ZnVuY3Rpb24oYSl7cmV0dXJuJ1N5bWJvbCgiJytILkVqKHRoaXMuYSkrJyIp
-J30sCkROOmZ1bmN0aW9uKGEsYil7aWYoYj09bnVsbClyZXR1cm4hMQpyZXR1cm4gYiBpbnN0YW5jZW9m
-IEgud3YmJnRoaXMuYT09Yi5hfSwKJGlHRDoxfQpILlFDLnByb3RvdHlwZT17fQpILlBELnByb3RvdHlw
-ZT17fQpILldVLnByb3RvdHlwZT17CmdsMDpmdW5jdGlvbihhKXtyZXR1cm4gdGhpcy5nQSh0aGlzKT09
-PTB9LAp3OmZ1bmN0aW9uKGEpe3JldHVybiBQLm5PKHRoaXMpfSwKWTpmdW5jdGlvbihhLGIsYyl7dmFy
-IHM9SC5MaCh0aGlzKQpzLmMuYShiKQpzLlFbMV0uYShjKQpILmRjKCkKSC5CaSh1LmcpfSwKZ1B1OmZ1
-bmN0aW9uKGEpe3JldHVybiB0aGlzLnE0KGEsSC5MaCh0aGlzKS5DKCJOMzwxLDI+IikpfSwKcTQ6ZnVu
-Y3Rpb24oYSxiKXt2YXIgcz10aGlzCnJldHVybiBQLmwwKGZ1bmN0aW9uKCl7dmFyIHI9YQp2YXIgcT0w
-LHA9MSxvLG4sbSxsLGsKcmV0dXJuIGZ1bmN0aW9uICRhc3luYyRnUHUoYyxkKXtpZihjPT09MSl7bz1k
-CnE9cH13aGlsZSh0cnVlKXN3aXRjaChxKXtjYXNlIDA6bj1zLmdWKCksbj1uLmdtKG4pLG09SC5MaChz
-KSxtPW0uQygiQDwxPiIpLktxKG0uUVsxXSkuQygiTjM8MSwyPiIpCmNhc2UgMjppZighbi5GKCkpe3E9
-MwpicmVha31sPW4uZ2woKQprPXMucSgwLGwpCmsudG9TdHJpbmcKcT00CnJldHVybiBuZXcgUC5OMyhs
-LGssbSkKY2FzZSA0OnE9MgpicmVhawpjYXNlIDM6cmV0dXJuIFAuVGgoKQpjYXNlIDE6cmV0dXJuIFAu
-WW0obyl9fX0sYil9LAokaVowOjF9CkguTFAucHJvdG90eXBlPXsKZ0E6ZnVuY3Rpb24oYSl7cmV0dXJu
-IHRoaXMuYX0sCng0OmZ1bmN0aW9uKGEpe2lmKHR5cGVvZiBhIT0ic3RyaW5nIilyZXR1cm4hMQppZigi
-X19wcm90b19fIj09PWEpcmV0dXJuITEKcmV0dXJuIHRoaXMuYi5oYXNPd25Qcm9wZXJ0eShhKX0sCnE6
-ZnVuY3Rpb24oYSxiKXtpZighdGhpcy54NChiKSlyZXR1cm4gbnVsbApyZXR1cm4gdGhpcy5xUChiKX0s
-CnFQOmZ1bmN0aW9uKGEpe3JldHVybiB0aGlzLmJbSC5oKGEpXX0sCks6ZnVuY3Rpb24oYSxiKXt2YXIg
-cyxyLHEscCxvPUguTGgodGhpcykKby5DKCJ+KDEsMikiKS5hKGIpCnM9dGhpcy5jCmZvcihyPXMubGVu
-Z3RoLG89by5RWzFdLHE9MDtxPHI7KytxKXtwPXNbcV0KYi4kMihwLG8uYSh0aGlzLnFQKHApKSl9fSwK
-Z1Y6ZnVuY3Rpb24oKXtyZXR1cm4gbmV3IEguWFIodGhpcyxILkxoKHRoaXMpLkMoIlhSPDE+IikpfX0K
-SC5YUi5wcm90b3R5cGU9ewpnbTpmdW5jdGlvbihhKXt2YXIgcz10aGlzLmEuYwpyZXR1cm4gbmV3IEou
-bTEocyxzLmxlbmd0aCxILnQ2KHMpLkMoIm0xPDE+IikpfSwKZ0E6ZnVuY3Rpb24oYSl7cmV0dXJuIHRo
-aXMuYS5jLmxlbmd0aH19CkguTEkucHJvdG90eXBlPXsKZ1dhOmZ1bmN0aW9uKCl7dmFyIHM9dGhpcy5h
-CnJldHVybiBzfSwKZ25kOmZ1bmN0aW9uKCl7dmFyIHMscixxLHAsbz10aGlzCmlmKG8uYz09PTEpcmV0
-dXJuIEMuaFUKcz1vLmQKcj1zLmxlbmd0aC1vLmUubGVuZ3RoLW8uZgppZihyPT09MClyZXR1cm4gQy5o
-VQpxPVtdCmZvcihwPTA7cDxyOysrcCl7aWYocD49cy5sZW5ndGgpcmV0dXJuIEguT0gocyxwKQpxLnB1
-c2goc1twXSl9cmV0dXJuIEouekMocSl9LApnVm06ZnVuY3Rpb24oKXt2YXIgcyxyLHEscCxvLG4sbSxs
-LGs9dGhpcwppZihrLmMhPT0wKXJldHVybiBDLldPCnM9ay5lCnI9cy5sZW5ndGgKcT1rLmQKcD1xLmxl
-bmd0aC1yLWsuZgppZihyPT09MClyZXR1cm4gQy5XTwpvPW5ldyBILk41KHQuZW8pCmZvcihuPTA7bjxy
-Oysrbil7aWYobj49cy5sZW5ndGgpcmV0dXJuIEguT0gocyxuKQptPXNbbl0KbD1wK24KaWYobDwwfHxs
-Pj1xLmxlbmd0aClyZXR1cm4gSC5PSChxLGwpCm8uWSgwLG5ldyBILnd2KG0pLHFbbF0pfXJldHVybiBu
-ZXcgSC5QRChvLHQuZ0YpfSwKJGl2UToxfQpILkNqLnByb3RvdHlwZT17CiQyOmZ1bmN0aW9uKGEsYil7
-dmFyIHMKSC5oKGEpCnM9dGhpcy5hCnMuYj1zLmIrIiQiK0guRWooYSkKQy5ObS5pKHRoaXMuYixhKQpD
-Lk5tLmkodGhpcy5jLGIpOysrcy5hfSwKJFM6MTJ9CkguZjkucHJvdG90eXBlPXsKcVM6ZnVuY3Rpb24o
-YSl7dmFyIHMscixxPXRoaXMscD1uZXcgUmVnRXhwKHEuYSkuZXhlYyhhKQppZihwPT1udWxsKXJldHVy
-biBudWxsCnM9T2JqZWN0LmNyZWF0ZShudWxsKQpyPXEuYgppZihyIT09LTEpcy5hcmd1bWVudHM9cFty
-KzFdCnI9cS5jCmlmKHIhPT0tMSlzLmFyZ3VtZW50c0V4cHI9cFtyKzFdCnI9cS5kCmlmKHIhPT0tMSlz
-LmV4cHI9cFtyKzFdCnI9cS5lCmlmKHIhPT0tMSlzLm1ldGhvZD1wW3IrMV0Kcj1xLmYKaWYociE9PS0x
-KXMucmVjZWl2ZXI9cFtyKzFdCnJldHVybiBzfX0KSC5XMC5wcm90b3R5cGU9ewp3OmZ1bmN0aW9uKGEp
-e3ZhciBzPXRoaXMuYgppZihzPT1udWxsKXJldHVybiJOb1N1Y2hNZXRob2RFcnJvcjogIitILkVqKHRo
-aXMuYSkKcmV0dXJuIk5vU3VjaE1ldGhvZEVycm9yOiBtZXRob2Qgbm90IGZvdW5kOiAnIitzKyInIG9u
-IG51bGwifX0KSC5hei5wcm90b3R5cGU9ewp3OmZ1bmN0aW9uKGEpe3ZhciBzLHI9dGhpcyxxPSJOb1N1
-Y2hNZXRob2RFcnJvcjogbWV0aG9kIG5vdCBmb3VuZDogJyIscD1yLmIKaWYocD09bnVsbClyZXR1cm4i
-Tm9TdWNoTWV0aG9kRXJyb3I6ICIrSC5FaihyLmEpCnM9ci5jCmlmKHM9PW51bGwpcmV0dXJuIHErcCsi
-JyAoIitILkVqKHIuYSkrIikiCnJldHVybiBxK3ArIicgb24gJyIrcysiJyAoIitILkVqKHIuYSkrIiki
-fX0KSC52Vi5wcm90b3R5cGU9ewp3OmZ1bmN0aW9uKGEpe3ZhciBzPXRoaXMuYQpyZXR1cm4gcy5sZW5n
-dGg9PT0wPyJFcnJvciI6IkVycm9yOiAiK3N9fQpILnRlLnByb3RvdHlwZT17Cnc6ZnVuY3Rpb24oYSl7
-cmV0dXJuIlRocm93IG9mIG51bGwgKCciKyh0aGlzLmE9PT1udWxsPyJudWxsIjoidW5kZWZpbmVkIikr
-IicgZnJvbSBKYXZhU2NyaXB0KSJ9LAokaVJ6OjF9CkguYnEucHJvdG90eXBlPXt9CkguWE8ucHJvdG90
-eXBlPXsKdzpmdW5jdGlvbihhKXt2YXIgcyxyPXRoaXMuYgppZihyIT1udWxsKXJldHVybiByCnI9dGhp
-cy5hCnM9ciE9PW51bGwmJnR5cGVvZiByPT09Im9iamVjdCI/ci5zdGFjazpudWxsCnJldHVybiB0aGlz
-LmI9cz09bnVsbD8iIjpzfSwKJGlHejoxfQpILlRwLnByb3RvdHlwZT17Cnc6ZnVuY3Rpb24oYSl7dmFy
-IHM9dGhpcy5jb25zdHJ1Y3RvcixyPXM9PW51bGw/bnVsbDpzLm5hbWUKcmV0dXJuIkNsb3N1cmUgJyIr
-SC5OUShyPT1udWxsPyJ1bmtub3duIjpyKSsiJyJ9LAokaUVIOjEsCmdLdTpmdW5jdGlvbigpe3JldHVy
-biB0aGlzfSwKJEM6IiQxIiwKJFI6MSwKJEQ6bnVsbH0KSC5sYy5wcm90b3R5cGU9e30KSC56eC5wcm90
-b3R5cGU9ewp3OmZ1bmN0aW9uKGEpe3ZhciBzPXRoaXMuJHN0YXRpY19uYW1lCmlmKHM9PW51bGwpcmV0
-dXJuIkNsb3N1cmUgb2YgdW5rbm93biBzdGF0aWMgbWV0aG9kIgpyZXR1cm4iQ2xvc3VyZSAnIitILk5R
-KHMpKyInIn19CkguclQucHJvdG90eXBlPXsKRE46ZnVuY3Rpb24oYSxiKXt2YXIgcz10aGlzCmlmKGI9
-PW51bGwpcmV0dXJuITEKaWYocz09PWIpcmV0dXJuITAKaWYoIShiIGluc3RhbmNlb2YgSC5yVCkpcmV0
-dXJuITEKcmV0dXJuIHMuYT09PWIuYSYmcy5iPT09Yi5iJiZzLmM9PT1iLmN9LApnaU86ZnVuY3Rpb24o
-YSl7dmFyIHMscj10aGlzLmMKaWYocj09bnVsbClzPUguZVEodGhpcy5hKQplbHNlIHM9dHlwZW9mIHIh
-PT0ib2JqZWN0Ij9KLmhmKHIpOkguZVEocikKcj1ILmVRKHRoaXMuYikKaWYodHlwZW9mIHMhPT0ibnVt
-YmVyIilyZXR1cm4gcy53TygpCnJldHVybihzXnIpPj4+MH0sCnc6ZnVuY3Rpb24oYSl7dmFyIHM9dGhp
-cy5jCmlmKHM9PW51bGwpcz10aGlzLmEKcmV0dXJuIkNsb3N1cmUgJyIrSC5Faih0aGlzLmQpKyInIG9m
-ICIrKCJJbnN0YW5jZSBvZiAnIitILkVqKEguTShzKSkrIiciKX19CkguRXEucHJvdG90eXBlPXsKdzpm
-dW5jdGlvbihhKXtyZXR1cm4iUnVudGltZUVycm9yOiAiK3RoaXMuYX19Ckgua1kucHJvdG90eXBlPXsK
-dzpmdW5jdGlvbihhKXtyZXR1cm4iQXNzZXJ0aW9uIGZhaWxlZDogIitQLnAodGhpcy5hKX19Ckgua3Iu
-cHJvdG90eXBlPXt9CkguTjUucHJvdG90eXBlPXsKZ0E6ZnVuY3Rpb24oYSl7cmV0dXJuIHRoaXMuYX0s
-CmdsMDpmdW5jdGlvbihhKXtyZXR1cm4gdGhpcy5hPT09MH0sCmdWOmZ1bmN0aW9uKCl7cmV0dXJuIG5l
-dyBILmk1KHRoaXMsSC5MaCh0aGlzKS5DKCJpNTwxPiIpKX0sCng0OmZ1bmN0aW9uKGEpe3ZhciBzLHIK
-aWYodHlwZW9mIGE9PSJzdHJpbmciKXtzPXRoaXMuYgppZihzPT1udWxsKXJldHVybiExCnJldHVybiB0
-aGlzLlh1KHMsYSl9ZWxzZXtyPXRoaXMuQ1goYSkKcmV0dXJuIHJ9fSwKQ1g6ZnVuY3Rpb24oYSl7dmFy
-IHM9dGhpcy5kCmlmKHM9PW51bGwpcmV0dXJuITEKcmV0dXJuIHRoaXMuRmgodGhpcy5CdChzLEouaGYo
-YSkmMHgzZmZmZmZmKSxhKT49MH0sCnE6ZnVuY3Rpb24oYSxiKXt2YXIgcyxyLHEscCxvPXRoaXMsbj1u
-dWxsCmlmKHR5cGVvZiBiPT0ic3RyaW5nIil7cz1vLmIKaWYocz09bnVsbClyZXR1cm4gbgpyPW8uajIo
-cyxiKQpxPXI9PW51bGw/bjpyLmIKcmV0dXJuIHF9ZWxzZSBpZih0eXBlb2YgYj09Im51bWJlciImJihi
-JjB4M2ZmZmZmZik9PT1iKXtwPW8uYwppZihwPT1udWxsKXJldHVybiBuCnI9by5qMihwLGIpCnE9cj09
-bnVsbD9uOnIuYgpyZXR1cm4gcX1lbHNlIHJldHVybiBvLmFhKGIpfSwKYWE6ZnVuY3Rpb24oYSl7dmFy
-IHMscixxPXRoaXMuZAppZihxPT1udWxsKXJldHVybiBudWxsCnM9dGhpcy5CdChxLEouaGYoYSkmMHgz
-ZmZmZmZmKQpyPXRoaXMuRmgocyxhKQppZihyPDApcmV0dXJuIG51bGwKcmV0dXJuIHNbcl0uYn0sClk6
-ZnVuY3Rpb24oYSxiLGMpe3ZhciBzLHIscSxwLG8sbixtPXRoaXMsbD1ILkxoKG0pCmwuYy5hKGIpCmwu
-UVsxXS5hKGMpCmlmKHR5cGVvZiBiPT0ic3RyaW5nIil7cz1tLmIKbS5FSChzPT1udWxsP20uYj1tLnpL
-KCk6cyxiLGMpfWVsc2UgaWYodHlwZW9mIGI9PSJudW1iZXIiJiYoYiYweDNmZmZmZmYpPT09Yil7cj1t
-LmMKbS5FSChyPT1udWxsP20uYz1tLnpLKCk6cixiLGMpfWVsc2V7cT1tLmQKaWYocT09bnVsbClxPW0u
-ZD1tLnpLKCkKcD1KLmhmKGIpJjB4M2ZmZmZmZgpvPW0uQnQocSxwKQppZihvPT1udWxsKW0uRUkocSxw
-LFttLkhuKGIsYyldKQplbHNle249bS5GaChvLGIpCmlmKG4+PTApb1tuXS5iPWMKZWxzZSBvLnB1c2go
-bS5IbihiLGMpKX19fSwKSzpmdW5jdGlvbihhLGIpe3ZhciBzLHIscT10aGlzCkguTGgocSkuQygifigx
-LDIpIikuYShiKQpzPXEuZQpyPXEucgpmb3IoO3MhPW51bGw7KXtiLiQyKHMuYSxzLmIpCmlmKHIhPT1x
-LnIpdGhyb3cgSC5iKFAuYTQocSkpCnM9cy5jfX0sCkVIOmZ1bmN0aW9uKGEsYixjKXt2YXIgcyxyPXRo
-aXMscT1ILkxoKHIpCnEuYy5hKGIpCnEuUVsxXS5hKGMpCnM9ci5qMihhLGIpCmlmKHM9PW51bGwpci5F
-SShhLGIsci5IbihiLGMpKQplbHNlIHMuYj1jfSwKa3M6ZnVuY3Rpb24oKXt0aGlzLnI9dGhpcy5yKzEm
-NjcxMDg4NjN9LApIbjpmdW5jdGlvbihhLGIpe3ZhciBzPXRoaXMscj1ILkxoKHMpLHE9bmV3IEgudmgo
-ci5jLmEoYSksci5RWzFdLmEoYikpCmlmKHMuZT09bnVsbClzLmU9cy5mPXEKZWxzZXtyPXMuZgpyLnRv
-U3RyaW5nCnEuZD1yCnMuZj1yLmM9cX0rK3MuYQpzLmtzKCkKcmV0dXJuIHF9LApGaDpmdW5jdGlvbihh
-LGIpe3ZhciBzLHIKaWYoYT09bnVsbClyZXR1cm4tMQpzPWEubGVuZ3RoCmZvcihyPTA7cjxzOysrcilp
-ZihKLlJNKGFbcl0uYSxiKSlyZXR1cm4gcgpyZXR1cm4tMX0sCnc6ZnVuY3Rpb24oYSl7cmV0dXJuIFAu
-bk8odGhpcyl9LApqMjpmdW5jdGlvbihhLGIpe3JldHVybiBhW2JdfSwKQnQ6ZnVuY3Rpb24oYSxiKXty
-ZXR1cm4gYVtiXX0sCkVJOmZ1bmN0aW9uKGEsYixjKXthW2JdPWN9LApybjpmdW5jdGlvbihhLGIpe2Rl
-bGV0ZSBhW2JdfSwKWHU6ZnVuY3Rpb24oYSxiKXtyZXR1cm4gdGhpcy5qMihhLGIpIT1udWxsfSwKeks6
-ZnVuY3Rpb24oKXt2YXIgcz0iPG5vbi1pZGVudGlmaWVyLWtleT4iLHI9T2JqZWN0LmNyZWF0ZShudWxs
-KQp0aGlzLkVJKHIscyxyKQp0aGlzLnJuKHIscykKcmV0dXJuIHJ9LAokaUZvOjF9CkgudmgucHJvdG90
-eXBlPXt9CkguaTUucHJvdG90eXBlPXsKZ0E6ZnVuY3Rpb24oYSl7cmV0dXJuIHRoaXMuYS5hfSwKZ2ww
-OmZ1bmN0aW9uKGEpe3JldHVybiB0aGlzLmEuYT09PTB9LApnbTpmdW5jdGlvbihhKXt2YXIgcz10aGlz
-LmEscj1uZXcgSC5ONihzLHMucix0aGlzLiR0aS5DKCJONjwxPiIpKQpyLmM9cy5lCnJldHVybiByfSwK
-dGc6ZnVuY3Rpb24oYSxiKXtyZXR1cm4gdGhpcy5hLng0KGIpfX0KSC5ONi5wcm90b3R5cGU9ewpnbDpm
-dW5jdGlvbigpe3JldHVybiB0aGlzLmR9LApGOmZ1bmN0aW9uKCl7dmFyIHMscj10aGlzLHE9ci5hCmlm
-KHIuYiE9PXEucil0aHJvdyBILmIoUC5hNChxKSkKcz1yLmMKaWYocz09bnVsbCl7ci5zcVkobnVsbCkK
-cmV0dXJuITF9ZWxzZXtyLnNxWShzLmEpCnIuYz1zLmMKcmV0dXJuITB9fSwKc3FZOmZ1bmN0aW9uKGEp
-e3RoaXMuZD10aGlzLiR0aS5DKCIxPyIpLmEoYSl9LAokaUFuOjF9CkguZEMucHJvdG90eXBlPXsKJDE6
-ZnVuY3Rpb24oYSl7cmV0dXJuIHRoaXMuYShhKX0sCiRTOjR9Ckgud04ucHJvdG90eXBlPXsKJDI6ZnVu
-Y3Rpb24oYSxiKXtyZXR1cm4gdGhpcy5hKGEsYil9LAokUzo0Nn0KSC5WWC5wcm90b3R5cGU9ewokMTpm
-dW5jdGlvbihhKXtyZXR1cm4gdGhpcy5hKEguaChhKSl9LAokUzo0MX0KSC5WUi5wcm90b3R5cGU9ewp3
-OmZ1bmN0aW9uKGEpe3JldHVybiJSZWdFeHAvIit0aGlzLmErIi8iK3RoaXMuYi5mbGFnc30sCmdIYzpm
-dW5jdGlvbigpe3ZhciBzPXRoaXMscj1zLmMKaWYociE9bnVsbClyZXR1cm4gcgpyPXMuYgpyZXR1cm4g
-cy5jPUgudjQocy5hLHIubXVsdGlsaW5lLCFyLmlnbm9yZUNhc2Usci51bmljb2RlLHIuZG90QWxsLCEw
-KX0sCmRkOmZ1bmN0aW9uKGEsYil7cmV0dXJuIG5ldyBILktXKHRoaXMsYiwwKX0sClVaOmZ1bmN0aW9u
-KGEsYil7dmFyIHMscj10aGlzLmdIYygpCnIubGFzdEluZGV4PWIKcz1yLmV4ZWMoYSkKaWYocz09bnVs
-bClyZXR1cm4gbnVsbApyZXR1cm4gbmV3IEguRUsocyl9LAokaXZYOjEsCiRpd0w6MX0KSC5FSy5wcm90
-b3R5cGU9ewpxOmZ1bmN0aW9uKGEsYil7dmFyIHMKSC51UChiKQpzPXRoaXMuYgppZihiPj1zLmxlbmd0
-aClyZXR1cm4gSC5PSChzLGIpCnJldHVybiBzW2JdfSwKJGlPZDoxLAokaWliOjF9CkguS1cucHJvdG90
-eXBlPXsKZ206ZnVuY3Rpb24oYSl7cmV0dXJuIG5ldyBILlBiKHRoaXMuYSx0aGlzLmIsdGhpcy5jKX19
-CkguUGIucHJvdG90eXBlPXsKZ2w6ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5kfSwKRjpmdW5jdGlvbigp
-e3ZhciBzLHIscSxwLG8sbixtPXRoaXMsbD1tLmIKaWYobD09bnVsbClyZXR1cm4hMQpzPW0uYwpyPWwu
-bGVuZ3RoCmlmKHM8PXIpe3E9bS5hCnA9cS5VWihsLHMpCmlmKHAhPW51bGwpe20uZD1wCnM9cC5iCm89
-cy5pbmRleApuPW8rc1swXS5sZW5ndGgKaWYobz09PW4pe2lmKHEuYi51bmljb2RlKXtzPW0uYwpxPXMr
-MQppZihxPHIpe3M9Qy54Qi5PMihsLHMpCmlmKHM+PTU1Mjk2JiZzPD01NjMxOSl7cz1DLnhCLk8yKGws
-cSkKcz1zPj01NjMyMCYmczw9NTczNDN9ZWxzZSBzPSExfWVsc2Ugcz0hMX1lbHNlIHM9ITEKbj0ocz9u
-KzE6bikrMX1tLmM9bgpyZXR1cm4hMH19bS5iPW0uZD1udWxsCnJldHVybiExfSwKJGlBbjoxfQpILnRR
-LnByb3RvdHlwZT17CnE6ZnVuY3Rpb24oYSxiKXtILnVQKGIpCmlmKGIhPT0wKUgudihQLk83KGIsbnVs
-bCkpCnJldHVybiB0aGlzLmN9LAokaU9kOjF9CkgudW4ucHJvdG90eXBlPXsKZ206ZnVuY3Rpb24oYSl7
-cmV0dXJuIG5ldyBILlNkKHRoaXMuYSx0aGlzLmIsdGhpcy5jKX19CkguU2QucHJvdG90eXBlPXsKRjpm
-dW5jdGlvbigpe3ZhciBzLHIscT10aGlzLHA9cS5jLG89cS5iLG49by5sZW5ndGgsbT1xLmEsbD1tLmxl
-bmd0aAppZihwK24+bCl7cS5kPW51bGwKcmV0dXJuITF9cz1tLmluZGV4T2YobyxwKQppZihzPDApe3Eu
-Yz1sKzEKcS5kPW51bGwKcmV0dXJuITF9cj1zK24KcS5kPW5ldyBILnRRKHMsbykKcS5jPXI9PT1xLmM/
-cisxOnIKcmV0dXJuITB9LApnbDpmdW5jdGlvbigpe3ZhciBzPXRoaXMuZApzLnRvU3RyaW5nCnJldHVy
-biBzfSwKJGlBbjoxfQpILkVULnByb3RvdHlwZT17JGlFVDoxLCRpQVM6MX0KSC5MWi5wcm90b3R5cGU9
-ewpnQTpmdW5jdGlvbihhKXtyZXR1cm4gYS5sZW5ndGh9LAokaVhqOjF9CkguRGcucHJvdG90eXBlPXsK
-cTpmdW5jdGlvbihhLGIpe0gudVAoYikKSC5vZChiLGEsYS5sZW5ndGgpCnJldHVybiBhW2JdfSwKWTpm
-dW5jdGlvbihhLGIsYyl7SC5HSChjKQpILm9kKGIsYSxhLmxlbmd0aCkKYVtiXT1jfSwKJGliUToxLAok
-aWNYOjEsCiRpek06MX0KSC5QZy5wcm90b3R5cGU9ewpZOmZ1bmN0aW9uKGEsYixjKXtILnVQKGMpCkgu
-b2QoYixhLGEubGVuZ3RoKQphW2JdPWN9LAokaWJROjEsCiRpY1g6MSwKJGl6TToxfQpILnhqLnByb3Rv
-dHlwZT17CnE6ZnVuY3Rpb24oYSxiKXtILnVQKGIpCkgub2QoYixhLGEubGVuZ3RoKQpyZXR1cm4gYVti
-XX19CkguZEUucHJvdG90eXBlPXsKcTpmdW5jdGlvbihhLGIpe0gudVAoYikKSC5vZChiLGEsYS5sZW5n
-dGgpCnJldHVybiBhW2JdfX0KSC5aQS5wcm90b3R5cGU9ewpxOmZ1bmN0aW9uKGEsYil7SC51UChiKQpI
-Lm9kKGIsYSxhLmxlbmd0aCkKcmV0dXJuIGFbYl19fQpILmRULnByb3RvdHlwZT17CnE6ZnVuY3Rpb24o
-YSxiKXtILnVQKGIpCkgub2QoYixhLGEubGVuZ3RoKQpyZXR1cm4gYVtiXX19CkguUHEucHJvdG90eXBl
-PXsKcTpmdW5jdGlvbihhLGIpe0gudVAoYikKSC5vZChiLGEsYS5sZW5ndGgpCnJldHVybiBhW2JdfX0K
-SC5lRS5wcm90b3R5cGU9ewpnQTpmdW5jdGlvbihhKXtyZXR1cm4gYS5sZW5ndGh9LApxOmZ1bmN0aW9u
-KGEsYil7SC51UChiKQpILm9kKGIsYSxhLmxlbmd0aCkKcmV0dXJuIGFbYl19fQpILlY2LnByb3RvdHlw
-ZT17CmdBOmZ1bmN0aW9uKGEpe3JldHVybiBhLmxlbmd0aH0sCnE6ZnVuY3Rpb24oYSxiKXtILnVQKGIp
-Ckgub2QoYixhLGEubGVuZ3RoKQpyZXR1cm4gYVtiXX0sCiRpVjY6MSwKJGluNjoxfQpILlJHLnByb3Rv
-dHlwZT17fQpILlZQLnByb3RvdHlwZT17fQpILldCLnByb3RvdHlwZT17fQpILlpHLnByb3RvdHlwZT17
-fQpILkpjLnByb3RvdHlwZT17CkM6ZnVuY3Rpb24oYSl7cmV0dXJuIEguY0Uodi50eXBlVW5pdmVyc2Us
-dGhpcyxhKX0sCktxOmZ1bmN0aW9uKGEpe3JldHVybiBILnY1KHYudHlwZVVuaXZlcnNlLHRoaXMsYSl9
-fQpILkcucHJvdG90eXBlPXt9CkgubFkucHJvdG90eXBlPXsKdzpmdW5jdGlvbihhKXtyZXR1cm4gSC5k
-bSh0aGlzLmEsbnVsbCl9fQpILmtTLnByb3RvdHlwZT17Cnc6ZnVuY3Rpb24oYSl7cmV0dXJuIHRoaXMu
-YX19CkguaU0ucHJvdG90eXBlPXt9ClAudGgucHJvdG90eXBlPXsKJDE6ZnVuY3Rpb24oYSl7dmFyIHM9
-dGhpcy5hLHI9cy5hCnMuYT1udWxsCnIuJDAoKX0sCiRTOjl9ClAuaGEucHJvdG90eXBlPXsKJDE6ZnVu
-Y3Rpb24oYSl7dmFyIHMscgp0aGlzLmEuYT10Lk0uYShhKQpzPXRoaXMuYgpyPXRoaXMuYwpzLmZpcnN0
-Q2hpbGQ/cy5yZW1vdmVDaGlsZChyKTpzLmFwcGVuZENoaWxkKHIpfSwKJFM6MzR9ClAuVnMucHJvdG90
-eXBlPXsKJDA6ZnVuY3Rpb24oKXt0aGlzLmEuJDAoKX0sCiRDOiIkMCIsCiRSOjAsCiRTOjF9ClAuRnQu
-cHJvdG90eXBlPXsKJDA6ZnVuY3Rpb24oKXt0aGlzLmEuJDAoKX0sCiRDOiIkMCIsCiRSOjAsCiRTOjF9
-ClAuVzMucHJvdG90eXBlPXsKQ1k6ZnVuY3Rpb24oYSxiKXtpZihzZWxmLnNldFRpbWVvdXQhPW51bGwp
-c2VsZi5zZXRUaW1lb3V0KEgudFIobmV3IFAueUgodGhpcyxiKSwwKSxhKQplbHNlIHRocm93IEguYihQ
-Lkw0KCJgc2V0VGltZW91dCgpYCBub3QgZm91bmQuIikpfX0KUC55SC5wcm90b3R5cGU9ewokMDpmdW5j
-dGlvbigpe3RoaXMuYi4kMCgpfSwKJEM6IiQwIiwKJFI6MCwKJFM6MH0KUC5paC5wcm90b3R5cGU9ewph
-TTpmdW5jdGlvbihhLGIpe3ZhciBzLHI9dGhpcyxxPXIuJHRpCnEuQygiMS8/IikuYShiKQppZighci5i
-KXIuYS5YZihiKQplbHNle3M9ci5hCmlmKHEuQygiYjg8MT4iKS5iKGIpKXMuY1UoYikKZWxzZSBzLlgy
-KHEuYy5hKGIpKX19LAp3MDpmdW5jdGlvbihhLGIpe3ZhciBzCmlmKGI9PW51bGwpYj1QLnYwKGEpCnM9
-dGhpcy5hCmlmKHRoaXMuYilzLlpMKGEsYikKZWxzZSBzLk5rKGEsYil9fQpQLldNLnByb3RvdHlwZT17
-CiQxOmZ1bmN0aW9uKGEpe3JldHVybiB0aGlzLmEuJDIoMCxhKX0sCiRTOjUyfQpQLlNYLnByb3RvdHlw
-ZT17CiQyOmZ1bmN0aW9uKGEsYil7dGhpcy5hLiQyKDEsbmV3IEguYnEoYSx0LmwuYShiKSkpfSwKJEM6
-IiQyIiwKJFI6MiwKJFM6MjR9ClAuR3MucHJvdG90eXBlPXsKJDI6ZnVuY3Rpb24oYSxiKXt0aGlzLmEo
-SC51UChhKSxiKX0sCiRTOjI2fQpQLkZ5LnByb3RvdHlwZT17Cnc6ZnVuY3Rpb24oYSl7cmV0dXJuIkl0
-ZXJhdGlvbk1hcmtlcigiK3RoaXMuYisiLCAiK0guRWoodGhpcy5hKSsiKSJ9fQpQLkdWLnByb3RvdHlw
-ZT17CmdsOmZ1bmN0aW9uKCl7dmFyIHM9dGhpcy5jCmlmKHM9PW51bGwpcmV0dXJuIHRoaXMuJHRpLmMu
-YSh0aGlzLmIpCnJldHVybiBzLmdsKCl9LApGOmZ1bmN0aW9uKCl7dmFyIHMscixxLHAsbyxuLG09dGhp
-cwpmb3Iocz1tLiR0aS5DKCJBbjwxPiIpOyEwOyl7cj1tLmMKaWYociE9bnVsbClpZihyLkYoKSlyZXR1
-cm4hMAplbHNlIG0uc1g5KG51bGwpCnE9ZnVuY3Rpb24oYSxiLGMpe3ZhciBsLGs9Ygp3aGlsZSh0cnVl
-KXRyeXtyZXR1cm4gYShrLGwpfWNhdGNoKGope2w9agprPWN9fShtLmEsMCwxKQppZihxIGluc3RhbmNl
-b2YgUC5GeSl7cD1xLmIKaWYocD09PTIpe289bS5kCmlmKG89PW51bGx8fG8ubGVuZ3RoPT09MCl7bS5z
-RUMobnVsbCkKcmV0dXJuITF9aWYoMD49by5sZW5ndGgpcmV0dXJuIEguT0gobywtMSkKbS5hPW8ucG9w
-KCkKY29udGludWV9ZWxzZXtyPXEuYQppZihwPT09Myl0aHJvdyByCmVsc2V7bj1zLmEoSi5JVChyKSkK
-aWYobiBpbnN0YW5jZW9mIFAuR1Ype3I9bS5kCmlmKHI9PW51bGwpcj1tLmQ9W10KQy5ObS5pKHIsbS5h
-KQptLmE9bi5hCmNvbnRpbnVlfWVsc2V7bS5zWDkobikKY29udGludWV9fX19ZWxzZXttLnNFQyhxKQpy
-ZXR1cm4hMH19cmV0dXJuITF9LApzRUM6ZnVuY3Rpb24oYSl7dGhpcy5iPXRoaXMuJHRpLkMoIjE/Iiku
-YShhKX0sCnNYOTpmdW5jdGlvbihhKXt0aGlzLmM9dGhpcy4kdGkuQygiQW48MT4/IikuYShhKX0sCiRp
-QW46MX0KUC5xNC5wcm90b3R5cGU9ewpnbTpmdW5jdGlvbihhKXtyZXR1cm4gbmV3IFAuR1YodGhpcy5h
-KCksdGhpcy4kdGkuQygiR1Y8MT4iKSl9fQpQLlBmLnByb3RvdHlwZT17CncwOmZ1bmN0aW9uKGEsYil7
-dmFyIHMKSC5jYihhLCJlcnJvciIsdC5LKQpzPXRoaXMuYQppZihzLmEhPT0wKXRocm93IEguYihQLlBW
-KCJGdXR1cmUgYWxyZWFkeSBjb21wbGV0ZWQiKSkKaWYoYj09bnVsbCliPVAudjAoYSkKcy5OayhhLGIp
-fSwKcG06ZnVuY3Rpb24oYSl7cmV0dXJuIHRoaXMudzAoYSxudWxsKX19ClAuWmYucHJvdG90eXBlPXsK
-YU06ZnVuY3Rpb24oYSxiKXt2YXIgcyxyPXRoaXMuJHRpCnIuQygiMS8/IikuYShiKQpzPXRoaXMuYQpp
-ZihzLmEhPT0wKXRocm93IEguYihQLlBWKCJGdXR1cmUgYWxyZWFkeSBjb21wbGV0ZWQiKSkKcy5YZihy
-LkMoIjEvIikuYShiKSl9fQpQLkZlLnByb3RvdHlwZT17CkhSOmZ1bmN0aW9uKGEpe2lmKCh0aGlzLmMm
-MTUpIT09NilyZXR1cm4hMApyZXR1cm4gdGhpcy5iLmIuYnYodC5hbC5hKHRoaXMuZCksYS5hLHQueSx0
-LkspfSwKS3c6ZnVuY3Rpb24oYSl7dmFyIHM9dGhpcy5lLHI9dC56LHE9dC5LLHA9dGhpcy4kdGkuQygi
-Mi8iKSxvPXRoaXMuYi5iCmlmKHQuYWcuYihzKSlyZXR1cm4gcC5hKG8ucnAocyxhLmEsYS5iLHIscSx0
-LmwpKQplbHNlIHJldHVybiBwLmEoby5idih0LmJJLmEocyksYS5hLHIscSkpfX0KUC52cy5wcm90b3R5
-cGU9ewpTcTpmdW5jdGlvbihhLGIsYyl7dmFyIHMscixxLHA9dGhpcy4kdGkKcC5LcShjKS5DKCIxLygy
-KSIpLmEoYSkKcz0kLlgzCmlmKHMhPT1DLk5VKXtjLkMoIkA8MC8+IikuS3EocC5jKS5DKCIxKDIpIiku
-YShhKQppZihiIT1udWxsKWI9UC5WSChiLHMpfXI9bmV3IFAudnMocyxjLkMoInZzPDA+IikpCnE9Yj09
-bnVsbD8xOjMKdGhpcy54ZihuZXcgUC5GZShyLHEsYSxiLHAuQygiQDwxPiIpLktxKGMpLkMoIkZlPDEs
-Mj4iKSkpCnJldHVybiByfSwKVzc6ZnVuY3Rpb24oYSxiKXtyZXR1cm4gdGhpcy5TcShhLG51bGwsYil9
-LApRZDpmdW5jdGlvbihhLGIsYyl7dmFyIHMscj10aGlzLiR0aQpyLktxKGMpLkMoIjEvKDIpIikuYShh
-KQpzPW5ldyBQLnZzKCQuWDMsYy5DKCJ2czwwPiIpKQp0aGlzLnhmKG5ldyBQLkZlKHMsMTksYSxiLHIu
-QygiQDwxPiIpLktxKGMpLkMoIkZlPDEsMj4iKSkpCnJldHVybiBzfSwKeGY6ZnVuY3Rpb24oYSl7dmFy
-IHMscj10aGlzLHE9ci5hCmlmKHE8PTEpe2EuYT10LkYuYShyLmMpCnIuYz1hfWVsc2V7aWYocT09PTIp
-e3M9dC5jLmEoci5jKQpxPXMuYQppZihxPDQpe3MueGYoYSkKcmV0dXJufXIuYT1xCnIuYz1zLmN9UC5U
-ayhudWxsLG51bGwsci5iLHQuTS5hKG5ldyBQLmRhKHIsYSkpKX19LApqUTpmdW5jdGlvbihhKXt2YXIg
-cyxyLHEscCxvLG4sbT10aGlzLGw9e30KbC5hPWEKaWYoYT09bnVsbClyZXR1cm4Kcz1tLmEKaWYoczw9
-MSl7cj10LkYuYShtLmMpCm0uYz1hCmlmKHIhPW51bGwpe3E9YS5hCmZvcihwPWE7cSE9bnVsbDtwPXEs
-cT1vKW89cS5hCnAuYT1yfX1lbHNle2lmKHM9PT0yKXtuPXQuYy5hKG0uYykKcz1uLmEKaWYoczw0KXtu
-LmpRKGEpCnJldHVybn1tLmE9cwptLmM9bi5jfWwuYT1tLk44KGEpClAuVGsobnVsbCxudWxsLG0uYix0
-Lk0uYShuZXcgUC5vUShsLG0pKSl9fSwKYWg6ZnVuY3Rpb24oKXt2YXIgcz10LkYuYSh0aGlzLmMpCnRo
-aXMuYz1udWxsCnJldHVybiB0aGlzLk44KHMpfSwKTjg6ZnVuY3Rpb24oYSl7dmFyIHMscixxCmZvcihz
-PWEscj1udWxsO3MhPW51bGw7cj1zLHM9cSl7cT1zLmEKcy5hPXJ9cmV0dXJuIHJ9LApISDpmdW5jdGlv
-bihhKXt2YXIgcyxyPXRoaXMscT1yLiR0aQpxLkMoIjEvIikuYShhKQppZihxLkMoImI4PDE+IikuYihh
-KSlpZihxLmIoYSkpUC5BOShhLHIpCmVsc2UgUC5rMyhhLHIpCmVsc2V7cz1yLmFoKCkKcS5jLmEoYSkK
-ci5hPTQKci5jPWEKUC5IWihyLHMpfX0sClgyOmZ1bmN0aW9uKGEpe3ZhciBzLHI9dGhpcwpyLiR0aS5j
-LmEoYSkKcz1yLmFoKCkKci5hPTQKci5jPWEKUC5IWihyLHMpfSwKWkw6ZnVuY3Rpb24oYSxiKXt2YXIg
-cyxyLHE9dGhpcwp0LmwuYShiKQpzPXEuYWgoKQpyPVAuVGwoYSxiKQpxLmE9OApxLmM9cgpQLkhaKHEs
-cyl9LApYZjpmdW5jdGlvbihhKXt2YXIgcz10aGlzLiR0aQpzLkMoIjEvIikuYShhKQppZihzLkMoImI4
-PDE+IikuYihhKSl7dGhpcy5jVShhKQpyZXR1cm59dGhpcy53VShzLmMuYShhKSl9LAp3VTpmdW5jdGlv
-bihhKXt2YXIgcz10aGlzCnMuJHRpLmMuYShhKQpzLmE9MQpQLlRrKG51bGwsbnVsbCxzLmIsdC5NLmEo
-bmV3IFAucnQocyxhKSkpfSwKY1U6ZnVuY3Rpb24oYSl7dmFyIHM9dGhpcyxyPXMuJHRpCnIuQygiYjg8
-MT4iKS5hKGEpCmlmKHIuYihhKSl7aWYoYS5hPT09OCl7cy5hPTEKUC5UayhudWxsLG51bGwscy5iLHQu
-TS5hKG5ldyBQLktGKHMsYSkpKX1lbHNlIFAuQTkoYSxzKQpyZXR1cm59UC5rMyhhLHMpfSwKTms6ZnVu
-Y3Rpb24oYSxiKXt0aGlzLmE9MQpQLlRrKG51bGwsbnVsbCx0aGlzLmIsdC5NLmEobmV3IFAuWkwodGhp
-cyxhLGIpKSl9LAokaWI4OjF9ClAuZGEucHJvdG90eXBlPXsKJDA6ZnVuY3Rpb24oKXtQLkhaKHRoaXMu
-YSx0aGlzLmIpfSwKJFM6MH0KUC5vUS5wcm90b3R5cGU9ewokMDpmdW5jdGlvbigpe1AuSFoodGhpcy5i
-LHRoaXMuYS5hKX0sCiRTOjB9ClAucFYucHJvdG90eXBlPXsKJDE6ZnVuY3Rpb24oYSl7dmFyIHM9dGhp
-cy5hCnMuYT0wCnMuSEgoYSl9LAokUzo5fQpQLlU3LnByb3RvdHlwZT17CiQyOmZ1bmN0aW9uKGEsYil7
-dGhpcy5hLlpMKGEsdC5sLmEoYikpfSwKJEM6IiQyIiwKJFI6MiwKJFM6Mjl9ClAudnIucHJvdG90eXBl
-PXsKJDA6ZnVuY3Rpb24oKXt0aGlzLmEuWkwodGhpcy5iLHRoaXMuYyl9LAokUzowfQpQLnJ0LnByb3Rv
-dHlwZT17CiQwOmZ1bmN0aW9uKCl7dGhpcy5hLlgyKHRoaXMuYil9LAokUzowfQpQLktGLnByb3RvdHlw
-ZT17CiQwOmZ1bmN0aW9uKCl7UC5BOSh0aGlzLmIsdGhpcy5hKX0sCiRTOjB9ClAuWkwucHJvdG90eXBl
-PXsKJDA6ZnVuY3Rpb24oKXt0aGlzLmEuWkwodGhpcy5iLHRoaXMuYyl9LAokUzowfQpQLlJULnByb3Rv
-dHlwZT17CiQwOmZ1bmN0aW9uKCl7dmFyIHMscixxLHAsbyxuLG09dGhpcyxsPW51bGwKdHJ5e3E9bS5h
-LmEKbD1xLmIuYi56eih0LmZPLmEocS5kKSx0LnopfWNhdGNoKHApe3M9SC5SdShwKQpyPUgudHMocCkK
-aWYobS5jKXtxPXQubi5hKG0uYi5hLmMpLmEKbz1zCm89cT09bnVsbD9vPT1udWxsOnE9PT1vCnE9b31l
-bHNlIHE9ITEKbz1tLmEKaWYocSlvLmM9dC5uLmEobS5iLmEuYykKZWxzZSBvLmM9UC5UbChzLHIpCm8u
-Yj0hMApyZXR1cm59aWYobCBpbnN0YW5jZW9mIFAudnMmJmwuYT49NCl7aWYobC5hPT09OCl7cT1tLmEK
-cS5jPXQubi5hKGwuYykKcS5iPSEwfXJldHVybn1pZih0LmQuYihsKSl7bj1tLmIuYQpxPW0uYQpxLmM9
-bC5XNyhuZXcgUC5qWihuKSx0LnopCnEuYj0hMX19LAokUzowfQpQLmpaLnByb3RvdHlwZT17CiQxOmZ1
-bmN0aW9uKGEpe3JldHVybiB0aGlzLmF9LAokUzozMn0KUC5ycS5wcm90b3R5cGU9ewokMDpmdW5jdGlv
-bigpe3ZhciBzLHIscSxwLG8sbixtLGwKdHJ5e3E9dGhpcy5hCnA9cS5hCm89cC4kdGkKbj1vLmMKbT1u
-LmEodGhpcy5iKQpxLmM9cC5iLmIuYnYoby5DKCIyLygxKSIpLmEocC5kKSxtLG8uQygiMi8iKSxuKX1j
-YXRjaChsKXtzPUguUnUobCkKcj1ILnRzKGwpCnE9dGhpcy5hCnEuYz1QLlRsKHMscikKcS5iPSEwfX0s
-CiRTOjB9ClAuUlcucHJvdG90eXBlPXsKJDA6ZnVuY3Rpb24oKXt2YXIgcyxyLHEscCxvLG4sbSxsLGs9
-dGhpcwp0cnl7cz10Lm4uYShrLmEuYS5jKQpwPWsuYgppZihILm9UKHAuYS5IUihzKSkmJnAuYS5lIT1u
-dWxsKXtwLmM9cC5hLkt3KHMpCnAuYj0hMX19Y2F0Y2gobyl7cj1ILlJ1KG8pCnE9SC50cyhvKQpwPXQu
-bi5hKGsuYS5hLmMpCm49cC5hCm09cgpsPWsuYgppZihuPT1udWxsP209PW51bGw6bj09PW0pbC5jPXAK
-ZWxzZSBsLmM9UC5UbChyLHEpCmwuYj0hMH19LAokUzowfQpQLk9NLnByb3RvdHlwZT17fQpQLnFoLnBy
-b3RvdHlwZT17CmdBOmZ1bmN0aW9uKGEpe3ZhciBzLHIscT10aGlzLHA9e30sbz1uZXcgUC52cygkLlgz
-LHQuZkopCnAuYT0wCnM9SC5MaChxKQpyPXMuQygifigxKT8iKS5hKG5ldyBQLkI1KHAscSkpCnQuWi5h
-KG5ldyBQLnVPKHAsbykpClcuSkUocS5hLHEuYixyLCExLHMuYykKcmV0dXJuIG99fQpQLkI1LnByb3Rv
-dHlwZT17CiQxOmZ1bmN0aW9uKGEpe0guTGgodGhpcy5iKS5jLmEoYSk7Kyt0aGlzLmEuYX0sCiRTOmZ1
-bmN0aW9uKCl7cmV0dXJuIEguTGgodGhpcy5iKS5DKCJ+KDEpIil9fQpQLnVPLnByb3RvdHlwZT17CiQw
-OmZ1bmN0aW9uKCl7dGhpcy5iLkhIKHRoaXMuYS5hKX0sCiRTOjB9ClAuTU8ucHJvdG90eXBlPXt9ClAu
-a1QucHJvdG90eXBlPXt9ClAueEkucHJvdG90eXBlPXt9ClAuQ3cucHJvdG90eXBlPXsKdzpmdW5jdGlv
-bihhKXtyZXR1cm4gSC5Faih0aGlzLmEpfSwKJGlYUzoxLApnSUk6ZnVuY3Rpb24oKXtyZXR1cm4gdGhp
-cy5ifX0KUC5tMC5wcm90b3R5cGU9eyRpUW06MX0KUC5wSy5wcm90b3R5cGU9ewokMDpmdW5jdGlvbigp
-e3ZhciBzPUguYih0aGlzLmEpCnMuc3RhY2s9Si5qKHRoaXMuYikKdGhyb3cgc30sCiRTOjB9ClAuSmku
-cHJvdG90eXBlPXsKYkg6ZnVuY3Rpb24oYSl7dmFyIHMscixxLHA9bnVsbAp0Lk0uYShhKQp0cnl7aWYo
-Qy5OVT09PSQuWDMpe2EuJDAoKQpyZXR1cm59UC5UOChwLHAsdGhpcyxhLHQuSCl9Y2F0Y2gocSl7cz1I
-LlJ1KHEpCnI9SC50cyhxKQpQLkwyKHAscCx0aGlzLHMsdC5sLmEocikpfX0sCkRsOmZ1bmN0aW9uKGEs
-YixjKXt2YXIgcyxyLHEscD1udWxsCmMuQygifigwKSIpLmEoYSkKYy5hKGIpCnRyeXtpZihDLk5VPT09
-JC5YMyl7YS4kMShiKQpyZXR1cm59UC55dihwLHAsdGhpcyxhLGIsdC5ILGMpfWNhdGNoKHEpe3M9SC5S
-dShxKQpyPUgudHMocSkKUC5MMihwLHAsdGhpcyxzLHQubC5hKHIpKX19LApSVDpmdW5jdGlvbihhLGIp
-e3JldHVybiBuZXcgUC5oaih0aGlzLGIuQygiMCgpIikuYShhKSxiKX0sCkdZOmZ1bmN0aW9uKGEpe3Jl
-dHVybiBuZXcgUC5WcCh0aGlzLHQuTS5hKGEpKX0sClB5OmZ1bmN0aW9uKGEsYil7cmV0dXJuIG5ldyBQ
-Lk9SKHRoaXMsYi5DKCJ+KDApIikuYShhKSxiKX0sCnE6ZnVuY3Rpb24oYSxiKXtyZXR1cm4gbnVsbH0s
-Cnp6OmZ1bmN0aW9uKGEsYil7Yi5DKCIwKCkiKS5hKGEpCmlmKCQuWDM9PT1DLk5VKXJldHVybiBhLiQw
-KCkKcmV0dXJuIFAuVDgobnVsbCxudWxsLHRoaXMsYSxiKX0sCmJ2OmZ1bmN0aW9uKGEsYixjLGQpe2Mu
-QygiQDwwPiIpLktxKGQpLkMoIjEoMikiKS5hKGEpCmQuYShiKQppZigkLlgzPT09Qy5OVSlyZXR1cm4g
-YS4kMShiKQpyZXR1cm4gUC55dihudWxsLG51bGwsdGhpcyxhLGIsYyxkKX0sCnJwOmZ1bmN0aW9uKGEs
-YixjLGQsZSxmKXtkLkMoIkA8MD4iKS5LcShlKS5LcShmKS5DKCIxKDIsMykiKS5hKGEpCmUuYShiKQpm
-LmEoYykKaWYoJC5YMz09PUMuTlUpcmV0dXJuIGEuJDIoYixjKQpyZXR1cm4gUC5ReChudWxsLG51bGws
-dGhpcyxhLGIsYyxkLGUsZil9LApMajpmdW5jdGlvbihhLGIsYyxkKXtyZXR1cm4gYi5DKCJAPDA+Iiku
-S3EoYykuS3EoZCkuQygiMSgyLDMpIikuYShhKX19ClAuaGoucHJvdG90eXBlPXsKJDA6ZnVuY3Rpb24o
-KXtyZXR1cm4gdGhpcy5hLnp6KHRoaXMuYix0aGlzLmMpfSwKJFM6ZnVuY3Rpb24oKXtyZXR1cm4gdGhp
-cy5jLkMoIjAoKSIpfX0KUC5WcC5wcm90b3R5cGU9ewokMDpmdW5jdGlvbigpe3JldHVybiB0aGlzLmEu
-YkgodGhpcy5iKX0sCiRTOjB9ClAuT1IucHJvdG90eXBlPXsKJDE6ZnVuY3Rpb24oYSl7dmFyIHM9dGhp
-cy5jCnJldHVybiB0aGlzLmEuRGwodGhpcy5iLHMuYShhKSxzKX0sCiRTOmZ1bmN0aW9uKCl7cmV0dXJu
-IHRoaXMuYy5DKCJ+KDApIil9fQpQLmI2LnByb3RvdHlwZT17CmdtOmZ1bmN0aW9uKGEpe3ZhciBzPXRo
-aXMscj1uZXcgUC5sbShzLHMucixILkxoKHMpLkMoImxtPDE+IikpCnIuYz1zLmUKcmV0dXJuIHJ9LApn
-QTpmdW5jdGlvbihhKXtyZXR1cm4gdGhpcy5hfSwKZ2wwOmZ1bmN0aW9uKGEpe3JldHVybiB0aGlzLmE9
-PT0wfSwKZ29yOmZ1bmN0aW9uKGEpe3JldHVybiB0aGlzLmEhPT0wfSwKdGc6ZnVuY3Rpb24oYSxiKXt2
-YXIgcyxyCmlmKHR5cGVvZiBiPT0ic3RyaW5nIiYmYiE9PSJfX3Byb3RvX18iKXtzPXRoaXMuYgppZihz
-PT1udWxsKXJldHVybiExCnJldHVybiB0LmUuYShzW2JdKSE9bnVsbH1lbHNle3I9dGhpcy5QUihiKQpy
-ZXR1cm4gcn19LApQUjpmdW5jdGlvbihhKXt2YXIgcz10aGlzLmQKaWYocz09bnVsbClyZXR1cm4hMQpy
-ZXR1cm4gdGhpcy5ERihzW3RoaXMuTihhKV0sYSk+PTB9LAppOmZ1bmN0aW9uKGEsYil7dmFyIHMscixx
-PXRoaXMKSC5MaChxKS5jLmEoYikKaWYodHlwZW9mIGI9PSJzdHJpbmciJiZiIT09Il9fcHJvdG9fXyIp
-e3M9cS5iCnJldHVybiBxLmJRKHM9PW51bGw/cS5iPVAuVDIoKTpzLGIpfWVsc2UgaWYodHlwZW9mIGI9
-PSJudW1iZXIiJiYoYiYxMDczNzQxODIzKT09PWIpe3I9cS5jCnJldHVybiBxLmJRKHI9PW51bGw/cS5j
-PVAuVDIoKTpyLGIpfWVsc2UgcmV0dXJuIHEuQjcoYil9LApCNzpmdW5jdGlvbihhKXt2YXIgcyxyLHEs
-cD10aGlzCkguTGgocCkuYy5hKGEpCnM9cC5kCmlmKHM9PW51bGwpcz1wLmQ9UC5UMigpCnI9cC5OKGEp
-CnE9c1tyXQppZihxPT1udWxsKXNbcl09W3AueW8oYSldCmVsc2V7aWYocC5ERihxLGEpPj0wKXJldHVy
-biExCnEucHVzaChwLnlvKGEpKX1yZXR1cm4hMH0sClI6ZnVuY3Rpb24oYSxiKXt2YXIgcz10aGlzCmlm
-KHR5cGVvZiBiPT0ic3RyaW5nIiYmYiE9PSJfX3Byb3RvX18iKXJldHVybiBzLkwocy5iLGIpCmVsc2Ug
-aWYodHlwZW9mIGI9PSJudW1iZXIiJiYoYiYxMDczNzQxODIzKT09PWIpcmV0dXJuIHMuTChzLmMsYikK
-ZWxzZSByZXR1cm4gcy5xZyhiKX0sCnFnOmZ1bmN0aW9uKGEpe3ZhciBzLHIscSxwLG89dGhpcyxuPW8u
-ZAppZihuPT1udWxsKXJldHVybiExCnM9by5OKGEpCnI9bltzXQpxPW8uREYocixhKQppZihxPDApcmV0
-dXJuITEKcD1yLnNwbGljZShxLDEpWzBdCmlmKDA9PT1yLmxlbmd0aClkZWxldGUgbltzXQpvLkdTKHAp
-CnJldHVybiEwfSwKYlE6ZnVuY3Rpb24oYSxiKXtILkxoKHRoaXMpLmMuYShiKQppZih0LmUuYShhW2Jd
-KSE9bnVsbClyZXR1cm4hMQphW2JdPXRoaXMueW8oYikKcmV0dXJuITB9LApMOmZ1bmN0aW9uKGEsYil7
-dmFyIHMKaWYoYT09bnVsbClyZXR1cm4hMQpzPXQuZS5hKGFbYl0pCmlmKHM9PW51bGwpcmV0dXJuITEK
-dGhpcy5HUyhzKQpkZWxldGUgYVtiXQpyZXR1cm4hMH0sClM6ZnVuY3Rpb24oKXt0aGlzLnI9dGhpcy5y
-KzEmMTA3Mzc0MTgyM30sCnlvOmZ1bmN0aW9uKGEpe3ZhciBzLHI9dGhpcyxxPW5ldyBQLmJuKEguTGgo
-cikuYy5hKGEpKQppZihyLmU9PW51bGwpci5lPXIuZj1xCmVsc2V7cz1yLmYKcy50b1N0cmluZwpxLmM9
-cwpyLmY9cy5iPXF9KytyLmEKci5TKCkKcmV0dXJuIHF9LApHUzpmdW5jdGlvbihhKXt2YXIgcz10aGlz
-LHI9YS5jLHE9YS5iCmlmKHI9PW51bGwpcy5lPXEKZWxzZSByLmI9cQppZihxPT1udWxsKXMuZj1yCmVs
-c2UgcS5jPXI7LS1zLmEKcy5TKCl9LApOOmZ1bmN0aW9uKGEpe3JldHVybiBKLmhmKGEpJjEwNzM3NDE4
-MjN9LApERjpmdW5jdGlvbihhLGIpe3ZhciBzLHIKaWYoYT09bnVsbClyZXR1cm4tMQpzPWEubGVuZ3Ro
-CmZvcihyPTA7cjxzOysrcilpZihKLlJNKGFbcl0uYSxiKSlyZXR1cm4gcgpyZXR1cm4tMX19ClAuYm4u
-cHJvdG90eXBlPXt9ClAubG0ucHJvdG90eXBlPXsKZ2w6ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5kfSwK
-RjpmdW5jdGlvbigpe3ZhciBzPXRoaXMscj1zLmMscT1zLmEKaWYocy5iIT09cS5yKXRocm93IEguYihQ
-LmE0KHEpKQplbHNlIGlmKHI9PW51bGwpe3Muc2oobnVsbCkKcmV0dXJuITF9ZWxzZXtzLnNqKHMuJHRp
-LkMoIjE/IikuYShyLmEpKQpzLmM9ci5iCnJldHVybiEwfX0sCnNqOmZ1bmN0aW9uKGEpe3RoaXMuZD10
-aGlzLiR0aS5DKCIxPyIpLmEoYSl9LAokaUFuOjF9ClAubVcucHJvdG90eXBlPXt9ClAudXkucHJvdG90
-eXBlPXskaWJROjEsJGljWDoxLCRpek06MX0KUC5sRC5wcm90b3R5cGU9ewpnbTpmdW5jdGlvbihhKXty
-ZXR1cm4gbmV3IEguYTcoYSx0aGlzLmdBKGEpLEgueihhKS5DKCJhNzxsRC5FPiIpKX0sCkU6ZnVuY3Rp
-b24oYSxiKXtyZXR1cm4gdGhpcy5xKGEsYil9LApLOmZ1bmN0aW9uKGEsYil7dmFyIHMscgpILnooYSku
-QygifihsRC5FKSIpLmEoYikKcz10aGlzLmdBKGEpCmZvcihyPTA7cjxzOysrcil7Yi4kMSh0aGlzLnEo
-YSxyKSkKaWYocyE9PXRoaXMuZ0EoYSkpdGhyb3cgSC5iKFAuYTQoYSkpfX0sCmdsMDpmdW5jdGlvbihh
-KXtyZXR1cm4gdGhpcy5nQShhKT09PTB9LApnb3I6ZnVuY3Rpb24oYSl7cmV0dXJuIXRoaXMuZ2wwKGEp
-fSwKRTI6ZnVuY3Rpb24oYSxiLGMpe3ZhciBzPUgueihhKQpyZXR1cm4gbmV3IEgubEooYSxzLktxKGMp
-LkMoIjEobEQuRSkiKS5hKGIpLHMuQygiQDxsRC5FPiIpLktxKGMpLkMoImxKPDEsMj4iKSl9LAplUjpm
-dW5jdGlvbihhLGIpe3JldHVybiBILnFDKGEsYixudWxsLEgueihhKS5DKCJsRC5FIikpfSwKZHI6ZnVu
-Y3Rpb24oYSxiKXtyZXR1cm4gbmV3IEgualYoYSxILnooYSkuQygiQDxsRC5FPiIpLktxKGIpLkMoImpW
-PDEsMj4iKSl9LApkdTpmdW5jdGlvbihhLGIsYyxkKXt2YXIgcwpILnooYSkuQygibEQuRT8iKS5hKGQp
-ClAuakIoYixjLHRoaXMuZ0EoYSkpCmZvcihzPWI7czxjOysrcyl0aGlzLlkoYSxzLGQpfSwKdzpmdW5j
-dGlvbihhKXtyZXR1cm4gUC5XRShhLCJbIiwiXSIpfX0KUC5pbC5wcm90b3R5cGU9e30KUC5yYS5wcm90
-b3R5cGU9ewokMjpmdW5jdGlvbihhLGIpe3ZhciBzLHI9dGhpcy5hCmlmKCFyLmEpdGhpcy5iLmErPSIs
-ICIKci5hPSExCnI9dGhpcy5iCnM9ci5hKz1ILkVqKGEpCnIuYT1zKyI6ICIKci5hKz1ILkVqKGIpfSwK
-JFM6MTB9ClAuWWsucHJvdG90eXBlPXsKSzpmdW5jdGlvbihhLGIpe3ZhciBzLHIKSC5MaCh0aGlzKS5D
-KCJ+KFlrLkssWWsuVikiKS5hKGIpCmZvcihzPUouSVQodGhpcy5nVigpKTtzLkYoKTspe3I9cy5nbCgp
-CmIuJDIocix0aGlzLnEoMCxyKSl9fSwKZ1B1OmZ1bmN0aW9uKGEpe3JldHVybiBKLk0xKHRoaXMuZ1Yo
-KSxuZXcgUC55USh0aGlzKSxILkxoKHRoaXMpLkMoIk4zPFlrLkssWWsuVj4iKSl9LAp4NDpmdW5jdGlv
-bihhKXtyZXR1cm4gSi56bCh0aGlzLmdWKCksYSl9LApnQTpmdW5jdGlvbihhKXtyZXR1cm4gSi5IbSh0
-aGlzLmdWKCkpfSwKZ2wwOmZ1bmN0aW9uKGEpe3JldHVybiBKLnVVKHRoaXMuZ1YoKSl9LAp3OmZ1bmN0
-aW9uKGEpe3JldHVybiBQLm5PKHRoaXMpfSwKJGlaMDoxfQpQLnlRLnByb3RvdHlwZT17CiQxOmZ1bmN0
-aW9uKGEpe3ZhciBzPXRoaXMuYSxyPUguTGgocykKci5DKCJZay5LIikuYShhKQpyZXR1cm4gbmV3IFAu
-TjMoYSxzLnEoMCxhKSxyLkMoIkA8WWsuSz4iKS5LcShyLkMoIllrLlYiKSkuQygiTjM8MSwyPiIpKX0s
-CiRTOmZ1bmN0aW9uKCl7cmV0dXJuIEguTGgodGhpcy5hKS5DKCJOMzxZay5LLFlrLlY+KFlrLkspIil9
-fQpQLktQLnByb3RvdHlwZT17Clk6ZnVuY3Rpb24oYSxiLGMpe3ZhciBzPUguTGgodGhpcykKcy5jLmEo
-YikKcy5RWzFdLmEoYykKdGhyb3cgSC5iKFAuTDQoIkNhbm5vdCBtb2RpZnkgdW5tb2RpZmlhYmxlIG1h
-cCIpKX19ClAuUG4ucHJvdG90eXBlPXsKcTpmdW5jdGlvbihhLGIpe3JldHVybiB0aGlzLmEucSgwLGIp
-fSwKWTpmdW5jdGlvbihhLGIsYyl7dmFyIHM9SC5MaCh0aGlzKQp0aGlzLmEuWSgwLHMuYy5hKGIpLHMu
-UVsxXS5hKGMpKX0sCng0OmZ1bmN0aW9uKGEpe3JldHVybiB0aGlzLmEueDQoYSl9LApLOmZ1bmN0aW9u
-KGEsYil7dGhpcy5hLksoMCxILkxoKHRoaXMpLkMoIn4oMSwyKSIpLmEoYikpfSwKZ2wwOmZ1bmN0aW9u
-KGEpe3ZhciBzPXRoaXMuYQpyZXR1cm4gcy5nbDAocyl9LApnQTpmdW5jdGlvbihhKXt2YXIgcz10aGlz
-LmEKcmV0dXJuIHMuZ0Eocyl9LAp3OmZ1bmN0aW9uKGEpe3JldHVybiBKLmoodGhpcy5hKX0sCmdQdTpm
-dW5jdGlvbihhKXt2YXIgcz10aGlzLmEKcmV0dXJuIHMuZ1B1KHMpfSwKJGlaMDoxfQpQLkdqLnByb3Rv
-dHlwZT17fQpQLmxmLnByb3RvdHlwZT17CmdsMDpmdW5jdGlvbihhKXtyZXR1cm4gdGhpcy5nQSh0aGlz
-KT09PTB9LApnb3I6ZnVuY3Rpb24oYSl7cmV0dXJuIHRoaXMuZ0EodGhpcykhPT0wfSwKRlY6ZnVuY3Rp
-b24oYSxiKXt2YXIgcwpmb3Iocz1KLklUKEguTGgodGhpcykuQygiY1g8bGYuRT4iKS5hKGIpKTtzLkYo
-KTspdGhpcy5pKDAscy5nbCgpKX0sCnc6ZnVuY3Rpb24oYSl7cmV0dXJuIFAuV0UodGhpcywieyIsIn0i
-KX0sCkg6ZnVuY3Rpb24oYSxiKXt2YXIgcyxyPXRoaXMuZ20odGhpcykKaWYoIXIuRigpKXJldHVybiIi
-CmlmKGI9PT0iIil7cz0iIgpkbyBzKz1ILkVqKHIuZCkKd2hpbGUoci5GKCkpfWVsc2V7cz1ILkVqKHIu
-ZCkKZm9yKDtyLkYoKTspcz1zK2IrSC5FaihyLmQpfXJldHVybiBzLmNoYXJDb2RlQXQoMCk9PTA/czpz
-fSwKZVI6ZnVuY3Rpb24oYSxiKXtyZXR1cm4gSC5iSyh0aGlzLGIsSC5MaCh0aGlzKS5DKCJsZi5FIikp
-fSwKRTpmdW5jdGlvbihhLGIpe3ZhciBzLHIscSxwPSJpbmRleCIKSC5jYihiLHAsdC5TKQpQLmsxKGIs
-cCkKZm9yKHM9dGhpcy5nbSh0aGlzKSxyPTA7cy5GKCk7KXtxPXMuZAppZihiPT09cilyZXR1cm4gcTsr
-K3J9dGhyb3cgSC5iKFAuQ2YoYix0aGlzLHAsbnVsbCxyKSl9fQpQLlZqLnByb3RvdHlwZT17JGliUTox
-LCRpY1g6MSwkaXh1OjF9ClAuWHYucHJvdG90eXBlPXskaWJROjEsJGljWDoxLCRpeHU6MX0KUC5uWS5w
-cm90b3R5cGU9e30KUC5XWS5wcm90b3R5cGU9e30KUC5SVS5wcm90b3R5cGU9e30KUC5wUi5wcm90b3R5
-cGU9e30KUC51dy5wcm90b3R5cGU9ewpxOmZ1bmN0aW9uKGEsYil7dmFyIHMscj10aGlzLmIKaWYocj09
-bnVsbClyZXR1cm4gdGhpcy5jLnEoMCxiKQplbHNlIGlmKHR5cGVvZiBiIT0ic3RyaW5nIilyZXR1cm4g
-bnVsbAplbHNle3M9cltiXQpyZXR1cm4gdHlwZW9mIHM9PSJ1bmRlZmluZWQiP3RoaXMuZmIoYik6c319
-LApnQTpmdW5jdGlvbihhKXtyZXR1cm4gdGhpcy5iPT1udWxsP3RoaXMuYy5hOnRoaXMuQ2YoKS5sZW5n
-dGh9LApnbDA6ZnVuY3Rpb24oYSl7cmV0dXJuIHRoaXMuZ0EodGhpcyk9PT0wfSwKZ1Y6ZnVuY3Rpb24o
-KXtpZih0aGlzLmI9PW51bGwpe3ZhciBzPXRoaXMuYwpyZXR1cm4gbmV3IEguaTUocyxILkxoKHMpLkMo
-Imk1PDE+IikpfXJldHVybiBuZXcgUC5pOCh0aGlzKX0sClk6ZnVuY3Rpb24oYSxiLGMpe3ZhciBzLHIs
-cT10aGlzCmlmKHEuYj09bnVsbClxLmMuWSgwLGIsYykKZWxzZSBpZihxLng0KGIpKXtzPXEuYgpzW2Jd
-PWMKcj1xLmEKaWYocj09bnVsbD9zIT1udWxsOnIhPT1zKXJbYl09bnVsbH1lbHNlIHEuWEsoKS5ZKDAs
-YixjKX0sCng0OmZ1bmN0aW9uKGEpe2lmKHRoaXMuYj09bnVsbClyZXR1cm4gdGhpcy5jLng0KGEpCnJl
-dHVybiBPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwodGhpcy5hLGEpfSwKSzpmdW5j
-dGlvbihhLGIpe3ZhciBzLHIscSxwLG89dGhpcwp0LmNBLmEoYikKaWYoby5iPT1udWxsKXJldHVybiBv
-LmMuSygwLGIpCnM9by5DZigpCmZvcihyPTA7cjxzLmxlbmd0aDsrK3Ipe3E9c1tyXQpwPW8uYltxXQpp
-Zih0eXBlb2YgcD09InVuZGVmaW5lZCIpe3A9UC5RZShvLmFbcV0pCm8uYltxXT1wfWIuJDIocSxwKQpp
-ZihzIT09by5jKXRocm93IEguYihQLmE0KG8pKX19LApDZjpmdW5jdGlvbigpe3ZhciBzPXQuYk0uYSh0
-aGlzLmMpCmlmKHM9PW51bGwpcz10aGlzLmM9SC5WTShPYmplY3Qua2V5cyh0aGlzLmEpLHQucykKcmV0
-dXJuIHN9LApYSzpmdW5jdGlvbigpe3ZhciBzLHIscSxwLG8sbj10aGlzCmlmKG4uYj09bnVsbClyZXR1
-cm4gbi5jCnM9UC5GbCh0Lk4sdC56KQpyPW4uQ2YoKQpmb3IocT0wO3A9ci5sZW5ndGgscTxwOysrcSl7
-bz1yW3FdCnMuWSgwLG8sbi5xKDAsbykpfWlmKHA9PT0wKUMuTm0uaShyLCIiKQplbHNlIEMuTm0uc0Eo
-ciwwKQpuLmE9bi5iPW51bGwKcmV0dXJuIG4uYz1zfSwKZmI6ZnVuY3Rpb24oYSl7dmFyIHMKaWYoIU9i
-amVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbCh0aGlzLmEsYSkpcmV0dXJuIG51bGwKcz1Q
-LlFlKHRoaXMuYVthXSkKcmV0dXJuIHRoaXMuYlthXT1zfX0KUC5pOC5wcm90b3R5cGU9ewpnQTpmdW5j
-dGlvbihhKXt2YXIgcz10aGlzLmEKcmV0dXJuIHMuZ0Eocyl9LApFOmZ1bmN0aW9uKGEsYil7dmFyIHM9
-dGhpcy5hCmlmKHMuYj09bnVsbClzPXMuZ1YoKS5FKDAsYikKZWxzZXtzPXMuQ2YoKQppZihiPDB8fGI+
-PXMubGVuZ3RoKXJldHVybiBILk9IKHMsYikKcz1zW2JdfXJldHVybiBzfSwKZ206ZnVuY3Rpb24oYSl7
-dmFyIHM9dGhpcy5hCmlmKHMuYj09bnVsbCl7cz1zLmdWKCkKcz1zLmdtKHMpfWVsc2V7cz1zLkNmKCkK
-cz1uZXcgSi5tMShzLHMubGVuZ3RoLEgudDYocykuQygibTE8MT4iKSl9cmV0dXJuIHN9LAp0ZzpmdW5j
-dGlvbihhLGIpe3JldHVybiB0aGlzLmEueDQoYil9fQpQLnBnLnByb3RvdHlwZT17CiQwOmZ1bmN0aW9u
-KCl7dmFyIHMscgp0cnl7cz1uZXcgVGV4dERlY29kZXIoInV0Zi04Iix7ZmF0YWw6dHJ1ZX0pCnJldHVy
-biBzfWNhdGNoKHIpe0guUnUocil9cmV0dXJuIG51bGx9LAokUzoxMX0KUC5jMi5wcm90b3R5cGU9ewok
-MDpmdW5jdGlvbigpe3ZhciBzLHIKdHJ5e3M9bmV3IFRleHREZWNvZGVyKCJ1dGYtOCIse2ZhdGFsOmZh
-bHNlfSkKcmV0dXJuIHN9Y2F0Y2gocil7SC5SdShyKX1yZXR1cm4gbnVsbH0sCiRTOjExfQpQLkNWLnBy
-b3RvdHlwZT17CnlyOmZ1bmN0aW9uKGEwLGExLGEyKXt2YXIgcyxyLHEscCxvLG4sbSxsLGssaixpLGgs
-ZyxmLGUsZCxjLGIsYT0iSW52YWxpZCBiYXNlNjQgZW5jb2RpbmcgbGVuZ3RoICIKYTI9UC5qQihhMSxh
-MixhMC5sZW5ndGgpCnM9JC5WNygpCmZvcihyPWExLHE9cixwPW51bGwsbz0tMSxuPS0xLG09MDtyPGEy
-O3I9bCl7bD1yKzEKaz1DLnhCLlcoYTAscikKaWYoaz09PTM3KXtqPWwrMgppZihqPD1hMil7aT1ILm9v
-KEMueEIuVyhhMCxsKSkKaD1ILm9vKEMueEIuVyhhMCxsKzEpKQpnPWkqMTYraC0oaCYyNTYpCmlmKGc9
-PT0zNylnPS0xCmw9an1lbHNlIGc9LTF9ZWxzZSBnPWsKaWYoMDw9ZyYmZzw9MTI3KXtpZihnPDB8fGc+
-PXMubGVuZ3RoKXJldHVybiBILk9IKHMsZykKZj1zW2ddCmlmKGY+PTApe2c9Qy54Qi5PMigiQUJDREVG
-R0hJSktMTU5PUFFSU1RVVldYWVphYmNkZWZnaGlqa2xtbm9wcXJzdHV2d3h5ejAxMjM0NTY3ODkrLyIs
-ZikKaWYoZz09PWspY29udGludWUKaz1nfWVsc2V7aWYoZj09PS0xKXtpZihvPDApe2U9cD09bnVsbD9u
-dWxsOnAuYS5sZW5ndGgKaWYoZT09bnVsbCllPTAKbz1lKyhyLXEpCm49cn0rK20KaWYoaz09PTYxKWNv
-bnRpbnVlfWs9Z31pZihmIT09LTIpe2lmKHA9PW51bGwpe3A9bmV3IFAuUm4oIiIpCmU9cH1lbHNlIGU9
-cAplLmErPUMueEIuTmooYTAscSxyKQplLmErPUguTHcoaykKcT1sCmNvbnRpbnVlfX10aHJvdyBILmIo
-UC5ycigiSW52YWxpZCBiYXNlNjQgZGF0YSIsYTAscikpfWlmKHAhPW51bGwpe2U9cC5hKz1DLnhCLk5q
-KGEwLHEsYTIpCmQ9ZS5sZW5ndGgKaWYobz49MClQLnhNKGEwLG4sYTIsbyxtLGQpCmVsc2V7Yz1DLmpu
-LnpZKGQtMSw0KSsxCmlmKGM9PT0xKXRocm93IEguYihQLnJyKGEsYTAsYTIpKQpmb3IoO2M8NDspe2Ur
-PSI9IgpwLmE9ZTsrK2N9fWU9cC5hCnJldHVybiBDLnhCLmk3KGEwLGExLGEyLGUuY2hhckNvZGVBdCgw
-KT09MD9lOmUpfWI9YTItYTEKaWYobz49MClQLnhNKGEwLG4sYTIsbyxtLGIpCmVsc2V7Yz1DLmpuLnpZ
-KGIsNCkKaWYoYz09PTEpdGhyb3cgSC5iKFAucnIoYSxhMCxhMikpCmlmKGM+MSlhMD1DLnhCLmk3KGEw
-LGEyLGEyLGM9PT0yPyI9PSI6Ij0iKX1yZXR1cm4gYTB9fQpQLlU4LnByb3RvdHlwZT17fQpQLlVrLnBy
-b3RvdHlwZT17fQpQLndJLnByb3RvdHlwZT17fQpQLlppLnByb3RvdHlwZT17fQpQLlVkLnByb3RvdHlw
-ZT17Cnc6ZnVuY3Rpb24oYSl7dmFyIHM9UC5wKHRoaXMuYSkKcmV0dXJuKHRoaXMuYiE9bnVsbD8iQ29u
-dmVydGluZyBvYmplY3QgdG8gYW4gZW5jb2RhYmxlIG9iamVjdCBmYWlsZWQ6IjoiQ29udmVydGluZyBv
-YmplY3QgZGlkIG5vdCByZXR1cm4gYW4gZW5jb2RhYmxlIG9iamVjdDoiKSsiICIrc319ClAuSzgucHJv
-dG90eXBlPXsKdzpmdW5jdGlvbihhKXtyZXR1cm4iQ3ljbGljIGVycm9yIGluIEpTT04gc3RyaW5naWZ5
-In19ClAuYnkucHJvdG90eXBlPXsKcFc6ZnVuY3Rpb24oYSxiLGMpe3ZhciBzCnQuZlYuYShjKQpzPVAu
-QlMoYix0aGlzLmdIZSgpLmEpCnJldHVybiBzfSwKT0I6ZnVuY3Rpb24oYSxiKXt2YXIgcwp0LmRBLmEo
-YikKcz1QLnVYKGEsdGhpcy5nWkUoKS5iLG51bGwpCnJldHVybiBzfSwKZ1pFOmZ1bmN0aW9uKCl7cmV0
-dXJuIEMublh9LApnSGU6ZnVuY3Rpb24oKXtyZXR1cm4gQy5BM319ClAub2oucHJvdG90eXBlPXt9ClAu
-TXgucHJvdG90eXBlPXt9ClAuU2gucHJvdG90eXBlPXsKdnA6ZnVuY3Rpb24oYSl7dmFyIHMscixxLHAs
-byxuLG0sbD1hLmxlbmd0aApmb3Iocz1KLnJZKGEpLHI9dGhpcy5jLHE9MCxwPTA7cDxsOysrcCl7bz1z
-LlcoYSxwKQppZihvPjkyKXtpZihvPj01NTI5Nil7bj1vJjY0NTEyCmlmKG49PT01NTI5Nil7bT1wKzEK
-bT0hKG08bCYmKEMueEIuVyhhLG0pJjY0NTEyKT09PTU2MzIwKX1lbHNlIG09ITEKaWYoIW0paWYobj09
-PTU2MzIwKXtuPXAtMQpuPSEobj49MCYmKEMueEIuTzIoYSxuKSY2NDUxMik9PT01NTI5Nil9ZWxzZSBu
-PSExCmVsc2Ugbj0hMAppZihuKXtpZihwPnEpci5hKz1DLnhCLk5qKGEscSxwKQpxPXArMQpyLmErPUgu
-THcoOTIpCnIuYSs9SC5MdygxMTcpCnIuYSs9SC5MdygxMDApCm49bz4+PjgmMTUKci5hKz1ILkx3KG48
-MTA/NDgrbjo4NytuKQpuPW8+Pj40JjE1CnIuYSs9SC5MdyhuPDEwPzQ4K246ODcrbikKbj1vJjE1CnIu
-YSs9SC5MdyhuPDEwPzQ4K246ODcrbil9fWNvbnRpbnVlfWlmKG88MzIpe2lmKHA+cSlyLmErPUMueEIu
-TmooYSxxLHApCnE9cCsxCnIuYSs9SC5Mdyg5MikKc3dpdGNoKG8pe2Nhc2UgODpyLmErPUguTHcoOTgp
-CmJyZWFrCmNhc2UgOTpyLmErPUguTHcoMTE2KQpicmVhawpjYXNlIDEwOnIuYSs9SC5MdygxMTApCmJy
-ZWFrCmNhc2UgMTI6ci5hKz1ILkx3KDEwMikKYnJlYWsKY2FzZSAxMzpyLmErPUguTHcoMTE0KQpicmVh
-awpkZWZhdWx0OnIuYSs9SC5MdygxMTcpCnIuYSs9SC5Mdyg0OCkKci5hKz1ILkx3KDQ4KQpuPW8+Pj40
-JjE1CnIuYSs9SC5MdyhuPDEwPzQ4K246ODcrbikKbj1vJjE1CnIuYSs9SC5MdyhuPDEwPzQ4K246ODcr
-bikKYnJlYWt9fWVsc2UgaWYobz09PTM0fHxvPT09OTIpe2lmKHA+cSlyLmErPUMueEIuTmooYSxxLHAp
-CnE9cCsxCnIuYSs9SC5Mdyg5MikKci5hKz1ILkx3KG8pfX1pZihxPT09MClyLmErPUguRWooYSkKZWxz
-ZSBpZihxPGwpci5hKz1zLk5qKGEscSxsKX0sCkpuOmZ1bmN0aW9uKGEpe3ZhciBzLHIscSxwCmZvcihz
-PXRoaXMuYSxyPXMubGVuZ3RoLHE9MDtxPHI7KytxKXtwPXNbcV0KaWYoYT09bnVsbD9wPT1udWxsOmE9
-PT1wKXRocm93IEguYihuZXcgUC5LOChhLG51bGwpKX1DLk5tLmkocyxhKX0sCmlVOmZ1bmN0aW9uKGEp
-e3ZhciBzLHIscSxwLG89dGhpcwppZihvLnRNKGEpKXJldHVybgpvLkpuKGEpCnRyeXtzPW8uYi4kMShh
-KQppZighby50TShzKSl7cT1QLkd5KGEsbnVsbCxvLmdWSygpKQp0aHJvdyBILmIocSl9cT1vLmEKaWYo
-MD49cS5sZW5ndGgpcmV0dXJuIEguT0gocSwtMSkKcS5wb3AoKX1jYXRjaChwKXtyPUguUnUocCkKcT1Q
-Lkd5KGEscixvLmdWSygpKQp0aHJvdyBILmIocSl9fSwKdE06ZnVuY3Rpb24oYSl7dmFyIHMscixxPXRo
-aXMKaWYodHlwZW9mIGE9PSJudW1iZXIiKXtpZighaXNGaW5pdGUoYSkpcmV0dXJuITEKcS5jLmErPUMu
-Q0QudyhhKQpyZXR1cm4hMH1lbHNlIGlmKGE9PT0hMCl7cS5jLmErPSJ0cnVlIgpyZXR1cm4hMH1lbHNl
-IGlmKGE9PT0hMSl7cS5jLmErPSJmYWxzZSIKcmV0dXJuITB9ZWxzZSBpZihhPT1udWxsKXtxLmMuYSs9
-Im51bGwiCnJldHVybiEwfWVsc2UgaWYodHlwZW9mIGE9PSJzdHJpbmciKXtzPXEuYwpzLmErPSciJwpx
-LnZwKGEpCnMuYSs9JyInCnJldHVybiEwfWVsc2UgaWYodC5qLmIoYSkpe3EuSm4oYSkKcS5sSyhhKQpz
-PXEuYQppZigwPj1zLmxlbmd0aClyZXR1cm4gSC5PSChzLC0xKQpzLnBvcCgpCnJldHVybiEwfWVsc2Ug
-aWYodC5mLmIoYSkpe3EuSm4oYSkKcj1xLmp3KGEpCnM9cS5hCmlmKDA+PXMubGVuZ3RoKXJldHVybiBI
-Lk9IKHMsLTEpCnMucG9wKCkKcmV0dXJuIHJ9ZWxzZSByZXR1cm4hMX0sCmxLOmZ1bmN0aW9uKGEpe3Zh
-ciBzLHIscT10aGlzLmMKcS5hKz0iWyIKcz1KLlU2KGEpCmlmKHMuZ29yKGEpKXt0aGlzLmlVKHMucShh
-LDApKQpmb3Iocj0xO3I8cy5nQShhKTsrK3Ipe3EuYSs9IiwiCnRoaXMuaVUocy5xKGEscikpfX1xLmEr
-PSJdIn0sCmp3OmZ1bmN0aW9uKGEpe3ZhciBzLHIscSxwLG8sbixtPXRoaXMsbD17fQppZihhLmdsMChh
-KSl7bS5jLmErPSJ7fSIKcmV0dXJuITB9cz1hLmdBKGEpKjIKcj1QLk84KHMsbnVsbCwhMSx0LlcpCnE9
-bC5hPTAKbC5iPSEwCmEuSygwLG5ldyBQLnRpKGwscikpCmlmKCFsLmIpcmV0dXJuITEKcD1tLmMKcC5h
-Kz0ieyIKZm9yKG89JyInO3E8cztxKz0yLG89JywiJyl7cC5hKz1vCm0udnAoSC5oKHJbcV0pKQpwLmEr
-PSciOicKbj1xKzEKaWYobj49cylyZXR1cm4gSC5PSChyLG4pCm0uaVUocltuXSl9cC5hKz0ifSIKcmV0
-dXJuITB9fQpQLnRpLnByb3RvdHlwZT17CiQyOmZ1bmN0aW9uKGEsYil7dmFyIHMscgppZih0eXBlb2Yg
-YSE9InN0cmluZyIpdGhpcy5hLmI9ITEKcz10aGlzLmIKcj10aGlzLmEKQy5ObS5ZKHMsci5hKyssYSkK
-Qy5ObS5ZKHMsci5hKyssYil9LAokUzoxMH0KUC50dS5wcm90b3R5cGU9ewpnVks6ZnVuY3Rpb24oKXt2
-YXIgcz10aGlzLmMuYQpyZXR1cm4gcy5jaGFyQ29kZUF0KDApPT0wP3M6c319ClAudTUucHJvdG90eXBl
-PXsKZ1pFOmZ1bmN0aW9uKCl7cmV0dXJuIEMuUWt9fQpQLkUzLnByb3RvdHlwZT17CldKOmZ1bmN0aW9u
-KGEpe3ZhciBzLHIscSxwPVAuakIoMCxudWxsLGEubGVuZ3RoKSxvPXAtMAppZihvPT09MClyZXR1cm4g
-bmV3IFVpbnQ4QXJyYXkoMCkKcz1vKjMKcj1uZXcgVWludDhBcnJheShzKQpxPW5ldyBQLlJ3KHIpCmlm
-KHEuR3goYSwwLHApIT09cCl7Si5hNihhLHAtMSkKcS5STygpfXJldHVybiBuZXcgVWludDhBcnJheShy
-LnN1YmFycmF5KDAsSC5yTSgwLHEuYixzKSkpfX0KUC5Sdy5wcm90b3R5cGU9ewpSTzpmdW5jdGlvbigp
-e3ZhciBzPXRoaXMscj1zLmMscT1zLmIscD1zLmI9cSsxLG89ci5sZW5ndGgKaWYocT49bylyZXR1cm4g
-SC5PSChyLHEpCnJbcV09MjM5CnE9cy5iPXArMQppZihwPj1vKXJldHVybiBILk9IKHIscCkKcltwXT0x
-OTEKcy5iPXErMQppZihxPj1vKXJldHVybiBILk9IKHIscSkKcltxXT0xODl9LApPNjpmdW5jdGlvbihh
-LGIpe3ZhciBzLHIscSxwLG8sbj10aGlzCmlmKChiJjY0NTEyKT09PTU2MzIwKXtzPTY1NTM2KygoYSYx
-MDIzKTw8MTApfGImMTAyMwpyPW4uYwpxPW4uYgpwPW4uYj1xKzEKbz1yLmxlbmd0aAppZihxPj1vKXJl
-dHVybiBILk9IKHIscSkKcltxXT1zPj4+MTh8MjQwCnE9bi5iPXArMQppZihwPj1vKXJldHVybiBILk9I
-KHIscCkKcltwXT1zPj4+MTImNjN8MTI4CnA9bi5iPXErMQppZihxPj1vKXJldHVybiBILk9IKHIscSkK
-cltxXT1zPj4+NiY2M3wxMjgKbi5iPXArMQppZihwPj1vKXJldHVybiBILk9IKHIscCkKcltwXT1zJjYz
-fDEyOApyZXR1cm4hMH1lbHNle24uUk8oKQpyZXR1cm4hMX19LApHeDpmdW5jdGlvbihhLGIsYyl7dmFy
-IHMscixxLHAsbyxuLG0sbD10aGlzCmlmKGIhPT1jJiYoQy54Qi5PMihhLGMtMSkmNjQ1MTIpPT09NTUy
-OTYpLS1jCmZvcihzPWwuYyxyPXMubGVuZ3RoLHE9YjtxPGM7KytxKXtwPUMueEIuVyhhLHEpCmlmKHA8
-PTEyNyl7bz1sLmIKaWYobz49cilicmVhawpsLmI9bysxCnNbb109cH1lbHNle289cCY2NDUxMgppZihv
-PT09NTUyOTYpe2lmKGwuYis0PnIpYnJlYWsKbj1xKzEKaWYobC5PNihwLEMueEIuVyhhLG4pKSlxPW59
-ZWxzZSBpZihvPT09NTYzMjApe2lmKGwuYiszPnIpYnJlYWsKbC5STygpfWVsc2UgaWYocDw9MjA0Nyl7
-bz1sLmIKbT1vKzEKaWYobT49cilicmVhawpsLmI9bQppZihvPj1yKXJldHVybiBILk9IKHMsbykKc1tv
-XT1wPj4+NnwxOTIKbC5iPW0rMQpzW21dPXAmNjN8MTI4fWVsc2V7bz1sLmIKaWYobysyPj1yKWJyZWFr
-Cm09bC5iPW8rMQppZihvPj1yKXJldHVybiBILk9IKHMsbykKc1tvXT1wPj4+MTJ8MjI0Cm89bC5iPW0r
-MQppZihtPj1yKXJldHVybiBILk9IKHMsbSkKc1ttXT1wPj4+NiY2M3wxMjgKbC5iPW8rMQppZihvPj1y
-KXJldHVybiBILk9IKHMsbykKc1tvXT1wJjYzfDEyOH19fXJldHVybiBxfX0KUC5HWS5wcm90b3R5cGU9
-ewpXSjpmdW5jdGlvbihhKXt2YXIgcyxyCnQuTC5hKGEpCnM9dGhpcy5hCnI9UC5reShzLGEsMCxudWxs
-KQppZihyIT1udWxsKXJldHVybiByCnJldHVybiBuZXcgUC5ieihzKS5OZShhLDAsbnVsbCwhMCl9fQpQ
-LmJ6LnByb3RvdHlwZT17Ck5lOmZ1bmN0aW9uKGEsYixjLGQpe3ZhciBzLHIscSxwLG8sbj10aGlzCnQu
-TC5hKGEpCnM9UC5qQihiLGMsSi5IbShhKSkKaWYoYj09PXMpcmV0dXJuIiIKcj1QLmp5KGEsYixzKQpx
-PW4uaE8ociwwLHMtYiwhMCkKcD1uLmIKaWYoKHAmMSkhPT0wKXtvPVAuajQocCkKbi5iPTAKdGhyb3cg
-SC5iKFAucnIobyxhLGIrbi5jKSl9cmV0dXJuIHF9LApoTzpmdW5jdGlvbihhLGIsYyxkKXt2YXIgcyxy
-LHE9dGhpcwppZihjLWI+MTAwMCl7cz1DLmpuLkJVKGIrYywyKQpyPXEuaE8oYSxiLHMsITEpCmlmKChx
-LmImMSkhPT0wKXJldHVybiByCnJldHVybiByK3EuaE8oYSxzLGMsZCl9cmV0dXJuIHEuRWgoYSxiLGMs
-ZCl9LApFaDpmdW5jdGlvbihhLGIsYyxkKXt2YXIgcyxyLHEscCxvLG4sbSxsLGs9dGhpcyxqPTY1NTMz
-LGk9ay5iLGg9ay5jLGc9bmV3IFAuUm4oIiIpLGY9YisxLGU9YS5sZW5ndGgKaWYoYjwwfHxiPj1lKXJl
-dHVybiBILk9IKGEsYikKcz1hW2JdCiRsYWJlbDAkMDpmb3Iocj1rLmE7ITA7KXtmb3IoOyEwO2Y9byl7
-cT1DLnhCLlcoIkFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFB
+dHVybiBtLml9cz0kLnZ2W3FdCmlmKHMhPW51bGwpcmV0dXJuIHMKcj12LmludGVyY2VwdG9yc0J5VGFn
+W3FdCm49cX19aWYocj09bnVsbClyZXR1cm4gbnVsbApzPXIucHJvdG90eXBlCnA9blswXQppZihwPT09
+IiEiKXttPUguVmEocykKJC5ud1tuXT1tCk9iamVjdC5kZWZpbmVQcm9wZXJ0eShhLHYuZGlzcGF0Y2hQ
+cm9wZXJ0eU5hbWUse3ZhbHVlOm0sZW51bWVyYWJsZTpmYWxzZSx3cml0YWJsZTp0cnVlLGNvbmZpZ3Vy
+YWJsZTp0cnVlfSkKcmV0dXJuIG0uaX1pZihwPT09In4iKXskLnZ2W25dPXMKcmV0dXJuIHN9aWYocD09
+PSItIil7bz1ILlZhKHMpCk9iamVjdC5kZWZpbmVQcm9wZXJ0eShPYmplY3QuZ2V0UHJvdG90eXBlT2Yo
+YSksdi5kaXNwYXRjaFByb3BlcnR5TmFtZSx7dmFsdWU6byxlbnVtZXJhYmxlOmZhbHNlLHdyaXRhYmxl
+OnRydWUsY29uZmlndXJhYmxlOnRydWV9KQpyZXR1cm4gby5pfWlmKHA9PT0iKyIpcmV0dXJuIEguTGMo
+YSxzKQppZihwPT09IioiKXRocm93IEguYihQLlNZKG4pKQppZih2LmxlYWZUYWdzW25dPT09dHJ1ZSl7
+bz1ILlZhKHMpCk9iamVjdC5kZWZpbmVQcm9wZXJ0eShPYmplY3QuZ2V0UHJvdG90eXBlT2YoYSksdi5k
+aXNwYXRjaFByb3BlcnR5TmFtZSx7dmFsdWU6byxlbnVtZXJhYmxlOmZhbHNlLHdyaXRhYmxlOnRydWUs
+Y29uZmlndXJhYmxlOnRydWV9KQpyZXR1cm4gby5pfWVsc2UgcmV0dXJuIEguTGMoYSxzKX0sCkxjOmZ1
+bmN0aW9uKGEsYil7dmFyIHM9T2JqZWN0LmdldFByb3RvdHlwZU9mKGEpCk9iamVjdC5kZWZpbmVQcm9w
+ZXJ0eShzLHYuZGlzcGF0Y2hQcm9wZXJ0eU5hbWUse3ZhbHVlOkouUXUoYixzLG51bGwsbnVsbCksZW51
+bWVyYWJsZTpmYWxzZSx3cml0YWJsZTp0cnVlLGNvbmZpZ3VyYWJsZTp0cnVlfSkKcmV0dXJuIGJ9LApW
+YTpmdW5jdGlvbihhKXtyZXR1cm4gSi5RdShhLCExLG51bGwsISFhLiRpWGopfSwKVkY6ZnVuY3Rpb24o
+YSxiLGMpe3ZhciBzPWIucHJvdG90eXBlCmlmKHYubGVhZlRhZ3NbYV09PT10cnVlKXJldHVybiBILlZh
+KHMpCmVsc2UgcmV0dXJuIEouUXUocyxjLG51bGwsbnVsbCl9LApYRDpmdW5jdGlvbigpe2lmKCEwPT09
+JC5CdilyZXR1cm4KJC5Cdj0hMApILloxKCl9LApaMTpmdW5jdGlvbigpe3ZhciBzLHIscSxwLG8sbixt
+LGwKJC5udz1PYmplY3QuY3JlYXRlKG51bGwpCiQudnY9T2JqZWN0LmNyZWF0ZShudWxsKQpILmtPKCkK
+cz12LmludGVyY2VwdG9yc0J5VGFnCnI9T2JqZWN0LmdldE93blByb3BlcnR5TmFtZXMocykKaWYodHlw
+ZW9mIHdpbmRvdyE9InVuZGVmaW5lZCIpe3dpbmRvdwpxPWZ1bmN0aW9uKCl7fQpmb3IocD0wO3A8ci5s
+ZW5ndGg7KytwKXtvPXJbcF0Kbj0kLng3LiQxKG8pCmlmKG4hPW51bGwpe209SC5WRihvLHNbb10sbikK
+aWYobSE9bnVsbCl7T2JqZWN0LmRlZmluZVByb3BlcnR5KG4sdi5kaXNwYXRjaFByb3BlcnR5TmFtZSx7
+dmFsdWU6bSxlbnVtZXJhYmxlOmZhbHNlLHdyaXRhYmxlOnRydWUsY29uZmlndXJhYmxlOnRydWV9KQpx
+LnByb3RvdHlwZT1ufX19fWZvcihwPTA7cDxyLmxlbmd0aDsrK3Ape289cltwXQppZigvXltBLVphLXpf
+XS8udGVzdChvKSl7bD1zW29dCnNbIiEiK29dPWwKc1sifiIrb109bApzWyItIitvXT1sCnNbIisiK29d
+PWwKc1siKiIrb109bH19fSwKa086ZnVuY3Rpb24oKXt2YXIgcyxyLHEscCxvLG4sbT1DLllxKCkKbT1I
+LnVkKEMuS1UsSC51ZChDLmZRLEgudWQoQy5pNyxILnVkKEMuaTcsSC51ZChDLnhpLEgudWQoQy5kayxI
+LnVkKEMud2IoQy5PNCksbSkpKSkpKSkKaWYodHlwZW9mIGRhcnROYXRpdmVEaXNwYXRjaEhvb2tzVHJh
+bnNmb3JtZXIhPSJ1bmRlZmluZWQiKXtzPWRhcnROYXRpdmVEaXNwYXRjaEhvb2tzVHJhbnNmb3JtZXIK
+aWYodHlwZW9mIHM9PSJmdW5jdGlvbiIpcz1bc10KaWYocy5jb25zdHJ1Y3Rvcj09QXJyYXkpZm9yKHI9
+MDtyPHMubGVuZ3RoOysrcil7cT1zW3JdCmlmKHR5cGVvZiBxPT0iZnVuY3Rpb24iKW09cShtKXx8bX19
+cD1tLmdldFRhZwpvPW0uZ2V0VW5rbm93blRhZwpuPW0ucHJvdG90eXBlRm9yVGFnCiQuTkY9bmV3IEgu
+ZEMocCkKJC5UWD1uZXcgSC53TihvKQokLng3PW5ldyBILlZYKG4pfSwKdWQ6ZnVuY3Rpb24oYSxiKXty
+ZXR1cm4gYShiKXx8Yn0sCnY0OmZ1bmN0aW9uKGEsYixjLGQsZSxmKXt2YXIgcz1iPyJtIjoiIixyPWM/
+IiI6ImkiLHE9ZD8idSI6IiIscD1lPyJzIjoiIixvPWY/ImciOiIiLG49ZnVuY3Rpb24oZyxoKXt0cnl7
+cmV0dXJuIG5ldyBSZWdFeHAoZyxoKX1jYXRjaChtKXtyZXR1cm4gbX19KGEscytyK3ErcCtvKQppZihu
+IGluc3RhbmNlb2YgUmVnRXhwKXJldHVybiBuCnRocm93IEguYihQLnJyKCJJbGxlZ2FsIFJlZ0V4cCBw
+YXR0ZXJuICgiK1N0cmluZyhuKSsiKSIsYSxudWxsKSl9LApTUTpmdW5jdGlvbihhLGIsYyl7dmFyIHMK
+aWYodHlwZW9mIGI9PSJzdHJpbmciKXJldHVybiBhLmluZGV4T2YoYixjKT49MAplbHNlIGlmKGIgaW5z
+dGFuY2VvZiBILlZSKXtzPUMueEIueW4oYSxjKQpyZXR1cm4gYi5iLnRlc3Qocyl9ZWxzZXtzPUouRkwo
+YixDLnhCLnluKGEsYykpCnJldHVybiFzLmdsMChzKX19LApBNDpmdW5jdGlvbihhKXtpZihhLmluZGV4
+T2YoIiQiLDApPj0wKXJldHVybiBhLnJlcGxhY2UoL1wkL2csIiQkJCQiKQpyZXR1cm4gYX0sCmVBOmZ1
+bmN0aW9uKGEpe2lmKC9bW1xde30oKSorPy5cXF4kfF0vLnRlc3QoYSkpcmV0dXJuIGEucmVwbGFjZSgv
+W1tcXXt9KCkqKz8uXFxeJHxdL2csIlxcJCYiKQpyZXR1cm4gYX0sCnlzOmZ1bmN0aW9uKGEsYixjKXt2
+YXIgcz1ILm5NKGEsYixjKQpyZXR1cm4gc30sCm5NOmZ1bmN0aW9uKGEsYixjKXt2YXIgcyxyLHEscApp
+ZihiPT09IiIpe2lmKGE9PT0iIilyZXR1cm4gYwpzPWEubGVuZ3RoCmZvcihyPWMscT0wO3E8czsrK3Ep
+cj1yK2FbcV0rYwpyZXR1cm4gci5jaGFyQ29kZUF0KDApPT0wP3I6cn1wPWEuaW5kZXhPZihiLDApCmlm
+KHA8MClyZXR1cm4gYQppZihhLmxlbmd0aDw1MDB8fGMuaW5kZXhPZigiJCIsMCk+PTApcmV0dXJuIGEu
+c3BsaXQoYikuam9pbihjKQpyZXR1cm4gYS5yZXBsYWNlKG5ldyBSZWdFeHAoSC5lQShiKSwnZycpLEgu
+QTQoYykpfSwKUEQ6ZnVuY3Rpb24gUEQoYSxiKXt0aGlzLmE9YQp0aGlzLiR0aT1ifSwKV1U6ZnVuY3Rp
+b24gV1UoKXt9LApMUDpmdW5jdGlvbiBMUChhLGIsYyxkKXt2YXIgXz10aGlzCl8uYT1hCl8uYj1iCl8u
+Yz1jCl8uJHRpPWR9LApYUjpmdW5jdGlvbiBYUihhLGIpe3RoaXMuYT1hCnRoaXMuJHRpPWJ9LApMSTpm
+dW5jdGlvbiBMSShhLGIsYyxkLGUpe3ZhciBfPXRoaXMKXy5hPWEKXy5jPWIKXy5kPWMKXy5lPWQKXy5m
+PWV9LApDajpmdW5jdGlvbiBDaihhLGIsYyl7dGhpcy5hPWEKdGhpcy5iPWIKdGhpcy5jPWN9LApmOTpm
+dW5jdGlvbiBmOShhLGIsYyxkLGUsZil7dmFyIF89dGhpcwpfLmE9YQpfLmI9YgpfLmM9YwpfLmQ9ZApf
+LmU9ZQpfLmY9Zn0sClcwOmZ1bmN0aW9uIFcwKGEsYil7dGhpcy5hPWEKdGhpcy5iPWJ9LAphejpmdW5j
+dGlvbiBheihhLGIsYyl7dGhpcy5hPWEKdGhpcy5iPWIKdGhpcy5jPWN9LAp2VjpmdW5jdGlvbiB2Vihh
+KXt0aGlzLmE9YX0sCnRlOmZ1bmN0aW9uIHRlKGEpe3RoaXMuYT1hfSwKYnE6ZnVuY3Rpb24gYnEoYSxi
+KXt0aGlzLmE9YQp0aGlzLmI9Yn0sClhPOmZ1bmN0aW9uIFhPKGEpe3RoaXMuYT1hCnRoaXMuYj1udWxs
+fSwKVHA6ZnVuY3Rpb24gVHAoKXt9LApsYzpmdW5jdGlvbiBsYygpe30sCnp4OmZ1bmN0aW9uIHp4KCl7
+fSwKclQ6ZnVuY3Rpb24gclQoYSxiLGMsZCl7dmFyIF89dGhpcwpfLmE9YQpfLmI9YgpfLmM9YwpfLmQ9
+ZH0sCkVxOmZ1bmN0aW9uIEVxKGEpe3RoaXMuYT1hfSwKa1k6ZnVuY3Rpb24ga1koYSl7dGhpcy5hPWF9
+LAprcjpmdW5jdGlvbiBrcigpe30sCk41OmZ1bmN0aW9uIE41KGEpe3ZhciBfPXRoaXMKXy5hPTAKXy5m
+PV8uZT1fLmQ9Xy5jPV8uYj1udWxsCl8ucj0wCl8uJHRpPWF9LAp2aDpmdW5jdGlvbiB2aChhLGIpe3Zh
+ciBfPXRoaXMKXy5hPWEKXy5iPWIKXy5kPV8uYz1udWxsfSwKaTU6ZnVuY3Rpb24gaTUoYSxiKXt0aGlz
+LmE9YQp0aGlzLiR0aT1ifSwKTjY6ZnVuY3Rpb24gTjYoYSxiLGMpe3ZhciBfPXRoaXMKXy5hPWEKXy5i
+PWIKXy5kPV8uYz1udWxsCl8uJHRpPWN9LApkQzpmdW5jdGlvbiBkQyhhKXt0aGlzLmE9YX0sCndOOmZ1
+bmN0aW9uIHdOKGEpe3RoaXMuYT1hfSwKVlg6ZnVuY3Rpb24gVlgoYSl7dGhpcy5hPWF9LApWUjpmdW5j
+dGlvbiBWUihhLGIpe3ZhciBfPXRoaXMKXy5hPWEKXy5iPWIKXy5kPV8uYz1udWxsfSwKRUs6ZnVuY3Rp
+b24gRUsoYSl7dGhpcy5iPWF9LApLVzpmdW5jdGlvbiBLVyhhLGIsYyl7dGhpcy5hPWEKdGhpcy5iPWIK
+dGhpcy5jPWN9LApQYjpmdW5jdGlvbiBQYihhLGIsYyl7dmFyIF89dGhpcwpfLmE9YQpfLmI9YgpfLmM9
+YwpfLmQ9bnVsbH0sCnRROmZ1bmN0aW9uIHRRKGEsYil7dGhpcy5hPWEKdGhpcy5jPWJ9LAp1bjpmdW5j
+dGlvbiB1bihhLGIsYyl7dGhpcy5hPWEKdGhpcy5iPWIKdGhpcy5jPWN9LApTZDpmdW5jdGlvbiBTZChh
+LGIsYyl7dmFyIF89dGhpcwpfLmE9YQpfLmI9YgpfLmM9YwpfLmQ9bnVsbH0sClhGOmZ1bmN0aW9uKGEp
+e3JldHVybiBhfSwKb2Q6ZnVuY3Rpb24oYSxiLGMpe2lmKGE+Pj4wIT09YXx8YT49Yyl0aHJvdyBILmIo
+SC5IWShiLGEpKX0sCnJNOmZ1bmN0aW9uKGEsYixjKXt2YXIgcwppZighKGE+Pj4wIT09YSkpcz1iPj4+
+MCE9PWJ8fGE+Ynx8Yj5jCmVsc2Ugcz0hMAppZihzKXRocm93IEguYihILmF1KGEsYixjKSkKcmV0dXJu
+IGJ9LApFVDpmdW5jdGlvbiBFVCgpe30sCkxaOmZ1bmN0aW9uIExaKCl7fSwKRGc6ZnVuY3Rpb24gRGco
+KXt9LApQZzpmdW5jdGlvbiBQZygpe30sCnhqOmZ1bmN0aW9uIHhqKCl7fSwKZEU6ZnVuY3Rpb24gZEUo
+KXt9LApaQTpmdW5jdGlvbiBaQSgpe30sCmRUOmZ1bmN0aW9uIGRUKCl7fSwKUHE6ZnVuY3Rpb24gUHEo
+KXt9LAplRTpmdW5jdGlvbiBlRSgpe30sClY2OmZ1bmN0aW9uIFY2KCl7fSwKUkc6ZnVuY3Rpb24gUkco
+KXt9LApWUDpmdW5jdGlvbiBWUCgpe30sCldCOmZ1bmN0aW9uIFdCKCl7fSwKWkc6ZnVuY3Rpb24gWkco
+KXt9LApjejpmdW5jdGlvbihhLGIpe3ZhciBzPWIuYwpyZXR1cm4gcz09bnVsbD9iLmM9SC5CKGEsYi56
+LCEwKTpzfSwKeFo6ZnVuY3Rpb24oYSxiKXt2YXIgcz1iLmMKcmV0dXJuIHM9PW51bGw/Yi5jPUguSihh
+LCJiOCIsW2Iuel0pOnN9LApRMTpmdW5jdGlvbihhKXt2YXIgcz1hLnkKaWYocz09PTZ8fHM9PT03fHxz
+PT09OClyZXR1cm4gSC5RMShhLnopCnJldHVybiBzPT09MTF8fHM9PT0xMn0sCm1EOmZ1bmN0aW9uKGEp
+e3JldHVybiBhLmN5fSwKTjA6ZnVuY3Rpb24oYSl7cmV0dXJuIEguRSh2LnR5cGVVbml2ZXJzZSxhLCEx
+KX0sClBMOmZ1bmN0aW9uKGEsYixhMCxhMSl7dmFyIHMscixxLHAsbyxuLG0sbCxrLGosaSxoLGcsZixl
+LGQsYz1iLnkKc3dpdGNoKGMpe2Nhc2UgNTpjYXNlIDE6Y2FzZSAyOmNhc2UgMzpjYXNlIDQ6cmV0dXJu
+IGIKY2FzZSA2OnM9Yi56CnI9SC5QTChhLHMsYTAsYTEpCmlmKHI9PT1zKXJldHVybiBiCnJldHVybiBI
+LkMoYSxyLCEwKQpjYXNlIDc6cz1iLnoKcj1ILlBMKGEscyxhMCxhMSkKaWYocj09PXMpcmV0dXJuIGIK
+cmV0dXJuIEguQihhLHIsITApCmNhc2UgODpzPWIuegpyPUguUEwoYSxzLGEwLGExKQppZihyPT09cyly
+ZXR1cm4gYgpyZXR1cm4gSC5mKGEsciwhMCkKY2FzZSA5OnE9Yi5RCnA9SC5iWihhLHEsYTAsYTEpCmlm
+KHA9PT1xKXJldHVybiBiCnJldHVybiBILkooYSxiLnoscCkKY2FzZSAxMDpvPWIuegpuPUguUEwoYSxv
+LGEwLGExKQptPWIuUQpsPUguYlooYSxtLGEwLGExKQppZihuPT09byYmbD09PW0pcmV0dXJuIGIKcmV0
+dXJuIEguYShhLG4sbCkKY2FzZSAxMTprPWIuegpqPUguUEwoYSxrLGEwLGExKQppPWIuUQpoPUgucVQo
+YSxpLGEwLGExKQppZihqPT09ayYmaD09PWkpcmV0dXJuIGIKcmV0dXJuIEguZChhLGosaCkKY2FzZSAx
+MjpnPWIuUQphMSs9Zy5sZW5ndGgKZj1ILmJaKGEsZyxhMCxhMSkKbz1iLnoKbj1ILlBMKGEsbyxhMCxh
+MSkKaWYoZj09PWcmJm49PT1vKXJldHVybiBiCnJldHVybiBILkQoYSxuLGYsITApCmNhc2UgMTM6ZT1i
+LnoKaWYoZTxhMSlyZXR1cm4gYgpkPWEwW2UtYTFdCmlmKGQ9PW51bGwpcmV0dXJuIGIKcmV0dXJuIGQK
+ZGVmYXVsdDp0aHJvdyBILmIoUC5oVigiQXR0ZW1wdGVkIHRvIHN1YnN0aXR1dGUgdW5leHBlY3RlZCBS
+VEkga2luZCAiK2MpKX19LApiWjpmdW5jdGlvbihhLGIsYyxkKXt2YXIgcyxyLHEscCxvPWIubGVuZ3Ro
+LG49W10KZm9yKHM9ITEscj0wO3I8bzsrK3Ipe3E9YltyXQpwPUguUEwoYSxxLGMsZCkKaWYocCE9PXEp
+cz0hMApuLnB1c2gocCl9cmV0dXJuIHM/bjpifSwKdk86ZnVuY3Rpb24oYSxiLGMsZCl7dmFyIHMscixx
+LHAsbyxuLG09Yi5sZW5ndGgsbD1bXQpmb3Iocz0hMSxyPTA7cjxtO3IrPTMpe3E9YltyXQpwPWJbcisx
+XQpvPWJbcisyXQpuPUguUEwoYSxvLGMsZCkKaWYobiE9PW8pcz0hMApsLnB1c2gocSkKbC5wdXNoKHAp
+CmwucHVzaChuKX1yZXR1cm4gcz9sOmJ9LApxVDpmdW5jdGlvbihhLGIsYyxkKXt2YXIgcyxyPWIuYSxx
+PUguYlooYSxyLGMsZCkscD1iLmIsbz1ILmJaKGEscCxjLGQpLG49Yi5jLG09SC52TyhhLG4sYyxkKQpp
+ZihxPT09ciYmbz09PXAmJm09PT1uKXJldHVybiBiCnM9bmV3IEguRygpCnMuYT1xCnMuYj1vCnMuYz1t
+CnJldHVybiBzfSwKVk06ZnVuY3Rpb24oYSxiKXthW3YuYXJyYXlSdGldPWIKcmV0dXJuIGF9LApKUzpm
+dW5jdGlvbihhKXt2YXIgcz1hLiRTCmlmKHMhPW51bGwpe2lmKHR5cGVvZiBzPT0ibnVtYmVyIilyZXR1
+cm4gSC5CcChzKQpyZXR1cm4gYS4kUygpfXJldHVybiBudWxsfSwKVWU6ZnVuY3Rpb24oYSxiKXt2YXIg
+cwppZihILlExKGIpKWlmKGEgaW5zdGFuY2VvZiBILlRwKXtzPUguSlMoYSkKaWYocyE9bnVsbClyZXR1
+cm4gc31yZXR1cm4gSC56KGEpfSwKejpmdW5jdGlvbihhKXt2YXIgcwppZihhIGluc3RhbmNlb2YgUC5N
+aCl7cz1hLiR0aQpyZXR1cm4gcyE9bnVsbD9zOkguVlUoYSl9aWYoQXJyYXkuaXNBcnJheShhKSlyZXR1
+cm4gSC50NihhKQpyZXR1cm4gSC5WVShKLmlhKGEpKX0sCnQ2OmZ1bmN0aW9uKGEpe3ZhciBzPWFbdi5h
+cnJheVJ0aV0scj10LngKaWYocz09bnVsbClyZXR1cm4gcgppZihzLmNvbnN0cnVjdG9yIT09ci5jb25z
+dHJ1Y3RvcilyZXR1cm4gcgpyZXR1cm4gc30sCkxoOmZ1bmN0aW9uKGEpe3ZhciBzPWEuJHRpCnJldHVy
+biBzIT1udWxsP3M6SC5WVShhKX0sClZVOmZ1bmN0aW9uKGEpe3ZhciBzPWEuY29uc3RydWN0b3Iscj1z
+LiRjY2FjaGUKaWYociE9bnVsbClyZXR1cm4gcgpyZXR1cm4gSC5yOShhLHMpfSwKcjk6ZnVuY3Rpb24o
+YSxiKXt2YXIgcz1hIGluc3RhbmNlb2YgSC5UcD9hLl9fcHJvdG9fXy5fX3Byb3RvX18uY29uc3RydWN0
+b3I6YixyPUguYWkodi50eXBlVW5pdmVyc2Uscy5uYW1lKQpiLiRjY2FjaGU9cgpyZXR1cm4gcn0sCkJw
+OmZ1bmN0aW9uKGEpe3ZhciBzLHIscQpILnVQKGEpCnM9di50eXBlcwpyPXNbYV0KaWYodHlwZW9mIHI9
+PSJzdHJpbmciKXtxPUguRSh2LnR5cGVVbml2ZXJzZSxyLCExKQpzW2FdPXEKcmV0dXJuIHF9cmV0dXJu
+IHJ9LApLeDpmdW5jdGlvbihhKXt2YXIgcyxyLHEscD1hLngKaWYocCE9bnVsbClyZXR1cm4gcApzPWEu
+Y3kKcj1zLnJlcGxhY2UoL1wqL2csIiIpCmlmKHI9PT1zKXJldHVybiBhLng9bmV3IEgubFkoYSkKcT1I
+LkUodi50eXBlVW5pdmVyc2UsciwhMCkKcD1xLngKcmV0dXJuIGEueD1wPT1udWxsP3EueD1uZXcgSC5s
+WShxKTpwfSwKSko6ZnVuY3Rpb24oYSl7dmFyIHMscixxPXRoaXMscD10LksKaWYocT09PXApcmV0dXJu
+IEguUkUocSxhLEgua2UpCmlmKCFILkE4KHEpKWlmKCEocT09PXQuXykpcD1xPT09cAplbHNlIHA9ITAK
+ZWxzZSBwPSEwCmlmKHApcmV0dXJuIEguUkUocSxhLEguSXcpCnA9cS55CnM9cD09PTY/cS56OnEKaWYo
+cz09PXQuUylyPUgub2sKZWxzZSBpZihzPT09dC5nUnx8cz09PXQuZGkpcj1ILktICmVsc2UgaWYocz09
+PXQuTilyPUguTU0KZWxzZSByPXM9PT10Lnk/SC5sOm51bGwKaWYociE9bnVsbClyZXR1cm4gSC5SRShx
+LGEscikKaWYocy55PT09OSl7cD1zLnoKaWYocy5RLmV2ZXJ5KEguY2MpKXtxLnI9IiRpIitwCnJldHVy
+biBILlJFKHEsYSxILnQ0KX19ZWxzZSBpZihwPT09NylyZXR1cm4gSC5SRShxLGEsSC5BUSkKcmV0dXJu
+IEguUkUocSxhLEguWU8pfSwKUkU6ZnVuY3Rpb24oYSxiLGMpe2EuYj1jCnJldHVybiBhLmIoYil9LApB
+dTpmdW5jdGlvbihhKXt2YXIgcyxyLHE9dGhpcwppZighSC5BOChxKSlpZighKHE9PT10Ll8pKXM9cT09
+PXQuSwplbHNlIHM9ITAKZWxzZSBzPSEwCmlmKHMpcj1ILmhuCmVsc2UgaWYocT09PXQuSylyPUguVGkK
+ZWxzZSByPUgubDQKcS5hPXIKcmV0dXJuIHEuYShhKX0sClFqOmZ1bmN0aW9uKGEpe3ZhciBzLHI9YS55
+CmlmKCFILkE4KGEpKWlmKCEoYT09PXQuXykpaWYoIShhPT09dC5jRikpaWYociE9PTcpcz1yPT09OCYm
+SC5RaihhLnopfHxhPT09dC5QfHxhPT09dC5UCmVsc2Ugcz0hMAplbHNlIHM9ITAKZWxzZSBzPSEwCmVs
+c2Ugcz0hMApyZXR1cm4gc30sCllPOmZ1bmN0aW9uKGEpe3ZhciBzPXRoaXMKaWYoYT09bnVsbClyZXR1
+cm4gSC5RaihzKQpyZXR1cm4gSC5XZSh2LnR5cGVVbml2ZXJzZSxILlVlKGEscyksbnVsbCxzLG51bGwp
+fSwKQVE6ZnVuY3Rpb24oYSl7aWYoYT09bnVsbClyZXR1cm4hMApyZXR1cm4gdGhpcy56LmIoYSl9LAp0
+NDpmdW5jdGlvbihhKXt2YXIgcyxyPXRoaXMKaWYoYT09bnVsbClyZXR1cm4gSC5RaihyKQpzPXIucgpp
+ZihhIGluc3RhbmNlb2YgUC5NaClyZXR1cm4hIWFbc10KcmV0dXJuISFKLmlhKGEpW3NdfSwKT3o6ZnVu
+Y3Rpb24oYSl7dmFyIHM9dGhpcwppZihhPT1udWxsKXJldHVybiBhCmVsc2UgaWYocy5iKGEpKXJldHVy
+biBhCkgubTQoYSxzKX0sCmw0OmZ1bmN0aW9uKGEpe3ZhciBzPXRoaXMKaWYoYT09bnVsbClyZXR1cm4g
+YQplbHNlIGlmKHMuYihhKSlyZXR1cm4gYQpILm00KGEscyl9LAptNDpmdW5jdGlvbihhLGIpe3Rocm93
+IEguYihILlpjKEguV0soYSxILlVlKGEsYiksSC5kbShiLG51bGwpKSkpfSwKRGg6ZnVuY3Rpb24oYSxi
+LGMsZCl7dmFyIHM9bnVsbAppZihILldlKHYudHlwZVVuaXZlcnNlLGEscyxiLHMpKXJldHVybiBhCnRo
+cm93IEguYihILlpjKCJUaGUgdHlwZSBhcmd1bWVudCAnIitILkVqKEguZG0oYSxzKSkrIicgaXMgbm90
+IGEgc3VidHlwZSBvZiB0aGUgdHlwZSB2YXJpYWJsZSBib3VuZCAnIitILkVqKEguZG0oYixzKSkrIicg
+b2YgdHlwZSB2YXJpYWJsZSAnIitILkVqKGMpKyInIGluICciK0guRWooZCkrIicuIikpfSwKV0s6ZnVu
+Y3Rpb24oYSxiLGMpe3ZhciBzPVAucChhKSxyPUguZG0oYj09bnVsbD9ILnooYSk6YixudWxsKQpyZXR1
+cm4gcysiOiB0eXBlICciK0guRWoocikrIicgaXMgbm90IGEgc3VidHlwZSBvZiB0eXBlICciK0guRWoo
+YykrIicifSwKWmM6ZnVuY3Rpb24oYSl7cmV0dXJuIG5ldyBILmlNKCJUeXBlRXJyb3I6ICIrYSl9LApx
+OmZ1bmN0aW9uKGEsYil7cmV0dXJuIG5ldyBILmlNKCJUeXBlRXJyb3I6ICIrSC5XSyhhLG51bGwsYikp
+fSwKa2U6ZnVuY3Rpb24oYSl7cmV0dXJuIGEhPW51bGx9LApUaTpmdW5jdGlvbihhKXtyZXR1cm4gYX0s
+Ckl3OmZ1bmN0aW9uKGEpe3JldHVybiEwfSwKaG46ZnVuY3Rpb24oYSl7cmV0dXJuIGF9LApsOmZ1bmN0
+aW9uKGEpe3JldHVybiEwPT09YXx8ITE9PT1hfSwKcDg6ZnVuY3Rpb24oYSl7aWYoITA9PT1hKXJldHVy
+biEwCmlmKCExPT09YSlyZXR1cm4hMQp0aHJvdyBILmIoSC5xKGEsImJvb2wiKSl9LAp5ODpmdW5jdGlv
+bihhKXtpZighMD09PWEpcmV0dXJuITAKaWYoITE9PT1hKXJldHVybiExCmlmKGE9PW51bGwpcmV0dXJu
+IGEKdGhyb3cgSC5iKEgucShhLCJib29sIikpfSwKZHA6ZnVuY3Rpb24oYSl7aWYoITA9PT1hKXJldHVy
+biEwCmlmKCExPT09YSlyZXR1cm4hMQppZihhPT1udWxsKXJldHVybiBhCnRocm93IEguYihILnEoYSwi
+Ym9vbD8iKSl9LApGRzpmdW5jdGlvbihhKXtpZih0eXBlb2YgYT09Im51bWJlciIpcmV0dXJuIGEKdGhy
+b3cgSC5iKEgucShhLCJkb3VibGUiKSl9LApHSDpmdW5jdGlvbihhKXtpZih0eXBlb2YgYT09Im51bWJl
+ciIpcmV0dXJuIGEKaWYoYT09bnVsbClyZXR1cm4gYQp0aHJvdyBILmIoSC5xKGEsImRvdWJsZSIpKX0s
+ClFrOmZ1bmN0aW9uKGEpe2lmKHR5cGVvZiBhPT0ibnVtYmVyIilyZXR1cm4gYQppZihhPT1udWxsKXJl
+dHVybiBhCnRocm93IEguYihILnEoYSwiZG91YmxlPyIpKX0sCm9rOmZ1bmN0aW9uKGEpe3JldHVybiB0
+eXBlb2YgYT09Im51bWJlciImJk1hdGguZmxvb3IoYSk9PT1hfSwKSVo6ZnVuY3Rpb24oYSl7aWYodHlw
+ZW9mIGE9PSJudW1iZXIiJiZNYXRoLmZsb29yKGEpPT09YSlyZXR1cm4gYQp0aHJvdyBILmIoSC5xKGEs
+ImludCIpKX0sCnVQOmZ1bmN0aW9uKGEpe2lmKHR5cGVvZiBhPT0ibnVtYmVyIiYmTWF0aC5mbG9vcihh
+KT09PWEpcmV0dXJuIGEKaWYoYT09bnVsbClyZXR1cm4gYQp0aHJvdyBILmIoSC5xKGEsImludCIpKX0s
+ClVjOmZ1bmN0aW9uKGEpe2lmKHR5cGVvZiBhPT0ibnVtYmVyIiYmTWF0aC5mbG9vcihhKT09PWEpcmV0
+dXJuIGEKaWYoYT09bnVsbClyZXR1cm4gYQp0aHJvdyBILmIoSC5xKGEsImludD8iKSl9LApLSDpmdW5j
+dGlvbihhKXtyZXR1cm4gdHlwZW9mIGE9PSJudW1iZXIifSwKejU6ZnVuY3Rpb24oYSl7aWYodHlwZW9m
+IGE9PSJudW1iZXIiKXJldHVybiBhCnRocm93IEguYihILnEoYSwibnVtIikpfSwKVzE6ZnVuY3Rpb24o
+YSl7aWYodHlwZW9mIGE9PSJudW1iZXIiKXJldHVybiBhCmlmKGE9PW51bGwpcmV0dXJuIGEKdGhyb3cg
+SC5iKEgucShhLCJudW0iKSl9LApjVTpmdW5jdGlvbihhKXtpZih0eXBlb2YgYT09Im51bWJlciIpcmV0
+dXJuIGEKaWYoYT09bnVsbClyZXR1cm4gYQp0aHJvdyBILmIoSC5xKGEsIm51bT8iKSl9LApNTTpmdW5j
+dGlvbihhKXtyZXR1cm4gdHlwZW9mIGE9PSJzdHJpbmcifSwKQnQ6ZnVuY3Rpb24oYSl7aWYodHlwZW9m
+IGE9PSJzdHJpbmciKXJldHVybiBhCnRocm93IEguYihILnEoYSwiU3RyaW5nIikpfSwKaDpmdW5jdGlv
+bihhKXtpZih0eXBlb2YgYT09InN0cmluZyIpcmV0dXJuIGEKaWYoYT09bnVsbClyZXR1cm4gYQp0aHJv
+dyBILmIoSC5xKGEsIlN0cmluZyIpKX0sCms6ZnVuY3Rpb24oYSl7aWYodHlwZW9mIGE9PSJzdHJpbmci
+KXJldHVybiBhCmlmKGE9PW51bGwpcmV0dXJuIGEKdGhyb3cgSC5iKEgucShhLCJTdHJpbmc/IikpfSwK
+aW86ZnVuY3Rpb24oYSxiKXt2YXIgcyxyLHEKZm9yKHM9IiIscj0iIixxPTA7cTxhLmxlbmd0aDsrK3Es
+cj0iLCAiKXMrPUMueEIuaChyLEguZG0oYVtxXSxiKSkKcmV0dXJuIHN9LApiSTpmdW5jdGlvbihhNSxh
+NixhNyl7dmFyIHMscixxLHAsbyxuLG0sbCxrLGosaSxoLGcsZixlLGQsYyxiLGEsYTAsYTEsYTIsYTMs
+YTQ9IiwgIgppZihhNyE9bnVsbCl7cz1hNy5sZW5ndGgKaWYoYTY9PW51bGwpe2E2PUguVk0oW10sdC5z
+KQpyPW51bGx9ZWxzZSByPWE2Lmxlbmd0aApxPWE2Lmxlbmd0aApmb3IocD1zO3A+MDstLXApQy5ObS5p
+KGE2LCJUIisocStwKSkKZm9yKG89dC5XLG49dC5fLG09dC5LLGw9IjwiLGs9IiIscD0wO3A8czsrK3As
+az1hNCl7bCs9awpqPWE2Lmxlbmd0aAppPWotMS1wCmlmKGk8MClyZXR1cm4gSC5PSChhNixpKQpsPUMu
+eEIuaChsLGE2W2ldKQpoPWE3W3BdCmc9aC55CmlmKCEoZz09PTJ8fGc9PT0zfHxnPT09NHx8Zz09PTV8
+fGg9PT1vKSlpZighKGg9PT1uKSlqPWg9PT1tCmVsc2Ugaj0hMAplbHNlIGo9ITAKaWYoIWopbCs9Qy54
+Qi5oKCIgZXh0ZW5kcyAiLEguZG0oaCxhNikpfWwrPSI+In1lbHNle2w9IiIKcj1udWxsfW89YTUuegpm
+PWE1LlEKZT1mLmEKZD1lLmxlbmd0aApjPWYuYgpiPWMubGVuZ3RoCmE9Zi5jCmEwPWEubGVuZ3RoCmEx
+PUguZG0obyxhNikKZm9yKGEyPSIiLGEzPSIiLHA9MDtwPGQ7KytwLGEzPWE0KWEyKz1DLnhCLmgoYTMs
+SC5kbShlW3BdLGE2KSkKaWYoYj4wKXthMis9YTMrIlsiCmZvcihhMz0iIixwPTA7cDxiOysrcCxhMz1h
+NClhMis9Qy54Qi5oKGEzLEguZG0oY1twXSxhNikpCmEyKz0iXSJ9aWYoYTA+MCl7YTIrPWEzKyJ7Igpm
+b3IoYTM9IiIscD0wO3A8YTA7cCs9MyxhMz1hNCl7YTIrPWEzCmlmKGFbcCsxXSlhMis9InJlcXVpcmVk
+ICIKYTIrPUouYmIoSC5kbShhW3ArMl0sYTYpLCIgIikrYVtwXX1hMis9In0ifWlmKHIhPW51bGwpe2E2
+LnRvU3RyaW5nCmE2Lmxlbmd0aD1yfXJldHVybiBsKyIoIithMisiKSA9PiAiK0guRWooYTEpfSwKZG06
+ZnVuY3Rpb24oYSxiKXt2YXIgcyxyLHEscCxvLG4sbSxsPWEueQppZihsPT09NSlyZXR1cm4iZXJhc2Vk
+IgppZihsPT09MilyZXR1cm4iZHluYW1pYyIKaWYobD09PTMpcmV0dXJuInZvaWQiCmlmKGw9PT0xKXJl
+dHVybiJOZXZlciIKaWYobD09PTQpcmV0dXJuImFueSIKaWYobD09PTYpe3M9SC5kbShhLnosYikKcmV0
+dXJuIHN9aWYobD09PTcpe3I9YS56CnM9SC5kbShyLGIpCnE9ci55CnJldHVybiBKLmJiKHE9PT0xMXx8
+cT09PTEyP0MueEIuaCgiKCIscykrIikiOnMsIj8iKX1pZihsPT09OClyZXR1cm4iRnV0dXJlT3I8IitI
+LkVqKEguZG0oYS56LGIpKSsiPiIKaWYobD09PTkpe3A9SC5vMyhhLnopCm89YS5RCnJldHVybiBvLmxl
+bmd0aCE9PTA/cCsoIjwiK0guaW8obyxiKSsiPiIpOnB9aWYobD09PTExKXJldHVybiBILmJJKGEsYixu
+dWxsKQppZihsPT09MTIpcmV0dXJuIEguYkkoYS56LGIsYS5RKQppZihsPT09MTMpe2IudG9TdHJpbmcK
+bj1hLnoKbT1iLmxlbmd0aApuPW0tMS1uCmlmKG48MHx8bj49bSlyZXR1cm4gSC5PSChiLG4pCnJldHVy
+biBiW25dfXJldHVybiI/In0sCm8zOmZ1bmN0aW9uKGEpe3ZhciBzLHI9SC5KZyhhKQppZihyIT1udWxs
+KXJldHVybiByCnM9Im1pbmlmaWVkOiIrYQpyZXR1cm4gc30sClFvOmZ1bmN0aW9uKGEsYil7dmFyIHM9
+YS50UltiXQpmb3IoO3R5cGVvZiBzPT0ic3RyaW5nIjspcz1hLnRSW3NdCnJldHVybiBzfSwKYWk6ZnVu
+Y3Rpb24oYSxiKXt2YXIgcyxyLHEscCxvLG49YS5lVCxtPW5bYl0KaWYobT09bnVsbClyZXR1cm4gSC5F
+KGEsYiwhMSkKZWxzZSBpZih0eXBlb2YgbT09Im51bWJlciIpe3M9bQpyPUgubShhLDUsIiMiKQpxPVtd
+CmZvcihwPTA7cDxzOysrcClxLnB1c2gocikKbz1ILkooYSxiLHEpCm5bYl09bwpyZXR1cm4gb31lbHNl
+IHJldHVybiBtfSwKeGI6ZnVuY3Rpb24oYSxiKXtyZXR1cm4gSC5JeChhLnRSLGIpfSwKRkY6ZnVuY3Rp
+b24oYSxiKXtyZXR1cm4gSC5JeChhLmVULGIpfSwKRTpmdW5jdGlvbihhLGIsYyl7dmFyIHMscj1hLmVD
+LHE9ci5nZXQoYikKaWYocSE9bnVsbClyZXR1cm4gcQpzPUguaShILm8oYSxudWxsLGIsYykpCnIuc2V0
+KGIscykKcmV0dXJuIHN9LApjRTpmdW5jdGlvbihhLGIsYyl7dmFyIHMscixxPWIuY2gKaWYocT09bnVs
+bClxPWIuY2g9bmV3IE1hcCgpCnM9cS5nZXQoYykKaWYocyE9bnVsbClyZXR1cm4gcwpyPUguaShILm8o
+YSxiLGMsITApKQpxLnNldChjLHIpCnJldHVybiByfSwKdjU6ZnVuY3Rpb24oYSxiLGMpe3ZhciBzLHIs
+cSxwPWIuY3gKaWYocD09bnVsbClwPWIuY3g9bmV3IE1hcCgpCnM9Yy5jeQpyPXAuZ2V0KHMpCmlmKHIh
+PW51bGwpcmV0dXJuIHIKcT1ILmEoYSxiLGMueT09PTEwP2MuUTpbY10pCnAuc2V0KHMscSkKcmV0dXJu
+IHF9LApCRDpmdW5jdGlvbihhLGIpe2IuYT1ILkF1CmIuYj1ILkpKCnJldHVybiBifSwKbTpmdW5jdGlv
+bihhLGIsYyl7dmFyIHMscixxPWEuZUMuZ2V0KGMpCmlmKHEhPW51bGwpcmV0dXJuIHEKcz1uZXcgSC5K
+YyhudWxsLG51bGwpCnMueT1iCnMuY3k9YwpyPUguQkQoYSxzKQphLmVDLnNldChjLHIpCnJldHVybiBy
+fSwKQzpmdW5jdGlvbihhLGIsYyl7dmFyIHMscj1iLmN5KyIqIixxPWEuZUMuZ2V0KHIpCmlmKHEhPW51
+bGwpcmV0dXJuIHEKcz1ILlo3KGEsYixyLGMpCmEuZUMuc2V0KHIscykKcmV0dXJuIHN9LApaNzpmdW5j
+dGlvbihhLGIsYyxkKXt2YXIgcyxyLHEKaWYoZCl7cz1iLnkKaWYoIUguQTgoYikpcj1iPT09dC5QfHxi
+PT09dC5UfHxzPT09N3x8cz09PTYKZWxzZSByPSEwCmlmKHIpcmV0dXJuIGJ9cT1uZXcgSC5KYyhudWxs
+LG51bGwpCnEueT02CnEuej1iCnEuY3k9YwpyZXR1cm4gSC5CRChhLHEpfSwKQjpmdW5jdGlvbihhLGIs
+Yyl7dmFyIHMscj1iLmN5KyI/IixxPWEuZUMuZ2V0KHIpCmlmKHEhPW51bGwpcmV0dXJuIHEKcz1ILmxs
+KGEsYixyLGMpCmEuZUMuc2V0KHIscykKcmV0dXJuIHN9LApsbDpmdW5jdGlvbihhLGIsYyxkKXt2YXIg
+cyxyLHEscAppZihkKXtzPWIueQppZighSC5BOChiKSlpZighKGI9PT10LlB8fGI9PT10LlQpKWlmKHMh
+PT03KXI9cz09PTgmJkgubFIoYi56KQplbHNlIHI9ITAKZWxzZSByPSEwCmVsc2Ugcj0hMAppZihyKXJl
+dHVybiBiCmVsc2UgaWYocz09PTF8fGI9PT10LmNGKXJldHVybiB0LlAKZWxzZSBpZihzPT09Nil7cT1i
+LnoKaWYocS55PT09OCYmSC5sUihxLnopKXJldHVybiBxCmVsc2UgcmV0dXJuIEguY3ooYSxiKX19cD1u
+ZXcgSC5KYyhudWxsLG51bGwpCnAueT03CnAuej1iCnAuY3k9YwpyZXR1cm4gSC5CRChhLHApfSwKZjpm
+dW5jdGlvbihhLGIsYyl7dmFyIHMscj1iLmN5KyIvIixxPWEuZUMuZ2V0KHIpCmlmKHEhPW51bGwpcmV0
+dXJuIHEKcz1ILmVWKGEsYixyLGMpCmEuZUMuc2V0KHIscykKcmV0dXJuIHN9LAplVjpmdW5jdGlvbihh
+LGIsYyxkKXt2YXIgcyxyLHEKaWYoZCl7cz1iLnkKaWYoIUguQTgoYikpaWYoIShiPT09dC5fKSlyPWI9
+PT10LksKZWxzZSByPSEwCmVsc2Ugcj0hMAppZihyfHxiPT09dC5LKXJldHVybiBiCmVsc2UgaWYocz09
+PTEpcmV0dXJuIEguSihhLCJiOCIsW2JdKQplbHNlIGlmKGI9PT10LlB8fGI9PT10LlQpcmV0dXJuIHQu
+Ykd9cT1uZXcgSC5KYyhudWxsLG51bGwpCnEueT04CnEuej1iCnEuY3k9YwpyZXR1cm4gSC5CRChhLHEp
+fSwKSDpmdW5jdGlvbihhLGIpe3ZhciBzLHIscT0iIitiKyJeIixwPWEuZUMuZ2V0KHEpCmlmKHAhPW51
+bGwpcmV0dXJuIHAKcz1uZXcgSC5KYyhudWxsLG51bGwpCnMueT0xMwpzLno9YgpzLmN5PXEKcj1ILkJE
+KGEscykKYS5lQy5zZXQocSxyKQpyZXR1cm4gcn0sClV4OmZ1bmN0aW9uKGEpe3ZhciBzLHIscSxwPWEu
+bGVuZ3RoCmZvcihzPSIiLHI9IiIscT0wO3E8cDsrK3Escj0iLCIpcys9cithW3FdLmN5CnJldHVybiBz
+fSwKUzQ6ZnVuY3Rpb24oYSl7dmFyIHMscixxLHAsbyxuLG09YS5sZW5ndGgKZm9yKHM9IiIscj0iIixx
+PTA7cTxtO3ErPTMscj0iLCIpe3A9YVtxXQpvPWFbcSsxXT8iISI6IjoiCm49YVtxKzJdLmN5CnMrPXIr
+cCtvK259cmV0dXJuIHN9LApKOmZ1bmN0aW9uKGEsYixjKXt2YXIgcyxyLHEscD1iCmlmKGMubGVuZ3Ro
+IT09MClwKz0iPCIrSC5VeChjKSsiPiIKcz1hLmVDLmdldChwKQppZihzIT1udWxsKXJldHVybiBzCnI9
+bmV3IEguSmMobnVsbCxudWxsKQpyLnk9OQpyLno9YgpyLlE9YwppZihjLmxlbmd0aD4wKXIuYz1jWzBd
+CnIuY3k9cApxPUguQkQoYSxyKQphLmVDLnNldChwLHEpCnJldHVybiBxfSwKYTpmdW5jdGlvbihhLGIs
+Yyl7dmFyIHMscixxLHAsbyxuCmlmKGIueT09PTEwKXtzPWIuegpyPWIuUS5jb25jYXQoYyl9ZWxzZXty
+PWMKcz1ifXE9cy5jeSsoIjs8IitILlV4KHIpKyI+IikKcD1hLmVDLmdldChxKQppZihwIT1udWxsKXJl
+dHVybiBwCm89bmV3IEguSmMobnVsbCxudWxsKQpvLnk9MTAKby56PXMKby5RPXIKby5jeT1xCm49SC5C
+RChhLG8pCmEuZUMuc2V0KHEsbikKcmV0dXJuIG59LApkOmZ1bmN0aW9uKGEsYixjKXt2YXIgcyxyLHEs
+cCxvLG49Yi5jeSxtPWMuYSxsPW0ubGVuZ3RoLGs9Yy5iLGo9ay5sZW5ndGgsaT1jLmMsaD1pLmxlbmd0
+aCxnPSIoIitILlV4KG0pCmlmKGo+MCl7cz1sPjA/IiwiOiIiCnI9SC5VeChrKQpnKz1zKyJbIityKyJd
+In1pZihoPjApe3M9bD4wPyIsIjoiIgpyPUguUzQoaSkKZys9cysieyIrcisifSJ9cT1uKyhnKyIpIikK
+cD1hLmVDLmdldChxKQppZihwIT1udWxsKXJldHVybiBwCm89bmV3IEguSmMobnVsbCxudWxsKQpvLnk9
+MTEKby56PWIKby5RPWMKby5jeT1xCnI9SC5CRChhLG8pCmEuZUMuc2V0KHEscikKcmV0dXJuIHJ9LApE
+OmZ1bmN0aW9uKGEsYixjLGQpe3ZhciBzLHI9Yi5jeSsoIjwiK0guVXgoYykrIj4iKSxxPWEuZUMuZ2V0
+KHIpCmlmKHEhPW51bGwpcmV0dXJuIHEKcz1ILmh3KGEsYixjLHIsZCkKYS5lQy5zZXQocixzKQpyZXR1
+cm4gc30sCmh3OmZ1bmN0aW9uKGEsYixjLGQsZSl7dmFyIHMscixxLHAsbyxuLG0sbAppZihlKXtzPWMu
+bGVuZ3RoCnI9bmV3IEFycmF5KHMpCmZvcihxPTAscD0wO3A8czsrK3Ape289Y1twXQppZihvLnk9PT0x
+KXtyW3BdPW87KytxfX1pZihxPjApe249SC5QTChhLGIsciwwKQptPUguYlooYSxjLHIsMCkKcmV0dXJu
+IEguRChhLG4sbSxjIT09bSl9fWw9bmV3IEguSmMobnVsbCxudWxsKQpsLnk9MTIKbC56PWIKbC5RPWMK
+bC5jeT1kCnJldHVybiBILkJEKGEsbCl9LApvOmZ1bmN0aW9uKGEsYixjLGQpe3JldHVybnt1OmEsZTpi
+LHI6YyxzOltdLHA6MCxuOmR9fSwKaTpmdW5jdGlvbihhKXt2YXIgcyxyLHEscCxvLG4sbSxsLGssaixp
+LGgsZz1hLnIsZj1hLnMKZm9yKHM9Zy5sZW5ndGgscj0wO3I8czspe3E9Zy5jaGFyQ29kZUF0KHIpCmlm
+KHE+PTQ4JiZxPD01NylyPUguQShyKzEscSxnLGYpCmVsc2UgaWYoKCgocXwzMik+Pj4wKS05NyY2NTUz
+NSk8MjZ8fHE9PT05NXx8cT09PTM2KXI9SC50KGEscixnLGYsITEpCmVsc2UgaWYocT09PTQ2KXI9SC50
+KGEscixnLGYsITApCmVsc2V7KytyCnN3aXRjaChxKXtjYXNlIDQ0OmJyZWFrCmNhc2UgNTg6Zi5wdXNo
+KCExKQpicmVhawpjYXNlIDMzOmYucHVzaCghMCkKYnJlYWsKY2FzZSA1OTpmLnB1c2goSC5LKGEudSxh
+LmUsZi5wb3AoKSkpCmJyZWFrCmNhc2UgOTQ6Zi5wdXNoKEguSChhLnUsZi5wb3AoKSkpCmJyZWFrCmNh
+c2UgMzU6Zi5wdXNoKEgubShhLnUsNSwiIyIpKQpicmVhawpjYXNlIDY0OmYucHVzaChILm0oYS51LDIs
+IkAiKSkKYnJlYWsKY2FzZSAxMjY6Zi5wdXNoKEgubShhLnUsMywifiIpKQpicmVhawpjYXNlIDYwOmYu
+cHVzaChhLnApCmEucD1mLmxlbmd0aApicmVhawpjYXNlIDYyOnA9YS51Cm89Zi5zcGxpY2UoYS5wKQpI
+LnIoYS51LGEuZSxvKQphLnA9Zi5wb3AoKQpuPWYucG9wKCkKaWYodHlwZW9mIG49PSJzdHJpbmciKWYu
+cHVzaChILkoocCxuLG8pKQplbHNle209SC5LKHAsYS5lLG4pCnN3aXRjaChtLnkpe2Nhc2UgMTE6Zi5w
+dXNoKEguRChwLG0sbyxhLm4pKQpicmVhawpkZWZhdWx0OmYucHVzaChILmEocCxtLG8pKQpicmVha319
+YnJlYWsKY2FzZSAzODpILkkoYSxmKQpicmVhawpjYXNlIDQyOmw9YS51CmYucHVzaChILkMobCxILkso
+bCxhLmUsZi5wb3AoKSksYS5uKSkKYnJlYWsKY2FzZSA2MzpsPWEudQpmLnB1c2goSC5CKGwsSC5LKGws
+YS5lLGYucG9wKCkpLGEubikpCmJyZWFrCmNhc2UgNDc6bD1hLnUKZi5wdXNoKEguZihsLEguSyhsLGEu
+ZSxmLnBvcCgpKSxhLm4pKQpicmVhawpjYXNlIDQwOmYucHVzaChhLnApCmEucD1mLmxlbmd0aApicmVh
+awpjYXNlIDQxOnA9YS51Cms9bmV3IEguRygpCmo9cC5zRUEKaT1wLnNFQQpuPWYucG9wKCkKaWYodHlw
+ZW9mIG49PSJudW1iZXIiKXN3aXRjaChuKXtjYXNlLTE6aj1mLnBvcCgpCmJyZWFrCmNhc2UtMjppPWYu
+cG9wKCkKYnJlYWsKZGVmYXVsdDpmLnB1c2gobikKYnJlYWt9ZWxzZSBmLnB1c2gobikKbz1mLnNwbGlj
+ZShhLnApCkgucihhLnUsYS5lLG8pCmEucD1mLnBvcCgpCmsuYT1vCmsuYj1qCmsuYz1pCmYucHVzaChI
+LmQocCxILksocCxhLmUsZi5wb3AoKSksaykpCmJyZWFrCmNhc2UgOTE6Zi5wdXNoKGEucCkKYS5wPWYu
+bGVuZ3RoCmJyZWFrCmNhc2UgOTM6bz1mLnNwbGljZShhLnApCkgucihhLnUsYS5lLG8pCmEucD1mLnBv
+cCgpCmYucHVzaChvKQpmLnB1c2goLTEpCmJyZWFrCmNhc2UgMTIzOmYucHVzaChhLnApCmEucD1mLmxl
+bmd0aApicmVhawpjYXNlIDEyNTpvPWYuc3BsaWNlKGEucCkKSC55KGEudSxhLmUsbykKYS5wPWYucG9w
+KCkKZi5wdXNoKG8pCmYucHVzaCgtMikKYnJlYWsKZGVmYXVsdDp0aHJvdyJCYWQgY2hhcmFjdGVyICIr
+cX19fWg9Zi5wb3AoKQpyZXR1cm4gSC5LKGEudSxhLmUsaCl9LApBOmZ1bmN0aW9uKGEsYixjLGQpe3Zh
+ciBzLHIscT1iLTQ4CmZvcihzPWMubGVuZ3RoO2E8czsrK2Epe3I9Yy5jaGFyQ29kZUF0KGEpCmlmKCEo
+cj49NDgmJnI8PTU3KSlicmVhawpxPXEqMTArKHItNDgpfWQucHVzaChxKQpyZXR1cm4gYX0sCnQ6ZnVu
+Y3Rpb24oYSxiLGMsZCxlKXt2YXIgcyxyLHEscCxvLG4sbT1iKzEKZm9yKHM9Yy5sZW5ndGg7bTxzOysr
+bSl7cj1jLmNoYXJDb2RlQXQobSkKaWYocj09PTQ2KXtpZihlKWJyZWFrCmU9ITB9ZWxzZXtpZighKCgo
+KHJ8MzIpPj4+MCktOTcmNjU1MzUpPDI2fHxyPT09OTV8fHI9PT0zNikpcT1yPj00OCYmcjw9NTcKZWxz
+ZSBxPSEwCmlmKCFxKWJyZWFrfX1wPWMuc3Vic3RyaW5nKGIsbSkKaWYoZSl7cz1hLnUKbz1hLmUKaWYo
+by55PT09MTApbz1vLnoKbj1ILlFvKHMsby56KVtwXQppZihuPT1udWxsKUgudignTm8gIicrcCsnIiBp
+biAiJytILm1EKG8pKyciJykKZC5wdXNoKEguY0UocyxvLG4pKX1lbHNlIGQucHVzaChwKQpyZXR1cm4g
+bX0sCkk6ZnVuY3Rpb24oYSxiKXt2YXIgcz1iLnBvcCgpCmlmKDA9PT1zKXtiLnB1c2goSC5tKGEudSwx
+LCIwJiIpKQpyZXR1cm59aWYoMT09PXMpe2IucHVzaChILm0oYS51LDQsIjEmIikpCnJldHVybn10aHJv
+dyBILmIoUC5oVigiVW5leHBlY3RlZCBleHRlbmRlZCBvcGVyYXRpb24gIitILkVqKHMpKSl9LApLOmZ1
+bmN0aW9uKGEsYixjKXtpZih0eXBlb2YgYz09InN0cmluZyIpcmV0dXJuIEguSihhLGMsYS5zRUEpCmVs
+c2UgaWYodHlwZW9mIGM9PSJudW1iZXIiKXJldHVybiBILlRWKGEsYixjKQplbHNlIHJldHVybiBjfSwK
+cjpmdW5jdGlvbihhLGIsYyl7dmFyIHMscj1jLmxlbmd0aApmb3Iocz0wO3M8cjsrK3MpY1tzXT1ILkso
+YSxiLGNbc10pfSwKeTpmdW5jdGlvbihhLGIsYyl7dmFyIHMscj1jLmxlbmd0aApmb3Iocz0yO3M8cjtz
+Kz0zKWNbc109SC5LKGEsYixjW3NdKX0sClRWOmZ1bmN0aW9uKGEsYixjKXt2YXIgcyxyLHE9Yi55Cmlm
+KHE9PT0xMCl7aWYoYz09PTApcmV0dXJuIGIuegpzPWIuUQpyPXMubGVuZ3RoCmlmKGM8PXIpcmV0dXJu
+IHNbYy0xXQpjLT1yCmI9Yi56CnE9Yi55fWVsc2UgaWYoYz09PTApcmV0dXJuIGIKaWYocSE9PTkpdGhy
+b3cgSC5iKFAuaFYoIkluZGV4ZWQgYmFzZSBtdXN0IGJlIGFuIGludGVyZmFjZSB0eXBlIikpCnM9Yi5R
+CmlmKGM8PXMubGVuZ3RoKXJldHVybiBzW2MtMV0KdGhyb3cgSC5iKFAuaFYoIkJhZCBpbmRleCAiK2Mr
+IiBmb3IgIitiLncoMCkpKX0sCldlOmZ1bmN0aW9uKGEsYixjLGQsZSl7dmFyIHMscixxLHAsbyxuLG0s
+bCxrLGoKaWYoYj09PWQpcmV0dXJuITAKaWYoIUguQTgoZCkpaWYoIShkPT09dC5fKSlzPWQ9PT10LksK
+ZWxzZSBzPSEwCmVsc2Ugcz0hMAppZihzKXJldHVybiEwCnI9Yi55CmlmKHI9PT00KXJldHVybiEwCmlm
+KEguQTgoYikpcmV0dXJuITEKaWYoYi55IT09MSlzPWI9PT10LlB8fGI9PT10LlQKZWxzZSBzPSEwCmlm
+KHMpcmV0dXJuITAKcT1yPT09MTMKaWYocSlpZihILldlKGEsY1tiLnpdLGMsZCxlKSlyZXR1cm4hMApw
+PWQueQppZihyPT09NilyZXR1cm4gSC5XZShhLGIueixjLGQsZSkKaWYocD09PTYpe3M9ZC56CnJldHVy
+biBILldlKGEsYixjLHMsZSl9aWYocj09PTgpe2lmKCFILldlKGEsYi56LGMsZCxlKSlyZXR1cm4hMQpy
+ZXR1cm4gSC5XZShhLEgueFooYSxiKSxjLGQsZSl9aWYocj09PTcpe3M9SC5XZShhLGIueixjLGQsZSkK
+cmV0dXJuIHN9aWYocD09PTgpe2lmKEguV2UoYSxiLGMsZC56LGUpKXJldHVybiEwCnJldHVybiBILldl
+KGEsYixjLEgueFooYSxkKSxlKX1pZihwPT09Nyl7cz1ILldlKGEsYixjLGQueixlKQpyZXR1cm4gc31p
+ZihxKXJldHVybiExCnM9ciE9PTExCmlmKCghc3x8cj09PTEyKSYmZD09PXQuWSlyZXR1cm4hMAppZihw
+PT09MTIpe2lmKGI9PT10LkQpcmV0dXJuITAKaWYociE9PTEyKXJldHVybiExCm89Yi5RCm49ZC5RCm09
+by5sZW5ndGgKaWYobSE9PW4ubGVuZ3RoKXJldHVybiExCmM9Yz09bnVsbD9vOm8uY29uY2F0KGMpCmU9
+ZT09bnVsbD9uOm4uY29uY2F0KGUpCmZvcihsPTA7bDxtOysrbCl7az1vW2xdCmo9bltsXQppZighSC5X
+ZShhLGssYyxqLGUpfHwhSC5XZShhLGosZSxrLGMpKXJldHVybiExfXJldHVybiBILmJPKGEsYi56LGMs
+ZC56LGUpfWlmKHA9PT0xMSl7aWYoYj09PXQuRClyZXR1cm4hMAppZihzKXJldHVybiExCnJldHVybiBI
+LmJPKGEsYixjLGQsZSl9aWYocj09PTkpe2lmKHAhPT05KXJldHVybiExCnJldHVybiBILnBHKGEsYixj
+LGQsZSl9cmV0dXJuITF9LApiTzpmdW5jdGlvbihhMixhMyxhNCxhNSxhNil7dmFyIHMscixxLHAsbyxu
+LG0sbCxrLGosaSxoLGcsZixlLGQsYyxiLGEsYTAsYTEKaWYoIUguV2UoYTIsYTMueixhNCxhNS56LGE2
+KSlyZXR1cm4hMQpzPWEzLlEKcj1hNS5RCnE9cy5hCnA9ci5hCm89cS5sZW5ndGgKbj1wLmxlbmd0aApp
+ZihvPm4pcmV0dXJuITEKbT1uLW8KbD1zLmIKaz1yLmIKaj1sLmxlbmd0aAppPWsubGVuZ3RoCmlmKG8r
+ajxuK2kpcmV0dXJuITEKZm9yKGg9MDtoPG87KytoKXtnPXFbaF0KaWYoIUguV2UoYTIscFtoXSxhNixn
+LGE0KSlyZXR1cm4hMX1mb3IoaD0wO2g8bTsrK2gpe2c9bFtoXQppZighSC5XZShhMixwW28raF0sYTYs
+ZyxhNCkpcmV0dXJuITF9Zm9yKGg9MDtoPGk7KytoKXtnPWxbbStoXQppZighSC5XZShhMixrW2hdLGE2
+LGcsYTQpKXJldHVybiExfWY9cy5jCmU9ci5jCmQ9Zi5sZW5ndGgKYz1lLmxlbmd0aApmb3IoYj0wLGE9
+MDthPGM7YSs9Myl7YTA9ZVthXQpmb3IoOyEwOyl7aWYoYj49ZClyZXR1cm4hMQphMT1mW2JdCmIrPTMK
+aWYoYTA8YTEpcmV0dXJuITEKaWYoYTE8YTApY29udGludWUKZz1mW2ItMV0KaWYoIUguV2UoYTIsZVth
+KzJdLGE2LGcsYTQpKXJldHVybiExCmJyZWFrfX1yZXR1cm4hMH0sCnBHOmZ1bmN0aW9uKGEsYixjLGQs
+ZSl7dmFyIHMscixxLHAsbyxuLG0sbCxrPWIueixqPWQuegppZihrPT09ail7cz1iLlEKcj1kLlEKcT1z
+Lmxlbmd0aApmb3IocD0wO3A8cTsrK3Ape289c1twXQpuPXJbcF0KaWYoIUguV2UoYSxvLGMsbixlKSly
+ZXR1cm4hMX1yZXR1cm4hMH1pZihkPT09dC5LKXJldHVybiEwCm09SC5RbyhhLGspCmlmKG09PW51bGwp
+cmV0dXJuITEKbD1tW2pdCmlmKGw9PW51bGwpcmV0dXJuITEKcT1sLmxlbmd0aApyPWQuUQpmb3IocD0w
+O3A8cTsrK3ApaWYoIUguV2UoYSxILmNFKGEsYixsW3BdKSxjLHJbcF0sZSkpcmV0dXJuITEKcmV0dXJu
+ITB9LApsUjpmdW5jdGlvbihhKXt2YXIgcyxyPWEueQppZighKGE9PT10LlB8fGE9PT10LlQpKWlmKCFI
+LkE4KGEpKWlmKHIhPT03KWlmKCEocj09PTYmJkgubFIoYS56KSkpcz1yPT09OCYmSC5sUihhLnopCmVs
+c2Ugcz0hMAplbHNlIHM9ITAKZWxzZSBzPSEwCmVsc2Ugcz0hMApyZXR1cm4gc30sCmNjOmZ1bmN0aW9u
+KGEpe3ZhciBzCmlmKCFILkE4KGEpKWlmKCEoYT09PXQuXykpcz1hPT09dC5LCmVsc2Ugcz0hMAplbHNl
+IHM9ITAKcmV0dXJuIHN9LApBODpmdW5jdGlvbihhKXt2YXIgcz1hLnkKcmV0dXJuIHM9PT0yfHxzPT09
+M3x8cz09PTR8fHM9PT01fHxhPT09dC5XfSwKSXg6ZnVuY3Rpb24oYSxiKXt2YXIgcyxyLHE9T2JqZWN0
+LmtleXMoYikscD1xLmxlbmd0aApmb3Iocz0wO3M8cDsrK3Mpe3I9cVtzXQphW3JdPWJbcl19fSwKSmM6
+ZnVuY3Rpb24gSmMoYSxiKXt2YXIgXz10aGlzCl8uYT1hCl8uYj1iCl8ueD1fLnI9Xy5jPW51bGwKXy55
+PTAKXy5jeT1fLmN4PV8uY2g9Xy5RPV8uej1udWxsfSwKRzpmdW5jdGlvbiBHKCl7dGhpcy5jPXRoaXMu
+Yj10aGlzLmE9bnVsbH0sCmxZOmZ1bmN0aW9uIGxZKGEpe3RoaXMuYT1hfSwKa1M6ZnVuY3Rpb24ga1Mo
+KXt9LAppTTpmdW5jdGlvbiBpTShhKXt0aGlzLmE9YX0sClI5OmZ1bmN0aW9uKGEpe3JldHVybiB0Lncu
+YihhKXx8dC5CLmIoYSl8fHQuZHouYihhKXx8dC5JLmIoYSl8fHQuQS5iKGEpfHx0Lmc0LmIoYSl8fHQu
+ZzIuYihhKX0sCkpnOmZ1bmN0aW9uKGEpe3JldHVybiB2Lm1hbmdsZWRHbG9iYWxOYW1lc1thXX19LEo9
+ewpRdTpmdW5jdGlvbihhLGIsYyxkKXtyZXR1cm57aTphLHA6YixlOmMseDpkfX0sCmtzOmZ1bmN0aW9u
+KGEpe3ZhciBzLHIscSxwLG89YVt2LmRpc3BhdGNoUHJvcGVydHlOYW1lXQppZihvPT1udWxsKWlmKCQu
+QnY9PW51bGwpe0guWEQoKQpvPWFbdi5kaXNwYXRjaFByb3BlcnR5TmFtZV19aWYobyE9bnVsbCl7cz1v
+LnAKaWYoITE9PT1zKXJldHVybiBvLmkKaWYoITA9PT1zKXJldHVybiBhCnI9T2JqZWN0LmdldFByb3Rv
+dHlwZU9mKGEpCmlmKHM9PT1yKXJldHVybiBvLmkKaWYoby5lPT09cil0aHJvdyBILmIoUC5TWSgiUmV0
+dXJuIGludGVyY2VwdG9yIGZvciAiK0guRWoocyhhLG8pKSkpfXE9YS5jb25zdHJ1Y3RvcgpwPXE9PW51
+bGw/bnVsbDpxW0ouUlAoKV0KaWYocCE9bnVsbClyZXR1cm4gcApwPUgudzMoYSkKaWYocCE9bnVsbCly
+ZXR1cm4gcAppZih0eXBlb2YgYT09ImZ1bmN0aW9uIilyZXR1cm4gQy5ERwpzPU9iamVjdC5nZXRQcm90
+b3R5cGVPZihhKQppZihzPT1udWxsKXJldHVybiBDLlpRCmlmKHM9PT1PYmplY3QucHJvdG90eXBlKXJl
+dHVybiBDLlpRCmlmKHR5cGVvZiBxPT0iZnVuY3Rpb24iKXtPYmplY3QuZGVmaW5lUHJvcGVydHkocSxK
+LlJQKCkse3ZhbHVlOkMudkIsZW51bWVyYWJsZTpmYWxzZSx3cml0YWJsZTp0cnVlLGNvbmZpZ3VyYWJs
+ZTp0cnVlfSkKcmV0dXJuIEMudkJ9cmV0dXJuIEMudkJ9LApSUDpmdW5jdGlvbigpe3ZhciBzPSQuem0K
+cmV0dXJuIHM9PW51bGw/JC56bT12LmdldElzb2xhdGVUYWcoIl8kZGFydF9qcyIpOnN9LApRaTpmdW5j
+dGlvbihhLGIpe2lmKGE8MHx8YT40Mjk0OTY3Mjk1KXRocm93IEguYihQLlRFKGEsMCw0Mjk0OTY3Mjk1
+LCJsZW5ndGgiLG51bGwpKQpyZXR1cm4gSi5weShuZXcgQXJyYXkoYSksYil9LApLaDpmdW5jdGlvbihh
+LGIpe2lmKGE8MCl0aHJvdyBILmIoUC54WSgiTGVuZ3RoIG11c3QgYmUgYSBub24tbmVnYXRpdmUgaW50
+ZWdlcjogIithKSkKcmV0dXJuIEguVk0obmV3IEFycmF5KGEpLGIuQygiamQ8MD4iKSl9LApweTpmdW5j
+dGlvbihhLGIpe3JldHVybiBKLkVwKEguVk0oYSxiLkMoImpkPDA+IikpLGIpfSwKRXA6ZnVuY3Rpb24o
+YSxiKXthLmZpeGVkJGxlbmd0aD1BcnJheQpyZXR1cm4gYX0sCnpDOmZ1bmN0aW9uKGEpe2EuZml4ZWQk
+bGVuZ3RoPUFycmF5CmEuaW1tdXRhYmxlJGxpc3Q9QXJyYXkKcmV0dXJuIGF9LApHYTpmdW5jdGlvbihh
+KXtpZihhPDI1Nilzd2l0Y2goYSl7Y2FzZSA5OmNhc2UgMTA6Y2FzZSAxMTpjYXNlIDEyOmNhc2UgMTM6
+Y2FzZSAzMjpjYXNlIDEzMzpjYXNlIDE2MDpyZXR1cm4hMApkZWZhdWx0OnJldHVybiExfXN3aXRjaChh
+KXtjYXNlIDU3NjA6Y2FzZSA4MTkyOmNhc2UgODE5MzpjYXNlIDgxOTQ6Y2FzZSA4MTk1OmNhc2UgODE5
+NjpjYXNlIDgxOTc6Y2FzZSA4MTk4OmNhc2UgODE5OTpjYXNlIDgyMDA6Y2FzZSA4MjAxOmNhc2UgODIw
+MjpjYXNlIDgyMzI6Y2FzZSA4MjMzOmNhc2UgODIzOTpjYXNlIDgyODc6Y2FzZSAxMjI4ODpjYXNlIDY1
+Mjc5OnJldHVybiEwCmRlZmF1bHQ6cmV0dXJuITF9fSwKbW06ZnVuY3Rpb24oYSxiKXt2YXIgcyxyCmZv
+cihzPWEubGVuZ3RoO2I8czspe3I9Qy54Qi5XKGEsYikKaWYociE9PTMyJiZyIT09MTMmJiFKLkdhKHIp
+KWJyZWFrOysrYn1yZXR1cm4gYn0sCmMxOmZ1bmN0aW9uKGEsYil7dmFyIHMscgpmb3IoO2I+MDtiPXMp
+e3M9Yi0xCnI9Qy54Qi5PMihhLHMpCmlmKHIhPT0zMiYmciE9PTEzJiYhSi5HYShyKSlicmVha31yZXR1
+cm4gYn0sClRKOmZ1bmN0aW9uKGEpe2lmKHR5cGVvZiBhPT0ibnVtYmVyIilyZXR1cm4gSi5xSS5wcm90
+b3R5cGUKaWYodHlwZW9mIGE9PSJzdHJpbmciKXJldHVybiBKLkRyLnByb3RvdHlwZQppZihhPT1udWxs
+KXJldHVybiBhCmlmKGEuY29uc3RydWN0b3I9PUFycmF5KXJldHVybiBKLmpkLnByb3RvdHlwZQppZih0
+eXBlb2YgYSE9Im9iamVjdCIpe2lmKHR5cGVvZiBhPT0iZnVuY3Rpb24iKXJldHVybiBKLmM1LnByb3Rv
+dHlwZQpyZXR1cm4gYX1pZihhIGluc3RhbmNlb2YgUC5NaClyZXR1cm4gYQpyZXR1cm4gSi5rcyhhKX0s
+ClU2OmZ1bmN0aW9uKGEpe2lmKHR5cGVvZiBhPT0ic3RyaW5nIilyZXR1cm4gSi5Eci5wcm90b3R5cGUK
+aWYoYT09bnVsbClyZXR1cm4gYQppZihhLmNvbnN0cnVjdG9yPT1BcnJheSlyZXR1cm4gSi5qZC5wcm90
+b3R5cGUKaWYodHlwZW9mIGEhPSJvYmplY3QiKXtpZih0eXBlb2YgYT09ImZ1bmN0aW9uIilyZXR1cm4g
+Si5jNS5wcm90b3R5cGUKcmV0dXJuIGF9aWYoYSBpbnN0YW5jZW9mIFAuTWgpcmV0dXJuIGEKcmV0dXJu
+IEoua3MoYSl9LApZRTpmdW5jdGlvbihhKXtpZihhPT1udWxsKXJldHVybiBhCmlmKHR5cGVvZiBhIT0i
+b2JqZWN0Iil7aWYodHlwZW9mIGE9PSJmdW5jdGlvbiIpcmV0dXJuIEouYzUucHJvdG90eXBlCnJldHVy
+biBhfWlmKGEgaW5zdGFuY2VvZiBQLk1oKXJldHVybiBhCnJldHVybiBKLmtzKGEpfSwKaWE6ZnVuY3Rp
+b24oYSl7aWYodHlwZW9mIGE9PSJudW1iZXIiKXtpZihNYXRoLmZsb29yKGEpPT1hKXJldHVybiBKLmJV
+LnByb3RvdHlwZQpyZXR1cm4gSi5WQS5wcm90b3R5cGV9aWYodHlwZW9mIGE9PSJzdHJpbmciKXJldHVy
+biBKLkRyLnByb3RvdHlwZQppZihhPT1udWxsKXJldHVybiBKLndlLnByb3RvdHlwZQppZih0eXBlb2Yg
+YT09ImJvb2xlYW4iKXJldHVybiBKLnlFLnByb3RvdHlwZQppZihhLmNvbnN0cnVjdG9yPT1BcnJheSly
+ZXR1cm4gSi5qZC5wcm90b3R5cGUKaWYodHlwZW9mIGEhPSJvYmplY3QiKXtpZih0eXBlb2YgYT09ImZ1
+bmN0aW9uIilyZXR1cm4gSi5jNS5wcm90b3R5cGUKcmV0dXJuIGF9aWYoYSBpbnN0YW5jZW9mIFAuTWgp
+cmV0dXJuIGEKcmV0dXJuIEoua3MoYSl9LApyWTpmdW5jdGlvbihhKXtpZih0eXBlb2YgYT09InN0cmlu
+ZyIpcmV0dXJuIEouRHIucHJvdG90eXBlCmlmKGE9PW51bGwpcmV0dXJuIGEKaWYoIShhIGluc3RhbmNl
+b2YgUC5NaCkpcmV0dXJuIEoua2QucHJvdG90eXBlCnJldHVybiBhfSwKdmQ6ZnVuY3Rpb24oYSl7aWYo
+dHlwZW9mIGE9PSJudW1iZXIiKXJldHVybiBKLnFJLnByb3RvdHlwZQppZihhPT1udWxsKXJldHVybiBh
+CmlmKCEoYSBpbnN0YW5jZW9mIFAuTWgpKXJldHVybiBKLmtkLnByb3RvdHlwZQpyZXR1cm4gYX0sCncx
+OmZ1bmN0aW9uKGEpe2lmKGE9PW51bGwpcmV0dXJuIGEKaWYoYS5jb25zdHJ1Y3Rvcj09QXJyYXkpcmV0
+dXJuIEouamQucHJvdG90eXBlCmlmKHR5cGVvZiBhIT0ib2JqZWN0Iil7aWYodHlwZW9mIGE9PSJmdW5j
+dGlvbiIpcmV0dXJuIEouYzUucHJvdG90eXBlCnJldHVybiBhfWlmKGEgaW5zdGFuY2VvZiBQLk1oKXJl
+dHVybiBhCnJldHVybiBKLmtzKGEpfSwKQTU6ZnVuY3Rpb24oYSxiKXtyZXR1cm4gSi53MShhKS5lUihh
+LGIpfSwKRWg6ZnVuY3Rpb24oYSxiLGMpe3JldHVybiBKLllFKGEpLm1LKGEsYixjKX0sCkVsOmZ1bmN0
+aW9uKGEsYil7cmV0dXJuIEoudzEoYSkuZHIoYSxiKX0sCkY3OmZ1bmN0aW9uKGEpe3JldHVybiBKLlU2
+KGEpLmdvcihhKX0sCkZMOmZ1bmN0aW9uKGEsYil7cmV0dXJuIEouclkoYSkuZGQoYSxiKX0sCkdBOmZ1
+bmN0aW9uKGEsYil7cmV0dXJuIEoudzEoYSkuRShhLGIpfSwKSG06ZnVuY3Rpb24oYSl7cmV0dXJuIEou
+VTYoYSkuZ0EoYSl9LApJVDpmdW5jdGlvbihhKXtyZXR1cm4gSi53MShhKS5nbShhKX0sCkp5OmZ1bmN0
+aW9uKGEsYil7cmV0dXJuIEouaWEoYSkuZTcoYSxiKX0sCktWOmZ1bmN0aW9uKGEsYil7cmV0dXJuIEou
+clkoYSkueW4oYSxiKX0sCkx0OmZ1bmN0aW9uKGEpe3JldHVybiBKLllFKGEpLndnKGEpfSwKTTE6ZnVu
+Y3Rpb24oYSxiLGMpe3JldHVybiBKLncxKGEpLkUyKGEsYixjKX0sCk11OmZ1bmN0aW9uKGEsYil7cmV0
+dXJuIEouWUUoYSkuc24oYSxiKX0sClF6OmZ1bmN0aW9uKGEsYil7cmV0dXJuIEouclkoYSkuVyhhLGIp
+fSwKUk06ZnVuY3Rpb24oYSxiKXtpZihhPT1udWxsKXJldHVybiBiPT1udWxsCmlmKHR5cGVvZiBhIT0i
+b2JqZWN0IilyZXR1cm4gYiE9bnVsbCYmYT09PWIKcmV0dXJuIEouaWEoYSkuRE4oYSxiKX0sClJYOmZ1
+bmN0aW9uKGEpe3JldHVybiBKLncxKGEpLmJyKGEpfSwKVDA6ZnVuY3Rpb24oYSl7cmV0dXJuIEouclko
+YSkuYlMoYSl9LApWdTpmdW5jdGlvbihhKXtyZXR1cm4gSi52ZChhKS56UShhKX0sCmE2OmZ1bmN0aW9u
+KGEsYil7cmV0dXJuIEouclkoYSkuTzIoYSxiKX0sCmJUOmZ1bmN0aW9uKGEpe3JldHVybiBKLllFKGEp
+LkQ0KGEpfSwKYmI6ZnVuY3Rpb24oYSxiKXtpZih0eXBlb2YgYT09Im51bWJlciImJnR5cGVvZiBiPT0i
+bnVtYmVyIilyZXR1cm4gYStiCnJldHVybiBKLlRKKGEpLmgoYSxiKX0sCmNIOmZ1bmN0aW9uKGEpe3Jl
+dHVybiBKLnJZKGEpLmhjKGEpfSwKZFI6ZnVuY3Rpb24oYSl7cmV0dXJuIEouWUUoYSkuZ24oYSl9LApk
+WjpmdW5jdGlvbihhLGIsYyxkKXtyZXR1cm4gSi5ZRShhKS5PbihhLGIsYyxkKX0sCmRnOmZ1bmN0aW9u
+KGEsYixjLGQpe3JldHVybiBKLnJZKGEpLmk3KGEsYixjLGQpfSwKZGg6ZnVuY3Rpb24oYSl7cmV0dXJu
+IEouWUUoYSkuRkYoYSl9LApkcjpmdW5jdGlvbihhLGIpe3JldHVybiBKLllFKGEpLnNhNChhLGIpfSwK
+aGY6ZnVuY3Rpb24oYSl7cmV0dXJuIEouaWEoYSkuZ2lPKGEpfSwKaWc6ZnVuY3Rpb24oYSl7cmV0dXJu
+IEouWUUoYSkuZ1FnKGEpfSwKajpmdW5jdGlvbihhKXtyZXR1cm4gSi5pYShhKS53KGEpfSwKbDU6ZnVu
+Y3Rpb24oYSxiKXtyZXR1cm4gSi5ZRShhKS5zaGYoYSxiKX0sCmxkOmZ1bmN0aW9uKGEsYixjKXtyZXR1
+cm4gSi5yWShhKS5OaihhLGIsYyl9LApwNDpmdW5jdGlvbihhLGIpe3JldHVybiBKLnJZKGEpLlRjKGEs
+Yil9LApxMDpmdW5jdGlvbihhLGIsYyl7cmV0dXJuIEouclkoYSkuUWkoYSxiLGMpfSwKcUY6ZnVuY3Rp
+b24oYSl7cmV0dXJuIEouWUUoYSkuZ1ZsKGEpfSwKdEg6ZnVuY3Rpb24oYSxiLGMpe3JldHVybiBKLllF
+KGEpLnBrKGEsYixjKX0sCnU5OmZ1bmN0aW9uKGEsYixjKXtyZXR1cm4gSi53MShhKS5ZNShhLGIsYyl9
+LAp1VTpmdW5jdGlvbihhKXtyZXR1cm4gSi5VNihhKS5nbDAoYSl9LAp3ZjpmdW5jdGlvbihhLGIpe3Jl
+dHVybiBKLllFKGEpLnNSTihhLGIpfSwKeDk6ZnVuY3Rpb24oYSxiKXtpZih0eXBlb2YgYj09PSJudW1i
+ZXIiKWlmKGEuY29uc3RydWN0b3I9PUFycmF5fHx0eXBlb2YgYT09InN0cmluZyJ8fEgud1YoYSxhW3Yu
+ZGlzcGF0Y2hQcm9wZXJ0eU5hbWVdKSlpZihiPj4+MD09PWImJmI8YS5sZW5ndGgpcmV0dXJuIGFbYl0K
+cmV0dXJuIEouVTYoYSkucShhLGIpfSwKemw6ZnVuY3Rpb24oYSxiKXtyZXR1cm4gSi5VNihhKS50Zyhh
+LGIpfSwKR3Y6ZnVuY3Rpb24gR3YoKXt9LAp5RTpmdW5jdGlvbiB5RSgpe30sCndlOmZ1bmN0aW9uIHdl
+KCl7fSwKTUY6ZnVuY3Rpb24gTUYoKXt9LAppQzpmdW5jdGlvbiBpQygpe30sCmtkOmZ1bmN0aW9uIGtk
+KCl7fSwKYzU6ZnVuY3Rpb24gYzUoKXt9LApqZDpmdW5jdGlvbiBqZChhKXt0aGlzLiR0aT1hfSwKUG86
+ZnVuY3Rpb24gUG8oYSl7dGhpcy4kdGk9YX0sCm0xOmZ1bmN0aW9uIG0xKGEsYixjKXt2YXIgXz10aGlz
+Cl8uYT1hCl8uYj1iCl8uYz0wCl8uZD1udWxsCl8uJHRpPWN9LApxSTpmdW5jdGlvbiBxSSgpe30sCmJV
+OmZ1bmN0aW9uIGJVKCl7fSwKVkE6ZnVuY3Rpb24gVkEoKXt9LApEcjpmdW5jdGlvbiBEcigpe319LFA9
+ewpPajpmdW5jdGlvbigpe3ZhciBzLHIscT17fQppZihzZWxmLnNjaGVkdWxlSW1tZWRpYXRlIT1udWxs
+KXJldHVybiBQLkVYKCkKaWYoc2VsZi5NdXRhdGlvbk9ic2VydmVyIT1udWxsJiZzZWxmLmRvY3VtZW50
+IT1udWxsKXtzPXNlbGYuZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgiZGl2IikKcj1zZWxmLmRvY3VtZW50
+LmNyZWF0ZUVsZW1lbnQoInNwYW4iKQpxLmE9bnVsbApuZXcgc2VsZi5NdXRhdGlvbk9ic2VydmVyKEgu
+dFIobmV3IFAudGgocSksMSkpLm9ic2VydmUocyx7Y2hpbGRMaXN0OnRydWV9KQpyZXR1cm4gbmV3IFAu
+aGEocSxzLHIpfWVsc2UgaWYoc2VsZi5zZXRJbW1lZGlhdGUhPW51bGwpcmV0dXJuIFAueXQoKQpyZXR1
+cm4gUC5xVygpfSwKWlY6ZnVuY3Rpb24oYSl7c2VsZi5zY2hlZHVsZUltbWVkaWF0ZShILnRSKG5ldyBQ
+LlZzKHQuTS5hKGEpKSwwKSl9LApvQTpmdW5jdGlvbihhKXtzZWxmLnNldEltbWVkaWF0ZShILnRSKG5l
+dyBQLkZ0KHQuTS5hKGEpKSwwKSl9LApCejpmdW5jdGlvbihhKXt0Lk0uYShhKQpQLlFOKDAsYSl9LApR
+TjpmdW5jdGlvbihhLGIpe3ZhciBzPW5ldyBQLlczKCkKcy5DWShhLGIpCnJldHVybiBzfSwKRlg6ZnVu
+Y3Rpb24oYSl7cmV0dXJuIG5ldyBQLmloKG5ldyBQLnZzKCQuWDMsYS5DKCJ2czwwPiIpKSxhLkMoImlo
+PDA+IikpfSwKREk6ZnVuY3Rpb24oYSxiKXthLiQyKDAsbnVsbCkKYi5iPSEwCnJldHVybiBiLmF9LApq
+UTpmdW5jdGlvbihhLGIpe1AuSmUoYSxiKX0sCnlDOmZ1bmN0aW9uKGEsYil7Yi5hTSgwLGEpfSwKZjM6
+ZnVuY3Rpb24oYSxiKXtiLncwKEguUnUoYSksSC50cyhhKSl9LApKZTpmdW5jdGlvbihhLGIpe3ZhciBz
+LHIscT1uZXcgUC5XTShiKSxwPW5ldyBQLlNYKGIpCmlmKGEgaW5zdGFuY2VvZiBQLnZzKWEuUWQocSxw
+LHQueikKZWxzZXtzPXQuegppZih0LmQuYihhKSlhLlNxKHEscCxzKQplbHNle3I9bmV3IFAudnMoJC5Y
+Myx0LmMpCnIuYT00CnIuYz1hCnIuUWQocSxwLHMpfX19LApsejpmdW5jdGlvbihhKXt2YXIgcz1mdW5j
+dGlvbihiLGMpe3JldHVybiBmdW5jdGlvbihkLGUpe3doaWxlKHRydWUpdHJ5e2IoZCxlKQpicmVha31j
+YXRjaChyKXtlPXIKZD1jfX19KGEsMSkKcmV0dXJuICQuWDMuTGoobmV3IFAuR3MocyksdC5ILHQuUyx0
+LnopfSwKSUc6ZnVuY3Rpb24oYSl7cmV0dXJuIG5ldyBQLkZ5KGEsMSl9LApUaDpmdW5jdGlvbigpe3Jl
+dHVybiBDLndRfSwKWW06ZnVuY3Rpb24oYSl7cmV0dXJuIG5ldyBQLkZ5KGEsMyl9LApsMDpmdW5jdGlv
+bihhLGIpe3JldHVybiBuZXcgUC5xNChhLGIuQygicTQ8MD4iKSl9LAprMzpmdW5jdGlvbihhLGIpe3Zh
+ciBzLHIscQpiLmE9MQp0cnl7YS5TcShuZXcgUC5wVihiKSxuZXcgUC5VNyhiKSx0LlApfWNhdGNoKHEp
+e3M9SC5SdShxKQpyPUgudHMocSkKUC5yYihuZXcgUC52cihiLHMscikpfX0sCkE5OmZ1bmN0aW9uKGEs
+Yil7dmFyIHMscixxCmZvcihzPXQuYztyPWEuYSxyPT09MjspYT1zLmEoYS5jKQppZihyPj00KXtxPWIu
+YWgoKQpiLmE9YS5hCmIuYz1hLmMKUC5IWihiLHEpfWVsc2V7cT10LkYuYShiLmMpCmIuYT0yCmIuYz1h
+CmEualEocSl9fSwKSFo6ZnVuY3Rpb24oYTAsYTEpe3ZhciBzLHIscSxwLG8sbixtLGwsayxqLGksaCxn
+LGYsZSxkLGM9bnVsbCxiPXt9LGE9Yi5hPWEwCmZvcihzPXQubixyPXQuRixxPXQuZDshMDspe3A9e30K
+bz1hLmE9PT04CmlmKGExPT1udWxsKXtpZihvKXtuPXMuYShhLmMpClAuTDIoYyxjLGEuYixuLmEsbi5i
+KX1yZXR1cm59cC5hPWExCm09YTEuYQpmb3IoYT1hMTttIT1udWxsO2E9bSxtPWwpe2EuYT1udWxsClAu
+SFooYi5hLGEpCnAuYT1tCmw9bS5hfWs9Yi5hCmo9ay5jCnAuYj1vCnAuYz1qCmk9IW8KaWYoaSl7aD1h
+LmMKaD0oaCYxKSE9PTB8fChoJjE1KT09PTh9ZWxzZSBoPSEwCmlmKGgpe2c9YS5iLmIKaWYobyl7aD1r
+LmI9PT1nCmg9IShofHxoKX1lbHNlIGg9ITEKaWYoaCl7cy5hKGopClAuTDIoYyxjLGsuYixqLmEsai5i
+KQpyZXR1cm59Zj0kLlgzCmlmKGYhPT1nKSQuWDM9ZwplbHNlIGY9YwphPWEuYwppZigoYSYxNSk9PT04
+KW5ldyBQLlJUKHAsYixvKS4kMCgpCmVsc2UgaWYoaSl7aWYoKGEmMSkhPT0wKW5ldyBQLnJxKHAsaiku
+JDAoKX1lbHNlIGlmKChhJjIpIT09MCluZXcgUC5SVyhiLHApLiQwKCkKaWYoZiE9bnVsbCkkLlgzPWYK
+YT1wLmMKaWYocS5iKGEpKXtlPXAuYS5iCmlmKGEuYT49NCl7ZD1yLmEoZS5jKQplLmM9bnVsbAphMT1l
+Lk44KGQpCmUuYT1hLmEKZS5jPWEuYwpiLmE9YQpjb250aW51ZX1lbHNlIFAuQTkoYSxlKQpyZXR1cm59
+fWU9cC5hLmIKZD1yLmEoZS5jKQplLmM9bnVsbAphMT1lLk44KGQpCmE9cC5iCms9cC5jCmlmKCFhKXtl
+LiR0aS5jLmEoaykKZS5hPTQKZS5jPWt9ZWxzZXtzLmEoaykKZS5hPTgKZS5jPWt9Yi5hPWUKYT1lfX0s
+ClZIOmZ1bmN0aW9uKGEsYil7dmFyIHMKaWYodC5hZy5iKGEpKXJldHVybiBiLkxqKGEsdC56LHQuSyx0
+LmwpCnM9dC5iSQppZihzLmIoYSkpcmV0dXJuIHMuYShhKQp0aHJvdyBILmIoUC5MMyhhLCJvbkVycm9y
+IiwiRXJyb3IgaGFuZGxlciBtdXN0IGFjY2VwdCBvbmUgT2JqZWN0IG9yIG9uZSBPYmplY3QgYW5kIGEg
+U3RhY2tUcmFjZSBhcyBhcmd1bWVudHMsIGFuZCByZXR1cm4gYSBhIHZhbGlkIHJlc3VsdCIpKX0sCnB1
+OmZ1bmN0aW9uKCl7dmFyIHMscgpmb3Iocz0kLlM2O3MhPW51bGw7cz0kLlM2KXskLm1nPW51bGwKcj1z
+LmIKJC5TNj1yCmlmKHI9PW51bGwpJC5rOD1udWxsCnMuYS4kMCgpfX0sCmVOOmZ1bmN0aW9uKCl7JC5V
+RD0hMAp0cnl7UC5wdSgpfWZpbmFsbHl7JC5tZz1udWxsCiQuVUQ9ITEKaWYoJC5TNiE9bnVsbCkkLnV0
+KCkuJDEoUC5VSSgpKX19LAplVzpmdW5jdGlvbihhKXt2YXIgcz1uZXcgUC5PTShhKSxyPSQuazgKaWYo
+cj09bnVsbCl7JC5TNj0kLms4PXMKaWYoISQuVUQpJC51dCgpLiQxKFAuVUkoKSl9ZWxzZSAkLms4PXIu
+Yj1zfSwKclI6ZnVuY3Rpb24oYSl7dmFyIHMscixxLHA9JC5TNgppZihwPT1udWxsKXtQLmVXKGEpCiQu
+bWc9JC5rOApyZXR1cm59cz1uZXcgUC5PTShhKQpyPSQubWcKaWYocj09bnVsbCl7cy5iPXAKJC5TNj0k
+Lm1nPXN9ZWxzZXtxPXIuYgpzLmI9cQokLm1nPXIuYj1zCmlmKHE9PW51bGwpJC5rOD1zfX0sCnJiOmZ1
+bmN0aW9uKGEpe3ZhciBzPW51bGwscj0kLlgzCmlmKEMuTlU9PT1yKXtQLlRrKHMscyxDLk5VLGEpCnJl
+dHVybn1QLlRrKHMscyxyLHQuTS5hKHIudDgoYSkpKX0sClF3OmZ1bmN0aW9uKGEsYil7SC5jYihhLCJz
+dHJlYW0iLHQuSykKcmV0dXJuIG5ldyBQLnhJKGIuQygieEk8MD4iKSl9LApUbDpmdW5jdGlvbihhLGIp
+e3ZhciBzPUguY2IoYSwiZXJyb3IiLHQuSykKcmV0dXJuIG5ldyBQLkN3KHMsYj09bnVsbD9QLnYwKGEp
+OmIpfSwKdjA6ZnVuY3Rpb24oYSl7dmFyIHMKaWYodC5yLmIoYSkpe3M9YS5nSUkoKQppZihzIT1udWxs
+KXJldHVybiBzfXJldHVybiBDLnBkfSwKTDI6ZnVuY3Rpb24oYSxiLGMsZCxlKXtQLnJSKG5ldyBQLnBL
+KGQsZSkpfSwKVDg6ZnVuY3Rpb24oYSxiLGMsZCxlKXt2YXIgcyxyPSQuWDMKaWYocj09PWMpcmV0dXJu
+IGQuJDAoKQokLlgzPWMKcz1yCnRyeXtyPWQuJDAoKQpyZXR1cm4gcn1maW5hbGx5eyQuWDM9c319LAp5
+djpmdW5jdGlvbihhLGIsYyxkLGUsZixnKXt2YXIgcyxyPSQuWDMKaWYocj09PWMpcmV0dXJuIGQuJDEo
+ZSkKJC5YMz1jCnM9cgp0cnl7cj1kLiQxKGUpCnJldHVybiByfWZpbmFsbHl7JC5YMz1zfX0sClF4OmZ1
+bmN0aW9uKGEsYixjLGQsZSxmLGcsaCxpKXt2YXIgcyxyPSQuWDMKaWYocj09PWMpcmV0dXJuIGQuJDIo
+ZSxmKQokLlgzPWMKcz1yCnRyeXtyPWQuJDIoZSxmKQpyZXR1cm4gcn1maW5hbGx5eyQuWDM9c319LApU
+azpmdW5jdGlvbihhLGIsYyxkKXt2YXIgcwp0Lk0uYShkKQpzPUMuTlUhPT1jCmlmKHMpZD0hKCFzfHwh
+MSk/Yy50OChkKTpjLlJUKGQsdC5IKQpQLmVXKGQpfSwKdGg6ZnVuY3Rpb24gdGgoYSl7dGhpcy5hPWF9
+LApoYTpmdW5jdGlvbiBoYShhLGIsYyl7dGhpcy5hPWEKdGhpcy5iPWIKdGhpcy5jPWN9LApWczpmdW5j
+dGlvbiBWcyhhKXt0aGlzLmE9YX0sCkZ0OmZ1bmN0aW9uIEZ0KGEpe3RoaXMuYT1hfSwKVzM6ZnVuY3Rp
+b24gVzMoKXt9LAp5SDpmdW5jdGlvbiB5SChhLGIpe3RoaXMuYT1hCnRoaXMuYj1ifSwKaWg6ZnVuY3Rp
+b24gaWgoYSxiKXt0aGlzLmE9YQp0aGlzLmI9ITEKdGhpcy4kdGk9Yn0sCldNOmZ1bmN0aW9uIFdNKGEp
+e3RoaXMuYT1hfSwKU1g6ZnVuY3Rpb24gU1goYSl7dGhpcy5hPWF9LApHczpmdW5jdGlvbiBHcyhhKXt0
+aGlzLmE9YX0sCkZ5OmZ1bmN0aW9uIEZ5KGEsYil7dGhpcy5hPWEKdGhpcy5iPWJ9LApHVjpmdW5jdGlv
+biBHVihhLGIpe3ZhciBfPXRoaXMKXy5hPWEKXy5kPV8uYz1fLmI9bnVsbApfLiR0aT1ifSwKcTQ6ZnVu
+Y3Rpb24gcTQoYSxiKXt0aGlzLmE9YQp0aGlzLiR0aT1ifSwKUGY6ZnVuY3Rpb24gUGYoKXt9LApaZjpm
+dW5jdGlvbiBaZihhLGIpe3RoaXMuYT1hCnRoaXMuJHRpPWJ9LApGZTpmdW5jdGlvbiBGZShhLGIsYyxk
+LGUpe3ZhciBfPXRoaXMKXy5hPW51bGwKXy5iPWEKXy5jPWIKXy5kPWMKXy5lPWQKXy4kdGk9ZX0sCnZz
+OmZ1bmN0aW9uIHZzKGEsYil7dmFyIF89dGhpcwpfLmE9MApfLmI9YQpfLmM9bnVsbApfLiR0aT1ifSwK
+ZGE6ZnVuY3Rpb24gZGEoYSxiKXt0aGlzLmE9YQp0aGlzLmI9Yn0sCm9ROmZ1bmN0aW9uIG9RKGEsYil7
+dGhpcy5hPWEKdGhpcy5iPWJ9LApwVjpmdW5jdGlvbiBwVihhKXt0aGlzLmE9YX0sClU3OmZ1bmN0aW9u
+IFU3KGEpe3RoaXMuYT1hfSwKdnI6ZnVuY3Rpb24gdnIoYSxiLGMpe3RoaXMuYT1hCnRoaXMuYj1iCnRo
+aXMuYz1jfSwKcnQ6ZnVuY3Rpb24gcnQoYSxiKXt0aGlzLmE9YQp0aGlzLmI9Yn0sCktGOmZ1bmN0aW9u
+IEtGKGEsYil7dGhpcy5hPWEKdGhpcy5iPWJ9LApaTDpmdW5jdGlvbiBaTChhLGIsYyl7dGhpcy5hPWEK
+dGhpcy5iPWIKdGhpcy5jPWN9LApSVDpmdW5jdGlvbiBSVChhLGIsYyl7dGhpcy5hPWEKdGhpcy5iPWIK
+dGhpcy5jPWN9LApqWjpmdW5jdGlvbiBqWihhKXt0aGlzLmE9YX0sCnJxOmZ1bmN0aW9uIHJxKGEsYil7
+dGhpcy5hPWEKdGhpcy5iPWJ9LApSVzpmdW5jdGlvbiBSVyhhLGIpe3RoaXMuYT1hCnRoaXMuYj1ifSwK
+T006ZnVuY3Rpb24gT00oYSl7dGhpcy5hPWEKdGhpcy5iPW51bGx9LApxaDpmdW5jdGlvbiBxaCgpe30s
+CkI1OmZ1bmN0aW9uIEI1KGEsYil7dGhpcy5hPWEKdGhpcy5iPWJ9LAp1TzpmdW5jdGlvbiB1TyhhLGIp
+e3RoaXMuYT1hCnRoaXMuYj1ifSwKTU86ZnVuY3Rpb24gTU8oKXt9LAprVDpmdW5jdGlvbiBrVCgpe30s
+CnhJOmZ1bmN0aW9uIHhJKGEpe3RoaXMuJHRpPWF9LApDdzpmdW5jdGlvbiBDdyhhLGIpe3RoaXMuYT1h
+CnRoaXMuYj1ifSwKbTA6ZnVuY3Rpb24gbTAoKXt9LApwSzpmdW5jdGlvbiBwSyhhLGIpe3RoaXMuYT1h
+CnRoaXMuYj1ifSwKSmk6ZnVuY3Rpb24gSmkoKXt9LApoajpmdW5jdGlvbiBoaihhLGIsYyl7dGhpcy5h
+PWEKdGhpcy5iPWIKdGhpcy5jPWN9LApWcDpmdW5jdGlvbiBWcChhLGIpe3RoaXMuYT1hCnRoaXMuYj1i
+fSwKT1I6ZnVuY3Rpb24gT1IoYSxiLGMpe3RoaXMuYT1hCnRoaXMuYj1iCnRoaXMuYz1jfSwKRUY6ZnVu
+Y3Rpb24oYSxiLGMpe3JldHVybiBiLkMoIkA8MD4iKS5LcShjKS5DKCJGbzwxLDI+IikuYShILkI3KGEs
+bmV3IEguTjUoYi5DKCJAPDA+IikuS3EoYykuQygiTjU8MSwyPiIpKSkpfSwKRmw6ZnVuY3Rpb24oYSxi
+KXtyZXR1cm4gbmV3IEguTjUoYS5DKCJAPDA+IikuS3EoYikuQygiTjU8MSwyPiIpKX0sCkxzOmZ1bmN0
+aW9uKGEpe3JldHVybiBuZXcgUC5iNihhLkMoImI2PDA+IikpfSwKVDI6ZnVuY3Rpb24oKXt2YXIgcz1P
+YmplY3QuY3JlYXRlKG51bGwpCnNbIjxub24taWRlbnRpZmllci1rZXk+Il09cwpkZWxldGUgc1siPG5v
+bi1pZGVudGlmaWVyLWtleT4iXQpyZXR1cm4gc30sCnJqOmZ1bmN0aW9uKGEsYixjKXt2YXIgcz1uZXcg
+UC5sbShhLGIsYy5DKCJsbTwwPiIpKQpzLmM9YS5lCnJldHVybiBzfSwKRVA6ZnVuY3Rpb24oYSxiLGMp
+e3ZhciBzLHIKaWYoUC5oQihhKSl7aWYoYj09PSIoIiYmYz09PSIpIilyZXR1cm4iKC4uLikiCnJldHVy
+biBiKyIuLi4iK2N9cz1ILlZNKFtdLHQucykKQy5ObS5pKCQueGcsYSkKdHJ5e1AuVnIoYSxzKX1maW5h
+bGx5e2lmKDA+PSQueGcubGVuZ3RoKXJldHVybiBILk9IKCQueGcsLTEpCiQueGcucG9wKCl9cj1QLnZn
+KGIsdC51LmEocyksIiwgIikrYwpyZXR1cm4gci5jaGFyQ29kZUF0KDApPT0wP3I6cn0sCldFOmZ1bmN0
+aW9uKGEsYixjKXt2YXIgcyxyCmlmKFAuaEIoYSkpcmV0dXJuIGIrIi4uLiIrYwpzPW5ldyBQLlJuKGIp
+CkMuTm0uaSgkLnhnLGEpCnRyeXtyPXMKci5hPVAudmcoci5hLGEsIiwgIil9ZmluYWxseXtpZigwPj0k
+LnhnLmxlbmd0aClyZXR1cm4gSC5PSCgkLnhnLC0xKQokLnhnLnBvcCgpfXMuYSs9YwpyPXMuYQpyZXR1
+cm4gci5jaGFyQ29kZUF0KDApPT0wP3I6cn0sCmhCOmZ1bmN0aW9uKGEpe3ZhciBzLHIKZm9yKHM9JC54
+Zy5sZW5ndGgscj0wO3I8czsrK3IpaWYoYT09PSQueGdbcl0pcmV0dXJuITAKcmV0dXJuITF9LApWcjpm
+dW5jdGlvbihhLGIpe3ZhciBzLHIscSxwLG8sbixtLGw9YS5nbShhKSxrPTAsaj0wCndoaWxlKCEwKXtp
+ZighKGs8ODB8fGo8MykpYnJlYWsKaWYoIWwuRigpKXJldHVybgpzPUguRWoobC5nbCgpKQpDLk5tLmko
+YixzKQprKz1zLmxlbmd0aCsyOysran1pZighbC5GKCkpe2lmKGo8PTUpcmV0dXJuCmlmKDA+PWIubGVu
+Z3RoKXJldHVybiBILk9IKGIsLTEpCnI9Yi5wb3AoKQppZigwPj1iLmxlbmd0aClyZXR1cm4gSC5PSChi
+LC0xKQpxPWIucG9wKCl9ZWxzZXtwPWwuZ2woKTsrK2oKaWYoIWwuRigpKXtpZihqPD00KXtDLk5tLmko
+YixILkVqKHApKQpyZXR1cm59cj1ILkVqKHApCmlmKDA+PWIubGVuZ3RoKXJldHVybiBILk9IKGIsLTEp
+CnE9Yi5wb3AoKQprKz1yLmxlbmd0aCsyfWVsc2V7bz1sLmdsKCk7KytqCmZvcig7bC5GKCk7cD1vLG89
+bil7bj1sLmdsKCk7KytqCmlmKGo+MTAwKXt3aGlsZSghMCl7aWYoIShrPjc1JiZqPjMpKWJyZWFrCmlm
+KDA+PWIubGVuZ3RoKXJldHVybiBILk9IKGIsLTEpCmstPWIucG9wKCkubGVuZ3RoKzI7LS1qfUMuTm0u
+aShiLCIuLi4iKQpyZXR1cm59fXE9SC5FaihwKQpyPUguRWoobykKays9ci5sZW5ndGgrcS5sZW5ndGgr
+NH19aWYoaj5iLmxlbmd0aCsyKXtrKz01Cm09Ii4uLiJ9ZWxzZSBtPW51bGwKd2hpbGUoITApe2lmKCEo
+az44MCYmYi5sZW5ndGg+MykpYnJlYWsKaWYoMD49Yi5sZW5ndGgpcmV0dXJuIEguT0goYiwtMSkKay09
+Yi5wb3AoKS5sZW5ndGgrMgppZihtPT1udWxsKXtrKz01Cm09Ii4uLiJ9fWlmKG0hPW51bGwpQy5ObS5p
+KGIsbSkKQy5ObS5pKGIscSkKQy5ObS5pKGIscil9LAp0TTpmdW5jdGlvbihhLGIpe3ZhciBzLHIscT1Q
+LkxzKGIpCmZvcihzPWEubGVuZ3RoLHI9MDtyPGEubGVuZ3RoO2EubGVuZ3RoPT09c3x8KDAsSC5sayko
+YSksKytyKXEuaSgwLGIuYShhW3JdKSkKcmV0dXJuIHF9LApuTzpmdW5jdGlvbihhKXt2YXIgcyxyPXt9
+CmlmKFAuaEIoYSkpcmV0dXJuInsuLi59IgpzPW5ldyBQLlJuKCIiKQp0cnl7Qy5ObS5pKCQueGcsYSkK
+cy5hKz0ieyIKci5hPSEwCmEuSygwLG5ldyBQLnJhKHIscykpCnMuYSs9In0ifWZpbmFsbHl7aWYoMD49
+JC54Zy5sZW5ndGgpcmV0dXJuIEguT0goJC54ZywtMSkKJC54Zy5wb3AoKX1yPXMuYQpyZXR1cm4gci5j
+aGFyQ29kZUF0KDApPT0wP3I6cn0sCmI2OmZ1bmN0aW9uIGI2KGEpe3ZhciBfPXRoaXMKXy5hPTAKXy5m
+PV8uZT1fLmQ9Xy5jPV8uYj1udWxsCl8ucj0wCl8uJHRpPWF9LApibjpmdW5jdGlvbiBibihhKXt0aGlz
+LmE9YQp0aGlzLmM9dGhpcy5iPW51bGx9LApsbTpmdW5jdGlvbiBsbShhLGIsYyl7dmFyIF89dGhpcwpf
+LmE9YQpfLmI9YgpfLmQ9Xy5jPW51bGwKXy4kdGk9Y30sCm1XOmZ1bmN0aW9uIG1XKCl7fSwKdXk6ZnVu
+Y3Rpb24gdXkoKXt9LApsRDpmdW5jdGlvbiBsRCgpe30sCmlsOmZ1bmN0aW9uIGlsKCl7fSwKcmE6ZnVu
+Y3Rpb24gcmEoYSxiKXt0aGlzLmE9YQp0aGlzLmI9Yn0sCllrOmZ1bmN0aW9uIFlrKCl7fSwKeVE6ZnVu
+Y3Rpb24geVEoYSl7dGhpcy5hPWF9LApLUDpmdW5jdGlvbiBLUCgpe30sClBuOmZ1bmN0aW9uIFBuKCl7
+fSwKR2o6ZnVuY3Rpb24gR2ooYSxiKXt0aGlzLmE9YQp0aGlzLiR0aT1ifSwKbGY6ZnVuY3Rpb24gbGYo
+KXt9LApWajpmdW5jdGlvbiBWaigpe30sClh2OmZ1bmN0aW9uIFh2KCl7fSwKblk6ZnVuY3Rpb24gblko
+KXt9LApXWTpmdW5jdGlvbiBXWSgpe30sClJVOmZ1bmN0aW9uIFJVKCl7fSwKcFI6ZnVuY3Rpb24gcFIo
+KXt9LApCUzpmdW5jdGlvbihhLGIpe3ZhciBzLHIscSxwCmlmKHR5cGVvZiBhIT0ic3RyaW5nIil0aHJv
+dyBILmIoSC50TChhKSkKcz1udWxsCnRyeXtzPUpTT04ucGFyc2UoYSl9Y2F0Y2gocSl7cj1ILlJ1KHEp
+CnA9UC5ycihTdHJpbmcociksbnVsbCxudWxsKQp0aHJvdyBILmIocCl9cD1QLlFlKHMpCnJldHVybiBw
+fSwKUWU6ZnVuY3Rpb24oYSl7dmFyIHMKaWYoYT09bnVsbClyZXR1cm4gbnVsbAppZih0eXBlb2YgYSE9
+Im9iamVjdCIpcmV0dXJuIGEKaWYoT2JqZWN0LmdldFByb3RvdHlwZU9mKGEpIT09QXJyYXkucHJvdG90
+eXBlKXJldHVybiBuZXcgUC51dyhhLE9iamVjdC5jcmVhdGUobnVsbCkpCmZvcihzPTA7czxhLmxlbmd0
+aDsrK3MpYVtzXT1QLlFlKGFbc10pCnJldHVybiBhfSwKa3k6ZnVuY3Rpb24oYSxiLGMsZCl7dmFyIHMs
+cgppZihiIGluc3RhbmNlb2YgVWludDhBcnJheSl7cz1iCmQ9cy5sZW5ndGgKaWYoZC1jPDE1KXJldHVy
+biBudWxsCnI9UC5DRyhhLHMsYyxkKQppZihyIT1udWxsJiZhKWlmKHIuaW5kZXhPZigiXHVmZmZkIik+
+PTApcmV0dXJuIG51bGwKcmV0dXJuIHJ9cmV0dXJuIG51bGx9LApDRzpmdW5jdGlvbihhLGIsYyxkKXt2
+YXIgcz1hPyQuSEcoKTokLnJmKCkKaWYocz09bnVsbClyZXR1cm4gbnVsbAppZigwPT09YyYmZD09PWIu
+bGVuZ3RoKXJldHVybiBQLlJiKHMsYikKcmV0dXJuIFAuUmIocyxiLnN1YmFycmF5KGMsUC5qQihjLGQs
+Yi5sZW5ndGgpKSl9LApSYjpmdW5jdGlvbihhLGIpe3ZhciBzLHIKdHJ5e3M9YS5kZWNvZGUoYikKcmV0
+dXJuIHN9Y2F0Y2gocil7SC5SdShyKX1yZXR1cm4gbnVsbH0sCnhNOmZ1bmN0aW9uKGEsYixjLGQsZSxm
+KXtpZihDLmpuLnpZKGYsNCkhPT0wKXRocm93IEguYihQLnJyKCJJbnZhbGlkIGJhc2U2NCBwYWRkaW5n
+LCBwYWRkZWQgbGVuZ3RoIG11c3QgYmUgbXVsdGlwbGUgb2YgZm91ciwgaXMgIitmLGEsYykpCmlmKGQr
+ZSE9PWYpdGhyb3cgSC5iKFAucnIoIkludmFsaWQgYmFzZTY0IHBhZGRpbmcsICc9JyBub3QgYXQgdGhl
+IGVuZCIsYSxiKSkKaWYoZT4yKXRocm93IEguYihQLnJyKCJJbnZhbGlkIGJhc2U2NCBwYWRkaW5nLCBt
+b3JlIHRoYW4gdHdvICc9JyBjaGFyYWN0ZXJzIixhLGIpKX0sCkd5OmZ1bmN0aW9uKGEsYixjKXtyZXR1
+cm4gbmV3IFAuVWQoYSxiKX0sCk5DOmZ1bmN0aW9uKGEpe3JldHVybiBhLkx0KCl9LApVZzpmdW5jdGlv
+bihhLGIpe3JldHVybiBuZXcgUC50dShhLFtdLFAuQ3koKSl9LAp1WDpmdW5jdGlvbihhLGIsYyl7dmFy
+IHMscj1uZXcgUC5SbigiIikscT1QLlVnKHIsYikKcS5pVShhKQpzPXIuYQpyZXR1cm4gcy5jaGFyQ29k
+ZUF0KDApPT0wP3M6c30sCmo0OmZ1bmN0aW9uKGEpe3N3aXRjaChhKXtjYXNlIDY1OnJldHVybiJNaXNz
+aW5nIGV4dGVuc2lvbiBieXRlIgpjYXNlIDY3OnJldHVybiJVbmV4cGVjdGVkIGV4dGVuc2lvbiBieXRl
+IgpjYXNlIDY5OnJldHVybiJJbnZhbGlkIFVURi04IGJ5dGUiCmNhc2UgNzE6cmV0dXJuIk92ZXJsb25n
+IGVuY29kaW5nIgpjYXNlIDczOnJldHVybiJPdXQgb2YgdW5pY29kZSByYW5nZSIKY2FzZSA3NTpyZXR1
+cm4iRW5jb2RlZCBzdXJyb2dhdGUiCmNhc2UgNzc6cmV0dXJuIlVuZmluaXNoZWQgVVRGLTggb2N0ZXQg
+c2VxdWVuY2UiCmRlZmF1bHQ6cmV0dXJuIiJ9fSwKank6ZnVuY3Rpb24oYSxiLGMpe3ZhciBzLHIscSxw
+PWMtYixvPW5ldyBVaW50OEFycmF5KHApCmZvcihzPUouVTYoYSkscj0wO3I8cDsrK3Ipe3E9cy5xKGEs
+YityKQppZih0eXBlb2YgcSE9PSJudW1iZXIiKXJldHVybiBxLnpNKCkKaWYoKHEmNDI5NDk2NzA0MCk+
+Pj4wIT09MClxPTI1NQppZihyPj1wKXJldHVybiBILk9IKG8scikKb1tyXT1xfXJldHVybiBvfSwKdXc6
+ZnVuY3Rpb24gdXcoYSxiKXt0aGlzLmE9YQp0aGlzLmI9Ygp0aGlzLmM9bnVsbH0sCmk4OmZ1bmN0aW9u
+IGk4KGEpe3RoaXMuYT1hfSwKcGc6ZnVuY3Rpb24gcGcoKXt9LApjMjpmdW5jdGlvbiBjMigpe30sCkNW
+OmZ1bmN0aW9uIENWKCl7fSwKVTg6ZnVuY3Rpb24gVTgoKXt9LApVazpmdW5jdGlvbiBVaygpe30sCndJ
+OmZ1bmN0aW9uIHdJKCl7fSwKWmk6ZnVuY3Rpb24gWmkoKXt9LApVZDpmdW5jdGlvbiBVZChhLGIpe3Ro
+aXMuYT1hCnRoaXMuYj1ifSwKSzg6ZnVuY3Rpb24gSzgoYSxiKXt0aGlzLmE9YQp0aGlzLmI9Yn0sCmJ5
+OmZ1bmN0aW9uIGJ5KCl7fSwKb2o6ZnVuY3Rpb24gb2ooYSl7dGhpcy5iPWF9LApNeDpmdW5jdGlvbiBN
+eChhKXt0aGlzLmE9YX0sClNoOmZ1bmN0aW9uIFNoKCl7fSwKdGk6ZnVuY3Rpb24gdGkoYSxiKXt0aGlz
+LmE9YQp0aGlzLmI9Yn0sCnR1OmZ1bmN0aW9uIHR1KGEsYixjKXt0aGlzLmM9YQp0aGlzLmE9Ygp0aGlz
+LmI9Y30sCnU1OmZ1bmN0aW9uIHU1KCl7fSwKRTM6ZnVuY3Rpb24gRTMoKXt9LApSdzpmdW5jdGlvbiBS
+dyhhKXt0aGlzLmI9MAp0aGlzLmM9YX0sCkdZOmZ1bmN0aW9uIEdZKGEpe3RoaXMuYT1hfSwKYno6ZnVu
+Y3Rpb24gYnooYSl7dGhpcy5hPWEKdGhpcy5iPTE2CnRoaXMuYz0wfSwKUUE6ZnVuY3Rpb24oYSxiKXt2
+YXIgcz1ILkhwKGEsYikKaWYocyE9bnVsbClyZXR1cm4gcwp0aHJvdyBILmIoUC5ycihhLG51bGwsbnVs
+bCkpfSwKb3M6ZnVuY3Rpb24oYSl7aWYoYSBpbnN0YW5jZW9mIEguVHApcmV0dXJuIGEudygwKQpyZXR1
+cm4iSW5zdGFuY2Ugb2YgJyIrSC5FaihILk0oYSkpKyInIn0sCk84OmZ1bmN0aW9uKGEsYixjLGQpe3Zh
+ciBzLHI9Yz9KLktoKGEsZCk6Si5RaShhLGQpCmlmKGEhPT0wJiZiIT1udWxsKWZvcihzPTA7czxyLmxl
+bmd0aDsrK3MpcltzXT1iCnJldHVybiByfSwKQ0g6ZnVuY3Rpb24oYSxiLGMpe3ZhciBzLHI9SC5WTShb
+XSxjLkMoImpkPDA+IikpCmZvcihzPUouSVQoYSk7cy5GKCk7KUMuTm0uaShyLGMuYShzLmdsKCkpKQpp
+ZihiKXJldHVybiByCnJldHVybiBKLkVwKHIsYyl9LApZMTpmdW5jdGlvbihhLGIsYyl7dmFyIHMKaWYo
+YilyZXR1cm4gUC5ldihhLGMpCnM9Si5FcChQLmV2KGEsYyksYykKcmV0dXJuIHN9LApldjpmdW5jdGlv
+bihhLGIpe3ZhciBzLHI9SC5WTShbXSxiLkMoImpkPDA+IikpCmZvcihzPUouSVQoYSk7cy5GKCk7KUMu
+Tm0uaShyLHMuZ2woKSkKcmV0dXJuIHJ9LApBRjpmdW5jdGlvbihhLGIpe3JldHVybiBKLnpDKFAuQ0go
+YSwhMSxiKSl9LApITTpmdW5jdGlvbihhLGIsYyl7aWYodC5ibS5iKGEpKXJldHVybiBILmZ3KGEsYixQ
+LmpCKGIsYyxhLmxlbmd0aCkpCnJldHVybiBQLmJ3KGEsYixjKX0sCk9vOmZ1bmN0aW9uKGEpe3JldHVy
+biBILkx3KGEpfSwKYnc6ZnVuY3Rpb24oYSxiLGMpe3ZhciBzLHIscSxwLG89bnVsbAppZihiPDApdGhy
+b3cgSC5iKFAuVEUoYiwwLGEubGVuZ3RoLG8sbykpCnM9Yz09bnVsbAppZighcyYmYzxiKXRocm93IEgu
+YihQLlRFKGMsYixhLmxlbmd0aCxvLG8pKQpyPW5ldyBILmE3KGEsYS5sZW5ndGgsSC56KGEpLkMoImE3
+PGxELkU+IikpCmZvcihxPTA7cTxiOysrcSlpZighci5GKCkpdGhyb3cgSC5iKFAuVEUoYiwwLHEsbyxv
+KSkKcD1bXQppZihzKWZvcig7ci5GKCk7KXAucHVzaChyLmQpCmVsc2UgZm9yKHE9YjtxPGM7KytxKXtp
+Zighci5GKCkpdGhyb3cgSC5iKFAuVEUoYyxiLHEsbyxvKSkKcC5wdXNoKHIuZCl9cmV0dXJuIEguZVQo
+cCl9LApudTpmdW5jdGlvbihhKXtyZXR1cm4gbmV3IEguVlIoYSxILnY0KGEsITEsITAsITEsITEsITEp
+KX0sCnZnOmZ1bmN0aW9uKGEsYixjKXt2YXIgcz1KLklUKGIpCmlmKCFzLkYoKSlyZXR1cm4gYQppZihj
+Lmxlbmd0aD09PTApe2RvIGErPUguRWoocy5nbCgpKQp3aGlsZShzLkYoKSl9ZWxzZXthKz1ILkVqKHMu
+Z2woKSkKZm9yKDtzLkYoKTspYT1hK2MrSC5FaihzLmdsKCkpfXJldHVybiBhfSwKbHI6ZnVuY3Rpb24o
+YSxiLGMsZCl7cmV0dXJuIG5ldyBQLm1wKGEsYixjLGQpfSwKdW86ZnVuY3Rpb24oKXt2YXIgcz1ILk0w
+KCkKaWYocyE9bnVsbClyZXR1cm4gUC5oSyhzKQp0aHJvdyBILmIoUC5MNCgiJ1VyaS5iYXNlJyBpcyBu
+b3Qgc3VwcG9ydGVkIikpfSwKZVA6ZnVuY3Rpb24oYSxiLGMsZCl7dmFyIHMscixxLHAsbyxuLG09IjAx
+MjM0NTY3ODlBQkNERUYiCmlmKGM9PT1DLnhNKXtzPSQuejQoKS5iCmlmKHR5cGVvZiBiIT0ic3RyaW5n
+IilILnYoSC50TChiKSkKcz1zLnRlc3QoYil9ZWxzZSBzPSExCmlmKHMpcmV0dXJuIGIKSC5MaChjKS5D
+KCJVay5TIikuYShiKQpyPWMuZ1pFKCkuV0ooYikKZm9yKHM9ci5sZW5ndGgscT0wLHA9IiI7cTxzOysr
+cSl7bz1yW3FdCmlmKG88MTI4KXtuPW8+Pj40CmlmKG4+PTgpcmV0dXJuIEguT0goYSxuKQpuPShhW25d
+JjE8PChvJjE1KSkhPT0wfWVsc2Ugbj0hMQppZihuKXArPUguTHcobykKZWxzZSBwPWQmJm89PT0zMj9w
+KyIrIjpwKyIlIittW28+Pj40JjE1XSttW28mMTVdfXJldHVybiBwLmNoYXJDb2RlQXQoMCk9PTA/cDpw
+fSwKR3E6ZnVuY3Rpb24oYSl7dmFyIHM9TWF0aC5hYnMoYSkscj1hPDA/Ii0iOiIiCmlmKHM+PTEwMDAp
+cmV0dXJuIiIrYQppZihzPj0xMDApcmV0dXJuIHIrIjAiK3MKaWYocz49MTApcmV0dXJuIHIrIjAwIitz
+CnJldHVybiByKyIwMDAiK3N9LApWeDpmdW5jdGlvbihhKXtpZihhPj0xMDApcmV0dXJuIiIrYQppZihh
+Pj0xMClyZXR1cm4iMCIrYQpyZXR1cm4iMDAiK2F9LApoMDpmdW5jdGlvbihhKXtpZihhPj0xMClyZXR1
+cm4iIithCnJldHVybiIwIithfSwKcDpmdW5jdGlvbihhKXtpZih0eXBlb2YgYT09Im51bWJlciJ8fEgu
+bChhKXx8bnVsbD09YSlyZXR1cm4gSi5qKGEpCmlmKHR5cGVvZiBhPT0ic3RyaW5nIilyZXR1cm4gSlNP
+Ti5zdHJpbmdpZnkoYSkKcmV0dXJuIFAub3MoYSl9LApoVjpmdW5jdGlvbihhKXtyZXR1cm4gbmV3IFAu
+QzYoYSl9LAp4WTpmdW5jdGlvbihhKXtyZXR1cm4gbmV3IFAudSghMSxudWxsLG51bGwsYSl9LApMMzpm
+dW5jdGlvbihhLGIsYyl7cmV0dXJuIG5ldyBQLnUoITAsYSxiLGMpfSwKTVI6ZnVuY3Rpb24oYSxiLGMp
+e3JldHVybiBhfSwKTzc6ZnVuY3Rpb24oYSxiKXtyZXR1cm4gbmV3IFAuYkoobnVsbCxudWxsLCEwLGEs
+YiwiVmFsdWUgbm90IGluIHJhbmdlIil9LApURTpmdW5jdGlvbihhLGIsYyxkLGUpe3JldHVybiBuZXcg
+UC5iSihiLGMsITAsYSxkLCJJbnZhbGlkIHZhbHVlIil9LAp3QTpmdW5jdGlvbihhLGIsYyxkKXtpZihh
+PGJ8fGE+Yyl0aHJvdyBILmIoUC5URShhLGIsYyxkLG51bGwpKQpyZXR1cm4gYX0sCmpCOmZ1bmN0aW9u
+KGEsYixjKXtpZigwPmF8fGE+Yyl0aHJvdyBILmIoUC5URShhLDAsYywic3RhcnQiLG51bGwpKQppZihi
+IT1udWxsKXtpZihhPmJ8fGI+Yyl0aHJvdyBILmIoUC5URShiLGEsYywiZW5kIixudWxsKSkKcmV0dXJu
+IGJ9cmV0dXJuIGN9LAprMTpmdW5jdGlvbihhLGIpe2lmKGE8MCl0aHJvdyBILmIoUC5URShhLDAsbnVs
+bCxiLG51bGwpKQpyZXR1cm4gYX0sCkNmOmZ1bmN0aW9uKGEsYixjLGQsZSl7dmFyIHM9SC51UChlPT1u
+dWxsP0ouSG0oYik6ZSkKcmV0dXJuIG5ldyBQLmVZKHMsITAsYSxjLCJJbmRleCBvdXQgb2YgcmFuZ2Ui
+KX0sCkw0OmZ1bmN0aW9uKGEpe3JldHVybiBuZXcgUC51YihhKX0sClNZOmZ1bmN0aW9uKGEpe3JldHVy
+biBuZXcgUC5kcyhhKX0sClBWOmZ1bmN0aW9uKGEpe3JldHVybiBuZXcgUC5saihhKX0sCmE0OmZ1bmN0
+aW9uKGEpe3JldHVybiBuZXcgUC5VVihhKX0sCnJyOmZ1bmN0aW9uKGEsYixjKXtyZXR1cm4gbmV3IFAu
+YUUoYSxiLGMpfSwKaEs6ZnVuY3Rpb24oYTUpe3ZhciBzLHIscSxwLG8sbixtLGwsayxqLGksaCxnLGYs
+ZSxkLGMsYixhLGEwLGExLGEyLGEzPW51bGwsYTQ9YTUubGVuZ3RoCmlmKGE0Pj01KXtzPSgoSi5Reihh
+NSw0KV41OCkqM3xDLnhCLlcoYTUsMCleMTAwfEMueEIuVyhhNSwxKV45N3xDLnhCLlcoYTUsMileMTE2
+fEMueEIuVyhhNSwzKV45Nyk+Pj4wCmlmKHM9PT0wKXJldHVybiBQLktEKGE0PGE0P0MueEIuTmooYTUs
+MCxhNCk6YTUsNSxhMykuZ2xSKCkKZWxzZSBpZihzPT09MzIpcmV0dXJuIFAuS0QoQy54Qi5OaihhNSw1
+LGE0KSwwLGEzKS5nbFIoKX1yPVAuTzgoOCwwLCExLHQuUykKQy5ObS5ZNShyLDAsMCkKQy5ObS5ZNShy
+LDEsLTEpCkMuTm0uWTUociwyLC0xKQpDLk5tLlk1KHIsNywtMSkKQy5ObS5ZNShyLDMsMCkKQy5ObS5Z
+NShyLDQsMCkKQy5ObS5ZNShyLDUsYTQpCkMuTm0uWTUociw2LGE0KQppZihQLlVCKGE1LDAsYTQsMCxy
+KT49MTQpQy5ObS5ZNShyLDcsYTQpCnE9clsxXQppZihxPj0wKWlmKFAuVUIoYTUsMCxxLDIwLHIpPT09
+MjApcls3XT1xCnA9clsyXSsxCm89clszXQpuPXJbNF0KbT1yWzVdCmw9cls2XQppZihsPG0pbT1sCmlm
+KG48cCluPW0KZWxzZSBpZihuPD1xKW49cSsxCmlmKG88cClvPW4Kaz1yWzddPDAKaWYoaylpZihwPnEr
+Myl7aj1hMwprPSExfWVsc2V7aT1vPjAKaWYoaSYmbysxPT09bil7aj1hMwprPSExfWVsc2V7aWYoISht
+PGE0JiZtPT09bisyJiZKLnEwKGE1LCIuLiIsbikpKWg9bT5uKzImJkoucTAoYTUsIi8uLiIsbS0zKQpl
+bHNlIGg9ITAKaWYoaCl7aj1hMwprPSExfWVsc2V7aWYocT09PTQpaWYoSi5xMChhNSwiZmlsZSIsMCkp
+e2lmKHA8PTApe2lmKCFDLnhCLlFpKGE1LCIvIixuKSl7Zz0iZmlsZTovLy8iCnM9M31lbHNle2c9ImZp
+bGU6Ly8iCnM9Mn1hNT1nK0MueEIuTmooYTUsbixhNCkKcS09MAppPXMtMAptKz1pCmwrPWkKYTQ9YTUu
+bGVuZ3RoCnA9NwpvPTcKbj03fWVsc2UgaWYobj09PW0peysrbApmPW0rMQphNT1DLnhCLmk3KGE1LG4s
+bSwiLyIpOysrYTQKbT1mfWo9ImZpbGUifWVsc2UgaWYoQy54Qi5RaShhNSwiaHR0cCIsMCkpe2lmKGkm
+Jm8rMz09PW4mJkMueEIuUWkoYTUsIjgwIixvKzEpKXtsLT0zCmU9bi0zCm0tPTMKYTU9Qy54Qi5pNyhh
+NSxvLG4sIiIpCmE0LT0zCm49ZX1qPSJodHRwIn1lbHNlIGo9YTMKZWxzZSBpZihxPT09NSYmSi5xMChh
+NSwiaHR0cHMiLDApKXtpZihpJiZvKzQ9PT1uJiZKLnEwKGE1LCI0NDMiLG8rMSkpe2wtPTQKZT1uLTQK
+bS09NAphNT1KLmRnKGE1LG8sbiwiIikKYTQtPTMKbj1lfWo9Imh0dHBzIn1lbHNlIGo9YTMKaz0hMH19
+fWVsc2Ugaj1hMwppZihrKXtpPWE1Lmxlbmd0aAppZihhNDxpKXthNT1KLmxkKGE1LDAsYTQpCnEtPTAK
+cC09MApvLT0wCm4tPTAKbS09MApsLT0wfXJldHVybiBuZXcgUC5VZihhNSxxLHAsbyxuLG0sbCxqKX1p
+ZihqPT1udWxsKWlmKHE+MClqPVAuUGkoYTUsMCxxKQplbHNle2lmKHE9PT0wKXtQLlIzKGE1LDAsIklu
+dmFsaWQgZW1wdHkgc2NoZW1lIikKSC5CaSh1LmcpfWo9IiJ9aWYocD4wKXtkPXErMwpjPWQ8cD9QLnpS
+KGE1LGQscC0xKToiIgpiPVAuT2UoYTUscCxvLCExKQppPW8rMQppZihpPG4pe2E9SC5IcChKLmxkKGE1
+LGksbiksYTMpCmEwPVAud0IoYT09bnVsbD9ILnYoUC5ycigiSW52YWxpZCBwb3J0IixhNSxpKSk6YSxq
+KX1lbHNlIGEwPWEzfWVsc2V7YTA9YTMKYj1hMApjPSIifWExPVAua2EoYTUsbixtLGEzLGosYiE9bnVs
+bCkKYTI9bTxsP1AubGUoYTUsbSsxLGwsYTMpOmEzCnJldHVybiBuZXcgUC5EbihqLGMsYixhMCxhMSxh
+MixsPGE0P1AudEcoYTUsbCsxLGE0KTphMyl9LApNdDpmdW5jdGlvbihhKXtILmgoYSkKcmV0dXJuIFAu
+a3UoYSwwLGEubGVuZ3RoLEMueE0sITEpfSwKV1g6ZnVuY3Rpb24oYSl7dmFyIHM9dC5OCnJldHVybiBD
+Lk5tLk4wKEguVk0oYS5zcGxpdCgiJiIpLHQucyksUC5GbChzLHMpLG5ldyBQLm4xKEMueE0pLHQuSil9
+LApIaDpmdW5jdGlvbihhLGIsYyl7dmFyIHMscixxLHAsbyxuLG09IklQdjQgYWRkcmVzcyBzaG91bGQg
+Y29udGFpbiBleGFjdGx5IDQgcGFydHMiLGw9ImVhY2ggcGFydCBtdXN0IGJlIGluIHRoZSByYW5nZSAw
+Li4yNTUiLGs9bmV3IFAuY1MoYSksaj1uZXcgVWludDhBcnJheSg0KQpmb3Iocz1iLHI9cyxxPTA7czxj
+Oysrcyl7cD1DLnhCLk8yKGEscykKaWYocCE9PTQ2KXtpZigocF40OCk+OSlrLiQyKCJpbnZhbGlkIGNo
+YXJhY3RlciIscyl9ZWxzZXtpZihxPT09MylrLiQyKG0scykKbz1QLlFBKEMueEIuTmooYSxyLHMpLG51
+bGwpCmlmKG8+MjU1KWsuJDIobCxyKQpuPXErMQppZihxPj00KXJldHVybiBILk9IKGoscSkKaltxXT1v
+CnI9cysxCnE9bn19aWYocSE9PTMpay4kMihtLGMpCm89UC5RQShDLnhCLk5qKGEscixjKSxudWxsKQpp
+ZihvPjI1NSlrLiQyKGwscikKaWYocT49NClyZXR1cm4gSC5PSChqLHEpCmpbcV09bwpyZXR1cm4gan0s
+CmVnOmZ1bmN0aW9uKGEsYixhMCl7dmFyIHMscixxLHAsbyxuLG0sbCxrLGosaSxoLGcsZixlLGQ9bmV3
+IFAuVkMoYSksYz1uZXcgUC5KVChkLGEpCmlmKGEubGVuZ3RoPDIpZC4kMSgiYWRkcmVzcyBpcyB0b28g
+c2hvcnQiKQpzPUguVk0oW10sdC5hKQpmb3Iocj1iLHE9cixwPSExLG89ITE7cjxhMDsrK3Ipe249Qy54
+Qi5PMihhLHIpCmlmKG49PT01OCl7aWYocj09PWIpeysrcgppZihDLnhCLk8yKGEscikhPT01OClkLiQy
+KCJpbnZhbGlkIHN0YXJ0IGNvbG9uLiIscikKcT1yfWlmKHI9PT1xKXtpZihwKWQuJDIoIm9ubHkgb25l
+IHdpbGRjYXJkIGA6OmAgaXMgYWxsb3dlZCIscikKQy5ObS5pKHMsLTEpCnA9ITB9ZWxzZSBDLk5tLmko
+cyxjLiQyKHEscikpCnE9cisxfWVsc2UgaWYobj09PTQ2KW89ITB9aWYocy5sZW5ndGg9PT0wKWQuJDEo
+InRvbyBmZXcgcGFydHMiKQptPXE9PT1hMApsPUMuTm0uZ3JaKHMpCmlmKG0mJmwhPT0tMSlkLiQyKCJl
+eHBlY3RlZCBhIHBhcnQgYWZ0ZXIgbGFzdCBgOmAiLGEwKQppZighbSlpZighbylDLk5tLmkocyxjLiQy
+KHEsYTApKQplbHNle2s9UC5IaChhLHEsYTApCkMuTm0uaShzLChrWzBdPDw4fGtbMV0pPj4+MCkKQy5O
+bS5pKHMsKGtbMl08PDh8a1szXSk+Pj4wKX1pZihwKXtpZihzLmxlbmd0aD43KWQuJDEoImFuIGFkZHJl
+c3Mgd2l0aCBhIHdpbGRjYXJkIG11c3QgaGF2ZSBsZXNzIHRoYW4gNyBwYXJ0cyIpfWVsc2UgaWYocy5s
+ZW5ndGghPT04KWQuJDEoImFuIGFkZHJlc3Mgd2l0aG91dCBhIHdpbGRjYXJkIG11c3QgY29udGFpbiBl
+eGFjdGx5IDggcGFydHMiKQpqPW5ldyBVaW50OEFycmF5KDE2KQpmb3IobD1zLmxlbmd0aCxpPTktbCxy
+PTAsaD0wO3I8bDsrK3Ipe2c9c1tyXQppZihnPT09LTEpZm9yKGY9MDtmPGk7KytmKXtpZihoPDB8fGg+
+PTE2KXJldHVybiBILk9IKGosaCkKaltoXT0wCmU9aCsxCmlmKGU+PTE2KXJldHVybiBILk9IKGosZSkK
+altlXT0wCmgrPTJ9ZWxzZXtlPUMuam4ud0coZyw4KQppZihoPDB8fGg+PTE2KXJldHVybiBILk9IKGos
+aCkKaltoXT1lCmU9aCsxCmlmKGU+PTE2KXJldHVybiBILk9IKGosZSkKaltlXT1nJjI1NQpoKz0yfX1y
+ZXR1cm4gan0sCktMOmZ1bmN0aW9uKGEsYixjLGQsZSxmLGcpe3ZhciBzLHIscSxwLG8sbgpmPWY9PW51
+bGw/IiI6UC5QaShmLDAsZi5sZW5ndGgpCmc9UC56UihnLDAsZz09bnVsbD8wOmcubGVuZ3RoKQphPVAu
+T2UoYSwwLGE9PW51bGw/MDphLmxlbmd0aCwhMSkKcz1QLmxlKG51bGwsMCwwLGUpCnI9UC50RyhudWxs
+LDAsMCkKZD1QLndCKGQsZikKcT1mPT09ImZpbGUiCmlmKGE9PW51bGwpcD1nLmxlbmd0aCE9PTB8fGQh
+PW51bGx8fHEKZWxzZSBwPSExCmlmKHApYT0iIgpwPWE9PW51bGwKbz0hcApiPVAua2EoYiwwLGI9PW51
+bGw/MDpiLmxlbmd0aCxjLGYsbykKbj1mLmxlbmd0aD09PTAKaWYobiYmcCYmIUMueEIubkMoYiwiLyIp
+KWI9UC53RihiLCFufHxvKQplbHNlIGI9UC54ZShiKQpyZXR1cm4gbmV3IFAuRG4oZixnLHAmJkMueEIu
+bkMoYiwiLy8iKT8iIjphLGQsYixzLHIpfSwKd0s6ZnVuY3Rpb24oYSl7aWYoYT09PSJodHRwIilyZXR1
+cm4gODAKaWYoYT09PSJodHRwcyIpcmV0dXJuIDQ0MwpyZXR1cm4gMH0sClIzOmZ1bmN0aW9uKGEsYixj
+KXt0aHJvdyBILmIoUC5ycihjLGEsYikpfSwKWGQ6ZnVuY3Rpb24oYSxiLGMsZCl7dmFyIHMscixxLHAs
+byxuLG0sbCxrLGosaSxoPW51bGwsZz1iLmxlbmd0aAppZihnIT09MCl7cT0wCndoaWxlKCEwKXtpZigh
+KHE8Zykpe3M9IiIKcj0wCmJyZWFrfWlmKEMueEIuVyhiLHEpPT09NjQpe3M9Qy54Qi5OaihiLDAscSkK
+cj1xKzEKYnJlYWt9KytxfWlmKHI8ZyYmQy54Qi5XKGIscik9PT05MSl7Zm9yKHA9cixvPS0xO3A8Zzsr
+K3Ape249Qy54Qi5XKGIscCkKaWYobj09PTM3JiZvPDApe209Qy54Qi5RaShiLCIyNSIscCsxKT9wKzI6
+cApvPXAKcD1tfWVsc2UgaWYobj09PTkzKWJyZWFrfWlmKHA9PT1nKXRocm93IEguYihQLnJyKCJJbnZh
+bGlkIElQdjYgaG9zdCBlbnRyeS4iLGIscikpCmw9bzwwP3A6bwpQLmVnKGIscisxLGwpOysrcAppZihw
+IT09ZyYmQy54Qi5XKGIscCkhPT01OCl0aHJvdyBILmIoUC5ycigiSW52YWxpZCBlbmQgb2YgYXV0aG9y
+aXR5IixiLHApKX1lbHNlIHA9cgp3aGlsZSghMCl7aWYoIShwPGcpKXtrPWgKYnJlYWt9aWYoQy54Qi5X
+KGIscCk9PT01OCl7aj1DLnhCLnluKGIscCsxKQprPWoubGVuZ3RoIT09MD9QLlFBKGosaCk6aApicmVh
+a30rK3B9aT1DLnhCLk5qKGIscixwKX1lbHNle2s9aAppPWsKcz0iIn1yZXR1cm4gUC5LTChpLGgsSC5W
+TShjLnNwbGl0KCIvIiksdC5zKSxrLGQsYSxzKX0sCmtFOmZ1bmN0aW9uKGEsYil7dmFyIHMscixxLHAs
+bwpmb3Iocz1hLmxlbmd0aCxyPTA7cjxzOysrcil7cT1hW3JdCnEudG9TdHJpbmcKcD1KLlU2KHEpCm89
+cC5nQShxKQppZigwPm8pSC52KFAuVEUoMCwwLHAuZ0EocSksbnVsbCxudWxsKSkKaWYoSC5TUShxLCIv
+IiwwKSl7cz1QLkw0KCJJbGxlZ2FsIHBhdGggY2hhcmFjdGVyICIrSC5FaihxKSkKdGhyb3cgSC5iKHMp
+fX19LApITjpmdW5jdGlvbihhLGIsYyl7dmFyIHMscixxCmZvcihzPUgucUMoYSxjLG51bGwsSC50Nihh
+KS5jKSxzPW5ldyBILmE3KHMscy5nQShzKSxzLiR0aS5DKCJhNzxhTC5FPiIpKTtzLkYoKTspe3I9cy5k
+CnE9UC5udSgnWyIqLzo8Pj9cXFxcfF0nKQpyLnRvU3RyaW5nCmlmKEguU1EocixxLDApKXtzPVAuTDQo
+IklsbGVnYWwgY2hhcmFjdGVyIGluIHBhdGg6ICIrcikKdGhyb3cgSC5iKHMpfX19LApyZzpmdW5jdGlv
+bihhLGIpe3ZhciBzCmlmKCEoNjU8PWEmJmE8PTkwKSlzPTk3PD1hJiZhPD0xMjIKZWxzZSBzPSEwCmlm
+KHMpcmV0dXJuCnM9UC5MNCgiSWxsZWdhbCBkcml2ZSBsZXR0ZXIgIitQLk9vKGEpKQp0aHJvdyBILmIo
+cyl9LAp3QjpmdW5jdGlvbihhLGIpe2lmKGEhPW51bGwmJmE9PT1QLndLKGIpKXJldHVybiBudWxsCnJl
+dHVybiBhfSwKT2U6ZnVuY3Rpb24oYSxiLGMsZCl7dmFyIHMscixxLHAsbyxuCmlmKGE9PW51bGwpcmV0
+dXJuIG51bGwKaWYoYj09PWMpcmV0dXJuIiIKaWYoQy54Qi5PMihhLGIpPT09OTEpe3M9Yy0xCmlmKEMu
+eEIuTzIoYSxzKSE9PTkzKXtQLlIzKGEsYiwiTWlzc2luZyBlbmQgYF1gIHRvIG1hdGNoIGBbYCBpbiBo
+b3N0IikKSC5CaSh1LmcpfXI9YisxCnE9UC50byhhLHIscykKaWYocTxzKXtwPXErMQpvPVAuT0EoYSxD
+LnhCLlFpKGEsIjI1IixwKT9xKzM6cCxzLCIlMjUiKX1lbHNlIG89IiIKUC5lZyhhLHIscSkKcmV0dXJu
+IEMueEIuTmooYSxiLHEpLnRvTG93ZXJDYXNlKCkrbysiXSJ9Zm9yKG49YjtuPGM7KytuKWlmKEMueEIu
+TzIoYSxuKT09PTU4KXtxPUMueEIuWFUoYSwiJSIsYikKcT1xPj1iJiZxPGM/cTpjCmlmKHE8Yyl7cD1x
+KzEKbz1QLk9BKGEsQy54Qi5RaShhLCIyNSIscCk/cSszOnAsYywiJTI1Iil9ZWxzZSBvPSIiClAuZWco
+YSxiLHEpCnJldHVybiJbIitDLnhCLk5qKGEsYixxKStvKyJdIn1yZXR1cm4gUC5PTChhLGIsYyl9LAp0
+bzpmdW5jdGlvbihhLGIsYyl7dmFyIHM9Qy54Qi5YVShhLCIlIixiKQpyZXR1cm4gcz49YiYmczxjP3M6
+Y30sCk9BOmZ1bmN0aW9uKGEsYixjLGQpe3ZhciBzLHIscSxwLG8sbixtLGwsayxqLGk9ZCE9PSIiP25l
+dyBQLlJuKGQpOm51bGwKZm9yKHM9YixyPXMscT0hMDtzPGM7KXtwPUMueEIuTzIoYSxzKQppZihwPT09
+Mzcpe289UC5ydihhLHMsITApCm49bz09bnVsbAppZihuJiZxKXtzKz0zCmNvbnRpbnVlfWlmKGk9PW51
+bGwpaT1uZXcgUC5SbigiIikKbT1pLmErPUMueEIuTmooYSxyLHMpCmlmKG4pbz1DLnhCLk5qKGEscyxz
+KzMpCmVsc2UgaWYobz09PSIlIil7UC5SMyhhLHMsIlpvbmVJRCBzaG91bGQgbm90IGNvbnRhaW4gJSBh
+bnltb3JlIikKSC5CaSh1LmcpfWkuYT1tK28Kcys9MwpyPXMKcT0hMH1lbHNle2lmKHA8MTI3KXtuPXA+
+Pj40CmlmKG4+PTgpcmV0dXJuIEguT0goQy5GMyxuKQpuPShDLkYzW25dJjE8PChwJjE1KSkhPT0wfWVs
+c2Ugbj0hMQppZihuKXtpZihxJiY2NTw9cCYmOTA+PXApe2lmKGk9PW51bGwpaT1uZXcgUC5SbigiIikK
+aWYocjxzKXtpLmErPUMueEIuTmooYSxyLHMpCnI9c31xPSExfSsrc31lbHNle2lmKChwJjY0NTEyKT09
+PTU1Mjk2JiZzKzE8Yyl7bD1DLnhCLk8yKGEscysxKQppZigobCY2NDUxMik9PT01NjMyMCl7cD0ocCYx
+MDIzKTw8MTB8bCYxMDIzfDY1NTM2Cms9Mn1lbHNlIGs9MX1lbHNlIGs9MQpqPUMueEIuTmooYSxyLHMp
+CmlmKGk9PW51bGwpe2k9bmV3IFAuUm4oIiIpCm49aX1lbHNlIG49aQpuLmErPWoKbi5hKz1QLnpYKHAp
+CnMrPWsKcj1zfX19aWYoaT09bnVsbClyZXR1cm4gQy54Qi5OaihhLGIsYykKaWYocjxjKWkuYSs9Qy54
+Qi5OaihhLHIsYykKbj1pLmEKcmV0dXJuIG4uY2hhckNvZGVBdCgwKT09MD9uOm59LApPTDpmdW5jdGlv
+bihhLGIsYyl7dmFyIHMscixxLHAsbyxuLG0sbCxrLGosaQpmb3Iocz1iLHI9cyxxPW51bGwscD0hMDtz
+PGM7KXtvPUMueEIuTzIoYSxzKQppZihvPT09Mzcpe249UC5ydihhLHMsITApCm09bj09bnVsbAppZiht
+JiZwKXtzKz0zCmNvbnRpbnVlfWlmKHE9PW51bGwpcT1uZXcgUC5SbigiIikKbD1DLnhCLk5qKGEscixz
+KQprPXEuYSs9IXA/bC50b0xvd2VyQ2FzZSgpOmwKaWYobSl7bj1DLnhCLk5qKGEscyxzKzMpCmo9M31l
+bHNlIGlmKG49PT0iJSIpe249IiUyNSIKaj0xfWVsc2Ugaj0zCnEuYT1rK24Kcys9agpyPXMKcD0hMH1l
+bHNle2lmKG88MTI3KXttPW8+Pj40CmlmKG0+PTgpcmV0dXJuIEguT0goQy5lYSxtKQptPShDLmVhW21d
+JjE8PChvJjE1KSkhPT0wfWVsc2UgbT0hMQppZihtKXtpZihwJiY2NTw9byYmOTA+PW8pe2lmKHE9PW51
+bGwpcT1uZXcgUC5SbigiIikKaWYocjxzKXtxLmErPUMueEIuTmooYSxyLHMpCnI9c31wPSExfSsrc31l
+bHNle2lmKG88PTkzKXttPW8+Pj40CmlmKG0+PTgpcmV0dXJuIEguT0goQy5hayxtKQptPShDLmFrW21d
+JjE8PChvJjE1KSkhPT0wfWVsc2UgbT0hMQppZihtKXtQLlIzKGEscywiSW52YWxpZCBjaGFyYWN0ZXIi
+KQpILkJpKHUuZyl9ZWxzZXtpZigobyY2NDUxMik9PT01NTI5NiYmcysxPGMpe2k9Qy54Qi5PMihhLHMr
+MSkKaWYoKGkmNjQ1MTIpPT09NTYzMjApe289KG8mMTAyMyk8PDEwfGkmMTAyM3w2NTUzNgpqPTJ9ZWxz
+ZSBqPTF9ZWxzZSBqPTEKbD1DLnhCLk5qKGEscixzKQppZighcClsPWwudG9Mb3dlckNhc2UoKQppZihx
+PT1udWxsKXtxPW5ldyBQLlJuKCIiKQptPXF9ZWxzZSBtPXEKbS5hKz1sCm0uYSs9UC56WChvKQpzKz1q
+CnI9c319fX1pZihxPT1udWxsKXJldHVybiBDLnhCLk5qKGEsYixjKQppZihyPGMpe2w9Qy54Qi5Oaihh
+LHIsYykKcS5hKz0hcD9sLnRvTG93ZXJDYXNlKCk6bH1tPXEuYQpyZXR1cm4gbS5jaGFyQ29kZUF0KDAp
+PT0wP206bX0sClBpOmZ1bmN0aW9uKGEsYixjKXt2YXIgcyxyLHEscCxvPXUuZwppZihiPT09YylyZXR1
+cm4iIgppZighUC5FdChKLnJZKGEpLlcoYSxiKSkpe1AuUjMoYSxiLCJTY2hlbWUgbm90IHN0YXJ0aW5n
+IHdpdGggYWxwaGFiZXRpYyBjaGFyYWN0ZXIiKQpILkJpKG8pfWZvcihzPWIscj0hMTtzPGM7KytzKXtx
+PUMueEIuVyhhLHMpCmlmKHE8MTI4KXtwPXE+Pj40CmlmKHA+PTgpcmV0dXJuIEguT0goQy5tSyxwKQpw
+PShDLm1LW3BdJjE8PChxJjE1KSkhPT0wfWVsc2UgcD0hMQppZighcCl7UC5SMyhhLHMsIklsbGVnYWwg
+c2NoZW1lIGNoYXJhY3RlciIpCkguQmkobyl9aWYoNjU8PXEmJnE8PTkwKXI9ITB9YT1DLnhCLk5qKGEs
+YixjKQpyZXR1cm4gUC5ZYShyP2EudG9Mb3dlckNhc2UoKTphKX0sCllhOmZ1bmN0aW9uKGEpe2lmKGE9
+PT0iaHR0cCIpcmV0dXJuImh0dHAiCmlmKGE9PT0iZmlsZSIpcmV0dXJuImZpbGUiCmlmKGE9PT0iaHR0
+cHMiKXJldHVybiJodHRwcyIKaWYoYT09PSJwYWNrYWdlIilyZXR1cm4icGFja2FnZSIKcmV0dXJuIGF9
+LAp6UjpmdW5jdGlvbihhLGIsYyl7aWYoYT09bnVsbClyZXR1cm4iIgpyZXR1cm4gUC5QSShhLGIsYyxD
+LnRvLCExKX0sCmthOmZ1bmN0aW9uKGEsYixjLGQsZSxmKXt2YXIgcyxyLHE9ZT09PSJmaWxlIixwPXF8
+fGYKaWYoYT09bnVsbCl7aWYoZD09bnVsbClyZXR1cm4gcT8iLyI6IiIKcz1ILnQ2KGQpCnI9bmV3IEgu
+bEooZCxzLkMoInFVKDEpIikuYShuZXcgUC5SWigpKSxzLkMoImxKPDEscVU+IikpLmsoMCwiLyIpfWVs
+c2UgaWYoZCE9bnVsbCl0aHJvdyBILmIoUC54WSgiQm90aCBwYXRoIGFuZCBwYXRoU2VnbWVudHMgc3Bl
+Y2lmaWVkIikpCmVsc2Ugcj1QLlBJKGEsYixjLEMuV2QsITApCmlmKHIubGVuZ3RoPT09MCl7aWYocSly
+ZXR1cm4iLyJ9ZWxzZSBpZihwJiYhQy54Qi5uQyhyLCIvIikpcj0iLyIrcgpyZXR1cm4gUC5KcihyLGUs
+Zil9LApKcjpmdW5jdGlvbihhLGIsYyl7dmFyIHM9Yi5sZW5ndGg9PT0wCmlmKHMmJiFjJiYhQy54Qi5u
+QyhhLCIvIikpcmV0dXJuIFAud0YoYSwhc3x8YykKcmV0dXJuIFAueGUoYSl9LApsZTpmdW5jdGlvbihh
+LGIsYyxkKXt2YXIgcyxyPXt9CmlmKGEhPW51bGwpe2lmKGQhPW51bGwpdGhyb3cgSC5iKFAueFkoIkJv
+dGggcXVlcnkgYW5kIHF1ZXJ5UGFyYW1ldGVycyBzcGVjaWZpZWQiKSkKcmV0dXJuIFAuUEkoYSxiLGMs
+Qy5WQywhMCl9aWYoZD09bnVsbClyZXR1cm4gbnVsbApzPW5ldyBQLlJuKCIiKQpyLmE9IiIKZC5LKDAs
+bmV3IFAueTUobmV3IFAuTUUocixzKSkpCnI9cy5hCnJldHVybiByLmNoYXJDb2RlQXQoMCk9PTA/cjpy
+fSwKdEc6ZnVuY3Rpb24oYSxiLGMpe2lmKGE9PW51bGwpcmV0dXJuIG51bGwKcmV0dXJuIFAuUEkoYSxi
+LGMsQy5WQywhMCl9LApydjpmdW5jdGlvbihhLGIsYyl7dmFyIHMscixxLHAsbyxuPWIrMgppZihuPj1h
+Lmxlbmd0aClyZXR1cm4iJSIKcz1DLnhCLk8yKGEsYisxKQpyPUMueEIuTzIoYSxuKQpxPUgub28ocykK
+cD1ILm9vKHIpCmlmKHE8MHx8cDwwKXJldHVybiIlIgpvPXEqMTYrcAppZihvPDEyNyl7bj1DLmpuLndH
+KG8sNCkKaWYobj49OClyZXR1cm4gSC5PSChDLkYzLG4pCm49KEMuRjNbbl0mMTw8KG8mMTUpKSE9PTB9
+ZWxzZSBuPSExCmlmKG4pcmV0dXJuIEguTHcoYyYmNjU8PW8mJjkwPj1vPyhvfDMyKT4+PjA6bykKaWYo
+cz49OTd8fHI+PTk3KXJldHVybiBDLnhCLk5qKGEsYixiKzMpLnRvVXBwZXJDYXNlKCkKcmV0dXJuIG51
+bGx9LAp6WDpmdW5jdGlvbihhKXt2YXIgcyxyLHEscCxvLG4sbSxsLGs9IjAxMjM0NTY3ODlBQkNERUYi
+CmlmKGE8MTI4KXtzPW5ldyBVaW50OEFycmF5KDMpCnNbMF09MzcKc1sxXT1DLnhCLlcoayxhPj4+NCkK
+c1syXT1DLnhCLlcoayxhJjE1KX1lbHNle2lmKGE+MjA0NylpZihhPjY1NTM1KXtyPTI0MApxPTR9ZWxz
+ZXtyPTIyNApxPTN9ZWxzZXtyPTE5MgpxPTJ9cD0zKnEKcz1uZXcgVWludDhBcnJheShwKQpmb3Iobz0w
+Oy0tcSxxPj0wO3I9MTI4KXtuPUMuam4uYmYoYSw2KnEpJjYzfHIKaWYobz49cClyZXR1cm4gSC5PSChz
+LG8pCnNbb109MzcKbT1vKzEKbD1DLnhCLlcoayxuPj4+NCkKaWYobT49cClyZXR1cm4gSC5PSChzLG0p
+CnNbbV09bApsPW8rMgptPUMueEIuVyhrLG4mMTUpCmlmKGw+PXApcmV0dXJuIEguT0gocyxsKQpzW2xd
+PW0Kbys9M319cmV0dXJuIFAuSE0ocywwLG51bGwpfSwKUEk6ZnVuY3Rpb24oYSxiLGMsZCxlKXt2YXIg
+cz1QLlVsKGEsYixjLGQsZSkKcmV0dXJuIHM9PW51bGw/Qy54Qi5OaihhLGIsYyk6c30sClVsOmZ1bmN0
+aW9uKGEsYixjLGQsZSl7dmFyIHMscixxLHAsbyxuLG0sbCxrLGo9bnVsbApmb3Iocz0hZSxyPWIscT1y
+LHA9ajtyPGM7KXtvPUMueEIuTzIoYSxyKQppZihvPDEyNyl7bj1vPj4+NAppZihuPj04KXJldHVybiBI
+Lk9IKGQsbikKbj0oZFtuXSYxPDwobyYxNSkpIT09MH1lbHNlIG49ITEKaWYobikrK3IKZWxzZXtpZihv
+PT09Mzcpe209UC5ydihhLHIsITEpCmlmKG09PW51bGwpe3IrPTMKY29udGludWV9aWYoIiUiPT09bSl7
+bT0iJTI1IgpsPTF9ZWxzZSBsPTN9ZWxzZXtpZihzKWlmKG88PTkzKXtuPW8+Pj40CmlmKG4+PTgpcmV0
+dXJuIEguT0goQy5hayxuKQpuPShDLmFrW25dJjE8PChvJjE1KSkhPT0wfWVsc2Ugbj0hMQplbHNlIG49
+ITEKaWYobil7UC5SMyhhLHIsIkludmFsaWQgY2hhcmFjdGVyIikKSC5CaSh1LmcpCmw9agptPWx9ZWxz
+ZXtpZigobyY2NDUxMik9PT01NTI5Nil7bj1yKzEKaWYobjxjKXtrPUMueEIuTzIoYSxuKQppZigoayY2
+NDUxMik9PT01NjMyMCl7bz0obyYxMDIzKTw8MTB8ayYxMDIzfDY1NTM2Cmw9Mn1lbHNlIGw9MX1lbHNl
+IGw9MX1lbHNlIGw9MQptPVAuelgobyl9fWlmKHA9PW51bGwpe3A9bmV3IFAuUm4oIiIpCm49cH1lbHNl
+IG49cApuLmErPUMueEIuTmooYSxxLHIpCm4uYSs9SC5FaihtKQppZih0eXBlb2YgbCE9PSJudW1iZXIi
+KXJldHVybiBILnBZKGwpCnIrPWwKcT1yfX1pZihwPT1udWxsKXJldHVybiBqCmlmKHE8YylwLmErPUMu
+eEIuTmooYSxxLGMpCnM9cC5hCnJldHVybiBzLmNoYXJDb2RlQXQoMCk9PTA/czpzfSwKeUI6ZnVuY3Rp
+b24oYSl7aWYoQy54Qi5uQyhhLCIuIikpcmV0dXJuITAKcmV0dXJuIEMueEIuT1koYSwiLy4iKSE9PS0x
+fSwKeGU6ZnVuY3Rpb24oYSl7dmFyIHMscixxLHAsbyxuLG0KaWYoIVAueUIoYSkpcmV0dXJuIGEKcz1I
+LlZNKFtdLHQucykKZm9yKHI9YS5zcGxpdCgiLyIpLHE9ci5sZW5ndGgscD0hMSxvPTA7bzxxOysrbyl7
+bj1yW29dCmlmKEouUk0obiwiLi4iKSl7bT1zLmxlbmd0aAppZihtIT09MCl7aWYoMD49bSlyZXR1cm4g
+SC5PSChzLC0xKQpzLnBvcCgpCmlmKHMubGVuZ3RoPT09MClDLk5tLmkocywiIil9cD0hMH1lbHNlIGlm
+KCIuIj09PW4pcD0hMAplbHNle0MuTm0uaShzLG4pCnA9ITF9fWlmKHApQy5ObS5pKHMsIiIpCnJldHVy
+biBDLk5tLmsocywiLyIpfSwKd0Y6ZnVuY3Rpb24oYSxiKXt2YXIgcyxyLHEscCxvLG4KaWYoIVAueUIo
+YSkpcmV0dXJuIWI/UC5DMShhKTphCnM9SC5WTShbXSx0LnMpCmZvcihyPWEuc3BsaXQoIi8iKSxxPXIu
+bGVuZ3RoLHA9ITEsbz0wO288cTsrK28pe249cltvXQppZigiLi4iPT09bilpZihzLmxlbmd0aCE9PTAm
+JkMuTm0uZ3JaKHMpIT09Ii4uIil7aWYoMD49cy5sZW5ndGgpcmV0dXJuIEguT0gocywtMSkKcy5wb3Ao
+KQpwPSEwfWVsc2V7Qy5ObS5pKHMsIi4uIikKcD0hMX1lbHNlIGlmKCIuIj09PW4pcD0hMAplbHNle0Mu
+Tm0uaShzLG4pCnA9ITF9fXI9cy5sZW5ndGgKaWYociE9PTApaWYocj09PTEpe2lmKDA+PXIpcmV0dXJu
+IEguT0gocywwKQpyPXNbMF0ubGVuZ3RoPT09MH1lbHNlIHI9ITEKZWxzZSByPSEwCmlmKHIpcmV0dXJu
+Ii4vIgppZihwfHxDLk5tLmdyWihzKT09PSIuLiIpQy5ObS5pKHMsIiIpCmlmKCFiKXtpZigwPj1zLmxl
+bmd0aClyZXR1cm4gSC5PSChzLDApCkMuTm0uWTUocywwLFAuQzEoc1swXSkpfXJldHVybiBDLk5tLmso
+cywiLyIpfSwKQzE6ZnVuY3Rpb24oYSl7dmFyIHMscixxLHA9YS5sZW5ndGgKaWYocD49MiYmUC5FdChK
+LlF6KGEsMCkpKWZvcihzPTE7czxwOysrcyl7cj1DLnhCLlcoYSxzKQppZihyPT09NTgpcmV0dXJuIEMu
+eEIuTmooYSwwLHMpKyIlM0EiK0MueEIueW4oYSxzKzEpCmlmKHI8PTEyNyl7cT1yPj4+NAppZihxPj04
+KXJldHVybiBILk9IKEMubUsscSkKcT0oQy5tS1txXSYxPDwociYxNSkpPT09MH1lbHNlIHE9ITAKaWYo
+cSlicmVha31yZXR1cm4gYX0sCm1uOmZ1bmN0aW9uKGEpe3ZhciBzLHIscSxwPWEuZ0ZqKCksbz1wLmxl
+bmd0aAppZihvPjAmJkouSG0ocFswXSk9PT0yJiZKLmE2KHBbMF0sMSk9PT01OCl7aWYoMD49bylyZXR1
+cm4gSC5PSChwLDApClAucmcoSi5hNihwWzBdLDApLCExKQpQLkhOKHAsITEsMSkKcz0hMH1lbHNle1Au
+SE4ocCwhMSwwKQpzPSExfXI9YS5ndFQoKSYmIXM/IlxcIjoiIgppZihhLmdjaigpKXtxPWEuZ0pmKGEp
+CmlmKHEubGVuZ3RoIT09MClyPXIrIlxcIitxKyJcXCJ9cj1QLnZnKHIscCwiXFwiKQpvPXMmJm89PT0x
+P3IrIlxcIjpyCnJldHVybiBvLmNoYXJDb2RlQXQoMCk9PTA/bzpvfSwKSWg6ZnVuY3Rpb24oYSxiKXt2
+YXIgcyxyLHEKZm9yKHM9MCxyPTA7cjwyOysrcil7cT1DLnhCLlcoYSxiK3IpCmlmKDQ4PD1xJiZxPD01
+NylzPXMqMTYrcS00OAplbHNle3F8PTMyCmlmKDk3PD1xJiZxPD0xMDIpcz1zKjE2K3EtODcKZWxzZSB0
+aHJvdyBILmIoUC54WSgiSW52YWxpZCBVUkwgZW5jb2RpbmciKSl9fXJldHVybiBzfSwKa3U6ZnVuY3Rp
+b24oYSxiLGMsZCxlKXt2YXIgcyxyLHEscCxvPUouclkoYSksbj1iCndoaWxlKCEwKXtpZighKG48Yykp
+e3M9ITAKYnJlYWt9cj1vLlcoYSxuKQppZihyPD0xMjcpaWYociE9PTM3KXE9ZSYmcj09PTQzCmVsc2Ug
+cT0hMAplbHNlIHE9ITAKaWYocSl7cz0hMQpicmVha30rK259aWYocyl7aWYoQy54TSE9PWQpcT0hMQpl
+bHNlIHE9ITAKaWYocSlyZXR1cm4gby5OaihhLGIsYykKZWxzZSBwPW5ldyBILnFqKG8uTmooYSxiLGMp
+KX1lbHNle3A9SC5WTShbXSx0LmEpCmZvcihuPWI7bjxjOysrbil7cj1vLlcoYSxuKQppZihyPjEyNyl0
+aHJvdyBILmIoUC54WSgiSWxsZWdhbCBwZXJjZW50IGVuY29kaW5nIGluIFVSSSIpKQppZihyPT09Mzcp
+e2lmKG4rMz5hLmxlbmd0aCl0aHJvdyBILmIoUC54WSgiVHJ1bmNhdGVkIFVSSSIpKQpDLk5tLmkocCxQ
+LkloKGEsbisxKSkKbis9Mn1lbHNlIGlmKGUmJnI9PT00MylDLk5tLmkocCwzMikKZWxzZSBDLk5tLmko
+cCxyKX19dC5MLmEocCkKcmV0dXJuIEMub0UuV0oocCl9LApFdDpmdW5jdGlvbihhKXt2YXIgcz1hfDMy
+CnJldHVybiA5Nzw9cyYmczw9MTIyfSwKS0Q6ZnVuY3Rpb24oYSxiLGMpe3ZhciBzLHIscSxwLG8sbixt
+LGwsaz0iSW52YWxpZCBNSU1FIHR5cGUiLGo9SC5WTShbYi0xXSx0LmEpCmZvcihzPWEubGVuZ3RoLHI9
+YixxPS0xLHA9bnVsbDtyPHM7KytyKXtwPUMueEIuVyhhLHIpCmlmKHA9PT00NHx8cD09PTU5KWJyZWFr
+CmlmKHA9PT00Nyl7aWYocTwwKXtxPXIKY29udGludWV9dGhyb3cgSC5iKFAucnIoayxhLHIpKX19aWYo
+cTwwJiZyPmIpdGhyb3cgSC5iKFAucnIoayxhLHIpKQpmb3IoO3AhPT00NDspe0MuTm0uaShqLHIpOysr
+cgpmb3Iobz0tMTtyPHM7KytyKXtwPUMueEIuVyhhLHIpCmlmKHA9PT02MSl7aWYobzwwKW89cn1lbHNl
+IGlmKHA9PT01OXx8cD09PTQ0KWJyZWFrfWlmKG8+PTApQy5ObS5pKGosbykKZWxzZXtuPUMuTm0uZ3Ja
+KGopCmlmKHAhPT00NHx8ciE9PW4rN3x8IUMueEIuUWkoYSwiYmFzZTY0IixuKzEpKXRocm93IEguYihQ
+LnJyKCJFeHBlY3RpbmcgJz0nIixhLHIpKQpicmVha319Qy5ObS5pKGoscikKbT1yKzEKaWYoKGoubGVu
+Z3RoJjEpPT09MSlhPUMuaDkueXIoYSxtLHMpCmVsc2V7bD1QLlVsKGEsbSxzLEMuVkMsITApCmlmKGwh
+PW51bGwpYT1DLnhCLmk3KGEsbSxzLGwpfXJldHVybiBuZXcgUC5QRShhLGosYyl9LApLTjpmdW5jdGlv
+bigpe3ZhciBzLHIscSxwLG8sbixtPSIwMTIzNDU2Nzg5QUJDREVGR0hJSktMTU5PUFFSU1RVVldYWVph
+YmNkZWZnaGlqa2xtbm9wcXJzdHV2d3h5ei0uX34hJCYnKCkqKyw7PSIsbD0iLiIsaz0iOiIsaj0iLyIs
+aT0iPyIsaD0iIyIsZz1ILlZNKG5ldyBBcnJheSgyMiksdC5nTikKZm9yKHM9MDtzPDIyOysrcylnW3Nd
+PW5ldyBVaW50OEFycmF5KDk2KQpyPW5ldyBQLnlJKGcpCnE9bmV3IFAuYzYoKQpwPW5ldyBQLnFkKCkK
+bz10LmdjCm49by5hKHIuJDIoMCwyMjUpKQpxLiQzKG4sbSwxKQpxLiQzKG4sbCwxNCkKcS4kMyhuLGss
+MzQpCnEuJDMobixqLDMpCnEuJDMobixpLDE3MikKcS4kMyhuLGgsMjA1KQpuPW8uYShyLiQyKDE0LDIy
+NSkpCnEuJDMobixtLDEpCnEuJDMobixsLDE1KQpxLiQzKG4saywzNCkKcS4kMyhuLGosMjM0KQpxLiQz
+KG4saSwxNzIpCnEuJDMobixoLDIwNSkKbj1vLmEoci4kMigxNSwyMjUpKQpxLiQzKG4sbSwxKQpxLiQz
+KG4sIiUiLDIyNSkKcS4kMyhuLGssMzQpCnEuJDMobixqLDkpCnEuJDMobixpLDE3MikKcS4kMyhuLGgs
+MjA1KQpuPW8uYShyLiQyKDEsMjI1KSkKcS4kMyhuLG0sMSkKcS4kMyhuLGssMzQpCnEuJDMobixqLDEw
+KQpxLiQzKG4saSwxNzIpCnEuJDMobixoLDIwNSkKbj1vLmEoci4kMigyLDIzNSkpCnEuJDMobixtLDEz
+OSkKcS4kMyhuLGosMTMxKQpxLiQzKG4sbCwxNDYpCnEuJDMobixpLDE3MikKcS4kMyhuLGgsMjA1KQpu
+PW8uYShyLiQyKDMsMjM1KSkKcS4kMyhuLG0sMTEpCnEuJDMobixqLDY4KQpxLiQzKG4sbCwxOCkKcS4k
+MyhuLGksMTcyKQpxLiQzKG4saCwyMDUpCm49by5hKHIuJDIoNCwyMjkpKQpxLiQzKG4sbSw1KQpwLiQz
+KG4sIkFaIiwyMjkpCnEuJDMobixrLDEwMikKcS4kMyhuLCJAIiw2OCkKcS4kMyhuLCJbIiwyMzIpCnEu
+JDMobixqLDEzOCkKcS4kMyhuLGksMTcyKQpxLiQzKG4saCwyMDUpCm49by5hKHIuJDIoNSwyMjkpKQpx
+LiQzKG4sbSw1KQpwLiQzKG4sIkFaIiwyMjkpCnEuJDMobixrLDEwMikKcS4kMyhuLCJAIiw2OCkKcS4k
+MyhuLGosMTM4KQpxLiQzKG4saSwxNzIpCnEuJDMobixoLDIwNSkKbj1vLmEoci4kMig2LDIzMSkpCnAu
+JDMobiwiMTkiLDcpCnEuJDMobiwiQCIsNjgpCnEuJDMobixqLDEzOCkKcS4kMyhuLGksMTcyKQpxLiQz
+KG4saCwyMDUpCm49by5hKHIuJDIoNywyMzEpKQpwLiQzKG4sIjA5Iiw3KQpxLiQzKG4sIkAiLDY4KQpx
+LiQzKG4saiwxMzgpCnEuJDMobixpLDE3MikKcS4kMyhuLGgsMjA1KQpxLiQzKG8uYShyLiQyKDgsOCkp
+LCJdIiw1KQpuPW8uYShyLiQyKDksMjM1KSkKcS4kMyhuLG0sMTEpCnEuJDMobixsLDE2KQpxLiQzKG4s
+aiwyMzQpCnEuJDMobixpLDE3MikKcS4kMyhuLGgsMjA1KQpuPW8uYShyLiQyKDE2LDIzNSkpCnEuJDMo
+bixtLDExKQpxLiQzKG4sbCwxNykKcS4kMyhuLGosMjM0KQpxLiQzKG4saSwxNzIpCnEuJDMobixoLDIw
+NSkKbj1vLmEoci4kMigxNywyMzUpKQpxLiQzKG4sbSwxMSkKcS4kMyhuLGosOSkKcS4kMyhuLGksMTcy
+KQpxLiQzKG4saCwyMDUpCm49by5hKHIuJDIoMTAsMjM1KSkKcS4kMyhuLG0sMTEpCnEuJDMobixsLDE4
+KQpxLiQzKG4saiwyMzQpCnEuJDMobixpLDE3MikKcS4kMyhuLGgsMjA1KQpuPW8uYShyLiQyKDE4LDIz
+NSkpCnEuJDMobixtLDExKQpxLiQzKG4sbCwxOSkKcS4kMyhuLGosMjM0KQpxLiQzKG4saSwxNzIpCnEu
+JDMobixoLDIwNSkKbj1vLmEoci4kMigxOSwyMzUpKQpxLiQzKG4sbSwxMSkKcS4kMyhuLGosMjM0KQpx
+LiQzKG4saSwxNzIpCnEuJDMobixoLDIwNSkKbj1vLmEoci4kMigxMSwyMzUpKQpxLiQzKG4sbSwxMSkK
+cS4kMyhuLGosMTApCnEuJDMobixpLDE3MikKcS4kMyhuLGgsMjA1KQpuPW8uYShyLiQyKDEyLDIzNikp
+CnEuJDMobixtLDEyKQpxLiQzKG4saSwxMikKcS4kMyhuLGgsMjA1KQpuPW8uYShyLiQyKDEzLDIzNykp
+CnEuJDMobixtLDEzKQpxLiQzKG4saSwxMykKcC4kMyhvLmEoci4kMigyMCwyNDUpKSwiYXoiLDIxKQpy
+PW8uYShyLiQyKDIxLDI0NSkpCnAuJDMociwiYXoiLDIxKQpwLiQzKHIsIjA5IiwyMSkKcS4kMyhyLCIr
+LS4iLDIxKQpyZXR1cm4gZ30sClVCOmZ1bmN0aW9uKGEsYixjLGQsZSl7dmFyIHMscixxLHAsbyxuPSQu
+dlooKQpmb3Iocz1KLnJZKGEpLHI9YjtyPGM7KytyKXtpZihkPDB8fGQ+PW4ubGVuZ3RoKXJldHVybiBI
+Lk9IKG4sZCkKcT1uW2RdCnA9cy5XKGEscileOTYKbz1xW3A+OTU/MzE6cF0KZD1vJjMxCkMuTm0uWTUo
+ZSxvPj4+NSxyKX1yZXR1cm4gZH0sCldGOmZ1bmN0aW9uIFdGKGEsYil7dGhpcy5hPWEKdGhpcy5iPWJ9
+LAppUDpmdW5jdGlvbiBpUChhLGIpe3RoaXMuYT1hCnRoaXMuYj1ifSwKWFM6ZnVuY3Rpb24gWFMoKXt9
+LApDNjpmdW5jdGlvbiBDNihhKXt0aGlzLmE9YX0sCkV6OmZ1bmN0aW9uIEV6KCl7fSwKRjpmdW5jdGlv
+biBGKCl7fSwKdTpmdW5jdGlvbiB1KGEsYixjLGQpe3ZhciBfPXRoaXMKXy5hPWEKXy5iPWIKXy5jPWMK
+Xy5kPWR9LApiSjpmdW5jdGlvbiBiSihhLGIsYyxkLGUsZil7dmFyIF89dGhpcwpfLmU9YQpfLmY9Ygpf
+LmE9YwpfLmI9ZApfLmM9ZQpfLmQ9Zn0sCmVZOmZ1bmN0aW9uIGVZKGEsYixjLGQsZSl7dmFyIF89dGhp
+cwpfLmY9YQpfLmE9YgpfLmI9YwpfLmM9ZApfLmQ9ZX0sCm1wOmZ1bmN0aW9uIG1wKGEsYixjLGQpe3Zh
+ciBfPXRoaXMKXy5hPWEKXy5iPWIKXy5jPWMKXy5kPWR9LAp1YjpmdW5jdGlvbiB1YihhKXt0aGlzLmE9
+YX0sCmRzOmZ1bmN0aW9uIGRzKGEpe3RoaXMuYT1hfSwKbGo6ZnVuY3Rpb24gbGooYSl7dGhpcy5hPWF9
+LApVVjpmdW5jdGlvbiBVVihhKXt0aGlzLmE9YX0sCms1OmZ1bmN0aW9uIGs1KCl7fSwKS1k6ZnVuY3Rp
+b24gS1koKXt9LApjOmZ1bmN0aW9uIGMoYSl7dGhpcy5hPWF9LApDRDpmdW5jdGlvbiBDRChhKXt0aGlz
+LmE9YX0sCmFFOmZ1bmN0aW9uIGFFKGEsYixjKXt0aGlzLmE9YQp0aGlzLmI9Ygp0aGlzLmM9Y30sCmNY
+OmZ1bmN0aW9uIGNYKCl7fSwKQW46ZnVuY3Rpb24gQW4oKXt9LApOMzpmdW5jdGlvbiBOMyhhLGIsYyl7
+dGhpcy5hPWEKdGhpcy5iPWIKdGhpcy4kdGk9Y30sCmM4OmZ1bmN0aW9uIGM4KCl7fSwKTWg6ZnVuY3Rp
+b24gTWgoKXt9LApaZDpmdW5jdGlvbiBaZCgpe30sClJuOmZ1bmN0aW9uIFJuKGEpe3RoaXMuYT1hfSwK
+bjE6ZnVuY3Rpb24gbjEoYSl7dGhpcy5hPWF9LApjUzpmdW5jdGlvbiBjUyhhKXt0aGlzLmE9YX0sClZD
+OmZ1bmN0aW9uIFZDKGEpe3RoaXMuYT1hfSwKSlQ6ZnVuY3Rpb24gSlQoYSxiKXt0aGlzLmE9YQp0aGlz
+LmI9Yn0sCkRuOmZ1bmN0aW9uIERuKGEsYixjLGQsZSxmLGcpe3ZhciBfPXRoaXMKXy5hPWEKXy5iPWIK
+Xy5jPWMKXy5kPWQKXy5lPWUKXy5mPWYKXy5yPWcKXy54PW51bGwKXy55PSExCl8uej1udWxsCl8uUT0h
+MQpfLmNoPW51bGwKXy5jeD0hMQpfLmN5PW51bGwKXy5kYj0hMX0sClJaOmZ1bmN0aW9uIFJaKCl7fSwK
+TUU6ZnVuY3Rpb24gTUUoYSxiKXt0aGlzLmE9YQp0aGlzLmI9Yn0sCnk1OmZ1bmN0aW9uIHk1KGEpe3Ro
+aXMuYT1hfSwKUEU6ZnVuY3Rpb24gUEUoYSxiLGMpe3RoaXMuYT1hCnRoaXMuYj1iCnRoaXMuYz1jfSwK
+eUk6ZnVuY3Rpb24geUkoYSl7dGhpcy5hPWF9LApjNjpmdW5jdGlvbiBjNigpe30sCnFkOmZ1bmN0aW9u
+IHFkKCl7fSwKVWY6ZnVuY3Rpb24gVWYoYSxiLGMsZCxlLGYsZyxoKXt2YXIgXz10aGlzCl8uYT1hCl8u
+Yj1iCl8uYz1jCl8uZD1kCl8uZT1lCl8uZj1mCl8ucj1nCl8ueD1oCl8ueT1udWxsfSwKcWU6ZnVuY3Rp
+b24gcWUoYSxiLGMsZCxlLGYsZyl7dmFyIF89dGhpcwpfLmE9YQpfLmI9YgpfLmM9YwpfLmQ9ZApfLmU9
+ZQpfLmY9ZgpfLnI9ZwpfLng9bnVsbApfLnk9ITEKXy56PW51bGwKXy5RPSExCl8uY2g9bnVsbApfLmN4
+PSExCl8uY3k9bnVsbApfLmRiPSExfSwKaUo6ZnVuY3Rpb24gaUooKXt9LApqZzpmdW5jdGlvbiBqZyhh
+LGIpe3RoaXMuYT1hCnRoaXMuYj1ifSwKVGE6ZnVuY3Rpb24gVGEoYSxiKXt0aGlzLmE9YQp0aGlzLmI9
+Yn0sCkJmOmZ1bmN0aW9uIEJmKGEsYil7dGhpcy5hPWEKdGhpcy5iPWJ9LApBczpmdW5jdGlvbiBBcygp
+e30sCkdFOmZ1bmN0aW9uIEdFKGEpe3RoaXMuYT1hfSwKTjc6ZnVuY3Rpb24gTjcoYSxiKXt0aGlzLmE9
+YQp0aGlzLmI9Yn0sCnVROmZ1bmN0aW9uIHVRKCl7fSwKaEY6ZnVuY3Rpb24gaEYoKXt9LApSNDpmdW5j
+dGlvbihhLGIsYyxkKXt2YXIgcyxyLHEKSC55OChiKQp0LmouYShkKQppZihILm9UKGIpKXtzPVtjXQpD
+Lk5tLkZWKHMsZCkKZD1zfXI9dC56CnE9UC5DSChKLk0xKGQsUC53MCgpLHIpLCEwLHIpCnQuWS5hKGEp
+CnJldHVybiBQLndZKEguRWsoYSxxLG51bGwpKX0sCkRtOmZ1bmN0aW9uKGEsYixjKXt2YXIgcwp0cnl7
+aWYoT2JqZWN0LmlzRXh0ZW5zaWJsZShhKSYmIU9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHku
+Y2FsbChhLGIpKXtPYmplY3QuZGVmaW5lUHJvcGVydHkoYSxiLHt2YWx1ZTpjfSkKcmV0dXJuITB9fWNh
+dGNoKHMpe0guUnUocyl9cmV0dXJuITF9LApPbTpmdW5jdGlvbihhLGIpe2lmKE9iamVjdC5wcm90b3R5
+cGUuaGFzT3duUHJvcGVydHkuY2FsbChhLGIpKXJldHVybiBhW2JdCnJldHVybiBudWxsfSwKd1k6ZnVu
+Y3Rpb24oYSl7aWYoYT09bnVsbHx8dHlwZW9mIGE9PSJzdHJpbmcifHx0eXBlb2YgYT09Im51bWJlciJ8
+fEgubChhKSlyZXR1cm4gYQppZihhIGluc3RhbmNlb2YgUC5FNClyZXR1cm4gYS5hCmlmKEguUjkoYSkp
+cmV0dXJuIGEKaWYodC5hay5iKGEpKXJldHVybiBhCmlmKGEgaW5zdGFuY2VvZiBQLmlQKXJldHVybiBI
+Lm8yKGEpCmlmKHQuWS5iKGEpKXJldHVybiBQLmhFKGEsIiRkYXJ0X2pzRnVuY3Rpb24iLG5ldyBQLlBD
+KCkpCnJldHVybiBQLmhFKGEsIl8kZGFydF9qc09iamVjdCIsbmV3IFAubXQoJC5rSSgpKSl9LApoRTpm
+dW5jdGlvbihhLGIsYyl7dmFyIHM9UC5PbShhLGIpCmlmKHM9PW51bGwpe3M9Yy4kMShhKQpQLkRtKGEs
+YixzKX1yZXR1cm4gc30sCmRVOmZ1bmN0aW9uKGEpe3ZhciBzLHIKaWYoYT09bnVsbHx8dHlwZW9mIGE9
+PSJzdHJpbmcifHx0eXBlb2YgYT09Im51bWJlciJ8fHR5cGVvZiBhPT0iYm9vbGVhbiIpcmV0dXJuIGEK
+ZWxzZSBpZihhIGluc3RhbmNlb2YgT2JqZWN0JiZILlI5KGEpKXJldHVybiBhCmVsc2UgaWYoYSBpbnN0
+YW5jZW9mIE9iamVjdCYmdC5hay5iKGEpKXJldHVybiBhCmVsc2UgaWYoYSBpbnN0YW5jZW9mIERhdGUp
+e3M9SC51UChhLmdldFRpbWUoKSkKaWYoTWF0aC5hYnMocyk8PTg2NGUxMylyPSExCmVsc2Ugcj0hMApp
+ZihyKUgudihQLnhZKCJEYXRlVGltZSBpcyBvdXRzaWRlIHZhbGlkIHJhbmdlOiAiK3MpKQpILmNiKCEx
+LCJpc1V0YyIsdC55KQpyZXR1cm4gbmV3IFAuaVAocywhMSl9ZWxzZSBpZihhLmNvbnN0cnVjdG9yPT09
+JC5rSSgpKXJldHVybiBhLm8KZWxzZSByZXR1cm4gUC5ORChhKX0sCk5EOmZ1bmN0aW9uKGEpe2lmKHR5
+cGVvZiBhPT0iZnVuY3Rpb24iKXJldHVybiBQLmlRKGEsJC53KCksbmV3IFAuTnooKSkKaWYoYSBpbnN0
+YW5jZW9mIEFycmF5KXJldHVybiBQLmlRKGEsJC5SOCgpLG5ldyBQLlFTKCkpCnJldHVybiBQLmlRKGEs
+JC5SOCgpLG5ldyBQLm5wKCkpfSwKaVE6ZnVuY3Rpb24oYSxiLGMpe3ZhciBzPVAuT20oYSxiKQppZihz
+PT1udWxsfHwhKGEgaW5zdGFuY2VvZiBPYmplY3QpKXtzPWMuJDEoYSkKUC5EbShhLGIscyl9cmV0dXJu
+IHN9LApQQzpmdW5jdGlvbiBQQygpe30sCm10OmZ1bmN0aW9uIG10KGEpe3RoaXMuYT1hfSwKTno6ZnVu
+Y3Rpb24gTnooKXt9LApRUzpmdW5jdGlvbiBRUygpe30sCm5wOmZ1bmN0aW9uIG5wKCl7fSwKRTQ6ZnVu
+Y3Rpb24gRTQoYSl7dGhpcy5hPWF9LApyNzpmdW5jdGlvbiByNyhhKXt0aGlzLmE9YX0sClR6OmZ1bmN0
+aW9uIFR6KGEsYil7dGhpcy5hPWEKdGhpcy4kdGk9Yn0sCmNvOmZ1bmN0aW9uIGNvKCl7fSwKbmQ6ZnVu
+Y3Rpb24gbmQoKXt9LApLZTpmdW5jdGlvbiBLZShhKXt0aGlzLmE9YX0sCmhpOmZ1bmN0aW9uIGhpKCl7
+fX0sVz17CngzOmZ1bmN0aW9uKCl7cmV0dXJuIHdpbmRvd30sClpyOmZ1bmN0aW9uKCl7cmV0dXJuIGRv
+Y3VtZW50fSwKSjY6ZnVuY3Rpb24oYSl7dmFyIHM9ZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgiYSIpCmlm
+KGEhPW51bGwpQy54bi5zTFUocyxhKQpyZXR1cm4gc30sClU5OmZ1bmN0aW9uKGEsYixjKXt2YXIgcyxy
+PWRvY3VtZW50LmJvZHkKci50b1N0cmluZwpzPUMuUlkucjYocixhLGIsYykKcy50b1N0cmluZwpyPXQu
+YWMKcj1uZXcgSC5VNShuZXcgVy5lNyhzKSxyLkMoImEyKGxELkUpIikuYShuZXcgVy5DdigpKSxyLkMo
+IlU1PGxELkU+IikpCnJldHVybiB0LmguYShyLmdyOChyKSl9LApyUzpmdW5jdGlvbihhKXt2YXIgcyxy
+LHE9ImVsZW1lbnQgdGFnIHVuYXZhaWxhYmxlIgp0cnl7cz1KLllFKGEpCmlmKHR5cGVvZiBzLmducyhh
+KT09InN0cmluZyIpcT1zLmducyhhKX1jYXRjaChyKXtILlJ1KHIpfXJldHVybiBxfSwKQzA6ZnVuY3Rp
+b24oYSxiKXthPWErYiY1MzY4NzA5MTEKYT1hKygoYSY1MjQyODcpPDwxMCkmNTM2ODcwOTExCnJldHVy
+biBhXmE+Pj42fSwKckU6ZnVuY3Rpb24oYSxiLGMsZCl7dmFyIHM9Vy5DMChXLkMwKFcuQzAoVy5DMCgw
+LGEpLGIpLGMpLGQpLHI9cysoKHMmNjcxMDg4NjMpPDwzKSY1MzY4NzA5MTEKcl49cj4+PjExCnJldHVy
+biByKygociYxNjM4Myk8PDE1KSY1MzY4NzA5MTF9LApUTjpmdW5jdGlvbihhLGIpe3ZhciBzLHIscT1h
+LmNsYXNzTGlzdApmb3Iocz1iLmxlbmd0aCxyPTA7cjxiLmxlbmd0aDtiLmxlbmd0aD09PXN8fCgwLEgu
+bGspKGIpLCsrcilxLmFkZChiW3JdKX0sCkpFOmZ1bmN0aW9uKGEsYixjLGQsZSl7dmFyIHM9Vy5hRihu
+ZXcgVy52TihjKSx0LkIpCmlmKHMhPW51bGwmJiEwKUouZFooYSxiLHMsITEpCnJldHVybiBuZXcgVy54
+QyhhLGIscywhMSxlLkMoInhDPDA+IikpfSwKVHc6ZnVuY3Rpb24oYSl7dmFyIHM9Vy5KNihudWxsKSxy
+PXdpbmRvdy5sb2NhdGlvbgpzPW5ldyBXLkpRKG5ldyBXLm1rKHMscikpCnMuQ1koYSkKcmV0dXJuIHN9
+LApxRDpmdW5jdGlvbihhLGIsYyxkKXt0LmguYShhKQpILmgoYikKSC5oKGMpCnQuY3IuYShkKQpyZXR1
+cm4hMH0sClFXOmZ1bmN0aW9uKGEsYixjLGQpe3ZhciBzLHIscQp0LmguYShhKQpILmgoYikKSC5oKGMp
+CnM9dC5jci5hKGQpLmEKcj1zLmEKQy54bi5zTFUocixjKQpxPXIuaG9zdG5hbWUKcz1zLmIKaWYoIShx
+PT1zLmhvc3RuYW1lJiZyLnBvcnQ9PXMucG9ydCYmci5wcm90b2NvbD09cy5wcm90b2NvbCkpaWYocT09
+PSIiKWlmKHIucG9ydD09PSIiKXtzPXIucHJvdG9jb2wKcz1zPT09IjoifHxzPT09IiJ9ZWxzZSBzPSEx
+CmVsc2Ugcz0hMQplbHNlIHM9ITAKcmV0dXJuIHN9LApCbDpmdW5jdGlvbigpe3ZhciBzPXQuTixyPVAu
+dE0oQy5ReCxzKSxxPXQuZDAuYShuZXcgVy5JQSgpKSxwPUguVk0oWyJURU1QTEFURSJdLHQucykKcz1u
+ZXcgVy5jdChyLFAuTHMocyksUC5McyhzKSxQLkxzKHMpLG51bGwpCnMuQ1kobnVsbCxuZXcgSC5sSihD
+LlF4LHEsdC5maikscCxudWxsKQpyZXR1cm4gc30sCnFjOmZ1bmN0aW9uKGEpe3ZhciBzCmlmKGE9PW51
+bGwpcmV0dXJuIG51bGwKaWYoInBvc3RNZXNzYWdlIiBpbiBhKXtzPVcuUDEoYSkKaWYodC5hUy5iKHMp
+KXJldHVybiBzCnJldHVybiBudWxsfWVsc2UgcmV0dXJuIHQuY2guYShhKX0sClAxOmZ1bmN0aW9uKGEp
+e2lmKGE9PT13aW5kb3cpcmV0dXJuIHQuY2kuYShhKQplbHNlIHJldHVybiBuZXcgVy5kVygpfSwKYUY6
+ZnVuY3Rpb24oYSxiKXt2YXIgcz0kLlgzCmlmKHM9PT1DLk5VKXJldHVybiBhCnJldHVybiBzLlB5KGEs
+Yil9LApxRTpmdW5jdGlvbiBxRSgpe30sCkdoOmZ1bmN0aW9uIEdoKCl7fSwKZlk6ZnVuY3Rpb24gZlko
+KXt9LApuQjpmdW5jdGlvbiBuQigpe30sCkF6OmZ1bmN0aW9uIEF6KCl7fSwKUVA6ZnVuY3Rpb24gUVAo
+KXt9LApueDpmdW5jdGlvbiBueCgpe30sCm9KOmZ1bmN0aW9uIG9KKCl7fSwKaWQ6ZnVuY3Rpb24gaWQo
+KXt9LApRRjpmdW5jdGlvbiBRRigpe30sCk5oOmZ1bmN0aW9uIE5oKCl7fSwKYWU6ZnVuY3Rpb24gYWUo
+KXt9LApJQjpmdW5jdGlvbiBJQigpe30sCm43OmZ1bmN0aW9uIG43KCl7fSwKd3o6ZnVuY3Rpb24gd3oo
+YSxiKXt0aGlzLmE9YQp0aGlzLiR0aT1ifSwKY3Y6ZnVuY3Rpb24gY3YoKXt9LApDdjpmdW5jdGlvbiBD
+digpe30sCmVhOmZ1bmN0aW9uIGVhKCl7fSwKRDA6ZnVuY3Rpb24gRDAoKXt9LApoSDpmdW5jdGlvbiBo
+SCgpe30sCmg0OmZ1bmN0aW9uIGg0KCl7fSwKYnI6ZnVuY3Rpb24gYnIoKXt9LApWYjpmdW5jdGlvbiBW
+Yigpe30sCmZKOmZ1bmN0aW9uIGZKKCl7fSwKd2E6ZnVuY3Rpb24gd2EoKXt9LApTZzpmdW5jdGlvbiBT
+Zygpe30sCnc3OmZ1bmN0aW9uIHc3KCl7fSwKQWo6ZnVuY3Rpb24gQWooKXt9LAplNzpmdW5jdGlvbiBl
+NyhhKXt0aGlzLmE9YX0sCnVIOmZ1bmN0aW9uIHVIKCl7fSwKQkg6ZnVuY3Rpb24gQkgoKXt9LApTTjpm
+dW5jdGlvbiBTTigpe30sCmV3OmZ1bmN0aW9uIGV3KCl7fSwKbHA6ZnVuY3Rpb24gbHAoKXt9LApUYjpm
+dW5jdGlvbiBUYigpe30sCkl2OmZ1bmN0aW9uIEl2KCl7fSwKV1A6ZnVuY3Rpb24gV1AoKXt9LAp5WTpm
+dW5jdGlvbiB5WSgpe30sCnc2OmZ1bmN0aW9uIHc2KCl7fSwKSzU6ZnVuY3Rpb24gSzUoKXt9LApDbTpm
+dW5jdGlvbiBDbSgpe30sCkNROmZ1bmN0aW9uIENRKCl7fSwKdzQ6ZnVuY3Rpb24gdzQoKXt9LApyaDpm
+dW5jdGlvbiByaCgpe30sCmNmOmZ1bmN0aW9uIGNmKCl7fSwKaTc6ZnVuY3Rpb24gaTcoYSl7dGhpcy5h
+PWF9LApTeTpmdW5jdGlvbiBTeShhKXt0aGlzLmE9YX0sCktTOmZ1bmN0aW9uIEtTKGEsYil7dGhpcy5h
+PWEKdGhpcy5iPWJ9LApBMzpmdW5jdGlvbiBBMyhhLGIpe3RoaXMuYT1hCnRoaXMuYj1ifSwKSTQ6ZnVu
+Y3Rpb24gSTQoYSl7dGhpcy5hPWF9LApGazpmdW5jdGlvbiBGayhhLGIpe3RoaXMuYT1hCnRoaXMuJHRp
+PWJ9LApSTzpmdW5jdGlvbiBSTyhhLGIsYyxkKXt2YXIgXz10aGlzCl8uYT1hCl8uYj1iCl8uYz1jCl8u
+JHRpPWR9LApldTpmdW5jdGlvbiBldShhLGIsYyxkKXt2YXIgXz10aGlzCl8uYT1hCl8uYj1iCl8uYz1j
+Cl8uJHRpPWR9LAp4QzpmdW5jdGlvbiB4QyhhLGIsYyxkLGUpe3ZhciBfPXRoaXMKXy5iPWEKXy5jPWIK
+Xy5kPWMKXy5lPWQKXy4kdGk9ZX0sCnZOOmZ1bmN0aW9uIHZOKGEpe3RoaXMuYT1hfSwKSlE6ZnVuY3Rp
+b24gSlEoYSl7dGhpcy5hPWF9LApHbTpmdW5jdGlvbiBHbSgpe30sCnZEOmZ1bmN0aW9uIHZEKGEpe3Ro
+aXMuYT1hfSwKVXY6ZnVuY3Rpb24gVXYoYSl7dGhpcy5hPWF9LApFZzpmdW5jdGlvbiBFZyhhLGIsYyl7
+dGhpcy5hPWEKdGhpcy5iPWIKdGhpcy5jPWN9LAptNjpmdW5jdGlvbiBtNigpe30sCkVvOmZ1bmN0aW9u
+IEVvKCl7fSwKV2s6ZnVuY3Rpb24gV2soKXt9LApjdDpmdW5jdGlvbiBjdChhLGIsYyxkLGUpe3ZhciBf
+PXRoaXMKXy5lPWEKXy5hPWIKXy5iPWMKXy5jPWQKXy5kPWV9LApJQTpmdW5jdGlvbiBJQSgpe30sCk93
+OmZ1bmN0aW9uIE93KCl7fSwKVzk6ZnVuY3Rpb24gVzkoYSxiLGMpe3ZhciBfPXRoaXMKXy5hPWEKXy5i
+PWIKXy5jPS0xCl8uZD1udWxsCl8uJHRpPWN9LApkVzpmdW5jdGlvbiBkVygpe30sCm1rOmZ1bmN0aW9u
+IG1rKGEsYil7dGhpcy5hPWEKdGhpcy5iPWJ9LApLbzpmdW5jdGlvbiBLbyhhKXt0aGlzLmE9YQp0aGlz
+LmI9ITF9LApmbTpmdW5jdGlvbiBmbShhKXt0aGlzLmE9YX0sCkxlOmZ1bmN0aW9uIExlKCl7fSwKSzc6
+ZnVuY3Rpb24gSzcoKXt9LApyQjpmdW5jdGlvbiByQigpe30sClhXOmZ1bmN0aW9uIFhXKCl7fSwKb2E6
+ZnVuY3Rpb24gb2EoKXt9fSxNPXsKT1g6ZnVuY3Rpb24oYSl7c3dpdGNoKGEpe2Nhc2UgQy5BZDpyZXR1
+cm4iQWRkIC8qPyovIGhpbnQiCmNhc2UgQy5uZTpyZXR1cm4iQWRkIC8qISovIGhpbnQiCmNhc2UgQy53
+VjpyZXR1cm4iUmVtb3ZlIC8qPyovIGhpbnQiCmNhc2UgQy5mUjpyZXR1cm4iUmVtb3ZlIC8qISovIGhp
+bnQiCmNhc2UgQy5teTpyZXR1cm4iQ2hhbmdlIHRvIC8qPyovIGhpbnQiCmNhc2UgQy5yeDpyZXR1cm4i
+Q2hhbmdlIHRvIC8qISovIGhpbnQifXJldHVybiBudWxsfSwKSDc6ZnVuY3Rpb24gSDcoYSxiKXt0aGlz
+LmE9YQp0aGlzLmI9Yn0sCllGOmZ1bmN0aW9uKGEsYil7dmFyIHMscixxLHAsbyxuLG0sbApmb3Iocz1i
+Lmxlbmd0aCxyPTE7cjxzOysrcil7aWYoYltyXT09bnVsbHx8YltyLTFdIT1udWxsKWNvbnRpbnVlCmZv
+cig7cz49MTtzPXEpe3E9cy0xCmlmKGJbcV0hPW51bGwpYnJlYWt9cD1uZXcgUC5SbigiIikKbz1hKyIo
+IgpwLmE9bwpuPUgudDYoYikKbT1uLkMoIm5IPDE+IikKbD1uZXcgSC5uSChiLDAscyxtKQpsLkhkKGIs
+MCxzLG4uYykKbT1vK25ldyBILmxKKGwsbS5DKCJxVShhTC5FKSIpLmEobmV3IE0uTm8oKSksbS5DKCJs
+SjxhTC5FLHFVPiIpKS5rKDAsIiwgIikKcC5hPW0KcC5hPW0rKCIpOiBwYXJ0ICIrKHItMSkrIiB3YXMg
+bnVsbCwgYnV0IHBhcnQgIityKyIgd2FzIG5vdC4iKQp0aHJvdyBILmIoUC54WShwLncoMCkpKX19LAps
+STpmdW5jdGlvbiBsSShhKXt0aGlzLmE9YX0sCnE3OmZ1bmN0aW9uIHE3KCl7fSwKTm86ZnVuY3Rpb24g
+Tm8oKXt9fSxVPXsKbno6ZnVuY3Rpb24oYSl7dmFyIHM9SC51UChhLnEoMCwibm9kZUlkIikpCnJldHVy
+biBuZXcgVS5MTChDLk5tLkh0KEMucmssbmV3IFUuTUQoYSkpLHMpfSwKTEw6ZnVuY3Rpb24gTEwoYSxi
+KXt0aGlzLmE9YQp0aGlzLmI9Yn0sCk1EOmZ1bmN0aW9uIE1EKGEpe3RoaXMuYT1hfSwKamY6ZnVuY3Rp
+b24oYSl7dmFyIHMscixxLHAKaWYoYT09bnVsbClzPW51bGwKZWxzZXtzPUguVk0oW10sdC5kNykKZm9y
+KHI9Si5JVCh0LlUuYShhKSk7ci5GKCk7KXtxPXIuZ2woKQpwPUouVTYocSkKcy5wdXNoKG5ldyBVLlNl
+KEguaChwLnEocSwiZGVzY3JpcHRpb24iKSksSC5oKHAucShxLCJocmVmIikpKSl9fXJldHVybiBzfSwK
+TmQ6ZnVuY3Rpb24oYSl7dmFyIHMscgppZihhPT1udWxsKXM9bnVsbAplbHNle3M9SC5WTShbXSx0LmFB
+KQpmb3Iocj1KLklUKHQuVS5hKGEpKTtyLkYoKTspcy5wdXNoKFUuTmYoci5nbCgpKSl9cmV0dXJuIHN9
+LApOZjpmdW5jdGlvbihhKXt2YXIgcz1KLlU2KGEpLHI9SC5oKHMucShhLCJkZXNjcmlwdGlvbiIpKSxx
+PUguVk0oW10sdC5hSikKZm9yKHM9Si5JVCh0LlUuYShzLnEoYSwiZW50cmllcyIpKSk7cy5GKCk7KXEu
+cHVzaChVLlJqKHMuZ2woKSkpCnJldHVybiBuZXcgVS55RChyLHEpfSwKUmo6ZnVuY3Rpb24oYSl7dmFy
+IHMscj1KLlU2KGEpLHE9SC5oKHIucShhLCJkZXNjcmlwdGlvbiIpKSxwPUguaChyLnEoYSwiZnVuY3Rp
+b24iKSksbz1yLnEoYSwibGluayIpCmlmKG89PW51bGwpbz1udWxsCmVsc2V7cz1KLlU2KG8pCm89bmV3
+IFUuTWwoSC5oKHMucShvLCJocmVmIikpLEgudVAocy5xKG8sImxpbmUiKSksSC5oKHMucShvLCJwYXRo
+IikpKX1yPXQuZksuYShyLnEoYSwiaGludEFjdGlvbnMiKSkKcj1yPT1udWxsP251bGw6Si5NMShyLG5l
+dyBVLmFOKCksdC5hWCkKcj1yPT1udWxsP251bGw6ci5icigwKQpyZXR1cm4gbmV3IFUud2IocSxwLG8s
+cj09bnVsbD9DLmRuOnIpfSwKZDI6ZnVuY3Rpb24gZDIoYSxiLGMsZCxlLGYpe3ZhciBfPXRoaXMKXy5h
+PWEKXy5iPWIKXy5jPWMKXy5kPWQKXy5lPWUKXy5mPWZ9LApTZTpmdW5jdGlvbiBTZShhLGIpe3RoaXMu
+YT1hCnRoaXMuYj1ifSwKTWw6ZnVuY3Rpb24gTWwoYSxiLGMpe3RoaXMuYT1hCnRoaXMuYj1iCnRoaXMu
+Yz1jfSwKeUQ6ZnVuY3Rpb24geUQoYSxiKXt0aGlzLmE9YQp0aGlzLmI9Yn0sCndiOmZ1bmN0aW9uIHdi
+KGEsYixjLGQpe3ZhciBfPXRoaXMKXy5hPWEKXy5iPWIKXy5jPWMKXy5kPWR9LAphTjpmdW5jdGlvbiBh
+Tigpe30sCmIwOmZ1bmN0aW9uIGIwKCl7fX0sQj17CndSOmZ1bmN0aW9uKCl7cmV0dXJuIG5ldyBCLnFw
+KCIiLCIiLCIiLEMuRHgpfSwKWWY6ZnVuY3Rpb24oYSl7dmFyIHMscixxLHAsbyxuLG0sbCxrPUguaChh
+LnEoMCwicmVnaW9ucyIpKSxqPUguaChhLnEoMCwibmF2aWdhdGlvbkNvbnRlbnQiKSksaT1ILmgoYS5x
+KDAsInNvdXJjZUNvZGUiKSksaD1QLkZsKHQuWCx0LmRfKQpmb3Iocz10LnQuYShhLnEoMCwiZWRpdHMi
+KSkscz1zLmdQdShzKSxzPXMuZ20ocykscj10LlUscT10Lmg0O3MuRigpOyl7cD1zLmdsKCkKbz1wLmEK
+bj1ILlZNKFtdLHEpCmZvcihwPUouSVQoci5hKHAuYikpO3AuRigpOyl7bT1wLmdsKCkKbD1KLlU2KG0p
+Cm4ucHVzaChuZXcgQi5qOChILnVQKGwucShtLCJsaW5lIikpLEguaChsLnEobSwiZXhwbGFuYXRpb24i
+KSksSC51UChsLnEobSwib2Zmc2V0IikpKSl9aC5ZNSgwLG8sbil9cmV0dXJuIG5ldyBCLnFwKGssaixp
+LGgpfSwKajg6ZnVuY3Rpb24gajgoYSxiLGMpe3RoaXMuYT1hCnRoaXMuYj1iCnRoaXMuYz1jfSwKcXA6
+ZnVuY3Rpb24gcXAoYSxiLGMsZCl7dmFyIF89dGhpcwpfLmE9YQpfLmI9YgpfLmM9YwpfLmQ9ZH0sCmZ2
+OmZ1bmN0aW9uIGZ2KCl7fSwKT1M6ZnVuY3Rpb24oYSl7dmFyIHMKaWYoIShhPj02NSYmYTw9OTApKXM9
+YT49OTcmJmE8PTEyMgplbHNlIHM9ITAKcmV0dXJuIHN9LApZdTpmdW5jdGlvbihhLGIpe3ZhciBzPWEu
+bGVuZ3RoLHI9YisyCmlmKHM8cilyZXR1cm4hMQppZighQi5PUyhDLnhCLk8yKGEsYikpKXJldHVybiEx
+CmlmKEMueEIuTzIoYSxiKzEpIT09NTgpcmV0dXJuITEKaWYocz09PXIpcmV0dXJuITAKcmV0dXJuIEMu
+eEIuTzIoYSxyKT09PTQ3fX0sVD17bVE6ZnVuY3Rpb24gbVEoKXt9fSxMPXsKSXE6ZnVuY3Rpb24oKXtD
+LkJaLkIoZG9jdW1lbnQsIkRPTUNvbnRlbnRMb2FkZWQiLG5ldyBMLmUoKSkKQy5vbC5CKHdpbmRvdywi
+cG9wc3RhdGUiLG5ldyBMLkwoKSl9LAprejpmdW5jdGlvbihhKXt2YXIgcyxyPXQuZy5hKGEucGFyZW50
+Tm9kZSkucXVlcnlTZWxlY3RvcigiOnNjb3BlID4gdWwiKSxxPXIuc3R5bGUscD0iIitDLkNELnpRKHIu
+b2Zmc2V0SGVpZ2h0KSoyKyJweCIKcS5tYXhIZWlnaHQ9cApxPUoucUYoYSkKcD1xLiR0aQpzPXAuQygi
+figxKT8iKS5hKG5ldyBMLld4KHIsYSkpCnQuWi5hKG51bGwpClcuSkUocS5hLHEuYixzLCExLHAuYyl9
+LAp5WDpmdW5jdGlvbihhLGIpe3ZhciBzLHIscSxwLG8sbixtPSJxdWVyeVNlbGVjdG9yQWxsIixsPWRv
+Y3VtZW50LnF1ZXJ5U2VsZWN0b3IoYSksaz10LmcKbC50b1N0cmluZwpzPXQuaApILkRoKGsscywiVCIs
+bSkKcj10LlIKcT1uZXcgVy53eihsLnF1ZXJ5U2VsZWN0b3JBbGwoIi5uYXYtbGluayIpLHIpCnEuSyhx
+LG5ldyBMLkFPKGIpKQpILkRoKGsscywiVCIsbSkKcD1uZXcgVy53eihsLnF1ZXJ5U2VsZWN0b3JBbGwo
+Ii5yZWdpb24iKSxyKQppZighcC5nbDAocCkpe289bC5xdWVyeVNlbGVjdG9yKCJ0YWJsZVtkYXRhLXBh
+dGhdIikKby50b1N0cmluZwpwLksocCxuZXcgTC5IbyhvLmdldEF0dHJpYnV0ZSgiZGF0YS0iK25ldyBX
+LlN5KG5ldyBXLmk3KG8pKS5QKCJwYXRoIikpKSl9SC5EaChrLHMsIlQiLG0pCm49bmV3IFcud3oobC5x
+dWVyeVNlbGVjdG9yQWxsKCIuYWRkLWhpbnQtbGluayIpLHIpCm4uSyhuLG5ldyBMLklDKCkpfSwKUTY6
+ZnVuY3Rpb24oYSxiLGMpe3ZhciBzPW5ldyBYTUxIdHRwUmVxdWVzdCgpCkMuRHQuZW8ocywiR0VUIixM
+LlE0KGEsYiksITApCnMuc2V0UmVxdWVzdEhlYWRlcigiQ29udGVudC1UeXBlIiwiYXBwbGljYXRpb24v
+anNvbjsgY2hhcnNldD1VVEYtOCIpCnJldHVybiBMLkxVKHMsbnVsbCxjLkMoIjAqIikpfSwKdHk6ZnVu
+Y3Rpb24oYSxiKXt2YXIgcz1uZXcgWE1MSHR0cFJlcXVlc3QoKSxyPXQuWApDLkR0LmVvKHMsIlBPU1Qi
+LEwuUTQoYSxQLkZsKHIscikpLCEwKQpzLnNldFJlcXVlc3RIZWFkZXIoIkNvbnRlbnQtVHlwZSIsImFw
+cGxpY2F0aW9uL2pzb247IGNoYXJzZXQ9VVRGLTgiKQpyZXR1cm4gTC5MVShzLGIsdC50KX0sCkxVOmZ1
+bmN0aW9uKGEsYixjKXtyZXR1cm4gTC5UZyhhLGIsYyxjLkMoIjAqIikpfSwKVGc6ZnVuY3Rpb24oYSxi
+LGMsZCl7dmFyIHM9MCxyPVAuRlgoZCkscSxwPTIsbyxuPVtdLG0sbCxrLGosaSxoLGcsZgp2YXIgJGFz
+eW5jJExVPVAubHooZnVuY3Rpb24oZSxhMCl7aWYoZT09PTEpe289YTAKcz1wfXdoaWxlKHRydWUpc3dp
+dGNoKHMpe2Nhc2UgMDppPW5ldyBQLlpmKG5ldyBQLnZzKCQuWDMsdC5nViksdC5iQykKaD10LmViCmc9
+aC5hKG5ldyBMLmZDKGksYSkpCnQuWi5hKG51bGwpCmw9dC5lUQpXLkpFKGEsImxvYWQiLGcsITEsbCkK
+Vy5KRShhLCJlcnJvciIsaC5hKGkuZ1lKKCkpLCExLGwpCmEuc2VuZChiPT1udWxsP251bGw6Qy5DdC5P
+QihiLG51bGwpKQpwPTQKcz03CnJldHVybiBQLmpRKGkuYSwkYXN5bmMkTFUpCmNhc2UgNzpwPTIKcz02
+CmJyZWFrCmNhc2UgNDpwPTMKZj1vCkguUnUoZikKbT1ILnRzKGYpCmg9UC5UbCgiRXJyb3IgcmVhY2hp
+bmcgbWlncmF0aW9uIHByZXZpZXcgc2VydmVyLiIsbSkKdGhyb3cgSC5iKGgpCnM9NgpicmVhawpjYXNl
+IDM6cz0yCmJyZWFrCmNhc2UgNjpqPUMuQ3QucFcoMCxhLnJlc3BvbnNlVGV4dCxudWxsKQppZihhLnN0
+YXR1cz09PTIwMCl7cT1jLkMoIjAqIikuYShqKQpzPTEKYnJlYWt9ZWxzZSB0aHJvdyBILmIoaikKY2Fz
+ZSAxOnJldHVybiBQLnlDKHEscikKY2FzZSAyOnJldHVybiBQLmYzKG8scil9fSkKcmV0dXJuIFAuREko
+JGFzeW5jJExVLHIpfSwKYUs6ZnVuY3Rpb24oYSl7dmFyIHM9UC5oSyhhKS5naFkoKS5xKDAsImxpbmUi
+KQpyZXR1cm4gcz09bnVsbD9udWxsOkguSHAocyxudWxsKX0sCkc2OmZ1bmN0aW9uKGEpe3ZhciBzPVAu
+aEsoYSkuZ2hZKCkucSgwLCJvZmZzZXQiKQpyZXR1cm4gcz09bnVsbD9udWxsOkguSHAocyxudWxsKX0s
+Cmk2OmZ1bmN0aW9uKGEpe3JldHVybiBMLm5XKHQuTy5hKGEpKX0sCm5XOmZ1bmN0aW9uKGEpe3ZhciBz
+PTAscj1QLkZYKHQueikscT0xLHAsbz1bXSxuLG0sbCxrLGosaSxoCnZhciAkYXN5bmMkaTY9UC5seihm
+dW5jdGlvbihiLGMpe2lmKGI9PT0xKXtwPWMKcz1xfXdoaWxlKHRydWUpc3dpdGNoKHMpe2Nhc2UgMDpp
+PXQuZy5hKFcucWMoYS5jdXJyZW50VGFyZ2V0KSkuZ2V0QXR0cmlidXRlKCJocmVmIikKYS5wcmV2ZW50
+RGVmYXVsdCgpCnE9MwprPWRvY3VtZW50Cm49Qy5DRC56UShrLnF1ZXJ5U2VsZWN0b3IoIi5jb250ZW50
+Iikuc2Nyb2xsVG9wKQpzPTYKcmV0dXJuIFAualEoTC50eShpLG51bGwpLCRhc3luYyRpNikKY2FzZSA2
+OnM9NwpyZXR1cm4gUC5qUShMLkc3KHdpbmRvdy5sb2NhdGlvbi5wYXRobmFtZSxudWxsLG51bGwsITEs
+bnVsbCksJGFzeW5jJGk2KQpjYXNlIDc6az1rLnF1ZXJ5U2VsZWN0b3IoIi5jb250ZW50IikKay50b1N0
+cmluZwprLnNjcm9sbFRvcD1KLlZ1KG4pCnE9MQpzPTUKYnJlYWsKY2FzZSAzOnE9MgpoPXAKbT1ILlJ1
+KGgpCmw9SC50cyhoKQpMLkMyKCJDb3VsZCBub3QgYWRkL3JlbW92ZSBoaW50IixtLGwpCnM9NQpicmVh
+awpjYXNlIDI6cz0xCmJyZWFrCmNhc2UgNTpyZXR1cm4gUC55QyhudWxsLHIpCmNhc2UgMTpyZXR1cm4g
+UC5mMyhwLHIpfX0pCnJldHVybiBQLkRJKCRhc3luYyRpNixyKX0sCkMyOmZ1bmN0aW9uKGEsYixjKXt2
+YXIgcyxyLHEscD0iZXhjZXB0aW9uIixvPSJzdGFja1RyYWNlIixuPXQudC5iKGIpJiZKLlJNKGIucSgw
+LCJzdWNjZXNzIiksITEpJiZiLng0KHApJiZiLng0KG8pLG09Si5pYShiKQppZihuKXtzPUguaChtLnEo
+YixwKSkKYz1tLnEoYixvKX1lbHNlIHM9bS53KGIpCm49ZG9jdW1lbnQKcj1uLnF1ZXJ5U2VsZWN0b3Io
+Ii5wb3B1cC1wYW5lIikKci5xdWVyeVNlbGVjdG9yKCJoMiIpLmlubmVyVGV4dD1hCnIucXVlcnlTZWxl
+Y3RvcigicCIpLmlubmVyVGV4dD1zCnIucXVlcnlTZWxlY3RvcigicHJlIikuaW5uZXJUZXh0PUouaihj
+KQpxPXQuZGQuYShyLnF1ZXJ5U2VsZWN0b3IoImEuYm90dG9tIikpCm09dC5YOyhxJiZDLnhuKS5zTFUo
+cSxQLlhkKCJodHRwcyIsImdpdGh1Yi5jb20iLCJkYXJ0LWxhbmcvc2RrL2lzc3Vlcy9uZXciLFAuRUYo
+WyJ0aXRsZSIsIkN1c3RvbWVyLXJlcG9ydGVkIGlzc3VlIHdpdGggTk5CRCBtaWdyYXRpb24gdG9vbDog
+IithLCJsYWJlbHMiLHUuZCwiYm9keSIsYSsiXG5cbkVycm9yOiAiK0guRWoocykrIlxuXG5QbGVhc2Ug
+ZmlsbCBpbiB0aGUgZm9sbG93aW5nOlxuXG4qKk5hbWUgb2YgcGFja2FnZSBiZWluZyBtaWdyYXRlZCAo
+aWYgcHVibGljKSoqOlxuKipXaGF0IEkgd2FzIGRvaW5nIHdoZW4gdGhpcyBpc3N1ZSBvY2N1cnJlZCoq
+OlxuKipJcyBpdCBwb3NzaWJsZSB0byB3b3JrIGFyb3VuZCB0aGlzIGlzc3VlKio6XG4qKkhhcyB0aGlz
+IGlzc3VlIGhhcHBlbmVkIGJlZm9yZSwgYW5kIGlmIHNvLCBob3cgb2Z0ZW4qKjpcbioqRGFydCBTREsg
+dmVyc2lvbioqOiAiK0guRWoobi5nZXRFbGVtZW50QnlJZCgic2RrLXZlcnNpb24iKS50ZXh0Q29udGVu
+dCkrIlxuKipBZGRpdGlvbmFsIGRldGFpbHMqKjpcblxuVGhhbmtzIGZvciBmaWxpbmchXG5cblN0YWNr
+dHJhY2U6IF9hdXRvIHBvcHVsYXRlZCBieSBtaWdyYXRpb24gcHJldmlldyB0b29sLl9cblxuYGBgXG4i
+K0guRWooYykrIlxuYGBgXG4iXSxtLG0pKS5nbkQoKSkKbT1xLnN0eWxlCm0uZGlzcGxheT0iaW5pdGlh
+bCIKbj1yLnN0eWxlCm4uZGlzcGxheT0iaW5pdGlhbCIKbj1hKyI6ICIrSC5FaihiKQp3aW5kb3cKaWYo
+dHlwZW9mIGNvbnNvbGUhPSJ1bmRlZmluZWQiKXdpbmRvdy5jb25zb2xlLmVycm9yKG4pCndpbmRvdwpu
+PUguRWooYykKaWYodHlwZW9mIGNvbnNvbGUhPSJ1bmRlZmluZWQiKXdpbmRvdy5jb25zb2xlLmVycm9y
+KG4pfSwKdDI6ZnVuY3Rpb24oYSxiLGMpe3ZhciBzLHIscSxwLG89dC5nLmEoVy5xYyhhLmN1cnJlbnRU
+YXJnZXQpKQphLnByZXZlbnREZWZhdWx0KCkKcz1vLmdldEF0dHJpYnV0ZSgiaHJlZiIpCnI9TC5Vcyhz
+KQpxPUwuRzYocykKcD1MLmFLKHMpCmlmKHEhPW51bGwpTC5hZihyLHEscCxiLG5ldyBMLm5UKHIscSxw
+KSkKZWxzZSBMLmFmKHIsbnVsbCxudWxsLGIsbmV3IEwuTlkocikpfSwKSzA6ZnVuY3Rpb24oYSl7dmFy
+IHMscixxLHA9ZG9jdW1lbnQucXVlcnlTZWxlY3RvcigiLnBvcHVwLXBhbmUiKQpwLnF1ZXJ5U2VsZWN0
+b3IoImgyIikuaW5uZXJUZXh0PSJGYWlsZWQgdG8gcmVydW4gZnJvbSBzb3VyY2VzIgpwLnF1ZXJ5U2Vs
+ZWN0b3IoInAiKS5pbm5lclRleHQ9IlNvdXJjZXMgY29udGFpbiBzdGF0aWMgYW5hbHlzaXMgZXJyb3Jz
+OiIKcz1wLnF1ZXJ5U2VsZWN0b3IoInByZSIpCnI9Si5FbChhLHQuYXcpCnE9SC5MaChyKQpzLmlubmVy
+VGV4dD1uZXcgSC5sSihyLHEuQygicVUqKGxELkUpIikuYShuZXcgTC51ZSgpKSxxLkMoImxKPGxELkUs
+cVUqPiIpKS5rKDAsIlxuIikKcT1wLnF1ZXJ5U2VsZWN0b3IoImEuYm90dG9tIikuc3R5bGUKcS5kaXNw
+bGF5PSJub25lIgpzPXAuc3R5bGUKcy5kaXNwbGF5PSJpbml0aWFsIn0sCnZVOmZ1bmN0aW9uKCl7dmFy
+IHM9ZG9jdW1lbnQKSC5EaCh0LmcsdC5oLCJUIiwicXVlcnlTZWxlY3RvckFsbCIpCnM9bmV3IFcud3oo
+cy5xdWVyeVNlbGVjdG9yQWxsKCIuY29kZSIpLHQuUikKcy5LKHMsbmV3IEwuZVgoKSl9LApoWDpmdW5j
+dGlvbihhLGIsYyl7cmV0dXJuIEwuWXcoYSxiLGMpfSwKWXc6ZnVuY3Rpb24oYSxiLGMpe3ZhciBzPTAs
+cj1QLkZYKHQueikscT0xLHAsbz1bXSxuLG0sbCxrLGosaSxoLGcKdmFyICRhc3luYyRoWD1QLmx6KGZ1
+bmN0aW9uKGQsZSl7aWYoZD09PTEpe3A9ZQpzPXF9d2hpbGUodHJ1ZSlzd2l0Y2gocyl7Y2FzZSAwOnE9
+MwpqPXQuWApzPTYKcmV0dXJuIFAualEoTC5RNihhLFAuRUYoWyJyZWdpb24iLCJyZWdpb24iLCJvZmZz
+ZXQiLEguRWooYildLGosaiksdC50KSwkYXN5bmMkaFgpCmNhc2UgNjpuPWUKaj1uCmk9Si5VNihqKQpt
+PW5ldyBVLmQyKFUuamYoaS5xKGosImVkaXRzIikpLEguaChpLnEoaiwiZXhwbGFuYXRpb24iKSksSC51
+UChpLnEoaiwibGluZSIpKSxILmgoaS5xKGosImRpc3BsYXlQYXRoIikpLEguaChpLnEoaiwidXJpUGF0
+aCIpKSxVLk5kKGkucShqLCJ0cmFjZXMiKSkpCkwuVDEobSkKTC5GcihhLGIsYykKTC55WCgiLmVkaXQt
+cGFuZWwgLnBhbmVsLWNvbnRlbnQiLCExKQpxPTEKcz01CmJyZWFrCmNhc2UgMzpxPTIKZz1wCmw9SC5S
+dShnKQprPUgudHMoZykKTC5DMigiQ291bGQgbm90IGxvYWQgZWRpdCBkZXRhaWxzIixsLGspCnM9NQpi
+cmVhawpjYXNlIDI6cz0xCmJyZWFrCmNhc2UgNTpyZXR1cm4gUC55QyhudWxsLHIpCmNhc2UgMTpyZXR1
+cm4gUC5mMyhwLHIpfX0pCnJldHVybiBQLkRJKCRhc3luYyRoWCxyKX0sCkc3OmZ1bmN0aW9uKGEsYixj
+LGQsZSl7cmV0dXJuIEwuTDUoYSxiLGMsZCxlKX0sCkw1OmZ1bmN0aW9uKGEsYixjLGQsZSl7dmFyIHM9
+MCxyPVAuRlgodC5IKSxxLHA9MixvLG49W10sbSxsLGssaixpLGgsZwp2YXIgJGFzeW5jJEc3PVAubHoo
+ZnVuY3Rpb24oZixhMCl7aWYoZj09PTEpe289YTAKcz1wfXdoaWxlKHRydWUpc3dpdGNoKHMpe2Nhc2Ug
+MDppZighSi5wNChhLCIuZGFydCIpKXtMLkJFKGEsQi53UigpLGQpCkwuQlgoYSxudWxsKQppZihlIT1u
+dWxsKWUuJDAoKQpzPTEKYnJlYWt9cD00Cmk9dC5YCnM9NwpyZXR1cm4gUC5qUShMLlE2KGEsUC5FRihb
+ImlubGluZSIsInRydWUiXSxpLGkpLHQudCksJGFzeW5jJEc3KQpjYXNlIDc6bT1hMApMLkJFKGEsQi5Z
+ZihtKSxkKQpMLmZHKGIsYykKbD1MLlVzKGEpCkwuQlgobCxiKQppZihlIT1udWxsKWUuJDAoKQpwPTIK
+cz02CmJyZWFrCmNhc2UgNDpwPTMKZz1vCms9SC5SdShnKQpqPUgudHMoZykKTC5DMigiQ291bGQgbm90
+IGxvYWQgZGFydCBmaWxlICIrYSxrLGopCnM9NgpicmVhawpjYXNlIDM6cz0yCmJyZWFrCmNhc2UgNjpj
+YXNlIDE6cmV0dXJuIFAueUMocSxyKQpjYXNlIDI6cmV0dXJuIFAuZjMobyxyKX19KQpyZXR1cm4gUC5E
+SSgkYXN5bmMkRzcscil9LApHZTpmdW5jdGlvbigpe3ZhciBzPTAscj1QLkZYKHQueikscT0xLHAsbz1b
+XSxuLG0sbCxrLGosaSxoLGcKdmFyICRhc3luYyRHZT1QLmx6KGZ1bmN0aW9uKGEsYil7aWYoYT09PTEp
+e3A9YgpzPXF9d2hpbGUodHJ1ZSlzd2l0Y2gocyl7Y2FzZSAwOmg9Ii9fcHJldmlldy9uYXZpZ2F0aW9u
+VHJlZS5qc29uIgpxPTMKcz02CnJldHVybiBQLmpRKEwuUTYoaCxDLkNNLHQubSksJGFzeW5jJEdlKQpj
+YXNlIDY6bj1iCm09ZG9jdW1lbnQucXVlcnlTZWxlY3RvcigiLm5hdi10cmVlIikKSi5sNShtLCIiKQpq
+PUwubUsobikKJC5JUj1qCkwudFgobSxqLCExKQpxPTEKcz01CmJyZWFrCmNhc2UgMzpxPTIKZz1wCmw9
+SC5SdShnKQprPUgudHMoZykKTC5DMigiQ291bGQgbm90IGxvYWQgbmF2aWdhdGlvbiB0cmVlIixsLGsp
+CnM9NQpicmVhawpjYXNlIDI6cz0xCmJyZWFrCmNhc2UgNTpyZXR1cm4gUC55QyhudWxsLHIpCmNhc2Ug
+MTpyZXR1cm4gUC5mMyhwLHIpfX0pCnJldHVybiBQLkRJKCRhc3luYyRHZSxyKX0sCnFPOmZ1bmN0aW9u
+KGEpe3ZhciBzLHI9YS5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKSxxPUMuQ0QuelEoJC5maSgpLm9mZnNl
+dEhlaWdodCkscD13aW5kb3cuaW5uZXJIZWlnaHQsbz1DLkNELnpRKCQuRFcoKS5vZmZzZXRIZWlnaHQp
+CmlmKHR5cGVvZiBwIT09Im51bWJlciIpcmV0dXJuIHAuSE4oKQpzPXIuYm90dG9tCnMudG9TdHJpbmcK
+aWYocz5wLShvKzE0KSlKLmRoKGEpCmVsc2V7cD1yLnRvcApwLnRvU3RyaW5nCmlmKHA8cSsxNClKLmRo
+KGEpfX0sCmZHOmZ1bmN0aW9uKGEsYil7dmFyIHMscixxLHAsbwppZihhIT1udWxsKXtzPWRvY3VtZW50
+CnI9cy5nZXRFbGVtZW50QnlJZCgibyIrSC5FaihhKSkKcT1zLnF1ZXJ5U2VsZWN0b3IoIi5saW5lLSIr
+SC5FaihiKSkKaWYociE9bnVsbCl7TC5xTyhyKQpKLmRSKHIpLmkoMCwidGFyZ2V0Iil9ZWxzZSBpZihx
+IT1udWxsKUwucU8ocS5wYXJlbnRFbGVtZW50KQppZihxIT1udWxsKUouZFIodC5nLmEocS5wYXJlbnRO
+b2RlKSkuaSgwLCJoaWdobGlnaHQiKX1lbHNle3M9ZG9jdW1lbnQKcD10LmcKSC5EaChwLHQuaCwiVCIs
+InF1ZXJ5U2VsZWN0b3JBbGwiKQpzPXMucXVlcnlTZWxlY3RvckFsbCgiLmxpbmUtbm8iKQpvPW5ldyBX
+Lnd6KHMsdC5SKQppZihvLmdBKG8pPT09MClyZXR1cm4KTC5xTyhwLmEoQy50NS5ndEgocykpKX19LAph
+ZjpmdW5jdGlvbihhLGIsYyxkLGUpe3ZhciBzLHIscT1MLkc2KHdpbmRvdy5sb2NhdGlvbi5ocmVmKSxw
+PUwuYUsod2luZG93LmxvY2F0aW9uLmhyZWYpCmlmKHEhPW51bGwpe3M9ZG9jdW1lbnQuZ2V0RWxlbWVu
+dEJ5SWQoIm8iK0guRWoocSkpCmlmKHMhPW51bGwpSi5kUihzKS5MKDAsInRhcmdldCIpfWlmKHAhPW51
+bGwpe3I9ZG9jdW1lbnQucXVlcnlTZWxlY3RvcigiLmxpbmUtIitILkVqKHApKQppZihyIT1udWxsKUou
+ZFIoci5wYXJlbnRFbGVtZW50KS5MKDAsImhpZ2hsaWdodCIpfWlmKGE9PXdpbmRvdy5sb2NhdGlvbi5w
+YXRobmFtZSl7TC5mRyhiLGMpCmUuJDAoKX1lbHNlIEwuRzcoYSxiLGMsZCxlKX0sClE0OmZ1bmN0aW9u
+KGEsYil7dmFyIHMscixxPVAuaEsoYSkscD10LlgKcD1QLkZsKHAscCkKZm9yKHM9cS5naFkoKSxzPXMu
+Z1B1KHMpLHM9cy5nbShzKTtzLkYoKTspe3I9cy5nbCgpCnAuWTUoMCxyLmEsci5iKX1mb3Iocz1iLmdQ
+dShiKSxzPXMuZ20ocyk7cy5GKCk7KXtyPXMuZ2woKQpwLlk1KDAsci5hLHIuYil9cC5ZNSgwLCJhdXRo
+VG9rZW4iLCQuVUUoKSkKcmV0dXJuIHEubm0oMCxwKS5nbkQoKX0sClQxOmZ1bmN0aW9uKGEpe3ZhciBz
+LHIscSxwLG8sbixtLGwsayxqPSQuaEwoKQpKLmw1KGosIiIpCmlmKGE9PW51bGwpe3M9ZG9jdW1lbnQu
+Y3JlYXRlRWxlbWVudCgicCIpCkMuTHQuc2E0KHMsIlNlZSBkZXRhaWxzIGFib3V0IGEgcHJvcG9zZWQg
+ZWRpdC4iKQpDLkx0LnNuKHMsSC5WTShbInBsYWNlaG9sZGVyIl0sdC5pKSkKai5hcHBlbmRDaGlsZChz
+KQpDLkx0LkZGKHMpCnJldHVybn1yPWEuZApxPSQublUoKQpwPXEuemYocikKbz1hLmIKbj1kb2N1bWVu
+dAptPXEuSFAocixKLlQwKG4ucXVlcnlTZWxlY3RvcigiLnJvb3QiKS50ZXh0Q29udGVudCkpCmw9YS5j
+Cms9bi5jcmVhdGVFbGVtZW50KCJwIikKai5hcHBlbmRDaGlsZChrKQprLmFwcGVuZENoaWxkKG4uY3Jl
+YXRlVGV4dE5vZGUoSC5FaihvKSsiIGF0ICIpKQpxPXQuWApxPVcuSjYoTC5RNChhLmUsUC5FRihbImxp
+bmUiLEouaihsKV0scSxxKSkpCnEuYXBwZW5kQ2hpbGQobi5jcmVhdGVUZXh0Tm9kZShILkVqKG0pKyI6
+IitILkVqKGwpKyIuIikpCmsuYXBwZW5kQ2hpbGQocSkKSi5kaChrKQpMLkNDKGEsaixwKQpMLkZ6KGEs
+ail9LApMSDpmdW5jdGlvbihhLGIsYyl7dmFyIHMscixxLHAsbyxuLG0sbCxrLGosaSxoLGcsZixlPSQu
+eVAoKQpKLmw1KGUsIiIpCmlmKGIuZ0EoYik9PT0wKXtzPWRvY3VtZW50CnI9cy5jcmVhdGVFbGVtZW50
+KCJwIikKZS5hcHBlbmRDaGlsZChyKQpyLmFwcGVuZENoaWxkKHMuY3JlYXRlVGV4dE5vZGUoIk5vIHBy
+b3Bvc2VkIGVkaXRzIikpfWVsc2UgZm9yKGU9Yi5nUHUoYiksZT1lLmdtKGUpLHM9dC5YLHE9dC5rLHA9
+cS5DKCJ+KDEpPyIpLG89dC5aLHE9cS5jO2UuRigpOyl7bj1lLmdsKCkKbT1kb2N1bWVudApyPW0uY3Jl
+YXRlRWxlbWVudCgicCIpCmw9JC55UCgpCmwuYXBwZW5kQ2hpbGQocikKci5hcHBlbmRDaGlsZChtLmNy
+ZWF0ZVRleHROb2RlKEguRWoobi5hKSsiOiIpKQprPW0uY3JlYXRlRWxlbWVudCgidWwiKQpsLmFwcGVu
+ZENoaWxkKGspCmZvcihuPUouSVQobi5iKTtuLkYoKTspe2w9bi5nbCgpCmo9bS5jcmVhdGVFbGVtZW50
+KCJsaSIpCmsuYXBwZW5kQ2hpbGQoaikKSi5kUihqKS5pKDAsImVkaXQiKQppPW0uY3JlYXRlRWxlbWVu
+dCgiYSIpCmouYXBwZW5kQ2hpbGQoaSkKaS5jbGFzc0xpc3QuYWRkKCJlZGl0LWxpbmsiKQpoPWwuYwpn
+PUguRWooaCkKaS5zZXRBdHRyaWJ1dGUoImRhdGEtIituZXcgVy5TeShuZXcgVy5pNyhpKSkuUCgib2Zm
+c2V0IiksZykKZj1sLmEKZz1ILkVqKGYpCmkuc2V0QXR0cmlidXRlKCJkYXRhLSIrbmV3IFcuU3kobmV3
+IFcuaTcoaSkpLlAoImxpbmUiKSxnKQppLmFwcGVuZENoaWxkKG0uY3JlYXRlVGV4dE5vZGUoImxpbmUg
+IitILkVqKGYpKSkKaS5zZXRBdHRyaWJ1dGUoImhyZWYiLEwuUTQod2luZG93LmxvY2F0aW9uLnBhdGhu
+YW1lLFAuRUYoWyJsaW5lIixILkVqKGYpLCJvZmZzZXQiLEguRWooaCldLHMscykpKQpnPXAuYShuZXcg
+TC5FRShoLGYsYSkpCm8uYShudWxsKQpXLkpFKGksImNsaWNrIixnLCExLHEpCmouYXBwZW5kQ2hpbGQo
+bS5jcmVhdGVUZXh0Tm9kZSgiOiAiK0guRWoobC5iKSkpfX1pZihjKUwuVDEobnVsbCl9LApGcjpmdW5j
+dGlvbihhLGIsYyl7dmFyIHMscixxPXdpbmRvdy5sb2NhdGlvbixwPVAuaEsoKHEmJkMuRXgpLmdEcihx
+KStILkVqKGEpKQpxPXQuWApxPVAuRmwocSxxKQppZihiIT1udWxsKXEuWTUoMCwib2Zmc2V0IixILkVq
+KGIpKQppZihjIT1udWxsKXEuWTUoMCwibGluZSIsSC5FaihjKSkKcS5ZNSgwLCJhdXRoVG9rZW4iLCQu
+VUUoKSkKcD1wLm5tKDAscSkKcT13aW5kb3cuaGlzdG9yeQpzPXQuegpyPXAuZ25EKCkKcS50b1N0cmlu
+ZwpxLnB1c2hTdGF0ZShuZXcgUC5CZihbXSxbXSkuUHYoUC5GbChzLHMpKSwiIixyKX0sCkVuOmZ1bmN0
+aW9uKGEpe3ZhciBzPUouYmIoZG9jdW1lbnQucXVlcnlTZWxlY3RvcigiLnJvb3QiKS50ZXh0Q29udGVu
+dCwiLyIpCmlmKEMueEIubkMoYSxzKSlyZXR1cm4gQy54Qi55bihhLHMubGVuZ3RoKQplbHNlIHJldHVy
+biBhfSwKT3Q6ZnVuY3Rpb24oYSl7c3dpdGNoKGEucil7Y2FzZSBDLmN3OmJyZWFrCmNhc2UgQy5XRDph
+LnI9Qy5YagpicmVhawpjYXNlIEMuWGo6YS5yPUMuV0QKYnJlYWsKY2FzZSBDLmRjOnRocm93IEguYihQ
+LlBWKCJGaWxlICIrSC5FaihhLmMpKyIgc2hvdWxkIG5vdCBoYXZlIGluZGV0ZXJtaW5hdGUgbWlncmF0
+aW9uIHN0YXR1cyIpKX19LAp4bjpmdW5jdGlvbihhLGIpe0wudGEoYSxiLmdkNigpKQppZihiLmM9PSQu
+RDkoKS5pbm5lclRleHQpTC50YSgkLmMwKCksYi5nZDYoKSl9LAp0YTpmdW5jdGlvbihhLGIpe3ZhciBz
+LHI9ImNoZWNrX2JveCIscT0idGl0bGUiLHA9Im9wdGVkLW91dCIsbz0ibWlncmF0aW5nIgpzd2l0Y2go
+Yil7Y2FzZSBDLmN3OmEuaW5uZXJUZXh0PXIKSi5kUihhKS5pKDAsImFscmVhZHktbWlncmF0ZWQiKQph
+LnNldEF0dHJpYnV0ZShxLCJBbHJlYWR5IG1pZ3JhdGVkIikKYnJlYWsKY2FzZSBDLldEOmEuaW5uZXJU
+ZXh0PXIKcz1KLllFKGEpCnMuZ24oYSkuTCgwLHApCnMuZ24oYSkuaSgwLG8pCmEuc2V0QXR0cmlidXRl
+KHEsIk1pZ3JhdGluZyB0byBudWxsIHNhZmV0eSIpCmJyZWFrCmNhc2UgQy5YajphLmlubmVyVGV4dD0i
+Y2hlY2tfYm94X291dGxpbmVfYmxhbmsiCnM9Si5ZRShhKQpzLmduKGEpLkwoMCxvKQpzLmduKGEpLmko
+MCxwKQphLnNldEF0dHJpYnV0ZShxLCJPcHRpbmcgb3V0IG9mIG51bGwgc2FmZXR5IikKYnJlYWsKZGVm
+YXVsdDphLmlubmVyVGV4dD0iaW5kZXRlcm1pbmF0ZV9jaGVja19ib3giCnM9Si5ZRShhKQpzLmduKGEp
+LkwoMCxvKQpzLmduKGEpLmkoMCxwKQphLnNldEF0dHJpYnV0ZShxLCJNaXhlZCBzdGF0dXNlcyBvZiAn
+bWlncmF0aW5nJyBhbmQgJ29wdGluZyBvdXQnIikKYnJlYWt9fSwKQlg6ZnVuY3Rpb24oYSxiKXt2YXIg
+cyxyPXt9CnIuYT1hCmE9TC5FbihhKQpyLmE9YQpKLmRyKCQuRDkoKSxhKQpzPWRvY3VtZW50CkguRGgo
+dC5nLHQuaCwiVCIsInF1ZXJ5U2VsZWN0b3JBbGwiKQpzPW5ldyBXLnd6KHMucXVlcnlTZWxlY3RvckFs
+bCgiLm5hdi1wYW5lbCAubmF2LWxpbmsiKSx0LlIpCnMuSyhzLG5ldyBMLlZTKHIpKQpKLmRSKCQuYk4o
+KSkuaSgwLCJ2aXNpYmxlIil9LApBUjpmdW5jdGlvbihhLGIpe3ZhciBzLHIscT1iLmIKaWYocSE9bnVs
+bCl7cz10LmcKcj1zLmEocy5hKGEucGFyZW50Tm9kZSkucGFyZW50Tm9kZSkKTC54bihyLnF1ZXJ5U2Vs
+ZWN0b3IoIjpzY29wZSA+IC5zdGF0dXMtaWNvbiIpLHEpCkwuQVIocixxKX19LApCRTpmdW5jdGlvbihh
+LGIsYyl7dmFyIHM9Ii5yZWdpb25zIixyPWRvY3VtZW50LHE9ci5xdWVyeVNlbGVjdG9yKHMpLHA9ci5x
+dWVyeVNlbGVjdG9yKCIuY29kZSIpCkoudEgocSxiLmEsJC5LRygpKQpKLnRIKHAsYi5iLCQuS0coKSkK
+TC5MSChhLGIuZCxjKQppZihiLmMubGVuZ3RoPDJlNSlMLnZVKCkKTC55WCgiLmNvZGUiLCEwKQpMLnlY
+KHMsITApfSwKdFg6ZnVuY3Rpb24oYSxiLGEwKXt2YXIgcyxyLHEscCxvLG4sbSxsLGssaixpLGgsZyxm
+LGU9Im1hdGVyaWFsLWljb25zIixkPWRvY3VtZW50LGM9ZC5jcmVhdGVFbGVtZW50KCJ1bCIpCmEuYXBw
+ZW5kQ2hpbGQoYykKZm9yKHM9Yi5sZW5ndGgscj10LlgscT10LloscD0wO3A8Yi5sZW5ndGg7Yi5sZW5n
+dGg9PT1zfHwoMCxILmxrKShiKSwrK3Ape289YltwXQpuPWQuY3JlYXRlRWxlbWVudCgibGkiKQpjLmFw
+cGVuZENoaWxkKG4pCmlmKG8gaW5zdGFuY2VvZiBMLnZ0KXtKLmRSKG4pLmkoMCwiZGlyIikKbi5zZXRB
+dHRyaWJ1dGUoImRhdGEtIituZXcgVy5TeShuZXcgVy5pNyhuKSkuUCgibmFtZSIpLG8uYykKbT1kLmNy
+ZWF0ZUVsZW1lbnQoInNwYW4iKQpuLmFwcGVuZENoaWxkKG0pCmw9Si5ZRShtKQpsLmduKG0pLmkoMCwi
+YXJyb3ciKQpsLnNoZihtLCImI3gyNUJDOyIpCms9ZC5jcmVhdGVFbGVtZW50KCJzcGFuIikKSi5kUihr
+KS5pKDAsZSkKay5pbm5lclRleHQ9ImZvbGRlcl9vcGVuIgpuLmFwcGVuZENoaWxkKGspCm4uYXBwZW5k
+Q2hpbGQoZC5jcmVhdGVUZXh0Tm9kZShvLmEpKQpMLnRYKG4sby5kLCExKQpMLmt6KG0pfWVsc2UgaWYo
+byBpbnN0YW5jZW9mIEwuY0Qpe2w9ZC5jcmVhdGVFbGVtZW50KCJzcGFuIikKSi5kUihsKS5pKDAsZSkK
+bC5pbm5lclRleHQ9Imluc2VydF9kcml2ZV9maWxlIgpuLmFwcGVuZENoaWxkKGwpCmo9ZC5jcmVhdGVF
+bGVtZW50KCJhIikKbi5hcHBlbmRDaGlsZChqKQpsPUouWUUoaikKbC5nbihqKS5pKDAsIm5hdi1saW5r
+IikKai5zZXRBdHRyaWJ1dGUoImRhdGEtIituZXcgVy5TeShuZXcgVy5pNyhqKSkuUCgibmFtZSIpLG8u
+YykKai5zZXRBdHRyaWJ1dGUoImhyZWYiLEwuUTQoby5kLFAuRmwocixyKSkpCmouYXBwZW5kQ2hpbGQo
+ZC5jcmVhdGVUZXh0Tm9kZShvLmEpKQpsPWwuZ1ZsKGopCmk9bC4kdGkKaD1pLkMoIn4oMSk/IikuYShu
+ZXcgTC5URCgpKQpxLmEobnVsbCkKVy5KRShsLmEsbC5iLGgsITEsaS5jKQpnPW8uZQppZih0eXBlb2Yg
+ZyE9PSJudW1iZXIiKXJldHVybiBnLm9zKCkKaWYoZz4wKXtmPWQuY3JlYXRlRWxlbWVudCgic3BhbiIp
+Cm4uYXBwZW5kQ2hpbGQoZikKSi5kUihmKS5pKDAsImVkaXQtY291bnQiKQpsPSIiK2crIiAiCmlmKGc9
+PT0xKWk9InByb3Bvc2VkIGVkaXQiCmVsc2UgaT0icHJvcG9zZWQgZWRpdHMiCmYuc2V0QXR0cmlidXRl
+KCJ0aXRsZSIsbCtpKQpmLmFwcGVuZENoaWxkKGQuY3JlYXRlVGV4dE5vZGUoQy5qbi53KGcpKSl9fX19
+LAp1ejpmdW5jdGlvbihhLGIsYyl7dmFyIHM9ZG9jdW1lbnQscj1zLmNyZWF0ZUVsZW1lbnQoImJ1dHRv
+biIpLHE9dC5rLHA9cS5DKCJ+KDEpPyIpLmEobmV3IEwubTIoYSxjKSkKdC5aLmEobnVsbCkKVy5KRShy
+LCJjbGljayIscCwhMSxxLmMpCnIuYXBwZW5kQ2hpbGQocy5jcmVhdGVUZXh0Tm9kZShNLk9YKGEuYSkp
+KQpiLmFwcGVuZENoaWxkKHIpfSwKRno6ZnVuY3Rpb24oYSxiKXt2YXIgcyxyLHEscCxvLG4sbSxsLGss
+aixpLGg9YS5hCmlmKGg9PW51bGwpcmV0dXJuCnM9ZG9jdW1lbnQKcj1zLmNyZWF0ZUVsZW1lbnQoInAi
+KQpxPWIuYXBwZW5kQ2hpbGQocikKcj1zLmNyZWF0ZUVsZW1lbnQoInNwYW4iKQpwPXQuaQpKLk11KHIs
+SC5WTShbInR5cGUtZGVzY3JpcHRpb24iXSxwKSkKci5hcHBlbmRDaGlsZChzLmNyZWF0ZVRleHROb2Rl
+KCJBY3Rpb25zIikpCnEuYXBwZW5kQ2hpbGQocikKcS5hcHBlbmRDaGlsZChzLmNyZWF0ZVRleHROb2Rl
+KCI6IikpCm89cy5jcmVhdGVFbGVtZW50KCJwIikKYi5hcHBlbmRDaGlsZChvKQpmb3Iocj1oLmxlbmd0
+aCxuPXQuUSxtPTA7bTxoLmxlbmd0aDtoLmxlbmd0aD09PXJ8fCgwLEgubGspKGgpLCsrbSl7bD1oW21d
+Cms9cy5jcmVhdGVFbGVtZW50KCJhIikKby5hcHBlbmRDaGlsZChrKQprLmFwcGVuZENoaWxkKHMuY3Jl
+YXRlVGV4dE5vZGUobC5hKSkKay5zZXRBdHRyaWJ1dGUoImhyZWYiLGwuYikKaj1uLmEoSC5WTShbImFk
+ZC1oaW50LWxpbmsiLCJiZWZvcmUtYXBwbHkiLCJidXR0b24iXSxwKSkKaT1KLmRSKGspCmkuVjEoMCkK
+aS5GVigwLGopfX0sCkNDOmZ1bmN0aW9uKGE0LGE1LGE2KXt2YXIgcyxyLHEscCxvLG4sbSxsLGssaixp
+LGgsZyxmLGUsZCxjLGIsYSxhMCxhMSxhMixhMwpmb3Iocz1hNC5mLHI9cy5sZW5ndGgscT10LmkscD10
+LlEsbz0wO288cy5sZW5ndGg7cy5sZW5ndGg9PT1yfHwoMCxILmxrKShzKSwrK28pe249c1tvXQptPWRv
+Y3VtZW50Cmw9bS5jcmVhdGVFbGVtZW50KCJwIikKaz1wLmEoSC5WTShbInRyYWNlIl0scSkpCmo9Si5k
+UihsKQpqLlYxKDApCmouRlYoMCxrKQppPWE1LmFwcGVuZENoaWxkKGwpCmw9bS5jcmVhdGVFbGVtZW50
+KCJzcGFuIikKaz1wLmEoSC5WTShbInR5cGUtZGVzY3JpcHRpb24iXSxxKSkKaj1KLmRSKGwpCmouVjEo
+MCkKai5GVigwLGspCmwuYXBwZW5kQ2hpbGQobS5jcmVhdGVUZXh0Tm9kZShuLmEpKQppLmFwcGVuZENo
+aWxkKGwpCmkuYXBwZW5kQ2hpbGQobS5jcmVhdGVUZXh0Tm9kZSgiOiIpKQpsPW0uY3JlYXRlRWxlbWVu
+dCgidWwiKQprPXAuYShILlZNKFsidHJhY2UiXSxxKSkKaj1KLmRSKGwpCmouVjEoMCkKai5GVigwLGsp
+Cmg9aS5hcHBlbmRDaGlsZChsKQpmb3IobD1uLmIsaz1sLmxlbmd0aCxnPTA7ZzxsLmxlbmd0aDtsLmxl
+bmd0aD09PWt8fCgwLEgubGspKGwpLCsrZyl7Zj1sW2ddCmU9bS5jcmVhdGVFbGVtZW50KCJsaSIpCmgu
+YXBwZW5kQ2hpbGQoZSkKZD1tLmNyZWF0ZUVsZW1lbnQoInNwYW4iKQpjPXAuYShILlZNKFsiZnVuY3Rp
+b24iXSxxKSkKaj1KLmRSKGQpCmouVjEoMCkKai5GVigwLGMpCmM9Zi5iCkwua0QoZCxjPT1udWxsPyJ1
+bmtub3duIjpjKQplLmFwcGVuZENoaWxkKGQpCmI9Zi5jCmlmKGIhPW51bGwpe2UuYXBwZW5kQ2hpbGQo
+bS5jcmVhdGVUZXh0Tm9kZSgiICgiKSkKYT1iLmIKYTA9bS5jcmVhdGVFbGVtZW50KCJhIikKYTAuYXBw
+ZW5kQ2hpbGQobS5jcmVhdGVUZXh0Tm9kZShILkVqKGIuYykrIjoiK0guRWooYSkpKQphMC5zZXRBdHRy
+aWJ1dGUoImhyZWYiLGIuYSkKYTAuY2xhc3NMaXN0LmFkZCgibmF2LWxpbmsiKQplLmFwcGVuZENoaWxk
+KGEwKQplLmFwcGVuZENoaWxkKG0uY3JlYXRlVGV4dE5vZGUoIikiKSl9ZS5hcHBlbmRDaGlsZChtLmNy
+ZWF0ZVRleHROb2RlKCI6ICIpKQpkPWYuYQpMLmtEKGUsZD09bnVsbD8idW5rbm93biI6ZCkKZD1mLmQK
+aWYoZC5sZW5ndGghPT0wKXtjPW0uY3JlYXRlRWxlbWVudCgicCIpCmExPXAuYShILlZNKFsiZHJhd2Vy
+IiwiYmVmb3JlLWFwcGx5Il0scSkpCmo9Si5kUihjKQpqLlYxKDApCmouRlYoMCxhMSkKYTI9ZS5hcHBl
+bmRDaGlsZChjKQpmb3IoYz1kLmxlbmd0aCxhMz0wO2EzPGQubGVuZ3RoO2QubGVuZ3RoPT09Y3x8KDAs
+SC5saykoZCksKythMylMLnV6KGRbYTNdLGEyLGIpfX19fSwKVXM6ZnVuY3Rpb24oYSl7cmV0dXJuIEou
+VTYoYSkudGcoYSwiPyIpP0MueEIuTmooYSwwLEMueEIuT1koYSwiPyIpKTphfSwKa0Q6ZnVuY3Rpb24o
+YSxiKXt2YXIgcyxyLHE9SC5WTShiLnNwbGl0KCIuIiksdC5zKSxwPUMuTm0uZ3RIKHEpLG89ZG9jdW1l
+bnQKYS5hcHBlbmRDaGlsZChvLmNyZWF0ZVRleHROb2RlKHApKQpmb3IocD1ILnFDKHEsMSxudWxsLHQu
+TikscD1uZXcgSC5hNyhwLHAuZ0EocCkscC4kdGkuQygiYTc8YUwuRT4iKSkscz1KLllFKGEpO3AuRigp
+Oyl7cj1wLmQKcy5ueihhLCJiZWZvcmVlbmQiLCImIzgyMDM7LiIsbnVsbCxudWxsKQphLmFwcGVuZENo
+aWxkKG8uY3JlYXRlVGV4dE5vZGUocikpfX0sCm1IOmZ1bmN0aW9uKGEsYil7dmFyIHMscixxLHAKZm9y
+KHM9YS5sZW5ndGgscj0wO3I8YS5sZW5ndGg7YS5sZW5ndGg9PT1zfHwoMCxILmxrKShhKSwrK3Ipe3E9
+YVtyXQppZihxIGluc3RhbmNlb2YgTC52dCl7cD1MLm1IKHEuZCxiKQppZihwIT1udWxsKXJldHVybiBw
+fWVsc2UgaWYocS5jPT1iKXJldHVybiBxfXJldHVybiBudWxsfSwKZTpmdW5jdGlvbiBlKCl7fSwKVlc6
+ZnVuY3Rpb24gVlcoYSxiLGMpe3RoaXMuYT1hCnRoaXMuYj1iCnRoaXMuYz1jfSwKb1o6ZnVuY3Rpb24g
+b1ooKXt9LApqcjpmdW5jdGlvbiBqcigpe30sCnFsOmZ1bmN0aW9uIHFsKCl7fSwKSGk6ZnVuY3Rpb24g
+SGkoKXt9LApCVDpmdW5jdGlvbiBCVCgpe30sClBZOmZ1bmN0aW9uIFBZKCl7fSwKdTg6ZnVuY3Rpb24g
+dTgoKXt9LApMOmZ1bmN0aW9uIEwoKXt9LApXeDpmdW5jdGlvbiBXeChhLGIpe3RoaXMuYT1hCnRoaXMu
+Yj1ifSwKQU86ZnVuY3Rpb24gQU8oYSl7dGhpcy5hPWF9LApkTjpmdW5jdGlvbiBkTihhKXt0aGlzLmE9
+YX0sCkhvOmZ1bmN0aW9uIEhvKGEpe3RoaXMuYT1hfSwKeHo6ZnVuY3Rpb24geHooYSxiKXt0aGlzLmE9
+YQp0aGlzLmI9Yn0sCklDOmZ1bmN0aW9uIElDKCl7fSwKZkM6ZnVuY3Rpb24gZkMoYSxiKXt0aGlzLmE9
+YQp0aGlzLmI9Yn0sCm5UOmZ1bmN0aW9uIG5UKGEsYixjKXt0aGlzLmE9YQp0aGlzLmI9Ygp0aGlzLmM9
+Y30sCk5ZOmZ1bmN0aW9uIE5ZKGEpe3RoaXMuYT1hfSwKdWU6ZnVuY3Rpb24gdWUoKXt9LAplWDpmdW5j
+dGlvbiBlWCgpe30sCkVFOmZ1bmN0aW9uIEVFKGEsYixjKXt0aGlzLmE9YQp0aGlzLmI9Ygp0aGlzLmM9
+Y30sClFMOmZ1bmN0aW9uIFFMKGEsYil7dGhpcy5hPWEKdGhpcy5iPWJ9LApWUzpmdW5jdGlvbiBWUyhh
+KXt0aGlzLmE9YX0sClREOmZ1bmN0aW9uIFREKCl7fSwKbTI6ZnVuY3Rpb24gbTIoYSxiKXt0aGlzLmE9
+YQp0aGlzLmI9Yn0sClhBOmZ1bmN0aW9uIFhBKCl7fSwKWnM6ZnVuY3Rpb24oYSl7dmFyIHMscixxPUou
+VTYoYSkKaWYoTC5wMihILmgocS5xKGEsInR5cGUiKSkpPT09Qy5ZMil7cz1ILmgocS5xKGEsIm5hbWUi
+KSkKcj1ILmgocS5xKGEsInBhdGgiKSkKcT1xLnEoYSwic3VidHJlZSIpCnE9bmV3IEwudnQocT09bnVs
+bD9udWxsOkwubUsocSkscyxyKQpxLkxWKCkKcmV0dXJuIHF9ZWxzZXtzPUguaChxLnEoYSwibmFtZSIp
+KQpyPUguaChxLnEoYSwicGF0aCIpKQpyZXR1cm4gbmV3IEwuY0QoSC5oKHEucShhLCJocmVmIikpLEgu
+dVAocS5xKGEsImVkaXRDb3VudCIpKSxILnk4KHEucShhLCJ3YXNFeHBsaWNpdGx5T3B0ZWRPdXQiKSks
+TC52QihILnVQKHEucShhLCJtaWdyYXRpb25TdGF0dXMiKSkpLHMscil9fSwKbUs6ZnVuY3Rpb24oYSl7
+dmFyIHMscj1ILlZNKFtdLHQuY1EpCmZvcihzPUouSVQodC5VLmEoYSkpO3MuRigpOylyLnB1c2goTC5a
+cyhzLmdsKCkpKQpyZXR1cm4gcn0sClZEOmZ1bmN0aW9uKGEpe3ZhciBzLHIscT1ILlZNKFtdLHQuRykK
+Zm9yKHM9YS5sZW5ndGgscj0wO3I8YS5sZW5ndGg7YS5sZW5ndGg9PT1zfHwoMCxILmxrKShhKSwrK3Ip
+cS5wdXNoKGFbcl0uTHQoKSkKcmV0dXJuIHF9LAp2QjpmdW5jdGlvbihhKXtpZihhPT1udWxsKXJldHVy
+biBudWxsCmlmKGE+Pj4wIT09YXx8YT49NClyZXR1cm4gSC5PSChDLmwwLGEpCnJldHVybiBDLmwwW2Fd
+fSwKcDI6ZnVuY3Rpb24oYSl7c3dpdGNoKGEpe2Nhc2UiZGlyZWN0b3J5IjpyZXR1cm4gQy5ZMgpjYXNl
+ImZpbGUiOnJldHVybiBDLnJmCmRlZmF1bHQ6dGhyb3cgSC5iKFAuUFYoIlVucmVjb2duaXplZCBuYXZp
+Z2F0aW9uIHRyZWUgbm9kZSB0eXBlOiAiK0guRWooYSkpKX19LAp2dDpmdW5jdGlvbiB2dChhLGIsYyl7
+dmFyIF89dGhpcwpfLmQ9YQpfLmE9YgpfLmI9bnVsbApfLmM9Y30sCmNEOmZ1bmN0aW9uIGNEKGEsYixj
+LGQsZSxmKXt2YXIgXz10aGlzCl8uZD1hCl8uZT1iCl8uZj1jCl8ucj1kCl8uYT1lCl8uYj1udWxsCl8u
+Yz1mfSwKRDg6ZnVuY3Rpb24gRDgoKXt9LApPOTpmdW5jdGlvbiBPOShhKXt0aGlzLmI9YX0sCkdiOmZ1
+bmN0aW9uIEdiKGEsYil7dGhpcy5hPWEKdGhpcy5iPWJ9LApJVjpmdW5jdGlvbiBJVihhLGIsYyxkKXt2
+YXIgXz10aGlzCl8uZD1hCl8uZT1iCl8uZj1jCl8ucj1kfX0sWD17CkNMOmZ1bmN0aW9uKGEsYil7dmFy
+IHMscixxLHAsbyxuPWIueFooYSkKYi5oSyhhKQppZihuIT1udWxsKWE9Si5LVihhLG4ubGVuZ3RoKQpz
+PXQucwpyPUguVk0oW10scykKcT1ILlZNKFtdLHMpCnM9YS5sZW5ndGgKaWYocyE9PTAmJmIucjQoQy54
+Qi5XKGEsMCkpKXtpZigwPj1zKXJldHVybiBILk9IKGEsMCkKQy5ObS5pKHEsYVswXSkKcD0xfWVsc2V7
+Qy5ObS5pKHEsIiIpCnA9MH1mb3Iobz1wO288czsrK28paWYoYi5yNChDLnhCLlcoYSxvKSkpe0MuTm0u
+aShyLEMueEIuTmooYSxwLG8pKQpDLk5tLmkocSxhW29dKQpwPW8rMX1pZihwPHMpe0MuTm0uaShyLEMu
+eEIueW4oYSxwKSkKQy5ObS5pKHEsIiIpfXJldHVybiBuZXcgWC5XRChiLG4scixxKX0sCldEOmZ1bmN0
+aW9uIFdEKGEsYixjLGQpe3ZhciBfPXRoaXMKXy5hPWEKXy5iPWIKXy5kPWMKXy5lPWR9LApJNzpmdW5j
+dGlvbihhKXtyZXR1cm4gbmV3IFguZHYoYSl9LApkdjpmdW5jdGlvbiBkdihhKXt0aGlzLmE9YX19LE89
+ewpSaDpmdW5jdGlvbigpe3ZhciBzLHI9bnVsbAppZihQLnVvKCkuZ0ZpKCkhPT0iZmlsZSIpcmV0dXJu
+ICQuRWIoKQpzPVAudW8oKQppZighQy54Qi5UYyhzLmdJaShzKSwiLyIpKXJldHVybiAkLkViKCkKaWYo
+UC5LTChyLCJhL2IiLHIscixyLHIscikudDQoKT09PSJhXFxiIilyZXR1cm4gJC5LaygpCnJldHVybiAk
+LmJEKCl9LAp6TDpmdW5jdGlvbiB6TCgpe319LEU9e09GOmZ1bmN0aW9uIE9GKGEsYixjKXt0aGlzLmQ9
+YQp0aGlzLmU9Ygp0aGlzLmY9Y319LEY9e3J1OmZ1bmN0aW9uIHJ1KGEsYixjLGQpe3ZhciBfPXRoaXMK
+Xy5kPWEKXy5lPWIKXy5mPWMKXy5yPWR9fSxEPXsKYWI6ZnVuY3Rpb24oKXt2YXIgcyxyLHEscCxvPW51
+bGwKdHJ5e289UC51bygpfWNhdGNoKHMpe2lmKHQuZzguYihILlJ1KHMpKSl7cj0kLkZmCmlmKHIhPW51
+bGwpcmV0dXJuIHIKdGhyb3cgc31lbHNlIHRocm93IHN9aWYoSi5STShvLCQuSTYpKXtyPSQuRmYKci50
+b1N0cmluZwpyZXR1cm4gcn0kLkk2PW8KaWYoJC5IaygpPT0kLkViKCkpcj0kLkZmPW8uWkkoIi4iKS53
+KDApCmVsc2V7cT1vLnQ0KCkKcD1xLmxlbmd0aC0xCnI9JC5GZj1wPT09MD9xOkMueEIuTmoocSwwLHAp
+fXIudG9TdHJpbmcKcmV0dXJuIHJ9fQp2YXIgdz1bQyxILEosUCxXLE0sVSxCLFQsTCxYLE8sRSxGLERd
+Cmh1bmtIZWxwZXJzLnNldEZ1bmN0aW9uTmFtZXNJZk5lY2Vzc2FyeSh3KQp2YXIgJD17fQpILkZLLnBy
+b3RvdHlwZT17fQpKLkd2LnByb3RvdHlwZT17CkROOmZ1bmN0aW9uKGEsYil7cmV0dXJuIGE9PT1ifSwK
+Z2lPOmZ1bmN0aW9uKGEpe3JldHVybiBILmVRKGEpfSwKdzpmdW5jdGlvbihhKXtyZXR1cm4iSW5zdGFu
+Y2Ugb2YgJyIrSC5FaihILk0oYSkpKyInIn0sCmU3OmZ1bmN0aW9uKGEsYil7dC5vLmEoYikKdGhyb3cg
+SC5iKFAubHIoYSxiLmdXYSgpLGIuZ25kKCksYi5nVm0oKSkpfX0KSi55RS5wcm90b3R5cGU9ewp3OmZ1
+bmN0aW9uKGEpe3JldHVybiBTdHJpbmcoYSl9LApnaU86ZnVuY3Rpb24oYSl7cmV0dXJuIGE/NTE5MDE4
+OjIxODE1OX0sCiRpYTI6MX0KSi53ZS5wcm90b3R5cGU9ewpETjpmdW5jdGlvbihhLGIpe3JldHVybiBu
+dWxsPT1ifSwKdzpmdW5jdGlvbihhKXtyZXR1cm4ibnVsbCJ9LApnaU86ZnVuY3Rpb24oYSl7cmV0dXJu
+IDB9LAplNzpmdW5jdGlvbihhLGIpe3JldHVybiB0aGlzLlNqKGEsdC5vLmEoYikpfSwKJGljODoxfQpK
+Lk1GLnByb3RvdHlwZT17CmdpTzpmdW5jdGlvbihhKXtyZXR1cm4gMH0sCnc6ZnVuY3Rpb24oYSl7cmV0
+dXJuIFN0cmluZyhhKX0sCiRpdm06MX0KSi5pQy5wcm90b3R5cGU9e30KSi5rZC5wcm90b3R5cGU9e30K
+Si5jNS5wcm90b3R5cGU9ewp3OmZ1bmN0aW9uKGEpe3ZhciBzPWFbJC53KCldCmlmKHM9PW51bGwpcmV0
+dXJuIHRoaXMudChhKQpyZXR1cm4iSmF2YVNjcmlwdCBmdW5jdGlvbiBmb3IgIitILkVqKEouaihzKSl9
+LAokaUVIOjF9CkouamQucHJvdG90eXBlPXsKZHI6ZnVuY3Rpb24oYSxiKXtyZXR1cm4gbmV3IEgualYo
+YSxILnQ2KGEpLkMoIkA8MT4iKS5LcShiKS5DKCJqVjwxLDI+IikpfSwKaTpmdW5jdGlvbihhLGIpe0gu
+dDYoYSkuYy5hKGIpCmlmKCEhYS5maXhlZCRsZW5ndGgpSC52KFAuTDQoImFkZCIpKQphLnB1c2goYil9
+LApXNDpmdW5jdGlvbihhLGIpe3ZhciBzCmlmKCEhYS5maXhlZCRsZW5ndGgpSC52KFAuTDQoInJlbW92
+ZUF0IikpCnM9YS5sZW5ndGgKaWYoYj49cyl0aHJvdyBILmIoUC5PNyhiLG51bGwpKQpyZXR1cm4gYS5z
+cGxpY2UoYiwxKVswXX0sClVHOmZ1bmN0aW9uKGEsYixjKXt2YXIgcyxyCkgudDYoYSkuQygiY1g8MT4i
+KS5hKGMpCmlmKCEhYS5maXhlZCRsZW5ndGgpSC52KFAuTDQoImluc2VydEFsbCIpKQpQLndBKGIsMCxh
+Lmxlbmd0aCwiaW5kZXgiKQppZighdC5iLmIoYykpYz1KLlJYKGMpCnM9Si5IbShjKQphLmxlbmd0aD1h
+Lmxlbmd0aCtzCnI9YitzCnRoaXMuWVcoYSxyLGEubGVuZ3RoLGEsYikKdGhpcy52ZyhhLGIscixjKX0s
+CkZWOmZ1bmN0aW9uKGEsYil7dmFyIHMKSC50NihhKS5DKCJjWDwxPiIpLmEoYikKaWYoISFhLmZpeGVk
+JGxlbmd0aClILnYoUC5MNCgiYWRkQWxsIikpCmZvcihzPUouSVQoYik7cy5GKCk7KWEucHVzaChzLmds
+KCkpfSwKRTI6ZnVuY3Rpb24oYSxiLGMpe3ZhciBzPUgudDYoYSkKcmV0dXJuIG5ldyBILmxKKGEscy5L
+cShjKS5DKCIxKDIpIikuYShiKSxzLkMoIkA8MT4iKS5LcShjKS5DKCJsSjwxLDI+IikpfSwKazpmdW5j
+dGlvbihhLGIpe3ZhciBzLHI9UC5POChhLmxlbmd0aCwiIiwhMSx0Lk4pCmZvcihzPTA7czxhLmxlbmd0
+aDsrK3MpdGhpcy5ZNShyLHMsSC5FaihhW3NdKSkKcmV0dXJuIHIuam9pbihiKX0sCmVSOmZ1bmN0aW9u
+KGEsYil7cmV0dXJuIEgucUMoYSxiLG51bGwsSC50NihhKS5jKX0sCk4wOmZ1bmN0aW9uKGEsYixjLGQp
+e3ZhciBzLHIscQpkLmEoYikKSC50NihhKS5LcShkKS5DKCIxKDEsMikiKS5hKGMpCnM9YS5sZW5ndGgK
+Zm9yKHI9YixxPTA7cTxzOysrcSl7cj1jLiQyKHIsYVtxXSkKaWYoYS5sZW5ndGghPT1zKXRocm93IEgu
+YihQLmE0KGEpKX1yZXR1cm4gcn0sCkh0OmZ1bmN0aW9uKGEsYil7dmFyIHMscixxLHAsbwpILnQ2KGEp
+LkMoImEyKDEpIikuYShiKQpzPWEubGVuZ3RoCmZvcihyPW51bGwscT0hMSxwPTA7cDxzOysrcCl7bz1h
+W3BdCmlmKEgub1QoYi4kMShvKSkpe2lmKHEpdGhyb3cgSC5iKEguQW0oKSkKcj1vCnE9ITB9aWYocyE9
+PWEubGVuZ3RoKXRocm93IEguYihQLmE0KGEpKX1pZihxKXJldHVybiByCnRocm93IEguYihILldwKCkp
+fSwKRTpmdW5jdGlvbihhLGIpe2lmKGI8MHx8Yj49YS5sZW5ndGgpcmV0dXJuIEguT0goYSxiKQpyZXR1
+cm4gYVtiXX0sCmd0SDpmdW5jdGlvbihhKXtpZihhLmxlbmd0aD4wKXJldHVybiBhWzBdCnRocm93IEgu
+YihILldwKCkpfSwKZ3JaOmZ1bmN0aW9uKGEpe3ZhciBzPWEubGVuZ3RoCmlmKHM+MClyZXR1cm4gYVtz
+LTFdCnRocm93IEguYihILldwKCkpfSwKWVc6ZnVuY3Rpb24oYSxiLGMsZCxlKXt2YXIgcyxyLHEscCxv
+CkgudDYoYSkuQygiY1g8MT4iKS5hKGQpCmlmKCEhYS5pbW11dGFibGUkbGlzdClILnYoUC5MNCgic2V0
+UmFuZ2UiKSkKUC5qQihiLGMsYS5sZW5ndGgpCnM9Yy1iCmlmKHM9PT0wKXJldHVybgpQLmsxKGUsInNr
+aXBDb3VudCIpCmlmKHQuai5iKGQpKXtyPWQKcT1lfWVsc2V7cj1KLkE1KGQsZSkudHQoMCwhMSkKcT0w
+fXA9Si5VNihyKQppZihxK3M+cC5nQShyKSl0aHJvdyBILmIoSC5hcigpKQppZihxPGIpZm9yKG89cy0x
+O28+PTA7LS1vKWFbYitvXT1wLnEocixxK28pCmVsc2UgZm9yKG89MDtvPHM7KytvKWFbYitvXT1wLnEo
+cixxK28pfSwKdmc6ZnVuY3Rpb24oYSxiLGMsZCl7cmV0dXJuIHRoaXMuWVcoYSxiLGMsZCwwKX0sClZy
+OmZ1bmN0aW9uKGEsYil7dmFyIHMscgpILnQ2KGEpLkMoImEyKDEpIikuYShiKQpzPWEubGVuZ3RoCmZv
+cihyPTA7cjxzOysrcil7aWYoSC5vVChiLiQxKGFbcl0pKSlyZXR1cm4hMAppZihhLmxlbmd0aCE9PXMp
+dGhyb3cgSC5iKFAuYTQoYSkpfXJldHVybiExfSwKdGc6ZnVuY3Rpb24oYSxiKXt2YXIgcwpmb3Iocz0w
+O3M8YS5sZW5ndGg7KytzKWlmKEouUk0oYVtzXSxiKSlyZXR1cm4hMApyZXR1cm4hMX0sCmdsMDpmdW5j
+dGlvbihhKXtyZXR1cm4gYS5sZW5ndGg9PT0wfSwKZ29yOmZ1bmN0aW9uKGEpe3JldHVybiBhLmxlbmd0
+aCE9PTB9LAp3OmZ1bmN0aW9uKGEpe3JldHVybiBQLldFKGEsIlsiLCJdIil9LAp0dDpmdW5jdGlvbihh
+LGIpe3ZhciBzPUguVk0oYS5zbGljZSgwKSxILnQ2KGEpKQpyZXR1cm4gc30sCmJyOmZ1bmN0aW9uKGEp
+e3JldHVybiB0aGlzLnR0KGEsITApfSwKZ206ZnVuY3Rpb24oYSl7cmV0dXJuIG5ldyBKLm0xKGEsYS5s
+ZW5ndGgsSC50NihhKS5DKCJtMTwxPiIpKX0sCmdpTzpmdW5jdGlvbihhKXtyZXR1cm4gSC5lUShhKX0s
+CmdBOmZ1bmN0aW9uKGEpe3JldHVybiBhLmxlbmd0aH0sCnNBOmZ1bmN0aW9uKGEsYil7aWYoISFhLmZp
+eGVkJGxlbmd0aClILnYoUC5MNCgic2V0IGxlbmd0aCIpKQppZihiPDApdGhyb3cgSC5iKFAuVEUoYiww
+LG51bGwsIm5ld0xlbmd0aCIsbnVsbCkpCmEubGVuZ3RoPWJ9LApxOmZ1bmN0aW9uKGEsYil7SC51UChi
+KQppZihiPj1hLmxlbmd0aHx8YjwwKXRocm93IEguYihILkhZKGEsYikpCnJldHVybiBhW2JdfSwKWTU6
+ZnVuY3Rpb24oYSxiLGMpe0gudDYoYSkuYy5hKGMpCmlmKCEhYS5pbW11dGFibGUkbGlzdClILnYoUC5M
+NCgiaW5kZXhlZCBzZXQiKSkKaWYoYj49YS5sZW5ndGh8fGI8MCl0aHJvdyBILmIoSC5IWShhLGIpKQph
+W2JdPWN9LAokaWJROjEsCiRpY1g6MSwKJGl6TToxfQpKLlBvLnByb3RvdHlwZT17fQpKLm0xLnByb3Rv
+dHlwZT17CmdsOmZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMuZH0sCkY6ZnVuY3Rpb24oKXt2YXIgcyxyPXRo
+aXMscT1yLmEscD1xLmxlbmd0aAppZihyLmIhPT1wKXRocm93IEguYihILmxrKHEpKQpzPXIuYwppZihz
+Pj1wKXtyLnNNKG51bGwpCnJldHVybiExfXIuc00ocVtzXSk7KytyLmMKcmV0dXJuITB9LApzTTpmdW5j
+dGlvbihhKXt0aGlzLmQ9dGhpcy4kdGkuQygiMT8iKS5hKGEpfSwKJGlBbjoxfQpKLnFJLnByb3RvdHlw
+ZT17CnpROmZ1bmN0aW9uKGEpe2lmKGE+MCl7aWYoYSE9PTEvMClyZXR1cm4gTWF0aC5yb3VuZChhKX1l
+bHNlIGlmKGE+LTEvMClyZXR1cm4gMC1NYXRoLnJvdW5kKDAtYSkKdGhyb3cgSC5iKFAuTDQoIiIrYSsi
+LnJvdW5kKCkiKSl9LAp3OmZ1bmN0aW9uKGEpe2lmKGE9PT0wJiYxL2E8MClyZXR1cm4iLTAuMCIKZWxz
+ZSByZXR1cm4iIithfSwKZ2lPOmZ1bmN0aW9uKGEpe3ZhciBzLHIscSxwLG89YXwwCmlmKGE9PT1vKXJl
+dHVybiBvJjUzNjg3MDkxMQpzPU1hdGguYWJzKGEpCnI9TWF0aC5sb2cocykvMC42OTMxNDcxODA1NTk5
+NDUzfDAKcT1NYXRoLnBvdygyLHIpCnA9czwxP3MvcTpxL3MKcmV0dXJuKChwKjkwMDcxOTkyNTQ3NDA5
+OTJ8MCkrKHAqMzU0MjI0MzE4MTE3NjUyMXwwKSkqNTk5MTk3K3IqMTI1OSY1MzY4NzA5MTF9LAp6WTpm
+dW5jdGlvbihhLGIpe3ZhciBzPWElYgppZihzPT09MClyZXR1cm4gMAppZihzPjApcmV0dXJuIHMKaWYo
+YjwwKXJldHVybiBzLWIKZWxzZSByZXR1cm4gcytifSwKQlU6ZnVuY3Rpb24oYSxiKXtyZXR1cm4oYXww
+KT09PWE/YS9ifDA6dGhpcy5ESihhLGIpfSwKREo6ZnVuY3Rpb24oYSxiKXt2YXIgcz1hL2IKaWYocz49
+LTIxNDc0ODM2NDgmJnM8PTIxNDc0ODM2NDcpcmV0dXJuIHN8MAppZihzPjApe2lmKHMhPT0xLzApcmV0
+dXJuIE1hdGguZmxvb3Iocyl9ZWxzZSBpZihzPi0xLzApcmV0dXJuIE1hdGguY2VpbChzKQp0aHJvdyBI
+LmIoUC5MNCgiUmVzdWx0IG9mIHRydW5jYXRpbmcgZGl2aXNpb24gaXMgIitILkVqKHMpKyI6ICIrSC5F
+aihhKSsiIH4vICIrYikpfSwKd0c6ZnVuY3Rpb24oYSxiKXt2YXIgcwppZihhPjApcz10aGlzLnAzKGEs
+YikKZWxzZXtzPWI+MzE/MzE6YgpzPWE+PnM+Pj4wfXJldHVybiBzfSwKYmY6ZnVuY3Rpb24oYSxiKXtp
+ZihiPDApdGhyb3cgSC5iKEgudEwoYikpCnJldHVybiB0aGlzLnAzKGEsYil9LApwMzpmdW5jdGlvbihh
+LGIpe3JldHVybiBiPjMxPzA6YT4+PmJ9LAokaUNQOjEsCiRpWlo6MX0KSi5iVS5wcm90b3R5cGU9eyRp
+SWY6MX0KSi5WQS5wcm90b3R5cGU9e30KSi5Eci5wcm90b3R5cGU9ewpPMjpmdW5jdGlvbihhLGIpe2lm
+KGI8MCl0aHJvdyBILmIoSC5IWShhLGIpKQppZihiPj1hLmxlbmd0aClILnYoSC5IWShhLGIpKQpyZXR1
+cm4gYS5jaGFyQ29kZUF0KGIpfSwKVzpmdW5jdGlvbihhLGIpe2lmKGI+PWEubGVuZ3RoKXRocm93IEgu
+YihILkhZKGEsYikpCnJldHVybiBhLmNoYXJDb2RlQXQoYil9LApkZDpmdW5jdGlvbihhLGIpe3JldHVy
+biBuZXcgSC51bihiLGEsMCl9LApoOmZ1bmN0aW9uKGEsYil7aWYodHlwZW9mIGIhPSJzdHJpbmciKXRo
+cm93IEguYihQLkwzKGIsbnVsbCxudWxsKSkKcmV0dXJuIGErYn0sClRjOmZ1bmN0aW9uKGEsYil7dmFy
+IHM9Yi5sZW5ndGgscj1hLmxlbmd0aAppZihzPnIpcmV0dXJuITEKcmV0dXJuIGI9PT10aGlzLnluKGEs
+ci1zKX0sCmk3OmZ1bmN0aW9uKGEsYixjLGQpe3ZhciBzPVAuakIoYixjLGEubGVuZ3RoKSxyPWEuc3Vi
+c3RyaW5nKDAsYikscT1hLnN1YnN0cmluZyhzKQpyZXR1cm4gcitkK3F9LApRaTpmdW5jdGlvbihhLGIs
+Yyl7dmFyIHMKaWYoYzwwfHxjPmEubGVuZ3RoKXRocm93IEguYihQLlRFKGMsMCxhLmxlbmd0aCxudWxs
+LG51bGwpKQpzPWMrYi5sZW5ndGgKaWYocz5hLmxlbmd0aClyZXR1cm4hMQpyZXR1cm4gYj09PWEuc3Vi
+c3RyaW5nKGMscyl9LApuQzpmdW5jdGlvbihhLGIpe3JldHVybiB0aGlzLlFpKGEsYiwwKX0sCk5qOmZ1
+bmN0aW9uKGEsYixjKXtpZihjPT1udWxsKWM9YS5sZW5ndGgKaWYoYjwwKXRocm93IEguYihQLk83KGIs
+bnVsbCkpCmlmKGI+Yyl0aHJvdyBILmIoUC5PNyhiLG51bGwpKQppZihjPmEubGVuZ3RoKXRocm93IEgu
+YihQLk83KGMsbnVsbCkpCnJldHVybiBhLnN1YnN0cmluZyhiLGMpfSwKeW46ZnVuY3Rpb24oYSxiKXty
+ZXR1cm4gdGhpcy5OaihhLGIsbnVsbCl9LApoYzpmdW5jdGlvbihhKXtyZXR1cm4gYS50b0xvd2VyQ2Fz
+ZSgpfSwKYlM6ZnVuY3Rpb24oYSl7dmFyIHMscixxLHA9YS50cmltKCksbz1wLmxlbmd0aAppZihvPT09
+MClyZXR1cm4gcAppZih0aGlzLlcocCwwKT09PTEzMyl7cz1KLm1tKHAsMSkKaWYocz09PW8pcmV0dXJu
+IiJ9ZWxzZSBzPTAKcj1vLTEKcT10aGlzLk8yKHAscik9PT0xMzM/Si5jMShwLHIpOm8KaWYocz09PTAm
+JnE9PT1vKXJldHVybiBwCnJldHVybiBwLnN1YnN0cmluZyhzLHEpfSwKVDpmdW5jdGlvbihhLGIpe3Zh
+ciBzLHIKaWYoMD49YilyZXR1cm4iIgppZihiPT09MXx8YS5sZW5ndGg9PT0wKXJldHVybiBhCmlmKGIh
+PT1iPj4+MCl0aHJvdyBILmIoQy5FcSkKZm9yKHM9YSxyPSIiOyEwOyl7aWYoKGImMSk9PT0xKXI9cyty
+CmI9Yj4+PjEKaWYoYj09PTApYnJlYWsKcys9c31yZXR1cm4gcn0sClhVOmZ1bmN0aW9uKGEsYixjKXt2
+YXIgcwppZihjPDB8fGM+YS5sZW5ndGgpdGhyb3cgSC5iKFAuVEUoYywwLGEubGVuZ3RoLG51bGwsbnVs
+bCkpCnM9YS5pbmRleE9mKGIsYykKcmV0dXJuIHN9LApPWTpmdW5jdGlvbihhLGIpe3JldHVybiB0aGlz
+LlhVKGEsYiwwKX0sClBrOmZ1bmN0aW9uKGEsYixjKXt2YXIgcyxyCmlmKGM9PW51bGwpYz1hLmxlbmd0
+aAplbHNlIGlmKGM8MHx8Yz5hLmxlbmd0aCl0aHJvdyBILmIoUC5URShjLDAsYS5sZW5ndGgsbnVsbCxu
+dWxsKSkKcz1iLmxlbmd0aApyPWEubGVuZ3RoCmlmKGMrcz5yKWM9ci1zCnJldHVybiBhLmxhc3RJbmRl
+eE9mKGIsYyl9LApjbjpmdW5jdGlvbihhLGIpe3JldHVybiB0aGlzLlBrKGEsYixudWxsKX0sCklzOmZ1
+bmN0aW9uKGEsYixjKXt2YXIgcz1hLmxlbmd0aAppZihjPnMpdGhyb3cgSC5iKFAuVEUoYywwLHMsbnVs
+bCxudWxsKSkKcmV0dXJuIEguU1EoYSxiLGMpfSwKdGc6ZnVuY3Rpb24oYSxiKXtyZXR1cm4gdGhpcy5J
+cyhhLGIsMCl9LAp3OmZ1bmN0aW9uKGEpe3JldHVybiBhfSwKZ2lPOmZ1bmN0aW9uKGEpe3ZhciBzLHIs
+cQpmb3Iocz1hLmxlbmd0aCxyPTAscT0wO3E8czsrK3Epe3I9cithLmNoYXJDb2RlQXQocSkmNTM2ODcw
+OTExCnI9cisoKHImNTI0Mjg3KTw8MTApJjUzNjg3MDkxMQpyXj1yPj42fXI9cisoKHImNjcxMDg4NjMp
+PDwzKSY1MzY4NzA5MTEKcl49cj4+MTEKcmV0dXJuIHIrKChyJjE2MzgzKTw8MTUpJjUzNjg3MDkxMX0s
+CmdBOmZ1bmN0aW9uKGEpe3JldHVybiBhLmxlbmd0aH0sCnE6ZnVuY3Rpb24oYSxiKXtILnVQKGIpCmlm
+KGI+PWEubGVuZ3RofHwhMSl0aHJvdyBILmIoSC5IWShhLGIpKQpyZXR1cm4gYVtiXX0sCiRpdlg6MSwK
+JGlxVToxfQpILkJSLnByb3RvdHlwZT17CmdtOmZ1bmN0aW9uKGEpe3ZhciBzPUguTGgodGhpcykKcmV0
+dXJuIG5ldyBILkU3KEouSVQodGhpcy5nT04oKSkscy5DKCJAPDE+IikuS3Eocy5RWzFdKS5DKCJFNzwx
+LDI+IikpfSwKZ0E6ZnVuY3Rpb24oYSl7cmV0dXJuIEouSG0odGhpcy5nT04oKSl9LApnbDA6ZnVuY3Rp
+b24oYSl7cmV0dXJuIEoudVUodGhpcy5nT04oKSl9LApnb3I6ZnVuY3Rpb24oYSl7cmV0dXJuIEouRjco
+dGhpcy5nT04oKSl9LAplUjpmdW5jdGlvbihhLGIpe3ZhciBzPUguTGgodGhpcykKcmV0dXJuIEguR0oo
+Si5BNSh0aGlzLmdPTigpLGIpLHMuYyxzLlFbMV0pfSwKRTpmdW5jdGlvbihhLGIpe3JldHVybiBILkxo
+KHRoaXMpLlFbMV0uYShKLkdBKHRoaXMuZ09OKCksYikpfSwKdzpmdW5jdGlvbihhKXtyZXR1cm4gSi5q
+KHRoaXMuZ09OKCkpfX0KSC5FNy5wcm90b3R5cGU9ewpGOmZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMuYS5G
+KCl9LApnbDpmdW5jdGlvbigpe3JldHVybiB0aGlzLiR0aS5RWzFdLmEodGhpcy5hLmdsKCkpfSwKJGlB
+bjoxfQpILlp5LnByb3RvdHlwZT17CmdPTjpmdW5jdGlvbigpe3JldHVybiB0aGlzLmF9fQpILm9sLnBy
+b3RvdHlwZT17JGliUToxfQpILlVxLnByb3RvdHlwZT17CnE6ZnVuY3Rpb24oYSxiKXtyZXR1cm4gdGhp
+cy4kdGkuUVsxXS5hKEoueDkodGhpcy5hLEgudVAoYikpKX0sClk1OmZ1bmN0aW9uKGEsYixjKXt2YXIg
+cz10aGlzLiR0aQpKLnU5KHRoaXMuYSxiLHMuYy5hKHMuUVsxXS5hKGMpKSl9LAokaWJROjEsCiRpek06
+MX0KSC5qVi5wcm90b3R5cGU9ewpkcjpmdW5jdGlvbihhLGIpe3JldHVybiBuZXcgSC5qVih0aGlzLmEs
+dGhpcy4kdGkuQygiQDwxPiIpLktxKGIpLkMoImpWPDEsMj4iKSl9LApnT046ZnVuY3Rpb24oKXtyZXR1
+cm4gdGhpcy5hfX0KSC5uLnByb3RvdHlwZT17Cnc6ZnVuY3Rpb24oYSl7dmFyIHM9dGhpcy5hCnJldHVy
+biBzIT1udWxsPyJMYXRlSW5pdGlhbGl6YXRpb25FcnJvcjogIitzOiJMYXRlSW5pdGlhbGl6YXRpb25F
+cnJvciJ9fQpILnIzLnByb3RvdHlwZT17Cnc6ZnVuY3Rpb24oYSl7dmFyIHM9IlJlYWNoYWJpbGl0eUVy
+cm9yOiAiK3RoaXMuYQpyZXR1cm4gc319CkgucWoucHJvdG90eXBlPXsKZ0E6ZnVuY3Rpb24oYSl7cmV0
+dXJuIHRoaXMuYS5sZW5ndGh9LApxOmZ1bmN0aW9uKGEsYil7cmV0dXJuIEMueEIuTzIodGhpcy5hLEgu
+dVAoYikpfX0KSC5HTS5wcm90b3R5cGU9ewp3OmZ1bmN0aW9uKGEpe3JldHVybiJOdWxsIGlzIG5vdCBh
+IHZhbGlkIHZhbHVlIGZvciB0aGUgcGFyYW1ldGVyICciK3RoaXMuYSsiJyBvZiB0eXBlICciK0guS3go
+dGhpcy4kdGkuYykudygwKSsiJyJ9fQpILmJRLnByb3RvdHlwZT17fQpILmFMLnByb3RvdHlwZT17Cmdt
+OmZ1bmN0aW9uKGEpe3ZhciBzPXRoaXMKcmV0dXJuIG5ldyBILmE3KHMscy5nQShzKSxILkxoKHMpLkMo
+ImE3PGFMLkU+IikpfSwKZ2wwOmZ1bmN0aW9uKGEpe3JldHVybiB0aGlzLmdBKHRoaXMpPT09MH0sCms6
+ZnVuY3Rpb24oYSxiKXt2YXIgcyxyLHEscD10aGlzLG89cC5nQShwKQppZihiLmxlbmd0aCE9PTApe2lm
+KG89PT0wKXJldHVybiIiCnM9SC5FaihwLkUoMCwwKSkKaWYobyE9PXAuZ0EocCkpdGhyb3cgSC5iKFAu
+YTQocCkpCmZvcihyPXMscT0xO3E8bzsrK3Epe3I9citiK0guRWoocC5FKDAscSkpCmlmKG8hPT1wLmdB
+KHApKXRocm93IEguYihQLmE0KHApKX1yZXR1cm4gci5jaGFyQ29kZUF0KDApPT0wP3I6cn1lbHNle2Zv
+cihxPTAscj0iIjtxPG87KytxKXtyKz1ILkVqKHAuRSgwLHEpKQppZihvIT09cC5nQShwKSl0aHJvdyBI
+LmIoUC5hNChwKSl9cmV0dXJuIHIuY2hhckNvZGVBdCgwKT09MD9yOnJ9fSwKZXY6ZnVuY3Rpb24oYSxi
+KXtyZXR1cm4gdGhpcy5HRygwLEguTGgodGhpcykuQygiYTIoYUwuRSkiKS5hKGIpKX0sCkUyOmZ1bmN0
+aW9uKGEsYixjKXt2YXIgcz1ILkxoKHRoaXMpCnJldHVybiBuZXcgSC5sSih0aGlzLHMuS3EoYykuQygi
+MShhTC5FKSIpLmEoYikscy5DKCJAPGFMLkU+IikuS3EoYykuQygibEo8MSwyPiIpKX0sCmVSOmZ1bmN0
+aW9uKGEsYil7cmV0dXJuIEgucUModGhpcyxiLG51bGwsSC5MaCh0aGlzKS5DKCJhTC5FIikpfSwKdHQ6
+ZnVuY3Rpb24oYSxiKXtyZXR1cm4gUC5ZMSh0aGlzLCEwLEguTGgodGhpcykuQygiYUwuRSIpKX0sCmJy
+OmZ1bmN0aW9uKGEpe3JldHVybiB0aGlzLnR0KGEsITApfX0KSC5uSC5wcm90b3R5cGU9ewpIZDpmdW5j
+dGlvbihhLGIsYyxkKXt2YXIgcyxyPXRoaXMuYgpQLmsxKHIsInN0YXJ0IikKcz10aGlzLmMKaWYocyE9
+bnVsbCl7UC5rMShzLCJlbmQiKQppZihyPnMpdGhyb3cgSC5iKFAuVEUociwwLHMsInN0YXJ0IixudWxs
+KSl9fSwKZ1VEOmZ1bmN0aW9uKCl7dmFyIHM9Si5IbSh0aGlzLmEpLHI9dGhpcy5jCmlmKHI9PW51bGx8
+fHI+cylyZXR1cm4gcwpyZXR1cm4gcn0sCmdBczpmdW5jdGlvbigpe3ZhciBzPUouSG0odGhpcy5hKSxy
+PXRoaXMuYgppZihyPnMpcmV0dXJuIHMKcmV0dXJuIHJ9LApnQTpmdW5jdGlvbihhKXt2YXIgcyxyPUou
+SG0odGhpcy5hKSxxPXRoaXMuYgppZihxPj1yKXJldHVybiAwCnM9dGhpcy5jCmlmKHM9PW51bGx8fHM+
+PXIpcmV0dXJuIHItcQppZih0eXBlb2YgcyE9PSJudW1iZXIiKXJldHVybiBzLkhOKCkKcmV0dXJuIHMt
+cX0sCkU6ZnVuY3Rpb24oYSxiKXt2YXIgcz10aGlzLHI9cy5nQXMoKStiCmlmKGI8MHx8cj49cy5nVUQo
+KSl0aHJvdyBILmIoUC5DZihiLHMsImluZGV4IixudWxsLG51bGwpKQpyZXR1cm4gSi5HQShzLmEscil9
+LAplUjpmdW5jdGlvbihhLGIpe3ZhciBzLHIscT10aGlzClAuazEoYiwiY291bnQiKQpzPXEuYitiCnI9
+cS5jCmlmKHIhPW51bGwmJnM+PXIpcmV0dXJuIG5ldyBILk1CKHEuJHRpLkMoIk1CPDE+IikpCnJldHVy
+biBILnFDKHEuYSxzLHIscS4kdGkuYyl9LAp0dDpmdW5jdGlvbihhLGIpe3ZhciBzLHIscSxwPXRoaXMs
+bz1wLmIsbj1wLmEsbT1KLlU2KG4pLGw9bS5nQShuKSxrPXAuYwppZihrIT1udWxsJiZrPGwpbD1rCmlm
+KHR5cGVvZiBsIT09Im51bWJlciIpcmV0dXJuIGwuSE4oKQpzPWwtbwppZihzPD0wKXtuPUouUWkoMCxw
+LiR0aS5jKQpyZXR1cm4gbn1yPVAuTzgocyxtLkUobixvKSwhMSxwLiR0aS5jKQpmb3IocT0xO3E8czsr
+K3Epe0MuTm0uWTUocixxLG0uRShuLG8rcSkpCmlmKG0uZ0Eobik8bCl0aHJvdyBILmIoUC5hNChwKSl9
+cmV0dXJuIHJ9fQpILmE3LnByb3RvdHlwZT17CmdsOmZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMuZH0sCkY6
+ZnVuY3Rpb24oKXt2YXIgcyxyPXRoaXMscT1yLmEscD1KLlU2KHEpLG89cC5nQShxKQppZihyLmIhPT1v
+KXRocm93IEguYihQLmE0KHEpKQpzPXIuYwppZihzPj1vKXtyLnNJKG51bGwpCnJldHVybiExfXIuc0ko
+cC5FKHEscykpOysrci5jCnJldHVybiEwfSwKc0k6ZnVuY3Rpb24oYSl7dGhpcy5kPXRoaXMuJHRpLkMo
+IjE/IikuYShhKX0sCiRpQW46MX0KSC5pMS5wcm90b3R5cGU9ewpnbTpmdW5jdGlvbihhKXt2YXIgcz1I
+LkxoKHRoaXMpCnJldHVybiBuZXcgSC5NSChKLklUKHRoaXMuYSksdGhpcy5iLHMuQygiQDwxPiIpLktx
+KHMuUVsxXSkuQygiTUg8MSwyPiIpKX0sCmdBOmZ1bmN0aW9uKGEpe3JldHVybiBKLkhtKHRoaXMuYSl9
+LApnbDA6ZnVuY3Rpb24oYSl7cmV0dXJuIEoudVUodGhpcy5hKX0sCkU6ZnVuY3Rpb24oYSxiKXtyZXR1
+cm4gdGhpcy5iLiQxKEouR0EodGhpcy5hLGIpKX19CkgueHkucHJvdG90eXBlPXskaWJROjF9CkguTUgu
+cHJvdG90eXBlPXsKRjpmdW5jdGlvbigpe3ZhciBzPXRoaXMscj1zLmIKaWYoci5GKCkpe3Muc0kocy5j
+LiQxKHIuZ2woKSkpCnJldHVybiEwfXMuc0kobnVsbCkKcmV0dXJuITF9LApnbDpmdW5jdGlvbigpe3Jl
+dHVybiB0aGlzLmF9LApzSTpmdW5jdGlvbihhKXt0aGlzLmE9dGhpcy4kdGkuQygiMj8iKS5hKGEpfX0K
+SC5sSi5wcm90b3R5cGU9ewpnQTpmdW5jdGlvbihhKXtyZXR1cm4gSi5IbSh0aGlzLmEpfSwKRTpmdW5j
+dGlvbihhLGIpe3JldHVybiB0aGlzLmIuJDEoSi5HQSh0aGlzLmEsYikpfX0KSC5VNS5wcm90b3R5cGU9
+ewpnbTpmdW5jdGlvbihhKXtyZXR1cm4gbmV3IEguU08oSi5JVCh0aGlzLmEpLHRoaXMuYix0aGlzLiR0
+aS5DKCJTTzwxPiIpKX19CkguU08ucHJvdG90eXBlPXsKRjpmdW5jdGlvbigpe3ZhciBzLHIKZm9yKHM9
+dGhpcy5hLHI9dGhpcy5iO3MuRigpOylpZihILm9UKHIuJDEocy5nbCgpKSkpcmV0dXJuITAKcmV0dXJu
+ITF9LApnbDpmdW5jdGlvbigpe3JldHVybiB0aGlzLmEuZ2woKX19CkguQU0ucHJvdG90eXBlPXsKZVI6
+ZnVuY3Rpb24oYSxiKXtQLk1SKGIsImNvdW50Iix0LlMpClAuazEoYiwiY291bnQiKQpyZXR1cm4gbmV3
+IEguQU0odGhpcy5hLHRoaXMuYitiLEguTGgodGhpcykuQygiQU08MT4iKSl9LApnbTpmdW5jdGlvbihh
+KXtyZXR1cm4gbmV3IEguVTEoSi5JVCh0aGlzLmEpLHRoaXMuYixILkxoKHRoaXMpLkMoIlUxPDE+Iikp
+fX0KSC5kNS5wcm90b3R5cGU9ewpnQTpmdW5jdGlvbihhKXt2YXIgcz1KLkhtKHRoaXMuYSktdGhpcy5i
+CmlmKHM+PTApcmV0dXJuIHMKcmV0dXJuIDB9LAplUjpmdW5jdGlvbihhLGIpe1AuTVIoYiwiY291bnQi
+LHQuUykKUC5rMShiLCJjb3VudCIpCnJldHVybiBuZXcgSC5kNSh0aGlzLmEsdGhpcy5iK2IsdGhpcy4k
+dGkpfSwKJGliUToxfQpILlUxLnByb3RvdHlwZT17CkY6ZnVuY3Rpb24oKXt2YXIgcyxyCmZvcihzPXRo
+aXMuYSxyPTA7cjx0aGlzLmI7KytyKXMuRigpCnRoaXMuYj0wCnJldHVybiBzLkYoKX0sCmdsOmZ1bmN0
+aW9uKCl7cmV0dXJuIHRoaXMuYS5nbCgpfX0KSC5NQi5wcm90b3R5cGU9ewpnbTpmdW5jdGlvbihhKXty
+ZXR1cm4gQy5Hd30sCmdsMDpmdW5jdGlvbihhKXtyZXR1cm4hMH0sCmdBOmZ1bmN0aW9uKGEpe3JldHVy
+biAwfSwKRTpmdW5jdGlvbihhLGIpe3Rocm93IEguYihQLlRFKGIsMCwwLCJpbmRleCIsbnVsbCkpfSwK
+ZVI6ZnVuY3Rpb24oYSxiKXtQLmsxKGIsImNvdW50IikKcmV0dXJuIHRoaXN9fQpILkZ1LnByb3RvdHlw
+ZT17CkY6ZnVuY3Rpb24oKXtyZXR1cm4hMX0sCmdsOmZ1bmN0aW9uKCl7dGhyb3cgSC5iKEguV3AoKSl9
+LAokaUFuOjF9CkgudTYucHJvdG90eXBlPXsKZ206ZnVuY3Rpb24oYSl7cmV0dXJuIG5ldyBILkpCKEou
+SVQodGhpcy5hKSx0aGlzLiR0aS5DKCJKQjwxPiIpKX19CkguSkIucHJvdG90eXBlPXsKRjpmdW5jdGlv
+bigpe3ZhciBzLHIKZm9yKHM9dGhpcy5hLHI9dGhpcy4kdGkuYztzLkYoKTspaWYoci5iKHMuZ2woKSkp
+cmV0dXJuITAKcmV0dXJuITF9LApnbDpmdW5jdGlvbigpe3JldHVybiB0aGlzLiR0aS5jLmEodGhpcy5h
+LmdsKCkpfSwKJGlBbjoxfQpILlNVLnByb3RvdHlwZT17fQpILlJlLnByb3RvdHlwZT17Clk1OmZ1bmN0
+aW9uKGEsYixjKXtILkxoKHRoaXMpLkMoIlJlLkUiKS5hKGMpCnRocm93IEguYihQLkw0KCJDYW5ub3Qg
+bW9kaWZ5IGFuIHVubW9kaWZpYWJsZSBsaXN0IikpfX0KSC53Mi5wcm90b3R5cGU9e30KSC53di5wcm90
+b3R5cGU9ewpnaU86ZnVuY3Rpb24oYSl7dmFyIHM9dGhpcy5faGFzaENvZGUKaWYocyE9bnVsbClyZXR1
+cm4gcwpzPTY2NDU5NypKLmhmKHRoaXMuYSkmNTM2ODcwOTExCnRoaXMuX2hhc2hDb2RlPXMKcmV0dXJu
+IHN9LAp3OmZ1bmN0aW9uKGEpe3JldHVybidTeW1ib2woIicrSC5Faih0aGlzLmEpKyciKSd9LApETjpm
+dW5jdGlvbihhLGIpe2lmKGI9PW51bGwpcmV0dXJuITEKcmV0dXJuIGIgaW5zdGFuY2VvZiBILnd2JiZ0
+aGlzLmE9PWIuYX0sCiRpR0Q6MX0KSC5RQy5wcm90b3R5cGU9e30KSC5QRC5wcm90b3R5cGU9e30KSC5X
+VS5wcm90b3R5cGU9ewpnbDA6ZnVuY3Rpb24oYSl7cmV0dXJuIHRoaXMuZ0EodGhpcyk9PT0wfSwKdzpm
+dW5jdGlvbihhKXtyZXR1cm4gUC5uTyh0aGlzKX0sClk1OmZ1bmN0aW9uKGEsYixjKXt2YXIgcz1ILkxo
+KHRoaXMpCnMuYy5hKGIpCnMuUVsxXS5hKGMpCkguZGMoKQpILkJpKHUuZyl9LApnUHU6ZnVuY3Rpb24o
+YSl7cmV0dXJuIHRoaXMucTQoYSxILkxoKHRoaXMpLkMoIk4zPDEsMj4iKSl9LApxNDpmdW5jdGlvbihh
+LGIpe3ZhciBzPXRoaXMKcmV0dXJuIFAubDAoZnVuY3Rpb24oKXt2YXIgcj1hCnZhciBxPTAscD0xLG8s
+bixtLGwsawpyZXR1cm4gZnVuY3Rpb24gJGFzeW5jJGdQdShjLGQpe2lmKGM9PT0xKXtvPWQKcT1wfXdo
+aWxlKHRydWUpc3dpdGNoKHEpe2Nhc2UgMDpuPXMuZ3ZjKCksbj1uLmdtKG4pLG09SC5MaChzKSxtPW0u
+QygiQDwxPiIpLktxKG0uUVsxXSkuQygiTjM8MSwyPiIpCmNhc2UgMjppZighbi5GKCkpe3E9MwpicmVh
+a31sPW4uZ2woKQprPXMucSgwLGwpCmsudG9TdHJpbmcKcT00CnJldHVybiBuZXcgUC5OMyhsLGssbSkK
+Y2FzZSA0OnE9MgpicmVhawpjYXNlIDM6cmV0dXJuIFAuVGgoKQpjYXNlIDE6cmV0dXJuIFAuWW0obyl9
+fX0sYil9LAokaVowOjF9CkguTFAucHJvdG90eXBlPXsKZ0E6ZnVuY3Rpb24oYSl7cmV0dXJuIHRoaXMu
+YX0sCng0OmZ1bmN0aW9uKGEpe2lmKHR5cGVvZiBhIT0ic3RyaW5nIilyZXR1cm4hMQppZigiX19wcm90
+b19fIj09PWEpcmV0dXJuITEKcmV0dXJuIHRoaXMuYi5oYXNPd25Qcm9wZXJ0eShhKX0sCnE6ZnVuY3Rp
+b24oYSxiKXtpZighdGhpcy54NChiKSlyZXR1cm4gbnVsbApyZXR1cm4gdGhpcy5xUChiKX0sCnFQOmZ1
+bmN0aW9uKGEpe3JldHVybiB0aGlzLmJbSC5oKGEpXX0sCks6ZnVuY3Rpb24oYSxiKXt2YXIgcyxyLHEs
+cCxvPUguTGgodGhpcykKby5DKCJ+KDEsMikiKS5hKGIpCnM9dGhpcy5jCmZvcihyPXMubGVuZ3RoLG89
+by5RWzFdLHE9MDtxPHI7KytxKXtwPXNbcV0KYi4kMihwLG8uYSh0aGlzLnFQKHApKSl9fSwKZ3ZjOmZ1
+bmN0aW9uKCl7cmV0dXJuIG5ldyBILlhSKHRoaXMsSC5MaCh0aGlzKS5DKCJYUjwxPiIpKX19CkguWFIu
+cHJvdG90eXBlPXsKZ206ZnVuY3Rpb24oYSl7dmFyIHM9dGhpcy5hLmMKcmV0dXJuIG5ldyBKLm0xKHMs
+cy5sZW5ndGgsSC50NihzKS5DKCJtMTwxPiIpKX0sCmdBOmZ1bmN0aW9uKGEpe3JldHVybiB0aGlzLmEu
+Yy5sZW5ndGh9fQpILkxJLnByb3RvdHlwZT17CmdXYTpmdW5jdGlvbigpe3ZhciBzPXRoaXMuYQpyZXR1
+cm4gc30sCmduZDpmdW5jdGlvbigpe3ZhciBzLHIscSxwLG89dGhpcwppZihvLmM9PT0xKXJldHVybiBD
+LmhVCnM9by5kCnI9cy5sZW5ndGgtby5lLmxlbmd0aC1vLmYKaWYocj09PTApcmV0dXJuIEMuaFUKcT1b
+XQpmb3IocD0wO3A8cjsrK3Ape2lmKHA+PXMubGVuZ3RoKXJldHVybiBILk9IKHMscCkKcS5wdXNoKHNb
+cF0pfXJldHVybiBKLnpDKHEpfSwKZ1ZtOmZ1bmN0aW9uKCl7dmFyIHMscixxLHAsbyxuLG0sbCxrPXRo
+aXMKaWYoay5jIT09MClyZXR1cm4gQy5XTwpzPWsuZQpyPXMubGVuZ3RoCnE9ay5kCnA9cS5sZW5ndGgt
+ci1rLmYKaWYocj09PTApcmV0dXJuIEMuV08Kbz1uZXcgSC5ONSh0LmVvKQpmb3Iobj0wO248cjsrK24p
+e2lmKG4+PXMubGVuZ3RoKXJldHVybiBILk9IKHMsbikKbT1zW25dCmw9cCtuCmlmKGw8MHx8bD49cS5s
+ZW5ndGgpcmV0dXJuIEguT0gocSxsKQpvLlk1KDAsbmV3IEgud3YobSkscVtsXSl9cmV0dXJuIG5ldyBI
+LlBEKG8sdC5nRil9LAokaXZROjF9CkguQ2oucHJvdG90eXBlPXsKJDI6ZnVuY3Rpb24oYSxiKXt2YXIg
+cwpILmgoYSkKcz10aGlzLmEKcy5iPXMuYisiJCIrSC5FaihhKQpDLk5tLmkodGhpcy5iLGEpCkMuTm0u
+aSh0aGlzLmMsYik7KytzLmF9LAokUzoxMn0KSC5mOS5wcm90b3R5cGU9ewpxUzpmdW5jdGlvbihhKXt2
+YXIgcyxyLHE9dGhpcyxwPW5ldyBSZWdFeHAocS5hKS5leGVjKGEpCmlmKHA9PW51bGwpcmV0dXJuIG51
+bGwKcz1PYmplY3QuY3JlYXRlKG51bGwpCnI9cS5iCmlmKHIhPT0tMSlzLmFyZ3VtZW50cz1wW3IrMV0K
+cj1xLmMKaWYociE9PS0xKXMuYXJndW1lbnRzRXhwcj1wW3IrMV0Kcj1xLmQKaWYociE9PS0xKXMuZXhw
+cj1wW3IrMV0Kcj1xLmUKaWYociE9PS0xKXMubWV0aG9kPXBbcisxXQpyPXEuZgppZihyIT09LTEpcy5y
+ZWNlaXZlcj1wW3IrMV0KcmV0dXJuIHN9fQpILlcwLnByb3RvdHlwZT17Cnc6ZnVuY3Rpb24oYSl7dmFy
+IHM9dGhpcy5iCmlmKHM9PW51bGwpcmV0dXJuIk5vU3VjaE1ldGhvZEVycm9yOiAiK0guRWoodGhpcy5h
+KQpyZXR1cm4iTm9TdWNoTWV0aG9kRXJyb3I6IG1ldGhvZCBub3QgZm91bmQ6ICciK3MrIicgb24gbnVs
+bCJ9fQpILmF6LnByb3RvdHlwZT17Cnc6ZnVuY3Rpb24oYSl7dmFyIHMscj10aGlzLHE9Ik5vU3VjaE1l
+dGhvZEVycm9yOiBtZXRob2Qgbm90IGZvdW5kOiAnIixwPXIuYgppZihwPT1udWxsKXJldHVybiJOb1N1
+Y2hNZXRob2RFcnJvcjogIitILkVqKHIuYSkKcz1yLmMKaWYocz09bnVsbClyZXR1cm4gcStwKyInICgi
+K0guRWooci5hKSsiKSIKcmV0dXJuIHErcCsiJyBvbiAnIitzKyInICgiK0guRWooci5hKSsiKSJ9fQpI
+LnZWLnByb3RvdHlwZT17Cnc6ZnVuY3Rpb24oYSl7dmFyIHM9dGhpcy5hCnJldHVybiBzLmxlbmd0aD09
+PTA/IkVycm9yIjoiRXJyb3I6ICIrc319CkgudGUucHJvdG90eXBlPXsKdzpmdW5jdGlvbihhKXtyZXR1
+cm4iVGhyb3cgb2YgbnVsbCAoJyIrKHRoaXMuYT09PW51bGw/Im51bGwiOiJ1bmRlZmluZWQiKSsiJyBm
+cm9tIEphdmFTY3JpcHQpIn0sCiRpUno6MX0KSC5icS5wcm90b3R5cGU9e30KSC5YTy5wcm90b3R5cGU9
+ewp3OmZ1bmN0aW9uKGEpe3ZhciBzLHI9dGhpcy5iCmlmKHIhPW51bGwpcmV0dXJuIHIKcj10aGlzLmEK
+cz1yIT09bnVsbCYmdHlwZW9mIHI9PT0ib2JqZWN0Ij9yLnN0YWNrOm51bGwKcmV0dXJuIHRoaXMuYj1z
+PT1udWxsPyIiOnN9LAokaUd6OjF9CkguVHAucHJvdG90eXBlPXsKdzpmdW5jdGlvbihhKXt2YXIgcz10
+aGlzLmNvbnN0cnVjdG9yLHI9cz09bnVsbD9udWxsOnMubmFtZQpyZXR1cm4iQ2xvc3VyZSAnIitILk5R
+KHI9PW51bGw/InVua25vd24iOnIpKyInIn0sCiRpRUg6MSwKZ0t1OmZ1bmN0aW9uKCl7cmV0dXJuIHRo
+aXN9LAokQzoiJDEiLAokUjoxLAokRDpudWxsfQpILmxjLnByb3RvdHlwZT17fQpILnp4LnByb3RvdHlw
+ZT17Cnc6ZnVuY3Rpb24oYSl7dmFyIHM9dGhpcy4kc3RhdGljX25hbWUKaWYocz09bnVsbClyZXR1cm4i
+Q2xvc3VyZSBvZiB1bmtub3duIHN0YXRpYyBtZXRob2QiCnJldHVybiJDbG9zdXJlICciK0guTlEocykr
+IicifX0KSC5yVC5wcm90b3R5cGU9ewpETjpmdW5jdGlvbihhLGIpe3ZhciBzPXRoaXMKaWYoYj09bnVs
+bClyZXR1cm4hMQppZihzPT09YilyZXR1cm4hMAppZighKGIgaW5zdGFuY2VvZiBILnJUKSlyZXR1cm4h
+MQpyZXR1cm4gcy5hPT09Yi5hJiZzLmI9PT1iLmImJnMuYz09PWIuY30sCmdpTzpmdW5jdGlvbihhKXt2
+YXIgcyxyPXRoaXMuYwppZihyPT1udWxsKXM9SC5lUSh0aGlzLmEpCmVsc2Ugcz10eXBlb2YgciE9PSJv
+YmplY3QiP0ouaGYocik6SC5lUShyKQpyPUguZVEodGhpcy5iKQppZih0eXBlb2YgcyE9PSJudW1iZXIi
+KXJldHVybiBzLlkoKQpyZXR1cm4oc15yKT4+PjB9LAp3OmZ1bmN0aW9uKGEpe3ZhciBzPXRoaXMuYwpp
+ZihzPT1udWxsKXM9dGhpcy5hCnJldHVybiJDbG9zdXJlICciK0guRWoodGhpcy5kKSsiJyBvZiAiKygi
+SW5zdGFuY2Ugb2YgJyIrSC5FaihILk0ocykpKyInIil9fQpILkVxLnByb3RvdHlwZT17Cnc6ZnVuY3Rp
+b24oYSl7cmV0dXJuIlJ1bnRpbWVFcnJvcjogIit0aGlzLmF9fQpILmtZLnByb3RvdHlwZT17Cnc6ZnVu
+Y3Rpb24oYSl7cmV0dXJuIkFzc2VydGlvbiBmYWlsZWQ6ICIrUC5wKHRoaXMuYSl9fQpILmtyLnByb3Rv
+dHlwZT17fQpILk41LnByb3RvdHlwZT17CmdBOmZ1bmN0aW9uKGEpe3JldHVybiB0aGlzLmF9LApnbDA6
+ZnVuY3Rpb24oYSl7cmV0dXJuIHRoaXMuYT09PTB9LApndmM6ZnVuY3Rpb24oKXtyZXR1cm4gbmV3IEgu
+aTUodGhpcyxILkxoKHRoaXMpLkMoImk1PDE+IikpfSwKeDQ6ZnVuY3Rpb24oYSl7dmFyIHMscgppZih0
+eXBlb2YgYT09InN0cmluZyIpe3M9dGhpcy5iCmlmKHM9PW51bGwpcmV0dXJuITEKcmV0dXJuIHRoaXMu
+WHUocyxhKX1lbHNle3I9dGhpcy5DWChhKQpyZXR1cm4gcn19LApDWDpmdW5jdGlvbihhKXt2YXIgcz10
+aGlzLmQKaWYocz09bnVsbClyZXR1cm4hMQpyZXR1cm4gdGhpcy5GaCh0aGlzLkJ0KHMsSi5oZihhKSYw
+eDNmZmZmZmYpLGEpPj0wfSwKcTpmdW5jdGlvbihhLGIpe3ZhciBzLHIscSxwLG89dGhpcyxuPW51bGwK
+aWYodHlwZW9mIGI9PSJzdHJpbmciKXtzPW8uYgppZihzPT1udWxsKXJldHVybiBuCnI9by5qMihzLGIp
+CnE9cj09bnVsbD9uOnIuYgpyZXR1cm4gcX1lbHNlIGlmKHR5cGVvZiBiPT0ibnVtYmVyIiYmKGImMHgz
+ZmZmZmZmKT09PWIpe3A9by5jCmlmKHA9PW51bGwpcmV0dXJuIG4Kcj1vLmoyKHAsYikKcT1yPT1udWxs
+P246ci5iCnJldHVybiBxfWVsc2UgcmV0dXJuIG8uYWEoYil9LAphYTpmdW5jdGlvbihhKXt2YXIgcyxy
+LHE9dGhpcy5kCmlmKHE9PW51bGwpcmV0dXJuIG51bGwKcz10aGlzLkJ0KHEsSi5oZihhKSYweDNmZmZm
+ZmYpCnI9dGhpcy5GaChzLGEpCmlmKHI8MClyZXR1cm4gbnVsbApyZXR1cm4gc1tyXS5ifSwKWTU6ZnVu
+Y3Rpb24oYSxiLGMpe3ZhciBzLHIscSxwLG8sbixtPXRoaXMsbD1ILkxoKG0pCmwuYy5hKGIpCmwuUVsx
+XS5hKGMpCmlmKHR5cGVvZiBiPT0ic3RyaW5nIil7cz1tLmIKbS5FSChzPT1udWxsP20uYj1tLnpLKCk6
+cyxiLGMpfWVsc2UgaWYodHlwZW9mIGI9PSJudW1iZXIiJiYoYiYweDNmZmZmZmYpPT09Yil7cj1tLmMK
+bS5FSChyPT1udWxsP20uYz1tLnpLKCk6cixiLGMpfWVsc2V7cT1tLmQKaWYocT09bnVsbClxPW0uZD1t
+LnpLKCkKcD1KLmhmKGIpJjB4M2ZmZmZmZgpvPW0uQnQocSxwKQppZihvPT1udWxsKW0uRUkocSxwLFtt
+LkhuKGIsYyldKQplbHNle249bS5GaChvLGIpCmlmKG4+PTApb1tuXS5iPWMKZWxzZSBvLnB1c2gobS5I
+bihiLGMpKX19fSwKSzpmdW5jdGlvbihhLGIpe3ZhciBzLHIscT10aGlzCkguTGgocSkuQygifigxLDIp
+IikuYShiKQpzPXEuZQpyPXEucgpmb3IoO3MhPW51bGw7KXtiLiQyKHMuYSxzLmIpCmlmKHIhPT1xLnIp
+dGhyb3cgSC5iKFAuYTQocSkpCnM9cy5jfX0sCkVIOmZ1bmN0aW9uKGEsYixjKXt2YXIgcyxyPXRoaXMs
+cT1ILkxoKHIpCnEuYy5hKGIpCnEuUVsxXS5hKGMpCnM9ci5qMihhLGIpCmlmKHM9PW51bGwpci5FSShh
+LGIsci5IbihiLGMpKQplbHNlIHMuYj1jfSwKa3M6ZnVuY3Rpb24oKXt0aGlzLnI9dGhpcy5yKzEmNjcx
+MDg4NjN9LApIbjpmdW5jdGlvbihhLGIpe3ZhciBzPXRoaXMscj1ILkxoKHMpLHE9bmV3IEgudmgoci5j
+LmEoYSksci5RWzFdLmEoYikpCmlmKHMuZT09bnVsbClzLmU9cy5mPXEKZWxzZXtyPXMuZgpyLnRvU3Ry
+aW5nCnEuZD1yCnMuZj1yLmM9cX0rK3MuYQpzLmtzKCkKcmV0dXJuIHF9LApGaDpmdW5jdGlvbihhLGIp
+e3ZhciBzLHIKaWYoYT09bnVsbClyZXR1cm4tMQpzPWEubGVuZ3RoCmZvcihyPTA7cjxzOysrcilpZihK
+LlJNKGFbcl0uYSxiKSlyZXR1cm4gcgpyZXR1cm4tMX0sCnc6ZnVuY3Rpb24oYSl7cmV0dXJuIFAubk8o
+dGhpcyl9LApqMjpmdW5jdGlvbihhLGIpe3JldHVybiBhW2JdfSwKQnQ6ZnVuY3Rpb24oYSxiKXtyZXR1
+cm4gYVtiXX0sCkVJOmZ1bmN0aW9uKGEsYixjKXthW2JdPWN9LApybjpmdW5jdGlvbihhLGIpe2RlbGV0
+ZSBhW2JdfSwKWHU6ZnVuY3Rpb24oYSxiKXtyZXR1cm4gdGhpcy5qMihhLGIpIT1udWxsfSwKeks6ZnVu
+Y3Rpb24oKXt2YXIgcz0iPG5vbi1pZGVudGlmaWVyLWtleT4iLHI9T2JqZWN0LmNyZWF0ZShudWxsKQp0
+aGlzLkVJKHIscyxyKQp0aGlzLnJuKHIscykKcmV0dXJuIHJ9LAokaUZvOjF9CkgudmgucHJvdG90eXBl
+PXt9CkguaTUucHJvdG90eXBlPXsKZ0E6ZnVuY3Rpb24oYSl7cmV0dXJuIHRoaXMuYS5hfSwKZ2wwOmZ1
+bmN0aW9uKGEpe3JldHVybiB0aGlzLmEuYT09PTB9LApnbTpmdW5jdGlvbihhKXt2YXIgcz10aGlzLmEs
+cj1uZXcgSC5ONihzLHMucix0aGlzLiR0aS5DKCJONjwxPiIpKQpyLmM9cy5lCnJldHVybiByfSwKdGc6
+ZnVuY3Rpb24oYSxiKXtyZXR1cm4gdGhpcy5hLng0KGIpfX0KSC5ONi5wcm90b3R5cGU9ewpnbDpmdW5j
+dGlvbigpe3JldHVybiB0aGlzLmR9LApGOmZ1bmN0aW9uKCl7dmFyIHMscj10aGlzLHE9ci5hCmlmKHIu
+YiE9PXEucil0aHJvdyBILmIoUC5hNChxKSkKcz1yLmMKaWYocz09bnVsbCl7ci5zcVkobnVsbCkKcmV0
+dXJuITF9ZWxzZXtyLnNxWShzLmEpCnIuYz1zLmMKcmV0dXJuITB9fSwKc3FZOmZ1bmN0aW9uKGEpe3Ro
+aXMuZD10aGlzLiR0aS5DKCIxPyIpLmEoYSl9LAokaUFuOjF9CkguZEMucHJvdG90eXBlPXsKJDE6ZnVu
+Y3Rpb24oYSl7cmV0dXJuIHRoaXMuYShhKX0sCiRTOjR9Ckgud04ucHJvdG90eXBlPXsKJDI6ZnVuY3Rp
+b24oYSxiKXtyZXR1cm4gdGhpcy5hKGEsYil9LAokUzo0Nn0KSC5WWC5wcm90b3R5cGU9ewokMTpmdW5j
+dGlvbihhKXtyZXR1cm4gdGhpcy5hKEguaChhKSl9LAokUzo0MX0KSC5WUi5wcm90b3R5cGU9ewp3OmZ1
+bmN0aW9uKGEpe3JldHVybiJSZWdFeHAvIit0aGlzLmErIi8iK3RoaXMuYi5mbGFnc30sCmdIYzpmdW5j
+dGlvbigpe3ZhciBzPXRoaXMscj1zLmMKaWYociE9bnVsbClyZXR1cm4gcgpyPXMuYgpyZXR1cm4gcy5j
+PUgudjQocy5hLHIubXVsdGlsaW5lLCFyLmlnbm9yZUNhc2Usci51bmljb2RlLHIuZG90QWxsLCEwKX0s
+CmRkOmZ1bmN0aW9uKGEsYil7cmV0dXJuIG5ldyBILktXKHRoaXMsYiwwKX0sClVaOmZ1bmN0aW9uKGEs
+Yil7dmFyIHMscj10aGlzLmdIYygpCnIubGFzdEluZGV4PWIKcz1yLmV4ZWMoYSkKaWYocz09bnVsbCly
+ZXR1cm4gbnVsbApyZXR1cm4gbmV3IEguRUsocyl9LAokaXZYOjEsCiRpd0w6MX0KSC5FSy5wcm90b3R5
+cGU9ewpxOmZ1bmN0aW9uKGEsYil7dmFyIHMKSC51UChiKQpzPXRoaXMuYgppZihiPj1zLmxlbmd0aCly
+ZXR1cm4gSC5PSChzLGIpCnJldHVybiBzW2JdfSwKJGlPZDoxLAokaWliOjF9CkguS1cucHJvdG90eXBl
+PXsKZ206ZnVuY3Rpb24oYSl7cmV0dXJuIG5ldyBILlBiKHRoaXMuYSx0aGlzLmIsdGhpcy5jKX19Ckgu
+UGIucHJvdG90eXBlPXsKZ2w6ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5kfSwKRjpmdW5jdGlvbigpe3Zh
+ciBzLHIscSxwLG8sbixtPXRoaXMsbD1tLmIKaWYobD09bnVsbClyZXR1cm4hMQpzPW0uYwpyPWwubGVu
+Z3RoCmlmKHM8PXIpe3E9bS5hCnA9cS5VWihsLHMpCmlmKHAhPW51bGwpe20uZD1wCnM9cC5iCm89cy5p
+bmRleApuPW8rc1swXS5sZW5ndGgKaWYobz09PW4pe2lmKHEuYi51bmljb2RlKXtzPW0uYwpxPXMrMQpp
+ZihxPHIpe3M9Qy54Qi5PMihsLHMpCmlmKHM+PTU1Mjk2JiZzPD01NjMxOSl7cz1DLnhCLk8yKGwscSkK
+cz1zPj01NjMyMCYmczw9NTczNDN9ZWxzZSBzPSExfWVsc2Ugcz0hMX1lbHNlIHM9ITEKbj0ocz9uKzE6
+bikrMX1tLmM9bgpyZXR1cm4hMH19bS5iPW0uZD1udWxsCnJldHVybiExfSwKJGlBbjoxfQpILnRRLnBy
+b3RvdHlwZT17CnE6ZnVuY3Rpb24oYSxiKXtILnVQKGIpCmlmKGIhPT0wKUgudihQLk83KGIsbnVsbCkp
+CnJldHVybiB0aGlzLmN9LAokaU9kOjF9CkgudW4ucHJvdG90eXBlPXsKZ206ZnVuY3Rpb24oYSl7cmV0
+dXJuIG5ldyBILlNkKHRoaXMuYSx0aGlzLmIsdGhpcy5jKX19CkguU2QucHJvdG90eXBlPXsKRjpmdW5j
+dGlvbigpe3ZhciBzLHIscT10aGlzLHA9cS5jLG89cS5iLG49by5sZW5ndGgsbT1xLmEsbD1tLmxlbmd0
+aAppZihwK24+bCl7cS5kPW51bGwKcmV0dXJuITF9cz1tLmluZGV4T2YobyxwKQppZihzPDApe3EuYz1s
+KzEKcS5kPW51bGwKcmV0dXJuITF9cj1zK24KcS5kPW5ldyBILnRRKHMsbykKcS5jPXI9PT1xLmM/cisx
+OnIKcmV0dXJuITB9LApnbDpmdW5jdGlvbigpe3ZhciBzPXRoaXMuZApzLnRvU3RyaW5nCnJldHVybiBz
+fSwKJGlBbjoxfQpILkVULnByb3RvdHlwZT17JGlFVDoxLCRpQVM6MX0KSC5MWi5wcm90b3R5cGU9ewpn
+QTpmdW5jdGlvbihhKXtyZXR1cm4gYS5sZW5ndGh9LAokaVhqOjF9CkguRGcucHJvdG90eXBlPXsKcTpm
+dW5jdGlvbihhLGIpe0gudVAoYikKSC5vZChiLGEsYS5sZW5ndGgpCnJldHVybiBhW2JdfSwKWTU6ZnVu
+Y3Rpb24oYSxiLGMpe0guR0goYykKSC5vZChiLGEsYS5sZW5ndGgpCmFbYl09Y30sCiRpYlE6MSwKJGlj
+WDoxLAokaXpNOjF9CkguUGcucHJvdG90eXBlPXsKWTU6ZnVuY3Rpb24oYSxiLGMpe0gudVAoYykKSC5v
+ZChiLGEsYS5sZW5ndGgpCmFbYl09Y30sCiRpYlE6MSwKJGljWDoxLAokaXpNOjF9CkgueGoucHJvdG90
+eXBlPXsKcTpmdW5jdGlvbihhLGIpe0gudVAoYikKSC5vZChiLGEsYS5sZW5ndGgpCnJldHVybiBhW2Jd
+fX0KSC5kRS5wcm90b3R5cGU9ewpxOmZ1bmN0aW9uKGEsYil7SC51UChiKQpILm9kKGIsYSxhLmxlbmd0
+aCkKcmV0dXJuIGFbYl19fQpILlpBLnByb3RvdHlwZT17CnE6ZnVuY3Rpb24oYSxiKXtILnVQKGIpCkgu
+b2QoYixhLGEubGVuZ3RoKQpyZXR1cm4gYVtiXX19CkguZFQucHJvdG90eXBlPXsKcTpmdW5jdGlvbihh
+LGIpe0gudVAoYikKSC5vZChiLGEsYS5sZW5ndGgpCnJldHVybiBhW2JdfX0KSC5QcS5wcm90b3R5cGU9
+ewpxOmZ1bmN0aW9uKGEsYil7SC51UChiKQpILm9kKGIsYSxhLmxlbmd0aCkKcmV0dXJuIGFbYl19fQpI
+LmVFLnByb3RvdHlwZT17CmdBOmZ1bmN0aW9uKGEpe3JldHVybiBhLmxlbmd0aH0sCnE6ZnVuY3Rpb24o
+YSxiKXtILnVQKGIpCkgub2QoYixhLGEubGVuZ3RoKQpyZXR1cm4gYVtiXX19CkguVjYucHJvdG90eXBl
+PXsKZ0E6ZnVuY3Rpb24oYSl7cmV0dXJuIGEubGVuZ3RofSwKcTpmdW5jdGlvbihhLGIpe0gudVAoYikK
+SC5vZChiLGEsYS5sZW5ndGgpCnJldHVybiBhW2JdfSwKJGlWNjoxLAokaW42OjF9CkguUkcucHJvdG90
+eXBlPXt9CkguVlAucHJvdG90eXBlPXt9CkguV0IucHJvdG90eXBlPXt9CkguWkcucHJvdG90eXBlPXt9
+CkguSmMucHJvdG90eXBlPXsKQzpmdW5jdGlvbihhKXtyZXR1cm4gSC5jRSh2LnR5cGVVbml2ZXJzZSx0
+aGlzLGEpfSwKS3E6ZnVuY3Rpb24oYSl7cmV0dXJuIEgudjUodi50eXBlVW5pdmVyc2UsdGhpcyxhKX19
+CkguRy5wcm90b3R5cGU9e30KSC5sWS5wcm90b3R5cGU9ewp3OmZ1bmN0aW9uKGEpe3JldHVybiBILmRt
+KHRoaXMuYSxudWxsKX19Ckgua1MucHJvdG90eXBlPXsKdzpmdW5jdGlvbihhKXtyZXR1cm4gdGhpcy5h
+fX0KSC5pTS5wcm90b3R5cGU9e30KUC50aC5wcm90b3R5cGU9ewokMTpmdW5jdGlvbihhKXt2YXIgcz10
+aGlzLmEscj1zLmEKcy5hPW51bGwKci4kMCgpfSwKJFM6OX0KUC5oYS5wcm90b3R5cGU9ewokMTpmdW5j
+dGlvbihhKXt2YXIgcyxyCnRoaXMuYS5hPXQuTS5hKGEpCnM9dGhpcy5iCnI9dGhpcy5jCnMuZmlyc3RD
+aGlsZD9zLnJlbW92ZUNoaWxkKHIpOnMuYXBwZW5kQ2hpbGQocil9LAokUzozNH0KUC5Wcy5wcm90b3R5
+cGU9ewokMDpmdW5jdGlvbigpe3RoaXMuYS4kMCgpfSwKJEM6IiQwIiwKJFI6MCwKJFM6Mn0KUC5GdC5w
+cm90b3R5cGU9ewokMDpmdW5jdGlvbigpe3RoaXMuYS4kMCgpfSwKJEM6IiQwIiwKJFI6MCwKJFM6Mn0K
+UC5XMy5wcm90b3R5cGU9ewpDWTpmdW5jdGlvbihhLGIpe2lmKHNlbGYuc2V0VGltZW91dCE9bnVsbClz
+ZWxmLnNldFRpbWVvdXQoSC50UihuZXcgUC55SCh0aGlzLGIpLDApLGEpCmVsc2UgdGhyb3cgSC5iKFAu
+TDQoImBzZXRUaW1lb3V0KClgIG5vdCBmb3VuZC4iKSl9fQpQLnlILnByb3RvdHlwZT17CiQwOmZ1bmN0
+aW9uKCl7dGhpcy5iLiQwKCl9LAokQzoiJDAiLAokUjowLAokUzowfQpQLmloLnByb3RvdHlwZT17CmFN
+OmZ1bmN0aW9uKGEsYil7dmFyIHMscj10aGlzLHE9ci4kdGkKcS5DKCIxLz8iKS5hKGIpCmlmKCFyLmIp
+ci5hLlhmKGIpCmVsc2V7cz1yLmEKaWYocS5DKCJiODwxPiIpLmIoYikpcy5jVShiKQplbHNlIHMuWDIo
+cS5jLmEoYikpfX0sCncwOmZ1bmN0aW9uKGEsYil7dmFyIHMKaWYoYj09bnVsbCliPVAudjAoYSkKcz10
+aGlzLmEKaWYodGhpcy5iKXMuWkwoYSxiKQplbHNlIHMuTmsoYSxiKX19ClAuV00ucHJvdG90eXBlPXsK
+JDE6ZnVuY3Rpb24oYSl7cmV0dXJuIHRoaXMuYS4kMigwLGEpfSwKJFM6NTJ9ClAuU1gucHJvdG90eXBl
+PXsKJDI6ZnVuY3Rpb24oYSxiKXt0aGlzLmEuJDIoMSxuZXcgSC5icShhLHQubC5hKGIpKSl9LAokQzoi
+JDIiLAokUjoyLAokUzoyNH0KUC5Hcy5wcm90b3R5cGU9ewokMjpmdW5jdGlvbihhLGIpe3RoaXMuYShI
+LnVQKGEpLGIpfSwKJFM6MjZ9ClAuRnkucHJvdG90eXBlPXsKdzpmdW5jdGlvbihhKXtyZXR1cm4iSXRl
+cmF0aW9uTWFya2VyKCIrdGhpcy5iKyIsICIrSC5Faih0aGlzLmEpKyIpIn19ClAuR1YucHJvdG90eXBl
+PXsKZ2w6ZnVuY3Rpb24oKXt2YXIgcz10aGlzLmMKaWYocz09bnVsbClyZXR1cm4gdGhpcy4kdGkuYy5h
+KHRoaXMuYikKcmV0dXJuIHMuZ2woKX0sCkY6ZnVuY3Rpb24oKXt2YXIgcyxyLHEscCxvLG4sbT10aGlz
+CmZvcihzPW0uJHRpLkMoIkFuPDE+Iik7ITA7KXtyPW0uYwppZihyIT1udWxsKWlmKHIuRigpKXJldHVy
+biEwCmVsc2UgbS5zWDkobnVsbCkKcT1mdW5jdGlvbihhLGIsYyl7dmFyIGwsaz1iCndoaWxlKHRydWUp
+dHJ5e3JldHVybiBhKGssbCl9Y2F0Y2goail7bD1qCms9Y319KG0uYSwwLDEpCmlmKHEgaW5zdGFuY2Vv
+ZiBQLkZ5KXtwPXEuYgppZihwPT09Mil7bz1tLmQKaWYobz09bnVsbHx8by5sZW5ndGg9PT0wKXttLnNF
+QyhudWxsKQpyZXR1cm4hMX1pZigwPj1vLmxlbmd0aClyZXR1cm4gSC5PSChvLC0xKQptLmE9by5wb3Ao
+KQpjb250aW51ZX1lbHNle3I9cS5hCmlmKHA9PT0zKXRocm93IHIKZWxzZXtuPXMuYShKLklUKHIpKQpp
+ZihuIGluc3RhbmNlb2YgUC5HVil7cj1tLmQKaWYocj09bnVsbClyPW0uZD1bXQpDLk5tLmkocixtLmEp
+Cm0uYT1uLmEKY29udGludWV9ZWxzZXttLnNYOShuKQpjb250aW51ZX19fX1lbHNle20uc0VDKHEpCnJl
+dHVybiEwfX1yZXR1cm4hMX0sCnNFQzpmdW5jdGlvbihhKXt0aGlzLmI9dGhpcy4kdGkuQygiMT8iKS5h
+KGEpfSwKc1g5OmZ1bmN0aW9uKGEpe3RoaXMuYz10aGlzLiR0aS5DKCJBbjwxPj8iKS5hKGEpfSwKJGlB
+bjoxfQpQLnE0LnByb3RvdHlwZT17CmdtOmZ1bmN0aW9uKGEpe3JldHVybiBuZXcgUC5HVih0aGlzLmEo
+KSx0aGlzLiR0aS5DKCJHVjwxPiIpKX19ClAuUGYucHJvdG90eXBlPXsKdzA6ZnVuY3Rpb24oYSxiKXt2
+YXIgcwpILmNiKGEsImVycm9yIix0LkspCnM9dGhpcy5hCmlmKHMuYSE9PTApdGhyb3cgSC5iKFAuUFYo
+IkZ1dHVyZSBhbHJlYWR5IGNvbXBsZXRlZCIpKQppZihiPT1udWxsKWI9UC52MChhKQpzLk5rKGEsYil9
+LApwbTpmdW5jdGlvbihhKXtyZXR1cm4gdGhpcy53MChhLG51bGwpfX0KUC5aZi5wcm90b3R5cGU9ewph
+TTpmdW5jdGlvbihhLGIpe3ZhciBzLHI9dGhpcy4kdGkKci5DKCIxLz8iKS5hKGIpCnM9dGhpcy5hCmlm
+KHMuYSE9PTApdGhyb3cgSC5iKFAuUFYoIkZ1dHVyZSBhbHJlYWR5IGNvbXBsZXRlZCIpKQpzLlhmKHIu
+QygiMS8iKS5hKGIpKX19ClAuRmUucHJvdG90eXBlPXsKSFI6ZnVuY3Rpb24oYSl7aWYoKHRoaXMuYyYx
+NSkhPT02KXJldHVybiEwCnJldHVybiB0aGlzLmIuYi5idih0LmFsLmEodGhpcy5kKSxhLmEsdC55LHQu
+Syl9LApLdzpmdW5jdGlvbihhKXt2YXIgcz10aGlzLmUscj10LnoscT10LksscD10aGlzLiR0aS5DKCIy
+LyIpLG89dGhpcy5iLmIKaWYodC5hZy5iKHMpKXJldHVybiBwLmEoby5ycChzLGEuYSxhLmIscixxLHQu
+bCkpCmVsc2UgcmV0dXJuIHAuYShvLmJ2KHQuYkkuYShzKSxhLmEscixxKSl9fQpQLnZzLnByb3RvdHlw
+ZT17ClNxOmZ1bmN0aW9uKGEsYixjKXt2YXIgcyxyLHEscD10aGlzLiR0aQpwLktxKGMpLkMoIjEvKDIp
+IikuYShhKQpzPSQuWDMKaWYocyE9PUMuTlUpe2MuQygiQDwwLz4iKS5LcShwLmMpLkMoIjEoMikiKS5h
+KGEpCmlmKGIhPW51bGwpYj1QLlZIKGIscyl9cj1uZXcgUC52cyhzLGMuQygidnM8MD4iKSkKcT1iPT1u
+dWxsPzE6Mwp0aGlzLnhmKG5ldyBQLkZlKHIscSxhLGIscC5DKCJAPDE+IikuS3EoYykuQygiRmU8MSwy
+PiIpKSkKcmV0dXJuIHJ9LApXNzpmdW5jdGlvbihhLGIpe3JldHVybiB0aGlzLlNxKGEsbnVsbCxiKX0s
+ClFkOmZ1bmN0aW9uKGEsYixjKXt2YXIgcyxyPXRoaXMuJHRpCnIuS3EoYykuQygiMS8oMikiKS5hKGEp
+CnM9bmV3IFAudnMoJC5YMyxjLkMoInZzPDA+IikpCnRoaXMueGYobmV3IFAuRmUocywxOSxhLGIsci5D
+KCJAPDE+IikuS3EoYykuQygiRmU8MSwyPiIpKSkKcmV0dXJuIHN9LAp4ZjpmdW5jdGlvbihhKXt2YXIg
+cyxyPXRoaXMscT1yLmEKaWYocTw9MSl7YS5hPXQuRi5hKHIuYykKci5jPWF9ZWxzZXtpZihxPT09Mil7
+cz10LmMuYShyLmMpCnE9cy5hCmlmKHE8NCl7cy54ZihhKQpyZXR1cm59ci5hPXEKci5jPXMuY31QLlRr
+KG51bGwsbnVsbCxyLmIsdC5NLmEobmV3IFAuZGEocixhKSkpfX0sCmpROmZ1bmN0aW9uKGEpe3ZhciBz
+LHIscSxwLG8sbixtPXRoaXMsbD17fQpsLmE9YQppZihhPT1udWxsKXJldHVybgpzPW0uYQppZihzPD0x
+KXtyPXQuRi5hKG0uYykKbS5jPWEKaWYociE9bnVsbCl7cT1hLmEKZm9yKHA9YTtxIT1udWxsO3A9cSxx
+PW8pbz1xLmEKcC5hPXJ9fWVsc2V7aWYocz09PTIpe249dC5jLmEobS5jKQpzPW4uYQppZihzPDQpe24u
+alEoYSkKcmV0dXJufW0uYT1zCm0uYz1uLmN9bC5hPW0uTjgoYSkKUC5UayhudWxsLG51bGwsbS5iLHQu
+TS5hKG5ldyBQLm9RKGwsbSkpKX19LAphaDpmdW5jdGlvbigpe3ZhciBzPXQuRi5hKHRoaXMuYykKdGhp
+cy5jPW51bGwKcmV0dXJuIHRoaXMuTjgocyl9LApOODpmdW5jdGlvbihhKXt2YXIgcyxyLHEKZm9yKHM9
+YSxyPW51bGw7cyE9bnVsbDtyPXMscz1xKXtxPXMuYQpzLmE9cn1yZXR1cm4gcn0sCkhIOmZ1bmN0aW9u
+KGEpe3ZhciBzLHI9dGhpcyxxPXIuJHRpCnEuQygiMS8iKS5hKGEpCmlmKHEuQygiYjg8MT4iKS5iKGEp
+KWlmKHEuYihhKSlQLkE5KGEscikKZWxzZSBQLmszKGEscikKZWxzZXtzPXIuYWgoKQpxLmMuYShhKQpy
+LmE9NApyLmM9YQpQLkhaKHIscyl9fSwKWDI6ZnVuY3Rpb24oYSl7dmFyIHMscj10aGlzCnIuJHRpLmMu
+YShhKQpzPXIuYWgoKQpyLmE9NApyLmM9YQpQLkhaKHIscyl9LApaTDpmdW5jdGlvbihhLGIpe3ZhciBz
+LHIscT10aGlzCnQubC5hKGIpCnM9cS5haCgpCnI9UC5UbChhLGIpCnEuYT04CnEuYz1yClAuSFoocSxz
+KX0sClhmOmZ1bmN0aW9uKGEpe3ZhciBzPXRoaXMuJHRpCnMuQygiMS8iKS5hKGEpCmlmKHMuQygiYjg8
+MT4iKS5iKGEpKXt0aGlzLmNVKGEpCnJldHVybn10aGlzLndVKHMuYy5hKGEpKX0sCndVOmZ1bmN0aW9u
+KGEpe3ZhciBzPXRoaXMKcy4kdGkuYy5hKGEpCnMuYT0xClAuVGsobnVsbCxudWxsLHMuYix0Lk0uYShu
+ZXcgUC5ydChzLGEpKSl9LApjVTpmdW5jdGlvbihhKXt2YXIgcz10aGlzLHI9cy4kdGkKci5DKCJiODwx
+PiIpLmEoYSkKaWYoci5iKGEpKXtpZihhLmE9PT04KXtzLmE9MQpQLlRrKG51bGwsbnVsbCxzLmIsdC5N
+LmEobmV3IFAuS0YocyxhKSkpfWVsc2UgUC5BOShhLHMpCnJldHVybn1QLmszKGEscyl9LApOazpmdW5j
+dGlvbihhLGIpe3RoaXMuYT0xClAuVGsobnVsbCxudWxsLHRoaXMuYix0Lk0uYShuZXcgUC5aTCh0aGlz
+LGEsYikpKX0sCiRpYjg6MX0KUC5kYS5wcm90b3R5cGU9ewokMDpmdW5jdGlvbigpe1AuSFoodGhpcy5h
+LHRoaXMuYil9LAokUzowfQpQLm9RLnByb3RvdHlwZT17CiQwOmZ1bmN0aW9uKCl7UC5IWih0aGlzLmIs
+dGhpcy5hLmEpfSwKJFM6MH0KUC5wVi5wcm90b3R5cGU9ewokMTpmdW5jdGlvbihhKXt2YXIgcz10aGlz
+LmEKcy5hPTAKcy5ISChhKX0sCiRTOjl9ClAuVTcucHJvdG90eXBlPXsKJDI6ZnVuY3Rpb24oYSxiKXt0
+aGlzLmEuWkwoYSx0LmwuYShiKSl9LAokQzoiJDIiLAokUjoyLAokUzoyOX0KUC52ci5wcm90b3R5cGU9
+ewokMDpmdW5jdGlvbigpe3RoaXMuYS5aTCh0aGlzLmIsdGhpcy5jKX0sCiRTOjB9ClAucnQucHJvdG90
+eXBlPXsKJDA6ZnVuY3Rpb24oKXt0aGlzLmEuWDIodGhpcy5iKX0sCiRTOjB9ClAuS0YucHJvdG90eXBl
+PXsKJDA6ZnVuY3Rpb24oKXtQLkE5KHRoaXMuYix0aGlzLmEpfSwKJFM6MH0KUC5aTC5wcm90b3R5cGU9
+ewokMDpmdW5jdGlvbigpe3RoaXMuYS5aTCh0aGlzLmIsdGhpcy5jKX0sCiRTOjB9ClAuUlQucHJvdG90
+eXBlPXsKJDA6ZnVuY3Rpb24oKXt2YXIgcyxyLHEscCxvLG4sbT10aGlzLGw9bnVsbAp0cnl7cT1tLmEu
+YQpsPXEuYi5iLnp6KHQuZk8uYShxLmQpLHQueil9Y2F0Y2gocCl7cz1ILlJ1KHApCnI9SC50cyhwKQpp
+ZihtLmMpe3E9dC5uLmEobS5iLmEuYykuYQpvPXMKbz1xPT1udWxsP289PW51bGw6cT09PW8KcT1vfWVs
+c2UgcT0hMQpvPW0uYQppZihxKW8uYz10Lm4uYShtLmIuYS5jKQplbHNlIG8uYz1QLlRsKHMscikKby5i
+PSEwCnJldHVybn1pZihsIGluc3RhbmNlb2YgUC52cyYmbC5hPj00KXtpZihsLmE9PT04KXtxPW0uYQpx
+LmM9dC5uLmEobC5jKQpxLmI9ITB9cmV0dXJufWlmKHQuZC5iKGwpKXtuPW0uYi5hCnE9bS5hCnEuYz1s
+Llc3KG5ldyBQLmpaKG4pLHQueikKcS5iPSExfX0sCiRTOjB9ClAualoucHJvdG90eXBlPXsKJDE6ZnVu
+Y3Rpb24oYSl7cmV0dXJuIHRoaXMuYX0sCiRTOjMyfQpQLnJxLnByb3RvdHlwZT17CiQwOmZ1bmN0aW9u
+KCl7dmFyIHMscixxLHAsbyxuLG0sbAp0cnl7cT10aGlzLmEKcD1xLmEKbz1wLiR0aQpuPW8uYwptPW4u
+YSh0aGlzLmIpCnEuYz1wLmIuYi5idihvLkMoIjIvKDEpIikuYShwLmQpLG0sby5DKCIyLyIpLG4pfWNh
+dGNoKGwpe3M9SC5SdShsKQpyPUgudHMobCkKcT10aGlzLmEKcS5jPVAuVGwocyxyKQpxLmI9ITB9fSwK
+JFM6MH0KUC5SVy5wcm90b3R5cGU9ewokMDpmdW5jdGlvbigpe3ZhciBzLHIscSxwLG8sbixtLGwsaz10
+aGlzCnRyeXtzPXQubi5hKGsuYS5hLmMpCnA9ay5iCmlmKEgub1QocC5hLkhSKHMpKSYmcC5hLmUhPW51
+bGwpe3AuYz1wLmEuS3cocykKcC5iPSExfX1jYXRjaChvKXtyPUguUnUobykKcT1ILnRzKG8pCnA9dC5u
+LmEoay5hLmEuYykKbj1wLmEKbT1yCmw9ay5iCmlmKG49PW51bGw/bT09bnVsbDpuPT09bSlsLmM9cApl
+bHNlIGwuYz1QLlRsKHIscSkKbC5iPSEwfX0sCiRTOjB9ClAuT00ucHJvdG90eXBlPXt9ClAucWgucHJv
+dG90eXBlPXsKZ0E6ZnVuY3Rpb24oYSl7dmFyIHMscixxPXRoaXMscD17fSxvPW5ldyBQLnZzKCQuWDMs
+dC5mSikKcC5hPTAKcz1ILkxoKHEpCnI9cy5DKCJ+KDEpPyIpLmEobmV3IFAuQjUocCxxKSkKdC5aLmEo
+bmV3IFAudU8ocCxvKSkKVy5KRShxLmEscS5iLHIsITEscy5jKQpyZXR1cm4gb319ClAuQjUucHJvdG90
+eXBlPXsKJDE6ZnVuY3Rpb24oYSl7SC5MaCh0aGlzLmIpLmMuYShhKTsrK3RoaXMuYS5hfSwKJFM6ZnVu
+Y3Rpb24oKXtyZXR1cm4gSC5MaCh0aGlzLmIpLkMoIn4oMSkiKX19ClAudU8ucHJvdG90eXBlPXsKJDA6
+ZnVuY3Rpb24oKXt0aGlzLmIuSEgodGhpcy5hLmEpfSwKJFM6MH0KUC5NTy5wcm90b3R5cGU9e30KUC5r
+VC5wcm90b3R5cGU9e30KUC54SS5wcm90b3R5cGU9e30KUC5Ddy5wcm90b3R5cGU9ewp3OmZ1bmN0aW9u
+KGEpe3JldHVybiBILkVqKHRoaXMuYSl9LAokaVhTOjEsCmdJSTpmdW5jdGlvbigpe3JldHVybiB0aGlz
+LmJ9fQpQLm0wLnByb3RvdHlwZT17JGlRbToxfQpQLnBLLnByb3RvdHlwZT17CiQwOmZ1bmN0aW9uKCl7
+dmFyIHM9SC5iKHRoaXMuYSkKcy5zdGFjaz1KLmoodGhpcy5iKQp0aHJvdyBzfSwKJFM6MH0KUC5KaS5w
+cm90b3R5cGU9ewpiSDpmdW5jdGlvbihhKXt2YXIgcyxyLHEscD1udWxsCnQuTS5hKGEpCnRyeXtpZihD
+Lk5VPT09JC5YMyl7YS4kMCgpCnJldHVybn1QLlQ4KHAscCx0aGlzLGEsdC5IKX1jYXRjaChxKXtzPUgu
+UnUocSkKcj1ILnRzKHEpClAuTDIocCxwLHRoaXMscyx0LmwuYShyKSl9fSwKRGw6ZnVuY3Rpb24oYSxi
+LGMpe3ZhciBzLHIscSxwPW51bGwKYy5DKCJ+KDApIikuYShhKQpjLmEoYikKdHJ5e2lmKEMuTlU9PT0k
+LlgzKXthLiQxKGIpCnJldHVybn1QLnl2KHAscCx0aGlzLGEsYix0LkgsYyl9Y2F0Y2gocSl7cz1ILlJ1
+KHEpCnI9SC50cyhxKQpQLkwyKHAscCx0aGlzLHMsdC5sLmEocikpfX0sClJUOmZ1bmN0aW9uKGEsYil7
+cmV0dXJuIG5ldyBQLmhqKHRoaXMsYi5DKCIwKCkiKS5hKGEpLGIpfSwKdDg6ZnVuY3Rpb24oYSl7cmV0
+dXJuIG5ldyBQLlZwKHRoaXMsdC5NLmEoYSkpfSwKUHk6ZnVuY3Rpb24oYSxiKXtyZXR1cm4gbmV3IFAu
+T1IodGhpcyxiLkMoIn4oMCkiKS5hKGEpLGIpfSwKcTpmdW5jdGlvbihhLGIpe3JldHVybiBudWxsfSwK
+eno6ZnVuY3Rpb24oYSxiKXtiLkMoIjAoKSIpLmEoYSkKaWYoJC5YMz09PUMuTlUpcmV0dXJuIGEuJDAo
+KQpyZXR1cm4gUC5UOChudWxsLG51bGwsdGhpcyxhLGIpfSwKYnY6ZnVuY3Rpb24oYSxiLGMsZCl7Yy5D
+KCJAPDA+IikuS3EoZCkuQygiMSgyKSIpLmEoYSkKZC5hKGIpCmlmKCQuWDM9PT1DLk5VKXJldHVybiBh
+LiQxKGIpCnJldHVybiBQLnl2KG51bGwsbnVsbCx0aGlzLGEsYixjLGQpfSwKcnA6ZnVuY3Rpb24oYSxi
+LGMsZCxlLGYpe2QuQygiQDwwPiIpLktxKGUpLktxKGYpLkMoIjEoMiwzKSIpLmEoYSkKZS5hKGIpCmYu
+YShjKQppZigkLlgzPT09Qy5OVSlyZXR1cm4gYS4kMihiLGMpCnJldHVybiBQLlF4KG51bGwsbnVsbCx0
+aGlzLGEsYixjLGQsZSxmKX0sCkxqOmZ1bmN0aW9uKGEsYixjLGQpe3JldHVybiBiLkMoIkA8MD4iKS5L
+cShjKS5LcShkKS5DKCIxKDIsMykiKS5hKGEpfX0KUC5oai5wcm90b3R5cGU9ewokMDpmdW5jdGlvbigp
+e3JldHVybiB0aGlzLmEuenoodGhpcy5iLHRoaXMuYyl9LAokUzpmdW5jdGlvbigpe3JldHVybiB0aGlz
+LmMuQygiMCgpIil9fQpQLlZwLnByb3RvdHlwZT17CiQwOmZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMuYS5i
+SCh0aGlzLmIpfSwKJFM6MH0KUC5PUi5wcm90b3R5cGU9ewokMTpmdW5jdGlvbihhKXt2YXIgcz10aGlz
+LmMKcmV0dXJuIHRoaXMuYS5EbCh0aGlzLmIscy5hKGEpLHMpfSwKJFM6ZnVuY3Rpb24oKXtyZXR1cm4g
+dGhpcy5jLkMoIn4oMCkiKX19ClAuYjYucHJvdG90eXBlPXsKZ206ZnVuY3Rpb24oYSl7dmFyIHM9dGhp
+cyxyPW5ldyBQLmxtKHMscy5yLEguTGgocykuQygibG08MT4iKSkKci5jPXMuZQpyZXR1cm4gcn0sCmdB
+OmZ1bmN0aW9uKGEpe3JldHVybiB0aGlzLmF9LApnbDA6ZnVuY3Rpb24oYSl7cmV0dXJuIHRoaXMuYT09
+PTB9LApnb3I6ZnVuY3Rpb24oYSl7cmV0dXJuIHRoaXMuYSE9PTB9LAp0ZzpmdW5jdGlvbihhLGIpe3Zh
+ciBzLHIKaWYodHlwZW9mIGI9PSJzdHJpbmciJiZiIT09Il9fcHJvdG9fXyIpe3M9dGhpcy5iCmlmKHM9
+PW51bGwpcmV0dXJuITEKcmV0dXJuIHQuZS5hKHNbYl0pIT1udWxsfWVsc2V7cj10aGlzLlBSKGIpCnJl
+dHVybiByfX0sClBSOmZ1bmN0aW9uKGEpe3ZhciBzPXRoaXMuZAppZihzPT1udWxsKXJldHVybiExCnJl
+dHVybiB0aGlzLlIoc1t0aGlzLk4oYSldLGEpPj0wfSwKaTpmdW5jdGlvbihhLGIpe3ZhciBzLHIscT10
+aGlzCkguTGgocSkuYy5hKGIpCmlmKHR5cGVvZiBiPT0ic3RyaW5nIiYmYiE9PSJfX3Byb3RvX18iKXtz
+PXEuYgpyZXR1cm4gcS5TKHM9PW51bGw/cS5iPVAuVDIoKTpzLGIpfWVsc2UgaWYodHlwZW9mIGI9PSJu
+dW1iZXIiJiYoYiYxMDczNzQxODIzKT09PWIpe3I9cS5jCnJldHVybiBxLlMocj09bnVsbD9xLmM9UC5U
+MigpOnIsYil9ZWxzZSByZXR1cm4gcS5HKGIpfSwKRzpmdW5jdGlvbihhKXt2YXIgcyxyLHEscD10aGlz
+CkguTGgocCkuYy5hKGEpCnM9cC5kCmlmKHM9PW51bGwpcz1wLmQ9UC5UMigpCnI9cC5OKGEpCnE9c1ty
+XQppZihxPT1udWxsKXNbcl09W3AuSChhKV0KZWxzZXtpZihwLlIocSxhKT49MClyZXR1cm4hMQpxLnB1
+c2gocC5IKGEpKX1yZXR1cm4hMH0sCkw6ZnVuY3Rpb24oYSxiKXt2YXIgcz10aGlzCmlmKHR5cGVvZiBi
+PT0ic3RyaW5nIiYmYiE9PSJfX3Byb3RvX18iKXJldHVybiBzLkg0KHMuYixiKQplbHNlIGlmKHR5cGVv
+ZiBiPT0ibnVtYmVyIiYmKGImMTA3Mzc0MTgyMyk9PT1iKXJldHVybiBzLkg0KHMuYyxiKQplbHNlIHJl
+dHVybiBzLnFnKGIpfSwKcWc6ZnVuY3Rpb24oYSl7dmFyIHMscixxLHAsbz10aGlzLG49by5kCmlmKG49
+PW51bGwpcmV0dXJuITEKcz1vLk4oYSkKcj1uW3NdCnE9by5SKHIsYSkKaWYocTwwKXJldHVybiExCnA9
+ci5zcGxpY2UocSwxKVswXQppZigwPT09ci5sZW5ndGgpZGVsZXRlIG5bc10Kby5HUyhwKQpyZXR1cm4h
+MH0sClM6ZnVuY3Rpb24oYSxiKXtILkxoKHRoaXMpLmMuYShiKQppZih0LmUuYShhW2JdKSE9bnVsbCly
+ZXR1cm4hMQphW2JdPXRoaXMuSChiKQpyZXR1cm4hMH0sCkg0OmZ1bmN0aW9uKGEsYil7dmFyIHMKaWYo
+YT09bnVsbClyZXR1cm4hMQpzPXQuZS5hKGFbYl0pCmlmKHM9PW51bGwpcmV0dXJuITEKdGhpcy5HUyhz
+KQpkZWxldGUgYVtiXQpyZXR1cm4hMH0sCkdZOmZ1bmN0aW9uKCl7dGhpcy5yPXRoaXMucisxJjEwNzM3
+NDE4MjN9LApIOmZ1bmN0aW9uKGEpe3ZhciBzLHI9dGhpcyxxPW5ldyBQLmJuKEguTGgocikuYy5hKGEp
+KQppZihyLmU9PW51bGwpci5lPXIuZj1xCmVsc2V7cz1yLmYKcy50b1N0cmluZwpxLmM9cwpyLmY9cy5i
+PXF9KytyLmEKci5HWSgpCnJldHVybiBxfSwKR1M6ZnVuY3Rpb24oYSl7dmFyIHM9dGhpcyxyPWEuYyxx
+PWEuYgppZihyPT1udWxsKXMuZT1xCmVsc2Ugci5iPXEKaWYocT09bnVsbClzLmY9cgplbHNlIHEuYz1y
+Oy0tcy5hCnMuR1koKX0sCk46ZnVuY3Rpb24oYSl7cmV0dXJuIEouaGYoYSkmMTA3Mzc0MTgyM30sClI6
+ZnVuY3Rpb24oYSxiKXt2YXIgcyxyCmlmKGE9PW51bGwpcmV0dXJuLTEKcz1hLmxlbmd0aApmb3Iocj0w
+O3I8czsrK3IpaWYoSi5STShhW3JdLmEsYikpcmV0dXJuIHIKcmV0dXJuLTF9fQpQLmJuLnByb3RvdHlw
+ZT17fQpQLmxtLnByb3RvdHlwZT17CmdsOmZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMuZH0sCkY6ZnVuY3Rp
+b24oKXt2YXIgcz10aGlzLHI9cy5jLHE9cy5hCmlmKHMuYiE9PXEucil0aHJvdyBILmIoUC5hNChxKSkK
+ZWxzZSBpZihyPT1udWxsKXtzLnNqKG51bGwpCnJldHVybiExfWVsc2V7cy5zaihzLiR0aS5DKCIxPyIp
+LmEoci5hKSkKcy5jPXIuYgpyZXR1cm4hMH19LApzajpmdW5jdGlvbihhKXt0aGlzLmQ9dGhpcy4kdGku
+QygiMT8iKS5hKGEpfSwKJGlBbjoxfQpQLm1XLnByb3RvdHlwZT17fQpQLnV5LnByb3RvdHlwZT17JGli
+UToxLCRpY1g6MSwkaXpNOjF9ClAubEQucHJvdG90eXBlPXsKZ206ZnVuY3Rpb24oYSl7cmV0dXJuIG5l
+dyBILmE3KGEsdGhpcy5nQShhKSxILnooYSkuQygiYTc8bEQuRT4iKSl9LApFOmZ1bmN0aW9uKGEsYil7
+cmV0dXJuIHRoaXMucShhLGIpfSwKSzpmdW5jdGlvbihhLGIpe3ZhciBzLHIKSC56KGEpLkMoIn4obEQu
+RSkiKS5hKGIpCnM9dGhpcy5nQShhKQpmb3Iocj0wO3I8czsrK3Ipe2IuJDEodGhpcy5xKGEscikpCmlm
+KHMhPT10aGlzLmdBKGEpKXRocm93IEguYihQLmE0KGEpKX19LApnbDA6ZnVuY3Rpb24oYSl7cmV0dXJu
+IHRoaXMuZ0EoYSk9PT0wfSwKZ29yOmZ1bmN0aW9uKGEpe3JldHVybiF0aGlzLmdsMChhKX0sCkUyOmZ1
+bmN0aW9uKGEsYixjKXt2YXIgcz1ILnooYSkKcmV0dXJuIG5ldyBILmxKKGEscy5LcShjKS5DKCIxKGxE
+LkUpIikuYShiKSxzLkMoIkA8bEQuRT4iKS5LcShjKS5DKCJsSjwxLDI+IikpfSwKZVI6ZnVuY3Rpb24o
+YSxiKXtyZXR1cm4gSC5xQyhhLGIsbnVsbCxILnooYSkuQygibEQuRSIpKX0sCmRyOmZ1bmN0aW9uKGEs
+Yil7cmV0dXJuIG5ldyBILmpWKGEsSC56KGEpLkMoIkA8bEQuRT4iKS5LcShiKS5DKCJqVjwxLDI+Iikp
+fSwKZHU6ZnVuY3Rpb24oYSxiLGMsZCl7dmFyIHMKSC56KGEpLkMoImxELkU/IikuYShkKQpQLmpCKGIs
+Yyx0aGlzLmdBKGEpKQpmb3Iocz1iO3M8YzsrK3MpdGhpcy5ZNShhLHMsZCl9LAp3OmZ1bmN0aW9uKGEp
+e3JldHVybiBQLldFKGEsIlsiLCJdIil9fQpQLmlsLnByb3RvdHlwZT17fQpQLnJhLnByb3RvdHlwZT17
+CiQyOmZ1bmN0aW9uKGEsYil7dmFyIHMscj10aGlzLmEKaWYoIXIuYSl0aGlzLmIuYSs9IiwgIgpyLmE9
+ITEKcj10aGlzLmIKcz1yLmErPUguRWooYSkKci5hPXMrIjogIgpyLmErPUguRWooYil9LAokUzoxMH0K
+UC5Zay5wcm90b3R5cGU9ewpLOmZ1bmN0aW9uKGEsYil7dmFyIHMscgpILkxoKHRoaXMpLkMoIn4oWWsu
+SyxZay5WKSIpLmEoYikKZm9yKHM9Si5JVCh0aGlzLmd2YygpKTtzLkYoKTspe3I9cy5nbCgpCmIuJDIo
+cix0aGlzLnEoMCxyKSl9fSwKZ1B1OmZ1bmN0aW9uKGEpe3JldHVybiBKLk0xKHRoaXMuZ3ZjKCksbmV3
+IFAueVEodGhpcyksSC5MaCh0aGlzKS5DKCJOMzxZay5LLFlrLlY+IikpfSwKeDQ6ZnVuY3Rpb24oYSl7
+cmV0dXJuIEouemwodGhpcy5ndmMoKSxhKX0sCmdBOmZ1bmN0aW9uKGEpe3JldHVybiBKLkhtKHRoaXMu
+Z3ZjKCkpfSwKZ2wwOmZ1bmN0aW9uKGEpe3JldHVybiBKLnVVKHRoaXMuZ3ZjKCkpfSwKdzpmdW5jdGlv
+bihhKXtyZXR1cm4gUC5uTyh0aGlzKX0sCiRpWjA6MX0KUC55US5wcm90b3R5cGU9ewokMTpmdW5jdGlv
+bihhKXt2YXIgcz10aGlzLmEscj1ILkxoKHMpCnIuQygiWWsuSyIpLmEoYSkKcmV0dXJuIG5ldyBQLk4z
+KGEscy5xKDAsYSksci5DKCJAPFlrLks+IikuS3Eoci5DKCJZay5WIikpLkMoIk4zPDEsMj4iKSl9LAok
+UzpmdW5jdGlvbigpe3JldHVybiBILkxoKHRoaXMuYSkuQygiTjM8WWsuSyxZay5WPihZay5LKSIpfX0K
+UC5LUC5wcm90b3R5cGU9ewpZNTpmdW5jdGlvbihhLGIsYyl7dmFyIHM9SC5MaCh0aGlzKQpzLmMuYShi
+KQpzLlFbMV0uYShjKQp0aHJvdyBILmIoUC5MNCgiQ2Fubm90IG1vZGlmeSB1bm1vZGlmaWFibGUgbWFw
+IikpfX0KUC5Qbi5wcm90b3R5cGU9ewpxOmZ1bmN0aW9uKGEsYil7cmV0dXJuIHRoaXMuYS5xKDAsYil9
+LApZNTpmdW5jdGlvbihhLGIsYyl7dmFyIHM9SC5MaCh0aGlzKQp0aGlzLmEuWTUoMCxzLmMuYShiKSxz
+LlFbMV0uYShjKSl9LAp4NDpmdW5jdGlvbihhKXtyZXR1cm4gdGhpcy5hLng0KGEpfSwKSzpmdW5jdGlv
+bihhLGIpe3RoaXMuYS5LKDAsSC5MaCh0aGlzKS5DKCJ+KDEsMikiKS5hKGIpKX0sCmdsMDpmdW5jdGlv
+bihhKXt2YXIgcz10aGlzLmEKcmV0dXJuIHMuZ2wwKHMpfSwKZ0E6ZnVuY3Rpb24oYSl7dmFyIHM9dGhp
+cy5hCnJldHVybiBzLmdBKHMpfSwKdzpmdW5jdGlvbihhKXtyZXR1cm4gSi5qKHRoaXMuYSl9LApnUHU6
+ZnVuY3Rpb24oYSl7dmFyIHM9dGhpcy5hCnJldHVybiBzLmdQdShzKX0sCiRpWjA6MX0KUC5Hai5wcm90
+b3R5cGU9e30KUC5sZi5wcm90b3R5cGU9ewpnbDA6ZnVuY3Rpb24oYSl7cmV0dXJuIHRoaXMuZ0EodGhp
+cyk9PT0wfSwKZ29yOmZ1bmN0aW9uKGEpe3JldHVybiB0aGlzLmdBKHRoaXMpIT09MH0sCkZWOmZ1bmN0
+aW9uKGEsYil7dmFyIHMKZm9yKHM9Si5JVChILkxoKHRoaXMpLkMoImNYPGxmLkU+IikuYShiKSk7cy5G
+KCk7KXRoaXMuaSgwLHMuZ2woKSl9LAp3OmZ1bmN0aW9uKGEpe3JldHVybiBQLldFKHRoaXMsInsiLCJ9
+Iil9LAprOmZ1bmN0aW9uKGEsYil7dmFyIHMscj10aGlzLmdtKHRoaXMpCmlmKCFyLkYoKSlyZXR1cm4i
+IgppZihiPT09IiIpe3M9IiIKZG8gcys9SC5FaihyLmQpCndoaWxlKHIuRigpKX1lbHNle3M9SC5Faihy
+LmQpCmZvcig7ci5GKCk7KXM9cytiK0guRWooci5kKX1yZXR1cm4gcy5jaGFyQ29kZUF0KDApPT0wP3M6
+c30sCmVSOmZ1bmN0aW9uKGEsYil7cmV0dXJuIEguYksodGhpcyxiLEguTGgodGhpcykuQygibGYuRSIp
+KX0sCkU6ZnVuY3Rpb24oYSxiKXt2YXIgcyxyLHEscD0iaW5kZXgiCkguY2IoYixwLHQuUykKUC5rMShi
+LHApCmZvcihzPXRoaXMuZ20odGhpcykscj0wO3MuRigpOyl7cT1zLmQKaWYoYj09PXIpcmV0dXJuIHE7
+KytyfXRocm93IEguYihQLkNmKGIsdGhpcyxwLG51bGwscikpfX0KUC5Wai5wcm90b3R5cGU9eyRpYlE6
+MSwkaWNYOjEsJGl4dToxfQpQLlh2LnByb3RvdHlwZT17JGliUToxLCRpY1g6MSwkaXh1OjF9ClAublku
+cHJvdG90eXBlPXt9ClAuV1kucHJvdG90eXBlPXt9ClAuUlUucHJvdG90eXBlPXt9ClAucFIucHJvdG90
+eXBlPXt9ClAudXcucHJvdG90eXBlPXsKcTpmdW5jdGlvbihhLGIpe3ZhciBzLHI9dGhpcy5iCmlmKHI9
+PW51bGwpcmV0dXJuIHRoaXMuYy5xKDAsYikKZWxzZSBpZih0eXBlb2YgYiE9InN0cmluZyIpcmV0dXJu
+IG51bGwKZWxzZXtzPXJbYl0KcmV0dXJuIHR5cGVvZiBzPT0idW5kZWZpbmVkIj90aGlzLmZiKGIpOnN9
+fSwKZ0E6ZnVuY3Rpb24oYSl7cmV0dXJuIHRoaXMuYj09bnVsbD90aGlzLmMuYTp0aGlzLkNmKCkubGVu
+Z3RofSwKZ2wwOmZ1bmN0aW9uKGEpe3JldHVybiB0aGlzLmdBKHRoaXMpPT09MH0sCmd2YzpmdW5jdGlv
+bigpe2lmKHRoaXMuYj09bnVsbCl7dmFyIHM9dGhpcy5jCnJldHVybiBuZXcgSC5pNShzLEguTGgocyku
+QygiaTU8MT4iKSl9cmV0dXJuIG5ldyBQLmk4KHRoaXMpfSwKWTU6ZnVuY3Rpb24oYSxiLGMpe3ZhciBz
+LHIscT10aGlzCmlmKHEuYj09bnVsbClxLmMuWTUoMCxiLGMpCmVsc2UgaWYocS54NChiKSl7cz1xLmIK
+c1tiXT1jCnI9cS5hCmlmKHI9PW51bGw/cyE9bnVsbDpyIT09cylyW2JdPW51bGx9ZWxzZSBxLlhLKCku
+WTUoMCxiLGMpfSwKeDQ6ZnVuY3Rpb24oYSl7aWYodGhpcy5iPT1udWxsKXJldHVybiB0aGlzLmMueDQo
+YSkKcmV0dXJuIE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbCh0aGlzLmEsYSl9LApL
+OmZ1bmN0aW9uKGEsYil7dmFyIHMscixxLHAsbz10aGlzCnQuY0EuYShiKQppZihvLmI9PW51bGwpcmV0
+dXJuIG8uYy5LKDAsYikKcz1vLkNmKCkKZm9yKHI9MDtyPHMubGVuZ3RoOysrcil7cT1zW3JdCnA9by5i
+W3FdCmlmKHR5cGVvZiBwPT0idW5kZWZpbmVkIil7cD1QLlFlKG8uYVtxXSkKby5iW3FdPXB9Yi4kMihx
+LHApCmlmKHMhPT1vLmMpdGhyb3cgSC5iKFAuYTQobykpfX0sCkNmOmZ1bmN0aW9uKCl7dmFyIHM9dC5i
+TS5hKHRoaXMuYykKaWYocz09bnVsbClzPXRoaXMuYz1ILlZNKE9iamVjdC5rZXlzKHRoaXMuYSksdC5z
+KQpyZXR1cm4gc30sClhLOmZ1bmN0aW9uKCl7dmFyIHMscixxLHAsbyxuPXRoaXMKaWYobi5iPT1udWxs
+KXJldHVybiBuLmMKcz1QLkZsKHQuTix0LnopCnI9bi5DZigpCmZvcihxPTA7cD1yLmxlbmd0aCxxPHA7
+KytxKXtvPXJbcV0Kcy5ZNSgwLG8sbi5xKDAsbykpfWlmKHA9PT0wKUMuTm0uaShyLCIiKQplbHNlIEMu
+Tm0uc0EociwwKQpuLmE9bi5iPW51bGwKcmV0dXJuIG4uYz1zfSwKZmI6ZnVuY3Rpb24oYSl7dmFyIHMK
+aWYoIU9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbCh0aGlzLmEsYSkpcmV0dXJuIG51
+bGwKcz1QLlFlKHRoaXMuYVthXSkKcmV0dXJuIHRoaXMuYlthXT1zfX0KUC5pOC5wcm90b3R5cGU9ewpn
+QTpmdW5jdGlvbihhKXt2YXIgcz10aGlzLmEKcmV0dXJuIHMuZ0Eocyl9LApFOmZ1bmN0aW9uKGEsYil7
+dmFyIHM9dGhpcy5hCmlmKHMuYj09bnVsbClzPXMuZ3ZjKCkuRSgwLGIpCmVsc2V7cz1zLkNmKCkKaWYo
+YjwwfHxiPj1zLmxlbmd0aClyZXR1cm4gSC5PSChzLGIpCnM9c1tiXX1yZXR1cm4gc30sCmdtOmZ1bmN0
+aW9uKGEpe3ZhciBzPXRoaXMuYQppZihzLmI9PW51bGwpe3M9cy5ndmMoKQpzPXMuZ20ocyl9ZWxzZXtz
+PXMuQ2YoKQpzPW5ldyBKLm0xKHMscy5sZW5ndGgsSC50NihzKS5DKCJtMTwxPiIpKX1yZXR1cm4gc30s
+CnRnOmZ1bmN0aW9uKGEsYil7cmV0dXJuIHRoaXMuYS54NChiKX19ClAucGcucHJvdG90eXBlPXsKJDA6
+ZnVuY3Rpb24oKXt2YXIgcyxyCnRyeXtzPW5ldyBUZXh0RGVjb2RlcigidXRmLTgiLHtmYXRhbDp0cnVl
+fSkKcmV0dXJuIHN9Y2F0Y2gocil7SC5SdShyKX1yZXR1cm4gbnVsbH0sCiRTOjExfQpQLmMyLnByb3Rv
+dHlwZT17CiQwOmZ1bmN0aW9uKCl7dmFyIHMscgp0cnl7cz1uZXcgVGV4dERlY29kZXIoInV0Zi04Iix7
+ZmF0YWw6ZmFsc2V9KQpyZXR1cm4gc31jYXRjaChyKXtILlJ1KHIpfXJldHVybiBudWxsfSwKJFM6MTF9
+ClAuQ1YucHJvdG90eXBlPXsKeXI6ZnVuY3Rpb24oYTAsYTEsYTIpe3ZhciBzLHIscSxwLG8sbixtLGws
+ayxqLGksaCxnLGYsZSxkLGMsYixhPSJJbnZhbGlkIGJhc2U2NCBlbmNvZGluZyBsZW5ndGggIgphMj1Q
+LmpCKGExLGEyLGEwLmxlbmd0aCkKcz0kLlY3KCkKZm9yKHI9YTEscT1yLHA9bnVsbCxvPS0xLG49LTEs
+bT0wO3I8YTI7cj1sKXtsPXIrMQprPUMueEIuVyhhMCxyKQppZihrPT09Mzcpe2o9bCsyCmlmKGo8PWEy
+KXtpPUgub28oQy54Qi5XKGEwLGwpKQpoPUgub28oQy54Qi5XKGEwLGwrMSkpCmc9aSoxNitoLShoJjI1
+NikKaWYoZz09PTM3KWc9LTEKbD1qfWVsc2UgZz0tMX1lbHNlIGc9awppZigwPD1nJiZnPD0xMjcpe2lm
+KGc8MHx8Zz49cy5sZW5ndGgpcmV0dXJuIEguT0gocyxnKQpmPXNbZ10KaWYoZj49MCl7Zz1DLnhCLk8y
+KCJBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWmFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6MDEyMzQ1
+Njc4OSsvIixmKQppZihnPT09ayljb250aW51ZQprPWd9ZWxzZXtpZihmPT09LTEpe2lmKG88MCl7ZT1w
+PT1udWxsP251bGw6cC5hLmxlbmd0aAppZihlPT1udWxsKWU9MApvPWUrKHItcSkKbj1yfSsrbQppZihr
+PT09NjEpY29udGludWV9az1nfWlmKGYhPT0tMil7aWYocD09bnVsbCl7cD1uZXcgUC5SbigiIikKZT1w
+fWVsc2UgZT1wCmUuYSs9Qy54Qi5OaihhMCxxLHIpCmUuYSs9SC5MdyhrKQpxPWwKY29udGludWV9fXRo
+cm93IEguYihQLnJyKCJJbnZhbGlkIGJhc2U2NCBkYXRhIixhMCxyKSl9aWYocCE9bnVsbCl7ZT1wLmEr
+PUMueEIuTmooYTAscSxhMikKZD1lLmxlbmd0aAppZihvPj0wKVAueE0oYTAsbixhMixvLG0sZCkKZWxz
+ZXtjPUMuam4uelkoZC0xLDQpKzEKaWYoYz09PTEpdGhyb3cgSC5iKFAucnIoYSxhMCxhMikpCmZvcig7
+Yzw0Oyl7ZSs9Ij0iCnAuYT1lOysrY319ZT1wLmEKcmV0dXJuIEMueEIuaTcoYTAsYTEsYTIsZS5jaGFy
+Q29kZUF0KDApPT0wP2U6ZSl9Yj1hMi1hMQppZihvPj0wKVAueE0oYTAsbixhMixvLG0sYikKZWxzZXtj
+PUMuam4uelkoYiw0KQppZihjPT09MSl0aHJvdyBILmIoUC5ycihhLGEwLGEyKSkKaWYoYz4xKWEwPUMu
+eEIuaTcoYTAsYTIsYTIsYz09PTI/Ij09IjoiPSIpfXJldHVybiBhMH19ClAuVTgucHJvdG90eXBlPXt9
+ClAuVWsucHJvdG90eXBlPXt9ClAud0kucHJvdG90eXBlPXt9ClAuWmkucHJvdG90eXBlPXt9ClAuVWQu
+cHJvdG90eXBlPXsKdzpmdW5jdGlvbihhKXt2YXIgcz1QLnAodGhpcy5hKQpyZXR1cm4odGhpcy5iIT1u
+dWxsPyJDb252ZXJ0aW5nIG9iamVjdCB0byBhbiBlbmNvZGFibGUgb2JqZWN0IGZhaWxlZDoiOiJDb252
+ZXJ0aW5nIG9iamVjdCBkaWQgbm90IHJldHVybiBhbiBlbmNvZGFibGUgb2JqZWN0OiIpKyIgIitzfX0K
+UC5LOC5wcm90b3R5cGU9ewp3OmZ1bmN0aW9uKGEpe3JldHVybiJDeWNsaWMgZXJyb3IgaW4gSlNPTiBz
+dHJpbmdpZnkifX0KUC5ieS5wcm90b3R5cGU9ewpwVzpmdW5jdGlvbihhLGIsYyl7dmFyIHMKdC5mVi5h
+KGMpCnM9UC5CUyhiLHRoaXMuZ0hlKCkuYSkKcmV0dXJuIHN9LApPQjpmdW5jdGlvbihhLGIpe3ZhciBz
+CnQuZEEuYShiKQpzPVAudVgoYSx0aGlzLmdaRSgpLmIsbnVsbCkKcmV0dXJuIHN9LApnWkU6ZnVuY3Rp
+b24oKXtyZXR1cm4gQy5uWH0sCmdIZTpmdW5jdGlvbigpe3JldHVybiBDLkEzfX0KUC5vai5wcm90b3R5
+cGU9e30KUC5NeC5wcm90b3R5cGU9e30KUC5TaC5wcm90b3R5cGU9ewp2cDpmdW5jdGlvbihhKXt2YXIg
+cyxyLHEscCxvLG4sbSxsPWEubGVuZ3RoCmZvcihzPUouclkoYSkscj10aGlzLmMscT0wLHA9MDtwPGw7
+KytwKXtvPXMuVyhhLHApCmlmKG8+OTIpe2lmKG8+PTU1Mjk2KXtuPW8mNjQ1MTIKaWYobj09PTU1Mjk2
+KXttPXArMQptPSEobTxsJiYoQy54Qi5XKGEsbSkmNjQ1MTIpPT09NTYzMjApfWVsc2UgbT0hMQppZigh
+bSlpZihuPT09NTYzMjApe249cC0xCm49IShuPj0wJiYoQy54Qi5PMihhLG4pJjY0NTEyKT09PTU1Mjk2
+KX1lbHNlIG49ITEKZWxzZSBuPSEwCmlmKG4pe2lmKHA+cSlyLmErPUMueEIuTmooYSxxLHApCnE9cCsx
+CnIuYSs9SC5Mdyg5MikKci5hKz1ILkx3KDExNykKci5hKz1ILkx3KDEwMCkKbj1vPj4+OCYxNQpyLmEr
+PUguTHcobjwxMD80OCtuOjg3K24pCm49bz4+PjQmMTUKci5hKz1ILkx3KG48MTA/NDgrbjo4NytuKQpu
+PW8mMTUKci5hKz1ILkx3KG48MTA/NDgrbjo4NytuKX19Y29udGludWV9aWYobzwzMil7aWYocD5xKXIu
+YSs9Qy54Qi5OaihhLHEscCkKcT1wKzEKci5hKz1ILkx3KDkyKQpzd2l0Y2gobyl7Y2FzZSA4OnIuYSs9
+SC5Mdyg5OCkKYnJlYWsKY2FzZSA5OnIuYSs9SC5MdygxMTYpCmJyZWFrCmNhc2UgMTA6ci5hKz1ILkx3
+KDExMCkKYnJlYWsKY2FzZSAxMjpyLmErPUguTHcoMTAyKQpicmVhawpjYXNlIDEzOnIuYSs9SC5Mdygx
+MTQpCmJyZWFrCmRlZmF1bHQ6ci5hKz1ILkx3KDExNykKci5hKz1ILkx3KDQ4KQpyLmErPUguTHcoNDgp
+Cm49bz4+PjQmMTUKci5hKz1ILkx3KG48MTA/NDgrbjo4NytuKQpuPW8mMTUKci5hKz1ILkx3KG48MTA/
+NDgrbjo4NytuKQpicmVha319ZWxzZSBpZihvPT09MzR8fG89PT05Mil7aWYocD5xKXIuYSs9Qy54Qi5O
+aihhLHEscCkKcT1wKzEKci5hKz1ILkx3KDkyKQpyLmErPUguTHcobyl9fWlmKHE9PT0wKXIuYSs9SC5F
+aihhKQplbHNlIGlmKHE8bClyLmErPXMuTmooYSxxLGwpfSwKSm46ZnVuY3Rpb24oYSl7dmFyIHMscixx
+LHAKZm9yKHM9dGhpcy5hLHI9cy5sZW5ndGgscT0wO3E8cjsrK3Epe3A9c1txXQppZihhPT1udWxsP3A9
+PW51bGw6YT09PXApdGhyb3cgSC5iKG5ldyBQLks4KGEsbnVsbCkpfUMuTm0uaShzLGEpfSwKaVU6ZnVu
+Y3Rpb24oYSl7dmFyIHMscixxLHAsbz10aGlzCmlmKG8udE0oYSkpcmV0dXJuCm8uSm4oYSkKdHJ5e3M9
+by5iLiQxKGEpCmlmKCFvLnRNKHMpKXtxPVAuR3koYSxudWxsLG8uZ1ZLKCkpCnRocm93IEguYihxKX1x
+PW8uYQppZigwPj1xLmxlbmd0aClyZXR1cm4gSC5PSChxLC0xKQpxLnBvcCgpfWNhdGNoKHApe3I9SC5S
+dShwKQpxPVAuR3koYSxyLG8uZ1ZLKCkpCnRocm93IEguYihxKX19LAp0TTpmdW5jdGlvbihhKXt2YXIg
+cyxyLHE9dGhpcwppZih0eXBlb2YgYT09Im51bWJlciIpe2lmKCFpc0Zpbml0ZShhKSlyZXR1cm4hMQpx
+LmMuYSs9Qy5DRC53KGEpCnJldHVybiEwfWVsc2UgaWYoYT09PSEwKXtxLmMuYSs9InRydWUiCnJldHVy
+biEwfWVsc2UgaWYoYT09PSExKXtxLmMuYSs9ImZhbHNlIgpyZXR1cm4hMH1lbHNlIGlmKGE9PW51bGwp
+e3EuYy5hKz0ibnVsbCIKcmV0dXJuITB9ZWxzZSBpZih0eXBlb2YgYT09InN0cmluZyIpe3M9cS5jCnMu
+YSs9JyInCnEudnAoYSkKcy5hKz0nIicKcmV0dXJuITB9ZWxzZSBpZih0LmouYihhKSl7cS5KbihhKQpx
+LmxLKGEpCnM9cS5hCmlmKDA+PXMubGVuZ3RoKXJldHVybiBILk9IKHMsLTEpCnMucG9wKCkKcmV0dXJu
+ITB9ZWxzZSBpZih0LmYuYihhKSl7cS5KbihhKQpyPXEuancoYSkKcz1xLmEKaWYoMD49cy5sZW5ndGgp
+cmV0dXJuIEguT0gocywtMSkKcy5wb3AoKQpyZXR1cm4gcn1lbHNlIHJldHVybiExfSwKbEs6ZnVuY3Rp
+b24oYSl7dmFyIHMscixxPXRoaXMuYwpxLmErPSJbIgpzPUouVTYoYSkKaWYocy5nb3IoYSkpe3RoaXMu
+aVUocy5xKGEsMCkpCmZvcihyPTE7cjxzLmdBKGEpOysrcil7cS5hKz0iLCIKdGhpcy5pVShzLnEoYSxy
+KSl9fXEuYSs9Il0ifSwKanc6ZnVuY3Rpb24oYSl7dmFyIHMscixxLHAsbyxuLG09dGhpcyxsPXt9Cmlm
+KGEuZ2wwKGEpKXttLmMuYSs9Int9IgpyZXR1cm4hMH1zPWEuZ0EoYSkqMgpyPVAuTzgocyxudWxsLCEx
+LHQuVykKcT1sLmE9MApsLmI9ITAKYS5LKDAsbmV3IFAudGkobCxyKSkKaWYoIWwuYilyZXR1cm4hMQpw
+PW0uYwpwLmErPSJ7Igpmb3Iobz0nIic7cTxzO3ErPTIsbz0nLCInKXtwLmErPW8KbS52cChILmgocltx
+XSkpCnAuYSs9JyI6JwpuPXErMQppZihuPj1zKXJldHVybiBILk9IKHIsbikKbS5pVShyW25dKX1wLmEr
+PSJ9IgpyZXR1cm4hMH19ClAudGkucHJvdG90eXBlPXsKJDI6ZnVuY3Rpb24oYSxiKXt2YXIgcyxyCmlm
+KHR5cGVvZiBhIT0ic3RyaW5nIil0aGlzLmEuYj0hMQpzPXRoaXMuYgpyPXRoaXMuYQpDLk5tLlk1KHMs
+ci5hKyssYSkKQy5ObS5ZNShzLHIuYSsrLGIpfSwKJFM6MTB9ClAudHUucHJvdG90eXBlPXsKZ1ZLOmZ1
+bmN0aW9uKCl7dmFyIHM9dGhpcy5jLmEKcmV0dXJuIHMuY2hhckNvZGVBdCgwKT09MD9zOnN9fQpQLnU1
+LnByb3RvdHlwZT17CmdaRTpmdW5jdGlvbigpe3JldHVybiBDLlFrfX0KUC5FMy5wcm90b3R5cGU9ewpX
+SjpmdW5jdGlvbihhKXt2YXIgcyxyLHEscD1QLmpCKDAsbnVsbCxhLmxlbmd0aCksbz1wLTAKaWYobz09
+PTApcmV0dXJuIG5ldyBVaW50OEFycmF5KDApCnM9byozCnI9bmV3IFVpbnQ4QXJyYXkocykKcT1uZXcg
+UC5SdyhyKQppZihxLkd4KGEsMCxwKSE9PXApe0ouYTYoYSxwLTEpCnEuUk8oKX1yZXR1cm4gbmV3IFVp
+bnQ4QXJyYXkoci5zdWJhcnJheSgwLEguck0oMCxxLmIscykpKX19ClAuUncucHJvdG90eXBlPXsKUk86
+ZnVuY3Rpb24oKXt2YXIgcz10aGlzLHI9cy5jLHE9cy5iLHA9cy5iPXErMSxvPXIubGVuZ3RoCmlmKHE+
+PW8pcmV0dXJuIEguT0gocixxKQpyW3FdPTIzOQpxPXMuYj1wKzEKaWYocD49bylyZXR1cm4gSC5PSChy
+LHApCnJbcF09MTkxCnMuYj1xKzEKaWYocT49bylyZXR1cm4gSC5PSChyLHEpCnJbcV09MTg5fSwKTzY6
+ZnVuY3Rpb24oYSxiKXt2YXIgcyxyLHEscCxvLG49dGhpcwppZigoYiY2NDUxMik9PT01NjMyMCl7cz02
+NTUzNisoKGEmMTAyMyk8PDEwKXxiJjEwMjMKcj1uLmMKcT1uLmIKcD1uLmI9cSsxCm89ci5sZW5ndGgK
+aWYocT49bylyZXR1cm4gSC5PSChyLHEpCnJbcV09cz4+PjE4fDI0MApxPW4uYj1wKzEKaWYocD49byly
+ZXR1cm4gSC5PSChyLHApCnJbcF09cz4+PjEyJjYzfDEyOApwPW4uYj1xKzEKaWYocT49bylyZXR1cm4g
+SC5PSChyLHEpCnJbcV09cz4+PjYmNjN8MTI4Cm4uYj1wKzEKaWYocD49bylyZXR1cm4gSC5PSChyLHAp
+CnJbcF09cyY2M3wxMjgKcmV0dXJuITB9ZWxzZXtuLlJPKCkKcmV0dXJuITF9fSwKR3g6ZnVuY3Rpb24o
+YSxiLGMpe3ZhciBzLHIscSxwLG8sbixtLGw9dGhpcwppZihiIT09YyYmKEMueEIuTzIoYSxjLTEpJjY0
+NTEyKT09PTU1Mjk2KS0tYwpmb3Iocz1sLmMscj1zLmxlbmd0aCxxPWI7cTxjOysrcSl7cD1DLnhCLlco
+YSxxKQppZihwPD0xMjcpe289bC5iCmlmKG8+PXIpYnJlYWsKbC5iPW8rMQpzW29dPXB9ZWxzZXtvPXAm
+NjQ1MTIKaWYobz09PTU1Mjk2KXtpZihsLmIrND5yKWJyZWFrCm49cSsxCmlmKGwuTzYocCxDLnhCLlco
+YSxuKSkpcT1ufWVsc2UgaWYobz09PTU2MzIwKXtpZihsLmIrMz5yKWJyZWFrCmwuUk8oKX1lbHNlIGlm
+KHA8PTIwNDcpe289bC5iCm09bysxCmlmKG0+PXIpYnJlYWsKbC5iPW0KaWYobz49cilyZXR1cm4gSC5P
+SChzLG8pCnNbb109cD4+PjZ8MTkyCmwuYj1tKzEKc1ttXT1wJjYzfDEyOH1lbHNle289bC5iCmlmKG8r
+Mj49cilicmVhawptPWwuYj1vKzEKaWYobz49cilyZXR1cm4gSC5PSChzLG8pCnNbb109cD4+PjEyfDIy
+NApvPWwuYj1tKzEKaWYobT49cilyZXR1cm4gSC5PSChzLG0pCnNbbV09cD4+PjYmNjN8MTI4CmwuYj1v
+KzEKaWYobz49cilyZXR1cm4gSC5PSChzLG8pCnNbb109cCY2M3wxMjh9fX1yZXR1cm4gcX19ClAuR1ku
+cHJvdG90eXBlPXsKV0o6ZnVuY3Rpb24oYSl7dmFyIHMscgp0LkwuYShhKQpzPXRoaXMuYQpyPVAua3ko
+cyxhLDAsbnVsbCkKaWYociE9bnVsbClyZXR1cm4gcgpyZXR1cm4gbmV3IFAuYnoocykuTmUoYSwwLG51
+bGwsITApfX0KUC5iei5wcm90b3R5cGU9ewpOZTpmdW5jdGlvbihhLGIsYyxkKXt2YXIgcyxyLHEscCxv
+LG49dGhpcwp0LkwuYShhKQpzPVAuakIoYixjLEouSG0oYSkpCmlmKGI9PT1zKXJldHVybiIiCnI9UC5q
+eShhLGIscykKcT1uLmhPKHIsMCxzLWIsITApCnA9bi5iCmlmKChwJjEpIT09MCl7bz1QLmo0KHApCm4u
+Yj0wCnRocm93IEguYihQLnJyKG8sYSxiK24uYykpfXJldHVybiBxfSwKaE86ZnVuY3Rpb24oYSxiLGMs
+ZCl7dmFyIHMscixxPXRoaXMKaWYoYy1iPjEwMDApe3M9Qy5qbi5CVShiK2MsMikKcj1xLmhPKGEsYixz
+LCExKQppZigocS5iJjEpIT09MClyZXR1cm4gcgpyZXR1cm4gcitxLmhPKGEscyxjLGQpfXJldHVybiBx
+LkVoKGEsYixjLGQpfSwKRWg6ZnVuY3Rpb24oYSxiLGMsZCl7dmFyIHMscixxLHAsbyxuLG0sbCxrPXRo
+aXMsaj02NTUzMyxpPWsuYixoPWsuYyxnPW5ldyBQLlJuKCIiKSxmPWIrMSxlPWEubGVuZ3RoCmlmKGI8
+MHx8Yj49ZSlyZXR1cm4gSC5PSChhLGIpCnM9YVtiXQokbGFiZWwwJDA6Zm9yKHI9ay5hOyEwOyl7Zm9y
+KDshMDtmPW8pe3E9Qy54Qi5XKCJBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFB
 QUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFB
-QUFBQUFBQUFBQUFBQUFBQUFBRkZGRkZGRkZGRkZGRkZGRkdHR0dHR0dHR0dHR0dHR0dISEhISEhISEhI
-SEhISEhISEhISEhISEhISEhJSEhISkVFQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCS0NDQ0ND
-Q0NDQ0NDQ0RDTE9OTk5NRUVFRUVFRUVFRUUiLHMpJjMxCmg9aTw9MzI/cyY2MTY5ND4+PnE6KHMmNjN8
-aDw8Nik+Pj4wCmk9Qy54Qi5XKCIgXHgwMDA6WEVDQ0NDQ046bERiIFx4MDAwOlhFQ0NDQ0NOdmxEYiBc
-eDAwMDpYRUNDQ0NDTjpsRGIgQUFBQUFceDAwXHgwMFx4MDBceDAwXHgwMEFBQUFBMDAwMDBBQUFBQTo6
-Ojo6QUFBQUFHRzAwMEFBQUFBMDBLS0tBQUFBQUc6Ojo6QUFBQUE6SUlJSUFBQUFBMDAwXHg4MDBBQUFB
-QVx4MDBceDAwXHgwMFx4MDAgQUFBQUEiLGkrcSkKaWYoaT09PTApe2cuYSs9SC5MdyhoKQppZihmPT09
-YylicmVhayAkbGFiZWwwJDAKYnJlYWt9ZWxzZSBpZigoaSYxKSE9PTApe2lmKHIpc3dpdGNoKGkpe2Nh
-c2UgNjk6Y2FzZSA2NzpnLmErPUguTHcoaikKYnJlYWsKY2FzZSA2NTpnLmErPUguTHcoaik7LS1mCmJy
-ZWFrCmRlZmF1bHQ6cD1nLmErPUguTHcoaikKZy5hPXArSC5MdyhqKQpicmVha31lbHNle2suYj1pCmsu
-Yz1mLTEKcmV0dXJuIiJ9aT0wfWlmKGY9PT1jKWJyZWFrICRsYWJlbDAkMApvPWYrMQppZihmPDB8fGY+
-PWUpcmV0dXJuIEguT0goYSxmKQpzPWFbZl19bz1mKzEKaWYoZjwwfHxmPj1lKXJldHVybiBILk9IKGEs
-ZikKcz1hW2ZdCmlmKHM8MTI4KXt3aGlsZSghMCl7aWYoIShvPGMpKXtuPWMKYnJlYWt9bT1vKzEKaWYo
-bzwwfHxvPj1lKXJldHVybiBILk9IKGEsbykKcz1hW29dCmlmKHM+PTEyOCl7bj1tLTEKbz1tCmJyZWFr
-fW89bX1pZihuLWY8MjApZm9yKGw9ZjtsPG47KytsKXtpZihsPj1lKXJldHVybiBILk9IKGEsbCkKZy5h
-Kz1ILkx3KGFbbF0pfWVsc2UgZy5hKz1QLkhNKGEsZixuKQppZihuPT09YylicmVhayAkbGFiZWwwJDAK
-Zj1vfWVsc2UgZj1vfWlmKGQmJmk+MzIpaWYocilnLmErPUguTHcoaikKZWxzZXtrLmI9NzcKay5jPWMK
-cmV0dXJuIiJ9ay5iPWkKay5jPWgKZT1nLmEKcmV0dXJuIGUuY2hhckNvZGVBdCgwKT09MD9lOmV9fQpQ
-LldGLnByb3RvdHlwZT17CiQyOmZ1bmN0aW9uKGEsYil7dmFyIHMscixxCnQuZm8uYShhKQpzPXRoaXMu
-YgpyPXRoaXMuYQpzLmErPXIuYQpxPXMuYSs9SC5FaihhLmEpCnMuYT1xKyI6ICIKcy5hKz1QLnAoYikK
-ci5hPSIsICJ9LAokUzo0Mn0KUC5pUC5wcm90b3R5cGU9ewpETjpmdW5jdGlvbihhLGIpe2lmKGI9PW51
-bGwpcmV0dXJuITEKcmV0dXJuIGIgaW5zdGFuY2VvZiBQLmlQJiZ0aGlzLmE9PT1iLmEmJiEwfSwKZ2lP
-OmZ1bmN0aW9uKGEpe3ZhciBzPXRoaXMuYQpyZXR1cm4oc15DLmpuLndHKHMsMzApKSYxMDczNzQxODIz
-fSwKdzpmdW5jdGlvbihhKXt2YXIgcz10aGlzLHI9UC5HcShILnRKKHMpKSxxPVAuaDAoSC5OUyhzKSks
-cD1QLmgwKEguakEocykpLG89UC5oMChILklYKHMpKSxuPVAuaDAoSC5jaChzKSksbT1QLmgwKEguSmQo
-cykpLGw9UC5WeChILm8xKHMpKSxrPXIrIi0iK3ErIi0iK3ArIiAiK28rIjoiK24rIjoiK20rIi4iK2wK
-cmV0dXJuIGt9fQpQLlhTLnByb3RvdHlwZT17CmdJSTpmdW5jdGlvbigpe3JldHVybiBILnRzKHRoaXMu
-JHRocm93bkpzRXJyb3IpfX0KUC5DNi5wcm90b3R5cGU9ewp3OmZ1bmN0aW9uKGEpe3ZhciBzPXRoaXMu
-YQppZihzIT1udWxsKXJldHVybiJBc3NlcnRpb24gZmFpbGVkOiAiK1AucChzKQpyZXR1cm4iQXNzZXJ0
-aW9uIGZhaWxlZCJ9fQpQLkV6LnByb3RvdHlwZT17fQpQLkYucHJvdG90eXBlPXsKdzpmdW5jdGlvbihh
-KXtyZXR1cm4iVGhyb3cgb2YgbnVsbC4ifX0KUC51LnByb3RvdHlwZT17CmdaOmZ1bmN0aW9uKCl7cmV0
-dXJuIkludmFsaWQgYXJndW1lbnQiKyghdGhpcy5hPyIocykiOiIiKX0sCmd1OmZ1bmN0aW9uKCl7cmV0
-dXJuIiJ9LAp3OmZ1bmN0aW9uKGEpe3ZhciBzLHIscT10aGlzLHA9cS5jLG89cD09bnVsbD8iIjoiICgi
-K3ArIikiLG49cS5kLG09bj09bnVsbD8iIjoiOiAiK0guRWoobiksbD1xLmdaKCkrbyttCmlmKCFxLmEp
-cmV0dXJuIGwKcz1xLmd1KCkKcj1QLnAocS5iKQpyZXR1cm4gbCtzKyI6ICIrcn19ClAuYkoucHJvdG90
-eXBlPXsKZ1o6ZnVuY3Rpb24oKXtyZXR1cm4iUmFuZ2VFcnJvciJ9LApndTpmdW5jdGlvbigpe3ZhciBz
-LHI9dGhpcy5lLHE9dGhpcy5mCmlmKHI9PW51bGwpcz1xIT1udWxsPyI6IE5vdCBsZXNzIHRoYW4gb3Ig
-ZXF1YWwgdG8gIitILkVqKHEpOiIiCmVsc2UgaWYocT09bnVsbClzPSI6IE5vdCBncmVhdGVyIHRoYW4g
-b3IgZXF1YWwgdG8gIitILkVqKHIpCmVsc2UgaWYocT5yKXM9IjogTm90IGluIGluY2x1c2l2ZSByYW5n
-ZSAiK0guRWoocikrIi4uIitILkVqKHEpCmVsc2Ugcz1xPHI/IjogVmFsaWQgdmFsdWUgcmFuZ2UgaXMg
-ZW1wdHkiOiI6IE9ubHkgdmFsaWQgdmFsdWUgaXMgIitILkVqKHIpCnJldHVybiBzfX0KUC5lWS5wcm90
-b3R5cGU9ewpnWjpmdW5jdGlvbigpe3JldHVybiJSYW5nZUVycm9yIn0sCmd1OmZ1bmN0aW9uKCl7dmFy
-IHMscj1ILnVQKHRoaXMuYikKaWYodHlwZW9mIHIhPT0ibnVtYmVyIilyZXR1cm4gci5KKCkKaWYocjww
-KXJldHVybiI6IGluZGV4IG11c3Qgbm90IGJlIG5lZ2F0aXZlIgpzPXRoaXMuZgppZihzPT09MClyZXR1
-cm4iOiBubyBpbmRpY2VzIGFyZSB2YWxpZCIKcmV0dXJuIjogaW5kZXggc2hvdWxkIGJlIGxlc3MgdGhh
-biAiK0guRWoocyl9LApnQTpmdW5jdGlvbihhKXtyZXR1cm4gdGhpcy5mfX0KUC5tcC5wcm90b3R5cGU9
-ewp3OmZ1bmN0aW9uKGEpe3ZhciBzLHIscSxwLG8sbixtLGwsaz10aGlzLGo9e30saT1uZXcgUC5Sbigi
-IikKai5hPSIiCnM9ay5jCmZvcihyPXMubGVuZ3RoLHE9MCxwPSIiLG89IiI7cTxyOysrcSxvPSIsICIp
-e249c1txXQppLmE9cCtvCnA9aS5hKz1QLnAobikKai5hPSIsICJ9ay5kLksoMCxuZXcgUC5XRihqLGkp
-KQptPVAucChrLmEpCmw9aS53KDApCnI9Ik5vU3VjaE1ldGhvZEVycm9yOiBtZXRob2Qgbm90IGZvdW5k
-OiAnIitILkVqKGsuYi5hKSsiJ1xuUmVjZWl2ZXI6ICIrbSsiXG5Bcmd1bWVudHM6IFsiK2wrIl0iCnJl
-dHVybiByfX0KUC51Yi5wcm90b3R5cGU9ewp3OmZ1bmN0aW9uKGEpe3JldHVybiJVbnN1cHBvcnRlZCBv
-cGVyYXRpb246ICIrdGhpcy5hfX0KUC5kcy5wcm90b3R5cGU9ewp3OmZ1bmN0aW9uKGEpe3ZhciBzPXRo
-aXMuYQpyZXR1cm4gcyE9bnVsbD8iVW5pbXBsZW1lbnRlZEVycm9yOiAiK3M6IlVuaW1wbGVtZW50ZWRF
-cnJvciJ9fQpQLmxqLnByb3RvdHlwZT17Cnc6ZnVuY3Rpb24oYSl7cmV0dXJuIkJhZCBzdGF0ZTogIit0
-aGlzLmF9fQpQLlVWLnByb3RvdHlwZT17Cnc6ZnVuY3Rpb24oYSl7dmFyIHM9dGhpcy5hCmlmKHM9PW51
-bGwpcmV0dXJuIkNvbmN1cnJlbnQgbW9kaWZpY2F0aW9uIGR1cmluZyBpdGVyYXRpb24uIgpyZXR1cm4i
-Q29uY3VycmVudCBtb2RpZmljYXRpb24gZHVyaW5nIGl0ZXJhdGlvbjogIitQLnAocykrIi4ifX0KUC5r
-NS5wcm90b3R5cGU9ewp3OmZ1bmN0aW9uKGEpe3JldHVybiJPdXQgb2YgTWVtb3J5In0sCmdJSTpmdW5j
-dGlvbigpe3JldHVybiBudWxsfSwKJGlYUzoxfQpQLktZLnByb3RvdHlwZT17Cnc6ZnVuY3Rpb24oYSl7
-cmV0dXJuIlN0YWNrIE92ZXJmbG93In0sCmdJSTpmdW5jdGlvbigpe3JldHVybiBudWxsfSwKJGlYUzox
-fQpQLmMucHJvdG90eXBlPXsKdzpmdW5jdGlvbihhKXt2YXIgcz10aGlzLmEKcmV0dXJuIHM9PW51bGw/
-IlJlYWRpbmcgc3RhdGljIHZhcmlhYmxlIGR1cmluZyBpdHMgaW5pdGlhbGl6YXRpb24iOiJSZWFkaW5n
-IHN0YXRpYyB2YXJpYWJsZSAnIitzKyInIGR1cmluZyBpdHMgaW5pdGlhbGl6YXRpb24ifX0KUC5DRC5w
-cm90b3R5cGU9ewp3OmZ1bmN0aW9uKGEpe3JldHVybiJFeGNlcHRpb246ICIrdGhpcy5hfSwKJGlSejox
-fQpQLmFFLnByb3RvdHlwZT17Cnc6ZnVuY3Rpb24oYSl7dmFyIHMscixxLHAsbyxuLG0sbCxrLGosaSxo
-LGc9dGhpcy5hLGY9ZyE9bnVsbCYmIiIhPT1nPyJGb3JtYXRFeGNlcHRpb246ICIrSC5FaihnKToiRm9y
-bWF0RXhjZXB0aW9uIixlPXRoaXMuYyxkPXRoaXMuYgppZih0eXBlb2YgZD09InN0cmluZyIpe2lmKGUh
-PW51bGwpcz1lPDB8fGU+ZC5sZW5ndGgKZWxzZSBzPSExCmlmKHMpZT1udWxsCmlmKGU9PW51bGwpe2lm
-KGQubGVuZ3RoPjc4KWQ9Qy54Qi5OaihkLDAsNzUpKyIuLi4iCnJldHVybiBmKyJcbiIrZH1mb3Iocj0x
-LHE9MCxwPSExLG89MDtvPGU7KytvKXtuPUMueEIuVyhkLG8pCmlmKG49PT0xMCl7aWYocSE9PW98fCFw
-KSsrcgpxPW8rMQpwPSExfWVsc2UgaWYobj09PTEzKXsrK3IKcT1vKzEKcD0hMH19Zj1yPjE/ZisoIiAo
-YXQgbGluZSAiK3IrIiwgY2hhcmFjdGVyICIrKGUtcSsxKSsiKVxuIik6ZisoIiAoYXQgY2hhcmFjdGVy
-ICIrKGUrMSkrIilcbiIpCm09ZC5sZW5ndGgKZm9yKG89ZTtvPG07KytvKXtuPUMueEIuTzIoZCxvKQpp
-ZihuPT09MTB8fG49PT0xMyl7bT1vCmJyZWFrfX1pZihtLXE+NzgpaWYoZS1xPDc1KXtsPXErNzUKaz1x
-Cmo9IiIKaT0iLi4uIn1lbHNle2lmKG0tZTw3NSl7az1tLTc1Cmw9bQppPSIifWVsc2V7az1lLTM2Cmw9
-ZSszNgppPSIuLi4ifWo9Ii4uLiJ9ZWxzZXtsPW0Kaz1xCmo9IiIKaT0iIn1oPUMueEIuTmooZCxrLGwp
-CnJldHVybiBmK2oraCtpKyJcbiIrQy54Qi5JeCgiICIsZS1rK2oubGVuZ3RoKSsiXlxuIn1lbHNlIHJl
-dHVybiBlIT1udWxsP2YrKCIgKGF0IG9mZnNldCAiK0guRWooZSkrIikiKTpmfSwKJGlSejoxfQpQLmNY
-LnByb3RvdHlwZT17CmRyOmZ1bmN0aW9uKGEsYil7cmV0dXJuIEguR0oodGhpcyxILkxoKHRoaXMpLkMo
-ImNYLkUiKSxiKX0sCkUyOmZ1bmN0aW9uKGEsYixjKXt2YXIgcz1ILkxoKHRoaXMpCnJldHVybiBILksx
-KHRoaXMscy5LcShjKS5DKCIxKGNYLkUpIikuYShiKSxzLkMoImNYLkUiKSxjKX0sCmV2OmZ1bmN0aW9u
-KGEsYil7dmFyIHM9SC5MaCh0aGlzKQpyZXR1cm4gbmV3IEguVTUodGhpcyxzLkMoImEyKGNYLkUpIiku
-YShiKSxzLkMoIlU1PGNYLkU+IikpfSwKdHQ6ZnVuY3Rpb24oYSxiKXtyZXR1cm4gUC5ZMSh0aGlzLGIs
-SC5MaCh0aGlzKS5DKCJjWC5FIikpfSwKYnI6ZnVuY3Rpb24oYSl7cmV0dXJuIHRoaXMudHQoYSwhMCl9
-LApnQTpmdW5jdGlvbihhKXt2YXIgcyxyPXRoaXMuZ20odGhpcykKZm9yKHM9MDtyLkYoKTspKytzCnJl
-dHVybiBzfSwKZ2wwOmZ1bmN0aW9uKGEpe3JldHVybiF0aGlzLmdtKHRoaXMpLkYoKX0sCmdvcjpmdW5j
-dGlvbihhKXtyZXR1cm4hdGhpcy5nbDAodGhpcyl9LAplUjpmdW5jdGlvbihhLGIpe3JldHVybiBILmJL
-KHRoaXMsYixILkxoKHRoaXMpLkMoImNYLkUiKSl9LApncjg6ZnVuY3Rpb24oYSl7dmFyIHMscj10aGlz
-LmdtKHRoaXMpCmlmKCFyLkYoKSl0aHJvdyBILmIoSC5XcCgpKQpzPXIuZ2woKQppZihyLkYoKSl0aHJv
-dyBILmIoSC5BbSgpKQpyZXR1cm4gc30sCkU6ZnVuY3Rpb24oYSxiKXt2YXIgcyxyLHEKUC5rMShiLCJp
-bmRleCIpCmZvcihzPXRoaXMuZ20odGhpcykscj0wO3MuRigpOyl7cT1zLmdsKCkKaWYoYj09PXIpcmV0
-dXJuIHE7KytyfXRocm93IEguYihQLkNmKGIsdGhpcywiaW5kZXgiLG51bGwscikpfSwKdzpmdW5jdGlv
-bihhKXtyZXR1cm4gUC5FUCh0aGlzLCIoIiwiKSIpfX0KUC5Bbi5wcm90b3R5cGU9e30KUC5OMy5wcm90
-b3R5cGU9ewp3OmZ1bmN0aW9uKGEpe3JldHVybiJNYXBFbnRyeSgiK0guRWooSi5qKHRoaXMuYSkpKyI6
-ICIrSC5FaihKLmoodGhpcy5iKSkrIikifX0KUC5jOC5wcm90b3R5cGU9ewpnaU86ZnVuY3Rpb24oYSl7
-cmV0dXJuIFAuTWgucHJvdG90eXBlLmdpTy5jYWxsKEMuak4sdGhpcyl9LAp3OmZ1bmN0aW9uKGEpe3Jl
-dHVybiJudWxsIn19ClAuTWgucHJvdG90eXBlPXtjb25zdHJ1Y3RvcjpQLk1oLCRpTWg6MSwKRE46ZnVu
-Y3Rpb24oYSxiKXtyZXR1cm4gdGhpcz09PWJ9LApnaU86ZnVuY3Rpb24oYSl7cmV0dXJuIEguZVEodGhp
-cyl9LAp3OmZ1bmN0aW9uKGEpe3JldHVybiJJbnN0YW5jZSBvZiAnIitILkVqKEguTSh0aGlzKSkrIici
-fSwKZTc6ZnVuY3Rpb24oYSxiKXt0Lm8uYShiKQp0aHJvdyBILmIoUC5scih0aGlzLGIuZ1dhKCksYi5n
-bmQoKSxiLmdWbSgpKSl9LAp0b1N0cmluZzpmdW5jdGlvbigpe3JldHVybiB0aGlzLncodGhpcyl9fQpQ
-LlpkLnByb3RvdHlwZT17Cnc6ZnVuY3Rpb24oYSl7cmV0dXJuIiJ9LAokaUd6OjF9ClAuUm4ucHJvdG90
-eXBlPXsKZ0E6ZnVuY3Rpb24oYSl7cmV0dXJuIHRoaXMuYS5sZW5ndGh9LAp3OmZ1bmN0aW9uKGEpe3Zh
-ciBzPXRoaXMuYQpyZXR1cm4gcy5jaGFyQ29kZUF0KDApPT0wP3M6c30sCiRpQkw6MX0KUC5uMS5wcm90
-b3R5cGU9ewokMjpmdW5jdGlvbihhLGIpe3ZhciBzLHIscSxwCnQuSi5hKGEpCkguaChiKQpzPUouclko
-YikuT1koYiwiPSIpCmlmKHM9PT0tMSl7aWYoYiE9PSIiKWEuWSgwLFAua3UoYiwwLGIubGVuZ3RoLHRo
-aXMuYSwhMCksIiIpfWVsc2UgaWYocyE9PTApe3I9Qy54Qi5OaihiLDAscykKcT1DLnhCLkcoYixzKzEp
-CnA9dGhpcy5hCmEuWSgwLFAua3UociwwLHIubGVuZ3RoLHAsITApLFAua3UocSwwLHEubGVuZ3RoLHAs
-ITApKX1yZXR1cm4gYX0sCiRTOjQ0fQpQLmNTLnByb3RvdHlwZT17CiQyOmZ1bmN0aW9uKGEsYil7dGhy
-b3cgSC5iKFAucnIoIklsbGVnYWwgSVB2NCBhZGRyZXNzLCAiK2EsdGhpcy5hLGIpKX0sCiRTOjIxfQpQ
-LlZDLnByb3RvdHlwZT17CiQyOmZ1bmN0aW9uKGEsYil7dGhyb3cgSC5iKFAucnIoIklsbGVnYWwgSVB2
-NiBhZGRyZXNzLCAiK2EsdGhpcy5hLGIpKX0sCiQxOmZ1bmN0aW9uKGEpe3JldHVybiB0aGlzLiQyKGEs
-bnVsbCl9LAokUzo0OX0KUC5KVC5wcm90b3R5cGU9ewokMjpmdW5jdGlvbihhLGIpe3ZhciBzCmlmKGIt
-YT40KXRoaXMuYS4kMigiYW4gSVB2NiBwYXJ0IGNhbiBvbmx5IGNvbnRhaW4gYSBtYXhpbXVtIG9mIDQg
-aGV4IGRpZ2l0cyIsYSkKcz1QLlFBKEMueEIuTmoodGhpcy5iLGEsYiksMTYpCmlmKHM8MHx8cz42NTUz
-NSl0aGlzLmEuJDIoImVhY2ggcGFydCBtdXN0IGJlIGluIHRoZSByYW5nZSBvZiBgMHgwLi4weEZGRkZg
-IixhKQpyZXR1cm4gc30sCiRTOjUxfQpQLkRuLnByb3RvdHlwZT17CmduRDpmdW5jdGlvbigpe3ZhciBz
-LHIscSxwLG89dGhpcwppZighby55KXtzPW8uYQpyPXMubGVuZ3RoIT09MD9zKyI6IjoiIgpxPW8uYwpw
-PXE9PW51bGwKaWYoIXB8fHM9PT0iZmlsZSIpe3M9cisiLy8iCnI9by5iCmlmKHIubGVuZ3RoIT09MClz
-PXMrcisiQCIKaWYoIXApcys9cQpyPW8uZAppZihyIT1udWxsKXM9cysiOiIrSC5FaihyKX1lbHNlIHM9
-cgpzKz1vLmUKcj1vLmYKaWYociE9bnVsbClzPXMrIj8iK3IKcj1vLnIKaWYociE9bnVsbClzPXMrIiMi
-K3IKaWYoby55KXRocm93IEguYihILkdRKCJfdGV4dCIpKQpvLng9cy5jaGFyQ29kZUF0KDApPT0wP3M6
-cwpvLnk9ITB9cmV0dXJuIG8ueH0sCmdGajpmdW5jdGlvbigpe3ZhciBzLHIscT10aGlzCmlmKCFxLlEp
-e3M9cS5lCmlmKHMubGVuZ3RoIT09MCYmQy54Qi5XKHMsMCk9PT00NylzPUMueEIuRyhzLDEpCnI9cy5s
-ZW5ndGg9PT0wP0MueEQ6UC5BRihuZXcgSC5sSihILlZNKHMuc3BsaXQoIi8iKSx0LnMpLHQuZE8uYShQ
-LlBIKCkpLHQuZG8pLHQuTikKaWYocS5RKXRocm93IEguYihILkdRKCJwYXRoU2VnbWVudHMiKSkKcS5z
-S3AocikKcS5RPSEwfXJldHVybiBxLnp9LApnaU86ZnVuY3Rpb24oYSl7dmFyIHMscj10aGlzCmlmKCFy
-LmN4KXtzPUouaGYoci5nbkQoKSkKaWYoci5jeCl0aHJvdyBILmIoSC5HUSgiaGFzaENvZGUiKSkKci5j
-aD1zCnIuY3g9ITB9cmV0dXJuIHIuY2h9LApnaFk6ZnVuY3Rpb24oKXt2YXIgcyxyPXRoaXMKaWYoIXIu
-ZGIpe3M9UC5XWChyLmd0UCgpKQppZihyLmRiKXRocm93IEguYihILkdRKCJxdWVyeVBhcmFtZXRlcnMi
-KSkKci5zTk0obmV3IFAuR2oocyx0LmR3KSkKci5kYj0hMH1yZXR1cm4gci5jeX0sCmdrdTpmdW5jdGlv
-bigpe3JldHVybiB0aGlzLmJ9LApnSmY6ZnVuY3Rpb24oYSl7dmFyIHM9dGhpcy5jCmlmKHM9PW51bGwp
-cmV0dXJuIiIKaWYoQy54Qi5uKHMsIlsiKSlyZXR1cm4gQy54Qi5OaihzLDEscy5sZW5ndGgtMSkKcmV0
-dXJuIHN9LApndHA6ZnVuY3Rpb24oYSl7dmFyIHM9dGhpcy5kCnJldHVybiBzPT1udWxsP1Aud0sodGhp
-cy5hKTpzfSwKZ3RQOmZ1bmN0aW9uKCl7dmFyIHM9dGhpcy5mCnJldHVybiBzPT1udWxsPyIiOnN9LApn
-S2E6ZnVuY3Rpb24oKXt2YXIgcz10aGlzLnIKcmV0dXJuIHM9PW51bGw/IiI6c30sCm5tOmZ1bmN0aW9u
-KGEsYil7dmFyIHMscixxLHAsbyxuLG0sbCxrLGo9dGhpcwp0LmM5LmEoYikKcz1qLmEKcj1zPT09ImZp
-bGUiCnE9ai5iCnA9ai5kCm89ai5jCmlmKCEobyE9bnVsbCkpbz1xLmxlbmd0aCE9PTB8fHAhPW51bGx8
-fHI/IiI6bnVsbApuPWouZQppZighciltPW8hPW51bGwmJm4ubGVuZ3RoIT09MAplbHNlIG09ITAKaWYo
-bSYmIUMueEIubihuLCIvIikpbj0iLyIrbgpsPW4Kaz1QLmxlKG51bGwsMCwwLGIpCnJldHVybiBuZXcg
-UC5EbihzLHEsbyxwLGwsayxqLnIpfSwKSmg6ZnVuY3Rpb24oYSxiKXt2YXIgcyxyLHEscCxvLG4KZm9y
-KHM9MCxyPTA7Qy54Qi5RaShiLCIuLi8iLHIpOyl7cis9MzsrK3N9cT1DLnhCLmNuKGEsIi8iKQp3aGls
-ZSghMCl7aWYoIShxPjAmJnM+MCkpYnJlYWsKcD1DLnhCLlBrKGEsIi8iLHEtMSkKaWYocDwwKWJyZWFr
-Cm89cS1wCm49byE9PTIKaWYoIW58fG89PT0zKWlmKEMueEIuTzIoYSxwKzEpPT09NDYpbj0hbnx8Qy54
-Qi5PMihhLHArMik9PT00NgplbHNlIG49ITEKZWxzZSBuPSExCmlmKG4pYnJlYWs7LS1zCnE9cH1yZXR1
-cm4gQy54Qi5pNyhhLHErMSxudWxsLEMueEIuRyhiLHItMypzKSl9LApaSTpmdW5jdGlvbihhKXtyZXR1
-cm4gdGhpcy5tUyhQLmhLKGEpKX0sCm1TOmZ1bmN0aW9uKGEpe3ZhciBzLHIscSxwLG8sbixtLGwsayxq
-PXRoaXMsaT1udWxsCmlmKGEuZ0ZpKCkubGVuZ3RoIT09MCl7cz1hLmdGaSgpCmlmKGEuZ2NqKCkpe3I9
-YS5na3UoKQpxPWEuZ0pmKGEpCnA9YS5neEEoKT9hLmd0cChhKTppfWVsc2V7cD1pCnE9cApyPSIifW89
-UC54ZShhLmdJaShhKSkKbj1hLmdRRCgpP2EuZ3RQKCk6aX1lbHNle3M9ai5hCmlmKGEuZ2NqKCkpe3I9
-YS5na3UoKQpxPWEuZ0pmKGEpCnA9UC53QihhLmd4QSgpP2EuZ3RwKGEpOmkscykKbz1QLnhlKGEuZ0lp
-KGEpKQpuPWEuZ1FEKCk/YS5ndFAoKTppfWVsc2V7cj1qLmIKcT1qLmMKcD1qLmQKaWYoYS5nSWkoYSk9
-PT0iIil7bz1qLmUKbj1hLmdRRCgpP2EuZ3RQKCk6ai5mfWVsc2V7aWYoYS5ndFQoKSlvPVAueGUoYS5n
-SWkoYSkpCmVsc2V7bT1qLmUKaWYobS5sZW5ndGg9PT0wKWlmKHE9PW51bGwpbz1zLmxlbmd0aD09PTA/
-YS5nSWkoYSk6UC54ZShhLmdJaShhKSkKZWxzZSBvPVAueGUoIi8iK2EuZ0lpKGEpKQplbHNle2w9ai5K
-aChtLGEuZ0lpKGEpKQprPXMubGVuZ3RoPT09MAppZigha3x8cSE9bnVsbHx8Qy54Qi5uKG0sIi8iKSlv
-PVAueGUobCkKZWxzZSBvPVAud0YobCwha3x8cSE9bnVsbCl9fW49YS5nUUQoKT9hLmd0UCgpOml9fX1y
-ZXR1cm4gbmV3IFAuRG4ocyxyLHEscCxvLG4sYS5nWjgoKT9hLmdLYSgpOmkpfSwKZ2NqOmZ1bmN0aW9u
-KCl7cmV0dXJuIHRoaXMuYyE9bnVsbH0sCmd4QTpmdW5jdGlvbigpe3JldHVybiB0aGlzLmQhPW51bGx9
-LApnUUQ6ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5mIT1udWxsfSwKZ1o4OmZ1bmN0aW9uKCl7cmV0dXJu
-IHRoaXMuciE9bnVsbH0sCmd0VDpmdW5jdGlvbigpe3JldHVybiBDLnhCLm4odGhpcy5lLCIvIil9LAp0
-NDpmdW5jdGlvbigpe3ZhciBzLHI9dGhpcyxxPXIuYQppZihxIT09IiImJnEhPT0iZmlsZSIpdGhyb3cg
-SC5iKFAuTDQoIkNhbm5vdCBleHRyYWN0IGEgZmlsZSBwYXRoIGZyb20gYSAiK3ErIiBVUkkiKSkKaWYo
-ci5ndFAoKSE9PSIiKXRocm93IEguYihQLkw0KHUuaSkpCmlmKHIuZ0thKCkhPT0iIil0aHJvdyBILmIo
-UC5MNCh1LmwpKQpxPSQud1EoKQppZihILm9UKHEpKXE9UC5tbihyKQplbHNle2lmKHIuYyE9bnVsbCYm
-ci5nSmYocikhPT0iIilILnYoUC5MNCh1LmopKQpzPXIuZ0ZqKCkKUC5rRShzLCExKQpxPVAudmcoQy54
-Qi5uKHIuZSwiLyIpPyIvIjoiIixzLCIvIikKcT1xLmNoYXJDb2RlQXQoMCk9PTA/cTpxfXJldHVybiBx
-fSwKdzpmdW5jdGlvbihhKXtyZXR1cm4gdGhpcy5nbkQoKX0sCkROOmZ1bmN0aW9uKGEsYil7dmFyIHM9
-dGhpcwppZihiPT1udWxsKXJldHVybiExCmlmKHM9PT1iKXJldHVybiEwCnJldHVybiB0LmRELmIoYikm
-JnMuYT09PWIuZ0ZpKCkmJnMuYyE9bnVsbD09PWIuZ2NqKCkmJnMuYj09PWIuZ2t1KCkmJnMuZ0pmKHMp
-PT09Yi5nSmYoYikmJnMuZ3RwKHMpPT09Yi5ndHAoYikmJnMuZT09PWIuZ0lpKGIpJiZzLmYhPW51bGw9
-PT1iLmdRRCgpJiZzLmd0UCgpPT09Yi5ndFAoKSYmcy5yIT1udWxsPT09Yi5nWjgoKSYmcy5nS2EoKT09
-PWIuZ0thKCl9LApzS3A6ZnVuY3Rpb24oYSl7dGhpcy56PXQuYmsuYShhKX0sCnNOTTpmdW5jdGlvbihh
-KXt0aGlzLmN5PXQuY1ouYShhKX0sCiRpaUQ6MSwKZ0ZpOmZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMuYX0s
-CmdJaTpmdW5jdGlvbihhKXtyZXR1cm4gdGhpcy5lfX0KUC5SWi5wcm90b3R5cGU9ewokMTpmdW5jdGlv
-bihhKXtyZXR1cm4gUC5lUChDLlpKLEguaChhKSxDLnhNLCExKX0sCiRTOjV9ClAuTUUucHJvdG90eXBl
-PXsKJDI6ZnVuY3Rpb24oYSxiKXt2YXIgcz10aGlzLmIscj10aGlzLmEKcy5hKz1yLmEKci5hPSImIgpy
-PXMuYSs9SC5FaihQLmVQKEMuRjMsYSxDLnhNLCEwKSkKaWYoYiE9bnVsbCYmYi5sZW5ndGghPT0wKXtz
-LmE9cisiPSIKcy5hKz1ILkVqKFAuZVAoQy5GMyxiLEMueE0sITApKX19LAokUzoyMn0KUC55NS5wcm90
-b3R5cGU9ewokMjpmdW5jdGlvbihhLGIpe3ZhciBzLHIKSC5oKGEpCmlmKGI9PW51bGx8fHR5cGVvZiBi
-PT0ic3RyaW5nIil0aGlzLmEuJDIoYSxILmsoYikpCmVsc2UgZm9yKHM9Si5JVCh0LnUuYShiKSkscj10
-aGlzLmE7cy5GKCk7KXIuJDIoYSxILmgocy5nbCgpKSl9LAokUzoxMn0KUC5QRS5wcm90b3R5cGU9ewpn
-bFI6ZnVuY3Rpb24oKXt2YXIgcyxyLHEscCxvPXRoaXMsbj1udWxsLG09by5jCmlmKG09PW51bGwpe209
-by5iCmlmKDA+PW0ubGVuZ3RoKXJldHVybiBILk9IKG0sMCkKcz1vLmEKbT1tWzBdKzEKcj1DLnhCLlhV
-KHMsIj8iLG0pCnE9cy5sZW5ndGgKaWYocj49MCl7cD1QLlBJKHMscisxLHEsQy5WQywhMSkKcT1yfWVs
-c2UgcD1uCm09by5jPW5ldyBQLnFlKCJkYXRhIiwiIixuLG4sUC5QSShzLG0scSxDLldkLCExKSxwLG4p
-fXJldHVybiBtfSwKdzpmdW5jdGlvbihhKXt2YXIgcyxyPXRoaXMuYgppZigwPj1yLmxlbmd0aClyZXR1
-cm4gSC5PSChyLDApCnM9dGhpcy5hCnJldHVybiByWzBdPT09LTE/ImRhdGE6IitzOnN9fQpQLnlJLnBy
-b3RvdHlwZT17CiQyOmZ1bmN0aW9uKGEsYil7dmFyIHM9dGhpcy5hCmlmKGE+PXMubGVuZ3RoKXJldHVy
-biBILk9IKHMsYSkKcz1zW2FdCkMuTkEuZHUocywwLDk2LGIpCnJldHVybiBzfSwKJFM6MjN9ClAuYzYu
-cHJvdG90eXBlPXsKJDM6ZnVuY3Rpb24oYSxiLGMpe3ZhciBzLHIscQpmb3Iocz1iLmxlbmd0aCxyPTA7
-cjxzOysrcil7cT1DLnhCLlcoYixyKV45NgppZihxPj05NilyZXR1cm4gSC5PSChhLHEpCmFbcV09Y319
-LAokUzoxM30KUC5xZC5wcm90b3R5cGU9ewokMzpmdW5jdGlvbihhLGIsYyl7dmFyIHMscixxCmZvcihz
-PUMueEIuVyhiLDApLHI9Qy54Qi5XKGIsMSk7czw9cjsrK3Mpe3E9KHNeOTYpPj4+MAppZihxPj05Nily
-ZXR1cm4gSC5PSChhLHEpCmFbcV09Y319LAokUzoxM30KUC5VZi5wcm90b3R5cGU9ewpnY2o6ZnVuY3Rp
-b24oKXtyZXR1cm4gdGhpcy5jPjB9LApneEE6ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5jPjAmJnRoaXMu
-ZCsxPHRoaXMuZX0sCmdRRDpmdW5jdGlvbigpe3JldHVybiB0aGlzLmY8dGhpcy5yfSwKZ1o4OmZ1bmN0
-aW9uKCl7cmV0dXJuIHRoaXMucjx0aGlzLmEubGVuZ3RofSwKZ053OmZ1bmN0aW9uKCl7cmV0dXJuIHRo
-aXMuYj09PTQmJkMueEIubih0aGlzLmEsImZpbGUiKX0sCmdXWjpmdW5jdGlvbigpe3JldHVybiB0aGlz
-LmI9PT00JiZDLnhCLm4odGhpcy5hLCJodHRwIil9LApnUmU6ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5i
-PT09NSYmQy54Qi5uKHRoaXMuYSwiaHR0cHMiKX0sCmd0VDpmdW5jdGlvbigpe3JldHVybiBDLnhCLlFp
-KHRoaXMuYSwiLyIsdGhpcy5lKX0sCmdGaTpmdW5jdGlvbigpe3ZhciBzPXRoaXMueApyZXR1cm4gcz09
-bnVsbD90aGlzLng9dGhpcy5VMigpOnN9LApVMjpmdW5jdGlvbigpe3ZhciBzPXRoaXMscj1zLmIKaWYo
-cjw9MClyZXR1cm4iIgppZihzLmdXWigpKXJldHVybiJodHRwIgppZihzLmdSZSgpKXJldHVybiJodHRw
-cyIKaWYocy5nTncoKSlyZXR1cm4iZmlsZSIKaWYocj09PTcmJkMueEIubihzLmEsInBhY2thZ2UiKSly
-ZXR1cm4icGFja2FnZSIKcmV0dXJuIEMueEIuTmoocy5hLDAscil9LApna3U6ZnVuY3Rpb24oKXt2YXIg
-cz10aGlzLmMscj10aGlzLmIrMwpyZXR1cm4gcz5yP0MueEIuTmoodGhpcy5hLHIscy0xKToiIn0sCmdK
-ZjpmdW5jdGlvbihhKXt2YXIgcz10aGlzLmMKcmV0dXJuIHM+MD9DLnhCLk5qKHRoaXMuYSxzLHRoaXMu
-ZCk6IiJ9LApndHA6ZnVuY3Rpb24oYSl7dmFyIHM9dGhpcwppZihzLmd4QSgpKXJldHVybiBQLlFBKEMu
-eEIuTmoocy5hLHMuZCsxLHMuZSksbnVsbCkKaWYocy5nV1ooKSlyZXR1cm4gODAKaWYocy5nUmUoKSly
-ZXR1cm4gNDQzCnJldHVybiAwfSwKZ0lpOmZ1bmN0aW9uKGEpe3JldHVybiBDLnhCLk5qKHRoaXMuYSx0
-aGlzLmUsdGhpcy5mKX0sCmd0UDpmdW5jdGlvbigpe3ZhciBzPXRoaXMuZixyPXRoaXMucgpyZXR1cm4g
-czxyP0MueEIuTmoodGhpcy5hLHMrMSxyKToiIn0sCmdLYTpmdW5jdGlvbigpe3ZhciBzPXRoaXMucixy
-PXRoaXMuYQpyZXR1cm4gczxyLmxlbmd0aD9DLnhCLkcocixzKzEpOiIifSwKZ0ZqOmZ1bmN0aW9uKCl7
-dmFyIHMscixxPXRoaXMuZSxwPXRoaXMuZixvPXRoaXMuYQppZihDLnhCLlFpKG8sIi8iLHEpKSsrcQpp
-ZihxPT09cClyZXR1cm4gQy54RApzPUguVk0oW10sdC5zKQpmb3Iocj1xO3I8cDsrK3IpaWYoQy54Qi5P
-MihvLHIpPT09NDcpe0MuTm0uaShzLEMueEIuTmoobyxxLHIpKQpxPXIrMX1DLk5tLmkocyxDLnhCLk5q
-KG8scSxwKSkKcmV0dXJuIFAuQUYocyx0Lk4pfSwKZ2hZOmZ1bmN0aW9uKCl7aWYodGhpcy5mPj10aGlz
-LnIpcmV0dXJuIEMuQ00KcmV0dXJuIG5ldyBQLkdqKFAuV1godGhpcy5ndFAoKSksdC5kdyl9LAprWDpm
-dW5jdGlvbihhKXt2YXIgcz10aGlzLmQrMQpyZXR1cm4gcythLmxlbmd0aD09PXRoaXMuZSYmQy54Qi5R
-aSh0aGlzLmEsYSxzKX0sCk45OmZ1bmN0aW9uKCl7dmFyIHM9dGhpcyxyPXMucixxPXMuYQppZihyPj1x
-Lmxlbmd0aClyZXR1cm4gcwpyZXR1cm4gbmV3IFAuVWYoQy54Qi5OaihxLDAscikscy5iLHMuYyxzLmQs
-cy5lLHMuZixyLHMueCl9LApubTpmdW5jdGlvbihhLGIpe3ZhciBzLHIscSxwLG8sbixtLGwsayxqLGk9
-dGhpcyxoPW51bGwKdC5jOS5hKGIpCnM9aS5nRmkoKQpyPXM9PT0iZmlsZSIKcT1pLmMKcD1xPjA/Qy54
-Qi5OaihpLmEsaS5iKzMscSk6IiIKbz1pLmd4QSgpP2kuZ3RwKGkpOmgKcT1pLmMKaWYocT4wKW49Qy54
-Qi5OaihpLmEscSxpLmQpCmVsc2Ugbj1wLmxlbmd0aCE9PTB8fG8hPW51bGx8fHI/IiI6aApxPWkuYQpt
-PUMueEIuTmoocSxpLmUsaS5mKQppZighcilsPW4hPW51bGwmJm0ubGVuZ3RoIT09MAplbHNlIGw9ITAK
-aWYobCYmIUMueEIubihtLCIvIikpbT0iLyIrbQprPVAubGUoaCwwLDAsYikKbD1pLnIKaj1sPHEubGVu
-Z3RoP0MueEIuRyhxLGwrMSk6aApyZXR1cm4gbmV3IFAuRG4ocyxwLG4sbyxtLGssail9LApaSTpmdW5j
-dGlvbihhKXtyZXR1cm4gdGhpcy5tUyhQLmhLKGEpKX0sCm1TOmZ1bmN0aW9uKGEpe2lmKGEgaW5zdGFu
-Y2VvZiBQLlVmKXJldHVybiB0aGlzLnUxKHRoaXMsYSkKcmV0dXJuIHRoaXMudnMoKS5tUyhhKX0sCnUx
-OmZ1bmN0aW9uKGEsYil7dmFyIHMscixxLHAsbyxuLG0sbCxrLGosaSxoLGc9Yi5iCmlmKGc+MClyZXR1
-cm4gYgpzPWIuYwppZihzPjApe3I9YS5iCmlmKHI8PTApcmV0dXJuIGIKaWYoYS5nTncoKSlxPWIuZSE9
-PWIuZgplbHNlIGlmKGEuZ1daKCkpcT0hYi5rWCgiODAiKQplbHNlIHE9IWEuZ1JlKCl8fCFiLmtYKCI0
-NDMiKQppZihxKXtwPXIrMQpyZXR1cm4gbmV3IFAuVWYoQy54Qi5OaihhLmEsMCxwKStDLnhCLkcoYi5h
-LGcrMSkscixzK3AsYi5kK3AsYi5lK3AsYi5mK3AsYi5yK3AsYS54KX1lbHNlIHJldHVybiB0aGlzLnZz
-KCkubVMoYil9bz1iLmUKZz1iLmYKaWYobz09PWcpe3M9Yi5yCmlmKGc8cyl7cj1hLmYKcD1yLWcKcmV0
-dXJuIG5ldyBQLlVmKEMueEIuTmooYS5hLDAscikrQy54Qi5HKGIuYSxnKSxhLmIsYS5jLGEuZCxhLmUs
-ZytwLHMrcCxhLngpfWc9Yi5hCmlmKHM8Zy5sZW5ndGgpe3I9YS5yCnJldHVybiBuZXcgUC5VZihDLnhC
-Lk5qKGEuYSwwLHIpK0MueEIuRyhnLHMpLGEuYixhLmMsYS5kLGEuZSxhLmYscysoci1zKSxhLngpfXJl
-dHVybiBhLk45KCl9cz1iLmEKaWYoQy54Qi5RaShzLCIvIixvKSl7cj1hLmUKcD1yLW8KcmV0dXJuIG5l
-dyBQLlVmKEMueEIuTmooYS5hLDAscikrQy54Qi5HKHMsbyksYS5iLGEuYyxhLmQscixnK3AsYi5yK3As
-YS54KX1uPWEuZQptPWEuZgppZihuPT09bSYmYS5jPjApe2Zvcig7Qy54Qi5RaShzLCIuLi8iLG8pOylv
-Kz0zCnA9bi1vKzEKcmV0dXJuIG5ldyBQLlVmKEMueEIuTmooYS5hLDAsbikrIi8iK0MueEIuRyhzLG8p
-LGEuYixhLmMsYS5kLG4sZytwLGIucitwLGEueCl9bD1hLmEKZm9yKGs9bjtDLnhCLlFpKGwsIi4uLyIs
-ayk7KWsrPTMKaj0wCndoaWxlKCEwKXtpPW8rMwppZighKGk8PWcmJkMueEIuUWkocywiLi4vIixvKSkp
-YnJlYWs7KytqCm89aX1mb3IoaD0iIjttPms7KXstLW0KaWYoQy54Qi5PMihsLG0pPT09NDcpe2lmKGo9
-PT0wKXtoPSIvIgpicmVha30tLWoKaD0iLyJ9fWlmKG09PT1rJiZhLmI8PTAmJiFDLnhCLlFpKGwsIi8i
-LG4pKXtvLT1qKjMKaD0iIn1wPW0tbytoLmxlbmd0aApyZXR1cm4gbmV3IFAuVWYoQy54Qi5OaihsLDAs
-bSkraCtDLnhCLkcocyxvKSxhLmIsYS5jLGEuZCxuLGcrcCxiLnIrcCxhLngpfSwKdDQ6ZnVuY3Rpb24o
-KXt2YXIgcyxyLHEscD10aGlzCmlmKHAuYj49MCYmIXAuZ053KCkpdGhyb3cgSC5iKFAuTDQoIkNhbm5v
-dCBleHRyYWN0IGEgZmlsZSBwYXRoIGZyb20gYSAiK3AuZ0ZpKCkrIiBVUkkiKSkKcz1wLmYKcj1wLmEK
-aWYoczxyLmxlbmd0aCl7aWYoczxwLnIpdGhyb3cgSC5iKFAuTDQodS5pKSkKdGhyb3cgSC5iKFAuTDQo
-dS5sKSl9cT0kLndRKCkKaWYoSC5vVChxKSlzPVAubW4ocCkKZWxzZXtpZihwLmM8cC5kKUgudihQLkw0
-KHUuaikpCnM9Qy54Qi5OaihyLHAuZSxzKX1yZXR1cm4gc30sCmdpTzpmdW5jdGlvbihhKXt2YXIgcz10
-aGlzLnkKcmV0dXJuIHM9PW51bGw/dGhpcy55PUMueEIuZ2lPKHRoaXMuYSk6c30sCkROOmZ1bmN0aW9u
-KGEsYil7aWYoYj09bnVsbClyZXR1cm4hMQppZih0aGlzPT09YilyZXR1cm4hMApyZXR1cm4gdC5kRC5i
-KGIpJiZ0aGlzLmE9PT1iLncoMCl9LAp2czpmdW5jdGlvbigpe3ZhciBzPXRoaXMscj1udWxsLHE9cy5n
-RmkoKSxwPXMuZ2t1KCksbz1zLmM+MD9zLmdKZihzKTpyLG49cy5neEEoKT9zLmd0cChzKTpyLG09cy5h
-LGw9cy5mLGs9Qy54Qi5OaihtLHMuZSxsKSxqPXMucgpsPWw8aj9zLmd0UCgpOnIKcmV0dXJuIG5ldyBQ
-LkRuKHEscCxvLG4sayxsLGo8bS5sZW5ndGg/cy5nS2EoKTpyKX0sCnc6ZnVuY3Rpb24oYSl7cmV0dXJu
-IHRoaXMuYX0sCiRpaUQ6MX0KUC5xZS5wcm90b3R5cGU9e30KVy5xRS5wcm90b3R5cGU9e30KVy5HaC5w
-cm90b3R5cGU9ewpzTFU6ZnVuY3Rpb24oYSxiKXthLmhyZWY9Yn0sCnc6ZnVuY3Rpb24oYSl7cmV0dXJu
-IFN0cmluZyhhKX0sCiRpR2g6MX0KVy5mWS5wcm90b3R5cGU9ewp3OmZ1bmN0aW9uKGEpe3JldHVybiBT
-dHJpbmcoYSl9fQpXLm5CLnByb3RvdHlwZT17JGluQjoxfQpXLkF6LnByb3RvdHlwZT17JGlBejoxfQpX
-LlFQLnByb3RvdHlwZT17JGlRUDoxfQpXLm54LnByb3RvdHlwZT17CmdBOmZ1bmN0aW9uKGEpe3JldHVy
-biBhLmxlbmd0aH19Clcub0oucHJvdG90eXBlPXsKZ0E6ZnVuY3Rpb24oYSl7cmV0dXJuIGEubGVuZ3Ro
-fX0KVy5pZC5wcm90b3R5cGU9e30KVy5RRi5wcm90b3R5cGU9e30KVy5OaC5wcm90b3R5cGU9ewp3OmZ1
-bmN0aW9uKGEpe3JldHVybiBTdHJpbmcoYSl9fQpXLmFlLnByb3RvdHlwZT17CkRjOmZ1bmN0aW9uKGEs
-Yil7cmV0dXJuIGEuY3JlYXRlSFRNTERvY3VtZW50KGIpfX0KVy5JQi5wcm90b3R5cGU9ewp3OmZ1bmN0
-aW9uKGEpe3ZhciBzLHI9YS5sZWZ0CnIudG9TdHJpbmcKcj0iUmVjdGFuZ2xlICgiK0guRWoocikrIiwg
-IgpzPWEudG9wCnMudG9TdHJpbmcKcz1yK0guRWoocykrIikgIgpyPWEud2lkdGgKci50b1N0cmluZwpy
-PXMrSC5FaihyKSsiIHggIgpzPWEuaGVpZ2h0CnMudG9TdHJpbmcKcmV0dXJuIHIrSC5FaihzKX0sCkRO
-OmZ1bmN0aW9uKGEsYil7dmFyIHMscgppZihiPT1udWxsKXJldHVybiExCmlmKHQucS5iKGIpKXtzPWEu
-bGVmdApzLnRvU3RyaW5nCnI9Yi5sZWZ0CnIudG9TdHJpbmcKaWYocz09PXIpe3M9YS50b3AKcy50b1N0
-cmluZwpyPWIudG9wCnIudG9TdHJpbmcKaWYocz09PXIpe3M9YS53aWR0aApzLnRvU3RyaW5nCnI9Yi53
-aWR0aApyLnRvU3RyaW5nCmlmKHM9PT1yKXtzPWEuaGVpZ2h0CnMudG9TdHJpbmcKcj1iLmhlaWdodApy
-LnRvU3RyaW5nCnI9cz09PXIKcz1yfWVsc2Ugcz0hMX1lbHNlIHM9ITF9ZWxzZSBzPSExfWVsc2Ugcz0h
-MQpyZXR1cm4gc30sCmdpTzpmdW5jdGlvbihhKXt2YXIgcyxyLHEscD1hLmxlZnQKcC50b1N0cmluZwpw
-PUMuQ0QuZ2lPKHApCnM9YS50b3AKcy50b1N0cmluZwpzPUMuQ0QuZ2lPKHMpCnI9YS53aWR0aApyLnRv
-U3RyaW5nCnI9Qy5DRC5naU8ocikKcT1hLmhlaWdodApxLnRvU3RyaW5nCnJldHVybiBXLnJFKHAscyxy
-LEMuQ0QuZ2lPKHEpKX0sCiRpdG46MX0KVy5uNy5wcm90b3R5cGU9ewpnQTpmdW5jdGlvbihhKXtyZXR1
-cm4gYS5sZW5ndGh9fQpXLnd6LnByb3RvdHlwZT17CmdBOmZ1bmN0aW9uKGEpe3JldHVybiB0aGlzLmEu
-bGVuZ3RofSwKcTpmdW5jdGlvbihhLGIpe3ZhciBzCkgudVAoYikKcz10aGlzLmEKaWYoYjwwfHxiPj1z
-Lmxlbmd0aClyZXR1cm4gSC5PSChzLGIpCnJldHVybiB0aGlzLiR0aS5jLmEoc1tiXSl9LApZOmZ1bmN0
-aW9uKGEsYixjKXt0aGlzLiR0aS5jLmEoYykKdGhyb3cgSC5iKFAuTDQoIkNhbm5vdCBtb2RpZnkgbGlz
-dCIpKX19ClcuY3YucHJvdG90eXBlPXsKZ1FnOmZ1bmN0aW9uKGEpe3JldHVybiBuZXcgVy5pNyhhKX0s
-CmdEOmZ1bmN0aW9uKGEpe3JldHVybiBuZXcgVy5JNChhKX0sCnNEOmZ1bmN0aW9uKGEsYil7dmFyIHMK
-dC5RLmEoYikKcz10aGlzLmdEKGEpCnMuVjEoMCkKcy5GVigwLGIpfSwKdzpmdW5jdGlvbihhKXtyZXR1
-cm4gYS5sb2NhbE5hbWV9LApGRjpmdW5jdGlvbihhKXt2YXIgcz0hIWEuc2Nyb2xsSW50b1ZpZXdJZk5l
-ZWRlZAppZihzKWEuc2Nyb2xsSW50b1ZpZXdJZk5lZWRlZCgpCmVsc2UgYS5zY3JvbGxJbnRvVmlldygp
-fSwKbno6ZnVuY3Rpb24oYSxiLGMsZCxlKXt2YXIgcyxyPXRoaXMucjYoYSxjLGQsZSkKc3dpdGNoKGIu
-dG9Mb3dlckNhc2UoKSl7Y2FzZSJiZWZvcmViZWdpbiI6cz1hLnBhcmVudE5vZGUKcy50b1N0cmluZwpK
-LkVoKHMscixhKQpicmVhawpjYXNlImFmdGVyYmVnaW4iOnM9YS5jaGlsZE5vZGVzCnRoaXMubUsoYSxy
-LHMubGVuZ3RoPjA/c1swXTpudWxsKQpicmVhawpjYXNlImJlZm9yZWVuZCI6YS5hcHBlbmRDaGlsZChy
-KQpicmVhawpjYXNlImFmdGVyZW5kIjpzPWEucGFyZW50Tm9kZQpzLnRvU3RyaW5nCkouRWgocyxyLGEu
-bmV4dFNpYmxpbmcpCmJyZWFrCmRlZmF1bHQ6SC52KFAueFkoIkludmFsaWQgcG9zaXRpb24gIitiKSl9
-fSwKcjY6ZnVuY3Rpb24oYSxiLGMsZCl7dmFyIHMscixxLHAKaWYoYz09bnVsbCl7aWYoZD09bnVsbCl7
-cz0kLmx0CmlmKHM9PW51bGwpe3M9SC5WTShbXSx0LnYpCnI9bmV3IFcudkQocykKQy5ObS5pKHMsVy5U
-dyhudWxsKSkKQy5ObS5pKHMsVy5CbCgpKQokLmx0PXIKZD1yfWVsc2UgZD1zfXM9JC5FVQppZihzPT1u
-dWxsKXtzPW5ldyBXLktvKGQpCiQuRVU9cwpjPXN9ZWxzZXtzLmE9ZApjPXN9fWVsc2UgaWYoZCE9bnVs
-bCl0aHJvdyBILmIoUC54WSgidmFsaWRhdG9yIGNhbiBvbmx5IGJlIHBhc3NlZCBpZiB0cmVlU2FuaXRp
-emVyIGlzIG51bGwiKSkKaWYoJC54bz09bnVsbCl7cz1kb2N1bWVudApyPXMuaW1wbGVtZW50YXRpb24K
-ci50b1N0cmluZwpyPUMubUguRGMociwiIikKJC54bz1yCiQuQk89ci5jcmVhdGVSYW5nZSgpCnI9JC54
-by5jcmVhdGVFbGVtZW50KCJiYXNlIikKdC5jUi5hKHIpCnM9cy5iYXNlVVJJCnMudG9TdHJpbmcKci5o
-cmVmPXMKJC54by5oZWFkLmFwcGVuZENoaWxkKHIpfXM9JC54bwppZihzLmJvZHk9PW51bGwpe3I9cy5j
-cmVhdGVFbGVtZW50KCJib2R5IikKQy5CWi5zWEcocyx0LnAuYShyKSl9cz0kLnhvCmlmKHQucC5iKGEp
-KXtzPXMuYm9keQpzLnRvU3RyaW5nCnE9c31lbHNle3MudG9TdHJpbmcKcT1zLmNyZWF0ZUVsZW1lbnQo
-YS50YWdOYW1lKQokLnhvLmJvZHkuYXBwZW5kQ2hpbGQocSl9aWYoImNyZWF0ZUNvbnRleHR1YWxGcmFn
-bWVudCIgaW4gd2luZG93LlJhbmdlLnByb3RvdHlwZSYmIUMuTm0udGcoQy5TcSxhLnRhZ05hbWUpKXsk
-LkJPLnNlbGVjdE5vZGVDb250ZW50cyhxKQpzPSQuQk8Kcy50b1N0cmluZwpwPXMuY3JlYXRlQ29udGV4
-dHVhbEZyYWdtZW50KGI9PW51bGw/Im51bGwiOmIpfWVsc2V7Si53ZihxLGIpCnA9JC54by5jcmVhdGVE
-b2N1bWVudEZyYWdtZW50KCkKZm9yKDtzPXEuZmlyc3RDaGlsZCxzIT1udWxsOylwLmFwcGVuZENoaWxk
-KHMpfWlmKHEhPT0kLnhvLmJvZHkpSi5MdChxKQpjLlBuKHApCmRvY3VtZW50LmFkb3B0Tm9kZShwKQpy
-ZXR1cm4gcH0sCkFIOmZ1bmN0aW9uKGEsYixjKXtyZXR1cm4gdGhpcy5yNihhLGIsYyxudWxsKX0sCnNo
-ZjpmdW5jdGlvbihhLGIpe3RoaXMuWUMoYSxiKX0sCnBrOmZ1bmN0aW9uKGEsYixjKXt0aGlzLnNhNChh
-LG51bGwpCmEuYXBwZW5kQ2hpbGQodGhpcy5yNihhLGIsbnVsbCxjKSl9LApZQzpmdW5jdGlvbihhLGIp
-e3JldHVybiB0aGlzLnBrKGEsYixudWxsKX0sCnNSTjpmdW5jdGlvbihhLGIpe2EuaW5uZXJIVE1MPWJ9
-LApnbnM6ZnVuY3Rpb24oYSl7cmV0dXJuIGEudGFnTmFtZX0sCmdWbDpmdW5jdGlvbihhKXtyZXR1cm4g
-bmV3IFcuZXUoYSwiY2xpY2siLCExLHQuayl9LAokaWN2OjF9ClcuQ3YucHJvdG90eXBlPXsKJDE6ZnVu
-Y3Rpb24oYSl7cmV0dXJuIHQuaC5iKHQuQS5hKGEpKX0sCiRTOjI1fQpXLmVhLnByb3RvdHlwZT17JGll
-YToxfQpXLkQwLnByb3RvdHlwZT17Ck9uOmZ1bmN0aW9uKGEsYixjLGQpe3QuYncuYShjKQppZihjIT1u
-dWxsKXRoaXMudihhLGIsYyxkKX0sCkI6ZnVuY3Rpb24oYSxiLGMpe3JldHVybiB0aGlzLk9uKGEsYixj
-LG51bGwpfSwKdjpmdW5jdGlvbihhLGIsYyxkKXtyZXR1cm4gYS5hZGRFdmVudExpc3RlbmVyKGIsSC50
-Uih0LmJ3LmEoYyksMSksZCl9LAokaUQwOjF9ClcuaEgucHJvdG90eXBlPXskaWhIOjF9ClcuaDQucHJv
-dG90eXBlPXsKZ0E6ZnVuY3Rpb24oYSl7cmV0dXJuIGEubGVuZ3RofX0KVy5ici5wcm90b3R5cGU9ewpn
-QTpmdW5jdGlvbihhKXtyZXR1cm4gYS5sZW5ndGh9fQpXLlZiLnByb3RvdHlwZT17CnNYRzpmdW5jdGlv
-bihhLGIpe2EuYm9keT1ifX0KVy5mSi5wcm90b3R5cGU9ewplbzpmdW5jdGlvbihhLGIsYyxkKXtyZXR1
-cm4gYS5vcGVuKGIsYywhMCl9LAokaWZKOjF9Clcud2EucHJvdG90eXBlPXt9ClcuU2cucHJvdG90eXBl
-PXskaVNnOjF9ClcudTgucHJvdG90eXBlPXsKZ0RyOmZ1bmN0aW9uKGEpe2lmKCJvcmlnaW4iIGluIGEp
-cmV0dXJuIGEub3JpZ2luCnJldHVybiBILkVqKGEucHJvdG9jb2wpKyIvLyIrSC5FaihhLmhvc3QpfSwK
-dzpmdW5jdGlvbihhKXtyZXR1cm4gU3RyaW5nKGEpfSwKJGl1ODoxfQpXLkFqLnByb3RvdHlwZT17JGlB
-ajoxfQpXLmU3LnByb3RvdHlwZT17CmdyODpmdW5jdGlvbihhKXt2YXIgcz10aGlzLmEscj1zLmNoaWxk
-Tm9kZXMubGVuZ3RoCmlmKHI9PT0wKXRocm93IEguYihQLlBWKCJObyBlbGVtZW50cyIpKQppZihyPjEp
-dGhyb3cgSC5iKFAuUFYoIk1vcmUgdGhhbiBvbmUgZWxlbWVudCIpKQpzPXMuZmlyc3RDaGlsZApzLnRv
-U3RyaW5nCnJldHVybiBzfSwKRlY6ZnVuY3Rpb24oYSxiKXt2YXIgcyxyLHEscCxvCnQuZWguYShiKQpp
-ZihiIGluc3RhbmNlb2YgVy5lNyl7cz1iLmEKcj10aGlzLmEKaWYocyE9PXIpZm9yKHE9cy5jaGlsZE5v
-ZGVzLmxlbmd0aCxwPTA7cDxxOysrcCl7bz1zLmZpcnN0Q2hpbGQKby50b1N0cmluZwpyLmFwcGVuZENo
-aWxkKG8pfXJldHVybn1mb3Iocz1iLmdtKGIpLHI9dGhpcy5hO3MuRigpOylyLmFwcGVuZENoaWxkKHMu
-Z2woKSl9LApZOmZ1bmN0aW9uKGEsYixjKXt2YXIgcyxyCnQuQS5hKGMpCnM9dGhpcy5hCnI9cy5jaGls
-ZE5vZGVzCmlmKGI8MHx8Yj49ci5sZW5ndGgpcmV0dXJuIEguT0gocixiKQpzLnJlcGxhY2VDaGlsZChj
-LHJbYl0pfSwKZ206ZnVuY3Rpb24oYSl7dmFyIHM9dGhpcy5hLmNoaWxkTm9kZXMKcmV0dXJuIG5ldyBX
-Llc5KHMscy5sZW5ndGgsSC56KHMpLkMoIlc5PEdtLkU+IikpfSwKZ0E6ZnVuY3Rpb24oYSl7cmV0dXJu
-IHRoaXMuYS5jaGlsZE5vZGVzLmxlbmd0aH0sCnE6ZnVuY3Rpb24oYSxiKXt2YXIgcwpILnVQKGIpCnM9
-dGhpcy5hLmNoaWxkTm9kZXMKaWYoYjwwfHxiPj1zLmxlbmd0aClyZXR1cm4gSC5PSChzLGIpCnJldHVy
-biBzW2JdfX0KVy51SC5wcm90b3R5cGU9ewp3ZzpmdW5jdGlvbihhKXt2YXIgcz1hLnBhcmVudE5vZGUK
-aWYocyE9bnVsbClzLnJlbW92ZUNoaWxkKGEpfSwKRDQ6ZnVuY3Rpb24oYSl7dmFyIHMKZm9yKDtzPWEu
-Zmlyc3RDaGlsZCxzIT1udWxsOylhLnJlbW92ZUNoaWxkKHMpfSwKdzpmdW5jdGlvbihhKXt2YXIgcz1h
-Lm5vZGVWYWx1ZQpyZXR1cm4gcz09bnVsbD90aGlzLlUoYSk6c30sCnNhNDpmdW5jdGlvbihhLGIpe2Eu
-dGV4dENvbnRlbnQ9Yn0sCm1LOmZ1bmN0aW9uKGEsYixjKXtyZXR1cm4gYS5pbnNlcnRCZWZvcmUoYixj
-KX0sCiRpdUg6MX0KVy5CSC5wcm90b3R5cGU9ewpnQTpmdW5jdGlvbihhKXtyZXR1cm4gYS5sZW5ndGh9
-LApxOmZ1bmN0aW9uKGEsYil7SC51UChiKQppZihiPj4+MCE9PWJ8fGI+PWEubGVuZ3RoKXRocm93IEgu
-YihQLkNmKGIsYSxudWxsLG51bGwsbnVsbCkpCnJldHVybiBhW2JdfSwKWTpmdW5jdGlvbihhLGIsYyl7
-dC5BLmEoYykKdGhyb3cgSC5iKFAuTDQoIkNhbm5vdCBhc3NpZ24gZWxlbWVudCBvZiBpbW11dGFibGUg
-TGlzdC4iKSl9LApndEg6ZnVuY3Rpb24oYSl7aWYoYS5sZW5ndGg+MClyZXR1cm4gYVswXQp0aHJvdyBI
-LmIoUC5QVigiTm8gZWxlbWVudHMiKSl9LApFOmZ1bmN0aW9uKGEsYil7aWYoYjwwfHxiPj1hLmxlbmd0
-aClyZXR1cm4gSC5PSChhLGIpCnJldHVybiBhW2JdfSwKJGliUToxLAokaVhqOjEsCiRpY1g6MSwKJGl6
-TToxfQpXLlNOLnByb3RvdHlwZT17fQpXLmV3LnByb3RvdHlwZT17JGlldzoxfQpXLmxwLnByb3RvdHlw
-ZT17CmdBOmZ1bmN0aW9uKGEpe3JldHVybiBhLmxlbmd0aH19ClcuVGIucHJvdG90eXBlPXsKcjY6ZnVu
-Y3Rpb24oYSxiLGMsZCl7dmFyIHMscgppZigiY3JlYXRlQ29udGV4dHVhbEZyYWdtZW50IiBpbiB3aW5k
-b3cuUmFuZ2UucHJvdG90eXBlKXJldHVybiB0aGlzLkRXKGEsYixjLGQpCnM9Vy5VOSgiPHRhYmxlPiIr
-SC5FaihiKSsiPC90YWJsZT4iLGMsZCkKcj1kb2N1bWVudC5jcmVhdGVEb2N1bWVudEZyYWdtZW50KCkK
-ci50b1N0cmluZwpzLnRvU3RyaW5nCm5ldyBXLmU3KHIpLkZWKDAsbmV3IFcuZTcocykpCnJldHVybiBy
-fX0KVy5Jdi5wcm90b3R5cGU9ewpyNjpmdW5jdGlvbihhLGIsYyxkKXt2YXIgcyxyLHEscAppZigiY3Jl
-YXRlQ29udGV4dHVhbEZyYWdtZW50IiBpbiB3aW5kb3cuUmFuZ2UucHJvdG90eXBlKXJldHVybiB0aGlz
-LkRXKGEsYixjLGQpCnM9ZG9jdW1lbnQKcj1zLmNyZWF0ZURvY3VtZW50RnJhZ21lbnQoKQpzPUMuSWUu
-cjYocy5jcmVhdGVFbGVtZW50KCJ0YWJsZSIpLGIsYyxkKQpzLnRvU3RyaW5nCnM9bmV3IFcuZTcocykK
-cT1zLmdyOChzKQpxLnRvU3RyaW5nCnM9bmV3IFcuZTcocSkKcD1zLmdyOChzKQpyLnRvU3RyaW5nCnAu
-dG9TdHJpbmcKbmV3IFcuZTcocikuRlYoMCxuZXcgVy5lNyhwKSkKcmV0dXJuIHJ9fQpXLldQLnByb3Rv
-dHlwZT17CnI2OmZ1bmN0aW9uKGEsYixjLGQpe3ZhciBzLHIscQppZigiY3JlYXRlQ29udGV4dHVhbEZy
-YWdtZW50IiBpbiB3aW5kb3cuUmFuZ2UucHJvdG90eXBlKXJldHVybiB0aGlzLkRXKGEsYixjLGQpCnM9
-ZG9jdW1lbnQKcj1zLmNyZWF0ZURvY3VtZW50RnJhZ21lbnQoKQpzPUMuSWUucjYocy5jcmVhdGVFbGVt
-ZW50KCJ0YWJsZSIpLGIsYyxkKQpzLnRvU3RyaW5nCnM9bmV3IFcuZTcocykKcT1zLmdyOChzKQpyLnRv
-U3RyaW5nCnEudG9TdHJpbmcKbmV3IFcuZTcocikuRlYoMCxuZXcgVy5lNyhxKSkKcmV0dXJuIHJ9fQpX
-LnlZLnByb3RvdHlwZT17CnBrOmZ1bmN0aW9uKGEsYixjKXt2YXIgcyxyCnRoaXMuc2E0KGEsbnVsbCkK
-cz1hLmNvbnRlbnQKcy50b1N0cmluZwpKLmJUKHMpCnI9dGhpcy5yNihhLGIsbnVsbCxjKQphLmNvbnRl
-bnQuYXBwZW5kQ2hpbGQocil9LApZQzpmdW5jdGlvbihhLGIpe3JldHVybiB0aGlzLnBrKGEsYixudWxs
-KX0sCiRpeVk6MX0KVy53Ni5wcm90b3R5cGU9e30KVy5LNS5wcm90b3R5cGU9ewpQbzpmdW5jdGlvbihh
-LGIsYyl7dmFyIHM9Vy5QMShhLm9wZW4oYixjKSkKcmV0dXJuIHN9LApnbVc6ZnVuY3Rpb24oYSl7cmV0
-dXJuIGEubG9jYXRpb259LAp1czpmdW5jdGlvbihhLGIpe3JldHVybiBhLmNvbmZpcm0oYil9LAokaUs1
-OjEsCiRpdjY6MX0KVy5DbS5wcm90b3R5cGU9eyRpQ206MX0KVy5DUS5wcm90b3R5cGU9eyRpQ1E6MX0K
-Vy53NC5wcm90b3R5cGU9ewp3OmZ1bmN0aW9uKGEpe3ZhciBzLHI9YS5sZWZ0CnIudG9TdHJpbmcKcj0i
-UmVjdGFuZ2xlICgiK0guRWoocikrIiwgIgpzPWEudG9wCnMudG9TdHJpbmcKcz1yK0guRWoocykrIikg
-IgpyPWEud2lkdGgKci50b1N0cmluZwpyPXMrSC5FaihyKSsiIHggIgpzPWEuaGVpZ2h0CnMudG9TdHJp
-bmcKcmV0dXJuIHIrSC5FaihzKX0sCkROOmZ1bmN0aW9uKGEsYil7dmFyIHMscgppZihiPT1udWxsKXJl
-dHVybiExCmlmKHQucS5iKGIpKXtzPWEubGVmdApzLnRvU3RyaW5nCnI9Yi5sZWZ0CnIudG9TdHJpbmcK
-aWYocz09PXIpe3M9YS50b3AKcy50b1N0cmluZwpyPWIudG9wCnIudG9TdHJpbmcKaWYocz09PXIpe3M9
-YS53aWR0aApzLnRvU3RyaW5nCnI9Yi53aWR0aApyLnRvU3RyaW5nCmlmKHM9PT1yKXtzPWEuaGVpZ2h0
-CnMudG9TdHJpbmcKcj1iLmhlaWdodApyLnRvU3RyaW5nCnI9cz09PXIKcz1yfWVsc2Ugcz0hMX1lbHNl
-IHM9ITF9ZWxzZSBzPSExfWVsc2Ugcz0hMQpyZXR1cm4gc30sCmdpTzpmdW5jdGlvbihhKXt2YXIgcyxy
-LHEscD1hLmxlZnQKcC50b1N0cmluZwpwPUMuQ0QuZ2lPKHApCnM9YS50b3AKcy50b1N0cmluZwpzPUMu
-Q0QuZ2lPKHMpCnI9YS53aWR0aApyLnRvU3RyaW5nCnI9Qy5DRC5naU8ocikKcT1hLmhlaWdodApxLnRv
-U3RyaW5nCnJldHVybiBXLnJFKHAscyxyLEMuQ0QuZ2lPKHEpKX19ClcucmgucHJvdG90eXBlPXsKZ0E6
-ZnVuY3Rpb24oYSl7cmV0dXJuIGEubGVuZ3RofSwKcTpmdW5jdGlvbihhLGIpe0gudVAoYikKaWYoYj4+
-PjAhPT1ifHxiPj1hLmxlbmd0aCl0aHJvdyBILmIoUC5DZihiLGEsbnVsbCxudWxsLG51bGwpKQpyZXR1
-cm4gYVtiXX0sClk6ZnVuY3Rpb24oYSxiLGMpe3QuQS5hKGMpCnRocm93IEguYihQLkw0KCJDYW5ub3Qg
-YXNzaWduIGVsZW1lbnQgb2YgaW1tdXRhYmxlIExpc3QuIikpfSwKRTpmdW5jdGlvbihhLGIpe2lmKGI8
-MHx8Yj49YS5sZW5ndGgpcmV0dXJuIEguT0goYSxiKQpyZXR1cm4gYVtiXX0sCiRpYlE6MSwKJGlYajox
-LAokaWNYOjEsCiRpek06MX0KVy5jZi5wcm90b3R5cGU9ewpLOmZ1bmN0aW9uKGEsYil7dmFyIHMscixx
-LHAsbwp0LmVBLmEoYikKZm9yKHM9dGhpcy5nVigpLHI9cy5sZW5ndGgscT10aGlzLmEscD0wO3A8cy5s
-ZW5ndGg7cy5sZW5ndGg9PT1yfHwoMCxILmxrKShzKSwrK3Ape289c1twXQpiLiQyKG8scS5nZXRBdHRy
-aWJ1dGUobykpfX0sCmdWOmZ1bmN0aW9uKCl7dmFyIHMscixxLHAsbyxuLG09dGhpcy5hLmF0dHJpYnV0
-ZXMKbS50b1N0cmluZwpzPUguVk0oW10sdC5zKQpmb3Iocj1tLmxlbmd0aCxxPXQuaDkscD0wO3A8cjsr
-K3Ape2lmKHA+PW0ubGVuZ3RoKXJldHVybiBILk9IKG0scCkKbz1xLmEobVtwXSkKaWYoby5uYW1lc3Bh
-Y2VVUkk9PW51bGwpe249by5uYW1lCm4udG9TdHJpbmcKQy5ObS5pKHMsbil9fXJldHVybiBzfSwKZ2ww
-OmZ1bmN0aW9uKGEpe3JldHVybiB0aGlzLmdWKCkubGVuZ3RoPT09MH19ClcuaTcucHJvdG90eXBlPXsK
-eDQ6ZnVuY3Rpb24oYSl7dmFyIHM9SC5vVCh0aGlzLmEuaGFzQXR0cmlidXRlKGEpKQpyZXR1cm4gc30s
-CnE6ZnVuY3Rpb24oYSxiKXtyZXR1cm4gdGhpcy5hLmdldEF0dHJpYnV0ZShILmgoYikpfSwKWTpmdW5j
-dGlvbihhLGIsYyl7dGhpcy5hLnNldEF0dHJpYnV0ZShiLGMpfSwKZ0E6ZnVuY3Rpb24oYSl7cmV0dXJu
-IHRoaXMuZ1YoKS5sZW5ndGh9fQpXLlN5LnByb3RvdHlwZT17Cng0OmZ1bmN0aW9uKGEpe3ZhciBzPUgu
-b1QodGhpcy5hLmEuaGFzQXR0cmlidXRlKCJkYXRhLSIrdGhpcy5PKGEpKSkKcmV0dXJuIHN9LApxOmZ1
-bmN0aW9uKGEsYil7cmV0dXJuIHRoaXMuYS5hLmdldEF0dHJpYnV0ZSgiZGF0YS0iK3RoaXMuTyhILmgo
-YikpKX0sClk6ZnVuY3Rpb24oYSxiLGMpe3RoaXMuYS5hLnNldEF0dHJpYnV0ZSgiZGF0YS0iK3RoaXMu
-TyhiKSxjKX0sCks6ZnVuY3Rpb24oYSxiKXt0aGlzLmEuSygwLG5ldyBXLktTKHRoaXMsdC5lQS5hKGIp
-KSl9LApnVjpmdW5jdGlvbigpe3ZhciBzPUguVk0oW10sdC5zKQp0aGlzLmEuSygwLG5ldyBXLkEzKHRo
-aXMscykpCnJldHVybiBzfSwKZ0E6ZnVuY3Rpb24oYSl7cmV0dXJuIHRoaXMuZ1YoKS5sZW5ndGh9LApn
-bDA6ZnVuY3Rpb24oYSl7cmV0dXJuIHRoaXMuZ1YoKS5sZW5ndGg9PT0wfSwKazpmdW5jdGlvbihhKXt2
-YXIgcyxyLHE9SC5WTShhLnNwbGl0KCItIiksdC5zKQpmb3Iocz0xO3M8cS5sZW5ndGg7KytzKXtyPXFb
-c10KaWYoci5sZW5ndGg+MClDLk5tLlkocSxzLHJbMF0udG9VcHBlckNhc2UoKStKLktWKHIsMSkpfXJl
-dHVybiBDLk5tLkgocSwiIil9LApPOmZ1bmN0aW9uKGEpe3ZhciBzLHIscSxwLG8KZm9yKHM9YS5sZW5n
-dGgscj0wLHE9IiI7cjxzOysrcil7cD1hW3JdCm89cC50b0xvd2VyQ2FzZSgpCnE9KHAhPT1vJiZyPjA/
-cSsiLSI6cSkrb31yZXR1cm4gcS5jaGFyQ29kZUF0KDApPT0wP3E6cX19ClcuS1MucHJvdG90eXBlPXsK
-JDI6ZnVuY3Rpb24oYSxiKXtpZihKLnJZKGEpLm4oYSwiZGF0YS0iKSl0aGlzLmIuJDIodGhpcy5hLmso
-Qy54Qi5HKGEsNSkpLGIpfSwKJFM6MTR9ClcuQTMucHJvdG90eXBlPXsKJDI6ZnVuY3Rpb24oYSxiKXtp
-ZihKLnJZKGEpLm4oYSwiZGF0YS0iKSlDLk5tLmkodGhpcy5iLHRoaXMuYS5rKEMueEIuRyhhLDUpKSl9
-LAokUzoxNH0KVy5JNC5wcm90b3R5cGU9ewpQOmZ1bmN0aW9uKCl7dmFyIHMscixxLHAsbz1QLkxzKHQu
-TikKZm9yKHM9dGhpcy5hLmNsYXNzTmFtZS5zcGxpdCgiICIpLHI9cy5sZW5ndGgscT0wO3E8cjsrK3Ep
-e3A9Si5UMChzW3FdKQppZihwLmxlbmd0aCE9PTApby5pKDAscCl9cmV0dXJuIG99LApYOmZ1bmN0aW9u
-KGEpe3RoaXMuYS5jbGFzc05hbWU9dC5DLmEoYSkuSCgwLCIgIil9LApnQTpmdW5jdGlvbihhKXtyZXR1
-cm4gdGhpcy5hLmNsYXNzTGlzdC5sZW5ndGh9LApnbDA6ZnVuY3Rpb24oYSl7cmV0dXJuIHRoaXMuYS5j
-bGFzc0xpc3QubGVuZ3RoPT09MH0sCmdvcjpmdW5jdGlvbihhKXtyZXR1cm4gdGhpcy5hLmNsYXNzTGlz
-dC5sZW5ndGghPT0wfSwKVjE6ZnVuY3Rpb24oYSl7dGhpcy5hLmNsYXNzTmFtZT0iIn0sCnRnOmZ1bmN0
-aW9uKGEsYil7dmFyIHM9dGhpcy5hLmNsYXNzTGlzdC5jb250YWlucyhiKQpyZXR1cm4gc30sCmk6ZnVu
-Y3Rpb24oYSxiKXt2YXIgcyxyCkguaChiKQpzPXRoaXMuYS5jbGFzc0xpc3QKcj1zLmNvbnRhaW5zKGIp
-CnMuYWRkKGIpCnJldHVybiFyfSwKUjpmdW5jdGlvbihhLGIpe3ZhciBzLHIscQppZih0eXBlb2YgYj09
-InN0cmluZyIpe3M9dGhpcy5hLmNsYXNzTGlzdApyPXMuY29udGFpbnMoYikKcy5yZW1vdmUoYikKcT1y
-fWVsc2UgcT0hMQpyZXR1cm4gcX0sCkZWOmZ1bmN0aW9uKGEsYil7Vy5UTih0aGlzLmEsdC5RLmEoYikp
-fX0KVy5Gay5wcm90b3R5cGU9e30KVy5STy5wcm90b3R5cGU9e30KVy5ldS5wcm90b3R5cGU9e30KVy54
-Qy5wcm90b3R5cGU9e30KVy52Ti5wcm90b3R5cGU9ewokMTpmdW5jdGlvbihhKXtyZXR1cm4gdGhpcy5h
-LiQxKHQuQi5hKGEpKX0sCiRTOjI3fQpXLkpRLnByb3RvdHlwZT17CkNZOmZ1bmN0aW9uKGEpe3ZhciBz
-CmlmKCQub3IuYT09PTApe2ZvcihzPTA7czwyNjI7KytzKSQub3IuWSgwLEMuY21bc10sVy5wUygpKQpm
-b3Iocz0wO3M8MTI7KytzKSQub3IuWSgwLEMuQklbc10sVy5WNCgpKX19LAppMDpmdW5jdGlvbihhKXty
-ZXR1cm4gJC5BTigpLnRnKDAsVy5yUyhhKSl9LApFYjpmdW5jdGlvbihhLGIsYyl7dmFyIHM9JC5vci5x
-KDAsSC5FaihXLnJTKGEpKSsiOjoiK2IpCmlmKHM9PW51bGwpcz0kLm9yLnEoMCwiKjo6IitiKQppZihz
-PT1udWxsKXJldHVybiExCnJldHVybiBILnk4KHMuJDQoYSxiLGMsdGhpcykpfSwKJGlrRjoxfQpXLkdt
-LnByb3RvdHlwZT17CmdtOmZ1bmN0aW9uKGEpe3JldHVybiBuZXcgVy5XOShhLHRoaXMuZ0EoYSksSC56
-KGEpLkMoIlc5PEdtLkU+IikpfX0KVy52RC5wcm90b3R5cGU9ewppMDpmdW5jdGlvbihhKXtyZXR1cm4g
-Qy5ObS5Wcih0aGlzLmEsbmV3IFcuVXYoYSkpfSwKRWI6ZnVuY3Rpb24oYSxiLGMpe3JldHVybiBDLk5t
-LlZyKHRoaXMuYSxuZXcgVy5FZyhhLGIsYykpfSwKJGlrRjoxfQpXLlV2LnByb3RvdHlwZT17CiQxOmZ1
-bmN0aW9uKGEpe3JldHVybiB0LmY2LmEoYSkuaTAodGhpcy5hKX0sCiRTOjE1fQpXLkVnLnByb3RvdHlw
-ZT17CiQxOmZ1bmN0aW9uKGEpe3JldHVybiB0LmY2LmEoYSkuRWIodGhpcy5hLHRoaXMuYix0aGlzLmMp
-fSwKJFM6MTV9ClcubTYucHJvdG90eXBlPXsKQ1k6ZnVuY3Rpb24oYSxiLGMsZCl7dmFyIHMscixxCnRo
-aXMuYS5GVigwLGMpCnM9Yi5ldigwLG5ldyBXLkVvKCkpCnI9Yi5ldigwLG5ldyBXLldrKCkpCnRoaXMu
-Yi5GVigwLHMpCnE9dGhpcy5jCnEuRlYoMCxDLnhEKQpxLkZWKDAscil9LAppMDpmdW5jdGlvbihhKXty
-ZXR1cm4gdGhpcy5hLnRnKDAsVy5yUyhhKSl9LApFYjpmdW5jdGlvbihhLGIsYyl7dmFyIHM9dGhpcyxy
-PVcuclMoYSkscT1zLmMKaWYocS50ZygwLEguRWoocikrIjo6IitiKSlyZXR1cm4gcy5kLkR0KGMpCmVs
-c2UgaWYocS50ZygwLCIqOjoiK2IpKXJldHVybiBzLmQuRHQoYykKZWxzZXtxPXMuYgppZihxLnRnKDAs
-SC5FaihyKSsiOjoiK2IpKXJldHVybiEwCmVsc2UgaWYocS50ZygwLCIqOjoiK2IpKXJldHVybiEwCmVs
-c2UgaWYocS50ZygwLEguRWoocikrIjo6KiIpKXJldHVybiEwCmVsc2UgaWYocS50ZygwLCIqOjoqIikp
-cmV0dXJuITB9cmV0dXJuITF9LAokaWtGOjF9ClcuRW8ucHJvdG90eXBlPXsKJDE6ZnVuY3Rpb24oYSl7
-cmV0dXJuIUMuTm0udGcoQy5CSSxILmgoYSkpfSwKJFM6Nn0KVy5Xay5wcm90b3R5cGU9ewokMTpmdW5j
-dGlvbihhKXtyZXR1cm4gQy5ObS50ZyhDLkJJLEguaChhKSl9LAokUzo2fQpXLmN0LnByb3RvdHlwZT17
-CkViOmZ1bmN0aW9uKGEsYixjKXtpZih0aGlzLmpGKGEsYixjKSlyZXR1cm4hMAppZihiPT09InRlbXBs
-YXRlIiYmYz09PSIiKXJldHVybiEwCmlmKGEuZ2V0QXR0cmlidXRlKCJ0ZW1wbGF0ZSIpPT09IiIpcmV0
-dXJuIHRoaXMuZS50ZygwLGIpCnJldHVybiExfX0KVy5JQS5wcm90b3R5cGU9ewokMTpmdW5jdGlvbihh
-KXtyZXR1cm4iVEVNUExBVEU6OiIrSC5FaihILmgoYSkpfSwKJFM6NX0KVy5Pdy5wcm90b3R5cGU9ewpp
-MDpmdW5jdGlvbihhKXt2YXIgcwppZih0LmV3LmIoYSkpcmV0dXJuITEKcz10Lmc3LmIoYSkKaWYocyYm
-Vy5yUyhhKT09PSJmb3JlaWduT2JqZWN0IilyZXR1cm4hMQppZihzKXJldHVybiEwCnJldHVybiExfSwK
-RWI6ZnVuY3Rpb24oYSxiLGMpe2lmKGI9PT0iaXMifHxDLnhCLm4oYiwib24iKSlyZXR1cm4hMQpyZXR1
-cm4gdGhpcy5pMChhKX0sCiRpa0Y6MX0KVy5XOS5wcm90b3R5cGU9ewpGOmZ1bmN0aW9uKCl7dmFyIHM9
-dGhpcyxyPXMuYysxLHE9cy5iCmlmKHI8cSl7cy5zcChKLng5KHMuYSxyKSkKcy5jPXIKcmV0dXJuITB9
-cy5zcChudWxsKQpzLmM9cQpyZXR1cm4hMX0sCmdsOmZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMuZH0sCnNw
-OmZ1bmN0aW9uKGEpe3RoaXMuZD10aGlzLiR0aS5DKCIxPyIpLmEoYSl9LAokaUFuOjF9ClcuZFcucHJv
-dG90eXBlPXskaUQwOjEsJGl2NjoxfQpXLm1rLnByb3RvdHlwZT17JGl5MDoxfQpXLktvLnByb3RvdHlw
-ZT17ClBuOmZ1bmN0aW9uKGEpe3ZhciBzPXRoaXMscj1uZXcgVy5mbShzKQpzLmI9ITEKci4kMihhLG51
-bGwpCmZvcig7cy5iOyl7cy5iPSExCnIuJDIoYSxudWxsKX19LApFUDpmdW5jdGlvbihhLGIpe3ZhciBz
-PXRoaXMuYj0hMAppZihiIT1udWxsP2IhPT1hLnBhcmVudE5vZGU6cylKLkx0KGEpCmVsc2UgYi5yZW1v
-dmVDaGlsZChhKX0sCkk0OmZ1bmN0aW9uKGEsYil7dmFyIHMscixxLHAsbyxuPSEwLG09bnVsbCxsPW51
-bGwKdHJ5e209Si5pZyhhKQpsPW0uYS5nZXRBdHRyaWJ1dGUoImlzIikKdC5oLmEoYSkKcz1mdW5jdGlv
-bihjKXtpZighKGMuYXR0cmlidXRlcyBpbnN0YW5jZW9mIE5hbWVkTm9kZU1hcCkpcmV0dXJuIHRydWUK
-aWYoYy5pZD09J2xhc3RDaGlsZCd8fGMubmFtZT09J2xhc3RDaGlsZCd8fGMuaWQ9PSdwcmV2aW91c1Np
-YmxpbmcnfHxjLm5hbWU9PSdwcmV2aW91c1NpYmxpbmcnfHxjLmlkPT0nY2hpbGRyZW4nfHxjLm5hbWU9
-PSdjaGlsZHJlbicpcmV0dXJuIHRydWUKdmFyIGs9Yy5jaGlsZE5vZGVzCmlmKGMubGFzdENoaWxkJiZj
-Lmxhc3RDaGlsZCE9PWtbay5sZW5ndGgtMV0pcmV0dXJuIHRydWUKaWYoYy5jaGlsZHJlbilpZighKGMu
-Y2hpbGRyZW4gaW5zdGFuY2VvZiBIVE1MQ29sbGVjdGlvbnx8Yy5jaGlsZHJlbiBpbnN0YW5jZW9mIE5v
-ZGVMaXN0KSlyZXR1cm4gdHJ1ZQp2YXIgaj0wCmlmKGMuY2hpbGRyZW4paj1jLmNoaWxkcmVuLmxlbmd0
-aApmb3IodmFyIGk9MDtpPGo7aSsrKXt2YXIgaD1jLmNoaWxkcmVuW2ldCmlmKGguaWQ9PSdhdHRyaWJ1
-dGVzJ3x8aC5uYW1lPT0nYXR0cmlidXRlcyd8fGguaWQ9PSdsYXN0Q2hpbGQnfHxoLm5hbWU9PSdsYXN0
-Q2hpbGQnfHxoLmlkPT0ncHJldmlvdXNTaWJsaW5nJ3x8aC5uYW1lPT0ncHJldmlvdXNTaWJsaW5nJ3x8
-aC5pZD09J2NoaWxkcmVuJ3x8aC5uYW1lPT0nY2hpbGRyZW4nKXJldHVybiB0cnVlfXJldHVybiBmYWxz
-ZX0oYSkKbj1ILm9UKHMpPyEwOiEoYS5hdHRyaWJ1dGVzIGluc3RhbmNlb2YgTmFtZWROb2RlTWFwKX1j
-YXRjaChwKXtILlJ1KHApfXI9ImVsZW1lbnQgdW5wcmludGFibGUiCnRyeXtyPUouaihhKX1jYXRjaChw
-KXtILlJ1KHApfXRyeXtxPVcuclMoYSkKdGhpcy5rUih0LmguYShhKSxiLG4scixxLHQuZi5hKG0pLEgu
-ayhsKSl9Y2F0Y2gocCl7aWYoSC5SdShwKSBpbnN0YW5jZW9mIFAudSl0aHJvdyBwCmVsc2V7dGhpcy5F
-UChhLGIpCndpbmRvdwpvPSJSZW1vdmluZyBjb3JydXB0ZWQgZWxlbWVudCAiK0guRWoocikKaWYodHlw
-ZW9mIGNvbnNvbGUhPSJ1bmRlZmluZWQiKXdpbmRvdy5jb25zb2xlLndhcm4obyl9fX0sCmtSOmZ1bmN0
-aW9uKGEsYixjLGQsZSxmLGcpe3ZhciBzLHIscSxwLG8sbixtPXRoaXMKaWYoYyl7bS5FUChhLGIpCndp
-bmRvdwpzPSJSZW1vdmluZyBlbGVtZW50IGR1ZSB0byBjb3JydXB0ZWQgYXR0cmlidXRlcyBvbiA8Iitk
-KyI+IgppZih0eXBlb2YgY29uc29sZSE9InVuZGVmaW5lZCIpd2luZG93LmNvbnNvbGUud2FybihzKQpy
-ZXR1cm59aWYoIW0uYS5pMChhKSl7bS5FUChhLGIpCndpbmRvdwpzPSJSZW1vdmluZyBkaXNhbGxvd2Vk
-IGVsZW1lbnQgPCIrSC5FaihlKSsiPiBmcm9tICIrSC5FaihiKQppZih0eXBlb2YgY29uc29sZSE9InVu
-ZGVmaW5lZCIpd2luZG93LmNvbnNvbGUud2FybihzKQpyZXR1cm59aWYoZyE9bnVsbClpZighbS5hLkVi
-KGEsImlzIixnKSl7bS5FUChhLGIpCndpbmRvdwpzPSJSZW1vdmluZyBkaXNhbGxvd2VkIHR5cGUgZXh0
-ZW5zaW9uIDwiK0guRWooZSkrJyBpcz0iJytnKyciPicKaWYodHlwZW9mIGNvbnNvbGUhPSJ1bmRlZmlu
-ZWQiKXdpbmRvdy5jb25zb2xlLndhcm4ocykKcmV0dXJufXM9Zi5nVigpCnI9SC5WTShzLnNsaWNlKDAp
-LEgudDYocykpCmZvcihxPWYuZ1YoKS5sZW5ndGgtMSxzPWYuYTtxPj0wOy0tcSl7aWYocT49ci5sZW5n
-dGgpcmV0dXJuIEguT0gocixxKQpwPXJbcV0Kbz1tLmEKbj1KLmNIKHApCkguaChwKQppZighby5FYihh
-LG4scy5nZXRBdHRyaWJ1dGUocCkpKXt3aW5kb3cKbz0iUmVtb3ZpbmcgZGlzYWxsb3dlZCBhdHRyaWJ1
-dGUgPCIrSC5FaihlKSsiICIrcCsnPSInK0guRWoocy5nZXRBdHRyaWJ1dGUocCkpKyciPicKaWYodHlw
-ZW9mIGNvbnNvbGUhPSJ1bmRlZmluZWQiKXdpbmRvdy5jb25zb2xlLndhcm4obykKcy5yZW1vdmVBdHRy
-aWJ1dGUocCl9fWlmKHQuYVcuYihhKSl7cz1hLmNvbnRlbnQKcy50b1N0cmluZwptLlBuKHMpfX0sCiRp
-b246MX0KVy5mbS5wcm90b3R5cGU9ewokMjpmdW5jdGlvbihhLGIpe3ZhciBzLHIscSxwLG8sbixtPXRo
-aXMuYQpzd2l0Y2goYS5ub2RlVHlwZSl7Y2FzZSAxOm0uSTQoYSxiKQpicmVhawpjYXNlIDg6Y2FzZSAx
-MTpjYXNlIDM6Y2FzZSA0OmJyZWFrCmRlZmF1bHQ6bS5FUChhLGIpfXM9YS5sYXN0Q2hpbGQKZm9yKHE9
-dC5BO251bGwhPXM7KXtyPW51bGwKdHJ5e3I9cy5wcmV2aW91c1NpYmxpbmcKaWYociE9bnVsbCl7cD1y
-Lm5leHRTaWJsaW5nCm89cwpvPXA9PW51bGw/byE9bnVsbDpwIT09bwpwPW99ZWxzZSBwPSExCmlmKHAp
-e3A9UC5QVigiQ29ycnVwdCBIVE1MIikKdGhyb3cgSC5iKHApfX1jYXRjaChuKXtILlJ1KG4pCnA9cS5h
-KHMpCm0uYj0hMApvPXAucGFyZW50Tm9kZQpvPWE9PW51bGw/byE9bnVsbDphIT09bwppZihvKXtvPXAu
-cGFyZW50Tm9kZQppZihvIT1udWxsKW8ucmVtb3ZlQ2hpbGQocCl9ZWxzZSBhLnJlbW92ZUNoaWxkKHAp
-CnM9bnVsbApyPWEubGFzdENoaWxkfWlmKHMhPW51bGwpdGhpcy4kMihzLGEpCnM9cn19LAokUzozMH0K
-Vy5MZS5wcm90b3R5cGU9e30KVy5LNy5wcm90b3R5cGU9e30KVy5yQi5wcm90b3R5cGU9e30KVy5YVy5w
-cm90b3R5cGU9e30KVy5vYS5wcm90b3R5cGU9e30KUC5pSi5wcm90b3R5cGU9ewpWSDpmdW5jdGlvbihh
-KXt2YXIgcyxyPXRoaXMuYSxxPXIubGVuZ3RoCmZvcihzPTA7czxxOysrcylpZihyW3NdPT09YSlyZXR1
-cm4gcwpDLk5tLmkocixhKQpDLk5tLmkodGhpcy5iLG51bGwpCnJldHVybiBxfSwKUHY6ZnVuY3Rpb24o
-YSl7dmFyIHMscixxLHA9dGhpcyxvPXt9CmlmKGE9PW51bGwpcmV0dXJuIGEKaWYoSC5sKGEpKXJldHVy
-biBhCmlmKHR5cGVvZiBhPT0ibnVtYmVyIilyZXR1cm4gYQppZih0eXBlb2YgYT09InN0cmluZyIpcmV0
-dXJuIGEKaWYoYSBpbnN0YW5jZW9mIFAuaVApcmV0dXJuIG5ldyBEYXRlKGEuYSkKaWYodC5mdi5iKGEp
-KXRocm93IEguYihQLlNZKCJzdHJ1Y3R1cmVkIGNsb25lIG9mIFJlZ0V4cCIpKQppZih0LmM4LmIoYSkp
-cmV0dXJuIGEKaWYodC53LmIoYSkpcmV0dXJuIGEKaWYodC5JLmIoYSkpcmV0dXJuIGEKcz10LmRFLmIo
-YSl8fCExCmlmKHMpcmV0dXJuIGEKaWYodC5mLmIoYSkpe3I9cC5WSChhKQpzPXAuYgppZihyPj1zLmxl
-bmd0aClyZXR1cm4gSC5PSChzLHIpCnE9by5hPXNbcl0KaWYocSE9bnVsbClyZXR1cm4gcQpxPXt9Cm8u
-YT1xCkMuTm0uWShzLHIscSkKYS5LKDAsbmV3IFAuamcobyxwKSkKcmV0dXJuIG8uYX1pZih0LmouYihh
-KSl7cj1wLlZIKGEpCm89cC5iCmlmKHI+PW8ubGVuZ3RoKXJldHVybiBILk9IKG8scikKcT1vW3JdCmlm
-KHEhPW51bGwpcmV0dXJuIHEKcmV0dXJuIHAuZWsoYSxyKX1pZih0LmVILmIoYSkpe3I9cC5WSChhKQpz
-PXAuYgppZihyPj1zLmxlbmd0aClyZXR1cm4gSC5PSChzLHIpCnE9by5iPXNbcl0KaWYocSE9bnVsbCly
-ZXR1cm4gcQpxPXt9Cm8uYj1xCkMuTm0uWShzLHIscSkKcC5pbShhLG5ldyBQLlRhKG8scCkpCnJldHVy
+QUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUZGRkZGRkZGRkZGRkZGRkZHR0dHR0dHR0dHR0dHR0dH
+SEhISEhISEhISEhISEhISEhISEhISEhISEhISUhISEpFRUJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJC
+QkJCQktDQ0NDQ0NDQ0NDQ0NEQ0xPTk5OTUVFRUVFRUVFRUVFIixzKSYzMQpoPWk8PTMyP3MmNjE2OTQ+
+Pj5xOihzJjYzfGg8PDYpPj4+MAppPUMueEIuVygiIFx4MDAwOlhFQ0NDQ0NOOmxEYiBceDAwMDpYRUND
+Q0NDTnZsRGIgXHgwMDA6WEVDQ0NDQ046bERiIEFBQUFBXHgwMFx4MDBceDAwXHgwMFx4MDBBQUFBQTAw
+MDAwQUFBQUE6Ojo6OkFBQUFBR0cwMDBBQUFBQTAwS0tLQUFBQUFHOjo6OkFBQUFBOklJSUlBQUFBQTAw
+MFx4ODAwQUFBQUFceDAwXHgwMFx4MDBceDAwIEFBQUFBIixpK3EpCmlmKGk9PT0wKXtnLmErPUguTHco
+aCkKaWYoZj09PWMpYnJlYWsgJGxhYmVsMCQwCmJyZWFrfWVsc2UgaWYoKGkmMSkhPT0wKXtpZihyKXN3
+aXRjaChpKXtjYXNlIDY5OmNhc2UgNjc6Zy5hKz1ILkx3KGopCmJyZWFrCmNhc2UgNjU6Zy5hKz1ILkx3
+KGopOy0tZgpicmVhawpkZWZhdWx0OnA9Zy5hKz1ILkx3KGopCmcuYT1wK0guTHcoaikKYnJlYWt9ZWxz
+ZXtrLmI9aQprLmM9Zi0xCnJldHVybiIifWk9MH1pZihmPT09YylicmVhayAkbGFiZWwwJDAKbz1mKzEK
+aWYoZjwwfHxmPj1lKXJldHVybiBILk9IKGEsZikKcz1hW2ZdfW89ZisxCmlmKGY8MHx8Zj49ZSlyZXR1
+cm4gSC5PSChhLGYpCnM9YVtmXQppZihzPDEyOCl7d2hpbGUoITApe2lmKCEobzxjKSl7bj1jCmJyZWFr
+fW09bysxCmlmKG88MHx8bz49ZSlyZXR1cm4gSC5PSChhLG8pCnM9YVtvXQppZihzPj0xMjgpe249bS0x
+Cm89bQpicmVha31vPW19aWYobi1mPDIwKWZvcihsPWY7bDxuOysrbCl7aWYobD49ZSlyZXR1cm4gSC5P
+SChhLGwpCmcuYSs9SC5MdyhhW2xdKX1lbHNlIGcuYSs9UC5ITShhLGYsbikKaWYobj09PWMpYnJlYWsg
+JGxhYmVsMCQwCmY9b31lbHNlIGY9b31pZihkJiZpPjMyKWlmKHIpZy5hKz1ILkx3KGopCmVsc2V7ay5i
+PTc3CmsuYz1jCnJldHVybiIifWsuYj1pCmsuYz1oCmU9Zy5hCnJldHVybiBlLmNoYXJDb2RlQXQoMCk9
+PTA/ZTplfX0KUC5XRi5wcm90b3R5cGU9ewokMjpmdW5jdGlvbihhLGIpe3ZhciBzLHIscQp0LmZvLmEo
+YSkKcz10aGlzLmIKcj10aGlzLmEKcy5hKz1yLmEKcT1zLmErPUguRWooYS5hKQpzLmE9cSsiOiAiCnMu
+YSs9UC5wKGIpCnIuYT0iLCAifSwKJFM6NDJ9ClAuaVAucHJvdG90eXBlPXsKRE46ZnVuY3Rpb24oYSxi
+KXtpZihiPT1udWxsKXJldHVybiExCnJldHVybiBiIGluc3RhbmNlb2YgUC5pUCYmdGhpcy5hPT09Yi5h
+JiYhMH0sCmdpTzpmdW5jdGlvbihhKXt2YXIgcz10aGlzLmEKcmV0dXJuKHNeQy5qbi53RyhzLDMwKSkm
+MTA3Mzc0MTgyM30sCnc6ZnVuY3Rpb24oYSl7dmFyIHM9dGhpcyxyPVAuR3EoSC50SihzKSkscT1QLmgw
+KEguTlMocykpLHA9UC5oMChILmpBKHMpKSxvPVAuaDAoSC5JWChzKSksbj1QLmgwKEguY2gocykpLG09
+UC5oMChILkpkKHMpKSxsPVAuVngoSC5vMShzKSksaz1yKyItIitxKyItIitwKyIgIitvKyI6IituKyI6
+IittKyIuIitsCnJldHVybiBrfX0KUC5YUy5wcm90b3R5cGU9ewpnSUk6ZnVuY3Rpb24oKXtyZXR1cm4g
+SC50cyh0aGlzLiR0aHJvd25Kc0Vycm9yKX19ClAuQzYucHJvdG90eXBlPXsKdzpmdW5jdGlvbihhKXt2
+YXIgcz10aGlzLmEKaWYocyE9bnVsbClyZXR1cm4iQXNzZXJ0aW9uIGZhaWxlZDogIitQLnAocykKcmV0
+dXJuIkFzc2VydGlvbiBmYWlsZWQifX0KUC5Fei5wcm90b3R5cGU9e30KUC5GLnByb3RvdHlwZT17Cnc6
+ZnVuY3Rpb24oYSl7cmV0dXJuIlRocm93IG9mIG51bGwuIn19ClAudS5wcm90b3R5cGU9ewpnWjpmdW5j
+dGlvbigpe3JldHVybiJJbnZhbGlkIGFyZ3VtZW50IisoIXRoaXMuYT8iKHMpIjoiIil9LApndTpmdW5j
+dGlvbigpe3JldHVybiIifSwKdzpmdW5jdGlvbihhKXt2YXIgcyxyLHE9dGhpcyxwPXEuYyxvPXA9PW51
+bGw/IiI6IiAoIitwKyIpIixuPXEuZCxtPW49PW51bGw/IiI6IjogIitILkVqKG4pLGw9cS5nWigpK28r
+bQppZighcS5hKXJldHVybiBsCnM9cS5ndSgpCnI9UC5wKHEuYikKcmV0dXJuIGwrcysiOiAiK3J9fQpQ
+LmJKLnByb3RvdHlwZT17CmdaOmZ1bmN0aW9uKCl7cmV0dXJuIlJhbmdlRXJyb3IifSwKZ3U6ZnVuY3Rp
+b24oKXt2YXIgcyxyPXRoaXMuZSxxPXRoaXMuZgppZihyPT1udWxsKXM9cSE9bnVsbD8iOiBOb3QgbGVz
+cyB0aGFuIG9yIGVxdWFsIHRvICIrSC5FaihxKToiIgplbHNlIGlmKHE9PW51bGwpcz0iOiBOb3QgZ3Jl
+YXRlciB0aGFuIG9yIGVxdWFsIHRvICIrSC5FaihyKQplbHNlIGlmKHE+cilzPSI6IE5vdCBpbiBpbmNs
+dXNpdmUgcmFuZ2UgIitILkVqKHIpKyIuLiIrSC5FaihxKQplbHNlIHM9cTxyPyI6IFZhbGlkIHZhbHVl
+IHJhbmdlIGlzIGVtcHR5IjoiOiBPbmx5IHZhbGlkIHZhbHVlIGlzICIrSC5FaihyKQpyZXR1cm4gc319
+ClAuZVkucHJvdG90eXBlPXsKZ1o6ZnVuY3Rpb24oKXtyZXR1cm4iUmFuZ2VFcnJvciJ9LApndTpmdW5j
+dGlvbigpe3ZhciBzLHI9SC51UCh0aGlzLmIpCmlmKHR5cGVvZiByIT09Im51bWJlciIpcmV0dXJuIHIu
+SigpCmlmKHI8MClyZXR1cm4iOiBpbmRleCBtdXN0IG5vdCBiZSBuZWdhdGl2ZSIKcz10aGlzLmYKaWYo
+cz09PTApcmV0dXJuIjogbm8gaW5kaWNlcyBhcmUgdmFsaWQiCnJldHVybiI6IGluZGV4IHNob3VsZCBi
+ZSBsZXNzIHRoYW4gIitILkVqKHMpfSwKZ0E6ZnVuY3Rpb24oYSl7cmV0dXJuIHRoaXMuZn19ClAubXAu
+cHJvdG90eXBlPXsKdzpmdW5jdGlvbihhKXt2YXIgcyxyLHEscCxvLG4sbSxsLGs9dGhpcyxqPXt9LGk9
+bmV3IFAuUm4oIiIpCmouYT0iIgpzPWsuYwpmb3Iocj1zLmxlbmd0aCxxPTAscD0iIixvPSIiO3E8cjsr
+K3Esbz0iLCAiKXtuPXNbcV0KaS5hPXArbwpwPWkuYSs9UC5wKG4pCmouYT0iLCAifWsuZC5LKDAsbmV3
+IFAuV0YoaixpKSkKbT1QLnAoay5hKQpsPWkudygwKQpyPSJOb1N1Y2hNZXRob2RFcnJvcjogbWV0aG9k
+IG5vdCBmb3VuZDogJyIrSC5FaihrLmIuYSkrIidcblJlY2VpdmVyOiAiK20rIlxuQXJndW1lbnRzOiBb
+IitsKyJdIgpyZXR1cm4gcn19ClAudWIucHJvdG90eXBlPXsKdzpmdW5jdGlvbihhKXtyZXR1cm4iVW5z
+dXBwb3J0ZWQgb3BlcmF0aW9uOiAiK3RoaXMuYX19ClAuZHMucHJvdG90eXBlPXsKdzpmdW5jdGlvbihh
+KXt2YXIgcz10aGlzLmEKcmV0dXJuIHMhPW51bGw/IlVuaW1wbGVtZW50ZWRFcnJvcjogIitzOiJVbmlt
+cGxlbWVudGVkRXJyb3IifX0KUC5sai5wcm90b3R5cGU9ewp3OmZ1bmN0aW9uKGEpe3JldHVybiJCYWQg
+c3RhdGU6ICIrdGhpcy5hfX0KUC5VVi5wcm90b3R5cGU9ewp3OmZ1bmN0aW9uKGEpe3ZhciBzPXRoaXMu
+YQppZihzPT1udWxsKXJldHVybiJDb25jdXJyZW50IG1vZGlmaWNhdGlvbiBkdXJpbmcgaXRlcmF0aW9u
+LiIKcmV0dXJuIkNvbmN1cnJlbnQgbW9kaWZpY2F0aW9uIGR1cmluZyBpdGVyYXRpb246ICIrUC5wKHMp
+KyIuIn19ClAuazUucHJvdG90eXBlPXsKdzpmdW5jdGlvbihhKXtyZXR1cm4iT3V0IG9mIE1lbW9yeSJ9
+LApnSUk6ZnVuY3Rpb24oKXtyZXR1cm4gbnVsbH0sCiRpWFM6MX0KUC5LWS5wcm90b3R5cGU9ewp3OmZ1
+bmN0aW9uKGEpe3JldHVybiJTdGFjayBPdmVyZmxvdyJ9LApnSUk6ZnVuY3Rpb24oKXtyZXR1cm4gbnVs
+bH0sCiRpWFM6MX0KUC5jLnByb3RvdHlwZT17Cnc6ZnVuY3Rpb24oYSl7dmFyIHM9dGhpcy5hCnJldHVy
+biBzPT1udWxsPyJSZWFkaW5nIHN0YXRpYyB2YXJpYWJsZSBkdXJpbmcgaXRzIGluaXRpYWxpemF0aW9u
+IjoiUmVhZGluZyBzdGF0aWMgdmFyaWFibGUgJyIrcysiJyBkdXJpbmcgaXRzIGluaXRpYWxpemF0aW9u
+In19ClAuQ0QucHJvdG90eXBlPXsKdzpmdW5jdGlvbihhKXtyZXR1cm4iRXhjZXB0aW9uOiAiK3RoaXMu
+YX0sCiRpUno6MX0KUC5hRS5wcm90b3R5cGU9ewp3OmZ1bmN0aW9uKGEpe3ZhciBzLHIscSxwLG8sbixt
+LGwsayxqLGksaCxnPXRoaXMuYSxmPWchPW51bGwmJiIiIT09Zz8iRm9ybWF0RXhjZXB0aW9uOiAiK0gu
+RWooZyk6IkZvcm1hdEV4Y2VwdGlvbiIsZT10aGlzLmMsZD10aGlzLmIKaWYodHlwZW9mIGQ9PSJzdHJp
+bmciKXtpZihlIT1udWxsKXM9ZTwwfHxlPmQubGVuZ3RoCmVsc2Ugcz0hMQppZihzKWU9bnVsbAppZihl
+PT1udWxsKXtpZihkLmxlbmd0aD43OClkPUMueEIuTmooZCwwLDc1KSsiLi4uIgpyZXR1cm4gZisiXG4i
+K2R9Zm9yKHI9MSxxPTAscD0hMSxvPTA7bzxlOysrbyl7bj1DLnhCLlcoZCxvKQppZihuPT09MTApe2lm
+KHEhPT1vfHwhcCkrK3IKcT1vKzEKcD0hMX1lbHNlIGlmKG49PT0xMyl7KytyCnE9bysxCnA9ITB9fWY9
+cj4xP2YrKCIgKGF0IGxpbmUgIityKyIsIGNoYXJhY3RlciAiKyhlLXErMSkrIilcbiIpOmYrKCIgKGF0
+IGNoYXJhY3RlciAiKyhlKzEpKyIpXG4iKQptPWQubGVuZ3RoCmZvcihvPWU7bzxtOysrbyl7bj1DLnhC
+Lk8yKGQsbykKaWYobj09PTEwfHxuPT09MTMpe209bwpicmVha319aWYobS1xPjc4KWlmKGUtcTw3NSl7
+bD1xKzc1Cms9cQpqPSIiCmk9Ii4uLiJ9ZWxzZXtpZihtLWU8NzUpe2s9bS03NQpsPW0KaT0iIn1lbHNl
+e2s9ZS0zNgpsPWUrMzYKaT0iLi4uIn1qPSIuLi4ifWVsc2V7bD1tCms9cQpqPSIiCmk9IiJ9aD1DLnhC
+Lk5qKGQsayxsKQpyZXR1cm4gZitqK2graSsiXG4iK0MueEIuVCgiICIsZS1rK2oubGVuZ3RoKSsiXlxu
+In1lbHNlIHJldHVybiBlIT1udWxsP2YrKCIgKGF0IG9mZnNldCAiK0guRWooZSkrIikiKTpmfSwKJGlS
+ejoxfQpQLmNYLnByb3RvdHlwZT17CmRyOmZ1bmN0aW9uKGEsYil7cmV0dXJuIEguR0oodGhpcyxILkxo
+KHRoaXMpLkMoImNYLkUiKSxiKX0sCkUyOmZ1bmN0aW9uKGEsYixjKXt2YXIgcz1ILkxoKHRoaXMpCnJl
+dHVybiBILksxKHRoaXMscy5LcShjKS5DKCIxKGNYLkUpIikuYShiKSxzLkMoImNYLkUiKSxjKX0sCmV2
+OmZ1bmN0aW9uKGEsYil7dmFyIHM9SC5MaCh0aGlzKQpyZXR1cm4gbmV3IEguVTUodGhpcyxzLkMoImEy
+KGNYLkUpIikuYShiKSxzLkMoIlU1PGNYLkU+IikpfSwKdHQ6ZnVuY3Rpb24oYSxiKXtyZXR1cm4gUC5Z
+MSh0aGlzLGIsSC5MaCh0aGlzKS5DKCJjWC5FIikpfSwKYnI6ZnVuY3Rpb24oYSl7cmV0dXJuIHRoaXMu
+dHQoYSwhMCl9LApnQTpmdW5jdGlvbihhKXt2YXIgcyxyPXRoaXMuZ20odGhpcykKZm9yKHM9MDtyLkYo
+KTspKytzCnJldHVybiBzfSwKZ2wwOmZ1bmN0aW9uKGEpe3JldHVybiF0aGlzLmdtKHRoaXMpLkYoKX0s
+CmdvcjpmdW5jdGlvbihhKXtyZXR1cm4hdGhpcy5nbDAodGhpcyl9LAplUjpmdW5jdGlvbihhLGIpe3Jl
+dHVybiBILmJLKHRoaXMsYixILkxoKHRoaXMpLkMoImNYLkUiKSl9LApncjg6ZnVuY3Rpb24oYSl7dmFy
+IHMscj10aGlzLmdtKHRoaXMpCmlmKCFyLkYoKSl0aHJvdyBILmIoSC5XcCgpKQpzPXIuZ2woKQppZihy
+LkYoKSl0aHJvdyBILmIoSC5BbSgpKQpyZXR1cm4gc30sCkU6ZnVuY3Rpb24oYSxiKXt2YXIgcyxyLHEK
+UC5rMShiLCJpbmRleCIpCmZvcihzPXRoaXMuZ20odGhpcykscj0wO3MuRigpOyl7cT1zLmdsKCkKaWYo
+Yj09PXIpcmV0dXJuIHE7KytyfXRocm93IEguYihQLkNmKGIsdGhpcywiaW5kZXgiLG51bGwscikpfSwK
+dzpmdW5jdGlvbihhKXtyZXR1cm4gUC5FUCh0aGlzLCIoIiwiKSIpfX0KUC5Bbi5wcm90b3R5cGU9e30K
+UC5OMy5wcm90b3R5cGU9ewp3OmZ1bmN0aW9uKGEpe3JldHVybiJNYXBFbnRyeSgiK0guRWooSi5qKHRo
+aXMuYSkpKyI6ICIrSC5FaihKLmoodGhpcy5iKSkrIikifX0KUC5jOC5wcm90b3R5cGU9ewpnaU86ZnVu
+Y3Rpb24oYSl7cmV0dXJuIFAuTWgucHJvdG90eXBlLmdpTy5jYWxsKEMuak4sdGhpcyl9LAp3OmZ1bmN0
+aW9uKGEpe3JldHVybiJudWxsIn19ClAuTWgucHJvdG90eXBlPXtjb25zdHJ1Y3RvcjpQLk1oLCRpTWg6
+MSwKRE46ZnVuY3Rpb24oYSxiKXtyZXR1cm4gdGhpcz09PWJ9LApnaU86ZnVuY3Rpb24oYSl7cmV0dXJu
+IEguZVEodGhpcyl9LAp3OmZ1bmN0aW9uKGEpe3JldHVybiJJbnN0YW5jZSBvZiAnIitILkVqKEguTSh0
+aGlzKSkrIicifSwKZTc6ZnVuY3Rpb24oYSxiKXt0Lm8uYShiKQp0aHJvdyBILmIoUC5scih0aGlzLGIu
+Z1dhKCksYi5nbmQoKSxiLmdWbSgpKSl9LAp0b1N0cmluZzpmdW5jdGlvbigpe3JldHVybiB0aGlzLnco
+dGhpcyl9fQpQLlpkLnByb3RvdHlwZT17Cnc6ZnVuY3Rpb24oYSl7cmV0dXJuIiJ9LAokaUd6OjF9ClAu
+Um4ucHJvdG90eXBlPXsKZ0E6ZnVuY3Rpb24oYSl7cmV0dXJuIHRoaXMuYS5sZW5ndGh9LAp3OmZ1bmN0
+aW9uKGEpe3ZhciBzPXRoaXMuYQpyZXR1cm4gcy5jaGFyQ29kZUF0KDApPT0wP3M6c30sCiRpQkw6MX0K
+UC5uMS5wcm90b3R5cGU9ewokMjpmdW5jdGlvbihhLGIpe3ZhciBzLHIscSxwCnQuSi5hKGEpCkguaChi
+KQpzPUouclkoYikuT1koYiwiPSIpCmlmKHM9PT0tMSl7aWYoYiE9PSIiKWEuWTUoMCxQLmt1KGIsMCxi
+Lmxlbmd0aCx0aGlzLmEsITApLCIiKX1lbHNlIGlmKHMhPT0wKXtyPUMueEIuTmooYiwwLHMpCnE9Qy54
+Qi55bihiLHMrMSkKcD10aGlzLmEKYS5ZNSgwLFAua3UociwwLHIubGVuZ3RoLHAsITApLFAua3UocSww
+LHEubGVuZ3RoLHAsITApKX1yZXR1cm4gYX0sCiRTOjQ0fQpQLmNTLnByb3RvdHlwZT17CiQyOmZ1bmN0
+aW9uKGEsYil7dGhyb3cgSC5iKFAucnIoIklsbGVnYWwgSVB2NCBhZGRyZXNzLCAiK2EsdGhpcy5hLGIp
+KX0sCiRTOjIxfQpQLlZDLnByb3RvdHlwZT17CiQyOmZ1bmN0aW9uKGEsYil7dGhyb3cgSC5iKFAucnIo
+IklsbGVnYWwgSVB2NiBhZGRyZXNzLCAiK2EsdGhpcy5hLGIpKX0sCiQxOmZ1bmN0aW9uKGEpe3JldHVy
+biB0aGlzLiQyKGEsbnVsbCl9LAokUzo0OX0KUC5KVC5wcm90b3R5cGU9ewokMjpmdW5jdGlvbihhLGIp
+e3ZhciBzCmlmKGItYT40KXRoaXMuYS4kMigiYW4gSVB2NiBwYXJ0IGNhbiBvbmx5IGNvbnRhaW4gYSBt
+YXhpbXVtIG9mIDQgaGV4IGRpZ2l0cyIsYSkKcz1QLlFBKEMueEIuTmoodGhpcy5iLGEsYiksMTYpCmlm
+KHM8MHx8cz42NTUzNSl0aGlzLmEuJDIoImVhY2ggcGFydCBtdXN0IGJlIGluIHRoZSByYW5nZSBvZiBg
+MHgwLi4weEZGRkZgIixhKQpyZXR1cm4gc30sCiRTOjUxfQpQLkRuLnByb3RvdHlwZT17CmduRDpmdW5j
+dGlvbigpe3ZhciBzLHIscSxwLG89dGhpcwppZighby55KXtzPW8uYQpyPXMubGVuZ3RoIT09MD9zKyI6
+IjoiIgpxPW8uYwpwPXE9PW51bGwKaWYoIXB8fHM9PT0iZmlsZSIpe3M9cisiLy8iCnI9by5iCmlmKHIu
+bGVuZ3RoIT09MClzPXMrcisiQCIKaWYoIXApcys9cQpyPW8uZAppZihyIT1udWxsKXM9cysiOiIrSC5F
+aihyKX1lbHNlIHM9cgpzKz1vLmUKcj1vLmYKaWYociE9bnVsbClzPXMrIj8iK3IKcj1vLnIKaWYociE9
+bnVsbClzPXMrIiMiK3IKaWYoby55KXRocm93IEguYihILkdRKCJfdGV4dCIpKQpvLng9cy5jaGFyQ29k
+ZUF0KDApPT0wP3M6cwpvLnk9ITB9cmV0dXJuIG8ueH0sCmdGajpmdW5jdGlvbigpe3ZhciBzLHIscT10
+aGlzCmlmKCFxLlEpe3M9cS5lCmlmKHMubGVuZ3RoIT09MCYmQy54Qi5XKHMsMCk9PT00NylzPUMueEIu
+eW4ocywxKQpyPXMubGVuZ3RoPT09MD9DLnhEOlAuQUYobmV3IEgubEooSC5WTShzLnNwbGl0KCIvIiks
+dC5zKSx0LmRPLmEoUC5QSCgpKSx0LmRvKSx0Lk4pCmlmKHEuUSl0aHJvdyBILmIoSC5HUSgicGF0aFNl
+Z21lbnRzIikpCnEuc0twKHIpCnEuUT0hMH1yZXR1cm4gcS56fSwKZ2lPOmZ1bmN0aW9uKGEpe3ZhciBz
+LHI9dGhpcwppZighci5jeCl7cz1KLmhmKHIuZ25EKCkpCmlmKHIuY3gpdGhyb3cgSC5iKEguR1EoImhh
+c2hDb2RlIikpCnIuY2g9cwpyLmN4PSEwfXJldHVybiByLmNofSwKZ2hZOmZ1bmN0aW9uKCl7dmFyIHMs
+cj10aGlzCmlmKCFyLmRiKXtzPVAuV1goci5ndFAoKSkKaWYoci5kYil0aHJvdyBILmIoSC5HUSgicXVl
+cnlQYXJhbWV0ZXJzIikpCnIuc05NKG5ldyBQLkdqKHMsdC5kdykpCnIuZGI9ITB9cmV0dXJuIHIuY3l9
+LApna3U6ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5ifSwKZ0pmOmZ1bmN0aW9uKGEpe3ZhciBzPXRoaXMu
+YwppZihzPT1udWxsKXJldHVybiIiCmlmKEMueEIubkMocywiWyIpKXJldHVybiBDLnhCLk5qKHMsMSxz
+Lmxlbmd0aC0xKQpyZXR1cm4gc30sCmd0cDpmdW5jdGlvbihhKXt2YXIgcz10aGlzLmQKcmV0dXJuIHM9
+PW51bGw/UC53Syh0aGlzLmEpOnN9LApndFA6ZnVuY3Rpb24oKXt2YXIgcz10aGlzLmYKcmV0dXJuIHM9
+PW51bGw/IiI6c30sCmdLYTpmdW5jdGlvbigpe3ZhciBzPXRoaXMucgpyZXR1cm4gcz09bnVsbD8iIjpz
+fSwKbm06ZnVuY3Rpb24oYSxiKXt2YXIgcyxyLHEscCxvLG4sbSxsLGssaj10aGlzCnQuYzkuYShiKQpz
+PWouYQpyPXM9PT0iZmlsZSIKcT1qLmIKcD1qLmQKbz1qLmMKaWYoIShvIT1udWxsKSlvPXEubGVuZ3Ro
+IT09MHx8cCE9bnVsbHx8cj8iIjpudWxsCm49ai5lCmlmKCFyKW09byE9bnVsbCYmbi5sZW5ndGghPT0w
+CmVsc2UgbT0hMAppZihtJiYhQy54Qi5uQyhuLCIvIikpbj0iLyIrbgpsPW4Kaz1QLmxlKG51bGwsMCww
+LGIpCnJldHVybiBuZXcgUC5EbihzLHEsbyxwLGwsayxqLnIpfSwKSmg6ZnVuY3Rpb24oYSxiKXt2YXIg
+cyxyLHEscCxvLG4KZm9yKHM9MCxyPTA7Qy54Qi5RaShiLCIuLi8iLHIpOyl7cis9MzsrK3N9cT1DLnhC
+LmNuKGEsIi8iKQp3aGlsZSghMCl7aWYoIShxPjAmJnM+MCkpYnJlYWsKcD1DLnhCLlBrKGEsIi8iLHEt
+MSkKaWYocDwwKWJyZWFrCm89cS1wCm49byE9PTIKaWYoIW58fG89PT0zKWlmKEMueEIuTzIoYSxwKzEp
+PT09NDYpbj0hbnx8Qy54Qi5PMihhLHArMik9PT00NgplbHNlIG49ITEKZWxzZSBuPSExCmlmKG4pYnJl
+YWs7LS1zCnE9cH1yZXR1cm4gQy54Qi5pNyhhLHErMSxudWxsLEMueEIueW4oYixyLTMqcykpfSwKWkk6
+ZnVuY3Rpb24oYSl7cmV0dXJuIHRoaXMubVMoUC5oSyhhKSl9LAptUzpmdW5jdGlvbihhKXt2YXIgcyxy
+LHEscCxvLG4sbSxsLGssaj10aGlzLGk9bnVsbAppZihhLmdGaSgpLmxlbmd0aCE9PTApe3M9YS5nRmko
+KQppZihhLmdjaigpKXtyPWEuZ2t1KCkKcT1hLmdKZihhKQpwPWEuZ3hBKCk/YS5ndHAoYSk6aX1lbHNl
+e3A9aQpxPXAKcj0iIn1vPVAueGUoYS5nSWkoYSkpCm49YS5nUUQoKT9hLmd0UCgpOml9ZWxzZXtzPWou
+YQppZihhLmdjaigpKXtyPWEuZ2t1KCkKcT1hLmdKZihhKQpwPVAud0IoYS5neEEoKT9hLmd0cChhKTpp
+LHMpCm89UC54ZShhLmdJaShhKSkKbj1hLmdRRCgpP2EuZ3RQKCk6aX1lbHNle3I9ai5iCnE9ai5jCnA9
+ai5kCmlmKGEuZ0lpKGEpPT09IiIpe289ai5lCm49YS5nUUQoKT9hLmd0UCgpOmouZn1lbHNle2lmKGEu
+Z3RUKCkpbz1QLnhlKGEuZ0lpKGEpKQplbHNle209ai5lCmlmKG0ubGVuZ3RoPT09MClpZihxPT1udWxs
+KW89cy5sZW5ndGg9PT0wP2EuZ0lpKGEpOlAueGUoYS5nSWkoYSkpCmVsc2Ugbz1QLnhlKCIvIithLmdJ
+aShhKSkKZWxzZXtsPWouSmgobSxhLmdJaShhKSkKaz1zLmxlbmd0aD09PTAKaWYoIWt8fHEhPW51bGx8
+fEMueEIubkMobSwiLyIpKW89UC54ZShsKQplbHNlIG89UC53RihsLCFrfHxxIT1udWxsKX19bj1hLmdR
+RCgpP2EuZ3RQKCk6aX19fXJldHVybiBuZXcgUC5EbihzLHIscSxwLG8sbixhLmdaOCgpP2EuZ0thKCk6
+aSl9LApnY2o6ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5jIT1udWxsfSwKZ3hBOmZ1bmN0aW9uKCl7cmV0
+dXJuIHRoaXMuZCE9bnVsbH0sCmdRRDpmdW5jdGlvbigpe3JldHVybiB0aGlzLmYhPW51bGx9LApnWjg6
+ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5yIT1udWxsfSwKZ3RUOmZ1bmN0aW9uKCl7cmV0dXJuIEMueEIu
+bkModGhpcy5lLCIvIil9LAp0NDpmdW5jdGlvbigpe3ZhciBzLHI9dGhpcyxxPXIuYQppZihxIT09IiIm
+JnEhPT0iZmlsZSIpdGhyb3cgSC5iKFAuTDQoIkNhbm5vdCBleHRyYWN0IGEgZmlsZSBwYXRoIGZyb20g
+YSAiK3ErIiBVUkkiKSkKaWYoci5ndFAoKSE9PSIiKXRocm93IEguYihQLkw0KHUuaSkpCmlmKHIuZ0th
+KCkhPT0iIil0aHJvdyBILmIoUC5MNCh1LmwpKQpxPSQud1EoKQppZihILm9UKHEpKXE9UC5tbihyKQpl
+bHNle2lmKHIuYyE9bnVsbCYmci5nSmYocikhPT0iIilILnYoUC5MNCh1LmopKQpzPXIuZ0ZqKCkKUC5r
+RShzLCExKQpxPVAudmcoQy54Qi5uQyhyLmUsIi8iKT8iLyI6IiIscywiLyIpCnE9cS5jaGFyQ29kZUF0
+KDApPT0wP3E6cX1yZXR1cm4gcX0sCnc6ZnVuY3Rpb24oYSl7cmV0dXJuIHRoaXMuZ25EKCl9LApETjpm
+dW5jdGlvbihhLGIpe3ZhciBzPXRoaXMKaWYoYj09bnVsbClyZXR1cm4hMQppZihzPT09YilyZXR1cm4h
+MApyZXR1cm4gdC5kRC5iKGIpJiZzLmE9PT1iLmdGaSgpJiZzLmMhPW51bGw9PT1iLmdjaigpJiZzLmI9
+PT1iLmdrdSgpJiZzLmdKZihzKT09PWIuZ0pmKGIpJiZzLmd0cChzKT09PWIuZ3RwKGIpJiZzLmU9PT1i
+LmdJaShiKSYmcy5mIT1udWxsPT09Yi5nUUQoKSYmcy5ndFAoKT09PWIuZ3RQKCkmJnMuciE9bnVsbD09
+PWIuZ1o4KCkmJnMuZ0thKCk9PT1iLmdLYSgpfSwKc0twOmZ1bmN0aW9uKGEpe3RoaXMuej10LmJrLmEo
+YSl9LApzTk06ZnVuY3Rpb24oYSl7dGhpcy5jeT10LmNaLmEoYSl9LAokaWlEOjEsCmdGaTpmdW5jdGlv
+bigpe3JldHVybiB0aGlzLmF9LApnSWk6ZnVuY3Rpb24oYSl7cmV0dXJuIHRoaXMuZX19ClAuUloucHJv
+dG90eXBlPXsKJDE6ZnVuY3Rpb24oYSl7cmV0dXJuIFAuZVAoQy5aSixILmgoYSksQy54TSwhMSl9LAok
+Uzo1fQpQLk1FLnByb3RvdHlwZT17CiQyOmZ1bmN0aW9uKGEsYil7dmFyIHM9dGhpcy5iLHI9dGhpcy5h
+CnMuYSs9ci5hCnIuYT0iJiIKcj1zLmErPUguRWooUC5lUChDLkYzLGEsQy54TSwhMCkpCmlmKGIhPW51
+bGwmJmIubGVuZ3RoIT09MCl7cy5hPXIrIj0iCnMuYSs9SC5FaihQLmVQKEMuRjMsYixDLnhNLCEwKSl9
+fSwKJFM6MjJ9ClAueTUucHJvdG90eXBlPXsKJDI6ZnVuY3Rpb24oYSxiKXt2YXIgcyxyCkguaChhKQpp
+ZihiPT1udWxsfHx0eXBlb2YgYj09InN0cmluZyIpdGhpcy5hLiQyKGEsSC5rKGIpKQplbHNlIGZvcihz
+PUouSVQodC51LmEoYikpLHI9dGhpcy5hO3MuRigpOylyLiQyKGEsSC5oKHMuZ2woKSkpfSwKJFM6MTJ9
+ClAuUEUucHJvdG90eXBlPXsKZ2xSOmZ1bmN0aW9uKCl7dmFyIHMscixxLHAsbz10aGlzLG49bnVsbCxt
+PW8uYwppZihtPT1udWxsKXttPW8uYgppZigwPj1tLmxlbmd0aClyZXR1cm4gSC5PSChtLDApCnM9by5h
+Cm09bVswXSsxCnI9Qy54Qi5YVShzLCI/IixtKQpxPXMubGVuZ3RoCmlmKHI+PTApe3A9UC5QSShzLHIr
+MSxxLEMuVkMsITEpCnE9cn1lbHNlIHA9bgptPW8uYz1uZXcgUC5xZSgiZGF0YSIsIiIsbixuLFAuUEko
+cyxtLHEsQy5XZCwhMSkscCxuKX1yZXR1cm4gbX0sCnc6ZnVuY3Rpb24oYSl7dmFyIHMscj10aGlzLmIK
+aWYoMD49ci5sZW5ndGgpcmV0dXJuIEguT0gociwwKQpzPXRoaXMuYQpyZXR1cm4gclswXT09PS0xPyJk
+YXRhOiIrczpzfX0KUC55SS5wcm90b3R5cGU9ewokMjpmdW5jdGlvbihhLGIpe3ZhciBzPXRoaXMuYQpp
+ZihhPj1zLmxlbmd0aClyZXR1cm4gSC5PSChzLGEpCnM9c1thXQpDLk5BLmR1KHMsMCw5NixiKQpyZXR1
+cm4gc30sCiRTOjIzfQpQLmM2LnByb3RvdHlwZT17CiQzOmZ1bmN0aW9uKGEsYixjKXt2YXIgcyxyLHEK
+Zm9yKHM9Yi5sZW5ndGgscj0wO3I8czsrK3Ipe3E9Qy54Qi5XKGIscileOTYKaWYocT49OTYpcmV0dXJu
+IEguT0goYSxxKQphW3FdPWN9fSwKJFM6MTN9ClAucWQucHJvdG90eXBlPXsKJDM6ZnVuY3Rpb24oYSxi
+LGMpe3ZhciBzLHIscQpmb3Iocz1DLnhCLlcoYiwwKSxyPUMueEIuVyhiLDEpO3M8PXI7KytzKXtxPShz
+Xjk2KT4+PjAKaWYocT49OTYpcmV0dXJuIEguT0goYSxxKQphW3FdPWN9fSwKJFM6MTN9ClAuVWYucHJv
+dG90eXBlPXsKZ2NqOmZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMuYz4wfSwKZ3hBOmZ1bmN0aW9uKCl7cmV0
+dXJuIHRoaXMuYz4wJiZ0aGlzLmQrMTx0aGlzLmV9LApnUUQ6ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5m
+PHRoaXMucn0sCmdaODpmdW5jdGlvbigpe3JldHVybiB0aGlzLnI8dGhpcy5hLmxlbmd0aH0sCmdOdzpm
+dW5jdGlvbigpe3JldHVybiB0aGlzLmI9PT00JiZDLnhCLm5DKHRoaXMuYSwiZmlsZSIpfSwKZ1daOmZ1
+bmN0aW9uKCl7cmV0dXJuIHRoaXMuYj09PTQmJkMueEIubkModGhpcy5hLCJodHRwIil9LApnUmU6ZnVu
+Y3Rpb24oKXtyZXR1cm4gdGhpcy5iPT09NSYmQy54Qi5uQyh0aGlzLmEsImh0dHBzIil9LApndFQ6ZnVu
+Y3Rpb24oKXtyZXR1cm4gQy54Qi5RaSh0aGlzLmEsIi8iLHRoaXMuZSl9LApnRmk6ZnVuY3Rpb24oKXt2
+YXIgcz10aGlzLngKcmV0dXJuIHM9PW51bGw/dGhpcy54PXRoaXMuVTIoKTpzfSwKVTI6ZnVuY3Rpb24o
+KXt2YXIgcz10aGlzLHI9cy5iCmlmKHI8PTApcmV0dXJuIiIKaWYocy5nV1ooKSlyZXR1cm4iaHR0cCIK
+aWYocy5nUmUoKSlyZXR1cm4iaHR0cHMiCmlmKHMuZ053KCkpcmV0dXJuImZpbGUiCmlmKHI9PT03JiZD
+LnhCLm5DKHMuYSwicGFja2FnZSIpKXJldHVybiJwYWNrYWdlIgpyZXR1cm4gQy54Qi5OaihzLmEsMCxy
+KX0sCmdrdTpmdW5jdGlvbigpe3ZhciBzPXRoaXMuYyxyPXRoaXMuYiszCnJldHVybiBzPnI/Qy54Qi5O
+aih0aGlzLmEscixzLTEpOiIifSwKZ0pmOmZ1bmN0aW9uKGEpe3ZhciBzPXRoaXMuYwpyZXR1cm4gcz4w
+P0MueEIuTmoodGhpcy5hLHMsdGhpcy5kKToiIn0sCmd0cDpmdW5jdGlvbihhKXt2YXIgcz10aGlzCmlm
+KHMuZ3hBKCkpcmV0dXJuIFAuUUEoQy54Qi5OaihzLmEscy5kKzEscy5lKSxudWxsKQppZihzLmdXWigp
+KXJldHVybiA4MAppZihzLmdSZSgpKXJldHVybiA0NDMKcmV0dXJuIDB9LApnSWk6ZnVuY3Rpb24oYSl7
+cmV0dXJuIEMueEIuTmoodGhpcy5hLHRoaXMuZSx0aGlzLmYpfSwKZ3RQOmZ1bmN0aW9uKCl7dmFyIHM9
+dGhpcy5mLHI9dGhpcy5yCnJldHVybiBzPHI/Qy54Qi5Oaih0aGlzLmEscysxLHIpOiIifSwKZ0thOmZ1
+bmN0aW9uKCl7dmFyIHM9dGhpcy5yLHI9dGhpcy5hCnJldHVybiBzPHIubGVuZ3RoP0MueEIueW4ocixz
+KzEpOiIifSwKZ0ZqOmZ1bmN0aW9uKCl7dmFyIHMscixxPXRoaXMuZSxwPXRoaXMuZixvPXRoaXMuYQpp
+ZihDLnhCLlFpKG8sIi8iLHEpKSsrcQppZihxPT09cClyZXR1cm4gQy54RApzPUguVk0oW10sdC5zKQpm
+b3Iocj1xO3I8cDsrK3IpaWYoQy54Qi5PMihvLHIpPT09NDcpe0MuTm0uaShzLEMueEIuTmoobyxxLHIp
+KQpxPXIrMX1DLk5tLmkocyxDLnhCLk5qKG8scSxwKSkKcmV0dXJuIFAuQUYocyx0Lk4pfSwKZ2hZOmZ1
+bmN0aW9uKCl7aWYodGhpcy5mPj10aGlzLnIpcmV0dXJuIEMuQ00KcmV0dXJuIG5ldyBQLkdqKFAuV1go
+dGhpcy5ndFAoKSksdC5kdyl9LAprWDpmdW5jdGlvbihhKXt2YXIgcz10aGlzLmQrMQpyZXR1cm4gcyth
+Lmxlbmd0aD09PXRoaXMuZSYmQy54Qi5RaSh0aGlzLmEsYSxzKX0sCk45OmZ1bmN0aW9uKCl7dmFyIHM9
+dGhpcyxyPXMucixxPXMuYQppZihyPj1xLmxlbmd0aClyZXR1cm4gcwpyZXR1cm4gbmV3IFAuVWYoQy54
+Qi5OaihxLDAscikscy5iLHMuYyxzLmQscy5lLHMuZixyLHMueCl9LApubTpmdW5jdGlvbihhLGIpe3Zh
+ciBzLHIscSxwLG8sbixtLGwsayxqLGk9dGhpcyxoPW51bGwKdC5jOS5hKGIpCnM9aS5nRmkoKQpyPXM9
+PT0iZmlsZSIKcT1pLmMKcD1xPjA/Qy54Qi5OaihpLmEsaS5iKzMscSk6IiIKbz1pLmd4QSgpP2kuZ3Rw
+KGkpOmgKcT1pLmMKaWYocT4wKW49Qy54Qi5OaihpLmEscSxpLmQpCmVsc2Ugbj1wLmxlbmd0aCE9PTB8
+fG8hPW51bGx8fHI/IiI6aApxPWkuYQptPUMueEIuTmoocSxpLmUsaS5mKQppZighcilsPW4hPW51bGwm
+Jm0ubGVuZ3RoIT09MAplbHNlIGw9ITAKaWYobCYmIUMueEIubkMobSwiLyIpKW09Ii8iK20Kaz1QLmxl
+KGgsMCwwLGIpCmw9aS5yCmo9bDxxLmxlbmd0aD9DLnhCLnluKHEsbCsxKTpoCnJldHVybiBuZXcgUC5E
+bihzLHAsbixvLG0sayxqKX0sClpJOmZ1bmN0aW9uKGEpe3JldHVybiB0aGlzLm1TKFAuaEsoYSkpfSwK
+bVM6ZnVuY3Rpb24oYSl7aWYoYSBpbnN0YW5jZW9mIFAuVWYpcmV0dXJuIHRoaXMudTEodGhpcyxhKQpy
+ZXR1cm4gdGhpcy52cygpLm1TKGEpfSwKdTE6ZnVuY3Rpb24oYSxiKXt2YXIgcyxyLHEscCxvLG4sbSxs
+LGssaixpLGgsZz1iLmIKaWYoZz4wKXJldHVybiBiCnM9Yi5jCmlmKHM+MCl7cj1hLmIKaWYocjw9MCly
+ZXR1cm4gYgppZihhLmdOdygpKXE9Yi5lIT09Yi5mCmVsc2UgaWYoYS5nV1ooKSlxPSFiLmtYKCI4MCIp
+CmVsc2UgcT0hYS5nUmUoKXx8IWIua1goIjQ0MyIpCmlmKHEpe3A9cisxCnJldHVybiBuZXcgUC5VZihD
+LnhCLk5qKGEuYSwwLHApK0MueEIueW4oYi5hLGcrMSkscixzK3AsYi5kK3AsYi5lK3AsYi5mK3AsYi5y
+K3AsYS54KX1lbHNlIHJldHVybiB0aGlzLnZzKCkubVMoYil9bz1iLmUKZz1iLmYKaWYobz09PWcpe3M9
+Yi5yCmlmKGc8cyl7cj1hLmYKcD1yLWcKcmV0dXJuIG5ldyBQLlVmKEMueEIuTmooYS5hLDAscikrQy54
+Qi55bihiLmEsZyksYS5iLGEuYyxhLmQsYS5lLGcrcCxzK3AsYS54KX1nPWIuYQppZihzPGcubGVuZ3Ro
+KXtyPWEucgpyZXR1cm4gbmV3IFAuVWYoQy54Qi5OaihhLmEsMCxyKStDLnhCLnluKGcscyksYS5iLGEu
+YyxhLmQsYS5lLGEuZixzKyhyLXMpLGEueCl9cmV0dXJuIGEuTjkoKX1zPWIuYQppZihDLnhCLlFpKHMs
+Ii8iLG8pKXtyPWEuZQpwPXItbwpyZXR1cm4gbmV3IFAuVWYoQy54Qi5OaihhLmEsMCxyKStDLnhCLnlu
+KHMsbyksYS5iLGEuYyxhLmQscixnK3AsYi5yK3AsYS54KX1uPWEuZQptPWEuZgppZihuPT09bSYmYS5j
+PjApe2Zvcig7Qy54Qi5RaShzLCIuLi8iLG8pOylvKz0zCnA9bi1vKzEKcmV0dXJuIG5ldyBQLlVmKEMu
+eEIuTmooYS5hLDAsbikrIi8iK0MueEIueW4ocyxvKSxhLmIsYS5jLGEuZCxuLGcrcCxiLnIrcCxhLngp
+fWw9YS5hCmZvcihrPW47Qy54Qi5RaShsLCIuLi8iLGspOylrKz0zCmo9MAp3aGlsZSghMCl7aT1vKzMK
+aWYoIShpPD1nJiZDLnhCLlFpKHMsIi4uLyIsbykpKWJyZWFrOysragpvPWl9Zm9yKGg9IiI7bT5rOyl7
+LS1tCmlmKEMueEIuTzIobCxtKT09PTQ3KXtpZihqPT09MCl7aD0iLyIKYnJlYWt9LS1qCmg9Ii8ifX1p
+ZihtPT09ayYmYS5iPD0wJiYhQy54Qi5RaShsLCIvIixuKSl7by09aiozCmg9IiJ9cD1tLW8raC5sZW5n
+dGgKcmV0dXJuIG5ldyBQLlVmKEMueEIuTmoobCwwLG0pK2grQy54Qi55bihzLG8pLGEuYixhLmMsYS5k
+LG4sZytwLGIucitwLGEueCl9LAp0NDpmdW5jdGlvbigpe3ZhciBzLHIscSxwPXRoaXMKaWYocC5iPj0w
+JiYhcC5nTncoKSl0aHJvdyBILmIoUC5MNCgiQ2Fubm90IGV4dHJhY3QgYSBmaWxlIHBhdGggZnJvbSBh
+ICIrcC5nRmkoKSsiIFVSSSIpKQpzPXAuZgpyPXAuYQppZihzPHIubGVuZ3RoKXtpZihzPHAucil0aHJv
+dyBILmIoUC5MNCh1LmkpKQp0aHJvdyBILmIoUC5MNCh1LmwpKX1xPSQud1EoKQppZihILm9UKHEpKXM9
+UC5tbihwKQplbHNle2lmKHAuYzxwLmQpSC52KFAuTDQodS5qKSkKcz1DLnhCLk5qKHIscC5lLHMpfXJl
+dHVybiBzfSwKZ2lPOmZ1bmN0aW9uKGEpe3ZhciBzPXRoaXMueQpyZXR1cm4gcz09bnVsbD90aGlzLnk9
+Qy54Qi5naU8odGhpcy5hKTpzfSwKRE46ZnVuY3Rpb24oYSxiKXtpZihiPT1udWxsKXJldHVybiExCmlm
+KHRoaXM9PT1iKXJldHVybiEwCnJldHVybiB0LmRELmIoYikmJnRoaXMuYT09PWIudygwKX0sCnZzOmZ1
+bmN0aW9uKCl7dmFyIHM9dGhpcyxyPW51bGwscT1zLmdGaSgpLHA9cy5na3UoKSxvPXMuYz4wP3MuZ0pm
+KHMpOnIsbj1zLmd4QSgpP3MuZ3RwKHMpOnIsbT1zLmEsbD1zLmYsaz1DLnhCLk5qKG0scy5lLGwpLGo9
+cy5yCmw9bDxqP3MuZ3RQKCk6cgpyZXR1cm4gbmV3IFAuRG4ocSxwLG8sbixrLGwsajxtLmxlbmd0aD9z
+LmdLYSgpOnIpfSwKdzpmdW5jdGlvbihhKXtyZXR1cm4gdGhpcy5hfSwKJGlpRDoxfQpQLnFlLnByb3Rv
+dHlwZT17fQpXLnFFLnByb3RvdHlwZT17fQpXLkdoLnByb3RvdHlwZT17CnNMVTpmdW5jdGlvbihhLGIp
+e2EuaHJlZj1ifSwKdzpmdW5jdGlvbihhKXtyZXR1cm4gU3RyaW5nKGEpfSwKJGlHaDoxfQpXLmZZLnBy
+b3RvdHlwZT17Cnc6ZnVuY3Rpb24oYSl7cmV0dXJuIFN0cmluZyhhKX19ClcubkIucHJvdG90eXBlPXsk
+aW5COjF9ClcuQXoucHJvdG90eXBlPXskaUF6OjF9ClcuUVAucHJvdG90eXBlPXskaVFQOjF9Clcubngu
+cHJvdG90eXBlPXsKZ0E6ZnVuY3Rpb24oYSl7cmV0dXJuIGEubGVuZ3RofX0KVy5vSi5wcm90b3R5cGU9
+ewpnQTpmdW5jdGlvbihhKXtyZXR1cm4gYS5sZW5ndGh9fQpXLmlkLnByb3RvdHlwZT17fQpXLlFGLnBy
+b3RvdHlwZT17fQpXLk5oLnByb3RvdHlwZT17Cnc6ZnVuY3Rpb24oYSl7cmV0dXJuIFN0cmluZyhhKX19
+ClcuYWUucHJvdG90eXBlPXsKRGM6ZnVuY3Rpb24oYSxiKXtyZXR1cm4gYS5jcmVhdGVIVE1MRG9jdW1l
+bnQoYil9fQpXLklCLnByb3RvdHlwZT17Cnc6ZnVuY3Rpb24oYSl7dmFyIHMscj1hLmxlZnQKci50b1N0
+cmluZwpyPSJSZWN0YW5nbGUgKCIrSC5FaihyKSsiLCAiCnM9YS50b3AKcy50b1N0cmluZwpzPXIrSC5F
+aihzKSsiKSAiCnI9YS53aWR0aApyLnRvU3RyaW5nCnI9cytILkVqKHIpKyIgeCAiCnM9YS5oZWlnaHQK
+cy50b1N0cmluZwpyZXR1cm4gcitILkVqKHMpfSwKRE46ZnVuY3Rpb24oYSxiKXt2YXIgcyxyCmlmKGI9
+PW51bGwpcmV0dXJuITEKaWYodC5xLmIoYikpe3M9YS5sZWZ0CnMudG9TdHJpbmcKcj1iLmxlZnQKci50
+b1N0cmluZwppZihzPT09cil7cz1hLnRvcApzLnRvU3RyaW5nCnI9Yi50b3AKci50b1N0cmluZwppZihz
+PT09cil7cz1hLndpZHRoCnMudG9TdHJpbmcKcj1iLndpZHRoCnIudG9TdHJpbmcKaWYocz09PXIpe3M9
+YS5oZWlnaHQKcy50b1N0cmluZwpyPWIuaGVpZ2h0CnIudG9TdHJpbmcKcj1zPT09cgpzPXJ9ZWxzZSBz
+PSExfWVsc2Ugcz0hMX1lbHNlIHM9ITF9ZWxzZSBzPSExCnJldHVybiBzfSwKZ2lPOmZ1bmN0aW9uKGEp
+e3ZhciBzLHIscSxwPWEubGVmdApwLnRvU3RyaW5nCnA9Qy5DRC5naU8ocCkKcz1hLnRvcApzLnRvU3Ry
+aW5nCnM9Qy5DRC5naU8ocykKcj1hLndpZHRoCnIudG9TdHJpbmcKcj1DLkNELmdpTyhyKQpxPWEuaGVp
+Z2h0CnEudG9TdHJpbmcKcmV0dXJuIFcuckUocCxzLHIsQy5DRC5naU8ocSkpfSwKJGl0bjoxfQpXLm43
+LnByb3RvdHlwZT17CmdBOmZ1bmN0aW9uKGEpe3JldHVybiBhLmxlbmd0aH19Clcud3oucHJvdG90eXBl
+PXsKZ0E6ZnVuY3Rpb24oYSl7cmV0dXJuIHRoaXMuYS5sZW5ndGh9LApxOmZ1bmN0aW9uKGEsYil7dmFy
+IHMKSC51UChiKQpzPXRoaXMuYQppZihiPDB8fGI+PXMubGVuZ3RoKXJldHVybiBILk9IKHMsYikKcmV0
+dXJuIHRoaXMuJHRpLmMuYShzW2JdKX0sClk1OmZ1bmN0aW9uKGEsYixjKXt0aGlzLiR0aS5jLmEoYykK
+dGhyb3cgSC5iKFAuTDQoIkNhbm5vdCBtb2RpZnkgbGlzdCIpKX19ClcuY3YucHJvdG90eXBlPXsKZ1Fn
+OmZ1bmN0aW9uKGEpe3JldHVybiBuZXcgVy5pNyhhKX0sCmduOmZ1bmN0aW9uKGEpe3JldHVybiBuZXcg
+Vy5JNChhKX0sCnNuOmZ1bmN0aW9uKGEsYil7dmFyIHMKdC5RLmEoYikKcz10aGlzLmduKGEpCnMuVjEo
+MCkKcy5GVigwLGIpfSwKdzpmdW5jdGlvbihhKXtyZXR1cm4gYS5sb2NhbE5hbWV9LApGRjpmdW5jdGlv
+bihhKXt2YXIgcz0hIWEuc2Nyb2xsSW50b1ZpZXdJZk5lZWRlZAppZihzKWEuc2Nyb2xsSW50b1ZpZXdJ
+Zk5lZWRlZCgpCmVsc2UgYS5zY3JvbGxJbnRvVmlldygpfSwKbno6ZnVuY3Rpb24oYSxiLGMsZCxlKXt2
+YXIgcyxyPXRoaXMucjYoYSxjLGQsZSkKc3dpdGNoKGIudG9Mb3dlckNhc2UoKSl7Y2FzZSJiZWZvcmVi
+ZWdpbiI6cz1hLnBhcmVudE5vZGUKcy50b1N0cmluZwpKLkVoKHMscixhKQpicmVhawpjYXNlImFmdGVy
+YmVnaW4iOnM9YS5jaGlsZE5vZGVzCnRoaXMubUsoYSxyLHMubGVuZ3RoPjA/c1swXTpudWxsKQpicmVh
+awpjYXNlImJlZm9yZWVuZCI6YS5hcHBlbmRDaGlsZChyKQpicmVhawpjYXNlImFmdGVyZW5kIjpzPWEu
+cGFyZW50Tm9kZQpzLnRvU3RyaW5nCkouRWgocyxyLGEubmV4dFNpYmxpbmcpCmJyZWFrCmRlZmF1bHQ6
+SC52KFAueFkoIkludmFsaWQgcG9zaXRpb24gIitiKSl9fSwKcjY6ZnVuY3Rpb24oYSxiLGMsZCl7dmFy
+IHMscixxLHAKaWYoYz09bnVsbCl7aWYoZD09bnVsbCl7cz0kLmx0CmlmKHM9PW51bGwpe3M9SC5WTShb
+XSx0LnYpCnI9bmV3IFcudkQocykKQy5ObS5pKHMsVy5UdyhudWxsKSkKQy5ObS5pKHMsVy5CbCgpKQok
+Lmx0PXIKZD1yfWVsc2UgZD1zfXM9JC5FVQppZihzPT1udWxsKXtzPW5ldyBXLktvKGQpCiQuRVU9cwpj
+PXN9ZWxzZXtzLmE9ZApjPXN9fWVsc2UgaWYoZCE9bnVsbCl0aHJvdyBILmIoUC54WSgidmFsaWRhdG9y
+IGNhbiBvbmx5IGJlIHBhc3NlZCBpZiB0cmVlU2FuaXRpemVyIGlzIG51bGwiKSkKaWYoJC54bz09bnVs
+bCl7cz1kb2N1bWVudApyPXMuaW1wbGVtZW50YXRpb24Kci50b1N0cmluZwpyPUMubUguRGMociwiIikK
+JC54bz1yCiQuQk89ci5jcmVhdGVSYW5nZSgpCnI9JC54by5jcmVhdGVFbGVtZW50KCJiYXNlIikKdC5j
+Ui5hKHIpCnM9cy5iYXNlVVJJCnMudG9TdHJpbmcKci5ocmVmPXMKJC54by5oZWFkLmFwcGVuZENoaWxk
+KHIpfXM9JC54bwppZihzLmJvZHk9PW51bGwpe3I9cy5jcmVhdGVFbGVtZW50KCJib2R5IikKQy5CWi5z
+WEcocyx0LnAuYShyKSl9cz0kLnhvCmlmKHQucC5iKGEpKXtzPXMuYm9keQpzLnRvU3RyaW5nCnE9c31l
+bHNle3MudG9TdHJpbmcKcT1zLmNyZWF0ZUVsZW1lbnQoYS50YWdOYW1lKQokLnhvLmJvZHkuYXBwZW5k
+Q2hpbGQocSl9aWYoImNyZWF0ZUNvbnRleHR1YWxGcmFnbWVudCIgaW4gd2luZG93LlJhbmdlLnByb3Rv
+dHlwZSYmIUMuTm0udGcoQy5TcSxhLnRhZ05hbWUpKXskLkJPLnNlbGVjdE5vZGVDb250ZW50cyhxKQpz
+PSQuQk8Kcy50b1N0cmluZwpwPXMuY3JlYXRlQ29udGV4dHVhbEZyYWdtZW50KGI9PW51bGw/Im51bGwi
+OmIpfWVsc2V7Si53ZihxLGIpCnA9JC54by5jcmVhdGVEb2N1bWVudEZyYWdtZW50KCkKZm9yKDtzPXEu
+Zmlyc3RDaGlsZCxzIT1udWxsOylwLmFwcGVuZENoaWxkKHMpfWlmKHEhPT0kLnhvLmJvZHkpSi5MdChx
+KQpjLlBuKHApCmRvY3VtZW50LmFkb3B0Tm9kZShwKQpyZXR1cm4gcH0sCkFIOmZ1bmN0aW9uKGEsYixj
+KXtyZXR1cm4gdGhpcy5yNihhLGIsYyxudWxsKX0sCnNoZjpmdW5jdGlvbihhLGIpe3RoaXMuWUMoYSxi
+KX0sCnBrOmZ1bmN0aW9uKGEsYixjKXt0aGlzLnNhNChhLG51bGwpCmEuYXBwZW5kQ2hpbGQodGhpcy5y
+NihhLGIsbnVsbCxjKSl9LApZQzpmdW5jdGlvbihhLGIpe3JldHVybiB0aGlzLnBrKGEsYixudWxsKX0s
+CnNSTjpmdW5jdGlvbihhLGIpe2EuaW5uZXJIVE1MPWJ9LApnbnM6ZnVuY3Rpb24oYSl7cmV0dXJuIGEu
+dGFnTmFtZX0sCmdWbDpmdW5jdGlvbihhKXtyZXR1cm4gbmV3IFcuZXUoYSwiY2xpY2siLCExLHQuayl9
+LAokaWN2OjF9ClcuQ3YucHJvdG90eXBlPXsKJDE6ZnVuY3Rpb24oYSl7cmV0dXJuIHQuaC5iKHQuQS5h
+KGEpKX0sCiRTOjI1fQpXLmVhLnByb3RvdHlwZT17JGllYToxfQpXLkQwLnByb3RvdHlwZT17Ck9uOmZ1
+bmN0aW9uKGEsYixjLGQpe3QuYncuYShjKQppZihjIT1udWxsKXRoaXMudihhLGIsYyxkKX0sCkI6ZnVu
+Y3Rpb24oYSxiLGMpe3JldHVybiB0aGlzLk9uKGEsYixjLG51bGwpfSwKdjpmdW5jdGlvbihhLGIsYyxk
+KXtyZXR1cm4gYS5hZGRFdmVudExpc3RlbmVyKGIsSC50Uih0LmJ3LmEoYyksMSksZCl9LAokaUQwOjF9
+ClcuaEgucHJvdG90eXBlPXskaWhIOjF9ClcuaDQucHJvdG90eXBlPXsKZ0E6ZnVuY3Rpb24oYSl7cmV0
+dXJuIGEubGVuZ3RofX0KVy5ici5wcm90b3R5cGU9ewpnQTpmdW5jdGlvbihhKXtyZXR1cm4gYS5sZW5n
+dGh9fQpXLlZiLnByb3RvdHlwZT17CnNYRzpmdW5jdGlvbihhLGIpe2EuYm9keT1ifX0KVy5mSi5wcm90
+b3R5cGU9ewplbzpmdW5jdGlvbihhLGIsYyxkKXtyZXR1cm4gYS5vcGVuKGIsYywhMCl9LAokaWZKOjF9
+Clcud2EucHJvdG90eXBlPXt9ClcuU2cucHJvdG90eXBlPXskaVNnOjF9ClcudzcucHJvdG90eXBlPXsK
+Z0RyOmZ1bmN0aW9uKGEpe2lmKCJvcmlnaW4iIGluIGEpcmV0dXJuIGEub3JpZ2luCnJldHVybiBILkVq
+KGEucHJvdG9jb2wpKyIvLyIrSC5FaihhLmhvc3QpfSwKdzpmdW5jdGlvbihhKXtyZXR1cm4gU3RyaW5n
+KGEpfSwKJGl3NzoxfQpXLkFqLnByb3RvdHlwZT17JGlBajoxfQpXLmU3LnByb3RvdHlwZT17CmdyODpm
+dW5jdGlvbihhKXt2YXIgcz10aGlzLmEscj1zLmNoaWxkTm9kZXMubGVuZ3RoCmlmKHI9PT0wKXRocm93
+IEguYihQLlBWKCJObyBlbGVtZW50cyIpKQppZihyPjEpdGhyb3cgSC5iKFAuUFYoIk1vcmUgdGhhbiBv
+bmUgZWxlbWVudCIpKQpzPXMuZmlyc3RDaGlsZApzLnRvU3RyaW5nCnJldHVybiBzfSwKRlY6ZnVuY3Rp
+b24oYSxiKXt2YXIgcyxyLHEscCxvCnQuZWguYShiKQppZihiIGluc3RhbmNlb2YgVy5lNyl7cz1iLmEK
+cj10aGlzLmEKaWYocyE9PXIpZm9yKHE9cy5jaGlsZE5vZGVzLmxlbmd0aCxwPTA7cDxxOysrcCl7bz1z
+LmZpcnN0Q2hpbGQKby50b1N0cmluZwpyLmFwcGVuZENoaWxkKG8pfXJldHVybn1mb3Iocz1iLmdtKGIp
+LHI9dGhpcy5hO3MuRigpOylyLmFwcGVuZENoaWxkKHMuZ2woKSl9LApZNTpmdW5jdGlvbihhLGIsYyl7
+dmFyIHMscgp0LkEuYShjKQpzPXRoaXMuYQpyPXMuY2hpbGROb2RlcwppZihiPDB8fGI+PXIubGVuZ3Ro
+KXJldHVybiBILk9IKHIsYikKcy5yZXBsYWNlQ2hpbGQoYyxyW2JdKX0sCmdtOmZ1bmN0aW9uKGEpe3Zh
+ciBzPXRoaXMuYS5jaGlsZE5vZGVzCnJldHVybiBuZXcgVy5XOShzLHMubGVuZ3RoLEgueihzKS5DKCJX
+OTxHbS5FPiIpKX0sCmdBOmZ1bmN0aW9uKGEpe3JldHVybiB0aGlzLmEuY2hpbGROb2Rlcy5sZW5ndGh9
+LApxOmZ1bmN0aW9uKGEsYil7dmFyIHMKSC51UChiKQpzPXRoaXMuYS5jaGlsZE5vZGVzCmlmKGI8MHx8
+Yj49cy5sZW5ndGgpcmV0dXJuIEguT0gocyxiKQpyZXR1cm4gc1tiXX19ClcudUgucHJvdG90eXBlPXsK
+d2c6ZnVuY3Rpb24oYSl7dmFyIHM9YS5wYXJlbnROb2RlCmlmKHMhPW51bGwpcy5yZW1vdmVDaGlsZChh
+KX0sCkQ0OmZ1bmN0aW9uKGEpe3ZhciBzCmZvcig7cz1hLmZpcnN0Q2hpbGQscyE9bnVsbDspYS5yZW1v
+dmVDaGlsZChzKX0sCnc6ZnVuY3Rpb24oYSl7dmFyIHM9YS5ub2RlVmFsdWUKcmV0dXJuIHM9PW51bGw/
+dGhpcy5VKGEpOnN9LApzYTQ6ZnVuY3Rpb24oYSxiKXthLnRleHRDb250ZW50PWJ9LAptSzpmdW5jdGlv
+bihhLGIsYyl7cmV0dXJuIGEuaW5zZXJ0QmVmb3JlKGIsYyl9LAokaXVIOjF9ClcuQkgucHJvdG90eXBl
+PXsKZ0E6ZnVuY3Rpb24oYSl7cmV0dXJuIGEubGVuZ3RofSwKcTpmdW5jdGlvbihhLGIpe0gudVAoYikK
+aWYoYj4+PjAhPT1ifHxiPj1hLmxlbmd0aCl0aHJvdyBILmIoUC5DZihiLGEsbnVsbCxudWxsLG51bGwp
+KQpyZXR1cm4gYVtiXX0sClk1OmZ1bmN0aW9uKGEsYixjKXt0LkEuYShjKQp0aHJvdyBILmIoUC5MNCgi
+Q2Fubm90IGFzc2lnbiBlbGVtZW50IG9mIGltbXV0YWJsZSBMaXN0LiIpKX0sCmd0SDpmdW5jdGlvbihh
+KXtpZihhLmxlbmd0aD4wKXJldHVybiBhWzBdCnRocm93IEguYihQLlBWKCJObyBlbGVtZW50cyIpKX0s
+CkU6ZnVuY3Rpb24oYSxiKXtpZihiPDB8fGI+PWEubGVuZ3RoKXJldHVybiBILk9IKGEsYikKcmV0dXJu
+IGFbYl19LAokaWJROjEsCiRpWGo6MSwKJGljWDoxLAokaXpNOjF9ClcuU04ucHJvdG90eXBlPXt9Clcu
+ZXcucHJvdG90eXBlPXskaWV3OjF9ClcubHAucHJvdG90eXBlPXsKZ0E6ZnVuY3Rpb24oYSl7cmV0dXJu
+IGEubGVuZ3RofX0KVy5UYi5wcm90b3R5cGU9ewpyNjpmdW5jdGlvbihhLGIsYyxkKXt2YXIgcyxyCmlm
+KCJjcmVhdGVDb250ZXh0dWFsRnJhZ21lbnQiIGluIHdpbmRvdy5SYW5nZS5wcm90b3R5cGUpcmV0dXJu
+IHRoaXMuRFcoYSxiLGMsZCkKcz1XLlU5KCI8dGFibGU+IitILkVqKGIpKyI8L3RhYmxlPiIsYyxkKQpy
+PWRvY3VtZW50LmNyZWF0ZURvY3VtZW50RnJhZ21lbnQoKQpyLnRvU3RyaW5nCnMudG9TdHJpbmcKbmV3
+IFcuZTcocikuRlYoMCxuZXcgVy5lNyhzKSkKcmV0dXJuIHJ9fQpXLkl2LnByb3RvdHlwZT17CnI2OmZ1
+bmN0aW9uKGEsYixjLGQpe3ZhciBzLHIscSxwCmlmKCJjcmVhdGVDb250ZXh0dWFsRnJhZ21lbnQiIGlu
+IHdpbmRvdy5SYW5nZS5wcm90b3R5cGUpcmV0dXJuIHRoaXMuRFcoYSxiLGMsZCkKcz1kb2N1bWVudApy
+PXMuY3JlYXRlRG9jdW1lbnRGcmFnbWVudCgpCnM9Qy5JZS5yNihzLmNyZWF0ZUVsZW1lbnQoInRhYmxl
+IiksYixjLGQpCnMudG9TdHJpbmcKcz1uZXcgVy5lNyhzKQpxPXMuZ3I4KHMpCnEudG9TdHJpbmcKcz1u
+ZXcgVy5lNyhxKQpwPXMuZ3I4KHMpCnIudG9TdHJpbmcKcC50b1N0cmluZwpuZXcgVy5lNyhyKS5GVigw
+LG5ldyBXLmU3KHApKQpyZXR1cm4gcn19ClcuV1AucHJvdG90eXBlPXsKcjY6ZnVuY3Rpb24oYSxiLGMs
+ZCl7dmFyIHMscixxCmlmKCJjcmVhdGVDb250ZXh0dWFsRnJhZ21lbnQiIGluIHdpbmRvdy5SYW5nZS5w
+cm90b3R5cGUpcmV0dXJuIHRoaXMuRFcoYSxiLGMsZCkKcz1kb2N1bWVudApyPXMuY3JlYXRlRG9jdW1l
+bnRGcmFnbWVudCgpCnM9Qy5JZS5yNihzLmNyZWF0ZUVsZW1lbnQoInRhYmxlIiksYixjLGQpCnMudG9T
+dHJpbmcKcz1uZXcgVy5lNyhzKQpxPXMuZ3I4KHMpCnIudG9TdHJpbmcKcS50b1N0cmluZwpuZXcgVy5l
+NyhyKS5GVigwLG5ldyBXLmU3KHEpKQpyZXR1cm4gcn19ClcueVkucHJvdG90eXBlPXsKcGs6ZnVuY3Rp
+b24oYSxiLGMpe3ZhciBzLHIKdGhpcy5zYTQoYSxudWxsKQpzPWEuY29udGVudApzLnRvU3RyaW5nCkou
+YlQocykKcj10aGlzLnI2KGEsYixudWxsLGMpCmEuY29udGVudC5hcHBlbmRDaGlsZChyKX0sCllDOmZ1
+bmN0aW9uKGEsYil7cmV0dXJuIHRoaXMucGsoYSxiLG51bGwpfSwKJGl5WToxfQpXLnc2LnByb3RvdHlw
+ZT17fQpXLks1LnByb3RvdHlwZT17ClBvOmZ1bmN0aW9uKGEsYixjKXt2YXIgcz1XLlAxKGEub3Blbihi
+LGMpKQpyZXR1cm4gc30sCmdtVzpmdW5jdGlvbihhKXtyZXR1cm4gYS5sb2NhdGlvbn0sCnVzOmZ1bmN0
+aW9uKGEsYil7cmV0dXJuIGEuY29uZmlybShiKX0sCiRpSzU6MSwKJGl2NjoxfQpXLkNtLnByb3RvdHlw
+ZT17JGlDbToxfQpXLkNRLnByb3RvdHlwZT17JGlDUToxfQpXLnc0LnByb3RvdHlwZT17Cnc6ZnVuY3Rp
+b24oYSl7dmFyIHMscj1hLmxlZnQKci50b1N0cmluZwpyPSJSZWN0YW5nbGUgKCIrSC5FaihyKSsiLCAi
+CnM9YS50b3AKcy50b1N0cmluZwpzPXIrSC5FaihzKSsiKSAiCnI9YS53aWR0aApyLnRvU3RyaW5nCnI9
+cytILkVqKHIpKyIgeCAiCnM9YS5oZWlnaHQKcy50b1N0cmluZwpyZXR1cm4gcitILkVqKHMpfSwKRE46
+ZnVuY3Rpb24oYSxiKXt2YXIgcyxyCmlmKGI9PW51bGwpcmV0dXJuITEKaWYodC5xLmIoYikpe3M9YS5s
+ZWZ0CnMudG9TdHJpbmcKcj1iLmxlZnQKci50b1N0cmluZwppZihzPT09cil7cz1hLnRvcApzLnRvU3Ry
+aW5nCnI9Yi50b3AKci50b1N0cmluZwppZihzPT09cil7cz1hLndpZHRoCnMudG9TdHJpbmcKcj1iLndp
+ZHRoCnIudG9TdHJpbmcKaWYocz09PXIpe3M9YS5oZWlnaHQKcy50b1N0cmluZwpyPWIuaGVpZ2h0CnIu
+dG9TdHJpbmcKcj1zPT09cgpzPXJ9ZWxzZSBzPSExfWVsc2Ugcz0hMX1lbHNlIHM9ITF9ZWxzZSBzPSEx
+CnJldHVybiBzfSwKZ2lPOmZ1bmN0aW9uKGEpe3ZhciBzLHIscSxwPWEubGVmdApwLnRvU3RyaW5nCnA9
+Qy5DRC5naU8ocCkKcz1hLnRvcApzLnRvU3RyaW5nCnM9Qy5DRC5naU8ocykKcj1hLndpZHRoCnIudG9T
+dHJpbmcKcj1DLkNELmdpTyhyKQpxPWEuaGVpZ2h0CnEudG9TdHJpbmcKcmV0dXJuIFcuckUocCxzLHIs
+Qy5DRC5naU8ocSkpfX0KVy5yaC5wcm90b3R5cGU9ewpnQTpmdW5jdGlvbihhKXtyZXR1cm4gYS5sZW5n
+dGh9LApxOmZ1bmN0aW9uKGEsYil7SC51UChiKQppZihiPj4+MCE9PWJ8fGI+PWEubGVuZ3RoKXRocm93
+IEguYihQLkNmKGIsYSxudWxsLG51bGwsbnVsbCkpCnJldHVybiBhW2JdfSwKWTU6ZnVuY3Rpb24oYSxi
+LGMpe3QuQS5hKGMpCnRocm93IEguYihQLkw0KCJDYW5ub3QgYXNzaWduIGVsZW1lbnQgb2YgaW1tdXRh
+YmxlIExpc3QuIikpfSwKRTpmdW5jdGlvbihhLGIpe2lmKGI8MHx8Yj49YS5sZW5ndGgpcmV0dXJuIEgu
+T0goYSxiKQpyZXR1cm4gYVtiXX0sCiRpYlE6MSwKJGlYajoxLAokaWNYOjEsCiRpek06MX0KVy5jZi5w
+cm90b3R5cGU9ewpLOmZ1bmN0aW9uKGEsYil7dmFyIHMscixxLHAsbwp0LmVBLmEoYikKZm9yKHM9dGhp
+cy5ndmMoKSxyPXMubGVuZ3RoLHE9dGhpcy5hLHA9MDtwPHMubGVuZ3RoO3MubGVuZ3RoPT09cnx8KDAs
+SC5saykocyksKytwKXtvPXNbcF0KYi4kMihvLHEuZ2V0QXR0cmlidXRlKG8pKX19LApndmM6ZnVuY3Rp
+b24oKXt2YXIgcyxyLHEscCxvLG4sbT10aGlzLmEuYXR0cmlidXRlcwptLnRvU3RyaW5nCnM9SC5WTShb
+XSx0LnMpCmZvcihyPW0ubGVuZ3RoLHE9dC5oOSxwPTA7cDxyOysrcCl7aWYocD49bS5sZW5ndGgpcmV0
+dXJuIEguT0gobSxwKQpvPXEuYShtW3BdKQppZihvLm5hbWVzcGFjZVVSST09bnVsbCl7bj1vLm5hbWUK
+bi50b1N0cmluZwpDLk5tLmkocyxuKX19cmV0dXJuIHN9LApnbDA6ZnVuY3Rpb24oYSl7cmV0dXJuIHRo
+aXMuZ3ZjKCkubGVuZ3RoPT09MH19ClcuaTcucHJvdG90eXBlPXsKeDQ6ZnVuY3Rpb24oYSl7dmFyIHM9
+SC5vVCh0aGlzLmEuaGFzQXR0cmlidXRlKGEpKQpyZXR1cm4gc30sCnE6ZnVuY3Rpb24oYSxiKXtyZXR1
+cm4gdGhpcy5hLmdldEF0dHJpYnV0ZShILmgoYikpfSwKWTU6ZnVuY3Rpb24oYSxiLGMpe3RoaXMuYS5z
+ZXRBdHRyaWJ1dGUoYixjKX0sCmdBOmZ1bmN0aW9uKGEpe3JldHVybiB0aGlzLmd2YygpLmxlbmd0aH19
+ClcuU3kucHJvdG90eXBlPXsKeDQ6ZnVuY3Rpb24oYSl7dmFyIHM9SC5vVCh0aGlzLmEuYS5oYXNBdHRy
+aWJ1dGUoImRhdGEtIit0aGlzLlAoYSkpKQpyZXR1cm4gc30sCnE6ZnVuY3Rpb24oYSxiKXtyZXR1cm4g
+dGhpcy5hLmEuZ2V0QXR0cmlidXRlKCJkYXRhLSIrdGhpcy5QKEguaChiKSkpfSwKWTU6ZnVuY3Rpb24o
+YSxiLGMpe3RoaXMuYS5hLnNldEF0dHJpYnV0ZSgiZGF0YS0iK3RoaXMuUChiKSxjKX0sCks6ZnVuY3Rp
+b24oYSxiKXt0aGlzLmEuSygwLG5ldyBXLktTKHRoaXMsdC5lQS5hKGIpKSl9LApndmM6ZnVuY3Rpb24o
+KXt2YXIgcz1ILlZNKFtdLHQucykKdGhpcy5hLksoMCxuZXcgVy5BMyh0aGlzLHMpKQpyZXR1cm4gc30s
+CmdBOmZ1bmN0aW9uKGEpe3JldHVybiB0aGlzLmd2YygpLmxlbmd0aH0sCmdsMDpmdW5jdGlvbihhKXty
+ZXR1cm4gdGhpcy5ndmMoKS5sZW5ndGg9PT0wfSwKeHE6ZnVuY3Rpb24oYSl7dmFyIHMscixxPUguVk0o
+YS5zcGxpdCgiLSIpLHQucykKZm9yKHM9MTtzPHEubGVuZ3RoOysrcyl7cj1xW3NdCmlmKHIubGVuZ3Ro
+PjApQy5ObS5ZNShxLHMsclswXS50b1VwcGVyQ2FzZSgpK0ouS1YociwxKSl9cmV0dXJuIEMuTm0uayhx
+LCIiKX0sClA6ZnVuY3Rpb24oYSl7dmFyIHMscixxLHAsbwpmb3Iocz1hLmxlbmd0aCxyPTAscT0iIjty
+PHM7KytyKXtwPWFbcl0Kbz1wLnRvTG93ZXJDYXNlKCkKcT0ocCE9PW8mJnI+MD9xKyItIjpxKStvfXJl
+dHVybiBxLmNoYXJDb2RlQXQoMCk9PTA/cTpxfX0KVy5LUy5wcm90b3R5cGU9ewokMjpmdW5jdGlvbihh
+LGIpe2lmKEouclkoYSkubkMoYSwiZGF0YS0iKSl0aGlzLmIuJDIodGhpcy5hLnhxKEMueEIueW4oYSw1
+KSksYil9LAokUzoxNH0KVy5BMy5wcm90b3R5cGU9ewokMjpmdW5jdGlvbihhLGIpe2lmKEouclkoYSku
+bkMoYSwiZGF0YS0iKSlDLk5tLmkodGhpcy5iLHRoaXMuYS54cShDLnhCLnluKGEsNSkpKX0sCiRTOjE0
+fQpXLkk0LnByb3RvdHlwZT17CkQ6ZnVuY3Rpb24oKXt2YXIgcyxyLHEscCxvPVAuTHModC5OKQpmb3Io
+cz10aGlzLmEuY2xhc3NOYW1lLnNwbGl0KCIgIikscj1zLmxlbmd0aCxxPTA7cTxyOysrcSl7cD1KLlQw
+KHNbcV0pCmlmKHAubGVuZ3RoIT09MClvLmkoMCxwKX1yZXR1cm4gb30sClg6ZnVuY3Rpb24oYSl7dGhp
+cy5hLmNsYXNzTmFtZT10LkMuYShhKS5rKDAsIiAiKX0sCmdBOmZ1bmN0aW9uKGEpe3JldHVybiB0aGlz
+LmEuY2xhc3NMaXN0Lmxlbmd0aH0sCmdsMDpmdW5jdGlvbihhKXtyZXR1cm4gdGhpcy5hLmNsYXNzTGlz
+dC5sZW5ndGg9PT0wfSwKZ29yOmZ1bmN0aW9uKGEpe3JldHVybiB0aGlzLmEuY2xhc3NMaXN0Lmxlbmd0
+aCE9PTB9LApWMTpmdW5jdGlvbihhKXt0aGlzLmEuY2xhc3NOYW1lPSIifSwKdGc6ZnVuY3Rpb24oYSxi
+KXt2YXIgcz10aGlzLmEuY2xhc3NMaXN0LmNvbnRhaW5zKGIpCnJldHVybiBzfSwKaTpmdW5jdGlvbihh
+LGIpe3ZhciBzLHIKSC5oKGIpCnM9dGhpcy5hLmNsYXNzTGlzdApyPXMuY29udGFpbnMoYikKcy5hZGQo
+YikKcmV0dXJuIXJ9LApMOmZ1bmN0aW9uKGEsYil7dmFyIHMscixxCmlmKHR5cGVvZiBiPT0ic3RyaW5n
+Iil7cz10aGlzLmEuY2xhc3NMaXN0CnI9cy5jb250YWlucyhiKQpzLnJlbW92ZShiKQpxPXJ9ZWxzZSBx
+PSExCnJldHVybiBxfSwKRlY6ZnVuY3Rpb24oYSxiKXtXLlROKHRoaXMuYSx0LlEuYShiKSl9fQpXLkZr
+LnByb3RvdHlwZT17fQpXLlJPLnByb3RvdHlwZT17fQpXLmV1LnByb3RvdHlwZT17fQpXLnhDLnByb3Rv
+dHlwZT17fQpXLnZOLnByb3RvdHlwZT17CiQxOmZ1bmN0aW9uKGEpe3JldHVybiB0aGlzLmEuJDEodC5C
+LmEoYSkpfSwKJFM6Mjd9ClcuSlEucHJvdG90eXBlPXsKQ1k6ZnVuY3Rpb24oYSl7dmFyIHMKaWYoJC5v
+ci5hPT09MCl7Zm9yKHM9MDtzPDI2MjsrK3MpJC5vci5ZNSgwLEMuY21bc10sVy5wUygpKQpmb3Iocz0w
+O3M8MTI7KytzKSQub3IuWTUoMCxDLkJJW3NdLFcuVjQoKSl9fSwKaTA6ZnVuY3Rpb24oYSl7cmV0dXJu
+ICQuQU4oKS50ZygwLFcuclMoYSkpfSwKRWI6ZnVuY3Rpb24oYSxiLGMpe3ZhciBzPSQub3IucSgwLEgu
+RWooVy5yUyhhKSkrIjo6IitiKQppZihzPT1udWxsKXM9JC5vci5xKDAsIio6OiIrYikKaWYocz09bnVs
+bClyZXR1cm4hMQpyZXR1cm4gSC55OChzLiQ0KGEsYixjLHRoaXMpKX0sCiRpa0Y6MX0KVy5HbS5wcm90
+b3R5cGU9ewpnbTpmdW5jdGlvbihhKXtyZXR1cm4gbmV3IFcuVzkoYSx0aGlzLmdBKGEpLEgueihhKS5D
+KCJXOTxHbS5FPiIpKX19ClcudkQucHJvdG90eXBlPXsKaTA6ZnVuY3Rpb24oYSl7cmV0dXJuIEMuTm0u
+VnIodGhpcy5hLG5ldyBXLlV2KGEpKX0sCkViOmZ1bmN0aW9uKGEsYixjKXtyZXR1cm4gQy5ObS5Wcih0
+aGlzLmEsbmV3IFcuRWcoYSxiLGMpKX0sCiRpa0Y6MX0KVy5Vdi5wcm90b3R5cGU9ewokMTpmdW5jdGlv
+bihhKXtyZXR1cm4gdC5mNi5hKGEpLmkwKHRoaXMuYSl9LAokUzoxNX0KVy5FZy5wcm90b3R5cGU9ewok
+MTpmdW5jdGlvbihhKXtyZXR1cm4gdC5mNi5hKGEpLkViKHRoaXMuYSx0aGlzLmIsdGhpcy5jKX0sCiRT
+OjE1fQpXLm02LnByb3RvdHlwZT17CkNZOmZ1bmN0aW9uKGEsYixjLGQpe3ZhciBzLHIscQp0aGlzLmEu
+RlYoMCxjKQpzPWIuZXYoMCxuZXcgVy5FbygpKQpyPWIuZXYoMCxuZXcgVy5XaygpKQp0aGlzLmIuRlYo
+MCxzKQpxPXRoaXMuYwpxLkZWKDAsQy54RCkKcS5GVigwLHIpfSwKaTA6ZnVuY3Rpb24oYSl7cmV0dXJu
+IHRoaXMuYS50ZygwLFcuclMoYSkpfSwKRWI6ZnVuY3Rpb24oYSxiLGMpe3ZhciBzPXRoaXMscj1XLnJT
+KGEpLHE9cy5jCmlmKHEudGcoMCxILkVqKHIpKyI6OiIrYikpcmV0dXJuIHMuZC5EdChjKQplbHNlIGlm
+KHEudGcoMCwiKjo6IitiKSlyZXR1cm4gcy5kLkR0KGMpCmVsc2V7cT1zLmIKaWYocS50ZygwLEguRWoo
+cikrIjo6IitiKSlyZXR1cm4hMAplbHNlIGlmKHEudGcoMCwiKjo6IitiKSlyZXR1cm4hMAplbHNlIGlm
+KHEudGcoMCxILkVqKHIpKyI6OioiKSlyZXR1cm4hMAplbHNlIGlmKHEudGcoMCwiKjo6KiIpKXJldHVy
+biEwfXJldHVybiExfSwKJGlrRjoxfQpXLkVvLnByb3RvdHlwZT17CiQxOmZ1bmN0aW9uKGEpe3JldHVy
+biFDLk5tLnRnKEMuQkksSC5oKGEpKX0sCiRTOjZ9ClcuV2sucHJvdG90eXBlPXsKJDE6ZnVuY3Rpb24o
+YSl7cmV0dXJuIEMuTm0udGcoQy5CSSxILmgoYSkpfSwKJFM6Nn0KVy5jdC5wcm90b3R5cGU9ewpFYjpm
+dW5jdGlvbihhLGIsYyl7aWYodGhpcy5qRihhLGIsYykpcmV0dXJuITAKaWYoYj09PSJ0ZW1wbGF0ZSIm
+JmM9PT0iIilyZXR1cm4hMAppZihhLmdldEF0dHJpYnV0ZSgidGVtcGxhdGUiKT09PSIiKXJldHVybiB0
+aGlzLmUudGcoMCxiKQpyZXR1cm4hMX19ClcuSUEucHJvdG90eXBlPXsKJDE6ZnVuY3Rpb24oYSl7cmV0
+dXJuIlRFTVBMQVRFOjoiK0guRWooSC5oKGEpKX0sCiRTOjV9ClcuT3cucHJvdG90eXBlPXsKaTA6ZnVu
+Y3Rpb24oYSl7dmFyIHMKaWYodC5ldy5iKGEpKXJldHVybiExCnM9dC5nNy5iKGEpCmlmKHMmJlcuclMo
+YSk9PT0iZm9yZWlnbk9iamVjdCIpcmV0dXJuITEKaWYocylyZXR1cm4hMApyZXR1cm4hMX0sCkViOmZ1
+bmN0aW9uKGEsYixjKXtpZihiPT09ImlzInx8Qy54Qi5uQyhiLCJvbiIpKXJldHVybiExCnJldHVybiB0
+aGlzLmkwKGEpfSwKJGlrRjoxfQpXLlc5LnByb3RvdHlwZT17CkY6ZnVuY3Rpb24oKXt2YXIgcz10aGlz
+LHI9cy5jKzEscT1zLmIKaWYocjxxKXtzLnNwKEoueDkocy5hLHIpKQpzLmM9cgpyZXR1cm4hMH1zLnNw
+KG51bGwpCnMuYz1xCnJldHVybiExfSwKZ2w6ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5kfSwKc3A6ZnVu
+Y3Rpb24oYSl7dGhpcy5kPXRoaXMuJHRpLkMoIjE/IikuYShhKX0sCiRpQW46MX0KVy5kVy5wcm90b3R5
+cGU9eyRpRDA6MSwkaXY2OjF9ClcubWsucHJvdG90eXBlPXskaXkwOjF9ClcuS28ucHJvdG90eXBlPXsK
+UG46ZnVuY3Rpb24oYSl7dmFyIHM9dGhpcyxyPW5ldyBXLmZtKHMpCnMuYj0hMQpyLiQyKGEsbnVsbCkK
+Zm9yKDtzLmI7KXtzLmI9ITEKci4kMihhLG51bGwpfX0sCkVQOmZ1bmN0aW9uKGEsYil7dmFyIHM9dGhp
+cy5iPSEwCmlmKGIhPW51bGw/YiE9PWEucGFyZW50Tm9kZTpzKUouTHQoYSkKZWxzZSBiLnJlbW92ZUNo
+aWxkKGEpfSwKSTQ6ZnVuY3Rpb24oYSxiKXt2YXIgcyxyLHEscCxvLG49ITAsbT1udWxsLGw9bnVsbAp0
+cnl7bT1KLmlnKGEpCmw9bS5hLmdldEF0dHJpYnV0ZSgiaXMiKQp0LmguYShhKQpzPWZ1bmN0aW9uKGMp
+e2lmKCEoYy5hdHRyaWJ1dGVzIGluc3RhbmNlb2YgTmFtZWROb2RlTWFwKSlyZXR1cm4gdHJ1ZQppZihj
+LmlkPT0nbGFzdENoaWxkJ3x8Yy5uYW1lPT0nbGFzdENoaWxkJ3x8Yy5pZD09J3ByZXZpb3VzU2libGlu
+Zyd8fGMubmFtZT09J3ByZXZpb3VzU2libGluZyd8fGMuaWQ9PSdjaGlsZHJlbid8fGMubmFtZT09J2No
+aWxkcmVuJylyZXR1cm4gdHJ1ZQp2YXIgaz1jLmNoaWxkTm9kZXMKaWYoYy5sYXN0Q2hpbGQmJmMubGFz
+dENoaWxkIT09a1trLmxlbmd0aC0xXSlyZXR1cm4gdHJ1ZQppZihjLmNoaWxkcmVuKWlmKCEoYy5jaGls
+ZHJlbiBpbnN0YW5jZW9mIEhUTUxDb2xsZWN0aW9ufHxjLmNoaWxkcmVuIGluc3RhbmNlb2YgTm9kZUxp
+c3QpKXJldHVybiB0cnVlCnZhciBqPTAKaWYoYy5jaGlsZHJlbilqPWMuY2hpbGRyZW4ubGVuZ3RoCmZv
+cih2YXIgaT0wO2k8ajtpKyspe3ZhciBoPWMuY2hpbGRyZW5baV0KaWYoaC5pZD09J2F0dHJpYnV0ZXMn
+fHxoLm5hbWU9PSdhdHRyaWJ1dGVzJ3x8aC5pZD09J2xhc3RDaGlsZCd8fGgubmFtZT09J2xhc3RDaGls
+ZCd8fGguaWQ9PSdwcmV2aW91c1NpYmxpbmcnfHxoLm5hbWU9PSdwcmV2aW91c1NpYmxpbmcnfHxoLmlk
+PT0nY2hpbGRyZW4nfHxoLm5hbWU9PSdjaGlsZHJlbicpcmV0dXJuIHRydWV9cmV0dXJuIGZhbHNlfShh
+KQpuPUgub1Qocyk/ITA6IShhLmF0dHJpYnV0ZXMgaW5zdGFuY2VvZiBOYW1lZE5vZGVNYXApfWNhdGNo
+KHApe0guUnUocCl9cj0iZWxlbWVudCB1bnByaW50YWJsZSIKdHJ5e3I9Si5qKGEpfWNhdGNoKHApe0gu
+UnUocCl9dHJ5e3E9Vy5yUyhhKQp0aGlzLmtSKHQuaC5hKGEpLGIsbixyLHEsdC5mLmEobSksSC5rKGwp
+KX1jYXRjaChwKXtpZihILlJ1KHApIGluc3RhbmNlb2YgUC51KXRocm93IHAKZWxzZXt0aGlzLkVQKGEs
+YikKd2luZG93Cm89IlJlbW92aW5nIGNvcnJ1cHRlZCBlbGVtZW50ICIrSC5FaihyKQppZih0eXBlb2Yg
+Y29uc29sZSE9InVuZGVmaW5lZCIpd2luZG93LmNvbnNvbGUud2FybihvKX19fSwKa1I6ZnVuY3Rpb24o
+YSxiLGMsZCxlLGYsZyl7dmFyIHMscixxLHAsbyxuLG09dGhpcwppZihjKXttLkVQKGEsYikKd2luZG93
+CnM9IlJlbW92aW5nIGVsZW1lbnQgZHVlIHRvIGNvcnJ1cHRlZCBhdHRyaWJ1dGVzIG9uIDwiK2QrIj4i
+CmlmKHR5cGVvZiBjb25zb2xlIT0idW5kZWZpbmVkIil3aW5kb3cuY29uc29sZS53YXJuKHMpCnJldHVy
+bn1pZighbS5hLmkwKGEpKXttLkVQKGEsYikKd2luZG93CnM9IlJlbW92aW5nIGRpc2FsbG93ZWQgZWxl
+bWVudCA8IitILkVqKGUpKyI+IGZyb20gIitILkVqKGIpCmlmKHR5cGVvZiBjb25zb2xlIT0idW5kZWZp
+bmVkIil3aW5kb3cuY29uc29sZS53YXJuKHMpCnJldHVybn1pZihnIT1udWxsKWlmKCFtLmEuRWIoYSwi
+aXMiLGcpKXttLkVQKGEsYikKd2luZG93CnM9IlJlbW92aW5nIGRpc2FsbG93ZWQgdHlwZSBleHRlbnNp
+b24gPCIrSC5FaihlKSsnIGlzPSInK2crJyI+JwppZih0eXBlb2YgY29uc29sZSE9InVuZGVmaW5lZCIp
+d2luZG93LmNvbnNvbGUud2FybihzKQpyZXR1cm59cz1mLmd2YygpCnI9SC5WTShzLnNsaWNlKDApLEgu
+dDYocykpCmZvcihxPWYuZ3ZjKCkubGVuZ3RoLTEscz1mLmE7cT49MDstLXEpe2lmKHE+PXIubGVuZ3Ro
+KXJldHVybiBILk9IKHIscSkKcD1yW3FdCm89bS5hCm49Si5jSChwKQpILmgocCkKaWYoIW8uRWIoYSxu
+LHMuZ2V0QXR0cmlidXRlKHApKSl7d2luZG93Cm89IlJlbW92aW5nIGRpc2FsbG93ZWQgYXR0cmlidXRl
+IDwiK0guRWooZSkrIiAiK3ArJz0iJytILkVqKHMuZ2V0QXR0cmlidXRlKHApKSsnIj4nCmlmKHR5cGVv
+ZiBjb25zb2xlIT0idW5kZWZpbmVkIil3aW5kb3cuY29uc29sZS53YXJuKG8pCnMucmVtb3ZlQXR0cmli
+dXRlKHApfX1pZih0LmFXLmIoYSkpe3M9YS5jb250ZW50CnMudG9TdHJpbmcKbS5QbihzKX19LAokaW9u
+OjF9ClcuZm0ucHJvdG90eXBlPXsKJDI6ZnVuY3Rpb24oYSxiKXt2YXIgcyxyLHEscCxvLG4sbT10aGlz
+LmEKc3dpdGNoKGEubm9kZVR5cGUpe2Nhc2UgMTptLkk0KGEsYikKYnJlYWsKY2FzZSA4OmNhc2UgMTE6
+Y2FzZSAzOmNhc2UgNDpicmVhawpkZWZhdWx0Om0uRVAoYSxiKX1zPWEubGFzdENoaWxkCmZvcihxPXQu
+QTtudWxsIT1zOyl7cj1udWxsCnRyeXtyPXMucHJldmlvdXNTaWJsaW5nCmlmKHIhPW51bGwpe3A9ci5u
+ZXh0U2libGluZwpvPXMKbz1wPT1udWxsP28hPW51bGw6cCE9PW8KcD1vfWVsc2UgcD0hMQppZihwKXtw
+PVAuUFYoIkNvcnJ1cHQgSFRNTCIpCnRocm93IEguYihwKX19Y2F0Y2gobil7SC5SdShuKQpwPXEuYShz
+KQptLmI9ITAKbz1wLnBhcmVudE5vZGUKbz1hPT1udWxsP28hPW51bGw6YSE9PW8KaWYobyl7bz1wLnBh
+cmVudE5vZGUKaWYobyE9bnVsbClvLnJlbW92ZUNoaWxkKHApfWVsc2UgYS5yZW1vdmVDaGlsZChwKQpz
+PW51bGwKcj1hLmxhc3RDaGlsZH1pZihzIT1udWxsKXRoaXMuJDIocyxhKQpzPXJ9fSwKJFM6MzB9Clcu
+TGUucHJvdG90eXBlPXt9ClcuSzcucHJvdG90eXBlPXt9ClcuckIucHJvdG90eXBlPXt9ClcuWFcucHJv
+dG90eXBlPXt9Clcub2EucHJvdG90eXBlPXt9ClAuaUoucHJvdG90eXBlPXsKVkg6ZnVuY3Rpb24oYSl7
+dmFyIHMscj10aGlzLmEscT1yLmxlbmd0aApmb3Iocz0wO3M8cTsrK3MpaWYocltzXT09PWEpcmV0dXJu
+IHMKQy5ObS5pKHIsYSkKQy5ObS5pKHRoaXMuYixudWxsKQpyZXR1cm4gcX0sClB2OmZ1bmN0aW9uKGEp
+e3ZhciBzLHIscSxwPXRoaXMsbz17fQppZihhPT1udWxsKXJldHVybiBhCmlmKEgubChhKSlyZXR1cm4g
+YQppZih0eXBlb2YgYT09Im51bWJlciIpcmV0dXJuIGEKaWYodHlwZW9mIGE9PSJzdHJpbmciKXJldHVy
+biBhCmlmKGEgaW5zdGFuY2VvZiBQLmlQKXJldHVybiBuZXcgRGF0ZShhLmEpCmlmKHQuZnYuYihhKSl0
+aHJvdyBILmIoUC5TWSgic3RydWN0dXJlZCBjbG9uZSBvZiBSZWdFeHAiKSkKaWYodC5jOC5iKGEpKXJl
+dHVybiBhCmlmKHQudy5iKGEpKXJldHVybiBhCmlmKHQuSS5iKGEpKXJldHVybiBhCnM9dC5kRS5iKGEp
+fHwhMQppZihzKXJldHVybiBhCmlmKHQuZi5iKGEpKXtyPXAuVkgoYSkKcz1wLmIKaWYocj49cy5sZW5n
+dGgpcmV0dXJuIEguT0gocyxyKQpxPW8uYT1zW3JdCmlmKHEhPW51bGwpcmV0dXJuIHEKcT17fQpvLmE9
+cQpDLk5tLlk1KHMscixxKQphLksoMCxuZXcgUC5qZyhvLHApKQpyZXR1cm4gby5hfWlmKHQuai5iKGEp
+KXtyPXAuVkgoYSkKbz1wLmIKaWYocj49by5sZW5ndGgpcmV0dXJuIEguT0gobyxyKQpxPW9bcl0KaWYo
+cSE9bnVsbClyZXR1cm4gcQpyZXR1cm4gcC5layhhLHIpfWlmKHQuZUguYihhKSl7cj1wLlZIKGEpCnM9
+cC5iCmlmKHI+PXMubGVuZ3RoKXJldHVybiBILk9IKHMscikKcT1vLmI9c1tyXQppZihxIT1udWxsKXJl
+dHVybiBxCnE9e30Kby5iPXEKQy5ObS5ZNShzLHIscSkKcC5pbShhLG5ldyBQLlRhKG8scCkpCnJldHVy
 biBvLmJ9dGhyb3cgSC5iKFAuU1koInN0cnVjdHVyZWQgY2xvbmUgb2Ygb3RoZXIgdHlwZSIpKX0sCmVr
 OmZ1bmN0aW9uKGEsYil7dmFyIHMscj1KLlU2KGEpLHE9ci5nQShhKSxwPW5ldyBBcnJheShxKQpDLk5t
-LlkodGhpcy5iLGIscCkKZm9yKHM9MDtzPHE7KytzKUMuTm0uWShwLHMsdGhpcy5QdihyLnEoYSxzKSkp
-CnJldHVybiBwfX0KUC5qZy5wcm90b3R5cGU9ewokMjpmdW5jdGlvbihhLGIpe3RoaXMuYS5hW2FdPXRo
-aXMuYi5QdihiKX0sCiRTOjMxfQpQLlRhLnByb3RvdHlwZT17CiQyOmZ1bmN0aW9uKGEsYil7dGhpcy5h
-LmJbYV09dGhpcy5iLlB2KGIpfSwKJFM6MTZ9ClAuQmYucHJvdG90eXBlPXsKaW06ZnVuY3Rpb24oYSxi
-KXt2YXIgcyxyLHEscAp0LmI4LmEoYikKZm9yKHM9T2JqZWN0LmtleXMoYSkscj1zLmxlbmd0aCxxPTA7
-cTxyOysrcSl7cD1zW3FdCmIuJDIocCxhW3BdKX19fQpQLkFzLnByb3RvdHlwZT17ClQ6ZnVuY3Rpb24o
-YSl7dmFyIHMKSC5oKGEpCnM9JC5oRygpLmIKaWYodHlwZW9mIGEhPSJzdHJpbmciKUgudihILnRMKGEp
-KQppZihzLnRlc3QoYSkpcmV0dXJuIGEKdGhyb3cgSC5iKFAuTDMoYSwidmFsdWUiLCJOb3QgYSB2YWxp
-ZCBjbGFzcyB0b2tlbiIpKX0sCnc6ZnVuY3Rpb24oYSl7cmV0dXJuIHRoaXMuUCgpLkgoMCwiICIpfSwK
-Z206ZnVuY3Rpb24oYSl7dmFyIHM9dGhpcy5QKCkKcmV0dXJuIFAucmoocyxzLnIsSC5MaChzKS5jKX0s
-CmdsMDpmdW5jdGlvbihhKXtyZXR1cm4gdGhpcy5QKCkuYT09PTB9LApnb3I6ZnVuY3Rpb24oYSl7cmV0
-dXJuIHRoaXMuUCgpLmEhPT0wfSwKZ0E6ZnVuY3Rpb24oYSl7cmV0dXJuIHRoaXMuUCgpLmF9LAp0Zzpm
-dW5jdGlvbihhLGIpe3RoaXMuVChiKQpyZXR1cm4gdGhpcy5QKCkudGcoMCxiKX0sCmk6ZnVuY3Rpb24o
-YSxiKXt2YXIgcwpILmgoYikKdGhpcy5UKGIpCnM9dGhpcy5PUyhuZXcgUC5HRShiKSkKcmV0dXJuIEgu
-eTgocz09bnVsbD8hMTpzKX0sClI6ZnVuY3Rpb24oYSxiKXt2YXIgcyxyCmlmKHR5cGVvZiBiIT0ic3Ry
-aW5nIilyZXR1cm4hMQp0aGlzLlQoYikKcz10aGlzLlAoKQpyPXMuUigwLGIpCnRoaXMuWChzKQpyZXR1
-cm4gcn0sCkZWOmZ1bmN0aW9uKGEsYil7dGhpcy5PUyhuZXcgUC5ONyh0aGlzLHQuUS5hKGIpKSl9LApl
-UjpmdW5jdGlvbihhLGIpe3ZhciBzPXRoaXMuUCgpCnJldHVybiBILmJLKHMsYixILkxoKHMpLkMoImxm
-LkUiKSl9LApFOmZ1bmN0aW9uKGEsYil7cmV0dXJuIHRoaXMuUCgpLkUoMCxiKX0sClYxOmZ1bmN0aW9u
-KGEpe3RoaXMuT1MobmV3IFAudVEoKSl9LApPUzpmdW5jdGlvbihhKXt2YXIgcyxyCnQuYlUuYShhKQpz
-PXRoaXMuUCgpCnI9YS4kMShzKQp0aGlzLlgocykKcmV0dXJuIHJ9fQpQLkdFLnByb3RvdHlwZT17CiQx
-OmZ1bmN0aW9uKGEpe3JldHVybiB0LkMuYShhKS5pKDAsdGhpcy5hKX0sCiRTOjMzfQpQLk43LnByb3Rv
-dHlwZT17CiQxOmZ1bmN0aW9uKGEpe3ZhciBzPXRoaXMuYixyPUgudDYocykKcmV0dXJuIHQuQy5hKGEp
-LkZWKDAsbmV3IEgubEoocyxyLkMoInFVKDEpIikuYSh0aGlzLmEuZ3VNKCkpLHIuQygibEo8MSxxVT4i
-KSkpfSwKJFM6MTd9ClAudVEucHJvdG90eXBlPXsKJDE6ZnVuY3Rpb24oYSl7dC5DLmEoYSkKaWYoYS5h
-PjApe2EuYj1hLmM9YS5kPWEuZT1hLmY9bnVsbAphLmE9MAphLlMoKX1yZXR1cm4gbnVsbH0sCiRTOjE3
-fQpQLmhGLnByb3RvdHlwZT17JGloRjoxfQpQLlBDLnByb3RvdHlwZT17CiQxOmZ1bmN0aW9uKGEpe3Zh
-ciBzCnQuWS5hKGEpCnM9ZnVuY3Rpb24oYixjLGQpe3JldHVybiBmdW5jdGlvbigpe3JldHVybiBiKGMs
-ZCx0aGlzLEFycmF5LnByb3RvdHlwZS5zbGljZS5hcHBseShhcmd1bWVudHMpKX19KFAuUjQsYSwhMSkK
-UC5EbShzLCQudygpLGEpCnJldHVybiBzfSwKJFM6NH0KUC5tdC5wcm90b3R5cGU9ewokMTpmdW5jdGlv
-bihhKXtyZXR1cm4gbmV3IHRoaXMuYShhKX0sCiRTOjR9ClAuTnoucHJvdG90eXBlPXsKJDE6ZnVuY3Rp
-b24oYSl7cmV0dXJuIG5ldyBQLnI3KGEpfSwKJFM6MzV9ClAuUVMucHJvdG90eXBlPXsKJDE6ZnVuY3Rp
-b24oYSl7cmV0dXJuIG5ldyBQLlR6KGEsdC5hbSl9LAokUzo1NH0KUC5ucC5wcm90b3R5cGU9ewokMTpm
-dW5jdGlvbihhKXtyZXR1cm4gbmV3IFAuRTQoYSl9LAokUzozN30KUC5FNC5wcm90b3R5cGU9ewpxOmZ1
-bmN0aW9uKGEsYil7aWYodHlwZW9mIGIhPSJzdHJpbmciJiZ0eXBlb2YgYiE9Im51bWJlciIpdGhyb3cg
-SC5iKFAueFkoInByb3BlcnR5IGlzIG5vdCBhIFN0cmluZyBvciBudW0iKSkKcmV0dXJuIFAuZFUodGhp
-cy5hW2JdKX0sClk6ZnVuY3Rpb24oYSxiLGMpe2lmKHR5cGVvZiBiIT0ic3RyaW5nIiYmdHlwZW9mIGIh
+Llk1KHRoaXMuYixiLHApCmZvcihzPTA7czxxOysrcylDLk5tLlk1KHAscyx0aGlzLlB2KHIucShhLHMp
+KSkKcmV0dXJuIHB9fQpQLmpnLnByb3RvdHlwZT17CiQyOmZ1bmN0aW9uKGEsYil7dGhpcy5hLmFbYV09
+dGhpcy5iLlB2KGIpfSwKJFM6MzF9ClAuVGEucHJvdG90eXBlPXsKJDI6ZnVuY3Rpb24oYSxiKXt0aGlz
+LmEuYlthXT10aGlzLmIuUHYoYil9LAokUzoxNn0KUC5CZi5wcm90b3R5cGU9ewppbTpmdW5jdGlvbihh
+LGIpe3ZhciBzLHIscSxwCnQuYjguYShiKQpmb3Iocz1PYmplY3Qua2V5cyhhKSxyPXMubGVuZ3RoLHE9
+MDtxPHI7KytxKXtwPXNbcV0KYi4kMihwLGFbcF0pfX19ClAuQXMucHJvdG90eXBlPXsKVjpmdW5jdGlv
+bihhKXt2YXIgcwpILmgoYSkKcz0kLmhHKCkuYgppZih0eXBlb2YgYSE9InN0cmluZyIpSC52KEgudEwo
+YSkpCmlmKHMudGVzdChhKSlyZXR1cm4gYQp0aHJvdyBILmIoUC5MMyhhLCJ2YWx1ZSIsIk5vdCBhIHZh
+bGlkIGNsYXNzIHRva2VuIikpfSwKdzpmdW5jdGlvbihhKXtyZXR1cm4gdGhpcy5EKCkuaygwLCIgIil9
+LApnbTpmdW5jdGlvbihhKXt2YXIgcz10aGlzLkQoKQpyZXR1cm4gUC5yaihzLHMucixILkxoKHMpLmMp
+fSwKZ2wwOmZ1bmN0aW9uKGEpe3JldHVybiB0aGlzLkQoKS5hPT09MH0sCmdvcjpmdW5jdGlvbihhKXty
+ZXR1cm4gdGhpcy5EKCkuYSE9PTB9LApnQTpmdW5jdGlvbihhKXtyZXR1cm4gdGhpcy5EKCkuYX0sCnRn
+OmZ1bmN0aW9uKGEsYil7dGhpcy5WKGIpCnJldHVybiB0aGlzLkQoKS50ZygwLGIpfSwKaTpmdW5jdGlv
+bihhLGIpe3ZhciBzCkguaChiKQp0aGlzLlYoYikKcz10aGlzLk8obmV3IFAuR0UoYikpCnJldHVybiBI
+Lnk4KHM9PW51bGw/ITE6cyl9LApMOmZ1bmN0aW9uKGEsYil7dmFyIHMscgppZih0eXBlb2YgYiE9InN0
+cmluZyIpcmV0dXJuITEKdGhpcy5WKGIpCnM9dGhpcy5EKCkKcj1zLkwoMCxiKQp0aGlzLlgocykKcmV0
+dXJuIHJ9LApGVjpmdW5jdGlvbihhLGIpe3RoaXMuTyhuZXcgUC5ONyh0aGlzLHQuUS5hKGIpKSl9LApl
+UjpmdW5jdGlvbihhLGIpe3ZhciBzPXRoaXMuRCgpCnJldHVybiBILmJLKHMsYixILkxoKHMpLkMoImxm
+LkUiKSl9LApFOmZ1bmN0aW9uKGEsYil7cmV0dXJuIHRoaXMuRCgpLkUoMCxiKX0sClYxOmZ1bmN0aW9u
+KGEpe3RoaXMuTyhuZXcgUC51USgpKX0sCk86ZnVuY3Rpb24oYSl7dmFyIHMscgp0LmJVLmEoYSkKcz10
+aGlzLkQoKQpyPWEuJDEocykKdGhpcy5YKHMpCnJldHVybiByfX0KUC5HRS5wcm90b3R5cGU9ewokMTpm
+dW5jdGlvbihhKXtyZXR1cm4gdC5DLmEoYSkuaSgwLHRoaXMuYSl9LAokUzozM30KUC5ONy5wcm90b3R5
+cGU9ewokMTpmdW5jdGlvbihhKXt2YXIgcz10aGlzLmIscj1ILnQ2KHMpCnJldHVybiB0LkMuYShhKS5G
+VigwLG5ldyBILmxKKHMsci5DKCJxVSgxKSIpLmEodGhpcy5hLmd1TSgpKSxyLkMoImxKPDEscVU+Iikp
+KX0sCiRTOjE3fQpQLnVRLnByb3RvdHlwZT17CiQxOmZ1bmN0aW9uKGEpe3QuQy5hKGEpCmlmKGEuYT4w
+KXthLmI9YS5jPWEuZD1hLmU9YS5mPW51bGwKYS5hPTAKYS5HWSgpfXJldHVybiBudWxsfSwKJFM6MTd9
+ClAuaEYucHJvdG90eXBlPXskaWhGOjF9ClAuUEMucHJvdG90eXBlPXsKJDE6ZnVuY3Rpb24oYSl7dmFy
+IHMKdC5ZLmEoYSkKcz1mdW5jdGlvbihiLGMsZCl7cmV0dXJuIGZ1bmN0aW9uKCl7cmV0dXJuIGIoYyxk
+LHRoaXMsQXJyYXkucHJvdG90eXBlLnNsaWNlLmFwcGx5KGFyZ3VtZW50cykpfX0oUC5SNCxhLCExKQpQ
+LkRtKHMsJC53KCksYSkKcmV0dXJuIHN9LAokUzo0fQpQLm10LnByb3RvdHlwZT17CiQxOmZ1bmN0aW9u
+KGEpe3JldHVybiBuZXcgdGhpcy5hKGEpfSwKJFM6NH0KUC5Oei5wcm90b3R5cGU9ewokMTpmdW5jdGlv
+bihhKXtyZXR1cm4gbmV3IFAucjcoYSl9LAokUzozNX0KUC5RUy5wcm90b3R5cGU9ewokMTpmdW5jdGlv
+bihhKXtyZXR1cm4gbmV3IFAuVHooYSx0LmFtKX0sCiRTOjU0fQpQLm5wLnByb3RvdHlwZT17CiQxOmZ1
+bmN0aW9uKGEpe3JldHVybiBuZXcgUC5FNChhKX0sCiRTOjM3fQpQLkU0LnByb3RvdHlwZT17CnE6ZnVu
+Y3Rpb24oYSxiKXtpZih0eXBlb2YgYiE9InN0cmluZyImJnR5cGVvZiBiIT0ibnVtYmVyIil0aHJvdyBI
+LmIoUC54WSgicHJvcGVydHkgaXMgbm90IGEgU3RyaW5nIG9yIG51bSIpKQpyZXR1cm4gUC5kVSh0aGlz
+LmFbYl0pfSwKWTU6ZnVuY3Rpb24oYSxiLGMpe2lmKHR5cGVvZiBiIT0ic3RyaW5nIiYmdHlwZW9mIGIh
 PSJudW1iZXIiKXRocm93IEguYihQLnhZKCJwcm9wZXJ0eSBpcyBub3QgYSBTdHJpbmcgb3IgbnVtIikp
 CnRoaXMuYVtiXT1QLndZKGMpfSwKRE46ZnVuY3Rpb24oYSxiKXtpZihiPT1udWxsKXJldHVybiExCnJl
 dHVybiBiIGluc3RhbmNlb2YgUC5FNCYmdGhpcy5hPT09Yi5hfSwKdzpmdW5jdGlvbihhKXt2YXIgcyxy
@@ -10757,975 +10793,990 @@
 Y3Rpb24oYSl7cmV0dXJuIDB9fQpQLnI3LnByb3RvdHlwZT17fQpQLlR6LnByb3RvdHlwZT17CmNQOmZ1
 bmN0aW9uKGEpe3ZhciBzPXRoaXMscj1hPDB8fGE+PXMuZ0EocykKaWYocil0aHJvdyBILmIoUC5URShh
 LDAscy5nQShzKSxudWxsLG51bGwpKX0sCnE6ZnVuY3Rpb24oYSxiKXtpZihILm9rKGIpKXRoaXMuY1Ao
-YikKcmV0dXJuIHRoaXMuJHRpLmMuYSh0aGlzLlVyKDAsYikpfSwKWTpmdW5jdGlvbihhLGIsYyl7dGhp
-cy5jUChiKQp0aGlzLmU0KDAsYixjKX0sCmdBOmZ1bmN0aW9uKGEpe3ZhciBzPXRoaXMuYS5sZW5ndGgK
-aWYodHlwZW9mIHM9PT0ibnVtYmVyIiYmcz4+PjA9PT1zKXJldHVybiBzCnRocm93IEguYihQLlBWKCJC
-YWQgSnNBcnJheSBsZW5ndGgiKSl9LAokaWJROjEsCiRpY1g6MSwKJGl6TToxfQpQLmNvLnByb3RvdHlw
-ZT17fQpQLm5kLnByb3RvdHlwZT17JGluZDoxfQpQLktlLnByb3RvdHlwZT17ClA6ZnVuY3Rpb24oKXt2
-YXIgcyxyLHEscCxvPXRoaXMuYS5nZXRBdHRyaWJ1dGUoImNsYXNzIiksbj1QLkxzKHQuTikKaWYobz09
-bnVsbClyZXR1cm4gbgpmb3Iocz1vLnNwbGl0KCIgIikscj1zLmxlbmd0aCxxPTA7cTxyOysrcSl7cD1K
-LlQwKHNbcV0pCmlmKHAubGVuZ3RoIT09MCluLmkoMCxwKX1yZXR1cm4gbn0sClg6ZnVuY3Rpb24oYSl7
-dGhpcy5hLnNldEF0dHJpYnV0ZSgiY2xhc3MiLGEuSCgwLCIgIikpfX0KUC5oaS5wcm90b3R5cGU9ewpn
-RDpmdW5jdGlvbihhKXtyZXR1cm4gbmV3IFAuS2UoYSl9LApzaGY6ZnVuY3Rpb24oYSxiKXt0aGlzLllD
-KGEsYil9LApyNjpmdW5jdGlvbihhLGIsYyxkKXt2YXIgcyxyLHEscCxvLG4KaWYoZD09bnVsbCl7cz1I
-LlZNKFtdLHQudikKZD1uZXcgVy52RChzKQpDLk5tLmkocyxXLlR3KG51bGwpKQpDLk5tLmkocyxXLkJs
-KCkpCkMuTm0uaShzLG5ldyBXLk93KCkpfWM9bmV3IFcuS28oZCkKcj0nPHN2ZyB2ZXJzaW9uPSIxLjEi
-PicrSC5FaihiKSsiPC9zdmc+IgpzPWRvY3VtZW50CnE9cy5ib2R5CnEudG9TdHJpbmcKcD1DLlJZLkFI
-KHEscixjKQpvPXMuY3JlYXRlRG9jdW1lbnRGcmFnbWVudCgpCnAudG9TdHJpbmcKcz1uZXcgVy5lNyhw
-KQpuPXMuZ3I4KHMpCmZvcig7cz1uLmZpcnN0Q2hpbGQscyE9bnVsbDspby5hcHBlbmRDaGlsZChzKQpy
-ZXR1cm4gb30sCm56OmZ1bmN0aW9uKGEsYixjLGQsZSl7dGhyb3cgSC5iKFAuTDQoIkNhbm5vdCBpbnZv
-a2UgaW5zZXJ0QWRqYWNlbnRIdG1sIG9uIFNWRy4iKSl9LApnVmw6ZnVuY3Rpb24oYSl7cmV0dXJuIG5l
-dyBXLmV1KGEsImNsaWNrIiwhMSx0LmspfSwKJGloaToxfQpNLkg3LnByb3RvdHlwZT17Cnc6ZnVuY3Rp
-b24oYSl7cmV0dXJuIHRoaXMuYn19ClUuTEwucHJvdG90eXBlPXsKTHQ6ZnVuY3Rpb24oKXtyZXR1cm4g
-UC5FRihbIm5vZGVJZCIsdGhpcy5iLCJraW5kIix0aGlzLmEuYV0sdC5YLHQuXyl9fQpVLk1ELnByb3Rv
-dHlwZT17CiQxOmZ1bmN0aW9uKGEpe3JldHVybiB0LmZFLmEoYSkuYT09PXRoaXMuYS5xKDAsImtpbmQi
-KX0sCiRTOjM4fQpVLmQyLnByb3RvdHlwZT17Ckx0OmZ1bmN0aW9uKCl7dmFyIHMscixxLHAsbz10aGlz
-LG49dC5YLG09dC5fLGw9UC5GbChuLG0pLGs9by5hCmlmKGshPW51bGwpe3M9SC5WTShbXSx0LkcpCmZv
-cihyPWsubGVuZ3RoLHE9MDtxPGsubGVuZ3RoO2subGVuZ3RoPT09cnx8KDAsSC5saykoayksKytxKXtw
-PWtbcV0Kcy5wdXNoKFAuRUYoWyJkZXNjcmlwdGlvbiIscC5hLCJocmVmIixwLmJdLG4sbSkpfWwuWSgw
-LCJlZGl0cyIscyl9bC5ZKDAsImV4cGxhbmF0aW9uIixvLmIpCmwuWSgwLCJsaW5lIixvLmMpCmwuWSgw
-LCJkaXNwbGF5UGF0aCIsby5kKQpsLlkoMCwidXJpUGF0aCIsby5lKQpuPW8uZgppZihuIT1udWxsKXtt
-PUguVk0oW10sdC5HKQpmb3Ioaz1uLmxlbmd0aCxxPTA7cTxuLmxlbmd0aDtuLmxlbmd0aD09PWt8fCgw
-LEgubGspKG4pLCsrcSltLnB1c2gobltxXS5MdCgpKQpsLlkoMCwidHJhY2VzIixtKX1yZXR1cm4gbH19
-ClUuU2UucHJvdG90eXBlPXsKTHQ6ZnVuY3Rpb24oKXtyZXR1cm4gUC5FRihbImRlc2NyaXB0aW9uIix0
-aGlzLmEsImhyZWYiLHRoaXMuYl0sdC5YLHQuXyl9fQpVLk1sLnByb3RvdHlwZT17Ckx0OmZ1bmN0aW9u
-KCl7cmV0dXJuIFAuRUYoWyJocmVmIix0aGlzLmEsImxpbmUiLHRoaXMuYiwicGF0aCIsdGhpcy5jXSx0
-LlgsdC5fKX19ClUueUQucHJvdG90eXBlPXsKTHQ6ZnVuY3Rpb24oKXt2YXIgcyxyLHEscD1ILlZNKFtd
-LHQuRykKZm9yKHM9dGhpcy5iLHI9cy5sZW5ndGgscT0wO3E8cy5sZW5ndGg7cy5sZW5ndGg9PT1yfHwo
-MCxILmxrKShzKSwrK3EpcC5wdXNoKHNbcV0uTHQoKSkKcmV0dXJuIFAuRUYoWyJkZXNjcmlwdGlvbiIs
-dGhpcy5hLCJlbnRyaWVzIixwXSx0LlgsdC5fKX19ClUud2IucHJvdG90eXBlPXsKTHQ6ZnVuY3Rpb24o
-KXt2YXIgcyxyLHEscD10aGlzLG89UC5GbCh0LlgsdC5fKQpvLlkoMCwiZGVzY3JpcHRpb24iLHAuYSkK
-cz1wLmIKaWYocyE9bnVsbClvLlkoMCwiZnVuY3Rpb24iLHMpCnM9cC5jCmlmKHMhPW51bGwpby5ZKDAs
-ImxpbmsiLHMuTHQoKSkKcz1wLmQKaWYocy5sZW5ndGghPT0wKXtyPUgudDYocykKcT1yLkMoImxKPDEs
-WjA8cVUqLE1oKj4qPiIpCm8uWSgwLCJoaW50QWN0aW9ucyIsUC5ZMShuZXcgSC5sSihzLHIuQygiWjA8
-cVUqLE1oKj4qKDEpIikuYShuZXcgVS5iMCgpKSxxKSwhMCxxLkMoImFMLkUiKSkpfXJldHVybiBvfX0K
-VS5hTi5wcm90b3R5cGU9ewokMTpmdW5jdGlvbihhKXtyZXR1cm4gVS5ueih0LnQuYShhKSl9LAokUzoz
-OX0KVS5iMC5wcm90b3R5cGU9ewokMTpmdW5jdGlvbihhKXtyZXR1cm4gdC5hWC5hKGEpLkx0KCl9LAok
-Uzo0MH0KQi5qOC5wcm90b3R5cGU9ewpMdDpmdW5jdGlvbigpe3JldHVybiBQLkVGKFsibGluZSIsdGhp
-cy5hLCJleHBsYW5hdGlvbiIsdGhpcy5iLCJvZmZzZXQiLHRoaXMuY10sdC5YLHQuXyl9fQpCLnFwLnBy
-b3RvdHlwZT17Ckx0OmZ1bmN0aW9uKCl7dmFyIHMscixxLHAsbyxuLG0sbD10aGlzLGs9dC5YLGo9UC5G
-bChrLHQuZHApCmZvcihzPWwuZCxzPXMuZ1B1KHMpLHM9cy5nbShzKSxyPXQuXyxxPXQuRztzLkYoKTsp
-e3A9cy5nbCgpCm89cC5hCm49SC5WTShbXSxxKQpmb3IocD1KLklUKHAuYik7cC5GKCk7KXttPXAuZ2wo
-KQpuLnB1c2goUC5FRihbImxpbmUiLG0uYSwiZXhwbGFuYXRpb24iLG0uYiwib2Zmc2V0IixtLmNdLGss
-cikpfWouWSgwLG8sbil9cmV0dXJuIFAuRUYoWyJyZWdpb25zIixsLmEsIm5hdmlnYXRpb25Db250ZW50
-IixsLmIsInNvdXJjZUNvZGUiLGwuYywiZWRpdHMiLGpdLGsscil9fQpULm1RLnByb3RvdHlwZT17fQpM
-LmUucHJvdG90eXBlPXsKJDE6ZnVuY3Rpb24oYSl7dmFyIHMscixxLHAsbyxuLG0KdC5hTC5hKGEpCnM9
-d2luZG93LmxvY2F0aW9uLnBhdGhuYW1lCnI9TC5HNih3aW5kb3cubG9jYXRpb24uaHJlZikKcT1MLmFL
-KHdpbmRvdy5sb2NhdGlvbi5ocmVmKQpMLkdlKCkKaWYocyE9PSIvIiYmcyE9PUouVDAoZG9jdW1lbnQu
-cXVlcnlTZWxlY3RvcigiLnJvb3QiKS50ZXh0Q29udGVudCkpTC5HNyhzLHIscSwhMCxuZXcgTC5WVyhz
-LHIscSkpCnA9ZG9jdW1lbnQKbz1KLnFGKHAucXVlcnlTZWxlY3RvcigiLmFwcGx5LW1pZ3JhdGlvbiIp
-KQpuPW8uJHRpCm09bi5DKCJ+KDEpPyIpLmEobmV3IEwub1ooKSkKdC5aLmEobnVsbCkKVy5KRShvLmEs
-by5iLG0sITEsbi5jKQpuPUoucUYocC5xdWVyeVNlbGVjdG9yKCIucmVydW4tbWlncmF0aW9uIikpCm09
-bi4kdGkKVy5KRShuLmEsbi5iLG0uQygifigxKT8iKS5hKG5ldyBMLkhpKCkpLCExLG0uYykKbT1KLnFG
-KHAucXVlcnlTZWxlY3RvcigiLnJlcG9ydC1wcm9ibGVtIikpCm49bS4kdGkKVy5KRShtLmEsbS5iLG4u
-QygifigxKT8iKS5hKG5ldyBMLkJUKCkpLCExLG4uYykKcD1KLnFGKHAucXVlcnlTZWxlY3RvcigiLnBv
-cHVwLXBhbmUgLmNsb3NlIikpCm49cC4kdGkKVy5KRShwLmEscC5iLG4uQygifigxKT8iKS5hKG5ldyBM
-LlBZKCkpLCExLG4uYyl9LAokUzoxOH0KTC5WVy5wcm90b3R5cGU9ewokMDpmdW5jdGlvbigpe0wuRnIo
-dGhpcy5hLHRoaXMuYix0aGlzLmMpfSwKJFM6MX0KTC5vWi5wcm90b3R5cGU9ewokMTpmdW5jdGlvbihh
-KXt2YXIgcyxyLHEscAp0Lk8uYShhKQppZihILm9UKEMub2wudXMod2luZG93LCJUaGlzIHdpbGwgYXBw
-bHkgdGhlIGNoYW5nZXMgeW91J3ZlIHByZXZpZXdlZCB0byB5b3VyIHdvcmtpbmcgZGlyZWN0b3J5LiBJ
-dCBpcyByZWNvbW1lbmRlZCB5b3UgY29tbWl0IGFueSBjaGFuZ2VzIHlvdSBtYWRlIGJlZm9yZSBkb2lu
-ZyB0aGlzLiIpKSl7cz1MLnR5KCIvYXBwbHktbWlncmF0aW9uIixudWxsKS5XNyhuZXcgTC5qcigpLHQu
-UCkKcj1uZXcgTC5xbCgpCnQuYjcuYShudWxsKQpxPXMuJHRpCnA9JC5YMwppZihwIT09Qy5OVSlyPVAu
-VkgocixwKQpzLnhmKG5ldyBQLkZlKG5ldyBQLnZzKHAscSksMixudWxsLHIscS5DKCJAPDE+IikuS3Eo
-cS5jKS5DKCJGZTwxLDI+IikpKX19LAokUzoyfQpMLmpyLnByb3RvdHlwZT17CiQxOmZ1bmN0aW9uKGEp
-e3ZhciBzCnQudC5hKGEpCnM9ZG9jdW1lbnQuYm9keQpzLmNsYXNzTGlzdC5yZW1vdmUoInByb3Bvc2Vk
-IikKcy5jbGFzc0xpc3QuYWRkKCJhcHBsaWVkIil9LAokUzo0M30KTC5xbC5wcm90b3R5cGU9ewokMjpm
-dW5jdGlvbihhLGIpe0wuQzIoIkNvdWxkIG5vdCBhcHBseSBtaWdyYXRpb24iLGEsYil9LAokQzoiJDIi
-LAokUjoyLAokUzoxNn0KTC5IaS5wcm90b3R5cGU9ewokMTpmdW5jdGlvbihhKXtyZXR1cm4gdGhpcy54
-bih0Lk8uYShhKSl9LAp4bjpmdW5jdGlvbihhKXt2YXIgcz0wLHI9UC5GWCh0LlApLHE9MSxwLG89W10s
-bixtLGwsayxqCnZhciAkYXN5bmMkJDE9UC5seihmdW5jdGlvbihiLGMpe2lmKGI9PT0xKXtwPWMKcz1x
-fXdoaWxlKHRydWUpc3dpdGNoKHMpe2Nhc2UgMDpxPTMKZG9jdW1lbnQuYm9keS5jbGFzc0xpc3QuYWRk
-KCJyZXJ1bm5pbmciKQpzPTYKcmV0dXJuIFAualEoTC50eSgiL3JlcnVuLW1pZ3JhdGlvbiIsbnVsbCks
-JGFzeW5jJCQxKQpjYXNlIDY6bj1jCmlmKEgub1QoSC55OChKLng5KG4sInN1Y2Nlc3MiKSkpKXdpbmRv
-dy5sb2NhdGlvbi5yZWxvYWQoKQplbHNlIEwuSzAodC5tLmEoSi54OShuLCJlcnJvcnMiKSkpCm8ucHVz
-aCg1KQpzPTQKYnJlYWsKY2FzZSAzOnE9MgpqPXAKbT1ILlJ1KGopCmw9SC50cyhqKQpMLkMyKCJGYWls
-ZWQgdG8gcmVydW4gbWlncmF0aW9uIixtLGwpCm8ucHVzaCg1KQpzPTQKYnJlYWsKY2FzZSAyOm89WzFd
-CmNhc2UgNDpxPTEKZG9jdW1lbnQuYm9keS5jbGFzc0xpc3QucmVtb3ZlKCJyZXJ1bm5pbmciKQpzPW8u
-cG9wKCkKYnJlYWsKY2FzZSA1OnJldHVybiBQLnlDKG51bGwscikKY2FzZSAxOnJldHVybiBQLmYzKHAs
-cil9fSkKcmV0dXJuIFAuREkoJGFzeW5jJCQxLHIpfSwKJFM6MTl9CkwuQlQucHJvdG90eXBlPXsKJDE6
-ZnVuY3Rpb24oYSl7dmFyIHMKdC5PLmEoYSkKcz10LlgKQy5vbC5Qbyh3aW5kb3csUC5YZCgiaHR0cHMi
-LCJnaXRodWIuY29tIiwiZGFydC1sYW5nL3Nkay9pc3N1ZXMvbmV3IixQLkVGKFsidGl0bGUiLCJDdXN0
-b21lci1yZXBvcnRlZCBpc3N1ZSB3aXRoIE5OQkQgbWlncmF0aW9uIHRvb2wiLCJsYWJlbHMiLHUuZCwi
-Ym9keSIsIiMjIyMgU3RlcHMgdG8gcmVwcm9kdWNlXG5cbiMjIyMgV2hhdCBkaWQgeW91IGV4cGVjdCB0
-byBoYXBwZW4/XG5cbiMjIyMgV2hhdCBhY3R1YWxseSBoYXBwZW5lZD9cblxuX1NjcmVlbnNob3RzIGFy
-ZSBhcHByZWNpYXRlZF9cblxuKipEYXJ0IFNESyB2ZXJzaW9uKio6ICIrSC5Faihkb2N1bWVudC5nZXRF
-bGVtZW50QnlJZCgic2RrLXZlcnNpb24iKS50ZXh0Q29udGVudCkrIlxuXG5UaGFua3MgZm9yIGZpbGlu
-ZyFcbiJdLHMscykpLmduRCgpLCJyZXBvcnQtcHJvYmxlbSIpfSwKJFM6Mn0KTC5QWS5wcm90b3R5cGU9
-ewokMTpmdW5jdGlvbihhKXt2YXIgcwp0Lk8uYShhKQpzPWRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoIi5w
-b3B1cC1wYW5lIikuc3R5bGUKcy5kaXNwbGF5PSJub25lIgpyZXR1cm4ibm9uZSJ9LAokUzo0NX0KTC5M
-LnByb3RvdHlwZT17CiQxOmZ1bmN0aW9uKGEpe3ZhciBzLHIscQp0LmFMLmEoYSkKcz13aW5kb3cubG9j
-YXRpb24ucGF0aG5hbWUKcj1MLkc2KHdpbmRvdy5sb2NhdGlvbi5ocmVmKQpxPUwuYUsod2luZG93Lmxv
-Y2F0aW9uLmhyZWYpCmlmKHMubGVuZ3RoPjEpTC5HNyhzLHIscSwhMSxudWxsKQplbHNle0wuQkUocyxC
-LndSKCksITApCkwuQlgoIiZuYnNwOyIsbnVsbCl9fSwKJFM6MTh9CkwuV3gucHJvdG90eXBlPXsKJDE6
-ZnVuY3Rpb24oYSl7dmFyIHMscixxLHA9ImNvbGxhcHNlZCIKdC5PLmEoYSkKcz10aGlzLmEKcj1KLllF
-KHMpCnE9dGhpcy5iCmlmKCFyLmdEKHMpLnRnKDAscCkpe3IuZ0QocykuaSgwLHApCkouZFIocSkuaSgw
-LHApfWVsc2V7ci5nRChzKS5SKDAscCkKSi5kUihxKS5SKDAscCl9fSwKJFM6Mn0KTC5BTy5wcm90b3R5
-cGU9ewokMTpmdW5jdGlvbihhKXt2YXIgcz1KLnFGKHQuZy5hKGEpKSxyPXMuJHRpLHE9ci5DKCJ+KDEp
-PyIpLmEobmV3IEwuZE4odGhpcy5hKSkKdC5aLmEobnVsbCkKVy5KRShzLmEscy5iLHEsITEsci5jKX0s
-CiRTOjN9CkwuZE4ucHJvdG90eXBlPXsKJDE6ZnVuY3Rpb24oYSl7dmFyIHMKdC5PLmEoYSkKcz1kb2N1
-bWVudC5xdWVyeVNlbGVjdG9yKCJ0YWJsZVtkYXRhLXBhdGhdIikKcy50b1N0cmluZwpMLnQyKGEsdGhp
-cy5hLHMuZ2V0QXR0cmlidXRlKCJkYXRhLSIrbmV3IFcuU3kobmV3IFcuaTcocykpLk8oInBhdGgiKSkp
-fSwKJFM6Mn0KTC5Iby5wcm90b3R5cGU9ewokMTpmdW5jdGlvbihhKXt2YXIgcyxyLHEKdC5nLmEoYSkK
-cz1KLnFGKGEpCnI9cy4kdGkKcT1yLkMoIn4oMSk/IikuYShuZXcgTC54eihhLHRoaXMuYSkpCnQuWi5h
-KG51bGwpClcuSkUocy5hLHMuYixxLCExLHIuYyl9LAokUzozfQpMLnh6LnByb3RvdHlwZT17CiQxOmZ1
-bmN0aW9uKGEpe3ZhciBzCnQuTy5hKGEpCnM9dGhpcy5hCkwuaFgodGhpcy5iLFAuUUEocy5nZXRBdHRy
-aWJ1dGUoImRhdGEtIituZXcgVy5TeShuZXcgVy5pNyhzKSkuTygib2Zmc2V0IikpLG51bGwpLFAuUUEo
-cy5nZXRBdHRyaWJ1dGUoImRhdGEtIituZXcgVy5TeShuZXcgVy5pNyhzKSkuTygibGluZSIpKSxudWxs
-KSl9LAokUzoyfQpMLklDLnByb3RvdHlwZT17CiQxOmZ1bmN0aW9uKGEpe3ZhciBzPUoucUYodC5nLmEo
-YSkpLHI9cy4kdGkKci5DKCJ+KDEpPyIpLmEoTC5pUygpKQp0LlouYShudWxsKQpXLkpFKHMuYSxzLmIs
-TC5pUygpLCExLHIuYyl9LAokUzozfQpMLmZDLnByb3RvdHlwZT17CiQxOmZ1bmN0aW9uKGEpe3QuZVEu
-YShhKQp0aGlzLmEuYU0oMCx0aGlzLmIpfSwKJFM6NDd9CkwublQucHJvdG90eXBlPXsKJDA6ZnVuY3Rp
-b24oKXtMLkZyKHRoaXMuYSx0aGlzLmIsdGhpcy5jKX0sCiRTOjF9CkwuTlkucHJvdG90eXBlPXsKJDA6
-ZnVuY3Rpb24oKXtMLkZyKHRoaXMuYSxudWxsLG51bGwpfSwKJFM6MX0KTC51ZS5wcm90b3R5cGU9ewok
-MTpmdW5jdGlvbihhKXt0LmF3LmEoYSkKcmV0dXJuIEguRWooYS5xKDAsInNldmVyaXR5IikpKyIgLSAi
-K0guRWooYS5xKDAsIm1lc3NhZ2UiKSkrIiBhdCAiK0guRWooYS5xKDAsImxvY2F0aW9uIikpKyIgLSAo
-IitILkVqKGEucSgwLCJjb2RlIikpKyIpIn0sCiRTOjQ4fQpMLmVYLnByb3RvdHlwZT17CiQxOmZ1bmN0
-aW9uKGEpe3QuZy5hKGEpCiQuekIoKS50b1N0cmluZwp0LmRILmEoJC5vdygpLnEoMCwiaGxqcyIpKS5W
-NygiaGlnaGxpZ2h0QmxvY2siLFthXSl9LAokUzozfQpMLkVFLnByb3RvdHlwZT17CiQxOmZ1bmN0aW9u
-KGEpe3ZhciBzLHIKdC5PLmEoYSkucHJldmVudERlZmF1bHQoKQpzPXRoaXMuYQpyPXRoaXMuYgpMLmFm
-KHdpbmRvdy5sb2NhdGlvbi5wYXRobmFtZSxzLHIsITAsbmV3IEwuUUwocyxyKSkKTC5oWCh0aGlzLmMs
-cyxyKX0sCiRTOjJ9CkwuUUwucHJvdG90eXBlPXsKJDA6ZnVuY3Rpb24oKXtMLkZyKHdpbmRvdy5sb2Nh
-dGlvbi5wYXRobmFtZSx0aGlzLmEsdGhpcy5iKX0sCiRTOjF9CkwuVlMucHJvdG90eXBlPXsKJDE6ZnVu
-Y3Rpb24oYSl7dmFyIHMscj0ic2VsZWN0ZWQtZmlsZSIKdC5nLmEoYSkKYS50b1N0cmluZwpzPUouWUUo
-YSkKaWYoYS5nZXRBdHRyaWJ1dGUoImRhdGEtIituZXcgVy5TeShuZXcgVy5pNyhhKSkuTygibmFtZSIp
-KT09PXRoaXMuYS5hKXMuZ0QoYSkuaSgwLHIpCmVsc2Ugcy5nRChhKS5SKDAscil9LAokUzozfQpMLlRE
-LnByb3RvdHlwZT17CiQxOmZ1bmN0aW9uKGEpe3JldHVybiBMLnQyKHQuTy5hKGEpLCEwLG51bGwpfSwK
-JFM6MjB9CkwubTIucHJvdG90eXBlPXsKJDE6ZnVuY3Rpb24oYSl7cmV0dXJuIHRoaXMuUkkodC5PLmEo
-YSkpfSwKUkk6ZnVuY3Rpb24oYSl7dmFyIHM9MCxyPVAuRlgodC5QKSxxPTEscCxvPVtdLG49dGhpcyxt
-LGwsayxqLGksaCxnLGYKdmFyICRhc3luYyQkMT1QLmx6KGZ1bmN0aW9uKGIsYyl7aWYoYj09PTEpe3A9
-YwpzPXF9d2hpbGUodHJ1ZSlzd2l0Y2gocyl7Y2FzZSAwOnE9MwppPWRvY3VtZW50Cm09Qy5DRC56UShp
-LnF1ZXJ5U2VsZWN0b3IoIi5jb250ZW50Iikuc2Nyb2xsVG9wKQpoPXQuWApzPTYKcmV0dXJuIFAualEo
-TC50eShMLlE0KCIvYXBwbHktaGludCIsUC5GbChoLGgpKSxuLmEuTHQoKSksJGFzeW5jJCQxKQpjYXNl
-IDY6aD1uLmIKbD1MLlVzKGguYSkKcz03CnJldHVybiBQLmpRKEwuRzcobCxudWxsLGguYiwhMSxudWxs
-KSwkYXN5bmMkJDEpCmNhc2UgNzppLmJvZHkuY2xhc3NMaXN0LmFkZCgibmVlZHMtcmVydW4iKQppPWku
-cXVlcnlTZWxlY3RvcigiLmNvbnRlbnQiKQppLnRvU3RyaW5nCmkuc2Nyb2xsVG9wPUouVnUobSkKcT0x
-CnM9NQpicmVhawpjYXNlIDM6cT0yCmY9cAprPUguUnUoZikKaj1ILnRzKGYpCkwuQzIoIkNvdWxkIG5v
-dCBhcHBseSBoaW50IixrLGopCnM9NQpicmVhawpjYXNlIDI6cz0xCmJyZWFrCmNhc2UgNTpyZXR1cm4g
-UC55QyhudWxsLHIpCmNhc2UgMTpyZXR1cm4gUC5mMyhwLHIpfX0pCnJldHVybiBQLkRJKCRhc3luYyQk
-MSxyKX0sCiRTOjE5fQpMLlhBLnByb3RvdHlwZT17CkViOmZ1bmN0aW9uKGEsYixjKXtyZXR1cm4hMH0s
-CmkwOmZ1bmN0aW9uKGEpe3JldHVybiEwfSwKJGlrRjoxfQpMLnZ0LnByb3RvdHlwZT17CkxWOmZ1bmN0
-aW9uKCl7dmFyIHMscixxPXRoaXMuZAppZihxIT1udWxsKWZvcihzPXEubGVuZ3RoLHI9MDtyPHM7Kyty
-KXFbcl0uYj10aGlzfSwKTHQ6ZnVuY3Rpb24oKXt2YXIgcyxyPVAuRmwodC5YLHQuXykKci5ZKDAsInR5
-cGUiLCJkaXJlY3RvcnkiKQpyLlkoMCwibmFtZSIsdGhpcy5hKQpyLlkoMCwic3VidHJlZSIsTC5WRCh0
-aGlzLmQpKQpzPXRoaXMuYwppZihzIT1udWxsKXIuWSgwLCJwYXRoIixzKQpyZXR1cm4gcn19CkwuY0Qu
-cHJvdG90eXBlPXsKTHQ6ZnVuY3Rpb24oKXt2YXIgcyxyPXRoaXMscT1QLkZsKHQuWCx0Ll8pCnEuWSgw
-LCJ0eXBlIiwiZmlsZSIpCnEuWSgwLCJuYW1lIixyLmEpCnM9ci5jCmlmKHMhPW51bGwpcS5ZKDAsInBh
-dGgiLHMpCnM9ci5kCmlmKHMhPW51bGwpcS5ZKDAsImhyZWYiLHMpCnM9ci5lCmlmKHMhPW51bGwpcS5Z
-KDAsImVkaXRDb3VudCIscykKcz1yLmYKaWYocyE9bnVsbClxLlkoMCwid2FzRXhwbGljaXRseU9wdGVk
-T3V0IixzKQpzPXIucgppZihzIT1udWxsKXEuWSgwLCJtaWdyYXRpb25TdGF0dXMiLHMuYSkKcmV0dXJu
-IHF9fQpMLkQ4LnByb3RvdHlwZT17fQpMLk85LnByb3RvdHlwZT17Cnc6ZnVuY3Rpb24oYSl7cmV0dXJu
-IHRoaXMuYn19CkwuR2IucHJvdG90eXBlPXsKdzpmdW5jdGlvbihhKXtyZXR1cm4gdGhpcy5ifX0KTS5s
-SS5wcm90b3R5cGU9ewpnbDpmdW5jdGlvbigpe3ZhciBzPUQuYWIoKQpyZXR1cm4gc30sCldPOmZ1bmN0
-aW9uKGEsYil7dmFyIHMscixxPXQuZDQKTS5ZRigiYWJzb2x1dGUiLEguVk0oW2IsbnVsbCxudWxsLG51
-bGwsbnVsbCxudWxsLG51bGxdLHEpKQpzPXRoaXMuYQpzPXMuWXIoYik+MCYmIXMuaEsoYikKaWYocyly
-ZXR1cm4gYgpyPUguVk0oW3RoaXMuZ2woKSxiLG51bGwsbnVsbCxudWxsLG51bGwsbnVsbCxudWxsXSxx
-KQpNLllGKCJqb2luIixyKQpyZXR1cm4gdGhpcy5JUChuZXcgSC51NihyLHQuZUopKX0sCnpmOmZ1bmN0
-aW9uKGEpe3ZhciBzLHIscT1YLkNMKGEsdGhpcy5hKQpxLklWKCkKcz1xLmQKcj1zLmxlbmd0aAppZihy
-PT09MCl7cz1xLmIKcmV0dXJuIHM9PW51bGw/Ii4iOnN9aWYocj09PTEpe3M9cS5iCnJldHVybiBzPT1u
-dWxsPyIuIjpzfWlmKDA+PXIpcmV0dXJuIEguT0gocywtMSkKcy5wb3AoKQpzPXEuZQppZigwPj1zLmxl
-bmd0aClyZXR1cm4gSC5PSChzLC0xKQpzLnBvcCgpCnEuSVYoKQpyZXR1cm4gcS53KDApfSwKSVA6ZnVu
-Y3Rpb24oYSl7dmFyIHMscixxLHAsbyxuLG0sbCxrLGoKdC5RLmEoYSkKZm9yKHM9YS4kdGkscj1zLkMo
-ImEyKGNYLkUpIikuYShuZXcgTS5xNygpKSxxPWEuZ20oYSkscz1uZXcgSC5TTyhxLHIscy5DKCJTTzxj
-WC5FPiIpKSxyPXRoaXMuYSxwPSExLG89ITEsbj0iIjtzLkYoKTspe209cS5nbCgpCmlmKHIuaEsobSkm
-Jm8pe2w9WC5DTChtLHIpCms9bi5jaGFyQ29kZUF0KDApPT0wP246bgpuPUMueEIuTmooaywwLHIuU3Ao
-aywhMCkpCmwuYj1uCmlmKHIuZHMobikpQy5ObS5ZKGwuZSwwLHIuZ21JKCkpCm49bC53KDApfWVsc2Ug
-aWYoci5ZcihtKT4wKXtvPSFyLmhLKG0pCm49SC5FaihtKX1lbHNle2o9bS5sZW5ndGgKaWYoaiE9PTAp
-e2lmKDA+PWopcmV0dXJuIEguT0gobSwwKQpqPXIuVWQobVswXSl9ZWxzZSBqPSExCmlmKCFqKWlmKHAp
-bis9ci5nbUkoKQpuKz1tfXA9ci5kcyhtKX1yZXR1cm4gbi5jaGFyQ29kZUF0KDApPT0wP246bn0sCm81
-OmZ1bmN0aW9uKGEpe3ZhciBzCmlmKCF0aGlzLnkzKGEpKXJldHVybiBhCnM9WC5DTChhLHRoaXMuYSkK
-cy5yUigpCnJldHVybiBzLncoMCl9LAp5MzpmdW5jdGlvbihhKXt2YXIgcyxyLHEscCxvLG4sbSxsLGss
-agphLnRvU3RyaW5nCnM9dGhpcy5hCnI9cy5ZcihhKQppZihyIT09MCl7aWYocz09PSQuS2soKSlmb3Io
-cT0wO3E8cjsrK3EpaWYoQy54Qi5XKGEscSk9PT00NylyZXR1cm4hMApwPXIKbz00N31lbHNle3A9MApv
-PW51bGx9Zm9yKG49bmV3IEgucWooYSkuYSxtPW4ubGVuZ3RoLHE9cCxsPW51bGw7cTxtOysrcSxsPW8s
-bz1rKXtrPUMueEIuTzIobixxKQppZihzLnI0KGspKXtpZihzPT09JC5LaygpJiZrPT09NDcpcmV0dXJu
-ITAKaWYobyE9bnVsbCYmcy5yNChvKSlyZXR1cm4hMAppZihvPT09NDYpaj1sPT1udWxsfHxsPT09NDZ8
-fHMucjQobCkKZWxzZSBqPSExCmlmKGopcmV0dXJuITB9fWlmKG89PW51bGwpcmV0dXJuITAKaWYocy5y
-NChvKSlyZXR1cm4hMAppZihvPT09NDYpcz1sPT1udWxsfHxzLnI0KGwpfHxsPT09NDYKZWxzZSBzPSEx
-CmlmKHMpcmV0dXJuITAKcmV0dXJuITF9LApIUDpmdW5jdGlvbihhLGIpe3ZhciBzLHIscSxwLG8sbixt
-LGw9dGhpcyxrPSdVbmFibGUgdG8gZmluZCBhIHBhdGggdG8gIicKYj1sLldPKDAsYikKcz1sLmEKaWYo
-cy5ZcihiKTw9MCYmcy5ZcihhKT4wKXJldHVybiBsLm81KGEpCmlmKHMuWXIoYSk8PTB8fHMuaEsoYSkp
-YT1sLldPKDAsYSkKaWYocy5ZcihhKTw9MCYmcy5ZcihiKT4wKXRocm93IEguYihYLkk3KGsrSC5Faihh
-KSsnIiBmcm9tICInK0guRWooYikrJyIuJykpCnI9WC5DTChiLHMpCnIuclIoKQpxPVguQ0woYSxzKQpx
-LnJSKCkKcD1yLmQKbz1wLmxlbmd0aAppZihvIT09MCl7aWYoMD49bylyZXR1cm4gSC5PSChwLDApCnA9
-Si5STShwWzBdLCIuIil9ZWxzZSBwPSExCmlmKHApcmV0dXJuIHEudygwKQpwPXIuYgpvPXEuYgppZihw
-IT1vKXA9cD09bnVsbHx8bz09bnVsbHx8IXMuTmMocCxvKQplbHNlIHA9ITEKaWYocClyZXR1cm4gcS53
-KDApCndoaWxlKCEwKXtwPXIuZApvPXAubGVuZ3RoCmlmKG8hPT0wKXtuPXEuZAptPW4ubGVuZ3RoCmlm
-KG0hPT0wKXtpZigwPj1vKXJldHVybiBILk9IKHAsMCkKcD1wWzBdCmlmKDA+PW0pcmV0dXJuIEguT0go
-biwwKQpuPXMuTmMocCxuWzBdKQpwPW59ZWxzZSBwPSExfWVsc2UgcD0hMQppZighcClicmVhawpDLk5t
-Llc0KHIuZCwwKQpDLk5tLlc0KHIuZSwxKQpDLk5tLlc0KHEuZCwwKQpDLk5tLlc0KHEuZSwxKX1wPXIu
-ZApvPXAubGVuZ3RoCmlmKG8hPT0wKXtpZigwPj1vKXJldHVybiBILk9IKHAsMCkKcD1KLlJNKHBbMF0s
-Ii4uIil9ZWxzZSBwPSExCmlmKHApdGhyb3cgSC5iKFguSTcoaytILkVqKGEpKyciIGZyb20gIicrSC5F
-aihiKSsnIi4nKSkKcD10Lk4KQy5ObS5VRyhxLmQsMCxQLk84KHIuZC5sZW5ndGgsIi4uIiwhMSxwKSkK
-Qy5ObS5ZKHEuZSwwLCIiKQpDLk5tLlVHKHEuZSwxLFAuTzgoci5kLmxlbmd0aCxzLmdtSSgpLCExLHAp
-KQpzPXEuZApwPXMubGVuZ3RoCmlmKHA9PT0wKXJldHVybiIuIgppZihwPjEmJkouUk0oQy5ObS5ncloo
-cyksIi4iKSl7cz1xLmQKaWYoMD49cy5sZW5ndGgpcmV0dXJuIEguT0gocywtMSkKcy5wb3AoKQpzPXEu
-ZQppZigwPj1zLmxlbmd0aClyZXR1cm4gSC5PSChzLC0xKQpzLnBvcCgpCmlmKDA+PXMubGVuZ3RoKXJl
-dHVybiBILk9IKHMsLTEpCnMucG9wKCkKQy5ObS5pKHMsIiIpfXEuYj0iIgpxLklWKCkKcmV0dXJuIHEu
-dygwKX19Ck0ucTcucHJvdG90eXBlPXsKJDE6ZnVuY3Rpb24oYSl7cmV0dXJuIEguaChhKSE9PSIifSwK
-JFM6Nn0KTS5Oby5wcm90b3R5cGU9ewokMTpmdW5jdGlvbihhKXtILmsoYSkKcmV0dXJuIGE9PW51bGw/
-Im51bGwiOiciJythKyciJ30sCiRTOjUwfQpCLmZ2LnByb3RvdHlwZT17CnhaOmZ1bmN0aW9uKGEpe3Zh
-ciBzLHI9dGhpcy5ZcihhKQppZihyPjApcmV0dXJuIEoubGQoYSwwLHIpCmlmKHRoaXMuaEsoYSkpe2lm
-KDA+PWEubGVuZ3RoKXJldHVybiBILk9IKGEsMCkKcz1hWzBdfWVsc2Ugcz1udWxsCnJldHVybiBzfSwK
-TmM6ZnVuY3Rpb24oYSxiKXtyZXR1cm4gYT09Yn19ClguV0QucHJvdG90eXBlPXsKSVY6ZnVuY3Rpb24o
-KXt2YXIgcyxyLHE9dGhpcwp3aGlsZSghMCl7cz1xLmQKaWYoIShzLmxlbmd0aCE9PTAmJkouUk0oQy5O
-bS5ncloocyksIiIpKSlicmVhawpzPXEuZAppZigwPj1zLmxlbmd0aClyZXR1cm4gSC5PSChzLC0xKQpz
-LnBvcCgpCnM9cS5lCmlmKDA+PXMubGVuZ3RoKXJldHVybiBILk9IKHMsLTEpCnMucG9wKCl9cz1xLmUK
-cj1zLmxlbmd0aAppZihyIT09MClDLk5tLlkocyxyLTEsIiIpfSwKclI6ZnVuY3Rpb24oKXt2YXIgcyxy
-LHEscCxvLG4sbT10aGlzLGw9SC5WTShbXSx0LnMpCmZvcihzPW0uZCxyPXMubGVuZ3RoLHE9MCxwPTA7
-cDxzLmxlbmd0aDtzLmxlbmd0aD09PXJ8fCgwLEgubGspKHMpLCsrcCl7bz1zW3BdCm49Si5pYShvKQpp
-ZighKG4uRE4obywiLiIpfHxuLkROKG8sIiIpKSlpZihuLkROKG8sIi4uIikpe249bC5sZW5ndGgKaWYo
-biE9PTApe2lmKDA+PW4pcmV0dXJuIEguT0gobCwtMSkKbC5wb3AoKX1lbHNlICsrcX1lbHNlIEMuTm0u
-aShsLG8pfWlmKG0uYj09bnVsbClDLk5tLlVHKGwsMCxQLk84KHEsIi4uIiwhMSx0Lk4pKQppZihsLmxl
-bmd0aD09PTAmJm0uYj09bnVsbClDLk5tLmkobCwiLiIpCm0uc25KKGwpCnM9bS5hCm0uc1BoKFAuTzgo
-bC5sZW5ndGgrMSxzLmdtSSgpLCEwLHQuTikpCnI9bS5iCmlmKHI9PW51bGx8fGwubGVuZ3RoPT09MHx8
-IXMuZHMocikpQy5ObS5ZKG0uZSwwLCIiKQpyPW0uYgppZihyIT1udWxsJiZzPT09JC5LaygpKXtyLnRv
-U3RyaW5nCm0uYj1ILnlzKHIsIi8iLCJcXCIpfW0uSVYoKX0sCnc6ZnVuY3Rpb24oYSl7dmFyIHMscixx
-PXRoaXMscD1xLmIKcD1wIT1udWxsP3A6IiIKZm9yKHM9MDtzPHEuZC5sZW5ndGg7KytzKXtyPXEuZQpp
-ZihzPj1yLmxlbmd0aClyZXR1cm4gSC5PSChyLHMpCnI9cCtILkVqKHJbc10pCnA9cS5kCmlmKHM+PXAu
-bGVuZ3RoKXJldHVybiBILk9IKHAscykKcD1yK0guRWoocFtzXSl9cCs9SC5FaihDLk5tLmdyWihxLmUp
-KQpyZXR1cm4gcC5jaGFyQ29kZUF0KDApPT0wP3A6cH0sCnNuSjpmdW5jdGlvbihhKXt0aGlzLmQ9dC5F
-LmEoYSl9LApzUGg6ZnVuY3Rpb24oYSl7dGhpcy5lPXQuRS5hKGEpfX0KWC5kdi5wcm90b3R5cGU9ewp3
-OmZ1bmN0aW9uKGEpe3JldHVybiJQYXRoRXhjZXB0aW9uOiAiK3RoaXMuYX0sCiRpUno6MX0KTy56TC5w
-cm90b3R5cGU9ewp3OmZ1bmN0aW9uKGEpe3JldHVybiB0aGlzLmdvYyh0aGlzKX19CkUuT0YucHJvdG90
-eXBlPXsKVWQ6ZnVuY3Rpb24oYSl7cmV0dXJuIEMueEIudGcoYSwiLyIpfSwKcjQ6ZnVuY3Rpb24oYSl7
-cmV0dXJuIGE9PT00N30sCmRzOmZ1bmN0aW9uKGEpe3ZhciBzPWEubGVuZ3RoCnJldHVybiBzIT09MCYm
-Qy54Qi5PMihhLHMtMSkhPT00N30sClNwOmZ1bmN0aW9uKGEsYil7aWYoYS5sZW5ndGghPT0wJiZDLnhC
-LlcoYSwwKT09PTQ3KXJldHVybiAxCnJldHVybiAwfSwKWXI6ZnVuY3Rpb24oYSl7cmV0dXJuIHRoaXMu
-U3AoYSwhMSl9LApoSzpmdW5jdGlvbihhKXtyZXR1cm4hMX0sCmdvYzpmdW5jdGlvbigpe3JldHVybiJw
-b3NpeCJ9LApnbUk6ZnVuY3Rpb24oKXtyZXR1cm4iLyJ9fQpGLnJ1LnByb3RvdHlwZT17ClVkOmZ1bmN0
-aW9uKGEpe3JldHVybiBDLnhCLnRnKGEsIi8iKX0sCnI0OmZ1bmN0aW9uKGEpe3JldHVybiBhPT09NDd9
-LApkczpmdW5jdGlvbihhKXt2YXIgcz1hLmxlbmd0aAppZihzPT09MClyZXR1cm4hMQppZihDLnhCLk8y
-KGEscy0xKSE9PTQ3KXJldHVybiEwCnJldHVybiBDLnhCLlRjKGEsIjovLyIpJiZ0aGlzLllyKGEpPT09
-c30sClNwOmZ1bmN0aW9uKGEsYil7dmFyIHMscixxLHAsbz1hLmxlbmd0aAppZihvPT09MClyZXR1cm4g
-MAppZihDLnhCLlcoYSwwKT09PTQ3KXJldHVybiAxCmZvcihzPTA7czxvOysrcyl7cj1DLnhCLlcoYSxz
-KQppZihyPT09NDcpcmV0dXJuIDAKaWYocj09PTU4KXtpZihzPT09MClyZXR1cm4gMApxPUMueEIuWFUo
-YSwiLyIsQy54Qi5RaShhLCIvLyIscysxKT9zKzM6cykKaWYocTw9MClyZXR1cm4gbwppZighYnx8bzxx
-KzMpcmV0dXJuIHEKaWYoIUMueEIubihhLCJmaWxlOi8vIikpcmV0dXJuIHEKaWYoIUIuWXUoYSxxKzEp
-KXJldHVybiBxCnA9cSszCnJldHVybiBvPT09cD9wOnErNH19cmV0dXJuIDB9LApZcjpmdW5jdGlvbihh
-KXtyZXR1cm4gdGhpcy5TcChhLCExKX0sCmhLOmZ1bmN0aW9uKGEpe3JldHVybiBhLmxlbmd0aCE9PTAm
-JkMueEIuVyhhLDApPT09NDd9LApnb2M6ZnVuY3Rpb24oKXtyZXR1cm4idXJsIn0sCmdtSTpmdW5jdGlv
-bigpe3JldHVybiIvIn19CkwuSVYucHJvdG90eXBlPXsKVWQ6ZnVuY3Rpb24oYSl7cmV0dXJuIEMueEIu
-dGcoYSwiLyIpfSwKcjQ6ZnVuY3Rpb24oYSl7cmV0dXJuIGE9PT00N3x8YT09PTkyfSwKZHM6ZnVuY3Rp
-b24oYSl7dmFyIHM9YS5sZW5ndGgKaWYocz09PTApcmV0dXJuITEKcz1DLnhCLk8yKGEscy0xKQpyZXR1
-cm4hKHM9PT00N3x8cz09PTkyKX0sClNwOmZ1bmN0aW9uKGEsYil7dmFyIHMscixxPWEubGVuZ3RoCmlm
-KHE9PT0wKXJldHVybiAwCnM9Qy54Qi5XKGEsMCkKaWYocz09PTQ3KXJldHVybiAxCmlmKHM9PT05Mil7
-aWYocTwyfHxDLnhCLlcoYSwxKSE9PTkyKXJldHVybiAxCnI9Qy54Qi5YVShhLCJcXCIsMikKaWYocj4w
-KXtyPUMueEIuWFUoYSwiXFwiLHIrMSkKaWYocj4wKXJldHVybiByfXJldHVybiBxfWlmKHE8MylyZXR1
-cm4gMAppZighQi5PUyhzKSlyZXR1cm4gMAppZihDLnhCLlcoYSwxKSE9PTU4KXJldHVybiAwCnE9Qy54
-Qi5XKGEsMikKaWYoIShxPT09NDd8fHE9PT05MikpcmV0dXJuIDAKcmV0dXJuIDN9LApZcjpmdW5jdGlv
-bihhKXtyZXR1cm4gdGhpcy5TcChhLCExKX0sCmhLOmZ1bmN0aW9uKGEpe3JldHVybiB0aGlzLllyKGEp
-PT09MX0sCk90OmZ1bmN0aW9uKGEsYil7dmFyIHMKaWYoYT09PWIpcmV0dXJuITAKaWYoYT09PTQ3KXJl
-dHVybiBiPT09OTIKaWYoYT09PTkyKXJldHVybiBiPT09NDcKaWYoKGFeYikhPT0zMilyZXR1cm4hMQpz
-PWF8MzIKcmV0dXJuIHM+PTk3JiZzPD0xMjJ9LApOYzpmdW5jdGlvbihhLGIpe3ZhciBzLHIscQppZihh
-PT1iKXJldHVybiEwCnM9YS5sZW5ndGgKaWYocyE9PWIubGVuZ3RoKXJldHVybiExCmZvcihyPUouclko
-YikscT0wO3E8czsrK3EpaWYoIXRoaXMuT3QoQy54Qi5XKGEscSksci5XKGIscSkpKXJldHVybiExCnJl
-dHVybiEwfSwKZ29jOmZ1bmN0aW9uKCl7cmV0dXJuIndpbmRvd3MifSwKZ21JOmZ1bmN0aW9uKCl7cmV0
-dXJuIlxcIn19OyhmdW5jdGlvbiBhbGlhc2VzKCl7dmFyIHM9Si5Hdi5wcm90b3R5cGUKcy5VPXMudwpz
-LlNqPXMuZTcKcz1KLk1GLnByb3RvdHlwZQpzLnQ9cy53CnM9UC5jWC5wcm90b3R5cGUKcy5HRz1zLmV2
-CnM9UC5NaC5wcm90b3R5cGUKcy54Yj1zLncKcz1XLmN2LnByb3RvdHlwZQpzLkRXPXMucjYKcz1XLm02
-LnByb3RvdHlwZQpzLmpGPXMuRWIKcz1QLkU0LnByb3RvdHlwZQpzLlVyPXMucQpzLmU0PXMuWX0pKCk7
-KGZ1bmN0aW9uIGluc3RhbGxUZWFyT2Zmcygpe3ZhciBzPWh1bmtIZWxwZXJzLl9zdGF0aWNfMSxyPWh1
-bmtIZWxwZXJzLl9zdGF0aWNfMCxxPWh1bmtIZWxwZXJzLmluc3RhbGxJbnN0YW5jZVRlYXJPZmYscD1o
-dW5rSGVscGVycy5pbnN0YWxsU3RhdGljVGVhck9mZixvPWh1bmtIZWxwZXJzLl9pbnN0YW5jZV8xdQpz
-KFAsIkVYIiwiWlYiLDcpCnMoUCwieXQiLCJvQSIsNykKcyhQLCJxVyIsIkJ6Iiw3KQpyKFAsIlVJIiwi
-ZU4iLDApCnEoUC5QZi5wcm90b3R5cGUsImdZSiIsMCwxLG51bGwsWyIkMiIsIiQxIl0sWyJ3MCIsInBt
-Il0sMjgsMCkKcyhQLCJDeSIsIk5DIiw0KQpzKFAsIlBIIiwiTXQiLDUpCnAoVywicFMiLDQsbnVsbCxb
-IiQ0Il0sWyJxRCJdLDgsMCkKcChXLCJWNCIsNCxudWxsLFsiJDQiXSxbIlFXIl0sOCwwKQpvKFAuQXMu
-cHJvdG90eXBlLCJndU0iLCJUIiw1KQpzKFAsImlHIiwid1kiLDUzKQpzKFAsIncwIiwiZFUiLDM2KQpz
-KEwsImlTIiwiaTYiLDIwKX0pKCk7KGZ1bmN0aW9uIGluaGVyaXRhbmNlKCl7dmFyIHM9aHVua0hlbHBl
-cnMubWl4aW4scj1odW5rSGVscGVycy5pbmhlcml0LHE9aHVua0hlbHBlcnMuaW5oZXJpdE1hbnkKcihQ
-Lk1oLG51bGwpCnEoUC5NaCxbSC5GSyxKLkd2LEoubTEsUC5jWCxILkU3LFAuWFMsUC5uWSxILmE3LFAu
-QW4sSC5GdSxILkpCLEguU1UsSC5SZSxILnd2LFAuUG4sSC5XVSxILkxJLEguVHAsSC5mOSxILnRlLEgu
-YnEsSC5YTyxILmtyLFAuWWssSC52aCxILk42LEguVlIsSC5FSyxILlBiLEgudFEsSC5TZCxILkpjLEgu
-RyxILmxZLFAuVzMsUC5paCxQLkZ5LFAuR1YsUC5QZixQLkZlLFAudnMsUC5PTSxQLnFoLFAuTU8sUC5r
-VCxQLnhJLFAuQ3csUC5tMCxQLnBSLFAuYm4sUC5sbSxQLmxELFAuS1AsUC5sZixQLldZLFAuVWssUC5T
-aCxQLlJ3LFAuYnosUC5pUCxQLms1LFAuS1ksUC5DRCxQLmFFLFAuTjMsUC5jOCxQLlpkLFAuUm4sUC5E
-bixQLlBFLFAuVWYsVy5pZCxXLkZrLFcuSlEsVy5HbSxXLnZELFcubTYsVy5PdyxXLlc5LFcuZFcsVy5t
-ayxXLktvLFAuaUosUC5FNCxNLkg3LFUuTEwsVS5kMixVLlNlLFUuTWwsVS55RCxVLndiLEIuajgsQi5x
-cCxULm1RLEwuWEEsTC5EOCxMLk85LEwuR2IsTS5sSSxPLnpMLFguV0QsWC5kdl0pCnEoSi5HdixbSi55
-RSxKLndlLEouTUYsSi5qZCxKLnFJLEouRHIsSC5FVCxXLkQwLFcuQXosVy5MZSxXLk5oLFcuYWUsVy5J
-QixXLm43LFcuZWEsVy5icixXLlNnLFcudTgsVy5LNyxXLlhXLFAuaEZdKQpxKEouTUYsW0ouaUMsSi5r
-ZCxKLmM1XSkKcihKLlBvLEouamQpCnEoSi5xSSxbSi5iVSxKLlZBXSkKcShQLmNYLFtILkJSLEguYlEs
-SC5pMSxILlU1LEguQU0sSC51NixILlhSLFAubVcsSC51bl0pCnEoSC5CUixbSC5aeSxILlFDXSkKcihI
-Lm9sLEguWnkpCnIoSC5VcSxILlFDKQpyKEgualYsSC5VcSkKcShQLlhTLFtILm4sSC5yMyxILkdNLFAu
-RXosSC5heixILnZWLEguRXEsUC5DNixILmtTLFAuVWQsUC5GLFAudSxQLm1wLFAudWIsUC5kcyxQLmxq
-LFAuVVYsUC5jXSkKcihQLnV5LFAublkpCnEoUC51eSxbSC53MixXLnd6LFcuZTddKQpyKEgucWosSC53
-MikKcShILmJRLFtILmFMLEguTUIsSC5pNV0pCnEoSC5hTCxbSC5uSCxILmxKLFAuaThdKQpyKEgueHks
-SC5pMSkKcShQLkFuLFtILk1ILEguU08sSC5VMV0pCnIoSC5kNSxILkFNKQpyKFAuUlUsUC5QbikKcihQ
-LkdqLFAuUlUpCnIoSC5QRCxQLkdqKQpyKEguTFAsSC5XVSkKcShILlRwLFtILkNqLEgubGMsSC5kQyxI
-LndOLEguVlgsUC50aCxQLmhhLFAuVnMsUC5GdCxQLnlILFAuV00sUC5TWCxQLkdzLFAuZGEsUC5vUSxQ
-LnBWLFAuVTcsUC52cixQLnJ0LFAuS0YsUC5aTCxQLlJULFAualosUC5ycSxQLlJXLFAuQjUsUC51TyxQ
-LnBLLFAuaGosUC5WcCxQLk9SLFAucmEsUC55USxQLnBnLFAuYzIsUC50aSxQLldGLFAubjEsUC5jUyxQ
-LlZDLFAuSlQsUC5SWixQLk1FLFAueTUsUC55SSxQLmM2LFAucWQsVy5DdixXLktTLFcuQTMsVy52TixX
-LlV2LFcuRWcsVy5FbyxXLldrLFcuSUEsVy5mbSxQLmpnLFAuVGEsUC5HRSxQLk43LFAudVEsUC5QQyxQ
-Lm10LFAuTnosUC5RUyxQLm5wLFUuTUQsVS5hTixVLmIwLEwuZSxMLlZXLEwub1osTC5qcixMLnFsLEwu
-SGksTC5CVCxMLlBZLEwuTCxMLld4LEwuQU8sTC5kTixMLkhvLEwueHosTC5JQyxMLmZDLEwublQsTC5O
-WSxMLnVlLEwuZVgsTC5FRSxMLlFMLEwuVlMsTC5URCxMLm0yLE0ucTcsTS5Ob10pCnIoSC5XMCxQLkV6
-KQpxKEgubGMsW0guengsSC5yVF0pCnIoSC5rWSxQLkM2KQpyKFAuaWwsUC5ZaykKcShQLmlsLFtILk41
-LFAudXcsVy5jZixXLlN5XSkKcShQLm1XLFtILktXLFAucTRdKQpyKEguTFosSC5FVCkKcShILkxaLFtI
-LlJHLEguV0JdKQpyKEguVlAsSC5SRykKcihILkRnLEguVlApCnIoSC5aRyxILldCKQpyKEguUGcsSC5a
-RykKcShILlBnLFtILnhqLEguZEUsSC5aQSxILmRULEguUHEsSC5lRSxILlY2XSkKcihILmlNLEgua1Mp
-CnIoUC5aZixQLlBmKQpyKFAuSmksUC5tMCkKcihQLlh2LFAucFIpCnIoUC5iNixQLlh2KQpyKFAuVmos
-UC5XWSkKcShQLlVrLFtQLkNWLFAuWmksUC5ieV0pCnIoUC53SSxQLmtUKQpxKFAud0ksW1AuVTgsUC5v
-aixQLk14LFAuRTMsUC5HWV0pCnIoUC5LOCxQLlVkKQpyKFAudHUsUC5TaCkKcihQLnU1LFAuWmkpCnEo
-UC51LFtQLmJKLFAuZVldKQpyKFAucWUsUC5EbikKcShXLkQwLFtXLnVILFcud2EsVy5LNSxXLkNtXSkK
-cShXLnVILFtXLmN2LFcubngsVy5RRixXLkNRXSkKcShXLmN2LFtXLnFFLFAuaGldKQpxKFcucUUsW1cu
-R2gsVy5mWSxXLm5CLFcuUVAsVy5oNCxXLlNOLFcubHAsVy5UYixXLkl2LFcuV1AsVy55WV0pCnIoVy5v
-SixXLkxlKQpyKFcuaEgsVy5BeikKcihXLlZiLFcuUUYpCnIoVy5mSixXLndhKQpxKFcuZWEsW1cudzYs
-Vy5ld10pCnIoVy5BaixXLnc2KQpyKFcuckIsVy5LNykKcihXLkJILFcuckIpCnIoVy53NCxXLklCKQpy
-KFcub2EsVy5YVykKcihXLnJoLFcub2EpCnIoVy5pNyxXLmNmKQpyKFAuQXMsUC5WaikKcShQLkFzLFtX
-Lkk0LFAuS2VdKQpyKFcuUk8sUC5xaCkKcihXLmV1LFcuUk8pCnIoVy54QyxQLk1PKQpyKFcuY3QsVy5t
-NikKcihQLkJmLFAuaUopCnEoUC5FNCxbUC5yNyxQLmNvXSkKcihQLlR6LFAuY28pCnIoUC5uZCxQLmhp
-KQpxKEwuRDgsW0wudnQsTC5jRF0pCnIoQi5mdixPLnpMKQpxKEIuZnYsW0UuT0YsRi5ydSxMLklWXSkK
-cyhILncyLEguUmUpCnMoSC5RQyxQLmxEKQpzKEguUkcsUC5sRCkKcyhILlZQLEguU1UpCnMoSC5XQixQ
-LmxEKQpzKEguWkcsSC5TVSkKcyhQLm5ZLFAubEQpCnMoUC5XWSxQLmxmKQpzKFAuUlUsUC5LUCkKcyhQ
-LnBSLFAubGYpCnMoVy5MZSxXLmlkKQpzKFcuSzcsUC5sRCkKcyhXLnJCLFcuR20pCnMoVy5YVyxQLmxE
-KQpzKFcub2EsVy5HbSkKcyhQLmNvLFAubEQpfSkoKQp2YXIgdj17dHlwZVVuaXZlcnNlOntlQzpuZXcg
-TWFwKCksdFI6e30sZVQ6e30sdFBWOnt9LHNFQTpbXX0sbWFuZ2xlZEdsb2JhbE5hbWVzOntJZjoiaW50
-IixDUDoiZG91YmxlIixaWjoibnVtIixxVToiU3RyaW5nIixhMjoiYm9vbCIsYzg6Ik51bGwiLHpNOiJM
-aXN0In0sbWFuZ2xlZE5hbWVzOnt9LGdldFR5cGVGcm9tTmFtZTpnZXRHbG9iYWxGcm9tTmFtZSxtZXRh
-ZGF0YTpbXSx0eXBlczpbIn4oKSIsImM4KCkiLCJjOChBaiopIiwiYzgoY3YqKSIsIkAoQCkiLCJxVShx
-VSkiLCJhMihxVSkiLCJ+KH4oKSkiLCJhMihjdixxVSxxVSxKUSkiLCJjOChAKSIsIn4oTWg/LE1oPyki
-LCJAKCkiLCJ+KHFVLEApIiwifihuNixxVSxJZikiLCJ+KHFVLHFVKSIsImEyKGtGKSIsImM4KEAsQCki
-LCJ+KHh1PHFVPikiLCJjOChlYSopIiwiYjg8Yzg+KihBaiopIiwifihBaiopIiwifihxVSxJZikiLCJ+
-KHFVLHFVPykiLCJuNihALEApIiwiYzgoQCxHeikiLCJhMih1SCkiLCJ+KElmLEApIiwifihlYSkiLCJ+
-KE1oW0d6P10pIiwiYzgoTWgsR3opIiwifih1SCx1SD8pIiwifihALEApIiwidnM8QD4oQCkiLCJhMih4
-dTxxVT4pIiwiYzgofigpKSIsInI3KEApIiwiTWg/KEApIiwiRTQoQCkiLCJhMiooSDcqKSIsIkxMKihA
-KSIsIlowPHFVKixNaCo+KihMTCopIiwiQChxVSkiLCJ+KEdELEApIiwiYzgoWjA8cVUqLE1oKj4qKSIs
-IlowPHFVLHFVPihaMDxxVSxxVT4scVUpIiwicVUqKEFqKikiLCJAKEAscVUpIiwiYzgoZXcqKSIsInFV
-KihaMDxALEA+KikiLCJ+KHFVW0BdKSIsInFVKHFVPykiLCJJZihJZixJZikiLCJ+KEApIiwiTWg/KE1o
-PykiLCJUejxAPihAKSJdLGludGVyY2VwdG9yc0J5VGFnOm51bGwsbGVhZlRhZ3M6bnVsbCxhcnJheVJ0
-aTp0eXBlb2YgU3ltYm9sPT0iZnVuY3Rpb24iJiZ0eXBlb2YgU3ltYm9sKCk9PSJzeW1ib2wiP1N5bWJv
-bCgiJHRpIik6IiR0aSJ9CkgueGIodi50eXBlVW5pdmVyc2UsSlNPTi5wYXJzZSgneyJjNSI6Ik1GIiwi
-aUMiOiJNRiIsImtkIjoiTUYiLCJyeCI6ImVhIiwiZTUiOiJlYSIsIlkwIjoiaGkiLCJ0cCI6ImhpIiwi
-RzgiOiJldyIsIk1yIjoicUUiLCJlTCI6InFFIiwiSTAiOiJ1SCIsImhzIjoidUgiLCJYZyI6IlFGIiwi
-bnIiOiJBaiIsInk0IjoidzYiLCJhUCI6IkNtIiwieGMiOiJueCIsImtKIjoibngiLCJ6VSI6IkRnIiwi
-ZGYiOiJFVCIsInlFIjp7ImEyIjpbXX0sIndlIjp7ImM4IjpbXX0sIk1GIjp7InZtIjpbXSwiRUgiOltd
-fSwiamQiOnsiek0iOlsiMSJdLCJiUSI6WyIxIl0sImNYIjpbIjEiXX0sIlBvIjp7ImpkIjpbIjEiXSwi
-ek0iOlsiMSJdLCJiUSI6WyIxIl0sImNYIjpbIjEiXX0sIm0xIjp7IkFuIjpbIjEiXX0sInFJIjp7IkNQ
-IjpbXSwiWloiOltdfSwiYlUiOnsiQ1AiOltdLCJJZiI6W10sIlpaIjpbXX0sIlZBIjp7IkNQIjpbXSwi
-WloiOltdfSwiRHIiOnsicVUiOltdLCJ2WCI6W119LCJCUiI6eyJjWCI6WyIyIl19LCJFNyI6eyJBbiI6
-WyIyIl19LCJaeSI6eyJCUiI6WyIxIiwiMiJdLCJjWCI6WyIyIl0sImNYLkUiOiIyIn0sIm9sIjp7Ilp5
-IjpbIjEiLCIyIl0sIkJSIjpbIjEiLCIyIl0sImJRIjpbIjIiXSwiY1giOlsiMiJdLCJjWC5FIjoiMiJ9
-LCJVcSI6eyJsRCI6WyIyIl0sInpNIjpbIjIiXSwiQlIiOlsiMSIsIjIiXSwiYlEiOlsiMiJdLCJjWCI6
-WyIyIl19LCJqViI6eyJVcSI6WyIxIiwiMiJdLCJsRCI6WyIyIl0sInpNIjpbIjIiXSwiQlIiOlsiMSIs
-IjIiXSwiYlEiOlsiMiJdLCJjWCI6WyIyIl0sImxELkUiOiIyIiwiY1guRSI6IjIifSwibiI6eyJYUyI6
-W119LCJyMyI6eyJYUyI6W119LCJxaiI6eyJsRCI6WyJJZiJdLCJSZSI6WyJJZiJdLCJ6TSI6WyJJZiJd
-LCJiUSI6WyJJZiJdLCJjWCI6WyJJZiJdLCJsRC5FIjoiSWYiLCJSZS5FIjoiSWYifSwiR00iOnsiWFMi
-OltdfSwiYlEiOnsiY1giOlsiMSJdfSwiYUwiOnsiYlEiOlsiMSJdLCJjWCI6WyIxIl19LCJuSCI6eyJh
-TCI6WyIxIl0sImJRIjpbIjEiXSwiY1giOlsiMSJdLCJhTC5FIjoiMSIsImNYLkUiOiIxIn0sImE3Ijp7
-IkFuIjpbIjEiXX0sImkxIjp7ImNYIjpbIjIiXSwiY1guRSI6IjIifSwieHkiOnsiaTEiOlsiMSIsIjIi
-XSwiYlEiOlsiMiJdLCJjWCI6WyIyIl0sImNYLkUiOiIyIn0sIk1IIjp7IkFuIjpbIjIiXX0sImxKIjp7
-ImFMIjpbIjIiXSwiYlEiOlsiMiJdLCJjWCI6WyIyIl0sImFMLkUiOiIyIiwiY1guRSI6IjIifSwiVTUi
-OnsiY1giOlsiMSJdLCJjWC5FIjoiMSJ9LCJTTyI6eyJBbiI6WyIxIl19LCJBTSI6eyJjWCI6WyIxIl0s
-ImNYLkUiOiIxIn0sImQ1Ijp7IkFNIjpbIjEiXSwiYlEiOlsiMSJdLCJjWCI6WyIxIl0sImNYLkUiOiIx
-In0sIlUxIjp7IkFuIjpbIjEiXX0sIk1CIjp7ImJRIjpbIjEiXSwiY1giOlsiMSJdLCJjWC5FIjoiMSJ9
-LCJGdSI6eyJBbiI6WyIxIl19LCJ1NiI6eyJjWCI6WyIxIl0sImNYLkUiOiIxIn0sIkpCIjp7IkFuIjpb
-IjEiXX0sIncyIjp7ImxEIjpbIjEiXSwiUmUiOlsiMSJdLCJ6TSI6WyIxIl0sImJRIjpbIjEiXSwiY1gi
-OlsiMSJdfSwid3YiOnsiR0QiOltdfSwiUEQiOnsiR2oiOlsiMSIsIjIiXSwiUlUiOlsiMSIsIjIiXSwi
-UG4iOlsiMSIsIjIiXSwiS1AiOlsiMSIsIjIiXSwiWjAiOlsiMSIsIjIiXX0sIldVIjp7IlowIjpbIjEi
-LCIyIl19LCJMUCI6eyJXVSI6WyIxIiwiMiJdLCJaMCI6WyIxIiwiMiJdfSwiWFIiOnsiY1giOlsiMSJd
-LCJjWC5FIjoiMSJ9LCJMSSI6eyJ2USI6W119LCJXMCI6eyJYUyI6W119LCJheiI6eyJYUyI6W119LCJ2
-ViI6eyJYUyI6W119LCJ0ZSI6eyJSeiI6W119LCJYTyI6eyJHeiI6W119LCJUcCI6eyJFSCI6W119LCJs
-YyI6eyJFSCI6W119LCJ6eCI6eyJFSCI6W119LCJyVCI6eyJFSCI6W119LCJFcSI6eyJYUyI6W119LCJr
-WSI6eyJYUyI6W119LCJONSI6eyJZayI6WyIxIiwiMiJdLCJGbyI6WyIxIiwiMiJdLCJaMCI6WyIxIiwi
-MiJdLCJZay5LIjoiMSIsIllrLlYiOiIyIn0sImk1Ijp7ImJRIjpbIjEiXSwiY1giOlsiMSJdLCJjWC5F
-IjoiMSJ9LCJONiI6eyJBbiI6WyIxIl19LCJWUiI6eyJ3TCI6W10sInZYIjpbXX0sIkVLIjp7ImliIjpb
-XSwiT2QiOltdfSwiS1ciOnsiY1giOlsiaWIiXSwiY1guRSI6ImliIn0sIlBiIjp7IkFuIjpbImliIl19
-LCJ0USI6eyJPZCI6W119LCJ1biI6eyJjWCI6WyJPZCJdLCJjWC5FIjoiT2QifSwiU2QiOnsiQW4iOlsi
-T2QiXX0sIkVUIjp7IkFTIjpbXX0sIkxaIjp7IlhqIjpbIjEiXSwiRVQiOltdLCJBUyI6W119LCJEZyI6
-eyJsRCI6WyJDUCJdLCJYaiI6WyJDUCJdLCJ6TSI6WyJDUCJdLCJFVCI6W10sImJRIjpbIkNQIl0sIkFT
-IjpbXSwiY1giOlsiQ1AiXSwiU1UiOlsiQ1AiXSwibEQuRSI6IkNQIn0sIlBnIjp7ImxEIjpbIklmIl0s
-IlhqIjpbIklmIl0sInpNIjpbIklmIl0sIkVUIjpbXSwiYlEiOlsiSWYiXSwiQVMiOltdLCJjWCI6WyJJ
-ZiJdLCJTVSI6WyJJZiJdfSwieGoiOnsibEQiOlsiSWYiXSwiWGoiOlsiSWYiXSwiek0iOlsiSWYiXSwi
-RVQiOltdLCJiUSI6WyJJZiJdLCJBUyI6W10sImNYIjpbIklmIl0sIlNVIjpbIklmIl0sImxELkUiOiJJ
-ZiJ9LCJkRSI6eyJsRCI6WyJJZiJdLCJYaiI6WyJJZiJdLCJ6TSI6WyJJZiJdLCJFVCI6W10sImJRIjpb
-IklmIl0sIkFTIjpbXSwiY1giOlsiSWYiXSwiU1UiOlsiSWYiXSwibEQuRSI6IklmIn0sIlpBIjp7ImxE
-IjpbIklmIl0sIlhqIjpbIklmIl0sInpNIjpbIklmIl0sIkVUIjpbXSwiYlEiOlsiSWYiXSwiQVMiOltd
-LCJjWCI6WyJJZiJdLCJTVSI6WyJJZiJdLCJsRC5FIjoiSWYifSwiZFQiOnsibEQiOlsiSWYiXSwiWGoi
-OlsiSWYiXSwiek0iOlsiSWYiXSwiRVQiOltdLCJiUSI6WyJJZiJdLCJBUyI6W10sImNYIjpbIklmIl0s
-IlNVIjpbIklmIl0sImxELkUiOiJJZiJ9LCJQcSI6eyJsRCI6WyJJZiJdLCJYaiI6WyJJZiJdLCJ6TSI6
-WyJJZiJdLCJFVCI6W10sImJRIjpbIklmIl0sIkFTIjpbXSwiY1giOlsiSWYiXSwiU1UiOlsiSWYiXSwi
-bEQuRSI6IklmIn0sImVFIjp7ImxEIjpbIklmIl0sIlhqIjpbIklmIl0sInpNIjpbIklmIl0sIkVUIjpb
-XSwiYlEiOlsiSWYiXSwiQVMiOltdLCJjWCI6WyJJZiJdLCJTVSI6WyJJZiJdLCJsRC5FIjoiSWYifSwi
-VjYiOnsibEQiOlsiSWYiXSwibjYiOltdLCJYaiI6WyJJZiJdLCJ6TSI6WyJJZiJdLCJFVCI6W10sImJR
-IjpbIklmIl0sIkFTIjpbXSwiY1giOlsiSWYiXSwiU1UiOlsiSWYiXSwibEQuRSI6IklmIn0sImtTIjp7
-IlhTIjpbXX0sImlNIjp7IlhTIjpbXX0sIkdWIjp7IkFuIjpbIjEiXX0sInE0Ijp7ImNYIjpbIjEiXSwi
-Y1guRSI6IjEifSwiWmYiOnsiUGYiOlsiMSJdfSwidnMiOnsiYjgiOlsiMSJdfSwiQ3ciOnsiWFMiOltd
-fSwibTAiOnsiUW0iOltdfSwiSmkiOnsibTAiOltdLCJRbSI6W119LCJiNiI6eyJsZiI6WyIxIl0sInh1
-IjpbIjEiXSwiYlEiOlsiMSJdLCJjWCI6WyIxIl0sImxmLkUiOiIxIn0sImxtIjp7IkFuIjpbIjEiXX0s
-Im1XIjp7ImNYIjpbIjEiXX0sInV5Ijp7ImxEIjpbIjEiXSwiek0iOlsiMSJdLCJiUSI6WyIxIl0sImNY
-IjpbIjEiXX0sImlsIjp7IllrIjpbIjEiLCIyIl0sIlowIjpbIjEiLCIyIl19LCJZayI6eyJaMCI6WyIx
-IiwiMiJdfSwiUG4iOnsiWjAiOlsiMSIsIjIiXX0sIkdqIjp7IlJVIjpbIjEiLCIyIl0sIlBuIjpbIjEi
-LCIyIl0sIktQIjpbIjEiLCIyIl0sIlowIjpbIjEiLCIyIl19LCJWaiI6eyJsZiI6WyIxIl0sInh1Ijpb
-IjEiXSwiYlEiOlsiMSJdLCJjWCI6WyIxIl19LCJYdiI6eyJsZiI6WyIxIl0sInh1IjpbIjEiXSwiYlEi
-OlsiMSJdLCJjWCI6WyIxIl19LCJ1dyI6eyJZayI6WyJxVSIsIkAiXSwiWjAiOlsicVUiLCJAIl0sIllr
-LksiOiJxVSIsIllrLlYiOiJAIn0sImk4Ijp7ImFMIjpbInFVIl0sImJRIjpbInFVIl0sImNYIjpbInFV
-Il0sImFMLkUiOiJxVSIsImNYLkUiOiJxVSJ9LCJDViI6eyJVayI6WyJ6TTxJZj4iLCJxVSJdLCJVay5T
-Ijoiek08SWY+In0sIlU4Ijp7IndJIjpbInpNPElmPiIsInFVIl19LCJaaSI6eyJVayI6WyJxVSIsInpN
-PElmPiJdfSwiVWQiOnsiWFMiOltdfSwiSzgiOnsiWFMiOltdfSwiYnkiOnsiVWsiOlsiTWg/IiwicVUi
-XSwiVWsuUyI6Ik1oPyJ9LCJvaiI6eyJ3SSI6WyJNaD8iLCJxVSJdfSwiTXgiOnsid0kiOlsicVUiLCJN
-aD8iXX0sInU1Ijp7IlVrIjpbInFVIiwiek08SWY+Il0sIlVrLlMiOiJxVSJ9LCJFMyI6eyJ3SSI6WyJx
-VSIsInpNPElmPiJdfSwiR1kiOnsid0kiOlsiek08SWY+IiwicVUiXX0sIkNQIjp7IlpaIjpbXX0sIklm
-Ijp7IlpaIjpbXX0sInpNIjp7ImJRIjpbIjEiXSwiY1giOlsiMSJdfSwiaWIiOnsiT2QiOltdfSwieHUi
-OnsiYlEiOlsiMSJdLCJjWCI6WyIxIl19LCJxVSI6eyJ2WCI6W119LCJDNiI6eyJYUyI6W119LCJFeiI6
-eyJYUyI6W119LCJGIjp7IlhTIjpbXX0sInUiOnsiWFMiOltdfSwiYkoiOnsiWFMiOltdfSwiZVkiOnsi
-WFMiOltdfSwibXAiOnsiWFMiOltdfSwidWIiOnsiWFMiOltdfSwiZHMiOnsiWFMiOltdfSwibGoiOnsi
-WFMiOltdfSwiVVYiOnsiWFMiOltdfSwiazUiOnsiWFMiOltdfSwiS1kiOnsiWFMiOltdfSwiYyI6eyJY
-UyI6W119LCJDRCI6eyJSeiI6W119LCJhRSI6eyJSeiI6W119LCJaZCI6eyJHeiI6W119LCJSbiI6eyJC
-TCI6W119LCJEbiI6eyJpRCI6W119LCJVZiI6eyJpRCI6W119LCJxZSI6eyJpRCI6W119LCJxRSI6eyJj
-diI6W10sInVIIjpbXSwiRDAiOltdfSwiR2giOnsiY3YiOltdLCJ1SCI6W10sIkQwIjpbXX0sImZZIjp7
-ImN2IjpbXSwidUgiOltdLCJEMCI6W119LCJuQiI6eyJjdiI6W10sInVIIjpbXSwiRDAiOltdfSwiUVAi
-OnsiY3YiOltdLCJ1SCI6W10sIkQwIjpbXX0sIm54Ijp7InVIIjpbXSwiRDAiOltdfSwiUUYiOnsidUgi
-OltdLCJEMCI6W119LCJJQiI6eyJ0biI6WyJaWiJdfSwid3oiOnsibEQiOlsiMSJdLCJ6TSI6WyIxIl0s
-ImJRIjpbIjEiXSwiY1giOlsiMSJdLCJsRC5FIjoiMSJ9LCJjdiI6eyJ1SCI6W10sIkQwIjpbXX0sImhI
-Ijp7IkF6IjpbXX0sImg0Ijp7ImN2IjpbXSwidUgiOltdLCJEMCI6W119LCJWYiI6eyJ1SCI6W10sIkQw
-IjpbXX0sImZKIjp7IkQwIjpbXX0sIndhIjp7IkQwIjpbXX0sIkFqIjp7ImVhIjpbXX0sImU3Ijp7ImxE
-IjpbInVIIl0sInpNIjpbInVIIl0sImJRIjpbInVIIl0sImNYIjpbInVIIl0sImxELkUiOiJ1SCJ9LCJ1
-SCI6eyJEMCI6W119LCJCSCI6eyJsRCI6WyJ1SCJdLCJHbSI6WyJ1SCJdLCJ6TSI6WyJ1SCJdLCJYaiI6
-WyJ1SCJdLCJiUSI6WyJ1SCJdLCJjWCI6WyJ1SCJdLCJsRC5FIjoidUgiLCJHbS5FIjoidUgifSwiU04i
-OnsiY3YiOltdLCJ1SCI6W10sIkQwIjpbXX0sImV3Ijp7ImVhIjpbXX0sImxwIjp7ImN2IjpbXSwidUgi
-OltdLCJEMCI6W119LCJUYiI6eyJjdiI6W10sInVIIjpbXSwiRDAiOltdfSwiSXYiOnsiY3YiOltdLCJ1
-SCI6W10sIkQwIjpbXX0sIldQIjp7ImN2IjpbXSwidUgiOltdLCJEMCI6W119LCJ5WSI6eyJjdiI6W10s
-InVIIjpbXSwiRDAiOltdfSwidzYiOnsiZWEiOltdfSwiSzUiOnsidjYiOltdLCJEMCI6W119LCJDbSI6
-eyJEMCI6W119LCJDUSI6eyJ1SCI6W10sIkQwIjpbXX0sInc0Ijp7InRuIjpbIlpaIl19LCJyaCI6eyJs
-RCI6WyJ1SCJdLCJHbSI6WyJ1SCJdLCJ6TSI6WyJ1SCJdLCJYaiI6WyJ1SCJdLCJiUSI6WyJ1SCJdLCJj
-WCI6WyJ1SCJdLCJsRC5FIjoidUgiLCJHbS5FIjoidUgifSwiY2YiOnsiWWsiOlsicVUiLCJxVSJdLCJa
-MCI6WyJxVSIsInFVIl19LCJpNyI6eyJZayI6WyJxVSIsInFVIl0sIlowIjpbInFVIiwicVUiXSwiWWsu
-SyI6InFVIiwiWWsuViI6InFVIn0sIlN5Ijp7IllrIjpbInFVIiwicVUiXSwiWjAiOlsicVUiLCJxVSJd
-LCJZay5LIjoicVUiLCJZay5WIjoicVUifSwiSTQiOnsibGYiOlsicVUiXSwieHUiOlsicVUiXSwiYlEi
-OlsicVUiXSwiY1giOlsicVUiXSwibGYuRSI6InFVIn0sIlJPIjp7InFoIjpbIjEiXX0sImV1Ijp7IlJP
-IjpbIjEiXSwicWgiOlsiMSJdfSwieEMiOnsiTU8iOlsiMSJdfSwiSlEiOnsia0YiOltdfSwidkQiOnsi
-a0YiOltdfSwibTYiOnsia0YiOltdfSwiY3QiOnsia0YiOltdfSwiT3ciOnsia0YiOltdfSwiVzkiOnsi
-QW4iOlsiMSJdfSwiZFciOnsidjYiOltdLCJEMCI6W119LCJtayI6eyJ5MCI6W119LCJLbyI6eyJvbiI6
-W119LCJBcyI6eyJsZiI6WyJxVSJdLCJ4dSI6WyJxVSJdLCJiUSI6WyJxVSJdLCJjWCI6WyJxVSJdfSwi
-cjciOnsiRTQiOltdfSwiVHoiOnsibEQiOlsiMSJdLCJ6TSI6WyIxIl0sImJRIjpbIjEiXSwiRTQiOltd
-LCJjWCI6WyIxIl0sImxELkUiOiIxIn0sIm5kIjp7ImhpIjpbXSwiY3YiOltdLCJ1SCI6W10sIkQwIjpb
-XX0sIktlIjp7ImxmIjpbInFVIl0sInh1IjpbInFVIl0sImJRIjpbInFVIl0sImNYIjpbInFVIl0sImxm
-LkUiOiJxVSJ9LCJoaSI6eyJjdiI6W10sInVIIjpbXSwiRDAiOltdfSwiWEEiOnsia0YiOltdfSwidnQi
-OnsiRDgiOltdfSwiY0QiOnsiRDgiOltdfSwiZHYiOnsiUnoiOltdfSwiT0YiOnsiZnYiOltdfSwicnUi
-OnsiZnYiOltdfSwiSVYiOnsiZnYiOltdfSwibjYiOnsiek0iOlsiSWYiXSwiYlEiOlsiSWYiXSwiY1gi
-OlsiSWYiXSwiQVMiOltdfX0nKSkKSC5GRih2LnR5cGVVbml2ZXJzZSxKU09OLnBhcnNlKCd7IncyIjox
-LCJRQyI6MiwiTFoiOjEsImtUIjoyLCJtVyI6MSwidXkiOjEsImlsIjoyLCJWaiI6MSwiWHYiOjEsIm5Z
-IjoxLCJXWSI6MSwicFIiOjEsImNvIjoxfScpKQp2YXIgdT17bDoiQ2Fubm90IGV4dHJhY3QgYSBmaWxl
-IHBhdGggZnJvbSBhIFVSSSB3aXRoIGEgZnJhZ21lbnQgY29tcG9uZW50IixpOiJDYW5ub3QgZXh0cmFj
-dCBhIGZpbGUgcGF0aCBmcm9tIGEgVVJJIHdpdGggYSBxdWVyeSBjb21wb25lbnQiLGo6IkNhbm5vdCBl
-eHRyYWN0IGEgbm9uLVdpbmRvd3MgZmlsZSBwYXRoIGZyb20gYSBmaWxlIFVSSSB3aXRoIGFuIGF1dGhv
-cml0eSIsZzoiYG51bGxgIGVuY291bnRlcmVkIGFzIHRoZSByZXN1bHQgZnJvbSBleHByZXNzaW9uIHdp
-dGggdHlwZSBgTmV2ZXJgLiIsZDoiYXJlYS1hbmFseXplcixhbmFseXplci1ubmJkLW1pZ3JhdGlvbix0
-eXBlLWJ1ZyJ9CnZhciB0PShmdW5jdGlvbiBydGlpKCl7dmFyIHM9SC5OMApyZXR1cm57bjpzKCJDdyIp
-LGNSOnMoIm5CIiksdzpzKCJBeiIpLHA6cygiUVAiKSxnRjpzKCJQRDxHRCxAPiIpLGI6cygiYlE8QD4i
-KSxoOnMoImN2IikscjpzKCJYUyIpLEI6cygiZWEiKSxhUzpzKCJEMCIpLGc4OnMoIlJ6IiksYzg6cygi
-aEgiKSxZOnMoIkVIIiksZDpzKCJiODxAPiIpLEk6cygiU2ciKSxvOnMoInZRIiksZWg6cygiY1g8dUg+
-IiksUTpzKCJjWDxxVT4iKSx1OnMoImNYPEA+IiksdjpzKCJqZDxrRj4iKSxzOnMoImpkPHFVPiIpLGdO
-OnMoImpkPG42PiIpLHg6cygiamQ8QD4iKSxhOnMoImpkPElmPiIpLGQ3OnMoImpkPFNlKj4iKSxoNDpz
-KCJqZDxqOCo+IiksRzpzKCJqZDxaMDxxVSosTWgqPio+IiksY1E6cygiamQ8RDgqPiIpLGk6cygiamQ8
-cVUqPiIpLGFBOnMoImpkPHlEKj4iKSxhSjpzKCJqZDx3Yio+IiksVjpzKCJqZDxJZio+IiksZDQ6cygi
-amQ8cVU/PiIpLFQ6cygid2UiKSxlSDpzKCJ2bSIpLEQ6cygiYzUiKSxhVTpzKCJYajxAPiIpLGFtOnMo
-IlR6PEA+IiksZW86cygiTjU8R0QsQD4iKSxkejpzKCJoRiIpLEU6cygiek08cVU+IiksajpzKCJ6TTxA
-PiIpLEw6cygiek08SWY+IiksSjpzKCJaMDxxVSxxVT4iKSxmOnMoIlowPEAsQD4iKSxkbzpzKCJsSjxx
-VSxAPiIpLGZqOnMoImxKPHFVKixxVT4iKSxkRTpzKCJFVCIpLGJtOnMoIlY2IiksQTpzKCJ1SCIpLGY2
-OnMoImtGIiksUDpzKCJjOCIpLEs6cygiTWgiKSxxOnMoInRuPFpaPiIpLGZ2OnMoIndMIiksZXc6cygi
-bmQiKSxDOnMoInh1PHFVPiIpLGw6cygiR3oiKSxOOnMoInFVIiksZDA6cygicVUocVUqKSIpLGc3OnMo
-ImhpIiksZm86cygiR0QiKSxhVzpzKCJ5WSIpLGFrOnMoIkFTIiksZ2M6cygibjYiKSxiSjpzKCJrZCIp
-LGR3OnMoIkdqPHFVLHFVPiIpLGREOnMoImlEIiksZUo6cygidTY8cVU+IiksZzQ6cygiSzUiKSxjaTpz
-KCJ2NiIpLGcyOnMoIkNtIiksYkM6cygiWmY8ZkoqPiIpLGg5OnMoIkNRIiksYWM6cygiZTciKSxrOnMo
-ImV1PEFqKj4iKSxSOnMoInd6PGN2Kj4iKSxjOnMoInZzPEA+IiksZko6cygidnM8SWY+IiksZ1Y6cygi
-dnM8ZkoqPiIpLGNyOnMoIkpRIikseTpzKCJhMiIpLGFsOnMoImEyKE1oKSIpLGdSOnMoIkNQIiksejpz
-KCJAIiksZk86cygiQCgpIiksYkk6cygiQChNaCkiKSxhZzpzKCJAKE1oLEd6KSIpLGJVOnMoIkAoeHU8
-cVU+KSIpLGRPOnMoIkAocVUpIiksYjg6cygiQChALEApIiksUzpzKCJJZiIpLGRkOnMoIkdoKiIpLGc6
-cygiY3YqIiksYUw6cygiZWEqIiksYVg6cygiTEwqIiksZkU6cygiSDcqIiksVTpzKCJjWDxAPioiKSxk
-SDpzKCJFNCoiKSxmSzpzKCJ6TTxAPioiKSxkXzpzKCJ6TTxqOCo+KiIpLGRwOnMoInpNPFowPHFVKixN
-aCo+Kj4qIiksbTpzKCJ6TTxNaCo+KiIpLGF3OnMoIlowPEAsQD4qIiksdDpzKCJaMDxxVSosTWgqPioi
-KSxPOnMoIkFqKiIpLGNGOnMoIjAmKiIpLF86cygiTWgqIiksZVE6cygiZXcqIiksWDpzKCJxVSoiKSxj
-aDpzKCJEMD8iKSxiRzpzKCJiODxjOD4/IiksYms6cygiek08cVU+PyIpLGJNOnMoInpNPEA+PyIpLGNa
-OnMoIlowPHFVLHFVPj8iKSxjOTpzKCJaMDxxVSxAPj8iKSxXOnMoIk1oPyIpLEY6cygiRmU8QCxAPj8i
-KSxlOnMoImJuPyIpLGI3OnMoImEyKE1oKT8iKSxidzpzKCJAKGVhKT8iKSxmVjpzKCJNaD8oTWg/LE1o
-Pyk/IiksZEE6cygiTWg/KEApPyIpLFo6cygifigpPyIpLGViOnMoIn4oZXcqKT8iKSxkaTpzKCJaWiIp
-LEg6cygifiIpLE06cygifigpIiksZUE6cygifihxVSxxVSkiKSxjQTpzKCJ+KHFVLEApIil9fSkoKTso
-ZnVuY3Rpb24gY29uc3RhbnRzKCl7dmFyIHM9aHVua0hlbHBlcnMubWFrZUNvbnN0TGlzdApDLnhuPVcu
-R2gucHJvdG90eXBlCkMuUlk9Vy5RUC5wcm90b3R5cGUKQy5tSD1XLmFlLnByb3RvdHlwZQpDLkJaPVcu
-VmIucHJvdG90eXBlCkMuRHQ9Vy5mSi5wcm90b3R5cGUKQy5Paz1KLkd2LnByb3RvdHlwZQpDLk5tPUou
-amQucHJvdG90eXBlCkMuam49Si5iVS5wcm90b3R5cGUKQy5qTj1KLndlLnByb3RvdHlwZQpDLkNEPUou
-cUkucHJvdG90eXBlCkMueEI9Si5Eci5wcm90b3R5cGUKQy5ERz1KLmM1LnByb3RvdHlwZQpDLkV4PVcu
-dTgucHJvdG90eXBlCkMuTkE9SC5WNi5wcm90b3R5cGUKQy50NT1XLkJILnByb3RvdHlwZQpDLkx0PVcu
-U04ucHJvdG90eXBlCkMuWlE9Si5pQy5wcm90b3R5cGUKQy5JZT1XLlRiLnByb3RvdHlwZQpDLnZCPUou
-a2QucHJvdG90eXBlCkMub2w9Vy5LNS5wcm90b3R5cGUKQy55OD1uZXcgUC5VOCgpCkMuaDk9bmV3IFAu
-Q1YoKQpDLkd3PW5ldyBILkZ1KEguTjAoIkZ1PGM4PiIpKQpDLk80PWZ1bmN0aW9uIGdldFRhZ0ZhbGxi
-YWNrKG8pIHsKICB2YXIgcyA9IE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmcuY2FsbChvKTsKICByZXR1
-cm4gcy5zdWJzdHJpbmcoOCwgcy5sZW5ndGggLSAxKTsKfQpDLllxPWZ1bmN0aW9uKCkgewogIHZhciB0
-b1N0cmluZ0Z1bmN0aW9uID0gT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZzsKICBmdW5jdGlvbiBnZXRU
-YWcobykgewogICAgdmFyIHMgPSB0b1N0cmluZ0Z1bmN0aW9uLmNhbGwobyk7CiAgICByZXR1cm4gcy5z
-dWJzdHJpbmcoOCwgcy5sZW5ndGggLSAxKTsKICB9CiAgZnVuY3Rpb24gZ2V0VW5rbm93blRhZyhvYmpl
-Y3QsIHRhZykgewogICAgaWYgKC9eSFRNTFtBLVpdLipFbGVtZW50JC8udGVzdCh0YWcpKSB7CiAgICAg
-IHZhciBuYW1lID0gdG9TdHJpbmdGdW5jdGlvbi5jYWxsKG9iamVjdCk7CiAgICAgIGlmIChuYW1lID09
-ICJbb2JqZWN0IE9iamVjdF0iKSByZXR1cm4gbnVsbDsKICAgICAgcmV0dXJuICJIVE1MRWxlbWVudCI7
-CiAgICB9CiAgfQogIGZ1bmN0aW9uIGdldFVua25vd25UYWdHZW5lcmljQnJvd3NlcihvYmplY3QsIHRh
-ZykgewogICAgaWYgKHNlbGYuSFRNTEVsZW1lbnQgJiYgb2JqZWN0IGluc3RhbmNlb2YgSFRNTEVsZW1l
-bnQpIHJldHVybiAiSFRNTEVsZW1lbnQiOwogICAgcmV0dXJuIGdldFVua25vd25UYWcob2JqZWN0LCB0
-YWcpOwogIH0KICBmdW5jdGlvbiBwcm90b3R5cGVGb3JUYWcodGFnKSB7CiAgICBpZiAodHlwZW9mIHdp
-bmRvdyA9PSAidW5kZWZpbmVkIikgcmV0dXJuIG51bGw7CiAgICBpZiAodHlwZW9mIHdpbmRvd1t0YWdd
-ID09ICJ1bmRlZmluZWQiKSByZXR1cm4gbnVsbDsKICAgIHZhciBjb25zdHJ1Y3RvciA9IHdpbmRvd1t0
-YWddOwogICAgaWYgKHR5cGVvZiBjb25zdHJ1Y3RvciAhPSAiZnVuY3Rpb24iKSByZXR1cm4gbnVsbDsK
-ICAgIHJldHVybiBjb25zdHJ1Y3Rvci5wcm90b3R5cGU7CiAgfQogIGZ1bmN0aW9uIGRpc2NyaW1pbmF0
-b3IodGFnKSB7IHJldHVybiBudWxsOyB9CiAgdmFyIGlzQnJvd3NlciA9IHR5cGVvZiBuYXZpZ2F0b3Ig
-PT0gIm9iamVjdCI7CiAgcmV0dXJuIHsKICAgIGdldFRhZzogZ2V0VGFnLAogICAgZ2V0VW5rbm93blRh
-ZzogaXNCcm93c2VyID8gZ2V0VW5rbm93blRhZ0dlbmVyaWNCcm93c2VyIDogZ2V0VW5rbm93blRhZywK
-ICAgIHByb3RvdHlwZUZvclRhZzogcHJvdG90eXBlRm9yVGFnLAogICAgZGlzY3JpbWluYXRvcjogZGlz
-Y3JpbWluYXRvciB9Owp9CkMud2I9ZnVuY3Rpb24oZ2V0VGFnRmFsbGJhY2spIHsKICByZXR1cm4gZnVu
-Y3Rpb24oaG9va3MpIHsKICAgIGlmICh0eXBlb2YgbmF2aWdhdG9yICE9ICJvYmplY3QiKSByZXR1cm4g
-aG9va3M7CiAgICB2YXIgdWEgPSBuYXZpZ2F0b3IudXNlckFnZW50OwogICAgaWYgKHVhLmluZGV4T2Yo
-IkR1bXBSZW5kZXJUcmVlIikgPj0gMCkgcmV0dXJuIGhvb2tzOwogICAgaWYgKHVhLmluZGV4T2YoIkNo
-cm9tZSIpID49IDApIHsKICAgICAgZnVuY3Rpb24gY29uZmlybShwKSB7CiAgICAgICAgcmV0dXJuIHR5
-cGVvZiB3aW5kb3cgPT0gIm9iamVjdCIgJiYgd2luZG93W3BdICYmIHdpbmRvd1twXS5uYW1lID09IHA7
-CiAgICAgIH0KICAgICAgaWYgKGNvbmZpcm0oIldpbmRvdyIpICYmIGNvbmZpcm0oIkhUTUxFbGVtZW50
-IikpIHJldHVybiBob29rczsKICAgIH0KICAgIGhvb2tzLmdldFRhZyA9IGdldFRhZ0ZhbGxiYWNrOwog
-IH07Cn0KQy5LVT1mdW5jdGlvbihob29rcykgewogIGlmICh0eXBlb2YgZGFydEV4cGVyaW1lbnRhbEZp
-eHVwR2V0VGFnICE9ICJmdW5jdGlvbiIpIHJldHVybiBob29rczsKICBob29rcy5nZXRUYWcgPSBkYXJ0
-RXhwZXJpbWVudGFsRml4dXBHZXRUYWcoaG9va3MuZ2V0VGFnKTsKfQpDLmZRPWZ1bmN0aW9uKGhvb2tz
-KSB7CiAgdmFyIGdldFRhZyA9IGhvb2tzLmdldFRhZzsKICB2YXIgcHJvdG90eXBlRm9yVGFnID0gaG9v
-a3MucHJvdG90eXBlRm9yVGFnOwogIGZ1bmN0aW9uIGdldFRhZ0ZpeGVkKG8pIHsKICAgIHZhciB0YWcg
-PSBnZXRUYWcobyk7CiAgICBpZiAodGFnID09ICJEb2N1bWVudCIpIHsKICAgICAgaWYgKCEhby54bWxW
-ZXJzaW9uKSByZXR1cm4gIiFEb2N1bWVudCI7CiAgICAgIHJldHVybiAiIUhUTUxEb2N1bWVudCI7CiAg
-ICB9CiAgICByZXR1cm4gdGFnOwogIH0KICBmdW5jdGlvbiBwcm90b3R5cGVGb3JUYWdGaXhlZCh0YWcp
-IHsKICAgIGlmICh0YWcgPT0gIkRvY3VtZW50IikgcmV0dXJuIG51bGw7CiAgICByZXR1cm4gcHJvdG90
-eXBlRm9yVGFnKHRhZyk7CiAgfQogIGhvb2tzLmdldFRhZyA9IGdldFRhZ0ZpeGVkOwogIGhvb2tzLnBy
-b3RvdHlwZUZvclRhZyA9IHByb3RvdHlwZUZvclRhZ0ZpeGVkOwp9CkMuZGs9ZnVuY3Rpb24oaG9va3Mp
-IHsKICB2YXIgdXNlckFnZW50ID0gdHlwZW9mIG5hdmlnYXRvciA9PSAib2JqZWN0IiA/IG5hdmlnYXRv
-ci51c2VyQWdlbnQgOiAiIjsKICBpZiAodXNlckFnZW50LmluZGV4T2YoIkZpcmVmb3giKSA9PSAtMSkg
-cmV0dXJuIGhvb2tzOwogIHZhciBnZXRUYWcgPSBob29rcy5nZXRUYWc7CiAgdmFyIHF1aWNrTWFwID0g
-ewogICAgIkJlZm9yZVVubG9hZEV2ZW50IjogIkV2ZW50IiwKICAgICJEYXRhVHJhbnNmZXIiOiAiQ2xp
-cGJvYXJkIiwKICAgICJHZW9HZW9sb2NhdGlvbiI6ICJHZW9sb2NhdGlvbiIsCiAgICAiTG9jYXRpb24i
-OiAiIUxvY2F0aW9uIiwKICAgICJXb3JrZXJNZXNzYWdlRXZlbnQiOiAiTWVzc2FnZUV2ZW50IiwKICAg
-ICJYTUxEb2N1bWVudCI6ICIhRG9jdW1lbnQifTsKICBmdW5jdGlvbiBnZXRUYWdGaXJlZm94KG8pIHsK
-ICAgIHZhciB0YWcgPSBnZXRUYWcobyk7CiAgICByZXR1cm4gcXVpY2tNYXBbdGFnXSB8fCB0YWc7CiAg
-fQogIGhvb2tzLmdldFRhZyA9IGdldFRhZ0ZpcmVmb3g7Cn0KQy54aT1mdW5jdGlvbihob29rcykgewog
-IHZhciB1c2VyQWdlbnQgPSB0eXBlb2YgbmF2aWdhdG9yID09ICJvYmplY3QiID8gbmF2aWdhdG9yLnVz
-ZXJBZ2VudCA6ICIiOwogIGlmICh1c2VyQWdlbnQuaW5kZXhPZigiVHJpZGVudC8iKSA9PSAtMSkgcmV0
-dXJuIGhvb2tzOwogIHZhciBnZXRUYWcgPSBob29rcy5nZXRUYWc7CiAgdmFyIHF1aWNrTWFwID0gewog
-ICAgIkJlZm9yZVVubG9hZEV2ZW50IjogIkV2ZW50IiwKICAgICJEYXRhVHJhbnNmZXIiOiAiQ2xpcGJv
-YXJkIiwKICAgICJIVE1MRERFbGVtZW50IjogIkhUTUxFbGVtZW50IiwKICAgICJIVE1MRFRFbGVtZW50
-IjogIkhUTUxFbGVtZW50IiwKICAgICJIVE1MUGhyYXNlRWxlbWVudCI6ICJIVE1MRWxlbWVudCIsCiAg
-ICAiUG9zaXRpb24iOiAiR2VvcG9zaXRpb24iCiAgfTsKICBmdW5jdGlvbiBnZXRUYWdJRShvKSB7CiAg
-ICB2YXIgdGFnID0gZ2V0VGFnKG8pOwogICAgdmFyIG5ld1RhZyA9IHF1aWNrTWFwW3RhZ107CiAgICBp
-ZiAobmV3VGFnKSByZXR1cm4gbmV3VGFnOwogICAgaWYgKHRhZyA9PSAiT2JqZWN0IikgewogICAgICBp
-ZiAod2luZG93LkRhdGFWaWV3ICYmIChvIGluc3RhbmNlb2Ygd2luZG93LkRhdGFWaWV3KSkgcmV0dXJu
-ICJEYXRhVmlldyI7CiAgICB9CiAgICByZXR1cm4gdGFnOwogIH0KICBmdW5jdGlvbiBwcm90b3R5cGVG
-b3JUYWdJRSh0YWcpIHsKICAgIHZhciBjb25zdHJ1Y3RvciA9IHdpbmRvd1t0YWddOwogICAgaWYgKGNv
-bnN0cnVjdG9yID09IG51bGwpIHJldHVybiBudWxsOwogICAgcmV0dXJuIGNvbnN0cnVjdG9yLnByb3Rv
-dHlwZTsKICB9CiAgaG9va3MuZ2V0VGFnID0gZ2V0VGFnSUU7CiAgaG9va3MucHJvdG90eXBlRm9yVGFn
-ID0gcHJvdG90eXBlRm9yVGFnSUU7Cn0KQy5pNz1mdW5jdGlvbihob29rcykgeyByZXR1cm4gaG9va3M7
-IH0KCkMuQ3Q9bmV3IFAuYnkoKQpDLkVxPW5ldyBQLms1KCkKQy54TT1uZXcgUC51NSgpCkMuUWs9bmV3
-IFAuRTMoKQpDLk52PW5ldyBILmtyKCkKQy5OVT1uZXcgUC5KaSgpCkMucGQ9bmV3IFAuWmQoKQpDLkFk
-PW5ldyBNLkg3KDAsIkhpbnRBY3Rpb25LaW5kLmFkZE51bGxhYmxlSGludCIpCkMubmU9bmV3IE0uSDco
-MSwiSGludEFjdGlvbktpbmQuYWRkTm9uTnVsbGFibGVIaW50IikKQy5teT1uZXcgTS5INygyLCJIaW50
-QWN0aW9uS2luZC5jaGFuZ2VUb051bGxhYmxlSGludCIpCkMucng9bmV3IE0uSDcoMywiSGludEFjdGlv
-bktpbmQuY2hhbmdlVG9Ob25OdWxsYWJsZUhpbnQiKQpDLndWPW5ldyBNLkg3KDQsIkhpbnRBY3Rpb25L
-aW5kLnJlbW92ZU51bGxhYmxlSGludCIpCkMuZlI9bmV3IE0uSDcoNSwiSGludEFjdGlvbktpbmQucmVt
-b3ZlTm9uTnVsbGFibGVIaW50IikKQy5BMz1uZXcgUC5NeChudWxsKQpDLm5YPW5ldyBQLm9qKG51bGwp
-CkMuY3c9bmV3IEwuR2IoMCwiVW5pdE1pZ3JhdGlvblN0YXR1cy5hbHJlYWR5TWlncmF0ZWQiKQpDLmRj
-PW5ldyBMLkdiKDEsIlVuaXRNaWdyYXRpb25TdGF0dXMuaW5kZXRlcm1pbmF0ZSIpCkMuV0Q9bmV3IEwu
-R2IoMiwiVW5pdE1pZ3JhdGlvblN0YXR1cy5taWdyYXRpbmciKQpDLlhqPW5ldyBMLkdiKDMsIlVuaXRN
-aWdyYXRpb25TdGF0dXMub3B0aW5nT3V0IikKQy5sMD1ILlZNKHMoW0MuY3csQy5kYyxDLldELEMuWGpd
-KSxILk4wKCJqZDxHYio+IikpCkMuYWs9SC5WTShzKFswLDAsMzI3NzYsMzM3OTIsMSwxMDI0MCwwLDBd
-KSx0LlYpCkMuY209SC5WTShzKFsiKjo6Y2xhc3MiLCIqOjpkaXIiLCIqOjpkcmFnZ2FibGUiLCIqOjpo
-aWRkZW4iLCIqOjppZCIsIio6OmluZXJ0IiwiKjo6aXRlbXByb3AiLCIqOjppdGVtcmVmIiwiKjo6aXRl
-bXNjb3BlIiwiKjo6bGFuZyIsIio6OnNwZWxsY2hlY2siLCIqOjp0aXRsZSIsIio6OnRyYW5zbGF0ZSIs
-IkE6OmFjY2Vzc2tleSIsIkE6OmNvb3JkcyIsIkE6OmhyZWZsYW5nIiwiQTo6bmFtZSIsIkE6OnNoYXBl
-IiwiQTo6dGFiaW5kZXgiLCJBOjp0YXJnZXQiLCJBOjp0eXBlIiwiQVJFQTo6YWNjZXNza2V5IiwiQVJF
-QTo6YWx0IiwiQVJFQTo6Y29vcmRzIiwiQVJFQTo6bm9ocmVmIiwiQVJFQTo6c2hhcGUiLCJBUkVBOjp0
-YWJpbmRleCIsIkFSRUE6OnRhcmdldCIsIkFVRElPOjpjb250cm9scyIsIkFVRElPOjpsb29wIiwiQVVE
-SU86Om1lZGlhZ3JvdXAiLCJBVURJTzo6bXV0ZWQiLCJBVURJTzo6cHJlbG9hZCIsIkJETzo6ZGlyIiwi
-Qk9EWTo6YWxpbmsiLCJCT0RZOjpiZ2NvbG9yIiwiQk9EWTo6bGluayIsIkJPRFk6OnRleHQiLCJCT0RZ
-Ojp2bGluayIsIkJSOjpjbGVhciIsIkJVVFRPTjo6YWNjZXNza2V5IiwiQlVUVE9OOjpkaXNhYmxlZCIs
-IkJVVFRPTjo6bmFtZSIsIkJVVFRPTjo6dGFiaW5kZXgiLCJCVVRUT046OnR5cGUiLCJCVVRUT046OnZh
-bHVlIiwiQ0FOVkFTOjpoZWlnaHQiLCJDQU5WQVM6OndpZHRoIiwiQ0FQVElPTjo6YWxpZ24iLCJDT0w6
-OmFsaWduIiwiQ09MOjpjaGFyIiwiQ09MOjpjaGFyb2ZmIiwiQ09MOjpzcGFuIiwiQ09MOjp2YWxpZ24i
-LCJDT0w6OndpZHRoIiwiQ09MR1JPVVA6OmFsaWduIiwiQ09MR1JPVVA6OmNoYXIiLCJDT0xHUk9VUDo6
-Y2hhcm9mZiIsIkNPTEdST1VQOjpzcGFuIiwiQ09MR1JPVVA6OnZhbGlnbiIsIkNPTEdST1VQOjp3aWR0
-aCIsIkNPTU1BTkQ6OmNoZWNrZWQiLCJDT01NQU5EOjpjb21tYW5kIiwiQ09NTUFORDo6ZGlzYWJsZWQi
-LCJDT01NQU5EOjpsYWJlbCIsIkNPTU1BTkQ6OnJhZGlvZ3JvdXAiLCJDT01NQU5EOjp0eXBlIiwiREFU
-QTo6dmFsdWUiLCJERUw6OmRhdGV0aW1lIiwiREVUQUlMUzo6b3BlbiIsIkRJUjo6Y29tcGFjdCIsIkRJ
-Vjo6YWxpZ24iLCJETDo6Y29tcGFjdCIsIkZJRUxEU0VUOjpkaXNhYmxlZCIsIkZPTlQ6OmNvbG9yIiwi
-Rk9OVDo6ZmFjZSIsIkZPTlQ6OnNpemUiLCJGT1JNOjphY2NlcHQiLCJGT1JNOjphdXRvY29tcGxldGUi
-LCJGT1JNOjplbmN0eXBlIiwiRk9STTo6bWV0aG9kIiwiRk9STTo6bmFtZSIsIkZPUk06Om5vdmFsaWRh
-dGUiLCJGT1JNOjp0YXJnZXQiLCJGUkFNRTo6bmFtZSIsIkgxOjphbGlnbiIsIkgyOjphbGlnbiIsIkgz
-OjphbGlnbiIsIkg0OjphbGlnbiIsIkg1OjphbGlnbiIsIkg2OjphbGlnbiIsIkhSOjphbGlnbiIsIkhS
-Ojpub3NoYWRlIiwiSFI6OnNpemUiLCJIUjo6d2lkdGgiLCJIVE1MOjp2ZXJzaW9uIiwiSUZSQU1FOjph
-bGlnbiIsIklGUkFNRTo6ZnJhbWVib3JkZXIiLCJJRlJBTUU6OmhlaWdodCIsIklGUkFNRTo6bWFyZ2lu
-aGVpZ2h0IiwiSUZSQU1FOjptYXJnaW53aWR0aCIsIklGUkFNRTo6d2lkdGgiLCJJTUc6OmFsaWduIiwi
-SU1HOjphbHQiLCJJTUc6OmJvcmRlciIsIklNRzo6aGVpZ2h0IiwiSU1HOjpoc3BhY2UiLCJJTUc6Omlz
-bWFwIiwiSU1HOjpuYW1lIiwiSU1HOjp1c2VtYXAiLCJJTUc6OnZzcGFjZSIsIklNRzo6d2lkdGgiLCJJ
-TlBVVDo6YWNjZXB0IiwiSU5QVVQ6OmFjY2Vzc2tleSIsIklOUFVUOjphbGlnbiIsIklOUFVUOjphbHQi
-LCJJTlBVVDo6YXV0b2NvbXBsZXRlIiwiSU5QVVQ6OmF1dG9mb2N1cyIsIklOUFVUOjpjaGVja2VkIiwi
-SU5QVVQ6OmRpc2FibGVkIiwiSU5QVVQ6OmlucHV0bW9kZSIsIklOUFVUOjppc21hcCIsIklOUFVUOjps
-aXN0IiwiSU5QVVQ6Om1heCIsIklOUFVUOjptYXhsZW5ndGgiLCJJTlBVVDo6bWluIiwiSU5QVVQ6Om11
-bHRpcGxlIiwiSU5QVVQ6Om5hbWUiLCJJTlBVVDo6cGxhY2Vob2xkZXIiLCJJTlBVVDo6cmVhZG9ubHki
-LCJJTlBVVDo6cmVxdWlyZWQiLCJJTlBVVDo6c2l6ZSIsIklOUFVUOjpzdGVwIiwiSU5QVVQ6OnRhYmlu
-ZGV4IiwiSU5QVVQ6OnR5cGUiLCJJTlBVVDo6dXNlbWFwIiwiSU5QVVQ6OnZhbHVlIiwiSU5TOjpkYXRl
-dGltZSIsIktFWUdFTjo6ZGlzYWJsZWQiLCJLRVlHRU46OmtleXR5cGUiLCJLRVlHRU46Om5hbWUiLCJM
-QUJFTDo6YWNjZXNza2V5IiwiTEFCRUw6OmZvciIsIkxFR0VORDo6YWNjZXNza2V5IiwiTEVHRU5EOjph
-bGlnbiIsIkxJOjp0eXBlIiwiTEk6OnZhbHVlIiwiTElOSzo6c2l6ZXMiLCJNQVA6Om5hbWUiLCJNRU5V
-Ojpjb21wYWN0IiwiTUVOVTo6bGFiZWwiLCJNRU5VOjp0eXBlIiwiTUVURVI6OmhpZ2giLCJNRVRFUjo6
-bG93IiwiTUVURVI6Om1heCIsIk1FVEVSOjptaW4iLCJNRVRFUjo6dmFsdWUiLCJPQkpFQ1Q6OnR5cGVt
-dXN0bWF0Y2giLCJPTDo6Y29tcGFjdCIsIk9MOjpyZXZlcnNlZCIsIk9MOjpzdGFydCIsIk9MOjp0eXBl
-IiwiT1BUR1JPVVA6OmRpc2FibGVkIiwiT1BUR1JPVVA6OmxhYmVsIiwiT1BUSU9OOjpkaXNhYmxlZCIs
-Ik9QVElPTjo6bGFiZWwiLCJPUFRJT046OnNlbGVjdGVkIiwiT1BUSU9OOjp2YWx1ZSIsIk9VVFBVVDo6
-Zm9yIiwiT1VUUFVUOjpuYW1lIiwiUDo6YWxpZ24iLCJQUkU6OndpZHRoIiwiUFJPR1JFU1M6Om1heCIs
-IlBST0dSRVNTOjptaW4iLCJQUk9HUkVTUzo6dmFsdWUiLCJTRUxFQ1Q6OmF1dG9jb21wbGV0ZSIsIlNF
-TEVDVDo6ZGlzYWJsZWQiLCJTRUxFQ1Q6Om11bHRpcGxlIiwiU0VMRUNUOjpuYW1lIiwiU0VMRUNUOjpy
-ZXF1aXJlZCIsIlNFTEVDVDo6c2l6ZSIsIlNFTEVDVDo6dGFiaW5kZXgiLCJTT1VSQ0U6OnR5cGUiLCJU
-QUJMRTo6YWxpZ24iLCJUQUJMRTo6Ymdjb2xvciIsIlRBQkxFOjpib3JkZXIiLCJUQUJMRTo6Y2VsbHBh
-ZGRpbmciLCJUQUJMRTo6Y2VsbHNwYWNpbmciLCJUQUJMRTo6ZnJhbWUiLCJUQUJMRTo6cnVsZXMiLCJU
-QUJMRTo6c3VtbWFyeSIsIlRBQkxFOjp3aWR0aCIsIlRCT0RZOjphbGlnbiIsIlRCT0RZOjpjaGFyIiwi
-VEJPRFk6OmNoYXJvZmYiLCJUQk9EWTo6dmFsaWduIiwiVEQ6OmFiYnIiLCJURDo6YWxpZ24iLCJURDo6
-YXhpcyIsIlREOjpiZ2NvbG9yIiwiVEQ6OmNoYXIiLCJURDo6Y2hhcm9mZiIsIlREOjpjb2xzcGFuIiwi
-VEQ6OmhlYWRlcnMiLCJURDo6aGVpZ2h0IiwiVEQ6Om5vd3JhcCIsIlREOjpyb3dzcGFuIiwiVEQ6OnNj
-b3BlIiwiVEQ6OnZhbGlnbiIsIlREOjp3aWR0aCIsIlRFWFRBUkVBOjphY2Nlc3NrZXkiLCJURVhUQVJF
-QTo6YXV0b2NvbXBsZXRlIiwiVEVYVEFSRUE6OmNvbHMiLCJURVhUQVJFQTo6ZGlzYWJsZWQiLCJURVhU
-QVJFQTo6aW5wdXRtb2RlIiwiVEVYVEFSRUE6Om5hbWUiLCJURVhUQVJFQTo6cGxhY2Vob2xkZXIiLCJU
-RVhUQVJFQTo6cmVhZG9ubHkiLCJURVhUQVJFQTo6cmVxdWlyZWQiLCJURVhUQVJFQTo6cm93cyIsIlRF
-WFRBUkVBOjp0YWJpbmRleCIsIlRFWFRBUkVBOjp3cmFwIiwiVEZPT1Q6OmFsaWduIiwiVEZPT1Q6OmNo
-YXIiLCJURk9PVDo6Y2hhcm9mZiIsIlRGT09UOjp2YWxpZ24iLCJUSDo6YWJiciIsIlRIOjphbGlnbiIs
-IlRIOjpheGlzIiwiVEg6OmJnY29sb3IiLCJUSDo6Y2hhciIsIlRIOjpjaGFyb2ZmIiwiVEg6OmNvbHNw
-YW4iLCJUSDo6aGVhZGVycyIsIlRIOjpoZWlnaHQiLCJUSDo6bm93cmFwIiwiVEg6OnJvd3NwYW4iLCJU
-SDo6c2NvcGUiLCJUSDo6dmFsaWduIiwiVEg6OndpZHRoIiwiVEhFQUQ6OmFsaWduIiwiVEhFQUQ6OmNo
-YXIiLCJUSEVBRDo6Y2hhcm9mZiIsIlRIRUFEOjp2YWxpZ24iLCJUUjo6YWxpZ24iLCJUUjo6Ymdjb2xv
-ciIsIlRSOjpjaGFyIiwiVFI6OmNoYXJvZmYiLCJUUjo6dmFsaWduIiwiVFJBQ0s6OmRlZmF1bHQiLCJU
-UkFDSzo6a2luZCIsIlRSQUNLOjpsYWJlbCIsIlRSQUNLOjpzcmNsYW5nIiwiVUw6OmNvbXBhY3QiLCJV
-TDo6dHlwZSIsIlZJREVPOjpjb250cm9scyIsIlZJREVPOjpoZWlnaHQiLCJWSURFTzo6bG9vcCIsIlZJ
-REVPOjptZWRpYWdyb3VwIiwiVklERU86Om11dGVkIiwiVklERU86OnByZWxvYWQiLCJWSURFTzo6d2lk
-dGgiXSksdC5pKQpDLlZDPUguVk0ocyhbMCwwLDY1NDkwLDQ1MDU1LDY1NTM1LDM0ODE1LDY1NTM0LDE4
-NDMxXSksdC5WKQpDLm1LPUguVk0ocyhbMCwwLDI2NjI0LDEwMjMsNjU1MzQsMjA0Nyw2NTUzNCwyMDQ3
-XSksdC5WKQpDLlNxPUguVk0ocyhbIkhFQUQiLCJBUkVBIiwiQkFTRSIsIkJBU0VGT05UIiwiQlIiLCJD
-T0wiLCJDT0xHUk9VUCIsIkVNQkVEIiwiRlJBTUUiLCJGUkFNRVNFVCIsIkhSIiwiSU1BR0UiLCJJTUci
-LCJJTlBVVCIsIklTSU5ERVgiLCJMSU5LIiwiTUVUQSIsIlBBUkFNIiwiU09VUkNFIiwiU1RZTEUiLCJU
-SVRMRSIsIldCUiJdKSx0LmkpCkMuaFU9SC5WTShzKFtdKSx0LngpCkMuZG49SC5WTShzKFtdKSxILk4w
-KCJqZDxMTCo+IikpCkMueEQ9SC5WTShzKFtdKSx0LmkpCkMudG89SC5WTShzKFswLDAsMzI3MjIsMTIy
-ODcsNjU1MzQsMzQ4MTUsNjU1MzQsMTg0MzFdKSx0LlYpCkMucms9SC5WTShzKFtDLkFkLEMubmUsQy5t
-eSxDLnJ4LEMud1YsQy5mUl0pLEguTjAoImpkPEg3Kj4iKSkKQy5GMz1ILlZNKHMoWzAsMCwyNDU3Niwx
-MDIzLDY1NTM0LDM0ODE1LDY1NTM0LDE4NDMxXSksdC5WKQpDLmVhPUguVk0ocyhbMCwwLDMyNzU0LDEx
-MjYzLDY1NTM0LDM0ODE1LDY1NTM0LDE4NDMxXSksdC5WKQpDLlpKPUguVk0ocyhbMCwwLDMyNzIyLDEy
-Mjg3LDY1NTM1LDM0ODE1LDY1NTM0LDE4NDMxXSksdC5WKQpDLldkPUguVk0ocyhbMCwwLDY1NDkwLDEy
-Mjg3LDY1NTM1LDM0ODE1LDY1NTM0LDE4NDMxXSksdC5WKQpDLlF4PUguVk0ocyhbImJpbmQiLCJpZiIs
-InJlZiIsInJlcGVhdCIsInN5bnRheCJdKSx0LmkpCkMuQkk9SC5WTShzKFsiQTo6aHJlZiIsIkFSRUE6
-OmhyZWYiLCJCTE9DS1FVT1RFOjpjaXRlIiwiQk9EWTo6YmFja2dyb3VuZCIsIkNPTU1BTkQ6Omljb24i
-LCJERUw6OmNpdGUiLCJGT1JNOjphY3Rpb24iLCJJTUc6OnNyYyIsIklOUFVUOjpzcmMiLCJJTlM6OmNp
-dGUiLCJROjpjaXRlIiwiVklERU86OnBvc3RlciJdKSx0LmkpCkMuRHg9bmV3IEguTFAoMCx7fSxDLnhE
-LEguTjAoIkxQPHFVKix6TTxqOCo+Kj4iKSkKQy5DTT1uZXcgSC5MUCgwLHt9LEMueEQsSC5OMCgiTFA8
-cVUqLHFVKj4iKSkKQy5pSD1ILlZNKHMoW10pLEguTjAoImpkPEdEKj4iKSkKQy5XTz1uZXcgSC5MUCgw
-LHt9LEMuaUgsSC5OMCgiTFA8R0QqLEA+IikpCkMuWTI9bmV3IEwuTzkoIk5hdmlnYXRpb25UcmVlTm9k
-ZVR5cGUuZGlyZWN0b3J5IikKQy5yZj1uZXcgTC5POSgiTmF2aWdhdGlvblRyZWVOb2RlVHlwZS5maWxl
-IikKQy5UZT1uZXcgSC53digiY2FsbCIpCkMub0U9bmV3IFAuR1koITEpCkMud1E9bmV3IFAuRnkobnVs
-bCwyKX0pKCk7KGZ1bmN0aW9uIHN0YXRpY0ZpZWxkcygpeyQuem09bnVsbAokLnlqPTAKJC5tSj1udWxs
-CiQuUDQ9bnVsbAokLk5GPW51bGwKJC5UWD1udWxsCiQueDc9bnVsbAokLm53PW51bGwKJC52dj1udWxs
-CiQuQnY9bnVsbAokLlM2PW51bGwKJC5rOD1udWxsCiQubWc9bnVsbAokLlVEPSExCiQuWDM9Qy5OVQok
-LnhnPUguVk0oW10sSC5OMCgiamQ8TWg+IikpCiQueG89bnVsbAokLkJPPW51bGwKJC5sdD1udWxsCiQu
-RVU9bnVsbAokLm9yPVAuRmwodC5OLHQuWSkKJC5JNj1udWxsCiQuRmY9bnVsbH0pKCk7KGZ1bmN0aW9u
-IGxhenlJbml0aWFsaXplcnMoKXt2YXIgcz1odW5rSGVscGVycy5sYXp5RmluYWwscj1odW5rSGVscGVy
-cy5sYXp5T2xkCnMoJCwiZmEiLCJ3IixmdW5jdGlvbigpe3JldHVybiBILllnKCJfJGRhcnRfZGFydENs
-b3N1cmUiKX0pCnMoJCwiVTIiLCJTbiIsZnVuY3Rpb24oKXtyZXR1cm4gSC5jTShILlM3KHsKdG9TdHJp
-bmc6ZnVuY3Rpb24oKXtyZXR1cm4iJHJlY2VpdmVyJCJ9fSkpfSkKcygkLCJ4cSIsImxxIixmdW5jdGlv
-bigpe3JldHVybiBILmNNKEguUzcoeyRtZXRob2QkOm51bGwsCnRvU3RyaW5nOmZ1bmN0aW9uKCl7cmV0
-dXJuIiRyZWNlaXZlciQifX0pKX0pCnMoJCwiUjEiLCJOOSIsZnVuY3Rpb24oKXtyZXR1cm4gSC5jTShI
-LlM3KG51bGwpKX0pCnMoJCwiZk4iLCJpSSIsZnVuY3Rpb24oKXtyZXR1cm4gSC5jTShmdW5jdGlvbigp
-e3ZhciAkYXJndW1lbnRzRXhwciQ9JyRhcmd1bWVudHMkJwp0cnl7bnVsbC4kbWV0aG9kJCgkYXJndW1l
-bnRzRXhwciQpfWNhdGNoKHEpe3JldHVybiBxLm1lc3NhZ2V9fSgpKX0pCnMoJCwicWkiLCJVTiIsZnVu
-Y3Rpb24oKXtyZXR1cm4gSC5jTShILlM3KHZvaWQgMCkpfSkKcygkLCJyWiIsIlpoIixmdW5jdGlvbigp
-e3JldHVybiBILmNNKGZ1bmN0aW9uKCl7dmFyICRhcmd1bWVudHNFeHByJD0nJGFyZ3VtZW50cyQnCnRy
-eXsodm9pZCAwKS4kbWV0aG9kJCgkYXJndW1lbnRzRXhwciQpfWNhdGNoKHEpe3JldHVybiBxLm1lc3Nh
-Z2V9fSgpKX0pCnMoJCwia3EiLCJyTiIsZnVuY3Rpb24oKXtyZXR1cm4gSC5jTShILk1qKG51bGwpKX0p
-CnMoJCwidHQiLCJjMyIsZnVuY3Rpb24oKXtyZXR1cm4gSC5jTShmdW5jdGlvbigpe3RyeXtudWxsLiRt
-ZXRob2QkfWNhdGNoKHEpe3JldHVybiBxLm1lc3NhZ2V9fSgpKX0pCnMoJCwiZHQiLCJISyIsZnVuY3Rp
-b24oKXtyZXR1cm4gSC5jTShILk1qKHZvaWQgMCkpfSkKcygkLCJBNyIsInIxIixmdW5jdGlvbigpe3Jl
-dHVybiBILmNNKGZ1bmN0aW9uKCl7dHJ5eyh2b2lkIDApLiRtZXRob2QkfWNhdGNoKHEpe3JldHVybiBx
-Lm1lc3NhZ2V9fSgpKX0pCnMoJCwiV2MiLCJ1dCIsZnVuY3Rpb24oKXtyZXR1cm4gUC5PaigpfSkKcygk
-LCJraCIsInJmIixmdW5jdGlvbigpe3JldHVybiBuZXcgUC5wZygpLiQwKCl9KQpzKCQsImRIIiwiSEci
-LGZ1bmN0aW9uKCl7cmV0dXJuIG5ldyBQLmMyKCkuJDAoKX0pCnMoJCwiYnQiLCJWNyIsZnVuY3Rpb24o
-KXtyZXR1cm4gbmV3IEludDhBcnJheShILlhGKEguVk0oWy0yLC0yLC0yLC0yLC0yLC0yLC0yLC0yLC0y
-LC0yLC0yLC0yLC0yLC0yLC0yLC0yLC0yLC0yLC0yLC0yLC0yLC0yLC0yLC0yLC0yLC0yLC0yLC0yLC0y
-LC0yLC0yLC0yLC0yLC0yLC0yLC0yLC0yLC0xLC0yLC0yLC0yLC0yLC0yLDYyLC0yLDYyLC0yLDYzLDUy
-LDUzLDU0LDU1LDU2LDU3LDU4LDU5LDYwLDYxLC0yLC0yLC0yLC0xLC0yLC0yLC0yLDAsMSwyLDMsNCw1
-LDYsNyw4LDksMTAsMTEsMTIsMTMsMTQsMTUsMTYsMTcsMTgsMTksMjAsMjEsMjIsMjMsMjQsMjUsLTIs
-LTIsLTIsLTIsNjMsLTIsMjYsMjcsMjgsMjksMzAsMzEsMzIsMzMsMzQsMzUsMzYsMzcsMzgsMzksNDAs
-NDEsNDIsNDMsNDQsNDUsNDYsNDcsNDgsNDksNTAsNTEsLTIsLTIsLTIsLTIsLTJdLHQuYSkpKX0pCnMo
-JCwiTTUiLCJ3USIsZnVuY3Rpb24oKXtyZXR1cm4gdHlwZW9mIHByb2Nlc3MhPSJ1bmRlZmluZWQiJiZP
-YmplY3QucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwocHJvY2Vzcyk9PSJbb2JqZWN0IHByb2Nlc3NdIiYm
-cHJvY2Vzcy5wbGF0Zm9ybT09IndpbjMyIn0pCnMoJCwibWYiLCJ6NCIsZnVuY3Rpb24oKXtyZXR1cm4g
-UC5udSgiXltcXC1cXC4wLTlBLVpfYS16fl0qJCIpfSkKcygkLCJPUSIsInZaIixmdW5jdGlvbigpe3Jl
-dHVybiBQLktOKCl9KQpzKCQsIlNDIiwiQU4iLGZ1bmN0aW9uKCl7cmV0dXJuIFAudE0oWyJBIiwiQUJC
-UiIsIkFDUk9OWU0iLCJBRERSRVNTIiwiQVJFQSIsIkFSVElDTEUiLCJBU0lERSIsIkFVRElPIiwiQiIs
-IkJESSIsIkJETyIsIkJJRyIsIkJMT0NLUVVPVEUiLCJCUiIsIkJVVFRPTiIsIkNBTlZBUyIsIkNBUFRJ
-T04iLCJDRU5URVIiLCJDSVRFIiwiQ09ERSIsIkNPTCIsIkNPTEdST1VQIiwiQ09NTUFORCIsIkRBVEEi
-LCJEQVRBTElTVCIsIkREIiwiREVMIiwiREVUQUlMUyIsIkRGTiIsIkRJUiIsIkRJViIsIkRMIiwiRFQi
-LCJFTSIsIkZJRUxEU0VUIiwiRklHQ0FQVElPTiIsIkZJR1VSRSIsIkZPTlQiLCJGT09URVIiLCJGT1JN
-IiwiSDEiLCJIMiIsIkgzIiwiSDQiLCJINSIsIkg2IiwiSEVBREVSIiwiSEdST1VQIiwiSFIiLCJJIiwi
-SUZSQU1FIiwiSU1HIiwiSU5QVVQiLCJJTlMiLCJLQkQiLCJMQUJFTCIsIkxFR0VORCIsIkxJIiwiTUFQ
-IiwiTUFSSyIsIk1FTlUiLCJNRVRFUiIsIk5BViIsIk5PQlIiLCJPTCIsIk9QVEdST1VQIiwiT1BUSU9O
-IiwiT1VUUFVUIiwiUCIsIlBSRSIsIlBST0dSRVNTIiwiUSIsIlMiLCJTQU1QIiwiU0VDVElPTiIsIlNF
-TEVDVCIsIlNNQUxMIiwiU09VUkNFIiwiU1BBTiIsIlNUUklLRSIsIlNUUk9ORyIsIlNVQiIsIlNVTU1B
-UlkiLCJTVVAiLCJUQUJMRSIsIlRCT0RZIiwiVEQiLCJURVhUQVJFQSIsIlRGT09UIiwiVEgiLCJUSEVB
-RCIsIlRJTUUiLCJUUiIsIlRSQUNLIiwiVFQiLCJVIiwiVUwiLCJWQVIiLCJWSURFTyIsIldCUiJdLHQu
-Til9KQpzKCQsIlg0IiwiaEciLGZ1bmN0aW9uKCl7cmV0dXJuIFAubnUoIl5cXFMrJCIpfSkKcygkLCJ3
-TyIsIm93IixmdW5jdGlvbigpe3JldHVybiBQLk5EKHNlbGYpfSkKcygkLCJrdCIsIlI4IixmdW5jdGlv
-bigpe3JldHVybiBILllnKCJfJGRhcnRfZGFydE9iamVjdCIpfSkKcygkLCJmSyIsImtJIixmdW5jdGlv
-bigpe3JldHVybiBmdW5jdGlvbiBEYXJ0T2JqZWN0KGEpe3RoaXMubz1hfX0pCnIoJCwicXQiLCJ6QiIs
-ZnVuY3Rpb24oKXtyZXR1cm4gbmV3IFQubVEoKX0pCnIoJCwiT2wiLCJVRSIsZnVuY3Rpb24oKXtyZXR1
-cm4gUC5oSyhDLm9sLmdtVyhXLngzKCkpLmhyZWYpLmdoWSgpLnEoMCwiYXV0aFRva2VuIil9KQpyKCQs
-ImhUIiwieVAiLGZ1bmN0aW9uKCl7cmV0dXJuIFcuWnIoKS5xdWVyeVNlbGVjdG9yKCIuZWRpdC1saXN0
-IC5wYW5lbC1jb250ZW50Iil9KQpyKCQsIlc2IiwiaEwiLGZ1bmN0aW9uKCl7cmV0dXJuIFcuWnIoKS5x
-dWVyeVNlbGVjdG9yKCIuZWRpdC1wYW5lbCAucGFuZWwtY29udGVudCIpfSkKcigkLCJUUiIsIkRXIixm
-dW5jdGlvbigpe3JldHVybiBXLlpyKCkucXVlcnlTZWxlY3RvcigiZm9vdGVyIil9KQpyKCQsIkVZIiwi
-ZmkiLGZ1bmN0aW9uKCl7cmV0dXJuIFcuWnIoKS5xdWVyeVNlbGVjdG9yKCJoZWFkZXIiKX0pCnIoJCwi
-YXYiLCJEOSIsZnVuY3Rpb24oKXtyZXR1cm4gVy5acigpLnF1ZXJ5U2VsZWN0b3IoIiN1bml0LW5hbWUi
-KX0pCnIoJCwiZmUiLCJLRyIsZnVuY3Rpb24oKXtyZXR1cm4gbmV3IEwuWEEoKX0pCnMoJCwiZW8iLCJu
-VSIsZnVuY3Rpb24oKXtyZXR1cm4gbmV3IE0ubEkoJC5IaygpKX0pCnMoJCwieXIiLCJiRCIsZnVuY3Rp
-b24oKXtyZXR1cm4gbmV3IEUuT0YoUC5udSgiLyIpLFAubnUoIlteL10kIiksUC5udSgiXi8iKSl9KQpz
-KCQsIk1rIiwiS2siLGZ1bmN0aW9uKCl7cmV0dXJuIG5ldyBMLklWKFAubnUoIlsvXFxcXF0iKSxQLm51
-KCJbXi9cXFxcXSQiKSxQLm51KCJeKFxcXFxcXFxcW15cXFxcXStcXFxcW15cXFxcL10rfFthLXpBLVpd
-OlsvXFxcXF0pIiksUC5udSgiXlsvXFxcXF0oPyFbL1xcXFxdKSIpKX0pCnMoJCwiYWsiLCJFYiIsZnVu
-Y3Rpb24oKXtyZXR1cm4gbmV3IEYucnUoUC5udSgiLyIpLFAubnUoIiheW2EtekEtWl1bLSsuYS16QS1a
-XFxkXSo6Ly98W14vXSkkIiksUC5udSgiW2EtekEtWl1bLSsuYS16QS1aXFxkXSo6Ly9bXi9dKiIpLFAu
-bnUoIl4vIikpfSkKcygkLCJscyIsIkhrIixmdW5jdGlvbigpe3JldHVybiBPLlJoKCl9KX0pKCk7KGZ1
-bmN0aW9uIG5hdGl2ZVN1cHBvcnQoKXshZnVuY3Rpb24oKXt2YXIgcz1mdW5jdGlvbihhKXt2YXIgbT17
-fQptW2FdPTEKcmV0dXJuIE9iamVjdC5rZXlzKGh1bmtIZWxwZXJzLmNvbnZlcnRUb0Zhc3RPYmplY3Qo
-bSkpWzBdfQp2LmdldElzb2xhdGVUYWc9ZnVuY3Rpb24oYSl7cmV0dXJuIHMoIl9fX2RhcnRfIithK3Yu
-aXNvbGF0ZVRhZyl9CnZhciByPSJfX19kYXJ0X2lzb2xhdGVfdGFnc18iCnZhciBxPU9iamVjdFtyXXx8
-KE9iamVjdFtyXT1PYmplY3QuY3JlYXRlKG51bGwpKQp2YXIgcD0iX1p4WXhYIgpmb3IodmFyIG89MDs7
-bysrKXt2YXIgbj1zKHArIl8iK28rIl8iKQppZighKG4gaW4gcSkpe3Fbbl09MQp2Lmlzb2xhdGVUYWc9
-bgpicmVha319di5kaXNwYXRjaFByb3BlcnR5TmFtZT12LmdldElzb2xhdGVUYWcoImRpc3BhdGNoX3Jl
-Y29yZCIpfSgpCmh1bmtIZWxwZXJzLnNldE9yVXBkYXRlSW50ZXJjZXB0b3JzQnlUYWcoe0RPTUVycm9y
-OkouR3YsTWVkaWFFcnJvcjpKLkd2LE5hdmlnYXRvcjpKLkd2LE5hdmlnYXRvckNvbmN1cnJlbnRIYXJk
-d2FyZTpKLkd2LE5hdmlnYXRvclVzZXJNZWRpYUVycm9yOkouR3YsT3ZlcmNvbnN0cmFpbmVkRXJyb3I6
-Si5HdixQb3NpdGlvbkVycm9yOkouR3YsUmFuZ2U6Si5HdixTUUxFcnJvcjpKLkd2LERhdGFWaWV3Okgu
-RVQsQXJyYXlCdWZmZXJWaWV3OkguRVQsRmxvYXQzMkFycmF5OkguRGcsRmxvYXQ2NEFycmF5OkguRGcs
-SW50MTZBcnJheTpILnhqLEludDMyQXJyYXk6SC5kRSxJbnQ4QXJyYXk6SC5aQSxVaW50MTZBcnJheTpI
-LmRULFVpbnQzMkFycmF5OkguUHEsVWludDhDbGFtcGVkQXJyYXk6SC5lRSxDYW52YXNQaXhlbEFycmF5
-OkguZUUsVWludDhBcnJheTpILlY2LEhUTUxBdWRpb0VsZW1lbnQ6Vy5xRSxIVE1MQlJFbGVtZW50Olcu
-cUUsSFRNTEJ1dHRvbkVsZW1lbnQ6Vy5xRSxIVE1MQ2FudmFzRWxlbWVudDpXLnFFLEhUTUxDb250ZW50
-RWxlbWVudDpXLnFFLEhUTUxETGlzdEVsZW1lbnQ6Vy5xRSxIVE1MRGF0YUVsZW1lbnQ6Vy5xRSxIVE1M
-RGF0YUxpc3RFbGVtZW50OlcucUUsSFRNTERldGFpbHNFbGVtZW50OlcucUUsSFRNTERpYWxvZ0VsZW1l
-bnQ6Vy5xRSxIVE1MRGl2RWxlbWVudDpXLnFFLEhUTUxFbWJlZEVsZW1lbnQ6Vy5xRSxIVE1MRmllbGRT
-ZXRFbGVtZW50OlcucUUsSFRNTEhSRWxlbWVudDpXLnFFLEhUTUxIZWFkRWxlbWVudDpXLnFFLEhUTUxI
-ZWFkaW5nRWxlbWVudDpXLnFFLEhUTUxIdG1sRWxlbWVudDpXLnFFLEhUTUxJRnJhbWVFbGVtZW50Olcu
-cUUsSFRNTEltYWdlRWxlbWVudDpXLnFFLEhUTUxJbnB1dEVsZW1lbnQ6Vy5xRSxIVE1MTElFbGVtZW50
-OlcucUUsSFRNTExhYmVsRWxlbWVudDpXLnFFLEhUTUxMZWdlbmRFbGVtZW50OlcucUUsSFRNTExpbmtF
-bGVtZW50OlcucUUsSFRNTE1hcEVsZW1lbnQ6Vy5xRSxIVE1MTWVkaWFFbGVtZW50OlcucUUsSFRNTE1l
-bnVFbGVtZW50OlcucUUsSFRNTE1ldGFFbGVtZW50OlcucUUsSFRNTE1ldGVyRWxlbWVudDpXLnFFLEhU
-TUxNb2RFbGVtZW50OlcucUUsSFRNTE9MaXN0RWxlbWVudDpXLnFFLEhUTUxPYmplY3RFbGVtZW50Olcu
-cUUsSFRNTE9wdEdyb3VwRWxlbWVudDpXLnFFLEhUTUxPcHRpb25FbGVtZW50OlcucUUsSFRNTE91dHB1
-dEVsZW1lbnQ6Vy5xRSxIVE1MUGFyYW1FbGVtZW50OlcucUUsSFRNTFBpY3R1cmVFbGVtZW50OlcucUUs
-SFRNTFByZUVsZW1lbnQ6Vy5xRSxIVE1MUHJvZ3Jlc3NFbGVtZW50OlcucUUsSFRNTFF1b3RlRWxlbWVu
-dDpXLnFFLEhUTUxTY3JpcHRFbGVtZW50OlcucUUsSFRNTFNoYWRvd0VsZW1lbnQ6Vy5xRSxIVE1MU2xv
-dEVsZW1lbnQ6Vy5xRSxIVE1MU291cmNlRWxlbWVudDpXLnFFLEhUTUxTcGFuRWxlbWVudDpXLnFFLEhU
-TUxTdHlsZUVsZW1lbnQ6Vy5xRSxIVE1MVGFibGVDYXB0aW9uRWxlbWVudDpXLnFFLEhUTUxUYWJsZUNl
-bGxFbGVtZW50OlcucUUsSFRNTFRhYmxlRGF0YUNlbGxFbGVtZW50OlcucUUsSFRNTFRhYmxlSGVhZGVy
-Q2VsbEVsZW1lbnQ6Vy5xRSxIVE1MVGFibGVDb2xFbGVtZW50OlcucUUsSFRNTFRleHRBcmVhRWxlbWVu
-dDpXLnFFLEhUTUxUaW1lRWxlbWVudDpXLnFFLEhUTUxUaXRsZUVsZW1lbnQ6Vy5xRSxIVE1MVHJhY2tF
-bGVtZW50OlcucUUsSFRNTFVMaXN0RWxlbWVudDpXLnFFLEhUTUxVbmtub3duRWxlbWVudDpXLnFFLEhU
-TUxWaWRlb0VsZW1lbnQ6Vy5xRSxIVE1MRGlyZWN0b3J5RWxlbWVudDpXLnFFLEhUTUxGb250RWxlbWVu
-dDpXLnFFLEhUTUxGcmFtZUVsZW1lbnQ6Vy5xRSxIVE1MRnJhbWVTZXRFbGVtZW50OlcucUUsSFRNTE1h
-cnF1ZWVFbGVtZW50OlcucUUsSFRNTEVsZW1lbnQ6Vy5xRSxIVE1MQW5jaG9yRWxlbWVudDpXLkdoLEhU
-TUxBcmVhRWxlbWVudDpXLmZZLEhUTUxCYXNlRWxlbWVudDpXLm5CLEJsb2I6Vy5BeixIVE1MQm9keUVs
-ZW1lbnQ6Vy5RUCxDREFUQVNlY3Rpb246Vy5ueCxDaGFyYWN0ZXJEYXRhOlcubngsQ29tbWVudDpXLm54
-LFByb2Nlc3NpbmdJbnN0cnVjdGlvbjpXLm54LFRleHQ6Vy5ueCxDU1NTdHlsZURlY2xhcmF0aW9uOlcu
-b0osTVNTdHlsZUNTU1Byb3BlcnRpZXM6Vy5vSixDU1MyUHJvcGVydGllczpXLm9KLFhNTERvY3VtZW50
-OlcuUUYsRG9jdW1lbnQ6Vy5RRixET01FeGNlcHRpb246Vy5OaCxET01JbXBsZW1lbnRhdGlvbjpXLmFl
-LERPTVJlY3RSZWFkT25seTpXLklCLERPTVRva2VuTGlzdDpXLm43LEVsZW1lbnQ6Vy5jdixBYm9ydFBh
-eW1lbnRFdmVudDpXLmVhLEFuaW1hdGlvbkV2ZW50OlcuZWEsQW5pbWF0aW9uUGxheWJhY2tFdmVudDpX
-LmVhLEFwcGxpY2F0aW9uQ2FjaGVFcnJvckV2ZW50OlcuZWEsQmFja2dyb3VuZEZldGNoQ2xpY2tFdmVu
-dDpXLmVhLEJhY2tncm91bmRGZXRjaEV2ZW50OlcuZWEsQmFja2dyb3VuZEZldGNoRmFpbEV2ZW50Olcu
-ZWEsQmFja2dyb3VuZEZldGNoZWRFdmVudDpXLmVhLEJlZm9yZUluc3RhbGxQcm9tcHRFdmVudDpXLmVh
-LEJlZm9yZVVubG9hZEV2ZW50OlcuZWEsQmxvYkV2ZW50OlcuZWEsQ2FuTWFrZVBheW1lbnRFdmVudDpX
-LmVhLENsaXBib2FyZEV2ZW50OlcuZWEsQ2xvc2VFdmVudDpXLmVhLEN1c3RvbUV2ZW50OlcuZWEsRGV2
-aWNlTW90aW9uRXZlbnQ6Vy5lYSxEZXZpY2VPcmllbnRhdGlvbkV2ZW50OlcuZWEsRXJyb3JFdmVudDpX
-LmVhLEV4dGVuZGFibGVFdmVudDpXLmVhLEV4dGVuZGFibGVNZXNzYWdlRXZlbnQ6Vy5lYSxGZXRjaEV2
-ZW50OlcuZWEsRm9udEZhY2VTZXRMb2FkRXZlbnQ6Vy5lYSxGb3JlaWduRmV0Y2hFdmVudDpXLmVhLEdh
-bWVwYWRFdmVudDpXLmVhLEhhc2hDaGFuZ2VFdmVudDpXLmVhLEluc3RhbGxFdmVudDpXLmVhLE1lZGlh
-RW5jcnlwdGVkRXZlbnQ6Vy5lYSxNZWRpYUtleU1lc3NhZ2VFdmVudDpXLmVhLE1lZGlhUXVlcnlMaXN0
-RXZlbnQ6Vy5lYSxNZWRpYVN0cmVhbUV2ZW50OlcuZWEsTWVkaWFTdHJlYW1UcmFja0V2ZW50OlcuZWEs
-TWVzc2FnZUV2ZW50OlcuZWEsTUlESUNvbm5lY3Rpb25FdmVudDpXLmVhLE1JRElNZXNzYWdlRXZlbnQ6
-Vy5lYSxNdXRhdGlvbkV2ZW50OlcuZWEsTm90aWZpY2F0aW9uRXZlbnQ6Vy5lYSxQYWdlVHJhbnNpdGlv
-bkV2ZW50OlcuZWEsUGF5bWVudFJlcXVlc3RFdmVudDpXLmVhLFBheW1lbnRSZXF1ZXN0VXBkYXRlRXZl
-bnQ6Vy5lYSxQb3BTdGF0ZUV2ZW50OlcuZWEsUHJlc2VudGF0aW9uQ29ubmVjdGlvbkF2YWlsYWJsZUV2
-ZW50OlcuZWEsUHJlc2VudGF0aW9uQ29ubmVjdGlvbkNsb3NlRXZlbnQ6Vy5lYSxQcm9taXNlUmVqZWN0
-aW9uRXZlbnQ6Vy5lYSxQdXNoRXZlbnQ6Vy5lYSxSVENEYXRhQ2hhbm5lbEV2ZW50OlcuZWEsUlRDRFRN
-RlRvbmVDaGFuZ2VFdmVudDpXLmVhLFJUQ1BlZXJDb25uZWN0aW9uSWNlRXZlbnQ6Vy5lYSxSVENUcmFj
-a0V2ZW50OlcuZWEsU2VjdXJpdHlQb2xpY3lWaW9sYXRpb25FdmVudDpXLmVhLFNlbnNvckVycm9yRXZl
-bnQ6Vy5lYSxTcGVlY2hSZWNvZ25pdGlvbkVycm9yOlcuZWEsU3BlZWNoUmVjb2duaXRpb25FdmVudDpX
-LmVhLFNwZWVjaFN5bnRoZXNpc0V2ZW50OlcuZWEsU3RvcmFnZUV2ZW50OlcuZWEsU3luY0V2ZW50Olcu
-ZWEsVHJhY2tFdmVudDpXLmVhLFRyYW5zaXRpb25FdmVudDpXLmVhLFdlYktpdFRyYW5zaXRpb25FdmVu
-dDpXLmVhLFZSRGV2aWNlRXZlbnQ6Vy5lYSxWUkRpc3BsYXlFdmVudDpXLmVhLFZSU2Vzc2lvbkV2ZW50
-OlcuZWEsTW9qb0ludGVyZmFjZVJlcXVlc3RFdmVudDpXLmVhLFVTQkNvbm5lY3Rpb25FdmVudDpXLmVh
-LElEQlZlcnNpb25DaGFuZ2VFdmVudDpXLmVhLEF1ZGlvUHJvY2Vzc2luZ0V2ZW50OlcuZWEsT2ZmbGlu
-ZUF1ZGlvQ29tcGxldGlvbkV2ZW50OlcuZWEsV2ViR0xDb250ZXh0RXZlbnQ6Vy5lYSxFdmVudDpXLmVh
-LElucHV0RXZlbnQ6Vy5lYSxTdWJtaXRFdmVudDpXLmVhLEV2ZW50VGFyZ2V0OlcuRDAsRmlsZTpXLmhI
-LEhUTUxGb3JtRWxlbWVudDpXLmg0LEhpc3Rvcnk6Vy5icixIVE1MRG9jdW1lbnQ6Vy5WYixYTUxIdHRw
-UmVxdWVzdDpXLmZKLFhNTEh0dHBSZXF1ZXN0RXZlbnRUYXJnZXQ6Vy53YSxJbWFnZURhdGE6Vy5TZyxM
-b2NhdGlvbjpXLnU4LE1vdXNlRXZlbnQ6Vy5BaixEcmFnRXZlbnQ6Vy5BaixQb2ludGVyRXZlbnQ6Vy5B
-aixXaGVlbEV2ZW50OlcuQWosRG9jdW1lbnRGcmFnbWVudDpXLnVILFNoYWRvd1Jvb3Q6Vy51SCxEb2N1
-bWVudFR5cGU6Vy51SCxOb2RlOlcudUgsTm9kZUxpc3Q6Vy5CSCxSYWRpb05vZGVMaXN0OlcuQkgsSFRN
-TFBhcmFncmFwaEVsZW1lbnQ6Vy5TTixQcm9ncmVzc0V2ZW50OlcuZXcsUmVzb3VyY2VQcm9ncmVzc0V2
-ZW50OlcuZXcsSFRNTFNlbGVjdEVsZW1lbnQ6Vy5scCxIVE1MVGFibGVFbGVtZW50OlcuVGIsSFRNTFRh
-YmxlUm93RWxlbWVudDpXLkl2LEhUTUxUYWJsZVNlY3Rpb25FbGVtZW50OlcuV1AsSFRNTFRlbXBsYXRl
-RWxlbWVudDpXLnlZLENvbXBvc2l0aW9uRXZlbnQ6Vy53NixGb2N1c0V2ZW50OlcudzYsS2V5Ym9hcmRF
-dmVudDpXLnc2LFRleHRFdmVudDpXLnc2LFRvdWNoRXZlbnQ6Vy53NixVSUV2ZW50OlcudzYsV2luZG93
-OlcuSzUsRE9NV2luZG93OlcuSzUsRGVkaWNhdGVkV29ya2VyR2xvYmFsU2NvcGU6Vy5DbSxTZXJ2aWNl
-V29ya2VyR2xvYmFsU2NvcGU6Vy5DbSxTaGFyZWRXb3JrZXJHbG9iYWxTY29wZTpXLkNtLFdvcmtlckds
-b2JhbFNjb3BlOlcuQ20sQXR0cjpXLkNRLENsaWVudFJlY3Q6Vy53NCxET01SZWN0OlcudzQsTmFtZWRO
-b2RlTWFwOlcucmgsTW96TmFtZWRBdHRyTWFwOlcucmgsSURCS2V5UmFuZ2U6UC5oRixTVkdTY3JpcHRF
-bGVtZW50OlAubmQsU1ZHQUVsZW1lbnQ6UC5oaSxTVkdBbmltYXRlRWxlbWVudDpQLmhpLFNWR0FuaW1h
-dGVNb3Rpb25FbGVtZW50OlAuaGksU1ZHQW5pbWF0ZVRyYW5zZm9ybUVsZW1lbnQ6UC5oaSxTVkdBbmlt
-YXRpb25FbGVtZW50OlAuaGksU1ZHQ2lyY2xlRWxlbWVudDpQLmhpLFNWR0NsaXBQYXRoRWxlbWVudDpQ
-LmhpLFNWR0RlZnNFbGVtZW50OlAuaGksU1ZHRGVzY0VsZW1lbnQ6UC5oaSxTVkdEaXNjYXJkRWxlbWVu
-dDpQLmhpLFNWR0VsbGlwc2VFbGVtZW50OlAuaGksU1ZHRkVCbGVuZEVsZW1lbnQ6UC5oaSxTVkdGRUNv
-bG9yTWF0cml4RWxlbWVudDpQLmhpLFNWR0ZFQ29tcG9uZW50VHJhbnNmZXJFbGVtZW50OlAuaGksU1ZH
-RkVDb21wb3NpdGVFbGVtZW50OlAuaGksU1ZHRkVDb252b2x2ZU1hdHJpeEVsZW1lbnQ6UC5oaSxTVkdG
-RURpZmZ1c2VMaWdodGluZ0VsZW1lbnQ6UC5oaSxTVkdGRURpc3BsYWNlbWVudE1hcEVsZW1lbnQ6UC5o
-aSxTVkdGRURpc3RhbnRMaWdodEVsZW1lbnQ6UC5oaSxTVkdGRUZsb29kRWxlbWVudDpQLmhpLFNWR0ZF
-RnVuY0FFbGVtZW50OlAuaGksU1ZHRkVGdW5jQkVsZW1lbnQ6UC5oaSxTVkdGRUZ1bmNHRWxlbWVudDpQ
-LmhpLFNWR0ZFRnVuY1JFbGVtZW50OlAuaGksU1ZHRkVHYXVzc2lhbkJsdXJFbGVtZW50OlAuaGksU1ZH
-RkVJbWFnZUVsZW1lbnQ6UC5oaSxTVkdGRU1lcmdlRWxlbWVudDpQLmhpLFNWR0ZFTWVyZ2VOb2RlRWxl
-bWVudDpQLmhpLFNWR0ZFTW9ycGhvbG9neUVsZW1lbnQ6UC5oaSxTVkdGRU9mZnNldEVsZW1lbnQ6UC5o
-aSxTVkdGRVBvaW50TGlnaHRFbGVtZW50OlAuaGksU1ZHRkVTcGVjdWxhckxpZ2h0aW5nRWxlbWVudDpQ
-LmhpLFNWR0ZFU3BvdExpZ2h0RWxlbWVudDpQLmhpLFNWR0ZFVGlsZUVsZW1lbnQ6UC5oaSxTVkdGRVR1
-cmJ1bGVuY2VFbGVtZW50OlAuaGksU1ZHRmlsdGVyRWxlbWVudDpQLmhpLFNWR0ZvcmVpZ25PYmplY3RF
-bGVtZW50OlAuaGksU1ZHR0VsZW1lbnQ6UC5oaSxTVkdHZW9tZXRyeUVsZW1lbnQ6UC5oaSxTVkdHcmFw
-aGljc0VsZW1lbnQ6UC5oaSxTVkdJbWFnZUVsZW1lbnQ6UC5oaSxTVkdMaW5lRWxlbWVudDpQLmhpLFNW
-R0xpbmVhckdyYWRpZW50RWxlbWVudDpQLmhpLFNWR01hcmtlckVsZW1lbnQ6UC5oaSxTVkdNYXNrRWxl
-bWVudDpQLmhpLFNWR01ldGFkYXRhRWxlbWVudDpQLmhpLFNWR1BhdGhFbGVtZW50OlAuaGksU1ZHUGF0
-dGVybkVsZW1lbnQ6UC5oaSxTVkdQb2x5Z29uRWxlbWVudDpQLmhpLFNWR1BvbHlsaW5lRWxlbWVudDpQ
-LmhpLFNWR1JhZGlhbEdyYWRpZW50RWxlbWVudDpQLmhpLFNWR1JlY3RFbGVtZW50OlAuaGksU1ZHU2V0
-RWxlbWVudDpQLmhpLFNWR1N0b3BFbGVtZW50OlAuaGksU1ZHU3R5bGVFbGVtZW50OlAuaGksU1ZHU1ZH
-RWxlbWVudDpQLmhpLFNWR1N3aXRjaEVsZW1lbnQ6UC5oaSxTVkdTeW1ib2xFbGVtZW50OlAuaGksU1ZH
-VFNwYW5FbGVtZW50OlAuaGksU1ZHVGV4dENvbnRlbnRFbGVtZW50OlAuaGksU1ZHVGV4dEVsZW1lbnQ6
-UC5oaSxTVkdUZXh0UGF0aEVsZW1lbnQ6UC5oaSxTVkdUZXh0UG9zaXRpb25pbmdFbGVtZW50OlAuaGks
-U1ZHVGl0bGVFbGVtZW50OlAuaGksU1ZHVXNlRWxlbWVudDpQLmhpLFNWR1ZpZXdFbGVtZW50OlAuaGks
-U1ZHR3JhZGllbnRFbGVtZW50OlAuaGksU1ZHQ29tcG9uZW50VHJhbnNmZXJGdW5jdGlvbkVsZW1lbnQ6
-UC5oaSxTVkdGRURyb3BTaGFkb3dFbGVtZW50OlAuaGksU1ZHTVBhdGhFbGVtZW50OlAuaGksU1ZHRWxl
-bWVudDpQLmhpfSkKaHVua0hlbHBlcnMuc2V0T3JVcGRhdGVMZWFmVGFncyh7RE9NRXJyb3I6dHJ1ZSxN
-ZWRpYUVycm9yOnRydWUsTmF2aWdhdG9yOnRydWUsTmF2aWdhdG9yQ29uY3VycmVudEhhcmR3YXJlOnRy
-dWUsTmF2aWdhdG9yVXNlck1lZGlhRXJyb3I6dHJ1ZSxPdmVyY29uc3RyYWluZWRFcnJvcjp0cnVlLFBv
-c2l0aW9uRXJyb3I6dHJ1ZSxSYW5nZTp0cnVlLFNRTEVycm9yOnRydWUsRGF0YVZpZXc6dHJ1ZSxBcnJh
-eUJ1ZmZlclZpZXc6ZmFsc2UsRmxvYXQzMkFycmF5OnRydWUsRmxvYXQ2NEFycmF5OnRydWUsSW50MTZB
-cnJheTp0cnVlLEludDMyQXJyYXk6dHJ1ZSxJbnQ4QXJyYXk6dHJ1ZSxVaW50MTZBcnJheTp0cnVlLFVp
-bnQzMkFycmF5OnRydWUsVWludDhDbGFtcGVkQXJyYXk6dHJ1ZSxDYW52YXNQaXhlbEFycmF5OnRydWUs
-VWludDhBcnJheTpmYWxzZSxIVE1MQXVkaW9FbGVtZW50OnRydWUsSFRNTEJSRWxlbWVudDp0cnVlLEhU
-TUxCdXR0b25FbGVtZW50OnRydWUsSFRNTENhbnZhc0VsZW1lbnQ6dHJ1ZSxIVE1MQ29udGVudEVsZW1l
-bnQ6dHJ1ZSxIVE1MRExpc3RFbGVtZW50OnRydWUsSFRNTERhdGFFbGVtZW50OnRydWUsSFRNTERhdGFM
-aXN0RWxlbWVudDp0cnVlLEhUTUxEZXRhaWxzRWxlbWVudDp0cnVlLEhUTUxEaWFsb2dFbGVtZW50OnRy
-dWUsSFRNTERpdkVsZW1lbnQ6dHJ1ZSxIVE1MRW1iZWRFbGVtZW50OnRydWUsSFRNTEZpZWxkU2V0RWxl
-bWVudDp0cnVlLEhUTUxIUkVsZW1lbnQ6dHJ1ZSxIVE1MSGVhZEVsZW1lbnQ6dHJ1ZSxIVE1MSGVhZGlu
-Z0VsZW1lbnQ6dHJ1ZSxIVE1MSHRtbEVsZW1lbnQ6dHJ1ZSxIVE1MSUZyYW1lRWxlbWVudDp0cnVlLEhU
-TUxJbWFnZUVsZW1lbnQ6dHJ1ZSxIVE1MSW5wdXRFbGVtZW50OnRydWUsSFRNTExJRWxlbWVudDp0cnVl
-LEhUTUxMYWJlbEVsZW1lbnQ6dHJ1ZSxIVE1MTGVnZW5kRWxlbWVudDp0cnVlLEhUTUxMaW5rRWxlbWVu
-dDp0cnVlLEhUTUxNYXBFbGVtZW50OnRydWUsSFRNTE1lZGlhRWxlbWVudDp0cnVlLEhUTUxNZW51RWxl
-bWVudDp0cnVlLEhUTUxNZXRhRWxlbWVudDp0cnVlLEhUTUxNZXRlckVsZW1lbnQ6dHJ1ZSxIVE1MTW9k
-RWxlbWVudDp0cnVlLEhUTUxPTGlzdEVsZW1lbnQ6dHJ1ZSxIVE1MT2JqZWN0RWxlbWVudDp0cnVlLEhU
-TUxPcHRHcm91cEVsZW1lbnQ6dHJ1ZSxIVE1MT3B0aW9uRWxlbWVudDp0cnVlLEhUTUxPdXRwdXRFbGVt
-ZW50OnRydWUsSFRNTFBhcmFtRWxlbWVudDp0cnVlLEhUTUxQaWN0dXJlRWxlbWVudDp0cnVlLEhUTUxQ
-cmVFbGVtZW50OnRydWUsSFRNTFByb2dyZXNzRWxlbWVudDp0cnVlLEhUTUxRdW90ZUVsZW1lbnQ6dHJ1
-ZSxIVE1MU2NyaXB0RWxlbWVudDp0cnVlLEhUTUxTaGFkb3dFbGVtZW50OnRydWUsSFRNTFNsb3RFbGVt
-ZW50OnRydWUsSFRNTFNvdXJjZUVsZW1lbnQ6dHJ1ZSxIVE1MU3BhbkVsZW1lbnQ6dHJ1ZSxIVE1MU3R5
-bGVFbGVtZW50OnRydWUsSFRNTFRhYmxlQ2FwdGlvbkVsZW1lbnQ6dHJ1ZSxIVE1MVGFibGVDZWxsRWxl
-bWVudDp0cnVlLEhUTUxUYWJsZURhdGFDZWxsRWxlbWVudDp0cnVlLEhUTUxUYWJsZUhlYWRlckNlbGxF
-bGVtZW50OnRydWUsSFRNTFRhYmxlQ29sRWxlbWVudDp0cnVlLEhUTUxUZXh0QXJlYUVsZW1lbnQ6dHJ1
-ZSxIVE1MVGltZUVsZW1lbnQ6dHJ1ZSxIVE1MVGl0bGVFbGVtZW50OnRydWUsSFRNTFRyYWNrRWxlbWVu
-dDp0cnVlLEhUTUxVTGlzdEVsZW1lbnQ6dHJ1ZSxIVE1MVW5rbm93bkVsZW1lbnQ6dHJ1ZSxIVE1MVmlk
-ZW9FbGVtZW50OnRydWUsSFRNTERpcmVjdG9yeUVsZW1lbnQ6dHJ1ZSxIVE1MRm9udEVsZW1lbnQ6dHJ1
-ZSxIVE1MRnJhbWVFbGVtZW50OnRydWUsSFRNTEZyYW1lU2V0RWxlbWVudDp0cnVlLEhUTUxNYXJxdWVl
-RWxlbWVudDp0cnVlLEhUTUxFbGVtZW50OmZhbHNlLEhUTUxBbmNob3JFbGVtZW50OnRydWUsSFRNTEFy
-ZWFFbGVtZW50OnRydWUsSFRNTEJhc2VFbGVtZW50OnRydWUsQmxvYjpmYWxzZSxIVE1MQm9keUVsZW1l
-bnQ6dHJ1ZSxDREFUQVNlY3Rpb246dHJ1ZSxDaGFyYWN0ZXJEYXRhOnRydWUsQ29tbWVudDp0cnVlLFBy
-b2Nlc3NpbmdJbnN0cnVjdGlvbjp0cnVlLFRleHQ6dHJ1ZSxDU1NTdHlsZURlY2xhcmF0aW9uOnRydWUs
-TVNTdHlsZUNTU1Byb3BlcnRpZXM6dHJ1ZSxDU1MyUHJvcGVydGllczp0cnVlLFhNTERvY3VtZW50OnRy
-dWUsRG9jdW1lbnQ6ZmFsc2UsRE9NRXhjZXB0aW9uOnRydWUsRE9NSW1wbGVtZW50YXRpb246dHJ1ZSxE
-T01SZWN0UmVhZE9ubHk6ZmFsc2UsRE9NVG9rZW5MaXN0OnRydWUsRWxlbWVudDpmYWxzZSxBYm9ydFBh
-eW1lbnRFdmVudDp0cnVlLEFuaW1hdGlvbkV2ZW50OnRydWUsQW5pbWF0aW9uUGxheWJhY2tFdmVudDp0
-cnVlLEFwcGxpY2F0aW9uQ2FjaGVFcnJvckV2ZW50OnRydWUsQmFja2dyb3VuZEZldGNoQ2xpY2tFdmVu
-dDp0cnVlLEJhY2tncm91bmRGZXRjaEV2ZW50OnRydWUsQmFja2dyb3VuZEZldGNoRmFpbEV2ZW50OnRy
-dWUsQmFja2dyb3VuZEZldGNoZWRFdmVudDp0cnVlLEJlZm9yZUluc3RhbGxQcm9tcHRFdmVudDp0cnVl
-LEJlZm9yZVVubG9hZEV2ZW50OnRydWUsQmxvYkV2ZW50OnRydWUsQ2FuTWFrZVBheW1lbnRFdmVudDp0
-cnVlLENsaXBib2FyZEV2ZW50OnRydWUsQ2xvc2VFdmVudDp0cnVlLEN1c3RvbUV2ZW50OnRydWUsRGV2
-aWNlTW90aW9uRXZlbnQ6dHJ1ZSxEZXZpY2VPcmllbnRhdGlvbkV2ZW50OnRydWUsRXJyb3JFdmVudDp0
-cnVlLEV4dGVuZGFibGVFdmVudDp0cnVlLEV4dGVuZGFibGVNZXNzYWdlRXZlbnQ6dHJ1ZSxGZXRjaEV2
-ZW50OnRydWUsRm9udEZhY2VTZXRMb2FkRXZlbnQ6dHJ1ZSxGb3JlaWduRmV0Y2hFdmVudDp0cnVlLEdh
-bWVwYWRFdmVudDp0cnVlLEhhc2hDaGFuZ2VFdmVudDp0cnVlLEluc3RhbGxFdmVudDp0cnVlLE1lZGlh
-RW5jcnlwdGVkRXZlbnQ6dHJ1ZSxNZWRpYUtleU1lc3NhZ2VFdmVudDp0cnVlLE1lZGlhUXVlcnlMaXN0
-RXZlbnQ6dHJ1ZSxNZWRpYVN0cmVhbUV2ZW50OnRydWUsTWVkaWFTdHJlYW1UcmFja0V2ZW50OnRydWUs
-TWVzc2FnZUV2ZW50OnRydWUsTUlESUNvbm5lY3Rpb25FdmVudDp0cnVlLE1JRElNZXNzYWdlRXZlbnQ6
-dHJ1ZSxNdXRhdGlvbkV2ZW50OnRydWUsTm90aWZpY2F0aW9uRXZlbnQ6dHJ1ZSxQYWdlVHJhbnNpdGlv
-bkV2ZW50OnRydWUsUGF5bWVudFJlcXVlc3RFdmVudDp0cnVlLFBheW1lbnRSZXF1ZXN0VXBkYXRlRXZl
-bnQ6dHJ1ZSxQb3BTdGF0ZUV2ZW50OnRydWUsUHJlc2VudGF0aW9uQ29ubmVjdGlvbkF2YWlsYWJsZUV2
-ZW50OnRydWUsUHJlc2VudGF0aW9uQ29ubmVjdGlvbkNsb3NlRXZlbnQ6dHJ1ZSxQcm9taXNlUmVqZWN0
-aW9uRXZlbnQ6dHJ1ZSxQdXNoRXZlbnQ6dHJ1ZSxSVENEYXRhQ2hhbm5lbEV2ZW50OnRydWUsUlRDRFRN
-RlRvbmVDaGFuZ2VFdmVudDp0cnVlLFJUQ1BlZXJDb25uZWN0aW9uSWNlRXZlbnQ6dHJ1ZSxSVENUcmFj
-a0V2ZW50OnRydWUsU2VjdXJpdHlQb2xpY3lWaW9sYXRpb25FdmVudDp0cnVlLFNlbnNvckVycm9yRXZl
-bnQ6dHJ1ZSxTcGVlY2hSZWNvZ25pdGlvbkVycm9yOnRydWUsU3BlZWNoUmVjb2duaXRpb25FdmVudDp0
-cnVlLFNwZWVjaFN5bnRoZXNpc0V2ZW50OnRydWUsU3RvcmFnZUV2ZW50OnRydWUsU3luY0V2ZW50OnRy
-dWUsVHJhY2tFdmVudDp0cnVlLFRyYW5zaXRpb25FdmVudDp0cnVlLFdlYktpdFRyYW5zaXRpb25FdmVu
-dDp0cnVlLFZSRGV2aWNlRXZlbnQ6dHJ1ZSxWUkRpc3BsYXlFdmVudDp0cnVlLFZSU2Vzc2lvbkV2ZW50
-OnRydWUsTW9qb0ludGVyZmFjZVJlcXVlc3RFdmVudDp0cnVlLFVTQkNvbm5lY3Rpb25FdmVudDp0cnVl
-LElEQlZlcnNpb25DaGFuZ2VFdmVudDp0cnVlLEF1ZGlvUHJvY2Vzc2luZ0V2ZW50OnRydWUsT2ZmbGlu
-ZUF1ZGlvQ29tcGxldGlvbkV2ZW50OnRydWUsV2ViR0xDb250ZXh0RXZlbnQ6dHJ1ZSxFdmVudDpmYWxz
-ZSxJbnB1dEV2ZW50OmZhbHNlLFN1Ym1pdEV2ZW50OmZhbHNlLEV2ZW50VGFyZ2V0OmZhbHNlLEZpbGU6
-dHJ1ZSxIVE1MRm9ybUVsZW1lbnQ6dHJ1ZSxIaXN0b3J5OnRydWUsSFRNTERvY3VtZW50OnRydWUsWE1M
-SHR0cFJlcXVlc3Q6dHJ1ZSxYTUxIdHRwUmVxdWVzdEV2ZW50VGFyZ2V0OmZhbHNlLEltYWdlRGF0YTp0
-cnVlLExvY2F0aW9uOnRydWUsTW91c2VFdmVudDp0cnVlLERyYWdFdmVudDp0cnVlLFBvaW50ZXJFdmVu
-dDp0cnVlLFdoZWVsRXZlbnQ6dHJ1ZSxEb2N1bWVudEZyYWdtZW50OnRydWUsU2hhZG93Um9vdDp0cnVl
-LERvY3VtZW50VHlwZTp0cnVlLE5vZGU6ZmFsc2UsTm9kZUxpc3Q6dHJ1ZSxSYWRpb05vZGVMaXN0OnRy
-dWUsSFRNTFBhcmFncmFwaEVsZW1lbnQ6dHJ1ZSxQcm9ncmVzc0V2ZW50OnRydWUsUmVzb3VyY2VQcm9n
-cmVzc0V2ZW50OnRydWUsSFRNTFNlbGVjdEVsZW1lbnQ6dHJ1ZSxIVE1MVGFibGVFbGVtZW50OnRydWUs
-SFRNTFRhYmxlUm93RWxlbWVudDp0cnVlLEhUTUxUYWJsZVNlY3Rpb25FbGVtZW50OnRydWUsSFRNTFRl
-bXBsYXRlRWxlbWVudDp0cnVlLENvbXBvc2l0aW9uRXZlbnQ6dHJ1ZSxGb2N1c0V2ZW50OnRydWUsS2V5
-Ym9hcmRFdmVudDp0cnVlLFRleHRFdmVudDp0cnVlLFRvdWNoRXZlbnQ6dHJ1ZSxVSUV2ZW50OmZhbHNl
-LFdpbmRvdzp0cnVlLERPTVdpbmRvdzp0cnVlLERlZGljYXRlZFdvcmtlckdsb2JhbFNjb3BlOnRydWUs
-U2VydmljZVdvcmtlckdsb2JhbFNjb3BlOnRydWUsU2hhcmVkV29ya2VyR2xvYmFsU2NvcGU6dHJ1ZSxX
-b3JrZXJHbG9iYWxTY29wZTp0cnVlLEF0dHI6dHJ1ZSxDbGllbnRSZWN0OnRydWUsRE9NUmVjdDp0cnVl
-LE5hbWVkTm9kZU1hcDp0cnVlLE1vek5hbWVkQXR0ck1hcDp0cnVlLElEQktleVJhbmdlOnRydWUsU1ZH
-U2NyaXB0RWxlbWVudDp0cnVlLFNWR0FFbGVtZW50OnRydWUsU1ZHQW5pbWF0ZUVsZW1lbnQ6dHJ1ZSxT
-VkdBbmltYXRlTW90aW9uRWxlbWVudDp0cnVlLFNWR0FuaW1hdGVUcmFuc2Zvcm1FbGVtZW50OnRydWUs
-U1ZHQW5pbWF0aW9uRWxlbWVudDp0cnVlLFNWR0NpcmNsZUVsZW1lbnQ6dHJ1ZSxTVkdDbGlwUGF0aEVs
-ZW1lbnQ6dHJ1ZSxTVkdEZWZzRWxlbWVudDp0cnVlLFNWR0Rlc2NFbGVtZW50OnRydWUsU1ZHRGlzY2Fy
-ZEVsZW1lbnQ6dHJ1ZSxTVkdFbGxpcHNlRWxlbWVudDp0cnVlLFNWR0ZFQmxlbmRFbGVtZW50OnRydWUs
-U1ZHRkVDb2xvck1hdHJpeEVsZW1lbnQ6dHJ1ZSxTVkdGRUNvbXBvbmVudFRyYW5zZmVyRWxlbWVudDp0
-cnVlLFNWR0ZFQ29tcG9zaXRlRWxlbWVudDp0cnVlLFNWR0ZFQ29udm9sdmVNYXRyaXhFbGVtZW50OnRy
-dWUsU1ZHRkVEaWZmdXNlTGlnaHRpbmdFbGVtZW50OnRydWUsU1ZHRkVEaXNwbGFjZW1lbnRNYXBFbGVt
-ZW50OnRydWUsU1ZHRkVEaXN0YW50TGlnaHRFbGVtZW50OnRydWUsU1ZHRkVGbG9vZEVsZW1lbnQ6dHJ1
-ZSxTVkdGRUZ1bmNBRWxlbWVudDp0cnVlLFNWR0ZFRnVuY0JFbGVtZW50OnRydWUsU1ZHRkVGdW5jR0Vs
-ZW1lbnQ6dHJ1ZSxTVkdGRUZ1bmNSRWxlbWVudDp0cnVlLFNWR0ZFR2F1c3NpYW5CbHVyRWxlbWVudDp0
-cnVlLFNWR0ZFSW1hZ2VFbGVtZW50OnRydWUsU1ZHRkVNZXJnZUVsZW1lbnQ6dHJ1ZSxTVkdGRU1lcmdl
-Tm9kZUVsZW1lbnQ6dHJ1ZSxTVkdGRU1vcnBob2xvZ3lFbGVtZW50OnRydWUsU1ZHRkVPZmZzZXRFbGVt
-ZW50OnRydWUsU1ZHRkVQb2ludExpZ2h0RWxlbWVudDp0cnVlLFNWR0ZFU3BlY3VsYXJMaWdodGluZ0Vs
-ZW1lbnQ6dHJ1ZSxTVkdGRVNwb3RMaWdodEVsZW1lbnQ6dHJ1ZSxTVkdGRVRpbGVFbGVtZW50OnRydWUs
-U1ZHRkVUdXJidWxlbmNlRWxlbWVudDp0cnVlLFNWR0ZpbHRlckVsZW1lbnQ6dHJ1ZSxTVkdGb3JlaWdu
-T2JqZWN0RWxlbWVudDp0cnVlLFNWR0dFbGVtZW50OnRydWUsU1ZHR2VvbWV0cnlFbGVtZW50OnRydWUs
-U1ZHR3JhcGhpY3NFbGVtZW50OnRydWUsU1ZHSW1hZ2VFbGVtZW50OnRydWUsU1ZHTGluZUVsZW1lbnQ6
-dHJ1ZSxTVkdMaW5lYXJHcmFkaWVudEVsZW1lbnQ6dHJ1ZSxTVkdNYXJrZXJFbGVtZW50OnRydWUsU1ZH
-TWFza0VsZW1lbnQ6dHJ1ZSxTVkdNZXRhZGF0YUVsZW1lbnQ6dHJ1ZSxTVkdQYXRoRWxlbWVudDp0cnVl
-LFNWR1BhdHRlcm5FbGVtZW50OnRydWUsU1ZHUG9seWdvbkVsZW1lbnQ6dHJ1ZSxTVkdQb2x5bGluZUVs
-ZW1lbnQ6dHJ1ZSxTVkdSYWRpYWxHcmFkaWVudEVsZW1lbnQ6dHJ1ZSxTVkdSZWN0RWxlbWVudDp0cnVl
-LFNWR1NldEVsZW1lbnQ6dHJ1ZSxTVkdTdG9wRWxlbWVudDp0cnVlLFNWR1N0eWxlRWxlbWVudDp0cnVl
-LFNWR1NWR0VsZW1lbnQ6dHJ1ZSxTVkdTd2l0Y2hFbGVtZW50OnRydWUsU1ZHU3ltYm9sRWxlbWVudDp0
-cnVlLFNWR1RTcGFuRWxlbWVudDp0cnVlLFNWR1RleHRDb250ZW50RWxlbWVudDp0cnVlLFNWR1RleHRF
-bGVtZW50OnRydWUsU1ZHVGV4dFBhdGhFbGVtZW50OnRydWUsU1ZHVGV4dFBvc2l0aW9uaW5nRWxlbWVu
-dDp0cnVlLFNWR1RpdGxlRWxlbWVudDp0cnVlLFNWR1VzZUVsZW1lbnQ6dHJ1ZSxTVkdWaWV3RWxlbWVu
-dDp0cnVlLFNWR0dyYWRpZW50RWxlbWVudDp0cnVlLFNWR0NvbXBvbmVudFRyYW5zZmVyRnVuY3Rpb25F
-bGVtZW50OnRydWUsU1ZHRkVEcm9wU2hhZG93RWxlbWVudDp0cnVlLFNWR01QYXRoRWxlbWVudDp0cnVl
-LFNWR0VsZW1lbnQ6ZmFsc2V9KQpILkxaLiRuYXRpdmVTdXBlcmNsYXNzVGFnPSJBcnJheUJ1ZmZlclZp
-ZXciCkguUkcuJG5hdGl2ZVN1cGVyY2xhc3NUYWc9IkFycmF5QnVmZmVyVmlldyIKSC5WUC4kbmF0aXZl
-U3VwZXJjbGFzc1RhZz0iQXJyYXlCdWZmZXJWaWV3IgpILkRnLiRuYXRpdmVTdXBlcmNsYXNzVGFnPSJB
-cnJheUJ1ZmZlclZpZXciCkguV0IuJG5hdGl2ZVN1cGVyY2xhc3NUYWc9IkFycmF5QnVmZmVyVmlldyIK
-SC5aRy4kbmF0aXZlU3VwZXJjbGFzc1RhZz0iQXJyYXlCdWZmZXJWaWV3IgpILlBnLiRuYXRpdmVTdXBl
-cmNsYXNzVGFnPSJBcnJheUJ1ZmZlclZpZXcifSkoKQpjb252ZXJ0QWxsVG9GYXN0T2JqZWN0KHcpCmNv
-bnZlcnRUb0Zhc3RPYmplY3QoJCk7KGZ1bmN0aW9uKGEpe2lmKHR5cGVvZiBkb2N1bWVudD09PSJ1bmRl
-ZmluZWQiKXthKG51bGwpCnJldHVybn1pZih0eXBlb2YgZG9jdW1lbnQuY3VycmVudFNjcmlwdCE9J3Vu
-ZGVmaW5lZCcpe2EoZG9jdW1lbnQuY3VycmVudFNjcmlwdCkKcmV0dXJufXZhciBzPWRvY3VtZW50LnNj
-cmlwdHMKZnVuY3Rpb24gb25Mb2FkKGIpe2Zvcih2YXIgcT0wO3E8cy5sZW5ndGg7KytxKXNbcV0ucmVt
-b3ZlRXZlbnRMaXN0ZW5lcigibG9hZCIsb25Mb2FkLGZhbHNlKQphKGIudGFyZ2V0KX1mb3IodmFyIHI9
-MDtyPHMubGVuZ3RoOysrcilzW3JdLmFkZEV2ZW50TGlzdGVuZXIoImxvYWQiLG9uTG9hZCxmYWxzZSl9
-KShmdW5jdGlvbihhKXt2LmN1cnJlbnRTY3JpcHQ9YQppZih0eXBlb2YgZGFydE1haW5SdW5uZXI9PT0i
-ZnVuY3Rpb24iKWRhcnRNYWluUnVubmVyKEwuSXEsW10pCmVsc2UgTC5JcShbXSl9KX0pKCkKLy8jIHNv
-dXJjZU1hcHBpbmdVUkw9bWlncmF0aW9uLmpzLm1hcAo=
+YikKcmV0dXJuIHRoaXMuJHRpLmMuYSh0aGlzLlVyKDAsYikpfSwKWTU6ZnVuY3Rpb24oYSxiLGMpe3Ro
+aXMuY1AoYikKdGhpcy5lNCgwLGIsYyl9LApnQTpmdW5jdGlvbihhKXt2YXIgcz10aGlzLmEubGVuZ3Ro
+CmlmKHR5cGVvZiBzPT09Im51bWJlciImJnM+Pj4wPT09cylyZXR1cm4gcwp0aHJvdyBILmIoUC5QVigi
+QmFkIEpzQXJyYXkgbGVuZ3RoIikpfSwKJGliUToxLAokaWNYOjEsCiRpek06MX0KUC5jby5wcm90b3R5
+cGU9e30KUC5uZC5wcm90b3R5cGU9eyRpbmQ6MX0KUC5LZS5wcm90b3R5cGU9ewpEOmZ1bmN0aW9uKCl7
+dmFyIHMscixxLHAsbz10aGlzLmEuZ2V0QXR0cmlidXRlKCJjbGFzcyIpLG49UC5Mcyh0Lk4pCmlmKG89
+PW51bGwpcmV0dXJuIG4KZm9yKHM9by5zcGxpdCgiICIpLHI9cy5sZW5ndGgscT0wO3E8cjsrK3Epe3A9
+Si5UMChzW3FdKQppZihwLmxlbmd0aCE9PTApbi5pKDAscCl9cmV0dXJuIG59LApYOmZ1bmN0aW9uKGEp
+e3RoaXMuYS5zZXRBdHRyaWJ1dGUoImNsYXNzIixhLmsoMCwiICIpKX19ClAuaGkucHJvdG90eXBlPXsK
+Z246ZnVuY3Rpb24oYSl7cmV0dXJuIG5ldyBQLktlKGEpfSwKc2hmOmZ1bmN0aW9uKGEsYil7dGhpcy5Z
+QyhhLGIpfSwKcjY6ZnVuY3Rpb24oYSxiLGMsZCl7dmFyIHMscixxLHAsbyxuCmlmKGQ9PW51bGwpe3M9
+SC5WTShbXSx0LnYpCmQ9bmV3IFcudkQocykKQy5ObS5pKHMsVy5UdyhudWxsKSkKQy5ObS5pKHMsVy5C
+bCgpKQpDLk5tLmkocyxuZXcgVy5PdygpKX1jPW5ldyBXLktvKGQpCnI9JzxzdmcgdmVyc2lvbj0iMS4x
+Ij4nK0guRWooYikrIjwvc3ZnPiIKcz1kb2N1bWVudApxPXMuYm9keQpxLnRvU3RyaW5nCnA9Qy5SWS5B
+SChxLHIsYykKbz1zLmNyZWF0ZURvY3VtZW50RnJhZ21lbnQoKQpwLnRvU3RyaW5nCnM9bmV3IFcuZTco
+cCkKbj1zLmdyOChzKQpmb3IoO3M9bi5maXJzdENoaWxkLHMhPW51bGw7KW8uYXBwZW5kQ2hpbGQocykK
+cmV0dXJuIG99LApuejpmdW5jdGlvbihhLGIsYyxkLGUpe3Rocm93IEguYihQLkw0KCJDYW5ub3QgaW52
+b2tlIGluc2VydEFkamFjZW50SHRtbCBvbiBTVkcuIikpfSwKZ1ZsOmZ1bmN0aW9uKGEpe3JldHVybiBu
+ZXcgVy5ldShhLCJjbGljayIsITEsdC5rKX0sCiRpaGk6MX0KTS5INy5wcm90b3R5cGU9ewp3OmZ1bmN0
+aW9uKGEpe3JldHVybiB0aGlzLmJ9fQpVLkxMLnByb3RvdHlwZT17Ckx0OmZ1bmN0aW9uKCl7cmV0dXJu
+IFAuRUYoWyJub2RlSWQiLHRoaXMuYiwia2luZCIsdGhpcy5hLmFdLHQuWCx0Ll8pfX0KVS5NRC5wcm90
+b3R5cGU9ewokMTpmdW5jdGlvbihhKXtyZXR1cm4gdC5mRS5hKGEpLmE9PT10aGlzLmEucSgwLCJraW5k
+Iil9LAokUzozOH0KVS5kMi5wcm90b3R5cGU9ewpMdDpmdW5jdGlvbigpe3ZhciBzLHIscSxwLG89dGhp
+cyxuPXQuWCxtPXQuXyxsPVAuRmwobixtKSxrPW8uYQppZihrIT1udWxsKXtzPUguVk0oW10sdC5HKQpm
+b3Iocj1rLmxlbmd0aCxxPTA7cTxrLmxlbmd0aDtrLmxlbmd0aD09PXJ8fCgwLEgubGspKGspLCsrcSl7
+cD1rW3FdCnMucHVzaChQLkVGKFsiZGVzY3JpcHRpb24iLHAuYSwiaHJlZiIscC5iXSxuLG0pKX1sLlk1
+KDAsImVkaXRzIixzKX1sLlk1KDAsImV4cGxhbmF0aW9uIixvLmIpCmwuWTUoMCwibGluZSIsby5jKQps
+Llk1KDAsImRpc3BsYXlQYXRoIixvLmQpCmwuWTUoMCwidXJpUGF0aCIsby5lKQpuPW8uZgppZihuIT1u
+dWxsKXttPUguVk0oW10sdC5HKQpmb3Ioaz1uLmxlbmd0aCxxPTA7cTxuLmxlbmd0aDtuLmxlbmd0aD09
+PWt8fCgwLEgubGspKG4pLCsrcSltLnB1c2gobltxXS5MdCgpKQpsLlk1KDAsInRyYWNlcyIsbSl9cmV0
+dXJuIGx9fQpVLlNlLnByb3RvdHlwZT17Ckx0OmZ1bmN0aW9uKCl7cmV0dXJuIFAuRUYoWyJkZXNjcmlw
+dGlvbiIsdGhpcy5hLCJocmVmIix0aGlzLmJdLHQuWCx0Ll8pfX0KVS5NbC5wcm90b3R5cGU9ewpMdDpm
+dW5jdGlvbigpe3JldHVybiBQLkVGKFsiaHJlZiIsdGhpcy5hLCJsaW5lIix0aGlzLmIsInBhdGgiLHRo
+aXMuY10sdC5YLHQuXyl9fQpVLnlELnByb3RvdHlwZT17Ckx0OmZ1bmN0aW9uKCl7dmFyIHMscixxLHA9
+SC5WTShbXSx0LkcpCmZvcihzPXRoaXMuYixyPXMubGVuZ3RoLHE9MDtxPHMubGVuZ3RoO3MubGVuZ3Ro
+PT09cnx8KDAsSC5saykocyksKytxKXAucHVzaChzW3FdLkx0KCkpCnJldHVybiBQLkVGKFsiZGVzY3Jp
+cHRpb24iLHRoaXMuYSwiZW50cmllcyIscF0sdC5YLHQuXyl9fQpVLndiLnByb3RvdHlwZT17Ckx0OmZ1
+bmN0aW9uKCl7dmFyIHMscixxLHA9dGhpcyxvPVAuRmwodC5YLHQuXykKby5ZNSgwLCJkZXNjcmlwdGlv
+biIscC5hKQpzPXAuYgppZihzIT1udWxsKW8uWTUoMCwiZnVuY3Rpb24iLHMpCnM9cC5jCmlmKHMhPW51
+bGwpby5ZNSgwLCJsaW5rIixzLkx0KCkpCnM9cC5kCmlmKHMubGVuZ3RoIT09MCl7cj1ILnQ2KHMpCnE9
+ci5DKCJsSjwxLFowPHFVKixNaCo+Kj4iKQpvLlk1KDAsImhpbnRBY3Rpb25zIixQLlkxKG5ldyBILmxK
+KHMsci5DKCJaMDxxVSosTWgqPiooMSkiKS5hKG5ldyBVLmIwKCkpLHEpLCEwLHEuQygiYUwuRSIpKSl9
+cmV0dXJuIG99fQpVLmFOLnByb3RvdHlwZT17CiQxOmZ1bmN0aW9uKGEpe3JldHVybiBVLm56KHQudC5h
+KGEpKX0sCiRTOjM5fQpVLmIwLnByb3RvdHlwZT17CiQxOmZ1bmN0aW9uKGEpe3JldHVybiB0LmFYLmEo
+YSkuTHQoKX0sCiRTOjQwfQpCLmo4LnByb3RvdHlwZT17Ckx0OmZ1bmN0aW9uKCl7cmV0dXJuIFAuRUYo
+WyJsaW5lIix0aGlzLmEsImV4cGxhbmF0aW9uIix0aGlzLmIsIm9mZnNldCIsdGhpcy5jXSx0LlgsdC5f
+KX19CkIucXAucHJvdG90eXBlPXsKTHQ6ZnVuY3Rpb24oKXt2YXIgcyxyLHEscCxvLG4sbSxsPXRoaXMs
+az10Llgsaj1QLkZsKGssdC5kcCkKZm9yKHM9bC5kLHM9cy5nUHUocykscz1zLmdtKHMpLHI9dC5fLHE9
+dC5HO3MuRigpOyl7cD1zLmdsKCkKbz1wLmEKbj1ILlZNKFtdLHEpCmZvcihwPUouSVQocC5iKTtwLkYo
+KTspe209cC5nbCgpCm4ucHVzaChQLkVGKFsibGluZSIsbS5hLCJleHBsYW5hdGlvbiIsbS5iLCJvZmZz
+ZXQiLG0uY10sayxyKSl9ai5ZNSgwLG8sbil9cmV0dXJuIFAuRUYoWyJyZWdpb25zIixsLmEsIm5hdmln
+YXRpb25Db250ZW50IixsLmIsInNvdXJjZUNvZGUiLGwuYywiZWRpdHMiLGpdLGsscil9fQpULm1RLnBy
+b3RvdHlwZT17fQpMLmUucHJvdG90eXBlPXsKJDE6ZnVuY3Rpb24oYSl7dmFyIHMscixxLHAsbyxuLG0K
+dC5hTC5hKGEpCnM9d2luZG93LmxvY2F0aW9uLnBhdGhuYW1lCnI9TC5HNih3aW5kb3cubG9jYXRpb24u
+aHJlZikKcT1MLmFLKHdpbmRvdy5sb2NhdGlvbi5ocmVmKQpMLkdlKCkKaWYocyE9PSIvIiYmcyE9PUou
+VDAoZG9jdW1lbnQucXVlcnlTZWxlY3RvcigiLnJvb3QiKS50ZXh0Q29udGVudCkpTC5HNyhzLHIscSwh
+MCxuZXcgTC5WVyhzLHIscSkpCnA9ZG9jdW1lbnQKbz1KLnFGKHAucXVlcnlTZWxlY3RvcigiLmFwcGx5
+LW1pZ3JhdGlvbiIpKQpuPW8uJHRpCm09bi5DKCJ+KDEpPyIpLmEobmV3IEwub1ooKSkKdC5aLmEobnVs
+bCkKVy5KRShvLmEsby5iLG0sITEsbi5jKQpuPUoucUYocC5xdWVyeVNlbGVjdG9yKCIucmVydW4tbWln
+cmF0aW9uIikpCm09bi4kdGkKVy5KRShuLmEsbi5iLG0uQygifigxKT8iKS5hKG5ldyBMLkhpKCkpLCEx
+LG0uYykKbT1KLnFGKHAucXVlcnlTZWxlY3RvcigiLnJlcG9ydC1wcm9ibGVtIikpCm49bS4kdGkKVy5K
+RShtLmEsbS5iLG4uQygifigxKT8iKS5hKG5ldyBMLkJUKCkpLCExLG4uYykKcD1KLnFGKHAucXVlcnlT
+ZWxlY3RvcigiLnBvcHVwLXBhbmUgLmNsb3NlIikpCm49cC4kdGkKVy5KRShwLmEscC5iLG4uQygifigx
+KT8iKS5hKG5ldyBMLlBZKCkpLCExLG4uYykKbj1KLnFGKCQuYzAoKSkKcD1uLiR0aQpXLkpFKG4uYSxu
+LmIscC5DKCJ+KDEpPyIpLmEobmV3IEwudTgoKSksITEscC5jKX0sCiRTOjE4fQpMLlZXLnByb3RvdHlw
+ZT17CiQwOmZ1bmN0aW9uKCl7TC5Gcih0aGlzLmEsdGhpcy5iLHRoaXMuYyl9LAokUzoyfQpMLm9aLnBy
+b3RvdHlwZT17CiQxOmZ1bmN0aW9uKGEpe3ZhciBzLHIscSxwCnQuTy5hKGEpCmlmKEgub1QoQy5vbC51
+cyh3aW5kb3csIlRoaXMgd2lsbCBhcHBseSB0aGUgY2hhbmdlcyB5b3UndmUgcHJldmlld2VkIHRvIHlv
+dXIgd29ya2luZyBkaXJlY3RvcnkuIEl0IGlzIHJlY29tbWVuZGVkIHlvdSBjb21taXQgYW55IGNoYW5n
+ZXMgeW91IG1hZGUgYmVmb3JlIGRvaW5nIHRoaXMuIikpKXtzPUwudHkoIi9hcHBseS1taWdyYXRpb24i
+LG51bGwpLlc3KG5ldyBMLmpyKCksdC5QKQpyPW5ldyBMLnFsKCkKdC5iNy5hKG51bGwpCnE9cy4kdGkK
+cD0kLlgzCmlmKHAhPT1DLk5VKXI9UC5WSChyLHApCnMueGYobmV3IFAuRmUobmV3IFAudnMocCxxKSwy
+LG51bGwscixxLkMoIkA8MT4iKS5LcShxLmMpLkMoIkZlPDEsMj4iKSkpfX0sCiRTOjF9CkwuanIucHJv
+dG90eXBlPXsKJDE6ZnVuY3Rpb24oYSl7dmFyIHMKdC50LmEoYSkKcz1kb2N1bWVudC5ib2R5CnMuY2xh
+c3NMaXN0LnJlbW92ZSgicHJvcG9zZWQiKQpzLmNsYXNzTGlzdC5hZGQoImFwcGxpZWQiKX0sCiRTOjQz
+fQpMLnFsLnByb3RvdHlwZT17CiQyOmZ1bmN0aW9uKGEsYil7TC5DMigiQ291bGQgbm90IGFwcGx5IG1p
+Z3JhdGlvbiIsYSxiKX0sCiRDOiIkMiIsCiRSOjIsCiRTOjE2fQpMLkhpLnByb3RvdHlwZT17CiQxOmZ1
+bmN0aW9uKGEpe3JldHVybiB0aGlzLnhuKHQuTy5hKGEpKX0sCnhuOmZ1bmN0aW9uKGEpe3ZhciBzPTAs
+cj1QLkZYKHQuUCkscT0xLHAsbz1bXSxuLG0sbCxrLGoKdmFyICRhc3luYyQkMT1QLmx6KGZ1bmN0aW9u
+KGIsYyl7aWYoYj09PTEpe3A9YwpzPXF9d2hpbGUodHJ1ZSlzd2l0Y2gocyl7Y2FzZSAwOnE9Mwpkb2N1
+bWVudC5ib2R5LmNsYXNzTGlzdC5hZGQoInJlcnVubmluZyIpCnM9NgpyZXR1cm4gUC5qUShMLnR5KCIv
+cmVydW4tbWlncmF0aW9uIixudWxsKSwkYXN5bmMkJDEpCmNhc2UgNjpuPWMKaWYoSC5vVChILnk4KEou
+eDkobiwic3VjY2VzcyIpKSkpd2luZG93LmxvY2F0aW9uLnJlbG9hZCgpCmVsc2UgTC5LMCh0Lm0uYShK
+Lng5KG4sImVycm9ycyIpKSkKby5wdXNoKDUpCnM9NApicmVhawpjYXNlIDM6cT0yCmo9cAptPUguUnUo
+aikKbD1ILnRzKGopCkwuQzIoIkZhaWxlZCB0byByZXJ1biBtaWdyYXRpb24iLG0sbCkKby5wdXNoKDUp
+CnM9NApicmVhawpjYXNlIDI6bz1bMV0KY2FzZSA0OnE9MQpkb2N1bWVudC5ib2R5LmNsYXNzTGlzdC5y
+ZW1vdmUoInJlcnVubmluZyIpCnM9by5wb3AoKQpicmVhawpjYXNlIDU6cmV0dXJuIFAueUMobnVsbCxy
+KQpjYXNlIDE6cmV0dXJuIFAuZjMocCxyKX19KQpyZXR1cm4gUC5ESSgkYXN5bmMkJDEscil9LAokUzox
+OX0KTC5CVC5wcm90b3R5cGU9ewokMTpmdW5jdGlvbihhKXt2YXIgcwp0Lk8uYShhKQpzPXQuWApDLm9s
+LlBvKHdpbmRvdyxQLlhkKCJodHRwcyIsImdpdGh1Yi5jb20iLCJkYXJ0LWxhbmcvc2RrL2lzc3Vlcy9u
+ZXciLFAuRUYoWyJ0aXRsZSIsIkN1c3RvbWVyLXJlcG9ydGVkIGlzc3VlIHdpdGggTk5CRCBtaWdyYXRp
+b24gdG9vbCIsImxhYmVscyIsdS5kLCJib2R5IiwiIyMjIyBTdGVwcyB0byByZXByb2R1Y2VcblxuIyMj
+IyBXaGF0IGRpZCB5b3UgZXhwZWN0IHRvIGhhcHBlbj9cblxuIyMjIyBXaGF0IGFjdHVhbGx5IGhhcHBl
+bmVkP1xuXG5fU2NyZWVuc2hvdHMgYXJlIGFwcHJlY2lhdGVkX1xuXG4qKkRhcnQgU0RLIHZlcnNpb24q
+KjogIitILkVqKGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCJzZGstdmVyc2lvbiIpLnRleHRDb250ZW50
+KSsiXG5cblRoYW5rcyBmb3IgZmlsaW5nIVxuIl0scyxzKSkuZ25EKCksInJlcG9ydC1wcm9ibGVtIil9
+LAokUzoxfQpMLlBZLnByb3RvdHlwZT17CiQxOmZ1bmN0aW9uKGEpe3ZhciBzCnQuTy5hKGEpCnM9ZG9j
+dW1lbnQucXVlcnlTZWxlY3RvcigiLnBvcHVwLXBhbmUiKS5zdHlsZQpzLmRpc3BsYXk9Im5vbmUiCnJl
+dHVybiJub25lIn0sCiRTOjQ1fQpMLnU4LnByb3RvdHlwZT17CiQxOmZ1bmN0aW9uKGEpe3ZhciBzLHIs
+cSxwCnQuTy5hKGEpCnM9JC5EOSgpLmlubmVyVGV4dApyPXQuZy5hKGRvY3VtZW50LnF1ZXJ5U2VsZWN0
+b3IoJy5uYXYtcGFuZWwgW2RhdGEtbmFtZSo9IicrSC5FaihzKSsnIl0nKS5wYXJlbnROb2RlKQpxPXIu
+cXVlcnlTZWxlY3RvcigiLnN0YXR1cy1pY29uIikKcD1MLm1IKCQuSVIscykKaWYocCBpbnN0YW5jZW9m
+IEwuY0Qpe0wuT3QocCkKTC54bihxLHApCkwuQVIocixwKX19LAokUzoxfQpMLkwucHJvdG90eXBlPXsK
+JDE6ZnVuY3Rpb24oYSl7dmFyIHMscixxCnQuYUwuYShhKQpzPXdpbmRvdy5sb2NhdGlvbi5wYXRobmFt
+ZQpyPUwuRzYod2luZG93LmxvY2F0aW9uLmhyZWYpCnE9TC5hSyh3aW5kb3cubG9jYXRpb24uaHJlZikK
+aWYocy5sZW5ndGg+MSlMLkc3KHMscixxLCExLG51bGwpCmVsc2V7TC5CRShzLEIud1IoKSwhMCkKTC5C
+WCgiJm5ic3A7IixudWxsKX19LAokUzoxOH0KTC5XeC5wcm90b3R5cGU9ewokMTpmdW5jdGlvbihhKXt2
+YXIgcyxyLHEscD0iY29sbGFwc2VkIgp0Lk8uYShhKQpzPXRoaXMuYQpyPUouWUUocykKcT10aGlzLmIK
+aWYoIXIuZ24ocykudGcoMCxwKSl7ci5nbihzKS5pKDAscCkKSi5kUihxKS5pKDAscCl9ZWxzZXtyLmdu
+KHMpLkwoMCxwKQpKLmRSKHEpLkwoMCxwKX19LAokUzoxfQpMLkFPLnByb3RvdHlwZT17CiQxOmZ1bmN0
+aW9uKGEpe3ZhciBzPUoucUYodC5nLmEoYSkpLHI9cy4kdGkscT1yLkMoIn4oMSk/IikuYShuZXcgTC5k
+Tih0aGlzLmEpKQp0LlouYShudWxsKQpXLkpFKHMuYSxzLmIscSwhMSxyLmMpfSwKJFM6M30KTC5kTi5w
+cm90b3R5cGU9ewokMTpmdW5jdGlvbihhKXt2YXIgcwp0Lk8uYShhKQpzPWRvY3VtZW50LnF1ZXJ5U2Vs
+ZWN0b3IoInRhYmxlW2RhdGEtcGF0aF0iKQpzLnRvU3RyaW5nCkwudDIoYSx0aGlzLmEscy5nZXRBdHRy
+aWJ1dGUoImRhdGEtIituZXcgVy5TeShuZXcgVy5pNyhzKSkuUCgicGF0aCIpKSl9LAokUzoxfQpMLkhv
+LnByb3RvdHlwZT17CiQxOmZ1bmN0aW9uKGEpe3ZhciBzLHIscQp0LmcuYShhKQpzPUoucUYoYSkKcj1z
+LiR0aQpxPXIuQygifigxKT8iKS5hKG5ldyBMLnh6KGEsdGhpcy5hKSkKdC5aLmEobnVsbCkKVy5KRShz
+LmEscy5iLHEsITEsci5jKX0sCiRTOjN9CkwueHoucHJvdG90eXBlPXsKJDE6ZnVuY3Rpb24oYSl7dmFy
+IHMKdC5PLmEoYSkKcz10aGlzLmEKTC5oWCh0aGlzLmIsUC5RQShzLmdldEF0dHJpYnV0ZSgiZGF0YS0i
+K25ldyBXLlN5KG5ldyBXLmk3KHMpKS5QKCJvZmZzZXQiKSksbnVsbCksUC5RQShzLmdldEF0dHJpYnV0
+ZSgiZGF0YS0iK25ldyBXLlN5KG5ldyBXLmk3KHMpKS5QKCJsaW5lIikpLG51bGwpKX0sCiRTOjF9Ckwu
+SUMucHJvdG90eXBlPXsKJDE6ZnVuY3Rpb24oYSl7dmFyIHM9Si5xRih0LmcuYShhKSkscj1zLiR0aQpy
+LkMoIn4oMSk/IikuYShMLmlTKCkpCnQuWi5hKG51bGwpClcuSkUocy5hLHMuYixMLmlTKCksITEsci5j
+KX0sCiRTOjN9CkwuZkMucHJvdG90eXBlPXsKJDE6ZnVuY3Rpb24oYSl7dC5lUS5hKGEpCnRoaXMuYS5h
+TSgwLHRoaXMuYil9LAokUzo0N30KTC5uVC5wcm90b3R5cGU9ewokMDpmdW5jdGlvbigpe0wuRnIodGhp
+cy5hLHRoaXMuYix0aGlzLmMpfSwKJFM6Mn0KTC5OWS5wcm90b3R5cGU9ewokMDpmdW5jdGlvbigpe0wu
+RnIodGhpcy5hLG51bGwsbnVsbCl9LAokUzoyfQpMLnVlLnByb3RvdHlwZT17CiQxOmZ1bmN0aW9uKGEp
+e3QuYXcuYShhKQpyZXR1cm4gSC5FaihhLnEoMCwic2V2ZXJpdHkiKSkrIiAtICIrSC5FaihhLnEoMCwi
+bWVzc2FnZSIpKSsiIGF0ICIrSC5FaihhLnEoMCwibG9jYXRpb24iKSkrIiAtICgiK0guRWooYS5xKDAs
+ImNvZGUiKSkrIikifSwKJFM6NDh9CkwuZVgucHJvdG90eXBlPXsKJDE6ZnVuY3Rpb24oYSl7dC5nLmEo
+YSkKJC56QigpLnRvU3RyaW5nCnQuZEguYSgkLm93KCkucSgwLCJobGpzIikpLlY3KCJoaWdobGlnaHRC
+bG9jayIsW2FdKX0sCiRTOjN9CkwuRUUucHJvdG90eXBlPXsKJDE6ZnVuY3Rpb24oYSl7dmFyIHMscgp0
+Lk8uYShhKS5wcmV2ZW50RGVmYXVsdCgpCnM9dGhpcy5hCnI9dGhpcy5iCkwuYWYod2luZG93LmxvY2F0
+aW9uLnBhdGhuYW1lLHMsciwhMCxuZXcgTC5RTChzLHIpKQpMLmhYKHRoaXMuYyxzLHIpfSwKJFM6MX0K
+TC5RTC5wcm90b3R5cGU9ewokMDpmdW5jdGlvbigpe0wuRnIod2luZG93LmxvY2F0aW9uLnBhdGhuYW1l
+LHRoaXMuYSx0aGlzLmIpfSwKJFM6Mn0KTC5WUy5wcm90b3R5cGU9ewokMTpmdW5jdGlvbihhKXt2YXIg
+cyxyPSJzZWxlY3RlZC1maWxlIgp0LmcuYShhKQphLnRvU3RyaW5nCnM9Si5ZRShhKQppZihhLmdldEF0
+dHJpYnV0ZSgiZGF0YS0iK25ldyBXLlN5KG5ldyBXLmk3KGEpKS5QKCJuYW1lIikpPT09dGhpcy5hLmEp
+cy5nbihhKS5pKDAscikKZWxzZSBzLmduKGEpLkwoMCxyKX0sCiRTOjN9CkwuVEQucHJvdG90eXBlPXsK
+JDE6ZnVuY3Rpb24oYSl7cmV0dXJuIEwudDIodC5PLmEoYSksITAsbnVsbCl9LAokUzoyMH0KTC5tMi5w
+cm90b3R5cGU9ewokMTpmdW5jdGlvbihhKXtyZXR1cm4gdGhpcy5SSSh0Lk8uYShhKSl9LApSSTpmdW5j
+dGlvbihhKXt2YXIgcz0wLHI9UC5GWCh0LlApLHE9MSxwLG89W10sbj10aGlzLG0sbCxrLGosaSxoLGcs
+Zgp2YXIgJGFzeW5jJCQxPVAubHooZnVuY3Rpb24oYixjKXtpZihiPT09MSl7cD1jCnM9cX13aGlsZSh0
+cnVlKXN3aXRjaChzKXtjYXNlIDA6cT0zCmk9ZG9jdW1lbnQKbT1DLkNELnpRKGkucXVlcnlTZWxlY3Rv
+cigiLmNvbnRlbnQiKS5zY3JvbGxUb3ApCmg9dC5YCnM9NgpyZXR1cm4gUC5qUShMLnR5KEwuUTQoIi9h
+cHBseS1oaW50IixQLkZsKGgsaCkpLG4uYS5MdCgpKSwkYXN5bmMkJDEpCmNhc2UgNjpoPW4uYgpsPUwu
+VXMoaC5hKQpzPTcKcmV0dXJuIFAualEoTC5HNyhsLG51bGwsaC5iLCExLG51bGwpLCRhc3luYyQkMSkK
+Y2FzZSA3OmkuYm9keS5jbGFzc0xpc3QuYWRkKCJuZWVkcy1yZXJ1biIpCmk9aS5xdWVyeVNlbGVjdG9y
+KCIuY29udGVudCIpCmkudG9TdHJpbmcKaS5zY3JvbGxUb3A9Si5WdShtKQpxPTEKcz01CmJyZWFrCmNh
+c2UgMzpxPTIKZj1wCms9SC5SdShmKQpqPUgudHMoZikKTC5DMigiQ291bGQgbm90IGFwcGx5IGhpbnQi
+LGssaikKcz01CmJyZWFrCmNhc2UgMjpzPTEKYnJlYWsKY2FzZSA1OnJldHVybiBQLnlDKG51bGwscikK
+Y2FzZSAxOnJldHVybiBQLmYzKHAscil9fSkKcmV0dXJuIFAuREkoJGFzeW5jJCQxLHIpfSwKJFM6MTl9
+CkwuWEEucHJvdG90eXBlPXsKRWI6ZnVuY3Rpb24oYSxiLGMpe3JldHVybiEwfSwKaTA6ZnVuY3Rpb24o
+YSl7cmV0dXJuITB9LAokaWtGOjF9CkwudnQucHJvdG90eXBlPXsKZ2Q2OmZ1bmN0aW9uKCl7dmFyIHMs
+cixxLHAsbyxuLG0sbD10aGlzLmQKaWYobC5sZW5ndGg9PT0wKXJldHVybiBDLmN3CnM9Qy5ObS5ndEgo
+bCkuZ2Q2KCkKZm9yKHI9bC5sZW5ndGgscT0hMCxwPSEwLG89MDtvPGwubGVuZ3RoO2wubGVuZ3RoPT09
+cnx8KDAsSC5saykobCksKytvKXtuPWxbb10uZ2Q2KCkKaWYobiE9cylzPW51bGwKbT1uIT09Qy5jdwpp
+ZihtJiZuIT09Qy5XRClxPSExCmlmKG0mJm4hPT1DLlhqKXA9ITF9aWYocyE9bnVsbClyZXR1cm4gcwpp
+ZihxKXJldHVybiBDLldECmlmKHApcmV0dXJuIEMuWGoKcmV0dXJuIEMuZGN9LApMVjpmdW5jdGlvbigp
+e3ZhciBzLHIscT10aGlzLmQKaWYocSE9bnVsbClmb3Iocz1xLmxlbmd0aCxyPTA7cjxzOysrcilxW3Jd
+LmI9dGhpc30sCkx0OmZ1bmN0aW9uKCl7dmFyIHMscj1QLkZsKHQuWCx0Ll8pCnIuWTUoMCwidHlwZSIs
+ImRpcmVjdG9yeSIpCnIuWTUoMCwibmFtZSIsdGhpcy5hKQpyLlk1KDAsInN1YnRyZWUiLEwuVkQodGhp
+cy5kKSkKcz10aGlzLmMKaWYocyE9bnVsbClyLlk1KDAsInBhdGgiLHMpCnJldHVybiByfX0KTC5jRC5w
+cm90b3R5cGU9ewpMdDpmdW5jdGlvbigpe3ZhciBzLHI9dGhpcyxxPVAuRmwodC5YLHQuXykKcS5ZNSgw
+LCJ0eXBlIiwiZmlsZSIpCnEuWTUoMCwibmFtZSIsci5hKQpzPXIuYwppZihzIT1udWxsKXEuWTUoMCwi
+cGF0aCIscykKcz1yLmQKaWYocyE9bnVsbClxLlk1KDAsImhyZWYiLHMpCnM9ci5lCmlmKHMhPW51bGwp
+cS5ZNSgwLCJlZGl0Q291bnQiLHMpCnM9ci5mCmlmKHMhPW51bGwpcS5ZNSgwLCJ3YXNFeHBsaWNpdGx5
+T3B0ZWRPdXQiLHMpCnM9ci5yCmlmKHMhPW51bGwpcS5ZNSgwLCJtaWdyYXRpb25TdGF0dXMiLHMuYSkK
+cmV0dXJuIHF9LApnZDY6ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5yfX0KTC5EOC5wcm90b3R5cGU9e30K
+TC5POS5wcm90b3R5cGU9ewp3OmZ1bmN0aW9uKGEpe3JldHVybiB0aGlzLmJ9fQpMLkdiLnByb3RvdHlw
+ZT17Cnc6ZnVuY3Rpb24oYSl7cmV0dXJuIHRoaXMuYn19Ck0ubEkucHJvdG90eXBlPXsKZ2w6ZnVuY3Rp
+b24oKXt2YXIgcz1ELmFiKCkKcmV0dXJuIHN9LApXTzpmdW5jdGlvbihhLGIpe3ZhciBzLHIscT10LmQ0
+Ck0uWUYoImFic29sdXRlIixILlZNKFtiLG51bGwsbnVsbCxudWxsLG51bGwsbnVsbCxudWxsXSxxKSkK
+cz10aGlzLmEKcz1zLllyKGIpPjAmJiFzLmhLKGIpCmlmKHMpcmV0dXJuIGIKcj1ILlZNKFt0aGlzLmds
+KCksYixudWxsLG51bGwsbnVsbCxudWxsLG51bGwsbnVsbF0scSkKTS5ZRigiam9pbiIscikKcmV0dXJu
+IHRoaXMuSVAobmV3IEgudTYocix0LmVKKSl9LAp6ZjpmdW5jdGlvbihhKXt2YXIgcyxyLHE9WC5DTChh
+LHRoaXMuYSkKcS5JeCgpCnM9cS5kCnI9cy5sZW5ndGgKaWYocj09PTApe3M9cS5iCnJldHVybiBzPT1u
+dWxsPyIuIjpzfWlmKHI9PT0xKXtzPXEuYgpyZXR1cm4gcz09bnVsbD8iLiI6c31pZigwPj1yKXJldHVy
+biBILk9IKHMsLTEpCnMucG9wKCkKcz1xLmUKaWYoMD49cy5sZW5ndGgpcmV0dXJuIEguT0gocywtMSkK
+cy5wb3AoKQpxLkl4KCkKcmV0dXJuIHEudygwKX0sCklQOmZ1bmN0aW9uKGEpe3ZhciBzLHIscSxwLG8s
+bixtLGwsayxqCnQuUS5hKGEpCmZvcihzPWEuJHRpLHI9cy5DKCJhMihjWC5FKSIpLmEobmV3IE0ucTco
+KSkscT1hLmdtKGEpLHM9bmV3IEguU08ocSxyLHMuQygiU088Y1guRT4iKSkscj10aGlzLmEscD0hMSxv
+PSExLG49IiI7cy5GKCk7KXttPXEuZ2woKQppZihyLmhLKG0pJiZvKXtsPVguQ0wobSxyKQprPW4uY2hh
+ckNvZGVBdCgwKT09MD9uOm4Kbj1DLnhCLk5qKGssMCxyLlNwKGssITApKQpsLmI9bgppZihyLmRzKG4p
+KUMuTm0uWTUobC5lLDAsci5nbUkoKSkKbj1sLncoMCl9ZWxzZSBpZihyLllyKG0pPjApe289IXIuaEso
+bSkKbj1ILkVqKG0pfWVsc2V7aj1tLmxlbmd0aAppZihqIT09MCl7aWYoMD49ailyZXR1cm4gSC5PSCht
+LDApCmo9ci5VZChtWzBdKX1lbHNlIGo9ITEKaWYoIWopaWYocCluKz1yLmdtSSgpCm4rPW19cD1yLmRz
+KG0pfXJldHVybiBuLmNoYXJDb2RlQXQoMCk9PTA/bjpufSwKbzU6ZnVuY3Rpb24oYSl7dmFyIHMKaWYo
+IXRoaXMueTMoYSkpcmV0dXJuIGEKcz1YLkNMKGEsdGhpcy5hKQpzLnJSKCkKcmV0dXJuIHMudygwKX0s
+CnkzOmZ1bmN0aW9uKGEpe3ZhciBzLHIscSxwLG8sbixtLGwsayxqCmEudG9TdHJpbmcKcz10aGlzLmEK
+cj1zLllyKGEpCmlmKHIhPT0wKXtpZihzPT09JC5LaygpKWZvcihxPTA7cTxyOysrcSlpZihDLnhCLlco
+YSxxKT09PTQ3KXJldHVybiEwCnA9cgpvPTQ3fWVsc2V7cD0wCm89bnVsbH1mb3Iobj1uZXcgSC5xaihh
+KS5hLG09bi5sZW5ndGgscT1wLGw9bnVsbDtxPG07KytxLGw9byxvPWspe2s9Qy54Qi5PMihuLHEpCmlm
+KHMucjQoaykpe2lmKHM9PT0kLktrKCkmJms9PT00NylyZXR1cm4hMAppZihvIT1udWxsJiZzLnI0KG8p
+KXJldHVybiEwCmlmKG89PT00NilqPWw9PW51bGx8fGw9PT00Nnx8cy5yNChsKQplbHNlIGo9ITEKaWYo
+ailyZXR1cm4hMH19aWYobz09bnVsbClyZXR1cm4hMAppZihzLnI0KG8pKXJldHVybiEwCmlmKG89PT00
+NilzPWw9PW51bGx8fHMucjQobCl8fGw9PT00NgplbHNlIHM9ITEKaWYocylyZXR1cm4hMApyZXR1cm4h
+MX0sCkhQOmZ1bmN0aW9uKGEsYil7dmFyIHMscixxLHAsbyxuLG0sbD10aGlzLGs9J1VuYWJsZSB0byBm
+aW5kIGEgcGF0aCB0byAiJwpiPWwuV08oMCxiKQpzPWwuYQppZihzLllyKGIpPD0wJiZzLllyKGEpPjAp
+cmV0dXJuIGwubzUoYSkKaWYocy5ZcihhKTw9MHx8cy5oSyhhKSlhPWwuV08oMCxhKQppZihzLllyKGEp
+PD0wJiZzLllyKGIpPjApdGhyb3cgSC5iKFguSTcoaytILkVqKGEpKyciIGZyb20gIicrSC5FaihiKSsn
+Ii4nKSkKcj1YLkNMKGIscykKci5yUigpCnE9WC5DTChhLHMpCnEuclIoKQpwPXIuZApvPXAubGVuZ3Ro
+CmlmKG8hPT0wKXtpZigwPj1vKXJldHVybiBILk9IKHAsMCkKcD1KLlJNKHBbMF0sIi4iKX1lbHNlIHA9
+ITEKaWYocClyZXR1cm4gcS53KDApCnA9ci5iCm89cS5iCmlmKHAhPW8pcD1wPT1udWxsfHxvPT1udWxs
+fHwhcy5OYyhwLG8pCmVsc2UgcD0hMQppZihwKXJldHVybiBxLncoMCkKd2hpbGUoITApe3A9ci5kCm89
+cC5sZW5ndGgKaWYobyE9PTApe249cS5kCm09bi5sZW5ndGgKaWYobSE9PTApe2lmKDA+PW8pcmV0dXJu
+IEguT0gocCwwKQpwPXBbMF0KaWYoMD49bSlyZXR1cm4gSC5PSChuLDApCm49cy5OYyhwLG5bMF0pCnA9
+bn1lbHNlIHA9ITF9ZWxzZSBwPSExCmlmKCFwKWJyZWFrCkMuTm0uVzQoci5kLDApCkMuTm0uVzQoci5l
+LDEpCkMuTm0uVzQocS5kLDApCkMuTm0uVzQocS5lLDEpfXA9ci5kCm89cC5sZW5ndGgKaWYobyE9PTAp
+e2lmKDA+PW8pcmV0dXJuIEguT0gocCwwKQpwPUouUk0ocFswXSwiLi4iKX1lbHNlIHA9ITEKaWYocCl0
+aHJvdyBILmIoWC5JNyhrK0guRWooYSkrJyIgZnJvbSAiJytILkVqKGIpKyciLicpKQpwPXQuTgpDLk5t
+LlVHKHEuZCwwLFAuTzgoci5kLmxlbmd0aCwiLi4iLCExLHApKQpDLk5tLlk1KHEuZSwwLCIiKQpDLk5t
+LlVHKHEuZSwxLFAuTzgoci5kLmxlbmd0aCxzLmdtSSgpLCExLHApKQpzPXEuZApwPXMubGVuZ3RoCmlm
+KHA9PT0wKXJldHVybiIuIgppZihwPjEmJkouUk0oQy5ObS5ncloocyksIi4iKSl7cz1xLmQKaWYoMD49
+cy5sZW5ndGgpcmV0dXJuIEguT0gocywtMSkKcy5wb3AoKQpzPXEuZQppZigwPj1zLmxlbmd0aClyZXR1
+cm4gSC5PSChzLC0xKQpzLnBvcCgpCmlmKDA+PXMubGVuZ3RoKXJldHVybiBILk9IKHMsLTEpCnMucG9w
+KCkKQy5ObS5pKHMsIiIpfXEuYj0iIgpxLkl4KCkKcmV0dXJuIHEudygwKX19Ck0ucTcucHJvdG90eXBl
+PXsKJDE6ZnVuY3Rpb24oYSl7cmV0dXJuIEguaChhKSE9PSIifSwKJFM6Nn0KTS5Oby5wcm90b3R5cGU9
+ewokMTpmdW5jdGlvbihhKXtILmsoYSkKcmV0dXJuIGE9PW51bGw/Im51bGwiOiciJythKyciJ30sCiRT
+OjUwfQpCLmZ2LnByb3RvdHlwZT17CnhaOmZ1bmN0aW9uKGEpe3ZhciBzLHI9dGhpcy5ZcihhKQppZihy
+PjApcmV0dXJuIEoubGQoYSwwLHIpCmlmKHRoaXMuaEsoYSkpe2lmKDA+PWEubGVuZ3RoKXJldHVybiBI
+Lk9IKGEsMCkKcz1hWzBdfWVsc2Ugcz1udWxsCnJldHVybiBzfSwKTmM6ZnVuY3Rpb24oYSxiKXtyZXR1
+cm4gYT09Yn19ClguV0QucHJvdG90eXBlPXsKSXg6ZnVuY3Rpb24oKXt2YXIgcyxyLHE9dGhpcwp3aGls
+ZSghMCl7cz1xLmQKaWYoIShzLmxlbmd0aCE9PTAmJkouUk0oQy5ObS5ncloocyksIiIpKSlicmVhawpz
+PXEuZAppZigwPj1zLmxlbmd0aClyZXR1cm4gSC5PSChzLC0xKQpzLnBvcCgpCnM9cS5lCmlmKDA+PXMu
+bGVuZ3RoKXJldHVybiBILk9IKHMsLTEpCnMucG9wKCl9cz1xLmUKcj1zLmxlbmd0aAppZihyIT09MClD
+Lk5tLlk1KHMsci0xLCIiKX0sCnJSOmZ1bmN0aW9uKCl7dmFyIHMscixxLHAsbyxuLG09dGhpcyxsPUgu
+Vk0oW10sdC5zKQpmb3Iocz1tLmQscj1zLmxlbmd0aCxxPTAscD0wO3A8cy5sZW5ndGg7cy5sZW5ndGg9
+PT1yfHwoMCxILmxrKShzKSwrK3Ape289c1twXQpuPUouaWEobykKaWYoIShuLkROKG8sIi4iKXx8bi5E
+TihvLCIiKSkpaWYobi5ETihvLCIuLiIpKXtuPWwubGVuZ3RoCmlmKG4hPT0wKXtpZigwPj1uKXJldHVy
+biBILk9IKGwsLTEpCmwucG9wKCl9ZWxzZSArK3F9ZWxzZSBDLk5tLmkobCxvKX1pZihtLmI9PW51bGwp
+Qy5ObS5VRyhsLDAsUC5POChxLCIuLiIsITEsdC5OKSkKaWYobC5sZW5ndGg9PT0wJiZtLmI9PW51bGwp
+Qy5ObS5pKGwsIi4iKQptLnNuSihsKQpzPW0uYQptLnNQaChQLk84KGwubGVuZ3RoKzEscy5nbUkoKSwh
+MCx0Lk4pKQpyPW0uYgppZihyPT1udWxsfHxsLmxlbmd0aD09PTB8fCFzLmRzKHIpKUMuTm0uWTUobS5l
+LDAsIiIpCnI9bS5iCmlmKHIhPW51bGwmJnM9PT0kLktrKCkpe3IudG9TdHJpbmcKbS5iPUgueXMociwi
+LyIsIlxcIil9bS5JeCgpfSwKdzpmdW5jdGlvbihhKXt2YXIgcyxyLHE9dGhpcyxwPXEuYgpwPXAhPW51
+bGw/cDoiIgpmb3Iocz0wO3M8cS5kLmxlbmd0aDsrK3Mpe3I9cS5lCmlmKHM+PXIubGVuZ3RoKXJldHVy
+biBILk9IKHIscykKcj1wK0guRWoocltzXSkKcD1xLmQKaWYocz49cC5sZW5ndGgpcmV0dXJuIEguT0go
+cCxzKQpwPXIrSC5FaihwW3NdKX1wKz1ILkVqKEMuTm0uZ3JaKHEuZSkpCnJldHVybiBwLmNoYXJDb2Rl
+QXQoMCk9PTA/cDpwfSwKc25KOmZ1bmN0aW9uKGEpe3RoaXMuZD10LkUuYShhKX0sCnNQaDpmdW5jdGlv
+bihhKXt0aGlzLmU9dC5FLmEoYSl9fQpYLmR2LnByb3RvdHlwZT17Cnc6ZnVuY3Rpb24oYSl7cmV0dXJu
+IlBhdGhFeGNlcHRpb246ICIrdGhpcy5hfSwKJGlSejoxfQpPLnpMLnByb3RvdHlwZT17Cnc6ZnVuY3Rp
+b24oYSl7cmV0dXJuIHRoaXMuZ29jKHRoaXMpfX0KRS5PRi5wcm90b3R5cGU9ewpVZDpmdW5jdGlvbihh
+KXtyZXR1cm4gQy54Qi50ZyhhLCIvIil9LApyNDpmdW5jdGlvbihhKXtyZXR1cm4gYT09PTQ3fSwKZHM6
+ZnVuY3Rpb24oYSl7dmFyIHM9YS5sZW5ndGgKcmV0dXJuIHMhPT0wJiZDLnhCLk8yKGEscy0xKSE9PTQ3
+fSwKU3A6ZnVuY3Rpb24oYSxiKXtpZihhLmxlbmd0aCE9PTAmJkMueEIuVyhhLDApPT09NDcpcmV0dXJu
+IDEKcmV0dXJuIDB9LApZcjpmdW5jdGlvbihhKXtyZXR1cm4gdGhpcy5TcChhLCExKX0sCmhLOmZ1bmN0
+aW9uKGEpe3JldHVybiExfSwKZ29jOmZ1bmN0aW9uKCl7cmV0dXJuInBvc2l4In0sCmdtSTpmdW5jdGlv
+bigpe3JldHVybiIvIn19CkYucnUucHJvdG90eXBlPXsKVWQ6ZnVuY3Rpb24oYSl7cmV0dXJuIEMueEIu
+dGcoYSwiLyIpfSwKcjQ6ZnVuY3Rpb24oYSl7cmV0dXJuIGE9PT00N30sCmRzOmZ1bmN0aW9uKGEpe3Zh
+ciBzPWEubGVuZ3RoCmlmKHM9PT0wKXJldHVybiExCmlmKEMueEIuTzIoYSxzLTEpIT09NDcpcmV0dXJu
+ITAKcmV0dXJuIEMueEIuVGMoYSwiOi8vIikmJnRoaXMuWXIoYSk9PT1zfSwKU3A6ZnVuY3Rpb24oYSxi
+KXt2YXIgcyxyLHEscCxvPWEubGVuZ3RoCmlmKG89PT0wKXJldHVybiAwCmlmKEMueEIuVyhhLDApPT09
+NDcpcmV0dXJuIDEKZm9yKHM9MDtzPG87KytzKXtyPUMueEIuVyhhLHMpCmlmKHI9PT00NylyZXR1cm4g
+MAppZihyPT09NTgpe2lmKHM9PT0wKXJldHVybiAwCnE9Qy54Qi5YVShhLCIvIixDLnhCLlFpKGEsIi8v
+IixzKzEpP3MrMzpzKQppZihxPD0wKXJldHVybiBvCmlmKCFifHxvPHErMylyZXR1cm4gcQppZighQy54
+Qi5uQyhhLCJmaWxlOi8vIikpcmV0dXJuIHEKaWYoIUIuWXUoYSxxKzEpKXJldHVybiBxCnA9cSszCnJl
+dHVybiBvPT09cD9wOnErNH19cmV0dXJuIDB9LApZcjpmdW5jdGlvbihhKXtyZXR1cm4gdGhpcy5TcChh
+LCExKX0sCmhLOmZ1bmN0aW9uKGEpe3JldHVybiBhLmxlbmd0aCE9PTAmJkMueEIuVyhhLDApPT09NDd9
+LApnb2M6ZnVuY3Rpb24oKXtyZXR1cm4idXJsIn0sCmdtSTpmdW5jdGlvbigpe3JldHVybiIvIn19Ckwu
+SVYucHJvdG90eXBlPXsKVWQ6ZnVuY3Rpb24oYSl7cmV0dXJuIEMueEIudGcoYSwiLyIpfSwKcjQ6ZnVu
+Y3Rpb24oYSl7cmV0dXJuIGE9PT00N3x8YT09PTkyfSwKZHM6ZnVuY3Rpb24oYSl7dmFyIHM9YS5sZW5n
+dGgKaWYocz09PTApcmV0dXJuITEKcz1DLnhCLk8yKGEscy0xKQpyZXR1cm4hKHM9PT00N3x8cz09PTky
+KX0sClNwOmZ1bmN0aW9uKGEsYil7dmFyIHMscixxPWEubGVuZ3RoCmlmKHE9PT0wKXJldHVybiAwCnM9
+Qy54Qi5XKGEsMCkKaWYocz09PTQ3KXJldHVybiAxCmlmKHM9PT05Mil7aWYocTwyfHxDLnhCLlcoYSwx
+KSE9PTkyKXJldHVybiAxCnI9Qy54Qi5YVShhLCJcXCIsMikKaWYocj4wKXtyPUMueEIuWFUoYSwiXFwi
+LHIrMSkKaWYocj4wKXJldHVybiByfXJldHVybiBxfWlmKHE8MylyZXR1cm4gMAppZighQi5PUyhzKSly
+ZXR1cm4gMAppZihDLnhCLlcoYSwxKSE9PTU4KXJldHVybiAwCnE9Qy54Qi5XKGEsMikKaWYoIShxPT09
+NDd8fHE9PT05MikpcmV0dXJuIDAKcmV0dXJuIDN9LApZcjpmdW5jdGlvbihhKXtyZXR1cm4gdGhpcy5T
+cChhLCExKX0sCmhLOmZ1bmN0aW9uKGEpe3JldHVybiB0aGlzLllyKGEpPT09MX0sCk90OmZ1bmN0aW9u
+KGEsYil7dmFyIHMKaWYoYT09PWIpcmV0dXJuITAKaWYoYT09PTQ3KXJldHVybiBiPT09OTIKaWYoYT09
+PTkyKXJldHVybiBiPT09NDcKaWYoKGFeYikhPT0zMilyZXR1cm4hMQpzPWF8MzIKcmV0dXJuIHM+PTk3
+JiZzPD0xMjJ9LApOYzpmdW5jdGlvbihhLGIpe3ZhciBzLHIscQppZihhPT1iKXJldHVybiEwCnM9YS5s
+ZW5ndGgKaWYocyE9PWIubGVuZ3RoKXJldHVybiExCmZvcihyPUouclkoYikscT0wO3E8czsrK3EpaWYo
+IXRoaXMuT3QoQy54Qi5XKGEscSksci5XKGIscSkpKXJldHVybiExCnJldHVybiEwfSwKZ29jOmZ1bmN0
+aW9uKCl7cmV0dXJuIndpbmRvd3MifSwKZ21JOmZ1bmN0aW9uKCl7cmV0dXJuIlxcIn19OyhmdW5jdGlv
+biBhbGlhc2VzKCl7dmFyIHM9Si5Hdi5wcm90b3R5cGUKcy5VPXMudwpzLlNqPXMuZTcKcz1KLk1GLnBy
+b3RvdHlwZQpzLnQ9cy53CnM9UC5jWC5wcm90b3R5cGUKcy5HRz1zLmV2CnM9UC5NaC5wcm90b3R5cGUK
+cy54Yj1zLncKcz1XLmN2LnByb3RvdHlwZQpzLkRXPXMucjYKcz1XLm02LnByb3RvdHlwZQpzLmpGPXMu
+RWIKcz1QLkU0LnByb3RvdHlwZQpzLlVyPXMucQpzLmU0PXMuWTV9KSgpOyhmdW5jdGlvbiBpbnN0YWxs
+VGVhck9mZnMoKXt2YXIgcz1odW5rSGVscGVycy5fc3RhdGljXzEscj1odW5rSGVscGVycy5fc3RhdGlj
+XzAscT1odW5rSGVscGVycy5pbnN0YWxsSW5zdGFuY2VUZWFyT2ZmLHA9aHVua0hlbHBlcnMuaW5zdGFs
+bFN0YXRpY1RlYXJPZmYsbz1odW5rSGVscGVycy5faW5zdGFuY2VfMXUKcyhQLCJFWCIsIlpWIiw3KQpz
+KFAsInl0Iiwib0EiLDcpCnMoUCwicVciLCJCeiIsNykKcihQLCJVSSIsImVOIiwwKQpxKFAuUGYucHJv
+dG90eXBlLCJnWUoiLDAsMSxudWxsLFsiJDIiLCIkMSJdLFsidzAiLCJwbSJdLDI4LDApCnMoUCwiQ3ki
+LCJOQyIsNCkKcyhQLCJQSCIsIk10Iiw1KQpwKFcsInBTIiw0LG51bGwsWyIkNCJdLFsicUQiXSw4LDAp
+CnAoVywiVjQiLDQsbnVsbCxbIiQ0Il0sWyJRVyJdLDgsMCkKbyhQLkFzLnByb3RvdHlwZSwiZ3VNIiwi
+ViIsNSkKcyhQLCJpRyIsIndZIiw1MykKcyhQLCJ3MCIsImRVIiwzNikKcyhMLCJpUyIsImk2IiwyMCl9
+KSgpOyhmdW5jdGlvbiBpbmhlcml0YW5jZSgpe3ZhciBzPWh1bmtIZWxwZXJzLm1peGluLHI9aHVua0hl
+bHBlcnMuaW5oZXJpdCxxPWh1bmtIZWxwZXJzLmluaGVyaXRNYW55CnIoUC5NaCxudWxsKQpxKFAuTWgs
+W0guRkssSi5HdixKLm0xLFAuY1gsSC5FNyxQLlhTLFAublksSC5hNyxQLkFuLEguRnUsSC5KQixILlNV
+LEguUmUsSC53dixQLlBuLEguV1UsSC5MSSxILlRwLEguZjksSC50ZSxILmJxLEguWE8sSC5rcixQLllr
+LEgudmgsSC5ONixILlZSLEguRUssSC5QYixILnRRLEguU2QsSC5KYyxILkcsSC5sWSxQLlczLFAuaWgs
+UC5GeSxQLkdWLFAuUGYsUC5GZSxQLnZzLFAuT00sUC5xaCxQLk1PLFAua1QsUC54SSxQLkN3LFAubTAs
+UC5wUixQLmJuLFAubG0sUC5sRCxQLktQLFAubGYsUC5XWSxQLlVrLFAuU2gsUC5SdyxQLmJ6LFAuaVAs
+UC5rNSxQLktZLFAuQ0QsUC5hRSxQLk4zLFAuYzgsUC5aZCxQLlJuLFAuRG4sUC5QRSxQLlVmLFcuaWQs
+Vy5GayxXLkpRLFcuR20sVy52RCxXLm02LFcuT3csVy5XOSxXLmRXLFcubWssVy5LbyxQLmlKLFAuRTQs
+TS5INyxVLkxMLFUuZDIsVS5TZSxVLk1sLFUueUQsVS53YixCLmo4LEIucXAsVC5tUSxMLlhBLEwuRDgs
+TC5POSxMLkdiLE0ubEksTy56TCxYLldELFguZHZdKQpxKEouR3YsW0oueUUsSi53ZSxKLk1GLEouamQs
+Si5xSSxKLkRyLEguRVQsVy5EMCxXLkF6LFcuTGUsVy5OaCxXLmFlLFcuSUIsVy5uNyxXLmVhLFcuYnIs
+Vy5TZyxXLnc3LFcuSzcsVy5YVyxQLmhGXSkKcShKLk1GLFtKLmlDLEoua2QsSi5jNV0pCnIoSi5QbyxK
+LmpkKQpxKEoucUksW0ouYlUsSi5WQV0pCnEoUC5jWCxbSC5CUixILmJRLEguaTEsSC5VNSxILkFNLEgu
+dTYsSC5YUixQLm1XLEgudW5dKQpxKEguQlIsW0guWnksSC5RQ10pCnIoSC5vbCxILlp5KQpyKEguVXEs
+SC5RQykKcihILmpWLEguVXEpCnEoUC5YUyxbSC5uLEgucjMsSC5HTSxQLkV6LEguYXosSC52VixILkVx
+LFAuQzYsSC5rUyxQLlVkLFAuRixQLnUsUC5tcCxQLnViLFAuZHMsUC5saixQLlVWLFAuY10pCnIoUC51
+eSxQLm5ZKQpxKFAudXksW0gudzIsVy53eixXLmU3XSkKcihILnFqLEgudzIpCnEoSC5iUSxbSC5hTCxI
+Lk1CLEguaTVdKQpxKEguYUwsW0gubkgsSC5sSixQLmk4XSkKcihILnh5LEguaTEpCnEoUC5BbixbSC5N
+SCxILlNPLEguVTFdKQpyKEguZDUsSC5BTSkKcihQLlJVLFAuUG4pCnIoUC5HaixQLlJVKQpyKEguUEQs
+UC5HaikKcihILkxQLEguV1UpCnEoSC5UcCxbSC5DaixILmxjLEguZEMsSC53TixILlZYLFAudGgsUC5o
+YSxQLlZzLFAuRnQsUC55SCxQLldNLFAuU1gsUC5HcyxQLmRhLFAub1EsUC5wVixQLlU3LFAudnIsUC5y
+dCxQLktGLFAuWkwsUC5SVCxQLmpaLFAucnEsUC5SVyxQLkI1LFAudU8sUC5wSyxQLmhqLFAuVnAsUC5P
+UixQLnJhLFAueVEsUC5wZyxQLmMyLFAudGksUC5XRixQLm4xLFAuY1MsUC5WQyxQLkpULFAuUlosUC5N
+RSxQLnk1LFAueUksUC5jNixQLnFkLFcuQ3YsVy5LUyxXLkEzLFcudk4sVy5VdixXLkVnLFcuRW8sVy5X
+ayxXLklBLFcuZm0sUC5qZyxQLlRhLFAuR0UsUC5ONyxQLnVRLFAuUEMsUC5tdCxQLk56LFAuUVMsUC5u
+cCxVLk1ELFUuYU4sVS5iMCxMLmUsTC5WVyxMLm9aLEwuanIsTC5xbCxMLkhpLEwuQlQsTC5QWSxMLnU4
+LEwuTCxMLld4LEwuQU8sTC5kTixMLkhvLEwueHosTC5JQyxMLmZDLEwublQsTC5OWSxMLnVlLEwuZVgs
+TC5FRSxMLlFMLEwuVlMsTC5URCxMLm0yLE0ucTcsTS5Ob10pCnIoSC5XMCxQLkV6KQpxKEgubGMsW0gu
+engsSC5yVF0pCnIoSC5rWSxQLkM2KQpyKFAuaWwsUC5ZaykKcShQLmlsLFtILk41LFAudXcsVy5jZixX
+LlN5XSkKcShQLm1XLFtILktXLFAucTRdKQpyKEguTFosSC5FVCkKcShILkxaLFtILlJHLEguV0JdKQpy
+KEguVlAsSC5SRykKcihILkRnLEguVlApCnIoSC5aRyxILldCKQpyKEguUGcsSC5aRykKcShILlBnLFtI
+LnhqLEguZEUsSC5aQSxILmRULEguUHEsSC5lRSxILlY2XSkKcihILmlNLEgua1MpCnIoUC5aZixQLlBm
+KQpyKFAuSmksUC5tMCkKcihQLlh2LFAucFIpCnIoUC5iNixQLlh2KQpyKFAuVmosUC5XWSkKcShQLlVr
+LFtQLkNWLFAuWmksUC5ieV0pCnIoUC53SSxQLmtUKQpxKFAud0ksW1AuVTgsUC5vaixQLk14LFAuRTMs
+UC5HWV0pCnIoUC5LOCxQLlVkKQpyKFAudHUsUC5TaCkKcihQLnU1LFAuWmkpCnEoUC51LFtQLmJKLFAu
+ZVldKQpyKFAucWUsUC5EbikKcShXLkQwLFtXLnVILFcud2EsVy5LNSxXLkNtXSkKcShXLnVILFtXLmN2
+LFcubngsVy5RRixXLkNRXSkKcShXLmN2LFtXLnFFLFAuaGldKQpxKFcucUUsW1cuR2gsVy5mWSxXLm5C
+LFcuUVAsVy5oNCxXLlNOLFcubHAsVy5UYixXLkl2LFcuV1AsVy55WV0pCnIoVy5vSixXLkxlKQpyKFcu
+aEgsVy5BeikKcihXLlZiLFcuUUYpCnIoVy5mSixXLndhKQpxKFcuZWEsW1cudzYsVy5ld10pCnIoVy5B
+aixXLnc2KQpyKFcuckIsVy5LNykKcihXLkJILFcuckIpCnIoVy53NCxXLklCKQpyKFcub2EsVy5YVykK
+cihXLnJoLFcub2EpCnIoVy5pNyxXLmNmKQpyKFAuQXMsUC5WaikKcShQLkFzLFtXLkk0LFAuS2VdKQpy
+KFcuUk8sUC5xaCkKcihXLmV1LFcuUk8pCnIoVy54QyxQLk1PKQpyKFcuY3QsVy5tNikKcihQLkJmLFAu
+aUopCnEoUC5FNCxbUC5yNyxQLmNvXSkKcihQLlR6LFAuY28pCnIoUC5uZCxQLmhpKQpxKEwuRDgsW0wu
+dnQsTC5jRF0pCnIoQi5mdixPLnpMKQpxKEIuZnYsW0UuT0YsRi5ydSxMLklWXSkKcyhILncyLEguUmUp
+CnMoSC5RQyxQLmxEKQpzKEguUkcsUC5sRCkKcyhILlZQLEguU1UpCnMoSC5XQixQLmxEKQpzKEguWkcs
+SC5TVSkKcyhQLm5ZLFAubEQpCnMoUC5XWSxQLmxmKQpzKFAuUlUsUC5LUCkKcyhQLnBSLFAubGYpCnMo
+Vy5MZSxXLmlkKQpzKFcuSzcsUC5sRCkKcyhXLnJCLFcuR20pCnMoVy5YVyxQLmxEKQpzKFcub2EsVy5H
+bSkKcyhQLmNvLFAubEQpfSkoKQp2YXIgdj17dHlwZVVuaXZlcnNlOntlQzpuZXcgTWFwKCksdFI6e30s
+ZVQ6e30sdFBWOnt9LHNFQTpbXX0sbWFuZ2xlZEdsb2JhbE5hbWVzOntJZjoiaW50IixDUDoiZG91Ymxl
+IixaWjoibnVtIixxVToiU3RyaW5nIixhMjoiYm9vbCIsYzg6Ik51bGwiLHpNOiJMaXN0In0sbWFuZ2xl
+ZE5hbWVzOnt9LGdldFR5cGVGcm9tTmFtZTpnZXRHbG9iYWxGcm9tTmFtZSxtZXRhZGF0YTpbXSx0eXBl
+czpbIn4oKSIsImM4KEFqKikiLCJjOCgpIiwiYzgoY3YqKSIsIkAoQCkiLCJxVShxVSkiLCJhMihxVSki
+LCJ+KH4oKSkiLCJhMihjdixxVSxxVSxKUSkiLCJjOChAKSIsIn4oTWg/LE1oPykiLCJAKCkiLCJ+KHFV
+LEApIiwifihuNixxVSxJZikiLCJ+KHFVLHFVKSIsImEyKGtGKSIsImM4KEAsQCkiLCJ+KHh1PHFVPiki
+LCJjOChlYSopIiwiYjg8Yzg+KihBaiopIiwifihBaiopIiwifihxVSxJZikiLCJ+KHFVLHFVPykiLCJu
+NihALEApIiwiYzgoQCxHeikiLCJhMih1SCkiLCJ+KElmLEApIiwifihlYSkiLCJ+KE1oW0d6P10pIiwi
+YzgoTWgsR3opIiwifih1SCx1SD8pIiwifihALEApIiwidnM8QD4oQCkiLCJhMih4dTxxVT4pIiwiYzgo
+figpKSIsInI3KEApIiwiTWg/KEApIiwiRTQoQCkiLCJhMiooSDcqKSIsIkxMKihAKSIsIlowPHFVKixN
+aCo+KihMTCopIiwiQChxVSkiLCJ+KEdELEApIiwiYzgoWjA8cVUqLE1oKj4qKSIsIlowPHFVLHFVPiha
+MDxxVSxxVT4scVUpIiwicVUqKEFqKikiLCJAKEAscVUpIiwiYzgoZXcqKSIsInFVKihaMDxALEA+Kiki
+LCJ+KHFVW0BdKSIsInFVKHFVPykiLCJJZihJZixJZikiLCJ+KEApIiwiTWg/KE1oPykiLCJUejxAPihA
+KSJdLGludGVyY2VwdG9yc0J5VGFnOm51bGwsbGVhZlRhZ3M6bnVsbCxhcnJheVJ0aTp0eXBlb2YgU3lt
+Ym9sPT0iZnVuY3Rpb24iJiZ0eXBlb2YgU3ltYm9sKCk9PSJzeW1ib2wiP1N5bWJvbCgiJHRpIik6IiR0
+aSJ9CkgueGIodi50eXBlVW5pdmVyc2UsSlNPTi5wYXJzZSgneyJjNSI6Ik1GIiwiaUMiOiJNRiIsImtk
+IjoiTUYiLCJyeCI6ImVhIiwiZTUiOiJlYSIsIlkwIjoiaGkiLCJ0cCI6ImhpIiwiRzgiOiJldyIsIk1y
+IjoicUUiLCJlTCI6InFFIiwiSTAiOiJ1SCIsImhzIjoidUgiLCJYZyI6IlFGIiwibnIiOiJBaiIsInk0
+IjoidzYiLCJhUCI6IkNtIiwieGMiOiJueCIsImtKIjoibngiLCJ6VSI6IkRnIiwiZGYiOiJFVCIsInlF
+Ijp7ImEyIjpbXX0sIndlIjp7ImM4IjpbXX0sIk1GIjp7InZtIjpbXSwiRUgiOltdfSwiamQiOnsiek0i
+OlsiMSJdLCJiUSI6WyIxIl0sImNYIjpbIjEiXX0sIlBvIjp7ImpkIjpbIjEiXSwiek0iOlsiMSJdLCJi
+USI6WyIxIl0sImNYIjpbIjEiXX0sIm0xIjp7IkFuIjpbIjEiXX0sInFJIjp7IkNQIjpbXSwiWloiOltd
+fSwiYlUiOnsiQ1AiOltdLCJJZiI6W10sIlpaIjpbXX0sIlZBIjp7IkNQIjpbXSwiWloiOltdfSwiRHIi
+OnsicVUiOltdLCJ2WCI6W119LCJCUiI6eyJjWCI6WyIyIl19LCJFNyI6eyJBbiI6WyIyIl19LCJaeSI6
+eyJCUiI6WyIxIiwiMiJdLCJjWCI6WyIyIl0sImNYLkUiOiIyIn0sIm9sIjp7Ilp5IjpbIjEiLCIyIl0s
+IkJSIjpbIjEiLCIyIl0sImJRIjpbIjIiXSwiY1giOlsiMiJdLCJjWC5FIjoiMiJ9LCJVcSI6eyJsRCI6
+WyIyIl0sInpNIjpbIjIiXSwiQlIiOlsiMSIsIjIiXSwiYlEiOlsiMiJdLCJjWCI6WyIyIl19LCJqViI6
+eyJVcSI6WyIxIiwiMiJdLCJsRCI6WyIyIl0sInpNIjpbIjIiXSwiQlIiOlsiMSIsIjIiXSwiYlEiOlsi
+MiJdLCJjWCI6WyIyIl0sImxELkUiOiIyIiwiY1guRSI6IjIifSwibiI6eyJYUyI6W119LCJyMyI6eyJY
+UyI6W119LCJxaiI6eyJsRCI6WyJJZiJdLCJSZSI6WyJJZiJdLCJ6TSI6WyJJZiJdLCJiUSI6WyJJZiJd
+LCJjWCI6WyJJZiJdLCJsRC5FIjoiSWYiLCJSZS5FIjoiSWYifSwiR00iOnsiWFMiOltdfSwiYlEiOnsi
+Y1giOlsiMSJdfSwiYUwiOnsiYlEiOlsiMSJdLCJjWCI6WyIxIl19LCJuSCI6eyJhTCI6WyIxIl0sImJR
+IjpbIjEiXSwiY1giOlsiMSJdLCJhTC5FIjoiMSIsImNYLkUiOiIxIn0sImE3Ijp7IkFuIjpbIjEiXX0s
+ImkxIjp7ImNYIjpbIjIiXSwiY1guRSI6IjIifSwieHkiOnsiaTEiOlsiMSIsIjIiXSwiYlEiOlsiMiJd
+LCJjWCI6WyIyIl0sImNYLkUiOiIyIn0sIk1IIjp7IkFuIjpbIjIiXX0sImxKIjp7ImFMIjpbIjIiXSwi
+YlEiOlsiMiJdLCJjWCI6WyIyIl0sImFMLkUiOiIyIiwiY1guRSI6IjIifSwiVTUiOnsiY1giOlsiMSJd
+LCJjWC5FIjoiMSJ9LCJTTyI6eyJBbiI6WyIxIl19LCJBTSI6eyJjWCI6WyIxIl0sImNYLkUiOiIxIn0s
+ImQ1Ijp7IkFNIjpbIjEiXSwiYlEiOlsiMSJdLCJjWCI6WyIxIl0sImNYLkUiOiIxIn0sIlUxIjp7IkFu
+IjpbIjEiXX0sIk1CIjp7ImJRIjpbIjEiXSwiY1giOlsiMSJdLCJjWC5FIjoiMSJ9LCJGdSI6eyJBbiI6
+WyIxIl19LCJ1NiI6eyJjWCI6WyIxIl0sImNYLkUiOiIxIn0sIkpCIjp7IkFuIjpbIjEiXX0sIncyIjp7
+ImxEIjpbIjEiXSwiUmUiOlsiMSJdLCJ6TSI6WyIxIl0sImJRIjpbIjEiXSwiY1giOlsiMSJdfSwid3Yi
+OnsiR0QiOltdfSwiUEQiOnsiR2oiOlsiMSIsIjIiXSwiUlUiOlsiMSIsIjIiXSwiUG4iOlsiMSIsIjIi
+XSwiS1AiOlsiMSIsIjIiXSwiWjAiOlsiMSIsIjIiXX0sIldVIjp7IlowIjpbIjEiLCIyIl19LCJMUCI6
+eyJXVSI6WyIxIiwiMiJdLCJaMCI6WyIxIiwiMiJdfSwiWFIiOnsiY1giOlsiMSJdLCJjWC5FIjoiMSJ9
+LCJMSSI6eyJ2USI6W119LCJXMCI6eyJYUyI6W119LCJheiI6eyJYUyI6W119LCJ2ViI6eyJYUyI6W119
+LCJ0ZSI6eyJSeiI6W119LCJYTyI6eyJHeiI6W119LCJUcCI6eyJFSCI6W119LCJsYyI6eyJFSCI6W119
+LCJ6eCI6eyJFSCI6W119LCJyVCI6eyJFSCI6W119LCJFcSI6eyJYUyI6W119LCJrWSI6eyJYUyI6W119
+LCJONSI6eyJZayI6WyIxIiwiMiJdLCJGbyI6WyIxIiwiMiJdLCJaMCI6WyIxIiwiMiJdLCJZay5LIjoi
+MSIsIllrLlYiOiIyIn0sImk1Ijp7ImJRIjpbIjEiXSwiY1giOlsiMSJdLCJjWC5FIjoiMSJ9LCJONiI6
+eyJBbiI6WyIxIl19LCJWUiI6eyJ3TCI6W10sInZYIjpbXX0sIkVLIjp7ImliIjpbXSwiT2QiOltdfSwi
+S1ciOnsiY1giOlsiaWIiXSwiY1guRSI6ImliIn0sIlBiIjp7IkFuIjpbImliIl19LCJ0USI6eyJPZCI6
+W119LCJ1biI6eyJjWCI6WyJPZCJdLCJjWC5FIjoiT2QifSwiU2QiOnsiQW4iOlsiT2QiXX0sIkVUIjp7
+IkFTIjpbXX0sIkxaIjp7IlhqIjpbIjEiXSwiRVQiOltdLCJBUyI6W119LCJEZyI6eyJsRCI6WyJDUCJd
+LCJYaiI6WyJDUCJdLCJ6TSI6WyJDUCJdLCJFVCI6W10sImJRIjpbIkNQIl0sIkFTIjpbXSwiY1giOlsi
+Q1AiXSwiU1UiOlsiQ1AiXSwibEQuRSI6IkNQIn0sIlBnIjp7ImxEIjpbIklmIl0sIlhqIjpbIklmIl0s
+InpNIjpbIklmIl0sIkVUIjpbXSwiYlEiOlsiSWYiXSwiQVMiOltdLCJjWCI6WyJJZiJdLCJTVSI6WyJJ
+ZiJdfSwieGoiOnsibEQiOlsiSWYiXSwiWGoiOlsiSWYiXSwiek0iOlsiSWYiXSwiRVQiOltdLCJiUSI6
+WyJJZiJdLCJBUyI6W10sImNYIjpbIklmIl0sIlNVIjpbIklmIl0sImxELkUiOiJJZiJ9LCJkRSI6eyJs
+RCI6WyJJZiJdLCJYaiI6WyJJZiJdLCJ6TSI6WyJJZiJdLCJFVCI6W10sImJRIjpbIklmIl0sIkFTIjpb
+XSwiY1giOlsiSWYiXSwiU1UiOlsiSWYiXSwibEQuRSI6IklmIn0sIlpBIjp7ImxEIjpbIklmIl0sIlhq
+IjpbIklmIl0sInpNIjpbIklmIl0sIkVUIjpbXSwiYlEiOlsiSWYiXSwiQVMiOltdLCJjWCI6WyJJZiJd
+LCJTVSI6WyJJZiJdLCJsRC5FIjoiSWYifSwiZFQiOnsibEQiOlsiSWYiXSwiWGoiOlsiSWYiXSwiek0i
+OlsiSWYiXSwiRVQiOltdLCJiUSI6WyJJZiJdLCJBUyI6W10sImNYIjpbIklmIl0sIlNVIjpbIklmIl0s
+ImxELkUiOiJJZiJ9LCJQcSI6eyJsRCI6WyJJZiJdLCJYaiI6WyJJZiJdLCJ6TSI6WyJJZiJdLCJFVCI6
+W10sImJRIjpbIklmIl0sIkFTIjpbXSwiY1giOlsiSWYiXSwiU1UiOlsiSWYiXSwibEQuRSI6IklmIn0s
+ImVFIjp7ImxEIjpbIklmIl0sIlhqIjpbIklmIl0sInpNIjpbIklmIl0sIkVUIjpbXSwiYlEiOlsiSWYi
+XSwiQVMiOltdLCJjWCI6WyJJZiJdLCJTVSI6WyJJZiJdLCJsRC5FIjoiSWYifSwiVjYiOnsibEQiOlsi
+SWYiXSwibjYiOltdLCJYaiI6WyJJZiJdLCJ6TSI6WyJJZiJdLCJFVCI6W10sImJRIjpbIklmIl0sIkFT
+IjpbXSwiY1giOlsiSWYiXSwiU1UiOlsiSWYiXSwibEQuRSI6IklmIn0sImtTIjp7IlhTIjpbXX0sImlN
+Ijp7IlhTIjpbXX0sIkdWIjp7IkFuIjpbIjEiXX0sInE0Ijp7ImNYIjpbIjEiXSwiY1guRSI6IjEifSwi
+WmYiOnsiUGYiOlsiMSJdfSwidnMiOnsiYjgiOlsiMSJdfSwiQ3ciOnsiWFMiOltdfSwibTAiOnsiUW0i
+OltdfSwiSmkiOnsibTAiOltdLCJRbSI6W119LCJiNiI6eyJsZiI6WyIxIl0sInh1IjpbIjEiXSwiYlEi
+OlsiMSJdLCJjWCI6WyIxIl0sImxmLkUiOiIxIn0sImxtIjp7IkFuIjpbIjEiXX0sIm1XIjp7ImNYIjpb
+IjEiXX0sInV5Ijp7ImxEIjpbIjEiXSwiek0iOlsiMSJdLCJiUSI6WyIxIl0sImNYIjpbIjEiXX0sImls
+Ijp7IllrIjpbIjEiLCIyIl0sIlowIjpbIjEiLCIyIl19LCJZayI6eyJaMCI6WyIxIiwiMiJdfSwiUG4i
+OnsiWjAiOlsiMSIsIjIiXX0sIkdqIjp7IlJVIjpbIjEiLCIyIl0sIlBuIjpbIjEiLCIyIl0sIktQIjpb
+IjEiLCIyIl0sIlowIjpbIjEiLCIyIl19LCJWaiI6eyJsZiI6WyIxIl0sInh1IjpbIjEiXSwiYlEiOlsi
+MSJdLCJjWCI6WyIxIl19LCJYdiI6eyJsZiI6WyIxIl0sInh1IjpbIjEiXSwiYlEiOlsiMSJdLCJjWCI6
+WyIxIl19LCJ1dyI6eyJZayI6WyJxVSIsIkAiXSwiWjAiOlsicVUiLCJAIl0sIllrLksiOiJxVSIsIllr
+LlYiOiJAIn0sImk4Ijp7ImFMIjpbInFVIl0sImJRIjpbInFVIl0sImNYIjpbInFVIl0sImFMLkUiOiJx
+VSIsImNYLkUiOiJxVSJ9LCJDViI6eyJVayI6WyJ6TTxJZj4iLCJxVSJdLCJVay5TIjoiek08SWY+In0s
+IlU4Ijp7IndJIjpbInpNPElmPiIsInFVIl19LCJaaSI6eyJVayI6WyJxVSIsInpNPElmPiJdfSwiVWQi
+OnsiWFMiOltdfSwiSzgiOnsiWFMiOltdfSwiYnkiOnsiVWsiOlsiTWg/IiwicVUiXSwiVWsuUyI6Ik1o
+PyJ9LCJvaiI6eyJ3SSI6WyJNaD8iLCJxVSJdfSwiTXgiOnsid0kiOlsicVUiLCJNaD8iXX0sInU1Ijp7
+IlVrIjpbInFVIiwiek08SWY+Il0sIlVrLlMiOiJxVSJ9LCJFMyI6eyJ3SSI6WyJxVSIsInpNPElmPiJd
+fSwiR1kiOnsid0kiOlsiek08SWY+IiwicVUiXX0sIkNQIjp7IlpaIjpbXX0sIklmIjp7IlpaIjpbXX0s
+InpNIjp7ImJRIjpbIjEiXSwiY1giOlsiMSJdfSwiaWIiOnsiT2QiOltdfSwieHUiOnsiYlEiOlsiMSJd
+LCJjWCI6WyIxIl19LCJxVSI6eyJ2WCI6W119LCJDNiI6eyJYUyI6W119LCJFeiI6eyJYUyI6W119LCJG
+Ijp7IlhTIjpbXX0sInUiOnsiWFMiOltdfSwiYkoiOnsiWFMiOltdfSwiZVkiOnsiWFMiOltdfSwibXAi
+OnsiWFMiOltdfSwidWIiOnsiWFMiOltdfSwiZHMiOnsiWFMiOltdfSwibGoiOnsiWFMiOltdfSwiVVYi
+OnsiWFMiOltdfSwiazUiOnsiWFMiOltdfSwiS1kiOnsiWFMiOltdfSwiYyI6eyJYUyI6W119LCJDRCI6
+eyJSeiI6W119LCJhRSI6eyJSeiI6W119LCJaZCI6eyJHeiI6W119LCJSbiI6eyJCTCI6W119LCJEbiI6
+eyJpRCI6W119LCJVZiI6eyJpRCI6W119LCJxZSI6eyJpRCI6W119LCJxRSI6eyJjdiI6W10sInVIIjpb
+XSwiRDAiOltdfSwiR2giOnsiY3YiOltdLCJ1SCI6W10sIkQwIjpbXX0sImZZIjp7ImN2IjpbXSwidUgi
+OltdLCJEMCI6W119LCJuQiI6eyJjdiI6W10sInVIIjpbXSwiRDAiOltdfSwiUVAiOnsiY3YiOltdLCJ1
+SCI6W10sIkQwIjpbXX0sIm54Ijp7InVIIjpbXSwiRDAiOltdfSwiUUYiOnsidUgiOltdLCJEMCI6W119
+LCJJQiI6eyJ0biI6WyJaWiJdfSwid3oiOnsibEQiOlsiMSJdLCJ6TSI6WyIxIl0sImJRIjpbIjEiXSwi
+Y1giOlsiMSJdLCJsRC5FIjoiMSJ9LCJjdiI6eyJ1SCI6W10sIkQwIjpbXX0sImhIIjp7IkF6IjpbXX0s
+Img0Ijp7ImN2IjpbXSwidUgiOltdLCJEMCI6W119LCJWYiI6eyJ1SCI6W10sIkQwIjpbXX0sImZKIjp7
+IkQwIjpbXX0sIndhIjp7IkQwIjpbXX0sIkFqIjp7ImVhIjpbXX0sImU3Ijp7ImxEIjpbInVIIl0sInpN
+IjpbInVIIl0sImJRIjpbInVIIl0sImNYIjpbInVIIl0sImxELkUiOiJ1SCJ9LCJ1SCI6eyJEMCI6W119
+LCJCSCI6eyJsRCI6WyJ1SCJdLCJHbSI6WyJ1SCJdLCJ6TSI6WyJ1SCJdLCJYaiI6WyJ1SCJdLCJiUSI6
+WyJ1SCJdLCJjWCI6WyJ1SCJdLCJsRC5FIjoidUgiLCJHbS5FIjoidUgifSwiU04iOnsiY3YiOltdLCJ1
+SCI6W10sIkQwIjpbXX0sImV3Ijp7ImVhIjpbXX0sImxwIjp7ImN2IjpbXSwidUgiOltdLCJEMCI6W119
+LCJUYiI6eyJjdiI6W10sInVIIjpbXSwiRDAiOltdfSwiSXYiOnsiY3YiOltdLCJ1SCI6W10sIkQwIjpb
+XX0sIldQIjp7ImN2IjpbXSwidUgiOltdLCJEMCI6W119LCJ5WSI6eyJjdiI6W10sInVIIjpbXSwiRDAi
+OltdfSwidzYiOnsiZWEiOltdfSwiSzUiOnsidjYiOltdLCJEMCI6W119LCJDbSI6eyJEMCI6W119LCJD
+USI6eyJ1SCI6W10sIkQwIjpbXX0sInc0Ijp7InRuIjpbIlpaIl19LCJyaCI6eyJsRCI6WyJ1SCJdLCJH
+bSI6WyJ1SCJdLCJ6TSI6WyJ1SCJdLCJYaiI6WyJ1SCJdLCJiUSI6WyJ1SCJdLCJjWCI6WyJ1SCJdLCJs
+RC5FIjoidUgiLCJHbS5FIjoidUgifSwiY2YiOnsiWWsiOlsicVUiLCJxVSJdLCJaMCI6WyJxVSIsInFV
+Il19LCJpNyI6eyJZayI6WyJxVSIsInFVIl0sIlowIjpbInFVIiwicVUiXSwiWWsuSyI6InFVIiwiWWsu
+ViI6InFVIn0sIlN5Ijp7IllrIjpbInFVIiwicVUiXSwiWjAiOlsicVUiLCJxVSJdLCJZay5LIjoicVUi
+LCJZay5WIjoicVUifSwiSTQiOnsibGYiOlsicVUiXSwieHUiOlsicVUiXSwiYlEiOlsicVUiXSwiY1gi
+OlsicVUiXSwibGYuRSI6InFVIn0sIlJPIjp7InFoIjpbIjEiXX0sImV1Ijp7IlJPIjpbIjEiXSwicWgi
+OlsiMSJdfSwieEMiOnsiTU8iOlsiMSJdfSwiSlEiOnsia0YiOltdfSwidkQiOnsia0YiOltdfSwibTYi
+Onsia0YiOltdfSwiY3QiOnsia0YiOltdfSwiT3ciOnsia0YiOltdfSwiVzkiOnsiQW4iOlsiMSJdfSwi
+ZFciOnsidjYiOltdLCJEMCI6W119LCJtayI6eyJ5MCI6W119LCJLbyI6eyJvbiI6W119LCJBcyI6eyJs
+ZiI6WyJxVSJdLCJ4dSI6WyJxVSJdLCJiUSI6WyJxVSJdLCJjWCI6WyJxVSJdfSwicjciOnsiRTQiOltd
+fSwiVHoiOnsibEQiOlsiMSJdLCJ6TSI6WyIxIl0sImJRIjpbIjEiXSwiRTQiOltdLCJjWCI6WyIxIl0s
+ImxELkUiOiIxIn0sIm5kIjp7ImhpIjpbXSwiY3YiOltdLCJ1SCI6W10sIkQwIjpbXX0sIktlIjp7Imxm
+IjpbInFVIl0sInh1IjpbInFVIl0sImJRIjpbInFVIl0sImNYIjpbInFVIl0sImxmLkUiOiJxVSJ9LCJo
+aSI6eyJjdiI6W10sInVIIjpbXSwiRDAiOltdfSwiWEEiOnsia0YiOltdfSwidnQiOnsiRDgiOltdfSwi
+Y0QiOnsiRDgiOltdfSwiZHYiOnsiUnoiOltdfSwiT0YiOnsiZnYiOltdfSwicnUiOnsiZnYiOltdfSwi
+SVYiOnsiZnYiOltdfSwibjYiOnsiek0iOlsiSWYiXSwiYlEiOlsiSWYiXSwiY1giOlsiSWYiXSwiQVMi
+OltdfX0nKSkKSC5GRih2LnR5cGVVbml2ZXJzZSxKU09OLnBhcnNlKCd7IncyIjoxLCJRQyI6MiwiTFoi
+OjEsImtUIjoyLCJtVyI6MSwidXkiOjEsImlsIjoyLCJWaiI6MSwiWHYiOjEsIm5ZIjoxLCJXWSI6MSwi
+cFIiOjEsImNvIjoxfScpKQp2YXIgdT17bDoiQ2Fubm90IGV4dHJhY3QgYSBmaWxlIHBhdGggZnJvbSBh
+IFVSSSB3aXRoIGEgZnJhZ21lbnQgY29tcG9uZW50IixpOiJDYW5ub3QgZXh0cmFjdCBhIGZpbGUgcGF0
+aCBmcm9tIGEgVVJJIHdpdGggYSBxdWVyeSBjb21wb25lbnQiLGo6IkNhbm5vdCBleHRyYWN0IGEgbm9u
+LVdpbmRvd3MgZmlsZSBwYXRoIGZyb20gYSBmaWxlIFVSSSB3aXRoIGFuIGF1dGhvcml0eSIsZzoiYG51
+bGxgIGVuY291bnRlcmVkIGFzIHRoZSByZXN1bHQgZnJvbSBleHByZXNzaW9uIHdpdGggdHlwZSBgTmV2
+ZXJgLiIsZDoiYXJlYS1hbmFseXplcixhbmFseXplci1ubmJkLW1pZ3JhdGlvbix0eXBlLWJ1ZyJ9CnZh
+ciB0PShmdW5jdGlvbiBydGlpKCl7dmFyIHM9SC5OMApyZXR1cm57bjpzKCJDdyIpLGNSOnMoIm5CIiks
+dzpzKCJBeiIpLHA6cygiUVAiKSxnRjpzKCJQRDxHRCxAPiIpLGI6cygiYlE8QD4iKSxoOnMoImN2Iiks
+cjpzKCJYUyIpLEI6cygiZWEiKSxhUzpzKCJEMCIpLGc4OnMoIlJ6IiksYzg6cygiaEgiKSxZOnMoIkVI
+IiksZDpzKCJiODxAPiIpLEk6cygiU2ciKSxvOnMoInZRIiksZWg6cygiY1g8dUg+IiksUTpzKCJjWDxx
+VT4iKSx1OnMoImNYPEA+IiksdjpzKCJqZDxrRj4iKSxzOnMoImpkPHFVPiIpLGdOOnMoImpkPG42PiIp
+LHg6cygiamQ8QD4iKSxhOnMoImpkPElmPiIpLGQ3OnMoImpkPFNlKj4iKSxoNDpzKCJqZDxqOCo+Iiks
+RzpzKCJqZDxaMDxxVSosTWgqPio+IiksY1E6cygiamQ8RDgqPiIpLGk6cygiamQ8cVUqPiIpLGFBOnMo
+ImpkPHlEKj4iKSxhSjpzKCJqZDx3Yio+IiksVjpzKCJqZDxJZio+IiksZDQ6cygiamQ8cVU/PiIpLFQ6
+cygid2UiKSxlSDpzKCJ2bSIpLEQ6cygiYzUiKSxhVTpzKCJYajxAPiIpLGFtOnMoIlR6PEA+IiksZW86
+cygiTjU8R0QsQD4iKSxkejpzKCJoRiIpLEU6cygiek08cVU+IiksajpzKCJ6TTxAPiIpLEw6cygiek08
+SWY+IiksSjpzKCJaMDxxVSxxVT4iKSxmOnMoIlowPEAsQD4iKSxkbzpzKCJsSjxxVSxAPiIpLGZqOnMo
+ImxKPHFVKixxVT4iKSxkRTpzKCJFVCIpLGJtOnMoIlY2IiksQTpzKCJ1SCIpLGY2OnMoImtGIiksUDpz
+KCJjOCIpLEs6cygiTWgiKSxxOnMoInRuPFpaPiIpLGZ2OnMoIndMIiksZXc6cygibmQiKSxDOnMoInh1
+PHFVPiIpLGw6cygiR3oiKSxOOnMoInFVIiksZDA6cygicVUocVUqKSIpLGc3OnMoImhpIiksZm86cygi
+R0QiKSxhVzpzKCJ5WSIpLGFrOnMoIkFTIiksZ2M6cygibjYiKSxiSjpzKCJrZCIpLGR3OnMoIkdqPHFV
+LHFVPiIpLGREOnMoImlEIiksZUo6cygidTY8cVU+IiksZzQ6cygiSzUiKSxjaTpzKCJ2NiIpLGcyOnMo
+IkNtIiksYkM6cygiWmY8ZkoqPiIpLGg5OnMoIkNRIiksYWM6cygiZTciKSxrOnMoImV1PEFqKj4iKSxS
+OnMoInd6PGN2Kj4iKSxjOnMoInZzPEA+IiksZko6cygidnM8SWY+IiksZ1Y6cygidnM8ZkoqPiIpLGNy
+OnMoIkpRIikseTpzKCJhMiIpLGFsOnMoImEyKE1oKSIpLGdSOnMoIkNQIiksejpzKCJAIiksZk86cygi
+QCgpIiksYkk6cygiQChNaCkiKSxhZzpzKCJAKE1oLEd6KSIpLGJVOnMoIkAoeHU8cVU+KSIpLGRPOnMo
+IkAocVUpIiksYjg6cygiQChALEApIiksUzpzKCJJZiIpLGRkOnMoIkdoKiIpLGc6cygiY3YqIiksYUw6
+cygiZWEqIiksYVg6cygiTEwqIiksZkU6cygiSDcqIiksVTpzKCJjWDxAPioiKSxkSDpzKCJFNCoiKSxm
+SzpzKCJ6TTxAPioiKSxkXzpzKCJ6TTxqOCo+KiIpLGRwOnMoInpNPFowPHFVKixNaCo+Kj4qIiksbTpz
+KCJ6TTxNaCo+KiIpLGF3OnMoIlowPEAsQD4qIiksdDpzKCJaMDxxVSosTWgqPioiKSxPOnMoIkFqKiIp
+LGNGOnMoIjAmKiIpLF86cygiTWgqIiksZVE6cygiZXcqIiksWDpzKCJxVSoiKSxjaDpzKCJEMD8iKSxi
+RzpzKCJiODxjOD4/IiksYms6cygiek08cVU+PyIpLGJNOnMoInpNPEA+PyIpLGNaOnMoIlowPHFVLHFV
+Pj8iKSxjOTpzKCJaMDxxVSxAPj8iKSxXOnMoIk1oPyIpLEY6cygiRmU8QCxAPj8iKSxlOnMoImJuPyIp
+LGI3OnMoImEyKE1oKT8iKSxidzpzKCJAKGVhKT8iKSxmVjpzKCJNaD8oTWg/LE1oPyk/IiksZEE6cygi
+TWg/KEApPyIpLFo6cygifigpPyIpLGViOnMoIn4oZXcqKT8iKSxkaTpzKCJaWiIpLEg6cygifiIpLE06
+cygifigpIiksZUE6cygifihxVSxxVSkiKSxjQTpzKCJ+KHFVLEApIil9fSkoKTsoZnVuY3Rpb24gY29u
+c3RhbnRzKCl7dmFyIHM9aHVua0hlbHBlcnMubWFrZUNvbnN0TGlzdApDLnhuPVcuR2gucHJvdG90eXBl
+CkMuUlk9Vy5RUC5wcm90b3R5cGUKQy5tSD1XLmFlLnByb3RvdHlwZQpDLkJaPVcuVmIucHJvdG90eXBl
+CkMuRHQ9Vy5mSi5wcm90b3R5cGUKQy5Paz1KLkd2LnByb3RvdHlwZQpDLk5tPUouamQucHJvdG90eXBl
+CkMuam49Si5iVS5wcm90b3R5cGUKQy5qTj1KLndlLnByb3RvdHlwZQpDLkNEPUoucUkucHJvdG90eXBl
+CkMueEI9Si5Eci5wcm90b3R5cGUKQy5ERz1KLmM1LnByb3RvdHlwZQpDLkV4PVcudzcucHJvdG90eXBl
+CkMuTkE9SC5WNi5wcm90b3R5cGUKQy50NT1XLkJILnByb3RvdHlwZQpDLkx0PVcuU04ucHJvdG90eXBl
+CkMuWlE9Si5pQy5wcm90b3R5cGUKQy5JZT1XLlRiLnByb3RvdHlwZQpDLnZCPUoua2QucHJvdG90eXBl
+CkMub2w9Vy5LNS5wcm90b3R5cGUKQy55OD1uZXcgUC5VOCgpCkMuaDk9bmV3IFAuQ1YoKQpDLkd3PW5l
+dyBILkZ1KEguTjAoIkZ1PGM4PiIpKQpDLk80PWZ1bmN0aW9uIGdldFRhZ0ZhbGxiYWNrKG8pIHsKICB2
+YXIgcyA9IE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmcuY2FsbChvKTsKICByZXR1cm4gcy5zdWJzdHJp
+bmcoOCwgcy5sZW5ndGggLSAxKTsKfQpDLllxPWZ1bmN0aW9uKCkgewogIHZhciB0b1N0cmluZ0Z1bmN0
+aW9uID0gT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZzsKICBmdW5jdGlvbiBnZXRUYWcobykgewogICAg
+dmFyIHMgPSB0b1N0cmluZ0Z1bmN0aW9uLmNhbGwobyk7CiAgICByZXR1cm4gcy5zdWJzdHJpbmcoOCwg
+cy5sZW5ndGggLSAxKTsKICB9CiAgZnVuY3Rpb24gZ2V0VW5rbm93blRhZyhvYmplY3QsIHRhZykgewog
+ICAgaWYgKC9eSFRNTFtBLVpdLipFbGVtZW50JC8udGVzdCh0YWcpKSB7CiAgICAgIHZhciBuYW1lID0g
+dG9TdHJpbmdGdW5jdGlvbi5jYWxsKG9iamVjdCk7CiAgICAgIGlmIChuYW1lID09ICJbb2JqZWN0IE9i
+amVjdF0iKSByZXR1cm4gbnVsbDsKICAgICAgcmV0dXJuICJIVE1MRWxlbWVudCI7CiAgICB9CiAgfQog
+IGZ1bmN0aW9uIGdldFVua25vd25UYWdHZW5lcmljQnJvd3NlcihvYmplY3QsIHRhZykgewogICAgaWYg
+KHNlbGYuSFRNTEVsZW1lbnQgJiYgb2JqZWN0IGluc3RhbmNlb2YgSFRNTEVsZW1lbnQpIHJldHVybiAi
+SFRNTEVsZW1lbnQiOwogICAgcmV0dXJuIGdldFVua25vd25UYWcob2JqZWN0LCB0YWcpOwogIH0KICBm
+dW5jdGlvbiBwcm90b3R5cGVGb3JUYWcodGFnKSB7CiAgICBpZiAodHlwZW9mIHdpbmRvdyA9PSAidW5k
+ZWZpbmVkIikgcmV0dXJuIG51bGw7CiAgICBpZiAodHlwZW9mIHdpbmRvd1t0YWddID09ICJ1bmRlZmlu
+ZWQiKSByZXR1cm4gbnVsbDsKICAgIHZhciBjb25zdHJ1Y3RvciA9IHdpbmRvd1t0YWddOwogICAgaWYg
+KHR5cGVvZiBjb25zdHJ1Y3RvciAhPSAiZnVuY3Rpb24iKSByZXR1cm4gbnVsbDsKICAgIHJldHVybiBj
+b25zdHJ1Y3Rvci5wcm90b3R5cGU7CiAgfQogIGZ1bmN0aW9uIGRpc2NyaW1pbmF0b3IodGFnKSB7IHJl
+dHVybiBudWxsOyB9CiAgdmFyIGlzQnJvd3NlciA9IHR5cGVvZiBuYXZpZ2F0b3IgPT0gIm9iamVjdCI7
+CiAgcmV0dXJuIHsKICAgIGdldFRhZzogZ2V0VGFnLAogICAgZ2V0VW5rbm93blRhZzogaXNCcm93c2Vy
+ID8gZ2V0VW5rbm93blRhZ0dlbmVyaWNCcm93c2VyIDogZ2V0VW5rbm93blRhZywKICAgIHByb3RvdHlw
+ZUZvclRhZzogcHJvdG90eXBlRm9yVGFnLAogICAgZGlzY3JpbWluYXRvcjogZGlzY3JpbWluYXRvciB9
+Owp9CkMud2I9ZnVuY3Rpb24oZ2V0VGFnRmFsbGJhY2spIHsKICByZXR1cm4gZnVuY3Rpb24oaG9va3Mp
+IHsKICAgIGlmICh0eXBlb2YgbmF2aWdhdG9yICE9ICJvYmplY3QiKSByZXR1cm4gaG9va3M7CiAgICB2
+YXIgdWEgPSBuYXZpZ2F0b3IudXNlckFnZW50OwogICAgaWYgKHVhLmluZGV4T2YoIkR1bXBSZW5kZXJU
+cmVlIikgPj0gMCkgcmV0dXJuIGhvb2tzOwogICAgaWYgKHVhLmluZGV4T2YoIkNocm9tZSIpID49IDAp
+IHsKICAgICAgZnVuY3Rpb24gY29uZmlybShwKSB7CiAgICAgICAgcmV0dXJuIHR5cGVvZiB3aW5kb3cg
+PT0gIm9iamVjdCIgJiYgd2luZG93W3BdICYmIHdpbmRvd1twXS5uYW1lID09IHA7CiAgICAgIH0KICAg
+ICAgaWYgKGNvbmZpcm0oIldpbmRvdyIpICYmIGNvbmZpcm0oIkhUTUxFbGVtZW50IikpIHJldHVybiBo
+b29rczsKICAgIH0KICAgIGhvb2tzLmdldFRhZyA9IGdldFRhZ0ZhbGxiYWNrOwogIH07Cn0KQy5LVT1m
+dW5jdGlvbihob29rcykgewogIGlmICh0eXBlb2YgZGFydEV4cGVyaW1lbnRhbEZpeHVwR2V0VGFnICE9
+ICJmdW5jdGlvbiIpIHJldHVybiBob29rczsKICBob29rcy5nZXRUYWcgPSBkYXJ0RXhwZXJpbWVudGFs
+Rml4dXBHZXRUYWcoaG9va3MuZ2V0VGFnKTsKfQpDLmZRPWZ1bmN0aW9uKGhvb2tzKSB7CiAgdmFyIGdl
+dFRhZyA9IGhvb2tzLmdldFRhZzsKICB2YXIgcHJvdG90eXBlRm9yVGFnID0gaG9va3MucHJvdG90eXBl
+Rm9yVGFnOwogIGZ1bmN0aW9uIGdldFRhZ0ZpeGVkKG8pIHsKICAgIHZhciB0YWcgPSBnZXRUYWcobyk7
+CiAgICBpZiAodGFnID09ICJEb2N1bWVudCIpIHsKICAgICAgaWYgKCEhby54bWxWZXJzaW9uKSByZXR1
+cm4gIiFEb2N1bWVudCI7CiAgICAgIHJldHVybiAiIUhUTUxEb2N1bWVudCI7CiAgICB9CiAgICByZXR1
+cm4gdGFnOwogIH0KICBmdW5jdGlvbiBwcm90b3R5cGVGb3JUYWdGaXhlZCh0YWcpIHsKICAgIGlmICh0
+YWcgPT0gIkRvY3VtZW50IikgcmV0dXJuIG51bGw7CiAgICByZXR1cm4gcHJvdG90eXBlRm9yVGFnKHRh
+Zyk7CiAgfQogIGhvb2tzLmdldFRhZyA9IGdldFRhZ0ZpeGVkOwogIGhvb2tzLnByb3RvdHlwZUZvclRh
+ZyA9IHByb3RvdHlwZUZvclRhZ0ZpeGVkOwp9CkMuZGs9ZnVuY3Rpb24oaG9va3MpIHsKICB2YXIgdXNl
+ckFnZW50ID0gdHlwZW9mIG5hdmlnYXRvciA9PSAib2JqZWN0IiA/IG5hdmlnYXRvci51c2VyQWdlbnQg
+OiAiIjsKICBpZiAodXNlckFnZW50LmluZGV4T2YoIkZpcmVmb3giKSA9PSAtMSkgcmV0dXJuIGhvb2tz
+OwogIHZhciBnZXRUYWcgPSBob29rcy5nZXRUYWc7CiAgdmFyIHF1aWNrTWFwID0gewogICAgIkJlZm9y
+ZVVubG9hZEV2ZW50IjogIkV2ZW50IiwKICAgICJEYXRhVHJhbnNmZXIiOiAiQ2xpcGJvYXJkIiwKICAg
+ICJHZW9HZW9sb2NhdGlvbiI6ICJHZW9sb2NhdGlvbiIsCiAgICAiTG9jYXRpb24iOiAiIUxvY2F0aW9u
+IiwKICAgICJXb3JrZXJNZXNzYWdlRXZlbnQiOiAiTWVzc2FnZUV2ZW50IiwKICAgICJYTUxEb2N1bWVu
+dCI6ICIhRG9jdW1lbnQifTsKICBmdW5jdGlvbiBnZXRUYWdGaXJlZm94KG8pIHsKICAgIHZhciB0YWcg
+PSBnZXRUYWcobyk7CiAgICByZXR1cm4gcXVpY2tNYXBbdGFnXSB8fCB0YWc7CiAgfQogIGhvb2tzLmdl
+dFRhZyA9IGdldFRhZ0ZpcmVmb3g7Cn0KQy54aT1mdW5jdGlvbihob29rcykgewogIHZhciB1c2VyQWdl
+bnQgPSB0eXBlb2YgbmF2aWdhdG9yID09ICJvYmplY3QiID8gbmF2aWdhdG9yLnVzZXJBZ2VudCA6ICIi
+OwogIGlmICh1c2VyQWdlbnQuaW5kZXhPZigiVHJpZGVudC8iKSA9PSAtMSkgcmV0dXJuIGhvb2tzOwog
+IHZhciBnZXRUYWcgPSBob29rcy5nZXRUYWc7CiAgdmFyIHF1aWNrTWFwID0gewogICAgIkJlZm9yZVVu
+bG9hZEV2ZW50IjogIkV2ZW50IiwKICAgICJEYXRhVHJhbnNmZXIiOiAiQ2xpcGJvYXJkIiwKICAgICJI
+VE1MRERFbGVtZW50IjogIkhUTUxFbGVtZW50IiwKICAgICJIVE1MRFRFbGVtZW50IjogIkhUTUxFbGVt
+ZW50IiwKICAgICJIVE1MUGhyYXNlRWxlbWVudCI6ICJIVE1MRWxlbWVudCIsCiAgICAiUG9zaXRpb24i
+OiAiR2VvcG9zaXRpb24iCiAgfTsKICBmdW5jdGlvbiBnZXRUYWdJRShvKSB7CiAgICB2YXIgdGFnID0g
+Z2V0VGFnKG8pOwogICAgdmFyIG5ld1RhZyA9IHF1aWNrTWFwW3RhZ107CiAgICBpZiAobmV3VGFnKSBy
+ZXR1cm4gbmV3VGFnOwogICAgaWYgKHRhZyA9PSAiT2JqZWN0IikgewogICAgICBpZiAod2luZG93LkRh
+dGFWaWV3ICYmIChvIGluc3RhbmNlb2Ygd2luZG93LkRhdGFWaWV3KSkgcmV0dXJuICJEYXRhVmlldyI7
+CiAgICB9CiAgICByZXR1cm4gdGFnOwogIH0KICBmdW5jdGlvbiBwcm90b3R5cGVGb3JUYWdJRSh0YWcp
+IHsKICAgIHZhciBjb25zdHJ1Y3RvciA9IHdpbmRvd1t0YWddOwogICAgaWYgKGNvbnN0cnVjdG9yID09
+IG51bGwpIHJldHVybiBudWxsOwogICAgcmV0dXJuIGNvbnN0cnVjdG9yLnByb3RvdHlwZTsKICB9CiAg
+aG9va3MuZ2V0VGFnID0gZ2V0VGFnSUU7CiAgaG9va3MucHJvdG90eXBlRm9yVGFnID0gcHJvdG90eXBl
+Rm9yVGFnSUU7Cn0KQy5pNz1mdW5jdGlvbihob29rcykgeyByZXR1cm4gaG9va3M7IH0KCkMuQ3Q9bmV3
+IFAuYnkoKQpDLkVxPW5ldyBQLms1KCkKQy54TT1uZXcgUC51NSgpCkMuUWs9bmV3IFAuRTMoKQpDLk52
+PW5ldyBILmtyKCkKQy5OVT1uZXcgUC5KaSgpCkMucGQ9bmV3IFAuWmQoKQpDLkFkPW5ldyBNLkg3KDAs
+IkhpbnRBY3Rpb25LaW5kLmFkZE51bGxhYmxlSGludCIpCkMubmU9bmV3IE0uSDcoMSwiSGludEFjdGlv
+bktpbmQuYWRkTm9uTnVsbGFibGVIaW50IikKQy5teT1uZXcgTS5INygyLCJIaW50QWN0aW9uS2luZC5j
+aGFuZ2VUb051bGxhYmxlSGludCIpCkMucng9bmV3IE0uSDcoMywiSGludEFjdGlvbktpbmQuY2hhbmdl
+VG9Ob25OdWxsYWJsZUhpbnQiKQpDLndWPW5ldyBNLkg3KDQsIkhpbnRBY3Rpb25LaW5kLnJlbW92ZU51
+bGxhYmxlSGludCIpCkMuZlI9bmV3IE0uSDcoNSwiSGludEFjdGlvbktpbmQucmVtb3ZlTm9uTnVsbGFi
+bGVIaW50IikKQy5BMz1uZXcgUC5NeChudWxsKQpDLm5YPW5ldyBQLm9qKG51bGwpCkMuY3c9bmV3IEwu
+R2IoMCwiVW5pdE1pZ3JhdGlvblN0YXR1cy5hbHJlYWR5TWlncmF0ZWQiKQpDLmRjPW5ldyBMLkdiKDEs
+IlVuaXRNaWdyYXRpb25TdGF0dXMuaW5kZXRlcm1pbmF0ZSIpCkMuV0Q9bmV3IEwuR2IoMiwiVW5pdE1p
+Z3JhdGlvblN0YXR1cy5taWdyYXRpbmciKQpDLlhqPW5ldyBMLkdiKDMsIlVuaXRNaWdyYXRpb25TdGF0
+dXMub3B0aW5nT3V0IikKQy5sMD1ILlZNKHMoW0MuY3csQy5kYyxDLldELEMuWGpdKSxILk4wKCJqZDxH
+Yio+IikpCkMuYWs9SC5WTShzKFswLDAsMzI3NzYsMzM3OTIsMSwxMDI0MCwwLDBdKSx0LlYpCkMuY209
+SC5WTShzKFsiKjo6Y2xhc3MiLCIqOjpkaXIiLCIqOjpkcmFnZ2FibGUiLCIqOjpoaWRkZW4iLCIqOjpp
+ZCIsIio6OmluZXJ0IiwiKjo6aXRlbXByb3AiLCIqOjppdGVtcmVmIiwiKjo6aXRlbXNjb3BlIiwiKjo6
+bGFuZyIsIio6OnNwZWxsY2hlY2siLCIqOjp0aXRsZSIsIio6OnRyYW5zbGF0ZSIsIkE6OmFjY2Vzc2tl
+eSIsIkE6OmNvb3JkcyIsIkE6OmhyZWZsYW5nIiwiQTo6bmFtZSIsIkE6OnNoYXBlIiwiQTo6dGFiaW5k
+ZXgiLCJBOjp0YXJnZXQiLCJBOjp0eXBlIiwiQVJFQTo6YWNjZXNza2V5IiwiQVJFQTo6YWx0IiwiQVJF
+QTo6Y29vcmRzIiwiQVJFQTo6bm9ocmVmIiwiQVJFQTo6c2hhcGUiLCJBUkVBOjp0YWJpbmRleCIsIkFS
+RUE6OnRhcmdldCIsIkFVRElPOjpjb250cm9scyIsIkFVRElPOjpsb29wIiwiQVVESU86Om1lZGlhZ3Jv
+dXAiLCJBVURJTzo6bXV0ZWQiLCJBVURJTzo6cHJlbG9hZCIsIkJETzo6ZGlyIiwiQk9EWTo6YWxpbmsi
+LCJCT0RZOjpiZ2NvbG9yIiwiQk9EWTo6bGluayIsIkJPRFk6OnRleHQiLCJCT0RZOjp2bGluayIsIkJS
+OjpjbGVhciIsIkJVVFRPTjo6YWNjZXNza2V5IiwiQlVUVE9OOjpkaXNhYmxlZCIsIkJVVFRPTjo6bmFt
+ZSIsIkJVVFRPTjo6dGFiaW5kZXgiLCJCVVRUT046OnR5cGUiLCJCVVRUT046OnZhbHVlIiwiQ0FOVkFT
+OjpoZWlnaHQiLCJDQU5WQVM6OndpZHRoIiwiQ0FQVElPTjo6YWxpZ24iLCJDT0w6OmFsaWduIiwiQ09M
+OjpjaGFyIiwiQ09MOjpjaGFyb2ZmIiwiQ09MOjpzcGFuIiwiQ09MOjp2YWxpZ24iLCJDT0w6OndpZHRo
+IiwiQ09MR1JPVVA6OmFsaWduIiwiQ09MR1JPVVA6OmNoYXIiLCJDT0xHUk9VUDo6Y2hhcm9mZiIsIkNP
+TEdST1VQOjpzcGFuIiwiQ09MR1JPVVA6OnZhbGlnbiIsIkNPTEdST1VQOjp3aWR0aCIsIkNPTU1BTkQ6
+OmNoZWNrZWQiLCJDT01NQU5EOjpjb21tYW5kIiwiQ09NTUFORDo6ZGlzYWJsZWQiLCJDT01NQU5EOjps
+YWJlbCIsIkNPTU1BTkQ6OnJhZGlvZ3JvdXAiLCJDT01NQU5EOjp0eXBlIiwiREFUQTo6dmFsdWUiLCJE
+RUw6OmRhdGV0aW1lIiwiREVUQUlMUzo6b3BlbiIsIkRJUjo6Y29tcGFjdCIsIkRJVjo6YWxpZ24iLCJE
+TDo6Y29tcGFjdCIsIkZJRUxEU0VUOjpkaXNhYmxlZCIsIkZPTlQ6OmNvbG9yIiwiRk9OVDo6ZmFjZSIs
+IkZPTlQ6OnNpemUiLCJGT1JNOjphY2NlcHQiLCJGT1JNOjphdXRvY29tcGxldGUiLCJGT1JNOjplbmN0
+eXBlIiwiRk9STTo6bWV0aG9kIiwiRk9STTo6bmFtZSIsIkZPUk06Om5vdmFsaWRhdGUiLCJGT1JNOjp0
+YXJnZXQiLCJGUkFNRTo6bmFtZSIsIkgxOjphbGlnbiIsIkgyOjphbGlnbiIsIkgzOjphbGlnbiIsIkg0
+OjphbGlnbiIsIkg1OjphbGlnbiIsIkg2OjphbGlnbiIsIkhSOjphbGlnbiIsIkhSOjpub3NoYWRlIiwi
+SFI6OnNpemUiLCJIUjo6d2lkdGgiLCJIVE1MOjp2ZXJzaW9uIiwiSUZSQU1FOjphbGlnbiIsIklGUkFN
+RTo6ZnJhbWVib3JkZXIiLCJJRlJBTUU6OmhlaWdodCIsIklGUkFNRTo6bWFyZ2luaGVpZ2h0IiwiSUZS
+QU1FOjptYXJnaW53aWR0aCIsIklGUkFNRTo6d2lkdGgiLCJJTUc6OmFsaWduIiwiSU1HOjphbHQiLCJJ
+TUc6OmJvcmRlciIsIklNRzo6aGVpZ2h0IiwiSU1HOjpoc3BhY2UiLCJJTUc6OmlzbWFwIiwiSU1HOjpu
+YW1lIiwiSU1HOjp1c2VtYXAiLCJJTUc6OnZzcGFjZSIsIklNRzo6d2lkdGgiLCJJTlBVVDo6YWNjZXB0
+IiwiSU5QVVQ6OmFjY2Vzc2tleSIsIklOUFVUOjphbGlnbiIsIklOUFVUOjphbHQiLCJJTlBVVDo6YXV0
+b2NvbXBsZXRlIiwiSU5QVVQ6OmF1dG9mb2N1cyIsIklOUFVUOjpjaGVja2VkIiwiSU5QVVQ6OmRpc2Fi
+bGVkIiwiSU5QVVQ6OmlucHV0bW9kZSIsIklOUFVUOjppc21hcCIsIklOUFVUOjpsaXN0IiwiSU5QVVQ6
+Om1heCIsIklOUFVUOjptYXhsZW5ndGgiLCJJTlBVVDo6bWluIiwiSU5QVVQ6Om11bHRpcGxlIiwiSU5Q
+VVQ6Om5hbWUiLCJJTlBVVDo6cGxhY2Vob2xkZXIiLCJJTlBVVDo6cmVhZG9ubHkiLCJJTlBVVDo6cmVx
+dWlyZWQiLCJJTlBVVDo6c2l6ZSIsIklOUFVUOjpzdGVwIiwiSU5QVVQ6OnRhYmluZGV4IiwiSU5QVVQ6
+OnR5cGUiLCJJTlBVVDo6dXNlbWFwIiwiSU5QVVQ6OnZhbHVlIiwiSU5TOjpkYXRldGltZSIsIktFWUdF
+Tjo6ZGlzYWJsZWQiLCJLRVlHRU46OmtleXR5cGUiLCJLRVlHRU46Om5hbWUiLCJMQUJFTDo6YWNjZXNz
+a2V5IiwiTEFCRUw6OmZvciIsIkxFR0VORDo6YWNjZXNza2V5IiwiTEVHRU5EOjphbGlnbiIsIkxJOjp0
+eXBlIiwiTEk6OnZhbHVlIiwiTElOSzo6c2l6ZXMiLCJNQVA6Om5hbWUiLCJNRU5VOjpjb21wYWN0Iiwi
+TUVOVTo6bGFiZWwiLCJNRU5VOjp0eXBlIiwiTUVURVI6OmhpZ2giLCJNRVRFUjo6bG93IiwiTUVURVI6
+Om1heCIsIk1FVEVSOjptaW4iLCJNRVRFUjo6dmFsdWUiLCJPQkpFQ1Q6OnR5cGVtdXN0bWF0Y2giLCJP
+TDo6Y29tcGFjdCIsIk9MOjpyZXZlcnNlZCIsIk9MOjpzdGFydCIsIk9MOjp0eXBlIiwiT1BUR1JPVVA6
+OmRpc2FibGVkIiwiT1BUR1JPVVA6OmxhYmVsIiwiT1BUSU9OOjpkaXNhYmxlZCIsIk9QVElPTjo6bGFi
+ZWwiLCJPUFRJT046OnNlbGVjdGVkIiwiT1BUSU9OOjp2YWx1ZSIsIk9VVFBVVDo6Zm9yIiwiT1VUUFVU
+OjpuYW1lIiwiUDo6YWxpZ24iLCJQUkU6OndpZHRoIiwiUFJPR1JFU1M6Om1heCIsIlBST0dSRVNTOjpt
+aW4iLCJQUk9HUkVTUzo6dmFsdWUiLCJTRUxFQ1Q6OmF1dG9jb21wbGV0ZSIsIlNFTEVDVDo6ZGlzYWJs
+ZWQiLCJTRUxFQ1Q6Om11bHRpcGxlIiwiU0VMRUNUOjpuYW1lIiwiU0VMRUNUOjpyZXF1aXJlZCIsIlNF
+TEVDVDo6c2l6ZSIsIlNFTEVDVDo6dGFiaW5kZXgiLCJTT1VSQ0U6OnR5cGUiLCJUQUJMRTo6YWxpZ24i
+LCJUQUJMRTo6Ymdjb2xvciIsIlRBQkxFOjpib3JkZXIiLCJUQUJMRTo6Y2VsbHBhZGRpbmciLCJUQUJM
+RTo6Y2VsbHNwYWNpbmciLCJUQUJMRTo6ZnJhbWUiLCJUQUJMRTo6cnVsZXMiLCJUQUJMRTo6c3VtbWFy
+eSIsIlRBQkxFOjp3aWR0aCIsIlRCT0RZOjphbGlnbiIsIlRCT0RZOjpjaGFyIiwiVEJPRFk6OmNoYXJv
+ZmYiLCJUQk9EWTo6dmFsaWduIiwiVEQ6OmFiYnIiLCJURDo6YWxpZ24iLCJURDo6YXhpcyIsIlREOjpi
+Z2NvbG9yIiwiVEQ6OmNoYXIiLCJURDo6Y2hhcm9mZiIsIlREOjpjb2xzcGFuIiwiVEQ6OmhlYWRlcnMi
+LCJURDo6aGVpZ2h0IiwiVEQ6Om5vd3JhcCIsIlREOjpyb3dzcGFuIiwiVEQ6OnNjb3BlIiwiVEQ6OnZh
+bGlnbiIsIlREOjp3aWR0aCIsIlRFWFRBUkVBOjphY2Nlc3NrZXkiLCJURVhUQVJFQTo6YXV0b2NvbXBs
+ZXRlIiwiVEVYVEFSRUE6OmNvbHMiLCJURVhUQVJFQTo6ZGlzYWJsZWQiLCJURVhUQVJFQTo6aW5wdXRt
+b2RlIiwiVEVYVEFSRUE6Om5hbWUiLCJURVhUQVJFQTo6cGxhY2Vob2xkZXIiLCJURVhUQVJFQTo6cmVh
+ZG9ubHkiLCJURVhUQVJFQTo6cmVxdWlyZWQiLCJURVhUQVJFQTo6cm93cyIsIlRFWFRBUkVBOjp0YWJp
+bmRleCIsIlRFWFRBUkVBOjp3cmFwIiwiVEZPT1Q6OmFsaWduIiwiVEZPT1Q6OmNoYXIiLCJURk9PVDo6
+Y2hhcm9mZiIsIlRGT09UOjp2YWxpZ24iLCJUSDo6YWJiciIsIlRIOjphbGlnbiIsIlRIOjpheGlzIiwi
+VEg6OmJnY29sb3IiLCJUSDo6Y2hhciIsIlRIOjpjaGFyb2ZmIiwiVEg6OmNvbHNwYW4iLCJUSDo6aGVh
+ZGVycyIsIlRIOjpoZWlnaHQiLCJUSDo6bm93cmFwIiwiVEg6OnJvd3NwYW4iLCJUSDo6c2NvcGUiLCJU
+SDo6dmFsaWduIiwiVEg6OndpZHRoIiwiVEhFQUQ6OmFsaWduIiwiVEhFQUQ6OmNoYXIiLCJUSEVBRDo6
+Y2hhcm9mZiIsIlRIRUFEOjp2YWxpZ24iLCJUUjo6YWxpZ24iLCJUUjo6Ymdjb2xvciIsIlRSOjpjaGFy
+IiwiVFI6OmNoYXJvZmYiLCJUUjo6dmFsaWduIiwiVFJBQ0s6OmRlZmF1bHQiLCJUUkFDSzo6a2luZCIs
+IlRSQUNLOjpsYWJlbCIsIlRSQUNLOjpzcmNsYW5nIiwiVUw6OmNvbXBhY3QiLCJVTDo6dHlwZSIsIlZJ
+REVPOjpjb250cm9scyIsIlZJREVPOjpoZWlnaHQiLCJWSURFTzo6bG9vcCIsIlZJREVPOjptZWRpYWdy
+b3VwIiwiVklERU86Om11dGVkIiwiVklERU86OnByZWxvYWQiLCJWSURFTzo6d2lkdGgiXSksdC5pKQpD
+LlZDPUguVk0ocyhbMCwwLDY1NDkwLDQ1MDU1LDY1NTM1LDM0ODE1LDY1NTM0LDE4NDMxXSksdC5WKQpD
+Lm1LPUguVk0ocyhbMCwwLDI2NjI0LDEwMjMsNjU1MzQsMjA0Nyw2NTUzNCwyMDQ3XSksdC5WKQpDLlNx
+PUguVk0ocyhbIkhFQUQiLCJBUkVBIiwiQkFTRSIsIkJBU0VGT05UIiwiQlIiLCJDT0wiLCJDT0xHUk9V
+UCIsIkVNQkVEIiwiRlJBTUUiLCJGUkFNRVNFVCIsIkhSIiwiSU1BR0UiLCJJTUciLCJJTlBVVCIsIklT
+SU5ERVgiLCJMSU5LIiwiTUVUQSIsIlBBUkFNIiwiU09VUkNFIiwiU1RZTEUiLCJUSVRMRSIsIldCUiJd
+KSx0LmkpCkMuaFU9SC5WTShzKFtdKSx0LngpCkMuZG49SC5WTShzKFtdKSxILk4wKCJqZDxMTCo+Iikp
+CkMueEQ9SC5WTShzKFtdKSx0LmkpCkMudG89SC5WTShzKFswLDAsMzI3MjIsMTIyODcsNjU1MzQsMzQ4
+MTUsNjU1MzQsMTg0MzFdKSx0LlYpCkMucms9SC5WTShzKFtDLkFkLEMubmUsQy5teSxDLnJ4LEMud1Ys
+Qy5mUl0pLEguTjAoImpkPEg3Kj4iKSkKQy5GMz1ILlZNKHMoWzAsMCwyNDU3NiwxMDIzLDY1NTM0LDM0
+ODE1LDY1NTM0LDE4NDMxXSksdC5WKQpDLmVhPUguVk0ocyhbMCwwLDMyNzU0LDExMjYzLDY1NTM0LDM0
+ODE1LDY1NTM0LDE4NDMxXSksdC5WKQpDLlpKPUguVk0ocyhbMCwwLDMyNzIyLDEyMjg3LDY1NTM1LDM0
+ODE1LDY1NTM0LDE4NDMxXSksdC5WKQpDLldkPUguVk0ocyhbMCwwLDY1NDkwLDEyMjg3LDY1NTM1LDM0
+ODE1LDY1NTM0LDE4NDMxXSksdC5WKQpDLlF4PUguVk0ocyhbImJpbmQiLCJpZiIsInJlZiIsInJlcGVh
+dCIsInN5bnRheCJdKSx0LmkpCkMuQkk9SC5WTShzKFsiQTo6aHJlZiIsIkFSRUE6OmhyZWYiLCJCTE9D
+S1FVT1RFOjpjaXRlIiwiQk9EWTo6YmFja2dyb3VuZCIsIkNPTU1BTkQ6Omljb24iLCJERUw6OmNpdGUi
+LCJGT1JNOjphY3Rpb24iLCJJTUc6OnNyYyIsIklOUFVUOjpzcmMiLCJJTlM6OmNpdGUiLCJROjpjaXRl
+IiwiVklERU86OnBvc3RlciJdKSx0LmkpCkMuRHg9bmV3IEguTFAoMCx7fSxDLnhELEguTjAoIkxQPHFV
+Kix6TTxqOCo+Kj4iKSkKQy5DTT1uZXcgSC5MUCgwLHt9LEMueEQsSC5OMCgiTFA8cVUqLHFVKj4iKSkK
+Qy5pSD1ILlZNKHMoW10pLEguTjAoImpkPEdEKj4iKSkKQy5XTz1uZXcgSC5MUCgwLHt9LEMuaUgsSC5O
+MCgiTFA8R0QqLEA+IikpCkMuWTI9bmV3IEwuTzkoIk5hdmlnYXRpb25UcmVlTm9kZVR5cGUuZGlyZWN0
+b3J5IikKQy5yZj1uZXcgTC5POSgiTmF2aWdhdGlvblRyZWVOb2RlVHlwZS5maWxlIikKQy5UZT1uZXcg
+SC53digiY2FsbCIpCkMub0U9bmV3IFAuR1koITEpCkMud1E9bmV3IFAuRnkobnVsbCwyKX0pKCk7KGZ1
+bmN0aW9uIHN0YXRpY0ZpZWxkcygpeyQuem09bnVsbAokLnlqPTAKJC5tSj1udWxsCiQuUDQ9bnVsbAok
+Lk5GPW51bGwKJC5UWD1udWxsCiQueDc9bnVsbAokLm53PW51bGwKJC52dj1udWxsCiQuQnY9bnVsbAok
+LlM2PW51bGwKJC5rOD1udWxsCiQubWc9bnVsbAokLlVEPSExCiQuWDM9Qy5OVQokLnhnPUguVk0oW10s
+SC5OMCgiamQ8TWg+IikpCiQueG89bnVsbAokLkJPPW51bGwKJC5sdD1udWxsCiQuRVU9bnVsbAokLm9y
+PVAuRmwodC5OLHQuWSkKJC5JUj1udWxsCiQuSTY9bnVsbAokLkZmPW51bGx9KSgpOyhmdW5jdGlvbiBs
+YXp5SW5pdGlhbGl6ZXJzKCl7dmFyIHM9aHVua0hlbHBlcnMubGF6eUZpbmFsLHI9aHVua0hlbHBlcnMu
+bGF6eU9sZApzKCQsImZhIiwidyIsZnVuY3Rpb24oKXtyZXR1cm4gSC5ZZygiXyRkYXJ0X2RhcnRDbG9z
+dXJlIil9KQpzKCQsIlUyIiwiU24iLGZ1bmN0aW9uKCl7cmV0dXJuIEguY00oSC5TNyh7CnRvU3RyaW5n
+OmZ1bmN0aW9uKCl7cmV0dXJuIiRyZWNlaXZlciQifX0pKX0pCnMoJCwieHEiLCJscSIsZnVuY3Rpb24o
+KXtyZXR1cm4gSC5jTShILlM3KHskbWV0aG9kJDpudWxsLAp0b1N0cmluZzpmdW5jdGlvbigpe3JldHVy
+biIkcmVjZWl2ZXIkIn19KSl9KQpzKCQsIlIxIiwiTjkiLGZ1bmN0aW9uKCl7cmV0dXJuIEguY00oSC5T
+NyhudWxsKSl9KQpzKCQsImZOIiwiaUkiLGZ1bmN0aW9uKCl7cmV0dXJuIEguY00oZnVuY3Rpb24oKXt2
+YXIgJGFyZ3VtZW50c0V4cHIkPSckYXJndW1lbnRzJCcKdHJ5e251bGwuJG1ldGhvZCQoJGFyZ3VtZW50
+c0V4cHIkKX1jYXRjaChxKXtyZXR1cm4gcS5tZXNzYWdlfX0oKSl9KQpzKCQsInFpIiwiVU4iLGZ1bmN0
+aW9uKCl7cmV0dXJuIEguY00oSC5TNyh2b2lkIDApKX0pCnMoJCwicloiLCJaaCIsZnVuY3Rpb24oKXty
+ZXR1cm4gSC5jTShmdW5jdGlvbigpe3ZhciAkYXJndW1lbnRzRXhwciQ9JyRhcmd1bWVudHMkJwp0cnl7
+KHZvaWQgMCkuJG1ldGhvZCQoJGFyZ3VtZW50c0V4cHIkKX1jYXRjaChxKXtyZXR1cm4gcS5tZXNzYWdl
+fX0oKSl9KQpzKCQsImtxIiwick4iLGZ1bmN0aW9uKCl7cmV0dXJuIEguY00oSC5NaihudWxsKSl9KQpz
+KCQsInR0IiwiYzMiLGZ1bmN0aW9uKCl7cmV0dXJuIEguY00oZnVuY3Rpb24oKXt0cnl7bnVsbC4kbWV0
+aG9kJH1jYXRjaChxKXtyZXR1cm4gcS5tZXNzYWdlfX0oKSl9KQpzKCQsImR0IiwiSEsiLGZ1bmN0aW9u
+KCl7cmV0dXJuIEguY00oSC5Naih2b2lkIDApKX0pCnMoJCwiQTciLCJyMSIsZnVuY3Rpb24oKXtyZXR1
+cm4gSC5jTShmdW5jdGlvbigpe3RyeXsodm9pZCAwKS4kbWV0aG9kJH1jYXRjaChxKXtyZXR1cm4gcS5t
+ZXNzYWdlfX0oKSl9KQpzKCQsIldjIiwidXQiLGZ1bmN0aW9uKCl7cmV0dXJuIFAuT2ooKX0pCnMoJCwi
+a2giLCJyZiIsZnVuY3Rpb24oKXtyZXR1cm4gbmV3IFAucGcoKS4kMCgpfSkKcygkLCJkSCIsIkhHIixm
+dW5jdGlvbigpe3JldHVybiBuZXcgUC5jMigpLiQwKCl9KQpzKCQsImJ0IiwiVjciLGZ1bmN0aW9uKCl7
+cmV0dXJuIG5ldyBJbnQ4QXJyYXkoSC5YRihILlZNKFstMiwtMiwtMiwtMiwtMiwtMiwtMiwtMiwtMiwt
+MiwtMiwtMiwtMiwtMiwtMiwtMiwtMiwtMiwtMiwtMiwtMiwtMiwtMiwtMiwtMiwtMiwtMiwtMiwtMiwt
+MiwtMiwtMiwtMiwtMiwtMiwtMiwtMiwtMSwtMiwtMiwtMiwtMiwtMiw2MiwtMiw2MiwtMiw2Myw1Miw1
+Myw1NCw1NSw1Niw1Nyw1OCw1OSw2MCw2MSwtMiwtMiwtMiwtMSwtMiwtMiwtMiwwLDEsMiwzLDQsNSw2
+LDcsOCw5LDEwLDExLDEyLDEzLDE0LDE1LDE2LDE3LDE4LDE5LDIwLDIxLDIyLDIzLDI0LDI1LC0yLC0y
+LC0yLC0yLDYzLC0yLDI2LDI3LDI4LDI5LDMwLDMxLDMyLDMzLDM0LDM1LDM2LDM3LDM4LDM5LDQwLDQx
+LDQyLDQzLDQ0LDQ1LDQ2LDQ3LDQ4LDQ5LDUwLDUxLC0yLC0yLC0yLC0yLC0yXSx0LmEpKSl9KQpzKCQs
+Ik01Iiwid1EiLGZ1bmN0aW9uKCl7cmV0dXJuIHR5cGVvZiBwcm9jZXNzIT0idW5kZWZpbmVkIiYmT2Jq
+ZWN0LnByb3RvdHlwZS50b1N0cmluZy5jYWxsKHByb2Nlc3MpPT0iW29iamVjdCBwcm9jZXNzXSImJnBy
+b2Nlc3MucGxhdGZvcm09PSJ3aW4zMiJ9KQpzKCQsIm1mIiwiejQiLGZ1bmN0aW9uKCl7cmV0dXJuIFAu
+bnUoIl5bXFwtXFwuMC05QS1aX2Eten5dKiQiKX0pCnMoJCwiT1EiLCJ2WiIsZnVuY3Rpb24oKXtyZXR1
+cm4gUC5LTigpfSkKcygkLCJTQyIsIkFOIixmdW5jdGlvbigpe3JldHVybiBQLnRNKFsiQSIsIkFCQlIi
+LCJBQ1JPTllNIiwiQUREUkVTUyIsIkFSRUEiLCJBUlRJQ0xFIiwiQVNJREUiLCJBVURJTyIsIkIiLCJC
+REkiLCJCRE8iLCJCSUciLCJCTE9DS1FVT1RFIiwiQlIiLCJCVVRUT04iLCJDQU5WQVMiLCJDQVBUSU9O
+IiwiQ0VOVEVSIiwiQ0lURSIsIkNPREUiLCJDT0wiLCJDT0xHUk9VUCIsIkNPTU1BTkQiLCJEQVRBIiwi
+REFUQUxJU1QiLCJERCIsIkRFTCIsIkRFVEFJTFMiLCJERk4iLCJESVIiLCJESVYiLCJETCIsIkRUIiwi
+RU0iLCJGSUVMRFNFVCIsIkZJR0NBUFRJT04iLCJGSUdVUkUiLCJGT05UIiwiRk9PVEVSIiwiRk9STSIs
+IkgxIiwiSDIiLCJIMyIsIkg0IiwiSDUiLCJINiIsIkhFQURFUiIsIkhHUk9VUCIsIkhSIiwiSSIsIklG
+UkFNRSIsIklNRyIsIklOUFVUIiwiSU5TIiwiS0JEIiwiTEFCRUwiLCJMRUdFTkQiLCJMSSIsIk1BUCIs
+Ik1BUksiLCJNRU5VIiwiTUVURVIiLCJOQVYiLCJOT0JSIiwiT0wiLCJPUFRHUk9VUCIsIk9QVElPTiIs
+Ik9VVFBVVCIsIlAiLCJQUkUiLCJQUk9HUkVTUyIsIlEiLCJTIiwiU0FNUCIsIlNFQ1RJT04iLCJTRUxF
+Q1QiLCJTTUFMTCIsIlNPVVJDRSIsIlNQQU4iLCJTVFJJS0UiLCJTVFJPTkciLCJTVUIiLCJTVU1NQVJZ
+IiwiU1VQIiwiVEFCTEUiLCJUQk9EWSIsIlREIiwiVEVYVEFSRUEiLCJURk9PVCIsIlRIIiwiVEhFQUQi
+LCJUSU1FIiwiVFIiLCJUUkFDSyIsIlRUIiwiVSIsIlVMIiwiVkFSIiwiVklERU8iLCJXQlIiXSx0Lk4p
+fSkKcygkLCJYNCIsImhHIixmdW5jdGlvbigpe3JldHVybiBQLm51KCJeXFxTKyQiKX0pCnMoJCwid08i
+LCJvdyIsZnVuY3Rpb24oKXtyZXR1cm4gUC5ORChzZWxmKX0pCnMoJCwia3QiLCJSOCIsZnVuY3Rpb24o
+KXtyZXR1cm4gSC5ZZygiXyRkYXJ0X2RhcnRPYmplY3QiKX0pCnMoJCwiZksiLCJrSSIsZnVuY3Rpb24o
+KXtyZXR1cm4gZnVuY3Rpb24gRGFydE9iamVjdChhKXt0aGlzLm89YX19KQpyKCQsInF0IiwiekIiLGZ1
+bmN0aW9uKCl7cmV0dXJuIG5ldyBULm1RKCl9KQpyKCQsIk9sIiwiVUUiLGZ1bmN0aW9uKCl7cmV0dXJu
+IFAuaEsoQy5vbC5nbVcoVy54MygpKS5ocmVmKS5naFkoKS5xKDAsImF1dGhUb2tlbiIpfSkKcigkLCJo
+VCIsInlQIixmdW5jdGlvbigpe3JldHVybiBXLlpyKCkucXVlcnlTZWxlY3RvcigiLmVkaXQtbGlzdCAu
+cGFuZWwtY29udGVudCIpfSkKcigkLCJXNiIsImhMIixmdW5jdGlvbigpe3JldHVybiBXLlpyKCkucXVl
+cnlTZWxlY3RvcigiLmVkaXQtcGFuZWwgLnBhbmVsLWNvbnRlbnQiKX0pCnIoJCwiVFIiLCJEVyIsZnVu
+Y3Rpb24oKXtyZXR1cm4gVy5acigpLnF1ZXJ5U2VsZWN0b3IoImZvb3RlciIpfSkKcigkLCJFWSIsImZp
+IixmdW5jdGlvbigpe3JldHVybiBXLlpyKCkucXVlcnlTZWxlY3RvcigiaGVhZGVyIil9KQpyKCQsImF2
+IiwiRDkiLGZ1bmN0aW9uKCl7cmV0dXJuIFcuWnIoKS5xdWVyeVNlbGVjdG9yKCIjdW5pdC1uYW1lIil9
+KQpyKCQsInQwIiwiYk4iLGZ1bmN0aW9uKCl7cmV0dXJuIFcuWnIoKS5xdWVyeVNlbGVjdG9yKCIjbWln
+cmF0ZS11bml0LXN0YXR1cy1pY29uLWxhYmVsIil9KQpyKCQsImJBIiwiYzAiLGZ1bmN0aW9uKCl7cmV0
+dXJuIFcuWnIoKS5xdWVyeVNlbGVjdG9yKCIjbWlncmF0ZS11bml0LXN0YXR1cy1pY29uIil9KQpyKCQs
+ImZlIiwiS0ciLGZ1bmN0aW9uKCl7cmV0dXJuIG5ldyBMLlhBKCl9KQpzKCQsImVvIiwiblUiLGZ1bmN0
+aW9uKCl7cmV0dXJuIG5ldyBNLmxJKCQuSGsoKSl9KQpzKCQsInlyIiwiYkQiLGZ1bmN0aW9uKCl7cmV0
+dXJuIG5ldyBFLk9GKFAubnUoIi8iKSxQLm51KCJbXi9dJCIpLFAubnUoIl4vIikpfSkKcygkLCJNayIs
+IktrIixmdW5jdGlvbigpe3JldHVybiBuZXcgTC5JVihQLm51KCJbL1xcXFxdIiksUC5udSgiW14vXFxc
+XF0kIiksUC5udSgiXihcXFxcXFxcXFteXFxcXF0rXFxcXFteXFxcXC9dK3xbYS16QS1aXTpbL1xcXFxd
+KSIpLFAubnUoIl5bL1xcXFxdKD8hWy9cXFxcXSkiKSl9KQpzKCQsImFrIiwiRWIiLGZ1bmN0aW9uKCl7
+cmV0dXJuIG5ldyBGLnJ1KFAubnUoIi8iKSxQLm51KCIoXlthLXpBLVpdWy0rLmEtekEtWlxcZF0qOi8v
+fFteL10pJCIpLFAubnUoIlthLXpBLVpdWy0rLmEtekEtWlxcZF0qOi8vW14vXSoiKSxQLm51KCJeLyIp
+KX0pCnMoJCwibHMiLCJIayIsZnVuY3Rpb24oKXtyZXR1cm4gTy5SaCgpfSl9KSgpOyhmdW5jdGlvbiBu
+YXRpdmVTdXBwb3J0KCl7IWZ1bmN0aW9uKCl7dmFyIHM9ZnVuY3Rpb24oYSl7dmFyIG09e30KbVthXT0x
+CnJldHVybiBPYmplY3Qua2V5cyhodW5rSGVscGVycy5jb252ZXJ0VG9GYXN0T2JqZWN0KG0pKVswXX0K
+di5nZXRJc29sYXRlVGFnPWZ1bmN0aW9uKGEpe3JldHVybiBzKCJfX19kYXJ0XyIrYSt2Lmlzb2xhdGVU
+YWcpfQp2YXIgcj0iX19fZGFydF9pc29sYXRlX3RhZ3NfIgp2YXIgcT1PYmplY3Rbcl18fChPYmplY3Rb
+cl09T2JqZWN0LmNyZWF0ZShudWxsKSkKdmFyIHA9Il9aeFl4WCIKZm9yKHZhciBvPTA7O28rKyl7dmFy
+IG49cyhwKyJfIitvKyJfIikKaWYoIShuIGluIHEpKXtxW25dPTEKdi5pc29sYXRlVGFnPW4KYnJlYWt9
+fXYuZGlzcGF0Y2hQcm9wZXJ0eU5hbWU9di5nZXRJc29sYXRlVGFnKCJkaXNwYXRjaF9yZWNvcmQiKX0o
+KQpodW5rSGVscGVycy5zZXRPclVwZGF0ZUludGVyY2VwdG9yc0J5VGFnKHtET01FcnJvcjpKLkd2LE1l
+ZGlhRXJyb3I6Si5HdixOYXZpZ2F0b3I6Si5HdixOYXZpZ2F0b3JDb25jdXJyZW50SGFyZHdhcmU6Si5H
+dixOYXZpZ2F0b3JVc2VyTWVkaWFFcnJvcjpKLkd2LE92ZXJjb25zdHJhaW5lZEVycm9yOkouR3YsUG9z
+aXRpb25FcnJvcjpKLkd2LFJhbmdlOkouR3YsU1FMRXJyb3I6Si5HdixEYXRhVmlldzpILkVULEFycmF5
+QnVmZmVyVmlldzpILkVULEZsb2F0MzJBcnJheTpILkRnLEZsb2F0NjRBcnJheTpILkRnLEludDE2QXJy
+YXk6SC54aixJbnQzMkFycmF5OkguZEUsSW50OEFycmF5OkguWkEsVWludDE2QXJyYXk6SC5kVCxVaW50
+MzJBcnJheTpILlBxLFVpbnQ4Q2xhbXBlZEFycmF5OkguZUUsQ2FudmFzUGl4ZWxBcnJheTpILmVFLFVp
+bnQ4QXJyYXk6SC5WNixIVE1MQXVkaW9FbGVtZW50OlcucUUsSFRNTEJSRWxlbWVudDpXLnFFLEhUTUxC
+dXR0b25FbGVtZW50OlcucUUsSFRNTENhbnZhc0VsZW1lbnQ6Vy5xRSxIVE1MQ29udGVudEVsZW1lbnQ6
+Vy5xRSxIVE1MRExpc3RFbGVtZW50OlcucUUsSFRNTERhdGFFbGVtZW50OlcucUUsSFRNTERhdGFMaXN0
+RWxlbWVudDpXLnFFLEhUTUxEZXRhaWxzRWxlbWVudDpXLnFFLEhUTUxEaWFsb2dFbGVtZW50OlcucUUs
+SFRNTERpdkVsZW1lbnQ6Vy5xRSxIVE1MRW1iZWRFbGVtZW50OlcucUUsSFRNTEZpZWxkU2V0RWxlbWVu
+dDpXLnFFLEhUTUxIUkVsZW1lbnQ6Vy5xRSxIVE1MSGVhZEVsZW1lbnQ6Vy5xRSxIVE1MSGVhZGluZ0Vs
+ZW1lbnQ6Vy5xRSxIVE1MSHRtbEVsZW1lbnQ6Vy5xRSxIVE1MSUZyYW1lRWxlbWVudDpXLnFFLEhUTUxJ
+bWFnZUVsZW1lbnQ6Vy5xRSxIVE1MSW5wdXRFbGVtZW50OlcucUUsSFRNTExJRWxlbWVudDpXLnFFLEhU
+TUxMYWJlbEVsZW1lbnQ6Vy5xRSxIVE1MTGVnZW5kRWxlbWVudDpXLnFFLEhUTUxMaW5rRWxlbWVudDpX
+LnFFLEhUTUxNYXBFbGVtZW50OlcucUUsSFRNTE1lZGlhRWxlbWVudDpXLnFFLEhUTUxNZW51RWxlbWVu
+dDpXLnFFLEhUTUxNZXRhRWxlbWVudDpXLnFFLEhUTUxNZXRlckVsZW1lbnQ6Vy5xRSxIVE1MTW9kRWxl
+bWVudDpXLnFFLEhUTUxPTGlzdEVsZW1lbnQ6Vy5xRSxIVE1MT2JqZWN0RWxlbWVudDpXLnFFLEhUTUxP
+cHRHcm91cEVsZW1lbnQ6Vy5xRSxIVE1MT3B0aW9uRWxlbWVudDpXLnFFLEhUTUxPdXRwdXRFbGVtZW50
+OlcucUUsSFRNTFBhcmFtRWxlbWVudDpXLnFFLEhUTUxQaWN0dXJlRWxlbWVudDpXLnFFLEhUTUxQcmVF
+bGVtZW50OlcucUUsSFRNTFByb2dyZXNzRWxlbWVudDpXLnFFLEhUTUxRdW90ZUVsZW1lbnQ6Vy5xRSxI
+VE1MU2NyaXB0RWxlbWVudDpXLnFFLEhUTUxTaGFkb3dFbGVtZW50OlcucUUsSFRNTFNsb3RFbGVtZW50
+OlcucUUsSFRNTFNvdXJjZUVsZW1lbnQ6Vy5xRSxIVE1MU3BhbkVsZW1lbnQ6Vy5xRSxIVE1MU3R5bGVF
+bGVtZW50OlcucUUsSFRNTFRhYmxlQ2FwdGlvbkVsZW1lbnQ6Vy5xRSxIVE1MVGFibGVDZWxsRWxlbWVu
+dDpXLnFFLEhUTUxUYWJsZURhdGFDZWxsRWxlbWVudDpXLnFFLEhUTUxUYWJsZUhlYWRlckNlbGxFbGVt
+ZW50OlcucUUsSFRNTFRhYmxlQ29sRWxlbWVudDpXLnFFLEhUTUxUZXh0QXJlYUVsZW1lbnQ6Vy5xRSxI
+VE1MVGltZUVsZW1lbnQ6Vy5xRSxIVE1MVGl0bGVFbGVtZW50OlcucUUsSFRNTFRyYWNrRWxlbWVudDpX
+LnFFLEhUTUxVTGlzdEVsZW1lbnQ6Vy5xRSxIVE1MVW5rbm93bkVsZW1lbnQ6Vy5xRSxIVE1MVmlkZW9F
+bGVtZW50OlcucUUsSFRNTERpcmVjdG9yeUVsZW1lbnQ6Vy5xRSxIVE1MRm9udEVsZW1lbnQ6Vy5xRSxI
+VE1MRnJhbWVFbGVtZW50OlcucUUsSFRNTEZyYW1lU2V0RWxlbWVudDpXLnFFLEhUTUxNYXJxdWVlRWxl
+bWVudDpXLnFFLEhUTUxFbGVtZW50OlcucUUsSFRNTEFuY2hvckVsZW1lbnQ6Vy5HaCxIVE1MQXJlYUVs
+ZW1lbnQ6Vy5mWSxIVE1MQmFzZUVsZW1lbnQ6Vy5uQixCbG9iOlcuQXosSFRNTEJvZHlFbGVtZW50Olcu
+UVAsQ0RBVEFTZWN0aW9uOlcubngsQ2hhcmFjdGVyRGF0YTpXLm54LENvbW1lbnQ6Vy5ueCxQcm9jZXNz
+aW5nSW5zdHJ1Y3Rpb246Vy5ueCxUZXh0OlcubngsQ1NTU3R5bGVEZWNsYXJhdGlvbjpXLm9KLE1TU3R5
+bGVDU1NQcm9wZXJ0aWVzOlcub0osQ1NTMlByb3BlcnRpZXM6Vy5vSixYTUxEb2N1bWVudDpXLlFGLERv
+Y3VtZW50OlcuUUYsRE9NRXhjZXB0aW9uOlcuTmgsRE9NSW1wbGVtZW50YXRpb246Vy5hZSxET01SZWN0
+UmVhZE9ubHk6Vy5JQixET01Ub2tlbkxpc3Q6Vy5uNyxFbGVtZW50OlcuY3YsQWJvcnRQYXltZW50RXZl
+bnQ6Vy5lYSxBbmltYXRpb25FdmVudDpXLmVhLEFuaW1hdGlvblBsYXliYWNrRXZlbnQ6Vy5lYSxBcHBs
+aWNhdGlvbkNhY2hlRXJyb3JFdmVudDpXLmVhLEJhY2tncm91bmRGZXRjaENsaWNrRXZlbnQ6Vy5lYSxC
+YWNrZ3JvdW5kRmV0Y2hFdmVudDpXLmVhLEJhY2tncm91bmRGZXRjaEZhaWxFdmVudDpXLmVhLEJhY2tn
+cm91bmRGZXRjaGVkRXZlbnQ6Vy5lYSxCZWZvcmVJbnN0YWxsUHJvbXB0RXZlbnQ6Vy5lYSxCZWZvcmVV
+bmxvYWRFdmVudDpXLmVhLEJsb2JFdmVudDpXLmVhLENhbk1ha2VQYXltZW50RXZlbnQ6Vy5lYSxDbGlw
+Ym9hcmRFdmVudDpXLmVhLENsb3NlRXZlbnQ6Vy5lYSxDdXN0b21FdmVudDpXLmVhLERldmljZU1vdGlv
+bkV2ZW50OlcuZWEsRGV2aWNlT3JpZW50YXRpb25FdmVudDpXLmVhLEVycm9yRXZlbnQ6Vy5lYSxFeHRl
+bmRhYmxlRXZlbnQ6Vy5lYSxFeHRlbmRhYmxlTWVzc2FnZUV2ZW50OlcuZWEsRmV0Y2hFdmVudDpXLmVh
+LEZvbnRGYWNlU2V0TG9hZEV2ZW50OlcuZWEsRm9yZWlnbkZldGNoRXZlbnQ6Vy5lYSxHYW1lcGFkRXZl
+bnQ6Vy5lYSxIYXNoQ2hhbmdlRXZlbnQ6Vy5lYSxJbnN0YWxsRXZlbnQ6Vy5lYSxNZWRpYUVuY3J5cHRl
+ZEV2ZW50OlcuZWEsTWVkaWFLZXlNZXNzYWdlRXZlbnQ6Vy5lYSxNZWRpYVF1ZXJ5TGlzdEV2ZW50Olcu
+ZWEsTWVkaWFTdHJlYW1FdmVudDpXLmVhLE1lZGlhU3RyZWFtVHJhY2tFdmVudDpXLmVhLE1lc3NhZ2VF
+dmVudDpXLmVhLE1JRElDb25uZWN0aW9uRXZlbnQ6Vy5lYSxNSURJTWVzc2FnZUV2ZW50OlcuZWEsTXV0
+YXRpb25FdmVudDpXLmVhLE5vdGlmaWNhdGlvbkV2ZW50OlcuZWEsUGFnZVRyYW5zaXRpb25FdmVudDpX
+LmVhLFBheW1lbnRSZXF1ZXN0RXZlbnQ6Vy5lYSxQYXltZW50UmVxdWVzdFVwZGF0ZUV2ZW50OlcuZWEs
+UG9wU3RhdGVFdmVudDpXLmVhLFByZXNlbnRhdGlvbkNvbm5lY3Rpb25BdmFpbGFibGVFdmVudDpXLmVh
+LFByZXNlbnRhdGlvbkNvbm5lY3Rpb25DbG9zZUV2ZW50OlcuZWEsUHJvbWlzZVJlamVjdGlvbkV2ZW50
+OlcuZWEsUHVzaEV2ZW50OlcuZWEsUlRDRGF0YUNoYW5uZWxFdmVudDpXLmVhLFJUQ0RUTUZUb25lQ2hh
+bmdlRXZlbnQ6Vy5lYSxSVENQZWVyQ29ubmVjdGlvbkljZUV2ZW50OlcuZWEsUlRDVHJhY2tFdmVudDpX
+LmVhLFNlY3VyaXR5UG9saWN5VmlvbGF0aW9uRXZlbnQ6Vy5lYSxTZW5zb3JFcnJvckV2ZW50OlcuZWEs
+U3BlZWNoUmVjb2duaXRpb25FcnJvcjpXLmVhLFNwZWVjaFJlY29nbml0aW9uRXZlbnQ6Vy5lYSxTcGVl
+Y2hTeW50aGVzaXNFdmVudDpXLmVhLFN0b3JhZ2VFdmVudDpXLmVhLFN5bmNFdmVudDpXLmVhLFRyYWNr
+RXZlbnQ6Vy5lYSxUcmFuc2l0aW9uRXZlbnQ6Vy5lYSxXZWJLaXRUcmFuc2l0aW9uRXZlbnQ6Vy5lYSxW
+UkRldmljZUV2ZW50OlcuZWEsVlJEaXNwbGF5RXZlbnQ6Vy5lYSxWUlNlc3Npb25FdmVudDpXLmVhLE1v
+am9JbnRlcmZhY2VSZXF1ZXN0RXZlbnQ6Vy5lYSxVU0JDb25uZWN0aW9uRXZlbnQ6Vy5lYSxJREJWZXJz
+aW9uQ2hhbmdlRXZlbnQ6Vy5lYSxBdWRpb1Byb2Nlc3NpbmdFdmVudDpXLmVhLE9mZmxpbmVBdWRpb0Nv
+bXBsZXRpb25FdmVudDpXLmVhLFdlYkdMQ29udGV4dEV2ZW50OlcuZWEsRXZlbnQ6Vy5lYSxJbnB1dEV2
+ZW50OlcuZWEsU3VibWl0RXZlbnQ6Vy5lYSxFdmVudFRhcmdldDpXLkQwLEZpbGU6Vy5oSCxIVE1MRm9y
+bUVsZW1lbnQ6Vy5oNCxIaXN0b3J5OlcuYnIsSFRNTERvY3VtZW50OlcuVmIsWE1MSHR0cFJlcXVlc3Q6
+Vy5mSixYTUxIdHRwUmVxdWVzdEV2ZW50VGFyZ2V0Olcud2EsSW1hZ2VEYXRhOlcuU2csTG9jYXRpb246
+Vy53NyxNb3VzZUV2ZW50OlcuQWosRHJhZ0V2ZW50OlcuQWosUG9pbnRlckV2ZW50OlcuQWosV2hlZWxF
+dmVudDpXLkFqLERvY3VtZW50RnJhZ21lbnQ6Vy51SCxTaGFkb3dSb290OlcudUgsRG9jdW1lbnRUeXBl
+OlcudUgsTm9kZTpXLnVILE5vZGVMaXN0OlcuQkgsUmFkaW9Ob2RlTGlzdDpXLkJILEhUTUxQYXJhZ3Jh
+cGhFbGVtZW50OlcuU04sUHJvZ3Jlc3NFdmVudDpXLmV3LFJlc291cmNlUHJvZ3Jlc3NFdmVudDpXLmV3
+LEhUTUxTZWxlY3RFbGVtZW50OlcubHAsSFRNTFRhYmxlRWxlbWVudDpXLlRiLEhUTUxUYWJsZVJvd0Vs
+ZW1lbnQ6Vy5JdixIVE1MVGFibGVTZWN0aW9uRWxlbWVudDpXLldQLEhUTUxUZW1wbGF0ZUVsZW1lbnQ6
+Vy55WSxDb21wb3NpdGlvbkV2ZW50OlcudzYsRm9jdXNFdmVudDpXLnc2LEtleWJvYXJkRXZlbnQ6Vy53
+NixUZXh0RXZlbnQ6Vy53NixUb3VjaEV2ZW50OlcudzYsVUlFdmVudDpXLnc2LFdpbmRvdzpXLks1LERP
+TVdpbmRvdzpXLks1LERlZGljYXRlZFdvcmtlckdsb2JhbFNjb3BlOlcuQ20sU2VydmljZVdvcmtlckds
+b2JhbFNjb3BlOlcuQ20sU2hhcmVkV29ya2VyR2xvYmFsU2NvcGU6Vy5DbSxXb3JrZXJHbG9iYWxTY29w
+ZTpXLkNtLEF0dHI6Vy5DUSxDbGllbnRSZWN0OlcudzQsRE9NUmVjdDpXLnc0LE5hbWVkTm9kZU1hcDpX
+LnJoLE1vek5hbWVkQXR0ck1hcDpXLnJoLElEQktleVJhbmdlOlAuaEYsU1ZHU2NyaXB0RWxlbWVudDpQ
+Lm5kLFNWR0FFbGVtZW50OlAuaGksU1ZHQW5pbWF0ZUVsZW1lbnQ6UC5oaSxTVkdBbmltYXRlTW90aW9u
+RWxlbWVudDpQLmhpLFNWR0FuaW1hdGVUcmFuc2Zvcm1FbGVtZW50OlAuaGksU1ZHQW5pbWF0aW9uRWxl
+bWVudDpQLmhpLFNWR0NpcmNsZUVsZW1lbnQ6UC5oaSxTVkdDbGlwUGF0aEVsZW1lbnQ6UC5oaSxTVkdE
+ZWZzRWxlbWVudDpQLmhpLFNWR0Rlc2NFbGVtZW50OlAuaGksU1ZHRGlzY2FyZEVsZW1lbnQ6UC5oaSxT
+VkdFbGxpcHNlRWxlbWVudDpQLmhpLFNWR0ZFQmxlbmRFbGVtZW50OlAuaGksU1ZHRkVDb2xvck1hdHJp
+eEVsZW1lbnQ6UC5oaSxTVkdGRUNvbXBvbmVudFRyYW5zZmVyRWxlbWVudDpQLmhpLFNWR0ZFQ29tcG9z
+aXRlRWxlbWVudDpQLmhpLFNWR0ZFQ29udm9sdmVNYXRyaXhFbGVtZW50OlAuaGksU1ZHRkVEaWZmdXNl
+TGlnaHRpbmdFbGVtZW50OlAuaGksU1ZHRkVEaXNwbGFjZW1lbnRNYXBFbGVtZW50OlAuaGksU1ZHRkVE
+aXN0YW50TGlnaHRFbGVtZW50OlAuaGksU1ZHRkVGbG9vZEVsZW1lbnQ6UC5oaSxTVkdGRUZ1bmNBRWxl
+bWVudDpQLmhpLFNWR0ZFRnVuY0JFbGVtZW50OlAuaGksU1ZHRkVGdW5jR0VsZW1lbnQ6UC5oaSxTVkdG
+RUZ1bmNSRWxlbWVudDpQLmhpLFNWR0ZFR2F1c3NpYW5CbHVyRWxlbWVudDpQLmhpLFNWR0ZFSW1hZ2VF
+bGVtZW50OlAuaGksU1ZHRkVNZXJnZUVsZW1lbnQ6UC5oaSxTVkdGRU1lcmdlTm9kZUVsZW1lbnQ6UC5o
+aSxTVkdGRU1vcnBob2xvZ3lFbGVtZW50OlAuaGksU1ZHRkVPZmZzZXRFbGVtZW50OlAuaGksU1ZHRkVQ
+b2ludExpZ2h0RWxlbWVudDpQLmhpLFNWR0ZFU3BlY3VsYXJMaWdodGluZ0VsZW1lbnQ6UC5oaSxTVkdG
+RVNwb3RMaWdodEVsZW1lbnQ6UC5oaSxTVkdGRVRpbGVFbGVtZW50OlAuaGksU1ZHRkVUdXJidWxlbmNl
+RWxlbWVudDpQLmhpLFNWR0ZpbHRlckVsZW1lbnQ6UC5oaSxTVkdGb3JlaWduT2JqZWN0RWxlbWVudDpQ
+LmhpLFNWR0dFbGVtZW50OlAuaGksU1ZHR2VvbWV0cnlFbGVtZW50OlAuaGksU1ZHR3JhcGhpY3NFbGVt
+ZW50OlAuaGksU1ZHSW1hZ2VFbGVtZW50OlAuaGksU1ZHTGluZUVsZW1lbnQ6UC5oaSxTVkdMaW5lYXJH
+cmFkaWVudEVsZW1lbnQ6UC5oaSxTVkdNYXJrZXJFbGVtZW50OlAuaGksU1ZHTWFza0VsZW1lbnQ6UC5o
+aSxTVkdNZXRhZGF0YUVsZW1lbnQ6UC5oaSxTVkdQYXRoRWxlbWVudDpQLmhpLFNWR1BhdHRlcm5FbGVt
+ZW50OlAuaGksU1ZHUG9seWdvbkVsZW1lbnQ6UC5oaSxTVkdQb2x5bGluZUVsZW1lbnQ6UC5oaSxTVkdS
+YWRpYWxHcmFkaWVudEVsZW1lbnQ6UC5oaSxTVkdSZWN0RWxlbWVudDpQLmhpLFNWR1NldEVsZW1lbnQ6
+UC5oaSxTVkdTdG9wRWxlbWVudDpQLmhpLFNWR1N0eWxlRWxlbWVudDpQLmhpLFNWR1NWR0VsZW1lbnQ6
+UC5oaSxTVkdTd2l0Y2hFbGVtZW50OlAuaGksU1ZHU3ltYm9sRWxlbWVudDpQLmhpLFNWR1RTcGFuRWxl
+bWVudDpQLmhpLFNWR1RleHRDb250ZW50RWxlbWVudDpQLmhpLFNWR1RleHRFbGVtZW50OlAuaGksU1ZH
+VGV4dFBhdGhFbGVtZW50OlAuaGksU1ZHVGV4dFBvc2l0aW9uaW5nRWxlbWVudDpQLmhpLFNWR1RpdGxl
+RWxlbWVudDpQLmhpLFNWR1VzZUVsZW1lbnQ6UC5oaSxTVkdWaWV3RWxlbWVudDpQLmhpLFNWR0dyYWRp
+ZW50RWxlbWVudDpQLmhpLFNWR0NvbXBvbmVudFRyYW5zZmVyRnVuY3Rpb25FbGVtZW50OlAuaGksU1ZH
+RkVEcm9wU2hhZG93RWxlbWVudDpQLmhpLFNWR01QYXRoRWxlbWVudDpQLmhpLFNWR0VsZW1lbnQ6UC5o
+aX0pCmh1bmtIZWxwZXJzLnNldE9yVXBkYXRlTGVhZlRhZ3Moe0RPTUVycm9yOnRydWUsTWVkaWFFcnJv
+cjp0cnVlLE5hdmlnYXRvcjp0cnVlLE5hdmlnYXRvckNvbmN1cnJlbnRIYXJkd2FyZTp0cnVlLE5hdmln
+YXRvclVzZXJNZWRpYUVycm9yOnRydWUsT3ZlcmNvbnN0cmFpbmVkRXJyb3I6dHJ1ZSxQb3NpdGlvbkVy
+cm9yOnRydWUsUmFuZ2U6dHJ1ZSxTUUxFcnJvcjp0cnVlLERhdGFWaWV3OnRydWUsQXJyYXlCdWZmZXJW
+aWV3OmZhbHNlLEZsb2F0MzJBcnJheTp0cnVlLEZsb2F0NjRBcnJheTp0cnVlLEludDE2QXJyYXk6dHJ1
+ZSxJbnQzMkFycmF5OnRydWUsSW50OEFycmF5OnRydWUsVWludDE2QXJyYXk6dHJ1ZSxVaW50MzJBcnJh
+eTp0cnVlLFVpbnQ4Q2xhbXBlZEFycmF5OnRydWUsQ2FudmFzUGl4ZWxBcnJheTp0cnVlLFVpbnQ4QXJy
+YXk6ZmFsc2UsSFRNTEF1ZGlvRWxlbWVudDp0cnVlLEhUTUxCUkVsZW1lbnQ6dHJ1ZSxIVE1MQnV0dG9u
+RWxlbWVudDp0cnVlLEhUTUxDYW52YXNFbGVtZW50OnRydWUsSFRNTENvbnRlbnRFbGVtZW50OnRydWUs
+SFRNTERMaXN0RWxlbWVudDp0cnVlLEhUTUxEYXRhRWxlbWVudDp0cnVlLEhUTUxEYXRhTGlzdEVsZW1l
+bnQ6dHJ1ZSxIVE1MRGV0YWlsc0VsZW1lbnQ6dHJ1ZSxIVE1MRGlhbG9nRWxlbWVudDp0cnVlLEhUTUxE
+aXZFbGVtZW50OnRydWUsSFRNTEVtYmVkRWxlbWVudDp0cnVlLEhUTUxGaWVsZFNldEVsZW1lbnQ6dHJ1
+ZSxIVE1MSFJFbGVtZW50OnRydWUsSFRNTEhlYWRFbGVtZW50OnRydWUsSFRNTEhlYWRpbmdFbGVtZW50
+OnRydWUsSFRNTEh0bWxFbGVtZW50OnRydWUsSFRNTElGcmFtZUVsZW1lbnQ6dHJ1ZSxIVE1MSW1hZ2VF
+bGVtZW50OnRydWUsSFRNTElucHV0RWxlbWVudDp0cnVlLEhUTUxMSUVsZW1lbnQ6dHJ1ZSxIVE1MTGFi
+ZWxFbGVtZW50OnRydWUsSFRNTExlZ2VuZEVsZW1lbnQ6dHJ1ZSxIVE1MTGlua0VsZW1lbnQ6dHJ1ZSxI
+VE1MTWFwRWxlbWVudDp0cnVlLEhUTUxNZWRpYUVsZW1lbnQ6dHJ1ZSxIVE1MTWVudUVsZW1lbnQ6dHJ1
+ZSxIVE1MTWV0YUVsZW1lbnQ6dHJ1ZSxIVE1MTWV0ZXJFbGVtZW50OnRydWUsSFRNTE1vZEVsZW1lbnQ6
+dHJ1ZSxIVE1MT0xpc3RFbGVtZW50OnRydWUsSFRNTE9iamVjdEVsZW1lbnQ6dHJ1ZSxIVE1MT3B0R3Jv
+dXBFbGVtZW50OnRydWUsSFRNTE9wdGlvbkVsZW1lbnQ6dHJ1ZSxIVE1MT3V0cHV0RWxlbWVudDp0cnVl
+LEhUTUxQYXJhbUVsZW1lbnQ6dHJ1ZSxIVE1MUGljdHVyZUVsZW1lbnQ6dHJ1ZSxIVE1MUHJlRWxlbWVu
+dDp0cnVlLEhUTUxQcm9ncmVzc0VsZW1lbnQ6dHJ1ZSxIVE1MUXVvdGVFbGVtZW50OnRydWUsSFRNTFNj
+cmlwdEVsZW1lbnQ6dHJ1ZSxIVE1MU2hhZG93RWxlbWVudDp0cnVlLEhUTUxTbG90RWxlbWVudDp0cnVl
+LEhUTUxTb3VyY2VFbGVtZW50OnRydWUsSFRNTFNwYW5FbGVtZW50OnRydWUsSFRNTFN0eWxlRWxlbWVu
+dDp0cnVlLEhUTUxUYWJsZUNhcHRpb25FbGVtZW50OnRydWUsSFRNTFRhYmxlQ2VsbEVsZW1lbnQ6dHJ1
+ZSxIVE1MVGFibGVEYXRhQ2VsbEVsZW1lbnQ6dHJ1ZSxIVE1MVGFibGVIZWFkZXJDZWxsRWxlbWVudDp0
+cnVlLEhUTUxUYWJsZUNvbEVsZW1lbnQ6dHJ1ZSxIVE1MVGV4dEFyZWFFbGVtZW50OnRydWUsSFRNTFRp
+bWVFbGVtZW50OnRydWUsSFRNTFRpdGxlRWxlbWVudDp0cnVlLEhUTUxUcmFja0VsZW1lbnQ6dHJ1ZSxI
+VE1MVUxpc3RFbGVtZW50OnRydWUsSFRNTFVua25vd25FbGVtZW50OnRydWUsSFRNTFZpZGVvRWxlbWVu
+dDp0cnVlLEhUTUxEaXJlY3RvcnlFbGVtZW50OnRydWUsSFRNTEZvbnRFbGVtZW50OnRydWUsSFRNTEZy
+YW1lRWxlbWVudDp0cnVlLEhUTUxGcmFtZVNldEVsZW1lbnQ6dHJ1ZSxIVE1MTWFycXVlZUVsZW1lbnQ6
+dHJ1ZSxIVE1MRWxlbWVudDpmYWxzZSxIVE1MQW5jaG9yRWxlbWVudDp0cnVlLEhUTUxBcmVhRWxlbWVu
+dDp0cnVlLEhUTUxCYXNlRWxlbWVudDp0cnVlLEJsb2I6ZmFsc2UsSFRNTEJvZHlFbGVtZW50OnRydWUs
+Q0RBVEFTZWN0aW9uOnRydWUsQ2hhcmFjdGVyRGF0YTp0cnVlLENvbW1lbnQ6dHJ1ZSxQcm9jZXNzaW5n
+SW5zdHJ1Y3Rpb246dHJ1ZSxUZXh0OnRydWUsQ1NTU3R5bGVEZWNsYXJhdGlvbjp0cnVlLE1TU3R5bGVD
+U1NQcm9wZXJ0aWVzOnRydWUsQ1NTMlByb3BlcnRpZXM6dHJ1ZSxYTUxEb2N1bWVudDp0cnVlLERvY3Vt
+ZW50OmZhbHNlLERPTUV4Y2VwdGlvbjp0cnVlLERPTUltcGxlbWVudGF0aW9uOnRydWUsRE9NUmVjdFJl
+YWRPbmx5OmZhbHNlLERPTVRva2VuTGlzdDp0cnVlLEVsZW1lbnQ6ZmFsc2UsQWJvcnRQYXltZW50RXZl
+bnQ6dHJ1ZSxBbmltYXRpb25FdmVudDp0cnVlLEFuaW1hdGlvblBsYXliYWNrRXZlbnQ6dHJ1ZSxBcHBs
+aWNhdGlvbkNhY2hlRXJyb3JFdmVudDp0cnVlLEJhY2tncm91bmRGZXRjaENsaWNrRXZlbnQ6dHJ1ZSxC
+YWNrZ3JvdW5kRmV0Y2hFdmVudDp0cnVlLEJhY2tncm91bmRGZXRjaEZhaWxFdmVudDp0cnVlLEJhY2tn
+cm91bmRGZXRjaGVkRXZlbnQ6dHJ1ZSxCZWZvcmVJbnN0YWxsUHJvbXB0RXZlbnQ6dHJ1ZSxCZWZvcmVV
+bmxvYWRFdmVudDp0cnVlLEJsb2JFdmVudDp0cnVlLENhbk1ha2VQYXltZW50RXZlbnQ6dHJ1ZSxDbGlw
+Ym9hcmRFdmVudDp0cnVlLENsb3NlRXZlbnQ6dHJ1ZSxDdXN0b21FdmVudDp0cnVlLERldmljZU1vdGlv
+bkV2ZW50OnRydWUsRGV2aWNlT3JpZW50YXRpb25FdmVudDp0cnVlLEVycm9yRXZlbnQ6dHJ1ZSxFeHRl
+bmRhYmxlRXZlbnQ6dHJ1ZSxFeHRlbmRhYmxlTWVzc2FnZUV2ZW50OnRydWUsRmV0Y2hFdmVudDp0cnVl
+LEZvbnRGYWNlU2V0TG9hZEV2ZW50OnRydWUsRm9yZWlnbkZldGNoRXZlbnQ6dHJ1ZSxHYW1lcGFkRXZl
+bnQ6dHJ1ZSxIYXNoQ2hhbmdlRXZlbnQ6dHJ1ZSxJbnN0YWxsRXZlbnQ6dHJ1ZSxNZWRpYUVuY3J5cHRl
+ZEV2ZW50OnRydWUsTWVkaWFLZXlNZXNzYWdlRXZlbnQ6dHJ1ZSxNZWRpYVF1ZXJ5TGlzdEV2ZW50OnRy
+dWUsTWVkaWFTdHJlYW1FdmVudDp0cnVlLE1lZGlhU3RyZWFtVHJhY2tFdmVudDp0cnVlLE1lc3NhZ2VF
+dmVudDp0cnVlLE1JRElDb25uZWN0aW9uRXZlbnQ6dHJ1ZSxNSURJTWVzc2FnZUV2ZW50OnRydWUsTXV0
+YXRpb25FdmVudDp0cnVlLE5vdGlmaWNhdGlvbkV2ZW50OnRydWUsUGFnZVRyYW5zaXRpb25FdmVudDp0
+cnVlLFBheW1lbnRSZXF1ZXN0RXZlbnQ6dHJ1ZSxQYXltZW50UmVxdWVzdFVwZGF0ZUV2ZW50OnRydWUs
+UG9wU3RhdGVFdmVudDp0cnVlLFByZXNlbnRhdGlvbkNvbm5lY3Rpb25BdmFpbGFibGVFdmVudDp0cnVl
+LFByZXNlbnRhdGlvbkNvbm5lY3Rpb25DbG9zZUV2ZW50OnRydWUsUHJvbWlzZVJlamVjdGlvbkV2ZW50
+OnRydWUsUHVzaEV2ZW50OnRydWUsUlRDRGF0YUNoYW5uZWxFdmVudDp0cnVlLFJUQ0RUTUZUb25lQ2hh
+bmdlRXZlbnQ6dHJ1ZSxSVENQZWVyQ29ubmVjdGlvbkljZUV2ZW50OnRydWUsUlRDVHJhY2tFdmVudDp0
+cnVlLFNlY3VyaXR5UG9saWN5VmlvbGF0aW9uRXZlbnQ6dHJ1ZSxTZW5zb3JFcnJvckV2ZW50OnRydWUs
+U3BlZWNoUmVjb2duaXRpb25FcnJvcjp0cnVlLFNwZWVjaFJlY29nbml0aW9uRXZlbnQ6dHJ1ZSxTcGVl
+Y2hTeW50aGVzaXNFdmVudDp0cnVlLFN0b3JhZ2VFdmVudDp0cnVlLFN5bmNFdmVudDp0cnVlLFRyYWNr
+RXZlbnQ6dHJ1ZSxUcmFuc2l0aW9uRXZlbnQ6dHJ1ZSxXZWJLaXRUcmFuc2l0aW9uRXZlbnQ6dHJ1ZSxW
+UkRldmljZUV2ZW50OnRydWUsVlJEaXNwbGF5RXZlbnQ6dHJ1ZSxWUlNlc3Npb25FdmVudDp0cnVlLE1v
+am9JbnRlcmZhY2VSZXF1ZXN0RXZlbnQ6dHJ1ZSxVU0JDb25uZWN0aW9uRXZlbnQ6dHJ1ZSxJREJWZXJz
+aW9uQ2hhbmdlRXZlbnQ6dHJ1ZSxBdWRpb1Byb2Nlc3NpbmdFdmVudDp0cnVlLE9mZmxpbmVBdWRpb0Nv
+bXBsZXRpb25FdmVudDp0cnVlLFdlYkdMQ29udGV4dEV2ZW50OnRydWUsRXZlbnQ6ZmFsc2UsSW5wdXRF
+dmVudDpmYWxzZSxTdWJtaXRFdmVudDpmYWxzZSxFdmVudFRhcmdldDpmYWxzZSxGaWxlOnRydWUsSFRN
+TEZvcm1FbGVtZW50OnRydWUsSGlzdG9yeTp0cnVlLEhUTUxEb2N1bWVudDp0cnVlLFhNTEh0dHBSZXF1
+ZXN0OnRydWUsWE1MSHR0cFJlcXVlc3RFdmVudFRhcmdldDpmYWxzZSxJbWFnZURhdGE6dHJ1ZSxMb2Nh
+dGlvbjp0cnVlLE1vdXNlRXZlbnQ6dHJ1ZSxEcmFnRXZlbnQ6dHJ1ZSxQb2ludGVyRXZlbnQ6dHJ1ZSxX
+aGVlbEV2ZW50OnRydWUsRG9jdW1lbnRGcmFnbWVudDp0cnVlLFNoYWRvd1Jvb3Q6dHJ1ZSxEb2N1bWVu
+dFR5cGU6dHJ1ZSxOb2RlOmZhbHNlLE5vZGVMaXN0OnRydWUsUmFkaW9Ob2RlTGlzdDp0cnVlLEhUTUxQ
+YXJhZ3JhcGhFbGVtZW50OnRydWUsUHJvZ3Jlc3NFdmVudDp0cnVlLFJlc291cmNlUHJvZ3Jlc3NFdmVu
+dDp0cnVlLEhUTUxTZWxlY3RFbGVtZW50OnRydWUsSFRNTFRhYmxlRWxlbWVudDp0cnVlLEhUTUxUYWJs
+ZVJvd0VsZW1lbnQ6dHJ1ZSxIVE1MVGFibGVTZWN0aW9uRWxlbWVudDp0cnVlLEhUTUxUZW1wbGF0ZUVs
+ZW1lbnQ6dHJ1ZSxDb21wb3NpdGlvbkV2ZW50OnRydWUsRm9jdXNFdmVudDp0cnVlLEtleWJvYXJkRXZl
+bnQ6dHJ1ZSxUZXh0RXZlbnQ6dHJ1ZSxUb3VjaEV2ZW50OnRydWUsVUlFdmVudDpmYWxzZSxXaW5kb3c6
+dHJ1ZSxET01XaW5kb3c6dHJ1ZSxEZWRpY2F0ZWRXb3JrZXJHbG9iYWxTY29wZTp0cnVlLFNlcnZpY2VX
+b3JrZXJHbG9iYWxTY29wZTp0cnVlLFNoYXJlZFdvcmtlckdsb2JhbFNjb3BlOnRydWUsV29ya2VyR2xv
+YmFsU2NvcGU6dHJ1ZSxBdHRyOnRydWUsQ2xpZW50UmVjdDp0cnVlLERPTVJlY3Q6dHJ1ZSxOYW1lZE5v
+ZGVNYXA6dHJ1ZSxNb3pOYW1lZEF0dHJNYXA6dHJ1ZSxJREJLZXlSYW5nZTp0cnVlLFNWR1NjcmlwdEVs
+ZW1lbnQ6dHJ1ZSxTVkdBRWxlbWVudDp0cnVlLFNWR0FuaW1hdGVFbGVtZW50OnRydWUsU1ZHQW5pbWF0
+ZU1vdGlvbkVsZW1lbnQ6dHJ1ZSxTVkdBbmltYXRlVHJhbnNmb3JtRWxlbWVudDp0cnVlLFNWR0FuaW1h
+dGlvbkVsZW1lbnQ6dHJ1ZSxTVkdDaXJjbGVFbGVtZW50OnRydWUsU1ZHQ2xpcFBhdGhFbGVtZW50OnRy
+dWUsU1ZHRGVmc0VsZW1lbnQ6dHJ1ZSxTVkdEZXNjRWxlbWVudDp0cnVlLFNWR0Rpc2NhcmRFbGVtZW50
+OnRydWUsU1ZHRWxsaXBzZUVsZW1lbnQ6dHJ1ZSxTVkdGRUJsZW5kRWxlbWVudDp0cnVlLFNWR0ZFQ29s
+b3JNYXRyaXhFbGVtZW50OnRydWUsU1ZHRkVDb21wb25lbnRUcmFuc2ZlckVsZW1lbnQ6dHJ1ZSxTVkdG
+RUNvbXBvc2l0ZUVsZW1lbnQ6dHJ1ZSxTVkdGRUNvbnZvbHZlTWF0cml4RWxlbWVudDp0cnVlLFNWR0ZF
+RGlmZnVzZUxpZ2h0aW5nRWxlbWVudDp0cnVlLFNWR0ZFRGlzcGxhY2VtZW50TWFwRWxlbWVudDp0cnVl
+LFNWR0ZFRGlzdGFudExpZ2h0RWxlbWVudDp0cnVlLFNWR0ZFRmxvb2RFbGVtZW50OnRydWUsU1ZHRkVG
+dW5jQUVsZW1lbnQ6dHJ1ZSxTVkdGRUZ1bmNCRWxlbWVudDp0cnVlLFNWR0ZFRnVuY0dFbGVtZW50OnRy
+dWUsU1ZHRkVGdW5jUkVsZW1lbnQ6dHJ1ZSxTVkdGRUdhdXNzaWFuQmx1ckVsZW1lbnQ6dHJ1ZSxTVkdG
+RUltYWdlRWxlbWVudDp0cnVlLFNWR0ZFTWVyZ2VFbGVtZW50OnRydWUsU1ZHRkVNZXJnZU5vZGVFbGVt
+ZW50OnRydWUsU1ZHRkVNb3JwaG9sb2d5RWxlbWVudDp0cnVlLFNWR0ZFT2Zmc2V0RWxlbWVudDp0cnVl
+LFNWR0ZFUG9pbnRMaWdodEVsZW1lbnQ6dHJ1ZSxTVkdGRVNwZWN1bGFyTGlnaHRpbmdFbGVtZW50OnRy
+dWUsU1ZHRkVTcG90TGlnaHRFbGVtZW50OnRydWUsU1ZHRkVUaWxlRWxlbWVudDp0cnVlLFNWR0ZFVHVy
+YnVsZW5jZUVsZW1lbnQ6dHJ1ZSxTVkdGaWx0ZXJFbGVtZW50OnRydWUsU1ZHRm9yZWlnbk9iamVjdEVs
+ZW1lbnQ6dHJ1ZSxTVkdHRWxlbWVudDp0cnVlLFNWR0dlb21ldHJ5RWxlbWVudDp0cnVlLFNWR0dyYXBo
+aWNzRWxlbWVudDp0cnVlLFNWR0ltYWdlRWxlbWVudDp0cnVlLFNWR0xpbmVFbGVtZW50OnRydWUsU1ZH
+TGluZWFyR3JhZGllbnRFbGVtZW50OnRydWUsU1ZHTWFya2VyRWxlbWVudDp0cnVlLFNWR01hc2tFbGVt
+ZW50OnRydWUsU1ZHTWV0YWRhdGFFbGVtZW50OnRydWUsU1ZHUGF0aEVsZW1lbnQ6dHJ1ZSxTVkdQYXR0
+ZXJuRWxlbWVudDp0cnVlLFNWR1BvbHlnb25FbGVtZW50OnRydWUsU1ZHUG9seWxpbmVFbGVtZW50OnRy
+dWUsU1ZHUmFkaWFsR3JhZGllbnRFbGVtZW50OnRydWUsU1ZHUmVjdEVsZW1lbnQ6dHJ1ZSxTVkdTZXRF
+bGVtZW50OnRydWUsU1ZHU3RvcEVsZW1lbnQ6dHJ1ZSxTVkdTdHlsZUVsZW1lbnQ6dHJ1ZSxTVkdTVkdF
+bGVtZW50OnRydWUsU1ZHU3dpdGNoRWxlbWVudDp0cnVlLFNWR1N5bWJvbEVsZW1lbnQ6dHJ1ZSxTVkdU
+U3BhbkVsZW1lbnQ6dHJ1ZSxTVkdUZXh0Q29udGVudEVsZW1lbnQ6dHJ1ZSxTVkdUZXh0RWxlbWVudDp0
+cnVlLFNWR1RleHRQYXRoRWxlbWVudDp0cnVlLFNWR1RleHRQb3NpdGlvbmluZ0VsZW1lbnQ6dHJ1ZSxT
+VkdUaXRsZUVsZW1lbnQ6dHJ1ZSxTVkdVc2VFbGVtZW50OnRydWUsU1ZHVmlld0VsZW1lbnQ6dHJ1ZSxT
+VkdHcmFkaWVudEVsZW1lbnQ6dHJ1ZSxTVkdDb21wb25lbnRUcmFuc2ZlckZ1bmN0aW9uRWxlbWVudDp0
+cnVlLFNWR0ZFRHJvcFNoYWRvd0VsZW1lbnQ6dHJ1ZSxTVkdNUGF0aEVsZW1lbnQ6dHJ1ZSxTVkdFbGVt
+ZW50OmZhbHNlfSkKSC5MWi4kbmF0aXZlU3VwZXJjbGFzc1RhZz0iQXJyYXlCdWZmZXJWaWV3IgpILlJH
+LiRuYXRpdmVTdXBlcmNsYXNzVGFnPSJBcnJheUJ1ZmZlclZpZXciCkguVlAuJG5hdGl2ZVN1cGVyY2xh
+c3NUYWc9IkFycmF5QnVmZmVyVmlldyIKSC5EZy4kbmF0aXZlU3VwZXJjbGFzc1RhZz0iQXJyYXlCdWZm
+ZXJWaWV3IgpILldCLiRuYXRpdmVTdXBlcmNsYXNzVGFnPSJBcnJheUJ1ZmZlclZpZXciCkguWkcuJG5h
+dGl2ZVN1cGVyY2xhc3NUYWc9IkFycmF5QnVmZmVyVmlldyIKSC5QZy4kbmF0aXZlU3VwZXJjbGFzc1Rh
+Zz0iQXJyYXlCdWZmZXJWaWV3In0pKCkKY29udmVydEFsbFRvRmFzdE9iamVjdCh3KQpjb252ZXJ0VG9G
+YXN0T2JqZWN0KCQpOyhmdW5jdGlvbihhKXtpZih0eXBlb2YgZG9jdW1lbnQ9PT0idW5kZWZpbmVkIil7
+YShudWxsKQpyZXR1cm59aWYodHlwZW9mIGRvY3VtZW50LmN1cnJlbnRTY3JpcHQhPSd1bmRlZmluZWQn
+KXthKGRvY3VtZW50LmN1cnJlbnRTY3JpcHQpCnJldHVybn12YXIgcz1kb2N1bWVudC5zY3JpcHRzCmZ1
+bmN0aW9uIG9uTG9hZChiKXtmb3IodmFyIHE9MDtxPHMubGVuZ3RoOysrcSlzW3FdLnJlbW92ZUV2ZW50
+TGlzdGVuZXIoImxvYWQiLG9uTG9hZCxmYWxzZSkKYShiLnRhcmdldCl9Zm9yKHZhciByPTA7cjxzLmxl
+bmd0aDsrK3Ipc1tyXS5hZGRFdmVudExpc3RlbmVyKCJsb2FkIixvbkxvYWQsZmFsc2UpfSkoZnVuY3Rp
+b24oYSl7di5jdXJyZW50U2NyaXB0PWEKaWYodHlwZW9mIGRhcnRNYWluUnVubmVyPT09ImZ1bmN0aW9u
+IilkYXJ0TWFpblJ1bm5lcihMLklxLFtdKQplbHNlIEwuSXEoW10pfSl9KSgpCi8vIyBzb3VyY2VNYXBw
+aW5nVVJMPW1pZ3JhdGlvbi5qcy5tYXAK
 ''';
diff --git a/pkg/nnbd_migration/lib/src/front_end/web/migration.dart b/pkg/nnbd_migration/lib/src/front_end/web/migration.dart
index 6d5f98b..e98bbea 100644
--- a/pkg/nnbd_migration/lib/src/front_end/web/migration.dart
+++ b/pkg/nnbd_migration/lib/src/front_end/web/migration.dart
@@ -72,6 +72,20 @@
 
     document.querySelector('.popup-pane .close').onClick.listen(
         (_) => document.querySelector('.popup-pane').style.display = 'none');
+
+    migrateUnitStatusIcon.onClick.listen((MouseEvent event) {
+      var unitPath = unitName.innerText;
+      var unitNavItem = document
+          .querySelector('.nav-panel [data-name*="$unitPath"]')
+          .parentNode as Element;
+      var statusIcon = unitNavItem.querySelector('.status-icon');
+      var entity = navigationTree.find(unitPath);
+      if (entity is NavigationTreeFileNode) {
+        toggleFileMigrationStatus(entity);
+        updateIconsForNode(statusIcon, entity);
+        updateParentIcons(unitNavItem, entity);
+      }
+    });
   });
 
   window.addEventListener('popstate', (event) {
@@ -109,10 +123,18 @@
 
 final Element unitName = document.querySelector('#unit-name');
 
+final Element migrateUnitStatusIconLabel =
+    document.querySelector('#migrate-unit-status-icon-label');
+
+final Element migrateUnitStatusIcon =
+    document.querySelector('#migrate-unit-status-icon');
+
 String get rootPath => querySelector('.root').text.trim();
 
 String get sdkVersion => document.getElementById('sdk-version').text;
 
+/*late final*/ List<NavigationTreeNode> navigationTree;
+
 void addArrowClickHandler(Element arrow) {
   var childList = (arrow.parentNode as Element).querySelector(':scope > ul');
   // Animating height from "auto" to "0" is not supported by CSS [1], so all we
@@ -430,7 +452,8 @@
     final response = await doGet<List<Object>>(path);
     var navTree = document.querySelector('.nav-tree');
     navTree.innerHtml = '';
-    writeNavigationSubtree(navTree, NavigationTreeNode.listFromJson(response),
+    navigationTree = NavigationTreeNode.listFromJson(response);
+    writeNavigationSubtree(navTree, navigationTree,
         enablePartialMigration: false);
   } catch (e, st) {
     handleError('Could not load navigation tree', e, st);
@@ -707,6 +730,19 @@
   }
 }
 
+/// Updates the navigation [icon] and current file icon according to the current
+/// migration status of [entity].
+void updateIconsForNode(Element icon, NavigationTreeNode entity) {
+  updateIconForStatus(icon, entity.migrationStatus);
+  // Update the status at the top of the file view if [entity] represents the
+  // current file.
+  var unitPath = unitName.innerText;
+  if (entity.path == unitPath) {
+    updateIconForStatus(migrateUnitStatusIcon, entity.migrationStatus);
+  }
+}
+
+/// Updates [icon] according to [status].
 void updateIconForStatus(Element icon, UnitMigrationStatus status) {
   switch (status) {
     case UnitMigrationStatus.alreadyMigrated:
@@ -753,6 +789,7 @@
       link.classes.remove('selected-file');
     }
   });
+  migrateUnitStatusIconLabel.classes.add('visible');
 }
 
 /// Updates the parent icons of [entity] with list item [element] in the
@@ -762,7 +799,7 @@
   if (parent != null) {
     var parentElement = (element.parentNode as Element).parentNode as Element;
     var statusIcon = parentElement.querySelector(':scope > .status-icon');
-    updateIconForStatus(statusIcon, parent.migrationStatus);
+    updateIconsForNode(statusIcon, parent);
     updateParentIcons(parentElement, parent);
   }
 }
@@ -774,11 +811,11 @@
     if (child is NavigationTreeDirectoryNode) {
       updateSubtreeIcons(childNode, child);
       var childIcon = childNode.querySelector(':scope > .status-icon');
-      updateIconForStatus(childIcon, entity.migrationStatus);
+      updateIconsForNode(childIcon, entity);
     } else {
       var childIcon = (childNode.parentNode as Element)
           .querySelector(':scope > .status-icon');
-      updateIconForStatus(childIcon, child.migrationStatus);
+      updateIconsForNode(childIcon, child);
     }
   }
 }
@@ -824,11 +861,11 @@
       if (enablePartialMigration) {
         var statusIcon = createIcon('indeterminate_check_box')
           ..classes.add('status-icon');
-        updateIconForStatus(statusIcon, entity.migrationStatus);
+        updateIconsForNode(statusIcon, entity);
         statusIcon.onClick.listen((MouseEvent event) {
           toggleDirectoryMigrationStatus(entity);
           updateSubtreeIcons(li, entity);
-          updateIconForStatus(statusIcon, entity.migrationStatus);
+          updateIconsForNode(statusIcon, entity);
           updateParentIcons(li, entity);
         });
         li.insertBefore(statusIcon, folderIcon);
@@ -837,10 +874,10 @@
     } else if (entity is NavigationTreeFileNode) {
       if (enablePartialMigration) {
         var statusIcon = createIcon()..classes.add('status-icon');
-        updateIconForStatus(statusIcon, entity.migrationStatus);
+        updateIconsForNode(statusIcon, entity);
         statusIcon.onClick.listen((MouseEvent event) {
           toggleFileMigrationStatus(entity);
-          updateIconForStatus(statusIcon, entity.migrationStatus);
+          updateIconsForNode(statusIcon, entity);
           updateParentIcons(li, entity);
         });
         li.append(statusIcon);
@@ -991,3 +1028,19 @@
     }
   }
 }
+
+extension on List<NavigationTreeNode> {
+  /// Finds the node with path equal to [path], recursively, or `null`.
+  NavigationTreeNode find(String path) {
+    for (var node in this) {
+      if (node is NavigationTreeDirectoryNode) {
+        var foundInSubtree = node.subtree.find(path);
+        if (foundInSubtree != null) return foundInSubtree;
+      } else {
+        assert(node is NavigationTreeFileNode);
+        if (node.path == path) return node;
+      }
+    }
+    return null;
+  }
+}
diff --git a/pkg/nnbd_migration/test/api_test.dart b/pkg/nnbd_migration/test/api_test.dart
index f36f2b2..8e1285fa 100644
--- a/pkg/nnbd_migration/test/api_test.dart
+++ b/pkg/nnbd_migration/test/api_test.dart
@@ -4678,6 +4678,54 @@
     await _checkSingleFileChanges(content, expected);
   }
 
+  Future<void> test_loop_var_is_field() async {
+    var content = '''
+class C {
+  int x;
+  C(this.x);
+  f(List<int/*?*/> y) {
+    for (x in y) {}
+  }
+}
+''';
+    var expected = '''
+class C {
+  int? x;
+  C(this.x);
+  f(List<int?> y) {
+    for (x in y) {}
+  }
+}
+''';
+    await _checkSingleFileChanges(content, expected);
+  }
+
+  Future<void> test_loop_var_is_inherited_field_with_substitution() async {
+    var content = '''
+class B<T> {
+  T x;
+  B(this.x);
+}
+abstract class C implements B<int> {
+  f(List<int/*?*/> y) {
+    for (x in y) {}
+  }
+}
+''';
+    var expected = '''
+class B<T> {
+  T x;
+  B(this.x);
+}
+abstract class C implements B<int?> {
+  f(List<int?> y) {
+    for (x in y) {}
+  }
+}
+''';
+    await _checkSingleFileChanges(content, expected);
+  }
+
   Future<void> test_make_downcast_explicit() async {
     var content = 'int f(num n) => n;';
     var expected = 'int f(num n) => n as int;';
diff --git a/runtime/bin/security_context_macos.cc b/runtime/bin/security_context_macos.cc
index c934fc5..927e139 100644
--- a/runtime/bin/security_context_macos.cc
+++ b/runtime/bin/security_context_macos.cc
@@ -106,6 +106,8 @@
                                                            uint8_t* out_alert) {
   SSLFilter* filter = static_cast<SSLFilter*>(
       SSL_get_ex_data(ssl, SSLFilter::filter_ssl_index));
+  SSLCertContext* context = static_cast<SSLCertContext*>(
+      SSL_get_ex_data(ssl, SSLFilter::ssl_cert_context_index));
 
   const X509TrustState* certificate_trust_state =
       filter->certificate_trust_state();
@@ -125,9 +127,90 @@
     }
   }
 
-  Dart_CObject dart_cobject_ssl;
-  dart_cobject_ssl.type = Dart_CObject_kInt64;
-  dart_cobject_ssl.value.as_int64 = reinterpret_cast<intptr_t>(ssl);
+  STACK_OF(X509)* unverified = sk_X509_dup(SSL_get_peer_full_cert_chain(ssl));
+
+  // Convert BoringSSL formatted certificates to SecCertificate certificates.
+  ScopedCFMutableArrayRef cert_chain(NULL);
+  X509* root_cert = NULL;
+  int num_certs = sk_X509_num(unverified);
+  int current_cert = 0;
+  cert_chain.set(CFArrayCreateMutable(NULL, num_certs, NULL));
+  X509* ca;
+  while ((ca = sk_X509_shift(unverified)) != NULL) {
+    ScopedSecCertificateRef cert(CreateSecCertificateFromX509(ca));
+    if (cert == NULL) {
+      return ssl_verify_invalid;
+    }
+    CFArrayAppendValue(cert_chain.get(), cert.release());
+    ++current_cert;
+
+    if (current_cert == num_certs) {
+      root_cert = ca;
+    }
+  }
+
+  SSL_CTX* ssl_ctx = SSL_get_SSL_CTX(ssl);
+  X509_STORE* store = SSL_CTX_get_cert_store(ssl_ctx);
+  // Convert all trusted certificates provided by the user via
+  // setTrustedCertificatesBytes or the command line into SecCertificates.
+  ScopedCFMutableArrayRef trusted_certs(CFArrayCreateMutable(NULL, 0, NULL));
+  ASSERT(store != NULL);
+
+  if (store->objs != NULL) {
+    for (uintptr_t i = 0; i < sk_X509_OBJECT_num(store->objs); ++i) {
+      X509* ca = sk_X509_OBJECT_value(store->objs, i)->data.x509;
+      ScopedSecCertificateRef cert(CreateSecCertificateFromX509(ca));
+      if (cert == NULL) {
+        return ssl_verify_invalid;
+      }
+      CFArrayAppendValue(trusted_certs.get(), cert.release());
+    }
+  }
+
+  // Generate a policy for validating chains for SSL.
+  CFStringRef cfhostname = NULL;
+  if (filter->hostname() != NULL) {
+    cfhostname = CFStringCreateWithCString(NULL, filter->hostname(),
+                                           kCFStringEncodingUTF8);
+  }
+  ScopedCFStringRef hostname(cfhostname);
+  ScopedSecPolicyRef policy(
+      SecPolicyCreateSSL(filter->is_client(), hostname.get()));
+
+  // Create the trust object with the certificates provided by the user.
+  ScopedSecTrustRef trust(NULL);
+  OSStatus status = SecTrustCreateWithCertificates(cert_chain.get(),
+                                                   policy.get(), trust.ptr());
+  if (status != noErr) {
+    return ssl_verify_invalid;
+  }
+
+  // If the user provided any additional CA certificates, add them to the trust
+  // object.
+  if (CFArrayGetCount(trusted_certs.get()) > 0) {
+    status = SecTrustSetAnchorCertificates(trust.get(), trusted_certs.get());
+    if (status != noErr) {
+      return ssl_verify_invalid;
+    }
+  }
+
+  // Specify whether or not to use the built-in CA certificates for
+  // verification.
+  status =
+      SecTrustSetAnchorCertificatesOnly(trust.get(), !context->trust_builtin());
+  if (status != noErr) {
+    return ssl_verify_invalid;
+  }
+
+  // Handler should release trust and root_cert.
+  Dart_CObject dart_cobject_trust;
+  dart_cobject_trust.type = Dart_CObject_kInt64;
+  dart_cobject_trust.value.as_int64 =
+      reinterpret_cast<intptr_t>(CFRetain(trust.get()));
+
+  Dart_CObject dart_cobject_root_cert;
+  dart_cobject_root_cert.type = Dart_CObject_kInt64;
+  dart_cobject_root_cert.value.as_int64 = reinterpret_cast<intptr_t>(root_cert);
 
   Dart_CObject reply_send_port;
   reply_send_port.type = Dart_CObject_kSendPort;
@@ -135,8 +218,9 @@
 
   Dart_CObject array;
   array.type = Dart_CObject_kArray;
-  array.value.as_array.length = 2;
-  Dart_CObject* values[] = {&dart_cobject_ssl, &reply_send_port};
+  array.value.as_array.length = 3;
+  Dart_CObject* values[] = {&dart_cobject_trust, &dart_cobject_root_cert,
+                            &reply_send_port};
   array.value.as_array.values = values;
 
   Dart_PostCObject(filter->trust_evaluate_reply_port(), &array);
@@ -166,104 +250,28 @@
 
 static void TrustEvaluateHandler(Dart_Port dest_port_id,
                                  Dart_CObject* message) {
-  CObjectArray request(message);
-  ASSERT(request.Length() == 2);
-
-  CObjectIntptr ssl_cobject(request[0]);
-  SSL* ssl = reinterpret_cast<SSL*>(ssl_cobject.Value());
-  SSLFilter* filter = static_cast<SSLFilter*>(
-      SSL_get_ex_data(ssl, SSLFilter::filter_ssl_index));
-  SSLCertContext* context = static_cast<SSLCertContext*>(
-      SSL_get_ex_data(ssl, SSLFilter::ssl_cert_context_index));
-  CObjectSendPort reply_port(request[1]);
-  Dart_Port reply_port_id = reply_port.Value();
-
-  STACK_OF(X509)* unverified = sk_X509_dup(SSL_get_peer_full_cert_chain(ssl));
-
-  // Convert BoringSSL formatted certificates to SecCertificate certificates.
-  ScopedCFMutableArrayRef cert_chain(NULL);
-  X509* root_cert = NULL;
-  int num_certs = sk_X509_num(unverified);
-  int current_cert = 0;
-  cert_chain.set(CFArrayCreateMutable(NULL, num_certs, NULL));
-  X509* ca;
-  while ((ca = sk_X509_shift(unverified)) != NULL) {
-    ScopedSecCertificateRef cert(CreateSecCertificateFromX509(ca));
-    if (cert == NULL) {
-      postReply(reply_port_id, /*success=*/false);
-      return;
-    }
-    CFArrayAppendValue(cert_chain.get(), cert.release());
-    ++current_cert;
-
-    if (current_cert == num_certs) {
-      root_cert = ca;
-    }
-  }
-
-  SSL_CTX* ssl_ctx = SSL_get_SSL_CTX(ssl);
-  X509_STORE* store = SSL_CTX_get_cert_store(ssl_ctx);
-  // Convert all trusted certificates provided by the user via
-  // setTrustedCertificatesBytes or the command line into SecCertificates.
-  ScopedCFMutableArrayRef trusted_certs(CFArrayCreateMutable(NULL, 0, NULL));
-  ASSERT(store != NULL);
-
-  if (store->objs != NULL) {
-    for (uintptr_t i = 0; i < sk_X509_OBJECT_num(store->objs); ++i) {
-      X509* ca = sk_X509_OBJECT_value(store->objs, i)->data.x509;
-      ScopedSecCertificateRef cert(CreateSecCertificateFromX509(ca));
-      if (cert == NULL) {
-        postReply(reply_port_id, /*success=*/false);
-        return;
-      }
-      CFArrayAppendValue(trusted_certs.get(), cert.release());
-    }
-  }
-
-  // Generate a policy for validating chains for SSL.
-  CFStringRef cfhostname = NULL;
-  if (filter->hostname() != NULL) {
-    cfhostname = CFStringCreateWithCString(NULL, filter->hostname(),
-                                           kCFStringEncodingUTF8);
-  }
-  ScopedCFStringRef hostname(cfhostname);
-  ScopedSecPolicyRef policy(
-      SecPolicyCreateSSL(filter->is_client(), hostname.get()));
-
-  // Create the trust object with the certificates provided by the user.
-  ScopedSecTrustRef trust(NULL);
-  OSStatus status = SecTrustCreateWithCertificates(cert_chain.get(),
-                                                   policy.get(), trust.ptr());
-  if (status != noErr) {
-    postReply(reply_port_id, /*success=*/false);
-    return;
-  }
-
-  // If the user provided any additional CA certificates, add them to the trust
-  // object.
-  if (CFArrayGetCount(trusted_certs.get()) > 0) {
-    status = SecTrustSetAnchorCertificates(trust.get(), trusted_certs.get());
-    if (status != noErr) {
-      postReply(reply_port_id, /*success=*/false);
-      return;
-    }
-  }
-
-  // Specify whether or not to use the built-in CA certificates for
-  // verification.
-  status =
-      SecTrustSetAnchorCertificatesOnly(trust.get(), !context->trust_builtin());
-  if (status != noErr) {
-    postReply(reply_port_id, /*success=*/false);
-    return;
-  }
-
-  SecTrustResultType trust_result;
-
   // This is used for testing to confirm that trust evaluation doesn't block
   // dart isolate.
+  // First sleep exposes problem where ssl data structures are released/freed
+  // by main isolate before this handler had a chance to access them.
+  // Second sleep(below) is there to maintain same long delay of certificate
+  // verification.
   if (SSLCertContext::long_ssl_cert_evaluation()) {
-    usleep(1000 * 1000 /*1 s*/);
+    usleep(2000 * 1000 /* 2 s*/);
+  }
+
+  CObjectArray request(message);
+  ASSERT(request.Length() == 3);
+  CObjectIntptr trust_cobject(request[0]);
+  ScopedSecTrustRef trust(reinterpret_cast<SecTrustRef>(trust_cobject.Value()));
+  CObjectIntptr root_cert_cobject(request[1]);
+  X509* root_cert = reinterpret_cast<X509*>(root_cert_cobject.Value());
+  CObjectSendPort reply_port(request[2]);
+  Dart_Port reply_port_id = reply_port.Value();
+
+  SecTrustResultType trust_result;
+  if (SSLCertContext::long_ssl_cert_evaluation()) {
+    usleep(3000 * 1000 /* 3 s*/);
   }
 
   // Perform the certificate verification.
@@ -277,11 +285,11 @@
   // from calling SecTrustEvaluate.
   bool res = SecTrustEvaluateWithError(trust.get(), NULL);
   USE(res);
-  status = SecTrustGetTrustResult(trust.get(), &trust_result);
+  OSStatus status = SecTrustGetTrustResult(trust.get(), &trust_result);
 #else
 
   // SecTrustEvaluate is deprecated as of OSX 10.15 and iOS 13.
-  status = SecTrustEvaluate(trust.get(), &trust_result);
+  OSStatus status = SecTrustEvaluate(trust.get(), &trust_result);
 #endif
 
   postReply(reply_port_id,
diff --git a/runtime/vm/compiler/backend/il.cc b/runtime/vm/compiler/backend/il.cc
index bd8e8b7..9fdefe6 100644
--- a/runtime/vm/compiler/backend/il.cc
+++ b/runtime/vm/compiler/backend/il.cc
@@ -820,23 +820,26 @@
     const Array& descriptor =
         Array::Handle(zone, ic_data.arguments_descriptor());
     Thread* thread = Thread::Current();
-    const MegamorphicCache& cache = MegamorphicCache::Handle(
+
+    const auto& cache = MegamorphicCache::Handle(
         zone, MegamorphicCacheTable::Lookup(thread, name, descriptor));
-    SafepointMutexLocker ml(thread->isolate()->megamorphic_mutex());
-    MegamorphicCacheEntries entries(Array::Handle(zone, cache.buckets()));
-    for (intptr_t i = 0, n = entries.Length(); i < n; i++) {
-      const intptr_t id =
-          Smi::Value(entries[i].Get<MegamorphicCache::kClassIdIndex>());
-      if (id == kIllegalCid) {
-        continue;
+    {
+      SafepointMutexLocker ml(thread->isolate()->type_feedback_mutex());
+      MegamorphicCacheEntries entries(Array::Handle(zone, cache.buckets()));
+      for (intptr_t i = 0, n = entries.Length(); i < n; i++) {
+        const intptr_t id =
+            Smi::Value(entries[i].Get<MegamorphicCache::kClassIdIndex>());
+        if (id == kIllegalCid) {
+          continue;
+        }
+        Function& function = Function::ZoneHandle(zone);
+        function ^= entries[i].Get<MegamorphicCache::kTargetFunctionIndex>();
+        const intptr_t filled_entry_count = cache.filled_entry_count();
+        ASSERT(filled_entry_count > 0);
+        cid_ranges_.Add(new (zone) TargetInfo(
+            id, id, &function, Usage(function) / filled_entry_count,
+            StaticTypeExactnessState::NotTracking()));
       }
-      Function& function = Function::ZoneHandle(zone);
-      function ^= entries[i].Get<MegamorphicCache::kTargetFunctionIndex>();
-      const intptr_t filled_entry_count = cache.filled_entry_count();
-      ASSERT(filled_entry_count > 0);
-      cid_ranges_.Add(new (zone) TargetInfo(
-          id, id, &function, Usage(function) / filled_entry_count,
-          StaticTypeExactnessState::NotTracking()));
     }
   }
 }
diff --git a/runtime/vm/isolate.cc b/runtime/vm/isolate.cc
index 2fe5ead..3849287 100644
--- a/runtime/vm/isolate.cc
+++ b/runtime/vm/isolate.cc
@@ -359,6 +359,8 @@
           NOT_IN_PRODUCT("IsolateGroup::type_canonicalization_mutex_")),
       type_arguments_canonicalization_mutex_(NOT_IN_PRODUCT(
           "IsolateGroup::type_arguments_canonicalization_mutex_")),
+      subtype_test_cache_mutex_(
+          NOT_IN_PRODUCT("IsolateGroup::subtype_test_cache_mutex_")),
       program_lock_(new SafepointRwLock()),
       active_mutators_monitor_(new Monitor()),
       max_active_mutators_(Scavenger::MaxMutatorThreadCount()) {
@@ -1646,7 +1648,9 @@
       mutex_(NOT_IN_PRODUCT("Isolate::mutex_")),
       constant_canonicalization_mutex_(
           NOT_IN_PRODUCT("Isolate::constant_canonicalization_mutex_")),
-      megamorphic_mutex_(NOT_IN_PRODUCT("Isolate::megamorphic_mutex_")),
+      megamorphic_table_mutex_(
+          NOT_IN_PRODUCT("Isolate::megamorphic_table_mutex_")),
+      type_feedback_mutex_(NOT_IN_PRODUCT("Isolate::type_feedback_mutex_")),
       kernel_data_lib_cache_mutex_(
           NOT_IN_PRODUCT("Isolate::kernel_data_lib_cache_mutex_")),
       kernel_data_class_cache_mutex_(
diff --git a/runtime/vm/isolate.h b/runtime/vm/isolate.h
index 8407f4f..77991a9 100644
--- a/runtime/vm/isolate.h
+++ b/runtime/vm/isolate.h
@@ -964,7 +964,8 @@
   Mutex* constant_canonicalization_mutex() {
     return &constant_canonicalization_mutex_;
   }
-  Mutex* megamorphic_mutex() { return &megamorphic_mutex_; }
+  Mutex* megamorphic_table_mutex() { return &megamorphic_table_mutex_; }
+  Mutex* type_feedback_mutex() { return &type_feedback_mutex_; }
 
   Mutex* kernel_data_lib_cache_mutex() { return &kernel_data_lib_cache_mutex_; }
   Mutex* kernel_data_class_cache_mutex() {
@@ -1600,8 +1601,8 @@
   Simulator* simulator_ = nullptr;
   Mutex mutex_;                            // Protects compiler stats.
   Mutex constant_canonicalization_mutex_;  // Protects const canonicalization.
-  Mutex megamorphic_mutex_;  // Protects the table of megamorphic caches and
-                             // their entries.
+  Mutex megamorphic_table_mutex_;
+  Mutex type_feedback_mutex_;
   Mutex kernel_data_lib_cache_mutex_;
   Mutex kernel_data_class_cache_mutex_;
   Mutex kernel_constants_mutex_;
diff --git a/runtime/vm/lockers.cc b/runtime/vm/lockers.cc
index 7ad731d..cb04006 100644
--- a/runtime/vm/lockers.cc
+++ b/runtime/vm/lockers.cc
@@ -40,7 +40,8 @@
   return result;
 }
 
-SafepointMutexLocker::SafepointMutexLocker(Mutex* mutex) : mutex_(mutex) {
+SafepointMutexLocker::SafepointMutexLocker(ThreadState* thread, Mutex* mutex)
+    : StackResource(thread), mutex_(mutex) {
   ASSERT(mutex != NULL);
   if (!mutex_->TryLock()) {
     // We did not get the lock and could potentially block, so transition
diff --git a/runtime/vm/lockers.h b/runtime/vm/lockers.h
index 94a8070..d5b2576 100644
--- a/runtime/vm/lockers.h
+++ b/runtime/vm/lockers.h
@@ -226,9 +226,11 @@
  *      ...
  *    }
  */
-class SafepointMutexLocker : public ValueObject {
+class SafepointMutexLocker : public StackResource {
  public:
-  explicit SafepointMutexLocker(Mutex* mutex);
+  explicit SafepointMutexLocker(Mutex* mutex)
+      : SafepointMutexLocker(ThreadState::Current(), mutex) {}
+  SafepointMutexLocker(ThreadState* thread, Mutex* mutex);
   virtual ~SafepointMutexLocker() { mutex_->Unlock(); }
 
  private:
diff --git a/runtime/vm/megamorphic_cache_table.cc b/runtime/vm/megamorphic_cache_table.cc
index 04a4acd..7a1b7f6 100644
--- a/runtime/vm/megamorphic_cache_table.cc
+++ b/runtime/vm/megamorphic_cache_table.cc
@@ -17,13 +17,13 @@
                                                   const String& name,
                                                   const Array& descriptor) {
   Isolate* isolate = thread->isolate();
-  // Multiple compilation threads could access this lookup.
-  SafepointMutexLocker ml(isolate->megamorphic_mutex());
+  SafepointMutexLocker ml(isolate->megamorphic_table_mutex());
+
   ASSERT(name.IsSymbol());
   // TODO(rmacnak): ASSERT(descriptor.IsCanonical());
 
   // TODO(rmacnak): Make a proper hashtable a la symbol table.
-  GrowableObjectArray& table = GrowableObjectArray::Handle(
+  auto& table = GrowableObjectArray::Handle(
       isolate->object_store()->megamorphic_cache_table());
   MegamorphicCache& cache = MegamorphicCache::Handle();
   if (table.IsNull()) {
@@ -45,7 +45,10 @@
 }
 
 void MegamorphicCacheTable::PrintSizes(Isolate* isolate) {
-  StackZone zone(Thread::Current());
+  auto thread = Thread::Current();
+  SafepointMutexLocker ml(thread->isolate()->megamorphic_table_mutex());
+
+  StackZone zone(thread);
   intptr_t size = 0;
   MegamorphicCache& cache = MegamorphicCache::Handle();
   Array& buckets = Array::Handle();
diff --git a/runtime/vm/object.cc b/runtime/vm/object.cc
index 160aa54..3f6ff74 100644
--- a/runtime/vm/object.cc
+++ b/runtime/vm/object.cc
@@ -15123,8 +15123,8 @@
 
 intptr_t ICData::FindCheck(const GrowableArray<intptr_t>& cids) const {
   const intptr_t len = NumberOfChecks();
+  GrowableArray<intptr_t> class_ids;
   for (intptr_t i = 0; i < len; i++) {
-    GrowableArray<intptr_t> class_ids;
     GetClassIdsAt(i, &class_ids);
     bool matches = true;
     for (intptr_t k = 0; k < class_ids.length(); k++) {
@@ -15236,9 +15236,27 @@
   return true;
 }
 
+void ICData::EnsureHasCheck(const GrowableArray<intptr_t>& class_ids,
+                            const Function& target,
+                            intptr_t count) const {
+  SafepointMutexLocker ml(Isolate::Current()->type_feedback_mutex());
+
+  if (FindCheck(class_ids) != -1) return;
+  AddCheckInternal(class_ids, target, count);
+}
+
 void ICData::AddCheck(const GrowableArray<intptr_t>& class_ids,
                       const Function& target,
                       intptr_t count) const {
+  SafepointMutexLocker ml(Isolate::Current()->type_feedback_mutex());
+  AddCheckInternal(class_ids, target, count);
+}
+
+void ICData::AddCheckInternal(const GrowableArray<intptr_t>& class_ids,
+                              const Function& target,
+                              intptr_t count) const {
+  ASSERT(Isolate::Current()->type_feedback_mutex()->IsOwnedByCurrentThread());
+
   ASSERT(!is_tracking_exactness());
   ASSERT(!target.IsNull());
   ASSERT((target.name() == target_name()) || ValidateInterceptor(target));
@@ -15321,10 +15339,32 @@
   }
 }
 
+void ICData::EnsureHasReceiverCheck(intptr_t receiver_class_id,
+                                    const Function& target,
+                                    intptr_t count,
+                                    StaticTypeExactnessState exactness) const {
+  SafepointMutexLocker ml(Isolate::Current()->type_feedback_mutex());
+
+  GrowableArray<intptr_t> class_ids(1);
+  class_ids.Add(receiver_class_id);
+  if (FindCheck(class_ids) != -1) return;
+
+  AddReceiverCheckInternal(receiver_class_id, target, count, exactness);
+}
+
 void ICData::AddReceiverCheck(intptr_t receiver_class_id,
                               const Function& target,
                               intptr_t count,
                               StaticTypeExactnessState exactness) const {
+  SafepointMutexLocker ml(Isolate::Current()->type_feedback_mutex());
+  AddReceiverCheckInternal(receiver_class_id, target, count, exactness);
+}
+
+void ICData::AddReceiverCheckInternal(
+    intptr_t receiver_class_id,
+    const Function& target,
+    intptr_t count,
+    StaticTypeExactnessState exactness) const {
 #if defined(DEBUG)
   GrowableArray<intptr_t> class_ids(1);
   class_ids.Add(receiver_class_id);
@@ -15566,8 +15606,9 @@
       result.IncrementCountAt(duplicate_class_id, count);
     } else {
       // This will make sure that Smi is first if it exists.
-      result.AddReceiverCheck(class_id, Function::Handle(GetTargetAt(i)),
-                              count);
+      result.AddReceiverCheckInternal(class_id,
+                                      Function::Handle(GetTargetAt(i)), count,
+                                      StaticTypeExactnessState::NotTracking());
     }
   }
 
@@ -17131,14 +17172,78 @@
   return result.raw();
 }
 
-void MegamorphicCache::Insert(const Smi& class_id, const Object& target) const {
-  SafepointMutexLocker ml(Isolate::Current()->megamorphic_mutex());
-  EnsureCapacityLocked();
-  InsertLocked(class_id, target);
+void MegamorphicCache::EnsureContains(const Smi& class_id,
+                                      const Object& target) const {
+  SafepointMutexLocker ml(Isolate::Current()->type_feedback_mutex());
+
+  if (LookupLocked(class_id) == Object::null()) {
+    InsertLocked(class_id, target);
+  }
+
+#if defined(DEBUG)
+  if (FLAG_precompiled_mode && FLAG_use_bare_instructions) {
+    if (target.IsFunction()) {
+      const auto& function = Function::Cast(target);
+      const auto& entry_point = Smi::Handle(
+          Smi::FromAlignedAddress(Code::EntryPointOf(function.CurrentCode())));
+      ASSERT(LookupLocked(class_id) == entry_point.raw());
+    }
+  } else {
+    ASSERT(LookupLocked(class_id) == target.raw());
+  }
+#endif  // define(DEBUG)
+}
+
+ObjectPtr MegamorphicCache::Lookup(const Smi& class_id) const {
+  SafepointMutexLocker ml(Isolate::Current()->type_feedback_mutex());
+  return LookupLocked(class_id);
+}
+
+ObjectPtr MegamorphicCache::LookupLocked(const Smi& class_id) const {
+  auto thread = Thread::Current();
+  auto zone = thread->zone();
+  ASSERT(thread->IsMutatorThread());
+  ASSERT(thread->isolate()->type_feedback_mutex()->IsOwnedByCurrentThread());
+
+  const auto& backing_array = Array::Handle(zone, buckets());
+  intptr_t id_mask = mask();
+  intptr_t index = (class_id.Value() * kSpreadFactor) & id_mask;
+  intptr_t i = index;
+  do {
+    const classid_t current_cid =
+        Smi::Value(Smi::RawCast(GetClassId(backing_array, i)));
+    if (current_cid == class_id.Value()) {
+      return GetTargetFunction(backing_array, i);
+    } else if (current_cid == kIllegalCid) {
+      return Object::null();
+    }
+    i = (i + 1) & id_mask;
+  } while (i != index);
+  UNREACHABLE();
+}
+
+void MegamorphicCache::InsertLocked(const Smi& class_id,
+                                    const Object& target) const {
+  auto isolate_group = IsolateGroup::Current();
+  ASSERT(Isolate::Current()->type_feedback_mutex()->IsOwnedByCurrentThread());
+
+  // As opposed to ICData we are stopping mutator threads from other isolates
+  // while modifying the megamorphic cache, since updates are not atomic.
+  //
+  // NOTE: In the future we might change the megamorphic cache insertions to
+  // carefully use store-release barriers on the writer as well as
+  // load-acquire barriers on the reader, ...
+  isolate_group->RunWithStoppedMutators(
+      [&]() {
+        EnsureCapacityLocked();
+        InsertEntryLocked(class_id, target);
+      },
+      /*use_force_growth=*/true);
 }
 
 void MegamorphicCache::EnsureCapacityLocked() const {
-  ASSERT(Isolate::Current()->megamorphic_mutex()->IsOwnedByCurrentThread());
+  ASSERT(Isolate::Current()->type_feedback_mutex()->IsOwnedByCurrentThread());
+
   intptr_t old_capacity = mask() + 1;
   double load_limit = kLoadFactor * static_cast<double>(old_capacity);
   if (static_cast<double>(filled_entry_count() + 1) > load_limit) {
@@ -17161,15 +17266,16 @@
       class_id ^= GetClassId(old_buckets, i);
       if (class_id.Value() != kIllegalCid) {
         target = GetTargetFunction(old_buckets, i);
-        InsertLocked(class_id, target);
+        InsertEntryLocked(class_id, target);
       }
     }
   }
 }
 
-void MegamorphicCache::InsertLocked(const Smi& class_id,
-                                    const Object& target) const {
-  ASSERT(Isolate::Current()->megamorphic_mutex()->IsOwnedByCurrentThread());
+void MegamorphicCache::InsertEntryLocked(const Smi& class_id,
+                                         const Object& target) const {
+  ASSERT(Isolate::Current()->type_feedback_mutex()->IsOwnedByCurrentThread());
+
   ASSERT(Thread::Current()->IsMutatorThread());
   ASSERT(static_cast<double>(filled_entry_count() + 1) <=
          (kLoadFactor * static_cast<double>(mask() + 1)));
diff --git a/runtime/vm/object.h b/runtime/vm/object.h
index 3c70ead..ada80f9 100644
--- a/runtime/vm/object.h
+++ b/runtime/vm/object.h
@@ -2088,6 +2088,15 @@
 
   // Adding checks.
 
+  // Ensures there is a check for [class_ids].
+  //
+  // Calls [AddCheck] iff there is no existing check. Ensures test (and
+  // potential update) will be performed under exclusive lock to guard against
+  // multiple threads trying to add the same check.
+  void EnsureHasCheck(const GrowableArray<intptr_t>& class_ids,
+                      const Function& target,
+                      intptr_t count = 1) const;
+
   // Adds one more class test to ICData. Length of 'classes' must be equal to
   // the number of arguments tested. Use only for num_args_tested > 1.
   void AddCheck(const GrowableArray<intptr_t>& class_ids,
@@ -2096,6 +2105,18 @@
 
   StaticTypeExactnessState GetExactnessAt(intptr_t count) const;
 
+  // Ensures there is a receiver check for [receiver_class_id].
+  //
+  // Calls [AddCheckReceiverCheck] iff there is no existing check. Ensures
+  // test (and potential update) will be performed under exclusive lock to
+  // guard against multiple threads trying to add the same check.
+  void EnsureHasReceiverCheck(
+      intptr_t receiver_class_id,
+      const Function& target,
+      intptr_t count = 1,
+      StaticTypeExactnessState exactness =
+          StaticTypeExactnessState::NotTracking()) const;
+
   // Adds sorted so that Smi is the first class-id. Use only for
   // num_args_tested == 1.
   void AddReceiverCheck(intptr_t receiver_class_id,
@@ -2262,6 +2283,13 @@
                              intptr_t data_pos,
                              intptr_t num_args_tested,
                              const Function& target);
+  void AddCheckInternal(const GrowableArray<intptr_t>& class_ids,
+                        const Function& target,
+                        intptr_t count) const;
+  void AddReceiverCheckInternal(intptr_t receiver_class_id,
+                                const Function& target,
+                                intptr_t count,
+                                StaticTypeExactnessState exactness) const;
 
   // This bit is set when a call site becomes megamorphic and starts using a
   // MegamorphicCache instead of ICData. It means that the entries in the
@@ -6822,7 +6850,8 @@
   static MegamorphicCachePtr New(const String& target_name,
                                  const Array& arguments_descriptor);
 
-  void Insert(const Smi& class_id, const Object& target) const;
+  void EnsureContains(const Smi& class_id, const Object& target) const;
+  ObjectPtr Lookup(const Smi& class_id) const;
 
   void SwitchToBareInstructions();
 
@@ -6830,8 +6859,6 @@
     return RoundedAllocationSize(sizeof(MegamorphicCacheLayout));
   }
 
-  static MegamorphicCachePtr Clone(const MegamorphicCache& from);
-
  private:
   friend class Class;
   friend class MegamorphicCacheTable;
@@ -6839,9 +6866,12 @@
 
   static MegamorphicCachePtr New();
 
-  // The caller must hold Isolate::megamorphic_mutex().
-  void EnsureCapacityLocked() const;
+  // The caller must hold IsolateGroup::type_feedback_mutex().
   void InsertLocked(const Smi& class_id, const Object& target) const;
+  void EnsureCapacityLocked() const;
+  ObjectPtr LookupLocked(const Smi& class_id) const;
+
+  void InsertEntryLocked(const Smi& class_id, const Object& target) const;
 
   static inline void SetEntry(const Array& array,
                               intptr_t index,
diff --git a/runtime/vm/object_test.cc b/runtime/vm/object_test.cc
index 94e3747..ccd43d8 100644
--- a/runtime/vm/object_test.cc
+++ b/runtime/vm/object_test.cc
@@ -3226,6 +3226,57 @@
   EXPECT_EQ(Bool::True().raw(), test_result.raw());
 }
 
+ISOLATE_UNIT_TEST_CASE(MegamorphicCache) {
+  const auto& name = String::Handle(String::New("name"));
+  const auto& args_descriptor =
+      Array::Handle(ArgumentsDescriptor::NewBoxed(1, 1, Object::null_array()));
+
+  const auto& cidA = Smi::Handle(Smi::New(1));
+  const auto& cidB = Smi::Handle(Smi::New(2));
+
+  const auto& valueA = Smi::Handle(Smi::New(42));
+  const auto& valueB = Smi::Handle(Smi::New(43));
+
+  // Test normal insert/lookup methods.
+  {
+    const auto& cache =
+        MegamorphicCache::Handle(MegamorphicCache::New(name, args_descriptor));
+
+    EXPECT(cache.Lookup(cidA) == Object::null());
+    cache.EnsureContains(cidA, valueA);
+    EXPECT(cache.Lookup(cidA) == valueA.raw());
+
+    EXPECT(cache.Lookup(cidB) == Object::null());
+    cache.EnsureContains(cidB, valueB);
+    EXPECT(cache.Lookup(cidB) == valueB.raw());
+  }
+
+  // Try to insert many keys to hit collisions & growth.
+  {
+    const auto& cache =
+        MegamorphicCache::Handle(MegamorphicCache::New(name, args_descriptor));
+
+    auto& cid = Smi::Handle();
+    auto& value = Object::Handle();
+    for (intptr_t i = 0; i < 100; ++i) {
+      cid = Smi::New(100 * i);
+      if (cid.Value() == kIllegalCid) continue;
+
+      value = Smi::New(i);
+      cache.EnsureContains(cid, value);
+    }
+    auto& expected = Object::Handle();
+    for (intptr_t i = 0; i < 100; ++i) {
+      cid = Smi::New(100 * i);
+      if (cid.Value() == kIllegalCid) continue;
+
+      expected = Smi::New(i);
+      value = cache.Lookup(cid);
+      EXPECT(Smi::Cast(value).Equals(Smi::Cast(expected)));
+    }
+  }
+}
+
 ISOLATE_UNIT_TEST_CASE(FieldTests) {
   const String& f = String::Handle(String::New("oneField"));
   const String& getter_f = String::Handle(Field::GetterName(f));
diff --git a/runtime/vm/runtime_entry.cc b/runtime/vm/runtime_entry.cc
index 8ef9463..b5f1d00 100644
--- a/runtime/vm/runtime_entry.cc
+++ b/runtime/vm/runtime_entry.cc
@@ -1267,30 +1267,27 @@
   const Instance& receiver = *args[0];
 
   if (args.length() == 1) {
+    auto exactness = StaticTypeExactnessState::NotTracking();
     if (ic_data.is_tracking_exactness()) {
 #if !defined(DART_PRECOMPILED_RUNTIME)
-      const auto state = receiver.IsNull()
-                             ? StaticTypeExactnessState::NotExact()
-                             : StaticTypeExactnessState::Compute(
-                                   Type::Cast(AbstractType::Handle(
-                                       ic_data.receivers_static_type())),
-                                   receiver);
-      ic_data.AddReceiverCheck(
-          receiver.GetClassId(), target_function, count,
-          /*exactness=*/state.CollapseSuperTypeExactness());
+      exactness = receiver.IsNull() ? StaticTypeExactnessState::NotExact()
+                                    : StaticTypeExactnessState::Compute(
+                                          Type::Cast(AbstractType::Handle(
+                                              ic_data.receivers_static_type())),
+                                          receiver);
 #else
       UNREACHABLE();
 #endif
-    } else {
-      ic_data.AddReceiverCheck(args[0]->GetClassId(), target_function, count);
     }
+    ic_data.EnsureHasReceiverCheck(receiver.GetClassId(), target_function,
+                                   count, exactness);
   } else {
     GrowableArray<intptr_t> class_ids(args.length());
     ASSERT(ic_data.NumArgsTested() == args.length());
     for (intptr_t i = 0; i < args.length(); i++) {
       class_ids.Add(args[i]->GetClassId());
     }
-    ic_data.AddCheck(class_ids, target_function, count);
+    ic_data.EnsureHasCheck(class_ids, target_function, count);
   }
   if (FLAG_trace_ic_miss_in_optimized || FLAG_trace_ic) {
     DartFrameIterator iterator(Thread::Current(),
@@ -1322,8 +1319,7 @@
 
 static FunctionPtr InlineCacheMissHandler(
     const GrowableArray<const Instance*>& args,  // Checked arguments only.
-    const ICData& ic_data,
-    intptr_t count = 1) {
+    const ICData& ic_data) {
   Thread* thread = Thread::Current();
   Zone* zone = thread->zone();
 
@@ -1365,7 +1361,7 @@
     return target_function.raw();
   }
 
-  return InlineCacheMissHandlerGivenTargetFunction(args, ic_data, count,
+  return InlineCacheMissHandlerGivenTargetFunction(args, ic_data, 1,
                                                    target_function);
 }
 
@@ -1416,7 +1412,7 @@
   const Function& target = Function::Handle(zone, ic_data.GetTargetAt(0));
   target.EnsureHasCode();
   ASSERT(!target.IsNull() && target.HasCode());
-  ic_data.AddReceiverCheck(arg.GetClassId(), target, 1);
+  ic_data.EnsureHasReceiverCheck(arg.GetClassId(), target, 1);
   if (FLAG_trace_ic) {
     DartFrameIterator iterator(thread,
                                StackFrameIterator::kNoCrossThreadIteration);
@@ -1444,7 +1440,7 @@
   GrowableArray<intptr_t> cids(2);
   cids.Add(arg0.GetClassId());
   cids.Add(arg1.GetClassId());
-  ic_data.AddCheck(cids, target);
+  ic_data.EnsureHasCheck(cids, target);
   if (FLAG_trace_ic) {
     DartFrameIterator iterator(thread,
                                StackFrameIterator::kNoCrossThreadIteration);
@@ -1945,7 +1941,7 @@
 
   // Insert function found into cache.
   const Smi& class_id = Smi::Handle(zone_, Smi::New(cls.id()));
-  data.Insert(class_id, target_function);
+  data.EnsureContains(class_id, target_function);
   arguments_.SetArgAt(0, StubCode::MegamorphicCall());
   arguments_.SetReturn(data);
 }
diff --git a/runtime/vm/thread_test.cc b/runtime/vm/thread_test.cc
index aaedbb7..95a0839 100644
--- a/runtime/vm/thread_test.cc
+++ b/runtime/vm/thread_test.cc
@@ -1029,6 +1029,38 @@
   EXPECT(!lock.IsCurrentThreadWriter());
 }
 
+template <typename LockType, typename LockerType>
+static void RunLockerWithLongJumpTest() {
+  const intptr_t kNumIterations = 5;
+  intptr_t execution_count = 0;
+  intptr_t thrown_count = 0;
+  LockType lock;
+  for (intptr_t i = 0; i < kNumIterations; ++i) {
+    LongJumpScope jump;
+    if (setjmp(*jump.Set()) == 0) {
+      LockerType locker(Thread::Current(), &lock);
+      execution_count++;
+      Thread::Current()->long_jump_base()->Jump(
+          1, Object::background_compilation_error());
+    } else {
+      thrown_count++;
+    }
+  }
+  EXPECT_EQ(kNumIterations, execution_count);
+  EXPECT_EQ(kNumIterations, thrown_count);
+}
+ISOLATE_UNIT_TEST_CASE(SafepointRwLockWriteWithLongJmp) {
+  RunLockerWithLongJumpTest<SafepointRwLock, SafepointWriteRwLocker>();
+}
+
+ISOLATE_UNIT_TEST_CASE(SafepointRwLockReadWithLongJmp) {
+  RunLockerWithLongJumpTest<SafepointRwLock, SafepointReadRwLocker>();
+}
+
+ISOLATE_UNIT_TEST_CASE(SafepointMutexLockerWithLongJmp) {
+  RunLockerWithLongJumpTest<Mutex, SafepointMutexLocker>();
+}
+
 struct ReaderThreadState {
   ThreadJoinId reader_id = OSThread::kInvalidThreadJoinId;
   SafepointRwLock* rw_lock = nullptr;
diff --git a/sdk/lib/_internal/js_runtime/lib/core_patch.dart b/sdk/lib/_internal/js_runtime/lib/core_patch.dart
index 2b48b5d..1cd3bc4 100644
--- a/sdk/lib/_internal/js_runtime/lib/core_patch.dart
+++ b/sdk/lib/_internal/js_runtime/lib/core_patch.dart
@@ -26,7 +26,7 @@
         getTraceFromException,
         RuntimeError;
 
-import 'dart:_foreign_helper' show JS, JS_GET_FLAG;
+import 'dart:_foreign_helper' show JS;
 import 'dart:_native_typed_data' show NativeUint8List;
 import 'dart:_rti' show getRuntimeType;
 
@@ -459,9 +459,15 @@
     assertUnreachable();
   }
 
+  factory List._ofArray(Iterable<E> elements) {
+    return JSArray<E>.markGrowable(
+        JS('effects:none;depends:no-static', '#.slice(0)', elements));
+  }
+
   factory List._of(Iterable<E> elements) {
-    // This is essentially `addAll`, but without a check for modifiability or
-    // ConcurrentModificationError on the receiver.
+    if (elements is JSArray) return List._ofArray(elements);
+    // This is essentially `<E>[]..addAll(elements)`, but without a check for
+    // modifiability or ConcurrentModificationError on the receiver.
     List<E> list = <E>[];
     for (final e in elements) {
       list.add(e);
diff --git a/sdk/lib/collection/linked_list.dart b/sdk/lib/collection/linked_list.dart
index 71e0226..6d6be81 100644
--- a/sdk/lib/collection/linked_list.dart
+++ b/sdk/lib/collection/linked_list.dart
@@ -6,7 +6,7 @@
 
 /// A specialized double-linked list of elements that extends [LinkedListEntry].
 ///
-/// This is not a generic data structure. It only accepts elements that extend
+/// This is not a generic data structure. It only accepts elements that *extend*
 /// the [LinkedListEntry] class. See the [Queue] implementations for generic
 /// collections that allow constant time adding and removing at the ends.
 ///
@@ -17,6 +17,9 @@
 /// Because the elements themselves contain the links of this linked list,
 /// each element can be in only one list at a time. To add an element to another
 /// list, it must first be removed from its current list (if any).
+/// For the same reason, the [remove] and [contains] methods
+/// are based on *identity*, even if the [LinkedListEntry] chooses
+/// to override [Object.operator==].
 ///
 /// In return, each element knows its own place in the linked list, as well as
 /// which list it is in. This allows constant time
@@ -61,6 +64,13 @@
     return true;
   }
 
+  /// Whether [entry] is a [LinkedListEntry] belonging to this list.
+  ///
+  /// The [entry] is considered as belonging to this list if
+  /// its [LinkedListEntry.list] is this list.
+  bool contains(Object? entry) =>
+      entry is LinkedListEntry && identical(this, entry.list);
+
   Iterator<E> get iterator => _LinkedListIterator<E>(this);
 
   int get length => _length;
diff --git a/tests/language/metadata/metadata_builtin_test.dart b/tests/language/metadata/metadata_builtin_test.dart
new file mode 100644
index 0000000..aceec19
--- /dev/null
+++ b/tests/language/metadata/metadata_builtin_test.dart
@@ -0,0 +1,125 @@
+// Copyright (c) 2020, 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.
+
+// Verify that built-in identifiers can be used to specify metadata.
+
+const abstract = 0;
+const as = 0;
+const covariant = 0;
+const deferred = 0;
+const dynamic = 0;
+const export = 0;
+const external = 0;
+const factory = 0;
+const Function = 0;
+const get = 0;
+const implements = 0;
+const import = 0;
+const interface = 0;
+const late = 0;
+const library = 0;
+const mixin = 0;
+const operator = 0;
+const part = 0;
+const required = 0;
+const set = 0;
+const static = 0;
+const typedef = 0;
+
+@abstract
+@as
+@covariant
+@deferred
+@dynamic
+@export
+@external
+@factory
+@Function
+@get
+@implements
+@import
+@interface
+@late
+@library
+@mixin
+@operator
+@part
+@required
+@set
+@static
+@typedef
+void main(
+  @abstract
+  @as
+  @covariant
+  @deferred
+  @dynamic
+  @export
+  @external
+  @factory
+  @Function
+  @get
+  @implements
+  @import
+  @interface
+  @late
+  @library
+  @mixin
+  @operator
+  @part
+  @required
+  @set
+  @static
+  @typedef
+      List<String> args,
+) {
+  @abstract
+  @as
+  @covariant
+  @deferred
+  @dynamic
+  @export
+  @external
+  @factory
+  @Function
+  @get
+  @implements
+  @import
+  @interface
+  @late
+  @library
+  @mixin
+  @operator
+  @part
+  @required
+  @set
+  @static
+  @typedef
+  var x = true;
+
+  void f<
+      @abstract
+      @as
+      @covariant
+      @deferred
+      @dynamic
+      @export
+      @external
+      @factory
+      @Function
+      @get
+      @implements
+      @import
+      @interface
+      @late
+      @library
+      @mixin
+      @operator
+      @part
+      @required
+      @set
+      @static
+      @typedef
+          X>() {}
+}
diff --git a/tests/language_2/metadata/metadata_builtin_test.dart b/tests/language_2/metadata/metadata_builtin_test.dart
new file mode 100644
index 0000000..f5c346d
--- /dev/null
+++ b/tests/language_2/metadata/metadata_builtin_test.dart
@@ -0,0 +1,115 @@
+// Copyright (c) 2020, 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.
+
+// Verify that built-in identifiers can be used to specify metadata.
+
+const abstract = 0;
+const as = 0;
+const covariant = 0;
+const deferred = 0;
+const dynamic = 0;
+const export = 0;
+const external = 0;
+const factory = 0;
+const Function = 0;
+const get = 0;
+const implements = 0;
+const import = 0;
+const interface = 0;
+const library = 0;
+const mixin = 0;
+const operator = 0;
+const part = 0;
+const set = 0;
+const static = 0;
+const typedef = 0;
+
+@abstract
+@as
+@covariant
+@deferred
+@dynamic
+@export
+@external
+@factory
+@Function
+@get
+@implements
+@import
+@interface
+@library
+@mixin
+@operator
+@part
+@set
+@static
+@typedef
+void main(
+  @abstract
+  @as
+  @covariant
+  @deferred
+  @dynamic
+  @export
+  @external
+  @factory
+  @Function
+  @get
+  @implements
+  @import
+  @interface
+  @library
+  @mixin
+  @operator
+  @part
+  @set
+  @static
+  @typedef
+      List<String> args,
+) {
+  @abstract
+  @as
+  @covariant
+  @deferred
+  @dynamic
+  @export
+  @external
+  @factory
+  @Function
+  @get
+  @implements
+  @import
+  @interface
+  @library
+  @mixin
+  @operator
+  @part
+  @set
+  @static
+  @typedef
+  var x = true;
+
+  void f<
+      @abstract
+      @as
+      @covariant
+      @deferred
+      @dynamic
+      @export
+      @external
+      @factory
+      @Function
+      @get
+      @implements
+      @import
+      @interface
+      @library
+      @mixin
+      @operator
+      @part
+      @set
+      @static
+      @typedef
+          X>() {}
+}
diff --git a/tests/lib/collection/linked_list_test.dart b/tests/lib/collection/linked_list_test.dart
index 2c06874..e2c6a7e 100644
--- a/tests/lib/collection/linked_list_test.dart
+++ b/tests/lib/collection/linked_list_test.dart
@@ -11,16 +11,19 @@
   MyEntry(int this.value);
 
   String toString() => value.toString();
+
+  int get hashCode => value.hashCode;
+  bool operator ==(Object o) => o is MyEntry && value == o.value;
 }
 
-testPreviousNext() {
-  var list = new LinkedList<MyEntry>();
+void testPreviousNext() {
+  var list = LinkedList<MyEntry>();
   Expect.throws(() => list.first);
   Expect.throws(() => list.last);
   Expect.equals(0, list.length);
 
   for (int i = 0; i < 3; i++) {
-    list.add(new MyEntry(i));
+    list.add(MyEntry(i));
   }
   Expect.equals(3, list.length);
 
@@ -39,11 +42,11 @@
   Expect.isNull(entry.previous);
 }
 
-testUnlinked() {
-  var unlinked = new MyEntry(0);
+void testUnlinked() {
+  var unlinked = MyEntry(0);
   Expect.isNull(unlinked.previous);
   Expect.isNull(unlinked.next);
-  var list = new LinkedList<MyEntry>();
+  var list = LinkedList<MyEntry>();
   list.add(unlinked);
   Expect.isNull(unlinked.previous);
   Expect.isNull(unlinked.next);
@@ -51,7 +54,7 @@
   Expect.isNull(unlinked.previous);
   Expect.isNull(unlinked.next);
   list.add(unlinked);
-  list.add(new MyEntry(1));
+  list.add(MyEntry(1));
   Expect.isNull(unlinked.previous);
   Expect.equals(1, unlinked.next!.value);
   list.remove(unlinked);
@@ -62,11 +65,11 @@
   Expect.equals(1, unlinked.previous!.value);
 }
 
-testInsert() {
+void testInsert() {
   // Insert last.
-  var list = new LinkedList<MyEntry>();
+  var list = LinkedList<MyEntry>();
   for (int i = 0; i < 10; i++) {
-    list.add(new MyEntry(i));
+    list.add(MyEntry(i));
   }
 
   Expect.equals(10, list.length);
@@ -83,7 +86,7 @@
 
   // Insert first.
   for (int i = 0; i < 10; i++) {
-    list.addFirst(new MyEntry(i));
+    list.addFirst(MyEntry(i));
   }
 
   Expect.equals(10, list.length);
@@ -97,9 +100,9 @@
   list.clear();
 
   // Insert after.
-  list.addFirst(new MyEntry(0));
+  list.addFirst(MyEntry(0));
   for (int i = 1; i < 10; i++) {
-    list.last.insertAfter(new MyEntry(i));
+    list.last.insertAfter(MyEntry(i));
   }
 
   Expect.equals(10, list.length);
@@ -115,9 +118,9 @@
   list.clear();
 
   // Insert before.
-  list.addFirst(new MyEntry(0));
+  list.addFirst(MyEntry(0));
   for (int i = 1; i < 10; i++) {
-    list.first.insertBefore(new MyEntry(i));
+    list.first.insertBefore(MyEntry(i));
   }
 
   Expect.equals(10, list.length);
@@ -131,10 +134,10 @@
   list.clear();
 }
 
-testRemove() {
-  var list = new LinkedList<MyEntry>();
+void testRemove() {
+  var list = LinkedList<MyEntry>();
   for (int i = 0; i < 10; i++) {
-    list.add(new MyEntry(i));
+    list.add(MyEntry(i));
   }
 
   Expect.equals(10, list.length);
@@ -162,21 +165,51 @@
   Expect.equals(0, list.length);
 }
 
-testBadAdd() {
-  var list1 = new LinkedList<MyEntry>();
-  list1.addFirst(new MyEntry(0));
+void testContains() {
+  var list = LinkedList<MyEntry>();
+  var entry5 = MyEntry(5);
 
-  var list2 = new LinkedList<MyEntry>();
-  Expect.throws(() => list2.addFirst(list1.first));
+  // Empty lists contains nothing.
+  Expect.isFalse(list.contains(null));
+  Expect.isFalse(list.contains(Object()));
+  Expect.isFalse(list.contains(entry5));
 
-  Expect.throws(() => new MyEntry(0).unlink());
+  // Works for singleton lists.
+  list.add(MyEntry(0));
+  Expect.isTrue(list.contains(list.first));
+  Expect.isFalse(list.contains(null));
+  Expect.isFalse(list.contains(Object()));
+  Expect.isFalse(list.contains(entry5));
+
+  // Works for larger lists.
+  for (int i = 1; i < 10; i++) {
+    list.add(MyEntry(i));
+  }
+  for (var entry in list) {
+    Expect.isTrue(list.contains(entry));
+  }
+  Expect.isFalse(list.contains(Object()));
+  Expect.isFalse(list.contains(null));
+  Expect.isFalse(list.contains(entry5));
+  // Based on identity, not equality.
+  Expect.equals(entry5, list.elementAt(5));
 }
 
-testConcurrentModificationError() {
+void testBadAdd() {
+  var list1 = LinkedList<MyEntry>();
+  list1.addFirst(MyEntry(0));
+
+  var list2 = LinkedList<MyEntry>();
+  Expect.throws(() => list2.addFirst(list1.first));
+
+  Expect.throws(() => MyEntry(0).unlink());
+}
+
+void testConcurrentModificationError() {
   test(function(LinkedList<MyEntry> ll)) {
-    var ll = new LinkedList<MyEntry>();
+    var ll = LinkedList<MyEntry>();
     for (int i = 0; i < 10; i++) {
-      ll.add(new MyEntry(i));
+      ll.add(MyEntry(i));
     }
     Expect.throws(() => function(ll), (e) => e is ConcurrentModificationError);
   }
@@ -269,11 +302,12 @@
   });
 }
 
-main() {
+void main() {
   testPreviousNext();
   testUnlinked();
   testInsert();
   testRemove();
+  testContains();
   testBadAdd();
   testConcurrentModificationError();
 }
diff --git a/tests/lib_2/collection/linked_list_test.dart b/tests/lib_2/collection/linked_list_test.dart
index 03e01bb..dd73a0a 100644
--- a/tests/lib_2/collection/linked_list_test.dart
+++ b/tests/lib_2/collection/linked_list_test.dart
@@ -11,16 +11,19 @@
   MyEntry(int this.value);
 
   String toString() => value.toString();
+
+  int get hashCode => value.hashCode;
+  bool operator ==(Object o) => o is MyEntry && value == o.value;
 }
 
-testPreviousNext() {
-  var list = new LinkedList<MyEntry>();
+void testPreviousNext() {
+  var list = LinkedList<MyEntry>();
   Expect.throws(() => list.first);
   Expect.throws(() => list.last);
   Expect.equals(0, list.length);
 
   for (int i = 0; i < 3; i++) {
-    list.add(new MyEntry(i));
+    list.add(MyEntry(i));
   }
   Expect.equals(3, list.length);
 
@@ -39,11 +42,11 @@
   Expect.isNull(entry.previous);
 }
 
-testUnlinked() {
-  var unlinked = new MyEntry(0);
+void testUnlinked() {
+  var unlinked = MyEntry(0);
   Expect.isNull(unlinked.previous);
   Expect.isNull(unlinked.next);
-  var list = new LinkedList<MyEntry>();
+  var list = LinkedList<MyEntry>();
   list.add(unlinked);
   Expect.isNull(unlinked.previous);
   Expect.isNull(unlinked.next);
@@ -51,7 +54,7 @@
   Expect.isNull(unlinked.previous);
   Expect.isNull(unlinked.next);
   list.add(unlinked);
-  list.add(new MyEntry(1));
+  list.add(MyEntry(1));
   Expect.isNull(unlinked.previous);
   Expect.equals(1, unlinked.next.value);
   list.remove(unlinked);
@@ -62,11 +65,11 @@
   Expect.equals(1, unlinked.previous.value);
 }
 
-testInsert() {
+void testInsert() {
   // Insert last.
-  var list = new LinkedList<MyEntry>();
+  var list = LinkedList<MyEntry>();
   for (int i = 0; i < 10; i++) {
-    list.add(new MyEntry(i));
+    list.add(MyEntry(i));
   }
 
   Expect.equals(10, list.length);
@@ -83,7 +86,7 @@
 
   // Insert first.
   for (int i = 0; i < 10; i++) {
-    list.addFirst(new MyEntry(i));
+    list.addFirst(MyEntry(i));
   }
 
   Expect.equals(10, list.length);
@@ -97,9 +100,9 @@
   list.clear();
 
   // Insert after.
-  list.addFirst(new MyEntry(0));
+  list.addFirst(MyEntry(0));
   for (int i = 1; i < 10; i++) {
-    list.last.insertAfter(new MyEntry(i));
+    list.last.insertAfter(MyEntry(i));
   }
 
   Expect.equals(10, list.length);
@@ -115,9 +118,9 @@
   list.clear();
 
   // Insert before.
-  list.addFirst(new MyEntry(0));
+  list.addFirst(MyEntry(0));
   for (int i = 1; i < 10; i++) {
-    list.first.insertBefore(new MyEntry(i));
+    list.first.insertBefore(MyEntry(i));
   }
 
   Expect.equals(10, list.length);
@@ -131,10 +134,10 @@
   list.clear();
 }
 
-testRemove() {
-  var list = new LinkedList<MyEntry>();
+void testRemove() {
+  var list = LinkedList<MyEntry>();
   for (int i = 0; i < 10; i++) {
-    list.add(new MyEntry(i));
+    list.add(MyEntry(i));
   }
 
   Expect.equals(10, list.length);
@@ -162,21 +165,51 @@
   Expect.equals(0, list.length);
 }
 
-testBadAdd() {
-  var list1 = new LinkedList<MyEntry>();
-  list1.addFirst(new MyEntry(0));
+void testContains() {
+  var list = LinkedList<MyEntry>();
+  var entry5 = MyEntry(5);
 
-  var list2 = new LinkedList<MyEntry>();
-  Expect.throws(() => list2.addFirst(list1.first));
+  // Empty lists contains nothing.
+  Expect.isFalse(list.contains(null));
+  Expect.isFalse(list.contains(Object()));
+  Expect.isFalse(list.contains(entry5));
 
-  Expect.throws(() => new MyEntry(0).unlink());
+  // Works for singleton lists.
+  list.add(MyEntry(0));
+  Expect.isTrue(list.contains(list.first));
+  Expect.isFalse(list.contains(null));
+  Expect.isFalse(list.contains(Object()));
+  Expect.isFalse(list.contains(entry5));
+
+  // Works for larger lists.
+  for (int i = 1; i < 10; i++) {
+    list.add(MyEntry(i));
+  }
+  for (var entry in list) {
+    Expect.isTrue(list.contains(entry));
+  }
+  Expect.isFalse(list.contains(Object()));
+  Expect.isFalse(list.contains(null));
+  Expect.isFalse(list.contains(entry5));
+  // Based on identity, not equality.
+  Expect.isTrue(list.elementAt(5) == entry5);
 }
 
-testConcurrentModificationError() {
+void testBadAdd() {
+  var list1 = LinkedList<MyEntry>();
+  list1.addFirst(MyEntry(0));
+
+  var list2 = LinkedList<MyEntry>();
+  Expect.throws(() => list2.addFirst(list1.first));
+
+  Expect.throws(() => MyEntry(0).unlink());
+}
+
+void testConcurrentModificationError() {
   test(function(LinkedList<MyEntry> ll)) {
-    var ll = new LinkedList<MyEntry>();
+    var ll = LinkedList<MyEntry>();
     for (int i = 0; i < 10; i++) {
-      ll.add(new MyEntry(i));
+      ll.add(MyEntry(i));
     }
     Expect.throws(() => function(ll), (e) => e is ConcurrentModificationError);
   }
@@ -269,11 +302,12 @@
   });
 }
 
-main() {
+void main() {
   testPreviousNext();
   testUnlinked();
   testInsert();
   testRemove();
+  testContains();
   testBadAdd();
   testConcurrentModificationError();
 }
diff --git a/tests/standalone/io/https_connection_closed_during_handshake_test.dart b/tests/standalone/io/https_connection_closed_during_handshake_test.dart
new file mode 100644
index 0000000..eed79c2
--- /dev/null
+++ b/tests/standalone/io/https_connection_closed_during_handshake_test.dart
@@ -0,0 +1,81 @@
+// Copyright (c) 2020, 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.
+
+// VMOptions=--long-ssl-cert-evaluation
+
+// This test verifies that lost of connection during handshake doesn't cause
+// vm crashes.
+
+import 'dart:async';
+import 'dart:convert';
+import 'dart:io';
+
+import "package:expect/expect.dart";
+
+String getFilename(String path) => Platform.script.resolve(path).toFilePath();
+
+final SecurityContext serverSecurityContext = () {
+  final context = SecurityContext();
+  context
+      .usePrivateKeyBytes(File(getFilename('localhost.key')).readAsBytesSync());
+  context.useCertificateChainBytes(
+      File(getFilename('localhost.crt')).readAsBytesSync());
+  return context;
+}();
+
+final SecurityContext clientSecurityContext = () {
+  final context = SecurityContext(withTrustedRoots: true);
+  context.setTrustedCertificatesBytes(
+      File(getFilename('localhost.crt')).readAsBytesSync());
+  return context;
+}();
+
+void main(List<String> args) async {
+  if (args.length >= 1 && args[0] == 'server') {
+    final server =
+        await SecureServerSocket.bind('localhost', 0, serverSecurityContext);
+    print('ok ${server.port}');
+    server.listen((socket) {
+      print('server: got connection');
+      socket.close();
+    });
+    await Future.delayed(Duration(seconds: 2));
+    print('server: exiting');
+    exit(1);
+  }
+
+  final serverProcess = await Process.start(
+      Platform.executable, [Platform.script.toFilePath(), 'server']);
+  final serverPortCompleter = Completer<int>();
+
+  serverProcess.stdout
+      .transform(utf8.decoder)
+      .transform(LineSplitter())
+      .listen((line) {
+    print('server stdout: $line');
+    if (line.startsWith('ok')) {
+      serverPortCompleter.complete(int.parse(line.substring('ok'.length)));
+    }
+  });
+  serverProcess.stderr
+      .transform(utf8.decoder)
+      .transform(LineSplitter())
+      .listen((line) => print('server stderr: $line'));
+
+  int port = await serverPortCompleter.future;
+
+  var thrownException;
+  try {
+    print('client connecting...');
+    await SecureSocket.connect('localhost', port,
+        context: clientSecurityContext);
+    print('client connected.');
+  } catch (e) {
+    thrownException = e;
+  } finally {
+    await serverProcess.kill();
+  }
+  print('thrownException: $thrownException');
+  Expect.isTrue(thrownException is HandshakeException);
+}
diff --git a/tests/standalone/io/localhost.crt b/tests/standalone/io/localhost.crt
new file mode 100644
index 0000000..eeab890
--- /dev/null
+++ b/tests/standalone/io/localhost.crt
@@ -0,0 +1,20 @@
+-----BEGIN CERTIFICATE-----
+MIIDNjCCAh6gAwIBAgIUe+E1Xth9TMlsYY7qmf9zlfC1Ms0wDQYJKoZIhvcNAQEL
+BQAwFDESMBAGA1UEAwwJbG9jYWxob3N0MCAXDTE4MTIzMTIzMDAxMVoYDzIxMTgx
+MjA3MjMwMDExWjAUMRIwEAYDVQQDDAlsb2NhbGhvc3QwggEiMA0GCSqGSIb3DQEB
+AQUAA4IBDwAwggEKAoIBAQDEEY2eWBX1rTDgsAWheltKiAHREteaqX4iaGwF6/TC
+6kMJajZQreySsib+lQ+FTLtMlPWorR5jMfsA6PDocRpK2zOObTqdVqJAiodUi0ov
+ds7wgaN7XnUfpPo8NDMA2tV8Bn2mfKWgC3QkUMPCDBkLqiYUuR6j5QJ4Vz2OFV5g
+1iR1HzgQgr4pbNjkUJJesr0r1J1a25YbYdLIvzss+aHBTWD+9HYfgWsfJGI3UFgc
+zoAJbKSIHYqDGsSKZMgmtixyyEjTDc6OAqjk10jhYdxdglXpTPOWP5YnwWsy8VbU
+1ozu93LlWkbbef95FD/XGH/ynglIe1laZwEXdyxOzT3bAgMBAAGjfjB8MB0GA1Ud
+DgQWBBS/3CUrYgiD2qwdEDStghi+X3+4pzAfBgNVHSMEGDAWgBS/3CUrYgiD2qwd
+EDStghi+X3+4pzAPBgNVHRMBAf8EBTADAQH/MBMGA1UdJQQMMAoGCCsGAQUFBwMB
+MBQGA1UdEQQNMAuCCWxvY2FsaG9zdDANBgkqhkiG9w0BAQsFAAOCAQEAu5adpS/h
+bWXYaDLW5JGZAiOVVkMDhspJDdPwDHUTqMPj3V6aaecZTc46Q7TLEkLxIjU5OjvR
+ZHh3vo9X4S84Yf7NHv8eX50MK/RrzZolUROhZ6gtYZKkdZtjQKQd62ih5EB6gNnZ
++IW9nedg7Sae2Yh22jDC9Tc+dbvroOd7IUwL9gVSCcwiqVjvuWkDa7jqjnRp4sog
+yY1Obr14tmUMgR73Db7q3g0cVToztLYIMJnhjiSUs8nk83m/9/O4SGqQmievoZ5N
+60OlhU6enfFoj1xKpXWSGv6mqqdX0G9Ehz1EIetFhkBK2pP/R00gf4OMKc4ubw8d
+yTSUIeMSOo0QjA==
+-----END CERTIFICATE-----
diff --git a/tests/standalone/io/localhost.key b/tests/standalone/io/localhost.key
new file mode 100644
index 0000000..20815e4
--- /dev/null
+++ b/tests/standalone/io/localhost.key
@@ -0,0 +1,28 @@
+-----BEGIN PRIVATE KEY-----
+MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDEEY2eWBX1rTDg
+sAWheltKiAHREteaqX4iaGwF6/TC6kMJajZQreySsib+lQ+FTLtMlPWorR5jMfsA
+6PDocRpK2zOObTqdVqJAiodUi0ovds7wgaN7XnUfpPo8NDMA2tV8Bn2mfKWgC3Qk
+UMPCDBkLqiYUuR6j5QJ4Vz2OFV5g1iR1HzgQgr4pbNjkUJJesr0r1J1a25YbYdLI
+vzss+aHBTWD+9HYfgWsfJGI3UFgczoAJbKSIHYqDGsSKZMgmtixyyEjTDc6OAqjk
+10jhYdxdglXpTPOWP5YnwWsy8VbU1ozu93LlWkbbef95FD/XGH/ynglIe1laZwEX
+dyxOzT3bAgMBAAECggEAHGsa5reHv0syCW8Z8dTFRKE/+ijL/UvRz3TpK1aO7G19
+9/BgHQOIhZ6yzjWWwVBk2W3ByYgGHoSRCAm7WUWDdRQefedRFpsG+2nYwaVKxGRp
+DC0OIASJ32NPLci3F8mgJdDfB3GLpA3k8JqQNSEBxFIOIPTP/xtjZ0Pl1SE9w7Uk
+8pwuJPJDPSAamguSNY5+HHcyta/i7Zsv2/S4BdV8Q8WQeCc6hcR3Zka1H0txgk8o
+qUurU2ApdnzINQ7ki0+D6CuVXEivmL/kPivQg0/khIQp1IXhdYdWCMKSUr1vkoAK
+0zc6H5DlDvdQPrjqdLGOUlVx5JnjTYd68/Wqje76eQKBgQD0uNR2yJYxmQmLC1y6
+TLXxvm0OOlmUiNMZgLOwDNdjXvOH/emtpHyyKhHpc3kzNK3xsNxyAYJRlaIUylj0
+C9dsipj+QTb4ICu0GlbLXsXN5iM592igoS4kMnP9KbzSc93k9BvMhh1emO8i3GB7
+v/1Cf/z+gP+viLMaPEFqKxI8FwKBgQDNGrjabA2jkawanHHUUhwscwB4RrvuuJTG
+Zv7L7QXBMYx7CUwJztV5amkUNrbBW/67/MMQB0Djv1pgMo4QCWeftb9oHFXGu3hV
+kUj7Or/Z2TWYtLIdxgTDbRRtit57z3NaCHCDgQhyAZUY3y8cvXFYdHDnJlqLTN77
+bzQub7BS3QKBgHtUep6yUB8GxSxxuXWaG0eNdGBrP6H/ooODvQrILfRCcfDjIdUE
+xGL1mLlSHI6VyeO4AiDiac673kckAtha72IgJyJbs1wwulW1wHAVfxJZHP+lk/D/
+ycUsOBAp7KMTCYzNCQV1wW9fG4UyEt3Kz9OntNR+Jl1MQxbBryXWNwZZAoGAO48x
+9MOB5mjL2GJrr6M0aTfv//1SX40cLs0D2oX2sNZJnATkHskANqTO5L7KrTWgsEhD
+AKmKj1gmz15+4GtKuxcVAQ+RXQddd0OcNNAnnAQ2SyTVwE2bXoCTeQfleYCRV6ix
+u45BvJF3EWTmEmt0uaH+kzERA/iLm+n79iwawMUCgYB7s6ZkEbyZbJDDT8MXU/37
+vvLo5/sPzJ6hMPIrWbKybmUfKAMBkXYV90bVfBxim+PEGyiIWSHlXRCgHLUc/C7C
+4s8ouWDR2F3zUWjadzRsPI58qWL9yVa5aGoSzoJu2qyuX4QKS8hOehxVMzIB4Mrf
+Hh0tvtntgpJAW2TwXMVxCw==
+-----END PRIVATE KEY-----
diff --git a/tests/standalone/standalone.status b/tests/standalone/standalone.status
index 66ee0cf..8c060c3 100644
--- a/tests/standalone/standalone.status
+++ b/tests/standalone/standalone.status
@@ -63,6 +63,7 @@
 
 [ $system != macos ]
 io/https_nonblocking_trust_evaluation_test: SkipByDesign
+io/https_connection_closed_during_handshake_test: SkipByDesign # long_ssl_cert_evaluation needed for long handshake is only supported on mac.
 
 [ $builder_tag == swarming && $system == macos ]
 io/*: Skip # Issue 30618
diff --git a/tests/standalone_2/io/https_connection_closed_during_handshake_test.dart b/tests/standalone_2/io/https_connection_closed_during_handshake_test.dart
new file mode 100644
index 0000000..eed79c2
--- /dev/null
+++ b/tests/standalone_2/io/https_connection_closed_during_handshake_test.dart
@@ -0,0 +1,81 @@
+// Copyright (c) 2020, 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.
+
+// VMOptions=--long-ssl-cert-evaluation
+
+// This test verifies that lost of connection during handshake doesn't cause
+// vm crashes.
+
+import 'dart:async';
+import 'dart:convert';
+import 'dart:io';
+
+import "package:expect/expect.dart";
+
+String getFilename(String path) => Platform.script.resolve(path).toFilePath();
+
+final SecurityContext serverSecurityContext = () {
+  final context = SecurityContext();
+  context
+      .usePrivateKeyBytes(File(getFilename('localhost.key')).readAsBytesSync());
+  context.useCertificateChainBytes(
+      File(getFilename('localhost.crt')).readAsBytesSync());
+  return context;
+}();
+
+final SecurityContext clientSecurityContext = () {
+  final context = SecurityContext(withTrustedRoots: true);
+  context.setTrustedCertificatesBytes(
+      File(getFilename('localhost.crt')).readAsBytesSync());
+  return context;
+}();
+
+void main(List<String> args) async {
+  if (args.length >= 1 && args[0] == 'server') {
+    final server =
+        await SecureServerSocket.bind('localhost', 0, serverSecurityContext);
+    print('ok ${server.port}');
+    server.listen((socket) {
+      print('server: got connection');
+      socket.close();
+    });
+    await Future.delayed(Duration(seconds: 2));
+    print('server: exiting');
+    exit(1);
+  }
+
+  final serverProcess = await Process.start(
+      Platform.executable, [Platform.script.toFilePath(), 'server']);
+  final serverPortCompleter = Completer<int>();
+
+  serverProcess.stdout
+      .transform(utf8.decoder)
+      .transform(LineSplitter())
+      .listen((line) {
+    print('server stdout: $line');
+    if (line.startsWith('ok')) {
+      serverPortCompleter.complete(int.parse(line.substring('ok'.length)));
+    }
+  });
+  serverProcess.stderr
+      .transform(utf8.decoder)
+      .transform(LineSplitter())
+      .listen((line) => print('server stderr: $line'));
+
+  int port = await serverPortCompleter.future;
+
+  var thrownException;
+  try {
+    print('client connecting...');
+    await SecureSocket.connect('localhost', port,
+        context: clientSecurityContext);
+    print('client connected.');
+  } catch (e) {
+    thrownException = e;
+  } finally {
+    await serverProcess.kill();
+  }
+  print('thrownException: $thrownException');
+  Expect.isTrue(thrownException is HandshakeException);
+}
diff --git a/tests/standalone_2/io/localhost.crt b/tests/standalone_2/io/localhost.crt
new file mode 100644
index 0000000..eeab890
--- /dev/null
+++ b/tests/standalone_2/io/localhost.crt
@@ -0,0 +1,20 @@
+-----BEGIN CERTIFICATE-----
+MIIDNjCCAh6gAwIBAgIUe+E1Xth9TMlsYY7qmf9zlfC1Ms0wDQYJKoZIhvcNAQEL
+BQAwFDESMBAGA1UEAwwJbG9jYWxob3N0MCAXDTE4MTIzMTIzMDAxMVoYDzIxMTgx
+MjA3MjMwMDExWjAUMRIwEAYDVQQDDAlsb2NhbGhvc3QwggEiMA0GCSqGSIb3DQEB
+AQUAA4IBDwAwggEKAoIBAQDEEY2eWBX1rTDgsAWheltKiAHREteaqX4iaGwF6/TC
+6kMJajZQreySsib+lQ+FTLtMlPWorR5jMfsA6PDocRpK2zOObTqdVqJAiodUi0ov
+ds7wgaN7XnUfpPo8NDMA2tV8Bn2mfKWgC3QkUMPCDBkLqiYUuR6j5QJ4Vz2OFV5g
+1iR1HzgQgr4pbNjkUJJesr0r1J1a25YbYdLIvzss+aHBTWD+9HYfgWsfJGI3UFgc
+zoAJbKSIHYqDGsSKZMgmtixyyEjTDc6OAqjk10jhYdxdglXpTPOWP5YnwWsy8VbU
+1ozu93LlWkbbef95FD/XGH/ynglIe1laZwEXdyxOzT3bAgMBAAGjfjB8MB0GA1Ud
+DgQWBBS/3CUrYgiD2qwdEDStghi+X3+4pzAfBgNVHSMEGDAWgBS/3CUrYgiD2qwd
+EDStghi+X3+4pzAPBgNVHRMBAf8EBTADAQH/MBMGA1UdJQQMMAoGCCsGAQUFBwMB
+MBQGA1UdEQQNMAuCCWxvY2FsaG9zdDANBgkqhkiG9w0BAQsFAAOCAQEAu5adpS/h
+bWXYaDLW5JGZAiOVVkMDhspJDdPwDHUTqMPj3V6aaecZTc46Q7TLEkLxIjU5OjvR
+ZHh3vo9X4S84Yf7NHv8eX50MK/RrzZolUROhZ6gtYZKkdZtjQKQd62ih5EB6gNnZ
++IW9nedg7Sae2Yh22jDC9Tc+dbvroOd7IUwL9gVSCcwiqVjvuWkDa7jqjnRp4sog
+yY1Obr14tmUMgR73Db7q3g0cVToztLYIMJnhjiSUs8nk83m/9/O4SGqQmievoZ5N
+60OlhU6enfFoj1xKpXWSGv6mqqdX0G9Ehz1EIetFhkBK2pP/R00gf4OMKc4ubw8d
+yTSUIeMSOo0QjA==
+-----END CERTIFICATE-----
diff --git a/tests/standalone_2/io/localhost.key b/tests/standalone_2/io/localhost.key
new file mode 100644
index 0000000..20815e4
--- /dev/null
+++ b/tests/standalone_2/io/localhost.key
@@ -0,0 +1,28 @@
+-----BEGIN PRIVATE KEY-----
+MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDEEY2eWBX1rTDg
+sAWheltKiAHREteaqX4iaGwF6/TC6kMJajZQreySsib+lQ+FTLtMlPWorR5jMfsA
+6PDocRpK2zOObTqdVqJAiodUi0ovds7wgaN7XnUfpPo8NDMA2tV8Bn2mfKWgC3Qk
+UMPCDBkLqiYUuR6j5QJ4Vz2OFV5g1iR1HzgQgr4pbNjkUJJesr0r1J1a25YbYdLI
+vzss+aHBTWD+9HYfgWsfJGI3UFgczoAJbKSIHYqDGsSKZMgmtixyyEjTDc6OAqjk
+10jhYdxdglXpTPOWP5YnwWsy8VbU1ozu93LlWkbbef95FD/XGH/ynglIe1laZwEX
+dyxOzT3bAgMBAAECggEAHGsa5reHv0syCW8Z8dTFRKE/+ijL/UvRz3TpK1aO7G19
+9/BgHQOIhZ6yzjWWwVBk2W3ByYgGHoSRCAm7WUWDdRQefedRFpsG+2nYwaVKxGRp
+DC0OIASJ32NPLci3F8mgJdDfB3GLpA3k8JqQNSEBxFIOIPTP/xtjZ0Pl1SE9w7Uk
+8pwuJPJDPSAamguSNY5+HHcyta/i7Zsv2/S4BdV8Q8WQeCc6hcR3Zka1H0txgk8o
+qUurU2ApdnzINQ7ki0+D6CuVXEivmL/kPivQg0/khIQp1IXhdYdWCMKSUr1vkoAK
+0zc6H5DlDvdQPrjqdLGOUlVx5JnjTYd68/Wqje76eQKBgQD0uNR2yJYxmQmLC1y6
+TLXxvm0OOlmUiNMZgLOwDNdjXvOH/emtpHyyKhHpc3kzNK3xsNxyAYJRlaIUylj0
+C9dsipj+QTb4ICu0GlbLXsXN5iM592igoS4kMnP9KbzSc93k9BvMhh1emO8i3GB7
+v/1Cf/z+gP+viLMaPEFqKxI8FwKBgQDNGrjabA2jkawanHHUUhwscwB4RrvuuJTG
+Zv7L7QXBMYx7CUwJztV5amkUNrbBW/67/MMQB0Djv1pgMo4QCWeftb9oHFXGu3hV
+kUj7Or/Z2TWYtLIdxgTDbRRtit57z3NaCHCDgQhyAZUY3y8cvXFYdHDnJlqLTN77
+bzQub7BS3QKBgHtUep6yUB8GxSxxuXWaG0eNdGBrP6H/ooODvQrILfRCcfDjIdUE
+xGL1mLlSHI6VyeO4AiDiac673kckAtha72IgJyJbs1wwulW1wHAVfxJZHP+lk/D/
+ycUsOBAp7KMTCYzNCQV1wW9fG4UyEt3Kz9OntNR+Jl1MQxbBryXWNwZZAoGAO48x
+9MOB5mjL2GJrr6M0aTfv//1SX40cLs0D2oX2sNZJnATkHskANqTO5L7KrTWgsEhD
+AKmKj1gmz15+4GtKuxcVAQ+RXQddd0OcNNAnnAQ2SyTVwE2bXoCTeQfleYCRV6ix
+u45BvJF3EWTmEmt0uaH+kzERA/iLm+n79iwawMUCgYB7s6ZkEbyZbJDDT8MXU/37
+vvLo5/sPzJ6hMPIrWbKybmUfKAMBkXYV90bVfBxim+PEGyiIWSHlXRCgHLUc/C7C
+4s8ouWDR2F3zUWjadzRsPI58qWL9yVa5aGoSzoJu2qyuX4QKS8hOehxVMzIB4Mrf
+Hh0tvtntgpJAW2TwXMVxCw==
+-----END PRIVATE KEY-----
diff --git a/tests/standalone_2/standalone_2.status b/tests/standalone_2/standalone_2.status
index abe364c..9dc0156 100644
--- a/tests/standalone_2/standalone_2.status
+++ b/tests/standalone_2/standalone_2.status
@@ -72,6 +72,7 @@
 
 [ $system != macos ]
 io/https_nonblocking_trust_evaluation_test: SkipByDesign
+io/https_connection_closed_during_handshake_test: SkipByDesign # long_ssl_cert_evaluation needed for long handshake is only supported on mac.
 
 [ $builder_tag == swarming && $system == macos ]
 io/*: Skip # Issue 30618
diff --git a/tools/VERSION b/tools/VERSION
index 51f1ac0..1fa2f63 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
 MAJOR 2
 MINOR 12
 PATCH 0
-PRERELEASE 105
+PRERELEASE 106
 PRERELEASE_PATCH 0
\ No newline at end of file
diff --git a/tools/spec_parser/Dart.g b/tools/spec_parser/Dart.g
index ad410ba..a200f70 100644
--- a/tools/spec_parser/Dart.g
+++ b/tools/spec_parser/Dart.g
@@ -472,6 +472,7 @@
 
 metadatum
     :    constructorDesignation arguments
+    |    identifier
     |    qualifiedName
     ;
 
@@ -905,8 +906,7 @@
     ;
 
 qualifiedName
-    :    typeIdentifier
-    |    typeIdentifier '.' identifier
+    :    typeIdentifier '.' identifier
     |    typeIdentifier '.' typeIdentifier '.' identifier
     ;
 
@@ -1253,7 +1253,8 @@
     ;
 
 constructorDesignation
-    :    qualifiedName
+    :    typeIdentifier
+    |    qualifiedName
     |    typeName typeArguments ('.' identifier)?
     ;
 
diff --git a/tools/spec_parser/SpecParser.java b/tools/spec_parser/SpecParser.java
index cc9d1ea..dc2c6e8 100644
--- a/tools/spec_parser/SpecParser.java
+++ b/tools/spec_parser/SpecParser.java
@@ -101,8 +101,8 @@
     }
   }
 
-  /// From [arguments], obey the flags ("--<flag_name>") if known and ignore
-  /// them if unknown; treat the remaining [arguments] as file paths and
+  /// From [arguments], obey the flags ("--<flag_name>", "-<any>") if known and
+  /// ignore them if unknown; treat the remaining [arguments] as file paths and
   /// parse each of them. Return a [ParsingResult] specifying how many files
   /// were parsed, and how many of them failed to parse.
   private static ParsingResult parseFiles(String[] arguments)
@@ -113,13 +113,13 @@
     result.numberOfFileArguments = arguments.length;
     for (int i = 0; i < arguments.length; i++) {
       String filePath = arguments[i];
-      if (filePath.substring(0, 2).equals("--")) {
-        result.numberOfFileArguments--;
-        if (result.numberOfFileArguments == 0) return result;
-        if (filePath.equals("--verbose")) verbose = true;
-        if (filePath.equals("--batch")) runAsBatch();
-        // Ignore all other flags.
-        continue;
+      if (filePath.startsWith("-")) {
+          result.numberOfFileArguments--;
+          if (result.numberOfFileArguments == 0) return result;
+          if (filePath.equals("--verbose")) verbose = true;
+          if (filePath.equals("--batch")) runAsBatch();
+          // Ignore all other flags.
+          continue;
       }
       if (verbose) System.err.println("Parsing file: " + filePath);
       DartLexer lexer = new DartLexer(new ANTLRFileStream(filePath));