diff --git a/lib/src/command/add.dart b/lib/src/command/add.dart
index 4839545..aabd67f 100644
--- a/lib/src/command/add.dart
+++ b/lib/src/command/add.dart
@@ -3,7 +3,6 @@
 // BSD-style license that can be found in the LICENSE file.
 
 import 'package:pub_semver/pub_semver.dart';
-import 'package:yaml_edit/yaml_edit.dart';
 
 import '../command.dart';
 import '../entrypoint.dart';
@@ -16,6 +15,7 @@
 import '../pubspec.dart';
 import '../solver.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 dc3bd26..94091c7 100644
--- a/lib/src/command/remove.dart
+++ b/lib/src/command/remove.dart
@@ -2,8 +2,6 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-import 'package:yaml_edit/yaml_edit.dart';
-
 import '../command.dart';
 import '../entrypoint.dart';
 import '../io.dart';
@@ -11,6 +9,7 @@
 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/yaml_edit/editor.dart b/lib/src/yaml_edit/editor.dart
new file mode 100644
index 0000000..fa397ce
--- /dev/null
+++ b/lib/src/yaml_edit/editor.dart
@@ -0,0 +1,632 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:meta/meta.dart';
+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
+/// [Argu,emtError] 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);
+    _yaml = edit.apply(_yaml);
+    _initialize();
+
+    final actualTree = loadYamlNode(_yaml);
+    if (!deepEquals(actualTree, expectedTree)) {
+      throw AssertionError('''
+Modification did not result in expected result! 
+
+Obtained: 
+$actualTree
+
+Expected: 
+$expectedTree''');
+    }
+
+    _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
new file mode 100644
index 0000000..21ad6a0
--- /dev/null
+++ b/lib/src/yaml_edit/equality.dart
@@ -0,0 +1,116 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import '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
new file mode 100644
index 0000000..5d1c9a0
--- /dev/null
+++ b/lib/src/yaml_edit/errors.dart
@@ -0,0 +1,68 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:meta/meta.dart';
+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.')}');
+}
diff --git a/lib/src/yaml_edit/list_mutations.dart b/lib/src/yaml_edit/list_mutations.dart
new file mode 100644
index 0000000..9eaa949
--- /dev/null
+++ b/lib/src/yaml_edit/list_mutations.dart
@@ -0,0 +1,335 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package: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
new file mode 100644
index 0000000..3dd8682
--- /dev/null
+++ b/lib/src/yaml_edit/map_mutations.dart
@@ -0,0 +1,262 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package: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 + 1;
+
+  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
new file mode 100644
index 0000000..d52373b
--- /dev/null
+++ b/lib/src/yaml_edit/source_edit.dart
@@ -0,0 +1,143 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:meta/meta.dart';
+
+/// 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
new file mode 100644
index 0000000..faebe8a
--- /dev/null
+++ b/lib/src/yaml_edit/strings.dart
@@ -0,0 +1,311 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package: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);
+
+      if (isCollection(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
new file mode 100644
index 0000000..b4e64e6
--- /dev/null
+++ b/lib/src/yaml_edit/utils.dart
@@ -0,0 +1,269 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package: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
new file mode 100644
index 0000000..5585ea6
--- /dev/null
+++ b/lib/src/yaml_edit/wrap.dart
@@ -0,0 +1,185 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart: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 076e303..30b464d 100644
--- a/pubspec.yaml
+++ b/pubspec.yaml
@@ -28,7 +28,6 @@
   source_span: ^1.4.0
   stack_trace: ^1.0.0
   yaml: ^2.2.0
-  yaml_edit: ^1.0.1
 
 dev_dependencies:
   shelf_test_handler: ^1.0.0
