Fix newly enforced package:pedantic lints (#58)

- always_declare_return_types
- annotate_overrides
- omit_local_variable_types
- prefer_collection_literals
- prefer_if_null_operators
- prefer_single_quotes
- prefer_spread_collections

Bump min SDK to 2.3.0 to allow spreads in collection literals.
diff --git a/.travis.yml b/.travis.yml
index 63ec5c2..78ba590 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -1,7 +1,7 @@
 language: dart
 
 dart:
-  - 2.0.0
+  - 2.3.0
   - dev
 
 dart_task:
diff --git a/benchmark/benchmark.dart b/benchmark/benchmark.dart
index 5e080eb..f5dc9e7 100644
--- a/benchmark/benchmark.dart
+++ b/benchmark/benchmark.dart
@@ -14,8 +14,8 @@
 const numTrials = 100;
 const runsPerTrial = 1000;
 
-final source = loadFile("input.yaml");
-final expected = loadFile("output.json");
+final source = loadFile('input.yaml');
+final expected = loadFile('output.json');
 
 void main(List<String> args) {
   var best = double.infinity;
@@ -41,7 +41,7 @@
     // Sanity check to make sure the output is what we expect and to make sure
     // the VM doesn't optimize "dead" code away.
     if (jsonEncode(result) != expected) {
-      print("Incorrect output:\n${jsonEncode(result)}");
+      print('Incorrect output:\n${jsonEncode(result)}');
       exit(1);
     }
 
@@ -51,7 +51,7 @@
     printResult("Run ${padLeft('#$i', 3)}", elapsed);
   }
 
-  printResult("Best   ", best);
+  printResult('Best   ', best);
 }
 
 String loadFile(String name) {
@@ -60,14 +60,14 @@
 }
 
 void printResult(String label, double time) {
-  print("$label: ${padLeft(time.toStringAsFixed(3), 4)}ms "
+  print('$label: ${padLeft(time.toStringAsFixed(3), 4)}ms '
       "${'=' * ((time * 100).toInt())}");
 }
 
 String padLeft(input, int length) {
   var result = input.toString();
   if (result.length < length) {
-    result = " " * (length - result.length) + result;
+    result = ' ' * (length - result.length) + result;
   }
 
   return result;
diff --git a/lib/src/equality.dart b/lib/src/equality.dart
index 299dfe8..b232eb9 100644
--- a/lib/src/equality.dart
+++ b/lib/src/equality.dart
@@ -100,7 +100,7 @@
 int deepHashCode(obj) {
   var parents = [];
 
-  _deepHashCode(value) {
+  int _deepHashCode(value) {
     if (parents.any((parent) => identical(parent, value))) return -1;
 
     parents.add(value);
diff --git a/lib/src/event.dart b/lib/src/event.dart
index 3be5a0a..733e39d 100644
--- a/lib/src/event.dart
+++ b/lib/src/event.dart
@@ -17,12 +17,15 @@
 
   Event(this.type, this.span);
 
+  @override
   String toString() => type.toString();
 }
 
 /// An event indicating the beginning of a YAML document.
 class DocumentStartEvent implements Event {
-  get type => EventType.DOCUMENT_START;
+  @override
+  EventType get type => EventType.DOCUMENT_START;
+  @override
   final FileSpan span;
 
   /// The document's `%YAML` directive, or `null` if there was none.
@@ -39,14 +42,17 @@
       {this.versionDirective,
       List<TagDirective> tagDirectives,
       this.isImplicit = true})
-      : tagDirectives = tagDirectives == null ? [] : tagDirectives;
+      : tagDirectives = tagDirectives ?? [];
 
-  String toString() => "DOCUMENT_START";
+  @override
+  String toString() => 'DOCUMENT_START';
 }
 
 /// An event indicating the end of a YAML document.
 class DocumentEndEvent implements Event {
-  get type => EventType.DOCUMENT_END;
+  @override
+  EventType get type => EventType.DOCUMENT_END;
+  @override
   final FileSpan span;
 
   /// Whether the document ended implicitly (that is, without an explicit
@@ -55,12 +61,15 @@
 
   DocumentEndEvent(this.span, {this.isImplicit = true});
 
-  String toString() => "DOCUMENT_END";
+  @override
+  String toString() => 'DOCUMENT_END';
 }
 
 /// An event indicating that an alias was referenced.
 class AliasEvent implements Event {
-  get type => EventType.ALIAS;
+  @override
+  EventType get type => EventType.ALIAS;
+  @override
   final FileSpan span;
 
   /// The name of the anchor.
@@ -68,7 +77,8 @@
 
   AliasEvent(this.span, this.name);
 
-  String toString() => "ALIAS $name";
+  @override
+  String toString() => 'ALIAS $name';
 }
 
 /// A base class for events that can have anchor and tag properties associated
@@ -80,19 +90,24 @@
   /// The text of the value's tag, or `null` if it wasn't tagged.
   String get tag;
 
+  @override
   String toString() {
     var buffer = StringBuffer('$type');
-    if (anchor != null) buffer.write(" &$anchor");
-    if (tag != null) buffer.write(" $tag");
+    if (anchor != null) buffer.write(' &$anchor');
+    if (tag != null) buffer.write(' $tag');
     return buffer.toString();
   }
 }
 
 /// An event indicating a single scalar value.
 class ScalarEvent extends _ValueEvent {
-  get type => EventType.SCALAR;
+  @override
+  EventType get type => EventType.SCALAR;
+  @override
   final FileSpan span;
+  @override
   final String anchor;
+  @override
   final String tag;
 
   /// The contents of the scalar.
@@ -103,14 +118,19 @@
 
   ScalarEvent(this.span, this.value, this.style, {this.anchor, this.tag});
 
-  String toString() => "${super.toString()} \"$value\"";
+  @override
+  String toString() => '${super.toString()} "$value"';
 }
 
 /// An event indicating the beginning of a sequence.
 class SequenceStartEvent extends _ValueEvent {
-  get type => EventType.SEQUENCE_START;
+  @override
+  EventType get type => EventType.SEQUENCE_START;
+  @override
   final FileSpan span;
+  @override
   final String anchor;
+  @override
   final String tag;
 
   /// The style of the collection in the original source.
@@ -121,9 +141,13 @@
 
 /// An event indicating the beginning of a mapping.
 class MappingStartEvent extends _ValueEvent {
-  get type => EventType.MAPPING_START;
+  @override
+  EventType get type => EventType.MAPPING_START;
+  @override
   final FileSpan span;
+  @override
   final String anchor;
+  @override
   final String tag;
 
   /// The style of the collection in the original source.
@@ -134,24 +158,25 @@
 
 /// An enum of types of [Event] object.
 class EventType {
-  static const STREAM_START = EventType._("STREAM_START");
-  static const STREAM_END = EventType._("STREAM_END");
+  static const STREAM_START = EventType._('STREAM_START');
+  static const STREAM_END = EventType._('STREAM_END');
 
-  static const DOCUMENT_START = EventType._("DOCUMENT_START");
-  static const DOCUMENT_END = EventType._("DOCUMENT_END");
+  static const DOCUMENT_START = EventType._('DOCUMENT_START');
+  static const DOCUMENT_END = EventType._('DOCUMENT_END');
 
-  static const ALIAS = EventType._("ALIAS");
-  static const SCALAR = EventType._("SCALAR");
+  static const ALIAS = EventType._('ALIAS');
+  static const SCALAR = EventType._('SCALAR');
 
-  static const SEQUENCE_START = EventType._("SEQUENCE_START");
-  static const SEQUENCE_END = EventType._("SEQUENCE_END");
+  static const SEQUENCE_START = EventType._('SEQUENCE_START');
+  static const SEQUENCE_END = EventType._('SEQUENCE_END');
 
-  static const MAPPING_START = EventType._("MAPPING_START");
-  static const MAPPING_END = EventType._("MAPPING_END");
+  static const MAPPING_START = EventType._('MAPPING_START');
+  static const MAPPING_END = EventType._('MAPPING_END');
 
   final String name;
 
   const EventType._(this.name);
 
+  @override
   String toString() => name;
 }
diff --git a/lib/src/loader.dart b/lib/src/loader.dart
index 70aec36..08b2544 100644
--- a/lib/src/loader.dart
+++ b/lib/src/loader.dart
@@ -23,7 +23,7 @@
   final Parser _parser;
 
   /// Aliases by the alias name.
-  final _aliases = Map<String, YamlNode>();
+  final _aliases = <String, YamlNode>{};
 
   /// The span of the entire stream emitted so far.
   FileSpan get span => _span;
@@ -85,7 +85,7 @@
       case EventType.MAPPING_START:
         return _loadMapping(firstEvent as MappingStartEvent);
       default:
-        throw "Unreachable";
+        throw 'Unreachable';
     }
   }
 
@@ -105,13 +105,13 @@
     var alias = _aliases[event.name];
     if (alias != null) return alias;
 
-    throw YamlException("Undefined alias.", event.span);
+    throw YamlException('Undefined alias.', event.span);
   }
 
   /// Composes a scalar node.
   YamlNode _loadScalar(ScalarEvent scalar) {
     YamlNode node;
-    if (scalar.tag == "!") {
+    if (scalar.tag == '!') {
       node = YamlScalar.internal(scalar.value, scalar);
     } else if (scalar.tag != null) {
       node = _parseByTag(scalar);
@@ -125,10 +125,10 @@
 
   /// Composes a sequence node.
   YamlNode _loadSequence(SequenceStartEvent firstEvent) {
-    if (firstEvent.tag != "!" &&
+    if (firstEvent.tag != '!' &&
         firstEvent.tag != null &&
-        firstEvent.tag != "tag:yaml.org,2002:seq") {
-      throw YamlException("Invalid tag for sequence.", firstEvent.span);
+        firstEvent.tag != 'tag:yaml.org,2002:seq') {
+      throw YamlException('Invalid tag for sequence.', firstEvent.span);
     }
 
     var children = <YamlNode>[];
@@ -147,10 +147,10 @@
 
   /// Composes a mapping node.
   YamlNode _loadMapping(MappingStartEvent firstEvent) {
-    if (firstEvent.tag != "!" &&
+    if (firstEvent.tag != '!' &&
         firstEvent.tag != null &&
-        firstEvent.tag != "tag:yaml.org,2002:map") {
-      throw YamlException("Invalid tag for mapping.", firstEvent.span);
+        firstEvent.tag != 'tag:yaml.org,2002:map') {
+      throw YamlException('Invalid tag for mapping.', firstEvent.span);
     }
 
     var children = deepEqualsMap<dynamic, YamlNode>();
@@ -162,7 +162,7 @@
       var key = _loadNode(event);
       var value = _loadNode(_parser.parse());
       if (children.containsKey(key)) {
-        throw YamlException("Duplicate mapping key.", key.span);
+        throw YamlException('Duplicate mapping key.', key.span);
       }
 
       children[key] = value;
@@ -176,23 +176,23 @@
   /// Parses a scalar according to its tag name.
   YamlScalar _parseByTag(ScalarEvent scalar) {
     switch (scalar.tag) {
-      case "tag:yaml.org,2002:null":
+      case 'tag:yaml.org,2002:null':
         var result = _parseNull(scalar);
         if (result != null) return result;
-        throw YamlException("Invalid null scalar.", scalar.span);
-      case "tag:yaml.org,2002:bool":
+        throw YamlException('Invalid null scalar.', scalar.span);
+      case 'tag:yaml.org,2002:bool':
         var result = _parseBool(scalar);
         if (result != null) return result;
-        throw YamlException("Invalid bool scalar.", scalar.span);
-      case "tag:yaml.org,2002:int":
+        throw YamlException('Invalid bool scalar.', scalar.span);
+      case 'tag:yaml.org,2002:int':
         var result = _parseNumber(scalar, allowFloat: false);
         if (result != null) return result;
-        throw YamlException("Invalid int scalar.", scalar.span);
-      case "tag:yaml.org,2002:float":
+        throw YamlException('Invalid int scalar.', scalar.span);
+      case 'tag:yaml.org,2002:float':
         var result = _parseNumber(scalar, allowInt: false);
         if (result != null) return result;
-        throw YamlException("Invalid float scalar.", scalar.span);
-      case "tag:yaml.org,2002:str":
+        throw YamlException('Invalid float scalar.', scalar.span);
+      case 'tag:yaml.org,2002:str':
         return YamlScalar.internal(scalar.value, scalar);
       default:
         throw YamlException('Undefined tag: ${scalar.tag}.', scalar.span);
@@ -241,11 +241,11 @@
   /// Returns a Dart `null` if parsing fails.
   YamlScalar _parseNull(ScalarEvent scalar) {
     switch (scalar.value) {
-      case "":
-      case "null":
-      case "Null":
-      case "NULL":
-      case "~":
+      case '':
+      case 'null':
+      case 'Null':
+      case 'NULL':
+      case '~':
         return YamlScalar.internal(null, scalar);
       default:
         return null;
@@ -257,13 +257,13 @@
   /// Returns `null` if parsing fails.
   YamlScalar _parseBool(ScalarEvent scalar) {
     switch (scalar.value) {
-      case "true":
-      case "True":
-      case "TRUE":
+      case 'true':
+      case 'True':
+      case 'TRUE':
         return YamlScalar.internal(true, scalar);
-      case "false":
-      case "False":
-      case "FALSE":
+      case 'false':
+      case 'False':
+      case 'FALSE':
         return YamlScalar.internal(false, scalar);
       default:
         return null;
@@ -335,13 +335,13 @@
       // Starting with a . and a number or a sign followed by a dot.
       if (length == 5) {
         switch (contents) {
-          case "+.inf":
-          case "+.Inf":
-          case "+.INF":
+          case '+.inf':
+          case '+.Inf':
+          case '+.INF':
             return double.infinity;
-          case "-.inf":
-          case "-.Inf":
-          case "-.INF":
+          case '-.inf':
+          case '-.Inf':
+          case '-.INF':
             return -double.infinity;
         }
       }
@@ -351,13 +351,13 @@
 
     if (length == 4 && firstChar == $dot) {
       switch (contents) {
-        case ".inf":
-        case ".Inf":
-        case ".INF":
+        case '.inf':
+        case '.Inf':
+        case '.INF':
           return double.infinity;
-        case ".nan":
-        case ".NaN":
-        case ".NAN":
+        case '.nan':
+        case '.NaN':
+        case '.NAN':
           return double.nan;
       }
     }
diff --git a/lib/src/null_span.dart b/lib/src/null_span.dart
index 7f0c9d6..64b3551 100644
--- a/lib/src/null_span.dart
+++ b/lib/src/null_span.dart
@@ -10,9 +10,12 @@
 /// accessing a non-YAML map that behaves transparently like a map parsed from
 /// YAML.
 class NullSpan extends SourceSpanMixin {
+  @override
   final SourceLocation start;
+  @override
   SourceLocation get end => start;
-  final text = "";
+  @override
+  final text = '';
 
   NullSpan(sourceUrl) : start = SourceLocation(0, sourceUrl: sourceUrl);
 }
diff --git a/lib/src/parser.dart b/lib/src/parser.dart
index bffaa17..4beb1de 100644
--- a/lib/src/parser.dart
+++ b/lib/src/parser.dart
@@ -23,13 +23,13 @@
   final Scanner _scanner;
 
   /// The stack of parse states for nested contexts.
-  final _states = List<_State>();
+  final _states = <_State>[];
 
   /// The current parse state.
   var _state = _State.STREAM_START;
 
   /// The custom tag directives, by tag handle.
-  final _tagDirectives = Map<String, TagDirective>();
+  final _tagDirectives = <String, TagDirective>{};
 
   /// Whether the parser has finished parsing.
   bool get isDone => _state == _State.END;
@@ -43,7 +43,7 @@
   /// Consumes and returns the next event.
   Event parse() {
     try {
-      if (isDone) throw StateError("No more events.");
+      if (isDone) throw StateError('No more events.');
       var event = _stateMachine();
       return event;
     } on StringScannerException catch (error) {
@@ -105,7 +105,7 @@
       case _State.FLOW_MAPPING_EMPTY_VALUE:
         return _parseFlowMappingValue(empty: true);
       default:
-        throw "Unreachable";
+        throw 'Unreachable';
     }
   }
 
@@ -165,7 +165,7 @@
     var tagDirectives = pair.last;
     token = _scanner.peek();
     if (token.type != TokenType.DOCUMENT_START) {
-      throw YamlException("Expected document start.", token.span);
+      throw YamlException('Expected document start.', token.span);
     }
 
     _states.add(_State.DOCUMENT_END);
@@ -284,7 +284,7 @@
       } else {
         var tagDirective = _tagDirectives[tagToken.handle];
         if (tagDirective == null) {
-          throw YamlException("Undefined tag handle.", tagToken.span);
+          throw YamlException('Undefined tag handle.', tagToken.span);
         }
 
         tag = tagDirective.prefix + tagToken.suffix;
@@ -299,7 +299,7 @@
 
     if (token is ScalarToken) {
       // All non-plain scalars have the "!" tag by default.
-      if (tag == null && token.style != ScalarStyle.PLAIN) tag = "!";
+      if (tag == null && token.style != ScalarStyle.PLAIN) tag = '!';
 
       _state = _states.removeLast();
       _scanner.scan();
@@ -336,7 +336,7 @@
       return ScalarEvent(span, '', ScalarStyle.PLAIN, anchor: anchor, tag: tag);
     }
 
-    throw YamlException("Expected node content.", span);
+    throw YamlException('Expected node content.', span);
   }
 
   /// Parses the productions:
@@ -438,7 +438,7 @@
       return Event(EventType.MAPPING_END, token.span);
     }
 
-    throw YamlException("Expected a key while parsing a block mapping.",
+    throw YamlException('Expected a key while parsing a block mapping.',
         token.span.start.pointSpan());
   }
 
@@ -661,18 +661,18 @@
         token.type == TokenType.TAG_DIRECTIVE) {
       if (token is VersionDirectiveToken) {
         if (versionDirective != null) {
-          throw YamlException("Duplicate %YAML directive.", token.span);
+          throw YamlException('Duplicate %YAML directive.', token.span);
         }
 
         if (token.major != 1 || token.minor == 0) {
           throw YamlException(
-              "Incompatible YAML document. This parser only supports YAML 1.1 "
-              "and 1.2.",
+              'Incompatible YAML document. This parser only supports YAML 1.1 '
+              'and 1.2.',
               token.span);
         } else if (token.minor > 2) {
           // TODO(nweiz): Print to stderr when issue 6943 is fixed and dart:io
           // is available.
-          warn("Warning: this parser only supports YAML 1.1 and 1.2.",
+          warn('Warning: this parser only supports YAML 1.1 and 1.2.',
               token.span);
         }
 
@@ -686,10 +686,10 @@
       token = _scanner.advance();
     }
 
-    _appendTagDirective(TagDirective("!", "!"), token.span.start.pointSpan(),
+    _appendTagDirective(TagDirective('!', '!'), token.span.start.pointSpan(),
         allowDuplicates: true);
     _appendTagDirective(
-        TagDirective("!!", "tag:yaml.org,2002:"), token.span.start.pointSpan(),
+        TagDirective('!!', 'tag:yaml.org,2002:'), token.span.start.pointSpan(),
         allowDuplicates: true);
 
     return Pair(versionDirective, tagDirectives);
@@ -700,7 +700,7 @@
       {bool allowDuplicates = false}) {
     if (_tagDirectives.containsKey(newDirective.handle)) {
       if (allowDuplicates) return;
-      throw YamlException("Duplicate %TAG directive.", span);
+      throw YamlException('Duplicate %TAG directive.', span);
     }
 
     _tagDirectives[newDirective.handle] = newDirective;
@@ -710,85 +710,86 @@
 /// The possible states for the parser.
 class _State {
   /// Expect [TokenType.STREAM_START].
-  static const STREAM_START = _State("STREAM_START");
+  static const STREAM_START = _State('STREAM_START');
 
   /// Expect the beginning of an implicit document.
-  static const IMPLICIT_DOCUMENT_START = _State("IMPLICIT_DOCUMENT_START");
+  static const IMPLICIT_DOCUMENT_START = _State('IMPLICIT_DOCUMENT_START');
 
   /// Expect [TokenType.DOCUMENT_START].
-  static const DOCUMENT_START = _State("DOCUMENT_START");
+  static const DOCUMENT_START = _State('DOCUMENT_START');
 
   /// Expect the content of a document.
-  static const DOCUMENT_CONTENT = _State("DOCUMENT_CONTENT");
+  static const DOCUMENT_CONTENT = _State('DOCUMENT_CONTENT');
 
   /// Expect [TokenType.DOCUMENT_END].
-  static const DOCUMENT_END = _State("DOCUMENT_END");
+  static const DOCUMENT_END = _State('DOCUMENT_END');
 
   /// Expect a block node.
-  static const BLOCK_NODE = _State("BLOCK_NODE");
+  static const BLOCK_NODE = _State('BLOCK_NODE');
 
   /// Expect a block node or indentless sequence.
   static const BLOCK_NODE_OR_INDENTLESS_SEQUENCE =
-      _State("BLOCK_NODE_OR_INDENTLESS_SEQUENCE");
+      _State('BLOCK_NODE_OR_INDENTLESS_SEQUENCE');
 
   /// Expect a flow node.
-  static const FLOW_NODE = _State("FLOW_NODE");
+  static const FLOW_NODE = _State('FLOW_NODE');
 
   /// Expect the first entry of a block sequence.
   static const BLOCK_SEQUENCE_FIRST_ENTRY =
-      _State("BLOCK_SEQUENCE_FIRST_ENTRY");
+      _State('BLOCK_SEQUENCE_FIRST_ENTRY');
 
   /// Expect an entry of a block sequence.
-  static const BLOCK_SEQUENCE_ENTRY = _State("BLOCK_SEQUENCE_ENTRY");
+  static const BLOCK_SEQUENCE_ENTRY = _State('BLOCK_SEQUENCE_ENTRY');
 
   /// Expect an entry of an indentless sequence.
-  static const INDENTLESS_SEQUENCE_ENTRY = _State("INDENTLESS_SEQUENCE_ENTRY");
+  static const INDENTLESS_SEQUENCE_ENTRY = _State('INDENTLESS_SEQUENCE_ENTRY');
 
   /// Expect the first key of a block mapping.
-  static const BLOCK_MAPPING_FIRST_KEY = _State("BLOCK_MAPPING_FIRST_KEY");
+  static const BLOCK_MAPPING_FIRST_KEY = _State('BLOCK_MAPPING_FIRST_KEY');
 
   /// Expect a block mapping key.
-  static const BLOCK_MAPPING_KEY = _State("BLOCK_MAPPING_KEY");
+  static const BLOCK_MAPPING_KEY = _State('BLOCK_MAPPING_KEY');
 
   /// Expect a block mapping value.
-  static const BLOCK_MAPPING_VALUE = _State("BLOCK_MAPPING_VALUE");
+  static const BLOCK_MAPPING_VALUE = _State('BLOCK_MAPPING_VALUE');
 
   /// Expect the first entry of a flow sequence.
-  static const FLOW_SEQUENCE_FIRST_ENTRY = _State("FLOW_SEQUENCE_FIRST_ENTRY");
+  static const FLOW_SEQUENCE_FIRST_ENTRY = _State('FLOW_SEQUENCE_FIRST_ENTRY');
 
   /// Expect an entry of a flow sequence.
-  static const FLOW_SEQUENCE_ENTRY = _State("FLOW_SEQUENCE_ENTRY");
+  static const FLOW_SEQUENCE_ENTRY = _State('FLOW_SEQUENCE_ENTRY');
 
   /// Expect a key of an ordered mapping.
   static const FLOW_SEQUENCE_ENTRY_MAPPING_KEY =
-      _State("FLOW_SEQUENCE_ENTRY_MAPPING_KEY");
+      _State('FLOW_SEQUENCE_ENTRY_MAPPING_KEY');
 
   /// Expect a value of an ordered mapping.
   static const FLOW_SEQUENCE_ENTRY_MAPPING_VALUE =
-      _State("FLOW_SEQUENCE_ENTRY_MAPPING_VALUE");
+      _State('FLOW_SEQUENCE_ENTRY_MAPPING_VALUE');
 
   /// Expect the and of an ordered mapping entry.
   static const FLOW_SEQUENCE_ENTRY_MAPPING_END =
-      _State("FLOW_SEQUENCE_ENTRY_MAPPING_END");
+      _State('FLOW_SEQUENCE_ENTRY_MAPPING_END');
 
   /// Expect the first key of a flow mapping.
-  static const FLOW_MAPPING_FIRST_KEY = _State("FLOW_MAPPING_FIRST_KEY");
+  static const FLOW_MAPPING_FIRST_KEY = _State('FLOW_MAPPING_FIRST_KEY');
 
   /// Expect a key of a flow mapping.
-  static const FLOW_MAPPING_KEY = _State("FLOW_MAPPING_KEY");
+  static const FLOW_MAPPING_KEY = _State('FLOW_MAPPING_KEY');
 
   /// Expect a value of a flow mapping.
-  static const FLOW_MAPPING_VALUE = _State("FLOW_MAPPING_VALUE");
+  static const FLOW_MAPPING_VALUE = _State('FLOW_MAPPING_VALUE');
 
   /// Expect an empty value of a flow mapping.
-  static const FLOW_MAPPING_EMPTY_VALUE = _State("FLOW_MAPPING_EMPTY_VALUE");
+  static const FLOW_MAPPING_EMPTY_VALUE = _State('FLOW_MAPPING_EMPTY_VALUE');
 
   /// Expect nothing.
-  static const END = _State("END");
+  static const END = _State('END');
 
   final String name;
 
   const _State(this.name);
 
+  @override
   String toString() => name;
 }
diff --git a/lib/src/scanner.dart b/lib/src/scanner.dart
index 637c8dd..66d9d8b 100644
--- a/lib/src/scanner.dart
+++ b/lib/src/scanner.dart
@@ -295,7 +295,7 @@
 
   /// Consumes and returns the next token.
   Token scan() {
-    if (_streamEndProduced) throw StateError("Out of tokens.");
+    if (_streamEndProduced) throw StateError('Out of tokens.');
     if (!_tokenAvailable) _fetchMoreTokens();
 
     var token = _tokens.removeFirst();
@@ -467,7 +467,7 @@
 
   /// Throws an error about a disallowed character.
   void _invalidScalarCharacter() =>
-      _scanner.error("Unexpected character.", length: 1);
+      _scanner.error('Unexpected character.', length: 1);
 
   /// Checks the list of potential simple keys and remove the positions that
   /// cannot contain simple keys anymore.
@@ -655,7 +655,7 @@
     if (_inBlockContext) {
       if (!_simpleKeyAllowed) {
         throw YamlException(
-            "Block sequence entries are not allowed here.", _scanner.emptySpan);
+            'Block sequence entries are not allowed here.', _scanner.emptySpan);
       }
 
       _rollIndent(
@@ -676,7 +676,7 @@
     if (_inBlockContext) {
       if (!_simpleKeyAllowed) {
         throw YamlException(
-            "Mapping keys are not allowed here.", _scanner.emptySpan);
+            'Mapping keys are not allowed here.', _scanner.emptySpan);
       }
 
       _rollIndent(
@@ -711,8 +711,8 @@
     } else if (_inBlockContext) {
       if (!_simpleKeyAllowed) {
         throw YamlException(
-            "Mapping values are not allowed here. Did you miss a colon "
-            "earlier?",
+            'Mapping values are not allowed here. Did you miss a colon '
+            'earlier?',
             _scanner.emptySpan);
       }
 
@@ -782,7 +782,7 @@
     var afterLineBreak = false;
     while (true) {
       // Allow the BOM to start a line.
-      if (_scanner.column == 0) _scanner.scan("\uFEFF");
+      if (_scanner.column == 0) _scanner.scan('\uFEFF');
 
       // Eat whitespace.
       //
@@ -795,7 +795,7 @@
       }
 
       if (_scanner.peekChar() == TAB) {
-        _scanner.error("Tab characters are not allowed as indentation.",
+        _scanner.error('Tab characters are not allowed as indentation.',
             length: 1);
       }
 
@@ -830,12 +830,12 @@
 
     Token token;
     var name = _scanDirectiveName();
-    if (name == "YAML") {
+    if (name == 'YAML') {
       token = _scanVersionDirectiveValue(start);
-    } else if (name == "TAG") {
+    } else if (name == 'TAG') {
       token = _scanTagDirectiveValue(start);
     } else {
-      warn("Warning: unknown directive.", _scanner.spanFrom(start));
+      warn('Warning: unknown directive.', _scanner.spanFrom(start));
 
       // libyaml doesn't support unknown directives, but the spec says to ignore
       // them and warn: http://yaml.org/spec/1.2/spec.html#id2781147.
@@ -851,7 +851,7 @@
     _skipComment();
 
     if (!_isBreakOrEnd) {
-      throw YamlException("Expected comment or line break after directive.",
+      throw YamlException('Expected comment or line break after directive.',
           _scanner.spanFrom(start));
     }
 
@@ -875,10 +875,10 @@
 
     var name = _scanner.substring(start);
     if (name.isEmpty) {
-      throw YamlException("Expected directive name.", _scanner.emptySpan);
+      throw YamlException('Expected directive name.', _scanner.emptySpan);
     } else if (!_isBlankOrEnd) {
       throw YamlException(
-          "Unexpected character in directive name.", _scanner.emptySpan);
+          'Unexpected character in directive name.', _scanner.emptySpan);
     }
 
     return name;
@@ -912,7 +912,7 @@
 
     var number = _scanner.substring(start);
     if (number.isEmpty) {
-      throw YamlException("Expected version number.", _scanner.emptySpan);
+      throw YamlException('Expected version number.', _scanner.emptySpan);
     }
 
     return int.parse(number);
@@ -927,14 +927,14 @@
 
     var handle = _scanTagHandle(directive: true);
     if (!_isBlank) {
-      throw YamlException("Expected whitespace.", _scanner.emptySpan);
+      throw YamlException('Expected whitespace.', _scanner.emptySpan);
     }
 
     _skipBlanks();
 
     var prefix = _scanTagUri();
     if (!_isBlankOrEnd) {
-      throw YamlException("Expected whitespace.", _scanner.emptySpan);
+      throw YamlException('Expected whitespace.', _scanner.emptySpan);
     }
 
     return TagDirectiveToken(_scanner.spanFrom(start), handle, prefix);
@@ -967,7 +967,7 @@
             next != AT &&
             next != GRAVE_ACCENT)) {
       throw YamlException(
-          "Expected alphanumeric character.", _scanner.emptySpan);
+          'Expected alphanumeric character.', _scanner.emptySpan);
     }
 
     if (anchor) {
@@ -1101,7 +1101,7 @@
       if (_isDigit) {
         // Check that the indentation is greater than 0.
         if (_scanner.peekChar() == NUMBER_0) {
-          throw YamlException("0 may not be used as an indentation indicator.",
+          throw YamlException('0 may not be used as an indentation indicator.',
               _scanner.spanFrom(start));
         }
 
@@ -1110,7 +1110,7 @@
     } else if (_isDigit) {
       // Do the same as above, but in the opposite order.
       if (_scanner.peekChar() == NUMBER_0) {
-        throw YamlException("0 may not be used as an indentation indicator.",
+        throw YamlException('0 may not be used as an indentation indicator.',
             _scanner.spanFrom(start));
       }
 
@@ -1130,7 +1130,7 @@
     // Check if we're at the end of the line.
     if (!_isBreakOrEnd) {
       throw YamlException(
-          "Expected comment or line break.", _scanner.emptySpan);
+          'Expected comment or line break.', _scanner.emptySpan);
     }
 
     _skipLine();
@@ -1257,11 +1257,11 @@
       // Check that there are no document indicators at the beginning of the
       // line.
       if (_isDocumentIndicator) {
-        _scanner.error("Unexpected document indicator.");
+        _scanner.error('Unexpected document indicator.');
       }
 
       if (_scanner.isDone) {
-        throw YamlException("Unexpected end of file.", _scanner.emptySpan);
+        throw YamlException('Unexpected end of file.', _scanner.emptySpan);
       }
 
       var leadingBlanks = false;
@@ -1349,7 +1349,7 @@
               break;
             default:
               throw YamlException(
-                  "Unknown escape character.", _scanner.spanFrom(escapeStart));
+                  'Unknown escape character.', _scanner.spanFrom(escapeStart));
           }
 
           _scanner.readChar();
@@ -1361,7 +1361,7 @@
               if (!_isHex) {
                 _scanner.readChar();
                 throw YamlException(
-                    "Expected $codeLength-digit hexidecimal number.",
+                    'Expected $codeLength-digit hexidecimal number.',
                     _scanner.spanFrom(escapeStart));
               }
 
@@ -1370,7 +1370,7 @@
 
             // Check the value and write the character.
             if ((value >= 0xD800 && value <= 0xDFFF) || value > 0x10FFFF) {
-              throw YamlException("Invalid Unicode character escape code.",
+              throw YamlException('Invalid Unicode character escape code.',
                   _scanner.spanFrom(escapeStart));
             }
 
@@ -1480,7 +1480,7 @@
           if (leadingBreak.isNotEmpty &&
               _scanner.column < indent &&
               _scanner.peekChar() == TAB) {
-            _scanner.error("Expected a space but found a tab.", length: 1);
+            _scanner.error('Expected a space but found a tab.', length: 1);
           }
 
           if (leadingBreak.isEmpty) {
@@ -1525,13 +1525,13 @@
     // libyaml supports NEL, PS, and LS characters as line separators, but this
     // is explicitly forbidden in section 5.4 of the YAML spec.
     if (char != CR && char != LF) {
-      throw YamlException("Expected newline.", _scanner.emptySpan);
+      throw YamlException('Expected newline.', _scanner.emptySpan);
     }
 
     _scanner.readChar();
     // CR LF | CR | LF -> LF
     if (char == CR && _scanner.peekChar() == LF) _scanner.readChar();
-    return "\n";
+    return '\n';
   }
 
   // Returns whether the character at [offset] is whitespace.
@@ -1668,17 +1668,18 @@
 /// See http://yaml.org/spec/1.2/spec.html#id2794534.
 class _Chomping {
   /// All trailing whitespace is discarded.
-  static const STRIP = _Chomping("STRIP");
+  static const STRIP = _Chomping('STRIP');
 
   /// A single trailing newline is retained.
-  static const CLIP = _Chomping("CLIP");
+  static const CLIP = _Chomping('CLIP');
 
   /// All trailing whitespace is preserved.
-  static const KEEP = _Chomping("KEEP");
+  static const KEEP = _Chomping('KEEP');
 
   final String name;
 
   const _Chomping(this.name);
 
+  @override
   String toString() => name;
 }
diff --git a/lib/src/style.dart b/lib/src/style.dart
index e945da8..6ddaf3d 100644
--- a/lib/src/style.dart
+++ b/lib/src/style.dart
@@ -7,32 +7,32 @@
   /// No source style was specified.
   ///
   /// This usually indicates a scalar constructed with [YamlScalar.wrap].
-  static const ANY = ScalarStyle._("ANY");
+  static const ANY = ScalarStyle._('ANY');
 
   /// The plain scalar style, unquoted and without a prefix.
   ///
   /// See http://yaml.org/spec/1.2/spec.html#style/flow/plain.
-  static const PLAIN = ScalarStyle._("PLAIN");
+  static const PLAIN = ScalarStyle._('PLAIN');
 
   /// The literal scalar style, with a `|` prefix.
   ///
   /// See http://yaml.org/spec/1.2/spec.html#id2795688.
-  static const LITERAL = ScalarStyle._("LITERAL");
+  static const LITERAL = ScalarStyle._('LITERAL');
 
   /// The folded scalar style, with a `>` prefix.
   ///
   /// See http://yaml.org/spec/1.2/spec.html#id2796251.
-  static const FOLDED = ScalarStyle._("FOLDED");
+  static const FOLDED = ScalarStyle._('FOLDED');
 
   /// The single-quoted scalar style.
   ///
   /// See http://yaml.org/spec/1.2/spec.html#style/flow/single-quoted.
-  static const SINGLE_QUOTED = ScalarStyle._("SINGLE_QUOTED");
+  static const SINGLE_QUOTED = ScalarStyle._('SINGLE_QUOTED');
 
   /// The double-quoted scalar style.
   ///
   /// See http://yaml.org/spec/1.2/spec.html#style/flow/double-quoted.
-  static const DOUBLE_QUOTED = ScalarStyle._("DOUBLE_QUOTED");
+  static const DOUBLE_QUOTED = ScalarStyle._('DOUBLE_QUOTED');
 
   final String name;
 
@@ -41,6 +41,7 @@
 
   const ScalarStyle._(this.name);
 
+  @override
   String toString() => name;
 }
 
@@ -50,21 +51,22 @@
   ///
   /// This usually indicates a collection constructed with [YamlList.wrap] or
   /// [YamlMap.wrap].
-  static const ANY = CollectionStyle._("ANY");
+  static const ANY = CollectionStyle._('ANY');
 
   /// The indentation-based block style.
   ///
   /// See http://yaml.org/spec/1.2/spec.html#id2797293.
-  static const BLOCK = CollectionStyle._("BLOCK");
+  static const BLOCK = CollectionStyle._('BLOCK');
 
   /// The delimiter-based block style.
   ///
   /// See http://yaml.org/spec/1.2/spec.html#id2790088.
-  static const FLOW = CollectionStyle._("FLOW");
+  static const FLOW = CollectionStyle._('FLOW');
 
   final String name;
 
   const CollectionStyle._(this.name);
 
+  @override
   String toString() => name;
 }
diff --git a/lib/src/token.dart b/lib/src/token.dart
index 62c7c58..7381a7d 100644
--- a/lib/src/token.dart
+++ b/lib/src/token.dart
@@ -16,12 +16,15 @@
 
   Token(this.type, this.span);
 
+  @override
   String toString() => type.toString();
 }
 
 /// A token representing a `%YAML` directive.
 class VersionDirectiveToken implements Token {
-  get type => TokenType.VERSION_DIRECTIVE;
+  @override
+  TokenType get type => TokenType.VERSION_DIRECTIVE;
+  @override
   final FileSpan span;
 
   /// The declared major version of the document.
@@ -32,12 +35,15 @@
 
   VersionDirectiveToken(this.span, this.major, this.minor);
 
-  String toString() => "VERSION_DIRECTIVE $major.$minor";
+  @override
+  String toString() => 'VERSION_DIRECTIVE $major.$minor';
 }
 
 /// A token representing a `%TAG` directive.
 class TagDirectiveToken implements Token {
-  get type => TokenType.TAG_DIRECTIVE;
+  @override
+  TokenType get type => TokenType.TAG_DIRECTIVE;
+  @override
   final FileSpan span;
 
   /// The tag handle used in the document.
@@ -48,12 +54,15 @@
 
   TagDirectiveToken(this.span, this.handle, this.prefix);
 
-  String toString() => "TAG_DIRECTIVE $handle $prefix";
+  @override
+  String toString() => 'TAG_DIRECTIVE $handle $prefix';
 }
 
 /// A token representing an anchor (`&foo`).
 class AnchorToken implements Token {
-  get type => TokenType.ANCHOR;
+  @override
+  TokenType get type => TokenType.ANCHOR;
+  @override
   final FileSpan span;
 
   /// The name of the anchor.
@@ -61,12 +70,15 @@
 
   AnchorToken(this.span, this.name);
 
-  String toString() => "ANCHOR $name";
+  @override
+  String toString() => 'ANCHOR $name';
 }
 
 /// A token representing an alias (`*foo`).
 class AliasToken implements Token {
-  get type => TokenType.ALIAS;
+  @override
+  TokenType get type => TokenType.ALIAS;
+  @override
   final FileSpan span;
 
   /// The name of the anchor.
@@ -74,12 +86,15 @@
 
   AliasToken(this.span, this.name);
 
-  String toString() => "ALIAS $name";
+  @override
+  String toString() => 'ALIAS $name';
 }
 
 /// A token representing a tag (`!foo`).
 class TagToken implements Token {
-  get type => TokenType.TAG;
+  @override
+  TokenType get type => TokenType.TAG;
+  @override
   final FileSpan span;
 
   /// The tag handle.
@@ -90,12 +105,15 @@
 
   TagToken(this.span, this.handle, this.suffix);
 
-  String toString() => "TAG $handle $suffix";
+  @override
+  String toString() => 'TAG $handle $suffix';
 }
 
 /// A tkoen representing a scalar value.
 class ScalarToken implements Token {
-  get type => TokenType.SCALAR;
+  @override
+  TokenType get type => TokenType.SCALAR;
+  @override
   final FileSpan span;
 
   /// The contents of the scalar.
@@ -106,41 +124,43 @@
 
   ScalarToken(this.span, this.value, this.style);
 
-  String toString() => "SCALAR $style \"$value\"";
+  @override
+  String toString() => 'SCALAR $style "$value"';
 }
 
 /// An enum of types of [Token] object.
 class TokenType {
-  static const STREAM_START = TokenType._("STREAM_START");
-  static const STREAM_END = TokenType._("STREAM_END");
+  static const STREAM_START = TokenType._('STREAM_START');
+  static const STREAM_END = TokenType._('STREAM_END');
 
-  static const VERSION_DIRECTIVE = TokenType._("VERSION_DIRECTIVE");
-  static const TAG_DIRECTIVE = TokenType._("TAG_DIRECTIVE");
-  static const DOCUMENT_START = TokenType._("DOCUMENT_START");
-  static const DOCUMENT_END = TokenType._("DOCUMENT_END");
+  static const VERSION_DIRECTIVE = TokenType._('VERSION_DIRECTIVE');
+  static const TAG_DIRECTIVE = TokenType._('TAG_DIRECTIVE');
+  static const DOCUMENT_START = TokenType._('DOCUMENT_START');
+  static const DOCUMENT_END = TokenType._('DOCUMENT_END');
 
-  static const BLOCK_SEQUENCE_START = TokenType._("BLOCK_SEQUENCE_START");
-  static const BLOCK_MAPPING_START = TokenType._("BLOCK_MAPPING_START");
-  static const BLOCK_END = TokenType._("BLOCK_END");
+  static const BLOCK_SEQUENCE_START = TokenType._('BLOCK_SEQUENCE_START');
+  static const BLOCK_MAPPING_START = TokenType._('BLOCK_MAPPING_START');
+  static const BLOCK_END = TokenType._('BLOCK_END');
 
-  static const FLOW_SEQUENCE_START = TokenType._("FLOW_SEQUENCE_START");
-  static const FLOW_SEQUENCE_END = TokenType._("FLOW_SEQUENCE_END");
-  static const FLOW_MAPPING_START = TokenType._("FLOW_MAPPING_START");
-  static const FLOW_MAPPING_END = TokenType._("FLOW_MAPPING_END");
+  static const FLOW_SEQUENCE_START = TokenType._('FLOW_SEQUENCE_START');
+  static const FLOW_SEQUENCE_END = TokenType._('FLOW_SEQUENCE_END');
+  static const FLOW_MAPPING_START = TokenType._('FLOW_MAPPING_START');
+  static const FLOW_MAPPING_END = TokenType._('FLOW_MAPPING_END');
 
-  static const BLOCK_ENTRY = TokenType._("BLOCK_ENTRY");
-  static const FLOW_ENTRY = TokenType._("FLOW_ENTRY");
-  static const KEY = TokenType._("KEY");
-  static const VALUE = TokenType._("VALUE");
+  static const BLOCK_ENTRY = TokenType._('BLOCK_ENTRY');
+  static const FLOW_ENTRY = TokenType._('FLOW_ENTRY');
+  static const KEY = TokenType._('KEY');
+  static const VALUE = TokenType._('VALUE');
 
-  static const ALIAS = TokenType._("ALIAS");
-  static const ANCHOR = TokenType._("ANCHOR");
-  static const TAG = TokenType._("TAG");
-  static const SCALAR = TokenType._("SCALAR");
+  static const ALIAS = TokenType._('ALIAS');
+  static const ANCHOR = TokenType._('ANCHOR');
+  static const TAG = TokenType._('TAG');
+  static const SCALAR = TokenType._('SCALAR');
 
   final String name;
 
   const TokenType._(this.name);
 
+  @override
   String toString() => name;
 }
diff --git a/lib/src/utils.dart b/lib/src/utils.dart
index 93954aa..8ce7855 100644
--- a/lib/src/utils.dart
+++ b/lib/src/utils.dart
@@ -11,6 +11,7 @@
 
   Pair(this.first, this.last);
 
+  @override
   String toString() => '($first, $last)';
 }
 
diff --git a/lib/src/yaml_document.dart b/lib/src/yaml_document.dart
index 07806e9..8757418 100644
--- a/lib/src/yaml_document.dart
+++ b/lib/src/yaml_document.dart
@@ -35,6 +35,7 @@
       {this.startImplicit = false, this.endImplicit = false})
       : tagDirectives = UnmodifiableListView(tagDirectives);
 
+  @override
   String toString() => contents.toString();
 }
 
@@ -48,7 +49,8 @@
 
   VersionDirective(this.major, this.minor);
 
-  String toString() => "%YAML $major.$minor";
+  @override
+  String toString() => '%YAML $major.$minor';
 }
 
 /// A directive describing a custom tag handle.
@@ -61,5 +63,6 @@
 
   TagDirective(this.handle, this.prefix);
 
-  String toString() => "%TAG $handle $prefix";
+  @override
+  String toString() => '%TAG $handle $prefix';
 }
diff --git a/lib/src/yaml_node.dart b/lib/src/yaml_node.dart
index 3b0a983..25982e8 100644
--- a/lib/src/yaml_node.dart
+++ b/lib/src/yaml_node.dart
@@ -35,7 +35,7 @@
   /// For [YamlScalar]s, this will return the wrapped value. For [YamlMap] and
   /// [YamlList], it will return [this], since they already implement [Map] and
   /// [List], respectively.
-  get value;
+  dynamic get value;
 }
 
 /// A read-only [Map] parsed from YAML.
@@ -53,8 +53,10 @@
   /// The style used for the map in the original document.
   final CollectionStyle style;
 
+  @override
   Map get value => this;
 
+  @override
   Iterable get keys => nodes.keys.map((node) => node.value);
 
   /// Creates an empty YamlMap.
@@ -84,10 +86,8 @@
     _span = span;
   }
 
-  operator [](key) {
-    var node = nodes[key];
-    return node == null ? null : node.value;
-  }
+  @override
+  dynamic operator [](key) => nodes[key]?.value;
 }
 
 // TODO(nweiz): Use UnmodifiableListMixin when issue 18970 is fixed.
@@ -98,12 +98,15 @@
   /// The style used for the list in the original document.
   final CollectionStyle style;
 
+  @override
   List get value => this;
 
+  @override
   int get length => nodes.length;
 
+  @override
   set length(int index) {
-    throw UnsupportedError("Cannot modify an unmodifiable List");
+    throw UnsupportedError('Cannot modify an unmodifiable List');
   }
 
   /// Creates an empty YamlList.
@@ -133,16 +136,19 @@
     _span = span;
   }
 
-  operator [](int index) => nodes[index].value;
+  @override
+  dynamic operator [](int index) => nodes[index].value;
 
+  @override
   operator []=(int index, value) {
-    throw UnsupportedError("Cannot modify an unmodifiable List");
+    throw UnsupportedError('Cannot modify an unmodifiable List');
   }
 }
 
 /// A wrapped scalar value parsed from YAML.
 class YamlScalar extends YamlNode {
-  final value;
+  @override
+  final dynamic value;
 
   /// The style used for the scalar in the original document.
   final ScalarStyle style;
@@ -169,6 +175,7 @@
     _span = span;
   }
 
+  @override
   String toString() => value.toString();
 }
 
diff --git a/lib/src/yaml_node_wrapper.dart b/lib/src/yaml_node_wrapper.dart
index fc987af..e714b65 100644
--- a/lib/src/yaml_node_wrapper.dart
+++ b/lib/src/yaml_node_wrapper.dart
@@ -15,16 +15,21 @@
 class YamlMapWrapper extends MapBase
     with pkg_collection.UnmodifiableMapMixin
     implements YamlMap {
-  final CollectionStyle style = CollectionStyle.ANY;
+  @override
+  final style = CollectionStyle.ANY;
 
   final Map _dartMap;
 
+  @override
   final SourceSpan span;
 
+  @override
   final Map<dynamic, YamlNode> nodes;
 
+  @override
   Map get value => this;
 
+  @override
   Iterable get keys => _dartMap.keys;
 
   YamlMapWrapper(Map dartMap, sourceUrl) : this._(dartMap, NullSpan(sourceUrl));
@@ -34,16 +39,19 @@
         span = span,
         nodes = _YamlMapNodes(dartMap, span);
 
-  operator [](Object key) {
+  @override
+  dynamic operator [](Object key) {
     var value = _dartMap[key];
     if (value is Map) return YamlMapWrapper._(value, span);
     if (value is List) return YamlListWrapper._(value, span);
     return value;
   }
 
+  @override
   int get hashCode => _dartMap.hashCode;
 
-  operator ==(Object other) =>
+  @override
+  bool operator ==(Object other) =>
       other is YamlMapWrapper && other._dartMap == _dartMap;
 }
 
@@ -55,11 +63,13 @@
 
   final SourceSpan _span;
 
+  @override
   Iterable get keys =>
       _dartMap.keys.map((key) => YamlScalar.internalWithSpan(key, _span));
 
   _YamlMapNodes(this._dartMap, this._span);
 
+  @override
   YamlNode operator [](Object key) {
     // Use "as" here because key being assigned to invalidates type propagation.
     if (key is YamlScalar) key = (key as YamlScalar).value;
@@ -67,29 +77,37 @@
     return _nodeForValue(_dartMap[key], _span);
   }
 
+  @override
   int get hashCode => _dartMap.hashCode;
 
-  operator ==(Object other) =>
+  @override
+  bool operator ==(Object other) =>
       other is _YamlMapNodes && other._dartMap == _dartMap;
 }
 
 // TODO(nweiz): Use UnmodifiableListMixin when issue 18970 is fixed.
 /// A wrapper that makes a normal Dart list behave like a [YamlList].
 class YamlListWrapper extends ListBase implements YamlList {
-  final CollectionStyle style = CollectionStyle.ANY;
+  @override
+  final style = CollectionStyle.ANY;
 
   final List _dartList;
 
+  @override
   final SourceSpan span;
 
+  @override
   final List<YamlNode> nodes;
 
+  @override
   List get value => this;
 
+  @override
   int get length => _dartList.length;
 
+  @override
   set length(int index) {
-    throw UnsupportedError("Cannot modify an unmodifiable List.");
+    throw UnsupportedError('Cannot modify an unmodifiable List.');
   }
 
   YamlListWrapper(List dartList, sourceUrl)
@@ -100,20 +118,24 @@
         span = span,
         nodes = _YamlListNodes(dartList, span);
 
-  operator [](int index) {
+  @override
+  dynamic operator [](int index) {
     var value = _dartList[index];
     if (value is Map) return YamlMapWrapper._(value, span);
     if (value is List) return YamlListWrapper._(value, span);
     return value;
   }
 
+  @override
   operator []=(int index, value) {
-    throw UnsupportedError("Cannot modify an unmodifiable List.");
+    throw UnsupportedError('Cannot modify an unmodifiable List.');
   }
 
+  @override
   int get hashCode => _dartList.hashCode;
 
-  operator ==(Object other) =>
+  @override
+  bool operator ==(Object other) =>
       other is YamlListWrapper && other._dartList == _dartList;
 }
 
@@ -125,23 +147,29 @@
 
   final SourceSpan _span;
 
+  @override
   int get length => _dartList.length;
 
+  @override
   set length(int index) {
-    throw UnsupportedError("Cannot modify an unmodifiable List.");
+    throw UnsupportedError('Cannot modify an unmodifiable List.');
   }
 
   _YamlListNodes(this._dartList, this._span);
 
+  @override
   YamlNode operator [](int index) => _nodeForValue(_dartList[index], _span);
 
+  @override
   operator []=(int index, value) {
-    throw UnsupportedError("Cannot modify an unmodifiable List.");
+    throw UnsupportedError('Cannot modify an unmodifiable List.');
   }
 
+  @override
   int get hashCode => _dartList.hashCode;
 
-  operator ==(Object other) =>
+  @override
+  bool operator ==(Object other) =>
       other is _YamlListNodes && other._dartList == _dartList;
 }
 
diff --git a/lib/yaml.dart b/lib/yaml.dart
index e2435ad..2ef65e7 100644
--- a/lib/yaml.dart
+++ b/lib/yaml.dart
@@ -30,7 +30,7 @@
 ///
 /// If [sourceUrl] is passed, it's used as the URL from which the YAML
 /// originated for error reporting. It can be a [String], a [Uri], or `null`.
-loadYaml(String yaml, {sourceUrl}) =>
+dynamic loadYaml(String yaml, {sourceUrl}) =>
     loadYamlNode(yaml, sourceUrl: sourceUrl).value;
 
 /// Loads a single document from a YAML string as a [YamlNode].
@@ -56,7 +56,7 @@
 
   var nextDocument = loader.load();
   if (nextDocument != null) {
-    throw YamlException("Only expected one document.", nextDocument.span);
+    throw YamlException('Only expected one document.', nextDocument.span);
   }
 
   return document;
diff --git a/pubspec.yaml b/pubspec.yaml
index 6d056da..d83ad8a 100644
--- a/pubspec.yaml
+++ b/pubspec.yaml
@@ -1,12 +1,12 @@
 name: yaml
-version: 2.2.0
+version: 2.2.1-dev
 
 description: A parser for YAML, a human-friendly data serialization standard
 author: Dart Team <misc@dartlang.org>
 homepage: https://github.com/dart-lang/yaml
 
 environment:
-  sdk: '>=2.0.0 <3.0.0'
+  sdk: '>=2.3.0 <3.0.0'
 
 dependencies:
   charcode: ^1.1.0
diff --git a/test/utils.dart b/test/utils.dart
index 5ecbd14..c49afe2 100644
--- a/test/utils.dart
+++ b/test/utils.dart
@@ -13,7 +13,7 @@
 ///
 /// This handles recursive loops and considers `NaN` to equal itself.
 Matcher deepEquals(expected) => predicate(
-    (actual) => equality.deepEquals(actual, expected), "equals $expected");
+    (actual) => equality.deepEquals(actual, expected), 'equals $expected');
 
 /// Constructs a new yaml.YamlMap, optionally from a normal Map.
 Map deepEqualsMap([Map from]) {
@@ -77,8 +77,8 @@
   if (lines.length <= 1) return text;
 
   for (var i = 0; i < lines.length; i++) {
-    lines[i] = "        ${lines[i]}";
+    lines[i] = '        ${lines[i]}';
   }
 
-  return lines.join("\n");
+  return lines.join('\n');
 }
diff --git a/test/yaml_node_wrapper_test.dart b/test/yaml_node_wrapper_test.dart
index f9b0272..9dc991e 100644
--- a/test/yaml_node_wrapper_test.dart
+++ b/test/yaml_node_wrapper_test.dart
@@ -6,94 +6,94 @@
 import 'package:test/test.dart';
 import 'package:yaml/yaml.dart';
 
-main() {
-  test("YamlMap() with no sourceUrl", () {
+void main() {
+  test('YamlMap() with no sourceUrl', () {
     var map = YamlMap();
     expect(map, isEmpty);
     expect(map.nodes, isEmpty);
     expect(map.span, isNullSpan(isNull));
   });
 
-  test("YamlMap() with a sourceUrl", () {
-    var map = YamlMap(sourceUrl: "source");
-    expect(map.span, isNullSpan(Uri.parse("source")));
+  test('YamlMap() with a sourceUrl', () {
+    var map = YamlMap(sourceUrl: 'source');
+    expect(map.span, isNullSpan(Uri.parse('source')));
   });
 
-  test("YamlList() with no sourceUrl", () {
+  test('YamlList() with no sourceUrl', () {
     var list = YamlList();
     expect(list, isEmpty);
     expect(list.nodes, isEmpty);
     expect(list.span, isNullSpan(isNull));
   });
 
-  test("YamlList() with a sourceUrl", () {
-    var list = YamlList(sourceUrl: "source");
-    expect(list.span, isNullSpan(Uri.parse("source")));
+  test('YamlList() with a sourceUrl', () {
+    var list = YamlList(sourceUrl: 'source');
+    expect(list.span, isNullSpan(Uri.parse('source')));
   });
 
-  test("YamlMap.wrap() with no sourceUrl", () {
+  test('YamlMap.wrap() with no sourceUrl', () {
     var map = YamlMap.wrap({
-      "list": [1, 2, 3],
-      "map": {
-        "foo": "bar",
-        "nested": [4, 5, 6]
+      'list': [1, 2, 3],
+      'map': {
+        'foo': 'bar',
+        'nested': [4, 5, 6]
       },
-      "scalar": "value"
+      'scalar': 'value'
     });
 
     expect(
         map,
         equals({
-          "list": [1, 2, 3],
-          "map": {
-            "foo": "bar",
-            "nested": [4, 5, 6]
+          'list': [1, 2, 3],
+          'map': {
+            'foo': 'bar',
+            'nested': [4, 5, 6]
           },
-          "scalar": "value"
+          'scalar': 'value'
         }));
 
     expect(map.span, isNullSpan(isNull));
-    expect(map["list"], TypeMatcher<YamlList>());
-    expect(map["list"].nodes[0], TypeMatcher<YamlScalar>());
-    expect(map["list"].span, isNullSpan(isNull));
-    expect(map["map"], TypeMatcher<YamlMap>());
-    expect(map["map"].nodes["foo"], TypeMatcher<YamlScalar>());
-    expect(map["map"]["nested"], TypeMatcher<YamlList>());
-    expect(map["map"].span, isNullSpan(isNull));
-    expect(map.nodes["scalar"], TypeMatcher<YamlScalar>());
-    expect(map.nodes["scalar"].value, "value");
-    expect(map.nodes["scalar"].span, isNullSpan(isNull));
-    expect(map["scalar"], "value");
-    expect(map.keys, unorderedEquals(["list", "map", "scalar"]));
+    expect(map['list'], TypeMatcher<YamlList>());
+    expect(map['list'].nodes[0], TypeMatcher<YamlScalar>());
+    expect(map['list'].span, isNullSpan(isNull));
+    expect(map['map'], TypeMatcher<YamlMap>());
+    expect(map['map'].nodes['foo'], TypeMatcher<YamlScalar>());
+    expect(map['map']['nested'], TypeMatcher<YamlList>());
+    expect(map['map'].span, isNullSpan(isNull));
+    expect(map.nodes['scalar'], TypeMatcher<YamlScalar>());
+    expect(map.nodes['scalar'].value, 'value');
+    expect(map.nodes['scalar'].span, isNullSpan(isNull));
+    expect(map['scalar'], 'value');
+    expect(map.keys, unorderedEquals(['list', 'map', 'scalar']));
     expect(map.nodes.keys, everyElement(TypeMatcher<YamlScalar>()));
-    expect(map.nodes[YamlScalar.wrap("list")], equals([1, 2, 3]));
+    expect(map.nodes[YamlScalar.wrap('list')], equals([1, 2, 3]));
   });
 
-  test("YamlMap.wrap() with a sourceUrl", () {
+  test('YamlMap.wrap() with a sourceUrl', () {
     var map = YamlMap.wrap({
-      "list": [1, 2, 3],
-      "map": {
-        "foo": "bar",
-        "nested": [4, 5, 6]
+      'list': [1, 2, 3],
+      'map': {
+        'foo': 'bar',
+        'nested': [4, 5, 6]
       },
-      "scalar": "value"
-    }, sourceUrl: "source");
+      'scalar': 'value'
+    }, sourceUrl: 'source');
 
-    var source = Uri.parse("source");
+    var source = Uri.parse('source');
     expect(map.span, isNullSpan(source));
-    expect(map["list"].span, isNullSpan(source));
-    expect(map["map"].span, isNullSpan(source));
-    expect(map.nodes["scalar"].span, isNullSpan(source));
+    expect(map['list'].span, isNullSpan(source));
+    expect(map['map'].span, isNullSpan(source));
+    expect(map.nodes['scalar'].span, isNullSpan(source));
   });
 
-  test("YamlList.wrap() with no sourceUrl", () {
+  test('YamlList.wrap() with no sourceUrl', () {
     var list = YamlList.wrap([
       [1, 2, 3],
       {
-        "foo": "bar",
-        "nested": [4, 5, 6]
+        'foo': 'bar',
+        'nested': [4, 5, 6]
       },
-      "value"
+      'value'
     ]);
 
     expect(
@@ -101,10 +101,10 @@
         equals([
           [1, 2, 3],
           {
-            "foo": "bar",
-            "nested": [4, 5, 6]
+            'foo': 'bar',
+            'nested': [4, 5, 6]
           },
-          "value"
+          'value'
         ]));
 
     expect(list.span, isNullSpan(isNull));
@@ -112,23 +112,23 @@
     expect(list[0].nodes[0], TypeMatcher<YamlScalar>());
     expect(list[0].span, isNullSpan(isNull));
     expect(list[1], TypeMatcher<YamlMap>());
-    expect(list[1].nodes["foo"], TypeMatcher<YamlScalar>());
-    expect(list[1]["nested"], TypeMatcher<YamlList>());
+    expect(list[1].nodes['foo'], TypeMatcher<YamlScalar>());
+    expect(list[1]['nested'], TypeMatcher<YamlList>());
     expect(list[1].span, isNullSpan(isNull));
     expect(list.nodes[2], TypeMatcher<YamlScalar>());
-    expect(list.nodes[2].value, "value");
+    expect(list.nodes[2].value, 'value');
     expect(list.nodes[2].span, isNullSpan(isNull));
-    expect(list[2], "value");
+    expect(list[2], 'value');
   });
 
-  test("YamlList.wrap() with a sourceUrl", () {
+  test('YamlList.wrap() with a sourceUrl', () {
     var list = YamlList.wrap([
       [1, 2, 3],
       {
-        "foo": "bar",
-        "nested": [4, 5, 6]
+        'foo': 'bar',
+        'nested': [4, 5, 6]
       },
-      "value"
+      'value'
     ]);
 
     expect(list.span, isNullSpan(isNull));
@@ -137,10 +137,10 @@
     expect(list.nodes[2].span, isNullSpan(isNull));
   });
 
-  test("re-wrapped objects equal one another", () {
+  test('re-wrapped objects equal one another', () {
     var list = YamlList.wrap([
       [1, 2, 3],
-      {"foo": "bar"}
+      {'foo': 'bar'}
     ]);
 
     expect(list[0] == list[0], isTrue);
@@ -148,7 +148,7 @@
     expect(list[0] == YamlList.wrap([1, 2, 3]), isFalse);
     expect(list[1] == list[1], isTrue);
     expect(list[1].nodes == list[1].nodes, isTrue);
-    expect(list[1] == YamlMap.wrap({"foo": "bar"}), isFalse);
+    expect(list[1] == YamlMap.wrap({'foo': 'bar'}), isFalse);
   });
 }
 
diff --git a/test/yaml_test.dart b/test/yaml_test.dart
index dcc506a..a0fb8f1 100644
--- a/test/yaml_test.dart
+++ b/test/yaml_test.dart
@@ -7,9 +7,9 @@
 
 import 'utils.dart';
 
-main() {
-  var infinity = double.parse("Infinity");
-  var nan = double.parse("NaN");
+void main() {
+  var infinity = double.parse('Infinity');
+  var nan = double.parse('NaN');
 
   group('has a friendly error message for', () {
     var tabError = predicate((e) =>
@@ -27,46 +27,46 @@
     });
   });
 
-  group("refuses", () {
+  group('refuses', () {
     // Regression test for #19.
-    test("invalid contents", () {
-      expectYamlFails("{");
+    test('invalid contents', () {
+      expectYamlFails('{');
     });
 
-    test("duplicate mapping keys", () {
-      expectYamlFails("{a: 1, a: 2}");
+    test('duplicate mapping keys', () {
+      expectYamlFails('{a: 1, a: 2}');
     });
 
-    group("documents that declare version", () {
-      test("1.0", () {
-        expectYamlFails("""
+    group('documents that declare version', () {
+      test('1.0', () {
+        expectYamlFails('''
          %YAML 1.0
          --- text
-         """);
+         ''');
       });
 
-      test("1.3", () {
-        expectYamlFails("""
+      test('1.3', () {
+        expectYamlFails('''
            %YAML 1.3
            --- text
-           """);
+           ''');
       });
 
-      test("2.0", () {
-        expectYamlFails("""
+      test('2.0', () {
+        expectYamlFails('''
            %YAML 2.0
            --- text
-           """);
+           ''');
       });
     });
   });
 
-  test("includes source span information", () {
-    var yaml = loadYamlNode(r"""
+  test('includes source span information', () {
+    var yaml = loadYamlNode(r'''
 - foo:
     bar
 - 123
-""") as YamlList;
+''') as YamlList;
 
     expect(yaml.span.start.line, equals(0));
     expect(yaml.span.start.column, equals(0));
@@ -113,24 +113,24 @@
   // the spec.
   group('2.1: Collections', () {
     test('[Example 2.1]', () {
-      expectYamlLoads(["Mark McGwire", "Sammy Sosa", "Ken Griffey"], """
+      expectYamlLoads(['Mark McGwire', 'Sammy Sosa', 'Ken Griffey'], '''
         - Mark McGwire
         - Sammy Sosa
-        - Ken Griffey""");
+        - Ken Griffey''');
     });
 
     test('[Example 2.2]', () {
-      expectYamlLoads({"hr": 65, "avg": 0.278, "rbi": 147}, """
+      expectYamlLoads({'hr': 65, 'avg': 0.278, 'rbi': 147}, '''
         hr:  65    # Home runs
         avg: 0.278 # Batting average
-        rbi: 147   # Runs Batted In""");
+        rbi: 147   # Runs Batted In''');
     });
 
     test('[Example 2.3]', () {
       expectYamlLoads({
-        "american": ["Boston Red Sox", "Detroit Tigers", "New York Yankees"],
-        "national": ["New York Mets", "Chicago Cubs", "Atlanta Braves"],
-      }, """
+        'american': ['Boston Red Sox', 'Detroit Tigers', 'New York Yankees'],
+        'national': ['New York Mets', 'Chicago Cubs', 'Atlanta Braves'],
+      }, '''
         american:
           - Boston Red Sox
           - Detroit Tigers
@@ -138,14 +138,14 @@
         national:
           - New York Mets
           - Chicago Cubs
-          - Atlanta Braves""");
+          - Atlanta Braves''');
     });
 
     test('[Example 2.4]', () {
       expectYamlLoads([
-        {"name": "Mark McGwire", "hr": 65, "avg": 0.278},
-        {"name": "Sammy Sosa", "hr": 63, "avg": 0.288},
-      ], """
+        {'name': 'Mark McGwire', 'hr': 65, 'avg': 0.278},
+        {'name': 'Sammy Sosa', 'hr': 63, 'avg': 0.288},
+      ], '''
         -
           name: Mark McGwire
           hr:   65
@@ -153,39 +153,39 @@
         -
           name: Sammy Sosa
           hr:   63
-          avg:  0.288""");
+          avg:  0.288''');
     });
 
     test('[Example 2.5]', () {
       expectYamlLoads([
-        ["name", "hr", "avg"],
-        ["Mark McGwire", 65, 0.278],
-        ["Sammy Sosa", 63, 0.288]
-      ], """
+        ['name', 'hr', 'avg'],
+        ['Mark McGwire', 65, 0.278],
+        ['Sammy Sosa', 63, 0.288]
+      ], '''
         - [name        , hr, avg  ]
         - [Mark McGwire, 65, 0.278]
-        - [Sammy Sosa  , 63, 0.288]""");
+        - [Sammy Sosa  , 63, 0.288]''');
     });
 
     test('[Example 2.6]', () {
       expectYamlLoads({
-        "Mark McGwire": {"hr": 65, "avg": 0.278},
-        "Sammy Sosa": {"hr": 63, "avg": 0.288}
-      }, """
+        'Mark McGwire': {'hr': 65, 'avg': 0.278},
+        'Sammy Sosa': {'hr': 63, 'avg': 0.288}
+      }, '''
         Mark McGwire: {hr: 65, avg: 0.278}
         Sammy Sosa: {
             hr: 63,
             avg: 0.288
-          }""");
+          }''');
     });
   });
 
   group('2.2: Structures', () {
     test('[Example 2.7]', () {
       expectYamlStreamLoads([
-        ["Mark McGwire", "Sammy Sosa", "Ken Griffey"],
-        ["Chicago Cubs", "St Louis Cardinals"]
-      ], """
+        ['Mark McGwire', 'Sammy Sosa', 'Ken Griffey'],
+        ['Chicago Cubs', 'St Louis Cardinals']
+      ], '''
         # Ranking of 1998 home runs
         ---
         - Mark McGwire
@@ -195,14 +195,14 @@
         # Team ranking
         ---
         - Chicago Cubs
-        - St Louis Cardinals""");
+        - St Louis Cardinals''');
     });
 
     test('[Example 2.8]', () {
       expectYamlStreamLoads([
-        {"time": "20:03:20", "player": "Sammy Sosa", "action": "strike (miss)"},
-        {"time": "20:03:47", "player": "Sammy Sosa", "action": "grand slam"},
-      ], """
+        {'time': '20:03:20', 'player': 'Sammy Sosa', 'action': 'strike (miss)'},
+        {'time': '20:03:47', 'player': 'Sammy Sosa', 'action': 'grand slam'},
+      ], '''
         ---
         time: 20:03:20
         player: Sammy Sosa
@@ -212,14 +212,14 @@
         time: 20:03:47
         player: Sammy Sosa
         action: grand slam
-        ...""");
+        ...''');
     });
 
     test('[Example 2.9]', () {
       expectYamlLoads({
-        "hr": ["Mark McGwire", "Sammy Sosa"],
-        "rbi": ["Sammy Sosa", "Ken Griffey"]
-      }, """
+        'hr': ['Mark McGwire', 'Sammy Sosa'],
+        'rbi': ['Sammy Sosa', 'Ken Griffey']
+      }, '''
         ---
         hr: # 1998 hr ranking
           - Mark McGwire
@@ -227,14 +227,14 @@
         rbi:
           # 1998 rbi ranking
           - Sammy Sosa
-          - Ken Griffey""");
+          - Ken Griffey''');
     });
 
     test('[Example 2.10]', () {
       expectYamlLoads({
-        "hr": ["Mark McGwire", "Sammy Sosa"],
-        "rbi": ["Sammy Sosa", "Ken Griffey"]
-      }, """
+        'hr': ['Mark McGwire', 'Sammy Sosa'],
+        'rbi': ['Sammy Sosa', 'Ken Griffey']
+      }, '''
         ---
         hr:
           - Mark McGwire
@@ -242,18 +242,18 @@
           - &SS Sammy Sosa
         rbi:
           - *SS # Subsequent occurrence
-          - Ken Griffey""");
+          - Ken Griffey''');
     });
 
     test('[Example 2.11]', () {
       var doc = deepEqualsMap();
-      doc[["Detroit Tigers", "Chicago cubs"]] = ["2001-07-23"];
-      doc[["New York Yankees", "Atlanta Braves"]] = [
-        "2001-07-02",
-        "2001-08-12",
-        "2001-08-14"
+      doc[['Detroit Tigers', 'Chicago cubs']] = ['2001-07-23'];
+      doc[['New York Yankees', 'Atlanta Braves']] = [
+        '2001-07-02',
+        '2001-08-12',
+        '2001-08-14'
       ];
-      expectYamlLoads(doc, """
+      expectYamlLoads(doc, '''
         ? - Detroit Tigers
           - Chicago cubs
         :
@@ -262,15 +262,15 @@
         ? [ New York Yankees,
             Atlanta Braves ]
         : [ 2001-07-02, 2001-08-12,
-            2001-08-14 ]""");
+            2001-08-14 ]''');
     });
 
     test('[Example 2.12]', () {
       expectYamlLoads([
-        {"item": "Super Hoop", "quantity": 1},
-        {"item": "Basketball", "quantity": 4},
-        {"item": "Big Shoes", "quantity": 1},
-      ], """
+        {'item': 'Super Hoop', 'quantity': 1},
+        {'item': 'Basketball', 'quantity': 4},
+        {'item': 'Big Shoes', 'quantity': 1},
+      ], '''
         ---
         # Products purchased
         - item    : Super Hoop
@@ -278,37 +278,37 @@
         - item    : Basketball
           quantity: 4
         - item    : Big Shoes
-          quantity: 1""");
+          quantity: 1''');
     });
   });
 
   group('2.3: Scalars', () {
     test('[Example 2.13]', () {
-      expectYamlLoads(cleanUpLiteral("""
+      expectYamlLoads(cleanUpLiteral('''
         \\//||\\/||
-        // ||  ||__"""), """
+        // ||  ||__'''), '''
         # ASCII Art
         --- |
           \\//||\\/||
-          // ||  ||__""");
+          // ||  ||__''');
     });
 
     test('[Example 2.14]', () {
-      expectYamlLoads("Mark McGwire's year was crippled by a knee injury.", """
+      expectYamlLoads("Mark McGwire's year was crippled by a knee injury.", '''
         --- >
           Mark McGwire's
           year was crippled
-          by a knee injury.""");
+          by a knee injury.''');
     });
 
     test('[Example 2.15]', () {
-      expectYamlLoads(cleanUpLiteral("""
+      expectYamlLoads(cleanUpLiteral('''
         Sammy Sosa completed another fine season with great stats.
 
           63 Home Runs
           0.288 Batting Average
 
-        What a year!"""), """
+        What a year!'''), '''
         >
          Sammy Sosa completed another
          fine season with great stats.
@@ -316,32 +316,32 @@
            63 Home Runs
            0.288 Batting Average
 
-         What a year!""");
+         What a year!''');
     });
 
     test('[Example 2.16]', () {
       expectYamlLoads({
-        "name": "Mark McGwire",
-        "accomplishment": "Mark set a major league home run record in 1998.\n",
-        "stats": "65 Home Runs\n0.278 Batting Average"
-      }, """
+        'name': 'Mark McGwire',
+        'accomplishment': 'Mark set a major league home run record in 1998.\n',
+        'stats': '65 Home Runs\n0.278 Batting Average'
+      }, '''
         name: Mark McGwire
         accomplishment: >
           Mark set a major league
           home run record in 1998.
         stats: |
           65 Home Runs
-          0.278 Batting Average""");
+          0.278 Batting Average''');
     });
 
     test('[Example 2.17]', () {
       expectYamlLoads({
-        "unicode": "Sosa did fine.\u263A",
-        "control": "\b1998\t1999\t2000\n",
-        "hex esc": "\r\n is \r\n",
-        "single": '"Howdy!" he cried.',
-        "quoted": " # Not a 'comment'.",
-        "tie-fighter": "|\\-*-/|"
+        'unicode': 'Sosa did fine.\u263A',
+        'control': '\b1998\t1999\t2000\n',
+        'hex esc': '\r\n is \r\n',
+        'single': '"Howdy!" he cried.',
+        'quoted': " # Not a 'comment'.",
+        'tie-fighter': '|\\-*-/|'
       }, """
         unicode: "Sosa did fine.\\u263A"
         control: "\\b1998\\t1999\\t2000\\n"
@@ -354,8 +354,8 @@
 
     test('[Example 2.18]', () {
       expectYamlLoads({
-        "plain": "This unquoted scalar spans many lines.",
-        "quoted": "So does this quoted scalar.\n"
+        'plain': 'This unquoted scalar spans many lines.',
+        'quoted': 'So does this quoted scalar.\n'
       }, '''
         plain:
           This unquoted scalar
@@ -369,36 +369,36 @@
   group('2.4: Tags', () {
     test('[Example 2.19]', () {
       expectYamlLoads({
-        "canonical": 12345,
-        "decimal": 12345,
-        "octal": 12,
-        "hexadecimal": 12
-      }, """
+        'canonical': 12345,
+        'decimal': 12345,
+        'octal': 12,
+        'hexadecimal': 12
+      }, '''
         canonical: 12345
         decimal: +12345
         octal: 0o14
-        hexadecimal: 0xC""");
+        hexadecimal: 0xC''');
     });
 
     test('[Example 2.20]', () {
       expectYamlLoads({
-        "canonical": 1230.15,
-        "exponential": 1230.15,
-        "fixed": 1230.15,
-        "negative infinity": -infinity,
-        "not a number": nan
-      }, """
+        'canonical': 1230.15,
+        'exponential': 1230.15,
+        'fixed': 1230.15,
+        'negative infinity': -infinity,
+        'not a number': nan
+      }, '''
         canonical: 1.23015e+3
         exponential: 12.3015e+02
         fixed: 1230.15
         negative infinity: -.inf
-        not a number: .NaN""");
+        not a number: .NaN''');
     });
 
     test('[Example 2.21]', () {
       var doc = deepEqualsMap({
-        "booleans": [true, false],
-        "string": "012345"
+        'booleans': [true, false],
+        'string': '012345'
       });
       doc[null] = null;
       expectYamlLoads(doc, """
@@ -418,29 +418,29 @@
     test('[Example 2.28]', () {
       expectYamlStreamLoads([
         {
-          "Time": "2001-11-23 15:01:42 -5",
-          "User": "ed",
-          "Warning": "This is an error message for the log file"
+          'Time': '2001-11-23 15:01:42 -5',
+          'User': 'ed',
+          'Warning': 'This is an error message for the log file'
         },
         {
-          "Time": "2001-11-23 15:02:31 -5",
-          "User": "ed",
-          "Warning": "A slightly different error message."
+          'Time': '2001-11-23 15:02:31 -5',
+          'User': 'ed',
+          'Warning': 'A slightly different error message.'
         },
         {
-          "DateTime": "2001-11-23 15:03:17 -5",
-          "User": "ed",
-          "Fatal": 'Unknown variable "bar"',
-          "Stack": [
+          'DateTime': '2001-11-23 15:03:17 -5',
+          'User': 'ed',
+          'Fatal': 'Unknown variable "bar"',
+          'Stack': [
             {
-              "file": "TopClass.py",
-              "line": 23,
-              "code": 'x = MoreObject("345\\n")\n'
+              'file': 'TopClass.py',
+              'line': 23,
+              'code': 'x = MoreObject("345\\n")\n'
             },
-            {"file": "MoreClass.py", "line": 58, "code": "foo = bar"}
+            {'file': 'MoreClass.py', 'line': 58, 'code': 'foo = bar'}
           ]
         }
-      ], """
+      ], '''
         ---
         Time: 2001-11-23 15:01:42 -5
         User: ed
@@ -466,7 +466,7 @@
           - file: MoreClass.py
             line: 58
             code: |-
-              foo = bar""");
+              foo = bar''');
     });
   });
 
@@ -475,19 +475,19 @@
 
   // Chapter 5: Characters
   group('5.1: Character Set', () {
-    expectAllowsCharacter(int charCode) {
+    void expectAllowsCharacter(int charCode) {
       var char = String.fromCharCodes([charCode]);
       expectYamlLoads('The character "$char" is allowed',
           'The character "$char" is allowed');
     }
 
-    expectAllowsQuotedCharacter(int charCode) {
+    void expectAllowsQuotedCharacter(int charCode) {
       var char = String.fromCharCodes([charCode]);
       expectYamlLoads("The character '$char' is allowed",
           '"The character \'$char\' is allowed"');
     }
 
-    expectDisallowsCharacter(int charCode) {
+    void expectDisallowsCharacter(int charCode) {
       var char = String.fromCharCodes([charCode]);
       expectYamlFails('The character "$char" is disallowed');
     }
@@ -498,7 +498,7 @@
       expectDisallowsCharacter(0x1F);
     });
 
-    test("includes TAB", () => expectAllowsCharacter(0x9));
+    test('includes TAB', () => expectAllowsCharacter(0x9));
     test("doesn't include DEL", () => expectDisallowsCharacter(0x7F));
 
     test("doesn't include C1 control characters", () {
@@ -507,11 +507,11 @@
       expectDisallowsCharacter(0x9F);
     });
 
-    test("includes NEL", () => expectAllowsCharacter(0x85));
+    test('includes NEL', () => expectAllowsCharacter(0x85));
 
-    group("within quoted strings", () {
-      test("includes DEL", () => expectAllowsQuotedCharacter(0x7F));
-      test("includes C1 control characters", () {
+    group('within quoted strings', () {
+      test('includes DEL', () => expectAllowsQuotedCharacter(0x7F));
+      test('includes C1 control characters', () {
         expectAllowsQuotedCharacter(0x80);
         expectAllowsQuotedCharacter(0x8A);
         expectAllowsQuotedCharacter(0x9F);
@@ -528,117 +528,117 @@
       expectYamlLoads({
         'sequence': ['one', 'two'],
         'mapping': {'sky': 'blue', 'sea': 'green'}
-      }, """
+      }, '''
         sequence:
         - one
         - two
         mapping:
           ? sky
           : blue
-          sea : green""");
+          sea : green''');
     });
 
     test('[Example 5.4]', () {
       expectYamlLoads({
         'sequence': ['one', 'two'],
         'mapping': {'sky': 'blue', 'sea': 'green'}
-      }, """
+      }, '''
         sequence: [ one, two, ]
-        mapping: { sky: blue, sea: green }""");
+        mapping: { sky: blue, sea: green }''');
     });
 
-    test('[Example 5.5]', () => expectYamlLoads(null, "# Comment only."));
+    test('[Example 5.5]', () => expectYamlLoads(null, '# Comment only.'));
 
     // Skipping 5.6 because it uses an undefined tag.
 
     test('[Example 5.7]', () {
-      expectYamlLoads({'literal': "some\ntext\n", 'folded': "some text\n"}, """
+      expectYamlLoads({'literal': 'some\ntext\n', 'folded': 'some text\n'}, '''
         literal: |
           some
           text
         folded: >
           some
           text
-        """);
+        ''');
     });
 
     test('[Example 5.8]', () {
-      expectYamlLoads({'single': "text", 'double': "text"}, """
+      expectYamlLoads({'single': 'text', 'double': 'text'}, '''
         single: 'text'
         double: "text"
-        """);
+        ''');
     });
 
     test('[Example 5.9]', () {
-      expectYamlLoads("text", """
+      expectYamlLoads('text', '''
         %YAML 1.2
-        --- text""");
+        --- text''');
     });
 
     test('[Example 5.10]', () {
-      expectYamlFails("commercial-at: @text");
-      expectYamlFails("commercial-at: `text");
+      expectYamlFails('commercial-at: @text');
+      expectYamlFails('commercial-at: `text');
     });
   });
 
   group('5.4: Line Break Characters', () {
     group('include', () {
-      test('\\n', () => expectYamlLoads([1, 2], indentLiteral("- 1\n- 2")));
-      test('\\r', () => expectYamlLoads([1, 2], "- 1\r- 2"));
+      test('\\n', () => expectYamlLoads([1, 2], indentLiteral('- 1\n- 2')));
+      test('\\r', () => expectYamlLoads([1, 2], '- 1\r- 2'));
     });
 
     group('do not include', () {
-      test('form feed', () => expectYamlFails("- 1\x0C- 2"));
-      test('NEL', () => expectYamlLoads(["1\x85- 2"], "- 1\x85- 2"));
-      test('0x2028', () => expectYamlLoads(["1\u2028- 2"], "- 1\u2028- 2"));
-      test('0x2029', () => expectYamlLoads(["1\u2029- 2"], "- 1\u2029- 2"));
+      test('form feed', () => expectYamlFails('- 1\x0C- 2'));
+      test('NEL', () => expectYamlLoads(['1\x85- 2'], '- 1\x85- 2'));
+      test('0x2028', () => expectYamlLoads(['1\u2028- 2'], '- 1\u2028- 2'));
+      test('0x2029', () => expectYamlLoads(['1\u2029- 2'], '- 1\u2029- 2'));
     });
 
     group('in a scalar context must be normalized', () {
       test(
-          "from \\r to \\n",
+          'from \\r to \\n',
           () => expectYamlLoads(
-              ["foo\nbar"], indentLiteral('- |\n  foo\r  bar')));
+              ['foo\nbar'], indentLiteral('- |\n  foo\r  bar')));
       test(
-          "from \\r\\n to \\n",
+          'from \\r\\n to \\n',
           () => expectYamlLoads(
-              ["foo\nbar"], indentLiteral('- |\n  foo\r\n  bar')));
+              ['foo\nbar'], indentLiteral('- |\n  foo\r\n  bar')));
     });
 
     test('[Example 5.11]', () {
-      expectYamlLoads(cleanUpLiteral("""
+      expectYamlLoads(cleanUpLiteral('''
         Line break (no glyph)
-        Line break (glyphed)"""), """
+        Line break (glyphed)'''), '''
         |
           Line break (no glyph)
-          Line break (glyphed)""");
+          Line break (glyphed)''');
     });
   });
 
   group('5.5: White Space Characters', () {
     test('[Example 5.12]', () {
       expectYamlLoads({
-        "quoted": "Quoted \t",
-        "block": 'void main() {\n\tprintf("Hello, world!\\n");\n}\n'
-      }, """
+        'quoted': 'Quoted \t',
+        'block': 'void main() {\n\tprintf("Hello, world!\\n");\n}\n'
+      }, '''
         # Tabs and spaces
         quoted: "Quoted \t"
         block:\t|
           void main() {
           \tprintf("Hello, world!\\n");
           }
-        """);
+        ''');
     });
   });
 
   group('5.7: Escaped Characters', () {
     test('[Example 5.13]', () {
       expectYamlLoads(
-          "Fun with \x5C "
-              "\x22 \x07 \x08 \x1B \x0C "
-              "\x0A \x0D \x09 \x0B \x00 "
-              "\x20 \xA0 \x85 \u2028 \u2029 "
-              "A A A",
+          'Fun with \x5C '
+              '\x22 \x07 \x08 \x1B \x0C '
+              '\x0A \x0D \x09 \x0B \x00 '
+              '\x20 \xA0 \x85 \u2028 \u2029 '
+              'A A A',
           '''
         "Fun with \\\\
         \\" \\a \\b \\e \\f \\
@@ -656,37 +656,37 @@
   // Chapter 6: Basic Structures
   group('6.1: Indentation Spaces', () {
     test('may not include TAB characters', () {
-      expectYamlFails("""
+      expectYamlFails('''
         -
         \t- foo
-        \t- bar""");
+        \t- bar''');
     });
 
     test('must be the same for all sibling nodes', () {
-      expectYamlFails("""
+      expectYamlFails('''
         -
           - foo
-         - bar""");
+         - bar''');
     });
 
     test('may be different for the children of sibling nodes', () {
       expectYamlLoads([
-        ["foo"],
-        ["bar"]
-      ], """
+        ['foo'],
+        ['bar']
+      ], '''
         -
           - foo
         -
-         - bar""");
+         - bar''');
     });
 
     test('[Example 6.1]', () {
       expectYamlLoads({
-        "Not indented": {
-          "By one space": "By four\n  spaces\n",
-          "Flow style": ["By two", "Also by two", "Still by two"]
+        'Not indented': {
+          'By one space': 'By four\n  spaces\n',
+          'Flow style': ['By two', 'Also by two', 'Still by two']
         }
-      }, """
+      }, '''
           # Leading comment line spaces are
            # neither content nor indentation.
             
@@ -698,7 +698,7 @@
            By two,        # in flow style
           Also by two,    # are neither
           \tStill by two   # content nor
-            ]             # indentation.""");
+            ]             # indentation.''');
     });
 
     test('[Example 6.2]', () {
@@ -707,11 +707,11 @@
           'b',
           ['c', 'd']
         ]
-      }, """
+      }, '''
         ? a
         : -\tb
           -  -\tc
-             - d""");
+             - d''');
     });
   });
 
@@ -720,20 +720,20 @@
       expectYamlLoads([
         {'foo': 'bar'},
         ['baz', 'baz']
-      ], """
+      ], '''
         - foo:\t bar
         - - baz
-          -\tbaz""");
+          -\tbaz''');
     });
   });
 
   group('6.3: Line Prefixes', () {
     test('[Example 6.4]', () {
       expectYamlLoads({
-        "plain": "text lines",
-        "quoted": "text lines",
-        "block": "text\n \tlines\n"
-      }, """
+        'plain': 'text lines',
+        'quoted': 'text lines',
+        'block': 'text\n \tlines\n'
+      }, '''
         plain: text
           lines
         quoted: "text
@@ -741,29 +741,29 @@
         block: |
           text
            \tlines
-        """);
+        ''');
     });
   });
 
   group('6.4: Empty Lines', () {
     test('[Example 6.5]', () {
       expectYamlLoads({
-        "Folding": "Empty line\nas a line feed",
-        "Chomping": "Clipped empty lines\n",
-      }, """
+        'Folding': 'Empty line\nas a line feed',
+        'Chomping': 'Clipped empty lines\n',
+      }, '''
         Folding:
           "Empty line
            \t
           as a line feed"
         Chomping: |
           Clipped empty lines
-         """);
+         ''');
     });
   });
 
   group('6.5: Line Folding', () {
     test('[Example 6.6]', () {
-      expectYamlLoads("trimmed\n\n\nas space", """
+      expectYamlLoads('trimmed\n\n\nas space', '''
         >-
           trimmed
           
@@ -771,22 +771,22 @@
 
           as
           space
-        """);
+        ''');
     });
 
     test('[Example 6.7]', () {
-      expectYamlLoads("foo \n\n\t bar\n\nbaz\n", """
+      expectYamlLoads('foo \n\n\t bar\n\nbaz\n', '''
         >
           foo 
          
           \t bar
 
           baz
-        """);
+        ''');
     });
 
     test('[Example 6.8]', () {
-      expectYamlLoads(" foo\nbar\nbaz ", '''
+      expectYamlLoads(' foo\nbar\nbaz ', '''
         "
           foo 
          
@@ -799,113 +799,113 @@
 
   group('6.6: Comments', () {
     test('must be separated from other tokens by white space characters', () {
-      expectYamlLoads("foo#bar", "foo#bar");
-      expectYamlLoads("foo:#bar", "foo:#bar");
-      expectYamlLoads("-#bar", "-#bar");
+      expectYamlLoads('foo#bar', 'foo#bar');
+      expectYamlLoads('foo:#bar', 'foo:#bar');
+      expectYamlLoads('-#bar', '-#bar');
     });
 
     test('[Example 6.9]', () {
-      expectYamlLoads({'key': 'value'}, """
+      expectYamlLoads({'key': 'value'}, '''
         key:    # Comment
-          value""");
+          value''');
     });
 
     group('outside of scalar content', () {
       test('may appear on a line of their own', () {
-        expectYamlLoads([1, 2], """
+        expectYamlLoads([1, 2], '''
         - 1
         # Comment
-        - 2""");
+        - 2''');
       });
 
       test('are independent of indentation level', () {
         expectYamlLoads([
           [1, 2]
-        ], """
+        ], '''
         -
           - 1
          # Comment
-          - 2""");
+          - 2''');
       });
 
       test('include lines containing only white space characters', () {
-        expectYamlLoads([1, 2], """
+        expectYamlLoads([1, 2], '''
         - 1
           \t  
-        - 2""");
+        - 2''');
       });
     });
 
     group('within scalar content', () {
       test('may not appear on a line of their own', () {
-        expectYamlLoads(["foo\n# not comment\nbar\n"], """
+        expectYamlLoads(['foo\n# not comment\nbar\n'], '''
         - |
           foo
           # not comment
           bar
-        """);
+        ''');
       });
 
       test("don't include lines containing only white space characters", () {
-        expectYamlLoads(["foo\n  \t   \nbar\n"], """
+        expectYamlLoads(['foo\n  \t   \nbar\n'], '''
         - |
           foo
             \t   
           bar
-        """);
+        ''');
       });
     });
 
     test('[Example 6.10]', () {
-      expectYamlLoads(null, """
+      expectYamlLoads(null, '''
           # Comment
            
-        """);
+        ''');
     });
 
     test('[Example 6.11]', () {
-      expectYamlLoads({'key': 'value'}, """
+      expectYamlLoads({'key': 'value'}, '''
         key:    # Comment
                 # lines
           value
-        """);
+        ''');
     });
 
     group('ending a block scalar header', () {
       test('may not be followed by additional comment lines', () {
-        expectYamlLoads(["# not comment\nfoo\n"], """
+        expectYamlLoads(['# not comment\nfoo\n'], '''
         - | # comment
             # not comment
             foo
-        """);
+        ''');
       });
     });
   });
 
   group('6.7: Separation Lines', () {
     test('may not be used within implicit keys', () {
-      expectYamlFails("""
+      expectYamlFails('''
         [1,
-         2]: 3""");
+         2]: 3''');
     });
 
     test('[Example 6.12]', () {
       var doc = deepEqualsMap();
       doc[{'first': 'Sammy', 'last': 'Sosa'}] = {'hr': 65, 'avg': 0.278};
-      expectYamlLoads(doc, """
+      expectYamlLoads(doc, '''
         { first: Sammy, last: Sosa }:
         # Statistics:
           hr:  # Home runs
              65
           avg: # Average
-           0.278""");
+           0.278''');
     });
   });
 
   group('6.8: Directives', () {
     // TODO(nweiz): assert that this produces a warning
     test('[Example 6.13]', () {
-      expectYamlLoads("foo", '''
+      expectYamlLoads('foo', '''
         %FOO  bar baz # Should be ignored
                       # with a warning.
         --- "foo"''');
@@ -913,7 +913,7 @@
 
     // TODO(nweiz): assert that this produces a warning.
     test('[Example 6.14]', () {
-      expectYamlLoads("foo", '''
+      expectYamlLoads('foo', '''
         %YAML 1.3 # Attempt parsing
                    # with a warning
         ---
@@ -921,24 +921,24 @@
     });
 
     test('[Example 6.15]', () {
-      expectYamlFails("""
+      expectYamlFails('''
         %YAML 1.2
         %YAML 1.1
-        foo""");
+        foo''');
     });
 
     test('[Example 6.16]', () {
-      expectYamlLoads("foo", '''
+      expectYamlLoads('foo', '''
         %TAG !yaml! tag:yaml.org,2002:
         ---
         !yaml!str "foo"''');
     });
 
     test('[Example 6.17]', () {
-      expectYamlFails("""
+      expectYamlFails('''
         %TAG ! !foo
         %TAG ! !foo
-        bar""");
+        bar''');
     });
 
     // Examples 6.18 through 6.22 test custom tag URIs, which this
@@ -947,13 +947,13 @@
 
   group('6.9: Node Properties', () {
     test('may be specified in any order', () {
-      expectYamlLoads(["foo", "bar"], """
+      expectYamlLoads(['foo', 'bar'], '''
         - !!str &a1 foo
-        - &a2 !!str bar""");
+        - &a2 !!str bar''');
     });
 
     test('[Example 6.23]', () {
-      expectYamlLoads({"foo": "bar", "baz": "foo"}, '''
+      expectYamlLoads({'foo': 'bar', 'baz': 'foo'}, '''
         !!str &a1 "foo":
           !!str bar
         &a2 baz : *a1''');
@@ -963,15 +963,15 @@
     // doesn't plan to support.
 
     test('[Example 6.25]', () {
-      expectYamlFails("- !<!> foo");
-      expectYamlFails("- !<\$:?> foo");
+      expectYamlFails('- !<!> foo');
+      expectYamlFails('- !<\$:?> foo');
     });
 
     // Examples 6.26 and 6.27 test custom tag URIs, which this implementation
     // currently doesn't plan to support.
 
     test('[Example 6.28]', () {
-      expectYamlLoads(["12", 12, "12"], '''
+      expectYamlLoads(['12', 12, '12'], '''
         # Assuming conventional resolution:
         - "12"
         - 12
@@ -980,50 +980,50 @@
 
     test('[Example 6.29]', () {
       expectYamlLoads(
-          {"First occurrence": "Value", "Second occurrence": "Value"}, """
+          {'First occurrence': 'Value', 'Second occurrence': 'Value'}, '''
         First occurrence: &anchor Value
-        Second occurrence: *anchor""");
+        Second occurrence: *anchor''');
     });
   });
 
   // Chapter 7: Flow Styles
   group('7.1: Alias Nodes', () {
     test("must not use an anchor that doesn't previously occur", () {
-      expectYamlFails("""
+      expectYamlFails('''
         - *anchor
-        - &anchor foo""");
+        - &anchor foo''');
     });
 
     test("don't have to exist for a given anchor node", () {
-      expectYamlLoads(["foo"], "- &anchor foo");
+      expectYamlLoads(['foo'], '- &anchor foo');
     });
 
     group('must not specify', () {
-      test('tag properties', () => expectYamlFails("""
+      test('tag properties', () => expectYamlFails('''
         - &anchor foo
-        - !str *anchor"""));
+        - !str *anchor'''));
 
-      test('anchor properties', () => expectYamlFails("""
+      test('anchor properties', () => expectYamlFails('''
         - &anchor foo
-        - &anchor2 *anchor"""));
+        - &anchor2 *anchor'''));
 
-      test('content', () => expectYamlFails("""
+      test('content', () => expectYamlFails('''
         - &anchor foo
-        - *anchor bar"""));
+        - *anchor bar'''));
     });
 
     test('must preserve structural equality', () {
-      var doc = loadYaml(cleanUpLiteral("""
+      var doc = loadYaml(cleanUpLiteral('''
         anchor: &anchor [a, b, c]
-        alias: *anchor"""));
+        alias: *anchor'''));
       var anchorList = doc['anchor'];
       var aliasList = doc['alias'];
       expect(anchorList, same(aliasList));
 
-      doc = loadYaml(cleanUpLiteral("""
+      doc = loadYaml(cleanUpLiteral('''
         ? &anchor [a, b, c]
         : ? *anchor
-          : bar"""));
+          : bar'''));
       anchorList = doc.keys.first;
       aliasList = doc[['a', 'b', 'c']].keys.first;
       expect(anchorList, same(aliasList));
@@ -1031,43 +1031,43 @@
 
     test('[Example 7.1]', () {
       expectYamlLoads({
-        "First occurrence": "Foo",
-        "Second occurrence": "Foo",
-        "Override anchor": "Bar",
-        "Reuse anchor": "Bar",
-      }, """
+        'First occurrence': 'Foo',
+        'Second occurrence': 'Foo',
+        'Override anchor': 'Bar',
+        'Reuse anchor': 'Bar',
+      }, '''
         First occurrence: &anchor Foo
         Second occurrence: *anchor
         Override anchor: &anchor Bar
-        Reuse anchor: *anchor""");
+        Reuse anchor: *anchor''');
     });
   });
 
   group('7.2: Empty Nodes', () {
     test('[Example 7.2]', () {
-      expectYamlLoads({"foo": "", "": "bar"}, """
+      expectYamlLoads({'foo': '', '': 'bar'}, '''
         {
           foo : !!str,
           !!str : bar,
-        }""");
+        }''');
     });
 
     test('[Example 7.3]', () {
-      var doc = deepEqualsMap({"foo": null});
-      doc[null] = "bar";
-      expectYamlLoads(doc, """
+      var doc = deepEqualsMap({'foo': null});
+      doc[null] = 'bar';
+      expectYamlLoads(doc, '''
         {
           ? foo :,
           : bar,
-        }""");
+        }''');
     });
   });
 
   group('7.3: Flow Scalar Styles', () {
     test('[Example 7.4]', () {
       expectYamlLoads({
-        "implicit block key": [
-          {"implicit flow key": "value"}
+        'implicit block key': [
+          {'implicit flow key': 'value'}
         ]
       }, '''
         "implicit block key" : [
@@ -1077,7 +1077,7 @@
 
     test('[Example 7.5]', () {
       expectYamlLoads(
-          "folded to a space,\nto a line feed, or \t \tnon-content", '''
+          'folded to a space,\nto a line feed, or \t \tnon-content', '''
         "folded 
         to a space,\t
          
@@ -1086,7 +1086,7 @@
     });
 
     test('[Example 7.6]', () {
-      expectYamlLoads(" 1st non-empty\n2nd non-empty 3rd non-empty ", '''
+      expectYamlLoads(' 1st non-empty\n2nd non-empty 3rd non-empty ', '''
         " 1st non-empty
 
          2nd non-empty 
@@ -1099,8 +1099,8 @@
 
     test('[Example 7.8]', () {
       expectYamlLoads({
-        "implicit block key": [
-          {"implicit flow key": "value"}
+        'implicit block key': [
+          {'implicit flow key': 'value'}
         ]
       }, """
         'implicit block key' : [
@@ -1109,7 +1109,7 @@
     });
 
     test('[Example 7.9]', () {
-      expectYamlLoads(" 1st non-empty\n2nd non-empty 3rd non-empty ", """
+      expectYamlLoads(' 1st non-empty\n2nd non-empty 3rd non-empty ', """
         ' 1st non-empty
 
          2nd non-empty 
@@ -1118,17 +1118,17 @@
 
     test('[Example 7.10]', () {
       expectYamlLoads([
-        "::vector",
-        ": - ()",
-        "Up, up, and away!",
+        '::vector',
+        ': - ()',
+        'Up, up, and away!',
         -123,
-        "http://example.com/foo#bar",
+        'http://example.com/foo#bar',
         [
-          "::vector",
-          ": - ()",
-          "Up, up, and away!",
+          '::vector',
+          ': - ()',
+          'Up, up, and away!',
           -123,
-          "http://example.com/foo#bar"
+          'http://example.com/foo#bar'
         ]
       ], '''
         # Outside flow collection:
@@ -1147,21 +1147,21 @@
 
     test('[Example 7.11]', () {
       expectYamlLoads({
-        "implicit block key": [
-          {"implicit flow key": "value"}
+        'implicit block key': [
+          {'implicit flow key': 'value'}
         ]
-      }, """
+      }, '''
         implicit block key : [
           implicit flow key : value,
-         ]""");
+         ]''');
     });
 
     test('[Example 7.12]', () {
-      expectYamlLoads("1st non-empty\n2nd non-empty 3rd non-empty", """
+      expectYamlLoads('1st non-empty\n2nd non-empty 3rd non-empty', '''
         1st non-empty
 
          2nd non-empty 
-        \t3rd non-empty""");
+        \t3rd non-empty''');
     });
   });
 
@@ -1170,18 +1170,18 @@
       expectYamlLoads([
         ['one', 'two'],
         ['three', 'four']
-      ], """
+      ], '''
         - [ one, two, ]
-        - [three ,four]""");
+        - [three ,four]''');
     });
 
     test('[Example 7.14]', () {
       expectYamlLoads([
-        "double quoted",
-        "single quoted",
-        "plain text",
-        ["nested"],
-        {"single": "pair"}
+        'double quoted',
+        'single quoted',
+        'plain text',
+        ['nested'],
+        {'single': 'pair'}
       ], """
         [
         "double
@@ -1195,31 +1195,31 @@
 
     test('[Example 7.15]', () {
       expectYamlLoads([
-        {"one": "two", "three": "four"},
-        {"five": "six", "seven": "eight"},
-      ], """
+        {'one': 'two', 'three': 'four'},
+        {'five': 'six', 'seven': 'eight'},
+      ], '''
         - { one : two , three: four , }
-        - {five: six,seven : eight}""");
+        - {five: six,seven : eight}''');
     });
 
     test('[Example 7.16]', () {
-      var doc = deepEqualsMap({"explicit": "entry", "implicit": "entry"});
+      var doc = deepEqualsMap({'explicit': 'entry', 'implicit': 'entry'});
       doc[null] = null;
-      expectYamlLoads(doc, """
+      expectYamlLoads(doc, '''
         {
         ? explicit: entry,
         implicit: entry,
         ?
-        }""");
+        }''');
     });
 
     test('[Example 7.17]', () {
       var doc = deepEqualsMap({
-        "unquoted": "separate",
-        "http://foo.com": null,
-        "omitted value": null
+        'unquoted': 'separate',
+        'http://foo.com': null,
+        'omitted value': null
       });
-      doc[null] = "omitted key";
+      doc[null] = 'omitted key';
       expectYamlLoads(doc, '''
         {
         unquoted : "separate",
@@ -1231,7 +1231,7 @@
 
     test('[Example 7.18]', () {
       expectYamlLoads(
-          {"adjacent": "value", "readable": "value", "empty": null}, '''
+          {'adjacent': 'value', 'readable': 'value', 'empty': null}, '''
         {
         "adjacent":value,
         "readable": value,
@@ -1241,40 +1241,40 @@
 
     test('[Example 7.19]', () {
       expectYamlLoads([
-        {"foo": "bar"}
-      ], """
+        {'foo': 'bar'}
+      ], '''
         [
         foo: bar
-        ]""");
+        ]''');
     });
 
     test('[Example 7.20]', () {
       expectYamlLoads([
-        {"foo bar": "baz"}
-      ], """
+        {'foo bar': 'baz'}
+      ], '''
         [
         ? foo
          bar : baz
-        ]""");
+        ]''');
     });
 
     test('[Example 7.21]', () {
       var el1 = deepEqualsMap();
-      el1[null] = "empty key entry";
+      el1[null] = 'empty key entry';
 
       var el2 = deepEqualsMap();
-      el2[{"JSON": "like"}] = "adjacent";
+      el2[{'JSON': 'like'}] = 'adjacent';
 
       expectYamlLoads([
         [
-          {"YAML": "separate"}
+          {'YAML': 'separate'}
         ],
         [el1],
         [el2]
-      ], """
+      ], '''
         - [ YAML : separate ]
         - [ : empty key entry ]
-        - [ {JSON: like}:adjacent ]""");
+        - [ {JSON: like}:adjacent ]''');
     });
 
     // TODO(nweiz): enable this when we throw an error for long or multiline
@@ -1294,33 +1294,33 @@
   group('7.5: Flow Nodes', () {
     test('[Example 7.23]', () {
       expectYamlLoads([
-        ["a", "b"],
-        {"a": "b"},
-        "a",
-        "b",
-        "c"
-      ], """
+        ['a', 'b'],
+        {'a': 'b'},
+        'a',
+        'b',
+        'c'
+      ], '''
         - [ a, b ]
         - { a: b }
-        - "a"
+        - 'a'
         - 'b'
-        - c""");
+        - c''');
     });
 
     test('[Example 7.24]', () {
-      expectYamlLoads(["a", "b", "c", "c", ""], """
+      expectYamlLoads(['a', 'b', 'c', 'c', ''], '''
         - !!str "a"
         - 'b'
         - &anchor "c"
         - *anchor
-        - !!str""");
+        - !!str''');
     });
   });
 
   // Chapter 8: Block Styles
   group('8.1: Block Scalar Styles', () {
     test('[Example 8.1]', () {
-      expectYamlLoads(["literal\n", " folded\n", "keep\n\n", " strip"], """
+      expectYamlLoads(['literal\n', ' folded\n', 'keep\n\n', ' strip'], '''
         - | # Empty header
          literal
         - >1 # Indentation indicator
@@ -1329,7 +1329,7 @@
          keep
 
         - >1- # Both indicators
-          strip""");
+          strip''');
     });
 
     test('[Example 8.2]', () {
@@ -1338,47 +1338,47 @@
       // confident that "\t\ndetected\n" is correct when parsed according to the
       // rest of the spec.
       expectYamlLoads(
-          ["detected\n", "\n\n# detected\n", " explicit\n", "\t\ndetected\n"],
-          """
+          ['detected\n', '\n\n# detected\n', ' explicit\n', '\t\ndetected\n'],
+          '''
         - |
          detected
         - >
-         
-          
+
+
           # detected
         - |1
           explicit
         - >
          \t
          detected
-        """);
+        ''');
     });
 
     test('[Example 8.3]', () {
-      expectYamlFails("""
+      expectYamlFails('''
         - |
           
-         text""");
+         text''');
 
-      expectYamlFails("""
+      expectYamlFails('''
         - >
           text
-         text""");
+         text''');
 
-      expectYamlFails("""
+      expectYamlFails('''
         - |2
-         text""");
+         text''');
     });
 
     test('[Example 8.4]', () {
-      expectYamlLoads({"strip": "text", "clip": "text\n", "keep": "text\n"}, """
+      expectYamlLoads({'strip': 'text', 'clip': 'text\n', 'keep': 'text\n'}, '''
         strip: |-
           text
         clip: |
           text
         keep: |+
           text
-        """);
+        ''');
     });
 
     test('[Example 8.5]', () {
@@ -1386,7 +1386,7 @@
       // value, but as far as I can tell that's not how it's supposed to be
       // parsed according to the rest of the spec.
       expectYamlLoads(
-          {"strip": "# text", "clip": "# text\n", "keep": "# text\n\n"}, """
+          {'strip': '# text', 'clip': '# text\n', 'keep': '# text\n\n'}, '''
          # Strip
           # Comments:
         strip: |-
@@ -1406,30 +1406,30 @@
 
          # Trail
           # comments.
-        """);
+        ''');
     });
 
     test('[Example 8.6]', () {
-      expectYamlLoads({"strip": "", "clip": "", "keep": "\n"}, """
+      expectYamlLoads({'strip': '', 'clip': '', 'keep': '\n'}, '''
         strip: >-
 
         clip: >
 
         keep: |+
 
-        """);
+        ''');
     });
 
     test('[Example 8.7]', () {
-      expectYamlLoads("literal\n\ttext\n", """
+      expectYamlLoads('literal\n\ttext\n', '''
         |
          literal
          \ttext
-        """);
+        ''');
     });
 
     test('[Example 8.8]', () {
-      expectYamlLoads("\n\nliteral\n \n\ntext\n", """
+      expectYamlLoads('\n\nliteral\n \n\ntext\n', '''
         |
          
           
@@ -1438,19 +1438,19 @@
           
           text
 
-         # Comment""");
+         # Comment''');
     });
 
     test('[Example 8.9]', () {
-      expectYamlLoads("folded text\n", """
+      expectYamlLoads('folded text\n', '''
         >
          folded
          text
-        """);
+        ''');
     });
 
     test('[Example 8.10]', () {
-      expectYamlLoads(cleanUpLiteral("""
+      expectYamlLoads(cleanUpLiteral('''
 
         folded line
         next line
@@ -1460,7 +1460,7 @@
           * lines
 
         last line
-        """), """
+        '''), '''
         >
 
          folded
@@ -1476,7 +1476,7 @@
          last
          line
 
-        # Comment""");
+        # Comment''');
     });
 
     // Examples 8.11 through 8.13 are duplicates of 8.10.
@@ -1485,55 +1485,55 @@
   group('8.2: Block Collection Styles', () {
     test('[Example 8.14]', () {
       expectYamlLoads({
-        "block sequence": [
-          "one",
-          {"two": "three"}
+        'block sequence': [
+          'one',
+          {'two': 'three'}
         ]
-      }, """
+      }, '''
         block sequence:
           - one
-          - two : three""");
+          - two : three''');
     });
 
     test('[Example 8.15]', () {
       expectYamlLoads([
         null,
-        "block node\n",
-        ["one", "two"],
-        {"one": "two"}
-      ], """
+        'block node\n',
+        ['one', 'two'],
+        {'one': 'two'}
+      ], '''
         - # Empty
         - |
          block node
         - - one # Compact
           - two # sequence
-        - one: two # Compact mapping""");
+        - one: two # Compact mapping''');
     });
 
     test('[Example 8.16]', () {
       expectYamlLoads({
-        "block mapping": {"key": "value"}
-      }, """
+        'block mapping': {'key': 'value'}
+      }, '''
         block mapping:
-         key: value""");
+         key: value''');
     });
 
     test('[Example 8.17]', () {
       expectYamlLoads({
-        "explicit key": null,
-        "block key\n": ["one", "two"]
-      }, """
+        'explicit key': null,
+        'block key\n': ['one', 'two']
+      }, '''
         ? explicit key # Empty value
         ? |
           block key
         : - one # Explicit compact
-          - two # block value""");
+          - two # block value''');
     });
 
     test('[Example 8.18]', () {
       var doc = deepEqualsMap({
         'plain key': 'in-line value',
-        "quoted key": ["entry"]
+        'quoted key': ['entry']
       });
       doc[null] = null;
       expectYamlLoads(doc, '''
@@ -1549,17 +1549,17 @@
       expectYamlLoads([
         {'sun': 'yellow'},
         el
-      ], """
+      ], '''
         - sun: yellow
         - ? earth: blue
-          : moon: white""");
+          : moon: white''');
     });
 
     test('[Example 8.20]', () {
       expectYamlLoads([
-        "flow in block",
-        "Block scalar\n",
-        {"foo": "bar"}
+        'flow in block',
+        'Block scalar\n',
+        {'foo': 'bar'}
       ], '''
         -
           "flow in block"
@@ -1572,29 +1572,29 @@
     test('[Example 8.21]', () {
       // The spec doesn't include a newline after "value" in the parsed map, but
       // the block scalar is clipped so it should be retained.
-      expectYamlLoads({"literal": "value\n", "folded": "value"}, """
+      expectYamlLoads({'literal': 'value\n', 'folded': 'value'}, '''
         literal: |2
           value
         folded:
            !!str
           >1
-         value""");
+         value''');
     });
 
     test('[Example 8.22]', () {
       expectYamlLoads({
-        "sequence": [
-          "entry",
-          ["nested"]
+        'sequence': [
+          'entry',
+          ['nested']
         ],
-        "mapping": {"foo": "bar"}
-      }, """
+        'mapping': {'foo': 'bar'}
+      }, '''
         sequence: !!seq
         - entry
         - !!seq
          - nested
         mapping: !!map
-         foo: bar""");
+         foo: bar''');
     });
   });
 
@@ -1604,11 +1604,11 @@
     // doesn't plan to support.
 
     test('[Example 9.2]', () {
-      expectYamlLoads("Document", """
+      expectYamlLoads('Document', '''
         %YAML 1.2
         ---
         Document
-        ... # Suffix""");
+        ... # Suffix''');
     });
 
     test('[Example 9.3]', () {
@@ -1620,7 +1620,7 @@
       // indented the same amount, the text would be part of the literal, which
       // implies that the spec's parse of this document is incorrect.
       expectYamlStreamLoads(
-          ["Bare document", "%!PS-Adobe-2.0 # Not the first line\n"], """
+          ['Bare document', '%!PS-Adobe-2.0 # Not the first line\n'], '''
         Bare
         document
         ...
@@ -1628,27 +1628,27 @@
         ...
         |
         %!PS-Adobe-2.0 # Not the first line
-        """);
+        ''');
     });
 
     test('[Example 9.4]', () {
       expectYamlStreamLoads([
-        {"matches %": 20},
+        {'matches %': 20},
         null
-      ], """
+      ], '''
         ---
         { matches
         % : 20 }
         ...
         ---
         # Empty
-        ...""");
+        ...''');
     });
 
     test('[Example 9.5]', () {
       // The spec doesn't have a space between the second
       // "YAML" and "1.2", but this seems to be a typo.
-      expectYamlStreamLoads(["%!PS-Adobe-2.0\n", null], """
+      expectYamlStreamLoads(['%!PS-Adobe-2.0\n', null], '''
         %YAML 1.2
         --- |
         %!PS-Adobe-2.0
@@ -1656,22 +1656,22 @@
         %YAML 1.2
         ---
         # Empty
-        ...""");
+        ...''');
     });
 
     test('[Example 9.6]', () {
       expectYamlStreamLoads([
-        "Document",
+        'Document',
         null,
-        {"matches %": 20}
-      ], """
+        {'matches %': 20}
+      ], '''
         Document
         ---
         # Empty
         ...
         %YAML 1.2
         ---
-        matches %: 20""");
+        matches %: 20''');
     });
   });
 
@@ -1679,38 +1679,38 @@
   group('10.1: Failsafe Schema', () {
     test('[Example 10.1]', () {
       expectYamlLoads({
-        "Block style": {
-          "Clark": "Evans",
-          "Ingy": "döt Net",
-          "Oren": "Ben-Kiki"
+        'Block style': {
+          'Clark': 'Evans',
+          'Ingy': 'döt Net',
+          'Oren': 'Ben-Kiki'
         },
-        "Flow style": {"Clark": "Evans", "Ingy": "döt Net", "Oren": "Ben-Kiki"}
-      }, """
+        'Flow style': {'Clark': 'Evans', 'Ingy': 'döt Net', 'Oren': 'Ben-Kiki'}
+      }, '''
         Block style: !!map
           Clark : Evans
           Ingy  : döt Net
           Oren  : Ben-Kiki
 
-        Flow style: !!map { Clark: Evans, Ingy: döt Net, Oren: Ben-Kiki }""");
+        Flow style: !!map { Clark: Evans, Ingy: döt Net, Oren: Ben-Kiki }''');
     });
 
     test('[Example 10.2]', () {
       expectYamlLoads({
-        "Block style": ["Clark Evans", "Ingy döt Net", "Oren Ben-Kiki"],
-        "Flow style": ["Clark Evans", "Ingy döt Net", "Oren Ben-Kiki"]
-      }, """
+        'Block style': ['Clark Evans', 'Ingy döt Net', 'Oren Ben-Kiki'],
+        'Flow style': ['Clark Evans', 'Ingy döt Net', 'Oren Ben-Kiki']
+      }, '''
         Block style: !!seq
         - Clark Evans
         - Ingy döt Net
         - Oren Ben-Kiki
 
-        Flow style: !!seq [ Clark Evans, Ingy döt Net, Oren Ben-Kiki ]""");
+        Flow style: !!seq [ Clark Evans, Ingy döt Net, Oren Ben-Kiki ]''');
     });
 
     test('[Example 10.3]', () {
       expectYamlLoads({
-        "Block style": "String: just a theory.",
-        "Flow style": "String: just a theory."
+        'Block style': 'String: just a theory.',
+        'Flow style': 'String: just a theory.'
       }, '''
         Block style: !!str |-
           String: just a theory.
@@ -1789,13 +1789,13 @@
   group('10.3: Core Schema', () {
     test('[Example 10.9]', () {
       expectYamlLoads({
-        "A null": null,
-        "Also a null": null,
-        "Not a null": "",
-        "Booleans": [true, true, false, false],
-        "Integers": [0, 7, 0x3A, -19],
-        "Floats": [0, 0, 0.5, 12000, -200000],
-        "Also floats": [infinity, -infinity, infinity, nan]
+        'A null': null,
+        'Also a null': null,
+        'Not a null': '',
+        'Booleans': [true, true, false, false],
+        'Integers': [0, 7, 0x3A, -19],
+        'Floats': [0, 0, 0.5, 12000, -200000],
+        'Also floats': [infinity, -infinity, infinity, nan]
       }, '''
         A null: null
         Also a null: # Empty
@@ -1809,8 +1809,8 @@
 
   test('preserves key order', () {
     const keys = ['a', 'b', 'c', 'd', 'e', 'f'];
-    int sanityCheckCount = 0;
-    for (List<String> permutation in _generatePermutations(keys)) {
+    var sanityCheckCount = 0;
+    for (var permutation in _generatePermutations(keys)) {
       final yaml = permutation.map((key) => '$key: value').join('\n');
       expect(loadYaml(yaml).keys.toList(), permutation);
       sanityCheckCount++;
@@ -1826,13 +1826,11 @@
     yield keys;
     return;
   }
-  for (int i = 0; i < keys.length; i++) {
+  for (var i = 0; i < keys.length; i++) {
     final first = keys[i];
-    final rest = <String>[]
-      ..addAll(keys.sublist(0, i))
-      ..addAll(keys.sublist(i + 1));
-    for (List<String> subPermutation in _generatePermutations(rest)) {
-      yield <String>[first]..addAll(subPermutation);
+    final rest = <String>[...keys.sublist(0, i), ...keys.sublist(i + 1)];
+    for (var subPermutation in _generatePermutations(rest)) {
+      yield <String>[first, ...subPermutation];
     }
   }
 }