Restructure the yaml package.

Review URL: https://codereview.chromium.org//14103026

git-svn-id: https://dart.googlecode.com/svn/branches/bleeding_edge/dart/pkg/yaml@21571 260f80e4-7a28-3924-810f-c04153c831b5
diff --git a/lib/composer.dart b/lib/src/composer.dart
similarity index 71%
rename from lib/composer.dart
rename to lib/src/composer.dart
index 90ed330..40b7667 100644
--- a/lib/composer.dart
+++ b/lib/src/composer.dart
@@ -2,41 +2,45 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-part of yaml;
+library composer;
+
+import 'model.dart';
+import 'visitor.dart';
+import 'yaml_exception.dart';
 
 /// Takes a parsed YAML document (what the spec calls the "serialization tree")
 /// and resolves aliases, resolves tags, and parses scalars to produce the
 /// "representation graph".
-class _Composer extends _Visitor {
+class Composer extends Visitor {
   /// The root node of the serialization tree.
-  _Node root;
+  final Node _root;
 
   /// Map from anchor names to the most recent representation graph node with
   /// that anchor.
-  Map<String, _Node> anchors;
+  final _anchors = <String, Node>{};
 
   /// The next id to use for the represenation graph's anchors. The spec doesn't
   /// use anchors in the representation graph, but we do so that the constructor
   /// can ensure that the same node in the representation graph produces the
   /// same native object.
-  int idCounter;
+  var _idCounter = 0;
 
-  _Composer(this.root) : this.anchors = <String, _Node>{}, this.idCounter = 0;
+  Composer(this._root);
 
   /// Runs the Composer to produce a representation graph.
-  _Node compose() => root.visit(this);
+  Node compose() => _root.visit(this);
 
   /// Returns the anchor to which an alias node refers.
-  _Node visitAlias(_AliasNode alias) {
-    if (!anchors.containsKey(alias.anchor)) {
+  Node visitAlias(AliasNode alias) {
+    if (!_anchors.containsKey(alias.anchor)) {
       throw new YamlException("no anchor for alias ${alias.anchor}");
     }
-    return anchors[alias.anchor];
+    return _anchors[alias.anchor];
   }
 
   /// Parses a scalar node according to its tag, or auto-detects the type if no
   /// tag exists. Currently this only supports the YAML core type schema.
-  _Node visitScalar(_ScalarNode scalar) {
+  Node visitScalar(ScalarNode scalar) {
     if (scalar.tag.name == "!") {
       return setAnchor(scalar, parseString(scalar.content));
     } else if (scalar.tag.name == "?") {
@@ -54,7 +58,7 @@
     };
 
     for (var key in tagParsers.keys) {
-      if (scalar.tag.name != _Tag.yaml(key)) continue;
+      if (scalar.tag.name != Tag.yaml(key)) continue;
       var result = tagParsers[key](scalar.content);
       if (result != null) return setAnchor(scalar, result);
       throw new YamlException('invalid literal for $key: "${scalar.content}"');
@@ -64,69 +68,69 @@
   }
 
   /// Assigns a tag to the sequence and recursively composes its contents.
-  _Node visitSequence(_SequenceNode seq) {
+  Node visitSequence(SequenceNode seq) {
     var tagName = seq.tag.name;
-    if (tagName != "!" && tagName != "?" && tagName != _Tag.yaml("seq")) {
+    if (tagName != "!" && tagName != "?" && tagName != Tag.yaml("seq")) {
       throw new YamlException("invalid tag for sequence: ${tagName}");
     }
 
-    var result = setAnchor(seq, new _SequenceNode(_Tag.yaml("seq"), null));
+    var result = setAnchor(seq, new SequenceNode(Tag.yaml("seq"), null));
     result.content = super.visitSequence(seq);
     return result;
   }
 
   /// Assigns a tag to the mapping and recursively composes its contents.
-  _Node visitMapping(_MappingNode map) {
+  Node visitMapping(MappingNode map) {
     var tagName = map.tag.name;
-    if (tagName != "!" && tagName != "?" && tagName != _Tag.yaml("map")) {
+    if (tagName != "!" && tagName != "?" && tagName != Tag.yaml("map")) {
       throw new YamlException("invalid tag for mapping: ${tagName}");
     }
 
-    var result = setAnchor(map, new _MappingNode(_Tag.yaml("map"), null));
+    var result = setAnchor(map, new MappingNode(Tag.yaml("map"), null));
     result.content = super.visitMapping(map);
     return result;
   }
 
   /// If the serialization tree node [anchored] has an anchor, records that
   /// that anchor is pointing to the representation graph node [result].
-  _Node setAnchor(_Node anchored, _Node result) {
+  Node setAnchor(Node anchored, Node result) {
     if (anchored.anchor == null) return result;
-    result.anchor = '${idCounter++}';
-    anchors[anchored.anchor] = result;
+    result.anchor = '${_idCounter++}';
+    _anchors[anchored.anchor] = result;
     return result;
   }
 
   /// Parses a null scalar.
-  _ScalarNode parseNull(String content) {
+  ScalarNode parseNull(String content) {
     if (!new RegExp(r"^(null|Null|NULL|~|)$").hasMatch(content)) return null;
-    return new _ScalarNode(_Tag.yaml("null"), value: null);
+    return new ScalarNode(Tag.yaml("null"), value: null);
   }
 
   /// Parses a boolean scalar.
-  _ScalarNode parseBool(String content) {
+  ScalarNode parseBool(String content) {
     var match = new RegExp(r"^(?:(true|True|TRUE)|(false|False|FALSE))$").
       firstMatch(content);
     if (match == null) return null;
-    return new _ScalarNode(_Tag.yaml("bool"), value: match.group(1) != null);
+    return new ScalarNode(Tag.yaml("bool"), value: match.group(1) != null);
   }
 
   /// Parses an integer scalar.
-  _ScalarNode parseInt(String content) {
+  ScalarNode parseInt(String content) {
     var match = new RegExp(r"^[-+]?[0-9]+$").firstMatch(content);
     if (match != null) {
-      return new _ScalarNode(_Tag.yaml("int"),
+      return new ScalarNode(Tag.yaml("int"),
           value: int.parse(match.group(0)));
     }
 
     match = new RegExp(r"^0o([0-7]+)$").firstMatch(content);
     if (match != null) {
       int n = int.parse(match.group(1), radix: 8);
-      return new _ScalarNode(_Tag.yaml("int"), value: n);
+      return new ScalarNode(Tag.yaml("int"), value: n);
     }
 
     match = new RegExp(r"^0x[0-9a-fA-F]+$").firstMatch(content);
     if (match != null) {
-      return new _ScalarNode(_Tag.yaml("int"),
+      return new ScalarNode(Tag.yaml("int"),
           value: int.parse(match.group(0)));
     }
 
@@ -134,7 +138,7 @@
   }
 
   /// Parses a floating-point scalar.
-  _ScalarNode parseFloat(String content) {
+  ScalarNode parseFloat(String content) {
     var match = new RegExp(
         r"^[-+]?(\.[0-9]+|[0-9]+(\.[0-9]*)?)([eE][-+]?[0-9]+)?$").
       firstMatch(content);
@@ -142,25 +146,25 @@
       // YAML allows floats of the form "0.", but Dart does not. Fix up those
       // floats by removing the trailing dot.
       var matchStr = match.group(0).replaceAll(new RegExp(r"\.$"), "");
-      return new _ScalarNode(_Tag.yaml("float"),
+      return new ScalarNode(Tag.yaml("float"),
           value: double.parse(matchStr));
     }
 
     match = new RegExp(r"^([+-]?)\.(inf|Inf|INF)$").firstMatch(content);
     if (match != null) {
       var value = match.group(1) == "-" ? -double.INFINITY : double.INFINITY;
-      return new _ScalarNode(_Tag.yaml("float"), value: value);
+      return new ScalarNode(Tag.yaml("float"), value: value);
     }
 
     match = new RegExp(r"^\.(nan|NaN|NAN)$").firstMatch(content);
     if (match != null) {
-      return new _ScalarNode(_Tag.yaml("float"), value: double.NAN);
+      return new ScalarNode(Tag.yaml("float"), value: double.NAN);
     }
 
     return null;
   }
 
   /// Parses a string scalar.
-  _ScalarNode parseString(String content) =>
-    new _ScalarNode(_Tag.yaml("str"), value: content);
+  ScalarNode parseString(String content) =>
+    new ScalarNode(Tag.yaml("str"), value: content);
 }
diff --git a/lib/constructor.dart b/lib/src/constructor.dart
similarity index 71%
rename from lib/constructor.dart
rename to lib/src/constructor.dart
index 73a62a8..428c476 100644
--- a/lib/constructor.dart
+++ b/lib/src/constructor.dart
@@ -2,28 +2,32 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-part of yaml;
+library constructor;
+
+import 'model.dart';
+import 'visitor.dart';
+import 'yaml_map.dart';
 
 /// Takes a parsed and composed YAML document (what the spec calls the
 /// "representation graph") and creates native Dart objects that represent that
 /// document.
-class _Constructor extends _Visitor {
+class Constructor extends Visitor {
   /// The root node of the representation graph.
-  _Node root;
+  final Node _root;
 
   /// Map from anchor names to the most recent Dart node with that anchor.
-  Map<String, dynamic> anchors;
+  final _anchors = <String, dynamic>{};
 
-  _Constructor(this.root) : this.anchors = {};
+  Constructor(this._root);
 
   /// Runs the Constructor to produce a Dart object.
-  construct() => root.visit(this);
+  construct() => _root.visit(this);
 
   /// Returns the value of a scalar.
-  visitScalar(_ScalarNode scalar) => scalar.value;
+  visitScalar(ScalarNode scalar) => scalar.value;
 
   /// Converts a sequence into a List of Dart objects.
-  visitSequence(_SequenceNode seq) {
+  visitSequence(SequenceNode seq) {
     var anchor = getAnchor(seq);
     if (anchor != null) return anchor;
     var dartSeq = setAnchor(seq, []);
@@ -32,7 +36,7 @@
   }
 
   /// Converts a mapping into a Map of Dart objects.
-  visitMapping(_MappingNode map) {
+  visitMapping(MappingNode map) {
     var anchor = getAnchor(map);
     if (anchor != null) return anchor;
     var dartMap = setAnchor(map, new YamlMap());
@@ -42,15 +46,15 @@
 
   /// Returns the Dart object that already represents [anchored], if such a
   /// thing exists.
-  getAnchor(_Node anchored) {
+  getAnchor(Node anchored) {
     if (anchored.anchor == null) return null;
-    if (anchors.containsKey(anchored.anchor)) return anchors[anchored.anchor];
+    if (_anchors.containsKey(anchored.anchor)) return _anchors[anchored.anchor];
   }
 
   /// Records that [value] is the Dart object representing [anchored].
-  setAnchor(_Node anchored, value) {
+  setAnchor(Node anchored, value) {
     if (anchored.anchor == null) return value;
-    anchors[anchored.anchor] = value;
+    _anchors[anchored.anchor] = value;
     return value;
   }
 }
diff --git a/lib/deep_equals.dart b/lib/src/deep_equals.dart
similarity index 100%
rename from lib/deep_equals.dart
rename to lib/src/deep_equals.dart
diff --git a/lib/model.dart b/lib/src/model.dart
similarity index 68%
rename from lib/model.dart
rename to lib/src/model.dart
index ac237a0..d7ee481 100644
--- a/lib/model.dart
+++ b/lib/src/model.dart
@@ -2,14 +2,19 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-part of yaml;
+/// This file contains the node classes for the internal representations of YAML
+/// documents. These nodes are used for both the serialization tree and the
+/// representation graph.
+library model;
 
-// This file contains the node classes for the internal representations of YAML
-// documents. These nodes are used for both the serialization tree and the
-// representation graph.
+import 'model.dart';
+import 'parser.dart';
+import 'utils.dart';
+import 'visitor.dart';
+import 'yaml_exception.dart';
 
 /// A tag that indicates the type of a YAML node.
-class _Tag {
+class Tag {
   // TODO(nweiz): it would better match the semantics of the spec if there were
   // a singleton instance of this class for each tag.
 
@@ -25,18 +30,18 @@
   /// The kind of the tag: SCALAR_KIND, SEQUENCE_KIND, or MAPPING_KIND.
   final int kind;
 
-  _Tag(this.name, this.kind);
+  Tag(this.name, this.kind);
 
-  _Tag.scalar(String name) : this(name, SCALAR_KIND);
-  _Tag.sequence(String name) : this(name, SEQUENCE_KIND);
-  _Tag.mapping(String name) : this(name, MAPPING_KIND);
+  Tag.scalar(String name) : this(name, SCALAR_KIND);
+  Tag.sequence(String name) : this(name, SEQUENCE_KIND);
+  Tag.mapping(String name) : this(name, MAPPING_KIND);
 
   /// Returns the standard YAML tag URI for [type].
   static String yaml(String type) => "tag:yaml.org,2002:$type";
 
   /// Two tags are equal if their URIs are equal.
   operator ==(other) {
-    if (other is! _Tag) return false;
+    if (other is! Tag) return false;
     return name == other.name;
   }
 
@@ -52,37 +57,37 @@
 }
 
 /// The abstract class for YAML nodes.
-abstract class _Node {
+abstract class Node {
   /// Every YAML node has a tag that describes its type.
-  _Tag tag;
+  Tag tag;
 
   /// Any YAML node can have an anchor associated with it.
   String anchor;
 
-  _Node(this.tag, [this.anchor]);
+  Node(this.tag, [this.anchor]);
 
   bool operator ==(other) {
-    if (other is! _Node) return false;
+    if (other is! Node) return false;
     return tag == other.tag;
   }
 
-  int get hashCode => _hashCode([tag, anchor]);
+  int get hashCode => hashCodeFor([tag, anchor]);
 
-  visit(_Visitor v);
+  visit(Visitor v);
 }
 
 /// A sequence node represents an ordered list of nodes.
-class _SequenceNode extends _Node {
+class SequenceNode extends Node {
   /// The nodes in the sequence.
-  List<_Node> content;
+  List<Node> content;
 
-  _SequenceNode(String tagName, this.content)
-    : super(new _Tag.sequence(tagName));
+  SequenceNode(String tagName, this.content)
+    : super(new Tag.sequence(tagName));
 
   /// Two sequences are equal if their tags and contents are equal.
   bool operator ==(other) {
     // Should be super != other; bug 2554
-    if (!(super == other) || other is! _SequenceNode) return false;
+    if (!(super == other) || other is! SequenceNode) return false;
     if (content.length != other.content.length) return false;
     for (var i = 0; i < content.length; i++) {
       if (content[i] != other.content[i]) return false;
@@ -92,20 +97,20 @@
 
   String toString() => '$tag [${content.map((e) => '$e').join(', ')}]';
 
-  int get hashCode => super.hashCode ^ _hashCode(content);
+  int get hashCode => super.hashCode ^ hashCodeFor(content);
 
-  visit(_Visitor v) => v.visitSequence(this);
+  visit(Visitor v) => v.visitSequence(this);
 }
 
 /// An alias node is a reference to an anchor.
-class _AliasNode extends _Node {
-  _AliasNode(String anchor) : super(new _Tag.scalar(_Tag.yaml("str")), anchor);
+class AliasNode extends Node {
+  AliasNode(String anchor) : super(new Tag.scalar(Tag.yaml("str")), anchor);
 
-  visit(_Visitor v) => v.visitAlias(this);
+  visit(Visitor v) => v.visitAlias(this);
 }
 
 /// A scalar node represents all YAML nodes that have a single value.
-class _ScalarNode extends _Node {
+class ScalarNode extends Node {
   /// The string value of the scalar node, if it was created by the parser.
   final String _content;
 
@@ -118,14 +123,14 @@
   /// be specified for a newly-parsed scalar that hasn't yet been composed.
   /// Value should be specified for a composed scalar, although `null` is a
   /// valid value.
-  _ScalarNode(String tagName, {String content, this.value})
+  ScalarNode(String tagName, {String content, this.value})
    : _content = content,
-     super(new _Tag.scalar(tagName));
+     super(new Tag.scalar(tagName));
 
   /// Two scalars are equal if their string representations are equal.
   bool operator ==(other) {
     // Should be super != other; bug 2554
-    if (!(super == other) || other is! _ScalarNode) return false;
+    if (!(super == other) || other is! ScalarNode) return false;
     return content == other.content;
   }
 
@@ -151,21 +156,21 @@
 
       var escapedValue = value.codeUnits.map((c) {
         switch (c) {
-        case _Parser.TAB: return "\\t";
-        case _Parser.LF: return "\\n";
-        case _Parser.CR: return "\\r";
-        case _Parser.DOUBLE_QUOTE: return '\\"';
-        case _Parser.NULL: return "\\0";
-        case _Parser.BELL: return "\\a";
-        case _Parser.BACKSPACE: return "\\b";
-        case _Parser.VERTICAL_TAB: return "\\v";
-        case _Parser.FORM_FEED: return "\\f";
-        case _Parser.ESCAPE: return "\\e";
-        case _Parser.BACKSLASH: return "\\\\";
-        case _Parser.NEL: return "\\N";
-        case _Parser.NBSP: return "\\_";
-        case _Parser.LINE_SEPARATOR: return "\\L";
-        case _Parser.PARAGRAPH_SEPARATOR: return "\\P";
+        case Parser.TAB: return "\\t";
+        case Parser.LF: return "\\n";
+        case Parser.CR: return "\\r";
+        case Parser.DOUBLE_QUOTE: return '\\"';
+        case Parser.NULL: return "\\0";
+        case Parser.BELL: return "\\a";
+        case Parser.BACKSPACE: return "\\b";
+        case Parser.VERTICAL_TAB: return "\\v";
+        case Parser.FORM_FEED: return "\\f";
+        case Parser.ESCAPE: return "\\e";
+        case Parser.BACKSLASH: return "\\\\";
+        case Parser.NEL: return "\\N";
+        case Parser.NBSP: return "\\_";
+        case Parser.LINE_SEPARATOR: return "\\L";
+        case Parser.PARAGRAPH_SEPARATOR: return "\\P";
         default:
           if (c < 0x20 || (c >= 0x7f && c < 0x100)) {
             return "\\x${zeroPad(c.toRadixString(16).toUpperCase(), 2)}";
@@ -196,21 +201,21 @@
 
   int get hashCode => super.hashCode ^ content.hashCode;
 
-  visit(_Visitor v) => v.visitScalar(this);
+  visit(Visitor v) => v.visitScalar(this);
 }
 
 /// A mapping node represents an unordered map of nodes to nodes.
-class _MappingNode extends _Node {
+class MappingNode extends Node {
   /// The node map.
-  Map<_Node, _Node> content;
+  Map<Node, Node> content;
 
-  _MappingNode(String tagName, this.content)
-    : super(new _Tag.mapping(tagName));
+  MappingNode(String tagName, this.content)
+    : super(new Tag.mapping(tagName));
 
   /// Two mappings are equal if their tags and contents are equal.
   bool operator ==(other) {
     // Should be super != other; bug 2554
-    if (!(super == other) || other is! _MappingNode) return false;
+    if (!(super == other) || other is! MappingNode) return false;
     if (content.length != other.content.length) return false;
     for (var key in content.keys) {
       if (!other.content.containsKey(key)) return false;
@@ -226,7 +231,7 @@
     return '$tag {$strContent}';
   }
 
-  int get hashCode => super.hashCode ^ _hashCode(content);
+  int get hashCode => super.hashCode ^ hashCodeFor(content);
 
-  visit(_Visitor v) => v.visitMapping(this);
+  visit(Visitor v) => v.visitMapping(this);
 }
diff --git a/lib/parser.dart b/lib/src/parser.dart
similarity index 85%
rename from lib/parser.dart
rename to lib/src/parser.dart
index b923fe3..2616038 100644
--- a/lib/parser.dart
+++ b/lib/src/parser.dart
@@ -2,7 +2,13 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-part of yaml;
+library parser;
+
+import 'dart:collection';
+
+import 'model.dart';
+import 'yaml_exception.dart';
+import 'yaml_map.dart';
 
 /// Translates a string of characters into a YAML serialization tree.
 ///
@@ -17,7 +23,7 @@
 /// named `nb-ns-plain-in-line`, and the method implementing it is named
 /// `nb_ns_plainInLine`. The exception to that rule is methods that just
 /// recognize character classes; these are named `is*`.
-class _Parser {
+class Parser {
   static const TAB = 0x9;
   static const LF = 0xA;
   static const CR = 0xD;
@@ -111,84 +117,84 @@
   static const CHOMPING_CLIP = 2;
 
   /// The source string being parsed.
-  final String s;
+  final String _s;
 
   /// The current position in the source string.
-  int pos = 0;
+  int _pos = 0;
 
   /// The length of the string being parsed.
-  final int len;
+  final int _len;
 
   /// The current (0-based) line in the source string.
-  int line = 0;
+  int _line = 0;
 
   /// The current (0-based) column in the source string.
-  int column = 0;
+  int _column = 0;
 
   /// Whether we're parsing a bare document (that is, one that doesn't begin
   /// with `---`). Bare documents don't allow `%` immediately following
   /// newlines.
-  bool inBareDocument = false;
+  bool _inBareDocument = false;
 
   /// The line number of the farthest position that has been parsed successfully
   /// before backtracking. Used for error reporting.
-  int farthestLine = 0;
+  int _farthestLine = 0;
 
   /// The column number of the farthest position that has been parsed
   /// successfully before backtracking. Used for error reporting.
-  int farthestColumn = 0;
+  int _farthestColumn = 0;
 
   /// The farthest position in the source string that has been parsed
   /// successfully before backtracking. Used for error reporting.
-  int farthestPos = 0;
+  int _farthestPos = 0;
 
   /// The name of the context of the farthest position that has been parsed
   /// successfully before backtracking. Used for error reporting.
-  String farthestContext = "document";
+  String _farthestContext = "document";
 
   /// A stack of the names of parse contexts. Used for error reporting.
-  List<String> contextStack;
+  List<String> _contextStack;
 
   /// Annotations attached to ranges of the source string that add extra
   /// information to any errors that occur in the annotated range.
-  _RangeMap<String> errorAnnotations;
+  _RangeMap<String> _errorAnnotations;
 
   /// The buffer containing the string currently being captured.
-  StringBuffer capturedString;
+  StringBuffer _capturedString;
 
   /// The beginning of the current section of the captured string.
-  int captureStart;
+  int _captureStart;
 
   /// Whether the current string capture is being overridden.
-  bool capturingAs = false;
+  bool _capturingAs = false;
 
-  _Parser(String s)
-    : this.s = s,
-      len = s.length,
-      contextStack = <String>["document"],
-      errorAnnotations = new _RangeMap();
+  Parser(String s)
+    : this._s = s,
+      _len = s.length,
+      _contextStack = <String>["document"],
+      _errorAnnotations = new _RangeMap();
 
   /// Return the character at the current position, then move that position
   /// forward one character. Also updates the current line and column numbers.
   int next() {
-    if (pos == len) return -1;
-    var char = s.codeUnitAt(pos++);
+    if (_pos == _len) return -1;
+    var char = _s.codeUnitAt(_pos++);
     if (isBreak(char)) {
-      line++;
-      column = 0;
+      _line++;
+      _column = 0;
     } else {
-      column++;
+      _column++;
     }
 
-    if (farthestLine < line) {
-      farthestLine = line;
-      farthestColumn = column;
-      farthestContext = contextStack.last;
-    } else if (farthestLine == line && farthestColumn < column) {
-      farthestColumn = column;
-      farthestContext = contextStack.last;
+    if (_farthestLine < _line) {
+      _farthestLine = _line;
+      _farthestColumn = _column;
+      _farthestContext = _contextStack.last;
+    } else if (_farthestLine == _line && _farthestColumn < _column) {
+      _farthestColumn = _column;
+      _farthestContext = _contextStack.last;
     }
-    farthestPos = pos;
+    _farthestPos = _pos;
 
     return char;
   }
@@ -199,8 +205,8 @@
   /// Returns -1 if this would return a character after the end or before the
   /// beginning of the input string.
   int peek([int i = 0]) {
-    var peekPos = pos + i;
-    return (peekPos >= len || peekPos < 0) ? -1 : s.codeUnitAt(peekPos);
+    var peekPos = _pos + i;
+    return (peekPos >= _len || peekPos < 0) ? -1 : _s.codeUnitAt(peekPos);
   }
 
   /// The truthiness operator. Returns `false` if [obj] is `null` or `false`,
@@ -243,11 +249,11 @@
   /// Conceptually, repeats a production any number of times.
   List zeroOrMore(consumer()) {
     var out = [];
-    var oldPos = pos;
+    var oldPos = _pos;
     while (true) {
       var el = consumer();
-      if (!truth(el) || oldPos == pos) return out;
-      oldPos = pos;
+      if (!truth(el) || oldPos == _pos) return out;
+      oldPos = _pos;
       out.add(el);
     }
     return null; // Unreachable.
@@ -270,20 +276,20 @@
   /// Calls [consumer] and returns its result, but rolls back the parser state
   /// if [consumer] returns a falsey value.
   transaction(consumer()) {
-    var oldPos = pos;
-    var oldLine = line;
-    var oldColumn = column;
-    var oldCaptureStart = captureStart;
-    String capturedSoFar = capturedString == null ? null :
-      capturedString.toString();
+    var oldPos = _pos;
+    var oldLine = _line;
+    var oldColumn = _column;
+    var oldCaptureStart = _captureStart;
+    String capturedSoFar = _capturedString == null ? null :
+      _capturedString.toString();
     var res = consumer();
     if (truth(res)) return res;
 
-    pos = oldPos;
-    line = oldLine;
-    column = oldColumn;
-    captureStart = oldCaptureStart;
-    capturedString = capturedSoFar == null ? null :
+    _pos = oldPos;
+    _line = oldLine;
+    _column = oldColumn;
+    _captureStart = oldCaptureStart;
+    _capturedString = capturedSoFar == null ? null :
       new StringBuffer(capturedSoFar);
     return res;
   }
@@ -316,21 +322,21 @@
   /// [consumer] in `transaction`.
   String captureString(consumer()) {
     // captureString calls may not be nested
-    assert(capturedString == null);
+    assert(_capturedString == null);
 
-    captureStart = pos;
-    capturedString = new StringBuffer();
+    _captureStart = _pos;
+    _capturedString = new StringBuffer();
     var res = transaction(consumer);
     if (!truth(res)) {
-      captureStart = null;
-      capturedString = null;
+      _captureStart = null;
+      _capturedString = null;
       return null;
     }
 
     flushCapture();
-    var result = capturedString.toString();
-    captureStart = null;
-    capturedString = null;
+    var result = _capturedString.toString();
+    _captureStart = null;
+    _capturedString = null;
     return result;
   }
 
@@ -338,27 +344,27 @@
       captureAndTransform(consumer, (_) => replacement);
 
   captureAndTransform(consumer(), String transformation(String captured)) {
-    if (capturedString == null) return consumer();
-    if (capturingAs) return consumer();
+    if (_capturedString == null) return consumer();
+    if (_capturingAs) return consumer();
 
     flushCapture();
-    capturingAs = true;
+    _capturingAs = true;
     var res = consumer();
-    capturingAs = false;
+    _capturingAs = false;
     if (!truth(res)) return res;
 
-    capturedString.write(transformation(s.substring(captureStart, pos)));
-    captureStart = pos;
+    _capturedString.write(transformation(_s.substring(_captureStart, _pos)));
+    _captureStart = _pos;
     return res;
   }
 
   void flushCapture() {
-    capturedString.write(s.substring(captureStart, pos));
-    captureStart = pos;
+    _capturedString.write(_s.substring(_captureStart, _pos));
+    _captureStart = _pos;
   }
 
   /// Adds a tag and an anchor to [node], if they're defined.
-  _Node addProps(_Node node, _Pair<_Tag, String> props) {
+  Node addProps(Node node, _Pair<Tag, String> props) {
     if (props == null || node == null) return node;
     if (truth(props.first)) node.tag = props.first;
     if (truth(props.last)) node.anchor = props.last;
@@ -366,19 +372,19 @@
   }
 
   /// Creates a MappingNode from [pairs].
-  _MappingNode map(List<_Pair<_Node, _Node>> pairs) {
-    var content = new Map<_Node, _Node>();
+  MappingNode map(List<_Pair<Node, Node>> pairs) {
+    var content = new Map<Node, Node>();
     pairs.forEach((pair) => content[pair.first] = pair.last);
-    return new _MappingNode("?", content);
+    return new MappingNode("?", content);
   }
 
   /// Runs [fn] in a context named [name]. Used for error reporting.
   context(String name, fn()) {
     try {
-      contextStack.add(name);
+      _contextStack.add(name);
       return fn();
     } finally {
-      var popped = contextStack.removeLast();
+      var popped = _contextStack.removeLast();
       assert(popped == name);
     }
   }
@@ -387,21 +393,21 @@
   /// current position and the position of the cursor after running [fn]. The
   /// cursor is reset after [fn] is run.
   annotateError(String message, fn()) {
-    var start = pos;
+    var start = _pos;
     var end;
     transaction(() {
       fn();
-      end = pos;
+      end = _pos;
       return false;
     });
-    errorAnnotations[new _Range(start, end)] = message;
+    _errorAnnotations[new _Range(start, end)] = message;
   }
 
   /// Throws an error with additional context information.
   error(String message) {
     // Line and column should be one-based.
-    throw new SyntaxError(line + 1, column + 1,
-        "$message (in $farthestContext)");
+    throw new SyntaxError(_line + 1, _column + 1,
+        "$message (in $_farthestContext)");
   }
 
   /// If [result] is falsey, throws an error saying that [expected] was
@@ -411,13 +417,13 @@
     error("expected $expected");
   }
 
-  /// Throws an error saying that the parse failed. Uses [farthestLine],
-  /// [farthestColumn], and [farthestContext] to provide additional information.
+  /// Throws an error saying that the parse failed. Uses [_farthestLine],
+  /// [_farthestColumn], and [_farthestContext] to provide additional information.
   parseFailed() {
-    var message = "invalid YAML in $farthestContext";
-    var extraError = errorAnnotations[farthestPos];
+    var message = "invalid YAML in $_farthestContext";
+    var extraError = _errorAnnotations[_farthestPos];
     if (extraError != null) message = "$message ($extraError)";
-    throw new SyntaxError(farthestLine + 1, farthestColumn + 1, message);
+    throw new SyntaxError(_farthestLine + 1, _farthestColumn + 1, message);
   }
 
   /// Returns the number of spaces after the current position.
@@ -439,7 +445,7 @@
         spaces = captureString(() => zeroOrMore(() => consumeChar(SP))).length;
         if (spaces > maxSpaces) {
           maxSpaces = spaces;
-          maxSpacesLine = line;
+          maxSpacesLine = _line;
         }
       } while (b_break());
       return false;
@@ -462,10 +468,10 @@
   }
 
   /// Returns whether the current position is at the beginning of a line.
-  bool get atStartOfLine => column == 0;
+  bool get atStartOfLine => _column == 0;
 
   /// Returns whether the current position is at the end of the input.
-  bool get atEndOfFile => pos == len;
+  bool get atEndOfFile => _pos == _len;
 
   /// Given an indicator character, returns the type of that indicator (or null
   /// if the indicator isn't found.
@@ -796,7 +802,7 @@
   bool l_directive() => false; // TODO(nweiz): implement
 
   // 96
-  _Pair<_Tag, String> c_ns_properties(int indent, int ctx) {
+  _Pair<Tag, String> c_ns_properties(int indent, int ctx) {
     var tag, anchor;
     tag = c_ns_tagProperty();
     if (truth(tag)) {
@@ -804,7 +810,7 @@
         if (!truth(s_separate(indent, ctx))) return null;
         return c_ns_anchorProperty();
       });
-      return new _Pair<_Tag, String>(tag, anchor);
+      return new _Pair<Tag, String>(tag, anchor);
     }
 
     anchor = c_ns_anchorProperty();
@@ -813,14 +819,14 @@
         if (!truth(s_separate(indent, ctx))) return null;
         return c_ns_tagProperty();
       });
-      return new _Pair<_Tag, String>(tag, anchor);
+      return new _Pair<Tag, String>(tag, anchor);
     }
 
     return null;
   }
 
   // 97
-  _Tag c_ns_tagProperty() => null; // TODO(nweiz): implement
+  Tag c_ns_tagProperty() => null; // TODO(nweiz): implement
 
   // 101
   String c_ns_anchorProperty() => null; // TODO(nweiz): implement
@@ -833,17 +839,17 @@
     captureString(() => oneOrMore(() => consume(isAnchorChar)));
 
   // 104
-  _Node c_ns_aliasNode() {
+  Node c_ns_aliasNode() {
     if (!truth(c_indicator(C_ALIAS))) return null;
     var name = expect(ns_anchorName(), 'anchor name');
-    return new _AliasNode(name);
+    return new AliasNode(name);
   }
 
   // 105
-  _ScalarNode e_scalar() => new _ScalarNode("?", content: "");
+  ScalarNode e_scalar() => new ScalarNode("?", content: "");
 
   // 106
-  _ScalarNode e_node() => e_scalar();
+  ScalarNode e_node() => e_scalar();
 
   // 107
   bool nb_doubleChar() => or([
@@ -855,12 +861,12 @@
   bool ns_doubleChar() => !isSpace(peek()) && truth(nb_doubleChar());
 
   // 109
-  _Node c_doubleQuoted(int indent, int ctx) => context('string', () {
+  Node c_doubleQuoted(int indent, int ctx) => context('string', () {
     return transaction(() {
       if (!truth(c_indicator(C_DOUBLE_QUOTE))) return null;
       var contents = nb_doubleText(indent, ctx);
       if (!truth(c_indicator(C_DOUBLE_QUOTE))) return null;
-      return new _ScalarNode("!", content: contents);
+      return new ScalarNode("!", content: contents);
     });
   });
 
@@ -943,12 +949,12 @@
   bool ns_singleChar() => !isSpace(peek()) && truth(nb_singleChar());
 
   // 120
-  _Node c_singleQuoted(int indent, int ctx) => context('string', () {
+  Node c_singleQuoted(int indent, int ctx) => context('string', () {
     return transaction(() {
       if (!truth(c_indicator(C_SINGLE_QUOTE))) return null;
       var contents = nb_singleText(indent, ctx);
       if (!truth(c_indicator(C_SINGLE_QUOTE))) return null;
-      return new _ScalarNode("!", content: contents);
+      return new ScalarNode("!", content: contents);
     });
   });
 
@@ -1110,18 +1116,18 @@
   }
 
   // 137
-  _SequenceNode c_flowSequence(int indent, int ctx) => transaction(() {
+  SequenceNode c_flowSequence(int indent, int ctx) => transaction(() {
     if (!truth(c_indicator(C_SEQUENCE_START))) return null;
     zeroOrOne(() => s_separate(indent, ctx));
     var content = zeroOrOne(() => ns_s_flowSeqEntries(indent, inFlow(ctx)));
     if (!truth(c_indicator(C_SEQUENCE_END))) return null;
-    return new _SequenceNode("?", new List<_Node>.from(content));
+    return new SequenceNode("?", new List<Node>.from(content));
   });
 
   // 138
-  Iterable<_Node> ns_s_flowSeqEntries(int indent, int ctx) {
+  Iterable<Node> ns_s_flowSeqEntries(int indent, int ctx) {
     var first = ns_flowSeqEntry(indent, ctx);
-    if (!truth(first)) return new Queue<_Node>();
+    if (!truth(first)) return new Queue<Node>();
     zeroOrOne(() => s_separate(indent, ctx));
 
     var rest;
@@ -1130,25 +1136,25 @@
       rest = zeroOrOne(() => ns_s_flowSeqEntries(indent, ctx));
     }
 
-    if (rest == null) rest = new Queue<_Node>();
+    if (rest == null) rest = new Queue<Node>();
     rest.addFirst(first);
 
     return rest;
   }
 
   // 139
-  _Node ns_flowSeqEntry(int indent, int ctx) => or([
+  Node ns_flowSeqEntry(int indent, int ctx) => or([
     () => ns_flowPair(indent, ctx),
     () => ns_flowNode(indent, ctx)
   ]);
 
   // 140
-  _Node c_flowMapping(int indent, int ctx) {
+  Node c_flowMapping(int indent, int ctx) {
     if (!truth(c_indicator(C_MAPPING_START))) return null;
     zeroOrOne(() => s_separate(indent, ctx));
     var content = zeroOrOne(() => ns_s_flowMapEntries(indent, inFlow(ctx)));
     if (!truth(c_indicator(C_MAPPING_END))) return null;
-    return new _MappingNode("?", content);
+    return new MappingNode("?", content);
   }
 
   // 141
@@ -1175,7 +1181,7 @@
   }
 
   // 142
-  _Pair<_Node, _Node> ns_flowMapEntry(int indent, int ctx) => or([
+  _Pair<Node, Node> ns_flowMapEntry(int indent, int ctx) => or([
     () => transaction(() {
       if (!truth(c_indicator(C_MAPPING_KEY))) return false;
       if (!truth(s_separate(indent, ctx))) return false;
@@ -1185,20 +1191,20 @@
   ]);
 
   // 143
-  _Pair<_Node, _Node> ns_flowMapExplicitEntry(int indent, int ctx) => or([
+  _Pair<Node, Node> ns_flowMapExplicitEntry(int indent, int ctx) => or([
     () => ns_flowMapImplicitEntry(indent, ctx),
-    () => new _Pair<_Node, _Node>(e_node(), e_node())
+    () => new _Pair<Node, Node>(e_node(), e_node())
   ]);
 
   // 144
-  _Pair<_Node, _Node> ns_flowMapImplicitEntry(int indent, int ctx) => or([
+  _Pair<Node, Node> ns_flowMapImplicitEntry(int indent, int ctx) => or([
     () => ns_flowMapYamlKeyEntry(indent, ctx),
     () => c_ns_flowMapEmptyKeyEntry(indent, ctx),
     () => c_ns_flowMapJsonKeyEntry(indent, ctx)
   ]);
 
   // 145
-  _Pair<_Node, _Node> ns_flowMapYamlKeyEntry(int indent, int ctx) {
+  _Pair<Node, Node> ns_flowMapYamlKeyEntry(int indent, int ctx) {
     var key = ns_flowYamlNode(indent, ctx);
     if (!truth(key)) return null;
     var value = or([
@@ -1208,18 +1214,18 @@
       }),
       e_node
     ]);
-    return new _Pair<_Node, _Node>(key, value);
+    return new _Pair<Node, Node>(key, value);
   }
 
   // 146
-  _Pair<_Node, _Node> c_ns_flowMapEmptyKeyEntry(int indent, int ctx) {
+  _Pair<Node, Node> c_ns_flowMapEmptyKeyEntry(int indent, int ctx) {
     var value = c_ns_flowMapSeparateValue(indent, ctx);
     if (!truth(value)) return null;
-    return new _Pair<_Node, _Node>(e_node(), value);
+    return new _Pair<Node, Node>(e_node(), value);
   }
 
   // 147
-  _Node c_ns_flowMapSeparateValue(int indent, int ctx) => transaction(() {
+  Node c_ns_flowMapSeparateValue(int indent, int ctx) => transaction(() {
     if (!truth(c_indicator(C_MAPPING_VALUE))) return null;
     if (isPlainSafe(ctx, peek())) return null;
 
@@ -1233,7 +1239,7 @@
   });
 
   // 148
-  _Pair<_Node, _Node> c_ns_flowMapJsonKeyEntry(int indent, int ctx) {
+  _Pair<Node, Node> c_ns_flowMapJsonKeyEntry(int indent, int ctx) {
     var key = c_flowJsonNode(indent, ctx);
     if (!truth(key)) return null;
     var value = or([
@@ -1243,11 +1249,11 @@
       }),
       e_node
     ]);
-    return new _Pair<_Node, _Node>(key, value);
+    return new _Pair<Node, Node>(key, value);
   }
 
   // 149
-  _Node c_ns_flowMapAdjacentValue(int indent, int ctx) {
+  Node c_ns_flowMapAdjacentValue(int indent, int ctx) {
     if (!truth(c_indicator(C_MAPPING_VALUE))) return null;
     return or([
       () => transaction(() {
@@ -1259,7 +1265,7 @@
   }
 
   // 150
-  _Node ns_flowPair(int indent, int ctx) {
+  Node ns_flowPair(int indent, int ctx) {
     var pair = or([
       () => transaction(() {
         if (!truth(c_indicator(C_MAPPING_KEY))) return null;
@@ -1274,34 +1280,34 @@
   }
 
   // 151
-  _Pair<_Node, _Node> ns_flowPairEntry(int indent, int ctx) => or([
+  _Pair<Node, Node> ns_flowPairEntry(int indent, int ctx) => or([
     () => ns_flowPairYamlKeyEntry(indent, ctx),
     () => c_ns_flowMapEmptyKeyEntry(indent, ctx),
     () => c_ns_flowPairJsonKeyEntry(indent, ctx)
   ]);
 
   // 152
-  _Pair<_Node, _Node> ns_flowPairYamlKeyEntry(int indent, int ctx) =>
+  _Pair<Node, Node> ns_flowPairYamlKeyEntry(int indent, int ctx) =>
     transaction(() {
       var key = ns_s_implicitYamlKey(FLOW_KEY);
       if (!truth(key)) return null;
       var value = c_ns_flowMapSeparateValue(indent, ctx);
       if (!truth(value)) return null;
-      return new _Pair<_Node, _Node>(key, value);
+      return new _Pair<Node, Node>(key, value);
     });
 
   // 153
-  _Pair<_Node, _Node> c_ns_flowPairJsonKeyEntry(int indent, int ctx) =>
+  _Pair<Node, Node> c_ns_flowPairJsonKeyEntry(int indent, int ctx) =>
     transaction(() {
       var key = c_s_implicitJsonKey(FLOW_KEY);
       if (!truth(key)) return null;
       var value = c_ns_flowMapAdjacentValue(indent, ctx);
       if (!truth(value)) return null;
-      return new _Pair<_Node, _Node>(key, value);
+      return new _Pair<Node, Node>(key, value);
     });
 
   // 154
-  _Node ns_s_implicitYamlKey(int ctx) => transaction(() {
+  Node ns_s_implicitYamlKey(int ctx) => transaction(() {
     // TODO(nweiz): this is supposed to be limited to 1024 characters.
 
     // The indentation parameter is "null" since it's unused in this path
@@ -1312,7 +1318,7 @@
   });
 
   // 155
-  _Node c_s_implicitJsonKey(int ctx) => transaction(() {
+  Node c_s_implicitJsonKey(int ctx) => transaction(() {
     // TODO(nweiz): this is supposed to be limited to 1024 characters.
 
     // The indentation parameter is "null" since it's unused in this path
@@ -1323,14 +1329,14 @@
   });
 
   // 156
-  _Node ns_flowYamlContent(int indent, int ctx) {
+  Node ns_flowYamlContent(int indent, int ctx) {
     var str = ns_plain(indent, ctx);
     if (!truth(str)) return null;
-    return new _ScalarNode("?", content: str);
+    return new ScalarNode("?", content: str);
   }
 
   // 157
-  _Node c_flowJsonContent(int indent, int ctx) => or([
+  Node c_flowJsonContent(int indent, int ctx) => or([
     () => c_flowSequence(indent, ctx),
     () => c_flowMapping(indent, ctx),
     () => c_singleQuoted(indent, ctx),
@@ -1338,13 +1344,13 @@
   ]);
 
   // 158
-  _Node ns_flowContent(int indent, int ctx) => or([
+  Node ns_flowContent(int indent, int ctx) => or([
     () => ns_flowYamlContent(indent, ctx),
     () => c_flowJsonContent(indent, ctx)
   ]);
 
   // 159
-  _Node ns_flowYamlNode(int indent, int ctx) => or([
+  Node ns_flowYamlNode(int indent, int ctx) => or([
     c_ns_aliasNode,
     () => ns_flowYamlContent(indent, ctx),
     () {
@@ -1362,7 +1368,7 @@
   ]);
 
   // 160
-  _Node c_flowJsonNode(int indent, int ctx) => transaction(() {
+  Node c_flowJsonNode(int indent, int ctx) => transaction(() {
     var props;
     zeroOrOne(() => transaction(() {
         props = c_ns_properties(indent, ctx);
@@ -1374,7 +1380,7 @@
   });
 
   // 161
-  _Node ns_flowNode(int indent, int ctx) => or([
+  Node ns_flowNode(int indent, int ctx) => or([
     c_ns_aliasNode,
     () => ns_flowContent(indent, ctx),
     () => transaction(() {
@@ -1471,7 +1477,7 @@
   });
 
   // 170
-  _Node c_l_literal(int indent) => transaction(() {
+  Node c_l_literal(int indent) => transaction(() {
     if (!truth(c_indicator(C_LITERAL))) return null;
     var header = c_b_blockHeader();
     if (!truth(header)) return null;
@@ -1480,7 +1486,7 @@
     var content = l_literalContent(indent + additionalIndent, header.chomping);
     if (!truth(content)) return null;
 
-    return new _ScalarNode("!", content: content);
+    return new ScalarNode("!", content: content);
   });
 
   // 171
@@ -1508,7 +1514,7 @@
   });
 
   // 174
-  _Node c_l_folded(int indent) => transaction(() {
+  Node c_l_folded(int indent) => transaction(() {
     if (!truth(c_indicator(C_FOLDED))) return null;
     var header = c_b_blockHeader();
     if (!truth(header)) return null;
@@ -1517,7 +1523,7 @@
     var content = l_foldedContent(indent + additionalIndent, header.chomping);
     if (!truth(content)) return null;
 
-    return new _ScalarNode("!", content: content);
+    return new ScalarNode("!", content: content);
   });
 
   // 175
@@ -1593,7 +1599,7 @@
   });
 
   // 183
-  _SequenceNode l_blockSequence(int indent) => context('sequence', () {
+  SequenceNode l_blockSequence(int indent) => context('sequence', () {
     var additionalIndent = countIndentation() - indent;
     if (additionalIndent <= 0) return null;
 
@@ -1603,11 +1609,11 @@
     }));
     if (!truth(content)) return null;
 
-    return new _SequenceNode("?", content);
+    return new SequenceNode("?", content);
   });
 
   // 184
-  _Node c_l_blockSeqEntry(int indent) => transaction(() {
+  Node c_l_blockSeqEntry(int indent) => transaction(() {
     if (!truth(c_indicator(C_SEQUENCE_ENTRY))) return null;
     if (isNonSpace(peek())) return null;
 
@@ -1615,7 +1621,7 @@
   });
 
   // 185
-  _Node s_l_blockIndented(int indent, int ctx) {
+  Node s_l_blockIndented(int indent, int ctx) {
     var additionalIndent = countIndentation();
     return or([
       () => transaction(() {
@@ -1629,7 +1635,7 @@
   }
 
   // 186
-  _Node ns_l_compactSequence(int indent) => context('sequence', () {
+  Node ns_l_compactSequence(int indent) => context('sequence', () {
     var first = c_l_blockSeqEntry(indent);
     if (!truth(first)) return null;
 
@@ -1639,11 +1645,11 @@
       }));
     content.insert(0, first);
 
-    return new _SequenceNode("?", content);
+    return new SequenceNode("?", content);
   });
 
   // 187
-  _Node l_blockMapping(int indent) => context('mapping', () {
+  Node l_blockMapping(int indent) => context('mapping', () {
     var additionalIndent = countIndentation() - indent;
     if (additionalIndent <= 0) return null;
 
@@ -1657,13 +1663,13 @@
   });
 
   // 188
-  _Pair<_Node, _Node> ns_l_blockMapEntry(int indent) => or([
+  _Pair<Node, Node> ns_l_blockMapEntry(int indent) => or([
     () => c_l_blockMapExplicitEntry(indent),
     () => ns_l_blockMapImplicitEntry(indent)
   ]);
 
   // 189
-  _Pair<_Node, _Node> c_l_blockMapExplicitEntry(int indent) {
+  _Pair<Node, Node> c_l_blockMapExplicitEntry(int indent) {
     var key = c_l_blockMapExplicitKey(indent);
     if (!truth(key)) return null;
 
@@ -1672,37 +1678,37 @@
       e_node
     ]);
 
-    return new _Pair<_Node, _Node>(key, value);
+    return new _Pair<Node, Node>(key, value);
   }
 
   // 190
-  _Node c_l_blockMapExplicitKey(int indent) => transaction(() {
+  Node c_l_blockMapExplicitKey(int indent) => transaction(() {
     if (!truth(c_indicator(C_MAPPING_KEY))) return null;
     return s_l_blockIndented(indent, BLOCK_OUT);
   });
 
   // 191
-  _Node l_blockMapExplicitValue(int indent) => transaction(() {
+  Node l_blockMapExplicitValue(int indent) => transaction(() {
     if (!truth(s_indent(indent))) return null;
     if (!truth(c_indicator(C_MAPPING_VALUE))) return null;
     return s_l_blockIndented(indent, BLOCK_OUT);
   });
 
   // 192
-  _Pair<_Node, _Node> ns_l_blockMapImplicitEntry(int indent) => transaction(() {
+  _Pair<Node, Node> ns_l_blockMapImplicitEntry(int indent) => transaction(() {
     var key = or([ns_s_blockMapImplicitKey, e_node]);
     var value = c_l_blockMapImplicitValue(indent);
-    return truth(value) ? new _Pair<_Node, _Node>(key, value) : null;
+    return truth(value) ? new _Pair<Node, Node>(key, value) : null;
   });
 
   // 193
-  _Node ns_s_blockMapImplicitKey() => context('mapping key', () => or([
+  Node ns_s_blockMapImplicitKey() => context('mapping key', () => or([
     () => c_s_implicitJsonKey(BLOCK_KEY),
     () => ns_s_implicitYamlKey(BLOCK_KEY)
   ]));
 
   // 194
-  _Node c_l_blockMapImplicitValue(int indent) => context('mapping value', () =>
+  Node c_l_blockMapImplicitValue(int indent) => context('mapping value', () =>
     transaction(() {
       if (!truth(c_indicator(C_MAPPING_VALUE))) return null;
       return or([
@@ -1712,7 +1718,7 @@
     }));
 
   // 195
-  _Node ns_l_compactMapping(int indent) => context('mapping', () {
+  Node ns_l_compactMapping(int indent) => context('mapping', () {
     var first = ns_l_blockMapEntry(indent);
     if (!truth(first)) return null;
 
@@ -1726,13 +1732,13 @@
   });
 
   // 196
-  _Node s_l_blockNode(int indent, int ctx) => or([
+  Node s_l_blockNode(int indent, int ctx) => or([
     () => s_l_blockInBlock(indent, ctx),
     () => s_l_flowInBlock(indent)
   ]);
 
   // 197
-  _Node s_l_flowInBlock(int indent) => transaction(() {
+  Node s_l_flowInBlock(int indent) => transaction(() {
     if (!truth(s_separate(indent + 1, FLOW_OUT))) return null;
     var node = ns_flowNode(indent + 1, FLOW_OUT);
     if (!truth(node)) return null;
@@ -1741,13 +1747,13 @@
   });
 
   // 198
-  _Node s_l_blockInBlock(int indent, int ctx) => or([
+  Node s_l_blockInBlock(int indent, int ctx) => or([
     () => s_l_blockScalar(indent, ctx),
     () => s_l_blockCollection(indent, ctx)
   ]);
 
   // 199
-  _Node s_l_blockScalar(int indent, int ctx) => transaction(() {
+  Node s_l_blockScalar(int indent, int ctx) => transaction(() {
     if (!truth(s_separate(indent + 1, ctx))) return null;
     var props = transaction(() {
       var innerProps = c_ns_properties(indent + 1, ctx);
@@ -1762,7 +1768,7 @@
   });
 
   // 200
-  _Node s_l_blockCollection(int indent, int ctx) => transaction(() {
+  Node s_l_blockCollection(int indent, int ctx) => transaction(() {
     var props = transaction(() {
       if (!truth(s_separate(indent + 1, ctx))) return null;
       return c_ns_properties(indent + 1, ctx);
@@ -1796,7 +1802,7 @@
 
   // 206
   bool c_forbidden() {
-    if (!inBareDocument || !atStartOfLine) return false;
+    if (!_inBareDocument || !atStartOfLine) return false;
     var forbidden = false;
     transaction(() {
       if (!truth(or([c_directivesEnd, c_documentEnd]))) return;
@@ -1808,17 +1814,17 @@
   }
 
   // 207
-  _Node l_bareDocument() {
+  Node l_bareDocument() {
     try {
-      inBareDocument = true;
+      _inBareDocument = true;
       return s_l_blockNode(-1, BLOCK_IN);
     } finally {
-      inBareDocument = false;
+      _inBareDocument = false;
     }
   }
 
   // 208
-  _Node l_explicitDocument() {
+  Node l_explicitDocument() {
     if (!truth(c_directivesEnd())) return null;
     var doc = l_bareDocument();
     if (truth(doc)) return doc;
@@ -1829,7 +1835,7 @@
   }
 
   // 209
-  _Node l_directiveDocument() {
+  Node l_directiveDocument() {
     if (!truth(oneOrMore(l_directive))) return null;
     var doc = l_explicitDocument();
     if (doc != null) return doc;
@@ -1838,11 +1844,11 @@
   }
 
   // 210
-  _Node l_anyDocument() =>
+  Node l_anyDocument() =>
     or([l_directiveDocument, l_explicitDocument, l_bareDocument]);
 
   // 211
-  List<_Node> l_yamlStream() {
+  List<Node> l_yamlStream() {
     var docs = [];
     zeroOrMore(l_documentPrefix);
     var first = zeroOrOne(l_anyDocument);
@@ -1868,12 +1874,13 @@
 }
 
 class SyntaxError extends YamlException {
-  final int line;
-  final int column;
+  final int _line;
+  final int _column;
 
-  SyntaxError(this.line, this.column, String msg) : super(msg);
+  SyntaxError(this._line, this._column, String msg) : super(msg);
 
-  String toString() => "Syntax error on line $line, column $column: $msg";
+  String toString() => "Syntax error on line $_line, column $_column: "
+      "${super.toString()}";
 }
 
 /// A pair of values.
@@ -1916,18 +1923,17 @@
 /// expensive.
 class _RangeMap<E> {
   /// The ranges and their associated elements.
-  final List<_Pair<_Range, E>> contents;
+  final List<_Pair<_Range, E>> _contents = <_Pair<_Range, E>>[];
 
-  _RangeMap() : this.contents = <_Pair<_Range, E>>[];
+  _RangeMap();
 
   /// Returns the value associated with the range in which [pos] lies, or null
   /// if there is no such range. If there's more than one such range, the most
   /// recently set one is used.
   E operator[](int pos) {
     // Iterate backwards through contents so the more recent range takes
-    // precedence. TODO(nweiz): clean this up when issue 2804 is fixed.
-    for (var i = contents.length - 1; i >= 0; i--) {
-      var pair = contents[i];
+    // precedence.
+    for (var pair in _contents.reversed) {
       if (pair.first.contains(pos)) return pair.last;
     }
     return null;
@@ -1935,5 +1941,5 @@
 
   /// Associates [value] with [range].
   operator[]=(_Range range, E value) =>
-    contents.add(new _Pair<_Range, E>(range, value));
+    _contents.add(new _Pair<_Range, E>(range, value));
 }
diff --git a/lib/src/utils.dart b/lib/src/utils.dart
new file mode 100644
index 0000000..a87555d
--- /dev/null
+++ b/lib/src/utils.dart
@@ -0,0 +1,39 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library utils;
+
+/// Returns the hash code for [obj]. This includes null, true, false, maps, and
+/// lists. Also handles self-referential structures.
+int hashCodeFor(obj, [List parents]) {
+  if (parents == null) {
+    parents = [];
+  } else if (parents.any((p) => identical(p, obj))) {
+    return -1;
+  }
+
+  parents.add(obj);
+  try {
+    if (obj == null) return 0;
+    if (obj == true) return 1;
+    if (obj == false) return 2;
+    if (obj is Map) {
+      return hashCodeFor(obj.keys, parents) ^
+        hashCodeFor(obj.values, parents);
+    }
+    if (obj is Iterable) {
+      // This is probably a really bad hash function, but presumably we'll get
+      // this in the standard library before it actually matters.
+      int hash = 0;
+      for (var e in obj) {
+        hash ^= hashCodeFor(e, parents);
+      }
+      return hash;
+    }
+    return obj.hashCode;
+  } finally {
+    parents.removeLast();
+  }
+}
+
diff --git a/lib/visitor.dart b/lib/src/visitor.dart
similarity index 74%
rename from lib/visitor.dart
rename to lib/src/visitor.dart
index 42dbb22..4a9c54f 100644
--- a/lib/visitor.dart
+++ b/lib/src/visitor.dart
@@ -2,22 +2,25 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-part of yaml;
+library visitor;
+
+import 'model.dart';
+import 'yaml_map.dart';
 
 /// The visitor pattern for YAML documents.
-class _Visitor {
+class Visitor {
   /// Returns [alias].
-  visitAlias(_AliasNode alias) => alias;
+  visitAlias(AliasNode alias) => alias;
 
   /// Returns [scalar].
-  visitScalar(_ScalarNode scalar) => scalar;
+  visitScalar(ScalarNode scalar) => scalar;
 
   /// Visits each node in [seq] and returns a list of the results.
-  visitSequence(_SequenceNode seq)
+  visitSequence(SequenceNode seq)
       => seq.content.map((e) => e.visit(this)).toList();
 
   /// Visits each key and value in [map] and returns a map of the results.
-  visitMapping(_MappingNode map) {
+  visitMapping(MappingNode map) {
     var out = new YamlMap();
     for (var key in map.content.keys) {
       out[key.visit(this)] = map.content[key].visit(this);
diff --git a/lib/src/yaml_exception.dart b/lib/src/yaml_exception.dart
new file mode 100644
index 0000000..66697a1
--- /dev/null
+++ b/lib/src/yaml_exception.dart
@@ -0,0 +1,15 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library yaml_exception;
+
+/// An error thrown by the YAML processor.
+class YamlException implements Exception {
+  final String _msg;
+
+  YamlException(this._msg);
+
+  String toString() => _msg;
+}
+
diff --git a/lib/yaml_map.dart b/lib/src/yaml_map.dart
similarity index 69%
rename from lib/yaml_map.dart
rename to lib/src/yaml_map.dart
index cbf18e5..29fec75 100644
--- a/lib/yaml_map.dart
+++ b/lib/src/yaml_map.dart
@@ -2,7 +2,10 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-part of yaml;
+library yaml_map;
+
+import 'deep_equals.dart';
+import 'utils.dart';
 
 /// This class wraps behaves almost identically to the normal Dart Map
 /// implementation, with the following differences:
@@ -12,7 +15,7 @@
 ///     have the same contents.
 ///  *  It has a compatible [hashCode] method.
 class YamlMap implements Map {
-  Map _map;
+  final Map _map;
 
   YamlMap() : _map = new Map();
 
@@ -35,7 +38,7 @@
   bool get isEmpty => _map.isEmpty;
   String toString() => _map.toString();
 
-  int get hashCode => _hashCode(_map);
+  int get hashCode => hashCodeFor(_map);
 
   bool operator ==(other) {
     if (other is! YamlMap) return false;
@@ -61,11 +64,11 @@
 /// A class for wrapping normally-unhashable objects that are being used as keys
 /// in a YamlMap.
 class _WrappedHashKey {
-  var value;
+  final value;
 
   _WrappedHashKey(this.value);
 
-  int get hashCode => _hashCode(value);
+  int get hashCode => hashCodeFor(value);
 
   String toString() => value.toString();
 
@@ -75,36 +78,3 @@
     return deepEquals(this.value, other.value);
   }
 }
-
-/// Returns the hash code for [obj]. This includes null, true, false, maps, and
-/// lists. Also handles self-referential structures.
-int _hashCode(obj, [List parents]) {
-  if (parents == null) {
-    parents = [];
-  } else if (parents.any((p) => identical(p, obj))) {
-    return -1;
-  }
-
-  parents.add(obj);
-  try {
-    if (obj == null) return 0;
-    if (obj == true) return 1;
-    if (obj == false) return 2;
-    if (obj is Map) {
-      return _hashCode(obj.keys, parents) ^
-        _hashCode(obj.values, parents);
-    }
-    if (obj is Iterable) {
-      // This is probably a really bad hash function, but presumably we'll get
-      // this in the standard library before it actually matters.
-      int hash = 0;
-      for (var e in obj) {
-        hash ^= _hashCode(e, parents);
-      }
-      return hash;
-    }
-    return obj.hashCode;
-  } finally {
-    parents.removeLast();
-  }
-}
diff --git a/lib/yaml.dart b/lib/yaml.dart
index e905e76..94e3d42 100644
--- a/lib/yaml.dart
+++ b/lib/yaml.dart
@@ -24,17 +24,13 @@
 ///     }
 library yaml;
 
-import 'dart:math' as Math;
-import 'dart:collection' show Queue;
+import 'src/composer.dart';
+import 'src/constructor.dart';
+import 'src/parser.dart';
+import 'src/yaml_exception.dart';
 
-import 'deep_equals.dart';
-
-part 'yaml_map.dart';
-part 'model.dart';
-part 'parser.dart';
-part 'visitor.dart';
-part 'composer.dart';
-part 'constructor.dart';
+export 'src/yaml_exception.dart';
+export 'src/yaml_map.dart';
 
 /// Loads a single document from a YAML string. If the string contains more than
 /// one document, this throws an error.
@@ -42,8 +38,8 @@
 /// The return value is mostly normal Dart objects. However, since YAML mappings
 /// support some key types that the default Dart map implementation doesn't
 /// (null, NaN, booleans, lists, and maps), all maps in the returned document
-/// are YamlMaps. These have a few small behavioral differences from the default
-/// Map implementation; for details, see the YamlMap class.
+/// are [YamlMap]s. These have a few small behavioral differences from the
+/// default Map implementation; for details, see the [YamlMap] class.
 loadYaml(String yaml) {
   var stream = loadYamlStream(yaml);
   if (stream.length != 1) {
@@ -57,19 +53,10 @@
 /// The return value is mostly normal Dart objects. However, since YAML mappings
 /// support some key types that the default Dart map implementation doesn't
 /// (null, NaN, booleans, lists, and maps), all maps in the returned document
-/// are YamlMaps. These have a few small behavioral differences from the default
-/// Map implementation; for details, see the YamlMap class.
+/// are [YamlMap]s. These have a few small behavioral differences from the
+/// default Map implementation; for details, see the [YamlMap] class.
 List loadYamlStream(String yaml) {
-  return new _Parser(yaml).l_yamlStream()
-      .map((doc) => new _Constructor(new _Composer(doc).compose()).construct())
+  return new Parser(yaml).l_yamlStream()
+      .map((doc) => new Constructor(new Composer(doc).compose()).construct())
       .toList();
 }
-
-/// An error thrown by the YAML processor.
-class YamlException implements Exception {
-  String msg;
-
-  YamlException(this.msg);
-
-  String toString() => msg;
-}
diff --git a/test/yaml_test.dart b/test/yaml_test.dart
index 047c273..42cb613 100644
--- a/test/yaml_test.dart
+++ b/test/yaml_test.dart
@@ -8,7 +8,7 @@
 import "package:expect/expect.dart";
 import 'package:unittest/unittest.dart';
 import 'package:yaml/yaml.dart';
-import 'package:yaml/deep_equals.dart';
+import 'package:yaml/src/deep_equals.dart';
 // TODO(jmesserly): we should not be reaching outside the YAML package
 // The http package has a similar problem.
 import '../../../tests/utils/test_utils.dart';