diff --git a/pkgs/yaml/.github/dependabot.yml b/pkgs/yaml/.github/dependabot.yml
new file mode 100644
index 0000000..cde02ad
--- /dev/null
+++ b/pkgs/yaml/.github/dependabot.yml
@@ -0,0 +1,15 @@
+# Dependabot configuration file.
+# See https://docs.github.com/en/code-security/dependabot/dependabot-version-updates
+version: 2
+
+updates:
+  - package-ecosystem: github-actions
+    directory: /
+    schedule:
+      interval: monthly
+    labels:
+      - autosubmit
+    groups:
+      github-actions:
+        patterns:
+          - "*"
diff --git a/pkgs/yaml/.github/workflows/no-response.yml b/pkgs/yaml/.github/workflows/no-response.yml
new file mode 100644
index 0000000..ab1ac49
--- /dev/null
+++ b/pkgs/yaml/.github/workflows/no-response.yml
@@ -0,0 +1,37 @@
+# A workflow to close issues where the author hasn't responded to a request for
+# more information; see https://github.com/actions/stale.
+
+name: No Response
+
+# Run as a daily cron.
+on:
+  schedule:
+    # Every day at 8am
+    - cron: '0 8 * * *'
+
+# All permissions not specified are set to 'none'.
+permissions:
+  issues: write
+  pull-requests: write
+
+jobs:
+  no-response:
+    runs-on: ubuntu-latest
+    if: ${{ github.repository_owner == 'dart-lang' }}
+    steps:
+      - uses: actions/stale@28ca1036281a5e5922ead5184a1bbf96e5fc984e
+        with:
+          # Don't automatically mark inactive issues+PRs as stale.
+          days-before-stale: -1
+          # Close needs-info issues and PRs after 14 days of inactivity.
+          days-before-close: 14
+          stale-issue-label: "needs-info"
+          close-issue-message: >
+            Without additional information we're not able to resolve this issue.
+            Feel free to add more info or respond to any questions above and we
+            can reopen the case. Thanks for your contribution!
+          stale-pr-label: "needs-info"
+          close-pr-message: >
+            Without additional information we're not able to resolve this PR.
+            Feel free to add more info or respond to any questions above.
+            Thanks for your contribution!
diff --git a/pkgs/yaml/.github/workflows/publish.yaml b/pkgs/yaml/.github/workflows/publish.yaml
new file mode 100644
index 0000000..27157a0
--- /dev/null
+++ b/pkgs/yaml/.github/workflows/publish.yaml
@@ -0,0 +1,17 @@
+# A CI configuration to auto-publish pub packages.
+
+name: Publish
+
+on:
+  pull_request:
+    branches: [ master ]
+  push:
+    tags: [ 'v[0-9]+.[0-9]+.[0-9]+' ]
+
+jobs:
+  publish:
+    if: ${{ github.repository_owner == 'dart-lang' }}
+    uses: dart-lang/ecosystem/.github/workflows/publish.yaml@main
+    permissions:
+      id-token: write # Required for authentication using OIDC
+      pull-requests: write # Required for writing the pull request note
diff --git a/pkgs/yaml/.github/workflows/test-package.yml b/pkgs/yaml/.github/workflows/test-package.yml
new file mode 100644
index 0000000..7bc6a0b
--- /dev/null
+++ b/pkgs/yaml/.github/workflows/test-package.yml
@@ -0,0 +1,64 @@
+name: Dart CI
+
+on:
+  # Run on PRs and pushes to the default branch.
+  push:
+    branches: [ master ]
+  pull_request:
+    branches: [ master ]
+  schedule:
+    - cron: "0 0 * * 0"
+
+env:
+  PUB_ENVIRONMENT: bot.github
+
+jobs:
+  # Check code formatting and static analysis on a single OS (linux)
+  # against Dart dev.
+  analyze:
+    runs-on: ubuntu-latest
+    strategy:
+      fail-fast: false
+      matrix:
+        sdk: [dev]
+    steps:
+      - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
+      - uses: dart-lang/setup-dart@e630b99d28a3b71860378cafdc2a067c71107f94
+        with:
+          sdk: ${{ matrix.sdk }}
+      - id: install
+        name: Install dependencies
+        run: dart pub get
+      - name: Check formatting
+        run: dart format --output=none --set-exit-if-changed .
+        if: always() && steps.install.outcome == 'success'
+      - name: Analyze code
+        run: dart analyze --fatal-infos
+        if: always() && steps.install.outcome == 'success'
+
+  # Run tests on a matrix consisting of two dimensions:
+  # 1. OS: ubuntu-latest, (macos-latest, windows-latest)
+  # 2. release channel: dev
+  test:
+    needs: analyze
+    runs-on: ${{ matrix.os }}
+    strategy:
+      fail-fast: false
+      matrix:
+        # Add macos-latest and/or windows-latest if relevant for this package.
+        os: [ubuntu-latest]
+        sdk: [3.4, dev]
+    steps:
+      - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
+      - uses: dart-lang/setup-dart@e630b99d28a3b71860378cafdc2a067c71107f94
+        with:
+          sdk: ${{ matrix.sdk }}
+      - id: install
+        name: Install dependencies
+        run: dart pub get
+      - name: Run VM tests
+        run: dart test --platform vm
+        if: always() && steps.install.outcome == 'success'
+      - name: Run Chrome tests
+        run: dart test --platform chrome
+        if: always() && steps.install.outcome == 'success'
diff --git a/pkgs/yaml/.gitignore b/pkgs/yaml/.gitignore
new file mode 100644
index 0000000..ab3cb76
--- /dev/null
+++ b/pkgs/yaml/.gitignore
@@ -0,0 +1,16 @@
+# Don’t commit the following directories created by pub.
+.buildlog
+.dart_tool/
+.pub/
+build/
+packages
+.packages
+
+# Or the files created by dart2js.
+*.dart.js
+*.js_
+*.js.deps
+*.js.map
+
+# Include when developing application packages.
+pubspec.lock
diff --git a/pkgs/yaml/CHANGELOG.md b/pkgs/yaml/CHANGELOG.md
new file mode 100644
index 0000000..cd800a8
--- /dev/null
+++ b/pkgs/yaml/CHANGELOG.md
@@ -0,0 +1,198 @@
+## 3.1.3-wip
+
+* Require Dart 3.4
+* Fix UTF-16 surrogate pair handling in plain scaler.
+
+## 3.1.2
+
+* Require Dart 2.19
+* Added `topics` in `pubspec.yaml`.
+
+## 3.1.1
+
+* Switch to using package:lints.
+* Populate the pubspec `repository` field.
+
+## 3.1.0
+
+* `loadYaml` and related functions now accept a `recover` flag instructing the parser
+  to attempt to recover from parse errors and may return invalid or synthetic nodes.
+  When recovering, an `ErrorListener` can also be supplied to listen for errors that
+  are recovered from.
+* Drop dependency on `package:charcode`.
+
+## 3.0.0
+
+* Stable null safety release.
+
+## 3.0.0-nullsafety.0
+
+* Updated to support 2.12.0 and null safety.
+* Allow `YamlNode`s to be wrapped with an optional `style` parameter.
+* **BREAKING** The `sourceUrl` named argument is statically typed as `Uri`
+  instead of allowing `String` or `Uri`.
+
+## 2.2.1
+
+* Update min Dart SDK to `2.4.0`.
+* Fixed span for null nodes in block lists.
+
+## 2.2.0
+
+* POSSIBLY BREAKING CHANGE: Make `YamlMap` preserve parsed key order.
+  This is breaking because some programs may rely on the
+  `HashMap` sort order.
+
+## 2.1.16
+
+* Fixed deprecated API usage in README.
+* Fixed lints that affect package score.
+
+## 2.1.15
+
+* Set max SDK version to `<3.0.0`, and adjust other dependencies.
+
+## 2.1.14
+
+* Remove use of deprecated features.
+* Updated SDK version to 2.0.0-dev.17.0
+
+## 2.1.13
+
+* Stop using comment-based generic syntax.
+
+## 2.1.12
+
+* Properly refuse mappings with duplicate keys.
+
+## 2.1.11
+
+* Fix an infinite loop when parsing some invalid documents.
+
+## 2.1.10
+
+* Support `string_scanner` 1.0.0.
+
+## 2.1.9
+
+* Fix all strong-mode warnings.
+
+## 2.1.8
+
+* Remove the dependency on `path`, since we don't actually import it.
+
+## 2.1.7
+
+* Fix more strong mode warnings.
+
+## 2.1.6
+
+* Fix two analysis issues with DDC's strong mode.
+
+## 2.1.5
+
+* Fix a bug with 2.1.4 where source span information was being discarded for
+  scalar values.
+
+## 2.1.4
+
+* Substantially improve performance.
+
+## 2.1.3
+
+* Add a hint that a colon might be missing when a mapping value is found in the
+  wrong context.
+
+## 2.1.2
+
+* Fix a crashing bug when parsing block scalars.
+
+## 2.1.1
+
+* Properly scope `SourceSpan`s for scalar values surrounded by whitespace.
+
+## 2.1.0
+
+* Rewrite the parser for a 10x speed improvement.
+
+* Support anchors and aliases (`&foo` and `*foo`).
+
+* Support explicit tags (e.g. `!!str`). Note that user-defined tags are still
+  not fully supported.
+
+* `%YAML` and `%TAG` directives are now parsed, although again user-defined tags
+  are not fully supported.
+
+* `YamlScalar`, `YamlList`, and `YamlMap` now expose the styles in which they
+  were written (for example plain vs folded, block vs flow).
+
+* A `yamlWarningCallback` field is exposed. This field can be used to customize
+  how YAML warnings are displayed.
+
+## 2.0.1+1
+
+* Fix an import in a test.
+
+* Widen the version constraint on the `collection` package.
+
+## 2.0.1
+
+* Fix a few lingering references to the old `Span` class in documentation and
+  tests.
+
+## 2.0.0
+
+* Switch from `source_maps`' `Span` class to `source_span`'s `SourceSpan` class.
+
+* For consistency with `source_span` and `string_scanner`, all `sourceName`
+  parameters have been renamed to `sourceUrl`. They now accept Urls as well as
+  Strings.
+
+## 1.1.1
+
+* Fix broken type arguments that caused breakage on dart2js.
+
+* Fix an analyzer warning in `yaml_node_wrapper.dart`.
+
+## 1.1.0
+
+* Add new publicly-accessible constructors for `YamlNode` subclasses. These
+  constructors make it possible to use the same API to access non-YAML data as
+  YAML data.
+
+* Make `YamlException` inherit from source_map's `SpanFormatException`. This
+  improves the error formatting and allows callers access to source range
+  information.
+
+## 1.0.0+1
+
+* Fix a variable name typo.
+
+## 1.0.0
+
+* **Backwards incompatibility**: The data structures returned by `loadYaml` and
+  `loadYamlStream` are now immutable.
+
+* **Backwards incompatibility**: The interface of the `YamlMap` class has
+  changed substantially in numerous ways. External users may no longer construct
+  their own instances.
+
+* Maps and lists returned by `loadYaml` and `loadYamlStream` now contain
+  information about their source locations.
+
+* A new `loadYamlNode` function returns the source location of top-level scalars
+  as well.
+
+## 0.10.0
+
+* Improve error messages when a file fails to parse.
+
+## 0.9.0+2
+
+* Ensure that maps are order-independent when used as map keys.
+
+## 0.9.0+1
+
+* The `YamlMap` class is deprecated. In a future version, maps returned by
+  `loadYaml` and `loadYamlStream` will be Dart `HashMap`s with a custom equality
+  operation.
diff --git a/pkgs/yaml/LICENSE b/pkgs/yaml/LICENSE
new file mode 100644
index 0000000..e7589cb
--- /dev/null
+++ b/pkgs/yaml/LICENSE
@@ -0,0 +1,20 @@
+Copyright (c) 2014, the Dart project authors.
+Copyright (c) 2006, Kirill Simonov.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of
+this software and associated documentation files (the "Software"), to deal in
+the Software without restriction, including without limitation the rights to
+use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+of the Software, and to permit persons to whom the Software is furnished to do
+so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
diff --git a/pkgs/yaml/README.md b/pkgs/yaml/README.md
new file mode 100644
index 0000000..6f5be28
--- /dev/null
+++ b/pkgs/yaml/README.md
@@ -0,0 +1,32 @@
+[![Build Status](https://github.com/dart-lang/yaml/workflows/Dart%20CI/badge.svg)](https://github.com/dart-lang/yaml/actions?query=workflow%3A"Dart+CI"+branch%3Amaster)
+[![Pub Package](https://img.shields.io/pub/v/yaml.svg)](https://pub.dev/packages/yaml)
+[![package publisher](https://img.shields.io/pub/publisher/yaml.svg)](https://pub.dev/packages/yaml/publisher)
+
+A parser for [YAML](https://yaml.org/).
+
+## Usage
+
+Use `loadYaml` to load a single document, or `loadYamlStream` to load a
+stream of documents. For example:
+
+```dart
+import 'package:yaml/yaml.dart';
+
+main() {
+  var doc = loadYaml("YAML: YAML Ain't Markup Language");
+  print(doc['YAML']);
+}
+```
+
+This library currently doesn't support dumping to YAML. You should use
+`json.encode` from `dart:convert` instead:
+
+```dart
+import 'dart:convert';
+import 'package:yaml/yaml.dart';
+
+main() {
+  var doc = loadYaml("YAML: YAML Ain't Markup Language");
+  print(json.encode(doc));
+}
+```
diff --git a/pkgs/yaml/analysis_options.yaml b/pkgs/yaml/analysis_options.yaml
new file mode 100644
index 0000000..46e45f0
--- /dev/null
+++ b/pkgs/yaml/analysis_options.yaml
@@ -0,0 +1,18 @@
+include: package:dart_flutter_team_lints/analysis_options.yaml
+
+analyzer:
+  language:
+    strict-casts: true
+
+linter:
+  rules:
+    - avoid_private_typedef_functions
+    - avoid_redundant_argument_values
+    - avoid_unused_constructor_parameters
+    - cancel_subscriptions
+    - join_return_with_assignment
+    - missing_whitespace_between_adjacent_strings
+    - no_runtimeType_toString
+    - prefer_const_declarations
+    - prefer_expression_function_bodies
+    - use_string_buffers
diff --git a/pkgs/yaml/benchmark/benchmark.dart b/pkgs/yaml/benchmark/benchmark.dart
new file mode 100644
index 0000000..afc3c97
--- /dev/null
+++ b/pkgs/yaml/benchmark/benchmark.dart
@@ -0,0 +1,65 @@
+// Copyright (c) 2015, the Dart project authors.
+// Copyright (c) 2006, Kirill Simonov.
+//
+// Use of this source code is governed by an MIT-style
+// license that can be found in the LICENSE file or at
+// https://opensource.org/licenses/MIT.
+
+import 'dart:convert';
+import 'dart:io';
+
+import 'package:path/path.dart' as p;
+import 'package:yaml/yaml.dart';
+
+const numTrials = 100;
+const runsPerTrial = 1000;
+
+final source = _loadFile('input.yaml');
+final expected = _loadFile('output.json');
+
+void main(List<String> args) {
+  var best = double.infinity;
+
+  // Run the benchmark several times. This ensures the VM is warmed up and lets
+  // us see how much variance there is.
+  for (var i = 0; i <= numTrials; i++) {
+    var start = DateTime.now();
+
+    // For a single benchmark, convert the source multiple times.
+    Object? result;
+    for (var j = 0; j < runsPerTrial; j++) {
+      result = loadYaml(source);
+    }
+
+    var elapsed =
+        DateTime.now().difference(start).inMilliseconds / runsPerTrial;
+
+    // Keep track of the best run so far.
+    if (elapsed >= best) continue;
+    best = elapsed;
+
+    // Sanity check to make sure the output is what we expect and to make sure
+    // the VM doesn't optimize "dead" code away.
+    if (jsonEncode(result) != expected) {
+      print('Incorrect output:\n${jsonEncode(result)}');
+      exit(1);
+    }
+
+    // Don't print the first run. It's always terrible since the VM hasn't
+    // warmed up yet.
+    if (i == 0) continue;
+    _printResult("Run ${'#$i'.padLeft(3, '')}", elapsed);
+  }
+
+  _printResult('Best   ', best);
+}
+
+String _loadFile(String name) {
+  var path = p.join(p.dirname(p.fromUri(Platform.script)), name);
+  return File(path).readAsStringSync();
+}
+
+void _printResult(String label, double time) {
+  print('$label: ${time.toStringAsFixed(3).padLeft(4, '0')}ms '
+      "${'=' * ((time * 100).toInt())}");
+}
diff --git a/pkgs/yaml/benchmark/input.yaml b/pkgs/yaml/benchmark/input.yaml
new file mode 100644
index 0000000..89bf9dc
--- /dev/null
+++ b/pkgs/yaml/benchmark/input.yaml
@@ -0,0 +1,48 @@
+verb: RecommendCafes
+recipe:
+  - verb: List
+    outputs: ["Cafe[]"]
+  - verb: Fetch
+    inputs: ["Cafe[]"]
+    outputs: ["CafeWithMenu[]"]
+  - verb: Flatten
+    inputs: ["CafeWithMenu[]"]
+    outputs: ["DishOffering[]"]
+  - verb: Score
+    inputs: ["DishOffering[]"]
+    outputs: ["DishOffering[]/Scored"]
+  - verb: Display
+    inputs: ["DishOffering[]/Scored"]
+tags:
+  booleans: [ true, false ]
+  dates:
+  - canonical: 2001-12-15T02:59:43.1Z
+  - iso8601: 2001-12-14t21:59:43.10-05:00
+  - spaced: 2001-12-14 21:59:43.10 -5
+  - date: 2002-12-14
+  numbers:
+  - int: 12345
+  - negative: -345
+  - floating-point: 345.678
+  - hexidecimal: 0x123abc
+  - exponential: 12.3015e+02
+  - octal: 0o14
+  strings:
+  - unicode: "Sosa did fine.\u263A"
+  - control: "\b1998\t1999\t2000\n"
+  - hex esc: "\x0d\x0a is \r\n"
+  - single: '"Howdy!" he cried.'
+  - quoted: ' # Not a ''comment''.'
+  - tie-fighter: '|\-*-/|'
+  - plain:
+      This unquoted scalar
+      spans many lines.
+
+  - quoted: "So does this
+      quoted scalar.\n"
+  - accomplishment: >
+      Mark set a major league
+      home run record in 1998.
+  - stats: |
+      65 Home Runs
+      0.278 Batting Average
diff --git a/pkgs/yaml/benchmark/output.json b/pkgs/yaml/benchmark/output.json
new file mode 100644
index 0000000..9e6cb84
--- /dev/null
+++ b/pkgs/yaml/benchmark/output.json
@@ -0,0 +1 @@
+{"verb":"RecommendCafes","recipe":[{"verb":"List","outputs":["Cafe[]"]},{"verb":"Fetch","inputs":["Cafe[]"],"outputs":["CafeWithMenu[]"]},{"verb":"Flatten","inputs":["CafeWithMenu[]"],"outputs":["DishOffering[]"]},{"verb":"Score","inputs":["DishOffering[]"],"outputs":["DishOffering[]/Scored"]},{"verb":"Display","inputs":["DishOffering[]/Scored"]}],"tags":{"booleans":[true,false],"dates":[{"canonical":"2001-12-15T02:59:43.1Z"},{"iso8601":"2001-12-14t21:59:43.10-05:00"},{"spaced":"2001-12-14 21:59:43.10 -5"},{"date":"2002-12-14"}],"numbers":[{"int":12345},{"negative":-345},{"floating-point":345.678},{"hexidecimal":1194684},{"exponential":1230.15},{"octal":12}],"strings":[{"unicode":"Sosa did fine.☺"},{"control":"\b1998\t1999\t2000\n"},{"hex esc":"\r\n is \r\n"},{"single":"\"Howdy!\" he cried."},{"quoted":" # Not a 'comment'."},{"tie-fighter":"|\\-*-/|"},{"plain":"This unquoted scalar spans many lines."},{"quoted":"So does this quoted scalar.\n"},{"accomplishment":"Mark set a major league home run record in 1998.\n"},{"stats":"65 Home Runs\n0.278 Batting Average\n"}]}}
\ No newline at end of file
diff --git a/pkgs/yaml/example/example.dart b/pkgs/yaml/example/example.dart
new file mode 100644
index 0000000..bb283a3
--- /dev/null
+++ b/pkgs/yaml/example/example.dart
@@ -0,0 +1,13 @@
+// Copyright (c) 2020, the Dart project authors.
+// Copyright (c) 2006, Kirill Simonov.
+//
+// Use of this source code is governed by an MIT-style
+// license that can be found in the LICENSE file or at
+// https://opensource.org/licenses/MIT.
+
+import 'package:yaml/yaml.dart';
+
+void main() {
+  var doc = loadYaml("YAML: YAML Ain't Markup Language") as Map;
+  print(doc['YAML']);
+}
diff --git a/pkgs/yaml/lib/src/charcodes.dart b/pkgs/yaml/lib/src/charcodes.dart
new file mode 100644
index 0000000..602d597
--- /dev/null
+++ b/pkgs/yaml/lib/src/charcodes.dart
@@ -0,0 +1,48 @@
+// Copyright (c) 2021, the Dart project authors.
+// Copyright (c) 2006, Kirill Simonov.
+//
+// Use of this source code is governed by an MIT-style
+// license that can be found in the LICENSE file or at
+// https://opensource.org/licenses/MIT.
+
+/// Character `+`.
+const int $plus = 0x2b;
+
+/// Character `-`.
+const int $minus = 0x2d;
+
+/// Character `.`.
+const int $dot = 0x2e;
+
+/// Character `0`.
+const int $0 = 0x30;
+
+/// Character `9`.
+const int $9 = 0x39;
+
+/// Character `F`.
+const int $F = 0x46;
+
+/// Character `N`.
+const int $N = 0x4e;
+
+/// Character `T`.
+const int $T = 0x54;
+
+/// Character `f`.
+const int $f = 0x66;
+
+/// Character `n`.
+const int $n = 0x6e;
+
+/// Character `o`.
+const int $o = 0x6f;
+
+/// Character `t`.
+const int $t = 0x74;
+
+/// Character `x`.
+const int $x = 0x78;
+
+/// Character `~`.
+const int $tilde = 0x7e;
diff --git a/pkgs/yaml/lib/src/equality.dart b/pkgs/yaml/lib/src/equality.dart
new file mode 100644
index 0000000..c833dc6
--- /dev/null
+++ b/pkgs/yaml/lib/src/equality.dart
@@ -0,0 +1,128 @@
+// Copyright (c) 2014, the Dart project authors.
+// Copyright (c) 2006, Kirill Simonov.
+//
+// Use of this source code is governed by an MIT-style
+// license that can be found in the LICENSE file or at
+// https://opensource.org/licenses/MIT.
+
+import 'dart:collection';
+
+import 'package:collection/collection.dart';
+
+import 'yaml_node.dart';
+
+/// Returns a [Map] that compares its keys based on [deepEquals].
+Map<K, V> deepEqualsMap<K, V>() =>
+    LinkedHashMap(equals: deepEquals, hashCode: deepHashCode);
+
+/// Returns whether two objects are structurally equivalent.
+///
+/// This considers `NaN` values to be equivalent, handles self-referential
+/// structures, and considers [YamlScalar]s to be equal to their values.
+bool deepEquals(Object? obj1, Object? obj2) => _DeepEquals().equals(obj1, obj2);
+
+/// A class that provides access to the list of parent objects used for loop
+/// detection.
+class _DeepEquals {
+  final _parents1 = <Object?>[];
+  final _parents2 = <Object?>[];
+
+  /// Returns whether [obj1] and [obj2] are structurally equivalent.
+  bool equals(Object? obj1, Object? obj2) {
+    if (obj1 is YamlScalar) obj1 = obj1.value;
+    if (obj2 is YamlScalar) obj2 = obj2.value;
+
+    // _parents1 and _parents2 are guaranteed to be the same size.
+    for (var i = 0; i < _parents1.length; i++) {
+      var loop1 = identical(obj1, _parents1[i]);
+      var loop2 = identical(obj2, _parents2[i]);
+      // If both structures loop in the same place, they're equal at that point
+      // in the structure. If one loops and the other doesn't, they're not
+      // equal.
+      if (loop1 && loop2) return true;
+      if (loop1 || loop2) return false;
+    }
+
+    _parents1.add(obj1);
+    _parents2.add(obj2);
+    try {
+      if (obj1 is List && obj2 is List) {
+        return _listEquals(obj1, obj2);
+      } else if (obj1 is Map && obj2 is Map) {
+        return _mapEquals(obj1, obj2);
+      } else if (obj1 is num && obj2 is num) {
+        return _numEquals(obj1, obj2);
+      } else {
+        return obj1 == obj2;
+      }
+    } finally {
+      _parents1.removeLast();
+      _parents2.removeLast();
+    }
+  }
+
+  /// Returns whether [list1] and [list2] are structurally equal.
+  bool _listEquals(List list1, List list2) {
+    if (list1.length != list2.length) return false;
+
+    for (var i = 0; i < list1.length; i++) {
+      if (!equals(list1[i], list2[i])) return false;
+    }
+
+    return true;
+  }
+
+  /// Returns whether [map1] and [map2] are structurally equal.
+  bool _mapEquals(Map map1, Map map2) {
+    if (map1.length != map2.length) return false;
+
+    for (var key in map1.keys) {
+      if (!map2.containsKey(key)) return false;
+      if (!equals(map1[key], map2[key])) return false;
+    }
+
+    return true;
+  }
+
+  /// Returns whether two numbers are equivalent.
+  ///
+  /// This differs from `n1 == n2` in that it considers `NaN` to be equal to
+  /// itself.
+  bool _numEquals(num n1, num n2) {
+    if (n1.isNaN && n2.isNaN) return true;
+    return n1 == n2;
+  }
+}
+
+/// Returns a hash code for [obj] such that structurally equivalent objects
+/// will have the same hash code.
+///
+/// This supports deep equality for maps and lists, including those with
+/// self-referential structures, and returns the same hash code for
+/// [YamlScalar]s and their values.
+int deepHashCode(Object? obj) {
+  var parents = <Object?>[];
+
+  int deepHashCodeInner(Object? value) {
+    if (parents.any((parent) => identical(parent, value))) return -1;
+
+    parents.add(value);
+    try {
+      if (value is Map) {
+        var equality = const UnorderedIterableEquality<Object?>();
+        return equality.hash(value.keys.map(deepHashCodeInner)) ^
+            equality.hash(value.values.map(deepHashCodeInner));
+      } else if (value is Iterable) {
+        return const IterableEquality<Object?>().hash(value.map(deepHashCode));
+      } else if (value is YamlScalar) {
+        return (value.value as Object?).hashCode;
+      } else {
+        return value.hashCode;
+      }
+    } finally {
+      parents.removeLast();
+    }
+  }
+
+  return deepHashCodeInner(obj);
+}
diff --git a/pkgs/yaml/lib/src/error_listener.dart b/pkgs/yaml/lib/src/error_listener.dart
new file mode 100644
index 0000000..0498d68
--- /dev/null
+++ b/pkgs/yaml/lib/src/error_listener.dart
@@ -0,0 +1,22 @@
+// Copyright (c) 2021, the Dart project authors.
+// Copyright (c) 2006, Kirill Simonov.
+//
+// Use of this source code is governed by an MIT-style
+// license that can be found in the LICENSE file or at
+// https://opensource.org/licenses/MIT.
+
+import 'yaml_exception.dart';
+
+/// A listener that is notified of [YamlException]s during scanning/parsing.
+abstract class ErrorListener {
+  /// This method is invoked when an [error] has been found in the YAML.
+  void onError(YamlException error);
+}
+
+/// An [ErrorListener] that collects all errors into [errors].
+class ErrorCollector extends ErrorListener {
+  final List<YamlException> errors = [];
+
+  @override
+  void onError(YamlException error) => errors.add(error);
+}
diff --git a/pkgs/yaml/lib/src/event.dart b/pkgs/yaml/lib/src/event.dart
new file mode 100644
index 0000000..1476311
--- /dev/null
+++ b/pkgs/yaml/lib/src/event.dart
@@ -0,0 +1,171 @@
+// Copyright (c) 2014, the Dart project authors.
+// Copyright (c) 2006, Kirill Simonov.
+//
+// Use of this source code is governed by an MIT-style
+// license that can be found in the LICENSE file or at
+// https://opensource.org/licenses/MIT.
+
+import 'package:source_span/source_span.dart';
+
+import 'parser.dart';
+import 'style.dart';
+import 'yaml_document.dart';
+
+/// An event emitted by a [Parser].
+class Event {
+  final EventType type;
+  final FileSpan span;
+
+  Event(this.type, this.span);
+
+  @override
+  String toString() => type.toString();
+}
+
+/// An event indicating the beginning of a YAML document.
+class DocumentStartEvent implements Event {
+  @override
+  EventType get type => EventType.documentStart;
+  @override
+  final FileSpan span;
+
+  /// The document's `%YAML` directive, or `null` if there was none.
+  final VersionDirective? versionDirective;
+
+  /// The document's `%TAG` directives, if any.
+  final List<TagDirective> tagDirectives;
+
+  /// Whether the document started implicitly (that is, without an explicit
+  /// `===` sequence).
+  final bool isImplicit;
+
+  DocumentStartEvent(this.span,
+      {this.versionDirective,
+      List<TagDirective>? tagDirectives,
+      this.isImplicit = true})
+      : tagDirectives = tagDirectives ?? [];
+
+  @override
+  String toString() => 'DOCUMENT_START';
+}
+
+/// An event indicating the end of a YAML document.
+class DocumentEndEvent implements Event {
+  @override
+  EventType get type => EventType.documentEnd;
+  @override
+  final FileSpan span;
+
+  /// Whether the document ended implicitly (that is, without an explicit
+  /// `...` sequence).
+  final bool isImplicit;
+
+  DocumentEndEvent(this.span, {this.isImplicit = true});
+
+  @override
+  String toString() => 'DOCUMENT_END';
+}
+
+/// An event indicating that an alias was referenced.
+class AliasEvent implements Event {
+  @override
+  EventType get type => EventType.alias;
+  @override
+  final FileSpan span;
+
+  /// The alias name.
+  final String name;
+
+  AliasEvent(this.span, this.name);
+
+  @override
+  String toString() => 'ALIAS $name';
+}
+
+/// An event that can have associated anchor and tag properties.
+abstract class _ValueEvent implements Event {
+  /// The name of the value's anchor, or `null` if it wasn't anchored.
+  String? get anchor;
+
+  /// The text of the value's tag, or `null` if it wasn't tagged.
+  String? get tag;
+
+  @override
+  String toString() {
+    var buffer = StringBuffer('$type');
+    if (anchor != null) buffer.write(' &$anchor');
+    if (tag != null) buffer.write(' $tag');
+    return buffer.toString();
+  }
+}
+
+/// An event indicating a single scalar value.
+class ScalarEvent extends _ValueEvent {
+  @override
+  EventType get type => EventType.scalar;
+  @override
+  final FileSpan span;
+  @override
+  final String? anchor;
+  @override
+  final String? tag;
+
+  /// The contents of the scalar.
+  final String value;
+
+  /// The style of the scalar in the original source.
+  final ScalarStyle style;
+
+  ScalarEvent(this.span, this.value, this.style, {this.anchor, this.tag});
+
+  @override
+  String toString() => '${super.toString()} "$value"';
+}
+
+/// An event indicating the beginning of a sequence.
+class SequenceStartEvent extends _ValueEvent {
+  @override
+  EventType get type => EventType.sequenceStart;
+  @override
+  final FileSpan span;
+  @override
+  final String? anchor;
+  @override
+  final String? tag;
+
+  /// The style of the collection in the original source.
+  final CollectionStyle style;
+
+  SequenceStartEvent(this.span, this.style, {this.anchor, this.tag});
+}
+
+/// An event indicating the beginning of a mapping.
+class MappingStartEvent extends _ValueEvent {
+  @override
+  EventType get type => EventType.mappingStart;
+  @override
+  final FileSpan span;
+  @override
+  final String? anchor;
+  @override
+  final String? tag;
+
+  /// The style of the collection in the original source.
+  final CollectionStyle style;
+
+  MappingStartEvent(this.span, this.style, {this.anchor, this.tag});
+}
+
+/// The types of [Event] objects.
+enum EventType {
+  streamStart,
+  streamEnd,
+  documentStart,
+  documentEnd,
+  alias,
+  scalar,
+  sequenceStart,
+  sequenceEnd,
+  mappingStart,
+  mappingEnd
+}
diff --git a/pkgs/yaml/lib/src/loader.dart b/pkgs/yaml/lib/src/loader.dart
new file mode 100644
index 0000000..7cdf45a
--- /dev/null
+++ b/pkgs/yaml/lib/src/loader.dart
@@ -0,0 +1,343 @@
+// Copyright (c) 2014, the Dart project authors.
+// Copyright (c) 2006, Kirill Simonov.
+//
+// Use of this source code is governed by an MIT-style
+// license that can be found in the LICENSE file or at
+// https://opensource.org/licenses/MIT.
+
+import 'package:source_span/source_span.dart';
+
+import 'charcodes.dart';
+import 'equality.dart';
+import 'error_listener.dart';
+import 'event.dart';
+import 'parser.dart';
+import 'yaml_document.dart';
+import 'yaml_exception.dart';
+import 'yaml_node.dart';
+
+/// A loader that reads [Event]s emitted by a [Parser] and emits
+/// [YamlDocument]s.
+///
+/// This is based on the libyaml loader, available at
+/// https://github.com/yaml/libyaml/blob/master/src/loader.c. The license for
+/// that is available in ../../libyaml-license.txt.
+class Loader {
+  /// The underlying [Parser] that generates [Event]s.
+  final Parser _parser;
+
+  /// Aliases by the alias name.
+  final _aliases = <String, YamlNode>{};
+
+  /// The span of the entire stream emitted so far.
+  FileSpan get span => _span;
+  FileSpan _span;
+
+  /// Creates a loader that loads [source].
+  factory Loader(String source,
+      {Uri? sourceUrl, bool recover = false, ErrorListener? errorListener}) {
+    var parser = Parser(source,
+        sourceUrl: sourceUrl, recover: recover, errorListener: errorListener);
+    var event = parser.parse();
+    assert(event.type == EventType.streamStart);
+    return Loader._(parser, event.span);
+  }
+
+  Loader._(this._parser, this._span);
+
+  /// Loads the next document from the stream.
+  ///
+  /// If there are no more documents, returns `null`.
+  YamlDocument? load() {
+    if (_parser.isDone) return null;
+
+    var event = _parser.parse();
+    if (event.type == EventType.streamEnd) {
+      _span = _span.expand(event.span);
+      return null;
+    }
+
+    var document = _loadDocument(event as DocumentStartEvent);
+    _span = _span.expand(document.span as FileSpan);
+    _aliases.clear();
+    return document;
+  }
+
+  /// Composes a document object.
+  YamlDocument _loadDocument(DocumentStartEvent firstEvent) {
+    var contents = _loadNode(_parser.parse());
+
+    var lastEvent = _parser.parse() as DocumentEndEvent;
+    assert(lastEvent.type == EventType.documentEnd);
+
+    return YamlDocument.internal(
+        contents,
+        firstEvent.span.expand(lastEvent.span),
+        firstEvent.versionDirective,
+        firstEvent.tagDirectives,
+        startImplicit: firstEvent.isImplicit,
+        endImplicit: lastEvent.isImplicit);
+  }
+
+  /// Composes a node.
+  YamlNode _loadNode(Event firstEvent) => switch (firstEvent.type) {
+        EventType.alias => _loadAlias(firstEvent as AliasEvent),
+        EventType.scalar => _loadScalar(firstEvent as ScalarEvent),
+        EventType.sequenceStart =>
+          _loadSequence(firstEvent as SequenceStartEvent),
+        EventType.mappingStart => _loadMapping(firstEvent as MappingStartEvent),
+        _ => throw StateError('Unreachable')
+      };
+
+  /// Registers an anchor.
+  void _registerAnchor(String? anchor, YamlNode node) {
+    if (anchor == null) return;
+
+    // libyaml throws an error for duplicate anchors, but example 7.1 makes it
+    // clear that they should be overridden:
+    // http://yaml.org/spec/1.2/spec.html#id2786448.
+
+    _aliases[anchor] = node;
+  }
+
+  /// Composes a node corresponding to an alias.
+  YamlNode _loadAlias(AliasEvent event) {
+    var alias = _aliases[event.name];
+    if (alias != null) return alias;
+
+    throw YamlException('Undefined alias.', event.span);
+  }
+
+  /// Composes a scalar node.
+  YamlNode _loadScalar(ScalarEvent scalar) {
+    YamlNode node;
+    if (scalar.tag == '!') {
+      node = YamlScalar.internal(scalar.value, scalar);
+    } else if (scalar.tag != null) {
+      node = _parseByTag(scalar);
+    } else {
+      node = _parseScalar(scalar);
+    }
+
+    _registerAnchor(scalar.anchor, node);
+    return node;
+  }
+
+  /// Composes a sequence node.
+  YamlNode _loadSequence(SequenceStartEvent firstEvent) {
+    if (firstEvent.tag != '!' &&
+        firstEvent.tag != null &&
+        firstEvent.tag != 'tag:yaml.org,2002:seq') {
+      throw YamlException('Invalid tag for sequence.', firstEvent.span);
+    }
+
+    var children = <YamlNode>[];
+    var node = YamlList.internal(children, firstEvent.span, firstEvent.style);
+    _registerAnchor(firstEvent.anchor, node);
+
+    var event = _parser.parse();
+    while (event.type != EventType.sequenceEnd) {
+      children.add(_loadNode(event));
+      event = _parser.parse();
+    }
+
+    setSpan(node, firstEvent.span.expand(event.span));
+    return node;
+  }
+
+  /// Composes a mapping node.
+  YamlNode _loadMapping(MappingStartEvent firstEvent) {
+    if (firstEvent.tag != '!' &&
+        firstEvent.tag != null &&
+        firstEvent.tag != 'tag:yaml.org,2002:map') {
+      throw YamlException('Invalid tag for mapping.', firstEvent.span);
+    }
+
+    var children = deepEqualsMap<dynamic, YamlNode>();
+    var node = YamlMap.internal(children, firstEvent.span, firstEvent.style);
+    _registerAnchor(firstEvent.anchor, node);
+
+    var event = _parser.parse();
+    while (event.type != EventType.mappingEnd) {
+      var key = _loadNode(event);
+      var value = _loadNode(_parser.parse());
+      if (children.containsKey(key)) {
+        throw YamlException('Duplicate mapping key.', key.span);
+      }
+
+      children[key] = value;
+      event = _parser.parse();
+    }
+
+    setSpan(node, firstEvent.span.expand(event.span));
+    return node;
+  }
+
+  /// Parses a scalar according to its tag name.
+  YamlScalar _parseByTag(ScalarEvent scalar) {
+    switch (scalar.tag) {
+      case 'tag:yaml.org,2002:null':
+        var result = _parseNull(scalar);
+        if (result != null) return result;
+        throw YamlException('Invalid null scalar.', scalar.span);
+      case 'tag:yaml.org,2002:bool':
+        var result = _parseBool(scalar);
+        if (result != null) return result;
+        throw YamlException('Invalid bool scalar.', scalar.span);
+      case 'tag:yaml.org,2002:int':
+        var result = _parseNumber(scalar, allowFloat: false);
+        if (result != null) return result;
+        throw YamlException('Invalid int scalar.', scalar.span);
+      case 'tag:yaml.org,2002:float':
+        var result = _parseNumber(scalar, allowInt: false);
+        if (result != null) return result;
+        throw YamlException('Invalid float scalar.', scalar.span);
+      case 'tag:yaml.org,2002:str':
+        return YamlScalar.internal(scalar.value, scalar);
+      default:
+        throw YamlException('Undefined tag: ${scalar.tag}.', scalar.span);
+    }
+  }
+
+  /// Parses [scalar], which may be one of several types.
+  YamlScalar _parseScalar(ScalarEvent scalar) =>
+      _tryParseScalar(scalar) ?? YamlScalar.internal(scalar.value, scalar);
+
+  /// Tries to parse [scalar].
+  ///
+  /// If parsing fails, this returns `null`, indicating that the scalar should
+  /// be parsed as a string.
+  YamlScalar? _tryParseScalar(ScalarEvent scalar) {
+    // Quickly check for the empty string, which means null.
+    var length = scalar.value.length;
+    if (length == 0) return YamlScalar.internal(null, scalar);
+
+    // Dispatch on the first character.
+    var firstChar = scalar.value.codeUnitAt(0);
+    return switch (firstChar) {
+      $dot || $plus || $minus => _parseNumber(scalar),
+      $n || $N => length == 4 ? _parseNull(scalar) : null,
+      $t || $T => length == 4 ? _parseBool(scalar) : null,
+      $f || $F => length == 5 ? _parseBool(scalar) : null,
+      $tilde => length == 1 ? YamlScalar.internal(null, scalar) : null,
+      _ => (firstChar >= $0 && firstChar <= $9) ? _parseNumber(scalar) : null
+    };
+  }
+
+  /// Parse a null scalar.
+  ///
+  /// Returns a Dart `null` if parsing fails.
+  YamlScalar? _parseNull(ScalarEvent scalar) => switch (scalar.value) {
+        '' ||
+        'null' ||
+        'Null' ||
+        'NULL' ||
+        '~' =>
+          YamlScalar.internal(null, scalar),
+        _ => null
+      };
+
+  /// Parse a boolean scalar.
+  ///
+  /// Returns `null` if parsing fails.
+  YamlScalar? _parseBool(ScalarEvent scalar) => switch (scalar.value) {
+        'true' || 'True' || 'TRUE' => YamlScalar.internal(true, scalar),
+        'false' || 'False' || 'FALSE' => YamlScalar.internal(false, scalar),
+        _ => null
+      };
+
+  /// Parses a numeric scalar.
+  ///
+  /// Returns `null` if parsing fails.
+  YamlScalar? _parseNumber(ScalarEvent scalar,
+      {bool allowInt = true, bool allowFloat = true}) {
+    var value = _parseNumberValue(scalar.value,
+        allowInt: allowInt, allowFloat: allowFloat);
+    return value == null ? null : YamlScalar.internal(value, scalar);
+  }
+
+  /// Parses the value of a number.
+  ///
+  /// Returns the number if it's parsed successfully, or `null` if it's not.
+  num? _parseNumberValue(String contents,
+      {bool allowInt = true, bool allowFloat = true}) {
+    assert(allowInt || allowFloat);
+
+    var firstChar = contents.codeUnitAt(0);
+    var length = contents.length;
+
+    // Quick check for single digit integers.
+    if (allowInt && length == 1) {
+      var value = firstChar - $0;
+      return value >= 0 && value <= 9 ? value : null;
+    }
+
+    var secondChar = contents.codeUnitAt(1);
+
+    // Hexadecimal or octal integers.
+    if (allowInt && firstChar == $0) {
+      // int.tryParse supports 0x natively.
+      if (secondChar == $x) return int.tryParse(contents);
+
+      if (secondChar == $o) {
+        var afterRadix = contents.substring(2);
+        return int.tryParse(afterRadix, radix: 8);
+      }
+    }
+
+    // Int or float starting with a digit or a +/- sign.
+    if ((firstChar >= $0 && firstChar <= $9) ||
+        ((firstChar == $plus || firstChar == $minus) &&
+            secondChar >= $0 &&
+            secondChar <= $9)) {
+      // Try to parse an int or, failing that, a double.
+      num? result;
+      if (allowInt) {
+        // Pass "radix: 10" explicitly to ensure that "-0x10", which is valid
+        // Dart but invalid YAML, doesn't get parsed.
+        result = int.tryParse(contents, radix: 10);
+      }
+
+      if (allowFloat) result ??= double.tryParse(contents);
+      return result;
+    }
+
+    if (!allowFloat) return null;
+
+    // Now the only possibility is to parse a float starting with a dot or a
+    // sign and a dot, or the signed/unsigned infinity values and not-a-numbers.
+    if ((firstChar == $dot && secondChar >= $0 && secondChar <= $9) ||
+        (firstChar == $minus || firstChar == $plus) && secondChar == $dot) {
+      // Starting with a . and a number or a sign followed by a dot.
+      if (length == 5) {
+        switch (contents) {
+          case '+.inf':
+          case '+.Inf':
+          case '+.INF':
+            return double.infinity;
+          case '-.inf':
+          case '-.Inf':
+          case '-.INF':
+            return -double.infinity;
+        }
+      }
+
+      return double.tryParse(contents);
+    }
+
+    if (length == 4 && firstChar == $dot) {
+      switch (contents) {
+        case '.inf':
+        case '.Inf':
+        case '.INF':
+          return double.infinity;
+        case '.nan':
+        case '.NaN':
+        case '.NAN':
+          return double.nan;
+      }
+    }
+
+    return null;
+  }
+}
diff --git a/pkgs/yaml/lib/src/null_span.dart b/pkgs/yaml/lib/src/null_span.dart
new file mode 100644
index 0000000..49e1a1c
--- /dev/null
+++ b/pkgs/yaml/lib/src/null_span.dart
@@ -0,0 +1,26 @@
+// Copyright (c) 2014, the Dart project authors.
+// Copyright (c) 2006, Kirill Simonov.
+//
+// Use of this source code is governed by an MIT-style
+// license that can be found in the LICENSE file or at
+// https://opensource.org/licenses/MIT.
+
+import 'package:source_span/source_span.dart';
+
+import 'yaml_node.dart';
+
+/// A [SourceSpan] with no location information.
+///
+/// This is used with [YamlMap.wrap] and [YamlList.wrap] to provide means of
+/// accessing a non-YAML map that behaves transparently like a map parsed from
+/// YAML.
+class NullSpan extends SourceSpanMixin {
+  @override
+  final SourceLocation start;
+  @override
+  SourceLocation get end => start;
+  @override
+  final text = '';
+
+  NullSpan(Object? sourceUrl) : start = SourceLocation(0, sourceUrl: sourceUrl);
+}
diff --git a/pkgs/yaml/lib/src/parser.dart b/pkgs/yaml/lib/src/parser.dart
new file mode 100644
index 0000000..e924e40
--- /dev/null
+++ b/pkgs/yaml/lib/src/parser.dart
@@ -0,0 +1,805 @@
+// Copyright (c) 2014, the Dart project authors.
+// Copyright (c) 2006, Kirill Simonov.
+//
+// Use of this source code is governed by an MIT-style
+// license that can be found in the LICENSE file or at
+// https://opensource.org/licenses/MIT.
+
+// ignore_for_file: constant_identifier_names
+
+import 'package:source_span/source_span.dart';
+import 'package:string_scanner/string_scanner.dart';
+
+import 'error_listener.dart';
+import 'event.dart';
+import 'scanner.dart';
+import 'style.dart';
+import 'token.dart';
+import 'utils.dart';
+import 'yaml_document.dart';
+import 'yaml_exception.dart';
+
+/// A parser that reads [Token]s emitted by a [Scanner] and emits [Event]s.
+///
+/// This is based on the libyaml parser, available at
+/// https://github.com/yaml/libyaml/blob/master/src/parser.c. The license for
+/// that is available in ../../libyaml-license.txt.
+class Parser {
+  /// The underlying [Scanner] that generates [Token]s.
+  final Scanner _scanner;
+
+  /// The stack of parse states for nested contexts.
+  final _states = <_State>[];
+
+  /// The current parse state.
+  var _state = _State.STREAM_START;
+
+  /// The custom tag directives, by tag handle.
+  final _tagDirectives = <String, TagDirective>{};
+
+  /// Whether the parser has finished parsing.
+  bool get isDone => _state == _State.END;
+
+  /// Creates a parser that parses [source].
+  ///
+  /// If [recover] is true, will attempt to recover from parse errors and may
+  /// return invalid or synthetic nodes. If [errorListener] is also supplied,
+  /// its onError method will be called for each error recovered from. It is not
+  /// valid to provide [errorListener] if [recover] is false.
+  Parser(String source,
+      {Uri? sourceUrl, bool recover = false, ErrorListener? errorListener})
+      : assert(recover || errorListener == null),
+        _scanner = Scanner(source,
+            sourceUrl: sourceUrl,
+            recover: recover,
+            errorListener: errorListener);
+
+  /// Consumes and returns the next event.
+  Event parse() {
+    try {
+      if (isDone) throw StateError('No more events.');
+      var event = _stateMachine();
+      return event;
+    } on StringScannerException catch (error) {
+      throw YamlException(error.message, error.span);
+    }
+  }
+
+  /// Dispatches parsing based on the current state.
+  Event _stateMachine() {
+    switch (_state) {
+      case _State.STREAM_START:
+        return _parseStreamStart();
+      case _State.DOCUMENT_START:
+        return _parseDocumentStart();
+      case _State.DOCUMENT_CONTENT:
+        return _parseDocumentContent();
+      case _State.DOCUMENT_END:
+        return _parseDocumentEnd();
+      case _State.BLOCK_NODE:
+        return _parseNode(block: true);
+      case _State.BLOCK_NODE_OR_INDENTLESS_SEQUENCE:
+        return _parseNode(block: true, indentlessSequence: true);
+      case _State.FLOW_NODE:
+        return _parseNode();
+      case _State.BLOCK_SEQUENCE_FIRST_ENTRY:
+        // Scan past the `BLOCK-SEQUENCE-FIRST-ENTRY` token to the
+        // `BLOCK-SEQUENCE-ENTRY` token.
+        _scanner.scan();
+        return _parseBlockSequenceEntry();
+      case _State.BLOCK_SEQUENCE_ENTRY:
+        return _parseBlockSequenceEntry();
+      case _State.INDENTLESS_SEQUENCE_ENTRY:
+        return _parseIndentlessSequenceEntry();
+      case _State.BLOCK_MAPPING_FIRST_KEY:
+        // Scan past the `BLOCK-MAPPING-FIRST-KEY` token to the
+        // `BLOCK-MAPPING-KEY` token.
+        _scanner.scan();
+        return _parseBlockMappingKey();
+      case _State.BLOCK_MAPPING_KEY:
+        return _parseBlockMappingKey();
+      case _State.BLOCK_MAPPING_VALUE:
+        return _parseBlockMappingValue();
+      case _State.FLOW_SEQUENCE_FIRST_ENTRY:
+        return _parseFlowSequenceEntry(first: true);
+      case _State.FLOW_SEQUENCE_ENTRY:
+        return _parseFlowSequenceEntry();
+      case _State.FLOW_SEQUENCE_ENTRY_MAPPING_KEY:
+        return _parseFlowSequenceEntryMappingKey();
+      case _State.FLOW_SEQUENCE_ENTRY_MAPPING_VALUE:
+        return _parseFlowSequenceEntryMappingValue();
+      case _State.FLOW_SEQUENCE_ENTRY_MAPPING_END:
+        return _parseFlowSequenceEntryMappingEnd();
+      case _State.FLOW_MAPPING_FIRST_KEY:
+        return _parseFlowMappingKey(first: true);
+      case _State.FLOW_MAPPING_KEY:
+        return _parseFlowMappingKey();
+      case _State.FLOW_MAPPING_VALUE:
+        return _parseFlowMappingValue();
+      case _State.FLOW_MAPPING_EMPTY_VALUE:
+        return _parseFlowMappingValue(empty: true);
+      default:
+        throw StateError('Unreachable');
+    }
+  }
+
+  /// Parses the production:
+  ///
+  ///     stream ::=
+  ///       STREAM-START implicit_document? explicit_document* STREAM-END
+  ///       ************
+  Event _parseStreamStart() {
+    var token = _scanner.scan();
+    assert(token.type == TokenType.streamStart);
+
+    _state = _State.DOCUMENT_START;
+    return Event(EventType.streamStart, token.span);
+  }
+
+  /// Parses the productions:
+  ///
+  ///     implicit_document    ::= block_node DOCUMENT-END*
+  ///                              *
+  ///     explicit_document    ::=
+  ///       DIRECTIVE* DOCUMENT-START block_node? DOCUMENT-END*
+  ///       *************************
+  Event _parseDocumentStart() {
+    var token = _scanner.peek()!;
+
+    // libyaml requires any document beyond the first in the stream to have an
+    // explicit document start indicator, but the spec allows it to be omitted
+    // as long as there was an end indicator.
+
+    // Parse extra document end indicators.
+    while (token.type == TokenType.documentEnd) {
+      token = _scanner.advance()!;
+    }
+
+    if (token.type != TokenType.versionDirective &&
+        token.type != TokenType.tagDirective &&
+        token.type != TokenType.documentStart &&
+        token.type != TokenType.streamEnd) {
+      // Parse an implicit document.
+      _processDirectives();
+      _states.add(_State.DOCUMENT_END);
+      _state = _State.BLOCK_NODE;
+      return DocumentStartEvent(token.span.start.pointSpan());
+    }
+
+    if (token.type == TokenType.streamEnd) {
+      _state = _State.END;
+      _scanner.scan();
+      return Event(EventType.streamEnd, token.span);
+    }
+
+    // Parse an explicit document.
+    var start = token.span;
+    var (versionDirective, tagDirectives) = _processDirectives();
+    token = _scanner.peek()!;
+    if (token.type != TokenType.documentStart) {
+      throw YamlException('Expected document start.', token.span);
+    }
+
+    _states.add(_State.DOCUMENT_END);
+    _state = _State.DOCUMENT_CONTENT;
+    _scanner.scan();
+    return DocumentStartEvent(start.expand(token.span),
+        versionDirective: versionDirective,
+        tagDirectives: tagDirectives,
+        isImplicit: false);
+  }
+
+  /// Parses the productions:
+  ///
+  ///     explicit_document    ::=
+  ///       DIRECTIVE* DOCUMENT-START block_node? DOCUMENT-END*
+  ///                                 ***********
+  Event _parseDocumentContent() {
+    var token = _scanner.peek()!;
+
+    switch (token.type) {
+      case TokenType.versionDirective:
+      case TokenType.tagDirective:
+      case TokenType.documentStart:
+      case TokenType.documentEnd:
+      case TokenType.streamEnd:
+        _state = _states.removeLast();
+        return _processEmptyScalar(token.span.start);
+      default:
+        return _parseNode(block: true);
+    }
+  }
+
+  /// Parses the productions:
+  ///
+  ///     implicit_document    ::= block_node DOCUMENT-END*
+  ///                                         *************
+  ///     explicit_document    ::=
+  ///       DIRECTIVE* DOCUMENT-START block_node? DOCUMENT-END*
+  ///                                             *************
+  Event _parseDocumentEnd() {
+    _tagDirectives.clear();
+    _state = _State.DOCUMENT_START;
+
+    var token = _scanner.peek()!;
+    if (token.type == TokenType.documentEnd) {
+      _scanner.scan();
+      return DocumentEndEvent(token.span, isImplicit: false);
+    } else {
+      return DocumentEndEvent(token.span.start.pointSpan());
+    }
+  }
+
+  /// Parses the productions:
+  ///
+  ///     block_node_or_indentless_sequence    ::=
+  ///       ALIAS
+  ///       *****
+  ///       | properties (block_content | indentless_block_sequence)?
+  ///         **********  *
+  ///       | block_content | indentless_block_sequence
+  ///         *
+  ///     block_node           ::= ALIAS
+  ///                              *****
+  ///                              | properties block_content?
+  ///                                ********** *
+  ///                              | block_content
+  ///                                *
+  ///     flow_node            ::= ALIAS
+  ///                              *****
+  ///                              | properties flow_content?
+  ///                                ********** *
+  ///                              | flow_content
+  ///                                *
+  ///     properties           ::= TAG ANCHOR? | ANCHOR TAG?
+  ///                              *************************
+  ///     block_content        ::= block_collection | flow_collection | SCALAR
+  ///                                                                   ******
+  ///     flow_content         ::= flow_collection | SCALAR
+  ///                                                ******
+  Event _parseNode({bool block = false, bool indentlessSequence = false}) {
+    var token = _scanner.peek()!;
+
+    if (token is AliasToken) {
+      _scanner.scan();
+      _state = _states.removeLast();
+      return AliasEvent(token.span, token.name);
+    }
+
+    String? anchor;
+    TagToken? tagToken;
+    var span = token.span.start.pointSpan();
+    Token parseAnchor(AnchorToken token) {
+      anchor = token.name;
+      span = span.expand(token.span);
+      return _scanner.advance()!;
+    }
+
+    Token parseTag(TagToken token) {
+      tagToken = token;
+      span = span.expand(token.span);
+      return _scanner.advance()!;
+    }
+
+    if (token is AnchorToken) {
+      token = parseAnchor(token);
+      if (token is TagToken) token = parseTag(token);
+    } else if (token is TagToken) {
+      token = parseTag(token);
+      if (token is AnchorToken) token = parseAnchor(token);
+    }
+
+    String? tag;
+    if (tagToken != null) {
+      if (tagToken!.handle == null) {
+        tag = tagToken!.suffix;
+      } else {
+        var tagDirective = _tagDirectives[tagToken!.handle];
+        if (tagDirective == null) {
+          throw YamlException('Undefined tag handle.', tagToken!.span);
+        }
+
+        tag = tagDirective.prefix + (tagToken?.suffix ?? '');
+      }
+    }
+
+    if (indentlessSequence && token.type == TokenType.blockEntry) {
+      _state = _State.INDENTLESS_SEQUENCE_ENTRY;
+      return SequenceStartEvent(span.expand(token.span), CollectionStyle.BLOCK,
+          anchor: anchor, tag: tag);
+    }
+
+    if (token is ScalarToken) {
+      // All non-plain scalars have the "!" tag by default.
+      if (tag == null && token.style != ScalarStyle.PLAIN) tag = '!';
+
+      _state = _states.removeLast();
+      _scanner.scan();
+      return ScalarEvent(span.expand(token.span), token.value, token.style,
+          anchor: anchor, tag: tag);
+    }
+
+    if (token.type == TokenType.flowSequenceStart) {
+      _state = _State.FLOW_SEQUENCE_FIRST_ENTRY;
+      return SequenceStartEvent(span.expand(token.span), CollectionStyle.FLOW,
+          anchor: anchor, tag: tag);
+    }
+
+    if (token.type == TokenType.flowMappingStart) {
+      _state = _State.FLOW_MAPPING_FIRST_KEY;
+      return MappingStartEvent(span.expand(token.span), CollectionStyle.FLOW,
+          anchor: anchor, tag: tag);
+    }
+
+    if (block && token.type == TokenType.blockSequenceStart) {
+      _state = _State.BLOCK_SEQUENCE_FIRST_ENTRY;
+      return SequenceStartEvent(span.expand(token.span), CollectionStyle.BLOCK,
+          anchor: anchor, tag: tag);
+    }
+
+    if (block && token.type == TokenType.blockMappingStart) {
+      _state = _State.BLOCK_MAPPING_FIRST_KEY;
+      return MappingStartEvent(span.expand(token.span), CollectionStyle.BLOCK,
+          anchor: anchor, tag: tag);
+    }
+
+    if (anchor != null || tag != null) {
+      _state = _states.removeLast();
+      return ScalarEvent(span, '', ScalarStyle.PLAIN, anchor: anchor, tag: tag);
+    }
+
+    throw YamlException('Expected node content.', span);
+  }
+
+  /// Parses the productions:
+  ///
+  ///     block_sequence ::=
+  ///       BLOCK-SEQUENCE-START (BLOCK-ENTRY block_node?)* BLOCK-END
+  ///       ********************  *********** *             *********
+  Event _parseBlockSequenceEntry() {
+    var token = _scanner.peek()!;
+
+    if (token.type == TokenType.blockEntry) {
+      var start = token.span.start;
+      token = _scanner.advance()!;
+
+      if (token.type == TokenType.blockEntry ||
+          token.type == TokenType.blockEnd) {
+        _state = _State.BLOCK_SEQUENCE_ENTRY;
+        return _processEmptyScalar(start);
+      } else {
+        _states.add(_State.BLOCK_SEQUENCE_ENTRY);
+        return _parseNode(block: true);
+      }
+    }
+
+    if (token.type == TokenType.blockEnd) {
+      _scanner.scan();
+      _state = _states.removeLast();
+      return Event(EventType.sequenceEnd, token.span);
+    }
+
+    throw YamlException("While parsing a block collection, expected '-'.",
+        token.span.start.pointSpan());
+  }
+
+  /// Parses the productions:
+  ///
+  ///     indentless_sequence  ::= (BLOCK-ENTRY block_node?)+
+  ///                               *********** *
+  Event _parseIndentlessSequenceEntry() {
+    var token = _scanner.peek()!;
+
+    if (token.type != TokenType.blockEntry) {
+      _state = _states.removeLast();
+      return Event(EventType.sequenceEnd, token.span.start.pointSpan());
+    }
+
+    var start = token.span.start;
+    token = _scanner.advance()!;
+
+    if (token.type == TokenType.blockEntry ||
+        token.type == TokenType.key ||
+        token.type == TokenType.value ||
+        token.type == TokenType.blockEnd) {
+      _state = _State.INDENTLESS_SEQUENCE_ENTRY;
+      return _processEmptyScalar(start);
+    } else {
+      _states.add(_State.INDENTLESS_SEQUENCE_ENTRY);
+      return _parseNode(block: true);
+    }
+  }
+
+  /// Parses the productions:
+  ///
+  ///     block_mapping        ::= BLOCK-MAPPING_START
+  ///                              *******************
+  ///                              ((KEY block_node_or_indentless_sequence?)?
+  ///                                *** *
+  ///                              (VALUE block_node_or_indentless_sequence?)?)*
+  ///
+  ///                              BLOCK-END
+  ///                              *********
+  Event _parseBlockMappingKey() {
+    var token = _scanner.peek()!;
+    if (token.type == TokenType.key) {
+      var start = token.span.start;
+      token = _scanner.advance()!;
+
+      if (token.type == TokenType.key ||
+          token.type == TokenType.value ||
+          token.type == TokenType.blockEnd) {
+        _state = _State.BLOCK_MAPPING_VALUE;
+        return _processEmptyScalar(start);
+      } else {
+        _states.add(_State.BLOCK_MAPPING_VALUE);
+        return _parseNode(block: true, indentlessSequence: true);
+      }
+    }
+
+    // libyaml doesn't allow empty keys without an explicit key indicator, but
+    // the spec does. See example 8.18:
+    // http://yaml.org/spec/1.2/spec.html#id2798896.
+    if (token.type == TokenType.value) {
+      _state = _State.BLOCK_MAPPING_VALUE;
+      return _processEmptyScalar(token.span.start);
+    }
+
+    if (token.type == TokenType.blockEnd) {
+      _scanner.scan();
+      _state = _states.removeLast();
+      return Event(EventType.mappingEnd, token.span);
+    }
+
+    throw YamlException('Expected a key while parsing a block mapping.',
+        token.span.start.pointSpan());
+  }
+
+  /// Parses the productions:
+  ///
+  ///     block_mapping        ::= BLOCK-MAPPING_START
+  ///
+  ///                              ((KEY block_node_or_indentless_sequence?)?
+  ///
+  ///                              (VALUE block_node_or_indentless_sequence?)?)*
+  ///                               ***** *
+  ///                              BLOCK-END
+  ///
+  Event _parseBlockMappingValue() {
+    var token = _scanner.peek()!;
+
+    if (token.type != TokenType.value) {
+      _state = _State.BLOCK_MAPPING_KEY;
+      return _processEmptyScalar(token.span.start);
+    }
+
+    var start = token.span.start;
+    token = _scanner.advance()!;
+    if (token.type == TokenType.key ||
+        token.type == TokenType.value ||
+        token.type == TokenType.blockEnd) {
+      _state = _State.BLOCK_MAPPING_KEY;
+      return _processEmptyScalar(start);
+    } else {
+      _states.add(_State.BLOCK_MAPPING_KEY);
+      return _parseNode(block: true, indentlessSequence: true);
+    }
+  }
+
+  /// Parses the productions:
+  ///
+  ///     flow_sequence        ::= FLOW-SEQUENCE-START
+  ///                              *******************
+  ///                              (flow_sequence_entry FLOW-ENTRY)*
+  ///                               *                   **********
+  ///                              flow_sequence_entry?
+  ///                              *
+  ///                              FLOW-SEQUENCE-END
+  ///                              *****************
+  ///     flow_sequence_entry  ::=
+  ///       flow_node | KEY flow_node? (VALUE flow_node?)?
+  ///       *
+  Event _parseFlowSequenceEntry({bool first = false}) {
+    if (first) _scanner.scan();
+    var token = _scanner.peek()!;
+
+    if (token.type != TokenType.flowSequenceEnd) {
+      if (!first) {
+        if (token.type != TokenType.flowEntry) {
+          throw YamlException(
+              "While parsing a flow sequence, expected ',' or ']'.",
+              token.span.start.pointSpan());
+        }
+
+        token = _scanner.advance()!;
+      }
+
+      if (token.type == TokenType.key) {
+        _state = _State.FLOW_SEQUENCE_ENTRY_MAPPING_KEY;
+        _scanner.scan();
+        return MappingStartEvent(token.span, CollectionStyle.FLOW);
+      } else if (token.type != TokenType.flowSequenceEnd) {
+        _states.add(_State.FLOW_SEQUENCE_ENTRY);
+        return _parseNode();
+      }
+    }
+
+    _scanner.scan();
+    _state = _states.removeLast();
+    return Event(EventType.sequenceEnd, token.span);
+  }
+
+  /// Parses the productions:
+  ///
+  ///     flow_sequence_entry  ::=
+  ///       flow_node | KEY flow_node? (VALUE flow_node?)?
+  ///                   *** *
+  Event _parseFlowSequenceEntryMappingKey() {
+    var token = _scanner.peek()!;
+
+    if (token.type == TokenType.value ||
+        token.type == TokenType.flowEntry ||
+        token.type == TokenType.flowSequenceEnd) {
+      // libyaml consumes the token here, but that seems like a bug, since it
+      // always causes [_parseFlowSequenceEntryMappingValue] to emit an empty
+      // scalar.
+
+      var start = token.span.start;
+      _state = _State.FLOW_SEQUENCE_ENTRY_MAPPING_VALUE;
+      return _processEmptyScalar(start);
+    } else {
+      _states.add(_State.FLOW_SEQUENCE_ENTRY_MAPPING_VALUE);
+      return _parseNode();
+    }
+  }
+
+  /// Parses the productions:
+  ///
+  ///     flow_sequence_entry  ::=
+  ///       flow_node | KEY flow_node? (VALUE flow_node?)?
+  ///                                   ***** *
+  Event _parseFlowSequenceEntryMappingValue() {
+    var token = _scanner.peek()!;
+
+    if (token.type == TokenType.value) {
+      token = _scanner.advance()!;
+      if (token.type != TokenType.flowEntry &&
+          token.type != TokenType.flowSequenceEnd) {
+        _states.add(_State.FLOW_SEQUENCE_ENTRY_MAPPING_END);
+        return _parseNode();
+      }
+    }
+
+    _state = _State.FLOW_SEQUENCE_ENTRY_MAPPING_END;
+    return _processEmptyScalar(token.span.start);
+  }
+
+  /// Parses the productions:
+  ///
+  ///     flow_sequence_entry  ::=
+  ///       flow_node | KEY flow_node? (VALUE flow_node?)?
+  ///                                                   *
+  Event _parseFlowSequenceEntryMappingEnd() {
+    _state = _State.FLOW_SEQUENCE_ENTRY;
+    return Event(EventType.mappingEnd, _scanner.peek()!.span.start.pointSpan());
+  }
+
+  /// Parses the productions:
+  ///
+  ///     flow_mapping         ::= FLOW-MAPPING-START
+  ///                              ******************
+  ///                              (flow_mapping_entry FLOW-ENTRY)*
+  ///                               *                  **********
+  ///                              flow_mapping_entry?
+  ///                              ******************
+  ///                              FLOW-MAPPING-END
+  ///                              ****************
+  ///     flow_mapping_entry   ::=
+  ///       flow_node | KEY flow_node? (VALUE flow_node?)?
+  ///       *           *** *
+  Event _parseFlowMappingKey({bool first = false}) {
+    if (first) _scanner.scan();
+    var token = _scanner.peek()!;
+
+    if (token.type != TokenType.flowMappingEnd) {
+      if (!first) {
+        if (token.type != TokenType.flowEntry) {
+          throw YamlException(
+              "While parsing a flow mapping, expected ',' or '}'.",
+              token.span.start.pointSpan());
+        }
+
+        token = _scanner.advance()!;
+      }
+
+      if (token.type == TokenType.key) {
+        token = _scanner.advance()!;
+        if (token.type != TokenType.value &&
+            token.type != TokenType.flowEntry &&
+            token.type != TokenType.flowMappingEnd) {
+          _states.add(_State.FLOW_MAPPING_VALUE);
+          return _parseNode();
+        } else {
+          _state = _State.FLOW_MAPPING_VALUE;
+          return _processEmptyScalar(token.span.start);
+        }
+      } else if (token.type != TokenType.flowMappingEnd) {
+        _states.add(_State.FLOW_MAPPING_EMPTY_VALUE);
+        return _parseNode();
+      }
+    }
+
+    _scanner.scan();
+    _state = _states.removeLast();
+    return Event(EventType.mappingEnd, token.span);
+  }
+
+  /// Parses the productions:
+  ///
+  ///     flow_mapping_entry   ::=
+  ///       flow_node | KEY flow_node? (VALUE flow_node?)?
+  ///                *                  ***** *
+  Event _parseFlowMappingValue({bool empty = false}) {
+    var token = _scanner.peek()!;
+
+    if (empty) {
+      _state = _State.FLOW_MAPPING_KEY;
+      return _processEmptyScalar(token.span.start);
+    }
+
+    if (token.type == TokenType.value) {
+      token = _scanner.advance()!;
+      if (token.type != TokenType.flowEntry &&
+          token.type != TokenType.flowMappingEnd) {
+        _states.add(_State.FLOW_MAPPING_KEY);
+        return _parseNode();
+      }
+    }
+
+    _state = _State.FLOW_MAPPING_KEY;
+    return _processEmptyScalar(token.span.start);
+  }
+
+  /// Generate an empty scalar event.
+  Event _processEmptyScalar(SourceLocation location) =>
+      ScalarEvent(location.pointSpan() as FileSpan, '', ScalarStyle.PLAIN);
+
+  /// Parses directives.
+  (VersionDirective?, List<TagDirective>) _processDirectives() {
+    var token = _scanner.peek()!;
+
+    VersionDirective? versionDirective;
+    var tagDirectives = <TagDirective>[];
+    while (token.type == TokenType.versionDirective ||
+        token.type == TokenType.tagDirective) {
+      if (token is VersionDirectiveToken) {
+        if (versionDirective != null) {
+          throw YamlException('Duplicate %YAML directive.', token.span);
+        }
+
+        if (token.major != 1 || token.minor == 0) {
+          throw YamlException(
+              'Incompatible YAML document. This parser only supports YAML 1.1 '
+              'and 1.2.',
+              token.span);
+        } else if (token.minor > 2) {
+          // TODO(nweiz): Print to stderr when issue 6943 is fixed and dart:io
+          // is available.
+          warn('Warning: this parser only supports YAML 1.1 and 1.2.',
+              token.span);
+        }
+
+        versionDirective = VersionDirective(token.major, token.minor);
+      } else if (token is TagDirectiveToken) {
+        var tagDirective = TagDirective(token.handle, token.prefix);
+        _appendTagDirective(tagDirective, token.span);
+        tagDirectives.add(tagDirective);
+      }
+
+      token = _scanner.advance()!;
+    }
+
+    _appendTagDirective(TagDirective('!', '!'), token.span.start.pointSpan(),
+        allowDuplicates: true);
+    _appendTagDirective(
+        TagDirective('!!', 'tag:yaml.org,2002:'), token.span.start.pointSpan(),
+        allowDuplicates: true);
+
+    return (versionDirective, tagDirectives);
+  }
+
+  /// Adds a tag directive to the directives stack.
+  void _appendTagDirective(TagDirective newDirective, FileSpan span,
+      {bool allowDuplicates = false}) {
+    if (_tagDirectives.containsKey(newDirective.handle)) {
+      if (allowDuplicates) return;
+      throw YamlException('Duplicate %TAG directive.', span);
+    }
+
+    _tagDirectives[newDirective.handle] = newDirective;
+  }
+}
+
+/// The possible states for the parser.
+class _State {
+  /// Expect [TokenType.streamStart].
+  static const STREAM_START = _State('STREAM_START');
+
+  /// Expect [TokenType.documentStart].
+  static const DOCUMENT_START = _State('DOCUMENT_START');
+
+  /// Expect the content of a document.
+  static const DOCUMENT_CONTENT = _State('DOCUMENT_CONTENT');
+
+  /// Expect [TokenType.documentEnd].
+  static const DOCUMENT_END = _State('DOCUMENT_END');
+
+  /// Expect a block node.
+  static const BLOCK_NODE = _State('BLOCK_NODE');
+
+  /// Expect a block node or indentless sequence.
+  static const BLOCK_NODE_OR_INDENTLESS_SEQUENCE =
+      _State('BLOCK_NODE_OR_INDENTLESS_SEQUENCE');
+
+  /// Expect a flow node.
+  static const FLOW_NODE = _State('FLOW_NODE');
+
+  /// Expect the first entry of a block sequence.
+  static const BLOCK_SEQUENCE_FIRST_ENTRY =
+      _State('BLOCK_SEQUENCE_FIRST_ENTRY');
+
+  /// Expect an entry of a block sequence.
+  static const BLOCK_SEQUENCE_ENTRY = _State('BLOCK_SEQUENCE_ENTRY');
+
+  /// Expect an entry of an indentless sequence.
+  static const INDENTLESS_SEQUENCE_ENTRY = _State('INDENTLESS_SEQUENCE_ENTRY');
+
+  /// Expect the first key of a block mapping.
+  static const BLOCK_MAPPING_FIRST_KEY = _State('BLOCK_MAPPING_FIRST_KEY');
+
+  /// Expect a block mapping key.
+  static const BLOCK_MAPPING_KEY = _State('BLOCK_MAPPING_KEY');
+
+  /// Expect a block mapping value.
+  static const BLOCK_MAPPING_VALUE = _State('BLOCK_MAPPING_VALUE');
+
+  /// Expect the first entry of a flow sequence.
+  static const FLOW_SEQUENCE_FIRST_ENTRY = _State('FLOW_SEQUENCE_FIRST_ENTRY');
+
+  /// Expect an entry of a flow sequence.
+  static const FLOW_SEQUENCE_ENTRY = _State('FLOW_SEQUENCE_ENTRY');
+
+  /// Expect a key of an ordered mapping.
+  static const FLOW_SEQUENCE_ENTRY_MAPPING_KEY =
+      _State('FLOW_SEQUENCE_ENTRY_MAPPING_KEY');
+
+  /// Expect a value of an ordered mapping.
+  static const FLOW_SEQUENCE_ENTRY_MAPPING_VALUE =
+      _State('FLOW_SEQUENCE_ENTRY_MAPPING_VALUE');
+
+  /// Expect the and of an ordered mapping entry.
+  static const FLOW_SEQUENCE_ENTRY_MAPPING_END =
+      _State('FLOW_SEQUENCE_ENTRY_MAPPING_END');
+
+  /// Expect the first key of a flow mapping.
+  static const FLOW_MAPPING_FIRST_KEY = _State('FLOW_MAPPING_FIRST_KEY');
+
+  /// Expect a key of a flow mapping.
+  static const FLOW_MAPPING_KEY = _State('FLOW_MAPPING_KEY');
+
+  /// Expect a value of a flow mapping.
+  static const FLOW_MAPPING_VALUE = _State('FLOW_MAPPING_VALUE');
+
+  /// Expect an empty value of a flow mapping.
+  static const FLOW_MAPPING_EMPTY_VALUE = _State('FLOW_MAPPING_EMPTY_VALUE');
+
+  /// Expect nothing.
+  static const END = _State('END');
+
+  final String name;
+
+  const _State(this.name);
+
+  @override
+  String toString() => name;
+}
diff --git a/pkgs/yaml/lib/src/scanner.dart b/pkgs/yaml/lib/src/scanner.dart
new file mode 100644
index 0000000..1cfd3af
--- /dev/null
+++ b/pkgs/yaml/lib/src/scanner.dart
@@ -0,0 +1,1695 @@
+// Copyright (c) 2014, the Dart project authors.
+// Copyright (c) 2006, Kirill Simonov.
+//
+// Use of this source code is governed by an MIT-style
+// license that can be found in the LICENSE file or at
+// https://opensource.org/licenses/MIT.
+
+// ignore_for_file: constant_identifier_names
+
+import 'package:collection/collection.dart';
+import 'package:source_span/source_span.dart';
+import 'package:string_scanner/string_scanner.dart';
+
+import 'error_listener.dart';
+import 'style.dart';
+import 'token.dart';
+import 'utils.dart';
+import 'yaml_exception.dart';
+
+/// A scanner that reads a string of Unicode characters and emits [Token]s.
+///
+/// This is based on the libyaml scanner, available at
+/// https://github.com/yaml/libyaml/blob/master/src/scanner.c. The license for
+/// that is available in ../../libyaml-license.txt.
+class Scanner {
+  static const TAB = 0x9;
+  static const LF = 0xA;
+  static const CR = 0xD;
+  static const SP = 0x20;
+  static const DOLLAR = 0x24;
+  static const LEFT_PAREN = 0x28;
+  static const RIGHT_PAREN = 0x29;
+  static const PLUS = 0x2B;
+  static const COMMA = 0x2C;
+  static const HYPHEN = 0x2D;
+  static const PERIOD = 0x2E;
+  static const QUESTION = 0x3F;
+  static const COLON = 0x3A;
+  static const SEMICOLON = 0x3B;
+  static const EQUALS = 0x3D;
+  static const LEFT_SQUARE = 0x5B;
+  static const RIGHT_SQUARE = 0x5D;
+  static const LEFT_CURLY = 0x7B;
+  static const RIGHT_CURLY = 0x7D;
+  static const HASH = 0x23;
+  static const AMPERSAND = 0x26;
+  static const ASTERISK = 0x2A;
+  static const EXCLAMATION = 0x21;
+  static const VERTICAL_BAR = 0x7C;
+  static const LEFT_ANGLE = 0x3C;
+  static const RIGHT_ANGLE = 0x3E;
+  static const SINGLE_QUOTE = 0x27;
+  static const DOUBLE_QUOTE = 0x22;
+  static const PERCENT = 0x25;
+  static const AT = 0x40;
+  static const GRAVE_ACCENT = 0x60;
+  static const TILDE = 0x7E;
+
+  static const NULL = 0x0;
+  static const BELL = 0x7;
+  static const BACKSPACE = 0x8;
+  static const VERTICAL_TAB = 0xB;
+  static const FORM_FEED = 0xC;
+  static const ESCAPE = 0x1B;
+  static const SLASH = 0x2F;
+  static const BACKSLASH = 0x5C;
+  static const UNDERSCORE = 0x5F;
+  static const NEL = 0x85;
+  static const NBSP = 0xA0;
+  static const LINE_SEPARATOR = 0x2028;
+  static const PARAGRAPH_SEPARATOR = 0x2029;
+  static const BOM = 0xFEFF;
+
+  static const NUMBER_0 = 0x30;
+  static const NUMBER_9 = 0x39;
+
+  static const LETTER_A = 0x61;
+  static const LETTER_B = 0x62;
+  static const LETTER_E = 0x65;
+  static const LETTER_F = 0x66;
+  static const LETTER_N = 0x6E;
+  static const LETTER_R = 0x72;
+  static const LETTER_T = 0x74;
+  static const LETTER_U = 0x75;
+  static const LETTER_V = 0x76;
+  static const LETTER_X = 0x78;
+  static const LETTER_Z = 0x7A;
+
+  static const LETTER_CAP_A = 0x41;
+  static const LETTER_CAP_F = 0x46;
+  static const LETTER_CAP_L = 0x4C;
+  static const LETTER_CAP_N = 0x4E;
+  static const LETTER_CAP_P = 0x50;
+  static const LETTER_CAP_U = 0x55;
+  static const LETTER_CAP_X = 0x58;
+  static const LETTER_CAP_Z = 0x5A;
+
+  /// Whether this scanner should attempt to recover when parsing invalid YAML.
+  final bool _recover;
+
+  /// A listener to report YAML errors to.
+  final ErrorListener? _errorListener;
+
+  /// The underlying [SpanScanner] used to read characters from the source text.
+  ///
+  /// This is also used to track line and column information and to generate
+  /// [SourceSpan]s.
+  final SpanScanner _scanner;
+
+  /// Whether this scanner has produced a [TokenType.streamStart] token
+  /// indicating the beginning of the YAML stream.
+  var _streamStartProduced = false;
+
+  /// Whether this scanner has produced a [TokenType.streamEnd] token
+  /// indicating the end of the YAML stream.
+  var _streamEndProduced = false;
+
+  /// The queue of tokens yet to be emitted.
+  ///
+  /// These are queued up in advance so that [TokenType.key] tokens can be
+  /// inserted once the scanner determines that a series of tokens represents a
+  /// mapping key.
+  final _tokens = QueueList<Token>();
+
+  /// The number of tokens that have been emitted.
+  ///
+  /// This doesn't count tokens in [_tokens].
+  var _tokensParsed = 0;
+
+  /// Whether the next token in [_tokens] is ready to be returned.
+  ///
+  /// It might not be ready if there may still be a [TokenType.key] inserted
+  /// before it.
+  var _tokenAvailable = false;
+
+  /// The stack of indent levels for the current nested block contexts.
+  ///
+  /// The YAML spec specifies that the initial indentation level is -1 spaces.
+  final _indents = <int>[-1];
+
+  /// Whether a simple key is allowed in this context.
+  ///
+  /// A simple key refers to any mapping key that doesn't have an explicit "?".
+  var _simpleKeyAllowed = true;
+
+  /// The stack of potential simple keys for each level of flow nesting.
+  ///
+  /// Entries in this list may be `null`, indicating that there is no valid
+  /// simple key for the associated level of nesting.
+  ///
+  /// When a ":" is parsed and there's a simple key available, a [TokenType.key]
+  /// token is inserted in [_tokens] before that key's token. This allows the
+  /// parser to tell that the key is intended to be a mapping key.
+  final _simpleKeys = <_SimpleKey?>[null];
+
+  /// The current indentation level.
+  int get _indent => _indents.last;
+
+  /// Whether the scanner's currently positioned in a block-level structure (as
+  /// opposed to flow-level).
+  bool get _inBlockContext => _simpleKeys.length == 1;
+
+  /// Whether the current character is a line break or the end of the source.
+  bool get _isBreakOrEnd => _scanner.isDone || _isBreak;
+
+  /// Whether the current character is a line break.
+  bool get _isBreak => _isBreakAt(0);
+
+  /// Whether the current character is whitespace or the end of the source.
+  bool get _isBlankOrEnd => _isBlankOrEndAt(0);
+
+  /// Whether the current character is whitespace.
+  bool get _isBlank => _isBlankAt(0);
+
+  /// Whether the current character is a valid tag name character.
+  ///
+  /// See http://yaml.org/spec/1.2/spec.html#ns-tag-name.
+  bool get _isTagChar {
+    var char = _scanner.peekChar();
+    if (char == null) return false;
+    switch (char) {
+      case HYPHEN:
+      case SEMICOLON:
+      case SLASH:
+      case COLON:
+      case AT:
+      case AMPERSAND:
+      case EQUALS:
+      case PLUS:
+      case DOLLAR:
+      case PERIOD:
+      case TILDE:
+      case QUESTION:
+      case ASTERISK:
+      case SINGLE_QUOTE:
+      case LEFT_PAREN:
+      case RIGHT_PAREN:
+      case PERCENT:
+        return true;
+      default:
+        return (char >= NUMBER_0 && char <= NUMBER_9) ||
+            (char >= LETTER_A && char <= LETTER_Z) ||
+            (char >= LETTER_CAP_A && char <= LETTER_CAP_Z);
+    }
+  }
+
+  /// Whether the current character is a valid anchor name character.
+  ///
+  /// See http://yaml.org/spec/1.2/spec.html#ns-anchor-name.
+  bool get _isAnchorChar {
+    if (!_isNonSpace) return false;
+
+    switch (_scanner.peekChar()) {
+      case COMMA:
+      case LEFT_SQUARE:
+      case RIGHT_SQUARE:
+      case LEFT_CURLY:
+      case RIGHT_CURLY:
+        return false;
+      default:
+        return true;
+    }
+  }
+
+  /// Whether the character at the current position is a decimal digit.
+  bool get _isDigit {
+    var char = _scanner.peekChar();
+    return char != null && (char >= NUMBER_0 && char <= NUMBER_9);
+  }
+
+  /// Whether the character at the current position is a hexidecimal
+  /// digit.
+  bool get _isHex {
+    var char = _scanner.peekChar();
+    if (char == null) return false;
+    return (char >= NUMBER_0 && char <= NUMBER_9) ||
+        (char >= LETTER_A && char <= LETTER_F) ||
+        (char >= LETTER_CAP_A && char <= LETTER_CAP_F);
+  }
+
+  /// Whether the character at the current position is a plain character.
+  ///
+  /// See http://yaml.org/spec/1.2/spec.html#ns-plain-char(c).
+  bool get _isPlainChar => _isPlainCharAt(0);
+
+  /// Whether the character at the current position is a printable character
+  /// other than a line break or byte-order mark.
+  ///
+  /// See http://yaml.org/spec/1.2/spec.html#nb-char.
+  bool get _isNonBreak {
+    var char = _scanner.peekChar();
+    return switch (char) {
+      null => false,
+      LF || CR || BOM => false,
+      TAB || NEL => true,
+      _ => _isStandardCharacterAt(0),
+    };
+  }
+
+  /// Whether the character at the current position is a printable character
+  /// other than whitespace.
+  ///
+  /// See http://yaml.org/spec/1.2/spec.html#nb-char.
+  bool get _isNonSpace {
+    var char = _scanner.peekChar();
+    return switch (char) {
+      null => false,
+      LF || CR || BOM || SP => false,
+      NEL => true,
+      _ => _isStandardCharacterAt(0),
+    };
+  }
+
+  /// Returns Whether or not the current character begins a documentation
+  /// indicator.
+  ///
+  /// If so, this sets the scanner's last match to that indicator.
+  bool get _isDocumentIndicator =>
+      _scanner.column == 0 &&
+      _isBlankOrEndAt(3) &&
+      (_scanner.matches('---') || _scanner.matches('...'));
+
+  /// Creates a scanner that scans [source].
+  Scanner(String source,
+      {Uri? sourceUrl, bool recover = false, ErrorListener? errorListener})
+      : _recover = recover,
+        _errorListener = errorListener,
+        _scanner = SpanScanner.eager(source, sourceUrl: sourceUrl);
+
+  /// Consumes and returns the next token.
+  Token scan() {
+    if (_streamEndProduced) throw StateError('Out of tokens.');
+    if (!_tokenAvailable) _fetchMoreTokens();
+
+    var token = _tokens.removeFirst();
+    _tokenAvailable = false;
+    _tokensParsed++;
+    _streamEndProduced = token.type == TokenType.streamEnd;
+    return token;
+  }
+
+  /// Consumes the next token and returns the one after that.
+  Token? advance() {
+    scan();
+    return peek();
+  }
+
+  /// Returns the next token without consuming it.
+  Token? peek() {
+    if (_streamEndProduced) return null;
+    if (!_tokenAvailable) _fetchMoreTokens();
+    return _tokens.first;
+  }
+
+  /// Ensures that [_tokens] contains at least one token which can be returned.
+  void _fetchMoreTokens() {
+    while (true) {
+      if (_tokens.isNotEmpty) {
+        _staleSimpleKeys();
+
+        // If there are no more tokens to fetch, break.
+        if (_tokens.last.type == TokenType.streamEnd) break;
+
+        // If the current token could be a simple key, we need to scan more
+        // tokens until we determine whether it is or not. Otherwise we might
+        // not emit the `KEY` token before we emit the value of the key.
+        if (!_simpleKeys
+            .any((key) => key != null && key.tokenNumber == _tokensParsed)) {
+          break;
+        }
+      }
+
+      _fetchNextToken();
+    }
+    _tokenAvailable = true;
+  }
+
+  /// The dispatcher for token fetchers.
+  void _fetchNextToken() {
+    if (!_streamStartProduced) {
+      _fetchStreamStart();
+      return;
+    }
+
+    _scanToNextToken();
+    _staleSimpleKeys();
+    _unrollIndent(_scanner.column);
+
+    if (_scanner.isDone) {
+      _fetchStreamEnd();
+      return;
+    }
+
+    if (_scanner.column == 0) {
+      if (_scanner.peekChar() == PERCENT) {
+        _fetchDirective();
+        return;
+      }
+
+      if (_isBlankOrEndAt(3)) {
+        if (_scanner.matches('---')) {
+          _fetchDocumentIndicator(TokenType.documentStart);
+          return;
+        }
+
+        if (_scanner.matches('...')) {
+          _fetchDocumentIndicator(TokenType.documentEnd);
+          return;
+        }
+      }
+    }
+
+    switch (_scanner.peekChar()) {
+      case LEFT_SQUARE:
+        _fetchFlowCollectionStart(TokenType.flowSequenceStart);
+        return;
+      case LEFT_CURLY:
+        _fetchFlowCollectionStart(TokenType.flowMappingStart);
+        return;
+      case RIGHT_SQUARE:
+        _fetchFlowCollectionEnd(TokenType.flowSequenceEnd);
+        return;
+      case RIGHT_CURLY:
+        _fetchFlowCollectionEnd(TokenType.flowMappingEnd);
+        return;
+      case COMMA:
+        _fetchFlowEntry();
+        return;
+      case ASTERISK:
+        _fetchAnchor(anchor: false);
+        return;
+      case AMPERSAND:
+        _fetchAnchor();
+        return;
+      case EXCLAMATION:
+        _fetchTag();
+        return;
+      case SINGLE_QUOTE:
+        _fetchFlowScalar(singleQuote: true);
+        return;
+      case DOUBLE_QUOTE:
+        _fetchFlowScalar();
+        return;
+      case VERTICAL_BAR:
+        if (!_inBlockContext) _invalidScalarCharacter();
+        _fetchBlockScalar(literal: true);
+        return;
+      case RIGHT_ANGLE:
+        if (!_inBlockContext) _invalidScalarCharacter();
+        _fetchBlockScalar();
+        return;
+      case PERCENT:
+      case AT:
+      case GRAVE_ACCENT:
+        _invalidScalarCharacter();
+        return;
+
+      // These characters may sometimes begin plain scalars.
+      case HYPHEN:
+        if (_isPlainCharAt(1)) {
+          _fetchPlainScalar();
+        } else {
+          _fetchBlockEntry();
+        }
+        return;
+      case QUESTION:
+        if (_isPlainCharAt(1)) {
+          _fetchPlainScalar();
+        } else {
+          _fetchKey();
+        }
+        return;
+      case COLON:
+        if (!_inBlockContext && _tokens.isNotEmpty) {
+          // If a colon follows a "JSON-like" value (an explicit map or list, or
+          // a quoted string) it isn't required to have whitespace after it
+          // since it unambiguously describes a map.
+          var token = _tokens.last;
+          if (token.type == TokenType.flowSequenceEnd ||
+              token.type == TokenType.flowMappingEnd ||
+              (token.type == TokenType.scalar &&
+                  (token as ScalarToken).style.isQuoted)) {
+            _fetchValue();
+            return;
+          }
+        }
+
+        if (_isPlainCharAt(1)) {
+          _fetchPlainScalar();
+        } else {
+          _fetchValue();
+        }
+        return;
+      default:
+        if (!_isNonBreak) _invalidScalarCharacter();
+
+        _fetchPlainScalar();
+        return;
+    }
+  }
+
+  /// Throws an error about a disallowed character.
+  void _invalidScalarCharacter() =>
+      _scanner.error('Unexpected character.', length: 1);
+
+  /// Checks the list of potential simple keys and remove the positions that
+  /// cannot contain simple keys anymore.
+  void _staleSimpleKeys() {
+    for (var i = 0; i < _simpleKeys.length; i++) {
+      var key = _simpleKeys[i];
+      if (key == null) continue;
+
+      // libyaml requires that all simple keys be a single line and no longer
+      // than 1024 characters. However, in section 7.4.2 of the spec
+      // (http://yaml.org/spec/1.2/spec.html#id2790832), these restrictions are
+      // only applied when the curly braces are omitted. It's difficult to
+      // retain enough context to know which keys need to have the restriction
+      // placed on them, so for now we go the other direction and allow
+      // everything but multiline simple keys in a block context.
+      if (!_inBlockContext) continue;
+
+      if (key.line == _scanner.line) continue;
+
+      if (key.required) {
+        _reportError(YamlException("Expected ':'.", _scanner.emptySpan));
+        _tokens.insert(key.tokenNumber - _tokensParsed,
+            Token(TokenType.key, key.location.pointSpan() as FileSpan));
+      }
+
+      _simpleKeys[i] = null;
+    }
+  }
+
+  /// Checks if a simple key may start at the current position and saves it if
+  /// so.
+  void _saveSimpleKey() {
+    // A simple key is required at the current position if the scanner is in the
+    // block context and the current column coincides with the indentation
+    // level.
+    var required = _inBlockContext && _indent == _scanner.column;
+
+    // A simple key is required only when it is the first token in the current
+    // line. Therefore it is always allowed. But we add a check anyway.
+    assert(_simpleKeyAllowed || !required);
+
+    if (!_simpleKeyAllowed) return;
+
+    // If the current position may start a simple key, save it.
+    _removeSimpleKey();
+    _simpleKeys[_simpleKeys.length - 1] = _SimpleKey(
+        _tokensParsed + _tokens.length,
+        _scanner.line,
+        _scanner.column,
+        _scanner.location,
+        required: required);
+  }
+
+  /// Removes a potential simple key at the current flow level.
+  void _removeSimpleKey() {
+    var key = _simpleKeys.last;
+    if (key != null && key.required) {
+      throw YamlException("Could not find expected ':' for simple key.",
+          key.location.pointSpan());
+    }
+
+    _simpleKeys[_simpleKeys.length - 1] = null;
+  }
+
+  /// Increases the flow level and resizes the simple key list.
+  void _increaseFlowLevel() {
+    _simpleKeys.add(null);
+  }
+
+  /// Decreases the flow level.
+  void _decreaseFlowLevel() {
+    if (_inBlockContext) return;
+    _simpleKeys.removeLast();
+  }
+
+  /// Pushes the current indentation level to the stack and sets the new level
+  /// if [column] is greater than [_indent].
+  ///
+  /// If it is, appends or inserts the specified token into [_tokens]. If
+  /// [tokenNumber] is provided, the corresponding token will be replaced;
+  /// otherwise, the token will be added at the end.
+  void _rollIndent(int column, TokenType type, SourceLocation location,
+      {int? tokenNumber}) {
+    if (!_inBlockContext) return;
+    if (_indent != -1 && _indent >= column) return;
+
+    // Push the current indentation level to the stack and set the new
+    // indentation level.
+    _indents.add(column);
+
+    // Create a token and insert it into the queue.
+    var token = Token(type, location.pointSpan() as FileSpan);
+    if (tokenNumber == null) {
+      _tokens.add(token);
+    } else {
+      _tokens.insert(tokenNumber - _tokensParsed, token);
+    }
+  }
+
+  /// Pops indentation levels from [_indents] until the current level becomes
+  /// less than or equal to [column].
+  ///
+  /// For each indentation level, appends a [TokenType.blockEnd] token.
+  void _unrollIndent(int column) {
+    if (!_inBlockContext) return;
+
+    while (_indent > column) {
+      _tokens.add(Token(TokenType.blockEnd, _scanner.emptySpan));
+      _indents.removeLast();
+    }
+  }
+
+  /// Pops indentation levels from [_indents] until the current level resets to
+  /// -1.
+  ///
+  /// For each indentation level, appends a [TokenType.blockEnd] token.
+  void _resetIndent() => _unrollIndent(-1);
+
+  /// Produces a [TokenType.streamStart] token.
+  void _fetchStreamStart() {
+    // Much of libyaml's initialization logic here is done in variable
+    // initializers instead.
+    _streamStartProduced = true;
+    _tokens.add(Token(TokenType.streamStart, _scanner.emptySpan));
+  }
+
+  /// Produces a [TokenType.streamEnd] token.
+  void _fetchStreamEnd() {
+    _resetIndent();
+    _removeSimpleKey();
+    _simpleKeyAllowed = false;
+    _tokens.add(Token(TokenType.streamEnd, _scanner.emptySpan));
+  }
+
+  /// Produces a [TokenType.versionDirective] or [TokenType.tagDirective]
+  /// token.
+  void _fetchDirective() {
+    _resetIndent();
+    _removeSimpleKey();
+    _simpleKeyAllowed = false;
+    var directive = _scanDirective();
+    if (directive != null) _tokens.add(directive);
+  }
+
+  /// Produces a [TokenType.documentStart] or [TokenType.documentEnd] token.
+  void _fetchDocumentIndicator(TokenType type) {
+    _resetIndent();
+    _removeSimpleKey();
+    _simpleKeyAllowed = false;
+
+    // Consume the indicator token.
+    var start = _scanner.state;
+    _scanner.readCodePoint();
+    _scanner.readCodePoint();
+    _scanner.readCodePoint();
+
+    _tokens.add(Token(type, _scanner.spanFrom(start)));
+  }
+
+  /// Produces a [TokenType.flowSequenceStart] or
+  /// [TokenType.flowMappingStart] token.
+  void _fetchFlowCollectionStart(TokenType type) {
+    _saveSimpleKey();
+    _increaseFlowLevel();
+    _simpleKeyAllowed = true;
+    _addCharToken(type);
+  }
+
+  /// Produces a [TokenType.flowSequenceEnd] or [TokenType.flowMappingEnd]
+  /// token.
+  void _fetchFlowCollectionEnd(TokenType type) {
+    _removeSimpleKey();
+    _decreaseFlowLevel();
+    _simpleKeyAllowed = false;
+    _addCharToken(type);
+  }
+
+  /// Produces a [TokenType.flowEntry] token.
+  void _fetchFlowEntry() {
+    _removeSimpleKey();
+    _simpleKeyAllowed = true;
+    _addCharToken(TokenType.flowEntry);
+  }
+
+  /// Produces a [TokenType.blockEntry] token.
+  void _fetchBlockEntry() {
+    if (_inBlockContext) {
+      if (!_simpleKeyAllowed) {
+        throw YamlException(
+            'Block sequence entries are not allowed here.', _scanner.emptySpan);
+      }
+
+      _rollIndent(
+          _scanner.column, TokenType.blockSequenceStart, _scanner.location);
+    } else {
+      // It is an error for the '-' indicator to occur in the flow context, but
+      // we let the Parser detect and report it because it's able to point to
+      // the context.
+    }
+
+    _removeSimpleKey();
+    _simpleKeyAllowed = true;
+    _addCharToken(TokenType.blockEntry);
+  }
+
+  /// Produces the [TokenType.key] token.
+  void _fetchKey() {
+    if (_inBlockContext) {
+      if (!_simpleKeyAllowed) {
+        throw YamlException(
+            'Mapping keys are not allowed here.', _scanner.emptySpan);
+      }
+
+      _rollIndent(
+          _scanner.column, TokenType.blockMappingStart, _scanner.location);
+    }
+
+    // Simple keys are allowed after `?` in a block context.
+    _simpleKeyAllowed = _inBlockContext;
+    _addCharToken(TokenType.key);
+  }
+
+  /// Produces the [TokenType.value] token.
+  void _fetchValue() {
+    var simpleKey = _simpleKeys.last;
+    if (simpleKey != null) {
+      // Add a [TokenType.KEY] directive before the first token of the simple
+      // key so the parser knows that it's part of a key/value pair.
+      _tokens.insert(simpleKey.tokenNumber - _tokensParsed,
+          Token(TokenType.key, simpleKey.location.pointSpan() as FileSpan));
+
+      // In the block context, we may need to add the
+      // [TokenType.BLOCK_MAPPING_START] token.
+      _rollIndent(
+          simpleKey.column, TokenType.blockMappingStart, simpleKey.location,
+          tokenNumber: simpleKey.tokenNumber);
+
+      // Remove the simple key.
+      _simpleKeys[_simpleKeys.length - 1] = null;
+
+      // A simple key cannot follow another simple key.
+      _simpleKeyAllowed = false;
+    } else if (_inBlockContext) {
+      if (!_simpleKeyAllowed) {
+        throw YamlException(
+            'Mapping values are not allowed here. Did you miss a colon '
+            'earlier?',
+            _scanner.emptySpan);
+      }
+
+      // If we're here, we've found the ':' indicator following a complex key.
+
+      _rollIndent(
+          _scanner.column, TokenType.blockMappingStart, _scanner.location);
+      _simpleKeyAllowed = true;
+    } else if (_simpleKeyAllowed) {
+      // If we're here, we've found the ':' indicator with an empty key. This
+      // behavior differs from libyaml, which disallows empty implicit keys.
+      _simpleKeyAllowed = false;
+      _addCharToken(TokenType.key);
+    }
+
+    _addCharToken(TokenType.value);
+  }
+
+  /// Adds a token with [type] to [_tokens].
+  ///
+  /// The span of the new token is the current character.
+  void _addCharToken(TokenType type) {
+    var start = _scanner.state;
+    _scanner.readCodePoint();
+    _tokens.add(Token(type, _scanner.spanFrom(start)));
+  }
+
+  /// Produces a [TokenType.alias] or [TokenType.anchor] token.
+  void _fetchAnchor({bool anchor = true}) {
+    _saveSimpleKey();
+    _simpleKeyAllowed = false;
+    _tokens.add(_scanAnchor(anchor: anchor));
+  }
+
+  /// Produces a [TokenType.tag] token.
+  void _fetchTag() {
+    _saveSimpleKey();
+    _simpleKeyAllowed = false;
+    _tokens.add(_scanTag());
+  }
+
+  /// Produces a [TokenType.scalar] token with style [ScalarStyle.LITERAL] or
+  /// [ScalarStyle.FOLDED].
+  void _fetchBlockScalar({bool literal = false}) {
+    _removeSimpleKey();
+    _simpleKeyAllowed = true;
+    _tokens.add(_scanBlockScalar(literal: literal));
+  }
+
+  /// Produces a [TokenType.scalar] token with style [ScalarStyle.SINGLE_QUOTED]
+  /// or [ScalarStyle.DOUBLE_QUOTED].
+  void _fetchFlowScalar({bool singleQuote = false}) {
+    _saveSimpleKey();
+    _simpleKeyAllowed = false;
+    _tokens.add(_scanFlowScalar(singleQuote: singleQuote));
+  }
+
+  /// Produces a [TokenType.scalar] token with style [ScalarStyle.PLAIN].
+  void _fetchPlainScalar() {
+    _saveSimpleKey();
+    _simpleKeyAllowed = false;
+    _tokens.add(_scanPlainScalar());
+  }
+
+  /// Eats whitespace and comments until the next token is found.
+  void _scanToNextToken() {
+    var afterLineBreak = false;
+    while (true) {
+      // Allow the BOM to start a line.
+      if (_scanner.column == 0) _scanner.scan('\uFEFF');
+
+      // Eat whitespace.
+      //
+      // libyaml disallows tabs after "-", "?", or ":", but the spec allows
+      // them. See section 6.2: http://yaml.org/spec/1.2/spec.html#id2778241.
+      while (_scanner.peekChar() == SP ||
+          ((!_inBlockContext || !afterLineBreak) &&
+              _scanner.peekChar() == TAB)) {
+        _scanner.readChar();
+      }
+
+      if (_scanner.peekChar() == TAB) {
+        _scanner.error('Tab characters are not allowed as indentation.',
+            length: 1);
+      }
+
+      // Eat a comment until a line break.
+      _skipComment();
+
+      // If we're at a line break, eat it.
+      if (_isBreak) {
+        _skipLine();
+
+        // In the block context, a new line may start a simple key.
+        if (_inBlockContext) _simpleKeyAllowed = true;
+        afterLineBreak = true;
+      } else {
+        // Otherwise we've found a token.
+        break;
+      }
+    }
+  }
+
+  /// Scans a [TokenType.versionDirective] or [TokenType.tagDirective] token.
+  ///
+  ///     %YAML    1.2    # a comment \n
+  ///     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+  ///     %TAG    !yaml!  tag:yaml.org,2002:  \n
+  ///     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+  Token? _scanDirective() {
+    var start = _scanner.state;
+
+    // Eat '%'.
+    _scanner.readChar();
+
+    Token token;
+    var name = _scanDirectiveName();
+    if (name == 'YAML') {
+      token = _scanVersionDirectiveValue(start);
+    } else if (name == 'TAG') {
+      token = _scanTagDirectiveValue(start);
+    } else {
+      warn('Warning: unknown directive.', _scanner.spanFrom(start));
+
+      // libyaml doesn't support unknown directives, but the spec says to ignore
+      // them and warn: http://yaml.org/spec/1.2/spec.html#id2781147.
+      while (!_isBreakOrEnd) {
+        _scanner.readCodePoint();
+      }
+
+      return null;
+    }
+
+    // Eat the rest of the line, including any comments.
+    _skipBlanks();
+    _skipComment();
+
+    if (!_isBreakOrEnd) {
+      throw YamlException('Expected comment or line break after directive.',
+          _scanner.spanFrom(start));
+    }
+
+    _skipLine();
+    return token;
+  }
+
+  /// Scans a directive name.
+  ///
+  ///      %YAML   1.2     # a comment \n
+  ///       ^^^^
+  ///      %TAG    !yaml!  tag:yaml.org,2002:  \n
+  ///       ^^^
+  String _scanDirectiveName() {
+    // libyaml only allows word characters in directive names, but the spec
+    // disagrees: http://yaml.org/spec/1.2/spec.html#ns-directive-name.
+    var start = _scanner.position;
+    while (_isNonSpace) {
+      _scanner.readCodePoint();
+    }
+
+    var name = _scanner.substring(start);
+    if (name.isEmpty) {
+      throw YamlException('Expected directive name.', _scanner.emptySpan);
+    } else if (!_isBlankOrEnd) {
+      throw YamlException(
+          'Unexpected character in directive name.', _scanner.emptySpan);
+    }
+
+    return name;
+  }
+
+  /// Scans the value of a version directive.
+  ///
+  ///      %YAML   1.2     # a comment \n
+  ///           ^^^^^^
+  Token _scanVersionDirectiveValue(LineScannerState start) {
+    _skipBlanks();
+
+    var major = _scanVersionDirectiveNumber();
+    _scanner.expect('.');
+    var minor = _scanVersionDirectiveNumber();
+
+    return VersionDirectiveToken(_scanner.spanFrom(start), major, minor);
+  }
+
+  /// Scans the version number of a version directive.
+  ///
+  ///      %YAML   1.2     # a comment \n
+  ///              ^
+  ///      %YAML   1.2     # a comment \n
+  ///                ^
+  int _scanVersionDirectiveNumber() {
+    var start = _scanner.position;
+    while (_isDigit) {
+      _scanner.readChar();
+    }
+
+    var number = _scanner.substring(start);
+    if (number.isEmpty) {
+      throw YamlException('Expected version number.', _scanner.emptySpan);
+    }
+
+    return int.parse(number);
+  }
+
+  /// Scans the value of a tag directive.
+  ///
+  ///      %TAG    !yaml!  tag:yaml.org,2002:  \n
+  ///          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+  Token _scanTagDirectiveValue(LineScannerState start) {
+    _skipBlanks();
+
+    var handle = _scanTagHandle(directive: true);
+    if (!_isBlank) {
+      throw YamlException('Expected whitespace.', _scanner.emptySpan);
+    }
+
+    _skipBlanks();
+
+    var prefix = _scanTagUri();
+    if (!_isBlankOrEnd) {
+      throw YamlException('Expected whitespace.', _scanner.emptySpan);
+    }
+
+    return TagDirectiveToken(_scanner.spanFrom(start), handle, prefix);
+  }
+
+  /// Scans a [TokenType.anchor] token.
+  Token _scanAnchor({bool anchor = true}) {
+    var start = _scanner.state;
+
+    // Eat the indicator character.
+    _scanner.readCodePoint();
+
+    // libyaml only allows word characters in anchor names, but the spec
+    // disagrees: http://yaml.org/spec/1.2/spec.html#ns-anchor-char.
+    var startPosition = _scanner.position;
+    while (_isAnchorChar) {
+      _scanner.readCodePoint();
+    }
+    var name = _scanner.substring(startPosition);
+
+    var next = _scanner.peekChar();
+    if (name.isEmpty ||
+        (!_isBlankOrEnd &&
+            next != QUESTION &&
+            next != COLON &&
+            next != COMMA &&
+            next != RIGHT_SQUARE &&
+            next != RIGHT_CURLY &&
+            next != PERCENT &&
+            next != AT &&
+            next != GRAVE_ACCENT)) {
+      throw YamlException(
+          'Expected alphanumeric character.', _scanner.emptySpan);
+    }
+
+    if (anchor) {
+      return AnchorToken(_scanner.spanFrom(start), name);
+    } else {
+      return AliasToken(_scanner.spanFrom(start), name);
+    }
+  }
+
+  /// Scans a [TokenType.tag] token.
+  Token _scanTag() {
+    String? handle;
+    String suffix;
+    var start = _scanner.state;
+
+    // Check if the tag is in the canonical form.
+    if (_scanner.peekChar(1) == LEFT_ANGLE) {
+      // Eat '!<'.
+      _scanner.readChar();
+      _scanner.readChar();
+
+      handle = '';
+      suffix = _scanTagUri();
+
+      _scanner.expect('>');
+    } else {
+      // The tag has either the '!suffix' or the '!handle!suffix' form.
+
+      // First, try to scan a handle.
+      handle = _scanTagHandle();
+
+      if (handle.length > 1 && handle.startsWith('!') && handle.endsWith('!')) {
+        suffix = _scanTagUri(flowSeparators: false);
+      } else {
+        suffix = _scanTagUri(head: handle, flowSeparators: false);
+
+        // There was no explicit handle.
+        if (suffix.isEmpty) {
+          // This is the special '!' tag.
+          handle = null;
+          suffix = '!';
+        } else {
+          handle = '!';
+        }
+      }
+    }
+
+    // libyaml insists on whitespace after a tag, but example 7.2 indicates
+    // that it's not required: http://yaml.org/spec/1.2/spec.html#id2786720.
+
+    return TagToken(_scanner.spanFrom(start), handle, suffix);
+  }
+
+  /// Scans a tag handle.
+  String _scanTagHandle({bool directive = false}) {
+    _scanner.expect('!');
+
+    var buffer = StringBuffer('!');
+
+    // libyaml only allows word characters in tags, but the spec disagrees:
+    // http://yaml.org/spec/1.2/spec.html#ns-tag-char.
+    var start = _scanner.position;
+    while (_isTagChar) {
+      _scanner.readChar();
+    }
+    buffer.write(_scanner.substring(start));
+
+    if (_scanner.peekChar() == EXCLAMATION) {
+      buffer.writeCharCode(_scanner.readCodePoint());
+    } else {
+      // It's either the '!' tag or not really a tag handle. If it's a %TAG
+      // directive, it's an error. If it's a tag token, it must be part of a
+      // URI.
+      if (directive && buffer.toString() != '!') _scanner.expect('!');
+    }
+
+    return buffer.toString();
+  }
+
+  /// Scans a tag URI.
+  ///
+  /// [head] is the initial portion of the tag that's already been scanned.
+  /// [flowSeparators] indicates whether the tag URI can contain flow
+  /// separators.
+  String _scanTagUri({String? head, bool flowSeparators = true}) {
+    var length = head == null ? 0 : head.length;
+    var buffer = StringBuffer();
+
+    // Copy the head if needed.
+    //
+    // Note that we don't copy the leading '!' character.
+    if (length > 1) buffer.write(head!.substring(1));
+
+    // The set of characters that may appear in URI is as follows:
+    //
+    //      '0'-'9', 'A'-'Z', 'a'-'z', '_', '-', ';', '/', '?', ':', '@', '&',
+    //      '=', '+', '$', ',', '.', '!', '~', '*', '\'', '(', ')', '[', ']',
+    //      '%'.
+    //
+    // In a shorthand tag annotation, the flow separators ',', '[', and ']' are
+    // disallowed.
+    var start = _scanner.position;
+    var char = _scanner.peekChar();
+    while (_isTagChar ||
+        (flowSeparators &&
+            (char == COMMA || char == LEFT_SQUARE || char == RIGHT_SQUARE))) {
+      _scanner.readChar();
+      char = _scanner.peekChar();
+    }
+
+    // libyaml manually decodes the URL, but we don't have to do that.
+    return Uri.decodeFull(_scanner.substring(start));
+  }
+
+  /// Scans a block scalar.
+  Token _scanBlockScalar({bool literal = false}) {
+    var start = _scanner.state;
+
+    // Eat the indicator '|' or '>'.
+    _scanner.readCodePoint();
+
+    // Check for a chomping indicator.
+    var chomping = _Chomping.clip;
+    var increment = 0;
+    var char = _scanner.peekChar();
+    if (char == PLUS || char == HYPHEN) {
+      chomping = char == PLUS ? _Chomping.keep : _Chomping.strip;
+      _scanner.readCodePoint();
+
+      // Check for an indentation indicator.
+      if (_isDigit) {
+        // Check that the indentation is greater than 0.
+        if (_scanner.peekChar() == NUMBER_0) {
+          throw YamlException('0 may not be used as an indentation indicator.',
+              _scanner.spanFrom(start));
+        }
+
+        increment = _scanner.readCodePoint() - NUMBER_0;
+      }
+    } else if (_isDigit) {
+      // Do the same as above, but in the opposite order.
+      if (_scanner.peekChar() == NUMBER_0) {
+        throw YamlException('0 may not be used as an indentation indicator.',
+            _scanner.spanFrom(start));
+      }
+
+      increment = _scanner.readCodePoint() - NUMBER_0;
+
+      char = _scanner.peekChar();
+      if (char == PLUS || char == HYPHEN) {
+        chomping = char == PLUS ? _Chomping.keep : _Chomping.strip;
+        _scanner.readCodePoint();
+      }
+    }
+
+    // Eat whitespace and comments to the end of the line.
+    _skipBlanks();
+    _skipComment();
+
+    // Check if we're at the end of the line.
+    if (!_isBreakOrEnd) {
+      throw YamlException(
+          'Expected comment or line break.', _scanner.emptySpan);
+    }
+
+    _skipLine();
+
+    // If the block scalar has an explicit indentation indicator, add that to
+    // the current indentation to get the indentation level for the scalar's
+    // contents.
+    var indent = 0;
+    if (increment != 0) {
+      indent = _indent >= 0 ? _indent + increment : increment;
+    }
+
+    // Scan the leading line breaks to determine the indentation level if
+    // needed.
+    var pair = _scanBlockScalarBreaks(indent);
+    indent = pair.indent;
+    var trailingBreaks = pair.trailingBreaks;
+
+    // Scan the block scalar contents.
+    var buffer = StringBuffer();
+    var leadingBreak = '';
+    var leadingBlank = false;
+    var trailingBlank = false;
+    var end = _scanner.state;
+    while (_scanner.column == indent && !_scanner.isDone) {
+      // Check for a document indicator. libyaml doesn't do this, but the spec
+      // mandates it. See example 9.5:
+      // http://yaml.org/spec/1.2/spec.html#id2801606.
+      if (_isDocumentIndicator) break;
+
+      // We are at the beginning of a non-empty line.
+
+      // Is there trailing whitespace?
+      trailingBlank = _isBlank;
+
+      // Check if we need to fold the leading line break.
+      if (!literal &&
+          leadingBreak.isNotEmpty &&
+          !leadingBlank &&
+          !trailingBlank) {
+        // Do we need to join the lines with a space?
+        if (trailingBreaks.isEmpty) buffer.writeCharCode(SP);
+      } else {
+        buffer.write(leadingBreak);
+      }
+      leadingBreak = '';
+
+      // Append the remaining line breaks.
+      buffer.write(trailingBreaks);
+
+      // Is there leading whitespace?
+      leadingBlank = _isBlank;
+
+      var startPosition = _scanner.position;
+      while (!_isBreakOrEnd) {
+        _scanner.readCodePoint();
+      }
+      buffer.write(_scanner.substring(startPosition));
+      end = _scanner.state;
+
+      // libyaml always reads a line here, but this breaks on block scalars at
+      // the end of the document that end without newlines. See example 8.1:
+      // http://yaml.org/spec/1.2/spec.html#id2793888.
+      if (!_scanner.isDone) leadingBreak = _readLine();
+
+      // Eat the following indentation and spaces.
+      var pair = _scanBlockScalarBreaks(indent);
+      indent = pair.indent;
+      trailingBreaks = pair.trailingBreaks;
+    }
+
+    // Chomp the tail.
+    if (chomping != _Chomping.strip) buffer.write(leadingBreak);
+    if (chomping == _Chomping.keep) buffer.write(trailingBreaks);
+
+    return ScalarToken(_scanner.spanFrom(start, end), buffer.toString(),
+        literal ? ScalarStyle.LITERAL : ScalarStyle.FOLDED);
+  }
+
+  /// Scans indentation spaces and line breaks for a block scalar.
+  ///
+  /// Determines the intendation level if needed. Returns the new indentation
+  /// level and the text of the line breaks.
+  ({int indent, String trailingBreaks}) _scanBlockScalarBreaks(int indent) {
+    var maxIndent = 0;
+    var breaks = StringBuffer();
+
+    while (true) {
+      while ((indent == 0 || _scanner.column < indent) &&
+          _scanner.peekChar() == SP) {
+        _scanner.readChar();
+      }
+
+      if (_scanner.column > maxIndent) maxIndent = _scanner.column;
+
+      // libyaml throws an error here if a tab character is detected, but the
+      // spec treats tabs like any other non-space character. See example 8.2:
+      // http://yaml.org/spec/1.2/spec.html#id2794311.
+
+      if (!_isBreak) break;
+      breaks.write(_readLine());
+    }
+
+    if (indent == 0) {
+      indent = maxIndent;
+      if (indent < _indent + 1) indent = _indent + 1;
+
+      // libyaml forces indent to be at least 1 here, but that doesn't seem to
+      // be supported by the spec.
+    }
+
+    return (indent: indent, trailingBreaks: breaks.toString());
+  }
+
+  // Scans a quoted scalar.
+  Token _scanFlowScalar({bool singleQuote = false}) {
+    var start = _scanner.state;
+    var buffer = StringBuffer();
+
+    // Eat the left quote.
+    _scanner.readChar();
+
+    while (true) {
+      // Check that there are no document indicators at the beginning of the
+      // line.
+      if (_isDocumentIndicator) {
+        _scanner.error('Unexpected document indicator.');
+      }
+
+      if (_scanner.isDone) {
+        throw YamlException('Unexpected end of file.', _scanner.emptySpan);
+      }
+
+      var leadingBlanks = false;
+      while (!_isBlankOrEnd) {
+        var char = _scanner.peekChar();
+        if (singleQuote &&
+            char == SINGLE_QUOTE &&
+            _scanner.peekChar(1) == SINGLE_QUOTE) {
+          // An escaped single quote.
+          _scanner.readChar();
+          _scanner.readChar();
+          buffer.writeCharCode(SINGLE_QUOTE);
+        } else if (char == (singleQuote ? SINGLE_QUOTE : DOUBLE_QUOTE)) {
+          // The closing quote.
+          break;
+        } else if (!singleQuote && char == BACKSLASH && _isBreakAt(1)) {
+          // An escaped newline.
+          _scanner.readChar();
+          _skipLine();
+          leadingBlanks = true;
+          break;
+        } else if (!singleQuote && char == BACKSLASH) {
+          var escapeStart = _scanner.state;
+
+          // An escape sequence.
+          int? codeLength;
+          switch (_scanner.peekChar(1)) {
+            case NUMBER_0:
+              buffer.writeCharCode(NULL);
+              break;
+            case LETTER_A:
+              buffer.writeCharCode(BELL);
+              break;
+            case LETTER_B:
+              buffer.writeCharCode(BACKSPACE);
+              break;
+            case LETTER_T:
+            case TAB:
+              buffer.writeCharCode(TAB);
+              break;
+            case LETTER_N:
+              buffer.writeCharCode(LF);
+              break;
+            case LETTER_V:
+              buffer.writeCharCode(VERTICAL_TAB);
+              break;
+            case LETTER_F:
+              buffer.writeCharCode(FORM_FEED);
+              break;
+            case LETTER_R:
+              buffer.writeCharCode(CR);
+              break;
+            case LETTER_E:
+              buffer.writeCharCode(ESCAPE);
+              break;
+            case SP:
+            case DOUBLE_QUOTE:
+            case SLASH:
+            case BACKSLASH:
+              // libyaml doesn't support an escaped forward slash, but it was
+              // added in YAML 1.2. See section 5.7:
+              // http://yaml.org/spec/1.2/spec.html#id2776092
+              buffer.writeCharCode(_scanner.peekChar(1)!);
+              break;
+            case LETTER_CAP_N:
+              buffer.writeCharCode(NEL);
+              break;
+            case UNDERSCORE:
+              buffer.writeCharCode(NBSP);
+              break;
+            case LETTER_CAP_L:
+              buffer.writeCharCode(LINE_SEPARATOR);
+              break;
+            case LETTER_CAP_P:
+              buffer.writeCharCode(PARAGRAPH_SEPARATOR);
+              break;
+            case LETTER_X:
+              codeLength = 2;
+              break;
+            case LETTER_U:
+              codeLength = 4;
+              break;
+            case LETTER_CAP_U:
+              codeLength = 8;
+              break;
+            default:
+              throw YamlException(
+                  'Unknown escape character.', _scanner.spanFrom(escapeStart));
+          }
+
+          _scanner.readChar();
+          _scanner.readChar();
+
+          if (codeLength != null) {
+            var value = 0;
+            for (var i = 0; i < codeLength; i++) {
+              if (!_isHex) {
+                _scanner.readChar();
+                throw YamlException(
+                    'Expected $codeLength-digit hexidecimal number.',
+                    _scanner.spanFrom(escapeStart));
+              }
+
+              value = (value << 4) + _asHex(_scanner.readChar());
+            }
+
+            // Check the value and write the character.
+            if ((value >= 0xD800 && value <= 0xDFFF) || value > 0x10FFFF) {
+              throw YamlException('Invalid Unicode character escape code.',
+                  _scanner.spanFrom(escapeStart));
+            }
+
+            buffer.writeCharCode(value);
+          }
+        } else {
+          buffer.writeCharCode(_scanner.readCodePoint());
+        }
+      }
+
+      // Check if we're at the end of a scalar.
+      if (_scanner.peekChar() == (singleQuote ? SINGLE_QUOTE : DOUBLE_QUOTE)) {
+        break;
+      }
+
+      var whitespace = StringBuffer();
+      var leadingBreak = '';
+      var trailingBreaks = StringBuffer();
+      while (_isBlank || _isBreak) {
+        if (_isBlank) {
+          // Consume a space or a tab.
+          if (!leadingBlanks) {
+            whitespace.writeCharCode(_scanner.readChar());
+          } else {
+            _scanner.readChar();
+          }
+        } else {
+          // Check if it's a first line break.
+          if (!leadingBlanks) {
+            whitespace.clear();
+            leadingBreak = _readLine();
+            leadingBlanks = true;
+          } else {
+            trailingBreaks.write(_readLine());
+          }
+        }
+      }
+
+      // Join the whitespace or fold line breaks.
+      if (leadingBlanks) {
+        if (leadingBreak.isNotEmpty && trailingBreaks.isEmpty) {
+          buffer.writeCharCode(SP);
+        } else {
+          buffer.write(trailingBreaks);
+        }
+      } else {
+        buffer.write(whitespace);
+        whitespace.clear();
+      }
+    }
+
+    // Eat the right quote.
+    _scanner.readChar();
+
+    return ScalarToken(_scanner.spanFrom(start), buffer.toString(),
+        singleQuote ? ScalarStyle.SINGLE_QUOTED : ScalarStyle.DOUBLE_QUOTED);
+  }
+
+  /// Scans a plain scalar.
+  Token _scanPlainScalar() {
+    var start = _scanner.state;
+    var end = _scanner.state;
+    var buffer = StringBuffer();
+    var leadingBreak = '';
+    var trailingBreaks = '';
+    var whitespace = StringBuffer();
+    var indent = _indent + 1;
+
+    while (true) {
+      // Check for a document indicator.
+      if (_isDocumentIndicator) break;
+
+      // Check for a comment.
+      if (_scanner.peekChar() == HASH) break;
+
+      if (_isPlainChar) {
+        // Join the whitespace or fold line breaks.
+        if (leadingBreak.isNotEmpty) {
+          if (trailingBreaks.isEmpty) {
+            buffer.writeCharCode(SP);
+          } else {
+            buffer.write(trailingBreaks);
+          }
+          leadingBreak = '';
+          trailingBreaks = '';
+        } else {
+          buffer.write(whitespace);
+          whitespace.clear();
+        }
+      }
+
+      // libyaml's notion of valid identifiers differs substantially from YAML
+      // 1.2's. We use [_isPlainChar] instead of libyaml's character here.
+      var startPosition = _scanner.position;
+      while (_isPlainChar) {
+        _scanner.readCodePoint();
+      }
+      buffer.write(_scanner.substring(startPosition));
+      end = _scanner.state;
+
+      // Is it the end?
+      if (!_isBlank && !_isBreak) break;
+
+      while (_isBlank || _isBreak) {
+        if (_isBlank) {
+          // Check for a tab character messing up the intendation.
+          if (leadingBreak.isNotEmpty &&
+              _scanner.column < indent &&
+              _scanner.peekChar() == TAB) {
+            _scanner.error('Expected a space but found a tab.', length: 1);
+          }
+
+          if (leadingBreak.isEmpty) {
+            whitespace.writeCharCode(_scanner.readChar());
+          } else {
+            _scanner.readChar();
+          }
+        } else {
+          // Check if it's a first line break.
+          if (leadingBreak.isEmpty) {
+            leadingBreak = _readLine();
+            whitespace.clear();
+          } else {
+            trailingBreaks = _readLine();
+          }
+        }
+      }
+
+      // Check the indentation level.
+      if (_inBlockContext && _scanner.column < indent) break;
+    }
+
+    // Allow a simple key after a plain scalar with leading blanks.
+    if (leadingBreak.isNotEmpty) _simpleKeyAllowed = true;
+
+    return ScalarToken(
+        _scanner.spanFrom(start, end), buffer.toString(), ScalarStyle.PLAIN);
+  }
+
+  /// Moves past the current line break, if there is one.
+  void _skipLine() {
+    var char = _scanner.peekChar();
+    if (char != CR && char != LF) return;
+    _scanner.readChar();
+    if (char == CR && _scanner.peekChar() == LF) _scanner.readChar();
+  }
+
+  // Moves past the current line break and returns a newline.
+  String _readLine() {
+    var char = _scanner.peekChar();
+
+    // libyaml supports NEL, PS, and LS characters as line separators, but this
+    // is explicitly forbidden in section 5.4 of the YAML spec.
+    if (char != CR && char != LF) {
+      throw YamlException('Expected newline.', _scanner.emptySpan);
+    }
+
+    _scanner.readChar();
+    // CR LF | CR | LF -> LF
+    if (char == CR && _scanner.peekChar() == LF) _scanner.readChar();
+    return '\n';
+  }
+
+  // Returns whether the character at [offset] is whitespace.
+  bool _isBlankAt(int offset) {
+    var char = _scanner.peekChar(offset);
+    return char == SP || char == TAB;
+  }
+
+  // Returns whether the character at [offset] is a line break.
+  bool _isBreakAt(int offset) {
+    // Libyaml considers NEL, LS, and PS to be line breaks as well, but that's
+    // contrary to the spec.
+    var char = _scanner.peekChar(offset);
+    return char == CR || char == LF;
+  }
+
+  // Returns whether the character at [offset] is whitespace or past the end of
+  // the source.
+  bool _isBlankOrEndAt(int offset) {
+    var char = _scanner.peekChar(offset);
+    return char == null ||
+        char == SP ||
+        char == TAB ||
+        char == CR ||
+        char == LF;
+  }
+
+  /// Returns whether the character at [offset] is a plain character.
+  ///
+  /// See http://yaml.org/spec/1.2/spec.html#ns-plain-char(c).
+  bool _isPlainCharAt(int offset) {
+    switch (_scanner.peekChar(offset)) {
+      case COLON:
+        return _isPlainSafeAt(offset + 1);
+      case HASH:
+        var previous = _scanner.peekChar(offset - 1);
+        return previous != SP && previous != TAB;
+      default:
+        return _isPlainSafeAt(offset);
+    }
+  }
+
+  /// Returns whether the character at [offset] is a plain-safe character.
+  ///
+  /// See http://yaml.org/spec/1.2/spec.html#ns-plain-safe(c).
+  bool _isPlainSafeAt(int offset) {
+    var char = _scanner.peekChar(offset);
+    return switch (char) {
+      null => false,
+      COMMA ||
+      LEFT_SQUARE ||
+      RIGHT_SQUARE ||
+      LEFT_CURLY ||
+      RIGHT_CURLY =>
+        // These characters are delimiters in a flow context and thus are only
+        // safe in a block context.
+        _inBlockContext,
+      SP || TAB || LF || CR || BOM => false,
+      NEL => true,
+      _ => _isStandardCharacterAt(offset)
+    };
+  }
+
+  bool _isStandardCharacterAt(int offset) {
+    var first = _scanner.peekChar(offset);
+    if (first == null) return false;
+
+    if (isHighSurrogate(first)) {
+      var next = _scanner.peekChar(offset + 1);
+      // A surrogate pair encodes code points from U+010000 to U+10FFFF, so it
+      // must be a standard character.
+      return next != null && isLowSurrogate(next);
+    }
+
+    return _isStandardCharacter(first);
+  }
+
+  bool _isStandardCharacter(int char) =>
+      (char >= 0x0020 && char <= 0x007E) ||
+      (char >= 0x00A0 && char <= 0xD7FF) ||
+      (char >= 0xE000 && char <= 0xFFFD);
+
+  /// Returns the hexidecimal value of [char].
+  int _asHex(int char) {
+    if (char <= NUMBER_9) return char - NUMBER_0;
+    if (char <= LETTER_CAP_F) return 10 + char - LETTER_CAP_A;
+    return 10 + char - LETTER_A;
+  }
+
+  /// Moves the scanner past any blank characters.
+  void _skipBlanks() {
+    while (_isBlank) {
+      _scanner.readChar();
+    }
+  }
+
+  /// Moves the scanner past a comment, if one starts at the current position.
+  void _skipComment() {
+    if (_scanner.peekChar() != HASH) return;
+    while (!_isBreakOrEnd) {
+      _scanner.readChar();
+    }
+  }
+
+  /// Reports a [YamlException] to [_errorListener] if [_recover] is true,
+  /// otherwise throws the exception.
+  void _reportError(YamlException exception) {
+    if (!_recover) {
+      throw exception;
+    }
+    _errorListener?.onError(exception);
+  }
+}
+
+/// A record of the location of a potential simple key.
+class _SimpleKey {
+  /// The index of the token that begins the simple key.
+  ///
+  /// This is the index relative to all tokens emitted, rather than relative to
+  /// [location].
+  final int tokenNumber;
+
+  /// The source location of the beginning of the simple key.
+  ///
+  /// This is used for error reporting and for determining when a simple key is
+  /// no longer on the current line.
+  final SourceLocation location;
+
+  /// The line on which the key appears.
+  ///
+  /// We could get this from [location], but that requires a binary search
+  /// whereas this is O(1).
+  final int line;
+
+  /// The column on which the key appears.
+  ///
+  /// We could get this from [location], but that requires a binary search
+  /// whereas this is O(1).
+  final int column;
+
+  /// Whether this key must exist for the document to be scanned.
+  final bool required;
+
+  _SimpleKey(
+    this.tokenNumber,
+    this.line,
+    this.column,
+    this.location, {
+    required this.required,
+  });
+}
+
+/// The ways to handle trailing whitespace for a block scalar.
+///
+/// See http://yaml.org/spec/1.2/spec.html#id2794534.
+enum _Chomping {
+  /// All trailing whitespace is discarded.
+  strip,
+
+  /// A single trailing newline is retained.
+  clip,
+
+  /// All trailing whitespace is preserved.
+  keep
+}
diff --git a/pkgs/yaml/lib/src/style.dart b/pkgs/yaml/lib/src/style.dart
new file mode 100644
index 0000000..96c3b94
--- /dev/null
+++ b/pkgs/yaml/lib/src/style.dart
@@ -0,0 +1,79 @@
+// Copyright (c) 2014, the Dart project authors.
+// Copyright (c) 2006, Kirill Simonov.
+//
+// Use of this source code is governed by an MIT-style
+// license that can be found in the LICENSE file or at
+// https://opensource.org/licenses/MIT.
+
+// ignore_for_file: constant_identifier_names
+
+import 'yaml_node.dart';
+
+/// An enum of source scalar styles.
+class ScalarStyle {
+  /// No source style was specified.
+  ///
+  /// This usually indicates a scalar constructed with [YamlScalar.wrap].
+  static const ANY = ScalarStyle._('ANY');
+
+  /// The plain scalar style, unquoted and without a prefix.
+  ///
+  /// See http://yaml.org/spec/1.2/spec.html#style/flow/plain.
+  static const PLAIN = ScalarStyle._('PLAIN');
+
+  /// The literal scalar style, with a `|` prefix.
+  ///
+  /// See http://yaml.org/spec/1.2/spec.html#id2795688.
+  static const LITERAL = ScalarStyle._('LITERAL');
+
+  /// The folded scalar style, with a `>` prefix.
+  ///
+  /// See http://yaml.org/spec/1.2/spec.html#id2796251.
+  static const FOLDED = ScalarStyle._('FOLDED');
+
+  /// The single-quoted scalar style.
+  ///
+  /// See http://yaml.org/spec/1.2/spec.html#style/flow/single-quoted.
+  static const SINGLE_QUOTED = ScalarStyle._('SINGLE_QUOTED');
+
+  /// The double-quoted scalar style.
+  ///
+  /// See http://yaml.org/spec/1.2/spec.html#style/flow/double-quoted.
+  static const DOUBLE_QUOTED = ScalarStyle._('DOUBLE_QUOTED');
+
+  final String name;
+
+  /// Whether this is a quoted style ([SINGLE_QUOTED] or [DOUBLE_QUOTED]).
+  bool get isQuoted => this == SINGLE_QUOTED || this == DOUBLE_QUOTED;
+
+  const ScalarStyle._(this.name);
+
+  @override
+  String toString() => name;
+}
+
+/// An enum of collection styles.
+class CollectionStyle {
+  /// No source style was specified.
+  ///
+  /// This usually indicates a collection constructed with [YamlList.wrap] or
+  /// [YamlMap.wrap].
+  static const ANY = CollectionStyle._('ANY');
+
+  /// The indentation-based block style.
+  ///
+  /// See http://yaml.org/spec/1.2/spec.html#id2797293.
+  static const BLOCK = CollectionStyle._('BLOCK');
+
+  /// The delimiter-based block style.
+  ///
+  /// See http://yaml.org/spec/1.2/spec.html#id2790088.
+  static const FLOW = CollectionStyle._('FLOW');
+
+  final String name;
+
+  const CollectionStyle._(this.name);
+
+  @override
+  String toString() => name;
+}
diff --git a/pkgs/yaml/lib/src/token.dart b/pkgs/yaml/lib/src/token.dart
new file mode 100644
index 0000000..7d5d6bc
--- /dev/null
+++ b/pkgs/yaml/lib/src/token.dart
@@ -0,0 +1,158 @@
+// Copyright (c) 2014, the Dart project authors.
+// Copyright (c) 2006, Kirill Simonov.
+//
+// Use of this source code is governed by an MIT-style
+// license that can be found in the LICENSE file or at
+// https://opensource.org/licenses/MIT.
+
+import 'package:source_span/source_span.dart';
+
+import 'scanner.dart';
+import 'style.dart';
+
+/// A token emitted by a [Scanner].
+class Token {
+  final TokenType type;
+  final FileSpan span;
+
+  Token(this.type, this.span);
+
+  @override
+  String toString() => type.toString();
+}
+
+/// A token representing a `%YAML` directive.
+class VersionDirectiveToken implements Token {
+  @override
+  TokenType get type => TokenType.versionDirective;
+  @override
+  final FileSpan span;
+
+  /// The declared major version of the document.
+  final int major;
+
+  /// The declared minor version of the document.
+  final int minor;
+
+  VersionDirectiveToken(this.span, this.major, this.minor);
+
+  @override
+  String toString() => 'VERSION_DIRECTIVE $major.$minor';
+}
+
+/// A token representing a `%TAG` directive.
+class TagDirectiveToken implements Token {
+  @override
+  TokenType get type => TokenType.tagDirective;
+  @override
+  final FileSpan span;
+
+  /// The tag handle used in the document.
+  final String handle;
+
+  /// The tag prefix that the handle maps to.
+  final String prefix;
+
+  TagDirectiveToken(this.span, this.handle, this.prefix);
+
+  @override
+  String toString() => 'TAG_DIRECTIVE $handle $prefix';
+}
+
+/// A token representing an anchor (`&foo`).
+class AnchorToken implements Token {
+  @override
+  TokenType get type => TokenType.anchor;
+  @override
+  final FileSpan span;
+
+  final String name;
+
+  AnchorToken(this.span, this.name);
+
+  @override
+  String toString() => 'ANCHOR $name';
+}
+
+/// A token representing an alias (`*foo`).
+class AliasToken implements Token {
+  @override
+  TokenType get type => TokenType.alias;
+  @override
+  final FileSpan span;
+
+  final String name;
+
+  AliasToken(this.span, this.name);
+
+  @override
+  String toString() => 'ALIAS $name';
+}
+
+/// A token representing a tag (`!foo`).
+class TagToken implements Token {
+  @override
+  TokenType get type => TokenType.tag;
+  @override
+  final FileSpan span;
+
+  /// The tag handle for named tags.
+  final String? handle;
+
+  /// The tag suffix.
+  final String suffix;
+
+  TagToken(this.span, this.handle, this.suffix);
+
+  @override
+  String toString() => 'TAG $handle $suffix';
+}
+
+/// A scalar value.
+class ScalarToken implements Token {
+  @override
+  TokenType get type => TokenType.scalar;
+  @override
+  final FileSpan span;
+
+  /// The unparsed contents of the value..
+  final String value;
+
+  /// The style of the scalar in the original source.
+  final ScalarStyle style;
+
+  ScalarToken(this.span, this.value, this.style);
+
+  @override
+  String toString() => 'SCALAR $style "$value"';
+}
+
+/// The types of [Token] objects.
+enum TokenType {
+  streamStart,
+  streamEnd,
+
+  versionDirective,
+  tagDirective,
+  documentStart,
+  documentEnd,
+
+  blockSequenceStart,
+  blockMappingStart,
+  blockEnd,
+
+  flowSequenceStart,
+  flowSequenceEnd,
+  flowMappingStart,
+  flowMappingEnd,
+
+  blockEntry,
+  flowEntry,
+  key,
+  value,
+
+  alias,
+  anchor,
+  tag,
+  scalar
+}
diff --git a/pkgs/yaml/lib/src/utils.dart b/pkgs/yaml/lib/src/utils.dart
new file mode 100644
index 0000000..0dc132f
--- /dev/null
+++ b/pkgs/yaml/lib/src/utils.dart
@@ -0,0 +1,40 @@
+// Copyright (c) 2013, the Dart project authors.
+// Copyright (c) 2006, Kirill Simonov.
+//
+// Use of this source code is governed by an MIT-style
+// license that can be found in the LICENSE file or at
+// https://opensource.org/licenses/MIT.
+
+import 'package:source_span/source_span.dart';
+
+/// Print a warning.
+///
+/// If [span] is passed, associates the warning with that span.
+void warn(String message, [SourceSpan? span]) =>
+    yamlWarningCallback(message, span);
+
+/// A callback for emitting a warning.
+///
+/// [message] is the text of the warning. If [span] is passed, it's the portion
+/// of the document that the warning is associated with and should be included
+/// in the printed warning.
+typedef YamlWarningCallback = void Function(String message, [SourceSpan? span]);
+
+/// A callback for emitting a warning.
+///
+/// In a very few cases, the YAML spec indicates that an implementation should
+/// emit a warning. To do so, it calls this callback. The default implementation
+/// prints a message using [print].
+// ignore: prefer_function_declarations_over_variables
+YamlWarningCallback yamlWarningCallback = (message, [SourceSpan? span]) {
+  // TODO(nweiz): Print to stderr with color when issue 6943 is fixed and
+  // dart:io is available.
+  if (span != null) message = span.message(message);
+  print(message);
+};
+
+/// Whether [codeUnit] is a UTF-16 high surrogate.
+bool isHighSurrogate(int codeUnit) => codeUnit >>> 10 == 0x36;
+
+/// Whether [codeUnit] is a UTF-16 low surrogate.
+bool isLowSurrogate(int codeUnit) => codeUnit >>> 10 == 0x37;
diff --git a/pkgs/yaml/lib/src/yaml_document.dart b/pkgs/yaml/lib/src/yaml_document.dart
new file mode 100644
index 0000000..da6aa1e
--- /dev/null
+++ b/pkgs/yaml/lib/src/yaml_document.dart
@@ -0,0 +1,71 @@
+// Copyright (c) 2014, the Dart project authors.
+// Copyright (c) 2006, Kirill Simonov.
+//
+// Use of this source code is governed by an MIT-style
+// license that can be found in the LICENSE file or at
+// https://opensource.org/licenses/MIT.
+
+import 'dart:collection';
+
+import 'package:source_span/source_span.dart';
+
+import 'yaml_node.dart';
+
+/// A YAML document, complete with metadata.
+class YamlDocument {
+  /// The contents of the document.
+  final YamlNode contents;
+
+  /// The span covering the entire document.
+  final SourceSpan span;
+
+  /// The version directive for the document, if any.
+  final VersionDirective? versionDirective;
+
+  /// The tag directives for the document.
+  final List<TagDirective> tagDirectives;
+
+  /// Whether the beginning of the document was implicit (versus explicit via
+  /// `===`).
+  final bool startImplicit;
+
+  /// Whether the end of the document was implicit (versus explicit via `...`).
+  final bool endImplicit;
+
+  /// Users of the library should not use this constructor.
+  YamlDocument.internal(this.contents, this.span, this.versionDirective,
+      List<TagDirective> tagDirectives,
+      {this.startImplicit = false, this.endImplicit = false})
+      : tagDirectives = UnmodifiableListView(tagDirectives);
+
+  @override
+  String toString() => contents.toString();
+}
+
+/// A directive indicating which version of YAML a document was written to.
+class VersionDirective {
+  /// The major version number.
+  final int major;
+
+  /// The minor version number.
+  final int minor;
+
+  VersionDirective(this.major, this.minor);
+
+  @override
+  String toString() => '%YAML $major.$minor';
+}
+
+/// A directive describing a custom tag handle.
+class TagDirective {
+  /// The handle for use in the document.
+  final String handle;
+
+  /// The prefix that the handle maps to.
+  final String prefix;
+
+  TagDirective(this.handle, this.prefix);
+
+  @override
+  String toString() => '%TAG $handle $prefix';
+}
diff --git a/pkgs/yaml/lib/src/yaml_exception.dart b/pkgs/yaml/lib/src/yaml_exception.dart
new file mode 100644
index 0000000..7aa5389
--- /dev/null
+++ b/pkgs/yaml/lib/src/yaml_exception.dart
@@ -0,0 +1,13 @@
+// Copyright (c) 2013, the Dart project authors.
+// Copyright (c) 2006, Kirill Simonov.
+//
+// Use of this source code is governed by an MIT-style
+// license that can be found in the LICENSE file or at
+// https://opensource.org/licenses/MIT.
+
+import 'package:source_span/source_span.dart';
+
+/// An error thrown by the YAML processor.
+class YamlException extends SourceSpanFormatException {
+  YamlException(super.message, super.span);
+}
diff --git a/pkgs/yaml/lib/src/yaml_node.dart b/pkgs/yaml/lib/src/yaml_node.dart
new file mode 100644
index 0000000..bd17b6c
--- /dev/null
+++ b/pkgs/yaml/lib/src/yaml_node.dart
@@ -0,0 +1,191 @@
+// Copyright (c) 2012, the Dart project authors.
+// Copyright (c) 2006, Kirill Simonov.
+//
+// Use of this source code is governed by an MIT-style
+// license that can be found in the LICENSE file or at
+// https://opensource.org/licenses/MIT.
+
+import 'dart:collection' as collection;
+
+import 'package:collection/collection.dart';
+import 'package:source_span/source_span.dart';
+
+import 'event.dart';
+import 'null_span.dart';
+import 'style.dart';
+import 'yaml_node_wrapper.dart';
+
+/// An interface for parsed nodes from a YAML source tree.
+///
+/// [YamlMap]s and [YamlList]s implement this interface in addition to the
+/// normal [Map] and [List] interfaces, so any maps and lists will be
+/// [YamlNode]s regardless of how they're accessed.
+///
+/// Scalars values like strings and numbers, on the other hand, don't have this
+/// interface by default. Instead, they can be accessed as [YamlScalar]s via
+/// [YamlMap.nodes] or [YamlList.nodes].
+abstract class YamlNode {
+  /// The source span for this node.
+  ///
+  /// [SourceSpan.message] can be used to produce a human-friendly message about
+  /// this node.
+  SourceSpan get span => _span;
+  SourceSpan _span;
+
+  YamlNode._(this._span);
+
+  /// The inner value of this node.
+  ///
+  /// For [YamlScalar]s, this will return the wrapped value. For [YamlMap] and
+  /// [YamlList], it will return `this`, since they already implement [Map] and
+  /// [List], respectively.
+  dynamic get value;
+}
+
+/// A read-only [Map] parsed from YAML.
+class YamlMap extends YamlNode with collection.MapMixin, UnmodifiableMapMixin {
+  /// A view of `this` where the keys and values are guaranteed to be
+  /// [YamlNode]s.
+  ///
+  /// The key type is `dynamic` to allow values to be accessed using
+  /// non-[YamlNode] keys, but [Map.keys] and [Map.forEach] will always expose
+  /// them as [YamlNode]s. For example, for `{"foo": [1, 2, 3]}` [nodes] will be
+  /// a map from a [YamlScalar] to a [YamlList], but since the key type is
+  /// `dynamic` `map.nodes["foo"]` will still work.
+  final Map<dynamic, YamlNode> nodes;
+
+  /// The style used for the map in the original document.
+  final CollectionStyle style;
+
+  @override
+  Map get value => this;
+
+  @override
+  Iterable get keys => nodes.keys.map((node) => (node as YamlNode).value);
+
+  /// Creates an empty YamlMap.
+  ///
+  /// This map's [span] won't have useful location information. However, it will
+  /// have a reasonable implementation of [SourceSpan.message]. If [sourceUrl]
+  /// is passed, it's used as the [SourceSpan.sourceUrl].
+  ///
+  /// [sourceUrl] may be either a [String], a [Uri], or `null`.
+  factory YamlMap({Object? sourceUrl}) => YamlMapWrapper(const {}, sourceUrl);
+
+  /// Wraps a Dart map so that it can be accessed (recursively) like a
+  /// [YamlMap].
+  ///
+  /// Any [SourceSpan]s returned by this map or its children will be dummies
+  /// without useful location information. However, they will have a reasonable
+  /// implementation of [SourceSpan.message]. If [sourceUrl] is
+  /// passed, it's used as the [SourceSpan.sourceUrl].
+  ///
+  /// [sourceUrl] may be either a [String], a [Uri], or `null`.
+  factory YamlMap.wrap(Map dartMap,
+          {Object? sourceUrl, CollectionStyle style = CollectionStyle.ANY}) =>
+      YamlMapWrapper(dartMap, sourceUrl, style: style);
+
+  /// Users of the library should not use this constructor.
+  YamlMap.internal(Map<dynamic, YamlNode> nodes, super.span, this.style)
+      : nodes = UnmodifiableMapView<dynamic, YamlNode>(nodes),
+        super._();
+
+  @override
+  dynamic operator [](Object? key) => nodes[key]?.value;
+}
+
+// TODO(nweiz): Use UnmodifiableListMixin when issue 18970 is fixed.
+/// A read-only [List] parsed from YAML.
+class YamlList extends YamlNode with collection.ListMixin {
+  final List<YamlNode> nodes;
+
+  /// The style used for the list in the original document.
+  final CollectionStyle style;
+
+  @override
+  List get value => this;
+
+  @override
+  int get length => nodes.length;
+
+  @override
+  set length(int index) {
+    throw UnsupportedError('Cannot modify an unmodifiable List');
+  }
+
+  /// Creates an empty YamlList.
+  ///
+  /// This list's [span] won't have useful location information. However, it
+  /// will have a reasonable implementation of [SourceSpan.message]. If
+  /// [sourceUrl] is passed, it's used as the [SourceSpan.sourceUrl].
+  ///
+  /// [sourceUrl] may be either a [String], a [Uri], or `null`.
+  factory YamlList({Object? sourceUrl}) => YamlListWrapper(const [], sourceUrl);
+
+  /// Wraps a Dart list so that it can be accessed (recursively) like a
+  /// [YamlList].
+  ///
+  /// Any [SourceSpan]s returned by this list or its children will be dummies
+  /// without useful location information. However, they will have a reasonable
+  /// implementation of [SourceSpan.message]. If [sourceUrl] is
+  /// passed, it's used as the [SourceSpan.sourceUrl].
+  ///
+  /// [sourceUrl] may be either a [String], a [Uri], or `null`.
+  factory YamlList.wrap(List dartList,
+          {Object? sourceUrl, CollectionStyle style = CollectionStyle.ANY}) =>
+      YamlListWrapper(dartList, sourceUrl, style: style);
+
+  /// Users of the library should not use this constructor.
+  YamlList.internal(List<YamlNode> nodes, super.span, this.style)
+      : nodes = UnmodifiableListView<YamlNode>(nodes),
+        super._();
+
+  @override
+  dynamic operator [](int index) => nodes[index].value;
+
+  @override
+  void operator []=(int index, Object? value) {
+    throw UnsupportedError('Cannot modify an unmodifiable List');
+  }
+}
+
+/// A wrapped scalar value parsed from YAML.
+class YamlScalar extends YamlNode {
+  @override
+  final dynamic value;
+
+  /// The style used for the scalar in the original document.
+  final ScalarStyle style;
+
+  /// Wraps a Dart value in a [YamlScalar].
+  ///
+  /// This scalar's [span] won't have useful location information. However, it
+  /// will have a reasonable implementation of [SourceSpan.message]. If
+  /// [sourceUrl] is passed, it's used as the [SourceSpan.sourceUrl].
+  ///
+  /// [sourceUrl] may be either a [String], a [Uri], or `null`.
+  YamlScalar.wrap(this.value, {Object? sourceUrl, this.style = ScalarStyle.ANY})
+      : super._(NullSpan(sourceUrl)) {
+    ArgumentError.checkNotNull(style, 'style');
+  }
+
+  /// Users of the library should not use this constructor.
+  YamlScalar.internal(this.value, ScalarEvent scalar)
+      : style = scalar.style,
+        super._(scalar.span);
+
+  /// Users of the library should not use this constructor.
+  YamlScalar.internalWithSpan(this.value, SourceSpan span)
+      : style = ScalarStyle.ANY,
+        super._(span);
+
+  @override
+  String toString() => value.toString();
+}
+
+/// Sets the source span of a [YamlNode].
+///
+/// This method is not exposed publicly.
+void setSpan(YamlNode node, SourceSpan span) {
+  node._span = span;
+}
diff --git a/pkgs/yaml/lib/src/yaml_node_wrapper.dart b/pkgs/yaml/lib/src/yaml_node_wrapper.dart
new file mode 100644
index 0000000..5250844
--- /dev/null
+++ b/pkgs/yaml/lib/src/yaml_node_wrapper.dart
@@ -0,0 +1,189 @@
+// Copyright (c) 2014, the Dart project authors.
+// Copyright (c) 2006, Kirill Simonov.
+//
+// Use of this source code is governed by an MIT-style
+// license that can be found in the LICENSE file or at
+// https://opensource.org/licenses/MIT.
+
+import 'dart:collection';
+
+import 'package:collection/collection.dart' as pkg_collection;
+import 'package:source_span/source_span.dart';
+
+import 'null_span.dart';
+import 'style.dart';
+import 'yaml_node.dart';
+
+/// A wrapper that makes a normal Dart map behave like a [YamlMap].
+class YamlMapWrapper extends MapBase
+    with pkg_collection.UnmodifiableMapMixin
+    implements YamlMap {
+  @override
+  final CollectionStyle style;
+
+  final Map _dartMap;
+
+  @override
+  final SourceSpan span;
+
+  @override
+  final Map<dynamic, YamlNode> nodes;
+
+  @override
+  Map get value => this;
+
+  @override
+  Iterable get keys => _dartMap.keys;
+
+  YamlMapWrapper(Map dartMap, Object? sourceUrl,
+      {CollectionStyle style = CollectionStyle.ANY})
+      : this._(dartMap, NullSpan(sourceUrl), style: style);
+
+  YamlMapWrapper._(Map dartMap, this.span, {this.style = CollectionStyle.ANY})
+      : _dartMap = dartMap,
+        nodes = _YamlMapNodes(dartMap, span) {
+    ArgumentError.checkNotNull(style, 'style');
+  }
+
+  @override
+  dynamic operator [](Object? key) {
+    var value = _dartMap[key];
+    if (value is Map) return YamlMapWrapper._(value, span);
+    if (value is List) return YamlListWrapper._(value, span);
+    return value;
+  }
+
+  @override
+  int get hashCode => _dartMap.hashCode;
+
+  @override
+  bool operator ==(Object other) =>
+      other is YamlMapWrapper && other._dartMap == _dartMap;
+}
+
+/// The implementation of [YamlMapWrapper.nodes] as a wrapper around the Dart
+/// map.
+class _YamlMapNodes extends MapBase<dynamic, YamlNode>
+    with pkg_collection.UnmodifiableMapMixin<dynamic, YamlNode> {
+  final Map _dartMap;
+
+  final SourceSpan _span;
+
+  @override
+  Iterable get keys =>
+      _dartMap.keys.map((key) => YamlScalar.internalWithSpan(key, _span));
+
+  _YamlMapNodes(this._dartMap, this._span);
+
+  @override
+  YamlNode? operator [](Object? key) {
+    // Use "as" here because key being assigned to invalidates type propagation.
+    if (key is YamlScalar) key = key.value;
+    if (!_dartMap.containsKey(key)) return null;
+    return _nodeForValue(_dartMap[key], _span);
+  }
+
+  @override
+  int get hashCode => _dartMap.hashCode;
+
+  @override
+  bool operator ==(Object other) =>
+      other is _YamlMapNodes && other._dartMap == _dartMap;
+}
+
+// TODO(nweiz): Use UnmodifiableListMixin when issue 18970 is fixed.
+/// A wrapper that makes a normal Dart list behave like a [YamlList].
+class YamlListWrapper extends ListBase implements YamlList {
+  @override
+  final CollectionStyle style;
+
+  final List _dartList;
+
+  @override
+  final SourceSpan span;
+
+  @override
+  final List<YamlNode> nodes;
+
+  @override
+  List get value => this;
+
+  @override
+  int get length => _dartList.length;
+
+  @override
+  set length(int index) {
+    throw UnsupportedError('Cannot modify an unmodifiable List.');
+  }
+
+  YamlListWrapper(List dartList, Object? sourceUrl,
+      {CollectionStyle style = CollectionStyle.ANY})
+      : this._(dartList, NullSpan(sourceUrl), style: style);
+
+  YamlListWrapper._(List dartList, this.span,
+      {this.style = CollectionStyle.ANY})
+      : _dartList = dartList,
+        nodes = _YamlListNodes(dartList, span) {
+    ArgumentError.checkNotNull(style, 'style');
+  }
+
+  @override
+  dynamic operator [](int index) {
+    var value = _dartList[index];
+    if (value is Map) return YamlMapWrapper._(value, span);
+    if (value is List) return YamlListWrapper._(value, span);
+    return value;
+  }
+
+  @override
+  void operator []=(int index, Object? value) {
+    throw UnsupportedError('Cannot modify an unmodifiable List.');
+  }
+
+  @override
+  int get hashCode => _dartList.hashCode;
+
+  @override
+  bool operator ==(Object other) =>
+      other is YamlListWrapper && other._dartList == _dartList;
+}
+
+// TODO(nweiz): Use UnmodifiableListMixin when issue 18970 is fixed.
+/// The implementation of [YamlListWrapper.nodes] as a wrapper around the Dart
+/// list.
+class _YamlListNodes extends ListBase<YamlNode> {
+  final List _dartList;
+
+  final SourceSpan _span;
+
+  @override
+  int get length => _dartList.length;
+
+  @override
+  set length(int index) {
+    throw UnsupportedError('Cannot modify an unmodifiable List.');
+  }
+
+  _YamlListNodes(this._dartList, this._span);
+
+  @override
+  YamlNode operator [](int index) => _nodeForValue(_dartList[index], _span);
+
+  @override
+  void operator []=(int index, Object? value) {
+    throw UnsupportedError('Cannot modify an unmodifiable List.');
+  }
+
+  @override
+  int get hashCode => _dartList.hashCode;
+
+  @override
+  bool operator ==(Object other) =>
+      other is _YamlListNodes && other._dartList == _dartList;
+}
+
+YamlNode _nodeForValue(Object? value, SourceSpan span) {
+  if (value is Map) return YamlMapWrapper._(value, span);
+  if (value is List) return YamlListWrapper._(value, span);
+  return YamlScalar.internalWithSpan(value, span);
+}
diff --git a/pkgs/yaml/lib/yaml.dart b/pkgs/yaml/lib/yaml.dart
new file mode 100644
index 0000000..26cc9b8
--- /dev/null
+++ b/pkgs/yaml/lib/yaml.dart
@@ -0,0 +1,126 @@
+// Copyright (c) 2012, the Dart project authors.
+// Copyright (c) 2006, Kirill Simonov.
+//
+// Use of this source code is governed by an MIT-style
+// license that can be found in the LICENSE file or at
+// https://opensource.org/licenses/MIT.
+
+import 'src/error_listener.dart';
+import 'src/loader.dart';
+import 'src/style.dart';
+import 'src/yaml_document.dart';
+import 'src/yaml_exception.dart';
+import 'src/yaml_node.dart';
+
+export 'src/style.dart';
+export 'src/utils.dart' show YamlWarningCallback, yamlWarningCallback;
+export 'src/yaml_document.dart';
+export 'src/yaml_exception.dart';
+export 'src/yaml_node.dart' hide setSpan;
+
+/// Loads a single document from a YAML string.
+///
+/// If the string contains more than one document, this throws a
+/// [YamlException]. In future releases, this will become an [ArgumentError].
+///
+/// The return value is mostly normal Dart objects. However, since YAML mappings
+/// support some key types that the default Dart map implementation doesn't
+/// (NaN, lists, and maps), all maps in the returned document are [YamlMap]s.
+/// These have a few small behavioral differences from the default Map
+/// implementation; for details, see the [YamlMap] class.
+///
+/// If [sourceUrl] is passed, it's used as the URL from which the YAML
+/// originated for error reporting.
+///
+/// If [recover] is true, will attempt to recover from parse errors and may
+/// return invalid or synthetic nodes. If [errorListener] is also supplied, its
+/// onError method will be called for each error recovered from. It is not valid
+/// to provide [errorListener] if [recover] is false.
+dynamic loadYaml(String yaml,
+        {Uri? sourceUrl, bool recover = false, ErrorListener? errorListener}) =>
+    loadYamlNode(yaml,
+            sourceUrl: sourceUrl,
+            recover: recover,
+            errorListener: errorListener)
+        .value;
+
+/// Loads a single document from a YAML string as a [YamlNode].
+///
+/// This is just like [loadYaml], except that where [loadYaml] would return a
+/// normal Dart value this returns a [YamlNode] instead. This allows the caller
+/// to be confident that the return value will always be a [YamlNode].
+YamlNode loadYamlNode(String yaml,
+        {Uri? sourceUrl, bool recover = false, ErrorListener? errorListener}) =>
+    loadYamlDocument(yaml,
+            sourceUrl: sourceUrl,
+            recover: recover,
+            errorListener: errorListener)
+        .contents;
+
+/// Loads a single document from a YAML string as a [YamlDocument].
+///
+/// This is just like [loadYaml], except that where [loadYaml] would return a
+/// normal Dart value this returns a [YamlDocument] instead. This allows the
+/// caller to access document metadata.
+YamlDocument loadYamlDocument(String yaml,
+    {Uri? sourceUrl, bool recover = false, ErrorListener? errorListener}) {
+  var loader = Loader(yaml,
+      sourceUrl: sourceUrl, recover: recover, errorListener: errorListener);
+  var document = loader.load();
+  if (document == null) {
+    return YamlDocument.internal(YamlScalar.internalWithSpan(null, loader.span),
+        loader.span, null, const []);
+  }
+
+  var nextDocument = loader.load();
+  if (nextDocument != null) {
+    throw YamlException('Only expected one document.', nextDocument.span);
+  }
+
+  return document;
+}
+
+/// Loads a stream of documents from a YAML string.
+///
+/// The return value is mostly normal Dart objects. However, since YAML mappings
+/// support some key types that the default Dart map implementation doesn't
+/// (NaN, lists, and maps), all maps in the returned document are [YamlMap]s.
+/// These have a few small behavioral differences from the default Map
+/// implementation; for details, see the [YamlMap] class.
+///
+/// If [sourceUrl] is passed, it's used as the URL from which the YAML
+/// originated for error reporting.
+YamlList loadYamlStream(String yaml, {Uri? sourceUrl}) {
+  var loader = Loader(yaml, sourceUrl: sourceUrl);
+
+  var documents = <YamlDocument>[];
+  var document = loader.load();
+  while (document != null) {
+    documents.add(document);
+    document = loader.load();
+  }
+
+  // TODO(jmesserly): the type on the `document` parameter is a workaround for:
+  // https://github.com/dart-lang/dev_compiler/issues/203
+  return YamlList.internal(
+      documents.map((YamlDocument document) => document.contents).toList(),
+      loader.span,
+      CollectionStyle.ANY);
+}
+
+/// Loads a stream of documents from a YAML string.
+///
+/// This is like [loadYamlStream], except that it returns [YamlDocument]s with
+/// metadata wrapping the document contents.
+List<YamlDocument> loadYamlDocuments(String yaml, {Uri? sourceUrl}) {
+  var loader = Loader(yaml, sourceUrl: sourceUrl);
+
+  var documents = <YamlDocument>[];
+  var document = loader.load();
+  while (document != null) {
+    documents.add(document);
+    document = loader.load();
+  }
+
+  return documents;
+}
diff --git a/pkgs/yaml/pubspec.yaml b/pkgs/yaml/pubspec.yaml
new file mode 100644
index 0000000..be7d165
--- /dev/null
+++ b/pkgs/yaml/pubspec.yaml
@@ -0,0 +1,20 @@
+name: yaml
+version: 3.1.3-wip
+description: A parser for YAML, a human-friendly data serialization standard
+repository: https://github.com/dart-lang/yaml
+topics:
+ - yaml
+ - config-format
+
+environment:
+  sdk: ^3.4.0
+
+dependencies:
+  collection: ^1.15.0
+  source_span: ^1.8.0
+  string_scanner: ^1.2.0
+
+dev_dependencies:
+  dart_flutter_team_lints: ^3.0.0
+  path: ^1.8.0
+  test: ^1.16.6
diff --git a/pkgs/yaml/test/span_test.dart b/pkgs/yaml/test/span_test.dart
new file mode 100644
index 0000000..03b7f9c
--- /dev/null
+++ b/pkgs/yaml/test/span_test.dart
@@ -0,0 +1,173 @@
+// Copyright (c) 2019, the Dart project authors.
+// Copyright (c) 2006, Kirill Simonov.
+//
+// Use of this source code is governed by an MIT-style
+// license that can be found in the LICENSE file or at
+// https://opensource.org/licenses/MIT.
+
+import 'dart:convert';
+
+import 'package:source_span/source_span.dart';
+import 'package:test/test.dart';
+import 'package:yaml/yaml.dart';
+
+void _expectSpan(SourceSpan source, String expected) {
+  final result = source.message('message');
+  printOnFailure("r'''\n$result'''");
+
+  expect(result, expected);
+}
+
+void main() {
+  late YamlMap yaml;
+
+  setUpAll(() {
+    yaml = loadYaml(const JsonEncoder.withIndent(' ').convert({
+      'num': 42,
+      'nested': {
+        'null': null,
+        'num': 42,
+      },
+      'null': null,
+    })) as YamlMap;
+  });
+
+  test('first root key', () {
+    _expectSpan(
+      yaml.nodes['num']!.span,
+      r'''
+line 2, column 9: message
+  ╷
+2 │  "num": 42,
+  │         ^^
+  ╵''',
+    );
+  });
+
+  test('first root key', () {
+    _expectSpan(
+      yaml.nodes['null']!.span,
+      r'''
+line 7, column 10: message
+  ╷
+7 │  "null": null
+  │          ^^^^
+  ╵''',
+    );
+  });
+
+  group('nested', () {
+    late YamlMap nestedMap;
+
+    setUpAll(() {
+      nestedMap = yaml.nodes['nested'] as YamlMap;
+    });
+
+    test('first root key', () {
+      _expectSpan(
+        nestedMap.nodes['null']!.span,
+        r'''
+line 4, column 11: message
+  ╷
+4 │   "null": null,
+  │           ^^^^
+  ╵''',
+      );
+    });
+
+    test('first root key', () {
+      _expectSpan(
+        nestedMap.nodes['num']!.span,
+        r'''
+line 5, column 10: message
+  ╷
+5 │     "num": 42
+  │ ┌──────────^
+6 │ │  },
+  │ └─^
+  ╵''',
+      );
+    });
+  });
+
+  group('block', () {
+    late YamlList list, nestedList;
+
+    setUpAll(() {
+      const yamlStr = '''
+- foo
+- 
+  - one
+  - 
+  - three
+  - 
+  - five
+  -
+- 
+  a : b
+  c : d
+- bar
+''';
+
+      list = loadYaml(yamlStr) as YamlList;
+      nestedList = list.nodes[1] as YamlList;
+    });
+
+    test('root nodes span', () {
+      _expectSpan(list.nodes[0].span, r'''
+line 1, column 3: message
+  ╷
+1 │ - foo
+  │   ^^^
+  ╵''');
+
+      _expectSpan(list.nodes[1].span, r'''
+line 3, column 3: message
+  ╷
+3 │ ┌   - one
+4 │ │   - 
+5 │ │   - three
+6 │ │   - 
+7 │ │   - five
+8 │ └   -
+  ╵''');
+
+      _expectSpan(list.nodes[2].span, r'''
+line 10, column 3: message
+   ╷
+10 │ ┌   a : b
+11 │ └   c : d
+   ╵''');
+
+      _expectSpan(list.nodes[3].span, r'''
+line 12, column 3: message
+   ╷
+12 │ - bar
+   │   ^^^
+   ╵''');
+    });
+
+    test('null nodes span', () {
+      _expectSpan(nestedList.nodes[1].span, r'''
+line 4, column 3: message
+  ╷
+4 │   - 
+  │   ^
+  ╵''');
+
+      _expectSpan(nestedList.nodes[3].span, r'''
+line 6, column 3: message
+  ╷
+6 │   - 
+  │   ^
+  ╵''');
+
+      _expectSpan(nestedList.nodes[5].span, r'''
+line 8, column 3: message
+  ╷
+8 │   -
+  │   ^
+  ╵''');
+    });
+  });
+}
diff --git a/pkgs/yaml/test/utils.dart b/pkgs/yaml/test/utils.dart
new file mode 100644
index 0000000..372440a
--- /dev/null
+++ b/pkgs/yaml/test/utils.dart
@@ -0,0 +1,95 @@
+// Copyright (c) 2014, the Dart project authors.
+// Copyright (c) 2006, Kirill Simonov.
+//
+// Use of this source code is governed by an MIT-style
+// license that can be found in the LICENSE file or at
+// https://opensource.org/licenses/MIT.
+
+import 'package:test/test.dart';
+import 'package:yaml/src/equality.dart' as equality;
+import 'package:yaml/yaml.dart';
+
+/// A matcher that validates that a closure or Future throws a [YamlException].
+final Matcher throwsYamlException = throwsA(isA<YamlException>());
+
+/// Returns a matcher that asserts that the value equals [expected].
+///
+/// This handles recursive loops and considers `NaN` to equal itself.
+Matcher deepEquals(Object? expected) => predicate(
+    (actual) => equality.deepEquals(actual, expected), 'equals $expected');
+
+/// Constructs a new yaml.YamlMap, optionally from a normal Map.
+Map deepEqualsMap([Map? from]) {
+  var map = equality.deepEqualsMap<Object?, Object?>();
+  if (from != null) map.addAll(from);
+  return map;
+}
+
+/// Asserts that an error has the given message and starts at the given line/col.
+void expectErrorAtLineCol(
+    YamlException error, String message, int line, int col) {
+  expect(error.message, equals(message));
+  expect(error.span!.start.line, equals(line));
+  expect(error.span!.start.column, equals(col));
+}
+
+/// Asserts that a string containing a single YAML document produces a given
+/// value when loaded.
+void expectYamlLoads(Object? expected, String source) {
+  var actual = loadYaml(cleanUpLiteral(source));
+  expect(actual, deepEquals(expected));
+}
+
+/// Asserts that a string containing a stream of YAML documents produces a given
+/// list of values when loaded.
+void expectYamlStreamLoads(List expected, String source) {
+  var actual = loadYamlStream(cleanUpLiteral(source));
+  expect(actual, deepEquals(expected));
+}
+
+/// Asserts that a string containing a single YAML document throws a
+/// [YamlException].
+void expectYamlFails(String source) {
+  expect(() => loadYaml(cleanUpLiteral(source)), throwsYamlException);
+}
+
+/// Removes eight spaces of leading indentation from a multiline string.
+///
+/// Note that this is very sensitive to how the literals are styled. They should
+/// be:
+///     '''
+///     Text starts on own line. Lines up with subsequent lines.
+///     Lines are indented exactly 8 characters from the left margin.
+///     Close is on the same line.'''
+///
+/// This does nothing if text is only a single line.
+String cleanUpLiteral(String text) {
+  var lines = text.split('\n');
+  if (lines.length <= 1) return text;
+
+  for (var j = 0; j < lines.length; j++) {
+    if (lines[j].length > 8) {
+      lines[j] = lines[j].substring(8, lines[j].length);
+    } else {
+      lines[j] = '';
+    }
+  }
+
+  return lines.join('\n');
+}
+
+/// Indents each line of [text] so that, when passed to [cleanUpLiteral], it
+/// will produce output identical to [text].
+///
+/// This is useful for literals that need to include newlines but can't be
+/// conveniently represented as multi-line strings.
+String indentLiteral(String text) {
+  var lines = text.split('\n');
+  if (lines.length <= 1) return text;
+
+  for (var i = 0; i < lines.length; i++) {
+    lines[i] = '        ${lines[i]}';
+  }
+
+  return lines.join('\n');
+}
diff --git a/pkgs/yaml/test/yaml_node_wrapper_test.dart b/pkgs/yaml/test/yaml_node_wrapper_test.dart
new file mode 100644
index 0000000..637b778
--- /dev/null
+++ b/pkgs/yaml/test/yaml_node_wrapper_test.dart
@@ -0,0 +1,235 @@
+// Copyright (c) 2012, the Dart project authors.
+// Copyright (c) 2006, Kirill Simonov.
+//
+// Use of this source code is governed by an MIT-style
+// license that can be found in the LICENSE file or at
+// https://opensource.org/licenses/MIT.
+
+// ignore_for_file: avoid_dynamic_calls
+
+import 'package:source_span/source_span.dart';
+import 'package:test/test.dart';
+import 'package:yaml/yaml.dart';
+
+void main() {
+  test('YamlMap() with no sourceUrl', () {
+    var map = YamlMap();
+    expect(map, isEmpty);
+    expect(map.nodes, isEmpty);
+    expect(map.span, isNullSpan(isNull));
+  });
+
+  test('YamlMap() with a sourceUrl', () {
+    var map = YamlMap(sourceUrl: 'source');
+    expect(map.span, isNullSpan(Uri.parse('source')));
+  });
+
+  test('YamlList() with no sourceUrl', () {
+    var list = YamlList();
+    expect(list, isEmpty);
+    expect(list.nodes, isEmpty);
+    expect(list.span, isNullSpan(isNull));
+  });
+
+  test('YamlList() with a sourceUrl', () {
+    var list = YamlList(sourceUrl: 'source');
+    expect(list.span, isNullSpan(Uri.parse('source')));
+  });
+
+  test('YamlMap.wrap() with no sourceUrl', () {
+    var map = YamlMap.wrap({
+      'list': [1, 2, 3],
+      'map': {
+        'foo': 'bar',
+        'nested': [4, 5, 6]
+      },
+      'scalar': 'value'
+    });
+
+    expect(
+        map,
+        equals({
+          'list': [1, 2, 3],
+          'map': {
+            'foo': 'bar',
+            'nested': [4, 5, 6]
+          },
+          'scalar': 'value'
+        }));
+
+    expect(map.span, isNullSpan(isNull));
+    expect(map['list'], isA<YamlList>());
+    expect(map['list'].nodes[0], isA<YamlScalar>());
+    expect(map['list'].span, isNullSpan(isNull));
+    expect(map['map'], isA<YamlMap>());
+    expect(map['map'].nodes['foo'], isA<YamlScalar>());
+    expect(map['map']['nested'], isA<YamlList>());
+    expect(map['map'].span, isNullSpan(isNull));
+    expect(map.nodes['scalar'], isA<YamlScalar>());
+    expect(map.nodes['scalar']!.value, 'value');
+    expect(map.nodes['scalar']!.span, isNullSpan(isNull));
+    expect(map['scalar'], 'value');
+    expect(map.keys, unorderedEquals(['list', 'map', 'scalar']));
+    expect(map.nodes.keys, everyElement(isA<YamlScalar>()));
+    expect(map.nodes[YamlScalar.wrap('list')], equals([1, 2, 3]));
+    expect(map.style, equals(CollectionStyle.ANY));
+    expect((map.nodes['list'] as YamlList).style, equals(CollectionStyle.ANY));
+    expect((map.nodes['map'] as YamlMap).style, equals(CollectionStyle.ANY));
+    expect((map['map'].nodes['nested'] as YamlList).style,
+        equals(CollectionStyle.ANY));
+  });
+
+  test('YamlMap.wrap() with a sourceUrl', () {
+    var map = YamlMap.wrap({
+      'list': [1, 2, 3],
+      'map': {
+        'foo': 'bar',
+        'nested': [4, 5, 6]
+      },
+      'scalar': 'value'
+    }, sourceUrl: 'source');
+
+    var source = Uri.parse('source');
+    expect(map.span, isNullSpan(source));
+    expect(map['list'].span, isNullSpan(source));
+    expect(map['map'].span, isNullSpan(source));
+    expect(map.nodes['scalar']!.span, isNullSpan(source));
+  });
+
+  test('YamlMap.wrap() with a sourceUrl and style', () {
+    var map = YamlMap.wrap({
+      'list': [1, 2, 3],
+      'map': {
+        'foo': 'bar',
+        'nested': [4, 5, 6]
+      },
+      'scalar': 'value'
+    }, sourceUrl: 'source', style: CollectionStyle.BLOCK);
+
+    expect(map.style, equals(CollectionStyle.BLOCK));
+    expect((map.nodes['list'] as YamlList).style, equals(CollectionStyle.ANY));
+    expect((map.nodes['map'] as YamlMap).style, equals(CollectionStyle.ANY));
+    expect((map['map'].nodes['nested'] as YamlList).style,
+        equals(CollectionStyle.ANY));
+  });
+
+  test('YamlList.wrap() with no sourceUrl', () {
+    var list = YamlList.wrap([
+      [1, 2, 3],
+      {
+        'foo': 'bar',
+        'nested': [4, 5, 6]
+      },
+      'value'
+    ]);
+
+    expect(
+        list,
+        equals([
+          [1, 2, 3],
+          {
+            'foo': 'bar',
+            'nested': [4, 5, 6]
+          },
+          'value'
+        ]));
+
+    expect(list.span, isNullSpan(isNull));
+    expect(list[0], isA<YamlList>());
+    expect(list[0].nodes[0], isA<YamlScalar>());
+    expect(list[0].span, isNullSpan(isNull));
+    expect(list[1], isA<YamlMap>());
+    expect(list[1].nodes['foo'], isA<YamlScalar>());
+    expect(list[1]['nested'], isA<YamlList>());
+    expect(list[1].span, isNullSpan(isNull));
+    expect(list.nodes[2], isA<YamlScalar>());
+    expect(list.nodes[2].value, 'value');
+    expect(list.nodes[2].span, isNullSpan(isNull));
+    expect(list[2], 'value');
+    expect(list.style, equals(CollectionStyle.ANY));
+    expect((list[0] as YamlList).style, equals(CollectionStyle.ANY));
+    expect((list[1] as YamlMap).style, equals(CollectionStyle.ANY));
+    expect((list[1]['nested'] as YamlList).style, equals(CollectionStyle.ANY));
+  });
+
+  test('YamlList.wrap() with a sourceUrl', () {
+    var list = YamlList.wrap([
+      [1, 2, 3],
+      {
+        'foo': 'bar',
+        'nested': [4, 5, 6]
+      },
+      'value'
+    ], sourceUrl: 'source');
+
+    var source = Uri.parse('source');
+    expect(list.span, isNullSpan(source));
+    expect(list[0].span, isNullSpan(source));
+    expect(list[1].span, isNullSpan(source));
+    expect(list.nodes[2].span, isNullSpan(source));
+  });
+
+  test('YamlList.wrap() with a sourceUrl and style', () {
+    var list = YamlList.wrap([
+      [1, 2, 3],
+      {
+        'foo': 'bar',
+        'nested': [4, 5, 6]
+      },
+      'value'
+    ], sourceUrl: 'source', style: CollectionStyle.FLOW);
+
+    expect(list.style, equals(CollectionStyle.FLOW));
+    expect((list[0] as YamlList).style, equals(CollectionStyle.ANY));
+    expect((list[1] as YamlMap).style, equals(CollectionStyle.ANY));
+    expect((list[1]['nested'] as YamlList).style, equals(CollectionStyle.ANY));
+  });
+
+  test('re-wrapped objects equal one another', () {
+    var list = YamlList.wrap([
+      [1, 2, 3],
+      {'foo': 'bar'}
+    ]);
+
+    expect(list[0] == list[0], isTrue);
+    expect(list[0].nodes == list[0].nodes, isTrue);
+    expect(list[0] == YamlList.wrap([1, 2, 3]), isFalse);
+    expect(list[1] == list[1], isTrue);
+    expect(list[1].nodes == list[1].nodes, isTrue);
+    expect(list[1] == YamlMap.wrap({'foo': 'bar'}), isFalse);
+  });
+
+  test('YamlScalar.wrap() with no sourceUrl', () {
+    var scalar = YamlScalar.wrap('foo');
+
+    expect(scalar.span, isNullSpan(isNull));
+    expect(scalar.value, 'foo');
+    expect(scalar.style, equals(ScalarStyle.ANY));
+  });
+
+  test('YamlScalar.wrap() with sourceUrl', () {
+    var scalar = YamlScalar.wrap('foo', sourceUrl: 'source');
+
+    var source = Uri.parse('source');
+    expect(scalar.span, isNullSpan(source));
+  });
+
+  test('YamlScalar.wrap() with sourceUrl and style', () {
+    var scalar = YamlScalar.wrap('foo',
+        sourceUrl: 'source', style: ScalarStyle.DOUBLE_QUOTED);
+
+    expect(scalar.style, equals(ScalarStyle.DOUBLE_QUOTED));
+  });
+}
+
+Matcher isNullSpan(Object sourceUrl) => predicate((SourceSpan span) {
+      expect(span, isA<SourceSpan>());
+      expect(span.length, equals(0));
+      expect(span.text, isEmpty);
+      expect(span.start, equals(span.end));
+      expect(span.start.offset, equals(0));
+      expect(span.start.line, equals(0));
+      expect(span.start.column, equals(0));
+      expect(span.sourceUrl, sourceUrl);
+      return true;
+    });
diff --git a/pkgs/yaml/test/yaml_test.dart b/pkgs/yaml/test/yaml_test.dart
new file mode 100644
index 0000000..3b5b77d
--- /dev/null
+++ b/pkgs/yaml/test/yaml_test.dart
@@ -0,0 +1,1921 @@
+// Copyright (c) 2012, the Dart project authors.
+// Copyright (c) 2006, Kirill Simonov.
+//
+// Use of this source code is governed by an MIT-style
+// license that can be found in the LICENSE file or at
+// https://opensource.org/licenses/MIT.
+
+// ignore_for_file: avoid_dynamic_calls
+
+import 'package:test/test.dart';
+import 'package:yaml/src/error_listener.dart';
+import 'package:yaml/yaml.dart';
+
+import 'utils.dart';
+
+void main() {
+  var infinity = double.parse('Infinity');
+  var nan = double.parse('NaN');
+
+  group('has a friendly error message for', () {
+    var tabError = predicate((e) =>
+        e.toString().contains('Tab characters are not allowed as indentation'));
+
+    test('using a tab as indentation', () {
+      expect(() => loadYaml('foo:\n\tbar'), throwsA(tabError));
+    });
+
+    test('using a tab not as indentation', () {
+      expect(() => loadYaml('''
+          "foo
+          \tbar"
+          error'''), throwsA(isNot(tabError)));
+    });
+  });
+
+  group('refuses', () {
+    // Regression test for #19.
+    test('invalid contents', () {
+      expectYamlFails('{');
+    });
+
+    test('duplicate mapping keys', () {
+      expectYamlFails('{a: 1, a: 2}');
+    });
+
+    group('documents that declare version', () {
+      test('1.0', () {
+        expectYamlFails('''
+         %YAML 1.0
+         --- text
+         ''');
+      });
+
+      test('1.3', () {
+        expectYamlFails('''
+           %YAML 1.3
+           --- text
+           ''');
+      });
+
+      test('2.0', () {
+        expectYamlFails('''
+           %YAML 2.0
+           --- text
+           ''');
+      });
+    });
+  });
+
+  group('recovers', () {
+    var collector = ErrorCollector();
+    setUp(() {
+      collector = ErrorCollector();
+    });
+
+    test('from incomplete leading keys', () {
+      final yaml = cleanUpLiteral(r'''
+        dependencies:
+          zero
+          one: any
+          ''');
+      var result = loadYaml(yaml, recover: true, errorListener: collector);
+      expect(
+          result,
+          deepEquals({
+            'dependencies': {
+              'zero': null,
+              'one': 'any',
+            }
+          }));
+      expect(collector.errors.length, equals(1));
+      // These errors are reported at the start of the next token (after the
+      // whitespace/newlines).
+      expectErrorAtLineCol(collector.errors[0], "Expected ':'.", 2, 2);
+      // Skipped because this case is not currently handled. If it's the first
+      // package without the colon, because the value is indented from the line
+      // above, the whole `zero\n     one` is treated as a scalar value.
+    }, skip: true);
+    test('from incomplete keys', () {
+      final yaml = cleanUpLiteral(r'''
+        dependencies:
+          one: any
+          two
+          three:
+          four
+          five:
+            1.2.3
+          six: 5.4.3
+          ''');
+      var result = loadYaml(yaml, recover: true, errorListener: collector);
+      expect(
+          result,
+          deepEquals({
+            'dependencies': {
+              'one': 'any',
+              'two': null,
+              'three': null,
+              'four': null,
+              'five': '1.2.3',
+              'six': '5.4.3',
+            }
+          }));
+
+      expect(collector.errors.length, equals(2));
+      // These errors are reported at the start of the next token (after the
+      // whitespace/newlines).
+      expectErrorAtLineCol(collector.errors[0], "Expected ':'.", 3, 2);
+      expectErrorAtLineCol(collector.errors[1], "Expected ':'.", 5, 2);
+    });
+    test('from incomplete trailing keys', () {
+      final yaml = cleanUpLiteral(r'''
+        dependencies:
+          six: 5.4.3
+          seven
+          ''');
+      var result = loadYaml(yaml, recover: true);
+      expect(
+          result,
+          deepEquals({
+            'dependencies': {
+              'six': '5.4.3',
+              'seven': null,
+            }
+          }));
+    });
+  });
+
+  test('includes source span information', () {
+    var yaml = loadYamlNode(r'''
+- foo:
+    bar
+- 123
+''') as YamlList;
+
+    expect(yaml.span.start.line, equals(0));
+    expect(yaml.span.start.column, equals(0));
+    expect(yaml.span.end.line, equals(3));
+    expect(yaml.span.end.column, equals(0));
+
+    var map = yaml.nodes.first as YamlMap;
+    expect(map.span.start.line, equals(0));
+    expect(map.span.start.column, equals(2));
+    expect(map.span.end.line, equals(2));
+    expect(map.span.end.column, equals(0));
+
+    var key = map.nodes.keys.first;
+    expect(key.span.start.line, equals(0));
+    expect(key.span.start.column, equals(2));
+    expect(key.span.end.line, equals(0));
+    expect(key.span.end.column, equals(5));
+
+    var value = map.nodes.values.first;
+    expect(value.span.start.line, equals(1));
+    expect(value.span.start.column, equals(4));
+    expect(value.span.end.line, equals(1));
+    expect(value.span.end.column, equals(7));
+
+    var scalar = yaml.nodes.last;
+    expect(scalar.span.start.line, equals(2));
+    expect(scalar.span.start.column, equals(2));
+    expect(scalar.span.end.line, equals(2));
+    expect(scalar.span.end.column, equals(5));
+  });
+
+  // The following tests are all taken directly from the YAML spec
+  // (http://www.yaml.org/spec/1.2/spec.html). Most of them are code examples
+  // that are directly included in the spec, but additional tests are derived
+  // from the prose.
+
+  // A few examples from the spec are deliberately excluded, because they test
+  // features that this implementation doesn't intend to support (character
+  // encoding detection and user-defined tags). More tests are commented out,
+  // because they're intended to be supported but not yet implemented.
+
+  // Chapter 2 is just a preview of various Yaml documents. It's probably not
+  // necessary to test its examples, but it would be nice to test everything in
+  // the spec.
+  group('2.1: Collections', () {
+    test('[Example 2.1]', () {
+      expectYamlLoads(['Mark McGwire', 'Sammy Sosa', 'Ken Griffey'], '''
+        - Mark McGwire
+        - Sammy Sosa
+        - Ken Griffey''');
+    });
+
+    test('[Example 2.2]', () {
+      expectYamlLoads({'hr': 65, 'avg': 0.278, 'rbi': 147}, '''
+        hr:  65    # Home runs
+        avg: 0.278 # Batting average
+        rbi: 147   # Runs Batted In''');
+    });
+
+    test('[Example 2.3]', () {
+      expectYamlLoads({
+        'american': ['Boston Red Sox', 'Detroit Tigers', 'New York Yankees'],
+        'national': ['New York Mets', 'Chicago Cubs', 'Atlanta Braves'],
+      }, '''
+        american:
+          - Boston Red Sox
+          - Detroit Tigers
+          - New York Yankees
+        national:
+          - New York Mets
+          - Chicago Cubs
+          - Atlanta Braves''');
+    });
+
+    test('[Example 2.4]', () {
+      expectYamlLoads([
+        {'name': 'Mark McGwire', 'hr': 65, 'avg': 0.278},
+        {'name': 'Sammy Sosa', 'hr': 63, 'avg': 0.288},
+      ], '''
+        -
+          name: Mark McGwire
+          hr:   65
+          avg:  0.278
+        -
+          name: Sammy Sosa
+          hr:   63
+          avg:  0.288''');
+    });
+
+    test('[Example 2.5]', () {
+      expectYamlLoads([
+        ['name', 'hr', 'avg'],
+        ['Mark McGwire', 65, 0.278],
+        ['Sammy Sosa', 63, 0.288]
+      ], '''
+        - [name        , hr, avg  ]
+        - [Mark McGwire, 65, 0.278]
+        - [Sammy Sosa  , 63, 0.288]''');
+    });
+
+    test('[Example 2.6]', () {
+      expectYamlLoads({
+        'Mark McGwire': {'hr': 65, 'avg': 0.278},
+        'Sammy Sosa': {'hr': 63, 'avg': 0.288}
+      }, '''
+        Mark McGwire: {hr: 65, avg: 0.278}
+        Sammy Sosa: {
+            hr: 63,
+            avg: 0.288
+          }''');
+    });
+  });
+
+  group('2.2: Structures', () {
+    test('[Example 2.7]', () {
+      expectYamlStreamLoads([
+        ['Mark McGwire', 'Sammy Sosa', 'Ken Griffey'],
+        ['Chicago Cubs', 'St Louis Cardinals']
+      ], '''
+        # Ranking of 1998 home runs
+        ---
+        - Mark McGwire
+        - Sammy Sosa
+        - Ken Griffey
+
+        # Team ranking
+        ---
+        - Chicago Cubs
+        - St Louis Cardinals''');
+    });
+
+    test('[Example 2.8]', () {
+      expectYamlStreamLoads([
+        {'time': '20:03:20', 'player': 'Sammy Sosa', 'action': 'strike (miss)'},
+        {'time': '20:03:47', 'player': 'Sammy Sosa', 'action': 'grand slam'},
+      ], '''
+        ---
+        time: 20:03:20
+        player: Sammy Sosa
+        action: strike (miss)
+        ...
+        ---
+        time: 20:03:47
+        player: Sammy Sosa
+        action: grand slam
+        ...''');
+    });
+
+    test('[Example 2.9]', () {
+      expectYamlLoads({
+        'hr': ['Mark McGwire', 'Sammy Sosa'],
+        'rbi': ['Sammy Sosa', 'Ken Griffey']
+      }, '''
+        ---
+        hr: # 1998 hr ranking
+          - Mark McGwire
+          - Sammy Sosa
+        rbi:
+          # 1998 rbi ranking
+          - Sammy Sosa
+          - Ken Griffey''');
+    });
+
+    test('[Example 2.10]', () {
+      expectYamlLoads({
+        'hr': ['Mark McGwire', 'Sammy Sosa'],
+        'rbi': ['Sammy Sosa', 'Ken Griffey']
+      }, '''
+        ---
+        hr:
+          - Mark McGwire
+          # Following node labeled SS
+          - &SS Sammy Sosa
+        rbi:
+          - *SS # Subsequent occurrence
+          - Ken Griffey''');
+    });
+
+    test('[Example 2.11]', () {
+      var doc = deepEqualsMap();
+      doc[['Detroit Tigers', 'Chicago cubs']] = ['2001-07-23'];
+      doc[['New York Yankees', 'Atlanta Braves']] = [
+        '2001-07-02',
+        '2001-08-12',
+        '2001-08-14'
+      ];
+      expectYamlLoads(doc, '''
+        ? - Detroit Tigers
+          - Chicago cubs
+        :
+          - 2001-07-23
+
+        ? [ New York Yankees,
+            Atlanta Braves ]
+        : [ 2001-07-02, 2001-08-12,
+            2001-08-14 ]''');
+    });
+
+    test('[Example 2.12]', () {
+      expectYamlLoads([
+        {'item': 'Super Hoop', 'quantity': 1},
+        {'item': 'Basketball', 'quantity': 4},
+        {'item': 'Big Shoes', 'quantity': 1},
+      ], '''
+        ---
+        # Products purchased
+        - item    : Super Hoop
+          quantity: 1
+        - item    : Basketball
+          quantity: 4
+        - item    : Big Shoes
+          quantity: 1''');
+    });
+  });
+
+  group('2.3: Scalars', () {
+    test('[Example 2.13]', () {
+      expectYamlLoads(cleanUpLiteral('''
+        \\//||\\/||
+        // ||  ||__'''), '''
+        # ASCII Art
+        --- |
+          \\//||\\/||
+          // ||  ||__''');
+    });
+
+    test('[Example 2.14]', () {
+      expectYamlLoads("Mark McGwire's year was crippled by a knee injury.", '''
+        --- >
+          Mark McGwire's
+          year was crippled
+          by a knee injury.''');
+    });
+
+    test('[Example 2.15]', () {
+      expectYamlLoads(cleanUpLiteral('''
+        Sammy Sosa completed another fine season with great stats.
+
+          63 Home Runs
+          0.288 Batting Average
+
+        What a year!'''), '''
+        >
+         Sammy Sosa completed another
+         fine season with great stats.
+
+           63 Home Runs
+           0.288 Batting Average
+
+         What a year!''');
+    });
+
+    test('[Example 2.16]', () {
+      expectYamlLoads({
+        'name': 'Mark McGwire',
+        'accomplishment': 'Mark set a major league home run record in 1998.\n',
+        'stats': '65 Home Runs\n0.278 Batting Average'
+      }, '''
+        name: Mark McGwire
+        accomplishment: >
+          Mark set a major league
+          home run record in 1998.
+        stats: |
+          65 Home Runs
+          0.278 Batting Average''');
+    });
+
+    test('[Example 2.17]', () {
+      expectYamlLoads({
+        'unicode': 'Sosa did fine.\u263A \u{1F680}',
+        'control': '\b1998\t1999\t2000\n',
+        'hex esc': '\r\n is \r\n',
+        'single': '"Howdy!" he cried.',
+        'quoted': " # Not a 'comment'.",
+        'tie-fighter': '|\\-*-/|',
+        'surrogate-pair': 'I \u{D83D}\u{DE03}  ️Dart!',
+        'key-\u{D83D}\u{DD11}': 'Look\u{D83D}\u{DE03}\u{D83C}\u{DF89}surprise!',
+      }, """
+        unicode: "Sosa did fine.\\u263A \\U0001F680"
+        control: "\\b1998\\t1999\\t2000\\n"
+        hex esc: "\\x0d\\x0a is \\r\\n"
+
+        single: '"Howdy!" he cried.'
+        quoted: ' # Not a ''comment''.'
+        tie-fighter: '|\\-*-/|'
+        
+        surrogate-pair: I \u{D83D}\u{DE03}  ️Dart!
+        key-\u{D83D}\u{DD11}: Look\u{D83D}\u{DE03}\u{D83C}\u{DF89}surprise!""");
+    });
+
+    test('[Example 2.18]', () {
+      expectYamlLoads({
+        'plain': 'This unquoted scalar spans many lines.',
+        'quoted': 'So does this quoted scalar.\n'
+      }, '''
+        plain:
+          This unquoted scalar
+          spans many lines.
+
+        quoted: "So does this
+          quoted scalar.\\n"''');
+    });
+  });
+
+  group('2.4: Tags', () {
+    test('[Example 2.19]', () {
+      expectYamlLoads({
+        'canonical': 12345,
+        'decimal': 12345,
+        'octal': 12,
+        'hexadecimal': 12
+      }, '''
+        canonical: 12345
+        decimal: +12345
+        octal: 0o14
+        hexadecimal: 0xC''');
+    });
+
+    test('[Example 2.20]', () {
+      expectYamlLoads({
+        'canonical': 1230.15,
+        'exponential': 1230.15,
+        'fixed': 1230.15,
+        'negative infinity': -infinity,
+        'not a number': nan
+      }, '''
+        canonical: 1.23015e+3
+        exponential: 12.3015e+02
+        fixed: 1230.15
+        negative infinity: -.inf
+        not a number: .NaN''');
+    });
+
+    test('[Example 2.21]', () {
+      var doc = deepEqualsMap({
+        'booleans': [true, false],
+        'string': '012345'
+      });
+      doc[null] = null;
+      expectYamlLoads(doc, """
+        null:
+        booleans: [ true, false ]
+        string: '012345'""");
+    });
+
+    // Examples 2.22 through 2.26 test custom tag URIs, which this
+    // implementation currently doesn't plan to support.
+  });
+
+  group('2.5 Full Length Example', () {
+    // Example 2.27 tests custom tag URIs, which this implementation currently
+    // doesn't plan to support.
+
+    test('[Example 2.28]', () {
+      expectYamlStreamLoads([
+        {
+          'Time': '2001-11-23 15:01:42 -5',
+          'User': 'ed',
+          'Warning': 'This is an error message for the log file'
+        },
+        {
+          'Time': '2001-11-23 15:02:31 -5',
+          'User': 'ed',
+          'Warning': 'A slightly different error message.'
+        },
+        {
+          'DateTime': '2001-11-23 15:03:17 -5',
+          'User': 'ed',
+          'Fatal': 'Unknown variable "bar"',
+          'Stack': [
+            {
+              'file': 'TopClass.py',
+              'line': 23,
+              'code': 'x = MoreObject("345\\n")\n'
+            },
+            {'file': 'MoreClass.py', 'line': 58, 'code': 'foo = bar'}
+          ]
+        }
+      ], '''
+        ---
+        Time: 2001-11-23 15:01:42 -5
+        User: ed
+        Warning:
+          This is an error message
+          for the log file
+        ---
+        Time: 2001-11-23 15:02:31 -5
+        User: ed
+        Warning:
+          A slightly different error
+          message.
+        ---
+        DateTime: 2001-11-23 15:03:17 -5
+        User: ed
+        Fatal:
+          Unknown variable "bar"
+        Stack:
+          - file: TopClass.py
+            line: 23
+            code: |
+              x = MoreObject("345\\n")
+          - file: MoreClass.py
+            line: 58
+            code: |-
+              foo = bar''');
+    });
+  });
+
+  // Chapter 3 just talks about the structure of loading and dumping Yaml.
+  // Chapter 4 explains conventions used in the spec.
+
+  // Chapter 5: Characters
+  group('5.1: Character Set', () {
+    void expectAllowsCharacter(int charCode) {
+      var char = String.fromCharCodes([charCode]);
+      expectYamlLoads('The character "$char" is allowed',
+          'The character "$char" is allowed');
+    }
+
+    void expectAllowsQuotedCharacter(int charCode) {
+      var char = String.fromCharCodes([charCode]);
+      expectYamlLoads("The character '$char' is allowed",
+          '"The character \'$char\' is allowed"');
+    }
+
+    void expectDisallowsCharacter(int charCode) {
+      var char = String.fromCharCodes([charCode]);
+      expectYamlFails('The character "$char" is disallowed');
+    }
+
+    test("doesn't include C0 control characters", () {
+      expectDisallowsCharacter(0x0);
+      expectDisallowsCharacter(0x8);
+      expectDisallowsCharacter(0x1F);
+    });
+
+    test('includes TAB', () => expectAllowsCharacter(0x9));
+    test("doesn't include DEL", () => expectDisallowsCharacter(0x7F));
+
+    test("doesn't include C1 control characters", () {
+      expectDisallowsCharacter(0x80);
+      expectDisallowsCharacter(0x8A);
+      expectDisallowsCharacter(0x9F);
+    });
+
+    test('includes NEL', () => expectAllowsCharacter(0x85));
+
+    group('within quoted strings', () {
+      test('includes DEL', () => expectAllowsQuotedCharacter(0x7F));
+      test('includes C1 control characters', () {
+        expectAllowsQuotedCharacter(0x80);
+        expectAllowsQuotedCharacter(0x8A);
+        expectAllowsQuotedCharacter(0x9F);
+      });
+    });
+  });
+
+  // Skipping section 5.2 (Character Encodings), since at the moment the module
+  // assumes that the client code is providing it with a string of the proper
+  // encoding.
+
+  group('5.3: Indicator Characters', () {
+    test('[Example 5.3]', () {
+      expectYamlLoads({
+        'sequence': ['one', 'two'],
+        'mapping': {'sky': 'blue', 'sea': 'green'}
+      }, '''
+        sequence:
+        - one
+        - two
+        mapping:
+          ? sky
+          : blue
+          sea : green''');
+    });
+
+    test('[Example 5.4]', () {
+      expectYamlLoads({
+        'sequence': ['one', 'two'],
+        'mapping': {'sky': 'blue', 'sea': 'green'}
+      }, '''
+        sequence: [ one, two, ]
+        mapping: { sky: blue, sea: green }''');
+    });
+
+    test('[Example 5.5]', () => expectYamlLoads(null, '# Comment only.'));
+
+    // Skipping 5.6 because it uses an undefined tag.
+
+    test('[Example 5.7]', () {
+      expectYamlLoads({'literal': 'some\ntext\n', 'folded': 'some text\n'}, '''
+        literal: |
+          some
+          text
+        folded: >
+          some
+          text
+        ''');
+    });
+
+    test('[Example 5.8]', () {
+      expectYamlLoads({'single': 'text', 'double': 'text'}, '''
+        single: 'text'
+        double: "text"
+        ''');
+    });
+
+    test('[Example 5.9]', () {
+      expectYamlLoads('text', '''
+        %YAML 1.2
+        --- text''');
+    });
+
+    test('[Example 5.10]', () {
+      expectYamlFails('commercial-at: @text');
+      expectYamlFails('commercial-at: `text');
+    });
+  });
+
+  group('5.4: Line Break Characters', () {
+    group('include', () {
+      test('\\n', () => expectYamlLoads([1, 2], indentLiteral('- 1\n- 2')));
+      test('\\r', () => expectYamlLoads([1, 2], '- 1\r- 2'));
+    });
+
+    group('do not include', () {
+      test('form feed', () => expectYamlFails('- 1\x0C- 2'));
+      test('NEL', () => expectYamlLoads(['1\x85- 2'], '- 1\x85- 2'));
+      test('0x2028', () => expectYamlLoads(['1\u2028- 2'], '- 1\u2028- 2'));
+      test('0x2029', () => expectYamlLoads(['1\u2029- 2'], '- 1\u2029- 2'));
+    });
+
+    group('in a scalar context must be normalized', () {
+      test(
+          'from \\r to \\n',
+          () => expectYamlLoads(
+              ['foo\nbar'], indentLiteral('- |\n  foo\r  bar')));
+      test(
+          'from \\r\\n to \\n',
+          () => expectYamlLoads(
+              ['foo\nbar'], indentLiteral('- |\n  foo\r\n  bar')));
+    });
+
+    test('[Example 5.11]', () {
+      expectYamlLoads(cleanUpLiteral('''
+        Line break (no glyph)
+        Line break (glyphed)'''), '''
+        |
+          Line break (no glyph)
+          Line break (glyphed)''');
+    });
+  });
+
+  group('5.5: White Space Characters', () {
+    test('[Example 5.12]', () {
+      expectYamlLoads({
+        'quoted': 'Quoted \t',
+        'block': 'void main() {\n\tprintf("Hello, world!\\n");\n}\n'
+      }, '''
+        # Tabs and spaces
+        quoted: "Quoted \t"
+        block:\t|
+          void main() {
+          \tprintf("Hello, world!\\n");
+          }
+        ''');
+    });
+  });
+
+  group('5.7: Escaped Characters', () {
+    test('[Example 5.13]', () {
+      expectYamlLoads(
+          'Fun with \x5C '
+              '\x22 \x07 \x08 \x1B \x0C '
+              '\x0A \x0D \x09 \x0B \x00 '
+              '\x20 \xA0 \x85 \u2028 \u2029 '
+              'A A A',
+          '''
+        "Fun with \\\\
+        \\" \\a \\b \\e \\f \\
+        \\n \\r \\t \\v \\0 \\
+        \\  \\_ \\N \\L \\P \\
+        \\x41 \\u0041 \\U00000041"''');
+    });
+
+    test('[Example 5.14]', () {
+      expectYamlFails('Bad escape: "\\c"');
+      expectYamlFails('Bad escape: "\\xq-"');
+    });
+  });
+
+  // Chapter 6: Basic Structures
+  group('6.1: Indentation Spaces', () {
+    test('may not include TAB characters', () {
+      expectYamlFails('''
+        -
+        \t- foo
+        \t- bar''');
+    });
+
+    test('must be the same for all sibling nodes', () {
+      expectYamlFails('''
+        -
+          - foo
+         - bar''');
+    });
+
+    test('may be different for the children of sibling nodes', () {
+      expectYamlLoads([
+        ['foo'],
+        ['bar']
+      ], '''
+        -
+          - foo
+        -
+         - bar''');
+    });
+
+    test('[Example 6.1]', () {
+      expectYamlLoads({
+        'Not indented': {
+          'By one space': 'By four\n  spaces\n',
+          'Flow style': ['By two', 'Also by two', 'Still by two']
+        }
+      }, '''
+          # Leading comment line spaces are
+           # neither content nor indentation.
+            
+        Not indented:
+         By one space: |
+            By four
+              spaces
+         Flow style: [    # Leading spaces
+           By two,        # in flow style
+          Also by two,    # are neither
+          \tStill by two   # content nor
+            ]             # indentation.''');
+    });
+
+    test('[Example 6.2]', () {
+      expectYamlLoads({
+        'a': [
+          'b',
+          ['c', 'd']
+        ]
+      }, '''
+        ? a
+        : -\tb
+          -  -\tc
+             - d''');
+    });
+  });
+
+  group('6.2: Separation Spaces', () {
+    test('[Example 6.3]', () {
+      expectYamlLoads([
+        {'foo': 'bar'},
+        ['baz', 'baz']
+      ], '''
+        - foo:\t bar
+        - - baz
+          -\tbaz''');
+    });
+  });
+
+  group('6.3: Line Prefixes', () {
+    test('[Example 6.4]', () {
+      expectYamlLoads({
+        'plain': 'text lines',
+        'quoted': 'text lines',
+        'block': 'text\n \tlines\n'
+      }, '''
+        plain: text
+          lines
+        quoted: "text
+          \tlines"
+        block: |
+          text
+           \tlines
+        ''');
+    });
+  });
+
+  group('6.4: Empty Lines', () {
+    test('[Example 6.5]', () {
+      expectYamlLoads({
+        'Folding': 'Empty line\nas a line feed',
+        'Chomping': 'Clipped empty lines\n',
+      }, '''
+        Folding:
+          "Empty line
+           \t
+          as a line feed"
+        Chomping: |
+          Clipped empty lines
+         ''');
+    });
+  });
+
+  group('6.5: Line Folding', () {
+    test('[Example 6.6]', () {
+      expectYamlLoads('trimmed\n\n\nas space', '''
+        >-
+          trimmed
+          
+         
+
+          as
+          space
+        ''');
+    });
+
+    test('[Example 6.7]', () {
+      expectYamlLoads('foo \n\n\t bar\n\nbaz\n', '''
+        >
+          foo 
+         
+          \t bar
+
+          baz
+        ''');
+    });
+
+    test('[Example 6.8]', () {
+      expectYamlLoads(' foo\nbar\nbaz ', '''
+        "
+          foo 
+         
+          \t bar
+
+          baz
+        "''');
+    });
+  });
+
+  group('6.6: Comments', () {
+    test('must be separated from other tokens by white space characters', () {
+      expectYamlLoads('foo#bar', 'foo#bar');
+      expectYamlLoads('foo:#bar', 'foo:#bar');
+      expectYamlLoads('-#bar', '-#bar');
+    });
+
+    test('[Example 6.9]', () {
+      expectYamlLoads({'key': 'value'}, '''
+        key:    # Comment
+          value''');
+    });
+
+    group('outside of scalar content', () {
+      test('may appear on a line of their own', () {
+        expectYamlLoads([1, 2], '''
+        - 1
+        # Comment
+        - 2''');
+      });
+
+      test('are independent of indentation level', () {
+        expectYamlLoads([
+          [1, 2]
+        ], '''
+        -
+          - 1
+         # Comment
+          - 2''');
+      });
+
+      test('include lines containing only white space characters', () {
+        expectYamlLoads([1, 2], '''
+        - 1
+          \t  
+        - 2''');
+      });
+    });
+
+    group('within scalar content', () {
+      test('may not appear on a line of their own', () {
+        expectYamlLoads(['foo\n# not comment\nbar\n'], '''
+        - |
+          foo
+          # not comment
+          bar
+        ''');
+      });
+
+      test("don't include lines containing only white space characters", () {
+        expectYamlLoads(['foo\n  \t   \nbar\n'], '''
+        - |
+          foo
+            \t   
+          bar
+        ''');
+      });
+    });
+
+    test('[Example 6.10]', () {
+      expectYamlLoads(null, '''
+          # Comment
+           
+        ''');
+    });
+
+    test('[Example 6.11]', () {
+      expectYamlLoads({'key': 'value'}, '''
+        key:    # Comment
+                # lines
+          value
+        ''');
+    });
+
+    group('ending a block scalar header', () {
+      test('may not be followed by additional comment lines', () {
+        expectYamlLoads(['# not comment\nfoo\n'], '''
+        - | # comment
+            # not comment
+            foo
+        ''');
+      });
+    });
+  });
+
+  group('6.7: Separation Lines', () {
+    test('may not be used within implicit keys', () {
+      expectYamlFails('''
+        [1,
+         2]: 3''');
+    });
+
+    test('[Example 6.12]', () {
+      var doc = deepEqualsMap();
+      doc[{'first': 'Sammy', 'last': 'Sosa'}] = {'hr': 65, 'avg': 0.278};
+      expectYamlLoads(doc, '''
+        { first: Sammy, last: Sosa }:
+        # Statistics:
+          hr:  # Home runs
+             65
+          avg: # Average
+           0.278''');
+    });
+  });
+
+  group('6.8: Directives', () {
+    // TODO(nweiz): assert that this produces a warning
+    test('[Example 6.13]', () {
+      expectYamlLoads('foo', '''
+        %FOO  bar baz # Should be ignored
+                      # with a warning.
+        --- "foo"''');
+    });
+
+    // TODO(nweiz): assert that this produces a warning.
+    test('[Example 6.14]', () {
+      expectYamlLoads('foo', '''
+        %YAML 1.3 # Attempt parsing
+                   # with a warning
+        ---
+        "foo"''');
+    });
+
+    test('[Example 6.15]', () {
+      expectYamlFails('''
+        %YAML 1.2
+        %YAML 1.1
+        foo''');
+    });
+
+    test('[Example 6.16]', () {
+      expectYamlLoads('foo', '''
+        %TAG !yaml! tag:yaml.org,2002:
+        ---
+        !yaml!str "foo"''');
+    });
+
+    test('[Example 6.17]', () {
+      expectYamlFails('''
+        %TAG ! !foo
+        %TAG ! !foo
+        bar''');
+    });
+
+    // Examples 6.18 through 6.22 test custom tag URIs, which this
+    // implementation currently doesn't plan to support.
+  });
+
+  group('6.9: Node Properties', () {
+    test('may be specified in any order', () {
+      expectYamlLoads(['foo', 'bar'], '''
+        - !!str &a1 foo
+        - &a2 !!str bar''');
+    });
+
+    test('[Example 6.23]', () {
+      expectYamlLoads({'foo': 'bar', 'baz': 'foo'}, '''
+        !!str &a1 "foo":
+          !!str bar
+        &a2 baz : *a1''');
+    });
+
+    // Example 6.24 tests custom tag URIs, which this implementation currently
+    // doesn't plan to support.
+
+    test('[Example 6.25]', () {
+      expectYamlFails('- !<!> foo');
+      expectYamlFails('- !<\$:?> foo');
+    });
+
+    // Examples 6.26 and 6.27 test custom tag URIs, which this implementation
+    // currently doesn't plan to support.
+
+    test('[Example 6.28]', () {
+      expectYamlLoads(['12', 12, '12'], '''
+        # Assuming conventional resolution:
+        - "12"
+        - 12
+        - ! 12''');
+    });
+
+    test('[Example 6.29]', () {
+      expectYamlLoads(
+          {'First occurrence': 'Value', 'Second occurrence': 'Value'}, '''
+        First occurrence: &anchor Value
+        Second occurrence: *anchor''');
+    });
+  });
+
+  // Chapter 7: Flow Styles
+  group('7.1: Alias Nodes', () {
+    test("must not use an anchor that doesn't previously occur", () {
+      expectYamlFails('''
+        - *anchor
+        - &anchor foo''');
+    });
+
+    test("don't have to exist for a given anchor node", () {
+      expectYamlLoads(['foo'], '- &anchor foo');
+    });
+
+    group('must not specify', () {
+      test('tag properties', () => expectYamlFails('''
+        - &anchor foo
+        - !str *anchor'''));
+
+      test('anchor properties', () => expectYamlFails('''
+        - &anchor foo
+        - &anchor2 *anchor'''));
+
+      test('content', () => expectYamlFails('''
+        - &anchor foo
+        - *anchor bar'''));
+    });
+
+    test('must preserve structural equality', () {
+      var doc = loadYaml(cleanUpLiteral('''
+        anchor: &anchor [a, b, c]
+        alias: *anchor'''));
+      var anchorList = doc['anchor'];
+      var aliasList = doc['alias'];
+      expect(anchorList, same(aliasList));
+
+      doc = loadYaml(cleanUpLiteral('''
+        ? &anchor [a, b, c]
+        : ? *anchor
+          : bar'''));
+      anchorList = doc.keys.first;
+      aliasList = doc[['a', 'b', 'c']].keys.first;
+      expect(anchorList, same(aliasList));
+    });
+
+    test('[Example 7.1]', () {
+      expectYamlLoads({
+        'First occurrence': 'Foo',
+        'Second occurrence': 'Foo',
+        'Override anchor': 'Bar',
+        'Reuse anchor': 'Bar',
+      }, '''
+        First occurrence: &anchor Foo
+        Second occurrence: *anchor
+        Override anchor: &anchor Bar
+        Reuse anchor: *anchor''');
+    });
+  });
+
+  group('7.2: Empty Nodes', () {
+    test('[Example 7.2]', () {
+      expectYamlLoads({'foo': '', '': 'bar'}, '''
+        {
+          foo : !!str,
+          !!str : bar,
+        }''');
+    });
+
+    test('[Example 7.3]', () {
+      var doc = deepEqualsMap({'foo': null});
+      doc[null] = 'bar';
+      expectYamlLoads(doc, '''
+        {
+          ? foo :,
+          : bar,
+        }''');
+    });
+  });
+
+  group('7.3: Flow Scalar Styles', () {
+    test('[Example 7.4]', () {
+      expectYamlLoads({
+        'implicit block key': [
+          {'implicit flow key': 'value'}
+        ]
+      }, '''
+        "implicit block key" : [
+          "implicit flow key" : value,
+         ]''');
+    });
+
+    test('[Example 7.5]', () {
+      expectYamlLoads(
+          'folded to a space,\nto a line feed, or \t \tnon-content', '''
+        "folded 
+        to a space,\t
+         
+        to a line feed, or \t\\
+         \\ \tnon-content"''');
+    });
+
+    test('[Example 7.6]', () {
+      expectYamlLoads(' 1st non-empty\n2nd non-empty 3rd non-empty ', '''
+        " 1st non-empty
+
+         2nd non-empty 
+        \t3rd non-empty "''');
+    });
+
+    test('[Example 7.7]', () {
+      expectYamlLoads("here's to \"quotes\"", "'here''s to \"quotes\"'");
+    });
+
+    test('[Example 7.8]', () {
+      expectYamlLoads({
+        'implicit block key': [
+          {'implicit flow key': 'value'}
+        ]
+      }, """
+        'implicit block key' : [
+          'implicit flow key' : value,
+         ]""");
+    });
+
+    test('[Example 7.9]', () {
+      expectYamlLoads(' 1st non-empty\n2nd non-empty 3rd non-empty ', """
+        ' 1st non-empty
+
+         2nd non-empty 
+        \t3rd non-empty '""");
+    });
+
+    test('[Example 7.10]', () {
+      expectYamlLoads([
+        '::vector',
+        ': - ()',
+        'Up, up, and away!',
+        -123,
+        'http://example.com/foo#bar',
+        [
+          '::vector',
+          ': - ()',
+          'Up, up, and away!',
+          -123,
+          'http://example.com/foo#bar'
+        ]
+      ], '''
+        # Outside flow collection:
+        - ::vector
+        - ": - ()"
+        - Up, up, and away!
+        - -123
+        - http://example.com/foo#bar
+        # Inside flow collection:
+        - [ ::vector,
+          ": - ()",
+          "Up, up, and away!",
+          -123,
+          http://example.com/foo#bar ]''');
+    });
+
+    test('[Example 7.11]', () {
+      expectYamlLoads({
+        'implicit block key': [
+          {'implicit flow key': 'value'}
+        ]
+      }, '''
+        implicit block key : [
+          implicit flow key : value,
+         ]''');
+    });
+
+    test('[Example 7.12]', () {
+      expectYamlLoads('1st non-empty\n2nd non-empty 3rd non-empty', '''
+        1st non-empty
+
+         2nd non-empty 
+        \t3rd non-empty''');
+    });
+  });
+
+  group('7.4: Flow Collection Styles', () {
+    test('[Example 7.13]', () {
+      expectYamlLoads([
+        ['one', 'two'],
+        ['three', 'four']
+      ], '''
+        - [ one, two, ]
+        - [three ,four]''');
+    });
+
+    test('[Example 7.14]', () {
+      expectYamlLoads([
+        'double quoted',
+        'single quoted',
+        'plain text',
+        ['nested'],
+        {'single': 'pair'}
+      ], """
+        [
+        "double
+         quoted", 'single
+                   quoted',
+        plain
+         text, [ nested ],
+        single: pair,
+        ]""");
+    });
+
+    test('[Example 7.15]', () {
+      expectYamlLoads([
+        {'one': 'two', 'three': 'four'},
+        {'five': 'six', 'seven': 'eight'},
+      ], '''
+        - { one : two , three: four , }
+        - {five: six,seven : eight}''');
+    });
+
+    test('[Example 7.16]', () {
+      var doc = deepEqualsMap({'explicit': 'entry', 'implicit': 'entry'});
+      doc[null] = null;
+      expectYamlLoads(doc, '''
+        {
+        ? explicit: entry,
+        implicit: entry,
+        ?
+        }''');
+    });
+
+    test('[Example 7.17]', () {
+      var doc = deepEqualsMap({
+        'unquoted': 'separate',
+        'http://foo.com': null,
+        'omitted value': null
+      });
+      doc[null] = 'omitted key';
+      expectYamlLoads(doc, '''
+        {
+        unquoted : "separate",
+        http://foo.com,
+        omitted value:,
+        : omitted key,
+        }''');
+    });
+
+    test('[Example 7.18]', () {
+      expectYamlLoads(
+          {'adjacent': 'value', 'readable': 'value', 'empty': null}, '''
+        {
+        "adjacent":value,
+        "readable": value,
+        "empty":
+        }''');
+    });
+
+    test('[Example 7.19]', () {
+      expectYamlLoads([
+        {'foo': 'bar'}
+      ], '''
+        [
+        foo: bar
+        ]''');
+    });
+
+    test('[Example 7.20]', () {
+      expectYamlLoads([
+        {'foo bar': 'baz'}
+      ], '''
+        [
+        ? foo
+         bar : baz
+        ]''');
+    });
+
+    test('[Example 7.21]', () {
+      var el1 = deepEqualsMap();
+      el1[null] = 'empty key entry';
+
+      var el2 = deepEqualsMap();
+      el2[{'JSON': 'like'}] = 'adjacent';
+
+      expectYamlLoads([
+        [
+          {'YAML': 'separate'}
+        ],
+        [el1],
+        [el2]
+      ], '''
+        - [ YAML : separate ]
+        - [ : empty key entry ]
+        - [ {JSON: like}:adjacent ]''');
+    });
+
+    // TODO(nweiz): enable this when we throw an error for long or multiline
+    // keys.
+    // test('[Example 7.22]', () {
+    //   expectYamlFails(
+    //     """
+    //     [ foo
+    //      bar: invalid ]""");
+    //
+    //   var dotList = new List.filled(1024, ' ');
+    //   var dots = dotList.join();
+    //   expectYamlFails('[ "foo...$dots...bar": invalid ]');
+    // });
+  });
+
+  group('7.5: Flow Nodes', () {
+    test('[Example 7.23]', () {
+      expectYamlLoads([
+        ['a', 'b'],
+        {'a': 'b'},
+        'a',
+        'b',
+        'c'
+      ], '''
+        - [ a, b ]
+        - { a: b }
+        - 'a'
+        - 'b'
+        - c''');
+    });
+
+    test('[Example 7.24]', () {
+      expectYamlLoads(['a', 'b', 'c', 'c', ''], '''
+        - !!str "a"
+        - 'b'
+        - &anchor "c"
+        - *anchor
+        - !!str''');
+    });
+  });
+
+  // Chapter 8: Block Styles
+  group('8.1: Block Scalar Styles', () {
+    test('[Example 8.1]', () {
+      expectYamlLoads(['literal\n', ' folded\n', 'keep\n\n', ' strip'], '''
+        - | # Empty header
+         literal
+        - >1 # Indentation indicator
+          folded
+        - |+ # Chomping indicator
+         keep
+
+        - >1- # Both indicators
+          strip''');
+    });
+
+    test('[Example 8.2]', () {
+      // Note: in the spec, the fourth element in this array is listed as
+      // "\t detected\n", not "\t\ndetected\n". However, I'm reasonably
+      // confident that "\t\ndetected\n" is correct when parsed according to the
+      // rest of the spec.
+      expectYamlLoads(
+          ['detected\n', '\n\n# detected\n', ' explicit\n', '\t\ndetected\n'],
+          '''
+        - |
+         detected
+        - >
+
+
+          # detected
+        - |1
+          explicit
+        - >
+         \t
+         detected
+        ''');
+    });
+
+    test('[Example 8.3]', () {
+      expectYamlFails('''
+        - |
+          
+         text''');
+
+      expectYamlFails('''
+        - >
+          text
+         text''');
+
+      expectYamlFails('''
+        - |2
+         text''');
+    });
+
+    test('[Example 8.4]', () {
+      expectYamlLoads({'strip': 'text', 'clip': 'text\n', 'keep': 'text\n'}, '''
+        strip: |-
+          text
+        clip: |
+          text
+        keep: |+
+          text
+        ''');
+    });
+
+    test('[Example 8.5]', () {
+      // This example in the spec only includes a single newline in the "keep"
+      // value, but as far as I can tell that's not how it's supposed to be
+      // parsed according to the rest of the spec.
+      expectYamlLoads(
+          {'strip': '# text', 'clip': '# text\n', 'keep': '# text\n\n'}, '''
+         # Strip
+          # Comments:
+        strip: |-
+          # text
+          
+         # Clip
+          # comments:
+
+        clip: |
+          # text
+         
+         # Keep
+          # comments:
+
+        keep: |+
+          # text
+
+         # Trail
+          # comments.
+        ''');
+    });
+
+    test('[Example 8.6]', () {
+      expectYamlLoads({'strip': '', 'clip': '', 'keep': '\n'}, '''
+        strip: >-
+
+        clip: >
+
+        keep: |+
+
+        ''');
+    });
+
+    test('[Example 8.7]', () {
+      expectYamlLoads('literal\n\ttext\n', '''
+        |
+         literal
+         \ttext
+        ''');
+    });
+
+    test('[Example 8.8]', () {
+      expectYamlLoads('\n\nliteral\n \n\ntext\n', '''
+        |
+         
+          
+          literal
+           
+          
+          text
+
+         # Comment''');
+    });
+
+    test('[Example 8.9]', () {
+      expectYamlLoads('folded text\n', '''
+        >
+         folded
+         text
+        ''');
+    });
+
+    test('[Example 8.10]', () {
+      expectYamlLoads(cleanUpLiteral('''
+
+        folded line
+        next line
+          * bullet
+
+          * list
+          * lines
+
+        last line
+        '''), '''
+        >
+
+         folded
+         line
+
+         next
+         line
+           * bullet
+
+           * list
+           * lines
+
+         last
+         line
+
+        # Comment''');
+    });
+
+    // Examples 8.11 through 8.13 are duplicates of 8.10.
+  });
+
+  group('8.2: Block Collection Styles', () {
+    test('[Example 8.14]', () {
+      expectYamlLoads({
+        'block sequence': [
+          'one',
+          {'two': 'three'}
+        ]
+      }, '''
+        block sequence:
+          - one
+          - two : three''');
+    });
+
+    test('[Example 8.15]', () {
+      expectYamlLoads([
+        null,
+        'block node\n',
+        ['one', 'two'],
+        {'one': 'two'}
+      ], '''
+        - # Empty
+        - |
+         block node
+        - - one # Compact
+          - two # sequence
+        - one: two # Compact mapping''');
+    });
+
+    test('[Example 8.16]', () {
+      expectYamlLoads({
+        'block mapping': {'key': 'value'}
+      }, '''
+        block mapping:
+         key: value''');
+    });
+
+    test('[Example 8.17]', () {
+      expectYamlLoads({
+        'explicit key': null,
+        'block key\n': ['one', 'two']
+      }, '''
+        ? explicit key # Empty value
+        ? |
+          block key
+        : - one # Explicit compact
+          - two # block value''');
+    });
+
+    test('[Example 8.18]', () {
+      var doc = deepEqualsMap({
+        'plain key': 'in-line value',
+        'quoted key': ['entry']
+      });
+      doc[null] = null;
+      expectYamlLoads(doc, '''
+        plain key: in-line value
+        : # Both empty
+        "quoted key":
+        - entry''');
+    });
+
+    test('[Example 8.19]', () {
+      var el = deepEqualsMap();
+      el[{'earth': 'blue'}] = {'moon': 'white'};
+      expectYamlLoads([
+        {'sun': 'yellow'},
+        el
+      ], '''
+        - sun: yellow
+        - ? earth: blue
+          : moon: white''');
+    });
+
+    test('[Example 8.20]', () {
+      expectYamlLoads([
+        'flow in block',
+        'Block scalar\n',
+        {'foo': 'bar'}
+      ], '''
+        -
+          "flow in block"
+        - >
+         Block scalar
+        - !!map # Block collection
+          foo : bar''');
+    });
+
+    test('[Example 8.21]', () {
+      // The spec doesn't include a newline after "value" in the parsed map, but
+      // the block scalar is clipped so it should be retained.
+      expectYamlLoads({'literal': 'value\n', 'folded': 'value'}, '''
+        literal: |2
+          value
+        folded:
+           !!str
+          >1
+         value''');
+    });
+
+    test('[Example 8.22]', () {
+      expectYamlLoads({
+        'sequence': [
+          'entry',
+          ['nested']
+        ],
+        'mapping': {'foo': 'bar'}
+      }, '''
+        sequence: !!seq
+        - entry
+        - !!seq
+         - nested
+        mapping: !!map
+         foo: bar''');
+    });
+  });
+
+  // Chapter 9: YAML Character Stream
+  group('9.1: Documents', () {
+    // Example 9.1 tests the use of a BOM, which this implementation currently
+    // doesn't plan to support.
+
+    test('[Example 9.2]', () {
+      expectYamlLoads('Document', '''
+        %YAML 1.2
+        ---
+        Document
+        ... # Suffix''');
+    });
+
+    test('[Example 9.3]', () {
+      // The spec example indicates that the comment after "%!PS-Adobe-2.0"
+      // should be stripped, which would imply that that line is not part of the
+      // literal defined by the "|". The rest of the spec is ambiguous on this
+      // point; the allowable indentation for non-indented literal content is
+      // not clearly explained. However, if both the "|" and the text were
+      // indented the same amount, the text would be part of the literal, which
+      // implies that the spec's parse of this document is incorrect.
+      expectYamlStreamLoads(
+          ['Bare document', '%!PS-Adobe-2.0 # Not the first line\n'], '''
+        Bare
+        document
+        ...
+        # No document
+        ...
+        |
+        %!PS-Adobe-2.0 # Not the first line
+        ''');
+    });
+
+    test('[Example 9.4]', () {
+      expectYamlStreamLoads([
+        {'matches %': 20},
+        null
+      ], '''
+        ---
+        { matches
+        % : 20 }
+        ...
+        ---
+        # Empty
+        ...''');
+    });
+
+    test('[Example 9.5]', () {
+      // The spec doesn't have a space between the second
+      // "YAML" and "1.2", but this seems to be a typo.
+      expectYamlStreamLoads(['%!PS-Adobe-2.0\n', null], '''
+        %YAML 1.2
+        --- |
+        %!PS-Adobe-2.0
+        ...
+        %YAML 1.2
+        ---
+        # Empty
+        ...''');
+    });
+
+    test('[Example 9.6]', () {
+      expectYamlStreamLoads([
+        'Document',
+        null,
+        {'matches %': 20}
+      ], '''
+        Document
+        ---
+        # Empty
+        ...
+        %YAML 1.2
+        ---
+        matches %: 20''');
+    });
+  });
+
+  // Chapter 10: Recommended Schemas
+  group('10.1: Failsafe Schema', () {
+    test('[Example 10.1]', () {
+      expectYamlLoads({
+        'Block style': {
+          'Clark': 'Evans',
+          'Ingy': 'döt Net',
+          'Oren': 'Ben-Kiki'
+        },
+        'Flow style': {'Clark': 'Evans', 'Ingy': 'döt Net', 'Oren': 'Ben-Kiki'}
+      }, '''
+        Block style: !!map
+          Clark : Evans
+          Ingy  : döt Net
+          Oren  : Ben-Kiki
+
+        Flow style: !!map { Clark: Evans, Ingy: döt Net, Oren: Ben-Kiki }''');
+    });
+
+    test('[Example 10.2]', () {
+      expectYamlLoads({
+        'Block style': ['Clark Evans', 'Ingy döt Net', 'Oren Ben-Kiki'],
+        'Flow style': ['Clark Evans', 'Ingy döt Net', 'Oren Ben-Kiki']
+      }, '''
+        Block style: !!seq
+        - Clark Evans
+        - Ingy döt Net
+        - Oren Ben-Kiki
+
+        Flow style: !!seq [ Clark Evans, Ingy döt Net, Oren Ben-Kiki ]''');
+    });
+
+    test('[Example 10.3]', () {
+      expectYamlLoads({
+        'Block style': 'String: just a theory.',
+        'Flow style': 'String: just a theory.'
+      }, '''
+        Block style: !!str |-
+          String: just a theory.
+
+        Flow style: !!str "String: just a theory."''');
+    });
+  });
+
+  group('10.2: JSON Schema', () {
+    test('[Example 10.4]', () {
+      var doc = deepEqualsMap({'key with null value': null});
+      doc[null] = 'value for null key';
+      expectYamlStreamLoads([doc], '''
+        !!null null: value for null key
+        key with null value: !!null null''');
+    });
+
+    test('[Example 10.5]', () {
+      expectYamlStreamLoads([
+        {'YAML is a superset of JSON': true, 'Pluto is a planet': false}
+      ], '''
+        YAML is a superset of JSON: !!bool true
+        Pluto is a planet: !!bool false''');
+    });
+
+    test('[Example 10.6]', () {
+      expectYamlStreamLoads([
+        {'negative': -12, 'zero': 0, 'positive': 34}
+      ], '''
+        negative: !!int -12
+        zero: !!int 0
+        positive: !!int 34''');
+    });
+
+    test('[Example 10.7]', () {
+      expectYamlStreamLoads([
+        {
+          'negative': -1,
+          'zero': 0,
+          'positive': 23000,
+          'infinity': infinity,
+          'not a number': nan
+        }
+      ], '''
+        negative: !!float -1
+        zero: !!float 0
+        positive: !!float 2.3e4
+        infinity: !!float .inf
+        not a number: !!float .nan''');
+    }, skip: 'Fails for single digit float');
+
+    test('[Example 10.8]', () {
+      expectYamlStreamLoads([
+        {
+          'A null': null,
+          'Booleans': [true, false],
+          'Integers': [0, -0, 3, -19],
+          'Floats': [0, 0, 12000, -200000],
+          // Despite being invalid in the JSON schema, these values are valid in
+          // the core schema which this implementation supports.
+          'Invalid': [true, null, 7, 0x3A, 12.3]
+        }
+      ], '''
+        A null: null
+        Booleans: [ true, false ]
+        Integers: [ 0, -0, 3, -19 ]
+        Floats: [ 0., -0.0, 12e03, -2E+05 ]
+        Invalid: [ True, Null, 0o7, 0x3A, +12.3 ]''');
+    });
+  });
+
+  group('10.3: Core Schema', () {
+    test('[Example 10.9]', () {
+      expectYamlLoads({
+        'A null': null,
+        'Also a null': null,
+        'Not a null': '',
+        'Booleans': [true, true, false, false],
+        'Integers': [0, 7, 0x3A, -19],
+        'Floats': [0, 0, 0.5, 12000, -200000],
+        'Also floats': [infinity, -infinity, infinity, nan]
+      }, '''
+        A null: null
+        Also a null: # Empty
+        Not a null: ""
+        Booleans: [ true, True, false, FALSE ]
+        Integers: [ 0, 0o7, 0x3A, -19 ]
+        Floats: [ 0., -0.0, .5, +12e03, -2E+05 ]
+        Also floats: [ .inf, -.Inf, +.INF, .NAN ]''');
+    });
+  });
+
+  test('preserves key order', () {
+    const keys = ['a', 'b', 'c', 'd', 'e', 'f'];
+    var sanityCheckCount = 0;
+    for (var permutation in _generatePermutations(keys)) {
+      final yaml = permutation.map((key) => '$key: value').join('\n');
+      expect(loadYaml(yaml).keys.toList(), permutation);
+      sanityCheckCount++;
+    }
+    final expectedPermutationCount =
+        List.generate(keys.length, (i) => i + 1).reduce((n, i) => n * i);
+    expect(sanityCheckCount, expectedPermutationCount);
+  });
+}
+
+Iterable<List<String>> _generatePermutations(List<String> keys) sync* {
+  if (keys.length <= 1) {
+    yield keys;
+    return;
+  }
+  for (var i = 0; i < keys.length; i++) {
+    final first = keys[i];
+    final rest = <String>[...keys.sublist(0, i), ...keys.sublist(i + 1)];
+    for (var subPermutation in _generatePermutations(rest)) {
+      yield <String>[first, ...subPermutation];
+    }
+  }
+}
