Delete lib/src/yaml_edit and use yaml_edit package instead (#3138)

diff --git a/lib/src/command/add.dart b/lib/src/command/add.dart
index faabf99..728f8ea 100644
--- a/lib/src/command/add.dart
+++ b/lib/src/command/add.dart
@@ -7,6 +7,7 @@
 import 'package:path/path.dart' as p;
 import 'package:pub_semver/pub_semver.dart';
 import 'package:yaml/yaml.dart';
+import 'package:yaml_edit/yaml_edit.dart';
 
 import '../command.dart';
 import '../entrypoint.dart';
@@ -20,7 +21,6 @@
 import '../solver.dart';
 import '../source/path.dart';
 import '../utils.dart';
-import '../yaml_edit/editor.dart';
 
 /// Handles the `add` pub command. Adds a dependency to `pubspec.yaml` and gets
 /// the package. The user may pass in a git constraint, host url, or path as
diff --git a/lib/src/command/remove.dart b/lib/src/command/remove.dart
index d1603d5..f505785 100644
--- a/lib/src/command/remove.dart
+++ b/lib/src/command/remove.dart
@@ -5,6 +5,7 @@
 // @dart=2.10
 
 import 'package:yaml/yaml.dart';
+import 'package:yaml_edit/yaml_edit.dart';
 
 import '../command.dart';
 import '../entrypoint.dart';
@@ -13,7 +14,6 @@
 import '../package.dart';
 import '../pubspec.dart';
 import '../solver.dart';
-import '../yaml_edit/editor.dart';
 
 /// Handles the `remove` pub command. Removes dependencies from `pubspec.yaml`,
 /// and performs an operation similar to `pub get`. Unlike `pub add`, this
diff --git a/lib/src/command/upgrade.dart b/lib/src/command/upgrade.dart
index 05b62f7..39a42c7 100644
--- a/lib/src/command/upgrade.dart
+++ b/lib/src/command/upgrade.dart
@@ -8,6 +8,7 @@
 import 'dart:io';
 
 import 'package:pub_semver/pub_semver.dart';
+import 'package:yaml_edit/yaml_edit.dart';
 
 import '../command.dart';
 import '../command_runner.dart';
@@ -22,7 +23,6 @@
 import '../pubspec_utils.dart';
 import '../solver.dart';
 import '../source/hosted.dart';
-import '../yaml_edit/editor.dart';
 
 /// Handles the `upgrade` pub command.
 class UpgradeCommand extends PubCommand {
diff --git a/lib/src/yaml_edit/editor.dart b/lib/src/yaml_edit/editor.dart
deleted file mode 100644
index e68cec1..0000000
--- a/lib/src/yaml_edit/editor.dart
+++ /dev/null
@@ -1,639 +0,0 @@
-// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-// @dart=2.10
-
-import 'package:meta/meta.dart';
-import 'package:yaml/yaml.dart';
-
-import 'equality.dart';
-import 'errors.dart';
-import 'list_mutations.dart';
-import 'map_mutations.dart';
-import 'source_edit.dart';
-import 'strings.dart';
-import 'utils.dart';
-import 'wrap.dart';
-
-/// An interface for modififying [YAML][1] documents while preserving comments
-/// and whitespaces.
-///
-/// YAML parsing is supported by `package:yaml`, and modifications are performed
-/// as string operations. An error will be thrown if internal assertions fail -
-/// such a situation should be extremely rare, and should only occur with
-/// degenerate formatting.
-///
-/// Most modification methods require the user to pass in an [Iterable<Object>]
-/// path that holds the keys/indices to navigate to the element.
-///
-/// **Example:**
-/// ```yaml
-/// a: 1
-/// b: 2
-/// c:
-///   - 3
-///   - 4
-///   - {e: 5, f: [6, 7]}
-/// ```
-///
-/// To get to `7`, our path will be `['c', 2, 'f', 1]`. The path for the base
-/// object is the empty array `[]`. All modification methods will throw a
-/// [ArgumentError] if the path provided is invalid. Note also that that the
-/// order of elements in the path is important, and it should be arranged in
-/// order of calling, with the first element being the first key or index to be
-/// called.
-///
-/// In most modification methods, users are required to pass in a value to be
-/// used for updating the YAML tree. This value is only allowed to either be a
-/// valid scalar that is recognizable by YAML (i.e. `bool`, `String`, `List`,
-/// `Map`, `num`, `null`) or a [YamlNode]. Should the user want to specify
-/// the style to be applied to the value passed in, the user may wrap the value
-/// using [wrapAsYamlNode] while passing in the appropriate `scalarStyle` or
-/// `collectionStyle`. While we try to respect the style that is passed in,
-/// there will be instances where the formatting will not result in valid YAML,
-/// and as such we will fallback to a default formatting while preserving the
-/// content.
-///
-/// To dump the YAML after all the modifications have been completed, simply
-/// call [toString()].
-///
-/// [1]: https://yaml.org/
-@sealed
-class YamlEditor {
-  final List<SourceEdit> _edits = [];
-
-  /// List of [SourceEdit]s that have been applied to [_yaml] since the creation
-  /// of this instance, in chronological order. Intended to be compatible with
-  /// `package:analysis_server`.
-  ///
-  /// The [SourceEdit] objects can be serialized to JSON using the `toJSON`
-  /// function, deserialized using [SourceEdit.fromJson], and applied to a
-  /// string using the `apply` function. Multiple [SourceEdit]s can be applied
-  /// to a string using [SourceEdit.applyAll].
-  ///
-  /// For more information, refer to the [SourceEdit] class.
-  List<SourceEdit> get edits => [..._edits];
-
-  /// Current YAML string.
-  String _yaml;
-
-  /// Root node of YAML AST.
-  YamlNode _contents;
-
-  /// Stores the list of nodes in [_contents] that are connected by aliases.
-  ///
-  /// When a node is anchored with an alias and subsequently referenced,
-  /// the full content of the anchored node is thought to be copied in the
-  /// following references.
-  ///
-  /// **Example:**
-  /// ```dart
-  /// a: &SS Sammy Sosa
-  /// b: *SS
-  /// ```
-  ///
-  /// is equivalent to
-  ///
-  /// ```dart
-  /// a: Sammy Sosa
-  /// b: Sammy Sosa
-  /// ```
-  ///
-  /// As such, aliased nodes have to be treated with special caution when
-  /// any modification is taking place.
-  ///
-  /// See 7.1 Alias Nodes: https://yaml.org/spec/1.2/spec.html#id2786196
-  Set<YamlNode> _aliases = {};
-
-  /// Returns the current YAML string.
-  @override
-  String toString() => _yaml;
-
-  factory YamlEditor(String yaml) => YamlEditor._(yaml);
-
-  YamlEditor._(this._yaml) {
-    ArgumentError.checkNotNull(_yaml);
-    _initialize();
-  }
-
-  /// Loads [_contents] from [_yaml], and traverses the YAML tree formed to
-  /// detect alias nodes.
-  void _initialize() {
-    _contents = loadYamlNode(_yaml);
-    _aliases = {};
-
-    /// Performs a DFS on [_contents] to detect alias nodes.
-    final visited = <YamlNode>{};
-    void collectAliases(YamlNode node) {
-      if (visited.add(node)) {
-        if (node is YamlMap) {
-          node.nodes.forEach((key, value) {
-            collectAliases(key);
-            collectAliases(value);
-          });
-        } else if (node is YamlList) {
-          node.nodes.forEach(collectAliases);
-        }
-      } else {
-        _aliases.add(node);
-      }
-    }
-
-    collectAliases(_contents);
-  }
-
-  /// Parses the document to return [YamlNode] currently present at [path].
-  ///
-  /// If no [YamlNode]s exist at [path], the result of invoking the [orElse]
-  /// function is returned.
-  ///
-  /// If [orElse] is omitted, it defaults to throwing a [ArgumentError].
-  ///
-  /// To get `null` when [path] does not point to a value in the [YamlNode]-tree,
-  /// simply pass `orElse: () => null`.
-  ///
-  /// **Example:** (using orElse)
-  /// ```dart
-  /// final myYamlEditor('{"key": "value"}');
-  /// final value = myYamlEditor.valueAt(['invalid', 'path'], orElse: () => null);
-  /// print(value) // null
-  /// ```
-  ///
-  /// **Example:** (common usage)
-  /// ```dart
-  ///   final doc = YamlEditor('''
-  /// a: 1
-  /// b:
-  ///   d: 4
-  ///   e: [5, 6, 7]
-  /// c: 3
-  /// ''');
-  /// print(doc.parseAt(['b', 'e', 2])); // 7
-  /// ```
-  /// The value returned by [parseAt] is invalidated when the documented is
-  /// mutated, as illustrated below:
-  ///
-  /// **Example:** (old [parseAt] value is invalidated)
-  /// ```dart
-  /// final doc = YamlEditor("YAML: YAML Ain't Markup Language");
-  /// final node = doc.parseAt(['YAML']);
-  ///
-  /// print(node.value); // Expected output: "YAML Ain't Markup Language"
-  ///
-  /// doc.update(['YAML'], 'YAML');
-  ///
-  /// final newNode = doc.parseAt(['YAML']);
-  ///
-  /// // Note that the value does not change
-  /// print(newNode.value); // "YAML"
-  /// print(node.value); // "YAML Ain't Markup Language"
-  /// ```
-  YamlNode parseAt(Iterable<Object> path, {YamlNode Function() orElse}) {
-    ArgumentError.checkNotNull(path, 'path');
-
-    return _traverse(path, orElse: orElse);
-  }
-
-  /// Sets [value] in the [path].
-  ///
-  /// There is a subtle difference between [update] and [remove] followed by
-  /// an [insertIntoList], because [update] preserves comments at the same level.
-  ///
-  /// Throws a [ArgumentError] if [path] is invalid.
-  ///
-  /// **Example:** (using [update])
-  /// ```dart
-  /// final doc = YamlEditor('''
-  ///   - 0
-  ///   - 1 # comment
-  ///   - 2
-  /// ''');
-  /// doc.update([1], 'test');
-  /// ```
-  ///
-  /// **Expected Output:**
-  /// ```yaml
-  ///   - 0
-  ///   - test # comment
-  ///   - 2
-  /// ```
-  ///
-  /// **Example:** (using [remove] and [insertIntoList])
-  /// ```dart
-  /// final doc2 = YamlEditor('''
-  ///   - 0
-  ///   - 1 # comment
-  ///   - 2
-  /// ''');
-  /// doc2.remove([1]);
-  /// doc2.insertIntoList([], 1, 'test');
-  /// ```
-  ///
-  /// **Expected Output:**
-  /// ```yaml
-  ///   - 0
-  ///   - test
-  ///   - 2
-  /// ```
-  void update(Iterable<Object> path, Object value) {
-    ArgumentError.checkNotNull(path, 'path');
-
-    final valueNode = wrapAsYamlNode(value);
-
-    if (path.isEmpty) {
-      final start = _contents.span.start.offset;
-      final end = getContentSensitiveEnd(_contents);
-      final lineEnding = getLineEnding(_yaml);
-      final edit = SourceEdit(
-          start, end - start, yamlEncodeBlockString(valueNode, 0, lineEnding));
-
-      return _performEdit(edit, path, valueNode);
-    }
-
-    final pathAsList = path.toList();
-    final collectionPath = pathAsList.take(path.length - 1);
-    final keyOrIndex = pathAsList.last;
-    final parentNode = _traverse(collectionPath, checkAlias: true);
-
-    if (parentNode is YamlList) {
-      final expected = wrapAsYamlNode(
-        [...parentNode.nodes]..[keyOrIndex] = valueNode,
-      );
-
-      return _performEdit(updateInList(this, parentNode, keyOrIndex, valueNode),
-          collectionPath, expected);
-    }
-
-    if (parentNode is YamlMap) {
-      final expectedMap =
-          updatedYamlMap(parentNode, (nodes) => nodes[keyOrIndex] = valueNode);
-      return _performEdit(updateInMap(this, parentNode, keyOrIndex, valueNode),
-          collectionPath, expectedMap);
-    }
-
-    throw PathError.unexpected(
-        path, 'Scalar $parentNode does not have key $keyOrIndex');
-  }
-
-  /// Appends [value] to the list at [path].
-  ///
-  /// Throws a [ArgumentError] if the element at the given path is not a
-  /// [YamlList] or if the path is invalid.
-  ///
-  /// **Example:**
-  /// ```dart
-  /// final doc = YamlEditor('[0, 1]');
-  /// doc.appendToList([], 2); // [0, 1, 2]
-  /// ```
-  void appendToList(Iterable<Object> path, Object value) {
-    ArgumentError.checkNotNull(path, 'path');
-    final yamlList = _traverseToList(path);
-
-    insertIntoList(path, yamlList.length, value);
-  }
-
-  /// Prepends [value] to the list at [path].
-  ///
-  /// Throws a [ArgumentError] if the element at the given path is not a
-  /// [YamlList] or if the path is invalid.
-  ///
-  /// **Example:**
-  /// ```dart
-  /// final doc = YamlEditor('[1, 2]');
-  /// doc.prependToList([], 0); // [0, 1, 2]
-  /// ```
-  void prependToList(Iterable<Object> path, Object value) {
-    ArgumentError.checkNotNull(path, 'path');
-
-    insertIntoList(path, 0, value);
-  }
-
-  /// Inserts [value] into the list at [path].
-  ///
-  /// [index] must be non-negative and no greater than the list's length.
-  ///
-  /// Throws a [ArgumentError] if the element at the given path is not a
-  /// [YamlList] or if the path is invalid.
-  ///
-  /// **Example:**
-  /// ```dart
-  /// final doc = YamlEditor('[0, 2]');
-  /// doc.insertIntoList([], 1, 1); // [0, 1, 2]
-  /// ```
-  void insertIntoList(Iterable<Object> path, int index, Object value) {
-    ArgumentError.checkNotNull(path, 'path');
-    final valueNode = wrapAsYamlNode(value);
-
-    final list = _traverseToList(path, checkAlias: true);
-    RangeError.checkValueInInterval(index, 0, list.length);
-
-    final edit = insertInList(this, list, index, valueNode);
-    final expected = wrapAsYamlNode(
-      [...list.nodes]..insert(index, valueNode),
-    );
-
-    _performEdit(edit, path, expected);
-  }
-
-  /// Changes the contents of the list at [path] by removing [deleteCount] items
-  /// at [index], and inserting [values] in-place. Returns the elements that
-  /// are deleted.
-  ///
-  /// [index] and [deleteCount] must be non-negative and [index] + [deleteCount]
-  /// must be no greater than the list's length.
-  ///
-  /// Throws a [ArgumentError] if the element at the given path is not a
-  /// [YamlList] or if the path is invalid.
-  ///
-  /// **Example:**
-  /// ```dart
-  /// final doc = YamlEditor('[Jan, March, April, June]');
-  /// doc.spliceList([], 1, 0, ['Feb']); // [Jan, Feb, March, April, June]
-  /// doc.spliceList([], 4, 1, ['May']); // [Jan, Feb, March, April, May]
-  /// ```
-  Iterable<YamlNode> spliceList(Iterable<Object> path, int index,
-      int deleteCount, Iterable<Object> values) {
-    ArgumentError.checkNotNull(path, 'path');
-    ArgumentError.checkNotNull(index, 'index');
-    ArgumentError.checkNotNull(deleteCount, 'deleteCount');
-    ArgumentError.checkNotNull(values, 'values');
-
-    final list = _traverseToList(path, checkAlias: true);
-
-    RangeError.checkValueInInterval(index, 0, list.length);
-    RangeError.checkValueInInterval(index + deleteCount, 0, list.length);
-
-    final nodesToRemove = list.nodes.getRange(index, index + deleteCount);
-
-    /// Perform addition of elements before removal to avoid scenarioes where
-    /// a block list gets emptied out to {} to avoid changing collection styles
-    /// where possible.
-
-    /// Reverse [values] and insert them.
-    final reversedValues = values.toList().reversed;
-    for (final value in reversedValues) {
-      insertIntoList(path, index, value);
-    }
-
-    for (var i = 0; i < deleteCount; i++) {
-      remove([...path, index + values.length]);
-    }
-
-    return nodesToRemove;
-  }
-
-  /// Removes the node at [path]. Comments "belonging" to the node will be
-  /// removed while surrounding comments will be left untouched.
-  ///
-  /// Throws a [ArgumentError] if [path] is invalid.
-  ///
-  /// **Example:**
-  /// ```dart
-  /// final doc = YamlEditor('''
-  /// - 0 # comment 0
-  /// # comment A
-  /// - 1 # comment 1
-  /// # comment B
-  /// - 2 # comment 2
-  /// ''');
-  /// doc.remove([1]);
-  /// ```
-  ///
-  /// **Expected Result:**
-  /// ```dart
-  /// '''
-  /// - 0 # comment 0
-  /// # comment A
-  /// # comment B
-  /// - 2 # comment 2
-  /// '''
-  /// ```
-  YamlNode remove(Iterable<Object> path) {
-    ArgumentError.checkNotNull(path, 'path');
-
-    SourceEdit edit;
-    YamlNode expectedNode;
-    final nodeToRemove = _traverse(path, checkAlias: true);
-
-    if (path.isEmpty) {
-      edit = SourceEdit(0, _yaml.length, '');
-
-      /// Parsing an empty YAML document returns `null`.
-      _performEdit(edit, path, expectedNode);
-      return nodeToRemove;
-    }
-
-    final pathAsList = path.toList();
-    final collectionPath = pathAsList.take(path.length - 1);
-    final keyOrIndex = pathAsList.last;
-    final parentNode = _traverse(collectionPath);
-
-    if (parentNode is YamlList) {
-      edit = removeInList(this, parentNode, keyOrIndex);
-      expectedNode = wrapAsYamlNode(
-        [...parentNode.nodes]..removeAt(keyOrIndex),
-      );
-    } else if (parentNode is YamlMap) {
-      edit = removeInMap(this, parentNode, keyOrIndex);
-
-      expectedNode =
-          updatedYamlMap(parentNode, (nodes) => nodes.remove(keyOrIndex));
-    }
-
-    _performEdit(edit, collectionPath, expectedNode);
-
-    return nodeToRemove;
-  }
-
-  /// Traverses down [path] to return the [YamlNode] at [path] if successful.
-  ///
-  /// If no [YamlNode]s exist at [path], the result of invoking the [orElse]
-  /// function is returned.
-  ///
-  /// If [orElse] is omitted, it defaults to throwing a [PathError].
-  ///
-  /// If [checkAlias] is `true`, throw [AliasError] if an aliased node is
-  /// encountered.
-  YamlNode _traverse(Iterable<Object> path,
-      {bool checkAlias = false, YamlNode Function() orElse}) {
-    ArgumentError.checkNotNull(path, 'path');
-    ArgumentError.checkNotNull(checkAlias, 'checkAlias');
-
-    if (path.isEmpty) return _contents;
-
-    var currentNode = _contents;
-    final pathList = path.toList();
-
-    for (var i = 0; i < pathList.length; i++) {
-      final keyOrIndex = pathList[i];
-
-      if (checkAlias && _aliases.contains(currentNode)) {
-        throw AliasError(path, currentNode);
-      }
-
-      if (currentNode is YamlList) {
-        final list = currentNode as YamlList;
-        if (!isValidIndex(keyOrIndex, list.length)) {
-          return _pathErrorOrElse(path, path.take(i + 1), list, orElse);
-        }
-
-        currentNode = list.nodes[keyOrIndex];
-      } else if (currentNode is YamlMap) {
-        final map = currentNode as YamlMap;
-
-        if (!containsKey(map, keyOrIndex)) {
-          return _pathErrorOrElse(path, path.take(i + 1), map, orElse);
-        }
-        final keyNode = getKeyNode(map, keyOrIndex);
-
-        if (checkAlias) {
-          if (_aliases.contains(keyNode)) throw AliasError(path, keyNode);
-        }
-
-        currentNode = map.nodes[keyNode];
-      } else {
-        return _pathErrorOrElse(path, path.take(i + 1), currentNode, orElse);
-      }
-    }
-
-    if (checkAlias) _assertNoChildAlias(path, currentNode);
-
-    return currentNode;
-  }
-
-  /// Throws a [PathError] if [orElse] is not provided, returns the result
-  /// of invoking the [orElse] function otherwise.
-  YamlNode _pathErrorOrElse(Iterable<Object> path, Iterable<Object> subPath,
-      YamlNode parent, YamlNode Function() orElse) {
-    if (orElse == null) throw PathError(path, subPath, parent);
-    return orElse();
-  }
-
-  /// Asserts that [node] and none its children are aliases
-  void _assertNoChildAlias(Iterable<Object> path, [YamlNode node]) {
-    ArgumentError.checkNotNull(path, 'path');
-
-    if (node == null) return _assertNoChildAlias(path, _traverse(path));
-    if (_aliases.contains(node)) throw AliasError(path, node);
-
-    if (node is YamlScalar) return;
-
-    if (node is YamlList) {
-      for (var i = 0; i < node.length; i++) {
-        final updatedPath = [...path, i];
-        _assertNoChildAlias(updatedPath, node.nodes[i]);
-      }
-    }
-
-    if (node is YamlMap) {
-      final keyList = node.keys.toList();
-      for (var i = 0; i < node.length; i++) {
-        final updatedPath = [...path, keyList[i]];
-        if (_aliases.contains(keyList[i])) throw AliasError(path, keyList[i]);
-        _assertNoChildAlias(updatedPath, node.nodes[keyList[i]]);
-      }
-    }
-  }
-
-  /// Traverses down the provided [path] to return the [YamlList] at [path].
-  ///
-  /// Convenience function to ensure that a [YamlList] is returned.
-  ///
-  /// Throws [ArgumentError] if the element at the given path is not a
-  /// [YamlList] or if the path is invalid. If [checkAlias] is `true`, and an
-  /// aliased node is encountered along [path], an [AliasError] will be thrown.
-  YamlList _traverseToList(Iterable<Object> path, {bool checkAlias = false}) {
-    ArgumentError.checkNotNull(path, 'path');
-    ArgumentError.checkNotNull(checkAlias, 'checkAlias');
-
-    final possibleList = _traverse(path, checkAlias: true);
-
-    if (possibleList is YamlList) {
-      return possibleList;
-    } else {
-      throw PathError.unexpected(
-          path, 'Path $path does not point to a YamlList!');
-    }
-  }
-
-  /// Utility method to replace the substring of [_yaml] according to [edit].
-  ///
-  /// When [_yaml] is modified with this method, the resulting string is parsed
-  /// and reloaded and traversed down [path] to ensure that the reloaded YAML
-  /// tree is equal to our expectations by deep equality of values. Throws an
-  /// [AssertionError] if the two trees do not match.
-  void _performEdit(
-      SourceEdit edit, Iterable<Object> path, YamlNode expectedNode) {
-    ArgumentError.checkNotNull(edit, 'edit');
-    ArgumentError.checkNotNull(path, 'path');
-
-    final expectedTree = _deepModify(_contents, path, [], expectedNode);
-    final initialYaml = _yaml;
-    _yaml = edit.apply(_yaml);
-
-    try {
-      _initialize();
-    } on YamlException {
-      throw createAssertionError(
-          'Failed to produce valid YAML after modification.',
-          initialYaml,
-          _yaml);
-    }
-
-    final actualTree = loadYamlNode(_yaml);
-    if (!deepEquals(actualTree, expectedTree)) {
-      throw createAssertionError(
-          'Modification did not result in expected result.',
-          initialYaml,
-          _yaml);
-    }
-    _contents = actualTree;
-    _edits.add(edit);
-  }
-
-  /// Utility method to produce an updated YAML tree equivalent to converting
-  /// the [YamlNode] at [path] to be [expectedNode]. [subPath] holds the portion
-  /// of [path] that has been traversed thus far.
-  ///
-  /// Throws a [PathError] if path is invalid.
-  ///
-  /// When called, it creates a new [YamlNode] of the same type as [tree], and
-  /// copies its children over, except for the child that is on the path. Doing
-  /// so allows us to "update" the immutable [YamlNode] without having to clone
-  /// the whole tree.
-  ///
-  /// [SourceSpan]s in this new tree are not guaranteed to be accurate.
-  YamlNode _deepModify(YamlNode tree, Iterable<Object> path,
-      Iterable<Object> subPath, YamlNode expectedNode) {
-    ArgumentError.checkNotNull(path, 'path');
-    ArgumentError.checkNotNull(tree, 'tree');
-    RangeError.checkValueInInterval(subPath.length, 0, path.length);
-
-    if (path.length == subPath.length) return expectedNode;
-
-    final keyOrIndex = path.elementAt(subPath.length);
-
-    if (tree is YamlList) {
-      if (!isValidIndex(keyOrIndex, tree.length)) {
-        throw PathError(path, subPath, tree);
-      }
-
-      return wrapAsYamlNode([...tree.nodes]..[keyOrIndex] = _deepModify(
-          tree.nodes[keyOrIndex],
-          path,
-          path.take(subPath.length + 1),
-          expectedNode));
-    }
-
-    if (tree is YamlMap) {
-      return updatedYamlMap(
-          tree,
-          (nodes) => nodes[keyOrIndex] = _deepModify(nodes[keyOrIndex], path,
-              path.take(subPath.length + 1), expectedNode));
-    }
-
-    /// Should not ever reach here.
-    throw PathError(path, subPath, tree);
-  }
-}
diff --git a/lib/src/yaml_edit/equality.dart b/lib/src/yaml_edit/equality.dart
deleted file mode 100644
index e7cce40..0000000
--- a/lib/src/yaml_edit/equality.dart
+++ /dev/null
@@ -1,118 +0,0 @@
-// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-// @dart=2.10
-
-import 'dart:collection';
-
-import 'package:collection/collection.dart';
-import 'package:yaml/yaml.dart';
-
-/// Creates a map that uses our custom [deepEquals] and [deepHashCode] functions
-/// to determine equality.
-Map<K, V> deepEqualsMap<K, V>() =>
-    LinkedHashMap(equals: deepEquals, hashCode: deepHashCode);
-
-/// Compares two [Object]s for deep equality. This implementation differs from
-/// `package:yaml`'s deep equality notation by allowing for comparison of
-/// non-scalar map keys.
-bool deepEquals(dynamic obj1, dynamic obj2) {
-  if (obj1 is YamlNode) obj1 = obj1.value;
-  if (obj2 is YamlNode) obj2 = obj2.value;
-
-  if (obj1 is Map && obj2 is Map) {
-    return mapDeepEquals(obj1, obj2);
-  }
-
-  if (obj1 is List && obj2 is List) {
-    return listDeepEquals(obj1, obj2);
-  }
-
-  return obj1 == obj2;
-}
-
-/// Compares two [List]s for deep equality.
-bool listDeepEquals(List list1, List list2) {
-  if (list1.length != list2.length) return false;
-
-  if (list1 is YamlList) list1 = (list1 as YamlList).nodes;
-  if (list2 is YamlList) list2 = (list2 as YamlList).nodes;
-
-  for (var i = 0; i < list1.length; i++) {
-    if (!deepEquals(list1[i], list2[i])) {
-      return false;
-    }
-  }
-
-  return true;
-}
-
-/// Compares two [Map]s for deep equality. Differs from `package:yaml`'s deep
-/// equality notation by allowing for comparison of non-scalar map keys.
-bool mapDeepEquals(Map map1, Map map2) {
-  if (map1.length != map2.length) return false;
-
-  if (map1 is YamlList) map1 = (map1 as YamlMap).nodes;
-  if (map2 is YamlList) map2 = (map2 as YamlMap).nodes;
-
-  return map1.keys.every((key) {
-    if (!containsKey(map2, key)) return false;
-
-    /// Because two keys may be equal by deep equality but using one key on the
-    /// other map might not get a hit since they may not be both using our
-    /// [deepEqualsMap].
-    final key2 = getKey(map2, key);
-
-    if (!deepEquals(map1[key], map2[key2])) {
-      return false;
-    }
-
-    return true;
-  });
-}
-
-/// Returns a hashcode for [value] such that structures that are equal by
-/// [deepEquals] will have the same hash code.
-int deepHashCode(Object value) {
-  if (value is Map) {
-    const equality = UnorderedIterableEquality();
-    return equality.hash(value.keys.map(deepHashCode)) ^
-        equality.hash(value.values.map(deepHashCode));
-  } else if (value is Iterable) {
-    return const IterableEquality().hash(value.map(deepHashCode));
-  } else if (value is YamlScalar) {
-    return value.value.hashCode;
-  }
-
-  return value.hashCode;
-}
-
-/// Returns the [YamlNode] corresponding to the provided [key].
-YamlNode getKeyNode(YamlMap map, Object key) {
-  return map.nodes.keys.firstWhere((node) => deepEquals(node, key)) as YamlNode;
-}
-
-/// Returns the [YamlNode] after the [YamlNode] corresponding to the provided
-/// [key].
-YamlNode getNextKeyNode(YamlMap map, Object key) {
-  final keyIterator = map.nodes.keys.iterator;
-  while (keyIterator.moveNext()) {
-    if (deepEquals(keyIterator.current, key) && keyIterator.moveNext()) {
-      return keyIterator.current;
-    }
-  }
-
-  return null;
-}
-
-/// Returns the key in [map] that is equal to the provided [key] by the notion
-/// of deep equality.
-Object getKey(Map map, Object key) {
-  return map.keys.firstWhere((k) => deepEquals(k, key));
-}
-
-/// Checks if [map] has any keys equal to the provided [key] by deep equality.
-bool containsKey(Map map, Object key) {
-  return map.keys.where((node) => deepEquals(node, key)).isNotEmpty;
-}
diff --git a/lib/src/yaml_edit/errors.dart b/lib/src/yaml_edit/errors.dart
deleted file mode 100644
index 7d490a9..0000000
--- a/lib/src/yaml_edit/errors.dart
+++ /dev/null
@@ -1,102 +0,0 @@
-// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-// @dart=2.10
-
-import 'package:meta/meta.dart';
-import 'package:yaml/yaml.dart';
-
-/// Error thrown when a function is passed an invalid path.
-@sealed
-class PathError extends ArgumentError {
-  /// The full path that caused the error
-  final Iterable<Object> path;
-
-  /// The subpath that caused the error
-  final Iterable<Object> subPath;
-
-  /// The last element of [path] that could be traversed.
-  YamlNode parent;
-
-  PathError(this.path, this.subPath, this.parent, [String message])
-      : super.value(subPath, 'path', message);
-
-  PathError.unexpected(this.path, String message)
-      : subPath = path,
-        super(message);
-
-  @override
-  String toString() {
-    if (message == null) {
-      var errorMessage = 'Failed to traverse to subpath $subPath!';
-
-      if (subPath.isNotEmpty) {
-        errorMessage +=
-            ' Parent $parent does not contain key or index ${subPath.last}';
-      }
-
-      return 'Invalid path: $path. $errorMessage.';
-    }
-
-    return 'Invalid path: $path. $message';
-  }
-}
-
-/// Error thrown when the path contains an alias along the way.
-///
-/// When a path contains an aliased node, the behavior becomes less well-defined
-/// because we cannot be certain if the user wishes for the change to
-/// propagate throughout all the other aliased nodes, or if the user wishes
-/// for only that particular node to be modified. As such, [AliasError] reflects
-/// the detection that our change will impact an alias, and we do not intend
-/// on supporting such changes for the foreseeable future.
-@sealed
-class AliasError extends UnsupportedError {
-  /// The path that caused the error
-  final Iterable<Object> path;
-
-  /// The anchor node of the alias
-  final YamlNode anchor;
-
-  AliasError(this.path, this.anchor)
-      : super('Encountered an alias node along $path! '
-            'Alias nodes are nodes that refer to a previously serialized nodes, '
-            'and are denoted by either the "*" or the "&" indicators in the '
-            'original YAML. As the resulting behavior of mutations on these '
-            'nodes is not well-defined, the operation will not be supported '
-            'by this library.\n\n'
-            '${anchor.span.message('The alias was first defined here.')}');
-}
-
-/// Error thrown when an assertion about the YAML fails. Extends
-/// [AssertionError] to override the [toString] method for pretty printing.
-class _YamlAssertionError extends AssertionError {
-  _YamlAssertionError(message) : super(message);
-
-  @override
-  String toString() {
-    if (message != null) {
-      return 'Assertion failed: $message';
-    }
-    return 'Assertion failed';
-  }
-}
-
-/// Throws an [AssertionError] with the given [message], and format
-/// [oldYaml] and [newYaml] for information.
-Error createAssertionError(String message, String oldYaml, String newYaml) {
-  return _YamlAssertionError('''
-(package:yaml_edit) $message
-
-# YAML before edit:
-> ${oldYaml.replaceAll('\n', '\n> ')}
-
-# YAML after edit:
-> ${newYaml.replaceAll('\n', '\n> ')}
-
-Please file an issue at:
-'''
-      'https://github.com/google/dart-neats/issues/new?labels=pkg%3Ayaml_edit'
-      '%2C+pending-triage&template=yaml_edit.md\n');
-}
diff --git a/lib/src/yaml_edit/list_mutations.dart b/lib/src/yaml_edit/list_mutations.dart
deleted file mode 100644
index 224b87c..0000000
--- a/lib/src/yaml_edit/list_mutations.dart
+++ /dev/null
@@ -1,337 +0,0 @@
-// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-// @dart=2.10
-
-import 'package:yaml/yaml.dart';
-
-import 'editor.dart';
-import 'source_edit.dart';
-import 'strings.dart';
-import 'utils.dart';
-import 'wrap.dart';
-
-/// Returns a [SourceEdit] describing the change to be made on [yaml] to achieve
-/// the effect of setting the element at [index] to [newValue] when re-parsed.
-SourceEdit updateInList(
-    YamlEditor yamlEdit, YamlList list, int index, YamlNode newValue) {
-  ArgumentError.checkNotNull(yamlEdit, 'yamlEdit');
-  ArgumentError.checkNotNull(list, 'list');
-  RangeError.checkValueInInterval(index, 0, list.length - 1);
-
-  final currValue = list.nodes[index];
-  var offset = currValue.span.start.offset;
-  final yaml = yamlEdit.toString();
-  String valueString;
-
-  /// We do not use [_formatNewBlock] since we want to only replace the contents
-  /// of this node while preserving comments/whitespace, while [_formatNewBlock]
-  /// produces a string representation of a new node.
-  if (list.style == CollectionStyle.BLOCK) {
-    final listIndentation = getListIndentation(yaml, list);
-    final indentation = listIndentation + getIndentation(yamlEdit);
-    final lineEnding = getLineEnding(yaml);
-    valueString = yamlEncodeBlockString(
-        wrapAsYamlNode(newValue), indentation, lineEnding);
-
-    /// We prefer the compact nested notation for collections.
-    ///
-    /// By virtue of [yamlEncodeBlockString], collections automatically
-    /// have the necessary line endings.
-    if ((newValue is List && (newValue as List).isNotEmpty) ||
-        (newValue is Map && (newValue as Map).isNotEmpty)) {
-      valueString = valueString.substring(indentation);
-    } else if (isCollection(currValue) &&
-        getStyle(currValue) == CollectionStyle.BLOCK) {
-      valueString += lineEnding;
-    }
-
-    var end = getContentSensitiveEnd(currValue);
-    if (end <= offset) {
-      offset++;
-      end = offset;
-      valueString = ' ' + valueString;
-    }
-
-    return SourceEdit(offset, end - offset, valueString);
-  } else {
-    valueString = yamlEncodeFlowString(newValue);
-    return SourceEdit(offset, currValue.span.length, valueString);
-  }
-}
-
-/// Returns a [SourceEdit] describing the change to be made on [yaml] to achieve
-/// the effect of appending [item] to the list.
-SourceEdit appendIntoList(YamlEditor yamlEdit, YamlList list, YamlNode item) {
-  ArgumentError.checkNotNull(yamlEdit, 'yamlEdit');
-  ArgumentError.checkNotNull(list, 'list');
-
-  if (list.style == CollectionStyle.FLOW) {
-    return _appendToFlowList(yamlEdit, list, item);
-  } else {
-    return _appendToBlockList(yamlEdit, list, item);
-  }
-}
-
-/// Returns a [SourceEdit] describing the change to be made on [yaml] to achieve
-/// the effect of inserting [item] to the list at [index].
-SourceEdit insertInList(
-    YamlEditor yamlEdit, YamlList list, int index, YamlNode item) {
-  ArgumentError.checkNotNull(yamlEdit, 'yamlEdit');
-  ArgumentError.checkNotNull(list, 'list');
-  RangeError.checkValueInInterval(index, 0, list.length);
-
-  /// We call the append method if the user wants to append it to the end of the
-  /// list because appending requires different techniques.
-  if (index == list.length) {
-    return appendIntoList(yamlEdit, list, item);
-  } else {
-    if (list.style == CollectionStyle.FLOW) {
-      return _insertInFlowList(yamlEdit, list, index, item);
-    } else {
-      return _insertInBlockList(yamlEdit, list, index, item);
-    }
-  }
-}
-
-/// Returns a [SourceEdit] describing the change to be made on [yaml] to achieve
-/// the effect of removing the element at [index] when re-parsed.
-SourceEdit removeInList(YamlEditor yamlEdit, YamlList list, int index) {
-  ArgumentError.checkNotNull(yamlEdit, 'yamlEdit');
-  ArgumentError.checkNotNull(list, 'list');
-
-  final nodeToRemove = list.nodes[index];
-
-  if (list.style == CollectionStyle.FLOW) {
-    return _removeFromFlowList(yamlEdit, list, nodeToRemove, index);
-  } else {
-    return _removeFromBlockList(yamlEdit, list, nodeToRemove, index);
-  }
-}
-
-/// Returns a [SourceEdit] describing the change to be made on [yaml] to achieve
-/// the effect of addition [item] into [nodes], noting that this is a flow list.
-SourceEdit _appendToFlowList(
-    YamlEditor yamlEdit, YamlList list, YamlNode item) {
-  ArgumentError.checkNotNull(yamlEdit, 'yamlEdit');
-  ArgumentError.checkNotNull(list, 'list');
-
-  final valueString = _formatNewFlow(list, item, true);
-  return SourceEdit(list.span.end.offset - 1, 0, valueString);
-}
-
-/// Returns a [SourceEdit] describing the change to be made on [yaml] to achieve
-/// the effect of addition [item] into [nodes], noting that this is a block list.
-SourceEdit _appendToBlockList(
-    YamlEditor yamlEdit, YamlList list, YamlNode item) {
-  ArgumentError.checkNotNull(yamlEdit, 'yamlEdit');
-  ArgumentError.checkNotNull(list, 'list');
-
-  var formattedValue = _formatNewBlock(yamlEdit, list, item);
-  final yaml = yamlEdit.toString();
-  var offset = list.span.end.offset;
-
-  // Adjusts offset to after the trailing newline of the last entry, if it exists
-  if (list.isNotEmpty) {
-    final lastValueSpanEnd = list.nodes.last.span.end.offset;
-    final nextNewLineIndex = yaml.indexOf('\n', lastValueSpanEnd);
-    if (nextNewLineIndex == -1) {
-      formattedValue = getLineEnding(yaml) + formattedValue;
-    } else {
-      offset = nextNewLineIndex + 1;
-    }
-  }
-
-  return SourceEdit(offset, 0, formattedValue);
-}
-
-/// Formats [item] into a new node for block lists.
-String _formatNewBlock(YamlEditor yamlEdit, YamlList list, YamlNode item) {
-  ArgumentError.checkNotNull(yamlEdit, 'yamlEdit');
-  ArgumentError.checkNotNull(list, 'list');
-
-  final yaml = yamlEdit.toString();
-  final listIndentation = getListIndentation(yaml, list);
-  final newIndentation = listIndentation + getIndentation(yamlEdit);
-  final lineEnding = getLineEnding(yaml);
-
-  var valueString = yamlEncodeBlockString(item, newIndentation, lineEnding);
-  if (isCollection(item) && !isFlowYamlCollectionNode(item) && !isEmpty(item)) {
-    valueString = valueString.substring(newIndentation);
-  }
-  final indentedHyphen = ' ' * listIndentation + '- ';
-
-  return '$indentedHyphen$valueString$lineEnding';
-}
-
-/// Formats [item] into a new node for flow lists.
-String _formatNewFlow(YamlList list, YamlNode item, [bool isLast = false]) {
-  ArgumentError.checkNotNull(list, 'list');
-  ArgumentError.checkNotNull(isLast, 'isLast');
-
-  var valueString = yamlEncodeFlowString(item);
-  if (list.isNotEmpty) {
-    if (isLast) {
-      valueString = ', $valueString';
-    } else {
-      valueString += ', ';
-    }
-  }
-
-  return valueString;
-}
-
-/// Returns a [SourceEdit] describing the change to be made on [yaml] to achieve
-/// the effect of inserting [item] into [nodes] at [index], noting that this is
-/// a block list.
-///
-/// [index] should be non-negative and less than or equal to [length].
-SourceEdit _insertInBlockList(
-    YamlEditor yamlEdit, YamlList list, int index, YamlNode item) {
-  ArgumentError.checkNotNull(yamlEdit, 'yamlEdit');
-  ArgumentError.checkNotNull(list, 'list');
-  RangeError.checkValueInInterval(index, 0, list.length);
-
-  if (index == list.length) return _appendToBlockList(yamlEdit, list, item);
-
-  final formattedValue = _formatNewBlock(yamlEdit, list, item);
-
-  final currNode = list.nodes[index];
-  final currNodeStart = currNode.span.start.offset;
-  final yaml = yamlEdit.toString();
-  final start = yaml.lastIndexOf('\n', currNodeStart) + 1;
-
-  return SourceEdit(start, 0, formattedValue);
-}
-
-/// Returns a [SourceEdit] describing the change to be made on [yaml] to achieve
-/// the effect of inserting [item] into [nodes] at [index], noting that this is
-/// a flow list.
-///
-/// [index] should be non-negative and less than or equal to [length].
-SourceEdit _insertInFlowList(
-    YamlEditor yamlEdit, YamlList list, int index, YamlNode item) {
-  ArgumentError.checkNotNull(yamlEdit, 'yamlEdit');
-  ArgumentError.checkNotNull(list, 'list');
-  RangeError.checkValueInInterval(index, 0, list.length);
-
-  if (index == list.length) return _appendToFlowList(yamlEdit, list, item);
-
-  final formattedValue = _formatNewFlow(list, item);
-
-  final yaml = yamlEdit.toString();
-  final currNode = list.nodes[index];
-  final currNodeStart = currNode.span.start.offset;
-  var start = yaml.lastIndexOf(RegExp(r',|\['), currNodeStart - 1) + 1;
-  if (yaml[start] == ' ') start++;
-
-  return SourceEdit(start, 0, formattedValue);
-}
-
-/// Returns a [SourceEdit] describing the change to be made on [yaml] to achieve
-/// the effect of removing [nodeToRemove] from [nodes], noting that this is a
-/// block list.
-///
-/// [index] should be non-negative and less than or equal to [length].
-SourceEdit _removeFromBlockList(
-    YamlEditor yamlEdit, YamlList list, YamlNode nodeToRemove, int index) {
-  ArgumentError.checkNotNull(yamlEdit, 'yamlEdit');
-  ArgumentError.checkNotNull(list, 'list');
-  RangeError.checkValueInInterval(index, 0, list.length - 1);
-
-  var end = getContentSensitiveEnd(nodeToRemove);
-
-  /// If we are removing the last element in a block list, convert it into a
-  /// flow empty list.
-  if (list.length == 1) {
-    final start = list.span.start.offset;
-
-    return SourceEdit(start, end - start, '[]');
-  }
-
-  final yaml = yamlEdit.toString();
-  final span = nodeToRemove.span;
-
-  /// Adjust the end to clear the new line after the end too.
-  ///
-  /// We do this because we suspect that our users will want the inline
-  /// comments to disappear too.
-  final nextNewLine = yaml.indexOf('\n', end);
-  if (nextNewLine != -1) {
-    end = nextNewLine + 1;
-  }
-
-  /// If the value is empty
-  if (span.length == 0) {
-    var start = span.start.offset;
-    return SourceEdit(start, end - start, '');
-  }
-
-  /// -1 accounts for the fact that the content can start with a dash
-  var start = yaml.lastIndexOf('-', span.start.offset - 1);
-
-  /// Check if there is a `-` before the node
-  if (start > 0) {
-    final lastHyphen = yaml.lastIndexOf('-', start - 1);
-    final lastNewLine = yaml.lastIndexOf('\n', start - 1);
-    if (lastHyphen > lastNewLine) {
-      start = lastHyphen + 2;
-
-      /// If there is a `-` before the node, we need to check if we have
-      /// to update the indentation of the next node.
-      if (index < list.length - 1) {
-        /// Since [end] is currently set to the next new line after the current
-        /// node, check if we see a possible comment first, or a hyphen first.
-        /// Note that no actual content can appear here.
-        ///
-        /// We check this way because the start of a span in a block list is
-        /// the start of its value, and checking from the back leaves us
-        /// easily confused if there are comments that have dashes in them.
-        final nextHash = yaml.indexOf('#', end);
-        final nextHyphen = yaml.indexOf('-', end);
-        final nextNewLine = yaml.indexOf('\n', end);
-
-        /// If [end] is on the same line as the hyphen of the next node
-        if ((nextHash == -1 || nextHyphen < nextHash) &&
-            nextHyphen < nextNewLine) {
-          end = nextHyphen;
-        }
-      }
-    } else if (lastNewLine > lastHyphen) {
-      start = lastNewLine + 1;
-    }
-  }
-
-  return SourceEdit(start, end - start, '');
-}
-
-/// Returns a [SourceEdit] describing the change to be made on [yaml] to achieve
-/// the effect of removing [nodeToRemove] from [nodes], noting that this is a
-/// flow list.
-///
-/// [index] should be non-negative and less than or equal to [length].
-SourceEdit _removeFromFlowList(
-    YamlEditor yamlEdit, YamlList list, YamlNode nodeToRemove, int index) {
-  ArgumentError.checkNotNull(yamlEdit, 'yamlEdit');
-  ArgumentError.checkNotNull(list, 'list');
-  RangeError.checkValueInInterval(index, 0, list.length - 1);
-
-  final span = nodeToRemove.span;
-  final yaml = yamlEdit.toString();
-  var start = span.start.offset;
-  var end = span.end.offset;
-
-  if (index == 0) {
-    start = yaml.lastIndexOf('[', start - 1) + 1;
-    if (index == list.length - 1) {
-      end = yaml.indexOf(']', end);
-    } else {
-      end = yaml.indexOf(',', end) + 1;
-    }
-  } else {
-    start = yaml.lastIndexOf(',', start - 1);
-  }
-
-  return SourceEdit(start, end - start, '');
-}
diff --git a/lib/src/yaml_edit/map_mutations.dart b/lib/src/yaml_edit/map_mutations.dart
deleted file mode 100644
index 597c0ba..0000000
--- a/lib/src/yaml_edit/map_mutations.dart
+++ /dev/null
@@ -1,264 +0,0 @@
-// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-// @dart=2.10
-
-import 'package:yaml/yaml.dart';
-
-import 'editor.dart';
-import 'equality.dart';
-import 'source_edit.dart';
-import 'strings.dart';
-import 'utils.dart';
-import 'wrap.dart';
-
-/// Performs the string operation on [yaml] to achieve the effect of setting
-/// the element at [key] to [newValue] when re-parsed.
-SourceEdit updateInMap(
-    YamlEditor yamlEdit, YamlMap map, Object key, YamlNode newValue) {
-  ArgumentError.checkNotNull(yamlEdit, 'yamlEdit');
-  ArgumentError.checkNotNull(map, 'map');
-
-  if (!containsKey(map, key)) {
-    final keyNode = wrapAsYamlNode(key);
-
-    if (map.style == CollectionStyle.FLOW) {
-      return _addToFlowMap(yamlEdit, map, keyNode, newValue);
-    } else {
-      return _addToBlockMap(yamlEdit, map, keyNode, newValue);
-    }
-  } else {
-    if (map.style == CollectionStyle.FLOW) {
-      return _replaceInFlowMap(yamlEdit, map, key, newValue);
-    } else {
-      return _replaceInBlockMap(yamlEdit, map, key, newValue);
-    }
-  }
-}
-
-/// Performs the string operation on [yaml] to achieve the effect of removing
-/// the element at [key] when re-parsed.
-SourceEdit removeInMap(YamlEditor yamlEdit, YamlMap map, Object key) {
-  ArgumentError.checkNotNull(yamlEdit, 'yamlEdit');
-  ArgumentError.checkNotNull(map, 'map');
-
-  if (!containsKey(map, key)) return null;
-
-  final keyNode = getKeyNode(map, key);
-  final valueNode = map.nodes[keyNode];
-
-  if (map.style == CollectionStyle.FLOW) {
-    return _removeFromFlowMap(yamlEdit, map, keyNode, valueNode);
-  } else {
-    return _removeFromBlockMap(yamlEdit, map, keyNode, valueNode);
-  }
-}
-
-/// Performs the string operation on [yaml] to achieve the effect of adding
-/// the [key]:[newValue] pair when reparsed, bearing in mind that this is a
-/// block map.
-SourceEdit _addToBlockMap(
-    YamlEditor yamlEdit, YamlMap map, Object key, YamlNode newValue) {
-  ArgumentError.checkNotNull(yamlEdit, 'yamlEdit');
-  ArgumentError.checkNotNull(map, 'map');
-
-  final yaml = yamlEdit.toString();
-  final newIndentation =
-      getMapIndentation(yaml, map) + getIndentation(yamlEdit);
-  final keyString = yamlEncodeFlowString(wrapAsYamlNode(key));
-  final lineEnding = getLineEnding(yaml);
-
-  var valueString = yamlEncodeBlockString(newValue, newIndentation, lineEnding);
-  if (isCollection(newValue) &&
-      !isFlowYamlCollectionNode(newValue) &&
-      !isEmpty(newValue)) {
-    valueString = '$lineEnding$valueString';
-  }
-
-  var formattedValue = ' ' * getMapIndentation(yaml, map) + '$keyString: ';
-  var offset = map.span.end.offset;
-
-  final insertionIndex = getMapInsertionIndex(map, keyString);
-
-  if (map.isNotEmpty) {
-    /// Adjusts offset to after the trailing newline of the last entry, if it
-    /// exists
-    if (insertionIndex == map.length) {
-      final lastValueSpanEnd = getContentSensitiveEnd(map.nodes.values.last);
-      final nextNewLineIndex = yaml.indexOf('\n', lastValueSpanEnd);
-
-      if (nextNewLineIndex != -1) {
-        offset = nextNewLineIndex + 1;
-      } else {
-        formattedValue = lineEnding + formattedValue;
-      }
-    } else {
-      final keyAtIndex = map.nodes.keys.toList()[insertionIndex] as YamlNode;
-      final keySpanStart = keyAtIndex.span.start.offset;
-      final prevNewLineIndex = yaml.lastIndexOf('\n', keySpanStart);
-
-      offset = prevNewLineIndex + 1;
-    }
-  }
-
-  formattedValue += valueString + lineEnding;
-
-  return SourceEdit(offset, 0, formattedValue);
-}
-
-/// Performs the string operation on [yaml] to achieve the effect of adding
-/// the [key]:[newValue] pair when reparsed, bearing in mind that this is a flow
-/// map.
-SourceEdit _addToFlowMap(
-    YamlEditor yamlEdit, YamlMap map, YamlNode keyNode, YamlNode newValue) {
-  ArgumentError.checkNotNull(yamlEdit, 'yamlEdit');
-  ArgumentError.checkNotNull(map, 'map');
-
-  final keyString = yamlEncodeFlowString(keyNode);
-  final valueString = yamlEncodeFlowString(newValue);
-
-  // The -1 accounts for the closing bracket.
-  if (map.isEmpty) {
-    return SourceEdit(map.span.end.offset - 1, 0, '$keyString: $valueString');
-  }
-
-  final insertionIndex = getMapInsertionIndex(map, keyString);
-
-  if (insertionIndex == map.length) {
-    return SourceEdit(map.span.end.offset - 1, 0, ', $keyString: $valueString');
-  }
-
-  final insertionOffset =
-      (map.nodes.keys.toList()[insertionIndex] as YamlNode).span.start.offset;
-
-  return SourceEdit(insertionOffset, 0, '$keyString: $valueString, ');
-}
-
-/// Performs the string operation on [yaml] to achieve the effect of replacing
-/// the value at [key] with [newValue] when reparsed, bearing in mind that this
-/// is a block map.
-SourceEdit _replaceInBlockMap(
-    YamlEditor yamlEdit, YamlMap map, Object key, YamlNode newValue) {
-  ArgumentError.checkNotNull(yamlEdit, 'yamlEdit');
-  ArgumentError.checkNotNull(map, 'map');
-
-  final yaml = yamlEdit.toString();
-  final lineEnding = getLineEnding(yaml);
-  final newIndentation =
-      getMapIndentation(yaml, map) + getIndentation(yamlEdit);
-
-  final keyNode = getKeyNode(map, key);
-  var valueAsString = yamlEncodeBlockString(
-      wrapAsYamlNode(newValue), newIndentation, lineEnding);
-  if (isCollection(newValue) &&
-      !isFlowYamlCollectionNode(newValue) &&
-      !isEmpty(newValue)) {
-    valueAsString = lineEnding + valueAsString;
-  }
-
-  /// +1 accounts for the colon
-  final start = keyNode.span.end.offset + 1;
-  var end = getContentSensitiveEnd(map.nodes[key]);
-
-  /// `package:yaml` parses empty nodes in a way where the start/end of the
-  /// empty value node is the end of the key node, so we have to adjust for
-  /// this.
-  if (end < start) end = start;
-
-  return SourceEdit(start, end - start, ' ' + valueAsString);
-}
-
-/// Performs the string operation on [yaml] to achieve the effect of replacing
-/// the value at [key] with [newValue] when reparsed, bearing in mind that this
-/// is a flow map.
-SourceEdit _replaceInFlowMap(
-    YamlEditor yamlEdit, YamlMap map, Object key, YamlNode newValue) {
-  ArgumentError.checkNotNull(yamlEdit, 'yamlEdit');
-  ArgumentError.checkNotNull(map, 'map');
-
-  final valueSpan = map.nodes[key].span;
-  final valueString = yamlEncodeFlowString(newValue);
-
-  return SourceEdit(valueSpan.start.offset, valueSpan.length, valueString);
-}
-
-/// Performs the string operation on [yaml] to achieve the effect of removing
-/// the [key] from the map, bearing in mind that this is a block map.
-SourceEdit _removeFromBlockMap(
-    YamlEditor yamlEdit, YamlMap map, YamlNode keyNode, YamlNode valueNode) {
-  ArgumentError.checkNotNull(yamlEdit, 'yamlEdit');
-  ArgumentError.checkNotNull(map, 'map');
-  ArgumentError.checkNotNull(keyNode, 'keyNode');
-  ArgumentError.checkNotNull(valueNode, 'valueNode');
-
-  final keySpan = keyNode.span;
-  var end = getContentSensitiveEnd(valueNode);
-  final yaml = yamlEdit.toString();
-
-  if (map.length == 1) {
-    final start = map.span.start.offset;
-    return SourceEdit(start, end - start, '{}');
-  }
-
-  var start = keySpan.start.offset;
-
-  /// Adjust the end to clear the new line after the end too.
-  ///
-  /// We do this because we suspect that our users will want the inline
-  /// comments to disappear too.
-  final nextNewLine = yaml.indexOf('\n', end);
-  if (nextNewLine != -1) {
-    end = nextNewLine + 1;
-  }
-
-  final nextNode = getNextKeyNode(map, keyNode);
-
-  if (start > 0) {
-    final lastHyphen = yaml.lastIndexOf('-', start - 1);
-    final lastNewLine = yaml.lastIndexOf('\n', start - 1);
-    if (lastHyphen > lastNewLine) {
-      start = lastHyphen + 2;
-
-      /// If there is a `-` before the node, and the end is on the same line
-      /// as the next node, we need to add the necessary offset to the end to
-      /// make sure the next node has the correct indentation.
-      if (nextNode != null &&
-          nextNode.span.start.offset - end <= nextNode.span.start.column) {
-        end += nextNode.span.start.column;
-      }
-    } else if (lastNewLine > lastHyphen) {
-      start = lastNewLine + 1;
-    }
-  }
-
-  return SourceEdit(start, end - start, '');
-}
-
-/// Performs the string operation on [yaml] to achieve the effect of removing
-/// the [key] from the map, bearing in mind that this is a flow map.
-SourceEdit _removeFromFlowMap(
-    YamlEditor yamlEdit, YamlMap map, YamlNode keyNode, YamlNode valueNode) {
-  ArgumentError.checkNotNull(yamlEdit, 'yamlEdit');
-  ArgumentError.checkNotNull(map, 'map');
-  ArgumentError.checkNotNull(keyNode, 'keyNode');
-  ArgumentError.checkNotNull(valueNode, 'valueNode');
-
-  var start = keyNode.span.start.offset;
-  var end = valueNode.span.end.offset;
-  final yaml = yamlEdit.toString();
-
-  if (deepEquals(keyNode, map.keys.first)) {
-    start = yaml.lastIndexOf('{', start - 1) + 1;
-
-    if (deepEquals(keyNode, map.keys.last)) {
-      end = yaml.indexOf('}', end);
-    } else {
-      end = yaml.indexOf(',', end) + 1;
-    }
-  } else {
-    start = yaml.lastIndexOf(',', start - 1);
-  }
-
-  return SourceEdit(start, end - start, '');
-}
diff --git a/lib/src/yaml_edit/source_edit.dart b/lib/src/yaml_edit/source_edit.dart
deleted file mode 100644
index 1b6512a..0000000
--- a/lib/src/yaml_edit/source_edit.dart
+++ /dev/null
@@ -1,145 +0,0 @@
-// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-// @dart=2.10
-
-import 'package:meta/meta.dart';
-
-/// A class representing a change on a [String], intended to be compatible with
-/// `package:analysis_server`'s [SourceEdit].
-///
-/// For example, changing a string from
-/// ```
-/// foo: foobar
-/// ```
-/// to
-/// ```
-/// foo: barbar
-/// ```
-/// will be represented by `SourceEdit(offset: 4, length: 3, replacement: 'bar')`
-@sealed
-class SourceEdit {
-  /// The offset from the start of the string where the modification begins.
-  final int offset;
-
-  /// The length of the substring to be replaced.
-  final int length;
-
-  /// The replacement string to be used.
-  final String replacement;
-
-  /// Creates a new [SourceEdit] instance. [offset], [length] and [replacement]
-  /// must be non-null, and [offset] and [length] must be non-negative.
-  factory SourceEdit(int offset, int length, String replacement) =>
-      SourceEdit._(offset, length, replacement);
-
-  SourceEdit._(this.offset, this.length, this.replacement) {
-    ArgumentError.checkNotNull(offset, 'offset');
-    ArgumentError.checkNotNull(length, 'length');
-    ArgumentError.checkNotNull(replacement, 'replacement');
-    RangeError.checkNotNegative(offset);
-    RangeError.checkNotNegative(length);
-  }
-
-  @override
-  bool operator ==(Object other) {
-    if (other is SourceEdit) {
-      return offset == other.offset &&
-          length == other.length &&
-          replacement == other.replacement;
-    }
-
-    return false;
-  }
-
-  @override
-  int get hashCode => offset.hashCode ^ length.hashCode ^ replacement.hashCode;
-
-  /// Constructs a SourceEdit from JSON.
-  ///
-  /// **Example:**
-  /// ```dart
-  /// final edit = {
-  ///   'offset': 1,
-  ///   'length': 2,
-  ///   'replacement': 'replacement string'
-  /// };
-  ///
-  /// final sourceEdit = SourceEdit.fromJson(edit);
-  /// ```
-  factory SourceEdit.fromJson(Map<String, dynamic> json) {
-    ArgumentError.checkNotNull(json, 'json');
-
-    if (json is Map) {
-      final offset = json['offset'];
-      final length = json['length'];
-      final replacement = json['replacement'];
-
-      if (offset is int && length is int && replacement is String) {
-        return SourceEdit(offset, length, replacement);
-      }
-    }
-    throw FormatException('Invalid JSON passed to SourceEdit');
-  }
-
-  /// Encodes this object as JSON-compatible structure.
-  ///
-  /// **Example:**
-  /// ```dart
-  /// import 'dart:convert' show jsonEncode;
-  ///
-  /// final edit = SourceEdit(offset, length, 'replacement string');
-  /// final jsonString = jsonEncode(edit.toJson());
-  /// print(jsonString);
-  /// ```
-  Map<String, dynamic> toJson() {
-    return {'offset': offset, 'length': length, 'replacement': replacement};
-  }
-
-  @override
-  String toString() => 'SourceEdit($offset, $length, "$replacement")';
-
-  /// Applies a series of [SourceEdit]s to an original string, and return the
-  /// final output.
-  ///
-  /// [edits] should be in order i.e. the first [SourceEdit] in [edits] should
-  /// be the first edit applied to [original].
-  ///
-  /// **Example:**
-  /// ```dart
-  /// const original = 'YAML: YAML';
-  /// final sourceEdits = [
-  ///        SourceEdit(6, 4, "YAML Ain't Markup Language"),
-  ///        SourceEdit(6, 4, "YAML Ain't Markup Language"),
-  ///        SourceEdit(0, 4, "YAML Ain't Markup Language")
-  ///      ];
-  /// final result = SourceEdit.applyAll(original, sourceEdits);
-  /// ```
-  /// **Expected result:**
-  /// ```dart
-  /// "YAML Ain't Markup Language: YAML Ain't Markup Language Ain't Markup
-  /// Language"
-  /// ```
-  static String applyAll(String original, Iterable<SourceEdit> edits) {
-    ArgumentError.checkNotNull(original, 'original');
-    ArgumentError.checkNotNull(edits, 'edits');
-
-    return edits.fold(original, (current, edit) => edit.apply(current));
-  }
-
-  /// Applies one [SourceEdit]s to an original string, and return the final
-  /// output.
-  ///
-  /// **Example:**
-  /// ```dart
-  /// final edit = SourceEdit(4, 3, 'bar');
-  /// final originalString = 'foo: foobar';
-  /// print(edit.apply(originalString)); // 'foo: barbar'
-  /// ```
-  String apply(String original) {
-    ArgumentError.checkNotNull(original, 'original');
-
-    return original.replaceRange(offset, offset + length, replacement);
-  }
-}
diff --git a/lib/src/yaml_edit/strings.dart b/lib/src/yaml_edit/strings.dart
deleted file mode 100644
index 8a7fee5..0000000
--- a/lib/src/yaml_edit/strings.dart
+++ /dev/null
@@ -1,315 +0,0 @@
-// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-// @dart=2.10
-
-import 'package:yaml/yaml.dart';
-import 'utils.dart';
-
-/// Given [value], tries to format it into a plain string recognizable by YAML.
-/// If it fails, it defaults to returning a double-quoted string.
-///
-/// Not all values can be formatted into a plain string. If the string contains
-/// an escape sequence, it can only be detected when in a double-quoted
-/// sequence. Plain strings may also be misinterpreted by the YAML parser (e.g.
-/// ' null').
-String _tryYamlEncodePlain(Object value) {
-  if (value is YamlNode) {
-    AssertionError(
-        'YamlNodes should not be passed directly into getSafeString!');
-  }
-
-  assertValidScalar(value);
-
-  if (value is String) {
-    /// If it contains a dangerous character we want to wrap the result with
-    /// double quotes because the double quoted style allows for arbitrary
-    /// strings with "\" escape sequences.
-    ///
-    /// See 7.3.1 Double-Quoted Style
-    /// https://yaml.org/spec/1.2/spec.html#id2787109
-    if (isDangerousString(value)) {
-      return _yamlEncodeDoubleQuoted(value);
-    }
-
-    return value;
-  }
-
-  return value.toString();
-}
-
-/// Checks if [string] has unprintable characters according to
-/// [unprintableCharCodes].
-bool _hasUnprintableCharacters(String string) {
-  ArgumentError.checkNotNull(string, 'string');
-
-  final codeUnits = string.codeUnits;
-
-  for (final key in unprintableCharCodes.keys) {
-    if (codeUnits.contains(key)) return true;
-  }
-
-  return false;
-}
-
-/// Generates a YAML-safe double-quoted string based on [string], escaping the
-/// list of characters as defined by the YAML 1.2 spec.
-///
-/// See 5.7 Escaped Characters https://yaml.org/spec/1.2/spec.html#id2776092
-String _yamlEncodeDoubleQuoted(String string) {
-  ArgumentError.checkNotNull(string, 'string');
-
-  final buffer = StringBuffer();
-  for (final codeUnit in string.codeUnits) {
-    if (doubleQuoteEscapeChars[codeUnit] != null) {
-      buffer.write(doubleQuoteEscapeChars[codeUnit]);
-    } else {
-      buffer.writeCharCode(codeUnit);
-    }
-  }
-
-  return '"$buffer"';
-}
-
-/// Generates a YAML-safe single-quoted string. Automatically escapes
-/// single-quotes.
-///
-/// It is important that we ensure that [string] is free of unprintable
-/// characters by calling [assertValidScalar] before invoking this function.
-String _tryYamlEncodeSingleQuoted(String string) {
-  ArgumentError.checkNotNull(string, 'string');
-
-  final result = string.replaceAll('\'', '\'\'');
-  return '\'$result\'';
-}
-
-/// Generates a YAML-safe folded string.
-///
-/// It is important that we ensure that [string] is free of unprintable
-/// characters by calling [assertValidScalar] before invoking this function.
-String _tryYamlEncodeFolded(String string, int indentation, String lineEnding) {
-  ArgumentError.checkNotNull(string, 'string');
-  ArgumentError.checkNotNull(indentation, 'indentation');
-  ArgumentError.checkNotNull(lineEnding, 'lineEnding');
-
-  String result;
-
-  final trimmedString = string.trimRight();
-  final removedPortion = string.substring(trimmedString.length);
-
-  if (removedPortion.contains('\n')) {
-    result = '>+\n' + ' ' * indentation;
-  } else {
-    result = '>-\n' + ' ' * indentation;
-  }
-
-  /// Duplicating the newline for folded strings preserves it in YAML.
-  /// Assumes the user did not try to account for windows documents by using
-  /// `\r\n` already
-  return result +
-      trimmedString.replaceAll('\n', lineEnding * 2 + ' ' * indentation) +
-      removedPortion;
-}
-
-/// Generates a YAML-safe literal string.
-///
-/// It is important that we ensure that [string] is free of unprintable
-/// characters by calling [assertValidScalar] before invoking this function.
-String _tryYamlEncodeLiteral(
-    String string, int indentation, String lineEnding) {
-  ArgumentError.checkNotNull(string, 'string');
-  ArgumentError.checkNotNull(indentation, 'indentation');
-  ArgumentError.checkNotNull(lineEnding, 'lineEnding');
-
-  final result = '|-\n$string';
-
-  /// Assumes the user did not try to account for windows documents by using
-  /// `\r\n` already
-  return result.replaceAll('\n', lineEnding + ' ' * indentation);
-}
-
-/// Returns [value] with the necessary formatting applied in a flow context
-/// if possible.
-///
-/// If [value] is a [YamlScalar], we try to respect its [style] parameter where
-/// possible. Certain cases make this impossible (e.g. a plain string scalar that
-/// starts with '>'), in which case we will produce [value] with default styling
-/// options.
-String _yamlEncodeFlowScalar(YamlNode value) {
-  if (value is YamlScalar) {
-    assertValidScalar(value.value);
-
-    if (value.value is String) {
-      if (_hasUnprintableCharacters(value.value) ||
-          value.style == ScalarStyle.DOUBLE_QUOTED) {
-        return _yamlEncodeDoubleQuoted(value.value);
-      }
-
-      if (value.style == ScalarStyle.SINGLE_QUOTED) {
-        return _tryYamlEncodeSingleQuoted(value.value);
-      }
-    }
-
-    return _tryYamlEncodePlain(value.value);
-  }
-
-  assertValidScalar(value);
-  return _tryYamlEncodePlain(value);
-}
-
-/// Returns [value] with the necessary formatting applied in a block context
-/// if possible.
-///
-/// If [value] is a [YamlScalar], we try to respect its [style] parameter where
-/// possible. Certain cases make this impossible (e.g. a folded string scalar
-/// 'null'), in which case we will produce [value] with default styling
-/// options.
-String yamlEncodeBlockScalar(
-    YamlNode value, int indentation, String lineEnding) {
-  ArgumentError.checkNotNull(indentation, 'indentation');
-  ArgumentError.checkNotNull(lineEnding, 'lineEnding');
-
-  if (value is YamlScalar) {
-    assertValidScalar(value.value);
-
-    if (value.value is String) {
-      if (_hasUnprintableCharacters(value.value)) {
-        return _yamlEncodeDoubleQuoted(value.value);
-      }
-
-      if (value.style == ScalarStyle.SINGLE_QUOTED) {
-        return _tryYamlEncodeSingleQuoted(value.value);
-      }
-
-      // Strings with only white spaces will cause a misparsing
-      if (value.value.trim().length == value.value.length &&
-          value.value.length != 0) {
-        if (value.style == ScalarStyle.FOLDED) {
-          return _tryYamlEncodeFolded(value.value, indentation, lineEnding);
-        }
-
-        if (value.style == ScalarStyle.LITERAL) {
-          return _tryYamlEncodeLiteral(value.value, indentation, lineEnding);
-        }
-      }
-    }
-
-    return _tryYamlEncodePlain(value.value);
-  }
-
-  assertValidScalar(value);
-
-  /// The remainder of the possibilities are similar to how [getFlowScalar]
-  /// treats [value].
-  return _yamlEncodeFlowScalar(value);
-}
-
-/// Returns [value] with the necessary formatting applied in a flow context.
-///
-/// If [value] is a [YamlNode], we try to respect its [style] parameter where
-/// possible. Certain cases make this impossible (e.g. a plain string scalar
-/// that starts with '>', a child having a block style parameters), in which
-/// case we will produce [value] with default styling options.
-String yamlEncodeFlowString(YamlNode value) {
-  if (value is YamlList) {
-    final list = value.nodes;
-
-    final safeValues = list.map(yamlEncodeFlowString);
-    return '[' + safeValues.join(', ') + ']';
-  } else if (value is YamlMap) {
-    final safeEntries = value.nodes.entries.map((entry) {
-      final safeKey = yamlEncodeFlowString(entry.key);
-      final safeValue = yamlEncodeFlowString(entry.value);
-      return '$safeKey: $safeValue';
-    });
-
-    return '{' + safeEntries.join(', ') + '}';
-  }
-
-  return _yamlEncodeFlowScalar(value);
-}
-
-/// Returns [value] with the necessary formatting applied in a block context.
-///
-/// If [value] is a [YamlNode], we respect its [style] parameter.
-String yamlEncodeBlockString(
-    YamlNode value, int indentation, String lineEnding) {
-  ArgumentError.checkNotNull(indentation, 'indentation');
-  ArgumentError.checkNotNull(lineEnding, 'lineEnding');
-
-  const additionalIndentation = 2;
-
-  if (!isBlockNode(value)) return yamlEncodeFlowString(value);
-
-  final newIndentation = indentation + additionalIndentation;
-
-  if (value is YamlList) {
-    if (value.isEmpty) return ' ' * indentation + '[]';
-
-    Iterable<String> safeValues;
-
-    final children = value.nodes;
-
-    safeValues = children.map((child) {
-      var valueString =
-          yamlEncodeBlockString(child, newIndentation, lineEnding);
-      if (isCollection(child) && !isFlowYamlCollectionNode(child)) {
-        valueString = valueString.substring(newIndentation);
-      }
-
-      return ' ' * indentation + '- $valueString';
-    });
-
-    return safeValues.join(lineEnding);
-  } else if (value is YamlMap) {
-    if (value.isEmpty) return ' ' * indentation + '{}';
-
-    return value.nodes.entries.map((entry) {
-      final safeKey = yamlEncodeFlowString(entry.key);
-      final formattedKey = ' ' * indentation + safeKey;
-      final formattedValue =
-          yamlEncodeBlockString(entry.value, newIndentation, lineEnding);
-
-      /// Empty collections are always encoded in flow-style, so new-line must
-      /// be avoided.
-      if (isCollection(entry.value) && !isEmpty(entry.value)) {
-        return formattedKey + ':\n' + formattedValue;
-      }
-
-      return formattedKey + ': ' + formattedValue;
-    }).join(lineEnding);
-  }
-
-  return yamlEncodeBlockScalar(value, newIndentation, lineEnding);
-}
-
-/// List of unprintable characters.
-///
-/// See 5.7 Escape Characters https://yaml.org/spec/1.2/spec.html#id2776092
-final Map<int, String> unprintableCharCodes = {
-  0: '\\0', //  Escaped ASCII null (#x0) character.
-  7: '\\a', //  Escaped ASCII bell (#x7) character.
-  8: '\\b', //  Escaped ASCII backspace (#x8) character.
-  11: '\\v', // 	Escaped ASCII vertical tab (#xB) character.
-  12: '\\f', //  Escaped ASCII form feed (#xC) character.
-  13: '\\r', //  Escaped ASCII carriage return (#xD) character. Line Break.
-  27: '\\e', //  Escaped ASCII escape (#x1B) character.
-  133: '\\N', //  Escaped Unicode next line (#x85) character.
-  160: '\\_', //  Escaped Unicode non-breaking space (#xA0) character.
-  8232: '\\L', //  Escaped Unicode line separator (#x2028) character.
-  8233: '\\P', //  Escaped Unicode paragraph separator (#x2029) character.
-};
-
-/// List of escape characters. In particular, \x32 is not included because it
-/// can be processed normally.
-///
-/// See 5.7 Escape Characters https://yaml.org/spec/1.2/spec.html#id2776092
-final Map<int, String> doubleQuoteEscapeChars = {
-  ...unprintableCharCodes,
-  9: '\\t', //  Escaped ASCII horizontal tab (#x9) character. Printable
-  10: '\\n', //  Escaped ASCII line feed (#xA) character. Line Break.
-  34: '\\"', //  Escaped ASCII double quote (#x22).
-  47: '\\/', //  Escaped ASCII slash (#x2F), for JSON compatibility.
-  92: '\\\\', //  Escaped ASCII back slash (#x5C).
-};
diff --git a/lib/src/yaml_edit/utils.dart b/lib/src/yaml_edit/utils.dart
deleted file mode 100644
index 91ff530..0000000
--- a/lib/src/yaml_edit/utils.dart
+++ /dev/null
@@ -1,271 +0,0 @@
-// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-// @dart=2.10
-
-import 'package:source_span/source_span.dart';
-import 'package:yaml/yaml.dart';
-
-import 'editor.dart';
-
-/// Determines if [string] is dangerous by checking if parsing the plain string can
-/// return a result different from [string].
-///
-/// This function is also capable of detecting if non-printable characters are in
-/// [string].
-bool isDangerousString(String string) {
-  ArgumentError.checkNotNull(string, 'string');
-
-  try {
-    if (loadYamlNode(string).value != string) {
-      return true;
-    }
-
-    /// [string] should also not contain the `[`, `]`, `,`, `{` and `}` indicator characters.
-    return string.contains(RegExp(r'\{|\[|\]|\}|,'));
-  } catch (e) {
-    /// This catch statement catches [ArgumentError] in `loadYamlNode` when
-    /// a string can be interpreted as a URI tag, but catches for other
-    /// [YamlException]s
-    return true;
-  }
-}
-
-/// Asserts that [value] is a valid scalar according to YAML.
-///
-/// A valid scalar is a number, String, boolean, or null.
-void assertValidScalar(Object value) {
-  if (value is num || value is String || value is bool || value == null) {
-    return;
-  }
-
-  throw ArgumentError.value(value, 'value', 'Not a valid scalar type!');
-}
-
-/// Checks if [node] is a [YamlNode] with block styling.
-///
-/// [ScalarStyle.ANY] and [CollectionStyle.ANY] are considered to be block styling
-/// by default for maximum flexibility.
-bool isBlockNode(YamlNode node) {
-  ArgumentError.checkNotNull(node, 'node');
-
-  if (node is YamlScalar) {
-    if (node.style == ScalarStyle.LITERAL ||
-        node.style == ScalarStyle.FOLDED ||
-        node.style == ScalarStyle.ANY) {
-      return true;
-    }
-  }
-
-  if (node is YamlList &&
-      (node.style == CollectionStyle.BLOCK ||
-          node.style == CollectionStyle.ANY)) return true;
-  if (node is YamlMap &&
-      (node.style == CollectionStyle.BLOCK ||
-          node.style == CollectionStyle.ANY)) return true;
-
-  return false;
-}
-
-/// Returns the content sensitive ending offset of [yamlNode] (i.e. where the last
-/// meaningful content happens)
-int getContentSensitiveEnd(YamlNode yamlNode) {
-  ArgumentError.checkNotNull(yamlNode, 'yamlNode');
-
-  if (yamlNode is YamlList) {
-    if (yamlNode.style == CollectionStyle.FLOW) {
-      return yamlNode.span.end.offset;
-    } else {
-      return getContentSensitiveEnd(yamlNode.nodes.last);
-    }
-  } else if (yamlNode is YamlMap) {
-    if (yamlNode.style == CollectionStyle.FLOW) {
-      return yamlNode.span.end.offset;
-    } else {
-      return getContentSensitiveEnd(yamlNode.nodes.values.last);
-    }
-  }
-
-  return yamlNode.span.end.offset;
-}
-
-/// Checks if the item is a Map or a List
-bool isCollection(Object item) => item is Map || item is List;
-
-/// Checks if [index] is [int], >=0, < [length]
-bool isValidIndex(Object index, int length) {
-  return index is int && index >= 0 && index < length;
-}
-
-/// Checks if the item is empty, if it is a List or a Map.
-///
-/// Returns `false` if [item] is not a List or Map.
-bool isEmpty(Object item) {
-  if (item is Map) return item.isEmpty;
-  if (item is List) return item.isEmpty;
-
-  return false;
-}
-
-/// Creates a [SourceSpan] from [sourceUrl] with no meaningful location
-/// information.
-///
-/// Mainly used with [wrapAsYamlNode] to allow for a reasonable
-/// implementation of [SourceSpan.message].
-SourceSpan shellSpan(Object sourceUrl) {
-  final shellSourceLocation = SourceLocation(0, sourceUrl: sourceUrl);
-  return SourceSpanBase(shellSourceLocation, shellSourceLocation, '');
-}
-
-/// Returns if [value] is a [YamlList] or [YamlMap] with [CollectionStyle.FLOW].
-bool isFlowYamlCollectionNode(Object value) {
-  if (value is YamlList || value is YamlMap) {
-    return (value as dynamic).style == CollectionStyle.FLOW;
-  }
-
-  return false;
-}
-
-/// Determines the index where [newKey] will be inserted if the keys in [map] are in
-/// alphabetical order when converted to strings.
-///
-/// Returns the length of [map] if the keys in [map] are not in alphabetical order.
-int getMapInsertionIndex(YamlMap map, Object newKey) {
-  ArgumentError.checkNotNull(map, 'map');
-
-  final keys = map.nodes.keys.map((k) => k.toString()).toList();
-
-  for (var i = 1; i < keys.length; i++) {
-    if (keys[i].compareTo(keys[i - 1]) < 0) {
-      return map.length;
-    }
-  }
-
-  final insertionIndex = keys.indexWhere((key) => key.compareTo(newKey) > 0);
-
-  if (insertionIndex != -1) return insertionIndex;
-
-  return map.length;
-}
-
-/// Returns the [style] property of [target], if it is a [YamlNode]. Otherwise return null.
-Object getStyle(Object target) {
-  if (target is YamlNode) {
-    return (target as dynamic).style;
-  }
-
-  return null;
-}
-
-/// Returns the detected indentation step used in [yaml], or
-/// defaults to a value of `2` if no indentation step can be detected.
-///
-/// Indentation step is determined by the difference in indentation of the
-/// first block-styled yaml collection in the second level as compared to the
-/// top-level elements. In the case where there are multiple possible
-/// candidates, we choose the candidate closest to the start of [yaml].
-int getIndentation(YamlEditor editor) {
-  final node = editor.parseAt([]);
-  Iterable<YamlNode> children;
-  var indentation = 2;
-
-  if (node is YamlMap && node.style == CollectionStyle.BLOCK) {
-    children = node.nodes.values;
-  } else if (node is YamlList && node.style == CollectionStyle.BLOCK) {
-    children = node.nodes;
-  }
-
-  if (children != null) {
-    for (final child in children) {
-      var indent = 0;
-      if (child is YamlList) {
-        indent = getListIndentation(editor.toString(), child);
-      } else if (child is YamlMap) {
-        indent = getMapIndentation(editor.toString(), child);
-      }
-
-      if (indent != 0) indentation = indent;
-    }
-  }
-  return indentation;
-}
-
-/// Gets the indentation level of [list]. This is 0 if it is a flow list,
-/// but returns the number of spaces before the hyphen of elements for
-/// block lists.
-///
-/// Throws [UnsupportedError] if an empty block map is passed in.
-int getListIndentation(String yaml, YamlList list) {
-  ArgumentError.checkNotNull(list, 'list');
-
-  if (list.style == CollectionStyle.FLOW) return 0;
-
-  /// An empty block map doesn't really exist.
-  if (list.isEmpty) {
-    throw UnsupportedError('Unable to get indentation for empty block list');
-  }
-
-  final lastSpanOffset = list.nodes.last.span.start.offset;
-  final lastNewLine = yaml.lastIndexOf('\n', lastSpanOffset - 1);
-  final lastHyphen = yaml.lastIndexOf('-', lastSpanOffset - 1);
-
-  if (lastNewLine == -1) return lastHyphen;
-
-  return lastHyphen - lastNewLine - 1;
-}
-
-/// Gets the indentation level of [map]. This is 0 if it is a flow map,
-/// but returns the number of spaces before the keys for block maps.
-int getMapIndentation(String yaml, YamlMap map) {
-  ArgumentError.checkNotNull(map, 'map');
-
-  if (map.style == CollectionStyle.FLOW) return 0;
-
-  /// An empty block map doesn't really exist.
-  if (map.isEmpty) {
-    throw UnsupportedError('Unable to get indentation for empty block map');
-  }
-
-  /// Use the number of spaces between the last key and the newline as
-  /// indentation.
-  final lastKey = map.nodes.keys.last as YamlNode;
-  final lastSpanOffset = lastKey.span.start.offset;
-  final lastNewLine = yaml.lastIndexOf('\n', lastSpanOffset);
-  final lastQuestionMark = yaml.lastIndexOf('?', lastSpanOffset);
-
-  if (lastQuestionMark == -1) {
-    if (lastNewLine == -1) return lastSpanOffset;
-    return lastSpanOffset - lastNewLine - 1;
-  }
-
-  /// If there is a question mark, it might be a complex key. Check if it
-  /// is on the same line as the key node to verify.
-  if (lastNewLine == -1) return lastQuestionMark;
-  if (lastQuestionMark > lastNewLine) {
-    return lastQuestionMark - lastNewLine - 1;
-  }
-
-  return lastSpanOffset - lastNewLine - 1;
-}
-
-/// Returns the detected line ending used in [yaml], more specifically, whether
-/// [yaml] appears to use Windows `\r\n` or Unix `\n` line endings.
-///
-/// The heuristic used is to count all `\n` in the text and if stricly more
-/// than half of them are preceded by `\r` we report that windows line endings
-/// are used.
-String getLineEnding(String yaml) {
-  var index = -1;
-  var unixNewlines = 0;
-  var windowsNewlines = 0;
-  while ((index = yaml.indexOf('\n', index + 1)) != -1) {
-    if (index != 0 && yaml[index - 1] == '\r') {
-      windowsNewlines++;
-    } else {
-      unixNewlines++;
-    }
-  }
-
-  return windowsNewlines > unixNewlines ? '\r\n' : '\n';
-}
diff --git a/lib/src/yaml_edit/wrap.dart b/lib/src/yaml_edit/wrap.dart
deleted file mode 100644
index a4e8975..0000000
--- a/lib/src/yaml_edit/wrap.dart
+++ /dev/null
@@ -1,187 +0,0 @@
-// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-// @dart=2.10
-
-import 'dart:collection' as collection;
-import 'package:collection/collection.dart';
-import 'package:source_span/source_span.dart';
-import 'package:yaml/yaml.dart';
-
-import 'equality.dart';
-import 'utils.dart';
-
-/// Returns a new [YamlMap] constructed by applying [update] onto the [nodes]
-/// of this [YamlMap].
-YamlMap updatedYamlMap(YamlMap map, Function(Map) update) {
-  ArgumentError.checkNotNull(map, 'map');
-
-  final dummyMap = deepEqualsMap();
-  dummyMap.addAll(map.nodes);
-
-  update(dummyMap);
-
-  return wrapAsYamlNode(dummyMap);
-}
-
-/// Wraps [value] into a [YamlNode].
-///
-/// [Map]s, [List]s and Scalars will be wrapped as [YamlMap]s, [YamlList]s,
-/// and [YamlScalar]s respectively. If [collectionStyle]/[scalarStyle] is
-/// defined, and [value] is a collection or scalar, the wrapped [YamlNode] will
-/// have the respective style, otherwise it defaults to the ANY style.
-///
-/// If a [YamlNode] is passed in, no further wrapping will be done, and the
-/// [collectionStyle]/[scalarStyle] will not be applied.
-YamlNode wrapAsYamlNode(Object value,
-    {CollectionStyle collectionStyle = CollectionStyle.ANY,
-    ScalarStyle scalarStyle = ScalarStyle.ANY}) {
-  if (value is YamlScalar) {
-    assertValidScalar(value.value);
-    return value;
-  } else if (value is YamlList) {
-    for (final item in value.nodes) {
-      wrapAsYamlNode(item);
-    }
-
-    return value;
-  } else if (value is YamlMap) {
-    /// Both [entry.key] and [entry.values] are guaranteed to be [YamlNode]s,
-    /// so running this will just assert that they are valid scalars.
-    for (final entry in value.nodes.entries) {
-      wrapAsYamlNode(entry.key);
-      wrapAsYamlNode(entry.value);
-    }
-
-    return value;
-  } else if (value is Map) {
-    ArgumentError.checkNotNull(collectionStyle, 'collectionStyle');
-    return YamlMapWrap(value, collectionStyle: collectionStyle);
-  } else if (value is List) {
-    ArgumentError.checkNotNull(collectionStyle, 'collectionStyle');
-    return YamlListWrap(value, collectionStyle: collectionStyle);
-  } else {
-    assertValidScalar(value);
-
-    ArgumentError.checkNotNull(scalarStyle, 'scalarStyle');
-    return YamlScalarWrap(value, style: scalarStyle);
-  }
-}
-
-/// Internal class that allows us to define a constructor on [YamlScalar]
-/// which takes in [style] as an argument.
-class YamlScalarWrap implements YamlScalar {
-  /// The [ScalarStyle] to be used for the scalar.
-  @override
-  final ScalarStyle style;
-
-  @override
-  final SourceSpan span;
-
-  @override
-  final dynamic value;
-
-  YamlScalarWrap(this.value, {this.style = ScalarStyle.ANY, Object sourceUrl})
-      : span = shellSpan(sourceUrl) {
-    ArgumentError.checkNotNull(style, 'scalarStyle');
-  }
-
-  @override
-  String toString() => value.toString();
-}
-
-/// Internal class that allows us to define a constructor on [YamlMap]
-/// which takes in [style] as an argument.
-class YamlMapWrap
-    with collection.MapMixin, UnmodifiableMapMixin
-    implements YamlMap {
-  /// The [CollectionStyle] to be used for the map.
-  @override
-  final CollectionStyle style;
-
-  @override
-  final Map<dynamic, YamlNode> nodes;
-
-  @override
-  final SourceSpan span;
-
-  factory YamlMapWrap(Map dartMap,
-      {CollectionStyle collectionStyle = CollectionStyle.ANY,
-      Object sourceUrl}) {
-    ArgumentError.checkNotNull(collectionStyle, 'collectionStyle');
-
-    final wrappedMap = deepEqualsMap<dynamic, YamlNode>();
-
-    for (final entry in dartMap.entries) {
-      final wrappedKey = wrapAsYamlNode(entry.key);
-      final wrappedValue = wrapAsYamlNode(entry.value);
-      wrappedMap[wrappedKey] = wrappedValue;
-    }
-
-    return YamlMapWrap._(wrappedMap,
-        style: collectionStyle, sourceUrl: sourceUrl);
-  }
-
-  YamlMapWrap._(this.nodes,
-      {CollectionStyle style = CollectionStyle.ANY, Object sourceUrl})
-      : span = shellSpan(sourceUrl),
-        style = nodes.isEmpty ? CollectionStyle.FLOW : style;
-
-  @override
-  dynamic operator [](Object key) => nodes[key]?.value;
-
-  @override
-  Iterable get keys => nodes.keys.map((node) => node.value);
-
-  @override
-  Map get value => this;
-}
-
-/// Internal class that allows us to define a constructor on [YamlList]
-/// which takes in [style] as an argument.
-class YamlListWrap with collection.ListMixin implements YamlList {
-  /// The [CollectionStyle] to be used for the list.
-  @override
-  final CollectionStyle style;
-
-  @override
-  final List<YamlNode> nodes;
-
-  @override
-  final SourceSpan span;
-
-  @override
-  int get length => nodes.length;
-
-  @override
-  set length(int index) {
-    throw UnsupportedError('Cannot modify an unmodifiable List');
-  }
-
-  factory YamlListWrap(List dartList,
-      {CollectionStyle collectionStyle = CollectionStyle.ANY,
-      Object sourceUrl}) {
-    ArgumentError.checkNotNull(collectionStyle, 'collectionStyle');
-
-    final wrappedList = dartList.map(wrapAsYamlNode).toList();
-    return YamlListWrap._(wrappedList,
-        style: collectionStyle, sourceUrl: sourceUrl);
-  }
-
-  YamlListWrap._(this.nodes,
-      {CollectionStyle style = CollectionStyle.ANY, Object sourceUrl})
-      : span = shellSpan(sourceUrl),
-        style = nodes.isEmpty ? CollectionStyle.FLOW : style;
-
-  @override
-  dynamic operator [](int index) => nodes[index].value;
-
-  @override
-  operator []=(int index, value) {
-    throw UnsupportedError('Cannot modify an unmodifiable List');
-  }
-
-  @override
-  List get value => this;
-}
diff --git a/pubspec.yaml b/pubspec.yaml
index 5902f9d..23fc0c8 100644
--- a/pubspec.yaml
+++ b/pubspec.yaml
@@ -25,6 +25,7 @@
   source_span: ^1.8.1
   stack_trace: ^1.10.0
   yaml: ^3.1.0
+  yaml_edit: ^2.0.0
 
 dev_dependencies:
   shelf_test_handler: ^2.0.0