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
