adding html package as part of app
diff --git a/html/.analysis_options b/html/.analysis_options
new file mode 100644
index 0000000..a10d4c5
--- /dev/null
+++ b/html/.analysis_options
@@ -0,0 +1,2 @@
+analyzer:
+  strong-mode: true
diff --git a/html/.status b/html/.status
new file mode 100644
index 0000000..a424138
--- /dev/null
+++ b/html/.status
@@ -0,0 +1,29 @@
+# Copyright (c) 2014, 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.
+
+# Don't run any test-like files that show up in packages directories. It
+# shouldn't be necessary to run "pub install" in these packages, but if you do
+# it shouldn't break the tests.
+*/packages/*/*: Skip
+*/*/packages/*/*: Skip
+*/*/*/packages/*/*: Skip
+*/*/*/*/packages/*/*: Skip
+*/*/*/*/*/packages/*/*: Skip
+
+build/*: Skip  # nothing requires pub-build
+
+[ $runtime == vm && $mode == debug]
+test/tokenizer_test: Skip  # Times out
+
+[ $runtime == vm && ( $arch == simarm || $arch == simmips ) ]
+test/tokenizer_test: Pass, Slow
+
+[ $browser ]
+test/parser_test: Skip
+test/tokenizer_test: Skip
+test/selectors/*: Skip
+
+[ $runtime == vm ]
+test/browser/browser_test: Skip
+test/selectors/level1_baseline_test: RuntimeError # Issue 37
\ No newline at end of file
diff --git a/html/CHANGELOG.md b/html/CHANGELOG.md
new file mode 100644
index 0000000..dbf745c
--- /dev/null
+++ b/html/CHANGELOG.md
@@ -0,0 +1,50 @@
+# changelog
+
+This file contains highlights of what changes on each version of the html
+package.
+
+## 0.13.1
+ * Update Set.difference to take a Set<Object>.
+
+## 0.13.0
+
+ * **BREAKING** Fix all [strong mode][] errors and warnings.
+   This involved adding more precise types on some public APIs, which is why it
+   may break users.
+
+[strong mode]: https://github.com/dart-lang/dev_compiler/blob/master/STRONG_MODE.md
+
+#### Pub version 0.12.2+2
+  * Support `csslib` versions `0.13.x`.
+  
+#### Pub version 0.12.2+1
+  * Exclude `.packages` file from the published package.
+
+#### Pub version 0.12.2
+  * Added `Element.endSourceSpan`, containing the span of a closing tag.
+
+#### Pub version 0.12.0+1
+  * Support `csslib` version `0.12.0`.
+
+#### Rename to package:html 0.12.0
+  * package has been renamed to `html`
+
+#### Pub version 0.12.0
+  * switch from `source_maps`' `Span` class to `source_span`'s
+    `SourceSpan` class.
+
+#### Pub version 0.11.0+2
+  * expand the version constraint for csslib.
+
+#### Pub version 0.10.0+1
+  * use a more recent source_maps version.
+
+#### Pub version 0.10.0
+  * fix how document fragments are added in NodeList.add/addAll/insertAll.
+
+#### Pub version 0.9.2-dev
+  * add Node.text, Node.append, Document.documentElement
+  * add Text.data, deprecate Node.value and Text.value.
+  * deprecate Node.$dom_nodeType
+  * added querySelector/querySelectorAll, deprecated query/queryAll.
+    This matches the current APIs in dart:html.
diff --git a/html/LICENSE b/html/LICENSE
new file mode 100644
index 0000000..d5ee641
--- /dev/null
+++ b/html/LICENSE
@@ -0,0 +1,23 @@
+Copyright (c) 2006-2012 The Authors
+
+Contributors:
+James Graham - jg307@cam.ac.uk
+Anne van Kesteren - annevankesteren@gmail.com
+Lachlan Hunt - lachlan.hunt@lachy.id.au
+Matt McDonald - kanashii@kanashii.ca
+Sam Ruby - rubys@intertwingly.net
+Ian Hickson (Google) - ian@hixie.ch
+Thomas Broyer - t.broyer@ltgt.net
+Jacques Distler - distler@golem.ph.utexas.edu
+Henri Sivonen - hsivonen@iki.fi
+Adam Barth - abarth@webkit.org
+Eric Seidel - eric@webkit.org
+The Mozilla Foundation (contributions from Henri Sivonen since 2008)
+David Flanagan (Mozilla) - dflanagan@mozilla.com
+Google Inc. (contributed the Dart port) - misc@dartlang.org
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
diff --git a/html/README.md b/html/README.md
new file mode 100644
index 0000000..27db3ce
--- /dev/null
+++ b/html/README.md
@@ -0,0 +1,55 @@
+html5 parser in dart
+====================
+
+This is a pure [Dart][dart] [html5 parser][html5parse]. It's a port of
+[html5lib](https://github.com/html5lib/html5lib-python) from Python. Since it's 100%
+Dart you can use it safely from a script or server side app.
+
+Eventually the parse tree API will be compatible with [dart:html][d_html], so
+the same code will work on the client and the server.
+
+(Formerly known as _html5lib_.)
+
+Installation
+------------
+
+Add this to your `pubspec.yaml` (or create it):
+```yaml
+dependencies:
+  html: any
+```
+Then run the [Pub Package Manager][pub] (comes with the Dart SDK):
+
+    pub install
+
+Usage
+-----
+
+Parsing HTML is easy!
+```dart
+import 'package:html/parser.dart' show parse;
+import 'package:html/dom.dart';
+
+main() {
+  var document = parse(
+      '<body>Hello world! <a href="www.html5rocks.com">HTML5 rocks!');
+  print(document.outerHtml);
+}
+```
+
+You can pass a String or list of bytes to `parse`.
+There's also `parseFragment` for parsing a document fragment, and `HtmlParser`
+if you want more low level control.
+
+Running Tests
+-------------
+
+```bash
+./test/run.sh
+```
+
+[dart]: http://www.dartlang.org/
+[html5parse]: http://dev.w3.org/html5/spec/parsing.html
+[d_html]: http://api.dartlang.org/docs/continuous/dart_html.html
+[files]: http://html5lib.googlecode.com/hg/python/html5lib/
+[pub]: http://www.dartlang.org/docs/pub-package-manager/
diff --git a/html/codereview.settings b/html/codereview.settings
new file mode 100644
index 0000000..caca72f
--- /dev/null
+++ b/html/codereview.settings
@@ -0,0 +1,3 @@
+CODE_REVIEW_SERVER: http://codereview.chromium.org/
+VIEW_VC: https://github.com/dart-lang/html/commit/
+CC_LIST: reviews@dartlang.org
diff --git a/html/lib/dom.dart b/html/lib/dom.dart
new file mode 100644
index 0000000..bd3e2bd
--- /dev/null
+++ b/html/lib/dom.dart
@@ -0,0 +1,1009 @@
+/// A simple tree API that results from parsing html. Intended to be compatible
+/// with dart:html, but it is missing many types and APIs.
+library dom;
+
+// TODO(jmesserly): lots to do here. Originally I wanted to generate this using
+// our Blink IDL generator, but another idea is to directly use the excellent
+// http://dom.spec.whatwg.org/ and http://html.spec.whatwg.org/ and just
+// implement that.
+
+import 'dart:collection';
+import 'package:source_span/source_span.dart';
+
+import 'src/constants.dart';
+import 'src/css_class_set.dart';
+import 'src/list_proxy.dart';
+import 'src/query_selector.dart' as query;
+import 'src/token.dart';
+import 'src/tokenizer.dart';
+import 'dom_parsing.dart';
+import 'parser.dart';
+
+export 'src/css_class_set.dart' show CssClassSet;
+
+// TODO(jmesserly): this needs to be replaced by an AttributeMap for attributes
+// that exposes namespace info.
+class AttributeName implements Comparable {
+  /// The namespace prefix, e.g. `xlink`.
+  final String prefix;
+
+  /// The attribute name, e.g. `title`.
+  final String name;
+
+  /// The namespace url, e.g. `http://www.w3.org/1999/xlink`
+  final String namespace;
+
+  const AttributeName(this.prefix, this.name, this.namespace);
+
+  String toString() {
+    // Implement:
+    // http://www.whatwg.org/specs/web-apps/current-work/multipage/the-end.html#serializing-html-fragments
+    // If we get here we know we are xml, xmlns, or xlink, because of
+    // [HtmlParser.adjustForeignAttriubtes] is the only place we create
+    // an AttributeName.
+    return prefix != null ? '$prefix:$name' : name;
+  }
+
+  int get hashCode {
+    int h = prefix.hashCode;
+    h = 37 * (h & 0x1FFFFF) + name.hashCode;
+    h = 37 * (h & 0x1FFFFF) + namespace.hashCode;
+    return h & 0x3FFFFFFF;
+  }
+
+  int compareTo(other) {
+    // Not sure about this sort order
+    if (other is! AttributeName) return 1;
+    int cmp = (prefix != null ? prefix : "")
+        .compareTo((other.prefix != null ? other.prefix : ""));
+    if (cmp != 0) return cmp;
+    cmp = name.compareTo(other.name);
+    if (cmp != 0) return cmp;
+    return namespace.compareTo(other.namespace);
+  }
+
+  bool operator ==(x) {
+    if (x is! AttributeName) return false;
+    return prefix == x.prefix && name == x.name && namespace == x.namespace;
+  }
+}
+
+// http://dom.spec.whatwg.org/#parentnode
+abstract class _ParentNode implements Node {
+  // TODO(jmesserly): this is only a partial implementation
+
+  /// Seaches for the first descendant node matching the given selectors, using
+  /// a preorder traversal.
+  ///
+  /// NOTE: Not all selectors from
+  /// [selectors level 4](http://dev.w3.org/csswg/selectors-4/)
+  /// are implemented. For example, nth-child does not implement An+B syntax
+  /// and *-of-type is not implemented. If a selector is not implemented this
+  /// method will throw [UniplmentedError].
+  Element querySelector(String selector) => query.querySelector(this, selector);
+
+  /// Returns all descendant nodes matching the given selectors, using a
+  /// preorder traversal.
+  ///
+  /// NOTE: Not all selectors from
+  /// [selectors level 4](http://dev.w3.org/csswg/selectors-4/)
+  /// are implemented. For example, nth-child does not implement An+B syntax
+  /// and *-of-type is not implemented. If a selector is not implemented this
+  /// method will throw [UniplmentedError].
+  List<Element> querySelectorAll(String selector) =>
+      query.querySelectorAll(this, selector);
+}
+
+// http://dom.spec.whatwg.org/#interface-nonelementparentnode
+abstract class _NonElementParentNode implements _ParentNode {
+  // TODO(jmesserly): could be faster, should throw on invalid id.
+  Element getElementById(String id) => querySelector('#$id');
+}
+
+// This doesn't exist as an interface in the spec, but it's useful to merge
+// common methods from these:
+// http://dom.spec.whatwg.org/#interface-document
+// http://dom.spec.whatwg.org/#element
+abstract class _ElementAndDocument implements _ParentNode {
+  // TODO(jmesserly): could be faster, should throw on invalid tag/class names.
+
+  List<Element> getElementsByTagName(String localName) =>
+      querySelectorAll(localName);
+
+  List<Element> getElementsByClassName(String classNames) => querySelectorAll(
+      classNames.splitMapJoin(' ',
+          onNonMatch: (m) => m.isNotEmpty ? '.$m' : m, onMatch: (m) => ''));
+}
+
+/// Really basic implementation of a DOM-core like Node.
+abstract class Node {
+  static const int ATTRIBUTE_NODE = 2;
+  static const int CDATA_SECTION_NODE = 4;
+  static const int COMMENT_NODE = 8;
+  static const int DOCUMENT_FRAGMENT_NODE = 11;
+  static const int DOCUMENT_NODE = 9;
+  static const int DOCUMENT_TYPE_NODE = 10;
+  static const int ELEMENT_NODE = 1;
+  static const int ENTITY_NODE = 6;
+  static const int ENTITY_REFERENCE_NODE = 5;
+  static const int NOTATION_NODE = 12;
+  static const int PROCESSING_INSTRUCTION_NODE = 7;
+  static const int TEXT_NODE = 3;
+
+  /// The parent of the current node (or null for the document node).
+  Node parentNode;
+
+  /// The parent element of this node.
+  ///
+  /// Returns null if this node either does not have a parent or its parent is
+  /// not an element.
+  Element get parent => parentNode is Element ? parentNode : null;
+
+  // TODO(jmesserly): should move to Element.
+  /// A map holding name, value pairs for attributes of the node.
+  ///
+  /// Note that attribute order needs to be stable for serialization, so we use
+  /// a LinkedHashMap. Each key is a [String] or [AttributeName].
+  LinkedHashMap<dynamic, String> attributes = new LinkedHashMap();
+
+  /// A list of child nodes of the current node. This must
+  /// include all elements but not necessarily other node types.
+  final NodeList nodes = new NodeList._();
+
+  List<Element> _elements;
+
+  // TODO(jmesserly): consider using an Expando for this, and put it in
+  // dom_parsing. Need to check the performance affect.
+  /// The source span of this node, if it was created by the [HtmlParser].
+  FileSpan sourceSpan;
+
+  /// The attribute spans if requested. Otherwise null.
+  LinkedHashMap<dynamic, FileSpan> _attributeSpans;
+  LinkedHashMap<dynamic, FileSpan> _attributeValueSpans;
+
+  Node._() {
+    nodes._parent = this;
+  }
+
+  /// If [sourceSpan] is available, this contains the spans of each attribute.
+  /// The span of an attribute is the entire attribute, including the name and
+  /// quotes (if any). For example, the span of "attr" in `<a attr="value">`
+  /// would be the text `attr="value"`.
+  LinkedHashMap<dynamic, FileSpan> get attributeSpans {
+    _ensureAttributeSpans();
+    return _attributeSpans;
+  }
+
+  /// If [sourceSpan] is available, this contains the spans of each attribute's
+  /// value. Unlike [attributeSpans], this span will inlcude only the value.
+  /// For example, the value span of "attr" in `<a attr="value">` would be the
+  /// text `value`.
+  LinkedHashMap<dynamic, FileSpan> get attributeValueSpans {
+    _ensureAttributeSpans();
+    return _attributeValueSpans;
+  }
+
+  List<Element> get children {
+    if (_elements == null) {
+      _elements = new FilteredElementList(this);
+    }
+    return _elements;
+  }
+
+  /// Returns a copy of this node.
+  ///
+  /// If [deep] is `true`, then all of this node's children and decendents are
+  /// copied as well. If [deep] is `false`, then only this node is copied.
+  Node clone(bool deep);
+
+  int get nodeType;
+
+  // http://domparsing.spec.whatwg.org/#extensions-to-the-element-interface
+  String get _outerHtml {
+    var str = new StringBuffer();
+    _addOuterHtml(str);
+    return str.toString();
+  }
+
+  String get _innerHtml {
+    var str = new StringBuffer();
+    _addInnerHtml(str);
+    return str.toString();
+  }
+
+  // Implemented per: http://dom.spec.whatwg.org/#dom-node-textcontent
+  String get text => null;
+  set text(String value) {}
+
+  void append(Node node) => nodes.add(node);
+
+  Node get firstChild => nodes.isNotEmpty ? nodes[0] : null;
+
+  void _addOuterHtml(StringBuffer str);
+
+  void _addInnerHtml(StringBuffer str) {
+    for (Node child in nodes) child._addOuterHtml(str);
+  }
+
+  Node remove() {
+    // TODO(jmesserly): is parent == null an error?
+    if (parentNode != null) {
+      parentNode.nodes.remove(this);
+    }
+    return this;
+  }
+
+  /// Insert [node] as a child of the current node, before [refNode] in the
+  /// list of child nodes. Raises [UnsupportedOperationException] if [refNode]
+  /// is not a child of the current node. If refNode is null, this adds to the
+  /// end of the list.
+  void insertBefore(Node node, Node refNode) {
+    if (refNode == null) {
+      nodes.add(node);
+    } else {
+      nodes.insert(nodes.indexOf(refNode), node);
+    }
+  }
+
+  /// Replaces this node with another node.
+  Node replaceWith(Node otherNode) {
+    if (parentNode == null) {
+      throw new UnsupportedError('Node must have a parent to replace it.');
+    }
+    parentNode.nodes[parentNode.nodes.indexOf(this)] = otherNode;
+    return this;
+  }
+
+  // TODO(jmesserly): should this be a property or remove?
+  /// Return true if the node has children or text.
+  bool hasContent() => nodes.length > 0;
+
+  /// Move all the children of the current node to [newParent].
+  /// This is needed so that trees that don't store text as nodes move the
+  /// text in the correct way.
+  void reparentChildren(Node newParent) {
+    newParent.nodes.addAll(nodes);
+    nodes.clear();
+  }
+
+  bool hasChildNodes() => !nodes.isEmpty;
+
+  bool contains(Node node) => nodes.contains(node);
+
+  /// Initialize [attributeSpans] using [sourceSpan].
+  void _ensureAttributeSpans() {
+    if (_attributeSpans != null) return;
+
+    _attributeSpans = new LinkedHashMap<dynamic, FileSpan>();
+    _attributeValueSpans = new LinkedHashMap<dynamic, FileSpan>();
+
+    if (sourceSpan == null) return;
+
+    var tokenizer = new HtmlTokenizer(sourceSpan.text,
+        generateSpans: true, attributeSpans: true);
+
+    tokenizer.moveNext();
+    var token = tokenizer.current as StartTagToken;
+
+    if (token.attributeSpans == null) return; // no attributes
+
+    for (var attr in token.attributeSpans) {
+      var offset = sourceSpan.start.offset;
+      _attributeSpans[attr.name] =
+          sourceSpan.file.span(offset + attr.start, offset + attr.end);
+      if (attr.startValue != null) {
+        _attributeValueSpans[attr.name] = sourceSpan.file.span(
+            offset + attr.startValue, offset + attr.endValue);
+      }
+    }
+  }
+
+  _clone(Node shallowClone, bool deep) {
+    if (deep) {
+      for (var child in nodes) {
+        shallowClone.append(child.clone(true));
+      }
+    }
+    return shallowClone;
+  }
+}
+
+class Document extends Node
+    with _ParentNode, _NonElementParentNode, _ElementAndDocument {
+  Document() : super._();
+  factory Document.html(String html) => parse(html);
+
+  int get nodeType => Node.DOCUMENT_NODE;
+
+  // TODO(jmesserly): optmize this if needed
+  Element get documentElement => querySelector('html');
+  Element get head => documentElement.querySelector('head');
+  Element get body => documentElement.querySelector('body');
+
+  /// Returns a fragment of HTML or XML that represents the element and its
+  /// contents.
+  // TODO(jmesserly): this API is not specified in:
+  // <http://domparsing.spec.whatwg.org/> nor is it in dart:html, instead
+  // only Element has outerHtml. However it is quite useful. Should we move it
+  // to dom_parsing, where we keep other custom APIs?
+  String get outerHtml => _outerHtml;
+
+  String toString() => "#document";
+
+  void _addOuterHtml(StringBuffer str) => _addInnerHtml(str);
+
+  Document clone(bool deep) => _clone(new Document(), deep);
+
+  Element createElement(String tag) => new Element.tag(tag);
+
+  // TODO(jmesserly): this is only a partial implementation of:
+  // http://dom.spec.whatwg.org/#dom-document-createelementns
+  Element createElementNS(String namespaceUri, String tag) {
+    if (namespaceUri == '') namespaceUri = null;
+    return new Element._(tag, namespaceUri);
+  }
+
+  DocumentFragment createDocumentFragment() => new DocumentFragment();
+}
+
+class DocumentFragment extends Node with _ParentNode, _NonElementParentNode {
+  DocumentFragment() : super._();
+  factory DocumentFragment.html(String html) => parseFragment(html);
+
+  int get nodeType => Node.DOCUMENT_FRAGMENT_NODE;
+
+  /// Returns a fragment of HTML or XML that represents the element and its
+  /// contents.
+  // TODO(jmesserly): this API is not specified in:
+  // <http://domparsing.spec.whatwg.org/> nor is it in dart:html, instead
+  // only Element has outerHtml. However it is quite useful. Should we move it
+  // to dom_parsing, where we keep other custom APIs?
+  String get outerHtml => _outerHtml;
+
+  String toString() => "#document-fragment";
+
+  DocumentFragment clone(bool deep) => _clone(new DocumentFragment(), deep);
+
+  void _addOuterHtml(StringBuffer str) => _addInnerHtml(str);
+
+  String get text => _getText(this);
+  set text(String value) => _setText(this, value);
+}
+
+class DocumentType extends Node {
+  final String name;
+  final String publicId;
+  final String systemId;
+
+  DocumentType(String name, this.publicId, this.systemId)
+      // Note: once Node.tagName is removed, don't pass "name" to super
+      : name = name,
+        super._();
+
+  int get nodeType => Node.DOCUMENT_TYPE_NODE;
+
+  String toString() {
+    if (publicId != null || systemId != null) {
+      // TODO(jmesserly): the html5 serialization spec does not add these. But
+      // it seems useful, and the parser can handle it, so for now keeping it.
+      var pid = publicId != null ? publicId : '';
+      var sid = systemId != null ? systemId : '';
+      return '<!DOCTYPE $name "$pid" "$sid">';
+    } else {
+      return '<!DOCTYPE $name>';
+    }
+  }
+
+  void _addOuterHtml(StringBuffer str) {
+    str.write(toString());
+  }
+
+  DocumentType clone(bool deep) => new DocumentType(name, publicId, systemId);
+}
+
+class Text extends Node {
+  /// The text node's data, stored as either a String or StringBuffer.
+  /// We support storing a StringBuffer here to support fast [appendData].
+  /// It will flatten back to a String on read.
+  var _data;
+
+  Text(String data) : _data = data != null ? data : '', super._();
+
+  int get nodeType => Node.TEXT_NODE;
+
+  String get data => _data = _data.toString();
+  set data(String value) {
+    _data = value != null ? value : '';
+  }
+
+  String toString() => '"$data"';
+
+  void _addOuterHtml(StringBuffer str) => writeTextNodeAsHtml(str, this);
+
+  Text clone(bool deep) => new Text(data);
+
+  void appendData(String data) {
+    if (_data is! StringBuffer) _data = new StringBuffer(_data);
+    StringBuffer sb = _data;
+    sb.write(data);
+  }
+
+  String get text => data;
+  set text(String value) {
+    data = value;
+  }
+}
+
+// TODO(jmesserly): Elements should have a pointer back to their document
+class Element extends Node with _ParentNode, _ElementAndDocument {
+  final String namespaceUri;
+
+  /// The [local name](http://dom.spec.whatwg.org/#concept-element-local-name)
+  /// of this element.
+  final String localName;
+
+  // TODO(jmesserly): consider using an Expando for this, and put it in
+  // dom_parsing. Need to check the performance affect.
+  /// The source span of the end tag this element, if it was created by the
+  /// [HtmlParser]. May be `null` if does not have an implicit end tag.
+  FileSpan endSourceSpan;
+
+  Element._(this.localName, [this.namespaceUri]) : super._();
+
+  Element.tag(this.localName)
+      : namespaceUri = Namespaces.html,
+        super._();
+
+  static final _START_TAG_REGEXP = new RegExp('<(\\w+)');
+
+  static final _CUSTOM_PARENT_TAG_MAP = const {
+    'body': 'html',
+    'head': 'html',
+    'caption': 'table',
+    'td': 'tr',
+    'colgroup': 'table',
+    'col': 'colgroup',
+    'tr': 'tbody',
+    'tbody': 'table',
+    'tfoot': 'table',
+    'thead': 'table',
+    'track': 'audio',
+  };
+
+  // TODO(jmesserly): this is from dart:html _ElementFactoryProvider...
+  // TODO(jmesserly): have a look at fixing some things in dart:html, in
+  // particular: is the parent tag map complete? Is it faster without regexp?
+  // TODO(jmesserly): for our version we can do something smarter in the parser.
+  // All we really need is to set the correct parse state.
+  factory Element.html(String html) {
+
+    // TODO(jacobr): this method can be made more robust and performant.
+    // 1) Cache the dummy parent elements required to use innerHTML rather than
+    //    creating them every call.
+    // 2) Verify that the html does not contain leading or trailing text nodes.
+    // 3) Verify that the html does not contain both <head> and <body> tags.
+    // 4) Detatch the created element from its dummy parent.
+    String parentTag = 'div';
+    String tag;
+    final match = _START_TAG_REGEXP.firstMatch(html);
+    if (match != null) {
+      tag = match.group(1).toLowerCase();
+      if (_CUSTOM_PARENT_TAG_MAP.containsKey(tag)) {
+        parentTag = _CUSTOM_PARENT_TAG_MAP[tag];
+      }
+    }
+
+    var fragment = parseFragment(html, container: parentTag);
+    Element element;
+    if (fragment.children.length == 1) {
+      element = fragment.children[0];
+    } else if (parentTag == 'html' && fragment.children.length == 2) {
+      // You'll always get a head and a body when starting from html.
+      element = fragment.children[tag == 'head' ? 0 : 1];
+    } else {
+      throw new ArgumentError('HTML had ${fragment.children.length} '
+          'top level elements but 1 expected');
+    }
+    element.remove();
+    return element;
+  }
+
+  int get nodeType => Node.ELEMENT_NODE;
+
+  // TODO(jmesserly): we can make this faster
+  Element get previousElementSibling {
+    if (parentNode == null) return null;
+    var siblings = parentNode.nodes;
+    for (int i = siblings.indexOf(this) - 1; i >= 0; i--) {
+      var s = siblings[i];
+      if (s is Element) return s;
+    }
+    return null;
+  }
+
+  Element get nextElementSibling {
+    if (parentNode == null) return null;
+    var siblings = parentNode.nodes;
+    for (int i = siblings.indexOf(this) + 1; i < siblings.length; i++) {
+      var s = siblings[i];
+      if (s is Element) return s;
+    }
+    return null;
+  }
+
+  String toString() {
+    var prefix = Namespaces.getPrefix(namespaceUri);
+    return "<${prefix == null ? '' : '$prefix '}$localName>";
+  }
+
+  String get text => _getText(this);
+  set text(String value) => _setText(this, value);
+
+  /// Returns a fragment of HTML or XML that represents the element and its
+  /// contents.
+  String get outerHtml => _outerHtml;
+
+  /// Returns a fragment of HTML or XML that represents the element's contents.
+  /// Can be set, to replace the contents of the element with nodes parsed from
+  /// the given string.
+  String get innerHtml => _innerHtml;
+  // TODO(jmesserly): deprecate in favor of:
+  // <https://api.dartlang.org/apidocs/channels/stable/#dart-dom-html.Element@id_setInnerHtml>
+  set innerHtml(String value) {
+    nodes.clear();
+    // TODO(jmesserly): should be able to get the same effect by adding the
+    // fragment directly.
+    nodes.addAll(parseFragment(value, container: localName).nodes);
+  }
+
+  void _addOuterHtml(StringBuffer str) {
+    // http://www.whatwg.org/specs/web-apps/current-work/multipage/the-end.html#serializing-html-fragments
+    // Element is the most complicated one.
+    str.write('<');
+    str.write(_getSerializationPrefix(namespaceUri));
+    str.write(localName);
+
+    if (attributes.length > 0) {
+      attributes.forEach((key, v) {
+        // Note: AttributeName.toString handles serialization of attribute
+        // namespace, if needed.
+        str.write(' ');
+        str.write(key);
+        str.write('="');
+        str.write(htmlSerializeEscape(v, attributeMode: true));
+        str.write('"');
+      });
+    }
+
+    str.write('>');
+
+    if (nodes.length > 0) {
+      if (localName == 'pre' ||
+          localName == 'textarea' ||
+          localName == 'listing') {
+        final first = nodes[0];
+        if (first is Text && first.data.startsWith('\n')) {
+          // These nodes will remove a leading \n at parse time, so if we still
+          // have one, it means we started with two. Add it back.
+          str.write('\n');
+        }
+      }
+
+      _addInnerHtml(str);
+    }
+
+    // void elements must not have an end tag
+    // http://dev.w3.org/html5/markup/syntax.html#void-elements
+    if (!isVoidElement(localName)) str.write('</$localName>');
+  }
+
+  static String _getSerializationPrefix(String uri) {
+    if (uri == null ||
+        uri == Namespaces.html ||
+        uri == Namespaces.mathml ||
+        uri == Namespaces.svg) {
+      return '';
+    }
+    var prefix = Namespaces.getPrefix(uri);
+    // TODO(jmesserly): the spec doesn't define "qualified name".
+    // I'm not sure if this is correct, but it should parse reasonably.
+    return prefix == null ? '' : '$prefix:';
+  }
+
+  Element clone(bool deep) {
+    var result = new Element._(localName, namespaceUri)
+      ..attributes = new LinkedHashMap.from(attributes);
+    return _clone(result, deep);
+  }
+
+  // http://dom.spec.whatwg.org/#dom-element-id
+  String get id {
+    var result = attributes['id'];
+    return result != null ? result : '';
+  }
+
+  set id(String value) {
+    attributes['id'] = '$value';
+  }
+
+  // http://dom.spec.whatwg.org/#dom-element-classname
+  String get className {
+    var result = attributes['class'];
+    return result != null ? result : '';
+  }
+
+  set className(String value) {
+    attributes['class'] = '$value';
+  }
+
+  /**
+   * The set of CSS classes applied to this element.
+   *
+   * This set makes it easy to add, remove or toggle the classes applied to
+   * this element.
+   *
+   *     element.classes.add('selected');
+   *     element.classes.toggle('isOnline');
+   *     element.classes.remove('selected');
+   */
+  CssClassSet get classes => new ElementCssClassSet(this);
+}
+
+class Comment extends Node {
+  String data;
+
+  Comment(this.data) : super._();
+
+  int get nodeType => Node.COMMENT_NODE;
+
+  String toString() => "<!-- $data -->";
+
+  void _addOuterHtml(StringBuffer str) {
+    str.write("<!--$data-->");
+  }
+
+  Comment clone(bool deep) => new Comment(data);
+
+  String get text => data;
+  set text(String value) {
+    this.data = value;
+  }
+}
+
+// TODO(jmesserly): fix this to extend one of the corelib classes if possible.
+// (The requirement to remove the node from the old node list makes it tricky.)
+// TODO(jmesserly): is there any way to share code with the _NodeListImpl?
+class NodeList extends ListProxy<Node> {
+  // Note: this is conceptually final, but because of circular reference
+  // between Node and NodeList we initialize it after construction.
+  Node _parent;
+
+  NodeList._();
+
+  Node get first => this[0];
+
+  Node _setParent(Node node) {
+    // Note: we need to remove the node from its previous parent node, if any,
+    // before updating its parent pointer to point at our parent.
+    node.remove();
+    node.parentNode = _parent;
+    return node;
+  }
+
+  void add(Node value) {
+    if (value is DocumentFragment) {
+      addAll(value.nodes);
+    } else {
+      super.add(_setParent(value));
+    }
+  }
+
+  void addLast(Node value) => add(value);
+
+  void addAll(Iterable<Node> collection) {
+    // Note: we need to be careful if collection is another NodeList.
+    // In particular:
+    //   1. we need to copy the items before updating their parent pointers,
+    //     _flattenDocFragments does a copy internally.
+    //   2. we should update parent pointers in reverse order. That way they
+    //      are removed from the original NodeList (if any) from the end, which
+    //      is faster.
+    var list = _flattenDocFragments(collection);
+    for (var node in list.reversed) _setParent(node);
+    super.addAll(list);
+  }
+
+  void insert(int index, Node value) {
+    if (value is DocumentFragment) {
+      insertAll(index, value.nodes);
+    } else {
+      super.insert(index, _setParent(value));
+    }
+  }
+
+  Node removeLast() => super.removeLast()..parentNode = null;
+
+  Node removeAt(int i) => super.removeAt(i)..parentNode = null;
+
+  void clear() {
+    for (var node in this) node.parentNode = null;
+    super.clear();
+  }
+
+  void operator []=(int index, Node value) {
+    if (value is DocumentFragment) {
+      removeAt(index);
+      insertAll(index, value.nodes);
+    } else {
+      this[index].parentNode = null;
+      super[index] = _setParent(value);
+    }
+  }
+
+  // TODO(jmesserly): These aren't implemented in DOM _NodeListImpl, see
+  // http://code.google.com/p/dart/issues/detail?id=5371
+  void setRange(int start, int rangeLength, Iterable<Node> from,
+      [int startFrom = 0]) {
+    List<Node> from_ = from as List<Node>;
+    if (from_ is NodeList) {
+      // Note: this is presumed to make a copy
+      from_ = from_.sublist(startFrom, startFrom + rangeLength);
+    }
+    // Note: see comment in [addAll]. We need to be careful about the order of
+    // operations if [from] is also a NodeList.
+    for (int i = rangeLength - 1; i >= 0; i--) {
+      this[start + i] = from_[startFrom + i];
+    }
+  }
+
+  void replaceRange(int start, int end, Iterable<Node> newContents) {
+    removeRange(start, end);
+    insertAll(start, newContents);
+  }
+
+  void removeRange(int start, int rangeLength) {
+    for (int i = start; i < rangeLength; i++) this[i].parentNode = null;
+    super.removeRange(start, rangeLength);
+  }
+
+  void removeWhere(bool test(Node e)) {
+    for (var node in where(test)) {
+      node.parentNode = null;
+    }
+    super.removeWhere(test);
+  }
+
+  void retainWhere(bool test(Node e)) {
+    for (var node in where((n) => !test(n))) {
+      node.parentNode = null;
+    }
+    super.retainWhere(test);
+  }
+
+  void insertAll(int index, Iterable<Node> collection) {
+    // Note: we need to be careful how we copy nodes. See note in addAll.
+    var list = _flattenDocFragments(collection);
+    for (var node in list.reversed) _setParent(node);
+    super.insertAll(index, list);
+  }
+
+  List<Node> _flattenDocFragments(Iterable<Node> collection) {
+    // Note: this function serves two purposes:
+    //  * it flattens document fragments
+    //  * it creates a copy of [collections] when `collection is NodeList`.
+    var result = <Node>[];
+    for (var node in collection) {
+      if (node is DocumentFragment) {
+        result.addAll(node.nodes);
+      } else {
+        result.add(node);
+      }
+    }
+    return result;
+  }
+}
+
+/// An indexable collection of a node's descendants in the document tree,
+/// filtered so that only elements are in the collection.
+// TODO(jmesserly): this was copied from dart:html
+// TODO(jmesserly): "implements List<Element>" is a workaround for analyzer bug.
+class FilteredElementList extends IterableBase<Element> with ListMixin<Element>
+    implements List<Element> {
+  final List<Node> _childNodes;
+
+  /// Creates a collection of the elements that descend from a node.
+  ///
+  /// Example usage:
+  ///
+  ///     var filteredElements = new FilteredElementList(query("#container"));
+  ///     // filteredElements is [a, b, c].
+  FilteredElementList(Node node)
+      : _childNodes = node.nodes;
+
+
+  // We can't memoize this, since it's possible that children will be messed
+  // with externally to this class.
+  //
+  // TODO(nweiz): we don't always need to create a new list. For example
+  // forEach, every, any, ... could directly work on the _childNodes.
+  List<Element> get _filtered =>
+      new List<Element>.from(_childNodes.where((n) => n is Element));
+
+  void forEach(void f(Element element)) {
+    _filtered.forEach(f);
+  }
+
+  void operator []=(int index, Element value) {
+    this[index].replaceWith(value);
+  }
+
+  void set length(int newLength) {
+    final len = this.length;
+    if (newLength >= len) {
+      return;
+    } else if (newLength < 0) {
+      throw new ArgumentError("Invalid list length");
+    }
+
+    removeRange(newLength, len);
+  }
+
+  String join([String separator = ""]) => _filtered.join(separator);
+
+  void add(Element value) {
+    _childNodes.add(value);
+  }
+
+  void addAll(Iterable<Element> iterable) {
+    for (Element element in iterable) {
+      add(element);
+    }
+  }
+
+  bool contains(Object element) {
+    return element is Element && _childNodes.contains(element);
+  }
+
+  Iterable<Element> get reversed => _filtered.reversed;
+
+  void sort([int compare(Element a, Element b)]) {
+    throw new UnsupportedError('TODO(jacobr): should we impl?');
+  }
+
+  void setRange(int start, int end, Iterable<Element> iterable,
+      [int skipCount = 0]) {
+    throw new UnimplementedError();
+  }
+
+  void fillRange(int start, int end, [Element fillValue]) {
+    throw new UnimplementedError();
+  }
+
+  void replaceRange(int start, int end, Iterable<Element> iterable) {
+    throw new UnimplementedError();
+  }
+
+  void removeRange(int start, int end) {
+    _filtered.sublist(start, end).forEach((el) => el.remove());
+  }
+
+  void clear() {
+    // Currently, ElementList#clear clears even non-element nodes, so we follow
+    // that behavior.
+    _childNodes.clear();
+  }
+
+  Element removeLast() {
+    final result = this.last;
+    if (result != null) {
+      result.remove();
+    }
+    return result;
+  }
+
+  Iterable/*<T>*/ map/*<T>*/(/*=T*/ f(Element element)) => _filtered.map(f);
+  Iterable<Element> where(bool f(Element element)) => _filtered.where(f);
+  Iterable/*<T>*/ expand/*<T>*/(Iterable/*<T>*/ f(Element element)) =>
+      _filtered.expand(f);
+
+  void insert(int index, Element value) {
+    _childNodes.insert(index, value);
+  }
+
+  void insertAll(int index, Iterable<Element> iterable) {
+    _childNodes.insertAll(index, iterable);
+  }
+
+  Element removeAt(int index) {
+    final result = this[index];
+    result.remove();
+    return result;
+  }
+
+  bool remove(Object element) {
+    if (element is! Element) return false;
+    for (int i = 0; i < length; i++) {
+      Element indexElement = this[i];
+      if (identical(indexElement, element)) {
+        indexElement.remove();
+        return true;
+      }
+    }
+    return false;
+  }
+
+  Element reduce(Element combine(Element value, Element element)) {
+    return _filtered.reduce(combine);
+  }
+
+  dynamic/*=T*/ fold/*<T>*/(var/*=T*/ initialValue,
+      dynamic/*=T*/ combine(var/*=T*/ previousValue, Element element)) {
+    return _filtered.fold(initialValue, combine);
+  }
+
+  bool every(bool f(Element element)) => _filtered.every(f);
+  bool any(bool f(Element element)) => _filtered.any(f);
+  List<Element> toList({bool growable: true}) =>
+      new List<Element>.from(this, growable: growable);
+  Set<Element> toSet() => new Set<Element>.from(this);
+  Element firstWhere(bool test(Element value), {Element orElse()}) {
+    return _filtered.firstWhere(test, orElse: orElse);
+  }
+
+  Element lastWhere(bool test(Element value), {Element orElse()}) {
+    return _filtered.lastWhere(test, orElse: orElse);
+  }
+
+  Element singleWhere(bool test(Element value)) {
+    return _filtered.singleWhere(test);
+  }
+
+  Element elementAt(int index) {
+    return this[index];
+  }
+
+  bool get isEmpty => _filtered.isEmpty;
+  int get length => _filtered.length;
+  Element operator [](int index) => _filtered[index];
+  Iterator<Element> get iterator => _filtered.iterator;
+  List<Element> sublist(int start, [int end]) => _filtered.sublist(start, end);
+  Iterable<Element> getRange(int start, int end) =>
+      _filtered.getRange(start, end);
+  // TODO(sigmund): this should be typed Element, but we currently run into a
+  // bug where ListMixin<E>.indexOf() expects Object as the argument.
+  int indexOf(element, [int start = 0]) =>
+      _filtered.indexOf(element, start);
+
+  // TODO(sigmund): this should be typed Element, but we currently run into a
+  // bug where ListMixin<E>.lastIndexOf() expects Object as the argument.
+  int lastIndexOf(element, [int start = null]) {
+    if (start == null) start = length - 1;
+    return _filtered.lastIndexOf(element, start);
+  }
+
+  Element get first => _filtered.first;
+
+  Element get last => _filtered.last;
+
+  Element get single => _filtered.single;
+}
+
+// http://dom.spec.whatwg.org/#dom-node-textcontent
+// For Element and DocumentFragment
+String _getText(Node node) =>
+    (new _ConcatTextVisitor()..visit(node)).toString();
+
+void _setText(Node node, String value) {
+  node.nodes.clear();
+  node.append(new Text(value));
+}
+
+class _ConcatTextVisitor extends TreeVisitor {
+  final _str = new StringBuffer();
+
+  String toString() => _str.toString();
+
+  visitText(Text node) {
+    _str.write(node.data);
+  }
+}
diff --git a/html/lib/dom_parsing.dart b/html/lib/dom_parsing.dart
new file mode 100644
index 0000000..5575dcd
--- /dev/null
+++ b/html/lib/dom_parsing.dart
@@ -0,0 +1,203 @@
+/// This library contains extra APIs that aren't in the DOM, but are useful
+/// when interacting with the parse tree.
+library dom_parsing;
+
+import 'dom.dart';
+import 'src/constants.dart' show rcdataElements;
+
+/// A simple tree visitor for the DOM nodes.
+class TreeVisitor {
+  visit(Node node) {
+    switch (node.nodeType) {
+      case Node.ELEMENT_NODE:
+        return visitElement(node);
+      case Node.TEXT_NODE:
+        return visitText(node);
+      case Node.COMMENT_NODE:
+        return visitComment(node);
+      case Node.DOCUMENT_FRAGMENT_NODE:
+        return visitDocumentFragment(node);
+      case Node.DOCUMENT_NODE:
+        return visitDocument(node);
+      case Node.DOCUMENT_TYPE_NODE:
+        return visitDocumentType(node);
+      default:
+        throw new UnsupportedError('DOM node type ${node.nodeType}');
+    }
+  }
+
+  visitChildren(Node node) {
+    // Allow for mutations (remove works) while iterating.
+    for (var child in node.nodes.toList()) visit(child);
+  }
+
+  /// The fallback handler if the more specific visit method hasn't been
+  /// overriden. Only use this from a subclass of [TreeVisitor], otherwise
+  /// call [visit] instead.
+  visitNodeFallback(Node node) => visitChildren(node);
+
+  visitDocument(Document node) => visitNodeFallback(node);
+
+  visitDocumentType(DocumentType node) => visitNodeFallback(node);
+
+  visitText(Text node) => visitNodeFallback(node);
+
+  // TODO(jmesserly): visit attributes.
+  visitElement(Element node) => visitNodeFallback(node);
+
+  visitComment(Comment node) => visitNodeFallback(node);
+
+  visitDocumentFragment(DocumentFragment node) => visitNodeFallback(node);
+}
+
+/// Converts the DOM tree into an HTML string with code markup suitable for
+/// displaying the HTML's source code with CSS colors for different parts of the
+/// markup. See also [CodeMarkupVisitor].
+String htmlToCodeMarkup(Node node) {
+  return (new CodeMarkupVisitor()..visit(node)).toString();
+}
+
+/// Converts the DOM tree into an HTML string with code markup suitable for
+/// displaying the HTML's source code with CSS colors for different parts of the
+/// markup. See also [htmlToCodeMarkup].
+class CodeMarkupVisitor extends TreeVisitor {
+  final StringBuffer _str;
+
+  CodeMarkupVisitor() : _str = new StringBuffer();
+
+  String toString() => _str.toString();
+
+  visitDocument(Document node) {
+    _str.write("<pre>");
+    visitChildren(node);
+    _str.write("</pre>");
+  }
+
+  visitDocumentType(DocumentType node) {
+    _str.write('<code class="markup doctype">&lt;!DOCTYPE ${node.name}>'
+        '</code>');
+  }
+
+  visitText(Text node) {
+    writeTextNodeAsHtml(_str, node);
+  }
+
+  visitElement(Element node) {
+    final tag = node.localName;
+    _str.write('&lt;<code class="markup element-name">$tag</code>');
+    if (node.attributes.length > 0) {
+      node.attributes.forEach((key, v) {
+        v = htmlSerializeEscape(v, attributeMode: true);
+        _str.write(' <code class="markup attribute-name">$key</code>'
+            '=<code class="markup attribute-value">"$v"</code>');
+      });
+    }
+    if (node.nodes.length > 0) {
+      _str.write(">");
+      visitChildren(node);
+    } else if (isVoidElement(tag)) {
+      _str.write(">");
+      return;
+    }
+    _str.write('&lt;/<code class="markup element-name">$tag</code>>');
+  }
+
+  visitComment(Comment node) {
+    var data = htmlSerializeEscape(node.data);
+    _str.write('<code class="markup comment">&lt;!--${data}--></code>');
+  }
+}
+
+// TODO(jmesserly): reconcile this with dart:web htmlEscape.
+// This one might be more useful, as it is HTML5 spec compliant.
+/// Escapes [text] for use in the
+/// [HTML fragment serialization algorithm][1]. In particular, as described
+/// in the [specification][2]:
+///
+/// - Replace any occurrence of the `&` character by the string `&amp;`.
+/// - Replace any occurrences of the U+00A0 NO-BREAK SPACE character by the
+///   string `&nbsp;`.
+/// - If the algorithm was invoked in [attributeMode], replace any occurrences
+///   of the `"` character by the string `&quot;`.
+/// - If the algorithm was not invoked in [attributeMode], replace any
+///   occurrences of the `<` character by the string `&lt;`, and any occurrences
+///   of the `>` character by the string `&gt;`.
+///
+/// [1]: http://www.whatwg.org/specs/web-apps/current-work/multipage/the-end.html#serializing-html-fragments
+/// [2]: http://www.whatwg.org/specs/web-apps/current-work/multipage/the-end.html#escapingString
+String htmlSerializeEscape(String text, {bool attributeMode: false}) {
+  // TODO(jmesserly): is it faster to build up a list of codepoints?
+  // StringBuffer seems cleaner assuming Dart can unbox 1-char strings.
+  StringBuffer result = null;
+  for (int i = 0; i < text.length; i++) {
+    var ch = text[i];
+    String replace = null;
+    switch (ch) {
+      case '&':
+        replace = '&amp;';
+        break;
+      case '\u00A0' /*NO-BREAK SPACE*/ :
+        replace = '&nbsp;';
+        break;
+      case '"':
+        if (attributeMode) replace = '&quot;';
+        break;
+      case '<':
+        if (!attributeMode) replace = '&lt;';
+        break;
+      case '>':
+        if (!attributeMode) replace = '&gt;';
+        break;
+    }
+    if (replace != null) {
+      if (result == null) result = new StringBuffer(text.substring(0, i));
+      result.write(replace);
+    } else if (result != null) {
+      result.write(ch);
+    }
+  }
+
+  return result != null ? result.toString() : text;
+}
+
+/// Returns true if this tag name is a void element.
+/// This method is useful to a pretty printer, because void elements must not
+/// have an end tag.
+/// See also: <http://dev.w3.org/html5/markup/syntax.html#void-elements>.
+bool isVoidElement(String tagName) {
+  switch (tagName) {
+    case "area":
+    case "base":
+    case "br":
+    case "col":
+    case "command":
+    case "embed":
+    case "hr":
+    case "img":
+    case "input":
+    case "keygen":
+    case "link":
+    case "meta":
+    case "param":
+    case "source":
+    case "track":
+    case "wbr":
+      return true;
+  }
+  return false;
+}
+
+/// Serialize text node according to:
+/// <http://www.whatwg.org/specs/web-apps/current-work/multipage/the-end.html#html-fragment-serialization-algorithm>
+void writeTextNodeAsHtml(StringBuffer str, Text node) {
+  // Don't escape text for certain elements, notably <script>.
+  final parent = node.parentNode;
+  if (parent is Element) {
+    var tag = parent.localName;
+    if (rcdataElements.contains(tag) || tag == 'plaintext') {
+      str.write(node.data);
+      return;
+    }
+  }
+  str.write(htmlSerializeEscape(node.data));
+}
diff --git a/html/lib/parser.dart b/html/lib/parser.dart
new file mode 100644
index 0000000..0575b3d
--- /dev/null
+++ b/html/lib/parser.dart
@@ -0,0 +1,3933 @@
+/// This library has a parser for HTML5 documents, that lets you parse HTML
+/// easily from a script or server side application:
+///
+///     import 'package:html/parser.dart' show parse;
+///     import 'package:html/dom.dart';
+///     main() {
+///       var document = parse(
+///           '<body>Hello world! <a href="www.html5rocks.com">HTML5 rocks!');
+///       print(document.outerHtml);
+///     }
+///
+/// The resulting document you get back has a DOM-like API for easy tree
+/// traversal and manipulation.
+library parser;
+
+import 'dart:collection';
+import 'dart:math';
+import 'package:source_span/source_span.dart';
+
+import 'src/treebuilder.dart';
+import 'src/constants.dart';
+import 'src/encoding_parser.dart';
+import 'src/token.dart';
+import 'src/tokenizer.dart';
+import 'src/utils.dart';
+import 'dom.dart';
+
+/// Parse the [input] html5 document into a tree. The [input] can be
+/// a [String], [List<int>] of bytes or an [HtmlTokenizer].
+///
+/// If [input] is not a [HtmlTokenizer], you can optionally specify the file's
+/// [encoding], which must be a string. If specified that encoding will be
+/// used regardless of any BOM or later declaration (such as in a meta element).
+///
+/// Set [generateSpans] if you want to generate [SourceSpan]s, otherwise the
+/// [Node.sourceSpan] property will be `null`. When using [generateSpans] you
+/// can additionally pass [sourceUrl] to indicate where the [input] was
+/// extracted from.
+Document parse(input,
+    {String encoding, bool generateSpans: false, String sourceUrl}) {
+  var p = new HtmlParser(input,
+      encoding: encoding, generateSpans: generateSpans, sourceUrl: sourceUrl);
+  return p.parse();
+}
+
+/// Parse the [input] html5 document fragment into a tree. The [input] can be
+/// a [String], [List<int>] of bytes or an [HtmlTokenizer]. The [container]
+/// element can optionally be specified, otherwise it defaults to "div".
+///
+/// If [input] is not a [HtmlTokenizer], you can optionally specify the file's
+/// [encoding], which must be a string. If specified, that encoding will be used,
+/// regardless of any BOM or later declaration (such as in a meta element).
+///
+/// Set [generateSpans] if you want to generate [SourceSpan]s, otherwise the
+/// [Node.sourceSpan] property will be `null`. When using [generateSpans] you can
+/// additionally pass [sourceUrl] to indicate where the [input] was extracted
+/// from.
+DocumentFragment parseFragment(input, {String container: "div", String encoding,
+    bool generateSpans: false, String sourceUrl}) {
+  var p = new HtmlParser(input,
+      encoding: encoding, generateSpans: generateSpans, sourceUrl: sourceUrl);
+  return p.parseFragment(container);
+}
+
+/// Parser for HTML, which generates a tree structure from a stream of
+/// (possibly malformed) characters.
+class HtmlParser {
+  /// Raise an exception on the first error encountered.
+  final bool strict;
+
+  /// True to generate [SourceSpan]s for the [Node.sourceSpan] property.
+  final bool generateSpans;
+
+  final HtmlTokenizer tokenizer;
+
+  final TreeBuilder tree;
+
+  final List<ParseError> errors = <ParseError>[];
+
+  String container;
+
+  bool firstStartTag = false;
+
+  // TODO(jmesserly): use enum?
+  /// "quirks" / "limited quirks" / "no quirks"
+  String compatMode = "no quirks";
+
+  /// innerHTML container when parsing document fragment.
+  String innerHTML;
+
+  Phase phase;
+
+  Phase lastPhase;
+
+  Phase originalPhase;
+
+  Phase beforeRCDataPhase;
+
+  bool framesetOK;
+
+  // These fields hold the different phase singletons. At any given time one
+  // of them will be active.
+  InitialPhase _initialPhase;
+  BeforeHtmlPhase _beforeHtmlPhase;
+  BeforeHeadPhase _beforeHeadPhase;
+  InHeadPhase _inHeadPhase;
+  AfterHeadPhase _afterHeadPhase;
+  InBodyPhase _inBodyPhase;
+  TextPhase _textPhase;
+  InTablePhase _inTablePhase;
+  InTableTextPhase _inTableTextPhase;
+  InCaptionPhase _inCaptionPhase;
+  InColumnGroupPhase _inColumnGroupPhase;
+  InTableBodyPhase _inTableBodyPhase;
+  InRowPhase _inRowPhase;
+  InCellPhase _inCellPhase;
+  InSelectPhase _inSelectPhase;
+  InSelectInTablePhase _inSelectInTablePhase;
+  InForeignContentPhase _inForeignContentPhase;
+  AfterBodyPhase _afterBodyPhase;
+  InFramesetPhase _inFramesetPhase;
+  AfterFramesetPhase _afterFramesetPhase;
+  AfterAfterBodyPhase _afterAfterBodyPhase;
+  AfterAfterFramesetPhase _afterAfterFramesetPhase;
+
+  /// Create an HtmlParser and configure the [tree] builder and [strict] mode.
+  /// The [input] can be a [String], [List<int>] of bytes or an [HtmlTokenizer].
+  ///
+  /// If [input] is not a [HtmlTokenizer], you can specify a few more arguments.
+  ///
+  /// The [encoding] must be a string that indicates the encoding. If specified,
+  /// that encoding will be used, regardless of any BOM or later declaration
+  /// (such as in a meta element).
+  ///
+  /// Set [parseMeta] to false if you want to disable parsing the meta element.
+  ///
+  /// Set [lowercaseElementName] or [lowercaseAttrName] to false to disable the
+  /// automatic conversion of element and attribute names to lower case. Note
+  /// that standard way to parse HTML is to lowercase, which is what the browser
+  /// DOM will do if you request [Node.outerHTML], for example.
+  HtmlParser(input, {String encoding, bool parseMeta: true,
+      bool lowercaseElementName: true, bool lowercaseAttrName: true,
+      this.strict: false, bool generateSpans: false, String sourceUrl,
+      TreeBuilder tree})
+      : generateSpans = generateSpans,
+        tree = tree != null ? tree : new TreeBuilder(true),
+        tokenizer = (input is HtmlTokenizer
+            ? input
+            : new HtmlTokenizer(input,
+                encoding: encoding,
+                parseMeta: parseMeta,
+                lowercaseElementName: lowercaseElementName,
+                lowercaseAttrName: lowercaseAttrName,
+                generateSpans: generateSpans,
+                sourceUrl: sourceUrl)) {
+    tokenizer.parser = this;
+    _initialPhase = new InitialPhase(this);
+    _beforeHtmlPhase = new BeforeHtmlPhase(this);
+    _beforeHeadPhase = new BeforeHeadPhase(this);
+    _inHeadPhase = new InHeadPhase(this);
+    // TODO(jmesserly): html5lib did not implement the no script parsing mode
+    // More information here:
+    // http://www.whatwg.org/specs/web-apps/current-work/multipage/parsing.html#scripting-flag
+    // http://www.whatwg.org/specs/web-apps/current-work/multipage/tree-construction.html#parsing-main-inheadnoscript
+    // "inHeadNoscript": new InHeadNoScriptPhase(this);
+    _afterHeadPhase = new AfterHeadPhase(this);
+    _inBodyPhase = new InBodyPhase(this);
+    _textPhase = new TextPhase(this);
+    _inTablePhase = new InTablePhase(this);
+    _inTableTextPhase = new InTableTextPhase(this);
+    _inCaptionPhase = new InCaptionPhase(this);
+    _inColumnGroupPhase = new InColumnGroupPhase(this);
+    _inTableBodyPhase = new InTableBodyPhase(this);
+    _inRowPhase = new InRowPhase(this);
+    _inCellPhase = new InCellPhase(this);
+    _inSelectPhase = new InSelectPhase(this);
+    _inSelectInTablePhase = new InSelectInTablePhase(this);
+    _inForeignContentPhase = new InForeignContentPhase(this);
+    _afterBodyPhase = new AfterBodyPhase(this);
+    _inFramesetPhase = new InFramesetPhase(this);
+    _afterFramesetPhase = new AfterFramesetPhase(this);
+    _afterAfterBodyPhase = new AfterAfterBodyPhase(this);
+    _afterAfterFramesetPhase = new AfterAfterFramesetPhase(this);
+  }
+
+  bool get innerHTMLMode => innerHTML != null;
+
+  /// Parse an html5 document into a tree.
+  /// After parsing, [errors] will be populated with parse errors, if any.
+  Document parse() {
+    innerHTML = null;
+    _parse();
+    return tree.getDocument();
+  }
+
+  /// Parse an html5 document fragment into a tree.
+  /// Pass a [container] to change the type of the containing element.
+  /// After parsing, [errors] will be populated with parse errors, if any.
+  DocumentFragment parseFragment([String container = "div"]) {
+    if (container == null) throw new ArgumentError('container');
+    innerHTML = container.toLowerCase();
+    _parse();
+    return tree.getFragment();
+  }
+
+  void _parse() {
+    reset();
+
+    while (true) {
+      try {
+        mainLoop();
+        break;
+      } on ReparseException catch (_) {
+        // Note: this happens if we start parsing but the character encoding
+        // changes. So we should only need to restart very early in the parse.
+        reset();
+      }
+    }
+  }
+
+  void reset() {
+    tokenizer.reset();
+
+    tree.reset();
+    firstStartTag = false;
+    errors.clear();
+    // "quirks" / "limited quirks" / "no quirks"
+    compatMode = "no quirks";
+
+    if (innerHTMLMode) {
+      if (cdataElements.contains(innerHTML)) {
+        tokenizer.state = tokenizer.rcdataState;
+      } else if (rcdataElements.contains(innerHTML)) {
+        tokenizer.state = tokenizer.rawtextState;
+      } else if (innerHTML == 'plaintext') {
+        tokenizer.state = tokenizer.plaintextState;
+      } else {
+        // state already is data state
+        // tokenizer.state = tokenizer.dataState;
+      }
+      phase = _beforeHtmlPhase;
+      _beforeHtmlPhase.insertHtmlElement();
+      resetInsertionMode();
+    } else {
+      phase = _initialPhase;
+    }
+
+    lastPhase = null;
+    beforeRCDataPhase = null;
+    framesetOK = true;
+  }
+
+  bool isHTMLIntegrationPoint(Element element) {
+    if (element.localName == "annotation-xml" &&
+        element.namespaceUri == Namespaces.mathml) {
+      var enc = element.attributes["encoding"];
+      if (enc != null) enc = asciiUpper2Lower(enc);
+      return enc == "text/html" || enc == "application/xhtml+xml";
+    } else {
+      return htmlIntegrationPointElements
+          .contains(new Pair(element.namespaceUri, element.localName));
+    }
+  }
+
+  bool isMathMLTextIntegrationPoint(Element element) {
+    return mathmlTextIntegrationPointElements
+        .contains(new Pair(element.namespaceUri, element.localName));
+  }
+
+  bool inForeignContent(Token token, int type) {
+    if (tree.openElements.length == 0) return false;
+
+    var node = tree.openElements.last;
+    if (node.namespaceUri == tree.defaultNamespace) return false;
+
+    if (isMathMLTextIntegrationPoint(node)) {
+      if (type == TokenKind.startTag &&
+          (token as StartTagToken).name != "mglyph" &&
+          (token as StartTagToken).name != "malignmark") {
+        return false;
+      }
+      if (type == TokenKind.characters || type == TokenKind.spaceCharacters) {
+        return false;
+      }
+    }
+
+    if (node.localName == "annotation-xml" &&
+        type == TokenKind.startTag &&
+        (token as StartTagToken).name == "svg") {
+      return false;
+    }
+
+    if (isHTMLIntegrationPoint(node)) {
+      if (type == TokenKind.startTag ||
+          type == TokenKind.characters ||
+          type == TokenKind.spaceCharacters) {
+        return false;
+      }
+    }
+
+    return true;
+  }
+
+  void mainLoop() {
+    while (tokenizer.moveNext()) {
+      var token = tokenizer.current;
+      var newToken = token;
+      int type;
+      while (newToken != null) {
+        type = newToken.kind;
+
+        // Note: avoid "is" test here, see http://dartbug.com/4795
+        if (type == TokenKind.parseError) {
+          ParseErrorToken error = newToken;
+          parseError(error.span, error.data, error.messageParams);
+          newToken = null;
+        } else {
+          Phase phase_ = phase;
+          if (inForeignContent(token, type)) {
+            phase_ = _inForeignContentPhase;
+          }
+
+          switch (type) {
+            case TokenKind.characters:
+              newToken = phase_.processCharacters(newToken);
+              break;
+            case TokenKind.spaceCharacters:
+              newToken = phase_.processSpaceCharacters(newToken);
+              break;
+            case TokenKind.startTag:
+              newToken = phase_.processStartTag(newToken);
+              break;
+            case TokenKind.endTag:
+              newToken = phase_.processEndTag(newToken);
+              break;
+            case TokenKind.comment:
+              newToken = phase_.processComment(newToken);
+              break;
+            case TokenKind.doctype:
+              newToken = phase_.processDoctype(newToken);
+              break;
+          }
+        }
+      }
+
+      if (token is StartTagToken) {
+        if (token.selfClosing && !token.selfClosingAcknowledged) {
+          parseError(token.span, "non-void-element-with-trailing-solidus", {
+            "name": token.name
+          });
+        }
+      }
+    }
+
+    // When the loop finishes it's EOF
+    var reprocess = true;
+    var reprocessPhases = [];
+    while (reprocess) {
+      reprocessPhases.add(phase);
+      reprocess = phase.processEOF();
+      if (reprocess) {
+        assert(!reprocessPhases.contains(phase));
+      }
+    }
+  }
+
+  /// The last span available. Used for EOF errors if we don't have something
+  /// better.
+  SourceSpan get _lastSpan {
+    if (tokenizer.stream.fileInfo == null) return null;
+    var pos = tokenizer.stream.position;
+    return tokenizer.stream.fileInfo.location(pos).pointSpan();
+  }
+
+  void parseError(SourceSpan span, String errorcode,
+      [Map datavars = const {}]) {
+    if (!generateSpans && span == null) {
+      span = _lastSpan;
+    }
+
+    var err = new ParseError(errorcode, span, datavars);
+    errors.add(err);
+    if (strict) throw err;
+  }
+
+  void adjustMathMLAttributes(StartTagToken token) {
+    var orig = token.data.remove("definitionurl");
+    if (orig != null) {
+      token.data["definitionURL"] = orig;
+    }
+  }
+
+  void adjustSVGAttributes(StartTagToken token) {
+    final replacements = const {
+      "attributename": "attributeName",
+      "attributetype": "attributeType",
+      "basefrequency": "baseFrequency",
+      "baseprofile": "baseProfile",
+      "calcmode": "calcMode",
+      "clippathunits": "clipPathUnits",
+      "contentscripttype": "contentScriptType",
+      "contentstyletype": "contentStyleType",
+      "diffuseconstant": "diffuseConstant",
+      "edgemode": "edgeMode",
+      "externalresourcesrequired": "externalResourcesRequired",
+      "filterres": "filterRes",
+      "filterunits": "filterUnits",
+      "glyphref": "glyphRef",
+      "gradienttransform": "gradientTransform",
+      "gradientunits": "gradientUnits",
+      "kernelmatrix": "kernelMatrix",
+      "kernelunitlength": "kernelUnitLength",
+      "keypoints": "keyPoints",
+      "keysplines": "keySplines",
+      "keytimes": "keyTimes",
+      "lengthadjust": "lengthAdjust",
+      "limitingconeangle": "limitingConeAngle",
+      "markerheight": "markerHeight",
+      "markerunits": "markerUnits",
+      "markerwidth": "markerWidth",
+      "maskcontentunits": "maskContentUnits",
+      "maskunits": "maskUnits",
+      "numoctaves": "numOctaves",
+      "pathlength": "pathLength",
+      "patterncontentunits": "patternContentUnits",
+      "patterntransform": "patternTransform",
+      "patternunits": "patternUnits",
+      "pointsatx": "pointsAtX",
+      "pointsaty": "pointsAtY",
+      "pointsatz": "pointsAtZ",
+      "preservealpha": "preserveAlpha",
+      "preserveaspectratio": "preserveAspectRatio",
+      "primitiveunits": "primitiveUnits",
+      "refx": "refX",
+      "refy": "refY",
+      "repeatcount": "repeatCount",
+      "repeatdur": "repeatDur",
+      "requiredextensions": "requiredExtensions",
+      "requiredfeatures": "requiredFeatures",
+      "specularconstant": "specularConstant",
+      "specularexponent": "specularExponent",
+      "spreadmethod": "spreadMethod",
+      "startoffset": "startOffset",
+      "stddeviation": "stdDeviation",
+      "stitchtiles": "stitchTiles",
+      "surfacescale": "surfaceScale",
+      "systemlanguage": "systemLanguage",
+      "tablevalues": "tableValues",
+      "targetx": "targetX",
+      "targety": "targetY",
+      "textlength": "textLength",
+      "viewbox": "viewBox",
+      "viewtarget": "viewTarget",
+      "xchannelselector": "xChannelSelector",
+      "ychannelselector": "yChannelSelector",
+      "zoomandpan": "zoomAndPan"
+    };
+    for (var originalName in token.data.keys.toList()) {
+      var svgName = replacements[originalName];
+      if (svgName != null) {
+        token.data[svgName] = token.data.remove(originalName);
+      }
+    }
+  }
+
+  void adjustForeignAttributes(StartTagToken token) {
+    // TODO(jmesserly): I don't like mixing non-string objects with strings in
+    // the Node.attributes Map. Is there another solution?
+    final replacements = const {
+      "xlink:actuate":
+          const AttributeName("xlink", "actuate", Namespaces.xlink),
+      "xlink:arcrole":
+          const AttributeName("xlink", "arcrole", Namespaces.xlink),
+      "xlink:href": const AttributeName("xlink", "href", Namespaces.xlink),
+      "xlink:role": const AttributeName("xlink", "role", Namespaces.xlink),
+      "xlink:show": const AttributeName("xlink", "show", Namespaces.xlink),
+      "xlink:title": const AttributeName("xlink", "title", Namespaces.xlink),
+      "xlink:type": const AttributeName("xlink", "type", Namespaces.xlink),
+      "xml:base": const AttributeName("xml", "base", Namespaces.xml),
+      "xml:lang": const AttributeName("xml", "lang", Namespaces.xml),
+      "xml:space": const AttributeName("xml", "space", Namespaces.xml),
+      "xmlns": const AttributeName(null, "xmlns", Namespaces.xmlns),
+      "xmlns:xlink": const AttributeName("xmlns", "xlink", Namespaces.xmlns)
+    };
+
+    for (var originalName in token.data.keys.toList()) {
+      var foreignName = replacements[originalName];
+      if (foreignName != null) {
+        token.data[foreignName] = token.data.remove(originalName);
+      }
+    }
+  }
+
+  void resetInsertionMode() {
+    // The name of this method is mostly historical. (It's also used in the
+    // specification.)
+    for (var node in tree.openElements.reversed) {
+      var nodeName = node.localName;
+      bool last = node == tree.openElements[0];
+      if (last) {
+        assert(innerHTMLMode);
+        nodeName = innerHTML;
+      }
+      // Check for conditions that should only happen in the innerHTML
+      // case
+      switch (nodeName) {
+        case "select":
+        case "colgroup":
+        case "head":
+        case "html":
+          assert(innerHTMLMode);
+          break;
+      }
+      if (!last && node.namespaceUri != tree.defaultNamespace) {
+        continue;
+      }
+      switch (nodeName) {
+        case "select":
+          phase = _inSelectPhase;
+          return;
+        case "td":
+          phase = _inCellPhase;
+          return;
+        case "th":
+          phase = _inCellPhase;
+          return;
+        case "tr":
+          phase = _inRowPhase;
+          return;
+        case "tbody":
+          phase = _inTableBodyPhase;
+          return;
+        case "thead":
+          phase = _inTableBodyPhase;
+          return;
+        case "tfoot":
+          phase = _inTableBodyPhase;
+          return;
+        case "caption":
+          phase = _inCaptionPhase;
+          return;
+        case "colgroup":
+          phase = _inColumnGroupPhase;
+          return;
+        case "table":
+          phase = _inTablePhase;
+          return;
+        case "head":
+          phase = _inBodyPhase;
+          return;
+        case "body":
+          phase = _inBodyPhase;
+          return;
+        case "frameset":
+          phase = _inFramesetPhase;
+          return;
+        case "html":
+          phase = _beforeHeadPhase;
+          return;
+      }
+    }
+    phase = _inBodyPhase;
+  }
+
+  /// Generic RCDATA/RAWTEXT Parsing algorithm
+  /// [contentType] - RCDATA or RAWTEXT
+  void parseRCDataRawtext(Token token, String contentType) {
+    assert(contentType == "RAWTEXT" || contentType == "RCDATA");
+
+    tree.insertElement(token);
+
+    if (contentType == "RAWTEXT") {
+      tokenizer.state = tokenizer.rawtextState;
+    } else {
+      tokenizer.state = tokenizer.rcdataState;
+    }
+
+    originalPhase = phase;
+    phase = _textPhase;
+  }
+}
+
+/// Base class for helper object that implements each phase of processing.
+class Phase {
+  // Order should be (they can be omitted):
+  // * EOF
+  // * Comment
+  // * Doctype
+  // * SpaceCharacters
+  // * Characters
+  // * StartTag
+  //   - startTag* methods
+  // * EndTag
+  //   - endTag* methods
+
+  final HtmlParser parser;
+
+  final TreeBuilder tree;
+
+  Phase(HtmlParser parser)
+      : parser = parser,
+        tree = parser.tree;
+
+  bool processEOF() {
+    throw new UnimplementedError();
+  }
+
+  Token processComment(CommentToken token) {
+    // For most phases the following is correct. Where it's not it will be
+    // overridden.
+    tree.insertComment(token, tree.openElements.last);
+    return null;
+  }
+
+  Token processDoctype(DoctypeToken token) {
+    parser.parseError(token.span, "unexpected-doctype");
+    return null;
+  }
+
+  Token processCharacters(CharactersToken token) {
+    tree.insertText(token.data, token.span);
+    return null;
+  }
+
+  Token processSpaceCharacters(SpaceCharactersToken token) {
+    tree.insertText(token.data, token.span);
+    return null;
+  }
+
+  Token processStartTag(StartTagToken token) {
+    throw new UnimplementedError();
+  }
+
+  Token startTagHtml(StartTagToken token) {
+    if (parser.firstStartTag == false && token.name == "html") {
+      parser.parseError(token.span, "non-html-root");
+    }
+    // XXX Need a check here to see if the first start tag token emitted is
+    // this token... If it's not, invoke parser.parseError().
+    tree.openElements[0].sourceSpan = token.span;
+    token.data.forEach((attr, value) {
+      tree.openElements[0].attributes.putIfAbsent(attr, () => value);
+    });
+    parser.firstStartTag = false;
+    return null;
+  }
+
+  Token processEndTag(EndTagToken token) {
+    throw new UnimplementedError();
+  }
+
+  /// Helper method for popping openElements.
+  void popOpenElementsUntil(EndTagToken token) {
+    String name = token.name;
+    var node = tree.openElements.removeLast();
+    while (node.localName != name) {
+      node = tree.openElements.removeLast();
+    }
+    if (node != null) {
+      node.endSourceSpan = token.span;
+    }
+  }
+}
+
+class InitialPhase extends Phase {
+  InitialPhase(parser) : super(parser);
+
+  Token processSpaceCharacters(SpaceCharactersToken token) {
+    return null;
+  }
+
+  Token processComment(CommentToken token) {
+    tree.insertComment(token, tree.document);
+    return null;
+  }
+
+  Token processDoctype(DoctypeToken token) {
+    var name = token.name;
+    String publicId = token.publicId;
+    var systemId = token.systemId;
+    var correct = token.correct;
+
+    if ((name != "html" ||
+        publicId != null ||
+        systemId != null && systemId != "about:legacy-compat")) {
+      parser.parseError(token.span, "unknown-doctype");
+    }
+
+    if (publicId == null) {
+      publicId = "";
+    }
+
+    tree.insertDoctype(token);
+
+    if (publicId != "") {
+      publicId = asciiUpper2Lower(publicId);
+    }
+
+    if (!correct || token.name != "html" || startsWithAny(publicId, const [
+      "+//silmaril//dtd html pro v0r11 19970101//",
+      "-//advasoft ltd//dtd html 3.0 aswedit + extensions//",
+      "-//as//dtd html 3.0 aswedit + extensions//",
+      "-//ietf//dtd html 2.0 level 1//",
+      "-//ietf//dtd html 2.0 level 2//",
+      "-//ietf//dtd html 2.0 strict level 1//",
+      "-//ietf//dtd html 2.0 strict level 2//",
+      "-//ietf//dtd html 2.0 strict//",
+      "-//ietf//dtd html 2.0//",
+      "-//ietf//dtd html 2.1e//",
+      "-//ietf//dtd html 3.0//",
+      "-//ietf//dtd html 3.2 final//",
+      "-//ietf//dtd html 3.2//",
+      "-//ietf//dtd html 3//",
+      "-//ietf//dtd html level 0//",
+      "-//ietf//dtd html level 1//",
+      "-//ietf//dtd html level 2//",
+      "-//ietf//dtd html level 3//",
+      "-//ietf//dtd html strict level 0//",
+      "-//ietf//dtd html strict level 1//",
+      "-//ietf//dtd html strict level 2//",
+      "-//ietf//dtd html strict level 3//",
+      "-//ietf//dtd html strict//",
+      "-//ietf//dtd html//",
+      "-//metrius//dtd metrius presentational//",
+      "-//microsoft//dtd internet explorer 2.0 html strict//",
+      "-//microsoft//dtd internet explorer 2.0 html//",
+      "-//microsoft//dtd internet explorer 2.0 tables//",
+      "-//microsoft//dtd internet explorer 3.0 html strict//",
+      "-//microsoft//dtd internet explorer 3.0 html//",
+      "-//microsoft//dtd internet explorer 3.0 tables//",
+      "-//netscape comm. corp.//dtd html//",
+      "-//netscape comm. corp.//dtd strict html//",
+      "-//o'reilly and associates//dtd html 2.0//",
+      "-//o'reilly and associates//dtd html extended 1.0//",
+      "-//o'reilly and associates//dtd html extended relaxed 1.0//",
+      "-//softquad software//dtd hotmetal pro 6.0::19990601::extensions to html 4.0//",
+      "-//softquad//dtd hotmetal pro 4.0::19971010::extensions to html 4.0//",
+      "-//spyglass//dtd html 2.0 extended//",
+      "-//sq//dtd html 2.0 hotmetal + extensions//",
+      "-//sun microsystems corp.//dtd hotjava html//",
+      "-//sun microsystems corp.//dtd hotjava strict html//",
+      "-//w3c//dtd html 3 1995-03-24//",
+      "-//w3c//dtd html 3.2 draft//",
+      "-//w3c//dtd html 3.2 final//",
+      "-//w3c//dtd html 3.2//",
+      "-//w3c//dtd html 3.2s draft//",
+      "-//w3c//dtd html 4.0 frameset//",
+      "-//w3c//dtd html 4.0 transitional//",
+      "-//w3c//dtd html experimental 19960712//",
+      "-//w3c//dtd html experimental 970421//",
+      "-//w3c//dtd w3 html//",
+      "-//w3o//dtd w3 html 3.0//",
+      "-//webtechs//dtd mozilla html 2.0//",
+      "-//webtechs//dtd mozilla html//"
+    ]) ||
+        const [
+      "-//w3o//dtd w3 html strict 3.0//en//",
+      "-/w3c/dtd html 4.0 transitional/en",
+      "html"
+    ].contains(publicId) ||
+        startsWithAny(publicId, const [
+      "-//w3c//dtd html 4.01 frameset//",
+      "-//w3c//dtd html 4.01 transitional//"
+    ]) &&
+            systemId == null ||
+        systemId != null &&
+            systemId.toLowerCase() ==
+                "http://www.ibm.com/data/dtd/v11/ibmxhtml1-transitional.dtd") {
+      parser.compatMode = "quirks";
+    } else if (startsWithAny(publicId, const [
+      "-//w3c//dtd xhtml 1.0 frameset//",
+      "-//w3c//dtd xhtml 1.0 transitional//"
+    ]) ||
+        startsWithAny(publicId, const [
+      "-//w3c//dtd html 4.01 frameset//",
+      "-//w3c//dtd html 4.01 transitional//"
+    ]) &&
+        systemId != null) {
+      parser.compatMode = "limited quirks";
+    }
+    parser.phase = parser._beforeHtmlPhase;
+    return null;
+  }
+
+  void anythingElse() {
+    parser.compatMode = "quirks";
+    parser.phase = parser._beforeHtmlPhase;
+  }
+
+  Token processCharacters(CharactersToken token) {
+    parser.parseError(token.span, "expected-doctype-but-got-chars");
+    anythingElse();
+    return token;
+  }
+
+  Token processStartTag(StartTagToken token) {
+    parser.parseError(
+        token.span, "expected-doctype-but-got-start-tag", {"name": token.name});
+    anythingElse();
+    return token;
+  }
+
+  Token processEndTag(EndTagToken token) {
+    parser.parseError(
+        token.span, "expected-doctype-but-got-end-tag", {"name": token.name});
+    anythingElse();
+    return token;
+  }
+
+  bool processEOF() {
+    parser.parseError(parser._lastSpan, "expected-doctype-but-got-eof");
+    anythingElse();
+    return true;
+  }
+}
+
+class BeforeHtmlPhase extends Phase {
+  BeforeHtmlPhase(parser) : super(parser);
+
+  // helper methods
+  void insertHtmlElement() {
+    tree.insertRoot(new StartTagToken("html",
+        data: new LinkedHashMap<dynamic, String>()));
+    parser.phase = parser._beforeHeadPhase;
+  }
+
+  // other
+  bool processEOF() {
+    insertHtmlElement();
+    return true;
+  }
+
+  Token processComment(CommentToken token) {
+    tree.insertComment(token, tree.document);
+    return null;
+  }
+
+  Token processSpaceCharacters(SpaceCharactersToken token) {
+    return null;
+  }
+
+  Token processCharacters(CharactersToken token) {
+    insertHtmlElement();
+    return token;
+  }
+
+  Token processStartTag(StartTagToken token) {
+    if (token.name == "html") {
+      parser.firstStartTag = true;
+    }
+    insertHtmlElement();
+    return token;
+  }
+
+  Token processEndTag(EndTagToken token) {
+    switch (token.name) {
+      case "head":
+      case "body":
+      case "html":
+      case "br":
+        insertHtmlElement();
+        return token;
+      default:
+        parser.parseError(
+            token.span, "unexpected-end-tag-before-html", {"name": token.name});
+        return null;
+    }
+  }
+}
+
+class BeforeHeadPhase extends Phase {
+  BeforeHeadPhase(parser) : super(parser);
+
+  processStartTag(StartTagToken token) {
+    switch (token.name) {
+      case 'html':
+        return startTagHtml(token);
+      case 'head':
+        startTagHead(token);
+        return null;
+      default:
+        return startTagOther(token);
+    }
+  }
+
+  processEndTag(EndTagToken token) {
+    switch (token.name) {
+      case "head":
+      case "body":
+      case "html":
+      case "br":
+        return endTagImplyHead(token);
+      default:
+        endTagOther(token);
+        return null;
+    }
+  }
+
+  bool processEOF() {
+    startTagHead(new StartTagToken("head",
+        data: new LinkedHashMap<dynamic, String>()));
+    return true;
+  }
+
+  Token processSpaceCharacters(SpaceCharactersToken token) {
+    return null;
+  }
+
+  Token processCharacters(CharactersToken token) {
+    startTagHead(new StartTagToken("head",
+        data: new LinkedHashMap<dynamic, String>()));
+    return token;
+  }
+
+  Token startTagHtml(StartTagToken token) {
+    return parser._inBodyPhase.processStartTag(token);
+  }
+
+  void startTagHead(StartTagToken token) {
+    tree.insertElement(token);
+    tree.headPointer = tree.openElements.last;
+    parser.phase = parser._inHeadPhase;
+  }
+
+  Token startTagOther(StartTagToken token) {
+    startTagHead(new StartTagToken("head",
+        data: new LinkedHashMap<dynamic, String>()));
+    return token;
+  }
+
+  Token endTagImplyHead(EndTagToken token) {
+    startTagHead(new StartTagToken("head",
+        data: new LinkedHashMap<dynamic, String>()));
+    return token;
+  }
+
+  void endTagOther(EndTagToken token) {
+    parser.parseError(
+        token.span, "end-tag-after-implied-root", {"name": token.name});
+  }
+}
+
+class InHeadPhase extends Phase {
+  InHeadPhase(parser) : super(parser);
+
+  processStartTag(StartTagToken token) {
+    switch (token.name) {
+      case "html":
+        return startTagHtml(token);
+      case "title":
+        startTagTitle(token);
+        return null;
+      case "noscript":
+      case "noframes":
+      case "style":
+        startTagNoScriptNoFramesStyle(token);
+        return null;
+      case "script":
+        startTagScript(token);
+        return null;
+      case "base":
+      case "basefont":
+      case "bgsound":
+      case "command":
+      case "link":
+        startTagBaseLinkCommand(token);
+        return null;
+      case "meta":
+        startTagMeta(token);
+        return null;
+      case "head":
+        startTagHead(token);
+        return null;
+      default:
+        return startTagOther(token);
+    }
+  }
+
+  processEndTag(EndTagToken token) {
+    switch (token.name) {
+      case "head":
+        endTagHead(token);
+        return null;
+      case "br":
+      case "html":
+      case "body":
+        return endTagHtmlBodyBr(token);
+      default:
+        endTagOther(token);
+        return null;
+    }
+  }
+
+  // the real thing
+  bool processEOF() {
+    anythingElse();
+    return true;
+  }
+
+  Token processCharacters(CharactersToken token) {
+    anythingElse();
+    return token;
+  }
+
+  Token startTagHtml(StartTagToken token) {
+    return parser._inBodyPhase.processStartTag(token);
+  }
+
+  void startTagHead(StartTagToken token) {
+    parser.parseError(token.span, "two-heads-are-not-better-than-one");
+  }
+
+  void startTagBaseLinkCommand(StartTagToken token) {
+    tree.insertElement(token);
+    tree.openElements.removeLast();
+    token.selfClosingAcknowledged = true;
+  }
+
+  void startTagMeta(StartTagToken token) {
+    tree.insertElement(token);
+    tree.openElements.removeLast();
+    token.selfClosingAcknowledged = true;
+
+    var attributes = token.data;
+    if (!parser.tokenizer.stream.charEncodingCertain) {
+      var charset = attributes["charset"];
+      var content = attributes["content"];
+      if (charset != null) {
+        parser.tokenizer.stream.changeEncoding(charset);
+      } else if (content != null) {
+        var data = new EncodingBytes(content);
+        var codec = new ContentAttrParser(data).parse();
+        parser.tokenizer.stream.changeEncoding(codec);
+      }
+    }
+  }
+
+  void startTagTitle(StartTagToken token) {
+    parser.parseRCDataRawtext(token, "RCDATA");
+  }
+
+  void startTagNoScriptNoFramesStyle(StartTagToken token) {
+    // Need to decide whether to implement the scripting-disabled case
+    parser.parseRCDataRawtext(token, "RAWTEXT");
+  }
+
+  void startTagScript(StartTagToken token) {
+    tree.insertElement(token);
+    parser.tokenizer.state = parser.tokenizer.scriptDataState;
+    parser.originalPhase = parser.phase;
+    parser.phase = parser._textPhase;
+  }
+
+  Token startTagOther(StartTagToken token) {
+    anythingElse();
+    return token;
+  }
+
+  void endTagHead(EndTagToken token) {
+    var node = parser.tree.openElements.removeLast();
+    assert(node.localName == "head");
+    node.endSourceSpan = token.span;
+    parser.phase = parser._afterHeadPhase;
+  }
+
+  Token endTagHtmlBodyBr(EndTagToken token) {
+    anythingElse();
+    return token;
+  }
+
+  void endTagOther(EndTagToken token) {
+    parser.parseError(token.span, "unexpected-end-tag", {"name": token.name});
+  }
+
+  void anythingElse() {
+    endTagHead(new EndTagToken("head"));
+  }
+}
+
+// XXX If we implement a parser for which scripting is disabled we need to
+// implement this phase.
+//
+// class InHeadNoScriptPhase extends Phase {
+
+class AfterHeadPhase extends Phase {
+  AfterHeadPhase(parser) : super(parser);
+
+  processStartTag(StartTagToken token) {
+    switch (token.name) {
+      case "html":
+        return startTagHtml(token);
+      case "body":
+        startTagBody(token);
+        return null;
+      case "frameset":
+        startTagFrameset(token);
+        return null;
+      case "base":
+      case "basefont":
+      case "bgsound":
+      case "link":
+      case "meta":
+      case "noframes":
+      case "script":
+      case "style":
+      case "title":
+        startTagFromHead(token);
+        return null;
+      case "head":
+        startTagHead(token);
+        return null;
+      default:
+        return startTagOther(token);
+    }
+  }
+
+  processEndTag(EndTagToken token) {
+    switch (token.name) {
+      case "body":
+      case "html":
+      case "br":
+        return endTagHtmlBodyBr(token);
+      default:
+        endTagOther(token);
+        return null;
+    }
+  }
+
+  bool processEOF() {
+    anythingElse();
+    return true;
+  }
+
+  Token processCharacters(CharactersToken token) {
+    anythingElse();
+    return token;
+  }
+
+  Token startTagHtml(StartTagToken token) {
+    return parser._inBodyPhase.processStartTag(token);
+  }
+
+  void startTagBody(StartTagToken token) {
+    parser.framesetOK = false;
+    tree.insertElement(token);
+    parser.phase = parser._inBodyPhase;
+  }
+
+  void startTagFrameset(StartTagToken token) {
+    tree.insertElement(token);
+    parser.phase = parser._inFramesetPhase;
+  }
+
+  void startTagFromHead(StartTagToken token) {
+    parser.parseError(token.span, "unexpected-start-tag-out-of-my-head", {
+      "name": token.name
+    });
+    tree.openElements.add(tree.headPointer);
+    parser._inHeadPhase.processStartTag(token);
+    for (var node in tree.openElements.reversed) {
+      if (node.localName == "head") {
+        tree.openElements.remove(node);
+        break;
+      }
+    }
+  }
+
+  void startTagHead(StartTagToken token) {
+    parser.parseError(token.span, "unexpected-start-tag", {"name": token.name});
+  }
+
+  Token startTagOther(StartTagToken token) {
+    anythingElse();
+    return token;
+  }
+
+  Token endTagHtmlBodyBr(EndTagToken token) {
+    anythingElse();
+    return token;
+  }
+
+  void endTagOther(EndTagToken token) {
+    parser.parseError(token.span, "unexpected-end-tag", {"name": token.name});
+  }
+
+  void anythingElse() {
+    tree.insertElement(new StartTagToken("body",
+        data: new LinkedHashMap<dynamic, String>()));
+    parser.phase = parser._inBodyPhase;
+    parser.framesetOK = true;
+  }
+}
+
+typedef Token TokenProccessor(Token token);
+
+class InBodyPhase extends Phase {
+  bool dropNewline = false;
+
+  // http://www.whatwg.org/specs/web-apps/current-work///parsing-main-inbody
+  // the really-really-really-very crazy mode
+  InBodyPhase(parser) : super(parser);
+
+  processStartTag(StartTagToken token) {
+    switch (token.name) {
+      case "html":
+        return startTagHtml(token);
+      case "base":
+      case "basefont":
+      case "bgsound":
+      case "command":
+      case "link":
+      case "meta":
+      case "noframes":
+      case "script":
+      case "style":
+      case "title":
+        return startTagProcessInHead(token);
+      case "body":
+        startTagBody(token);
+        return null;
+      case "frameset":
+        startTagFrameset(token);
+        return null;
+      case "address":
+      case "article":
+      case "aside":
+      case "blockquote":
+      case "center":
+      case "details":
+      case "details":
+      case "dir":
+      case "div":
+      case "dl":
+      case "fieldset":
+      case "figcaption":
+      case "figure":
+      case "footer":
+      case "header":
+      case "hgroup":
+      case "menu":
+      case "nav":
+      case "ol":
+      case "p":
+      case "section":
+      case "summary":
+      case "ul":
+        startTagCloseP(token);
+        return null;
+      // headingElements
+      case "h1":
+      case "h2":
+      case "h3":
+      case "h4":
+      case "h5":
+      case "h6":
+        startTagHeading(token);
+        return null;
+      case "pre":
+      case "listing":
+        startTagPreListing(token);
+        return null;
+      case "form":
+        startTagForm(token);
+        return null;
+      case "li":
+      case "dd":
+      case "dt":
+        startTagListItem(token);
+        return null;
+      case "plaintext":
+        startTagPlaintext(token);
+        return null;
+      case "a":
+        startTagA(token);
+        return null;
+      case "b":
+      case "big":
+      case "code":
+      case "em":
+      case "font":
+      case "i":
+      case "s":
+      case "small":
+      case "strike":
+      case "strong":
+      case "tt":
+      case "u":
+        startTagFormatting(token);
+        return null;
+      case "nobr":
+        startTagNobr(token);
+        return null;
+      case "button":
+        return startTagButton(token);
+      case "applet":
+      case "marquee":
+      case "object":
+        startTagAppletMarqueeObject(token);
+        return null;
+      case "xmp":
+        startTagXmp(token);
+        return null;
+      case "table":
+        startTagTable(token);
+        return null;
+      case "area":
+      case "br":
+      case "embed":
+      case "img":
+      case "keygen":
+      case "wbr":
+        startTagVoidFormatting(token);
+        return null;
+      case "param":
+      case "source":
+      case "track":
+        startTagParamSource(token);
+        return null;
+      case "input":
+        startTagInput(token);
+        return null;
+      case "hr":
+        startTagHr(token);
+        return null;
+      case "image":
+        startTagImage(token);
+        return null;
+      case "isindex":
+        startTagIsIndex(token);
+        return null;
+      case "textarea":
+        startTagTextarea(token);
+        return null;
+      case "iframe":
+        startTagIFrame(token);
+        return null;
+      case "noembed":
+      case "noframes":
+      case "noscript":
+        startTagRawtext(token);
+        return null;
+      case "select":
+        startTagSelect(token);
+        return null;
+      case "rp":
+      case "rt":
+        startTagRpRt(token);
+        return null;
+      case "option":
+      case "optgroup":
+        startTagOpt(token);
+        return null;
+      case "math":
+        startTagMath(token);
+        return null;
+      case "svg":
+        startTagSvg(token);
+        return null;
+      case "caption":
+      case "col":
+      case "colgroup":
+      case "frame":
+      case "head":
+      case "tbody":
+      case "td":
+      case "tfoot":
+      case "th":
+      case "thead":
+      case "tr":
+        startTagMisplaced(token);
+        return null;
+      default:
+        return startTagOther(token);
+    }
+  }
+
+  processEndTag(EndTagToken token) {
+    switch (token.name) {
+      case "body":
+        endTagBody(token);
+        return null;
+      case "html":
+        return endTagHtml(token);
+      case "address":
+      case "article":
+      case "aside":
+      case "blockquote":
+      case "center":
+      case "details":
+      case "dir":
+      case "div":
+      case "dl":
+      case "fieldset":
+      case "figcaption":
+      case "figure":
+      case "footer":
+      case "header":
+      case "hgroup":
+      case "listing":
+      case "menu":
+      case "nav":
+      case "ol":
+      case "pre":
+      case "section":
+      case "summary":
+      case "ul":
+        endTagBlock(token);
+        return null;
+      case "form":
+        endTagForm(token);
+        return null;
+      case "p":
+        endTagP(token);
+        return null;
+      case "dd":
+      case "dt":
+      case "li":
+        endTagListItem(token);
+        return null;
+      // headingElements
+      case "h1":
+      case "h2":
+      case "h3":
+      case "h4":
+      case "h5":
+      case "h6":
+        endTagHeading(token);
+        return null;
+      case "a":
+      case "b":
+      case "big":
+      case "code":
+      case "em":
+      case "font":
+      case "i":
+      case "nobr":
+      case "s":
+      case "small":
+      case "strike":
+      case "strong":
+      case "tt":
+      case "u":
+        endTagFormatting(token);
+        return null;
+      case "applet":
+      case "marquee":
+      case "object":
+        endTagAppletMarqueeObject(token);
+        return null;
+      case "br":
+        endTagBr(token);
+        return null;
+      default:
+        endTagOther(token);
+        return null;
+    }
+  }
+
+  bool isMatchingFormattingElement(Element node1, Element node2) {
+    if (node1.localName != node2.localName ||
+        node1.namespaceUri != node2.namespaceUri) {
+      return false;
+    } else if (node1.attributes.length != node2.attributes.length) {
+      return false;
+    } else {
+      for (var key in node1.attributes.keys) {
+        if (node1.attributes[key] != node2.attributes[key]) {
+          return false;
+        }
+      }
+    }
+    return true;
+  }
+
+  // helper
+  void addFormattingElement(token) {
+    tree.insertElement(token);
+    var element = tree.openElements.last;
+
+    var matchingElements = [];
+    for (Node node in tree.activeFormattingElements.reversed) {
+      if (node == Marker) {
+        break;
+      } else if (isMatchingFormattingElement(node, element)) {
+        matchingElements.add(node);
+      }
+    }
+
+    assert(matchingElements.length <= 3);
+    if (matchingElements.length == 3) {
+      tree.activeFormattingElements.remove(matchingElements.last);
+    }
+    tree.activeFormattingElements.add(element);
+  }
+
+  // the real deal
+  bool processEOF() {
+    for (var node in tree.openElements.reversed) {
+      switch (node.localName) {
+        case "dd":
+        case "dt":
+        case "li":
+        case "p":
+        case "tbody":
+        case "td":
+        case "tfoot":
+        case "th":
+        case "thead":
+        case "tr":
+        case "body":
+        case "html":
+          continue;
+      }
+      parser.parseError(node.sourceSpan, "expected-closing-tag-but-got-eof");
+      break;
+    }
+    //Stop parsing
+    return false;
+  }
+
+  void processSpaceCharactersDropNewline(StringToken token) {
+    // Sometimes (start of <pre>, <listing>, and <textarea> blocks) we
+    // want to drop leading newlines
+    var data = token.data;
+    dropNewline = false;
+    if (data.startsWith("\n")) {
+      var lastOpen = tree.openElements.last;
+      if (const ["pre", "listing", "textarea"].contains(lastOpen.localName) &&
+          !lastOpen.hasContent()) {
+        data = data.substring(1);
+      }
+    }
+    if (data.length > 0) {
+      tree.reconstructActiveFormattingElements();
+      tree.insertText(data, token.span);
+    }
+  }
+
+  Token processCharacters(CharactersToken token) {
+    if (token.data == "\u0000") {
+      //The tokenizer should always emit null on its own
+      return null;
+    }
+    tree.reconstructActiveFormattingElements();
+    tree.insertText(token.data, token.span);
+    if (parser.framesetOK && !allWhitespace(token.data)) {
+      parser.framesetOK = false;
+    }
+    return null;
+  }
+
+  Token processSpaceCharacters(SpaceCharactersToken token) {
+    if (dropNewline) {
+      processSpaceCharactersDropNewline(token);
+    } else {
+      tree.reconstructActiveFormattingElements();
+      tree.insertText(token.data, token.span);
+    }
+    return null;
+  }
+
+  Token startTagProcessInHead(StartTagToken token) {
+    return parser._inHeadPhase.processStartTag(token);
+  }
+
+  void startTagBody(StartTagToken token) {
+    parser.parseError(token.span, "unexpected-start-tag", {"name": "body"});
+    if (tree.openElements.length == 1 ||
+        tree.openElements[1].localName != "body") {
+      assert(parser.innerHTMLMode);
+    } else {
+      parser.framesetOK = false;
+      token.data.forEach((attr, value) {
+        tree.openElements[1].attributes.putIfAbsent(attr, () => value);
+      });
+    }
+  }
+
+  void startTagFrameset(StartTagToken token) {
+    parser.parseError(token.span, "unexpected-start-tag", {"name": "frameset"});
+    if ((tree.openElements.length == 1 ||
+        tree.openElements[1].localName != "body")) {
+      assert(parser.innerHTMLMode);
+    } else if (parser.framesetOK) {
+      if (tree.openElements[1].parentNode != null) {
+        tree.openElements[1].parentNode.nodes.remove(tree.openElements[1]);
+      }
+      while (tree.openElements.last.localName != "html") {
+        tree.openElements.removeLast();
+      }
+      tree.insertElement(token);
+      parser.phase = parser._inFramesetPhase;
+    }
+  }
+
+  void startTagCloseP(StartTagToken token) {
+    if (tree.elementInScope("p", variant: "button")) {
+      endTagP(new EndTagToken("p"));
+    }
+    tree.insertElement(token);
+  }
+
+  void startTagPreListing(StartTagToken token) {
+    if (tree.elementInScope("p", variant: "button")) {
+      endTagP(new EndTagToken("p"));
+    }
+    tree.insertElement(token);
+    parser.framesetOK = false;
+    dropNewline = true;
+  }
+
+  void startTagForm(StartTagToken token) {
+    if (tree.formPointer != null) {
+      parser.parseError(token.span, "unexpected-start-tag", {"name": "form"});
+    } else {
+      if (tree.elementInScope("p", variant: "button")) {
+        endTagP(new EndTagToken("p"));
+      }
+      tree.insertElement(token);
+      tree.formPointer = tree.openElements.last;
+    }
+  }
+
+  void startTagListItem(StartTagToken token) {
+    parser.framesetOK = false;
+
+    final stopNamesMap = const {
+      "li": const ["li"],
+      "dt": const ["dt", "dd"],
+      "dd": const ["dt", "dd"]
+    };
+    var stopNames = stopNamesMap[token.name];
+    for (var node in tree.openElements.reversed) {
+      if (stopNames.contains(node.localName)) {
+        parser.phase.processEndTag(new EndTagToken(node.localName));
+        break;
+      }
+      if (specialElements.contains(getElementNameTuple(node)) &&
+          !const ["address", "div", "p"].contains(node.localName)) {
+        break;
+      }
+    }
+
+    if (tree.elementInScope("p", variant: "button")) {
+      parser.phase.processEndTag(new EndTagToken("p"));
+    }
+
+    tree.insertElement(token);
+  }
+
+  void startTagPlaintext(StartTagToken token) {
+    if (tree.elementInScope("p", variant: "button")) {
+      endTagP(new EndTagToken("p"));
+    }
+    tree.insertElement(token);
+    parser.tokenizer.state = parser.tokenizer.plaintextState;
+  }
+
+  void startTagHeading(StartTagToken token) {
+    if (tree.elementInScope("p", variant: "button")) {
+      endTagP(new EndTagToken("p"));
+    }
+    if (headingElements.contains(tree.openElements.last.localName)) {
+      parser.parseError(
+          token.span, "unexpected-start-tag", {"name": token.name});
+      tree.openElements.removeLast();
+    }
+    tree.insertElement(token);
+  }
+
+  void startTagA(StartTagToken token) {
+    var afeAElement = tree.elementInActiveFormattingElements("a");
+    if (afeAElement != null) {
+      parser.parseError(token.span, "unexpected-start-tag-implies-end-tag", {
+        "startName": "a",
+        "endName": "a"
+      });
+      endTagFormatting(new EndTagToken("a"));
+      tree.openElements.remove(afeAElement);
+      tree.activeFormattingElements.remove(afeAElement);
+    }
+    tree.reconstructActiveFormattingElements();
+    addFormattingElement(token);
+  }
+
+  void startTagFormatting(StartTagToken token) {
+    tree.reconstructActiveFormattingElements();
+    addFormattingElement(token);
+  }
+
+  void startTagNobr(StartTagToken token) {
+    tree.reconstructActiveFormattingElements();
+    if (tree.elementInScope("nobr")) {
+      parser.parseError(token.span, "unexpected-start-tag-implies-end-tag", {
+        "startName": "nobr",
+        "endName": "nobr"
+      });
+      processEndTag(new EndTagToken("nobr"));
+      // XXX Need tests that trigger the following
+      tree.reconstructActiveFormattingElements();
+    }
+    addFormattingElement(token);
+  }
+
+  Token startTagButton(StartTagToken token) {
+    if (tree.elementInScope("button")) {
+      parser.parseError(token.span, "unexpected-start-tag-implies-end-tag", {
+        "startName": "button",
+        "endName": "button"
+      });
+      processEndTag(new EndTagToken("button"));
+      return token;
+    } else {
+      tree.reconstructActiveFormattingElements();
+      tree.insertElement(token);
+      parser.framesetOK = false;
+    }
+    return null;
+  }
+
+  void startTagAppletMarqueeObject(StartTagToken token) {
+    tree.reconstructActiveFormattingElements();
+    tree.insertElement(token);
+    tree.activeFormattingElements.add(Marker);
+    parser.framesetOK = false;
+  }
+
+  void startTagXmp(StartTagToken token) {
+    if (tree.elementInScope("p", variant: "button")) {
+      endTagP(new EndTagToken("p"));
+    }
+    tree.reconstructActiveFormattingElements();
+    parser.framesetOK = false;
+    parser.parseRCDataRawtext(token, "RAWTEXT");
+  }
+
+  void startTagTable(StartTagToken token) {
+    if (parser.compatMode != "quirks") {
+      if (tree.elementInScope("p", variant: "button")) {
+        processEndTag(new EndTagToken("p"));
+      }
+    }
+    tree.insertElement(token);
+    parser.framesetOK = false;
+    parser.phase = parser._inTablePhase;
+  }
+
+  void startTagVoidFormatting(StartTagToken token) {
+    tree.reconstructActiveFormattingElements();
+    tree.insertElement(token);
+    tree.openElements.removeLast();
+    token.selfClosingAcknowledged = true;
+    parser.framesetOK = false;
+  }
+
+  void startTagInput(StartTagToken token) {
+    var savedFramesetOK = parser.framesetOK;
+    startTagVoidFormatting(token);
+    if (asciiUpper2Lower(token.data["type"]) == "hidden") {
+      //input type=hidden doesn't change framesetOK
+      parser.framesetOK = savedFramesetOK;
+    }
+  }
+
+  void startTagParamSource(StartTagToken token) {
+    tree.insertElement(token);
+    tree.openElements.removeLast();
+    token.selfClosingAcknowledged = true;
+  }
+
+  void startTagHr(StartTagToken token) {
+    if (tree.elementInScope("p", variant: "button")) {
+      endTagP(new EndTagToken("p"));
+    }
+    tree.insertElement(token);
+    tree.openElements.removeLast();
+    token.selfClosingAcknowledged = true;
+    parser.framesetOK = false;
+  }
+
+  void startTagImage(StartTagToken token) {
+    // No really...
+    parser.parseError(token.span, "unexpected-start-tag-treated-as", {
+      "originalName": "image",
+      "newName": "img"
+    });
+    processStartTag(new StartTagToken("img",
+        data: token.data, selfClosing: token.selfClosing));
+  }
+
+  void startTagIsIndex(StartTagToken token) {
+    parser.parseError(token.span, "deprecated-tag", {"name": "isindex"});
+    if (tree.formPointer != null) {
+      return;
+    }
+    var formAttrs = new LinkedHashMap<dynamic, String>();
+    var dataAction = token.data["action"];
+    if (dataAction != null) {
+      formAttrs["action"] = dataAction;
+    }
+    processStartTag(new StartTagToken("form", data: formAttrs));
+    processStartTag(new StartTagToken("hr",
+        data: new LinkedHashMap<dynamic, String>()));
+    processStartTag(new StartTagToken("label",
+        data: new LinkedHashMap<dynamic, String>()));
+    // XXX Localization ...
+    var prompt = token.data["prompt"];
+    if (prompt == null) {
+      prompt = "This is a searchable index. Enter search keywords: ";
+    }
+    processCharacters(new CharactersToken(prompt));
+    var attributes = new LinkedHashMap<dynamic, String>.from(token.data);
+    attributes.remove('action');
+    attributes.remove('prompt');
+    attributes["name"] = "isindex";
+    processStartTag(new StartTagToken(
+        "input", data: attributes, selfClosing: token.selfClosing));
+    processEndTag(new EndTagToken("label"));
+    processStartTag(new StartTagToken("hr",
+        data: new LinkedHashMap<dynamic, String>()));
+    processEndTag(new EndTagToken("form"));
+  }
+
+  void startTagTextarea(StartTagToken token) {
+    tree.insertElement(token);
+    parser.tokenizer.state = parser.tokenizer.rcdataState;
+    dropNewline = true;
+    parser.framesetOK = false;
+  }
+
+  void startTagIFrame(StartTagToken token) {
+    parser.framesetOK = false;
+    startTagRawtext(token);
+  }
+
+  /// iframe, noembed noframes, noscript(if scripting enabled).
+  void startTagRawtext(StartTagToken token) {
+    parser.parseRCDataRawtext(token, "RAWTEXT");
+  }
+
+  void startTagOpt(StartTagToken token) {
+    if (tree.openElements.last.localName == "option") {
+      parser.phase.processEndTag(new EndTagToken("option"));
+    }
+    tree.reconstructActiveFormattingElements();
+    parser.tree.insertElement(token);
+  }
+
+  void startTagSelect(StartTagToken token) {
+    tree.reconstructActiveFormattingElements();
+    tree.insertElement(token);
+    parser.framesetOK = false;
+
+    if (parser._inTablePhase == parser.phase ||
+        parser._inCaptionPhase == parser.phase ||
+        parser._inColumnGroupPhase == parser.phase ||
+        parser._inTableBodyPhase == parser.phase ||
+        parser._inRowPhase == parser.phase ||
+        parser._inCellPhase == parser.phase) {
+      parser.phase = parser._inSelectInTablePhase;
+    } else {
+      parser.phase = parser._inSelectPhase;
+    }
+  }
+
+  void startTagRpRt(StartTagToken token) {
+    if (tree.elementInScope("ruby")) {
+      tree.generateImpliedEndTags();
+      var last = tree.openElements.last;
+      if (last.localName != "ruby") {
+        parser.parseError(last.sourceSpan, 'undefined-error');
+      }
+    }
+    tree.insertElement(token);
+  }
+
+  void startTagMath(StartTagToken token) {
+    tree.reconstructActiveFormattingElements();
+    parser.adjustMathMLAttributes(token);
+    parser.adjustForeignAttributes(token);
+    token.namespace = Namespaces.mathml;
+    tree.insertElement(token);
+    //Need to get the parse error right for the case where the token
+    //has a namespace not equal to the xmlns attribute
+    if (token.selfClosing) {
+      tree.openElements.removeLast();
+      token.selfClosingAcknowledged = true;
+    }
+  }
+
+  void startTagSvg(StartTagToken token) {
+    tree.reconstructActiveFormattingElements();
+    parser.adjustSVGAttributes(token);
+    parser.adjustForeignAttributes(token);
+    token.namespace = Namespaces.svg;
+    tree.insertElement(token);
+    //Need to get the parse error right for the case where the token
+    //has a namespace not equal to the xmlns attribute
+    if (token.selfClosing) {
+      tree.openElements.removeLast();
+      token.selfClosingAcknowledged = true;
+    }
+  }
+
+  /// Elements that should be children of other elements that have a
+  /// different insertion mode; here they are ignored
+  /// "caption", "col", "colgroup", "frame", "frameset", "head",
+  /// "option", "optgroup", "tbody", "td", "tfoot", "th", "thead",
+  /// "tr", "noscript"
+  void startTagMisplaced(StartTagToken token) {
+    parser.parseError(
+        token.span, "unexpected-start-tag-ignored", {"name": token.name});
+  }
+
+  Token startTagOther(StartTagToken token) {
+    tree.reconstructActiveFormattingElements();
+    tree.insertElement(token);
+    return null;
+  }
+
+  void endTagP(EndTagToken token) {
+    if (!tree.elementInScope("p", variant: "button")) {
+      startTagCloseP(new StartTagToken("p",
+          data: new LinkedHashMap<dynamic, String>()));
+      parser.parseError(token.span, "unexpected-end-tag", {"name": "p"});
+      endTagP(new EndTagToken("p"));
+    } else {
+      tree.generateImpliedEndTags("p");
+      if (tree.openElements.last.localName != "p") {
+        parser.parseError(token.span, "unexpected-end-tag", {"name": "p"});
+      }
+      popOpenElementsUntil(token);
+    }
+  }
+
+  void endTagBody(EndTagToken token) {
+    if (!tree.elementInScope("body")) {
+      parser.parseError(token.span, 'undefined-error');
+      return;
+    } else if (tree.openElements.last.localName == "body") {
+      tree.openElements.last.endSourceSpan = token.span;
+    } else {
+      for (Element node in slice(tree.openElements, 2)) {
+        switch (node.localName) {
+          case "dd":
+          case "dt":
+          case "li":
+          case "optgroup":
+          case "option":
+          case "p":
+          case "rp":
+          case "rt":
+          case "tbody":
+          case "td":
+          case "tfoot":
+          case "th":
+          case "thead":
+          case "tr":
+          case "body":
+          case "html":
+            continue;
+        }
+        // Not sure this is the correct name for the parse error
+        parser.parseError(token.span, "expected-one-end-tag-but-got-another", {
+          "gotName": "body",
+          "expectedName": node.localName
+        });
+        break;
+      }
+    }
+    parser.phase = parser._afterBodyPhase;
+  }
+
+  Token endTagHtml(EndTagToken token) {
+    //We repeat the test for the body end tag token being ignored here
+    if (tree.elementInScope("body")) {
+      endTagBody(new EndTagToken("body"));
+      return token;
+    }
+    return null;
+  }
+
+  void endTagBlock(EndTagToken token) {
+    //Put us back in the right whitespace handling mode
+    if (token.name == "pre") {
+      dropNewline = false;
+    }
+    var inScope = tree.elementInScope(token.name);
+    if (inScope) {
+      tree.generateImpliedEndTags();
+    }
+    if (tree.openElements.last.localName != token.name) {
+      parser.parseError(token.span, "end-tag-too-early", {"name": token.name});
+    }
+    if (inScope) {
+      popOpenElementsUntil(token);
+    }
+  }
+
+  void endTagForm(EndTagToken token) {
+    var node = tree.formPointer;
+    tree.formPointer = null;
+    if (node == null || !tree.elementInScope(node)) {
+      parser.parseError(token.span, "unexpected-end-tag", {"name": "form"});
+    } else {
+      tree.generateImpliedEndTags();
+      if (tree.openElements.last != node) {
+        parser.parseError(
+            token.span, "end-tag-too-early-ignored", {"name": "form"});
+      }
+      tree.openElements.remove(node);
+      node.endSourceSpan = token.span;
+    }
+  }
+
+  void endTagListItem(EndTagToken token) {
+    var variant;
+    if (token.name == "li") {
+      variant = "list";
+    } else {
+      variant = null;
+    }
+    if (!tree.elementInScope(token.name, variant: variant)) {
+      parser.parseError(token.span, "unexpected-end-tag", {"name": token.name});
+    } else {
+      tree.generateImpliedEndTags(token.name);
+      if (tree.openElements.last.localName != token.name) {
+        parser.parseError(
+            token.span, "end-tag-too-early", {"name": token.name});
+      }
+      popOpenElementsUntil(token);
+    }
+  }
+
+  void endTagHeading(EndTagToken token) {
+    for (var item in headingElements) {
+      if (tree.elementInScope(item)) {
+        tree.generateImpliedEndTags();
+        break;
+      }
+    }
+    if (tree.openElements.last.localName != token.name) {
+      parser.parseError(token.span, "end-tag-too-early", {"name": token.name});
+    }
+
+    for (var item in headingElements) {
+      if (tree.elementInScope(item)) {
+        Element node = tree.openElements.removeLast();
+        while (!headingElements.contains(node.localName)) {
+          node = tree.openElements.removeLast();
+        }
+        if (node != null) {
+          node.endSourceSpan = token.span;
+        }
+        break;
+      }
+    }
+  }
+
+  /// The much-feared adoption agency algorithm.
+  void endTagFormatting(EndTagToken token) {
+    // http://www.whatwg.org/specs/web-apps/current-work/multipage/tree-construction.html#adoptionAgency
+    // TODO(jmesserly): the comments here don't match the numbered steps in the
+    // updated spec. This needs a pass over it to verify that it still matches.
+    // In particular the html5lib Python code skiped "step 4", I'm not sure why.
+    // XXX Better parseError messages appreciated.
+    int outerLoopCounter = 0;
+    while (outerLoopCounter < 8) {
+      outerLoopCounter += 1;
+
+      // Step 1 paragraph 1
+      var formattingElement =
+          tree.elementInActiveFormattingElements(token.name);
+      if (formattingElement == null ||
+          (tree.openElements.contains(formattingElement) &&
+              !tree.elementInScope(formattingElement.localName))) {
+        parser.parseError(
+            token.span, "adoption-agency-1.1", {"name": token.name});
+        return;
+        // Step 1 paragraph 2
+      } else if (!tree.openElements.contains(formattingElement)) {
+        parser.parseError(
+            token.span, "adoption-agency-1.2", {"name": token.name});
+        tree.activeFormattingElements.remove(formattingElement);
+        return;
+      }
+
+      // Step 1 paragraph 3
+      if (formattingElement != tree.openElements.last) {
+        parser.parseError(
+            token.span, "adoption-agency-1.3", {"name": token.name});
+      }
+
+      // Step 2
+      // Start of the adoption agency algorithm proper
+      var afeIndex = tree.openElements.indexOf(formattingElement);
+      Node furthestBlock = null;
+      for (Node element in slice(tree.openElements, afeIndex)) {
+        if (specialElements.contains(getElementNameTuple(element))) {
+          furthestBlock = element;
+          break;
+        }
+      }
+      // Step 3
+      if (furthestBlock == null) {
+        Element element = tree.openElements.removeLast();
+        while (element != formattingElement) {
+          element = tree.openElements.removeLast();
+        }
+        if (element != null) {
+          element.endSourceSpan = token.span;
+        }
+        tree.activeFormattingElements.remove(element);
+        return;
+      }
+
+      var commonAncestor = tree.openElements[afeIndex - 1];
+
+      // Step 5
+      // The bookmark is supposed to help us identify where to reinsert
+      // nodes in step 12. We have to ensure that we reinsert nodes after
+      // the node before the active formatting element. Note the bookmark
+      // can move in step 7.4
+      var bookmark = tree.activeFormattingElements.indexOf(formattingElement);
+
+      // Step 6
+      Node lastNode = furthestBlock;
+      var node = furthestBlock;
+      int innerLoopCounter = 0;
+
+      var index = tree.openElements.indexOf(node);
+      while (innerLoopCounter < 3) {
+        innerLoopCounter += 1;
+
+        // Node is element before node in open elements
+        index -= 1;
+        node = tree.openElements[index];
+        if (!tree.activeFormattingElements.contains(node)) {
+          tree.openElements.remove(node);
+          continue;
+        }
+        // Step 6.3
+        if (node == formattingElement) {
+          break;
+        }
+        // Step 6.4
+        if (lastNode == furthestBlock) {
+          bookmark = (tree.activeFormattingElements.indexOf(node) + 1);
+        }
+        // Step 6.5
+        //cite = node.parent
+        var clone = node.clone(false);
+        // Replace node with clone
+        tree.activeFormattingElements[
+            tree.activeFormattingElements.indexOf(node)] = clone;
+        tree.openElements[tree.openElements.indexOf(node)] = clone;
+        node = clone;
+
+        // Step 6.6
+        // Remove lastNode from its parents, if any
+        if (lastNode.parentNode != null) {
+          lastNode.parentNode.nodes.remove(lastNode);
+        }
+        node.nodes.add(lastNode);
+        // Step 7.7
+        lastNode = node;
+        // End of inner loop
+      }
+
+      // Step 7
+      // Foster parent lastNode if commonAncestor is a
+      // table, tbody, tfoot, thead, or tr we need to foster parent the
+      // lastNode
+      if (lastNode.parentNode != null) {
+        lastNode.parentNode.nodes.remove(lastNode);
+      }
+
+      if (const [
+        "table",
+        "tbody",
+        "tfoot",
+        "thead",
+        "tr"
+      ].contains(commonAncestor.localName)) {
+        var nodePos = tree.getTableMisnestedNodePosition();
+        nodePos[0].insertBefore(lastNode, nodePos[1]);
+      } else {
+        commonAncestor.nodes.add(lastNode);
+      }
+
+      // Step 8
+      var clone = formattingElement.clone(false);
+
+      // Step 9
+      furthestBlock.reparentChildren(clone);
+
+      // Step 10
+      furthestBlock.nodes.add(clone);
+
+      // Step 11
+      tree.activeFormattingElements.remove(formattingElement);
+      tree.activeFormattingElements.insert(
+          min(bookmark, tree.activeFormattingElements.length), clone);
+
+      // Step 12
+      tree.openElements.remove(formattingElement);
+      tree.openElements.insert(
+          tree.openElements.indexOf(furthestBlock) + 1, clone);
+    }
+  }
+
+  void endTagAppletMarqueeObject(EndTagToken token) {
+    if (tree.elementInScope(token.name)) {
+      tree.generateImpliedEndTags();
+    }
+    if (tree.openElements.last.localName != token.name) {
+      parser.parseError(token.span, "end-tag-too-early", {"name": token.name});
+    }
+    if (tree.elementInScope(token.name)) {
+      popOpenElementsUntil(token);
+      tree.clearActiveFormattingElements();
+    }
+  }
+
+  void endTagBr(EndTagToken token) {
+    parser.parseError(token.span, "unexpected-end-tag-treated-as", {
+      "originalName": "br",
+      "newName": "br element"
+    });
+    tree.reconstructActiveFormattingElements();
+    tree.insertElement(new StartTagToken("br",
+        data: new LinkedHashMap<dynamic, String>()));
+    tree.openElements.removeLast();
+  }
+
+  void endTagOther(EndTagToken token) {
+    for (var node in tree.openElements.reversed) {
+      if (node.localName == token.name) {
+        tree.generateImpliedEndTags(token.name);
+        if (tree.openElements.last.localName != token.name) {
+          parser.parseError(
+              token.span, "unexpected-end-tag", {"name": token.name});
+        }
+        while (tree.openElements.removeLast() != node);
+        node.endSourceSpan = token.span;
+        break;
+      } else {
+        if (specialElements.contains(getElementNameTuple(node))) {
+          parser.parseError(
+              token.span, "unexpected-end-tag", {"name": token.name});
+          break;
+        }
+      }
+    }
+  }
+}
+
+class TextPhase extends Phase {
+  TextPhase(parser) : super(parser);
+
+  // "Tried to process start tag %s in RCDATA/RAWTEXT mode"%token.name
+  processStartTag(StartTagToken token) {
+    assert(false);
+  }
+
+  processEndTag(EndTagToken token) {
+    if (token.name == 'script') {
+      endTagScript(token);
+      return null;
+    }
+    endTagOther(token);
+  }
+
+  Token processCharacters(CharactersToken token) {
+    tree.insertText(token.data, token.span);
+    return null;
+  }
+
+  bool processEOF() {
+    var last = tree.openElements.last;
+    parser.parseError(last.sourceSpan, "expected-named-closing-tag-but-got-eof",
+        {'name': last.localName});
+    tree.openElements.removeLast();
+    parser.phase = parser.originalPhase;
+    return true;
+  }
+
+  void endTagScript(EndTagToken token) {
+    var node = tree.openElements.removeLast();
+    assert(node.localName == "script");
+    parser.phase = parser.originalPhase;
+    //The rest of this method is all stuff that only happens if
+    //document.write works
+  }
+
+  void endTagOther(EndTagToken token) {
+    tree.openElements.removeLast();
+    parser.phase = parser.originalPhase;
+  }
+}
+
+class InTablePhase extends Phase {
+  // http://www.whatwg.org/specs/web-apps/current-work///in-table
+  InTablePhase(parser) : super(parser);
+
+  processStartTag(StartTagToken token) {
+    switch (token.name) {
+      case "html":
+        return startTagHtml(token);
+      case "caption":
+        startTagCaption(token);
+        return null;
+      case "colgroup":
+        startTagColgroup(token);
+        return null;
+      case "col":
+        return startTagCol(token);
+      case "tbody":
+      case "tfoot":
+      case "thead":
+        startTagRowGroup(token);
+        return null;
+      case "td":
+      case "th":
+      case "tr":
+        return startTagImplyTbody(token);
+      case "table":
+        return startTagTable(token);
+      case "style":
+      case "script":
+        return startTagStyleScript(token);
+      case "input":
+        startTagInput(token);
+        return null;
+      case "form":
+        startTagForm(token);
+        return null;
+      default:
+        startTagOther(token);
+        return null;
+    }
+  }
+
+  processEndTag(EndTagToken token) {
+    switch (token.name) {
+      case "table":
+        endTagTable(token);
+        return null;
+      case "body":
+      case "caption":
+      case "col":
+      case "colgroup":
+      case "html":
+      case "tbody":
+      case "td":
+      case "tfoot":
+      case "th":
+      case "thead":
+      case "tr":
+        endTagIgnore(token);
+        return null;
+      default:
+        endTagOther(token);
+        return null;
+    }
+  }
+
+  // helper methods
+  void clearStackToTableContext() {
+    // "clear the stack back to a table context"
+    while (tree.openElements.last.localName != "table" &&
+        tree.openElements.last.localName != "html") {
+      //parser.parseError(token.span, "unexpected-implied-end-tag-in-table",
+      //  {"name":  tree.openElements.last.name})
+      tree.openElements.removeLast();
+    }
+    // When the current node is <html> it's an innerHTML case
+  }
+
+  // processing methods
+  bool processEOF() {
+    var last = tree.openElements.last;
+    if (last.localName != "html") {
+      parser.parseError(last.sourceSpan, "eof-in-table");
+    } else {
+      assert(parser.innerHTMLMode);
+    }
+    //Stop parsing
+    return false;
+  }
+
+  Token processSpaceCharacters(SpaceCharactersToken token) {
+    var originalPhase = parser.phase;
+    parser.phase = parser._inTableTextPhase;
+    parser._inTableTextPhase.originalPhase = originalPhase;
+    parser.phase.processSpaceCharacters(token);
+    return null;
+  }
+
+  Token processCharacters(CharactersToken token) {
+    var originalPhase = parser.phase;
+    parser.phase = parser._inTableTextPhase;
+    parser._inTableTextPhase.originalPhase = originalPhase;
+    parser.phase.processCharacters(token);
+    return null;
+  }
+
+  void insertText(CharactersToken token) {
+    // If we get here there must be at least one non-whitespace character
+    // Do the table magic!
+    tree.insertFromTable = true;
+    parser._inBodyPhase.processCharacters(token);
+    tree.insertFromTable = false;
+  }
+
+  void startTagCaption(StartTagToken token) {
+    clearStackToTableContext();
+    tree.activeFormattingElements.add(Marker);
+    tree.insertElement(token);
+    parser.phase = parser._inCaptionPhase;
+  }
+
+  void startTagColgroup(StartTagToken token) {
+    clearStackToTableContext();
+    tree.insertElement(token);
+    parser.phase = parser._inColumnGroupPhase;
+  }
+
+  Token startTagCol(StartTagToken token) {
+    startTagColgroup(new StartTagToken("colgroup",
+        data: new LinkedHashMap<dynamic, String>()));
+    return token;
+  }
+
+  void startTagRowGroup(StartTagToken token) {
+    clearStackToTableContext();
+    tree.insertElement(token);
+    parser.phase = parser._inTableBodyPhase;
+  }
+
+  Token startTagImplyTbody(StartTagToken token) {
+    startTagRowGroup(new StartTagToken("tbody",
+        data: new LinkedHashMap<dynamic, String>()));
+    return token;
+  }
+
+  Token startTagTable(StartTagToken token) {
+    parser.parseError(token.span, "unexpected-start-tag-implies-end-tag", {
+      "startName": "table",
+      "endName": "table"
+    });
+    parser.phase.processEndTag(new EndTagToken("table"));
+    if (!parser.innerHTMLMode) {
+      return token;
+    }
+    return null;
+  }
+
+  Token startTagStyleScript(StartTagToken token) {
+    return parser._inHeadPhase.processStartTag(token);
+  }
+
+  void startTagInput(StartTagToken token) {
+    if (asciiUpper2Lower(token.data["type"]) == "hidden") {
+      parser.parseError(token.span, "unexpected-hidden-input-in-table");
+      tree.insertElement(token);
+      // XXX associate with form
+      tree.openElements.removeLast();
+    } else {
+      startTagOther(token);
+    }
+  }
+
+  void startTagForm(StartTagToken token) {
+    parser.parseError(token.span, "unexpected-form-in-table");
+    if (tree.formPointer == null) {
+      tree.insertElement(token);
+      tree.formPointer = tree.openElements.last;
+      tree.openElements.removeLast();
+    }
+  }
+
+  void startTagOther(StartTagToken token) {
+    parser.parseError(token.span, "unexpected-start-tag-implies-table-voodoo", {
+      "name": token.name
+    });
+    // Do the table magic!
+    tree.insertFromTable = true;
+    parser._inBodyPhase.processStartTag(token);
+    tree.insertFromTable = false;
+  }
+
+  void endTagTable(EndTagToken token) {
+    if (tree.elementInScope("table", variant: "table")) {
+      tree.generateImpliedEndTags();
+      var last = tree.openElements.last;
+      if (last.localName != "table") {
+        parser.parseError(token.span, "end-tag-too-early-named", {
+          "gotName": "table",
+          "expectedName": last.localName
+        });
+      }
+      while (tree.openElements.last.localName != "table") {
+        tree.openElements.removeLast();
+      }
+      var node = tree.openElements.removeLast();
+      node.endSourceSpan = token.span;
+      parser.resetInsertionMode();
+    } else {
+      // innerHTML case
+      assert(parser.innerHTMLMode);
+      parser.parseError(token.span, "undefined-error");
+    }
+  }
+
+  void endTagIgnore(EndTagToken token) {
+    parser.parseError(token.span, "unexpected-end-tag", {"name": token.name});
+  }
+
+  void endTagOther(EndTagToken token) {
+    parser.parseError(token.span, "unexpected-end-tag-implies-table-voodoo", {
+      "name": token.name
+    });
+    // Do the table magic!
+    tree.insertFromTable = true;
+    parser._inBodyPhase.processEndTag(token);
+    tree.insertFromTable = false;
+  }
+}
+
+class InTableTextPhase extends Phase {
+  Phase originalPhase;
+  List<StringToken> characterTokens;
+
+  InTableTextPhase(parser)
+      : characterTokens = <StringToken>[],
+        super(parser);
+
+  void flushCharacters() {
+    if (characterTokens.length == 0) return;
+
+    // TODO(sigmund,jmesserly): remove '' (dartbug.com/8480)
+    var data = characterTokens.map((t) => t.data).join('');
+    var span = null;
+
+    if (parser.generateSpans) {
+      span = characterTokens[0].span.expand(characterTokens.last.span);
+    }
+
+    if (!allWhitespace(data)) {
+      parser._inTablePhase.insertText(new CharactersToken(data)..span = span);
+    } else if (data.length > 0) {
+      tree.insertText(data, span);
+    }
+    characterTokens = <StringToken>[];
+  }
+
+  Token processComment(CommentToken token) {
+    flushCharacters();
+    parser.phase = originalPhase;
+    return token;
+  }
+
+  bool processEOF() {
+    flushCharacters();
+    parser.phase = originalPhase;
+    return true;
+  }
+
+  Token processCharacters(CharactersToken token) {
+    if (token.data == "\u0000") {
+      return null;
+    }
+    characterTokens.add(token);
+    return null;
+  }
+
+  Token processSpaceCharacters(SpaceCharactersToken token) {
+    //pretty sure we should never reach here
+    characterTokens.add(token);
+    // XXX assert(false);
+    return null;
+  }
+
+  Token processStartTag(StartTagToken token) {
+    flushCharacters();
+    parser.phase = originalPhase;
+    return token;
+  }
+
+  Token processEndTag(EndTagToken token) {
+    flushCharacters();
+    parser.phase = originalPhase;
+    return token;
+  }
+}
+
+class InCaptionPhase extends Phase {
+  // http://www.whatwg.org/specs/web-apps/current-work///in-caption
+  InCaptionPhase(parser) : super(parser);
+
+  processStartTag(StartTagToken token) {
+    switch (token.name) {
+      case "html":
+        return startTagHtml(token);
+      case "caption":
+      case "col":
+      case "colgroup":
+      case "tbody":
+      case "td":
+      case "tfoot":
+      case "th":
+      case "thead":
+      case "tr":
+        return startTagTableElement(token);
+      default:
+        return startTagOther(token);
+    }
+  }
+
+  processEndTag(EndTagToken token) {
+    switch (token.name) {
+      case "caption":
+        endTagCaption(token);
+        return null;
+      case "table":
+        return endTagTable(token);
+      case "body":
+      case "col":
+      case "colgroup":
+      case "html":
+      case "tbody":
+      case "td":
+      case "tfoot":
+      case "th":
+      case "thead":
+      case "tr":
+        endTagIgnore(token);
+        return null;
+      default:
+        return endTagOther(token);
+    }
+  }
+
+  bool ignoreEndTagCaption() {
+    return !tree.elementInScope("caption", variant: "table");
+  }
+
+  bool processEOF() {
+    parser._inBodyPhase.processEOF();
+    return false;
+  }
+
+  Token processCharacters(CharactersToken token) {
+    return parser._inBodyPhase.processCharacters(token);
+  }
+
+  Token startTagTableElement(StartTagToken token) {
+    parser.parseError(token.span, "undefined-error");
+    //XXX Have to duplicate logic here to find out if the tag is ignored
+    var ignoreEndTag = ignoreEndTagCaption();
+    parser.phase.processEndTag(new EndTagToken("caption"));
+    if (!ignoreEndTag) {
+      return token;
+    }
+    return null;
+  }
+
+  Token startTagOther(StartTagToken token) {
+    return parser._inBodyPhase.processStartTag(token);
+  }
+
+  void endTagCaption(EndTagToken token) {
+    if (!ignoreEndTagCaption()) {
+      // AT this code is quite similar to endTagTable in "InTable"
+      tree.generateImpliedEndTags();
+      if (tree.openElements.last.localName != "caption") {
+        parser.parseError(token.span, "expected-one-end-tag-but-got-another", {
+          "gotName": "caption",
+          "expectedName": tree.openElements.last.localName
+        });
+      }
+      while (tree.openElements.last.localName != "caption") {
+        tree.openElements.removeLast();
+      }
+      var node = tree.openElements.removeLast();
+      node.endSourceSpan = token.span;
+      tree.clearActiveFormattingElements();
+      parser.phase = parser._inTablePhase;
+    } else {
+      // innerHTML case
+      assert(parser.innerHTMLMode);
+      parser.parseError(token.span, "undefined-error");
+    }
+  }
+
+  Token endTagTable(EndTagToken token) {
+    parser.parseError(token.span, "undefined-error");
+    var ignoreEndTag = ignoreEndTagCaption();
+    parser.phase.processEndTag(new EndTagToken("caption"));
+    if (!ignoreEndTag) {
+      return token;
+    }
+    return null;
+  }
+
+  void endTagIgnore(EndTagToken token) {
+    parser.parseError(token.span, "unexpected-end-tag", {"name": token.name});
+  }
+
+  Token endTagOther(EndTagToken token) {
+    return parser._inBodyPhase.processEndTag(token);
+  }
+}
+
+class InColumnGroupPhase extends Phase {
+  // http://www.whatwg.org/specs/web-apps/current-work///in-column
+  InColumnGroupPhase(parser) : super(parser);
+
+  processStartTag(StartTagToken token) {
+    switch (token.name) {
+      case "html":
+        return startTagHtml(token);
+      case "col":
+        startTagCol(token);
+        return null;
+      default:
+        return startTagOther(token);
+    }
+  }
+
+  processEndTag(EndTagToken token) {
+    switch (token.name) {
+      case "colgroup":
+        endTagColgroup(token);
+        return null;
+      case "col":
+        endTagCol(token);
+        return null;
+      default:
+        return endTagOther(token);
+    }
+  }
+
+  bool ignoreEndTagColgroup() {
+    return tree.openElements.last.localName == "html";
+  }
+
+  bool processEOF() {
+    var ignoreEndTag = ignoreEndTagColgroup();
+    if (ignoreEndTag) {
+      assert(parser.innerHTMLMode);
+      return false;
+    } else {
+      endTagColgroup(new EndTagToken("colgroup"));
+      return true;
+    }
+  }
+
+  Token processCharacters(CharactersToken token) {
+    var ignoreEndTag = ignoreEndTagColgroup();
+    endTagColgroup(new EndTagToken("colgroup"));
+    return ignoreEndTag ? null : token;
+  }
+
+  void startTagCol(StartTagToken token) {
+    tree.insertElement(token);
+    tree.openElements.removeLast();
+  }
+
+  Token startTagOther(StartTagToken token) {
+    var ignoreEndTag = ignoreEndTagColgroup();
+    endTagColgroup(new EndTagToken("colgroup"));
+    return ignoreEndTag ? null : token;
+  }
+
+  void endTagColgroup(EndTagToken token) {
+    if (ignoreEndTagColgroup()) {
+      // innerHTML case
+      assert(parser.innerHTMLMode);
+      parser.parseError(token.span, "undefined-error");
+    } else {
+      var node = tree.openElements.removeLast();
+      node.endSourceSpan = token.span;
+      parser.phase = parser._inTablePhase;
+    }
+  }
+
+  void endTagCol(EndTagToken token) {
+    parser.parseError(token.span, "no-end-tag", {"name": "col"});
+  }
+
+  Token endTagOther(EndTagToken token) {
+    var ignoreEndTag = ignoreEndTagColgroup();
+    endTagColgroup(new EndTagToken("colgroup"));
+    return ignoreEndTag ? null : token;
+  }
+}
+
+class InTableBodyPhase extends Phase {
+  // http://www.whatwg.org/specs/web-apps/current-work///in-table0
+  InTableBodyPhase(parser) : super(parser);
+
+  processStartTag(StartTagToken token) {
+    switch (token.name) {
+      case "html":
+        return startTagHtml(token);
+      case "tr":
+        startTagTr(token);
+        return null;
+      case "td":
+      case "th":
+        return startTagTableCell(token);
+      case "caption":
+      case "col":
+      case "colgroup":
+      case "tbody":
+      case "tfoot":
+      case "thead":
+        return startTagTableOther(token);
+      default:
+        return startTagOther(token);
+    }
+  }
+
+  processEndTag(EndTagToken token) {
+    switch (token.name) {
+      case "tbody":
+      case "tfoot":
+      case "thead":
+        endTagTableRowGroup(token);
+        return null;
+      case "table":
+        return endTagTable(token);
+      case "body":
+      case "caption":
+      case "col":
+      case "colgroup":
+      case "html":
+      case "td":
+      case "th":
+      case "tr":
+        endTagIgnore(token);
+        return null;
+      default:
+        return endTagOther(token);
+    }
+  }
+
+  // helper methods
+  void clearStackToTableBodyContext() {
+    var tableTags = const ["tbody", "tfoot", "thead", "html"];
+    while (!tableTags.contains(tree.openElements.last.localName)) {
+      //XXX parser.parseError(token.span, "unexpected-implied-end-tag-in-table",
+      //  {"name": tree.openElements.last.name})
+      tree.openElements.removeLast();
+    }
+    if (tree.openElements.last.localName == "html") {
+      assert(parser.innerHTMLMode);
+    }
+  }
+
+  // the rest
+  bool processEOF() {
+    parser._inTablePhase.processEOF();
+    return false;
+  }
+
+  Token processSpaceCharacters(SpaceCharactersToken token) {
+    return parser._inTablePhase.processSpaceCharacters(token);
+  }
+
+  Token processCharacters(CharactersToken token) {
+    return parser._inTablePhase.processCharacters(token);
+  }
+
+  void startTagTr(StartTagToken token) {
+    clearStackToTableBodyContext();
+    tree.insertElement(token);
+    parser.phase = parser._inRowPhase;
+  }
+
+  Token startTagTableCell(StartTagToken token) {
+    parser.parseError(
+        token.span, "unexpected-cell-in-table-body", {"name": token.name});
+    startTagTr(new StartTagToken("tr",
+        data: new LinkedHashMap<dynamic, String>()));
+    return token;
+  }
+
+  Token startTagTableOther(token) => endTagTable(token);
+
+  Token startTagOther(StartTagToken token) {
+    return parser._inTablePhase.processStartTag(token);
+  }
+
+  void endTagTableRowGroup(EndTagToken token) {
+    if (tree.elementInScope(token.name, variant: "table")) {
+      clearStackToTableBodyContext();
+      var node = tree.openElements.removeLast();
+      node.endSourceSpan = token.span;
+      parser.phase = parser._inTablePhase;
+    } else {
+      parser.parseError(
+          token.span, "unexpected-end-tag-in-table-body", {"name": token.name});
+    }
+  }
+
+  Token endTagTable(TagToken token) {
+    // XXX AT Any ideas on how to share this with endTagTable?
+    if (tree.elementInScope("tbody", variant: "table") ||
+        tree.elementInScope("thead", variant: "table") ||
+        tree.elementInScope("tfoot", variant: "table")) {
+      clearStackToTableBodyContext();
+      endTagTableRowGroup(new EndTagToken(tree.openElements.last.localName));
+      return token;
+    } else {
+      // innerHTML case
+      assert(parser.innerHTMLMode);
+      parser.parseError(token.span, "undefined-error");
+    }
+    return null;
+  }
+
+  void endTagIgnore(EndTagToken token) {
+    parser.parseError(
+        token.span, "unexpected-end-tag-in-table-body", {"name": token.name});
+  }
+
+  Token endTagOther(EndTagToken token) {
+    return parser._inTablePhase.processEndTag(token);
+  }
+}
+
+class InRowPhase extends Phase {
+  // http://www.whatwg.org/specs/web-apps/current-work///in-row
+  InRowPhase(parser) : super(parser);
+
+  processStartTag(StartTagToken token) {
+    switch (token.name) {
+      case "html":
+        return startTagHtml(token);
+      case "td":
+      case "th":
+        startTagTableCell(token);
+        return null;
+      case "caption":
+      case "col":
+      case "colgroup":
+      case "tbody":
+      case "tfoot":
+      case "thead":
+      case "tr":
+        return startTagTableOther(token);
+      default:
+        return startTagOther(token);
+    }
+  }
+
+  processEndTag(EndTagToken token) {
+    switch (token.name) {
+      case "tr":
+        endTagTr(token);
+        return null;
+      case "table":
+        return endTagTable(token);
+      case "tbody":
+      case "tfoot":
+      case "thead":
+        return endTagTableRowGroup(token);
+      case "body":
+      case "caption":
+      case "col":
+      case "colgroup":
+      case "html":
+      case "td":
+      case "th":
+        endTagIgnore(token);
+        return null;
+      default:
+        return endTagOther(token);
+    }
+  }
+
+  // helper methods (XXX unify this with other table helper methods)
+  void clearStackToTableRowContext() {
+    while (true) {
+      var last = tree.openElements.last;
+      if (last.localName == "tr" || last.localName == "html") break;
+
+      parser.parseError(last.sourceSpan,
+          "unexpected-implied-end-tag-in-table-row", {
+        "name": tree.openElements.last.localName
+      });
+      tree.openElements.removeLast();
+    }
+  }
+
+  bool ignoreEndTagTr() {
+    return !tree.elementInScope("tr", variant: "table");
+  }
+
+  // the rest
+  bool processEOF() {
+    parser._inTablePhase.processEOF();
+    return false;
+  }
+
+  Token processSpaceCharacters(SpaceCharactersToken token) {
+    return parser._inTablePhase.processSpaceCharacters(token);
+  }
+
+  Token processCharacters(CharactersToken token) {
+    return parser._inTablePhase.processCharacters(token);
+  }
+
+  void startTagTableCell(StartTagToken token) {
+    clearStackToTableRowContext();
+    tree.insertElement(token);
+    parser.phase = parser._inCellPhase;
+    tree.activeFormattingElements.add(Marker);
+  }
+
+  Token startTagTableOther(StartTagToken token) {
+    bool ignoreEndTag = ignoreEndTagTr();
+    endTagTr(new EndTagToken("tr"));
+    // XXX how are we sure it's always ignored in the innerHTML case?
+    return ignoreEndTag ? null : token;
+  }
+
+  Token startTagOther(StartTagToken token) {
+    return parser._inTablePhase.processStartTag(token);
+  }
+
+  void endTagTr(EndTagToken token) {
+    if (!ignoreEndTagTr()) {
+      clearStackToTableRowContext();
+      var node = tree.openElements.removeLast();
+      node.endSourceSpan = token.span;
+      parser.phase = parser._inTableBodyPhase;
+    } else {
+      // innerHTML case
+      assert(parser.innerHTMLMode);
+      parser.parseError(token.span, "undefined-error");
+    }
+  }
+
+  Token endTagTable(EndTagToken token) {
+    var ignoreEndTag = ignoreEndTagTr();
+    endTagTr(new EndTagToken("tr"));
+    // Reprocess the current tag if the tr end tag was not ignored
+    // XXX how are we sure it's always ignored in the innerHTML case?
+    return ignoreEndTag ? null : token;
+  }
+
+  Token endTagTableRowGroup(EndTagToken token) {
+    if (tree.elementInScope(token.name, variant: "table")) {
+      endTagTr(new EndTagToken("tr"));
+      return token;
+    } else {
+      parser.parseError(token.span, "undefined-error");
+      return null;
+    }
+  }
+
+  void endTagIgnore(EndTagToken token) {
+    parser.parseError(
+        token.span, "unexpected-end-tag-in-table-row", {"name": token.name});
+  }
+
+  Token endTagOther(EndTagToken token) {
+    return parser._inTablePhase.processEndTag(token);
+  }
+}
+
+class InCellPhase extends Phase {
+  // http://www.whatwg.org/specs/web-apps/current-work///in-cell
+  InCellPhase(parser) : super(parser);
+
+  processStartTag(StartTagToken token) {
+    switch (token.name) {
+      case "html":
+        return startTagHtml(token);
+      case "caption":
+      case "col":
+      case "colgroup":
+      case "tbody":
+      case "td":
+      case "tfoot":
+      case "th":
+      case "thead":
+      case "tr":
+        return startTagTableOther(token);
+      default:
+        return startTagOther(token);
+    }
+  }
+
+  processEndTag(EndTagToken token) {
+    switch (token.name) {
+      case "td":
+      case "th":
+        endTagTableCell(token);
+        return null;
+      case "body":
+      case "caption":
+      case "col":
+      case "colgroup":
+      case "html":
+        endTagIgnore(token);
+        return null;
+      case "table":
+      case "tbody":
+      case "tfoot":
+      case "thead":
+      case "tr":
+        return endTagImply(token);
+      default:
+        return endTagOther(token);
+    }
+  }
+
+  // helper
+  void closeCell() {
+    if (tree.elementInScope("td", variant: "table")) {
+      endTagTableCell(new EndTagToken("td"));
+    } else if (tree.elementInScope("th", variant: "table")) {
+      endTagTableCell(new EndTagToken("th"));
+    }
+  }
+
+  // the rest
+  bool processEOF() {
+    parser._inBodyPhase.processEOF();
+    return false;
+  }
+
+  Token processCharacters(CharactersToken token) {
+    return parser._inBodyPhase.processCharacters(token);
+  }
+
+  Token startTagTableOther(StartTagToken token) {
+    if (tree.elementInScope("td", variant: "table") ||
+        tree.elementInScope("th", variant: "table")) {
+      closeCell();
+      return token;
+    } else {
+      // innerHTML case
+      assert(parser.innerHTMLMode);
+      parser.parseError(token.span, "undefined-error");
+      return null;
+    }
+  }
+
+  Token startTagOther(StartTagToken token) {
+    return parser._inBodyPhase.processStartTag(token);
+  }
+
+  void endTagTableCell(EndTagToken token) {
+    if (tree.elementInScope(token.name, variant: "table")) {
+      tree.generateImpliedEndTags(token.name);
+      if (tree.openElements.last.localName != token.name) {
+        parser.parseError(
+            token.span, "unexpected-cell-end-tag", {"name": token.name});
+        popOpenElementsUntil(token);
+      } else {
+        var node = tree.openElements.removeLast();
+        node.endSourceSpan = token.span;
+      }
+      tree.clearActiveFormattingElements();
+      parser.phase = parser._inRowPhase;
+    } else {
+      parser.parseError(token.span, "unexpected-end-tag", {"name": token.name});
+    }
+  }
+
+  void endTagIgnore(EndTagToken token) {
+    parser.parseError(token.span, "unexpected-end-tag", {"name": token.name});
+  }
+
+  Token endTagImply(EndTagToken token) {
+    if (tree.elementInScope(token.name, variant: "table")) {
+      closeCell();
+      return token;
+    } else {
+      // sometimes innerHTML case
+      parser.parseError(token.span, "undefined-error");
+    }
+    return null;
+  }
+
+  Token endTagOther(EndTagToken token) {
+    return parser._inBodyPhase.processEndTag(token);
+  }
+}
+
+class InSelectPhase extends Phase {
+  InSelectPhase(parser) : super(parser);
+
+  processStartTag(StartTagToken token) {
+    switch (token.name) {
+      case "html":
+        return startTagHtml(token);
+      case "option":
+        startTagOption(token);
+        return null;
+      case "optgroup":
+        startTagOptgroup(token);
+        return null;
+      case "select":
+        startTagSelect(token);
+        return null;
+      case "input":
+      case "keygen":
+      case "textarea":
+        return startTagInput(token);
+      case "script":
+        return startTagScript(token);
+      default:
+        return startTagOther(token);
+    }
+  }
+
+  processEndTag(EndTagToken token) {
+    switch (token.name) {
+      case "option":
+        endTagOption(token);
+        return null;
+      case "optgroup":
+        endTagOptgroup(token);
+        return null;
+      case "select":
+        endTagSelect(token);
+        return null;
+      default:
+        endTagOther(token);
+        return null;
+    }
+  }
+
+  // http://www.whatwg.org/specs/web-apps/current-work///in-select
+  bool processEOF() {
+    var last = tree.openElements.last;
+    if (last.localName != "html") {
+      parser.parseError(last.sourceSpan, "eof-in-select");
+    } else {
+      assert(parser.innerHTMLMode);
+    }
+    return false;
+  }
+
+  Token processCharacters(CharactersToken token) {
+    if (token.data == "\u0000") {
+      return null;
+    }
+    tree.insertText(token.data, token.span);
+    return null;
+  }
+
+  void startTagOption(StartTagToken token) {
+    // We need to imply </option> if <option> is the current node.
+    if (tree.openElements.last.localName == "option") {
+      tree.openElements.removeLast();
+    }
+    tree.insertElement(token);
+  }
+
+  void startTagOptgroup(StartTagToken token) {
+    if (tree.openElements.last.localName == "option") {
+      tree.openElements.removeLast();
+    }
+    if (tree.openElements.last.localName == "optgroup") {
+      tree.openElements.removeLast();
+    }
+    tree.insertElement(token);
+  }
+
+  void startTagSelect(StartTagToken token) {
+    parser.parseError(token.span, "unexpected-select-in-select");
+    endTagSelect(new EndTagToken("select"));
+  }
+
+  Token startTagInput(StartTagToken token) {
+    parser.parseError(token.span, "unexpected-input-in-select");
+    if (tree.elementInScope("select", variant: "select")) {
+      endTagSelect(new EndTagToken("select"));
+      return token;
+    } else {
+      assert(parser.innerHTMLMode);
+    }
+    return null;
+  }
+
+  Token startTagScript(StartTagToken token) {
+    return parser._inHeadPhase.processStartTag(token);
+  }
+
+  Token startTagOther(StartTagToken token) {
+    parser.parseError(
+        token.span, "unexpected-start-tag-in-select", {"name": token.name});
+    return null;
+  }
+
+  void endTagOption(EndTagToken token) {
+    if (tree.openElements.last.localName == "option") {
+      var node = tree.openElements.removeLast();
+      node.endSourceSpan = token.span;
+    } else {
+      parser.parseError(
+          token.span, "unexpected-end-tag-in-select", {"name": "option"});
+    }
+  }
+
+  void endTagOptgroup(EndTagToken token) {
+    // </optgroup> implicitly closes <option>
+    if (tree.openElements.last.localName == "option" &&
+        tree.openElements[tree.openElements.length - 2].localName ==
+            "optgroup") {
+      tree.openElements.removeLast();
+    }
+    // It also closes </optgroup>
+    if (tree.openElements.last.localName == "optgroup") {
+      var node = tree.openElements.removeLast();
+      node.endSourceSpan = token.span;
+      // But nothing else
+    } else {
+      parser.parseError(
+          token.span, "unexpected-end-tag-in-select", {"name": "optgroup"});
+    }
+  }
+
+  void endTagSelect(EndTagToken token) {
+    if (tree.elementInScope("select", variant: "select")) {
+      popOpenElementsUntil(token);
+      parser.resetInsertionMode();
+    } else {
+      // innerHTML case
+      assert(parser.innerHTMLMode);
+      parser.parseError(token.span, "undefined-error");
+    }
+  }
+
+  void endTagOther(EndTagToken token) {
+    parser.parseError(
+        token.span, "unexpected-end-tag-in-select", {"name": token.name});
+  }
+}
+
+class InSelectInTablePhase extends Phase {
+  InSelectInTablePhase(parser) : super(parser);
+
+  processStartTag(StartTagToken token) {
+    switch (token.name) {
+      case "caption":
+      case "table":
+      case "tbody":
+      case "tfoot":
+      case "thead":
+      case "tr":
+      case "td":
+      case "th":
+        return startTagTable(token);
+      default:
+        return startTagOther(token);
+    }
+  }
+
+  processEndTag(EndTagToken token) {
+    switch (token.name) {
+      case "caption":
+      case "table":
+      case "tbody":
+      case "tfoot":
+      case "thead":
+      case "tr":
+      case "td":
+      case "th":
+        return endTagTable(token);
+      default:
+        return endTagOther(token);
+    }
+  }
+
+  bool processEOF() {
+    parser._inSelectPhase.processEOF();
+    return false;
+  }
+
+  Token processCharacters(CharactersToken token) {
+    return parser._inSelectPhase.processCharacters(token);
+  }
+
+  Token startTagTable(StartTagToken token) {
+    parser.parseError(token.span,
+        "unexpected-table-element-start-tag-in-select-in-table", {
+      "name": token.name
+    });
+    endTagOther(new EndTagToken("select"));
+    return token;
+  }
+
+  Token startTagOther(StartTagToken token) {
+    return parser._inSelectPhase.processStartTag(token);
+  }
+
+  Token endTagTable(EndTagToken token) {
+    parser.parseError(token.span,
+        "unexpected-table-element-end-tag-in-select-in-table", {
+      "name": token.name
+    });
+    if (tree.elementInScope(token.name, variant: "table")) {
+      endTagOther(new EndTagToken("select"));
+      return token;
+    }
+    return null;
+  }
+
+  Token endTagOther(EndTagToken token) {
+    return parser._inSelectPhase.processEndTag(token);
+  }
+}
+
+class InForeignContentPhase extends Phase {
+  // TODO(jmesserly): this is sorted so we could binary search.
+  static const breakoutElements = const [
+    'b',
+    'big',
+    'blockquote',
+    'body',
+    'br',
+    'center',
+    'code',
+    'dd',
+    'div',
+    'dl',
+    'dt',
+    'em',
+    'embed',
+    'h1',
+    'h2',
+    'h3',
+    'h4',
+    'h5',
+    'h6',
+    'head',
+    'hr',
+    'i',
+    'img',
+    'li',
+    'listing',
+    'menu',
+    'meta',
+    'nobr',
+    'ol',
+    'p',
+    'pre',
+    'ruby',
+    's',
+    'small',
+    'span',
+    'strike',
+    'strong',
+    'sub',
+    'sup',
+    'table',
+    'tt',
+    'u',
+    'ul',
+    'var'
+  ];
+
+  InForeignContentPhase(parser) : super(parser);
+
+  void adjustSVGTagNames(token) {
+    final replacements = const {
+      "altglyph": "altGlyph",
+      "altglyphdef": "altGlyphDef",
+      "altglyphitem": "altGlyphItem",
+      "animatecolor": "animateColor",
+      "animatemotion": "animateMotion",
+      "animatetransform": "animateTransform",
+      "clippath": "clipPath",
+      "feblend": "feBlend",
+      "fecolormatrix": "feColorMatrix",
+      "fecomponenttransfer": "feComponentTransfer",
+      "fecomposite": "feComposite",
+      "feconvolvematrix": "feConvolveMatrix",
+      "fediffuselighting": "feDiffuseLighting",
+      "fedisplacementmap": "feDisplacementMap",
+      "fedistantlight": "feDistantLight",
+      "feflood": "feFlood",
+      "fefunca": "feFuncA",
+      "fefuncb": "feFuncB",
+      "fefuncg": "feFuncG",
+      "fefuncr": "feFuncR",
+      "fegaussianblur": "feGaussianBlur",
+      "feimage": "feImage",
+      "femerge": "feMerge",
+      "femergenode": "feMergeNode",
+      "femorphology": "feMorphology",
+      "feoffset": "feOffset",
+      "fepointlight": "fePointLight",
+      "fespecularlighting": "feSpecularLighting",
+      "fespotlight": "feSpotLight",
+      "fetile": "feTile",
+      "feturbulence": "feTurbulence",
+      "foreignobject": "foreignObject",
+      "glyphref": "glyphRef",
+      "lineargradient": "linearGradient",
+      "radialgradient": "radialGradient",
+      "textpath": "textPath"
+    };
+
+    var replace = replacements[token.name];
+    if (replace != null) {
+      token.name = replace;
+    }
+  }
+
+  Token processCharacters(CharactersToken token) {
+    if (token.data == "\u0000") {
+      token.replaceData("\uFFFD");
+    } else if (parser.framesetOK && !allWhitespace(token.data)) {
+      parser.framesetOK = false;
+    }
+    return super.processCharacters(token);
+  }
+
+  Token processStartTag(StartTagToken token) {
+    var currentNode = tree.openElements.last;
+    if (breakoutElements.contains(token.name) ||
+        (token.name == "font" &&
+            (token.data.containsKey("color") ||
+                token.data.containsKey("face") ||
+                token.data.containsKey("size")))) {
+      parser.parseError(token.span,
+          "unexpected-html-element-in-foreign-content", {'name': token.name});
+      while (tree.openElements.last.namespaceUri != tree.defaultNamespace &&
+          !parser.isHTMLIntegrationPoint(tree.openElements.last) &&
+          !parser.isMathMLTextIntegrationPoint(tree.openElements.last)) {
+        tree.openElements.removeLast();
+      }
+      return token;
+    } else {
+      if (currentNode.namespaceUri == Namespaces.mathml) {
+        parser.adjustMathMLAttributes(token);
+      } else if (currentNode.namespaceUri == Namespaces.svg) {
+        adjustSVGTagNames(token);
+        parser.adjustSVGAttributes(token);
+      }
+      parser.adjustForeignAttributes(token);
+      token.namespace = currentNode.namespaceUri;
+      tree.insertElement(token);
+      if (token.selfClosing) {
+        tree.openElements.removeLast();
+        token.selfClosingAcknowledged = true;
+      }
+      return null;
+    }
+  }
+
+  Token processEndTag(EndTagToken token) {
+    var nodeIndex = tree.openElements.length - 1;
+    var node = tree.openElements.last;
+    if (asciiUpper2Lower(node.localName) != token.name) {
+      parser.parseError(token.span, "unexpected-end-tag", {"name": token.name});
+    }
+
+    var newToken = null;
+    while (true) {
+      if (asciiUpper2Lower(node.localName) == token.name) {
+        //XXX this isn't in the spec but it seems necessary
+        if (parser.phase == parser._inTableTextPhase) {
+          InTableTextPhase inTableText = parser.phase;
+          inTableText.flushCharacters();
+          parser.phase = inTableText.originalPhase;
+        }
+        while (tree.openElements.removeLast() != node) {
+          assert(tree.openElements.length > 0);
+        }
+        newToken = null;
+        break;
+      }
+      nodeIndex -= 1;
+
+      node = tree.openElements[nodeIndex];
+      if (node.namespaceUri != tree.defaultNamespace) {
+        continue;
+      } else {
+        newToken = parser.phase.processEndTag(token);
+        break;
+      }
+    }
+    return newToken;
+  }
+}
+
+class AfterBodyPhase extends Phase {
+  AfterBodyPhase(parser) : super(parser);
+
+  processStartTag(StartTagToken token) {
+    if (token.name == "html") return startTagHtml(token);
+    return startTagOther(token);
+  }
+
+  processEndTag(EndTagToken token) {
+    if (token.name == "html") {
+      endTagHtml(token);
+      return null;
+    }
+    return endTagOther(token);
+  }
+
+  //Stop parsing
+  bool processEOF() => false;
+
+  Token processComment(CommentToken token) {
+    // This is needed because data is to be appended to the <html> element
+    // here and not to whatever is currently open.
+    tree.insertComment(token, tree.openElements[0]);
+    return null;
+  }
+
+  Token processCharacters(CharactersToken token) {
+    parser.parseError(token.span, "unexpected-char-after-body");
+    parser.phase = parser._inBodyPhase;
+    return token;
+  }
+
+  Token startTagHtml(StartTagToken token) {
+    return parser._inBodyPhase.processStartTag(token);
+  }
+
+  Token startTagOther(StartTagToken token) {
+    parser.parseError(
+        token.span, "unexpected-start-tag-after-body", {"name": token.name});
+    parser.phase = parser._inBodyPhase;
+    return token;
+  }
+
+  void endTagHtml(Token token) {
+    for (var node in tree.openElements.reversed) {
+      if (node.localName == 'html') {
+        node.endSourceSpan = token.span;
+        break;
+      }
+    }
+    if (parser.innerHTMLMode) {
+      parser.parseError(token.span, "unexpected-end-tag-after-body-innerhtml");
+    } else {
+      parser.phase = parser._afterAfterBodyPhase;
+    }
+  }
+
+  Token endTagOther(EndTagToken token) {
+    parser.parseError(
+        token.span, "unexpected-end-tag-after-body", {"name": token.name});
+    parser.phase = parser._inBodyPhase;
+    return token;
+  }
+}
+
+class InFramesetPhase extends Phase {
+  // http://www.whatwg.org/specs/web-apps/current-work///in-frameset
+  InFramesetPhase(parser) : super(parser);
+
+  processStartTag(StartTagToken token) {
+    switch (token.name) {
+      case "html":
+        return startTagHtml(token);
+      case "frameset":
+        startTagFrameset(token);
+        return null;
+      case "frame":
+        startTagFrame(token);
+        return null;
+      case "noframes":
+        return startTagNoframes(token);
+      default:
+        return startTagOther(token);
+    }
+  }
+
+  processEndTag(EndTagToken token) {
+    switch (token.name) {
+      case "frameset":
+        endTagFrameset(token);
+        return null;
+      default:
+        endTagOther(token);
+        return null;
+    }
+  }
+
+  bool processEOF() {
+    var last = tree.openElements.last;
+    if (last.localName != "html") {
+      parser.parseError(last.sourceSpan, "eof-in-frameset");
+    } else {
+      assert(parser.innerHTMLMode);
+    }
+    return false;
+  }
+
+  Token processCharacters(CharactersToken token) {
+    parser.parseError(token.span, "unexpected-char-in-frameset");
+    return null;
+  }
+
+  void startTagFrameset(StartTagToken token) {
+    tree.insertElement(token);
+  }
+
+  void startTagFrame(StartTagToken token) {
+    tree.insertElement(token);
+    tree.openElements.removeLast();
+  }
+
+  Token startTagNoframes(StartTagToken token) {
+    return parser._inBodyPhase.processStartTag(token);
+  }
+
+  Token startTagOther(StartTagToken token) {
+    parser.parseError(
+        token.span, "unexpected-start-tag-in-frameset", {"name": token.name});
+    return null;
+  }
+
+  void endTagFrameset(EndTagToken token) {
+    if (tree.openElements.last.localName == "html") {
+      // innerHTML case
+      parser.parseError(
+          token.span, "unexpected-frameset-in-frameset-innerhtml");
+    } else {
+      var node = tree.openElements.removeLast();
+      node.endSourceSpan = token.span;
+    }
+    if (!parser.innerHTMLMode &&
+        tree.openElements.last.localName != "frameset") {
+      // If we're not in innerHTML mode and the the current node is not a
+      // "frameset" element (anymore) then switch.
+      parser.phase = parser._afterFramesetPhase;
+    }
+  }
+
+  void endTagOther(EndTagToken token) {
+    parser.parseError(
+        token.span, "unexpected-end-tag-in-frameset", {"name": token.name});
+  }
+}
+
+class AfterFramesetPhase extends Phase {
+  // http://www.whatwg.org/specs/web-apps/current-work///after3
+  AfterFramesetPhase(parser) : super(parser);
+
+  processStartTag(StartTagToken token) {
+    switch (token.name) {
+      case "html":
+        return startTagHtml(token);
+      case "noframes":
+        return startTagNoframes(token);
+      default:
+        startTagOther(token);
+        return null;
+    }
+  }
+
+  processEndTag(EndTagToken token) {
+    switch (token.name) {
+      case "html":
+        endTagHtml(token);
+        return null;
+      default:
+        endTagOther(token);
+        return null;
+    }
+  }
+
+  // Stop parsing
+  bool processEOF() => false;
+
+  Token processCharacters(CharactersToken token) {
+    parser.parseError(token.span, "unexpected-char-after-frameset");
+    return null;
+  }
+
+  Token startTagNoframes(StartTagToken token) {
+    return parser._inHeadPhase.processStartTag(token);
+  }
+
+  void startTagOther(StartTagToken token) {
+    parser.parseError(token.span, "unexpected-start-tag-after-frameset", {
+      "name": token.name
+    });
+  }
+
+  void endTagHtml(EndTagToken token) {
+    parser.phase = parser._afterAfterFramesetPhase;
+  }
+
+  void endTagOther(EndTagToken token) {
+    parser.parseError(
+        token.span, "unexpected-end-tag-after-frameset", {"name": token.name});
+  }
+}
+
+class AfterAfterBodyPhase extends Phase {
+  AfterAfterBodyPhase(parser) : super(parser);
+
+  processStartTag(StartTagToken token) {
+    if (token.name == 'html') return startTagHtml(token);
+    return startTagOther(token);
+  }
+
+  bool processEOF() => false;
+
+  Token processComment(CommentToken token) {
+    tree.insertComment(token, tree.document);
+    return null;
+  }
+
+  Token processSpaceCharacters(SpaceCharactersToken token) {
+    return parser._inBodyPhase.processSpaceCharacters(token);
+  }
+
+  Token processCharacters(CharactersToken token) {
+    parser.parseError(token.span, "expected-eof-but-got-char");
+    parser.phase = parser._inBodyPhase;
+    return token;
+  }
+
+  Token startTagHtml(StartTagToken token) {
+    return parser._inBodyPhase.processStartTag(token);
+  }
+
+  Token startTagOther(StartTagToken token) {
+    parser.parseError(
+        token.span, "expected-eof-but-got-start-tag", {"name": token.name});
+    parser.phase = parser._inBodyPhase;
+    return token;
+  }
+
+  Token processEndTag(EndTagToken token) {
+    parser.parseError(
+        token.span, "expected-eof-but-got-end-tag", {"name": token.name});
+    parser.phase = parser._inBodyPhase;
+    return token;
+  }
+}
+
+class AfterAfterFramesetPhase extends Phase {
+  AfterAfterFramesetPhase(parser) : super(parser);
+
+  processStartTag(StartTagToken token) {
+    switch (token.name) {
+      case "html":
+        return startTagHtml(token);
+      case "noframes":
+        return startTagNoFrames(token);
+      default:
+        startTagOther(token);
+        return null;
+    }
+  }
+
+  bool processEOF() => false;
+
+  Token processComment(CommentToken token) {
+    tree.insertComment(token, tree.document);
+    return null;
+  }
+
+  Token processSpaceCharacters(SpaceCharactersToken token) {
+    return parser._inBodyPhase.processSpaceCharacters(token);
+  }
+
+  Token processCharacters(CharactersToken token) {
+    parser.parseError(token.span, "expected-eof-but-got-char");
+    return null;
+  }
+
+  Token startTagHtml(StartTagToken token) {
+    return parser._inBodyPhase.processStartTag(token);
+  }
+
+  Token startTagNoFrames(StartTagToken token) {
+    return parser._inHeadPhase.processStartTag(token);
+  }
+
+  void startTagOther(StartTagToken token) {
+    parser.parseError(
+        token.span, "expected-eof-but-got-start-tag", {"name": token.name});
+  }
+
+  Token processEndTag(EndTagToken token) {
+    parser.parseError(
+        token.span, "expected-eof-but-got-end-tag", {"name": token.name});
+    return null;
+  }
+}
+
+/// Error in parsed document.
+class ParseError implements SourceSpanException {
+  final String errorCode;
+  final SourceSpan span;
+  final Map data;
+
+  ParseError(this.errorCode, this.span, this.data);
+
+  int get line => span.start.line;
+
+  int get column => span.start.column;
+
+  /// Gets the human readable error message for this error. Use
+  /// [span.getLocationMessage] or [toString] to get a message including span
+  /// information. If there is a file associated with the span, both
+  /// [span.getLocationMessage] and [toString] are equivalent. Otherwise,
+  /// [span.getLocationMessage] will not show any source url information, but
+  /// [toString] will include 'ParserError:' as a prefix.
+  String get message => formatStr(errorMessages[errorCode], data);
+
+  String toString({color}) {
+    var res = span.message(message, color: color);
+    return span.sourceUrl == null ? 'ParserError on $res' : 'On $res';
+  }
+}
+
+/// Convenience function to get the pair of namespace and localName.
+Pair<String, String> getElementNameTuple(Element e) {
+  var ns = e.namespaceUri;
+  if (ns == null) ns = Namespaces.html;
+  return new Pair(ns, e.localName);
+}
diff --git a/html/lib/parser_console.dart b/html/lib/parser_console.dart
new file mode 100644
index 0000000..515f891
--- /dev/null
+++ b/html/lib/parser_console.dart
@@ -0,0 +1,42 @@
+/// This library adds `dart:io` support to the HTML5 parser. Call
+/// [initDartIOSupport] before calling the [parse] methods and they will accept
+/// a [RandomAccessFile] as input, in addition to the other input types.
+library parser_console;
+
+import 'dart:io';
+import 'parser.dart';
+import 'src/inputstream.dart' as inputstream;
+
+/// Adds support to the [HtmlParser] for running on a console VM. In particular
+/// this means it will be able to handle `dart:io` and [RandomAccessFile]s as
+/// input to the various [parse] methods.
+void useConsole() {
+  inputstream.consoleSupport = new _ConsoleSupport();
+}
+
+class _ConsoleSupport extends inputstream.ConsoleSupport {
+  List<int> bytesFromFile(source) {
+    if (source is! RandomAccessFile) return null;
+    return readAllBytesFromFile(source);
+  }
+}
+
+// TODO(jmesserly): this should be `RandomAccessFile.readAllBytes`.
+/// Synchronously reads all bytes from the [file].
+List<int> readAllBytesFromFile(RandomAccessFile file) {
+  int length = file.lengthSync();
+  var bytes = new List<int>(length);
+
+  int bytesRead = 0;
+  while (bytesRead < length) {
+    int read = file.readIntoSync(bytes, bytesRead, length - bytesRead);
+    if (read <= 0) {
+      // This could happen if, for example, the file was resized while
+      // we're reading. Just shrink the bytes array and move on.
+      bytes = bytes.sublist(0, bytesRead);
+      break;
+    }
+    bytesRead += read;
+  }
+  return bytes;
+}
diff --git a/html/lib/src/char_encodings.dart b/html/lib/src/char_encodings.dart
new file mode 100644
index 0000000..5ddf727
--- /dev/null
+++ b/html/lib/src/char_encodings.dart
@@ -0,0 +1,223 @@
+/// Decodes bytes using the correct name. See [decodeBytes].
+library char_encodings;
+
+import 'dart:collection';
+import 'package:utf/utf.dart';
+
+// TODO(jmesserly): this function is conspicuously absent from dart:utf.
+/// Returns true if the [bytes] starts with a UTF-8 byte order mark.
+/// Since UTF-8 doesn't have byte order, it's somewhat of a misnomer, but it is
+/// used in HTML to detect the UTF-
+bool hasUtf8Bom(List<int> bytes, [int offset = 0, int length]) {
+  int end = length != null ? offset + length : bytes.length;
+  return (offset + 3) <= end &&
+      bytes[offset] == 0xEF &&
+      bytes[offset + 1] == 0xBB &&
+      bytes[offset + 2] == 0xBF;
+}
+
+// TODO(jmesserly): it's unfortunate that this has to be one-shot on the entire
+// file, but dart:utf does not expose stream-based decoders yet.
+/// Decodes the [bytes] with the provided [encoding] and returns an iterable for
+/// the codepoints. Supports the major unicode encodings as well as ascii and
+/// and windows-1252 encodings.
+Iterable<int> decodeBytes(String encoding, List<int> bytes, [int offset = 0,
+    int length,
+    int replacementCodepoint = UNICODE_REPLACEMENT_CHARACTER_CODEPOINT]) {
+  if (length == null) length = bytes.length;
+  final replace = replacementCodepoint;
+  switch (encoding) {
+    case 'ascii':
+      bytes = bytes.sublist(offset, offset + length);
+      // TODO(jmesserly): this was taken from runtime/bin/string_stream.dart
+      for (int byte in bytes) {
+        if (byte > 127) {
+          // TODO(jmesserly): ideally this would be DecoderException, like the
+          // one thrown in runtime/bin/string_stream.dart, but we don't want to
+          // depend on dart:io.
+          throw new FormatException("Illegal ASCII character $byte");
+        }
+      }
+      return bytes;
+
+    case 'windows-1252':
+    case 'cp1252':
+      return decodeWindows1252AsIterable(bytes, offset, length, replace);
+
+    case 'utf-8':
+      // NOTE: to match the behavior of the other decode functions, we eat the
+      // utf-8 BOM here.
+      if (hasUtf8Bom(bytes, offset, length)) {
+        offset += 3;
+        length -= 3;
+      }
+      return decodeUtf8AsIterable(bytes, offset, length, replace);
+
+    case 'utf-16':
+      return decodeUtf16AsIterable(bytes, offset, length, replace);
+    case 'utf-16-be':
+      return decodeUtf16beAsIterable(bytes, offset, length, true, replace);
+    case 'utf-16-le':
+      return decodeUtf16leAsIterable(bytes, offset, length, true, replace);
+
+    case 'utf-32':
+      return decodeUtf32AsIterable(bytes, offset, length, replace);
+    case 'utf-32-be':
+      return decodeUtf32beAsIterable(bytes, offset, length, true, replace);
+    case 'utf-32-le':
+      return decodeUtf32leAsIterable(bytes, offset, length, true, replace);
+
+    default:
+      throw new ArgumentError('Encoding $encoding not supported');
+  }
+}
+
+// TODO(jmesserly): use dart:utf once http://dartbug.com/6476 is fixed.
+/// Returns the code points for the [input]. This works like [String.charCodes]
+/// but it decodes UTF-16 surrogate pairs.
+List<int> toCodepoints(String input) {
+  var newCodes = <int>[];
+  for (int i = 0; i < input.length; i++) {
+    var c = input.codeUnitAt(i);
+    if (0xD800 <= c && c <= 0xDBFF) {
+      int next = i + 1;
+      if (next < input.length) {
+        var d = input.codeUnitAt(next);
+        if (0xDC00 <= d && d <= 0xDFFF) {
+          c = 0x10000 + ((c - 0xD800) << 10) + (d - 0xDC00);
+          i = next;
+        }
+      }
+    }
+    newCodes.add(c);
+  }
+  return newCodes;
+}
+
+/// Decodes [windows-1252](http://en.wikipedia.org/wiki/Windows-1252) bytes as
+/// an iterable. Thus, the consumer can only convert as much of the input as
+/// needed. Set the [replacementCharacter] to null to throw an [ArgumentError]
+/// rather than replace the bad value.
+IterableWindows1252Decoder decodeWindows1252AsIterable(List<int> bytes,
+    [int offset = 0, int length,
+    int replacementCodepoint = UNICODE_REPLACEMENT_CHARACTER_CODEPOINT]) {
+  return new IterableWindows1252Decoder(
+      bytes, offset, length, replacementCodepoint);
+}
+
+/// Return type of [decodeWindows1252AsIterable] and variants. The Iterable type
+/// provides an iterator on demand and the iterator will only translate bytes
+/// as requested by the user of the iterator. (Note: results are not cached.)
+class IterableWindows1252Decoder extends IterableBase<int> {
+  final List<int> bytes;
+  final int offset;
+  final int length;
+  final int replacementCodepoint;
+
+  IterableWindows1252Decoder(List<int> this.bytes, [int this.offset = 0,
+      int this.length = null,
+      int this.replacementCodepoint = UNICODE_REPLACEMENT_CHARACTER_CODEPOINT]);
+
+  Windows1252Decoder get iterator =>
+      new Windows1252Decoder(bytes, offset, length, replacementCodepoint);
+}
+
+/// Provides an iterator of Unicode codepoints from windows-1252 encoded bytes.
+/// The parameters can set an offset into a list of bytes (as int), limit the
+/// length of the values to be decoded, and override the default Unicode
+/// replacement character. Set the replacementCharacter to null to throw an
+/// ArgumentError rather than replace the bad value. The return value
+/// from this method can be used as an Iterable (e.g. in a for-loop).
+class Windows1252Decoder implements Iterator<int> {
+  final int replacementCodepoint;
+  final List<int> _bytes;
+  int _offset;
+  final int _length;
+
+  Windows1252Decoder(List<int> bytes, [int offset = 0, int length,
+      this.replacementCodepoint = UNICODE_REPLACEMENT_CHARACTER_CODEPOINT])
+      : _bytes = bytes,
+        _offset = offset - 1,
+        _length = length == null ? bytes.length : length;
+
+  bool get _inRange => _offset >= 0 && _offset < _length;
+  int get current => _inRange ? _mapChar(_bytes[_offset]) : null;
+
+  bool moveNext() {
+    _offset++;
+    return _inRange;
+  }
+
+  int _mapChar(int char) {
+    // TODO(jmesserly): this is duplicating entitiesWindows1252 and
+    // replacementCharacters from constants.dart
+    switch (char) {
+      case 0x80:
+        return 0x20AC; // EURO SIGN
+      case 0x82:
+        return 0x201A; // SINGLE LOW-9 QUOTATION MARK
+      case 0x83:
+        return 0x0192; // LATIN SMALL LETTER F WITH HOOK
+      case 0x84:
+        return 0x201E; // DOUBLE LOW-9 QUOTATION MARK
+      case 0x85:
+        return 0x2026; // HORIZONTAL ELLIPSIS
+      case 0x86:
+        return 0x2020; // DAGGER
+      case 0x87:
+        return 0x2021; // DOUBLE DAGGER
+      case 0x88:
+        return 0x02C6; // MODIFIER LETTER CIRCUMFLEX ACCENT
+      case 0x89:
+        return 0x2030; // PER MILLE SIGN
+      case 0x8A:
+        return 0x0160; // LATIN CAPITAL LETTER S WITH CARON
+      case 0x8B:
+        return 0x2039; // SINGLE LEFT-POINTING ANGLE QUOTATION MARK
+      case 0x8C:
+        return 0x0152; // LATIN CAPITAL LIGATURE OE
+      case 0x8E:
+        return 0x017D; // LATIN CAPITAL LETTER Z WITH CARON
+      case 0x91:
+        return 0x2018; // LEFT SINGLE QUOTATION MARK
+      case 0x92:
+        return 0x2019; // RIGHT SINGLE QUOTATION MARK
+      case 0x93:
+        return 0x201C; // LEFT DOUBLE QUOTATION MARK
+      case 0x94:
+        return 0x201D; // RIGHT DOUBLE QUOTATION MARK
+      case 0x95:
+        return 0x2022; // BULLET
+      case 0x96:
+        return 0x2013; // EN DASH
+      case 0x97:
+        return 0x2014; // EM DASH
+      case 0x98:
+        return 0x02DC; // SMALL TILDE
+      case 0x99:
+        return 0x2122; // TRADE MARK SIGN
+      case 0x9A:
+        return 0x0161; // LATIN SMALL LETTER S WITH CARON
+      case 0x9B:
+        return 0x203A; // SINGLE RIGHT-POINTING ANGLE QUOTATION MARK
+      case 0x9C:
+        return 0x0153; // LATIN SMALL LIGATURE OE
+      case 0x9E:
+        return 0x017E; // LATIN SMALL LETTER Z WITH CARON
+      case 0x9F:
+        return 0x0178; // LATIN CAPITAL LETTER Y WITH DIAERESIS
+
+      case 0x81:
+      case 0x8D:
+      case 0x8F:
+      case 0x90:
+      case 0x9D:
+        if (replacementCodepoint == null) {
+          throw new ArgumentError(
+              "Invalid windows-1252 code point $char at $_offset");
+        }
+        return replacementCodepoint;
+    }
+    return char;
+  }
+}
diff --git a/html/lib/src/constants.dart b/html/lib/src/constants.dart
new file mode 100644
index 0000000..e85e43a
--- /dev/null
+++ b/html/lib/src/constants.dart
@@ -0,0 +1,3082 @@
+library constants;
+
+import 'utils.dart';
+
+// TODO(jmesserly): fix up the const lists. For the bigger ones, we need faster
+// lookup than linear search "contains". In the Python code they were
+// frozensets.
+
+final String EOF = null;
+
+class ReparseException implements Exception {
+  final String message;
+  ReparseException(this.message);
+  String toString() => "ReparseException: $message";
+}
+
+// TODO(jmesserly): assuming the programmatic name is not important, it would be
+// good to make these "static const" fields on an ErrorMessage class.
+/// These are error messages emitted by [HtmlParser]. The values use Python
+/// style string formatting, as implemented by [formatStr]. That function only
+/// supports the subset of format functionality used here.
+const Map<String, String> errorMessages = const {
+  "null-character": "Null character in input stream, replaced with U+FFFD.",
+  "invalid-codepoint": "Invalid codepoint in stream.",
+  "incorrectly-placed-solidus": "Solidus (/) incorrectly placed in tag.",
+  "incorrect-cr-newline-entity":
+      "Incorrect CR newline entity, replaced with LF.",
+  "illegal-windows-1252-entity":
+      "Entity used with illegal number (windows-1252 reference).",
+  "cant-convert-numeric-entity":
+      "Numeric entity couldn't be converted to character "
+      "(codepoint U+%(charAsInt)08x).",
+  "illegal-codepoint-for-numeric-entity":
+      "Numeric entity represents an illegal codepoint: "
+      "U+%(charAsInt)08x.",
+  "numeric-entity-without-semicolon": "Numeric entity didn't end with ';'.",
+  "expected-numeric-entity-but-got-eof":
+      "Numeric entity expected. Got end of file instead.",
+  "expected-numeric-entity": "Numeric entity expected but none found.",
+  "named-entity-without-semicolon": "Named entity didn't end with ';'.",
+  "expected-named-entity": "Named entity expected. Got none.",
+  "attributes-in-end-tag": "End tag contains unexpected attributes.",
+  'self-closing-flag-on-end-tag':
+      "End tag contains unexpected self-closing flag.",
+  "expected-tag-name-but-got-right-bracket":
+      "Expected tag name. Got '>' instead.",
+  "expected-tag-name-but-got-question-mark":
+      "Expected tag name. Got '?' instead. (HTML doesn't "
+      "support processing instructions.)",
+  "expected-tag-name": "Expected tag name. Got something else instead",
+  "expected-closing-tag-but-got-right-bracket":
+      "Expected closing tag. Got '>' instead. Ignoring '</>'.",
+  "expected-closing-tag-but-got-eof":
+      "Expected closing tag. Unexpected end of file.",
+  "expected-closing-tag-but-got-char":
+      "Expected closing tag. Unexpected character '%(data)s' found.",
+  "eof-in-tag-name": "Unexpected end of file in the tag name.",
+  "expected-attribute-name-but-got-eof":
+      "Unexpected end of file. Expected attribute name instead.",
+  "eof-in-attribute-name": "Unexpected end of file in attribute name.",
+  "invalid-character-in-attribute-name": "Invalid character in attribute name",
+  "duplicate-attribute": "Dropped duplicate attribute on tag.",
+  "expected-end-of-tag-name-but-got-eof":
+      "Unexpected end of file. Expected = or end of tag.",
+  "expected-attribute-value-but-got-eof":
+      "Unexpected end of file. Expected attribute value.",
+  "expected-attribute-value-but-got-right-bracket":
+      "Expected attribute value. Got '>' instead.",
+  'equals-in-unquoted-attribute-value': "Unexpected = in unquoted attribute",
+  'unexpected-character-in-unquoted-attribute-value':
+      "Unexpected character in unquoted attribute",
+  "invalid-character-after-attribute-name":
+      "Unexpected character after attribute name.",
+  "unexpected-character-after-attribute-value":
+      "Unexpected character after attribute value.",
+  "eof-in-attribute-value-double-quote":
+      "Unexpected end of file in attribute value (\".",
+  "eof-in-attribute-value-single-quote":
+      "Unexpected end of file in attribute value (').",
+  "eof-in-attribute-value-no-quotes":
+      "Unexpected end of file in attribute value.",
+  "unexpected-EOF-after-solidus-in-tag":
+      "Unexpected end of file in tag. Expected >",
+  "unexpected-character-after-soldius-in-tag":
+      "Unexpected character after / in tag. Expected >",
+  "expected-dashes-or-doctype": "Expected '--' or 'DOCTYPE'. Not found.",
+  "unexpected-bang-after-double-dash-in-comment":
+      "Unexpected ! after -- in comment",
+  "unexpected-space-after-double-dash-in-comment":
+      "Unexpected space after -- in comment",
+  "incorrect-comment": "Incorrect comment.",
+  "eof-in-comment": "Unexpected end of file in comment.",
+  "eof-in-comment-end-dash": "Unexpected end of file in comment (-)",
+  "unexpected-dash-after-double-dash-in-comment":
+      "Unexpected '-' after '--' found in comment.",
+  "eof-in-comment-double-dash": "Unexpected end of file in comment (--).",
+  "eof-in-comment-end-space-state": "Unexpected end of file in comment.",
+  "eof-in-comment-end-bang-state": "Unexpected end of file in comment.",
+  "unexpected-char-in-comment": "Unexpected character in comment found.",
+  "need-space-after-doctype": "No space after literal string 'DOCTYPE'.",
+  "expected-doctype-name-but-got-right-bracket":
+      "Unexpected > character. Expected DOCTYPE name.",
+  "expected-doctype-name-but-got-eof":
+      "Unexpected end of file. Expected DOCTYPE name.",
+  "eof-in-doctype-name": "Unexpected end of file in DOCTYPE name.",
+  "eof-in-doctype": "Unexpected end of file in DOCTYPE.",
+  "expected-space-or-right-bracket-in-doctype":
+      "Expected space or '>'. Got '%(data)s'",
+  "unexpected-end-of-doctype": "Unexpected end of DOCTYPE.",
+  "unexpected-char-in-doctype": "Unexpected character in DOCTYPE.",
+  "eof-in-innerhtml": "XXX innerHTML EOF",
+  "unexpected-doctype": "Unexpected DOCTYPE. Ignored.",
+  "non-html-root": "html needs to be the first start tag.",
+  "expected-doctype-but-got-eof": "Unexpected End of file. Expected DOCTYPE.",
+  "unknown-doctype": "Erroneous DOCTYPE.",
+  "expected-doctype-but-got-chars":
+      "Unexpected non-space characters. Expected DOCTYPE.",
+  "expected-doctype-but-got-start-tag":
+      "Unexpected start tag (%(name)s). Expected DOCTYPE.",
+  "expected-doctype-but-got-end-tag":
+      "Unexpected end tag (%(name)s). Expected DOCTYPE.",
+  "end-tag-after-implied-root":
+      "Unexpected end tag (%(name)s) after the (implied) root element.",
+  "expected-named-closing-tag-but-got-eof":
+      "Unexpected end of file. Expected end tag (%(name)s).",
+  "two-heads-are-not-better-than-one":
+      "Unexpected start tag head in existing head. Ignored.",
+  "unexpected-end-tag": "Unexpected end tag (%(name)s). Ignored.",
+  "unexpected-start-tag-out-of-my-head":
+      "Unexpected start tag (%(name)s) that can be in head. Moved.",
+  "unexpected-start-tag": "Unexpected start tag (%(name)s).",
+  "missing-end-tag": "Missing end tag (%(name)s).",
+  "missing-end-tags": "Missing end tags (%(name)s).",
+  "unexpected-start-tag-implies-end-tag":
+      "Unexpected start tag (%(startName)s) "
+      "implies end tag (%(endName)s).",
+  "unexpected-start-tag-treated-as":
+      "Unexpected start tag (%(originalName)s). Treated as %(newName)s.",
+  "deprecated-tag": "Unexpected start tag %(name)s. Don't use it!",
+  "unexpected-start-tag-ignored": "Unexpected start tag %(name)s. Ignored.",
+  "expected-one-end-tag-but-got-another": "Unexpected end tag (%(gotName)s). "
+      "Missing end tag (%(expectedName)s).",
+  "end-tag-too-early":
+      "End tag (%(name)s) seen too early. Expected other end tag.",
+  "end-tag-too-early-named":
+      "Unexpected end tag (%(gotName)s). Expected end tag (%(expectedName)s).",
+  "end-tag-too-early-ignored": "End tag (%(name)s) seen too early. Ignored.",
+  "adoption-agency-1.1": "End tag (%(name)s) violates step 1, "
+      "paragraph 1 of the adoption agency algorithm.",
+  "adoption-agency-1.2": "End tag (%(name)s) violates step 1, "
+      "paragraph 2 of the adoption agency algorithm.",
+  "adoption-agency-1.3": "End tag (%(name)s) violates step 1, "
+      "paragraph 3 of the adoption agency algorithm.",
+  "unexpected-end-tag-treated-as":
+      "Unexpected end tag (%(originalName)s). Treated as %(newName)s.",
+  "no-end-tag": "This element (%(name)s) has no end tag.",
+  "unexpected-implied-end-tag-in-table":
+      "Unexpected implied end tag (%(name)s) in the table phase.",
+  "unexpected-implied-end-tag-in-table-body":
+      "Unexpected implied end tag (%(name)s) in the table body phase.",
+  "unexpected-char-implies-table-voodoo": "Unexpected non-space characters in "
+      "table context caused voodoo mode.",
+  "unexpected-hidden-input-in-table":
+      "Unexpected input with type hidden in table context.",
+  "unexpected-form-in-table": "Unexpected form in table context.",
+  "unexpected-start-tag-implies-table-voodoo":
+      "Unexpected start tag (%(name)s) in "
+      "table context caused voodoo mode.",
+  "unexpected-end-tag-implies-table-voodoo": "Unexpected end tag (%(name)s) in "
+      "table context caused voodoo mode.",
+  "unexpected-cell-in-table-body": "Unexpected table cell start tag (%(name)s) "
+      "in the table body phase.",
+  "unexpected-cell-end-tag": "Got table cell end tag (%(name)s) "
+      "while required end tags are missing.",
+  "unexpected-end-tag-in-table-body":
+      "Unexpected end tag (%(name)s) in the table body phase. Ignored.",
+  "unexpected-implied-end-tag-in-table-row":
+      "Unexpected implied end tag (%(name)s) in the table row phase.",
+  "unexpected-end-tag-in-table-row":
+      "Unexpected end tag (%(name)s) in the table row phase. Ignored.",
+  "unexpected-select-in-select":
+      "Unexpected select start tag in the select phase "
+      "treated as select end tag.",
+  "unexpected-input-in-select":
+      "Unexpected input start tag in the select phase.",
+  "unexpected-start-tag-in-select":
+      "Unexpected start tag token (%(name)s in the select phase. "
+      "Ignored.",
+  "unexpected-end-tag-in-select":
+      "Unexpected end tag (%(name)s) in the select phase. Ignored.",
+  "unexpected-table-element-start-tag-in-select-in-table":
+      "Unexpected table element start tag (%(name)s) in the select in table phase.",
+  "unexpected-table-element-end-tag-in-select-in-table":
+      "Unexpected table element end tag (%(name)s) in the select in table phase.",
+  "unexpected-char-after-body":
+      "Unexpected non-space characters in the after body phase.",
+  "unexpected-start-tag-after-body": "Unexpected start tag token (%(name)s)"
+      " in the after body phase.",
+  "unexpected-end-tag-after-body": "Unexpected end tag token (%(name)s)"
+      " in the after body phase.",
+  "unexpected-char-in-frameset":
+      "Unepxected characters in the frameset phase. Characters ignored.",
+  "unexpected-start-tag-in-frameset": "Unexpected start tag token (%(name)s)"
+      " in the frameset phase. Ignored.",
+  "unexpected-frameset-in-frameset-innerhtml":
+      "Unexpected end tag token (frameset) "
+      "in the frameset phase (innerHTML).",
+  "unexpected-end-tag-in-frameset": "Unexpected end tag token (%(name)s)"
+      " in the frameset phase. Ignored.",
+  "unexpected-char-after-frameset": "Unexpected non-space characters in the "
+      "after frameset phase. Ignored.",
+  "unexpected-start-tag-after-frameset": "Unexpected start tag (%(name)s)"
+      " in the after frameset phase. Ignored.",
+  "unexpected-end-tag-after-frameset": "Unexpected end tag (%(name)s)"
+      " in the after frameset phase. Ignored.",
+  "unexpected-end-tag-after-body-innerhtml":
+      "Unexpected end tag after body(innerHtml)",
+  "expected-eof-but-got-char":
+      "Unexpected non-space characters. Expected end of file.",
+  "expected-eof-but-got-start-tag": "Unexpected start tag (%(name)s)"
+      ". Expected end of file.",
+  "expected-eof-but-got-end-tag": "Unexpected end tag (%(name)s)"
+      ". Expected end of file.",
+  "eof-in-table": "Unexpected end of file. Expected table content.",
+  "eof-in-select": "Unexpected end of file. Expected select content.",
+  "eof-in-frameset": "Unexpected end of file. Expected frameset content.",
+  "eof-in-script-in-script": "Unexpected end of file. Expected script content.",
+  "eof-in-foreign-lands": "Unexpected end of file. Expected foreign content",
+  "non-void-element-with-trailing-solidus":
+      "Trailing solidus not allowed on element %(name)s",
+  "unexpected-html-element-in-foreign-content":
+      "Element %(name)s not allowed in a non-html context",
+  "unexpected-end-tag-before-html":
+      "Unexpected end tag (%(name)s) before html.",
+  "undefined-error": "Undefined error (this sucks and should be fixed)",
+};
+
+class Namespaces {
+  static const html = "http://www.w3.org/1999/xhtml";
+  static const mathml = "http://www.w3.org/1998/Math/MathML";
+  static const svg = "http://www.w3.org/2000/svg";
+  static const xlink = "http://www.w3.org/1999/xlink";
+  static const xml = "http://www.w3.org/XML/1998/namespace";
+  static const xmlns = "http://www.w3.org/2000/xmlns/";
+  Namespaces._();
+
+  static String getPrefix(String url) {
+    switch (url) {
+      case html:
+        return 'html';
+      case mathml:
+        return 'math';
+      case svg:
+        return 'svg';
+      case xlink:
+        return 'xlink';
+      case xml:
+        return 'xml';
+      case xmlns:
+        return 'xmlns';
+      default:
+        return null;
+    }
+  }
+}
+
+const List scopingElements = const [
+  const Pair(Namespaces.html, "applet"),
+  const Pair(Namespaces.html, "caption"),
+  const Pair(Namespaces.html, "html"),
+  const Pair(Namespaces.html, "marquee"),
+  const Pair(Namespaces.html, "object"),
+  const Pair(Namespaces.html, "table"),
+  const Pair(Namespaces.html, "td"),
+  const Pair(Namespaces.html, "th"),
+  const Pair(Namespaces.mathml, "mi"),
+  const Pair(Namespaces.mathml, "mo"),
+  const Pair(Namespaces.mathml, "mn"),
+  const Pair(Namespaces.mathml, "ms"),
+  const Pair(Namespaces.mathml, "mtext"),
+  const Pair(Namespaces.mathml, "annotation-xml"),
+  const Pair(Namespaces.svg, "foreignObject"),
+  const Pair(Namespaces.svg, "desc"),
+  const Pair(Namespaces.svg, "title")
+];
+
+const formattingElements = const [
+  const Pair(Namespaces.html, "a"),
+  const Pair(Namespaces.html, "b"),
+  const Pair(Namespaces.html, "big"),
+  const Pair(Namespaces.html, "code"),
+  const Pair(Namespaces.html, "em"),
+  const Pair(Namespaces.html, "font"),
+  const Pair(Namespaces.html, "i"),
+  const Pair(Namespaces.html, "nobr"),
+  const Pair(Namespaces.html, "s"),
+  const Pair(Namespaces.html, "small"),
+  const Pair(Namespaces.html, "strike"),
+  const Pair(Namespaces.html, "strong"),
+  const Pair(Namespaces.html, "tt"),
+  const Pair(Namespaces.html, "")
+];
+
+const specialElements = const [
+  const Pair(Namespaces.html, "address"),
+  const Pair(Namespaces.html, "applet"),
+  const Pair(Namespaces.html, "area"),
+  const Pair(Namespaces.html, "article"),
+  const Pair(Namespaces.html, "aside"),
+  const Pair(Namespaces.html, "base"),
+  const Pair(Namespaces.html, "basefont"),
+  const Pair(Namespaces.html, "bgsound"),
+  const Pair(Namespaces.html, "blockquote"),
+  const Pair(Namespaces.html, "body"),
+  const Pair(Namespaces.html, "br"),
+  const Pair(Namespaces.html, "button"),
+  const Pair(Namespaces.html, "caption"),
+  const Pair(Namespaces.html, "center"),
+  const Pair(Namespaces.html, "col"),
+  const Pair(Namespaces.html, "colgroup"),
+  const Pair(Namespaces.html, "command"),
+  const Pair(Namespaces.html, "dd"),
+  const Pair(Namespaces.html, "details"),
+  const Pair(Namespaces.html, "dir"),
+  const Pair(Namespaces.html, "div"),
+  const Pair(Namespaces.html, "dl"),
+  const Pair(Namespaces.html, "dt"),
+  const Pair(Namespaces.html, "embed"),
+  const Pair(Namespaces.html, "fieldset"),
+  const Pair(Namespaces.html, "figure"),
+  const Pair(Namespaces.html, "footer"),
+  const Pair(Namespaces.html, "form"),
+  const Pair(Namespaces.html, "frame"),
+  const Pair(Namespaces.html, "frameset"),
+  const Pair(Namespaces.html, "h1"),
+  const Pair(Namespaces.html, "h2"),
+  const Pair(Namespaces.html, "h3"),
+  const Pair(Namespaces.html, "h4"),
+  const Pair(Namespaces.html, "h5"),
+  const Pair(Namespaces.html, "h6"),
+  const Pair(Namespaces.html, "head"),
+  const Pair(Namespaces.html, "header"),
+  const Pair(Namespaces.html, "hr"),
+  const Pair(Namespaces.html, "html"),
+  const Pair(Namespaces.html, "iframe"),
+  // Note that image is commented out in the spec as "this isn't an
+  // element that can end up on the stack, so it doesn't matter,"
+  const Pair(Namespaces.html, "image"),
+  const Pair(Namespaces.html, "img"),
+  const Pair(Namespaces.html, "input"),
+  const Pair(Namespaces.html, "isindex"),
+  const Pair(Namespaces.html, "li"),
+  const Pair(Namespaces.html, "link"),
+  const Pair(Namespaces.html, "listing"),
+  const Pair(Namespaces.html, "marquee"),
+  const Pair(Namespaces.html, "men"),
+  const Pair(Namespaces.html, "meta"),
+  const Pair(Namespaces.html, "nav"),
+  const Pair(Namespaces.html, "noembed"),
+  const Pair(Namespaces.html, "noframes"),
+  const Pair(Namespaces.html, "noscript"),
+  const Pair(Namespaces.html, "object"),
+  const Pair(Namespaces.html, "ol"),
+  const Pair(Namespaces.html, "p"),
+  const Pair(Namespaces.html, "param"),
+  const Pair(Namespaces.html, "plaintext"),
+  const Pair(Namespaces.html, "pre"),
+  const Pair(Namespaces.html, "script"),
+  const Pair(Namespaces.html, "section"),
+  const Pair(Namespaces.html, "select"),
+  const Pair(Namespaces.html, "style"),
+  const Pair(Namespaces.html, "table"),
+  const Pair(Namespaces.html, "tbody"),
+  const Pair(Namespaces.html, "td"),
+  const Pair(Namespaces.html, "textarea"),
+  const Pair(Namespaces.html, "tfoot"),
+  const Pair(Namespaces.html, "th"),
+  const Pair(Namespaces.html, "thead"),
+  const Pair(Namespaces.html, "title"),
+  const Pair(Namespaces.html, "tr"),
+  const Pair(Namespaces.html, "ul"),
+  const Pair(Namespaces.html, "wbr"),
+  const Pair(Namespaces.html, "xmp"),
+  const Pair(Namespaces.svg, "foreignObject")
+];
+
+const htmlIntegrationPointElements = const [
+  const Pair(Namespaces.mathml, "annotaion-xml"),
+  const Pair(Namespaces.svg, "foreignObject"),
+  const Pair(Namespaces.svg, "desc"),
+  const Pair(Namespaces.svg, "title")
+];
+
+const mathmlTextIntegrationPointElements = const [
+  const Pair(Namespaces.mathml, "mi"),
+  const Pair(Namespaces.mathml, "mo"),
+  const Pair(Namespaces.mathml, "mn"),
+  const Pair(Namespaces.mathml, "ms"),
+  const Pair(Namespaces.mathml, "mtext")
+];
+
+const spaceCharacters = " \n\r\t\u000C";
+
+const int NEWLINE = 10;
+const int RETURN = 13;
+
+bool isWhitespace(String char) {
+  if (char == null) return false;
+  return isWhitespaceCC(char.codeUnitAt(0));
+}
+
+bool isWhitespaceCC(int charCode) {
+  switch (charCode) {
+    case 9: // '\t'
+    case NEWLINE: // '\n'
+    case 12: // '\f'
+    case RETURN: // '\r'
+    case 32: // ' '
+      return true;
+  }
+  return false;
+}
+
+const List<String> tableInsertModeElements = const [
+  "table",
+  "tbody",
+  "tfoot",
+  "thead",
+  "tr"
+];
+
+// TODO(jmesserly): remove these in favor of the test functions
+const asciiLetters = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
+
+const ZERO = 48;
+const LOWER_A = 97;
+const LOWER_Z = 122;
+const UPPER_A = 65;
+const UPPER_Z = 90;
+
+bool isLetterOrDigit(String char) => isLetter(char) || isDigit(char);
+
+// Note: this is intentially ASCII only
+bool isLetter(String char) {
+  if (char == null) return false;
+  int cc = char.codeUnitAt(0);
+  return cc >= LOWER_A && cc <= LOWER_Z || cc >= UPPER_A && cc <= UPPER_Z;
+}
+
+bool isDigit(String char) {
+  if (char == null) return false;
+  int cc = char.codeUnitAt(0);
+  return cc >= ZERO && cc < ZERO + 10;
+}
+
+bool isHexDigit(String char) {
+  if (char == null) return false;
+  switch (char.codeUnitAt(0)) {
+    case 48:
+    case 49:
+    case 50:
+    case 51:
+    case 52: // '0' - '4'
+    case 53:
+    case 54:
+    case 55:
+    case 56:
+    case 57: // '5' - '9'
+    case 65:
+    case 66:
+    case 67:
+    case 68:
+    case 69:
+    case 70: // 'A' - 'F'
+    case 97:
+    case 98:
+    case 99:
+    case 100:
+    case 101:
+    case 102: // 'a' - 'f'
+      return true;
+  }
+  return false;
+}
+
+// Note: based on the original Python code, I assume we only want to convert
+// ASCII chars to.toLowerCase() case, unlike Dart's toLowerCase function.
+String asciiUpper2Lower(String text) {
+  if (text == null) return null;
+  var result = new List<int>(text.length);
+  for (int i = 0; i < text.length; i++) {
+    var c = text.codeUnitAt(i);
+    if (c >= UPPER_A && c <= UPPER_Z) {
+      c += LOWER_A - UPPER_A;
+    }
+    result[i] = c;
+  }
+  return new String.fromCharCodes(result);
+}
+
+// Heading elements need to be ordered
+const headingElements = const ["h1", "h2", "h3", "h4", "h5", "h6"];
+
+const cdataElements = const ['title', 'textarea'];
+
+const rcdataElements = const [
+  'style',
+  'script',
+  'xmp',
+  'iframe',
+  'noembed',
+  'noframes',
+  'noscript'
+];
+
+const Map<String, List<String>> booleanAttributes = const {
+  "": const ["irrelevant",],
+  "style": const ["scoped",],
+  "img": const ["ismap",],
+  "audio": const ["autoplay", "controls"],
+  "video": const ["autoplay", "controls"],
+  "script": const ["defer", "async"],
+  "details": const ["open",],
+  "datagrid": const ["multiple", "disabled"],
+  "command": const ["hidden", "disabled", "checked", "default"],
+  "hr": const ["noshade"],
+  "men": const ["autosubmit",],
+  "fieldset": const ["disabled", "readonly"],
+  "option": const ["disabled", "readonly", "selected"],
+  "optgroup": const ["disabled", "readonly"],
+  "button": const ["disabled", "autofocus"],
+  "input": const [
+    "disabled",
+    "readonly",
+    "required",
+    "autofocus",
+    "checked",
+    "ismap"
+  ],
+  "select": const ["disabled", "readonly", "autofocus", "multiple"],
+  "output": const ["disabled", "readonly"],
+};
+
+// entitiesWindows1252 has to be _ordered_ and needs to have an index. It
+// therefore can't be a frozenset.
+const List<int> entitiesWindows1252 = const [
+  8364, // 0x80  0x20AC  EURO SIGN
+  65533, // 0x81          UNDEFINED
+  8218, // 0x82  0x201A  SINGLE LOW-9 QUOTATION MARK
+  402, // 0x83  0x0192  LATIN SMALL LETTER F WITH HOOK
+  8222, // 0x84  0x201E  DOUBLE LOW-9 QUOTATION MARK
+  8230, // 0x85  0x2026  HORIZONTAL ELLIPSIS
+  8224, // 0x86  0x2020  DAGGER
+  8225, // 0x87  0x2021  DOUBLE DAGGER
+  710, // 0x88  0x02C6  MODIFIER LETTER CIRCUMFLEX ACCENT
+  8240, // 0x89  0x2030  PER MILLE SIGN
+  352, // 0x8A  0x0160  LATIN CAPITAL LETTER S WITH CARON
+  8249, // 0x8B  0x2039  SINGLE LEFT-POINTING ANGLE QUOTATION MARK
+  338, // 0x8C  0x0152  LATIN CAPITAL LIGATURE OE
+  65533, // 0x8D          UNDEFINED
+  381, // 0x8E  0x017D  LATIN CAPITAL LETTER Z WITH CARON
+  65533, // 0x8F          UNDEFINED
+  65533, // 0x90          UNDEFINED
+  8216, // 0x91  0x2018  LEFT SINGLE QUOTATION MARK
+  8217, // 0x92  0x2019  RIGHT SINGLE QUOTATION MARK
+  8220, // 0x93  0x201C  LEFT DOUBLE QUOTATION MARK
+  8221, // 0x94  0x201D  RIGHT DOUBLE QUOTATION MARK
+  8226, // 0x95  0x2022  BULLET
+  8211, // 0x96  0x2013  EN DASH
+  8212, // 0x97  0x2014  EM DASH
+  732, // 0x98  0x02DC  SMALL TILDE
+  8482, // 0x99  0x2122  TRADE MARK SIGN
+  353, // 0x9A  0x0161  LATIN SMALL LETTER S WITH CARON
+  8250, // 0x9B  0x203A  SINGLE RIGHT-POINTING ANGLE QUOTATION MARK
+  339, // 0x9C  0x0153  LATIN SMALL LIGATURE OE
+  65533, // 0x9D          UNDEFINED
+  382, // 0x9E  0x017E  LATIN SMALL LETTER Z WITH CARON
+  376 // 0x9F  0x0178  LATIN CAPITAL LETTER Y WITH DIAERESIS
+];
+
+const xmlEntities = const ['lt;', 'gt;', 'amp;', 'apos;', 'quot;'];
+
+const Map<String, String> entities = const {
+  "AElig": "\xc6",
+  "AElig;": "\xc6",
+  "AMP": "&",
+  "AMP;": "&",
+  "Aacute": "\xc1",
+  "Aacute;": "\xc1",
+  "Abreve;": "\u0102",
+  "Acirc": "\xc2",
+  "Acirc;": "\xc2",
+  "Acy;": "\u0410",
+  "Afr;": "\u{01d504}",
+  "Agrave": "\xc0",
+  "Agrave;": "\xc0",
+  "Alpha;": "\u0391",
+  "Amacr;": "\u0100",
+  "And;": "\u2a53",
+  "Aogon;": "\u0104",
+  "Aopf;": "\u{01d538}",
+  "ApplyFunction;": "\u2061",
+  "Aring": "\xc5",
+  "Aring;": "\xc5",
+  "Ascr;": "\u{01d49c}",
+  "Assign;": "\u2254",
+  "Atilde": "\xc3",
+  "Atilde;": "\xc3",
+  "Auml": "\xc4",
+  "Auml;": "\xc4",
+  "Backslash;": "\u2216",
+  "Barv;": "\u2ae7",
+  "Barwed;": "\u2306",
+  "Bcy;": "\u0411",
+  "Because;": "\u2235",
+  "Bernoullis;": "\u212c",
+  "Beta;": "\u0392",
+  "Bfr;": "\u{01d505}",
+  "Bopf;": "\u{01d539}",
+  "Breve;": "\u02d8",
+  "Bscr;": "\u212c",
+  "Bumpeq;": "\u224e",
+  "CHcy;": "\u0427",
+  "COPY": "\xa9",
+  "COPY;": "\xa9",
+  "Cacute;": "\u0106",
+  "Cap;": "\u22d2",
+  "CapitalDifferentialD;": "\u2145",
+  "Cayleys;": "\u212d",
+  "Ccaron;": "\u010c",
+  "Ccedil": "\xc7",
+  "Ccedil;": "\xc7",
+  "Ccirc;": "\u0108",
+  "Cconint;": "\u2230",
+  "Cdot;": "\u010a",
+  "Cedilla;": "\xb8",
+  "CenterDot;": "\xb7",
+  "Cfr;": "\u212d",
+  "Chi;": "\u03a7",
+  "CircleDot;": "\u2299",
+  "CircleMinus;": "\u2296",
+  "CirclePlus;": "\u2295",
+  "CircleTimes;": "\u2297",
+  "ClockwiseContourIntegral;": "\u2232",
+  "CloseCurlyDoubleQuote;": "\u201d",
+  "CloseCurlyQuote;": "\u2019",
+  "Colon;": "\u2237",
+  "Colone;": "\u2a74",
+  "Congruent;": "\u2261",
+  "Conint;": "\u222f",
+  "ContourIntegral;": "\u222e",
+  "Copf;": "\u2102",
+  "Coproduct;": "\u2210",
+  "CounterClockwiseContourIntegral;": "\u2233",
+  "Cross;": "\u2a2f",
+  "Cscr;": "\u{01d49e}",
+  "Cup;": "\u22d3",
+  "CupCap;": "\u224d",
+  "DD;": "\u2145",
+  "DDotrahd;": "\u2911",
+  "DJcy;": "\u0402",
+  "DScy;": "\u0405",
+  "DZcy;": "\u040f",
+  "Dagger;": "\u2021",
+  "Darr;": "\u21a1",
+  "Dashv;": "\u2ae4",
+  "Dcaron;": "\u010e",
+  "Dcy;": "\u0414",
+  "Del;": "\u2207",
+  "Delta;": "\u0394",
+  "Dfr;": "\u{01d507}",
+  "DiacriticalAcute;": "\xb4",
+  "DiacriticalDot;": "\u02d9",
+  "DiacriticalDoubleAcute;": "\u02dd",
+  "DiacriticalGrave;": "`",
+  "DiacriticalTilde;": "\u02dc",
+  "Diamond;": "\u22c4",
+  "DifferentialD;": "\u2146",
+  "Dopf;": "\u{01d53b}",
+  "Dot;": "\xa8",
+  "DotDot;": "\u20dc",
+  "DotEqual;": "\u2250",
+  "DoubleContourIntegral;": "\u222f",
+  "DoubleDot;": "\xa8",
+  "DoubleDownArrow;": "\u21d3",
+  "DoubleLeftArrow;": "\u21d0",
+  "DoubleLeftRightArrow;": "\u21d4",
+  "DoubleLeftTee;": "\u2ae4",
+  "DoubleLongLeftArrow;": "\u27f8",
+  "DoubleLongLeftRightArrow;": "\u27fa",
+  "DoubleLongRightArrow;": "\u27f9",
+  "DoubleRightArrow;": "\u21d2",
+  "DoubleRightTee;": "\u22a8",
+  "DoubleUpArrow;": "\u21d1",
+  "DoubleUpDownArrow;": "\u21d5",
+  "DoubleVerticalBar;": "\u2225",
+  "DownArrow;": "\u2193",
+  "DownArrowBar;": "\u2913",
+  "DownArrowUpArrow;": "\u21f5",
+  "DownBreve;": "\u0311",
+  "DownLeftRightVector;": "\u2950",
+  "DownLeftTeeVector;": "\u295e",
+  "DownLeftVector;": "\u21bd",
+  "DownLeftVectorBar;": "\u2956",
+  "DownRightTeeVector;": "\u295f",
+  "DownRightVector;": "\u21c1",
+  "DownRightVectorBar;": "\u2957",
+  "DownTee;": "\u22a4",
+  "DownTeeArrow;": "\u21a7",
+  "Downarrow;": "\u21d3",
+  "Dscr;": "\u{01d49f}",
+  "Dstrok;": "\u0110",
+  "ENG;": "\u014a",
+  "ETH": "\xd0",
+  "ETH;": "\xd0",
+  "Eacute": "\xc9",
+  "Eacute;": "\xc9",
+  "Ecaron;": "\u011a",
+  "Ecirc": "\xca",
+  "Ecirc;": "\xca",
+  "Ecy;": "\u042d",
+  "Edot;": "\u0116",
+  "Efr;": "\u{01d508}",
+  "Egrave": "\xc8",
+  "Egrave;": "\xc8",
+  "Element;": "\u2208",
+  "Emacr;": "\u0112",
+  "EmptySmallSquare;": "\u25fb",
+  "EmptyVerySmallSquare;": "\u25ab",
+  "Eogon;": "\u0118",
+  "Eopf;": "\u{01d53c}",
+  "Epsilon;": "\u0395",
+  "Equal;": "\u2a75",
+  "EqualTilde;": "\u2242",
+  "Equilibrium;": "\u21cc",
+  "Escr;": "\u2130",
+  "Esim;": "\u2a73",
+  "Eta;": "\u0397",
+  "Euml": "\xcb",
+  "Euml;": "\xcb",
+  "Exists;": "\u2203",
+  "ExponentialE;": "\u2147",
+  "Fcy;": "\u0424",
+  "Ffr;": "\u{01d509}",
+  "FilledSmallSquare;": "\u25fc",
+  "FilledVerySmallSquare;": "\u25aa",
+  "Fopf;": "\u{01d53d}",
+  "ForAll;": "\u2200",
+  "Fouriertrf;": "\u2131",
+  "Fscr;": "\u2131",
+  "GJcy;": "\u0403",
+  "GT": ">",
+  "GT;": ">",
+  "Gamma;": "\u0393",
+  "Gammad;": "\u03dc",
+  "Gbreve;": "\u011e",
+  "Gcedil;": "\u0122",
+  "Gcirc;": "\u011c",
+  "Gcy;": "\u0413",
+  "Gdot;": "\u0120",
+  "Gfr;": "\u{01d50a}",
+  "Gg;": "\u22d9",
+  "Gopf;": "\u{01d53e}",
+  "GreaterEqual;": "\u2265",
+  "GreaterEqualLess;": "\u22db",
+  "GreaterFullEqual;": "\u2267",
+  "GreaterGreater;": "\u2aa2",
+  "GreaterLess;": "\u2277",
+  "GreaterSlantEqual;": "\u2a7e",
+  "GreaterTilde;": "\u2273",
+  "Gscr;": "\u{01d4a2}",
+  "Gt;": "\u226b",
+  "HARDcy;": "\u042a",
+  "Hacek;": "\u02c7",
+  "Hat;": "^",
+  "Hcirc;": "\u0124",
+  "Hfr;": "\u210c",
+  "HilbertSpace;": "\u210b",
+  "Hopf;": "\u210d",
+  "HorizontalLine;": "\u2500",
+  "Hscr;": "\u210b",
+  "Hstrok;": "\u0126",
+  "HumpDownHump;": "\u224e",
+  "HumpEqual;": "\u224f",
+  "IEcy;": "\u0415",
+  "IJlig;": "\u0132",
+  "IOcy;": "\u0401",
+  "Iacute": "\xcd",
+  "Iacute;": "\xcd",
+  "Icirc": "\xce",
+  "Icirc;": "\xce",
+  "Icy;": "\u0418",
+  "Idot;": "\u0130",
+  "Ifr;": "\u2111",
+  "Igrave": "\xcc",
+  "Igrave;": "\xcc",
+  "Im;": "\u2111",
+  "Imacr;": "\u012a",
+  "ImaginaryI;": "\u2148",
+  "Implies;": "\u21d2",
+  "Int;": "\u222c",
+  "Integral;": "\u222b",
+  "Intersection;": "\u22c2",
+  "InvisibleComma;": "\u2063",
+  "InvisibleTimes;": "\u2062",
+  "Iogon;": "\u012e",
+  "Iopf;": "\u{01d540}",
+  "Iota;": "\u0399",
+  "Iscr;": "\u2110",
+  "Itilde;": "\u0128",
+  "Iukcy;": "\u0406",
+  "Iuml": "\xcf",
+  "Iuml;": "\xcf",
+  "Jcirc;": "\u0134",
+  "Jcy;": "\u0419",
+  "Jfr;": "\u{01d50d}",
+  "Jopf;": "\u{01d541}",
+  "Jscr;": "\u{01d4a5}",
+  "Jsercy;": "\u0408",
+  "Jukcy;": "\u0404",
+  "KHcy;": "\u0425",
+  "KJcy;": "\u040c",
+  "Kappa;": "\u039a",
+  "Kcedil;": "\u0136",
+  "Kcy;": "\u041a",
+  "Kfr;": "\u{01d50e}",
+  "Kopf;": "\u{01d542}",
+  "Kscr;": "\u{01d4a6}",
+  "LJcy;": "\u0409",
+  "LT": "<",
+  "LT;": "<",
+  "Lacute;": "\u0139",
+  "Lambda;": "\u039b",
+  "Lang;": "\u27ea",
+  "Laplacetrf;": "\u2112",
+  "Larr;": "\u219e",
+  "Lcaron;": "\u013d",
+  "Lcedil;": "\u013b",
+  "Lcy;": "\u041b",
+  "LeftAngleBracket;": "\u27e8",
+  "LeftArrow;": "\u2190",
+  "LeftArrowBar;": "\u21e4",
+  "LeftArrowRightArrow;": "\u21c6",
+  "LeftCeiling;": "\u2308",
+  "LeftDoubleBracket;": "\u27e6",
+  "LeftDownTeeVector;": "\u2961",
+  "LeftDownVector;": "\u21c3",
+  "LeftDownVectorBar;": "\u2959",
+  "LeftFloor;": "\u230a",
+  "LeftRightArrow;": "\u2194",
+  "LeftRightVector;": "\u294e",
+  "LeftTee;": "\u22a3",
+  "LeftTeeArrow;": "\u21a4",
+  "LeftTeeVector;": "\u295a",
+  "LeftTriangle;": "\u22b2",
+  "LeftTriangleBar;": "\u29cf",
+  "LeftTriangleEqual;": "\u22b4",
+  "LeftUpDownVector;": "\u2951",
+  "LeftUpTeeVector;": "\u2960",
+  "LeftUpVector;": "\u21bf",
+  "LeftUpVectorBar;": "\u2958",
+  "LeftVector;": "\u21bc",
+  "LeftVectorBar;": "\u2952",
+  "Leftarrow;": "\u21d0",
+  "Leftrightarrow;": "\u21d4",
+  "LessEqualGreater;": "\u22da",
+  "LessFullEqual;": "\u2266",
+  "LessGreater;": "\u2276",
+  "LessLess;": "\u2aa1",
+  "LessSlantEqual;": "\u2a7d",
+  "LessTilde;": "\u2272",
+  "Lfr;": "\u{01d50f}",
+  "Ll;": "\u22d8",
+  "Lleftarrow;": "\u21da",
+  "Lmidot;": "\u013f",
+  "LongLeftArrow;": "\u27f5",
+  "LongLeftRightArrow;": "\u27f7",
+  "LongRightArrow;": "\u27f6",
+  "Longleftarrow;": "\u27f8",
+  "Longleftrightarrow;": "\u27fa",
+  "Longrightarrow;": "\u27f9",
+  "Lopf;": "\u{01d543}",
+  "LowerLeftArrow;": "\u2199",
+  "LowerRightArrow;": "\u2198",
+  "Lscr;": "\u2112",
+  "Lsh;": "\u21b0",
+  "Lstrok;": "\u0141",
+  "Lt;": "\u226a",
+  "Map;": "\u2905",
+  "Mcy;": "\u041c",
+  "MediumSpace;": "\u205f",
+  "Mellintrf;": "\u2133",
+  "Mfr;": "\u{01d510}",
+  "MinusPlus;": "\u2213",
+  "Mopf;": "\u{01d544}",
+  "Mscr;": "\u2133",
+  "Mu;": "\u039c",
+  "NJcy;": "\u040a",
+  "Nacute;": "\u0143",
+  "Ncaron;": "\u0147",
+  "Ncedil;": "\u0145",
+  "Ncy;": "\u041d",
+  "NegativeMediumSpace;": "\u200b",
+  "NegativeThickSpace;": "\u200b",
+  "NegativeThinSpace;": "\u200b",
+  "NegativeVeryThinSpace;": "\u200b",
+  "NestedGreaterGreater;": "\u226b",
+  "NestedLessLess;": "\u226a",
+  "NewLine;": "\n",
+  "Nfr;": "\u{01d511}",
+  "NoBreak;": "\u2060",
+  "NonBreakingSpace;": "\xa0",
+  "Nopf;": "\u2115",
+  "Not;": "\u2aec",
+  "NotCongruent;": "\u2262",
+  "NotCupCap;": "\u226d",
+  "NotDoubleVerticalBar;": "\u2226",
+  "NotElement;": "\u2209",
+  "NotEqual;": "\u2260",
+  "NotEqualTilde;": "\u2242\u0338",
+  "NotExists;": "\u2204",
+  "NotGreater;": "\u226f",
+  "NotGreaterEqual;": "\u2271",
+  "NotGreaterFullEqual;": "\u2267\u0338",
+  "NotGreaterGreater;": "\u226b\u0338",
+  "NotGreaterLess;": "\u2279",
+  "NotGreaterSlantEqual;": "\u2a7e\u0338",
+  "NotGreaterTilde;": "\u2275",
+  "NotHumpDownHump;": "\u224e\u0338",
+  "NotHumpEqual;": "\u224f\u0338",
+  "NotLeftTriangle;": "\u22ea",
+  "NotLeftTriangleBar;": "\u29cf\u0338",
+  "NotLeftTriangleEqual;": "\u22ec",
+  "NotLess;": "\u226e",
+  "NotLessEqual;": "\u2270",
+  "NotLessGreater;": "\u2278",
+  "NotLessLess;": "\u226a\u0338",
+  "NotLessSlantEqual;": "\u2a7d\u0338",
+  "NotLessTilde;": "\u2274",
+  "NotNestedGreaterGreater;": "\u2aa2\u0338",
+  "NotNestedLessLess;": "\u2aa1\u0338",
+  "NotPrecedes;": "\u2280",
+  "NotPrecedesEqual;": "\u2aaf\u0338",
+  "NotPrecedesSlantEqual;": "\u22e0",
+  "NotReverseElement;": "\u220c",
+  "NotRightTriangle;": "\u22eb",
+  "NotRightTriangleBar;": "\u29d0\u0338",
+  "NotRightTriangleEqual;": "\u22ed",
+  "NotSquareSubset;": "\u228f\u0338",
+  "NotSquareSubsetEqual;": "\u22e2",
+  "NotSquareSuperset;": "\u2290\u0338",
+  "NotSquareSupersetEqual;": "\u22e3",
+  "NotSubset;": "\u2282\u20d2",
+  "NotSubsetEqual;": "\u2288",
+  "NotSucceeds;": "\u2281",
+  "NotSucceedsEqual;": "\u2ab0\u0338",
+  "NotSucceedsSlantEqual;": "\u22e1",
+  "NotSucceedsTilde;": "\u227f\u0338",
+  "NotSuperset;": "\u2283\u20d2",
+  "NotSupersetEqual;": "\u2289",
+  "NotTilde;": "\u2241",
+  "NotTildeEqual;": "\u2244",
+  "NotTildeFullEqual;": "\u2247",
+  "NotTildeTilde;": "\u2249",
+  "NotVerticalBar;": "\u2224",
+  "Nscr;": "\u{01d4a9}",
+  "Ntilde": "\xd1",
+  "Ntilde;": "\xd1",
+  "Nu;": "\u039d",
+  "OElig;": "\u0152",
+  "Oacute": "\xd3",
+  "Oacute;": "\xd3",
+  "Ocirc": "\xd4",
+  "Ocirc;": "\xd4",
+  "Ocy;": "\u041e",
+  "Odblac;": "\u0150",
+  "Ofr;": "\u{01d512}",
+  "Ograve": "\xd2",
+  "Ograve;": "\xd2",
+  "Omacr;": "\u014c",
+  "Omega;": "\u03a9",
+  "Omicron;": "\u039f",
+  "Oopf;": "\u{01d546}",
+  "OpenCurlyDoubleQuote;": "\u201c",
+  "OpenCurlyQuote;": "\u2018",
+  "Or;": "\u2a54",
+  "Oscr;": "\u{01d4aa}",
+  "Oslash": "\xd8",
+  "Oslash;": "\xd8",
+  "Otilde": "\xd5",
+  "Otilde;": "\xd5",
+  "Otimes;": "\u2a37",
+  "Ouml": "\xd6",
+  "Ouml;": "\xd6",
+  "OverBar;": "\u203e",
+  "OverBrace;": "\u23de",
+  "OverBracket;": "\u23b4",
+  "OverParenthesis;": "\u23dc",
+  "PartialD;": "\u2202",
+  "Pcy;": "\u041f",
+  "Pfr;": "\u{01d513}",
+  "Phi;": "\u03a6",
+  "Pi;": "\u03a0",
+  "PlusMinus;": "\xb1",
+  "Poincareplane;": "\u210c",
+  "Popf;": "\u2119",
+  "Pr;": "\u2abb",
+  "Precedes;": "\u227a",
+  "PrecedesEqual;": "\u2aaf",
+  "PrecedesSlantEqual;": "\u227c",
+  "PrecedesTilde;": "\u227e",
+  "Prime;": "\u2033",
+  "Product;": "\u220f",
+  "Proportion;": "\u2237",
+  "Proportional;": "\u221d",
+  "Pscr;": "\u{01d4ab}",
+  "Psi;": "\u03a8",
+  "QUOT": "\"",
+  "QUOT;": "\"",
+  "Qfr;": "\u{01d514}",
+  "Qopf;": "\u211a",
+  "Qscr;": "\u{01d4ac}",
+  "RBarr;": "\u2910",
+  "REG": "\xae",
+  "REG;": "\xae",
+  "Racute;": "\u0154",
+  "Rang;": "\u27eb",
+  "Rarr;": "\u21a0",
+  "Rarrtl;": "\u2916",
+  "Rcaron;": "\u0158",
+  "Rcedil;": "\u0156",
+  "Rcy;": "\u0420",
+  "Re;": "\u211c",
+  "ReverseElement;": "\u220b",
+  "ReverseEquilibrium;": "\u21cb",
+  "ReverseUpEquilibrium;": "\u296f",
+  "Rfr;": "\u211c",
+  "Rho;": "\u03a1",
+  "RightAngleBracket;": "\u27e9",
+  "RightArrow;": "\u2192",
+  "RightArrowBar;": "\u21e5",
+  "RightArrowLeftArrow;": "\u21c4",
+  "RightCeiling;": "\u2309",
+  "RightDoubleBracket;": "\u27e7",
+  "RightDownTeeVector;": "\u295d",
+  "RightDownVector;": "\u21c2",
+  "RightDownVectorBar;": "\u2955",
+  "RightFloor;": "\u230b",
+  "RightTee;": "\u22a2",
+  "RightTeeArrow;": "\u21a6",
+  "RightTeeVector;": "\u295b",
+  "RightTriangle;": "\u22b3",
+  "RightTriangleBar;": "\u29d0",
+  "RightTriangleEqual;": "\u22b5",
+  "RightUpDownVector;": "\u294f",
+  "RightUpTeeVector;": "\u295c",
+  "RightUpVector;": "\u21be",
+  "RightUpVectorBar;": "\u2954",
+  "RightVector;": "\u21c0",
+  "RightVectorBar;": "\u2953",
+  "Rightarrow;": "\u21d2",
+  "Ropf;": "\u211d",
+  "RoundImplies;": "\u2970",
+  "Rrightarrow;": "\u21db",
+  "Rscr;": "\u211b",
+  "Rsh;": "\u21b1",
+  "RuleDelayed;": "\u29f4",
+  "SHCHcy;": "\u0429",
+  "SHcy;": "\u0428",
+  "SOFTcy;": "\u042c",
+  "Sacute;": "\u015a",
+  "Sc;": "\u2abc",
+  "Scaron;": "\u0160",
+  "Scedil;": "\u015e",
+  "Scirc;": "\u015c",
+  "Scy;": "\u0421",
+  "Sfr;": "\u{01d516}",
+  "ShortDownArrow;": "\u2193",
+  "ShortLeftArrow;": "\u2190",
+  "ShortRightArrow;": "\u2192",
+  "ShortUpArrow;": "\u2191",
+  "Sigma;": "\u03a3",
+  "SmallCircle;": "\u2218",
+  "Sopf;": "\u{01d54a}",
+  "Sqrt;": "\u221a",
+  "Square;": "\u25a1",
+  "SquareIntersection;": "\u2293",
+  "SquareSubset;": "\u228f",
+  "SquareSubsetEqual;": "\u2291",
+  "SquareSuperset;": "\u2290",
+  "SquareSupersetEqual;": "\u2292",
+  "SquareUnion;": "\u2294",
+  "Sscr;": "\u{01d4ae}",
+  "Star;": "\u22c6",
+  "Sub;": "\u22d0",
+  "Subset;": "\u22d0",
+  "SubsetEqual;": "\u2286",
+  "Succeeds;": "\u227b",
+  "SucceedsEqual;": "\u2ab0",
+  "SucceedsSlantEqual;": "\u227d",
+  "SucceedsTilde;": "\u227f",
+  "SuchThat;": "\u220b",
+  "Sum;": "\u2211",
+  "Sup;": "\u22d1",
+  "Superset;": "\u2283",
+  "SupersetEqual;": "\u2287",
+  "Supset;": "\u22d1",
+  "THORN": "\xde",
+  "THORN;": "\xde",
+  "TRADE;": "\u2122",
+  "TSHcy;": "\u040b",
+  "TScy;": "\u0426",
+  "Tab;": "\t",
+  "Tau;": "\u03a4",
+  "Tcaron;": "\u0164",
+  "Tcedil;": "\u0162",
+  "Tcy;": "\u0422",
+  "Tfr;": "\u{01d517}",
+  "Therefore;": "\u2234",
+  "Theta;": "\u0398",
+  "ThickSpace;": "\u205f\u200a",
+  "ThinSpace;": "\u2009",
+  "Tilde;": "\u223c",
+  "TildeEqual;": "\u2243",
+  "TildeFullEqual;": "\u2245",
+  "TildeTilde;": "\u2248",
+  "Topf;": "\u{01d54b}",
+  "TripleDot;": "\u20db",
+  "Tscr;": "\u{01d4af}",
+  "Tstrok;": "\u0166",
+  "Uacute": "\xda",
+  "Uacute;": "\xda",
+  "Uarr;": "\u219f",
+  "Uarrocir;": "\u2949",
+  "Ubrcy;": "\u040e",
+  "Ubreve;": "\u016c",
+  "Ucirc": "\xdb",
+  "Ucirc;": "\xdb",
+  "Ucy;": "\u0423",
+  "Udblac;": "\u0170",
+  "Ufr;": "\u{01d518}",
+  "Ugrave": "\xd9",
+  "Ugrave;": "\xd9",
+  "Umacr;": "\u016a",
+  "UnderBar;": "_",
+  "UnderBrace;": "\u23df",
+  "UnderBracket;": "\u23b5",
+  "UnderParenthesis;": "\u23dd",
+  "Union;": "\u22c3",
+  "UnionPlus;": "\u228e",
+  "Uogon;": "\u0172",
+  "Uopf;": "\u{01d54c}",
+  "UpArrow;": "\u2191",
+  "UpArrowBar;": "\u2912",
+  "UpArrowDownArrow;": "\u21c5",
+  "UpDownArrow;": "\u2195",
+  "UpEquilibrium;": "\u296e",
+  "UpTee;": "\u22a5",
+  "UpTeeArrow;": "\u21a5",
+  "Uparrow;": "\u21d1",
+  "Updownarrow;": "\u21d5",
+  "UpperLeftArrow;": "\u2196",
+  "UpperRightArrow;": "\u2197",
+  "Upsi;": "\u03d2",
+  "Upsilon;": "\u03a5",
+  "Uring;": "\u016e",
+  "Uscr;": "\u{01d4b0}",
+  "Utilde;": "\u0168",
+  "Uuml": "\xdc",
+  "Uuml;": "\xdc",
+  "VDash;": "\u22ab",
+  "Vbar;": "\u2aeb",
+  "Vcy;": "\u0412",
+  "Vdash;": "\u22a9",
+  "Vdashl;": "\u2ae6",
+  "Vee;": "\u22c1",
+  "Verbar;": "\u2016",
+  "Vert;": "\u2016",
+  "VerticalBar;": "\u2223",
+  "VerticalLine;": "|",
+  "VerticalSeparator;": "\u2758",
+  "VerticalTilde;": "\u2240",
+  "VeryThinSpace;": "\u200a",
+  "Vfr;": "\u{01d519}",
+  "Vopf;": "\u{01d54d}",
+  "Vscr;": "\u{01d4b1}",
+  "Vvdash;": "\u22aa",
+  "Wcirc;": "\u0174",
+  "Wedge;": "\u22c0",
+  "Wfr;": "\u{01d51a}",
+  "Wopf;": "\u{01d54e}",
+  "Wscr;": "\u{01d4b2}",
+  "Xfr;": "\u{01d51b}",
+  "Xi;": "\u039e",
+  "Xopf;": "\u{01d54f}",
+  "Xscr;": "\u{01d4b3}",
+  "YAcy;": "\u042f",
+  "YIcy;": "\u0407",
+  "YUcy;": "\u042e",
+  "Yacute": "\xdd",
+  "Yacute;": "\xdd",
+  "Ycirc;": "\u0176",
+  "Ycy;": "\u042b",
+  "Yfr;": "\u{01d51c}",
+  "Yopf;": "\u{01d550}",
+  "Yscr;": "\u{01d4b4}",
+  "Yuml;": "\u0178",
+  "ZHcy;": "\u0416",
+  "Zacute;": "\u0179",
+  "Zcaron;": "\u017d",
+  "Zcy;": "\u0417",
+  "Zdot;": "\u017b",
+  "ZeroWidthSpace;": "\u200b",
+  "Zeta;": "\u0396",
+  "Zfr;": "\u2128",
+  "Zopf;": "\u2124",
+  "Zscr;": "\u{01d4b5}",
+  "aacute": "\xe1",
+  "aacute;": "\xe1",
+  "abreve;": "\u0103",
+  "ac;": "\u223e",
+  "acE;": "\u223e\u0333",
+  "acd;": "\u223f",
+  "acirc": "\xe2",
+  "acirc;": "\xe2",
+  "acute": "\xb4",
+  "acute;": "\xb4",
+  "acy;": "\u0430",
+  "aelig": "\xe6",
+  "aelig;": "\xe6",
+  "af;": "\u2061",
+  "afr;": "\u{01d51e}",
+  "agrave": "\xe0",
+  "agrave;": "\xe0",
+  "alefsym;": "\u2135",
+  "aleph;": "\u2135",
+  "alpha;": "\u03b1",
+  "amacr;": "\u0101",
+  "amalg;": "\u2a3f",
+  "amp": "&",
+  "amp;": "&",
+  "and;": "\u2227",
+  "andand;": "\u2a55",
+  "andd;": "\u2a5c",
+  "andslope;": "\u2a58",
+  "andv;": "\u2a5a",
+  "ang;": "\u2220",
+  "ange;": "\u29a4",
+  "angle;": "\u2220",
+  "angmsd;": "\u2221",
+  "angmsdaa;": "\u29a8",
+  "angmsdab;": "\u29a9",
+  "angmsdac;": "\u29aa",
+  "angmsdad;": "\u29ab",
+  "angmsdae;": "\u29ac",
+  "angmsdaf;": "\u29ad",
+  "angmsdag;": "\u29ae",
+  "angmsdah;": "\u29af",
+  "angrt;": "\u221f",
+  "angrtvb;": "\u22be",
+  "angrtvbd;": "\u299d",
+  "angsph;": "\u2222",
+  "angst;": "\xc5",
+  "angzarr;": "\u237c",
+  "aogon;": "\u0105",
+  "aopf;": "\u{01d552}",
+  "ap;": "\u2248",
+  "apE;": "\u2a70",
+  "apacir;": "\u2a6f",
+  "ape;": "\u224a",
+  "apid;": "\u224b",
+  "apos;": "'",
+  "approx;": "\u2248",
+  "approxeq;": "\u224a",
+  "aring": "\xe5",
+  "aring;": "\xe5",
+  "ascr;": "\u{01d4b6}",
+  "ast;": "*",
+  "asymp;": "\u2248",
+  "asympeq;": "\u224d",
+  "atilde": "\xe3",
+  "atilde;": "\xe3",
+  "auml": "\xe4",
+  "auml;": "\xe4",
+  "awconint;": "\u2233",
+  "awint;": "\u2a11",
+  "bNot;": "\u2aed",
+  "backcong;": "\u224c",
+  "backepsilon;": "\u03f6",
+  "backprime;": "\u2035",
+  "backsim;": "\u223d",
+  "backsimeq;": "\u22cd",
+  "barvee;": "\u22bd",
+  "barwed;": "\u2305",
+  "barwedge;": "\u2305",
+  "bbrk;": "\u23b5",
+  "bbrktbrk;": "\u23b6",
+  "bcong;": "\u224c",
+  "bcy;": "\u0431",
+  "bdquo;": "\u201e",
+  "becaus;": "\u2235",
+  "because;": "\u2235",
+  "bemptyv;": "\u29b0",
+  "bepsi;": "\u03f6",
+  "bernou;": "\u212c",
+  "beta;": "\u03b2",
+  "beth;": "\u2136",
+  "between;": "\u226c",
+  "bfr;": "\u{01d51f}",
+  "bigcap;": "\u22c2",
+  "bigcirc;": "\u25ef",
+  "bigcup;": "\u22c3",
+  "bigodot;": "\u2a00",
+  "bigoplus;": "\u2a01",
+  "bigotimes;": "\u2a02",
+  "bigsqcup;": "\u2a06",
+  "bigstar;": "\u2605",
+  "bigtriangledown;": "\u25bd",
+  "bigtriangleup;": "\u25b3",
+  "biguplus;": "\u2a04",
+  "bigvee;": "\u22c1",
+  "bigwedge;": "\u22c0",
+  "bkarow;": "\u290d",
+  "blacklozenge;": "\u29eb",
+  "blacksquare;": "\u25aa",
+  "blacktriangle;": "\u25b4",
+  "blacktriangledown;": "\u25be",
+  "blacktriangleleft;": "\u25c2",
+  "blacktriangleright;": "\u25b8",
+  "blank;": "\u2423",
+  "blk12;": "\u2592",
+  "blk14;": "\u2591",
+  "blk34;": "\u2593",
+  "block;": "\u2588",
+  "bne;": "=\u20e5",
+  "bnequiv;": "\u2261\u20e5",
+  "bnot;": "\u2310",
+  "bopf;": "\u{01d553}",
+  "bot;": "\u22a5",
+  "bottom;": "\u22a5",
+  "bowtie;": "\u22c8",
+  "boxDL;": "\u2557",
+  "boxDR;": "\u2554",
+  "boxDl;": "\u2556",
+  "boxDr;": "\u2553",
+  "boxH;": "\u2550",
+  "boxHD;": "\u2566",
+  "boxHU;": "\u2569",
+  "boxHd;": "\u2564",
+  "boxHu;": "\u2567",
+  "boxUL;": "\u255d",
+  "boxUR;": "\u255a",
+  "boxUl;": "\u255c",
+  "boxUr;": "\u2559",
+  "boxV;": "\u2551",
+  "boxVH;": "\u256c",
+  "boxVL;": "\u2563",
+  "boxVR;": "\u2560",
+  "boxVh;": "\u256b",
+  "boxVl;": "\u2562",
+  "boxVr;": "\u255f",
+  "boxbox;": "\u29c9",
+  "boxdL;": "\u2555",
+  "boxdR;": "\u2552",
+  "boxdl;": "\u2510",
+  "boxdr;": "\u250c",
+  "boxh;": "\u2500",
+  "boxhD;": "\u2565",
+  "boxhU;": "\u2568",
+  "boxhd;": "\u252c",
+  "boxhu;": "\u2534",
+  "boxminus;": "\u229f",
+  "boxplus;": "\u229e",
+  "boxtimes;": "\u22a0",
+  "boxuL;": "\u255b",
+  "boxuR;": "\u2558",
+  "boxul;": "\u2518",
+  "boxur;": "\u2514",
+  "boxv;": "\u2502",
+  "boxvH;": "\u256a",
+  "boxvL;": "\u2561",
+  "boxvR;": "\u255e",
+  "boxvh;": "\u253c",
+  "boxvl;": "\u2524",
+  "boxvr;": "\u251c",
+  "bprime;": "\u2035",
+  "breve;": "\u02d8",
+  "brvbar": "\xa6",
+  "brvbar;": "\xa6",
+  "bscr;": "\u{01d4b7}",
+  "bsemi;": "\u204f",
+  "bsim;": "\u223d",
+  "bsime;": "\u22cd",
+  "bsol;": "\\",
+  "bsolb;": "\u29c5",
+  "bsolhsub;": "\u27c8",
+  "bull;": "\u2022",
+  "bullet;": "\u2022",
+  "bump;": "\u224e",
+  "bumpE;": "\u2aae",
+  "bumpe;": "\u224f",
+  "bumpeq;": "\u224f",
+  "cacute;": "\u0107",
+  "cap;": "\u2229",
+  "capand;": "\u2a44",
+  "capbrcup;": "\u2a49",
+  "capcap;": "\u2a4b",
+  "capcup;": "\u2a47",
+  "capdot;": "\u2a40",
+  "caps;": "\u2229\ufe00",
+  "caret;": "\u2041",
+  "caron;": "\u02c7",
+  "ccaps;": "\u2a4d",
+  "ccaron;": "\u010d",
+  "ccedil": "\xe7",
+  "ccedil;": "\xe7",
+  "ccirc;": "\u0109",
+  "ccups;": "\u2a4c",
+  "ccupssm;": "\u2a50",
+  "cdot;": "\u010b",
+  "cedil": "\xb8",
+  "cedil;": "\xb8",
+  "cemptyv;": "\u29b2",
+  "cent": "\xa2",
+  "cent;": "\xa2",
+  "centerdot;": "\xb7",
+  "cfr;": "\u{01d520}",
+  "chcy;": "\u0447",
+  "check;": "\u2713",
+  "checkmark;": "\u2713",
+  "chi;": "\u03c7",
+  "cir;": "\u25cb",
+  "cirE;": "\u29c3",
+  "circ;": "\u02c6",
+  "circeq;": "\u2257",
+  "circlearrowleft;": "\u21ba",
+  "circlearrowright;": "\u21bb",
+  "circledR;": "\xae",
+  "circledS;": "\u24c8",
+  "circledast;": "\u229b",
+  "circledcirc;": "\u229a",
+  "circleddash;": "\u229d",
+  "cire;": "\u2257",
+  "cirfnint;": "\u2a10",
+  "cirmid;": "\u2aef",
+  "cirscir;": "\u29c2",
+  "clubs;": "\u2663",
+  "clubsuit;": "\u2663",
+  "colon;": ":",
+  "colone;": "\u2254",
+  "coloneq;": "\u2254",
+  "comma;": ",",
+  "commat;": "@",
+  "comp;": "\u2201",
+  "compfn;": "\u2218",
+  "complement;": "\u2201",
+  "complexes;": "\u2102",
+  "cong;": "\u2245",
+  "congdot;": "\u2a6d",
+  "conint;": "\u222e",
+  "copf;": "\u{01d554}",
+  "coprod;": "\u2210",
+  "copy": "\xa9",
+  "copy;": "\xa9",
+  "copysr;": "\u2117",
+  "crarr;": "\u21b5",
+  "cross;": "\u2717",
+  "cscr;": "\u{01d4b8}",
+  "csub;": "\u2acf",
+  "csube;": "\u2ad1",
+  "csup;": "\u2ad0",
+  "csupe;": "\u2ad2",
+  "ctdot;": "\u22ef",
+  "cudarrl;": "\u2938",
+  "cudarrr;": "\u2935",
+  "cuepr;": "\u22de",
+  "cuesc;": "\u22df",
+  "cularr;": "\u21b6",
+  "cularrp;": "\u293d",
+  "cup;": "\u222a",
+  "cupbrcap;": "\u2a48",
+  "cupcap;": "\u2a46",
+  "cupcup;": "\u2a4a",
+  "cupdot;": "\u228d",
+  "cupor;": "\u2a45",
+  "cups;": "\u222a\ufe00",
+  "curarr;": "\u21b7",
+  "curarrm;": "\u293c",
+  "curlyeqprec;": "\u22de",
+  "curlyeqsucc;": "\u22df",
+  "curlyvee;": "\u22ce",
+  "curlywedge;": "\u22cf",
+  "curren": "\xa4",
+  "curren;": "\xa4",
+  "curvearrowleft;": "\u21b6",
+  "curvearrowright;": "\u21b7",
+  "cuvee;": "\u22ce",
+  "cuwed;": "\u22cf",
+  "cwconint;": "\u2232",
+  "cwint;": "\u2231",
+  "cylcty;": "\u232d",
+  "dArr;": "\u21d3",
+  "dHar;": "\u2965",
+  "dagger;": "\u2020",
+  "daleth;": "\u2138",
+  "darr;": "\u2193",
+  "dash;": "\u2010",
+  "dashv;": "\u22a3",
+  "dbkarow;": "\u290f",
+  "dblac;": "\u02dd",
+  "dcaron;": "\u010f",
+  "dcy;": "\u0434",
+  "dd;": "\u2146",
+  "ddagger;": "\u2021",
+  "ddarr;": "\u21ca",
+  "ddotseq;": "\u2a77",
+  "deg": "\xb0",
+  "deg;": "\xb0",
+  "delta;": "\u03b4",
+  "demptyv;": "\u29b1",
+  "dfisht;": "\u297f",
+  "dfr;": "\u{01d521}",
+  "dharl;": "\u21c3",
+  "dharr;": "\u21c2",
+  "diam;": "\u22c4",
+  "diamond;": "\u22c4",
+  "diamondsuit;": "\u2666",
+  "diams;": "\u2666",
+  "die;": "\xa8",
+  "digamma;": "\u03dd",
+  "disin;": "\u22f2",
+  "div;": "\xf7",
+  "divide": "\xf7",
+  "divide;": "\xf7",
+  "divideontimes;": "\u22c7",
+  "divonx;": "\u22c7",
+  "djcy;": "\u0452",
+  "dlcorn;": "\u231e",
+  "dlcrop;": "\u230d",
+  "dollar;": "\$",
+  "dopf;": "\u{01d555}",
+  "dot;": "\u02d9",
+  "doteq;": "\u2250",
+  "doteqdot;": "\u2251",
+  "dotminus;": "\u2238",
+  "dotplus;": "\u2214",
+  "dotsquare;": "\u22a1",
+  "doublebarwedge;": "\u2306",
+  "downarrow;": "\u2193",
+  "downdownarrows;": "\u21ca",
+  "downharpoonleft;": "\u21c3",
+  "downharpoonright;": "\u21c2",
+  "drbkarow;": "\u2910",
+  "drcorn;": "\u231f",
+  "drcrop;": "\u230c",
+  "dscr;": "\u{01d4b9}",
+  "dscy;": "\u0455",
+  "dsol;": "\u29f6",
+  "dstrok;": "\u0111",
+  "dtdot;": "\u22f1",
+  "dtri;": "\u25bf",
+  "dtrif;": "\u25be",
+  "duarr;": "\u21f5",
+  "duhar;": "\u296f",
+  "dwangle;": "\u29a6",
+  "dzcy;": "\u045f",
+  "dzigrarr;": "\u27ff",
+  "eDDot;": "\u2a77",
+  "eDot;": "\u2251",
+  "eacute": "\xe9",
+  "eacute;": "\xe9",
+  "easter;": "\u2a6e",
+  "ecaron;": "\u011b",
+  "ecir;": "\u2256",
+  "ecirc": "\xea",
+  "ecirc;": "\xea",
+  "ecolon;": "\u2255",
+  "ecy;": "\u044d",
+  "edot;": "\u0117",
+  "ee;": "\u2147",
+  "efDot;": "\u2252",
+  "efr;": "\u{01d522}",
+  "eg;": "\u2a9a",
+  "egrave": "\xe8",
+  "egrave;": "\xe8",
+  "egs;": "\u2a96",
+  "egsdot;": "\u2a98",
+  "el;": "\u2a99",
+  "elinters;": "\u23e7",
+  "ell;": "\u2113",
+  "els;": "\u2a95",
+  "elsdot;": "\u2a97",
+  "emacr;": "\u0113",
+  "empty;": "\u2205",
+  "emptyset;": "\u2205",
+  "emptyv;": "\u2205",
+  "emsp13;": "\u2004",
+  "emsp14;": "\u2005",
+  "emsp;": "\u2003",
+  "eng;": "\u014b",
+  "ensp;": "\u2002",
+  "eogon;": "\u0119",
+  "eopf;": "\u{01d556}",
+  "epar;": "\u22d5",
+  "eparsl;": "\u29e3",
+  "eplus;": "\u2a71",
+  "epsi;": "\u03b5",
+  "epsilon;": "\u03b5",
+  "epsiv;": "\u03f5",
+  "eqcirc;": "\u2256",
+  "eqcolon;": "\u2255",
+  "eqsim;": "\u2242",
+  "eqslantgtr;": "\u2a96",
+  "eqslantless;": "\u2a95",
+  "equals;": "=",
+  "equest;": "\u225f",
+  "equiv;": "\u2261",
+  "equivDD;": "\u2a78",
+  "eqvparsl;": "\u29e5",
+  "erDot;": "\u2253",
+  "erarr;": "\u2971",
+  "escr;": "\u212f",
+  "esdot;": "\u2250",
+  "esim;": "\u2242",
+  "eta;": "\u03b7",
+  "eth": "\xf0",
+  "eth;": "\xf0",
+  "euml": "\xeb",
+  "euml;": "\xeb",
+  "euro;": "\u20ac",
+  "excl;": "!",
+  "exist;": "\u2203",
+  "expectation;": "\u2130",
+  "exponentiale;": "\u2147",
+  "fallingdotseq;": "\u2252",
+  "fcy;": "\u0444",
+  "female;": "\u2640",
+  "ffilig;": "\ufb03",
+  "fflig;": "\ufb00",
+  "ffllig;": "\ufb04",
+  "ffr;": "\u{01d523}",
+  "filig;": "\ufb01",
+  "fjlig;": "fj",
+  "flat;": "\u266d",
+  "fllig;": "\ufb02",
+  "fltns;": "\u25b1",
+  "fnof;": "\u0192",
+  "fopf;": "\u{01d557}",
+  "forall;": "\u2200",
+  "fork;": "\u22d4",
+  "forkv;": "\u2ad9",
+  "fpartint;": "\u2a0d",
+  "frac12": "\xbd",
+  "frac12;": "\xbd",
+  "frac13;": "\u2153",
+  "frac14": "\xbc",
+  "frac14;": "\xbc",
+  "frac15;": "\u2155",
+  "frac16;": "\u2159",
+  "frac18;": "\u215b",
+  "frac23;": "\u2154",
+  "frac25;": "\u2156",
+  "frac34": "\xbe",
+  "frac34;": "\xbe",
+  "frac35;": "\u2157",
+  "frac38;": "\u215c",
+  "frac45;": "\u2158",
+  "frac56;": "\u215a",
+  "frac58;": "\u215d",
+  "frac78;": "\u215e",
+  "frasl;": "\u2044",
+  "frown;": "\u2322",
+  "fscr;": "\u{01d4bb}",
+  "gE;": "\u2267",
+  "gEl;": "\u2a8c",
+  "gacute;": "\u01f5",
+  "gamma;": "\u03b3",
+  "gammad;": "\u03dd",
+  "gap;": "\u2a86",
+  "gbreve;": "\u011f",
+  "gcirc;": "\u011d",
+  "gcy;": "\u0433",
+  "gdot;": "\u0121",
+  "ge;": "\u2265",
+  "gel;": "\u22db",
+  "geq;": "\u2265",
+  "geqq;": "\u2267",
+  "geqslant;": "\u2a7e",
+  "ges;": "\u2a7e",
+  "gescc;": "\u2aa9",
+  "gesdot;": "\u2a80",
+  "gesdoto;": "\u2a82",
+  "gesdotol;": "\u2a84",
+  "gesl;": "\u22db\ufe00",
+  "gesles;": "\u2a94",
+  "gfr;": "\u{01d524}",
+  "gg;": "\u226b",
+  "ggg;": "\u22d9",
+  "gimel;": "\u2137",
+  "gjcy;": "\u0453",
+  "gl;": "\u2277",
+  "glE;": "\u2a92",
+  "gla;": "\u2aa5",
+  "glj;": "\u2aa4",
+  "gnE;": "\u2269",
+  "gnap;": "\u2a8a",
+  "gnapprox;": "\u2a8a",
+  "gne;": "\u2a88",
+  "gneq;": "\u2a88",
+  "gneqq;": "\u2269",
+  "gnsim;": "\u22e7",
+  "gopf;": "\u{01d558}",
+  "grave;": "`",
+  "gscr;": "\u210a",
+  "gsim;": "\u2273",
+  "gsime;": "\u2a8e",
+  "gsiml;": "\u2a90",
+  "gt": ">",
+  "gt;": ">",
+  "gtcc;": "\u2aa7",
+  "gtcir;": "\u2a7a",
+  "gtdot;": "\u22d7",
+  "gtlPar;": "\u2995",
+  "gtquest;": "\u2a7c",
+  "gtrapprox;": "\u2a86",
+  "gtrarr;": "\u2978",
+  "gtrdot;": "\u22d7",
+  "gtreqless;": "\u22db",
+  "gtreqqless;": "\u2a8c",
+  "gtrless;": "\u2277",
+  "gtrsim;": "\u2273",
+  "gvertneqq;": "\u2269\ufe00",
+  "gvnE;": "\u2269\ufe00",
+  "hArr;": "\u21d4",
+  "hairsp;": "\u200a",
+  "half;": "\xbd",
+  "hamilt;": "\u210b",
+  "hardcy;": "\u044a",
+  "harr;": "\u2194",
+  "harrcir;": "\u2948",
+  "harrw;": "\u21ad",
+  "hbar;": "\u210f",
+  "hcirc;": "\u0125",
+  "hearts;": "\u2665",
+  "heartsuit;": "\u2665",
+  "hellip;": "\u2026",
+  "hercon;": "\u22b9",
+  "hfr;": "\u{01d525}",
+  "hksearow;": "\u2925",
+  "hkswarow;": "\u2926",
+  "hoarr;": "\u21ff",
+  "homtht;": "\u223b",
+  "hookleftarrow;": "\u21a9",
+  "hookrightarrow;": "\u21aa",
+  "hopf;": "\u{01d559}",
+  "horbar;": "\u2015",
+  "hscr;": "\u{01d4bd}",
+  "hslash;": "\u210f",
+  "hstrok;": "\u0127",
+  "hybull;": "\u2043",
+  "hyphen;": "\u2010",
+  "iacute": "\xed",
+  "iacute;": "\xed",
+  "ic;": "\u2063",
+  "icirc": "\xee",
+  "icirc;": "\xee",
+  "icy;": "\u0438",
+  "iecy;": "\u0435",
+  "iexcl": "\xa1",
+  "iexcl;": "\xa1",
+  "iff;": "\u21d4",
+  "ifr;": "\u{01d526}",
+  "igrave": "\xec",
+  "igrave;": "\xec",
+  "ii;": "\u2148",
+  "iiiint;": "\u2a0c",
+  "iiint;": "\u222d",
+  "iinfin;": "\u29dc",
+  "iiota;": "\u2129",
+  "ijlig;": "\u0133",
+  "imacr;": "\u012b",
+  "image;": "\u2111",
+  "imagline;": "\u2110",
+  "imagpart;": "\u2111",
+  "imath;": "\u0131",
+  "imof;": "\u22b7",
+  "imped;": "\u01b5",
+  "in;": "\u2208",
+  "incare;": "\u2105",
+  "infin;": "\u221e",
+  "infintie;": "\u29dd",
+  "inodot;": "\u0131",
+  "int;": "\u222b",
+  "intcal;": "\u22ba",
+  "integers;": "\u2124",
+  "intercal;": "\u22ba",
+  "intlarhk;": "\u2a17",
+  "intprod;": "\u2a3c",
+  "iocy;": "\u0451",
+  "iogon;": "\u012f",
+  "iopf;": "\u{01d55a}",
+  "iota;": "\u03b9",
+  "iprod;": "\u2a3c",
+  "iquest": "\xbf",
+  "iquest;": "\xbf",
+  "iscr;": "\u{01d4be}",
+  "isin;": "\u2208",
+  "isinE;": "\u22f9",
+  "isindot;": "\u22f5",
+  "isins;": "\u22f4",
+  "isinsv;": "\u22f3",
+  "isinv;": "\u2208",
+  "it;": "\u2062",
+  "itilde;": "\u0129",
+  "iukcy;": "\u0456",
+  "iuml": "\xef",
+  "iuml;": "\xef",
+  "jcirc;": "\u0135",
+  "jcy;": "\u0439",
+  "jfr;": "\u{01d527}",
+  "jmath;": "\u0237",
+  "jopf;": "\u{01d55b}",
+  "jscr;": "\u{01d4bf}",
+  "jsercy;": "\u0458",
+  "jukcy;": "\u0454",
+  "kappa;": "\u03ba",
+  "kappav;": "\u03f0",
+  "kcedil;": "\u0137",
+  "kcy;": "\u043a",
+  "kfr;": "\u{01d528}",
+  "kgreen;": "\u0138",
+  "khcy;": "\u0445",
+  "kjcy;": "\u045c",
+  "kopf;": "\u{01d55c}",
+  "kscr;": "\u{01d4c0}",
+  "lAarr;": "\u21da",
+  "lArr;": "\u21d0",
+  "lAtail;": "\u291b",
+  "lBarr;": "\u290e",
+  "lE;": "\u2266",
+  "lEg;": "\u2a8b",
+  "lHar;": "\u2962",
+  "lacute;": "\u013a",
+  "laemptyv;": "\u29b4",
+  "lagran;": "\u2112",
+  "lambda;": "\u03bb",
+  "lang;": "\u27e8",
+  "langd;": "\u2991",
+  "langle;": "\u27e8",
+  "lap;": "\u2a85",
+  "laquo": "\xab",
+  "laquo;": "\xab",
+  "larr;": "\u2190",
+  "larrb;": "\u21e4",
+  "larrbfs;": "\u291f",
+  "larrfs;": "\u291d",
+  "larrhk;": "\u21a9",
+  "larrlp;": "\u21ab",
+  "larrpl;": "\u2939",
+  "larrsim;": "\u2973",
+  "larrtl;": "\u21a2",
+  "lat;": "\u2aab",
+  "latail;": "\u2919",
+  "late;": "\u2aad",
+  "lates;": "\u2aad\ufe00",
+  "lbarr;": "\u290c",
+  "lbbrk;": "\u2772",
+  "lbrace;": "{",
+  "lbrack;": "[",
+  "lbrke;": "\u298b",
+  "lbrksld;": "\u298f",
+  "lbrkslu;": "\u298d",
+  "lcaron;": "\u013e",
+  "lcedil;": "\u013c",
+  "lceil;": "\u2308",
+  "lcub;": "{",
+  "lcy;": "\u043b",
+  "ldca;": "\u2936",
+  "ldquo;": "\u201c",
+  "ldquor;": "\u201e",
+  "ldrdhar;": "\u2967",
+  "ldrushar;": "\u294b",
+  "ldsh;": "\u21b2",
+  "le;": "\u2264",
+  "leftarrow;": "\u2190",
+  "leftarrowtail;": "\u21a2",
+  "leftharpoondown;": "\u21bd",
+  "leftharpoonup;": "\u21bc",
+  "leftleftarrows;": "\u21c7",
+  "leftrightarrow;": "\u2194",
+  "leftrightarrows;": "\u21c6",
+  "leftrightharpoons;": "\u21cb",
+  "leftrightsquigarrow;": "\u21ad",
+  "leftthreetimes;": "\u22cb",
+  "leg;": "\u22da",
+  "leq;": "\u2264",
+  "leqq;": "\u2266",
+  "leqslant;": "\u2a7d",
+  "les;": "\u2a7d",
+  "lescc;": "\u2aa8",
+  "lesdot;": "\u2a7f",
+  "lesdoto;": "\u2a81",
+  "lesdotor;": "\u2a83",
+  "lesg;": "\u22da\ufe00",
+  "lesges;": "\u2a93",
+  "lessapprox;": "\u2a85",
+  "lessdot;": "\u22d6",
+  "lesseqgtr;": "\u22da",
+  "lesseqqgtr;": "\u2a8b",
+  "lessgtr;": "\u2276",
+  "lesssim;": "\u2272",
+  "lfisht;": "\u297c",
+  "lfloor;": "\u230a",
+  "lfr;": "\u{01d529}",
+  "lg;": "\u2276",
+  "lgE;": "\u2a91",
+  "lhard;": "\u21bd",
+  "lharu;": "\u21bc",
+  "lharul;": "\u296a",
+  "lhblk;": "\u2584",
+  "ljcy;": "\u0459",
+  "ll;": "\u226a",
+  "llarr;": "\u21c7",
+  "llcorner;": "\u231e",
+  "llhard;": "\u296b",
+  "lltri;": "\u25fa",
+  "lmidot;": "\u0140",
+  "lmoust;": "\u23b0",
+  "lmoustache;": "\u23b0",
+  "lnE;": "\u2268",
+  "lnap;": "\u2a89",
+  "lnapprox;": "\u2a89",
+  "lne;": "\u2a87",
+  "lneq;": "\u2a87",
+  "lneqq;": "\u2268",
+  "lnsim;": "\u22e6",
+  "loang;": "\u27ec",
+  "loarr;": "\u21fd",
+  "lobrk;": "\u27e6",
+  "longleftarrow;": "\u27f5",
+  "longleftrightarrow;": "\u27f7",
+  "longmapsto;": "\u27fc",
+  "longrightarrow;": "\u27f6",
+  "looparrowleft;": "\u21ab",
+  "looparrowright;": "\u21ac",
+  "lopar;": "\u2985",
+  "lopf;": "\u{01d55d}",
+  "loplus;": "\u2a2d",
+  "lotimes;": "\u2a34",
+  "lowast;": "\u2217",
+  "lowbar;": "_",
+  "loz;": "\u25ca",
+  "lozenge;": "\u25ca",
+  "lozf;": "\u29eb",
+  "lpar;": "(",
+  "lparlt;": "\u2993",
+  "lrarr;": "\u21c6",
+  "lrcorner;": "\u231f",
+  "lrhar;": "\u21cb",
+  "lrhard;": "\u296d",
+  "lrm;": "\u200e",
+  "lrtri;": "\u22bf",
+  "lsaquo;": "\u2039",
+  "lscr;": "\u{01d4c1}",
+  "lsh;": "\u21b0",
+  "lsim;": "\u2272",
+  "lsime;": "\u2a8d",
+  "lsimg;": "\u2a8f",
+  "lsqb;": "[",
+  "lsquo;": "\u2018",
+  "lsquor;": "\u201a",
+  "lstrok;": "\u0142",
+  "lt": "<",
+  "lt;": "<",
+  "ltcc;": "\u2aa6",
+  "ltcir;": "\u2a79",
+  "ltdot;": "\u22d6",
+  "lthree;": "\u22cb",
+  "ltimes;": "\u22c9",
+  "ltlarr;": "\u2976",
+  "ltquest;": "\u2a7b",
+  "ltrPar;": "\u2996",
+  "ltri;": "\u25c3",
+  "ltrie;": "\u22b4",
+  "ltrif;": "\u25c2",
+  "lurdshar;": "\u294a",
+  "luruhar;": "\u2966",
+  "lvertneqq;": "\u2268\ufe00",
+  "lvnE;": "\u2268\ufe00",
+  "mDDot;": "\u223a",
+  "macr": "\xaf",
+  "macr;": "\xaf",
+  "male;": "\u2642",
+  "malt;": "\u2720",
+  "maltese;": "\u2720",
+  "map;": "\u21a6",
+  "mapsto;": "\u21a6",
+  "mapstodown;": "\u21a7",
+  "mapstoleft;": "\u21a4",
+  "mapstoup;": "\u21a5",
+  "marker;": "\u25ae",
+  "mcomma;": "\u2a29",
+  "mcy;": "\u043c",
+  "mdash;": "\u2014",
+  "measuredangle;": "\u2221",
+  "mfr;": "\u{01d52a}",
+  "mho;": "\u2127",
+  "micro": "\xb5",
+  "micro;": "\xb5",
+  "mid;": "\u2223",
+  "midast;": "*",
+  "midcir;": "\u2af0",
+  "middot": "\xb7",
+  "middot;": "\xb7",
+  "minus;": "\u2212",
+  "minusb;": "\u229f",
+  "minusd;": "\u2238",
+  "minusdu;": "\u2a2a",
+  "mlcp;": "\u2adb",
+  "mldr;": "\u2026",
+  "mnplus;": "\u2213",
+  "models;": "\u22a7",
+  "mopf;": "\u{01d55e}",
+  "mp;": "\u2213",
+  "mscr;": "\u{01d4c2}",
+  "mstpos;": "\u223e",
+  "mu;": "\u03bc",
+  "multimap;": "\u22b8",
+  "mumap;": "\u22b8",
+  "nGg;": "\u22d9\u0338",
+  "nGt;": "\u226b\u20d2",
+  "nGtv;": "\u226b\u0338",
+  "nLeftarrow;": "\u21cd",
+  "nLeftrightarrow;": "\u21ce",
+  "nLl;": "\u22d8\u0338",
+  "nLt;": "\u226a\u20d2",
+  "nLtv;": "\u226a\u0338",
+  "nRightarrow;": "\u21cf",
+  "nVDash;": "\u22af",
+  "nVdash;": "\u22ae",
+  "nabla;": "\u2207",
+  "nacute;": "\u0144",
+  "nang;": "\u2220\u20d2",
+  "nap;": "\u2249",
+  "napE;": "\u2a70\u0338",
+  "napid;": "\u224b\u0338",
+  "napos;": "\u0149",
+  "napprox;": "\u2249",
+  "natur;": "\u266e",
+  "natural;": "\u266e",
+  "naturals;": "\u2115",
+  "nbsp": "\xa0",
+  "nbsp;": "\xa0",
+  "nbump;": "\u224e\u0338",
+  "nbumpe;": "\u224f\u0338",
+  "ncap;": "\u2a43",
+  "ncaron;": "\u0148",
+  "ncedil;": "\u0146",
+  "ncong;": "\u2247",
+  "ncongdot;": "\u2a6d\u0338",
+  "ncup;": "\u2a42",
+  "ncy;": "\u043d",
+  "ndash;": "\u2013",
+  "ne;": "\u2260",
+  "neArr;": "\u21d7",
+  "nearhk;": "\u2924",
+  "nearr;": "\u2197",
+  "nearrow;": "\u2197",
+  "nedot;": "\u2250\u0338",
+  "nequiv;": "\u2262",
+  "nesear;": "\u2928",
+  "nesim;": "\u2242\u0338",
+  "nexist;": "\u2204",
+  "nexists;": "\u2204",
+  "nfr;": "\u{01d52b}",
+  "ngE;": "\u2267\u0338",
+  "nge;": "\u2271",
+  "ngeq;": "\u2271",
+  "ngeqq;": "\u2267\u0338",
+  "ngeqslant;": "\u2a7e\u0338",
+  "nges;": "\u2a7e\u0338",
+  "ngsim;": "\u2275",
+  "ngt;": "\u226f",
+  "ngtr;": "\u226f",
+  "nhArr;": "\u21ce",
+  "nharr;": "\u21ae",
+  "nhpar;": "\u2af2",
+  "ni;": "\u220b",
+  "nis;": "\u22fc",
+  "nisd;": "\u22fa",
+  "niv;": "\u220b",
+  "njcy;": "\u045a",
+  "nlArr;": "\u21cd",
+  "nlE;": "\u2266\u0338",
+  "nlarr;": "\u219a",
+  "nldr;": "\u2025",
+  "nle;": "\u2270",
+  "nleftarrow;": "\u219a",
+  "nleftrightarrow;": "\u21ae",
+  "nleq;": "\u2270",
+  "nleqq;": "\u2266\u0338",
+  "nleqslant;": "\u2a7d\u0338",
+  "nles;": "\u2a7d\u0338",
+  "nless;": "\u226e",
+  "nlsim;": "\u2274",
+  "nlt;": "\u226e",
+  "nltri;": "\u22ea",
+  "nltrie;": "\u22ec",
+  "nmid;": "\u2224",
+  "nopf;": "\u{01d55f}",
+  "not": "\xac",
+  "not;": "\xac",
+  "notin;": "\u2209",
+  "notinE;": "\u22f9\u0338",
+  "notindot;": "\u22f5\u0338",
+  "notinva;": "\u2209",
+  "notinvb;": "\u22f7",
+  "notinvc;": "\u22f6",
+  "notni;": "\u220c",
+  "notniva;": "\u220c",
+  "notnivb;": "\u22fe",
+  "notnivc;": "\u22fd",
+  "npar;": "\u2226",
+  "nparallel;": "\u2226",
+  "nparsl;": "\u2afd\u20e5",
+  "npart;": "\u2202\u0338",
+  "npolint;": "\u2a14",
+  "npr;": "\u2280",
+  "nprcue;": "\u22e0",
+  "npre;": "\u2aaf\u0338",
+  "nprec;": "\u2280",
+  "npreceq;": "\u2aaf\u0338",
+  "nrArr;": "\u21cf",
+  "nrarr;": "\u219b",
+  "nrarrc;": "\u2933\u0338",
+  "nrarrw;": "\u219d\u0338",
+  "nrightarrow;": "\u219b",
+  "nrtri;": "\u22eb",
+  "nrtrie;": "\u22ed",
+  "nsc;": "\u2281",
+  "nsccue;": "\u22e1",
+  "nsce;": "\u2ab0\u0338",
+  "nscr;": "\u{01d4c3}",
+  "nshortmid;": "\u2224",
+  "nshortparallel;": "\u2226",
+  "nsim;": "\u2241",
+  "nsime;": "\u2244",
+  "nsimeq;": "\u2244",
+  "nsmid;": "\u2224",
+  "nspar;": "\u2226",
+  "nsqsube;": "\u22e2",
+  "nsqsupe;": "\u22e3",
+  "nsub;": "\u2284",
+  "nsubE;": "\u2ac5\u0338",
+  "nsube;": "\u2288",
+  "nsubset;": "\u2282\u20d2",
+  "nsubseteq;": "\u2288",
+  "nsubseteqq;": "\u2ac5\u0338",
+  "nsucc;": "\u2281",
+  "nsucceq;": "\u2ab0\u0338",
+  "nsup;": "\u2285",
+  "nsupE;": "\u2ac6\u0338",
+  "nsupe;": "\u2289",
+  "nsupset;": "\u2283\u20d2",
+  "nsupseteq;": "\u2289",
+  "nsupseteqq;": "\u2ac6\u0338",
+  "ntgl;": "\u2279",
+  "ntilde": "\xf1",
+  "ntilde;": "\xf1",
+  "ntlg;": "\u2278",
+  "ntriangleleft;": "\u22ea",
+  "ntrianglelefteq;": "\u22ec",
+  "ntriangleright;": "\u22eb",
+  "ntrianglerighteq;": "\u22ed",
+  "nu;": "\u03bd",
+  "num;": "#",
+  "numero;": "\u2116",
+  "numsp;": "\u2007",
+  "nvDash;": "\u22ad",
+  "nvHarr;": "\u2904",
+  "nvap;": "\u224d\u20d2",
+  "nvdash;": "\u22ac",
+  "nvge;": "\u2265\u20d2",
+  "nvgt;": ">\u20d2",
+  "nvinfin;": "\u29de",
+  "nvlArr;": "\u2902",
+  "nvle;": "\u2264\u20d2",
+  "nvlt;": "<\u20d2",
+  "nvltrie;": "\u22b4\u20d2",
+  "nvrArr;": "\u2903",
+  "nvrtrie;": "\u22b5\u20d2",
+  "nvsim;": "\u223c\u20d2",
+  "nwArr;": "\u21d6",
+  "nwarhk;": "\u2923",
+  "nwarr;": "\u2196",
+  "nwarrow;": "\u2196",
+  "nwnear;": "\u2927",
+  "oS;": "\u24c8",
+  "oacute": "\xf3",
+  "oacute;": "\xf3",
+  "oast;": "\u229b",
+  "ocir;": "\u229a",
+  "ocirc": "\xf4",
+  "ocirc;": "\xf4",
+  "ocy;": "\u043e",
+  "odash;": "\u229d",
+  "odblac;": "\u0151",
+  "odiv;": "\u2a38",
+  "odot;": "\u2299",
+  "odsold;": "\u29bc",
+  "oelig;": "\u0153",
+  "ofcir;": "\u29bf",
+  "ofr;": "\u{01d52c}",
+  "ogon;": "\u02db",
+  "ograve": "\xf2",
+  "ograve;": "\xf2",
+  "ogt;": "\u29c1",
+  "ohbar;": "\u29b5",
+  "ohm;": "\u03a9",
+  "oint;": "\u222e",
+  "olarr;": "\u21ba",
+  "olcir;": "\u29be",
+  "olcross;": "\u29bb",
+  "oline;": "\u203e",
+  "olt;": "\u29c0",
+  "omacr;": "\u014d",
+  "omega;": "\u03c9",
+  "omicron;": "\u03bf",
+  "omid;": "\u29b6",
+  "ominus;": "\u2296",
+  "oopf;": "\u{01d560}",
+  "opar;": "\u29b7",
+  "operp;": "\u29b9",
+  "oplus;": "\u2295",
+  "or;": "\u2228",
+  "orarr;": "\u21bb",
+  "ord;": "\u2a5d",
+  "order;": "\u2134",
+  "orderof;": "\u2134",
+  "ordf": "\xaa",
+  "ordf;": "\xaa",
+  "ordm": "\xba",
+  "ordm;": "\xba",
+  "origof;": "\u22b6",
+  "oror;": "\u2a56",
+  "orslope;": "\u2a57",
+  "orv;": "\u2a5b",
+  "oscr;": "\u2134",
+  "oslash": "\xf8",
+  "oslash;": "\xf8",
+  "osol;": "\u2298",
+  "otilde": "\xf5",
+  "otilde;": "\xf5",
+  "otimes;": "\u2297",
+  "otimesas;": "\u2a36",
+  "ouml": "\xf6",
+  "ouml;": "\xf6",
+  "ovbar;": "\u233d",
+  "par;": "\u2225",
+  "para": "\xb6",
+  "para;": "\xb6",
+  "parallel;": "\u2225",
+  "parsim;": "\u2af3",
+  "parsl;": "\u2afd",
+  "part;": "\u2202",
+  "pcy;": "\u043f",
+  "percnt;": "%",
+  "period;": ".",
+  "permil;": "\u2030",
+  "perp;": "\u22a5",
+  "pertenk;": "\u2031",
+  "pfr;": "\u{01d52d}",
+  "phi;": "\u03c6",
+  "phiv;": "\u03d5",
+  "phmmat;": "\u2133",
+  "phone;": "\u260e",
+  "pi;": "\u03c0",
+  "pitchfork;": "\u22d4",
+  "piv;": "\u03d6",
+  "planck;": "\u210f",
+  "planckh;": "\u210e",
+  "plankv;": "\u210f",
+  "plus;": "+",
+  "plusacir;": "\u2a23",
+  "plusb;": "\u229e",
+  "pluscir;": "\u2a22",
+  "plusdo;": "\u2214",
+  "plusdu;": "\u2a25",
+  "pluse;": "\u2a72",
+  "plusmn": "\xb1",
+  "plusmn;": "\xb1",
+  "plussim;": "\u2a26",
+  "plustwo;": "\u2a27",
+  "pm;": "\xb1",
+  "pointint;": "\u2a15",
+  "popf;": "\u{01d561}",
+  "pound": "\xa3",
+  "pound;": "\xa3",
+  "pr;": "\u227a",
+  "prE;": "\u2ab3",
+  "prap;": "\u2ab7",
+  "prcue;": "\u227c",
+  "pre;": "\u2aaf",
+  "prec;": "\u227a",
+  "precapprox;": "\u2ab7",
+  "preccurlyeq;": "\u227c",
+  "preceq;": "\u2aaf",
+  "precnapprox;": "\u2ab9",
+  "precneqq;": "\u2ab5",
+  "precnsim;": "\u22e8",
+  "precsim;": "\u227e",
+  "prime;": "\u2032",
+  "primes;": "\u2119",
+  "prnE;": "\u2ab5",
+  "prnap;": "\u2ab9",
+  "prnsim;": "\u22e8",
+  "prod;": "\u220f",
+  "profalar;": "\u232e",
+  "profline;": "\u2312",
+  "profsurf;": "\u2313",
+  "prop;": "\u221d",
+  "propto;": "\u221d",
+  "prsim;": "\u227e",
+  "prurel;": "\u22b0",
+  "pscr;": "\u{01d4c5}",
+  "psi;": "\u03c8",
+  "puncsp;": "\u2008",
+  "qfr;": "\u{01d52e}",
+  "qint;": "\u2a0c",
+  "qopf;": "\u{01d562}",
+  "qprime;": "\u2057",
+  "qscr;": "\u{01d4c6}",
+  "quaternions;": "\u210d",
+  "quatint;": "\u2a16",
+  "quest;": "?",
+  "questeq;": "\u225f",
+  "quot": "\"",
+  "quot;": "\"",
+  "rAarr;": "\u21db",
+  "rArr;": "\u21d2",
+  "rAtail;": "\u291c",
+  "rBarr;": "\u290f",
+  "rHar;": "\u2964",
+  "race;": "\u223d\u0331",
+  "racute;": "\u0155",
+  "radic;": "\u221a",
+  "raemptyv;": "\u29b3",
+  "rang;": "\u27e9",
+  "rangd;": "\u2992",
+  "range;": "\u29a5",
+  "rangle;": "\u27e9",
+  "raquo": "\xbb",
+  "raquo;": "\xbb",
+  "rarr;": "\u2192",
+  "rarrap;": "\u2975",
+  "rarrb;": "\u21e5",
+  "rarrbfs;": "\u2920",
+  "rarrc;": "\u2933",
+  "rarrfs;": "\u291e",
+  "rarrhk;": "\u21aa",
+  "rarrlp;": "\u21ac",
+  "rarrpl;": "\u2945",
+  "rarrsim;": "\u2974",
+  "rarrtl;": "\u21a3",
+  "rarrw;": "\u219d",
+  "ratail;": "\u291a",
+  "ratio;": "\u2236",
+  "rationals;": "\u211a",
+  "rbarr;": "\u290d",
+  "rbbrk;": "\u2773",
+  "rbrace;": "}",
+  "rbrack;": "]",
+  "rbrke;": "\u298c",
+  "rbrksld;": "\u298e",
+  "rbrkslu;": "\u2990",
+  "rcaron;": "\u0159",
+  "rcedil;": "\u0157",
+  "rceil;": "\u2309",
+  "rcub;": "}",
+  "rcy;": "\u0440",
+  "rdca;": "\u2937",
+  "rdldhar;": "\u2969",
+  "rdquo;": "\u201d",
+  "rdquor;": "\u201d",
+  "rdsh;": "\u21b3",
+  "real;": "\u211c",
+  "realine;": "\u211b",
+  "realpart;": "\u211c",
+  "reals;": "\u211d",
+  "rect;": "\u25ad",
+  "reg": "\xae",
+  "reg;": "\xae",
+  "rfisht;": "\u297d",
+  "rfloor;": "\u230b",
+  "rfr;": "\u{01d52f}",
+  "rhard;": "\u21c1",
+  "rharu;": "\u21c0",
+  "rharul;": "\u296c",
+  "rho;": "\u03c1",
+  "rhov;": "\u03f1",
+  "rightarrow;": "\u2192",
+  "rightarrowtail;": "\u21a3",
+  "rightharpoondown;": "\u21c1",
+  "rightharpoonup;": "\u21c0",
+  "rightleftarrows;": "\u21c4",
+  "rightleftharpoons;": "\u21cc",
+  "rightrightarrows;": "\u21c9",
+  "rightsquigarrow;": "\u219d",
+  "rightthreetimes;": "\u22cc",
+  "ring;": "\u02da",
+  "risingdotseq;": "\u2253",
+  "rlarr;": "\u21c4",
+  "rlhar;": "\u21cc",
+  "rlm;": "\u200f",
+  "rmoust;": "\u23b1",
+  "rmoustache;": "\u23b1",
+  "rnmid;": "\u2aee",
+  "roang;": "\u27ed",
+  "roarr;": "\u21fe",
+  "robrk;": "\u27e7",
+  "ropar;": "\u2986",
+  "ropf;": "\u{01d563}",
+  "roplus;": "\u2a2e",
+  "rotimes;": "\u2a35",
+  "rpar;": ")",
+  "rpargt;": "\u2994",
+  "rppolint;": "\u2a12",
+  "rrarr;": "\u21c9",
+  "rsaquo;": "\u203a",
+  "rscr;": "\u{01d4c7}",
+  "rsh;": "\u21b1",
+  "rsqb;": "]",
+  "rsquo;": "\u2019",
+  "rsquor;": "\u2019",
+  "rthree;": "\u22cc",
+  "rtimes;": "\u22ca",
+  "rtri;": "\u25b9",
+  "rtrie;": "\u22b5",
+  "rtrif;": "\u25b8",
+  "rtriltri;": "\u29ce",
+  "ruluhar;": "\u2968",
+  "rx;": "\u211e",
+  "sacute;": "\u015b",
+  "sbquo;": "\u201a",
+  "sc;": "\u227b",
+  "scE;": "\u2ab4",
+  "scap;": "\u2ab8",
+  "scaron;": "\u0161",
+  "sccue;": "\u227d",
+  "sce;": "\u2ab0",
+  "scedil;": "\u015f",
+  "scirc;": "\u015d",
+  "scnE;": "\u2ab6",
+  "scnap;": "\u2aba",
+  "scnsim;": "\u22e9",
+  "scpolint;": "\u2a13",
+  "scsim;": "\u227f",
+  "scy;": "\u0441",
+  "sdot;": "\u22c5",
+  "sdotb;": "\u22a1",
+  "sdote;": "\u2a66",
+  "seArr;": "\u21d8",
+  "searhk;": "\u2925",
+  "searr;": "\u2198",
+  "searrow;": "\u2198",
+  "sect": "\xa7",
+  "sect;": "\xa7",
+  "semi;": ";",
+  "seswar;": "\u2929",
+  "setminus;": "\u2216",
+  "setmn;": "\u2216",
+  "sext;": "\u2736",
+  "sfr;": "\u{01d530}",
+  "sfrown;": "\u2322",
+  "sharp;": "\u266f",
+  "shchcy;": "\u0449",
+  "shcy;": "\u0448",
+  "shortmid;": "\u2223",
+  "shortparallel;": "\u2225",
+  "shy": "\xad",
+  "shy;": "\xad",
+  "sigma;": "\u03c3",
+  "sigmaf;": "\u03c2",
+  "sigmav;": "\u03c2",
+  "sim;": "\u223c",
+  "simdot;": "\u2a6a",
+  "sime;": "\u2243",
+  "simeq;": "\u2243",
+  "simg;": "\u2a9e",
+  "simgE;": "\u2aa0",
+  "siml;": "\u2a9d",
+  "simlE;": "\u2a9f",
+  "simne;": "\u2246",
+  "simplus;": "\u2a24",
+  "simrarr;": "\u2972",
+  "slarr;": "\u2190",
+  "smallsetminus;": "\u2216",
+  "smashp;": "\u2a33",
+  "smeparsl;": "\u29e4",
+  "smid;": "\u2223",
+  "smile;": "\u2323",
+  "smt;": "\u2aaa",
+  "smte;": "\u2aac",
+  "smtes;": "\u2aac\ufe00",
+  "softcy;": "\u044c",
+  "sol;": "/",
+  "solb;": "\u29c4",
+  "solbar;": "\u233f",
+  "sopf;": "\u{01d564}",
+  "spades;": "\u2660",
+  "spadesuit;": "\u2660",
+  "spar;": "\u2225",
+  "sqcap;": "\u2293",
+  "sqcaps;": "\u2293\ufe00",
+  "sqcup;": "\u2294",
+  "sqcups;": "\u2294\ufe00",
+  "sqsub;": "\u228f",
+  "sqsube;": "\u2291",
+  "sqsubset;": "\u228f",
+  "sqsubseteq;": "\u2291",
+  "sqsup;": "\u2290",
+  "sqsupe;": "\u2292",
+  "sqsupset;": "\u2290",
+  "sqsupseteq;": "\u2292",
+  "squ;": "\u25a1",
+  "square;": "\u25a1",
+  "squarf;": "\u25aa",
+  "squf;": "\u25aa",
+  "srarr;": "\u2192",
+  "sscr;": "\u{01d4c8}",
+  "ssetmn;": "\u2216",
+  "ssmile;": "\u2323",
+  "sstarf;": "\u22c6",
+  "star;": "\u2606",
+  "starf;": "\u2605",
+  "straightepsilon;": "\u03f5",
+  "straightphi;": "\u03d5",
+  "strns;": "\xaf",
+  "sub;": "\u2282",
+  "subE;": "\u2ac5",
+  "subdot;": "\u2abd",
+  "sube;": "\u2286",
+  "subedot;": "\u2ac3",
+  "submult;": "\u2ac1",
+  "subnE;": "\u2acb",
+  "subne;": "\u228a",
+  "subplus;": "\u2abf",
+  "subrarr;": "\u2979",
+  "subset;": "\u2282",
+  "subseteq;": "\u2286",
+  "subseteqq;": "\u2ac5",
+  "subsetneq;": "\u228a",
+  "subsetneqq;": "\u2acb",
+  "subsim;": "\u2ac7",
+  "subsub;": "\u2ad5",
+  "subsup;": "\u2ad3",
+  "succ;": "\u227b",
+  "succapprox;": "\u2ab8",
+  "succcurlyeq;": "\u227d",
+  "succeq;": "\u2ab0",
+  "succnapprox;": "\u2aba",
+  "succneqq;": "\u2ab6",
+  "succnsim;": "\u22e9",
+  "succsim;": "\u227f",
+  "sum;": "\u2211",
+  "sung;": "\u266a",
+  "sup1": "\xb9",
+  "sup1;": "\xb9",
+  "sup2": "\xb2",
+  "sup2;": "\xb2",
+  "sup3": "\xb3",
+  "sup3;": "\xb3",
+  "sup;": "\u2283",
+  "supE;": "\u2ac6",
+  "supdot;": "\u2abe",
+  "supdsub;": "\u2ad8",
+  "supe;": "\u2287",
+  "supedot;": "\u2ac4",
+  "suphsol;": "\u27c9",
+  "suphsub;": "\u2ad7",
+  "suplarr;": "\u297b",
+  "supmult;": "\u2ac2",
+  "supnE;": "\u2acc",
+  "supne;": "\u228b",
+  "supplus;": "\u2ac0",
+  "supset;": "\u2283",
+  "supseteq;": "\u2287",
+  "supseteqq;": "\u2ac6",
+  "supsetneq;": "\u228b",
+  "supsetneqq;": "\u2acc",
+  "supsim;": "\u2ac8",
+  "supsub;": "\u2ad4",
+  "supsup;": "\u2ad6",
+  "swArr;": "\u21d9",
+  "swarhk;": "\u2926",
+  "swarr;": "\u2199",
+  "swarrow;": "\u2199",
+  "swnwar;": "\u292a",
+  "szlig": "\xdf",
+  "szlig;": "\xdf",
+  "target;": "\u2316",
+  "tau;": "\u03c4",
+  "tbrk;": "\u23b4",
+  "tcaron;": "\u0165",
+  "tcedil;": "\u0163",
+  "tcy;": "\u0442",
+  "tdot;": "\u20db",
+  "telrec;": "\u2315",
+  "tfr;": "\u{01d531}",
+  "there4;": "\u2234",
+  "therefore;": "\u2234",
+  "theta;": "\u03b8",
+  "thetasym;": "\u03d1",
+  "thetav;": "\u03d1",
+  "thickapprox;": "\u2248",
+  "thicksim;": "\u223c",
+  "thinsp;": "\u2009",
+  "thkap;": "\u2248",
+  "thksim;": "\u223c",
+  "thorn": "\xfe",
+  "thorn;": "\xfe",
+  "tilde;": "\u02dc",
+  "times": "\xd7",
+  "times;": "\xd7",
+  "timesb;": "\u22a0",
+  "timesbar;": "\u2a31",
+  "timesd;": "\u2a30",
+  "tint;": "\u222d",
+  "toea;": "\u2928",
+  "top;": "\u22a4",
+  "topbot;": "\u2336",
+  "topcir;": "\u2af1",
+  "topf;": "\u{01d565}",
+  "topfork;": "\u2ada",
+  "tosa;": "\u2929",
+  "tprime;": "\u2034",
+  "trade;": "\u2122",
+  "triangle;": "\u25b5",
+  "triangledown;": "\u25bf",
+  "triangleleft;": "\u25c3",
+  "trianglelefteq;": "\u22b4",
+  "triangleq;": "\u225c",
+  "triangleright;": "\u25b9",
+  "trianglerighteq;": "\u22b5",
+  "tridot;": "\u25ec",
+  "trie;": "\u225c",
+  "triminus;": "\u2a3a",
+  "triplus;": "\u2a39",
+  "trisb;": "\u29cd",
+  "tritime;": "\u2a3b",
+  "trpezium;": "\u23e2",
+  "tscr;": "\u{01d4c9}",
+  "tscy;": "\u0446",
+  "tshcy;": "\u045b",
+  "tstrok;": "\u0167",
+  "twixt;": "\u226c",
+  "twoheadleftarrow;": "\u219e",
+  "twoheadrightarrow;": "\u21a0",
+  "uArr;": "\u21d1",
+  "uHar;": "\u2963",
+  "uacute": "\xfa",
+  "uacute;": "\xfa",
+  "uarr;": "\u2191",
+  "ubrcy;": "\u045e",
+  "ubreve;": "\u016d",
+  "ucirc": "\xfb",
+  "ucirc;": "\xfb",
+  "ucy;": "\u0443",
+  "udarr;": "\u21c5",
+  "udblac;": "\u0171",
+  "udhar;": "\u296e",
+  "ufisht;": "\u297e",
+  "ufr;": "\u{01d532}",
+  "ugrave": "\xf9",
+  "ugrave;": "\xf9",
+  "uharl;": "\u21bf",
+  "uharr;": "\u21be",
+  "uhblk;": "\u2580",
+  "ulcorn;": "\u231c",
+  "ulcorner;": "\u231c",
+  "ulcrop;": "\u230f",
+  "ultri;": "\u25f8",
+  "umacr;": "\u016b",
+  "uml": "\xa8",
+  "uml;": "\xa8",
+  "uogon;": "\u0173",
+  "uopf;": "\u{01d566}",
+  "uparrow;": "\u2191",
+  "updownarrow;": "\u2195",
+  "upharpoonleft;": "\u21bf",
+  "upharpoonright;": "\u21be",
+  "uplus;": "\u228e",
+  "upsi;": "\u03c5",
+  "upsih;": "\u03d2",
+  "upsilon;": "\u03c5",
+  "upuparrows;": "\u21c8",
+  "urcorn;": "\u231d",
+  "urcorner;": "\u231d",
+  "urcrop;": "\u230e",
+  "uring;": "\u016f",
+  "urtri;": "\u25f9",
+  "uscr;": "\u{01d4ca}",
+  "utdot;": "\u22f0",
+  "utilde;": "\u0169",
+  "utri;": "\u25b5",
+  "utrif;": "\u25b4",
+  "uuarr;": "\u21c8",
+  "uuml": "\xfc",
+  "uuml;": "\xfc",
+  "uwangle;": "\u29a7",
+  "vArr;": "\u21d5",
+  "vBar;": "\u2ae8",
+  "vBarv;": "\u2ae9",
+  "vDash;": "\u22a8",
+  "vangrt;": "\u299c",
+  "varepsilon;": "\u03f5",
+  "varkappa;": "\u03f0",
+  "varnothing;": "\u2205",
+  "varphi;": "\u03d5",
+  "varpi;": "\u03d6",
+  "varpropto;": "\u221d",
+  "varr;": "\u2195",
+  "varrho;": "\u03f1",
+  "varsigma;": "\u03c2",
+  "varsubsetneq;": "\u228a\ufe00",
+  "varsubsetneqq;": "\u2acb\ufe00",
+  "varsupsetneq;": "\u228b\ufe00",
+  "varsupsetneqq;": "\u2acc\ufe00",
+  "vartheta;": "\u03d1",
+  "vartriangleleft;": "\u22b2",
+  "vartriangleright;": "\u22b3",
+  "vcy;": "\u0432",
+  "vdash;": "\u22a2",
+  "vee;": "\u2228",
+  "veebar;": "\u22bb",
+  "veeeq;": "\u225a",
+  "vellip;": "\u22ee",
+  "verbar;": "|",
+  "vert;": "|",
+  "vfr;": "\u{01d533}",
+  "vltri;": "\u22b2",
+  "vnsub;": "\u2282\u20d2",
+  "vnsup;": "\u2283\u20d2",
+  "vopf;": "\u{01d567}",
+  "vprop;": "\u221d",
+  "vrtri;": "\u22b3",
+  "vscr;": "\u{01d4cb}",
+  "vsubnE;": "\u2acb\ufe00",
+  "vsubne;": "\u228a\ufe00",
+  "vsupnE;": "\u2acc\ufe00",
+  "vsupne;": "\u228b\ufe00",
+  "vzigzag;": "\u299a",
+  "wcirc;": "\u0175",
+  "wedbar;": "\u2a5f",
+  "wedge;": "\u2227",
+  "wedgeq;": "\u2259",
+  "weierp;": "\u2118",
+  "wfr;": "\u{01d534}",
+  "wopf;": "\u{01d568}",
+  "wp;": "\u2118",
+  "wr;": "\u2240",
+  "wreath;": "\u2240",
+  "wscr;": "\u{01d4cc}",
+  "xcap;": "\u22c2",
+  "xcirc;": "\u25ef",
+  "xcup;": "\u22c3",
+  "xdtri;": "\u25bd",
+  "xfr;": "\u{01d535}",
+  "xhArr;": "\u27fa",
+  "xharr;": "\u27f7",
+  "xi;": "\u03be",
+  "xlArr;": "\u27f8",
+  "xlarr;": "\u27f5",
+  "xmap;": "\u27fc",
+  "xnis;": "\u22fb",
+  "xodot;": "\u2a00",
+  "xopf;": "\u{01d569}",
+  "xoplus;": "\u2a01",
+  "xotime;": "\u2a02",
+  "xrArr;": "\u27f9",
+  "xrarr;": "\u27f6",
+  "xscr;": "\u{01d4cd}",
+  "xsqcup;": "\u2a06",
+  "xuplus;": "\u2a04",
+  "xutri;": "\u25b3",
+  "xvee;": "\u22c1",
+  "xwedge;": "\u22c0",
+  "yacute": "\xfd",
+  "yacute;": "\xfd",
+  "yacy;": "\u044f",
+  "ycirc;": "\u0177",
+  "ycy;": "\u044b",
+  "yen": "\xa5",
+  "yen;": "\xa5",
+  "yfr;": "\u{01d536}",
+  "yicy;": "\u0457",
+  "yopf;": "\u{01d56a}",
+  "yscr;": "\u{01d4ce}",
+  "yucy;": "\u044e",
+  "yuml": "\xff",
+  "yuml;": "\xff",
+  "zacute;": "\u017a",
+  "zcaron;": "\u017e",
+  "zcy;": "\u0437",
+  "zdot;": "\u017c",
+  "zeetrf;": "\u2128",
+  "zeta;": "\u03b6",
+  "zfr;": "\u{01d537}",
+  "zhcy;": "\u0436",
+  "zigrarr;": "\u21dd",
+  "zopf;": "\u{01d56b}",
+  "zscr;": "\u{01d4cf}",
+  "zwj;": "\u200d",
+  "zwnj;": "\u200c",
+};
+
+const Map<int, String> replacementCharacters = const {
+  0x00: "\uFFFD",
+  0x0d: "\u000D",
+  0x80: "\u20AC",
+  0x81: "\u0081",
+  0x82: "\u201A",
+  0x83: "\u0192",
+  0x84: "\u201E",
+  0x85: "\u2026",
+  0x86: "\u2020",
+  0x87: "\u2021",
+  0x88: "\u02C6",
+  0x89: "\u2030",
+  0x8A: "\u0160",
+  0x8B: "\u2039",
+  0x8C: "\u0152",
+  0x8D: "\u008D",
+  0x8E: "\u017D",
+  0x8F: "\u008F",
+  0x90: "\u0090",
+  0x91: "\u2018",
+  0x92: "\u2019",
+  0x93: "\u201C",
+  0x94: "\u201D",
+  0x95: "\u2022",
+  0x96: "\u2013",
+  0x97: "\u2014",
+  0x98: "\u02DC",
+  0x99: "\u2122",
+  0x9A: "\u0161",
+  0x9B: "\u203A",
+  0x9C: "\u0153",
+  0x9D: "\u009D",
+  0x9E: "\u017E",
+  0x9F: "\u0178"
+};
+
+const Map<String, String> encodings = const {
+  '437': 'cp437',
+  '850': 'cp850',
+  '852': 'cp852',
+  '855': 'cp855',
+  '857': 'cp857',
+  '860': 'cp860',
+  '861': 'cp861',
+  '862': 'cp862',
+  '863': 'cp863',
+  '865': 'cp865',
+  '866': 'cp866',
+  '869': 'cp869',
+  'ansix341968': 'ascii',
+  'ansix341986': 'ascii',
+  'arabic': 'iso8859-6',
+  'ascii': 'ascii',
+  'asmo708': 'iso8859-6',
+  'big5': 'big5',
+  'big5hkscs': 'big5hkscs',
+  'chinese': 'gbk',
+  'cp037': 'cp037',
+  'cp1026': 'cp1026',
+  'cp154': 'ptcp154',
+  'cp367': 'ascii',
+  'cp424': 'cp424',
+  'cp437': 'cp437',
+  'cp500': 'cp500',
+  'cp775': 'cp775',
+  'cp819': 'windows-1252',
+  'cp850': 'cp850',
+  'cp852': 'cp852',
+  'cp855': 'cp855',
+  'cp857': 'cp857',
+  'cp860': 'cp860',
+  'cp861': 'cp861',
+  'cp862': 'cp862',
+  'cp863': 'cp863',
+  'cp864': 'cp864',
+  'cp865': 'cp865',
+  'cp866': 'cp866',
+  'cp869': 'cp869',
+  'cp936': 'gbk',
+  'cpgr': 'cp869',
+  'cpis': 'cp861',
+  'csascii': 'ascii',
+  'csbig5': 'big5',
+  'cseuckr': 'cp949',
+  'cseucpkdfmtjapanese': 'euc_jp',
+  'csgb2312': 'gbk',
+  'cshproman8': 'hp-roman8',
+  'csibm037': 'cp037',
+  'csibm1026': 'cp1026',
+  'csibm424': 'cp424',
+  'csibm500': 'cp500',
+  'csibm855': 'cp855',
+  'csibm857': 'cp857',
+  'csibm860': 'cp860',
+  'csibm861': 'cp861',
+  'csibm863': 'cp863',
+  'csibm864': 'cp864',
+  'csibm865': 'cp865',
+  'csibm866': 'cp866',
+  'csibm869': 'cp869',
+  'csiso2022jp': 'iso2022_jp',
+  'csiso2022jp2': 'iso2022_jp_2',
+  'csiso2022kr': 'iso2022_kr',
+  'csiso58gb231280': 'gbk',
+  'csisolatin1': 'windows-1252',
+  'csisolatin2': 'iso8859-2',
+  'csisolatin3': 'iso8859-3',
+  'csisolatin4': 'iso8859-4',
+  'csisolatin5': 'windows-1254',
+  'csisolatin6': 'iso8859-10',
+  'csisolatinarabic': 'iso8859-6',
+  'csisolatincyrillic': 'iso8859-5',
+  'csisolatingreek': 'iso8859-7',
+  'csisolatinhebrew': 'iso8859-8',
+  'cskoi8r': 'koi8-r',
+  'csksc56011987': 'cp949',
+  'cspc775baltic': 'cp775',
+  'cspc850multilingual': 'cp850',
+  'cspc862latinhebrew': 'cp862',
+  'cspc8codepage437': 'cp437',
+  'cspcp852': 'cp852',
+  'csptcp154': 'ptcp154',
+  'csshiftjis': 'shift_jis',
+  'csunicode11utf7': 'utf-7',
+  'cyrillic': 'iso8859-5',
+  'cyrillicasian': 'ptcp154',
+  'ebcdiccpbe': 'cp500',
+  'ebcdiccpca': 'cp037',
+  'ebcdiccpch': 'cp500',
+  'ebcdiccphe': 'cp424',
+  'ebcdiccpnl': 'cp037',
+  'ebcdiccpus': 'cp037',
+  'ebcdiccpwt': 'cp037',
+  'ecma114': 'iso8859-6',
+  'ecma118': 'iso8859-7',
+  'elot928': 'iso8859-7',
+  'eucjp': 'euc_jp',
+  'euckr': 'cp949',
+  'extendedunixcodepackedformatforjapanese': 'euc_jp',
+  'gb18030': 'gb18030',
+  'gb2312': 'gbk',
+  'gb231280': 'gbk',
+  'gbk': 'gbk',
+  'greek': 'iso8859-7',
+  'greek8': 'iso8859-7',
+  'hebrew': 'iso8859-8',
+  'hproman8': 'hp-roman8',
+  'hzgb2312': 'hz',
+  'ibm037': 'cp037',
+  'ibm1026': 'cp1026',
+  'ibm367': 'ascii',
+  'ibm424': 'cp424',
+  'ibm437': 'cp437',
+  'ibm500': 'cp500',
+  'ibm775': 'cp775',
+  'ibm819': 'windows-1252',
+  'ibm850': 'cp850',
+  'ibm852': 'cp852',
+  'ibm855': 'cp855',
+  'ibm857': 'cp857',
+  'ibm860': 'cp860',
+  'ibm861': 'cp861',
+  'ibm862': 'cp862',
+  'ibm863': 'cp863',
+  'ibm864': 'cp864',
+  'ibm865': 'cp865',
+  'ibm866': 'cp866',
+  'ibm869': 'cp869',
+  'iso2022jp': 'iso2022_jp',
+  'iso2022jp2': 'iso2022_jp_2',
+  'iso2022kr': 'iso2022_kr',
+  'iso646irv1991': 'ascii',
+  'iso646us': 'ascii',
+  'iso88591': 'windows-1252',
+  'iso885910': 'iso8859-10',
+  'iso8859101992': 'iso8859-10',
+  'iso885911987': 'windows-1252',
+  'iso885913': 'iso8859-13',
+  'iso885914': 'iso8859-14',
+  'iso8859141998': 'iso8859-14',
+  'iso885915': 'iso8859-15',
+  'iso885916': 'iso8859-16',
+  'iso8859162001': 'iso8859-16',
+  'iso88592': 'iso8859-2',
+  'iso885921987': 'iso8859-2',
+  'iso88593': 'iso8859-3',
+  'iso885931988': 'iso8859-3',
+  'iso88594': 'iso8859-4',
+  'iso885941988': 'iso8859-4',
+  'iso88595': 'iso8859-5',
+  'iso885951988': 'iso8859-5',
+  'iso88596': 'iso8859-6',
+  'iso885961987': 'iso8859-6',
+  'iso88597': 'iso8859-7',
+  'iso885971987': 'iso8859-7',
+  'iso88598': 'iso8859-8',
+  'iso885981988': 'iso8859-8',
+  'iso88599': 'windows-1254',
+  'iso885991989': 'windows-1254',
+  'isoceltic': 'iso8859-14',
+  'isoir100': 'windows-1252',
+  'isoir101': 'iso8859-2',
+  'isoir109': 'iso8859-3',
+  'isoir110': 'iso8859-4',
+  'isoir126': 'iso8859-7',
+  'isoir127': 'iso8859-6',
+  'isoir138': 'iso8859-8',
+  'isoir144': 'iso8859-5',
+  'isoir148': 'windows-1254',
+  'isoir149': 'cp949',
+  'isoir157': 'iso8859-10',
+  'isoir199': 'iso8859-14',
+  'isoir226': 'iso8859-16',
+  'isoir58': 'gbk',
+  'isoir6': 'ascii',
+  'koi8r': 'koi8-r',
+  'koi8u': 'koi8-u',
+  'korean': 'cp949',
+  'ksc5601': 'cp949',
+  'ksc56011987': 'cp949',
+  'ksc56011989': 'cp949',
+  'l1': 'windows-1252',
+  'l10': 'iso8859-16',
+  'l2': 'iso8859-2',
+  'l3': 'iso8859-3',
+  'l4': 'iso8859-4',
+  'l5': 'windows-1254',
+  'l6': 'iso8859-10',
+  'l8': 'iso8859-14',
+  'latin1': 'windows-1252',
+  'latin10': 'iso8859-16',
+  'latin2': 'iso8859-2',
+  'latin3': 'iso8859-3',
+  'latin4': 'iso8859-4',
+  'latin5': 'windows-1254',
+  'latin6': 'iso8859-10',
+  'latin8': 'iso8859-14',
+  'latin9': 'iso8859-15',
+  'ms936': 'gbk',
+  'mskanji': 'shift_jis',
+  'pt154': 'ptcp154',
+  'ptcp154': 'ptcp154',
+  'r8': 'hp-roman8',
+  'roman8': 'hp-roman8',
+  'shiftjis': 'shift_jis',
+  'tis620': 'cp874',
+  'unicode11utf7': 'utf-7',
+  'us': 'ascii',
+  'usascii': 'ascii',
+  'utf16': 'utf-16',
+  'utf16be': 'utf-16-be',
+  'utf16le': 'utf-16-le',
+  'utf8': 'utf-8',
+  'windows1250': 'cp1250',
+  'windows1251': 'cp1251',
+  'windows1252': 'cp1252',
+  'windows1253': 'cp1253',
+  'windows1254': 'cp1254',
+  'windows1255': 'cp1255',
+  'windows1256': 'cp1256',
+  'windows1257': 'cp1257',
+  'windows1258': 'cp1258',
+  'windows936': 'gbk',
+  'x-x-big5': 'big5'
+};
diff --git a/html/lib/src/css_class_set.dart b/html/lib/src/css_class_set.dart
new file mode 100644
index 0000000..ddc1612
--- /dev/null
+++ b/html/lib/src/css_class_set.dart
@@ -0,0 +1,330 @@
+// Copyright (c) 2014, 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.
+
+// TODO(jmesserly): everything in this file is copied straight from "dart:html".
+library html.dom.src;
+
+import 'dart:collection';
+import 'package:html/dom.dart';
+
+class ElementCssClassSet extends CssClassSetImpl {
+  final Element _element;
+
+  ElementCssClassSet(this._element);
+
+  Set<String> readClasses() {
+    var s = new LinkedHashSet<String>();
+    var classname = _element.className;
+
+    for (String name in classname.split(' ')) {
+      String trimmed = name.trim();
+      if (!trimmed.isEmpty) {
+        s.add(trimmed);
+      }
+    }
+    return s;
+  }
+
+  void writeClasses(Set<String> s) {
+    _element.className = s.join(' ');
+  }
+}
+
+/** A Set that stores the CSS class names for an element. */
+abstract class CssClassSet implements Set<String> {
+
+  /**
+   * Adds the class [value] to the element if it is not on it, removes it if it
+   * is.
+   *
+   * If [shouldAdd] is true, then we always add that [value] to the element. If
+   * [shouldAdd] is false then we always remove [value] from the element.
+   */
+  bool toggle(String value, [bool shouldAdd]);
+
+  /**
+   * Returns [:true:] if classes cannot be added or removed from this
+   * [:CssClassSet:].
+   */
+  bool get frozen;
+
+  /**
+   * Determine if this element contains the class [value].
+   *
+   * This is the Dart equivalent of jQuery's
+   * [hasClass](http://api.jquery.com/hasClass/).
+   */
+  bool contains(Object value);
+
+  /**
+   * Add the class [value] to element.
+   *
+   * This is the Dart equivalent of jQuery's
+   * [addClass](http://api.jquery.com/addClass/).
+   *
+   * If this corresponds to one element. Returns true if [value] was added to
+   * the set, otherwise false.
+   *
+   * If this corresponds to many elements, null is always returned.
+   */
+  bool add(String value);
+
+  /**
+   * Remove the class [value] from element, and return true on successful
+   * removal.
+   *
+   * This is the Dart equivalent of jQuery's
+   * [removeClass](http://api.jquery.com/removeClass/).
+   */
+  bool remove(Object value);
+
+  /**
+   * Add all classes specified in [iterable] to element.
+   *
+   * This is the Dart equivalent of jQuery's
+   * [addClass](http://api.jquery.com/addClass/).
+   */
+  void addAll(Iterable<String> iterable);
+
+  /**
+   * Remove all classes specified in [iterable] from element.
+   *
+   * This is the Dart equivalent of jQuery's
+   * [removeClass](http://api.jquery.com/removeClass/).
+   */
+  void removeAll(Iterable<Object> iterable);
+
+  /**
+   * Toggles all classes specified in [iterable] on element.
+   *
+   * Iterate through [iterable]'s items, and add it if it is not on it, or
+   * remove it if it is. This is the Dart equivalent of jQuery's
+   * [toggleClass](http://api.jquery.com/toggleClass/).
+   * If [shouldAdd] is true, then we always add all the classes in [iterable]
+   * element. If [shouldAdd] is false then we always remove all the classes in
+   * [iterable] from the element.
+   */
+  void toggleAll(Iterable<String> iterable, [bool shouldAdd]);
+}
+
+abstract class CssClassSetImpl implements CssClassSet {
+  String toString() {
+    return readClasses().join(' ');
+  }
+
+  /**
+   * Adds the class [value] to the element if it is not on it, removes it if it
+   * is.
+   *
+   * If [shouldAdd] is true, then we always add that [value] to the element. If
+   * [shouldAdd] is false then we always remove [value] from the element.
+   */
+  bool toggle(String value, [bool shouldAdd]) {
+    Set<String> s = readClasses();
+    bool result = false;
+    if (shouldAdd == null) shouldAdd = !s.contains(value);
+    if (shouldAdd) {
+      s.add(value);
+      result = true;
+    } else {
+      s.remove(value);
+    }
+    writeClasses(s);
+    return result;
+  }
+
+  /**
+   * Returns [:true:] if classes cannot be added or removed from this
+   * [:CssClassSet:].
+   */
+  bool get frozen => false;
+
+  // interface Iterable - BEGIN
+  Iterator<String> get iterator => readClasses().iterator;
+  // interface Iterable - END
+
+  // interface Collection - BEGIN
+  void forEach(void f(String element)) {
+    readClasses().forEach(f);
+  }
+
+  String join([String separator = ""]) => readClasses().join(separator);
+
+  Iterable/*<T>*/ map/*<T>*/(/*=T*/ f(String e)) => readClasses().map(f);
+
+  Iterable<String> where(bool f(String element)) => readClasses().where(f);
+
+  Iterable/*<T>*/ expand/*<T>*/(Iterable/*<T>*/ f(String element)) => readClasses().expand(f);
+
+  bool every(bool f(String element)) => readClasses().every(f);
+
+  bool any(bool f(String element)) => readClasses().any(f);
+
+  bool get isEmpty => readClasses().isEmpty;
+
+  bool get isNotEmpty => readClasses().isNotEmpty;
+
+  int get length => readClasses().length;
+
+  String reduce(String combine(String value, String element)) {
+    return readClasses().reduce(combine);
+  }
+
+  dynamic/*=T*/ fold/*<T>*/(var/*=T*/ initialValue,
+      dynamic/*=T*/ combine(var/*=T*/ previousValue, String element)) {
+    return readClasses().fold(initialValue, combine);
+  }
+  // interface Collection - END
+
+  // interface Set - BEGIN
+  /**
+   * Determine if this element contains the class [value].
+   *
+   * This is the Dart equivalent of jQuery's
+   * [hasClass](http://api.jquery.com/hasClass/).
+   */
+  bool contains(Object value) => readClasses().contains(value);
+
+  /** Lookup from the Set interface. Not interesting for a String set. */
+  String lookup(Object value) => contains(value) ? value as String : null;
+
+  /**
+   * Add the class [value] to element.
+   *
+   * This is the Dart equivalent of jQuery's
+   * [addClass](http://api.jquery.com/addClass/).
+   */
+  bool add(String value) {
+    // TODO - figure out if we need to do any validation here
+    // or if the browser natively does enough.
+    return modify((s) => s.add(value));
+  }
+
+  /**
+   * Remove the class [value] from element, and return true on successful
+   * removal.
+   *
+   * This is the Dart equivalent of jQuery's
+   * [removeClass](http://api.jquery.com/removeClass/).
+   */
+  bool remove(Object value) {
+    if (value is! String) return false;
+    Set<String> s = readClasses();
+    bool result = s.remove(value);
+    writeClasses(s);
+    return result;
+  }
+
+  /**
+   * Add all classes specified in [iterable] to element.
+   *
+   * This is the Dart equivalent of jQuery's
+   * [addClass](http://api.jquery.com/addClass/).
+   */
+  void addAll(Iterable<String> iterable) {
+    // TODO - see comment above about validation.
+    modify((s) => s.addAll(iterable));
+  }
+
+  /**
+   * Remove all classes specified in [iterable] from element.
+   *
+   * This is the Dart equivalent of jQuery's
+   * [removeClass](http://api.jquery.com/removeClass/).
+   */
+  void removeAll(Iterable<Object> iterable) {
+    modify((s) => s.removeAll(iterable));
+  }
+
+  /**
+   * Toggles all classes specified in [iterable] on element.
+   *
+   * Iterate through [iterable]'s items, and add it if it is not on it, or
+   * remove it if it is. This is the Dart equivalent of jQuery's
+   * [toggleClass](http://api.jquery.com/toggleClass/).
+   * If [shouldAdd] is true, then we always add all the classes in [iterable]
+   * element. If [shouldAdd] is false then we always remove all the classes in
+   * [iterable] from the element.
+   */
+  void toggleAll(Iterable<String> iterable, [bool shouldAdd]) {
+    iterable.forEach((e) => toggle(e, shouldAdd));
+  }
+
+  void retainAll(Iterable<Object> iterable) {
+    modify((s) => s.retainAll(iterable));
+  }
+
+  void removeWhere(bool test(String name)) {
+    modify((s) => s.removeWhere(test));
+  }
+
+  void retainWhere(bool test(String name)) {
+    modify((s) => s.retainWhere(test));
+  }
+
+  bool containsAll(Iterable<Object> collection) =>
+      readClasses().containsAll(collection);
+
+  Set<String> intersection(Set<Object> other) =>
+      readClasses().intersection(other);
+
+  Set<String> union(Set<String> other) => readClasses().union(other);
+
+  Set<String> difference(Set<Object> other) => readClasses().difference(other);
+
+  String get first => readClasses().first;
+  String get last => readClasses().last;
+  String get single => readClasses().single;
+  List<String> toList({bool growable: true}) =>
+      readClasses().toList(growable: growable);
+  Set<String> toSet() => readClasses().toSet();
+  Iterable<String> take(int n) => readClasses().take(n);
+  Iterable<String> takeWhile(bool test(String value)) =>
+      readClasses().takeWhile(test);
+  Iterable<String> skip(int n) => readClasses().skip(n);
+  Iterable<String> skipWhile(bool test(String value)) =>
+      readClasses().skipWhile(test);
+  String firstWhere(bool test(String value), {String orElse()}) =>
+      readClasses().firstWhere(test, orElse: orElse);
+  String lastWhere(bool test(String value), {String orElse()}) =>
+      readClasses().lastWhere(test, orElse: orElse);
+  String singleWhere(bool test(String value)) =>
+      readClasses().singleWhere(test);
+  String elementAt(int index) => readClasses().elementAt(index);
+
+  void clear() {
+    modify((s) => s.clear());
+  }
+  // interface Set - END
+
+  /**
+   * Helper method used to modify the set of css classes on this element.
+   *
+   *   f - callback with:
+   *   s - a Set of all the css class name currently on this element.
+   *
+   *   After f returns, the modified set is written to the
+   *       className property of this element.
+   */
+  modify(f(Set<String> s)) {
+    Set<String> s = readClasses();
+    var ret = f(s);
+    writeClasses(s);
+    return ret;
+  }
+
+  /**
+   * Read the class names from the Element class property,
+   * and put them into a set (duplicates are discarded).
+   * This is intended to be overridden by specific implementations.
+   */
+  Set<String> readClasses();
+
+  /**
+   * Join all the elements of a set into one string and write
+   * back to the element.
+   * This is intended to be overridden by specific implementations.
+   */
+  void writeClasses(Set<String> s);
+}
diff --git a/html/lib/src/encoding_parser.dart b/html/lib/src/encoding_parser.dart
new file mode 100644
index 0000000..9da260b
--- /dev/null
+++ b/html/lib/src/encoding_parser.dart
@@ -0,0 +1,376 @@
+library encoding_parser;
+
+import 'constants.dart';
+import 'inputstream.dart';
+
+// TODO(jmesserly): I converted StopIteration to StateError("No more elements").
+// Seems strange to throw this from outside of an iterator though.
+/// String-like object with an associated position and various extra methods
+/// If the position is ever greater than the string length then an exception is
+/// raised.
+class EncodingBytes {
+  final String _bytes;
+  int _position = -1;
+
+  EncodingBytes(this._bytes);
+
+  int get length => _bytes.length;
+
+  String next() {
+    var p = _position = _position + 1;
+    if (p >= length) {
+      throw new StateError("No more elements");
+    } else if (p < 0) {
+      throw new RangeError(p);
+    }
+    return _bytes[p];
+  }
+
+  String previous() {
+    var p = _position;
+    if (p >= length) {
+      throw new StateError("No more elements");
+    } else if (p < 0) {
+      throw new RangeError(p);
+    }
+    _position = p = p - 1;
+    return _bytes[p];
+  }
+
+  set position(int value) {
+    if (_position >= length) {
+      throw new StateError("No more elements");
+    }
+    _position = value;
+  }
+
+  int get position {
+    if (_position >= length) {
+      throw new StateError("No more elements");
+    }
+    if (_position >= 0) {
+      return _position;
+    } else {
+      return 0;
+    }
+  }
+
+  String get currentByte => _bytes[position];
+
+  /// Skip past a list of characters. Defaults to skipping [isWhitespace].
+  String skipChars([CharPreciate skipChars]) {
+    if (skipChars == null) skipChars = isWhitespace;
+    var p = position; // use property for the error-checking
+    while (p < length) {
+      var c = _bytes[p];
+      if (!skipChars(c)) {
+        _position = p;
+        return c;
+      }
+      p += 1;
+    }
+    _position = p;
+    return null;
+  }
+
+  String skipUntil(CharPreciate untilChars) {
+    var p = position;
+    while (p < length) {
+      var c = _bytes[p];
+      if (untilChars(c)) {
+        _position = p;
+        return c;
+      }
+      p += 1;
+    }
+    return null;
+  }
+
+  /// Look for a sequence of bytes at the start of a string. If the bytes
+  /// are found return true and advance the position to the byte after the
+  /// match. Otherwise return false and leave the position alone.
+  bool matchBytes(String bytes) {
+    var p = position;
+    if (_bytes.length < p + bytes.length) {
+      return false;
+    }
+    var data = _bytes.substring(p, p + bytes.length);
+    if (data == bytes) {
+      position += bytes.length;
+      return true;
+    }
+    return false;
+  }
+
+  /// Look for the next sequence of bytes matching a given sequence. If
+  /// a match is found advance the position to the last byte of the match
+  bool jumpTo(String bytes) {
+    var newPosition = _bytes.indexOf(bytes, position);
+    if (newPosition >= 0) {
+      _position = newPosition + bytes.length - 1;
+      return true;
+    } else {
+      throw new StateError("No more elements");
+    }
+  }
+
+  String slice(int start, [int end]) {
+    if (end == null) end = length;
+    if (end < 0) end += length;
+    return _bytes.substring(start, end - start);
+  }
+}
+
+typedef bool _MethodHandler();
+
+class _DispatchEntry {
+  final String pattern;
+  final _MethodHandler handler;
+  _DispatchEntry(this.pattern, this.handler);
+}
+
+/// Mini parser for detecting character encoding from meta elements.
+class EncodingParser {
+  final EncodingBytes data;
+  String encoding;
+
+  /// [bytes] - the data to work on for encoding detection.
+  EncodingParser(List<int> bytes)
+      // Note: this is intentionally interpreting bytes as codepoints.
+      : data = new EncodingBytes(new String.fromCharCodes(bytes).toLowerCase());
+
+  String getEncoding() {
+    final methodDispatch = [
+        new _DispatchEntry("<!--", handleComment),
+        new _DispatchEntry("<meta", handleMeta),
+        new _DispatchEntry("</", handlePossibleEndTag),
+        new _DispatchEntry("<!", handleOther),
+        new _DispatchEntry("<?", handleOther),
+        new _DispatchEntry("<", handlePossibleStartTag),
+    ];
+
+    try {
+      for (;;) {
+        for (var dispatch in methodDispatch) {
+          if (data.matchBytes(dispatch.pattern)) {
+            var keepParsing = dispatch.handler();
+            if (keepParsing) break;
+
+            // We found an encoding. Stop.
+            return encoding;
+          }
+        }
+        data.position += 1;
+      }
+    } on StateError catch (_) {
+      // Catch this here to match behavior of Python's StopIteration
+      // TODO(jmesserly): refactor to not use exceptions
+    }
+    return encoding;
+  }
+
+  /// Skip over comments.
+  bool handleComment() => data.jumpTo("-->");
+
+  bool handleMeta() {
+    if (!isWhitespace(data.currentByte)) {
+      // if we have <meta not followed by a space so just keep going
+      return true;
+    }
+    // We have a valid meta element we want to search for attributes
+    while (true) {
+      // Try to find the next attribute after the current position
+      var attr = getAttribute();
+      if (attr == null) return true;
+
+      if (attr[0] == "charset") {
+        var tentativeEncoding = attr[1];
+        var codec = codecName(tentativeEncoding);
+        if (codec != null) {
+          encoding = codec;
+          return false;
+        }
+      } else if (attr[0] == "content") {
+        var contentParser = new ContentAttrParser(new EncodingBytes(attr[1]));
+        var tentativeEncoding = contentParser.parse();
+        var codec = codecName(tentativeEncoding);
+        if (codec != null) {
+          encoding = codec;
+          return false;
+        }
+      }
+    }
+  }
+
+  bool handlePossibleStartTag() => handlePossibleTag(false);
+
+  bool handlePossibleEndTag() {
+    data.next();
+    return handlePossibleTag(true);
+  }
+
+  bool handlePossibleTag(bool endTag) {
+    if (!isLetter(data.currentByte)) {
+      //If the next byte is not an ascii letter either ignore this
+      //fragment (possible start tag case) or treat it according to
+      //handleOther
+      if (endTag) {
+        data.previous();
+        handleOther();
+      }
+      return true;
+    }
+
+    var c = data.skipUntil(isSpaceOrAngleBracket);
+    if (c == "<") {
+      // return to the first step in the overall "two step" algorithm
+      // reprocessing the < byte
+      data.previous();
+    } else {
+      //Read all attributes
+      var attr = getAttribute();
+      while (attr != null) {
+        attr = getAttribute();
+      }
+    }
+    return true;
+  }
+
+  bool handleOther() => data.jumpTo(">");
+
+  /// Return a name,value pair for the next attribute in the stream,
+  /// if one is found, or null
+  List<String> getAttribute() {
+    // Step 1 (skip chars)
+    var c = data.skipChars((x) => x == "/" || isWhitespace(x));
+    // Step 2
+    if (c == ">" || c == null) {
+      return null;
+    }
+    // Step 3
+    var attrName = [];
+    var attrValue = [];
+    // Step 4 attribute name
+    while (true) {
+      if (c == null) {
+        return null;
+      } else if (c == "=" && attrName.length > 0) {
+        break;
+      } else if (isWhitespace(c)) {
+        // Step 6!
+        c = data.skipChars();
+        c = data.next();
+        break;
+      } else if (c == "/" || c == ">") {
+        return [attrName.join(), ""];
+      } else if (isLetter(c)) {
+        attrName.add(c.toLowerCase());
+      } else {
+        attrName.add(c);
+      }
+      // Step 5
+      c = data.next();
+    }
+    // Step 7
+    if (c != "=") {
+      data.previous();
+      return [attrName.join(), ""];
+    }
+    // Step 8
+    data.next();
+    // Step 9
+    c = data.skipChars();
+    // Step 10
+    if (c == "'" || c == '"') {
+      // 10.1
+      var quoteChar = c;
+      while (true) {
+        // 10.2
+        c = data.next();
+        if (c == quoteChar) {
+          // 10.3
+          data.next();
+          return [attrName.join(), attrValue.join()];
+        } else if (isLetter(c)) {
+          // 10.4
+          attrValue.add(c.toLowerCase());
+        } else {
+          // 10.5
+          attrValue.add(c);
+        }
+      }
+    } else if (c == ">") {
+      return [attrName.join(), ""];
+    } else if (c == null) {
+      return null;
+    } else if (isLetter(c)) {
+      attrValue.add(c.toLowerCase());
+    } else {
+      attrValue.add(c);
+    }
+    // Step 11
+    while (true) {
+      c = data.next();
+      if (isSpaceOrAngleBracket(c)) {
+        return [attrName.join(), attrValue.join()];
+      } else if (c == null) {
+        return null;
+      } else if (isLetter(c)) {
+        attrValue.add(c.toLowerCase());
+      } else {
+        attrValue.add(c);
+      }
+    }
+  }
+}
+
+class ContentAttrParser {
+  final EncodingBytes data;
+
+  ContentAttrParser(this.data);
+
+  String parse() {
+    try {
+      // Check if the attr name is charset
+      // otherwise return
+      data.jumpTo("charset");
+      data.position += 1;
+      data.skipChars();
+      if (data.currentByte != "=") {
+        // If there is no = sign keep looking for attrs
+        return null;
+      }
+      data.position += 1;
+      data.skipChars();
+      // Look for an encoding between matching quote marks
+      if (data.currentByte == '"' || data.currentByte == "'") {
+        var quoteMark = data.currentByte;
+        data.position += 1;
+        var oldPosition = data.position;
+        if (data.jumpTo(quoteMark)) {
+          return data.slice(oldPosition, data.position);
+        } else {
+          return null;
+        }
+      } else {
+        // Unquoted value
+        var oldPosition = data.position;
+        try {
+          data.skipUntil(isWhitespace);
+          return data.slice(oldPosition, data.position);
+        } on StateError catch (_) {
+          //Return the whole remaining value
+          return data.slice(oldPosition);
+        }
+      }
+    } on StateError catch (_) {
+      return null;
+    }
+  }
+}
+
+bool isSpaceOrAngleBracket(String char) {
+  return char == ">" || char == "<" || isWhitespace(char);
+}
+
+typedef bool CharPreciate(String char);
diff --git a/html/lib/src/inputstream.dart b/html/lib/src/inputstream.dart
new file mode 100644
index 0000000..cb40bc9
--- /dev/null
+++ b/html/lib/src/inputstream.dart
@@ -0,0 +1,318 @@
+library inputstream;
+
+import 'dart:collection';
+import 'package:utf/utf.dart';
+import 'package:source_span/source_span.dart';
+import 'char_encodings.dart';
+import 'constants.dart';
+import 'utils.dart';
+import 'encoding_parser.dart';
+
+/// Hooks to call into dart:io without directly referencing it.
+class ConsoleSupport {
+  List<int> bytesFromFile(source) => null;
+}
+
+// TODO(jmesserly): use lazy init here when supported.
+ConsoleSupport consoleSupport = new ConsoleSupport();
+
+/// Provides a unicode stream of characters to the HtmlTokenizer.
+///
+/// This class takes care of character encoding and removing or replacing
+/// incorrect byte-sequences and also provides column and line tracking.
+class HtmlInputStream {
+  /// Number of bytes to use when looking for a meta element with
+  /// encoding information.
+  static const int numBytesMeta = 512;
+
+  /// Encoding to use if no other information can be found.
+  static const String defaultEncoding = 'windows-1252';
+
+  /// The name of the character encoding.
+  String charEncodingName;
+
+  /// True if we are certain about [charEncodingName], false for tenative.
+  bool charEncodingCertain = true;
+
+  final bool generateSpans;
+
+  /// Location where the contents of the stream were found.
+  final String sourceUrl;
+
+  List<int> _rawBytes;
+
+  /// Raw UTF-16 codes, used if a Dart String is passed in.
+  Iterable<int> _rawChars;
+
+  Queue<String> errors;
+
+  SourceFile fileInfo;
+
+  List<int> _lineStarts;
+
+  List<int> _chars;
+
+  int _offset;
+
+  /// Initialises the HtmlInputStream.
+  ///
+  /// HtmlInputStream(source, [encoding]) -> Normalized stream from source
+  /// for use by html5lib.
+  ///
+  /// [source] can be either a [String] or a [List<int>] containing the raw
+  /// bytes, or a file if [consoleSupport] is initialized.
+  ///
+  /// The optional encoding parameter must be a string that indicates
+  /// the encoding.  If specified, that encoding will be used,
+  /// regardless of any BOM or later declaration (such as in a meta
+  /// element)
+  ///
+  /// [parseMeta] - Look for a <meta> element containing encoding information
+  HtmlInputStream(source, [String encoding, bool parseMeta = true,
+      this.generateSpans = false, this.sourceUrl])
+      : charEncodingName = codecName(encoding) {
+    if (source is String) {
+      _rawChars = toCodepoints(source);
+      charEncodingName = 'utf-8';
+      charEncodingCertain = true;
+    } else if (source is List<int>) {
+      _rawBytes = source;
+    } else {
+      // TODO(jmesserly): it's unfortunate we need to read all bytes in advance,
+      // but it's necessary because of how the UTF decoders work.
+      _rawBytes = consoleSupport.bytesFromFile(source);
+
+      if (_rawBytes == null) {
+        // TODO(jmesserly): we should accept some kind of stream API too.
+        // Unfortunately dart:io InputStream is async only, which won't work.
+        throw new ArgumentError("'source' must be a String or "
+            "List<int> (of bytes). You can also pass a RandomAccessFile if you"
+            "`import 'package:html/parser_console.dart'` and call "
+            "`useConsole()`.");
+      }
+    }
+
+    // Detect encoding iff no explicit "transport level" encoding is supplied
+    if (charEncodingName == null) {
+      detectEncoding(parseMeta);
+    }
+
+    reset();
+  }
+
+  void reset() {
+    errors = new Queue<String>();
+
+    _offset = 0;
+    _lineStarts = <int>[0];
+    _chars = <int>[];
+
+    if (_rawChars == null) {
+      _rawChars = decodeBytes(charEncodingName, _rawBytes);
+    }
+
+    bool skipNewline = false;
+    for (var c in _rawChars) {
+      if (skipNewline) {
+        skipNewline = false;
+        if (c == NEWLINE) continue;
+      }
+
+      if (invalidUnicode(c)) errors.add('invalid-codepoint');
+
+      if (0xD800 <= c && c <= 0xDFFF) {
+        c = 0xFFFD;
+      } else if (c == RETURN) {
+        skipNewline = true;
+        c = NEWLINE;
+      }
+
+      _chars.add(c);
+      if (c == NEWLINE) _lineStarts.add(_chars.length);
+    }
+
+    // Free decoded characters if they aren't needed anymore.
+    if (_rawBytes != null) _rawChars = null;
+
+    // TODO(sigmund): Don't parse the file at all if spans aren't being
+    // generated.
+    fileInfo = new SourceFile.decoded(_chars, url: sourceUrl);
+  }
+
+  void detectEncoding([bool parseMeta = true]) {
+    // First look for a BOM
+    // This will also read past the BOM if present
+    charEncodingName = detectBOM();
+    charEncodingCertain = true;
+
+    // If there is no BOM need to look for meta elements with encoding
+    // information
+    if (charEncodingName == null && parseMeta) {
+      charEncodingName = detectEncodingMeta();
+      charEncodingCertain = false;
+    }
+    // If all else fails use the default encoding
+    if (charEncodingName == null) {
+      charEncodingCertain = false;
+      charEncodingName = defaultEncoding;
+    }
+
+    // Substitute for equivalent encodings:
+    if (charEncodingName.toLowerCase() == 'iso-8859-1') {
+      charEncodingName = 'windows-1252';
+    }
+  }
+
+  void changeEncoding(String newEncoding) {
+    if (_rawBytes == null) {
+      // We should never get here -- if encoding is certain we won't try to
+      // change it.
+      throw new StateError('cannot change encoding when parsing a String.');
+    }
+
+    newEncoding = codecName(newEncoding);
+    if (const ['utf-16', 'utf-16-be', 'utf-16-le'].contains(newEncoding)) {
+      newEncoding = 'utf-8';
+    }
+    if (newEncoding == null) {
+      return;
+    } else if (newEncoding == charEncodingName) {
+      charEncodingCertain = true;
+    } else {
+      charEncodingName = newEncoding;
+      charEncodingCertain = true;
+      _rawChars = null;
+      reset();
+      throw new ReparseException(
+          'Encoding changed from $charEncodingName to $newEncoding');
+    }
+  }
+
+  /// Attempts to detect at BOM at the start of the stream. If
+  /// an encoding can be determined from the BOM return the name of the
+  /// encoding otherwise return null.
+  String detectBOM() {
+    // Try detecting the BOM using bytes from the string
+    if (hasUtf8Bom(_rawBytes)) {
+      return 'utf-8';
+    }
+    // Note: we don't need to remember whether it was big or little endian
+    // because the decoder will do that later. It will also eat the BOM for us.
+    if (hasUtf16Bom(_rawBytes)) {
+      return 'utf-16';
+    }
+    if (hasUtf32Bom(_rawBytes)) {
+      return 'utf-32';
+    }
+    return null;
+  }
+
+  /// Report the encoding declared by the meta element.
+  String detectEncodingMeta() {
+    var parser = new EncodingParser(slice(_rawBytes, 0, numBytesMeta));
+    var encoding = parser.getEncoding();
+
+    if (const ['utf-16', 'utf-16-be', 'utf-16-le'].contains(encoding)) {
+      encoding = 'utf-8';
+    }
+
+    return encoding;
+  }
+
+  /// Returns the current offset in the stream, i.e. the number of codepoints
+  /// since the start of the file.
+  int get position => _offset;
+
+  /// Read one character from the stream or queue if available. Return
+  /// EOF when EOF is reached.
+  String char() {
+    if (_offset >= _chars.length) return EOF;
+    return new String.fromCharCodes([_chars[_offset++]]);
+  }
+
+  String peekChar() {
+    if (_offset >= _chars.length) return EOF;
+    return new String.fromCharCodes([_chars[_offset]]);
+  }
+
+  /// Returns a string of characters from the stream up to but not
+  /// including any character in 'characters' or EOF.
+  String charsUntil(String characters, [bool opposite = false]) {
+    int start = _offset;
+    String c;
+    while ((c = peekChar()) != null && characters.contains(c) == opposite) {
+      _offset++;
+    }
+
+    return new String.fromCharCodes(_chars.sublist(start, _offset));
+  }
+
+  void unget(String ch) {
+    // Only one character is allowed to be ungotten at once - it must
+    // be consumed again before any further call to unget
+    if (ch != null) {
+      _offset--;
+      assert(peekChar() == ch);
+    }
+  }
+}
+
+// TODO(jmesserly): the Python code used a regex to check for this. But
+// Dart doesn't let you create a regexp with invalid characters.
+bool invalidUnicode(int c) {
+  if (0x0001 <= c && c <= 0x0008) return true;
+  if (0x000E <= c && c <= 0x001F) return true;
+  if (0x007F <= c && c <= 0x009F) return true;
+  if (0xD800 <= c && c <= 0xDFFF) return true;
+  if (0xFDD0 <= c && c <= 0xFDEF) return true;
+  switch (c) {
+    case 0x000B:
+    case 0xFFFE:
+    case 0xFFFF:
+    case 0x01FFFE:
+    case 0x01FFFF:
+    case 0x02FFFE:
+    case 0x02FFFF:
+    case 0x03FFFE:
+    case 0x03FFFF:
+    case 0x04FFFE:
+    case 0x04FFFF:
+    case 0x05FFFE:
+    case 0x05FFFF:
+    case 0x06FFFE:
+    case 0x06FFFF:
+    case 0x07FFFE:
+    case 0x07FFFF:
+    case 0x08FFFE:
+    case 0x08FFFF:
+    case 0x09FFFE:
+    case 0x09FFFF:
+    case 0x0AFFFE:
+    case 0x0AFFFF:
+    case 0x0BFFFE:
+    case 0x0BFFFF:
+    case 0x0CFFFE:
+    case 0x0CFFFF:
+    case 0x0DFFFE:
+    case 0x0DFFFF:
+    case 0x0EFFFE:
+    case 0x0EFFFF:
+    case 0x0FFFFE:
+    case 0x0FFFFF:
+    case 0x10FFFE:
+    case 0x10FFFF:
+      return true;
+  }
+  return false;
+}
+
+/// Return the python codec name corresponding to an encoding or null if the
+/// string doesn't correspond to a valid encoding.
+String codecName(String encoding) {
+  final asciiPunctuation = new RegExp(
+      "[\u0009-\u000D\u0020-\u002F\u003A-\u0040\u005B-\u0060\u007B-\u007E]");
+
+  if (encoding == null) return null;
+  var canonicalName = encoding.replaceAll(asciiPunctuation, '').toLowerCase();
+  return encodings[canonicalName];
+}
diff --git a/html/lib/src/list_proxy.dart b/html/lib/src/list_proxy.dart
new file mode 100644
index 0000000..5df1ed4
--- /dev/null
+++ b/html/lib/src/list_proxy.dart
@@ -0,0 +1,108 @@
+// TODO(jmesserly): remove this once we have a subclassable growable list
+// in our libraries.
+
+/// A [List] proxy that you can subclass.
+library list_proxy;
+
+import 'dart:collection';
+import 'dart:math' show Random;
+
+// TOOD(jmesserly): this needs to be removed, but fixing NodeList is tricky.
+class ListProxy<E> extends IterableBase<E> implements List<E> {
+
+  /// The inner [List<T>] with the actual storage.
+  final List<E> _list;
+
+  /// Creates a list proxy.
+  /// You can optionally specify the list to use for [storage] of the items,
+  /// otherwise this will create a [List<E>].
+  ListProxy([List<E> storage]) : _list = storage != null ? storage : <E>[];
+
+  // TODO(jmesserly): This should be on List.
+  // See http://code.google.com/p/dart/issues/detail?id=947
+  bool remove(Object item) {
+    if (item is E) {
+      int i = indexOf(item);
+      if (i == -1) return false;
+      removeAt(i);
+      return true;
+    }
+    return false;
+  }
+
+  void insert(int index, E item) => _list.insert(index, item);
+
+  // Override from Iterable to fix performance
+  // Length and last become O(1) instead of O(N)
+  // The others are just different constant factor.
+  int get length => _list.length;
+  E get last => _list.last;
+  E get first => _list.first;
+  E get single => _list.single;
+
+  // From Iterable
+  Iterator<E> get iterator => _list.iterator;
+
+  // From List
+  E operator [](int index) => _list[index];
+  operator []=(int index, E value) {
+    _list[index] = value;
+  }
+  set length(int value) {
+    _list.length = value;
+  }
+  void add(E value) {
+    _list.add(value);
+  }
+
+  void addLast(E value) {
+    add(value);
+  }
+  void addAll(Iterable<E> collection) {
+    _list.addAll(collection);
+  }
+  void sort([int compare(E a, E b)]) {
+    _list.sort(compare);
+  }
+  void shuffle([Random random]) {
+    _list.shuffle(random);
+  }
+
+  int indexOf(E element, [int start = 0]) => _list.indexOf(element, start);
+  int lastIndexOf(E element, [int start]) => _list.lastIndexOf(element, start);
+  void clear() {
+    _list.clear();
+  }
+
+  E removeAt(int index) => _list.removeAt(index);
+  E removeLast() => _list.removeLast();
+
+  void removeWhere(bool test(E element)) => _list.removeWhere(test);
+  void retainWhere(bool test(E element)) => _list.retainWhere(test);
+
+  List<E> sublist(int start, [int end]) => _list.sublist(start, end);
+
+  List<E> getRange(int start, int end) => _list.getRange(start, end);
+
+  void setRange(int start, int length, Iterable<E> from, [int startFrom = 0]) {
+    _list.setRange(start, length, from, startFrom);
+  }
+  void removeRange(int start, int length) {
+    _list.removeRange(start, length);
+  }
+  void insertAll(int index, Iterable<E> iterable) {
+    _list.insertAll(index, iterable);
+  }
+
+  Iterable<E> get reversed => _list.reversed;
+
+  Map<int, E> asMap() => _list.asMap();
+
+  void replaceRange(int start, int end, Iterable<E> newContents) =>
+      _list.replaceRange(start, end, newContents);
+
+  void setAll(int index, Iterable<E> iterable) => _list.setAll(index, iterable);
+
+  void fillRange(int start, int end, [E fillValue]) =>
+      _list.fillRange(start, end, fillValue);
+}
diff --git a/html/lib/src/query_selector.dart b/html/lib/src/query_selector.dart
new file mode 100644
index 0000000..3aa45f2
--- /dev/null
+++ b/html/lib/src/query_selector.dart
@@ -0,0 +1,294 @@
+/// Query selector implementation for our DOM.
+library html.src.query;
+
+import 'package:csslib/parser.dart' as css;
+import 'package:csslib/parser.dart' show TokenKind;
+import 'package:csslib/src/messages.dart' show Message;
+import 'package:csslib/visitor.dart'; // the CSSOM
+import 'package:html/dom.dart';
+import 'package:html/src/constants.dart' show isWhitespaceCC;
+
+bool matches(Node node, String selector) =>
+    new SelectorEvaluator().matches(node, _parseSelectorList(selector));
+
+Element querySelector(Node node, String selector) =>
+    new SelectorEvaluator().querySelector(node, _parseSelectorList(selector));
+
+List<Element> querySelectorAll(Node node, String selector) {
+  var results = <Element>[];
+  new SelectorEvaluator().querySelectorAll(
+      node, _parseSelectorList(selector), results);
+  return results;
+}
+
+// http://dev.w3.org/csswg/selectors-4/#grouping
+SelectorGroup _parseSelectorList(String selector) {
+  var errors = <Message>[];
+  var group = css.parseSelectorGroup(selector, errors: errors);
+  if (group == null || errors.isNotEmpty) {
+    throw new FormatException("'$selector' is not a valid selector: $errors");
+  }
+  return group;
+}
+
+class SelectorEvaluator extends Visitor {
+  /// The current HTML element to match against.
+  Element _element;
+
+  bool matches(Element element, SelectorGroup selector) {
+    _element = element;
+    return visitSelectorGroup(selector);
+  }
+
+  Element querySelector(Node root, SelectorGroup selector) {
+    for (var node in root.nodes) {
+      if (node is! Element) continue;
+      if (matches(node, selector)) return node;
+      var result = querySelector(node, selector);
+      if (result != null) return result;
+    }
+    return null;
+  }
+
+  void querySelectorAll(
+      Node root, SelectorGroup selector, List<Element> results) {
+    for (var node in root.nodes) {
+      if (node is! Element) continue;
+      if (matches(node, selector)) results.add(node);
+      querySelectorAll(node, selector, results);
+    }
+  }
+
+  bool visitSelectorGroup(SelectorGroup group) =>
+      group.selectors.any(visitSelector);
+
+  bool visitSelector(Selector selector) {
+    var old = _element;
+    var result = true;
+
+    // Note: evaluate selectors right-to-left as it's more efficient.
+    int combinator = null;
+    for (var s in selector.simpleSelectorSequences.reversed) {
+      if (combinator == null) {
+        result = s.simpleSelector.visit(this);
+      } else if (combinator == TokenKind.COMBINATOR_DESCENDANT) {
+        // descendant combinator
+        // http://dev.w3.org/csswg/selectors-4/#descendant-combinators
+        do {
+          _element = _element.parent;
+        } while (_element != null && !s.simpleSelector.visit(this));
+
+        if (_element == null) result = false;
+      } else if (combinator == TokenKind.COMBINATOR_TILDE) {
+        // Following-sibling combinator
+        // http://dev.w3.org/csswg/selectors-4/#general-sibling-combinators
+        do {
+          _element = _element.previousElementSibling;
+        } while (_element != null && !s.simpleSelector.visit(this));
+
+        if (_element == null) result = false;
+      }
+
+      if (!result) break;
+
+      switch (s.combinator) {
+        case TokenKind.COMBINATOR_PLUS:
+          // Next-sibling combinator
+          // http://dev.w3.org/csswg/selectors-4/#adjacent-sibling-combinators
+          _element = _element.previousElementSibling;
+          break;
+        case TokenKind.COMBINATOR_GREATER:
+          // Child combinator
+          // http://dev.w3.org/csswg/selectors-4/#child-combinators
+          _element = _element.parent;
+          break;
+        case TokenKind.COMBINATOR_DESCENDANT:
+        case TokenKind.COMBINATOR_TILDE:
+          // We need to iterate through all siblings or parents.
+          // For now, just remember what the combinator was.
+          combinator = s.combinator;
+          break;
+        case TokenKind.COMBINATOR_NONE:
+          break;
+        default:
+          throw _unsupported(selector);
+      }
+
+      if (_element == null) {
+        result = false;
+        break;
+      }
+    }
+
+    _element = old;
+    return result;
+  }
+
+  _unimplemented(SimpleSelector selector) => new UnimplementedError(
+      "'$selector' selector of type "
+      "${selector.runtimeType} is not implemented");
+
+  _unsupported(selector) =>
+      new FormatException("'$selector' is not a valid selector");
+
+  bool visitPseudoClassSelector(PseudoClassSelector selector) {
+    switch (selector.name) {
+      // http://dev.w3.org/csswg/selectors-4/#structural-pseudos
+
+      // http://dev.w3.org/csswg/selectors-4/#the-root-pseudo
+      case 'root':
+        // TODO(jmesserly): fix when we have a .ownerDocument pointer
+        // return _element == _element.ownerDocument.rootElement;
+        return _element.localName == 'html' && _element.parentNode == null;
+
+      // http://dev.w3.org/csswg/selectors-4/#the-empty-pseudo
+      case 'empty':
+        return _element.nodes
+            .any((n) => !(n is Element || n is Text && n.text.isNotEmpty));
+
+      // http://dev.w3.org/csswg/selectors-4/#the-blank-pseudo
+      case 'blank':
+        return _element.nodes.any((n) => !(n is Element ||
+            n is Text && n.text.runes.any((r) => !isWhitespaceCC(r))));
+
+      // http://dev.w3.org/csswg/selectors-4/#the-first-child-pseudo
+      case 'first-child':
+        return _element.previousElementSibling == null;
+
+      // http://dev.w3.org/csswg/selectors-4/#the-last-child-pseudo
+      case 'last-child':
+        return _element.nextElementSibling == null;
+
+      // http://dev.w3.org/csswg/selectors-4/#the-only-child-pseudo
+      case 'only-child':
+        return _element.previousElementSibling == null &&
+            _element.nextElementSibling == null;
+
+      // http://dev.w3.org/csswg/selectors-4/#link
+      case 'link':
+        return _element.attributes['href'] != null;
+
+      case 'visited':
+        // Always return false since we aren't a browser. This is allowed per:
+        // http://dev.w3.org/csswg/selectors-4/#visited-pseudo
+        return false;
+    }
+
+    // :before, :after, :first-letter/line can't match DOM elements.
+    if (_isLegacyPsuedoClass(selector.name)) return false;
+
+    throw _unimplemented(selector);
+  }
+
+  bool visitPseudoElementSelector(PseudoElementSelector selector) {
+    // :before, :after, :first-letter/line can't match DOM elements.
+    if (_isLegacyPsuedoClass(selector.name)) return false;
+
+    throw _unimplemented(selector);
+  }
+
+  static bool _isLegacyPsuedoClass(String name) {
+    switch (name) {
+      case 'before':
+      case 'after':
+      case 'first-line':
+      case 'first-letter':
+        return true;
+      default:
+        return false;
+    }
+  }
+
+  bool visitPseudoElementFunctionSelector(PseudoElementFunctionSelector s) =>
+      throw _unimplemented(s);
+
+  bool visitPseudoClassFunctionSelector(PseudoClassFunctionSelector selector) {
+    switch (selector.name) {
+      // http://dev.w3.org/csswg/selectors-4/#child-index
+
+      // http://dev.w3.org/csswg/selectors-4/#the-nth-child-pseudo
+      case 'nth-child':
+        // TODO(jmesserly): support An+B syntax too.
+        var exprs = selector.expression.expressions;
+        if (exprs.length == 1 && exprs[0] is LiteralTerm) {
+          LiteralTerm literal = exprs[0];
+          var parent = _element.parentNode;
+          return parent != null &&
+              literal.value > 0 &&
+              parent.nodes.indexOf(_element) == literal.value;
+        }
+        break;
+
+      // http://dev.w3.org/csswg/selectors-4/#the-lang-pseudo
+      case 'lang':
+        // TODO(jmesserly): shouldn't need to get the raw text here, but csslib
+        // gets confused by the "-" in the expression, such as in "es-AR".
+        var toMatch = selector.expression.span.text;
+        var lang = _getInheritedLanguage(_element);
+        // TODO(jmesserly): implement wildcards in level 4
+        return lang != null && lang.startsWith(toMatch);
+    }
+    throw _unimplemented(selector);
+  }
+
+  static String _getInheritedLanguage(Node node) {
+    while (node != null) {
+      var lang = node.attributes['lang'];
+      if (lang != null) return lang;
+      node = node.parent;
+    }
+    return null;
+  }
+
+  bool visitNamespaceSelector(NamespaceSelector selector) {
+    // Match element tag name
+    if (!selector.nameAsSimpleSelector.visit(this)) return false;
+
+    if (selector.isNamespaceWildcard) return true;
+
+    if (selector.namespace == '') return _element.namespaceUri == null;
+
+    throw _unimplemented(selector);
+  }
+
+  bool visitElementSelector(ElementSelector selector) =>
+      selector.isWildcard || _element.localName == selector.name.toLowerCase();
+
+  bool visitIdSelector(IdSelector selector) => _element.id == selector.name;
+
+  bool visitClassSelector(ClassSelector selector) =>
+      _element.classes.contains(selector.name);
+
+  // TODO(jmesserly): negation should support any selectors in level 4,
+  // not just simple selectors.
+  // http://dev.w3.org/csswg/selectors-4/#negation
+  bool visitNegationSelector(NegationSelector selector) =>
+      !selector.negationArg.visit(this);
+
+  bool visitAttributeSelector(AttributeSelector selector) {
+    // Match name first
+    var value = _element.attributes[selector.name.toLowerCase()];
+    if (value == null) return false;
+
+    if (selector.operatorKind == TokenKind.NO_MATCH) return true;
+
+    var select = '${selector.value}';
+    switch (selector.operatorKind) {
+      case TokenKind.EQUALS:
+        return value == select;
+      case TokenKind.INCLUDES:
+        return value.split(' ').any((v) => v.isNotEmpty && v == select);
+      case TokenKind.DASH_MATCH:
+        return value.startsWith(select) &&
+            (value.length == select.length || value[select.length] == '-');
+      case TokenKind.PREFIX_MATCH:
+        return value.startsWith(select);
+      case TokenKind.SUFFIX_MATCH:
+        return value.endsWith(select);
+      case TokenKind.SUBSTRING_MATCH:
+        return value.contains(select);
+      default:
+        throw _unsupported(selector);
+    }
+  }
+}
diff --git a/html/lib/src/token.dart b/html/lib/src/token.dart
new file mode 100644
index 0000000..9a2843c
--- /dev/null
+++ b/html/lib/src/token.dart
@@ -0,0 +1,141 @@
+/// This library contains token types used by the html5 tokenizer.
+library token;
+
+import 'dart:collection';
+import 'package:source_span/source_span.dart';
+
+/// An html5 token.
+abstract class Token {
+  FileSpan span;
+
+  int get kind;
+}
+
+abstract class TagToken extends Token {
+  String name;
+
+  bool selfClosing;
+
+  TagToken(this.name, this.selfClosing);
+}
+
+class StartTagToken extends TagToken {
+  /// The tag's attributes. A map from the name to the value, where the name
+  /// can be a [String] or [AttributeName].
+  LinkedHashMap<dynamic, String> data;
+
+  /// The attribute spans if requested. Otherwise null.
+  List<TagAttribute> attributeSpans;
+
+  bool selfClosingAcknowledged;
+
+  /// The namespace. This is filled in later during tree building.
+  String namespace;
+
+  StartTagToken(String name, {this.data, bool selfClosing: false,
+      this.selfClosingAcknowledged: false, this.namespace})
+      : super(name, selfClosing);
+
+  int get kind => TokenKind.startTag;
+}
+
+class EndTagToken extends TagToken {
+  EndTagToken(String name, {bool selfClosing: false})
+      : super(name, selfClosing);
+
+  int get kind => TokenKind.endTag;
+}
+
+abstract class StringToken extends Token {
+  StringBuffer _buffer;
+
+  String _string;
+  String get data {
+    if (_string == null) {
+      _string = _buffer.toString();
+      _buffer = null;
+    }
+    return _string;
+  }
+
+  StringToken(string)
+      : _string = string,
+        _buffer = string == null ? new StringBuffer() : null;
+
+  StringToken add(String data) {
+    _buffer.write(data);
+    return this;
+  }
+}
+
+class ParseErrorToken extends StringToken {
+  /// Extra information that goes along with the error message.
+  Map messageParams;
+
+  ParseErrorToken(String data, {this.messageParams}) : super(data);
+
+  int get kind => TokenKind.parseError;
+}
+
+class CharactersToken extends StringToken {
+  CharactersToken([String data]) : super(data);
+
+  int get kind => TokenKind.characters;
+
+  /// Replaces the token's [data]. This should only be used to wholly replace
+  /// data, not to append data.
+  void replaceData(String newData) {
+    _string = newData;
+    _buffer = null;
+  }
+}
+
+class SpaceCharactersToken extends StringToken {
+  SpaceCharactersToken([String data]) : super(data);
+
+  int get kind => TokenKind.spaceCharacters;
+}
+
+class CommentToken extends StringToken {
+  CommentToken([String data]) : super(data);
+
+  int get kind => TokenKind.comment;
+}
+
+class DoctypeToken extends Token {
+  String publicId;
+  String systemId;
+  String name = "";
+  bool correct;
+
+  DoctypeToken({this.publicId, this.systemId, this.correct: false});
+
+  int get kind => TokenKind.doctype;
+}
+
+/// These are used by the tokenizer to build up the attribute map.
+/// They're also used by [StartTagToken.attributeSpans] if attribute spans are
+/// requested.
+class TagAttribute {
+  String name;
+  String value;
+
+  // The spans of the attribute. This is not used unless we are computing an
+  // attribute span on demand.
+  int start;
+  int end;
+  int startValue;
+  int endValue;
+
+  TagAttribute();
+}
+
+class TokenKind {
+  static const int spaceCharacters = 0;
+  static const int characters = 1;
+  static const int startTag = 2;
+  static const int endTag = 3;
+  static const int comment = 4;
+  static const int doctype = 5;
+  static const int parseError = 6;
+}
diff --git a/html/lib/src/tokenizer.dart b/html/lib/src/tokenizer.dart
new file mode 100644
index 0000000..68cb6dc
--- /dev/null
+++ b/html/lib/src/tokenizer.dart
@@ -0,0 +1,1908 @@
+library tokenizer;
+
+import 'dart:collection';
+import 'package:html/parser.dart' show HtmlParser;
+import 'constants.dart';
+import 'inputstream.dart';
+import 'token.dart';
+import 'utils.dart';
+
+// Group entities by their first character, for faster lookups
+
+// TODO(jmesserly): we could use a better data structure here like a trie, if
+// we had it implemented in Dart.
+Map<String, List<String>> entitiesByFirstChar = (() {
+  var result = <String, List<String>>{};
+  for (var k in entities.keys) {
+    result.putIfAbsent(k[0], () => []).add(k);
+  }
+  return result;
+})();
+
+// TODO(jmesserly): lots of ways to make this faster:
+// - use char codes everywhere instead of 1-char strings
+// - use switch instead of contains, indexOf
+// - use switch instead of the sequential if tests
+// - avoid string concat
+
+/// This class takes care of tokenizing HTML.
+class HtmlTokenizer implements Iterator<Token> {
+  // TODO(jmesserly): a lot of these could be made private
+
+  final HtmlInputStream stream;
+
+  final bool lowercaseElementName;
+
+  final bool lowercaseAttrName;
+
+  /// True to generate spans in for [Token.span].
+  final bool generateSpans;
+
+  /// True to generate spans for attributes.
+  final bool attributeSpans;
+
+  /// This reference to the parser is used for correct CDATA handling.
+  /// The [HtmlParser] will set this at construction time.
+  HtmlParser parser;
+
+  final Queue<Token> tokenQueue;
+
+  /// Holds the token that is currently being processed.
+  Token currentToken;
+
+  /// Holds a reference to the method to be invoked for the next parser state.
+  // TODO(jmesserly): the type should be "Predicate" but a dart2js checked mode
+  // bug prevents us from doing that. See http://dartbug.com/12465
+  Function state;
+
+  final StringBuffer _buffer = new StringBuffer();
+
+  int _lastOffset;
+
+  // TODO(jmesserly): ideally this would be a LinkedHashMap and we wouldn't add
+  // an item until it's ready. But the code doesn't have a clear notion of when
+  // it's "done" with the attribute.
+  List<TagAttribute> _attributes;
+  Set<String> _attributeNames;
+
+  HtmlTokenizer(doc, {String encoding, bool parseMeta: true,
+      this.lowercaseElementName: true, this.lowercaseAttrName: true,
+      bool generateSpans: false, String sourceUrl, this.attributeSpans: false})
+      : stream = new HtmlInputStream(
+          doc, encoding, parseMeta, generateSpans, sourceUrl),
+        tokenQueue = new Queue(),
+        generateSpans = generateSpans {
+    reset();
+  }
+
+  TagToken get currentTagToken => currentToken;
+  DoctypeToken get currentDoctypeToken => currentToken;
+  StringToken get currentStringToken => currentToken;
+
+  Token _current;
+  Token get current => _current;
+
+  final StringBuffer _attributeName = new StringBuffer();
+  final StringBuffer _attributeValue = new StringBuffer();
+
+  void _markAttributeEnd(int offset) {
+    _attributes.last.value = '$_attributeValue';
+    if (attributeSpans) _attributes.last.end = stream.position + offset;
+  }
+
+  void _markAttributeValueStart(int offset) {
+    if (attributeSpans) _attributes.last.startValue = stream.position + offset;
+  }
+
+  void _markAttributeValueEnd(int offset) {
+    if (attributeSpans) _attributes.last.endValue = stream.position + offset;
+    _markAttributeEnd(offset);
+  }
+
+  // Note: we could track the name span here, if we need it.
+  void _markAttributeNameEnd(int offset) => _markAttributeEnd(offset);
+
+  void _addAttribute(String name) {
+    if (_attributes == null) _attributes = [];
+    _attributeName.clear();
+    _attributeName.write(name);
+    _attributeValue.clear();
+    var attr = new TagAttribute();
+    _attributes.add(attr);
+    if (attributeSpans) attr.start = stream.position - name.length;
+  }
+
+  /// This is where the magic happens.
+  ///
+  /// We do our usually processing through the states and when we have a token
+  /// to return we yield the token which pauses processing until the next token
+  /// is requested.
+  bool moveNext() {
+    // Start processing. When EOF is reached state will return false;
+    // instead of true and the loop will terminate.
+    while (stream.errors.length == 0 && tokenQueue.length == 0) {
+      if (!state()) {
+        _current = null;
+        return false;
+      }
+    }
+    if (stream.errors.length > 0) {
+      _current = new ParseErrorToken(stream.errors.removeFirst());
+    } else {
+      assert(tokenQueue.length > 0);
+      _current = tokenQueue.removeFirst();
+    }
+    return true;
+  }
+
+  /// Resets the tokenizer state. Calling this does not reset the [stream] or
+  /// the [parser].
+  void reset() {
+    _lastOffset = 0;
+    tokenQueue.clear();
+    currentToken = null;
+    _buffer.clear();
+    _attributes = null;
+    _attributeNames = null;
+    state = dataState;
+  }
+
+  /// Adds a token to the queue. Sets the span if needed.
+  void _addToken(Token token) {
+    if (generateSpans && token.span == null) {
+      int offset = stream.position;
+      token.span = stream.fileInfo.span(_lastOffset, offset);
+      if (token is! ParseErrorToken) {
+        _lastOffset = offset;
+      }
+    }
+    tokenQueue.add(token);
+  }
+
+  /// This function returns either U+FFFD or the character based on the
+  /// decimal or hexadecimal representation. It also discards ";" if present.
+  /// If not present it will add a [ParseErrorToken].
+  String consumeNumberEntity(bool isHex) {
+    var allowed = isDigit;
+    var radix = 10;
+    if (isHex) {
+      allowed = isHexDigit;
+      radix = 16;
+    }
+
+    var charStack = [];
+
+    // Consume all the characters that are in range while making sure we
+    // don't hit an EOF.
+    var c = stream.char();
+    while (allowed(c) && c != EOF) {
+      charStack.add(c);
+      c = stream.char();
+    }
+
+    // Convert the set of characters consumed to an int.
+    var charAsInt = parseIntRadix(charStack.join(), radix);
+
+    // Certain characters get replaced with others
+    var char = replacementCharacters[charAsInt];
+    if (char != null) {
+      _addToken(new ParseErrorToken("illegal-codepoint-for-numeric-entity",
+          messageParams: {"charAsInt": charAsInt}));
+    } else if ((0xD800 <= charAsInt && charAsInt <= 0xDFFF) ||
+        (charAsInt > 0x10FFFF)) {
+      char = "\uFFFD";
+      _addToken(new ParseErrorToken("illegal-codepoint-for-numeric-entity",
+          messageParams: {"charAsInt": charAsInt}));
+    } else {
+      // Should speed up this check somehow (e.g. move the set to a constant)
+      if ((0x0001 <= charAsInt && charAsInt <= 0x0008) ||
+          (0x000E <= charAsInt && charAsInt <= 0x001F) ||
+          (0x007F <= charAsInt && charAsInt <= 0x009F) ||
+          (0xFDD0 <= charAsInt && charAsInt <= 0xFDEF) ||
+          const [
+        0x000B,
+        0xFFFE,
+        0xFFFF,
+        0x1FFFE,
+        0x1FFFF,
+        0x2FFFE,
+        0x2FFFF,
+        0x3FFFE,
+        0x3FFFF,
+        0x4FFFE,
+        0x4FFFF,
+        0x5FFFE,
+        0x5FFFF,
+        0x6FFFE,
+        0x6FFFF,
+        0x7FFFE,
+        0x7FFFF,
+        0x8FFFE,
+        0x8FFFF,
+        0x9FFFE,
+        0x9FFFF,
+        0xAFFFE,
+        0xAFFFF,
+        0xBFFFE,
+        0xBFFFF,
+        0xCFFFE,
+        0xCFFFF,
+        0xDFFFE,
+        0xDFFFF,
+        0xEFFFE,
+        0xEFFFF,
+        0xFFFFE,
+        0xFFFFF,
+        0x10FFFE,
+        0x10FFFF
+      ].contains(charAsInt)) {
+        _addToken(new ParseErrorToken("illegal-codepoint-for-numeric-entity",
+            messageParams: {"charAsInt": charAsInt}));
+      }
+      char = new String.fromCharCodes([charAsInt]);
+    }
+
+    // Discard the ; if present. Otherwise, put it back on the queue and
+    // invoke parseError on parser.
+    if (c != ";") {
+      _addToken(new ParseErrorToken("numeric-entity-without-semicolon"));
+      stream.unget(c);
+    }
+    return char;
+  }
+
+  void consumeEntity({String allowedChar, bool fromAttribute: false}) {
+    // Initialise to the default output for when no entity is matched
+    var output = "&";
+
+    var charStack = [stream.char()];
+    if (isWhitespace(charStack[0]) ||
+        charStack[0] == '<' ||
+        charStack[0] == '&' ||
+        charStack[0] == EOF ||
+        allowedChar == charStack[0]) {
+      stream.unget(charStack[0]);
+    } else if (charStack[0] == "#") {
+      // Read the next character to see if it's hex or decimal
+      bool hex = false;
+      charStack.add(stream.char());
+      if (charStack.last == 'x' || charStack.last == 'X') {
+        hex = true;
+        charStack.add(stream.char());
+      }
+
+      // charStack.last should be the first digit
+      if (hex && isHexDigit(charStack.last) ||
+          (!hex && isDigit(charStack.last))) {
+        // At least one digit found, so consume the whole number
+        stream.unget(charStack.last);
+        output = consumeNumberEntity(hex);
+      } else {
+        // No digits found
+        _addToken(new ParseErrorToken("expected-numeric-entity"));
+        stream.unget(charStack.removeLast());
+        output = "&${charStack.join()}";
+      }
+    } else {
+      // At this point in the process might have named entity. Entities
+      // are stored in the global variable "entities".
+      //
+      // Consume characters and compare to these to a substring of the
+      // entity names in the list until the substring no longer matches.
+      var filteredEntityList = entitiesByFirstChar[charStack[0]];
+      if (filteredEntityList == null) filteredEntityList = const [];
+
+      while (charStack.last != EOF) {
+        var name = charStack.join();
+        filteredEntityList =
+            filteredEntityList.where((e) => e.startsWith(name)).toList();
+
+        if (filteredEntityList.length == 0) {
+          break;
+        }
+        charStack.add(stream.char());
+      }
+
+      // At this point we have a string that starts with some characters
+      // that may match an entity
+      String entityName = null;
+
+      // Try to find the longest entity the string will match to take care
+      // of &noti for instance.
+
+      int entityLen;
+      for (entityLen = charStack.length - 1; entityLen > 1; entityLen--) {
+        var possibleEntityName = charStack.sublist(0, entityLen).join();
+        if (entities.containsKey(possibleEntityName)) {
+          entityName = possibleEntityName;
+          break;
+        }
+      }
+
+      if (entityName != null) {
+        var lastChar = entityName[entityName.length - 1];
+        if (lastChar != ";") {
+          _addToken(new ParseErrorToken("named-entity-without-semicolon"));
+        }
+        if (lastChar != ";" &&
+            fromAttribute &&
+            (isLetterOrDigit(charStack[entityLen]) ||
+                charStack[entityLen] == '=')) {
+          stream.unget(charStack.removeLast());
+          output = "&${charStack.join()}";
+        } else {
+          output = entities[entityName];
+          stream.unget(charStack.removeLast());
+          output = '${output}${slice(charStack, entityLen).join()}';
+        }
+      } else {
+        _addToken(new ParseErrorToken("expected-named-entity"));
+        stream.unget(charStack.removeLast());
+        output = "&${charStack.join()}";
+      }
+    }
+    if (fromAttribute) {
+      _attributeValue.write(output);
+    } else {
+      var token;
+      if (isWhitespace(output)) {
+        token = new SpaceCharactersToken(output);
+      } else {
+        token = new CharactersToken(output);
+      }
+      _addToken(token);
+    }
+  }
+
+  /// This method replaces the need for "entityInAttributeValueState".
+  void processEntityInAttribute(String allowedChar) {
+    consumeEntity(allowedChar: allowedChar, fromAttribute: true);
+  }
+
+  /// This method is a generic handler for emitting the tags. It also sets
+  /// the state to "data" because that's what's needed after a token has been
+  /// emitted.
+  void emitCurrentToken() {
+    var token = currentToken;
+    // Add token to the queue to be yielded
+    if (token is TagToken) {
+      if (lowercaseElementName) {
+        token.name = asciiUpper2Lower(token.name);
+      }
+      if (token is EndTagToken) {
+        if (_attributes != null) {
+          _addToken(new ParseErrorToken("attributes-in-end-tag"));
+        }
+        if (token.selfClosing) {
+          _addToken(new ParseErrorToken("this-closing-flag-on-end-tag"));
+        }
+      } else if (token is StartTagToken) {
+        // HTML5 specific normalizations to the token stream.
+        // Convert the list into a map where first key wins.
+        token.data = new LinkedHashMap<Object, String>();
+        if (_attributes != null) {
+          for (var attr in _attributes) {
+            token.data.putIfAbsent(attr.name, () => attr.value);
+          }
+          if (attributeSpans) token.attributeSpans = _attributes;
+        }
+      }
+      _attributes = null;
+      _attributeNames = null;
+    }
+    _addToken(token);
+    state = dataState;
+  }
+
+  // Below are the various tokenizer states worked out.
+
+  bool dataState() {
+    var data = stream.char();
+    if (data == "&") {
+      state = entityDataState;
+    } else if (data == "<") {
+      state = tagOpenState;
+    } else if (data == "\u0000") {
+      _addToken(new ParseErrorToken("invalid-codepoint"));
+      _addToken(new CharactersToken("\u0000"));
+    } else if (data == EOF) {
+      // Tokenization ends.
+      return false;
+    } else if (isWhitespace(data)) {
+      // Directly after emitting a token you switch back to the "data
+      // state". At that point spaceCharacters are important so they are
+      // emitted separately.
+      _addToken(new SpaceCharactersToken(
+          '${data}${stream.charsUntil(spaceCharacters, true)}'));
+      // No need to update lastFourChars here, since the first space will
+      // have already been appended to lastFourChars and will have broken
+      // any <!-- or --> sequences
+    } else {
+      var chars = stream.charsUntil("&<\u0000");
+      _addToken(new CharactersToken('${data}${chars}'));
+    }
+    return true;
+  }
+
+  bool entityDataState() {
+    consumeEntity();
+    state = dataState;
+    return true;
+  }
+
+  bool rcdataState() {
+    var data = stream.char();
+    if (data == "&") {
+      state = characterReferenceInRcdata;
+    } else if (data == "<") {
+      state = rcdataLessThanSignState;
+    } else if (data == EOF) {
+      // Tokenization ends.
+      return false;
+    } else if (data == "\u0000") {
+      _addToken(new ParseErrorToken("invalid-codepoint"));
+      _addToken(new CharactersToken("\uFFFD"));
+    } else if (isWhitespace(data)) {
+      // Directly after emitting a token you switch back to the "data
+      // state". At that point spaceCharacters are important so they are
+      // emitted separately.
+      _addToken(new SpaceCharactersToken(
+          '${data}${stream.charsUntil(spaceCharacters, true)}'));
+    } else {
+      var chars = stream.charsUntil("&<");
+      _addToken(new CharactersToken('${data}${chars}'));
+    }
+    return true;
+  }
+
+  bool characterReferenceInRcdata() {
+    consumeEntity();
+    state = rcdataState;
+    return true;
+  }
+
+  bool rawtextState() {
+    var data = stream.char();
+    if (data == "<") {
+      state = rawtextLessThanSignState;
+    } else if (data == "\u0000") {
+      _addToken(new ParseErrorToken("invalid-codepoint"));
+      _addToken(new CharactersToken("\uFFFD"));
+    } else if (data == EOF) {
+      // Tokenization ends.
+      return false;
+    } else {
+      var chars = stream.charsUntil("<\u0000");
+      _addToken(new CharactersToken("${data}${chars}"));
+    }
+    return true;
+  }
+
+  bool scriptDataState() {
+    var data = stream.char();
+    if (data == "<") {
+      state = scriptDataLessThanSignState;
+    } else if (data == "\u0000") {
+      _addToken(new ParseErrorToken("invalid-codepoint"));
+      _addToken(new CharactersToken("\uFFFD"));
+    } else if (data == EOF) {
+      // Tokenization ends.
+      return false;
+    } else {
+      var chars = stream.charsUntil("<\u0000");
+      _addToken(new CharactersToken("${data}${chars}"));
+    }
+    return true;
+  }
+
+  bool plaintextState() {
+    var data = stream.char();
+    if (data == EOF) {
+      // Tokenization ends.
+      return false;
+    } else if (data == "\u0000") {
+      _addToken(new ParseErrorToken("invalid-codepoint"));
+      _addToken(new CharactersToken("\uFFFD"));
+    } else {
+      _addToken(new CharactersToken('${data}${stream.charsUntil("\u0000")}'));
+    }
+    return true;
+  }
+
+  bool tagOpenState() {
+    var data = stream.char();
+    if (data == "!") {
+      state = markupDeclarationOpenState;
+    } else if (data == "/") {
+      state = closeTagOpenState;
+    } else if (isLetter(data)) {
+      currentToken = new StartTagToken(data);
+      state = tagNameState;
+    } else if (data == ">") {
+      // XXX In theory it could be something besides a tag name. But
+      // do we really care?
+      _addToken(new ParseErrorToken("expected-tag-name-but-got-right-bracket"));
+      _addToken(new CharactersToken("<>"));
+      state = dataState;
+    } else if (data == "?") {
+      // XXX In theory it could be something besides a tag name. But
+      // do we really care?
+      _addToken(new ParseErrorToken("expected-tag-name-but-got-question-mark"));
+      stream.unget(data);
+      state = bogusCommentState;
+    } else {
+      // XXX
+      _addToken(new ParseErrorToken("expected-tag-name"));
+      _addToken(new CharactersToken("<"));
+      stream.unget(data);
+      state = dataState;
+    }
+    return true;
+  }
+
+  bool closeTagOpenState() {
+    var data = stream.char();
+    if (isLetter(data)) {
+      currentToken = new EndTagToken(data);
+      state = tagNameState;
+    } else if (data == ">") {
+      _addToken(
+          new ParseErrorToken("expected-closing-tag-but-got-right-bracket"));
+      state = dataState;
+    } else if (data == EOF) {
+      _addToken(new ParseErrorToken("expected-closing-tag-but-got-eof"));
+      _addToken(new CharactersToken("</"));
+      state = dataState;
+    } else {
+      // XXX data can be _'_...
+      _addToken(new ParseErrorToken("expected-closing-tag-but-got-char",
+          messageParams: {"data": data}));
+      stream.unget(data);
+      state = bogusCommentState;
+    }
+    return true;
+  }
+
+  bool tagNameState() {
+    var data = stream.char();
+    if (isWhitespace(data)) {
+      state = beforeAttributeNameState;
+    } else if (data == ">") {
+      emitCurrentToken();
+    } else if (data == EOF) {
+      _addToken(new ParseErrorToken("eof-in-tag-name"));
+      state = dataState;
+    } else if (data == "/") {
+      state = selfClosingStartTagState;
+    } else if (data == "\u0000") {
+      _addToken(new ParseErrorToken("invalid-codepoint"));
+      currentTagToken.name = '${currentTagToken.name}\uFFFD';
+    } else {
+      currentTagToken.name = '${currentTagToken.name}$data';
+      // (Don't use charsUntil here, because tag names are
+      // very short and it's faster to not do anything fancy)
+    }
+    return true;
+  }
+
+  bool rcdataLessThanSignState() {
+    var data = stream.char();
+    if (data == "/") {
+      _buffer.clear();
+      state = rcdataEndTagOpenState;
+    } else {
+      _addToken(new CharactersToken("<"));
+      stream.unget(data);
+      state = rcdataState;
+    }
+    return true;
+  }
+
+  bool rcdataEndTagOpenState() {
+    var data = stream.char();
+    if (isLetter(data)) {
+      _buffer.write(data);
+      state = rcdataEndTagNameState;
+    } else {
+      _addToken(new CharactersToken("</"));
+      stream.unget(data);
+      state = rcdataState;
+    }
+    return true;
+  }
+
+  bool _tokenIsAppropriate() {
+    // TODO(jmesserly): this should use case insensitive compare instead.
+    return currentToken is TagToken &&
+        currentTagToken.name.toLowerCase() == '$_buffer'.toLowerCase();
+  }
+
+  bool rcdataEndTagNameState() {
+    var appropriate = _tokenIsAppropriate();
+    var data = stream.char();
+    if (isWhitespace(data) && appropriate) {
+      currentToken = new EndTagToken('$_buffer');
+      state = beforeAttributeNameState;
+    } else if (data == "/" && appropriate) {
+      currentToken = new EndTagToken('$_buffer');
+      state = selfClosingStartTagState;
+    } else if (data == ">" && appropriate) {
+      currentToken = new EndTagToken('$_buffer');
+      emitCurrentToken();
+      state = dataState;
+    } else if (isLetter(data)) {
+      _buffer.write(data);
+    } else {
+      _addToken(new CharactersToken("</$_buffer"));
+      stream.unget(data);
+      state = rcdataState;
+    }
+    return true;
+  }
+
+  bool rawtextLessThanSignState() {
+    var data = stream.char();
+    if (data == "/") {
+      _buffer.clear();
+      state = rawtextEndTagOpenState;
+    } else {
+      _addToken(new CharactersToken("<"));
+      stream.unget(data);
+      state = rawtextState;
+    }
+    return true;
+  }
+
+  bool rawtextEndTagOpenState() {
+    var data = stream.char();
+    if (isLetter(data)) {
+      _buffer.write(data);
+      state = rawtextEndTagNameState;
+    } else {
+      _addToken(new CharactersToken("</"));
+      stream.unget(data);
+      state = rawtextState;
+    }
+    return true;
+  }
+
+  bool rawtextEndTagNameState() {
+    var appropriate = _tokenIsAppropriate();
+    var data = stream.char();
+    if (isWhitespace(data) && appropriate) {
+      currentToken = new EndTagToken('$_buffer');
+      state = beforeAttributeNameState;
+    } else if (data == "/" && appropriate) {
+      currentToken = new EndTagToken('$_buffer');
+      state = selfClosingStartTagState;
+    } else if (data == ">" && appropriate) {
+      currentToken = new EndTagToken('$_buffer');
+      emitCurrentToken();
+      state = dataState;
+    } else if (isLetter(data)) {
+      _buffer.write(data);
+    } else {
+      _addToken(new CharactersToken("</$_buffer"));
+      stream.unget(data);
+      state = rawtextState;
+    }
+    return true;
+  }
+
+  bool scriptDataLessThanSignState() {
+    var data = stream.char();
+    if (data == "/") {
+      _buffer.clear();
+      state = scriptDataEndTagOpenState;
+    } else if (data == "!") {
+      _addToken(new CharactersToken("<!"));
+      state = scriptDataEscapeStartState;
+    } else {
+      _addToken(new CharactersToken("<"));
+      stream.unget(data);
+      state = scriptDataState;
+    }
+    return true;
+  }
+
+  bool scriptDataEndTagOpenState() {
+    var data = stream.char();
+    if (isLetter(data)) {
+      _buffer.write(data);
+      state = scriptDataEndTagNameState;
+    } else {
+      _addToken(new CharactersToken("</"));
+      stream.unget(data);
+      state = scriptDataState;
+    }
+    return true;
+  }
+
+  bool scriptDataEndTagNameState() {
+    var appropriate = _tokenIsAppropriate();
+    var data = stream.char();
+    if (isWhitespace(data) && appropriate) {
+      currentToken = new EndTagToken('$_buffer');
+      state = beforeAttributeNameState;
+    } else if (data == "/" && appropriate) {
+      currentToken = new EndTagToken('$_buffer');
+      state = selfClosingStartTagState;
+    } else if (data == ">" && appropriate) {
+      currentToken = new EndTagToken('$_buffer');
+      emitCurrentToken();
+      state = dataState;
+    } else if (isLetter(data)) {
+      _buffer.write(data);
+    } else {
+      _addToken(new CharactersToken("</$_buffer"));
+      stream.unget(data);
+      state = scriptDataState;
+    }
+    return true;
+  }
+
+  bool scriptDataEscapeStartState() {
+    var data = stream.char();
+    if (data == "-") {
+      _addToken(new CharactersToken("-"));
+      state = scriptDataEscapeStartDashState;
+    } else {
+      stream.unget(data);
+      state = scriptDataState;
+    }
+    return true;
+  }
+
+  bool scriptDataEscapeStartDashState() {
+    var data = stream.char();
+    if (data == "-") {
+      _addToken(new CharactersToken("-"));
+      state = scriptDataEscapedDashDashState;
+    } else {
+      stream.unget(data);
+      state = scriptDataState;
+    }
+    return true;
+  }
+
+  bool scriptDataEscapedState() {
+    var data = stream.char();
+    if (data == "-") {
+      _addToken(new CharactersToken("-"));
+      state = scriptDataEscapedDashState;
+    } else if (data == "<") {
+      state = scriptDataEscapedLessThanSignState;
+    } else if (data == "\u0000") {
+      _addToken(new ParseErrorToken("invalid-codepoint"));
+      _addToken(new CharactersToken("\uFFFD"));
+    } else if (data == EOF) {
+      state = dataState;
+    } else {
+      var chars = stream.charsUntil("<-\u0000");
+      _addToken(new CharactersToken("${data}${chars}"));
+    }
+    return true;
+  }
+
+  bool scriptDataEscapedDashState() {
+    var data = stream.char();
+    if (data == "-") {
+      _addToken(new CharactersToken("-"));
+      state = scriptDataEscapedDashDashState;
+    } else if (data == "<") {
+      state = scriptDataEscapedLessThanSignState;
+    } else if (data == "\u0000") {
+      _addToken(new ParseErrorToken("invalid-codepoint"));
+      _addToken(new CharactersToken("\uFFFD"));
+      state = scriptDataEscapedState;
+    } else if (data == EOF) {
+      state = dataState;
+    } else {
+      _addToken(new CharactersToken(data));
+      state = scriptDataEscapedState;
+    }
+    return true;
+  }
+
+  bool scriptDataEscapedDashDashState() {
+    var data = stream.char();
+    if (data == "-") {
+      _addToken(new CharactersToken("-"));
+    } else if (data == "<") {
+      state = scriptDataEscapedLessThanSignState;
+    } else if (data == ">") {
+      _addToken(new CharactersToken(">"));
+      state = scriptDataState;
+    } else if (data == "\u0000") {
+      _addToken(new ParseErrorToken("invalid-codepoint"));
+      _addToken(new CharactersToken("\uFFFD"));
+      state = scriptDataEscapedState;
+    } else if (data == EOF) {
+      state = dataState;
+    } else {
+      _addToken(new CharactersToken(data));
+      state = scriptDataEscapedState;
+    }
+    return true;
+  }
+
+  bool scriptDataEscapedLessThanSignState() {
+    var data = stream.char();
+    if (data == "/") {
+      _buffer.clear();
+      state = scriptDataEscapedEndTagOpenState;
+    } else if (isLetter(data)) {
+      _addToken(new CharactersToken("<$data"));
+      _buffer.clear();
+      _buffer.write(data);
+      state = scriptDataDoubleEscapeStartState;
+    } else {
+      _addToken(new CharactersToken("<"));
+      stream.unget(data);
+      state = scriptDataEscapedState;
+    }
+    return true;
+  }
+
+  bool scriptDataEscapedEndTagOpenState() {
+    var data = stream.char();
+    if (isLetter(data)) {
+      _buffer.clear();
+      _buffer.write(data);
+      state = scriptDataEscapedEndTagNameState;
+    } else {
+      _addToken(new CharactersToken("</"));
+      stream.unget(data);
+      state = scriptDataEscapedState;
+    }
+    return true;
+  }
+
+  bool scriptDataEscapedEndTagNameState() {
+    var appropriate = _tokenIsAppropriate();
+    var data = stream.char();
+    if (isWhitespace(data) && appropriate) {
+      currentToken = new EndTagToken('$_buffer');
+      state = beforeAttributeNameState;
+    } else if (data == "/" && appropriate) {
+      currentToken = new EndTagToken('$_buffer');
+      state = selfClosingStartTagState;
+    } else if (data == ">" && appropriate) {
+      currentToken = new EndTagToken('$_buffer');
+      emitCurrentToken();
+      state = dataState;
+    } else if (isLetter(data)) {
+      _buffer.write(data);
+    } else {
+      _addToken(new CharactersToken("</$_buffer"));
+      stream.unget(data);
+      state = scriptDataEscapedState;
+    }
+    return true;
+  }
+
+  bool scriptDataDoubleEscapeStartState() {
+    var data = stream.char();
+    if (isWhitespace(data) || data == "/" || data == ">") {
+      _addToken(new CharactersToken(data));
+      if ('$_buffer'.toLowerCase() == "script") {
+        state = scriptDataDoubleEscapedState;
+      } else {
+        state = scriptDataEscapedState;
+      }
+    } else if (isLetter(data)) {
+      _addToken(new CharactersToken(data));
+      _buffer.write(data);
+    } else {
+      stream.unget(data);
+      state = scriptDataEscapedState;
+    }
+    return true;
+  }
+
+  bool scriptDataDoubleEscapedState() {
+    var data = stream.char();
+    if (data == "-") {
+      _addToken(new CharactersToken("-"));
+      state = scriptDataDoubleEscapedDashState;
+    } else if (data == "<") {
+      _addToken(new CharactersToken("<"));
+      state = scriptDataDoubleEscapedLessThanSignState;
+    } else if (data == "\u0000") {
+      _addToken(new ParseErrorToken("invalid-codepoint"));
+      _addToken(new CharactersToken("\uFFFD"));
+    } else if (data == EOF) {
+      _addToken(new ParseErrorToken("eof-in-script-in-script"));
+      state = dataState;
+    } else {
+      _addToken(new CharactersToken(data));
+    }
+    return true;
+  }
+
+  bool scriptDataDoubleEscapedDashState() {
+    var data = stream.char();
+    if (data == "-") {
+      _addToken(new CharactersToken("-"));
+      state = scriptDataDoubleEscapedDashDashState;
+    } else if (data == "<") {
+      _addToken(new CharactersToken("<"));
+      state = scriptDataDoubleEscapedLessThanSignState;
+    } else if (data == "\u0000") {
+      _addToken(new ParseErrorToken("invalid-codepoint"));
+      _addToken(new CharactersToken("\uFFFD"));
+      state = scriptDataDoubleEscapedState;
+    } else if (data == EOF) {
+      _addToken(new ParseErrorToken("eof-in-script-in-script"));
+      state = dataState;
+    } else {
+      _addToken(new CharactersToken(data));
+      state = scriptDataDoubleEscapedState;
+    }
+    return true;
+  }
+
+  // TODO(jmesserly): report bug in original code
+  // (was "Dash" instead of "DashDash")
+  bool scriptDataDoubleEscapedDashDashState() {
+    var data = stream.char();
+    if (data == "-") {
+      _addToken(new CharactersToken("-"));
+    } else if (data == "<") {
+      _addToken(new CharactersToken("<"));
+      state = scriptDataDoubleEscapedLessThanSignState;
+    } else if (data == ">") {
+      _addToken(new CharactersToken(">"));
+      state = scriptDataState;
+    } else if (data == "\u0000") {
+      _addToken(new ParseErrorToken("invalid-codepoint"));
+      _addToken(new CharactersToken("\uFFFD"));
+      state = scriptDataDoubleEscapedState;
+    } else if (data == EOF) {
+      _addToken(new ParseErrorToken("eof-in-script-in-script"));
+      state = dataState;
+    } else {
+      _addToken(new CharactersToken(data));
+      state = scriptDataDoubleEscapedState;
+    }
+    return true;
+  }
+
+  bool scriptDataDoubleEscapedLessThanSignState() {
+    var data = stream.char();
+    if (data == "/") {
+      _addToken(new CharactersToken("/"));
+      _buffer.clear();
+      state = scriptDataDoubleEscapeEndState;
+    } else {
+      stream.unget(data);
+      state = scriptDataDoubleEscapedState;
+    }
+    return true;
+  }
+
+  bool scriptDataDoubleEscapeEndState() {
+    var data = stream.char();
+    if (isWhitespace(data) || data == "/" || data == ">") {
+      _addToken(new CharactersToken(data));
+      if ('$_buffer'.toLowerCase() == "script") {
+        state = scriptDataEscapedState;
+      } else {
+        state = scriptDataDoubleEscapedState;
+      }
+    } else if (isLetter(data)) {
+      _addToken(new CharactersToken(data));
+      _buffer.write(data);
+    } else {
+      stream.unget(data);
+      state = scriptDataDoubleEscapedState;
+    }
+    return true;
+  }
+
+  bool beforeAttributeNameState() {
+    var data = stream.char();
+    if (isWhitespace(data)) {
+      stream.charsUntil(spaceCharacters, true);
+    } else if (isLetter(data)) {
+      _addAttribute(data);
+      state = attributeNameState;
+    } else if (data == ">") {
+      emitCurrentToken();
+    } else if (data == "/") {
+      state = selfClosingStartTagState;
+    } else if (data == EOF) {
+      _addToken(new ParseErrorToken("expected-attribute-name-but-got-eof"));
+      state = dataState;
+    } else if ("'\"=<".contains(data)) {
+      _addToken(new ParseErrorToken("invalid-character-in-attribute-name"));
+      _addAttribute(data);
+      state = attributeNameState;
+    } else if (data == "\u0000") {
+      _addToken(new ParseErrorToken("invalid-codepoint"));
+      _addAttribute("\uFFFD");
+      state = attributeNameState;
+    } else {
+      _addAttribute(data);
+      state = attributeNameState;
+    }
+    return true;
+  }
+
+  bool attributeNameState() {
+    var data = stream.char();
+    bool leavingThisState = true;
+    bool emitToken = false;
+    if (data == "=") {
+      state = beforeAttributeValueState;
+    } else if (isLetter(data)) {
+      _attributeName.write(data);
+      _attributeName.write(stream.charsUntil(asciiLetters, true));
+      leavingThisState = false;
+    } else if (data == ">") {
+      // XXX If we emit here the attributes are converted to a dict
+      // without being checked and when the code below runs we error
+      // because data is a dict not a list
+      emitToken = true;
+    } else if (isWhitespace(data)) {
+      state = afterAttributeNameState;
+    } else if (data == "/") {
+      state = selfClosingStartTagState;
+    } else if (data == "\u0000") {
+      _addToken(new ParseErrorToken("invalid-codepoint"));
+      _attributeName.write('\uFFFD');
+      leavingThisState = false;
+    } else if (data == EOF) {
+      _addToken(new ParseErrorToken("eof-in-attribute-name"));
+      state = dataState;
+    } else if ("'\"<".contains(data)) {
+      _addToken(new ParseErrorToken("invalid-character-in-attribute-name"));
+      _attributeName.write(data);
+      leavingThisState = false;
+    } else {
+      _attributeName.write(data);
+      leavingThisState = false;
+    }
+
+    if (leavingThisState) {
+      _markAttributeNameEnd(-1);
+
+      // Attributes are not dropped at this stage. That happens when the
+      // start tag token is emitted so values can still be safely appended
+      // to attributes, but we do want to report the parse error in time.
+      var attrName = _attributeName.toString();
+      if (lowercaseAttrName) {
+        attrName = asciiUpper2Lower(attrName);
+      }
+      _attributes.last.name = attrName;
+      if (_attributeNames == null) _attributeNames = new Set();
+      if (_attributeNames.contains(attrName)) {
+        _addToken(new ParseErrorToken("duplicate-attribute"));
+      }
+      _attributeNames.add(attrName);
+
+      // XXX Fix for above XXX
+      if (emitToken) {
+        emitCurrentToken();
+      }
+    }
+    return true;
+  }
+
+  bool afterAttributeNameState() {
+    var data = stream.char();
+    if (isWhitespace(data)) {
+      stream.charsUntil(spaceCharacters, true);
+    } else if (data == "=") {
+      state = beforeAttributeValueState;
+    } else if (data == ">") {
+      emitCurrentToken();
+    } else if (isLetter(data)) {
+      _addAttribute(data);
+      state = attributeNameState;
+    } else if (data == "/") {
+      state = selfClosingStartTagState;
+    } else if (data == "\u0000") {
+      _addToken(new ParseErrorToken("invalid-codepoint"));
+      _addAttribute("\uFFFD");
+      state = attributeNameState;
+    } else if (data == EOF) {
+      _addToken(new ParseErrorToken("expected-end-of-tag-but-got-eof"));
+      state = dataState;
+    } else if ("'\"<".contains(data)) {
+      _addToken(new ParseErrorToken("invalid-character-after-attribute-name"));
+      _addAttribute(data);
+      state = attributeNameState;
+    } else {
+      _addAttribute(data);
+      state = attributeNameState;
+    }
+    return true;
+  }
+
+  bool beforeAttributeValueState() {
+    var data = stream.char();
+    if (isWhitespace(data)) {
+      stream.charsUntil(spaceCharacters, true);
+    } else if (data == "\"") {
+      _markAttributeValueStart(0);
+      state = attributeValueDoubleQuotedState;
+    } else if (data == "&") {
+      state = attributeValueUnQuotedState;
+      stream.unget(data);
+      _markAttributeValueStart(0);
+    } else if (data == "'") {
+      _markAttributeValueStart(0);
+      state = attributeValueSingleQuotedState;
+    } else if (data == ">") {
+      _addToken(new ParseErrorToken(
+          "expected-attribute-value-but-got-right-bracket"));
+      emitCurrentToken();
+    } else if (data == "\u0000") {
+      _addToken(new ParseErrorToken("invalid-codepoint"));
+      _markAttributeValueStart(-1);
+      _attributeValue.write('\uFFFD');
+      state = attributeValueUnQuotedState;
+    } else if (data == EOF) {
+      _addToken(new ParseErrorToken("expected-attribute-value-but-got-eof"));
+      state = dataState;
+    } else if ("=<`".contains(data)) {
+      _addToken(new ParseErrorToken("equals-in-unquoted-attribute-value"));
+      _markAttributeValueStart(-1);
+      _attributeValue.write(data);
+      state = attributeValueUnQuotedState;
+    } else {
+      _markAttributeValueStart(-1);
+      _attributeValue.write(data);
+      state = attributeValueUnQuotedState;
+    }
+    return true;
+  }
+
+  bool attributeValueDoubleQuotedState() {
+    var data = stream.char();
+    if (data == "\"") {
+      _markAttributeValueEnd(-1);
+      _markAttributeEnd(0);
+      state = afterAttributeValueState;
+    } else if (data == "&") {
+      processEntityInAttribute('"');
+    } else if (data == "\u0000") {
+      _addToken(new ParseErrorToken("invalid-codepoint"));
+      _attributeValue.write('\uFFFD');
+    } else if (data == EOF) {
+      _addToken(new ParseErrorToken("eof-in-attribute-value-double-quote"));
+      _markAttributeValueEnd(-1);
+      state = dataState;
+    } else {
+      _attributeValue.write(data);
+      _attributeValue.write(stream.charsUntil("\"&"));
+    }
+    return true;
+  }
+
+  bool attributeValueSingleQuotedState() {
+    var data = stream.char();
+    if (data == "'") {
+      _markAttributeValueEnd(-1);
+      _markAttributeEnd(0);
+      state = afterAttributeValueState;
+    } else if (data == "&") {
+      processEntityInAttribute("'");
+    } else if (data == "\u0000") {
+      _addToken(new ParseErrorToken("invalid-codepoint"));
+      _attributeValue.write('\uFFFD');
+    } else if (data == EOF) {
+      _addToken(new ParseErrorToken("eof-in-attribute-value-single-quote"));
+      _markAttributeValueEnd(-1);
+      state = dataState;
+    } else {
+      _attributeValue.write(data);
+      _attributeValue.write(stream.charsUntil("\'&"));
+    }
+    return true;
+  }
+
+  bool attributeValueUnQuotedState() {
+    var data = stream.char();
+    if (isWhitespace(data)) {
+      _markAttributeValueEnd(-1);
+      state = beforeAttributeNameState;
+    } else if (data == "&") {
+      processEntityInAttribute(">");
+    } else if (data == ">") {
+      _markAttributeValueEnd(-1);
+      emitCurrentToken();
+    } else if (data == EOF) {
+      _addToken(new ParseErrorToken("eof-in-attribute-value-no-quotes"));
+      _markAttributeValueEnd(-1);
+      state = dataState;
+    } else if ('"\'=<`'.contains(data)) {
+      _addToken(new ParseErrorToken(
+          "unexpected-character-in-unquoted-attribute-value"));
+      _attributeValue.write(data);
+    } else if (data == "\u0000") {
+      _addToken(new ParseErrorToken("invalid-codepoint"));
+      _attributeValue.write('\uFFFD');
+    } else {
+      _attributeValue.write(data);
+      _attributeValue.write(stream.charsUntil("&>\"\'=<`$spaceCharacters"));
+    }
+    return true;
+  }
+
+  bool afterAttributeValueState() {
+    var data = stream.char();
+    if (isWhitespace(data)) {
+      state = beforeAttributeNameState;
+    } else if (data == ">") {
+      emitCurrentToken();
+    } else if (data == "/") {
+      state = selfClosingStartTagState;
+    } else if (data == EOF) {
+      _addToken(new ParseErrorToken("unexpected-EOF-after-attribute-value"));
+      stream.unget(data);
+      state = dataState;
+    } else {
+      _addToken(
+          new ParseErrorToken("unexpected-character-after-attribute-value"));
+      stream.unget(data);
+      state = beforeAttributeNameState;
+    }
+    return true;
+  }
+
+  bool selfClosingStartTagState() {
+    var data = stream.char();
+    if (data == ">") {
+      currentTagToken.selfClosing = true;
+      emitCurrentToken();
+    } else if (data == EOF) {
+      _addToken(new ParseErrorToken("unexpected-EOF-after-solidus-in-tag"));
+      stream.unget(data);
+      state = dataState;
+    } else {
+      _addToken(
+          new ParseErrorToken("unexpected-character-after-soldius-in-tag"));
+      stream.unget(data);
+      state = beforeAttributeNameState;
+    }
+    return true;
+  }
+
+  bool bogusCommentState() {
+    // Make a new comment token and give it as value all the characters
+    // until the first > or EOF (charsUntil checks for EOF automatically)
+    // and emit it.
+    var data = stream.charsUntil(">");
+    data = data.replaceAll("\u0000", "\uFFFD");
+    _addToken(new CommentToken(data));
+
+    // Eat the character directly after the bogus comment which is either a
+    // ">" or an EOF.
+    stream.char();
+    state = dataState;
+    return true;
+  }
+
+  bool markupDeclarationOpenState() {
+    var charStack = [stream.char()];
+    if (charStack.last == "-") {
+      charStack.add(stream.char());
+      if (charStack.last == "-") {
+        currentToken = new CommentToken();
+        state = commentStartState;
+        return true;
+      }
+    } else if (charStack.last == 'd' || charStack.last == 'D') {
+      var matched = true;
+      for (var expected in const ['oO', 'cC', 'tT', 'yY', 'pP', 'eE']) {
+        var char = stream.char();
+        charStack.add(char);
+        if (char == EOF || !expected.contains(char)) {
+          matched = false;
+          break;
+        }
+      }
+      if (matched) {
+        currentToken = new DoctypeToken(correct: true);
+        state = doctypeState;
+        return true;
+      }
+    } else if (charStack.last == "[" &&
+        parser != null &&
+        parser.tree.openElements.length > 0 &&
+        parser.tree.openElements.last.namespaceUri !=
+            parser.tree.defaultNamespace) {
+      var matched = true;
+      for (var expected in const ["C", "D", "A", "T", "A", "["]) {
+        charStack.add(stream.char());
+        if (charStack.last != expected) {
+          matched = false;
+          break;
+        }
+      }
+      if (matched) {
+        state = cdataSectionState;
+        return true;
+      }
+    }
+
+    _addToken(new ParseErrorToken("expected-dashes-or-doctype"));
+
+    while (charStack.length > 0) {
+      stream.unget(charStack.removeLast());
+    }
+    state = bogusCommentState;
+    return true;
+  }
+
+  bool commentStartState() {
+    var data = stream.char();
+    if (data == "-") {
+      state = commentStartDashState;
+    } else if (data == "\u0000") {
+      _addToken(new ParseErrorToken("invalid-codepoint"));
+      currentStringToken.add('\uFFFD');
+    } else if (data == ">") {
+      _addToken(new ParseErrorToken("incorrect-comment"));
+      _addToken(currentToken);
+      state = dataState;
+    } else if (data == EOF) {
+      _addToken(new ParseErrorToken("eof-in-comment"));
+      _addToken(currentToken);
+      state = dataState;
+    } else {
+      currentStringToken.add(data);
+      state = commentState;
+    }
+    return true;
+  }
+
+  bool commentStartDashState() {
+    var data = stream.char();
+    if (data == "-") {
+      state = commentEndState;
+    } else if (data == "\u0000") {
+      _addToken(new ParseErrorToken("invalid-codepoint"));
+      currentStringToken.add('-\uFFFD');
+    } else if (data == ">") {
+      _addToken(new ParseErrorToken("incorrect-comment"));
+      _addToken(currentToken);
+      state = dataState;
+    } else if (data == EOF) {
+      _addToken(new ParseErrorToken("eof-in-comment"));
+      _addToken(currentToken);
+      state = dataState;
+    } else {
+      currentStringToken.add('-').add(data);
+      state = commentState;
+    }
+    return true;
+  }
+
+  bool commentState() {
+    var data = stream.char();
+    if (data == "-") {
+      state = commentEndDashState;
+    } else if (data == "\u0000") {
+      _addToken(new ParseErrorToken("invalid-codepoint"));
+      currentStringToken.add('\uFFFD');
+    } else if (data == EOF) {
+      _addToken(new ParseErrorToken("eof-in-comment"));
+      _addToken(currentToken);
+      state = dataState;
+    } else {
+      currentStringToken.add(data).add(stream.charsUntil("-\u0000"));
+    }
+    return true;
+  }
+
+  bool commentEndDashState() {
+    var data = stream.char();
+    if (data == "-") {
+      state = commentEndState;
+    } else if (data == "\u0000") {
+      _addToken(new ParseErrorToken("invalid-codepoint"));
+      currentStringToken.add('-\uFFFD');
+      state = commentState;
+    } else if (data == EOF) {
+      _addToken(new ParseErrorToken("eof-in-comment-end-dash"));
+      _addToken(currentToken);
+      state = dataState;
+    } else {
+      currentStringToken.add('-').add(data);
+      state = commentState;
+    }
+    return true;
+  }
+
+  bool commentEndState() {
+    var data = stream.char();
+    if (data == ">") {
+      _addToken(currentToken);
+      state = dataState;
+    } else if (data == "\u0000") {
+      _addToken(new ParseErrorToken("invalid-codepoint"));
+      currentStringToken.add('--\uFFFD');
+      state = commentState;
+    } else if (data == "!") {
+      _addToken(
+          new ParseErrorToken("unexpected-bang-after-double-dash-in-comment"));
+      state = commentEndBangState;
+    } else if (data == "-") {
+      _addToken(
+          new ParseErrorToken("unexpected-dash-after-double-dash-in-comment"));
+      currentStringToken.add(data);
+    } else if (data == EOF) {
+      _addToken(new ParseErrorToken("eof-in-comment-double-dash"));
+      _addToken(currentToken);
+      state = dataState;
+    } else {
+      // XXX
+      _addToken(new ParseErrorToken("unexpected-char-in-comment"));
+      currentStringToken.add('--').add(data);
+      state = commentState;
+    }
+    return true;
+  }
+
+  bool commentEndBangState() {
+    var data = stream.char();
+    if (data == ">") {
+      _addToken(currentToken);
+      state = dataState;
+    } else if (data == "-") {
+      currentStringToken.add('--!');
+      state = commentEndDashState;
+    } else if (data == "\u0000") {
+      _addToken(new ParseErrorToken("invalid-codepoint"));
+      currentStringToken.add('--!\uFFFD');
+      state = commentState;
+    } else if (data == EOF) {
+      _addToken(new ParseErrorToken("eof-in-comment-end-bang-state"));
+      _addToken(currentToken);
+      state = dataState;
+    } else {
+      currentStringToken.add('--!').add(data);
+      state = commentState;
+    }
+    return true;
+  }
+
+  bool doctypeState() {
+    var data = stream.char();
+    if (isWhitespace(data)) {
+      state = beforeDoctypeNameState;
+    } else if (data == EOF) {
+      _addToken(new ParseErrorToken("expected-doctype-name-but-got-eof"));
+      currentDoctypeToken.correct = false;
+      _addToken(currentToken);
+      state = dataState;
+    } else {
+      _addToken(new ParseErrorToken("need-space-after-doctype"));
+      stream.unget(data);
+      state = beforeDoctypeNameState;
+    }
+    return true;
+  }
+
+  bool beforeDoctypeNameState() {
+    var data = stream.char();
+    if (isWhitespace(data)) {
+      return true;
+    } else if (data == ">") {
+      _addToken(
+          new ParseErrorToken("expected-doctype-name-but-got-right-bracket"));
+      currentDoctypeToken.correct = false;
+      _addToken(currentToken);
+      state = dataState;
+    } else if (data == "\u0000") {
+      _addToken(new ParseErrorToken("invalid-codepoint"));
+      currentDoctypeToken.name = "\uFFFD";
+      state = doctypeNameState;
+    } else if (data == EOF) {
+      _addToken(new ParseErrorToken("expected-doctype-name-but-got-eof"));
+      currentDoctypeToken.correct = false;
+      _addToken(currentToken);
+      state = dataState;
+    } else {
+      currentDoctypeToken.name = data;
+      state = doctypeNameState;
+    }
+    return true;
+  }
+
+  bool doctypeNameState() {
+    var data = stream.char();
+    if (isWhitespace(data)) {
+      currentDoctypeToken.name = asciiUpper2Lower(currentDoctypeToken.name);
+      state = afterDoctypeNameState;
+    } else if (data == ">") {
+      currentDoctypeToken.name = asciiUpper2Lower(currentDoctypeToken.name);
+      _addToken(currentToken);
+      state = dataState;
+    } else if (data == "\u0000") {
+      _addToken(new ParseErrorToken("invalid-codepoint"));
+      currentDoctypeToken.name = "${currentDoctypeToken.name}\uFFFD";
+      state = doctypeNameState;
+    } else if (data == EOF) {
+      _addToken(new ParseErrorToken("eof-in-doctype-name"));
+      currentDoctypeToken.correct = false;
+      currentDoctypeToken.name = asciiUpper2Lower(currentDoctypeToken.name);
+      _addToken(currentToken);
+      state = dataState;
+    } else {
+      currentDoctypeToken.name = '${currentDoctypeToken.name}$data';
+    }
+    return true;
+  }
+
+  bool afterDoctypeNameState() {
+    var data = stream.char();
+    if (isWhitespace(data)) {
+      return true;
+    } else if (data == ">") {
+      _addToken(currentToken);
+      state = dataState;
+    } else if (data == EOF) {
+      currentDoctypeToken.correct = false;
+      stream.unget(data);
+      _addToken(new ParseErrorToken("eof-in-doctype"));
+      _addToken(currentToken);
+      state = dataState;
+    } else {
+      if (data == "p" || data == "P") {
+        // TODO(jmesserly): would be nice to have a helper for this.
+        var matched = true;
+        for (var expected in const ["uU", "bB", "lL", "iI", "cC"]) {
+          data = stream.char();
+          if (data == EOF || !expected.contains(data)) {
+            matched = false;
+            break;
+          }
+        }
+        if (matched) {
+          state = afterDoctypePublicKeywordState;
+          return true;
+        }
+      } else if (data == "s" || data == "S") {
+        var matched = true;
+        for (var expected in const ["yY", "sS", "tT", "eE", "mM"]) {
+          data = stream.char();
+          if (data == EOF || !expected.contains(data)) {
+            matched = false;
+            break;
+          }
+        }
+        if (matched) {
+          state = afterDoctypeSystemKeywordState;
+          return true;
+        }
+      }
+
+      // All the characters read before the current 'data' will be
+      // [a-zA-Z], so they're garbage in the bogus doctype and can be
+      // discarded; only the latest character might be '>' or EOF
+      // and needs to be ungetted
+      stream.unget(data);
+      _addToken(new ParseErrorToken(
+          "expected-space-or-right-bracket-in-doctype",
+          messageParams: {"data": data}));
+      currentDoctypeToken.correct = false;
+      state = bogusDoctypeState;
+    }
+    return true;
+  }
+
+  bool afterDoctypePublicKeywordState() {
+    var data = stream.char();
+    if (isWhitespace(data)) {
+      state = beforeDoctypePublicIdentifierState;
+    } else if (data == "'" || data == '"') {
+      _addToken(new ParseErrorToken("unexpected-char-in-doctype"));
+      stream.unget(data);
+      state = beforeDoctypePublicIdentifierState;
+    } else if (data == EOF) {
+      _addToken(new ParseErrorToken("eof-in-doctype"));
+      currentDoctypeToken.correct = false;
+      _addToken(currentToken);
+      state = dataState;
+    } else {
+      stream.unget(data);
+      state = beforeDoctypePublicIdentifierState;
+    }
+    return true;
+  }
+
+  bool beforeDoctypePublicIdentifierState() {
+    var data = stream.char();
+    if (isWhitespace(data)) {
+      return true;
+    } else if (data == "\"") {
+      currentDoctypeToken.publicId = "";
+      state = doctypePublicIdentifierDoubleQuotedState;
+    } else if (data == "'") {
+      currentDoctypeToken.publicId = "";
+      state = doctypePublicIdentifierSingleQuotedState;
+    } else if (data == ">") {
+      _addToken(new ParseErrorToken("unexpected-end-of-doctype"));
+      currentDoctypeToken.correct = false;
+      _addToken(currentToken);
+      state = dataState;
+    } else if (data == EOF) {
+      _addToken(new ParseErrorToken("eof-in-doctype"));
+      currentDoctypeToken.correct = false;
+      _addToken(currentToken);
+      state = dataState;
+    } else {
+      _addToken(new ParseErrorToken("unexpected-char-in-doctype"));
+      currentDoctypeToken.correct = false;
+      state = bogusDoctypeState;
+    }
+    return true;
+  }
+
+  bool doctypePublicIdentifierDoubleQuotedState() {
+    var data = stream.char();
+    if (data == '"') {
+      state = afterDoctypePublicIdentifierState;
+    } else if (data == "\u0000") {
+      _addToken(new ParseErrorToken("invalid-codepoint"));
+      currentDoctypeToken.publicId = "${currentDoctypeToken.publicId}\uFFFD";
+    } else if (data == ">") {
+      _addToken(new ParseErrorToken("unexpected-end-of-doctype"));
+      currentDoctypeToken.correct = false;
+      _addToken(currentToken);
+      state = dataState;
+    } else if (data == EOF) {
+      _addToken(new ParseErrorToken("eof-in-doctype"));
+      currentDoctypeToken.correct = false;
+      _addToken(currentToken);
+      state = dataState;
+    } else {
+      currentDoctypeToken.publicId = '${currentDoctypeToken.publicId}$data';
+    }
+    return true;
+  }
+
+  bool doctypePublicIdentifierSingleQuotedState() {
+    var data = stream.char();
+    if (data == "'") {
+      state = afterDoctypePublicIdentifierState;
+    } else if (data == "\u0000") {
+      _addToken(new ParseErrorToken("invalid-codepoint"));
+      currentDoctypeToken.publicId = "${currentDoctypeToken.publicId}\uFFFD";
+    } else if (data == ">") {
+      _addToken(new ParseErrorToken("unexpected-end-of-doctype"));
+      currentDoctypeToken.correct = false;
+      _addToken(currentToken);
+      state = dataState;
+    } else if (data == EOF) {
+      _addToken(new ParseErrorToken("eof-in-doctype"));
+      currentDoctypeToken.correct = false;
+      _addToken(currentToken);
+      state = dataState;
+    } else {
+      currentDoctypeToken.publicId = '${currentDoctypeToken.publicId}$data';
+    }
+    return true;
+  }
+
+  bool afterDoctypePublicIdentifierState() {
+    var data = stream.char();
+    if (isWhitespace(data)) {
+      state = betweenDoctypePublicAndSystemIdentifiersState;
+    } else if (data == ">") {
+      _addToken(currentToken);
+      state = dataState;
+    } else if (data == '"') {
+      _addToken(new ParseErrorToken("unexpected-char-in-doctype"));
+      currentDoctypeToken.systemId = "";
+      state = doctypeSystemIdentifierDoubleQuotedState;
+    } else if (data == "'") {
+      _addToken(new ParseErrorToken("unexpected-char-in-doctype"));
+      currentDoctypeToken.systemId = "";
+      state = doctypeSystemIdentifierSingleQuotedState;
+    } else if (data == EOF) {
+      _addToken(new ParseErrorToken("eof-in-doctype"));
+      currentDoctypeToken.correct = false;
+      _addToken(currentToken);
+      state = dataState;
+    } else {
+      _addToken(new ParseErrorToken("unexpected-char-in-doctype"));
+      currentDoctypeToken.correct = false;
+      state = bogusDoctypeState;
+    }
+    return true;
+  }
+
+  bool betweenDoctypePublicAndSystemIdentifiersState() {
+    var data = stream.char();
+    if (isWhitespace(data)) {
+      return true;
+    } else if (data == ">") {
+      _addToken(currentToken);
+      state = dataState;
+    } else if (data == '"') {
+      currentDoctypeToken.systemId = "";
+      state = doctypeSystemIdentifierDoubleQuotedState;
+    } else if (data == "'") {
+      currentDoctypeToken.systemId = "";
+      state = doctypeSystemIdentifierSingleQuotedState;
+    } else if (data == EOF) {
+      _addToken(new ParseErrorToken("eof-in-doctype"));
+      currentDoctypeToken.correct = false;
+      _addToken(currentToken);
+      state = dataState;
+    } else {
+      _addToken(new ParseErrorToken("unexpected-char-in-doctype"));
+      currentDoctypeToken.correct = false;
+      state = bogusDoctypeState;
+    }
+    return true;
+  }
+
+  bool afterDoctypeSystemKeywordState() {
+    var data = stream.char();
+    if (isWhitespace(data)) {
+      state = beforeDoctypeSystemIdentifierState;
+    } else if (data == "'" || data == '"') {
+      _addToken(new ParseErrorToken("unexpected-char-in-doctype"));
+      stream.unget(data);
+      state = beforeDoctypeSystemIdentifierState;
+    } else if (data == EOF) {
+      _addToken(new ParseErrorToken("eof-in-doctype"));
+      currentDoctypeToken.correct = false;
+      _addToken(currentToken);
+      state = dataState;
+    } else {
+      stream.unget(data);
+      state = beforeDoctypeSystemIdentifierState;
+    }
+    return true;
+  }
+
+  bool beforeDoctypeSystemIdentifierState() {
+    var data = stream.char();
+    if (isWhitespace(data)) {
+      return true;
+    } else if (data == "\"") {
+      currentDoctypeToken.systemId = "";
+      state = doctypeSystemIdentifierDoubleQuotedState;
+    } else if (data == "'") {
+      currentDoctypeToken.systemId = "";
+      state = doctypeSystemIdentifierSingleQuotedState;
+    } else if (data == ">") {
+      _addToken(new ParseErrorToken("unexpected-char-in-doctype"));
+      currentDoctypeToken.correct = false;
+      _addToken(currentToken);
+      state = dataState;
+    } else if (data == EOF) {
+      _addToken(new ParseErrorToken("eof-in-doctype"));
+      currentDoctypeToken.correct = false;
+      _addToken(currentToken);
+      state = dataState;
+    } else {
+      _addToken(new ParseErrorToken("unexpected-char-in-doctype"));
+      currentDoctypeToken.correct = false;
+      state = bogusDoctypeState;
+    }
+    return true;
+  }
+
+  bool doctypeSystemIdentifierDoubleQuotedState() {
+    var data = stream.char();
+    if (data == "\"") {
+      state = afterDoctypeSystemIdentifierState;
+    } else if (data == "\u0000") {
+      _addToken(new ParseErrorToken("invalid-codepoint"));
+      currentDoctypeToken.systemId = "${currentDoctypeToken.systemId}\uFFFD";
+    } else if (data == ">") {
+      _addToken(new ParseErrorToken("unexpected-end-of-doctype"));
+      currentDoctypeToken.correct = false;
+      _addToken(currentToken);
+      state = dataState;
+    } else if (data == EOF) {
+      _addToken(new ParseErrorToken("eof-in-doctype"));
+      currentDoctypeToken.correct = false;
+      _addToken(currentToken);
+      state = dataState;
+    } else {
+      currentDoctypeToken.systemId = '${currentDoctypeToken.systemId}$data';
+    }
+    return true;
+  }
+
+  bool doctypeSystemIdentifierSingleQuotedState() {
+    var data = stream.char();
+    if (data == "'") {
+      state = afterDoctypeSystemIdentifierState;
+    } else if (data == "\u0000") {
+      _addToken(new ParseErrorToken("invalid-codepoint"));
+      currentDoctypeToken.systemId = "${currentDoctypeToken.systemId}\uFFFD";
+    } else if (data == ">") {
+      _addToken(new ParseErrorToken("unexpected-end-of-doctype"));
+      currentDoctypeToken.correct = false;
+      _addToken(currentToken);
+      state = dataState;
+    } else if (data == EOF) {
+      _addToken(new ParseErrorToken("eof-in-doctype"));
+      currentDoctypeToken.correct = false;
+      _addToken(currentToken);
+      state = dataState;
+    } else {
+      currentDoctypeToken.systemId = '${currentDoctypeToken.systemId}$data';
+    }
+    return true;
+  }
+
+  bool afterDoctypeSystemIdentifierState() {
+    var data = stream.char();
+    if (isWhitespace(data)) {
+      return true;
+    } else if (data == ">") {
+      _addToken(currentToken);
+      state = dataState;
+    } else if (data == EOF) {
+      _addToken(new ParseErrorToken("eof-in-doctype"));
+      currentDoctypeToken.correct = false;
+      _addToken(currentToken);
+      state = dataState;
+    } else {
+      _addToken(new ParseErrorToken("unexpected-char-in-doctype"));
+      state = bogusDoctypeState;
+    }
+    return true;
+  }
+
+  bool bogusDoctypeState() {
+    var data = stream.char();
+    if (data == ">") {
+      _addToken(currentToken);
+      state = dataState;
+    } else if (data == EOF) {
+      // XXX EMIT
+      stream.unget(data);
+      _addToken(currentToken);
+      state = dataState;
+    }
+    return true;
+  }
+
+  bool cdataSectionState() {
+    var data = [];
+    int matchedEnd = 0;
+    while (true) {
+      var ch = stream.char();
+      if (ch == EOF) {
+        break;
+      }
+      // Deal with null here rather than in the parser
+      if (ch == "\u0000") {
+        _addToken(new ParseErrorToken("invalid-codepoint"));
+        ch = "\uFFFD";
+      }
+      data.add(ch);
+      // TODO(jmesserly): it'd be nice if we had an easier way to match the end,
+      // perhaps with a "peek" API.
+      if (ch == "]" && matchedEnd < 2) {
+        matchedEnd++;
+      } else if (ch == ">" && matchedEnd == 2) {
+        // Remove "]]>" from the end.
+        data.removeLast();
+        data.removeLast();
+        data.removeLast();
+        break;
+      } else {
+        matchedEnd = 0;
+      }
+    }
+
+    if (data.length > 0) {
+      _addToken(new CharactersToken(data.join()));
+    }
+    state = dataState;
+    return true;
+  }
+}
diff --git a/html/lib/src/treebuilder.dart b/html/lib/src/treebuilder.dart
new file mode 100644
index 0000000..6be687e
--- /dev/null
+++ b/html/lib/src/treebuilder.dart
@@ -0,0 +1,408 @@
+/// Internals to the tree builders.
+library treebuilder;
+
+import 'dart:collection';
+import 'package:html/dom.dart';
+import 'package:html/parser.dart' show getElementNameTuple;
+import 'package:source_span/source_span.dart';
+import 'constants.dart';
+import 'list_proxy.dart';
+import 'token.dart';
+import 'utils.dart';
+
+// The scope markers are inserted when entering object elements,
+// marquees, table cells, and table captions, and are used to prevent formatting
+// from "leaking" into tables, object elements, and marquees.
+const Node Marker = null;
+
+// TODO(jmesserly): this should extend ListBase<Element>, but my simple attempt
+// didn't work.
+class ActiveFormattingElements extends ListProxy<Element> {
+  ActiveFormattingElements() : super();
+
+  // Override the "add" method.
+  // TODO(jmesserly): I'd rather not override this; can we do this in the
+  // calling code instead?
+  void add(Element node) {
+    int equalCount = 0;
+    if (node != Marker) {
+      for (var element in reversed) {
+        if (element == Marker) {
+          break;
+        }
+        if (_nodesEqual(element, node)) {
+          equalCount += 1;
+        }
+        if (equalCount == 3) {
+          remove(element);
+          break;
+        }
+      }
+    }
+    super.add(node);
+  }
+}
+
+// TODO(jmesserly): this should exist in corelib...
+bool _mapEquals(Map a, Map b) {
+  if (a.length != b.length) return false;
+  if (a.length == 0) return true;
+
+  for (var keyA in a.keys) {
+    var valB = b[keyA];
+    if (valB == null && !b.containsKey(keyA)) {
+      return false;
+    }
+
+    if (a[keyA] != valB) {
+      return false;
+    }
+  }
+  return true;
+}
+
+bool _nodesEqual(Element node1, Element node2) {
+  return getElementNameTuple(node1) == getElementNameTuple(node2) &&
+      _mapEquals(node1.attributes, node2.attributes);
+}
+
+/// Basic treebuilder implementation.
+class TreeBuilder {
+  final String defaultNamespace;
+
+  Document document;
+
+  final List<Element> openElements = <Element>[];
+
+  final activeFormattingElements = new ActiveFormattingElements();
+
+  Node headPointer;
+
+  Element formPointer;
+
+  /// Switch the function used to insert an element from the
+  /// normal one to the misnested table one and back again
+  bool insertFromTable;
+
+  TreeBuilder(bool namespaceHTMLElements)
+      : defaultNamespace = namespaceHTMLElements ? Namespaces.html : null {
+    reset();
+  }
+
+  void reset() {
+    openElements.clear();
+    activeFormattingElements.clear();
+
+    //XXX - rename these to headElement, formElement
+    headPointer = null;
+    formPointer = null;
+
+    insertFromTable = false;
+
+    document = new Document();
+  }
+
+  bool elementInScope(target, {String variant}) {
+    //If we pass a node in we match that. if we pass a string
+    //match any node with that name
+    bool exactNode = target is Node;
+
+    List listElements1 = scopingElements;
+    List listElements2 = const [];
+    bool invert = false;
+    if (variant != null) {
+      switch (variant) {
+        case "button":
+          listElements2 = const [const Pair(Namespaces.html, "button")];
+          break;
+        case "list":
+          listElements2 = const [
+            const Pair(Namespaces.html, "ol"),
+            const Pair(Namespaces.html, "ul")
+          ];
+          break;
+        case "table":
+          listElements1 = const [
+            const Pair(Namespaces.html, "html"),
+            const Pair(Namespaces.html, "table")
+          ];
+          break;
+        case "select":
+          listElements1 = const [
+            const Pair(Namespaces.html, "optgroup"),
+            const Pair(Namespaces.html, "option")
+          ];
+          invert = true;
+          break;
+        default:
+          throw new StateError('We should never reach this point');
+      }
+    }
+
+    for (var node in openElements.reversed) {
+      if (!exactNode && node.localName == target ||
+          exactNode && node == target) {
+        return true;
+      } else if (invert !=
+          (listElements1.contains(getElementNameTuple(node)) ||
+              listElements2.contains(getElementNameTuple(node)))) {
+        return false;
+      }
+    }
+
+    throw new StateError('We should never reach this point');
+  }
+
+  void reconstructActiveFormattingElements() {
+    // Within this algorithm the order of steps described in the
+    // specification is not quite the same as the order of steps in the
+    // code. It should still do the same though.
+
+    // Step 1: stop the algorithm when there's nothing to do.
+    if (activeFormattingElements.length == 0) {
+      return;
+    }
+
+    // Step 2 and step 3: we start with the last element. So i is -1.
+    int i = activeFormattingElements.length - 1;
+    var entry = activeFormattingElements[i];
+    if (entry == Marker || openElements.contains(entry)) {
+      return;
+    }
+
+    // Step 6
+    while (entry != Marker && !openElements.contains(entry)) {
+      if (i == 0) {
+        //This will be reset to 0 below
+        i = -1;
+        break;
+      }
+      i -= 1;
+      // Step 5: let entry be one earlier in the list.
+      entry = activeFormattingElements[i];
+    }
+
+    while (true) {
+      // Step 7
+      i += 1;
+
+      // Step 8
+      entry = activeFormattingElements[i];
+
+      // TODO(jmesserly): optimize this. No need to create a token.
+      var cloneToken = new StartTagToken(entry.localName,
+          namespace: entry.namespaceUri,
+          data: new LinkedHashMap.from(entry.attributes))
+        ..span = entry.sourceSpan;
+
+      // Step 9
+      var element = insertElement(cloneToken);
+
+      // Step 10
+      activeFormattingElements[i] = element;
+
+      // Step 11
+      if (element == activeFormattingElements.last) {
+        break;
+      }
+    }
+  }
+
+  void clearActiveFormattingElements() {
+    var entry = activeFormattingElements.removeLast();
+    while (activeFormattingElements.length > 0 && entry != Marker) {
+      entry = activeFormattingElements.removeLast();
+    }
+  }
+
+  /// Check if an element exists between the end of the active
+  /// formatting elements and the last marker. If it does, return it, else
+  /// return null.
+  Element elementInActiveFormattingElements(String name) {
+    for (var item in activeFormattingElements.reversed) {
+      // Check for Marker first because if it's a Marker it doesn't have a
+      // name attribute.
+      if (item == Marker) {
+        break;
+      } else if (item.localName == name) {
+        return item;
+      }
+    }
+    return null;
+  }
+
+  void insertRoot(Token token) {
+    var element = createElement(token);
+    openElements.add(element);
+    document.nodes.add(element);
+  }
+
+  void insertDoctype(DoctypeToken token) {
+    var doctype = new DocumentType(token.name, token.publicId, token.systemId)
+      ..sourceSpan = token.span;
+    document.nodes.add(doctype);
+  }
+
+  void insertComment(StringToken token, [Node parent]) {
+    if (parent == null) {
+      parent = openElements.last;
+    }
+    parent.nodes.add(new Comment(token.data)..sourceSpan = token.span);
+  }
+
+  /// Create an element but don't insert it anywhere
+  Element createElement(StartTagToken token) {
+    var name = token.name;
+    var namespace = token.namespace;
+    if (namespace == null) namespace = defaultNamespace;
+    var element = document.createElementNS(namespace, name)
+      ..attributes = token.data
+      ..sourceSpan = token.span;
+    return element;
+  }
+
+  Element insertElement(StartTagToken token) {
+    if (insertFromTable) return insertElementTable(token);
+    return insertElementNormal(token);
+  }
+
+  Element insertElementNormal(StartTagToken token) {
+    var name = token.name;
+    var namespace = token.namespace;
+    if (namespace == null) namespace = defaultNamespace;
+    var element = document.createElementNS(namespace, name)
+      ..attributes = token.data
+      ..sourceSpan = token.span;
+    openElements.last.nodes.add(element);
+    openElements.add(element);
+    return element;
+  }
+
+  Element insertElementTable(token) {
+    /// Create an element and insert it into the tree
+    var element = createElement(token);
+    if (!tableInsertModeElements.contains(openElements.last.localName)) {
+      return insertElementNormal(token);
+    } else {
+      // We should be in the InTable mode. This means we want to do
+      // special magic element rearranging
+      var nodePos = getTableMisnestedNodePosition();
+      if (nodePos[1] == null) {
+        // TODO(jmesserly): I don't think this is reachable. If insertFromTable
+        // is true, there will be a <table> element open, and it always has a
+        // parent pointer.
+        nodePos[0].nodes.add(element);
+      } else {
+        nodePos[0].insertBefore(element, nodePos[1]);
+      }
+      openElements.add(element);
+    }
+    return element;
+  }
+
+  /// Insert text data.
+  void insertText(String data, FileSpan span) {
+    var parent = openElements.last;
+
+    if (!insertFromTable ||
+        insertFromTable &&
+            !tableInsertModeElements.contains(openElements.last.localName)) {
+      _insertText(parent, data, span);
+    } else {
+      // We should be in the InTable mode. This means we want to do
+      // special magic element rearranging
+      var nodePos = getTableMisnestedNodePosition();
+      _insertText(nodePos[0], data, span, nodePos[1]);
+    }
+  }
+
+  /// Insert [data] as text in the current node, positioned before the
+  /// start of node [refNode] or to the end of the node's text.
+  static void _insertText(Node parent, String data, FileSpan span,
+      [Element refNode]) {
+    var nodes = parent.nodes;
+    if (refNode == null) {
+      if (nodes.length > 0 && nodes.last is Text) {
+        Text last = nodes.last;
+        last.appendData(data);
+
+        if (span != null) {
+          last.sourceSpan =
+              span.file.span(last.sourceSpan.start.offset, span.end.offset);
+        }
+      } else {
+        nodes.add(new Text(data)..sourceSpan = span);
+      }
+    } else {
+      int index = nodes.indexOf(refNode);
+      if (index > 0 && nodes[index - 1] is Text) {
+        Text last = nodes[index - 1];
+        last.appendData(data);
+      } else {
+        nodes.insert(index, new Text(data)..sourceSpan = span);
+      }
+    }
+  }
+
+  /// Get the foster parent element, and sibling to insert before
+  /// (or null) when inserting a misnested table node
+  List<Node> getTableMisnestedNodePosition() {
+    // The foster parent element is the one which comes before the most
+    // recently opened table element
+    // XXX - this is really inelegant
+    Node lastTable = null;
+    Node fosterParent = null;
+    Node insertBefore = null;
+    for (var elm in openElements.reversed) {
+      if (elm.localName == "table") {
+        lastTable = elm;
+        break;
+      }
+    }
+    if (lastTable != null) {
+      // XXX - we should really check that this parent is actually a
+      // node here
+      if (lastTable.parentNode != null) {
+        fosterParent = lastTable.parentNode;
+        insertBefore = lastTable;
+      } else {
+        fosterParent = openElements[openElements.indexOf(lastTable) - 1];
+      }
+    } else {
+      fosterParent = openElements[0];
+    }
+    return [fosterParent, insertBefore];
+  }
+
+  void generateImpliedEndTags([String exclude]) {
+    var name = openElements.last.localName;
+    // XXX td, th and tr are not actually needed
+    if (name != exclude &&
+        const [
+      "dd",
+      "dt",
+      "li",
+      "option",
+      "optgroup",
+      "p",
+      "rp",
+      "rt"
+    ].contains(name)) {
+      openElements.removeLast();
+      // XXX This is not entirely what the specification says. We should
+      // investigate it more closely.
+      generateImpliedEndTags(exclude);
+    }
+  }
+
+  /// Return the final tree.
+  Document getDocument() => document;
+
+  /// Return the final fragment.
+  DocumentFragment getFragment() {
+    //XXX assert innerHTML
+    var fragment = new DocumentFragment();
+    openElements[0].reparentChildren(fragment);
+    return fragment;
+  }
+}
diff --git a/html/lib/src/utils.dart b/html/lib/src/utils.dart
new file mode 100644
index 0000000..16837b0
--- /dev/null
+++ b/html/lib/src/utils.dart
@@ -0,0 +1,123 @@
+/// Misc things that were useful when porting the code from Python.
+library utils;
+
+import 'constants.dart';
+
+typedef bool Predicate();
+
+class Pair<F, S> {
+  final F first;
+  final S second;
+
+  const Pair(this.first, this.second);
+
+  int get hashCode => 37 * first.hashCode + second.hashCode;
+  bool operator ==(other) => other.first == first && other.second == second;
+}
+
+int parseIntRadix(String str, [int radix = 10]) {
+  int val = 0;
+  for (int i = 0; i < str.length; i++) {
+    var digit = str.codeUnitAt(i);
+    if (digit >= LOWER_A) {
+      digit += 10 - LOWER_A;
+    } else if (digit >= UPPER_A) {
+      digit += 10 - UPPER_A;
+    } else {
+      digit -= ZERO;
+    }
+    val = val * radix + digit;
+  }
+  return val;
+}
+
+bool any(List<bool> iterable) => iterable.any((f) => f);
+
+bool startsWithAny(String str, List<String> prefixes) {
+  for (var prefix in prefixes) {
+    if (str.startsWith(prefix)) {
+      return true;
+    }
+  }
+  return false;
+}
+
+// Like the python [:] operator.
+List/*<T>*/ slice/*<T>*/(List/*<T>*/ list, int start, [int end]) {
+  if (end == null) end = list.length;
+  if (end < 0) end += list.length;
+
+  // Ensure the indexes are in bounds.
+  if (end < start) end = start;
+  if (end > list.length) end = list.length;
+  return list.sublist(start, end);
+}
+
+bool allWhitespace(String str) {
+  for (int i = 0; i < str.length; i++) {
+    if (!isWhitespaceCC(str.codeUnitAt(i))) return false;
+  }
+  return true;
+}
+
+String padWithZeros(String str, int size) {
+  if (str.length == size) return str;
+  var result = new StringBuffer();
+  size -= str.length;
+  for (int i = 0; i < size; i++) result.write('0');
+  result.write(str);
+  return result.toString();
+}
+
+// TODO(jmesserly): this implementation is pretty wrong, but I need something
+// quick until dartbug.com/1694 is fixed.
+/// Format a string like Python's % string format operator. Right now this only
+/// supports a [data] dictionary used with %s or %08x. Those were the only
+/// things needed for [errorMessages].
+String formatStr(String format, Map data) {
+  if (data == null) return format;
+  data.forEach((key, value) {
+    var result = new StringBuffer();
+    var search = '%($key)';
+    int last = 0,
+        match;
+    while ((match = format.indexOf(search, last)) >= 0) {
+      result.write(format.substring(last, match));
+      match += search.length;
+
+      int digits = match;
+      while (isDigit(format[digits])) {
+        digits++;
+      }
+      int numberSize;
+      if (digits > match) {
+        numberSize = int.parse(format.substring(match, digits));
+        match = digits;
+      }
+
+      switch (format[match]) {
+        case 's':
+          result.write(value);
+          break;
+        case 'd':
+          var number = value.toString();
+          result.write(padWithZeros(number, numberSize));
+          break;
+        case 'x':
+          var number = value.toRadixString(16);
+          result.write(padWithZeros(number, numberSize));
+          break;
+        default:
+          throw "not implemented: formatStr does not support format "
+              "character ${format[match]}";
+      }
+
+      last = match + 1;
+    }
+
+    result.write(format.substring(last, format.length));
+    format = result.toString();
+  });
+
+  return format;
+}
diff --git a/html/pubspec.yaml b/html/pubspec.yaml
new file mode 100644
index 0000000..cceb1e4
--- /dev/null
+++ b/html/pubspec.yaml
@@ -0,0 +1,14 @@
+name: html
+version: 0.13.1
+author: Dart Team <misc@dartlang.org>
+description: A library for working with HTML documents. Previously known as html5lib.
+homepage: https://github.com/dart-lang/html
+environment:
+  sdk: '>=1.21.0-dev.2.0 <2.0.0'
+dependencies:
+  csslib: '>=0.13.2 <0.14.0'
+  source_span: '>=1.0.0 <2.0.0'
+  utf: '>=0.9.0 <0.10.0'
+dev_dependencies:
+  path: '>=0.9.0 <2.0.0'
+  unittest: '>=0.10.0 <0.12.0'
diff --git a/html/test/data/parser_feature/raw_file.html b/html/test/data/parser_feature/raw_file.html
new file mode 100644
index 0000000..bcdbf76
--- /dev/null
+++ b/html/test/data/parser_feature/raw_file.html
@@ -0,0 +1,6 @@
+<!doctype html>
+<html>
+<body>
+Hello world!
+</body>
+</html>
diff --git a/html/test/data/tokenizer/contentModelFlags.test b/html/test/data/tokenizer/contentModelFlags.test
new file mode 100644
index 0000000..a8b1695
--- /dev/null
+++ b/html/test/data/tokenizer/contentModelFlags.test
@@ -0,0 +1,75 @@
+{"tests": [
+
+{"description":"PLAINTEXT content model flag",
+"initialStates":["PLAINTEXT state"],
+"lastStartTag":"plaintext",
+"input":"<head>&body;",
+"output":[["Character", "<head>&body;"]]},
+
+{"description":"End tag closing RCDATA or RAWTEXT",
+"initialStates":["RCDATA state", "RAWTEXT state"],
+"lastStartTag":"xmp",
+"input":"foo</xmp>",
+"output":[["Character", "foo"], ["EndTag", "xmp"]]},
+
+{"description":"End tag closing RCDATA or RAWTEXT (case-insensitivity)",
+"initialStates":["RCDATA state", "RAWTEXT state"],
+"lastStartTag":"xmp",
+"input":"foo</xMp>",
+"output":[["Character", "foo"], ["EndTag", "xmp"]]},
+
+{"description":"End tag closing RCDATA or RAWTEXT (ending with space)",
+"initialStates":["RCDATA state", "RAWTEXT state"],
+"lastStartTag":"xmp",
+"input":"foo</xmp ",
+"output":[["Character", "foo"], "ParseError"]},
+
+{"description":"End tag closing RCDATA or RAWTEXT (ending with EOF)",
+"initialStates":["RCDATA state", "RAWTEXT state"],
+"lastStartTag":"xmp",
+"input":"foo</xmp",
+"output":[["Character", "foo</xmp"]]},
+
+{"description":"End tag closing RCDATA or RAWTEXT (ending with slash)",
+"initialStates":["RCDATA state", "RAWTEXT state"],
+"lastStartTag":"xmp",
+"input":"foo</xmp/",
+"output":[["Character", "foo"], "ParseError"]},
+
+{"description":"End tag not closing RCDATA or RAWTEXT (ending with left-angle-bracket)",
+"initialStates":["RCDATA state", "RAWTEXT state"],
+"lastStartTag":"xmp",
+"input":"foo</xmp<",
+"output":[["Character", "foo</xmp<"]]},
+
+{"description":"End tag with incorrect name in RCDATA or RAWTEXT",
+"initialStates":["RCDATA state", "RAWTEXT state"],
+"lastStartTag":"xmp",
+"input":"</foo>bar</xmp>",
+"output":[["Character", "</foo>bar"], ["EndTag", "xmp"]]},
+
+{"description":"End tag with incorrect name in RCDATA or RAWTEXT (starting like correct name)",
+"initialStates":["RCDATA state", "RAWTEXT state"],
+"lastStartTag":"xmp",
+"input":"</foo>bar</xmpaar>",
+"output":[["Character", "</foo>bar</xmpaar>"]]},
+
+{"description":"End tag closing RCDATA or RAWTEXT, switching back to PCDATA",
+"initialStates":["RCDATA state", "RAWTEXT state"],
+"lastStartTag":"xmp",
+"input":"foo</xmp></baz>",
+"output":[["Character", "foo"], ["EndTag", "xmp"], ["EndTag", "baz"]]},
+
+{"description":"RAWTEXT w/ something looking like an entity",
+"initialStates":["RAWTEXT state"],
+"lastStartTag":"xmp",
+"input":"&foo;",
+"output":[["Character", "&foo;"]]},
+
+{"description":"RCDATA w/ an entity",
+"initialStates":["RCDATA state"],
+"lastStartTag":"textarea",
+"input":"&lt;",
+"output":[["Character", "<"]]}
+
+]}
diff --git a/html/test/data/tokenizer/domjs.test b/html/test/data/tokenizer/domjs.test
new file mode 100644
index 0000000..74771e2
--- /dev/null
+++ b/html/test/data/tokenizer/domjs.test
@@ -0,0 +1,90 @@
+{
+    "tests": [
+        {
+            "description":"CR in bogus comment state",
+            "input":"<?\u000d",
+            "output":["ParseError", ["Comment", "?\u000a"]]
+        },
+        {
+            "description":"CRLF in bogus comment state",
+            "input":"<?\u000d\u000a",
+            "output":["ParseError", ["Comment", "?\u000a"]]
+        },
+        {
+            "description":"NUL in RCDATA and RAWTEXT",
+            "doubleEscaped":true,
+            "initialStates":["RCDATA state", "RAWTEXT state"],
+            "input":"\\u0000",
+            "output":["ParseError", ["Character", "\\uFFFD"]]
+        },
+        {
+            "description":"skip first BOM but not later ones",
+            "input":"\uFEFFfoo\uFEFFbar",
+            "output":[["Character", "foo\uFEFFbar"]]
+        },
+        {
+            "description":"Non BMP-charref in in RCDATA",
+            "initialStates":["RCDATA state"],
+            "input":"&NotEqualTilde;",
+            "output":[["Character", "\u2242\u0338"]]
+        },
+        {
+            "description":"Bad charref in in RCDATA",
+            "initialStates":["RCDATA state"],
+            "input":"&NotEqualTild;",
+            "output":["ParseError", ["Character", "&NotEqualTild;"]]
+        },
+        {
+            "description":"lowercase endtags in RCDATA and RAWTEXT",
+            "initialStates":["RCDATA state", "RAWTEXT state"],
+            "lastStartTag":"xmp",
+            "input":"</XMP>",
+            "output":[["EndTag","xmp"]]
+        },
+        {
+            "description":"bad endtag in RCDATA and RAWTEXT",
+            "initialStates":["RCDATA state", "RAWTEXT state"],
+            "lastStartTag":"xmp",
+            "input":"</ XMP>",
+            "output":[["Character","</ XMP>"]]
+        },
+        {
+            "description":"bad endtag in RCDATA and RAWTEXT",
+            "initialStates":["RCDATA state", "RAWTEXT state"],
+            "lastStartTag":"xmp",
+            "input":"</xm>",
+            "output":[["Character","</xm>"]]
+        },
+        {
+            "description":"bad endtag in RCDATA and RAWTEXT",
+            "initialStates":["RCDATA state", "RAWTEXT state"],
+            "lastStartTag":"xmp",
+            "input":"</xm ",
+            "output":[["Character","</xm "]]
+        },
+        {
+            "description":"bad endtag in RCDATA and RAWTEXT",
+            "initialStates":["RCDATA state", "RAWTEXT state"],
+            "lastStartTag":"xmp",
+            "input":"</xm/",
+            "output":[["Character","</xm/"]]
+        },
+        {
+            "description":"Non BMP-charref in attribute",
+            "input":"<p id=\"&NotEqualTilde;\">",
+            "output":[["StartTag", "p", {"id":"\u2242\u0338"}]]
+        },
+        {
+            "description":"--!NUL in comment ",
+            "doubleEscaped":true,
+            "input":"<!----!\\u0000-->",
+            "output":["ParseError", ["Comment", "--!\\uFFFD"]]
+        },
+        {
+            "description":"space EOF after doctype ",
+            "input":"<!DOCTYPE html ",
+            "output":["ParseError", ["DOCTYPE", "html", null, null , false]]
+        }
+
+    ]
+}
diff --git a/html/test/data/tokenizer/entities.test b/html/test/data/tokenizer/entities.test
new file mode 100644
index 0000000..1cb17a7
--- /dev/null
+++ b/html/test/data/tokenizer/entities.test
@@ -0,0 +1,283 @@
+{"tests": [
+
+{"description": "Undefined named entity in attribute value ending in semicolon and whose name starts with a known entity name.",
+"input":"<h a='&noti;'>",
+"output": ["ParseError", ["StartTag", "h", {"a": "&noti;"}]]},
+
+{"description": "Entity name followed by the equals sign in an attribute value.",
+"input":"<h a='&lang='>",
+"output": ["ParseError", ["StartTag", "h", {"a": "&lang="}]]},
+
+{"description": "CR as numeric entity",
+"input":"&#013;",
+"output": ["ParseError", ["Character", "\r"]]},
+
+{"description": "CR as hexadecimal numeric entity",
+"input":"&#x00D;",
+"output": ["ParseError", ["Character", "\r"]]},
+
+{"description": "Windows-1252 EURO SIGN numeric entity.",
+"input":"&#0128;",
+"output": ["ParseError", ["Character", "\u20AC"]]},
+
+{"description": "Windows-1252 REPLACEMENT CHAR numeric entity.",
+"input":"&#0129;",
+"output": ["ParseError", ["Character", "\u0081"]]},
+
+{"description": "Windows-1252 SINGLE LOW-9 QUOTATION MARK numeric entity.",
+"input":"&#0130;",
+"output": ["ParseError", ["Character", "\u201A"]]},
+
+{"description": "Windows-1252 LATIN SMALL LETTER F WITH HOOK numeric entity.",
+"input":"&#0131;",
+"output": ["ParseError", ["Character", "\u0192"]]},
+
+{"description": "Windows-1252 DOUBLE LOW-9 QUOTATION MARK numeric entity.",
+"input":"&#0132;",
+"output": ["ParseError", ["Character", "\u201E"]]},
+
+{"description": "Windows-1252 HORIZONTAL ELLIPSIS numeric entity.",
+"input":"&#0133;",
+"output": ["ParseError", ["Character", "\u2026"]]},
+
+{"description": "Windows-1252 DAGGER numeric entity.",
+"input":"&#0134;",
+"output": ["ParseError", ["Character", "\u2020"]]},
+
+{"description": "Windows-1252 DOUBLE DAGGER numeric entity.",
+"input":"&#0135;",
+"output": ["ParseError", ["Character", "\u2021"]]},
+
+{"description": "Windows-1252 MODIFIER LETTER CIRCUMFLEX ACCENT numeric entity.",
+"input":"&#0136;",
+"output": ["ParseError", ["Character", "\u02C6"]]},
+
+{"description": "Windows-1252 PER MILLE SIGN numeric entity.",
+"input":"&#0137;",
+"output": ["ParseError", ["Character", "\u2030"]]},
+
+{"description": "Windows-1252 LATIN CAPITAL LETTER S WITH CARON numeric entity.",
+"input":"&#0138;",
+"output": ["ParseError", ["Character", "\u0160"]]},
+
+{"description": "Windows-1252 SINGLE LEFT-POINTING ANGLE QUOTATION MARK numeric entity.",
+"input":"&#0139;",
+"output": ["ParseError", ["Character", "\u2039"]]},
+
+{"description": "Windows-1252 LATIN CAPITAL LIGATURE OE numeric entity.",
+"input":"&#0140;",
+"output": ["ParseError", ["Character", "\u0152"]]},
+
+{"description": "Windows-1252 REPLACEMENT CHAR numeric entity.",
+"input":"&#0141;",
+"output": ["ParseError", ["Character", "\u008D"]]},
+
+{"description": "Windows-1252 LATIN CAPITAL LETTER Z WITH CARON numeric entity.",
+"input":"&#0142;",
+"output": ["ParseError", ["Character", "\u017D"]]},
+
+{"description": "Windows-1252 REPLACEMENT CHAR numeric entity.",
+"input":"&#0143;",
+"output": ["ParseError", ["Character", "\u008F"]]},
+
+{"description": "Windows-1252 REPLACEMENT CHAR numeric entity.",
+"input":"&#0144;",
+"output": ["ParseError", ["Character", "\u0090"]]},
+
+{"description": "Windows-1252 LEFT SINGLE QUOTATION MARK numeric entity.",
+"input":"&#0145;",
+"output": ["ParseError", ["Character", "\u2018"]]},
+
+{"description": "Windows-1252 RIGHT SINGLE QUOTATION MARK numeric entity.",
+"input":"&#0146;",
+"output": ["ParseError", ["Character", "\u2019"]]},
+
+{"description": "Windows-1252 LEFT DOUBLE QUOTATION MARK numeric entity.",
+"input":"&#0147;",
+"output": ["ParseError", ["Character", "\u201C"]]},
+
+{"description": "Windows-1252 RIGHT DOUBLE QUOTATION MARK numeric entity.",
+"input":"&#0148;",
+"output": ["ParseError", ["Character", "\u201D"]]},
+
+{"description": "Windows-1252 BULLET numeric entity.",
+"input":"&#0149;",
+"output": ["ParseError", ["Character", "\u2022"]]},
+
+{"description": "Windows-1252 EN DASH numeric entity.",
+"input":"&#0150;",
+"output": ["ParseError", ["Character", "\u2013"]]},
+
+{"description": "Windows-1252 EM DASH numeric entity.",
+"input":"&#0151;",
+"output": ["ParseError", ["Character", "\u2014"]]},
+
+{"description": "Windows-1252 SMALL TILDE numeric entity.",
+"input":"&#0152;",
+"output": ["ParseError", ["Character", "\u02DC"]]},
+
+{"description": "Windows-1252 TRADE MARK SIGN numeric entity.",
+"input":"&#0153;",
+"output": ["ParseError", ["Character", "\u2122"]]},
+
+{"description": "Windows-1252 LATIN SMALL LETTER S WITH CARON numeric entity.",
+"input":"&#0154;",
+"output": ["ParseError", ["Character", "\u0161"]]},
+
+{"description": "Windows-1252 SINGLE RIGHT-POINTING ANGLE QUOTATION MARK numeric entity.",
+"input":"&#0155;",
+"output": ["ParseError", ["Character", "\u203A"]]},
+
+{"description": "Windows-1252 LATIN SMALL LIGATURE OE numeric entity.",
+"input":"&#0156;",
+"output": ["ParseError", ["Character", "\u0153"]]},
+
+{"description": "Windows-1252 REPLACEMENT CHAR numeric entity.",
+"input":"&#0157;",
+"output": ["ParseError", ["Character", "\u009D"]]},
+
+{"description": "Windows-1252 EURO SIGN hexadecimal numeric entity.",
+"input":"&#x080;",
+"output": ["ParseError", ["Character", "\u20AC"]]},
+
+{"description": "Windows-1252 REPLACEMENT CHAR hexadecimal numeric entity.",
+"input":"&#x081;",
+"output": ["ParseError", ["Character", "\u0081"]]},
+
+{"description": "Windows-1252 SINGLE LOW-9 QUOTATION MARK hexadecimal numeric entity.",
+"input":"&#x082;",
+"output": ["ParseError", ["Character", "\u201A"]]},
+
+{"description": "Windows-1252 LATIN SMALL LETTER F WITH HOOK hexadecimal numeric entity.",
+"input":"&#x083;",
+"output": ["ParseError", ["Character", "\u0192"]]},
+
+{"description": "Windows-1252 DOUBLE LOW-9 QUOTATION MARK hexadecimal numeric entity.",
+"input":"&#x084;",
+"output": ["ParseError", ["Character", "\u201E"]]},
+
+{"description": "Windows-1252 HORIZONTAL ELLIPSIS hexadecimal numeric entity.",
+"input":"&#x085;",
+"output": ["ParseError", ["Character", "\u2026"]]},
+
+{"description": "Windows-1252 DAGGER hexadecimal numeric entity.",
+"input":"&#x086;",
+"output": ["ParseError", ["Character", "\u2020"]]},
+
+{"description": "Windows-1252 DOUBLE DAGGER hexadecimal numeric entity.",
+"input":"&#x087;",
+"output": ["ParseError", ["Character", "\u2021"]]},
+
+{"description": "Windows-1252 MODIFIER LETTER CIRCUMFLEX ACCENT hexadecimal numeric entity.",
+"input":"&#x088;",
+"output": ["ParseError", ["Character", "\u02C6"]]},
+
+{"description": "Windows-1252 PER MILLE SIGN hexadecimal numeric entity.",
+"input":"&#x089;",
+"output": ["ParseError", ["Character", "\u2030"]]},
+
+{"description": "Windows-1252 LATIN CAPITAL LETTER S WITH CARON hexadecimal numeric entity.",
+"input":"&#x08A;",
+"output": ["ParseError", ["Character", "\u0160"]]},
+
+{"description": "Windows-1252 SINGLE LEFT-POINTING ANGLE QUOTATION MARK hexadecimal numeric entity.",
+"input":"&#x08B;",
+"output": ["ParseError", ["Character", "\u2039"]]},
+
+{"description": "Windows-1252 LATIN CAPITAL LIGATURE OE hexadecimal numeric entity.",
+"input":"&#x08C;",
+"output": ["ParseError", ["Character", "\u0152"]]},
+
+{"description": "Windows-1252 REPLACEMENT CHAR hexadecimal numeric entity.",
+"input":"&#x08D;",
+"output": ["ParseError", ["Character", "\u008D"]]},
+
+{"description": "Windows-1252 LATIN CAPITAL LETTER Z WITH CARON hexadecimal numeric entity.",
+"input":"&#x08E;",
+"output": ["ParseError", ["Character", "\u017D"]]},
+
+{"description": "Windows-1252 REPLACEMENT CHAR hexadecimal numeric entity.",
+"input":"&#x08F;",
+"output": ["ParseError", ["Character", "\u008F"]]},
+
+{"description": "Windows-1252 REPLACEMENT CHAR hexadecimal numeric entity.",
+"input":"&#x090;",
+"output": ["ParseError", ["Character", "\u0090"]]},
+
+{"description": "Windows-1252 LEFT SINGLE QUOTATION MARK hexadecimal numeric entity.",
+"input":"&#x091;",
+"output": ["ParseError", ["Character", "\u2018"]]},
+
+{"description": "Windows-1252 RIGHT SINGLE QUOTATION MARK hexadecimal numeric entity.",
+"input":"&#x092;",
+"output": ["ParseError", ["Character", "\u2019"]]},
+
+{"description": "Windows-1252 LEFT DOUBLE QUOTATION MARK hexadecimal numeric entity.",
+"input":"&#x093;",
+"output": ["ParseError", ["Character", "\u201C"]]},
+
+{"description": "Windows-1252 RIGHT DOUBLE QUOTATION MARK hexadecimal numeric entity.",
+"input":"&#x094;",
+"output": ["ParseError", ["Character", "\u201D"]]},
+
+{"description": "Windows-1252 BULLET hexadecimal numeric entity.",
+"input":"&#x095;",
+"output": ["ParseError", ["Character", "\u2022"]]},
+
+{"description": "Windows-1252 EN DASH hexadecimal numeric entity.",
+"input":"&#x096;",
+"output": ["ParseError", ["Character", "\u2013"]]},
+
+{"description": "Windows-1252 EM DASH hexadecimal numeric entity.",
+"input":"&#x097;",
+"output": ["ParseError", ["Character", "\u2014"]]},
+
+{"description": "Windows-1252 SMALL TILDE hexadecimal numeric entity.",
+"input":"&#x098;",
+"output": ["ParseError", ["Character", "\u02DC"]]},
+
+{"description": "Windows-1252 TRADE MARK SIGN hexadecimal numeric entity.",
+"input":"&#x099;",
+"output": ["ParseError", ["Character", "\u2122"]]},
+
+{"description": "Windows-1252 LATIN SMALL LETTER S WITH CARON hexadecimal numeric entity.",
+"input":"&#x09A;",
+"output": ["ParseError", ["Character", "\u0161"]]},
+
+{"description": "Windows-1252 SINGLE RIGHT-POINTING ANGLE QUOTATION MARK hexadecimal numeric entity.",
+"input":"&#x09B;",
+"output": ["ParseError", ["Character", "\u203A"]]},
+
+{"description": "Windows-1252 LATIN SMALL LIGATURE OE hexadecimal numeric entity.",
+"input":"&#x09C;",
+"output": ["ParseError", ["Character", "\u0153"]]},
+
+{"description": "Windows-1252 REPLACEMENT CHAR hexadecimal numeric entity.",
+"input":"&#x09D;",
+"output": ["ParseError", ["Character", "\u009D"]]},
+
+{"description": "Windows-1252 LATIN SMALL LETTER Z WITH CARON hexadecimal numeric entity.",
+"input":"&#x09E;",
+"output": ["ParseError", ["Character", "\u017E"]]},
+
+{"description": "Windows-1252 LATIN CAPITAL LETTER Y WITH DIAERESIS hexadecimal numeric entity.",
+"input":"&#x09F;",
+"output": ["ParseError", ["Character", "\u0178"]]},
+
+{"description": "Decimal numeric entity followed by hex character a.",
+"input":"&#97a",
+"output": ["ParseError", ["Character", "aa"]]},
+
+{"description": "Decimal numeric entity followed by hex character A.",
+"input":"&#97A",
+"output": ["ParseError", ["Character", "aA"]]},
+
+{"description": "Decimal numeric entity followed by hex character f.",
+"input":"&#97f",
+"output": ["ParseError", ["Character", "af"]]},
+
+{"description": "Decimal numeric entity followed by hex character A.",
+"input":"&#97F",
+"output": ["ParseError", ["Character", "aF"]]}
+
+]}
diff --git a/html/test/data/tokenizer/escapeFlag.test b/html/test/data/tokenizer/escapeFlag.test
new file mode 100644
index 0000000..18cb430
--- /dev/null
+++ b/html/test/data/tokenizer/escapeFlag.test
@@ -0,0 +1,33 @@
+{"tests": [
+
+{"description":"Commented close tag in RCDATA or RAWTEXT",
+"initialStates":["RCDATA state", "RAWTEXT state"],
+"lastStartTag":"xmp",
+"input":"foo<!--</xmp>--></xmp>",
+"output":[["Character", "foo<!--"], ["EndTag", "xmp"], ["Character", "-->"], ["EndTag", "xmp"]]},
+
+{"description":"Bogus comment in RCDATA or RAWTEXT",
+"initialStates":["RCDATA state", "RAWTEXT state"],
+"lastStartTag":"xmp",
+"input":"foo<!-->baz</xmp>",
+"output":[["Character", "foo<!-->baz"], ["EndTag", "xmp"]]},
+
+{"description":"End tag surrounded by bogus comment in RCDATA or RAWTEXT",
+"initialStates":["RCDATA state", "RAWTEXT state"],
+"lastStartTag":"xmp",
+"input":"foo<!--></xmp><!-->baz</xmp>",
+"output":[["Character", "foo<!-->"], ["EndTag", "xmp"], "ParseError", ["Comment", ""], ["Character", "baz"], ["EndTag", "xmp"]]},
+
+{"description":"Commented entities in RCDATA",
+"initialStates":["RCDATA state"],
+"lastStartTag":"xmp",
+"input":" &amp; <!-- &amp; --> &amp; </xmp>",
+"output":[["Character", " & <!-- & --> & "], ["EndTag", "xmp"]]},
+
+{"description":"Incorrect comment ending sequences in RCDATA or RAWTEXT",
+"initialStates":["RCDATA state", "RAWTEXT state"],
+"lastStartTag":"xmp",
+"input":"foo<!-- x --x>x-- >x--!>x--<></xmp>",
+"output":[["Character", "foo<!-- x --x>x-- >x--!>x--<>"], ["EndTag", "xmp"]]}
+
+]}
diff --git a/html/test/data/tokenizer/namedEntities.test b/html/test/data/tokenizer/namedEntities.test
new file mode 100644
index 0000000..4a51c9c
--- /dev/null
+++ b/html/test/data/tokenizer/namedEntities.test
@@ -0,0 +1,44189 @@
+{
+    "tests": [
+        {
+            "input": "&AElig", 
+            "description": "Named entity: AElig without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "\u00c6"
+                ]
+            ]
+        }, 
+        {
+            "input": "&AElig;", 
+            "description": "Named entity: AElig; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u00c6"
+                ]
+            ]
+        }, 
+        {
+            "input": "&AMP", 
+            "description": "Named entity: AMP without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&"
+                ]
+            ]
+        }, 
+        {
+            "input": "&AMP;", 
+            "description": "Named entity: AMP; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "&"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Aacute", 
+            "description": "Named entity: Aacute without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "\u00c1"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Aacute;", 
+            "description": "Named entity: Aacute; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u00c1"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Abreve", 
+            "description": "Bad named entity: Abreve without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&Abreve"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Abreve;", 
+            "description": "Named entity: Abreve; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u0102"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Acirc", 
+            "description": "Named entity: Acirc without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "\u00c2"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Acirc;", 
+            "description": "Named entity: Acirc; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u00c2"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Acy", 
+            "description": "Bad named entity: Acy without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&Acy"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Acy;", 
+            "description": "Named entity: Acy; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u0410"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Afr", 
+            "description": "Bad named entity: Afr without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&Afr"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Afr;", 
+            "description": "Named entity: Afr; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\ud835\udd04"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Agrave", 
+            "description": "Named entity: Agrave without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "\u00c0"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Agrave;", 
+            "description": "Named entity: Agrave; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u00c0"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Alpha", 
+            "description": "Bad named entity: Alpha without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&Alpha"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Alpha;", 
+            "description": "Named entity: Alpha; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u0391"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Amacr", 
+            "description": "Bad named entity: Amacr without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&Amacr"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Amacr;", 
+            "description": "Named entity: Amacr; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u0100"
+                ]
+            ]
+        }, 
+        {
+            "input": "&And", 
+            "description": "Bad named entity: And without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&And"
+                ]
+            ]
+        }, 
+        {
+            "input": "&And;", 
+            "description": "Named entity: And; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2a53"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Aogon", 
+            "description": "Bad named entity: Aogon without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&Aogon"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Aogon;", 
+            "description": "Named entity: Aogon; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u0104"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Aopf", 
+            "description": "Bad named entity: Aopf without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&Aopf"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Aopf;", 
+            "description": "Named entity: Aopf; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\ud835\udd38"
+                ]
+            ]
+        }, 
+        {
+            "input": "&ApplyFunction", 
+            "description": "Bad named entity: ApplyFunction without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&ApplyFunction"
+                ]
+            ]
+        }, 
+        {
+            "input": "&ApplyFunction;", 
+            "description": "Named entity: ApplyFunction; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2061"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Aring", 
+            "description": "Named entity: Aring without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "\u00c5"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Aring;", 
+            "description": "Named entity: Aring; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u00c5"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Ascr", 
+            "description": "Bad named entity: Ascr without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&Ascr"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Ascr;", 
+            "description": "Named entity: Ascr; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\ud835\udc9c"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Assign", 
+            "description": "Bad named entity: Assign without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&Assign"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Assign;", 
+            "description": "Named entity: Assign; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2254"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Atilde", 
+            "description": "Named entity: Atilde without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "\u00c3"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Atilde;", 
+            "description": "Named entity: Atilde; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u00c3"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Auml", 
+            "description": "Named entity: Auml without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "\u00c4"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Auml;", 
+            "description": "Named entity: Auml; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u00c4"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Backslash", 
+            "description": "Bad named entity: Backslash without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&Backslash"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Backslash;", 
+            "description": "Named entity: Backslash; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2216"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Barv", 
+            "description": "Bad named entity: Barv without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&Barv"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Barv;", 
+            "description": "Named entity: Barv; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2ae7"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Barwed", 
+            "description": "Bad named entity: Barwed without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&Barwed"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Barwed;", 
+            "description": "Named entity: Barwed; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2306"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Bcy", 
+            "description": "Bad named entity: Bcy without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&Bcy"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Bcy;", 
+            "description": "Named entity: Bcy; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u0411"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Because", 
+            "description": "Bad named entity: Because without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&Because"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Because;", 
+            "description": "Named entity: Because; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2235"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Bernoullis", 
+            "description": "Bad named entity: Bernoullis without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&Bernoullis"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Bernoullis;", 
+            "description": "Named entity: Bernoullis; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u212c"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Beta", 
+            "description": "Bad named entity: Beta without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&Beta"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Beta;", 
+            "description": "Named entity: Beta; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u0392"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Bfr", 
+            "description": "Bad named entity: Bfr without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&Bfr"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Bfr;", 
+            "description": "Named entity: Bfr; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\ud835\udd05"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Bopf", 
+            "description": "Bad named entity: Bopf without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&Bopf"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Bopf;", 
+            "description": "Named entity: Bopf; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\ud835\udd39"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Breve", 
+            "description": "Bad named entity: Breve without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&Breve"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Breve;", 
+            "description": "Named entity: Breve; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u02d8"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Bscr", 
+            "description": "Bad named entity: Bscr without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&Bscr"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Bscr;", 
+            "description": "Named entity: Bscr; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u212c"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Bumpeq", 
+            "description": "Bad named entity: Bumpeq without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&Bumpeq"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Bumpeq;", 
+            "description": "Named entity: Bumpeq; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u224e"
+                ]
+            ]
+        }, 
+        {
+            "input": "&CHcy", 
+            "description": "Bad named entity: CHcy without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&CHcy"
+                ]
+            ]
+        }, 
+        {
+            "input": "&CHcy;", 
+            "description": "Named entity: CHcy; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u0427"
+                ]
+            ]
+        }, 
+        {
+            "input": "&COPY", 
+            "description": "Named entity: COPY without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "\u00a9"
+                ]
+            ]
+        }, 
+        {
+            "input": "&COPY;", 
+            "description": "Named entity: COPY; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u00a9"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Cacute", 
+            "description": "Bad named entity: Cacute without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&Cacute"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Cacute;", 
+            "description": "Named entity: Cacute; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u0106"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Cap", 
+            "description": "Bad named entity: Cap without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&Cap"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Cap;", 
+            "description": "Named entity: Cap; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u22d2"
+                ]
+            ]
+        }, 
+        {
+            "input": "&CapitalDifferentialD", 
+            "description": "Bad named entity: CapitalDifferentialD without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&CapitalDifferentialD"
+                ]
+            ]
+        }, 
+        {
+            "input": "&CapitalDifferentialD;", 
+            "description": "Named entity: CapitalDifferentialD; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2145"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Cayleys", 
+            "description": "Bad named entity: Cayleys without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&Cayleys"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Cayleys;", 
+            "description": "Named entity: Cayleys; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u212d"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Ccaron", 
+            "description": "Bad named entity: Ccaron without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&Ccaron"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Ccaron;", 
+            "description": "Named entity: Ccaron; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u010c"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Ccedil", 
+            "description": "Named entity: Ccedil without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "\u00c7"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Ccedil;", 
+            "description": "Named entity: Ccedil; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u00c7"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Ccirc", 
+            "description": "Bad named entity: Ccirc without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&Ccirc"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Ccirc;", 
+            "description": "Named entity: Ccirc; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u0108"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Cconint", 
+            "description": "Bad named entity: Cconint without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&Cconint"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Cconint;", 
+            "description": "Named entity: Cconint; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2230"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Cdot", 
+            "description": "Bad named entity: Cdot without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&Cdot"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Cdot;", 
+            "description": "Named entity: Cdot; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u010a"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Cedilla", 
+            "description": "Bad named entity: Cedilla without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&Cedilla"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Cedilla;", 
+            "description": "Named entity: Cedilla; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u00b8"
+                ]
+            ]
+        }, 
+        {
+            "input": "&CenterDot", 
+            "description": "Bad named entity: CenterDot without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&CenterDot"
+                ]
+            ]
+        }, 
+        {
+            "input": "&CenterDot;", 
+            "description": "Named entity: CenterDot; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u00b7"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Cfr", 
+            "description": "Bad named entity: Cfr without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&Cfr"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Cfr;", 
+            "description": "Named entity: Cfr; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u212d"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Chi", 
+            "description": "Bad named entity: Chi without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&Chi"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Chi;", 
+            "description": "Named entity: Chi; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u03a7"
+                ]
+            ]
+        }, 
+        {
+            "input": "&CircleDot", 
+            "description": "Bad named entity: CircleDot without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&CircleDot"
+                ]
+            ]
+        }, 
+        {
+            "input": "&CircleDot;", 
+            "description": "Named entity: CircleDot; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2299"
+                ]
+            ]
+        }, 
+        {
+            "input": "&CircleMinus", 
+            "description": "Bad named entity: CircleMinus without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&CircleMinus"
+                ]
+            ]
+        }, 
+        {
+            "input": "&CircleMinus;", 
+            "description": "Named entity: CircleMinus; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2296"
+                ]
+            ]
+        }, 
+        {
+            "input": "&CirclePlus", 
+            "description": "Bad named entity: CirclePlus without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&CirclePlus"
+                ]
+            ]
+        }, 
+        {
+            "input": "&CirclePlus;", 
+            "description": "Named entity: CirclePlus; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2295"
+                ]
+            ]
+        }, 
+        {
+            "input": "&CircleTimes", 
+            "description": "Bad named entity: CircleTimes without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&CircleTimes"
+                ]
+            ]
+        }, 
+        {
+            "input": "&CircleTimes;", 
+            "description": "Named entity: CircleTimes; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2297"
+                ]
+            ]
+        }, 
+        {
+            "input": "&ClockwiseContourIntegral", 
+            "description": "Bad named entity: ClockwiseContourIntegral without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&ClockwiseContourIntegral"
+                ]
+            ]
+        }, 
+        {
+            "input": "&ClockwiseContourIntegral;", 
+            "description": "Named entity: ClockwiseContourIntegral; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2232"
+                ]
+            ]
+        }, 
+        {
+            "input": "&CloseCurlyDoubleQuote", 
+            "description": "Bad named entity: CloseCurlyDoubleQuote without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&CloseCurlyDoubleQuote"
+                ]
+            ]
+        }, 
+        {
+            "input": "&CloseCurlyDoubleQuote;", 
+            "description": "Named entity: CloseCurlyDoubleQuote; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u201d"
+                ]
+            ]
+        }, 
+        {
+            "input": "&CloseCurlyQuote", 
+            "description": "Bad named entity: CloseCurlyQuote without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&CloseCurlyQuote"
+                ]
+            ]
+        }, 
+        {
+            "input": "&CloseCurlyQuote;", 
+            "description": "Named entity: CloseCurlyQuote; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2019"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Colon", 
+            "description": "Bad named entity: Colon without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&Colon"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Colon;", 
+            "description": "Named entity: Colon; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2237"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Colone", 
+            "description": "Bad named entity: Colone without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&Colone"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Colone;", 
+            "description": "Named entity: Colone; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2a74"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Congruent", 
+            "description": "Bad named entity: Congruent without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&Congruent"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Congruent;", 
+            "description": "Named entity: Congruent; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2261"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Conint", 
+            "description": "Bad named entity: Conint without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&Conint"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Conint;", 
+            "description": "Named entity: Conint; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u222f"
+                ]
+            ]
+        }, 
+        {
+            "input": "&ContourIntegral", 
+            "description": "Bad named entity: ContourIntegral without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&ContourIntegral"
+                ]
+            ]
+        }, 
+        {
+            "input": "&ContourIntegral;", 
+            "description": "Named entity: ContourIntegral; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u222e"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Copf", 
+            "description": "Bad named entity: Copf without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&Copf"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Copf;", 
+            "description": "Named entity: Copf; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2102"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Coproduct", 
+            "description": "Bad named entity: Coproduct without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&Coproduct"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Coproduct;", 
+            "description": "Named entity: Coproduct; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2210"
+                ]
+            ]
+        }, 
+        {
+            "input": "&CounterClockwiseContourIntegral", 
+            "description": "Bad named entity: CounterClockwiseContourIntegral without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&CounterClockwiseContourIntegral"
+                ]
+            ]
+        }, 
+        {
+            "input": "&CounterClockwiseContourIntegral;", 
+            "description": "Named entity: CounterClockwiseContourIntegral; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2233"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Cross", 
+            "description": "Bad named entity: Cross without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&Cross"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Cross;", 
+            "description": "Named entity: Cross; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2a2f"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Cscr", 
+            "description": "Bad named entity: Cscr without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&Cscr"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Cscr;", 
+            "description": "Named entity: Cscr; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\ud835\udc9e"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Cup", 
+            "description": "Bad named entity: Cup without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&Cup"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Cup;", 
+            "description": "Named entity: Cup; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u22d3"
+                ]
+            ]
+        }, 
+        {
+            "input": "&CupCap", 
+            "description": "Bad named entity: CupCap without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&CupCap"
+                ]
+            ]
+        }, 
+        {
+            "input": "&CupCap;", 
+            "description": "Named entity: CupCap; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u224d"
+                ]
+            ]
+        }, 
+        {
+            "input": "&DD", 
+            "description": "Bad named entity: DD without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&DD"
+                ]
+            ]
+        }, 
+        {
+            "input": "&DD;", 
+            "description": "Named entity: DD; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2145"
+                ]
+            ]
+        }, 
+        {
+            "input": "&DDotrahd", 
+            "description": "Bad named entity: DDotrahd without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&DDotrahd"
+                ]
+            ]
+        }, 
+        {
+            "input": "&DDotrahd;", 
+            "description": "Named entity: DDotrahd; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2911"
+                ]
+            ]
+        }, 
+        {
+            "input": "&DJcy", 
+            "description": "Bad named entity: DJcy without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&DJcy"
+                ]
+            ]
+        }, 
+        {
+            "input": "&DJcy;", 
+            "description": "Named entity: DJcy; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u0402"
+                ]
+            ]
+        }, 
+        {
+            "input": "&DScy", 
+            "description": "Bad named entity: DScy without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&DScy"
+                ]
+            ]
+        }, 
+        {
+            "input": "&DScy;", 
+            "description": "Named entity: DScy; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u0405"
+                ]
+            ]
+        }, 
+        {
+            "input": "&DZcy", 
+            "description": "Bad named entity: DZcy without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&DZcy"
+                ]
+            ]
+        }, 
+        {
+            "input": "&DZcy;", 
+            "description": "Named entity: DZcy; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u040f"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Dagger", 
+            "description": "Bad named entity: Dagger without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&Dagger"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Dagger;", 
+            "description": "Named entity: Dagger; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2021"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Darr", 
+            "description": "Bad named entity: Darr without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&Darr"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Darr;", 
+            "description": "Named entity: Darr; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u21a1"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Dashv", 
+            "description": "Bad named entity: Dashv without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&Dashv"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Dashv;", 
+            "description": "Named entity: Dashv; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2ae4"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Dcaron", 
+            "description": "Bad named entity: Dcaron without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&Dcaron"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Dcaron;", 
+            "description": "Named entity: Dcaron; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u010e"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Dcy", 
+            "description": "Bad named entity: Dcy without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&Dcy"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Dcy;", 
+            "description": "Named entity: Dcy; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u0414"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Del", 
+            "description": "Bad named entity: Del without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&Del"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Del;", 
+            "description": "Named entity: Del; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2207"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Delta", 
+            "description": "Bad named entity: Delta without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&Delta"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Delta;", 
+            "description": "Named entity: Delta; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u0394"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Dfr", 
+            "description": "Bad named entity: Dfr without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&Dfr"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Dfr;", 
+            "description": "Named entity: Dfr; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\ud835\udd07"
+                ]
+            ]
+        }, 
+        {
+            "input": "&DiacriticalAcute", 
+            "description": "Bad named entity: DiacriticalAcute without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&DiacriticalAcute"
+                ]
+            ]
+        }, 
+        {
+            "input": "&DiacriticalAcute;", 
+            "description": "Named entity: DiacriticalAcute; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u00b4"
+                ]
+            ]
+        }, 
+        {
+            "input": "&DiacriticalDot", 
+            "description": "Bad named entity: DiacriticalDot without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&DiacriticalDot"
+                ]
+            ]
+        }, 
+        {
+            "input": "&DiacriticalDot;", 
+            "description": "Named entity: DiacriticalDot; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u02d9"
+                ]
+            ]
+        }, 
+        {
+            "input": "&DiacriticalDoubleAcute", 
+            "description": "Bad named entity: DiacriticalDoubleAcute without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&DiacriticalDoubleAcute"
+                ]
+            ]
+        }, 
+        {
+            "input": "&DiacriticalDoubleAcute;", 
+            "description": "Named entity: DiacriticalDoubleAcute; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u02dd"
+                ]
+            ]
+        }, 
+        {
+            "input": "&DiacriticalGrave", 
+            "description": "Bad named entity: DiacriticalGrave without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&DiacriticalGrave"
+                ]
+            ]
+        }, 
+        {
+            "input": "&DiacriticalGrave;", 
+            "description": "Named entity: DiacriticalGrave; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "`"
+                ]
+            ]
+        }, 
+        {
+            "input": "&DiacriticalTilde", 
+            "description": "Bad named entity: DiacriticalTilde without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&DiacriticalTilde"
+                ]
+            ]
+        }, 
+        {
+            "input": "&DiacriticalTilde;", 
+            "description": "Named entity: DiacriticalTilde; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u02dc"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Diamond", 
+            "description": "Bad named entity: Diamond without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&Diamond"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Diamond;", 
+            "description": "Named entity: Diamond; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u22c4"
+                ]
+            ]
+        }, 
+        {
+            "input": "&DifferentialD", 
+            "description": "Bad named entity: DifferentialD without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&DifferentialD"
+                ]
+            ]
+        }, 
+        {
+            "input": "&DifferentialD;", 
+            "description": "Named entity: DifferentialD; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2146"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Dopf", 
+            "description": "Bad named entity: Dopf without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&Dopf"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Dopf;", 
+            "description": "Named entity: Dopf; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\ud835\udd3b"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Dot", 
+            "description": "Bad named entity: Dot without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&Dot"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Dot;", 
+            "description": "Named entity: Dot; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u00a8"
+                ]
+            ]
+        }, 
+        {
+            "input": "&DotDot", 
+            "description": "Bad named entity: DotDot without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&DotDot"
+                ]
+            ]
+        }, 
+        {
+            "input": "&DotDot;", 
+            "description": "Named entity: DotDot; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u20dc"
+                ]
+            ]
+        }, 
+        {
+            "input": "&DotEqual", 
+            "description": "Bad named entity: DotEqual without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&DotEqual"
+                ]
+            ]
+        }, 
+        {
+            "input": "&DotEqual;", 
+            "description": "Named entity: DotEqual; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2250"
+                ]
+            ]
+        }, 
+        {
+            "input": "&DoubleContourIntegral", 
+            "description": "Bad named entity: DoubleContourIntegral without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&DoubleContourIntegral"
+                ]
+            ]
+        }, 
+        {
+            "input": "&DoubleContourIntegral;", 
+            "description": "Named entity: DoubleContourIntegral; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u222f"
+                ]
+            ]
+        }, 
+        {
+            "input": "&DoubleDot", 
+            "description": "Bad named entity: DoubleDot without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&DoubleDot"
+                ]
+            ]
+        }, 
+        {
+            "input": "&DoubleDot;", 
+            "description": "Named entity: DoubleDot; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u00a8"
+                ]
+            ]
+        }, 
+        {
+            "input": "&DoubleDownArrow", 
+            "description": "Bad named entity: DoubleDownArrow without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&DoubleDownArrow"
+                ]
+            ]
+        }, 
+        {
+            "input": "&DoubleDownArrow;", 
+            "description": "Named entity: DoubleDownArrow; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u21d3"
+                ]
+            ]
+        }, 
+        {
+            "input": "&DoubleLeftArrow", 
+            "description": "Bad named entity: DoubleLeftArrow without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&DoubleLeftArrow"
+                ]
+            ]
+        }, 
+        {
+            "input": "&DoubleLeftArrow;", 
+            "description": "Named entity: DoubleLeftArrow; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u21d0"
+                ]
+            ]
+        }, 
+        {
+            "input": "&DoubleLeftRightArrow", 
+            "description": "Bad named entity: DoubleLeftRightArrow without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&DoubleLeftRightArrow"
+                ]
+            ]
+        }, 
+        {
+            "input": "&DoubleLeftRightArrow;", 
+            "description": "Named entity: DoubleLeftRightArrow; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u21d4"
+                ]
+            ]
+        }, 
+        {
+            "input": "&DoubleLeftTee", 
+            "description": "Bad named entity: DoubleLeftTee without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&DoubleLeftTee"
+                ]
+            ]
+        }, 
+        {
+            "input": "&DoubleLeftTee;", 
+            "description": "Named entity: DoubleLeftTee; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2ae4"
+                ]
+            ]
+        }, 
+        {
+            "input": "&DoubleLongLeftArrow", 
+            "description": "Bad named entity: DoubleLongLeftArrow without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&DoubleLongLeftArrow"
+                ]
+            ]
+        }, 
+        {
+            "input": "&DoubleLongLeftArrow;", 
+            "description": "Named entity: DoubleLongLeftArrow; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u27f8"
+                ]
+            ]
+        }, 
+        {
+            "input": "&DoubleLongLeftRightArrow", 
+            "description": "Bad named entity: DoubleLongLeftRightArrow without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&DoubleLongLeftRightArrow"
+                ]
+            ]
+        }, 
+        {
+            "input": "&DoubleLongLeftRightArrow;", 
+            "description": "Named entity: DoubleLongLeftRightArrow; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u27fa"
+                ]
+            ]
+        }, 
+        {
+            "input": "&DoubleLongRightArrow", 
+            "description": "Bad named entity: DoubleLongRightArrow without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&DoubleLongRightArrow"
+                ]
+            ]
+        }, 
+        {
+            "input": "&DoubleLongRightArrow;", 
+            "description": "Named entity: DoubleLongRightArrow; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u27f9"
+                ]
+            ]
+        }, 
+        {
+            "input": "&DoubleRightArrow", 
+            "description": "Bad named entity: DoubleRightArrow without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&DoubleRightArrow"
+                ]
+            ]
+        }, 
+        {
+            "input": "&DoubleRightArrow;", 
+            "description": "Named entity: DoubleRightArrow; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u21d2"
+                ]
+            ]
+        }, 
+        {
+            "input": "&DoubleRightTee", 
+            "description": "Bad named entity: DoubleRightTee without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&DoubleRightTee"
+                ]
+            ]
+        }, 
+        {
+            "input": "&DoubleRightTee;", 
+            "description": "Named entity: DoubleRightTee; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u22a8"
+                ]
+            ]
+        }, 
+        {
+            "input": "&DoubleUpArrow", 
+            "description": "Bad named entity: DoubleUpArrow without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&DoubleUpArrow"
+                ]
+            ]
+        }, 
+        {
+            "input": "&DoubleUpArrow;", 
+            "description": "Named entity: DoubleUpArrow; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u21d1"
+                ]
+            ]
+        }, 
+        {
+            "input": "&DoubleUpDownArrow", 
+            "description": "Bad named entity: DoubleUpDownArrow without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&DoubleUpDownArrow"
+                ]
+            ]
+        }, 
+        {
+            "input": "&DoubleUpDownArrow;", 
+            "description": "Named entity: DoubleUpDownArrow; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u21d5"
+                ]
+            ]
+        }, 
+        {
+            "input": "&DoubleVerticalBar", 
+            "description": "Bad named entity: DoubleVerticalBar without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&DoubleVerticalBar"
+                ]
+            ]
+        }, 
+        {
+            "input": "&DoubleVerticalBar;", 
+            "description": "Named entity: DoubleVerticalBar; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2225"
+                ]
+            ]
+        }, 
+        {
+            "input": "&DownArrow", 
+            "description": "Bad named entity: DownArrow without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&DownArrow"
+                ]
+            ]
+        }, 
+        {
+            "input": "&DownArrow;", 
+            "description": "Named entity: DownArrow; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2193"
+                ]
+            ]
+        }, 
+        {
+            "input": "&DownArrowBar", 
+            "description": "Bad named entity: DownArrowBar without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&DownArrowBar"
+                ]
+            ]
+        }, 
+        {
+            "input": "&DownArrowBar;", 
+            "description": "Named entity: DownArrowBar; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2913"
+                ]
+            ]
+        }, 
+        {
+            "input": "&DownArrowUpArrow", 
+            "description": "Bad named entity: DownArrowUpArrow without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&DownArrowUpArrow"
+                ]
+            ]
+        }, 
+        {
+            "input": "&DownArrowUpArrow;", 
+            "description": "Named entity: DownArrowUpArrow; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u21f5"
+                ]
+            ]
+        }, 
+        {
+            "input": "&DownBreve", 
+            "description": "Bad named entity: DownBreve without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&DownBreve"
+                ]
+            ]
+        }, 
+        {
+            "input": "&DownBreve;", 
+            "description": "Named entity: DownBreve; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u0311"
+                ]
+            ]
+        }, 
+        {
+            "input": "&DownLeftRightVector", 
+            "description": "Bad named entity: DownLeftRightVector without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&DownLeftRightVector"
+                ]
+            ]
+        }, 
+        {
+            "input": "&DownLeftRightVector;", 
+            "description": "Named entity: DownLeftRightVector; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2950"
+                ]
+            ]
+        }, 
+        {
+            "input": "&DownLeftTeeVector", 
+            "description": "Bad named entity: DownLeftTeeVector without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&DownLeftTeeVector"
+                ]
+            ]
+        }, 
+        {
+            "input": "&DownLeftTeeVector;", 
+            "description": "Named entity: DownLeftTeeVector; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u295e"
+                ]
+            ]
+        }, 
+        {
+            "input": "&DownLeftVector", 
+            "description": "Bad named entity: DownLeftVector without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&DownLeftVector"
+                ]
+            ]
+        }, 
+        {
+            "input": "&DownLeftVector;", 
+            "description": "Named entity: DownLeftVector; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u21bd"
+                ]
+            ]
+        }, 
+        {
+            "input": "&DownLeftVectorBar", 
+            "description": "Bad named entity: DownLeftVectorBar without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&DownLeftVectorBar"
+                ]
+            ]
+        }, 
+        {
+            "input": "&DownLeftVectorBar;", 
+            "description": "Named entity: DownLeftVectorBar; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2956"
+                ]
+            ]
+        }, 
+        {
+            "input": "&DownRightTeeVector", 
+            "description": "Bad named entity: DownRightTeeVector without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&DownRightTeeVector"
+                ]
+            ]
+        }, 
+        {
+            "input": "&DownRightTeeVector;", 
+            "description": "Named entity: DownRightTeeVector; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u295f"
+                ]
+            ]
+        }, 
+        {
+            "input": "&DownRightVector", 
+            "description": "Bad named entity: DownRightVector without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&DownRightVector"
+                ]
+            ]
+        }, 
+        {
+            "input": "&DownRightVector;", 
+            "description": "Named entity: DownRightVector; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u21c1"
+                ]
+            ]
+        }, 
+        {
+            "input": "&DownRightVectorBar", 
+            "description": "Bad named entity: DownRightVectorBar without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&DownRightVectorBar"
+                ]
+            ]
+        }, 
+        {
+            "input": "&DownRightVectorBar;", 
+            "description": "Named entity: DownRightVectorBar; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2957"
+                ]
+            ]
+        }, 
+        {
+            "input": "&DownTee", 
+            "description": "Bad named entity: DownTee without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&DownTee"
+                ]
+            ]
+        }, 
+        {
+            "input": "&DownTee;", 
+            "description": "Named entity: DownTee; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u22a4"
+                ]
+            ]
+        }, 
+        {
+            "input": "&DownTeeArrow", 
+            "description": "Bad named entity: DownTeeArrow without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&DownTeeArrow"
+                ]
+            ]
+        }, 
+        {
+            "input": "&DownTeeArrow;", 
+            "description": "Named entity: DownTeeArrow; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u21a7"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Downarrow", 
+            "description": "Bad named entity: Downarrow without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&Downarrow"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Downarrow;", 
+            "description": "Named entity: Downarrow; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u21d3"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Dscr", 
+            "description": "Bad named entity: Dscr without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&Dscr"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Dscr;", 
+            "description": "Named entity: Dscr; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\ud835\udc9f"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Dstrok", 
+            "description": "Bad named entity: Dstrok without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&Dstrok"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Dstrok;", 
+            "description": "Named entity: Dstrok; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u0110"
+                ]
+            ]
+        }, 
+        {
+            "input": "&ENG", 
+            "description": "Bad named entity: ENG without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&ENG"
+                ]
+            ]
+        }, 
+        {
+            "input": "&ENG;", 
+            "description": "Named entity: ENG; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u014a"
+                ]
+            ]
+        }, 
+        {
+            "input": "&ETH", 
+            "description": "Named entity: ETH without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "\u00d0"
+                ]
+            ]
+        }, 
+        {
+            "input": "&ETH;", 
+            "description": "Named entity: ETH; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u00d0"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Eacute", 
+            "description": "Named entity: Eacute without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "\u00c9"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Eacute;", 
+            "description": "Named entity: Eacute; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u00c9"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Ecaron", 
+            "description": "Bad named entity: Ecaron without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&Ecaron"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Ecaron;", 
+            "description": "Named entity: Ecaron; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u011a"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Ecirc", 
+            "description": "Named entity: Ecirc without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "\u00ca"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Ecirc;", 
+            "description": "Named entity: Ecirc; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u00ca"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Ecy", 
+            "description": "Bad named entity: Ecy without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&Ecy"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Ecy;", 
+            "description": "Named entity: Ecy; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u042d"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Edot", 
+            "description": "Bad named entity: Edot without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&Edot"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Edot;", 
+            "description": "Named entity: Edot; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u0116"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Efr", 
+            "description": "Bad named entity: Efr without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&Efr"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Efr;", 
+            "description": "Named entity: Efr; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\ud835\udd08"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Egrave", 
+            "description": "Named entity: Egrave without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "\u00c8"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Egrave;", 
+            "description": "Named entity: Egrave; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u00c8"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Element", 
+            "description": "Bad named entity: Element without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&Element"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Element;", 
+            "description": "Named entity: Element; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2208"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Emacr", 
+            "description": "Bad named entity: Emacr without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&Emacr"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Emacr;", 
+            "description": "Named entity: Emacr; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u0112"
+                ]
+            ]
+        }, 
+        {
+            "input": "&EmptySmallSquare", 
+            "description": "Bad named entity: EmptySmallSquare without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&EmptySmallSquare"
+                ]
+            ]
+        }, 
+        {
+            "input": "&EmptySmallSquare;", 
+            "description": "Named entity: EmptySmallSquare; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u25fb"
+                ]
+            ]
+        }, 
+        {
+            "input": "&EmptyVerySmallSquare", 
+            "description": "Bad named entity: EmptyVerySmallSquare without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&EmptyVerySmallSquare"
+                ]
+            ]
+        }, 
+        {
+            "input": "&EmptyVerySmallSquare;", 
+            "description": "Named entity: EmptyVerySmallSquare; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u25ab"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Eogon", 
+            "description": "Bad named entity: Eogon without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&Eogon"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Eogon;", 
+            "description": "Named entity: Eogon; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u0118"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Eopf", 
+            "description": "Bad named entity: Eopf without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&Eopf"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Eopf;", 
+            "description": "Named entity: Eopf; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\ud835\udd3c"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Epsilon", 
+            "description": "Bad named entity: Epsilon without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&Epsilon"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Epsilon;", 
+            "description": "Named entity: Epsilon; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u0395"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Equal", 
+            "description": "Bad named entity: Equal without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&Equal"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Equal;", 
+            "description": "Named entity: Equal; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2a75"
+                ]
+            ]
+        }, 
+        {
+            "input": "&EqualTilde", 
+            "description": "Bad named entity: EqualTilde without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&EqualTilde"
+                ]
+            ]
+        }, 
+        {
+            "input": "&EqualTilde;", 
+            "description": "Named entity: EqualTilde; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2242"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Equilibrium", 
+            "description": "Bad named entity: Equilibrium without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&Equilibrium"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Equilibrium;", 
+            "description": "Named entity: Equilibrium; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u21cc"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Escr", 
+            "description": "Bad named entity: Escr without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&Escr"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Escr;", 
+            "description": "Named entity: Escr; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2130"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Esim", 
+            "description": "Bad named entity: Esim without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&Esim"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Esim;", 
+            "description": "Named entity: Esim; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2a73"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Eta", 
+            "description": "Bad named entity: Eta without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&Eta"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Eta;", 
+            "description": "Named entity: Eta; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u0397"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Euml", 
+            "description": "Named entity: Euml without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "\u00cb"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Euml;", 
+            "description": "Named entity: Euml; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u00cb"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Exists", 
+            "description": "Bad named entity: Exists without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&Exists"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Exists;", 
+            "description": "Named entity: Exists; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2203"
+                ]
+            ]
+        }, 
+        {
+            "input": "&ExponentialE", 
+            "description": "Bad named entity: ExponentialE without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&ExponentialE"
+                ]
+            ]
+        }, 
+        {
+            "input": "&ExponentialE;", 
+            "description": "Named entity: ExponentialE; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2147"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Fcy", 
+            "description": "Bad named entity: Fcy without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&Fcy"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Fcy;", 
+            "description": "Named entity: Fcy; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u0424"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Ffr", 
+            "description": "Bad named entity: Ffr without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&Ffr"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Ffr;", 
+            "description": "Named entity: Ffr; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\ud835\udd09"
+                ]
+            ]
+        }, 
+        {
+            "input": "&FilledSmallSquare", 
+            "description": "Bad named entity: FilledSmallSquare without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&FilledSmallSquare"
+                ]
+            ]
+        }, 
+        {
+            "input": "&FilledSmallSquare;", 
+            "description": "Named entity: FilledSmallSquare; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u25fc"
+                ]
+            ]
+        }, 
+        {
+            "input": "&FilledVerySmallSquare", 
+            "description": "Bad named entity: FilledVerySmallSquare without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&FilledVerySmallSquare"
+                ]
+            ]
+        }, 
+        {
+            "input": "&FilledVerySmallSquare;", 
+            "description": "Named entity: FilledVerySmallSquare; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u25aa"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Fopf", 
+            "description": "Bad named entity: Fopf without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&Fopf"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Fopf;", 
+            "description": "Named entity: Fopf; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\ud835\udd3d"
+                ]
+            ]
+        }, 
+        {
+            "input": "&ForAll", 
+            "description": "Bad named entity: ForAll without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&ForAll"
+                ]
+            ]
+        }, 
+        {
+            "input": "&ForAll;", 
+            "description": "Named entity: ForAll; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2200"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Fouriertrf", 
+            "description": "Bad named entity: Fouriertrf without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&Fouriertrf"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Fouriertrf;", 
+            "description": "Named entity: Fouriertrf; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2131"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Fscr", 
+            "description": "Bad named entity: Fscr without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&Fscr"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Fscr;", 
+            "description": "Named entity: Fscr; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2131"
+                ]
+            ]
+        }, 
+        {
+            "input": "&GJcy", 
+            "description": "Bad named entity: GJcy without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&GJcy"
+                ]
+            ]
+        }, 
+        {
+            "input": "&GJcy;", 
+            "description": "Named entity: GJcy; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u0403"
+                ]
+            ]
+        }, 
+        {
+            "input": "&GT", 
+            "description": "Named entity: GT without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    ">"
+                ]
+            ]
+        }, 
+        {
+            "input": "&GT;", 
+            "description": "Named entity: GT; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    ">"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Gamma", 
+            "description": "Bad named entity: Gamma without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&Gamma"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Gamma;", 
+            "description": "Named entity: Gamma; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u0393"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Gammad", 
+            "description": "Bad named entity: Gammad without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&Gammad"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Gammad;", 
+            "description": "Named entity: Gammad; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u03dc"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Gbreve", 
+            "description": "Bad named entity: Gbreve without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&Gbreve"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Gbreve;", 
+            "description": "Named entity: Gbreve; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u011e"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Gcedil", 
+            "description": "Bad named entity: Gcedil without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&Gcedil"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Gcedil;", 
+            "description": "Named entity: Gcedil; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u0122"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Gcirc", 
+            "description": "Bad named entity: Gcirc without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&Gcirc"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Gcirc;", 
+            "description": "Named entity: Gcirc; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u011c"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Gcy", 
+            "description": "Bad named entity: Gcy without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&Gcy"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Gcy;", 
+            "description": "Named entity: Gcy; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u0413"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Gdot", 
+            "description": "Bad named entity: Gdot without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&Gdot"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Gdot;", 
+            "description": "Named entity: Gdot; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u0120"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Gfr", 
+            "description": "Bad named entity: Gfr without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&Gfr"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Gfr;", 
+            "description": "Named entity: Gfr; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\ud835\udd0a"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Gg", 
+            "description": "Bad named entity: Gg without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&Gg"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Gg;", 
+            "description": "Named entity: Gg; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u22d9"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Gopf", 
+            "description": "Bad named entity: Gopf without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&Gopf"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Gopf;", 
+            "description": "Named entity: Gopf; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\ud835\udd3e"
+                ]
+            ]
+        }, 
+        {
+            "input": "&GreaterEqual", 
+            "description": "Bad named entity: GreaterEqual without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&GreaterEqual"
+                ]
+            ]
+        }, 
+        {
+            "input": "&GreaterEqual;", 
+            "description": "Named entity: GreaterEqual; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2265"
+                ]
+            ]
+        }, 
+        {
+            "input": "&GreaterEqualLess", 
+            "description": "Bad named entity: GreaterEqualLess without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&GreaterEqualLess"
+                ]
+            ]
+        }, 
+        {
+            "input": "&GreaterEqualLess;", 
+            "description": "Named entity: GreaterEqualLess; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u22db"
+                ]
+            ]
+        }, 
+        {
+            "input": "&GreaterFullEqual", 
+            "description": "Bad named entity: GreaterFullEqual without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&GreaterFullEqual"
+                ]
+            ]
+        }, 
+        {
+            "input": "&GreaterFullEqual;", 
+            "description": "Named entity: GreaterFullEqual; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2267"
+                ]
+            ]
+        }, 
+        {
+            "input": "&GreaterGreater", 
+            "description": "Bad named entity: GreaterGreater without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&GreaterGreater"
+                ]
+            ]
+        }, 
+        {
+            "input": "&GreaterGreater;", 
+            "description": "Named entity: GreaterGreater; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2aa2"
+                ]
+            ]
+        }, 
+        {
+            "input": "&GreaterLess", 
+            "description": "Bad named entity: GreaterLess without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&GreaterLess"
+                ]
+            ]
+        }, 
+        {
+            "input": "&GreaterLess;", 
+            "description": "Named entity: GreaterLess; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2277"
+                ]
+            ]
+        }, 
+        {
+            "input": "&GreaterSlantEqual", 
+            "description": "Bad named entity: GreaterSlantEqual without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&GreaterSlantEqual"
+                ]
+            ]
+        }, 
+        {
+            "input": "&GreaterSlantEqual;", 
+            "description": "Named entity: GreaterSlantEqual; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2a7e"
+                ]
+            ]
+        }, 
+        {
+            "input": "&GreaterTilde", 
+            "description": "Bad named entity: GreaterTilde without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&GreaterTilde"
+                ]
+            ]
+        }, 
+        {
+            "input": "&GreaterTilde;", 
+            "description": "Named entity: GreaterTilde; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2273"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Gscr", 
+            "description": "Bad named entity: Gscr without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&Gscr"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Gscr;", 
+            "description": "Named entity: Gscr; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\ud835\udca2"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Gt", 
+            "description": "Bad named entity: Gt without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&Gt"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Gt;", 
+            "description": "Named entity: Gt; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u226b"
+                ]
+            ]
+        }, 
+        {
+            "input": "&HARDcy", 
+            "description": "Bad named entity: HARDcy without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&HARDcy"
+                ]
+            ]
+        }, 
+        {
+            "input": "&HARDcy;", 
+            "description": "Named entity: HARDcy; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u042a"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Hacek", 
+            "description": "Bad named entity: Hacek without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&Hacek"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Hacek;", 
+            "description": "Named entity: Hacek; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u02c7"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Hat", 
+            "description": "Bad named entity: Hat without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&Hat"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Hat;", 
+            "description": "Named entity: Hat; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "^"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Hcirc", 
+            "description": "Bad named entity: Hcirc without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&Hcirc"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Hcirc;", 
+            "description": "Named entity: Hcirc; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u0124"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Hfr", 
+            "description": "Bad named entity: Hfr without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&Hfr"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Hfr;", 
+            "description": "Named entity: Hfr; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u210c"
+                ]
+            ]
+        }, 
+        {
+            "input": "&HilbertSpace", 
+            "description": "Bad named entity: HilbertSpace without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&HilbertSpace"
+                ]
+            ]
+        }, 
+        {
+            "input": "&HilbertSpace;", 
+            "description": "Named entity: HilbertSpace; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u210b"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Hopf", 
+            "description": "Bad named entity: Hopf without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&Hopf"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Hopf;", 
+            "description": "Named entity: Hopf; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u210d"
+                ]
+            ]
+        }, 
+        {
+            "input": "&HorizontalLine", 
+            "description": "Bad named entity: HorizontalLine without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&HorizontalLine"
+                ]
+            ]
+        }, 
+        {
+            "input": "&HorizontalLine;", 
+            "description": "Named entity: HorizontalLine; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2500"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Hscr", 
+            "description": "Bad named entity: Hscr without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&Hscr"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Hscr;", 
+            "description": "Named entity: Hscr; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u210b"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Hstrok", 
+            "description": "Bad named entity: Hstrok without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&Hstrok"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Hstrok;", 
+            "description": "Named entity: Hstrok; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u0126"
+                ]
+            ]
+        }, 
+        {
+            "input": "&HumpDownHump", 
+            "description": "Bad named entity: HumpDownHump without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&HumpDownHump"
+                ]
+            ]
+        }, 
+        {
+            "input": "&HumpDownHump;", 
+            "description": "Named entity: HumpDownHump; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u224e"
+                ]
+            ]
+        }, 
+        {
+            "input": "&HumpEqual", 
+            "description": "Bad named entity: HumpEqual without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&HumpEqual"
+                ]
+            ]
+        }, 
+        {
+            "input": "&HumpEqual;", 
+            "description": "Named entity: HumpEqual; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u224f"
+                ]
+            ]
+        }, 
+        {
+            "input": "&IEcy", 
+            "description": "Bad named entity: IEcy without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&IEcy"
+                ]
+            ]
+        }, 
+        {
+            "input": "&IEcy;", 
+            "description": "Named entity: IEcy; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u0415"
+                ]
+            ]
+        }, 
+        {
+            "input": "&IJlig", 
+            "description": "Bad named entity: IJlig without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&IJlig"
+                ]
+            ]
+        }, 
+        {
+            "input": "&IJlig;", 
+            "description": "Named entity: IJlig; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u0132"
+                ]
+            ]
+        }, 
+        {
+            "input": "&IOcy", 
+            "description": "Bad named entity: IOcy without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&IOcy"
+                ]
+            ]
+        }, 
+        {
+            "input": "&IOcy;", 
+            "description": "Named entity: IOcy; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u0401"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Iacute", 
+            "description": "Named entity: Iacute without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "\u00cd"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Iacute;", 
+            "description": "Named entity: Iacute; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u00cd"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Icirc", 
+            "description": "Named entity: Icirc without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "\u00ce"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Icirc;", 
+            "description": "Named entity: Icirc; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u00ce"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Icy", 
+            "description": "Bad named entity: Icy without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&Icy"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Icy;", 
+            "description": "Named entity: Icy; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u0418"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Idot", 
+            "description": "Bad named entity: Idot without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&Idot"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Idot;", 
+            "description": "Named entity: Idot; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u0130"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Ifr", 
+            "description": "Bad named entity: Ifr without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&Ifr"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Ifr;", 
+            "description": "Named entity: Ifr; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2111"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Igrave", 
+            "description": "Named entity: Igrave without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "\u00cc"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Igrave;", 
+            "description": "Named entity: Igrave; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u00cc"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Im", 
+            "description": "Bad named entity: Im without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&Im"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Im;", 
+            "description": "Named entity: Im; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2111"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Imacr", 
+            "description": "Bad named entity: Imacr without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&Imacr"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Imacr;", 
+            "description": "Named entity: Imacr; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u012a"
+                ]
+            ]
+        }, 
+        {
+            "input": "&ImaginaryI", 
+            "description": "Bad named entity: ImaginaryI without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&ImaginaryI"
+                ]
+            ]
+        }, 
+        {
+            "input": "&ImaginaryI;", 
+            "description": "Named entity: ImaginaryI; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2148"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Implies", 
+            "description": "Bad named entity: Implies without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&Implies"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Implies;", 
+            "description": "Named entity: Implies; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u21d2"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Int", 
+            "description": "Bad named entity: Int without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&Int"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Int;", 
+            "description": "Named entity: Int; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u222c"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Integral", 
+            "description": "Bad named entity: Integral without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&Integral"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Integral;", 
+            "description": "Named entity: Integral; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u222b"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Intersection", 
+            "description": "Bad named entity: Intersection without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&Intersection"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Intersection;", 
+            "description": "Named entity: Intersection; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u22c2"
+                ]
+            ]
+        }, 
+        {
+            "input": "&InvisibleComma", 
+            "description": "Bad named entity: InvisibleComma without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&InvisibleComma"
+                ]
+            ]
+        }, 
+        {
+            "input": "&InvisibleComma;", 
+            "description": "Named entity: InvisibleComma; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2063"
+                ]
+            ]
+        }, 
+        {
+            "input": "&InvisibleTimes", 
+            "description": "Bad named entity: InvisibleTimes without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&InvisibleTimes"
+                ]
+            ]
+        }, 
+        {
+            "input": "&InvisibleTimes;", 
+            "description": "Named entity: InvisibleTimes; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2062"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Iogon", 
+            "description": "Bad named entity: Iogon without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&Iogon"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Iogon;", 
+            "description": "Named entity: Iogon; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u012e"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Iopf", 
+            "description": "Bad named entity: Iopf without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&Iopf"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Iopf;", 
+            "description": "Named entity: Iopf; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\ud835\udd40"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Iota", 
+            "description": "Bad named entity: Iota without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&Iota"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Iota;", 
+            "description": "Named entity: Iota; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u0399"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Iscr", 
+            "description": "Bad named entity: Iscr without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&Iscr"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Iscr;", 
+            "description": "Named entity: Iscr; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2110"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Itilde", 
+            "description": "Bad named entity: Itilde without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&Itilde"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Itilde;", 
+            "description": "Named entity: Itilde; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u0128"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Iukcy", 
+            "description": "Bad named entity: Iukcy without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&Iukcy"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Iukcy;", 
+            "description": "Named entity: Iukcy; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u0406"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Iuml", 
+            "description": "Named entity: Iuml without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "\u00cf"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Iuml;", 
+            "description": "Named entity: Iuml; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u00cf"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Jcirc", 
+            "description": "Bad named entity: Jcirc without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&Jcirc"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Jcirc;", 
+            "description": "Named entity: Jcirc; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u0134"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Jcy", 
+            "description": "Bad named entity: Jcy without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&Jcy"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Jcy;", 
+            "description": "Named entity: Jcy; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u0419"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Jfr", 
+            "description": "Bad named entity: Jfr without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&Jfr"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Jfr;", 
+            "description": "Named entity: Jfr; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\ud835\udd0d"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Jopf", 
+            "description": "Bad named entity: Jopf without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&Jopf"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Jopf;", 
+            "description": "Named entity: Jopf; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\ud835\udd41"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Jscr", 
+            "description": "Bad named entity: Jscr without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&Jscr"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Jscr;", 
+            "description": "Named entity: Jscr; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\ud835\udca5"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Jsercy", 
+            "description": "Bad named entity: Jsercy without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&Jsercy"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Jsercy;", 
+            "description": "Named entity: Jsercy; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u0408"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Jukcy", 
+            "description": "Bad named entity: Jukcy without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&Jukcy"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Jukcy;", 
+            "description": "Named entity: Jukcy; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u0404"
+                ]
+            ]
+        }, 
+        {
+            "input": "&KHcy", 
+            "description": "Bad named entity: KHcy without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&KHcy"
+                ]
+            ]
+        }, 
+        {
+            "input": "&KHcy;", 
+            "description": "Named entity: KHcy; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u0425"
+                ]
+            ]
+        }, 
+        {
+            "input": "&KJcy", 
+            "description": "Bad named entity: KJcy without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&KJcy"
+                ]
+            ]
+        }, 
+        {
+            "input": "&KJcy;", 
+            "description": "Named entity: KJcy; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u040c"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Kappa", 
+            "description": "Bad named entity: Kappa without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&Kappa"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Kappa;", 
+            "description": "Named entity: Kappa; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u039a"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Kcedil", 
+            "description": "Bad named entity: Kcedil without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&Kcedil"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Kcedil;", 
+            "description": "Named entity: Kcedil; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u0136"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Kcy", 
+            "description": "Bad named entity: Kcy without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&Kcy"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Kcy;", 
+            "description": "Named entity: Kcy; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u041a"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Kfr", 
+            "description": "Bad named entity: Kfr without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&Kfr"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Kfr;", 
+            "description": "Named entity: Kfr; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\ud835\udd0e"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Kopf", 
+            "description": "Bad named entity: Kopf without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&Kopf"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Kopf;", 
+            "description": "Named entity: Kopf; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\ud835\udd42"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Kscr", 
+            "description": "Bad named entity: Kscr without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&Kscr"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Kscr;", 
+            "description": "Named entity: Kscr; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\ud835\udca6"
+                ]
+            ]
+        }, 
+        {
+            "input": "&LJcy", 
+            "description": "Bad named entity: LJcy without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&LJcy"
+                ]
+            ]
+        }, 
+        {
+            "input": "&LJcy;", 
+            "description": "Named entity: LJcy; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u0409"
+                ]
+            ]
+        }, 
+        {
+            "input": "&LT", 
+            "description": "Named entity: LT without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "<"
+                ]
+            ]
+        }, 
+        {
+            "input": "&LT;", 
+            "description": "Named entity: LT; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "<"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Lacute", 
+            "description": "Bad named entity: Lacute without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&Lacute"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Lacute;", 
+            "description": "Named entity: Lacute; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u0139"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Lambda", 
+            "description": "Bad named entity: Lambda without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&Lambda"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Lambda;", 
+            "description": "Named entity: Lambda; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u039b"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Lang", 
+            "description": "Bad named entity: Lang without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&Lang"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Lang;", 
+            "description": "Named entity: Lang; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u27ea"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Laplacetrf", 
+            "description": "Bad named entity: Laplacetrf without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&Laplacetrf"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Laplacetrf;", 
+            "description": "Named entity: Laplacetrf; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2112"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Larr", 
+            "description": "Bad named entity: Larr without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&Larr"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Larr;", 
+            "description": "Named entity: Larr; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u219e"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Lcaron", 
+            "description": "Bad named entity: Lcaron without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&Lcaron"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Lcaron;", 
+            "description": "Named entity: Lcaron; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u013d"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Lcedil", 
+            "description": "Bad named entity: Lcedil without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&Lcedil"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Lcedil;", 
+            "description": "Named entity: Lcedil; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u013b"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Lcy", 
+            "description": "Bad named entity: Lcy without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&Lcy"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Lcy;", 
+            "description": "Named entity: Lcy; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u041b"
+                ]
+            ]
+        }, 
+        {
+            "input": "&LeftAngleBracket", 
+            "description": "Bad named entity: LeftAngleBracket without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&LeftAngleBracket"
+                ]
+            ]
+        }, 
+        {
+            "input": "&LeftAngleBracket;", 
+            "description": "Named entity: LeftAngleBracket; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u27e8"
+                ]
+            ]
+        }, 
+        {
+            "input": "&LeftArrow", 
+            "description": "Bad named entity: LeftArrow without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&LeftArrow"
+                ]
+            ]
+        }, 
+        {
+            "input": "&LeftArrow;", 
+            "description": "Named entity: LeftArrow; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2190"
+                ]
+            ]
+        }, 
+        {
+            "input": "&LeftArrowBar", 
+            "description": "Bad named entity: LeftArrowBar without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&LeftArrowBar"
+                ]
+            ]
+        }, 
+        {
+            "input": "&LeftArrowBar;", 
+            "description": "Named entity: LeftArrowBar; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u21e4"
+                ]
+            ]
+        }, 
+        {
+            "input": "&LeftArrowRightArrow", 
+            "description": "Bad named entity: LeftArrowRightArrow without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&LeftArrowRightArrow"
+                ]
+            ]
+        }, 
+        {
+            "input": "&LeftArrowRightArrow;", 
+            "description": "Named entity: LeftArrowRightArrow; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u21c6"
+                ]
+            ]
+        }, 
+        {
+            "input": "&LeftCeiling", 
+            "description": "Bad named entity: LeftCeiling without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&LeftCeiling"
+                ]
+            ]
+        }, 
+        {
+            "input": "&LeftCeiling;", 
+            "description": "Named entity: LeftCeiling; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2308"
+                ]
+            ]
+        }, 
+        {
+            "input": "&LeftDoubleBracket", 
+            "description": "Bad named entity: LeftDoubleBracket without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&LeftDoubleBracket"
+                ]
+            ]
+        }, 
+        {
+            "input": "&LeftDoubleBracket;", 
+            "description": "Named entity: LeftDoubleBracket; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u27e6"
+                ]
+            ]
+        }, 
+        {
+            "input": "&LeftDownTeeVector", 
+            "description": "Bad named entity: LeftDownTeeVector without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&LeftDownTeeVector"
+                ]
+            ]
+        }, 
+        {
+            "input": "&LeftDownTeeVector;", 
+            "description": "Named entity: LeftDownTeeVector; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2961"
+                ]
+            ]
+        }, 
+        {
+            "input": "&LeftDownVector", 
+            "description": "Bad named entity: LeftDownVector without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&LeftDownVector"
+                ]
+            ]
+        }, 
+        {
+            "input": "&LeftDownVector;", 
+            "description": "Named entity: LeftDownVector; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u21c3"
+                ]
+            ]
+        }, 
+        {
+            "input": "&LeftDownVectorBar", 
+            "description": "Bad named entity: LeftDownVectorBar without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&LeftDownVectorBar"
+                ]
+            ]
+        }, 
+        {
+            "input": "&LeftDownVectorBar;", 
+            "description": "Named entity: LeftDownVectorBar; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2959"
+                ]
+            ]
+        }, 
+        {
+            "input": "&LeftFloor", 
+            "description": "Bad named entity: LeftFloor without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&LeftFloor"
+                ]
+            ]
+        }, 
+        {
+            "input": "&LeftFloor;", 
+            "description": "Named entity: LeftFloor; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u230a"
+                ]
+            ]
+        }, 
+        {
+            "input": "&LeftRightArrow", 
+            "description": "Bad named entity: LeftRightArrow without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&LeftRightArrow"
+                ]
+            ]
+        }, 
+        {
+            "input": "&LeftRightArrow;", 
+            "description": "Named entity: LeftRightArrow; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2194"
+                ]
+            ]
+        }, 
+        {
+            "input": "&LeftRightVector", 
+            "description": "Bad named entity: LeftRightVector without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&LeftRightVector"
+                ]
+            ]
+        }, 
+        {
+            "input": "&LeftRightVector;", 
+            "description": "Named entity: LeftRightVector; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u294e"
+                ]
+            ]
+        }, 
+        {
+            "input": "&LeftTee", 
+            "description": "Bad named entity: LeftTee without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&LeftTee"
+                ]
+            ]
+        }, 
+        {
+            "input": "&LeftTee;", 
+            "description": "Named entity: LeftTee; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u22a3"
+                ]
+            ]
+        }, 
+        {
+            "input": "&LeftTeeArrow", 
+            "description": "Bad named entity: LeftTeeArrow without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&LeftTeeArrow"
+                ]
+            ]
+        }, 
+        {
+            "input": "&LeftTeeArrow;", 
+            "description": "Named entity: LeftTeeArrow; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u21a4"
+                ]
+            ]
+        }, 
+        {
+            "input": "&LeftTeeVector", 
+            "description": "Bad named entity: LeftTeeVector without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&LeftTeeVector"
+                ]
+            ]
+        }, 
+        {
+            "input": "&LeftTeeVector;", 
+            "description": "Named entity: LeftTeeVector; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u295a"
+                ]
+            ]
+        }, 
+        {
+            "input": "&LeftTriangle", 
+            "description": "Bad named entity: LeftTriangle without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&LeftTriangle"
+                ]
+            ]
+        }, 
+        {
+            "input": "&LeftTriangle;", 
+            "description": "Named entity: LeftTriangle; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u22b2"
+                ]
+            ]
+        }, 
+        {
+            "input": "&LeftTriangleBar", 
+            "description": "Bad named entity: LeftTriangleBar without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&LeftTriangleBar"
+                ]
+            ]
+        }, 
+        {
+            "input": "&LeftTriangleBar;", 
+            "description": "Named entity: LeftTriangleBar; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u29cf"
+                ]
+            ]
+        }, 
+        {
+            "input": "&LeftTriangleEqual", 
+            "description": "Bad named entity: LeftTriangleEqual without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&LeftTriangleEqual"
+                ]
+            ]
+        }, 
+        {
+            "input": "&LeftTriangleEqual;", 
+            "description": "Named entity: LeftTriangleEqual; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u22b4"
+                ]
+            ]
+        }, 
+        {
+            "input": "&LeftUpDownVector", 
+            "description": "Bad named entity: LeftUpDownVector without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&LeftUpDownVector"
+                ]
+            ]
+        }, 
+        {
+            "input": "&LeftUpDownVector;", 
+            "description": "Named entity: LeftUpDownVector; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2951"
+                ]
+            ]
+        }, 
+        {
+            "input": "&LeftUpTeeVector", 
+            "description": "Bad named entity: LeftUpTeeVector without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&LeftUpTeeVector"
+                ]
+            ]
+        }, 
+        {
+            "input": "&LeftUpTeeVector;", 
+            "description": "Named entity: LeftUpTeeVector; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2960"
+                ]
+            ]
+        }, 
+        {
+            "input": "&LeftUpVector", 
+            "description": "Bad named entity: LeftUpVector without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&LeftUpVector"
+                ]
+            ]
+        }, 
+        {
+            "input": "&LeftUpVector;", 
+            "description": "Named entity: LeftUpVector; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u21bf"
+                ]
+            ]
+        }, 
+        {
+            "input": "&LeftUpVectorBar", 
+            "description": "Bad named entity: LeftUpVectorBar without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&LeftUpVectorBar"
+                ]
+            ]
+        }, 
+        {
+            "input": "&LeftUpVectorBar;", 
+            "description": "Named entity: LeftUpVectorBar; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2958"
+                ]
+            ]
+        }, 
+        {
+            "input": "&LeftVector", 
+            "description": "Bad named entity: LeftVector without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&LeftVector"
+                ]
+            ]
+        }, 
+        {
+            "input": "&LeftVector;", 
+            "description": "Named entity: LeftVector; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u21bc"
+                ]
+            ]
+        }, 
+        {
+            "input": "&LeftVectorBar", 
+            "description": "Bad named entity: LeftVectorBar without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&LeftVectorBar"
+                ]
+            ]
+        }, 
+        {
+            "input": "&LeftVectorBar;", 
+            "description": "Named entity: LeftVectorBar; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2952"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Leftarrow", 
+            "description": "Bad named entity: Leftarrow without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&Leftarrow"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Leftarrow;", 
+            "description": "Named entity: Leftarrow; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u21d0"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Leftrightarrow", 
+            "description": "Bad named entity: Leftrightarrow without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&Leftrightarrow"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Leftrightarrow;", 
+            "description": "Named entity: Leftrightarrow; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u21d4"
+                ]
+            ]
+        }, 
+        {
+            "input": "&LessEqualGreater", 
+            "description": "Bad named entity: LessEqualGreater without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&LessEqualGreater"
+                ]
+            ]
+        }, 
+        {
+            "input": "&LessEqualGreater;", 
+            "description": "Named entity: LessEqualGreater; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u22da"
+                ]
+            ]
+        }, 
+        {
+            "input": "&LessFullEqual", 
+            "description": "Bad named entity: LessFullEqual without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&LessFullEqual"
+                ]
+            ]
+        }, 
+        {
+            "input": "&LessFullEqual;", 
+            "description": "Named entity: LessFullEqual; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2266"
+                ]
+            ]
+        }, 
+        {
+            "input": "&LessGreater", 
+            "description": "Bad named entity: LessGreater without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&LessGreater"
+                ]
+            ]
+        }, 
+        {
+            "input": "&LessGreater;", 
+            "description": "Named entity: LessGreater; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2276"
+                ]
+            ]
+        }, 
+        {
+            "input": "&LessLess", 
+            "description": "Bad named entity: LessLess without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&LessLess"
+                ]
+            ]
+        }, 
+        {
+            "input": "&LessLess;", 
+            "description": "Named entity: LessLess; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2aa1"
+                ]
+            ]
+        }, 
+        {
+            "input": "&LessSlantEqual", 
+            "description": "Bad named entity: LessSlantEqual without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&LessSlantEqual"
+                ]
+            ]
+        }, 
+        {
+            "input": "&LessSlantEqual;", 
+            "description": "Named entity: LessSlantEqual; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2a7d"
+                ]
+            ]
+        }, 
+        {
+            "input": "&LessTilde", 
+            "description": "Bad named entity: LessTilde without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&LessTilde"
+                ]
+            ]
+        }, 
+        {
+            "input": "&LessTilde;", 
+            "description": "Named entity: LessTilde; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2272"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Lfr", 
+            "description": "Bad named entity: Lfr without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&Lfr"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Lfr;", 
+            "description": "Named entity: Lfr; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\ud835\udd0f"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Ll", 
+            "description": "Bad named entity: Ll without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&Ll"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Ll;", 
+            "description": "Named entity: Ll; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u22d8"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Lleftarrow", 
+            "description": "Bad named entity: Lleftarrow without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&Lleftarrow"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Lleftarrow;", 
+            "description": "Named entity: Lleftarrow; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u21da"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Lmidot", 
+            "description": "Bad named entity: Lmidot without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&Lmidot"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Lmidot;", 
+            "description": "Named entity: Lmidot; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u013f"
+                ]
+            ]
+        }, 
+        {
+            "input": "&LongLeftArrow", 
+            "description": "Bad named entity: LongLeftArrow without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&LongLeftArrow"
+                ]
+            ]
+        }, 
+        {
+            "input": "&LongLeftArrow;", 
+            "description": "Named entity: LongLeftArrow; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u27f5"
+                ]
+            ]
+        }, 
+        {
+            "input": "&LongLeftRightArrow", 
+            "description": "Bad named entity: LongLeftRightArrow without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&LongLeftRightArrow"
+                ]
+            ]
+        }, 
+        {
+            "input": "&LongLeftRightArrow;", 
+            "description": "Named entity: LongLeftRightArrow; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u27f7"
+                ]
+            ]
+        }, 
+        {
+            "input": "&LongRightArrow", 
+            "description": "Bad named entity: LongRightArrow without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&LongRightArrow"
+                ]
+            ]
+        }, 
+        {
+            "input": "&LongRightArrow;", 
+            "description": "Named entity: LongRightArrow; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u27f6"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Longleftarrow", 
+            "description": "Bad named entity: Longleftarrow without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&Longleftarrow"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Longleftarrow;", 
+            "description": "Named entity: Longleftarrow; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u27f8"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Longleftrightarrow", 
+            "description": "Bad named entity: Longleftrightarrow without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&Longleftrightarrow"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Longleftrightarrow;", 
+            "description": "Named entity: Longleftrightarrow; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u27fa"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Longrightarrow", 
+            "description": "Bad named entity: Longrightarrow without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&Longrightarrow"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Longrightarrow;", 
+            "description": "Named entity: Longrightarrow; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u27f9"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Lopf", 
+            "description": "Bad named entity: Lopf without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&Lopf"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Lopf;", 
+            "description": "Named entity: Lopf; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\ud835\udd43"
+                ]
+            ]
+        }, 
+        {
+            "input": "&LowerLeftArrow", 
+            "description": "Bad named entity: LowerLeftArrow without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&LowerLeftArrow"
+                ]
+            ]
+        }, 
+        {
+            "input": "&LowerLeftArrow;", 
+            "description": "Named entity: LowerLeftArrow; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2199"
+                ]
+            ]
+        }, 
+        {
+            "input": "&LowerRightArrow", 
+            "description": "Bad named entity: LowerRightArrow without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&LowerRightArrow"
+                ]
+            ]
+        }, 
+        {
+            "input": "&LowerRightArrow;", 
+            "description": "Named entity: LowerRightArrow; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2198"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Lscr", 
+            "description": "Bad named entity: Lscr without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&Lscr"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Lscr;", 
+            "description": "Named entity: Lscr; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2112"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Lsh", 
+            "description": "Bad named entity: Lsh without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&Lsh"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Lsh;", 
+            "description": "Named entity: Lsh; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u21b0"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Lstrok", 
+            "description": "Bad named entity: Lstrok without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&Lstrok"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Lstrok;", 
+            "description": "Named entity: Lstrok; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u0141"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Lt", 
+            "description": "Bad named entity: Lt without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&Lt"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Lt;", 
+            "description": "Named entity: Lt; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u226a"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Map", 
+            "description": "Bad named entity: Map without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&Map"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Map;", 
+            "description": "Named entity: Map; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2905"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Mcy", 
+            "description": "Bad named entity: Mcy without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&Mcy"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Mcy;", 
+            "description": "Named entity: Mcy; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u041c"
+                ]
+            ]
+        }, 
+        {
+            "input": "&MediumSpace", 
+            "description": "Bad named entity: MediumSpace without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&MediumSpace"
+                ]
+            ]
+        }, 
+        {
+            "input": "&MediumSpace;", 
+            "description": "Named entity: MediumSpace; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u205f"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Mellintrf", 
+            "description": "Bad named entity: Mellintrf without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&Mellintrf"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Mellintrf;", 
+            "description": "Named entity: Mellintrf; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2133"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Mfr", 
+            "description": "Bad named entity: Mfr without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&Mfr"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Mfr;", 
+            "description": "Named entity: Mfr; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\ud835\udd10"
+                ]
+            ]
+        }, 
+        {
+            "input": "&MinusPlus", 
+            "description": "Bad named entity: MinusPlus without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&MinusPlus"
+                ]
+            ]
+        }, 
+        {
+            "input": "&MinusPlus;", 
+            "description": "Named entity: MinusPlus; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2213"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Mopf", 
+            "description": "Bad named entity: Mopf without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&Mopf"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Mopf;", 
+            "description": "Named entity: Mopf; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\ud835\udd44"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Mscr", 
+            "description": "Bad named entity: Mscr without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&Mscr"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Mscr;", 
+            "description": "Named entity: Mscr; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2133"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Mu", 
+            "description": "Bad named entity: Mu without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&Mu"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Mu;", 
+            "description": "Named entity: Mu; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u039c"
+                ]
+            ]
+        }, 
+        {
+            "input": "&NJcy", 
+            "description": "Bad named entity: NJcy without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&NJcy"
+                ]
+            ]
+        }, 
+        {
+            "input": "&NJcy;", 
+            "description": "Named entity: NJcy; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u040a"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Nacute", 
+            "description": "Bad named entity: Nacute without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&Nacute"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Nacute;", 
+            "description": "Named entity: Nacute; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u0143"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Ncaron", 
+            "description": "Bad named entity: Ncaron without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&Ncaron"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Ncaron;", 
+            "description": "Named entity: Ncaron; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u0147"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Ncedil", 
+            "description": "Bad named entity: Ncedil without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&Ncedil"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Ncedil;", 
+            "description": "Named entity: Ncedil; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u0145"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Ncy", 
+            "description": "Bad named entity: Ncy without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&Ncy"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Ncy;", 
+            "description": "Named entity: Ncy; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u041d"
+                ]
+            ]
+        }, 
+        {
+            "input": "&NegativeMediumSpace", 
+            "description": "Bad named entity: NegativeMediumSpace without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&NegativeMediumSpace"
+                ]
+            ]
+        }, 
+        {
+            "input": "&NegativeMediumSpace;", 
+            "description": "Named entity: NegativeMediumSpace; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u200b"
+                ]
+            ]
+        }, 
+        {
+            "input": "&NegativeThickSpace", 
+            "description": "Bad named entity: NegativeThickSpace without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&NegativeThickSpace"
+                ]
+            ]
+        }, 
+        {
+            "input": "&NegativeThickSpace;", 
+            "description": "Named entity: NegativeThickSpace; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u200b"
+                ]
+            ]
+        }, 
+        {
+            "input": "&NegativeThinSpace", 
+            "description": "Bad named entity: NegativeThinSpace without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&NegativeThinSpace"
+                ]
+            ]
+        }, 
+        {
+            "input": "&NegativeThinSpace;", 
+            "description": "Named entity: NegativeThinSpace; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u200b"
+                ]
+            ]
+        }, 
+        {
+            "input": "&NegativeVeryThinSpace", 
+            "description": "Bad named entity: NegativeVeryThinSpace without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&NegativeVeryThinSpace"
+                ]
+            ]
+        }, 
+        {
+            "input": "&NegativeVeryThinSpace;", 
+            "description": "Named entity: NegativeVeryThinSpace; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u200b"
+                ]
+            ]
+        }, 
+        {
+            "input": "&NestedGreaterGreater", 
+            "description": "Bad named entity: NestedGreaterGreater without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&NestedGreaterGreater"
+                ]
+            ]
+        }, 
+        {
+            "input": "&NestedGreaterGreater;", 
+            "description": "Named entity: NestedGreaterGreater; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u226b"
+                ]
+            ]
+        }, 
+        {
+            "input": "&NestedLessLess", 
+            "description": "Bad named entity: NestedLessLess without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&NestedLessLess"
+                ]
+            ]
+        }, 
+        {
+            "input": "&NestedLessLess;", 
+            "description": "Named entity: NestedLessLess; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u226a"
+                ]
+            ]
+        }, 
+        {
+            "input": "&NewLine", 
+            "description": "Bad named entity: NewLine without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&NewLine"
+                ]
+            ]
+        }, 
+        {
+            "input": "&NewLine;", 
+            "description": "Named entity: NewLine; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\n"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Nfr", 
+            "description": "Bad named entity: Nfr without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&Nfr"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Nfr;", 
+            "description": "Named entity: Nfr; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\ud835\udd11"
+                ]
+            ]
+        }, 
+        {
+            "input": "&NoBreak", 
+            "description": "Bad named entity: NoBreak without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&NoBreak"
+                ]
+            ]
+        }, 
+        {
+            "input": "&NoBreak;", 
+            "description": "Named entity: NoBreak; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2060"
+                ]
+            ]
+        }, 
+        {
+            "input": "&NonBreakingSpace", 
+            "description": "Bad named entity: NonBreakingSpace without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&NonBreakingSpace"
+                ]
+            ]
+        }, 
+        {
+            "input": "&NonBreakingSpace;", 
+            "description": "Named entity: NonBreakingSpace; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u00a0"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Nopf", 
+            "description": "Bad named entity: Nopf without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&Nopf"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Nopf;", 
+            "description": "Named entity: Nopf; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2115"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Not", 
+            "description": "Bad named entity: Not without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&Not"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Not;", 
+            "description": "Named entity: Not; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2aec"
+                ]
+            ]
+        }, 
+        {
+            "input": "&NotCongruent", 
+            "description": "Bad named entity: NotCongruent without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&NotCongruent"
+                ]
+            ]
+        }, 
+        {
+            "input": "&NotCongruent;", 
+            "description": "Named entity: NotCongruent; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2262"
+                ]
+            ]
+        }, 
+        {
+            "input": "&NotCupCap", 
+            "description": "Bad named entity: NotCupCap without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&NotCupCap"
+                ]
+            ]
+        }, 
+        {
+            "input": "&NotCupCap;", 
+            "description": "Named entity: NotCupCap; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u226d"
+                ]
+            ]
+        }, 
+        {
+            "input": "&NotDoubleVerticalBar", 
+            "description": "Bad named entity: NotDoubleVerticalBar without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&NotDoubleVerticalBar"
+                ]
+            ]
+        }, 
+        {
+            "input": "&NotDoubleVerticalBar;", 
+            "description": "Named entity: NotDoubleVerticalBar; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2226"
+                ]
+            ]
+        }, 
+        {
+            "input": "&NotElement", 
+            "description": "Bad named entity: NotElement without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&NotElement"
+                ]
+            ]
+        }, 
+        {
+            "input": "&NotElement;", 
+            "description": "Named entity: NotElement; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2209"
+                ]
+            ]
+        }, 
+        {
+            "input": "&NotEqual", 
+            "description": "Bad named entity: NotEqual without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&NotEqual"
+                ]
+            ]
+        }, 
+        {
+            "input": "&NotEqual;", 
+            "description": "Named entity: NotEqual; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2260"
+                ]
+            ]
+        }, 
+        {
+            "input": "&NotEqualTilde", 
+            "description": "Bad named entity: NotEqualTilde without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&NotEqualTilde"
+                ]
+            ]
+        }, 
+        {
+            "input": "&NotEqualTilde;", 
+            "description": "Named entity: NotEqualTilde; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2242\u0338"
+                ]
+            ]
+        }, 
+        {
+            "input": "&NotExists", 
+            "description": "Bad named entity: NotExists without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&NotExists"
+                ]
+            ]
+        }, 
+        {
+            "input": "&NotExists;", 
+            "description": "Named entity: NotExists; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2204"
+                ]
+            ]
+        }, 
+        {
+            "input": "&NotGreater", 
+            "description": "Bad named entity: NotGreater without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&NotGreater"
+                ]
+            ]
+        }, 
+        {
+            "input": "&NotGreater;", 
+            "description": "Named entity: NotGreater; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u226f"
+                ]
+            ]
+        }, 
+        {
+            "input": "&NotGreaterEqual", 
+            "description": "Bad named entity: NotGreaterEqual without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&NotGreaterEqual"
+                ]
+            ]
+        }, 
+        {
+            "input": "&NotGreaterEqual;", 
+            "description": "Named entity: NotGreaterEqual; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2271"
+                ]
+            ]
+        }, 
+        {
+            "input": "&NotGreaterFullEqual", 
+            "description": "Bad named entity: NotGreaterFullEqual without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&NotGreaterFullEqual"
+                ]
+            ]
+        }, 
+        {
+            "input": "&NotGreaterFullEqual;", 
+            "description": "Named entity: NotGreaterFullEqual; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2267\u0338"
+                ]
+            ]
+        }, 
+        {
+            "input": "&NotGreaterGreater", 
+            "description": "Bad named entity: NotGreaterGreater without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&NotGreaterGreater"
+                ]
+            ]
+        }, 
+        {
+            "input": "&NotGreaterGreater;", 
+            "description": "Named entity: NotGreaterGreater; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u226b\u0338"
+                ]
+            ]
+        }, 
+        {
+            "input": "&NotGreaterLess", 
+            "description": "Bad named entity: NotGreaterLess without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&NotGreaterLess"
+                ]
+            ]
+        }, 
+        {
+            "input": "&NotGreaterLess;", 
+            "description": "Named entity: NotGreaterLess; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2279"
+                ]
+            ]
+        }, 
+        {
+            "input": "&NotGreaterSlantEqual", 
+            "description": "Bad named entity: NotGreaterSlantEqual without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&NotGreaterSlantEqual"
+                ]
+            ]
+        }, 
+        {
+            "input": "&NotGreaterSlantEqual;", 
+            "description": "Named entity: NotGreaterSlantEqual; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2a7e\u0338"
+                ]
+            ]
+        }, 
+        {
+            "input": "&NotGreaterTilde", 
+            "description": "Bad named entity: NotGreaterTilde without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&NotGreaterTilde"
+                ]
+            ]
+        }, 
+        {
+            "input": "&NotGreaterTilde;", 
+            "description": "Named entity: NotGreaterTilde; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2275"
+                ]
+            ]
+        }, 
+        {
+            "input": "&NotHumpDownHump", 
+            "description": "Bad named entity: NotHumpDownHump without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&NotHumpDownHump"
+                ]
+            ]
+        }, 
+        {
+            "input": "&NotHumpDownHump;", 
+            "description": "Named entity: NotHumpDownHump; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u224e\u0338"
+                ]
+            ]
+        }, 
+        {
+            "input": "&NotHumpEqual", 
+            "description": "Bad named entity: NotHumpEqual without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&NotHumpEqual"
+                ]
+            ]
+        }, 
+        {
+            "input": "&NotHumpEqual;", 
+            "description": "Named entity: NotHumpEqual; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u224f\u0338"
+                ]
+            ]
+        }, 
+        {
+            "input": "&NotLeftTriangle", 
+            "description": "Bad named entity: NotLeftTriangle without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&NotLeftTriangle"
+                ]
+            ]
+        }, 
+        {
+            "input": "&NotLeftTriangle;", 
+            "description": "Named entity: NotLeftTriangle; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u22ea"
+                ]
+            ]
+        }, 
+        {
+            "input": "&NotLeftTriangleBar", 
+            "description": "Bad named entity: NotLeftTriangleBar without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&NotLeftTriangleBar"
+                ]
+            ]
+        }, 
+        {
+            "input": "&NotLeftTriangleBar;", 
+            "description": "Named entity: NotLeftTriangleBar; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u29cf\u0338"
+                ]
+            ]
+        }, 
+        {
+            "input": "&NotLeftTriangleEqual", 
+            "description": "Bad named entity: NotLeftTriangleEqual without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&NotLeftTriangleEqual"
+                ]
+            ]
+        }, 
+        {
+            "input": "&NotLeftTriangleEqual;", 
+            "description": "Named entity: NotLeftTriangleEqual; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u22ec"
+                ]
+            ]
+        }, 
+        {
+            "input": "&NotLess", 
+            "description": "Bad named entity: NotLess without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&NotLess"
+                ]
+            ]
+        }, 
+        {
+            "input": "&NotLess;", 
+            "description": "Named entity: NotLess; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u226e"
+                ]
+            ]
+        }, 
+        {
+            "input": "&NotLessEqual", 
+            "description": "Bad named entity: NotLessEqual without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&NotLessEqual"
+                ]
+            ]
+        }, 
+        {
+            "input": "&NotLessEqual;", 
+            "description": "Named entity: NotLessEqual; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2270"
+                ]
+            ]
+        }, 
+        {
+            "input": "&NotLessGreater", 
+            "description": "Bad named entity: NotLessGreater without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&NotLessGreater"
+                ]
+            ]
+        }, 
+        {
+            "input": "&NotLessGreater;", 
+            "description": "Named entity: NotLessGreater; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2278"
+                ]
+            ]
+        }, 
+        {
+            "input": "&NotLessLess", 
+            "description": "Bad named entity: NotLessLess without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&NotLessLess"
+                ]
+            ]
+        }, 
+        {
+            "input": "&NotLessLess;", 
+            "description": "Named entity: NotLessLess; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u226a\u0338"
+                ]
+            ]
+        }, 
+        {
+            "input": "&NotLessSlantEqual", 
+            "description": "Bad named entity: NotLessSlantEqual without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&NotLessSlantEqual"
+                ]
+            ]
+        }, 
+        {
+            "input": "&NotLessSlantEqual;", 
+            "description": "Named entity: NotLessSlantEqual; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2a7d\u0338"
+                ]
+            ]
+        }, 
+        {
+            "input": "&NotLessTilde", 
+            "description": "Bad named entity: NotLessTilde without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&NotLessTilde"
+                ]
+            ]
+        }, 
+        {
+            "input": "&NotLessTilde;", 
+            "description": "Named entity: NotLessTilde; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2274"
+                ]
+            ]
+        }, 
+        {
+            "input": "&NotNestedGreaterGreater", 
+            "description": "Bad named entity: NotNestedGreaterGreater without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&NotNestedGreaterGreater"
+                ]
+            ]
+        }, 
+        {
+            "input": "&NotNestedGreaterGreater;", 
+            "description": "Named entity: NotNestedGreaterGreater; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2aa2\u0338"
+                ]
+            ]
+        }, 
+        {
+            "input": "&NotNestedLessLess", 
+            "description": "Bad named entity: NotNestedLessLess without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&NotNestedLessLess"
+                ]
+            ]
+        }, 
+        {
+            "input": "&NotNestedLessLess;", 
+            "description": "Named entity: NotNestedLessLess; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2aa1\u0338"
+                ]
+            ]
+        }, 
+        {
+            "input": "&NotPrecedes", 
+            "description": "Bad named entity: NotPrecedes without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&NotPrecedes"
+                ]
+            ]
+        }, 
+        {
+            "input": "&NotPrecedes;", 
+            "description": "Named entity: NotPrecedes; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2280"
+                ]
+            ]
+        }, 
+        {
+            "input": "&NotPrecedesEqual", 
+            "description": "Bad named entity: NotPrecedesEqual without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&NotPrecedesEqual"
+                ]
+            ]
+        }, 
+        {
+            "input": "&NotPrecedesEqual;", 
+            "description": "Named entity: NotPrecedesEqual; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2aaf\u0338"
+                ]
+            ]
+        }, 
+        {
+            "input": "&NotPrecedesSlantEqual", 
+            "description": "Bad named entity: NotPrecedesSlantEqual without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&NotPrecedesSlantEqual"
+                ]
+            ]
+        }, 
+        {
+            "input": "&NotPrecedesSlantEqual;", 
+            "description": "Named entity: NotPrecedesSlantEqual; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u22e0"
+                ]
+            ]
+        }, 
+        {
+            "input": "&NotReverseElement", 
+            "description": "Bad named entity: NotReverseElement without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&NotReverseElement"
+                ]
+            ]
+        }, 
+        {
+            "input": "&NotReverseElement;", 
+            "description": "Named entity: NotReverseElement; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u220c"
+                ]
+            ]
+        }, 
+        {
+            "input": "&NotRightTriangle", 
+            "description": "Bad named entity: NotRightTriangle without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&NotRightTriangle"
+                ]
+            ]
+        }, 
+        {
+            "input": "&NotRightTriangle;", 
+            "description": "Named entity: NotRightTriangle; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u22eb"
+                ]
+            ]
+        }, 
+        {
+            "input": "&NotRightTriangleBar", 
+            "description": "Bad named entity: NotRightTriangleBar without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&NotRightTriangleBar"
+                ]
+            ]
+        }, 
+        {
+            "input": "&NotRightTriangleBar;", 
+            "description": "Named entity: NotRightTriangleBar; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u29d0\u0338"
+                ]
+            ]
+        }, 
+        {
+            "input": "&NotRightTriangleEqual", 
+            "description": "Bad named entity: NotRightTriangleEqual without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&NotRightTriangleEqual"
+                ]
+            ]
+        }, 
+        {
+            "input": "&NotRightTriangleEqual;", 
+            "description": "Named entity: NotRightTriangleEqual; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u22ed"
+                ]
+            ]
+        }, 
+        {
+            "input": "&NotSquareSubset", 
+            "description": "Bad named entity: NotSquareSubset without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&NotSquareSubset"
+                ]
+            ]
+        }, 
+        {
+            "input": "&NotSquareSubset;", 
+            "description": "Named entity: NotSquareSubset; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u228f\u0338"
+                ]
+            ]
+        }, 
+        {
+            "input": "&NotSquareSubsetEqual", 
+            "description": "Bad named entity: NotSquareSubsetEqual without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&NotSquareSubsetEqual"
+                ]
+            ]
+        }, 
+        {
+            "input": "&NotSquareSubsetEqual;", 
+            "description": "Named entity: NotSquareSubsetEqual; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u22e2"
+                ]
+            ]
+        }, 
+        {
+            "input": "&NotSquareSuperset", 
+            "description": "Bad named entity: NotSquareSuperset without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&NotSquareSuperset"
+                ]
+            ]
+        }, 
+        {
+            "input": "&NotSquareSuperset;", 
+            "description": "Named entity: NotSquareSuperset; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2290\u0338"
+                ]
+            ]
+        }, 
+        {
+            "input": "&NotSquareSupersetEqual", 
+            "description": "Bad named entity: NotSquareSupersetEqual without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&NotSquareSupersetEqual"
+                ]
+            ]
+        }, 
+        {
+            "input": "&NotSquareSupersetEqual;", 
+            "description": "Named entity: NotSquareSupersetEqual; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u22e3"
+                ]
+            ]
+        }, 
+        {
+            "input": "&NotSubset", 
+            "description": "Bad named entity: NotSubset without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&NotSubset"
+                ]
+            ]
+        }, 
+        {
+            "input": "&NotSubset;", 
+            "description": "Named entity: NotSubset; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2282\u20d2"
+                ]
+            ]
+        }, 
+        {
+            "input": "&NotSubsetEqual", 
+            "description": "Bad named entity: NotSubsetEqual without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&NotSubsetEqual"
+                ]
+            ]
+        }, 
+        {
+            "input": "&NotSubsetEqual;", 
+            "description": "Named entity: NotSubsetEqual; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2288"
+                ]
+            ]
+        }, 
+        {
+            "input": "&NotSucceeds", 
+            "description": "Bad named entity: NotSucceeds without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&NotSucceeds"
+                ]
+            ]
+        }, 
+        {
+            "input": "&NotSucceeds;", 
+            "description": "Named entity: NotSucceeds; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2281"
+                ]
+            ]
+        }, 
+        {
+            "input": "&NotSucceedsEqual", 
+            "description": "Bad named entity: NotSucceedsEqual without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&NotSucceedsEqual"
+                ]
+            ]
+        }, 
+        {
+            "input": "&NotSucceedsEqual;", 
+            "description": "Named entity: NotSucceedsEqual; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2ab0\u0338"
+                ]
+            ]
+        }, 
+        {
+            "input": "&NotSucceedsSlantEqual", 
+            "description": "Bad named entity: NotSucceedsSlantEqual without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&NotSucceedsSlantEqual"
+                ]
+            ]
+        }, 
+        {
+            "input": "&NotSucceedsSlantEqual;", 
+            "description": "Named entity: NotSucceedsSlantEqual; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u22e1"
+                ]
+            ]
+        }, 
+        {
+            "input": "&NotSucceedsTilde", 
+            "description": "Bad named entity: NotSucceedsTilde without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&NotSucceedsTilde"
+                ]
+            ]
+        }, 
+        {
+            "input": "&NotSucceedsTilde;", 
+            "description": "Named entity: NotSucceedsTilde; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u227f\u0338"
+                ]
+            ]
+        }, 
+        {
+            "input": "&NotSuperset", 
+            "description": "Bad named entity: NotSuperset without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&NotSuperset"
+                ]
+            ]
+        }, 
+        {
+            "input": "&NotSuperset;", 
+            "description": "Named entity: NotSuperset; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2283\u20d2"
+                ]
+            ]
+        }, 
+        {
+            "input": "&NotSupersetEqual", 
+            "description": "Bad named entity: NotSupersetEqual without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&NotSupersetEqual"
+                ]
+            ]
+        }, 
+        {
+            "input": "&NotSupersetEqual;", 
+            "description": "Named entity: NotSupersetEqual; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2289"
+                ]
+            ]
+        }, 
+        {
+            "input": "&NotTilde", 
+            "description": "Bad named entity: NotTilde without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&NotTilde"
+                ]
+            ]
+        }, 
+        {
+            "input": "&NotTilde;", 
+            "description": "Named entity: NotTilde; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2241"
+                ]
+            ]
+        }, 
+        {
+            "input": "&NotTildeEqual", 
+            "description": "Bad named entity: NotTildeEqual without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&NotTildeEqual"
+                ]
+            ]
+        }, 
+        {
+            "input": "&NotTildeEqual;", 
+            "description": "Named entity: NotTildeEqual; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2244"
+                ]
+            ]
+        }, 
+        {
+            "input": "&NotTildeFullEqual", 
+            "description": "Bad named entity: NotTildeFullEqual without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&NotTildeFullEqual"
+                ]
+            ]
+        }, 
+        {
+            "input": "&NotTildeFullEqual;", 
+            "description": "Named entity: NotTildeFullEqual; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2247"
+                ]
+            ]
+        }, 
+        {
+            "input": "&NotTildeTilde", 
+            "description": "Bad named entity: NotTildeTilde without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&NotTildeTilde"
+                ]
+            ]
+        }, 
+        {
+            "input": "&NotTildeTilde;", 
+            "description": "Named entity: NotTildeTilde; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2249"
+                ]
+            ]
+        }, 
+        {
+            "input": "&NotVerticalBar", 
+            "description": "Bad named entity: NotVerticalBar without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&NotVerticalBar"
+                ]
+            ]
+        }, 
+        {
+            "input": "&NotVerticalBar;", 
+            "description": "Named entity: NotVerticalBar; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2224"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Nscr", 
+            "description": "Bad named entity: Nscr without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&Nscr"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Nscr;", 
+            "description": "Named entity: Nscr; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\ud835\udca9"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Ntilde", 
+            "description": "Named entity: Ntilde without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "\u00d1"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Ntilde;", 
+            "description": "Named entity: Ntilde; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u00d1"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Nu", 
+            "description": "Bad named entity: Nu without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&Nu"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Nu;", 
+            "description": "Named entity: Nu; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u039d"
+                ]
+            ]
+        }, 
+        {
+            "input": "&OElig", 
+            "description": "Bad named entity: OElig without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&OElig"
+                ]
+            ]
+        }, 
+        {
+            "input": "&OElig;", 
+            "description": "Named entity: OElig; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u0152"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Oacute", 
+            "description": "Named entity: Oacute without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "\u00d3"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Oacute;", 
+            "description": "Named entity: Oacute; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u00d3"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Ocirc", 
+            "description": "Named entity: Ocirc without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "\u00d4"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Ocirc;", 
+            "description": "Named entity: Ocirc; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u00d4"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Ocy", 
+            "description": "Bad named entity: Ocy without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&Ocy"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Ocy;", 
+            "description": "Named entity: Ocy; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u041e"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Odblac", 
+            "description": "Bad named entity: Odblac without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&Odblac"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Odblac;", 
+            "description": "Named entity: Odblac; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u0150"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Ofr", 
+            "description": "Bad named entity: Ofr without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&Ofr"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Ofr;", 
+            "description": "Named entity: Ofr; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\ud835\udd12"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Ograve", 
+            "description": "Named entity: Ograve without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "\u00d2"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Ograve;", 
+            "description": "Named entity: Ograve; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u00d2"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Omacr", 
+            "description": "Bad named entity: Omacr without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&Omacr"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Omacr;", 
+            "description": "Named entity: Omacr; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u014c"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Omega", 
+            "description": "Bad named entity: Omega without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&Omega"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Omega;", 
+            "description": "Named entity: Omega; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u03a9"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Omicron", 
+            "description": "Bad named entity: Omicron without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&Omicron"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Omicron;", 
+            "description": "Named entity: Omicron; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u039f"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Oopf", 
+            "description": "Bad named entity: Oopf without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&Oopf"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Oopf;", 
+            "description": "Named entity: Oopf; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\ud835\udd46"
+                ]
+            ]
+        }, 
+        {
+            "input": "&OpenCurlyDoubleQuote", 
+            "description": "Bad named entity: OpenCurlyDoubleQuote without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&OpenCurlyDoubleQuote"
+                ]
+            ]
+        }, 
+        {
+            "input": "&OpenCurlyDoubleQuote;", 
+            "description": "Named entity: OpenCurlyDoubleQuote; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u201c"
+                ]
+            ]
+        }, 
+        {
+            "input": "&OpenCurlyQuote", 
+            "description": "Bad named entity: OpenCurlyQuote without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&OpenCurlyQuote"
+                ]
+            ]
+        }, 
+        {
+            "input": "&OpenCurlyQuote;", 
+            "description": "Named entity: OpenCurlyQuote; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2018"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Or", 
+            "description": "Bad named entity: Or without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&Or"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Or;", 
+            "description": "Named entity: Or; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2a54"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Oscr", 
+            "description": "Bad named entity: Oscr without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&Oscr"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Oscr;", 
+            "description": "Named entity: Oscr; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\ud835\udcaa"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Oslash", 
+            "description": "Named entity: Oslash without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "\u00d8"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Oslash;", 
+            "description": "Named entity: Oslash; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u00d8"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Otilde", 
+            "description": "Named entity: Otilde without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "\u00d5"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Otilde;", 
+            "description": "Named entity: Otilde; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u00d5"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Otimes", 
+            "description": "Bad named entity: Otimes without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&Otimes"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Otimes;", 
+            "description": "Named entity: Otimes; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2a37"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Ouml", 
+            "description": "Named entity: Ouml without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "\u00d6"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Ouml;", 
+            "description": "Named entity: Ouml; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u00d6"
+                ]
+            ]
+        }, 
+        {
+            "input": "&OverBar", 
+            "description": "Bad named entity: OverBar without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&OverBar"
+                ]
+            ]
+        }, 
+        {
+            "input": "&OverBar;", 
+            "description": "Named entity: OverBar; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u203e"
+                ]
+            ]
+        }, 
+        {
+            "input": "&OverBrace", 
+            "description": "Bad named entity: OverBrace without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&OverBrace"
+                ]
+            ]
+        }, 
+        {
+            "input": "&OverBrace;", 
+            "description": "Named entity: OverBrace; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u23de"
+                ]
+            ]
+        }, 
+        {
+            "input": "&OverBracket", 
+            "description": "Bad named entity: OverBracket without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&OverBracket"
+                ]
+            ]
+        }, 
+        {
+            "input": "&OverBracket;", 
+            "description": "Named entity: OverBracket; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u23b4"
+                ]
+            ]
+        }, 
+        {
+            "input": "&OverParenthesis", 
+            "description": "Bad named entity: OverParenthesis without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&OverParenthesis"
+                ]
+            ]
+        }, 
+        {
+            "input": "&OverParenthesis;", 
+            "description": "Named entity: OverParenthesis; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u23dc"
+                ]
+            ]
+        }, 
+        {
+            "input": "&PartialD", 
+            "description": "Bad named entity: PartialD without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&PartialD"
+                ]
+            ]
+        }, 
+        {
+            "input": "&PartialD;", 
+            "description": "Named entity: PartialD; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2202"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Pcy", 
+            "description": "Bad named entity: Pcy without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&Pcy"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Pcy;", 
+            "description": "Named entity: Pcy; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u041f"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Pfr", 
+            "description": "Bad named entity: Pfr without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&Pfr"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Pfr;", 
+            "description": "Named entity: Pfr; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\ud835\udd13"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Phi", 
+            "description": "Bad named entity: Phi without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&Phi"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Phi;", 
+            "description": "Named entity: Phi; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u03a6"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Pi", 
+            "description": "Bad named entity: Pi without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&Pi"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Pi;", 
+            "description": "Named entity: Pi; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u03a0"
+                ]
+            ]
+        }, 
+        {
+            "input": "&PlusMinus", 
+            "description": "Bad named entity: PlusMinus without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&PlusMinus"
+                ]
+            ]
+        }, 
+        {
+            "input": "&PlusMinus;", 
+            "description": "Named entity: PlusMinus; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u00b1"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Poincareplane", 
+            "description": "Bad named entity: Poincareplane without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&Poincareplane"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Poincareplane;", 
+            "description": "Named entity: Poincareplane; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u210c"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Popf", 
+            "description": "Bad named entity: Popf without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&Popf"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Popf;", 
+            "description": "Named entity: Popf; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2119"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Pr", 
+            "description": "Bad named entity: Pr without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&Pr"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Pr;", 
+            "description": "Named entity: Pr; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2abb"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Precedes", 
+            "description": "Bad named entity: Precedes without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&Precedes"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Precedes;", 
+            "description": "Named entity: Precedes; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u227a"
+                ]
+            ]
+        }, 
+        {
+            "input": "&PrecedesEqual", 
+            "description": "Bad named entity: PrecedesEqual without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&PrecedesEqual"
+                ]
+            ]
+        }, 
+        {
+            "input": "&PrecedesEqual;", 
+            "description": "Named entity: PrecedesEqual; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2aaf"
+                ]
+            ]
+        }, 
+        {
+            "input": "&PrecedesSlantEqual", 
+            "description": "Bad named entity: PrecedesSlantEqual without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&PrecedesSlantEqual"
+                ]
+            ]
+        }, 
+        {
+            "input": "&PrecedesSlantEqual;", 
+            "description": "Named entity: PrecedesSlantEqual; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u227c"
+                ]
+            ]
+        }, 
+        {
+            "input": "&PrecedesTilde", 
+            "description": "Bad named entity: PrecedesTilde without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&PrecedesTilde"
+                ]
+            ]
+        }, 
+        {
+            "input": "&PrecedesTilde;", 
+            "description": "Named entity: PrecedesTilde; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u227e"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Prime", 
+            "description": "Bad named entity: Prime without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&Prime"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Prime;", 
+            "description": "Named entity: Prime; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2033"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Product", 
+            "description": "Bad named entity: Product without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&Product"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Product;", 
+            "description": "Named entity: Product; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u220f"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Proportion", 
+            "description": "Bad named entity: Proportion without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&Proportion"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Proportion;", 
+            "description": "Named entity: Proportion; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2237"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Proportional", 
+            "description": "Bad named entity: Proportional without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&Proportional"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Proportional;", 
+            "description": "Named entity: Proportional; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u221d"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Pscr", 
+            "description": "Bad named entity: Pscr without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&Pscr"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Pscr;", 
+            "description": "Named entity: Pscr; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\ud835\udcab"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Psi", 
+            "description": "Bad named entity: Psi without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&Psi"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Psi;", 
+            "description": "Named entity: Psi; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u03a8"
+                ]
+            ]
+        }, 
+        {
+            "input": "&QUOT", 
+            "description": "Named entity: QUOT without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "\""
+                ]
+            ]
+        }, 
+        {
+            "input": "&QUOT;", 
+            "description": "Named entity: QUOT; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\""
+                ]
+            ]
+        }, 
+        {
+            "input": "&Qfr", 
+            "description": "Bad named entity: Qfr without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&Qfr"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Qfr;", 
+            "description": "Named entity: Qfr; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\ud835\udd14"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Qopf", 
+            "description": "Bad named entity: Qopf without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&Qopf"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Qopf;", 
+            "description": "Named entity: Qopf; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u211a"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Qscr", 
+            "description": "Bad named entity: Qscr without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&Qscr"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Qscr;", 
+            "description": "Named entity: Qscr; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\ud835\udcac"
+                ]
+            ]
+        }, 
+        {
+            "input": "&RBarr", 
+            "description": "Bad named entity: RBarr without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&RBarr"
+                ]
+            ]
+        }, 
+        {
+            "input": "&RBarr;", 
+            "description": "Named entity: RBarr; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2910"
+                ]
+            ]
+        }, 
+        {
+            "input": "&REG", 
+            "description": "Named entity: REG without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "\u00ae"
+                ]
+            ]
+        }, 
+        {
+            "input": "&REG;", 
+            "description": "Named entity: REG; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u00ae"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Racute", 
+            "description": "Bad named entity: Racute without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&Racute"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Racute;", 
+            "description": "Named entity: Racute; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u0154"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Rang", 
+            "description": "Bad named entity: Rang without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&Rang"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Rang;", 
+            "description": "Named entity: Rang; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u27eb"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Rarr", 
+            "description": "Bad named entity: Rarr without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&Rarr"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Rarr;", 
+            "description": "Named entity: Rarr; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u21a0"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Rarrtl", 
+            "description": "Bad named entity: Rarrtl without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&Rarrtl"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Rarrtl;", 
+            "description": "Named entity: Rarrtl; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2916"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Rcaron", 
+            "description": "Bad named entity: Rcaron without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&Rcaron"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Rcaron;", 
+            "description": "Named entity: Rcaron; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u0158"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Rcedil", 
+            "description": "Bad named entity: Rcedil without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&Rcedil"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Rcedil;", 
+            "description": "Named entity: Rcedil; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u0156"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Rcy", 
+            "description": "Bad named entity: Rcy without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&Rcy"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Rcy;", 
+            "description": "Named entity: Rcy; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u0420"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Re", 
+            "description": "Bad named entity: Re without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&Re"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Re;", 
+            "description": "Named entity: Re; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u211c"
+                ]
+            ]
+        }, 
+        {
+            "input": "&ReverseElement", 
+            "description": "Bad named entity: ReverseElement without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&ReverseElement"
+                ]
+            ]
+        }, 
+        {
+            "input": "&ReverseElement;", 
+            "description": "Named entity: ReverseElement; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u220b"
+                ]
+            ]
+        }, 
+        {
+            "input": "&ReverseEquilibrium", 
+            "description": "Bad named entity: ReverseEquilibrium without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&ReverseEquilibrium"
+                ]
+            ]
+        }, 
+        {
+            "input": "&ReverseEquilibrium;", 
+            "description": "Named entity: ReverseEquilibrium; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u21cb"
+                ]
+            ]
+        }, 
+        {
+            "input": "&ReverseUpEquilibrium", 
+            "description": "Bad named entity: ReverseUpEquilibrium without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&ReverseUpEquilibrium"
+                ]
+            ]
+        }, 
+        {
+            "input": "&ReverseUpEquilibrium;", 
+            "description": "Named entity: ReverseUpEquilibrium; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u296f"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Rfr", 
+            "description": "Bad named entity: Rfr without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&Rfr"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Rfr;", 
+            "description": "Named entity: Rfr; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u211c"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Rho", 
+            "description": "Bad named entity: Rho without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&Rho"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Rho;", 
+            "description": "Named entity: Rho; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u03a1"
+                ]
+            ]
+        }, 
+        {
+            "input": "&RightAngleBracket", 
+            "description": "Bad named entity: RightAngleBracket without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&RightAngleBracket"
+                ]
+            ]
+        }, 
+        {
+            "input": "&RightAngleBracket;", 
+            "description": "Named entity: RightAngleBracket; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u27e9"
+                ]
+            ]
+        }, 
+        {
+            "input": "&RightArrow", 
+            "description": "Bad named entity: RightArrow without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&RightArrow"
+                ]
+            ]
+        }, 
+        {
+            "input": "&RightArrow;", 
+            "description": "Named entity: RightArrow; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2192"
+                ]
+            ]
+        }, 
+        {
+            "input": "&RightArrowBar", 
+            "description": "Bad named entity: RightArrowBar without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&RightArrowBar"
+                ]
+            ]
+        }, 
+        {
+            "input": "&RightArrowBar;", 
+            "description": "Named entity: RightArrowBar; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u21e5"
+                ]
+            ]
+        }, 
+        {
+            "input": "&RightArrowLeftArrow", 
+            "description": "Bad named entity: RightArrowLeftArrow without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&RightArrowLeftArrow"
+                ]
+            ]
+        }, 
+        {
+            "input": "&RightArrowLeftArrow;", 
+            "description": "Named entity: RightArrowLeftArrow; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u21c4"
+                ]
+            ]
+        }, 
+        {
+            "input": "&RightCeiling", 
+            "description": "Bad named entity: RightCeiling without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&RightCeiling"
+                ]
+            ]
+        }, 
+        {
+            "input": "&RightCeiling;", 
+            "description": "Named entity: RightCeiling; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2309"
+                ]
+            ]
+        }, 
+        {
+            "input": "&RightDoubleBracket", 
+            "description": "Bad named entity: RightDoubleBracket without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&RightDoubleBracket"
+                ]
+            ]
+        }, 
+        {
+            "input": "&RightDoubleBracket;", 
+            "description": "Named entity: RightDoubleBracket; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u27e7"
+                ]
+            ]
+        }, 
+        {
+            "input": "&RightDownTeeVector", 
+            "description": "Bad named entity: RightDownTeeVector without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&RightDownTeeVector"
+                ]
+            ]
+        }, 
+        {
+            "input": "&RightDownTeeVector;", 
+            "description": "Named entity: RightDownTeeVector; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u295d"
+                ]
+            ]
+        }, 
+        {
+            "input": "&RightDownVector", 
+            "description": "Bad named entity: RightDownVector without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&RightDownVector"
+                ]
+            ]
+        }, 
+        {
+            "input": "&RightDownVector;", 
+            "description": "Named entity: RightDownVector; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u21c2"
+                ]
+            ]
+        }, 
+        {
+            "input": "&RightDownVectorBar", 
+            "description": "Bad named entity: RightDownVectorBar without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&RightDownVectorBar"
+                ]
+            ]
+        }, 
+        {
+            "input": "&RightDownVectorBar;", 
+            "description": "Named entity: RightDownVectorBar; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2955"
+                ]
+            ]
+        }, 
+        {
+            "input": "&RightFloor", 
+            "description": "Bad named entity: RightFloor without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&RightFloor"
+                ]
+            ]
+        }, 
+        {
+            "input": "&RightFloor;", 
+            "description": "Named entity: RightFloor; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u230b"
+                ]
+            ]
+        }, 
+        {
+            "input": "&RightTee", 
+            "description": "Bad named entity: RightTee without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&RightTee"
+                ]
+            ]
+        }, 
+        {
+            "input": "&RightTee;", 
+            "description": "Named entity: RightTee; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u22a2"
+                ]
+            ]
+        }, 
+        {
+            "input": "&RightTeeArrow", 
+            "description": "Bad named entity: RightTeeArrow without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&RightTeeArrow"
+                ]
+            ]
+        }, 
+        {
+            "input": "&RightTeeArrow;", 
+            "description": "Named entity: RightTeeArrow; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u21a6"
+                ]
+            ]
+        }, 
+        {
+            "input": "&RightTeeVector", 
+            "description": "Bad named entity: RightTeeVector without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&RightTeeVector"
+                ]
+            ]
+        }, 
+        {
+            "input": "&RightTeeVector;", 
+            "description": "Named entity: RightTeeVector; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u295b"
+                ]
+            ]
+        }, 
+        {
+            "input": "&RightTriangle", 
+            "description": "Bad named entity: RightTriangle without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&RightTriangle"
+                ]
+            ]
+        }, 
+        {
+            "input": "&RightTriangle;", 
+            "description": "Named entity: RightTriangle; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u22b3"
+                ]
+            ]
+        }, 
+        {
+            "input": "&RightTriangleBar", 
+            "description": "Bad named entity: RightTriangleBar without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&RightTriangleBar"
+                ]
+            ]
+        }, 
+        {
+            "input": "&RightTriangleBar;", 
+            "description": "Named entity: RightTriangleBar; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u29d0"
+                ]
+            ]
+        }, 
+        {
+            "input": "&RightTriangleEqual", 
+            "description": "Bad named entity: RightTriangleEqual without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&RightTriangleEqual"
+                ]
+            ]
+        }, 
+        {
+            "input": "&RightTriangleEqual;", 
+            "description": "Named entity: RightTriangleEqual; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u22b5"
+                ]
+            ]
+        }, 
+        {
+            "input": "&RightUpDownVector", 
+            "description": "Bad named entity: RightUpDownVector without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&RightUpDownVector"
+                ]
+            ]
+        }, 
+        {
+            "input": "&RightUpDownVector;", 
+            "description": "Named entity: RightUpDownVector; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u294f"
+                ]
+            ]
+        }, 
+        {
+            "input": "&RightUpTeeVector", 
+            "description": "Bad named entity: RightUpTeeVector without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&RightUpTeeVector"
+                ]
+            ]
+        }, 
+        {
+            "input": "&RightUpTeeVector;", 
+            "description": "Named entity: RightUpTeeVector; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u295c"
+                ]
+            ]
+        }, 
+        {
+            "input": "&RightUpVector", 
+            "description": "Bad named entity: RightUpVector without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&RightUpVector"
+                ]
+            ]
+        }, 
+        {
+            "input": "&RightUpVector;", 
+            "description": "Named entity: RightUpVector; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u21be"
+                ]
+            ]
+        }, 
+        {
+            "input": "&RightUpVectorBar", 
+            "description": "Bad named entity: RightUpVectorBar without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&RightUpVectorBar"
+                ]
+            ]
+        }, 
+        {
+            "input": "&RightUpVectorBar;", 
+            "description": "Named entity: RightUpVectorBar; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2954"
+                ]
+            ]
+        }, 
+        {
+            "input": "&RightVector", 
+            "description": "Bad named entity: RightVector without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&RightVector"
+                ]
+            ]
+        }, 
+        {
+            "input": "&RightVector;", 
+            "description": "Named entity: RightVector; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u21c0"
+                ]
+            ]
+        }, 
+        {
+            "input": "&RightVectorBar", 
+            "description": "Bad named entity: RightVectorBar without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&RightVectorBar"
+                ]
+            ]
+        }, 
+        {
+            "input": "&RightVectorBar;", 
+            "description": "Named entity: RightVectorBar; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2953"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Rightarrow", 
+            "description": "Bad named entity: Rightarrow without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&Rightarrow"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Rightarrow;", 
+            "description": "Named entity: Rightarrow; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u21d2"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Ropf", 
+            "description": "Bad named entity: Ropf without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&Ropf"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Ropf;", 
+            "description": "Named entity: Ropf; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u211d"
+                ]
+            ]
+        }, 
+        {
+            "input": "&RoundImplies", 
+            "description": "Bad named entity: RoundImplies without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&RoundImplies"
+                ]
+            ]
+        }, 
+        {
+            "input": "&RoundImplies;", 
+            "description": "Named entity: RoundImplies; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2970"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Rrightarrow", 
+            "description": "Bad named entity: Rrightarrow without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&Rrightarrow"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Rrightarrow;", 
+            "description": "Named entity: Rrightarrow; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u21db"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Rscr", 
+            "description": "Bad named entity: Rscr without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&Rscr"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Rscr;", 
+            "description": "Named entity: Rscr; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u211b"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Rsh", 
+            "description": "Bad named entity: Rsh without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&Rsh"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Rsh;", 
+            "description": "Named entity: Rsh; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u21b1"
+                ]
+            ]
+        }, 
+        {
+            "input": "&RuleDelayed", 
+            "description": "Bad named entity: RuleDelayed without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&RuleDelayed"
+                ]
+            ]
+        }, 
+        {
+            "input": "&RuleDelayed;", 
+            "description": "Named entity: RuleDelayed; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u29f4"
+                ]
+            ]
+        }, 
+        {
+            "input": "&SHCHcy", 
+            "description": "Bad named entity: SHCHcy without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&SHCHcy"
+                ]
+            ]
+        }, 
+        {
+            "input": "&SHCHcy;", 
+            "description": "Named entity: SHCHcy; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u0429"
+                ]
+            ]
+        }, 
+        {
+            "input": "&SHcy", 
+            "description": "Bad named entity: SHcy without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&SHcy"
+                ]
+            ]
+        }, 
+        {
+            "input": "&SHcy;", 
+            "description": "Named entity: SHcy; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u0428"
+                ]
+            ]
+        }, 
+        {
+            "input": "&SOFTcy", 
+            "description": "Bad named entity: SOFTcy without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&SOFTcy"
+                ]
+            ]
+        }, 
+        {
+            "input": "&SOFTcy;", 
+            "description": "Named entity: SOFTcy; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u042c"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Sacute", 
+            "description": "Bad named entity: Sacute without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&Sacute"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Sacute;", 
+            "description": "Named entity: Sacute; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u015a"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Sc", 
+            "description": "Bad named entity: Sc without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&Sc"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Sc;", 
+            "description": "Named entity: Sc; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2abc"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Scaron", 
+            "description": "Bad named entity: Scaron without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&Scaron"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Scaron;", 
+            "description": "Named entity: Scaron; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u0160"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Scedil", 
+            "description": "Bad named entity: Scedil without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&Scedil"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Scedil;", 
+            "description": "Named entity: Scedil; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u015e"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Scirc", 
+            "description": "Bad named entity: Scirc without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&Scirc"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Scirc;", 
+            "description": "Named entity: Scirc; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u015c"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Scy", 
+            "description": "Bad named entity: Scy without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&Scy"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Scy;", 
+            "description": "Named entity: Scy; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u0421"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Sfr", 
+            "description": "Bad named entity: Sfr without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&Sfr"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Sfr;", 
+            "description": "Named entity: Sfr; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\ud835\udd16"
+                ]
+            ]
+        }, 
+        {
+            "input": "&ShortDownArrow", 
+            "description": "Bad named entity: ShortDownArrow without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&ShortDownArrow"
+                ]
+            ]
+        }, 
+        {
+            "input": "&ShortDownArrow;", 
+            "description": "Named entity: ShortDownArrow; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2193"
+                ]
+            ]
+        }, 
+        {
+            "input": "&ShortLeftArrow", 
+            "description": "Bad named entity: ShortLeftArrow without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&ShortLeftArrow"
+                ]
+            ]
+        }, 
+        {
+            "input": "&ShortLeftArrow;", 
+            "description": "Named entity: ShortLeftArrow; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2190"
+                ]
+            ]
+        }, 
+        {
+            "input": "&ShortRightArrow", 
+            "description": "Bad named entity: ShortRightArrow without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&ShortRightArrow"
+                ]
+            ]
+        }, 
+        {
+            "input": "&ShortRightArrow;", 
+            "description": "Named entity: ShortRightArrow; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2192"
+                ]
+            ]
+        }, 
+        {
+            "input": "&ShortUpArrow", 
+            "description": "Bad named entity: ShortUpArrow without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&ShortUpArrow"
+                ]
+            ]
+        }, 
+        {
+            "input": "&ShortUpArrow;", 
+            "description": "Named entity: ShortUpArrow; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2191"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Sigma", 
+            "description": "Bad named entity: Sigma without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&Sigma"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Sigma;", 
+            "description": "Named entity: Sigma; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u03a3"
+                ]
+            ]
+        }, 
+        {
+            "input": "&SmallCircle", 
+            "description": "Bad named entity: SmallCircle without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&SmallCircle"
+                ]
+            ]
+        }, 
+        {
+            "input": "&SmallCircle;", 
+            "description": "Named entity: SmallCircle; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2218"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Sopf", 
+            "description": "Bad named entity: Sopf without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&Sopf"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Sopf;", 
+            "description": "Named entity: Sopf; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\ud835\udd4a"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Sqrt", 
+            "description": "Bad named entity: Sqrt without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&Sqrt"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Sqrt;", 
+            "description": "Named entity: Sqrt; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u221a"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Square", 
+            "description": "Bad named entity: Square without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&Square"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Square;", 
+            "description": "Named entity: Square; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u25a1"
+                ]
+            ]
+        }, 
+        {
+            "input": "&SquareIntersection", 
+            "description": "Bad named entity: SquareIntersection without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&SquareIntersection"
+                ]
+            ]
+        }, 
+        {
+            "input": "&SquareIntersection;", 
+            "description": "Named entity: SquareIntersection; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2293"
+                ]
+            ]
+        }, 
+        {
+            "input": "&SquareSubset", 
+            "description": "Bad named entity: SquareSubset without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&SquareSubset"
+                ]
+            ]
+        }, 
+        {
+            "input": "&SquareSubset;", 
+            "description": "Named entity: SquareSubset; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u228f"
+                ]
+            ]
+        }, 
+        {
+            "input": "&SquareSubsetEqual", 
+            "description": "Bad named entity: SquareSubsetEqual without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&SquareSubsetEqual"
+                ]
+            ]
+        }, 
+        {
+            "input": "&SquareSubsetEqual;", 
+            "description": "Named entity: SquareSubsetEqual; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2291"
+                ]
+            ]
+        }, 
+        {
+            "input": "&SquareSuperset", 
+            "description": "Bad named entity: SquareSuperset without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&SquareSuperset"
+                ]
+            ]
+        }, 
+        {
+            "input": "&SquareSuperset;", 
+            "description": "Named entity: SquareSuperset; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2290"
+                ]
+            ]
+        }, 
+        {
+            "input": "&SquareSupersetEqual", 
+            "description": "Bad named entity: SquareSupersetEqual without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&SquareSupersetEqual"
+                ]
+            ]
+        }, 
+        {
+            "input": "&SquareSupersetEqual;", 
+            "description": "Named entity: SquareSupersetEqual; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2292"
+                ]
+            ]
+        }, 
+        {
+            "input": "&SquareUnion", 
+            "description": "Bad named entity: SquareUnion without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&SquareUnion"
+                ]
+            ]
+        }, 
+        {
+            "input": "&SquareUnion;", 
+            "description": "Named entity: SquareUnion; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2294"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Sscr", 
+            "description": "Bad named entity: Sscr without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&Sscr"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Sscr;", 
+            "description": "Named entity: Sscr; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\ud835\udcae"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Star", 
+            "description": "Bad named entity: Star without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&Star"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Star;", 
+            "description": "Named entity: Star; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u22c6"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Sub", 
+            "description": "Bad named entity: Sub without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&Sub"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Sub;", 
+            "description": "Named entity: Sub; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u22d0"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Subset", 
+            "description": "Bad named entity: Subset without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&Subset"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Subset;", 
+            "description": "Named entity: Subset; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u22d0"
+                ]
+            ]
+        }, 
+        {
+            "input": "&SubsetEqual", 
+            "description": "Bad named entity: SubsetEqual without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&SubsetEqual"
+                ]
+            ]
+        }, 
+        {
+            "input": "&SubsetEqual;", 
+            "description": "Named entity: SubsetEqual; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2286"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Succeeds", 
+            "description": "Bad named entity: Succeeds without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&Succeeds"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Succeeds;", 
+            "description": "Named entity: Succeeds; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u227b"
+                ]
+            ]
+        }, 
+        {
+            "input": "&SucceedsEqual", 
+            "description": "Bad named entity: SucceedsEqual without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&SucceedsEqual"
+                ]
+            ]
+        }, 
+        {
+            "input": "&SucceedsEqual;", 
+            "description": "Named entity: SucceedsEqual; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2ab0"
+                ]
+            ]
+        }, 
+        {
+            "input": "&SucceedsSlantEqual", 
+            "description": "Bad named entity: SucceedsSlantEqual without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&SucceedsSlantEqual"
+                ]
+            ]
+        }, 
+        {
+            "input": "&SucceedsSlantEqual;", 
+            "description": "Named entity: SucceedsSlantEqual; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u227d"
+                ]
+            ]
+        }, 
+        {
+            "input": "&SucceedsTilde", 
+            "description": "Bad named entity: SucceedsTilde without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&SucceedsTilde"
+                ]
+            ]
+        }, 
+        {
+            "input": "&SucceedsTilde;", 
+            "description": "Named entity: SucceedsTilde; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u227f"
+                ]
+            ]
+        }, 
+        {
+            "input": "&SuchThat", 
+            "description": "Bad named entity: SuchThat without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&SuchThat"
+                ]
+            ]
+        }, 
+        {
+            "input": "&SuchThat;", 
+            "description": "Named entity: SuchThat; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u220b"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Sum", 
+            "description": "Bad named entity: Sum without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&Sum"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Sum;", 
+            "description": "Named entity: Sum; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2211"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Sup", 
+            "description": "Bad named entity: Sup without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&Sup"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Sup;", 
+            "description": "Named entity: Sup; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u22d1"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Superset", 
+            "description": "Bad named entity: Superset without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&Superset"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Superset;", 
+            "description": "Named entity: Superset; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2283"
+                ]
+            ]
+        }, 
+        {
+            "input": "&SupersetEqual", 
+            "description": "Bad named entity: SupersetEqual without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&SupersetEqual"
+                ]
+            ]
+        }, 
+        {
+            "input": "&SupersetEqual;", 
+            "description": "Named entity: SupersetEqual; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2287"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Supset", 
+            "description": "Bad named entity: Supset without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&Supset"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Supset;", 
+            "description": "Named entity: Supset; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u22d1"
+                ]
+            ]
+        }, 
+        {
+            "input": "&THORN", 
+            "description": "Named entity: THORN without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "\u00de"
+                ]
+            ]
+        }, 
+        {
+            "input": "&THORN;", 
+            "description": "Named entity: THORN; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u00de"
+                ]
+            ]
+        }, 
+        {
+            "input": "&TRADE", 
+            "description": "Bad named entity: TRADE without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&TRADE"
+                ]
+            ]
+        }, 
+        {
+            "input": "&TRADE;", 
+            "description": "Named entity: TRADE; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2122"
+                ]
+            ]
+        }, 
+        {
+            "input": "&TSHcy", 
+            "description": "Bad named entity: TSHcy without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&TSHcy"
+                ]
+            ]
+        }, 
+        {
+            "input": "&TSHcy;", 
+            "description": "Named entity: TSHcy; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u040b"
+                ]
+            ]
+        }, 
+        {
+            "input": "&TScy", 
+            "description": "Bad named entity: TScy without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&TScy"
+                ]
+            ]
+        }, 
+        {
+            "input": "&TScy;", 
+            "description": "Named entity: TScy; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u0426"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Tab", 
+            "description": "Bad named entity: Tab without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&Tab"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Tab;", 
+            "description": "Named entity: Tab; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\t"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Tau", 
+            "description": "Bad named entity: Tau without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&Tau"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Tau;", 
+            "description": "Named entity: Tau; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u03a4"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Tcaron", 
+            "description": "Bad named entity: Tcaron without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&Tcaron"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Tcaron;", 
+            "description": "Named entity: Tcaron; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u0164"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Tcedil", 
+            "description": "Bad named entity: Tcedil without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&Tcedil"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Tcedil;", 
+            "description": "Named entity: Tcedil; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u0162"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Tcy", 
+            "description": "Bad named entity: Tcy without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&Tcy"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Tcy;", 
+            "description": "Named entity: Tcy; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u0422"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Tfr", 
+            "description": "Bad named entity: Tfr without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&Tfr"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Tfr;", 
+            "description": "Named entity: Tfr; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\ud835\udd17"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Therefore", 
+            "description": "Bad named entity: Therefore without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&Therefore"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Therefore;", 
+            "description": "Named entity: Therefore; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2234"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Theta", 
+            "description": "Bad named entity: Theta without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&Theta"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Theta;", 
+            "description": "Named entity: Theta; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u0398"
+                ]
+            ]
+        }, 
+        {
+            "input": "&ThickSpace", 
+            "description": "Bad named entity: ThickSpace without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&ThickSpace"
+                ]
+            ]
+        }, 
+        {
+            "input": "&ThickSpace;", 
+            "description": "Named entity: ThickSpace; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u205f\u200a"
+                ]
+            ]
+        }, 
+        {
+            "input": "&ThinSpace", 
+            "description": "Bad named entity: ThinSpace without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&ThinSpace"
+                ]
+            ]
+        }, 
+        {
+            "input": "&ThinSpace;", 
+            "description": "Named entity: ThinSpace; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2009"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Tilde", 
+            "description": "Bad named entity: Tilde without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&Tilde"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Tilde;", 
+            "description": "Named entity: Tilde; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u223c"
+                ]
+            ]
+        }, 
+        {
+            "input": "&TildeEqual", 
+            "description": "Bad named entity: TildeEqual without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&TildeEqual"
+                ]
+            ]
+        }, 
+        {
+            "input": "&TildeEqual;", 
+            "description": "Named entity: TildeEqual; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2243"
+                ]
+            ]
+        }, 
+        {
+            "input": "&TildeFullEqual", 
+            "description": "Bad named entity: TildeFullEqual without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&TildeFullEqual"
+                ]
+            ]
+        }, 
+        {
+            "input": "&TildeFullEqual;", 
+            "description": "Named entity: TildeFullEqual; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2245"
+                ]
+            ]
+        }, 
+        {
+            "input": "&TildeTilde", 
+            "description": "Bad named entity: TildeTilde without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&TildeTilde"
+                ]
+            ]
+        }, 
+        {
+            "input": "&TildeTilde;", 
+            "description": "Named entity: TildeTilde; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2248"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Topf", 
+            "description": "Bad named entity: Topf without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&Topf"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Topf;", 
+            "description": "Named entity: Topf; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\ud835\udd4b"
+                ]
+            ]
+        }, 
+        {
+            "input": "&TripleDot", 
+            "description": "Bad named entity: TripleDot without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&TripleDot"
+                ]
+            ]
+        }, 
+        {
+            "input": "&TripleDot;", 
+            "description": "Named entity: TripleDot; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u20db"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Tscr", 
+            "description": "Bad named entity: Tscr without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&Tscr"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Tscr;", 
+            "description": "Named entity: Tscr; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\ud835\udcaf"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Tstrok", 
+            "description": "Bad named entity: Tstrok without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&Tstrok"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Tstrok;", 
+            "description": "Named entity: Tstrok; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u0166"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Uacute", 
+            "description": "Named entity: Uacute without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "\u00da"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Uacute;", 
+            "description": "Named entity: Uacute; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u00da"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Uarr", 
+            "description": "Bad named entity: Uarr without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&Uarr"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Uarr;", 
+            "description": "Named entity: Uarr; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u219f"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Uarrocir", 
+            "description": "Bad named entity: Uarrocir without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&Uarrocir"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Uarrocir;", 
+            "description": "Named entity: Uarrocir; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2949"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Ubrcy", 
+            "description": "Bad named entity: Ubrcy without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&Ubrcy"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Ubrcy;", 
+            "description": "Named entity: Ubrcy; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u040e"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Ubreve", 
+            "description": "Bad named entity: Ubreve without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&Ubreve"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Ubreve;", 
+            "description": "Named entity: Ubreve; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u016c"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Ucirc", 
+            "description": "Named entity: Ucirc without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "\u00db"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Ucirc;", 
+            "description": "Named entity: Ucirc; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u00db"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Ucy", 
+            "description": "Bad named entity: Ucy without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&Ucy"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Ucy;", 
+            "description": "Named entity: Ucy; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u0423"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Udblac", 
+            "description": "Bad named entity: Udblac without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&Udblac"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Udblac;", 
+            "description": "Named entity: Udblac; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u0170"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Ufr", 
+            "description": "Bad named entity: Ufr without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&Ufr"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Ufr;", 
+            "description": "Named entity: Ufr; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\ud835\udd18"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Ugrave", 
+            "description": "Named entity: Ugrave without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "\u00d9"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Ugrave;", 
+            "description": "Named entity: Ugrave; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u00d9"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Umacr", 
+            "description": "Bad named entity: Umacr without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&Umacr"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Umacr;", 
+            "description": "Named entity: Umacr; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u016a"
+                ]
+            ]
+        }, 
+        {
+            "input": "&UnderBar", 
+            "description": "Bad named entity: UnderBar without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&UnderBar"
+                ]
+            ]
+        }, 
+        {
+            "input": "&UnderBar;", 
+            "description": "Named entity: UnderBar; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "_"
+                ]
+            ]
+        }, 
+        {
+            "input": "&UnderBrace", 
+            "description": "Bad named entity: UnderBrace without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&UnderBrace"
+                ]
+            ]
+        }, 
+        {
+            "input": "&UnderBrace;", 
+            "description": "Named entity: UnderBrace; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u23df"
+                ]
+            ]
+        }, 
+        {
+            "input": "&UnderBracket", 
+            "description": "Bad named entity: UnderBracket without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&UnderBracket"
+                ]
+            ]
+        }, 
+        {
+            "input": "&UnderBracket;", 
+            "description": "Named entity: UnderBracket; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u23b5"
+                ]
+            ]
+        }, 
+        {
+            "input": "&UnderParenthesis", 
+            "description": "Bad named entity: UnderParenthesis without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&UnderParenthesis"
+                ]
+            ]
+        }, 
+        {
+            "input": "&UnderParenthesis;", 
+            "description": "Named entity: UnderParenthesis; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u23dd"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Union", 
+            "description": "Bad named entity: Union without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&Union"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Union;", 
+            "description": "Named entity: Union; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u22c3"
+                ]
+            ]
+        }, 
+        {
+            "input": "&UnionPlus", 
+            "description": "Bad named entity: UnionPlus without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&UnionPlus"
+                ]
+            ]
+        }, 
+        {
+            "input": "&UnionPlus;", 
+            "description": "Named entity: UnionPlus; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u228e"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Uogon", 
+            "description": "Bad named entity: Uogon without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&Uogon"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Uogon;", 
+            "description": "Named entity: Uogon; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u0172"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Uopf", 
+            "description": "Bad named entity: Uopf without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&Uopf"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Uopf;", 
+            "description": "Named entity: Uopf; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\ud835\udd4c"
+                ]
+            ]
+        }, 
+        {
+            "input": "&UpArrow", 
+            "description": "Bad named entity: UpArrow without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&UpArrow"
+                ]
+            ]
+        }, 
+        {
+            "input": "&UpArrow;", 
+            "description": "Named entity: UpArrow; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2191"
+                ]
+            ]
+        }, 
+        {
+            "input": "&UpArrowBar", 
+            "description": "Bad named entity: UpArrowBar without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&UpArrowBar"
+                ]
+            ]
+        }, 
+        {
+            "input": "&UpArrowBar;", 
+            "description": "Named entity: UpArrowBar; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2912"
+                ]
+            ]
+        }, 
+        {
+            "input": "&UpArrowDownArrow", 
+            "description": "Bad named entity: UpArrowDownArrow without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&UpArrowDownArrow"
+                ]
+            ]
+        }, 
+        {
+            "input": "&UpArrowDownArrow;", 
+            "description": "Named entity: UpArrowDownArrow; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u21c5"
+                ]
+            ]
+        }, 
+        {
+            "input": "&UpDownArrow", 
+            "description": "Bad named entity: UpDownArrow without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&UpDownArrow"
+                ]
+            ]
+        }, 
+        {
+            "input": "&UpDownArrow;", 
+            "description": "Named entity: UpDownArrow; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2195"
+                ]
+            ]
+        }, 
+        {
+            "input": "&UpEquilibrium", 
+            "description": "Bad named entity: UpEquilibrium without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&UpEquilibrium"
+                ]
+            ]
+        }, 
+        {
+            "input": "&UpEquilibrium;", 
+            "description": "Named entity: UpEquilibrium; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u296e"
+                ]
+            ]
+        }, 
+        {
+            "input": "&UpTee", 
+            "description": "Bad named entity: UpTee without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&UpTee"
+                ]
+            ]
+        }, 
+        {
+            "input": "&UpTee;", 
+            "description": "Named entity: UpTee; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u22a5"
+                ]
+            ]
+        }, 
+        {
+            "input": "&UpTeeArrow", 
+            "description": "Bad named entity: UpTeeArrow without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&UpTeeArrow"
+                ]
+            ]
+        }, 
+        {
+            "input": "&UpTeeArrow;", 
+            "description": "Named entity: UpTeeArrow; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u21a5"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Uparrow", 
+            "description": "Bad named entity: Uparrow without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&Uparrow"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Uparrow;", 
+            "description": "Named entity: Uparrow; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u21d1"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Updownarrow", 
+            "description": "Bad named entity: Updownarrow without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&Updownarrow"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Updownarrow;", 
+            "description": "Named entity: Updownarrow; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u21d5"
+                ]
+            ]
+        }, 
+        {
+            "input": "&UpperLeftArrow", 
+            "description": "Bad named entity: UpperLeftArrow without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&UpperLeftArrow"
+                ]
+            ]
+        }, 
+        {
+            "input": "&UpperLeftArrow;", 
+            "description": "Named entity: UpperLeftArrow; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2196"
+                ]
+            ]
+        }, 
+        {
+            "input": "&UpperRightArrow", 
+            "description": "Bad named entity: UpperRightArrow without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&UpperRightArrow"
+                ]
+            ]
+        }, 
+        {
+            "input": "&UpperRightArrow;", 
+            "description": "Named entity: UpperRightArrow; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2197"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Upsi", 
+            "description": "Bad named entity: Upsi without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&Upsi"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Upsi;", 
+            "description": "Named entity: Upsi; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u03d2"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Upsilon", 
+            "description": "Bad named entity: Upsilon without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&Upsilon"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Upsilon;", 
+            "description": "Named entity: Upsilon; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u03a5"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Uring", 
+            "description": "Bad named entity: Uring without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&Uring"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Uring;", 
+            "description": "Named entity: Uring; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u016e"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Uscr", 
+            "description": "Bad named entity: Uscr without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&Uscr"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Uscr;", 
+            "description": "Named entity: Uscr; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\ud835\udcb0"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Utilde", 
+            "description": "Bad named entity: Utilde without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&Utilde"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Utilde;", 
+            "description": "Named entity: Utilde; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u0168"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Uuml", 
+            "description": "Named entity: Uuml without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "\u00dc"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Uuml;", 
+            "description": "Named entity: Uuml; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u00dc"
+                ]
+            ]
+        }, 
+        {
+            "input": "&VDash", 
+            "description": "Bad named entity: VDash without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&VDash"
+                ]
+            ]
+        }, 
+        {
+            "input": "&VDash;", 
+            "description": "Named entity: VDash; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u22ab"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Vbar", 
+            "description": "Bad named entity: Vbar without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&Vbar"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Vbar;", 
+            "description": "Named entity: Vbar; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2aeb"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Vcy", 
+            "description": "Bad named entity: Vcy without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&Vcy"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Vcy;", 
+            "description": "Named entity: Vcy; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u0412"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Vdash", 
+            "description": "Bad named entity: Vdash without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&Vdash"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Vdash;", 
+            "description": "Named entity: Vdash; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u22a9"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Vdashl", 
+            "description": "Bad named entity: Vdashl without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&Vdashl"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Vdashl;", 
+            "description": "Named entity: Vdashl; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2ae6"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Vee", 
+            "description": "Bad named entity: Vee without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&Vee"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Vee;", 
+            "description": "Named entity: Vee; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u22c1"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Verbar", 
+            "description": "Bad named entity: Verbar without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&Verbar"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Verbar;", 
+            "description": "Named entity: Verbar; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2016"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Vert", 
+            "description": "Bad named entity: Vert without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&Vert"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Vert;", 
+            "description": "Named entity: Vert; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2016"
+                ]
+            ]
+        }, 
+        {
+            "input": "&VerticalBar", 
+            "description": "Bad named entity: VerticalBar without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&VerticalBar"
+                ]
+            ]
+        }, 
+        {
+            "input": "&VerticalBar;", 
+            "description": "Named entity: VerticalBar; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2223"
+                ]
+            ]
+        }, 
+        {
+            "input": "&VerticalLine", 
+            "description": "Bad named entity: VerticalLine without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&VerticalLine"
+                ]
+            ]
+        }, 
+        {
+            "input": "&VerticalLine;", 
+            "description": "Named entity: VerticalLine; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "|"
+                ]
+            ]
+        }, 
+        {
+            "input": "&VerticalSeparator", 
+            "description": "Bad named entity: VerticalSeparator without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&VerticalSeparator"
+                ]
+            ]
+        }, 
+        {
+            "input": "&VerticalSeparator;", 
+            "description": "Named entity: VerticalSeparator; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2758"
+                ]
+            ]
+        }, 
+        {
+            "input": "&VerticalTilde", 
+            "description": "Bad named entity: VerticalTilde without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&VerticalTilde"
+                ]
+            ]
+        }, 
+        {
+            "input": "&VerticalTilde;", 
+            "description": "Named entity: VerticalTilde; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2240"
+                ]
+            ]
+        }, 
+        {
+            "input": "&VeryThinSpace", 
+            "description": "Bad named entity: VeryThinSpace without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&VeryThinSpace"
+                ]
+            ]
+        }, 
+        {
+            "input": "&VeryThinSpace;", 
+            "description": "Named entity: VeryThinSpace; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u200a"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Vfr", 
+            "description": "Bad named entity: Vfr without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&Vfr"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Vfr;", 
+            "description": "Named entity: Vfr; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\ud835\udd19"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Vopf", 
+            "description": "Bad named entity: Vopf without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&Vopf"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Vopf;", 
+            "description": "Named entity: Vopf; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\ud835\udd4d"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Vscr", 
+            "description": "Bad named entity: Vscr without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&Vscr"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Vscr;", 
+            "description": "Named entity: Vscr; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\ud835\udcb1"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Vvdash", 
+            "description": "Bad named entity: Vvdash without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&Vvdash"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Vvdash;", 
+            "description": "Named entity: Vvdash; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u22aa"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Wcirc", 
+            "description": "Bad named entity: Wcirc without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&Wcirc"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Wcirc;", 
+            "description": "Named entity: Wcirc; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u0174"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Wedge", 
+            "description": "Bad named entity: Wedge without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&Wedge"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Wedge;", 
+            "description": "Named entity: Wedge; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u22c0"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Wfr", 
+            "description": "Bad named entity: Wfr without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&Wfr"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Wfr;", 
+            "description": "Named entity: Wfr; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\ud835\udd1a"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Wopf", 
+            "description": "Bad named entity: Wopf without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&Wopf"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Wopf;", 
+            "description": "Named entity: Wopf; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\ud835\udd4e"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Wscr", 
+            "description": "Bad named entity: Wscr without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&Wscr"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Wscr;", 
+            "description": "Named entity: Wscr; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\ud835\udcb2"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Xfr", 
+            "description": "Bad named entity: Xfr without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&Xfr"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Xfr;", 
+            "description": "Named entity: Xfr; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\ud835\udd1b"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Xi", 
+            "description": "Bad named entity: Xi without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&Xi"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Xi;", 
+            "description": "Named entity: Xi; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u039e"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Xopf", 
+            "description": "Bad named entity: Xopf without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&Xopf"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Xopf;", 
+            "description": "Named entity: Xopf; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\ud835\udd4f"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Xscr", 
+            "description": "Bad named entity: Xscr without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&Xscr"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Xscr;", 
+            "description": "Named entity: Xscr; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\ud835\udcb3"
+                ]
+            ]
+        }, 
+        {
+            "input": "&YAcy", 
+            "description": "Bad named entity: YAcy without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&YAcy"
+                ]
+            ]
+        }, 
+        {
+            "input": "&YAcy;", 
+            "description": "Named entity: YAcy; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u042f"
+                ]
+            ]
+        }, 
+        {
+            "input": "&YIcy", 
+            "description": "Bad named entity: YIcy without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&YIcy"
+                ]
+            ]
+        }, 
+        {
+            "input": "&YIcy;", 
+            "description": "Named entity: YIcy; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u0407"
+                ]
+            ]
+        }, 
+        {
+            "input": "&YUcy", 
+            "description": "Bad named entity: YUcy without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&YUcy"
+                ]
+            ]
+        }, 
+        {
+            "input": "&YUcy;", 
+            "description": "Named entity: YUcy; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u042e"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Yacute", 
+            "description": "Named entity: Yacute without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "\u00dd"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Yacute;", 
+            "description": "Named entity: Yacute; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u00dd"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Ycirc", 
+            "description": "Bad named entity: Ycirc without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&Ycirc"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Ycirc;", 
+            "description": "Named entity: Ycirc; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u0176"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Ycy", 
+            "description": "Bad named entity: Ycy without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&Ycy"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Ycy;", 
+            "description": "Named entity: Ycy; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u042b"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Yfr", 
+            "description": "Bad named entity: Yfr without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&Yfr"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Yfr;", 
+            "description": "Named entity: Yfr; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\ud835\udd1c"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Yopf", 
+            "description": "Bad named entity: Yopf without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&Yopf"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Yopf;", 
+            "description": "Named entity: Yopf; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\ud835\udd50"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Yscr", 
+            "description": "Bad named entity: Yscr without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&Yscr"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Yscr;", 
+            "description": "Named entity: Yscr; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\ud835\udcb4"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Yuml", 
+            "description": "Bad named entity: Yuml without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&Yuml"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Yuml;", 
+            "description": "Named entity: Yuml; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u0178"
+                ]
+            ]
+        }, 
+        {
+            "input": "&ZHcy", 
+            "description": "Bad named entity: ZHcy without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&ZHcy"
+                ]
+            ]
+        }, 
+        {
+            "input": "&ZHcy;", 
+            "description": "Named entity: ZHcy; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u0416"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Zacute", 
+            "description": "Bad named entity: Zacute without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&Zacute"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Zacute;", 
+            "description": "Named entity: Zacute; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u0179"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Zcaron", 
+            "description": "Bad named entity: Zcaron without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&Zcaron"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Zcaron;", 
+            "description": "Named entity: Zcaron; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u017d"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Zcy", 
+            "description": "Bad named entity: Zcy without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&Zcy"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Zcy;", 
+            "description": "Named entity: Zcy; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u0417"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Zdot", 
+            "description": "Bad named entity: Zdot without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&Zdot"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Zdot;", 
+            "description": "Named entity: Zdot; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u017b"
+                ]
+            ]
+        }, 
+        {
+            "input": "&ZeroWidthSpace", 
+            "description": "Bad named entity: ZeroWidthSpace without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&ZeroWidthSpace"
+                ]
+            ]
+        }, 
+        {
+            "input": "&ZeroWidthSpace;", 
+            "description": "Named entity: ZeroWidthSpace; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u200b"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Zeta", 
+            "description": "Bad named entity: Zeta without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&Zeta"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Zeta;", 
+            "description": "Named entity: Zeta; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u0396"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Zfr", 
+            "description": "Bad named entity: Zfr without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&Zfr"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Zfr;", 
+            "description": "Named entity: Zfr; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2128"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Zopf", 
+            "description": "Bad named entity: Zopf without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&Zopf"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Zopf;", 
+            "description": "Named entity: Zopf; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2124"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Zscr", 
+            "description": "Bad named entity: Zscr without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&Zscr"
+                ]
+            ]
+        }, 
+        {
+            "input": "&Zscr;", 
+            "description": "Named entity: Zscr; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\ud835\udcb5"
+                ]
+            ]
+        }, 
+        {
+            "input": "&aacute", 
+            "description": "Named entity: aacute without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "\u00e1"
+                ]
+            ]
+        }, 
+        {
+            "input": "&aacute;", 
+            "description": "Named entity: aacute; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u00e1"
+                ]
+            ]
+        }, 
+        {
+            "input": "&abreve", 
+            "description": "Bad named entity: abreve without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&abreve"
+                ]
+            ]
+        }, 
+        {
+            "input": "&abreve;", 
+            "description": "Named entity: abreve; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u0103"
+                ]
+            ]
+        }, 
+        {
+            "input": "&ac", 
+            "description": "Bad named entity: ac without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&ac"
+                ]
+            ]
+        }, 
+        {
+            "input": "&ac;", 
+            "description": "Named entity: ac; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u223e"
+                ]
+            ]
+        }, 
+        {
+            "input": "&acE", 
+            "description": "Bad named entity: acE without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&acE"
+                ]
+            ]
+        }, 
+        {
+            "input": "&acE;", 
+            "description": "Named entity: acE; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u223e\u0333"
+                ]
+            ]
+        }, 
+        {
+            "input": "&acd", 
+            "description": "Bad named entity: acd without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&acd"
+                ]
+            ]
+        }, 
+        {
+            "input": "&acd;", 
+            "description": "Named entity: acd; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u223f"
+                ]
+            ]
+        }, 
+        {
+            "input": "&acirc", 
+            "description": "Named entity: acirc without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "\u00e2"
+                ]
+            ]
+        }, 
+        {
+            "input": "&acirc;", 
+            "description": "Named entity: acirc; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u00e2"
+                ]
+            ]
+        }, 
+        {
+            "input": "&acute", 
+            "description": "Named entity: acute without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "\u00b4"
+                ]
+            ]
+        }, 
+        {
+            "input": "&acute;", 
+            "description": "Named entity: acute; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u00b4"
+                ]
+            ]
+        }, 
+        {
+            "input": "&acy", 
+            "description": "Bad named entity: acy without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&acy"
+                ]
+            ]
+        }, 
+        {
+            "input": "&acy;", 
+            "description": "Named entity: acy; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u0430"
+                ]
+            ]
+        }, 
+        {
+            "input": "&aelig", 
+            "description": "Named entity: aelig without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "\u00e6"
+                ]
+            ]
+        }, 
+        {
+            "input": "&aelig;", 
+            "description": "Named entity: aelig; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u00e6"
+                ]
+            ]
+        }, 
+        {
+            "input": "&af", 
+            "description": "Bad named entity: af without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&af"
+                ]
+            ]
+        }, 
+        {
+            "input": "&af;", 
+            "description": "Named entity: af; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2061"
+                ]
+            ]
+        }, 
+        {
+            "input": "&afr", 
+            "description": "Bad named entity: afr without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&afr"
+                ]
+            ]
+        }, 
+        {
+            "input": "&afr;", 
+            "description": "Named entity: afr; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\ud835\udd1e"
+                ]
+            ]
+        }, 
+        {
+            "input": "&agrave", 
+            "description": "Named entity: agrave without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "\u00e0"
+                ]
+            ]
+        }, 
+        {
+            "input": "&agrave;", 
+            "description": "Named entity: agrave; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u00e0"
+                ]
+            ]
+        }, 
+        {
+            "input": "&alefsym", 
+            "description": "Bad named entity: alefsym without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&alefsym"
+                ]
+            ]
+        }, 
+        {
+            "input": "&alefsym;", 
+            "description": "Named entity: alefsym; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2135"
+                ]
+            ]
+        }, 
+        {
+            "input": "&aleph", 
+            "description": "Bad named entity: aleph without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&aleph"
+                ]
+            ]
+        }, 
+        {
+            "input": "&aleph;", 
+            "description": "Named entity: aleph; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2135"
+                ]
+            ]
+        }, 
+        {
+            "input": "&alpha", 
+            "description": "Bad named entity: alpha without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&alpha"
+                ]
+            ]
+        }, 
+        {
+            "input": "&alpha;", 
+            "description": "Named entity: alpha; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u03b1"
+                ]
+            ]
+        }, 
+        {
+            "input": "&amacr", 
+            "description": "Bad named entity: amacr without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&amacr"
+                ]
+            ]
+        }, 
+        {
+            "input": "&amacr;", 
+            "description": "Named entity: amacr; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u0101"
+                ]
+            ]
+        }, 
+        {
+            "input": "&amalg", 
+            "description": "Bad named entity: amalg without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&amalg"
+                ]
+            ]
+        }, 
+        {
+            "input": "&amalg;", 
+            "description": "Named entity: amalg; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2a3f"
+                ]
+            ]
+        }, 
+        {
+            "input": "&amp", 
+            "description": "Named entity: amp without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&"
+                ]
+            ]
+        }, 
+        {
+            "input": "&amp;", 
+            "description": "Named entity: amp; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "&"
+                ]
+            ]
+        }, 
+        {
+            "input": "&and", 
+            "description": "Bad named entity: and without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&and"
+                ]
+            ]
+        }, 
+        {
+            "input": "&and;", 
+            "description": "Named entity: and; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2227"
+                ]
+            ]
+        }, 
+        {
+            "input": "&andand", 
+            "description": "Bad named entity: andand without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&andand"
+                ]
+            ]
+        }, 
+        {
+            "input": "&andand;", 
+            "description": "Named entity: andand; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2a55"
+                ]
+            ]
+        }, 
+        {
+            "input": "&andd", 
+            "description": "Bad named entity: andd without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&andd"
+                ]
+            ]
+        }, 
+        {
+            "input": "&andd;", 
+            "description": "Named entity: andd; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2a5c"
+                ]
+            ]
+        }, 
+        {
+            "input": "&andslope", 
+            "description": "Bad named entity: andslope without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&andslope"
+                ]
+            ]
+        }, 
+        {
+            "input": "&andslope;", 
+            "description": "Named entity: andslope; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2a58"
+                ]
+            ]
+        }, 
+        {
+            "input": "&andv", 
+            "description": "Bad named entity: andv without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&andv"
+                ]
+            ]
+        }, 
+        {
+            "input": "&andv;", 
+            "description": "Named entity: andv; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2a5a"
+                ]
+            ]
+        }, 
+        {
+            "input": "&ang", 
+            "description": "Bad named entity: ang without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&ang"
+                ]
+            ]
+        }, 
+        {
+            "input": "&ang;", 
+            "description": "Named entity: ang; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2220"
+                ]
+            ]
+        }, 
+        {
+            "input": "&ange", 
+            "description": "Bad named entity: ange without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&ange"
+                ]
+            ]
+        }, 
+        {
+            "input": "&ange;", 
+            "description": "Named entity: ange; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u29a4"
+                ]
+            ]
+        }, 
+        {
+            "input": "&angle", 
+            "description": "Bad named entity: angle without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&angle"
+                ]
+            ]
+        }, 
+        {
+            "input": "&angle;", 
+            "description": "Named entity: angle; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2220"
+                ]
+            ]
+        }, 
+        {
+            "input": "&angmsd", 
+            "description": "Bad named entity: angmsd without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&angmsd"
+                ]
+            ]
+        }, 
+        {
+            "input": "&angmsd;", 
+            "description": "Named entity: angmsd; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2221"
+                ]
+            ]
+        }, 
+        {
+            "input": "&angmsdaa", 
+            "description": "Bad named entity: angmsdaa without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&angmsdaa"
+                ]
+            ]
+        }, 
+        {
+            "input": "&angmsdaa;", 
+            "description": "Named entity: angmsdaa; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u29a8"
+                ]
+            ]
+        }, 
+        {
+            "input": "&angmsdab", 
+            "description": "Bad named entity: angmsdab without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&angmsdab"
+                ]
+            ]
+        }, 
+        {
+            "input": "&angmsdab;", 
+            "description": "Named entity: angmsdab; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u29a9"
+                ]
+            ]
+        }, 
+        {
+            "input": "&angmsdac", 
+            "description": "Bad named entity: angmsdac without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&angmsdac"
+                ]
+            ]
+        }, 
+        {
+            "input": "&angmsdac;", 
+            "description": "Named entity: angmsdac; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u29aa"
+                ]
+            ]
+        }, 
+        {
+            "input": "&angmsdad", 
+            "description": "Bad named entity: angmsdad without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&angmsdad"
+                ]
+            ]
+        }, 
+        {
+            "input": "&angmsdad;", 
+            "description": "Named entity: angmsdad; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u29ab"
+                ]
+            ]
+        }, 
+        {
+            "input": "&angmsdae", 
+            "description": "Bad named entity: angmsdae without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&angmsdae"
+                ]
+            ]
+        }, 
+        {
+            "input": "&angmsdae;", 
+            "description": "Named entity: angmsdae; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u29ac"
+                ]
+            ]
+        }, 
+        {
+            "input": "&angmsdaf", 
+            "description": "Bad named entity: angmsdaf without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&angmsdaf"
+                ]
+            ]
+        }, 
+        {
+            "input": "&angmsdaf;", 
+            "description": "Named entity: angmsdaf; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u29ad"
+                ]
+            ]
+        }, 
+        {
+            "input": "&angmsdag", 
+            "description": "Bad named entity: angmsdag without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&angmsdag"
+                ]
+            ]
+        }, 
+        {
+            "input": "&angmsdag;", 
+            "description": "Named entity: angmsdag; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u29ae"
+                ]
+            ]
+        }, 
+        {
+            "input": "&angmsdah", 
+            "description": "Bad named entity: angmsdah without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&angmsdah"
+                ]
+            ]
+        }, 
+        {
+            "input": "&angmsdah;", 
+            "description": "Named entity: angmsdah; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u29af"
+                ]
+            ]
+        }, 
+        {
+            "input": "&angrt", 
+            "description": "Bad named entity: angrt without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&angrt"
+                ]
+            ]
+        }, 
+        {
+            "input": "&angrt;", 
+            "description": "Named entity: angrt; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u221f"
+                ]
+            ]
+        }, 
+        {
+            "input": "&angrtvb", 
+            "description": "Bad named entity: angrtvb without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&angrtvb"
+                ]
+            ]
+        }, 
+        {
+            "input": "&angrtvb;", 
+            "description": "Named entity: angrtvb; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u22be"
+                ]
+            ]
+        }, 
+        {
+            "input": "&angrtvbd", 
+            "description": "Bad named entity: angrtvbd without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&angrtvbd"
+                ]
+            ]
+        }, 
+        {
+            "input": "&angrtvbd;", 
+            "description": "Named entity: angrtvbd; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u299d"
+                ]
+            ]
+        }, 
+        {
+            "input": "&angsph", 
+            "description": "Bad named entity: angsph without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&angsph"
+                ]
+            ]
+        }, 
+        {
+            "input": "&angsph;", 
+            "description": "Named entity: angsph; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2222"
+                ]
+            ]
+        }, 
+        {
+            "input": "&angst", 
+            "description": "Bad named entity: angst without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&angst"
+                ]
+            ]
+        }, 
+        {
+            "input": "&angst;", 
+            "description": "Named entity: angst; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u00c5"
+                ]
+            ]
+        }, 
+        {
+            "input": "&angzarr", 
+            "description": "Bad named entity: angzarr without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&angzarr"
+                ]
+            ]
+        }, 
+        {
+            "input": "&angzarr;", 
+            "description": "Named entity: angzarr; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u237c"
+                ]
+            ]
+        }, 
+        {
+            "input": "&aogon", 
+            "description": "Bad named entity: aogon without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&aogon"
+                ]
+            ]
+        }, 
+        {
+            "input": "&aogon;", 
+            "description": "Named entity: aogon; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u0105"
+                ]
+            ]
+        }, 
+        {
+            "input": "&aopf", 
+            "description": "Bad named entity: aopf without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&aopf"
+                ]
+            ]
+        }, 
+        {
+            "input": "&aopf;", 
+            "description": "Named entity: aopf; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\ud835\udd52"
+                ]
+            ]
+        }, 
+        {
+            "input": "&ap", 
+            "description": "Bad named entity: ap without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&ap"
+                ]
+            ]
+        }, 
+        {
+            "input": "&ap;", 
+            "description": "Named entity: ap; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2248"
+                ]
+            ]
+        }, 
+        {
+            "input": "&apE", 
+            "description": "Bad named entity: apE without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&apE"
+                ]
+            ]
+        }, 
+        {
+            "input": "&apE;", 
+            "description": "Named entity: apE; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2a70"
+                ]
+            ]
+        }, 
+        {
+            "input": "&apacir", 
+            "description": "Bad named entity: apacir without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&apacir"
+                ]
+            ]
+        }, 
+        {
+            "input": "&apacir;", 
+            "description": "Named entity: apacir; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2a6f"
+                ]
+            ]
+        }, 
+        {
+            "input": "&ape", 
+            "description": "Bad named entity: ape without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&ape"
+                ]
+            ]
+        }, 
+        {
+            "input": "&ape;", 
+            "description": "Named entity: ape; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u224a"
+                ]
+            ]
+        }, 
+        {
+            "input": "&apid", 
+            "description": "Bad named entity: apid without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&apid"
+                ]
+            ]
+        }, 
+        {
+            "input": "&apid;", 
+            "description": "Named entity: apid; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u224b"
+                ]
+            ]
+        }, 
+        {
+            "input": "&apos", 
+            "description": "Bad named entity: apos without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&apos"
+                ]
+            ]
+        }, 
+        {
+            "input": "&apos;", 
+            "description": "Named entity: apos; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "'"
+                ]
+            ]
+        }, 
+        {
+            "input": "&approx", 
+            "description": "Bad named entity: approx without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&approx"
+                ]
+            ]
+        }, 
+        {
+            "input": "&approx;", 
+            "description": "Named entity: approx; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2248"
+                ]
+            ]
+        }, 
+        {
+            "input": "&approxeq", 
+            "description": "Bad named entity: approxeq without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&approxeq"
+                ]
+            ]
+        }, 
+        {
+            "input": "&approxeq;", 
+            "description": "Named entity: approxeq; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u224a"
+                ]
+            ]
+        }, 
+        {
+            "input": "&aring", 
+            "description": "Named entity: aring without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "\u00e5"
+                ]
+            ]
+        }, 
+        {
+            "input": "&aring;", 
+            "description": "Named entity: aring; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u00e5"
+                ]
+            ]
+        }, 
+        {
+            "input": "&ascr", 
+            "description": "Bad named entity: ascr without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&ascr"
+                ]
+            ]
+        }, 
+        {
+            "input": "&ascr;", 
+            "description": "Named entity: ascr; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\ud835\udcb6"
+                ]
+            ]
+        }, 
+        {
+            "input": "&ast", 
+            "description": "Bad named entity: ast without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&ast"
+                ]
+            ]
+        }, 
+        {
+            "input": "&ast;", 
+            "description": "Named entity: ast; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "*"
+                ]
+            ]
+        }, 
+        {
+            "input": "&asymp", 
+            "description": "Bad named entity: asymp without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&asymp"
+                ]
+            ]
+        }, 
+        {
+            "input": "&asymp;", 
+            "description": "Named entity: asymp; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2248"
+                ]
+            ]
+        }, 
+        {
+            "input": "&asympeq", 
+            "description": "Bad named entity: asympeq without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&asympeq"
+                ]
+            ]
+        }, 
+        {
+            "input": "&asympeq;", 
+            "description": "Named entity: asympeq; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u224d"
+                ]
+            ]
+        }, 
+        {
+            "input": "&atilde", 
+            "description": "Named entity: atilde without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "\u00e3"
+                ]
+            ]
+        }, 
+        {
+            "input": "&atilde;", 
+            "description": "Named entity: atilde; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u00e3"
+                ]
+            ]
+        }, 
+        {
+            "input": "&auml", 
+            "description": "Named entity: auml without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "\u00e4"
+                ]
+            ]
+        }, 
+        {
+            "input": "&auml;", 
+            "description": "Named entity: auml; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u00e4"
+                ]
+            ]
+        }, 
+        {
+            "input": "&awconint", 
+            "description": "Bad named entity: awconint without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&awconint"
+                ]
+            ]
+        }, 
+        {
+            "input": "&awconint;", 
+            "description": "Named entity: awconint; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2233"
+                ]
+            ]
+        }, 
+        {
+            "input": "&awint", 
+            "description": "Bad named entity: awint without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&awint"
+                ]
+            ]
+        }, 
+        {
+            "input": "&awint;", 
+            "description": "Named entity: awint; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2a11"
+                ]
+            ]
+        }, 
+        {
+            "input": "&bNot", 
+            "description": "Bad named entity: bNot without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&bNot"
+                ]
+            ]
+        }, 
+        {
+            "input": "&bNot;", 
+            "description": "Named entity: bNot; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2aed"
+                ]
+            ]
+        }, 
+        {
+            "input": "&backcong", 
+            "description": "Bad named entity: backcong without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&backcong"
+                ]
+            ]
+        }, 
+        {
+            "input": "&backcong;", 
+            "description": "Named entity: backcong; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u224c"
+                ]
+            ]
+        }, 
+        {
+            "input": "&backepsilon", 
+            "description": "Bad named entity: backepsilon without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&backepsilon"
+                ]
+            ]
+        }, 
+        {
+            "input": "&backepsilon;", 
+            "description": "Named entity: backepsilon; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u03f6"
+                ]
+            ]
+        }, 
+        {
+            "input": "&backprime", 
+            "description": "Bad named entity: backprime without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&backprime"
+                ]
+            ]
+        }, 
+        {
+            "input": "&backprime;", 
+            "description": "Named entity: backprime; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2035"
+                ]
+            ]
+        }, 
+        {
+            "input": "&backsim", 
+            "description": "Bad named entity: backsim without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&backsim"
+                ]
+            ]
+        }, 
+        {
+            "input": "&backsim;", 
+            "description": "Named entity: backsim; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u223d"
+                ]
+            ]
+        }, 
+        {
+            "input": "&backsimeq", 
+            "description": "Bad named entity: backsimeq without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&backsimeq"
+                ]
+            ]
+        }, 
+        {
+            "input": "&backsimeq;", 
+            "description": "Named entity: backsimeq; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u22cd"
+                ]
+            ]
+        }, 
+        {
+            "input": "&barvee", 
+            "description": "Bad named entity: barvee without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&barvee"
+                ]
+            ]
+        }, 
+        {
+            "input": "&barvee;", 
+            "description": "Named entity: barvee; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u22bd"
+                ]
+            ]
+        }, 
+        {
+            "input": "&barwed", 
+            "description": "Bad named entity: barwed without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&barwed"
+                ]
+            ]
+        }, 
+        {
+            "input": "&barwed;", 
+            "description": "Named entity: barwed; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2305"
+                ]
+            ]
+        }, 
+        {
+            "input": "&barwedge", 
+            "description": "Bad named entity: barwedge without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&barwedge"
+                ]
+            ]
+        }, 
+        {
+            "input": "&barwedge;", 
+            "description": "Named entity: barwedge; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2305"
+                ]
+            ]
+        }, 
+        {
+            "input": "&bbrk", 
+            "description": "Bad named entity: bbrk without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&bbrk"
+                ]
+            ]
+        }, 
+        {
+            "input": "&bbrk;", 
+            "description": "Named entity: bbrk; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u23b5"
+                ]
+            ]
+        }, 
+        {
+            "input": "&bbrktbrk", 
+            "description": "Bad named entity: bbrktbrk without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&bbrktbrk"
+                ]
+            ]
+        }, 
+        {
+            "input": "&bbrktbrk;", 
+            "description": "Named entity: bbrktbrk; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u23b6"
+                ]
+            ]
+        }, 
+        {
+            "input": "&bcong", 
+            "description": "Bad named entity: bcong without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&bcong"
+                ]
+            ]
+        }, 
+        {
+            "input": "&bcong;", 
+            "description": "Named entity: bcong; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u224c"
+                ]
+            ]
+        }, 
+        {
+            "input": "&bcy", 
+            "description": "Bad named entity: bcy without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&bcy"
+                ]
+            ]
+        }, 
+        {
+            "input": "&bcy;", 
+            "description": "Named entity: bcy; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u0431"
+                ]
+            ]
+        }, 
+        {
+            "input": "&bdquo", 
+            "description": "Bad named entity: bdquo without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&bdquo"
+                ]
+            ]
+        }, 
+        {
+            "input": "&bdquo;", 
+            "description": "Named entity: bdquo; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u201e"
+                ]
+            ]
+        }, 
+        {
+            "input": "&becaus", 
+            "description": "Bad named entity: becaus without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&becaus"
+                ]
+            ]
+        }, 
+        {
+            "input": "&becaus;", 
+            "description": "Named entity: becaus; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2235"
+                ]
+            ]
+        }, 
+        {
+            "input": "&because", 
+            "description": "Bad named entity: because without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&because"
+                ]
+            ]
+        }, 
+        {
+            "input": "&because;", 
+            "description": "Named entity: because; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2235"
+                ]
+            ]
+        }, 
+        {
+            "input": "&bemptyv", 
+            "description": "Bad named entity: bemptyv without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&bemptyv"
+                ]
+            ]
+        }, 
+        {
+            "input": "&bemptyv;", 
+            "description": "Named entity: bemptyv; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u29b0"
+                ]
+            ]
+        }, 
+        {
+            "input": "&bepsi", 
+            "description": "Bad named entity: bepsi without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&bepsi"
+                ]
+            ]
+        }, 
+        {
+            "input": "&bepsi;", 
+            "description": "Named entity: bepsi; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u03f6"
+                ]
+            ]
+        }, 
+        {
+            "input": "&bernou", 
+            "description": "Bad named entity: bernou without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&bernou"
+                ]
+            ]
+        }, 
+        {
+            "input": "&bernou;", 
+            "description": "Named entity: bernou; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u212c"
+                ]
+            ]
+        }, 
+        {
+            "input": "&beta", 
+            "description": "Bad named entity: beta without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&beta"
+                ]
+            ]
+        }, 
+        {
+            "input": "&beta;", 
+            "description": "Named entity: beta; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u03b2"
+                ]
+            ]
+        }, 
+        {
+            "input": "&beth", 
+            "description": "Bad named entity: beth without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&beth"
+                ]
+            ]
+        }, 
+        {
+            "input": "&beth;", 
+            "description": "Named entity: beth; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2136"
+                ]
+            ]
+        }, 
+        {
+            "input": "&between", 
+            "description": "Bad named entity: between without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&between"
+                ]
+            ]
+        }, 
+        {
+            "input": "&between;", 
+            "description": "Named entity: between; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u226c"
+                ]
+            ]
+        }, 
+        {
+            "input": "&bfr", 
+            "description": "Bad named entity: bfr without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&bfr"
+                ]
+            ]
+        }, 
+        {
+            "input": "&bfr;", 
+            "description": "Named entity: bfr; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\ud835\udd1f"
+                ]
+            ]
+        }, 
+        {
+            "input": "&bigcap", 
+            "description": "Bad named entity: bigcap without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&bigcap"
+                ]
+            ]
+        }, 
+        {
+            "input": "&bigcap;", 
+            "description": "Named entity: bigcap; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u22c2"
+                ]
+            ]
+        }, 
+        {
+            "input": "&bigcirc", 
+            "description": "Bad named entity: bigcirc without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&bigcirc"
+                ]
+            ]
+        }, 
+        {
+            "input": "&bigcirc;", 
+            "description": "Named entity: bigcirc; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u25ef"
+                ]
+            ]
+        }, 
+        {
+            "input": "&bigcup", 
+            "description": "Bad named entity: bigcup without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&bigcup"
+                ]
+            ]
+        }, 
+        {
+            "input": "&bigcup;", 
+            "description": "Named entity: bigcup; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u22c3"
+                ]
+            ]
+        }, 
+        {
+            "input": "&bigodot", 
+            "description": "Bad named entity: bigodot without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&bigodot"
+                ]
+            ]
+        }, 
+        {
+            "input": "&bigodot;", 
+            "description": "Named entity: bigodot; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2a00"
+                ]
+            ]
+        }, 
+        {
+            "input": "&bigoplus", 
+            "description": "Bad named entity: bigoplus without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&bigoplus"
+                ]
+            ]
+        }, 
+        {
+            "input": "&bigoplus;", 
+            "description": "Named entity: bigoplus; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2a01"
+                ]
+            ]
+        }, 
+        {
+            "input": "&bigotimes", 
+            "description": "Bad named entity: bigotimes without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&bigotimes"
+                ]
+            ]
+        }, 
+        {
+            "input": "&bigotimes;", 
+            "description": "Named entity: bigotimes; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2a02"
+                ]
+            ]
+        }, 
+        {
+            "input": "&bigsqcup", 
+            "description": "Bad named entity: bigsqcup without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&bigsqcup"
+                ]
+            ]
+        }, 
+        {
+            "input": "&bigsqcup;", 
+            "description": "Named entity: bigsqcup; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2a06"
+                ]
+            ]
+        }, 
+        {
+            "input": "&bigstar", 
+            "description": "Bad named entity: bigstar without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&bigstar"
+                ]
+            ]
+        }, 
+        {
+            "input": "&bigstar;", 
+            "description": "Named entity: bigstar; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2605"
+                ]
+            ]
+        }, 
+        {
+            "input": "&bigtriangledown", 
+            "description": "Bad named entity: bigtriangledown without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&bigtriangledown"
+                ]
+            ]
+        }, 
+        {
+            "input": "&bigtriangledown;", 
+            "description": "Named entity: bigtriangledown; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u25bd"
+                ]
+            ]
+        }, 
+        {
+            "input": "&bigtriangleup", 
+            "description": "Bad named entity: bigtriangleup without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&bigtriangleup"
+                ]
+            ]
+        }, 
+        {
+            "input": "&bigtriangleup;", 
+            "description": "Named entity: bigtriangleup; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u25b3"
+                ]
+            ]
+        }, 
+        {
+            "input": "&biguplus", 
+            "description": "Bad named entity: biguplus without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&biguplus"
+                ]
+            ]
+        }, 
+        {
+            "input": "&biguplus;", 
+            "description": "Named entity: biguplus; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2a04"
+                ]
+            ]
+        }, 
+        {
+            "input": "&bigvee", 
+            "description": "Bad named entity: bigvee without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&bigvee"
+                ]
+            ]
+        }, 
+        {
+            "input": "&bigvee;", 
+            "description": "Named entity: bigvee; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u22c1"
+                ]
+            ]
+        }, 
+        {
+            "input": "&bigwedge", 
+            "description": "Bad named entity: bigwedge without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&bigwedge"
+                ]
+            ]
+        }, 
+        {
+            "input": "&bigwedge;", 
+            "description": "Named entity: bigwedge; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u22c0"
+                ]
+            ]
+        }, 
+        {
+            "input": "&bkarow", 
+            "description": "Bad named entity: bkarow without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&bkarow"
+                ]
+            ]
+        }, 
+        {
+            "input": "&bkarow;", 
+            "description": "Named entity: bkarow; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u290d"
+                ]
+            ]
+        }, 
+        {
+            "input": "&blacklozenge", 
+            "description": "Bad named entity: blacklozenge without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&blacklozenge"
+                ]
+            ]
+        }, 
+        {
+            "input": "&blacklozenge;", 
+            "description": "Named entity: blacklozenge; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u29eb"
+                ]
+            ]
+        }, 
+        {
+            "input": "&blacksquare", 
+            "description": "Bad named entity: blacksquare without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&blacksquare"
+                ]
+            ]
+        }, 
+        {
+            "input": "&blacksquare;", 
+            "description": "Named entity: blacksquare; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u25aa"
+                ]
+            ]
+        }, 
+        {
+            "input": "&blacktriangle", 
+            "description": "Bad named entity: blacktriangle without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&blacktriangle"
+                ]
+            ]
+        }, 
+        {
+            "input": "&blacktriangle;", 
+            "description": "Named entity: blacktriangle; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u25b4"
+                ]
+            ]
+        }, 
+        {
+            "input": "&blacktriangledown", 
+            "description": "Bad named entity: blacktriangledown without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&blacktriangledown"
+                ]
+            ]
+        }, 
+        {
+            "input": "&blacktriangledown;", 
+            "description": "Named entity: blacktriangledown; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u25be"
+                ]
+            ]
+        }, 
+        {
+            "input": "&blacktriangleleft", 
+            "description": "Bad named entity: blacktriangleleft without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&blacktriangleleft"
+                ]
+            ]
+        }, 
+        {
+            "input": "&blacktriangleleft;", 
+            "description": "Named entity: blacktriangleleft; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u25c2"
+                ]
+            ]
+        }, 
+        {
+            "input": "&blacktriangleright", 
+            "description": "Bad named entity: blacktriangleright without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&blacktriangleright"
+                ]
+            ]
+        }, 
+        {
+            "input": "&blacktriangleright;", 
+            "description": "Named entity: blacktriangleright; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u25b8"
+                ]
+            ]
+        }, 
+        {
+            "input": "&blank", 
+            "description": "Bad named entity: blank without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&blank"
+                ]
+            ]
+        }, 
+        {
+            "input": "&blank;", 
+            "description": "Named entity: blank; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2423"
+                ]
+            ]
+        }, 
+        {
+            "input": "&blk12", 
+            "description": "Bad named entity: blk12 without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&blk12"
+                ]
+            ]
+        }, 
+        {
+            "input": "&blk12;", 
+            "description": "Named entity: blk12; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2592"
+                ]
+            ]
+        }, 
+        {
+            "input": "&blk14", 
+            "description": "Bad named entity: blk14 without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&blk14"
+                ]
+            ]
+        }, 
+        {
+            "input": "&blk14;", 
+            "description": "Named entity: blk14; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2591"
+                ]
+            ]
+        }, 
+        {
+            "input": "&blk34", 
+            "description": "Bad named entity: blk34 without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&blk34"
+                ]
+            ]
+        }, 
+        {
+            "input": "&blk34;", 
+            "description": "Named entity: blk34; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2593"
+                ]
+            ]
+        }, 
+        {
+            "input": "&block", 
+            "description": "Bad named entity: block without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&block"
+                ]
+            ]
+        }, 
+        {
+            "input": "&block;", 
+            "description": "Named entity: block; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2588"
+                ]
+            ]
+        }, 
+        {
+            "input": "&bne", 
+            "description": "Bad named entity: bne without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&bne"
+                ]
+            ]
+        }, 
+        {
+            "input": "&bne;", 
+            "description": "Named entity: bne; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "=\u20e5"
+                ]
+            ]
+        }, 
+        {
+            "input": "&bnequiv", 
+            "description": "Bad named entity: bnequiv without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&bnequiv"
+                ]
+            ]
+        }, 
+        {
+            "input": "&bnequiv;", 
+            "description": "Named entity: bnequiv; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2261\u20e5"
+                ]
+            ]
+        }, 
+        {
+            "input": "&bnot", 
+            "description": "Bad named entity: bnot without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&bnot"
+                ]
+            ]
+        }, 
+        {
+            "input": "&bnot;", 
+            "description": "Named entity: bnot; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2310"
+                ]
+            ]
+        }, 
+        {
+            "input": "&bopf", 
+            "description": "Bad named entity: bopf without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&bopf"
+                ]
+            ]
+        }, 
+        {
+            "input": "&bopf;", 
+            "description": "Named entity: bopf; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\ud835\udd53"
+                ]
+            ]
+        }, 
+        {
+            "input": "&bot", 
+            "description": "Bad named entity: bot without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&bot"
+                ]
+            ]
+        }, 
+        {
+            "input": "&bot;", 
+            "description": "Named entity: bot; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u22a5"
+                ]
+            ]
+        }, 
+        {
+            "input": "&bottom", 
+            "description": "Bad named entity: bottom without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&bottom"
+                ]
+            ]
+        }, 
+        {
+            "input": "&bottom;", 
+            "description": "Named entity: bottom; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u22a5"
+                ]
+            ]
+        }, 
+        {
+            "input": "&bowtie", 
+            "description": "Bad named entity: bowtie without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&bowtie"
+                ]
+            ]
+        }, 
+        {
+            "input": "&bowtie;", 
+            "description": "Named entity: bowtie; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u22c8"
+                ]
+            ]
+        }, 
+        {
+            "input": "&boxDL", 
+            "description": "Bad named entity: boxDL without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&boxDL"
+                ]
+            ]
+        }, 
+        {
+            "input": "&boxDL;", 
+            "description": "Named entity: boxDL; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2557"
+                ]
+            ]
+        }, 
+        {
+            "input": "&boxDR", 
+            "description": "Bad named entity: boxDR without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&boxDR"
+                ]
+            ]
+        }, 
+        {
+            "input": "&boxDR;", 
+            "description": "Named entity: boxDR; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2554"
+                ]
+            ]
+        }, 
+        {
+            "input": "&boxDl", 
+            "description": "Bad named entity: boxDl without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&boxDl"
+                ]
+            ]
+        }, 
+        {
+            "input": "&boxDl;", 
+            "description": "Named entity: boxDl; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2556"
+                ]
+            ]
+        }, 
+        {
+            "input": "&boxDr", 
+            "description": "Bad named entity: boxDr without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&boxDr"
+                ]
+            ]
+        }, 
+        {
+            "input": "&boxDr;", 
+            "description": "Named entity: boxDr; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2553"
+                ]
+            ]
+        }, 
+        {
+            "input": "&boxH", 
+            "description": "Bad named entity: boxH without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&boxH"
+                ]
+            ]
+        }, 
+        {
+            "input": "&boxH;", 
+            "description": "Named entity: boxH; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2550"
+                ]
+            ]
+        }, 
+        {
+            "input": "&boxHD", 
+            "description": "Bad named entity: boxHD without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&boxHD"
+                ]
+            ]
+        }, 
+        {
+            "input": "&boxHD;", 
+            "description": "Named entity: boxHD; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2566"
+                ]
+            ]
+        }, 
+        {
+            "input": "&boxHU", 
+            "description": "Bad named entity: boxHU without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&boxHU"
+                ]
+            ]
+        }, 
+        {
+            "input": "&boxHU;", 
+            "description": "Named entity: boxHU; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2569"
+                ]
+            ]
+        }, 
+        {
+            "input": "&boxHd", 
+            "description": "Bad named entity: boxHd without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&boxHd"
+                ]
+            ]
+        }, 
+        {
+            "input": "&boxHd;", 
+            "description": "Named entity: boxHd; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2564"
+                ]
+            ]
+        }, 
+        {
+            "input": "&boxHu", 
+            "description": "Bad named entity: boxHu without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&boxHu"
+                ]
+            ]
+        }, 
+        {
+            "input": "&boxHu;", 
+            "description": "Named entity: boxHu; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2567"
+                ]
+            ]
+        }, 
+        {
+            "input": "&boxUL", 
+            "description": "Bad named entity: boxUL without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&boxUL"
+                ]
+            ]
+        }, 
+        {
+            "input": "&boxUL;", 
+            "description": "Named entity: boxUL; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u255d"
+                ]
+            ]
+        }, 
+        {
+            "input": "&boxUR", 
+            "description": "Bad named entity: boxUR without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&boxUR"
+                ]
+            ]
+        }, 
+        {
+            "input": "&boxUR;", 
+            "description": "Named entity: boxUR; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u255a"
+                ]
+            ]
+        }, 
+        {
+            "input": "&boxUl", 
+            "description": "Bad named entity: boxUl without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&boxUl"
+                ]
+            ]
+        }, 
+        {
+            "input": "&boxUl;", 
+            "description": "Named entity: boxUl; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u255c"
+                ]
+            ]
+        }, 
+        {
+            "input": "&boxUr", 
+            "description": "Bad named entity: boxUr without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&boxUr"
+                ]
+            ]
+        }, 
+        {
+            "input": "&boxUr;", 
+            "description": "Named entity: boxUr; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2559"
+                ]
+            ]
+        }, 
+        {
+            "input": "&boxV", 
+            "description": "Bad named entity: boxV without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&boxV"
+                ]
+            ]
+        }, 
+        {
+            "input": "&boxV;", 
+            "description": "Named entity: boxV; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2551"
+                ]
+            ]
+        }, 
+        {
+            "input": "&boxVH", 
+            "description": "Bad named entity: boxVH without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&boxVH"
+                ]
+            ]
+        }, 
+        {
+            "input": "&boxVH;", 
+            "description": "Named entity: boxVH; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u256c"
+                ]
+            ]
+        }, 
+        {
+            "input": "&boxVL", 
+            "description": "Bad named entity: boxVL without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&boxVL"
+                ]
+            ]
+        }, 
+        {
+            "input": "&boxVL;", 
+            "description": "Named entity: boxVL; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2563"
+                ]
+            ]
+        }, 
+        {
+            "input": "&boxVR", 
+            "description": "Bad named entity: boxVR without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&boxVR"
+                ]
+            ]
+        }, 
+        {
+            "input": "&boxVR;", 
+            "description": "Named entity: boxVR; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2560"
+                ]
+            ]
+        }, 
+        {
+            "input": "&boxVh", 
+            "description": "Bad named entity: boxVh without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&boxVh"
+                ]
+            ]
+        }, 
+        {
+            "input": "&boxVh;", 
+            "description": "Named entity: boxVh; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u256b"
+                ]
+            ]
+        }, 
+        {
+            "input": "&boxVl", 
+            "description": "Bad named entity: boxVl without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&boxVl"
+                ]
+            ]
+        }, 
+        {
+            "input": "&boxVl;", 
+            "description": "Named entity: boxVl; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2562"
+                ]
+            ]
+        }, 
+        {
+            "input": "&boxVr", 
+            "description": "Bad named entity: boxVr without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&boxVr"
+                ]
+            ]
+        }, 
+        {
+            "input": "&boxVr;", 
+            "description": "Named entity: boxVr; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u255f"
+                ]
+            ]
+        }, 
+        {
+            "input": "&boxbox", 
+            "description": "Bad named entity: boxbox without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&boxbox"
+                ]
+            ]
+        }, 
+        {
+            "input": "&boxbox;", 
+            "description": "Named entity: boxbox; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u29c9"
+                ]
+            ]
+        }, 
+        {
+            "input": "&boxdL", 
+            "description": "Bad named entity: boxdL without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&boxdL"
+                ]
+            ]
+        }, 
+        {
+            "input": "&boxdL;", 
+            "description": "Named entity: boxdL; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2555"
+                ]
+            ]
+        }, 
+        {
+            "input": "&boxdR", 
+            "description": "Bad named entity: boxdR without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&boxdR"
+                ]
+            ]
+        }, 
+        {
+            "input": "&boxdR;", 
+            "description": "Named entity: boxdR; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2552"
+                ]
+            ]
+        }, 
+        {
+            "input": "&boxdl", 
+            "description": "Bad named entity: boxdl without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&boxdl"
+                ]
+            ]
+        }, 
+        {
+            "input": "&boxdl;", 
+            "description": "Named entity: boxdl; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2510"
+                ]
+            ]
+        }, 
+        {
+            "input": "&boxdr", 
+            "description": "Bad named entity: boxdr without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&boxdr"
+                ]
+            ]
+        }, 
+        {
+            "input": "&boxdr;", 
+            "description": "Named entity: boxdr; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u250c"
+                ]
+            ]
+        }, 
+        {
+            "input": "&boxh", 
+            "description": "Bad named entity: boxh without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&boxh"
+                ]
+            ]
+        }, 
+        {
+            "input": "&boxh;", 
+            "description": "Named entity: boxh; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2500"
+                ]
+            ]
+        }, 
+        {
+            "input": "&boxhD", 
+            "description": "Bad named entity: boxhD without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&boxhD"
+                ]
+            ]
+        }, 
+        {
+            "input": "&boxhD;", 
+            "description": "Named entity: boxhD; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2565"
+                ]
+            ]
+        }, 
+        {
+            "input": "&boxhU", 
+            "description": "Bad named entity: boxhU without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&boxhU"
+                ]
+            ]
+        }, 
+        {
+            "input": "&boxhU;", 
+            "description": "Named entity: boxhU; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2568"
+                ]
+            ]
+        }, 
+        {
+            "input": "&boxhd", 
+            "description": "Bad named entity: boxhd without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&boxhd"
+                ]
+            ]
+        }, 
+        {
+            "input": "&boxhd;", 
+            "description": "Named entity: boxhd; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u252c"
+                ]
+            ]
+        }, 
+        {
+            "input": "&boxhu", 
+            "description": "Bad named entity: boxhu without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&boxhu"
+                ]
+            ]
+        }, 
+        {
+            "input": "&boxhu;", 
+            "description": "Named entity: boxhu; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2534"
+                ]
+            ]
+        }, 
+        {
+            "input": "&boxminus", 
+            "description": "Bad named entity: boxminus without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&boxminus"
+                ]
+            ]
+        }, 
+        {
+            "input": "&boxminus;", 
+            "description": "Named entity: boxminus; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u229f"
+                ]
+            ]
+        }, 
+        {
+            "input": "&boxplus", 
+            "description": "Bad named entity: boxplus without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&boxplus"
+                ]
+            ]
+        }, 
+        {
+            "input": "&boxplus;", 
+            "description": "Named entity: boxplus; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u229e"
+                ]
+            ]
+        }, 
+        {
+            "input": "&boxtimes", 
+            "description": "Bad named entity: boxtimes without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&boxtimes"
+                ]
+            ]
+        }, 
+        {
+            "input": "&boxtimes;", 
+            "description": "Named entity: boxtimes; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u22a0"
+                ]
+            ]
+        }, 
+        {
+            "input": "&boxuL", 
+            "description": "Bad named entity: boxuL without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&boxuL"
+                ]
+            ]
+        }, 
+        {
+            "input": "&boxuL;", 
+            "description": "Named entity: boxuL; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u255b"
+                ]
+            ]
+        }, 
+        {
+            "input": "&boxuR", 
+            "description": "Bad named entity: boxuR without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&boxuR"
+                ]
+            ]
+        }, 
+        {
+            "input": "&boxuR;", 
+            "description": "Named entity: boxuR; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2558"
+                ]
+            ]
+        }, 
+        {
+            "input": "&boxul", 
+            "description": "Bad named entity: boxul without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&boxul"
+                ]
+            ]
+        }, 
+        {
+            "input": "&boxul;", 
+            "description": "Named entity: boxul; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2518"
+                ]
+            ]
+        }, 
+        {
+            "input": "&boxur", 
+            "description": "Bad named entity: boxur without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&boxur"
+                ]
+            ]
+        }, 
+        {
+            "input": "&boxur;", 
+            "description": "Named entity: boxur; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2514"
+                ]
+            ]
+        }, 
+        {
+            "input": "&boxv", 
+            "description": "Bad named entity: boxv without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&boxv"
+                ]
+            ]
+        }, 
+        {
+            "input": "&boxv;", 
+            "description": "Named entity: boxv; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2502"
+                ]
+            ]
+        }, 
+        {
+            "input": "&boxvH", 
+            "description": "Bad named entity: boxvH without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&boxvH"
+                ]
+            ]
+        }, 
+        {
+            "input": "&boxvH;", 
+            "description": "Named entity: boxvH; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u256a"
+                ]
+            ]
+        }, 
+        {
+            "input": "&boxvL", 
+            "description": "Bad named entity: boxvL without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&boxvL"
+                ]
+            ]
+        }, 
+        {
+            "input": "&boxvL;", 
+            "description": "Named entity: boxvL; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2561"
+                ]
+            ]
+        }, 
+        {
+            "input": "&boxvR", 
+            "description": "Bad named entity: boxvR without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&boxvR"
+                ]
+            ]
+        }, 
+        {
+            "input": "&boxvR;", 
+            "description": "Named entity: boxvR; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u255e"
+                ]
+            ]
+        }, 
+        {
+            "input": "&boxvh", 
+            "description": "Bad named entity: boxvh without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&boxvh"
+                ]
+            ]
+        }, 
+        {
+            "input": "&boxvh;", 
+            "description": "Named entity: boxvh; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u253c"
+                ]
+            ]
+        }, 
+        {
+            "input": "&boxvl", 
+            "description": "Bad named entity: boxvl without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&boxvl"
+                ]
+            ]
+        }, 
+        {
+            "input": "&boxvl;", 
+            "description": "Named entity: boxvl; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2524"
+                ]
+            ]
+        }, 
+        {
+            "input": "&boxvr", 
+            "description": "Bad named entity: boxvr without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&boxvr"
+                ]
+            ]
+        }, 
+        {
+            "input": "&boxvr;", 
+            "description": "Named entity: boxvr; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u251c"
+                ]
+            ]
+        }, 
+        {
+            "input": "&bprime", 
+            "description": "Bad named entity: bprime without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&bprime"
+                ]
+            ]
+        }, 
+        {
+            "input": "&bprime;", 
+            "description": "Named entity: bprime; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2035"
+                ]
+            ]
+        }, 
+        {
+            "input": "&breve", 
+            "description": "Bad named entity: breve without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&breve"
+                ]
+            ]
+        }, 
+        {
+            "input": "&breve;", 
+            "description": "Named entity: breve; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u02d8"
+                ]
+            ]
+        }, 
+        {
+            "input": "&brvbar", 
+            "description": "Named entity: brvbar without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "\u00a6"
+                ]
+            ]
+        }, 
+        {
+            "input": "&brvbar;", 
+            "description": "Named entity: brvbar; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u00a6"
+                ]
+            ]
+        }, 
+        {
+            "input": "&bscr", 
+            "description": "Bad named entity: bscr without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&bscr"
+                ]
+            ]
+        }, 
+        {
+            "input": "&bscr;", 
+            "description": "Named entity: bscr; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\ud835\udcb7"
+                ]
+            ]
+        }, 
+        {
+            "input": "&bsemi", 
+            "description": "Bad named entity: bsemi without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&bsemi"
+                ]
+            ]
+        }, 
+        {
+            "input": "&bsemi;", 
+            "description": "Named entity: bsemi; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u204f"
+                ]
+            ]
+        }, 
+        {
+            "input": "&bsim", 
+            "description": "Bad named entity: bsim without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&bsim"
+                ]
+            ]
+        }, 
+        {
+            "input": "&bsim;", 
+            "description": "Named entity: bsim; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u223d"
+                ]
+            ]
+        }, 
+        {
+            "input": "&bsime", 
+            "description": "Bad named entity: bsime without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&bsime"
+                ]
+            ]
+        }, 
+        {
+            "input": "&bsime;", 
+            "description": "Named entity: bsime; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u22cd"
+                ]
+            ]
+        }, 
+        {
+            "input": "&bsol", 
+            "description": "Bad named entity: bsol without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&bsol"
+                ]
+            ]
+        }, 
+        {
+            "input": "&bsol;", 
+            "description": "Named entity: bsol; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\\"
+                ]
+            ]
+        }, 
+        {
+            "input": "&bsolb", 
+            "description": "Bad named entity: bsolb without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&bsolb"
+                ]
+            ]
+        }, 
+        {
+            "input": "&bsolb;", 
+            "description": "Named entity: bsolb; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u29c5"
+                ]
+            ]
+        }, 
+        {
+            "input": "&bsolhsub", 
+            "description": "Bad named entity: bsolhsub without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&bsolhsub"
+                ]
+            ]
+        }, 
+        {
+            "input": "&bsolhsub;", 
+            "description": "Named entity: bsolhsub; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u27c8"
+                ]
+            ]
+        }, 
+        {
+            "input": "&bull", 
+            "description": "Bad named entity: bull without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&bull"
+                ]
+            ]
+        }, 
+        {
+            "input": "&bull;", 
+            "description": "Named entity: bull; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2022"
+                ]
+            ]
+        }, 
+        {
+            "input": "&bullet", 
+            "description": "Bad named entity: bullet without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&bullet"
+                ]
+            ]
+        }, 
+        {
+            "input": "&bullet;", 
+            "description": "Named entity: bullet; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2022"
+                ]
+            ]
+        }, 
+        {
+            "input": "&bump", 
+            "description": "Bad named entity: bump without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&bump"
+                ]
+            ]
+        }, 
+        {
+            "input": "&bump;", 
+            "description": "Named entity: bump; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u224e"
+                ]
+            ]
+        }, 
+        {
+            "input": "&bumpE", 
+            "description": "Bad named entity: bumpE without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&bumpE"
+                ]
+            ]
+        }, 
+        {
+            "input": "&bumpE;", 
+            "description": "Named entity: bumpE; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2aae"
+                ]
+            ]
+        }, 
+        {
+            "input": "&bumpe", 
+            "description": "Bad named entity: bumpe without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&bumpe"
+                ]
+            ]
+        }, 
+        {
+            "input": "&bumpe;", 
+            "description": "Named entity: bumpe; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u224f"
+                ]
+            ]
+        }, 
+        {
+            "input": "&bumpeq", 
+            "description": "Bad named entity: bumpeq without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&bumpeq"
+                ]
+            ]
+        }, 
+        {
+            "input": "&bumpeq;", 
+            "description": "Named entity: bumpeq; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u224f"
+                ]
+            ]
+        }, 
+        {
+            "input": "&cacute", 
+            "description": "Bad named entity: cacute without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&cacute"
+                ]
+            ]
+        }, 
+        {
+            "input": "&cacute;", 
+            "description": "Named entity: cacute; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u0107"
+                ]
+            ]
+        }, 
+        {
+            "input": "&cap", 
+            "description": "Bad named entity: cap without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&cap"
+                ]
+            ]
+        }, 
+        {
+            "input": "&cap;", 
+            "description": "Named entity: cap; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2229"
+                ]
+            ]
+        }, 
+        {
+            "input": "&capand", 
+            "description": "Bad named entity: capand without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&capand"
+                ]
+            ]
+        }, 
+        {
+            "input": "&capand;", 
+            "description": "Named entity: capand; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2a44"
+                ]
+            ]
+        }, 
+        {
+            "input": "&capbrcup", 
+            "description": "Bad named entity: capbrcup without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&capbrcup"
+                ]
+            ]
+        }, 
+        {
+            "input": "&capbrcup;", 
+            "description": "Named entity: capbrcup; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2a49"
+                ]
+            ]
+        }, 
+        {
+            "input": "&capcap", 
+            "description": "Bad named entity: capcap without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&capcap"
+                ]
+            ]
+        }, 
+        {
+            "input": "&capcap;", 
+            "description": "Named entity: capcap; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2a4b"
+                ]
+            ]
+        }, 
+        {
+            "input": "&capcup", 
+            "description": "Bad named entity: capcup without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&capcup"
+                ]
+            ]
+        }, 
+        {
+            "input": "&capcup;", 
+            "description": "Named entity: capcup; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2a47"
+                ]
+            ]
+        }, 
+        {
+            "input": "&capdot", 
+            "description": "Bad named entity: capdot without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&capdot"
+                ]
+            ]
+        }, 
+        {
+            "input": "&capdot;", 
+            "description": "Named entity: capdot; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2a40"
+                ]
+            ]
+        }, 
+        {
+            "input": "&caps", 
+            "description": "Bad named entity: caps without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&caps"
+                ]
+            ]
+        }, 
+        {
+            "input": "&caps;", 
+            "description": "Named entity: caps; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2229\ufe00"
+                ]
+            ]
+        }, 
+        {
+            "input": "&caret", 
+            "description": "Bad named entity: caret without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&caret"
+                ]
+            ]
+        }, 
+        {
+            "input": "&caret;", 
+            "description": "Named entity: caret; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2041"
+                ]
+            ]
+        }, 
+        {
+            "input": "&caron", 
+            "description": "Bad named entity: caron without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&caron"
+                ]
+            ]
+        }, 
+        {
+            "input": "&caron;", 
+            "description": "Named entity: caron; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u02c7"
+                ]
+            ]
+        }, 
+        {
+            "input": "&ccaps", 
+            "description": "Bad named entity: ccaps without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&ccaps"
+                ]
+            ]
+        }, 
+        {
+            "input": "&ccaps;", 
+            "description": "Named entity: ccaps; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2a4d"
+                ]
+            ]
+        }, 
+        {
+            "input": "&ccaron", 
+            "description": "Bad named entity: ccaron without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&ccaron"
+                ]
+            ]
+        }, 
+        {
+            "input": "&ccaron;", 
+            "description": "Named entity: ccaron; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u010d"
+                ]
+            ]
+        }, 
+        {
+            "input": "&ccedil", 
+            "description": "Named entity: ccedil without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "\u00e7"
+                ]
+            ]
+        }, 
+        {
+            "input": "&ccedil;", 
+            "description": "Named entity: ccedil; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u00e7"
+                ]
+            ]
+        }, 
+        {
+            "input": "&ccirc", 
+            "description": "Bad named entity: ccirc without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&ccirc"
+                ]
+            ]
+        }, 
+        {
+            "input": "&ccirc;", 
+            "description": "Named entity: ccirc; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u0109"
+                ]
+            ]
+        }, 
+        {
+            "input": "&ccups", 
+            "description": "Bad named entity: ccups without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&ccups"
+                ]
+            ]
+        }, 
+        {
+            "input": "&ccups;", 
+            "description": "Named entity: ccups; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2a4c"
+                ]
+            ]
+        }, 
+        {
+            "input": "&ccupssm", 
+            "description": "Bad named entity: ccupssm without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&ccupssm"
+                ]
+            ]
+        }, 
+        {
+            "input": "&ccupssm;", 
+            "description": "Named entity: ccupssm; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2a50"
+                ]
+            ]
+        }, 
+        {
+            "input": "&cdot", 
+            "description": "Bad named entity: cdot without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&cdot"
+                ]
+            ]
+        }, 
+        {
+            "input": "&cdot;", 
+            "description": "Named entity: cdot; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u010b"
+                ]
+            ]
+        }, 
+        {
+            "input": "&cedil", 
+            "description": "Named entity: cedil without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "\u00b8"
+                ]
+            ]
+        }, 
+        {
+            "input": "&cedil;", 
+            "description": "Named entity: cedil; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u00b8"
+                ]
+            ]
+        }, 
+        {
+            "input": "&cemptyv", 
+            "description": "Bad named entity: cemptyv without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&cemptyv"
+                ]
+            ]
+        }, 
+        {
+            "input": "&cemptyv;", 
+            "description": "Named entity: cemptyv; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u29b2"
+                ]
+            ]
+        }, 
+        {
+            "input": "&cent", 
+            "description": "Named entity: cent without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "\u00a2"
+                ]
+            ]
+        }, 
+        {
+            "input": "&cent;", 
+            "description": "Named entity: cent; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u00a2"
+                ]
+            ]
+        }, 
+        {
+            "input": "&centerdot;", 
+            "description": "Named entity: centerdot; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u00b7"
+                ]
+            ]
+        }, 
+        {
+            "input": "&cfr", 
+            "description": "Bad named entity: cfr without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&cfr"
+                ]
+            ]
+        }, 
+        {
+            "input": "&cfr;", 
+            "description": "Named entity: cfr; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\ud835\udd20"
+                ]
+            ]
+        }, 
+        {
+            "input": "&chcy", 
+            "description": "Bad named entity: chcy without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&chcy"
+                ]
+            ]
+        }, 
+        {
+            "input": "&chcy;", 
+            "description": "Named entity: chcy; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u0447"
+                ]
+            ]
+        }, 
+        {
+            "input": "&check", 
+            "description": "Bad named entity: check without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&check"
+                ]
+            ]
+        }, 
+        {
+            "input": "&check;", 
+            "description": "Named entity: check; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2713"
+                ]
+            ]
+        }, 
+        {
+            "input": "&checkmark", 
+            "description": "Bad named entity: checkmark without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&checkmark"
+                ]
+            ]
+        }, 
+        {
+            "input": "&checkmark;", 
+            "description": "Named entity: checkmark; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2713"
+                ]
+            ]
+        }, 
+        {
+            "input": "&chi", 
+            "description": "Bad named entity: chi without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&chi"
+                ]
+            ]
+        }, 
+        {
+            "input": "&chi;", 
+            "description": "Named entity: chi; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u03c7"
+                ]
+            ]
+        }, 
+        {
+            "input": "&cir", 
+            "description": "Bad named entity: cir without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&cir"
+                ]
+            ]
+        }, 
+        {
+            "input": "&cir;", 
+            "description": "Named entity: cir; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u25cb"
+                ]
+            ]
+        }, 
+        {
+            "input": "&cirE", 
+            "description": "Bad named entity: cirE without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&cirE"
+                ]
+            ]
+        }, 
+        {
+            "input": "&cirE;", 
+            "description": "Named entity: cirE; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u29c3"
+                ]
+            ]
+        }, 
+        {
+            "input": "&circ", 
+            "description": "Bad named entity: circ without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&circ"
+                ]
+            ]
+        }, 
+        {
+            "input": "&circ;", 
+            "description": "Named entity: circ; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u02c6"
+                ]
+            ]
+        }, 
+        {
+            "input": "&circeq", 
+            "description": "Bad named entity: circeq without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&circeq"
+                ]
+            ]
+        }, 
+        {
+            "input": "&circeq;", 
+            "description": "Named entity: circeq; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2257"
+                ]
+            ]
+        }, 
+        {
+            "input": "&circlearrowleft", 
+            "description": "Bad named entity: circlearrowleft without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&circlearrowleft"
+                ]
+            ]
+        }, 
+        {
+            "input": "&circlearrowleft;", 
+            "description": "Named entity: circlearrowleft; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u21ba"
+                ]
+            ]
+        }, 
+        {
+            "input": "&circlearrowright", 
+            "description": "Bad named entity: circlearrowright without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&circlearrowright"
+                ]
+            ]
+        }, 
+        {
+            "input": "&circlearrowright;", 
+            "description": "Named entity: circlearrowright; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u21bb"
+                ]
+            ]
+        }, 
+        {
+            "input": "&circledR", 
+            "description": "Bad named entity: circledR without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&circledR"
+                ]
+            ]
+        }, 
+        {
+            "input": "&circledR;", 
+            "description": "Named entity: circledR; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u00ae"
+                ]
+            ]
+        }, 
+        {
+            "input": "&circledS", 
+            "description": "Bad named entity: circledS without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&circledS"
+                ]
+            ]
+        }, 
+        {
+            "input": "&circledS;", 
+            "description": "Named entity: circledS; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u24c8"
+                ]
+            ]
+        }, 
+        {
+            "input": "&circledast", 
+            "description": "Bad named entity: circledast without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&circledast"
+                ]
+            ]
+        }, 
+        {
+            "input": "&circledast;", 
+            "description": "Named entity: circledast; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u229b"
+                ]
+            ]
+        }, 
+        {
+            "input": "&circledcirc", 
+            "description": "Bad named entity: circledcirc without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&circledcirc"
+                ]
+            ]
+        }, 
+        {
+            "input": "&circledcirc;", 
+            "description": "Named entity: circledcirc; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u229a"
+                ]
+            ]
+        }, 
+        {
+            "input": "&circleddash", 
+            "description": "Bad named entity: circleddash without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&circleddash"
+                ]
+            ]
+        }, 
+        {
+            "input": "&circleddash;", 
+            "description": "Named entity: circleddash; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u229d"
+                ]
+            ]
+        }, 
+        {
+            "input": "&cire", 
+            "description": "Bad named entity: cire without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&cire"
+                ]
+            ]
+        }, 
+        {
+            "input": "&cire;", 
+            "description": "Named entity: cire; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2257"
+                ]
+            ]
+        }, 
+        {
+            "input": "&cirfnint", 
+            "description": "Bad named entity: cirfnint without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&cirfnint"
+                ]
+            ]
+        }, 
+        {
+            "input": "&cirfnint;", 
+            "description": "Named entity: cirfnint; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2a10"
+                ]
+            ]
+        }, 
+        {
+            "input": "&cirmid", 
+            "description": "Bad named entity: cirmid without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&cirmid"
+                ]
+            ]
+        }, 
+        {
+            "input": "&cirmid;", 
+            "description": "Named entity: cirmid; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2aef"
+                ]
+            ]
+        }, 
+        {
+            "input": "&cirscir", 
+            "description": "Bad named entity: cirscir without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&cirscir"
+                ]
+            ]
+        }, 
+        {
+            "input": "&cirscir;", 
+            "description": "Named entity: cirscir; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u29c2"
+                ]
+            ]
+        }, 
+        {
+            "input": "&clubs", 
+            "description": "Bad named entity: clubs without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&clubs"
+                ]
+            ]
+        }, 
+        {
+            "input": "&clubs;", 
+            "description": "Named entity: clubs; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2663"
+                ]
+            ]
+        }, 
+        {
+            "input": "&clubsuit", 
+            "description": "Bad named entity: clubsuit without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&clubsuit"
+                ]
+            ]
+        }, 
+        {
+            "input": "&clubsuit;", 
+            "description": "Named entity: clubsuit; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2663"
+                ]
+            ]
+        }, 
+        {
+            "input": "&colon", 
+            "description": "Bad named entity: colon without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&colon"
+                ]
+            ]
+        }, 
+        {
+            "input": "&colon;", 
+            "description": "Named entity: colon; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    ":"
+                ]
+            ]
+        }, 
+        {
+            "input": "&colone", 
+            "description": "Bad named entity: colone without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&colone"
+                ]
+            ]
+        }, 
+        {
+            "input": "&colone;", 
+            "description": "Named entity: colone; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2254"
+                ]
+            ]
+        }, 
+        {
+            "input": "&coloneq", 
+            "description": "Bad named entity: coloneq without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&coloneq"
+                ]
+            ]
+        }, 
+        {
+            "input": "&coloneq;", 
+            "description": "Named entity: coloneq; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2254"
+                ]
+            ]
+        }, 
+        {
+            "input": "&comma", 
+            "description": "Bad named entity: comma without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&comma"
+                ]
+            ]
+        }, 
+        {
+            "input": "&comma;", 
+            "description": "Named entity: comma; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    ","
+                ]
+            ]
+        }, 
+        {
+            "input": "&commat", 
+            "description": "Bad named entity: commat without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&commat"
+                ]
+            ]
+        }, 
+        {
+            "input": "&commat;", 
+            "description": "Named entity: commat; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "@"
+                ]
+            ]
+        }, 
+        {
+            "input": "&comp", 
+            "description": "Bad named entity: comp without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&comp"
+                ]
+            ]
+        }, 
+        {
+            "input": "&comp;", 
+            "description": "Named entity: comp; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2201"
+                ]
+            ]
+        }, 
+        {
+            "input": "&compfn", 
+            "description": "Bad named entity: compfn without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&compfn"
+                ]
+            ]
+        }, 
+        {
+            "input": "&compfn;", 
+            "description": "Named entity: compfn; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2218"
+                ]
+            ]
+        }, 
+        {
+            "input": "&complement", 
+            "description": "Bad named entity: complement without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&complement"
+                ]
+            ]
+        }, 
+        {
+            "input": "&complement;", 
+            "description": "Named entity: complement; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2201"
+                ]
+            ]
+        }, 
+        {
+            "input": "&complexes", 
+            "description": "Bad named entity: complexes without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&complexes"
+                ]
+            ]
+        }, 
+        {
+            "input": "&complexes;", 
+            "description": "Named entity: complexes; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2102"
+                ]
+            ]
+        }, 
+        {
+            "input": "&cong", 
+            "description": "Bad named entity: cong without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&cong"
+                ]
+            ]
+        }, 
+        {
+            "input": "&cong;", 
+            "description": "Named entity: cong; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2245"
+                ]
+            ]
+        }, 
+        {
+            "input": "&congdot", 
+            "description": "Bad named entity: congdot without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&congdot"
+                ]
+            ]
+        }, 
+        {
+            "input": "&congdot;", 
+            "description": "Named entity: congdot; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2a6d"
+                ]
+            ]
+        }, 
+        {
+            "input": "&conint", 
+            "description": "Bad named entity: conint without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&conint"
+                ]
+            ]
+        }, 
+        {
+            "input": "&conint;", 
+            "description": "Named entity: conint; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u222e"
+                ]
+            ]
+        }, 
+        {
+            "input": "&copf", 
+            "description": "Bad named entity: copf without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&copf"
+                ]
+            ]
+        }, 
+        {
+            "input": "&copf;", 
+            "description": "Named entity: copf; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\ud835\udd54"
+                ]
+            ]
+        }, 
+        {
+            "input": "&coprod", 
+            "description": "Bad named entity: coprod without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&coprod"
+                ]
+            ]
+        }, 
+        {
+            "input": "&coprod;", 
+            "description": "Named entity: coprod; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2210"
+                ]
+            ]
+        }, 
+        {
+            "input": "&copy", 
+            "description": "Named entity: copy without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "\u00a9"
+                ]
+            ]
+        }, 
+        {
+            "input": "&copy;", 
+            "description": "Named entity: copy; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u00a9"
+                ]
+            ]
+        }, 
+        {
+            "input": "&copysr;", 
+            "description": "Named entity: copysr; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2117"
+                ]
+            ]
+        }, 
+        {
+            "input": "&crarr", 
+            "description": "Bad named entity: crarr without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&crarr"
+                ]
+            ]
+        }, 
+        {
+            "input": "&crarr;", 
+            "description": "Named entity: crarr; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u21b5"
+                ]
+            ]
+        }, 
+        {
+            "input": "&cross", 
+            "description": "Bad named entity: cross without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&cross"
+                ]
+            ]
+        }, 
+        {
+            "input": "&cross;", 
+            "description": "Named entity: cross; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2717"
+                ]
+            ]
+        }, 
+        {
+            "input": "&cscr", 
+            "description": "Bad named entity: cscr without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&cscr"
+                ]
+            ]
+        }, 
+        {
+            "input": "&cscr;", 
+            "description": "Named entity: cscr; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\ud835\udcb8"
+                ]
+            ]
+        }, 
+        {
+            "input": "&csub", 
+            "description": "Bad named entity: csub without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&csub"
+                ]
+            ]
+        }, 
+        {
+            "input": "&csub;", 
+            "description": "Named entity: csub; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2acf"
+                ]
+            ]
+        }, 
+        {
+            "input": "&csube", 
+            "description": "Bad named entity: csube without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&csube"
+                ]
+            ]
+        }, 
+        {
+            "input": "&csube;", 
+            "description": "Named entity: csube; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2ad1"
+                ]
+            ]
+        }, 
+        {
+            "input": "&csup", 
+            "description": "Bad named entity: csup without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&csup"
+                ]
+            ]
+        }, 
+        {
+            "input": "&csup;", 
+            "description": "Named entity: csup; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2ad0"
+                ]
+            ]
+        }, 
+        {
+            "input": "&csupe", 
+            "description": "Bad named entity: csupe without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&csupe"
+                ]
+            ]
+        }, 
+        {
+            "input": "&csupe;", 
+            "description": "Named entity: csupe; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2ad2"
+                ]
+            ]
+        }, 
+        {
+            "input": "&ctdot", 
+            "description": "Bad named entity: ctdot without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&ctdot"
+                ]
+            ]
+        }, 
+        {
+            "input": "&ctdot;", 
+            "description": "Named entity: ctdot; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u22ef"
+                ]
+            ]
+        }, 
+        {
+            "input": "&cudarrl", 
+            "description": "Bad named entity: cudarrl without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&cudarrl"
+                ]
+            ]
+        }, 
+        {
+            "input": "&cudarrl;", 
+            "description": "Named entity: cudarrl; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2938"
+                ]
+            ]
+        }, 
+        {
+            "input": "&cudarrr", 
+            "description": "Bad named entity: cudarrr without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&cudarrr"
+                ]
+            ]
+        }, 
+        {
+            "input": "&cudarrr;", 
+            "description": "Named entity: cudarrr; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2935"
+                ]
+            ]
+        }, 
+        {
+            "input": "&cuepr", 
+            "description": "Bad named entity: cuepr without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&cuepr"
+                ]
+            ]
+        }, 
+        {
+            "input": "&cuepr;", 
+            "description": "Named entity: cuepr; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u22de"
+                ]
+            ]
+        }, 
+        {
+            "input": "&cuesc", 
+            "description": "Bad named entity: cuesc without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&cuesc"
+                ]
+            ]
+        }, 
+        {
+            "input": "&cuesc;", 
+            "description": "Named entity: cuesc; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u22df"
+                ]
+            ]
+        }, 
+        {
+            "input": "&cularr", 
+            "description": "Bad named entity: cularr without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&cularr"
+                ]
+            ]
+        }, 
+        {
+            "input": "&cularr;", 
+            "description": "Named entity: cularr; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u21b6"
+                ]
+            ]
+        }, 
+        {
+            "input": "&cularrp", 
+            "description": "Bad named entity: cularrp without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&cularrp"
+                ]
+            ]
+        }, 
+        {
+            "input": "&cularrp;", 
+            "description": "Named entity: cularrp; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u293d"
+                ]
+            ]
+        }, 
+        {
+            "input": "&cup", 
+            "description": "Bad named entity: cup without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&cup"
+                ]
+            ]
+        }, 
+        {
+            "input": "&cup;", 
+            "description": "Named entity: cup; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u222a"
+                ]
+            ]
+        }, 
+        {
+            "input": "&cupbrcap", 
+            "description": "Bad named entity: cupbrcap without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&cupbrcap"
+                ]
+            ]
+        }, 
+        {
+            "input": "&cupbrcap;", 
+            "description": "Named entity: cupbrcap; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2a48"
+                ]
+            ]
+        }, 
+        {
+            "input": "&cupcap", 
+            "description": "Bad named entity: cupcap without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&cupcap"
+                ]
+            ]
+        }, 
+        {
+            "input": "&cupcap;", 
+            "description": "Named entity: cupcap; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2a46"
+                ]
+            ]
+        }, 
+        {
+            "input": "&cupcup", 
+            "description": "Bad named entity: cupcup without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&cupcup"
+                ]
+            ]
+        }, 
+        {
+            "input": "&cupcup;", 
+            "description": "Named entity: cupcup; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2a4a"
+                ]
+            ]
+        }, 
+        {
+            "input": "&cupdot", 
+            "description": "Bad named entity: cupdot without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&cupdot"
+                ]
+            ]
+        }, 
+        {
+            "input": "&cupdot;", 
+            "description": "Named entity: cupdot; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u228d"
+                ]
+            ]
+        }, 
+        {
+            "input": "&cupor", 
+            "description": "Bad named entity: cupor without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&cupor"
+                ]
+            ]
+        }, 
+        {
+            "input": "&cupor;", 
+            "description": "Named entity: cupor; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2a45"
+                ]
+            ]
+        }, 
+        {
+            "input": "&cups", 
+            "description": "Bad named entity: cups without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&cups"
+                ]
+            ]
+        }, 
+        {
+            "input": "&cups;", 
+            "description": "Named entity: cups; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u222a\ufe00"
+                ]
+            ]
+        }, 
+        {
+            "input": "&curarr", 
+            "description": "Bad named entity: curarr without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&curarr"
+                ]
+            ]
+        }, 
+        {
+            "input": "&curarr;", 
+            "description": "Named entity: curarr; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u21b7"
+                ]
+            ]
+        }, 
+        {
+            "input": "&curarrm", 
+            "description": "Bad named entity: curarrm without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&curarrm"
+                ]
+            ]
+        }, 
+        {
+            "input": "&curarrm;", 
+            "description": "Named entity: curarrm; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u293c"
+                ]
+            ]
+        }, 
+        {
+            "input": "&curlyeqprec", 
+            "description": "Bad named entity: curlyeqprec without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&curlyeqprec"
+                ]
+            ]
+        }, 
+        {
+            "input": "&curlyeqprec;", 
+            "description": "Named entity: curlyeqprec; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u22de"
+                ]
+            ]
+        }, 
+        {
+            "input": "&curlyeqsucc", 
+            "description": "Bad named entity: curlyeqsucc without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&curlyeqsucc"
+                ]
+            ]
+        }, 
+        {
+            "input": "&curlyeqsucc;", 
+            "description": "Named entity: curlyeqsucc; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u22df"
+                ]
+            ]
+        }, 
+        {
+            "input": "&curlyvee", 
+            "description": "Bad named entity: curlyvee without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&curlyvee"
+                ]
+            ]
+        }, 
+        {
+            "input": "&curlyvee;", 
+            "description": "Named entity: curlyvee; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u22ce"
+                ]
+            ]
+        }, 
+        {
+            "input": "&curlywedge", 
+            "description": "Bad named entity: curlywedge without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&curlywedge"
+                ]
+            ]
+        }, 
+        {
+            "input": "&curlywedge;", 
+            "description": "Named entity: curlywedge; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u22cf"
+                ]
+            ]
+        }, 
+        {
+            "input": "&curren", 
+            "description": "Named entity: curren without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "\u00a4"
+                ]
+            ]
+        }, 
+        {
+            "input": "&curren;", 
+            "description": "Named entity: curren; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u00a4"
+                ]
+            ]
+        }, 
+        {
+            "input": "&curvearrowleft", 
+            "description": "Bad named entity: curvearrowleft without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&curvearrowleft"
+                ]
+            ]
+        }, 
+        {
+            "input": "&curvearrowleft;", 
+            "description": "Named entity: curvearrowleft; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u21b6"
+                ]
+            ]
+        }, 
+        {
+            "input": "&curvearrowright", 
+            "description": "Bad named entity: curvearrowright without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&curvearrowright"
+                ]
+            ]
+        }, 
+        {
+            "input": "&curvearrowright;", 
+            "description": "Named entity: curvearrowright; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u21b7"
+                ]
+            ]
+        }, 
+        {
+            "input": "&cuvee", 
+            "description": "Bad named entity: cuvee without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&cuvee"
+                ]
+            ]
+        }, 
+        {
+            "input": "&cuvee;", 
+            "description": "Named entity: cuvee; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u22ce"
+                ]
+            ]
+        }, 
+        {
+            "input": "&cuwed", 
+            "description": "Bad named entity: cuwed without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&cuwed"
+                ]
+            ]
+        }, 
+        {
+            "input": "&cuwed;", 
+            "description": "Named entity: cuwed; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u22cf"
+                ]
+            ]
+        }, 
+        {
+            "input": "&cwconint", 
+            "description": "Bad named entity: cwconint without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&cwconint"
+                ]
+            ]
+        }, 
+        {
+            "input": "&cwconint;", 
+            "description": "Named entity: cwconint; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2232"
+                ]
+            ]
+        }, 
+        {
+            "input": "&cwint", 
+            "description": "Bad named entity: cwint without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&cwint"
+                ]
+            ]
+        }, 
+        {
+            "input": "&cwint;", 
+            "description": "Named entity: cwint; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2231"
+                ]
+            ]
+        }, 
+        {
+            "input": "&cylcty", 
+            "description": "Bad named entity: cylcty without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&cylcty"
+                ]
+            ]
+        }, 
+        {
+            "input": "&cylcty;", 
+            "description": "Named entity: cylcty; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u232d"
+                ]
+            ]
+        }, 
+        {
+            "input": "&dArr", 
+            "description": "Bad named entity: dArr without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&dArr"
+                ]
+            ]
+        }, 
+        {
+            "input": "&dArr;", 
+            "description": "Named entity: dArr; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u21d3"
+                ]
+            ]
+        }, 
+        {
+            "input": "&dHar", 
+            "description": "Bad named entity: dHar without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&dHar"
+                ]
+            ]
+        }, 
+        {
+            "input": "&dHar;", 
+            "description": "Named entity: dHar; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2965"
+                ]
+            ]
+        }, 
+        {
+            "input": "&dagger", 
+            "description": "Bad named entity: dagger without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&dagger"
+                ]
+            ]
+        }, 
+        {
+            "input": "&dagger;", 
+            "description": "Named entity: dagger; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2020"
+                ]
+            ]
+        }, 
+        {
+            "input": "&daleth", 
+            "description": "Bad named entity: daleth without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&daleth"
+                ]
+            ]
+        }, 
+        {
+            "input": "&daleth;", 
+            "description": "Named entity: daleth; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2138"
+                ]
+            ]
+        }, 
+        {
+            "input": "&darr", 
+            "description": "Bad named entity: darr without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&darr"
+                ]
+            ]
+        }, 
+        {
+            "input": "&darr;", 
+            "description": "Named entity: darr; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2193"
+                ]
+            ]
+        }, 
+        {
+            "input": "&dash", 
+            "description": "Bad named entity: dash without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&dash"
+                ]
+            ]
+        }, 
+        {
+            "input": "&dash;", 
+            "description": "Named entity: dash; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2010"
+                ]
+            ]
+        }, 
+        {
+            "input": "&dashv", 
+            "description": "Bad named entity: dashv without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&dashv"
+                ]
+            ]
+        }, 
+        {
+            "input": "&dashv;", 
+            "description": "Named entity: dashv; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u22a3"
+                ]
+            ]
+        }, 
+        {
+            "input": "&dbkarow", 
+            "description": "Bad named entity: dbkarow without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&dbkarow"
+                ]
+            ]
+        }, 
+        {
+            "input": "&dbkarow;", 
+            "description": "Named entity: dbkarow; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u290f"
+                ]
+            ]
+        }, 
+        {
+            "input": "&dblac", 
+            "description": "Bad named entity: dblac without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&dblac"
+                ]
+            ]
+        }, 
+        {
+            "input": "&dblac;", 
+            "description": "Named entity: dblac; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u02dd"
+                ]
+            ]
+        }, 
+        {
+            "input": "&dcaron", 
+            "description": "Bad named entity: dcaron without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&dcaron"
+                ]
+            ]
+        }, 
+        {
+            "input": "&dcaron;", 
+            "description": "Named entity: dcaron; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u010f"
+                ]
+            ]
+        }, 
+        {
+            "input": "&dcy", 
+            "description": "Bad named entity: dcy without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&dcy"
+                ]
+            ]
+        }, 
+        {
+            "input": "&dcy;", 
+            "description": "Named entity: dcy; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u0434"
+                ]
+            ]
+        }, 
+        {
+            "input": "&dd", 
+            "description": "Bad named entity: dd without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&dd"
+                ]
+            ]
+        }, 
+        {
+            "input": "&dd;", 
+            "description": "Named entity: dd; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2146"
+                ]
+            ]
+        }, 
+        {
+            "input": "&ddagger", 
+            "description": "Bad named entity: ddagger without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&ddagger"
+                ]
+            ]
+        }, 
+        {
+            "input": "&ddagger;", 
+            "description": "Named entity: ddagger; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2021"
+                ]
+            ]
+        }, 
+        {
+            "input": "&ddarr", 
+            "description": "Bad named entity: ddarr without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&ddarr"
+                ]
+            ]
+        }, 
+        {
+            "input": "&ddarr;", 
+            "description": "Named entity: ddarr; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u21ca"
+                ]
+            ]
+        }, 
+        {
+            "input": "&ddotseq", 
+            "description": "Bad named entity: ddotseq without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&ddotseq"
+                ]
+            ]
+        }, 
+        {
+            "input": "&ddotseq;", 
+            "description": "Named entity: ddotseq; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2a77"
+                ]
+            ]
+        }, 
+        {
+            "input": "&deg", 
+            "description": "Named entity: deg without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "\u00b0"
+                ]
+            ]
+        }, 
+        {
+            "input": "&deg;", 
+            "description": "Named entity: deg; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u00b0"
+                ]
+            ]
+        }, 
+        {
+            "input": "&delta", 
+            "description": "Bad named entity: delta without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&delta"
+                ]
+            ]
+        }, 
+        {
+            "input": "&delta;", 
+            "description": "Named entity: delta; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u03b4"
+                ]
+            ]
+        }, 
+        {
+            "input": "&demptyv", 
+            "description": "Bad named entity: demptyv without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&demptyv"
+                ]
+            ]
+        }, 
+        {
+            "input": "&demptyv;", 
+            "description": "Named entity: demptyv; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u29b1"
+                ]
+            ]
+        }, 
+        {
+            "input": "&dfisht", 
+            "description": "Bad named entity: dfisht without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&dfisht"
+                ]
+            ]
+        }, 
+        {
+            "input": "&dfisht;", 
+            "description": "Named entity: dfisht; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u297f"
+                ]
+            ]
+        }, 
+        {
+            "input": "&dfr", 
+            "description": "Bad named entity: dfr without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&dfr"
+                ]
+            ]
+        }, 
+        {
+            "input": "&dfr;", 
+            "description": "Named entity: dfr; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\ud835\udd21"
+                ]
+            ]
+        }, 
+        {
+            "input": "&dharl", 
+            "description": "Bad named entity: dharl without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&dharl"
+                ]
+            ]
+        }, 
+        {
+            "input": "&dharl;", 
+            "description": "Named entity: dharl; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u21c3"
+                ]
+            ]
+        }, 
+        {
+            "input": "&dharr", 
+            "description": "Bad named entity: dharr without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&dharr"
+                ]
+            ]
+        }, 
+        {
+            "input": "&dharr;", 
+            "description": "Named entity: dharr; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u21c2"
+                ]
+            ]
+        }, 
+        {
+            "input": "&diam", 
+            "description": "Bad named entity: diam without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&diam"
+                ]
+            ]
+        }, 
+        {
+            "input": "&diam;", 
+            "description": "Named entity: diam; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u22c4"
+                ]
+            ]
+        }, 
+        {
+            "input": "&diamond", 
+            "description": "Bad named entity: diamond without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&diamond"
+                ]
+            ]
+        }, 
+        {
+            "input": "&diamond;", 
+            "description": "Named entity: diamond; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u22c4"
+                ]
+            ]
+        }, 
+        {
+            "input": "&diamondsuit", 
+            "description": "Bad named entity: diamondsuit without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&diamondsuit"
+                ]
+            ]
+        }, 
+        {
+            "input": "&diamondsuit;", 
+            "description": "Named entity: diamondsuit; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2666"
+                ]
+            ]
+        }, 
+        {
+            "input": "&diams", 
+            "description": "Bad named entity: diams without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&diams"
+                ]
+            ]
+        }, 
+        {
+            "input": "&diams;", 
+            "description": "Named entity: diams; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2666"
+                ]
+            ]
+        }, 
+        {
+            "input": "&die", 
+            "description": "Bad named entity: die without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&die"
+                ]
+            ]
+        }, 
+        {
+            "input": "&die;", 
+            "description": "Named entity: die; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u00a8"
+                ]
+            ]
+        }, 
+        {
+            "input": "&digamma", 
+            "description": "Bad named entity: digamma without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&digamma"
+                ]
+            ]
+        }, 
+        {
+            "input": "&digamma;", 
+            "description": "Named entity: digamma; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u03dd"
+                ]
+            ]
+        }, 
+        {
+            "input": "&disin", 
+            "description": "Bad named entity: disin without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&disin"
+                ]
+            ]
+        }, 
+        {
+            "input": "&disin;", 
+            "description": "Named entity: disin; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u22f2"
+                ]
+            ]
+        }, 
+        {
+            "input": "&div", 
+            "description": "Bad named entity: div without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&div"
+                ]
+            ]
+        }, 
+        {
+            "input": "&div;", 
+            "description": "Named entity: div; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u00f7"
+                ]
+            ]
+        }, 
+        {
+            "input": "&divide", 
+            "description": "Named entity: divide without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "\u00f7"
+                ]
+            ]
+        }, 
+        {
+            "input": "&divide;", 
+            "description": "Named entity: divide; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u00f7"
+                ]
+            ]
+        }, 
+        {
+            "input": "&divideontimes;", 
+            "description": "Named entity: divideontimes; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u22c7"
+                ]
+            ]
+        }, 
+        {
+            "input": "&divonx", 
+            "description": "Bad named entity: divonx without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&divonx"
+                ]
+            ]
+        }, 
+        {
+            "input": "&divonx;", 
+            "description": "Named entity: divonx; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u22c7"
+                ]
+            ]
+        }, 
+        {
+            "input": "&djcy", 
+            "description": "Bad named entity: djcy without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&djcy"
+                ]
+            ]
+        }, 
+        {
+            "input": "&djcy;", 
+            "description": "Named entity: djcy; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u0452"
+                ]
+            ]
+        }, 
+        {
+            "input": "&dlcorn", 
+            "description": "Bad named entity: dlcorn without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&dlcorn"
+                ]
+            ]
+        }, 
+        {
+            "input": "&dlcorn;", 
+            "description": "Named entity: dlcorn; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u231e"
+                ]
+            ]
+        }, 
+        {
+            "input": "&dlcrop", 
+            "description": "Bad named entity: dlcrop without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&dlcrop"
+                ]
+            ]
+        }, 
+        {
+            "input": "&dlcrop;", 
+            "description": "Named entity: dlcrop; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u230d"
+                ]
+            ]
+        }, 
+        {
+            "input": "&dollar", 
+            "description": "Bad named entity: dollar without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&dollar"
+                ]
+            ]
+        }, 
+        {
+            "input": "&dollar;", 
+            "description": "Named entity: dollar; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "$"
+                ]
+            ]
+        }, 
+        {
+            "input": "&dopf", 
+            "description": "Bad named entity: dopf without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&dopf"
+                ]
+            ]
+        }, 
+        {
+            "input": "&dopf;", 
+            "description": "Named entity: dopf; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\ud835\udd55"
+                ]
+            ]
+        }, 
+        {
+            "input": "&dot", 
+            "description": "Bad named entity: dot without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&dot"
+                ]
+            ]
+        }, 
+        {
+            "input": "&dot;", 
+            "description": "Named entity: dot; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u02d9"
+                ]
+            ]
+        }, 
+        {
+            "input": "&doteq", 
+            "description": "Bad named entity: doteq without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&doteq"
+                ]
+            ]
+        }, 
+        {
+            "input": "&doteq;", 
+            "description": "Named entity: doteq; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2250"
+                ]
+            ]
+        }, 
+        {
+            "input": "&doteqdot", 
+            "description": "Bad named entity: doteqdot without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&doteqdot"
+                ]
+            ]
+        }, 
+        {
+            "input": "&doteqdot;", 
+            "description": "Named entity: doteqdot; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2251"
+                ]
+            ]
+        }, 
+        {
+            "input": "&dotminus", 
+            "description": "Bad named entity: dotminus without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&dotminus"
+                ]
+            ]
+        }, 
+        {
+            "input": "&dotminus;", 
+            "description": "Named entity: dotminus; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2238"
+                ]
+            ]
+        }, 
+        {
+            "input": "&dotplus", 
+            "description": "Bad named entity: dotplus without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&dotplus"
+                ]
+            ]
+        }, 
+        {
+            "input": "&dotplus;", 
+            "description": "Named entity: dotplus; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2214"
+                ]
+            ]
+        }, 
+        {
+            "input": "&dotsquare", 
+            "description": "Bad named entity: dotsquare without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&dotsquare"
+                ]
+            ]
+        }, 
+        {
+            "input": "&dotsquare;", 
+            "description": "Named entity: dotsquare; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u22a1"
+                ]
+            ]
+        }, 
+        {
+            "input": "&doublebarwedge", 
+            "description": "Bad named entity: doublebarwedge without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&doublebarwedge"
+                ]
+            ]
+        }, 
+        {
+            "input": "&doublebarwedge;", 
+            "description": "Named entity: doublebarwedge; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2306"
+                ]
+            ]
+        }, 
+        {
+            "input": "&downarrow", 
+            "description": "Bad named entity: downarrow without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&downarrow"
+                ]
+            ]
+        }, 
+        {
+            "input": "&downarrow;", 
+            "description": "Named entity: downarrow; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2193"
+                ]
+            ]
+        }, 
+        {
+            "input": "&downdownarrows", 
+            "description": "Bad named entity: downdownarrows without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&downdownarrows"
+                ]
+            ]
+        }, 
+        {
+            "input": "&downdownarrows;", 
+            "description": "Named entity: downdownarrows; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u21ca"
+                ]
+            ]
+        }, 
+        {
+            "input": "&downharpoonleft", 
+            "description": "Bad named entity: downharpoonleft without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&downharpoonleft"
+                ]
+            ]
+        }, 
+        {
+            "input": "&downharpoonleft;", 
+            "description": "Named entity: downharpoonleft; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u21c3"
+                ]
+            ]
+        }, 
+        {
+            "input": "&downharpoonright", 
+            "description": "Bad named entity: downharpoonright without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&downharpoonright"
+                ]
+            ]
+        }, 
+        {
+            "input": "&downharpoonright;", 
+            "description": "Named entity: downharpoonright; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u21c2"
+                ]
+            ]
+        }, 
+        {
+            "input": "&drbkarow", 
+            "description": "Bad named entity: drbkarow without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&drbkarow"
+                ]
+            ]
+        }, 
+        {
+            "input": "&drbkarow;", 
+            "description": "Named entity: drbkarow; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2910"
+                ]
+            ]
+        }, 
+        {
+            "input": "&drcorn", 
+            "description": "Bad named entity: drcorn without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&drcorn"
+                ]
+            ]
+        }, 
+        {
+            "input": "&drcorn;", 
+            "description": "Named entity: drcorn; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u231f"
+                ]
+            ]
+        }, 
+        {
+            "input": "&drcrop", 
+            "description": "Bad named entity: drcrop without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&drcrop"
+                ]
+            ]
+        }, 
+        {
+            "input": "&drcrop;", 
+            "description": "Named entity: drcrop; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u230c"
+                ]
+            ]
+        }, 
+        {
+            "input": "&dscr", 
+            "description": "Bad named entity: dscr without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&dscr"
+                ]
+            ]
+        }, 
+        {
+            "input": "&dscr;", 
+            "description": "Named entity: dscr; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\ud835\udcb9"
+                ]
+            ]
+        }, 
+        {
+            "input": "&dscy", 
+            "description": "Bad named entity: dscy without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&dscy"
+                ]
+            ]
+        }, 
+        {
+            "input": "&dscy;", 
+            "description": "Named entity: dscy; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u0455"
+                ]
+            ]
+        }, 
+        {
+            "input": "&dsol", 
+            "description": "Bad named entity: dsol without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&dsol"
+                ]
+            ]
+        }, 
+        {
+            "input": "&dsol;", 
+            "description": "Named entity: dsol; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u29f6"
+                ]
+            ]
+        }, 
+        {
+            "input": "&dstrok", 
+            "description": "Bad named entity: dstrok without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&dstrok"
+                ]
+            ]
+        }, 
+        {
+            "input": "&dstrok;", 
+            "description": "Named entity: dstrok; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u0111"
+                ]
+            ]
+        }, 
+        {
+            "input": "&dtdot", 
+            "description": "Bad named entity: dtdot without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&dtdot"
+                ]
+            ]
+        }, 
+        {
+            "input": "&dtdot;", 
+            "description": "Named entity: dtdot; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u22f1"
+                ]
+            ]
+        }, 
+        {
+            "input": "&dtri", 
+            "description": "Bad named entity: dtri without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&dtri"
+                ]
+            ]
+        }, 
+        {
+            "input": "&dtri;", 
+            "description": "Named entity: dtri; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u25bf"
+                ]
+            ]
+        }, 
+        {
+            "input": "&dtrif", 
+            "description": "Bad named entity: dtrif without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&dtrif"
+                ]
+            ]
+        }, 
+        {
+            "input": "&dtrif;", 
+            "description": "Named entity: dtrif; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u25be"
+                ]
+            ]
+        }, 
+        {
+            "input": "&duarr", 
+            "description": "Bad named entity: duarr without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&duarr"
+                ]
+            ]
+        }, 
+        {
+            "input": "&duarr;", 
+            "description": "Named entity: duarr; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u21f5"
+                ]
+            ]
+        }, 
+        {
+            "input": "&duhar", 
+            "description": "Bad named entity: duhar without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&duhar"
+                ]
+            ]
+        }, 
+        {
+            "input": "&duhar;", 
+            "description": "Named entity: duhar; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u296f"
+                ]
+            ]
+        }, 
+        {
+            "input": "&dwangle", 
+            "description": "Bad named entity: dwangle without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&dwangle"
+                ]
+            ]
+        }, 
+        {
+            "input": "&dwangle;", 
+            "description": "Named entity: dwangle; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u29a6"
+                ]
+            ]
+        }, 
+        {
+            "input": "&dzcy", 
+            "description": "Bad named entity: dzcy without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&dzcy"
+                ]
+            ]
+        }, 
+        {
+            "input": "&dzcy;", 
+            "description": "Named entity: dzcy; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u045f"
+                ]
+            ]
+        }, 
+        {
+            "input": "&dzigrarr", 
+            "description": "Bad named entity: dzigrarr without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&dzigrarr"
+                ]
+            ]
+        }, 
+        {
+            "input": "&dzigrarr;", 
+            "description": "Named entity: dzigrarr; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u27ff"
+                ]
+            ]
+        }, 
+        {
+            "input": "&eDDot", 
+            "description": "Bad named entity: eDDot without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&eDDot"
+                ]
+            ]
+        }, 
+        {
+            "input": "&eDDot;", 
+            "description": "Named entity: eDDot; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2a77"
+                ]
+            ]
+        }, 
+        {
+            "input": "&eDot", 
+            "description": "Bad named entity: eDot without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&eDot"
+                ]
+            ]
+        }, 
+        {
+            "input": "&eDot;", 
+            "description": "Named entity: eDot; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2251"
+                ]
+            ]
+        }, 
+        {
+            "input": "&eacute", 
+            "description": "Named entity: eacute without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "\u00e9"
+                ]
+            ]
+        }, 
+        {
+            "input": "&eacute;", 
+            "description": "Named entity: eacute; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u00e9"
+                ]
+            ]
+        }, 
+        {
+            "input": "&easter", 
+            "description": "Bad named entity: easter without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&easter"
+                ]
+            ]
+        }, 
+        {
+            "input": "&easter;", 
+            "description": "Named entity: easter; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2a6e"
+                ]
+            ]
+        }, 
+        {
+            "input": "&ecaron", 
+            "description": "Bad named entity: ecaron without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&ecaron"
+                ]
+            ]
+        }, 
+        {
+            "input": "&ecaron;", 
+            "description": "Named entity: ecaron; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u011b"
+                ]
+            ]
+        }, 
+        {
+            "input": "&ecir", 
+            "description": "Bad named entity: ecir without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&ecir"
+                ]
+            ]
+        }, 
+        {
+            "input": "&ecir;", 
+            "description": "Named entity: ecir; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2256"
+                ]
+            ]
+        }, 
+        {
+            "input": "&ecirc", 
+            "description": "Named entity: ecirc without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "\u00ea"
+                ]
+            ]
+        }, 
+        {
+            "input": "&ecirc;", 
+            "description": "Named entity: ecirc; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u00ea"
+                ]
+            ]
+        }, 
+        {
+            "input": "&ecolon", 
+            "description": "Bad named entity: ecolon without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&ecolon"
+                ]
+            ]
+        }, 
+        {
+            "input": "&ecolon;", 
+            "description": "Named entity: ecolon; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2255"
+                ]
+            ]
+        }, 
+        {
+            "input": "&ecy", 
+            "description": "Bad named entity: ecy without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&ecy"
+                ]
+            ]
+        }, 
+        {
+            "input": "&ecy;", 
+            "description": "Named entity: ecy; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u044d"
+                ]
+            ]
+        }, 
+        {
+            "input": "&edot", 
+            "description": "Bad named entity: edot without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&edot"
+                ]
+            ]
+        }, 
+        {
+            "input": "&edot;", 
+            "description": "Named entity: edot; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u0117"
+                ]
+            ]
+        }, 
+        {
+            "input": "&ee", 
+            "description": "Bad named entity: ee without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&ee"
+                ]
+            ]
+        }, 
+        {
+            "input": "&ee;", 
+            "description": "Named entity: ee; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2147"
+                ]
+            ]
+        }, 
+        {
+            "input": "&efDot", 
+            "description": "Bad named entity: efDot without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&efDot"
+                ]
+            ]
+        }, 
+        {
+            "input": "&efDot;", 
+            "description": "Named entity: efDot; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2252"
+                ]
+            ]
+        }, 
+        {
+            "input": "&efr", 
+            "description": "Bad named entity: efr without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&efr"
+                ]
+            ]
+        }, 
+        {
+            "input": "&efr;", 
+            "description": "Named entity: efr; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\ud835\udd22"
+                ]
+            ]
+        }, 
+        {
+            "input": "&eg", 
+            "description": "Bad named entity: eg without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&eg"
+                ]
+            ]
+        }, 
+        {
+            "input": "&eg;", 
+            "description": "Named entity: eg; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2a9a"
+                ]
+            ]
+        }, 
+        {
+            "input": "&egrave", 
+            "description": "Named entity: egrave without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "\u00e8"
+                ]
+            ]
+        }, 
+        {
+            "input": "&egrave;", 
+            "description": "Named entity: egrave; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u00e8"
+                ]
+            ]
+        }, 
+        {
+            "input": "&egs", 
+            "description": "Bad named entity: egs without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&egs"
+                ]
+            ]
+        }, 
+        {
+            "input": "&egs;", 
+            "description": "Named entity: egs; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2a96"
+                ]
+            ]
+        }, 
+        {
+            "input": "&egsdot", 
+            "description": "Bad named entity: egsdot without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&egsdot"
+                ]
+            ]
+        }, 
+        {
+            "input": "&egsdot;", 
+            "description": "Named entity: egsdot; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2a98"
+                ]
+            ]
+        }, 
+        {
+            "input": "&el", 
+            "description": "Bad named entity: el without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&el"
+                ]
+            ]
+        }, 
+        {
+            "input": "&el;", 
+            "description": "Named entity: el; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2a99"
+                ]
+            ]
+        }, 
+        {
+            "input": "&elinters", 
+            "description": "Bad named entity: elinters without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&elinters"
+                ]
+            ]
+        }, 
+        {
+            "input": "&elinters;", 
+            "description": "Named entity: elinters; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u23e7"
+                ]
+            ]
+        }, 
+        {
+            "input": "&ell", 
+            "description": "Bad named entity: ell without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&ell"
+                ]
+            ]
+        }, 
+        {
+            "input": "&ell;", 
+            "description": "Named entity: ell; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2113"
+                ]
+            ]
+        }, 
+        {
+            "input": "&els", 
+            "description": "Bad named entity: els without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&els"
+                ]
+            ]
+        }, 
+        {
+            "input": "&els;", 
+            "description": "Named entity: els; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2a95"
+                ]
+            ]
+        }, 
+        {
+            "input": "&elsdot", 
+            "description": "Bad named entity: elsdot without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&elsdot"
+                ]
+            ]
+        }, 
+        {
+            "input": "&elsdot;", 
+            "description": "Named entity: elsdot; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2a97"
+                ]
+            ]
+        }, 
+        {
+            "input": "&emacr", 
+            "description": "Bad named entity: emacr without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&emacr"
+                ]
+            ]
+        }, 
+        {
+            "input": "&emacr;", 
+            "description": "Named entity: emacr; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u0113"
+                ]
+            ]
+        }, 
+        {
+            "input": "&empty", 
+            "description": "Bad named entity: empty without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&empty"
+                ]
+            ]
+        }, 
+        {
+            "input": "&empty;", 
+            "description": "Named entity: empty; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2205"
+                ]
+            ]
+        }, 
+        {
+            "input": "&emptyset", 
+            "description": "Bad named entity: emptyset without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&emptyset"
+                ]
+            ]
+        }, 
+        {
+            "input": "&emptyset;", 
+            "description": "Named entity: emptyset; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2205"
+                ]
+            ]
+        }, 
+        {
+            "input": "&emptyv", 
+            "description": "Bad named entity: emptyv without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&emptyv"
+                ]
+            ]
+        }, 
+        {
+            "input": "&emptyv;", 
+            "description": "Named entity: emptyv; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2205"
+                ]
+            ]
+        }, 
+        {
+            "input": "&emsp", 
+            "description": "Bad named entity: emsp without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&emsp"
+                ]
+            ]
+        }, 
+        {
+            "input": "&emsp13", 
+            "description": "Bad named entity: emsp13 without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&emsp13"
+                ]
+            ]
+        }, 
+        {
+            "input": "&emsp13;", 
+            "description": "Named entity: emsp13; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2004"
+                ]
+            ]
+        }, 
+        {
+            "input": "&emsp14", 
+            "description": "Bad named entity: emsp14 without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&emsp14"
+                ]
+            ]
+        }, 
+        {
+            "input": "&emsp14;", 
+            "description": "Named entity: emsp14; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2005"
+                ]
+            ]
+        }, 
+        {
+            "input": "&emsp;", 
+            "description": "Named entity: emsp; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2003"
+                ]
+            ]
+        }, 
+        {
+            "input": "&eng", 
+            "description": "Bad named entity: eng without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&eng"
+                ]
+            ]
+        }, 
+        {
+            "input": "&eng;", 
+            "description": "Named entity: eng; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u014b"
+                ]
+            ]
+        }, 
+        {
+            "input": "&ensp", 
+            "description": "Bad named entity: ensp without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&ensp"
+                ]
+            ]
+        }, 
+        {
+            "input": "&ensp;", 
+            "description": "Named entity: ensp; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2002"
+                ]
+            ]
+        }, 
+        {
+            "input": "&eogon", 
+            "description": "Bad named entity: eogon without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&eogon"
+                ]
+            ]
+        }, 
+        {
+            "input": "&eogon;", 
+            "description": "Named entity: eogon; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u0119"
+                ]
+            ]
+        }, 
+        {
+            "input": "&eopf", 
+            "description": "Bad named entity: eopf without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&eopf"
+                ]
+            ]
+        }, 
+        {
+            "input": "&eopf;", 
+            "description": "Named entity: eopf; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\ud835\udd56"
+                ]
+            ]
+        }, 
+        {
+            "input": "&epar", 
+            "description": "Bad named entity: epar without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&epar"
+                ]
+            ]
+        }, 
+        {
+            "input": "&epar;", 
+            "description": "Named entity: epar; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u22d5"
+                ]
+            ]
+        }, 
+        {
+            "input": "&eparsl", 
+            "description": "Bad named entity: eparsl without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&eparsl"
+                ]
+            ]
+        }, 
+        {
+            "input": "&eparsl;", 
+            "description": "Named entity: eparsl; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u29e3"
+                ]
+            ]
+        }, 
+        {
+            "input": "&eplus", 
+            "description": "Bad named entity: eplus without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&eplus"
+                ]
+            ]
+        }, 
+        {
+            "input": "&eplus;", 
+            "description": "Named entity: eplus; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2a71"
+                ]
+            ]
+        }, 
+        {
+            "input": "&epsi", 
+            "description": "Bad named entity: epsi without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&epsi"
+                ]
+            ]
+        }, 
+        {
+            "input": "&epsi;", 
+            "description": "Named entity: epsi; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u03b5"
+                ]
+            ]
+        }, 
+        {
+            "input": "&epsilon", 
+            "description": "Bad named entity: epsilon without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&epsilon"
+                ]
+            ]
+        }, 
+        {
+            "input": "&epsilon;", 
+            "description": "Named entity: epsilon; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u03b5"
+                ]
+            ]
+        }, 
+        {
+            "input": "&epsiv", 
+            "description": "Bad named entity: epsiv without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&epsiv"
+                ]
+            ]
+        }, 
+        {
+            "input": "&epsiv;", 
+            "description": "Named entity: epsiv; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u03f5"
+                ]
+            ]
+        }, 
+        {
+            "input": "&eqcirc", 
+            "description": "Bad named entity: eqcirc without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&eqcirc"
+                ]
+            ]
+        }, 
+        {
+            "input": "&eqcirc;", 
+            "description": "Named entity: eqcirc; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2256"
+                ]
+            ]
+        }, 
+        {
+            "input": "&eqcolon", 
+            "description": "Bad named entity: eqcolon without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&eqcolon"
+                ]
+            ]
+        }, 
+        {
+            "input": "&eqcolon;", 
+            "description": "Named entity: eqcolon; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2255"
+                ]
+            ]
+        }, 
+        {
+            "input": "&eqsim", 
+            "description": "Bad named entity: eqsim without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&eqsim"
+                ]
+            ]
+        }, 
+        {
+            "input": "&eqsim;", 
+            "description": "Named entity: eqsim; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2242"
+                ]
+            ]
+        }, 
+        {
+            "input": "&eqslantgtr", 
+            "description": "Bad named entity: eqslantgtr without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&eqslantgtr"
+                ]
+            ]
+        }, 
+        {
+            "input": "&eqslantgtr;", 
+            "description": "Named entity: eqslantgtr; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2a96"
+                ]
+            ]
+        }, 
+        {
+            "input": "&eqslantless", 
+            "description": "Bad named entity: eqslantless without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&eqslantless"
+                ]
+            ]
+        }, 
+        {
+            "input": "&eqslantless;", 
+            "description": "Named entity: eqslantless; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2a95"
+                ]
+            ]
+        }, 
+        {
+            "input": "&equals", 
+            "description": "Bad named entity: equals without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&equals"
+                ]
+            ]
+        }, 
+        {
+            "input": "&equals;", 
+            "description": "Named entity: equals; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "="
+                ]
+            ]
+        }, 
+        {
+            "input": "&equest", 
+            "description": "Bad named entity: equest without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&equest"
+                ]
+            ]
+        }, 
+        {
+            "input": "&equest;", 
+            "description": "Named entity: equest; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u225f"
+                ]
+            ]
+        }, 
+        {
+            "input": "&equiv", 
+            "description": "Bad named entity: equiv without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&equiv"
+                ]
+            ]
+        }, 
+        {
+            "input": "&equiv;", 
+            "description": "Named entity: equiv; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2261"
+                ]
+            ]
+        }, 
+        {
+            "input": "&equivDD", 
+            "description": "Bad named entity: equivDD without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&equivDD"
+                ]
+            ]
+        }, 
+        {
+            "input": "&equivDD;", 
+            "description": "Named entity: equivDD; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2a78"
+                ]
+            ]
+        }, 
+        {
+            "input": "&eqvparsl", 
+            "description": "Bad named entity: eqvparsl without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&eqvparsl"
+                ]
+            ]
+        }, 
+        {
+            "input": "&eqvparsl;", 
+            "description": "Named entity: eqvparsl; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u29e5"
+                ]
+            ]
+        }, 
+        {
+            "input": "&erDot", 
+            "description": "Bad named entity: erDot without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&erDot"
+                ]
+            ]
+        }, 
+        {
+            "input": "&erDot;", 
+            "description": "Named entity: erDot; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2253"
+                ]
+            ]
+        }, 
+        {
+            "input": "&erarr", 
+            "description": "Bad named entity: erarr without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&erarr"
+                ]
+            ]
+        }, 
+        {
+            "input": "&erarr;", 
+            "description": "Named entity: erarr; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2971"
+                ]
+            ]
+        }, 
+        {
+            "input": "&escr", 
+            "description": "Bad named entity: escr without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&escr"
+                ]
+            ]
+        }, 
+        {
+            "input": "&escr;", 
+            "description": "Named entity: escr; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u212f"
+                ]
+            ]
+        }, 
+        {
+            "input": "&esdot", 
+            "description": "Bad named entity: esdot without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&esdot"
+                ]
+            ]
+        }, 
+        {
+            "input": "&esdot;", 
+            "description": "Named entity: esdot; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2250"
+                ]
+            ]
+        }, 
+        {
+            "input": "&esim", 
+            "description": "Bad named entity: esim without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&esim"
+                ]
+            ]
+        }, 
+        {
+            "input": "&esim;", 
+            "description": "Named entity: esim; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2242"
+                ]
+            ]
+        }, 
+        {
+            "input": "&eta", 
+            "description": "Bad named entity: eta without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&eta"
+                ]
+            ]
+        }, 
+        {
+            "input": "&eta;", 
+            "description": "Named entity: eta; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u03b7"
+                ]
+            ]
+        }, 
+        {
+            "input": "&eth", 
+            "description": "Named entity: eth without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "\u00f0"
+                ]
+            ]
+        }, 
+        {
+            "input": "&eth;", 
+            "description": "Named entity: eth; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u00f0"
+                ]
+            ]
+        }, 
+        {
+            "input": "&euml", 
+            "description": "Named entity: euml without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "\u00eb"
+                ]
+            ]
+        }, 
+        {
+            "input": "&euml;", 
+            "description": "Named entity: euml; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u00eb"
+                ]
+            ]
+        }, 
+        {
+            "input": "&euro", 
+            "description": "Bad named entity: euro without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&euro"
+                ]
+            ]
+        }, 
+        {
+            "input": "&euro;", 
+            "description": "Named entity: euro; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u20ac"
+                ]
+            ]
+        }, 
+        {
+            "input": "&excl", 
+            "description": "Bad named entity: excl without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&excl"
+                ]
+            ]
+        }, 
+        {
+            "input": "&excl;", 
+            "description": "Named entity: excl; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "!"
+                ]
+            ]
+        }, 
+        {
+            "input": "&exist", 
+            "description": "Bad named entity: exist without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&exist"
+                ]
+            ]
+        }, 
+        {
+            "input": "&exist;", 
+            "description": "Named entity: exist; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2203"
+                ]
+            ]
+        }, 
+        {
+            "input": "&expectation", 
+            "description": "Bad named entity: expectation without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&expectation"
+                ]
+            ]
+        }, 
+        {
+            "input": "&expectation;", 
+            "description": "Named entity: expectation; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2130"
+                ]
+            ]
+        }, 
+        {
+            "input": "&exponentiale", 
+            "description": "Bad named entity: exponentiale without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&exponentiale"
+                ]
+            ]
+        }, 
+        {
+            "input": "&exponentiale;", 
+            "description": "Named entity: exponentiale; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2147"
+                ]
+            ]
+        }, 
+        {
+            "input": "&fallingdotseq", 
+            "description": "Bad named entity: fallingdotseq without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&fallingdotseq"
+                ]
+            ]
+        }, 
+        {
+            "input": "&fallingdotseq;", 
+            "description": "Named entity: fallingdotseq; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2252"
+                ]
+            ]
+        }, 
+        {
+            "input": "&fcy", 
+            "description": "Bad named entity: fcy without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&fcy"
+                ]
+            ]
+        }, 
+        {
+            "input": "&fcy;", 
+            "description": "Named entity: fcy; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u0444"
+                ]
+            ]
+        }, 
+        {
+            "input": "&female", 
+            "description": "Bad named entity: female without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&female"
+                ]
+            ]
+        }, 
+        {
+            "input": "&female;", 
+            "description": "Named entity: female; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2640"
+                ]
+            ]
+        }, 
+        {
+            "input": "&ffilig", 
+            "description": "Bad named entity: ffilig without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&ffilig"
+                ]
+            ]
+        }, 
+        {
+            "input": "&ffilig;", 
+            "description": "Named entity: ffilig; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\ufb03"
+                ]
+            ]
+        }, 
+        {
+            "input": "&fflig", 
+            "description": "Bad named entity: fflig without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&fflig"
+                ]
+            ]
+        }, 
+        {
+            "input": "&fflig;", 
+            "description": "Named entity: fflig; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\ufb00"
+                ]
+            ]
+        }, 
+        {
+            "input": "&ffllig", 
+            "description": "Bad named entity: ffllig without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&ffllig"
+                ]
+            ]
+        }, 
+        {
+            "input": "&ffllig;", 
+            "description": "Named entity: ffllig; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\ufb04"
+                ]
+            ]
+        }, 
+        {
+            "input": "&ffr", 
+            "description": "Bad named entity: ffr without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&ffr"
+                ]
+            ]
+        }, 
+        {
+            "input": "&ffr;", 
+            "description": "Named entity: ffr; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\ud835\udd23"
+                ]
+            ]
+        }, 
+        {
+            "input": "&filig", 
+            "description": "Bad named entity: filig without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&filig"
+                ]
+            ]
+        }, 
+        {
+            "input": "&filig;", 
+            "description": "Named entity: filig; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\ufb01"
+                ]
+            ]
+        }, 
+        {
+            "input": "&fjlig", 
+            "description": "Bad named entity: fjlig without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&fjlig"
+                ]
+            ]
+        }, 
+        {
+            "input": "&fjlig;", 
+            "description": "Named entity: fjlig; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "fj"
+                ]
+            ]
+        }, 
+        {
+            "input": "&flat", 
+            "description": "Bad named entity: flat without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&flat"
+                ]
+            ]
+        }, 
+        {
+            "input": "&flat;", 
+            "description": "Named entity: flat; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u266d"
+                ]
+            ]
+        }, 
+        {
+            "input": "&fllig", 
+            "description": "Bad named entity: fllig without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&fllig"
+                ]
+            ]
+        }, 
+        {
+            "input": "&fllig;", 
+            "description": "Named entity: fllig; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\ufb02"
+                ]
+            ]
+        }, 
+        {
+            "input": "&fltns", 
+            "description": "Bad named entity: fltns without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&fltns"
+                ]
+            ]
+        }, 
+        {
+            "input": "&fltns;", 
+            "description": "Named entity: fltns; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u25b1"
+                ]
+            ]
+        }, 
+        {
+            "input": "&fnof", 
+            "description": "Bad named entity: fnof without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&fnof"
+                ]
+            ]
+        }, 
+        {
+            "input": "&fnof;", 
+            "description": "Named entity: fnof; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u0192"
+                ]
+            ]
+        }, 
+        {
+            "input": "&fopf", 
+            "description": "Bad named entity: fopf without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&fopf"
+                ]
+            ]
+        }, 
+        {
+            "input": "&fopf;", 
+            "description": "Named entity: fopf; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\ud835\udd57"
+                ]
+            ]
+        }, 
+        {
+            "input": "&forall", 
+            "description": "Bad named entity: forall without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&forall"
+                ]
+            ]
+        }, 
+        {
+            "input": "&forall;", 
+            "description": "Named entity: forall; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2200"
+                ]
+            ]
+        }, 
+        {
+            "input": "&fork", 
+            "description": "Bad named entity: fork without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&fork"
+                ]
+            ]
+        }, 
+        {
+            "input": "&fork;", 
+            "description": "Named entity: fork; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u22d4"
+                ]
+            ]
+        }, 
+        {
+            "input": "&forkv", 
+            "description": "Bad named entity: forkv without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&forkv"
+                ]
+            ]
+        }, 
+        {
+            "input": "&forkv;", 
+            "description": "Named entity: forkv; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2ad9"
+                ]
+            ]
+        }, 
+        {
+            "input": "&fpartint", 
+            "description": "Bad named entity: fpartint without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&fpartint"
+                ]
+            ]
+        }, 
+        {
+            "input": "&fpartint;", 
+            "description": "Named entity: fpartint; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2a0d"
+                ]
+            ]
+        }, 
+        {
+            "input": "&frac12", 
+            "description": "Named entity: frac12 without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "\u00bd"
+                ]
+            ]
+        }, 
+        {
+            "input": "&frac12;", 
+            "description": "Named entity: frac12; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u00bd"
+                ]
+            ]
+        }, 
+        {
+            "input": "&frac13", 
+            "description": "Bad named entity: frac13 without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&frac13"
+                ]
+            ]
+        }, 
+        {
+            "input": "&frac13;", 
+            "description": "Named entity: frac13; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2153"
+                ]
+            ]
+        }, 
+        {
+            "input": "&frac14", 
+            "description": "Named entity: frac14 without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "\u00bc"
+                ]
+            ]
+        }, 
+        {
+            "input": "&frac14;", 
+            "description": "Named entity: frac14; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u00bc"
+                ]
+            ]
+        }, 
+        {
+            "input": "&frac15", 
+            "description": "Bad named entity: frac15 without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&frac15"
+                ]
+            ]
+        }, 
+        {
+            "input": "&frac15;", 
+            "description": "Named entity: frac15; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2155"
+                ]
+            ]
+        }, 
+        {
+            "input": "&frac16", 
+            "description": "Bad named entity: frac16 without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&frac16"
+                ]
+            ]
+        }, 
+        {
+            "input": "&frac16;", 
+            "description": "Named entity: frac16; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2159"
+                ]
+            ]
+        }, 
+        {
+            "input": "&frac18", 
+            "description": "Bad named entity: frac18 without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&frac18"
+                ]
+            ]
+        }, 
+        {
+            "input": "&frac18;", 
+            "description": "Named entity: frac18; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u215b"
+                ]
+            ]
+        }, 
+        {
+            "input": "&frac23", 
+            "description": "Bad named entity: frac23 without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&frac23"
+                ]
+            ]
+        }, 
+        {
+            "input": "&frac23;", 
+            "description": "Named entity: frac23; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2154"
+                ]
+            ]
+        }, 
+        {
+            "input": "&frac25", 
+            "description": "Bad named entity: frac25 without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&frac25"
+                ]
+            ]
+        }, 
+        {
+            "input": "&frac25;", 
+            "description": "Named entity: frac25; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2156"
+                ]
+            ]
+        }, 
+        {
+            "input": "&frac34", 
+            "description": "Named entity: frac34 without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "\u00be"
+                ]
+            ]
+        }, 
+        {
+            "input": "&frac34;", 
+            "description": "Named entity: frac34; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u00be"
+                ]
+            ]
+        }, 
+        {
+            "input": "&frac35", 
+            "description": "Bad named entity: frac35 without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&frac35"
+                ]
+            ]
+        }, 
+        {
+            "input": "&frac35;", 
+            "description": "Named entity: frac35; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2157"
+                ]
+            ]
+        }, 
+        {
+            "input": "&frac38", 
+            "description": "Bad named entity: frac38 without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&frac38"
+                ]
+            ]
+        }, 
+        {
+            "input": "&frac38;", 
+            "description": "Named entity: frac38; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u215c"
+                ]
+            ]
+        }, 
+        {
+            "input": "&frac45", 
+            "description": "Bad named entity: frac45 without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&frac45"
+                ]
+            ]
+        }, 
+        {
+            "input": "&frac45;", 
+            "description": "Named entity: frac45; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2158"
+                ]
+            ]
+        }, 
+        {
+            "input": "&frac56", 
+            "description": "Bad named entity: frac56 without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&frac56"
+                ]
+            ]
+        }, 
+        {
+            "input": "&frac56;", 
+            "description": "Named entity: frac56; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u215a"
+                ]
+            ]
+        }, 
+        {
+            "input": "&frac58", 
+            "description": "Bad named entity: frac58 without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&frac58"
+                ]
+            ]
+        }, 
+        {
+            "input": "&frac58;", 
+            "description": "Named entity: frac58; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u215d"
+                ]
+            ]
+        }, 
+        {
+            "input": "&frac78", 
+            "description": "Bad named entity: frac78 without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&frac78"
+                ]
+            ]
+        }, 
+        {
+            "input": "&frac78;", 
+            "description": "Named entity: frac78; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u215e"
+                ]
+            ]
+        }, 
+        {
+            "input": "&frasl", 
+            "description": "Bad named entity: frasl without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&frasl"
+                ]
+            ]
+        }, 
+        {
+            "input": "&frasl;", 
+            "description": "Named entity: frasl; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2044"
+                ]
+            ]
+        }, 
+        {
+            "input": "&frown", 
+            "description": "Bad named entity: frown without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&frown"
+                ]
+            ]
+        }, 
+        {
+            "input": "&frown;", 
+            "description": "Named entity: frown; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2322"
+                ]
+            ]
+        }, 
+        {
+            "input": "&fscr", 
+            "description": "Bad named entity: fscr without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&fscr"
+                ]
+            ]
+        }, 
+        {
+            "input": "&fscr;", 
+            "description": "Named entity: fscr; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\ud835\udcbb"
+                ]
+            ]
+        }, 
+        {
+            "input": "&gE", 
+            "description": "Bad named entity: gE without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&gE"
+                ]
+            ]
+        }, 
+        {
+            "input": "&gE;", 
+            "description": "Named entity: gE; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2267"
+                ]
+            ]
+        }, 
+        {
+            "input": "&gEl", 
+            "description": "Bad named entity: gEl without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&gEl"
+                ]
+            ]
+        }, 
+        {
+            "input": "&gEl;", 
+            "description": "Named entity: gEl; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2a8c"
+                ]
+            ]
+        }, 
+        {
+            "input": "&gacute", 
+            "description": "Bad named entity: gacute without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&gacute"
+                ]
+            ]
+        }, 
+        {
+            "input": "&gacute;", 
+            "description": "Named entity: gacute; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u01f5"
+                ]
+            ]
+        }, 
+        {
+            "input": "&gamma", 
+            "description": "Bad named entity: gamma without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&gamma"
+                ]
+            ]
+        }, 
+        {
+            "input": "&gamma;", 
+            "description": "Named entity: gamma; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u03b3"
+                ]
+            ]
+        }, 
+        {
+            "input": "&gammad", 
+            "description": "Bad named entity: gammad without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&gammad"
+                ]
+            ]
+        }, 
+        {
+            "input": "&gammad;", 
+            "description": "Named entity: gammad; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u03dd"
+                ]
+            ]
+        }, 
+        {
+            "input": "&gap", 
+            "description": "Bad named entity: gap without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&gap"
+                ]
+            ]
+        }, 
+        {
+            "input": "&gap;", 
+            "description": "Named entity: gap; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2a86"
+                ]
+            ]
+        }, 
+        {
+            "input": "&gbreve", 
+            "description": "Bad named entity: gbreve without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&gbreve"
+                ]
+            ]
+        }, 
+        {
+            "input": "&gbreve;", 
+            "description": "Named entity: gbreve; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u011f"
+                ]
+            ]
+        }, 
+        {
+            "input": "&gcirc", 
+            "description": "Bad named entity: gcirc without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&gcirc"
+                ]
+            ]
+        }, 
+        {
+            "input": "&gcirc;", 
+            "description": "Named entity: gcirc; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u011d"
+                ]
+            ]
+        }, 
+        {
+            "input": "&gcy", 
+            "description": "Bad named entity: gcy without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&gcy"
+                ]
+            ]
+        }, 
+        {
+            "input": "&gcy;", 
+            "description": "Named entity: gcy; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u0433"
+                ]
+            ]
+        }, 
+        {
+            "input": "&gdot", 
+            "description": "Bad named entity: gdot without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&gdot"
+                ]
+            ]
+        }, 
+        {
+            "input": "&gdot;", 
+            "description": "Named entity: gdot; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u0121"
+                ]
+            ]
+        }, 
+        {
+            "input": "&ge", 
+            "description": "Bad named entity: ge without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&ge"
+                ]
+            ]
+        }, 
+        {
+            "input": "&ge;", 
+            "description": "Named entity: ge; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2265"
+                ]
+            ]
+        }, 
+        {
+            "input": "&gel", 
+            "description": "Bad named entity: gel without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&gel"
+                ]
+            ]
+        }, 
+        {
+            "input": "&gel;", 
+            "description": "Named entity: gel; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u22db"
+                ]
+            ]
+        }, 
+        {
+            "input": "&geq", 
+            "description": "Bad named entity: geq without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&geq"
+                ]
+            ]
+        }, 
+        {
+            "input": "&geq;", 
+            "description": "Named entity: geq; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2265"
+                ]
+            ]
+        }, 
+        {
+            "input": "&geqq", 
+            "description": "Bad named entity: geqq without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&geqq"
+                ]
+            ]
+        }, 
+        {
+            "input": "&geqq;", 
+            "description": "Named entity: geqq; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2267"
+                ]
+            ]
+        }, 
+        {
+            "input": "&geqslant", 
+            "description": "Bad named entity: geqslant without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&geqslant"
+                ]
+            ]
+        }, 
+        {
+            "input": "&geqslant;", 
+            "description": "Named entity: geqslant; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2a7e"
+                ]
+            ]
+        }, 
+        {
+            "input": "&ges", 
+            "description": "Bad named entity: ges without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&ges"
+                ]
+            ]
+        }, 
+        {
+            "input": "&ges;", 
+            "description": "Named entity: ges; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2a7e"
+                ]
+            ]
+        }, 
+        {
+            "input": "&gescc", 
+            "description": "Bad named entity: gescc without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&gescc"
+                ]
+            ]
+        }, 
+        {
+            "input": "&gescc;", 
+            "description": "Named entity: gescc; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2aa9"
+                ]
+            ]
+        }, 
+        {
+            "input": "&gesdot", 
+            "description": "Bad named entity: gesdot without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&gesdot"
+                ]
+            ]
+        }, 
+        {
+            "input": "&gesdot;", 
+            "description": "Named entity: gesdot; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2a80"
+                ]
+            ]
+        }, 
+        {
+            "input": "&gesdoto", 
+            "description": "Bad named entity: gesdoto without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&gesdoto"
+                ]
+            ]
+        }, 
+        {
+            "input": "&gesdoto;", 
+            "description": "Named entity: gesdoto; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2a82"
+                ]
+            ]
+        }, 
+        {
+            "input": "&gesdotol", 
+            "description": "Bad named entity: gesdotol without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&gesdotol"
+                ]
+            ]
+        }, 
+        {
+            "input": "&gesdotol;", 
+            "description": "Named entity: gesdotol; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2a84"
+                ]
+            ]
+        }, 
+        {
+            "input": "&gesl", 
+            "description": "Bad named entity: gesl without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&gesl"
+                ]
+            ]
+        }, 
+        {
+            "input": "&gesl;", 
+            "description": "Named entity: gesl; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u22db\ufe00"
+                ]
+            ]
+        }, 
+        {
+            "input": "&gesles", 
+            "description": "Bad named entity: gesles without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&gesles"
+                ]
+            ]
+        }, 
+        {
+            "input": "&gesles;", 
+            "description": "Named entity: gesles; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2a94"
+                ]
+            ]
+        }, 
+        {
+            "input": "&gfr", 
+            "description": "Bad named entity: gfr without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&gfr"
+                ]
+            ]
+        }, 
+        {
+            "input": "&gfr;", 
+            "description": "Named entity: gfr; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\ud835\udd24"
+                ]
+            ]
+        }, 
+        {
+            "input": "&gg", 
+            "description": "Bad named entity: gg without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&gg"
+                ]
+            ]
+        }, 
+        {
+            "input": "&gg;", 
+            "description": "Named entity: gg; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u226b"
+                ]
+            ]
+        }, 
+        {
+            "input": "&ggg", 
+            "description": "Bad named entity: ggg without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&ggg"
+                ]
+            ]
+        }, 
+        {
+            "input": "&ggg;", 
+            "description": "Named entity: ggg; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u22d9"
+                ]
+            ]
+        }, 
+        {
+            "input": "&gimel", 
+            "description": "Bad named entity: gimel without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&gimel"
+                ]
+            ]
+        }, 
+        {
+            "input": "&gimel;", 
+            "description": "Named entity: gimel; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2137"
+                ]
+            ]
+        }, 
+        {
+            "input": "&gjcy", 
+            "description": "Bad named entity: gjcy without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&gjcy"
+                ]
+            ]
+        }, 
+        {
+            "input": "&gjcy;", 
+            "description": "Named entity: gjcy; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u0453"
+                ]
+            ]
+        }, 
+        {
+            "input": "&gl", 
+            "description": "Bad named entity: gl without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&gl"
+                ]
+            ]
+        }, 
+        {
+            "input": "&gl;", 
+            "description": "Named entity: gl; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2277"
+                ]
+            ]
+        }, 
+        {
+            "input": "&glE", 
+            "description": "Bad named entity: glE without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&glE"
+                ]
+            ]
+        }, 
+        {
+            "input": "&glE;", 
+            "description": "Named entity: glE; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2a92"
+                ]
+            ]
+        }, 
+        {
+            "input": "&gla", 
+            "description": "Bad named entity: gla without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&gla"
+                ]
+            ]
+        }, 
+        {
+            "input": "&gla;", 
+            "description": "Named entity: gla; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2aa5"
+                ]
+            ]
+        }, 
+        {
+            "input": "&glj", 
+            "description": "Bad named entity: glj without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&glj"
+                ]
+            ]
+        }, 
+        {
+            "input": "&glj;", 
+            "description": "Named entity: glj; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2aa4"
+                ]
+            ]
+        }, 
+        {
+            "input": "&gnE", 
+            "description": "Bad named entity: gnE without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&gnE"
+                ]
+            ]
+        }, 
+        {
+            "input": "&gnE;", 
+            "description": "Named entity: gnE; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2269"
+                ]
+            ]
+        }, 
+        {
+            "input": "&gnap", 
+            "description": "Bad named entity: gnap without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&gnap"
+                ]
+            ]
+        }, 
+        {
+            "input": "&gnap;", 
+            "description": "Named entity: gnap; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2a8a"
+                ]
+            ]
+        }, 
+        {
+            "input": "&gnapprox", 
+            "description": "Bad named entity: gnapprox without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&gnapprox"
+                ]
+            ]
+        }, 
+        {
+            "input": "&gnapprox;", 
+            "description": "Named entity: gnapprox; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2a8a"
+                ]
+            ]
+        }, 
+        {
+            "input": "&gne", 
+            "description": "Bad named entity: gne without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&gne"
+                ]
+            ]
+        }, 
+        {
+            "input": "&gne;", 
+            "description": "Named entity: gne; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2a88"
+                ]
+            ]
+        }, 
+        {
+            "input": "&gneq", 
+            "description": "Bad named entity: gneq without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&gneq"
+                ]
+            ]
+        }, 
+        {
+            "input": "&gneq;", 
+            "description": "Named entity: gneq; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2a88"
+                ]
+            ]
+        }, 
+        {
+            "input": "&gneqq", 
+            "description": "Bad named entity: gneqq without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&gneqq"
+                ]
+            ]
+        }, 
+        {
+            "input": "&gneqq;", 
+            "description": "Named entity: gneqq; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2269"
+                ]
+            ]
+        }, 
+        {
+            "input": "&gnsim", 
+            "description": "Bad named entity: gnsim without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&gnsim"
+                ]
+            ]
+        }, 
+        {
+            "input": "&gnsim;", 
+            "description": "Named entity: gnsim; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u22e7"
+                ]
+            ]
+        }, 
+        {
+            "input": "&gopf", 
+            "description": "Bad named entity: gopf without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&gopf"
+                ]
+            ]
+        }, 
+        {
+            "input": "&gopf;", 
+            "description": "Named entity: gopf; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\ud835\udd58"
+                ]
+            ]
+        }, 
+        {
+            "input": "&grave", 
+            "description": "Bad named entity: grave without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&grave"
+                ]
+            ]
+        }, 
+        {
+            "input": "&grave;", 
+            "description": "Named entity: grave; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "`"
+                ]
+            ]
+        }, 
+        {
+            "input": "&gscr", 
+            "description": "Bad named entity: gscr without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&gscr"
+                ]
+            ]
+        }, 
+        {
+            "input": "&gscr;", 
+            "description": "Named entity: gscr; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u210a"
+                ]
+            ]
+        }, 
+        {
+            "input": "&gsim", 
+            "description": "Bad named entity: gsim without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&gsim"
+                ]
+            ]
+        }, 
+        {
+            "input": "&gsim;", 
+            "description": "Named entity: gsim; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2273"
+                ]
+            ]
+        }, 
+        {
+            "input": "&gsime", 
+            "description": "Bad named entity: gsime without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&gsime"
+                ]
+            ]
+        }, 
+        {
+            "input": "&gsime;", 
+            "description": "Named entity: gsime; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2a8e"
+                ]
+            ]
+        }, 
+        {
+            "input": "&gsiml", 
+            "description": "Bad named entity: gsiml without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&gsiml"
+                ]
+            ]
+        }, 
+        {
+            "input": "&gsiml;", 
+            "description": "Named entity: gsiml; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2a90"
+                ]
+            ]
+        }, 
+        {
+            "input": "&gt", 
+            "description": "Named entity: gt without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    ">"
+                ]
+            ]
+        }, 
+        {
+            "input": "&gt;", 
+            "description": "Named entity: gt; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    ">"
+                ]
+            ]
+        }, 
+        {
+            "input": "&gtcc;", 
+            "description": "Named entity: gtcc; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2aa7"
+                ]
+            ]
+        }, 
+        {
+            "input": "&gtcir;", 
+            "description": "Named entity: gtcir; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2a7a"
+                ]
+            ]
+        }, 
+        {
+            "input": "&gtdot;", 
+            "description": "Named entity: gtdot; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u22d7"
+                ]
+            ]
+        }, 
+        {
+            "input": "&gtlPar;", 
+            "description": "Named entity: gtlPar; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2995"
+                ]
+            ]
+        }, 
+        {
+            "input": "&gtquest;", 
+            "description": "Named entity: gtquest; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2a7c"
+                ]
+            ]
+        }, 
+        {
+            "input": "&gtrapprox;", 
+            "description": "Named entity: gtrapprox; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2a86"
+                ]
+            ]
+        }, 
+        {
+            "input": "&gtrarr;", 
+            "description": "Named entity: gtrarr; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2978"
+                ]
+            ]
+        }, 
+        {
+            "input": "&gtrdot;", 
+            "description": "Named entity: gtrdot; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u22d7"
+                ]
+            ]
+        }, 
+        {
+            "input": "&gtreqless;", 
+            "description": "Named entity: gtreqless; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u22db"
+                ]
+            ]
+        }, 
+        {
+            "input": "&gtreqqless;", 
+            "description": "Named entity: gtreqqless; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2a8c"
+                ]
+            ]
+        }, 
+        {
+            "input": "&gtrless;", 
+            "description": "Named entity: gtrless; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2277"
+                ]
+            ]
+        }, 
+        {
+            "input": "&gtrsim;", 
+            "description": "Named entity: gtrsim; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2273"
+                ]
+            ]
+        }, 
+        {
+            "input": "&gvertneqq", 
+            "description": "Bad named entity: gvertneqq without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&gvertneqq"
+                ]
+            ]
+        }, 
+        {
+            "input": "&gvertneqq;", 
+            "description": "Named entity: gvertneqq; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2269\ufe00"
+                ]
+            ]
+        }, 
+        {
+            "input": "&gvnE", 
+            "description": "Bad named entity: gvnE without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&gvnE"
+                ]
+            ]
+        }, 
+        {
+            "input": "&gvnE;", 
+            "description": "Named entity: gvnE; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2269\ufe00"
+                ]
+            ]
+        }, 
+        {
+            "input": "&hArr", 
+            "description": "Bad named entity: hArr without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&hArr"
+                ]
+            ]
+        }, 
+        {
+            "input": "&hArr;", 
+            "description": "Named entity: hArr; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u21d4"
+                ]
+            ]
+        }, 
+        {
+            "input": "&hairsp", 
+            "description": "Bad named entity: hairsp without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&hairsp"
+                ]
+            ]
+        }, 
+        {
+            "input": "&hairsp;", 
+            "description": "Named entity: hairsp; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u200a"
+                ]
+            ]
+        }, 
+        {
+            "input": "&half", 
+            "description": "Bad named entity: half without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&half"
+                ]
+            ]
+        }, 
+        {
+            "input": "&half;", 
+            "description": "Named entity: half; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u00bd"
+                ]
+            ]
+        }, 
+        {
+            "input": "&hamilt", 
+            "description": "Bad named entity: hamilt without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&hamilt"
+                ]
+            ]
+        }, 
+        {
+            "input": "&hamilt;", 
+            "description": "Named entity: hamilt; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u210b"
+                ]
+            ]
+        }, 
+        {
+            "input": "&hardcy", 
+            "description": "Bad named entity: hardcy without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&hardcy"
+                ]
+            ]
+        }, 
+        {
+            "input": "&hardcy;", 
+            "description": "Named entity: hardcy; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u044a"
+                ]
+            ]
+        }, 
+        {
+            "input": "&harr", 
+            "description": "Bad named entity: harr without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&harr"
+                ]
+            ]
+        }, 
+        {
+            "input": "&harr;", 
+            "description": "Named entity: harr; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2194"
+                ]
+            ]
+        }, 
+        {
+            "input": "&harrcir", 
+            "description": "Bad named entity: harrcir without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&harrcir"
+                ]
+            ]
+        }, 
+        {
+            "input": "&harrcir;", 
+            "description": "Named entity: harrcir; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2948"
+                ]
+            ]
+        }, 
+        {
+            "input": "&harrw", 
+            "description": "Bad named entity: harrw without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&harrw"
+                ]
+            ]
+        }, 
+        {
+            "input": "&harrw;", 
+            "description": "Named entity: harrw; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u21ad"
+                ]
+            ]
+        }, 
+        {
+            "input": "&hbar", 
+            "description": "Bad named entity: hbar without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&hbar"
+                ]
+            ]
+        }, 
+        {
+            "input": "&hbar;", 
+            "description": "Named entity: hbar; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u210f"
+                ]
+            ]
+        }, 
+        {
+            "input": "&hcirc", 
+            "description": "Bad named entity: hcirc without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&hcirc"
+                ]
+            ]
+        }, 
+        {
+            "input": "&hcirc;", 
+            "description": "Named entity: hcirc; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u0125"
+                ]
+            ]
+        }, 
+        {
+            "input": "&hearts", 
+            "description": "Bad named entity: hearts without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&hearts"
+                ]
+            ]
+        }, 
+        {
+            "input": "&hearts;", 
+            "description": "Named entity: hearts; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2665"
+                ]
+            ]
+        }, 
+        {
+            "input": "&heartsuit", 
+            "description": "Bad named entity: heartsuit without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&heartsuit"
+                ]
+            ]
+        }, 
+        {
+            "input": "&heartsuit;", 
+            "description": "Named entity: heartsuit; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2665"
+                ]
+            ]
+        }, 
+        {
+            "input": "&hellip", 
+            "description": "Bad named entity: hellip without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&hellip"
+                ]
+            ]
+        }, 
+        {
+            "input": "&hellip;", 
+            "description": "Named entity: hellip; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2026"
+                ]
+            ]
+        }, 
+        {
+            "input": "&hercon", 
+            "description": "Bad named entity: hercon without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&hercon"
+                ]
+            ]
+        }, 
+        {
+            "input": "&hercon;", 
+            "description": "Named entity: hercon; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u22b9"
+                ]
+            ]
+        }, 
+        {
+            "input": "&hfr", 
+            "description": "Bad named entity: hfr without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&hfr"
+                ]
+            ]
+        }, 
+        {
+            "input": "&hfr;", 
+            "description": "Named entity: hfr; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\ud835\udd25"
+                ]
+            ]
+        }, 
+        {
+            "input": "&hksearow", 
+            "description": "Bad named entity: hksearow without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&hksearow"
+                ]
+            ]
+        }, 
+        {
+            "input": "&hksearow;", 
+            "description": "Named entity: hksearow; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2925"
+                ]
+            ]
+        }, 
+        {
+            "input": "&hkswarow", 
+            "description": "Bad named entity: hkswarow without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&hkswarow"
+                ]
+            ]
+        }, 
+        {
+            "input": "&hkswarow;", 
+            "description": "Named entity: hkswarow; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2926"
+                ]
+            ]
+        }, 
+        {
+            "input": "&hoarr", 
+            "description": "Bad named entity: hoarr without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&hoarr"
+                ]
+            ]
+        }, 
+        {
+            "input": "&hoarr;", 
+            "description": "Named entity: hoarr; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u21ff"
+                ]
+            ]
+        }, 
+        {
+            "input": "&homtht", 
+            "description": "Bad named entity: homtht without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&homtht"
+                ]
+            ]
+        }, 
+        {
+            "input": "&homtht;", 
+            "description": "Named entity: homtht; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u223b"
+                ]
+            ]
+        }, 
+        {
+            "input": "&hookleftarrow", 
+            "description": "Bad named entity: hookleftarrow without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&hookleftarrow"
+                ]
+            ]
+        }, 
+        {
+            "input": "&hookleftarrow;", 
+            "description": "Named entity: hookleftarrow; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u21a9"
+                ]
+            ]
+        }, 
+        {
+            "input": "&hookrightarrow", 
+            "description": "Bad named entity: hookrightarrow without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&hookrightarrow"
+                ]
+            ]
+        }, 
+        {
+            "input": "&hookrightarrow;", 
+            "description": "Named entity: hookrightarrow; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u21aa"
+                ]
+            ]
+        }, 
+        {
+            "input": "&hopf", 
+            "description": "Bad named entity: hopf without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&hopf"
+                ]
+            ]
+        }, 
+        {
+            "input": "&hopf;", 
+            "description": "Named entity: hopf; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\ud835\udd59"
+                ]
+            ]
+        }, 
+        {
+            "input": "&horbar", 
+            "description": "Bad named entity: horbar without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&horbar"
+                ]
+            ]
+        }, 
+        {
+            "input": "&horbar;", 
+            "description": "Named entity: horbar; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2015"
+                ]
+            ]
+        }, 
+        {
+            "input": "&hscr", 
+            "description": "Bad named entity: hscr without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&hscr"
+                ]
+            ]
+        }, 
+        {
+            "input": "&hscr;", 
+            "description": "Named entity: hscr; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\ud835\udcbd"
+                ]
+            ]
+        }, 
+        {
+            "input": "&hslash", 
+            "description": "Bad named entity: hslash without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&hslash"
+                ]
+            ]
+        }, 
+        {
+            "input": "&hslash;", 
+            "description": "Named entity: hslash; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u210f"
+                ]
+            ]
+        }, 
+        {
+            "input": "&hstrok", 
+            "description": "Bad named entity: hstrok without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&hstrok"
+                ]
+            ]
+        }, 
+        {
+            "input": "&hstrok;", 
+            "description": "Named entity: hstrok; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u0127"
+                ]
+            ]
+        }, 
+        {
+            "input": "&hybull", 
+            "description": "Bad named entity: hybull without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&hybull"
+                ]
+            ]
+        }, 
+        {
+            "input": "&hybull;", 
+            "description": "Named entity: hybull; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2043"
+                ]
+            ]
+        }, 
+        {
+            "input": "&hyphen", 
+            "description": "Bad named entity: hyphen without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&hyphen"
+                ]
+            ]
+        }, 
+        {
+            "input": "&hyphen;", 
+            "description": "Named entity: hyphen; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2010"
+                ]
+            ]
+        }, 
+        {
+            "input": "&iacute", 
+            "description": "Named entity: iacute without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "\u00ed"
+                ]
+            ]
+        }, 
+        {
+            "input": "&iacute;", 
+            "description": "Named entity: iacute; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u00ed"
+                ]
+            ]
+        }, 
+        {
+            "input": "&ic", 
+            "description": "Bad named entity: ic without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&ic"
+                ]
+            ]
+        }, 
+        {
+            "input": "&ic;", 
+            "description": "Named entity: ic; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2063"
+                ]
+            ]
+        }, 
+        {
+            "input": "&icirc", 
+            "description": "Named entity: icirc without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "\u00ee"
+                ]
+            ]
+        }, 
+        {
+            "input": "&icirc;", 
+            "description": "Named entity: icirc; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u00ee"
+                ]
+            ]
+        }, 
+        {
+            "input": "&icy", 
+            "description": "Bad named entity: icy without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&icy"
+                ]
+            ]
+        }, 
+        {
+            "input": "&icy;", 
+            "description": "Named entity: icy; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u0438"
+                ]
+            ]
+        }, 
+        {
+            "input": "&iecy", 
+            "description": "Bad named entity: iecy without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&iecy"
+                ]
+            ]
+        }, 
+        {
+            "input": "&iecy;", 
+            "description": "Named entity: iecy; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u0435"
+                ]
+            ]
+        }, 
+        {
+            "input": "&iexcl", 
+            "description": "Named entity: iexcl without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "\u00a1"
+                ]
+            ]
+        }, 
+        {
+            "input": "&iexcl;", 
+            "description": "Named entity: iexcl; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u00a1"
+                ]
+            ]
+        }, 
+        {
+            "input": "&iff", 
+            "description": "Bad named entity: iff without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&iff"
+                ]
+            ]
+        }, 
+        {
+            "input": "&iff;", 
+            "description": "Named entity: iff; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u21d4"
+                ]
+            ]
+        }, 
+        {
+            "input": "&ifr", 
+            "description": "Bad named entity: ifr without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&ifr"
+                ]
+            ]
+        }, 
+        {
+            "input": "&ifr;", 
+            "description": "Named entity: ifr; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\ud835\udd26"
+                ]
+            ]
+        }, 
+        {
+            "input": "&igrave", 
+            "description": "Named entity: igrave without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "\u00ec"
+                ]
+            ]
+        }, 
+        {
+            "input": "&igrave;", 
+            "description": "Named entity: igrave; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u00ec"
+                ]
+            ]
+        }, 
+        {
+            "input": "&ii", 
+            "description": "Bad named entity: ii without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&ii"
+                ]
+            ]
+        }, 
+        {
+            "input": "&ii;", 
+            "description": "Named entity: ii; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2148"
+                ]
+            ]
+        }, 
+        {
+            "input": "&iiiint", 
+            "description": "Bad named entity: iiiint without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&iiiint"
+                ]
+            ]
+        }, 
+        {
+            "input": "&iiiint;", 
+            "description": "Named entity: iiiint; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2a0c"
+                ]
+            ]
+        }, 
+        {
+            "input": "&iiint", 
+            "description": "Bad named entity: iiint without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&iiint"
+                ]
+            ]
+        }, 
+        {
+            "input": "&iiint;", 
+            "description": "Named entity: iiint; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u222d"
+                ]
+            ]
+        }, 
+        {
+            "input": "&iinfin", 
+            "description": "Bad named entity: iinfin without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&iinfin"
+                ]
+            ]
+        }, 
+        {
+            "input": "&iinfin;", 
+            "description": "Named entity: iinfin; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u29dc"
+                ]
+            ]
+        }, 
+        {
+            "input": "&iiota", 
+            "description": "Bad named entity: iiota without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&iiota"
+                ]
+            ]
+        }, 
+        {
+            "input": "&iiota;", 
+            "description": "Named entity: iiota; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2129"
+                ]
+            ]
+        }, 
+        {
+            "input": "&ijlig", 
+            "description": "Bad named entity: ijlig without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&ijlig"
+                ]
+            ]
+        }, 
+        {
+            "input": "&ijlig;", 
+            "description": "Named entity: ijlig; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u0133"
+                ]
+            ]
+        }, 
+        {
+            "input": "&imacr", 
+            "description": "Bad named entity: imacr without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&imacr"
+                ]
+            ]
+        }, 
+        {
+            "input": "&imacr;", 
+            "description": "Named entity: imacr; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u012b"
+                ]
+            ]
+        }, 
+        {
+            "input": "&image", 
+            "description": "Bad named entity: image without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&image"
+                ]
+            ]
+        }, 
+        {
+            "input": "&image;", 
+            "description": "Named entity: image; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2111"
+                ]
+            ]
+        }, 
+        {
+            "input": "&imagline", 
+            "description": "Bad named entity: imagline without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&imagline"
+                ]
+            ]
+        }, 
+        {
+            "input": "&imagline;", 
+            "description": "Named entity: imagline; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2110"
+                ]
+            ]
+        }, 
+        {
+            "input": "&imagpart", 
+            "description": "Bad named entity: imagpart without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&imagpart"
+                ]
+            ]
+        }, 
+        {
+            "input": "&imagpart;", 
+            "description": "Named entity: imagpart; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2111"
+                ]
+            ]
+        }, 
+        {
+            "input": "&imath", 
+            "description": "Bad named entity: imath without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&imath"
+                ]
+            ]
+        }, 
+        {
+            "input": "&imath;", 
+            "description": "Named entity: imath; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u0131"
+                ]
+            ]
+        }, 
+        {
+            "input": "&imof", 
+            "description": "Bad named entity: imof without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&imof"
+                ]
+            ]
+        }, 
+        {
+            "input": "&imof;", 
+            "description": "Named entity: imof; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u22b7"
+                ]
+            ]
+        }, 
+        {
+            "input": "&imped", 
+            "description": "Bad named entity: imped without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&imped"
+                ]
+            ]
+        }, 
+        {
+            "input": "&imped;", 
+            "description": "Named entity: imped; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u01b5"
+                ]
+            ]
+        }, 
+        {
+            "input": "&in", 
+            "description": "Bad named entity: in without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&in"
+                ]
+            ]
+        }, 
+        {
+            "input": "&in;", 
+            "description": "Named entity: in; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2208"
+                ]
+            ]
+        }, 
+        {
+            "input": "&incare", 
+            "description": "Bad named entity: incare without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&incare"
+                ]
+            ]
+        }, 
+        {
+            "input": "&incare;", 
+            "description": "Named entity: incare; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2105"
+                ]
+            ]
+        }, 
+        {
+            "input": "&infin", 
+            "description": "Bad named entity: infin without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&infin"
+                ]
+            ]
+        }, 
+        {
+            "input": "&infin;", 
+            "description": "Named entity: infin; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u221e"
+                ]
+            ]
+        }, 
+        {
+            "input": "&infintie", 
+            "description": "Bad named entity: infintie without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&infintie"
+                ]
+            ]
+        }, 
+        {
+            "input": "&infintie;", 
+            "description": "Named entity: infintie; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u29dd"
+                ]
+            ]
+        }, 
+        {
+            "input": "&inodot", 
+            "description": "Bad named entity: inodot without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&inodot"
+                ]
+            ]
+        }, 
+        {
+            "input": "&inodot;", 
+            "description": "Named entity: inodot; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u0131"
+                ]
+            ]
+        }, 
+        {
+            "input": "&int", 
+            "description": "Bad named entity: int without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&int"
+                ]
+            ]
+        }, 
+        {
+            "input": "&int;", 
+            "description": "Named entity: int; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u222b"
+                ]
+            ]
+        }, 
+        {
+            "input": "&intcal", 
+            "description": "Bad named entity: intcal without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&intcal"
+                ]
+            ]
+        }, 
+        {
+            "input": "&intcal;", 
+            "description": "Named entity: intcal; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u22ba"
+                ]
+            ]
+        }, 
+        {
+            "input": "&integers", 
+            "description": "Bad named entity: integers without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&integers"
+                ]
+            ]
+        }, 
+        {
+            "input": "&integers;", 
+            "description": "Named entity: integers; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2124"
+                ]
+            ]
+        }, 
+        {
+            "input": "&intercal", 
+            "description": "Bad named entity: intercal without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&intercal"
+                ]
+            ]
+        }, 
+        {
+            "input": "&intercal;", 
+            "description": "Named entity: intercal; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u22ba"
+                ]
+            ]
+        }, 
+        {
+            "input": "&intlarhk", 
+            "description": "Bad named entity: intlarhk without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&intlarhk"
+                ]
+            ]
+        }, 
+        {
+            "input": "&intlarhk;", 
+            "description": "Named entity: intlarhk; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2a17"
+                ]
+            ]
+        }, 
+        {
+            "input": "&intprod", 
+            "description": "Bad named entity: intprod without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&intprod"
+                ]
+            ]
+        }, 
+        {
+            "input": "&intprod;", 
+            "description": "Named entity: intprod; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2a3c"
+                ]
+            ]
+        }, 
+        {
+            "input": "&iocy", 
+            "description": "Bad named entity: iocy without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&iocy"
+                ]
+            ]
+        }, 
+        {
+            "input": "&iocy;", 
+            "description": "Named entity: iocy; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u0451"
+                ]
+            ]
+        }, 
+        {
+            "input": "&iogon", 
+            "description": "Bad named entity: iogon without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&iogon"
+                ]
+            ]
+        }, 
+        {
+            "input": "&iogon;", 
+            "description": "Named entity: iogon; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u012f"
+                ]
+            ]
+        }, 
+        {
+            "input": "&iopf", 
+            "description": "Bad named entity: iopf without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&iopf"
+                ]
+            ]
+        }, 
+        {
+            "input": "&iopf;", 
+            "description": "Named entity: iopf; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\ud835\udd5a"
+                ]
+            ]
+        }, 
+        {
+            "input": "&iota", 
+            "description": "Bad named entity: iota without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&iota"
+                ]
+            ]
+        }, 
+        {
+            "input": "&iota;", 
+            "description": "Named entity: iota; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u03b9"
+                ]
+            ]
+        }, 
+        {
+            "input": "&iprod", 
+            "description": "Bad named entity: iprod without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&iprod"
+                ]
+            ]
+        }, 
+        {
+            "input": "&iprod;", 
+            "description": "Named entity: iprod; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2a3c"
+                ]
+            ]
+        }, 
+        {
+            "input": "&iquest", 
+            "description": "Named entity: iquest without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "\u00bf"
+                ]
+            ]
+        }, 
+        {
+            "input": "&iquest;", 
+            "description": "Named entity: iquest; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u00bf"
+                ]
+            ]
+        }, 
+        {
+            "input": "&iscr", 
+            "description": "Bad named entity: iscr without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&iscr"
+                ]
+            ]
+        }, 
+        {
+            "input": "&iscr;", 
+            "description": "Named entity: iscr; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\ud835\udcbe"
+                ]
+            ]
+        }, 
+        {
+            "input": "&isin", 
+            "description": "Bad named entity: isin without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&isin"
+                ]
+            ]
+        }, 
+        {
+            "input": "&isin;", 
+            "description": "Named entity: isin; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2208"
+                ]
+            ]
+        }, 
+        {
+            "input": "&isinE", 
+            "description": "Bad named entity: isinE without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&isinE"
+                ]
+            ]
+        }, 
+        {
+            "input": "&isinE;", 
+            "description": "Named entity: isinE; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u22f9"
+                ]
+            ]
+        }, 
+        {
+            "input": "&isindot", 
+            "description": "Bad named entity: isindot without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&isindot"
+                ]
+            ]
+        }, 
+        {
+            "input": "&isindot;", 
+            "description": "Named entity: isindot; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u22f5"
+                ]
+            ]
+        }, 
+        {
+            "input": "&isins", 
+            "description": "Bad named entity: isins without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&isins"
+                ]
+            ]
+        }, 
+        {
+            "input": "&isins;", 
+            "description": "Named entity: isins; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u22f4"
+                ]
+            ]
+        }, 
+        {
+            "input": "&isinsv", 
+            "description": "Bad named entity: isinsv without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&isinsv"
+                ]
+            ]
+        }, 
+        {
+            "input": "&isinsv;", 
+            "description": "Named entity: isinsv; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u22f3"
+                ]
+            ]
+        }, 
+        {
+            "input": "&isinv", 
+            "description": "Bad named entity: isinv without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&isinv"
+                ]
+            ]
+        }, 
+        {
+            "input": "&isinv;", 
+            "description": "Named entity: isinv; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2208"
+                ]
+            ]
+        }, 
+        {
+            "input": "&it", 
+            "description": "Bad named entity: it without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&it"
+                ]
+            ]
+        }, 
+        {
+            "input": "&it;", 
+            "description": "Named entity: it; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2062"
+                ]
+            ]
+        }, 
+        {
+            "input": "&itilde", 
+            "description": "Bad named entity: itilde without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&itilde"
+                ]
+            ]
+        }, 
+        {
+            "input": "&itilde;", 
+            "description": "Named entity: itilde; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u0129"
+                ]
+            ]
+        }, 
+        {
+            "input": "&iukcy", 
+            "description": "Bad named entity: iukcy without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&iukcy"
+                ]
+            ]
+        }, 
+        {
+            "input": "&iukcy;", 
+            "description": "Named entity: iukcy; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u0456"
+                ]
+            ]
+        }, 
+        {
+            "input": "&iuml", 
+            "description": "Named entity: iuml without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "\u00ef"
+                ]
+            ]
+        }, 
+        {
+            "input": "&iuml;", 
+            "description": "Named entity: iuml; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u00ef"
+                ]
+            ]
+        }, 
+        {
+            "input": "&jcirc", 
+            "description": "Bad named entity: jcirc without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&jcirc"
+                ]
+            ]
+        }, 
+        {
+            "input": "&jcirc;", 
+            "description": "Named entity: jcirc; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u0135"
+                ]
+            ]
+        }, 
+        {
+            "input": "&jcy", 
+            "description": "Bad named entity: jcy without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&jcy"
+                ]
+            ]
+        }, 
+        {
+            "input": "&jcy;", 
+            "description": "Named entity: jcy; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u0439"
+                ]
+            ]
+        }, 
+        {
+            "input": "&jfr", 
+            "description": "Bad named entity: jfr without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&jfr"
+                ]
+            ]
+        }, 
+        {
+            "input": "&jfr;", 
+            "description": "Named entity: jfr; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\ud835\udd27"
+                ]
+            ]
+        }, 
+        {
+            "input": "&jmath", 
+            "description": "Bad named entity: jmath without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&jmath"
+                ]
+            ]
+        }, 
+        {
+            "input": "&jmath;", 
+            "description": "Named entity: jmath; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u0237"
+                ]
+            ]
+        }, 
+        {
+            "input": "&jopf", 
+            "description": "Bad named entity: jopf without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&jopf"
+                ]
+            ]
+        }, 
+        {
+            "input": "&jopf;", 
+            "description": "Named entity: jopf; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\ud835\udd5b"
+                ]
+            ]
+        }, 
+        {
+            "input": "&jscr", 
+            "description": "Bad named entity: jscr without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&jscr"
+                ]
+            ]
+        }, 
+        {
+            "input": "&jscr;", 
+            "description": "Named entity: jscr; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\ud835\udcbf"
+                ]
+            ]
+        }, 
+        {
+            "input": "&jsercy", 
+            "description": "Bad named entity: jsercy without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&jsercy"
+                ]
+            ]
+        }, 
+        {
+            "input": "&jsercy;", 
+            "description": "Named entity: jsercy; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u0458"
+                ]
+            ]
+        }, 
+        {
+            "input": "&jukcy", 
+            "description": "Bad named entity: jukcy without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&jukcy"
+                ]
+            ]
+        }, 
+        {
+            "input": "&jukcy;", 
+            "description": "Named entity: jukcy; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u0454"
+                ]
+            ]
+        }, 
+        {
+            "input": "&kappa", 
+            "description": "Bad named entity: kappa without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&kappa"
+                ]
+            ]
+        }, 
+        {
+            "input": "&kappa;", 
+            "description": "Named entity: kappa; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u03ba"
+                ]
+            ]
+        }, 
+        {
+            "input": "&kappav", 
+            "description": "Bad named entity: kappav without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&kappav"
+                ]
+            ]
+        }, 
+        {
+            "input": "&kappav;", 
+            "description": "Named entity: kappav; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u03f0"
+                ]
+            ]
+        }, 
+        {
+            "input": "&kcedil", 
+            "description": "Bad named entity: kcedil without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&kcedil"
+                ]
+            ]
+        }, 
+        {
+            "input": "&kcedil;", 
+            "description": "Named entity: kcedil; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u0137"
+                ]
+            ]
+        }, 
+        {
+            "input": "&kcy", 
+            "description": "Bad named entity: kcy without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&kcy"
+                ]
+            ]
+        }, 
+        {
+            "input": "&kcy;", 
+            "description": "Named entity: kcy; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u043a"
+                ]
+            ]
+        }, 
+        {
+            "input": "&kfr", 
+            "description": "Bad named entity: kfr without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&kfr"
+                ]
+            ]
+        }, 
+        {
+            "input": "&kfr;", 
+            "description": "Named entity: kfr; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\ud835\udd28"
+                ]
+            ]
+        }, 
+        {
+            "input": "&kgreen", 
+            "description": "Bad named entity: kgreen without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&kgreen"
+                ]
+            ]
+        }, 
+        {
+            "input": "&kgreen;", 
+            "description": "Named entity: kgreen; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u0138"
+                ]
+            ]
+        }, 
+        {
+            "input": "&khcy", 
+            "description": "Bad named entity: khcy without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&khcy"
+                ]
+            ]
+        }, 
+        {
+            "input": "&khcy;", 
+            "description": "Named entity: khcy; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u0445"
+                ]
+            ]
+        }, 
+        {
+            "input": "&kjcy", 
+            "description": "Bad named entity: kjcy without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&kjcy"
+                ]
+            ]
+        }, 
+        {
+            "input": "&kjcy;", 
+            "description": "Named entity: kjcy; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u045c"
+                ]
+            ]
+        }, 
+        {
+            "input": "&kopf", 
+            "description": "Bad named entity: kopf without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&kopf"
+                ]
+            ]
+        }, 
+        {
+            "input": "&kopf;", 
+            "description": "Named entity: kopf; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\ud835\udd5c"
+                ]
+            ]
+        }, 
+        {
+            "input": "&kscr", 
+            "description": "Bad named entity: kscr without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&kscr"
+                ]
+            ]
+        }, 
+        {
+            "input": "&kscr;", 
+            "description": "Named entity: kscr; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\ud835\udcc0"
+                ]
+            ]
+        }, 
+        {
+            "input": "&lAarr", 
+            "description": "Bad named entity: lAarr without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&lAarr"
+                ]
+            ]
+        }, 
+        {
+            "input": "&lAarr;", 
+            "description": "Named entity: lAarr; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u21da"
+                ]
+            ]
+        }, 
+        {
+            "input": "&lArr", 
+            "description": "Bad named entity: lArr without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&lArr"
+                ]
+            ]
+        }, 
+        {
+            "input": "&lArr;", 
+            "description": "Named entity: lArr; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u21d0"
+                ]
+            ]
+        }, 
+        {
+            "input": "&lAtail", 
+            "description": "Bad named entity: lAtail without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&lAtail"
+                ]
+            ]
+        }, 
+        {
+            "input": "&lAtail;", 
+            "description": "Named entity: lAtail; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u291b"
+                ]
+            ]
+        }, 
+        {
+            "input": "&lBarr", 
+            "description": "Bad named entity: lBarr without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&lBarr"
+                ]
+            ]
+        }, 
+        {
+            "input": "&lBarr;", 
+            "description": "Named entity: lBarr; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u290e"
+                ]
+            ]
+        }, 
+        {
+            "input": "&lE", 
+            "description": "Bad named entity: lE without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&lE"
+                ]
+            ]
+        }, 
+        {
+            "input": "&lE;", 
+            "description": "Named entity: lE; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2266"
+                ]
+            ]
+        }, 
+        {
+            "input": "&lEg", 
+            "description": "Bad named entity: lEg without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&lEg"
+                ]
+            ]
+        }, 
+        {
+            "input": "&lEg;", 
+            "description": "Named entity: lEg; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2a8b"
+                ]
+            ]
+        }, 
+        {
+            "input": "&lHar", 
+            "description": "Bad named entity: lHar without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&lHar"
+                ]
+            ]
+        }, 
+        {
+            "input": "&lHar;", 
+            "description": "Named entity: lHar; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2962"
+                ]
+            ]
+        }, 
+        {
+            "input": "&lacute", 
+            "description": "Bad named entity: lacute without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&lacute"
+                ]
+            ]
+        }, 
+        {
+            "input": "&lacute;", 
+            "description": "Named entity: lacute; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u013a"
+                ]
+            ]
+        }, 
+        {
+            "input": "&laemptyv", 
+            "description": "Bad named entity: laemptyv without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&laemptyv"
+                ]
+            ]
+        }, 
+        {
+            "input": "&laemptyv;", 
+            "description": "Named entity: laemptyv; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u29b4"
+                ]
+            ]
+        }, 
+        {
+            "input": "&lagran", 
+            "description": "Bad named entity: lagran without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&lagran"
+                ]
+            ]
+        }, 
+        {
+            "input": "&lagran;", 
+            "description": "Named entity: lagran; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2112"
+                ]
+            ]
+        }, 
+        {
+            "input": "&lambda", 
+            "description": "Bad named entity: lambda without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&lambda"
+                ]
+            ]
+        }, 
+        {
+            "input": "&lambda;", 
+            "description": "Named entity: lambda; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u03bb"
+                ]
+            ]
+        }, 
+        {
+            "input": "&lang", 
+            "description": "Bad named entity: lang without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&lang"
+                ]
+            ]
+        }, 
+        {
+            "input": "&lang;", 
+            "description": "Named entity: lang; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u27e8"
+                ]
+            ]
+        }, 
+        {
+            "input": "&langd", 
+            "description": "Bad named entity: langd without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&langd"
+                ]
+            ]
+        }, 
+        {
+            "input": "&langd;", 
+            "description": "Named entity: langd; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2991"
+                ]
+            ]
+        }, 
+        {
+            "input": "&langle", 
+            "description": "Bad named entity: langle without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&langle"
+                ]
+            ]
+        }, 
+        {
+            "input": "&langle;", 
+            "description": "Named entity: langle; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u27e8"
+                ]
+            ]
+        }, 
+        {
+            "input": "&lap", 
+            "description": "Bad named entity: lap without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&lap"
+                ]
+            ]
+        }, 
+        {
+            "input": "&lap;", 
+            "description": "Named entity: lap; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2a85"
+                ]
+            ]
+        }, 
+        {
+            "input": "&laquo", 
+            "description": "Named entity: laquo without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "\u00ab"
+                ]
+            ]
+        }, 
+        {
+            "input": "&laquo;", 
+            "description": "Named entity: laquo; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u00ab"
+                ]
+            ]
+        }, 
+        {
+            "input": "&larr", 
+            "description": "Bad named entity: larr without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&larr"
+                ]
+            ]
+        }, 
+        {
+            "input": "&larr;", 
+            "description": "Named entity: larr; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2190"
+                ]
+            ]
+        }, 
+        {
+            "input": "&larrb", 
+            "description": "Bad named entity: larrb without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&larrb"
+                ]
+            ]
+        }, 
+        {
+            "input": "&larrb;", 
+            "description": "Named entity: larrb; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u21e4"
+                ]
+            ]
+        }, 
+        {
+            "input": "&larrbfs", 
+            "description": "Bad named entity: larrbfs without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&larrbfs"
+                ]
+            ]
+        }, 
+        {
+            "input": "&larrbfs;", 
+            "description": "Named entity: larrbfs; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u291f"
+                ]
+            ]
+        }, 
+        {
+            "input": "&larrfs", 
+            "description": "Bad named entity: larrfs without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&larrfs"
+                ]
+            ]
+        }, 
+        {
+            "input": "&larrfs;", 
+            "description": "Named entity: larrfs; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u291d"
+                ]
+            ]
+        }, 
+        {
+            "input": "&larrhk", 
+            "description": "Bad named entity: larrhk without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&larrhk"
+                ]
+            ]
+        }, 
+        {
+            "input": "&larrhk;", 
+            "description": "Named entity: larrhk; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u21a9"
+                ]
+            ]
+        }, 
+        {
+            "input": "&larrlp", 
+            "description": "Bad named entity: larrlp without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&larrlp"
+                ]
+            ]
+        }, 
+        {
+            "input": "&larrlp;", 
+            "description": "Named entity: larrlp; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u21ab"
+                ]
+            ]
+        }, 
+        {
+            "input": "&larrpl", 
+            "description": "Bad named entity: larrpl without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&larrpl"
+                ]
+            ]
+        }, 
+        {
+            "input": "&larrpl;", 
+            "description": "Named entity: larrpl; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2939"
+                ]
+            ]
+        }, 
+        {
+            "input": "&larrsim", 
+            "description": "Bad named entity: larrsim without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&larrsim"
+                ]
+            ]
+        }, 
+        {
+            "input": "&larrsim;", 
+            "description": "Named entity: larrsim; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2973"
+                ]
+            ]
+        }, 
+        {
+            "input": "&larrtl", 
+            "description": "Bad named entity: larrtl without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&larrtl"
+                ]
+            ]
+        }, 
+        {
+            "input": "&larrtl;", 
+            "description": "Named entity: larrtl; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u21a2"
+                ]
+            ]
+        }, 
+        {
+            "input": "&lat", 
+            "description": "Bad named entity: lat without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&lat"
+                ]
+            ]
+        }, 
+        {
+            "input": "&lat;", 
+            "description": "Named entity: lat; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2aab"
+                ]
+            ]
+        }, 
+        {
+            "input": "&latail", 
+            "description": "Bad named entity: latail without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&latail"
+                ]
+            ]
+        }, 
+        {
+            "input": "&latail;", 
+            "description": "Named entity: latail; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2919"
+                ]
+            ]
+        }, 
+        {
+            "input": "&late", 
+            "description": "Bad named entity: late without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&late"
+                ]
+            ]
+        }, 
+        {
+            "input": "&late;", 
+            "description": "Named entity: late; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2aad"
+                ]
+            ]
+        }, 
+        {
+            "input": "&lates", 
+            "description": "Bad named entity: lates without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&lates"
+                ]
+            ]
+        }, 
+        {
+            "input": "&lates;", 
+            "description": "Named entity: lates; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2aad\ufe00"
+                ]
+            ]
+        }, 
+        {
+            "input": "&lbarr", 
+            "description": "Bad named entity: lbarr without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&lbarr"
+                ]
+            ]
+        }, 
+        {
+            "input": "&lbarr;", 
+            "description": "Named entity: lbarr; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u290c"
+                ]
+            ]
+        }, 
+        {
+            "input": "&lbbrk", 
+            "description": "Bad named entity: lbbrk without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&lbbrk"
+                ]
+            ]
+        }, 
+        {
+            "input": "&lbbrk;", 
+            "description": "Named entity: lbbrk; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2772"
+                ]
+            ]
+        }, 
+        {
+            "input": "&lbrace", 
+            "description": "Bad named entity: lbrace without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&lbrace"
+                ]
+            ]
+        }, 
+        {
+            "input": "&lbrace;", 
+            "description": "Named entity: lbrace; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "{"
+                ]
+            ]
+        }, 
+        {
+            "input": "&lbrack", 
+            "description": "Bad named entity: lbrack without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&lbrack"
+                ]
+            ]
+        }, 
+        {
+            "input": "&lbrack;", 
+            "description": "Named entity: lbrack; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "["
+                ]
+            ]
+        }, 
+        {
+            "input": "&lbrke", 
+            "description": "Bad named entity: lbrke without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&lbrke"
+                ]
+            ]
+        }, 
+        {
+            "input": "&lbrke;", 
+            "description": "Named entity: lbrke; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u298b"
+                ]
+            ]
+        }, 
+        {
+            "input": "&lbrksld", 
+            "description": "Bad named entity: lbrksld without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&lbrksld"
+                ]
+            ]
+        }, 
+        {
+            "input": "&lbrksld;", 
+            "description": "Named entity: lbrksld; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u298f"
+                ]
+            ]
+        }, 
+        {
+            "input": "&lbrkslu", 
+            "description": "Bad named entity: lbrkslu without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&lbrkslu"
+                ]
+            ]
+        }, 
+        {
+            "input": "&lbrkslu;", 
+            "description": "Named entity: lbrkslu; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u298d"
+                ]
+            ]
+        }, 
+        {
+            "input": "&lcaron", 
+            "description": "Bad named entity: lcaron without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&lcaron"
+                ]
+            ]
+        }, 
+        {
+            "input": "&lcaron;", 
+            "description": "Named entity: lcaron; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u013e"
+                ]
+            ]
+        }, 
+        {
+            "input": "&lcedil", 
+            "description": "Bad named entity: lcedil without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&lcedil"
+                ]
+            ]
+        }, 
+        {
+            "input": "&lcedil;", 
+            "description": "Named entity: lcedil; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u013c"
+                ]
+            ]
+        }, 
+        {
+            "input": "&lceil", 
+            "description": "Bad named entity: lceil without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&lceil"
+                ]
+            ]
+        }, 
+        {
+            "input": "&lceil;", 
+            "description": "Named entity: lceil; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2308"
+                ]
+            ]
+        }, 
+        {
+            "input": "&lcub", 
+            "description": "Bad named entity: lcub without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&lcub"
+                ]
+            ]
+        }, 
+        {
+            "input": "&lcub;", 
+            "description": "Named entity: lcub; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "{"
+                ]
+            ]
+        }, 
+        {
+            "input": "&lcy", 
+            "description": "Bad named entity: lcy without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&lcy"
+                ]
+            ]
+        }, 
+        {
+            "input": "&lcy;", 
+            "description": "Named entity: lcy; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u043b"
+                ]
+            ]
+        }, 
+        {
+            "input": "&ldca", 
+            "description": "Bad named entity: ldca without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&ldca"
+                ]
+            ]
+        }, 
+        {
+            "input": "&ldca;", 
+            "description": "Named entity: ldca; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2936"
+                ]
+            ]
+        }, 
+        {
+            "input": "&ldquo", 
+            "description": "Bad named entity: ldquo without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&ldquo"
+                ]
+            ]
+        }, 
+        {
+            "input": "&ldquo;", 
+            "description": "Named entity: ldquo; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u201c"
+                ]
+            ]
+        }, 
+        {
+            "input": "&ldquor", 
+            "description": "Bad named entity: ldquor without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&ldquor"
+                ]
+            ]
+        }, 
+        {
+            "input": "&ldquor;", 
+            "description": "Named entity: ldquor; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u201e"
+                ]
+            ]
+        }, 
+        {
+            "input": "&ldrdhar", 
+            "description": "Bad named entity: ldrdhar without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&ldrdhar"
+                ]
+            ]
+        }, 
+        {
+            "input": "&ldrdhar;", 
+            "description": "Named entity: ldrdhar; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2967"
+                ]
+            ]
+        }, 
+        {
+            "input": "&ldrushar", 
+            "description": "Bad named entity: ldrushar without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&ldrushar"
+                ]
+            ]
+        }, 
+        {
+            "input": "&ldrushar;", 
+            "description": "Named entity: ldrushar; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u294b"
+                ]
+            ]
+        }, 
+        {
+            "input": "&ldsh", 
+            "description": "Bad named entity: ldsh without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&ldsh"
+                ]
+            ]
+        }, 
+        {
+            "input": "&ldsh;", 
+            "description": "Named entity: ldsh; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u21b2"
+                ]
+            ]
+        }, 
+        {
+            "input": "&le", 
+            "description": "Bad named entity: le without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&le"
+                ]
+            ]
+        }, 
+        {
+            "input": "&le;", 
+            "description": "Named entity: le; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2264"
+                ]
+            ]
+        }, 
+        {
+            "input": "&leftarrow", 
+            "description": "Bad named entity: leftarrow without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&leftarrow"
+                ]
+            ]
+        }, 
+        {
+            "input": "&leftarrow;", 
+            "description": "Named entity: leftarrow; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2190"
+                ]
+            ]
+        }, 
+        {
+            "input": "&leftarrowtail", 
+            "description": "Bad named entity: leftarrowtail without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&leftarrowtail"
+                ]
+            ]
+        }, 
+        {
+            "input": "&leftarrowtail;", 
+            "description": "Named entity: leftarrowtail; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u21a2"
+                ]
+            ]
+        }, 
+        {
+            "input": "&leftharpoondown", 
+            "description": "Bad named entity: leftharpoondown without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&leftharpoondown"
+                ]
+            ]
+        }, 
+        {
+            "input": "&leftharpoondown;", 
+            "description": "Named entity: leftharpoondown; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u21bd"
+                ]
+            ]
+        }, 
+        {
+            "input": "&leftharpoonup", 
+            "description": "Bad named entity: leftharpoonup without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&leftharpoonup"
+                ]
+            ]
+        }, 
+        {
+            "input": "&leftharpoonup;", 
+            "description": "Named entity: leftharpoonup; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u21bc"
+                ]
+            ]
+        }, 
+        {
+            "input": "&leftleftarrows", 
+            "description": "Bad named entity: leftleftarrows without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&leftleftarrows"
+                ]
+            ]
+        }, 
+        {
+            "input": "&leftleftarrows;", 
+            "description": "Named entity: leftleftarrows; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u21c7"
+                ]
+            ]
+        }, 
+        {
+            "input": "&leftrightarrow", 
+            "description": "Bad named entity: leftrightarrow without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&leftrightarrow"
+                ]
+            ]
+        }, 
+        {
+            "input": "&leftrightarrow;", 
+            "description": "Named entity: leftrightarrow; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2194"
+                ]
+            ]
+        }, 
+        {
+            "input": "&leftrightarrows", 
+            "description": "Bad named entity: leftrightarrows without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&leftrightarrows"
+                ]
+            ]
+        }, 
+        {
+            "input": "&leftrightarrows;", 
+            "description": "Named entity: leftrightarrows; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u21c6"
+                ]
+            ]
+        }, 
+        {
+            "input": "&leftrightharpoons", 
+            "description": "Bad named entity: leftrightharpoons without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&leftrightharpoons"
+                ]
+            ]
+        }, 
+        {
+            "input": "&leftrightharpoons;", 
+            "description": "Named entity: leftrightharpoons; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u21cb"
+                ]
+            ]
+        }, 
+        {
+            "input": "&leftrightsquigarrow", 
+            "description": "Bad named entity: leftrightsquigarrow without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&leftrightsquigarrow"
+                ]
+            ]
+        }, 
+        {
+            "input": "&leftrightsquigarrow;", 
+            "description": "Named entity: leftrightsquigarrow; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u21ad"
+                ]
+            ]
+        }, 
+        {
+            "input": "&leftthreetimes", 
+            "description": "Bad named entity: leftthreetimes without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&leftthreetimes"
+                ]
+            ]
+        }, 
+        {
+            "input": "&leftthreetimes;", 
+            "description": "Named entity: leftthreetimes; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u22cb"
+                ]
+            ]
+        }, 
+        {
+            "input": "&leg", 
+            "description": "Bad named entity: leg without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&leg"
+                ]
+            ]
+        }, 
+        {
+            "input": "&leg;", 
+            "description": "Named entity: leg; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u22da"
+                ]
+            ]
+        }, 
+        {
+            "input": "&leq", 
+            "description": "Bad named entity: leq without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&leq"
+                ]
+            ]
+        }, 
+        {
+            "input": "&leq;", 
+            "description": "Named entity: leq; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2264"
+                ]
+            ]
+        }, 
+        {
+            "input": "&leqq", 
+            "description": "Bad named entity: leqq without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&leqq"
+                ]
+            ]
+        }, 
+        {
+            "input": "&leqq;", 
+            "description": "Named entity: leqq; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2266"
+                ]
+            ]
+        }, 
+        {
+            "input": "&leqslant", 
+            "description": "Bad named entity: leqslant without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&leqslant"
+                ]
+            ]
+        }, 
+        {
+            "input": "&leqslant;", 
+            "description": "Named entity: leqslant; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2a7d"
+                ]
+            ]
+        }, 
+        {
+            "input": "&les", 
+            "description": "Bad named entity: les without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&les"
+                ]
+            ]
+        }, 
+        {
+            "input": "&les;", 
+            "description": "Named entity: les; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2a7d"
+                ]
+            ]
+        }, 
+        {
+            "input": "&lescc", 
+            "description": "Bad named entity: lescc without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&lescc"
+                ]
+            ]
+        }, 
+        {
+            "input": "&lescc;", 
+            "description": "Named entity: lescc; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2aa8"
+                ]
+            ]
+        }, 
+        {
+            "input": "&lesdot", 
+            "description": "Bad named entity: lesdot without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&lesdot"
+                ]
+            ]
+        }, 
+        {
+            "input": "&lesdot;", 
+            "description": "Named entity: lesdot; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2a7f"
+                ]
+            ]
+        }, 
+        {
+            "input": "&lesdoto", 
+            "description": "Bad named entity: lesdoto without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&lesdoto"
+                ]
+            ]
+        }, 
+        {
+            "input": "&lesdoto;", 
+            "description": "Named entity: lesdoto; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2a81"
+                ]
+            ]
+        }, 
+        {
+            "input": "&lesdotor", 
+            "description": "Bad named entity: lesdotor without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&lesdotor"
+                ]
+            ]
+        }, 
+        {
+            "input": "&lesdotor;", 
+            "description": "Named entity: lesdotor; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2a83"
+                ]
+            ]
+        }, 
+        {
+            "input": "&lesg", 
+            "description": "Bad named entity: lesg without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&lesg"
+                ]
+            ]
+        }, 
+        {
+            "input": "&lesg;", 
+            "description": "Named entity: lesg; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u22da\ufe00"
+                ]
+            ]
+        }, 
+        {
+            "input": "&lesges", 
+            "description": "Bad named entity: lesges without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&lesges"
+                ]
+            ]
+        }, 
+        {
+            "input": "&lesges;", 
+            "description": "Named entity: lesges; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2a93"
+                ]
+            ]
+        }, 
+        {
+            "input": "&lessapprox", 
+            "description": "Bad named entity: lessapprox without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&lessapprox"
+                ]
+            ]
+        }, 
+        {
+            "input": "&lessapprox;", 
+            "description": "Named entity: lessapprox; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2a85"
+                ]
+            ]
+        }, 
+        {
+            "input": "&lessdot", 
+            "description": "Bad named entity: lessdot without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&lessdot"
+                ]
+            ]
+        }, 
+        {
+            "input": "&lessdot;", 
+            "description": "Named entity: lessdot; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u22d6"
+                ]
+            ]
+        }, 
+        {
+            "input": "&lesseqgtr", 
+            "description": "Bad named entity: lesseqgtr without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&lesseqgtr"
+                ]
+            ]
+        }, 
+        {
+            "input": "&lesseqgtr;", 
+            "description": "Named entity: lesseqgtr; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u22da"
+                ]
+            ]
+        }, 
+        {
+            "input": "&lesseqqgtr", 
+            "description": "Bad named entity: lesseqqgtr without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&lesseqqgtr"
+                ]
+            ]
+        }, 
+        {
+            "input": "&lesseqqgtr;", 
+            "description": "Named entity: lesseqqgtr; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2a8b"
+                ]
+            ]
+        }, 
+        {
+            "input": "&lessgtr", 
+            "description": "Bad named entity: lessgtr without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&lessgtr"
+                ]
+            ]
+        }, 
+        {
+            "input": "&lessgtr;", 
+            "description": "Named entity: lessgtr; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2276"
+                ]
+            ]
+        }, 
+        {
+            "input": "&lesssim", 
+            "description": "Bad named entity: lesssim without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&lesssim"
+                ]
+            ]
+        }, 
+        {
+            "input": "&lesssim;", 
+            "description": "Named entity: lesssim; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2272"
+                ]
+            ]
+        }, 
+        {
+            "input": "&lfisht", 
+            "description": "Bad named entity: lfisht without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&lfisht"
+                ]
+            ]
+        }, 
+        {
+            "input": "&lfisht;", 
+            "description": "Named entity: lfisht; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u297c"
+                ]
+            ]
+        }, 
+        {
+            "input": "&lfloor", 
+            "description": "Bad named entity: lfloor without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&lfloor"
+                ]
+            ]
+        }, 
+        {
+            "input": "&lfloor;", 
+            "description": "Named entity: lfloor; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u230a"
+                ]
+            ]
+        }, 
+        {
+            "input": "&lfr", 
+            "description": "Bad named entity: lfr without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&lfr"
+                ]
+            ]
+        }, 
+        {
+            "input": "&lfr;", 
+            "description": "Named entity: lfr; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\ud835\udd29"
+                ]
+            ]
+        }, 
+        {
+            "input": "&lg", 
+            "description": "Bad named entity: lg without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&lg"
+                ]
+            ]
+        }, 
+        {
+            "input": "&lg;", 
+            "description": "Named entity: lg; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2276"
+                ]
+            ]
+        }, 
+        {
+            "input": "&lgE", 
+            "description": "Bad named entity: lgE without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&lgE"
+                ]
+            ]
+        }, 
+        {
+            "input": "&lgE;", 
+            "description": "Named entity: lgE; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2a91"
+                ]
+            ]
+        }, 
+        {
+            "input": "&lhard", 
+            "description": "Bad named entity: lhard without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&lhard"
+                ]
+            ]
+        }, 
+        {
+            "input": "&lhard;", 
+            "description": "Named entity: lhard; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u21bd"
+                ]
+            ]
+        }, 
+        {
+            "input": "&lharu", 
+            "description": "Bad named entity: lharu without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&lharu"
+                ]
+            ]
+        }, 
+        {
+            "input": "&lharu;", 
+            "description": "Named entity: lharu; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u21bc"
+                ]
+            ]
+        }, 
+        {
+            "input": "&lharul", 
+            "description": "Bad named entity: lharul without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&lharul"
+                ]
+            ]
+        }, 
+        {
+            "input": "&lharul;", 
+            "description": "Named entity: lharul; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u296a"
+                ]
+            ]
+        }, 
+        {
+            "input": "&lhblk", 
+            "description": "Bad named entity: lhblk without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&lhblk"
+                ]
+            ]
+        }, 
+        {
+            "input": "&lhblk;", 
+            "description": "Named entity: lhblk; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2584"
+                ]
+            ]
+        }, 
+        {
+            "input": "&ljcy", 
+            "description": "Bad named entity: ljcy without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&ljcy"
+                ]
+            ]
+        }, 
+        {
+            "input": "&ljcy;", 
+            "description": "Named entity: ljcy; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u0459"
+                ]
+            ]
+        }, 
+        {
+            "input": "&ll", 
+            "description": "Bad named entity: ll without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&ll"
+                ]
+            ]
+        }, 
+        {
+            "input": "&ll;", 
+            "description": "Named entity: ll; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u226a"
+                ]
+            ]
+        }, 
+        {
+            "input": "&llarr", 
+            "description": "Bad named entity: llarr without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&llarr"
+                ]
+            ]
+        }, 
+        {
+            "input": "&llarr;", 
+            "description": "Named entity: llarr; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u21c7"
+                ]
+            ]
+        }, 
+        {
+            "input": "&llcorner", 
+            "description": "Bad named entity: llcorner without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&llcorner"
+                ]
+            ]
+        }, 
+        {
+            "input": "&llcorner;", 
+            "description": "Named entity: llcorner; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u231e"
+                ]
+            ]
+        }, 
+        {
+            "input": "&llhard", 
+            "description": "Bad named entity: llhard without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&llhard"
+                ]
+            ]
+        }, 
+        {
+            "input": "&llhard;", 
+            "description": "Named entity: llhard; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u296b"
+                ]
+            ]
+        }, 
+        {
+            "input": "&lltri", 
+            "description": "Bad named entity: lltri without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&lltri"
+                ]
+            ]
+        }, 
+        {
+            "input": "&lltri;", 
+            "description": "Named entity: lltri; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u25fa"
+                ]
+            ]
+        }, 
+        {
+            "input": "&lmidot", 
+            "description": "Bad named entity: lmidot without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&lmidot"
+                ]
+            ]
+        }, 
+        {
+            "input": "&lmidot;", 
+            "description": "Named entity: lmidot; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u0140"
+                ]
+            ]
+        }, 
+        {
+            "input": "&lmoust", 
+            "description": "Bad named entity: lmoust without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&lmoust"
+                ]
+            ]
+        }, 
+        {
+            "input": "&lmoust;", 
+            "description": "Named entity: lmoust; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u23b0"
+                ]
+            ]
+        }, 
+        {
+            "input": "&lmoustache", 
+            "description": "Bad named entity: lmoustache without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&lmoustache"
+                ]
+            ]
+        }, 
+        {
+            "input": "&lmoustache;", 
+            "description": "Named entity: lmoustache; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u23b0"
+                ]
+            ]
+        }, 
+        {
+            "input": "&lnE", 
+            "description": "Bad named entity: lnE without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&lnE"
+                ]
+            ]
+        }, 
+        {
+            "input": "&lnE;", 
+            "description": "Named entity: lnE; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2268"
+                ]
+            ]
+        }, 
+        {
+            "input": "&lnap", 
+            "description": "Bad named entity: lnap without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&lnap"
+                ]
+            ]
+        }, 
+        {
+            "input": "&lnap;", 
+            "description": "Named entity: lnap; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2a89"
+                ]
+            ]
+        }, 
+        {
+            "input": "&lnapprox", 
+            "description": "Bad named entity: lnapprox without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&lnapprox"
+                ]
+            ]
+        }, 
+        {
+            "input": "&lnapprox;", 
+            "description": "Named entity: lnapprox; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2a89"
+                ]
+            ]
+        }, 
+        {
+            "input": "&lne", 
+            "description": "Bad named entity: lne without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&lne"
+                ]
+            ]
+        }, 
+        {
+            "input": "&lne;", 
+            "description": "Named entity: lne; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2a87"
+                ]
+            ]
+        }, 
+        {
+            "input": "&lneq", 
+            "description": "Bad named entity: lneq without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&lneq"
+                ]
+            ]
+        }, 
+        {
+            "input": "&lneq;", 
+            "description": "Named entity: lneq; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2a87"
+                ]
+            ]
+        }, 
+        {
+            "input": "&lneqq", 
+            "description": "Bad named entity: lneqq without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&lneqq"
+                ]
+            ]
+        }, 
+        {
+            "input": "&lneqq;", 
+            "description": "Named entity: lneqq; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2268"
+                ]
+            ]
+        }, 
+        {
+            "input": "&lnsim", 
+            "description": "Bad named entity: lnsim without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&lnsim"
+                ]
+            ]
+        }, 
+        {
+            "input": "&lnsim;", 
+            "description": "Named entity: lnsim; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u22e6"
+                ]
+            ]
+        }, 
+        {
+            "input": "&loang", 
+            "description": "Bad named entity: loang without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&loang"
+                ]
+            ]
+        }, 
+        {
+            "input": "&loang;", 
+            "description": "Named entity: loang; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u27ec"
+                ]
+            ]
+        }, 
+        {
+            "input": "&loarr", 
+            "description": "Bad named entity: loarr without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&loarr"
+                ]
+            ]
+        }, 
+        {
+            "input": "&loarr;", 
+            "description": "Named entity: loarr; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u21fd"
+                ]
+            ]
+        }, 
+        {
+            "input": "&lobrk", 
+            "description": "Bad named entity: lobrk without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&lobrk"
+                ]
+            ]
+        }, 
+        {
+            "input": "&lobrk;", 
+            "description": "Named entity: lobrk; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u27e6"
+                ]
+            ]
+        }, 
+        {
+            "input": "&longleftarrow", 
+            "description": "Bad named entity: longleftarrow without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&longleftarrow"
+                ]
+            ]
+        }, 
+        {
+            "input": "&longleftarrow;", 
+            "description": "Named entity: longleftarrow; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u27f5"
+                ]
+            ]
+        }, 
+        {
+            "input": "&longleftrightarrow", 
+            "description": "Bad named entity: longleftrightarrow without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&longleftrightarrow"
+                ]
+            ]
+        }, 
+        {
+            "input": "&longleftrightarrow;", 
+            "description": "Named entity: longleftrightarrow; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u27f7"
+                ]
+            ]
+        }, 
+        {
+            "input": "&longmapsto", 
+            "description": "Bad named entity: longmapsto without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&longmapsto"
+                ]
+            ]
+        }, 
+        {
+            "input": "&longmapsto;", 
+            "description": "Named entity: longmapsto; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u27fc"
+                ]
+            ]
+        }, 
+        {
+            "input": "&longrightarrow", 
+            "description": "Bad named entity: longrightarrow without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&longrightarrow"
+                ]
+            ]
+        }, 
+        {
+            "input": "&longrightarrow;", 
+            "description": "Named entity: longrightarrow; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u27f6"
+                ]
+            ]
+        }, 
+        {
+            "input": "&looparrowleft", 
+            "description": "Bad named entity: looparrowleft without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&looparrowleft"
+                ]
+            ]
+        }, 
+        {
+            "input": "&looparrowleft;", 
+            "description": "Named entity: looparrowleft; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u21ab"
+                ]
+            ]
+        }, 
+        {
+            "input": "&looparrowright", 
+            "description": "Bad named entity: looparrowright without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&looparrowright"
+                ]
+            ]
+        }, 
+        {
+            "input": "&looparrowright;", 
+            "description": "Named entity: looparrowright; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u21ac"
+                ]
+            ]
+        }, 
+        {
+            "input": "&lopar", 
+            "description": "Bad named entity: lopar without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&lopar"
+                ]
+            ]
+        }, 
+        {
+            "input": "&lopar;", 
+            "description": "Named entity: lopar; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2985"
+                ]
+            ]
+        }, 
+        {
+            "input": "&lopf", 
+            "description": "Bad named entity: lopf without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&lopf"
+                ]
+            ]
+        }, 
+        {
+            "input": "&lopf;", 
+            "description": "Named entity: lopf; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\ud835\udd5d"
+                ]
+            ]
+        }, 
+        {
+            "input": "&loplus", 
+            "description": "Bad named entity: loplus without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&loplus"
+                ]
+            ]
+        }, 
+        {
+            "input": "&loplus;", 
+            "description": "Named entity: loplus; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2a2d"
+                ]
+            ]
+        }, 
+        {
+            "input": "&lotimes", 
+            "description": "Bad named entity: lotimes without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&lotimes"
+                ]
+            ]
+        }, 
+        {
+            "input": "&lotimes;", 
+            "description": "Named entity: lotimes; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2a34"
+                ]
+            ]
+        }, 
+        {
+            "input": "&lowast", 
+            "description": "Bad named entity: lowast without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&lowast"
+                ]
+            ]
+        }, 
+        {
+            "input": "&lowast;", 
+            "description": "Named entity: lowast; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2217"
+                ]
+            ]
+        }, 
+        {
+            "input": "&lowbar", 
+            "description": "Bad named entity: lowbar without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&lowbar"
+                ]
+            ]
+        }, 
+        {
+            "input": "&lowbar;", 
+            "description": "Named entity: lowbar; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "_"
+                ]
+            ]
+        }, 
+        {
+            "input": "&loz", 
+            "description": "Bad named entity: loz without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&loz"
+                ]
+            ]
+        }, 
+        {
+            "input": "&loz;", 
+            "description": "Named entity: loz; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u25ca"
+                ]
+            ]
+        }, 
+        {
+            "input": "&lozenge", 
+            "description": "Bad named entity: lozenge without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&lozenge"
+                ]
+            ]
+        }, 
+        {
+            "input": "&lozenge;", 
+            "description": "Named entity: lozenge; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u25ca"
+                ]
+            ]
+        }, 
+        {
+            "input": "&lozf", 
+            "description": "Bad named entity: lozf without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&lozf"
+                ]
+            ]
+        }, 
+        {
+            "input": "&lozf;", 
+            "description": "Named entity: lozf; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u29eb"
+                ]
+            ]
+        }, 
+        {
+            "input": "&lpar", 
+            "description": "Bad named entity: lpar without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&lpar"
+                ]
+            ]
+        }, 
+        {
+            "input": "&lpar;", 
+            "description": "Named entity: lpar; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "("
+                ]
+            ]
+        }, 
+        {
+            "input": "&lparlt", 
+            "description": "Bad named entity: lparlt without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&lparlt"
+                ]
+            ]
+        }, 
+        {
+            "input": "&lparlt;", 
+            "description": "Named entity: lparlt; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2993"
+                ]
+            ]
+        }, 
+        {
+            "input": "&lrarr", 
+            "description": "Bad named entity: lrarr without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&lrarr"
+                ]
+            ]
+        }, 
+        {
+            "input": "&lrarr;", 
+            "description": "Named entity: lrarr; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u21c6"
+                ]
+            ]
+        }, 
+        {
+            "input": "&lrcorner", 
+            "description": "Bad named entity: lrcorner without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&lrcorner"
+                ]
+            ]
+        }, 
+        {
+            "input": "&lrcorner;", 
+            "description": "Named entity: lrcorner; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u231f"
+                ]
+            ]
+        }, 
+        {
+            "input": "&lrhar", 
+            "description": "Bad named entity: lrhar without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&lrhar"
+                ]
+            ]
+        }, 
+        {
+            "input": "&lrhar;", 
+            "description": "Named entity: lrhar; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u21cb"
+                ]
+            ]
+        }, 
+        {
+            "input": "&lrhard", 
+            "description": "Bad named entity: lrhard without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&lrhard"
+                ]
+            ]
+        }, 
+        {
+            "input": "&lrhard;", 
+            "description": "Named entity: lrhard; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u296d"
+                ]
+            ]
+        }, 
+        {
+            "input": "&lrm", 
+            "description": "Bad named entity: lrm without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&lrm"
+                ]
+            ]
+        }, 
+        {
+            "input": "&lrm;", 
+            "description": "Named entity: lrm; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u200e"
+                ]
+            ]
+        }, 
+        {
+            "input": "&lrtri", 
+            "description": "Bad named entity: lrtri without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&lrtri"
+                ]
+            ]
+        }, 
+        {
+            "input": "&lrtri;", 
+            "description": "Named entity: lrtri; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u22bf"
+                ]
+            ]
+        }, 
+        {
+            "input": "&lsaquo", 
+            "description": "Bad named entity: lsaquo without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&lsaquo"
+                ]
+            ]
+        }, 
+        {
+            "input": "&lsaquo;", 
+            "description": "Named entity: lsaquo; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2039"
+                ]
+            ]
+        }, 
+        {
+            "input": "&lscr", 
+            "description": "Bad named entity: lscr without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&lscr"
+                ]
+            ]
+        }, 
+        {
+            "input": "&lscr;", 
+            "description": "Named entity: lscr; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\ud835\udcc1"
+                ]
+            ]
+        }, 
+        {
+            "input": "&lsh", 
+            "description": "Bad named entity: lsh without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&lsh"
+                ]
+            ]
+        }, 
+        {
+            "input": "&lsh;", 
+            "description": "Named entity: lsh; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u21b0"
+                ]
+            ]
+        }, 
+        {
+            "input": "&lsim", 
+            "description": "Bad named entity: lsim without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&lsim"
+                ]
+            ]
+        }, 
+        {
+            "input": "&lsim;", 
+            "description": "Named entity: lsim; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2272"
+                ]
+            ]
+        }, 
+        {
+            "input": "&lsime", 
+            "description": "Bad named entity: lsime without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&lsime"
+                ]
+            ]
+        }, 
+        {
+            "input": "&lsime;", 
+            "description": "Named entity: lsime; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2a8d"
+                ]
+            ]
+        }, 
+        {
+            "input": "&lsimg", 
+            "description": "Bad named entity: lsimg without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&lsimg"
+                ]
+            ]
+        }, 
+        {
+            "input": "&lsimg;", 
+            "description": "Named entity: lsimg; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2a8f"
+                ]
+            ]
+        }, 
+        {
+            "input": "&lsqb", 
+            "description": "Bad named entity: lsqb without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&lsqb"
+                ]
+            ]
+        }, 
+        {
+            "input": "&lsqb;", 
+            "description": "Named entity: lsqb; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "["
+                ]
+            ]
+        }, 
+        {
+            "input": "&lsquo", 
+            "description": "Bad named entity: lsquo without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&lsquo"
+                ]
+            ]
+        }, 
+        {
+            "input": "&lsquo;", 
+            "description": "Named entity: lsquo; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2018"
+                ]
+            ]
+        }, 
+        {
+            "input": "&lsquor", 
+            "description": "Bad named entity: lsquor without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&lsquor"
+                ]
+            ]
+        }, 
+        {
+            "input": "&lsquor;", 
+            "description": "Named entity: lsquor; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u201a"
+                ]
+            ]
+        }, 
+        {
+            "input": "&lstrok", 
+            "description": "Bad named entity: lstrok without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&lstrok"
+                ]
+            ]
+        }, 
+        {
+            "input": "&lstrok;", 
+            "description": "Named entity: lstrok; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u0142"
+                ]
+            ]
+        }, 
+        {
+            "input": "&lt", 
+            "description": "Named entity: lt without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "<"
+                ]
+            ]
+        }, 
+        {
+            "input": "&lt;", 
+            "description": "Named entity: lt; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "<"
+                ]
+            ]
+        }, 
+        {
+            "input": "&ltcc;", 
+            "description": "Named entity: ltcc; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2aa6"
+                ]
+            ]
+        }, 
+        {
+            "input": "&ltcir;", 
+            "description": "Named entity: ltcir; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2a79"
+                ]
+            ]
+        }, 
+        {
+            "input": "&ltdot;", 
+            "description": "Named entity: ltdot; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u22d6"
+                ]
+            ]
+        }, 
+        {
+            "input": "&lthree;", 
+            "description": "Named entity: lthree; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u22cb"
+                ]
+            ]
+        }, 
+        {
+            "input": "&ltimes;", 
+            "description": "Named entity: ltimes; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u22c9"
+                ]
+            ]
+        }, 
+        {
+            "input": "&ltlarr;", 
+            "description": "Named entity: ltlarr; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2976"
+                ]
+            ]
+        }, 
+        {
+            "input": "&ltquest;", 
+            "description": "Named entity: ltquest; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2a7b"
+                ]
+            ]
+        }, 
+        {
+            "input": "&ltrPar;", 
+            "description": "Named entity: ltrPar; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2996"
+                ]
+            ]
+        }, 
+        {
+            "input": "&ltri;", 
+            "description": "Named entity: ltri; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u25c3"
+                ]
+            ]
+        }, 
+        {
+            "input": "&ltrie;", 
+            "description": "Named entity: ltrie; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u22b4"
+                ]
+            ]
+        }, 
+        {
+            "input": "&ltrif;", 
+            "description": "Named entity: ltrif; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u25c2"
+                ]
+            ]
+        }, 
+        {
+            "input": "&lurdshar", 
+            "description": "Bad named entity: lurdshar without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&lurdshar"
+                ]
+            ]
+        }, 
+        {
+            "input": "&lurdshar;", 
+            "description": "Named entity: lurdshar; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u294a"
+                ]
+            ]
+        }, 
+        {
+            "input": "&luruhar", 
+            "description": "Bad named entity: luruhar without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&luruhar"
+                ]
+            ]
+        }, 
+        {
+            "input": "&luruhar;", 
+            "description": "Named entity: luruhar; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2966"
+                ]
+            ]
+        }, 
+        {
+            "input": "&lvertneqq", 
+            "description": "Bad named entity: lvertneqq without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&lvertneqq"
+                ]
+            ]
+        }, 
+        {
+            "input": "&lvertneqq;", 
+            "description": "Named entity: lvertneqq; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2268\ufe00"
+                ]
+            ]
+        }, 
+        {
+            "input": "&lvnE", 
+            "description": "Bad named entity: lvnE without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&lvnE"
+                ]
+            ]
+        }, 
+        {
+            "input": "&lvnE;", 
+            "description": "Named entity: lvnE; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2268\ufe00"
+                ]
+            ]
+        }, 
+        {
+            "input": "&mDDot", 
+            "description": "Bad named entity: mDDot without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&mDDot"
+                ]
+            ]
+        }, 
+        {
+            "input": "&mDDot;", 
+            "description": "Named entity: mDDot; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u223a"
+                ]
+            ]
+        }, 
+        {
+            "input": "&macr", 
+            "description": "Named entity: macr without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "\u00af"
+                ]
+            ]
+        }, 
+        {
+            "input": "&macr;", 
+            "description": "Named entity: macr; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u00af"
+                ]
+            ]
+        }, 
+        {
+            "input": "&male", 
+            "description": "Bad named entity: male without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&male"
+                ]
+            ]
+        }, 
+        {
+            "input": "&male;", 
+            "description": "Named entity: male; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2642"
+                ]
+            ]
+        }, 
+        {
+            "input": "&malt", 
+            "description": "Bad named entity: malt without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&malt"
+                ]
+            ]
+        }, 
+        {
+            "input": "&malt;", 
+            "description": "Named entity: malt; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2720"
+                ]
+            ]
+        }, 
+        {
+            "input": "&maltese", 
+            "description": "Bad named entity: maltese without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&maltese"
+                ]
+            ]
+        }, 
+        {
+            "input": "&maltese;", 
+            "description": "Named entity: maltese; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2720"
+                ]
+            ]
+        }, 
+        {
+            "input": "&map", 
+            "description": "Bad named entity: map without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&map"
+                ]
+            ]
+        }, 
+        {
+            "input": "&map;", 
+            "description": "Named entity: map; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u21a6"
+                ]
+            ]
+        }, 
+        {
+            "input": "&mapsto", 
+            "description": "Bad named entity: mapsto without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&mapsto"
+                ]
+            ]
+        }, 
+        {
+            "input": "&mapsto;", 
+            "description": "Named entity: mapsto; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u21a6"
+                ]
+            ]
+        }, 
+        {
+            "input": "&mapstodown", 
+            "description": "Bad named entity: mapstodown without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&mapstodown"
+                ]
+            ]
+        }, 
+        {
+            "input": "&mapstodown;", 
+            "description": "Named entity: mapstodown; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u21a7"
+                ]
+            ]
+        }, 
+        {
+            "input": "&mapstoleft", 
+            "description": "Bad named entity: mapstoleft without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&mapstoleft"
+                ]
+            ]
+        }, 
+        {
+            "input": "&mapstoleft;", 
+            "description": "Named entity: mapstoleft; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u21a4"
+                ]
+            ]
+        }, 
+        {
+            "input": "&mapstoup", 
+            "description": "Bad named entity: mapstoup without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&mapstoup"
+                ]
+            ]
+        }, 
+        {
+            "input": "&mapstoup;", 
+            "description": "Named entity: mapstoup; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u21a5"
+                ]
+            ]
+        }, 
+        {
+            "input": "&marker", 
+            "description": "Bad named entity: marker without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&marker"
+                ]
+            ]
+        }, 
+        {
+            "input": "&marker;", 
+            "description": "Named entity: marker; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u25ae"
+                ]
+            ]
+        }, 
+        {
+            "input": "&mcomma", 
+            "description": "Bad named entity: mcomma without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&mcomma"
+                ]
+            ]
+        }, 
+        {
+            "input": "&mcomma;", 
+            "description": "Named entity: mcomma; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2a29"
+                ]
+            ]
+        }, 
+        {
+            "input": "&mcy", 
+            "description": "Bad named entity: mcy without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&mcy"
+                ]
+            ]
+        }, 
+        {
+            "input": "&mcy;", 
+            "description": "Named entity: mcy; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u043c"
+                ]
+            ]
+        }, 
+        {
+            "input": "&mdash", 
+            "description": "Bad named entity: mdash without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&mdash"
+                ]
+            ]
+        }, 
+        {
+            "input": "&mdash;", 
+            "description": "Named entity: mdash; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2014"
+                ]
+            ]
+        }, 
+        {
+            "input": "&measuredangle", 
+            "description": "Bad named entity: measuredangle without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&measuredangle"
+                ]
+            ]
+        }, 
+        {
+            "input": "&measuredangle;", 
+            "description": "Named entity: measuredangle; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2221"
+                ]
+            ]
+        }, 
+        {
+            "input": "&mfr", 
+            "description": "Bad named entity: mfr without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&mfr"
+                ]
+            ]
+        }, 
+        {
+            "input": "&mfr;", 
+            "description": "Named entity: mfr; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\ud835\udd2a"
+                ]
+            ]
+        }, 
+        {
+            "input": "&mho", 
+            "description": "Bad named entity: mho without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&mho"
+                ]
+            ]
+        }, 
+        {
+            "input": "&mho;", 
+            "description": "Named entity: mho; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2127"
+                ]
+            ]
+        }, 
+        {
+            "input": "&micro", 
+            "description": "Named entity: micro without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "\u00b5"
+                ]
+            ]
+        }, 
+        {
+            "input": "&micro;", 
+            "description": "Named entity: micro; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u00b5"
+                ]
+            ]
+        }, 
+        {
+            "input": "&mid", 
+            "description": "Bad named entity: mid without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&mid"
+                ]
+            ]
+        }, 
+        {
+            "input": "&mid;", 
+            "description": "Named entity: mid; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2223"
+                ]
+            ]
+        }, 
+        {
+            "input": "&midast", 
+            "description": "Bad named entity: midast without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&midast"
+                ]
+            ]
+        }, 
+        {
+            "input": "&midast;", 
+            "description": "Named entity: midast; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "*"
+                ]
+            ]
+        }, 
+        {
+            "input": "&midcir", 
+            "description": "Bad named entity: midcir without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&midcir"
+                ]
+            ]
+        }, 
+        {
+            "input": "&midcir;", 
+            "description": "Named entity: midcir; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2af0"
+                ]
+            ]
+        }, 
+        {
+            "input": "&middot", 
+            "description": "Named entity: middot without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "\u00b7"
+                ]
+            ]
+        }, 
+        {
+            "input": "&middot;", 
+            "description": "Named entity: middot; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u00b7"
+                ]
+            ]
+        }, 
+        {
+            "input": "&minus", 
+            "description": "Bad named entity: minus without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&minus"
+                ]
+            ]
+        }, 
+        {
+            "input": "&minus;", 
+            "description": "Named entity: minus; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2212"
+                ]
+            ]
+        }, 
+        {
+            "input": "&minusb", 
+            "description": "Bad named entity: minusb without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&minusb"
+                ]
+            ]
+        }, 
+        {
+            "input": "&minusb;", 
+            "description": "Named entity: minusb; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u229f"
+                ]
+            ]
+        }, 
+        {
+            "input": "&minusd", 
+            "description": "Bad named entity: minusd without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&minusd"
+                ]
+            ]
+        }, 
+        {
+            "input": "&minusd;", 
+            "description": "Named entity: minusd; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2238"
+                ]
+            ]
+        }, 
+        {
+            "input": "&minusdu", 
+            "description": "Bad named entity: minusdu without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&minusdu"
+                ]
+            ]
+        }, 
+        {
+            "input": "&minusdu;", 
+            "description": "Named entity: minusdu; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2a2a"
+                ]
+            ]
+        }, 
+        {
+            "input": "&mlcp", 
+            "description": "Bad named entity: mlcp without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&mlcp"
+                ]
+            ]
+        }, 
+        {
+            "input": "&mlcp;", 
+            "description": "Named entity: mlcp; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2adb"
+                ]
+            ]
+        }, 
+        {
+            "input": "&mldr", 
+            "description": "Bad named entity: mldr without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&mldr"
+                ]
+            ]
+        }, 
+        {
+            "input": "&mldr;", 
+            "description": "Named entity: mldr; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2026"
+                ]
+            ]
+        }, 
+        {
+            "input": "&mnplus", 
+            "description": "Bad named entity: mnplus without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&mnplus"
+                ]
+            ]
+        }, 
+        {
+            "input": "&mnplus;", 
+            "description": "Named entity: mnplus; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2213"
+                ]
+            ]
+        }, 
+        {
+            "input": "&models", 
+            "description": "Bad named entity: models without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&models"
+                ]
+            ]
+        }, 
+        {
+            "input": "&models;", 
+            "description": "Named entity: models; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u22a7"
+                ]
+            ]
+        }, 
+        {
+            "input": "&mopf", 
+            "description": "Bad named entity: mopf without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&mopf"
+                ]
+            ]
+        }, 
+        {
+            "input": "&mopf;", 
+            "description": "Named entity: mopf; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\ud835\udd5e"
+                ]
+            ]
+        }, 
+        {
+            "input": "&mp", 
+            "description": "Bad named entity: mp without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&mp"
+                ]
+            ]
+        }, 
+        {
+            "input": "&mp;", 
+            "description": "Named entity: mp; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2213"
+                ]
+            ]
+        }, 
+        {
+            "input": "&mscr", 
+            "description": "Bad named entity: mscr without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&mscr"
+                ]
+            ]
+        }, 
+        {
+            "input": "&mscr;", 
+            "description": "Named entity: mscr; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\ud835\udcc2"
+                ]
+            ]
+        }, 
+        {
+            "input": "&mstpos", 
+            "description": "Bad named entity: mstpos without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&mstpos"
+                ]
+            ]
+        }, 
+        {
+            "input": "&mstpos;", 
+            "description": "Named entity: mstpos; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u223e"
+                ]
+            ]
+        }, 
+        {
+            "input": "&mu", 
+            "description": "Bad named entity: mu without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&mu"
+                ]
+            ]
+        }, 
+        {
+            "input": "&mu;", 
+            "description": "Named entity: mu; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u03bc"
+                ]
+            ]
+        }, 
+        {
+            "input": "&multimap", 
+            "description": "Bad named entity: multimap without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&multimap"
+                ]
+            ]
+        }, 
+        {
+            "input": "&multimap;", 
+            "description": "Named entity: multimap; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u22b8"
+                ]
+            ]
+        }, 
+        {
+            "input": "&mumap", 
+            "description": "Bad named entity: mumap without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&mumap"
+                ]
+            ]
+        }, 
+        {
+            "input": "&mumap;", 
+            "description": "Named entity: mumap; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u22b8"
+                ]
+            ]
+        }, 
+        {
+            "input": "&nGg", 
+            "description": "Bad named entity: nGg without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&nGg"
+                ]
+            ]
+        }, 
+        {
+            "input": "&nGg;", 
+            "description": "Named entity: nGg; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u22d9\u0338"
+                ]
+            ]
+        }, 
+        {
+            "input": "&nGt", 
+            "description": "Bad named entity: nGt without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&nGt"
+                ]
+            ]
+        }, 
+        {
+            "input": "&nGt;", 
+            "description": "Named entity: nGt; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u226b\u20d2"
+                ]
+            ]
+        }, 
+        {
+            "input": "&nGtv", 
+            "description": "Bad named entity: nGtv without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&nGtv"
+                ]
+            ]
+        }, 
+        {
+            "input": "&nGtv;", 
+            "description": "Named entity: nGtv; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u226b\u0338"
+                ]
+            ]
+        }, 
+        {
+            "input": "&nLeftarrow", 
+            "description": "Bad named entity: nLeftarrow without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&nLeftarrow"
+                ]
+            ]
+        }, 
+        {
+            "input": "&nLeftarrow;", 
+            "description": "Named entity: nLeftarrow; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u21cd"
+                ]
+            ]
+        }, 
+        {
+            "input": "&nLeftrightarrow", 
+            "description": "Bad named entity: nLeftrightarrow without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&nLeftrightarrow"
+                ]
+            ]
+        }, 
+        {
+            "input": "&nLeftrightarrow;", 
+            "description": "Named entity: nLeftrightarrow; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u21ce"
+                ]
+            ]
+        }, 
+        {
+            "input": "&nLl", 
+            "description": "Bad named entity: nLl without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&nLl"
+                ]
+            ]
+        }, 
+        {
+            "input": "&nLl;", 
+            "description": "Named entity: nLl; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u22d8\u0338"
+                ]
+            ]
+        }, 
+        {
+            "input": "&nLt", 
+            "description": "Bad named entity: nLt without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&nLt"
+                ]
+            ]
+        }, 
+        {
+            "input": "&nLt;", 
+            "description": "Named entity: nLt; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u226a\u20d2"
+                ]
+            ]
+        }, 
+        {
+            "input": "&nLtv", 
+            "description": "Bad named entity: nLtv without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&nLtv"
+                ]
+            ]
+        }, 
+        {
+            "input": "&nLtv;", 
+            "description": "Named entity: nLtv; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u226a\u0338"
+                ]
+            ]
+        }, 
+        {
+            "input": "&nRightarrow", 
+            "description": "Bad named entity: nRightarrow without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&nRightarrow"
+                ]
+            ]
+        }, 
+        {
+            "input": "&nRightarrow;", 
+            "description": "Named entity: nRightarrow; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u21cf"
+                ]
+            ]
+        }, 
+        {
+            "input": "&nVDash", 
+            "description": "Bad named entity: nVDash without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&nVDash"
+                ]
+            ]
+        }, 
+        {
+            "input": "&nVDash;", 
+            "description": "Named entity: nVDash; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u22af"
+                ]
+            ]
+        }, 
+        {
+            "input": "&nVdash", 
+            "description": "Bad named entity: nVdash without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&nVdash"
+                ]
+            ]
+        }, 
+        {
+            "input": "&nVdash;", 
+            "description": "Named entity: nVdash; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u22ae"
+                ]
+            ]
+        }, 
+        {
+            "input": "&nabla", 
+            "description": "Bad named entity: nabla without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&nabla"
+                ]
+            ]
+        }, 
+        {
+            "input": "&nabla;", 
+            "description": "Named entity: nabla; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2207"
+                ]
+            ]
+        }, 
+        {
+            "input": "&nacute", 
+            "description": "Bad named entity: nacute without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&nacute"
+                ]
+            ]
+        }, 
+        {
+            "input": "&nacute;", 
+            "description": "Named entity: nacute; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u0144"
+                ]
+            ]
+        }, 
+        {
+            "input": "&nang", 
+            "description": "Bad named entity: nang without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&nang"
+                ]
+            ]
+        }, 
+        {
+            "input": "&nang;", 
+            "description": "Named entity: nang; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2220\u20d2"
+                ]
+            ]
+        }, 
+        {
+            "input": "&nap", 
+            "description": "Bad named entity: nap without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&nap"
+                ]
+            ]
+        }, 
+        {
+            "input": "&nap;", 
+            "description": "Named entity: nap; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2249"
+                ]
+            ]
+        }, 
+        {
+            "input": "&napE", 
+            "description": "Bad named entity: napE without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&napE"
+                ]
+            ]
+        }, 
+        {
+            "input": "&napE;", 
+            "description": "Named entity: napE; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2a70\u0338"
+                ]
+            ]
+        }, 
+        {
+            "input": "&napid", 
+            "description": "Bad named entity: napid without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&napid"
+                ]
+            ]
+        }, 
+        {
+            "input": "&napid;", 
+            "description": "Named entity: napid; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u224b\u0338"
+                ]
+            ]
+        }, 
+        {
+            "input": "&napos", 
+            "description": "Bad named entity: napos without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&napos"
+                ]
+            ]
+        }, 
+        {
+            "input": "&napos;", 
+            "description": "Named entity: napos; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u0149"
+                ]
+            ]
+        }, 
+        {
+            "input": "&napprox", 
+            "description": "Bad named entity: napprox without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&napprox"
+                ]
+            ]
+        }, 
+        {
+            "input": "&napprox;", 
+            "description": "Named entity: napprox; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2249"
+                ]
+            ]
+        }, 
+        {
+            "input": "&natur", 
+            "description": "Bad named entity: natur without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&natur"
+                ]
+            ]
+        }, 
+        {
+            "input": "&natur;", 
+            "description": "Named entity: natur; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u266e"
+                ]
+            ]
+        }, 
+        {
+            "input": "&natural", 
+            "description": "Bad named entity: natural without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&natural"
+                ]
+            ]
+        }, 
+        {
+            "input": "&natural;", 
+            "description": "Named entity: natural; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u266e"
+                ]
+            ]
+        }, 
+        {
+            "input": "&naturals", 
+            "description": "Bad named entity: naturals without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&naturals"
+                ]
+            ]
+        }, 
+        {
+            "input": "&naturals;", 
+            "description": "Named entity: naturals; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2115"
+                ]
+            ]
+        }, 
+        {
+            "input": "&nbsp", 
+            "description": "Named entity: nbsp without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "\u00a0"
+                ]
+            ]
+        }, 
+        {
+            "input": "&nbsp;", 
+            "description": "Named entity: nbsp; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u00a0"
+                ]
+            ]
+        }, 
+        {
+            "input": "&nbump", 
+            "description": "Bad named entity: nbump without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&nbump"
+                ]
+            ]
+        }, 
+        {
+            "input": "&nbump;", 
+            "description": "Named entity: nbump; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u224e\u0338"
+                ]
+            ]
+        }, 
+        {
+            "input": "&nbumpe", 
+            "description": "Bad named entity: nbumpe without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&nbumpe"
+                ]
+            ]
+        }, 
+        {
+            "input": "&nbumpe;", 
+            "description": "Named entity: nbumpe; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u224f\u0338"
+                ]
+            ]
+        }, 
+        {
+            "input": "&ncap", 
+            "description": "Bad named entity: ncap without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&ncap"
+                ]
+            ]
+        }, 
+        {
+            "input": "&ncap;", 
+            "description": "Named entity: ncap; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2a43"
+                ]
+            ]
+        }, 
+        {
+            "input": "&ncaron", 
+            "description": "Bad named entity: ncaron without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&ncaron"
+                ]
+            ]
+        }, 
+        {
+            "input": "&ncaron;", 
+            "description": "Named entity: ncaron; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u0148"
+                ]
+            ]
+        }, 
+        {
+            "input": "&ncedil", 
+            "description": "Bad named entity: ncedil without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&ncedil"
+                ]
+            ]
+        }, 
+        {
+            "input": "&ncedil;", 
+            "description": "Named entity: ncedil; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u0146"
+                ]
+            ]
+        }, 
+        {
+            "input": "&ncong", 
+            "description": "Bad named entity: ncong without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&ncong"
+                ]
+            ]
+        }, 
+        {
+            "input": "&ncong;", 
+            "description": "Named entity: ncong; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2247"
+                ]
+            ]
+        }, 
+        {
+            "input": "&ncongdot", 
+            "description": "Bad named entity: ncongdot without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&ncongdot"
+                ]
+            ]
+        }, 
+        {
+            "input": "&ncongdot;", 
+            "description": "Named entity: ncongdot; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2a6d\u0338"
+                ]
+            ]
+        }, 
+        {
+            "input": "&ncup", 
+            "description": "Bad named entity: ncup without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&ncup"
+                ]
+            ]
+        }, 
+        {
+            "input": "&ncup;", 
+            "description": "Named entity: ncup; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2a42"
+                ]
+            ]
+        }, 
+        {
+            "input": "&ncy", 
+            "description": "Bad named entity: ncy without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&ncy"
+                ]
+            ]
+        }, 
+        {
+            "input": "&ncy;", 
+            "description": "Named entity: ncy; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u043d"
+                ]
+            ]
+        }, 
+        {
+            "input": "&ndash", 
+            "description": "Bad named entity: ndash without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&ndash"
+                ]
+            ]
+        }, 
+        {
+            "input": "&ndash;", 
+            "description": "Named entity: ndash; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2013"
+                ]
+            ]
+        }, 
+        {
+            "input": "&ne", 
+            "description": "Bad named entity: ne without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&ne"
+                ]
+            ]
+        }, 
+        {
+            "input": "&ne;", 
+            "description": "Named entity: ne; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2260"
+                ]
+            ]
+        }, 
+        {
+            "input": "&neArr", 
+            "description": "Bad named entity: neArr without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&neArr"
+                ]
+            ]
+        }, 
+        {
+            "input": "&neArr;", 
+            "description": "Named entity: neArr; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u21d7"
+                ]
+            ]
+        }, 
+        {
+            "input": "&nearhk", 
+            "description": "Bad named entity: nearhk without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&nearhk"
+                ]
+            ]
+        }, 
+        {
+            "input": "&nearhk;", 
+            "description": "Named entity: nearhk; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2924"
+                ]
+            ]
+        }, 
+        {
+            "input": "&nearr", 
+            "description": "Bad named entity: nearr without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&nearr"
+                ]
+            ]
+        }, 
+        {
+            "input": "&nearr;", 
+            "description": "Named entity: nearr; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2197"
+                ]
+            ]
+        }, 
+        {
+            "input": "&nearrow", 
+            "description": "Bad named entity: nearrow without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&nearrow"
+                ]
+            ]
+        }, 
+        {
+            "input": "&nearrow;", 
+            "description": "Named entity: nearrow; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2197"
+                ]
+            ]
+        }, 
+        {
+            "input": "&nedot", 
+            "description": "Bad named entity: nedot without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&nedot"
+                ]
+            ]
+        }, 
+        {
+            "input": "&nedot;", 
+            "description": "Named entity: nedot; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2250\u0338"
+                ]
+            ]
+        }, 
+        {
+            "input": "&nequiv", 
+            "description": "Bad named entity: nequiv without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&nequiv"
+                ]
+            ]
+        }, 
+        {
+            "input": "&nequiv;", 
+            "description": "Named entity: nequiv; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2262"
+                ]
+            ]
+        }, 
+        {
+            "input": "&nesear", 
+            "description": "Bad named entity: nesear without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&nesear"
+                ]
+            ]
+        }, 
+        {
+            "input": "&nesear;", 
+            "description": "Named entity: nesear; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2928"
+                ]
+            ]
+        }, 
+        {
+            "input": "&nesim", 
+            "description": "Bad named entity: nesim without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&nesim"
+                ]
+            ]
+        }, 
+        {
+            "input": "&nesim;", 
+            "description": "Named entity: nesim; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2242\u0338"
+                ]
+            ]
+        }, 
+        {
+            "input": "&nexist", 
+            "description": "Bad named entity: nexist without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&nexist"
+                ]
+            ]
+        }, 
+        {
+            "input": "&nexist;", 
+            "description": "Named entity: nexist; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2204"
+                ]
+            ]
+        }, 
+        {
+            "input": "&nexists", 
+            "description": "Bad named entity: nexists without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&nexists"
+                ]
+            ]
+        }, 
+        {
+            "input": "&nexists;", 
+            "description": "Named entity: nexists; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2204"
+                ]
+            ]
+        }, 
+        {
+            "input": "&nfr", 
+            "description": "Bad named entity: nfr without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&nfr"
+                ]
+            ]
+        }, 
+        {
+            "input": "&nfr;", 
+            "description": "Named entity: nfr; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\ud835\udd2b"
+                ]
+            ]
+        }, 
+        {
+            "input": "&ngE", 
+            "description": "Bad named entity: ngE without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&ngE"
+                ]
+            ]
+        }, 
+        {
+            "input": "&ngE;", 
+            "description": "Named entity: ngE; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2267\u0338"
+                ]
+            ]
+        }, 
+        {
+            "input": "&nge", 
+            "description": "Bad named entity: nge without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&nge"
+                ]
+            ]
+        }, 
+        {
+            "input": "&nge;", 
+            "description": "Named entity: nge; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2271"
+                ]
+            ]
+        }, 
+        {
+            "input": "&ngeq", 
+            "description": "Bad named entity: ngeq without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&ngeq"
+                ]
+            ]
+        }, 
+        {
+            "input": "&ngeq;", 
+            "description": "Named entity: ngeq; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2271"
+                ]
+            ]
+        }, 
+        {
+            "input": "&ngeqq", 
+            "description": "Bad named entity: ngeqq without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&ngeqq"
+                ]
+            ]
+        }, 
+        {
+            "input": "&ngeqq;", 
+            "description": "Named entity: ngeqq; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2267\u0338"
+                ]
+            ]
+        }, 
+        {
+            "input": "&ngeqslant", 
+            "description": "Bad named entity: ngeqslant without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&ngeqslant"
+                ]
+            ]
+        }, 
+        {
+            "input": "&ngeqslant;", 
+            "description": "Named entity: ngeqslant; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2a7e\u0338"
+                ]
+            ]
+        }, 
+        {
+            "input": "&nges", 
+            "description": "Bad named entity: nges without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&nges"
+                ]
+            ]
+        }, 
+        {
+            "input": "&nges;", 
+            "description": "Named entity: nges; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2a7e\u0338"
+                ]
+            ]
+        }, 
+        {
+            "input": "&ngsim", 
+            "description": "Bad named entity: ngsim without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&ngsim"
+                ]
+            ]
+        }, 
+        {
+            "input": "&ngsim;", 
+            "description": "Named entity: ngsim; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2275"
+                ]
+            ]
+        }, 
+        {
+            "input": "&ngt", 
+            "description": "Bad named entity: ngt without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&ngt"
+                ]
+            ]
+        }, 
+        {
+            "input": "&ngt;", 
+            "description": "Named entity: ngt; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u226f"
+                ]
+            ]
+        }, 
+        {
+            "input": "&ngtr", 
+            "description": "Bad named entity: ngtr without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&ngtr"
+                ]
+            ]
+        }, 
+        {
+            "input": "&ngtr;", 
+            "description": "Named entity: ngtr; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u226f"
+                ]
+            ]
+        }, 
+        {
+            "input": "&nhArr", 
+            "description": "Bad named entity: nhArr without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&nhArr"
+                ]
+            ]
+        }, 
+        {
+            "input": "&nhArr;", 
+            "description": "Named entity: nhArr; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u21ce"
+                ]
+            ]
+        }, 
+        {
+            "input": "&nharr", 
+            "description": "Bad named entity: nharr without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&nharr"
+                ]
+            ]
+        }, 
+        {
+            "input": "&nharr;", 
+            "description": "Named entity: nharr; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u21ae"
+                ]
+            ]
+        }, 
+        {
+            "input": "&nhpar", 
+            "description": "Bad named entity: nhpar without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&nhpar"
+                ]
+            ]
+        }, 
+        {
+            "input": "&nhpar;", 
+            "description": "Named entity: nhpar; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2af2"
+                ]
+            ]
+        }, 
+        {
+            "input": "&ni", 
+            "description": "Bad named entity: ni without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&ni"
+                ]
+            ]
+        }, 
+        {
+            "input": "&ni;", 
+            "description": "Named entity: ni; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u220b"
+                ]
+            ]
+        }, 
+        {
+            "input": "&nis", 
+            "description": "Bad named entity: nis without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&nis"
+                ]
+            ]
+        }, 
+        {
+            "input": "&nis;", 
+            "description": "Named entity: nis; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u22fc"
+                ]
+            ]
+        }, 
+        {
+            "input": "&nisd", 
+            "description": "Bad named entity: nisd without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&nisd"
+                ]
+            ]
+        }, 
+        {
+            "input": "&nisd;", 
+            "description": "Named entity: nisd; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u22fa"
+                ]
+            ]
+        }, 
+        {
+            "input": "&niv", 
+            "description": "Bad named entity: niv without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&niv"
+                ]
+            ]
+        }, 
+        {
+            "input": "&niv;", 
+            "description": "Named entity: niv; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u220b"
+                ]
+            ]
+        }, 
+        {
+            "input": "&njcy", 
+            "description": "Bad named entity: njcy without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&njcy"
+                ]
+            ]
+        }, 
+        {
+            "input": "&njcy;", 
+            "description": "Named entity: njcy; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u045a"
+                ]
+            ]
+        }, 
+        {
+            "input": "&nlArr", 
+            "description": "Bad named entity: nlArr without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&nlArr"
+                ]
+            ]
+        }, 
+        {
+            "input": "&nlArr;", 
+            "description": "Named entity: nlArr; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u21cd"
+                ]
+            ]
+        }, 
+        {
+            "input": "&nlE", 
+            "description": "Bad named entity: nlE without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&nlE"
+                ]
+            ]
+        }, 
+        {
+            "input": "&nlE;", 
+            "description": "Named entity: nlE; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2266\u0338"
+                ]
+            ]
+        }, 
+        {
+            "input": "&nlarr", 
+            "description": "Bad named entity: nlarr without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&nlarr"
+                ]
+            ]
+        }, 
+        {
+            "input": "&nlarr;", 
+            "description": "Named entity: nlarr; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u219a"
+                ]
+            ]
+        }, 
+        {
+            "input": "&nldr", 
+            "description": "Bad named entity: nldr without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&nldr"
+                ]
+            ]
+        }, 
+        {
+            "input": "&nldr;", 
+            "description": "Named entity: nldr; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2025"
+                ]
+            ]
+        }, 
+        {
+            "input": "&nle", 
+            "description": "Bad named entity: nle without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&nle"
+                ]
+            ]
+        }, 
+        {
+            "input": "&nle;", 
+            "description": "Named entity: nle; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2270"
+                ]
+            ]
+        }, 
+        {
+            "input": "&nleftarrow", 
+            "description": "Bad named entity: nleftarrow without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&nleftarrow"
+                ]
+            ]
+        }, 
+        {
+            "input": "&nleftarrow;", 
+            "description": "Named entity: nleftarrow; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u219a"
+                ]
+            ]
+        }, 
+        {
+            "input": "&nleftrightarrow", 
+            "description": "Bad named entity: nleftrightarrow without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&nleftrightarrow"
+                ]
+            ]
+        }, 
+        {
+            "input": "&nleftrightarrow;", 
+            "description": "Named entity: nleftrightarrow; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u21ae"
+                ]
+            ]
+        }, 
+        {
+            "input": "&nleq", 
+            "description": "Bad named entity: nleq without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&nleq"
+                ]
+            ]
+        }, 
+        {
+            "input": "&nleq;", 
+            "description": "Named entity: nleq; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2270"
+                ]
+            ]
+        }, 
+        {
+            "input": "&nleqq", 
+            "description": "Bad named entity: nleqq without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&nleqq"
+                ]
+            ]
+        }, 
+        {
+            "input": "&nleqq;", 
+            "description": "Named entity: nleqq; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2266\u0338"
+                ]
+            ]
+        }, 
+        {
+            "input": "&nleqslant", 
+            "description": "Bad named entity: nleqslant without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&nleqslant"
+                ]
+            ]
+        }, 
+        {
+            "input": "&nleqslant;", 
+            "description": "Named entity: nleqslant; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2a7d\u0338"
+                ]
+            ]
+        }, 
+        {
+            "input": "&nles", 
+            "description": "Bad named entity: nles without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&nles"
+                ]
+            ]
+        }, 
+        {
+            "input": "&nles;", 
+            "description": "Named entity: nles; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2a7d\u0338"
+                ]
+            ]
+        }, 
+        {
+            "input": "&nless", 
+            "description": "Bad named entity: nless without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&nless"
+                ]
+            ]
+        }, 
+        {
+            "input": "&nless;", 
+            "description": "Named entity: nless; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u226e"
+                ]
+            ]
+        }, 
+        {
+            "input": "&nlsim", 
+            "description": "Bad named entity: nlsim without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&nlsim"
+                ]
+            ]
+        }, 
+        {
+            "input": "&nlsim;", 
+            "description": "Named entity: nlsim; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2274"
+                ]
+            ]
+        }, 
+        {
+            "input": "&nlt", 
+            "description": "Bad named entity: nlt without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&nlt"
+                ]
+            ]
+        }, 
+        {
+            "input": "&nlt;", 
+            "description": "Named entity: nlt; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u226e"
+                ]
+            ]
+        }, 
+        {
+            "input": "&nltri", 
+            "description": "Bad named entity: nltri without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&nltri"
+                ]
+            ]
+        }, 
+        {
+            "input": "&nltri;", 
+            "description": "Named entity: nltri; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u22ea"
+                ]
+            ]
+        }, 
+        {
+            "input": "&nltrie", 
+            "description": "Bad named entity: nltrie without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&nltrie"
+                ]
+            ]
+        }, 
+        {
+            "input": "&nltrie;", 
+            "description": "Named entity: nltrie; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u22ec"
+                ]
+            ]
+        }, 
+        {
+            "input": "&nmid", 
+            "description": "Bad named entity: nmid without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&nmid"
+                ]
+            ]
+        }, 
+        {
+            "input": "&nmid;", 
+            "description": "Named entity: nmid; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2224"
+                ]
+            ]
+        }, 
+        {
+            "input": "&nopf", 
+            "description": "Bad named entity: nopf without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&nopf"
+                ]
+            ]
+        }, 
+        {
+            "input": "&nopf;", 
+            "description": "Named entity: nopf; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\ud835\udd5f"
+                ]
+            ]
+        }, 
+        {
+            "input": "&not", 
+            "description": "Named entity: not without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "\u00ac"
+                ]
+            ]
+        }, 
+        {
+            "input": "&not;", 
+            "description": "Named entity: not; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u00ac"
+                ]
+            ]
+        }, 
+        {
+            "input": "&notin;", 
+            "description": "Named entity: notin; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2209"
+                ]
+            ]
+        }, 
+        {
+            "input": "&notinE;", 
+            "description": "Named entity: notinE; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u22f9\u0338"
+                ]
+            ]
+        }, 
+        {
+            "input": "&notindot;", 
+            "description": "Named entity: notindot; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u22f5\u0338"
+                ]
+            ]
+        }, 
+        {
+            "input": "&notinva;", 
+            "description": "Named entity: notinva; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2209"
+                ]
+            ]
+        }, 
+        {
+            "input": "&notinvb;", 
+            "description": "Named entity: notinvb; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u22f7"
+                ]
+            ]
+        }, 
+        {
+            "input": "&notinvc;", 
+            "description": "Named entity: notinvc; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u22f6"
+                ]
+            ]
+        }, 
+        {
+            "input": "&notni;", 
+            "description": "Named entity: notni; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u220c"
+                ]
+            ]
+        }, 
+        {
+            "input": "&notniva;", 
+            "description": "Named entity: notniva; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u220c"
+                ]
+            ]
+        }, 
+        {
+            "input": "&notnivb;", 
+            "description": "Named entity: notnivb; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u22fe"
+                ]
+            ]
+        }, 
+        {
+            "input": "&notnivc;", 
+            "description": "Named entity: notnivc; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u22fd"
+                ]
+            ]
+        }, 
+        {
+            "input": "&npar", 
+            "description": "Bad named entity: npar without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&npar"
+                ]
+            ]
+        }, 
+        {
+            "input": "&npar;", 
+            "description": "Named entity: npar; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2226"
+                ]
+            ]
+        }, 
+        {
+            "input": "&nparallel", 
+            "description": "Bad named entity: nparallel without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&nparallel"
+                ]
+            ]
+        }, 
+        {
+            "input": "&nparallel;", 
+            "description": "Named entity: nparallel; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2226"
+                ]
+            ]
+        }, 
+        {
+            "input": "&nparsl", 
+            "description": "Bad named entity: nparsl without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&nparsl"
+                ]
+            ]
+        }, 
+        {
+            "input": "&nparsl;", 
+            "description": "Named entity: nparsl; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2afd\u20e5"
+                ]
+            ]
+        }, 
+        {
+            "input": "&npart", 
+            "description": "Bad named entity: npart without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&npart"
+                ]
+            ]
+        }, 
+        {
+            "input": "&npart;", 
+            "description": "Named entity: npart; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2202\u0338"
+                ]
+            ]
+        }, 
+        {
+            "input": "&npolint", 
+            "description": "Bad named entity: npolint without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&npolint"
+                ]
+            ]
+        }, 
+        {
+            "input": "&npolint;", 
+            "description": "Named entity: npolint; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2a14"
+                ]
+            ]
+        }, 
+        {
+            "input": "&npr", 
+            "description": "Bad named entity: npr without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&npr"
+                ]
+            ]
+        }, 
+        {
+            "input": "&npr;", 
+            "description": "Named entity: npr; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2280"
+                ]
+            ]
+        }, 
+        {
+            "input": "&nprcue", 
+            "description": "Bad named entity: nprcue without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&nprcue"
+                ]
+            ]
+        }, 
+        {
+            "input": "&nprcue;", 
+            "description": "Named entity: nprcue; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u22e0"
+                ]
+            ]
+        }, 
+        {
+            "input": "&npre", 
+            "description": "Bad named entity: npre without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&npre"
+                ]
+            ]
+        }, 
+        {
+            "input": "&npre;", 
+            "description": "Named entity: npre; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2aaf\u0338"
+                ]
+            ]
+        }, 
+        {
+            "input": "&nprec", 
+            "description": "Bad named entity: nprec without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&nprec"
+                ]
+            ]
+        }, 
+        {
+            "input": "&nprec;", 
+            "description": "Named entity: nprec; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2280"
+                ]
+            ]
+        }, 
+        {
+            "input": "&npreceq", 
+            "description": "Bad named entity: npreceq without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&npreceq"
+                ]
+            ]
+        }, 
+        {
+            "input": "&npreceq;", 
+            "description": "Named entity: npreceq; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2aaf\u0338"
+                ]
+            ]
+        }, 
+        {
+            "input": "&nrArr", 
+            "description": "Bad named entity: nrArr without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&nrArr"
+                ]
+            ]
+        }, 
+        {
+            "input": "&nrArr;", 
+            "description": "Named entity: nrArr; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u21cf"
+                ]
+            ]
+        }, 
+        {
+            "input": "&nrarr", 
+            "description": "Bad named entity: nrarr without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&nrarr"
+                ]
+            ]
+        }, 
+        {
+            "input": "&nrarr;", 
+            "description": "Named entity: nrarr; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u219b"
+                ]
+            ]
+        }, 
+        {
+            "input": "&nrarrc", 
+            "description": "Bad named entity: nrarrc without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&nrarrc"
+                ]
+            ]
+        }, 
+        {
+            "input": "&nrarrc;", 
+            "description": "Named entity: nrarrc; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2933\u0338"
+                ]
+            ]
+        }, 
+        {
+            "input": "&nrarrw", 
+            "description": "Bad named entity: nrarrw without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&nrarrw"
+                ]
+            ]
+        }, 
+        {
+            "input": "&nrarrw;", 
+            "description": "Named entity: nrarrw; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u219d\u0338"
+                ]
+            ]
+        }, 
+        {
+            "input": "&nrightarrow", 
+            "description": "Bad named entity: nrightarrow without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&nrightarrow"
+                ]
+            ]
+        }, 
+        {
+            "input": "&nrightarrow;", 
+            "description": "Named entity: nrightarrow; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u219b"
+                ]
+            ]
+        }, 
+        {
+            "input": "&nrtri", 
+            "description": "Bad named entity: nrtri without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&nrtri"
+                ]
+            ]
+        }, 
+        {
+            "input": "&nrtri;", 
+            "description": "Named entity: nrtri; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u22eb"
+                ]
+            ]
+        }, 
+        {
+            "input": "&nrtrie", 
+            "description": "Bad named entity: nrtrie without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&nrtrie"
+                ]
+            ]
+        }, 
+        {
+            "input": "&nrtrie;", 
+            "description": "Named entity: nrtrie; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u22ed"
+                ]
+            ]
+        }, 
+        {
+            "input": "&nsc", 
+            "description": "Bad named entity: nsc without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&nsc"
+                ]
+            ]
+        }, 
+        {
+            "input": "&nsc;", 
+            "description": "Named entity: nsc; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2281"
+                ]
+            ]
+        }, 
+        {
+            "input": "&nsccue", 
+            "description": "Bad named entity: nsccue without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&nsccue"
+                ]
+            ]
+        }, 
+        {
+            "input": "&nsccue;", 
+            "description": "Named entity: nsccue; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u22e1"
+                ]
+            ]
+        }, 
+        {
+            "input": "&nsce", 
+            "description": "Bad named entity: nsce without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&nsce"
+                ]
+            ]
+        }, 
+        {
+            "input": "&nsce;", 
+            "description": "Named entity: nsce; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2ab0\u0338"
+                ]
+            ]
+        }, 
+        {
+            "input": "&nscr", 
+            "description": "Bad named entity: nscr without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&nscr"
+                ]
+            ]
+        }, 
+        {
+            "input": "&nscr;", 
+            "description": "Named entity: nscr; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\ud835\udcc3"
+                ]
+            ]
+        }, 
+        {
+            "input": "&nshortmid", 
+            "description": "Bad named entity: nshortmid without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&nshortmid"
+                ]
+            ]
+        }, 
+        {
+            "input": "&nshortmid;", 
+            "description": "Named entity: nshortmid; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2224"
+                ]
+            ]
+        }, 
+        {
+            "input": "&nshortparallel", 
+            "description": "Bad named entity: nshortparallel without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&nshortparallel"
+                ]
+            ]
+        }, 
+        {
+            "input": "&nshortparallel;", 
+            "description": "Named entity: nshortparallel; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2226"
+                ]
+            ]
+        }, 
+        {
+            "input": "&nsim", 
+            "description": "Bad named entity: nsim without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&nsim"
+                ]
+            ]
+        }, 
+        {
+            "input": "&nsim;", 
+            "description": "Named entity: nsim; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2241"
+                ]
+            ]
+        }, 
+        {
+            "input": "&nsime", 
+            "description": "Bad named entity: nsime without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&nsime"
+                ]
+            ]
+        }, 
+        {
+            "input": "&nsime;", 
+            "description": "Named entity: nsime; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2244"
+                ]
+            ]
+        }, 
+        {
+            "input": "&nsimeq", 
+            "description": "Bad named entity: nsimeq without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&nsimeq"
+                ]
+            ]
+        }, 
+        {
+            "input": "&nsimeq;", 
+            "description": "Named entity: nsimeq; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2244"
+                ]
+            ]
+        }, 
+        {
+            "input": "&nsmid", 
+            "description": "Bad named entity: nsmid without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&nsmid"
+                ]
+            ]
+        }, 
+        {
+            "input": "&nsmid;", 
+            "description": "Named entity: nsmid; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2224"
+                ]
+            ]
+        }, 
+        {
+            "input": "&nspar", 
+            "description": "Bad named entity: nspar without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&nspar"
+                ]
+            ]
+        }, 
+        {
+            "input": "&nspar;", 
+            "description": "Named entity: nspar; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2226"
+                ]
+            ]
+        }, 
+        {
+            "input": "&nsqsube", 
+            "description": "Bad named entity: nsqsube without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&nsqsube"
+                ]
+            ]
+        }, 
+        {
+            "input": "&nsqsube;", 
+            "description": "Named entity: nsqsube; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u22e2"
+                ]
+            ]
+        }, 
+        {
+            "input": "&nsqsupe", 
+            "description": "Bad named entity: nsqsupe without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&nsqsupe"
+                ]
+            ]
+        }, 
+        {
+            "input": "&nsqsupe;", 
+            "description": "Named entity: nsqsupe; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u22e3"
+                ]
+            ]
+        }, 
+        {
+            "input": "&nsub", 
+            "description": "Bad named entity: nsub without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&nsub"
+                ]
+            ]
+        }, 
+        {
+            "input": "&nsub;", 
+            "description": "Named entity: nsub; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2284"
+                ]
+            ]
+        }, 
+        {
+            "input": "&nsubE", 
+            "description": "Bad named entity: nsubE without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&nsubE"
+                ]
+            ]
+        }, 
+        {
+            "input": "&nsubE;", 
+            "description": "Named entity: nsubE; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2ac5\u0338"
+                ]
+            ]
+        }, 
+        {
+            "input": "&nsube", 
+            "description": "Bad named entity: nsube without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&nsube"
+                ]
+            ]
+        }, 
+        {
+            "input": "&nsube;", 
+            "description": "Named entity: nsube; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2288"
+                ]
+            ]
+        }, 
+        {
+            "input": "&nsubset", 
+            "description": "Bad named entity: nsubset without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&nsubset"
+                ]
+            ]
+        }, 
+        {
+            "input": "&nsubset;", 
+            "description": "Named entity: nsubset; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2282\u20d2"
+                ]
+            ]
+        }, 
+        {
+            "input": "&nsubseteq", 
+            "description": "Bad named entity: nsubseteq without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&nsubseteq"
+                ]
+            ]
+        }, 
+        {
+            "input": "&nsubseteq;", 
+            "description": "Named entity: nsubseteq; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2288"
+                ]
+            ]
+        }, 
+        {
+            "input": "&nsubseteqq", 
+            "description": "Bad named entity: nsubseteqq without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&nsubseteqq"
+                ]
+            ]
+        }, 
+        {
+            "input": "&nsubseteqq;", 
+            "description": "Named entity: nsubseteqq; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2ac5\u0338"
+                ]
+            ]
+        }, 
+        {
+            "input": "&nsucc", 
+            "description": "Bad named entity: nsucc without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&nsucc"
+                ]
+            ]
+        }, 
+        {
+            "input": "&nsucc;", 
+            "description": "Named entity: nsucc; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2281"
+                ]
+            ]
+        }, 
+        {
+            "input": "&nsucceq", 
+            "description": "Bad named entity: nsucceq without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&nsucceq"
+                ]
+            ]
+        }, 
+        {
+            "input": "&nsucceq;", 
+            "description": "Named entity: nsucceq; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2ab0\u0338"
+                ]
+            ]
+        }, 
+        {
+            "input": "&nsup", 
+            "description": "Bad named entity: nsup without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&nsup"
+                ]
+            ]
+        }, 
+        {
+            "input": "&nsup;", 
+            "description": "Named entity: nsup; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2285"
+                ]
+            ]
+        }, 
+        {
+            "input": "&nsupE", 
+            "description": "Bad named entity: nsupE without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&nsupE"
+                ]
+            ]
+        }, 
+        {
+            "input": "&nsupE;", 
+            "description": "Named entity: nsupE; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2ac6\u0338"
+                ]
+            ]
+        }, 
+        {
+            "input": "&nsupe", 
+            "description": "Bad named entity: nsupe without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&nsupe"
+                ]
+            ]
+        }, 
+        {
+            "input": "&nsupe;", 
+            "description": "Named entity: nsupe; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2289"
+                ]
+            ]
+        }, 
+        {
+            "input": "&nsupset", 
+            "description": "Bad named entity: nsupset without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&nsupset"
+                ]
+            ]
+        }, 
+        {
+            "input": "&nsupset;", 
+            "description": "Named entity: nsupset; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2283\u20d2"
+                ]
+            ]
+        }, 
+        {
+            "input": "&nsupseteq", 
+            "description": "Bad named entity: nsupseteq without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&nsupseteq"
+                ]
+            ]
+        }, 
+        {
+            "input": "&nsupseteq;", 
+            "description": "Named entity: nsupseteq; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2289"
+                ]
+            ]
+        }, 
+        {
+            "input": "&nsupseteqq", 
+            "description": "Bad named entity: nsupseteqq without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&nsupseteqq"
+                ]
+            ]
+        }, 
+        {
+            "input": "&nsupseteqq;", 
+            "description": "Named entity: nsupseteqq; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2ac6\u0338"
+                ]
+            ]
+        }, 
+        {
+            "input": "&ntgl", 
+            "description": "Bad named entity: ntgl without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&ntgl"
+                ]
+            ]
+        }, 
+        {
+            "input": "&ntgl;", 
+            "description": "Named entity: ntgl; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2279"
+                ]
+            ]
+        }, 
+        {
+            "input": "&ntilde", 
+            "description": "Named entity: ntilde without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "\u00f1"
+                ]
+            ]
+        }, 
+        {
+            "input": "&ntilde;", 
+            "description": "Named entity: ntilde; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u00f1"
+                ]
+            ]
+        }, 
+        {
+            "input": "&ntlg", 
+            "description": "Bad named entity: ntlg without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&ntlg"
+                ]
+            ]
+        }, 
+        {
+            "input": "&ntlg;", 
+            "description": "Named entity: ntlg; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2278"
+                ]
+            ]
+        }, 
+        {
+            "input": "&ntriangleleft", 
+            "description": "Bad named entity: ntriangleleft without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&ntriangleleft"
+                ]
+            ]
+        }, 
+        {
+            "input": "&ntriangleleft;", 
+            "description": "Named entity: ntriangleleft; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u22ea"
+                ]
+            ]
+        }, 
+        {
+            "input": "&ntrianglelefteq", 
+            "description": "Bad named entity: ntrianglelefteq without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&ntrianglelefteq"
+                ]
+            ]
+        }, 
+        {
+            "input": "&ntrianglelefteq;", 
+            "description": "Named entity: ntrianglelefteq; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u22ec"
+                ]
+            ]
+        }, 
+        {
+            "input": "&ntriangleright", 
+            "description": "Bad named entity: ntriangleright without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&ntriangleright"
+                ]
+            ]
+        }, 
+        {
+            "input": "&ntriangleright;", 
+            "description": "Named entity: ntriangleright; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u22eb"
+                ]
+            ]
+        }, 
+        {
+            "input": "&ntrianglerighteq", 
+            "description": "Bad named entity: ntrianglerighteq without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&ntrianglerighteq"
+                ]
+            ]
+        }, 
+        {
+            "input": "&ntrianglerighteq;", 
+            "description": "Named entity: ntrianglerighteq; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u22ed"
+                ]
+            ]
+        }, 
+        {
+            "input": "&nu", 
+            "description": "Bad named entity: nu without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&nu"
+                ]
+            ]
+        }, 
+        {
+            "input": "&nu;", 
+            "description": "Named entity: nu; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u03bd"
+                ]
+            ]
+        }, 
+        {
+            "input": "&num", 
+            "description": "Bad named entity: num without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&num"
+                ]
+            ]
+        }, 
+        {
+            "input": "&num;", 
+            "description": "Named entity: num; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "#"
+                ]
+            ]
+        }, 
+        {
+            "input": "&numero", 
+            "description": "Bad named entity: numero without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&numero"
+                ]
+            ]
+        }, 
+        {
+            "input": "&numero;", 
+            "description": "Named entity: numero; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2116"
+                ]
+            ]
+        }, 
+        {
+            "input": "&numsp", 
+            "description": "Bad named entity: numsp without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&numsp"
+                ]
+            ]
+        }, 
+        {
+            "input": "&numsp;", 
+            "description": "Named entity: numsp; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2007"
+                ]
+            ]
+        }, 
+        {
+            "input": "&nvDash", 
+            "description": "Bad named entity: nvDash without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&nvDash"
+                ]
+            ]
+        }, 
+        {
+            "input": "&nvDash;", 
+            "description": "Named entity: nvDash; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u22ad"
+                ]
+            ]
+        }, 
+        {
+            "input": "&nvHarr", 
+            "description": "Bad named entity: nvHarr without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&nvHarr"
+                ]
+            ]
+        }, 
+        {
+            "input": "&nvHarr;", 
+            "description": "Named entity: nvHarr; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2904"
+                ]
+            ]
+        }, 
+        {
+            "input": "&nvap", 
+            "description": "Bad named entity: nvap without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&nvap"
+                ]
+            ]
+        }, 
+        {
+            "input": "&nvap;", 
+            "description": "Named entity: nvap; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u224d\u20d2"
+                ]
+            ]
+        }, 
+        {
+            "input": "&nvdash", 
+            "description": "Bad named entity: nvdash without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&nvdash"
+                ]
+            ]
+        }, 
+        {
+            "input": "&nvdash;", 
+            "description": "Named entity: nvdash; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u22ac"
+                ]
+            ]
+        }, 
+        {
+            "input": "&nvge", 
+            "description": "Bad named entity: nvge without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&nvge"
+                ]
+            ]
+        }, 
+        {
+            "input": "&nvge;", 
+            "description": "Named entity: nvge; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2265\u20d2"
+                ]
+            ]
+        }, 
+        {
+            "input": "&nvgt", 
+            "description": "Bad named entity: nvgt without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&nvgt"
+                ]
+            ]
+        }, 
+        {
+            "input": "&nvgt;", 
+            "description": "Named entity: nvgt; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    ">\u20d2"
+                ]
+            ]
+        }, 
+        {
+            "input": "&nvinfin", 
+            "description": "Bad named entity: nvinfin without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&nvinfin"
+                ]
+            ]
+        }, 
+        {
+            "input": "&nvinfin;", 
+            "description": "Named entity: nvinfin; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u29de"
+                ]
+            ]
+        }, 
+        {
+            "input": "&nvlArr", 
+            "description": "Bad named entity: nvlArr without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&nvlArr"
+                ]
+            ]
+        }, 
+        {
+            "input": "&nvlArr;", 
+            "description": "Named entity: nvlArr; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2902"
+                ]
+            ]
+        }, 
+        {
+            "input": "&nvle", 
+            "description": "Bad named entity: nvle without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&nvle"
+                ]
+            ]
+        }, 
+        {
+            "input": "&nvle;", 
+            "description": "Named entity: nvle; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2264\u20d2"
+                ]
+            ]
+        }, 
+        {
+            "input": "&nvlt", 
+            "description": "Bad named entity: nvlt without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&nvlt"
+                ]
+            ]
+        }, 
+        {
+            "input": "&nvlt;", 
+            "description": "Named entity: nvlt; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "<\u20d2"
+                ]
+            ]
+        }, 
+        {
+            "input": "&nvltrie", 
+            "description": "Bad named entity: nvltrie without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&nvltrie"
+                ]
+            ]
+        }, 
+        {
+            "input": "&nvltrie;", 
+            "description": "Named entity: nvltrie; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u22b4\u20d2"
+                ]
+            ]
+        }, 
+        {
+            "input": "&nvrArr", 
+            "description": "Bad named entity: nvrArr without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&nvrArr"
+                ]
+            ]
+        }, 
+        {
+            "input": "&nvrArr;", 
+            "description": "Named entity: nvrArr; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2903"
+                ]
+            ]
+        }, 
+        {
+            "input": "&nvrtrie", 
+            "description": "Bad named entity: nvrtrie without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&nvrtrie"
+                ]
+            ]
+        }, 
+        {
+            "input": "&nvrtrie;", 
+            "description": "Named entity: nvrtrie; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u22b5\u20d2"
+                ]
+            ]
+        }, 
+        {
+            "input": "&nvsim", 
+            "description": "Bad named entity: nvsim without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&nvsim"
+                ]
+            ]
+        }, 
+        {
+            "input": "&nvsim;", 
+            "description": "Named entity: nvsim; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u223c\u20d2"
+                ]
+            ]
+        }, 
+        {
+            "input": "&nwArr", 
+            "description": "Bad named entity: nwArr without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&nwArr"
+                ]
+            ]
+        }, 
+        {
+            "input": "&nwArr;", 
+            "description": "Named entity: nwArr; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u21d6"
+                ]
+            ]
+        }, 
+        {
+            "input": "&nwarhk", 
+            "description": "Bad named entity: nwarhk without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&nwarhk"
+                ]
+            ]
+        }, 
+        {
+            "input": "&nwarhk;", 
+            "description": "Named entity: nwarhk; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2923"
+                ]
+            ]
+        }, 
+        {
+            "input": "&nwarr", 
+            "description": "Bad named entity: nwarr without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&nwarr"
+                ]
+            ]
+        }, 
+        {
+            "input": "&nwarr;", 
+            "description": "Named entity: nwarr; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2196"
+                ]
+            ]
+        }, 
+        {
+            "input": "&nwarrow", 
+            "description": "Bad named entity: nwarrow without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&nwarrow"
+                ]
+            ]
+        }, 
+        {
+            "input": "&nwarrow;", 
+            "description": "Named entity: nwarrow; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2196"
+                ]
+            ]
+        }, 
+        {
+            "input": "&nwnear", 
+            "description": "Bad named entity: nwnear without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&nwnear"
+                ]
+            ]
+        }, 
+        {
+            "input": "&nwnear;", 
+            "description": "Named entity: nwnear; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2927"
+                ]
+            ]
+        }, 
+        {
+            "input": "&oS", 
+            "description": "Bad named entity: oS without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&oS"
+                ]
+            ]
+        }, 
+        {
+            "input": "&oS;", 
+            "description": "Named entity: oS; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u24c8"
+                ]
+            ]
+        }, 
+        {
+            "input": "&oacute", 
+            "description": "Named entity: oacute without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "\u00f3"
+                ]
+            ]
+        }, 
+        {
+            "input": "&oacute;", 
+            "description": "Named entity: oacute; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u00f3"
+                ]
+            ]
+        }, 
+        {
+            "input": "&oast", 
+            "description": "Bad named entity: oast without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&oast"
+                ]
+            ]
+        }, 
+        {
+            "input": "&oast;", 
+            "description": "Named entity: oast; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u229b"
+                ]
+            ]
+        }, 
+        {
+            "input": "&ocir", 
+            "description": "Bad named entity: ocir without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&ocir"
+                ]
+            ]
+        }, 
+        {
+            "input": "&ocir;", 
+            "description": "Named entity: ocir; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u229a"
+                ]
+            ]
+        }, 
+        {
+            "input": "&ocirc", 
+            "description": "Named entity: ocirc without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "\u00f4"
+                ]
+            ]
+        }, 
+        {
+            "input": "&ocirc;", 
+            "description": "Named entity: ocirc; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u00f4"
+                ]
+            ]
+        }, 
+        {
+            "input": "&ocy", 
+            "description": "Bad named entity: ocy without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&ocy"
+                ]
+            ]
+        }, 
+        {
+            "input": "&ocy;", 
+            "description": "Named entity: ocy; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u043e"
+                ]
+            ]
+        }, 
+        {
+            "input": "&odash", 
+            "description": "Bad named entity: odash without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&odash"
+                ]
+            ]
+        }, 
+        {
+            "input": "&odash;", 
+            "description": "Named entity: odash; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u229d"
+                ]
+            ]
+        }, 
+        {
+            "input": "&odblac", 
+            "description": "Bad named entity: odblac without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&odblac"
+                ]
+            ]
+        }, 
+        {
+            "input": "&odblac;", 
+            "description": "Named entity: odblac; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u0151"
+                ]
+            ]
+        }, 
+        {
+            "input": "&odiv", 
+            "description": "Bad named entity: odiv without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&odiv"
+                ]
+            ]
+        }, 
+        {
+            "input": "&odiv;", 
+            "description": "Named entity: odiv; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2a38"
+                ]
+            ]
+        }, 
+        {
+            "input": "&odot", 
+            "description": "Bad named entity: odot without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&odot"
+                ]
+            ]
+        }, 
+        {
+            "input": "&odot;", 
+            "description": "Named entity: odot; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2299"
+                ]
+            ]
+        }, 
+        {
+            "input": "&odsold", 
+            "description": "Bad named entity: odsold without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&odsold"
+                ]
+            ]
+        }, 
+        {
+            "input": "&odsold;", 
+            "description": "Named entity: odsold; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u29bc"
+                ]
+            ]
+        }, 
+        {
+            "input": "&oelig", 
+            "description": "Bad named entity: oelig without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&oelig"
+                ]
+            ]
+        }, 
+        {
+            "input": "&oelig;", 
+            "description": "Named entity: oelig; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u0153"
+                ]
+            ]
+        }, 
+        {
+            "input": "&ofcir", 
+            "description": "Bad named entity: ofcir without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&ofcir"
+                ]
+            ]
+        }, 
+        {
+            "input": "&ofcir;", 
+            "description": "Named entity: ofcir; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u29bf"
+                ]
+            ]
+        }, 
+        {
+            "input": "&ofr", 
+            "description": "Bad named entity: ofr without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&ofr"
+                ]
+            ]
+        }, 
+        {
+            "input": "&ofr;", 
+            "description": "Named entity: ofr; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\ud835\udd2c"
+                ]
+            ]
+        }, 
+        {
+            "input": "&ogon", 
+            "description": "Bad named entity: ogon without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&ogon"
+                ]
+            ]
+        }, 
+        {
+            "input": "&ogon;", 
+            "description": "Named entity: ogon; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u02db"
+                ]
+            ]
+        }, 
+        {
+            "input": "&ograve", 
+            "description": "Named entity: ograve without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "\u00f2"
+                ]
+            ]
+        }, 
+        {
+            "input": "&ograve;", 
+            "description": "Named entity: ograve; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u00f2"
+                ]
+            ]
+        }, 
+        {
+            "input": "&ogt", 
+            "description": "Bad named entity: ogt without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&ogt"
+                ]
+            ]
+        }, 
+        {
+            "input": "&ogt;", 
+            "description": "Named entity: ogt; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u29c1"
+                ]
+            ]
+        }, 
+        {
+            "input": "&ohbar", 
+            "description": "Bad named entity: ohbar without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&ohbar"
+                ]
+            ]
+        }, 
+        {
+            "input": "&ohbar;", 
+            "description": "Named entity: ohbar; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u29b5"
+                ]
+            ]
+        }, 
+        {
+            "input": "&ohm", 
+            "description": "Bad named entity: ohm without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&ohm"
+                ]
+            ]
+        }, 
+        {
+            "input": "&ohm;", 
+            "description": "Named entity: ohm; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u03a9"
+                ]
+            ]
+        }, 
+        {
+            "input": "&oint", 
+            "description": "Bad named entity: oint without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&oint"
+                ]
+            ]
+        }, 
+        {
+            "input": "&oint;", 
+            "description": "Named entity: oint; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u222e"
+                ]
+            ]
+        }, 
+        {
+            "input": "&olarr", 
+            "description": "Bad named entity: olarr without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&olarr"
+                ]
+            ]
+        }, 
+        {
+            "input": "&olarr;", 
+            "description": "Named entity: olarr; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u21ba"
+                ]
+            ]
+        }, 
+        {
+            "input": "&olcir", 
+            "description": "Bad named entity: olcir without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&olcir"
+                ]
+            ]
+        }, 
+        {
+            "input": "&olcir;", 
+            "description": "Named entity: olcir; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u29be"
+                ]
+            ]
+        }, 
+        {
+            "input": "&olcross", 
+            "description": "Bad named entity: olcross without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&olcross"
+                ]
+            ]
+        }, 
+        {
+            "input": "&olcross;", 
+            "description": "Named entity: olcross; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u29bb"
+                ]
+            ]
+        }, 
+        {
+            "input": "&oline", 
+            "description": "Bad named entity: oline without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&oline"
+                ]
+            ]
+        }, 
+        {
+            "input": "&oline;", 
+            "description": "Named entity: oline; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u203e"
+                ]
+            ]
+        }, 
+        {
+            "input": "&olt", 
+            "description": "Bad named entity: olt without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&olt"
+                ]
+            ]
+        }, 
+        {
+            "input": "&olt;", 
+            "description": "Named entity: olt; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u29c0"
+                ]
+            ]
+        }, 
+        {
+            "input": "&omacr", 
+            "description": "Bad named entity: omacr without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&omacr"
+                ]
+            ]
+        }, 
+        {
+            "input": "&omacr;", 
+            "description": "Named entity: omacr; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u014d"
+                ]
+            ]
+        }, 
+        {
+            "input": "&omega", 
+            "description": "Bad named entity: omega without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&omega"
+                ]
+            ]
+        }, 
+        {
+            "input": "&omega;", 
+            "description": "Named entity: omega; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u03c9"
+                ]
+            ]
+        }, 
+        {
+            "input": "&omicron", 
+            "description": "Bad named entity: omicron without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&omicron"
+                ]
+            ]
+        }, 
+        {
+            "input": "&omicron;", 
+            "description": "Named entity: omicron; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u03bf"
+                ]
+            ]
+        }, 
+        {
+            "input": "&omid", 
+            "description": "Bad named entity: omid without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&omid"
+                ]
+            ]
+        }, 
+        {
+            "input": "&omid;", 
+            "description": "Named entity: omid; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u29b6"
+                ]
+            ]
+        }, 
+        {
+            "input": "&ominus", 
+            "description": "Bad named entity: ominus without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&ominus"
+                ]
+            ]
+        }, 
+        {
+            "input": "&ominus;", 
+            "description": "Named entity: ominus; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2296"
+                ]
+            ]
+        }, 
+        {
+            "input": "&oopf", 
+            "description": "Bad named entity: oopf without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&oopf"
+                ]
+            ]
+        }, 
+        {
+            "input": "&oopf;", 
+            "description": "Named entity: oopf; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\ud835\udd60"
+                ]
+            ]
+        }, 
+        {
+            "input": "&opar", 
+            "description": "Bad named entity: opar without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&opar"
+                ]
+            ]
+        }, 
+        {
+            "input": "&opar;", 
+            "description": "Named entity: opar; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u29b7"
+                ]
+            ]
+        }, 
+        {
+            "input": "&operp", 
+            "description": "Bad named entity: operp without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&operp"
+                ]
+            ]
+        }, 
+        {
+            "input": "&operp;", 
+            "description": "Named entity: operp; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u29b9"
+                ]
+            ]
+        }, 
+        {
+            "input": "&oplus", 
+            "description": "Bad named entity: oplus without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&oplus"
+                ]
+            ]
+        }, 
+        {
+            "input": "&oplus;", 
+            "description": "Named entity: oplus; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2295"
+                ]
+            ]
+        }, 
+        {
+            "input": "&or", 
+            "description": "Bad named entity: or without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&or"
+                ]
+            ]
+        }, 
+        {
+            "input": "&or;", 
+            "description": "Named entity: or; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2228"
+                ]
+            ]
+        }, 
+        {
+            "input": "&orarr", 
+            "description": "Bad named entity: orarr without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&orarr"
+                ]
+            ]
+        }, 
+        {
+            "input": "&orarr;", 
+            "description": "Named entity: orarr; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u21bb"
+                ]
+            ]
+        }, 
+        {
+            "input": "&ord", 
+            "description": "Bad named entity: ord without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&ord"
+                ]
+            ]
+        }, 
+        {
+            "input": "&ord;", 
+            "description": "Named entity: ord; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2a5d"
+                ]
+            ]
+        }, 
+        {
+            "input": "&order", 
+            "description": "Bad named entity: order without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&order"
+                ]
+            ]
+        }, 
+        {
+            "input": "&order;", 
+            "description": "Named entity: order; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2134"
+                ]
+            ]
+        }, 
+        {
+            "input": "&orderof", 
+            "description": "Bad named entity: orderof without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&orderof"
+                ]
+            ]
+        }, 
+        {
+            "input": "&orderof;", 
+            "description": "Named entity: orderof; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2134"
+                ]
+            ]
+        }, 
+        {
+            "input": "&ordf", 
+            "description": "Named entity: ordf without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "\u00aa"
+                ]
+            ]
+        }, 
+        {
+            "input": "&ordf;", 
+            "description": "Named entity: ordf; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u00aa"
+                ]
+            ]
+        }, 
+        {
+            "input": "&ordm", 
+            "description": "Named entity: ordm without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "\u00ba"
+                ]
+            ]
+        }, 
+        {
+            "input": "&ordm;", 
+            "description": "Named entity: ordm; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u00ba"
+                ]
+            ]
+        }, 
+        {
+            "input": "&origof", 
+            "description": "Bad named entity: origof without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&origof"
+                ]
+            ]
+        }, 
+        {
+            "input": "&origof;", 
+            "description": "Named entity: origof; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u22b6"
+                ]
+            ]
+        }, 
+        {
+            "input": "&oror", 
+            "description": "Bad named entity: oror without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&oror"
+                ]
+            ]
+        }, 
+        {
+            "input": "&oror;", 
+            "description": "Named entity: oror; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2a56"
+                ]
+            ]
+        }, 
+        {
+            "input": "&orslope", 
+            "description": "Bad named entity: orslope without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&orslope"
+                ]
+            ]
+        }, 
+        {
+            "input": "&orslope;", 
+            "description": "Named entity: orslope; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2a57"
+                ]
+            ]
+        }, 
+        {
+            "input": "&orv", 
+            "description": "Bad named entity: orv without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&orv"
+                ]
+            ]
+        }, 
+        {
+            "input": "&orv;", 
+            "description": "Named entity: orv; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2a5b"
+                ]
+            ]
+        }, 
+        {
+            "input": "&oscr", 
+            "description": "Bad named entity: oscr without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&oscr"
+                ]
+            ]
+        }, 
+        {
+            "input": "&oscr;", 
+            "description": "Named entity: oscr; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2134"
+                ]
+            ]
+        }, 
+        {
+            "input": "&oslash", 
+            "description": "Named entity: oslash without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "\u00f8"
+                ]
+            ]
+        }, 
+        {
+            "input": "&oslash;", 
+            "description": "Named entity: oslash; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u00f8"
+                ]
+            ]
+        }, 
+        {
+            "input": "&osol", 
+            "description": "Bad named entity: osol without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&osol"
+                ]
+            ]
+        }, 
+        {
+            "input": "&osol;", 
+            "description": "Named entity: osol; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2298"
+                ]
+            ]
+        }, 
+        {
+            "input": "&otilde", 
+            "description": "Named entity: otilde without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "\u00f5"
+                ]
+            ]
+        }, 
+        {
+            "input": "&otilde;", 
+            "description": "Named entity: otilde; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u00f5"
+                ]
+            ]
+        }, 
+        {
+            "input": "&otimes", 
+            "description": "Bad named entity: otimes without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&otimes"
+                ]
+            ]
+        }, 
+        {
+            "input": "&otimes;", 
+            "description": "Named entity: otimes; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2297"
+                ]
+            ]
+        }, 
+        {
+            "input": "&otimesas", 
+            "description": "Bad named entity: otimesas without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&otimesas"
+                ]
+            ]
+        }, 
+        {
+            "input": "&otimesas;", 
+            "description": "Named entity: otimesas; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2a36"
+                ]
+            ]
+        }, 
+        {
+            "input": "&ouml", 
+            "description": "Named entity: ouml without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "\u00f6"
+                ]
+            ]
+        }, 
+        {
+            "input": "&ouml;", 
+            "description": "Named entity: ouml; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u00f6"
+                ]
+            ]
+        }, 
+        {
+            "input": "&ovbar", 
+            "description": "Bad named entity: ovbar without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&ovbar"
+                ]
+            ]
+        }, 
+        {
+            "input": "&ovbar;", 
+            "description": "Named entity: ovbar; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u233d"
+                ]
+            ]
+        }, 
+        {
+            "input": "&par", 
+            "description": "Bad named entity: par without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&par"
+                ]
+            ]
+        }, 
+        {
+            "input": "&par;", 
+            "description": "Named entity: par; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2225"
+                ]
+            ]
+        }, 
+        {
+            "input": "&para", 
+            "description": "Named entity: para without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "\u00b6"
+                ]
+            ]
+        }, 
+        {
+            "input": "&para;", 
+            "description": "Named entity: para; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u00b6"
+                ]
+            ]
+        }, 
+        {
+            "input": "&parallel;", 
+            "description": "Named entity: parallel; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2225"
+                ]
+            ]
+        }, 
+        {
+            "input": "&parsim", 
+            "description": "Bad named entity: parsim without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&parsim"
+                ]
+            ]
+        }, 
+        {
+            "input": "&parsim;", 
+            "description": "Named entity: parsim; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2af3"
+                ]
+            ]
+        }, 
+        {
+            "input": "&parsl", 
+            "description": "Bad named entity: parsl without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&parsl"
+                ]
+            ]
+        }, 
+        {
+            "input": "&parsl;", 
+            "description": "Named entity: parsl; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2afd"
+                ]
+            ]
+        }, 
+        {
+            "input": "&part", 
+            "description": "Bad named entity: part without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&part"
+                ]
+            ]
+        }, 
+        {
+            "input": "&part;", 
+            "description": "Named entity: part; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2202"
+                ]
+            ]
+        }, 
+        {
+            "input": "&pcy", 
+            "description": "Bad named entity: pcy without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&pcy"
+                ]
+            ]
+        }, 
+        {
+            "input": "&pcy;", 
+            "description": "Named entity: pcy; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u043f"
+                ]
+            ]
+        }, 
+        {
+            "input": "&percnt", 
+            "description": "Bad named entity: percnt without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&percnt"
+                ]
+            ]
+        }, 
+        {
+            "input": "&percnt;", 
+            "description": "Named entity: percnt; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "%"
+                ]
+            ]
+        }, 
+        {
+            "input": "&period", 
+            "description": "Bad named entity: period without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&period"
+                ]
+            ]
+        }, 
+        {
+            "input": "&period;", 
+            "description": "Named entity: period; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "."
+                ]
+            ]
+        }, 
+        {
+            "input": "&permil", 
+            "description": "Bad named entity: permil without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&permil"
+                ]
+            ]
+        }, 
+        {
+            "input": "&permil;", 
+            "description": "Named entity: permil; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2030"
+                ]
+            ]
+        }, 
+        {
+            "input": "&perp", 
+            "description": "Bad named entity: perp without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&perp"
+                ]
+            ]
+        }, 
+        {
+            "input": "&perp;", 
+            "description": "Named entity: perp; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u22a5"
+                ]
+            ]
+        }, 
+        {
+            "input": "&pertenk", 
+            "description": "Bad named entity: pertenk without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&pertenk"
+                ]
+            ]
+        }, 
+        {
+            "input": "&pertenk;", 
+            "description": "Named entity: pertenk; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2031"
+                ]
+            ]
+        }, 
+        {
+            "input": "&pfr", 
+            "description": "Bad named entity: pfr without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&pfr"
+                ]
+            ]
+        }, 
+        {
+            "input": "&pfr;", 
+            "description": "Named entity: pfr; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\ud835\udd2d"
+                ]
+            ]
+        }, 
+        {
+            "input": "&phi", 
+            "description": "Bad named entity: phi without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&phi"
+                ]
+            ]
+        }, 
+        {
+            "input": "&phi;", 
+            "description": "Named entity: phi; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u03c6"
+                ]
+            ]
+        }, 
+        {
+            "input": "&phiv", 
+            "description": "Bad named entity: phiv without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&phiv"
+                ]
+            ]
+        }, 
+        {
+            "input": "&phiv;", 
+            "description": "Named entity: phiv; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u03d5"
+                ]
+            ]
+        }, 
+        {
+            "input": "&phmmat", 
+            "description": "Bad named entity: phmmat without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&phmmat"
+                ]
+            ]
+        }, 
+        {
+            "input": "&phmmat;", 
+            "description": "Named entity: phmmat; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2133"
+                ]
+            ]
+        }, 
+        {
+            "input": "&phone", 
+            "description": "Bad named entity: phone without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&phone"
+                ]
+            ]
+        }, 
+        {
+            "input": "&phone;", 
+            "description": "Named entity: phone; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u260e"
+                ]
+            ]
+        }, 
+        {
+            "input": "&pi", 
+            "description": "Bad named entity: pi without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&pi"
+                ]
+            ]
+        }, 
+        {
+            "input": "&pi;", 
+            "description": "Named entity: pi; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u03c0"
+                ]
+            ]
+        }, 
+        {
+            "input": "&pitchfork", 
+            "description": "Bad named entity: pitchfork without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&pitchfork"
+                ]
+            ]
+        }, 
+        {
+            "input": "&pitchfork;", 
+            "description": "Named entity: pitchfork; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u22d4"
+                ]
+            ]
+        }, 
+        {
+            "input": "&piv", 
+            "description": "Bad named entity: piv without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&piv"
+                ]
+            ]
+        }, 
+        {
+            "input": "&piv;", 
+            "description": "Named entity: piv; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u03d6"
+                ]
+            ]
+        }, 
+        {
+            "input": "&planck", 
+            "description": "Bad named entity: planck without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&planck"
+                ]
+            ]
+        }, 
+        {
+            "input": "&planck;", 
+            "description": "Named entity: planck; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u210f"
+                ]
+            ]
+        }, 
+        {
+            "input": "&planckh", 
+            "description": "Bad named entity: planckh without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&planckh"
+                ]
+            ]
+        }, 
+        {
+            "input": "&planckh;", 
+            "description": "Named entity: planckh; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u210e"
+                ]
+            ]
+        }, 
+        {
+            "input": "&plankv", 
+            "description": "Bad named entity: plankv without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&plankv"
+                ]
+            ]
+        }, 
+        {
+            "input": "&plankv;", 
+            "description": "Named entity: plankv; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u210f"
+                ]
+            ]
+        }, 
+        {
+            "input": "&plus", 
+            "description": "Bad named entity: plus without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&plus"
+                ]
+            ]
+        }, 
+        {
+            "input": "&plus;", 
+            "description": "Named entity: plus; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "+"
+                ]
+            ]
+        }, 
+        {
+            "input": "&plusacir", 
+            "description": "Bad named entity: plusacir without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&plusacir"
+                ]
+            ]
+        }, 
+        {
+            "input": "&plusacir;", 
+            "description": "Named entity: plusacir; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2a23"
+                ]
+            ]
+        }, 
+        {
+            "input": "&plusb", 
+            "description": "Bad named entity: plusb without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&plusb"
+                ]
+            ]
+        }, 
+        {
+            "input": "&plusb;", 
+            "description": "Named entity: plusb; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u229e"
+                ]
+            ]
+        }, 
+        {
+            "input": "&pluscir", 
+            "description": "Bad named entity: pluscir without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&pluscir"
+                ]
+            ]
+        }, 
+        {
+            "input": "&pluscir;", 
+            "description": "Named entity: pluscir; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2a22"
+                ]
+            ]
+        }, 
+        {
+            "input": "&plusdo", 
+            "description": "Bad named entity: plusdo without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&plusdo"
+                ]
+            ]
+        }, 
+        {
+            "input": "&plusdo;", 
+            "description": "Named entity: plusdo; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2214"
+                ]
+            ]
+        }, 
+        {
+            "input": "&plusdu", 
+            "description": "Bad named entity: plusdu without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&plusdu"
+                ]
+            ]
+        }, 
+        {
+            "input": "&plusdu;", 
+            "description": "Named entity: plusdu; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2a25"
+                ]
+            ]
+        }, 
+        {
+            "input": "&pluse", 
+            "description": "Bad named entity: pluse without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&pluse"
+                ]
+            ]
+        }, 
+        {
+            "input": "&pluse;", 
+            "description": "Named entity: pluse; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2a72"
+                ]
+            ]
+        }, 
+        {
+            "input": "&plusmn", 
+            "description": "Named entity: plusmn without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "\u00b1"
+                ]
+            ]
+        }, 
+        {
+            "input": "&plusmn;", 
+            "description": "Named entity: plusmn; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u00b1"
+                ]
+            ]
+        }, 
+        {
+            "input": "&plussim", 
+            "description": "Bad named entity: plussim without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&plussim"
+                ]
+            ]
+        }, 
+        {
+            "input": "&plussim;", 
+            "description": "Named entity: plussim; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2a26"
+                ]
+            ]
+        }, 
+        {
+            "input": "&plustwo", 
+            "description": "Bad named entity: plustwo without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&plustwo"
+                ]
+            ]
+        }, 
+        {
+            "input": "&plustwo;", 
+            "description": "Named entity: plustwo; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2a27"
+                ]
+            ]
+        }, 
+        {
+            "input": "&pm", 
+            "description": "Bad named entity: pm without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&pm"
+                ]
+            ]
+        }, 
+        {
+            "input": "&pm;", 
+            "description": "Named entity: pm; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u00b1"
+                ]
+            ]
+        }, 
+        {
+            "input": "&pointint", 
+            "description": "Bad named entity: pointint without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&pointint"
+                ]
+            ]
+        }, 
+        {
+            "input": "&pointint;", 
+            "description": "Named entity: pointint; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2a15"
+                ]
+            ]
+        }, 
+        {
+            "input": "&popf", 
+            "description": "Bad named entity: popf without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&popf"
+                ]
+            ]
+        }, 
+        {
+            "input": "&popf;", 
+            "description": "Named entity: popf; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\ud835\udd61"
+                ]
+            ]
+        }, 
+        {
+            "input": "&pound", 
+            "description": "Named entity: pound without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "\u00a3"
+                ]
+            ]
+        }, 
+        {
+            "input": "&pound;", 
+            "description": "Named entity: pound; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u00a3"
+                ]
+            ]
+        }, 
+        {
+            "input": "&pr", 
+            "description": "Bad named entity: pr without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&pr"
+                ]
+            ]
+        }, 
+        {
+            "input": "&pr;", 
+            "description": "Named entity: pr; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u227a"
+                ]
+            ]
+        }, 
+        {
+            "input": "&prE", 
+            "description": "Bad named entity: prE without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&prE"
+                ]
+            ]
+        }, 
+        {
+            "input": "&prE;", 
+            "description": "Named entity: prE; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2ab3"
+                ]
+            ]
+        }, 
+        {
+            "input": "&prap", 
+            "description": "Bad named entity: prap without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&prap"
+                ]
+            ]
+        }, 
+        {
+            "input": "&prap;", 
+            "description": "Named entity: prap; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2ab7"
+                ]
+            ]
+        }, 
+        {
+            "input": "&prcue", 
+            "description": "Bad named entity: prcue without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&prcue"
+                ]
+            ]
+        }, 
+        {
+            "input": "&prcue;", 
+            "description": "Named entity: prcue; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u227c"
+                ]
+            ]
+        }, 
+        {
+            "input": "&pre", 
+            "description": "Bad named entity: pre without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&pre"
+                ]
+            ]
+        }, 
+        {
+            "input": "&pre;", 
+            "description": "Named entity: pre; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2aaf"
+                ]
+            ]
+        }, 
+        {
+            "input": "&prec", 
+            "description": "Bad named entity: prec without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&prec"
+                ]
+            ]
+        }, 
+        {
+            "input": "&prec;", 
+            "description": "Named entity: prec; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u227a"
+                ]
+            ]
+        }, 
+        {
+            "input": "&precapprox", 
+            "description": "Bad named entity: precapprox without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&precapprox"
+                ]
+            ]
+        }, 
+        {
+            "input": "&precapprox;", 
+            "description": "Named entity: precapprox; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2ab7"
+                ]
+            ]
+        }, 
+        {
+            "input": "&preccurlyeq", 
+            "description": "Bad named entity: preccurlyeq without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&preccurlyeq"
+                ]
+            ]
+        }, 
+        {
+            "input": "&preccurlyeq;", 
+            "description": "Named entity: preccurlyeq; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u227c"
+                ]
+            ]
+        }, 
+        {
+            "input": "&preceq", 
+            "description": "Bad named entity: preceq without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&preceq"
+                ]
+            ]
+        }, 
+        {
+            "input": "&preceq;", 
+            "description": "Named entity: preceq; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2aaf"
+                ]
+            ]
+        }, 
+        {
+            "input": "&precnapprox", 
+            "description": "Bad named entity: precnapprox without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&precnapprox"
+                ]
+            ]
+        }, 
+        {
+            "input": "&precnapprox;", 
+            "description": "Named entity: precnapprox; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2ab9"
+                ]
+            ]
+        }, 
+        {
+            "input": "&precneqq", 
+            "description": "Bad named entity: precneqq without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&precneqq"
+                ]
+            ]
+        }, 
+        {
+            "input": "&precneqq;", 
+            "description": "Named entity: precneqq; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2ab5"
+                ]
+            ]
+        }, 
+        {
+            "input": "&precnsim", 
+            "description": "Bad named entity: precnsim without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&precnsim"
+                ]
+            ]
+        }, 
+        {
+            "input": "&precnsim;", 
+            "description": "Named entity: precnsim; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u22e8"
+                ]
+            ]
+        }, 
+        {
+            "input": "&precsim", 
+            "description": "Bad named entity: precsim without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&precsim"
+                ]
+            ]
+        }, 
+        {
+            "input": "&precsim;", 
+            "description": "Named entity: precsim; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u227e"
+                ]
+            ]
+        }, 
+        {
+            "input": "&prime", 
+            "description": "Bad named entity: prime without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&prime"
+                ]
+            ]
+        }, 
+        {
+            "input": "&prime;", 
+            "description": "Named entity: prime; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2032"
+                ]
+            ]
+        }, 
+        {
+            "input": "&primes", 
+            "description": "Bad named entity: primes without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&primes"
+                ]
+            ]
+        }, 
+        {
+            "input": "&primes;", 
+            "description": "Named entity: primes; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2119"
+                ]
+            ]
+        }, 
+        {
+            "input": "&prnE", 
+            "description": "Bad named entity: prnE without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&prnE"
+                ]
+            ]
+        }, 
+        {
+            "input": "&prnE;", 
+            "description": "Named entity: prnE; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2ab5"
+                ]
+            ]
+        }, 
+        {
+            "input": "&prnap", 
+            "description": "Bad named entity: prnap without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&prnap"
+                ]
+            ]
+        }, 
+        {
+            "input": "&prnap;", 
+            "description": "Named entity: prnap; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2ab9"
+                ]
+            ]
+        }, 
+        {
+            "input": "&prnsim", 
+            "description": "Bad named entity: prnsim without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&prnsim"
+                ]
+            ]
+        }, 
+        {
+            "input": "&prnsim;", 
+            "description": "Named entity: prnsim; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u22e8"
+                ]
+            ]
+        }, 
+        {
+            "input": "&prod", 
+            "description": "Bad named entity: prod without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&prod"
+                ]
+            ]
+        }, 
+        {
+            "input": "&prod;", 
+            "description": "Named entity: prod; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u220f"
+                ]
+            ]
+        }, 
+        {
+            "input": "&profalar", 
+            "description": "Bad named entity: profalar without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&profalar"
+                ]
+            ]
+        }, 
+        {
+            "input": "&profalar;", 
+            "description": "Named entity: profalar; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u232e"
+                ]
+            ]
+        }, 
+        {
+            "input": "&profline", 
+            "description": "Bad named entity: profline without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&profline"
+                ]
+            ]
+        }, 
+        {
+            "input": "&profline;", 
+            "description": "Named entity: profline; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2312"
+                ]
+            ]
+        }, 
+        {
+            "input": "&profsurf", 
+            "description": "Bad named entity: profsurf without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&profsurf"
+                ]
+            ]
+        }, 
+        {
+            "input": "&profsurf;", 
+            "description": "Named entity: profsurf; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2313"
+                ]
+            ]
+        }, 
+        {
+            "input": "&prop", 
+            "description": "Bad named entity: prop without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&prop"
+                ]
+            ]
+        }, 
+        {
+            "input": "&prop;", 
+            "description": "Named entity: prop; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u221d"
+                ]
+            ]
+        }, 
+        {
+            "input": "&propto", 
+            "description": "Bad named entity: propto without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&propto"
+                ]
+            ]
+        }, 
+        {
+            "input": "&propto;", 
+            "description": "Named entity: propto; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u221d"
+                ]
+            ]
+        }, 
+        {
+            "input": "&prsim", 
+            "description": "Bad named entity: prsim without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&prsim"
+                ]
+            ]
+        }, 
+        {
+            "input": "&prsim;", 
+            "description": "Named entity: prsim; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u227e"
+                ]
+            ]
+        }, 
+        {
+            "input": "&prurel", 
+            "description": "Bad named entity: prurel without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&prurel"
+                ]
+            ]
+        }, 
+        {
+            "input": "&prurel;", 
+            "description": "Named entity: prurel; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u22b0"
+                ]
+            ]
+        }, 
+        {
+            "input": "&pscr", 
+            "description": "Bad named entity: pscr without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&pscr"
+                ]
+            ]
+        }, 
+        {
+            "input": "&pscr;", 
+            "description": "Named entity: pscr; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\ud835\udcc5"
+                ]
+            ]
+        }, 
+        {
+            "input": "&psi", 
+            "description": "Bad named entity: psi without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&psi"
+                ]
+            ]
+        }, 
+        {
+            "input": "&psi;", 
+            "description": "Named entity: psi; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u03c8"
+                ]
+            ]
+        }, 
+        {
+            "input": "&puncsp", 
+            "description": "Bad named entity: puncsp without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&puncsp"
+                ]
+            ]
+        }, 
+        {
+            "input": "&puncsp;", 
+            "description": "Named entity: puncsp; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2008"
+                ]
+            ]
+        }, 
+        {
+            "input": "&qfr", 
+            "description": "Bad named entity: qfr without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&qfr"
+                ]
+            ]
+        }, 
+        {
+            "input": "&qfr;", 
+            "description": "Named entity: qfr; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\ud835\udd2e"
+                ]
+            ]
+        }, 
+        {
+            "input": "&qint", 
+            "description": "Bad named entity: qint without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&qint"
+                ]
+            ]
+        }, 
+        {
+            "input": "&qint;", 
+            "description": "Named entity: qint; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2a0c"
+                ]
+            ]
+        }, 
+        {
+            "input": "&qopf", 
+            "description": "Bad named entity: qopf without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&qopf"
+                ]
+            ]
+        }, 
+        {
+            "input": "&qopf;", 
+            "description": "Named entity: qopf; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\ud835\udd62"
+                ]
+            ]
+        }, 
+        {
+            "input": "&qprime", 
+            "description": "Bad named entity: qprime without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&qprime"
+                ]
+            ]
+        }, 
+        {
+            "input": "&qprime;", 
+            "description": "Named entity: qprime; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2057"
+                ]
+            ]
+        }, 
+        {
+            "input": "&qscr", 
+            "description": "Bad named entity: qscr without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&qscr"
+                ]
+            ]
+        }, 
+        {
+            "input": "&qscr;", 
+            "description": "Named entity: qscr; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\ud835\udcc6"
+                ]
+            ]
+        }, 
+        {
+            "input": "&quaternions", 
+            "description": "Bad named entity: quaternions without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&quaternions"
+                ]
+            ]
+        }, 
+        {
+            "input": "&quaternions;", 
+            "description": "Named entity: quaternions; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u210d"
+                ]
+            ]
+        }, 
+        {
+            "input": "&quatint", 
+            "description": "Bad named entity: quatint without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&quatint"
+                ]
+            ]
+        }, 
+        {
+            "input": "&quatint;", 
+            "description": "Named entity: quatint; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2a16"
+                ]
+            ]
+        }, 
+        {
+            "input": "&quest", 
+            "description": "Bad named entity: quest without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&quest"
+                ]
+            ]
+        }, 
+        {
+            "input": "&quest;", 
+            "description": "Named entity: quest; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "?"
+                ]
+            ]
+        }, 
+        {
+            "input": "&questeq", 
+            "description": "Bad named entity: questeq without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&questeq"
+                ]
+            ]
+        }, 
+        {
+            "input": "&questeq;", 
+            "description": "Named entity: questeq; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u225f"
+                ]
+            ]
+        }, 
+        {
+            "input": "&quot", 
+            "description": "Named entity: quot without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "\""
+                ]
+            ]
+        }, 
+        {
+            "input": "&quot;", 
+            "description": "Named entity: quot; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\""
+                ]
+            ]
+        }, 
+        {
+            "input": "&rAarr", 
+            "description": "Bad named entity: rAarr without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&rAarr"
+                ]
+            ]
+        }, 
+        {
+            "input": "&rAarr;", 
+            "description": "Named entity: rAarr; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u21db"
+                ]
+            ]
+        }, 
+        {
+            "input": "&rArr", 
+            "description": "Bad named entity: rArr without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&rArr"
+                ]
+            ]
+        }, 
+        {
+            "input": "&rArr;", 
+            "description": "Named entity: rArr; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u21d2"
+                ]
+            ]
+        }, 
+        {
+            "input": "&rAtail", 
+            "description": "Bad named entity: rAtail without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&rAtail"
+                ]
+            ]
+        }, 
+        {
+            "input": "&rAtail;", 
+            "description": "Named entity: rAtail; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u291c"
+                ]
+            ]
+        }, 
+        {
+            "input": "&rBarr", 
+            "description": "Bad named entity: rBarr without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&rBarr"
+                ]
+            ]
+        }, 
+        {
+            "input": "&rBarr;", 
+            "description": "Named entity: rBarr; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u290f"
+                ]
+            ]
+        }, 
+        {
+            "input": "&rHar", 
+            "description": "Bad named entity: rHar without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&rHar"
+                ]
+            ]
+        }, 
+        {
+            "input": "&rHar;", 
+            "description": "Named entity: rHar; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2964"
+                ]
+            ]
+        }, 
+        {
+            "input": "&race", 
+            "description": "Bad named entity: race without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&race"
+                ]
+            ]
+        }, 
+        {
+            "input": "&race;", 
+            "description": "Named entity: race; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u223d\u0331"
+                ]
+            ]
+        }, 
+        {
+            "input": "&racute", 
+            "description": "Bad named entity: racute without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&racute"
+                ]
+            ]
+        }, 
+        {
+            "input": "&racute;", 
+            "description": "Named entity: racute; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u0155"
+                ]
+            ]
+        }, 
+        {
+            "input": "&radic", 
+            "description": "Bad named entity: radic without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&radic"
+                ]
+            ]
+        }, 
+        {
+            "input": "&radic;", 
+            "description": "Named entity: radic; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u221a"
+                ]
+            ]
+        }, 
+        {
+            "input": "&raemptyv", 
+            "description": "Bad named entity: raemptyv without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&raemptyv"
+                ]
+            ]
+        }, 
+        {
+            "input": "&raemptyv;", 
+            "description": "Named entity: raemptyv; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u29b3"
+                ]
+            ]
+        }, 
+        {
+            "input": "&rang", 
+            "description": "Bad named entity: rang without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&rang"
+                ]
+            ]
+        }, 
+        {
+            "input": "&rang;", 
+            "description": "Named entity: rang; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u27e9"
+                ]
+            ]
+        }, 
+        {
+            "input": "&rangd", 
+            "description": "Bad named entity: rangd without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&rangd"
+                ]
+            ]
+        }, 
+        {
+            "input": "&rangd;", 
+            "description": "Named entity: rangd; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2992"
+                ]
+            ]
+        }, 
+        {
+            "input": "&range", 
+            "description": "Bad named entity: range without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&range"
+                ]
+            ]
+        }, 
+        {
+            "input": "&range;", 
+            "description": "Named entity: range; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u29a5"
+                ]
+            ]
+        }, 
+        {
+            "input": "&rangle", 
+            "description": "Bad named entity: rangle without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&rangle"
+                ]
+            ]
+        }, 
+        {
+            "input": "&rangle;", 
+            "description": "Named entity: rangle; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u27e9"
+                ]
+            ]
+        }, 
+        {
+            "input": "&raquo", 
+            "description": "Named entity: raquo without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "\u00bb"
+                ]
+            ]
+        }, 
+        {
+            "input": "&raquo;", 
+            "description": "Named entity: raquo; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u00bb"
+                ]
+            ]
+        }, 
+        {
+            "input": "&rarr", 
+            "description": "Bad named entity: rarr without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&rarr"
+                ]
+            ]
+        }, 
+        {
+            "input": "&rarr;", 
+            "description": "Named entity: rarr; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2192"
+                ]
+            ]
+        }, 
+        {
+            "input": "&rarrap", 
+            "description": "Bad named entity: rarrap without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&rarrap"
+                ]
+            ]
+        }, 
+        {
+            "input": "&rarrap;", 
+            "description": "Named entity: rarrap; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2975"
+                ]
+            ]
+        }, 
+        {
+            "input": "&rarrb", 
+            "description": "Bad named entity: rarrb without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&rarrb"
+                ]
+            ]
+        }, 
+        {
+            "input": "&rarrb;", 
+            "description": "Named entity: rarrb; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u21e5"
+                ]
+            ]
+        }, 
+        {
+            "input": "&rarrbfs", 
+            "description": "Bad named entity: rarrbfs without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&rarrbfs"
+                ]
+            ]
+        }, 
+        {
+            "input": "&rarrbfs;", 
+            "description": "Named entity: rarrbfs; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2920"
+                ]
+            ]
+        }, 
+        {
+            "input": "&rarrc", 
+            "description": "Bad named entity: rarrc without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&rarrc"
+                ]
+            ]
+        }, 
+        {
+            "input": "&rarrc;", 
+            "description": "Named entity: rarrc; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2933"
+                ]
+            ]
+        }, 
+        {
+            "input": "&rarrfs", 
+            "description": "Bad named entity: rarrfs without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&rarrfs"
+                ]
+            ]
+        }, 
+        {
+            "input": "&rarrfs;", 
+            "description": "Named entity: rarrfs; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u291e"
+                ]
+            ]
+        }, 
+        {
+            "input": "&rarrhk", 
+            "description": "Bad named entity: rarrhk without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&rarrhk"
+                ]
+            ]
+        }, 
+        {
+            "input": "&rarrhk;", 
+            "description": "Named entity: rarrhk; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u21aa"
+                ]
+            ]
+        }, 
+        {
+            "input": "&rarrlp", 
+            "description": "Bad named entity: rarrlp without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&rarrlp"
+                ]
+            ]
+        }, 
+        {
+            "input": "&rarrlp;", 
+            "description": "Named entity: rarrlp; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u21ac"
+                ]
+            ]
+        }, 
+        {
+            "input": "&rarrpl", 
+            "description": "Bad named entity: rarrpl without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&rarrpl"
+                ]
+            ]
+        }, 
+        {
+            "input": "&rarrpl;", 
+            "description": "Named entity: rarrpl; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2945"
+                ]
+            ]
+        }, 
+        {
+            "input": "&rarrsim", 
+            "description": "Bad named entity: rarrsim without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&rarrsim"
+                ]
+            ]
+        }, 
+        {
+            "input": "&rarrsim;", 
+            "description": "Named entity: rarrsim; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2974"
+                ]
+            ]
+        }, 
+        {
+            "input": "&rarrtl", 
+            "description": "Bad named entity: rarrtl without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&rarrtl"
+                ]
+            ]
+        }, 
+        {
+            "input": "&rarrtl;", 
+            "description": "Named entity: rarrtl; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u21a3"
+                ]
+            ]
+        }, 
+        {
+            "input": "&rarrw", 
+            "description": "Bad named entity: rarrw without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&rarrw"
+                ]
+            ]
+        }, 
+        {
+            "input": "&rarrw;", 
+            "description": "Named entity: rarrw; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u219d"
+                ]
+            ]
+        }, 
+        {
+            "input": "&ratail", 
+            "description": "Bad named entity: ratail without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&ratail"
+                ]
+            ]
+        }, 
+        {
+            "input": "&ratail;", 
+            "description": "Named entity: ratail; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u291a"
+                ]
+            ]
+        }, 
+        {
+            "input": "&ratio", 
+            "description": "Bad named entity: ratio without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&ratio"
+                ]
+            ]
+        }, 
+        {
+            "input": "&ratio;", 
+            "description": "Named entity: ratio; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2236"
+                ]
+            ]
+        }, 
+        {
+            "input": "&rationals", 
+            "description": "Bad named entity: rationals without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&rationals"
+                ]
+            ]
+        }, 
+        {
+            "input": "&rationals;", 
+            "description": "Named entity: rationals; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u211a"
+                ]
+            ]
+        }, 
+        {
+            "input": "&rbarr", 
+            "description": "Bad named entity: rbarr without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&rbarr"
+                ]
+            ]
+        }, 
+        {
+            "input": "&rbarr;", 
+            "description": "Named entity: rbarr; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u290d"
+                ]
+            ]
+        }, 
+        {
+            "input": "&rbbrk", 
+            "description": "Bad named entity: rbbrk without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&rbbrk"
+                ]
+            ]
+        }, 
+        {
+            "input": "&rbbrk;", 
+            "description": "Named entity: rbbrk; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2773"
+                ]
+            ]
+        }, 
+        {
+            "input": "&rbrace", 
+            "description": "Bad named entity: rbrace without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&rbrace"
+                ]
+            ]
+        }, 
+        {
+            "input": "&rbrace;", 
+            "description": "Named entity: rbrace; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "}"
+                ]
+            ]
+        }, 
+        {
+            "input": "&rbrack", 
+            "description": "Bad named entity: rbrack without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&rbrack"
+                ]
+            ]
+        }, 
+        {
+            "input": "&rbrack;", 
+            "description": "Named entity: rbrack; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "]"
+                ]
+            ]
+        }, 
+        {
+            "input": "&rbrke", 
+            "description": "Bad named entity: rbrke without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&rbrke"
+                ]
+            ]
+        }, 
+        {
+            "input": "&rbrke;", 
+            "description": "Named entity: rbrke; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u298c"
+                ]
+            ]
+        }, 
+        {
+            "input": "&rbrksld", 
+            "description": "Bad named entity: rbrksld without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&rbrksld"
+                ]
+            ]
+        }, 
+        {
+            "input": "&rbrksld;", 
+            "description": "Named entity: rbrksld; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u298e"
+                ]
+            ]
+        }, 
+        {
+            "input": "&rbrkslu", 
+            "description": "Bad named entity: rbrkslu without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&rbrkslu"
+                ]
+            ]
+        }, 
+        {
+            "input": "&rbrkslu;", 
+            "description": "Named entity: rbrkslu; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2990"
+                ]
+            ]
+        }, 
+        {
+            "input": "&rcaron", 
+            "description": "Bad named entity: rcaron without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&rcaron"
+                ]
+            ]
+        }, 
+        {
+            "input": "&rcaron;", 
+            "description": "Named entity: rcaron; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u0159"
+                ]
+            ]
+        }, 
+        {
+            "input": "&rcedil", 
+            "description": "Bad named entity: rcedil without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&rcedil"
+                ]
+            ]
+        }, 
+        {
+            "input": "&rcedil;", 
+            "description": "Named entity: rcedil; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u0157"
+                ]
+            ]
+        }, 
+        {
+            "input": "&rceil", 
+            "description": "Bad named entity: rceil without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&rceil"
+                ]
+            ]
+        }, 
+        {
+            "input": "&rceil;", 
+            "description": "Named entity: rceil; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2309"
+                ]
+            ]
+        }, 
+        {
+            "input": "&rcub", 
+            "description": "Bad named entity: rcub without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&rcub"
+                ]
+            ]
+        }, 
+        {
+            "input": "&rcub;", 
+            "description": "Named entity: rcub; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "}"
+                ]
+            ]
+        }, 
+        {
+            "input": "&rcy", 
+            "description": "Bad named entity: rcy without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&rcy"
+                ]
+            ]
+        }, 
+        {
+            "input": "&rcy;", 
+            "description": "Named entity: rcy; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u0440"
+                ]
+            ]
+        }, 
+        {
+            "input": "&rdca", 
+            "description": "Bad named entity: rdca without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&rdca"
+                ]
+            ]
+        }, 
+        {
+            "input": "&rdca;", 
+            "description": "Named entity: rdca; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2937"
+                ]
+            ]
+        }, 
+        {
+            "input": "&rdldhar", 
+            "description": "Bad named entity: rdldhar without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&rdldhar"
+                ]
+            ]
+        }, 
+        {
+            "input": "&rdldhar;", 
+            "description": "Named entity: rdldhar; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2969"
+                ]
+            ]
+        }, 
+        {
+            "input": "&rdquo", 
+            "description": "Bad named entity: rdquo without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&rdquo"
+                ]
+            ]
+        }, 
+        {
+            "input": "&rdquo;", 
+            "description": "Named entity: rdquo; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u201d"
+                ]
+            ]
+        }, 
+        {
+            "input": "&rdquor", 
+            "description": "Bad named entity: rdquor without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&rdquor"
+                ]
+            ]
+        }, 
+        {
+            "input": "&rdquor;", 
+            "description": "Named entity: rdquor; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u201d"
+                ]
+            ]
+        }, 
+        {
+            "input": "&rdsh", 
+            "description": "Bad named entity: rdsh without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&rdsh"
+                ]
+            ]
+        }, 
+        {
+            "input": "&rdsh;", 
+            "description": "Named entity: rdsh; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u21b3"
+                ]
+            ]
+        }, 
+        {
+            "input": "&real", 
+            "description": "Bad named entity: real without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&real"
+                ]
+            ]
+        }, 
+        {
+            "input": "&real;", 
+            "description": "Named entity: real; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u211c"
+                ]
+            ]
+        }, 
+        {
+            "input": "&realine", 
+            "description": "Bad named entity: realine without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&realine"
+                ]
+            ]
+        }, 
+        {
+            "input": "&realine;", 
+            "description": "Named entity: realine; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u211b"
+                ]
+            ]
+        }, 
+        {
+            "input": "&realpart", 
+            "description": "Bad named entity: realpart without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&realpart"
+                ]
+            ]
+        }, 
+        {
+            "input": "&realpart;", 
+            "description": "Named entity: realpart; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u211c"
+                ]
+            ]
+        }, 
+        {
+            "input": "&reals", 
+            "description": "Bad named entity: reals without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&reals"
+                ]
+            ]
+        }, 
+        {
+            "input": "&reals;", 
+            "description": "Named entity: reals; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u211d"
+                ]
+            ]
+        }, 
+        {
+            "input": "&rect", 
+            "description": "Bad named entity: rect without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&rect"
+                ]
+            ]
+        }, 
+        {
+            "input": "&rect;", 
+            "description": "Named entity: rect; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u25ad"
+                ]
+            ]
+        }, 
+        {
+            "input": "&reg", 
+            "description": "Named entity: reg without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "\u00ae"
+                ]
+            ]
+        }, 
+        {
+            "input": "&reg;", 
+            "description": "Named entity: reg; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u00ae"
+                ]
+            ]
+        }, 
+        {
+            "input": "&rfisht", 
+            "description": "Bad named entity: rfisht without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&rfisht"
+                ]
+            ]
+        }, 
+        {
+            "input": "&rfisht;", 
+            "description": "Named entity: rfisht; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u297d"
+                ]
+            ]
+        }, 
+        {
+            "input": "&rfloor", 
+            "description": "Bad named entity: rfloor without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&rfloor"
+                ]
+            ]
+        }, 
+        {
+            "input": "&rfloor;", 
+            "description": "Named entity: rfloor; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u230b"
+                ]
+            ]
+        }, 
+        {
+            "input": "&rfr", 
+            "description": "Bad named entity: rfr without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&rfr"
+                ]
+            ]
+        }, 
+        {
+            "input": "&rfr;", 
+            "description": "Named entity: rfr; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\ud835\udd2f"
+                ]
+            ]
+        }, 
+        {
+            "input": "&rhard", 
+            "description": "Bad named entity: rhard without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&rhard"
+                ]
+            ]
+        }, 
+        {
+            "input": "&rhard;", 
+            "description": "Named entity: rhard; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u21c1"
+                ]
+            ]
+        }, 
+        {
+            "input": "&rharu", 
+            "description": "Bad named entity: rharu without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&rharu"
+                ]
+            ]
+        }, 
+        {
+            "input": "&rharu;", 
+            "description": "Named entity: rharu; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u21c0"
+                ]
+            ]
+        }, 
+        {
+            "input": "&rharul", 
+            "description": "Bad named entity: rharul without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&rharul"
+                ]
+            ]
+        }, 
+        {
+            "input": "&rharul;", 
+            "description": "Named entity: rharul; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u296c"
+                ]
+            ]
+        }, 
+        {
+            "input": "&rho", 
+            "description": "Bad named entity: rho without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&rho"
+                ]
+            ]
+        }, 
+        {
+            "input": "&rho;", 
+            "description": "Named entity: rho; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u03c1"
+                ]
+            ]
+        }, 
+        {
+            "input": "&rhov", 
+            "description": "Bad named entity: rhov without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&rhov"
+                ]
+            ]
+        }, 
+        {
+            "input": "&rhov;", 
+            "description": "Named entity: rhov; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u03f1"
+                ]
+            ]
+        }, 
+        {
+            "input": "&rightarrow", 
+            "description": "Bad named entity: rightarrow without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&rightarrow"
+                ]
+            ]
+        }, 
+        {
+            "input": "&rightarrow;", 
+            "description": "Named entity: rightarrow; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2192"
+                ]
+            ]
+        }, 
+        {
+            "input": "&rightarrowtail", 
+            "description": "Bad named entity: rightarrowtail without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&rightarrowtail"
+                ]
+            ]
+        }, 
+        {
+            "input": "&rightarrowtail;", 
+            "description": "Named entity: rightarrowtail; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u21a3"
+                ]
+            ]
+        }, 
+        {
+            "input": "&rightharpoondown", 
+            "description": "Bad named entity: rightharpoondown without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&rightharpoondown"
+                ]
+            ]
+        }, 
+        {
+            "input": "&rightharpoondown;", 
+            "description": "Named entity: rightharpoondown; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u21c1"
+                ]
+            ]
+        }, 
+        {
+            "input": "&rightharpoonup", 
+            "description": "Bad named entity: rightharpoonup without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&rightharpoonup"
+                ]
+            ]
+        }, 
+        {
+            "input": "&rightharpoonup;", 
+            "description": "Named entity: rightharpoonup; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u21c0"
+                ]
+            ]
+        }, 
+        {
+            "input": "&rightleftarrows", 
+            "description": "Bad named entity: rightleftarrows without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&rightleftarrows"
+                ]
+            ]
+        }, 
+        {
+            "input": "&rightleftarrows;", 
+            "description": "Named entity: rightleftarrows; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u21c4"
+                ]
+            ]
+        }, 
+        {
+            "input": "&rightleftharpoons", 
+            "description": "Bad named entity: rightleftharpoons without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&rightleftharpoons"
+                ]
+            ]
+        }, 
+        {
+            "input": "&rightleftharpoons;", 
+            "description": "Named entity: rightleftharpoons; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u21cc"
+                ]
+            ]
+        }, 
+        {
+            "input": "&rightrightarrows", 
+            "description": "Bad named entity: rightrightarrows without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&rightrightarrows"
+                ]
+            ]
+        }, 
+        {
+            "input": "&rightrightarrows;", 
+            "description": "Named entity: rightrightarrows; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u21c9"
+                ]
+            ]
+        }, 
+        {
+            "input": "&rightsquigarrow", 
+            "description": "Bad named entity: rightsquigarrow without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&rightsquigarrow"
+                ]
+            ]
+        }, 
+        {
+            "input": "&rightsquigarrow;", 
+            "description": "Named entity: rightsquigarrow; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u219d"
+                ]
+            ]
+        }, 
+        {
+            "input": "&rightthreetimes", 
+            "description": "Bad named entity: rightthreetimes without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&rightthreetimes"
+                ]
+            ]
+        }, 
+        {
+            "input": "&rightthreetimes;", 
+            "description": "Named entity: rightthreetimes; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u22cc"
+                ]
+            ]
+        }, 
+        {
+            "input": "&ring", 
+            "description": "Bad named entity: ring without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&ring"
+                ]
+            ]
+        }, 
+        {
+            "input": "&ring;", 
+            "description": "Named entity: ring; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u02da"
+                ]
+            ]
+        }, 
+        {
+            "input": "&risingdotseq", 
+            "description": "Bad named entity: risingdotseq without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&risingdotseq"
+                ]
+            ]
+        }, 
+        {
+            "input": "&risingdotseq;", 
+            "description": "Named entity: risingdotseq; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2253"
+                ]
+            ]
+        }, 
+        {
+            "input": "&rlarr", 
+            "description": "Bad named entity: rlarr without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&rlarr"
+                ]
+            ]
+        }, 
+        {
+            "input": "&rlarr;", 
+            "description": "Named entity: rlarr; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u21c4"
+                ]
+            ]
+        }, 
+        {
+            "input": "&rlhar", 
+            "description": "Bad named entity: rlhar without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&rlhar"
+                ]
+            ]
+        }, 
+        {
+            "input": "&rlhar;", 
+            "description": "Named entity: rlhar; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u21cc"
+                ]
+            ]
+        }, 
+        {
+            "input": "&rlm", 
+            "description": "Bad named entity: rlm without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&rlm"
+                ]
+            ]
+        }, 
+        {
+            "input": "&rlm;", 
+            "description": "Named entity: rlm; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u200f"
+                ]
+            ]
+        }, 
+        {
+            "input": "&rmoust", 
+            "description": "Bad named entity: rmoust without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&rmoust"
+                ]
+            ]
+        }, 
+        {
+            "input": "&rmoust;", 
+            "description": "Named entity: rmoust; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u23b1"
+                ]
+            ]
+        }, 
+        {
+            "input": "&rmoustache", 
+            "description": "Bad named entity: rmoustache without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&rmoustache"
+                ]
+            ]
+        }, 
+        {
+            "input": "&rmoustache;", 
+            "description": "Named entity: rmoustache; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u23b1"
+                ]
+            ]
+        }, 
+        {
+            "input": "&rnmid", 
+            "description": "Bad named entity: rnmid without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&rnmid"
+                ]
+            ]
+        }, 
+        {
+            "input": "&rnmid;", 
+            "description": "Named entity: rnmid; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2aee"
+                ]
+            ]
+        }, 
+        {
+            "input": "&roang", 
+            "description": "Bad named entity: roang without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&roang"
+                ]
+            ]
+        }, 
+        {
+            "input": "&roang;", 
+            "description": "Named entity: roang; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u27ed"
+                ]
+            ]
+        }, 
+        {
+            "input": "&roarr", 
+            "description": "Bad named entity: roarr without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&roarr"
+                ]
+            ]
+        }, 
+        {
+            "input": "&roarr;", 
+            "description": "Named entity: roarr; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u21fe"
+                ]
+            ]
+        }, 
+        {
+            "input": "&robrk", 
+            "description": "Bad named entity: robrk without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&robrk"
+                ]
+            ]
+        }, 
+        {
+            "input": "&robrk;", 
+            "description": "Named entity: robrk; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u27e7"
+                ]
+            ]
+        }, 
+        {
+            "input": "&ropar", 
+            "description": "Bad named entity: ropar without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&ropar"
+                ]
+            ]
+        }, 
+        {
+            "input": "&ropar;", 
+            "description": "Named entity: ropar; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2986"
+                ]
+            ]
+        }, 
+        {
+            "input": "&ropf", 
+            "description": "Bad named entity: ropf without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&ropf"
+                ]
+            ]
+        }, 
+        {
+            "input": "&ropf;", 
+            "description": "Named entity: ropf; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\ud835\udd63"
+                ]
+            ]
+        }, 
+        {
+            "input": "&roplus", 
+            "description": "Bad named entity: roplus without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&roplus"
+                ]
+            ]
+        }, 
+        {
+            "input": "&roplus;", 
+            "description": "Named entity: roplus; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2a2e"
+                ]
+            ]
+        }, 
+        {
+            "input": "&rotimes", 
+            "description": "Bad named entity: rotimes without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&rotimes"
+                ]
+            ]
+        }, 
+        {
+            "input": "&rotimes;", 
+            "description": "Named entity: rotimes; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2a35"
+                ]
+            ]
+        }, 
+        {
+            "input": "&rpar", 
+            "description": "Bad named entity: rpar without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&rpar"
+                ]
+            ]
+        }, 
+        {
+            "input": "&rpar;", 
+            "description": "Named entity: rpar; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    ")"
+                ]
+            ]
+        }, 
+        {
+            "input": "&rpargt", 
+            "description": "Bad named entity: rpargt without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&rpargt"
+                ]
+            ]
+        }, 
+        {
+            "input": "&rpargt;", 
+            "description": "Named entity: rpargt; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2994"
+                ]
+            ]
+        }, 
+        {
+            "input": "&rppolint", 
+            "description": "Bad named entity: rppolint without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&rppolint"
+                ]
+            ]
+        }, 
+        {
+            "input": "&rppolint;", 
+            "description": "Named entity: rppolint; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2a12"
+                ]
+            ]
+        }, 
+        {
+            "input": "&rrarr", 
+            "description": "Bad named entity: rrarr without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&rrarr"
+                ]
+            ]
+        }, 
+        {
+            "input": "&rrarr;", 
+            "description": "Named entity: rrarr; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u21c9"
+                ]
+            ]
+        }, 
+        {
+            "input": "&rsaquo", 
+            "description": "Bad named entity: rsaquo without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&rsaquo"
+                ]
+            ]
+        }, 
+        {
+            "input": "&rsaquo;", 
+            "description": "Named entity: rsaquo; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u203a"
+                ]
+            ]
+        }, 
+        {
+            "input": "&rscr", 
+            "description": "Bad named entity: rscr without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&rscr"
+                ]
+            ]
+        }, 
+        {
+            "input": "&rscr;", 
+            "description": "Named entity: rscr; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\ud835\udcc7"
+                ]
+            ]
+        }, 
+        {
+            "input": "&rsh", 
+            "description": "Bad named entity: rsh without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&rsh"
+                ]
+            ]
+        }, 
+        {
+            "input": "&rsh;", 
+            "description": "Named entity: rsh; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u21b1"
+                ]
+            ]
+        }, 
+        {
+            "input": "&rsqb", 
+            "description": "Bad named entity: rsqb without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&rsqb"
+                ]
+            ]
+        }, 
+        {
+            "input": "&rsqb;", 
+            "description": "Named entity: rsqb; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "]"
+                ]
+            ]
+        }, 
+        {
+            "input": "&rsquo", 
+            "description": "Bad named entity: rsquo without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&rsquo"
+                ]
+            ]
+        }, 
+        {
+            "input": "&rsquo;", 
+            "description": "Named entity: rsquo; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2019"
+                ]
+            ]
+        }, 
+        {
+            "input": "&rsquor", 
+            "description": "Bad named entity: rsquor without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&rsquor"
+                ]
+            ]
+        }, 
+        {
+            "input": "&rsquor;", 
+            "description": "Named entity: rsquor; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2019"
+                ]
+            ]
+        }, 
+        {
+            "input": "&rthree", 
+            "description": "Bad named entity: rthree without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&rthree"
+                ]
+            ]
+        }, 
+        {
+            "input": "&rthree;", 
+            "description": "Named entity: rthree; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u22cc"
+                ]
+            ]
+        }, 
+        {
+            "input": "&rtimes", 
+            "description": "Bad named entity: rtimes without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&rtimes"
+                ]
+            ]
+        }, 
+        {
+            "input": "&rtimes;", 
+            "description": "Named entity: rtimes; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u22ca"
+                ]
+            ]
+        }, 
+        {
+            "input": "&rtri", 
+            "description": "Bad named entity: rtri without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&rtri"
+                ]
+            ]
+        }, 
+        {
+            "input": "&rtri;", 
+            "description": "Named entity: rtri; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u25b9"
+                ]
+            ]
+        }, 
+        {
+            "input": "&rtrie", 
+            "description": "Bad named entity: rtrie without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&rtrie"
+                ]
+            ]
+        }, 
+        {
+            "input": "&rtrie;", 
+            "description": "Named entity: rtrie; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u22b5"
+                ]
+            ]
+        }, 
+        {
+            "input": "&rtrif", 
+            "description": "Bad named entity: rtrif without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&rtrif"
+                ]
+            ]
+        }, 
+        {
+            "input": "&rtrif;", 
+            "description": "Named entity: rtrif; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u25b8"
+                ]
+            ]
+        }, 
+        {
+            "input": "&rtriltri", 
+            "description": "Bad named entity: rtriltri without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&rtriltri"
+                ]
+            ]
+        }, 
+        {
+            "input": "&rtriltri;", 
+            "description": "Named entity: rtriltri; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u29ce"
+                ]
+            ]
+        }, 
+        {
+            "input": "&ruluhar", 
+            "description": "Bad named entity: ruluhar without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&ruluhar"
+                ]
+            ]
+        }, 
+        {
+            "input": "&ruluhar;", 
+            "description": "Named entity: ruluhar; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2968"
+                ]
+            ]
+        }, 
+        {
+            "input": "&rx", 
+            "description": "Bad named entity: rx without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&rx"
+                ]
+            ]
+        }, 
+        {
+            "input": "&rx;", 
+            "description": "Named entity: rx; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u211e"
+                ]
+            ]
+        }, 
+        {
+            "input": "&sacute", 
+            "description": "Bad named entity: sacute without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&sacute"
+                ]
+            ]
+        }, 
+        {
+            "input": "&sacute;", 
+            "description": "Named entity: sacute; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u015b"
+                ]
+            ]
+        }, 
+        {
+            "input": "&sbquo", 
+            "description": "Bad named entity: sbquo without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&sbquo"
+                ]
+            ]
+        }, 
+        {
+            "input": "&sbquo;", 
+            "description": "Named entity: sbquo; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u201a"
+                ]
+            ]
+        }, 
+        {
+            "input": "&sc", 
+            "description": "Bad named entity: sc without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&sc"
+                ]
+            ]
+        }, 
+        {
+            "input": "&sc;", 
+            "description": "Named entity: sc; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u227b"
+                ]
+            ]
+        }, 
+        {
+            "input": "&scE", 
+            "description": "Bad named entity: scE without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&scE"
+                ]
+            ]
+        }, 
+        {
+            "input": "&scE;", 
+            "description": "Named entity: scE; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2ab4"
+                ]
+            ]
+        }, 
+        {
+            "input": "&scap", 
+            "description": "Bad named entity: scap without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&scap"
+                ]
+            ]
+        }, 
+        {
+            "input": "&scap;", 
+            "description": "Named entity: scap; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2ab8"
+                ]
+            ]
+        }, 
+        {
+            "input": "&scaron", 
+            "description": "Bad named entity: scaron without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&scaron"
+                ]
+            ]
+        }, 
+        {
+            "input": "&scaron;", 
+            "description": "Named entity: scaron; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u0161"
+                ]
+            ]
+        }, 
+        {
+            "input": "&sccue", 
+            "description": "Bad named entity: sccue without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&sccue"
+                ]
+            ]
+        }, 
+        {
+            "input": "&sccue;", 
+            "description": "Named entity: sccue; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u227d"
+                ]
+            ]
+        }, 
+        {
+            "input": "&sce", 
+            "description": "Bad named entity: sce without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&sce"
+                ]
+            ]
+        }, 
+        {
+            "input": "&sce;", 
+            "description": "Named entity: sce; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2ab0"
+                ]
+            ]
+        }, 
+        {
+            "input": "&scedil", 
+            "description": "Bad named entity: scedil without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&scedil"
+                ]
+            ]
+        }, 
+        {
+            "input": "&scedil;", 
+            "description": "Named entity: scedil; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u015f"
+                ]
+            ]
+        }, 
+        {
+            "input": "&scirc", 
+            "description": "Bad named entity: scirc without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&scirc"
+                ]
+            ]
+        }, 
+        {
+            "input": "&scirc;", 
+            "description": "Named entity: scirc; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u015d"
+                ]
+            ]
+        }, 
+        {
+            "input": "&scnE", 
+            "description": "Bad named entity: scnE without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&scnE"
+                ]
+            ]
+        }, 
+        {
+            "input": "&scnE;", 
+            "description": "Named entity: scnE; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2ab6"
+                ]
+            ]
+        }, 
+        {
+            "input": "&scnap", 
+            "description": "Bad named entity: scnap without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&scnap"
+                ]
+            ]
+        }, 
+        {
+            "input": "&scnap;", 
+            "description": "Named entity: scnap; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2aba"
+                ]
+            ]
+        }, 
+        {
+            "input": "&scnsim", 
+            "description": "Bad named entity: scnsim without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&scnsim"
+                ]
+            ]
+        }, 
+        {
+            "input": "&scnsim;", 
+            "description": "Named entity: scnsim; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u22e9"
+                ]
+            ]
+        }, 
+        {
+            "input": "&scpolint", 
+            "description": "Bad named entity: scpolint without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&scpolint"
+                ]
+            ]
+        }, 
+        {
+            "input": "&scpolint;", 
+            "description": "Named entity: scpolint; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2a13"
+                ]
+            ]
+        }, 
+        {
+            "input": "&scsim", 
+            "description": "Bad named entity: scsim without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&scsim"
+                ]
+            ]
+        }, 
+        {
+            "input": "&scsim;", 
+            "description": "Named entity: scsim; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u227f"
+                ]
+            ]
+        }, 
+        {
+            "input": "&scy", 
+            "description": "Bad named entity: scy without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&scy"
+                ]
+            ]
+        }, 
+        {
+            "input": "&scy;", 
+            "description": "Named entity: scy; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u0441"
+                ]
+            ]
+        }, 
+        {
+            "input": "&sdot", 
+            "description": "Bad named entity: sdot without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&sdot"
+                ]
+            ]
+        }, 
+        {
+            "input": "&sdot;", 
+            "description": "Named entity: sdot; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u22c5"
+                ]
+            ]
+        }, 
+        {
+            "input": "&sdotb", 
+            "description": "Bad named entity: sdotb without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&sdotb"
+                ]
+            ]
+        }, 
+        {
+            "input": "&sdotb;", 
+            "description": "Named entity: sdotb; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u22a1"
+                ]
+            ]
+        }, 
+        {
+            "input": "&sdote", 
+            "description": "Bad named entity: sdote without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&sdote"
+                ]
+            ]
+        }, 
+        {
+            "input": "&sdote;", 
+            "description": "Named entity: sdote; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2a66"
+                ]
+            ]
+        }, 
+        {
+            "input": "&seArr", 
+            "description": "Bad named entity: seArr without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&seArr"
+                ]
+            ]
+        }, 
+        {
+            "input": "&seArr;", 
+            "description": "Named entity: seArr; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u21d8"
+                ]
+            ]
+        }, 
+        {
+            "input": "&searhk", 
+            "description": "Bad named entity: searhk without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&searhk"
+                ]
+            ]
+        }, 
+        {
+            "input": "&searhk;", 
+            "description": "Named entity: searhk; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2925"
+                ]
+            ]
+        }, 
+        {
+            "input": "&searr", 
+            "description": "Bad named entity: searr without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&searr"
+                ]
+            ]
+        }, 
+        {
+            "input": "&searr;", 
+            "description": "Named entity: searr; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2198"
+                ]
+            ]
+        }, 
+        {
+            "input": "&searrow", 
+            "description": "Bad named entity: searrow without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&searrow"
+                ]
+            ]
+        }, 
+        {
+            "input": "&searrow;", 
+            "description": "Named entity: searrow; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2198"
+                ]
+            ]
+        }, 
+        {
+            "input": "&sect", 
+            "description": "Named entity: sect without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "\u00a7"
+                ]
+            ]
+        }, 
+        {
+            "input": "&sect;", 
+            "description": "Named entity: sect; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u00a7"
+                ]
+            ]
+        }, 
+        {
+            "input": "&semi", 
+            "description": "Bad named entity: semi without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&semi"
+                ]
+            ]
+        }, 
+        {
+            "input": "&semi;", 
+            "description": "Named entity: semi; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    ";"
+                ]
+            ]
+        }, 
+        {
+            "input": "&seswar", 
+            "description": "Bad named entity: seswar without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&seswar"
+                ]
+            ]
+        }, 
+        {
+            "input": "&seswar;", 
+            "description": "Named entity: seswar; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2929"
+                ]
+            ]
+        }, 
+        {
+            "input": "&setminus", 
+            "description": "Bad named entity: setminus without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&setminus"
+                ]
+            ]
+        }, 
+        {
+            "input": "&setminus;", 
+            "description": "Named entity: setminus; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2216"
+                ]
+            ]
+        }, 
+        {
+            "input": "&setmn", 
+            "description": "Bad named entity: setmn without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&setmn"
+                ]
+            ]
+        }, 
+        {
+            "input": "&setmn;", 
+            "description": "Named entity: setmn; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2216"
+                ]
+            ]
+        }, 
+        {
+            "input": "&sext", 
+            "description": "Bad named entity: sext without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&sext"
+                ]
+            ]
+        }, 
+        {
+            "input": "&sext;", 
+            "description": "Named entity: sext; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2736"
+                ]
+            ]
+        }, 
+        {
+            "input": "&sfr", 
+            "description": "Bad named entity: sfr without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&sfr"
+                ]
+            ]
+        }, 
+        {
+            "input": "&sfr;", 
+            "description": "Named entity: sfr; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\ud835\udd30"
+                ]
+            ]
+        }, 
+        {
+            "input": "&sfrown", 
+            "description": "Bad named entity: sfrown without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&sfrown"
+                ]
+            ]
+        }, 
+        {
+            "input": "&sfrown;", 
+            "description": "Named entity: sfrown; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2322"
+                ]
+            ]
+        }, 
+        {
+            "input": "&sharp", 
+            "description": "Bad named entity: sharp without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&sharp"
+                ]
+            ]
+        }, 
+        {
+            "input": "&sharp;", 
+            "description": "Named entity: sharp; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u266f"
+                ]
+            ]
+        }, 
+        {
+            "input": "&shchcy", 
+            "description": "Bad named entity: shchcy without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&shchcy"
+                ]
+            ]
+        }, 
+        {
+            "input": "&shchcy;", 
+            "description": "Named entity: shchcy; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u0449"
+                ]
+            ]
+        }, 
+        {
+            "input": "&shcy", 
+            "description": "Bad named entity: shcy without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&shcy"
+                ]
+            ]
+        }, 
+        {
+            "input": "&shcy;", 
+            "description": "Named entity: shcy; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u0448"
+                ]
+            ]
+        }, 
+        {
+            "input": "&shortmid", 
+            "description": "Bad named entity: shortmid without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&shortmid"
+                ]
+            ]
+        }, 
+        {
+            "input": "&shortmid;", 
+            "description": "Named entity: shortmid; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2223"
+                ]
+            ]
+        }, 
+        {
+            "input": "&shortparallel", 
+            "description": "Bad named entity: shortparallel without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&shortparallel"
+                ]
+            ]
+        }, 
+        {
+            "input": "&shortparallel;", 
+            "description": "Named entity: shortparallel; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2225"
+                ]
+            ]
+        }, 
+        {
+            "input": "&shy", 
+            "description": "Named entity: shy without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "\u00ad"
+                ]
+            ]
+        }, 
+        {
+            "input": "&shy;", 
+            "description": "Named entity: shy; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u00ad"
+                ]
+            ]
+        }, 
+        {
+            "input": "&sigma", 
+            "description": "Bad named entity: sigma without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&sigma"
+                ]
+            ]
+        }, 
+        {
+            "input": "&sigma;", 
+            "description": "Named entity: sigma; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u03c3"
+                ]
+            ]
+        }, 
+        {
+            "input": "&sigmaf", 
+            "description": "Bad named entity: sigmaf without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&sigmaf"
+                ]
+            ]
+        }, 
+        {
+            "input": "&sigmaf;", 
+            "description": "Named entity: sigmaf; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u03c2"
+                ]
+            ]
+        }, 
+        {
+            "input": "&sigmav", 
+            "description": "Bad named entity: sigmav without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&sigmav"
+                ]
+            ]
+        }, 
+        {
+            "input": "&sigmav;", 
+            "description": "Named entity: sigmav; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u03c2"
+                ]
+            ]
+        }, 
+        {
+            "input": "&sim", 
+            "description": "Bad named entity: sim without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&sim"
+                ]
+            ]
+        }, 
+        {
+            "input": "&sim;", 
+            "description": "Named entity: sim; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u223c"
+                ]
+            ]
+        }, 
+        {
+            "input": "&simdot", 
+            "description": "Bad named entity: simdot without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&simdot"
+                ]
+            ]
+        }, 
+        {
+            "input": "&simdot;", 
+            "description": "Named entity: simdot; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2a6a"
+                ]
+            ]
+        }, 
+        {
+            "input": "&sime", 
+            "description": "Bad named entity: sime without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&sime"
+                ]
+            ]
+        }, 
+        {
+            "input": "&sime;", 
+            "description": "Named entity: sime; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2243"
+                ]
+            ]
+        }, 
+        {
+            "input": "&simeq", 
+            "description": "Bad named entity: simeq without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&simeq"
+                ]
+            ]
+        }, 
+        {
+            "input": "&simeq;", 
+            "description": "Named entity: simeq; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2243"
+                ]
+            ]
+        }, 
+        {
+            "input": "&simg", 
+            "description": "Bad named entity: simg without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&simg"
+                ]
+            ]
+        }, 
+        {
+            "input": "&simg;", 
+            "description": "Named entity: simg; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2a9e"
+                ]
+            ]
+        }, 
+        {
+            "input": "&simgE", 
+            "description": "Bad named entity: simgE without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&simgE"
+                ]
+            ]
+        }, 
+        {
+            "input": "&simgE;", 
+            "description": "Named entity: simgE; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2aa0"
+                ]
+            ]
+        }, 
+        {
+            "input": "&siml", 
+            "description": "Bad named entity: siml without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&siml"
+                ]
+            ]
+        }, 
+        {
+            "input": "&siml;", 
+            "description": "Named entity: siml; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2a9d"
+                ]
+            ]
+        }, 
+        {
+            "input": "&simlE", 
+            "description": "Bad named entity: simlE without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&simlE"
+                ]
+            ]
+        }, 
+        {
+            "input": "&simlE;", 
+            "description": "Named entity: simlE; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2a9f"
+                ]
+            ]
+        }, 
+        {
+            "input": "&simne", 
+            "description": "Bad named entity: simne without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&simne"
+                ]
+            ]
+        }, 
+        {
+            "input": "&simne;", 
+            "description": "Named entity: simne; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2246"
+                ]
+            ]
+        }, 
+        {
+            "input": "&simplus", 
+            "description": "Bad named entity: simplus without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&simplus"
+                ]
+            ]
+        }, 
+        {
+            "input": "&simplus;", 
+            "description": "Named entity: simplus; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2a24"
+                ]
+            ]
+        }, 
+        {
+            "input": "&simrarr", 
+            "description": "Bad named entity: simrarr without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&simrarr"
+                ]
+            ]
+        }, 
+        {
+            "input": "&simrarr;", 
+            "description": "Named entity: simrarr; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2972"
+                ]
+            ]
+        }, 
+        {
+            "input": "&slarr", 
+            "description": "Bad named entity: slarr without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&slarr"
+                ]
+            ]
+        }, 
+        {
+            "input": "&slarr;", 
+            "description": "Named entity: slarr; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2190"
+                ]
+            ]
+        }, 
+        {
+            "input": "&smallsetminus", 
+            "description": "Bad named entity: smallsetminus without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&smallsetminus"
+                ]
+            ]
+        }, 
+        {
+            "input": "&smallsetminus;", 
+            "description": "Named entity: smallsetminus; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2216"
+                ]
+            ]
+        }, 
+        {
+            "input": "&smashp", 
+            "description": "Bad named entity: smashp without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&smashp"
+                ]
+            ]
+        }, 
+        {
+            "input": "&smashp;", 
+            "description": "Named entity: smashp; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2a33"
+                ]
+            ]
+        }, 
+        {
+            "input": "&smeparsl", 
+            "description": "Bad named entity: smeparsl without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&smeparsl"
+                ]
+            ]
+        }, 
+        {
+            "input": "&smeparsl;", 
+            "description": "Named entity: smeparsl; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u29e4"
+                ]
+            ]
+        }, 
+        {
+            "input": "&smid", 
+            "description": "Bad named entity: smid without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&smid"
+                ]
+            ]
+        }, 
+        {
+            "input": "&smid;", 
+            "description": "Named entity: smid; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2223"
+                ]
+            ]
+        }, 
+        {
+            "input": "&smile", 
+            "description": "Bad named entity: smile without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&smile"
+                ]
+            ]
+        }, 
+        {
+            "input": "&smile;", 
+            "description": "Named entity: smile; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2323"
+                ]
+            ]
+        }, 
+        {
+            "input": "&smt", 
+            "description": "Bad named entity: smt without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&smt"
+                ]
+            ]
+        }, 
+        {
+            "input": "&smt;", 
+            "description": "Named entity: smt; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2aaa"
+                ]
+            ]
+        }, 
+        {
+            "input": "&smte", 
+            "description": "Bad named entity: smte without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&smte"
+                ]
+            ]
+        }, 
+        {
+            "input": "&smte;", 
+            "description": "Named entity: smte; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2aac"
+                ]
+            ]
+        }, 
+        {
+            "input": "&smtes", 
+            "description": "Bad named entity: smtes without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&smtes"
+                ]
+            ]
+        }, 
+        {
+            "input": "&smtes;", 
+            "description": "Named entity: smtes; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2aac\ufe00"
+                ]
+            ]
+        }, 
+        {
+            "input": "&softcy", 
+            "description": "Bad named entity: softcy without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&softcy"
+                ]
+            ]
+        }, 
+        {
+            "input": "&softcy;", 
+            "description": "Named entity: softcy; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u044c"
+                ]
+            ]
+        }, 
+        {
+            "input": "&sol", 
+            "description": "Bad named entity: sol without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&sol"
+                ]
+            ]
+        }, 
+        {
+            "input": "&sol;", 
+            "description": "Named entity: sol; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "/"
+                ]
+            ]
+        }, 
+        {
+            "input": "&solb", 
+            "description": "Bad named entity: solb without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&solb"
+                ]
+            ]
+        }, 
+        {
+            "input": "&solb;", 
+            "description": "Named entity: solb; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u29c4"
+                ]
+            ]
+        }, 
+        {
+            "input": "&solbar", 
+            "description": "Bad named entity: solbar without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&solbar"
+                ]
+            ]
+        }, 
+        {
+            "input": "&solbar;", 
+            "description": "Named entity: solbar; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u233f"
+                ]
+            ]
+        }, 
+        {
+            "input": "&sopf", 
+            "description": "Bad named entity: sopf without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&sopf"
+                ]
+            ]
+        }, 
+        {
+            "input": "&sopf;", 
+            "description": "Named entity: sopf; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\ud835\udd64"
+                ]
+            ]
+        }, 
+        {
+            "input": "&spades", 
+            "description": "Bad named entity: spades without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&spades"
+                ]
+            ]
+        }, 
+        {
+            "input": "&spades;", 
+            "description": "Named entity: spades; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2660"
+                ]
+            ]
+        }, 
+        {
+            "input": "&spadesuit", 
+            "description": "Bad named entity: spadesuit without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&spadesuit"
+                ]
+            ]
+        }, 
+        {
+            "input": "&spadesuit;", 
+            "description": "Named entity: spadesuit; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2660"
+                ]
+            ]
+        }, 
+        {
+            "input": "&spar", 
+            "description": "Bad named entity: spar without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&spar"
+                ]
+            ]
+        }, 
+        {
+            "input": "&spar;", 
+            "description": "Named entity: spar; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2225"
+                ]
+            ]
+        }, 
+        {
+            "input": "&sqcap", 
+            "description": "Bad named entity: sqcap without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&sqcap"
+                ]
+            ]
+        }, 
+        {
+            "input": "&sqcap;", 
+            "description": "Named entity: sqcap; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2293"
+                ]
+            ]
+        }, 
+        {
+            "input": "&sqcaps", 
+            "description": "Bad named entity: sqcaps without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&sqcaps"
+                ]
+            ]
+        }, 
+        {
+            "input": "&sqcaps;", 
+            "description": "Named entity: sqcaps; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2293\ufe00"
+                ]
+            ]
+        }, 
+        {
+            "input": "&sqcup", 
+            "description": "Bad named entity: sqcup without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&sqcup"
+                ]
+            ]
+        }, 
+        {
+            "input": "&sqcup;", 
+            "description": "Named entity: sqcup; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2294"
+                ]
+            ]
+        }, 
+        {
+            "input": "&sqcups", 
+            "description": "Bad named entity: sqcups without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&sqcups"
+                ]
+            ]
+        }, 
+        {
+            "input": "&sqcups;", 
+            "description": "Named entity: sqcups; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2294\ufe00"
+                ]
+            ]
+        }, 
+        {
+            "input": "&sqsub", 
+            "description": "Bad named entity: sqsub without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&sqsub"
+                ]
+            ]
+        }, 
+        {
+            "input": "&sqsub;", 
+            "description": "Named entity: sqsub; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u228f"
+                ]
+            ]
+        }, 
+        {
+            "input": "&sqsube", 
+            "description": "Bad named entity: sqsube without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&sqsube"
+                ]
+            ]
+        }, 
+        {
+            "input": "&sqsube;", 
+            "description": "Named entity: sqsube; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2291"
+                ]
+            ]
+        }, 
+        {
+            "input": "&sqsubset", 
+            "description": "Bad named entity: sqsubset without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&sqsubset"
+                ]
+            ]
+        }, 
+        {
+            "input": "&sqsubset;", 
+            "description": "Named entity: sqsubset; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u228f"
+                ]
+            ]
+        }, 
+        {
+            "input": "&sqsubseteq", 
+            "description": "Bad named entity: sqsubseteq without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&sqsubseteq"
+                ]
+            ]
+        }, 
+        {
+            "input": "&sqsubseteq;", 
+            "description": "Named entity: sqsubseteq; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2291"
+                ]
+            ]
+        }, 
+        {
+            "input": "&sqsup", 
+            "description": "Bad named entity: sqsup without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&sqsup"
+                ]
+            ]
+        }, 
+        {
+            "input": "&sqsup;", 
+            "description": "Named entity: sqsup; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2290"
+                ]
+            ]
+        }, 
+        {
+            "input": "&sqsupe", 
+            "description": "Bad named entity: sqsupe without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&sqsupe"
+                ]
+            ]
+        }, 
+        {
+            "input": "&sqsupe;", 
+            "description": "Named entity: sqsupe; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2292"
+                ]
+            ]
+        }, 
+        {
+            "input": "&sqsupset", 
+            "description": "Bad named entity: sqsupset without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&sqsupset"
+                ]
+            ]
+        }, 
+        {
+            "input": "&sqsupset;", 
+            "description": "Named entity: sqsupset; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2290"
+                ]
+            ]
+        }, 
+        {
+            "input": "&sqsupseteq", 
+            "description": "Bad named entity: sqsupseteq without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&sqsupseteq"
+                ]
+            ]
+        }, 
+        {
+            "input": "&sqsupseteq;", 
+            "description": "Named entity: sqsupseteq; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2292"
+                ]
+            ]
+        }, 
+        {
+            "input": "&squ", 
+            "description": "Bad named entity: squ without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&squ"
+                ]
+            ]
+        }, 
+        {
+            "input": "&squ;", 
+            "description": "Named entity: squ; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u25a1"
+                ]
+            ]
+        }, 
+        {
+            "input": "&square", 
+            "description": "Bad named entity: square without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&square"
+                ]
+            ]
+        }, 
+        {
+            "input": "&square;", 
+            "description": "Named entity: square; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u25a1"
+                ]
+            ]
+        }, 
+        {
+            "input": "&squarf", 
+            "description": "Bad named entity: squarf without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&squarf"
+                ]
+            ]
+        }, 
+        {
+            "input": "&squarf;", 
+            "description": "Named entity: squarf; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u25aa"
+                ]
+            ]
+        }, 
+        {
+            "input": "&squf", 
+            "description": "Bad named entity: squf without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&squf"
+                ]
+            ]
+        }, 
+        {
+            "input": "&squf;", 
+            "description": "Named entity: squf; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u25aa"
+                ]
+            ]
+        }, 
+        {
+            "input": "&srarr", 
+            "description": "Bad named entity: srarr without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&srarr"
+                ]
+            ]
+        }, 
+        {
+            "input": "&srarr;", 
+            "description": "Named entity: srarr; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2192"
+                ]
+            ]
+        }, 
+        {
+            "input": "&sscr", 
+            "description": "Bad named entity: sscr without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&sscr"
+                ]
+            ]
+        }, 
+        {
+            "input": "&sscr;", 
+            "description": "Named entity: sscr; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\ud835\udcc8"
+                ]
+            ]
+        }, 
+        {
+            "input": "&ssetmn", 
+            "description": "Bad named entity: ssetmn without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&ssetmn"
+                ]
+            ]
+        }, 
+        {
+            "input": "&ssetmn;", 
+            "description": "Named entity: ssetmn; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2216"
+                ]
+            ]
+        }, 
+        {
+            "input": "&ssmile", 
+            "description": "Bad named entity: ssmile without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&ssmile"
+                ]
+            ]
+        }, 
+        {
+            "input": "&ssmile;", 
+            "description": "Named entity: ssmile; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2323"
+                ]
+            ]
+        }, 
+        {
+            "input": "&sstarf", 
+            "description": "Bad named entity: sstarf without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&sstarf"
+                ]
+            ]
+        }, 
+        {
+            "input": "&sstarf;", 
+            "description": "Named entity: sstarf; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u22c6"
+                ]
+            ]
+        }, 
+        {
+            "input": "&star", 
+            "description": "Bad named entity: star without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&star"
+                ]
+            ]
+        }, 
+        {
+            "input": "&star;", 
+            "description": "Named entity: star; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2606"
+                ]
+            ]
+        }, 
+        {
+            "input": "&starf", 
+            "description": "Bad named entity: starf without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&starf"
+                ]
+            ]
+        }, 
+        {
+            "input": "&starf;", 
+            "description": "Named entity: starf; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2605"
+                ]
+            ]
+        }, 
+        {
+            "input": "&straightepsilon", 
+            "description": "Bad named entity: straightepsilon without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&straightepsilon"
+                ]
+            ]
+        }, 
+        {
+            "input": "&straightepsilon;", 
+            "description": "Named entity: straightepsilon; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u03f5"
+                ]
+            ]
+        }, 
+        {
+            "input": "&straightphi", 
+            "description": "Bad named entity: straightphi without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&straightphi"
+                ]
+            ]
+        }, 
+        {
+            "input": "&straightphi;", 
+            "description": "Named entity: straightphi; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u03d5"
+                ]
+            ]
+        }, 
+        {
+            "input": "&strns", 
+            "description": "Bad named entity: strns without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&strns"
+                ]
+            ]
+        }, 
+        {
+            "input": "&strns;", 
+            "description": "Named entity: strns; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u00af"
+                ]
+            ]
+        }, 
+        {
+            "input": "&sub", 
+            "description": "Bad named entity: sub without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&sub"
+                ]
+            ]
+        }, 
+        {
+            "input": "&sub;", 
+            "description": "Named entity: sub; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2282"
+                ]
+            ]
+        }, 
+        {
+            "input": "&subE", 
+            "description": "Bad named entity: subE without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&subE"
+                ]
+            ]
+        }, 
+        {
+            "input": "&subE;", 
+            "description": "Named entity: subE; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2ac5"
+                ]
+            ]
+        }, 
+        {
+            "input": "&subdot", 
+            "description": "Bad named entity: subdot without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&subdot"
+                ]
+            ]
+        }, 
+        {
+            "input": "&subdot;", 
+            "description": "Named entity: subdot; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2abd"
+                ]
+            ]
+        }, 
+        {
+            "input": "&sube", 
+            "description": "Bad named entity: sube without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&sube"
+                ]
+            ]
+        }, 
+        {
+            "input": "&sube;", 
+            "description": "Named entity: sube; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2286"
+                ]
+            ]
+        }, 
+        {
+            "input": "&subedot", 
+            "description": "Bad named entity: subedot without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&subedot"
+                ]
+            ]
+        }, 
+        {
+            "input": "&subedot;", 
+            "description": "Named entity: subedot; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2ac3"
+                ]
+            ]
+        }, 
+        {
+            "input": "&submult", 
+            "description": "Bad named entity: submult without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&submult"
+                ]
+            ]
+        }, 
+        {
+            "input": "&submult;", 
+            "description": "Named entity: submult; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2ac1"
+                ]
+            ]
+        }, 
+        {
+            "input": "&subnE", 
+            "description": "Bad named entity: subnE without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&subnE"
+                ]
+            ]
+        }, 
+        {
+            "input": "&subnE;", 
+            "description": "Named entity: subnE; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2acb"
+                ]
+            ]
+        }, 
+        {
+            "input": "&subne", 
+            "description": "Bad named entity: subne without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&subne"
+                ]
+            ]
+        }, 
+        {
+            "input": "&subne;", 
+            "description": "Named entity: subne; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u228a"
+                ]
+            ]
+        }, 
+        {
+            "input": "&subplus", 
+            "description": "Bad named entity: subplus without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&subplus"
+                ]
+            ]
+        }, 
+        {
+            "input": "&subplus;", 
+            "description": "Named entity: subplus; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2abf"
+                ]
+            ]
+        }, 
+        {
+            "input": "&subrarr", 
+            "description": "Bad named entity: subrarr without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&subrarr"
+                ]
+            ]
+        }, 
+        {
+            "input": "&subrarr;", 
+            "description": "Named entity: subrarr; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2979"
+                ]
+            ]
+        }, 
+        {
+            "input": "&subset", 
+            "description": "Bad named entity: subset without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&subset"
+                ]
+            ]
+        }, 
+        {
+            "input": "&subset;", 
+            "description": "Named entity: subset; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2282"
+                ]
+            ]
+        }, 
+        {
+            "input": "&subseteq", 
+            "description": "Bad named entity: subseteq without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&subseteq"
+                ]
+            ]
+        }, 
+        {
+            "input": "&subseteq;", 
+            "description": "Named entity: subseteq; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2286"
+                ]
+            ]
+        }, 
+        {
+            "input": "&subseteqq", 
+            "description": "Bad named entity: subseteqq without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&subseteqq"
+                ]
+            ]
+        }, 
+        {
+            "input": "&subseteqq;", 
+            "description": "Named entity: subseteqq; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2ac5"
+                ]
+            ]
+        }, 
+        {
+            "input": "&subsetneq", 
+            "description": "Bad named entity: subsetneq without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&subsetneq"
+                ]
+            ]
+        }, 
+        {
+            "input": "&subsetneq;", 
+            "description": "Named entity: subsetneq; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u228a"
+                ]
+            ]
+        }, 
+        {
+            "input": "&subsetneqq", 
+            "description": "Bad named entity: subsetneqq without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&subsetneqq"
+                ]
+            ]
+        }, 
+        {
+            "input": "&subsetneqq;", 
+            "description": "Named entity: subsetneqq; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2acb"
+                ]
+            ]
+        }, 
+        {
+            "input": "&subsim", 
+            "description": "Bad named entity: subsim without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&subsim"
+                ]
+            ]
+        }, 
+        {
+            "input": "&subsim;", 
+            "description": "Named entity: subsim; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2ac7"
+                ]
+            ]
+        }, 
+        {
+            "input": "&subsub", 
+            "description": "Bad named entity: subsub without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&subsub"
+                ]
+            ]
+        }, 
+        {
+            "input": "&subsub;", 
+            "description": "Named entity: subsub; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2ad5"
+                ]
+            ]
+        }, 
+        {
+            "input": "&subsup", 
+            "description": "Bad named entity: subsup without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&subsup"
+                ]
+            ]
+        }, 
+        {
+            "input": "&subsup;", 
+            "description": "Named entity: subsup; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2ad3"
+                ]
+            ]
+        }, 
+        {
+            "input": "&succ", 
+            "description": "Bad named entity: succ without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&succ"
+                ]
+            ]
+        }, 
+        {
+            "input": "&succ;", 
+            "description": "Named entity: succ; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u227b"
+                ]
+            ]
+        }, 
+        {
+            "input": "&succapprox", 
+            "description": "Bad named entity: succapprox without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&succapprox"
+                ]
+            ]
+        }, 
+        {
+            "input": "&succapprox;", 
+            "description": "Named entity: succapprox; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2ab8"
+                ]
+            ]
+        }, 
+        {
+            "input": "&succcurlyeq", 
+            "description": "Bad named entity: succcurlyeq without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&succcurlyeq"
+                ]
+            ]
+        }, 
+        {
+            "input": "&succcurlyeq;", 
+            "description": "Named entity: succcurlyeq; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u227d"
+                ]
+            ]
+        }, 
+        {
+            "input": "&succeq", 
+            "description": "Bad named entity: succeq without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&succeq"
+                ]
+            ]
+        }, 
+        {
+            "input": "&succeq;", 
+            "description": "Named entity: succeq; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2ab0"
+                ]
+            ]
+        }, 
+        {
+            "input": "&succnapprox", 
+            "description": "Bad named entity: succnapprox without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&succnapprox"
+                ]
+            ]
+        }, 
+        {
+            "input": "&succnapprox;", 
+            "description": "Named entity: succnapprox; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2aba"
+                ]
+            ]
+        }, 
+        {
+            "input": "&succneqq", 
+            "description": "Bad named entity: succneqq without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&succneqq"
+                ]
+            ]
+        }, 
+        {
+            "input": "&succneqq;", 
+            "description": "Named entity: succneqq; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2ab6"
+                ]
+            ]
+        }, 
+        {
+            "input": "&succnsim", 
+            "description": "Bad named entity: succnsim without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&succnsim"
+                ]
+            ]
+        }, 
+        {
+            "input": "&succnsim;", 
+            "description": "Named entity: succnsim; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u22e9"
+                ]
+            ]
+        }, 
+        {
+            "input": "&succsim", 
+            "description": "Bad named entity: succsim without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&succsim"
+                ]
+            ]
+        }, 
+        {
+            "input": "&succsim;", 
+            "description": "Named entity: succsim; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u227f"
+                ]
+            ]
+        }, 
+        {
+            "input": "&sum", 
+            "description": "Bad named entity: sum without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&sum"
+                ]
+            ]
+        }, 
+        {
+            "input": "&sum;", 
+            "description": "Named entity: sum; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2211"
+                ]
+            ]
+        }, 
+        {
+            "input": "&sung", 
+            "description": "Bad named entity: sung without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&sung"
+                ]
+            ]
+        }, 
+        {
+            "input": "&sung;", 
+            "description": "Named entity: sung; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u266a"
+                ]
+            ]
+        }, 
+        {
+            "input": "&sup", 
+            "description": "Bad named entity: sup without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&sup"
+                ]
+            ]
+        }, 
+        {
+            "input": "&sup1", 
+            "description": "Named entity: sup1 without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "\u00b9"
+                ]
+            ]
+        }, 
+        {
+            "input": "&sup1;", 
+            "description": "Named entity: sup1; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u00b9"
+                ]
+            ]
+        }, 
+        {
+            "input": "&sup2", 
+            "description": "Named entity: sup2 without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "\u00b2"
+                ]
+            ]
+        }, 
+        {
+            "input": "&sup2;", 
+            "description": "Named entity: sup2; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u00b2"
+                ]
+            ]
+        }, 
+        {
+            "input": "&sup3", 
+            "description": "Named entity: sup3 without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "\u00b3"
+                ]
+            ]
+        }, 
+        {
+            "input": "&sup3;", 
+            "description": "Named entity: sup3; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u00b3"
+                ]
+            ]
+        }, 
+        {
+            "input": "&sup;", 
+            "description": "Named entity: sup; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2283"
+                ]
+            ]
+        }, 
+        {
+            "input": "&supE", 
+            "description": "Bad named entity: supE without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&supE"
+                ]
+            ]
+        }, 
+        {
+            "input": "&supE;", 
+            "description": "Named entity: supE; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2ac6"
+                ]
+            ]
+        }, 
+        {
+            "input": "&supdot", 
+            "description": "Bad named entity: supdot without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&supdot"
+                ]
+            ]
+        }, 
+        {
+            "input": "&supdot;", 
+            "description": "Named entity: supdot; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2abe"
+                ]
+            ]
+        }, 
+        {
+            "input": "&supdsub", 
+            "description": "Bad named entity: supdsub without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&supdsub"
+                ]
+            ]
+        }, 
+        {
+            "input": "&supdsub;", 
+            "description": "Named entity: supdsub; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2ad8"
+                ]
+            ]
+        }, 
+        {
+            "input": "&supe", 
+            "description": "Bad named entity: supe without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&supe"
+                ]
+            ]
+        }, 
+        {
+            "input": "&supe;", 
+            "description": "Named entity: supe; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2287"
+                ]
+            ]
+        }, 
+        {
+            "input": "&supedot", 
+            "description": "Bad named entity: supedot without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&supedot"
+                ]
+            ]
+        }, 
+        {
+            "input": "&supedot;", 
+            "description": "Named entity: supedot; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2ac4"
+                ]
+            ]
+        }, 
+        {
+            "input": "&suphsol", 
+            "description": "Bad named entity: suphsol without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&suphsol"
+                ]
+            ]
+        }, 
+        {
+            "input": "&suphsol;", 
+            "description": "Named entity: suphsol; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u27c9"
+                ]
+            ]
+        }, 
+        {
+            "input": "&suphsub", 
+            "description": "Bad named entity: suphsub without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&suphsub"
+                ]
+            ]
+        }, 
+        {
+            "input": "&suphsub;", 
+            "description": "Named entity: suphsub; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2ad7"
+                ]
+            ]
+        }, 
+        {
+            "input": "&suplarr", 
+            "description": "Bad named entity: suplarr without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&suplarr"
+                ]
+            ]
+        }, 
+        {
+            "input": "&suplarr;", 
+            "description": "Named entity: suplarr; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u297b"
+                ]
+            ]
+        }, 
+        {
+            "input": "&supmult", 
+            "description": "Bad named entity: supmult without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&supmult"
+                ]
+            ]
+        }, 
+        {
+            "input": "&supmult;", 
+            "description": "Named entity: supmult; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2ac2"
+                ]
+            ]
+        }, 
+        {
+            "input": "&supnE", 
+            "description": "Bad named entity: supnE without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&supnE"
+                ]
+            ]
+        }, 
+        {
+            "input": "&supnE;", 
+            "description": "Named entity: supnE; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2acc"
+                ]
+            ]
+        }, 
+        {
+            "input": "&supne", 
+            "description": "Bad named entity: supne without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&supne"
+                ]
+            ]
+        }, 
+        {
+            "input": "&supne;", 
+            "description": "Named entity: supne; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u228b"
+                ]
+            ]
+        }, 
+        {
+            "input": "&supplus", 
+            "description": "Bad named entity: supplus without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&supplus"
+                ]
+            ]
+        }, 
+        {
+            "input": "&supplus;", 
+            "description": "Named entity: supplus; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2ac0"
+                ]
+            ]
+        }, 
+        {
+            "input": "&supset", 
+            "description": "Bad named entity: supset without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&supset"
+                ]
+            ]
+        }, 
+        {
+            "input": "&supset;", 
+            "description": "Named entity: supset; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2283"
+                ]
+            ]
+        }, 
+        {
+            "input": "&supseteq", 
+            "description": "Bad named entity: supseteq without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&supseteq"
+                ]
+            ]
+        }, 
+        {
+            "input": "&supseteq;", 
+            "description": "Named entity: supseteq; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2287"
+                ]
+            ]
+        }, 
+        {
+            "input": "&supseteqq", 
+            "description": "Bad named entity: supseteqq without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&supseteqq"
+                ]
+            ]
+        }, 
+        {
+            "input": "&supseteqq;", 
+            "description": "Named entity: supseteqq; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2ac6"
+                ]
+            ]
+        }, 
+        {
+            "input": "&supsetneq", 
+            "description": "Bad named entity: supsetneq without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&supsetneq"
+                ]
+            ]
+        }, 
+        {
+            "input": "&supsetneq;", 
+            "description": "Named entity: supsetneq; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u228b"
+                ]
+            ]
+        }, 
+        {
+            "input": "&supsetneqq", 
+            "description": "Bad named entity: supsetneqq without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&supsetneqq"
+                ]
+            ]
+        }, 
+        {
+            "input": "&supsetneqq;", 
+            "description": "Named entity: supsetneqq; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2acc"
+                ]
+            ]
+        }, 
+        {
+            "input": "&supsim", 
+            "description": "Bad named entity: supsim without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&supsim"
+                ]
+            ]
+        }, 
+        {
+            "input": "&supsim;", 
+            "description": "Named entity: supsim; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2ac8"
+                ]
+            ]
+        }, 
+        {
+            "input": "&supsub", 
+            "description": "Bad named entity: supsub without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&supsub"
+                ]
+            ]
+        }, 
+        {
+            "input": "&supsub;", 
+            "description": "Named entity: supsub; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2ad4"
+                ]
+            ]
+        }, 
+        {
+            "input": "&supsup", 
+            "description": "Bad named entity: supsup without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&supsup"
+                ]
+            ]
+        }, 
+        {
+            "input": "&supsup;", 
+            "description": "Named entity: supsup; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2ad6"
+                ]
+            ]
+        }, 
+        {
+            "input": "&swArr", 
+            "description": "Bad named entity: swArr without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&swArr"
+                ]
+            ]
+        }, 
+        {
+            "input": "&swArr;", 
+            "description": "Named entity: swArr; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u21d9"
+                ]
+            ]
+        }, 
+        {
+            "input": "&swarhk", 
+            "description": "Bad named entity: swarhk without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&swarhk"
+                ]
+            ]
+        }, 
+        {
+            "input": "&swarhk;", 
+            "description": "Named entity: swarhk; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2926"
+                ]
+            ]
+        }, 
+        {
+            "input": "&swarr", 
+            "description": "Bad named entity: swarr without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&swarr"
+                ]
+            ]
+        }, 
+        {
+            "input": "&swarr;", 
+            "description": "Named entity: swarr; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2199"
+                ]
+            ]
+        }, 
+        {
+            "input": "&swarrow", 
+            "description": "Bad named entity: swarrow without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&swarrow"
+                ]
+            ]
+        }, 
+        {
+            "input": "&swarrow;", 
+            "description": "Named entity: swarrow; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2199"
+                ]
+            ]
+        }, 
+        {
+            "input": "&swnwar", 
+            "description": "Bad named entity: swnwar without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&swnwar"
+                ]
+            ]
+        }, 
+        {
+            "input": "&swnwar;", 
+            "description": "Named entity: swnwar; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u292a"
+                ]
+            ]
+        }, 
+        {
+            "input": "&szlig", 
+            "description": "Named entity: szlig without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "\u00df"
+                ]
+            ]
+        }, 
+        {
+            "input": "&szlig;", 
+            "description": "Named entity: szlig; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u00df"
+                ]
+            ]
+        }, 
+        {
+            "input": "&target", 
+            "description": "Bad named entity: target without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&target"
+                ]
+            ]
+        }, 
+        {
+            "input": "&target;", 
+            "description": "Named entity: target; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2316"
+                ]
+            ]
+        }, 
+        {
+            "input": "&tau", 
+            "description": "Bad named entity: tau without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&tau"
+                ]
+            ]
+        }, 
+        {
+            "input": "&tau;", 
+            "description": "Named entity: tau; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u03c4"
+                ]
+            ]
+        }, 
+        {
+            "input": "&tbrk", 
+            "description": "Bad named entity: tbrk without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&tbrk"
+                ]
+            ]
+        }, 
+        {
+            "input": "&tbrk;", 
+            "description": "Named entity: tbrk; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u23b4"
+                ]
+            ]
+        }, 
+        {
+            "input": "&tcaron", 
+            "description": "Bad named entity: tcaron without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&tcaron"
+                ]
+            ]
+        }, 
+        {
+            "input": "&tcaron;", 
+            "description": "Named entity: tcaron; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u0165"
+                ]
+            ]
+        }, 
+        {
+            "input": "&tcedil", 
+            "description": "Bad named entity: tcedil without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&tcedil"
+                ]
+            ]
+        }, 
+        {
+            "input": "&tcedil;", 
+            "description": "Named entity: tcedil; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u0163"
+                ]
+            ]
+        }, 
+        {
+            "input": "&tcy", 
+            "description": "Bad named entity: tcy without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&tcy"
+                ]
+            ]
+        }, 
+        {
+            "input": "&tcy;", 
+            "description": "Named entity: tcy; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u0442"
+                ]
+            ]
+        }, 
+        {
+            "input": "&tdot", 
+            "description": "Bad named entity: tdot without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&tdot"
+                ]
+            ]
+        }, 
+        {
+            "input": "&tdot;", 
+            "description": "Named entity: tdot; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u20db"
+                ]
+            ]
+        }, 
+        {
+            "input": "&telrec", 
+            "description": "Bad named entity: telrec without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&telrec"
+                ]
+            ]
+        }, 
+        {
+            "input": "&telrec;", 
+            "description": "Named entity: telrec; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2315"
+                ]
+            ]
+        }, 
+        {
+            "input": "&tfr", 
+            "description": "Bad named entity: tfr without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&tfr"
+                ]
+            ]
+        }, 
+        {
+            "input": "&tfr;", 
+            "description": "Named entity: tfr; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\ud835\udd31"
+                ]
+            ]
+        }, 
+        {
+            "input": "&there4", 
+            "description": "Bad named entity: there4 without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&there4"
+                ]
+            ]
+        }, 
+        {
+            "input": "&there4;", 
+            "description": "Named entity: there4; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2234"
+                ]
+            ]
+        }, 
+        {
+            "input": "&therefore", 
+            "description": "Bad named entity: therefore without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&therefore"
+                ]
+            ]
+        }, 
+        {
+            "input": "&therefore;", 
+            "description": "Named entity: therefore; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2234"
+                ]
+            ]
+        }, 
+        {
+            "input": "&theta", 
+            "description": "Bad named entity: theta without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&theta"
+                ]
+            ]
+        }, 
+        {
+            "input": "&theta;", 
+            "description": "Named entity: theta; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u03b8"
+                ]
+            ]
+        }, 
+        {
+            "input": "&thetasym", 
+            "description": "Bad named entity: thetasym without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&thetasym"
+                ]
+            ]
+        }, 
+        {
+            "input": "&thetasym;", 
+            "description": "Named entity: thetasym; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u03d1"
+                ]
+            ]
+        }, 
+        {
+            "input": "&thetav", 
+            "description": "Bad named entity: thetav without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&thetav"
+                ]
+            ]
+        }, 
+        {
+            "input": "&thetav;", 
+            "description": "Named entity: thetav; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u03d1"
+                ]
+            ]
+        }, 
+        {
+            "input": "&thickapprox", 
+            "description": "Bad named entity: thickapprox without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&thickapprox"
+                ]
+            ]
+        }, 
+        {
+            "input": "&thickapprox;", 
+            "description": "Named entity: thickapprox; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2248"
+                ]
+            ]
+        }, 
+        {
+            "input": "&thicksim", 
+            "description": "Bad named entity: thicksim without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&thicksim"
+                ]
+            ]
+        }, 
+        {
+            "input": "&thicksim;", 
+            "description": "Named entity: thicksim; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u223c"
+                ]
+            ]
+        }, 
+        {
+            "input": "&thinsp", 
+            "description": "Bad named entity: thinsp without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&thinsp"
+                ]
+            ]
+        }, 
+        {
+            "input": "&thinsp;", 
+            "description": "Named entity: thinsp; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2009"
+                ]
+            ]
+        }, 
+        {
+            "input": "&thkap", 
+            "description": "Bad named entity: thkap without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&thkap"
+                ]
+            ]
+        }, 
+        {
+            "input": "&thkap;", 
+            "description": "Named entity: thkap; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2248"
+                ]
+            ]
+        }, 
+        {
+            "input": "&thksim", 
+            "description": "Bad named entity: thksim without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&thksim"
+                ]
+            ]
+        }, 
+        {
+            "input": "&thksim;", 
+            "description": "Named entity: thksim; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u223c"
+                ]
+            ]
+        }, 
+        {
+            "input": "&thorn", 
+            "description": "Named entity: thorn without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "\u00fe"
+                ]
+            ]
+        }, 
+        {
+            "input": "&thorn;", 
+            "description": "Named entity: thorn; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u00fe"
+                ]
+            ]
+        }, 
+        {
+            "input": "&tilde", 
+            "description": "Bad named entity: tilde without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&tilde"
+                ]
+            ]
+        }, 
+        {
+            "input": "&tilde;", 
+            "description": "Named entity: tilde; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u02dc"
+                ]
+            ]
+        }, 
+        {
+            "input": "&times", 
+            "description": "Named entity: times without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "\u00d7"
+                ]
+            ]
+        }, 
+        {
+            "input": "&times;", 
+            "description": "Named entity: times; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u00d7"
+                ]
+            ]
+        }, 
+        {
+            "input": "&timesb;", 
+            "description": "Named entity: timesb; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u22a0"
+                ]
+            ]
+        }, 
+        {
+            "input": "&timesbar;", 
+            "description": "Named entity: timesbar; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2a31"
+                ]
+            ]
+        }, 
+        {
+            "input": "&timesd;", 
+            "description": "Named entity: timesd; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2a30"
+                ]
+            ]
+        }, 
+        {
+            "input": "&tint", 
+            "description": "Bad named entity: tint without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&tint"
+                ]
+            ]
+        }, 
+        {
+            "input": "&tint;", 
+            "description": "Named entity: tint; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u222d"
+                ]
+            ]
+        }, 
+        {
+            "input": "&toea", 
+            "description": "Bad named entity: toea without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&toea"
+                ]
+            ]
+        }, 
+        {
+            "input": "&toea;", 
+            "description": "Named entity: toea; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2928"
+                ]
+            ]
+        }, 
+        {
+            "input": "&top", 
+            "description": "Bad named entity: top without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&top"
+                ]
+            ]
+        }, 
+        {
+            "input": "&top;", 
+            "description": "Named entity: top; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u22a4"
+                ]
+            ]
+        }, 
+        {
+            "input": "&topbot", 
+            "description": "Bad named entity: topbot without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&topbot"
+                ]
+            ]
+        }, 
+        {
+            "input": "&topbot;", 
+            "description": "Named entity: topbot; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2336"
+                ]
+            ]
+        }, 
+        {
+            "input": "&topcir", 
+            "description": "Bad named entity: topcir without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&topcir"
+                ]
+            ]
+        }, 
+        {
+            "input": "&topcir;", 
+            "description": "Named entity: topcir; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2af1"
+                ]
+            ]
+        }, 
+        {
+            "input": "&topf", 
+            "description": "Bad named entity: topf without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&topf"
+                ]
+            ]
+        }, 
+        {
+            "input": "&topf;", 
+            "description": "Named entity: topf; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\ud835\udd65"
+                ]
+            ]
+        }, 
+        {
+            "input": "&topfork", 
+            "description": "Bad named entity: topfork without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&topfork"
+                ]
+            ]
+        }, 
+        {
+            "input": "&topfork;", 
+            "description": "Named entity: topfork; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2ada"
+                ]
+            ]
+        }, 
+        {
+            "input": "&tosa", 
+            "description": "Bad named entity: tosa without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&tosa"
+                ]
+            ]
+        }, 
+        {
+            "input": "&tosa;", 
+            "description": "Named entity: tosa; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2929"
+                ]
+            ]
+        }, 
+        {
+            "input": "&tprime", 
+            "description": "Bad named entity: tprime without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&tprime"
+                ]
+            ]
+        }, 
+        {
+            "input": "&tprime;", 
+            "description": "Named entity: tprime; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2034"
+                ]
+            ]
+        }, 
+        {
+            "input": "&trade", 
+            "description": "Bad named entity: trade without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&trade"
+                ]
+            ]
+        }, 
+        {
+            "input": "&trade;", 
+            "description": "Named entity: trade; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2122"
+                ]
+            ]
+        }, 
+        {
+            "input": "&triangle", 
+            "description": "Bad named entity: triangle without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&triangle"
+                ]
+            ]
+        }, 
+        {
+            "input": "&triangle;", 
+            "description": "Named entity: triangle; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u25b5"
+                ]
+            ]
+        }, 
+        {
+            "input": "&triangledown", 
+            "description": "Bad named entity: triangledown without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&triangledown"
+                ]
+            ]
+        }, 
+        {
+            "input": "&triangledown;", 
+            "description": "Named entity: triangledown; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u25bf"
+                ]
+            ]
+        }, 
+        {
+            "input": "&triangleleft", 
+            "description": "Bad named entity: triangleleft without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&triangleleft"
+                ]
+            ]
+        }, 
+        {
+            "input": "&triangleleft;", 
+            "description": "Named entity: triangleleft; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u25c3"
+                ]
+            ]
+        }, 
+        {
+            "input": "&trianglelefteq", 
+            "description": "Bad named entity: trianglelefteq without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&trianglelefteq"
+                ]
+            ]
+        }, 
+        {
+            "input": "&trianglelefteq;", 
+            "description": "Named entity: trianglelefteq; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u22b4"
+                ]
+            ]
+        }, 
+        {
+            "input": "&triangleq", 
+            "description": "Bad named entity: triangleq without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&triangleq"
+                ]
+            ]
+        }, 
+        {
+            "input": "&triangleq;", 
+            "description": "Named entity: triangleq; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u225c"
+                ]
+            ]
+        }, 
+        {
+            "input": "&triangleright", 
+            "description": "Bad named entity: triangleright without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&triangleright"
+                ]
+            ]
+        }, 
+        {
+            "input": "&triangleright;", 
+            "description": "Named entity: triangleright; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u25b9"
+                ]
+            ]
+        }, 
+        {
+            "input": "&trianglerighteq", 
+            "description": "Bad named entity: trianglerighteq without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&trianglerighteq"
+                ]
+            ]
+        }, 
+        {
+            "input": "&trianglerighteq;", 
+            "description": "Named entity: trianglerighteq; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u22b5"
+                ]
+            ]
+        }, 
+        {
+            "input": "&tridot", 
+            "description": "Bad named entity: tridot without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&tridot"
+                ]
+            ]
+        }, 
+        {
+            "input": "&tridot;", 
+            "description": "Named entity: tridot; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u25ec"
+                ]
+            ]
+        }, 
+        {
+            "input": "&trie", 
+            "description": "Bad named entity: trie without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&trie"
+                ]
+            ]
+        }, 
+        {
+            "input": "&trie;", 
+            "description": "Named entity: trie; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u225c"
+                ]
+            ]
+        }, 
+        {
+            "input": "&triminus", 
+            "description": "Bad named entity: triminus without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&triminus"
+                ]
+            ]
+        }, 
+        {
+            "input": "&triminus;", 
+            "description": "Named entity: triminus; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2a3a"
+                ]
+            ]
+        }, 
+        {
+            "input": "&triplus", 
+            "description": "Bad named entity: triplus without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&triplus"
+                ]
+            ]
+        }, 
+        {
+            "input": "&triplus;", 
+            "description": "Named entity: triplus; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2a39"
+                ]
+            ]
+        }, 
+        {
+            "input": "&trisb", 
+            "description": "Bad named entity: trisb without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&trisb"
+                ]
+            ]
+        }, 
+        {
+            "input": "&trisb;", 
+            "description": "Named entity: trisb; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u29cd"
+                ]
+            ]
+        }, 
+        {
+            "input": "&tritime", 
+            "description": "Bad named entity: tritime without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&tritime"
+                ]
+            ]
+        }, 
+        {
+            "input": "&tritime;", 
+            "description": "Named entity: tritime; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2a3b"
+                ]
+            ]
+        }, 
+        {
+            "input": "&trpezium", 
+            "description": "Bad named entity: trpezium without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&trpezium"
+                ]
+            ]
+        }, 
+        {
+            "input": "&trpezium;", 
+            "description": "Named entity: trpezium; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u23e2"
+                ]
+            ]
+        }, 
+        {
+            "input": "&tscr", 
+            "description": "Bad named entity: tscr without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&tscr"
+                ]
+            ]
+        }, 
+        {
+            "input": "&tscr;", 
+            "description": "Named entity: tscr; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\ud835\udcc9"
+                ]
+            ]
+        }, 
+        {
+            "input": "&tscy", 
+            "description": "Bad named entity: tscy without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&tscy"
+                ]
+            ]
+        }, 
+        {
+            "input": "&tscy;", 
+            "description": "Named entity: tscy; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u0446"
+                ]
+            ]
+        }, 
+        {
+            "input": "&tshcy", 
+            "description": "Bad named entity: tshcy without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&tshcy"
+                ]
+            ]
+        }, 
+        {
+            "input": "&tshcy;", 
+            "description": "Named entity: tshcy; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u045b"
+                ]
+            ]
+        }, 
+        {
+            "input": "&tstrok", 
+            "description": "Bad named entity: tstrok without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&tstrok"
+                ]
+            ]
+        }, 
+        {
+            "input": "&tstrok;", 
+            "description": "Named entity: tstrok; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u0167"
+                ]
+            ]
+        }, 
+        {
+            "input": "&twixt", 
+            "description": "Bad named entity: twixt without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&twixt"
+                ]
+            ]
+        }, 
+        {
+            "input": "&twixt;", 
+            "description": "Named entity: twixt; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u226c"
+                ]
+            ]
+        }, 
+        {
+            "input": "&twoheadleftarrow", 
+            "description": "Bad named entity: twoheadleftarrow without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&twoheadleftarrow"
+                ]
+            ]
+        }, 
+        {
+            "input": "&twoheadleftarrow;", 
+            "description": "Named entity: twoheadleftarrow; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u219e"
+                ]
+            ]
+        }, 
+        {
+            "input": "&twoheadrightarrow", 
+            "description": "Bad named entity: twoheadrightarrow without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&twoheadrightarrow"
+                ]
+            ]
+        }, 
+        {
+            "input": "&twoheadrightarrow;", 
+            "description": "Named entity: twoheadrightarrow; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u21a0"
+                ]
+            ]
+        }, 
+        {
+            "input": "&uArr", 
+            "description": "Bad named entity: uArr without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&uArr"
+                ]
+            ]
+        }, 
+        {
+            "input": "&uArr;", 
+            "description": "Named entity: uArr; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u21d1"
+                ]
+            ]
+        }, 
+        {
+            "input": "&uHar", 
+            "description": "Bad named entity: uHar without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&uHar"
+                ]
+            ]
+        }, 
+        {
+            "input": "&uHar;", 
+            "description": "Named entity: uHar; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2963"
+                ]
+            ]
+        }, 
+        {
+            "input": "&uacute", 
+            "description": "Named entity: uacute without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "\u00fa"
+                ]
+            ]
+        }, 
+        {
+            "input": "&uacute;", 
+            "description": "Named entity: uacute; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u00fa"
+                ]
+            ]
+        }, 
+        {
+            "input": "&uarr", 
+            "description": "Bad named entity: uarr without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&uarr"
+                ]
+            ]
+        }, 
+        {
+            "input": "&uarr;", 
+            "description": "Named entity: uarr; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2191"
+                ]
+            ]
+        }, 
+        {
+            "input": "&ubrcy", 
+            "description": "Bad named entity: ubrcy without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&ubrcy"
+                ]
+            ]
+        }, 
+        {
+            "input": "&ubrcy;", 
+            "description": "Named entity: ubrcy; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u045e"
+                ]
+            ]
+        }, 
+        {
+            "input": "&ubreve", 
+            "description": "Bad named entity: ubreve without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&ubreve"
+                ]
+            ]
+        }, 
+        {
+            "input": "&ubreve;", 
+            "description": "Named entity: ubreve; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u016d"
+                ]
+            ]
+        }, 
+        {
+            "input": "&ucirc", 
+            "description": "Named entity: ucirc without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "\u00fb"
+                ]
+            ]
+        }, 
+        {
+            "input": "&ucirc;", 
+            "description": "Named entity: ucirc; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u00fb"
+                ]
+            ]
+        }, 
+        {
+            "input": "&ucy", 
+            "description": "Bad named entity: ucy without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&ucy"
+                ]
+            ]
+        }, 
+        {
+            "input": "&ucy;", 
+            "description": "Named entity: ucy; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u0443"
+                ]
+            ]
+        }, 
+        {
+            "input": "&udarr", 
+            "description": "Bad named entity: udarr without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&udarr"
+                ]
+            ]
+        }, 
+        {
+            "input": "&udarr;", 
+            "description": "Named entity: udarr; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u21c5"
+                ]
+            ]
+        }, 
+        {
+            "input": "&udblac", 
+            "description": "Bad named entity: udblac without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&udblac"
+                ]
+            ]
+        }, 
+        {
+            "input": "&udblac;", 
+            "description": "Named entity: udblac; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u0171"
+                ]
+            ]
+        }, 
+        {
+            "input": "&udhar", 
+            "description": "Bad named entity: udhar without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&udhar"
+                ]
+            ]
+        }, 
+        {
+            "input": "&udhar;", 
+            "description": "Named entity: udhar; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u296e"
+                ]
+            ]
+        }, 
+        {
+            "input": "&ufisht", 
+            "description": "Bad named entity: ufisht without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&ufisht"
+                ]
+            ]
+        }, 
+        {
+            "input": "&ufisht;", 
+            "description": "Named entity: ufisht; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u297e"
+                ]
+            ]
+        }, 
+        {
+            "input": "&ufr", 
+            "description": "Bad named entity: ufr without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&ufr"
+                ]
+            ]
+        }, 
+        {
+            "input": "&ufr;", 
+            "description": "Named entity: ufr; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\ud835\udd32"
+                ]
+            ]
+        }, 
+        {
+            "input": "&ugrave", 
+            "description": "Named entity: ugrave without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "\u00f9"
+                ]
+            ]
+        }, 
+        {
+            "input": "&ugrave;", 
+            "description": "Named entity: ugrave; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u00f9"
+                ]
+            ]
+        }, 
+        {
+            "input": "&uharl", 
+            "description": "Bad named entity: uharl without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&uharl"
+                ]
+            ]
+        }, 
+        {
+            "input": "&uharl;", 
+            "description": "Named entity: uharl; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u21bf"
+                ]
+            ]
+        }, 
+        {
+            "input": "&uharr", 
+            "description": "Bad named entity: uharr without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&uharr"
+                ]
+            ]
+        }, 
+        {
+            "input": "&uharr;", 
+            "description": "Named entity: uharr; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u21be"
+                ]
+            ]
+        }, 
+        {
+            "input": "&uhblk", 
+            "description": "Bad named entity: uhblk without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&uhblk"
+                ]
+            ]
+        }, 
+        {
+            "input": "&uhblk;", 
+            "description": "Named entity: uhblk; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2580"
+                ]
+            ]
+        }, 
+        {
+            "input": "&ulcorn", 
+            "description": "Bad named entity: ulcorn without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&ulcorn"
+                ]
+            ]
+        }, 
+        {
+            "input": "&ulcorn;", 
+            "description": "Named entity: ulcorn; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u231c"
+                ]
+            ]
+        }, 
+        {
+            "input": "&ulcorner", 
+            "description": "Bad named entity: ulcorner without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&ulcorner"
+                ]
+            ]
+        }, 
+        {
+            "input": "&ulcorner;", 
+            "description": "Named entity: ulcorner; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u231c"
+                ]
+            ]
+        }, 
+        {
+            "input": "&ulcrop", 
+            "description": "Bad named entity: ulcrop without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&ulcrop"
+                ]
+            ]
+        }, 
+        {
+            "input": "&ulcrop;", 
+            "description": "Named entity: ulcrop; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u230f"
+                ]
+            ]
+        }, 
+        {
+            "input": "&ultri", 
+            "description": "Bad named entity: ultri without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&ultri"
+                ]
+            ]
+        }, 
+        {
+            "input": "&ultri;", 
+            "description": "Named entity: ultri; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u25f8"
+                ]
+            ]
+        }, 
+        {
+            "input": "&umacr", 
+            "description": "Bad named entity: umacr without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&umacr"
+                ]
+            ]
+        }, 
+        {
+            "input": "&umacr;", 
+            "description": "Named entity: umacr; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u016b"
+                ]
+            ]
+        }, 
+        {
+            "input": "&uml", 
+            "description": "Named entity: uml without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "\u00a8"
+                ]
+            ]
+        }, 
+        {
+            "input": "&uml;", 
+            "description": "Named entity: uml; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u00a8"
+                ]
+            ]
+        }, 
+        {
+            "input": "&uogon", 
+            "description": "Bad named entity: uogon without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&uogon"
+                ]
+            ]
+        }, 
+        {
+            "input": "&uogon;", 
+            "description": "Named entity: uogon; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u0173"
+                ]
+            ]
+        }, 
+        {
+            "input": "&uopf", 
+            "description": "Bad named entity: uopf without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&uopf"
+                ]
+            ]
+        }, 
+        {
+            "input": "&uopf;", 
+            "description": "Named entity: uopf; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\ud835\udd66"
+                ]
+            ]
+        }, 
+        {
+            "input": "&uparrow", 
+            "description": "Bad named entity: uparrow without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&uparrow"
+                ]
+            ]
+        }, 
+        {
+            "input": "&uparrow;", 
+            "description": "Named entity: uparrow; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2191"
+                ]
+            ]
+        }, 
+        {
+            "input": "&updownarrow", 
+            "description": "Bad named entity: updownarrow without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&updownarrow"
+                ]
+            ]
+        }, 
+        {
+            "input": "&updownarrow;", 
+            "description": "Named entity: updownarrow; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2195"
+                ]
+            ]
+        }, 
+        {
+            "input": "&upharpoonleft", 
+            "description": "Bad named entity: upharpoonleft without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&upharpoonleft"
+                ]
+            ]
+        }, 
+        {
+            "input": "&upharpoonleft;", 
+            "description": "Named entity: upharpoonleft; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u21bf"
+                ]
+            ]
+        }, 
+        {
+            "input": "&upharpoonright", 
+            "description": "Bad named entity: upharpoonright without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&upharpoonright"
+                ]
+            ]
+        }, 
+        {
+            "input": "&upharpoonright;", 
+            "description": "Named entity: upharpoonright; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u21be"
+                ]
+            ]
+        }, 
+        {
+            "input": "&uplus", 
+            "description": "Bad named entity: uplus without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&uplus"
+                ]
+            ]
+        }, 
+        {
+            "input": "&uplus;", 
+            "description": "Named entity: uplus; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u228e"
+                ]
+            ]
+        }, 
+        {
+            "input": "&upsi", 
+            "description": "Bad named entity: upsi without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&upsi"
+                ]
+            ]
+        }, 
+        {
+            "input": "&upsi;", 
+            "description": "Named entity: upsi; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u03c5"
+                ]
+            ]
+        }, 
+        {
+            "input": "&upsih", 
+            "description": "Bad named entity: upsih without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&upsih"
+                ]
+            ]
+        }, 
+        {
+            "input": "&upsih;", 
+            "description": "Named entity: upsih; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u03d2"
+                ]
+            ]
+        }, 
+        {
+            "input": "&upsilon", 
+            "description": "Bad named entity: upsilon without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&upsilon"
+                ]
+            ]
+        }, 
+        {
+            "input": "&upsilon;", 
+            "description": "Named entity: upsilon; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u03c5"
+                ]
+            ]
+        }, 
+        {
+            "input": "&upuparrows", 
+            "description": "Bad named entity: upuparrows without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&upuparrows"
+                ]
+            ]
+        }, 
+        {
+            "input": "&upuparrows;", 
+            "description": "Named entity: upuparrows; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u21c8"
+                ]
+            ]
+        }, 
+        {
+            "input": "&urcorn", 
+            "description": "Bad named entity: urcorn without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&urcorn"
+                ]
+            ]
+        }, 
+        {
+            "input": "&urcorn;", 
+            "description": "Named entity: urcorn; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u231d"
+                ]
+            ]
+        }, 
+        {
+            "input": "&urcorner", 
+            "description": "Bad named entity: urcorner without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&urcorner"
+                ]
+            ]
+        }, 
+        {
+            "input": "&urcorner;", 
+            "description": "Named entity: urcorner; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u231d"
+                ]
+            ]
+        }, 
+        {
+            "input": "&urcrop", 
+            "description": "Bad named entity: urcrop without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&urcrop"
+                ]
+            ]
+        }, 
+        {
+            "input": "&urcrop;", 
+            "description": "Named entity: urcrop; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u230e"
+                ]
+            ]
+        }, 
+        {
+            "input": "&uring", 
+            "description": "Bad named entity: uring without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&uring"
+                ]
+            ]
+        }, 
+        {
+            "input": "&uring;", 
+            "description": "Named entity: uring; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u016f"
+                ]
+            ]
+        }, 
+        {
+            "input": "&urtri", 
+            "description": "Bad named entity: urtri without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&urtri"
+                ]
+            ]
+        }, 
+        {
+            "input": "&urtri;", 
+            "description": "Named entity: urtri; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u25f9"
+                ]
+            ]
+        }, 
+        {
+            "input": "&uscr", 
+            "description": "Bad named entity: uscr without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&uscr"
+                ]
+            ]
+        }, 
+        {
+            "input": "&uscr;", 
+            "description": "Named entity: uscr; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\ud835\udcca"
+                ]
+            ]
+        }, 
+        {
+            "input": "&utdot", 
+            "description": "Bad named entity: utdot without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&utdot"
+                ]
+            ]
+        }, 
+        {
+            "input": "&utdot;", 
+            "description": "Named entity: utdot; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u22f0"
+                ]
+            ]
+        }, 
+        {
+            "input": "&utilde", 
+            "description": "Bad named entity: utilde without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&utilde"
+                ]
+            ]
+        }, 
+        {
+            "input": "&utilde;", 
+            "description": "Named entity: utilde; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u0169"
+                ]
+            ]
+        }, 
+        {
+            "input": "&utri", 
+            "description": "Bad named entity: utri without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&utri"
+                ]
+            ]
+        }, 
+        {
+            "input": "&utri;", 
+            "description": "Named entity: utri; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u25b5"
+                ]
+            ]
+        }, 
+        {
+            "input": "&utrif", 
+            "description": "Bad named entity: utrif without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&utrif"
+                ]
+            ]
+        }, 
+        {
+            "input": "&utrif;", 
+            "description": "Named entity: utrif; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u25b4"
+                ]
+            ]
+        }, 
+        {
+            "input": "&uuarr", 
+            "description": "Bad named entity: uuarr without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&uuarr"
+                ]
+            ]
+        }, 
+        {
+            "input": "&uuarr;", 
+            "description": "Named entity: uuarr; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u21c8"
+                ]
+            ]
+        }, 
+        {
+            "input": "&uuml", 
+            "description": "Named entity: uuml without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "\u00fc"
+                ]
+            ]
+        }, 
+        {
+            "input": "&uuml;", 
+            "description": "Named entity: uuml; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u00fc"
+                ]
+            ]
+        }, 
+        {
+            "input": "&uwangle", 
+            "description": "Bad named entity: uwangle without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&uwangle"
+                ]
+            ]
+        }, 
+        {
+            "input": "&uwangle;", 
+            "description": "Named entity: uwangle; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u29a7"
+                ]
+            ]
+        }, 
+        {
+            "input": "&vArr", 
+            "description": "Bad named entity: vArr without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&vArr"
+                ]
+            ]
+        }, 
+        {
+            "input": "&vArr;", 
+            "description": "Named entity: vArr; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u21d5"
+                ]
+            ]
+        }, 
+        {
+            "input": "&vBar", 
+            "description": "Bad named entity: vBar without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&vBar"
+                ]
+            ]
+        }, 
+        {
+            "input": "&vBar;", 
+            "description": "Named entity: vBar; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2ae8"
+                ]
+            ]
+        }, 
+        {
+            "input": "&vBarv", 
+            "description": "Bad named entity: vBarv without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&vBarv"
+                ]
+            ]
+        }, 
+        {
+            "input": "&vBarv;", 
+            "description": "Named entity: vBarv; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2ae9"
+                ]
+            ]
+        }, 
+        {
+            "input": "&vDash", 
+            "description": "Bad named entity: vDash without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&vDash"
+                ]
+            ]
+        }, 
+        {
+            "input": "&vDash;", 
+            "description": "Named entity: vDash; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u22a8"
+                ]
+            ]
+        }, 
+        {
+            "input": "&vangrt", 
+            "description": "Bad named entity: vangrt without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&vangrt"
+                ]
+            ]
+        }, 
+        {
+            "input": "&vangrt;", 
+            "description": "Named entity: vangrt; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u299c"
+                ]
+            ]
+        }, 
+        {
+            "input": "&varepsilon", 
+            "description": "Bad named entity: varepsilon without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&varepsilon"
+                ]
+            ]
+        }, 
+        {
+            "input": "&varepsilon;", 
+            "description": "Named entity: varepsilon; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u03f5"
+                ]
+            ]
+        }, 
+        {
+            "input": "&varkappa", 
+            "description": "Bad named entity: varkappa without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&varkappa"
+                ]
+            ]
+        }, 
+        {
+            "input": "&varkappa;", 
+            "description": "Named entity: varkappa; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u03f0"
+                ]
+            ]
+        }, 
+        {
+            "input": "&varnothing", 
+            "description": "Bad named entity: varnothing without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&varnothing"
+                ]
+            ]
+        }, 
+        {
+            "input": "&varnothing;", 
+            "description": "Named entity: varnothing; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2205"
+                ]
+            ]
+        }, 
+        {
+            "input": "&varphi", 
+            "description": "Bad named entity: varphi without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&varphi"
+                ]
+            ]
+        }, 
+        {
+            "input": "&varphi;", 
+            "description": "Named entity: varphi; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u03d5"
+                ]
+            ]
+        }, 
+        {
+            "input": "&varpi", 
+            "description": "Bad named entity: varpi without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&varpi"
+                ]
+            ]
+        }, 
+        {
+            "input": "&varpi;", 
+            "description": "Named entity: varpi; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u03d6"
+                ]
+            ]
+        }, 
+        {
+            "input": "&varpropto", 
+            "description": "Bad named entity: varpropto without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&varpropto"
+                ]
+            ]
+        }, 
+        {
+            "input": "&varpropto;", 
+            "description": "Named entity: varpropto; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u221d"
+                ]
+            ]
+        }, 
+        {
+            "input": "&varr", 
+            "description": "Bad named entity: varr without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&varr"
+                ]
+            ]
+        }, 
+        {
+            "input": "&varr;", 
+            "description": "Named entity: varr; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2195"
+                ]
+            ]
+        }, 
+        {
+            "input": "&varrho", 
+            "description": "Bad named entity: varrho without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&varrho"
+                ]
+            ]
+        }, 
+        {
+            "input": "&varrho;", 
+            "description": "Named entity: varrho; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u03f1"
+                ]
+            ]
+        }, 
+        {
+            "input": "&varsigma", 
+            "description": "Bad named entity: varsigma without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&varsigma"
+                ]
+            ]
+        }, 
+        {
+            "input": "&varsigma;", 
+            "description": "Named entity: varsigma; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u03c2"
+                ]
+            ]
+        }, 
+        {
+            "input": "&varsubsetneq", 
+            "description": "Bad named entity: varsubsetneq without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&varsubsetneq"
+                ]
+            ]
+        }, 
+        {
+            "input": "&varsubsetneq;", 
+            "description": "Named entity: varsubsetneq; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u228a\ufe00"
+                ]
+            ]
+        }, 
+        {
+            "input": "&varsubsetneqq", 
+            "description": "Bad named entity: varsubsetneqq without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&varsubsetneqq"
+                ]
+            ]
+        }, 
+        {
+            "input": "&varsubsetneqq;", 
+            "description": "Named entity: varsubsetneqq; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2acb\ufe00"
+                ]
+            ]
+        }, 
+        {
+            "input": "&varsupsetneq", 
+            "description": "Bad named entity: varsupsetneq without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&varsupsetneq"
+                ]
+            ]
+        }, 
+        {
+            "input": "&varsupsetneq;", 
+            "description": "Named entity: varsupsetneq; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u228b\ufe00"
+                ]
+            ]
+        }, 
+        {
+            "input": "&varsupsetneqq", 
+            "description": "Bad named entity: varsupsetneqq without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&varsupsetneqq"
+                ]
+            ]
+        }, 
+        {
+            "input": "&varsupsetneqq;", 
+            "description": "Named entity: varsupsetneqq; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2acc\ufe00"
+                ]
+            ]
+        }, 
+        {
+            "input": "&vartheta", 
+            "description": "Bad named entity: vartheta without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&vartheta"
+                ]
+            ]
+        }, 
+        {
+            "input": "&vartheta;", 
+            "description": "Named entity: vartheta; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u03d1"
+                ]
+            ]
+        }, 
+        {
+            "input": "&vartriangleleft", 
+            "description": "Bad named entity: vartriangleleft without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&vartriangleleft"
+                ]
+            ]
+        }, 
+        {
+            "input": "&vartriangleleft;", 
+            "description": "Named entity: vartriangleleft; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u22b2"
+                ]
+            ]
+        }, 
+        {
+            "input": "&vartriangleright", 
+            "description": "Bad named entity: vartriangleright without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&vartriangleright"
+                ]
+            ]
+        }, 
+        {
+            "input": "&vartriangleright;", 
+            "description": "Named entity: vartriangleright; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u22b3"
+                ]
+            ]
+        }, 
+        {
+            "input": "&vcy", 
+            "description": "Bad named entity: vcy without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&vcy"
+                ]
+            ]
+        }, 
+        {
+            "input": "&vcy;", 
+            "description": "Named entity: vcy; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u0432"
+                ]
+            ]
+        }, 
+        {
+            "input": "&vdash", 
+            "description": "Bad named entity: vdash without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&vdash"
+                ]
+            ]
+        }, 
+        {
+            "input": "&vdash;", 
+            "description": "Named entity: vdash; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u22a2"
+                ]
+            ]
+        }, 
+        {
+            "input": "&vee", 
+            "description": "Bad named entity: vee without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&vee"
+                ]
+            ]
+        }, 
+        {
+            "input": "&vee;", 
+            "description": "Named entity: vee; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2228"
+                ]
+            ]
+        }, 
+        {
+            "input": "&veebar", 
+            "description": "Bad named entity: veebar without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&veebar"
+                ]
+            ]
+        }, 
+        {
+            "input": "&veebar;", 
+            "description": "Named entity: veebar; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u22bb"
+                ]
+            ]
+        }, 
+        {
+            "input": "&veeeq", 
+            "description": "Bad named entity: veeeq without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&veeeq"
+                ]
+            ]
+        }, 
+        {
+            "input": "&veeeq;", 
+            "description": "Named entity: veeeq; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u225a"
+                ]
+            ]
+        }, 
+        {
+            "input": "&vellip", 
+            "description": "Bad named entity: vellip without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&vellip"
+                ]
+            ]
+        }, 
+        {
+            "input": "&vellip;", 
+            "description": "Named entity: vellip; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u22ee"
+                ]
+            ]
+        }, 
+        {
+            "input": "&verbar", 
+            "description": "Bad named entity: verbar without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&verbar"
+                ]
+            ]
+        }, 
+        {
+            "input": "&verbar;", 
+            "description": "Named entity: verbar; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "|"
+                ]
+            ]
+        }, 
+        {
+            "input": "&vert", 
+            "description": "Bad named entity: vert without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&vert"
+                ]
+            ]
+        }, 
+        {
+            "input": "&vert;", 
+            "description": "Named entity: vert; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "|"
+                ]
+            ]
+        }, 
+        {
+            "input": "&vfr", 
+            "description": "Bad named entity: vfr without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&vfr"
+                ]
+            ]
+        }, 
+        {
+            "input": "&vfr;", 
+            "description": "Named entity: vfr; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\ud835\udd33"
+                ]
+            ]
+        }, 
+        {
+            "input": "&vltri", 
+            "description": "Bad named entity: vltri without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&vltri"
+                ]
+            ]
+        }, 
+        {
+            "input": "&vltri;", 
+            "description": "Named entity: vltri; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u22b2"
+                ]
+            ]
+        }, 
+        {
+            "input": "&vnsub", 
+            "description": "Bad named entity: vnsub without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&vnsub"
+                ]
+            ]
+        }, 
+        {
+            "input": "&vnsub;", 
+            "description": "Named entity: vnsub; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2282\u20d2"
+                ]
+            ]
+        }, 
+        {
+            "input": "&vnsup", 
+            "description": "Bad named entity: vnsup without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&vnsup"
+                ]
+            ]
+        }, 
+        {
+            "input": "&vnsup;", 
+            "description": "Named entity: vnsup; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2283\u20d2"
+                ]
+            ]
+        }, 
+        {
+            "input": "&vopf", 
+            "description": "Bad named entity: vopf without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&vopf"
+                ]
+            ]
+        }, 
+        {
+            "input": "&vopf;", 
+            "description": "Named entity: vopf; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\ud835\udd67"
+                ]
+            ]
+        }, 
+        {
+            "input": "&vprop", 
+            "description": "Bad named entity: vprop without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&vprop"
+                ]
+            ]
+        }, 
+        {
+            "input": "&vprop;", 
+            "description": "Named entity: vprop; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u221d"
+                ]
+            ]
+        }, 
+        {
+            "input": "&vrtri", 
+            "description": "Bad named entity: vrtri without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&vrtri"
+                ]
+            ]
+        }, 
+        {
+            "input": "&vrtri;", 
+            "description": "Named entity: vrtri; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u22b3"
+                ]
+            ]
+        }, 
+        {
+            "input": "&vscr", 
+            "description": "Bad named entity: vscr without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&vscr"
+                ]
+            ]
+        }, 
+        {
+            "input": "&vscr;", 
+            "description": "Named entity: vscr; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\ud835\udccb"
+                ]
+            ]
+        }, 
+        {
+            "input": "&vsubnE", 
+            "description": "Bad named entity: vsubnE without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&vsubnE"
+                ]
+            ]
+        }, 
+        {
+            "input": "&vsubnE;", 
+            "description": "Named entity: vsubnE; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2acb\ufe00"
+                ]
+            ]
+        }, 
+        {
+            "input": "&vsubne", 
+            "description": "Bad named entity: vsubne without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&vsubne"
+                ]
+            ]
+        }, 
+        {
+            "input": "&vsubne;", 
+            "description": "Named entity: vsubne; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u228a\ufe00"
+                ]
+            ]
+        }, 
+        {
+            "input": "&vsupnE", 
+            "description": "Bad named entity: vsupnE without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&vsupnE"
+                ]
+            ]
+        }, 
+        {
+            "input": "&vsupnE;", 
+            "description": "Named entity: vsupnE; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2acc\ufe00"
+                ]
+            ]
+        }, 
+        {
+            "input": "&vsupne", 
+            "description": "Bad named entity: vsupne without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&vsupne"
+                ]
+            ]
+        }, 
+        {
+            "input": "&vsupne;", 
+            "description": "Named entity: vsupne; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u228b\ufe00"
+                ]
+            ]
+        }, 
+        {
+            "input": "&vzigzag", 
+            "description": "Bad named entity: vzigzag without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&vzigzag"
+                ]
+            ]
+        }, 
+        {
+            "input": "&vzigzag;", 
+            "description": "Named entity: vzigzag; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u299a"
+                ]
+            ]
+        }, 
+        {
+            "input": "&wcirc", 
+            "description": "Bad named entity: wcirc without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&wcirc"
+                ]
+            ]
+        }, 
+        {
+            "input": "&wcirc;", 
+            "description": "Named entity: wcirc; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u0175"
+                ]
+            ]
+        }, 
+        {
+            "input": "&wedbar", 
+            "description": "Bad named entity: wedbar without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&wedbar"
+                ]
+            ]
+        }, 
+        {
+            "input": "&wedbar;", 
+            "description": "Named entity: wedbar; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2a5f"
+                ]
+            ]
+        }, 
+        {
+            "input": "&wedge", 
+            "description": "Bad named entity: wedge without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&wedge"
+                ]
+            ]
+        }, 
+        {
+            "input": "&wedge;", 
+            "description": "Named entity: wedge; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2227"
+                ]
+            ]
+        }, 
+        {
+            "input": "&wedgeq", 
+            "description": "Bad named entity: wedgeq without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&wedgeq"
+                ]
+            ]
+        }, 
+        {
+            "input": "&wedgeq;", 
+            "description": "Named entity: wedgeq; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2259"
+                ]
+            ]
+        }, 
+        {
+            "input": "&weierp", 
+            "description": "Bad named entity: weierp without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&weierp"
+                ]
+            ]
+        }, 
+        {
+            "input": "&weierp;", 
+            "description": "Named entity: weierp; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2118"
+                ]
+            ]
+        }, 
+        {
+            "input": "&wfr", 
+            "description": "Bad named entity: wfr without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&wfr"
+                ]
+            ]
+        }, 
+        {
+            "input": "&wfr;", 
+            "description": "Named entity: wfr; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\ud835\udd34"
+                ]
+            ]
+        }, 
+        {
+            "input": "&wopf", 
+            "description": "Bad named entity: wopf without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&wopf"
+                ]
+            ]
+        }, 
+        {
+            "input": "&wopf;", 
+            "description": "Named entity: wopf; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\ud835\udd68"
+                ]
+            ]
+        }, 
+        {
+            "input": "&wp", 
+            "description": "Bad named entity: wp without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&wp"
+                ]
+            ]
+        }, 
+        {
+            "input": "&wp;", 
+            "description": "Named entity: wp; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2118"
+                ]
+            ]
+        }, 
+        {
+            "input": "&wr", 
+            "description": "Bad named entity: wr without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&wr"
+                ]
+            ]
+        }, 
+        {
+            "input": "&wr;", 
+            "description": "Named entity: wr; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2240"
+                ]
+            ]
+        }, 
+        {
+            "input": "&wreath", 
+            "description": "Bad named entity: wreath without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&wreath"
+                ]
+            ]
+        }, 
+        {
+            "input": "&wreath;", 
+            "description": "Named entity: wreath; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2240"
+                ]
+            ]
+        }, 
+        {
+            "input": "&wscr", 
+            "description": "Bad named entity: wscr without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&wscr"
+                ]
+            ]
+        }, 
+        {
+            "input": "&wscr;", 
+            "description": "Named entity: wscr; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\ud835\udccc"
+                ]
+            ]
+        }, 
+        {
+            "input": "&xcap", 
+            "description": "Bad named entity: xcap without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&xcap"
+                ]
+            ]
+        }, 
+        {
+            "input": "&xcap;", 
+            "description": "Named entity: xcap; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u22c2"
+                ]
+            ]
+        }, 
+        {
+            "input": "&xcirc", 
+            "description": "Bad named entity: xcirc without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&xcirc"
+                ]
+            ]
+        }, 
+        {
+            "input": "&xcirc;", 
+            "description": "Named entity: xcirc; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u25ef"
+                ]
+            ]
+        }, 
+        {
+            "input": "&xcup", 
+            "description": "Bad named entity: xcup without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&xcup"
+                ]
+            ]
+        }, 
+        {
+            "input": "&xcup;", 
+            "description": "Named entity: xcup; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u22c3"
+                ]
+            ]
+        }, 
+        {
+            "input": "&xdtri", 
+            "description": "Bad named entity: xdtri without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&xdtri"
+                ]
+            ]
+        }, 
+        {
+            "input": "&xdtri;", 
+            "description": "Named entity: xdtri; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u25bd"
+                ]
+            ]
+        }, 
+        {
+            "input": "&xfr", 
+            "description": "Bad named entity: xfr without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&xfr"
+                ]
+            ]
+        }, 
+        {
+            "input": "&xfr;", 
+            "description": "Named entity: xfr; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\ud835\udd35"
+                ]
+            ]
+        }, 
+        {
+            "input": "&xhArr", 
+            "description": "Bad named entity: xhArr without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&xhArr"
+                ]
+            ]
+        }, 
+        {
+            "input": "&xhArr;", 
+            "description": "Named entity: xhArr; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u27fa"
+                ]
+            ]
+        }, 
+        {
+            "input": "&xharr", 
+            "description": "Bad named entity: xharr without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&xharr"
+                ]
+            ]
+        }, 
+        {
+            "input": "&xharr;", 
+            "description": "Named entity: xharr; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u27f7"
+                ]
+            ]
+        }, 
+        {
+            "input": "&xi", 
+            "description": "Bad named entity: xi without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&xi"
+                ]
+            ]
+        }, 
+        {
+            "input": "&xi;", 
+            "description": "Named entity: xi; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u03be"
+                ]
+            ]
+        }, 
+        {
+            "input": "&xlArr", 
+            "description": "Bad named entity: xlArr without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&xlArr"
+                ]
+            ]
+        }, 
+        {
+            "input": "&xlArr;", 
+            "description": "Named entity: xlArr; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u27f8"
+                ]
+            ]
+        }, 
+        {
+            "input": "&xlarr", 
+            "description": "Bad named entity: xlarr without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&xlarr"
+                ]
+            ]
+        }, 
+        {
+            "input": "&xlarr;", 
+            "description": "Named entity: xlarr; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u27f5"
+                ]
+            ]
+        }, 
+        {
+            "input": "&xmap", 
+            "description": "Bad named entity: xmap without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&xmap"
+                ]
+            ]
+        }, 
+        {
+            "input": "&xmap;", 
+            "description": "Named entity: xmap; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u27fc"
+                ]
+            ]
+        }, 
+        {
+            "input": "&xnis", 
+            "description": "Bad named entity: xnis without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&xnis"
+                ]
+            ]
+        }, 
+        {
+            "input": "&xnis;", 
+            "description": "Named entity: xnis; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u22fb"
+                ]
+            ]
+        }, 
+        {
+            "input": "&xodot", 
+            "description": "Bad named entity: xodot without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&xodot"
+                ]
+            ]
+        }, 
+        {
+            "input": "&xodot;", 
+            "description": "Named entity: xodot; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2a00"
+                ]
+            ]
+        }, 
+        {
+            "input": "&xopf", 
+            "description": "Bad named entity: xopf without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&xopf"
+                ]
+            ]
+        }, 
+        {
+            "input": "&xopf;", 
+            "description": "Named entity: xopf; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\ud835\udd69"
+                ]
+            ]
+        }, 
+        {
+            "input": "&xoplus", 
+            "description": "Bad named entity: xoplus without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&xoplus"
+                ]
+            ]
+        }, 
+        {
+            "input": "&xoplus;", 
+            "description": "Named entity: xoplus; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2a01"
+                ]
+            ]
+        }, 
+        {
+            "input": "&xotime", 
+            "description": "Bad named entity: xotime without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&xotime"
+                ]
+            ]
+        }, 
+        {
+            "input": "&xotime;", 
+            "description": "Named entity: xotime; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2a02"
+                ]
+            ]
+        }, 
+        {
+            "input": "&xrArr", 
+            "description": "Bad named entity: xrArr without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&xrArr"
+                ]
+            ]
+        }, 
+        {
+            "input": "&xrArr;", 
+            "description": "Named entity: xrArr; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u27f9"
+                ]
+            ]
+        }, 
+        {
+            "input": "&xrarr", 
+            "description": "Bad named entity: xrarr without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&xrarr"
+                ]
+            ]
+        }, 
+        {
+            "input": "&xrarr;", 
+            "description": "Named entity: xrarr; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u27f6"
+                ]
+            ]
+        }, 
+        {
+            "input": "&xscr", 
+            "description": "Bad named entity: xscr without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&xscr"
+                ]
+            ]
+        }, 
+        {
+            "input": "&xscr;", 
+            "description": "Named entity: xscr; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\ud835\udccd"
+                ]
+            ]
+        }, 
+        {
+            "input": "&xsqcup", 
+            "description": "Bad named entity: xsqcup without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&xsqcup"
+                ]
+            ]
+        }, 
+        {
+            "input": "&xsqcup;", 
+            "description": "Named entity: xsqcup; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2a06"
+                ]
+            ]
+        }, 
+        {
+            "input": "&xuplus", 
+            "description": "Bad named entity: xuplus without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&xuplus"
+                ]
+            ]
+        }, 
+        {
+            "input": "&xuplus;", 
+            "description": "Named entity: xuplus; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2a04"
+                ]
+            ]
+        }, 
+        {
+            "input": "&xutri", 
+            "description": "Bad named entity: xutri without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&xutri"
+                ]
+            ]
+        }, 
+        {
+            "input": "&xutri;", 
+            "description": "Named entity: xutri; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u25b3"
+                ]
+            ]
+        }, 
+        {
+            "input": "&xvee", 
+            "description": "Bad named entity: xvee without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&xvee"
+                ]
+            ]
+        }, 
+        {
+            "input": "&xvee;", 
+            "description": "Named entity: xvee; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u22c1"
+                ]
+            ]
+        }, 
+        {
+            "input": "&xwedge", 
+            "description": "Bad named entity: xwedge without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&xwedge"
+                ]
+            ]
+        }, 
+        {
+            "input": "&xwedge;", 
+            "description": "Named entity: xwedge; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u22c0"
+                ]
+            ]
+        }, 
+        {
+            "input": "&yacute", 
+            "description": "Named entity: yacute without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "\u00fd"
+                ]
+            ]
+        }, 
+        {
+            "input": "&yacute;", 
+            "description": "Named entity: yacute; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u00fd"
+                ]
+            ]
+        }, 
+        {
+            "input": "&yacy", 
+            "description": "Bad named entity: yacy without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&yacy"
+                ]
+            ]
+        }, 
+        {
+            "input": "&yacy;", 
+            "description": "Named entity: yacy; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u044f"
+                ]
+            ]
+        }, 
+        {
+            "input": "&ycirc", 
+            "description": "Bad named entity: ycirc without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&ycirc"
+                ]
+            ]
+        }, 
+        {
+            "input": "&ycirc;", 
+            "description": "Named entity: ycirc; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u0177"
+                ]
+            ]
+        }, 
+        {
+            "input": "&ycy", 
+            "description": "Bad named entity: ycy without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&ycy"
+                ]
+            ]
+        }, 
+        {
+            "input": "&ycy;", 
+            "description": "Named entity: ycy; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u044b"
+                ]
+            ]
+        }, 
+        {
+            "input": "&yen", 
+            "description": "Named entity: yen without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "\u00a5"
+                ]
+            ]
+        }, 
+        {
+            "input": "&yen;", 
+            "description": "Named entity: yen; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u00a5"
+                ]
+            ]
+        }, 
+        {
+            "input": "&yfr", 
+            "description": "Bad named entity: yfr without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&yfr"
+                ]
+            ]
+        }, 
+        {
+            "input": "&yfr;", 
+            "description": "Named entity: yfr; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\ud835\udd36"
+                ]
+            ]
+        }, 
+        {
+            "input": "&yicy", 
+            "description": "Bad named entity: yicy without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&yicy"
+                ]
+            ]
+        }, 
+        {
+            "input": "&yicy;", 
+            "description": "Named entity: yicy; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u0457"
+                ]
+            ]
+        }, 
+        {
+            "input": "&yopf", 
+            "description": "Bad named entity: yopf without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&yopf"
+                ]
+            ]
+        }, 
+        {
+            "input": "&yopf;", 
+            "description": "Named entity: yopf; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\ud835\udd6a"
+                ]
+            ]
+        }, 
+        {
+            "input": "&yscr", 
+            "description": "Bad named entity: yscr without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&yscr"
+                ]
+            ]
+        }, 
+        {
+            "input": "&yscr;", 
+            "description": "Named entity: yscr; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\ud835\udcce"
+                ]
+            ]
+        }, 
+        {
+            "input": "&yucy", 
+            "description": "Bad named entity: yucy without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&yucy"
+                ]
+            ]
+        }, 
+        {
+            "input": "&yucy;", 
+            "description": "Named entity: yucy; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u044e"
+                ]
+            ]
+        }, 
+        {
+            "input": "&yuml", 
+            "description": "Named entity: yuml without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "\u00ff"
+                ]
+            ]
+        }, 
+        {
+            "input": "&yuml;", 
+            "description": "Named entity: yuml; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u00ff"
+                ]
+            ]
+        }, 
+        {
+            "input": "&zacute", 
+            "description": "Bad named entity: zacute without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&zacute"
+                ]
+            ]
+        }, 
+        {
+            "input": "&zacute;", 
+            "description": "Named entity: zacute; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u017a"
+                ]
+            ]
+        }, 
+        {
+            "input": "&zcaron", 
+            "description": "Bad named entity: zcaron without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&zcaron"
+                ]
+            ]
+        }, 
+        {
+            "input": "&zcaron;", 
+            "description": "Named entity: zcaron; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u017e"
+                ]
+            ]
+        }, 
+        {
+            "input": "&zcy", 
+            "description": "Bad named entity: zcy without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&zcy"
+                ]
+            ]
+        }, 
+        {
+            "input": "&zcy;", 
+            "description": "Named entity: zcy; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u0437"
+                ]
+            ]
+        }, 
+        {
+            "input": "&zdot", 
+            "description": "Bad named entity: zdot without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&zdot"
+                ]
+            ]
+        }, 
+        {
+            "input": "&zdot;", 
+            "description": "Named entity: zdot; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u017c"
+                ]
+            ]
+        }, 
+        {
+            "input": "&zeetrf", 
+            "description": "Bad named entity: zeetrf without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&zeetrf"
+                ]
+            ]
+        }, 
+        {
+            "input": "&zeetrf;", 
+            "description": "Named entity: zeetrf; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u2128"
+                ]
+            ]
+        }, 
+        {
+            "input": "&zeta", 
+            "description": "Bad named entity: zeta without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&zeta"
+                ]
+            ]
+        }, 
+        {
+            "input": "&zeta;", 
+            "description": "Named entity: zeta; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u03b6"
+                ]
+            ]
+        }, 
+        {
+            "input": "&zfr", 
+            "description": "Bad named entity: zfr without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&zfr"
+                ]
+            ]
+        }, 
+        {
+            "input": "&zfr;", 
+            "description": "Named entity: zfr; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\ud835\udd37"
+                ]
+            ]
+        }, 
+        {
+            "input": "&zhcy", 
+            "description": "Bad named entity: zhcy without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&zhcy"
+                ]
+            ]
+        }, 
+        {
+            "input": "&zhcy;", 
+            "description": "Named entity: zhcy; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u0436"
+                ]
+            ]
+        }, 
+        {
+            "input": "&zigrarr", 
+            "description": "Bad named entity: zigrarr without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&zigrarr"
+                ]
+            ]
+        }, 
+        {
+            "input": "&zigrarr;", 
+            "description": "Named entity: zigrarr; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u21dd"
+                ]
+            ]
+        }, 
+        {
+            "input": "&zopf", 
+            "description": "Bad named entity: zopf without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&zopf"
+                ]
+            ]
+        }, 
+        {
+            "input": "&zopf;", 
+            "description": "Named entity: zopf; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\ud835\udd6b"
+                ]
+            ]
+        }, 
+        {
+            "input": "&zscr", 
+            "description": "Bad named entity: zscr without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&zscr"
+                ]
+            ]
+        }, 
+        {
+            "input": "&zscr;", 
+            "description": "Named entity: zscr; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\ud835\udccf"
+                ]
+            ]
+        }, 
+        {
+            "input": "&zwj", 
+            "description": "Bad named entity: zwj without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&zwj"
+                ]
+            ]
+        }, 
+        {
+            "input": "&zwj;", 
+            "description": "Named entity: zwj; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u200d"
+                ]
+            ]
+        }, 
+        {
+            "input": "&zwnj", 
+            "description": "Bad named entity: zwnj without a semi-colon", 
+            "output": [
+                "ParseError", 
+                [
+                    "Character", 
+                    "&zwnj"
+                ]
+            ]
+        }, 
+        {
+            "input": "&zwnj;", 
+            "description": "Named entity: zwnj; with a semi-colon", 
+            "output": [
+                [
+                    "Character", 
+                    "\u200c"
+                ]
+            ]
+        }
+    ]
+}
\ No newline at end of file
diff --git a/html/test/data/tokenizer/numericEntities.test b/html/test/data/tokenizer/numericEntities.test
new file mode 100644
index 0000000..36c8228
--- /dev/null
+++ b/html/test/data/tokenizer/numericEntities.test
@@ -0,0 +1,1313 @@
+{"tests": [
+
+{"description": "Invalid numeric entity character U+0000",
+"input": "&#x0000;",
+"output": ["ParseError", ["Character", "\uFFFD"]]},
+
+{"description": "Invalid numeric entity character U+0001",
+"input": "&#x0001;",
+"output": ["ParseError", ["Character", "\u0001"]]},
+
+{"description": "Invalid numeric entity character U+0002",
+"input": "&#x0002;",
+"output": ["ParseError", ["Character", "\u0002"]]},
+
+{"description": "Invalid numeric entity character U+0003",
+"input": "&#x0003;",
+"output": ["ParseError", ["Character", "\u0003"]]},
+
+{"description": "Invalid numeric entity character U+0004",
+"input": "&#x0004;",
+"output": ["ParseError", ["Character", "\u0004"]]},
+
+{"description": "Invalid numeric entity character U+0005",
+"input": "&#x0005;",
+"output": ["ParseError", ["Character", "\u0005"]]},
+
+{"description": "Invalid numeric entity character U+0006",
+"input": "&#x0006;",
+"output": ["ParseError", ["Character", "\u0006"]]},
+
+{"description": "Invalid numeric entity character U+0007",
+"input": "&#x0007;",
+"output": ["ParseError", ["Character", "\u0007"]]},
+
+{"description": "Invalid numeric entity character U+0008",
+"input": "&#x0008;",
+"output": ["ParseError", ["Character", "\u0008"]]},
+
+{"description": "Invalid numeric entity character U+000B",
+"input": "&#x000b;",
+"output": ["ParseError", ["Character", "\u000b"]]},
+
+{"description": "Invalid numeric entity character U+000E",
+"input": "&#x000e;",
+"output": ["ParseError", ["Character", "\u000e"]]},
+
+{"description": "Invalid numeric entity character U+000F",
+"input": "&#x000f;",
+"output": ["ParseError", ["Character", "\u000f"]]},
+
+{"description": "Invalid numeric entity character U+0010",
+"input": "&#x0010;",
+"output": ["ParseError", ["Character", "\u0010"]]},
+
+{"description": "Invalid numeric entity character U+0011",
+"input": "&#x0011;",
+"output": ["ParseError", ["Character", "\u0011"]]},
+
+{"description": "Invalid numeric entity character U+0012",
+"input": "&#x0012;",
+"output": ["ParseError", ["Character", "\u0012"]]},
+
+{"description": "Invalid numeric entity character U+0013",
+"input": "&#x0013;",
+"output": ["ParseError", ["Character", "\u0013"]]},
+
+{"description": "Invalid numeric entity character U+0014",
+"input": "&#x0014;",
+"output": ["ParseError", ["Character", "\u0014"]]},
+
+{"description": "Invalid numeric entity character U+0015",
+"input": "&#x0015;",
+"output": ["ParseError", ["Character", "\u0015"]]},
+
+{"description": "Invalid numeric entity character U+0016",
+"input": "&#x0016;",
+"output": ["ParseError", ["Character", "\u0016"]]},
+
+{"description": "Invalid numeric entity character U+0017",
+"input": "&#x0017;",
+"output": ["ParseError", ["Character", "\u0017"]]},
+
+{"description": "Invalid numeric entity character U+0018",
+"input": "&#x0018;",
+"output": ["ParseError", ["Character", "\u0018"]]},
+
+{"description": "Invalid numeric entity character U+0019",
+"input": "&#x0019;",
+"output": ["ParseError", ["Character", "\u0019"]]},
+
+{"description": "Invalid numeric entity character U+001A",
+"input": "&#x001a;",
+"output": ["ParseError", ["Character", "\u001a"]]},
+
+{"description": "Invalid numeric entity character U+001B",
+"input": "&#x001b;",
+"output": ["ParseError", ["Character", "\u001b"]]},
+
+{"description": "Invalid numeric entity character U+001C",
+"input": "&#x001c;",
+"output": ["ParseError", ["Character", "\u001c"]]},
+
+{"description": "Invalid numeric entity character U+001D",
+"input": "&#x001d;",
+"output": ["ParseError", ["Character", "\u001d"]]},
+
+{"description": "Invalid numeric entity character U+001E",
+"input": "&#x001e;",
+"output": ["ParseError", ["Character", "\u001e"]]},
+
+{"description": "Invalid numeric entity character U+001F",
+"input": "&#x001f;",
+"output": ["ParseError", ["Character", "\u001f"]]},
+
+{"description": "Invalid numeric entity character U+007F",
+"input": "&#x007f;",
+"output": ["ParseError", ["Character", "\u007f"]]},
+
+{"description": "Invalid numeric entity character U+D800",
+"input": "&#xd800;",
+"output": ["ParseError", ["Character", "\uFFFD"]]},
+
+{"description": "Invalid numeric entity character U+DFFF",
+"input": "&#xdfff;",
+"output": ["ParseError", ["Character", "\uFFFD"]]},
+
+{"description": "Invalid numeric entity character U+FDD0",
+"input": "&#xfdd0;",
+"output": ["ParseError", ["Character", "\ufdd0"]]},
+
+{"description": "Invalid numeric entity character U+FDD1",
+"input": "&#xfdd1;",
+"output": ["ParseError", ["Character", "\ufdd1"]]},
+
+{"description": "Invalid numeric entity character U+FDD2",
+"input": "&#xfdd2;",
+"output": ["ParseError", ["Character", "\ufdd2"]]},
+
+{"description": "Invalid numeric entity character U+FDD3",
+"input": "&#xfdd3;",
+"output": ["ParseError", ["Character", "\ufdd3"]]},
+
+{"description": "Invalid numeric entity character U+FDD4",
+"input": "&#xfdd4;",
+"output": ["ParseError", ["Character", "\ufdd4"]]},
+
+{"description": "Invalid numeric entity character U+FDD5",
+"input": "&#xfdd5;",
+"output": ["ParseError", ["Character", "\ufdd5"]]},
+
+{"description": "Invalid numeric entity character U+FDD6",
+"input": "&#xfdd6;",
+"output": ["ParseError", ["Character", "\ufdd6"]]},
+
+{"description": "Invalid numeric entity character U+FDD7",
+"input": "&#xfdd7;",
+"output": ["ParseError", ["Character", "\ufdd7"]]},
+
+{"description": "Invalid numeric entity character U+FDD8",
+"input": "&#xfdd8;",
+"output": ["ParseError", ["Character", "\ufdd8"]]},
+
+{"description": "Invalid numeric entity character U+FDD9",
+"input": "&#xfdd9;",
+"output": ["ParseError", ["Character", "\ufdd9"]]},
+
+{"description": "Invalid numeric entity character U+FDDA",
+"input": "&#xfdda;",
+"output": ["ParseError", ["Character", "\ufdda"]]},
+
+{"description": "Invalid numeric entity character U+FDDB",
+"input": "&#xfddb;",
+"output": ["ParseError", ["Character", "\ufddb"]]},
+
+{"description": "Invalid numeric entity character U+FDDC",
+"input": "&#xfddc;",
+"output": ["ParseError", ["Character", "\ufddc"]]},
+
+{"description": "Invalid numeric entity character U+FDDD",
+"input": "&#xfddd;",
+"output": ["ParseError", ["Character", "\ufddd"]]},
+
+{"description": "Invalid numeric entity character U+FDDE",
+"input": "&#xfdde;",
+"output": ["ParseError", ["Character", "\ufdde"]]},
+
+{"description": "Invalid numeric entity character U+FDDF",
+"input": "&#xfddf;",
+"output": ["ParseError", ["Character", "\ufddf"]]},
+
+{"description": "Invalid numeric entity character U+FDE0",
+"input": "&#xfde0;",
+"output": ["ParseError", ["Character", "\ufde0"]]},
+
+{"description": "Invalid numeric entity character U+FDE1",
+"input": "&#xfde1;",
+"output": ["ParseError", ["Character", "\ufde1"]]},
+
+{"description": "Invalid numeric entity character U+FDE2",
+"input": "&#xfde2;",
+"output": ["ParseError", ["Character", "\ufde2"]]},
+
+{"description": "Invalid numeric entity character U+FDE3",
+"input": "&#xfde3;",
+"output": ["ParseError", ["Character", "\ufde3"]]},
+
+{"description": "Invalid numeric entity character U+FDE4",
+"input": "&#xfde4;",
+"output": ["ParseError", ["Character", "\ufde4"]]},
+
+{"description": "Invalid numeric entity character U+FDE5",
+"input": "&#xfde5;",
+"output": ["ParseError", ["Character", "\ufde5"]]},
+
+{"description": "Invalid numeric entity character U+FDE6",
+"input": "&#xfde6;",
+"output": ["ParseError", ["Character", "\ufde6"]]},
+
+{"description": "Invalid numeric entity character U+FDE7",
+"input": "&#xfde7;",
+"output": ["ParseError", ["Character", "\ufde7"]]},
+
+{"description": "Invalid numeric entity character U+FDE8",
+"input": "&#xfde8;",
+"output": ["ParseError", ["Character", "\ufde8"]]},
+
+{"description": "Invalid numeric entity character U+FDE9",
+"input": "&#xfde9;",
+"output": ["ParseError", ["Character", "\ufde9"]]},
+
+{"description": "Invalid numeric entity character U+FDEA",
+"input": "&#xfdea;",
+"output": ["ParseError", ["Character", "\ufdea"]]},
+
+{"description": "Invalid numeric entity character U+FDEB",
+"input": "&#xfdeb;",
+"output": ["ParseError", ["Character", "\ufdeb"]]},
+
+{"description": "Invalid numeric entity character U+FDEC",
+"input": "&#xfdec;",
+"output": ["ParseError", ["Character", "\ufdec"]]},
+
+{"description": "Invalid numeric entity character U+FDED",
+"input": "&#xfded;",
+"output": ["ParseError", ["Character", "\ufded"]]},
+
+{"description": "Invalid numeric entity character U+FDEE",
+"input": "&#xfdee;",
+"output": ["ParseError", ["Character", "\ufdee"]]},
+
+{"description": "Invalid numeric entity character U+FDEF",
+"input": "&#xfdef;",
+"output": ["ParseError", ["Character", "\ufdef"]]},
+
+{"description": "Invalid numeric entity character U+FFFE",
+"input": "&#xfffe;",
+"output": ["ParseError", ["Character", "\ufffe"]]},
+
+{"description": "Invalid numeric entity character U+FFFF",
+"input": "&#xffff;",
+"output": ["ParseError", ["Character", "\uffff"]]},
+
+{"description": "Invalid numeric entity character U+1FFFE",
+"input": "&#x1fffe;",
+"output": ["ParseError", ["Character", "\uD83F\uDFFE"]]},
+
+{"description": "Invalid numeric entity character U+1FFFF",
+"input": "&#x1ffff;",
+"output": ["ParseError", ["Character", "\uD83F\uDFFF"]]},
+
+{"description": "Invalid numeric entity character U+2FFFE",
+"input": "&#x2fffe;",
+"output": ["ParseError", ["Character", "\uD87F\uDFFE"]]},
+
+{"description": "Invalid numeric entity character U+2FFFF",
+"input": "&#x2ffff;",
+"output": ["ParseError", ["Character", "\uD87F\uDFFF"]]},
+
+{"description": "Invalid numeric entity character U+3FFFE",
+"input": "&#x3fffe;",
+"output": ["ParseError", ["Character", "\uD8BF\uDFFE"]]},
+
+{"description": "Invalid numeric entity character U+3FFFF",
+"input": "&#x3ffff;",
+"output": ["ParseError", ["Character", "\uD8BF\uDFFF"]]},
+
+{"description": "Invalid numeric entity character U+4FFFE",
+"input": "&#x4fffe;",
+"output": ["ParseError", ["Character", "\uD8FF\uDFFE"]]},
+
+{"description": "Invalid numeric entity character U+4FFFF",
+"input": "&#x4ffff;",
+"output": ["ParseError", ["Character", "\uD8FF\uDFFF"]]},
+
+{"description": "Invalid numeric entity character U+5FFFE",
+"input": "&#x5fffe;",
+"output": ["ParseError", ["Character", "\uD93F\uDFFE"]]},
+
+{"description": "Invalid numeric entity character U+5FFFF",
+"input": "&#x5ffff;",
+"output": ["ParseError", ["Character", "\uD93F\uDFFF"]]},
+
+{"description": "Invalid numeric entity character U+6FFFE",
+"input": "&#x6fffe;",
+"output": ["ParseError", ["Character", "\uD97F\uDFFE"]]},
+
+{"description": "Invalid numeric entity character U+6FFFF",
+"input": "&#x6ffff;",
+"output": ["ParseError", ["Character", "\uD97F\uDFFF"]]},
+
+{"description": "Invalid numeric entity character U+7FFFE",
+"input": "&#x7fffe;",
+"output": ["ParseError", ["Character", "\uD9BF\uDFFE"]]},
+
+{"description": "Invalid numeric entity character U+7FFFF",
+"input": "&#x7ffff;",
+"output": ["ParseError", ["Character", "\uD9BF\uDFFF"]]},
+
+{"description": "Invalid numeric entity character U+8FFFE",
+"input": "&#x8fffe;",
+"output": ["ParseError", ["Character", "\uD9FF\uDFFE"]]},
+
+{"description": "Invalid numeric entity character U+8FFFF",
+"input": "&#x8ffff;",
+"output": ["ParseError", ["Character", "\uD9FF\uDFFF"]]},
+
+{"description": "Invalid numeric entity character U+9FFFE",
+"input": "&#x9fffe;",
+"output": ["ParseError", ["Character", "\uDA3F\uDFFE"]]},
+
+{"description": "Invalid numeric entity character U+9FFFF",
+"input": "&#x9ffff;",
+"output": ["ParseError", ["Character", "\uDA3F\uDFFF"]]},
+
+{"description": "Invalid numeric entity character U+AFFFE",
+"input": "&#xafffe;",
+"output": ["ParseError", ["Character", "\uDA7F\uDFFE"]]},
+
+{"description": "Invalid numeric entity character U+AFFFF",
+"input": "&#xaffff;",
+"output": ["ParseError", ["Character", "\uDA7F\uDFFF"]]},
+
+{"description": "Invalid numeric entity character U+BFFFE",
+"input": "&#xbfffe;",
+"output": ["ParseError", ["Character", "\uDABF\uDFFE"]]},
+
+{"description": "Invalid numeric entity character U+BFFFF",
+"input": "&#xbffff;",
+"output": ["ParseError", ["Character", "\uDABF\uDFFF"]]},
+
+{"description": "Invalid numeric entity character U+CFFFE",
+"input": "&#xcfffe;",
+"output": ["ParseError", ["Character", "\uDAFF\uDFFE"]]},
+
+{"description": "Invalid numeric entity character U+CFFFF",
+"input": "&#xcffff;",
+"output": ["ParseError", ["Character", "\uDAFF\uDFFF"]]},
+
+{"description": "Invalid numeric entity character U+DFFFE",
+"input": "&#xdfffe;",
+"output": ["ParseError", ["Character", "\uDB3F\uDFFE"]]},
+
+{"description": "Invalid numeric entity character U+DFFFF",
+"input": "&#xdffff;",
+"output": ["ParseError", ["Character", "\uDB3F\uDFFF"]]},
+
+{"description": "Invalid numeric entity character U+EFFFE",
+"input": "&#xefffe;",
+"output": ["ParseError", ["Character", "\uDB7F\uDFFE"]]},
+
+{"description": "Invalid numeric entity character U+EFFFF",
+"input": "&#xeffff;",
+"output": ["ParseError", ["Character", "\uDB7F\uDFFF"]]},
+
+{"description": "Invalid numeric entity character U+FFFFE",
+"input": "&#xffffe;",
+"output": ["ParseError", ["Character", "\uDBBF\uDFFE"]]},
+
+{"description": "Invalid numeric entity character U+FFFFF",
+"input": "&#xfffff;",
+"output": ["ParseError", ["Character", "\uDBBF\uDFFF"]]},
+
+{"description": "Invalid numeric entity character U+10FFFE",
+"input": "&#x10fffe;",
+"output": ["ParseError", ["Character", "\uDBFF\uDFFE"]]},
+
+{"description": "Invalid numeric entity character U+10FFFF",
+"input": "&#x10ffff;",
+"output": ["ParseError", ["Character", "\uDBFF\uDFFF"]]},
+
+{"description": "Valid numeric entity character U+0009",
+"input": "&#x0009;",
+"output": [["Character", "\u0009"]]},
+
+{"description": "Valid numeric entity character U+000A",
+"input": "&#x000a;",
+"output": [["Character", "\u000A"]]},
+
+{"description": "Valid numeric entity character U+0020",
+"input": "&#x0020;",
+"output": [["Character", "\u0020"]]},
+
+{"description": "Valid numeric entity character U+0021",
+"input": "&#x0021;",
+"output": [["Character", "\u0021"]]},
+
+{"description": "Valid numeric entity character U+0022",
+"input": "&#x0022;",
+"output": [["Character", "\u0022"]]},
+
+{"description": "Valid numeric entity character U+0023",
+"input": "&#x0023;",
+"output": [["Character", "\u0023"]]},
+
+{"description": "Valid numeric entity character U+0024",
+"input": "&#x0024;",
+"output": [["Character", "\u0024"]]},
+
+{"description": "Valid numeric entity character U+0025",
+"input": "&#x0025;",
+"output": [["Character", "\u0025"]]},
+
+{"description": "Valid numeric entity character U+0026",
+"input": "&#x0026;",
+"output": [["Character", "\u0026"]]},
+
+{"description": "Valid numeric entity character U+0027",
+"input": "&#x0027;",
+"output": [["Character", "\u0027"]]},
+
+{"description": "Valid numeric entity character U+0028",
+"input": "&#x0028;",
+"output": [["Character", "\u0028"]]},
+
+{"description": "Valid numeric entity character U+0029",
+"input": "&#x0029;",
+"output": [["Character", "\u0029"]]},
+
+{"description": "Valid numeric entity character U+002A",
+"input": "&#x002a;",
+"output": [["Character", "\u002A"]]},
+
+{"description": "Valid numeric entity character U+002B",
+"input": "&#x002b;",
+"output": [["Character", "\u002B"]]},
+
+{"description": "Valid numeric entity character U+002C",
+"input": "&#x002c;",
+"output": [["Character", "\u002C"]]},
+
+{"description": "Valid numeric entity character U+002D",
+"input": "&#x002d;",
+"output": [["Character", "\u002D"]]},
+
+{"description": "Valid numeric entity character U+002E",
+"input": "&#x002e;",
+"output": [["Character", "\u002E"]]},
+
+{"description": "Valid numeric entity character U+002F",
+"input": "&#x002f;",
+"output": [["Character", "\u002F"]]},
+
+{"description": "Valid numeric entity character U+0030",
+"input": "&#x0030;",
+"output": [["Character", "\u0030"]]},
+
+{"description": "Valid numeric entity character U+0031",
+"input": "&#x0031;",
+"output": [["Character", "\u0031"]]},
+
+{"description": "Valid numeric entity character U+0032",
+"input": "&#x0032;",
+"output": [["Character", "\u0032"]]},
+
+{"description": "Valid numeric entity character U+0033",
+"input": "&#x0033;",
+"output": [["Character", "\u0033"]]},
+
+{"description": "Valid numeric entity character U+0034",
+"input": "&#x0034;",
+"output": [["Character", "\u0034"]]},
+
+{"description": "Valid numeric entity character U+0035",
+"input": "&#x0035;",
+"output": [["Character", "\u0035"]]},
+
+{"description": "Valid numeric entity character U+0036",
+"input": "&#x0036;",
+"output": [["Character", "\u0036"]]},
+
+{"description": "Valid numeric entity character U+0037",
+"input": "&#x0037;",
+"output": [["Character", "\u0037"]]},
+
+{"description": "Valid numeric entity character U+0038",
+"input": "&#x0038;",
+"output": [["Character", "\u0038"]]},
+
+{"description": "Valid numeric entity character U+0039",
+"input": "&#x0039;",
+"output": [["Character", "\u0039"]]},
+
+{"description": "Valid numeric entity character U+003A",
+"input": "&#x003a;",
+"output": [["Character", "\u003A"]]},
+
+{"description": "Valid numeric entity character U+003B",
+"input": "&#x003b;",
+"output": [["Character", "\u003B"]]},
+
+{"description": "Valid numeric entity character U+003C",
+"input": "&#x003c;",
+"output": [["Character", "\u003C"]]},
+
+{"description": "Valid numeric entity character U+003D",
+"input": "&#x003d;",
+"output": [["Character", "\u003D"]]},
+
+{"description": "Valid numeric entity character U+003E",
+"input": "&#x003e;",
+"output": [["Character", "\u003E"]]},
+
+{"description": "Valid numeric entity character U+003F",
+"input": "&#x003f;",
+"output": [["Character", "\u003F"]]},
+
+{"description": "Valid numeric entity character U+0040",
+"input": "&#x0040;",
+"output": [["Character", "\u0040"]]},
+
+{"description": "Valid numeric entity character U+0041",
+"input": "&#x0041;",
+"output": [["Character", "\u0041"]]},
+
+{"description": "Valid numeric entity character U+0042",
+"input": "&#x0042;",
+"output": [["Character", "\u0042"]]},
+
+{"description": "Valid numeric entity character U+0043",
+"input": "&#x0043;",
+"output": [["Character", "\u0043"]]},
+
+{"description": "Valid numeric entity character U+0044",
+"input": "&#x0044;",
+"output": [["Character", "\u0044"]]},
+
+{"description": "Valid numeric entity character U+0045",
+"input": "&#x0045;",
+"output": [["Character", "\u0045"]]},
+
+{"description": "Valid numeric entity character U+0046",
+"input": "&#x0046;",
+"output": [["Character", "\u0046"]]},
+
+{"description": "Valid numeric entity character U+0047",
+"input": "&#x0047;",
+"output": [["Character", "\u0047"]]},
+
+{"description": "Valid numeric entity character U+0048",
+"input": "&#x0048;",
+"output": [["Character", "\u0048"]]},
+
+{"description": "Valid numeric entity character U+0049",
+"input": "&#x0049;",
+"output": [["Character", "\u0049"]]},
+
+{"description": "Valid numeric entity character U+004A",
+"input": "&#x004a;",
+"output": [["Character", "\u004A"]]},
+
+{"description": "Valid numeric entity character U+004B",
+"input": "&#x004b;",
+"output": [["Character", "\u004B"]]},
+
+{"description": "Valid numeric entity character U+004C",
+"input": "&#x004c;",
+"output": [["Character", "\u004C"]]},
+
+{"description": "Valid numeric entity character U+004D",
+"input": "&#x004d;",
+"output": [["Character", "\u004D"]]},
+
+{"description": "Valid numeric entity character U+004E",
+"input": "&#x004e;",
+"output": [["Character", "\u004E"]]},
+
+{"description": "Valid numeric entity character U+004F",
+"input": "&#x004f;",
+"output": [["Character", "\u004F"]]},
+
+{"description": "Valid numeric entity character U+0050",
+"input": "&#x0050;",
+"output": [["Character", "\u0050"]]},
+
+{"description": "Valid numeric entity character U+0051",
+"input": "&#x0051;",
+"output": [["Character", "\u0051"]]},
+
+{"description": "Valid numeric entity character U+0052",
+"input": "&#x0052;",
+"output": [["Character", "\u0052"]]},
+
+{"description": "Valid numeric entity character U+0053",
+"input": "&#x0053;",
+"output": [["Character", "\u0053"]]},
+
+{"description": "Valid numeric entity character U+0054",
+"input": "&#x0054;",
+"output": [["Character", "\u0054"]]},
+
+{"description": "Valid numeric entity character U+0055",
+"input": "&#x0055;",
+"output": [["Character", "\u0055"]]},
+
+{"description": "Valid numeric entity character U+0056",
+"input": "&#x0056;",
+"output": [["Character", "\u0056"]]},
+
+{"description": "Valid numeric entity character U+0057",
+"input": "&#x0057;",
+"output": [["Character", "\u0057"]]},
+
+{"description": "Valid numeric entity character U+0058",
+"input": "&#x0058;",
+"output": [["Character", "\u0058"]]},
+
+{"description": "Valid numeric entity character U+0059",
+"input": "&#x0059;",
+"output": [["Character", "\u0059"]]},
+
+{"description": "Valid numeric entity character U+005A",
+"input": "&#x005a;",
+"output": [["Character", "\u005A"]]},
+
+{"description": "Valid numeric entity character U+005B",
+"input": "&#x005b;",
+"output": [["Character", "\u005B"]]},
+
+{"description": "Valid numeric entity character U+005C",
+"input": "&#x005c;",
+"output": [["Character", "\u005C"]]},
+
+{"description": "Valid numeric entity character U+005D",
+"input": "&#x005d;",
+"output": [["Character", "\u005D"]]},
+
+{"description": "Valid numeric entity character U+005E",
+"input": "&#x005e;",
+"output": [["Character", "\u005E"]]},
+
+{"description": "Valid numeric entity character U+005F",
+"input": "&#x005f;",
+"output": [["Character", "\u005F"]]},
+
+{"description": "Valid numeric entity character U+0060",
+"input": "&#x0060;",
+"output": [["Character", "\u0060"]]},
+
+{"description": "Valid numeric entity character U+0061",
+"input": "&#x0061;",
+"output": [["Character", "\u0061"]]},
+
+{"description": "Valid numeric entity character U+0062",
+"input": "&#x0062;",
+"output": [["Character", "\u0062"]]},
+
+{"description": "Valid numeric entity character U+0063",
+"input": "&#x0063;",
+"output": [["Character", "\u0063"]]},
+
+{"description": "Valid numeric entity character U+0064",
+"input": "&#x0064;",
+"output": [["Character", "\u0064"]]},
+
+{"description": "Valid numeric entity character U+0065",
+"input": "&#x0065;",
+"output": [["Character", "\u0065"]]},
+
+{"description": "Valid numeric entity character U+0066",
+"input": "&#x0066;",
+"output": [["Character", "\u0066"]]},
+
+{"description": "Valid numeric entity character U+0067",
+"input": "&#x0067;",
+"output": [["Character", "\u0067"]]},
+
+{"description": "Valid numeric entity character U+0068",
+"input": "&#x0068;",
+"output": [["Character", "\u0068"]]},
+
+{"description": "Valid numeric entity character U+0069",
+"input": "&#x0069;",
+"output": [["Character", "\u0069"]]},
+
+{"description": "Valid numeric entity character U+006A",
+"input": "&#x006a;",
+"output": [["Character", "\u006A"]]},
+
+{"description": "Valid numeric entity character U+006B",
+"input": "&#x006b;",
+"output": [["Character", "\u006B"]]},
+
+{"description": "Valid numeric entity character U+006C",
+"input": "&#x006c;",
+"output": [["Character", "\u006C"]]},
+
+{"description": "Valid numeric entity character U+006D",
+"input": "&#x006d;",
+"output": [["Character", "\u006D"]]},
+
+{"description": "Valid numeric entity character U+006E",
+"input": "&#x006e;",
+"output": [["Character", "\u006E"]]},
+
+{"description": "Valid numeric entity character U+006F",
+"input": "&#x006f;",
+"output": [["Character", "\u006F"]]},
+
+{"description": "Valid numeric entity character U+0070",
+"input": "&#x0070;",
+"output": [["Character", "\u0070"]]},
+
+{"description": "Valid numeric entity character U+0071",
+"input": "&#x0071;",
+"output": [["Character", "\u0071"]]},
+
+{"description": "Valid numeric entity character U+0072",
+"input": "&#x0072;",
+"output": [["Character", "\u0072"]]},
+
+{"description": "Valid numeric entity character U+0073",
+"input": "&#x0073;",
+"output": [["Character", "\u0073"]]},
+
+{"description": "Valid numeric entity character U+0074",
+"input": "&#x0074;",
+"output": [["Character", "\u0074"]]},
+
+{"description": "Valid numeric entity character U+0075",
+"input": "&#x0075;",
+"output": [["Character", "\u0075"]]},
+
+{"description": "Valid numeric entity character U+0076",
+"input": "&#x0076;",
+"output": [["Character", "\u0076"]]},
+
+{"description": "Valid numeric entity character U+0077",
+"input": "&#x0077;",
+"output": [["Character", "\u0077"]]},
+
+{"description": "Valid numeric entity character U+0078",
+"input": "&#x0078;",
+"output": [["Character", "\u0078"]]},
+
+{"description": "Valid numeric entity character U+0079",
+"input": "&#x0079;",
+"output": [["Character", "\u0079"]]},
+
+{"description": "Valid numeric entity character U+007A",
+"input": "&#x007a;",
+"output": [["Character", "\u007A"]]},
+
+{"description": "Valid numeric entity character U+007B",
+"input": "&#x007b;",
+"output": [["Character", "\u007B"]]},
+
+{"description": "Valid numeric entity character U+007C",
+"input": "&#x007c;",
+"output": [["Character", "\u007C"]]},
+
+{"description": "Valid numeric entity character U+007D",
+"input": "&#x007d;",
+"output": [["Character", "\u007D"]]},
+
+{"description": "Valid numeric entity character U+007E",
+"input": "&#x007e;",
+"output": [["Character", "\u007E"]]},
+
+{"description": "Valid numeric entity character U+00A0",
+"input": "&#x00a0;",
+"output": [["Character", "\u00A0"]]},
+
+{"description": "Valid numeric entity character U+00A1",
+"input": "&#x00a1;",
+"output": [["Character", "\u00A1"]]},
+
+{"description": "Valid numeric entity character U+00A2",
+"input": "&#x00a2;",
+"output": [["Character", "\u00A2"]]},
+
+{"description": "Valid numeric entity character U+00A3",
+"input": "&#x00a3;",
+"output": [["Character", "\u00A3"]]},
+
+{"description": "Valid numeric entity character U+00A4",
+"input": "&#x00a4;",
+"output": [["Character", "\u00A4"]]},
+
+{"description": "Valid numeric entity character U+00A5",
+"input": "&#x00a5;",
+"output": [["Character", "\u00A5"]]},
+
+{"description": "Valid numeric entity character U+00A6",
+"input": "&#x00a6;",
+"output": [["Character", "\u00A6"]]},
+
+{"description": "Valid numeric entity character U+00A7",
+"input": "&#x00a7;",
+"output": [["Character", "\u00A7"]]},
+
+{"description": "Valid numeric entity character U+00A8",
+"input": "&#x00a8;",
+"output": [["Character", "\u00A8"]]},
+
+{"description": "Valid numeric entity character U+00A9",
+"input": "&#x00a9;",
+"output": [["Character", "\u00A9"]]},
+
+{"description": "Valid numeric entity character U+00AA",
+"input": "&#x00aa;",
+"output": [["Character", "\u00AA"]]},
+
+{"description": "Valid numeric entity character U+00AB",
+"input": "&#x00ab;",
+"output": [["Character", "\u00AB"]]},
+
+{"description": "Valid numeric entity character U+00AC",
+"input": "&#x00ac;",
+"output": [["Character", "\u00AC"]]},
+
+{"description": "Valid numeric entity character U+00AD",
+"input": "&#x00ad;",
+"output": [["Character", "\u00AD"]]},
+
+{"description": "Valid numeric entity character U+00AE",
+"input": "&#x00ae;",
+"output": [["Character", "\u00AE"]]},
+
+{"description": "Valid numeric entity character U+00AF",
+"input": "&#x00af;",
+"output": [["Character", "\u00AF"]]},
+
+{"description": "Valid numeric entity character U+00B0",
+"input": "&#x00b0;",
+"output": [["Character", "\u00B0"]]},
+
+{"description": "Valid numeric entity character U+00B1",
+"input": "&#x00b1;",
+"output": [["Character", "\u00B1"]]},
+
+{"description": "Valid numeric entity character U+00B2",
+"input": "&#x00b2;",
+"output": [["Character", "\u00B2"]]},
+
+{"description": "Valid numeric entity character U+00B3",
+"input": "&#x00b3;",
+"output": [["Character", "\u00B3"]]},
+
+{"description": "Valid numeric entity character U+00B4",
+"input": "&#x00b4;",
+"output": [["Character", "\u00B4"]]},
+
+{"description": "Valid numeric entity character U+00B5",
+"input": "&#x00b5;",
+"output": [["Character", "\u00B5"]]},
+
+{"description": "Valid numeric entity character U+00B6",
+"input": "&#x00b6;",
+"output": [["Character", "\u00B6"]]},
+
+{"description": "Valid numeric entity character U+00B7",
+"input": "&#x00b7;",
+"output": [["Character", "\u00B7"]]},
+
+{"description": "Valid numeric entity character U+00B8",
+"input": "&#x00b8;",
+"output": [["Character", "\u00B8"]]},
+
+{"description": "Valid numeric entity character U+00B9",
+"input": "&#x00b9;",
+"output": [["Character", "\u00B9"]]},
+
+{"description": "Valid numeric entity character U+00BA",
+"input": "&#x00ba;",
+"output": [["Character", "\u00BA"]]},
+
+{"description": "Valid numeric entity character U+00BB",
+"input": "&#x00bb;",
+"output": [["Character", "\u00BB"]]},
+
+{"description": "Valid numeric entity character U+00BC",
+"input": "&#x00bc;",
+"output": [["Character", "\u00BC"]]},
+
+{"description": "Valid numeric entity character U+00BD",
+"input": "&#x00bd;",
+"output": [["Character", "\u00BD"]]},
+
+{"description": "Valid numeric entity character U+00BE",
+"input": "&#x00be;",
+"output": [["Character", "\u00BE"]]},
+
+{"description": "Valid numeric entity character U+00BF",
+"input": "&#x00bf;",
+"output": [["Character", "\u00BF"]]},
+
+{"description": "Valid numeric entity character U+00C0",
+"input": "&#x00c0;",
+"output": [["Character", "\u00C0"]]},
+
+{"description": "Valid numeric entity character U+00C1",
+"input": "&#x00c1;",
+"output": [["Character", "\u00C1"]]},
+
+{"description": "Valid numeric entity character U+00C2",
+"input": "&#x00c2;",
+"output": [["Character", "\u00C2"]]},
+
+{"description": "Valid numeric entity character U+00C3",
+"input": "&#x00c3;",
+"output": [["Character", "\u00C3"]]},
+
+{"description": "Valid numeric entity character U+00C4",
+"input": "&#x00c4;",
+"output": [["Character", "\u00C4"]]},
+
+{"description": "Valid numeric entity character U+00C5",
+"input": "&#x00c5;",
+"output": [["Character", "\u00C5"]]},
+
+{"description": "Valid numeric entity character U+00C6",
+"input": "&#x00c6;",
+"output": [["Character", "\u00C6"]]},
+
+{"description": "Valid numeric entity character U+00C7",
+"input": "&#x00c7;",
+"output": [["Character", "\u00C7"]]},
+
+{"description": "Valid numeric entity character U+00C8",
+"input": "&#x00c8;",
+"output": [["Character", "\u00C8"]]},
+
+{"description": "Valid numeric entity character U+00C9",
+"input": "&#x00c9;",
+"output": [["Character", "\u00C9"]]},
+
+{"description": "Valid numeric entity character U+00CA",
+"input": "&#x00ca;",
+"output": [["Character", "\u00CA"]]},
+
+{"description": "Valid numeric entity character U+00CB",
+"input": "&#x00cb;",
+"output": [["Character", "\u00CB"]]},
+
+{"description": "Valid numeric entity character U+00CC",
+"input": "&#x00cc;",
+"output": [["Character", "\u00CC"]]},
+
+{"description": "Valid numeric entity character U+00CD",
+"input": "&#x00cd;",
+"output": [["Character", "\u00CD"]]},
+
+{"description": "Valid numeric entity character U+00CE",
+"input": "&#x00ce;",
+"output": [["Character", "\u00CE"]]},
+
+{"description": "Valid numeric entity character U+00CF",
+"input": "&#x00cf;",
+"output": [["Character", "\u00CF"]]},
+
+{"description": "Valid numeric entity character U+00D0",
+"input": "&#x00d0;",
+"output": [["Character", "\u00D0"]]},
+
+{"description": "Valid numeric entity character U+00D1",
+"input": "&#x00d1;",
+"output": [["Character", "\u00D1"]]},
+
+{"description": "Valid numeric entity character U+00D2",
+"input": "&#x00d2;",
+"output": [["Character", "\u00D2"]]},
+
+{"description": "Valid numeric entity character U+00D3",
+"input": "&#x00d3;",
+"output": [["Character", "\u00D3"]]},
+
+{"description": "Valid numeric entity character U+00D4",
+"input": "&#x00d4;",
+"output": [["Character", "\u00D4"]]},
+
+{"description": "Valid numeric entity character U+00D5",
+"input": "&#x00d5;",
+"output": [["Character", "\u00D5"]]},
+
+{"description": "Valid numeric entity character U+00D6",
+"input": "&#x00d6;",
+"output": [["Character", "\u00D6"]]},
+
+{"description": "Valid numeric entity character U+00D7",
+"input": "&#x00d7;",
+"output": [["Character", "\u00D7"]]},
+
+{"description": "Valid numeric entity character U+00D8",
+"input": "&#x00d8;",
+"output": [["Character", "\u00D8"]]},
+
+{"description": "Valid numeric entity character U+00D9",
+"input": "&#x00d9;",
+"output": [["Character", "\u00D9"]]},
+
+{"description": "Valid numeric entity character U+00DA",
+"input": "&#x00da;",
+"output": [["Character", "\u00DA"]]},
+
+{"description": "Valid numeric entity character U+00DB",
+"input": "&#x00db;",
+"output": [["Character", "\u00DB"]]},
+
+{"description": "Valid numeric entity character U+00DC",
+"input": "&#x00dc;",
+"output": [["Character", "\u00DC"]]},
+
+{"description": "Valid numeric entity character U+00DD",
+"input": "&#x00dd;",
+"output": [["Character", "\u00DD"]]},
+
+{"description": "Valid numeric entity character U+00DE",
+"input": "&#x00de;",
+"output": [["Character", "\u00DE"]]},
+
+{"description": "Valid numeric entity character U+00DF",
+"input": "&#x00df;",
+"output": [["Character", "\u00DF"]]},
+
+{"description": "Valid numeric entity character U+00E0",
+"input": "&#x00e0;",
+"output": [["Character", "\u00E0"]]},
+
+{"description": "Valid numeric entity character U+00E1",
+"input": "&#x00e1;",
+"output": [["Character", "\u00E1"]]},
+
+{"description": "Valid numeric entity character U+00E2",
+"input": "&#x00e2;",
+"output": [["Character", "\u00E2"]]},
+
+{"description": "Valid numeric entity character U+00E3",
+"input": "&#x00e3;",
+"output": [["Character", "\u00E3"]]},
+
+{"description": "Valid numeric entity character U+00E4",
+"input": "&#x00e4;",
+"output": [["Character", "\u00E4"]]},
+
+{"description": "Valid numeric entity character U+00E5",
+"input": "&#x00e5;",
+"output": [["Character", "\u00E5"]]},
+
+{"description": "Valid numeric entity character U+00E6",
+"input": "&#x00e6;",
+"output": [["Character", "\u00E6"]]},
+
+{"description": "Valid numeric entity character U+00E7",
+"input": "&#x00e7;",
+"output": [["Character", "\u00E7"]]},
+
+{"description": "Valid numeric entity character U+00E8",
+"input": "&#x00e8;",
+"output": [["Character", "\u00E8"]]},
+
+{"description": "Valid numeric entity character U+00E9",
+"input": "&#x00e9;",
+"output": [["Character", "\u00E9"]]},
+
+{"description": "Valid numeric entity character U+00EA",
+"input": "&#x00ea;",
+"output": [["Character", "\u00EA"]]},
+
+{"description": "Valid numeric entity character U+00EB",
+"input": "&#x00eb;",
+"output": [["Character", "\u00EB"]]},
+
+{"description": "Valid numeric entity character U+00EC",
+"input": "&#x00ec;",
+"output": [["Character", "\u00EC"]]},
+
+{"description": "Valid numeric entity character U+00ED",
+"input": "&#x00ed;",
+"output": [["Character", "\u00ED"]]},
+
+{"description": "Valid numeric entity character U+00EE",
+"input": "&#x00ee;",
+"output": [["Character", "\u00EE"]]},
+
+{"description": "Valid numeric entity character U+00EF",
+"input": "&#x00ef;",
+"output": [["Character", "\u00EF"]]},
+
+{"description": "Valid numeric entity character U+00F0",
+"input": "&#x00f0;",
+"output": [["Character", "\u00F0"]]},
+
+{"description": "Valid numeric entity character U+00F1",
+"input": "&#x00f1;",
+"output": [["Character", "\u00F1"]]},
+
+{"description": "Valid numeric entity character U+00F2",
+"input": "&#x00f2;",
+"output": [["Character", "\u00F2"]]},
+
+{"description": "Valid numeric entity character U+00F3",
+"input": "&#x00f3;",
+"output": [["Character", "\u00F3"]]},
+
+{"description": "Valid numeric entity character U+00F4",
+"input": "&#x00f4;",
+"output": [["Character", "\u00F4"]]},
+
+{"description": "Valid numeric entity character U+00F5",
+"input": "&#x00f5;",
+"output": [["Character", "\u00F5"]]},
+
+{"description": "Valid numeric entity character U+00F6",
+"input": "&#x00f6;",
+"output": [["Character", "\u00F6"]]},
+
+{"description": "Valid numeric entity character U+00F7",
+"input": "&#x00f7;",
+"output": [["Character", "\u00F7"]]},
+
+{"description": "Valid numeric entity character U+00F8",
+"input": "&#x00f8;",
+"output": [["Character", "\u00F8"]]},
+
+{"description": "Valid numeric entity character U+00F9",
+"input": "&#x00f9;",
+"output": [["Character", "\u00F9"]]},
+
+{"description": "Valid numeric entity character U+00FA",
+"input": "&#x00fa;",
+"output": [["Character", "\u00FA"]]},
+
+{"description": "Valid numeric entity character U+00FB",
+"input": "&#x00fb;",
+"output": [["Character", "\u00FB"]]},
+
+{"description": "Valid numeric entity character U+00FC",
+"input": "&#x00fc;",
+"output": [["Character", "\u00FC"]]},
+
+{"description": "Valid numeric entity character U+00FD",
+"input": "&#x00fd;",
+"output": [["Character", "\u00FD"]]},
+
+{"description": "Valid numeric entity character U+00FE",
+"input": "&#x00fe;",
+"output": [["Character", "\u00FE"]]},
+
+{"description": "Valid numeric entity character U+00FF",
+"input": "&#x00ff;",
+"output": [["Character", "\u00FF"]]},
+
+{"description": "Valid numeric entity character U+D7FF",
+"input": "&#xd7ff;",
+"output": [["Character", "\uD7FF"]]},
+
+{"description": "Valid numeric entity character U+E000",
+"input": "&#xe000;",
+"output": [["Character", "\uE000"]]},
+
+{"description": "Valid numeric entity character U+FDCF",
+"input": "&#xfdcf;",
+"output": [["Character", "\uFDCF"]]},
+
+{"description": "Valid numeric entity character U+FDF0",
+"input": "&#xfdf0;",
+"output": [["Character", "\uFDF0"]]},
+
+{"description": "Valid numeric entity character U+FFFD",
+"input": "&#xfffd;",
+"output": [["Character", "\uFFFD"]]},
+
+{"description": "Valid numeric entity character U+10000",
+"input": "&#x10000;",
+"output": [["Character", "\uD800\uDC00"]]},
+
+{"description": "Valid numeric entity character U+1FFFD",
+"input": "&#x1fffd;",
+"output": [["Character", "\uD83F\uDFFD"]]},
+
+{"description": "Valid numeric entity character U+20000",
+"input": "&#x20000;",
+"output": [["Character", "\uD840\uDC00"]]},
+
+{"description": "Valid numeric entity character U+2FFFD",
+"input": "&#x2fffd;",
+"output": [["Character", "\uD87F\uDFFD"]]},
+
+{"description": "Valid numeric entity character U+30000",
+"input": "&#x30000;",
+"output": [["Character", "\uD880\uDC00"]]},
+
+{"description": "Valid numeric entity character U+3FFFD",
+"input": "&#x3fffd;",
+"output": [["Character", "\uD8BF\uDFFD"]]},
+
+{"description": "Valid numeric entity character U+40000",
+"input": "&#x40000;",
+"output": [["Character", "\uD8C0\uDC00"]]},
+
+{"description": "Valid numeric entity character U+4FFFD",
+"input": "&#x4fffd;",
+"output": [["Character", "\uD8FF\uDFFD"]]},
+
+{"description": "Valid numeric entity character U+50000",
+"input": "&#x50000;",
+"output": [["Character", "\uD900\uDC00"]]},
+
+{"description": "Valid numeric entity character U+5FFFD",
+"input": "&#x5fffd;",
+"output": [["Character", "\uD93F\uDFFD"]]},
+
+{"description": "Valid numeric entity character U+60000",
+"input": "&#x60000;",
+"output": [["Character", "\uD940\uDC00"]]},
+
+{"description": "Valid numeric entity character U+6FFFD",
+"input": "&#x6fffd;",
+"output": [["Character", "\uD97F\uDFFD"]]},
+
+{"description": "Valid numeric entity character U+70000",
+"input": "&#x70000;",
+"output": [["Character", "\uD980\uDC00"]]},
+
+{"description": "Valid numeric entity character U+7FFFD",
+"input": "&#x7fffd;",
+"output": [["Character", "\uD9BF\uDFFD"]]},
+
+{"description": "Valid numeric entity character U+80000",
+"input": "&#x80000;",
+"output": [["Character", "\uD9C0\uDC00"]]},
+
+{"description": "Valid numeric entity character U+8FFFD",
+"input": "&#x8fffd;",
+"output": [["Character", "\uD9FF\uDFFD"]]},
+
+{"description": "Valid numeric entity character U+90000",
+"input": "&#x90000;",
+"output": [["Character", "\uDA00\uDC00"]]},
+
+{"description": "Valid numeric entity character U+9FFFD",
+"input": "&#x9fffd;",
+"output": [["Character", "\uDA3F\uDFFD"]]},
+
+{"description": "Valid numeric entity character U+A0000",
+"input": "&#xa0000;",
+"output": [["Character", "\uDA40\uDC00"]]},
+
+{"description": "Valid numeric entity character U+AFFFD",
+"input": "&#xafffd;",
+"output": [["Character", "\uDA7F\uDFFD"]]},
+
+{"description": "Valid numeric entity character U+B0000",
+"input": "&#xb0000;",
+"output": [["Character", "\uDA80\uDC00"]]},
+
+{"description": "Valid numeric entity character U+BFFFD",
+"input": "&#xbfffd;",
+"output": [["Character", "\uDABF\uDFFD"]]},
+
+{"description": "Valid numeric entity character U+C0000",
+"input": "&#xc0000;",
+"output": [["Character", "\uDAC0\uDC00"]]},
+
+{"description": "Valid numeric entity character U+CFFFD",
+"input": "&#xcfffd;",
+"output": [["Character", "\uDAFF\uDFFD"]]},
+
+{"description": "Valid numeric entity character U+D0000",
+"input": "&#xd0000;",
+"output": [["Character", "\uDB00\uDC00"]]},
+
+{"description": "Valid numeric entity character U+DFFFD",
+"input": "&#xdfffd;",
+"output": [["Character", "\uDB3F\uDFFD"]]},
+
+{"description": "Valid numeric entity character U+E0000",
+"input": "&#xe0000;",
+"output": [["Character", "\uDB40\uDC00"]]},
+
+{"description": "Valid numeric entity character U+EFFFD",
+"input": "&#xefffd;",
+"output": [["Character", "\uDB7F\uDFFD"]]},
+
+{"description": "Valid numeric entity character U+F0000",
+"input": "&#xf0000;",
+"output": [["Character", "\uDB80\uDC00"]]},
+
+{"description": "Valid numeric entity character U+FFFFD",
+"input": "&#xffffd;",
+"output": [["Character", "\uDBBF\uDFFD"]]},
+
+{"description": "Valid numeric entity character U+100000",
+"input": "&#x100000;",
+"output": [["Character", "\uDBC0\uDC00"]]},
+
+{"description": "Valid numeric entity character U+10FFFD",
+"input": "&#x10fffd;",
+"output": [["Character", "\uDBFF\uDFFD"]]}
+
+]}
+
+
diff --git a/html/test/data/tokenizer/pendingSpecChanges.test b/html/test/data/tokenizer/pendingSpecChanges.test
new file mode 100644
index 0000000..1b7dc3c
--- /dev/null
+++ b/html/test/data/tokenizer/pendingSpecChanges.test
@@ -0,0 +1,7 @@
+{"tests": [
+
+{"description":"<!---- >",
+"input":"<!---- >",
+"output":["ParseError", "ParseError", ["Comment","-- >"]]}
+
+]}
diff --git a/html/test/data/tokenizer/test1.test b/html/test/data/tokenizer/test1.test
new file mode 100644
index 0000000..5de66f5
--- /dev/null
+++ b/html/test/data/tokenizer/test1.test
@@ -0,0 +1,196 @@
+{"tests": [
+
+{"description":"Correct Doctype lowercase",
+"input":"<!DOCTYPE html>",
+"output":[["DOCTYPE", "html", null, null, true]]},
+
+{"description":"Correct Doctype uppercase",
+"input":"<!DOCTYPE HTML>",
+"output":[["DOCTYPE", "html", null, null, true]]},
+
+{"description":"Correct Doctype mixed case",
+"input":"<!DOCTYPE HtMl>", 
+"output":[["DOCTYPE", "html", null, null, true]]},
+
+{"description":"Correct Doctype case with EOF",
+"input":"<!DOCTYPE HtMl", 
+"output":["ParseError", ["DOCTYPE", "html", null, null, false]]},
+
+{"description":"Truncated doctype start",
+"input":"<!DOC>", 
+"output":["ParseError", ["Comment", "DOC"]]},
+
+{"description":"Doctype in error",
+"input":"<!DOCTYPE foo>", 
+"output":[["DOCTYPE", "foo", null, null, true]]},
+
+{"description":"Single Start Tag",
+"input":"<h>",
+"output":[["StartTag", "h", {}]]},
+
+{"description":"Empty end tag",
+"input":"</>",
+"output":["ParseError"]},
+
+{"description":"Empty start tag",
+"input":"<>",
+"output":["ParseError", ["Character", "<>"]]},
+
+{"description":"Start Tag w/attribute",
+"input":"<h a='b'>",
+"output":[["StartTag", "h", {"a":"b"}]]},
+
+{"description":"Start Tag w/attribute no quotes",
+"input":"<h a=b>",
+"output":[["StartTag", "h", {"a":"b"}]]},
+
+{"description":"Start/End Tag",
+"input":"<h></h>",
+"output":[["StartTag", "h", {}], ["EndTag", "h"]]},
+
+{"description":"Two unclosed start tags",
+"input":"<p>One<p>Two",
+"output":[["StartTag", "p", {}], ["Character", "One"], ["StartTag", "p", {}], ["Character", "Two"]]},
+
+{"description":"End Tag w/attribute",
+"input":"<h></h a='b'>",
+"output":[["StartTag", "h", {}], "ParseError", ["EndTag", "h"]]},
+
+{"description":"Multiple atts",
+"input":"<h a='b' c='d'>",
+"output":[["StartTag", "h", {"a":"b", "c":"d"}]]},
+
+{"description":"Multiple atts no space",
+"input":"<h a='b'c='d'>",
+"output":["ParseError", ["StartTag", "h", {"a":"b", "c":"d"}]]},
+
+{"description":"Repeated attr",
+ "input":"<h a='b' a='d'>",
+ "output":["ParseError", ["StartTag", "h", {"a":"b"}]]},
+
+{"description":"Simple comment",
+ "input":"<!--comment-->",
+ "output":[["Comment", "comment"]]},
+
+{"description":"Comment, Central dash no space",
+ "input":"<!----->",
+ "output":["ParseError", ["Comment", "-"]]},
+
+{"description":"Comment, two central dashes",
+"input":"<!-- --comment -->",
+"output":["ParseError", ["Comment", " --comment "]]},
+
+{"description":"Unfinished comment",
+"input":"<!--comment",
+"output":["ParseError", ["Comment", "comment"]]},
+
+{"description":"Start of a comment",
+"input":"<!-",
+"output":["ParseError", ["Comment", "-"]]},
+
+{"description":"Short comment",
+ "input":"<!-->",
+ "output":["ParseError", ["Comment", ""]]},
+
+{"description":"Short comment two",
+ "input":"<!--->",
+ "output":["ParseError", ["Comment", ""]]},
+
+{"description":"Short comment three",
+ "input":"<!---->",
+ "output":[["Comment", ""]]},
+
+
+{"description":"Ampersand EOF",
+"input":"&",
+"output":[["Character", "&"]]},
+
+{"description":"Ampersand ampersand EOF",
+"input":"&&",
+"output":[["Character", "&&"]]},
+
+{"description":"Ampersand space EOF",
+"input":"& ",
+"output":[["Character", "& "]]},
+
+{"description":"Unfinished entity",
+"input":"&f",
+"output":["ParseError", ["Character", "&f"]]},
+
+{"description":"Ampersand, number sign",
+"input":"&#",
+"output":["ParseError", ["Character", "&#"]]},
+
+{"description":"Unfinished numeric entity",
+"input":"&#x",
+"output":["ParseError", ["Character", "&#x"]]},
+
+{"description":"Entity with trailing semicolon (1)",
+"input":"I'm &not;it",
+"output":[["Character","I'm \u00ACit"]]},
+
+{"description":"Entity with trailing semicolon (2)",
+"input":"I'm &notin;",
+"output":[["Character","I'm \u2209"]]},
+
+{"description":"Entity without trailing semicolon (1)",
+"input":"I'm &notit",
+"output":[["Character","I'm "], "ParseError", ["Character", "\u00ACit"]]},
+
+{"description":"Entity without trailing semicolon (2)",
+"input":"I'm &notin",
+"output":[["Character","I'm "], "ParseError", ["Character", "\u00ACin"]]},
+
+{"description":"Partial entity match at end of file",
+"input":"I'm &no",
+"output":[["Character","I'm "], "ParseError", ["Character", "&no"]]},
+
+{"description":"Non-ASCII character reference name",
+"input":"&\u00AC;",
+"output":["ParseError", ["Character", "&\u00AC;"]]},
+
+{"description":"ASCII decimal entity",
+"input":"&#0036;",
+"output":[["Character","$"]]},
+
+{"description":"ASCII hexadecimal entity",
+"input":"&#x3f;",
+"output":[["Character","?"]]},
+
+{"description":"Hexadecimal entity in attribute",
+"input":"<h a='&#x3f;'></h>",
+"output":[["StartTag", "h", {"a":"?"}], ["EndTag", "h"]]},
+
+{"description":"Entity in attribute without semicolon ending in x",
+"input":"<h a='&notx'>",
+"output":["ParseError", ["StartTag", "h", {"a":"&notx"}]]},
+
+{"description":"Entity in attribute without semicolon ending in 1",
+"input":"<h a='&not1'>",
+"output":["ParseError", ["StartTag", "h", {"a":"&not1"}]]},
+
+{"description":"Entity in attribute without semicolon ending in i",
+"input":"<h a='&noti'>",
+"output":["ParseError", ["StartTag", "h", {"a":"&noti"}]]},
+
+{"description":"Entity in attribute without semicolon",
+"input":"<h a='&COPY'>",
+"output":["ParseError", ["StartTag", "h", {"a":"\u00A9"}]]},
+
+{"description":"Unquoted attribute ending in ampersand",
+"input":"<s o=& t>",
+"output":[["StartTag","s",{"o":"&","t":""}]]},
+
+{"description":"Unquoted attribute at end of tag with final character of &, with tag followed by characters",
+"input":"<a a=a&>foo",
+"output":[["StartTag", "a", {"a":"a&"}], ["Character", "foo"]]},
+
+{"description":"plaintext element",
+ "input":"<plaintext>foobar",
+ "output":[["StartTag","plaintext",{}], ["Character","foobar"]]},
+
+{"description":"Open angled bracket in unquoted attribute value state",
+ "input":"<a a=f<>",
+ "output":["ParseError", ["StartTag", "a", {"a":"f<"}]]}
+
+]}
diff --git a/html/test/data/tokenizer/test2.test b/html/test/data/tokenizer/test2.test
new file mode 100644
index 0000000..e157514
--- /dev/null
+++ b/html/test/data/tokenizer/test2.test
@@ -0,0 +1,179 @@
+{"tests": [
+
+{"description":"DOCTYPE without name",
+"input":"<!DOCTYPE>",
+"output":["ParseError", "ParseError", ["DOCTYPE", "", null, null, false]]},
+
+{"description":"DOCTYPE without space before name",
+"input":"<!DOCTYPEhtml>",
+"output":["ParseError", ["DOCTYPE", "html", null, null, true]]},
+
+{"description":"Incorrect DOCTYPE without a space before name",
+"input":"<!DOCTYPEfoo>",
+"output":["ParseError", ["DOCTYPE", "foo", null, null, true]]},
+
+{"description":"DOCTYPE with publicId",
+"input":"<!DOCTYPE html PUBLIC \"-//W3C//DTD HTML Transitional 4.01//EN\">",
+"output":[["DOCTYPE", "html", "-//W3C//DTD HTML Transitional 4.01//EN", null, true]]},
+
+{"description":"DOCTYPE with EOF after PUBLIC",
+"input":"<!DOCTYPE html PUBLIC",
+"output":["ParseError", ["DOCTYPE", "html", null, null, false]]},
+
+{"description":"DOCTYPE with EOF after PUBLIC '",
+"input":"<!DOCTYPE html PUBLIC '",
+"output":["ParseError", ["DOCTYPE", "html", "", null, false]]},
+
+{"description":"DOCTYPE with EOF after PUBLIC 'x",
+"input":"<!DOCTYPE html PUBLIC 'x",
+"output":["ParseError", ["DOCTYPE", "html", "x", null, false]]},
+
+{"description":"DOCTYPE with systemId",
+"input":"<!DOCTYPE html SYSTEM \"-//W3C//DTD HTML Transitional 4.01//EN\">",
+"output":[["DOCTYPE", "html", null, "-//W3C//DTD HTML Transitional 4.01//EN", true]]},
+
+{"description":"DOCTYPE with publicId and systemId",
+"input":"<!DOCTYPE html PUBLIC \"-//W3C//DTD HTML Transitional 4.01//EN\" \"-//W3C//DTD HTML Transitional 4.01//EN\">",
+"output":[["DOCTYPE", "html", "-//W3C//DTD HTML Transitional 4.01//EN", "-//W3C//DTD HTML Transitional 4.01//EN", true]]},
+
+{"description":"DOCTYPE with > in double-quoted publicId",
+"input":"<!DOCTYPE html PUBLIC \">x",
+"output":["ParseError", ["DOCTYPE", "html", "", null, false], ["Character", "x"]]},
+
+{"description":"DOCTYPE with > in single-quoted publicId",
+"input":"<!DOCTYPE html PUBLIC '>x",
+"output":["ParseError", ["DOCTYPE", "html", "", null, false], ["Character", "x"]]},
+
+{"description":"DOCTYPE with > in double-quoted systemId",
+"input":"<!DOCTYPE html PUBLIC \"foo\" \">x",
+"output":["ParseError", ["DOCTYPE", "html", "foo", "", false], ["Character", "x"]]},
+
+{"description":"DOCTYPE with > in single-quoted systemId",
+"input":"<!DOCTYPE html PUBLIC 'foo' '>x",
+"output":["ParseError", ["DOCTYPE", "html", "foo", "", false], ["Character", "x"]]},
+
+{"description":"Incomplete doctype",
+"input":"<!DOCTYPE html ",
+"output":["ParseError", ["DOCTYPE", "html", null, null, false]]},
+
+{"description":"Numeric entity representing the NUL character",
+"input":"&#0000;",
+"output":["ParseError", ["Character", "\uFFFD"]]},
+
+{"description":"Hexadecimal entity representing the NUL character",
+"input":"&#x0000;",
+"output":["ParseError", ["Character", "\uFFFD"]]},
+
+{"description":"Numeric entity representing a codepoint after 1114111 (U+10FFFF)",
+"input":"&#2225222;",
+"output":["ParseError", ["Character", "\uFFFD"]]},
+
+{"description":"Hexadecimal entity representing a codepoint after 1114111 (U+10FFFF)",
+"input":"&#x1010FFFF;",
+"output":["ParseError", ["Character", "\uFFFD"]]},
+
+{"description":"Hexadecimal entity pair representing a surrogate pair",
+"input":"&#xD869;&#xDED6;",
+"output":["ParseError", ["Character", "\uFFFD"], "ParseError", ["Character", "\uFFFD"]]},
+
+{"description":"Hexadecimal entity with mixed uppercase and lowercase",
+"input":"&#xaBcD;",
+"output":[["Character", "\uABCD"]]},
+
+{"description":"Entity without a name",
+"input":"&;",
+"output":["ParseError", ["Character", "&;"]]},
+
+{"description":"Unescaped ampersand in attribute value",
+"input":"<h a='&'>",
+"output":[["StartTag", "h", { "a":"&" }]]},
+
+{"description":"StartTag containing <",
+"input":"<a<b>",
+"output":[["StartTag", "a<b", { }]]},
+
+{"description":"Non-void element containing trailing /",
+"input":"<h/>",
+"output":[["StartTag","h",{},true]]},
+
+{"description":"Void element with permitted slash",
+"input":"<br/>",
+"output":[["StartTag","br",{},true]]},
+
+{"description":"Void element with permitted slash (with attribute)",
+"input":"<br foo='bar'/>",
+"output":[["StartTag","br",{"foo":"bar"},true]]},
+
+{"description":"StartTag containing /",
+"input":"<h/a='b'>",
+"output":["ParseError", ["StartTag", "h", { "a":"b" }]]},
+
+{"description":"Double-quoted attribute value",
+"input":"<h a=\"b\">",
+"output":[["StartTag", "h", { "a":"b" }]]},
+
+{"description":"Unescaped </",
+"input":"</",
+"output":["ParseError", ["Character", "</"]]},
+
+{"description":"Illegal end tag name",
+"input":"</1>",
+"output":["ParseError", ["Comment", "1"]]},
+
+{"description":"Simili processing instruction",
+"input":"<?namespace>",
+"output":["ParseError", ["Comment", "?namespace"]]},
+
+{"description":"A bogus comment stops at >, even if preceeded by two dashes",
+"input":"<?foo-->",
+"output":["ParseError", ["Comment", "?foo--"]]},
+
+{"description":"Unescaped <",
+"input":"foo < bar",
+"output":[["Character", "foo "], "ParseError", ["Character", "< bar"]]},
+
+{"description":"Null Byte Replacement",
+"input":"\u0000",
+"output":["ParseError", ["Character", "\u0000"]]},
+
+{"description":"Comment with dash",
+"input":"<!---x",
+"output":["ParseError", ["Comment", "-x"]]},
+
+{"description":"Entity + newline",
+"input":"\nx\n&gt;\n",
+"output":[["Character","\nx\n>\n"]]},
+
+{"description":"Start tag with no attributes but space before the greater-than sign",
+"input":"<h >",
+"output":[["StartTag", "h", {}]]},
+
+{"description":"Empty attribute followed by uppercase attribute",
+"input":"<h a B=''>",
+"output":[["StartTag", "h", {"a":"", "b":""}]]},
+
+{"description":"Double-quote after attribute name",
+"input":"<h a \">",
+"output":["ParseError", ["StartTag", "h", {"a":"", "\"":""}]]},
+
+{"description":"Single-quote after attribute name",
+"input":"<h a '>",
+"output":["ParseError", ["StartTag", "h", {"a":"", "'":""}]]},
+
+{"description":"Empty end tag with following characters",
+"input":"a</>bc",
+"output":[["Character", "a"], "ParseError", ["Character", "bc"]]},
+
+{"description":"Empty end tag with following tag",
+"input":"a</><b>c",
+"output":[["Character", "a"], "ParseError", ["StartTag", "b", {}], ["Character", "c"]]},
+
+{"description":"Empty end tag with following comment",
+"input":"a</><!--b-->c",
+"output":[["Character", "a"], "ParseError", ["Comment", "b"], ["Character", "c"]]},
+
+{"description":"Empty end tag with following end tag",
+"input":"a</></b>c",
+"output":[["Character", "a"], "ParseError", ["EndTag", "b"], ["Character", "c"]]}
+
+]}
diff --git a/html/test/data/tokenizer/test3.test b/html/test/data/tokenizer/test3.test
new file mode 100644
index 0000000..58519e8
--- /dev/null
+++ b/html/test/data/tokenizer/test3.test
@@ -0,0 +1,6047 @@
+{"tests": [
+
+{"description":"",
+"input":"",
+"output":[]},
+
+{"description":"\\u0009",
+"input":"\u0009",
+"output":[["Character", "\u0009"]]},
+
+{"description":"\\u000A",
+"input":"\u000A",
+"output":[["Character", "\u000A"]]},
+
+{"description":"\\u000B",
+"input":"\u000B",
+"output":["ParseError", ["Character", "\u000B"]]},
+
+{"description":"\\u000C",
+"input":"\u000C",
+"output":[["Character", "\u000C"]]},
+
+{"description":" ",
+"input":" ",
+"output":[["Character", " "]]},
+
+{"description":"!",
+"input":"!",
+"output":[["Character", "!"]]},
+
+{"description":"\"",
+"input":"\"",
+"output":[["Character", "\""]]},
+
+{"description":"%",
+"input":"%",
+"output":[["Character", "%"]]},
+
+{"description":"&",
+"input":"&",
+"output":[["Character", "&"]]},
+
+{"description":"'",
+"input":"'",
+"output":[["Character", "'"]]},
+
+{"description":",",
+"input":",",
+"output":[["Character", ","]]},
+
+{"description":"-",
+"input":"-",
+"output":[["Character", "-"]]},
+
+{"description":".",
+"input":".",
+"output":[["Character", "."]]},
+
+{"description":"/",
+"input":"/",
+"output":[["Character", "/"]]},
+
+{"description":"0",
+"input":"0",
+"output":[["Character", "0"]]},
+
+{"description":"1",
+"input":"1",
+"output":[["Character", "1"]]},
+
+{"description":"9",
+"input":"9",
+"output":[["Character", "9"]]},
+
+{"description":";",
+"input":";",
+"output":[["Character", ";"]]},
+
+{"description":"<",
+"input":"<",
+"output":["ParseError", ["Character", "<"]]},
+
+{"description":"<\\u0000",
+"input":"<\u0000",
+"output":["ParseError", ["Character", "<"], "ParseError", ["Character", "\u0000"]]},
+
+{"description":"<\\u0009",
+"input":"<\u0009",
+"output":["ParseError", ["Character", "<\u0009"]]},
+
+{"description":"<\\u000A",
+"input":"<\u000A",
+"output":["ParseError", ["Character", "<\u000A"]]},
+
+{"description":"<\\u000B",
+"input":"<\u000B",
+"output":["ParseError", "ParseError", ["Character", "<\u000B"]]},
+
+{"description":"<\\u000C",
+"input":"<\u000C",
+"output":["ParseError", ["Character", "<\u000C"]]},
+
+{"description":"< ",
+"input":"< ",
+"output":["ParseError", ["Character", "< "]]},
+
+{"description":"<!",
+"input":"<!",
+"output":["ParseError", ["Comment", ""]]},
+
+{"description":"<!\\u0000",
+"input":"<!\u0000",
+"output":["ParseError", ["Comment", "\uFFFD"]]},
+
+{"description":"<!\\u0009",
+"input":"<!\u0009",
+"output":["ParseError", ["Comment", "\u0009"]]},
+
+{"description":"<!\\u000A",
+"input":"<!\u000A",
+"output":["ParseError", ["Comment", "\u000A"]]},
+
+{"description":"<!\\u000B",
+"input":"<!\u000B",
+"output":["ParseError", "ParseError", ["Comment", "\u000B"]]},
+
+{"description":"<!\\u000C",
+"input":"<!\u000C",
+"output":["ParseError", ["Comment", "\u000C"]]},
+
+{"description":"<! ",
+"input":"<! ",
+"output":["ParseError", ["Comment", " "]]},
+
+{"description":"<!!",
+"input":"<!!",
+"output":["ParseError", ["Comment", "!"]]},
+
+{"description":"<!\"",
+"input":"<!\"",
+"output":["ParseError", ["Comment", "\""]]},
+
+{"description":"<!&",
+"input":"<!&",
+"output":["ParseError", ["Comment", "&"]]},
+
+{"description":"<!'",
+"input":"<!'",
+"output":["ParseError", ["Comment", "'"]]},
+
+{"description":"<!-",
+"input":"<!-",
+"output":["ParseError", ["Comment", "-"]]},
+
+{"description":"<!--",
+"input":"<!--",
+"output":["ParseError", ["Comment", ""]]},
+
+{"description":"<!--\\u0000",
+"input":"<!--\u0000",
+"output":["ParseError", "ParseError", ["Comment", "\uFFFD"]]},
+
+{"description":"<!--\\u0009",
+"input":"<!--\u0009",
+"output":["ParseError", ["Comment", "\u0009"]]},
+
+{"description":"<!--\\u000A",
+"input":"<!--\u000A",
+"output":["ParseError", ["Comment", "\u000A"]]},
+
+{"description":"<!--\\u000B",
+"input":"<!--\u000B",
+"output":["ParseError", "ParseError", ["Comment", "\u000B"]]},
+
+{"description":"<!--\\u000C",
+"input":"<!--\u000C",
+"output":["ParseError", ["Comment", "\u000C"]]},
+
+{"description":"<!-- ",
+"input":"<!-- ",
+"output":["ParseError", ["Comment", " "]]},
+
+{"description":"<!-- \\u0000",
+"input":"<!-- \u0000",
+"output":["ParseError", "ParseError", ["Comment", " \uFFFD"]]},
+
+{"description":"<!-- \\u0009",
+"input":"<!-- \u0009",
+"output":["ParseError", ["Comment", " \u0009"]]},
+
+{"description":"<!-- \\u000A",
+"input":"<!-- \u000A",
+"output":["ParseError", ["Comment", " \u000A"]]},
+
+{"description":"<!-- \\u000B",
+"input":"<!-- \u000B",
+"output":["ParseError", "ParseError", ["Comment", " \u000B"]]},
+
+{"description":"<!-- \\u000C",
+"input":"<!-- \u000C",
+"output":["ParseError", ["Comment", " \u000C"]]},
+
+{"description":"<!--  ",
+"input":"<!--  ",
+"output":["ParseError", ["Comment", "  "]]},
+
+{"description":"<!-- !",
+"input":"<!-- !",
+"output":["ParseError", ["Comment", " !"]]},
+
+{"description":"<!-- \"",
+"input":"<!-- \"",
+"output":["ParseError", ["Comment", " \""]]},
+
+{"description":"<!-- &",
+"input":"<!-- &",
+"output":["ParseError", ["Comment", " &"]]},
+
+{"description":"<!-- '",
+"input":"<!-- '",
+"output":["ParseError", ["Comment", " '"]]},
+
+{"description":"<!-- ,",
+"input":"<!-- ,",
+"output":["ParseError", ["Comment", " ,"]]},
+
+{"description":"<!-- -",
+"input":"<!-- -",
+"output":["ParseError", ["Comment", " "]]},
+
+{"description":"<!-- -\\u0000",
+"input":"<!-- -\u0000",
+"output":["ParseError", "ParseError", ["Comment", " -\uFFFD"]]},
+
+{"description":"<!-- -\\u0009",
+"input":"<!-- -\u0009",
+"output":["ParseError", ["Comment", " -\u0009"]]},
+
+{"description":"<!-- -\\u000A",
+"input":"<!-- -\u000A",
+"output":["ParseError", ["Comment", " -\u000A"]]},
+
+{"description":"<!-- -\\u000B",
+"input":"<!-- -\u000B",
+"output":["ParseError", "ParseError", ["Comment", " -\u000B"]]},
+
+{"description":"<!-- -\\u000C",
+"input":"<!-- -\u000C",
+"output":["ParseError", ["Comment", " -\u000C"]]},
+
+{"description":"<!-- - ",
+"input":"<!-- - ",
+"output":["ParseError", ["Comment", " - "]]},
+
+{"description":"<!-- -!",
+"input":"<!-- -!",
+"output":["ParseError", ["Comment", " -!"]]},
+
+{"description":"<!-- -\"",
+"input":"<!-- -\"",
+"output":["ParseError", ["Comment", " -\""]]},
+
+{"description":"<!-- -&",
+"input":"<!-- -&",
+"output":["ParseError", ["Comment", " -&"]]},
+
+{"description":"<!-- -'",
+"input":"<!-- -'",
+"output":["ParseError", ["Comment", " -'"]]},
+
+{"description":"<!-- -,",
+"input":"<!-- -,",
+"output":["ParseError", ["Comment", " -,"]]},
+
+{"description":"<!-- --",
+"input":"<!-- --",
+"output":["ParseError", ["Comment", " "]]},
+
+{"description":"<!-- -.",
+"input":"<!-- -.",
+"output":["ParseError", ["Comment", " -."]]},
+
+{"description":"<!-- -/",
+"input":"<!-- -/",
+"output":["ParseError", ["Comment", " -/"]]},
+
+{"description":"<!-- -0",
+"input":"<!-- -0",
+"output":["ParseError", ["Comment", " -0"]]},
+
+{"description":"<!-- -1",
+"input":"<!-- -1",
+"output":["ParseError", ["Comment", " -1"]]},
+
+{"description":"<!-- -9",
+"input":"<!-- -9",
+"output":["ParseError", ["Comment", " -9"]]},
+
+{"description":"<!-- -<",
+"input":"<!-- -<",
+"output":["ParseError", ["Comment", " -<"]]},
+
+{"description":"<!-- -=",
+"input":"<!-- -=",
+"output":["ParseError", ["Comment", " -="]]},
+
+{"description":"<!-- ->",
+"input":"<!-- ->",
+"output":["ParseError", ["Comment", " ->"]]},
+
+{"description":"<!-- -?",
+"input":"<!-- -?",
+"output":["ParseError", ["Comment", " -?"]]},
+
+{"description":"<!-- -@",
+"input":"<!-- -@",
+"output":["ParseError", ["Comment", " -@"]]},
+
+{"description":"<!-- -A",
+"input":"<!-- -A",
+"output":["ParseError", ["Comment", " -A"]]},
+
+{"description":"<!-- -B",
+"input":"<!-- -B",
+"output":["ParseError", ["Comment", " -B"]]},
+
+{"description":"<!-- -Y",
+"input":"<!-- -Y",
+"output":["ParseError", ["Comment", " -Y"]]},
+
+{"description":"<!-- -Z",
+"input":"<!-- -Z",
+"output":["ParseError", ["Comment", " -Z"]]},
+
+{"description":"<!-- -`",
+"input":"<!-- -`",
+"output":["ParseError", ["Comment", " -`"]]},
+
+{"description":"<!-- -a",
+"input":"<!-- -a",
+"output":["ParseError", ["Comment", " -a"]]},
+
+{"description":"<!-- -b",
+"input":"<!-- -b",
+"output":["ParseError", ["Comment", " -b"]]},
+
+{"description":"<!-- -y",
+"input":"<!-- -y",
+"output":["ParseError", ["Comment", " -y"]]},
+
+{"description":"<!-- -z",
+"input":"<!-- -z",
+"output":["ParseError", ["Comment", " -z"]]},
+
+{"description":"<!-- -{",
+"input":"<!-- -{",
+"output":["ParseError", ["Comment", " -{"]]},
+
+{"description":"<!-- -\\uDBC0\\uDC00",
+"input":"<!-- -\uDBC0\uDC00",
+"output":["ParseError", ["Comment", " -\uDBC0\uDC00"]]},
+
+{"description":"<!-- .",
+"input":"<!-- .",
+"output":["ParseError", ["Comment", " ."]]},
+
+{"description":"<!-- /",
+"input":"<!-- /",
+"output":["ParseError", ["Comment", " /"]]},
+
+{"description":"<!-- 0",
+"input":"<!-- 0",
+"output":["ParseError", ["Comment", " 0"]]},
+
+{"description":"<!-- 1",
+"input":"<!-- 1",
+"output":["ParseError", ["Comment", " 1"]]},
+
+{"description":"<!-- 9",
+"input":"<!-- 9",
+"output":["ParseError", ["Comment", " 9"]]},
+
+{"description":"<!-- <",
+"input":"<!-- <",
+"output":["ParseError", ["Comment", " <"]]},
+
+{"description":"<!-- =",
+"input":"<!-- =",
+"output":["ParseError", ["Comment", " ="]]},
+
+{"description":"<!-- >",
+"input":"<!-- >",
+"output":["ParseError", ["Comment", " >"]]},
+
+{"description":"<!-- ?",
+"input":"<!-- ?",
+"output":["ParseError", ["Comment", " ?"]]},
+
+{"description":"<!-- @",
+"input":"<!-- @",
+"output":["ParseError", ["Comment", " @"]]},
+
+{"description":"<!-- A",
+"input":"<!-- A",
+"output":["ParseError", ["Comment", " A"]]},
+
+{"description":"<!-- B",
+"input":"<!-- B",
+"output":["ParseError", ["Comment", " B"]]},
+
+{"description":"<!-- Y",
+"input":"<!-- Y",
+"output":["ParseError", ["Comment", " Y"]]},
+
+{"description":"<!-- Z",
+"input":"<!-- Z",
+"output":["ParseError", ["Comment", " Z"]]},
+
+{"description":"<!-- `",
+"input":"<!-- `",
+"output":["ParseError", ["Comment", " `"]]},
+
+{"description":"<!-- a",
+"input":"<!-- a",
+"output":["ParseError", ["Comment", " a"]]},
+
+{"description":"<!-- b",
+"input":"<!-- b",
+"output":["ParseError", ["Comment", " b"]]},
+
+{"description":"<!-- y",
+"input":"<!-- y",
+"output":["ParseError", ["Comment", " y"]]},
+
+{"description":"<!-- z",
+"input":"<!-- z",
+"output":["ParseError", ["Comment", " z"]]},
+
+{"description":"<!-- {",
+"input":"<!-- {",
+"output":["ParseError", ["Comment", " {"]]},
+
+{"description":"<!-- \\uDBC0\\uDC00",
+"input":"<!-- \uDBC0\uDC00",
+"output":["ParseError", ["Comment", " \uDBC0\uDC00"]]},
+
+{"description":"<!--!",
+"input":"<!--!",
+"output":["ParseError", ["Comment", "!"]]},
+
+{"description":"<!--\"",
+"input":"<!--\"",
+"output":["ParseError", ["Comment", "\""]]},
+
+{"description":"<!--&",
+"input":"<!--&",
+"output":["ParseError", ["Comment", "&"]]},
+
+{"description":"<!--'",
+"input":"<!--'",
+"output":["ParseError", ["Comment", "'"]]},
+
+{"description":"<!--,",
+"input":"<!--,",
+"output":["ParseError", ["Comment", ","]]},
+
+{"description":"<!---",
+"input":"<!---",
+"output":["ParseError", ["Comment", ""]]},
+
+{"description":"<!---\\u0000",
+"input":"<!---\u0000",
+"output":["ParseError", "ParseError", ["Comment", "-\uFFFD"]]},
+
+{"description":"<!---\\u0009",
+"input":"<!---\u0009",
+"output":["ParseError", ["Comment", "-\u0009"]]},
+
+{"description":"<!---\\u000A",
+"input":"<!---\u000A",
+"output":["ParseError", ["Comment", "-\u000A"]]},
+
+{"description":"<!---\\u000B",
+"input":"<!---\u000B",
+"output":["ParseError", "ParseError", ["Comment", "-\u000B"]]},
+
+{"description":"<!---\\u000C",
+"input":"<!---\u000C",
+"output":["ParseError", ["Comment", "-\u000C"]]},
+
+{"description":"<!--- ",
+"input":"<!--- ",
+"output":["ParseError", ["Comment", "- "]]},
+
+{"description":"<!---!",
+"input":"<!---!",
+"output":["ParseError", ["Comment", "-!"]]},
+
+{"description":"<!---\"",
+"input":"<!---\"",
+"output":["ParseError", ["Comment", "-\""]]},
+
+{"description":"<!---&",
+"input":"<!---&",
+"output":["ParseError", ["Comment", "-&"]]},
+
+{"description":"<!---'",
+"input":"<!---'",
+"output":["ParseError", ["Comment", "-'"]]},
+
+{"description":"<!---,",
+"input":"<!---,",
+"output":["ParseError", ["Comment", "-,"]]},
+
+{"description":"<!----",
+"input":"<!----",
+"output":["ParseError", ["Comment", ""]]},
+
+{"description":"<!----\\u0000",
+"input":"<!----\u0000",
+"output":["ParseError", "ParseError", ["Comment", "--\uFFFD"]]},
+
+{"description":"<!----\\u0009",
+"input":"<!----\u0009",
+"output":["ParseError", "ParseError", ["Comment", "--\u0009"]]},
+
+{"description":"<!----\\u000A",
+"input":"<!----\u000A",
+"output":["ParseError", "ParseError", ["Comment", "--\u000A"]]},
+
+{"description":"<!----\\u000B",
+"input":"<!----\u000B",
+"output":["ParseError", "ParseError", "ParseError", ["Comment", "--\u000B"]]},
+
+{"description":"<!----\\u000C",
+"input":"<!----\u000C",
+"output":["ParseError", "ParseError", ["Comment", "--\u000C"]]},
+
+{"description":"<!---- ",
+"input":"<!---- ",
+"output":["ParseError", "ParseError", ["Comment", "-- "]]},
+
+{"description":"<!---- -",
+"input":"<!---- -",
+"output":["ParseError", "ParseError", ["Comment", "-- "]]},
+
+{"description":"<!---- --",
+"input":"<!---- --",
+"output":["ParseError", "ParseError", ["Comment", "-- "]]},
+
+{"description":"<!---- -->",
+"input":"<!---- -->",
+"output":["ParseError", ["Comment", "-- "]]},
+
+{"description":"<!----  -->",
+"input":"<!----  -->",
+"output":["ParseError", ["Comment", "--  "]]},
+
+{"description":"<!---- a-->",
+"input":"<!---- a-->",
+"output":["ParseError", ["Comment", "-- a"]]},
+
+{"description":"<!----!",
+"input":"<!----!",
+"output":["ParseError", "ParseError", ["Comment", ""]]},
+
+{"description":"<!----!>",
+"input":"<!----!>",
+"output":["ParseError", ["Comment", ""]]},
+
+{"description":"<!----!a",
+"input":"<!----!a",
+"output":["ParseError", "ParseError", ["Comment", "--!a"]]},
+
+{"description":"<!----!a-",
+"input":"<!----!a-",
+"output":["ParseError", "ParseError", ["Comment", "--!a"]]},
+
+{"description":"<!----!a--",
+"input":"<!----!a--",
+"output":["ParseError", "ParseError", ["Comment", "--!a"]]},
+
+{"description":"<!----!a-->",
+"input":"<!----!a-->",
+"output":["ParseError", ["Comment", "--!a"]]},
+
+{"description":"<!----!-",
+"input":"<!----!-",
+"output":["ParseError", "ParseError", ["Comment", "--!"]]},
+
+{"description":"<!----!--",
+"input":"<!----!--",
+"output":["ParseError", "ParseError", ["Comment", "--!"]]},
+
+{"description":"<!----!-->",
+"input":"<!----!-->",
+"output":["ParseError", ["Comment", "--!"]]},
+
+{"description":"<!----\"",
+"input":"<!----\"",
+"output":["ParseError", "ParseError", ["Comment", "--\""]]},
+
+{"description":"<!----&",
+"input":"<!----&",
+"output":["ParseError", "ParseError", ["Comment", "--&"]]},
+
+{"description":"<!----'",
+"input":"<!----'",
+"output":["ParseError", "ParseError", ["Comment", "--'"]]},
+
+{"description":"<!----,",
+"input":"<!----,",
+"output":["ParseError", "ParseError", ["Comment", "--,"]]},
+
+{"description":"<!-----",
+"input":"<!-----",
+"output":["ParseError", "ParseError", ["Comment", "-"]]},
+
+{"description":"<!----.",
+"input":"<!----.",
+"output":["ParseError", "ParseError", ["Comment", "--."]]},
+
+{"description":"<!----/",
+"input":"<!----/",
+"output":["ParseError", "ParseError", ["Comment", "--/"]]},
+
+{"description":"<!----0",
+"input":"<!----0",
+"output":["ParseError", "ParseError", ["Comment", "--0"]]},
+
+{"description":"<!----1",
+"input":"<!----1",
+"output":["ParseError", "ParseError", ["Comment", "--1"]]},
+
+{"description":"<!----9",
+"input":"<!----9",
+"output":["ParseError", "ParseError", ["Comment", "--9"]]},
+
+{"description":"<!----<",
+"input":"<!----<",
+"output":["ParseError", "ParseError", ["Comment", "--<"]]},
+
+{"description":"<!----=",
+"input":"<!----=",
+"output":["ParseError", "ParseError", ["Comment", "--="]]},
+
+{"description":"<!---->",
+"input":"<!---->",
+"output":[["Comment", ""]]},
+
+{"description":"<!----?",
+"input":"<!----?",
+"output":["ParseError", "ParseError", ["Comment", "--?"]]},
+
+{"description":"<!----@",
+"input":"<!----@",
+"output":["ParseError", "ParseError", ["Comment", "--@"]]},
+
+{"description":"<!----A",
+"input":"<!----A",
+"output":["ParseError", "ParseError", ["Comment", "--A"]]},
+
+{"description":"<!----B",
+"input":"<!----B",
+"output":["ParseError", "ParseError", ["Comment", "--B"]]},
+
+{"description":"<!----Y",
+"input":"<!----Y",
+"output":["ParseError", "ParseError", ["Comment", "--Y"]]},
+
+{"description":"<!----Z",
+"input":"<!----Z",
+"output":["ParseError", "ParseError", ["Comment", "--Z"]]},
+
+{"description":"<!----`",
+"input":"<!----`",
+"output":["ParseError", "ParseError", ["Comment", "--`"]]},
+
+{"description":"<!----a",
+"input":"<!----a",
+"output":["ParseError", "ParseError", ["Comment", "--a"]]},
+
+{"description":"<!----b",
+"input":"<!----b",
+"output":["ParseError", "ParseError", ["Comment", "--b"]]},
+
+{"description":"<!----y",
+"input":"<!----y",
+"output":["ParseError", "ParseError", ["Comment", "--y"]]},
+
+{"description":"<!----z",
+"input":"<!----z",
+"output":["ParseError", "ParseError", ["Comment", "--z"]]},
+
+{"description":"<!----{",
+"input":"<!----{",
+"output":["ParseError", "ParseError", ["Comment", "--{"]]},
+
+{"description":"<!----\\uDBC0\\uDC00",
+"input":"<!----\uDBC0\uDC00",
+"output":["ParseError", "ParseError", ["Comment", "--\uDBC0\uDC00"]]},
+
+{"description":"<!---.",
+"input":"<!---.",
+"output":["ParseError", ["Comment", "-."]]},
+
+{"description":"<!---/",
+"input":"<!---/",
+"output":["ParseError", ["Comment", "-/"]]},
+
+{"description":"<!---0",
+"input":"<!---0",
+"output":["ParseError", ["Comment", "-0"]]},
+
+{"description":"<!---1",
+"input":"<!---1",
+"output":["ParseError", ["Comment", "-1"]]},
+
+{"description":"<!---9",
+"input":"<!---9",
+"output":["ParseError", ["Comment", "-9"]]},
+
+{"description":"<!---<",
+"input":"<!---<",
+"output":["ParseError", ["Comment", "-<"]]},
+
+{"description":"<!---=",
+"input":"<!---=",
+"output":["ParseError", ["Comment", "-="]]},
+
+{"description":"<!--->",
+"input":"<!--->",
+"output":["ParseError", ["Comment", ""]]},
+
+{"description":"<!---?",
+"input":"<!---?",
+"output":["ParseError", ["Comment", "-?"]]},
+
+{"description":"<!---@",
+"input":"<!---@",
+"output":["ParseError", ["Comment", "-@"]]},
+
+{"description":"<!---A",
+"input":"<!---A",
+"output":["ParseError", ["Comment", "-A"]]},
+
+{"description":"<!---B",
+"input":"<!---B",
+"output":["ParseError", ["Comment", "-B"]]},
+
+{"description":"<!---Y",
+"input":"<!---Y",
+"output":["ParseError", ["Comment", "-Y"]]},
+
+{"description":"<!---Z",
+"input":"<!---Z",
+"output":["ParseError", ["Comment", "-Z"]]},
+
+{"description":"<!---`",
+"input":"<!---`",
+"output":["ParseError", ["Comment", "-`"]]},
+
+{"description":"<!---a",
+"input":"<!---a",
+"output":["ParseError", ["Comment", "-a"]]},
+
+{"description":"<!---b",
+"input":"<!---b",
+"output":["ParseError", ["Comment", "-b"]]},
+
+{"description":"<!---y",
+"input":"<!---y",
+"output":["ParseError", ["Comment", "-y"]]},
+
+{"description":"<!---z",
+"input":"<!---z",
+"output":["ParseError", ["Comment", "-z"]]},
+
+{"description":"<!---{",
+"input":"<!---{",
+"output":["ParseError", ["Comment", "-{"]]},
+
+{"description":"<!---\\uDBC0\\uDC00",
+"input":"<!---\uDBC0\uDC00",
+"output":["ParseError", ["Comment", "-\uDBC0\uDC00"]]},
+
+{"description":"<!--.",
+"input":"<!--.",
+"output":["ParseError", ["Comment", "."]]},
+
+{"description":"<!--/",
+"input":"<!--/",
+"output":["ParseError", ["Comment", "/"]]},
+
+{"description":"<!--0",
+"input":"<!--0",
+"output":["ParseError", ["Comment", "0"]]},
+
+{"description":"<!--1",
+"input":"<!--1",
+"output":["ParseError", ["Comment", "1"]]},
+
+{"description":"<!--9",
+"input":"<!--9",
+"output":["ParseError", ["Comment", "9"]]},
+
+{"description":"<!--<",
+"input":"<!--<",
+"output":["ParseError", ["Comment", "<"]]},
+
+{"description":"<!--=",
+"input":"<!--=",
+"output":["ParseError", ["Comment", "="]]},
+
+{"description":"<!-->",
+"input":"<!-->",
+"output":["ParseError", ["Comment", ""]]},
+
+{"description":"<!--?",
+"input":"<!--?",
+"output":["ParseError", ["Comment", "?"]]},
+
+{"description":"<!--@",
+"input":"<!--@",
+"output":["ParseError", ["Comment", "@"]]},
+
+{"description":"<!--A",
+"input":"<!--A",
+"output":["ParseError", ["Comment", "A"]]},
+
+{"description":"<!--B",
+"input":"<!--B",
+"output":["ParseError", ["Comment", "B"]]},
+
+{"description":"<!--Y",
+"input":"<!--Y",
+"output":["ParseError", ["Comment", "Y"]]},
+
+{"description":"<!--Z",
+"input":"<!--Z",
+"output":["ParseError", ["Comment", "Z"]]},
+
+{"description":"<!--`",
+"input":"<!--`",
+"output":["ParseError", ["Comment", "`"]]},
+
+{"description":"<!--a",
+"input":"<!--a",
+"output":["ParseError", ["Comment", "a"]]},
+
+{"description":"<!--b",
+"input":"<!--b",
+"output":["ParseError", ["Comment", "b"]]},
+
+{"description":"<!--y",
+"input":"<!--y",
+"output":["ParseError", ["Comment", "y"]]},
+
+{"description":"<!--z",
+"input":"<!--z",
+"output":["ParseError", ["Comment", "z"]]},
+
+{"description":"<!--{",
+"input":"<!--{",
+"output":["ParseError", ["Comment", "{"]]},
+
+{"description":"<!--\\uDBC0\\uDC00",
+"input":"<!--\uDBC0\uDC00",
+"output":["ParseError", ["Comment", "\uDBC0\uDC00"]]},
+
+{"description":"<!/",
+"input":"<!/",
+"output":["ParseError", ["Comment", "/"]]},
+
+{"description":"<!0",
+"input":"<!0",
+"output":["ParseError", ["Comment", "0"]]},
+
+{"description":"<!1",
+"input":"<!1",
+"output":["ParseError", ["Comment", "1"]]},
+
+{"description":"<!9",
+"input":"<!9",
+"output":["ParseError", ["Comment", "9"]]},
+
+{"description":"<!<",
+"input":"<!<",
+"output":["ParseError", ["Comment", "<"]]},
+
+{"description":"<!=",
+"input":"<!=",
+"output":["ParseError", ["Comment", "="]]},
+
+{"description":"<!>",
+"input":"<!>",
+"output":["ParseError", ["Comment", ""]]},
+
+{"description":"<!?",
+"input":"<!?",
+"output":["ParseError", ["Comment", "?"]]},
+
+{"description":"<!@",
+"input":"<!@",
+"output":["ParseError", ["Comment", "@"]]},
+
+{"description":"<!A",
+"input":"<!A",
+"output":["ParseError", ["Comment", "A"]]},
+
+{"description":"<!B",
+"input":"<!B",
+"output":["ParseError", ["Comment", "B"]]},
+
+{"description":"<!DOCTYPE",
+"input":"<!DOCTYPE",
+"output":["ParseError", ["DOCTYPE", "", null, null, false]]},
+
+{"description":"<!DOCTYPE\\u0000",
+"input":"<!DOCTYPE\u0000",
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "\uFFFD", null, null, false]]},
+
+{"description":"<!DOCTYPE\\u0008",
+"input":"<!DOCTYPE\u0008",
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "\u0008", null, null, false]]},
+
+{"description":"<!DOCTYPE\\u0009",
+"input":"<!DOCTYPE\u0009",
+"output":["ParseError", ["DOCTYPE", "", null, null, false]]},
+
+{"description":"<!DOCTYPE\\u000A",
+"input":"<!DOCTYPE\u000A",
+"output":["ParseError", ["DOCTYPE", "", null, null, false]]},
+
+{"description":"<!DOCTYPE\\u000B",
+"input":"<!DOCTYPE\u000B",
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "\u000B", null, null, false]]},
+
+{"description":"<!DOCTYPE\\u000C",
+"input":"<!DOCTYPE\u000C",
+"output":["ParseError", ["DOCTYPE", "", null, null, false]]},
+
+{"description":"<!DOCTYPE\\u000D",
+"input":"<!DOCTYPE\u000D",
+"output":["ParseError", ["DOCTYPE", "", null, null, false]]},
+
+{"description":"<!DOCTYPE\\u001F",
+"input":"<!DOCTYPE\u001F",
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "\u001F", null, null, false]]},
+
+{"description":"<!DOCTYPE ",
+"input":"<!DOCTYPE ",
+"output":["ParseError", ["DOCTYPE", "", null, null, false]]},
+
+{"description":"<!DOCTYPE \\u0000",
+"input":"<!DOCTYPE \u0000",
+"output":["ParseError", "ParseError", ["DOCTYPE", "\uFFFD", null, null, false]]},
+
+{"description":"<!DOCTYPE \\u0008",
+"input":"<!DOCTYPE \u0008",
+"output":["ParseError", "ParseError", ["DOCTYPE", "\u0008", null, null, false]]},
+
+{"description":"<!DOCTYPE \\u0009",
+"input":"<!DOCTYPE \u0009",
+"output":["ParseError", ["DOCTYPE", "", null, null, false]]},
+
+{"description":"<!DOCTYPE \\u000A",
+"input":"<!DOCTYPE \u000A",
+"output":["ParseError", ["DOCTYPE", "", null, null, false]]},
+
+{"description":"<!DOCTYPE \\u000B",
+"input":"<!DOCTYPE \u000B",
+"output":["ParseError", "ParseError", ["DOCTYPE", "\u000B", null, null, false]]},
+
+{"description":"<!DOCTYPE \\u000C",
+"input":"<!DOCTYPE \u000C",
+"output":["ParseError", ["DOCTYPE", "", null, null, false]]},
+
+{"description":"<!DOCTYPE \\u000D",
+"input":"<!DOCTYPE \u000D",
+"output":["ParseError", ["DOCTYPE", "", null, null, false]]},
+
+{"description":"<!DOCTYPE \\u001F",
+"input":"<!DOCTYPE \u001F",
+"output":["ParseError", "ParseError", ["DOCTYPE", "\u001F", null, null, false]]},
+
+{"description":"<!DOCTYPE  ",
+"input":"<!DOCTYPE  ",
+"output":["ParseError", ["DOCTYPE", "", null, null, false]]},
+
+{"description":"<!DOCTYPE !",
+"input":"<!DOCTYPE !",
+"output":["ParseError", ["DOCTYPE", "!", null, null, false]]},
+
+{"description":"<!DOCTYPE \"",
+"input":"<!DOCTYPE \"",
+"output":["ParseError", ["DOCTYPE", "\"", null, null, false]]},
+
+{"description":"<!DOCTYPE &",
+"input":"<!DOCTYPE &",
+"output":["ParseError", ["DOCTYPE", "&", null, null, false]]},
+
+{"description":"<!DOCTYPE '",
+"input":"<!DOCTYPE '",
+"output":["ParseError", ["DOCTYPE", "'", null, null, false]]},
+
+{"description":"<!DOCTYPE -",
+"input":"<!DOCTYPE -",
+"output":["ParseError", ["DOCTYPE", "-", null, null, false]]},
+
+{"description":"<!DOCTYPE /",
+"input":"<!DOCTYPE /",
+"output":["ParseError", ["DOCTYPE", "/", null, null, false]]},
+
+{"description":"<!DOCTYPE 0",
+"input":"<!DOCTYPE 0",
+"output":["ParseError", ["DOCTYPE", "0", null, null, false]]},
+
+{"description":"<!DOCTYPE 1",
+"input":"<!DOCTYPE 1",
+"output":["ParseError", ["DOCTYPE", "1", null, null, false]]},
+
+{"description":"<!DOCTYPE 9",
+"input":"<!DOCTYPE 9",
+"output":["ParseError", ["DOCTYPE", "9", null, null, false]]},
+
+{"description":"<!DOCTYPE <",
+"input":"<!DOCTYPE <",
+"output":["ParseError", ["DOCTYPE", "<", null, null, false]]},
+
+{"description":"<!DOCTYPE =",
+"input":"<!DOCTYPE =",
+"output":["ParseError", ["DOCTYPE", "=", null, null, false]]},
+
+{"description":"<!DOCTYPE >",
+"input":"<!DOCTYPE >",
+"output":["ParseError", ["DOCTYPE", "", null, null, false]]},
+
+{"description":"<!DOCTYPE ?",
+"input":"<!DOCTYPE ?",
+"output":["ParseError", ["DOCTYPE", "?", null, null, false]]},
+
+{"description":"<!DOCTYPE @",
+"input":"<!DOCTYPE @",
+"output":["ParseError", ["DOCTYPE", "@", null, null, false]]},
+
+{"description":"<!DOCTYPE A",
+"input":"<!DOCTYPE A",
+"output":["ParseError", ["DOCTYPE", "a", null, null, false]]},
+
+{"description":"<!DOCTYPE B",
+"input":"<!DOCTYPE B",
+"output":["ParseError", ["DOCTYPE", "b", null, null, false]]},
+
+{"description":"<!DOCTYPE Y",
+"input":"<!DOCTYPE Y",
+"output":["ParseError", ["DOCTYPE", "y", null, null, false]]},
+
+{"description":"<!DOCTYPE Z",
+"input":"<!DOCTYPE Z",
+"output":["ParseError", ["DOCTYPE", "z", null, null, false]]},
+
+{"description":"<!DOCTYPE [",
+"input":"<!DOCTYPE [",
+"output":["ParseError", ["DOCTYPE", "[", null, null, false]]},
+
+{"description":"<!DOCTYPE `",
+"input":"<!DOCTYPE `",
+"output":["ParseError", ["DOCTYPE", "`", null, null, false]]},
+
+{"description":"<!DOCTYPE a",
+"input":"<!DOCTYPE a",
+"output":["ParseError", ["DOCTYPE", "a", null, null, false]]},
+
+{"description":"<!DOCTYPE a\\u0000",
+"input":"<!DOCTYPE a\u0000",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a\uFFFD", null, null, false]]},
+
+{"description":"<!DOCTYPE a\\u0008",
+"input":"<!DOCTYPE a\u0008",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a\u0008", null, null, false]]},
+
+{"description":"<!DOCTYPE a\\u0009",
+"input":"<!DOCTYPE a\u0009",
+"output":["ParseError", ["DOCTYPE", "a", null, null, false]]},
+
+{"description":"<!DOCTYPE a\\u000A",
+"input":"<!DOCTYPE a\u000A",
+"output":["ParseError", ["DOCTYPE", "a", null, null, false]]},
+
+{"description":"<!DOCTYPE a\\u000B",
+"input":"<!DOCTYPE a\u000B",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a\u000B", null, null, false]]},
+
+{"description":"<!DOCTYPE a\\u000C",
+"input":"<!DOCTYPE a\u000C",
+"output":["ParseError", ["DOCTYPE", "a", null, null, false]]},
+
+{"description":"<!DOCTYPE a\\u000D",
+"input":"<!DOCTYPE a\u000D",
+"output":["ParseError", ["DOCTYPE", "a", null, null, false]]},
+
+{"description":"<!DOCTYPE a\\u001F",
+"input":"<!DOCTYPE a\u001F",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a\u001F", null, null, false]]},
+
+{"description":"<!DOCTYPE a ",
+"input":"<!DOCTYPE a ",
+"output":["ParseError", ["DOCTYPE", "a", null, null, false]]},
+
+{"description":"<!DOCTYPE a \\u0000",
+"input":"<!DOCTYPE a \u0000",
+"output":["ParseError", ["DOCTYPE", "a", null, null, false]]},
+
+{"description":"<!DOCTYPE a \\u0008",
+"input":"<!DOCTYPE a \u0008",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, null, false]]},
+
+{"description":"<!DOCTYPE a \\u0009",
+"input":"<!DOCTYPE a \u0009",
+"output":["ParseError", ["DOCTYPE", "a", null, null, false]]},
+
+{"description":"<!DOCTYPE a \\u000A",
+"input":"<!DOCTYPE a \u000A",
+"output":["ParseError", ["DOCTYPE", "a", null, null, false]]},
+
+{"description":"<!DOCTYPE a \\u000B",
+"input":"<!DOCTYPE a \u000B",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, null, false]]},
+
+{"description":"<!DOCTYPE a \\u000C",
+"input":"<!DOCTYPE a \u000C",
+"output":["ParseError", ["DOCTYPE", "a", null, null, false]]},
+
+{"description":"<!DOCTYPE a \\u000D",
+"input":"<!DOCTYPE a \u000D",
+"output":["ParseError", ["DOCTYPE", "a", null, null, false]]},
+
+{"description":"<!DOCTYPE a \\u001F",
+"input":"<!DOCTYPE a \u001F",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, null, false]]},
+
+{"description":"<!DOCTYPE a  ",
+"input":"<!DOCTYPE a  ",
+"output":["ParseError", ["DOCTYPE", "a", null, null, false]]},
+
+{"description":"<!DOCTYPE a !",
+"input":"<!DOCTYPE a !",
+"output":["ParseError", ["DOCTYPE", "a", null, null, false]]},
+
+{"description":"<!DOCTYPE a \"",
+"input":"<!DOCTYPE a \"",
+"output":["ParseError", ["DOCTYPE", "a", null, null, false]]},
+
+{"description":"<!DOCTYPE a &",
+"input":"<!DOCTYPE a &",
+"output":["ParseError", ["DOCTYPE", "a", null, null, false]]},
+
+{"description":"<!DOCTYPE a '",
+"input":"<!DOCTYPE a '",
+"output":["ParseError", ["DOCTYPE", "a", null, null, false]]},
+
+{"description":"<!DOCTYPE a -",
+"input":"<!DOCTYPE a -",
+"output":["ParseError", ["DOCTYPE", "a", null, null, false]]},
+
+{"description":"<!DOCTYPE a /",
+"input":"<!DOCTYPE a /",
+"output":["ParseError", ["DOCTYPE", "a", null, null, false]]},
+
+{"description":"<!DOCTYPE a 0",
+"input":"<!DOCTYPE a 0",
+"output":["ParseError", ["DOCTYPE", "a", null, null, false]]},
+
+{"description":"<!DOCTYPE a 1",
+"input":"<!DOCTYPE a 1",
+"output":["ParseError", ["DOCTYPE", "a", null, null, false]]},
+
+{"description":"<!DOCTYPE a 9",
+"input":"<!DOCTYPE a 9",
+"output":["ParseError", ["DOCTYPE", "a", null, null, false]]},
+
+{"description":"<!DOCTYPE a <",
+"input":"<!DOCTYPE a <",
+"output":["ParseError", ["DOCTYPE", "a", null, null, false]]},
+
+{"description":"<!DOCTYPE a =",
+"input":"<!DOCTYPE a =",
+"output":["ParseError", ["DOCTYPE", "a", null, null, false]]},
+
+{"description":"<!DOCTYPE a >",
+"input":"<!DOCTYPE a >",
+"output":[["DOCTYPE", "a", null, null, true]]},
+
+{"description":"<!DOCTYPE a ?",
+"input":"<!DOCTYPE a ?",
+"output":["ParseError", ["DOCTYPE", "a", null, null, false]]},
+
+{"description":"<!DOCTYPE a @",
+"input":"<!DOCTYPE a @",
+"output":["ParseError", ["DOCTYPE", "a", null, null, false]]},
+
+{"description":"<!DOCTYPE a A",
+"input":"<!DOCTYPE a A",
+"output":["ParseError", ["DOCTYPE", "a", null, null, false]]},
+
+{"description":"<!DOCTYPE a B",
+"input":"<!DOCTYPE a B",
+"output":["ParseError", ["DOCTYPE", "a", null, null, false]]},
+
+{"description":"<!DOCTYPE a PUBLIC",
+"input":"<!DOCTYPE a PUBLIC",
+"output":["ParseError", ["DOCTYPE", "a", null, null, false]]},
+
+{"description":"<!DOCTYPE a PUBLIC\\u0000",
+"input":"<!DOCTYPE a PUBLIC\u0000",
+"output":["ParseError", ["DOCTYPE", "a", null, null, false]]},
+
+{"description":"<!DOCTYPE a PUBLIC\\u0008",
+"input":"<!DOCTYPE a PUBLIC\u0008",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, null, false]]},
+
+{"description":"<!DOCTYPE a PUBLIC\\u0009",
+"input":"<!DOCTYPE a PUBLIC\u0009",
+"output":["ParseError", ["DOCTYPE", "a", null, null, false]]},
+
+{"description":"<!DOCTYPE a PUBLIC\\u000A",
+"input":"<!DOCTYPE a PUBLIC\u000A",
+"output":["ParseError", ["DOCTYPE", "a", null, null, false]]},
+
+{"description":"<!DOCTYPE a PUBLIC\\u000B",
+"input":"<!DOCTYPE a PUBLIC\u000B",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, null, false]]},
+
+{"description":"<!DOCTYPE a PUBLIC\\u000C",
+"input":"<!DOCTYPE a PUBLIC\u000C",
+"output":["ParseError", ["DOCTYPE", "a", null, null, false]]},
+
+{"description":"<!DOCTYPE a PUBLIC\\u000D",
+"input":"<!DOCTYPE a PUBLIC\u000D",
+"output":["ParseError", ["DOCTYPE", "a", null, null, false]]},
+
+{"description":"<!DOCTYPE a PUBLIC\\u001F",
+"input":"<!DOCTYPE a PUBLIC\u001F",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, null, false]]},
+
+{"description":"<!DOCTYPE a PUBLIC ",
+"input":"<!DOCTYPE a PUBLIC ",
+"output":["ParseError", ["DOCTYPE", "a", null, null, false]]},
+
+{"description":"<!DOCTYPE a PUBLIC!",
+"input":"<!DOCTYPE a PUBLIC!",
+"output":["ParseError", ["DOCTYPE", "a", null, null, false]]},
+
+{"description":"<!DOCTYPE a PUBLIC\"",
+"input":"<!DOCTYPE a PUBLIC\"",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", "", null, false]]},
+
+{"description":"<!DOCTYPE a PUBLIC\"\\u0000",
+"input":"<!DOCTYPE a PUBLIC\"\u0000",
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", "\uFFFD", null, false]]},
+
+{"description":"<!DOCTYPE a PUBLIC\"\\u0009",
+"input":"<!DOCTYPE a PUBLIC\"\u0009",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", "\u0009", null, false]]},
+
+{"description":"<!DOCTYPE a PUBLIC\"\\u000A",
+"input":"<!DOCTYPE a PUBLIC\"\u000A",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", "\u000A", null, false]]},
+
+{"description":"<!DOCTYPE a PUBLIC\"\\u000B",
+"input":"<!DOCTYPE a PUBLIC\"\u000B",
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", "\u000B", null, false]]},
+
+{"description":"<!DOCTYPE a PUBLIC\"\\u000C",
+"input":"<!DOCTYPE a PUBLIC\"\u000C",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", "\u000C", null, false]]},
+
+{"description":"<!DOCTYPE a PUBLIC\" ",
+"input":"<!DOCTYPE a PUBLIC\" ",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", " ", null, false]]},
+
+{"description":"<!DOCTYPE a PUBLIC\"!",
+"input":"<!DOCTYPE a PUBLIC\"!",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", "!", null, false]]},
+
+{"description":"<!DOCTYPE a PUBLIC\"\"",
+"input":"<!DOCTYPE a PUBLIC\"\"",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", "", null, false]]},
+
+{"description":"<!DOCTYPE a PUBLIC\"#",
+"input":"<!DOCTYPE a PUBLIC\"#",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", "#", null, false]]},
+
+{"description":"<!DOCTYPE a PUBLIC\"&",
+"input":"<!DOCTYPE a PUBLIC\"&",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", "&", null, false]]},
+
+{"description":"<!DOCTYPE a PUBLIC\"'",
+"input":"<!DOCTYPE a PUBLIC\"'",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", "'", null, false]]},
+
+{"description":"<!DOCTYPE a PUBLIC\"-",
+"input":"<!DOCTYPE a PUBLIC\"-",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", "-", null, false]]},
+
+{"description":"<!DOCTYPE a PUBLIC\"/",
+"input":"<!DOCTYPE a PUBLIC\"/",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", "/", null, false]]},
+
+{"description":"<!DOCTYPE a PUBLIC\"0",
+"input":"<!DOCTYPE a PUBLIC\"0",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", "0", null, false]]},
+
+{"description":"<!DOCTYPE a PUBLIC\"1",
+"input":"<!DOCTYPE a PUBLIC\"1",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", "1", null, false]]},
+
+{"description":"<!DOCTYPE a PUBLIC\"9",
+"input":"<!DOCTYPE a PUBLIC\"9",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", "9", null, false]]},
+
+{"description":"<!DOCTYPE a PUBLIC\"<",
+"input":"<!DOCTYPE a PUBLIC\"<",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", "<", null, false]]},
+
+{"description":"<!DOCTYPE a PUBLIC\"=",
+"input":"<!DOCTYPE a PUBLIC\"=",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", "=", null, false]]},
+
+{"description":"<!DOCTYPE a PUBLIC\">",
+"input":"<!DOCTYPE a PUBLIC\">",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", "", null, false]]},
+
+{"description":"<!DOCTYPE a PUBLIC\"?",
+"input":"<!DOCTYPE a PUBLIC\"?",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", "?", null, false]]},
+
+{"description":"<!DOCTYPE a PUBLIC\"@",
+"input":"<!DOCTYPE a PUBLIC\"@",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", "@", null, false]]},
+
+{"description":"<!DOCTYPE a PUBLIC\"A",
+"input":"<!DOCTYPE a PUBLIC\"A",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", "A", null, false]]},
+
+{"description":"<!DOCTYPE a PUBLIC\"B",
+"input":"<!DOCTYPE a PUBLIC\"B",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", "B", null, false]]},
+
+{"description":"<!DOCTYPE a PUBLIC\"Y",
+"input":"<!DOCTYPE a PUBLIC\"Y",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", "Y", null, false]]},
+
+{"description":"<!DOCTYPE a PUBLIC\"Z",
+"input":"<!DOCTYPE a PUBLIC\"Z",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", "Z", null, false]]},
+
+{"description":"<!DOCTYPE a PUBLIC\"`",
+"input":"<!DOCTYPE a PUBLIC\"`",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", "`", null, false]]},
+
+{"description":"<!DOCTYPE a PUBLIC\"a",
+"input":"<!DOCTYPE a PUBLIC\"a",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", "a", null, false]]},
+
+{"description":"<!DOCTYPE a PUBLIC\"b",
+"input":"<!DOCTYPE a PUBLIC\"b",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", "b", null, false]]},
+
+{"description":"<!DOCTYPE a PUBLIC\"y",
+"input":"<!DOCTYPE a PUBLIC\"y",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", "y", null, false]]},
+
+{"description":"<!DOCTYPE a PUBLIC\"z",
+"input":"<!DOCTYPE a PUBLIC\"z",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", "z", null, false]]},
+
+{"description":"<!DOCTYPE a PUBLIC\"{",
+"input":"<!DOCTYPE a PUBLIC\"{",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", "{", null, false]]},
+
+{"description":"<!DOCTYPE a PUBLIC\"\\uDBC0\\uDC00",
+"input":"<!DOCTYPE a PUBLIC\"\uDBC0\uDC00",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", "\uDBC0\uDC00", null, false]]},
+
+{"description":"<!DOCTYPE a PUBLIC#",
+"input":"<!DOCTYPE a PUBLIC#",
+"output":["ParseError", ["DOCTYPE", "a", null, null, false]]},
+
+{"description":"<!DOCTYPE a PUBLIC&",
+"input":"<!DOCTYPE a PUBLIC&",
+"output":["ParseError", ["DOCTYPE", "a", null, null, false]]},
+
+{"description":"<!DOCTYPE a PUBLIC'",
+"input":"<!DOCTYPE a PUBLIC'",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", "", null, false]]},
+
+{"description":"<!DOCTYPE a PUBLIC'\\u0000",
+"input":"<!DOCTYPE a PUBLIC'\u0000",
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", "\uFFFD", null, false]]},
+
+{"description":"<!DOCTYPE a PUBLIC'\\u0009",
+"input":"<!DOCTYPE a PUBLIC'\u0009",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", "\u0009", null, false]]},
+
+{"description":"<!DOCTYPE a PUBLIC'\\u000A",
+"input":"<!DOCTYPE a PUBLIC'\u000A",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", "\u000A", null, false]]},
+
+{"description":"<!DOCTYPE a PUBLIC'\\u000B",
+"input":"<!DOCTYPE a PUBLIC'\u000B",
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", "\u000B", null, false]]},
+
+{"description":"<!DOCTYPE a PUBLIC'\\u000C",
+"input":"<!DOCTYPE a PUBLIC'\u000C",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", "\u000C", null, false]]},
+
+{"description":"<!DOCTYPE a PUBLIC' ",
+"input":"<!DOCTYPE a PUBLIC' ",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", " ", null, false]]},
+
+{"description":"<!DOCTYPE a PUBLIC'!",
+"input":"<!DOCTYPE a PUBLIC'!",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", "!", null, false]]},
+
+{"description":"<!DOCTYPE a PUBLIC'\"",
+"input":"<!DOCTYPE a PUBLIC'\"",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", "\"", null, false]]},
+
+{"description":"<!DOCTYPE a PUBLIC'&",
+"input":"<!DOCTYPE a PUBLIC'&",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", "&", null, false]]},
+
+{"description":"<!DOCTYPE a PUBLIC''",
+"input":"<!DOCTYPE a PUBLIC''",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", "", null, false]]},
+
+{"description":"<!DOCTYPE a PUBLIC''\\u0000",
+"input":"<!DOCTYPE a PUBLIC''\u0000",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", "", null, false]]},
+
+{"description":"<!DOCTYPE a PUBLIC''\\u0008",
+"input":"<!DOCTYPE a PUBLIC''\u0008",
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", "", null, false]]},
+
+{"description":"<!DOCTYPE a PUBLIC''\\u0009",
+"input":"<!DOCTYPE a PUBLIC''\u0009",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", "", null, false]]},
+
+{"description":"<!DOCTYPE a PUBLIC''\\u000A",
+"input":"<!DOCTYPE a PUBLIC''\u000A",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", "", null, false]]},
+
+{"description":"<!DOCTYPE a PUBLIC''\\u000B",
+"input":"<!DOCTYPE a PUBLIC''\u000B",
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", "", null, false]]},
+
+{"description":"<!DOCTYPE a PUBLIC''\\u000C",
+"input":"<!DOCTYPE a PUBLIC''\u000C",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", "", null, false]]},
+
+{"description":"<!DOCTYPE a PUBLIC''\\u000D",
+"input":"<!DOCTYPE a PUBLIC''\u000D",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", "", null, false]]},
+
+{"description":"<!DOCTYPE a PUBLIC''\\u001F",
+"input":"<!DOCTYPE a PUBLIC''\u001F",
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", "", null, false]]},
+
+{"description":"<!DOCTYPE a PUBLIC'' ",
+"input":"<!DOCTYPE a PUBLIC'' ",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", "", null, false]]},
+
+{"description":"<!DOCTYPE a PUBLIC''!",
+"input":"<!DOCTYPE a PUBLIC''!",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", "", null, false]]},
+
+{"description":"<!DOCTYPE a PUBLIC''\"",
+"input":"<!DOCTYPE a PUBLIC''\"",
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", "", "", false]]},
+
+{"description":"<!DOCTYPE a PUBLIC''#",
+"input":"<!DOCTYPE a PUBLIC''#",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", "", null, false]]},
+
+{"description":"<!DOCTYPE a PUBLIC''&",
+"input":"<!DOCTYPE a PUBLIC''&",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", "", null, false]]},
+
+{"description":"<!DOCTYPE a PUBLIC'''",
+"input":"<!DOCTYPE a PUBLIC'''",
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", "", "", false]]},
+
+{"description":"<!DOCTYPE a PUBLIC''(",
+"input":"<!DOCTYPE a PUBLIC''(",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", "", null, false]]},
+
+{"description":"<!DOCTYPE a PUBLIC''-",
+"input":"<!DOCTYPE a PUBLIC''-",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", "", null, false]]},
+
+{"description":"<!DOCTYPE a PUBLIC''/",
+"input":"<!DOCTYPE a PUBLIC''/",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", "", null, false]]},
+
+{"description":"<!DOCTYPE a PUBLIC''0",
+"input":"<!DOCTYPE a PUBLIC''0",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", "", null, false]]},
+
+{"description":"<!DOCTYPE a PUBLIC''1",
+"input":"<!DOCTYPE a PUBLIC''1",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", "", null, false]]},
+
+{"description":"<!DOCTYPE a PUBLIC''9",
+"input":"<!DOCTYPE a PUBLIC''9",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", "", null, false]]},
+
+{"description":"<!DOCTYPE a PUBLIC''<",
+"input":"<!DOCTYPE a PUBLIC''<",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", "", null, false]]},
+
+{"description":"<!DOCTYPE a PUBLIC''=",
+"input":"<!DOCTYPE a PUBLIC''=",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", "", null, false]]},
+
+{"description":"<!DOCTYPE a PUBLIC''>",
+"input":"<!DOCTYPE a PUBLIC''>",
+"output":["ParseError", ["DOCTYPE", "a", "", null, true]]},
+
+{"description":"<!DOCTYPE a PUBLIC''?",
+"input":"<!DOCTYPE a PUBLIC''?",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", "", null, false]]},
+
+{"description":"<!DOCTYPE a PUBLIC''@",
+"input":"<!DOCTYPE a PUBLIC''@",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", "", null, false]]},
+
+{"description":"<!DOCTYPE a PUBLIC''A",
+"input":"<!DOCTYPE a PUBLIC''A",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", "", null, false]]},
+
+{"description":"<!DOCTYPE a PUBLIC''B",
+"input":"<!DOCTYPE a PUBLIC''B",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", "", null, false]]},
+
+{"description":"<!DOCTYPE a PUBLIC''Y",
+"input":"<!DOCTYPE a PUBLIC''Y",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", "", null, false]]},
+
+{"description":"<!DOCTYPE a PUBLIC''Z",
+"input":"<!DOCTYPE a PUBLIC''Z",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", "", null, false]]},
+
+{"description":"<!DOCTYPE a PUBLIC''`",
+"input":"<!DOCTYPE a PUBLIC''`",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", "", null, false]]},
+
+{"description":"<!DOCTYPE a PUBLIC''a",
+"input":"<!DOCTYPE a PUBLIC''a",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", "", null, false]]},
+
+{"description":"<!DOCTYPE a PUBLIC''b",
+"input":"<!DOCTYPE a PUBLIC''b",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", "", null, false]]},
+
+{"description":"<!DOCTYPE a PUBLIC''y",
+"input":"<!DOCTYPE a PUBLIC''y",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", "", null, false]]},
+
+{"description":"<!DOCTYPE a PUBLIC''z",
+"input":"<!DOCTYPE a PUBLIC''z",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", "", null, false]]},
+
+{"description":"<!DOCTYPE a PUBLIC''{",
+"input":"<!DOCTYPE a PUBLIC''{",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", "", null, false]]},
+
+{"description":"<!DOCTYPE a PUBLIC''\\uDBC0\\uDC00",
+"input":"<!DOCTYPE a PUBLIC''\uDBC0\uDC00",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", "", null, false]]},
+
+{"description":"<!DOCTYPE a PUBLIC'(",
+"input":"<!DOCTYPE a PUBLIC'(",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", "(", null, false]]},
+
+{"description":"<!DOCTYPE a PUBLIC'-",
+"input":"<!DOCTYPE a PUBLIC'-",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", "-", null, false]]},
+
+{"description":"<!DOCTYPE a PUBLIC'/",
+"input":"<!DOCTYPE a PUBLIC'/",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", "/", null, false]]},
+
+{"description":"<!DOCTYPE a PUBLIC'0",
+"input":"<!DOCTYPE a PUBLIC'0",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", "0", null, false]]},
+
+{"description":"<!DOCTYPE a PUBLIC'1",
+"input":"<!DOCTYPE a PUBLIC'1",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", "1", null, false]]},
+
+{"description":"<!DOCTYPE a PUBLIC'9",
+"input":"<!DOCTYPE a PUBLIC'9",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", "9", null, false]]},
+
+{"description":"<!DOCTYPE a PUBLIC'<",
+"input":"<!DOCTYPE a PUBLIC'<",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", "<", null, false]]},
+
+{"description":"<!DOCTYPE a PUBLIC'=",
+"input":"<!DOCTYPE a PUBLIC'=",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", "=", null, false]]},
+
+{"description":"<!DOCTYPE a PUBLIC'>",
+"input":"<!DOCTYPE a PUBLIC'>",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", "", null, false]]},
+
+{"description":"<!DOCTYPE a PUBLIC'?",
+"input":"<!DOCTYPE a PUBLIC'?",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", "?", null, false]]},
+
+{"description":"<!DOCTYPE a PUBLIC'@",
+"input":"<!DOCTYPE a PUBLIC'@",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", "@", null, false]]},
+
+{"description":"<!DOCTYPE a PUBLIC'A",
+"input":"<!DOCTYPE a PUBLIC'A",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", "A", null, false]]},
+
+{"description":"<!DOCTYPE a PUBLIC'B",
+"input":"<!DOCTYPE a PUBLIC'B",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", "B", null, false]]},
+
+{"description":"<!DOCTYPE a PUBLIC'Y",
+"input":"<!DOCTYPE a PUBLIC'Y",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", "Y", null, false]]},
+
+{"description":"<!DOCTYPE a PUBLIC'Z",
+"input":"<!DOCTYPE a PUBLIC'Z",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", "Z", null, false]]},
+
+{"description":"<!DOCTYPE a PUBLIC'`",
+"input":"<!DOCTYPE a PUBLIC'`",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", "`", null, false]]},
+
+{"description":"<!DOCTYPE a PUBLIC'a",
+"input":"<!DOCTYPE a PUBLIC'a",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", "a", null, false]]},
+
+{"description":"<!DOCTYPE a PUBLIC'b",
+"input":"<!DOCTYPE a PUBLIC'b",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", "b", null, false]]},
+
+{"description":"<!DOCTYPE a PUBLIC'y",
+"input":"<!DOCTYPE a PUBLIC'y",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", "y", null, false]]},
+
+{"description":"<!DOCTYPE a PUBLIC'z",
+"input":"<!DOCTYPE a PUBLIC'z",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", "z", null, false]]},
+
+{"description":"<!DOCTYPE a PUBLIC'{",
+"input":"<!DOCTYPE a PUBLIC'{",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", "{", null, false]]},
+
+{"description":"<!DOCTYPE a PUBLIC'\\uDBC0\\uDC00",
+"input":"<!DOCTYPE a PUBLIC'\uDBC0\uDC00",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", "\uDBC0\uDC00", null, false]]},
+
+{"description":"<!DOCTYPE a PUBLIC(",
+"input":"<!DOCTYPE a PUBLIC(",
+"output":["ParseError", ["DOCTYPE", "a", null, null, false]]},
+
+{"description":"<!DOCTYPE a PUBLIC-",
+"input":"<!DOCTYPE a PUBLIC-",
+"output":["ParseError", ["DOCTYPE", "a", null, null, false]]},
+
+{"description":"<!DOCTYPE a PUBLIC/",
+"input":"<!DOCTYPE a PUBLIC/",
+"output":["ParseError", ["DOCTYPE", "a", null, null, false]]},
+
+{"description":"<!DOCTYPE a PUBLIC0",
+"input":"<!DOCTYPE a PUBLIC0",
+"output":["ParseError", ["DOCTYPE", "a", null, null, false]]},
+
+{"description":"<!DOCTYPE a PUBLIC1",
+"input":"<!DOCTYPE a PUBLIC1",
+"output":["ParseError", ["DOCTYPE", "a", null, null, false]]},
+
+{"description":"<!DOCTYPE a PUBLIC9",
+"input":"<!DOCTYPE a PUBLIC9",
+"output":["ParseError", ["DOCTYPE", "a", null, null, false]]},
+
+{"description":"<!DOCTYPE a PUBLIC<",
+"input":"<!DOCTYPE a PUBLIC<",
+"output":["ParseError", ["DOCTYPE", "a", null, null, false]]},
+
+{"description":"<!DOCTYPE a PUBLIC=",
+"input":"<!DOCTYPE a PUBLIC=",
+"output":["ParseError", ["DOCTYPE", "a", null, null, false]]},
+
+{"description":"<!DOCTYPE a PUBLIC>",
+"input":"<!DOCTYPE a PUBLIC>",
+"output":["ParseError", ["DOCTYPE", "a", null, null, false]]},
+
+{"description":"<!DOCTYPE a PUBLIC?",
+"input":"<!DOCTYPE a PUBLIC?",
+"output":["ParseError", ["DOCTYPE", "a", null, null, false]]},
+
+{"description":"<!DOCTYPE a PUBLIC@",
+"input":"<!DOCTYPE a PUBLIC@",
+"output":["ParseError", ["DOCTYPE", "a", null, null, false]]},
+
+{"description":"<!DOCTYPE a PUBLICA",
+"input":"<!DOCTYPE a PUBLICA",
+"output":["ParseError", ["DOCTYPE", "a", null, null, false]]},
+
+{"description":"<!DOCTYPE a PUBLICB",
+"input":"<!DOCTYPE a PUBLICB",
+"output":["ParseError", ["DOCTYPE", "a", null, null, false]]},
+
+{"description":"<!DOCTYPE a PUBLICY",
+"input":"<!DOCTYPE a PUBLICY",
+"output":["ParseError", ["DOCTYPE", "a", null, null, false]]},
+
+{"description":"<!DOCTYPE a PUBLICZ",
+"input":"<!DOCTYPE a PUBLICZ",
+"output":["ParseError", ["DOCTYPE", "a", null, null, false]]},
+
+{"description":"<!DOCTYPE a PUBLIC`",
+"input":"<!DOCTYPE a PUBLIC`",
+"output":["ParseError", ["DOCTYPE", "a", null, null, false]]},
+
+{"description":"<!DOCTYPE a PUBLICa",
+"input":"<!DOCTYPE a PUBLICa",
+"output":["ParseError", ["DOCTYPE", "a", null, null, false]]},
+
+{"description":"<!DOCTYPE a PUBLICb",
+"input":"<!DOCTYPE a PUBLICb",
+"output":["ParseError", ["DOCTYPE", "a", null, null, false]]},
+
+{"description":"<!DOCTYPE a PUBLICy",
+"input":"<!DOCTYPE a PUBLICy",
+"output":["ParseError", ["DOCTYPE", "a", null, null, false]]},
+
+{"description":"<!DOCTYPE a PUBLICz",
+"input":"<!DOCTYPE a PUBLICz",
+"output":["ParseError", ["DOCTYPE", "a", null, null, false]]},
+
+{"description":"<!DOCTYPE a PUBLIC{",
+"input":"<!DOCTYPE a PUBLIC{",
+"output":["ParseError", ["DOCTYPE", "a", null, null, false]]},
+
+{"description":"<!DOCTYPE a PUBLIC\\uDBC0\\uDC00",
+"input":"<!DOCTYPE a PUBLIC\uDBC0\uDC00",
+"output":["ParseError", ["DOCTYPE", "a", null, null, false]]},
+
+{"description":"<!DOCTYPE a SYSTEM",
+"input":"<!DOCTYPE a SYSTEM",
+"output":["ParseError", ["DOCTYPE", "a", null, null, false]]},
+
+{"description":"<!DOCTYPE a SYSTEM\\u0000",
+"input":"<!DOCTYPE a SYSTEM\u0000",
+"output":["ParseError", ["DOCTYPE", "a", null, null, false]]},
+
+{"description":"<!DOCTYPE a SYSTEM\\u0008",
+"input":"<!DOCTYPE a SYSTEM\u0008",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, null, false]]},
+
+{"description":"<!DOCTYPE a SYSTEM\\u0009",
+"input":"<!DOCTYPE a SYSTEM\u0009",
+"output":["ParseError", ["DOCTYPE", "a", null, null, false]]},
+
+{"description":"<!DOCTYPE a SYSTEM\\u000A",
+"input":"<!DOCTYPE a SYSTEM\u000A",
+"output":["ParseError", ["DOCTYPE", "a", null, null, false]]},
+
+{"description":"<!DOCTYPE a SYSTEM\\u000B",
+"input":"<!DOCTYPE a SYSTEM\u000B",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, null, false]]},
+
+{"description":"<!DOCTYPE a SYSTEM\\u000C",
+"input":"<!DOCTYPE a SYSTEM\u000C",
+"output":["ParseError", ["DOCTYPE", "a", null, null, false]]},
+
+{"description":"<!DOCTYPE a SYSTEM\\u000D",
+"input":"<!DOCTYPE a SYSTEM\u000D",
+"output":["ParseError", ["DOCTYPE", "a", null, null, false]]},
+
+{"description":"<!DOCTYPE a SYSTEM\\u001F",
+"input":"<!DOCTYPE a SYSTEM\u001F",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, null, false]]},
+
+{"description":"<!DOCTYPE a SYSTEM ",
+"input":"<!DOCTYPE a SYSTEM ",
+"output":["ParseError", ["DOCTYPE", "a", null, null, false]]},
+
+{"description":"<!DOCTYPE a SYSTEM!",
+"input":"<!DOCTYPE a SYSTEM!",
+"output":["ParseError", ["DOCTYPE", "a", null, null, false]]},
+
+{"description":"<!DOCTYPE a SYSTEM\"",
+"input":"<!DOCTYPE a SYSTEM\"",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, "", false]]},
+
+{"description":"<!DOCTYPE a SYSTEM\"\\u0000",
+"input":"<!DOCTYPE a SYSTEM\"\u0000",
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", null, "\uFFFD", false]]},
+
+{"description":"<!DOCTYPE a SYSTEM\"\\u0009",
+"input":"<!DOCTYPE a SYSTEM\"\u0009",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, "\u0009", false]]},
+
+{"description":"<!DOCTYPE a SYSTEM\"\\u000A",
+"input":"<!DOCTYPE a SYSTEM\"\u000A",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, "\u000A", false]]},
+
+{"description":"<!DOCTYPE a SYSTEM\"\\u000B",
+"input":"<!DOCTYPE a SYSTEM\"\u000B",
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", null, "\u000B", false]]},
+
+{"description":"<!DOCTYPE a SYSTEM\"\\u000C",
+"input":"<!DOCTYPE a SYSTEM\"\u000C",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, "\u000C", false]]},
+
+{"description":"<!DOCTYPE a SYSTEM\" ",
+"input":"<!DOCTYPE a SYSTEM\" ",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, " ", false]]},
+
+{"description":"<!DOCTYPE a SYSTEM\"!",
+"input":"<!DOCTYPE a SYSTEM\"!",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, "!", false]]},
+
+{"description":"<!DOCTYPE a SYSTEM\"\"",
+"input":"<!DOCTYPE a SYSTEM\"\"",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, "", false]]},
+
+{"description":"<!DOCTYPE a SYSTEM\"#",
+"input":"<!DOCTYPE a SYSTEM\"#",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, "#", false]]},
+
+{"description":"<!DOCTYPE a SYSTEM\"&",
+"input":"<!DOCTYPE a SYSTEM\"&",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, "&", false]]},
+
+{"description":"<!DOCTYPE a SYSTEM\"'",
+"input":"<!DOCTYPE a SYSTEM\"'",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, "'", false]]},
+
+{"description":"<!DOCTYPE a SYSTEM\"-",
+"input":"<!DOCTYPE a SYSTEM\"-",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, "-", false]]},
+
+{"description":"<!DOCTYPE a SYSTEM\"/",
+"input":"<!DOCTYPE a SYSTEM\"/",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, "/", false]]},
+
+{"description":"<!DOCTYPE a SYSTEM\"0",
+"input":"<!DOCTYPE a SYSTEM\"0",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, "0", false]]},
+
+{"description":"<!DOCTYPE a SYSTEM\"1",
+"input":"<!DOCTYPE a SYSTEM\"1",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, "1", false]]},
+
+{"description":"<!DOCTYPE a SYSTEM\"9",
+"input":"<!DOCTYPE a SYSTEM\"9",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, "9", false]]},
+
+{"description":"<!DOCTYPE a SYSTEM\"<",
+"input":"<!DOCTYPE a SYSTEM\"<",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, "<", false]]},
+
+{"description":"<!DOCTYPE a SYSTEM\"=",
+"input":"<!DOCTYPE a SYSTEM\"=",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, "=", false]]},
+
+{"description":"<!DOCTYPE a SYSTEM\">",
+"input":"<!DOCTYPE a SYSTEM\">",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, "", false]]},
+
+{"description":"<!DOCTYPE a SYSTEM\"?",
+"input":"<!DOCTYPE a SYSTEM\"?",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, "?", false]]},
+
+{"description":"<!DOCTYPE a SYSTEM\"@",
+"input":"<!DOCTYPE a SYSTEM\"@",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, "@", false]]},
+
+{"description":"<!DOCTYPE a SYSTEM\"A",
+"input":"<!DOCTYPE a SYSTEM\"A",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, "A", false]]},
+
+{"description":"<!DOCTYPE a SYSTEM\"B",
+"input":"<!DOCTYPE a SYSTEM\"B",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, "B", false]]},
+
+{"description":"<!DOCTYPE a SYSTEM\"Y",
+"input":"<!DOCTYPE a SYSTEM\"Y",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, "Y", false]]},
+
+{"description":"<!DOCTYPE a SYSTEM\"Z",
+"input":"<!DOCTYPE a SYSTEM\"Z",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, "Z", false]]},
+
+{"description":"<!DOCTYPE a SYSTEM\"`",
+"input":"<!DOCTYPE a SYSTEM\"`",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, "`", false]]},
+
+{"description":"<!DOCTYPE a SYSTEM\"a",
+"input":"<!DOCTYPE a SYSTEM\"a",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, "a", false]]},
+
+{"description":"<!DOCTYPE a SYSTEM\"b",
+"input":"<!DOCTYPE a SYSTEM\"b",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, "b", false]]},
+
+{"description":"<!DOCTYPE a SYSTEM\"y",
+"input":"<!DOCTYPE a SYSTEM\"y",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, "y", false]]},
+
+{"description":"<!DOCTYPE a SYSTEM\"z",
+"input":"<!DOCTYPE a SYSTEM\"z",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, "z", false]]},
+
+{"description":"<!DOCTYPE a SYSTEM\"{",
+"input":"<!DOCTYPE a SYSTEM\"{",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, "{", false]]},
+
+{"description":"<!DOCTYPE a SYSTEM\"\\uDBC0\\uDC00",
+"input":"<!DOCTYPE a SYSTEM\"\uDBC0\uDC00",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, "\uDBC0\uDC00", false]]},
+
+{"description":"<!DOCTYPE a SYSTEM#",
+"input":"<!DOCTYPE a SYSTEM#",
+"output":["ParseError", ["DOCTYPE", "a", null, null, false]]},
+
+{"description":"<!DOCTYPE a SYSTEM&",
+"input":"<!DOCTYPE a SYSTEM&",
+"output":["ParseError", ["DOCTYPE", "a", null, null, false]]},
+
+{"description":"<!DOCTYPE a SYSTEM'",
+"input":"<!DOCTYPE a SYSTEM'",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, "", false]]},
+
+{"description":"<!DOCTYPE a SYSTEM'\\u0000",
+"input":"<!DOCTYPE a SYSTEM'\u0000",
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", null, "\uFFFD", false]]},
+
+{"description":"<!DOCTYPE a SYSTEM'\\u0009",
+"input":"<!DOCTYPE a SYSTEM'\u0009",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, "\u0009", false]]},
+
+{"description":"<!DOCTYPE a SYSTEM'\\u000A",
+"input":"<!DOCTYPE a SYSTEM'\u000A",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, "\u000A", false]]},
+
+{"description":"<!DOCTYPE a SYSTEM'\\u000B",
+"input":"<!DOCTYPE a SYSTEM'\u000B",
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", null, "\u000B", false]]},
+
+{"description":"<!DOCTYPE a SYSTEM'\\u000C",
+"input":"<!DOCTYPE a SYSTEM'\u000C",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, "\u000C", false]]},
+
+{"description":"<!DOCTYPE a SYSTEM' ",
+"input":"<!DOCTYPE a SYSTEM' ",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, " ", false]]},
+
+{"description":"<!DOCTYPE a SYSTEM'!",
+"input":"<!DOCTYPE a SYSTEM'!",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, "!", false]]},
+
+{"description":"<!DOCTYPE a SYSTEM'\"",
+"input":"<!DOCTYPE a SYSTEM'\"",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, "\"", false]]},
+
+{"description":"<!DOCTYPE a SYSTEM'&",
+"input":"<!DOCTYPE a SYSTEM'&",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, "&", false]]},
+
+{"description":"<!DOCTYPE a SYSTEM''",
+"input":"<!DOCTYPE a SYSTEM''",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, "", false]]},
+
+{"description":"<!DOCTYPE a SYSTEM''\\u0000",
+"input":"<!DOCTYPE a SYSTEM''\u0000",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, "", true]]},
+
+{"description":"<!DOCTYPE a SYSTEM''\\u0008",
+"input":"<!DOCTYPE a SYSTEM''\u0008",
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", null, "", true]]},
+
+{"description":"<!DOCTYPE a SYSTEM''\\u0009",
+"input":"<!DOCTYPE a SYSTEM''\u0009",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, "", false]]},
+
+{"description":"<!DOCTYPE a SYSTEM''\\u000A",
+"input":"<!DOCTYPE a SYSTEM''\u000A",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, "", false]]},
+
+{"description":"<!DOCTYPE a SYSTEM''\\u000B",
+"input":"<!DOCTYPE a SYSTEM''\u000B",
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", null, "", true]]},
+
+{"description":"<!DOCTYPE a SYSTEM''\\u000C",
+"input":"<!DOCTYPE a SYSTEM''\u000C",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, "", false]]},
+
+{"description":"<!DOCTYPE a SYSTEM''\\u000D",
+"input":"<!DOCTYPE a SYSTEM''\u000D",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, "", false]]},
+
+{"description":"<!DOCTYPE a SYSTEM''\\u001F",
+"input":"<!DOCTYPE a SYSTEM''\u001F",
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", null, "", true]]},
+
+{"description":"<!DOCTYPE a SYSTEM'' ",
+"input":"<!DOCTYPE a SYSTEM'' ",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, "", false]]},
+
+{"description":"<!DOCTYPE a SYSTEM''!",
+"input":"<!DOCTYPE a SYSTEM''!",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, "", true]]},
+
+{"description":"<!DOCTYPE a SYSTEM''\"",
+"input":"<!DOCTYPE a SYSTEM''\"",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, "", true]]},
+
+{"description":"<!DOCTYPE a SYSTEM''&",
+"input":"<!DOCTYPE a SYSTEM''&",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, "", true]]},
+
+{"description":"<!DOCTYPE a SYSTEM'''",
+"input":"<!DOCTYPE a SYSTEM'''",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, "", true]]},
+
+{"description":"<!DOCTYPE a SYSTEM''-",
+"input":"<!DOCTYPE a SYSTEM''-",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, "", true]]},
+
+{"description":"<!DOCTYPE a SYSTEM''/",
+"input":"<!DOCTYPE a SYSTEM''/",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, "", true]]},
+
+{"description":"<!DOCTYPE a SYSTEM''0",
+"input":"<!DOCTYPE a SYSTEM''0",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, "", true]]},
+
+{"description":"<!DOCTYPE a SYSTEM''1",
+"input":"<!DOCTYPE a SYSTEM''1",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, "", true]]},
+
+{"description":"<!DOCTYPE a SYSTEM''9",
+"input":"<!DOCTYPE a SYSTEM''9",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, "", true]]},
+
+{"description":"<!DOCTYPE a SYSTEM''<",
+"input":"<!DOCTYPE a SYSTEM''<",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, "", true]]},
+
+{"description":"<!DOCTYPE a SYSTEM''=",
+"input":"<!DOCTYPE a SYSTEM''=",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, "", true]]},
+
+{"description":"<!DOCTYPE a SYSTEM''>",
+"input":"<!DOCTYPE a SYSTEM''>",
+"output":["ParseError", ["DOCTYPE", "a", null, "", true]]},
+
+{"description":"<!DOCTYPE a SYSTEM''?",
+"input":"<!DOCTYPE a SYSTEM''?",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, "", true]]},
+
+{"description":"<!DOCTYPE a SYSTEM''@",
+"input":"<!DOCTYPE a SYSTEM''@",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, "", true]]},
+
+{"description":"<!DOCTYPE a SYSTEM''A",
+"input":"<!DOCTYPE a SYSTEM''A",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, "", true]]},
+
+{"description":"<!DOCTYPE a SYSTEM''B",
+"input":"<!DOCTYPE a SYSTEM''B",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, "", true]]},
+
+{"description":"<!DOCTYPE a SYSTEM''Y",
+"input":"<!DOCTYPE a SYSTEM''Y",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, "", true]]},
+
+{"description":"<!DOCTYPE a SYSTEM''Z",
+"input":"<!DOCTYPE a SYSTEM''Z",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, "", true]]},
+
+{"description":"<!DOCTYPE a SYSTEM''`",
+"input":"<!DOCTYPE a SYSTEM''`",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, "", true]]},
+
+{"description":"<!DOCTYPE a SYSTEM''a",
+"input":"<!DOCTYPE a SYSTEM''a",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, "", true]]},
+
+{"description":"<!DOCTYPE a SYSTEM''b",
+"input":"<!DOCTYPE a SYSTEM''b",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, "", true]]},
+
+{"description":"<!DOCTYPE a SYSTEM''y",
+"input":"<!DOCTYPE a SYSTEM''y",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, "", true]]},
+
+{"description":"<!DOCTYPE a SYSTEM''z",
+"input":"<!DOCTYPE a SYSTEM''z",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, "", true]]},
+
+{"description":"<!DOCTYPE a SYSTEM''{",
+"input":"<!DOCTYPE a SYSTEM''{",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, "", true]]},
+
+{"description":"<!DOCTYPE a SYSTEM''\\uDBC0\\uDC00",
+"input":"<!DOCTYPE a SYSTEM''\uDBC0\uDC00",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, "", true]]},
+
+{"description":"<!DOCTYPE a SYSTEM'(",
+"input":"<!DOCTYPE a SYSTEM'(",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, "(", false]]},
+
+{"description":"<!DOCTYPE a SYSTEM'-",
+"input":"<!DOCTYPE a SYSTEM'-",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, "-", false]]},
+
+{"description":"<!DOCTYPE a SYSTEM'/",
+"input":"<!DOCTYPE a SYSTEM'/",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, "/", false]]},
+
+{"description":"<!DOCTYPE a SYSTEM'0",
+"input":"<!DOCTYPE a SYSTEM'0",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, "0", false]]},
+
+{"description":"<!DOCTYPE a SYSTEM'1",
+"input":"<!DOCTYPE a SYSTEM'1",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, "1", false]]},
+
+{"description":"<!DOCTYPE a SYSTEM'9",
+"input":"<!DOCTYPE a SYSTEM'9",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, "9", false]]},
+
+{"description":"<!DOCTYPE a SYSTEM'<",
+"input":"<!DOCTYPE a SYSTEM'<",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, "<", false]]},
+
+{"description":"<!DOCTYPE a SYSTEM'=",
+"input":"<!DOCTYPE a SYSTEM'=",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, "=", false]]},
+
+{"description":"<!DOCTYPE a SYSTEM'>",
+"input":"<!DOCTYPE a SYSTEM'>",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, "", false]]},
+
+{"description":"<!DOCTYPE a SYSTEM'?",
+"input":"<!DOCTYPE a SYSTEM'?",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, "?", false]]},
+
+{"description":"<!DOCTYPE a SYSTEM'@",
+"input":"<!DOCTYPE a SYSTEM'@",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, "@", false]]},
+
+{"description":"<!DOCTYPE a SYSTEM'A",
+"input":"<!DOCTYPE a SYSTEM'A",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, "A", false]]},
+
+{"description":"<!DOCTYPE a SYSTEM'B",
+"input":"<!DOCTYPE a SYSTEM'B",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, "B", false]]},
+
+{"description":"<!DOCTYPE a SYSTEM'Y",
+"input":"<!DOCTYPE a SYSTEM'Y",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, "Y", false]]},
+
+{"description":"<!DOCTYPE a SYSTEM'Z",
+"input":"<!DOCTYPE a SYSTEM'Z",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, "Z", false]]},
+
+{"description":"<!DOCTYPE a SYSTEM'`",
+"input":"<!DOCTYPE a SYSTEM'`",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, "`", false]]},
+
+{"description":"<!DOCTYPE a SYSTEM'a",
+"input":"<!DOCTYPE a SYSTEM'a",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, "a", false]]},
+
+{"description":"<!DOCTYPE a SYSTEM'b",
+"input":"<!DOCTYPE a SYSTEM'b",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, "b", false]]},
+
+{"description":"<!DOCTYPE a SYSTEM'y",
+"input":"<!DOCTYPE a SYSTEM'y",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, "y", false]]},
+
+{"description":"<!DOCTYPE a SYSTEM'z",
+"input":"<!DOCTYPE a SYSTEM'z",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, "z", false]]},
+
+{"description":"<!DOCTYPE a SYSTEM'{",
+"input":"<!DOCTYPE a SYSTEM'{",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, "{", false]]},
+
+{"description":"<!DOCTYPE a SYSTEM'\\uDBC0\\uDC00",
+"input":"<!DOCTYPE a SYSTEM'\uDBC0\uDC00",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, "\uDBC0\uDC00", false]]},
+
+{"description":"<!DOCTYPE a SYSTEM(",
+"input":"<!DOCTYPE a SYSTEM(",
+"output":["ParseError", ["DOCTYPE", "a", null, null, false]]},
+
+{"description":"<!DOCTYPE a SYSTEM-",
+"input":"<!DOCTYPE a SYSTEM-",
+"output":["ParseError", ["DOCTYPE", "a", null, null, false]]},
+
+{"description":"<!DOCTYPE a SYSTEM/",
+"input":"<!DOCTYPE a SYSTEM/",
+"output":["ParseError", ["DOCTYPE", "a", null, null, false]]},
+
+{"description":"<!DOCTYPE a SYSTEM0",
+"input":"<!DOCTYPE a SYSTEM0",
+"output":["ParseError", ["DOCTYPE", "a", null, null, false]]},
+
+{"description":"<!DOCTYPE a SYSTEM1",
+"input":"<!DOCTYPE a SYSTEM1",
+"output":["ParseError", ["DOCTYPE", "a", null, null, false]]},
+
+{"description":"<!DOCTYPE a SYSTEM9",
+"input":"<!DOCTYPE a SYSTEM9",
+"output":["ParseError", ["DOCTYPE", "a", null, null, false]]},
+
+{"description":"<!DOCTYPE a SYSTEM<",
+"input":"<!DOCTYPE a SYSTEM<",
+"output":["ParseError", ["DOCTYPE", "a", null, null, false]]},
+
+{"description":"<!DOCTYPE a SYSTEM=",
+"input":"<!DOCTYPE a SYSTEM=",
+"output":["ParseError", ["DOCTYPE", "a", null, null, false]]},
+
+{"description":"<!DOCTYPE a SYSTEM>",
+"input":"<!DOCTYPE a SYSTEM>",
+"output":["ParseError", ["DOCTYPE", "a", null, null, false]]},
+
+{"description":"<!DOCTYPE a SYSTEM?",
+"input":"<!DOCTYPE a SYSTEM?",
+"output":["ParseError", ["DOCTYPE", "a", null, null, false]]},
+
+{"description":"<!DOCTYPE a SYSTEM@",
+"input":"<!DOCTYPE a SYSTEM@",
+"output":["ParseError", ["DOCTYPE", "a", null, null, false]]},
+
+{"description":"<!DOCTYPE a SYSTEMA",
+"input":"<!DOCTYPE a SYSTEMA",
+"output":["ParseError", ["DOCTYPE", "a", null, null, false]]},
+
+{"description":"<!DOCTYPE a SYSTEMB",
+"input":"<!DOCTYPE a SYSTEMB",
+"output":["ParseError", ["DOCTYPE", "a", null, null, false]]},
+
+{"description":"<!DOCTYPE a SYSTEMY",
+"input":"<!DOCTYPE a SYSTEMY",
+"output":["ParseError", ["DOCTYPE", "a", null, null, false]]},
+
+{"description":"<!DOCTYPE a SYSTEMZ",
+"input":"<!DOCTYPE a SYSTEMZ",
+"output":["ParseError", ["DOCTYPE", "a", null, null, false]]},
+
+{"description":"<!DOCTYPE a SYSTEM`",
+"input":"<!DOCTYPE a SYSTEM`",
+"output":["ParseError", ["DOCTYPE", "a", null, null, false]]},
+
+{"description":"<!DOCTYPE a SYSTEMa",
+"input":"<!DOCTYPE a SYSTEMa",
+"output":["ParseError", ["DOCTYPE", "a", null, null, false]]},
+
+{"description":"<!DOCTYPE a SYSTEMb",
+"input":"<!DOCTYPE a SYSTEMb",
+"output":["ParseError", ["DOCTYPE", "a", null, null, false]]},
+
+{"description":"<!DOCTYPE a SYSTEMy",
+"input":"<!DOCTYPE a SYSTEMy",
+"output":["ParseError", ["DOCTYPE", "a", null, null, false]]},
+
+{"description":"<!DOCTYPE a SYSTEMz",
+"input":"<!DOCTYPE a SYSTEMz",
+"output":["ParseError", ["DOCTYPE", "a", null, null, false]]},
+
+{"description":"<!DOCTYPE a SYSTEM{",
+"input":"<!DOCTYPE a SYSTEM{",
+"output":["ParseError", ["DOCTYPE", "a", null, null, false]]},
+
+{"description":"<!DOCTYPE a SYSTEM\\uDBC0\\uDC00",
+"input":"<!DOCTYPE a SYSTEM\uDBC0\uDC00",
+"output":["ParseError", ["DOCTYPE", "a", null, null, false]]},
+
+{"description":"<!DOCTYPE a Y",
+"input":"<!DOCTYPE a Y",
+"output":["ParseError", ["DOCTYPE", "a", null, null, false]]},
+
+{"description":"<!DOCTYPE a Z",
+"input":"<!DOCTYPE a Z",
+"output":["ParseError", ["DOCTYPE", "a", null, null, false]]},
+
+{"description":"<!DOCTYPE a `",
+"input":"<!DOCTYPE a `",
+"output":["ParseError", ["DOCTYPE", "a", null, null, false]]},
+
+{"description":"<!DOCTYPE a a",
+"input":"<!DOCTYPE a a",
+"output":["ParseError", ["DOCTYPE", "a", null, null, false]]},
+
+{"description":"<!DOCTYPE a a\\u0000",
+"input":"<!DOCTYPE a a\u0000",
+"output":["ParseError", ["DOCTYPE", "a", null, null, false]]},
+
+{"description":"<!DOCTYPE a a\\u0009",
+"input":"<!DOCTYPE a a\u0009",
+"output":["ParseError", ["DOCTYPE", "a", null, null, false]]},
+
+{"description":"<!DOCTYPE a a\\u000A",
+"input":"<!DOCTYPE a a\u000A",
+"output":["ParseError", ["DOCTYPE", "a", null, null, false]]},
+
+{"description":"<!DOCTYPE a a\\u000B",
+"input":"<!DOCTYPE a a\u000B",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, null, false]]},
+
+{"description":"<!DOCTYPE a a\\u000C",
+"input":"<!DOCTYPE a a\u000C",
+"output":["ParseError", ["DOCTYPE", "a", null, null, false]]},
+
+{"description":"<!DOCTYPE a a ",
+"input":"<!DOCTYPE a a ",
+"output":["ParseError", ["DOCTYPE", "a", null, null, false]]},
+
+{"description":"<!DOCTYPE a a!",
+"input":"<!DOCTYPE a a!",
+"output":["ParseError", ["DOCTYPE", "a", null, null, false]]},
+
+{"description":"<!DOCTYPE a a\"",
+"input":"<!DOCTYPE a a\"",
+"output":["ParseError", ["DOCTYPE", "a", null, null, false]]},
+
+{"description":"<!DOCTYPE a a&",
+"input":"<!DOCTYPE a a&",
+"output":["ParseError", ["DOCTYPE", "a", null, null, false]]},
+
+{"description":"<!DOCTYPE a a'",
+"input":"<!DOCTYPE a a'",
+"output":["ParseError", ["DOCTYPE", "a", null, null, false]]},
+
+{"description":"<!DOCTYPE a a-",
+"input":"<!DOCTYPE a a-",
+"output":["ParseError", ["DOCTYPE", "a", null, null, false]]},
+
+{"description":"<!DOCTYPE a a/",
+"input":"<!DOCTYPE a a/",
+"output":["ParseError", ["DOCTYPE", "a", null, null, false]]},
+
+{"description":"<!DOCTYPE a a0",
+"input":"<!DOCTYPE a a0",
+"output":["ParseError", ["DOCTYPE", "a", null, null, false]]},
+
+{"description":"<!DOCTYPE a a1",
+"input":"<!DOCTYPE a a1",
+"output":["ParseError", ["DOCTYPE", "a", null, null, false]]},
+
+{"description":"<!DOCTYPE a a9",
+"input":"<!DOCTYPE a a9",
+"output":["ParseError", ["DOCTYPE", "a", null, null, false]]},
+
+{"description":"<!DOCTYPE a a<",
+"input":"<!DOCTYPE a a<",
+"output":["ParseError", ["DOCTYPE", "a", null, null, false]]},
+
+{"description":"<!DOCTYPE a a=",
+"input":"<!DOCTYPE a a=",
+"output":["ParseError", ["DOCTYPE", "a", null, null, false]]},
+
+{"description":"<!DOCTYPE a a>",
+"input":"<!DOCTYPE a a>",
+"output":["ParseError", ["DOCTYPE", "a", null, null, false]]},
+
+{"description":"<!DOCTYPE a a?",
+"input":"<!DOCTYPE a a?",
+"output":["ParseError", ["DOCTYPE", "a", null, null, false]]},
+
+{"description":"<!DOCTYPE a a@",
+"input":"<!DOCTYPE a a@",
+"output":["ParseError", ["DOCTYPE", "a", null, null, false]]},
+
+{"description":"<!DOCTYPE a aA",
+"input":"<!DOCTYPE a aA",
+"output":["ParseError", ["DOCTYPE", "a", null, null, false]]},
+
+{"description":"<!DOCTYPE a aB",
+"input":"<!DOCTYPE a aB",
+"output":["ParseError", ["DOCTYPE", "a", null, null, false]]},
+
+{"description":"<!DOCTYPE a aY",
+"input":"<!DOCTYPE a aY",
+"output":["ParseError", ["DOCTYPE", "a", null, null, false]]},
+
+{"description":"<!DOCTYPE a aZ",
+"input":"<!DOCTYPE a aZ",
+"output":["ParseError", ["DOCTYPE", "a", null, null, false]]},
+
+{"description":"<!DOCTYPE a a`",
+"input":"<!DOCTYPE a a`",
+"output":["ParseError", ["DOCTYPE", "a", null, null, false]]},
+
+{"description":"<!DOCTYPE a aa",
+"input":"<!DOCTYPE a aa",
+"output":["ParseError", ["DOCTYPE", "a", null, null, false]]},
+
+{"description":"<!DOCTYPE a ab",
+"input":"<!DOCTYPE a ab",
+"output":["ParseError", ["DOCTYPE", "a", null, null, false]]},
+
+{"description":"<!DOCTYPE a ay",
+"input":"<!DOCTYPE a ay",
+"output":["ParseError", ["DOCTYPE", "a", null, null, false]]},
+
+{"description":"<!DOCTYPE a az",
+"input":"<!DOCTYPE a az",
+"output":["ParseError", ["DOCTYPE", "a", null, null, false]]},
+
+{"description":"<!DOCTYPE a a{",
+"input":"<!DOCTYPE a a{",
+"output":["ParseError", ["DOCTYPE", "a", null, null, false]]},
+
+{"description":"<!DOCTYPE a a\\uDBC0\\uDC00",
+"input":"<!DOCTYPE a a\uDBC0\uDC00",
+"output":["ParseError", ["DOCTYPE", "a", null, null, false]]},
+
+{"description":"<!DOCTYPE a b",
+"input":"<!DOCTYPE a b",
+"output":["ParseError", ["DOCTYPE", "a", null, null, false]]},
+
+{"description":"<!DOCTYPE a y",
+"input":"<!DOCTYPE a y",
+"output":["ParseError", ["DOCTYPE", "a", null, null, false]]},
+
+{"description":"<!DOCTYPE a z",
+"input":"<!DOCTYPE a z",
+"output":["ParseError", ["DOCTYPE", "a", null, null, false]]},
+
+{"description":"<!DOCTYPE a {",
+"input":"<!DOCTYPE a {",
+"output":["ParseError", ["DOCTYPE", "a", null, null, false]]},
+
+{"description":"<!DOCTYPE a \\uDBC0\\uDC00",
+"input":"<!DOCTYPE a \uDBC0\uDC00",
+"output":["ParseError", ["DOCTYPE", "a", null, null, false]]},
+
+{"description":"<!DOCTYPE a!",
+"input":"<!DOCTYPE a!",
+"output":["ParseError", ["DOCTYPE", "a!", null, null, false]]},
+
+{"description":"<!DOCTYPE a\"",
+"input":"<!DOCTYPE a\"",
+"output":["ParseError", ["DOCTYPE", "a\"", null, null, false]]},
+
+{"description":"<!DOCTYPE a&",
+"input":"<!DOCTYPE a&",
+"output":["ParseError", ["DOCTYPE", "a&", null, null, false]]},
+
+{"description":"<!DOCTYPE a'",
+"input":"<!DOCTYPE a'",
+"output":["ParseError", ["DOCTYPE", "a'", null, null, false]]},
+
+{"description":"<!DOCTYPE a-",
+"input":"<!DOCTYPE a-",
+"output":["ParseError", ["DOCTYPE", "a-", null, null, false]]},
+
+{"description":"<!DOCTYPE a/",
+"input":"<!DOCTYPE a/",
+"output":["ParseError", ["DOCTYPE", "a/", null, null, false]]},
+
+{"description":"<!DOCTYPE a0",
+"input":"<!DOCTYPE a0",
+"output":["ParseError", ["DOCTYPE", "a0", null, null, false]]},
+
+{"description":"<!DOCTYPE a1",
+"input":"<!DOCTYPE a1",
+"output":["ParseError", ["DOCTYPE", "a1", null, null, false]]},
+
+{"description":"<!DOCTYPE a9",
+"input":"<!DOCTYPE a9",
+"output":["ParseError", ["DOCTYPE", "a9", null, null, false]]},
+
+{"description":"<!DOCTYPE a<",
+"input":"<!DOCTYPE a<",
+"output":["ParseError", ["DOCTYPE", "a<", null, null, false]]},
+
+{"description":"<!DOCTYPE a=",
+"input":"<!DOCTYPE a=",
+"output":["ParseError", ["DOCTYPE", "a=", null, null, false]]},
+
+{"description":"<!DOCTYPE a>",
+"input":"<!DOCTYPE a>",
+"output":[["DOCTYPE", "a", null, null, true]]},
+
+{"description":"<!DOCTYPE a?",
+"input":"<!DOCTYPE a?",
+"output":["ParseError", ["DOCTYPE", "a?", null, null, false]]},
+
+{"description":"<!DOCTYPE a@",
+"input":"<!DOCTYPE a@",
+"output":["ParseError", ["DOCTYPE", "a@", null, null, false]]},
+
+{"description":"<!DOCTYPE aA",
+"input":"<!DOCTYPE aA",
+"output":["ParseError", ["DOCTYPE", "aa", null, null, false]]},
+
+{"description":"<!DOCTYPE aB",
+"input":"<!DOCTYPE aB",
+"output":["ParseError", ["DOCTYPE", "ab", null, null, false]]},
+
+{"description":"<!DOCTYPE aY",
+"input":"<!DOCTYPE aY",
+"output":["ParseError", ["DOCTYPE", "ay", null, null, false]]},
+
+{"description":"<!DOCTYPE aZ",
+"input":"<!DOCTYPE aZ",
+"output":["ParseError", ["DOCTYPE", "az", null, null, false]]},
+
+{"description":"<!DOCTYPE a[",
+"input":"<!DOCTYPE a[",
+"output":["ParseError", ["DOCTYPE", "a[", null, null, false]]},
+
+{"description":"<!DOCTYPE a`",
+"input":"<!DOCTYPE a`",
+"output":["ParseError", ["DOCTYPE", "a`", null, null, false]]},
+
+{"description":"<!DOCTYPE aa",
+"input":"<!DOCTYPE aa",
+"output":["ParseError", ["DOCTYPE", "aa", null, null, false]]},
+
+{"description":"<!DOCTYPE ab",
+"input":"<!DOCTYPE ab",
+"output":["ParseError", ["DOCTYPE", "ab", null, null, false]]},
+
+{"description":"<!DOCTYPE ay",
+"input":"<!DOCTYPE ay",
+"output":["ParseError", ["DOCTYPE", "ay", null, null, false]]},
+
+{"description":"<!DOCTYPE az",
+"input":"<!DOCTYPE az",
+"output":["ParseError", ["DOCTYPE", "az", null, null, false]]},
+
+{"description":"<!DOCTYPE a{",
+"input":"<!DOCTYPE a{",
+"output":["ParseError", ["DOCTYPE", "a{", null, null, false]]},
+
+{"description":"<!DOCTYPE a\\uDBC0\\uDC00",
+"input":"<!DOCTYPE a\uDBC0\uDC00",
+"output":["ParseError", ["DOCTYPE", "a\uDBC0\uDC00", null, null, false]]},
+
+{"description":"<!DOCTYPE b",
+"input":"<!DOCTYPE b",
+"output":["ParseError", ["DOCTYPE", "b", null, null, false]]},
+
+{"description":"<!DOCTYPE y",
+"input":"<!DOCTYPE y",
+"output":["ParseError", ["DOCTYPE", "y", null, null, false]]},
+
+{"description":"<!DOCTYPE z",
+"input":"<!DOCTYPE z",
+"output":["ParseError", ["DOCTYPE", "z", null, null, false]]},
+
+{"description":"<!DOCTYPE {",
+"input":"<!DOCTYPE {",
+"output":["ParseError", ["DOCTYPE", "{", null, null, false]]},
+
+{"description":"<!DOCTYPE \\uDBC0\\uDC00",
+"input":"<!DOCTYPE \uDBC0\uDC00",
+"output":["ParseError", ["DOCTYPE", "\uDBC0\uDC00", null, null, false]]},
+
+{"description":"<!DOCTYPE!",
+"input":"<!DOCTYPE!",
+"output":["ParseError", "ParseError", ["DOCTYPE", "!", null, null, false]]},
+
+{"description":"<!DOCTYPE\"",
+"input":"<!DOCTYPE\"",
+"output":["ParseError", "ParseError", ["DOCTYPE", "\"", null, null, false]]},
+
+{"description":"<!DOCTYPE&",
+"input":"<!DOCTYPE&",
+"output":["ParseError", "ParseError", ["DOCTYPE", "&", null, null, false]]},
+
+{"description":"<!DOCTYPE'",
+"input":"<!DOCTYPE'",
+"output":["ParseError", "ParseError", ["DOCTYPE", "'", null, null, false]]},
+
+{"description":"<!DOCTYPE-",
+"input":"<!DOCTYPE-",
+"output":["ParseError", "ParseError", ["DOCTYPE", "-", null, null, false]]},
+
+{"description":"<!DOCTYPE/",
+"input":"<!DOCTYPE/",
+"output":["ParseError", "ParseError", ["DOCTYPE", "/", null, null, false]]},
+
+{"description":"<!DOCTYPE0",
+"input":"<!DOCTYPE0",
+"output":["ParseError", "ParseError", ["DOCTYPE", "0", null, null, false]]},
+
+{"description":"<!DOCTYPE1",
+"input":"<!DOCTYPE1",
+"output":["ParseError", "ParseError", ["DOCTYPE", "1", null, null, false]]},
+
+{"description":"<!DOCTYPE9",
+"input":"<!DOCTYPE9",
+"output":["ParseError", "ParseError", ["DOCTYPE", "9", null, null, false]]},
+
+{"description":"<!DOCTYPE<",
+"input":"<!DOCTYPE<",
+"output":["ParseError", "ParseError", ["DOCTYPE", "<", null, null, false]]},
+
+{"description":"<!DOCTYPE=",
+"input":"<!DOCTYPE=",
+"output":["ParseError", "ParseError", ["DOCTYPE", "=", null, null, false]]},
+
+{"description":"<!DOCTYPE>",
+"input":"<!DOCTYPE>",
+"output":["ParseError", "ParseError", ["DOCTYPE", "", null, null, false]]},
+
+{"description":"<!DOCTYPE?",
+"input":"<!DOCTYPE?",
+"output":["ParseError", "ParseError", ["DOCTYPE", "?", null, null, false]]},
+
+{"description":"<!DOCTYPE@",
+"input":"<!DOCTYPE@",
+"output":["ParseError", "ParseError", ["DOCTYPE", "@", null, null, false]]},
+
+{"description":"<!DOCTYPEA",
+"input":"<!DOCTYPEA",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, null, false]]},
+
+{"description":"<!DOCTYPEB",
+"input":"<!DOCTYPEB",
+"output":["ParseError", "ParseError", ["DOCTYPE", "b", null, null, false]]},
+
+{"description":"<!DOCTYPEY",
+"input":"<!DOCTYPEY",
+"output":["ParseError", "ParseError", ["DOCTYPE", "y", null, null, false]]},
+
+{"description":"<!DOCTYPEZ",
+"input":"<!DOCTYPEZ",
+"output":["ParseError", "ParseError", ["DOCTYPE", "z", null, null, false]]},
+
+{"description":"<!DOCTYPE`",
+"input":"<!DOCTYPE`",
+"output":["ParseError", "ParseError", ["DOCTYPE", "`", null, null, false]]},
+
+{"description":"<!DOCTYPEa",
+"input":"<!DOCTYPEa",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, null, false]]},
+
+{"description":"<!DOCTYPEa\\u0000",
+"input":"<!DOCTYPEa\u0000",
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a\uFFFD", null, null, false]]},
+
+{"description":"<!DOCTYPEa\\u0008",
+"input":"<!DOCTYPEa\u0008",
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a\u0008", null, null, false]]},
+
+{"description":"<!DOCTYPEa\\u0009",
+"input":"<!DOCTYPEa\u0009",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, null, false]]},
+
+{"description":"<!DOCTYPEa\\u000A",
+"input":"<!DOCTYPEa\u000A",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, null, false]]},
+
+{"description":"<!DOCTYPEa\\u000B",
+"input":"<!DOCTYPEa\u000B",
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a\u000B", null, null, false]]},
+
+{"description":"<!DOCTYPEa\\u000C",
+"input":"<!DOCTYPEa\u000C",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, null, false]]},
+
+{"description":"<!DOCTYPEa\\u000D",
+"input":"<!DOCTYPEa\u000D",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, null, false]]},
+
+{"description":"<!DOCTYPEa\\u001F",
+"input":"<!DOCTYPEa\u001F",
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a\u001F", null, null, false]]},
+
+{"description":"<!DOCTYPEa ",
+"input":"<!DOCTYPEa ",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, null, false]]},
+
+{"description":"<!DOCTYPEa \\u0000",
+"input":"<!DOCTYPEa \u0000",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, null, false]]},
+
+{"description":"<!DOCTYPEa \\u0008",
+"input":"<!DOCTYPEa \u0008",
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", null, null, false]]},
+
+{"description":"<!DOCTYPEa \\u0009",
+"input":"<!DOCTYPEa \u0009",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, null, false]]},
+
+{"description":"<!DOCTYPEa \\u000A",
+"input":"<!DOCTYPEa \u000A",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, null, false]]},
+
+{"description":"<!DOCTYPEa \\u000B",
+"input":"<!DOCTYPEa \u000B",
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", null, null, false]]},
+
+{"description":"<!DOCTYPEa \\u000C",
+"input":"<!DOCTYPEa \u000C",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, null, false]]},
+
+{"description":"<!DOCTYPEa \\u000D",
+"input":"<!DOCTYPEa \u000D",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, null, false]]},
+
+{"description":"<!DOCTYPEa \\u001F",
+"input":"<!DOCTYPEa \u001F",
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", null, null, false]]},
+
+{"description":"<!DOCTYPEa  ",
+"input":"<!DOCTYPEa  ",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, null, false]]},
+
+{"description":"<!DOCTYPEa !",
+"input":"<!DOCTYPEa !",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, null, false]]},
+
+{"description":"<!DOCTYPEa \"",
+"input":"<!DOCTYPEa \"",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, null, false]]},
+
+{"description":"<!DOCTYPEa &",
+"input":"<!DOCTYPEa &",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, null, false]]},
+
+{"description":"<!DOCTYPEa '",
+"input":"<!DOCTYPEa '",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, null, false]]},
+
+{"description":"<!DOCTYPEa -",
+"input":"<!DOCTYPEa -",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, null, false]]},
+
+{"description":"<!DOCTYPEa /",
+"input":"<!DOCTYPEa /",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, null, false]]},
+
+{"description":"<!DOCTYPEa 0",
+"input":"<!DOCTYPEa 0",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, null, false]]},
+
+{"description":"<!DOCTYPEa 1",
+"input":"<!DOCTYPEa 1",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, null, false]]},
+
+{"description":"<!DOCTYPEa 9",
+"input":"<!DOCTYPEa 9",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, null, false]]},
+
+{"description":"<!DOCTYPEa <",
+"input":"<!DOCTYPEa <",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, null, false]]},
+
+{"description":"<!DOCTYPEa =",
+"input":"<!DOCTYPEa =",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, null, false]]},
+
+{"description":"<!DOCTYPEa >",
+"input":"<!DOCTYPEa >",
+"output":["ParseError", ["DOCTYPE", "a", null, null, true]]},
+
+{"description":"<!DOCTYPEa ?",
+"input":"<!DOCTYPEa ?",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, null, false]]},
+
+{"description":"<!DOCTYPEa @",
+"input":"<!DOCTYPEa @",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, null, false]]},
+
+{"description":"<!DOCTYPEa A",
+"input":"<!DOCTYPEa A",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, null, false]]},
+
+{"description":"<!DOCTYPEa B",
+"input":"<!DOCTYPEa B",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, null, false]]},
+
+{"description":"<!DOCTYPEa PUBLIC",
+"input":"<!DOCTYPEa PUBLIC",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, null, false]]},
+
+{"description":"<!DOCTYPEa PUBLIC\\u0000",
+"input":"<!DOCTYPEa PUBLIC\u0000",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, null, false]]},
+
+{"description":"<!DOCTYPEa PUBLIC\\u0008",
+"input":"<!DOCTYPEa PUBLIC\u0008",
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", null, null, false]]},
+
+{"description":"<!DOCTYPEa PUBLIC\\u0009",
+"input":"<!DOCTYPEa PUBLIC\u0009",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, null, false]]},
+
+{"description":"<!DOCTYPEa PUBLIC\\u000A",
+"input":"<!DOCTYPEa PUBLIC\u000A",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, null, false]]},
+
+{"description":"<!DOCTYPEa PUBLIC\\u000B",
+"input":"<!DOCTYPEa PUBLIC\u000B",
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", null, null, false]]},
+
+{"description":"<!DOCTYPEa PUBLIC\\u000C",
+"input":"<!DOCTYPEa PUBLIC\u000C",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, null, false]]},
+
+{"description":"<!DOCTYPEa PUBLIC\\u000D",
+"input":"<!DOCTYPEa PUBLIC\u000D",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, null, false]]},
+
+{"description":"<!DOCTYPEa PUBLIC\\u001F",
+"input":"<!DOCTYPEa PUBLIC\u001F",
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", null, null, false]]},
+
+{"description":"<!DOCTYPEa PUBLIC ",
+"input":"<!DOCTYPEa PUBLIC ",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, null, false]]},
+
+{"description":"<!DOCTYPEa PUBLIC!",
+"input":"<!DOCTYPEa PUBLIC!",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, null, false]]},
+
+{"description":"<!DOCTYPEa PUBLIC\"",
+"input":"<!DOCTYPEa PUBLIC\"",
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", "", null, false]]},
+
+{"description":"<!DOCTYPEa PUBLIC\"\\u0000",
+"input":"<!DOCTYPEa PUBLIC\"\u0000",
+"output":["ParseError", "ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", "\uFFFD", null, false]]},
+
+{"description":"<!DOCTYPEa PUBLIC\"\\u0009",
+"input":"<!DOCTYPEa PUBLIC\"\u0009",
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", "\u0009", null, false]]},
+
+{"description":"<!DOCTYPEa PUBLIC\"\\u000A",
+"input":"<!DOCTYPEa PUBLIC\"\u000A",
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", "\u000A", null, false]]},
+
+{"description":"<!DOCTYPEa PUBLIC\"\\u000B",
+"input":"<!DOCTYPEa PUBLIC\"\u000B",
+"output":["ParseError", "ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", "\u000B", null, false]]},
+
+{"description":"<!DOCTYPEa PUBLIC\"\\u000C",
+"input":"<!DOCTYPEa PUBLIC\"\u000C",
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", "\u000C", null, false]]},
+
+{"description":"<!DOCTYPEa PUBLIC\" ",
+"input":"<!DOCTYPEa PUBLIC\" ",
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", " ", null, false]]},
+
+{"description":"<!DOCTYPEa PUBLIC\"!",
+"input":"<!DOCTYPEa PUBLIC\"!",
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", "!", null, false]]},
+
+{"description":"<!DOCTYPEa PUBLIC\"\"",
+"input":"<!DOCTYPEa PUBLIC\"\"",
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", "", null, false]]},
+
+{"description":"<!DOCTYPEa PUBLIC\"#",
+"input":"<!DOCTYPEa PUBLIC\"#",
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", "#", null, false]]},
+
+{"description":"<!DOCTYPEa PUBLIC\"&",
+"input":"<!DOCTYPEa PUBLIC\"&",
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", "&", null, false]]},
+
+{"description":"<!DOCTYPEa PUBLIC\"'",
+"input":"<!DOCTYPEa PUBLIC\"'",
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", "'", null, false]]},
+
+{"description":"<!DOCTYPEa PUBLIC\"-",
+"input":"<!DOCTYPEa PUBLIC\"-",
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", "-", null, false]]},
+
+{"description":"<!DOCTYPEa PUBLIC\"/",
+"input":"<!DOCTYPEa PUBLIC\"/",
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", "/", null, false]]},
+
+{"description":"<!DOCTYPEa PUBLIC\"0",
+"input":"<!DOCTYPEa PUBLIC\"0",
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", "0", null, false]]},
+
+{"description":"<!DOCTYPEa PUBLIC\"1",
+"input":"<!DOCTYPEa PUBLIC\"1",
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", "1", null, false]]},
+
+{"description":"<!DOCTYPEa PUBLIC\"9",
+"input":"<!DOCTYPEa PUBLIC\"9",
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", "9", null, false]]},
+
+{"description":"<!DOCTYPEa PUBLIC\"<",
+"input":"<!DOCTYPEa PUBLIC\"<",
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", "<", null, false]]},
+
+{"description":"<!DOCTYPEa PUBLIC\"=",
+"input":"<!DOCTYPEa PUBLIC\"=",
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", "=", null, false]]},
+
+{"description":"<!DOCTYPEa PUBLIC\">",
+"input":"<!DOCTYPEa PUBLIC\">",
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", "", null, false]]},
+
+{"description":"<!DOCTYPEa PUBLIC\"?",
+"input":"<!DOCTYPEa PUBLIC\"?",
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", "?", null, false]]},
+
+{"description":"<!DOCTYPEa PUBLIC\"@",
+"input":"<!DOCTYPEa PUBLIC\"@",
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", "@", null, false]]},
+
+{"description":"<!DOCTYPEa PUBLIC\"A",
+"input":"<!DOCTYPEa PUBLIC\"A",
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", "A", null, false]]},
+
+{"description":"<!DOCTYPEa PUBLIC\"B",
+"input":"<!DOCTYPEa PUBLIC\"B",
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", "B", null, false]]},
+
+{"description":"<!DOCTYPEa PUBLIC\"Y",
+"input":"<!DOCTYPEa PUBLIC\"Y",
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", "Y", null, false]]},
+
+{"description":"<!DOCTYPEa PUBLIC\"Z",
+"input":"<!DOCTYPEa PUBLIC\"Z",
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", "Z", null, false]]},
+
+{"description":"<!DOCTYPEa PUBLIC\"`",
+"input":"<!DOCTYPEa PUBLIC\"`",
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", "`", null, false]]},
+
+{"description":"<!DOCTYPEa PUBLIC\"a",
+"input":"<!DOCTYPEa PUBLIC\"a",
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", "a", null, false]]},
+
+{"description":"<!DOCTYPEa PUBLIC\"b",
+"input":"<!DOCTYPEa PUBLIC\"b",
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", "b", null, false]]},
+
+{"description":"<!DOCTYPEa PUBLIC\"y",
+"input":"<!DOCTYPEa PUBLIC\"y",
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", "y", null, false]]},
+
+{"description":"<!DOCTYPEa PUBLIC\"z",
+"input":"<!DOCTYPEa PUBLIC\"z",
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", "z", null, false]]},
+
+{"description":"<!DOCTYPEa PUBLIC\"{",
+"input":"<!DOCTYPEa PUBLIC\"{",
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", "{", null, false]]},
+
+{"description":"<!DOCTYPEa PUBLIC\"\\uDBC0\\uDC00",
+"input":"<!DOCTYPEa PUBLIC\"\uDBC0\uDC00",
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", "\uDBC0\uDC00", null, false]]},
+
+{"description":"<!DOCTYPEa PUBLIC#",
+"input":"<!DOCTYPEa PUBLIC#",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, null, false]]},
+
+{"description":"<!DOCTYPEa PUBLIC&",
+"input":"<!DOCTYPEa PUBLIC&",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, null, false]]},
+
+{"description":"<!DOCTYPEa PUBLIC'",
+"input":"<!DOCTYPEa PUBLIC'",
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", "", null, false]]},
+
+{"description":"<!DOCTYPEa PUBLIC'\\u0000",
+"input":"<!DOCTYPEa PUBLIC'\u0000",
+"output":["ParseError", "ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", "\uFFFD", null, false]]},
+
+{"description":"<!DOCTYPEa PUBLIC'\\u0009",
+"input":"<!DOCTYPEa PUBLIC'\u0009",
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", "\u0009", null, false]]},
+
+{"description":"<!DOCTYPEa PUBLIC'\\u000A",
+"input":"<!DOCTYPEa PUBLIC'\u000A",
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", "\u000A", null, false]]},
+
+{"description":"<!DOCTYPEa PUBLIC'\\u000B",
+"input":"<!DOCTYPEa PUBLIC'\u000B",
+"output":["ParseError", "ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", "\u000B", null, false]]},
+
+{"description":"<!DOCTYPEa PUBLIC'\\u000C",
+"input":"<!DOCTYPEa PUBLIC'\u000C",
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", "\u000C", null, false]]},
+
+{"description":"<!DOCTYPEa PUBLIC' ",
+"input":"<!DOCTYPEa PUBLIC' ",
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", " ", null, false]]},
+
+{"description":"<!DOCTYPEa PUBLIC'!",
+"input":"<!DOCTYPEa PUBLIC'!",
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", "!", null, false]]},
+
+{"description":"<!DOCTYPEa PUBLIC'\"",
+"input":"<!DOCTYPEa PUBLIC'\"",
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", "\"", null, false]]},
+
+{"description":"<!DOCTYPEa PUBLIC'&",
+"input":"<!DOCTYPEa PUBLIC'&",
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", "&", null, false]]},
+
+{"description":"<!DOCTYPEa PUBLIC''",
+"input":"<!DOCTYPEa PUBLIC''",
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", "", null, false]]},
+
+{"description":"<!DOCTYPEa PUBLIC''\\u0000",
+"input":"<!DOCTYPEa PUBLIC''\u0000",
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", "", null, false]]},
+
+{"description":"<!DOCTYPEa PUBLIC''\\u0008",
+"input":"<!DOCTYPEa PUBLIC''\u0008",
+"output":["ParseError", "ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", "", null, false]]},
+
+{"description":"<!DOCTYPEa PUBLIC''\\u0009",
+"input":"<!DOCTYPEa PUBLIC''\u0009",
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", "", null, false]]},
+
+{"description":"<!DOCTYPEa PUBLIC''\\u000A",
+"input":"<!DOCTYPEa PUBLIC''\u000A",
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", "", null, false]]},
+
+{"description":"<!DOCTYPEa PUBLIC''\\u000B",
+"input":"<!DOCTYPEa PUBLIC''\u000B",
+"output":["ParseError", "ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", "", null, false]]},
+
+{"description":"<!DOCTYPEa PUBLIC''\\u000C",
+"input":"<!DOCTYPEa PUBLIC''\u000C",
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", "", null, false]]},
+
+{"description":"<!DOCTYPEa PUBLIC''\\u000D",
+"input":"<!DOCTYPEa PUBLIC''\u000D",
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", "", null, false]]},
+
+{"description":"<!DOCTYPEa PUBLIC''\\u001F",
+"input":"<!DOCTYPEa PUBLIC''\u001F",
+"output":["ParseError", "ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", "", null, false]]},
+
+{"description":"<!DOCTYPEa PUBLIC'' ",
+"input":"<!DOCTYPEa PUBLIC'' ",
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", "", null, false]]},
+
+{"description":"<!DOCTYPEa PUBLIC''!",
+"input":"<!DOCTYPEa PUBLIC''!",
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", "", null, false]]},
+
+{"description":"<!DOCTYPEa PUBLIC''\"",
+"input":"<!DOCTYPEa PUBLIC''\"",
+"output":["ParseError", "ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", "", "", false]]},
+
+{"description":"<!DOCTYPEa PUBLIC''#",
+"input":"<!DOCTYPEa PUBLIC''#",
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", "", null, false]]},
+
+{"description":"<!DOCTYPEa PUBLIC''&",
+"input":"<!DOCTYPEa PUBLIC''&",
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", "", null, false]]},
+
+{"description":"<!DOCTYPEa PUBLIC'''",
+"input":"<!DOCTYPEa PUBLIC'''",
+"output":["ParseError", "ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", "", "", false]]},
+
+{"description":"<!DOCTYPEa PUBLIC''(",
+"input":"<!DOCTYPEa PUBLIC''(",
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", "", null, false]]},
+
+{"description":"<!DOCTYPEa PUBLIC''-",
+"input":"<!DOCTYPEa PUBLIC''-",
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", "", null, false]]},
+
+{"description":"<!DOCTYPEa PUBLIC''/",
+"input":"<!DOCTYPEa PUBLIC''/",
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", "", null, false]]},
+
+{"description":"<!DOCTYPEa PUBLIC''0",
+"input":"<!DOCTYPEa PUBLIC''0",
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", "", null, false]]},
+
+{"description":"<!DOCTYPEa PUBLIC''1",
+"input":"<!DOCTYPEa PUBLIC''1",
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", "", null, false]]},
+
+{"description":"<!DOCTYPEa PUBLIC''9",
+"input":"<!DOCTYPEa PUBLIC''9",
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", "", null, false]]},
+
+{"description":"<!DOCTYPEa PUBLIC''<",
+"input":"<!DOCTYPEa PUBLIC''<",
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", "", null, false]]},
+
+{"description":"<!DOCTYPEa PUBLIC''=",
+"input":"<!DOCTYPEa PUBLIC''=",
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", "", null, false]]},
+
+{"description":"<!DOCTYPEa PUBLIC''>",
+"input":"<!DOCTYPEa PUBLIC''>",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", "", null, true]]},
+
+{"description":"<!DOCTYPEa PUBLIC''?",
+"input":"<!DOCTYPEa PUBLIC''?",
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", "", null, false]]},
+
+{"description":"<!DOCTYPEa PUBLIC''@",
+"input":"<!DOCTYPEa PUBLIC''@",
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", "", null, false]]},
+
+{"description":"<!DOCTYPEa PUBLIC''A",
+"input":"<!DOCTYPEa PUBLIC''A",
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", "", null, false]]},
+
+{"description":"<!DOCTYPEa PUBLIC''B",
+"input":"<!DOCTYPEa PUBLIC''B",
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", "", null, false]]},
+
+{"description":"<!DOCTYPEa PUBLIC''Y",
+"input":"<!DOCTYPEa PUBLIC''Y",
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", "", null, false]]},
+
+{"description":"<!DOCTYPEa PUBLIC''Z",
+"input":"<!DOCTYPEa PUBLIC''Z",
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", "", null, false]]},
+
+{"description":"<!DOCTYPEa PUBLIC''`",
+"input":"<!DOCTYPEa PUBLIC''`",
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", "", null, false]]},
+
+{"description":"<!DOCTYPEa PUBLIC''a",
+"input":"<!DOCTYPEa PUBLIC''a",
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", "", null, false]]},
+
+{"description":"<!DOCTYPEa PUBLIC''b",
+"input":"<!DOCTYPEa PUBLIC''b",
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", "", null, false]]},
+
+{"description":"<!DOCTYPEa PUBLIC''y",
+"input":"<!DOCTYPEa PUBLIC''y",
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", "", null, false]]},
+
+{"description":"<!DOCTYPEa PUBLIC''z",
+"input":"<!DOCTYPEa PUBLIC''z",
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", "", null, false]]},
+
+{"description":"<!DOCTYPEa PUBLIC''{",
+"input":"<!DOCTYPEa PUBLIC''{",
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", "", null, false]]},
+
+{"description":"<!DOCTYPEa PUBLIC''\\uDBC0\\uDC00",
+"input":"<!DOCTYPEa PUBLIC''\uDBC0\uDC00",
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", "", null, false]]},
+
+{"description":"<!DOCTYPEa PUBLIC'(",
+"input":"<!DOCTYPEa PUBLIC'(",
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", "(", null, false]]},
+
+{"description":"<!DOCTYPEa PUBLIC'-",
+"input":"<!DOCTYPEa PUBLIC'-",
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", "-", null, false]]},
+
+{"description":"<!DOCTYPEa PUBLIC'/",
+"input":"<!DOCTYPEa PUBLIC'/",
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", "/", null, false]]},
+
+{"description":"<!DOCTYPEa PUBLIC'0",
+"input":"<!DOCTYPEa PUBLIC'0",
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", "0", null, false]]},
+
+{"description":"<!DOCTYPEa PUBLIC'1",
+"input":"<!DOCTYPEa PUBLIC'1",
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", "1", null, false]]},
+
+{"description":"<!DOCTYPEa PUBLIC'9",
+"input":"<!DOCTYPEa PUBLIC'9",
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", "9", null, false]]},
+
+{"description":"<!DOCTYPEa PUBLIC'<",
+"input":"<!DOCTYPEa PUBLIC'<",
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", "<", null, false]]},
+
+{"description":"<!DOCTYPEa PUBLIC'=",
+"input":"<!DOCTYPEa PUBLIC'=",
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", "=", null, false]]},
+
+{"description":"<!DOCTYPEa PUBLIC'>",
+"input":"<!DOCTYPEa PUBLIC'>",
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", "", null, false]]},
+
+{"description":"<!DOCTYPEa PUBLIC'?",
+"input":"<!DOCTYPEa PUBLIC'?",
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", "?", null, false]]},
+
+{"description":"<!DOCTYPEa PUBLIC'@",
+"input":"<!DOCTYPEa PUBLIC'@",
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", "@", null, false]]},
+
+{"description":"<!DOCTYPEa PUBLIC'A",
+"input":"<!DOCTYPEa PUBLIC'A",
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", "A", null, false]]},
+
+{"description":"<!DOCTYPEa PUBLIC'B",
+"input":"<!DOCTYPEa PUBLIC'B",
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", "B", null, false]]},
+
+{"description":"<!DOCTYPEa PUBLIC'Y",
+"input":"<!DOCTYPEa PUBLIC'Y",
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", "Y", null, false]]},
+
+{"description":"<!DOCTYPEa PUBLIC'Z",
+"input":"<!DOCTYPEa PUBLIC'Z",
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", "Z", null, false]]},
+
+{"description":"<!DOCTYPEa PUBLIC'`",
+"input":"<!DOCTYPEa PUBLIC'`",
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", "`", null, false]]},
+
+{"description":"<!DOCTYPEa PUBLIC'a",
+"input":"<!DOCTYPEa PUBLIC'a",
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", "a", null, false]]},
+
+{"description":"<!DOCTYPEa PUBLIC'b",
+"input":"<!DOCTYPEa PUBLIC'b",
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", "b", null, false]]},
+
+{"description":"<!DOCTYPEa PUBLIC'y",
+"input":"<!DOCTYPEa PUBLIC'y",
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", "y", null, false]]},
+
+{"description":"<!DOCTYPEa PUBLIC'z",
+"input":"<!DOCTYPEa PUBLIC'z",
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", "z", null, false]]},
+
+{"description":"<!DOCTYPEa PUBLIC'{",
+"input":"<!DOCTYPEa PUBLIC'{",
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", "{", null, false]]},
+
+{"description":"<!DOCTYPEa PUBLIC'\\uDBC0\\uDC00",
+"input":"<!DOCTYPEa PUBLIC'\uDBC0\uDC00",
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", "\uDBC0\uDC00", null, false]]},
+
+{"description":"<!DOCTYPEa PUBLIC(",
+"input":"<!DOCTYPEa PUBLIC(",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, null, false]]},
+
+{"description":"<!DOCTYPEa PUBLIC-",
+"input":"<!DOCTYPEa PUBLIC-",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, null, false]]},
+
+{"description":"<!DOCTYPEa PUBLIC/",
+"input":"<!DOCTYPEa PUBLIC/",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, null, false]]},
+
+{"description":"<!DOCTYPEa PUBLIC0",
+"input":"<!DOCTYPEa PUBLIC0",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, null, false]]},
+
+{"description":"<!DOCTYPEa PUBLIC1",
+"input":"<!DOCTYPEa PUBLIC1",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, null, false]]},
+
+{"description":"<!DOCTYPEa PUBLIC9",
+"input":"<!DOCTYPEa PUBLIC9",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, null, false]]},
+
+{"description":"<!DOCTYPEa PUBLIC<",
+"input":"<!DOCTYPEa PUBLIC<",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, null, false]]},
+
+{"description":"<!DOCTYPEa PUBLIC=",
+"input":"<!DOCTYPEa PUBLIC=",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, null, false]]},
+
+{"description":"<!DOCTYPEa PUBLIC>",
+"input":"<!DOCTYPEa PUBLIC>",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, null, false]]},
+
+{"description":"<!DOCTYPEa PUBLIC?",
+"input":"<!DOCTYPEa PUBLIC?",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, null, false]]},
+
+{"description":"<!DOCTYPEa PUBLIC@",
+"input":"<!DOCTYPEa PUBLIC@",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, null, false]]},
+
+{"description":"<!DOCTYPEa PUBLICA",
+"input":"<!DOCTYPEa PUBLICA",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, null, false]]},
+
+{"description":"<!DOCTYPEa PUBLICB",
+"input":"<!DOCTYPEa PUBLICB",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, null, false]]},
+
+{"description":"<!DOCTYPEa PUBLICY",
+"input":"<!DOCTYPEa PUBLICY",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, null, false]]},
+
+{"description":"<!DOCTYPEa PUBLICZ",
+"input":"<!DOCTYPEa PUBLICZ",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, null, false]]},
+
+{"description":"<!DOCTYPEa PUBLIC`",
+"input":"<!DOCTYPEa PUBLIC`",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, null, false]]},
+
+{"description":"<!DOCTYPEa PUBLICa",
+"input":"<!DOCTYPEa PUBLICa",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, null, false]]},
+
+{"description":"<!DOCTYPEa PUBLICb",
+"input":"<!DOCTYPEa PUBLICb",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, null, false]]},
+
+{"description":"<!DOCTYPEa PUBLICy",
+"input":"<!DOCTYPEa PUBLICy",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, null, false]]},
+
+{"description":"<!DOCTYPEa PUBLICz",
+"input":"<!DOCTYPEa PUBLICz",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, null, false]]},
+
+{"description":"<!DOCTYPEa PUBLIC{",
+"input":"<!DOCTYPEa PUBLIC{",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, null, false]]},
+
+{"description":"<!DOCTYPEa PUBLIC\\uDBC0\\uDC00",
+"input":"<!DOCTYPEa PUBLIC\uDBC0\uDC00",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, null, false]]},
+
+{"description":"<!DOCTYPEa SYSTEM",
+"input":"<!DOCTYPEa SYSTEM",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, null, false]]},
+
+{"description":"<!DOCTYPEa SYSTEM\\u0000",
+"input":"<!DOCTYPEa SYSTEM\u0000",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, null, false]]},
+
+{"description":"<!DOCTYPEa SYSTEM\\u0008",
+"input":"<!DOCTYPEa SYSTEM\u0008",
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", null, null, false]]},
+
+{"description":"<!DOCTYPEa SYSTEM\\u0009",
+"input":"<!DOCTYPEa SYSTEM\u0009",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, null, false]]},
+
+{"description":"<!DOCTYPEa SYSTEM\\u000A",
+"input":"<!DOCTYPEa SYSTEM\u000A",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, null, false]]},
+
+{"description":"<!DOCTYPEa SYSTEM\\u000B",
+"input":"<!DOCTYPEa SYSTEM\u000B",
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", null, null, false]]},
+
+{"description":"<!DOCTYPEa SYSTEM\\u000C",
+"input":"<!DOCTYPEa SYSTEM\u000C",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, null, false]]},
+
+{"description":"<!DOCTYPEa SYSTEM\\u000D",
+"input":"<!DOCTYPEa SYSTEM\u000D",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, null, false]]},
+
+{"description":"<!DOCTYPEa SYSTEM\\u001F",
+"input":"<!DOCTYPEa SYSTEM\u001F",
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", null, null, false]]},
+
+{"description":"<!DOCTYPEa SYSTEM ",
+"input":"<!DOCTYPEa SYSTEM ",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, null, false]]},
+
+{"description":"<!DOCTYPEa SYSTEM!",
+"input":"<!DOCTYPEa SYSTEM!",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, null, false]]},
+
+{"description":"<!DOCTYPEa SYSTEM\"",
+"input":"<!DOCTYPEa SYSTEM\"",
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", null, "", false]]},
+
+{"description":"<!DOCTYPEa SYSTEM\"\\u0000",
+"input":"<!DOCTYPEa SYSTEM\"\u0000",
+"output":["ParseError", "ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", null, "\uFFFD", false]]},
+
+{"description":"<!DOCTYPEa SYSTEM\"\\u0009",
+"input":"<!DOCTYPEa SYSTEM\"\u0009",
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", null, "\u0009", false]]},
+
+{"description":"<!DOCTYPEa SYSTEM\"\\u000A",
+"input":"<!DOCTYPEa SYSTEM\"\u000A",
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", null, "\u000A", false]]},
+
+{"description":"<!DOCTYPEa SYSTEM\"\\u000B",
+"input":"<!DOCTYPEa SYSTEM\"\u000B",
+"output":["ParseError", "ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", null, "\u000B", false]]},
+
+{"description":"<!DOCTYPEa SYSTEM\"\\u000C",
+"input":"<!DOCTYPEa SYSTEM\"\u000C",
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", null, "\u000C", false]]},
+
+{"description":"<!DOCTYPEa SYSTEM\" ",
+"input":"<!DOCTYPEa SYSTEM\" ",
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", null, " ", false]]},
+
+{"description":"<!DOCTYPEa SYSTEM\"!",
+"input":"<!DOCTYPEa SYSTEM\"!",
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", null, "!", false]]},
+
+{"description":"<!DOCTYPEa SYSTEM\"\"",
+"input":"<!DOCTYPEa SYSTEM\"\"",
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", null, "", false]]},
+
+{"description":"<!DOCTYPEa SYSTEM\"#",
+"input":"<!DOCTYPEa SYSTEM\"#",
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", null, "#", false]]},
+
+{"description":"<!DOCTYPEa SYSTEM\"&",
+"input":"<!DOCTYPEa SYSTEM\"&",
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", null, "&", false]]},
+
+{"description":"<!DOCTYPEa SYSTEM\"'",
+"input":"<!DOCTYPEa SYSTEM\"'",
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", null, "'", false]]},
+
+{"description":"<!DOCTYPEa SYSTEM\"-",
+"input":"<!DOCTYPEa SYSTEM\"-",
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", null, "-", false]]},
+
+{"description":"<!DOCTYPEa SYSTEM\"/",
+"input":"<!DOCTYPEa SYSTEM\"/",
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", null, "/", false]]},
+
+{"description":"<!DOCTYPEa SYSTEM\"0",
+"input":"<!DOCTYPEa SYSTEM\"0",
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", null, "0", false]]},
+
+{"description":"<!DOCTYPEa SYSTEM\"1",
+"input":"<!DOCTYPEa SYSTEM\"1",
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", null, "1", false]]},
+
+{"description":"<!DOCTYPEa SYSTEM\"9",
+"input":"<!DOCTYPEa SYSTEM\"9",
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", null, "9", false]]},
+
+{"description":"<!DOCTYPEa SYSTEM\"<",
+"input":"<!DOCTYPEa SYSTEM\"<",
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", null, "<", false]]},
+
+{"description":"<!DOCTYPEa SYSTEM\"=",
+"input":"<!DOCTYPEa SYSTEM\"=",
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", null, "=", false]]},
+
+{"description":"<!DOCTYPEa SYSTEM\">",
+"input":"<!DOCTYPEa SYSTEM\">",
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", null, "", false]]},
+
+{"description":"<!DOCTYPEa SYSTEM\"?",
+"input":"<!DOCTYPEa SYSTEM\"?",
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", null, "?", false]]},
+
+{"description":"<!DOCTYPEa SYSTEM\"@",
+"input":"<!DOCTYPEa SYSTEM\"@",
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", null, "@", false]]},
+
+{"description":"<!DOCTYPEa SYSTEM\"A",
+"input":"<!DOCTYPEa SYSTEM\"A",
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", null, "A", false]]},
+
+{"description":"<!DOCTYPEa SYSTEM\"B",
+"input":"<!DOCTYPEa SYSTEM\"B",
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", null, "B", false]]},
+
+{"description":"<!DOCTYPEa SYSTEM\"Y",
+"input":"<!DOCTYPEa SYSTEM\"Y",
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", null, "Y", false]]},
+
+{"description":"<!DOCTYPEa SYSTEM\"Z",
+"input":"<!DOCTYPEa SYSTEM\"Z",
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", null, "Z", false]]},
+
+{"description":"<!DOCTYPEa SYSTEM\"`",
+"input":"<!DOCTYPEa SYSTEM\"`",
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", null, "`", false]]},
+
+{"description":"<!DOCTYPEa SYSTEM\"a",
+"input":"<!DOCTYPEa SYSTEM\"a",
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", null, "a", false]]},
+
+{"description":"<!DOCTYPEa SYSTEM\"b",
+"input":"<!DOCTYPEa SYSTEM\"b",
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", null, "b", false]]},
+
+{"description":"<!DOCTYPEa SYSTEM\"y",
+"input":"<!DOCTYPEa SYSTEM\"y",
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", null, "y", false]]},
+
+{"description":"<!DOCTYPEa SYSTEM\"z",
+"input":"<!DOCTYPEa SYSTEM\"z",
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", null, "z", false]]},
+
+{"description":"<!DOCTYPEa SYSTEM\"{",
+"input":"<!DOCTYPEa SYSTEM\"{",
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", null, "{", false]]},
+
+{"description":"<!DOCTYPEa SYSTEM\"\\uDBC0\\uDC00",
+"input":"<!DOCTYPEa SYSTEM\"\uDBC0\uDC00",
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", null, "\uDBC0\uDC00", false]]},
+
+{"description":"<!DOCTYPEa SYSTEM#",
+"input":"<!DOCTYPEa SYSTEM#",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, null, false]]},
+
+{"description":"<!DOCTYPEa SYSTEM&",
+"input":"<!DOCTYPEa SYSTEM&",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, null, false]]},
+
+{"description":"<!DOCTYPEa SYSTEM'",
+"input":"<!DOCTYPEa SYSTEM'",
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", null, "", false]]},
+
+{"description":"<!DOCTYPEa SYSTEM'\\u0000",
+"input":"<!DOCTYPEa SYSTEM'\u0000",
+"output":["ParseError", "ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", null, "\uFFFD", false]]},
+
+{"description":"<!DOCTYPEa SYSTEM'\\u0009",
+"input":"<!DOCTYPEa SYSTEM'\u0009",
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", null, "\u0009", false]]},
+
+{"description":"<!DOCTYPEa SYSTEM'\\u000A",
+"input":"<!DOCTYPEa SYSTEM'\u000A",
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", null, "\u000A", false]]},
+
+{"description":"<!DOCTYPEa SYSTEM'\\u000B",
+"input":"<!DOCTYPEa SYSTEM'\u000B",
+"output":["ParseError", "ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", null, "\u000B", false]]},
+
+{"description":"<!DOCTYPEa SYSTEM'\\u000C",
+"input":"<!DOCTYPEa SYSTEM'\u000C",
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", null, "\u000C", false]]},
+
+{"description":"<!DOCTYPEa SYSTEM' ",
+"input":"<!DOCTYPEa SYSTEM' ",
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", null, " ", false]]},
+
+{"description":"<!DOCTYPEa SYSTEM'!",
+"input":"<!DOCTYPEa SYSTEM'!",
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", null, "!", false]]},
+
+{"description":"<!DOCTYPEa SYSTEM'\"",
+"input":"<!DOCTYPEa SYSTEM'\"",
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", null, "\"", false]]},
+
+{"description":"<!DOCTYPEa SYSTEM'&",
+"input":"<!DOCTYPEa SYSTEM'&",
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", null, "&", false]]},
+
+{"description":"<!DOCTYPEa SYSTEM''",
+"input":"<!DOCTYPEa SYSTEM''",
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", null, "", false]]},
+
+{"description":"<!DOCTYPEa SYSTEM''\\u0000",
+"input":"<!DOCTYPEa SYSTEM''\u0000",
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", null, "", true]]},
+
+{"description":"<!DOCTYPEa SYSTEM''\\u0008",
+"input":"<!DOCTYPEa SYSTEM''\u0008",
+"output":["ParseError", "ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", null, "", true]]},
+
+{"description":"<!DOCTYPEa SYSTEM''\\u0009",
+"input":"<!DOCTYPEa SYSTEM''\u0009",
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", null, "", false]]},
+
+{"description":"<!DOCTYPEa SYSTEM''\\u000A",
+"input":"<!DOCTYPEa SYSTEM''\u000A",
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", null, "", false]]},
+
+{"description":"<!DOCTYPEa SYSTEM''\\u000B",
+"input":"<!DOCTYPEa SYSTEM''\u000B",
+"output":["ParseError", "ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", null, "", true]]},
+
+{"description":"<!DOCTYPEa SYSTEM''\\u000C",
+"input":"<!DOCTYPEa SYSTEM''\u000C",
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", null, "", false]]},
+
+{"description":"<!DOCTYPEa SYSTEM''\\u000D",
+"input":"<!DOCTYPEa SYSTEM''\u000D",
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", null, "", false]]},
+
+{"description":"<!DOCTYPEa SYSTEM''\\u001F",
+"input":"<!DOCTYPEa SYSTEM''\u001F",
+"output":["ParseError", "ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", null, "", true]]},
+
+{"description":"<!DOCTYPEa SYSTEM'' ",
+"input":"<!DOCTYPEa SYSTEM'' ",
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", null, "", false]]},
+
+{"description":"<!DOCTYPEa SYSTEM''!",
+"input":"<!DOCTYPEa SYSTEM''!",
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", null, "", true]]},
+
+{"description":"<!DOCTYPEa SYSTEM''\"",
+"input":"<!DOCTYPEa SYSTEM''\"",
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", null, "", true]]},
+
+{"description":"<!DOCTYPEa SYSTEM''&",
+"input":"<!DOCTYPEa SYSTEM''&",
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", null, "", true]]},
+
+{"description":"<!DOCTYPEa SYSTEM'''",
+"input":"<!DOCTYPEa SYSTEM'''",
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", null, "", true]]},
+
+{"description":"<!DOCTYPEa SYSTEM''-",
+"input":"<!DOCTYPEa SYSTEM''-",
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", null, "", true]]},
+
+{"description":"<!DOCTYPEa SYSTEM''/",
+"input":"<!DOCTYPEa SYSTEM''/",
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", null, "", true]]},
+
+{"description":"<!DOCTYPEa SYSTEM''0",
+"input":"<!DOCTYPEa SYSTEM''0",
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", null, "", true]]},
+
+{"description":"<!DOCTYPEa SYSTEM''1",
+"input":"<!DOCTYPEa SYSTEM''1",
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", null, "", true]]},
+
+{"description":"<!DOCTYPEa SYSTEM''9",
+"input":"<!DOCTYPEa SYSTEM''9",
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", null, "", true]]},
+
+{"description":"<!DOCTYPEa SYSTEM''<",
+"input":"<!DOCTYPEa SYSTEM''<",
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", null, "", true]]},
+
+{"description":"<!DOCTYPEa SYSTEM''=",
+"input":"<!DOCTYPEa SYSTEM''=",
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", null, "", true]]},
+
+{"description":"<!DOCTYPEa SYSTEM''>",
+"input":"<!DOCTYPEa SYSTEM''>",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, "", true]]},
+
+{"description":"<!DOCTYPEa SYSTEM''?",
+"input":"<!DOCTYPEa SYSTEM''?",
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", null, "", true]]},
+
+{"description":"<!DOCTYPEa SYSTEM''@",
+"input":"<!DOCTYPEa SYSTEM''@",
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", null, "", true]]},
+
+{"description":"<!DOCTYPEa SYSTEM''A",
+"input":"<!DOCTYPEa SYSTEM''A",
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", null, "", true]]},
+
+{"description":"<!DOCTYPEa SYSTEM''B",
+"input":"<!DOCTYPEa SYSTEM''B",
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", null, "", true]]},
+
+{"description":"<!DOCTYPEa SYSTEM''Y",
+"input":"<!DOCTYPEa SYSTEM''Y",
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", null, "", true]]},
+
+{"description":"<!DOCTYPEa SYSTEM''Z",
+"input":"<!DOCTYPEa SYSTEM''Z",
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", null, "", true]]},
+
+{"description":"<!DOCTYPEa SYSTEM''`",
+"input":"<!DOCTYPEa SYSTEM''`",
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", null, "", true]]},
+
+{"description":"<!DOCTYPEa SYSTEM''a",
+"input":"<!DOCTYPEa SYSTEM''a",
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", null, "", true]]},
+
+{"description":"<!DOCTYPEa SYSTEM''b",
+"input":"<!DOCTYPEa SYSTEM''b",
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", null, "", true]]},
+
+{"description":"<!DOCTYPEa SYSTEM''y",
+"input":"<!DOCTYPEa SYSTEM''y",
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", null, "", true]]},
+
+{"description":"<!DOCTYPEa SYSTEM''z",
+"input":"<!DOCTYPEa SYSTEM''z",
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", null, "", true]]},
+
+{"description":"<!DOCTYPEa SYSTEM''{",
+"input":"<!DOCTYPEa SYSTEM''{",
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", null, "", true]]},
+
+{"description":"<!DOCTYPEa SYSTEM''\\uDBC0\\uDC00",
+"input":"<!DOCTYPEa SYSTEM''\uDBC0\uDC00",
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", null, "", true]]},
+
+{"description":"<!DOCTYPEa SYSTEM'(",
+"input":"<!DOCTYPEa SYSTEM'(",
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", null, "(", false]]},
+
+{"description":"<!DOCTYPEa SYSTEM'-",
+"input":"<!DOCTYPEa SYSTEM'-",
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", null, "-", false]]},
+
+{"description":"<!DOCTYPEa SYSTEM'/",
+"input":"<!DOCTYPEa SYSTEM'/",
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", null, "/", false]]},
+
+{"description":"<!DOCTYPEa SYSTEM'0",
+"input":"<!DOCTYPEa SYSTEM'0",
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", null, "0", false]]},
+
+{"description":"<!DOCTYPEa SYSTEM'1",
+"input":"<!DOCTYPEa SYSTEM'1",
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", null, "1", false]]},
+
+{"description":"<!DOCTYPEa SYSTEM'9",
+"input":"<!DOCTYPEa SYSTEM'9",
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", null, "9", false]]},
+
+{"description":"<!DOCTYPEa SYSTEM'<",
+"input":"<!DOCTYPEa SYSTEM'<",
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", null, "<", false]]},
+
+{"description":"<!DOCTYPEa SYSTEM'=",
+"input":"<!DOCTYPEa SYSTEM'=",
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", null, "=", false]]},
+
+{"description":"<!DOCTYPEa SYSTEM'>",
+"input":"<!DOCTYPEa SYSTEM'>",
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", null, "", false]]},
+
+{"description":"<!DOCTYPEa SYSTEM'?",
+"input":"<!DOCTYPEa SYSTEM'?",
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", null, "?", false]]},
+
+{"description":"<!DOCTYPEa SYSTEM'@",
+"input":"<!DOCTYPEa SYSTEM'@",
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", null, "@", false]]},
+
+{"description":"<!DOCTYPEa SYSTEM'A",
+"input":"<!DOCTYPEa SYSTEM'A",
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", null, "A", false]]},
+
+{"description":"<!DOCTYPEa SYSTEM'B",
+"input":"<!DOCTYPEa SYSTEM'B",
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", null, "B", false]]},
+
+{"description":"<!DOCTYPEa SYSTEM'Y",
+"input":"<!DOCTYPEa SYSTEM'Y",
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", null, "Y", false]]},
+
+{"description":"<!DOCTYPEa SYSTEM'Z",
+"input":"<!DOCTYPEa SYSTEM'Z",
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", null, "Z", false]]},
+
+{"description":"<!DOCTYPEa SYSTEM'`",
+"input":"<!DOCTYPEa SYSTEM'`",
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", null, "`", false]]},
+
+{"description":"<!DOCTYPEa SYSTEM'a",
+"input":"<!DOCTYPEa SYSTEM'a",
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", null, "a", false]]},
+
+{"description":"<!DOCTYPEa SYSTEM'b",
+"input":"<!DOCTYPEa SYSTEM'b",
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", null, "b", false]]},
+
+{"description":"<!DOCTYPEa SYSTEM'y",
+"input":"<!DOCTYPEa SYSTEM'y",
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", null, "y", false]]},
+
+{"description":"<!DOCTYPEa SYSTEM'z",
+"input":"<!DOCTYPEa SYSTEM'z",
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", null, "z", false]]},
+
+{"description":"<!DOCTYPEa SYSTEM'{",
+"input":"<!DOCTYPEa SYSTEM'{",
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", null, "{", false]]},
+
+{"description":"<!DOCTYPEa SYSTEM'\\uDBC0\\uDC00",
+"input":"<!DOCTYPEa SYSTEM'\uDBC0\uDC00",
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", null, "\uDBC0\uDC00", false]]},
+
+{"description":"<!DOCTYPEa SYSTEM(",
+"input":"<!DOCTYPEa SYSTEM(",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, null, false]]},
+
+{"description":"<!DOCTYPEa SYSTEM-",
+"input":"<!DOCTYPEa SYSTEM-",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, null, false]]},
+
+{"description":"<!DOCTYPEa SYSTEM/",
+"input":"<!DOCTYPEa SYSTEM/",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, null, false]]},
+
+{"description":"<!DOCTYPEa SYSTEM0",
+"input":"<!DOCTYPEa SYSTEM0",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, null, false]]},
+
+{"description":"<!DOCTYPEa SYSTEM1",
+"input":"<!DOCTYPEa SYSTEM1",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, null, false]]},
+
+{"description":"<!DOCTYPEa SYSTEM9",
+"input":"<!DOCTYPEa SYSTEM9",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, null, false]]},
+
+{"description":"<!DOCTYPEa SYSTEM<",
+"input":"<!DOCTYPEa SYSTEM<",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, null, false]]},
+
+{"description":"<!DOCTYPEa SYSTEM=",
+"input":"<!DOCTYPEa SYSTEM=",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, null, false]]},
+
+{"description":"<!DOCTYPEa SYSTEM>",
+"input":"<!DOCTYPEa SYSTEM>",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, null, false]]},
+
+{"description":"<!DOCTYPEa SYSTEM?",
+"input":"<!DOCTYPEa SYSTEM?",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, null, false]]},
+
+{"description":"<!DOCTYPEa SYSTEM@",
+"input":"<!DOCTYPEa SYSTEM@",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, null, false]]},
+
+{"description":"<!DOCTYPEa SYSTEMA",
+"input":"<!DOCTYPEa SYSTEMA",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, null, false]]},
+
+{"description":"<!DOCTYPEa SYSTEMB",
+"input":"<!DOCTYPEa SYSTEMB",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, null, false]]},
+
+{"description":"<!DOCTYPEa SYSTEMY",
+"input":"<!DOCTYPEa SYSTEMY",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, null, false]]},
+
+{"description":"<!DOCTYPEa SYSTEMZ",
+"input":"<!DOCTYPEa SYSTEMZ",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, null, false]]},
+
+{"description":"<!DOCTYPEa SYSTEM`",
+"input":"<!DOCTYPEa SYSTEM`",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, null, false]]},
+
+{"description":"<!DOCTYPEa SYSTEMa",
+"input":"<!DOCTYPEa SYSTEMa",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, null, false]]},
+
+{"description":"<!DOCTYPEa SYSTEMb",
+"input":"<!DOCTYPEa SYSTEMb",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, null, false]]},
+
+{"description":"<!DOCTYPEa SYSTEMy",
+"input":"<!DOCTYPEa SYSTEMy",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, null, false]]},
+
+{"description":"<!DOCTYPEa SYSTEMz",
+"input":"<!DOCTYPEa SYSTEMz",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, null, false]]},
+
+{"description":"<!DOCTYPEa SYSTEM{",
+"input":"<!DOCTYPEa SYSTEM{",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, null, false]]},
+
+{"description":"<!DOCTYPEa SYSTEM\\uDBC0\\uDC00",
+"input":"<!DOCTYPEa SYSTEM\uDBC0\uDC00",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, null, false]]},
+
+{"description":"<!DOCTYPEa Y",
+"input":"<!DOCTYPEa Y",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, null, false]]},
+
+{"description":"<!DOCTYPEa Z",
+"input":"<!DOCTYPEa Z",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, null, false]]},
+
+{"description":"<!DOCTYPEa `",
+"input":"<!DOCTYPEa `",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, null, false]]},
+
+{"description":"<!DOCTYPEa a",
+"input":"<!DOCTYPEa a",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, null, false]]},
+
+{"description":"<!DOCTYPEa a\\u0000",
+"input":"<!DOCTYPEa a\u0000",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, null, false]]},
+
+{"description":"<!DOCTYPEa a\\u0009",
+"input":"<!DOCTYPEa a\u0009",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, null, false]]},
+
+{"description":"<!DOCTYPEa a\\u000A",
+"input":"<!DOCTYPEa a\u000A",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, null, false]]},
+
+{"description":"<!DOCTYPEa a\\u000B",
+"input":"<!DOCTYPEa a\u000B",
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", null, null, false]]},
+
+{"description":"<!DOCTYPEa a\\u000C",
+"input":"<!DOCTYPEa a\u000C",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, null, false]]},
+
+{"description":"<!DOCTYPEa a ",
+"input":"<!DOCTYPEa a ",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, null, false]]},
+
+{"description":"<!DOCTYPEa a!",
+"input":"<!DOCTYPEa a!",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, null, false]]},
+
+{"description":"<!DOCTYPEa a\"",
+"input":"<!DOCTYPEa a\"",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, null, false]]},
+
+{"description":"<!DOCTYPEa a&",
+"input":"<!DOCTYPEa a&",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, null, false]]},
+
+{"description":"<!DOCTYPEa a'",
+"input":"<!DOCTYPEa a'",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, null, false]]},
+
+{"description":"<!DOCTYPEa a-",
+"input":"<!DOCTYPEa a-",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, null, false]]},
+
+{"description":"<!DOCTYPEa a/",
+"input":"<!DOCTYPEa a/",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, null, false]]},
+
+{"description":"<!DOCTYPEa a0",
+"input":"<!DOCTYPEa a0",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, null, false]]},
+
+{"description":"<!DOCTYPEa a1",
+"input":"<!DOCTYPEa a1",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, null, false]]},
+
+{"description":"<!DOCTYPEa a9",
+"input":"<!DOCTYPEa a9",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, null, false]]},
+
+{"description":"<!DOCTYPEa a<",
+"input":"<!DOCTYPEa a<",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, null, false]]},
+
+{"description":"<!DOCTYPEa a=",
+"input":"<!DOCTYPEa a=",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, null, false]]},
+
+{"description":"<!DOCTYPEa a>",
+"input":"<!DOCTYPEa a>",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, null, false]]},
+
+{"description":"<!DOCTYPEa a?",
+"input":"<!DOCTYPEa a?",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, null, false]]},
+
+{"description":"<!DOCTYPEa a@",
+"input":"<!DOCTYPEa a@",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, null, false]]},
+
+{"description":"<!DOCTYPEa aA",
+"input":"<!DOCTYPEa aA",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, null, false]]},
+
+{"description":"<!DOCTYPEa aB",
+"input":"<!DOCTYPEa aB",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, null, false]]},
+
+{"description":"<!DOCTYPEa aY",
+"input":"<!DOCTYPEa aY",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, null, false]]},
+
+{"description":"<!DOCTYPEa aZ",
+"input":"<!DOCTYPEa aZ",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, null, false]]},
+
+{"description":"<!DOCTYPEa a`",
+"input":"<!DOCTYPEa a`",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, null, false]]},
+
+{"description":"<!DOCTYPEa aa",
+"input":"<!DOCTYPEa aa",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, null, false]]},
+
+{"description":"<!DOCTYPEa ab",
+"input":"<!DOCTYPEa ab",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, null, false]]},
+
+{"description":"<!DOCTYPEa ay",
+"input":"<!DOCTYPEa ay",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, null, false]]},
+
+{"description":"<!DOCTYPEa az",
+"input":"<!DOCTYPEa az",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, null, false]]},
+
+{"description":"<!DOCTYPEa a{",
+"input":"<!DOCTYPEa a{",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, null, false]]},
+
+{"description":"<!DOCTYPEa a\\uDBC0\\uDC00",
+"input":"<!DOCTYPEa a\uDBC0\uDC00",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, null, false]]},
+
+{"description":"<!DOCTYPEa b",
+"input":"<!DOCTYPEa b",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, null, false]]},
+
+{"description":"<!DOCTYPEa y",
+"input":"<!DOCTYPEa y",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, null, false]]},
+
+{"description":"<!DOCTYPEa z",
+"input":"<!DOCTYPEa z",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, null, false]]},
+
+{"description":"<!DOCTYPEa {",
+"input":"<!DOCTYPEa {",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, null, false]]},
+
+{"description":"<!DOCTYPEa \\uDBC0\\uDC00",
+"input":"<!DOCTYPEa \uDBC0\uDC00",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, null, false]]},
+
+{"description":"<!DOCTYPEa!",
+"input":"<!DOCTYPEa!",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a!", null, null, false]]},
+
+{"description":"<!DOCTYPEa\"",
+"input":"<!DOCTYPEa\"",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a\"", null, null, false]]},
+
+{"description":"<!DOCTYPEa&",
+"input":"<!DOCTYPEa&",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a&", null, null, false]]},
+
+{"description":"<!DOCTYPEa'",
+"input":"<!DOCTYPEa'",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a'", null, null, false]]},
+
+{"description":"<!DOCTYPEa-",
+"input":"<!DOCTYPEa-",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a-", null, null, false]]},
+
+{"description":"<!DOCTYPEa/",
+"input":"<!DOCTYPEa/",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a/", null, null, false]]},
+
+{"description":"<!DOCTYPEa0",
+"input":"<!DOCTYPEa0",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a0", null, null, false]]},
+
+{"description":"<!DOCTYPEa1",
+"input":"<!DOCTYPEa1",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a1", null, null, false]]},
+
+{"description":"<!DOCTYPEa9",
+"input":"<!DOCTYPEa9",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a9", null, null, false]]},
+
+{"description":"<!DOCTYPEa<",
+"input":"<!DOCTYPEa<",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a<", null, null, false]]},
+
+{"description":"<!DOCTYPEa=",
+"input":"<!DOCTYPEa=",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a=", null, null, false]]},
+
+{"description":"<!DOCTYPEa>",
+"input":"<!DOCTYPEa>",
+"output":["ParseError", ["DOCTYPE", "a", null, null, true]]},
+
+{"description":"<!DOCTYPEa?",
+"input":"<!DOCTYPEa?",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a?", null, null, false]]},
+
+{"description":"<!DOCTYPEa@",
+"input":"<!DOCTYPEa@",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a@", null, null, false]]},
+
+{"description":"<!DOCTYPEaA",
+"input":"<!DOCTYPEaA",
+"output":["ParseError", "ParseError", ["DOCTYPE", "aa", null, null, false]]},
+
+{"description":"<!DOCTYPEaB",
+"input":"<!DOCTYPEaB",
+"output":["ParseError", "ParseError", ["DOCTYPE", "ab", null, null, false]]},
+
+{"description":"<!DOCTYPEaY",
+"input":"<!DOCTYPEaY",
+"output":["ParseError", "ParseError", ["DOCTYPE", "ay", null, null, false]]},
+
+{"description":"<!DOCTYPEaZ",
+"input":"<!DOCTYPEaZ",
+"output":["ParseError", "ParseError", ["DOCTYPE", "az", null, null, false]]},
+
+{"description":"<!DOCTYPEa[",
+"input":"<!DOCTYPEa[",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a[", null, null, false]]},
+
+{"description":"<!DOCTYPEa`",
+"input":"<!DOCTYPEa`",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a`", null, null, false]]},
+
+{"description":"<!DOCTYPEaa",
+"input":"<!DOCTYPEaa",
+"output":["ParseError", "ParseError", ["DOCTYPE", "aa", null, null, false]]},
+
+{"description":"<!DOCTYPEab",
+"input":"<!DOCTYPEab",
+"output":["ParseError", "ParseError", ["DOCTYPE", "ab", null, null, false]]},
+
+{"description":"<!DOCTYPEay",
+"input":"<!DOCTYPEay",
+"output":["ParseError", "ParseError", ["DOCTYPE", "ay", null, null, false]]},
+
+{"description":"<!DOCTYPEaz",
+"input":"<!DOCTYPEaz",
+"output":["ParseError", "ParseError", ["DOCTYPE", "az", null, null, false]]},
+
+{"description":"<!DOCTYPEa{",
+"input":"<!DOCTYPEa{",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a{", null, null, false]]},
+
+{"description":"<!DOCTYPEa\\uDBC0\\uDC00",
+"input":"<!DOCTYPEa\uDBC0\uDC00",
+"output":["ParseError", "ParseError", ["DOCTYPE", "a\uDBC0\uDC00", null, null, false]]},
+
+{"description":"<!DOCTYPEb",
+"input":"<!DOCTYPEb",
+"output":["ParseError", "ParseError", ["DOCTYPE", "b", null, null, false]]},
+
+{"description":"<!DOCTYPEy",
+"input":"<!DOCTYPEy",
+"output":["ParseError", "ParseError", ["DOCTYPE", "y", null, null, false]]},
+
+{"description":"<!DOCTYPEz",
+"input":"<!DOCTYPEz",
+"output":["ParseError", "ParseError", ["DOCTYPE", "z", null, null, false]]},
+
+{"description":"<!DOCTYPE{",
+"input":"<!DOCTYPE{",
+"output":["ParseError", "ParseError", ["DOCTYPE", "{", null, null, false]]},
+
+{"description":"<!DOCTYPE\\uDBC0\\uDC00",
+"input":"<!DOCTYPE\uDBC0\uDC00",
+"output":["ParseError", "ParseError", ["DOCTYPE", "\uDBC0\uDC00", null, null, false]]},
+
+{"description":"<!Y",
+"input":"<!Y",
+"output":["ParseError", ["Comment", "Y"]]},
+
+{"description":"<!Z",
+"input":"<!Z",
+"output":["ParseError", ["Comment", "Z"]]},
+
+{"description":"<!`",
+"input":"<!`",
+"output":["ParseError", ["Comment", "`"]]},
+
+{"description":"<!a",
+"input":"<!a",
+"output":["ParseError", ["Comment", "a"]]},
+
+{"description":"<!b",
+"input":"<!b",
+"output":["ParseError", ["Comment", "b"]]},
+
+{"description":"<!y",
+"input":"<!y",
+"output":["ParseError", ["Comment", "y"]]},
+
+{"description":"<!z",
+"input":"<!z",
+"output":["ParseError", ["Comment", "z"]]},
+
+{"description":"<!{",
+"input":"<!{",
+"output":["ParseError", ["Comment", "{"]]},
+
+{"description":"<!\\uDBC0\\uDC00",
+"input":"<!\uDBC0\uDC00",
+"output":["ParseError", ["Comment", "\uDBC0\uDC00"]]},
+
+{"description":"<\"",
+"input":"<\"",
+"output":["ParseError", ["Character", "<\""]]},
+
+{"description":"<&",
+"input":"<&",
+"output":["ParseError", ["Character", "<&"]]},
+
+{"description":"<'",
+"input":"<'",
+"output":["ParseError", ["Character", "<'"]]},
+
+{"description":"<-",
+"input":"<-",
+"output":["ParseError", ["Character", "<-"]]},
+
+{"description":"<.",
+"input":"<.",
+"output":["ParseError", ["Character", "<."]]},
+
+{"description":"</",
+"input":"</",
+"output":["ParseError", ["Character", "</"]]},
+
+{"description":"</\\u0000",
+"input":"</\u0000",
+"output":["ParseError", ["Comment", "\uFFFD"]]},
+
+{"description":"</\\u0009",
+"input":"</\u0009",
+"output":["ParseError", ["Comment", "\u0009"]]},
+
+{"description":"</\\u000A",
+"input":"</\u000A",
+"output":["ParseError", ["Comment", "\u000A"]]},
+
+{"description":"</\\u000B",
+"input":"</\u000B",
+"output":["ParseError", "ParseError", ["Comment", "\u000B"]]},
+
+{"description":"</\\u000C",
+"input":"</\u000C",
+"output":["ParseError", ["Comment", "\u000C"]]},
+
+{"description":"</ ",
+"input":"</ ",
+"output":["ParseError", ["Comment", " "]]},
+
+{"description":"</!",
+"input":"</!",
+"output":["ParseError", ["Comment", "!"]]},
+
+{"description":"</\"",
+"input":"</\"",
+"output":["ParseError", ["Comment", "\""]]},
+
+{"description":"</&",
+"input":"</&",
+"output":["ParseError", ["Comment", "&"]]},
+
+{"description":"</'",
+"input":"</'",
+"output":["ParseError", ["Comment", "'"]]},
+
+{"description":"</-",
+"input":"</-",
+"output":["ParseError", ["Comment", "-"]]},
+
+{"description":"<//",
+"input":"<//",
+"output":["ParseError", ["Comment", "/"]]},
+
+{"description":"</0",
+"input":"</0",
+"output":["ParseError", ["Comment", "0"]]},
+
+{"description":"</1",
+"input":"</1",
+"output":["ParseError", ["Comment", "1"]]},
+
+{"description":"</9",
+"input":"</9",
+"output":["ParseError", ["Comment", "9"]]},
+
+{"description":"</<",
+"input":"</<",
+"output":["ParseError", ["Comment", "<"]]},
+
+{"description":"</=",
+"input":"</=",
+"output":["ParseError", ["Comment", "="]]},
+
+{"description":"</>",
+"input":"</>",
+"output":["ParseError"]},
+
+{"description":"</?",
+"input":"</?",
+"output":["ParseError", ["Comment", "?"]]},
+
+{"description":"</@",
+"input":"</@",
+"output":["ParseError", ["Comment", "@"]]},
+
+{"description":"</A>",
+"input":"</A>",
+"output":[["EndTag", "a"]]},
+
+{"description":"</B>",
+"input":"</B>",
+"output":[["EndTag", "b"]]},
+
+{"description":"</Y>",
+"input":"</Y>",
+"output":[["EndTag", "y"]]},
+
+{"description":"</Z>",
+"input":"</Z>",
+"output":[["EndTag", "z"]]},
+
+{"description":"</[",
+"input":"</[",
+"output":["ParseError", ["Comment", "["]]},
+
+{"description":"</`",
+"input":"</`",
+"output":["ParseError", ["Comment", "`"]]},
+
+{"description":"</a>",
+"input":"</a>",
+"output":[["EndTag", "a"]]},
+
+{"description":"</b>",
+"input":"</b>",
+"output":[["EndTag", "b"]]},
+
+{"description":"</y>",
+"input":"</y>",
+"output":[["EndTag", "y"]]},
+
+{"description":"</z>",
+"input":"</z>",
+"output":[["EndTag", "z"]]},
+
+{"description":"</{",
+"input":"</{",
+"output":["ParseError", ["Comment", "{"]]},
+
+{"description":"</\\uDBC0\\uDC00",
+"input":"</\uDBC0\uDC00",
+"output":["ParseError", ["Comment", "\uDBC0\uDC00"]]},
+
+{"description":"<0",
+"input":"<0",
+"output":["ParseError", ["Character", "<0"]]},
+
+{"description":"<1",
+"input":"<1",
+"output":["ParseError", ["Character", "<1"]]},
+
+{"description":"<9",
+"input":"<9",
+"output":["ParseError", ["Character", "<9"]]},
+
+{"description":"<<",
+"input":"<<",
+"output":["ParseError", ["Character", "<"], "ParseError", ["Character", "<"]]},
+
+{"description":"<=",
+"input":"<=",
+"output":["ParseError", ["Character", "<="]]},
+
+{"description":"<>",
+"input":"<>",
+"output":["ParseError", ["Character", "<>"]]},
+
+{"description":"<?",
+"input":"<?",
+"output":["ParseError", ["Comment", "?"]]},
+
+{"description":"<?\\u0000",
+"input":"<?\u0000",
+"output":["ParseError", ["Comment", "?\uFFFD"]]},
+
+{"description":"<?\\u0009",
+"input":"<?\u0009",
+"output":["ParseError", ["Comment", "?\u0009"]]},
+
+{"description":"<?\\u000A",
+"input":"<?\u000A",
+"output":["ParseError", ["Comment", "?\u000A"]]},
+
+{"description":"<?\\u000B",
+"input":"<?\u000B",
+"output":["ParseError", "ParseError", ["Comment", "?\u000B"]]},
+
+{"description":"<?\\u000C",
+"input":"<?\u000C",
+"output":["ParseError", ["Comment", "?\u000C"]]},
+
+{"description":"<? ",
+"input":"<? ",
+"output":["ParseError", ["Comment", "? "]]},
+
+{"description":"<?!",
+"input":"<?!",
+"output":["ParseError", ["Comment", "?!"]]},
+
+{"description":"<?\"",
+"input":"<?\"",
+"output":["ParseError", ["Comment", "?\""]]},
+
+{"description":"<?&",
+"input":"<?&",
+"output":["ParseError", ["Comment", "?&"]]},
+
+{"description":"<?'",
+"input":"<?'",
+"output":["ParseError", ["Comment", "?'"]]},
+
+{"description":"<?-",
+"input":"<?-",
+"output":["ParseError", ["Comment", "?-"]]},
+
+{"description":"<?/",
+"input":"<?/",
+"output":["ParseError", ["Comment", "?/"]]},
+
+{"description":"<?0",
+"input":"<?0",
+"output":["ParseError", ["Comment", "?0"]]},
+
+{"description":"<?1",
+"input":"<?1",
+"output":["ParseError", ["Comment", "?1"]]},
+
+{"description":"<?9",
+"input":"<?9",
+"output":["ParseError", ["Comment", "?9"]]},
+
+{"description":"<?<",
+"input":"<?<",
+"output":["ParseError", ["Comment", "?<"]]},
+
+{"description":"<?=",
+"input":"<?=",
+"output":["ParseError", ["Comment", "?="]]},
+
+{"description":"<?>",
+"input":"<?>",
+"output":["ParseError", ["Comment", "?"]]},
+
+{"description":"<??",
+"input":"<??",
+"output":["ParseError", ["Comment", "??"]]},
+
+{"description":"<?@",
+"input":"<?@",
+"output":["ParseError", ["Comment", "?@"]]},
+
+{"description":"<?A",
+"input":"<?A",
+"output":["ParseError", ["Comment", "?A"]]},
+
+{"description":"<?B",
+"input":"<?B",
+"output":["ParseError", ["Comment", "?B"]]},
+
+{"description":"<?Y",
+"input":"<?Y",
+"output":["ParseError", ["Comment", "?Y"]]},
+
+{"description":"<?Z",
+"input":"<?Z",
+"output":["ParseError", ["Comment", "?Z"]]},
+
+{"description":"<?`",
+"input":"<?`",
+"output":["ParseError", ["Comment", "?`"]]},
+
+{"description":"<?a",
+"input":"<?a",
+"output":["ParseError", ["Comment", "?a"]]},
+
+{"description":"<?b",
+"input":"<?b",
+"output":["ParseError", ["Comment", "?b"]]},
+
+{"description":"<?y",
+"input":"<?y",
+"output":["ParseError", ["Comment", "?y"]]},
+
+{"description":"<?z",
+"input":"<?z",
+"output":["ParseError", ["Comment", "?z"]]},
+
+{"description":"<?{",
+"input":"<?{",
+"output":["ParseError", ["Comment", "?{"]]},
+
+{"description":"<?\\uDBC0\\uDC00",
+"input":"<?\uDBC0\uDC00",
+"output":["ParseError", ["Comment", "?\uDBC0\uDC00"]]},
+
+{"description":"<@",
+"input":"<@",
+"output":["ParseError", ["Character", "<@"]]},
+
+{"description":"<A>",
+"input":"<A>",
+"output":[["StartTag", "a", {}]]},
+
+{"description":"<B>",
+"input":"<B>",
+"output":[["StartTag", "b", {}]]},
+
+{"description":"<Y>",
+"input":"<Y>",
+"output":[["StartTag", "y", {}]]},
+
+{"description":"<Z>",
+"input":"<Z>",
+"output":[["StartTag", "z", {}]]},
+
+{"description":"<[",
+"input":"<[",
+"output":["ParseError", ["Character", "<["]]},
+
+{"description":"<`",
+"input":"<`",
+"output":["ParseError", ["Character", "<`"]]},
+
+{"description":"<a>",
+"input":"<a>",
+"output":[["StartTag", "a", {}]]},
+
+{"description":"<a\\u0000>",
+"input":"<a\u0000>",
+"output":["ParseError", ["StartTag", "a\uFFFD", {}]]},
+
+{"description":"<a\\u0008>",
+"input":"<a\u0008>",
+"output":["ParseError", ["StartTag", "a\u0008", {}]]},
+
+{"description":"<a\\u0009>",
+"input":"<a\u0009>",
+"output":[["StartTag", "a", {}]]},
+
+{"description":"<a\\u000A>",
+"input":"<a\u000A>",
+"output":[["StartTag", "a", {}]]},
+
+{"description":"<a\\u000B>",
+"input":"<a\u000B>",
+"output":["ParseError", ["StartTag", "a\u000B", {}]]},
+
+{"description":"<a\\u000C>",
+"input":"<a\u000C>",
+"output":[["StartTag", "a", {}]]},
+
+{"description":"<a\\u000D>",
+"input":"<a\u000D>",
+"output":[["StartTag", "a", {}]]},
+
+{"description":"<a\\u001F>",
+"input":"<a\u001F>",
+"output":["ParseError", ["StartTag", "a\u001F", {}]]},
+
+{"description":"<a >",
+"input":"<a >",
+"output":[["StartTag", "a", {}]]},
+
+{"description":"<a \\u0000>",
+"input":"<a \u0000>",
+"output":["ParseError", ["StartTag", "a", {"\uFFFD":""}]]},
+
+{"description":"<a \\u0008>",
+"input":"<a \u0008>",
+"output":["ParseError", ["StartTag", "a", {"\u0008":""}]]},
+
+{"description":"<a \\u0009>",
+"input":"<a \u0009>",
+"output":[["StartTag", "a", {}]]},
+
+{"description":"<a \\u000A>",
+"input":"<a \u000A>",
+"output":[["StartTag", "a", {}]]},
+
+{"description":"<a \\u000B>",
+"input":"<a \u000B>",
+"output":["ParseError", ["StartTag", "a", {"\u000B":""}]]},
+
+{"description":"<a \\u000C>",
+"input":"<a \u000C>",
+"output":[["StartTag", "a", {}]]},
+
+{"description":"<a \\u000D>",
+"input":"<a \u000D>",
+"output":[["StartTag", "a", {}]]},
+
+{"description":"<a \\u001F>",
+"input":"<a \u001F>",
+"output":["ParseError", ["StartTag", "a", {"\u001F":""}]]},
+
+{"description":"<a  >",
+"input":"<a  >",
+"output":[["StartTag", "a", {}]]},
+
+{"description":"<a !>",
+"input":"<a !>",
+"output":[["StartTag", "a", {"!":""}]]},
+
+{"description":"<a \">",
+"input":"<a \">",
+"output":["ParseError", ["StartTag", "a", {"\"":""}]]},
+
+{"description":"<a #>",
+"input":"<a #>",
+"output":[["StartTag", "a", {"#":""}]]},
+
+{"description":"<a &>",
+"input":"<a &>",
+"output":[["StartTag", "a", {"&":""}]]},
+
+{"description":"<a '>",
+"input":"<a '>",
+"output":["ParseError", ["StartTag", "a", {"'":""}]]},
+
+{"description":"<a (>",
+"input":"<a (>",
+"output":[["StartTag", "a", {"(":""}]]},
+
+{"description":"<a ->",
+"input":"<a ->",
+"output":[["StartTag", "a", {"-":""}]]},
+
+{"description":"<a .>",
+"input":"<a .>",
+"output":[["StartTag", "a", {".":""}]]},
+
+{"description":"<a />",
+"input":"<a />",
+"output":[["StartTag", "a", {}, true]]},
+
+{"description":"<a 0>",
+"input":"<a 0>",
+"output":[["StartTag", "a", {"0":""}]]},
+
+{"description":"<a 1>",
+"input":"<a 1>",
+"output":[["StartTag", "a", {"1":""}]]},
+
+{"description":"<a 9>",
+"input":"<a 9>",
+"output":[["StartTag", "a", {"9":""}]]},
+
+{"description":"<a <>",
+"input":"<a <>",
+"output":["ParseError", ["StartTag", "a", {"<":""}]]},
+
+{"description":"<a =>",
+"input":"<a =>",
+"output":["ParseError", ["StartTag", "a", {"=":""}]]},
+
+{"description":"<a >",
+"input":"<a >",
+"output":[["StartTag", "a", {}]]},
+
+{"description":"<a ?>",
+"input":"<a ?>",
+"output":[["StartTag", "a", {"?":""}]]},
+
+{"description":"<a @>",
+"input":"<a @>",
+"output":[["StartTag", "a", {"@":""}]]},
+
+{"description":"<a A>",
+"input":"<a A>",
+"output":[["StartTag", "a", {"a":""}]]},
+
+{"description":"<a B>",
+"input":"<a B>",
+"output":[["StartTag", "a", {"b":""}]]},
+
+{"description":"<a Y>",
+"input":"<a Y>",
+"output":[["StartTag", "a", {"y":""}]]},
+
+{"description":"<a Z>",
+"input":"<a Z>",
+"output":[["StartTag", "a", {"z":""}]]},
+
+{"description":"<a [>",
+"input":"<a [>",
+"output":[["StartTag", "a", {"[":""}]]},
+
+{"description":"<a `>",
+"input":"<a `>",
+"output":[["StartTag", "a", {"`":""}]]},
+
+{"description":"<a a>",
+"input":"<a a>",
+"output":[["StartTag", "a", {"a":""}]]},
+
+{"description":"<a a\\u0000>",
+"input":"<a a\u0000>",
+"output":["ParseError", ["StartTag", "a", {"a\uFFFD":""}]]},
+
+{"description":"<a a\\u0008>",
+"input":"<a a\u0008>",
+"output":["ParseError", ["StartTag", "a", {"a\u0008":""}]]},
+
+{"description":"<a a\\u0009>",
+"input":"<a a\u0009>",
+"output":[["StartTag", "a", {"a":""}]]},
+
+{"description":"<a a\\u000A>",
+"input":"<a a\u000A>",
+"output":[["StartTag", "a", {"a":""}]]},
+
+{"description":"<a a\\u000B>",
+"input":"<a a\u000B>",
+"output":["ParseError", ["StartTag", "a", {"a\u000B":""}]]},
+
+{"description":"<a a\\u000C>",
+"input":"<a a\u000C>",
+"output":[["StartTag", "a", {"a":""}]]},
+
+{"description":"<a a\\u000D>",
+"input":"<a a\u000D>",
+"output":[["StartTag", "a", {"a":""}]]},
+
+{"description":"<a a\\u001F>",
+"input":"<a a\u001F>",
+"output":["ParseError", ["StartTag", "a", {"a\u001F":""}]]},
+
+{"description":"<a a >",
+"input":"<a a >",
+"output":[["StartTag", "a", {"a":""}]]},
+
+{"description":"<a a \\u0000>",
+"input":"<a a \u0000>",
+"output":["ParseError", ["StartTag", "a", {"a":"", "\uFFFD":""}]]},
+
+{"description":"<a a \\u0008>",
+"input":"<a a \u0008>",
+"output":["ParseError", ["StartTag", "a", {"a":"", "\u0008":""}]]},
+
+{"description":"<a a \\u0009>",
+"input":"<a a \u0009>",
+"output":[["StartTag", "a", {"a":""}]]},
+
+{"description":"<a a \\u000A>",
+"input":"<a a \u000A>",
+"output":[["StartTag", "a", {"a":""}]]},
+
+{"description":"<a a \\u000B>",
+"input":"<a a \u000B>",
+"output":["ParseError", ["StartTag", "a", {"a":"", "\u000B":""}]]},
+
+{"description":"<a a \\u000C>",
+"input":"<a a \u000C>",
+"output":[["StartTag", "a", {"a":""}]]},
+
+{"description":"<a a \\u000D>",
+"input":"<a a \u000D>",
+"output":[["StartTag", "a", {"a":""}]]},
+
+{"description":"<a a \\u001F>",
+"input":"<a a \u001F>",
+"output":["ParseError", ["StartTag", "a", {"a":"", "\u001F":""}]]},
+
+{"description":"<a a  >",
+"input":"<a a  >",
+"output":[["StartTag", "a", {"a":""}]]},
+
+{"description":"<a a !>",
+"input":"<a a !>",
+"output":[["StartTag", "a", {"a":"", "!":""}]]},
+
+{"description":"<a a \">",
+"input":"<a a \">",
+"output":["ParseError", ["StartTag", "a", {"a":"", "\"":""}]]},
+
+{"description":"<a a #>",
+"input":"<a a #>",
+"output":[["StartTag", "a", {"a":"", "#":""}]]},
+
+{"description":"<a a &>",
+"input":"<a a &>",
+"output":[["StartTag", "a", {"a":"", "&":""}]]},
+
+{"description":"<a a '>",
+"input":"<a a '>",
+"output":["ParseError", ["StartTag", "a", {"a":"", "'":""}]]},
+
+{"description":"<a a (>",
+"input":"<a a (>",
+"output":[["StartTag", "a", {"a":"", "(":""}]]},
+
+{"description":"<a a ->",
+"input":"<a a ->",
+"output":[["StartTag", "a", {"a":"", "-":""}]]},
+
+{"description":"<a a .>",
+"input":"<a a .>",
+"output":[["StartTag", "a", {"a":"", ".":""}]]},
+
+{"description":"<a a />",
+"input":"<a a />",
+"output":[["StartTag", "a", {"a":""}, true]]},
+
+{"description":"<a a 0>",
+"input":"<a a 0>",
+"output":[["StartTag", "a", {"a":"", "0":""}]]},
+
+{"description":"<a a 1>",
+"input":"<a a 1>",
+"output":[["StartTag", "a", {"a":"", "1":""}]]},
+
+{"description":"<a a 9>",
+"input":"<a a 9>",
+"output":[["StartTag", "a", {"a":"", "9":""}]]},
+
+{"description":"<a a <>",
+"input":"<a a <>",
+"output":["ParseError", ["StartTag", "a", {"a":"", "<":""}]]},
+
+{"description":"<a a =>",
+"input":"<a a =>",
+"output":["ParseError", ["StartTag", "a", {"a":""}]]},
+
+{"description":"<a a >",
+"input":"<a a >",
+"output":[["StartTag", "a", {"a":""}]]},
+
+{"description":"<a a ?>",
+"input":"<a a ?>",
+"output":[["StartTag", "a", {"a":"", "?":""}]]},
+
+{"description":"<a a @>",
+"input":"<a a @>",
+"output":[["StartTag", "a", {"a":"", "@":""}]]},
+
+{"description":"<a a A>",
+"input":"<a a A>",
+"output":["ParseError", ["StartTag", "a", {"a":""}]]},
+
+{"description":"<a a B>",
+"input":"<a a B>",
+"output":[["StartTag", "a", {"a":"", "b":""}]]},
+
+{"description":"<a a Y>",
+"input":"<a a Y>",
+"output":[["StartTag", "a", {"a":"", "y":""}]]},
+
+{"description":"<a a Z>",
+"input":"<a a Z>",
+"output":[["StartTag", "a", {"a":"", "z":""}]]},
+
+{"description":"<a a [>",
+"input":"<a a [>",
+"output":[["StartTag", "a", {"a":"", "[":""}]]},
+
+{"description":"<a a `>",
+"input":"<a a `>",
+"output":[["StartTag", "a", {"a":"", "`":""}]]},
+
+{"description":"<a a a>",
+"input":"<a a a>",
+"output":["ParseError", ["StartTag", "a", {"a":""}]]},
+
+{"description":"<a a b>",
+"input":"<a a b>",
+"output":[["StartTag", "a", {"a":"", "b":""}]]},
+
+{"description":"<a a y>",
+"input":"<a a y>",
+"output":[["StartTag", "a", {"a":"", "y":""}]]},
+
+{"description":"<a a z>",
+"input":"<a a z>",
+"output":[["StartTag", "a", {"a":"", "z":""}]]},
+
+{"description":"<a a {>",
+"input":"<a a {>",
+"output":[["StartTag", "a", {"a":"", "{":""}]]},
+
+{"description":"<a a \\uDBC0\\uDC00>",
+"input":"<a a \uDBC0\uDC00>",
+"output":[["StartTag", "a", {"a":"", "\uDBC0\uDC00":""}]]},
+
+{"description":"<a a!>",
+"input":"<a a!>",
+"output":[["StartTag", "a", {"a!":""}]]},
+
+{"description":"<a a\">",
+"input":"<a a\">",
+"output":["ParseError", ["StartTag", "a", {"a\"":""}]]},
+
+{"description":"<a a#>",
+"input":"<a a#>",
+"output":[["StartTag", "a", {"a#":""}]]},
+
+{"description":"<a a&>",
+"input":"<a a&>",
+"output":[["StartTag", "a", {"a&":""}]]},
+
+{"description":"<a a'>",
+"input":"<a a'>",
+"output":["ParseError", ["StartTag", "a", {"a'":""}]]},
+
+{"description":"<a a(>",
+"input":"<a a(>",
+"output":[["StartTag", "a", {"a(":""}]]},
+
+{"description":"<a a->",
+"input":"<a a->",
+"output":[["StartTag", "a", {"a-":""}]]},
+
+{"description":"<a a.>",
+"input":"<a a.>",
+"output":[["StartTag", "a", {"a.":""}]]},
+
+{"description":"<a a/>",
+"input":"<a a/>",
+"output":[["StartTag", "a", {"a":""}, true]]},
+
+{"description":"<a a0>",
+"input":"<a a0>",
+"output":[["StartTag", "a", {"a0":""}]]},
+
+{"description":"<a a1>",
+"input":"<a a1>",
+"output":[["StartTag", "a", {"a1":""}]]},
+
+{"description":"<a a9>",
+"input":"<a a9>",
+"output":[["StartTag", "a", {"a9":""}]]},
+
+{"description":"<a a<>",
+"input":"<a a<>",
+"output":["ParseError", ["StartTag", "a", {"a<":""}]]},
+
+{"description":"<a a=>",
+"input":"<a a=>",
+"output":["ParseError", ["StartTag", "a", {"a":""}]]},
+
+{"description":"<a a=\\u0000>",
+"input":"<a a=\u0000>",
+"output":["ParseError", ["StartTag", "a", {"a":"\uFFFD"}]]},
+
+{"description":"<a a=\\u0008>",
+"input":"<a a=\u0008>",
+"output":["ParseError", ["StartTag", "a", {"a":"\u0008"}]]},
+
+{"description":"<a a=\\u0009>",
+"input":"<a a=\u0009>",
+"output":["ParseError", ["StartTag", "a", {"a":""}]]},
+
+{"description":"<a a=\\u000A>",
+"input":"<a a=\u000A>",
+"output":["ParseError", ["StartTag", "a", {"a":""}]]},
+
+{"description":"<a a=\\u000B>",
+"input":"<a a=\u000B>",
+"output":["ParseError", ["StartTag", "a", {"a":"\u000B"}]]},
+
+{"description":"<a a=\\u000C>",
+"input":"<a a=\u000C>",
+"output":["ParseError", ["StartTag", "a", {"a":""}]]},
+
+{"description":"<a a=\\u000D>",
+"input":"<a a=\u000D>",
+"output":["ParseError", ["StartTag", "a", {"a":""}]]},
+
+{"description":"<a a=\\u001F>",
+"input":"<a a=\u001F>",
+"output":["ParseError", ["StartTag", "a", {"a":"\u001F"}]]},
+
+{"description":"<a a= >",
+"input":"<a a= >",
+"output":["ParseError", ["StartTag", "a", {"a":""}]]},
+
+{"description":"<a a=!>",
+"input":"<a a=!>",
+"output":[["StartTag", "a", {"a":"!"}]]},
+
+{"description":"<a a=\"\">",
+"input":"<a a=\"\">",
+"output":[["StartTag", "a", {"a":""}]]},
+
+{"description":"<a a=\"\\u0000\">",
+"input":"<a a=\"\u0000\">",
+"output":["ParseError", ["StartTag", "a", {"a":"\uFFFD"}]]},
+
+{"description":"<a a=\"\\u0009\">",
+"input":"<a a=\"\u0009\">",
+"output":[["StartTag", "a", {"a":"\u0009"}]]},
+
+{"description":"<a a=\"\\u000A\">",
+"input":"<a a=\"\u000A\">",
+"output":[["StartTag", "a", {"a":"\u000A"}]]},
+
+{"description":"<a a=\"\\u000B\">",
+"input":"<a a=\"\u000B\">",
+"output":["ParseError", ["StartTag", "a", {"a":"\u000B"}]]},
+
+{"description":"<a a=\"\\u000C\">",
+"input":"<a a=\"\u000C\">",
+"output":[["StartTag", "a", {"a":"\u000C"}]]},
+
+{"description":"<a a=\" \">",
+"input":"<a a=\" \">",
+"output":[["StartTag", "a", {"a":" "}]]},
+
+{"description":"<a a=\"!\">",
+"input":"<a a=\"!\">",
+"output":[["StartTag", "a", {"a":"!"}]]},
+
+{"description":"<a a=\"\">",
+"input":"<a a=\"\">",
+"output":[["StartTag", "a", {"a":""}]]},
+
+{"description":"<a a=\"#\">",
+"input":"<a a=\"#\">",
+"output":[["StartTag", "a", {"a":"#"}]]},
+
+{"description":"<a a=\"%\">",
+"input":"<a a=\"%\">",
+"output":[["StartTag", "a", {"a":"%"}]]},
+
+{"description":"<a a=\"&\">",
+"input":"<a a=\"&\">",
+"output":[["StartTag", "a", {"a":"&"}]]},
+
+{"description":"<a a=\"'\">",
+"input":"<a a=\"'\">",
+"output":[["StartTag", "a", {"a":"'"}]]},
+
+{"description":"<a a=\"-\">",
+"input":"<a a=\"-\">",
+"output":[["StartTag", "a", {"a":"-"}]]},
+
+{"description":"<a a=\"/\">",
+"input":"<a a=\"/\">",
+"output":[["StartTag", "a", {"a":"/"}]]},
+
+{"description":"<a a=\"0\">",
+"input":"<a a=\"0\">",
+"output":[["StartTag", "a", {"a":"0"}]]},
+
+{"description":"<a a=\"1\">",
+"input":"<a a=\"1\">",
+"output":[["StartTag", "a", {"a":"1"}]]},
+
+{"description":"<a a=\"9\">",
+"input":"<a a=\"9\">",
+"output":[["StartTag", "a", {"a":"9"}]]},
+
+{"description":"<a a=\"<\">",
+"input":"<a a=\"<\">",
+"output":[["StartTag", "a", {"a":"<"}]]},
+
+{"description":"<a a=\"=\">",
+"input":"<a a=\"=\">",
+"output":[["StartTag", "a", {"a":"="}]]},
+
+{"description":"<a a=\">\">",
+"input":"<a a=\">\">",
+"output":[["StartTag", "a", {"a":">"}]]},
+
+{"description":"<a a=\"?\">",
+"input":"<a a=\"?\">",
+"output":[["StartTag", "a", {"a":"?"}]]},
+
+{"description":"<a a=\"@\">",
+"input":"<a a=\"@\">",
+"output":[["StartTag", "a", {"a":"@"}]]},
+
+{"description":"<a a=\"A\">",
+"input":"<a a=\"A\">",
+"output":[["StartTag", "a", {"a":"A"}]]},
+
+{"description":"<a a=\"B\">",
+"input":"<a a=\"B\">",
+"output":[["StartTag", "a", {"a":"B"}]]},
+
+{"description":"<a a=\"Y\">",
+"input":"<a a=\"Y\">",
+"output":[["StartTag", "a", {"a":"Y"}]]},
+
+{"description":"<a a=\"Z\">",
+"input":"<a a=\"Z\">",
+"output":[["StartTag", "a", {"a":"Z"}]]},
+
+{"description":"<a a=\"`\">",
+"input":"<a a=\"`\">",
+"output":[["StartTag", "a", {"a":"`"}]]},
+
+{"description":"<a a=\"a\">",
+"input":"<a a=\"a\">",
+"output":[["StartTag", "a", {"a":"a"}]]},
+
+{"description":"<a a=\"b\">",
+"input":"<a a=\"b\">",
+"output":[["StartTag", "a", {"a":"b"}]]},
+
+{"description":"<a a=\"y\">",
+"input":"<a a=\"y\">",
+"output":[["StartTag", "a", {"a":"y"}]]},
+
+{"description":"<a a=\"z\">",
+"input":"<a a=\"z\">",
+"output":[["StartTag", "a", {"a":"z"}]]},
+
+{"description":"<a a=\"{\">",
+"input":"<a a=\"{\">",
+"output":[["StartTag", "a", {"a":"{"}]]},
+
+{"description":"<a a=\"\\uDBC0\\uDC00\">",
+"input":"<a a=\"\uDBC0\uDC00\">",
+"output":[["StartTag", "a", {"a":"\uDBC0\uDC00"}]]},
+
+{"description":"<a a=#>",
+"input":"<a a=#>",
+"output":[["StartTag", "a", {"a":"#"}]]},
+
+{"description":"<a a=%>",
+"input":"<a a=%>",
+"output":[["StartTag", "a", {"a":"%"}]]},
+
+{"description":"<a a=&>",
+"input":"<a a=&>",
+"output":[["StartTag", "a", {"a":"&"}]]},
+
+{"description":"<a a=''>",
+"input":"<a a=''>",
+"output":[["StartTag", "a", {"a":""}]]},
+
+{"description":"<a a='\\u0000'>",
+"input":"<a a='\u0000'>",
+"output":["ParseError", ["StartTag", "a", {"a":"\uFFFD"}]]},
+
+{"description":"<a a='\\u0009'>",
+"input":"<a a='\u0009'>",
+"output":[["StartTag", "a", {"a":"\u0009"}]]},
+
+{"description":"<a a='\\u000A'>",
+"input":"<a a='\u000A'>",
+"output":[["StartTag", "a", {"a":"\u000A"}]]},
+
+{"description":"<a a='\\u000B'>",
+"input":"<a a='\u000B'>",
+"output":["ParseError", ["StartTag", "a", {"a":"\u000B"}]]},
+
+{"description":"<a a='\\u000C'>",
+"input":"<a a='\u000C'>",
+"output":[["StartTag", "a", {"a":"\u000C"}]]},
+
+{"description":"<a a=' '>",
+"input":"<a a=' '>",
+"output":[["StartTag", "a", {"a":" "}]]},
+
+{"description":"<a a='!'>",
+"input":"<a a='!'>",
+"output":[["StartTag", "a", {"a":"!"}]]},
+
+{"description":"<a a='\"'>",
+"input":"<a a='\"'>",
+"output":[["StartTag", "a", {"a":"\""}]]},
+
+{"description":"<a a='%'>",
+"input":"<a a='%'>",
+"output":[["StartTag", "a", {"a":"%"}]]},
+
+{"description":"<a a='&'>",
+"input":"<a a='&'>",
+"output":[["StartTag", "a", {"a":"&"}]]},
+
+{"description":"<a a=''>",
+"input":"<a a=''>",
+"output":[["StartTag", "a", {"a":""}]]},
+
+{"description":"<a a=''\\u0000>",
+"input":"<a a=''\u0000>",
+"output":["ParseError", "ParseError", ["StartTag", "a", {"a":"", "\uFFFD":""}]]},
+
+{"description":"<a a=''\\u0008>",
+"input":"<a a=''\u0008>",
+"output":["ParseError", "ParseError", ["StartTag", "a", {"a":"", "\u0008":""}]]},
+
+{"description":"<a a=''\\u0009>",
+"input":"<a a=''\u0009>",
+"output":[["StartTag", "a", {"a":""}]]},
+
+{"description":"<a a=''\\u000A>",
+"input":"<a a=''\u000A>",
+"output":[["StartTag", "a", {"a":""}]]},
+
+{"description":"<a a=''\\u000B>",
+"input":"<a a=''\u000B>",
+"output":["ParseError", "ParseError", ["StartTag", "a", {"a":"", "\u000B":""}]]},
+
+{"description":"<a a=''\\u000C>",
+"input":"<a a=''\u000C>",
+"output":[["StartTag", "a", {"a":""}]]},
+
+{"description":"<a a=''\\u000D>",
+"input":"<a a=''\u000D>",
+"output":[["StartTag", "a", {"a":""}]]},
+
+{"description":"<a a=''\\u001F>",
+"input":"<a a=''\u001F>",
+"output":["ParseError", "ParseError", ["StartTag", "a", {"a":"", "\u001F":""}]]},
+
+{"description":"<a a='' >",
+"input":"<a a='' >",
+"output":[["StartTag", "a", {"a":""}]]},
+
+{"description":"<a a=''!>",
+"input":"<a a=''!>",
+"output":["ParseError", ["StartTag", "a", {"a":"", "!":""}]]},
+
+{"description":"<a a=''\">",
+"input":"<a a=''\">",
+"output":["ParseError", "ParseError", ["StartTag", "a", {"a":"", "\"":""}]]},
+
+{"description":"<a a=''&>",
+"input":"<a a=''&>",
+"output":["ParseError", ["StartTag", "a", {"a":"", "&":""}]]},
+
+{"description":"<a a='''>",
+"input":"<a a='''>",
+"output":["ParseError", "ParseError", ["StartTag", "a", {"a":"", "'":""}]]},
+
+{"description":"<a a=''->",
+"input":"<a a=''->",
+"output":["ParseError", ["StartTag", "a", {"a":"", "-":""}]]},
+
+{"description":"<a a=''.>",
+"input":"<a a=''.>",
+"output":["ParseError", ["StartTag", "a", {"a":"", ".":""}]]},
+
+{"description":"<a a=''/>",
+"input":"<a a=''/>",
+"output":[["StartTag", "a", {"a":""}, true]]},
+
+{"description":"<a a=''0>",
+"input":"<a a=''0>",
+"output":["ParseError", ["StartTag", "a", {"a":"", "0":""}]]},
+
+{"description":"<a a=''1>",
+"input":"<a a=''1>",
+"output":["ParseError", ["StartTag", "a", {"a":"", "1":""}]]},
+
+{"description":"<a a=''9>",
+"input":"<a a=''9>",
+"output":["ParseError", ["StartTag", "a", {"a":"", "9":""}]]},
+
+{"description":"<a a=''<>",
+"input":"<a a=''<>",
+"output":["ParseError", "ParseError", ["StartTag", "a", {"a":"", "<":""}]]},
+
+{"description":"<a a=''=>",
+"input":"<a a=''=>",
+"output":["ParseError", "ParseError", ["StartTag", "a", {"a":"", "=":""}]]},
+
+{"description":"<a a=''>",
+"input":"<a a=''>",
+"output":[["StartTag", "a", {"a":""}]]},
+
+{"description":"<a a=''?>",
+"input":"<a a=''?>",
+"output":["ParseError", ["StartTag", "a", {"a":"", "?":""}]]},
+
+{"description":"<a a=''@>",
+"input":"<a a=''@>",
+"output":["ParseError", ["StartTag", "a", {"a":"", "@":""}]]},
+
+{"description":"<a a=''A>",
+"input":"<a a=''A>",
+"output":["ParseError", "ParseError", ["StartTag", "a", {"a":""}]]},
+
+{"description":"<a a=''B>",
+"input":"<a a=''B>",
+"output":["ParseError", ["StartTag", "a", {"a":"", "b":""}]]},
+
+{"description":"<a a=''Y>",
+"input":"<a a=''Y>",
+"output":["ParseError", ["StartTag", "a", {"a":"", "y":""}]]},
+
+{"description":"<a a=''Z>",
+"input":"<a a=''Z>",
+"output":["ParseError", ["StartTag", "a", {"a":"", "z":""}]]},
+
+{"description":"<a a=''`>",
+"input":"<a a=''`>",
+"output":["ParseError", ["StartTag", "a", {"a":"", "`":""}]]},
+
+{"description":"<a a=''a>",
+"input":"<a a=''a>",
+"output":["ParseError", "ParseError", ["StartTag", "a", {"a":""}]]},
+
+{"description":"<a a=''b>",
+"input":"<a a=''b>",
+"output":["ParseError", ["StartTag", "a", {"a":"", "b":""}]]},
+
+{"description":"<a a=''y>",
+"input":"<a a=''y>",
+"output":["ParseError", ["StartTag", "a", {"a":"", "y":""}]]},
+
+{"description":"<a a=''z>",
+"input":"<a a=''z>",
+"output":["ParseError", ["StartTag", "a", {"a":"", "z":""}]]},
+
+{"description":"<a a=''{>",
+"input":"<a a=''{>",
+"output":["ParseError", ["StartTag", "a", {"a":"", "{":""}]]},
+
+{"description":"<a a=''\\uDBC0\\uDC00>",
+"input":"<a a=''\uDBC0\uDC00>",
+"output":["ParseError", ["StartTag", "a", {"a":"", "\uDBC0\uDC00":""}]]},
+
+{"description":"<a a='('>",
+"input":"<a a='('>",
+"output":[["StartTag", "a", {"a":"("}]]},
+
+{"description":"<a a='-'>",
+"input":"<a a='-'>",
+"output":[["StartTag", "a", {"a":"-"}]]},
+
+{"description":"<a a='/'>",
+"input":"<a a='/'>",
+"output":[["StartTag", "a", {"a":"/"}]]},
+
+{"description":"<a a='0'>",
+"input":"<a a='0'>",
+"output":[["StartTag", "a", {"a":"0"}]]},
+
+{"description":"<a a='1'>",
+"input":"<a a='1'>",
+"output":[["StartTag", "a", {"a":"1"}]]},
+
+{"description":"<a a='9'>",
+"input":"<a a='9'>",
+"output":[["StartTag", "a", {"a":"9"}]]},
+
+{"description":"<a a='<'>",
+"input":"<a a='<'>",
+"output":[["StartTag", "a", {"a":"<"}]]},
+
+{"description":"<a a='='>",
+"input":"<a a='='>",
+"output":[["StartTag", "a", {"a":"="}]]},
+
+{"description":"<a a='>'>",
+"input":"<a a='>'>",
+"output":[["StartTag", "a", {"a":">"}]]},
+
+{"description":"<a a='?'>",
+"input":"<a a='?'>",
+"output":[["StartTag", "a", {"a":"?"}]]},
+
+{"description":"<a a='@'>",
+"input":"<a a='@'>",
+"output":[["StartTag", "a", {"a":"@"}]]},
+
+{"description":"<a a='A'>",
+"input":"<a a='A'>",
+"output":[["StartTag", "a", {"a":"A"}]]},
+
+{"description":"<a a='B'>",
+"input":"<a a='B'>",
+"output":[["StartTag", "a", {"a":"B"}]]},
+
+{"description":"<a a='Y'>",
+"input":"<a a='Y'>",
+"output":[["StartTag", "a", {"a":"Y"}]]},
+
+{"description":"<a a='Z'>",
+"input":"<a a='Z'>",
+"output":[["StartTag", "a", {"a":"Z"}]]},
+
+{"description":"<a a='`'>",
+"input":"<a a='`'>",
+"output":[["StartTag", "a", {"a":"`"}]]},
+
+{"description":"<a a='a'>",
+"input":"<a a='a'>",
+"output":[["StartTag", "a", {"a":"a"}]]},
+
+{"description":"<a a='b'>",
+"input":"<a a='b'>",
+"output":[["StartTag", "a", {"a":"b"}]]},
+
+{"description":"<a a='y'>",
+"input":"<a a='y'>",
+"output":[["StartTag", "a", {"a":"y"}]]},
+
+{"description":"<a a='z'>",
+"input":"<a a='z'>",
+"output":[["StartTag", "a", {"a":"z"}]]},
+
+{"description":"<a a='{'>",
+"input":"<a a='{'>",
+"output":[["StartTag", "a", {"a":"{"}]]},
+
+{"description":"<a a='\\uDBC0\\uDC00'>",
+"input":"<a a='\uDBC0\uDC00'>",
+"output":[["StartTag", "a", {"a":"\uDBC0\uDC00"}]]},
+
+{"description":"<a a=(>",
+"input":"<a a=(>",
+"output":[["StartTag", "a", {"a":"("}]]},
+
+{"description":"<a a=->",
+"input":"<a a=->",
+"output":[["StartTag", "a", {"a":"-"}]]},
+
+{"description":"<a a=/>",
+"input":"<a a=/>",
+"output":[["StartTag", "a", {"a":"/"}]]},
+
+{"description":"<a a=0>",
+"input":"<a a=0>",
+"output":[["StartTag", "a", {"a":"0"}]]},
+
+{"description":"<a a=1>",
+"input":"<a a=1>",
+"output":[["StartTag", "a", {"a":"1"}]]},
+
+{"description":"<a a=9>",
+"input":"<a a=9>",
+"output":[["StartTag", "a", {"a":"9"}]]},
+
+{"description":"<a a=<>",
+"input":"<a a=<>",
+"output":["ParseError", ["StartTag", "a", {"a":"<"}]]},
+
+{"description":"<a a==>",
+"input":"<a a==>",
+"output":["ParseError", ["StartTag", "a", {"a":"="}]]},
+
+{"description":"<a a=>",
+"input":"<a a=>",
+"output":["ParseError", ["StartTag", "a", {"a":""}]]},
+
+{"description":"<a a=?>",
+"input":"<a a=?>",
+"output":[["StartTag", "a", {"a":"?"}]]},
+
+{"description":"<a a=@>",
+"input":"<a a=@>",
+"output":[["StartTag", "a", {"a":"@"}]]},
+
+{"description":"<a a=A>",
+"input":"<a a=A>",
+"output":[["StartTag", "a", {"a":"A"}]]},
+
+{"description":"<a a=B>",
+"input":"<a a=B>",
+"output":[["StartTag", "a", {"a":"B"}]]},
+
+{"description":"<a a=Y>",
+"input":"<a a=Y>",
+"output":[["StartTag", "a", {"a":"Y"}]]},
+
+{"description":"<a a=Z>",
+"input":"<a a=Z>",
+"output":[["StartTag", "a", {"a":"Z"}]]},
+
+{"description":"<a a=`>",
+"input":"<a a=`>",
+"output":["ParseError", ["StartTag", "a", {"a":"`"}]]},
+
+{"description":"<a a=a>",
+"input":"<a a=a>",
+"output":[["StartTag", "a", {"a":"a"}]]},
+
+{"description":"<a a=a\\u0000>",
+"input":"<a a=a\u0000>",
+"output":["ParseError", ["StartTag", "a", {"a":"a\uFFFD"}]]},
+
+{"description":"<a a=a\\u0008>",
+"input":"<a a=a\u0008>",
+"output":["ParseError", ["StartTag", "a", {"a":"a\u0008"}]]},
+
+{"description":"<a a=a\\u0009>",
+"input":"<a a=a\u0009>",
+"output":[["StartTag", "a", {"a":"a"}]]},
+
+{"description":"<a a=a\\u000A>",
+"input":"<a a=a\u000A>",
+"output":[["StartTag", "a", {"a":"a"}]]},
+
+{"description":"<a a=a\\u000B>",
+"input":"<a a=a\u000B>",
+"output":["ParseError", ["StartTag", "a", {"a":"a\u000B"}]]},
+
+{"description":"<a a=a\\u000C>",
+"input":"<a a=a\u000C>",
+"output":[["StartTag", "a", {"a":"a"}]]},
+
+{"description":"<a a=a\\u000D>",
+"input":"<a a=a\u000D>",
+"output":[["StartTag", "a", {"a":"a"}]]},
+
+{"description":"<a a=a\\u001F>",
+"input":"<a a=a\u001F>",
+"output":["ParseError", ["StartTag", "a", {"a":"a\u001F"}]]},
+
+{"description":"<a a=a >",
+"input":"<a a=a >",
+"output":[["StartTag", "a", {"a":"a"}]]},
+
+{"description":"<a a=a!>",
+"input":"<a a=a!>",
+"output":[["StartTag", "a", {"a":"a!"}]]},
+
+{"description":"<a a=a\">",
+"input":"<a a=a\">",
+"output":["ParseError", ["StartTag", "a", {"a":"a\""}]]},
+
+{"description":"<a a=a#>",
+"input":"<a a=a#>",
+"output":[["StartTag", "a", {"a":"a#"}]]},
+
+{"description":"<a a=a%>",
+"input":"<a a=a%>",
+"output":[["StartTag", "a", {"a":"a%"}]]},
+
+{"description":"<a a=a&>",
+"input":"<a a=a&>",
+"output":[["StartTag", "a", {"a":"a&"}]]},
+
+{"description":"<a a=a'>",
+"input":"<a a=a'>",
+"output":["ParseError", ["StartTag", "a", {"a":"a'"}]]},
+
+{"description":"<a a=a(>",
+"input":"<a a=a(>",
+"output":[["StartTag", "a", {"a":"a("}]]},
+
+{"description":"<a a=a->",
+"input":"<a a=a->",
+"output":[["StartTag", "a", {"a":"a-"}]]},
+
+{"description":"<a a=a/>",
+"input":"<a a=a/>",
+"output":[["StartTag", "a", {"a":"a/"}]]},
+
+{"description":"<a a=a0>",
+"input":"<a a=a0>",
+"output":[["StartTag", "a", {"a":"a0"}]]},
+
+{"description":"<a a=a1>",
+"input":"<a a=a1>",
+"output":[["StartTag", "a", {"a":"a1"}]]},
+
+{"description":"<a a=a9>",
+"input":"<a a=a9>",
+"output":[["StartTag", "a", {"a":"a9"}]]},
+
+{"description":"<a a=a<>",
+"input":"<a a=a<>",
+"output":["ParseError", ["StartTag", "a", {"a":"a<"}]]},
+
+{"description":"<a a=a=>",
+"input":"<a a=a=>",
+"output":["ParseError", ["StartTag", "a", {"a":"a="}]]},
+
+{"description":"<a a=a>",
+"input":"<a a=a>",
+"output":[["StartTag", "a", {"a":"a"}]]},
+
+{"description":"<a a=a?>",
+"input":"<a a=a?>",
+"output":[["StartTag", "a", {"a":"a?"}]]},
+
+{"description":"<a a=a@>",
+"input":"<a a=a@>",
+"output":[["StartTag", "a", {"a":"a@"}]]},
+
+{"description":"<a a=aA>",
+"input":"<a a=aA>",
+"output":[["StartTag", "a", {"a":"aA"}]]},
+
+{"description":"<a a=aB>",
+"input":"<a a=aB>",
+"output":[["StartTag", "a", {"a":"aB"}]]},
+
+{"description":"<a a=aY>",
+"input":"<a a=aY>",
+"output":[["StartTag", "a", {"a":"aY"}]]},
+
+{"description":"<a a=aZ>",
+"input":"<a a=aZ>",
+"output":[["StartTag", "a", {"a":"aZ"}]]},
+
+{"description":"<a a=a`>",
+"input":"<a a=a`>",
+"output":["ParseError", ["StartTag", "a", {"a":"a`"}]]},
+
+{"description":"<a a=aa>",
+"input":"<a a=aa>",
+"output":[["StartTag", "a", {"a":"aa"}]]},
+
+{"description":"<a a=ab>",
+"input":"<a a=ab>",
+"output":[["StartTag", "a", {"a":"ab"}]]},
+
+{"description":"<a a=ay>",
+"input":"<a a=ay>",
+"output":[["StartTag", "a", {"a":"ay"}]]},
+
+{"description":"<a a=az>",
+"input":"<a a=az>",
+"output":[["StartTag", "a", {"a":"az"}]]},
+
+{"description":"<a a=a{>",
+"input":"<a a=a{>",
+"output":[["StartTag", "a", {"a":"a{"}]]},
+
+{"description":"<a a=a\\uDBC0\\uDC00>",
+"input":"<a a=a\uDBC0\uDC00>",
+"output":[["StartTag", "a", {"a":"a\uDBC0\uDC00"}]]},
+
+{"description":"<a a=b>",
+"input":"<a a=b>",
+"output":[["StartTag", "a", {"a":"b"}]]},
+
+{"description":"<a a=y>",
+"input":"<a a=y>",
+"output":[["StartTag", "a", {"a":"y"}]]},
+
+{"description":"<a a=z>",
+"input":"<a a=z>",
+"output":[["StartTag", "a", {"a":"z"}]]},
+
+{"description":"<a a={>",
+"input":"<a a={>",
+"output":[["StartTag", "a", {"a":"{"}]]},
+
+{"description":"<a a=\\uDBC0\\uDC00>",
+"input":"<a a=\uDBC0\uDC00>",
+"output":[["StartTag", "a", {"a":"\uDBC0\uDC00"}]]},
+
+{"description":"<a a>",
+"input":"<a a>",
+"output":[["StartTag", "a", {"a":""}]]},
+
+{"description":"<a a?>",
+"input":"<a a?>",
+"output":[["StartTag", "a", {"a?":""}]]},
+
+{"description":"<a a@>",
+"input":"<a a@>",
+"output":[["StartTag", "a", {"a@":""}]]},
+
+{"description":"<a aA>",
+"input":"<a aA>",
+"output":[["StartTag", "a", {"aa":""}]]},
+
+{"description":"<a aB>",
+"input":"<a aB>",
+"output":[["StartTag", "a", {"ab":""}]]},
+
+{"description":"<a aY>",
+"input":"<a aY>",
+"output":[["StartTag", "a", {"ay":""}]]},
+
+{"description":"<a aZ>",
+"input":"<a aZ>",
+"output":[["StartTag", "a", {"az":""}]]},
+
+{"description":"<a a[>",
+"input":"<a a[>",
+"output":[["StartTag", "a", {"a[":""}]]},
+
+{"description":"<a a`>",
+"input":"<a a`>",
+"output":[["StartTag", "a", {"a`":""}]]},
+
+{"description":"<a aa>",
+"input":"<a aa>",
+"output":[["StartTag", "a", {"aa":""}]]},
+
+{"description":"<a ab>",
+"input":"<a ab>",
+"output":[["StartTag", "a", {"ab":""}]]},
+
+{"description":"<a ay>",
+"input":"<a ay>",
+"output":[["StartTag", "a", {"ay":""}]]},
+
+{"description":"<a az>",
+"input":"<a az>",
+"output":[["StartTag", "a", {"az":""}]]},
+
+{"description":"<a a{>",
+"input":"<a a{>",
+"output":[["StartTag", "a", {"a{":""}]]},
+
+{"description":"<a a\\uDBC0\\uDC00>",
+"input":"<a a\uDBC0\uDC00>",
+"output":[["StartTag", "a", {"a\uDBC0\uDC00":""}]]},
+
+{"description":"<a b>",
+"input":"<a b>",
+"output":[["StartTag", "a", {"b":""}]]},
+
+{"description":"<a y>",
+"input":"<a y>",
+"output":[["StartTag", "a", {"y":""}]]},
+
+{"description":"<a z>",
+"input":"<a z>",
+"output":[["StartTag", "a", {"z":""}]]},
+
+{"description":"<a {>",
+"input":"<a {>",
+"output":[["StartTag", "a", {"{":""}]]},
+
+{"description":"<a \\uDBC0\\uDC00>",
+"input":"<a \uDBC0\uDC00>",
+"output":[["StartTag", "a", {"\uDBC0\uDC00":""}]]},
+
+{"description":"<a!>",
+"input":"<a!>",
+"output":[["StartTag", "a!", {}]]},
+
+{"description":"<a\">",
+"input":"<a\">",
+"output":[["StartTag", "a\"", {}]]},
+
+{"description":"<a&>",
+"input":"<a&>",
+"output":[["StartTag", "a&", {}]]},
+
+{"description":"<a'>",
+"input":"<a'>",
+"output":[["StartTag", "a'", {}]]},
+
+{"description":"<a->",
+"input":"<a->",
+"output":[["StartTag", "a-", {}]]},
+
+{"description":"<a.>",
+"input":"<a.>",
+"output":[["StartTag", "a.", {}]]},
+
+{"description":"<a/>",
+"input":"<a/>",
+"output":[["StartTag", "a", {}, true]]},
+
+{"description":"<a/\\u0000>",
+"input":"<a/\u0000>",
+"output":["ParseError", "ParseError", ["StartTag", "a", {"\uFFFD":""}]]},
+
+{"description":"<a/\\u0009>",
+"input":"<a/\u0009>",
+"output":["ParseError", ["StartTag", "a", {}]]},
+
+{"description":"<a/\\u000A>",
+"input":"<a/\u000A>",
+"output":["ParseError", ["StartTag", "a", {}]]},
+
+{"description":"<a/\\u000B>",
+"input":"<a/\u000B>",
+"output":["ParseError", "ParseError", ["StartTag", "a", {"\u000B":""}]]},
+
+{"description":"<a/\\u000C>",
+"input":"<a/\u000C>",
+"output":["ParseError", ["StartTag", "a", {}]]},
+
+{"description":"<a/ >",
+"input":"<a/ >",
+"output":["ParseError", ["StartTag", "a", {}]]},
+
+{"description":"<a/!>",
+"input":"<a/!>",
+"output":["ParseError", ["StartTag", "a", {"!":""}]]},
+
+{"description":"<a/\">",
+"input":"<a/\">",
+"output":["ParseError", "ParseError", ["StartTag", "a", {"\"":""}]]},
+
+{"description":"<a/&>",
+"input":"<a/&>",
+"output":["ParseError", ["StartTag", "a", {"&":""}]]},
+
+{"description":"<a/'>",
+"input":"<a/'>",
+"output":["ParseError", "ParseError", ["StartTag", "a", {"'":""}]]},
+
+{"description":"<a/->",
+"input":"<a/->",
+"output":["ParseError", ["StartTag", "a", {"-":""}]]},
+
+{"description":"<a//>",
+"input":"<a//>",
+"output":["ParseError", ["StartTag", "a", {}, true]]},
+
+{"description":"<a/0>",
+"input":"<a/0>",
+"output":["ParseError", ["StartTag", "a", {"0":""}]]},
+
+{"description":"<a/1>",
+"input":"<a/1>",
+"output":["ParseError", ["StartTag", "a", {"1":""}]]},
+
+{"description":"<a/9>",
+"input":"<a/9>",
+"output":["ParseError", ["StartTag", "a", {"9":""}]]},
+
+{"description":"<a/<>",
+"input":"<a/<>",
+"output":["ParseError", "ParseError", ["StartTag", "a", {"<":""}]]},
+
+{"description":"<a/=>",
+"input":"<a/=>",
+"output":["ParseError", "ParseError", ["StartTag", "a", {"=":""}]]},
+
+{"description":"<a/>",
+"input":"<a/>",
+"output":[["StartTag", "a", {}, true]]},
+
+{"description":"<a/?>",
+"input":"<a/?>",
+"output":["ParseError", ["StartTag", "a", {"?":""}]]},
+
+{"description":"<a/@>",
+"input":"<a/@>",
+"output":["ParseError", ["StartTag", "a", {"@":""}]]},
+
+{"description":"<a/A>",
+"input":"<a/A>",
+"output":["ParseError", ["StartTag", "a", {"a":""}]]},
+
+{"description":"<a/B>",
+"input":"<a/B>",
+"output":["ParseError", ["StartTag", "a", {"b":""}]]},
+
+{"description":"<a/Y>",
+"input":"<a/Y>",
+"output":["ParseError", ["StartTag", "a", {"y":""}]]},
+
+{"description":"<a/Z>",
+"input":"<a/Z>",
+"output":["ParseError", ["StartTag", "a", {"z":""}]]},
+
+{"description":"<a/`>",
+"input":"<a/`>",
+"output":["ParseError", ["StartTag", "a", {"`":""}]]},
+
+{"description":"<a/a>",
+"input":"<a/a>",
+"output":["ParseError", ["StartTag", "a", {"a":""}]]},
+
+{"description":"<a/b>",
+"input":"<a/b>",
+"output":["ParseError", ["StartTag", "a", {"b":""}]]},
+
+{"description":"<a/y>",
+"input":"<a/y>",
+"output":["ParseError", ["StartTag", "a", {"y":""}]]},
+
+{"description":"<a/z>",
+"input":"<a/z>",
+"output":["ParseError", ["StartTag", "a", {"z":""}]]},
+
+{"description":"<a/{>",
+"input":"<a/{>",
+"output":["ParseError", ["StartTag", "a", {"{":""}]]},
+
+{"description":"<a/\\uDBC0\\uDC00>",
+"input":"<a/\uDBC0\uDC00>",
+"output":["ParseError", ["StartTag", "a", {"\uDBC0\uDC00":""}]]},
+
+{"description":"<a0>",
+"input":"<a0>",
+"output":[["StartTag", "a0", {}]]},
+
+{"description":"<a1>",
+"input":"<a1>",
+"output":[["StartTag", "a1", {}]]},
+
+{"description":"<a9>",
+"input":"<a9>",
+"output":[["StartTag", "a9", {}]]},
+
+{"description":"<a<>",
+"input":"<a<>",
+"output":[["StartTag", "a<", {}]]},
+
+{"description":"<a=>",
+"input":"<a=>",
+"output":[["StartTag", "a=", {}]]},
+
+{"description":"<a>",
+"input":"<a>",
+"output":[["StartTag", "a", {}]]},
+
+{"description":"<a?>",
+"input":"<a?>",
+"output":[["StartTag", "a?", {}]]},
+
+{"description":"<a@>",
+"input":"<a@>",
+"output":[["StartTag", "a@", {}]]},
+
+{"description":"<aA>",
+"input":"<aA>",
+"output":[["StartTag", "aa", {}]]},
+
+{"description":"<aB>",
+"input":"<aB>",
+"output":[["StartTag", "ab", {}]]},
+
+{"description":"<aY>",
+"input":"<aY>",
+"output":[["StartTag", "ay", {}]]},
+
+{"description":"<aZ>",
+"input":"<aZ>",
+"output":[["StartTag", "az", {}]]},
+
+{"description":"<a[>",
+"input":"<a[>",
+"output":[["StartTag", "a[", {}]]},
+
+{"description":"<a`>",
+"input":"<a`>",
+"output":[["StartTag", "a`", {}]]},
+
+{"description":"<aa>",
+"input":"<aa>",
+"output":[["StartTag", "aa", {}]]},
+
+{"description":"<ab>",
+"input":"<ab>",
+"output":[["StartTag", "ab", {}]]},
+
+{"description":"<ay>",
+"input":"<ay>",
+"output":[["StartTag", "ay", {}]]},
+
+{"description":"<az>",
+"input":"<az>",
+"output":[["StartTag", "az", {}]]},
+
+{"description":"<a{>",
+"input":"<a{>",
+"output":[["StartTag", "a{", {}]]},
+
+{"description":"<a\\uDBC0\\uDC00>",
+"input":"<a\uDBC0\uDC00>",
+"output":[["StartTag", "a\uDBC0\uDC00", {}]]},
+
+{"description":"<b>",
+"input":"<b>",
+"output":[["StartTag", "b", {}]]},
+
+{"description":"<y>",
+"input":"<y>",
+"output":[["StartTag", "y", {}]]},
+
+{"description":"<z>",
+"input":"<z>",
+"output":[["StartTag", "z", {}]]},
+
+{"description":"<{",
+"input":"<{",
+"output":["ParseError", ["Character", "<{"]]},
+
+{"description":"<\\uDBC0\\uDC00",
+"input":"<\uDBC0\uDC00",
+"output":["ParseError", ["Character", "<\uDBC0\uDC00"]]},
+
+{"description":"=",
+"input":"=",
+"output":[["Character", "="]]},
+
+{"description":">",
+"input":">",
+"output":[["Character", ">"]]},
+
+{"description":"?",
+"input":"?",
+"output":[["Character", "?"]]},
+
+{"description":"@",
+"input":"@",
+"output":[["Character", "@"]]},
+
+{"description":"A",
+"input":"A",
+"output":[["Character", "A"]]},
+
+{"description":"B",
+"input":"B",
+"output":[["Character", "B"]]},
+
+{"description":"Y",
+"input":"Y",
+"output":[["Character", "Y"]]},
+
+{"description":"Z",
+"input":"Z",
+"output":[["Character", "Z"]]},
+
+{"description":"`",
+"input":"`",
+"output":[["Character", "`"]]},
+
+{"description":"a",
+"input":"a",
+"output":[["Character", "a"]]},
+
+{"description":"b",
+"input":"b",
+"output":[["Character", "b"]]},
+
+{"description":"y",
+"input":"y",
+"output":[["Character", "y"]]},
+
+{"description":"z",
+"input":"z",
+"output":[["Character", "z"]]},
+
+{"description":"{",
+"input":"{",
+"output":[["Character", "{"]]},
+
+{"description":"\\uDBC0\\uDC00",
+"input":"\uDBC0\uDC00",
+"output":[["Character", "\uDBC0\uDC00"]]}
+
+]}
diff --git a/html/test/data/tokenizer/test4.test b/html/test/data/tokenizer/test4.test
new file mode 100644
index 0000000..80f859e
--- /dev/null
+++ b/html/test/data/tokenizer/test4.test
@@ -0,0 +1,344 @@
+{"tests": [
+
+{"description":"< in attribute name",
+"input":"<z/0  <>",
+"output":["ParseError", "ParseError", ["StartTag", "z", {"0": "", "<": ""}]]},
+
+{"description":"< in attribute value",
+"input":"<z x=<>",
+"output":["ParseError", ["StartTag", "z", {"x": "<"}]]},
+
+{"description":"= in unquoted attribute value",
+"input":"<z z=z=z>",
+"output":["ParseError", ["StartTag", "z", {"z": "z=z"}]]},
+
+{"description":"= attribute",
+"input":"<z =>",
+"output":["ParseError", ["StartTag", "z", {"=": ""}]]},
+
+{"description":"== attribute",
+"input":"<z ==>",
+"output":["ParseError", "ParseError", ["StartTag", "z", {"=": ""}]]},
+
+{"description":"=== attribute",
+"input":"<z ===>",
+"output":["ParseError", "ParseError", ["StartTag", "z", {"=": "="}]]},
+
+{"description":"==== attribute",
+"input":"<z ====>",
+"output":["ParseError", "ParseError", "ParseError", ["StartTag", "z", {"=": "=="}]]},
+
+{"description":"Allowed \" after ampersand in attribute value",
+"input":"<z z=\"&\">",
+"output":[["StartTag", "z", {"z": "&"}]]},
+
+{"description":"Non-allowed ' after ampersand in attribute value",
+"input":"<z z=\"&'\">",
+"output":["ParseError", ["StartTag", "z", {"z": "&'"}]]},
+
+{"description":"Allowed ' after ampersand in attribute value",
+"input":"<z z='&'>",
+"output":[["StartTag", "z", {"z": "&"}]]},
+
+{"description":"Non-allowed \" after ampersand in attribute value",
+"input":"<z z='&\"'>",
+"output":["ParseError", ["StartTag", "z", {"z": "&\""}]]},
+
+{"description":"Text after bogus character reference",
+"input":"<z z='&xlink_xmlns;'>bar<z>",
+"output":["ParseError",["StartTag","z",{"z":"&xlink_xmlns;"}],["Character","bar"],["StartTag","z",{}]]},
+
+{"description":"Text after hex character reference",
+"input":"<z z='&#x0020; foo'>bar<z>",
+"output":[["StartTag","z",{"z":"  foo"}],["Character","bar"],["StartTag","z",{}]]},
+
+{"description":"Attribute name starting with \"",
+"input":"<foo \"='bar'>",
+"output":["ParseError", ["StartTag", "foo", {"\"": "bar"}]]},
+
+{"description":"Attribute name starting with '",
+"input":"<foo '='bar'>",
+"output":["ParseError", ["StartTag", "foo", {"'": "bar"}]]},
+
+{"description":"Attribute name containing \"",
+"input":"<foo a\"b='bar'>",
+"output":["ParseError", ["StartTag", "foo", {"a\"b": "bar"}]]},
+
+{"description":"Attribute name containing '",
+"input":"<foo a'b='bar'>",
+"output":["ParseError", ["StartTag", "foo", {"a'b": "bar"}]]},
+
+{"description":"Unquoted attribute value containing '",
+"input":"<foo a=b'c>",
+"output":["ParseError", ["StartTag", "foo", {"a": "b'c"}]]},
+
+{"description":"Unquoted attribute value containing \"",
+"input":"<foo a=b\"c>",
+"output":["ParseError", ["StartTag", "foo", {"a": "b\"c"}]]},
+
+{"description":"Double-quoted attribute value not followed by whitespace",
+"input":"<foo a=\"b\"c>",
+"output":["ParseError", ["StartTag", "foo", {"a": "b", "c": ""}]]},
+
+{"description":"Single-quoted attribute value not followed by whitespace",
+"input":"<foo a='b'c>",
+"output":["ParseError", ["StartTag", "foo", {"a": "b", "c": ""}]]},
+
+{"description":"Quoted attribute followed by permitted /",
+"input":"<br a='b'/>",
+"output":[["StartTag","br",{"a":"b"},true]]},
+
+{"description":"Quoted attribute followed by non-permitted /",
+"input":"<bar a='b'/>",
+"output":[["StartTag","bar",{"a":"b"},true]]},
+
+{"description":"CR EOF after doctype name",
+"input":"<!doctype html \r",
+"output":["ParseError", ["DOCTYPE", "html", null, null, false]]},
+
+{"description":"CR EOF in tag name",
+"input":"<z\r",
+"output":["ParseError"]},
+
+{"description":"Slash EOF in tag name",
+"input":"<z/",
+"output":["ParseError"]},
+
+{"description":"Zero hex numeric entity",
+"input":"&#x0",
+"output":["ParseError", "ParseError", ["Character", "\uFFFD"]]},
+
+{"description":"Zero decimal numeric entity",
+"input":"&#0",
+"output":["ParseError", "ParseError", ["Character", "\uFFFD"]]},
+
+{"description":"Zero-prefixed hex numeric entity",
+"input":"&#x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000041;",
+"output":[["Character", "A"]]},
+
+{"description":"Zero-prefixed decimal numeric entity",
+"input":"&#000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000065;",
+"output":[["Character", "A"]]},
+
+{"description":"Empty hex numeric entities",
+"input":"&#x &#X ",
+"output":["ParseError", ["Character", "&#x "], "ParseError", ["Character", "&#X "]]},
+
+{"description":"Empty decimal numeric entities",
+"input":"&# &#; ",
+"output":["ParseError", ["Character", "&# "], "ParseError", ["Character", "&#; "]]},
+
+{"description":"Non-BMP numeric entity",
+"input":"&#x10000;",
+"output":[["Character", "\uD800\uDC00"]]},
+
+{"description":"Maximum non-BMP numeric entity",
+"input":"&#X10FFFF;",
+"output":["ParseError", ["Character", "\uDBFF\uDFFF"]]},
+
+{"description":"Above maximum numeric entity",
+"input":"&#x110000;",
+"output":["ParseError", ["Character", "\uFFFD"]]},
+
+{"description":"32-bit hex numeric entity",
+"input":"&#x80000041;",
+"output":["ParseError", ["Character", "\uFFFD"]]},
+
+{"description":"33-bit hex numeric entity",
+"input":"&#x100000041;",
+"output":["ParseError", ["Character", "\uFFFD"]]},
+
+{"description":"33-bit decimal numeric entity",
+"input":"&#4294967361;",
+"output":["ParseError", ["Character", "\uFFFD"]]},
+
+{"description":"65-bit hex numeric entity",
+"input":"&#x10000000000000041;",
+"output":["ParseError", ["Character", "\uFFFD"]]},
+
+{"description":"65-bit decimal numeric entity",
+"input":"&#18446744073709551681;",
+"output":["ParseError", ["Character", "\uFFFD"]]},
+
+{"description":"Surrogate code point edge cases",
+"input":"&#xD7FF;&#xD800;&#xD801;&#xDFFE;&#xDFFF;&#xE000;",
+"output":[["Character", "\uD7FF"], "ParseError", ["Character", "\uFFFD"], "ParseError", ["Character", "\uFFFD"], "ParseError", ["Character", "\uFFFD"], "ParseError", ["Character", "\uFFFD\uE000"]]},
+
+{"description":"Uppercase start tag name",
+"input":"<X>",
+"output":[["StartTag", "x", {}]]},
+
+{"description":"Uppercase end tag name",
+"input":"</X>",
+"output":[["EndTag", "x"]]},
+
+{"description":"Uppercase attribute name",
+"input":"<x X>",
+"output":[["StartTag", "x", { "x":"" }]]},
+
+{"description":"Tag/attribute name case edge values",
+"input":"<x@AZ[`az{ @AZ[`az{>",
+"output":[["StartTag", "x@az[`az{", { "@az[`az{":"" }]]},
+
+{"description":"Duplicate different-case attributes",
+"input":"<x x=1 x=2 X=3>",
+"output":["ParseError", "ParseError", ["StartTag", "x", { "x":"1" }]]},
+
+{"description":"Uppercase close tag attributes",
+"input":"</x X>",
+"output":["ParseError", ["EndTag", "x"]]},
+
+{"description":"Duplicate close tag attributes",
+"input":"</x x x>",
+"output":["ParseError", "ParseError", ["EndTag", "x"]]},
+
+{"description":"Permitted slash",
+"input":"<br/>",
+"output":[["StartTag","br",{},true]]},
+
+{"description":"Non-permitted slash",
+"input":"<xr/>",
+"output":[["StartTag","xr",{},true]]},
+
+{"description":"Permitted slash but in close tag",
+"input":"</br/>",
+"output":["ParseError", ["EndTag", "br"]]},
+
+{"description":"Doctype public case-sensitivity (1)",
+"input":"<!DoCtYpE HtMl PuBlIc \"AbC\" \"XyZ\">",
+"output":[["DOCTYPE", "html", "AbC", "XyZ", true]]},
+
+{"description":"Doctype public case-sensitivity (2)",
+"input":"<!dOcTyPe hTmL pUbLiC \"aBc\" \"xYz\">",
+"output":[["DOCTYPE", "html", "aBc", "xYz", true]]},
+
+{"description":"Doctype system case-sensitivity (1)",
+"input":"<!DoCtYpE HtMl SyStEm \"XyZ\">",
+"output":[["DOCTYPE", "html", null, "XyZ", true]]},
+
+{"description":"Doctype system case-sensitivity (2)",
+"input":"<!dOcTyPe hTmL sYsTeM \"xYz\">",
+"output":[["DOCTYPE", "html", null, "xYz", true]]},
+
+{"description":"U+0000 in lookahead region after non-matching character",
+"input":"<!doc>\u0000",
+"output":["ParseError", ["Comment", "doc"], "ParseError", ["Character", "\u0000"]],
+"ignoreErrorOrder":true},
+
+{"description":"U+0000 in lookahead region",
+"input":"<!doc\u0000",
+"output":["ParseError", ["Comment", "doc\uFFFD"]],
+"ignoreErrorOrder":true},
+
+{"description":"U+0080 in lookahead region",
+"input":"<!doc\u0080",
+"output":["ParseError", "ParseError", ["Comment", "doc\u0080"]],
+"ignoreErrorOrder":true},
+
+{"description":"U+FDD1 in lookahead region",
+"input":"<!doc\uFDD1",
+"output":["ParseError", "ParseError", ["Comment", "doc\uFDD1"]],
+"ignoreErrorOrder":true},
+
+{"description":"U+1FFFF in lookahead region",
+"input":"<!doc\uD83F\uDFFF",
+"output":["ParseError", "ParseError", ["Comment", "doc\uD83F\uDFFF"]],
+"ignoreErrorOrder":true},
+
+{"description":"CR followed by non-LF",
+"input":"\r?",
+"output":[["Character", "\n?"]]},
+
+{"description":"CR at EOF",
+"input":"\r",
+"output":[["Character", "\n"]]},
+
+{"description":"LF at EOF",
+"input":"\n",
+"output":[["Character", "\n"]]},
+
+{"description":"CR LF",
+"input":"\r\n",
+"output":[["Character", "\n"]]},
+
+{"description":"CR CR",
+"input":"\r\r",
+"output":[["Character", "\n\n"]]},
+
+{"description":"LF LF",
+"input":"\n\n",
+"output":[["Character", "\n\n"]]},
+
+{"description":"LF CR",
+"input":"\n\r",
+"output":[["Character", "\n\n"]]},
+
+{"description":"text CR CR CR text",
+"input":"text\r\r\rtext",
+"output":[["Character", "text\n\n\ntext"]]},
+
+{"description":"Doctype publik",
+"input":"<!DOCTYPE html PUBLIK \"AbC\" \"XyZ\">",
+"output":["ParseError", ["DOCTYPE", "html", null, null, false]]},
+
+{"description":"Doctype publi",
+"input":"<!DOCTYPE html PUBLI",
+"output":["ParseError", ["DOCTYPE", "html", null, null, false]]},
+
+{"description":"Doctype sistem",
+"input":"<!DOCTYPE html SISTEM \"AbC\">",
+"output":["ParseError", ["DOCTYPE", "html", null, null, false]]},
+
+{"description":"Doctype sys",
+"input":"<!DOCTYPE html SYS",
+"output":["ParseError", ["DOCTYPE", "html", null, null, false]]},
+
+{"description":"Doctype html x>text",
+"input":"<!DOCTYPE html x>text",
+"output":["ParseError", ["DOCTYPE", "html", null, null, false], ["Character", "text"]]},
+
+{"description":"Grave accent in unquoted attribute",
+"input":"<a a=aa`>",
+"output":["ParseError", ["StartTag", "a", {"a":"aa`"}]]},
+
+{"description":"EOF in tag name state ",
+"input":"<a",
+"output":["ParseError"]},
+
+{"description":"EOF in tag name state",
+"input":"<a",
+"output":["ParseError"]},
+
+{"description":"EOF in before attribute name state",
+"input":"<a ",
+"output":["ParseError"]},
+
+{"description":"EOF in attribute name state",
+"input":"<a a",
+"output":["ParseError"]},
+
+{"description":"EOF in after attribute name state",
+"input":"<a a ",
+"output":["ParseError"]},
+
+{"description":"EOF in before attribute value state",
+"input":"<a a =",
+"output":["ParseError"]},
+
+{"description":"EOF in attribute value (double quoted) state",
+"input":"<a a =\"a",
+"output":["ParseError"]},
+
+{"description":"EOF in attribute value (single quoted) state",
+"input":"<a a ='a",
+"output":["ParseError"]},
+
+{"description":"EOF in attribute value (unquoted) state",
+"input":"<a a =a",
+"output":["ParseError"]},
+
+{"description":"EOF in after attribute value state",
+"input":"<a a ='a'",
+"output":["ParseError"]}
+
+]}
diff --git a/html/test/data/tokenizer/unicodeChars.test b/html/test/data/tokenizer/unicodeChars.test
new file mode 100644
index 0000000..c778668
--- /dev/null
+++ b/html/test/data/tokenizer/unicodeChars.test
@@ -0,0 +1,1295 @@
+{"tests": [
+
+{"description": "Invalid Unicode character U+0001",
+"input": "\u0001",
+"output": ["ParseError", ["Character", "\u0001"]]},
+
+{"description": "Invalid Unicode character U+0002",
+"input": "\u0002",
+"output": ["ParseError", ["Character", "\u0002"]]},
+
+{"description": "Invalid Unicode character U+0003",
+"input": "\u0003",
+"output": ["ParseError", ["Character", "\u0003"]]},
+
+{"description": "Invalid Unicode character U+0004",
+"input": "\u0004",
+"output": ["ParseError", ["Character", "\u0004"]]},
+
+{"description": "Invalid Unicode character U+0005",
+"input": "\u0005",
+"output": ["ParseError", ["Character", "\u0005"]]},
+
+{"description": "Invalid Unicode character U+0006",
+"input": "\u0006",
+"output": ["ParseError", ["Character", "\u0006"]]},
+
+{"description": "Invalid Unicode character U+0007",
+"input": "\u0007",
+"output": ["ParseError", ["Character", "\u0007"]]},
+
+{"description": "Invalid Unicode character U+0008",
+"input": "\u0008",
+"output": ["ParseError", ["Character", "\u0008"]]},
+
+{"description": "Invalid Unicode character U+000B",
+"input": "\u000B",
+"output": ["ParseError", ["Character", "\u000B"]]},
+
+{"description": "Invalid Unicode character U+000E",
+"input": "\u000E",
+"output": ["ParseError", ["Character", "\u000E"]]},
+
+{"description": "Invalid Unicode character U+000F",
+"input": "\u000F",
+"output": ["ParseError", ["Character", "\u000F"]]},
+
+{"description": "Invalid Unicode character U+0010",
+"input": "\u0010",
+"output": ["ParseError", ["Character", "\u0010"]]},
+
+{"description": "Invalid Unicode character U+0011",
+"input": "\u0011",
+"output": ["ParseError", ["Character", "\u0011"]]},
+
+{"description": "Invalid Unicode character U+0012",
+"input": "\u0012",
+"output": ["ParseError", ["Character", "\u0012"]]},
+
+{"description": "Invalid Unicode character U+0013",
+"input": "\u0013",
+"output": ["ParseError", ["Character", "\u0013"]]},
+
+{"description": "Invalid Unicode character U+0014",
+"input": "\u0014",
+"output": ["ParseError", ["Character", "\u0014"]]},
+
+{"description": "Invalid Unicode character U+0015",
+"input": "\u0015",
+"output": ["ParseError", ["Character", "\u0015"]]},
+
+{"description": "Invalid Unicode character U+0016",
+"input": "\u0016",
+"output": ["ParseError", ["Character", "\u0016"]]},
+
+{"description": "Invalid Unicode character U+0017",
+"input": "\u0017",
+"output": ["ParseError", ["Character", "\u0017"]]},
+
+{"description": "Invalid Unicode character U+0018",
+"input": "\u0018",
+"output": ["ParseError", ["Character", "\u0018"]]},
+
+{"description": "Invalid Unicode character U+0019",
+"input": "\u0019",
+"output": ["ParseError", ["Character", "\u0019"]]},
+
+{"description": "Invalid Unicode character U+001A",
+"input": "\u001A",
+"output": ["ParseError", ["Character", "\u001A"]]},
+
+{"description": "Invalid Unicode character U+001B",
+"input": "\u001B",
+"output": ["ParseError", ["Character", "\u001B"]]},
+
+{"description": "Invalid Unicode character U+001C",
+"input": "\u001C",
+"output": ["ParseError", ["Character", "\u001C"]]},
+
+{"description": "Invalid Unicode character U+001D",
+"input": "\u001D",
+"output": ["ParseError", ["Character", "\u001D"]]},
+
+{"description": "Invalid Unicode character U+001E",
+"input": "\u001E",
+"output": ["ParseError", ["Character", "\u001E"]]},
+
+{"description": "Invalid Unicode character U+001F",
+"input": "\u001F",
+"output": ["ParseError", ["Character", "\u001F"]]},
+
+{"description": "Invalid Unicode character U+007F",
+"input": "\u007F",
+"output": ["ParseError", ["Character", "\u007F"]]},
+
+{"description": "Invalid Unicode character U+FDD0",
+"input": "\uFDD0",
+"output": ["ParseError", ["Character", "\uFDD0"]]},
+
+{"description": "Invalid Unicode character U+FDD1",
+"input": "\uFDD1",
+"output": ["ParseError", ["Character", "\uFDD1"]]},
+
+{"description": "Invalid Unicode character U+FDD2",
+"input": "\uFDD2",
+"output": ["ParseError", ["Character", "\uFDD2"]]},
+
+{"description": "Invalid Unicode character U+FDD3",
+"input": "\uFDD3",
+"output": ["ParseError", ["Character", "\uFDD3"]]},
+
+{"description": "Invalid Unicode character U+FDD4",
+"input": "\uFDD4",
+"output": ["ParseError", ["Character", "\uFDD4"]]},
+
+{"description": "Invalid Unicode character U+FDD5",
+"input": "\uFDD5",
+"output": ["ParseError", ["Character", "\uFDD5"]]},
+
+{"description": "Invalid Unicode character U+FDD6",
+"input": "\uFDD6",
+"output": ["ParseError", ["Character", "\uFDD6"]]},
+
+{"description": "Invalid Unicode character U+FDD7",
+"input": "\uFDD7",
+"output": ["ParseError", ["Character", "\uFDD7"]]},
+
+{"description": "Invalid Unicode character U+FDD8",
+"input": "\uFDD8",
+"output": ["ParseError", ["Character", "\uFDD8"]]},
+
+{"description": "Invalid Unicode character U+FDD9",
+"input": "\uFDD9",
+"output": ["ParseError", ["Character", "\uFDD9"]]},
+
+{"description": "Invalid Unicode character U+FDDA",
+"input": "\uFDDA",
+"output": ["ParseError", ["Character", "\uFDDA"]]},
+
+{"description": "Invalid Unicode character U+FDDB",
+"input": "\uFDDB",
+"output": ["ParseError", ["Character", "\uFDDB"]]},
+
+{"description": "Invalid Unicode character U+FDDC",
+"input": "\uFDDC",
+"output": ["ParseError", ["Character", "\uFDDC"]]},
+
+{"description": "Invalid Unicode character U+FDDD",
+"input": "\uFDDD",
+"output": ["ParseError", ["Character", "\uFDDD"]]},
+
+{"description": "Invalid Unicode character U+FDDE",
+"input": "\uFDDE",
+"output": ["ParseError", ["Character", "\uFDDE"]]},
+
+{"description": "Invalid Unicode character U+FDDF",
+"input": "\uFDDF",
+"output": ["ParseError", ["Character", "\uFDDF"]]},
+
+{"description": "Invalid Unicode character U+FDE0",
+"input": "\uFDE0",
+"output": ["ParseError", ["Character", "\uFDE0"]]},
+
+{"description": "Invalid Unicode character U+FDE1",
+"input": "\uFDE1",
+"output": ["ParseError", ["Character", "\uFDE1"]]},
+
+{"description": "Invalid Unicode character U+FDE2",
+"input": "\uFDE2",
+"output": ["ParseError", ["Character", "\uFDE2"]]},
+
+{"description": "Invalid Unicode character U+FDE3",
+"input": "\uFDE3",
+"output": ["ParseError", ["Character", "\uFDE3"]]},
+
+{"description": "Invalid Unicode character U+FDE4",
+"input": "\uFDE4",
+"output": ["ParseError", ["Character", "\uFDE4"]]},
+
+{"description": "Invalid Unicode character U+FDE5",
+"input": "\uFDE5",
+"output": ["ParseError", ["Character", "\uFDE5"]]},
+
+{"description": "Invalid Unicode character U+FDE6",
+"input": "\uFDE6",
+"output": ["ParseError", ["Character", "\uFDE6"]]},
+
+{"description": "Invalid Unicode character U+FDE7",
+"input": "\uFDE7",
+"output": ["ParseError", ["Character", "\uFDE7"]]},
+
+{"description": "Invalid Unicode character U+FDE8",
+"input": "\uFDE8",
+"output": ["ParseError", ["Character", "\uFDE8"]]},
+
+{"description": "Invalid Unicode character U+FDE9",
+"input": "\uFDE9",
+"output": ["ParseError", ["Character", "\uFDE9"]]},
+
+{"description": "Invalid Unicode character U+FDEA",
+"input": "\uFDEA",
+"output": ["ParseError", ["Character", "\uFDEA"]]},
+
+{"description": "Invalid Unicode character U+FDEB",
+"input": "\uFDEB",
+"output": ["ParseError", ["Character", "\uFDEB"]]},
+
+{"description": "Invalid Unicode character U+FDEC",
+"input": "\uFDEC",
+"output": ["ParseError", ["Character", "\uFDEC"]]},
+
+{"description": "Invalid Unicode character U+FDED",
+"input": "\uFDED",
+"output": ["ParseError", ["Character", "\uFDED"]]},
+
+{"description": "Invalid Unicode character U+FDEE",
+"input": "\uFDEE",
+"output": ["ParseError", ["Character", "\uFDEE"]]},
+
+{"description": "Invalid Unicode character U+FDEF",
+"input": "\uFDEF",
+"output": ["ParseError", ["Character", "\uFDEF"]]},
+
+{"description": "Invalid Unicode character U+FFFE",
+"input": "\uFFFE",
+"output": ["ParseError", ["Character", "\uFFFE"]]},
+
+{"description": "Invalid Unicode character U+FFFF",
+"input": "\uFFFF",
+"output": ["ParseError", ["Character", "\uFFFF"]]},
+
+{"description": "Invalid Unicode character U+1FFFE",
+"input": "\uD83F\uDFFE",
+"output": ["ParseError", ["Character", "\uD83F\uDFFE"]]},
+
+{"description": "Invalid Unicode character U+1FFFF",
+"input": "\uD83F\uDFFF",
+"output": ["ParseError", ["Character", "\uD83F\uDFFF"]]},
+
+{"description": "Invalid Unicode character U+2FFFE",
+"input": "\uD87F\uDFFE",
+"output": ["ParseError", ["Character", "\uD87F\uDFFE"]]},
+
+{"description": "Invalid Unicode character U+2FFFF",
+"input": "\uD87F\uDFFF",
+"output": ["ParseError", ["Character", "\uD87F\uDFFF"]]},
+
+{"description": "Invalid Unicode character U+3FFFE",
+"input": "\uD8BF\uDFFE",
+"output": ["ParseError", ["Character", "\uD8BF\uDFFE"]]},
+
+{"description": "Invalid Unicode character U+3FFFF",
+"input": "\uD8BF\uDFFF",
+"output": ["ParseError", ["Character", "\uD8BF\uDFFF"]]},
+
+{"description": "Invalid Unicode character U+4FFFE",
+"input": "\uD8FF\uDFFE",
+"output": ["ParseError", ["Character", "\uD8FF\uDFFE"]]},
+
+{"description": "Invalid Unicode character U+4FFFF",
+"input": "\uD8FF\uDFFF",
+"output": ["ParseError", ["Character", "\uD8FF\uDFFF"]]},
+
+{"description": "Invalid Unicode character U+5FFFE",
+"input": "\uD93F\uDFFE",
+"output": ["ParseError", ["Character", "\uD93F\uDFFE"]]},
+
+{"description": "Invalid Unicode character U+5FFFF",
+"input": "\uD93F\uDFFF",
+"output": ["ParseError", ["Character", "\uD93F\uDFFF"]]},
+
+{"description": "Invalid Unicode character U+6FFFE",
+"input": "\uD97F\uDFFE",
+"output": ["ParseError", ["Character", "\uD97F\uDFFE"]]},
+
+{"description": "Invalid Unicode character U+6FFFF",
+"input": "\uD97F\uDFFF",
+"output": ["ParseError", ["Character", "\uD97F\uDFFF"]]},
+
+{"description": "Invalid Unicode character U+7FFFE",
+"input": "\uD9BF\uDFFE",
+"output": ["ParseError", ["Character", "\uD9BF\uDFFE"]]},
+
+{"description": "Invalid Unicode character U+7FFFF",
+"input": "\uD9BF\uDFFF",
+"output": ["ParseError", ["Character", "\uD9BF\uDFFF"]]},
+
+{"description": "Invalid Unicode character U+8FFFE",
+"input": "\uD9FF\uDFFE",
+"output": ["ParseError", ["Character", "\uD9FF\uDFFE"]]},
+
+{"description": "Invalid Unicode character U+8FFFF",
+"input": "\uD9FF\uDFFF",
+"output": ["ParseError", ["Character", "\uD9FF\uDFFF"]]},
+
+{"description": "Invalid Unicode character U+9FFFE",
+"input": "\uDA3F\uDFFE",
+"output": ["ParseError", ["Character", "\uDA3F\uDFFE"]]},
+
+{"description": "Invalid Unicode character U+9FFFF",
+"input": "\uDA3F\uDFFF",
+"output": ["ParseError", ["Character", "\uDA3F\uDFFF"]]},
+
+{"description": "Invalid Unicode character U+AFFFE",
+"input": "\uDA7F\uDFFE",
+"output": ["ParseError", ["Character", "\uDA7F\uDFFE"]]},
+
+{"description": "Invalid Unicode character U+AFFFF",
+"input": "\uDA7F\uDFFF",
+"output": ["ParseError", ["Character", "\uDA7F\uDFFF"]]},
+
+{"description": "Invalid Unicode character U+BFFFE",
+"input": "\uDABF\uDFFE",
+"output": ["ParseError", ["Character", "\uDABF\uDFFE"]]},
+
+{"description": "Invalid Unicode character U+BFFFF",
+"input": "\uDABF\uDFFF",
+"output": ["ParseError", ["Character", "\uDABF\uDFFF"]]},
+
+{"description": "Invalid Unicode character U+CFFFE",
+"input": "\uDAFF\uDFFE",
+"output": ["ParseError", ["Character", "\uDAFF\uDFFE"]]},
+
+{"description": "Invalid Unicode character U+CFFFF",
+"input": "\uDAFF\uDFFF",
+"output": ["ParseError", ["Character", "\uDAFF\uDFFF"]]},
+
+{"description": "Invalid Unicode character U+DFFFE",
+"input": "\uDB3F\uDFFE",
+"output": ["ParseError", ["Character", "\uDB3F\uDFFE"]]},
+
+{"description": "Invalid Unicode character U+DFFFF",
+"input": "\uDB3F\uDFFF",
+"output": ["ParseError", ["Character", "\uDB3F\uDFFF"]]},
+
+{"description": "Invalid Unicode character U+EFFFE",
+"input": "\uDB7F\uDFFE",
+"output": ["ParseError", ["Character", "\uDB7F\uDFFE"]]},
+
+{"description": "Invalid Unicode character U+EFFFF",
+"input": "\uDB7F\uDFFF",
+"output": ["ParseError", ["Character", "\uDB7F\uDFFF"]]},
+
+{"description": "Invalid Unicode character U+FFFFE",
+"input": "\uDBBF\uDFFE",
+"output": ["ParseError", ["Character", "\uDBBF\uDFFE"]]},
+
+{"description": "Invalid Unicode character U+FFFFF",
+"input": "\uDBBF\uDFFF",
+"output": ["ParseError", ["Character", "\uDBBF\uDFFF"]]},
+
+{"description": "Invalid Unicode character U+10FFFE",
+"input": "\uDBFF\uDFFE",
+"output": ["ParseError", ["Character", "\uDBFF\uDFFE"]]},
+
+{"description": "Invalid Unicode character U+10FFFF",
+"input": "\uDBFF\uDFFF",
+"output": ["ParseError", ["Character", "\uDBFF\uDFFF"]]},
+
+{"description": "Valid Unicode character U+0009",
+"input": "\u0009",
+"output": [["Character", "\u0009"]]},
+
+{"description": "Valid Unicode character U+000A",
+"input": "\u000A",
+"output": [["Character", "\u000A"]]},
+
+{"description": "Valid Unicode character U+0020",
+"input": "\u0020",
+"output": [["Character", "\u0020"]]},
+
+{"description": "Valid Unicode character U+0021",
+"input": "\u0021",
+"output": [["Character", "\u0021"]]},
+
+{"description": "Valid Unicode character U+0022",
+"input": "\u0022",
+"output": [["Character", "\u0022"]]},
+
+{"description": "Valid Unicode character U+0023",
+"input": "\u0023",
+"output": [["Character", "\u0023"]]},
+
+{"description": "Valid Unicode character U+0024",
+"input": "\u0024",
+"output": [["Character", "\u0024"]]},
+
+{"description": "Valid Unicode character U+0025",
+"input": "\u0025",
+"output": [["Character", "\u0025"]]},
+
+{"description": "Valid Unicode character U+0026",
+"input": "\u0026",
+"output": [["Character", "\u0026"]]},
+
+{"description": "Valid Unicode character U+0027",
+"input": "\u0027",
+"output": [["Character", "\u0027"]]},
+
+{"description": "Valid Unicode character U+0028",
+"input": "\u0028",
+"output": [["Character", "\u0028"]]},
+
+{"description": "Valid Unicode character U+0029",
+"input": "\u0029",
+"output": [["Character", "\u0029"]]},
+
+{"description": "Valid Unicode character U+002A",
+"input": "\u002A",
+"output": [["Character", "\u002A"]]},
+
+{"description": "Valid Unicode character U+002B",
+"input": "\u002B",
+"output": [["Character", "\u002B"]]},
+
+{"description": "Valid Unicode character U+002C",
+"input": "\u002C",
+"output": [["Character", "\u002C"]]},
+
+{"description": "Valid Unicode character U+002D",
+"input": "\u002D",
+"output": [["Character", "\u002D"]]},
+
+{"description": "Valid Unicode character U+002E",
+"input": "\u002E",
+"output": [["Character", "\u002E"]]},
+
+{"description": "Valid Unicode character U+002F",
+"input": "\u002F",
+"output": [["Character", "\u002F"]]},
+
+{"description": "Valid Unicode character U+0030",
+"input": "\u0030",
+"output": [["Character", "\u0030"]]},
+
+{"description": "Valid Unicode character U+0031",
+"input": "\u0031",
+"output": [["Character", "\u0031"]]},
+
+{"description": "Valid Unicode character U+0032",
+"input": "\u0032",
+"output": [["Character", "\u0032"]]},
+
+{"description": "Valid Unicode character U+0033",
+"input": "\u0033",
+"output": [["Character", "\u0033"]]},
+
+{"description": "Valid Unicode character U+0034",
+"input": "\u0034",
+"output": [["Character", "\u0034"]]},
+
+{"description": "Valid Unicode character U+0035",
+"input": "\u0035",
+"output": [["Character", "\u0035"]]},
+
+{"description": "Valid Unicode character U+0036",
+"input": "\u0036",
+"output": [["Character", "\u0036"]]},
+
+{"description": "Valid Unicode character U+0037",
+"input": "\u0037",
+"output": [["Character", "\u0037"]]},
+
+{"description": "Valid Unicode character U+0038",
+"input": "\u0038",
+"output": [["Character", "\u0038"]]},
+
+{"description": "Valid Unicode character U+0039",
+"input": "\u0039",
+"output": [["Character", "\u0039"]]},
+
+{"description": "Valid Unicode character U+003A",
+"input": "\u003A",
+"output": [["Character", "\u003A"]]},
+
+{"description": "Valid Unicode character U+003B",
+"input": "\u003B",
+"output": [["Character", "\u003B"]]},
+
+{"description": "Valid Unicode character U+003D",
+"input": "\u003D",
+"output": [["Character", "\u003D"]]},
+
+{"description": "Valid Unicode character U+003E",
+"input": "\u003E",
+"output": [["Character", "\u003E"]]},
+
+{"description": "Valid Unicode character U+003F",
+"input": "\u003F",
+"output": [["Character", "\u003F"]]},
+
+{"description": "Valid Unicode character U+0040",
+"input": "\u0040",
+"output": [["Character", "\u0040"]]},
+
+{"description": "Valid Unicode character U+0041",
+"input": "\u0041",
+"output": [["Character", "\u0041"]]},
+
+{"description": "Valid Unicode character U+0042",
+"input": "\u0042",
+"output": [["Character", "\u0042"]]},
+
+{"description": "Valid Unicode character U+0043",
+"input": "\u0043",
+"output": [["Character", "\u0043"]]},
+
+{"description": "Valid Unicode character U+0044",
+"input": "\u0044",
+"output": [["Character", "\u0044"]]},
+
+{"description": "Valid Unicode character U+0045",
+"input": "\u0045",
+"output": [["Character", "\u0045"]]},
+
+{"description": "Valid Unicode character U+0046",
+"input": "\u0046",
+"output": [["Character", "\u0046"]]},
+
+{"description": "Valid Unicode character U+0047",
+"input": "\u0047",
+"output": [["Character", "\u0047"]]},
+
+{"description": "Valid Unicode character U+0048",
+"input": "\u0048",
+"output": [["Character", "\u0048"]]},
+
+{"description": "Valid Unicode character U+0049",
+"input": "\u0049",
+"output": [["Character", "\u0049"]]},
+
+{"description": "Valid Unicode character U+004A",
+"input": "\u004A",
+"output": [["Character", "\u004A"]]},
+
+{"description": "Valid Unicode character U+004B",
+"input": "\u004B",
+"output": [["Character", "\u004B"]]},
+
+{"description": "Valid Unicode character U+004C",
+"input": "\u004C",
+"output": [["Character", "\u004C"]]},
+
+{"description": "Valid Unicode character U+004D",
+"input": "\u004D",
+"output": [["Character", "\u004D"]]},
+
+{"description": "Valid Unicode character U+004E",
+"input": "\u004E",
+"output": [["Character", "\u004E"]]},
+
+{"description": "Valid Unicode character U+004F",
+"input": "\u004F",
+"output": [["Character", "\u004F"]]},
+
+{"description": "Valid Unicode character U+0050",
+"input": "\u0050",
+"output": [["Character", "\u0050"]]},
+
+{"description": "Valid Unicode character U+0051",
+"input": "\u0051",
+"output": [["Character", "\u0051"]]},
+
+{"description": "Valid Unicode character U+0052",
+"input": "\u0052",
+"output": [["Character", "\u0052"]]},
+
+{"description": "Valid Unicode character U+0053",
+"input": "\u0053",
+"output": [["Character", "\u0053"]]},
+
+{"description": "Valid Unicode character U+0054",
+"input": "\u0054",
+"output": [["Character", "\u0054"]]},
+
+{"description": "Valid Unicode character U+0055",
+"input": "\u0055",
+"output": [["Character", "\u0055"]]},
+
+{"description": "Valid Unicode character U+0056",
+"input": "\u0056",
+"output": [["Character", "\u0056"]]},
+
+{"description": "Valid Unicode character U+0057",
+"input": "\u0057",
+"output": [["Character", "\u0057"]]},
+
+{"description": "Valid Unicode character U+0058",
+"input": "\u0058",
+"output": [["Character", "\u0058"]]},
+
+{"description": "Valid Unicode character U+0059",
+"input": "\u0059",
+"output": [["Character", "\u0059"]]},
+
+{"description": "Valid Unicode character U+005A",
+"input": "\u005A",
+"output": [["Character", "\u005A"]]},
+
+{"description": "Valid Unicode character U+005B",
+"input": "\u005B",
+"output": [["Character", "\u005B"]]},
+
+{"description": "Valid Unicode character U+005C",
+"input": "\u005C",
+"output": [["Character", "\u005C"]]},
+
+{"description": "Valid Unicode character U+005D",
+"input": "\u005D",
+"output": [["Character", "\u005D"]]},
+
+{"description": "Valid Unicode character U+005E",
+"input": "\u005E",
+"output": [["Character", "\u005E"]]},
+
+{"description": "Valid Unicode character U+005F",
+"input": "\u005F",
+"output": [["Character", "\u005F"]]},
+
+{"description": "Valid Unicode character U+0060",
+"input": "\u0060",
+"output": [["Character", "\u0060"]]},
+
+{"description": "Valid Unicode character U+0061",
+"input": "\u0061",
+"output": [["Character", "\u0061"]]},
+
+{"description": "Valid Unicode character U+0062",
+"input": "\u0062",
+"output": [["Character", "\u0062"]]},
+
+{"description": "Valid Unicode character U+0063",
+"input": "\u0063",
+"output": [["Character", "\u0063"]]},
+
+{"description": "Valid Unicode character U+0064",
+"input": "\u0064",
+"output": [["Character", "\u0064"]]},
+
+{"description": "Valid Unicode character U+0065",
+"input": "\u0065",
+"output": [["Character", "\u0065"]]},
+
+{"description": "Valid Unicode character U+0066",
+"input": "\u0066",
+"output": [["Character", "\u0066"]]},
+
+{"description": "Valid Unicode character U+0067",
+"input": "\u0067",
+"output": [["Character", "\u0067"]]},
+
+{"description": "Valid Unicode character U+0068",
+"input": "\u0068",
+"output": [["Character", "\u0068"]]},
+
+{"description": "Valid Unicode character U+0069",
+"input": "\u0069",
+"output": [["Character", "\u0069"]]},
+
+{"description": "Valid Unicode character U+006A",
+"input": "\u006A",
+"output": [["Character", "\u006A"]]},
+
+{"description": "Valid Unicode character U+006B",
+"input": "\u006B",
+"output": [["Character", "\u006B"]]},
+
+{"description": "Valid Unicode character U+006C",
+"input": "\u006C",
+"output": [["Character", "\u006C"]]},
+
+{"description": "Valid Unicode character U+006D",
+"input": "\u006D",
+"output": [["Character", "\u006D"]]},
+
+{"description": "Valid Unicode character U+006E",
+"input": "\u006E",
+"output": [["Character", "\u006E"]]},
+
+{"description": "Valid Unicode character U+006F",
+"input": "\u006F",
+"output": [["Character", "\u006F"]]},
+
+{"description": "Valid Unicode character U+0070",
+"input": "\u0070",
+"output": [["Character", "\u0070"]]},
+
+{"description": "Valid Unicode character U+0071",
+"input": "\u0071",
+"output": [["Character", "\u0071"]]},
+
+{"description": "Valid Unicode character U+0072",
+"input": "\u0072",
+"output": [["Character", "\u0072"]]},
+
+{"description": "Valid Unicode character U+0073",
+"input": "\u0073",
+"output": [["Character", "\u0073"]]},
+
+{"description": "Valid Unicode character U+0074",
+"input": "\u0074",
+"output": [["Character", "\u0074"]]},
+
+{"description": "Valid Unicode character U+0075",
+"input": "\u0075",
+"output": [["Character", "\u0075"]]},
+
+{"description": "Valid Unicode character U+0076",
+"input": "\u0076",
+"output": [["Character", "\u0076"]]},
+
+{"description": "Valid Unicode character U+0077",
+"input": "\u0077",
+"output": [["Character", "\u0077"]]},
+
+{"description": "Valid Unicode character U+0078",
+"input": "\u0078",
+"output": [["Character", "\u0078"]]},
+
+{"description": "Valid Unicode character U+0079",
+"input": "\u0079",
+"output": [["Character", "\u0079"]]},
+
+{"description": "Valid Unicode character U+007A",
+"input": "\u007A",
+"output": [["Character", "\u007A"]]},
+
+{"description": "Valid Unicode character U+007B",
+"input": "\u007B",
+"output": [["Character", "\u007B"]]},
+
+{"description": "Valid Unicode character U+007C",
+"input": "\u007C",
+"output": [["Character", "\u007C"]]},
+
+{"description": "Valid Unicode character U+007D",
+"input": "\u007D",
+"output": [["Character", "\u007D"]]},
+
+{"description": "Valid Unicode character U+007E",
+"input": "\u007E",
+"output": [["Character", "\u007E"]]},
+
+{"description": "Valid Unicode character U+00A0",
+"input": "\u00A0",
+"output": [["Character", "\u00A0"]]},
+
+{"description": "Valid Unicode character U+00A1",
+"input": "\u00A1",
+"output": [["Character", "\u00A1"]]},
+
+{"description": "Valid Unicode character U+00A2",
+"input": "\u00A2",
+"output": [["Character", "\u00A2"]]},
+
+{"description": "Valid Unicode character U+00A3",
+"input": "\u00A3",
+"output": [["Character", "\u00A3"]]},
+
+{"description": "Valid Unicode character U+00A4",
+"input": "\u00A4",
+"output": [["Character", "\u00A4"]]},
+
+{"description": "Valid Unicode character U+00A5",
+"input": "\u00A5",
+"output": [["Character", "\u00A5"]]},
+
+{"description": "Valid Unicode character U+00A6",
+"input": "\u00A6",
+"output": [["Character", "\u00A6"]]},
+
+{"description": "Valid Unicode character U+00A7",
+"input": "\u00A7",
+"output": [["Character", "\u00A7"]]},
+
+{"description": "Valid Unicode character U+00A8",
+"input": "\u00A8",
+"output": [["Character", "\u00A8"]]},
+
+{"description": "Valid Unicode character U+00A9",
+"input": "\u00A9",
+"output": [["Character", "\u00A9"]]},
+
+{"description": "Valid Unicode character U+00AA",
+"input": "\u00AA",
+"output": [["Character", "\u00AA"]]},
+
+{"description": "Valid Unicode character U+00AB",
+"input": "\u00AB",
+"output": [["Character", "\u00AB"]]},
+
+{"description": "Valid Unicode character U+00AC",
+"input": "\u00AC",
+"output": [["Character", "\u00AC"]]},
+
+{"description": "Valid Unicode character U+00AD",
+"input": "\u00AD",
+"output": [["Character", "\u00AD"]]},
+
+{"description": "Valid Unicode character U+00AE",
+"input": "\u00AE",
+"output": [["Character", "\u00AE"]]},
+
+{"description": "Valid Unicode character U+00AF",
+"input": "\u00AF",
+"output": [["Character", "\u00AF"]]},
+
+{"description": "Valid Unicode character U+00B0",
+"input": "\u00B0",
+"output": [["Character", "\u00B0"]]},
+
+{"description": "Valid Unicode character U+00B1",
+"input": "\u00B1",
+"output": [["Character", "\u00B1"]]},
+
+{"description": "Valid Unicode character U+00B2",
+"input": "\u00B2",
+"output": [["Character", "\u00B2"]]},
+
+{"description": "Valid Unicode character U+00B3",
+"input": "\u00B3",
+"output": [["Character", "\u00B3"]]},
+
+{"description": "Valid Unicode character U+00B4",
+"input": "\u00B4",
+"output": [["Character", "\u00B4"]]},
+
+{"description": "Valid Unicode character U+00B5",
+"input": "\u00B5",
+"output": [["Character", "\u00B5"]]},
+
+{"description": "Valid Unicode character U+00B6",
+"input": "\u00B6",
+"output": [["Character", "\u00B6"]]},
+
+{"description": "Valid Unicode character U+00B7",
+"input": "\u00B7",
+"output": [["Character", "\u00B7"]]},
+
+{"description": "Valid Unicode character U+00B8",
+"input": "\u00B8",
+"output": [["Character", "\u00B8"]]},
+
+{"description": "Valid Unicode character U+00B9",
+"input": "\u00B9",
+"output": [["Character", "\u00B9"]]},
+
+{"description": "Valid Unicode character U+00BA",
+"input": "\u00BA",
+"output": [["Character", "\u00BA"]]},
+
+{"description": "Valid Unicode character U+00BB",
+"input": "\u00BB",
+"output": [["Character", "\u00BB"]]},
+
+{"description": "Valid Unicode character U+00BC",
+"input": "\u00BC",
+"output": [["Character", "\u00BC"]]},
+
+{"description": "Valid Unicode character U+00BD",
+"input": "\u00BD",
+"output": [["Character", "\u00BD"]]},
+
+{"description": "Valid Unicode character U+00BE",
+"input": "\u00BE",
+"output": [["Character", "\u00BE"]]},
+
+{"description": "Valid Unicode character U+00BF",
+"input": "\u00BF",
+"output": [["Character", "\u00BF"]]},
+
+{"description": "Valid Unicode character U+00C0",
+"input": "\u00C0",
+"output": [["Character", "\u00C0"]]},
+
+{"description": "Valid Unicode character U+00C1",
+"input": "\u00C1",
+"output": [["Character", "\u00C1"]]},
+
+{"description": "Valid Unicode character U+00C2",
+"input": "\u00C2",
+"output": [["Character", "\u00C2"]]},
+
+{"description": "Valid Unicode character U+00C3",
+"input": "\u00C3",
+"output": [["Character", "\u00C3"]]},
+
+{"description": "Valid Unicode character U+00C4",
+"input": "\u00C4",
+"output": [["Character", "\u00C4"]]},
+
+{"description": "Valid Unicode character U+00C5",
+"input": "\u00C5",
+"output": [["Character", "\u00C5"]]},
+
+{"description": "Valid Unicode character U+00C6",
+"input": "\u00C6",
+"output": [["Character", "\u00C6"]]},
+
+{"description": "Valid Unicode character U+00C7",
+"input": "\u00C7",
+"output": [["Character", "\u00C7"]]},
+
+{"description": "Valid Unicode character U+00C8",
+"input": "\u00C8",
+"output": [["Character", "\u00C8"]]},
+
+{"description": "Valid Unicode character U+00C9",
+"input": "\u00C9",
+"output": [["Character", "\u00C9"]]},
+
+{"description": "Valid Unicode character U+00CA",
+"input": "\u00CA",
+"output": [["Character", "\u00CA"]]},
+
+{"description": "Valid Unicode character U+00CB",
+"input": "\u00CB",
+"output": [["Character", "\u00CB"]]},
+
+{"description": "Valid Unicode character U+00CC",
+"input": "\u00CC",
+"output": [["Character", "\u00CC"]]},
+
+{"description": "Valid Unicode character U+00CD",
+"input": "\u00CD",
+"output": [["Character", "\u00CD"]]},
+
+{"description": "Valid Unicode character U+00CE",
+"input": "\u00CE",
+"output": [["Character", "\u00CE"]]},
+
+{"description": "Valid Unicode character U+00CF",
+"input": "\u00CF",
+"output": [["Character", "\u00CF"]]},
+
+{"description": "Valid Unicode character U+00D0",
+"input": "\u00D0",
+"output": [["Character", "\u00D0"]]},
+
+{"description": "Valid Unicode character U+00D1",
+"input": "\u00D1",
+"output": [["Character", "\u00D1"]]},
+
+{"description": "Valid Unicode character U+00D2",
+"input": "\u00D2",
+"output": [["Character", "\u00D2"]]},
+
+{"description": "Valid Unicode character U+00D3",
+"input": "\u00D3",
+"output": [["Character", "\u00D3"]]},
+
+{"description": "Valid Unicode character U+00D4",
+"input": "\u00D4",
+"output": [["Character", "\u00D4"]]},
+
+{"description": "Valid Unicode character U+00D5",
+"input": "\u00D5",
+"output": [["Character", "\u00D5"]]},
+
+{"description": "Valid Unicode character U+00D6",
+"input": "\u00D6",
+"output": [["Character", "\u00D6"]]},
+
+{"description": "Valid Unicode character U+00D7",
+"input": "\u00D7",
+"output": [["Character", "\u00D7"]]},
+
+{"description": "Valid Unicode character U+00D8",
+"input": "\u00D8",
+"output": [["Character", "\u00D8"]]},
+
+{"description": "Valid Unicode character U+00D9",
+"input": "\u00D9",
+"output": [["Character", "\u00D9"]]},
+
+{"description": "Valid Unicode character U+00DA",
+"input": "\u00DA",
+"output": [["Character", "\u00DA"]]},
+
+{"description": "Valid Unicode character U+00DB",
+"input": "\u00DB",
+"output": [["Character", "\u00DB"]]},
+
+{"description": "Valid Unicode character U+00DC",
+"input": "\u00DC",
+"output": [["Character", "\u00DC"]]},
+
+{"description": "Valid Unicode character U+00DD",
+"input": "\u00DD",
+"output": [["Character", "\u00DD"]]},
+
+{"description": "Valid Unicode character U+00DE",
+"input": "\u00DE",
+"output": [["Character", "\u00DE"]]},
+
+{"description": "Valid Unicode character U+00DF",
+"input": "\u00DF",
+"output": [["Character", "\u00DF"]]},
+
+{"description": "Valid Unicode character U+00E0",
+"input": "\u00E0",
+"output": [["Character", "\u00E0"]]},
+
+{"description": "Valid Unicode character U+00E1",
+"input": "\u00E1",
+"output": [["Character", "\u00E1"]]},
+
+{"description": "Valid Unicode character U+00E2",
+"input": "\u00E2",
+"output": [["Character", "\u00E2"]]},
+
+{"description": "Valid Unicode character U+00E3",
+"input": "\u00E3",
+"output": [["Character", "\u00E3"]]},
+
+{"description": "Valid Unicode character U+00E4",
+"input": "\u00E4",
+"output": [["Character", "\u00E4"]]},
+
+{"description": "Valid Unicode character U+00E5",
+"input": "\u00E5",
+"output": [["Character", "\u00E5"]]},
+
+{"description": "Valid Unicode character U+00E6",
+"input": "\u00E6",
+"output": [["Character", "\u00E6"]]},
+
+{"description": "Valid Unicode character U+00E7",
+"input": "\u00E7",
+"output": [["Character", "\u00E7"]]},
+
+{"description": "Valid Unicode character U+00E8",
+"input": "\u00E8",
+"output": [["Character", "\u00E8"]]},
+
+{"description": "Valid Unicode character U+00E9",
+"input": "\u00E9",
+"output": [["Character", "\u00E9"]]},
+
+{"description": "Valid Unicode character U+00EA",
+"input": "\u00EA",
+"output": [["Character", "\u00EA"]]},
+
+{"description": "Valid Unicode character U+00EB",
+"input": "\u00EB",
+"output": [["Character", "\u00EB"]]},
+
+{"description": "Valid Unicode character U+00EC",
+"input": "\u00EC",
+"output": [["Character", "\u00EC"]]},
+
+{"description": "Valid Unicode character U+00ED",
+"input": "\u00ED",
+"output": [["Character", "\u00ED"]]},
+
+{"description": "Valid Unicode character U+00EE",
+"input": "\u00EE",
+"output": [["Character", "\u00EE"]]},
+
+{"description": "Valid Unicode character U+00EF",
+"input": "\u00EF",
+"output": [["Character", "\u00EF"]]},
+
+{"description": "Valid Unicode character U+00F0",
+"input": "\u00F0",
+"output": [["Character", "\u00F0"]]},
+
+{"description": "Valid Unicode character U+00F1",
+"input": "\u00F1",
+"output": [["Character", "\u00F1"]]},
+
+{"description": "Valid Unicode character U+00F2",
+"input": "\u00F2",
+"output": [["Character", "\u00F2"]]},
+
+{"description": "Valid Unicode character U+00F3",
+"input": "\u00F3",
+"output": [["Character", "\u00F3"]]},
+
+{"description": "Valid Unicode character U+00F4",
+"input": "\u00F4",
+"output": [["Character", "\u00F4"]]},
+
+{"description": "Valid Unicode character U+00F5",
+"input": "\u00F5",
+"output": [["Character", "\u00F5"]]},
+
+{"description": "Valid Unicode character U+00F6",
+"input": "\u00F6",
+"output": [["Character", "\u00F6"]]},
+
+{"description": "Valid Unicode character U+00F7",
+"input": "\u00F7",
+"output": [["Character", "\u00F7"]]},
+
+{"description": "Valid Unicode character U+00F8",
+"input": "\u00F8",
+"output": [["Character", "\u00F8"]]},
+
+{"description": "Valid Unicode character U+00F9",
+"input": "\u00F9",
+"output": [["Character", "\u00F9"]]},
+
+{"description": "Valid Unicode character U+00FA",
+"input": "\u00FA",
+"output": [["Character", "\u00FA"]]},
+
+{"description": "Valid Unicode character U+00FB",
+"input": "\u00FB",
+"output": [["Character", "\u00FB"]]},
+
+{"description": "Valid Unicode character U+00FC",
+"input": "\u00FC",
+"output": [["Character", "\u00FC"]]},
+
+{"description": "Valid Unicode character U+00FD",
+"input": "\u00FD",
+"output": [["Character", "\u00FD"]]},
+
+{"description": "Valid Unicode character U+00FE",
+"input": "\u00FE",
+"output": [["Character", "\u00FE"]]},
+
+{"description": "Valid Unicode character U+00FF",
+"input": "\u00FF",
+"output": [["Character", "\u00FF"]]},
+
+{"description": "Valid Unicode character U+D7FF",
+"input": "\uD7FF",
+"output": [["Character", "\uD7FF"]]},
+
+{"description": "Valid Unicode character U+E000",
+"input": "\uE000",
+"output": [["Character", "\uE000"]]},
+
+{"description": "Valid Unicode character U+FDCF",
+"input": "\uFDCF",
+"output": [["Character", "\uFDCF"]]},
+
+{"description": "Valid Unicode character U+FDF0",
+"input": "\uFDF0",
+"output": [["Character", "\uFDF0"]]},
+
+{"description": "Valid Unicode character U+FFFD",
+"input": "\uFFFD",
+"output": [["Character", "\uFFFD"]]},
+
+{"description": "Valid Unicode character U+10000",
+"input": "\uD800\uDC00",
+"output": [["Character", "\uD800\uDC00"]]},
+
+{"description": "Valid Unicode character U+1FFFD",
+"input": "\uD83F\uDFFD",
+"output": [["Character", "\uD83F\uDFFD"]]},
+
+{"description": "Valid Unicode character U+20000",
+"input": "\uD840\uDC00",
+"output": [["Character", "\uD840\uDC00"]]},
+
+{"description": "Valid Unicode character U+2FFFD",
+"input": "\uD87F\uDFFD",
+"output": [["Character", "\uD87F\uDFFD"]]},
+
+{"description": "Valid Unicode character U+30000",
+"input": "\uD880\uDC00",
+"output": [["Character", "\uD880\uDC00"]]},
+
+{"description": "Valid Unicode character U+3FFFD",
+"input": "\uD8BF\uDFFD",
+"output": [["Character", "\uD8BF\uDFFD"]]},
+
+{"description": "Valid Unicode character U+40000",
+"input": "\uD8C0\uDC00",
+"output": [["Character", "\uD8C0\uDC00"]]},
+
+{"description": "Valid Unicode character U+4FFFD",
+"input": "\uD8FF\uDFFD",
+"output": [["Character", "\uD8FF\uDFFD"]]},
+
+{"description": "Valid Unicode character U+50000",
+"input": "\uD900\uDC00",
+"output": [["Character", "\uD900\uDC00"]]},
+
+{"description": "Valid Unicode character U+5FFFD",
+"input": "\uD93F\uDFFD",
+"output": [["Character", "\uD93F\uDFFD"]]},
+
+{"description": "Valid Unicode character U+60000",
+"input": "\uD940\uDC00",
+"output": [["Character", "\uD940\uDC00"]]},
+
+{"description": "Valid Unicode character U+6FFFD",
+"input": "\uD97F\uDFFD",
+"output": [["Character", "\uD97F\uDFFD"]]},
+
+{"description": "Valid Unicode character U+70000",
+"input": "\uD980\uDC00",
+"output": [["Character", "\uD980\uDC00"]]},
+
+{"description": "Valid Unicode character U+7FFFD",
+"input": "\uD9BF\uDFFD",
+"output": [["Character", "\uD9BF\uDFFD"]]},
+
+{"description": "Valid Unicode character U+80000",
+"input": "\uD9C0\uDC00",
+"output": [["Character", "\uD9C0\uDC00"]]},
+
+{"description": "Valid Unicode character U+8FFFD",
+"input": "\uD9FF\uDFFD",
+"output": [["Character", "\uD9FF\uDFFD"]]},
+
+{"description": "Valid Unicode character U+90000",
+"input": "\uDA00\uDC00",
+"output": [["Character", "\uDA00\uDC00"]]},
+
+{"description": "Valid Unicode character U+9FFFD",
+"input": "\uDA3F\uDFFD",
+"output": [["Character", "\uDA3F\uDFFD"]]},
+
+{"description": "Valid Unicode character U+A0000",
+"input": "\uDA40\uDC00",
+"output": [["Character", "\uDA40\uDC00"]]},
+
+{"description": "Valid Unicode character U+AFFFD",
+"input": "\uDA7F\uDFFD",
+"output": [["Character", "\uDA7F\uDFFD"]]},
+
+{"description": "Valid Unicode character U+B0000",
+"input": "\uDA80\uDC00",
+"output": [["Character", "\uDA80\uDC00"]]},
+
+{"description": "Valid Unicode character U+BFFFD",
+"input": "\uDABF\uDFFD",
+"output": [["Character", "\uDABF\uDFFD"]]},
+
+{"description": "Valid Unicode character U+C0000",
+"input": "\uDAC0\uDC00",
+"output": [["Character", "\uDAC0\uDC00"]]},
+
+{"description": "Valid Unicode character U+CFFFD",
+"input": "\uDAFF\uDFFD",
+"output": [["Character", "\uDAFF\uDFFD"]]},
+
+{"description": "Valid Unicode character U+D0000",
+"input": "\uDB00\uDC00",
+"output": [["Character", "\uDB00\uDC00"]]},
+
+{"description": "Valid Unicode character U+DFFFD",
+"input": "\uDB3F\uDFFD",
+"output": [["Character", "\uDB3F\uDFFD"]]},
+
+{"description": "Valid Unicode character U+E0000",
+"input": "\uDB40\uDC00",
+"output": [["Character", "\uDB40\uDC00"]]},
+
+{"description": "Valid Unicode character U+EFFFD",
+"input": "\uDB7F\uDFFD",
+"output": [["Character", "\uDB7F\uDFFD"]]},
+
+{"description": "Valid Unicode character U+F0000",
+"input": "\uDB80\uDC00",
+"output": [["Character", "\uDB80\uDC00"]]},
+
+{"description": "Valid Unicode character U+FFFFD",
+"input": "\uDBBF\uDFFD",
+"output": [["Character", "\uDBBF\uDFFD"]]},
+
+{"description": "Valid Unicode character U+100000",
+"input": "\uDBC0\uDC00",
+"output": [["Character", "\uDBC0\uDC00"]]},
+
+{"description": "Valid Unicode character U+10FFFD",
+"input": "\uDBFF\uDFFD",
+"output": [["Character", "\uDBFF\uDFFD"]]}
+
+]}
diff --git a/html/test/data/tokenizer/unicodeCharsProblematic.test b/html/test/data/tokenizer/unicodeCharsProblematic.test
new file mode 100644
index 0000000..cf2fbe6
--- /dev/null
+++ b/html/test/data/tokenizer/unicodeCharsProblematic.test
@@ -0,0 +1,27 @@
+{"tests" : [
+{"description": "Invalid Unicode character U+DFFF",
+"doubleEscaped":true,
+"input": "\\uDFFF",
+"output":["ParseError", ["Character", "\\uFFFD"]]},
+
+{"description": "Invalid Unicode character U+D800",
+"doubleEscaped":true,
+"input": "\\uD800",
+"output":["ParseError", ["Character", "\\uFFFD"]]},
+
+{"description": "Invalid Unicode character U+DFFF with valid preceding character",
+"doubleEscaped":true,
+"input": "a\\uDFFF",
+"output":["ParseError", ["Character", "a\\uFFFD"]]},
+
+{"description": "Invalid Unicode character U+D800 with valid following character",
+"doubleEscaped":true,
+"input": "\\uD800a",
+"output":["ParseError", ["Character", "\\uFFFDa"]]},
+
+{"description":"CR followed by U+0000",
+"input":"\r\u0000",
+"output":[["Character", "\n"], "ParseError", ["Character", "\u0000"]],
+"ignoreErrorOrder":true}
+]
+}
\ No newline at end of file
diff --git a/html/test/data/tokenizer/xmlViolation.test b/html/test/data/tokenizer/xmlViolation.test
new file mode 100644
index 0000000..137d964
--- /dev/null
+++ b/html/test/data/tokenizer/xmlViolation.test
@@ -0,0 +1,22 @@
+{"xmlViolationTests": [
+
+{"description":"Non-XML character",
+"input":"a\uFFFFb",
+"ignoreErrorOrder":true,
+"output":["ParseError",["Character","a\uFFFDb"]]},
+
+{"description":"Non-XML space",
+"input":"a\u000Cb",
+"ignoreErrorOrder":true,
+"output":[["Character","a b"]]},
+
+{"description":"Double hyphen in comment",
+"input":"<!-- foo -- bar -->",
+"output":["ParseError",["Comment"," foo - - bar "]]},
+
+{"description":"FF between attributes",
+"input":"<a b=''\u000Cc=''>",
+"output":[["StartTag","a",{"b":"","c":""}]]}
+]}
+
+
diff --git a/html/test/data/tree-construction/adoption01.dat b/html/test/data/tree-construction/adoption01.dat
new file mode 100644
index 0000000..787e1b0
--- /dev/null
+++ b/html/test/data/tree-construction/adoption01.dat
@@ -0,0 +1,194 @@
+#data
+<a><p></a></p>
+#errors
+#document
+| <html>
+|   <head>
+|   <body>
+|     <a>
+|     <p>
+|       <a>
+
+#data
+<a>1<p>2</a>3</p>
+#errors
+#document
+| <html>
+|   <head>
+|   <body>
+|     <a>
+|       "1"
+|     <p>
+|       <a>
+|         "2"
+|       "3"
+
+#data
+<a>1<button>2</a>3</button>
+#errors
+#document
+| <html>
+|   <head>
+|   <body>
+|     <a>
+|       "1"
+|     <button>
+|       <a>
+|         "2"
+|       "3"
+
+#data
+<a>1<b>2</a>3</b>
+#errors
+#document
+| <html>
+|   <head>
+|   <body>
+|     <a>
+|       "1"
+|       <b>
+|         "2"
+|     <b>
+|       "3"
+
+#data
+<a>1<div>2<div>3</a>4</div>5</div>
+#errors
+#document
+| <html>
+|   <head>
+|   <body>
+|     <a>
+|       "1"
+|     <div>
+|       <a>
+|         "2"
+|       <div>
+|         <a>
+|           "3"
+|         "4"
+|       "5"
+
+#data
+<table><a>1<p>2</a>3</p>
+#errors
+#document
+| <html>
+|   <head>
+|   <body>
+|     <a>
+|       "1"
+|     <p>
+|       <a>
+|         "2"
+|       "3"
+|     <table>
+
+#data
+<b><b><a><p></a>
+#errors
+#document
+| <html>
+|   <head>
+|   <body>
+|     <b>
+|       <b>
+|         <a>
+|         <p>
+|           <a>
+
+#data
+<b><a><b><p></a>
+#errors
+#document
+| <html>
+|   <head>
+|   <body>
+|     <b>
+|       <a>
+|         <b>
+|       <b>
+|         <p>
+|           <a>
+
+#data
+<a><b><b><p></a>
+#errors
+#document
+| <html>
+|   <head>
+|   <body>
+|     <a>
+|       <b>
+|         <b>
+|     <b>
+|       <b>
+|         <p>
+|           <a>
+
+#data
+<p>1<s id="A">2<b id="B">3</p>4</s>5</b>
+#errors
+#document
+| <html>
+|   <head>
+|   <body>
+|     <p>
+|       "1"
+|       <s>
+|         id="A"
+|         "2"
+|         <b>
+|           id="B"
+|           "3"
+|     <s>
+|       id="A"
+|       <b>
+|         id="B"
+|         "4"
+|     <b>
+|       id="B"
+|       "5"
+
+#data
+<table><a>1<td>2</td>3</table>
+#errors
+#document
+| <html>
+|   <head>
+|   <body>
+|     <a>
+|       "1"
+|     <a>
+|       "3"
+|     <table>
+|       <tbody>
+|         <tr>
+|           <td>
+|             "2"
+
+#data
+<table>A<td>B</td>C</table>
+#errors
+#document
+| <html>
+|   <head>
+|   <body>
+|     "AC"
+|     <table>
+|       <tbody>
+|         <tr>
+|           <td>
+|             "B"
+
+#data
+<a><svg><tr><input></a>
+#errors
+#document
+| <html>
+|   <head>
+|   <body>
+|     <a>
+|       <svg svg>
+|         <svg tr>
+|           <svg input>
diff --git a/html/test/data/tree-construction/adoption02.dat b/html/test/data/tree-construction/adoption02.dat
new file mode 100644
index 0000000..d18151b
--- /dev/null
+++ b/html/test/data/tree-construction/adoption02.dat
@@ -0,0 +1,31 @@
+#data
+<b>1<i>2<p>3</b>4
+#errors
+#document
+| <html>
+|   <head>
+|   <body>
+|     <b>
+|       "1"
+|       <i>
+|         "2"
+|     <i>
+|       <p>
+|         <b>
+|           "3"
+|         "4"
+
+#data
+<a><div><style></style><address><a>
+#errors
+#document
+| <html>
+|   <head>
+|   <body>
+|     <a>
+|     <div>
+|       <a>
+|         <style>
+|       <address>
+|         <a>
+|         <a>
diff --git a/html/test/data/tree-construction/comments01.dat b/html/test/data/tree-construction/comments01.dat
new file mode 100644
index 0000000..44f1876
--- /dev/null
+++ b/html/test/data/tree-construction/comments01.dat
@@ -0,0 +1,135 @@
+#data
+FOO<!-- BAR -->BAZ
+#errors
+#document
+| <html>
+|   <head>
+|   <body>
+|     "FOO"
+|     <!--  BAR  -->
+|     "BAZ"
+
+#data
+FOO<!-- BAR --!>BAZ
+#errors
+#document
+| <html>
+|   <head>
+|   <body>
+|     "FOO"
+|     <!--  BAR  -->
+|     "BAZ"
+
+#data
+FOO<!-- BAR --   >BAZ
+#errors
+#document
+| <html>
+|   <head>
+|   <body>
+|     "FOO"
+|     <!--  BAR --   >BAZ -->
+
+#data
+FOO<!-- BAR -- <QUX> -- MUX -->BAZ
+#errors
+#document
+| <html>
+|   <head>
+|   <body>
+|     "FOO"
+|     <!--  BAR -- <QUX> -- MUX  -->
+|     "BAZ"
+
+#data
+FOO<!-- BAR -- <QUX> -- MUX --!>BAZ
+#errors
+#document
+| <html>
+|   <head>
+|   <body>
+|     "FOO"
+|     <!--  BAR -- <QUX> -- MUX  -->
+|     "BAZ"
+
+#data
+FOO<!-- BAR -- <QUX> -- MUX -- >BAZ
+#errors
+#document
+| <html>
+|   <head>
+|   <body>
+|     "FOO"
+|     <!--  BAR -- <QUX> -- MUX -- >BAZ -->
+
+#data
+FOO<!---->BAZ
+#errors
+#document
+| <html>
+|   <head>
+|   <body>
+|     "FOO"
+|     <!--  -->
+|     "BAZ"
+
+#data
+FOO<!--->BAZ
+#errors
+#document
+| <html>
+|   <head>
+|   <body>
+|     "FOO"
+|     <!--  -->
+|     "BAZ"
+
+#data
+FOO<!-->BAZ
+#errors
+#document
+| <html>
+|   <head>
+|   <body>
+|     "FOO"
+|     <!--  -->
+|     "BAZ"
+
+#data
+<?xml version="1.0">Hi
+#errors
+#document
+| <!-- ?xml version="1.0" -->
+| <html>
+|   <head>
+|   <body>
+|     "Hi"
+
+#data
+<?xml version="1.0">
+#errors
+#document
+| <!-- ?xml version="1.0" -->
+| <html>
+|   <head>
+|   <body>
+
+#data
+<?xml version
+#errors
+#document
+| <!-- ?xml version -->
+| <html>
+|   <head>
+|   <body>
+
+#data
+FOO<!----->BAZ
+#errors
+#document
+| <html>
+|   <head>
+|   <body>
+|     "FOO"
+|     <!-- - -->
+|     "BAZ"
diff --git a/html/test/data/tree-construction/doctype01.dat b/html/test/data/tree-construction/doctype01.dat
new file mode 100644
index 0000000..ae45732
--- /dev/null
+++ b/html/test/data/tree-construction/doctype01.dat
@@ -0,0 +1,370 @@
+#data
+<!DOCTYPE html>Hello
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     "Hello"
+
+#data
+<!dOctYpE HtMl>Hello
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     "Hello"
+
+#data
+<!DOCTYPEhtml>Hello
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     "Hello"
+
+#data
+<!DOCTYPE>Hello
+#errors
+#document
+| <!DOCTYPE >
+| <html>
+|   <head>
+|   <body>
+|     "Hello"
+
+#data
+<!DOCTYPE >Hello
+#errors
+#document
+| <!DOCTYPE >
+| <html>
+|   <head>
+|   <body>
+|     "Hello"
+
+#data
+<!DOCTYPE potato>Hello
+#errors
+#document
+| <!DOCTYPE potato>
+| <html>
+|   <head>
+|   <body>
+|     "Hello"
+
+#data
+<!DOCTYPE potato >Hello
+#errors
+#document
+| <!DOCTYPE potato>
+| <html>
+|   <head>
+|   <body>
+|     "Hello"
+
+#data
+<!DOCTYPE potato taco>Hello
+#errors
+#document
+| <!DOCTYPE potato>
+| <html>
+|   <head>
+|   <body>
+|     "Hello"
+
+#data
+<!DOCTYPE potato taco "ddd>Hello
+#errors
+#document
+| <!DOCTYPE potato>
+| <html>
+|   <head>
+|   <body>
+|     "Hello"
+
+#data
+<!DOCTYPE potato sYstEM>Hello
+#errors
+#document
+| <!DOCTYPE potato>
+| <html>
+|   <head>
+|   <body>
+|     "Hello"
+
+#data
+<!DOCTYPE potato sYstEM    >Hello
+#errors
+#document
+| <!DOCTYPE potato>
+| <html>
+|   <head>
+|   <body>
+|     "Hello"
+
+#data
+<!DOCTYPE   potato       sYstEM  ggg>Hello
+#errors
+#document
+| <!DOCTYPE potato>
+| <html>
+|   <head>
+|   <body>
+|     "Hello"
+
+#data
+<!DOCTYPE potato SYSTEM taco  >Hello
+#errors
+#document
+| <!DOCTYPE potato>
+| <html>
+|   <head>
+|   <body>
+|     "Hello"
+
+#data
+<!DOCTYPE potato SYSTEM 'taco"'>Hello
+#errors
+#document
+| <!DOCTYPE potato "" "taco"">
+| <html>
+|   <head>
+|   <body>
+|     "Hello"
+
+#data
+<!DOCTYPE potato SYSTEM "taco">Hello
+#errors
+#document
+| <!DOCTYPE potato "" "taco">
+| <html>
+|   <head>
+|   <body>
+|     "Hello"
+
+#data
+<!DOCTYPE potato SYSTEM "tai'co">Hello
+#errors
+#document
+| <!DOCTYPE potato "" "tai'co">
+| <html>
+|   <head>
+|   <body>
+|     "Hello"
+
+#data
+<!DOCTYPE potato SYSTEMtaco "ddd">Hello
+#errors
+#document
+| <!DOCTYPE potato>
+| <html>
+|   <head>
+|   <body>
+|     "Hello"
+
+#data
+<!DOCTYPE potato grass SYSTEM taco>Hello
+#errors
+#document
+| <!DOCTYPE potato>
+| <html>
+|   <head>
+|   <body>
+|     "Hello"
+
+#data
+<!DOCTYPE potato pUbLIc>Hello
+#errors
+#document
+| <!DOCTYPE potato>
+| <html>
+|   <head>
+|   <body>
+|     "Hello"
+
+#data
+<!DOCTYPE potato pUbLIc >Hello
+#errors
+#document
+| <!DOCTYPE potato>
+| <html>
+|   <head>
+|   <body>
+|     "Hello"
+
+#data
+<!DOCTYPE potato pUbLIcgoof>Hello
+#errors
+#document
+| <!DOCTYPE potato>
+| <html>
+|   <head>
+|   <body>
+|     "Hello"
+
+#data
+<!DOCTYPE potato PUBLIC goof>Hello
+#errors
+#document
+| <!DOCTYPE potato>
+| <html>
+|   <head>
+|   <body>
+|     "Hello"
+
+#data
+<!DOCTYPE potato PUBLIC "go'of">Hello
+#errors
+#document
+| <!DOCTYPE potato "go'of" "">
+| <html>
+|   <head>
+|   <body>
+|     "Hello"
+
+#data
+<!DOCTYPE potato PUBLIC 'go'of'>Hello
+#errors
+#document
+| <!DOCTYPE potato "go" "">
+| <html>
+|   <head>
+|   <body>
+|     "Hello"
+
+#data
+<!DOCTYPE potato PUBLIC 'go:hh   of' >Hello
+#errors
+#document
+| <!DOCTYPE potato "go:hh   of" "">
+| <html>
+|   <head>
+|   <body>
+|     "Hello"
+
+#data
+<!DOCTYPE potato PUBLIC "W3C-//dfdf" SYSTEM ggg>Hello
+#errors
+#document
+| <!DOCTYPE potato "W3C-//dfdf" "">
+| <html>
+|   <head>
+|   <body>
+|     "Hello"
+
+#data
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
+   "http://www.w3.org/TR/html4/strict.dtd">Hello
+#errors
+#document
+| <!DOCTYPE html "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+| <html>
+|   <head>
+|   <body>
+|     "Hello"
+
+#data
+<!DOCTYPE ...>Hello
+#errors
+#document
+| <!DOCTYPE ...>
+| <html>
+|   <head>
+|   <body>
+|     "Hello"
+
+#data
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+#errors
+#document
+| <!DOCTYPE html "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+| <html>
+|   <head>
+|   <body>
+
+#data
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Frameset//EN"
+"http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd">
+#errors
+#document
+| <!DOCTYPE html "-//W3C//DTD XHTML 1.0 Frameset//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd">
+| <html>
+|   <head>
+|   <body>
+
+#data
+<!DOCTYPE root-element [SYSTEM OR PUBLIC FPI] "uri" [ 
+<!-- internal declarations -->
+]>
+#errors
+#document
+| <!DOCTYPE root-element>
+| <html>
+|   <head>
+|   <body>
+|     "]>"
+
+#data
+<!DOCTYPE html PUBLIC
+  "-//WAPFORUM//DTD XHTML Mobile 1.0//EN"
+    "http://www.wapforum.org/DTD/xhtml-mobile10.dtd">
+#errors
+#document
+| <!DOCTYPE html "-//WAPFORUM//DTD XHTML Mobile 1.0//EN" "http://www.wapforum.org/DTD/xhtml-mobile10.dtd">
+| <html>
+|   <head>
+|   <body>
+
+#data
+<!DOCTYPE HTML SYSTEM "http://www.w3.org/DTD/HTML4-strict.dtd"><body><b>Mine!</b></body>
+#errors
+#document
+| <!DOCTYPE html "" "http://www.w3.org/DTD/HTML4-strict.dtd">
+| <html>
+|   <head>
+|   <body>
+|     <b>
+|       "Mine!"
+
+#data
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN""http://www.w3.org/TR/html4/strict.dtd">
+#errors
+#document
+| <!DOCTYPE html "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+| <html>
+|   <head>
+|   <body>
+
+#data
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"'http://www.w3.org/TR/html4/strict.dtd'>
+#errors
+#document
+| <!DOCTYPE html "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+| <html>
+|   <head>
+|   <body>
+
+#data
+<!DOCTYPE HTML PUBLIC"-//W3C//DTD HTML 4.01//EN"'http://www.w3.org/TR/html4/strict.dtd'>
+#errors
+#document
+| <!DOCTYPE html "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+| <html>
+|   <head>
+|   <body>
+
+#data
+<!DOCTYPE HTML PUBLIC'-//W3C//DTD HTML 4.01//EN''http://www.w3.org/TR/html4/strict.dtd'>
+#errors
+#document
+| <!DOCTYPE html "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+| <html>
+|   <head>
+|   <body>
diff --git a/html/test/data/tree-construction/domjs-unsafe.dat b/html/test/data/tree-construction/domjs-unsafe.dat
new file mode 100644
index 0000000..905b94e
--- /dev/null
+++ b/html/test/data/tree-construction/domjs-unsafe.dat
Binary files differ
diff --git a/html/test/data/tree-construction/entities01.dat b/html/test/data/tree-construction/entities01.dat
new file mode 100644
index 0000000..c8073b7
--- /dev/null
+++ b/html/test/data/tree-construction/entities01.dat
@@ -0,0 +1,603 @@
+#data
+FOO&gt;BAR
+#errors
+#document
+| <html>
+|   <head>
+|   <body>
+|     "FOO>BAR"
+
+#data
+FOO&gtBAR
+#errors
+#document
+| <html>
+|   <head>
+|   <body>
+|     "FOO>BAR"
+
+#data
+FOO&gt BAR
+#errors
+#document
+| <html>
+|   <head>
+|   <body>
+|     "FOO> BAR"
+
+#data
+FOO&gt;;;BAR
+#errors
+#document
+| <html>
+|   <head>
+|   <body>
+|     "FOO>;;BAR"
+
+#data
+I'm &notit; I tell you
+#errors
+#document
+| <html>
+|   <head>
+|   <body>
+|     "I'm ¬it; I tell you"
+
+#data
+I'm &notin; I tell you
+#errors
+#document
+| <html>
+|   <head>
+|   <body>
+|     "I'm ∉ I tell you"
+
+#data
+FOO& BAR
+#errors
+#document
+| <html>
+|   <head>
+|   <body>
+|     "FOO& BAR"
+
+#data
+FOO&<BAR>
+#errors
+#document
+| <html>
+|   <head>
+|   <body>
+|     "FOO&"
+|     <bar>
+
+#data
+FOO&&&&gt;BAR
+#errors
+#document
+| <html>
+|   <head>
+|   <body>
+|     "FOO&&&>BAR"
+
+#data
+FOO&#41;BAR
+#errors
+#document
+| <html>
+|   <head>
+|   <body>
+|     "FOO)BAR"
+
+#data
+FOO&#x41;BAR
+#errors
+#document
+| <html>
+|   <head>
+|   <body>
+|     "FOOABAR"
+
+#data
+FOO&#X41;BAR
+#errors
+#document
+| <html>
+|   <head>
+|   <body>
+|     "FOOABAR"
+
+#data
+FOO&#BAR
+#errors
+#document
+| <html>
+|   <head>
+|   <body>
+|     "FOO&#BAR"
+
+#data
+FOO&#ZOO
+#errors
+#document
+| <html>
+|   <head>
+|   <body>
+|     "FOO&#ZOO"
+
+#data
+FOO&#xBAR
+#errors
+#document
+| <html>
+|   <head>
+|   <body>
+|     "FOOºR"
+
+#data
+FOO&#xZOO
+#errors
+#document
+| <html>
+|   <head>
+|   <body>
+|     "FOO&#xZOO"
+
+#data
+FOO&#XZOO
+#errors
+#document
+| <html>
+|   <head>
+|   <body>
+|     "FOO&#XZOO"
+
+#data
+FOO&#41BAR
+#errors
+#document
+| <html>
+|   <head>
+|   <body>
+|     "FOO)BAR"
+
+#data
+FOO&#x41BAR
+#errors
+#document
+| <html>
+|   <head>
+|   <body>
+|     "FOO䆺R"
+
+#data
+FOO&#x41ZOO
+#errors
+#document
+| <html>
+|   <head>
+|   <body>
+|     "FOOAZOO"
+
+#data
+FOO&#x0000;ZOO
+#errors
+#document
+| <html>
+|   <head>
+|   <body>
+|     "FOO�ZOO"
+
+#data
+FOO&#x0078;ZOO
+#errors
+#document
+| <html>
+|   <head>
+|   <body>
+|     "FOOxZOO"
+
+#data
+FOO&#x0079;ZOO
+#errors
+#document
+| <html>
+|   <head>
+|   <body>
+|     "FOOyZOO"
+
+#data
+FOO&#x0080;ZOO
+#errors
+#document
+| <html>
+|   <head>
+|   <body>
+|     "FOO€ZOO"
+
+#data
+FOO&#x0081;ZOO
+#errors
+#document
+| <html>
+|   <head>
+|   <body>
+|     "FOOZOO"
+
+#data
+FOO&#x0082;ZOO
+#errors
+#document
+| <html>
+|   <head>
+|   <body>
+|     "FOO‚ZOO"
+
+#data
+FOO&#x0083;ZOO
+#errors
+#document
+| <html>
+|   <head>
+|   <body>
+|     "FOOƒZOO"
+
+#data
+FOO&#x0084;ZOO
+#errors
+#document
+| <html>
+|   <head>
+|   <body>
+|     "FOO„ZOO"
+
+#data
+FOO&#x0085;ZOO
+#errors
+#document
+| <html>
+|   <head>
+|   <body>
+|     "FOO…ZOO"
+
+#data
+FOO&#x0086;ZOO
+#errors
+#document
+| <html>
+|   <head>
+|   <body>
+|     "FOO†ZOO"
+
+#data
+FOO&#x0087;ZOO
+#errors
+#document
+| <html>
+|   <head>
+|   <body>
+|     "FOO‡ZOO"
+
+#data
+FOO&#x0088;ZOO
+#errors
+#document
+| <html>
+|   <head>
+|   <body>
+|     "FOOˆZOO"
+
+#data
+FOO&#x0089;ZOO
+#errors
+#document
+| <html>
+|   <head>
+|   <body>
+|     "FOO‰ZOO"
+
+#data
+FOO&#x008A;ZOO
+#errors
+#document
+| <html>
+|   <head>
+|   <body>
+|     "FOOŠZOO"
+
+#data
+FOO&#x008B;ZOO
+#errors
+#document
+| <html>
+|   <head>
+|   <body>
+|     "FOO‹ZOO"
+
+#data
+FOO&#x008C;ZOO
+#errors
+#document
+| <html>
+|   <head>
+|   <body>
+|     "FOOŒZOO"
+
+#data
+FOO&#x008D;ZOO
+#errors
+#document
+| <html>
+|   <head>
+|   <body>
+|     "FOOZOO"
+
+#data
+FOO&#x008E;ZOO
+#errors
+#document
+| <html>
+|   <head>
+|   <body>
+|     "FOOŽZOO"
+
+#data
+FOO&#x008F;ZOO
+#errors
+#document
+| <html>
+|   <head>
+|   <body>
+|     "FOOZOO"
+
+#data
+FOO&#x0090;ZOO
+#errors
+#document
+| <html>
+|   <head>
+|   <body>
+|     "FOOZOO"
+
+#data
+FOO&#x0091;ZOO
+#errors
+#document
+| <html>
+|   <head>
+|   <body>
+|     "FOO‘ZOO"
+
+#data
+FOO&#x0092;ZOO
+#errors
+#document
+| <html>
+|   <head>
+|   <body>
+|     "FOO’ZOO"
+
+#data
+FOO&#x0093;ZOO
+#errors
+#document
+| <html>
+|   <head>
+|   <body>
+|     "FOO“ZOO"
+
+#data
+FOO&#x0094;ZOO
+#errors
+#document
+| <html>
+|   <head>
+|   <body>
+|     "FOO”ZOO"
+
+#data
+FOO&#x0095;ZOO
+#errors
+#document
+| <html>
+|   <head>
+|   <body>
+|     "FOO•ZOO"
+
+#data
+FOO&#x0096;ZOO
+#errors
+#document
+| <html>
+|   <head>
+|   <body>
+|     "FOO–ZOO"
+
+#data
+FOO&#x0097;ZOO
+#errors
+#document
+| <html>
+|   <head>
+|   <body>
+|     "FOO—ZOO"
+
+#data
+FOO&#x0098;ZOO
+#errors
+#document
+| <html>
+|   <head>
+|   <body>
+|     "FOO˜ZOO"
+
+#data
+FOO&#x0099;ZOO
+#errors
+#document
+| <html>
+|   <head>
+|   <body>
+|     "FOO™ZOO"
+
+#data
+FOO&#x009A;ZOO
+#errors
+#document
+| <html>
+|   <head>
+|   <body>
+|     "FOOšZOO"
+
+#data
+FOO&#x009B;ZOO
+#errors
+#document
+| <html>
+|   <head>
+|   <body>
+|     "FOO›ZOO"
+
+#data
+FOO&#x009C;ZOO
+#errors
+#document
+| <html>
+|   <head>
+|   <body>
+|     "FOOœZOO"
+
+#data
+FOO&#x009D;ZOO
+#errors
+#document
+| <html>
+|   <head>
+|   <body>
+|     "FOOZOO"
+
+#data
+FOO&#x009E;ZOO
+#errors
+#document
+| <html>
+|   <head>
+|   <body>
+|     "FOOžZOO"
+
+#data
+FOO&#x009F;ZOO
+#errors
+#document
+| <html>
+|   <head>
+|   <body>
+|     "FOOŸZOO"
+
+#data
+FOO&#x00A0;ZOO
+#errors
+#document
+| <html>
+|   <head>
+|   <body>
+|     "FOO ZOO"
+
+#data
+FOO&#xD7FF;ZOO
+#errors
+#document
+| <html>
+|   <head>
+|   <body>
+|     "FOO퟿ZOO"
+
+#data
+FOO&#xD800;ZOO
+#errors
+#document
+| <html>
+|   <head>
+|   <body>
+|     "FOO�ZOO"
+
+#data
+FOO&#xD801;ZOO
+#errors
+#document
+| <html>
+|   <head>
+|   <body>
+|     "FOO�ZOO"
+
+#data
+FOO&#xDFFE;ZOO
+#errors
+#document
+| <html>
+|   <head>
+|   <body>
+|     "FOO�ZOO"
+
+#data
+FOO&#xDFFF;ZOO
+#errors
+#document
+| <html>
+|   <head>
+|   <body>
+|     "FOO�ZOO"
+
+#data
+FOO&#xE000;ZOO
+#errors
+#document
+| <html>
+|   <head>
+|   <body>
+|     "FOOZOO"
+
+#data
+FOO&#x10FFFE;ZOO
+#errors
+#document
+| <html>
+|   <head>
+|   <body>
+|     "FOO􏿾ZOO"
+
+#data
+FOO&#x1087D4;ZOO
+#errors
+#document
+| <html>
+|   <head>
+|   <body>
+|     "FOO􈟔ZOO"
+
+#data
+FOO&#x10FFFF;ZOO
+#errors
+#document
+| <html>
+|   <head>
+|   <body>
+|     "FOO􏿿ZOO"
+
+#data
+FOO&#x110000;ZOO
+#errors
+#document
+| <html>
+|   <head>
+|   <body>
+|     "FOO�ZOO"
+
+#data
+FOO&#xFFFFFF;ZOO
+#errors
+#document
+| <html>
+|   <head>
+|   <body>
+|     "FOO�ZOO"
diff --git a/html/test/data/tree-construction/entities02.dat b/html/test/data/tree-construction/entities02.dat
new file mode 100644
index 0000000..e2fb42a
--- /dev/null
+++ b/html/test/data/tree-construction/entities02.dat
@@ -0,0 +1,249 @@
+#data
+<div bar="ZZ&gt;YY"></div>
+#errors
+#document
+| <html>
+|   <head>
+|   <body>
+|     <div>
+|       bar="ZZ>YY"
+
+#data
+<div bar="ZZ&"></div>
+#errors
+#document
+| <html>
+|   <head>
+|   <body>
+|     <div>
+|       bar="ZZ&"
+
+#data
+<div bar='ZZ&'></div>
+#errors
+#document
+| <html>
+|   <head>
+|   <body>
+|     <div>
+|       bar="ZZ&"
+
+#data
+<div bar=ZZ&></div>
+#errors
+#document
+| <html>
+|   <head>
+|   <body>
+|     <div>
+|       bar="ZZ&"
+
+#data
+<div bar="ZZ&gt=YY"></div>
+#errors
+#document
+| <html>
+|   <head>
+|   <body>
+|     <div>
+|       bar="ZZ&gt=YY"
+
+#data
+<div bar="ZZ&gt0YY"></div>
+#errors
+#document
+| <html>
+|   <head>
+|   <body>
+|     <div>
+|       bar="ZZ&gt0YY"
+
+#data
+<div bar="ZZ&gt9YY"></div>
+#errors
+#document
+| <html>
+|   <head>
+|   <body>
+|     <div>
+|       bar="ZZ&gt9YY"
+
+#data
+<div bar="ZZ&gtaYY"></div>
+#errors
+#document
+| <html>
+|   <head>
+|   <body>
+|     <div>
+|       bar="ZZ&gtaYY"
+
+#data
+<div bar="ZZ&gtZYY"></div>
+#errors
+#document
+| <html>
+|   <head>
+|   <body>
+|     <div>
+|       bar="ZZ&gtZYY"
+
+#data
+<div bar="ZZ&gt YY"></div>
+#errors
+#document
+| <html>
+|   <head>
+|   <body>
+|     <div>
+|       bar="ZZ> YY"
+
+#data
+<div bar="ZZ&gt"></div>
+#errors
+#document
+| <html>
+|   <head>
+|   <body>
+|     <div>
+|       bar="ZZ>"
+
+#data
+<div bar='ZZ&gt'></div>
+#errors
+#document
+| <html>
+|   <head>
+|   <body>
+|     <div>
+|       bar="ZZ>"
+
+#data
+<div bar=ZZ&gt></div>
+#errors
+#document
+| <html>
+|   <head>
+|   <body>
+|     <div>
+|       bar="ZZ>"
+
+#data
+<div bar="ZZ&pound_id=23"></div>
+#errors
+#document
+| <html>
+|   <head>
+|   <body>
+|     <div>
+|       bar="ZZ£_id=23"
+
+#data
+<div bar="ZZ&prod_id=23"></div>
+#errors
+#document
+| <html>
+|   <head>
+|   <body>
+|     <div>
+|       bar="ZZ&prod_id=23"
+
+#data
+<div bar="ZZ&pound;_id=23"></div>
+#errors
+#document
+| <html>
+|   <head>
+|   <body>
+|     <div>
+|       bar="ZZ£_id=23"
+
+#data
+<div bar="ZZ&prod;_id=23"></div>
+#errors
+#document
+| <html>
+|   <head>
+|   <body>
+|     <div>
+|       bar="ZZ∏_id=23"
+
+#data
+<div bar="ZZ&pound=23"></div>
+#errors
+#document
+| <html>
+|   <head>
+|   <body>
+|     <div>
+|       bar="ZZ&pound=23"
+
+#data
+<div bar="ZZ&prod=23"></div>
+#errors
+#document
+| <html>
+|   <head>
+|   <body>
+|     <div>
+|       bar="ZZ&prod=23"
+
+#data
+<div>ZZ&pound_id=23</div>
+#errors
+#document
+| <html>
+|   <head>
+|   <body>
+|     <div>
+|       "ZZ£_id=23"
+
+#data
+<div>ZZ&prod_id=23</div>
+#errors
+#document
+| <html>
+|   <head>
+|   <body>
+|     <div>
+|       "ZZ&prod_id=23"
+
+#data
+<div>ZZ&pound;_id=23</div>
+#errors
+#document
+| <html>
+|   <head>
+|   <body>
+|     <div>
+|       "ZZ£_id=23"
+
+#data
+<div>ZZ&prod;_id=23</div>
+#errors
+#document
+| <html>
+|   <head>
+|   <body>
+|     <div>
+|       "ZZ∏_id=23"
+
+#data
+<div>ZZ&pound=23</div>
+#errors
+#document
+| <html>
+|   <head>
+|   <body>
+|     <div>
+|       "ZZ£=23"
+
+#data
+<div>ZZ&prod=23</div>
+#errors
+#document
+| <html>
+|   <head>
+|   <body>
+|     <div>
+|       "ZZ&prod=23"
diff --git a/html/test/data/tree-construction/html5test-com.dat b/html/test/data/tree-construction/html5test-com.dat
new file mode 100644
index 0000000..d7cb71d
--- /dev/null
+++ b/html/test/data/tree-construction/html5test-com.dat
@@ -0,0 +1,246 @@
+#data
+<div<div>
+#errors
+#document
+| <html>
+|   <head>
+|   <body>
+|     <div<div>
+
+#data
+<div foo<bar=''>
+#errors
+#document
+| <html>
+|   <head>
+|   <body>
+|     <div>
+|       foo<bar=""
+
+#data
+<div foo=`bar`>
+#errors
+#document
+| <html>
+|   <head>
+|   <body>
+|     <div>
+|       foo="`bar`"
+
+#data
+<div \"foo=''>
+#errors
+#document
+| <html>
+|   <head>
+|   <body>
+|     <div>
+|       \"foo=""
+
+#data
+<a href='\nbar'></a>
+#errors
+#document
+| <html>
+|   <head>
+|   <body>
+|     <a>
+|       href="\nbar"
+
+#data
+<!DOCTYPE html>
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+
+#data
+&lang;&rang;
+#errors
+#document
+| <html>
+|   <head>
+|   <body>
+|     "⟨⟩"
+
+#data
+&apos;
+#errors
+#document
+| <html>
+|   <head>
+|   <body>
+|     "'"
+
+#data
+&ImaginaryI;
+#errors
+#document
+| <html>
+|   <head>
+|   <body>
+|     "ⅈ"
+
+#data
+&Kopf;
+#errors
+#document
+| <html>
+|   <head>
+|   <body>
+|     "𝕂"
+
+#data
+&notinva;
+#errors
+#document
+| <html>
+|   <head>
+|   <body>
+|     "∉"
+
+#data
+<?import namespace="foo" implementation="#bar">
+#errors
+#document
+| <!-- ?import namespace="foo" implementation="#bar" -->
+| <html>
+|   <head>
+|   <body>
+
+#data
+<!--foo--bar-->
+#errors
+#document
+| <!-- foo--bar -->
+| <html>
+|   <head>
+|   <body>
+
+#data
+<![CDATA[x]]>
+#errors
+#document
+| <!-- [CDATA[x]] -->
+| <html>
+|   <head>
+|   <body>
+
+#data
+<textarea><!--</textarea>--></textarea>
+#errors
+#document
+| <html>
+|   <head>
+|   <body>
+|     <textarea>
+|       "<!--"
+|     "-->"
+
+#data
+<textarea><!--</textarea>-->
+#errors
+#document
+| <html>
+|   <head>
+|   <body>
+|     <textarea>
+|       "<!--"
+|     "-->"
+
+#data
+<style><!--</style>--></style>
+#errors
+#document
+| <html>
+|   <head>
+|     <style>
+|       "<!--"
+|   <body>
+|     "-->"
+
+#data
+<style><!--</style>-->
+#errors
+#document
+| <html>
+|   <head>
+|     <style>
+|       "<!--"
+|   <body>
+|     "-->"
+
+#data
+<ul><li>A </li> <li>B</li></ul>
+#errors
+#document
+| <html>
+|   <head>
+|   <body>
+|     <ul>
+|       <li>
+|         "A "
+|       " "
+|       <li>
+|         "B"
+
+#data
+<table><form><input type=hidden><input></form><div></div></table>
+#errors
+#document
+| <html>
+|   <head>
+|   <body>
+|     <input>
+|     <div>
+|     <table>
+|       <form>
+|       <input>
+|         type="hidden"
+
+#data
+<i>A<b>B<p></i>C</b>D
+#errors
+#document
+| <html>
+|   <head>
+|   <body>
+|     <i>
+|       "A"
+|       <b>
+|         "B"
+|     <b>
+|     <p>
+|       <b>
+|         <i>
+|         "C"
+|       "D"
+
+#data
+<div></div>
+#errors
+#document
+| <html>
+|   <head>
+|   <body>
+|     <div>
+
+#data
+<svg></svg>
+#errors
+#document
+| <html>
+|   <head>
+|   <body>
+|     <svg svg>
+
+#data
+<math></math>
+#errors
+#document
+| <html>
+|   <head>
+|   <body>
+|     <math math>
diff --git a/html/test/data/tree-construction/inbody01.dat b/html/test/data/tree-construction/inbody01.dat
new file mode 100644
index 0000000..3f2bd37
--- /dev/null
+++ b/html/test/data/tree-construction/inbody01.dat
@@ -0,0 +1,43 @@
+#data
+<button>1</foo>
+#errors
+#document
+| <html>
+|   <head>
+|   <body>
+|     <button>
+|       "1"
+
+#data
+<foo>1<p>2</foo>
+#errors
+#document
+| <html>
+|   <head>
+|   <body>
+|     <foo>
+|       "1"
+|       <p>
+|         "2"
+
+#data
+<dd>1</foo>
+#errors
+#document
+| <html>
+|   <head>
+|   <body>
+|     <dd>
+|       "1"
+
+#data
+<foo>1<dd>2</foo>
+#errors
+#document
+| <html>
+|   <head>
+|   <body>
+|     <foo>
+|       "1"
+|       <dd>
+|         "2"
diff --git a/html/test/data/tree-construction/isindex.dat b/html/test/data/tree-construction/isindex.dat
new file mode 100644
index 0000000..88325ff
--- /dev/null
+++ b/html/test/data/tree-construction/isindex.dat
@@ -0,0 +1,40 @@
+#data
+<isindex>
+#errors
+#document
+| <html>
+|   <head>
+|   <body>
+|     <form>
+|       <hr>
+|       <label>
+|         "This is a searchable index. Enter search keywords: "
+|         <input>
+|           name="isindex"
+|       <hr>
+
+#data
+<isindex name="A" action="B" prompt="C" foo="D">
+#errors
+#document
+| <html>
+|   <head>
+|   <body>
+|     <form>
+|       action="B"
+|       <hr>
+|       <label>
+|         "C"
+|         <input>
+|           foo="D"
+|           name="isindex"
+|       <hr>
+
+#data
+<form><isindex>
+#errors
+#document
+| <html>
+|   <head>
+|   <body>
+|     <form>
diff --git a/html/test/data/tree-construction/pending-spec-changes-plain-text-unsafe.dat b/html/test/data/tree-construction/pending-spec-changes-plain-text-unsafe.dat
new file mode 100644
index 0000000..a5ebb1e
--- /dev/null
+++ b/html/test/data/tree-construction/pending-spec-changes-plain-text-unsafe.dat
Binary files differ
diff --git a/html/test/data/tree-construction/pending-spec-changes.dat b/html/test/data/tree-construction/pending-spec-changes.dat
new file mode 100644
index 0000000..5a92084
--- /dev/null
+++ b/html/test/data/tree-construction/pending-spec-changes.dat
@@ -0,0 +1,52 @@
+#data
+<input type="hidden"><frameset>
+#errors
+21: Start tag seen without seeing a doctype first. Expected “<!DOCTYPE html>”.
+31: “frameset” start tag seen.
+31: End of file seen and there were open elements.
+#document
+| <html>
+|   <head>
+|   <frameset>
+
+#data
+<!DOCTYPE html><table><caption><svg>foo</table>bar
+#errors
+47: End tag “table” did not match the name of the current open element (“svg”).
+47: “table” closed but “caption” was still open.
+47: End tag “table” seen, but there were open elements.
+36: Unclosed element “svg”.
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     <table>
+|       <caption>
+|         <svg svg>
+|           "foo"
+|     "bar"
+
+#data
+<table><tr><td><svg><desc><td></desc><circle>
+#errors
+7: Start tag seen without seeing a doctype first. Expected “<!DOCTYPE html>”.
+30: A table cell was implicitly closed, but there were open elements.
+26: Unclosed element “desc”.
+20: Unclosed element “svg”.
+37: Stray end tag “desc”.
+45: End of file seen and there were open elements.
+45: Unclosed element “circle”.
+7: Unclosed element “table”.
+#document
+| <html>
+|   <head>
+|   <body>
+|     <table>
+|       <tbody>
+|         <tr>
+|           <td>
+|             <svg svg>
+|               <svg desc>
+|           <td>
+|             <circle>
diff --git a/html/test/data/tree-construction/plain-text-unsafe.dat b/html/test/data/tree-construction/plain-text-unsafe.dat
new file mode 100644
index 0000000..04cc11f
--- /dev/null
+++ b/html/test/data/tree-construction/plain-text-unsafe.dat
Binary files differ
diff --git a/html/test/data/tree-construction/scriptdata01.dat b/html/test/data/tree-construction/scriptdata01.dat
new file mode 100644
index 0000000..76b67f4
--- /dev/null
+++ b/html/test/data/tree-construction/scriptdata01.dat
@@ -0,0 +1,308 @@
+#data
+FOO<script>'Hello'</script>BAR
+#errors
+#document
+| <html>
+|   <head>
+|   <body>
+|     "FOO"
+|     <script>
+|       "'Hello'"
+|     "BAR"
+
+#data
+FOO<script></script>BAR
+#errors
+#document
+| <html>
+|   <head>
+|   <body>
+|     "FOO"
+|     <script>
+|     "BAR"
+
+#data
+FOO<script></script >BAR
+#errors
+#document
+| <html>
+|   <head>
+|   <body>
+|     "FOO"
+|     <script>
+|     "BAR"
+
+#data
+FOO<script></script/>BAR
+#errors
+#document
+| <html>
+|   <head>
+|   <body>
+|     "FOO"
+|     <script>
+|     "BAR"
+
+#data
+FOO<script></script/ >BAR
+#errors
+#document
+| <html>
+|   <head>
+|   <body>
+|     "FOO"
+|     <script>
+|     "BAR"
+
+#data
+FOO<script type="text/plain"></scriptx>BAR
+#errors
+#document
+| <html>
+|   <head>
+|   <body>
+|     "FOO"
+|     <script>
+|       type="text/plain"
+|       "</scriptx>BAR"
+
+#data
+FOO<script></script foo=">" dd>BAR
+#errors
+#document
+| <html>
+|   <head>
+|   <body>
+|     "FOO"
+|     <script>
+|     "BAR"
+
+#data
+FOO<script>'<'</script>BAR
+#errors
+#document
+| <html>
+|   <head>
+|   <body>
+|     "FOO"
+|     <script>
+|       "'<'"
+|     "BAR"
+
+#data
+FOO<script>'<!'</script>BAR
+#errors
+#document
+| <html>
+|   <head>
+|   <body>
+|     "FOO"
+|     <script>
+|       "'<!'"
+|     "BAR"
+
+#data
+FOO<script>'<!-'</script>BAR
+#errors
+#document
+| <html>
+|   <head>
+|   <body>
+|     "FOO"
+|     <script>
+|       "'<!-'"
+|     "BAR"
+
+#data
+FOO<script>'<!--'</script>BAR
+#errors
+#document
+| <html>
+|   <head>
+|   <body>
+|     "FOO"
+|     <script>
+|       "'<!--'"
+|     "BAR"
+
+#data
+FOO<script>'<!---'</script>BAR
+#errors
+#document
+| <html>
+|   <head>
+|   <body>
+|     "FOO"
+|     <script>
+|       "'<!---'"
+|     "BAR"
+
+#data
+FOO<script>'<!-->'</script>BAR
+#errors
+#document
+| <html>
+|   <head>
+|   <body>
+|     "FOO"
+|     <script>
+|       "'<!-->'"
+|     "BAR"
+
+#data
+FOO<script>'<!-->'</script>BAR
+#errors
+#document
+| <html>
+|   <head>
+|   <body>
+|     "FOO"
+|     <script>
+|       "'<!-->'"
+|     "BAR"
+
+#data
+FOO<script>'<!-- potato'</script>BAR
+#errors
+#document
+| <html>
+|   <head>
+|   <body>
+|     "FOO"
+|     <script>
+|       "'<!-- potato'"
+|     "BAR"
+
+#data
+FOO<script>'<!-- <sCrIpt'</script>BAR
+#errors
+#document
+| <html>
+|   <head>
+|   <body>
+|     "FOO"
+|     <script>
+|       "'<!-- <sCrIpt'"
+|     "BAR"
+
+#data
+FOO<script type="text/plain">'<!-- <sCrIpt>'</script>BAR
+#errors
+#document
+| <html>
+|   <head>
+|   <body>
+|     "FOO"
+|     <script>
+|       type="text/plain"
+|       "'<!-- <sCrIpt>'</script>BAR"
+
+#data
+FOO<script type="text/plain">'<!-- <sCrIpt> -'</script>BAR
+#errors
+#document
+| <html>
+|   <head>
+|   <body>
+|     "FOO"
+|     <script>
+|       type="text/plain"
+|       "'<!-- <sCrIpt> -'</script>BAR"
+
+#data
+FOO<script type="text/plain">'<!-- <sCrIpt> --'</script>BAR
+#errors
+#document
+| <html>
+|   <head>
+|   <body>
+|     "FOO"
+|     <script>
+|       type="text/plain"
+|       "'<!-- <sCrIpt> --'</script>BAR"
+
+#data
+FOO<script>'<!-- <sCrIpt> -->'</script>BAR
+#errors
+#document
+| <html>
+|   <head>
+|   <body>
+|     "FOO"
+|     <script>
+|       "'<!-- <sCrIpt> -->'"
+|     "BAR"
+
+#data
+FOO<script type="text/plain">'<!-- <sCrIpt> --!>'</script>BAR
+#errors
+#document
+| <html>
+|   <head>
+|   <body>
+|     "FOO"
+|     <script>
+|       type="text/plain"
+|       "'<!-- <sCrIpt> --!>'</script>BAR"
+
+#data
+FOO<script type="text/plain">'<!-- <sCrIpt> -- >'</script>BAR
+#errors
+#document
+| <html>
+|   <head>
+|   <body>
+|     "FOO"
+|     <script>
+|       type="text/plain"
+|       "'<!-- <sCrIpt> -- >'</script>BAR"
+
+#data
+FOO<script type="text/plain">'<!-- <sCrIpt '</script>BAR
+#errors
+#document
+| <html>
+|   <head>
+|   <body>
+|     "FOO"
+|     <script>
+|       type="text/plain"
+|       "'<!-- <sCrIpt '</script>BAR"
+
+#data
+FOO<script type="text/plain">'<!-- <sCrIpt/'</script>BAR
+#errors
+#document
+| <html>
+|   <head>
+|   <body>
+|     "FOO"
+|     <script>
+|       type="text/plain"
+|       "'<!-- <sCrIpt/'</script>BAR"
+
+#data
+FOO<script type="text/plain">'<!-- <sCrIpt\'</script>BAR
+#errors
+#document
+| <html>
+|   <head>
+|   <body>
+|     "FOO"
+|     <script>
+|       type="text/plain"
+|       "'<!-- <sCrIpt\'"
+|     "BAR"
+
+#data
+FOO<script type="text/plain">'<!-- <sCrIpt/'</script>BAR</script>QUX
+#errors
+#document
+| <html>
+|   <head>
+|   <body>
+|     "FOO"
+|     <script>
+|       type="text/plain"
+|       "'<!-- <sCrIpt/'</script>BAR"
+|     "QUX"
diff --git a/html/test/data/tree-construction/scripted/adoption01.dat b/html/test/data/tree-construction/scripted/adoption01.dat
new file mode 100644
index 0000000..4e08d0e
--- /dev/null
+++ b/html/test/data/tree-construction/scripted/adoption01.dat
@@ -0,0 +1,15 @@
+#data
+<p><b id="A"><script>document.getElementById("A").id = "B"</script></p>TEXT</b>
+#errors
+#document
+| <html>
+|   <head>
+|   <body>
+|     <p>
+|       <b>
+|         id="B"
+|         <script>
+|           "document.getElementById("A").id = "B""
+|     <b>
+|       id="A"
+|       "TEXT"
diff --git a/html/test/data/tree-construction/scripted/ark.dat b/html/test/data/tree-construction/scripted/ark.dat
new file mode 100644
index 0000000..acbac41
--- /dev/null
+++ b/html/test/data/tree-construction/scripted/ark.dat
@@ -0,0 +1,26 @@
+#data
+<p><font size=4><font size=4><font size=4><script>document.getElementsByTagName("font")[2].setAttribute("size", "5");</script><font size=4><p>X
+#errors
+#document
+| <html>
+|   <head>
+|   <body>
+|     <p>
+|       <font>
+|         size="4"
+|         <font>
+|           size="4"
+|           <font>
+|             size="5"
+|             <script>
+|               "document.getElementsByTagName("font")[2].setAttribute("size", "5");"
+|             <font>
+|               size="4"
+|     <p>
+|       <font>
+|         size="4"
+|         <font>
+|           size="4"
+|           <font>
+|             size="4"
+|             "X"
diff --git a/html/test/data/tree-construction/scripted/webkit01.dat b/html/test/data/tree-construction/scripted/webkit01.dat
new file mode 100644
index 0000000..ef4a41c
--- /dev/null
+++ b/html/test/data/tree-construction/scripted/webkit01.dat
@@ -0,0 +1,28 @@
+#data
+1<script>document.write("2")</script>3
+#errors
+#document
+| <html>
+|   <head>
+|   <body>
+|     "1"
+|     <script>
+|       "document.write("2")"
+|     "23"
+
+#data
+1<script>document.write("<script>document.write('2')</scr"+ "ipt><script>document.write('3')</scr" + "ipt>")</script>4
+#errors
+#document
+| <html>
+|   <head>
+|   <body>
+|     "1"
+|     <script>
+|       "document.write("<script>document.write('2')</scr"+ "ipt><script>document.write('3')</scr" + "ipt>")"
+|     <script>
+|       "document.write('2')"
+|     "2"
+|     <script>
+|       "document.write('3')"
+|     "34"
diff --git a/html/test/data/tree-construction/tables01.dat b/html/test/data/tree-construction/tables01.dat
new file mode 100644
index 0000000..c4b47e4
--- /dev/null
+++ b/html/test/data/tree-construction/tables01.dat
@@ -0,0 +1,212 @@
+#data
+<table><th>
+#errors
+#document
+| <html>
+|   <head>
+|   <body>
+|     <table>
+|       <tbody>
+|         <tr>
+|           <th>
+
+#data
+<table><td>
+#errors
+#document
+| <html>
+|   <head>
+|   <body>
+|     <table>
+|       <tbody>
+|         <tr>
+|           <td>
+
+#data
+<table><col foo='bar'>
+#errors
+#document
+| <html>
+|   <head>
+|   <body>
+|     <table>
+|       <colgroup>
+|         <col>
+|           foo="bar"
+
+#data
+<table><colgroup></html>foo
+#errors
+#document
+| <html>
+|   <head>
+|   <body>
+|     "foo"
+|     <table>
+|       <colgroup>
+
+#data
+<table></table><p>foo
+#errors
+#document
+| <html>
+|   <head>
+|   <body>
+|     <table>
+|     <p>
+|       "foo"
+
+#data
+<table></body></caption></col></colgroup></html></tbody></td></tfoot></th></thead></tr><td>
+#errors
+#document
+| <html>
+|   <head>
+|   <body>
+|     <table>
+|       <tbody>
+|         <tr>
+|           <td>
+
+#data
+<table><select><option>3</select></table>
+#errors
+#document
+| <html>
+|   <head>
+|   <body>
+|     <select>
+|       <option>
+|         "3"
+|     <table>
+
+#data
+<table><select><table></table></select></table>
+#errors
+#document
+| <html>
+|   <head>
+|   <body>
+|     <select>
+|     <table>
+|     <table>
+
+#data
+<table><select></table>
+#errors
+#document
+| <html>
+|   <head>
+|   <body>
+|     <select>
+|     <table>
+
+#data
+<table><select><option>A<tr><td>B</td></tr></table>
+#errors
+#document
+| <html>
+|   <head>
+|   <body>
+|     <select>
+|       <option>
+|         "A"
+|     <table>
+|       <tbody>
+|         <tr>
+|           <td>
+|             "B"
+
+#data
+<table><td></body></caption></col></colgroup></html>foo
+#errors
+#document
+| <html>
+|   <head>
+|   <body>
+|     <table>
+|       <tbody>
+|         <tr>
+|           <td>
+|             "foo"
+
+#data
+<table><td>A</table>B
+#errors
+#document
+| <html>
+|   <head>
+|   <body>
+|     <table>
+|       <tbody>
+|         <tr>
+|           <td>
+|             "A"
+|     "B"
+
+#data
+<table><tr><caption>
+#errors
+#document
+| <html>
+|   <head>
+|   <body>
+|     <table>
+|       <tbody>
+|         <tr>
+|       <caption>
+
+#data
+<table><tr></body></caption></col></colgroup></html></td></th><td>foo
+#errors
+#document
+| <html>
+|   <head>
+|   <body>
+|     <table>
+|       <tbody>
+|         <tr>
+|           <td>
+|             "foo"
+
+#data
+<table><td><tr>
+#errors
+#document
+| <html>
+|   <head>
+|   <body>
+|     <table>
+|       <tbody>
+|         <tr>
+|           <td>
+|         <tr>
+
+#data
+<table><td><button><td>
+#errors
+#document
+| <html>
+|   <head>
+|   <body>
+|     <table>
+|       <tbody>
+|         <tr>
+|           <td>
+|             <button>
+|           <td>
+
+#data
+<table><tr><td><svg><desc><td>
+#errors
+#document
+| <html>
+|   <head>
+|   <body>
+|     <table>
+|       <tbody>
+|         <tr>
+|           <td>
+|             <svg svg>
+|               <svg desc>
+|           <td>
diff --git a/html/test/data/tree-construction/tests1.dat b/html/test/data/tree-construction/tests1.dat
new file mode 100644
index 0000000..cbf8bdd
--- /dev/null
+++ b/html/test/data/tree-construction/tests1.dat
@@ -0,0 +1,1952 @@
+#data
+Test
+#errors
+Line: 1 Col: 4 Unexpected non-space characters. Expected DOCTYPE.
+#document
+| <html>
+|   <head>
+|   <body>
+|     "Test"
+
+#data
+<p>One<p>Two
+#errors
+Line: 1 Col: 3 Unexpected start tag (p). Expected DOCTYPE.
+#document
+| <html>
+|   <head>
+|   <body>
+|     <p>
+|       "One"
+|     <p>
+|       "Two"
+
+#data
+Line1<br>Line2<br>Line3<br>Line4
+#errors
+Line: 1 Col: 5 Unexpected non-space characters. Expected DOCTYPE.
+#document
+| <html>
+|   <head>
+|   <body>
+|     "Line1"
+|     <br>
+|     "Line2"
+|     <br>
+|     "Line3"
+|     <br>
+|     "Line4"
+
+#data
+<html>
+#errors
+Line: 1 Col: 6 Unexpected start tag (html). Expected DOCTYPE.
+#document
+| <html>
+|   <head>
+|   <body>
+
+#data
+<head>
+#errors
+Line: 1 Col: 6 Unexpected start tag (head). Expected DOCTYPE.
+#document
+| <html>
+|   <head>
+|   <body>
+
+#data
+<body>
+#errors
+Line: 1 Col: 6 Unexpected start tag (body). Expected DOCTYPE.
+#document
+| <html>
+|   <head>
+|   <body>
+
+#data
+<html><head>
+#errors
+Line: 1 Col: 6 Unexpected start tag (html). Expected DOCTYPE.
+#document
+| <html>
+|   <head>
+|   <body>
+
+#data
+<html><head></head>
+#errors
+Line: 1 Col: 6 Unexpected start tag (html). Expected DOCTYPE.
+#document
+| <html>
+|   <head>
+|   <body>
+
+#data
+<html><head></head><body>
+#errors
+Line: 1 Col: 6 Unexpected start tag (html). Expected DOCTYPE.
+#document
+| <html>
+|   <head>
+|   <body>
+
+#data
+<html><head></head><body></body>
+#errors
+Line: 1 Col: 6 Unexpected start tag (html). Expected DOCTYPE.
+#document
+| <html>
+|   <head>
+|   <body>
+
+#data
+<html><head><body></body></html>
+#errors
+Line: 1 Col: 6 Unexpected start tag (html). Expected DOCTYPE.
+#document
+| <html>
+|   <head>
+|   <body>
+
+#data
+<html><head></body></html>
+#errors
+Line: 1 Col: 6 Unexpected start tag (html). Expected DOCTYPE.
+Line: 1 Col: 19 Unexpected end tag (body).
+Line: 1 Col: 26 Unexpected end tag (html).
+#document
+| <html>
+|   <head>
+|   <body>
+
+#data
+<html><head><body></html>
+#errors
+Line: 1 Col: 6 Unexpected start tag (html). Expected DOCTYPE.
+#document
+| <html>
+|   <head>
+|   <body>
+
+#data
+<html><body></html>
+#errors
+Line: 1 Col: 6 Unexpected start tag (html). Expected DOCTYPE.
+#document
+| <html>
+|   <head>
+|   <body>
+
+#data
+<body></html>
+#errors
+Line: 1 Col: 6 Unexpected start tag (body). Expected DOCTYPE.
+#document
+| <html>
+|   <head>
+|   <body>
+
+#data
+<head></html>
+#errors
+Line: 1 Col: 6 Unexpected start tag (head). Expected DOCTYPE.
+Line: 1 Col: 13 Unexpected end tag (html). Ignored.
+#document
+| <html>
+|   <head>
+|   <body>
+
+#data
+</head>
+#errors
+Line: 1 Col: 7 Unexpected end tag (head). Expected DOCTYPE.
+#document
+| <html>
+|   <head>
+|   <body>
+
+#data
+</body>
+#errors
+Line: 1 Col: 7 Unexpected end tag (body). Expected DOCTYPE.
+Line: 1 Col: 7 Unexpected end tag (body) after the (implied) root element.
+#document
+| <html>
+|   <head>
+|   <body>
+
+#data
+</html>
+#errors
+Line: 1 Col: 7 Unexpected end tag (html). Expected DOCTYPE.
+Line: 1 Col: 7 Unexpected end tag (html) after the (implied) root element.
+#document
+| <html>
+|   <head>
+|   <body>
+
+#data
+<b><table><td><i></table>
+#errors
+Line: 1 Col: 3 Unexpected start tag (b). Expected DOCTYPE.
+Line: 1 Col: 14 Unexpected table cell start tag (td) in the table body phase.
+Line: 1 Col: 25 Got table cell end tag (td) while required end tags are missing.
+Line: 1 Col: 25 Expected closing tag. Unexpected end of file.
+#document
+| <html>
+|   <head>
+|   <body>
+|     <b>
+|       <table>
+|         <tbody>
+|           <tr>
+|             <td>
+|               <i>
+
+#data
+<b><table><td></b><i></table>X
+#errors
+Line: 1 Col: 3 Unexpected start tag (b). Expected DOCTYPE.
+Line: 1 Col: 14 Unexpected table cell start tag (td) in the table body phase.
+Line: 1 Col: 18 End tag (b) violates step 1, paragraph 1 of the adoption agency algorithm.
+Line: 1 Col: 29 Got table cell end tag (td) while required end tags are missing.
+Line: 1 Col: 30 Expected closing tag. Unexpected end of file.
+#document
+| <html>
+|   <head>
+|   <body>
+|     <b>
+|       <table>
+|         <tbody>
+|           <tr>
+|             <td>
+|               <i>
+|       "X"
+
+#data
+<h1>Hello<h2>World
+#errors
+4: Start tag seen without seeing a doctype first. Expected “<!DOCTYPE html>”.
+13: Heading cannot be a child of another heading.
+18: End of file seen and there were open elements.
+#document
+| <html>
+|   <head>
+|   <body>
+|     <h1>
+|       "Hello"
+|     <h2>
+|       "World"
+
+#data
+<a><p>X<a>Y</a>Z</p></a>
+#errors
+Line: 1 Col: 3 Unexpected start tag (a). Expected DOCTYPE.
+Line: 1 Col: 10 Unexpected start tag (a) implies end tag (a).
+Line: 1 Col: 10 End tag (a) violates step 1, paragraph 3 of the adoption agency algorithm.
+Line: 1 Col: 24 End tag (a) violates step 1, paragraph 1 of the adoption agency algorithm.
+#document
+| <html>
+|   <head>
+|   <body>
+|     <a>
+|     <p>
+|       <a>
+|         "X"
+|       <a>
+|         "Y"
+|       "Z"
+
+#data
+<b><button>foo</b>bar
+#errors
+Line: 1 Col: 3 Unexpected start tag (b). Expected DOCTYPE.
+Line: 1 Col: 15 End tag (b) violates step 1, paragraph 1 of the adoption agency algorithm.
+#document
+| <html>
+|   <head>
+|   <body>
+|     <b>
+|     <button>
+|       <b>
+|         "foo"
+|       "bar"
+
+#data
+<!DOCTYPE html><span><button>foo</span>bar
+#errors
+39: End tag “span” seen but there were unclosed elements.
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     <span>
+|       <button>
+|         "foobar"
+
+#data
+<p><b><div><marquee></p></b></div>X
+#errors
+Line: 1 Col: 3 Unexpected start tag (p). Expected DOCTYPE.
+Line: 1 Col: 11 Unexpected end tag (p). Ignored.
+Line: 1 Col: 24 Unexpected end tag (p). Ignored.
+Line: 1 Col: 28 End tag (b) violates step 1, paragraph 1 of the adoption agency algorithm.
+Line: 1 Col: 34 End tag (div) seen too early. Expected other end tag.
+Line: 1 Col: 35 Expected closing tag. Unexpected end of file.
+#document
+| <html>
+|   <head>
+|   <body>
+|     <p>
+|       <b>
+|     <div>
+|       <b>
+|         <marquee>
+|           <p>
+|           "X"
+
+#data
+<script><div></script></div><title><p></title><p><p>
+#errors
+Line: 1 Col: 8 Unexpected start tag (script). Expected DOCTYPE.
+Line: 1 Col: 28 Unexpected end tag (div). Ignored.
+#document
+| <html>
+|   <head>
+|     <script>
+|       "<div>"
+|     <title>
+|       "<p>"
+|   <body>
+|     <p>
+|     <p>
+
+#data
+<!--><div>--<!-->
+#errors
+Line: 1 Col: 5 Incorrect comment.
+Line: 1 Col: 10 Unexpected start tag (div). Expected DOCTYPE.
+Line: 1 Col: 17 Incorrect comment.
+Line: 1 Col: 17 Expected closing tag. Unexpected end of file.
+#document
+| <!--  -->
+| <html>
+|   <head>
+|   <body>
+|     <div>
+|       "--"
+|       <!--  -->
+
+#data
+<p><hr></p>
+#errors
+Line: 1 Col: 3 Unexpected start tag (p). Expected DOCTYPE.
+Line: 1 Col: 11 Unexpected end tag (p). Ignored.
+#document
+| <html>
+|   <head>
+|   <body>
+|     <p>
+|     <hr>
+|     <p>
+
+#data
+<select><b><option><select><option></b></select>X
+#errors
+Line: 1 Col: 8 Unexpected start tag (select). Expected DOCTYPE.
+Line: 1 Col: 11 Unexpected start tag token (b) in the select phase. Ignored.
+Line: 1 Col: 27 Unexpected select start tag in the select phase treated as select end tag.
+Line: 1 Col: 39 End tag (b) violates step 1, paragraph 1 of the adoption agency algorithm.
+Line: 1 Col: 48 Unexpected end tag (select). Ignored.
+Line: 1 Col: 49 Expected closing tag. Unexpected end of file.
+#document
+| <html>
+|   <head>
+|   <body>
+|     <select>
+|       <option>
+|     <option>
+|       "X"
+
+#data
+<a><table><td><a><table></table><a></tr><a></table><b>X</b>C<a>Y
+#errors
+Line: 1 Col: 3 Unexpected start tag (a). Expected DOCTYPE.
+Line: 1 Col: 14 Unexpected table cell start tag (td) in the table body phase.
+Line: 1 Col: 35 Unexpected start tag (a) implies end tag (a).
+Line: 1 Col: 40 Got table cell end tag (td) while required end tags are missing.
+Line: 1 Col: 43 Unexpected start tag (a) in table context caused voodoo mode.
+Line: 1 Col: 43 Unexpected start tag (a) implies end tag (a).
+Line: 1 Col: 43 End tag (a) violates step 1, paragraph 1 of the adoption agency algorithm.
+Line: 1 Col: 51 Unexpected implied end tag (a) in the table phase.
+Line: 1 Col: 63 Unexpected start tag (a) implies end tag (a).
+Line: 1 Col: 64 Expected closing tag. Unexpected end of file.
+#document
+| <html>
+|   <head>
+|   <body>
+|     <a>
+|       <a>
+|       <table>
+|         <tbody>
+|           <tr>
+|             <td>
+|               <a>
+|                 <table>
+|               <a>
+|     <a>
+|       <b>
+|         "X"
+|       "C"
+|     <a>
+|       "Y"
+
+#data
+<a X>0<b>1<a Y>2
+#errors
+Line: 1 Col: 5 Unexpected start tag (a). Expected DOCTYPE.
+Line: 1 Col: 15 Unexpected start tag (a) implies end tag (a).
+Line: 1 Col: 15 End tag (a) violates step 1, paragraph 3 of the adoption agency algorithm.
+Line: 1 Col: 16 Expected closing tag. Unexpected end of file.
+#document
+| <html>
+|   <head>
+|   <body>
+|     <a>
+|       x=""
+|       "0"
+|       <b>
+|         "1"
+|     <b>
+|       <a>
+|         y=""
+|         "2"
+
+#data
+<!-----><font><div>hello<table>excite!<b>me!<th><i>please!</tr><!--X-->
+#errors
+Line: 1 Col: 7 Unexpected '-' after '--' found in comment.
+Line: 1 Col: 14 Unexpected start tag (font). Expected DOCTYPE.
+Line: 1 Col: 38 Unexpected non-space characters in table context caused voodoo mode.
+Line: 1 Col: 41 Unexpected start tag (b) in table context caused voodoo mode.
+Line: 1 Col: 48 Unexpected implied end tag (b) in the table phase.
+Line: 1 Col: 48 Unexpected table cell start tag (th) in the table body phase.
+Line: 1 Col: 63 Got table cell end tag (th) while required end tags are missing.
+Line: 1 Col: 71 Unexpected end of file. Expected table content.
+#document
+| <!-- - -->
+| <html>
+|   <head>
+|   <body>
+|     <font>
+|       <div>
+|         "helloexcite!"
+|         <b>
+|           "me!"
+|         <table>
+|           <tbody>
+|             <tr>
+|               <th>
+|                 <i>
+|                   "please!"
+|             <!-- X -->
+
+#data
+<!DOCTYPE html><li>hello<li>world<ul>how<li>do</ul>you</body><!--do-->
+#errors
+Line: 1 Col: 61 Unexpected end tag (li). Missing end tag (body).
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     <li>
+|       "hello"
+|     <li>
+|       "world"
+|       <ul>
+|         "how"
+|         <li>
+|           "do"
+|       "you"
+|   <!-- do -->
+
+#data
+<!DOCTYPE html>A<option>B<optgroup>C<select>D</option>E
+#errors
+Line: 1 Col: 54 Unexpected end tag (option) in the select phase. Ignored.
+Line: 1 Col: 55 Expected closing tag. Unexpected end of file.
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     "A"
+|     <option>
+|       "B"
+|     <optgroup>
+|       "C"
+|       <select>
+|         "DE"
+
+#data
+<
+#errors
+Line: 1 Col: 1 Expected tag name. Got something else instead
+Line: 1 Col: 1 Unexpected non-space characters. Expected DOCTYPE.
+#document
+| <html>
+|   <head>
+|   <body>
+|     "<"
+
+#data
+<#
+#errors
+Line: 1 Col: 1 Expected tag name. Got something else instead
+Line: 1 Col: 1 Unexpected non-space characters. Expected DOCTYPE.
+#document
+| <html>
+|   <head>
+|   <body>
+|     "<#"
+
+#data
+</
+#errors
+Line: 1 Col: 2 Expected closing tag. Unexpected end of file.
+Line: 1 Col: 2 Unexpected non-space characters. Expected DOCTYPE.
+#document
+| <html>
+|   <head>
+|   <body>
+|     "</"
+
+#data
+</#
+#errors
+Line: 1 Col: 2 Expected closing tag. Unexpected character '#' found.
+Line: 1 Col: 3 Unexpected End of file. Expected DOCTYPE.
+#document
+| <!-- # -->
+| <html>
+|   <head>
+|   <body>
+
+#data
+<?
+#errors
+Line: 1 Col: 1 Expected tag name. Got '?' instead. (HTML doesn't support processing instructions.)
+Line: 1 Col: 2 Unexpected End of file. Expected DOCTYPE.
+#document
+| <!-- ? -->
+| <html>
+|   <head>
+|   <body>
+
+#data
+<?#
+#errors
+Line: 1 Col: 1 Expected tag name. Got '?' instead. (HTML doesn't support processing instructions.)
+Line: 1 Col: 3 Unexpected End of file. Expected DOCTYPE.
+#document
+| <!-- ?# -->
+| <html>
+|   <head>
+|   <body>
+
+#data
+<!
+#errors
+Line: 1 Col: 2 Expected '--' or 'DOCTYPE'. Not found.
+Line: 1 Col: 2 Unexpected End of file. Expected DOCTYPE.
+#document
+| <!--  -->
+| <html>
+|   <head>
+|   <body>
+
+#data
+<!#
+#errors
+Line: 1 Col: 3 Expected '--' or 'DOCTYPE'. Not found.
+Line: 1 Col: 3 Unexpected End of file. Expected DOCTYPE.
+#document
+| <!-- # -->
+| <html>
+|   <head>
+|   <body>
+
+#data
+<?COMMENT?>
+#errors
+Line: 1 Col: 1 Expected tag name. Got '?' instead. (HTML doesn't support processing instructions.)
+Line: 1 Col: 11 Unexpected End of file. Expected DOCTYPE.
+#document
+| <!-- ?COMMENT? -->
+| <html>
+|   <head>
+|   <body>
+
+#data
+<!COMMENT>
+#errors
+Line: 1 Col: 2 Expected '--' or 'DOCTYPE'. Not found.
+Line: 1 Col: 10 Unexpected End of file. Expected DOCTYPE.
+#document
+| <!-- COMMENT -->
+| <html>
+|   <head>
+|   <body>
+
+#data
+</ COMMENT >
+#errors
+Line: 1 Col: 2 Expected closing tag. Unexpected character ' ' found.
+Line: 1 Col: 12 Unexpected End of file. Expected DOCTYPE.
+#document
+| <!--  COMMENT  -->
+| <html>
+|   <head>
+|   <body>
+
+#data
+<?COM--MENT?>
+#errors
+Line: 1 Col: 1 Expected tag name. Got '?' instead. (HTML doesn't support processing instructions.)
+Line: 1 Col: 13 Unexpected End of file. Expected DOCTYPE.
+#document
+| <!-- ?COM--MENT? -->
+| <html>
+|   <head>
+|   <body>
+
+#data
+<!COM--MENT>
+#errors
+Line: 1 Col: 2 Expected '--' or 'DOCTYPE'. Not found.
+Line: 1 Col: 12 Unexpected End of file. Expected DOCTYPE.
+#document
+| <!-- COM--MENT -->
+| <html>
+|   <head>
+|   <body>
+
+#data
+</ COM--MENT >
+#errors
+Line: 1 Col: 2 Expected closing tag. Unexpected character ' ' found.
+Line: 1 Col: 14 Unexpected End of file. Expected DOCTYPE.
+#document
+| <!--  COM--MENT  -->
+| <html>
+|   <head>
+|   <body>
+
+#data
+<!DOCTYPE html><style> EOF
+#errors
+Line: 1 Col: 26 Unexpected end of file. Expected end tag (style).
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|     <style>
+|       " EOF"
+|   <body>
+
+#data
+<!DOCTYPE html><script> <!-- </script> --> </script> EOF
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|     <script>
+|       " <!-- "
+|     " "
+|   <body>
+|     "-->  EOF"
+
+#data
+<b><p></b>TEST
+#errors
+Line: 1 Col: 3 Unexpected start tag (b). Expected DOCTYPE.
+Line: 1 Col: 10 End tag (b) violates step 1, paragraph 3 of the adoption agency algorithm.
+#document
+| <html>
+|   <head>
+|   <body>
+|     <b>
+|     <p>
+|       <b>
+|       "TEST"
+
+#data
+<p id=a><b><p id=b></b>TEST
+#errors
+Line: 1 Col: 8 Unexpected start tag (p). Expected DOCTYPE.
+Line: 1 Col: 19 Unexpected end tag (p). Ignored.
+Line: 1 Col: 23 End tag (b) violates step 1, paragraph 2 of the adoption agency algorithm.
+#document
+| <html>
+|   <head>
+|   <body>
+|     <p>
+|       id="a"
+|       <b>
+|     <p>
+|       id="b"
+|       "TEST"
+
+#data
+<b id=a><p><b id=b></p></b>TEST
+#errors
+Line: 1 Col: 8 Unexpected start tag (b). Expected DOCTYPE.
+Line: 1 Col: 23 Unexpected end tag (p). Ignored.
+Line: 1 Col: 27 End tag (b) violates step 1, paragraph 2 of the adoption agency algorithm.
+Line: 1 Col: 31 Expected closing tag. Unexpected end of file.
+#document
+| <html>
+|   <head>
+|   <body>
+|     <b>
+|       id="a"
+|       <p>
+|         <b>
+|           id="b"
+|       "TEST"
+
+#data
+<!DOCTYPE html><title>U-test</title><body><div><p>Test<u></p></div></body>
+#errors
+Line: 1 Col: 61 Unexpected end tag (p). Ignored.
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|     <title>
+|       "U-test"
+|   <body>
+|     <div>
+|       <p>
+|         "Test"
+|         <u>
+
+#data
+<!DOCTYPE html><font><table></font></table></font>
+#errors
+Line: 1 Col: 35 Unexpected end tag (font) in table context caused voodoo mode.
+Line: 1 Col: 35 End tag (font) violates step 1, paragraph 1 of the adoption agency algorithm.
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     <font>
+|       <table>
+
+#data
+<font><p>hello<b>cruel</font>world
+#errors
+Line: 1 Col: 6 Unexpected start tag (font). Expected DOCTYPE.
+Line: 1 Col: 29 End tag (font) violates step 1, paragraph 3 of the adoption agency algorithm.
+Line: 1 Col: 29 End tag (font) violates step 1, paragraph 3 of the adoption agency algorithm.
+Line: 1 Col: 34 Expected closing tag. Unexpected end of file.
+#document
+| <html>
+|   <head>
+|   <body>
+|     <font>
+|     <p>
+|       <font>
+|         "hello"
+|         <b>
+|           "cruel"
+|       <b>
+|         "world"
+
+#data
+<b>Test</i>Test
+#errors
+Line: 1 Col: 3 Unexpected start tag (b). Expected DOCTYPE.
+Line: 1 Col: 11 End tag (i) violates step 1, paragraph 1 of the adoption agency algorithm.
+Line: 1 Col: 15 Expected closing tag. Unexpected end of file.
+#document
+| <html>
+|   <head>
+|   <body>
+|     <b>
+|       "TestTest"
+
+#data
+<b>A<cite>B<div>C
+#errors
+Line: 1 Col: 3 Unexpected start tag (b). Expected DOCTYPE.
+Line: 1 Col: 17 Expected closing tag. Unexpected end of file.
+#document
+| <html>
+|   <head>
+|   <body>
+|     <b>
+|       "A"
+|       <cite>
+|         "B"
+|         <div>
+|           "C"
+
+#data
+<b>A<cite>B<div>C</cite>D
+#errors
+Line: 1 Col: 3 Unexpected start tag (b). Expected DOCTYPE.
+Line: 1 Col: 24 Unexpected end tag (cite). Ignored.
+Line: 1 Col: 25 Expected closing tag. Unexpected end of file.
+#document
+| <html>
+|   <head>
+|   <body>
+|     <b>
+|       "A"
+|       <cite>
+|         "B"
+|         <div>
+|           "CD"
+
+#data
+<b>A<cite>B<div>C</b>D
+#errors
+Line: 1 Col: 3 Unexpected start tag (b). Expected DOCTYPE.
+Line: 1 Col: 21 End tag (b) violates step 1, paragraph 3 of the adoption agency algorithm.
+Line: 1 Col: 22 Expected closing tag. Unexpected end of file.
+#document
+| <html>
+|   <head>
+|   <body>
+|     <b>
+|       "A"
+|       <cite>
+|         "B"
+|     <div>
+|       <b>
+|         "C"
+|       "D"
+
+#data
+
+#errors
+Line: 1 Col: 0 Unexpected End of file. Expected DOCTYPE.
+#document
+| <html>
+|   <head>
+|   <body>
+
+#data
+<DIV>
+#errors
+Line: 1 Col: 5 Unexpected start tag (div). Expected DOCTYPE.
+Line: 1 Col: 5 Expected closing tag. Unexpected end of file.
+#document
+| <html>
+|   <head>
+|   <body>
+|     <div>
+
+#data
+<DIV> abc
+#errors
+Line: 1 Col: 5 Unexpected start tag (div). Expected DOCTYPE.
+Line: 1 Col: 9 Expected closing tag. Unexpected end of file.
+#document
+| <html>
+|   <head>
+|   <body>
+|     <div>
+|       " abc"
+
+#data
+<DIV> abc <B>
+#errors
+Line: 1 Col: 5 Unexpected start tag (div). Expected DOCTYPE.
+Line: 1 Col: 13 Expected closing tag. Unexpected end of file.
+#document
+| <html>
+|   <head>
+|   <body>
+|     <div>
+|       " abc "
+|       <b>
+
+#data
+<DIV> abc <B> def
+#errors
+Line: 1 Col: 5 Unexpected start tag (div). Expected DOCTYPE.
+Line: 1 Col: 17 Expected closing tag. Unexpected end of file.
+#document
+| <html>
+|   <head>
+|   <body>
+|     <div>
+|       " abc "
+|       <b>
+|         " def"
+
+#data
+<DIV> abc <B> def <I>
+#errors
+Line: 1 Col: 5 Unexpected start tag (div). Expected DOCTYPE.
+Line: 1 Col: 21 Expected closing tag. Unexpected end of file.
+#document
+| <html>
+|   <head>
+|   <body>
+|     <div>
+|       " abc "
+|       <b>
+|         " def "
+|         <i>
+
+#data
+<DIV> abc <B> def <I> ghi
+#errors
+Line: 1 Col: 5 Unexpected start tag (div). Expected DOCTYPE.
+Line: 1 Col: 25 Expected closing tag. Unexpected end of file.
+#document
+| <html>
+|   <head>
+|   <body>
+|     <div>
+|       " abc "
+|       <b>
+|         " def "
+|         <i>
+|           " ghi"
+
+#data
+<DIV> abc <B> def <I> ghi <P>
+#errors
+Line: 1 Col: 5 Unexpected start tag (div). Expected DOCTYPE.
+Line: 1 Col: 29 Expected closing tag. Unexpected end of file.
+#document
+| <html>
+|   <head>
+|   <body>
+|     <div>
+|       " abc "
+|       <b>
+|         " def "
+|         <i>
+|           " ghi "
+|           <p>
+
+#data
+<DIV> abc <B> def <I> ghi <P> jkl
+#errors
+Line: 1 Col: 5 Unexpected start tag (div). Expected DOCTYPE.
+Line: 1 Col: 33 Expected closing tag. Unexpected end of file.
+#document
+| <html>
+|   <head>
+|   <body>
+|     <div>
+|       " abc "
+|       <b>
+|         " def "
+|         <i>
+|           " ghi "
+|           <p>
+|             " jkl"
+
+#data
+<DIV> abc <B> def <I> ghi <P> jkl </B>
+#errors
+Line: 1 Col: 5 Unexpected start tag (div). Expected DOCTYPE.
+Line: 1 Col: 38 End tag (b) violates step 1, paragraph 3 of the adoption agency algorithm.
+Line: 1 Col: 38 Expected closing tag. Unexpected end of file.
+#document
+| <html>
+|   <head>
+|   <body>
+|     <div>
+|       " abc "
+|       <b>
+|         " def "
+|         <i>
+|           " ghi "
+|       <i>
+|         <p>
+|           <b>
+|             " jkl "
+
+#data
+<DIV> abc <B> def <I> ghi <P> jkl </B> mno
+#errors
+Line: 1 Col: 5 Unexpected start tag (div). Expected DOCTYPE.
+Line: 1 Col: 38 End tag (b) violates step 1, paragraph 3 of the adoption agency algorithm.
+Line: 1 Col: 42 Expected closing tag. Unexpected end of file.
+#document
+| <html>
+|   <head>
+|   <body>
+|     <div>
+|       " abc "
+|       <b>
+|         " def "
+|         <i>
+|           " ghi "
+|       <i>
+|         <p>
+|           <b>
+|             " jkl "
+|           " mno"
+
+#data
+<DIV> abc <B> def <I> ghi <P> jkl </B> mno </I>
+#errors
+Line: 1 Col: 5 Unexpected start tag (div). Expected DOCTYPE.
+Line: 1 Col: 38 End tag (b) violates step 1, paragraph 3 of the adoption agency algorithm.
+Line: 1 Col: 47 End tag (i) violates step 1, paragraph 3 of the adoption agency algorithm.
+Line: 1 Col: 47 Expected closing tag. Unexpected end of file.
+#document
+| <html>
+|   <head>
+|   <body>
+|     <div>
+|       " abc "
+|       <b>
+|         " def "
+|         <i>
+|           " ghi "
+|       <i>
+|       <p>
+|         <i>
+|           <b>
+|             " jkl "
+|           " mno "
+
+#data
+<DIV> abc <B> def <I> ghi <P> jkl </B> mno </I> pqr
+#errors
+Line: 1 Col: 5 Unexpected start tag (div). Expected DOCTYPE.
+Line: 1 Col: 38 End tag (b) violates step 1, paragraph 3 of the adoption agency algorithm.
+Line: 1 Col: 47 End tag (i) violates step 1, paragraph 3 of the adoption agency algorithm.
+Line: 1 Col: 51 Expected closing tag. Unexpected end of file.
+#document
+| <html>
+|   <head>
+|   <body>
+|     <div>
+|       " abc "
+|       <b>
+|         " def "
+|         <i>
+|           " ghi "
+|       <i>
+|       <p>
+|         <i>
+|           <b>
+|             " jkl "
+|           " mno "
+|         " pqr"
+
+#data
+<DIV> abc <B> def <I> ghi <P> jkl </B> mno </I> pqr </P>
+#errors
+Line: 1 Col: 5 Unexpected start tag (div). Expected DOCTYPE.
+Line: 1 Col: 38 End tag (b) violates step 1, paragraph 3 of the adoption agency algorithm.
+Line: 1 Col: 47 End tag (i) violates step 1, paragraph 3 of the adoption agency algorithm.
+Line: 1 Col: 56 Expected closing tag. Unexpected end of file.
+#document
+| <html>
+|   <head>
+|   <body>
+|     <div>
+|       " abc "
+|       <b>
+|         " def "
+|         <i>
+|           " ghi "
+|       <i>
+|       <p>
+|         <i>
+|           <b>
+|             " jkl "
+|           " mno "
+|         " pqr "
+
+#data
+<DIV> abc <B> def <I> ghi <P> jkl </B> mno </I> pqr </P> stu
+#errors
+Line: 1 Col: 5 Unexpected start tag (div). Expected DOCTYPE.
+Line: 1 Col: 38 End tag (b) violates step 1, paragraph 3 of the adoption agency algorithm.
+Line: 1 Col: 47 End tag (i) violates step 1, paragraph 3 of the adoption agency algorithm.
+Line: 1 Col: 60 Expected closing tag. Unexpected end of file.
+#document
+| <html>
+|   <head>
+|   <body>
+|     <div>
+|       " abc "
+|       <b>
+|         " def "
+|         <i>
+|           " ghi "
+|       <i>
+|       <p>
+|         <i>
+|           <b>
+|             " jkl "
+|           " mno "
+|         " pqr "
+|       " stu"
+
+#data
+<test attribute---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------->
+#errors
+Line: 1 Col: 1040 Unexpected start tag (test). Expected DOCTYPE.
+Line: 1 Col: 1040 Expected closing tag. Unexpected end of file.
+#document
+| <html>
+|   <head>
+|   <body>
+|     <test>
+|       attribute----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------=""
+
+#data
+<a href="blah">aba<table><a href="foo">br<tr><td></td></tr>x</table>aoe
+#errors
+Line: 1 Col: 15 Unexpected start tag (a). Expected DOCTYPE.
+Line: 1 Col: 39 Unexpected start tag (a) in table context caused voodoo mode.
+Line: 1 Col: 39 Unexpected start tag (a) implies end tag (a).
+Line: 1 Col: 39 End tag (a) violates step 1, paragraph 1 of the adoption agency algorithm.
+Line: 1 Col: 45 Unexpected implied end tag (a) in the table phase.
+Line: 1 Col: 68 Unexpected implied end tag (a) in the table phase.
+Line: 1 Col: 71 Expected closing tag. Unexpected end of file.
+
+#document
+| <html>
+|   <head>
+|   <body>
+|     <a>
+|       href="blah"
+|       "aba"
+|       <a>
+|         href="foo"
+|         "br"
+|       <a>
+|         href="foo"
+|         "x"
+|       <table>
+|         <tbody>
+|           <tr>
+|             <td>
+|     <a>
+|       href="foo"
+|       "aoe"
+
+#data
+<a href="blah">aba<table><tr><td><a href="foo">br</td></tr>x</table>aoe
+#errors
+Line: 1 Col: 15 Unexpected start tag (a). Expected DOCTYPE.
+Line: 1 Col: 54 Got table cell end tag (td) while required end tags are missing.
+Line: 1 Col: 60 Unexpected non-space characters in table context caused voodoo mode.
+Line: 1 Col: 71 Expected closing tag. Unexpected end of file.
+#document
+| <html>
+|   <head>
+|   <body>
+|     <a>
+|       href="blah"
+|       "abax"
+|       <table>
+|         <tbody>
+|           <tr>
+|             <td>
+|               <a>
+|                 href="foo"
+|                 "br"
+|       "aoe"
+
+#data
+<table><a href="blah">aba<tr><td><a href="foo">br</td></tr>x</table>aoe
+#errors
+Line: 1 Col: 7 Unexpected start tag (table). Expected DOCTYPE.
+Line: 1 Col: 22 Unexpected start tag (a) in table context caused voodoo mode.
+Line: 1 Col: 29 Unexpected implied end tag (a) in the table phase.
+Line: 1 Col: 54 Got table cell end tag (td) while required end tags are missing.
+Line: 1 Col: 68 Unexpected implied end tag (a) in the table phase.
+Line: 1 Col: 71 Expected closing tag. Unexpected end of file.
+#document
+| <html>
+|   <head>
+|   <body>
+|     <a>
+|       href="blah"
+|       "aba"
+|     <a>
+|       href="blah"
+|       "x"
+|     <table>
+|       <tbody>
+|         <tr>
+|           <td>
+|             <a>
+|               href="foo"
+|               "br"
+|     <a>
+|       href="blah"
+|       "aoe"
+
+#data
+<a href=a>aa<marquee>aa<a href=b>bb</marquee>aa
+#errors
+Line: 1 Col: 10 Unexpected start tag (a). Expected DOCTYPE.
+Line: 1 Col: 45 End tag (marquee) seen too early. Expected other end tag.
+Line: 1 Col: 47 Expected closing tag. Unexpected end of file.
+#document
+| <html>
+|   <head>
+|   <body>
+|     <a>
+|       href="a"
+|       "aa"
+|       <marquee>
+|         "aa"
+|         <a>
+|           href="b"
+|           "bb"
+|       "aa"
+
+#data
+<wbr><strike><code></strike><code><strike></code>
+#errors
+Line: 1 Col: 5 Unexpected start tag (wbr). Expected DOCTYPE.
+Line: 1 Col: 28 End tag (strike) violates step 1, paragraph 3 of the adoption agency algorithm.
+Line: 1 Col: 49 Unexpected end tag (code). Ignored.
+#document
+| <html>
+|   <head>
+|   <body>
+|     <wbr>
+|     <strike>
+|       <code>
+|     <code>
+|       <code>
+|         <strike>
+
+#data
+<!DOCTYPE html><spacer>foo
+#errors
+26: End of file seen and there were open elements.
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     <spacer>
+|       "foo"
+
+#data
+<title><meta></title><link><title><meta></title>
+#errors
+Line: 1 Col: 7 Unexpected start tag (title). Expected DOCTYPE.
+#document
+| <html>
+|   <head>
+|     <title>
+|       "<meta>"
+|     <link>
+|     <title>
+|       "<meta>"
+|   <body>
+
+#data
+<style><!--</style><meta><script>--><link></script>
+#errors
+Line: 1 Col: 7 Unexpected start tag (style). Expected DOCTYPE.
+Line: 1 Col: 51 Unexpected end of file. Expected end tag (style).
+#document
+| <html>
+|   <head>
+|     <style>
+|       "<!--"
+|     <meta>
+|     <script>
+|       "--><link>"
+|   <body>
+
+#data
+<head><meta></head><link>
+#errors
+Line: 1 Col: 6 Unexpected start tag (head). Expected DOCTYPE.
+Line: 1 Col: 25 Unexpected start tag (link) that can be in head. Moved.
+#document
+| <html>
+|   <head>
+|     <meta>
+|     <link>
+|   <body>
+
+#data
+<table><tr><tr><td><td><span><th><span>X</table>
+#errors
+Line: 1 Col: 7 Unexpected start tag (table). Expected DOCTYPE.
+Line: 1 Col: 33 Got table cell end tag (td) while required end tags are missing.
+Line: 1 Col: 48 Got table cell end tag (th) while required end tags are missing.
+#document
+| <html>
+|   <head>
+|   <body>
+|     <table>
+|       <tbody>
+|         <tr>
+|         <tr>
+|           <td>
+|           <td>
+|             <span>
+|           <th>
+|             <span>
+|               "X"
+
+#data
+<body><body><base><link><meta><title><p></title><body><p></body>
+#errors
+Line: 1 Col: 6 Unexpected start tag (body). Expected DOCTYPE.
+Line: 1 Col: 12 Unexpected start tag (body).
+Line: 1 Col: 54 Unexpected start tag (body).
+Line: 1 Col: 64 Unexpected end tag (p). Missing end tag (body).
+#document
+| <html>
+|   <head>
+|   <body>
+|     <base>
+|     <link>
+|     <meta>
+|     <title>
+|       "<p>"
+|     <p>
+
+#data
+<textarea><p></textarea>
+#errors
+Line: 1 Col: 10 Unexpected start tag (textarea). Expected DOCTYPE.
+#document
+| <html>
+|   <head>
+|   <body>
+|     <textarea>
+|       "<p>"
+
+#data
+<p><image></p>
+#errors
+Line: 1 Col: 3 Unexpected start tag (p). Expected DOCTYPE.
+Line: 1 Col: 10 Unexpected start tag (image). Treated as img.
+#document
+| <html>
+|   <head>
+|   <body>
+|     <p>
+|       <img>
+
+#data
+<a><table><a></table><p><a><div><a>
+#errors
+Line: 1 Col: 3 Unexpected start tag (a). Expected DOCTYPE.
+Line: 1 Col: 13 Unexpected start tag (a) in table context caused voodoo mode.
+Line: 1 Col: 13 Unexpected start tag (a) implies end tag (a).
+Line: 1 Col: 13 End tag (a) violates step 1, paragraph 1 of the adoption agency algorithm.
+Line: 1 Col: 21 Unexpected end tag (table). Expected end tag (a).
+Line: 1 Col: 27 Unexpected start tag (a) implies end tag (a).
+Line: 1 Col: 27 End tag (a) violates step 1, paragraph 2 of the adoption agency algorithm.
+Line: 1 Col: 32 Unexpected end tag (p). Ignored.
+Line: 1 Col: 35 Unexpected start tag (a) implies end tag (a).
+Line: 1 Col: 35 End tag (a) violates step 1, paragraph 2 of the adoption agency algorithm.
+Line: 1 Col: 35 Expected closing tag. Unexpected end of file.
+#document
+| <html>
+|   <head>
+|   <body>
+|     <a>
+|       <a>
+|       <table>
+|     <p>
+|       <a>
+|     <div>
+|       <a>
+
+#data
+<head></p><meta><p>
+#errors
+Line: 1 Col: 6 Unexpected start tag (head). Expected DOCTYPE.
+Line: 1 Col: 10 Unexpected end tag (p). Ignored.
+#document
+| <html>
+|   <head>
+|     <meta>
+|   <body>
+|     <p>
+
+#data
+<head></html><meta><p>
+#errors
+Line: 1 Col: 6 Unexpected start tag (head). Expected DOCTYPE.
+Line: 1 Col: 19 Unexpected start tag (meta).
+#document
+| <html>
+|   <head>
+|   <body>
+|     <meta>
+|     <p>
+
+#data
+<b><table><td><i></table>
+#errors
+Line: 1 Col: 3 Unexpected start tag (b). Expected DOCTYPE.
+Line: 1 Col: 14 Unexpected table cell start tag (td) in the table body phase.
+Line: 1 Col: 25 Got table cell end tag (td) while required end tags are missing.
+Line: 1 Col: 25 Expected closing tag. Unexpected end of file.
+#document
+| <html>
+|   <head>
+|   <body>
+|     <b>
+|       <table>
+|         <tbody>
+|           <tr>
+|             <td>
+|               <i>
+
+#data
+<b><table><td></b><i></table>
+#errors
+Line: 1 Col: 3 Unexpected start tag (b). Expected DOCTYPE.
+Line: 1 Col: 14 Unexpected table cell start tag (td) in the table body phase.
+Line: 1 Col: 18 End tag (b) violates step 1, paragraph 1 of the adoption agency algorithm.
+Line: 1 Col: 29 Got table cell end tag (td) while required end tags are missing.
+Line: 1 Col: 29 Expected closing tag. Unexpected end of file.
+#document
+| <html>
+|   <head>
+|   <body>
+|     <b>
+|       <table>
+|         <tbody>
+|           <tr>
+|             <td>
+|               <i>
+
+#data
+<h1><h2>
+#errors
+4: Start tag seen without seeing a doctype first. Expected “<!DOCTYPE html>”.
+8: Heading cannot be a child of another heading.
+8: End of file seen and there were open elements.
+#document
+| <html>
+|   <head>
+|   <body>
+|     <h1>
+|     <h2>
+
+#data
+<a><p><a></a></p></a>
+#errors
+Line: 1 Col: 3 Unexpected start tag (a). Expected DOCTYPE.
+Line: 1 Col: 9 Unexpected start tag (a) implies end tag (a).
+Line: 1 Col: 9 End tag (a) violates step 1, paragraph 3 of the adoption agency algorithm.
+Line: 1 Col: 21 End tag (a) violates step 1, paragraph 1 of the adoption agency algorithm.
+#document
+| <html>
+|   <head>
+|   <body>
+|     <a>
+|     <p>
+|       <a>
+|       <a>
+
+#data
+<b><button></b></button></b>
+#errors
+Line: 1 Col: 3 Unexpected start tag (b). Expected DOCTYPE.
+Line: 1 Col: 15 End tag (b) violates step 1, paragraph 1 of the adoption agency algorithm.
+#document
+| <html>
+|   <head>
+|   <body>
+|     <b>
+|     <button>
+|       <b>
+
+#data
+<p><b><div><marquee></p></b></div>
+#errors
+Line: 1 Col: 3 Unexpected start tag (p). Expected DOCTYPE.
+Line: 1 Col: 11 Unexpected end tag (p). Ignored.
+Line: 1 Col: 24 Unexpected end tag (p). Ignored.
+Line: 1 Col: 28 End tag (b) violates step 1, paragraph 1 of the adoption agency algorithm.
+Line: 1 Col: 34 End tag (div) seen too early. Expected other end tag.
+Line: 1 Col: 34 Expected closing tag. Unexpected end of file.
+#document
+| <html>
+|   <head>
+|   <body>
+|     <p>
+|       <b>
+|     <div>
+|       <b>
+|         <marquee>
+|           <p>
+
+#data
+<script></script></div><title></title><p><p>
+#errors
+Line: 1 Col: 8 Unexpected start tag (script). Expected DOCTYPE.
+Line: 1 Col: 23 Unexpected end tag (div). Ignored.
+#document
+| <html>
+|   <head>
+|     <script>
+|     <title>
+|   <body>
+|     <p>
+|     <p>
+
+#data
+<p><hr></p>
+#errors
+Line: 1 Col: 3 Unexpected start tag (p). Expected DOCTYPE.
+Line: 1 Col: 11 Unexpected end tag (p). Ignored.
+#document
+| <html>
+|   <head>
+|   <body>
+|     <p>
+|     <hr>
+|     <p>
+
+#data
+<select><b><option><select><option></b></select>
+#errors
+Line: 1 Col: 8 Unexpected start tag (select). Expected DOCTYPE.
+Line: 1 Col: 11 Unexpected start tag token (b) in the select phase. Ignored.
+Line: 1 Col: 27 Unexpected select start tag in the select phase treated as select end tag.
+Line: 1 Col: 39 End tag (b) violates step 1, paragraph 1 of the adoption agency algorithm.
+Line: 1 Col: 48 Unexpected end tag (select). Ignored.
+Line: 1 Col: 48 Expected closing tag. Unexpected end of file.
+#document
+| <html>
+|   <head>
+|   <body>
+|     <select>
+|       <option>
+|     <option>
+
+#data
+<html><head><title></title><body></body></html>
+#errors
+Line: 1 Col: 6 Unexpected start tag (html). Expected DOCTYPE.
+#document
+| <html>
+|   <head>
+|     <title>
+|   <body>
+
+#data
+<a><table><td><a><table></table><a></tr><a></table><a>
+#errors
+Line: 1 Col: 3 Unexpected start tag (a). Expected DOCTYPE.
+Line: 1 Col: 14 Unexpected table cell start tag (td) in the table body phase.
+Line: 1 Col: 35 Unexpected start tag (a) implies end tag (a).
+Line: 1 Col: 40 Got table cell end tag (td) while required end tags are missing.
+Line: 1 Col: 43 Unexpected start tag (a) in table context caused voodoo mode.
+Line: 1 Col: 43 Unexpected start tag (a) implies end tag (a).
+Line: 1 Col: 43 End tag (a) violates step 1, paragraph 1 of the adoption agency algorithm.
+Line: 1 Col: 51 Unexpected implied end tag (a) in the table phase.
+Line: 1 Col: 54 Unexpected start tag (a) implies end tag (a).
+Line: 1 Col: 54 End tag (a) violates step 1, paragraph 2 of the adoption agency algorithm.
+Line: 1 Col: 54 Expected closing tag. Unexpected end of file.
+#document
+| <html>
+|   <head>
+|   <body>
+|     <a>
+|       <a>
+|       <table>
+|         <tbody>
+|           <tr>
+|             <td>
+|               <a>
+|                 <table>
+|               <a>
+|     <a>
+
+#data
+<ul><li></li><div><li></div><li><li><div><li><address><li><b><em></b><li></ul>
+#errors
+Line: 1 Col: 4 Unexpected start tag (ul). Expected DOCTYPE.
+Line: 1 Col: 45 Missing end tag (div, li).
+Line: 1 Col: 58 Missing end tag (address, li).
+Line: 1 Col: 69 End tag (b) violates step 1, paragraph 3 of the adoption agency algorithm.
+#document
+| <html>
+|   <head>
+|   <body>
+|     <ul>
+|       <li>
+|       <div>
+|         <li>
+|       <li>
+|       <li>
+|         <div>
+|       <li>
+|         <address>
+|       <li>
+|         <b>
+|           <em>
+|       <li>
+
+#data
+<ul><li><ul></li><li>a</li></ul></li></ul>
+#errors
+XXX: fix me
+#document
+| <html>
+|   <head>
+|   <body>
+|     <ul>
+|       <li>
+|         <ul>
+|           <li>
+|             "a"
+
+#data
+<frameset><frame><frameset><frame></frameset><noframes></noframes></frameset>
+#errors
+Line: 1 Col: 10 Unexpected start tag (frameset). Expected DOCTYPE.
+#document
+| <html>
+|   <head>
+|   <frameset>
+|     <frame>
+|     <frameset>
+|       <frame>
+|     <noframes>
+
+#data
+<h1><table><td><h3></table><h3></h1>
+#errors
+4: Start tag seen without seeing a doctype first. Expected “<!DOCTYPE html>”.
+15: “td” start tag in table body.
+27: Unclosed elements.
+31: Heading cannot be a child of another heading.
+36: End tag “h1” seen but there were unclosed elements.
+#document
+| <html>
+|   <head>
+|   <body>
+|     <h1>
+|       <table>
+|         <tbody>
+|           <tr>
+|             <td>
+|               <h3>
+|     <h3>
+
+#data
+<table><colgroup><col><colgroup><col><col><col><colgroup><col><col><thead><tr><td></table>
+#errors
+Line: 1 Col: 7 Unexpected start tag (table). Expected DOCTYPE.
+#document
+| <html>
+|   <head>
+|   <body>
+|     <table>
+|       <colgroup>
+|         <col>
+|       <colgroup>
+|         <col>
+|         <col>
+|         <col>
+|       <colgroup>
+|         <col>
+|         <col>
+|       <thead>
+|         <tr>
+|           <td>
+
+#data
+<table><col><tbody><col><tr><col><td><col></table><col>
+#errors
+Line: 1 Col: 7 Unexpected start tag (table). Expected DOCTYPE.
+Line: 1 Col: 37 Unexpected table cell start tag (td) in the table body phase.
+Line: 1 Col: 55 Unexpected start tag col. Ignored.
+#document
+| <html>
+|   <head>
+|   <body>
+|     <table>
+|       <colgroup>
+|         <col>
+|       <tbody>
+|       <colgroup>
+|         <col>
+|       <tbody>
+|         <tr>
+|       <colgroup>
+|         <col>
+|       <tbody>
+|         <tr>
+|           <td>
+|       <colgroup>
+|         <col>
+
+#data
+<table><colgroup><tbody><colgroup><tr><colgroup><td><colgroup></table><colgroup>
+#errors
+Line: 1 Col: 7 Unexpected start tag (table). Expected DOCTYPE.
+Line: 1 Col: 52 Unexpected table cell start tag (td) in the table body phase.
+Line: 1 Col: 80 Unexpected start tag colgroup. Ignored.
+#document
+| <html>
+|   <head>
+|   <body>
+|     <table>
+|       <colgroup>
+|       <tbody>
+|       <colgroup>
+|       <tbody>
+|         <tr>
+|       <colgroup>
+|       <tbody>
+|         <tr>
+|           <td>
+|       <colgroup>
+
+#data
+</strong></b></em></i></u></strike></s></blink></tt></pre></big></small></font></select></h1></h2></h3></h4></h5></h6></body></br></a></img></title></span></style></script></table></th></td></tr></frame></area></link></param></hr></input></col></base></meta></basefont></bgsound></embed></spacer></p></dd></dt></caption></colgroup></tbody></tfoot></thead></address></blockquote></center></dir></div></dl></fieldset></listing></menu></ol></ul></li></nobr></wbr></form></button></marquee></object></html></frameset></head></iframe></image></isindex></noembed></noframes></noscript></optgroup></option></plaintext></textarea>
+#errors
+Line: 1 Col: 9 Unexpected end tag (strong). Expected DOCTYPE.
+Line: 1 Col: 9 Unexpected end tag (strong) after the (implied) root element.
+Line: 1 Col: 13 Unexpected end tag (b) after the (implied) root element.
+Line: 1 Col: 18 Unexpected end tag (em) after the (implied) root element.
+Line: 1 Col: 22 Unexpected end tag (i) after the (implied) root element.
+Line: 1 Col: 26 Unexpected end tag (u) after the (implied) root element.
+Line: 1 Col: 35 Unexpected end tag (strike) after the (implied) root element.
+Line: 1 Col: 39 Unexpected end tag (s) after the (implied) root element.
+Line: 1 Col: 47 Unexpected end tag (blink) after the (implied) root element.
+Line: 1 Col: 52 Unexpected end tag (tt) after the (implied) root element.
+Line: 1 Col: 58 Unexpected end tag (pre) after the (implied) root element.
+Line: 1 Col: 64 Unexpected end tag (big) after the (implied) root element.
+Line: 1 Col: 72 Unexpected end tag (small) after the (implied) root element.
+Line: 1 Col: 79 Unexpected end tag (font) after the (implied) root element.
+Line: 1 Col: 88 Unexpected end tag (select) after the (implied) root element.
+Line: 1 Col: 93 Unexpected end tag (h1) after the (implied) root element.
+Line: 1 Col: 98 Unexpected end tag (h2) after the (implied) root element.
+Line: 1 Col: 103 Unexpected end tag (h3) after the (implied) root element.
+Line: 1 Col: 108 Unexpected end tag (h4) after the (implied) root element.
+Line: 1 Col: 113 Unexpected end tag (h5) after the (implied) root element.
+Line: 1 Col: 118 Unexpected end tag (h6) after the (implied) root element.
+Line: 1 Col: 125 Unexpected end tag (body) after the (implied) root element.
+Line: 1 Col: 130 Unexpected end tag (br). Treated as br element.
+Line: 1 Col: 134 End tag (a) violates step 1, paragraph 1 of the adoption agency algorithm.
+Line: 1 Col: 140 This element (img) has no end tag.
+Line: 1 Col: 148 Unexpected end tag (title). Ignored.
+Line: 1 Col: 155 Unexpected end tag (span). Ignored.
+Line: 1 Col: 163 Unexpected end tag (style). Ignored.
+Line: 1 Col: 172 Unexpected end tag (script). Ignored.
+Line: 1 Col: 180 Unexpected end tag (table). Ignored.
+Line: 1 Col: 185 Unexpected end tag (th). Ignored.
+Line: 1 Col: 190 Unexpected end tag (td). Ignored.
+Line: 1 Col: 195 Unexpected end tag (tr). Ignored.
+Line: 1 Col: 203 This element (frame) has no end tag.
+Line: 1 Col: 210 This element (area) has no end tag.
+Line: 1 Col: 217 Unexpected end tag (link). Ignored.
+Line: 1 Col: 225 This element (param) has no end tag.
+Line: 1 Col: 230 This element (hr) has no end tag.
+Line: 1 Col: 238 This element (input) has no end tag.
+Line: 1 Col: 244 Unexpected end tag (col). Ignored.
+Line: 1 Col: 251 Unexpected end tag (base). Ignored.
+Line: 1 Col: 258 Unexpected end tag (meta). Ignored.
+Line: 1 Col: 269 This element (basefont) has no end tag.
+Line: 1 Col: 279 This element (bgsound) has no end tag.
+Line: 1 Col: 287 This element (embed) has no end tag.
+Line: 1 Col: 296 This element (spacer) has no end tag.
+Line: 1 Col: 300 Unexpected end tag (p). Ignored.
+Line: 1 Col: 305 End tag (dd) seen too early. Expected other end tag.
+Line: 1 Col: 310 End tag (dt) seen too early. Expected other end tag.
+Line: 1 Col: 320 Unexpected end tag (caption). Ignored.
+Line: 1 Col: 331 Unexpected end tag (colgroup). Ignored.
+Line: 1 Col: 339 Unexpected end tag (tbody). Ignored.
+Line: 1 Col: 347 Unexpected end tag (tfoot). Ignored.
+Line: 1 Col: 355 Unexpected end tag (thead). Ignored.
+Line: 1 Col: 365 End tag (address) seen too early. Expected other end tag.
+Line: 1 Col: 378 End tag (blockquote) seen too early. Expected other end tag.
+Line: 1 Col: 387 End tag (center) seen too early. Expected other end tag.
+Line: 1 Col: 393 Unexpected end tag (dir). Ignored.
+Line: 1 Col: 399 End tag (div) seen too early. Expected other end tag.
+Line: 1 Col: 404 End tag (dl) seen too early. Expected other end tag.
+Line: 1 Col: 415 End tag (fieldset) seen too early. Expected other end tag.
+Line: 1 Col: 425 End tag (listing) seen too early. Expected other end tag.
+Line: 1 Col: 432 End tag (menu) seen too early. Expected other end tag.
+Line: 1 Col: 437 End tag (ol) seen too early. Expected other end tag.
+Line: 1 Col: 442 End tag (ul) seen too early. Expected other end tag.
+Line: 1 Col: 447 End tag (li) seen too early. Expected other end tag.
+Line: 1 Col: 454 End tag (nobr) violates step 1, paragraph 1 of the adoption agency algorithm.
+Line: 1 Col: 460 This element (wbr) has no end tag.
+Line: 1 Col: 476 End tag (button) seen too early. Expected other end tag.
+Line: 1 Col: 486 End tag (marquee) seen too early. Expected other end tag.
+Line: 1 Col: 495 End tag (object) seen too early. Expected other end tag.
+Line: 1 Col: 513 Unexpected end tag (html). Ignored.
+Line: 1 Col: 513 Unexpected end tag (frameset). Ignored.
+Line: 1 Col: 520 Unexpected end tag (head). Ignored.
+Line: 1 Col: 529 Unexpected end tag (iframe). Ignored.
+Line: 1 Col: 537 This element (image) has no end tag.
+Line: 1 Col: 547 This element (isindex) has no end tag.
+Line: 1 Col: 557 Unexpected end tag (noembed). Ignored.
+Line: 1 Col: 568 Unexpected end tag (noframes). Ignored.
+Line: 1 Col: 579 Unexpected end tag (noscript). Ignored.
+Line: 1 Col: 590 Unexpected end tag (optgroup). Ignored.
+Line: 1 Col: 599 Unexpected end tag (option). Ignored.
+Line: 1 Col: 611 Unexpected end tag (plaintext). Ignored.
+Line: 1 Col: 622 Unexpected end tag (textarea). Ignored.
+#document
+| <html>
+|   <head>
+|   <body>
+|     <br>
+|     <p>
+
+#data
+<table><tr></strong></b></em></i></u></strike></s></blink></tt></pre></big></small></font></select></h1></h2></h3></h4></h5></h6></body></br></a></img></title></span></style></script></table></th></td></tr></frame></area></link></param></hr></input></col></base></meta></basefont></bgsound></embed></spacer></p></dd></dt></caption></colgroup></tbody></tfoot></thead></address></blockquote></center></dir></div></dl></fieldset></listing></menu></ol></ul></li></nobr></wbr></form></button></marquee></object></html></frameset></head></iframe></image></isindex></noembed></noframes></noscript></optgroup></option></plaintext></textarea>
+#errors
+Line: 1 Col: 7 Unexpected start tag (table). Expected DOCTYPE.
+Line: 1 Col: 20 Unexpected end tag (strong) in table context caused voodoo mode.
+Line: 1 Col: 20 End tag (strong) violates step 1, paragraph 1 of the adoption agency algorithm.
+Line: 1 Col: 24 Unexpected end tag (b) in table context caused voodoo mode.
+Line: 1 Col: 24 End tag (b) violates step 1, paragraph 1 of the adoption agency algorithm.
+Line: 1 Col: 29 Unexpected end tag (em) in table context caused voodoo mode.
+Line: 1 Col: 29 End tag (em) violates step 1, paragraph 1 of the adoption agency algorithm.
+Line: 1 Col: 33 Unexpected end tag (i) in table context caused voodoo mode.
+Line: 1 Col: 33 End tag (i) violates step 1, paragraph 1 of the adoption agency algorithm.
+Line: 1 Col: 37 Unexpected end tag (u) in table context caused voodoo mode.
+Line: 1 Col: 37 End tag (u) violates step 1, paragraph 1 of the adoption agency algorithm.
+Line: 1 Col: 46 Unexpected end tag (strike) in table context caused voodoo mode.
+Line: 1 Col: 46 End tag (strike) violates step 1, paragraph 1 of the adoption agency algorithm.
+Line: 1 Col: 50 Unexpected end tag (s) in table context caused voodoo mode.
+Line: 1 Col: 50 End tag (s) violates step 1, paragraph 1 of the adoption agency algorithm.
+Line: 1 Col: 58 Unexpected end tag (blink) in table context caused voodoo mode.
+Line: 1 Col: 58 Unexpected end tag (blink). Ignored.
+Line: 1 Col: 63 Unexpected end tag (tt) in table context caused voodoo mode.
+Line: 1 Col: 63 End tag (tt) violates step 1, paragraph 1 of the adoption agency algorithm.
+Line: 1 Col: 69 Unexpected end tag (pre) in table context caused voodoo mode.
+Line: 1 Col: 69 End tag (pre) seen too early. Expected other end tag.
+Line: 1 Col: 75 Unexpected end tag (big) in table context caused voodoo mode.
+Line: 1 Col: 75 End tag (big) violates step 1, paragraph 1 of the adoption agency algorithm.
+Line: 1 Col: 83 Unexpected end tag (small) in table context caused voodoo mode.
+Line: 1 Col: 83 End tag (small) violates step 1, paragraph 1 of the adoption agency algorithm.
+Line: 1 Col: 90 Unexpected end tag (font) in table context caused voodoo mode.
+Line: 1 Col: 90 End tag (font) violates step 1, paragraph 1 of the adoption agency algorithm.
+Line: 1 Col: 99 Unexpected end tag (select) in table context caused voodoo mode.
+Line: 1 Col: 99 Unexpected end tag (select). Ignored.
+Line: 1 Col: 104 Unexpected end tag (h1) in table context caused voodoo mode.
+Line: 1 Col: 104 End tag (h1) seen too early. Expected other end tag.
+Line: 1 Col: 109 Unexpected end tag (h2) in table context caused voodoo mode.
+Line: 1 Col: 109 End tag (h2) seen too early. Expected other end tag.
+Line: 1 Col: 114 Unexpected end tag (h3) in table context caused voodoo mode.
+Line: 1 Col: 114 End tag (h3) seen too early. Expected other end tag.
+Line: 1 Col: 119 Unexpected end tag (h4) in table context caused voodoo mode.
+Line: 1 Col: 119 End tag (h4) seen too early. Expected other end tag.
+Line: 1 Col: 124 Unexpected end tag (h5) in table context caused voodoo mode.
+Line: 1 Col: 124 End tag (h5) seen too early. Expected other end tag.
+Line: 1 Col: 129 Unexpected end tag (h6) in table context caused voodoo mode.
+Line: 1 Col: 129 End tag (h6) seen too early. Expected other end tag.
+Line: 1 Col: 136 Unexpected end tag (body) in the table row phase. Ignored.
+Line: 1 Col: 141 Unexpected end tag (br) in table context caused voodoo mode.
+Line: 1 Col: 141 Unexpected end tag (br). Treated as br element.
+Line: 1 Col: 145 Unexpected end tag (a) in table context caused voodoo mode.
+Line: 1 Col: 145 End tag (a) violates step 1, paragraph 1 of the adoption agency algorithm.
+Line: 1 Col: 151 Unexpected end tag (img) in table context caused voodoo mode.
+Line: 1 Col: 151 This element (img) has no end tag.
+Line: 1 Col: 159 Unexpected end tag (title) in table context caused voodoo mode.
+Line: 1 Col: 159 Unexpected end tag (title). Ignored.
+Line: 1 Col: 166 Unexpected end tag (span) in table context caused voodoo mode.
+Line: 1 Col: 166 Unexpected end tag (span). Ignored.
+Line: 1 Col: 174 Unexpected end tag (style) in table context caused voodoo mode.
+Line: 1 Col: 174 Unexpected end tag (style). Ignored.
+Line: 1 Col: 183 Unexpected end tag (script) in table context caused voodoo mode.
+Line: 1 Col: 183 Unexpected end tag (script). Ignored.
+Line: 1 Col: 196 Unexpected end tag (th). Ignored.
+Line: 1 Col: 201 Unexpected end tag (td). Ignored.
+Line: 1 Col: 206 Unexpected end tag (tr). Ignored.
+Line: 1 Col: 214 This element (frame) has no end tag.
+Line: 1 Col: 221 This element (area) has no end tag.
+Line: 1 Col: 228 Unexpected end tag (link). Ignored.
+Line: 1 Col: 236 This element (param) has no end tag.
+Line: 1 Col: 241 This element (hr) has no end tag.
+Line: 1 Col: 249 This element (input) has no end tag.
+Line: 1 Col: 255 Unexpected end tag (col). Ignored.
+Line: 1 Col: 262 Unexpected end tag (base). Ignored.
+Line: 1 Col: 269 Unexpected end tag (meta). Ignored.
+Line: 1 Col: 280 This element (basefont) has no end tag.
+Line: 1 Col: 290 This element (bgsound) has no end tag.
+Line: 1 Col: 298 This element (embed) has no end tag.
+Line: 1 Col: 307 This element (spacer) has no end tag.
+Line: 1 Col: 311 Unexpected end tag (p). Ignored.
+Line: 1 Col: 316 End tag (dd) seen too early. Expected other end tag.
+Line: 1 Col: 321 End tag (dt) seen too early. Expected other end tag.
+Line: 1 Col: 331 Unexpected end tag (caption). Ignored.
+Line: 1 Col: 342 Unexpected end tag (colgroup). Ignored.
+Line: 1 Col: 350 Unexpected end tag (tbody). Ignored.
+Line: 1 Col: 358 Unexpected end tag (tfoot). Ignored.
+Line: 1 Col: 366 Unexpected end tag (thead). Ignored.
+Line: 1 Col: 376 End tag (address) seen too early. Expected other end tag.
+Line: 1 Col: 389 End tag (blockquote) seen too early. Expected other end tag.
+Line: 1 Col: 398 End tag (center) seen too early. Expected other end tag.
+Line: 1 Col: 404 Unexpected end tag (dir). Ignored.
+Line: 1 Col: 410 End tag (div) seen too early. Expected other end tag.
+Line: 1 Col: 415 End tag (dl) seen too early. Expected other end tag.
+Line: 1 Col: 426 End tag (fieldset) seen too early. Expected other end tag.
+Line: 1 Col: 436 End tag (listing) seen too early. Expected other end tag.
+Line: 1 Col: 443 End tag (menu) seen too early. Expected other end tag.
+Line: 1 Col: 448 End tag (ol) seen too early. Expected other end tag.
+Line: 1 Col: 453 End tag (ul) seen too early. Expected other end tag.
+Line: 1 Col: 458 End tag (li) seen too early. Expected other end tag.
+Line: 1 Col: 465 End tag (nobr) violates step 1, paragraph 1 of the adoption agency algorithm.
+Line: 1 Col: 471 This element (wbr) has no end tag.
+Line: 1 Col: 487 End tag (button) seen too early. Expected other end tag.
+Line: 1 Col: 497 End tag (marquee) seen too early. Expected other end tag.
+Line: 1 Col: 506 End tag (object) seen too early. Expected other end tag.
+Line: 1 Col: 524 Unexpected end tag (html). Ignored.
+Line: 1 Col: 524 Unexpected end tag (frameset). Ignored.
+Line: 1 Col: 531 Unexpected end tag (head). Ignored.
+Line: 1 Col: 540 Unexpected end tag (iframe). Ignored.
+Line: 1 Col: 548 This element (image) has no end tag.
+Line: 1 Col: 558 This element (isindex) has no end tag.
+Line: 1 Col: 568 Unexpected end tag (noembed). Ignored.
+Line: 1 Col: 579 Unexpected end tag (noframes). Ignored.
+Line: 1 Col: 590 Unexpected end tag (noscript). Ignored.
+Line: 1 Col: 601 Unexpected end tag (optgroup). Ignored.
+Line: 1 Col: 610 Unexpected end tag (option). Ignored.
+Line: 1 Col: 622 Unexpected end tag (plaintext). Ignored.
+Line: 1 Col: 633 Unexpected end tag (textarea). Ignored.
+#document
+| <html>
+|   <head>
+|   <body>
+|     <br>
+|     <table>
+|       <tbody>
+|         <tr>
+|     <p>
+
+#data
+<frameset>
+#errors
+Line: 1 Col: 10 Unexpected start tag (frameset). Expected DOCTYPE.
+Line: 1 Col: 10 Expected closing tag. Unexpected end of file.
+#document
+| <html>
+|   <head>
+|   <frameset>
diff --git a/html/test/data/tree-construction/tests10.dat b/html/test/data/tree-construction/tests10.dat
new file mode 100644
index 0000000..4f8df86
--- /dev/null
+++ b/html/test/data/tree-construction/tests10.dat
@@ -0,0 +1,799 @@
+#data
+<!DOCTYPE html><svg></svg>
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     <svg svg>
+
+#data
+<!DOCTYPE html><svg></svg><![CDATA[a]]>
+#errors
+29: Bogus comment
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     <svg svg>
+|     <!-- [CDATA[a]] -->
+
+#data
+<!DOCTYPE html><body><svg></svg>
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     <svg svg>
+
+#data
+<!DOCTYPE html><body><select><svg></svg></select>
+#errors
+35: Stray “svg” start tag.
+42: Stray end tag “svg”
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     <select>
+
+#data
+<!DOCTYPE html><body><select><option><svg></svg></option></select>
+#errors
+43: Stray “svg” start tag.
+50: Stray end tag “svg”
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     <select>
+|       <option>
+
+#data
+<!DOCTYPE html><body><table><svg></svg></table>
+#errors
+34: Start tag “svg” seen in “table”.
+41: Stray end tag “svg”.
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     <svg svg>
+|     <table>
+
+#data
+<!DOCTYPE html><body><table><svg><g>foo</g></svg></table>
+#errors
+34: Start tag “svg” seen in “table”.
+46: Stray end tag “g”.
+53: Stray end tag “svg”.
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     <svg svg>
+|       <svg g>
+|         "foo"
+|     <table>
+
+#data
+<!DOCTYPE html><body><table><svg><g>foo</g><g>bar</g></svg></table>
+#errors
+34: Start tag “svg” seen in “table”.
+46: Stray end tag “g”.
+58: Stray end tag “g”.
+65: Stray end tag “svg”.
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     <svg svg>
+|       <svg g>
+|         "foo"
+|       <svg g>
+|         "bar"
+|     <table>
+
+#data
+<!DOCTYPE html><body><table><tbody><svg><g>foo</g><g>bar</g></svg></tbody></table>
+#errors
+41: Start tag “svg” seen in “table”.
+53: Stray end tag “g”.
+65: Stray end tag “g”.
+72: Stray end tag “svg”.
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     <svg svg>
+|       <svg g>
+|         "foo"
+|       <svg g>
+|         "bar"
+|     <table>
+|       <tbody>
+
+#data
+<!DOCTYPE html><body><table><tbody><tr><svg><g>foo</g><g>bar</g></svg></tr></tbody></table>
+#errors
+45: Start tag “svg” seen in “table”.
+57: Stray end tag “g”.
+69: Stray end tag “g”.
+76: Stray end tag “svg”.
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     <svg svg>
+|       <svg g>
+|         "foo"
+|       <svg g>
+|         "bar"
+|     <table>
+|       <tbody>
+|         <tr>
+
+#data
+<!DOCTYPE html><body><table><tbody><tr><td><svg><g>foo</g><g>bar</g></svg></td></tr></tbody></table>
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     <table>
+|       <tbody>
+|         <tr>
+|           <td>
+|             <svg svg>
+|               <svg g>
+|                 "foo"
+|               <svg g>
+|                 "bar"
+
+#data
+<!DOCTYPE html><body><table><tbody><tr><td><svg><g>foo</g><g>bar</g></svg><p>baz</td></tr></tbody></table>
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     <table>
+|       <tbody>
+|         <tr>
+|           <td>
+|             <svg svg>
+|               <svg g>
+|                 "foo"
+|               <svg g>
+|                 "bar"
+|             <p>
+|               "baz"
+
+#data
+<!DOCTYPE html><body><table><caption><svg><g>foo</g><g>bar</g></svg><p>baz</caption></table>
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     <table>
+|       <caption>
+|         <svg svg>
+|           <svg g>
+|             "foo"
+|           <svg g>
+|             "bar"
+|         <p>
+|           "baz"
+
+#data
+<!DOCTYPE html><body><table><caption><svg><g>foo</g><g>bar</g><p>baz</table><p>quux
+#errors
+70: HTML start tag “p” in a foreign namespace context.
+81: “table” closed but “caption” was still open.
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     <table>
+|       <caption>
+|         <svg svg>
+|           <svg g>
+|             "foo"
+|           <svg g>
+|             "bar"
+|         <p>
+|           "baz"
+|     <p>
+|       "quux"
+
+#data
+<!DOCTYPE html><body><table><caption><svg><g>foo</g><g>bar</g>baz</table><p>quux
+#errors
+78: “table” closed but “caption” was still open.
+78: Unclosed elements on stack.
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     <table>
+|       <caption>
+|         <svg svg>
+|           <svg g>
+|             "foo"
+|           <svg g>
+|             "bar"
+|           "baz"
+|     <p>
+|       "quux"
+
+#data
+<!DOCTYPE html><body><table><colgroup><svg><g>foo</g><g>bar</g><p>baz</table><p>quux
+#errors
+44: Start tag “svg” seen in “table”.
+56: Stray end tag “g”.
+68: Stray end tag “g”.
+71: HTML start tag “p” in a foreign namespace context.
+71: Start tag “p” seen in “table”.
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     <svg svg>
+|       <svg g>
+|         "foo"
+|       <svg g>
+|         "bar"
+|     <p>
+|       "baz"
+|     <table>
+|       <colgroup>
+|     <p>
+|       "quux"
+
+#data
+<!DOCTYPE html><body><table><tr><td><select><svg><g>foo</g><g>bar</g><p>baz</table><p>quux
+#errors
+50: Stray “svg” start tag.
+54: Stray “g” start tag.
+62: Stray end tag “g”
+66: Stray “g” start tag.
+74: Stray end tag “g”
+77: Stray “p” start tag.
+88: “table” end tag with “select” open.
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     <table>
+|       <tbody>
+|         <tr>
+|           <td>
+|             <select>
+|               "foobarbaz"
+|     <p>
+|       "quux"
+
+#data
+<!DOCTYPE html><body><table><select><svg><g>foo</g><g>bar</g><p>baz</table><p>quux
+#errors
+36: Start tag “select” seen in “table”.
+42: Stray “svg” start tag.
+46: Stray “g” start tag.
+54: Stray end tag “g”
+58: Stray “g” start tag.
+66: Stray end tag “g”
+69: Stray “p” start tag.
+80: “table” end tag with “select” open.
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     <select>
+|       "foobarbaz"
+|     <table>
+|     <p>
+|       "quux"
+
+#data
+<!DOCTYPE html><body></body></html><svg><g>foo</g><g>bar</g><p>baz
+#errors
+41: Stray “svg” start tag.
+68: HTML start tag “p” in a foreign namespace context.
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     <svg svg>
+|       <svg g>
+|         "foo"
+|       <svg g>
+|         "bar"
+|     <p>
+|       "baz"
+
+#data
+<!DOCTYPE html><body></body><svg><g>foo</g><g>bar</g><p>baz
+#errors
+34: Stray “svg” start tag.
+61: HTML start tag “p” in a foreign namespace context.
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     <svg svg>
+|       <svg g>
+|         "foo"
+|       <svg g>
+|         "bar"
+|     <p>
+|       "baz"
+
+#data
+<!DOCTYPE html><frameset><svg><g></g><g></g><p><span>
+#errors
+31: Stray “svg” start tag.
+35: Stray “g” start tag.
+40: Stray end tag “g”
+44: Stray “g” start tag.
+49: Stray end tag “g”
+52: Stray “p” start tag.
+58: Stray “span” start tag.
+58: End of file seen and there were open elements.
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <frameset>
+
+#data
+<!DOCTYPE html><frameset></frameset><svg><g></g><g></g><p><span>
+#errors
+42: Stray “svg” start tag.
+46: Stray “g” start tag.
+51: Stray end tag “g”
+55: Stray “g” start tag.
+60: Stray end tag “g”
+63: Stray “p” start tag.
+69: Stray “span” start tag.
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <frameset>
+
+#data
+<!DOCTYPE html><body xlink:href=foo><svg xlink:href=foo></svg>
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     xlink:href="foo"
+|     <svg svg>
+|       xlink href="foo"
+
+#data
+<!DOCTYPE html><body xlink:href=foo xml:lang=en><svg><g xml:lang=en xlink:href=foo></g></svg>
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     xlink:href="foo"
+|     xml:lang="en"
+|     <svg svg>
+|       <svg g>
+|         xlink href="foo"
+|         xml lang="en"
+
+#data
+<!DOCTYPE html><body xlink:href=foo xml:lang=en><svg><g xml:lang=en xlink:href=foo /></svg>
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     xlink:href="foo"
+|     xml:lang="en"
+|     <svg svg>
+|       <svg g>
+|         xlink href="foo"
+|         xml lang="en"
+
+#data
+<!DOCTYPE html><body xlink:href=foo xml:lang=en><svg><g xml:lang=en xlink:href=foo />bar</svg>
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     xlink:href="foo"
+|     xml:lang="en"
+|     <svg svg>
+|       <svg g>
+|         xlink href="foo"
+|         xml lang="en"
+|       "bar"
+
+#data
+<svg></path>
+#errors
+#document
+| <html>
+|   <head>
+|   <body>
+|     <svg svg>
+
+#data
+<div><svg></div>a
+#errors
+#document
+| <html>
+|   <head>
+|   <body>
+|     <div>
+|       <svg svg>
+|     "a"
+
+#data
+<div><svg><path></div>a
+#errors
+#document
+| <html>
+|   <head>
+|   <body>
+|     <div>
+|       <svg svg>
+|         <svg path>
+|     "a"
+
+#data
+<div><svg><path></svg><path>
+#errors
+#document
+| <html>
+|   <head>
+|   <body>
+|     <div>
+|       <svg svg>
+|         <svg path>
+|       <path>
+
+#data
+<div><svg><path><foreignObject><math></div>a
+#errors
+#document
+| <html>
+|   <head>
+|   <body>
+|     <div>
+|       <svg svg>
+|         <svg path>
+|           <svg foreignObject>
+|             <math math>
+|               "a"
+
+#data
+<div><svg><path><foreignObject><p></div>a
+#errors
+#document
+| <html>
+|   <head>
+|   <body>
+|     <div>
+|       <svg svg>
+|         <svg path>
+|           <svg foreignObject>
+|             <p>
+|               "a"
+
+#data
+<!DOCTYPE html><svg><desc><div><svg><ul>a
+#errors
+40: HTML start tag “ul” in a foreign namespace context.
+41: End of file in a foreign namespace context.
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     <svg svg>
+|       <svg desc>
+|         <div>
+|           <svg svg>
+|           <ul>
+|             "a"
+
+#data
+<!DOCTYPE html><svg><desc><svg><ul>a
+#errors
+35: HTML start tag “ul” in a foreign namespace context.
+36: End of file in a foreign namespace context.
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     <svg svg>
+|       <svg desc>
+|         <svg svg>
+|         <ul>
+|           "a"
+
+#data
+<!DOCTYPE html><p><svg><desc><p>
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     <p>
+|       <svg svg>
+|         <svg desc>
+|           <p>
+
+#data
+<!DOCTYPE html><p><svg><title><p>
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     <p>
+|       <svg svg>
+|         <svg title>
+|           <p>
+
+#data
+<div><svg><path><foreignObject><p></foreignObject><p>
+#errors
+#document
+| <html>
+|   <head>
+|   <body>
+|     <div>
+|       <svg svg>
+|         <svg path>
+|           <svg foreignObject>
+|             <p>
+|             <p>
+
+#data
+<math><mi><div><object><div><span></span></div></object></div></mi><mi>
+#errors
+#document
+| <html>
+|   <head>
+|   <body>
+|     <math math>
+|       <math mi>
+|         <div>
+|           <object>
+|             <div>
+|               <span>
+|       <math mi>
+
+#data
+<math><mi><svg><foreignObject><div><div></div></div></foreignObject></svg></mi><mi>
+#errors
+#document
+| <html>
+|   <head>
+|   <body>
+|     <math math>
+|       <math mi>
+|         <svg svg>
+|           <svg foreignObject>
+|             <div>
+|               <div>
+|       <math mi>
+
+#data
+<svg><script></script><path>
+#errors
+#document
+| <html>
+|   <head>
+|   <body>
+|     <svg svg>
+|       <svg script>
+|       <svg path>
+
+#data
+<table><svg></svg><tr>
+#errors
+#document
+| <html>
+|   <head>
+|   <body>
+|     <svg svg>
+|     <table>
+|       <tbody>
+|         <tr>
+
+#data
+<math><mi><mglyph>
+#errors
+#document
+| <html>
+|   <head>
+|   <body>
+|     <math math>
+|       <math mi>
+|         <math mglyph>
+
+#data
+<math><mi><malignmark>
+#errors
+#document
+| <html>
+|   <head>
+|   <body>
+|     <math math>
+|       <math mi>
+|         <math malignmark>
+
+#data
+<math><mo><mglyph>
+#errors
+#document
+| <html>
+|   <head>
+|   <body>
+|     <math math>
+|       <math mo>
+|         <math mglyph>
+
+#data
+<math><mo><malignmark>
+#errors
+#document
+| <html>
+|   <head>
+|   <body>
+|     <math math>
+|       <math mo>
+|         <math malignmark>
+
+#data
+<math><mn><mglyph>
+#errors
+#document
+| <html>
+|   <head>
+|   <body>
+|     <math math>
+|       <math mn>
+|         <math mglyph>
+
+#data
+<math><mn><malignmark>
+#errors
+#document
+| <html>
+|   <head>
+|   <body>
+|     <math math>
+|       <math mn>
+|         <math malignmark>
+
+#data
+<math><ms><mglyph>
+#errors
+#document
+| <html>
+|   <head>
+|   <body>
+|     <math math>
+|       <math ms>
+|         <math mglyph>
+
+#data
+<math><ms><malignmark>
+#errors
+#document
+| <html>
+|   <head>
+|   <body>
+|     <math math>
+|       <math ms>
+|         <math malignmark>
+
+#data
+<math><mtext><mglyph>
+#errors
+#document
+| <html>
+|   <head>
+|   <body>
+|     <math math>
+|       <math mtext>
+|         <math mglyph>
+
+#data
+<math><mtext><malignmark>
+#errors
+#document
+| <html>
+|   <head>
+|   <body>
+|     <math math>
+|       <math mtext>
+|         <math malignmark>
+
+#data
+<math><annotation-xml><svg></svg></annotation-xml><mi>
+#errors
+#document
+| <html>
+|   <head>
+|   <body>
+|     <math math>
+|       <math annotation-xml>
+|         <svg svg>
+|       <math mi>
+
+#data
+<math><annotation-xml><svg><foreignObject><div><math><mi></mi></math><span></span></div></foreignObject><path></path></svg></annotation-xml><mi>
+#errors
+#document
+| <html>
+|   <head>
+|   <body>
+|     <math math>
+|       <math annotation-xml>
+|         <svg svg>
+|           <svg foreignObject>
+|             <div>
+|               <math math>
+|                 <math mi>
+|               <span>
+|           <svg path>
+|       <math mi>
+
+#data
+<math><annotation-xml><svg><foreignObject><math><mi><svg></svg></mi><mo></mo></math><span></span></foreignObject><path></path></svg></annotation-xml><mi>
+#errors
+#document
+| <html>
+|   <head>
+|   <body>
+|     <math math>
+|       <math annotation-xml>
+|         <svg svg>
+|           <svg foreignObject>
+|             <math math>
+|               <math mi>
+|                 <svg svg>
+|               <math mo>
+|             <span>
+|           <svg path>
+|       <math mi>
diff --git a/html/test/data/tree-construction/tests11.dat b/html/test/data/tree-construction/tests11.dat
new file mode 100644
index 0000000..638cde4
--- /dev/null
+++ b/html/test/data/tree-construction/tests11.dat
@@ -0,0 +1,482 @@
+#data
+<!DOCTYPE html><body><svg attributeName='' attributeType='' baseFrequency='' baseProfile='' calcMode='' clipPathUnits='' contentScriptType='' contentStyleType='' diffuseConstant='' edgeMode='' externalResourcesRequired='' filterRes='' filterUnits='' glyphRef='' gradientTransform='' gradientUnits='' kernelMatrix='' kernelUnitLength='' keyPoints='' keySplines='' keyTimes='' lengthAdjust='' limitingConeAngle='' markerHeight='' markerUnits='' markerWidth='' maskContentUnits='' maskUnits='' numOctaves='' pathLength='' patternContentUnits='' patternTransform='' patternUnits='' pointsAtX='' pointsAtY='' pointsAtZ='' preserveAlpha='' preserveAspectRatio='' primitiveUnits='' refX='' refY='' repeatCount='' repeatDur='' requiredExtensions='' requiredFeatures='' specularConstant='' specularExponent='' spreadMethod='' startOffset='' stdDeviation='' stitchTiles='' surfaceScale='' systemLanguage='' tableValues='' targetX='' targetY='' textLength='' viewBox='' viewTarget='' xChannelSelector='' yChannelSelector='' zoomAndPan=''></svg>
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     <svg svg>
+|       attributeName=""
+|       attributeType=""
+|       baseFrequency=""
+|       baseProfile=""
+|       calcMode=""
+|       clipPathUnits=""
+|       contentScriptType=""
+|       contentStyleType=""
+|       diffuseConstant=""
+|       edgeMode=""
+|       externalResourcesRequired=""
+|       filterRes=""
+|       filterUnits=""
+|       glyphRef=""
+|       gradientTransform=""
+|       gradientUnits=""
+|       kernelMatrix=""
+|       kernelUnitLength=""
+|       keyPoints=""
+|       keySplines=""
+|       keyTimes=""
+|       lengthAdjust=""
+|       limitingConeAngle=""
+|       markerHeight=""
+|       markerUnits=""
+|       markerWidth=""
+|       maskContentUnits=""
+|       maskUnits=""
+|       numOctaves=""
+|       pathLength=""
+|       patternContentUnits=""
+|       patternTransform=""
+|       patternUnits=""
+|       pointsAtX=""
+|       pointsAtY=""
+|       pointsAtZ=""
+|       preserveAlpha=""
+|       preserveAspectRatio=""
+|       primitiveUnits=""
+|       refX=""
+|       refY=""
+|       repeatCount=""
+|       repeatDur=""
+|       requiredExtensions=""
+|       requiredFeatures=""
+|       specularConstant=""
+|       specularExponent=""
+|       spreadMethod=""
+|       startOffset=""
+|       stdDeviation=""
+|       stitchTiles=""
+|       surfaceScale=""
+|       systemLanguage=""
+|       tableValues=""
+|       targetX=""
+|       targetY=""
+|       textLength=""
+|       viewBox=""
+|       viewTarget=""
+|       xChannelSelector=""
+|       yChannelSelector=""
+|       zoomAndPan=""
+
+#data
+<!DOCTYPE html><BODY><SVG ATTRIBUTENAME='' ATTRIBUTETYPE='' BASEFREQUENCY='' BASEPROFILE='' CALCMODE='' CLIPPATHUNITS='' CONTENTSCRIPTTYPE='' CONTENTSTYLETYPE='' DIFFUSECONSTANT='' EDGEMODE='' EXTERNALRESOURCESREQUIRED='' FILTERRES='' FILTERUNITS='' GLYPHREF='' GRADIENTTRANSFORM='' GRADIENTUNITS='' KERNELMATRIX='' KERNELUNITLENGTH='' KEYPOINTS='' KEYSPLINES='' KEYTIMES='' LENGTHADJUST='' LIMITINGCONEANGLE='' MARKERHEIGHT='' MARKERUNITS='' MARKERWIDTH='' MASKCONTENTUNITS='' MASKUNITS='' NUMOCTAVES='' PATHLENGTH='' PATTERNCONTENTUNITS='' PATTERNTRANSFORM='' PATTERNUNITS='' POINTSATX='' POINTSATY='' POINTSATZ='' PRESERVEALPHA='' PRESERVEASPECTRATIO='' PRIMITIVEUNITS='' REFX='' REFY='' REPEATCOUNT='' REPEATDUR='' REQUIREDEXTENSIONS='' REQUIREDFEATURES='' SPECULARCONSTANT='' SPECULAREXPONENT='' SPREADMETHOD='' STARTOFFSET='' STDDEVIATION='' STITCHTILES='' SURFACESCALE='' SYSTEMLANGUAGE='' TABLEVALUES='' TARGETX='' TARGETY='' TEXTLENGTH='' VIEWBOX='' VIEWTARGET='' XCHANNELSELECTOR='' YCHANNELSELECTOR='' ZOOMANDPAN=''></SVG>
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     <svg svg>
+|       attributeName=""
+|       attributeType=""
+|       baseFrequency=""
+|       baseProfile=""
+|       calcMode=""
+|       clipPathUnits=""
+|       contentScriptType=""
+|       contentStyleType=""
+|       diffuseConstant=""
+|       edgeMode=""
+|       externalResourcesRequired=""
+|       filterRes=""
+|       filterUnits=""
+|       glyphRef=""
+|       gradientTransform=""
+|       gradientUnits=""
+|       kernelMatrix=""
+|       kernelUnitLength=""
+|       keyPoints=""
+|       keySplines=""
+|       keyTimes=""
+|       lengthAdjust=""
+|       limitingConeAngle=""
+|       markerHeight=""
+|       markerUnits=""
+|       markerWidth=""
+|       maskContentUnits=""
+|       maskUnits=""
+|       numOctaves=""
+|       pathLength=""
+|       patternContentUnits=""
+|       patternTransform=""
+|       patternUnits=""
+|       pointsAtX=""
+|       pointsAtY=""
+|       pointsAtZ=""
+|       preserveAlpha=""
+|       preserveAspectRatio=""
+|       primitiveUnits=""
+|       refX=""
+|       refY=""
+|       repeatCount=""
+|       repeatDur=""
+|       requiredExtensions=""
+|       requiredFeatures=""
+|       specularConstant=""
+|       specularExponent=""
+|       spreadMethod=""
+|       startOffset=""
+|       stdDeviation=""
+|       stitchTiles=""
+|       surfaceScale=""
+|       systemLanguage=""
+|       tableValues=""
+|       targetX=""
+|       targetY=""
+|       textLength=""
+|       viewBox=""
+|       viewTarget=""
+|       xChannelSelector=""
+|       yChannelSelector=""
+|       zoomAndPan=""
+
+#data
+<!DOCTYPE html><body><svg attributename='' attributetype='' basefrequency='' baseprofile='' calcmode='' clippathunits='' contentscripttype='' contentstyletype='' diffuseconstant='' edgemode='' externalresourcesrequired='' filterres='' filterunits='' glyphref='' gradienttransform='' gradientunits='' kernelmatrix='' kernelunitlength='' keypoints='' keysplines='' keytimes='' lengthadjust='' limitingconeangle='' markerheight='' markerunits='' markerwidth='' maskcontentunits='' maskunits='' numoctaves='' pathlength='' patterncontentunits='' patterntransform='' patternunits='' pointsatx='' pointsaty='' pointsatz='' preservealpha='' preserveaspectratio='' primitiveunits='' refx='' refy='' repeatcount='' repeatdur='' requiredextensions='' requiredfeatures='' specularconstant='' specularexponent='' spreadmethod='' startoffset='' stddeviation='' stitchtiles='' surfacescale='' systemlanguage='' tablevalues='' targetx='' targety='' textlength='' viewbox='' viewtarget='' xchannelselector='' ychannelselector='' zoomandpan=''></svg>
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     <svg svg>
+|       attributeName=""
+|       attributeType=""
+|       baseFrequency=""
+|       baseProfile=""
+|       calcMode=""
+|       clipPathUnits=""
+|       contentScriptType=""
+|       contentStyleType=""
+|       diffuseConstant=""
+|       edgeMode=""
+|       externalResourcesRequired=""
+|       filterRes=""
+|       filterUnits=""
+|       glyphRef=""
+|       gradientTransform=""
+|       gradientUnits=""
+|       kernelMatrix=""
+|       kernelUnitLength=""
+|       keyPoints=""
+|       keySplines=""
+|       keyTimes=""
+|       lengthAdjust=""
+|       limitingConeAngle=""
+|       markerHeight=""
+|       markerUnits=""
+|       markerWidth=""
+|       maskContentUnits=""
+|       maskUnits=""
+|       numOctaves=""
+|       pathLength=""
+|       patternContentUnits=""
+|       patternTransform=""
+|       patternUnits=""
+|       pointsAtX=""
+|       pointsAtY=""
+|       pointsAtZ=""
+|       preserveAlpha=""
+|       preserveAspectRatio=""
+|       primitiveUnits=""
+|       refX=""
+|       refY=""
+|       repeatCount=""
+|       repeatDur=""
+|       requiredExtensions=""
+|       requiredFeatures=""
+|       specularConstant=""
+|       specularExponent=""
+|       spreadMethod=""
+|       startOffset=""
+|       stdDeviation=""
+|       stitchTiles=""
+|       surfaceScale=""
+|       systemLanguage=""
+|       tableValues=""
+|       targetX=""
+|       targetY=""
+|       textLength=""
+|       viewBox=""
+|       viewTarget=""
+|       xChannelSelector=""
+|       yChannelSelector=""
+|       zoomAndPan=""
+
+#data
+<!DOCTYPE html><body><math attributeName='' attributeType='' baseFrequency='' baseProfile='' calcMode='' clipPathUnits='' contentScriptType='' contentStyleType='' diffuseConstant='' edgeMode='' externalResourcesRequired='' filterRes='' filterUnits='' glyphRef='' gradientTransform='' gradientUnits='' kernelMatrix='' kernelUnitLength='' keyPoints='' keySplines='' keyTimes='' lengthAdjust='' limitingConeAngle='' markerHeight='' markerUnits='' markerWidth='' maskContentUnits='' maskUnits='' numOctaves='' pathLength='' patternContentUnits='' patternTransform='' patternUnits='' pointsAtX='' pointsAtY='' pointsAtZ='' preserveAlpha='' preserveAspectRatio='' primitiveUnits='' refX='' refY='' repeatCount='' repeatDur='' requiredExtensions='' requiredFeatures='' specularConstant='' specularExponent='' spreadMethod='' startOffset='' stdDeviation='' stitchTiles='' surfaceScale='' systemLanguage='' tableValues='' targetX='' targetY='' textLength='' viewBox='' viewTarget='' xChannelSelector='' yChannelSelector='' zoomAndPan=''></math>
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     <math math>
+|       attributename=""
+|       attributetype=""
+|       basefrequency=""
+|       baseprofile=""
+|       calcmode=""
+|       clippathunits=""
+|       contentscripttype=""
+|       contentstyletype=""
+|       diffuseconstant=""
+|       edgemode=""
+|       externalresourcesrequired=""
+|       filterres=""
+|       filterunits=""
+|       glyphref=""
+|       gradienttransform=""
+|       gradientunits=""
+|       kernelmatrix=""
+|       kernelunitlength=""
+|       keypoints=""
+|       keysplines=""
+|       keytimes=""
+|       lengthadjust=""
+|       limitingconeangle=""
+|       markerheight=""
+|       markerunits=""
+|       markerwidth=""
+|       maskcontentunits=""
+|       maskunits=""
+|       numoctaves=""
+|       pathlength=""
+|       patterncontentunits=""
+|       patterntransform=""
+|       patternunits=""
+|       pointsatx=""
+|       pointsaty=""
+|       pointsatz=""
+|       preservealpha=""
+|       preserveaspectratio=""
+|       primitiveunits=""
+|       refx=""
+|       refy=""
+|       repeatcount=""
+|       repeatdur=""
+|       requiredextensions=""
+|       requiredfeatures=""
+|       specularconstant=""
+|       specularexponent=""
+|       spreadmethod=""
+|       startoffset=""
+|       stddeviation=""
+|       stitchtiles=""
+|       surfacescale=""
+|       systemlanguage=""
+|       tablevalues=""
+|       targetx=""
+|       targety=""
+|       textlength=""
+|       viewbox=""
+|       viewtarget=""
+|       xchannelselector=""
+|       ychannelselector=""
+|       zoomandpan=""
+
+#data
+<!DOCTYPE html><body><svg><altGlyph /><altGlyphDef /><altGlyphItem /><animateColor /><animateMotion /><animateTransform /><clipPath /><feBlend /><feColorMatrix /><feComponentTransfer /><feComposite /><feConvolveMatrix /><feDiffuseLighting /><feDisplacementMap /><feDistantLight /><feFlood /><feFuncA /><feFuncB /><feFuncG /><feFuncR /><feGaussianBlur /><feImage /><feMerge /><feMergeNode /><feMorphology /><feOffset /><fePointLight /><feSpecularLighting /><feSpotLight /><feTile /><feTurbulence /><foreignObject /><glyphRef /><linearGradient /><radialGradient /><textPath /></svg>
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     <svg svg>
+|       <svg altGlyph>
+|       <svg altGlyphDef>
+|       <svg altGlyphItem>
+|       <svg animateColor>
+|       <svg animateMotion>
+|       <svg animateTransform>
+|       <svg clipPath>
+|       <svg feBlend>
+|       <svg feColorMatrix>
+|       <svg feComponentTransfer>
+|       <svg feComposite>
+|       <svg feConvolveMatrix>
+|       <svg feDiffuseLighting>
+|       <svg feDisplacementMap>
+|       <svg feDistantLight>
+|       <svg feFlood>
+|       <svg feFuncA>
+|       <svg feFuncB>
+|       <svg feFuncG>
+|       <svg feFuncR>
+|       <svg feGaussianBlur>
+|       <svg feImage>
+|       <svg feMerge>
+|       <svg feMergeNode>
+|       <svg feMorphology>
+|       <svg feOffset>
+|       <svg fePointLight>
+|       <svg feSpecularLighting>
+|       <svg feSpotLight>
+|       <svg feTile>
+|       <svg feTurbulence>
+|       <svg foreignObject>
+|       <svg glyphRef>
+|       <svg linearGradient>
+|       <svg radialGradient>
+|       <svg textPath>
+
+#data
+<!DOCTYPE html><body><svg><altglyph /><altglyphdef /><altglyphitem /><animatecolor /><animatemotion /><animatetransform /><clippath /><feblend /><fecolormatrix /><fecomponenttransfer /><fecomposite /><feconvolvematrix /><fediffuselighting /><fedisplacementmap /><fedistantlight /><feflood /><fefunca /><fefuncb /><fefuncg /><fefuncr /><fegaussianblur /><feimage /><femerge /><femergenode /><femorphology /><feoffset /><fepointlight /><fespecularlighting /><fespotlight /><fetile /><feturbulence /><foreignobject /><glyphref /><lineargradient /><radialgradient /><textpath /></svg>
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     <svg svg>
+|       <svg altGlyph>
+|       <svg altGlyphDef>
+|       <svg altGlyphItem>
+|       <svg animateColor>
+|       <svg animateMotion>
+|       <svg animateTransform>
+|       <svg clipPath>
+|       <svg feBlend>
+|       <svg feColorMatrix>
+|       <svg feComponentTransfer>
+|       <svg feComposite>
+|       <svg feConvolveMatrix>
+|       <svg feDiffuseLighting>
+|       <svg feDisplacementMap>
+|       <svg feDistantLight>
+|       <svg feFlood>
+|       <svg feFuncA>
+|       <svg feFuncB>
+|       <svg feFuncG>
+|       <svg feFuncR>
+|       <svg feGaussianBlur>
+|       <svg feImage>
+|       <svg feMerge>
+|       <svg feMergeNode>
+|       <svg feMorphology>
+|       <svg feOffset>
+|       <svg fePointLight>
+|       <svg feSpecularLighting>
+|       <svg feSpotLight>
+|       <svg feTile>
+|       <svg feTurbulence>
+|       <svg foreignObject>
+|       <svg glyphRef>
+|       <svg linearGradient>
+|       <svg radialGradient>
+|       <svg textPath>
+
+#data
+<!DOCTYPE html><BODY><SVG><ALTGLYPH /><ALTGLYPHDEF /><ALTGLYPHITEM /><ANIMATECOLOR /><ANIMATEMOTION /><ANIMATETRANSFORM /><CLIPPATH /><FEBLEND /><FECOLORMATRIX /><FECOMPONENTTRANSFER /><FECOMPOSITE /><FECONVOLVEMATRIX /><FEDIFFUSELIGHTING /><FEDISPLACEMENTMAP /><FEDISTANTLIGHT /><FEFLOOD /><FEFUNCA /><FEFUNCB /><FEFUNCG /><FEFUNCR /><FEGAUSSIANBLUR /><FEIMAGE /><FEMERGE /><FEMERGENODE /><FEMORPHOLOGY /><FEOFFSET /><FEPOINTLIGHT /><FESPECULARLIGHTING /><FESPOTLIGHT /><FETILE /><FETURBULENCE /><FOREIGNOBJECT /><GLYPHREF /><LINEARGRADIENT /><RADIALGRADIENT /><TEXTPATH /></SVG>
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     <svg svg>
+|       <svg altGlyph>
+|       <svg altGlyphDef>
+|       <svg altGlyphItem>
+|       <svg animateColor>
+|       <svg animateMotion>
+|       <svg animateTransform>
+|       <svg clipPath>
+|       <svg feBlend>
+|       <svg feColorMatrix>
+|       <svg feComponentTransfer>
+|       <svg feComposite>
+|       <svg feConvolveMatrix>
+|       <svg feDiffuseLighting>
+|       <svg feDisplacementMap>
+|       <svg feDistantLight>
+|       <svg feFlood>
+|       <svg feFuncA>
+|       <svg feFuncB>
+|       <svg feFuncG>
+|       <svg feFuncR>
+|       <svg feGaussianBlur>
+|       <svg feImage>
+|       <svg feMerge>
+|       <svg feMergeNode>
+|       <svg feMorphology>
+|       <svg feOffset>
+|       <svg fePointLight>
+|       <svg feSpecularLighting>
+|       <svg feSpotLight>
+|       <svg feTile>
+|       <svg feTurbulence>
+|       <svg foreignObject>
+|       <svg glyphRef>
+|       <svg linearGradient>
+|       <svg radialGradient>
+|       <svg textPath>
+
+#data
+<!DOCTYPE html><body><math><altGlyph /><altGlyphDef /><altGlyphItem /><animateColor /><animateMotion /><animateTransform /><clipPath /><feBlend /><feColorMatrix /><feComponentTransfer /><feComposite /><feConvolveMatrix /><feDiffuseLighting /><feDisplacementMap /><feDistantLight /><feFlood /><feFuncA /><feFuncB /><feFuncG /><feFuncR /><feGaussianBlur /><feImage /><feMerge /><feMergeNode /><feMorphology /><feOffset /><fePointLight /><feSpecularLighting /><feSpotLight /><feTile /><feTurbulence /><foreignObject /><glyphRef /><linearGradient /><radialGradient /><textPath /></math>
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     <math math>
+|       <math altglyph>
+|       <math altglyphdef>
+|       <math altglyphitem>
+|       <math animatecolor>
+|       <math animatemotion>
+|       <math animatetransform>
+|       <math clippath>
+|       <math feblend>
+|       <math fecolormatrix>
+|       <math fecomponenttransfer>
+|       <math fecomposite>
+|       <math feconvolvematrix>
+|       <math fediffuselighting>
+|       <math fedisplacementmap>
+|       <math fedistantlight>
+|       <math feflood>
+|       <math fefunca>
+|       <math fefuncb>
+|       <math fefuncg>
+|       <math fefuncr>
+|       <math fegaussianblur>
+|       <math feimage>
+|       <math femerge>
+|       <math femergenode>
+|       <math femorphology>
+|       <math feoffset>
+|       <math fepointlight>
+|       <math fespecularlighting>
+|       <math fespotlight>
+|       <math fetile>
+|       <math feturbulence>
+|       <math foreignobject>
+|       <math glyphref>
+|       <math lineargradient>
+|       <math radialgradient>
+|       <math textpath>
+
+#data
+<!DOCTYPE html><body><svg><solidColor /></svg>
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     <svg svg>
+|       <svg solidcolor>
diff --git a/html/test/data/tree-construction/tests12.dat b/html/test/data/tree-construction/tests12.dat
new file mode 100644
index 0000000..63107d2
--- /dev/null
+++ b/html/test/data/tree-construction/tests12.dat
@@ -0,0 +1,62 @@
+#data
+<!DOCTYPE html><body><p>foo<math><mtext><i>baz</i></mtext><annotation-xml><svg><desc><b>eggs</b></desc><g><foreignObject><P>spam<TABLE><tr><td><img></td></table></foreignObject></g><g>quux</g></svg></annotation-xml></math>bar
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     <p>
+|       "foo"
+|       <math math>
+|         <math mtext>
+|           <i>
+|             "baz"
+|         <math annotation-xml>
+|           <svg svg>
+|             <svg desc>
+|               <b>
+|                 "eggs"
+|             <svg g>
+|               <svg foreignObject>
+|                 <p>
+|                   "spam"
+|                 <table>
+|                   <tbody>
+|                     <tr>
+|                       <td>
+|                         <img>
+|             <svg g>
+|               "quux"
+|       "bar"
+
+#data
+<!DOCTYPE html><body>foo<math><mtext><i>baz</i></mtext><annotation-xml><svg><desc><b>eggs</b></desc><g><foreignObject><P>spam<TABLE><tr><td><img></td></table></foreignObject></g><g>quux</g></svg></annotation-xml></math>bar
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     "foo"
+|     <math math>
+|       <math mtext>
+|         <i>
+|           "baz"
+|       <math annotation-xml>
+|         <svg svg>
+|           <svg desc>
+|             <b>
+|               "eggs"
+|           <svg g>
+|             <svg foreignObject>
+|               <p>
+|                 "spam"
+|               <table>
+|                 <tbody>
+|                   <tr>
+|                     <td>
+|                       <img>
+|           <svg g>
+|             "quux"
+|     "bar"
diff --git a/html/test/data/tree-construction/tests14.dat b/html/test/data/tree-construction/tests14.dat
new file mode 100644
index 0000000..b8713f8
--- /dev/null
+++ b/html/test/data/tree-construction/tests14.dat
@@ -0,0 +1,74 @@
+#data
+<!DOCTYPE html><html><body><xyz:abc></xyz:abc>
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     <xyz:abc>
+
+#data
+<!DOCTYPE html><html><body><xyz:abc></xyz:abc><span></span>
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     <xyz:abc>
+|     <span>
+
+#data
+<!DOCTYPE html><html><html abc:def=gh><xyz:abc></xyz:abc>
+#errors
+15: Unexpected start tag html
+#document
+| <!DOCTYPE html>
+| <html>
+|   abc:def="gh"
+|   <head>
+|   <body>
+|     <xyz:abc>
+
+#data
+<!DOCTYPE html><html xml:lang=bar><html xml:lang=foo>
+#errors
+15: Unexpected start tag html
+#document
+| <!DOCTYPE html>
+| <html>
+|   xml:lang="bar"
+|   <head>
+|   <body>
+
+#data
+<!DOCTYPE html><html 123=456>
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+|   123="456"
+|   <head>
+|   <body>
+
+#data
+<!DOCTYPE html><html 123=456><html 789=012>
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+|   123="456"
+|   789="012"
+|   <head>
+|   <body>
+
+#data
+<!DOCTYPE html><html><body 789=012>
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     789="012"
diff --git a/html/test/data/tree-construction/tests15.dat b/html/test/data/tree-construction/tests15.dat
new file mode 100644
index 0000000..6ce1c0d
--- /dev/null
+++ b/html/test/data/tree-construction/tests15.dat
@@ -0,0 +1,208 @@
+#data
+<!DOCTYPE html><p><b><i><u></p> <p>X
+#errors
+Line: 1 Col: 31 Unexpected end tag (p). Ignored.
+Line: 1 Col: 36 Expected closing tag. Unexpected end of file.
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     <p>
+|       <b>
+|         <i>
+|           <u>
+|     <b>
+|       <i>
+|         <u>
+|           " "
+|           <p>
+|             "X"
+
+#data
+<p><b><i><u></p>
+<p>X
+#errors
+Line: 1 Col: 3 Unexpected start tag (p). Expected DOCTYPE.
+Line: 1 Col: 16 Unexpected end tag (p). Ignored.
+Line: 2 Col: 4 Expected closing tag. Unexpected end of file.
+#document
+| <html>
+|   <head>
+|   <body>
+|     <p>
+|       <b>
+|         <i>
+|           <u>
+|     <b>
+|       <i>
+|         <u>
+|           "
+"
+|           <p>
+|             "X"
+
+#data
+<!doctype html></html> <head>
+#errors
+Line: 1 Col: 22 Unexpected end tag (html) after the (implied) root element.
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     " "
+
+#data
+<!doctype html></body><meta>
+#errors
+Line: 1 Col: 22 Unexpected end tag (body) after the (implied) root element.
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     <meta>
+
+#data
+<html></html><!-- foo -->
+#errors
+Line: 1 Col: 6 Unexpected start tag (html). Expected DOCTYPE.
+Line: 1 Col: 13 Unexpected end tag (html) after the (implied) root element.
+#document
+| <html>
+|   <head>
+|   <body>
+| <!--  foo  -->
+
+#data
+<!doctype html></body><title>X</title>
+#errors
+Line: 1 Col: 22 Unexpected end tag (body) after the (implied) root element.
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     <title>
+|       "X"
+
+#data
+<!doctype html><table> X<meta></table>
+#errors
+Line: 1 Col: 24 Unexpected non-space characters in table context caused voodoo mode.
+Line: 1 Col: 30 Unexpected start tag (meta) in table context caused voodoo mode.
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     " X"
+|     <meta>
+|     <table>
+
+#data
+<!doctype html><table> x</table>
+#errors
+Line: 1 Col: 24 Unexpected non-space characters in table context caused voodoo mode.
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     " x"
+|     <table>
+
+#data
+<!doctype html><table> x </table>
+#errors
+Line: 1 Col: 25 Unexpected non-space characters in table context caused voodoo mode.
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     " x "
+|     <table>
+
+#data
+<!doctype html><table><tr> x</table>
+#errors
+Line: 1 Col: 28 Unexpected non-space characters in table context caused voodoo mode.
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     " x"
+|     <table>
+|       <tbody>
+|         <tr>
+
+#data
+<!doctype html><table>X<style> <tr>x </style> </table>
+#errors
+Line: 1 Col: 23 Unexpected non-space characters in table context caused voodoo mode.
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     "X"
+|     <table>
+|       <style>
+|         " <tr>x "
+|       " "
+
+#data
+<!doctype html><div><table><a>foo</a> <tr><td>bar</td> </tr></table></div>
+#errors
+Line: 1 Col: 30 Unexpected start tag (a) in table context caused voodoo mode.
+Line: 1 Col: 37 Unexpected end tag (a) in table context caused voodoo mode.
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     <div>
+|       <a>
+|         "foo"
+|       <table>
+|         " "
+|         <tbody>
+|           <tr>
+|             <td>
+|               "bar"
+|             " "
+
+#data
+<frame></frame></frame><frameset><frame><frameset><frame></frameset><noframes></frameset><noframes>
+#errors
+6: Start tag seen without seeing a doctype first. Expected “<!DOCTYPE html>”.
+13: Stray start tag “frame”.
+21: Stray end tag “frame”.
+29: Stray end tag “frame”.
+39: “frameset” start tag after “body” already open.
+105: End of file seen inside an [R]CDATA element.
+105: End of file seen and there were open elements.
+XXX: These errors are wrong, please fix me!
+#document
+| <html>
+|   <head>
+|   <frameset>
+|     <frame>
+|     <frameset>
+|       <frame>
+|     <noframes>
+|       "</frameset><noframes>"
+
+#data
+<!DOCTYPE html><object></html>
+#errors
+1: Expected closing tag. Unexpected end of file
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     <object>
diff --git a/html/test/data/tree-construction/tests16.dat b/html/test/data/tree-construction/tests16.dat
new file mode 100644
index 0000000..c8ef66f
--- /dev/null
+++ b/html/test/data/tree-construction/tests16.dat
@@ -0,0 +1,2299 @@
+#data
+<!doctype html><script>
+#errors
+Line: 1 Col: 23 Unexpected end of file. Expected end tag (script).
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|     <script>
+|   <body>
+
+#data
+<!doctype html><script>a
+#errors
+Line: 1 Col: 24 Unexpected end of file. Expected end tag (script).
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|     <script>
+|       "a"
+|   <body>
+
+#data
+<!doctype html><script><
+#errors
+Line: 1 Col: 24 Unexpected end of file. Expected end tag (script).
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|     <script>
+|       "<"
+|   <body>
+
+#data
+<!doctype html><script></
+#errors
+Line: 1 Col: 25 Unexpected end of file. Expected end tag (script).
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|     <script>
+|       "</"
+|   <body>
+
+#data
+<!doctype html><script></S
+#errors
+Line: 1 Col: 26 Unexpected end of file. Expected end tag (script).
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|     <script>
+|       "</S"
+|   <body>
+
+#data
+<!doctype html><script></SC
+#errors
+Line: 1 Col: 27 Unexpected end of file. Expected end tag (script).
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|     <script>
+|       "</SC"
+|   <body>
+
+#data
+<!doctype html><script></SCR
+#errors
+Line: 1 Col: 28 Unexpected end of file. Expected end tag (script).
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|     <script>
+|       "</SCR"
+|   <body>
+
+#data
+<!doctype html><script></SCRI
+#errors
+Line: 1 Col: 29 Unexpected end of file. Expected end tag (script).
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|     <script>
+|       "</SCRI"
+|   <body>
+
+#data
+<!doctype html><script></SCRIP
+#errors
+Line: 1 Col: 30 Unexpected end of file. Expected end tag (script).
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|     <script>
+|       "</SCRIP"
+|   <body>
+
+#data
+<!doctype html><script></SCRIPT
+#errors
+Line: 1 Col: 31 Unexpected end of file. Expected end tag (script).
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|     <script>
+|       "</SCRIPT"
+|   <body>
+
+#data
+<!doctype html><script></SCRIPT 
+#errors
+Line: 1 Col: 32 Unexpected end of file. Expected end tag (script).
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|     <script>
+|   <body>
+
+#data
+<!doctype html><script></s
+#errors
+Line: 1 Col: 26 Unexpected end of file. Expected end tag (script).
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|     <script>
+|       "</s"
+|   <body>
+
+#data
+<!doctype html><script></sc
+#errors
+Line: 1 Col: 27 Unexpected end of file. Expected end tag (script).
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|     <script>
+|       "</sc"
+|   <body>
+
+#data
+<!doctype html><script></scr
+#errors
+Line: 1 Col: 28 Unexpected end of file. Expected end tag (script).
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|     <script>
+|       "</scr"
+|   <body>
+
+#data
+<!doctype html><script></scri
+#errors
+Line: 1 Col: 29 Unexpected end of file. Expected end tag (script).
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|     <script>
+|       "</scri"
+|   <body>
+
+#data
+<!doctype html><script></scrip
+#errors
+Line: 1 Col: 30 Unexpected end of file. Expected end tag (script).
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|     <script>
+|       "</scrip"
+|   <body>
+
+#data
+<!doctype html><script></script
+#errors
+Line: 1 Col: 31 Unexpected end of file. Expected end tag (script).
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|     <script>
+|       "</script"
+|   <body>
+
+#data
+<!doctype html><script></script 
+#errors
+Line: 1 Col: 32 Unexpected end of file. Expected end tag (script).
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|     <script>
+|   <body>
+
+#data
+<!doctype html><script><!
+#errors
+Line: 1 Col: 25 Unexpected end of file. Expected end tag (script).
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|     <script>
+|       "<!"
+|   <body>
+
+#data
+<!doctype html><script><!a
+#errors
+Line: 1 Col: 26 Unexpected end of file. Expected end tag (script).
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|     <script>
+|       "<!a"
+|   <body>
+
+#data
+<!doctype html><script><!-
+#errors
+Line: 1 Col: 26 Unexpected end of file. Expected end tag (script).
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|     <script>
+|       "<!-"
+|   <body>
+
+#data
+<!doctype html><script><!-a
+#errors
+Line: 1 Col: 27 Unexpected end of file. Expected end tag (script).
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|     <script>
+|       "<!-a"
+|   <body>
+
+#data
+<!doctype html><script><!--
+#errors
+Line: 1 Col: 27 Unexpected end of file. Expected end tag (script).
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|     <script>
+|       "<!--"
+|   <body>
+
+#data
+<!doctype html><script><!--a
+#errors
+Line: 1 Col: 28 Unexpected end of file. Expected end tag (script).
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|     <script>
+|       "<!--a"
+|   <body>
+
+#data
+<!doctype html><script><!--<
+#errors
+Line: 1 Col: 28 Unexpected end of file. Expected end tag (script).
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|     <script>
+|       "<!--<"
+|   <body>
+
+#data
+<!doctype html><script><!--<a
+#errors
+Line: 1 Col: 29 Unexpected end of file. Expected end tag (script).
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|     <script>
+|       "<!--<a"
+|   <body>
+
+#data
+<!doctype html><script><!--</
+#errors
+Line: 1 Col: 27 Unexpected end of file. Expected end tag (script).
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|     <script>
+|       "<!--</"
+|   <body>
+
+#data
+<!doctype html><script><!--</script
+#errors
+Line: 1 Col: 35 Unexpected end of file. Expected end tag (script).
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|     <script>
+|       "<!--</script"
+|   <body>
+
+#data
+<!doctype html><script><!--</script 
+#errors
+Line: 1 Col: 36 Unexpected end of file. Expected end tag (script).
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|     <script>
+|       "<!--"
+|   <body>
+
+#data
+<!doctype html><script><!--<s
+#errors
+Line: 1 Col: 29 Unexpected end of file. Expected end tag (script).
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|     <script>
+|       "<!--<s"
+|   <body>
+
+#data
+<!doctype html><script><!--<script
+#errors
+Line: 1 Col: 34 Unexpected end of file. Expected end tag (script).
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|     <script>
+|       "<!--<script"
+|   <body>
+
+#data
+<!doctype html><script><!--<script 
+#errors
+Line: 1 Col: 35 Unexpected end of file. Expected end tag (script).
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|     <script>
+|       "<!--<script "
+|   <body>
+
+#data
+<!doctype html><script><!--<script <
+#errors
+Line: 1 Col: 36 Unexpected end of file. Expected end tag (script).
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|     <script>
+|       "<!--<script <"
+|   <body>
+
+#data
+<!doctype html><script><!--<script <a
+#errors
+Line: 1 Col: 37 Unexpected end of file. Expected end tag (script).
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|     <script>
+|       "<!--<script <a"
+|   <body>
+
+#data
+<!doctype html><script><!--<script </
+#errors
+Line: 1 Col: 37 Unexpected end of file. Expected end tag (script).
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|     <script>
+|       "<!--<script </"
+|   <body>
+
+#data
+<!doctype html><script><!--<script </s
+#errors
+Line: 1 Col: 38 Unexpected end of file. Expected end tag (script).
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|     <script>
+|       "<!--<script </s"
+|   <body>
+
+#data
+<!doctype html><script><!--<script </script
+#errors
+Line: 1 Col: 43 Unexpected end of file. Expected end tag (script).
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|     <script>
+|       "<!--<script </script"
+|   <body>
+
+#data
+<!doctype html><script><!--<script </scripta
+#errors
+Line: 1 Col: 44 Unexpected end of file. Expected end tag (script).
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|     <script>
+|       "<!--<script </scripta"
+|   <body>
+
+#data
+<!doctype html><script><!--<script </script 
+#errors
+Line: 1 Col: 44 Unexpected end of file. Expected end tag (script).
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|     <script>
+|       "<!--<script </script "
+|   <body>
+
+#data
+<!doctype html><script><!--<script </script>
+#errors
+Line: 1 Col: 44 Unexpected end of file. Expected end tag (script).
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|     <script>
+|       "<!--<script </script>"
+|   <body>
+
+#data
+<!doctype html><script><!--<script </script/
+#errors
+Line: 1 Col: 44 Unexpected end of file. Expected end tag (script).
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|     <script>
+|       "<!--<script </script/"
+|   <body>
+
+#data
+<!doctype html><script><!--<script </script <
+#errors
+Line: 1 Col: 45 Unexpected end of file. Expected end tag (script).
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|     <script>
+|       "<!--<script </script <"
+|   <body>
+
+#data
+<!doctype html><script><!--<script </script <a
+#errors
+Line: 1 Col: 46 Unexpected end of file. Expected end tag (script).
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|     <script>
+|       "<!--<script </script <a"
+|   <body>
+
+#data
+<!doctype html><script><!--<script </script </
+#errors
+Line: 1 Col: 46 Unexpected end of file. Expected end tag (script).
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|     <script>
+|       "<!--<script </script </"
+|   <body>
+
+#data
+<!doctype html><script><!--<script </script </script
+#errors
+Line: 1 Col: 52 Unexpected end of file. Expected end tag (script).
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|     <script>
+|       "<!--<script </script </script"
+|   <body>
+
+#data
+<!doctype html><script><!--<script </script </script 
+#errors
+Line: 1 Col: 53 Unexpected end of file. Expected end tag (script).
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|     <script>
+|       "<!--<script </script "
+|   <body>
+
+#data
+<!doctype html><script><!--<script </script </script/
+#errors
+Line: 1 Col: 53 Unexpected end of file. Expected end tag (script).
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|     <script>
+|       "<!--<script </script "
+|   <body>
+
+#data
+<!doctype html><script><!--<script </script </script>
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|     <script>
+|       "<!--<script </script "
+|   <body>
+
+#data
+<!doctype html><script><!--<script -
+#errors
+Line: 1 Col: 36 Unexpected end of file. Expected end tag (script).
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|     <script>
+|       "<!--<script -"
+|   <body>
+
+#data
+<!doctype html><script><!--<script -a
+#errors
+Line: 1 Col: 37 Unexpected end of file. Expected end tag (script).
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|     <script>
+|       "<!--<script -a"
+|   <body>
+
+#data
+<!doctype html><script><!--<script -<
+#errors
+Line: 1 Col: 37 Unexpected end of file. Expected end tag (script).
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|     <script>
+|       "<!--<script -<"
+|   <body>
+
+#data
+<!doctype html><script><!--<script --
+#errors
+Line: 1 Col: 37 Unexpected end of file. Expected end tag (script).
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|     <script>
+|       "<!--<script --"
+|   <body>
+
+#data
+<!doctype html><script><!--<script --a
+#errors
+Line: 1 Col: 38 Unexpected end of file. Expected end tag (script).
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|     <script>
+|       "<!--<script --a"
+|   <body>
+
+#data
+<!doctype html><script><!--<script --<
+#errors
+Line: 1 Col: 38 Unexpected end of file. Expected end tag (script).
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|     <script>
+|       "<!--<script --<"
+|   <body>
+
+#data
+<!doctype html><script><!--<script -->
+#errors
+Line: 1 Col: 38 Unexpected end of file. Expected end tag (script).
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|     <script>
+|       "<!--<script -->"
+|   <body>
+
+#data
+<!doctype html><script><!--<script --><
+#errors
+Line: 1 Col: 39 Unexpected end of file. Expected end tag (script).
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|     <script>
+|       "<!--<script --><"
+|   <body>
+
+#data
+<!doctype html><script><!--<script --></
+#errors
+Line: 1 Col: 40 Unexpected end of file. Expected end tag (script).
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|     <script>
+|       "<!--<script --></"
+|   <body>
+
+#data
+<!doctype html><script><!--<script --></script
+#errors
+Line: 1 Col: 46 Unexpected end of file. Expected end tag (script).
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|     <script>
+|       "<!--<script --></script"
+|   <body>
+
+#data
+<!doctype html><script><!--<script --></script 
+#errors
+Line: 1 Col: 47 Unexpected end of file. Expected end tag (script).
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|     <script>
+|       "<!--<script -->"
+|   <body>
+
+#data
+<!doctype html><script><!--<script --></script/
+#errors
+Line: 1 Col: 47 Unexpected end of file. Expected end tag (script).
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|     <script>
+|       "<!--<script -->"
+|   <body>
+
+#data
+<!doctype html><script><!--<script --></script>
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|     <script>
+|       "<!--<script -->"
+|   <body>
+
+#data
+<!doctype html><script><!--<script><\/script>--></script>
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|     <script>
+|       "<!--<script><\/script>-->"
+|   <body>
+
+#data
+<!doctype html><script><!--<script></scr'+'ipt>--></script>
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|     <script>
+|       "<!--<script></scr'+'ipt>-->"
+|   <body>
+
+#data
+<!doctype html><script><!--<script></script><script></script></script>
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|     <script>
+|       "<!--<script></script><script></script>"
+|   <body>
+
+#data
+<!doctype html><script><!--<script></script><script></script>--><!--</script>
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|     <script>
+|       "<!--<script></script><script></script>--><!--"
+|   <body>
+
+#data
+<!doctype html><script><!--<script></script><script></script>-- ></script>
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|     <script>
+|       "<!--<script></script><script></script>-- >"
+|   <body>
+
+#data
+<!doctype html><script><!--<script></script><script></script>- -></script>
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|     <script>
+|       "<!--<script></script><script></script>- ->"
+|   <body>
+
+#data
+<!doctype html><script><!--<script></script><script></script>- - ></script>
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|     <script>
+|       "<!--<script></script><script></script>- - >"
+|   <body>
+
+#data
+<!doctype html><script><!--<script></script><script></script>-></script>
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|     <script>
+|       "<!--<script></script><script></script>->"
+|   <body>
+
+#data
+<!doctype html><script><!--<script>--!></script>X
+#errors
+Line: 1 Col: 49 Unexpected end of file. Expected end tag (script).
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|     <script>
+|       "<!--<script>--!></script>X"
+|   <body>
+
+#data
+<!doctype html><script><!--<scr'+'ipt></script>--></script>
+#errors
+Line: 1 Col: 59 Unexpected end tag (script).
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|     <script>
+|       "<!--<scr'+'ipt>"
+|   <body>
+|     "-->"
+
+#data
+<!doctype html><script><!--<script></scr'+'ipt></script>X
+#errors
+Line: 1 Col: 57 Unexpected end of file. Expected end tag (script).
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|     <script>
+|       "<!--<script></scr'+'ipt></script>X"
+|   <body>
+
+#data
+<!doctype html><style><!--<style></style>--></style>
+#errors
+Line: 1 Col: 52 Unexpected end tag (style).
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|     <style>
+|       "<!--<style>"
+|   <body>
+|     "-->"
+
+#data
+<!doctype html><style><!--</style>X
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|     <style>
+|       "<!--"
+|   <body>
+|     "X"
+
+#data
+<!doctype html><style><!--...</style>...--></style>
+#errors
+Line: 1 Col: 51 Unexpected end tag (style).
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|     <style>
+|       "<!--..."
+|   <body>
+|     "...-->"
+
+#data
+<!doctype html><style><!--<br><html xmlns:v="urn:schemas-microsoft-com:vml"><!--[if !mso]><style></style>X
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|     <style>
+|       "<!--<br><html xmlns:v="urn:schemas-microsoft-com:vml"><!--[if !mso]><style>"
+|   <body>
+|     "X"
+
+#data
+<!doctype html><style><!--...<style><!--...--!></style>--></style>
+#errors
+Line: 1 Col: 66 Unexpected end tag (style).
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|     <style>
+|       "<!--...<style><!--...--!>"
+|   <body>
+|     "-->"
+
+#data
+<!doctype html><style><!--...</style><!-- --><style>@import ...</style>
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|     <style>
+|       "<!--..."
+|     <!--   -->
+|     <style>
+|       "@import ..."
+|   <body>
+
+#data
+<!doctype html><style>...<style><!--...</style><!-- --></style>
+#errors
+Line: 1 Col: 63 Unexpected end tag (style).
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|     <style>
+|       "...<style><!--..."
+|     <!--   -->
+|   <body>
+
+#data
+<!doctype html><style>...<!--[if IE]><style>...</style>X
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|     <style>
+|       "...<!--[if IE]><style>..."
+|   <body>
+|     "X"
+
+#data
+<!doctype html><title><!--<title></title>--></title>
+#errors
+Line: 1 Col: 52 Unexpected end tag (title).
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|     <title>
+|       "<!--<title>"
+|   <body>
+|     "-->"
+
+#data
+<!doctype html><title>&lt;/title></title>
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|     <title>
+|       "</title>"
+|   <body>
+
+#data
+<!doctype html><title>foo/title><link></head><body>X
+#errors
+Line: 1 Col: 52 Unexpected end of file. Expected end tag (title).
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|     <title>
+|       "foo/title><link></head><body>X"
+|   <body>
+
+#data
+<!doctype html><noscript><!--<noscript></noscript>--></noscript>
+#errors
+Line: 1 Col: 64 Unexpected end tag (noscript).
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|     <noscript>
+|       "<!--<noscript>"
+|   <body>
+|     "-->"
+
+#data
+<!doctype html><noscript><!--</noscript>X<noscript>--></noscript>
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|     <noscript>
+|       "<!--"
+|   <body>
+|     "X"
+|     <noscript>
+|       "-->"
+
+#data
+<!doctype html><noscript><iframe></noscript>X
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|     <noscript>
+|       "<iframe>"
+|   <body>
+|     "X"
+
+#data
+<!doctype html><noframes><!--<noframes></noframes>--></noframes>
+#errors
+Line: 1 Col: 64 Unexpected end tag (noframes).
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|     <noframes>
+|       "<!--<noframes>"
+|   <body>
+|     "-->"
+
+#data
+<!doctype html><noframes><body><script><!--...</script></body></noframes></html>
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|     <noframes>
+|       "<body><script><!--...</script></body>"
+|   <body>
+
+#data
+<!doctype html><textarea><!--<textarea></textarea>--></textarea>
+#errors
+Line: 1 Col: 64 Unexpected end tag (textarea).
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     <textarea>
+|       "<!--<textarea>"
+|     "-->"
+
+#data
+<!doctype html><textarea>&lt;/textarea></textarea>
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     <textarea>
+|       "</textarea>"
+
+#data
+<!doctype html><textarea>&lt;</textarea>
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     <textarea>
+|       "<"
+
+#data
+<!doctype html><textarea>a&lt;b</textarea>
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     <textarea>
+|       "a<b"
+
+#data
+<!doctype html><iframe><!--<iframe></iframe>--></iframe>
+#errors
+Line: 1 Col: 56 Unexpected end tag (iframe).
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     <iframe>
+|       "<!--<iframe>"
+|     "-->"
+
+#data
+<!doctype html><iframe>...<!--X->...<!--/X->...</iframe>
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     <iframe>
+|       "...<!--X->...<!--/X->..."
+
+#data
+<!doctype html><xmp><!--<xmp></xmp>--></xmp>
+#errors
+Line: 1 Col: 44 Unexpected end tag (xmp).
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     <xmp>
+|       "<!--<xmp>"
+|     "-->"
+
+#data
+<!doctype html><noembed><!--<noembed></noembed>--></noembed>
+#errors
+Line: 1 Col: 60 Unexpected end tag (noembed).
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     <noembed>
+|       "<!--<noembed>"
+|     "-->"
+
+#data
+<script>
+#errors
+Line: 1 Col: 8 Unexpected start tag (script). Expected DOCTYPE.
+Line: 1 Col: 8 Unexpected end of file. Expected end tag (script).
+#document
+| <html>
+|   <head>
+|     <script>
+|   <body>
+
+#data
+<script>a
+#errors
+Line: 1 Col: 8 Unexpected start tag (script). Expected DOCTYPE.
+Line: 1 Col: 9 Unexpected end of file. Expected end tag (script).
+#document
+| <html>
+|   <head>
+|     <script>
+|       "a"
+|   <body>
+
+#data
+<script><
+#errors
+Line: 1 Col: 8 Unexpected start tag (script). Expected DOCTYPE.
+Line: 1 Col: 9 Unexpected end of file. Expected end tag (script).
+#document
+| <html>
+|   <head>
+|     <script>
+|       "<"
+|   <body>
+
+#data
+<script></
+#errors
+Line: 1 Col: 8 Unexpected start tag (script). Expected DOCTYPE.
+Line: 1 Col: 10 Unexpected end of file. Expected end tag (script).
+#document
+| <html>
+|   <head>
+|     <script>
+|       "</"
+|   <body>
+
+#data
+<script></S
+#errors
+Line: 1 Col: 8 Unexpected start tag (script). Expected DOCTYPE.
+Line: 1 Col: 11 Unexpected end of file. Expected end tag (script).
+#document
+| <html>
+|   <head>
+|     <script>
+|       "</S"
+|   <body>
+
+#data
+<script></SC
+#errors
+Line: 1 Col: 8 Unexpected start tag (script). Expected DOCTYPE.
+Line: 1 Col: 12 Unexpected end of file. Expected end tag (script).
+#document
+| <html>
+|   <head>
+|     <script>
+|       "</SC"
+|   <body>
+
+#data
+<script></SCR
+#errors
+Line: 1 Col: 8 Unexpected start tag (script). Expected DOCTYPE.
+Line: 1 Col: 13 Unexpected end of file. Expected end tag (script).
+#document
+| <html>
+|   <head>
+|     <script>
+|       "</SCR"
+|   <body>
+
+#data
+<script></SCRI
+#errors
+Line: 1 Col: 8 Unexpected start tag (script). Expected DOCTYPE.
+Line: 1 Col: 14 Unexpected end of file. Expected end tag (script).
+#document
+| <html>
+|   <head>
+|     <script>
+|       "</SCRI"
+|   <body>
+
+#data
+<script></SCRIP
+#errors
+Line: 1 Col: 8 Unexpected start tag (script). Expected DOCTYPE.
+Line: 1 Col: 15 Unexpected end of file. Expected end tag (script).
+#document
+| <html>
+|   <head>
+|     <script>
+|       "</SCRIP"
+|   <body>
+
+#data
+<script></SCRIPT
+#errors
+Line: 1 Col: 8 Unexpected start tag (script). Expected DOCTYPE.
+Line: 1 Col: 16 Unexpected end of file. Expected end tag (script).
+#document
+| <html>
+|   <head>
+|     <script>
+|       "</SCRIPT"
+|   <body>
+
+#data
+<script></SCRIPT 
+#errors
+Line: 1 Col: 8 Unexpected start tag (script). Expected DOCTYPE.
+Line: 1 Col: 17 Unexpected end of file. Expected end tag (script).
+#document
+| <html>
+|   <head>
+|     <script>
+|   <body>
+
+#data
+<script></s
+#errors
+Line: 1 Col: 8 Unexpected start tag (script). Expected DOCTYPE.
+Line: 1 Col: 11 Unexpected end of file. Expected end tag (script).
+#document
+| <html>
+|   <head>
+|     <script>
+|       "</s"
+|   <body>
+
+#data
+<script></sc
+#errors
+Line: 1 Col: 8 Unexpected start tag (script). Expected DOCTYPE.
+Line: 1 Col: 12 Unexpected end of file. Expected end tag (script).
+#document
+| <html>
+|   <head>
+|     <script>
+|       "</sc"
+|   <body>
+
+#data
+<script></scr
+#errors
+Line: 1 Col: 8 Unexpected start tag (script). Expected DOCTYPE.
+Line: 1 Col: 13 Unexpected end of file. Expected end tag (script).
+#document
+| <html>
+|   <head>
+|     <script>
+|       "</scr"
+|   <body>
+
+#data
+<script></scri
+#errors
+Line: 1 Col: 8 Unexpected start tag (script). Expected DOCTYPE.
+Line: 1 Col: 14 Unexpected end of file. Expected end tag (script).
+#document
+| <html>
+|   <head>
+|     <script>
+|       "</scri"
+|   <body>
+
+#data
+<script></scrip
+#errors
+Line: 1 Col: 8 Unexpected start tag (script). Expected DOCTYPE.
+Line: 1 Col: 15 Unexpected end of file. Expected end tag (script).
+#document
+| <html>
+|   <head>
+|     <script>
+|       "</scrip"
+|   <body>
+
+#data
+<script></script
+#errors
+Line: 1 Col: 8 Unexpected start tag (script). Expected DOCTYPE.
+Line: 1 Col: 16 Unexpected end of file. Expected end tag (script).
+#document
+| <html>
+|   <head>
+|     <script>
+|       "</script"
+|   <body>
+
+#data
+<script></script 
+#errors
+Line: 1 Col: 8 Unexpected start tag (script). Expected DOCTYPE.
+Line: 1 Col: 17 Unexpected end of file. Expected end tag (script).
+#document
+| <html>
+|   <head>
+|     <script>
+|   <body>
+
+#data
+<script><!
+#errors
+Line: 1 Col: 8 Unexpected start tag (script). Expected DOCTYPE.
+Line: 1 Col: 10 Unexpected end of file. Expected end tag (script).
+#document
+| <html>
+|   <head>
+|     <script>
+|       "<!"
+|   <body>
+
+#data
+<script><!a
+#errors
+Line: 1 Col: 8 Unexpected start tag (script). Expected DOCTYPE.
+Line: 1 Col: 11 Unexpected end of file. Expected end tag (script).
+#document
+| <html>
+|   <head>
+|     <script>
+|       "<!a"
+|   <body>
+
+#data
+<script><!-
+#errors
+Line: 1 Col: 8 Unexpected start tag (script). Expected DOCTYPE.
+Line: 1 Col: 11 Unexpected end of file. Expected end tag (script).
+#document
+| <html>
+|   <head>
+|     <script>
+|       "<!-"
+|   <body>
+
+#data
+<script><!-a
+#errors
+Line: 1 Col: 8 Unexpected start tag (script). Expected DOCTYPE.
+Line: 1 Col: 12 Unexpected end of file. Expected end tag (script).
+#document
+| <html>
+|   <head>
+|     <script>
+|       "<!-a"
+|   <body>
+
+#data
+<script><!--
+#errors
+Line: 1 Col: 8 Unexpected start tag (script). Expected DOCTYPE.
+Line: 1 Col: 12 Unexpected end of file. Expected end tag (script).
+#document
+| <html>
+|   <head>
+|     <script>
+|       "<!--"
+|   <body>
+
+#data
+<script><!--a
+#errors
+Line: 1 Col: 8 Unexpected start tag (script). Expected DOCTYPE.
+Line: 1 Col: 13 Unexpected end of file. Expected end tag (script).
+#document
+| <html>
+|   <head>
+|     <script>
+|       "<!--a"
+|   <body>
+
+#data
+<script><!--<
+#errors
+Line: 1 Col: 8 Unexpected start tag (script). Expected DOCTYPE.
+Line: 1 Col: 13 Unexpected end of file. Expected end tag (script).
+#document
+| <html>
+|   <head>
+|     <script>
+|       "<!--<"
+|   <body>
+
+#data
+<script><!--<a
+#errors
+Line: 1 Col: 8 Unexpected start tag (script). Expected DOCTYPE.
+Line: 1 Col: 14 Unexpected end of file. Expected end tag (script).
+#document
+| <html>
+|   <head>
+|     <script>
+|       "<!--<a"
+|   <body>
+
+#data
+<script><!--</
+#errors
+Line: 1 Col: 8 Unexpected start tag (script). Expected DOCTYPE.
+Line: 1 Col: 14 Unexpected end of file. Expected end tag (script).
+#document
+| <html>
+|   <head>
+|     <script>
+|       "<!--</"
+|   <body>
+
+#data
+<script><!--</script
+#errors
+Line: 1 Col: 8 Unexpected start tag (script). Expected DOCTYPE.
+Line: 1 Col: 20 Unexpected end of file. Expected end tag (script).
+#document
+| <html>
+|   <head>
+|     <script>
+|       "<!--</script"
+|   <body>
+
+#data
+<script><!--</script 
+#errors
+Line: 1 Col: 8 Unexpected start tag (script). Expected DOCTYPE.
+Line: 1 Col: 21 Unexpected end of file. Expected end tag (script).
+#document
+| <html>
+|   <head>
+|     <script>
+|       "<!--"
+|   <body>
+
+#data
+<script><!--<s
+#errors
+Line: 1 Col: 8 Unexpected start tag (script). Expected DOCTYPE.
+Line: 1 Col: 14 Unexpected end of file. Expected end tag (script).
+#document
+| <html>
+|   <head>
+|     <script>
+|       "<!--<s"
+|   <body>
+
+#data
+<script><!--<script
+#errors
+Line: 1 Col: 8 Unexpected start tag (script). Expected DOCTYPE.
+Line: 1 Col: 19 Unexpected end of file. Expected end tag (script).
+#document
+| <html>
+|   <head>
+|     <script>
+|       "<!--<script"
+|   <body>
+
+#data
+<script><!--<script 
+#errors
+Line: 1 Col: 8 Unexpected start tag (script). Expected DOCTYPE.
+Line: 1 Col: 20 Unexpected end of file. Expected end tag (script).
+#document
+| <html>
+|   <head>
+|     <script>
+|       "<!--<script "
+|   <body>
+
+#data
+<script><!--<script <
+#errors
+Line: 1 Col: 8 Unexpected start tag (script). Expected DOCTYPE.
+Line: 1 Col: 21 Unexpected end of file. Expected end tag (script).
+#document
+| <html>
+|   <head>
+|     <script>
+|       "<!--<script <"
+|   <body>
+
+#data
+<script><!--<script <a
+#errors
+Line: 1 Col: 8 Unexpected start tag (script). Expected DOCTYPE.
+Line: 1 Col: 22 Unexpected end of file. Expected end tag (script).
+#document
+| <html>
+|   <head>
+|     <script>
+|       "<!--<script <a"
+|   <body>
+
+#data
+<script><!--<script </
+#errors
+Line: 1 Col: 8 Unexpected start tag (script). Expected DOCTYPE.
+Line: 1 Col: 22 Unexpected end of file. Expected end tag (script).
+#document
+| <html>
+|   <head>
+|     <script>
+|       "<!--<script </"
+|   <body>
+
+#data
+<script><!--<script </s
+#errors
+Line: 1 Col: 8 Unexpected start tag (script). Expected DOCTYPE.
+Line: 1 Col: 23 Unexpected end of file. Expected end tag (script).
+#document
+| <html>
+|   <head>
+|     <script>
+|       "<!--<script </s"
+|   <body>
+
+#data
+<script><!--<script </script
+#errors
+Line: 1 Col: 8 Unexpected start tag (script). Expected DOCTYPE.
+Line: 1 Col: 28 Unexpected end of file. Expected end tag (script).
+#document
+| <html>
+|   <head>
+|     <script>
+|       "<!--<script </script"
+|   <body>
+
+#data
+<script><!--<script </scripta
+#errors
+Line: 1 Col: 8 Unexpected start tag (script). Expected DOCTYPE.
+Line: 1 Col: 29 Unexpected end of file. Expected end tag (script).
+#document
+| <html>
+|   <head>
+|     <script>
+|       "<!--<script </scripta"
+|   <body>
+
+#data
+<script><!--<script </script 
+#errors
+Line: 1 Col: 8 Unexpected start tag (script). Expected DOCTYPE.
+Line: 1 Col: 29 Unexpected end of file. Expected end tag (script).
+#document
+| <html>
+|   <head>
+|     <script>
+|       "<!--<script </script "
+|   <body>
+
+#data
+<script><!--<script </script>
+#errors
+Line: 1 Col: 8 Unexpected start tag (script). Expected DOCTYPE.
+Line: 1 Col: 29 Unexpected end of file. Expected end tag (script).
+#document
+| <html>
+|   <head>
+|     <script>
+|       "<!--<script </script>"
+|   <body>
+
+#data
+<script><!--<script </script/
+#errors
+Line: 1 Col: 8 Unexpected start tag (script). Expected DOCTYPE.
+Line: 1 Col: 29 Unexpected end of file. Expected end tag (script).
+#document
+| <html>
+|   <head>
+|     <script>
+|       "<!--<script </script/"
+|   <body>
+
+#data
+<script><!--<script </script <
+#errors
+Line: 1 Col: 8 Unexpected start tag (script). Expected DOCTYPE.
+Line: 1 Col: 30 Unexpected end of file. Expected end tag (script).
+#document
+| <html>
+|   <head>
+|     <script>
+|       "<!--<script </script <"
+|   <body>
+
+#data
+<script><!--<script </script <a
+#errors
+Line: 1 Col: 8 Unexpected start tag (script). Expected DOCTYPE.
+Line: 1 Col: 31 Unexpected end of file. Expected end tag (script).
+#document
+| <html>
+|   <head>
+|     <script>
+|       "<!--<script </script <a"
+|   <body>
+
+#data
+<script><!--<script </script </
+#errors
+Line: 1 Col: 8 Unexpected start tag (script). Expected DOCTYPE.
+Line: 1 Col: 31 Unexpected end of file. Expected end tag (script).
+#document
+| <html>
+|   <head>
+|     <script>
+|       "<!--<script </script </"
+|   <body>
+
+#data
+<script><!--<script </script </script
+#errors
+Line: 1 Col: 8 Unexpected start tag (script). Expected DOCTYPE.
+Line: 1 Col: 38 Unexpected end of file. Expected end tag (script).
+#document
+| <html>
+|   <head>
+|     <script>
+|       "<!--<script </script </script"
+|   <body>
+
+#data
+<script><!--<script </script </script 
+#errors
+Line: 1 Col: 8 Unexpected start tag (script). Expected DOCTYPE.
+Line: 1 Col: 38 Unexpected end of file. Expected end tag (script).
+#document
+| <html>
+|   <head>
+|     <script>
+|       "<!--<script </script "
+|   <body>
+
+#data
+<script><!--<script </script </script/
+#errors
+Line: 1 Col: 8 Unexpected start tag (script). Expected DOCTYPE.
+Line: 1 Col: 38 Unexpected end of file. Expected end tag (script).
+#document
+| <html>
+|   <head>
+|     <script>
+|       "<!--<script </script "
+|   <body>
+
+#data
+<script><!--<script </script </script>
+#errors
+Line: 1 Col: 8 Unexpected start tag (script). Expected DOCTYPE.
+#document
+| <html>
+|   <head>
+|     <script>
+|       "<!--<script </script "
+|   <body>
+
+#data
+<script><!--<script -
+#errors
+Line: 1 Col: 8 Unexpected start tag (script). Expected DOCTYPE.
+Line: 1 Col: 21 Unexpected end of file. Expected end tag (script).
+#document
+| <html>
+|   <head>
+|     <script>
+|       "<!--<script -"
+|   <body>
+
+#data
+<script><!--<script -a
+#errors
+Line: 1 Col: 8 Unexpected start tag (script). Expected DOCTYPE.
+Line: 1 Col: 22 Unexpected end of file. Expected end tag (script).
+#document
+| <html>
+|   <head>
+|     <script>
+|       "<!--<script -a"
+|   <body>
+
+#data
+<script><!--<script --
+#errors
+Line: 1 Col: 8 Unexpected start tag (script). Expected DOCTYPE.
+Line: 1 Col: 22 Unexpected end of file. Expected end tag (script).
+#document
+| <html>
+|   <head>
+|     <script>
+|       "<!--<script --"
+|   <body>
+
+#data
+<script><!--<script --a
+#errors
+Line: 1 Col: 8 Unexpected start tag (script). Expected DOCTYPE.
+Line: 1 Col: 23 Unexpected end of file. Expected end tag (script).
+#document
+| <html>
+|   <head>
+|     <script>
+|       "<!--<script --a"
+|   <body>
+
+#data
+<script><!--<script -->
+#errors
+Line: 1 Col: 8 Unexpected start tag (script). Expected DOCTYPE.
+Line: 1 Col: 23 Unexpected end of file. Expected end tag (script).
+#document
+| <html>
+|   <head>
+|     <script>
+|       "<!--<script -->"
+|   <body>
+
+#data
+<script><!--<script --><
+#errors
+Line: 1 Col: 8 Unexpected start tag (script). Expected DOCTYPE.
+Line: 1 Col: 24 Unexpected end of file. Expected end tag (script).
+#document
+| <html>
+|   <head>
+|     <script>
+|       "<!--<script --><"
+|   <body>
+
+#data
+<script><!--<script --></
+#errors
+Line: 1 Col: 8 Unexpected start tag (script). Expected DOCTYPE.
+Line: 1 Col: 25 Unexpected end of file. Expected end tag (script).
+#document
+| <html>
+|   <head>
+|     <script>
+|       "<!--<script --></"
+|   <body>
+
+#data
+<script><!--<script --></script
+#errors
+Line: 1 Col: 8 Unexpected start tag (script). Expected DOCTYPE.
+Line: 1 Col: 31 Unexpected end of file. Expected end tag (script).
+#document
+| <html>
+|   <head>
+|     <script>
+|       "<!--<script --></script"
+|   <body>
+
+#data
+<script><!--<script --></script 
+#errors
+Line: 1 Col: 8 Unexpected start tag (script). Expected DOCTYPE.
+Line: 1 Col: 32 Unexpected end of file. Expected end tag (script).
+#document
+| <html>
+|   <head>
+|     <script>
+|       "<!--<script -->"
+|   <body>
+
+#data
+<script><!--<script --></script/
+#errors
+Line: 1 Col: 8 Unexpected start tag (script). Expected DOCTYPE.
+Line: 1 Col: 32 Unexpected end of file. Expected end tag (script).
+#document
+| <html>
+|   <head>
+|     <script>
+|       "<!--<script -->"
+|   <body>
+
+#data
+<script><!--<script --></script>
+#errors
+Line: 1 Col: 8 Unexpected start tag (script). Expected DOCTYPE.
+#document
+| <html>
+|   <head>
+|     <script>
+|       "<!--<script -->"
+|   <body>
+
+#data
+<script><!--<script><\/script>--></script>
+#errors
+Line: 1 Col: 8 Unexpected start tag (script). Expected DOCTYPE.
+#document
+| <html>
+|   <head>
+|     <script>
+|       "<!--<script><\/script>-->"
+|   <body>
+
+#data
+<script><!--<script></scr'+'ipt>--></script>
+#errors
+Line: 1 Col: 8 Unexpected start tag (script). Expected DOCTYPE.
+#document
+| <html>
+|   <head>
+|     <script>
+|       "<!--<script></scr'+'ipt>-->"
+|   <body>
+
+#data
+<script><!--<script></script><script></script></script>
+#errors
+Line: 1 Col: 8 Unexpected start tag (script). Expected DOCTYPE.
+#document
+| <html>
+|   <head>
+|     <script>
+|       "<!--<script></script><script></script>"
+|   <body>
+
+#data
+<script><!--<script></script><script></script>--><!--</script>
+#errors
+Line: 1 Col: 8 Unexpected start tag (script). Expected DOCTYPE.
+#document
+| <html>
+|   <head>
+|     <script>
+|       "<!--<script></script><script></script>--><!--"
+|   <body>
+
+#data
+<script><!--<script></script><script></script>-- ></script>
+#errors
+Line: 1 Col: 8 Unexpected start tag (script). Expected DOCTYPE.
+#document
+| <html>
+|   <head>
+|     <script>
+|       "<!--<script></script><script></script>-- >"
+|   <body>
+
+#data
+<script><!--<script></script><script></script>- -></script>
+#errors
+Line: 1 Col: 8 Unexpected start tag (script). Expected DOCTYPE.
+#document
+| <html>
+|   <head>
+|     <script>
+|       "<!--<script></script><script></script>- ->"
+|   <body>
+
+#data
+<script><!--<script></script><script></script>- - ></script>
+#errors
+Line: 1 Col: 8 Unexpected start tag (script). Expected DOCTYPE.
+#document
+| <html>
+|   <head>
+|     <script>
+|       "<!--<script></script><script></script>- - >"
+|   <body>
+
+#data
+<script><!--<script></script><script></script>-></script>
+#errors
+Line: 1 Col: 8 Unexpected start tag (script). Expected DOCTYPE.
+#document
+| <html>
+|   <head>
+|     <script>
+|       "<!--<script></script><script></script>->"
+|   <body>
+
+#data
+<script><!--<script>--!></script>X
+#errors
+Line: 1 Col: 8 Unexpected start tag (script). Expected DOCTYPE.
+Line: 1 Col: 34 Unexpected end of file. Expected end tag (script).
+#document
+| <html>
+|   <head>
+|     <script>
+|       "<!--<script>--!></script>X"
+|   <body>
+
+#data
+<script><!--<scr'+'ipt></script>--></script>
+#errors
+Line: 1 Col: 8 Unexpected start tag (script). Expected DOCTYPE.
+Line: 1 Col: 44 Unexpected end tag (script).
+#document
+| <html>
+|   <head>
+|     <script>
+|       "<!--<scr'+'ipt>"
+|   <body>
+|     "-->"
+
+#data
+<script><!--<script></scr'+'ipt></script>X
+#errors
+Line: 1 Col: 8 Unexpected start tag (script). Expected DOCTYPE.
+Line: 1 Col: 42 Unexpected end of file. Expected end tag (script).
+#document
+| <html>
+|   <head>
+|     <script>
+|       "<!--<script></scr'+'ipt></script>X"
+|   <body>
+
+#data
+<style><!--<style></style>--></style>
+#errors
+Line: 1 Col: 7 Unexpected start tag (style). Expected DOCTYPE.
+Line: 1 Col: 37 Unexpected end tag (style).
+#document
+| <html>
+|   <head>
+|     <style>
+|       "<!--<style>"
+|   <body>
+|     "-->"
+
+#data
+<style><!--</style>X
+#errors
+Line: 1 Col: 7 Unexpected start tag (style). Expected DOCTYPE.
+#document
+| <html>
+|   <head>
+|     <style>
+|       "<!--"
+|   <body>
+|     "X"
+
+#data
+<style><!--...</style>...--></style>
+#errors
+Line: 1 Col: 7 Unexpected start tag (style). Expected DOCTYPE.
+Line: 1 Col: 36 Unexpected end tag (style).
+#document
+| <html>
+|   <head>
+|     <style>
+|       "<!--..."
+|   <body>
+|     "...-->"
+
+#data
+<style><!--<br><html xmlns:v="urn:schemas-microsoft-com:vml"><!--[if !mso]><style></style>X
+#errors
+Line: 1 Col: 7 Unexpected start tag (style). Expected DOCTYPE.
+#document
+| <html>
+|   <head>
+|     <style>
+|       "<!--<br><html xmlns:v="urn:schemas-microsoft-com:vml"><!--[if !mso]><style>"
+|   <body>
+|     "X"
+
+#data
+<style><!--...<style><!--...--!></style>--></style>
+#errors
+Line: 1 Col: 7 Unexpected start tag (style). Expected DOCTYPE.
+Line: 1 Col: 51 Unexpected end tag (style).
+#document
+| <html>
+|   <head>
+|     <style>
+|       "<!--...<style><!--...--!>"
+|   <body>
+|     "-->"
+
+#data
+<style><!--...</style><!-- --><style>@import ...</style>
+#errors
+Line: 1 Col: 7 Unexpected start tag (style). Expected DOCTYPE.
+#document
+| <html>
+|   <head>
+|     <style>
+|       "<!--..."
+|     <!--   -->
+|     <style>
+|       "@import ..."
+|   <body>
+
+#data
+<style>...<style><!--...</style><!-- --></style>
+#errors
+Line: 1 Col: 7 Unexpected start tag (style). Expected DOCTYPE.
+Line: 1 Col: 48 Unexpected end tag (style).
+#document
+| <html>
+|   <head>
+|     <style>
+|       "...<style><!--..."
+|     <!--   -->
+|   <body>
+
+#data
+<style>...<!--[if IE]><style>...</style>X
+#errors
+Line: 1 Col: 7 Unexpected start tag (style). Expected DOCTYPE.
+#document
+| <html>
+|   <head>
+|     <style>
+|       "...<!--[if IE]><style>..."
+|   <body>
+|     "X"
+
+#data
+<title><!--<title></title>--></title>
+#errors
+Line: 1 Col: 7 Unexpected start tag (title). Expected DOCTYPE.
+Line: 1 Col: 37 Unexpected end tag (title).
+#document
+| <html>
+|   <head>
+|     <title>
+|       "<!--<title>"
+|   <body>
+|     "-->"
+
+#data
+<title>&lt;/title></title>
+#errors
+Line: 1 Col: 7 Unexpected start tag (title). Expected DOCTYPE.
+#document
+| <html>
+|   <head>
+|     <title>
+|       "</title>"
+|   <body>
+
+#data
+<title>foo/title><link></head><body>X
+#errors
+Line: 1 Col: 7 Unexpected start tag (title). Expected DOCTYPE.
+Line: 1 Col: 37 Unexpected end of file. Expected end tag (title).
+#document
+| <html>
+|   <head>
+|     <title>
+|       "foo/title><link></head><body>X"
+|   <body>
+
+#data
+<noscript><!--<noscript></noscript>--></noscript>
+#errors
+Line: 1 Col: 10 Unexpected start tag (noscript). Expected DOCTYPE.
+Line: 1 Col: 49 Unexpected end tag (noscript).
+#document
+| <html>
+|   <head>
+|     <noscript>
+|       "<!--<noscript>"
+|   <body>
+|     "-->"
+
+#data
+<noscript><!--</noscript>X<noscript>--></noscript>
+#errors
+Line: 1 Col: 10 Unexpected start tag (noscript). Expected DOCTYPE.
+#document
+| <html>
+|   <head>
+|     <noscript>
+|       "<!--"
+|   <body>
+|     "X"
+|     <noscript>
+|       "-->"
+
+#data
+<noscript><iframe></noscript>X
+#errors
+Line: 1 Col: 10 Unexpected start tag (noscript). Expected DOCTYPE.
+#document
+| <html>
+|   <head>
+|     <noscript>
+|       "<iframe>"
+|   <body>
+|     "X"
+
+#data
+<noframes><!--<noframes></noframes>--></noframes>
+#errors
+Line: 1 Col: 10 Unexpected start tag (noframes). Expected DOCTYPE.
+Line: 1 Col: 49 Unexpected end tag (noframes).
+#document
+| <html>
+|   <head>
+|     <noframes>
+|       "<!--<noframes>"
+|   <body>
+|     "-->"
+
+#data
+<noframes><body><script><!--...</script></body></noframes></html>
+#errors
+Line: 1 Col: 10 Unexpected start tag (noframes). Expected DOCTYPE.
+#document
+| <html>
+|   <head>
+|     <noframes>
+|       "<body><script><!--...</script></body>"
+|   <body>
+
+#data
+<textarea><!--<textarea></textarea>--></textarea>
+#errors
+Line: 1 Col: 10 Unexpected start tag (textarea). Expected DOCTYPE.
+Line: 1 Col: 49 Unexpected end tag (textarea).
+#document
+| <html>
+|   <head>
+|   <body>
+|     <textarea>
+|       "<!--<textarea>"
+|     "-->"
+
+#data
+<textarea>&lt;/textarea></textarea>
+#errors
+Line: 1 Col: 10 Unexpected start tag (textarea). Expected DOCTYPE.
+#document
+| <html>
+|   <head>
+|   <body>
+|     <textarea>
+|       "</textarea>"
+
+#data
+<iframe><!--<iframe></iframe>--></iframe>
+#errors
+Line: 1 Col: 8 Unexpected start tag (iframe). Expected DOCTYPE.
+Line: 1 Col: 41 Unexpected end tag (iframe).
+#document
+| <html>
+|   <head>
+|   <body>
+|     <iframe>
+|       "<!--<iframe>"
+|     "-->"
+
+#data
+<iframe>...<!--X->...<!--/X->...</iframe>
+#errors
+Line: 1 Col: 8 Unexpected start tag (iframe). Expected DOCTYPE.
+#document
+| <html>
+|   <head>
+|   <body>
+|     <iframe>
+|       "...<!--X->...<!--/X->..."
+
+#data
+<xmp><!--<xmp></xmp>--></xmp>
+#errors
+Line: 1 Col: 5 Unexpected start tag (xmp). Expected DOCTYPE.
+Line: 1 Col: 29 Unexpected end tag (xmp).
+#document
+| <html>
+|   <head>
+|   <body>
+|     <xmp>
+|       "<!--<xmp>"
+|     "-->"
+
+#data
+<noembed><!--<noembed></noembed>--></noembed>
+#errors
+Line: 1 Col: 9 Unexpected start tag (noembed). Expected DOCTYPE.
+Line: 1 Col: 45 Unexpected end tag (noembed).
+#document
+| <html>
+|   <head>
+|   <body>
+|     <noembed>
+|       "<!--<noembed>"
+|     "-->"
+
+#data
+<!doctype html><table>
+
+#errors
+Line 2 Col 0 Unexpected end of file. Expected table content.
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     <table>
+|       "
+"
+
+#data
+<!doctype html><table><td><span><font></span><span>
+#errors
+Line 1 Col 26 Unexpected table cell start tag (td) in the table body phase.
+Line 1 Col 45 Unexpected end tag (span).
+Line 1 Col 51 Expected closing tag. Unexpected end of file.
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     <table>
+|       <tbody>
+|         <tr>
+|           <td>
+|             <span>
+|               <font>
+|             <font>
+|               <span>
+
+#data
+<!doctype html><form><table></form><form></table></form>
+#errors
+35: Stray end tag “form”.
+41: Start tag “form” seen in “table”.
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     <form>
+|       <table>
+|         <form>
diff --git a/html/test/data/tree-construction/tests17.dat b/html/test/data/tree-construction/tests17.dat
new file mode 100644
index 0000000..7b555f8
--- /dev/null
+++ b/html/test/data/tree-construction/tests17.dat
@@ -0,0 +1,153 @@
+#data
+<!doctype html><table><tbody><select><tr>
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     <select>
+|     <table>
+|       <tbody>
+|         <tr>
+
+#data
+<!doctype html><table><tr><select><td>
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     <select>
+|     <table>
+|       <tbody>
+|         <tr>
+|           <td>
+
+#data
+<!doctype html><table><tr><td><select><td>
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     <table>
+|       <tbody>
+|         <tr>
+|           <td>
+|             <select>
+|           <td>
+
+#data
+<!doctype html><table><tr><th><select><td>
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     <table>
+|       <tbody>
+|         <tr>
+|           <th>
+|             <select>
+|           <td>
+
+#data
+<!doctype html><table><caption><select><tr>
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     <table>
+|       <caption>
+|         <select>
+|       <tbody>
+|         <tr>
+
+#data
+<!doctype html><select><tr>
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     <select>
+
+#data
+<!doctype html><select><td>
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     <select>
+
+#data
+<!doctype html><select><th>
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     <select>
+
+#data
+<!doctype html><select><tbody>
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     <select>
+
+#data
+<!doctype html><select><thead>
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     <select>
+
+#data
+<!doctype html><select><tfoot>
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     <select>
+
+#data
+<!doctype html><select><caption>
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     <select>
+
+#data
+<!doctype html><table><tr></table>a
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     <table>
+|       <tbody>
+|         <tr>
+|     "a"
diff --git a/html/test/data/tree-construction/tests18.dat b/html/test/data/tree-construction/tests18.dat
new file mode 100644
index 0000000..680e1f0
--- /dev/null
+++ b/html/test/data/tree-construction/tests18.dat
@@ -0,0 +1,269 @@
+#data
+<!doctype html><plaintext></plaintext>
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     <plaintext>
+|       "</plaintext>"
+
+#data
+<!doctype html><table><plaintext></plaintext>
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     <plaintext>
+|       "</plaintext>"
+|     <table>
+
+#data
+<!doctype html><table><tbody><plaintext></plaintext>
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     <plaintext>
+|       "</plaintext>"
+|     <table>
+|       <tbody>
+
+#data
+<!doctype html><table><tbody><tr><plaintext></plaintext>
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     <plaintext>
+|       "</plaintext>"
+|     <table>
+|       <tbody>
+|         <tr>
+
+#data
+<!doctype html><table><tbody><tr><plaintext></plaintext>
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     <plaintext>
+|       "</plaintext>"
+|     <table>
+|       <tbody>
+|         <tr>
+
+#data
+<!doctype html><table><td><plaintext></plaintext>
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     <table>
+|       <tbody>
+|         <tr>
+|           <td>
+|             <plaintext>
+|               "</plaintext>"
+
+#data
+<!doctype html><table><caption><plaintext></plaintext>
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     <table>
+|       <caption>
+|         <plaintext>
+|           "</plaintext>"
+
+#data
+<!doctype html><table><tr><style></script></style>abc
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     "abc"
+|     <table>
+|       <tbody>
+|         <tr>
+|           <style>
+|             "</script>"
+
+#data
+<!doctype html><table><tr><script></style></script>abc
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     "abc"
+|     <table>
+|       <tbody>
+|         <tr>
+|           <script>
+|             "</style>"
+
+#data
+<!doctype html><table><caption><style></script></style>abc
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     <table>
+|       <caption>
+|         <style>
+|           "</script>"
+|         "abc"
+
+#data
+<!doctype html><table><td><style></script></style>abc
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     <table>
+|       <tbody>
+|         <tr>
+|           <td>
+|             <style>
+|               "</script>"
+|             "abc"
+
+#data
+<!doctype html><select><script></style></script>abc
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     <select>
+|       <script>
+|         "</style>"
+|       "abc"
+
+#data
+<!doctype html><table><select><script></style></script>abc
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     <select>
+|       <script>
+|         "</style>"
+|       "abc"
+|     <table>
+
+#data
+<!doctype html><table><tr><select><script></style></script>abc
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     <select>
+|       <script>
+|         "</style>"
+|       "abc"
+|     <table>
+|       <tbody>
+|         <tr>
+
+#data
+<!doctype html><frameset></frameset><noframes>abc
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <frameset>
+|   <noframes>
+|     "abc"
+
+#data
+<!doctype html><frameset></frameset><noframes>abc</noframes><!--abc-->
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <frameset>
+|   <noframes>
+|     "abc"
+|   <!-- abc -->
+
+#data
+<!doctype html><frameset></frameset></html><noframes>abc
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <frameset>
+|   <noframes>
+|     "abc"
+
+#data
+<!doctype html><frameset></frameset></html><noframes>abc</noframes><!--abc-->
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <frameset>
+|   <noframes>
+|     "abc"
+| <!-- abc -->
+
+#data
+<!doctype html><table><tr></tbody><tfoot>
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     <table>
+|       <tbody>
+|         <tr>
+|       <tfoot>
+
+#data
+<!doctype html><table><td><svg></svg>abc<td>
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     <table>
+|       <tbody>
+|         <tr>
+|           <td>
+|             <svg svg>
+|             "abc"
+|           <td>
diff --git a/html/test/data/tree-construction/tests19.dat b/html/test/data/tree-construction/tests19.dat
new file mode 100644
index 0000000..0d62f5a
--- /dev/null
+++ b/html/test/data/tree-construction/tests19.dat
@@ -0,0 +1,1237 @@
+#data
+<!doctype html><math><mn DefinitionUrl="foo">
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     <math math>
+|       <math mn>
+|         definitionURL="foo"
+
+#data
+<!doctype html><html></p><!--foo-->
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+|   <!-- foo -->
+|   <head>
+|   <body>
+
+#data
+<!doctype html><head></head></p><!--foo-->
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <!-- foo -->
+|   <body>
+
+#data
+<!doctype html><body><p><pre>
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     <p>
+|     <pre>
+
+#data
+<!doctype html><body><p><listing>
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     <p>
+|     <listing>
+
+#data
+<!doctype html><p><plaintext>
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     <p>
+|     <plaintext>
+
+#data
+<!doctype html><p><h1>
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     <p>
+|     <h1>
+
+#data
+<!doctype html><form><isindex>
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     <form>
+
+#data
+<!doctype html><isindex action="POST">
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     <form>
+|       action="POST"
+|       <hr>
+|       <label>
+|         "This is a searchable index. Enter search keywords: "
+|         <input>
+|           name="isindex"
+|       <hr>
+
+#data
+<!doctype html><isindex prompt="this is isindex">
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     <form>
+|       <hr>
+|       <label>
+|         "this is isindex"
+|         <input>
+|           name="isindex"
+|       <hr>
+
+#data
+<!doctype html><isindex type="hidden">
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     <form>
+|       <hr>
+|       <label>
+|         "This is a searchable index. Enter search keywords: "
+|         <input>
+|           name="isindex"
+|           type="hidden"
+|       <hr>
+
+#data
+<!doctype html><isindex name="foo">
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     <form>
+|       <hr>
+|       <label>
+|         "This is a searchable index. Enter search keywords: "
+|         <input>
+|           name="isindex"
+|       <hr>
+
+#data
+<!doctype html><ruby><p><rp>
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     <ruby>
+|       <p>
+|       <rp>
+
+#data
+<!doctype html><ruby><div><span><rp>
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     <ruby>
+|       <div>
+|         <span>
+|           <rp>
+
+#data
+<!doctype html><ruby><div><p><rp>
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     <ruby>
+|       <div>
+|         <p>
+|         <rp>
+
+#data
+<!doctype html><ruby><p><rt>
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     <ruby>
+|       <p>
+|       <rt>
+
+#data
+<!doctype html><ruby><div><span><rt>
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     <ruby>
+|       <div>
+|         <span>
+|           <rt>
+
+#data
+<!doctype html><ruby><div><p><rt>
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     <ruby>
+|       <div>
+|         <p>
+|         <rt>
+
+#data
+<!doctype html><math/><foo>
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     <math math>
+|     <foo>
+
+#data
+<!doctype html><svg/><foo>
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     <svg svg>
+|     <foo>
+
+#data
+<!doctype html><div></body><!--foo-->
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     <div>
+|   <!-- foo -->
+
+#data
+<!doctype html><h1><div><h3><span></h1>foo
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     <h1>
+|       <div>
+|         <h3>
+|           <span>
+|         "foo"
+
+#data
+<!doctype html><p></h3>foo
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     <p>
+|       "foo"
+
+#data
+<!doctype html><h3><li>abc</h2>foo
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     <h3>
+|       <li>
+|         "abc"
+|     "foo"
+
+#data
+<!doctype html><table>abc<!--foo-->
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     "abc"
+|     <table>
+|       <!-- foo -->
+
+#data
+<!doctype html><table>  <!--foo-->
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     <table>
+|       "  "
+|       <!-- foo -->
+
+#data
+<!doctype html><table> b <!--foo-->
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     " b "
+|     <table>
+|       <!-- foo -->
+
+#data
+<!doctype html><select><option><option>
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     <select>
+|       <option>
+|       <option>
+
+#data
+<!doctype html><select><option></optgroup>
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     <select>
+|       <option>
+
+#data
+<!doctype html><select><option></optgroup>
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     <select>
+|       <option>
+
+#data
+<!doctype html><p><math><mi><p><h1>
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     <p>
+|       <math math>
+|         <math mi>
+|           <p>
+|           <h1>
+
+#data
+<!doctype html><p><math><mo><p><h1>
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     <p>
+|       <math math>
+|         <math mo>
+|           <p>
+|           <h1>
+
+#data
+<!doctype html><p><math><mn><p><h1>
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     <p>
+|       <math math>
+|         <math mn>
+|           <p>
+|           <h1>
+
+#data
+<!doctype html><p><math><ms><p><h1>
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     <p>
+|       <math math>
+|         <math ms>
+|           <p>
+|           <h1>
+
+#data
+<!doctype html><p><math><mtext><p><h1>
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     <p>
+|       <math math>
+|         <math mtext>
+|           <p>
+|           <h1>
+
+#data
+<!doctype html><frameset></noframes>
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <frameset>
+
+#data
+<!doctype html><html c=d><body></html><html a=b>
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+|   a="b"
+|   c="d"
+|   <head>
+|   <body>
+
+#data
+<!doctype html><html c=d><frameset></frameset></html><html a=b>
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+|   a="b"
+|   c="d"
+|   <head>
+|   <frameset>
+
+#data
+<!doctype html><html><frameset></frameset></html><!--foo-->
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <frameset>
+| <!-- foo -->
+
+#data
+<!doctype html><html><frameset></frameset></html>  
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <frameset>
+|   "  "
+
+#data
+<!doctype html><html><frameset></frameset></html>abc
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <frameset>
+
+#data
+<!doctype html><html><frameset></frameset></html><p>
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <frameset>
+
+#data
+<!doctype html><html><frameset></frameset></html></p>
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <frameset>
+
+#data
+<html><frameset></frameset></html><!doctype html>
+#errors
+#document
+| <html>
+|   <head>
+|   <frameset>
+
+#data
+<!doctype html><body><frameset>
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+
+#data
+<!doctype html><p><frameset><frame>
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <frameset>
+|     <frame>
+
+#data
+<!doctype html><p>a<frameset>
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     <p>
+|       "a"
+
+#data
+<!doctype html><p> <frameset><frame>
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <frameset>
+|     <frame>
+
+#data
+<!doctype html><pre><frameset>
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     <pre>
+
+#data
+<!doctype html><listing><frameset>
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     <listing>
+
+#data
+<!doctype html><li><frameset>
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     <li>
+
+#data
+<!doctype html><dd><frameset>
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     <dd>
+
+#data
+<!doctype html><dt><frameset>
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     <dt>
+
+#data
+<!doctype html><button><frameset>
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     <button>
+
+#data
+<!doctype html><applet><frameset>
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     <applet>
+
+#data
+<!doctype html><marquee><frameset>
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     <marquee>
+
+#data
+<!doctype html><object><frameset>
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     <object>
+
+#data
+<!doctype html><table><frameset>
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     <table>
+
+#data
+<!doctype html><area><frameset>
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     <area>
+
+#data
+<!doctype html><basefont><frameset>
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|     <basefont>
+|   <frameset>
+
+#data
+<!doctype html><bgsound><frameset>
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|     <bgsound>
+|   <frameset>
+
+#data
+<!doctype html><br><frameset>
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     <br>
+
+#data
+<!doctype html><embed><frameset>
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     <embed>
+
+#data
+<!doctype html><img><frameset>
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     <img>
+
+#data
+<!doctype html><input><frameset>
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     <input>
+
+#data
+<!doctype html><keygen><frameset>
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     <keygen>
+
+#data
+<!doctype html><wbr><frameset>
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     <wbr>
+
+#data
+<!doctype html><hr><frameset>
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     <hr>
+
+#data
+<!doctype html><textarea></textarea><frameset>
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     <textarea>
+
+#data
+<!doctype html><xmp></xmp><frameset>
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     <xmp>
+
+#data
+<!doctype html><iframe></iframe><frameset>
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     <iframe>
+
+#data
+<!doctype html><select></select><frameset>
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     <select>
+
+#data
+<!doctype html><svg></svg><frameset><frame>
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <frameset>
+|     <frame>
+
+#data
+<!doctype html><math></math><frameset><frame>
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <frameset>
+|     <frame>
+
+#data
+<!doctype html><svg><foreignObject><div> <frameset><frame>
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <frameset>
+|     <frame>
+
+#data
+<!doctype html><svg>a</svg><frameset><frame>
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     <svg svg>
+|       "a"
+
+#data
+<!doctype html><svg> </svg><frameset><frame>
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <frameset>
+|     <frame>
+
+#data
+<html>aaa<frameset></frameset>
+#errors
+#document
+| <html>
+|   <head>
+|   <body>
+|     "aaa"
+
+#data
+<html> a <frameset></frameset>
+#errors
+#document
+| <html>
+|   <head>
+|   <body>
+|     "a "
+
+#data
+<!doctype html><div><frameset>
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <frameset>
+
+#data
+<!doctype html><div><body><frameset>
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     <div>
+
+#data
+<!doctype html><p><math></p>a
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     <p>
+|       <math math>
+|     "a"
+
+#data
+<!doctype html><p><math><mn><span></p>a
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     <p>
+|       <math math>
+|         <math mn>
+|           <span>
+|             <p>
+|             "a"
+
+#data
+<!doctype html><math></html>
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     <math math>
+
+#data
+<!doctype html><meta charset="ascii">
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|     <meta>
+|       charset="ascii"
+|   <body>
+
+#data
+<!doctype html><meta http-equiv="content-type" content="text/html;charset=ascii">
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|     <meta>
+|       content="text/html;charset=ascii"
+|       http-equiv="content-type"
+|   <body>
+
+#data
+<!doctype html><head><!--aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa--><meta charset="utf8">
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|     <!-- aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -->
+|     <meta>
+|       charset="utf8"
+|   <body>
+
+#data
+<!doctype html><html a=b><head></head><html c=d>
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+|   a="b"
+|   c="d"
+|   <head>
+|   <body>
+
+#data
+<!doctype html><image/>
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     <img>
+
+#data
+<!doctype html>a<i>b<table>c<b>d</i>e</b>f
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     "a"
+|     <i>
+|       "bc"
+|       <b>
+|         "de"
+|       "f"
+|       <table>
+
+#data
+<!doctype html><table><i>a<b>b<div>c<a>d</i>e</b>f
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     <i>
+|       "a"
+|       <b>
+|         "b"
+|     <b>
+|     <div>
+|       <b>
+|         <i>
+|           "c"
+|           <a>
+|             "d"
+|         <a>
+|           "e"
+|       <a>
+|         "f"
+|     <table>
+
+#data
+<!doctype html><i>a<b>b<div>c<a>d</i>e</b>f
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     <i>
+|       "a"
+|       <b>
+|         "b"
+|     <b>
+|     <div>
+|       <b>
+|         <i>
+|           "c"
+|           <a>
+|             "d"
+|         <a>
+|           "e"
+|       <a>
+|         "f"
+
+#data
+<!doctype html><table><i>a<b>b<div>c</i>
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     <i>
+|       "a"
+|       <b>
+|         "b"
+|     <b>
+|       <div>
+|         <i>
+|           "c"
+|     <table>
+
+#data
+<!doctype html><table><i>a<b>b<div>c<a>d</i>e</b>f
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     <i>
+|       "a"
+|       <b>
+|         "b"
+|     <b>
+|     <div>
+|       <b>
+|         <i>
+|           "c"
+|           <a>
+|             "d"
+|         <a>
+|           "e"
+|       <a>
+|         "f"
+|     <table>
+
+#data
+<!doctype html><table><i>a<div>b<tr>c<b>d</i>e
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     <i>
+|       "a"
+|       <div>
+|         "b"
+|     <i>
+|       "c"
+|       <b>
+|         "d"
+|     <b>
+|       "e"
+|     <table>
+|       <tbody>
+|         <tr>
+
+#data
+<!doctype html><table><td><table><i>a<div>b<b>c</i>d
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     <table>
+|       <tbody>
+|         <tr>
+|           <td>
+|             <i>
+|               "a"
+|             <div>
+|               <i>
+|                 "b"
+|                 <b>
+|                   "c"
+|               <b>
+|                 "d"
+|             <table>
+
+#data
+<!doctype html><body><bgsound>
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     <bgsound>
+
+#data
+<!doctype html><body><basefont>
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     <basefont>
+
+#data
+<!doctype html><a><b></a><basefont>
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     <a>
+|       <b>
+|     <basefont>
+
+#data
+<!doctype html><a><b></a><bgsound>
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     <a>
+|       <b>
+|     <bgsound>
+
+#data
+<!doctype html><figcaption><article></figcaption>a
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     <figcaption>
+|       <article>
+|     "a"
+
+#data
+<!doctype html><summary><article></summary>a
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     <summary>
+|       <article>
+|     "a"
+
+#data
+<!doctype html><p><a><plaintext>b
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     <p>
+|       <a>
+|     <plaintext>
+|       <a>
+|         "b"
+
+#data
+<!DOCTYPE html><div>a<a></div>b<p>c</p>d
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     <div>
+|       "a"
+|       <a>
+|     <a>
+|       "b"
+|       <p>
+|         "c"
+|       "d"
diff --git a/html/test/data/tree-construction/tests2.dat b/html/test/data/tree-construction/tests2.dat
new file mode 100644
index 0000000..60d8592
--- /dev/null
+++ b/html/test/data/tree-construction/tests2.dat
@@ -0,0 +1,763 @@
+#data
+<!DOCTYPE html>Test
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     "Test"
+
+#data
+<textarea>test</div>test
+#errors
+Line: 1 Col: 10 Unexpected start tag (textarea). Expected DOCTYPE.
+Line: 1 Col: 24 Expected closing tag. Unexpected end of file.
+#document
+| <html>
+|   <head>
+|   <body>
+|     <textarea>
+|       "test</div>test"
+
+#data
+<table><td>
+#errors
+Line: 1 Col: 7 Unexpected start tag (table). Expected DOCTYPE.
+Line: 1 Col: 11 Unexpected table cell start tag (td) in the table body phase.
+Line: 1 Col: 11 Expected closing tag. Unexpected end of file.
+#document
+| <html>
+|   <head>
+|   <body>
+|     <table>
+|       <tbody>
+|         <tr>
+|           <td>
+
+#data
+<table><td>test</tbody></table>
+#errors
+Line: 1 Col: 7 Unexpected start tag (table). Expected DOCTYPE.
+Line: 1 Col: 11 Unexpected table cell start tag (td) in the table body phase.
+#document
+| <html>
+|   <head>
+|   <body>
+|     <table>
+|       <tbody>
+|         <tr>
+|           <td>
+|             "test"
+
+#data
+<frame>test
+#errors
+Line: 1 Col: 7 Unexpected start tag (frame). Expected DOCTYPE.
+Line: 1 Col: 7 Unexpected start tag frame. Ignored.
+#document
+| <html>
+|   <head>
+|   <body>
+|     "test"
+
+#data
+<!DOCTYPE html><frameset>test
+#errors
+Line: 1 Col: 29 Unepxected characters in the frameset phase. Characters ignored.
+Line: 1 Col: 29 Expected closing tag. Unexpected end of file.
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <frameset>
+
+#data
+<!DOCTYPE html><frameset><!DOCTYPE html>
+#errors
+Line: 1 Col: 40 Unexpected DOCTYPE. Ignored.
+Line: 1 Col: 40 Expected closing tag. Unexpected end of file.
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <frameset>
+
+#data
+<!DOCTYPE html><font><p><b>test</font>
+#errors
+Line: 1 Col: 38 End tag (font) violates step 1, paragraph 3 of the adoption agency algorithm.
+Line: 1 Col: 38 End tag (font) violates step 1, paragraph 3 of the adoption agency algorithm.
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     <font>
+|     <p>
+|       <font>
+|         <b>
+|           "test"
+
+#data
+<!DOCTYPE html><dt><div><dd>
+#errors
+Line: 1 Col: 28 Missing end tag (div, dt).
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     <dt>
+|       <div>
+|     <dd>
+
+#data
+<script></x
+#errors
+Line: 1 Col: 8 Unexpected start tag (script). Expected DOCTYPE.
+Line: 1 Col: 11 Unexpected end of file. Expected end tag (script).
+#document
+| <html>
+|   <head>
+|     <script>
+|       "</x"
+|   <body>
+
+#data
+<table><plaintext><td>
+#errors
+Line: 1 Col: 7 Unexpected start tag (table). Expected DOCTYPE.
+Line: 1 Col: 18 Unexpected start tag (plaintext) in table context caused voodoo mode.
+Line: 1 Col: 22 Unexpected end of file. Expected table content.
+#document
+| <html>
+|   <head>
+|   <body>
+|     <plaintext>
+|       "<td>"
+|     <table>
+
+#data
+<plaintext></plaintext>
+#errors
+Line: 1 Col: 11 Unexpected start tag (plaintext). Expected DOCTYPE.
+Line: 1 Col: 23 Expected closing tag. Unexpected end of file.
+#document
+| <html>
+|   <head>
+|   <body>
+|     <plaintext>
+|       "</plaintext>"
+
+#data
+<!DOCTYPE html><table><tr>TEST
+#errors
+Line: 1 Col: 30 Unexpected non-space characters in table context caused voodoo mode.
+Line: 1 Col: 30 Unexpected end of file. Expected table content.
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     "TEST"
+|     <table>
+|       <tbody>
+|         <tr>
+
+#data
+<!DOCTYPE html><body t1=1><body t2=2><body t3=3 t4=4>
+#errors
+Line: 1 Col: 37 Unexpected start tag (body).
+Line: 1 Col: 53 Unexpected start tag (body).
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     t1="1"
+|     t2="2"
+|     t3="3"
+|     t4="4"
+
+#data
+</b test
+#errors
+Line: 1 Col: 8 Unexpected end of file in attribute name.
+Line: 1 Col: 8 End tag contains unexpected attributes.
+Line: 1 Col: 8 Unexpected end tag (b). Expected DOCTYPE.
+Line: 1 Col: 8 Unexpected end tag (b) after the (implied) root element.
+#document
+| <html>
+|   <head>
+|   <body>
+
+#data
+<!DOCTYPE html></b test<b &=&amp>X
+#errors
+Line: 1 Col: 32 Named entity didn't end with ';'.
+Line: 1 Col: 33 End tag contains unexpected attributes.
+Line: 1 Col: 33 Unexpected end tag (b) after the (implied) root element.
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     "X"
+
+#data
+<!doctypehtml><scrIPt type=text/x-foobar;baz>X</SCRipt
+#errors
+Line: 1 Col: 9 No space after literal string 'DOCTYPE'.
+Line: 1 Col: 54 Unexpected end of file in the tag name.
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|     <script>
+|       type="text/x-foobar;baz"
+|       "X</SCRipt"
+|   <body>
+
+#data
+&
+#errors
+Line: 1 Col: 1 Unexpected non-space characters. Expected DOCTYPE.
+#document
+| <html>
+|   <head>
+|   <body>
+|     "&"
+
+#data
+&#
+#errors
+Line: 1 Col: 1 Numeric entity expected. Got end of file instead.
+Line: 1 Col: 1 Unexpected non-space characters. Expected DOCTYPE.
+#document
+| <html>
+|   <head>
+|   <body>
+|     "&#"
+
+#data
+&#X
+#errors
+Line: 1 Col: 3 Numeric entity expected but none found.
+Line: 1 Col: 3 Unexpected non-space characters. Expected DOCTYPE.
+#document
+| <html>
+|   <head>
+|   <body>
+|     "&#X"
+
+#data
+&#x
+#errors
+Line: 1 Col: 3 Numeric entity expected but none found.
+Line: 1 Col: 3 Unexpected non-space characters. Expected DOCTYPE.
+#document
+| <html>
+|   <head>
+|   <body>
+|     "&#x"
+
+#data
+&#45
+#errors
+Line: 1 Col: 4 Numeric entity didn't end with ';'.
+Line: 1 Col: 4 Unexpected non-space characters. Expected DOCTYPE.
+#document
+| <html>
+|   <head>
+|   <body>
+|     "-"
+
+#data
+&x-test
+#errors
+Line: 1 Col: 1 Named entity expected. Got none.
+Line: 1 Col: 1 Unexpected non-space characters. Expected DOCTYPE.
+#document
+| <html>
+|   <head>
+|   <body>
+|     "&x-test"
+
+#data
+<!doctypehtml><p><li>
+#errors
+Line: 1 Col: 9 No space after literal string 'DOCTYPE'.
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     <p>
+|     <li>
+
+#data
+<!doctypehtml><p><dt>
+#errors
+Line: 1 Col: 9 No space after literal string 'DOCTYPE'.
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     <p>
+|     <dt>
+
+#data
+<!doctypehtml><p><dd>
+#errors
+Line: 1 Col: 9 No space after literal string 'DOCTYPE'.
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     <p>
+|     <dd>
+
+#data
+<!doctypehtml><p><form>
+#errors
+Line: 1 Col: 9 No space after literal string 'DOCTYPE'.
+Line: 1 Col: 23 Expected closing tag. Unexpected end of file.
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     <p>
+|     <form>
+
+#data
+<!DOCTYPE html><p></P>X
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     <p>
+|     "X"
+
+#data
+&AMP
+#errors
+Line: 1 Col: 4 Named entity didn't end with ';'.
+Line: 1 Col: 4 Unexpected non-space characters. Expected DOCTYPE.
+#document
+| <html>
+|   <head>
+|   <body>
+|     "&"
+
+#data
+&AMp;
+#errors
+Line: 1 Col: 1 Named entity expected. Got none.
+Line: 1 Col: 1 Unexpected non-space characters. Expected DOCTYPE.
+#document
+| <html>
+|   <head>
+|   <body>
+|     "&AMp;"
+
+#data
+<!DOCTYPE html><html><head></head><body><thisISasillyTESTelementNameToMakeSureCrazyTagNamesArePARSEDcorrectLY>
+#errors
+Line: 1 Col: 110 Expected closing tag. Unexpected end of file.
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     <thisisasillytestelementnametomakesurecrazytagnamesareparsedcorrectly>
+
+#data
+<!DOCTYPE html>X</body>X
+#errors
+Line: 1 Col: 24 Unexpected non-space characters in the after body phase.
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     "XX"
+
+#data
+<!DOCTYPE html><!-- X
+#errors
+Line: 1 Col: 21 Unexpected end of file in comment.
+#document
+| <!DOCTYPE html>
+| <!--  X -->
+| <html>
+|   <head>
+|   <body>
+
+#data
+<!DOCTYPE html><table><caption>test TEST</caption><td>test
+#errors
+Line: 1 Col: 54 Unexpected table cell start tag (td) in the table body phase.
+Line: 1 Col: 58 Expected closing tag. Unexpected end of file.
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     <table>
+|       <caption>
+|         "test TEST"
+|       <tbody>
+|         <tr>
+|           <td>
+|             "test"
+
+#data
+<!DOCTYPE html><select><option><optgroup>
+#errors
+Line: 1 Col: 41 Expected closing tag. Unexpected end of file.
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     <select>
+|       <option>
+|       <optgroup>
+
+#data
+<!DOCTYPE html><select><optgroup><option></optgroup><option><select><option>
+#errors
+Line: 1 Col: 68 Unexpected select start tag in the select phase treated as select end tag.
+Line: 1 Col: 76 Expected closing tag. Unexpected end of file.
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     <select>
+|       <optgroup>
+|         <option>
+|       <option>
+|     <option>
+
+#data
+<!DOCTYPE html><select><optgroup><option><optgroup>
+#errors
+Line: 1 Col: 51 Expected closing tag. Unexpected end of file.
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     <select>
+|       <optgroup>
+|         <option>
+|       <optgroup>
+
+#data
+<!DOCTYPE html><datalist><option>foo</datalist>bar
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     <datalist>
+|       <option>
+|         "foo"
+|     "bar"
+
+#data
+<!DOCTYPE html><font><input><input></font>
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     <font>
+|       <input>
+|       <input>
+
+#data
+<!DOCTYPE html><!-- XXX - XXX -->
+#errors
+#document
+| <!DOCTYPE html>
+| <!--  XXX - XXX  -->
+| <html>
+|   <head>
+|   <body>
+
+#data
+<!DOCTYPE html><!-- XXX - XXX
+#errors
+Line: 1 Col: 29 Unexpected end of file in comment (-)
+#document
+| <!DOCTYPE html>
+| <!--  XXX - XXX -->
+| <html>
+|   <head>
+|   <body>
+
+#data
+<!DOCTYPE html><!-- XXX - XXX - XXX -->
+#errors
+#document
+| <!DOCTYPE html>
+| <!--  XXX - XXX - XXX  -->
+| <html>
+|   <head>
+|   <body>
+
+#data
+<isindex test=x name=x>
+#errors
+Line: 1 Col: 23 Unexpected start tag (isindex). Expected DOCTYPE.
+Line: 1 Col: 23 Unexpected start tag isindex. Don't use it!
+#document
+| <html>
+|   <head>
+|   <body>
+|     <form>
+|       <hr>
+|       <label>
+|         "This is a searchable index. Enter search keywords: "
+|         <input>
+|           name="isindex"
+|           test="x"
+|       <hr>
+
+#data
+test
+test
+#errors
+Line: 2 Col: 4 Unexpected non-space characters. Expected DOCTYPE.
+#document
+| <html>
+|   <head>
+|   <body>
+|     "test
+test"
+
+#data
+<!DOCTYPE html><body><title>test</body></title>
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     <title>
+|       "test</body>"
+
+#data
+<!DOCTYPE html><body><title>X</title><meta name=z><link rel=foo><style>
+x { content:"</style" } </style>
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     <title>
+|       "X"
+|     <meta>
+|       name="z"
+|     <link>
+|       rel="foo"
+|     <style>
+|       "
+x { content:"</style" } "
+
+#data
+<!DOCTYPE html><select><optgroup></optgroup></select>
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     <select>
+|       <optgroup>
+
+#data
+ 
+ 
+#errors
+Line: 2 Col: 1 Unexpected End of file. Expected DOCTYPE.
+#document
+| <html>
+|   <head>
+|   <body>
+
+#data
+<!DOCTYPE html>  <html>
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+
+#data
+<!DOCTYPE html><script>
+</script>  <title>x</title>  </head>
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|     <script>
+|       "
+"
+|     "  "
+|     <title>
+|       "x"
+|     "  "
+|   <body>
+
+#data
+<!DOCTYPE html><html><body><html id=x>
+#errors
+Line: 1 Col: 38 html needs to be the first start tag.
+#document
+| <!DOCTYPE html>
+| <html>
+|   id="x"
+|   <head>
+|   <body>
+
+#data
+<!DOCTYPE html>X</body><html id="x">
+#errors
+Line: 1 Col: 36 Unexpected start tag token (html) in the after body phase.
+Line: 1 Col: 36 html needs to be the first start tag.
+#document
+| <!DOCTYPE html>
+| <html>
+|   id="x"
+|   <head>
+|   <body>
+|     "X"
+
+#data
+<!DOCTYPE html><head><html id=x>
+#errors
+Line: 1 Col: 32 html needs to be the first start tag.
+#document
+| <!DOCTYPE html>
+| <html>
+|   id="x"
+|   <head>
+|   <body>
+
+#data
+<!DOCTYPE html>X</html>X
+#errors
+Line: 1 Col: 24 Unexpected non-space characters in the after body phase.
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     "XX"
+
+#data
+<!DOCTYPE html>X</html> 
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     "X "
+
+#data
+<!DOCTYPE html>X</html><p>X
+#errors
+Line: 1 Col: 26 Unexpected start tag (p).
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     "X"
+|     <p>
+|       "X"
+
+#data
+<!DOCTYPE html>X<p/x/y/z>
+#errors
+Line: 1 Col: 19 Expected a > after the /.
+Line: 1 Col: 21 Solidus (/) incorrectly placed in tag.
+Line: 1 Col: 23 Solidus (/) incorrectly placed in tag.
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     "X"
+|     <p>
+|       x=""
+|       y=""
+|       z=""
+
+#data
+<!DOCTYPE html><!--x--
+#errors
+Line: 1 Col: 22 Unexpected end of file in comment (--).
+#document
+| <!DOCTYPE html>
+| <!-- x -->
+| <html>
+|   <head>
+|   <body>
+
+#data
+<!DOCTYPE html><table><tr><td></p></table>
+#errors
+Line: 1 Col: 34 Unexpected end tag (p). Ignored.
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     <table>
+|       <tbody>
+|         <tr>
+|           <td>
+|             <p>
+
+#data
+<!DOCTYPE <!DOCTYPE HTML>><!--<!--x-->-->
+#errors
+Line: 1 Col: 20 Expected space or '>'. Got ''
+Line: 1 Col: 25 Erroneous DOCTYPE.
+Line: 1 Col: 35 Unexpected character in comment found.
+#document
+| <!DOCTYPE <!doctype>
+| <html>
+|   <head>
+|   <body>
+|     ">"
+|     <!-- <!--x -->
+|     "-->"
+
+#data
+<!doctype html><div><form></form><div></div></div>
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     <div>
+|       <form>
+|       <div>
diff --git a/html/test/data/tree-construction/tests20.dat b/html/test/data/tree-construction/tests20.dat
new file mode 100644
index 0000000..6bd8256
--- /dev/null
+++ b/html/test/data/tree-construction/tests20.dat
@@ -0,0 +1,455 @@
+#data
+<!doctype html><p><button><button>
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     <p>
+|       <button>
+|       <button>
+
+#data
+<!doctype html><p><button><address>
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     <p>
+|       <button>
+|         <address>
+
+#data
+<!doctype html><p><button><blockquote>
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     <p>
+|       <button>
+|         <blockquote>
+
+#data
+<!doctype html><p><button><menu>
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     <p>
+|       <button>
+|         <menu>
+
+#data
+<!doctype html><p><button><p>
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     <p>
+|       <button>
+|         <p>
+
+#data
+<!doctype html><p><button><ul>
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     <p>
+|       <button>
+|         <ul>
+
+#data
+<!doctype html><p><button><h1>
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     <p>
+|       <button>
+|         <h1>
+
+#data
+<!doctype html><p><button><h6>
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     <p>
+|       <button>
+|         <h6>
+
+#data
+<!doctype html><p><button><listing>
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     <p>
+|       <button>
+|         <listing>
+
+#data
+<!doctype html><p><button><pre>
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     <p>
+|       <button>
+|         <pre>
+
+#data
+<!doctype html><p><button><form>
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     <p>
+|       <button>
+|         <form>
+
+#data
+<!doctype html><p><button><li>
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     <p>
+|       <button>
+|         <li>
+
+#data
+<!doctype html><p><button><dd>
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     <p>
+|       <button>
+|         <dd>
+
+#data
+<!doctype html><p><button><dt>
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     <p>
+|       <button>
+|         <dt>
+
+#data
+<!doctype html><p><button><plaintext>
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     <p>
+|       <button>
+|         <plaintext>
+
+#data
+<!doctype html><p><button><table>
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     <p>
+|       <button>
+|         <table>
+
+#data
+<!doctype html><p><button><hr>
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     <p>
+|       <button>
+|         <hr>
+
+#data
+<!doctype html><p><button><xmp>
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     <p>
+|       <button>
+|         <xmp>
+
+#data
+<!doctype html><p><button></p>
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     <p>
+|       <button>
+|         <p>
+
+#data
+<!doctype html><address><button></address>a
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     <address>
+|       <button>
+|     "a"
+
+#data
+<!doctype html><address><button></address>a
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     <address>
+|       <button>
+|     "a"
+
+#data
+<p><table></p>
+#errors
+#document
+| <html>
+|   <head>
+|   <body>
+|     <p>
+|       <p>
+|       <table>
+
+#data
+<!doctype html><svg>
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     <svg svg>
+
+#data
+<!doctype html><p><figcaption>
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     <p>
+|     <figcaption>
+
+#data
+<!doctype html><p><summary>
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     <p>
+|     <summary>
+
+#data
+<!doctype html><form><table><form>
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     <form>
+|       <table>
+
+#data
+<!doctype html><table><form><form>
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     <table>
+|       <form>
+
+#data
+<!doctype html><table><form></table><form>
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     <table>
+|       <form>
+
+#data
+<!doctype html><svg><foreignObject><p>
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     <svg svg>
+|       <svg foreignObject>
+|         <p>
+
+#data
+<!doctype html><svg><title>abc
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     <svg svg>
+|       <svg title>
+|         "abc"
+
+#data
+<option><span><option>
+#errors
+#document
+| <html>
+|   <head>
+|   <body>
+|     <option>
+|       <span>
+|         <option>
+
+#data
+<option><option>
+#errors
+#document
+| <html>
+|   <head>
+|   <body>
+|     <option>
+|     <option>
+
+#data
+<math><annotation-xml><div>
+#errors
+#document
+| <html>
+|   <head>
+|   <body>
+|     <math math>
+|       <math annotation-xml>
+|     <div>
+
+#data
+<math><annotation-xml encoding="application/svg+xml"><div>
+#errors
+#document
+| <html>
+|   <head>
+|   <body>
+|     <math math>
+|       <math annotation-xml>
+|         encoding="application/svg+xml"
+|     <div>
+
+#data
+<math><annotation-xml encoding="application/xhtml+xml"><div>
+#errors
+#document
+| <html>
+|   <head>
+|   <body>
+|     <math math>
+|       <math annotation-xml>
+|         encoding="application/xhtml+xml"
+|         <div>
+
+#data
+<math><annotation-xml encoding="aPPlication/xhtmL+xMl"><div>
+#errors
+#document
+| <html>
+|   <head>
+|   <body>
+|     <math math>
+|       <math annotation-xml>
+|         encoding="aPPlication/xhtmL+xMl"
+|         <div>
+
+#data
+<math><annotation-xml encoding="text/html"><div>
+#errors
+#document
+| <html>
+|   <head>
+|   <body>
+|     <math math>
+|       <math annotation-xml>
+|         encoding="text/html"
+|         <div>
+
+#data
+<math><annotation-xml encoding="Text/htmL"><div>
+#errors
+#document
+| <html>
+|   <head>
+|   <body>
+|     <math math>
+|       <math annotation-xml>
+|         encoding="Text/htmL"
+|         <div>
+
+#data
+<math><annotation-xml encoding=" text/html "><div>
+#errors
+#document
+| <html>
+|   <head>
+|   <body>
+|     <math math>
+|       <math annotation-xml>
+|         encoding=" text/html "
+|     <div>
diff --git a/html/test/data/tree-construction/tests21.dat b/html/test/data/tree-construction/tests21.dat
new file mode 100644
index 0000000..1260ec0
--- /dev/null
+++ b/html/test/data/tree-construction/tests21.dat
@@ -0,0 +1,221 @@
+#data
+<svg><![CDATA[foo]]>
+#errors
+#document
+| <html>
+|   <head>
+|   <body>
+|     <svg svg>
+|       "foo"
+
+#data
+<math><![CDATA[foo]]>
+#errors
+#document
+| <html>
+|   <head>
+|   <body>
+|     <math math>
+|       "foo"
+
+#data
+<div><![CDATA[foo]]>
+#errors
+#document
+| <html>
+|   <head>
+|   <body>
+|     <div>
+|       <!-- [CDATA[foo]] -->
+
+#data
+<svg><![CDATA[foo
+#errors
+#document
+| <html>
+|   <head>
+|   <body>
+|     <svg svg>
+|       "foo"
+
+#data
+<svg><![CDATA[foo
+#errors
+#document
+| <html>
+|   <head>
+|   <body>
+|     <svg svg>
+|       "foo"
+
+#data
+<svg><![CDATA[
+#errors
+#document
+| <html>
+|   <head>
+|   <body>
+|     <svg svg>
+
+#data
+<svg><![CDATA[]]>
+#errors
+#document
+| <html>
+|   <head>
+|   <body>
+|     <svg svg>
+
+#data
+<svg><![CDATA[]] >]]>
+#errors
+#document
+| <html>
+|   <head>
+|   <body>
+|     <svg svg>
+|       "]] >"
+
+#data
+<svg><![CDATA[]] >]]>
+#errors
+#document
+| <html>
+|   <head>
+|   <body>
+|     <svg svg>
+|       "]] >"
+
+#data
+<svg><![CDATA[]]
+#errors
+#document
+| <html>
+|   <head>
+|   <body>
+|     <svg svg>
+|       "]]"
+
+#data
+<svg><![CDATA[]
+#errors
+#document
+| <html>
+|   <head>
+|   <body>
+|     <svg svg>
+|       "]"
+
+#data
+<svg><![CDATA[]>a
+#errors
+#document
+| <html>
+|   <head>
+|   <body>
+|     <svg svg>
+|       "]>a"
+
+#data
+<svg><foreignObject><div><![CDATA[foo]]>
+#errors
+#document
+| <html>
+|   <head>
+|   <body>
+|     <svg svg>
+|       <svg foreignObject>
+|         <div>
+|           <!-- [CDATA[foo]] -->
+
+#data
+<svg><![CDATA[<svg>]]>
+#errors
+#document
+| <html>
+|   <head>
+|   <body>
+|     <svg svg>
+|       "<svg>"
+
+#data
+<svg><![CDATA[</svg>a]]>
+#errors
+#document
+| <html>
+|   <head>
+|   <body>
+|     <svg svg>
+|       "</svg>a"
+
+#data
+<svg><![CDATA[<svg>a
+#errors
+#document
+| <html>
+|   <head>
+|   <body>
+|     <svg svg>
+|       "<svg>a"
+
+#data
+<svg><![CDATA[</svg>a
+#errors
+#document
+| <html>
+|   <head>
+|   <body>
+|     <svg svg>
+|       "</svg>a"
+
+#data
+<svg><![CDATA[<svg>]]><path>
+#errors
+#document
+| <html>
+|   <head>
+|   <body>
+|     <svg svg>
+|       "<svg>"
+|       <svg path>
+
+#data
+<svg><![CDATA[<svg>]]></path>
+#errors
+#document
+| <html>
+|   <head>
+|   <body>
+|     <svg svg>
+|       "<svg>"
+
+#data
+<svg><![CDATA[<svg>]]><!--path-->
+#errors
+#document
+| <html>
+|   <head>
+|   <body>
+|     <svg svg>
+|       "<svg>"
+|       <!-- path -->
+
+#data
+<svg><![CDATA[<svg>]]>path
+#errors
+#document
+| <html>
+|   <head>
+|   <body>
+|     <svg svg>
+|       "<svg>path"
+
+#data
+<svg><![CDATA[<!--svg-->]]>
+#errors
+#document
+| <html>
+|   <head>
+|   <body>
+|     <svg svg>
+|       "<!--svg-->"
diff --git a/html/test/data/tree-construction/tests22.dat b/html/test/data/tree-construction/tests22.dat
new file mode 100644
index 0000000..aab27b2
--- /dev/null
+++ b/html/test/data/tree-construction/tests22.dat
@@ -0,0 +1,157 @@
+#data
+<a><b><big><em><strong><div>X</a>
+#errors
+#document
+| <html>
+|   <head>
+|   <body>
+|     <a>
+|       <b>
+|         <big>
+|           <em>
+|             <strong>
+|     <big>
+|       <em>
+|         <strong>
+|           <div>
+|             <a>
+|               "X"
+
+#data
+<a><b><div id=1><div id=2><div id=3><div id=4><div id=5><div id=6><div id=7><div id=8>A</a>
+#errors
+#document
+| <html>
+|   <head>
+|   <body>
+|     <a>
+|       <b>
+|     <b>
+|       <div>
+|         id="1"
+|         <a>
+|         <div>
+|           id="2"
+|           <a>
+|           <div>
+|             id="3"
+|             <a>
+|             <div>
+|               id="4"
+|               <a>
+|               <div>
+|                 id="5"
+|                 <a>
+|                 <div>
+|                   id="6"
+|                   <a>
+|                   <div>
+|                     id="7"
+|                     <a>
+|                     <div>
+|                       id="8"
+|                       <a>
+|                         "A"
+
+#data
+<a><b><div id=1><div id=2><div id=3><div id=4><div id=5><div id=6><div id=7><div id=8><div id=9>A</a>
+#errors
+#document
+| <html>
+|   <head>
+|   <body>
+|     <a>
+|       <b>
+|     <b>
+|       <div>
+|         id="1"
+|         <a>
+|         <div>
+|           id="2"
+|           <a>
+|           <div>
+|             id="3"
+|             <a>
+|             <div>
+|               id="4"
+|               <a>
+|               <div>
+|                 id="5"
+|                 <a>
+|                 <div>
+|                   id="6"
+|                   <a>
+|                   <div>
+|                     id="7"
+|                     <a>
+|                     <div>
+|                       id="8"
+|                       <a>
+|                         <div>
+|                           id="9"
+|                           "A"
+
+#data
+<a><b><div id=1><div id=2><div id=3><div id=4><div id=5><div id=6><div id=7><div id=8><div id=9><div id=10>A</a>
+#errors
+#document
+| <html>
+|   <head>
+|   <body>
+|     <a>
+|       <b>
+|     <b>
+|       <div>
+|         id="1"
+|         <a>
+|         <div>
+|           id="2"
+|           <a>
+|           <div>
+|             id="3"
+|             <a>
+|             <div>
+|               id="4"
+|               <a>
+|               <div>
+|                 id="5"
+|                 <a>
+|                 <div>
+|                   id="6"
+|                   <a>
+|                   <div>
+|                     id="7"
+|                     <a>
+|                     <div>
+|                       id="8"
+|                       <a>
+|                         <div>
+|                           id="9"
+|                           <div>
+|                             id="10"
+|                             "A"
+
+#data
+<cite><b><cite><i><cite><i><cite><i><div>X</b>TEST
+#errors
+Line: 1 Col: 6 Unexpected start tag (cite). Expected DOCTYPE.
+Line: 1 Col: 46 End tag (b) violates step 1, paragraph 3 of the adoption agency algorithm.
+Line: 1 Col: 50 Expected closing tag. Unexpected end of file.
+#document
+| <html>
+|   <head>
+|   <body>
+|     <cite>
+|       <b>
+|         <cite>
+|           <i>
+|             <cite>
+|               <i>
+|                 <cite>
+|                   <i>
+|       <i>
+|         <i>
+|           <div>
+|             <b>
+|               "X"
+|             "TEST"
diff --git a/html/test/data/tree-construction/tests23.dat b/html/test/data/tree-construction/tests23.dat
new file mode 100644
index 0000000..34d2a73
--- /dev/null
+++ b/html/test/data/tree-construction/tests23.dat
@@ -0,0 +1,155 @@
+#data
+<p><font size=4><font color=red><font size=4><font size=4><font size=4><font size=4><font size=4><font color=red><p>X
+#errors
+3: Start tag seen without seeing a doctype first. Expected “<!DOCTYPE html>”.
+116: Unclosed elements.
+117: End of file seen and there were open elements.
+#document
+| <html>
+|   <head>
+|   <body>
+|     <p>
+|       <font>
+|         size="4"
+|         <font>
+|           color="red"
+|           <font>
+|             size="4"
+|             <font>
+|               size="4"
+|               <font>
+|                 size="4"
+|                 <font>
+|                   size="4"
+|                   <font>
+|                     size="4"
+|                     <font>
+|                       color="red"
+|     <p>
+|       <font>
+|         color="red"
+|         <font>
+|           size="4"
+|           <font>
+|             size="4"
+|             <font>
+|               size="4"
+|               <font>
+|                 color="red"
+|                 "X"
+
+#data
+<p><font size=4><font size=4><font size=4><font size=4><p>X
+#errors
+#document
+| <html>
+|   <head>
+|   <body>
+|     <p>
+|       <font>
+|         size="4"
+|         <font>
+|           size="4"
+|           <font>
+|             size="4"
+|             <font>
+|               size="4"
+|     <p>
+|       <font>
+|         size="4"
+|         <font>
+|           size="4"
+|           <font>
+|             size="4"
+|             "X"
+
+#data
+<p><font size=4><font size=4><font size=4><font size="5"><font size=4><p>X
+#errors
+#document
+| <html>
+|   <head>
+|   <body>
+|     <p>
+|       <font>
+|         size="4"
+|         <font>
+|           size="4"
+|           <font>
+|             size="4"
+|             <font>
+|               size="5"
+|               <font>
+|                 size="4"
+|     <p>
+|       <font>
+|         size="4"
+|         <font>
+|           size="4"
+|           <font>
+|             size="5"
+|             <font>
+|               size="4"
+|               "X"
+
+#data
+<p><font size=4 id=a><font size=4 id=b><font size=4><font size=4><p>X
+#errors
+#document
+| <html>
+|   <head>
+|   <body>
+|     <p>
+|       <font>
+|         id="a"
+|         size="4"
+|         <font>
+|           id="b"
+|           size="4"
+|           <font>
+|             size="4"
+|             <font>
+|               size="4"
+|     <p>
+|       <font>
+|         id="a"
+|         size="4"
+|         <font>
+|           id="b"
+|           size="4"
+|           <font>
+|             size="4"
+|             <font>
+|               size="4"
+|               "X"
+
+#data
+<p><b id=a><b id=a><b id=a><b><object><b id=a><b id=a>X</object><p>Y
+#errors
+#document
+| <html>
+|   <head>
+|   <body>
+|     <p>
+|       <b>
+|         id="a"
+|         <b>
+|           id="a"
+|           <b>
+|             id="a"
+|             <b>
+|               <object>
+|                 <b>
+|                   id="a"
+|                   <b>
+|                     id="a"
+|                     "X"
+|     <p>
+|       <b>
+|         id="a"
+|         <b>
+|           id="a"
+|           <b>
+|             id="a"
+|             <b>
+|               "Y"
diff --git a/html/test/data/tree-construction/tests24.dat b/html/test/data/tree-construction/tests24.dat
new file mode 100644
index 0000000..f6dc7eb
--- /dev/null
+++ b/html/test/data/tree-construction/tests24.dat
@@ -0,0 +1,79 @@
+#data
+<!DOCTYPE html>&NotEqualTilde;
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     "≂̸"
+
+#data
+<!DOCTYPE html>&NotEqualTilde;A
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     "≂̸A"
+
+#data
+<!DOCTYPE html>&ThickSpace;
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     "  "
+
+#data
+<!DOCTYPE html>&ThickSpace;A
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     "  A"
+
+#data
+<!DOCTYPE html>&NotSubset;
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     "⊂⃒"
+
+#data
+<!DOCTYPE html>&NotSubset;A
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     "⊂⃒A"
+
+#data
+<!DOCTYPE html>&Gopf;
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     "𝔾"
+
+#data
+<!DOCTYPE html>&Gopf;A
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     "𝔾A"
diff --git a/html/test/data/tree-construction/tests25.dat b/html/test/data/tree-construction/tests25.dat
new file mode 100644
index 0000000..00de729
--- /dev/null
+++ b/html/test/data/tree-construction/tests25.dat
@@ -0,0 +1,219 @@
+#data
+<!DOCTYPE html><body><foo>A
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     <foo>
+|       "A"
+
+#data
+<!DOCTYPE html><body><area>A
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     <area>
+|     "A"
+
+#data
+<!DOCTYPE html><body><base>A
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     <base>
+|     "A"
+
+#data
+<!DOCTYPE html><body><basefont>A
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     <basefont>
+|     "A"
+
+#data
+<!DOCTYPE html><body><bgsound>A
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     <bgsound>
+|     "A"
+
+#data
+<!DOCTYPE html><body><br>A
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     <br>
+|     "A"
+
+#data
+<!DOCTYPE html><body><col>A
+#errors
+26: Stray start tag “col”.
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     "A"
+
+#data
+<!DOCTYPE html><body><command>A
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     <command>
+|     "A"
+
+#data
+<!DOCTYPE html><body><embed>A
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     <embed>
+|     "A"
+
+#data
+<!DOCTYPE html><body><frame>A
+#errors
+26: Stray start tag “frame”.
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     "A"
+
+#data
+<!DOCTYPE html><body><hr>A
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     <hr>
+|     "A"
+
+#data
+<!DOCTYPE html><body><img>A
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     <img>
+|     "A"
+
+#data
+<!DOCTYPE html><body><input>A
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     <input>
+|     "A"
+
+#data
+<!DOCTYPE html><body><keygen>A
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     <keygen>
+|     "A"
+
+#data
+<!DOCTYPE html><body><link>A
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     <link>
+|     "A"
+
+#data
+<!DOCTYPE html><body><meta>A
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     <meta>
+|     "A"
+
+#data
+<!DOCTYPE html><body><param>A
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     <param>
+|     "A"
+
+#data
+<!DOCTYPE html><body><source>A
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     <source>
+|     "A"
+
+#data
+<!DOCTYPE html><body><track>A
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     <track>
+|     "A"
+
+#data
+<!DOCTYPE html><body><wbr>A
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     <wbr>
+|     "A"
diff --git a/html/test/data/tree-construction/tests26.dat b/html/test/data/tree-construction/tests26.dat
new file mode 100644
index 0000000..fae11ff
--- /dev/null
+++ b/html/test/data/tree-construction/tests26.dat
@@ -0,0 +1,313 @@
+#data
+<!DOCTYPE html><body><a href='#1'><nobr>1<nobr></a><br><a href='#2'><nobr>2<nobr></a><br><a href='#3'><nobr>3<nobr></a>
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     <a>
+|       href="#1"
+|       <nobr>
+|         "1"
+|       <nobr>
+|     <nobr>
+|       <br>
+|       <a>
+|         href="#2"
+|     <a>
+|       href="#2"
+|       <nobr>
+|         "2"
+|       <nobr>
+|     <nobr>
+|       <br>
+|       <a>
+|         href="#3"
+|     <a>
+|       href="#3"
+|       <nobr>
+|         "3"
+|       <nobr>
+
+#data
+<!DOCTYPE html><body><b><nobr>1<nobr></b><i><nobr>2<nobr></i>3
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     <b>
+|       <nobr>
+|         "1"
+|       <nobr>
+|     <nobr>
+|       <i>
+|     <i>
+|       <nobr>
+|         "2"
+|       <nobr>
+|     <nobr>
+|       "3"
+
+#data
+<!DOCTYPE html><body><b><nobr>1<table><nobr></b><i><nobr>2<nobr></i>3
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     <b>
+|       <nobr>
+|         "1"
+|         <nobr>
+|           <i>
+|         <i>
+|           <nobr>
+|             "2"
+|           <nobr>
+|         <nobr>
+|           "3"
+|         <table>
+
+#data
+<!DOCTYPE html><body><b><nobr>1<table><tr><td><nobr></b><i><nobr>2<nobr></i>3
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     <b>
+|       <nobr>
+|         "1"
+|         <table>
+|           <tbody>
+|             <tr>
+|               <td>
+|                 <nobr>
+|                   <i>
+|                 <i>
+|                   <nobr>
+|                     "2"
+|                   <nobr>
+|                 <nobr>
+|                   "3"
+
+#data
+<!DOCTYPE html><body><b><nobr>1<div><nobr></b><i><nobr>2<nobr></i>3
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     <b>
+|       <nobr>
+|         "1"
+|     <div>
+|       <b>
+|         <nobr>
+|         <nobr>
+|       <nobr>
+|         <i>
+|       <i>
+|         <nobr>
+|           "2"
+|         <nobr>
+|       <nobr>
+|         "3"
+
+#data
+<!DOCTYPE html><body><b><nobr>1<nobr></b><div><i><nobr>2<nobr></i>3
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     <b>
+|       <nobr>
+|         "1"
+|       <nobr>
+|     <div>
+|       <nobr>
+|         <i>
+|       <i>
+|         <nobr>
+|           "2"
+|         <nobr>
+|       <nobr>
+|         "3"
+
+#data
+<!DOCTYPE html><body><b><nobr>1<nobr><ins></b><i><nobr>
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     <b>
+|       <nobr>
+|         "1"
+|       <nobr>
+|         <ins>
+|     <nobr>
+|       <i>
+|     <i>
+|       <nobr>
+
+#data
+<!DOCTYPE html><body><b><nobr>1<ins><nobr></b><i>2
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     <b>
+|       <nobr>
+|         "1"
+|         <ins>
+|       <nobr>
+|     <nobr>
+|       <i>
+|         "2"
+
+#data
+<!DOCTYPE html><body><b>1<nobr></b><i><nobr>2</i>
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     <b>
+|       "1"
+|       <nobr>
+|     <nobr>
+|       <i>
+|     <i>
+|       <nobr>
+|         "2"
+
+#data
+<p><code x</code></p>
+
+#errors
+#document
+| <html>
+|   <head>
+|   <body>
+|     <p>
+|       <code>
+|         code=""
+|         x<=""
+|     <code>
+|       code=""
+|       x<=""
+|       "
+"
+
+#data
+<!DOCTYPE html><svg><foreignObject><p><i></p>a
+#errors
+45: End tag “p” seen, but there were open elements.
+41: Unclosed element “i”.
+46: End of file seen and there were open elements.
+35: Unclosed element “foreignObject”.
+20: Unclosed element “svg”.
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     <svg svg>
+|       <svg foreignObject>
+|         <p>
+|           <i>
+|         <i>
+|           "a"
+
+#data
+<!DOCTYPE html><table><tr><td><svg><foreignObject><p><i></p>a
+#errors
+56: End tag “p” seen, but there were open elements.
+52: Unclosed element “i”.
+57: End of file seen and there were open elements.
+46: Unclosed element “foreignObject”.
+31: Unclosed element “svg”.
+22: Unclosed element “table”.
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     <table>
+|       <tbody>
+|         <tr>
+|           <td>
+|             <svg svg>
+|               <svg foreignObject>
+|                 <p>
+|                   <i>
+|                 <i>
+|                   "a"
+
+#data
+<!DOCTYPE html><math><mtext><p><i></p>a
+#errors
+38: End tag “p” seen, but there were open elements.
+34: Unclosed element “i”.
+39: End of file in a foreign namespace context.
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     <math math>
+|       <math mtext>
+|         <p>
+|           <i>
+|         <i>
+|           "a"
+
+#data
+<!DOCTYPE html><table><tr><td><math><mtext><p><i></p>a
+#errors
+53: End tag “p” seen, but there were open elements.
+49: Unclosed element “i”.
+54: End of file in a foreign namespace context.
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     <table>
+|       <tbody>
+|         <tr>
+|           <td>
+|             <math math>
+|               <math mtext>
+|                 <p>
+|                   <i>
+|                 <i>
+|                   "a"
+
+#data
+<!DOCTYPE html><body><div><!/div>a
+#errors
+29: Bogus comment.
+34: End of file seen and there were open elements.
+26: Unclosed element “div”.
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     <div>
+|       <!-- /div -->
+|       "a"
diff --git a/html/test/data/tree-construction/tests3.dat b/html/test/data/tree-construction/tests3.dat
new file mode 100644
index 0000000..38dc501
--- /dev/null
+++ b/html/test/data/tree-construction/tests3.dat
@@ -0,0 +1,305 @@
+#data
+<head></head><style></style>
+#errors
+Line: 1 Col: 6 Unexpected start tag (head). Expected DOCTYPE.
+Line: 1 Col: 20 Unexpected start tag (style) that can be in head. Moved.
+#document
+| <html>
+|   <head>
+|     <style>
+|   <body>
+
+#data
+<head></head><script></script>
+#errors
+Line: 1 Col: 6 Unexpected start tag (head). Expected DOCTYPE.
+Line: 1 Col: 21 Unexpected start tag (script) that can be in head. Moved.
+#document
+| <html>
+|   <head>
+|     <script>
+|   <body>
+
+#data
+<head></head><!-- --><style></style><!-- --><script></script>
+#errors
+Line: 1 Col: 6 Unexpected start tag (head). Expected DOCTYPE.
+Line: 1 Col: 28 Unexpected start tag (style) that can be in head. Moved.
+#document
+| <html>
+|   <head>
+|     <style>
+|     <script>
+|   <!--   -->
+|   <!--   -->
+|   <body>
+
+#data
+<head></head><!-- -->x<style></style><!-- --><script></script>
+#errors
+Line: 1 Col: 6 Unexpected start tag (head). Expected DOCTYPE.
+#document
+| <html>
+|   <head>
+|   <!--   -->
+|   <body>
+|     "x"
+|     <style>
+|     <!--   -->
+|     <script>
+
+#data
+<!DOCTYPE html><html><head></head><body><pre>
+</pre></body></html>
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     <pre>
+
+#data
+<!DOCTYPE html><html><head></head><body><pre>
+foo</pre></body></html>
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     <pre>
+|       "foo"
+
+#data
+<!DOCTYPE html><html><head></head><body><pre>
+
+foo</pre></body></html>
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     <pre>
+|       "
+foo"
+
+#data
+<!DOCTYPE html><html><head></head><body><pre>
+foo
+</pre></body></html>
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     <pre>
+|       "foo
+"
+
+#data
+<!DOCTYPE html><html><head></head><body><pre>x</pre><span>
+</span></body></html>
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     <pre>
+|       "x"
+|     <span>
+|       "
+"
+
+#data
+<!DOCTYPE html><html><head></head><body><pre>x
+y</pre></body></html>
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     <pre>
+|       "x
+y"
+
+#data
+<!DOCTYPE html><html><head></head><body><pre>x<div>
+y</pre></body></html>
+#errors
+Line: 2 Col: 7 End tag (pre) seen too early. Expected other end tag.
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     <pre>
+|       "x"
+|       <div>
+|         "
+y"
+
+#data
+<!DOCTYPE html><pre>&#x0a;&#x0a;A</pre>
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     <pre>
+|       "
+A"
+
+#data
+<!DOCTYPE html><HTML><META><HEAD></HEAD></HTML>
+#errors
+Line: 1 Col: 33 Unexpected start tag head in existing head. Ignored.
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|     <meta>
+|   <body>
+
+#data
+<!DOCTYPE html><HTML><HEAD><head></HEAD></HTML>
+#errors
+Line: 1 Col: 33 Unexpected start tag head in existing head. Ignored.
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+
+#data
+<textarea>foo<span>bar</span><i>baz
+#errors
+Line: 1 Col: 10 Unexpected start tag (textarea). Expected DOCTYPE.
+Line: 1 Col: 35 Expected closing tag. Unexpected end of file.
+#document
+| <html>
+|   <head>
+|   <body>
+|     <textarea>
+|       "foo<span>bar</span><i>baz"
+
+#data
+<title>foo<span>bar</em><i>baz
+#errors
+Line: 1 Col: 7 Unexpected start tag (title). Expected DOCTYPE.
+Line: 1 Col: 30 Unexpected end of file. Expected end tag (title).
+#document
+| <html>
+|   <head>
+|     <title>
+|       "foo<span>bar</em><i>baz"
+|   <body>
+
+#data
+<!DOCTYPE html><textarea>
+</textarea>
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     <textarea>
+
+#data
+<!DOCTYPE html><textarea>
+foo</textarea>
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     <textarea>
+|       "foo"
+
+#data
+<!DOCTYPE html><textarea>
+
+foo</textarea>
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     <textarea>
+|       "
+foo"
+
+#data
+<!DOCTYPE html><html><head></head><body><ul><li><div><p><li></ul></body></html>
+#errors
+Line: 1 Col: 60 Missing end tag (div, li).
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     <ul>
+|       <li>
+|         <div>
+|           <p>
+|       <li>
+
+#data
+<!doctype html><nobr><nobr><nobr>
+#errors
+Line: 1 Col: 27 Unexpected start tag (nobr) implies end tag (nobr).
+Line: 1 Col: 33 Unexpected start tag (nobr) implies end tag (nobr).
+Line: 1 Col: 33 Expected closing tag. Unexpected end of file.
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     <nobr>
+|     <nobr>
+|     <nobr>
+
+#data
+<!doctype html><nobr><nobr></nobr><nobr>
+#errors
+Line: 1 Col: 27 Unexpected start tag (nobr) implies end tag (nobr).
+Line: 1 Col: 40 Expected closing tag. Unexpected end of file.
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     <nobr>
+|     <nobr>
+|     <nobr>
+
+#data
+<!doctype html><html><body><p><table></table></body></html>
+#errors
+Not known
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     <p>
+|     <table>
+
+#data
+<p><table></table>
+#errors
+Not known
+#document
+| <html>
+|   <head>
+|   <body>
+|     <p>
+|       <table>
diff --git a/html/test/data/tree-construction/tests4.dat b/html/test/data/tree-construction/tests4.dat
new file mode 100644
index 0000000..3c50632
--- /dev/null
+++ b/html/test/data/tree-construction/tests4.dat
@@ -0,0 +1,59 @@
+#data
+direct div content
+#errors
+#document-fragment
+div
+#document
+| "direct div content"
+
+#data
+direct textarea content
+#errors
+#document-fragment
+textarea
+#document
+| "direct textarea content"
+
+#data
+textarea content with <em>pseudo</em> <foo>markup
+#errors
+#document-fragment
+textarea
+#document
+| "textarea content with <em>pseudo</em> <foo>markup"
+
+#data
+this is &#x0043;DATA inside a <style> element
+#errors
+#document-fragment
+style
+#document
+| "this is &#x0043;DATA inside a <style> element"
+
+#data
+</plaintext>
+#errors
+#document-fragment
+plaintext
+#document
+| "</plaintext>"
+
+#data
+setting html's innerHTML
+#errors
+Line: 1 Col: 24 Unexpected EOF in inner html mode.
+#document-fragment
+html
+#document
+| <head>
+| <body>
+|   "setting html's innerHTML"
+
+#data
+<title>setting head's innerHTML</title>
+#errors
+#document-fragment
+head
+#document
+| <title>
+|   "setting head's innerHTML"
diff --git a/html/test/data/tree-construction/tests5.dat b/html/test/data/tree-construction/tests5.dat
new file mode 100644
index 0000000..d7b5128
--- /dev/null
+++ b/html/test/data/tree-construction/tests5.dat
@@ -0,0 +1,191 @@
+#data
+<style> <!-- </style>x
+#errors
+Line: 1 Col: 7 Unexpected start tag (style). Expected DOCTYPE.
+Line: 1 Col: 22 Unexpected end of file. Expected end tag (style).
+#document
+| <html>
+|   <head>
+|     <style>
+|       " <!-- "
+|   <body>
+|     "x"
+
+#data
+<style> <!-- </style> --> </style>x
+#errors
+Line: 1 Col: 7 Unexpected start tag (style). Expected DOCTYPE.
+#document
+| <html>
+|   <head>
+|     <style>
+|       " <!-- "
+|     " "
+|   <body>
+|     "--> x"
+
+#data
+<style> <!--> </style>x
+#errors
+Line: 1 Col: 7 Unexpected start tag (style). Expected DOCTYPE.
+#document
+| <html>
+|   <head>
+|     <style>
+|       " <!--> "
+|   <body>
+|     "x"
+
+#data
+<style> <!---> </style>x
+#errors
+Line: 1 Col: 7 Unexpected start tag (style). Expected DOCTYPE.
+#document
+| <html>
+|   <head>
+|     <style>
+|       " <!---> "
+|   <body>
+|     "x"
+
+#data
+<iframe> <!---> </iframe>x
+#errors
+Line: 1 Col: 8 Unexpected start tag (iframe). Expected DOCTYPE.
+#document
+| <html>
+|   <head>
+|   <body>
+|     <iframe>
+|       " <!---> "
+|     "x"
+
+#data
+<iframe> <!--- </iframe>->x</iframe> --> </iframe>x
+#errors
+Line: 1 Col: 8 Unexpected start tag (iframe). Expected DOCTYPE.
+#document
+| <html>
+|   <head>
+|   <body>
+|     <iframe>
+|       " <!--- "
+|     "->x --> x"
+
+#data
+<script> <!-- </script> --> </script>x
+#errors
+Line: 1 Col: 8 Unexpected start tag (script). Expected DOCTYPE.
+#document
+| <html>
+|   <head>
+|     <script>
+|       " <!-- "
+|     " "
+|   <body>
+|     "--> x"
+
+#data
+<title> <!-- </title> --> </title>x
+#errors
+Line: 1 Col: 7 Unexpected start tag (title). Expected DOCTYPE.
+#document
+| <html>
+|   <head>
+|     <title>
+|       " <!-- "
+|     " "
+|   <body>
+|     "--> x"
+
+#data
+<textarea> <!--- </textarea>->x</textarea> --> </textarea>x
+#errors
+Line: 1 Col: 10 Unexpected start tag (textarea). Expected DOCTYPE.
+#document
+| <html>
+|   <head>
+|   <body>
+|     <textarea>
+|       " <!--- "
+|     "->x --> x"
+
+#data
+<style> <!</-- </style>x
+#errors
+Line: 1 Col: 7 Unexpected start tag (style). Expected DOCTYPE.
+#document
+| <html>
+|   <head>
+|     <style>
+|       " <!</-- "
+|   <body>
+|     "x"
+
+#data
+<p><xmp></xmp>
+#errors
+XXX: Unknown
+#document
+| <html>
+|   <head>
+|   <body>
+|     <p>
+|     <xmp>
+
+#data
+<xmp> <!-- > --> </xmp>
+#errors
+Line: 1 Col: 5 Unexpected start tag (xmp). Expected DOCTYPE.
+#document
+| <html>
+|   <head>
+|   <body>
+|     <xmp>
+|       " <!-- > --> "
+
+#data
+<title>&amp;</title>
+#errors
+Line: 1 Col: 7 Unexpected start tag (title). Expected DOCTYPE.
+#document
+| <html>
+|   <head>
+|     <title>
+|       "&"
+|   <body>
+
+#data
+<title><!--&amp;--></title>
+#errors
+Line: 1 Col: 7 Unexpected start tag (title). Expected DOCTYPE.
+#document
+| <html>
+|   <head>
+|     <title>
+|       "<!--&-->"
+|   <body>
+
+#data
+<title><!--</title>
+#errors
+Line: 1 Col: 7 Unexpected start tag (title). Expected DOCTYPE.
+Line: 1 Col: 19 Unexpected end of file. Expected end tag (title).
+#document
+| <html>
+|   <head>
+|     <title>
+|       "<!--"
+|   <body>
+
+#data
+<noscript><!--</noscript>--></noscript>
+#errors
+Line: 1 Col: 10 Unexpected start tag (noscript). Expected DOCTYPE.
+#document
+| <html>
+|   <head>
+|     <noscript>
+|       "<!--"
+|   <body>
+|     "-->"
diff --git a/html/test/data/tree-construction/tests6.dat b/html/test/data/tree-construction/tests6.dat
new file mode 100644
index 0000000..f28ece4
--- /dev/null
+++ b/html/test/data/tree-construction/tests6.dat
@@ -0,0 +1,663 @@
+#data
+<!doctype html></head> <head>
+#errors
+Line: 1 Col: 29 Unexpected start tag head. Ignored.
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   " "
+|   <body>
+
+#data
+<!doctype html><form><div></form><div>
+#errors
+33: End tag "form" seen but there were unclosed elements.
+38: End of file seen and there were open elements.
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     <form>
+|       <div>
+|         <div>
+
+#data
+<!doctype html><title>&amp;</title>
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|     <title>
+|       "&"
+|   <body>
+
+#data
+<!doctype html><title><!--&amp;--></title>
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|     <title>
+|       "<!--&-->"
+|   <body>
+
+#data
+<!doctype>
+#errors
+Line: 1 Col: 9 No space after literal string 'DOCTYPE'.
+Line: 1 Col: 10 Unexpected > character. Expected DOCTYPE name.
+Line: 1 Col: 10 Erroneous DOCTYPE.
+#document
+| <!DOCTYPE >
+| <html>
+|   <head>
+|   <body>
+
+#data
+<!---x
+#errors
+Line: 1 Col: 6 Unexpected end of file in comment.
+Line: 1 Col: 6 Unexpected End of file. Expected DOCTYPE.
+#document
+| <!-- -x -->
+| <html>
+|   <head>
+|   <body>
+
+#data
+<body>
+<div>
+#errors
+Line: 1 Col: 6 Unexpected start tag (body).
+Line: 2 Col: 5 Expected closing tag. Unexpected end of file.
+#document-fragment
+div
+#document
+| "
+"
+| <div>
+
+#data
+<frameset></frameset>
+foo
+#errors
+Line: 1 Col: 10 Unexpected start tag (frameset). Expected DOCTYPE.
+Line: 2 Col: 3 Unexpected non-space characters in the after frameset phase. Ignored.
+#document
+| <html>
+|   <head>
+|   <frameset>
+|   "
+"
+
+#data
+<frameset></frameset>
+<noframes>
+#errors
+Line: 1 Col: 10 Unexpected start tag (frameset). Expected DOCTYPE.
+Line: 2 Col: 10 Expected closing tag. Unexpected end of file.
+#document
+| <html>
+|   <head>
+|   <frameset>
+|   "
+"
+|   <noframes>
+
+#data
+<frameset></frameset>
+<div>
+#errors
+Line: 1 Col: 10 Unexpected start tag (frameset). Expected DOCTYPE.
+Line: 2 Col: 5 Unexpected start tag (div) in the after frameset phase. Ignored.
+#document
+| <html>
+|   <head>
+|   <frameset>
+|   "
+"
+
+#data
+<frameset></frameset>
+</html>
+#errors
+Line: 1 Col: 10 Unexpected start tag (frameset). Expected DOCTYPE.
+#document
+| <html>
+|   <head>
+|   <frameset>
+|   "
+"
+
+#data
+<frameset></frameset>
+</div>
+#errors
+Line: 1 Col: 10 Unexpected start tag (frameset). Expected DOCTYPE.
+Line: 2 Col: 6 Unexpected end tag (div) in the after frameset phase. Ignored.
+#document
+| <html>
+|   <head>
+|   <frameset>
+|   "
+"
+
+#data
+<form><form>
+#errors
+Line: 1 Col: 6 Unexpected start tag (form). Expected DOCTYPE.
+Line: 1 Col: 12 Unexpected start tag (form).
+Line: 1 Col: 12 Expected closing tag. Unexpected end of file.
+#document
+| <html>
+|   <head>
+|   <body>
+|     <form>
+
+#data
+<button><button>
+#errors
+Line: 1 Col: 8 Unexpected start tag (button). Expected DOCTYPE.
+Line: 1 Col: 16 Unexpected start tag (button) implies end tag (button).
+Line: 1 Col: 16 Expected closing tag. Unexpected end of file.
+#document
+| <html>
+|   <head>
+|   <body>
+|     <button>
+|     <button>
+
+#data
+<table><tr><td></th>
+#errors
+Line: 1 Col: 7 Unexpected start tag (table). Expected DOCTYPE.
+Line: 1 Col: 20 Unexpected end tag (th). Ignored.
+Line: 1 Col: 20 Expected closing tag. Unexpected end of file.
+#document
+| <html>
+|   <head>
+|   <body>
+|     <table>
+|       <tbody>
+|         <tr>
+|           <td>
+
+#data
+<table><caption><td>
+#errors
+Line: 1 Col: 7 Unexpected start tag (table). Expected DOCTYPE.
+Line: 1 Col: 20 Unexpected end tag (td). Ignored.
+Line: 1 Col: 20 Unexpected table cell start tag (td) in the table body phase.
+Line: 1 Col: 20 Expected closing tag. Unexpected end of file.
+#document
+| <html>
+|   <head>
+|   <body>
+|     <table>
+|       <caption>
+|       <tbody>
+|         <tr>
+|           <td>
+
+#data
+<table><caption><div>
+#errors
+Line: 1 Col: 7 Unexpected start tag (table). Expected DOCTYPE.
+Line: 1 Col: 21 Expected closing tag. Unexpected end of file.
+#document
+| <html>
+|   <head>
+|   <body>
+|     <table>
+|       <caption>
+|         <div>
+
+#data
+</caption><div>
+#errors
+Line: 1 Col: 10 Unexpected end tag (caption). Ignored.
+Line: 1 Col: 15 Expected closing tag. Unexpected end of file.
+#document-fragment
+caption
+#document
+| <div>
+
+#data
+<table><caption><div></caption>
+#errors
+Line: 1 Col: 7 Unexpected start tag (table). Expected DOCTYPE.
+Line: 1 Col: 31 Unexpected end tag (caption). Missing end tag (div).
+Line: 1 Col: 31 Unexpected end of file. Expected table content.
+#document
+| <html>
+|   <head>
+|   <body>
+|     <table>
+|       <caption>
+|         <div>
+
+#data
+<table><caption></table>
+#errors
+Line: 1 Col: 7 Unexpected start tag (table). Expected DOCTYPE.
+Line: 1 Col: 24 Unexpected end table tag in caption. Generates implied end caption.
+#document
+| <html>
+|   <head>
+|   <body>
+|     <table>
+|       <caption>
+
+#data
+</table><div>
+#errors
+Line: 1 Col: 8 Unexpected end table tag in caption. Generates implied end caption.
+Line: 1 Col: 8 Unexpected end tag (caption). Ignored.
+Line: 1 Col: 13 Expected closing tag. Unexpected end of file.
+#document-fragment
+caption
+#document
+| <div>
+
+#data
+<table><caption></body></col></colgroup></html></tbody></td></tfoot></th></thead></tr>
+#errors
+Line: 1 Col: 7 Unexpected start tag (table). Expected DOCTYPE.
+Line: 1 Col: 23 Unexpected end tag (body). Ignored.
+Line: 1 Col: 29 Unexpected end tag (col). Ignored.
+Line: 1 Col: 40 Unexpected end tag (colgroup). Ignored.
+Line: 1 Col: 47 Unexpected end tag (html). Ignored.
+Line: 1 Col: 55 Unexpected end tag (tbody). Ignored.
+Line: 1 Col: 60 Unexpected end tag (td). Ignored.
+Line: 1 Col: 68 Unexpected end tag (tfoot). Ignored.
+Line: 1 Col: 73 Unexpected end tag (th). Ignored.
+Line: 1 Col: 81 Unexpected end tag (thead). Ignored.
+Line: 1 Col: 86 Unexpected end tag (tr). Ignored.
+Line: 1 Col: 86 Expected closing tag. Unexpected end of file.
+#document
+| <html>
+|   <head>
+|   <body>
+|     <table>
+|       <caption>
+
+#data
+<table><caption><div></div>
+#errors
+Line: 1 Col: 7 Unexpected start tag (table). Expected DOCTYPE.
+Line: 1 Col: 27 Expected closing tag. Unexpected end of file.
+#document
+| <html>
+|   <head>
+|   <body>
+|     <table>
+|       <caption>
+|         <div>
+
+#data
+<table><tr><td></body></caption></col></colgroup></html>
+#errors
+Line: 1 Col: 7 Unexpected start tag (table). Expected DOCTYPE.
+Line: 1 Col: 22 Unexpected end tag (body). Ignored.
+Line: 1 Col: 32 Unexpected end tag (caption). Ignored.
+Line: 1 Col: 38 Unexpected end tag (col). Ignored.
+Line: 1 Col: 49 Unexpected end tag (colgroup). Ignored.
+Line: 1 Col: 56 Unexpected end tag (html). Ignored.
+Line: 1 Col: 56 Expected closing tag. Unexpected end of file.
+#document
+| <html>
+|   <head>
+|   <body>
+|     <table>
+|       <tbody>
+|         <tr>
+|           <td>
+
+#data
+</table></tbody></tfoot></thead></tr><div>
+#errors
+Line: 1 Col: 8 Unexpected end tag (table). Ignored.
+Line: 1 Col: 16 Unexpected end tag (tbody). Ignored.
+Line: 1 Col: 24 Unexpected end tag (tfoot). Ignored.
+Line: 1 Col: 32 Unexpected end tag (thead). Ignored.
+Line: 1 Col: 37 Unexpected end tag (tr). Ignored.
+Line: 1 Col: 42 Expected closing tag. Unexpected end of file.
+#document-fragment
+td
+#document
+| <div>
+
+#data
+<table><colgroup>foo
+#errors
+Line: 1 Col: 7 Unexpected start tag (table). Expected DOCTYPE.
+Line: 1 Col: 20 Unexpected non-space characters in table context caused voodoo mode.
+Line: 1 Col: 20 Unexpected end of file. Expected table content.
+#document
+| <html>
+|   <head>
+|   <body>
+|     "foo"
+|     <table>
+|       <colgroup>
+
+#data
+foo<col>
+#errors
+Line: 1 Col: 3 Unexpected end tag (colgroup). Ignored.
+#document-fragment
+colgroup
+#document
+| <col>
+
+#data
+<table><colgroup></col>
+#errors
+Line: 1 Col: 7 Unexpected start tag (table). Expected DOCTYPE.
+Line: 1 Col: 23 This element (col) has no end tag.
+Line: 1 Col: 23 Expected closing tag. Unexpected end of file.
+#document
+| <html>
+|   <head>
+|   <body>
+|     <table>
+|       <colgroup>
+
+#data
+<frameset><div>
+#errors
+Line: 1 Col: 10 Unexpected start tag (frameset). Expected DOCTYPE.
+Line: 1 Col: 15 Unexpected start tag token (div) in the frameset phase. Ignored.
+Line: 1 Col: 15 Expected closing tag. Unexpected end of file.
+#document
+| <html>
+|   <head>
+|   <frameset>
+
+#data
+</frameset><frame>
+#errors
+Line: 1 Col: 11 Unexpected end tag token (frameset) in the frameset phase (innerHTML).
+#document-fragment
+frameset
+#document
+| <frame>
+
+#data
+<frameset></div>
+#errors
+Line: 1 Col: 10 Unexpected start tag (frameset). Expected DOCTYPE.
+Line: 1 Col: 16 Unexpected end tag token (div) in the frameset phase. Ignored.
+Line: 1 Col: 16 Expected closing tag. Unexpected end of file.
+#document
+| <html>
+|   <head>
+|   <frameset>
+
+#data
+</body><div>
+#errors
+Line: 1 Col: 7 Unexpected end tag (body). Ignored.
+Line: 1 Col: 12 Expected closing tag. Unexpected end of file.
+#document-fragment
+body
+#document
+| <div>
+
+#data
+<table><tr><div>
+#errors
+Line: 1 Col: 7 Unexpected start tag (table). Expected DOCTYPE.
+Line: 1 Col: 16 Unexpected start tag (div) in table context caused voodoo mode.
+Line: 1 Col: 16 Unexpected end of file. Expected table content.
+#document
+| <html>
+|   <head>
+|   <body>
+|     <div>
+|     <table>
+|       <tbody>
+|         <tr>
+
+#data
+</tr><td>
+#errors
+Line: 1 Col: 5 Unexpected end tag (tr). Ignored.
+#document-fragment
+tr
+#document
+| <td>
+
+#data
+</tbody></tfoot></thead><td>
+#errors
+Line: 1 Col: 8 Unexpected end tag (tbody). Ignored.
+Line: 1 Col: 16 Unexpected end tag (tfoot). Ignored.
+Line: 1 Col: 24 Unexpected end tag (thead). Ignored.
+#document-fragment
+tr
+#document
+| <td>
+
+#data
+<table><tr><div><td>
+#errors
+Line: 1 Col: 7 Unexpected start tag (table). Expected DOCTYPE.
+Line: 1 Col: 16 Unexpected start tag (div) in table context caused voodoo mode.
+Line: 1 Col: 20 Unexpected implied end tag (div) in the table row phase.
+Line: 1 Col: 20 Expected closing tag. Unexpected end of file.
+#document
+| <html>
+|   <head>
+|   <body>
+|     <div>
+|     <table>
+|       <tbody>
+|         <tr>
+|           <td>
+
+#data
+<caption><col><colgroup><tbody><tfoot><thead><tr>
+#errors
+Line: 1 Col: 9 Unexpected start tag (caption).
+Line: 1 Col: 14 Unexpected start tag (col).
+Line: 1 Col: 24 Unexpected start tag (colgroup).
+Line: 1 Col: 31 Unexpected start tag (tbody).
+Line: 1 Col: 38 Unexpected start tag (tfoot).
+Line: 1 Col: 45 Unexpected start tag (thead).
+Line: 1 Col: 49 Unexpected end of file. Expected table content.
+#document-fragment
+tbody
+#document
+| <tr>
+
+#data
+<table><tbody></thead>
+#errors
+Line: 1 Col: 7 Unexpected start tag (table). Expected DOCTYPE.
+Line: 1 Col: 22 Unexpected end tag (thead) in the table body phase. Ignored.
+Line: 1 Col: 22 Unexpected end of file. Expected table content.
+#document
+| <html>
+|   <head>
+|   <body>
+|     <table>
+|       <tbody>
+
+#data
+</table><tr>
+#errors
+Line: 1 Col: 8 Unexpected end tag (table). Ignored.
+Line: 1 Col: 12 Unexpected end of file. Expected table content.
+#document-fragment
+tbody
+#document
+| <tr>
+
+#data
+<table><tbody></body></caption></col></colgroup></html></td></th></tr>
+#errors
+Line: 1 Col: 7 Unexpected start tag (table). Expected DOCTYPE.
+Line: 1 Col: 21 Unexpected end tag (body) in the table body phase. Ignored.
+Line: 1 Col: 31 Unexpected end tag (caption) in the table body phase. Ignored.
+Line: 1 Col: 37 Unexpected end tag (col) in the table body phase. Ignored.
+Line: 1 Col: 48 Unexpected end tag (colgroup) in the table body phase. Ignored.
+Line: 1 Col: 55 Unexpected end tag (html) in the table body phase. Ignored.
+Line: 1 Col: 60 Unexpected end tag (td) in the table body phase. Ignored.
+Line: 1 Col: 65 Unexpected end tag (th) in the table body phase. Ignored.
+Line: 1 Col: 70 Unexpected end tag (tr) in the table body phase. Ignored.
+Line: 1 Col: 70 Unexpected end of file. Expected table content.
+#document
+| <html>
+|   <head>
+|   <body>
+|     <table>
+|       <tbody>
+
+#data
+<table><tbody></div>
+#errors
+Line: 1 Col: 7 Unexpected start tag (table). Expected DOCTYPE.
+Line: 1 Col: 20 Unexpected end tag (div) in table context caused voodoo mode.
+Line: 1 Col: 20 End tag (div) seen too early. Expected other end tag.
+Line: 1 Col: 20 Unexpected end of file. Expected table content.
+#document
+| <html>
+|   <head>
+|   <body>
+|     <table>
+|       <tbody>
+
+#data
+<table><table>
+#errors
+Line: 1 Col: 7 Unexpected start tag (table). Expected DOCTYPE.
+Line: 1 Col: 14 Unexpected start tag (table) implies end tag (table).
+Line: 1 Col: 14 Unexpected end of file. Expected table content.
+#document
+| <html>
+|   <head>
+|   <body>
+|     <table>
+|     <table>
+
+#data
+<table></body></caption></col></colgroup></html></tbody></td></tfoot></th></thead></tr>
+#errors
+Line: 1 Col: 7 Unexpected start tag (table). Expected DOCTYPE.
+Line: 1 Col: 14 Unexpected end tag (body). Ignored.
+Line: 1 Col: 24 Unexpected end tag (caption). Ignored.
+Line: 1 Col: 30 Unexpected end tag (col). Ignored.
+Line: 1 Col: 41 Unexpected end tag (colgroup). Ignored.
+Line: 1 Col: 48 Unexpected end tag (html). Ignored.
+Line: 1 Col: 56 Unexpected end tag (tbody). Ignored.
+Line: 1 Col: 61 Unexpected end tag (td). Ignored.
+Line: 1 Col: 69 Unexpected end tag (tfoot). Ignored.
+Line: 1 Col: 74 Unexpected end tag (th). Ignored.
+Line: 1 Col: 82 Unexpected end tag (thead). Ignored.
+Line: 1 Col: 87 Unexpected end tag (tr). Ignored.
+Line: 1 Col: 87 Unexpected end of file. Expected table content.
+#document
+| <html>
+|   <head>
+|   <body>
+|     <table>
+
+#data
+</table><tr>
+#errors
+Line: 1 Col: 8 Unexpected end tag (table). Ignored.
+Line: 1 Col: 12 Unexpected end of file. Expected table content.
+#document-fragment
+table
+#document
+| <tbody>
+|   <tr>
+
+#data
+<body></body></html>
+#errors
+Line: 1 Col: 20 Unexpected html end tag in inner html mode.
+Line: 1 Col: 20 Unexpected EOF in inner html mode.
+#document-fragment
+html
+#document
+| <head>
+| <body>
+
+#data
+<html><frameset></frameset></html> 
+#errors
+Line: 1 Col: 6 Unexpected start tag (html). Expected DOCTYPE.
+#document
+| <html>
+|   <head>
+|   <frameset>
+|   " "
+
+#data
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN"><html></html>
+#errors
+Line: 1 Col: 50 Erroneous DOCTYPE.
+Line: 1 Col: 63 Unexpected end tag (html) after the (implied) root element.
+#document
+| <!DOCTYPE html "-//W3C//DTD HTML 4.01//EN" "">
+| <html>
+|   <head>
+|   <body>
+
+#data
+<param><frameset></frameset>
+#errors
+Line: 1 Col: 7 Unexpected start tag (param). Expected DOCTYPE.
+Line: 1 Col: 17 Unexpected start tag (frameset).
+#document
+| <html>
+|   <head>
+|   <frameset>
+
+#data
+<source><frameset></frameset>
+#errors
+Line: 1 Col: 7 Unexpected start tag (source). Expected DOCTYPE.
+Line: 1 Col: 17 Unexpected start tag (frameset).
+#document
+| <html>
+|   <head>
+|   <frameset>
+
+#data
+<track><frameset></frameset>
+#errors
+Line: 1 Col: 7 Unexpected start tag (track). Expected DOCTYPE.
+Line: 1 Col: 17 Unexpected start tag (frameset).
+#document
+| <html>
+|   <head>
+|   <frameset>
+
+#data
+</html><frameset></frameset>
+#errors
+7: End tag seen without seeing a doctype first. Expected “<!DOCTYPE html>”.
+17: Stray “frameset” start tag.
+17: “frameset” start tag seen.
+#document
+| <html>
+|   <head>
+|   <frameset>
+
+#data
+</body><frameset></frameset>
+#errors
+7: End tag seen without seeing a doctype first. Expected “<!DOCTYPE html>”.
+17: Stray “frameset” start tag.
+17: “frameset” start tag seen.
+#document
+| <html>
+|   <head>
+|   <frameset>
diff --git a/html/test/data/tree-construction/tests7.dat b/html/test/data/tree-construction/tests7.dat
new file mode 100644
index 0000000..f5193c6
--- /dev/null
+++ b/html/test/data/tree-construction/tests7.dat
@@ -0,0 +1,390 @@
+#data
+<!doctype html><body><title>X</title>
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     <title>
+|       "X"
+
+#data
+<!doctype html><table><title>X</title></table>
+#errors
+Line: 1 Col: 29 Unexpected start tag (title) in table context caused voodoo mode.
+Line: 1 Col: 38 Unexpected end tag (title) in table context caused voodoo mode.
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     <title>
+|       "X"
+|     <table>
+
+#data
+<!doctype html><head></head><title>X</title>
+#errors
+Line: 1 Col: 35 Unexpected start tag (title) that can be in head. Moved.
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|     <title>
+|       "X"
+|   <body>
+
+#data
+<!doctype html></head><title>X</title>
+#errors
+Line: 1 Col: 29 Unexpected start tag (title) that can be in head. Moved.
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|     <title>
+|       "X"
+|   <body>
+
+#data
+<!doctype html><table><meta></table>
+#errors
+Line: 1 Col: 28 Unexpected start tag (meta) in table context caused voodoo mode.
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     <meta>
+|     <table>
+
+#data
+<!doctype html><table>X<tr><td><table> <meta></table></table>
+#errors
+Line: 1 Col: 23 Unexpected non-space characters in table context caused voodoo mode.
+Line: 1 Col: 45 Unexpected start tag (meta) in table context caused voodoo mode.
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     "X"
+|     <table>
+|       <tbody>
+|         <tr>
+|           <td>
+|             <meta>
+|             <table>
+|               " "
+
+#data
+<!doctype html><html> <head>
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+
+#data
+<!doctype html> <head>
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+
+#data
+<!doctype html><table><style> <tr>x </style> </table>
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     <table>
+|       <style>
+|         " <tr>x "
+|       " "
+
+#data
+<!doctype html><table><TBODY><script> <tr>x </script> </table>
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     <table>
+|       <tbody>
+|         <script>
+|           " <tr>x "
+|         " "
+
+#data
+<!doctype html><p><applet><p>X</p></applet>
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     <p>
+|       <applet>
+|         <p>
+|           "X"
+
+#data
+<!doctype html><listing>
+X</listing>
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     <listing>
+|       "X"
+
+#data
+<!doctype html><select><input>X
+#errors
+Line: 1 Col: 30 Unexpected input start tag in the select phase.
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     <select>
+|     <input>
+|     "X"
+
+#data
+<!doctype html><select><select>X
+#errors
+Line: 1 Col: 31 Unexpected select start tag in the select phase treated as select end tag.
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     <select>
+|     "X"
+
+#data
+<!doctype html><table><input type=hidDEN></table>
+#errors
+Line: 1 Col: 41 Unexpected input with type hidden in table context.
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     <table>
+|       <input>
+|         type="hidDEN"
+
+#data
+<!doctype html><table>X<input type=hidDEN></table>
+#errors
+Line: 1 Col: 23 Unexpected non-space characters in table context caused voodoo mode.
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     "X"
+|     <table>
+|       <input>
+|         type="hidDEN"
+
+#data
+<!doctype html><table>  <input type=hidDEN></table>
+#errors
+Line: 1 Col: 43 Unexpected input with type hidden in table context.
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     <table>
+|       "  "
+|       <input>
+|         type="hidDEN"
+
+#data
+<!doctype html><table>  <input type='hidDEN'></table>
+#errors
+Line: 1 Col: 45 Unexpected input with type hidden in table context.
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     <table>
+|       "  "
+|       <input>
+|         type="hidDEN"
+
+#data
+<!doctype html><table><input type=" hidden"><input type=hidDEN></table>
+#errors
+Line: 1 Col: 44 Unexpected start tag (input) in table context caused voodoo mode.
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     <input>
+|       type=" hidden"
+|     <table>
+|       <input>
+|         type="hidDEN"
+
+#data
+<!doctype html><table><select>X<tr>
+#errors
+Line: 1 Col: 30 Unexpected start tag (select) in table context caused voodoo mode.
+Line: 1 Col: 35 Unexpected table element start tag (trs) in the select in table phase.
+Line: 1 Col: 35 Unexpected end of file. Expected table content.
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     <select>
+|       "X"
+|     <table>
+|       <tbody>
+|         <tr>
+
+#data
+<!doctype html><select>X</select>
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     <select>
+|       "X"
+
+#data
+<!DOCTYPE hTmL><html></html>
+#errors
+Line: 1 Col: 28 Unexpected end tag (html) after the (implied) root element.
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+
+#data
+<!DOCTYPE HTML><html></html>
+#errors
+Line: 1 Col: 28 Unexpected end tag (html) after the (implied) root element.
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+
+#data
+<body>X</body></body>
+#errors
+Line: 1 Col: 21 Unexpected end tag token (body) in the after body phase.
+Line: 1 Col: 21 Unexpected EOF in inner html mode.
+#document-fragment
+html
+#document
+| <head>
+| <body>
+|   "X"
+
+#data
+<div><p>a</x> b
+#errors
+Line: 1 Col: 5 Unexpected start tag (div). Expected DOCTYPE.
+Line: 1 Col: 13 Unexpected end tag (x). Ignored.
+Line: 1 Col: 15 Expected closing tag. Unexpected end of file.
+#document
+| <html>
+|   <head>
+|   <body>
+|     <div>
+|       <p>
+|         "a b"
+
+#data
+<table><tr><td><code></code> </table>
+#errors
+Line: 1 Col: 7 Unexpected start tag (table). Expected DOCTYPE.
+#document
+| <html>
+|   <head>
+|   <body>
+|     <table>
+|       <tbody>
+|         <tr>
+|           <td>
+|             <code>
+|             " "
+
+#data
+<table><b><tr><td>aaa</td></tr>bbb</table>ccc
+#errors
+XXX: Fix me
+#document
+| <html>
+|   <head>
+|   <body>
+|     <b>
+|     <b>
+|       "bbb"
+|     <table>
+|       <tbody>
+|         <tr>
+|           <td>
+|             "aaa"
+|     <b>
+|       "ccc"
+
+#data
+A<table><tr> B</tr> B</table>
+#errors
+XXX: Fix me
+#document
+| <html>
+|   <head>
+|   <body>
+|     "A B B"
+|     <table>
+|       <tbody>
+|         <tr>
+
+#data
+A<table><tr> B</tr> </em>C</table>
+#errors
+XXX: Fix me
+#document
+| <html>
+|   <head>
+|   <body>
+|     "A BC"
+|     <table>
+|       <tbody>
+|         <tr>
+|         " "
+
+#data
+<select><keygen>
+#errors
+Not known
+#document
+| <html>
+|   <head>
+|   <body>
+|     <select>
+|     <keygen>
diff --git a/html/test/data/tree-construction/tests8.dat b/html/test/data/tree-construction/tests8.dat
new file mode 100644
index 0000000..90e6c91
--- /dev/null
+++ b/html/test/data/tree-construction/tests8.dat
@@ -0,0 +1,148 @@
+#data
+<div>
+<div></div>
+</span>x
+#errors
+Line: 1 Col: 5 Unexpected start tag (div). Expected DOCTYPE.
+Line: 3 Col: 7 Unexpected end tag (span). Ignored.
+Line: 3 Col: 8 Expected closing tag. Unexpected end of file.
+#document
+| <html>
+|   <head>
+|   <body>
+|     <div>
+|       "
+"
+|       <div>
+|       "
+x"
+
+#data
+<div>x<div></div>
+</span>x
+#errors
+Line: 1 Col: 5 Unexpected start tag (div). Expected DOCTYPE.
+Line: 2 Col: 7 Unexpected end tag (span). Ignored.
+Line: 2 Col: 8 Expected closing tag. Unexpected end of file.
+#document
+| <html>
+|   <head>
+|   <body>
+|     <div>
+|       "x"
+|       <div>
+|       "
+x"
+
+#data
+<div>x<div></div>x</span>x
+#errors
+Line: 1 Col: 5 Unexpected start tag (div). Expected DOCTYPE.
+Line: 1 Col: 25 Unexpected end tag (span). Ignored.
+Line: 1 Col: 26 Expected closing tag. Unexpected end of file.
+#document
+| <html>
+|   <head>
+|   <body>
+|     <div>
+|       "x"
+|       <div>
+|       "xx"
+
+#data
+<div>x<div></div>y</span>z
+#errors
+Line: 1 Col: 5 Unexpected start tag (div). Expected DOCTYPE.
+Line: 1 Col: 25 Unexpected end tag (span). Ignored.
+Line: 1 Col: 26 Expected closing tag. Unexpected end of file.
+#document
+| <html>
+|   <head>
+|   <body>
+|     <div>
+|       "x"
+|       <div>
+|       "yz"
+
+#data
+<table><div>x<div></div>x</span>x
+#errors
+Line: 1 Col: 7 Unexpected start tag (table). Expected DOCTYPE.
+Line: 1 Col: 12 Unexpected start tag (div) in table context caused voodoo mode.
+Line: 1 Col: 18 Unexpected start tag (div) in table context caused voodoo mode.
+Line: 1 Col: 24 Unexpected end tag (div) in table context caused voodoo mode.
+Line: 1 Col: 32 Unexpected end tag (span) in table context caused voodoo mode.
+Line: 1 Col: 32 Unexpected end tag (span). Ignored.
+Line: 1 Col: 33 Unexpected end of file. Expected table content.
+#document
+| <html>
+|   <head>
+|   <body>
+|     <div>
+|       "x"
+|       <div>
+|       "xx"
+|     <table>
+
+#data
+x<table>x
+#errors
+Line: 1 Col: 1 Unexpected non-space characters. Expected DOCTYPE.
+Line: 1 Col: 9 Unexpected non-space characters in table context caused voodoo mode.
+Line: 1 Col: 9 Unexpected end of file. Expected table content.
+#document
+| <html>
+|   <head>
+|   <body>
+|     "xx"
+|     <table>
+
+#data
+x<table><table>x
+#errors
+Line: 1 Col: 1 Unexpected non-space characters. Expected DOCTYPE.
+Line: 1 Col: 15 Unexpected start tag (table) implies end tag (table).
+Line: 1 Col: 16 Unexpected non-space characters in table context caused voodoo mode.
+Line: 1 Col: 16 Unexpected end of file. Expected table content.
+#document
+| <html>
+|   <head>
+|   <body>
+|     "x"
+|     <table>
+|     "x"
+|     <table>
+
+#data
+<b>a<div></div><div></b>y
+#errors
+Line: 1 Col: 3 Unexpected start tag (b). Expected DOCTYPE.
+Line: 1 Col: 24 End tag (b) violates step 1, paragraph 3 of the adoption agency algorithm.
+Line: 1 Col: 25 Expected closing tag. Unexpected end of file.
+#document
+| <html>
+|   <head>
+|   <body>
+|     <b>
+|       "a"
+|       <div>
+|     <div>
+|       <b>
+|       "y"
+
+#data
+<a><div><p></a>
+#errors
+Line: 1 Col: 3 Unexpected start tag (a). Expected DOCTYPE.
+Line: 1 Col: 15 End tag (a) violates step 1, paragraph 3 of the adoption agency algorithm.
+Line: 1 Col: 15 End tag (a) violates step 1, paragraph 3 of the adoption agency algorithm.
+Line: 1 Col: 15 Expected closing tag. Unexpected end of file.
+#document
+| <html>
+|   <head>
+|   <body>
+|     <a>
+|     <div>
+|       <a>
+|       <p>
+|         <a>
diff --git a/html/test/data/tree-construction/tests9.dat b/html/test/data/tree-construction/tests9.dat
new file mode 100644
index 0000000..554e27a
--- /dev/null
+++ b/html/test/data/tree-construction/tests9.dat
@@ -0,0 +1,457 @@
+#data
+<!DOCTYPE html><math></math>
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     <math math>
+
+#data
+<!DOCTYPE html><body><math></math>
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     <math math>
+
+#data
+<!DOCTYPE html><math><mi>
+#errors
+25: End of file in a foreign namespace context.
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     <math math>
+|       <math mi>
+
+#data
+<!DOCTYPE html><math><annotation-xml><svg><u>
+#errors
+45: HTML start tag “u” in a foreign namespace context.
+45: End of file seen and there were open elements.
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     <math math>
+|       <math annotation-xml>
+|         <svg svg>
+|     <u>
+
+#data
+<!DOCTYPE html><body><select><math></math></select>
+#errors
+Line: 1 Col: 35 Unexpected start tag token (math) in the select phase. Ignored.
+Line: 1 Col: 42 Unexpected end tag (math) in the select phase. Ignored.
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     <select>
+
+#data
+<!DOCTYPE html><body><select><option><math></math></option></select>
+#errors
+Line: 1 Col: 43 Unexpected start tag token (math) in the select phase. Ignored.
+Line: 1 Col: 50 Unexpected end tag (math) in the select phase. Ignored.
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     <select>
+|       <option>
+
+#data
+<!DOCTYPE html><body><table><math></math></table>
+#errors
+Line: 1 Col: 34 Unexpected start tag (math) in table context caused voodoo mode.
+Line: 1 Col: 41 Unexpected end tag (math) in table context caused voodoo mode.
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     <math math>
+|     <table>
+
+#data
+<!DOCTYPE html><body><table><math><mi>foo</mi></math></table>
+#errors
+Line: 1 Col: 34 Unexpected start tag (math) in table context caused voodoo mode.
+Line: 1 Col: 46 Unexpected end tag (mi) in table context caused voodoo mode.
+Line: 1 Col: 53 Unexpected end tag (math) in table context caused voodoo mode.
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     <math math>
+|       <math mi>
+|         "foo"
+|     <table>
+
+#data
+<!DOCTYPE html><body><table><math><mi>foo</mi><mi>bar</mi></math></table>
+#errors
+Line: 1 Col: 34 Unexpected start tag (math) in table context caused voodoo mode.
+Line: 1 Col: 46 Unexpected end tag (mi) in table context caused voodoo mode.
+Line: 1 Col: 58 Unexpected end tag (mi) in table context caused voodoo mode.
+Line: 1 Col: 65 Unexpected end tag (math) in table context caused voodoo mode.
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     <math math>
+|       <math mi>
+|         "foo"
+|       <math mi>
+|         "bar"
+|     <table>
+
+#data
+<!DOCTYPE html><body><table><tbody><math><mi>foo</mi><mi>bar</mi></math></tbody></table>
+#errors
+Line: 1 Col: 41 Unexpected start tag (math) in table context caused voodoo mode.
+Line: 1 Col: 53 Unexpected end tag (mi) in table context caused voodoo mode.
+Line: 1 Col: 65 Unexpected end tag (mi) in table context caused voodoo mode.
+Line: 1 Col: 72 Unexpected end tag (math) in table context caused voodoo mode.
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     <math math>
+|       <math mi>
+|         "foo"
+|       <math mi>
+|         "bar"
+|     <table>
+|       <tbody>
+
+#data
+<!DOCTYPE html><body><table><tbody><tr><math><mi>foo</mi><mi>bar</mi></math></tr></tbody></table>
+#errors
+Line: 1 Col: 45 Unexpected start tag (math) in table context caused voodoo mode.
+Line: 1 Col: 57 Unexpected end tag (mi) in table context caused voodoo mode.
+Line: 1 Col: 69 Unexpected end tag (mi) in table context caused voodoo mode.
+Line: 1 Col: 76 Unexpected end tag (math) in table context caused voodoo mode.
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     <math math>
+|       <math mi>
+|         "foo"
+|       <math mi>
+|         "bar"
+|     <table>
+|       <tbody>
+|         <tr>
+
+#data
+<!DOCTYPE html><body><table><tbody><tr><td><math><mi>foo</mi><mi>bar</mi></math></td></tr></tbody></table>
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     <table>
+|       <tbody>
+|         <tr>
+|           <td>
+|             <math math>
+|               <math mi>
+|                 "foo"
+|               <math mi>
+|                 "bar"
+
+#data
+<!DOCTYPE html><body><table><tbody><tr><td><math><mi>foo</mi><mi>bar</mi></math><p>baz</td></tr></tbody></table>
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     <table>
+|       <tbody>
+|         <tr>
+|           <td>
+|             <math math>
+|               <math mi>
+|                 "foo"
+|               <math mi>
+|                 "bar"
+|             <p>
+|               "baz"
+
+#data
+<!DOCTYPE html><body><table><caption><math><mi>foo</mi><mi>bar</mi></math><p>baz</caption></table>
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     <table>
+|       <caption>
+|         <math math>
+|           <math mi>
+|             "foo"
+|           <math mi>
+|             "bar"
+|         <p>
+|           "baz"
+
+#data
+<!DOCTYPE html><body><table><caption><math><mi>foo</mi><mi>bar</mi><p>baz</table><p>quux
+#errors
+Line: 1 Col: 70 HTML start tag "p" in a foreign namespace context.
+Line: 1 Col: 81 Unexpected end table tag in caption. Generates implied end caption.
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     <table>
+|       <caption>
+|         <math math>
+|           <math mi>
+|             "foo"
+|           <math mi>
+|             "bar"
+|         <p>
+|           "baz"
+|     <p>
+|       "quux"
+
+#data
+<!DOCTYPE html><body><table><caption><math><mi>foo</mi><mi>bar</mi>baz</table><p>quux
+#errors
+Line: 1 Col: 78 Unexpected end table tag in caption. Generates implied end caption.
+Line: 1 Col: 78 Unexpected end tag (caption). Missing end tag (math).
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     <table>
+|       <caption>
+|         <math math>
+|           <math mi>
+|             "foo"
+|           <math mi>
+|             "bar"
+|           "baz"
+|     <p>
+|       "quux"
+
+#data
+<!DOCTYPE html><body><table><colgroup><math><mi>foo</mi><mi>bar</mi><p>baz</table><p>quux
+#errors
+Line: 1 Col: 44 Unexpected start tag (math) in table context caused voodoo mode.
+Line: 1 Col: 56 Unexpected end tag (mi) in table context caused voodoo mode.
+Line: 1 Col: 68 Unexpected end tag (mi) in table context caused voodoo mode.
+Line: 1 Col: 71 HTML start tag "p" in a foreign namespace context.
+Line: 1 Col: 71 Unexpected start tag (p) in table context caused voodoo mode.
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     <math math>
+|       <math mi>
+|         "foo"
+|       <math mi>
+|         "bar"
+|     <p>
+|       "baz"
+|     <table>
+|       <colgroup>
+|     <p>
+|       "quux"
+
+#data
+<!DOCTYPE html><body><table><tr><td><select><math><mi>foo</mi><mi>bar</mi><p>baz</table><p>quux
+#errors
+Line: 1 Col: 50 Unexpected start tag token (math) in the select phase. Ignored.
+Line: 1 Col: 54 Unexpected start tag token (mi) in the select phase. Ignored.
+Line: 1 Col: 62 Unexpected end tag (mi) in the select phase. Ignored.
+Line: 1 Col: 66 Unexpected start tag token (mi) in the select phase. Ignored.
+Line: 1 Col: 74 Unexpected end tag (mi) in the select phase. Ignored.
+Line: 1 Col: 77 Unexpected start tag token (p) in the select phase. Ignored.
+Line: 1 Col: 88 Unexpected table element end tag (tables) in the select in table phase.
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     <table>
+|       <tbody>
+|         <tr>
+|           <td>
+|             <select>
+|               "foobarbaz"
+|     <p>
+|       "quux"
+
+#data
+<!DOCTYPE html><body><table><select><math><mi>foo</mi><mi>bar</mi><p>baz</table><p>quux
+#errors
+Line: 1 Col: 36 Unexpected start tag (select) in table context caused voodoo mode.
+Line: 1 Col: 42 Unexpected start tag token (math) in the select phase. Ignored.
+Line: 1 Col: 46 Unexpected start tag token (mi) in the select phase. Ignored.
+Line: 1 Col: 54 Unexpected end tag (mi) in the select phase. Ignored.
+Line: 1 Col: 58 Unexpected start tag token (mi) in the select phase. Ignored.
+Line: 1 Col: 66 Unexpected end tag (mi) in the select phase. Ignored.
+Line: 1 Col: 69 Unexpected start tag token (p) in the select phase. Ignored.
+Line: 1 Col: 80 Unexpected table element end tag (tables) in the select in table phase.
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     <select>
+|       "foobarbaz"
+|     <table>
+|     <p>
+|       "quux"
+
+#data
+<!DOCTYPE html><body></body></html><math><mi>foo</mi><mi>bar</mi><p>baz
+#errors
+Line: 1 Col: 41 Unexpected start tag (math).
+Line: 1 Col: 68 HTML start tag "p" in a foreign namespace context.
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     <math math>
+|       <math mi>
+|         "foo"
+|       <math mi>
+|         "bar"
+|     <p>
+|       "baz"
+
+#data
+<!DOCTYPE html><body></body><math><mi>foo</mi><mi>bar</mi><p>baz
+#errors
+Line: 1 Col: 34 Unexpected start tag token (math) in the after body phase.
+Line: 1 Col: 61 HTML start tag "p" in a foreign namespace context.
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     <math math>
+|       <math mi>
+|         "foo"
+|       <math mi>
+|         "bar"
+|     <p>
+|       "baz"
+
+#data
+<!DOCTYPE html><frameset><math><mi></mi><mi></mi><p><span>
+#errors
+Line: 1 Col: 31 Unexpected start tag token (math) in the frameset phase. Ignored.
+Line: 1 Col: 35 Unexpected start tag token (mi) in the frameset phase. Ignored.
+Line: 1 Col: 40 Unexpected end tag token (mi) in the frameset phase. Ignored.
+Line: 1 Col: 44 Unexpected start tag token (mi) in the frameset phase. Ignored.
+Line: 1 Col: 49 Unexpected end tag token (mi) in the frameset phase. Ignored.
+Line: 1 Col: 52 Unexpected start tag token (p) in the frameset phase. Ignored.
+Line: 1 Col: 58 Unexpected start tag token (span) in the frameset phase. Ignored.
+Line: 1 Col: 58 Expected closing tag. Unexpected end of file.
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <frameset>
+
+#data
+<!DOCTYPE html><frameset></frameset><math><mi></mi><mi></mi><p><span>
+#errors
+Line: 1 Col: 42 Unexpected start tag (math) in the after frameset phase. Ignored.
+Line: 1 Col: 46 Unexpected start tag (mi) in the after frameset phase. Ignored.
+Line: 1 Col: 51 Unexpected end tag (mi) in the after frameset phase. Ignored.
+Line: 1 Col: 55 Unexpected start tag (mi) in the after frameset phase. Ignored.
+Line: 1 Col: 60 Unexpected end tag (mi) in the after frameset phase. Ignored.
+Line: 1 Col: 63 Unexpected start tag (p) in the after frameset phase. Ignored.
+Line: 1 Col: 69 Unexpected start tag (span) in the after frameset phase. Ignored.
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <frameset>
+
+#data
+<!DOCTYPE html><body xlink:href=foo><math xlink:href=foo></math>
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     xlink:href="foo"
+|     <math math>
+|       xlink href="foo"
+
+#data
+<!DOCTYPE html><body xlink:href=foo xml:lang=en><math><mi xml:lang=en xlink:href=foo></mi></math>
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     xlink:href="foo"
+|     xml:lang="en"
+|     <math math>
+|       <math mi>
+|         xlink href="foo"
+|         xml lang="en"
+
+#data
+<!DOCTYPE html><body xlink:href=foo xml:lang=en><math><mi xml:lang=en xlink:href=foo /></math>
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     xlink:href="foo"
+|     xml:lang="en"
+|     <math math>
+|       <math mi>
+|         xlink href="foo"
+|         xml lang="en"
+
+#data
+<!DOCTYPE html><body xlink:href=foo xml:lang=en><math><mi xml:lang=en xlink:href=foo />bar</math>
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     xlink:href="foo"
+|     xml:lang="en"
+|     <math math>
+|       <math mi>
+|         xlink href="foo"
+|         xml lang="en"
+|       "bar"
diff --git a/html/test/data/tree-construction/tests_innerHTML_1.dat b/html/test/data/tree-construction/tests_innerHTML_1.dat
new file mode 100644
index 0000000..6c78661
--- /dev/null
+++ b/html/test/data/tree-construction/tests_innerHTML_1.dat
@@ -0,0 +1,741 @@
+#data
+<body><span>
+#errors
+#document-fragment
+body
+#document
+| <span>
+
+#data
+<span><body>
+#errors
+#document-fragment
+body
+#document
+| <span>
+
+#data
+<span><body>
+#errors
+#document-fragment
+div
+#document
+| <span>
+
+#data
+<body><span>
+#errors
+#document-fragment
+html
+#document
+| <head>
+| <body>
+|   <span>
+
+#data
+<frameset><span>
+#errors
+#document-fragment
+body
+#document
+| <span>
+
+#data
+<span><frameset>
+#errors
+#document-fragment
+body
+#document
+| <span>
+
+#data
+<span><frameset>
+#errors
+#document-fragment
+div
+#document
+| <span>
+
+#data
+<frameset><span>
+#errors
+#document-fragment
+html
+#document
+| <head>
+| <frameset>
+
+#data
+<table><tr>
+#errors
+#document-fragment
+table
+#document
+| <tbody>
+|   <tr>
+
+#data
+</table><tr>
+#errors
+#document-fragment
+table
+#document
+| <tbody>
+|   <tr>
+
+#data
+<a>
+#errors
+#document-fragment
+table
+#document
+| <a>
+
+#data
+<a>
+#errors
+#document-fragment
+table
+#document
+| <a>
+
+#data
+<a><caption>a
+#errors
+#document-fragment
+table
+#document
+| <a>
+| <caption>
+|   "a"
+
+#data
+<a><colgroup><col>
+#errors
+#document-fragment
+table
+#document
+| <a>
+| <colgroup>
+|   <col>
+
+#data
+<a><tbody><tr>
+#errors
+#document-fragment
+table
+#document
+| <a>
+| <tbody>
+|   <tr>
+
+#data
+<a><tfoot><tr>
+#errors
+#document-fragment
+table
+#document
+| <a>
+| <tfoot>
+|   <tr>
+
+#data
+<a><thead><tr>
+#errors
+#document-fragment
+table
+#document
+| <a>
+| <thead>
+|   <tr>
+
+#data
+<a><tr>
+#errors
+#document-fragment
+table
+#document
+| <a>
+| <tbody>
+|   <tr>
+
+#data
+<a><th>
+#errors
+#document-fragment
+table
+#document
+| <a>
+| <tbody>
+|   <tr>
+|     <th>
+
+#data
+<a><td>
+#errors
+#document-fragment
+table
+#document
+| <a>
+| <tbody>
+|   <tr>
+|     <td>
+
+#data
+<table></table><tbody>
+#errors
+#document-fragment
+caption
+#document
+| <table>
+
+#data
+</table><span>
+#errors
+#document-fragment
+caption
+#document
+| <span>
+
+#data
+<span></table>
+#errors
+#document-fragment
+caption
+#document
+| <span>
+
+#data
+</caption><span>
+#errors
+#document-fragment
+caption
+#document
+| <span>
+
+#data
+<span></caption><span>
+#errors
+#document-fragment
+caption
+#document
+| <span>
+|   <span>
+
+#data
+<span><caption><span>
+#errors
+#document-fragment
+caption
+#document
+| <span>
+|   <span>
+
+#data
+<span><col><span>
+#errors
+#document-fragment
+caption
+#document
+| <span>
+|   <span>
+
+#data
+<span><colgroup><span>
+#errors
+#document-fragment
+caption
+#document
+| <span>
+|   <span>
+
+#data
+<span><html><span>
+#errors
+#document-fragment
+caption
+#document
+| <span>
+|   <span>
+
+#data
+<span><tbody><span>
+#errors
+#document-fragment
+caption
+#document
+| <span>
+|   <span>
+
+#data
+<span><td><span>
+#errors
+#document-fragment
+caption
+#document
+| <span>
+|   <span>
+
+#data
+<span><tfoot><span>
+#errors
+#document-fragment
+caption
+#document
+| <span>
+|   <span>
+
+#data
+<span><thead><span>
+#errors
+#document-fragment
+caption
+#document
+| <span>
+|   <span>
+
+#data
+<span><th><span>
+#errors
+#document-fragment
+caption
+#document
+| <span>
+|   <span>
+
+#data
+<span><tr><span>
+#errors
+#document-fragment
+caption
+#document
+| <span>
+|   <span>
+
+#data
+<span></table><span>
+#errors
+#document-fragment
+caption
+#document
+| <span>
+|   <span>
+
+#data
+</colgroup><col>
+#errors
+#document-fragment
+colgroup
+#document
+| <col>
+
+#data
+<a><col>
+#errors
+#document-fragment
+colgroup
+#document
+| <col>
+
+#data
+<caption><a>
+#errors
+#document-fragment
+tbody
+#document
+| <a>
+
+#data
+<col><a>
+#errors
+#document-fragment
+tbody
+#document
+| <a>
+
+#data
+<colgroup><a>
+#errors
+#document-fragment
+tbody
+#document
+| <a>
+
+#data
+<tbody><a>
+#errors
+#document-fragment
+tbody
+#document
+| <a>
+
+#data
+<tfoot><a>
+#errors
+#document-fragment
+tbody
+#document
+| <a>
+
+#data
+<thead><a>
+#errors
+#document-fragment
+tbody
+#document
+| <a>
+
+#data
+</table><a>
+#errors
+#document-fragment
+tbody
+#document
+| <a>
+
+#data
+<a><tr>
+#errors
+#document-fragment
+tbody
+#document
+| <a>
+| <tr>
+
+#data
+<a><td>
+#errors
+#document-fragment
+tbody
+#document
+| <a>
+| <tr>
+|   <td>
+
+#data
+<a><td>
+#errors
+#document-fragment
+tbody
+#document
+| <a>
+| <tr>
+|   <td>
+
+#data
+<a><td>
+#errors
+#document-fragment
+tbody
+#document
+| <a>
+| <tr>
+|   <td>
+
+#data
+<td><table><tbody><a><tr>
+#errors
+#document-fragment
+tbody
+#document
+| <tr>
+|   <td>
+|     <a>
+|     <table>
+|       <tbody>
+|         <tr>
+
+#data
+</tr><td>
+#errors
+#document-fragment
+tr
+#document
+| <td>
+
+#data
+<td><table><a><tr></tr><tr>
+#errors
+#document-fragment
+tr
+#document
+| <td>
+|   <a>
+|   <table>
+|     <tbody>
+|       <tr>
+|       <tr>
+
+#data
+<caption><td>
+#errors
+#document-fragment
+tr
+#document
+| <td>
+
+#data
+<col><td>
+#errors
+#document-fragment
+tr
+#document
+| <td>
+
+#data
+<colgroup><td>
+#errors
+#document-fragment
+tr
+#document
+| <td>
+
+#data
+<tbody><td>
+#errors
+#document-fragment
+tr
+#document
+| <td>
+
+#data
+<tfoot><td>
+#errors
+#document-fragment
+tr
+#document
+| <td>
+
+#data
+<thead><td>
+#errors
+#document-fragment
+tr
+#document
+| <td>
+
+#data
+<tr><td>
+#errors
+#document-fragment
+tr
+#document
+| <td>
+
+#data
+</table><td>
+#errors
+#document-fragment
+tr
+#document
+| <td>
+
+#data
+<td><table></table><td>
+#errors
+#document-fragment
+tr
+#document
+| <td>
+|   <table>
+| <td>
+
+#data
+<td><table></table><td>
+#errors
+#document-fragment
+tr
+#document
+| <td>
+|   <table>
+| <td>
+
+#data
+<caption><a>
+#errors
+#document-fragment
+td
+#document
+| <a>
+
+#data
+<col><a>
+#errors
+#document-fragment
+td
+#document
+| <a>
+
+#data
+<colgroup><a>
+#errors
+#document-fragment
+td
+#document
+| <a>
+
+#data
+<tbody><a>
+#errors
+#document-fragment
+td
+#document
+| <a>
+
+#data
+<tfoot><a>
+#errors
+#document-fragment
+td
+#document
+| <a>
+
+#data
+<th><a>
+#errors
+#document-fragment
+td
+#document
+| <a>
+
+#data
+<thead><a>
+#errors
+#document-fragment
+td
+#document
+| <a>
+
+#data
+<tr><a>
+#errors
+#document-fragment
+td
+#document
+| <a>
+
+#data
+</table><a>
+#errors
+#document-fragment
+td
+#document
+| <a>
+
+#data
+</tbody><a>
+#errors
+#document-fragment
+td
+#document
+| <a>
+
+#data
+</td><a>
+#errors
+#document-fragment
+td
+#document
+| <a>
+
+#data
+</tfoot><a>
+#errors
+#document-fragment
+td
+#document
+| <a>
+
+#data
+</thead><a>
+#errors
+#document-fragment
+td
+#document
+| <a>
+
+#data
+</th><a>
+#errors
+#document-fragment
+td
+#document
+| <a>
+
+#data
+</tr><a>
+#errors
+#document-fragment
+td
+#document
+| <a>
+
+#data
+<table><td><td>
+#errors
+#document-fragment
+td
+#document
+| <table>
+|   <tbody>
+|     <tr>
+|       <td>
+|       <td>
+
+#data
+</select><option>
+#errors
+#document-fragment
+select
+#document
+| <option>
+
+#data
+<input><option>
+#errors
+#document-fragment
+select
+#document
+| <option>
+
+#data
+<keygen><option>
+#errors
+#document-fragment
+select
+#document
+| <option>
+
+#data
+<textarea><option>
+#errors
+#document-fragment
+select
+#document
+| <option>
+
+#data
+</html><!--abc-->
+#errors
+#document-fragment
+html
+#document
+| <head>
+| <body>
+| <!-- abc -->
+
+#data
+</frameset><frame>
+#errors
+#document-fragment
+frameset
+#document
+| <frame>
+
+#data
+#errors
+#document-fragment
+html
+#document
+| <head>
+| <body>
diff --git a/html/test/data/tree-construction/tricky01.dat b/html/test/data/tree-construction/tricky01.dat
new file mode 100644
index 0000000..0841992
--- /dev/null
+++ b/html/test/data/tree-construction/tricky01.dat
@@ -0,0 +1,261 @@
+#data
+<b><p>Bold </b> Not bold</p>
+Also not bold.
+#errors
+#document
+| <html>
+|   <head>
+|   <body>
+|     <b>
+|     <p>
+|       <b>
+|         "Bold "
+|       " Not bold"
+|     "
+Also not bold."
+
+#data
+<html>
+<font color=red><i>Italic and Red<p>Italic and Red </font> Just italic.</p> Italic only.</i> Plain
+<p>I should not be red. <font color=red>Red. <i>Italic and red.</p>
+<p>Italic and red. </i> Red.</font> I should not be red.</p>
+<b>Bold <i>Bold and italic</b> Only Italic </i> Plain
+#errors
+#document
+| <html>
+|   <head>
+|   <body>
+|     <font>
+|       color="red"
+|       <i>
+|         "Italic and Red"
+|     <i>
+|       <p>
+|         <font>
+|           color="red"
+|           "Italic and Red "
+|         " Just italic."
+|       " Italic only."
+|     " Plain
+"
+|     <p>
+|       "I should not be red. "
+|       <font>
+|         color="red"
+|         "Red. "
+|         <i>
+|           "Italic and red."
+|     <font>
+|       color="red"
+|       <i>
+|         "
+"
+|     <p>
+|       <font>
+|         color="red"
+|         <i>
+|           "Italic and red. "
+|         " Red."
+|       " I should not be red."
+|     "
+"
+|     <b>
+|       "Bold "
+|       <i>
+|         "Bold and italic"
+|     <i>
+|       " Only Italic "
+|     " Plain"
+
+#data
+<html><body>
+<p><font size="7">First paragraph.</p>
+<p>Second paragraph.</p></font>
+<b><p><i>Bold and Italic</b> Italic</p>
+#errors
+#document
+| <html>
+|   <head>
+|   <body>
+|     "
+"
+|     <p>
+|       <font>
+|         size="7"
+|         "First paragraph."
+|     <font>
+|       size="7"
+|       "
+"
+|       <p>
+|         "Second paragraph."
+|     "
+"
+|     <b>
+|     <p>
+|       <b>
+|         <i>
+|           "Bold and Italic"
+|       <i>
+|         " Italic"
+
+#data
+<html>
+<dl>
+<dt><b>Boo
+<dd>Goo?
+</dl>
+</html>
+#errors
+#document
+| <html>
+|   <head>
+|   <body>
+|     <dl>
+|       "
+"
+|       <dt>
+|         <b>
+|           "Boo
+"
+|       <dd>
+|         <b>
+|           "Goo?
+"
+|     <b>
+|       "
+"
+
+#data
+<html><body>
+<label><a><div>Hello<div>World</div></a></label>  
+</body></html>
+#errors
+#document
+| <html>
+|   <head>
+|   <body>
+|     "
+"
+|     <label>
+|       <a>
+|       <div>
+|         <a>
+|           "Hello"
+|           <div>
+|             "World"
+|         "  
+"
+
+#data
+<table><center> <font>a</center> <img> <tr><td> </td> </tr> </table>
+#errors
+#document
+| <html>
+|   <head>
+|   <body>
+|     <center>
+|       " "
+|       <font>
+|         "a"
+|     <font>
+|       <img>
+|       " "
+|     <table>
+|       " "
+|       <tbody>
+|         <tr>
+|           <td>
+|             " "
+|           " "
+|         " "
+
+#data
+<table><tr><p><a><p>You should see this text.
+#errors
+#document
+| <html>
+|   <head>
+|   <body>
+|     <p>
+|       <a>
+|     <p>
+|       <a>
+|         "You should see this text."
+|     <table>
+|       <tbody>
+|         <tr>
+
+#data
+<TABLE>
+<TR>
+<CENTER><CENTER><TD></TD></TR><TR>
+<FONT>
+<TABLE><tr></tr></TABLE>
+</P>
+<a></font><font></a>
+This page contains an insanely badly-nested tag sequence.
+#errors
+#document
+| <html>
+|   <head>
+|   <body>
+|     <center>
+|       <center>
+|     <font>
+|       "
+"
+|     <table>
+|       "
+"
+|       <tbody>
+|         <tr>
+|           "
+"
+|           <td>
+|         <tr>
+|           "
+"
+|     <table>
+|       <tbody>
+|         <tr>
+|     <font>
+|       "
+"
+|       <p>
+|       "
+"
+|       <a>
+|     <a>
+|       <font>
+|     <font>
+|       "
+This page contains an insanely badly-nested tag sequence."
+
+#data
+<html>
+<body>
+<b><nobr><div>This text is in a div inside a nobr</nobr>More text that should not be in the nobr, i.e., the
+nobr should have closed the div inside it implicitly. </b><pre>A pre tag outside everything else.</pre>
+</body>
+</html>
+#errors
+#document
+| <html>
+|   <head>
+|   <body>
+|     "
+"
+|     <b>
+|       <nobr>
+|     <div>
+|       <b>
+|         <nobr>
+|           "This text is in a div inside a nobr"
+|         "More text that should not be in the nobr, i.e., the
+nobr should have closed the div inside it implicitly. "
+|       <pre>
+|         "A pre tag outside everything else."
+|       "
+
+"
diff --git a/html/test/data/tree-construction/webkit01.dat b/html/test/data/tree-construction/webkit01.dat
new file mode 100644
index 0000000..06bc436
--- /dev/null
+++ b/html/test/data/tree-construction/webkit01.dat
@@ -0,0 +1,594 @@
+#data
+Test
+#errors
+Line: 1 Col: 4 Unexpected non-space characters. Expected DOCTYPE.
+#document
+| <html>
+|   <head>
+|   <body>
+|     "Test"
+
+#data
+<div></div>
+#errors
+#document
+| <html>
+|   <head>
+|   <body>
+|     <div>
+
+#data
+<div>Test</div>
+#errors
+#document
+| <html>
+|   <head>
+|   <body>
+|     <div>
+|       "Test"
+
+#data
+<di
+#errors
+#document
+| <html>
+|   <head>
+|   <body>
+
+#data
+<div>Hello</div>
+<script>
+console.log("PASS");
+</script>
+<div>Bye</div>
+#errors
+#document
+| <html>
+|   <head>
+|   <body>
+|     <div>
+|       "Hello"
+|     "
+"
+|     <script>
+|       "
+console.log("PASS");
+"
+|     "
+"
+|     <div>
+|       "Bye"
+
+#data
+<div foo="bar">Hello</div>
+#errors
+#document
+| <html>
+|   <head>
+|   <body>
+|     <div>
+|       foo="bar"
+|       "Hello"
+
+#data
+<div>Hello</div>
+<script>
+console.log("FOO<span>BAR</span>BAZ");
+</script>
+<div>Bye</div>
+#errors
+#document
+| <html>
+|   <head>
+|   <body>
+|     <div>
+|       "Hello"
+|     "
+"
+|     <script>
+|       "
+console.log("FOO<span>BAR</span>BAZ");
+"
+|     "
+"
+|     <div>
+|       "Bye"
+
+#data
+<foo bar="baz"></foo><potato quack="duck"></potato>
+#errors
+#document
+| <html>
+|   <head>
+|   <body>
+|     <foo>
+|       bar="baz"
+|     <potato>
+|       quack="duck"
+
+#data
+<foo bar="baz"><potato quack="duck"></potato></foo>
+#errors
+#document
+| <html>
+|   <head>
+|   <body>
+|     <foo>
+|       bar="baz"
+|       <potato>
+|         quack="duck"
+
+#data
+<foo></foo bar="baz"><potato></potato quack="duck">
+#errors
+#document
+| <html>
+|   <head>
+|   <body>
+|     <foo>
+|     <potato>
+
+#data
+</ tttt>
+#errors
+#document
+| <!--  tttt -->
+| <html>
+|   <head>
+|   <body>
+
+#data
+<div FOO ><img><img></div>
+#errors
+#document
+| <html>
+|   <head>
+|   <body>
+|     <div>
+|       foo=""
+|       <img>
+|       <img>
+
+#data
+<p>Test</p<p>Test2</p>
+#errors
+#document
+| <html>
+|   <head>
+|   <body>
+|     <p>
+|       "TestTest2"
+
+#data
+<rdar://problem/6869687>
+#errors
+#document
+| <html>
+|   <head>
+|   <body>
+|     <rdar:>
+|       6869687=""
+|       problem=""
+
+#data
+<A>test< /A>
+#errors
+#document
+| <html>
+|   <head>
+|   <body>
+|     <a>
+|       "test< /A>"
+
+#data
+&lt;
+#errors
+#document
+| <html>
+|   <head>
+|   <body>
+|     "<"
+
+#data
+<body foo='bar'><body foo='baz' yo='mama'>
+#errors
+#document
+| <html>
+|   <head>
+|   <body>
+|     foo="bar"
+|     yo="mama"
+
+#data
+<body></br foo="bar"></body>
+#errors
+#document
+| <html>
+|   <head>
+|   <body>
+|     <br>
+
+#data
+<bdy><br foo="bar"></body>
+#errors
+#document
+| <html>
+|   <head>
+|   <body>
+|     <bdy>
+|       <br>
+|         foo="bar"
+
+#data
+<body></body></br foo="bar">
+#errors
+#document
+| <html>
+|   <head>
+|   <body>
+|     <br>
+
+#data
+<bdy></body><br foo="bar">
+#errors
+#document
+| <html>
+|   <head>
+|   <body>
+|     <bdy>
+|       <br>
+|         foo="bar"
+
+#data
+<html><body></body></html><!-- Hi there -->
+#errors
+#document
+| <html>
+|   <head>
+|   <body>
+| <!--  Hi there  -->
+
+#data
+<html><body></body></html>x<!-- Hi there -->
+#errors
+#document
+| <html>
+|   <head>
+|   <body>
+|     "x"
+|     <!--  Hi there  -->
+
+#data
+<html><body></body></html>x<!-- Hi there --></html><!-- Again -->
+#errors
+#document
+| <html>
+|   <head>
+|   <body>
+|     "x"
+|     <!--  Hi there  -->
+| <!--  Again  -->
+
+#data
+<html><body></body></html>x<!-- Hi there --></body></html><!-- Again -->
+#errors
+#document
+| <html>
+|   <head>
+|   <body>
+|     "x"
+|     <!--  Hi there  -->
+| <!--  Again  -->
+
+#data
+<html><body><ruby><div><rp>xx</rp></div></ruby></body></html>
+#errors
+#document
+| <html>
+|   <head>
+|   <body>
+|     <ruby>
+|       <div>
+|         <rp>
+|           "xx"
+
+#data
+<html><body><ruby><div><rt>xx</rt></div></ruby></body></html>
+#errors
+#document
+| <html>
+|   <head>
+|   <body>
+|     <ruby>
+|       <div>
+|         <rt>
+|           "xx"
+
+#data
+<html><frameset><!--1--><noframes>A</noframes><!--2--></frameset><!--3--><noframes>B</noframes><!--4--></html><!--5--><noframes>C</noframes><!--6-->
+#errors
+#document
+| <html>
+|   <head>
+|   <frameset>
+|     <!-- 1 -->
+|     <noframes>
+|       "A"
+|     <!-- 2 -->
+|   <!-- 3 -->
+|   <noframes>
+|     "B"
+|   <!-- 4 -->
+|   <noframes>
+|     "C"
+| <!-- 5 -->
+| <!-- 6 -->
+
+#data
+<select><option>A<select><option>B<select><option>C<select><option>D<select><option>E<select><option>F<select><option>G<select>
+#errors
+#document
+| <html>
+|   <head>
+|   <body>
+|     <select>
+|       <option>
+|         "A"
+|     <option>
+|       "B"
+|       <select>
+|         <option>
+|           "C"
+|     <option>
+|       "D"
+|       <select>
+|         <option>
+|           "E"
+|     <option>
+|       "F"
+|       <select>
+|         <option>
+|           "G"
+
+#data
+<dd><dd><dt><dt><dd><li><li>
+#errors
+#document
+| <html>
+|   <head>
+|   <body>
+|     <dd>
+|     <dd>
+|     <dt>
+|     <dt>
+|     <dd>
+|       <li>
+|       <li>
+
+#data
+<div><b></div><div><nobr>a<nobr>
+#errors
+#document
+| <html>
+|   <head>
+|   <body>
+|     <div>
+|       <b>
+|     <div>
+|       <b>
+|         <nobr>
+|           "a"
+|         <nobr>
+
+#data
+<head></head>
+<body></body>
+#errors
+#document
+| <html>
+|   <head>
+|   "
+"
+|   <body>
+
+#data
+<head></head> <style></style>ddd
+#errors
+#document
+| <html>
+|   <head>
+|     <style>
+|   " "
+|   <body>
+|     "ddd"
+
+#data
+<kbd><table></kbd><col><select><tr>
+#errors
+#document
+| <html>
+|   <head>
+|   <body>
+|     <kbd>
+|       <select>
+|       <table>
+|         <colgroup>
+|           <col>
+|         <tbody>
+|           <tr>
+
+#data
+<kbd><table></kbd><col><select><tr></table><div>
+#errors
+#document
+| <html>
+|   <head>
+|   <body>
+|     <kbd>
+|       <select>
+|       <table>
+|         <colgroup>
+|           <col>
+|         <tbody>
+|           <tr>
+|       <div>
+
+#data
+<a><li><style></style><title></title></a>
+#errors
+#document
+| <html>
+|   <head>
+|   <body>
+|     <a>
+|     <li>
+|       <a>
+|         <style>
+|         <title>
+
+#data
+<font></p><p><meta><title></title></font>
+#errors
+#document
+| <html>
+|   <head>
+|   <body>
+|     <font>
+|       <p>
+|     <p>
+|       <font>
+|         <meta>
+|         <title>
+
+#data
+<a><center><title></title><a>
+#errors
+#document
+| <html>
+|   <head>
+|   <body>
+|     <a>
+|     <center>
+|       <a>
+|         <title>
+|       <a>
+
+#data
+<svg><title><div>
+#errors
+#document
+| <html>
+|   <head>
+|   <body>
+|     <svg svg>
+|       <svg title>
+|         <div>
+
+#data
+<svg><title><rect><div>
+#errors
+#document
+| <html>
+|   <head>
+|   <body>
+|     <svg svg>
+|       <svg title>
+|         <rect>
+|           <div>
+
+#data
+<svg><title><svg><div>
+#errors
+#document
+| <html>
+|   <head>
+|   <body>
+|     <svg svg>
+|       <svg title>
+|         <svg svg>
+|         <div>
+
+#data
+<img <="" FAIL>
+#errors
+#document
+| <html>
+|   <head>
+|   <body>
+|     <img>
+|       <=""
+|       fail=""
+
+#data
+<ul><li><div id='foo'/>A</li><li>B<div>C</div></li></ul>
+#errors
+#document
+| <html>
+|   <head>
+|   <body>
+|     <ul>
+|       <li>
+|         <div>
+|           id="foo"
+|           "A"
+|       <li>
+|         "B"
+|         <div>
+|           "C"
+
+#data
+<svg><em><desc></em>
+#errors
+#document
+| <html>
+|   <head>
+|   <body>
+|     <svg svg>
+|     <em>
+|       <desc>
+
+#data
+<svg><tfoot></mi><td>
+#errors
+#document
+| <html>
+|   <head>
+|   <body>
+|     <svg svg>
+|       <svg tfoot>
+|         <svg td>
+
+#data
+<math><mrow><mrow><mn>1</mn></mrow><mi>a</mi></mrow></math>
+#errors
+#document
+| <html>
+|   <head>
+|   <body>
+|     <math math>
+|       <math mrow>
+|         <math mrow>
+|           <math mn>
+|             "1"
+|         <math mi>
+|           "a"
+
+#data
+<!doctype html><input type="hidden"><frameset>
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <frameset>
+
+#data
+<!doctype html><input type="button"><frameset>
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     <input>
+|       type="button"
diff --git a/html/test/data/tree-construction/webkit02.dat b/html/test/data/tree-construction/webkit02.dat
new file mode 100644
index 0000000..468879b
--- /dev/null
+++ b/html/test/data/tree-construction/webkit02.dat
@@ -0,0 +1,94 @@
+#data
+<foo bar=qux/>
+#errors
+#document
+| <html>
+|   <head>
+|   <body>
+|     <foo>
+|       bar="qux/"
+
+#data
+<p id="status"><noscript><strong>A</strong></noscript><span>B</span></p>
+#errors
+#document
+| <html>
+|   <head>
+|   <body>
+|     <p>
+|       id="status"
+|       <noscript>
+|         "<strong>A</strong>"
+|       <span>
+|         "B"
+
+#data
+<div><sarcasm><div></div></sarcasm></div>
+#errors
+#document
+| <html>
+|   <head>
+|   <body>
+|     <div>
+|       <sarcasm>
+|         <div>
+
+#data
+<html><body><img src="" border="0" alt="><div>A</div></body></html>
+#errors
+#document
+| <html>
+|   <head>
+|   <body>
+
+#data
+<table><td></tbody>A
+#errors
+#document
+| <html>
+|   <head>
+|   <body>
+|     "A"
+|     <table>
+|       <tbody>
+|         <tr>
+|           <td>
+
+#data
+<table><td></thead>A
+#errors
+#document
+| <html>
+|   <head>
+|   <body>
+|     <table>
+|       <tbody>
+|         <tr>
+|           <td>
+|             "A"
+
+#data
+<table><td></tfoot>A
+#errors
+#document
+| <html>
+|   <head>
+|   <body>
+|     <table>
+|       <tbody>
+|         <tr>
+|           <td>
+|             "A"
+
+#data
+<table><thead><td></tbody>A
+#errors
+#document
+| <html>
+|   <head>
+|   <body>
+|     <table>
+|       <thead>
+|         <tr>
+|           <td>
+|             "A"
diff --git a/html/test/dom_test.dart b/html/test/dom_test.dart
new file mode 100644
index 0000000..404a488
--- /dev/null
+++ b/html/test/dom_test.dart
@@ -0,0 +1,190 @@
+/// Additional feature tests that aren't based on test data.
+library dom_test;
+
+import 'package:unittest/unittest.dart';
+import 'package:html/dom.dart';
+import 'package:html/parser.dart';
+
+main() {
+  group('Element', () {
+    test('classes', () {
+      final barBaz = new Element.html('<div class=" bar baz"></div>');
+      final quxBaz = new Element.html('<div class="qux  baz "></div>');
+      expect(barBaz.className, ' bar baz');
+      expect(quxBaz.className, 'qux  baz ');
+      expect(barBaz.classes, ['bar', 'baz']);
+      expect(quxBaz.classes, ['qux', 'baz']);
+    });
+  });
+
+  group('Document', () {
+    final doc = parse('<div id=foo>'
+        '<div class=" bar baz"></div>'
+        '<div class="qux  baz "></div>'
+        '<div id=Foo>');
+
+    test('getElementById', () {
+      var foo = doc.body.nodes[0];
+      var Foo = foo.nodes[2];
+      expect((foo as Element).id, 'foo');
+      expect((Foo as Element).id, 'Foo');
+      expect(doc.getElementById('foo'), foo);
+      expect(doc.getElementById('Foo'), Foo);
+    });
+
+    test('getElementsByClassName', () {
+      var foo = doc.body.nodes[0];
+      var barBaz = foo.nodes[0];
+      var quxBaz = foo.nodes[1];
+      expect((barBaz as Element).className, ' bar baz');
+      expect((quxBaz as Element).className, 'qux  baz ');
+      expect(doc.getElementsByClassName('baz'), [barBaz, quxBaz]);
+      expect(doc.getElementsByClassName('bar '), [barBaz]);
+      expect(doc.getElementsByClassName('  qux'), [quxBaz]);
+      expect(doc.getElementsByClassName(' baz qux'), [quxBaz]);
+    });
+
+    test('getElementsByTagName', () {
+      var foo = doc.body.nodes[0];
+      var barBaz = foo.nodes[0];
+      var quxBaz = foo.nodes[1];
+      var Foo = foo.nodes[2];
+      expect(doc.getElementsByTagName('div'), [foo, barBaz, quxBaz, Foo]);
+    });
+  });
+
+  group('fragments are flattened', () {
+    test('add', () {
+      var doc = parse('<body>');
+      doc.body.nodes.add(parseFragment('<x-foo>'));
+      expect((doc.body.nodes[0] as Element).localName, 'x-foo');
+      doc.body.nodes.add(parseFragment('<x-bar>'));
+      expect((doc.body.nodes[1] as Element).localName, 'x-bar');
+    });
+
+    test('addLast', () {
+      var doc = parse('<body>');
+      doc.body.nodes.addLast(parseFragment('<x-foo>'));
+      expect((doc.body.nodes[0] as Element).localName, 'x-foo');
+      doc.body.nodes.addLast(parseFragment('<x-bar>'));
+      expect((doc.body.nodes[1] as Element).localName, 'x-bar');
+    });
+
+    test('addAll', () {
+      var doc = parse('<body><x-a></x-a>');
+      doc.body.nodes.addAll([parseFragment('<x-b></x-b><x-c></x-c>')]);
+      expect((doc.body.nodes[0] as Element).localName, 'x-a');
+      expect((doc.body.nodes[1] as Element).localName, 'x-b');
+      expect((doc.body.nodes[2] as Element).localName, 'x-c');
+    });
+
+    test('insert', () {
+      var doc = parse('<body><x-a></x-a>');
+      doc.body.nodes.insert(0, parseFragment('<x-b></x-b><x-c></x-c>'));
+      expect((doc.body.nodes[0] as Element).localName, 'x-b');
+      expect((doc.body.nodes[1] as Element).localName, 'x-c');
+      expect((doc.body.nodes[2] as Element).localName, 'x-a');
+
+      doc = parse('<body><x-a></x-a>');
+      doc.body.nodes.insert(1, parseFragment('<x-b></x-b><x-c></x-c>'));
+      expect((doc.body.nodes[0] as Element).localName, 'x-a');
+      expect((doc.body.nodes[1] as Element).localName, 'x-b');
+      expect((doc.body.nodes[2] as Element).localName, 'x-c');
+
+      doc = parse('<body><x-a></x-a>');
+      doc.body.nodes.insert(0, parseFragment('<x-b></x-b>'));
+      doc.body.nodes.insert(1, parseFragment('<x-c></x-c>'));
+      expect((doc.body.nodes[0] as Element).localName, 'x-b');
+      expect((doc.body.nodes[1] as Element).localName, 'x-c');
+      expect((doc.body.nodes[2] as Element).localName, 'x-a');
+    });
+
+    test('insertAll', () {
+      var doc = parse('<body><x-a></x-a>');
+      doc.body.nodes.insertAll(0, [parseFragment('<x-b></x-b><x-c></x-c>')]);
+      expect((doc.body.nodes[0] as Element).localName, 'x-b');
+      expect((doc.body.nodes[1] as Element).localName, 'x-c');
+      expect((doc.body.nodes[2] as Element).localName, 'x-a');
+      expect(doc.body.nodes.length, 3);
+
+      doc = parse('<body><x-a></x-a>');
+      doc.body.nodes.insertAll(1, [parseFragment('<x-b></x-b><x-c></x-c>')]);
+      expect((doc.body.nodes[0] as Element).localName, 'x-a');
+      expect((doc.body.nodes[1] as Element).localName, 'x-b');
+      expect((doc.body.nodes[2] as Element).localName, 'x-c');
+
+      doc = parse('<body><x-a></x-a>');
+      doc.body.nodes.insertAll(0, [parseFragment('<x-b></x-b>')]);
+      doc.body.nodes.insertAll(1, [parseFragment('<x-c></x-c>')]);
+      expect((doc.body.nodes[0] as Element).localName, 'x-b');
+      expect((doc.body.nodes[1] as Element).localName, 'x-c');
+      expect((doc.body.nodes[2] as Element).localName, 'x-a');
+    });
+
+    test('operator []=', () {
+      var doc = parse('<body><x-a></x-a>');
+      doc.body.nodes[0] = parseFragment('<x-b></x-b><x-c></x-c>');
+      expect((doc.body.nodes[0] as Element).localName, 'x-b');
+      expect((doc.body.nodes[1] as Element).localName, 'x-c');
+      expect(doc.body.nodes.length, 2);
+
+      doc = parse('<body><x-a></x-a><x-b></x-b><x-c></x-c>');
+      doc.body.nodes[1] = parseFragment('<y-b></y-b><y-c></y-c>');
+      expect((doc.body.nodes[0] as Element).localName, 'x-a');
+      expect((doc.body.nodes[1] as Element).localName, 'y-b');
+      expect((doc.body.nodes[2] as Element).localName, 'y-c');
+      expect((doc.body.nodes[3] as Element).localName, 'x-c');
+      expect(doc.body.nodes.length, 4);
+    });
+
+    test('setRange', () {
+      var fragment = parseFragment('<y-b></y-b><y-c></y-c>');
+      var doc = parse('<body><x-a></x-a><x-b></x-b><x-c></x-c>');
+      doc.body.nodes.setRange(1, 2, fragment.nodes, 0);
+      expect((doc.body.nodes[0] as Element).localName, 'x-a');
+      expect((doc.body.nodes[1] as Element).localName, 'y-b');
+      expect((doc.body.nodes[2] as Element).localName, 'y-c');
+      expect(doc.body.nodes.length, 3);
+
+      fragment = parseFragment('<y-b></y-b><y-c></y-c>');
+      doc = parse('<body><x-a></x-a><x-b></x-b><x-c></x-c>');
+      doc.body.nodes.setRange(1, 1, [fragment], 0);
+      expect((doc.body.nodes[0] as Element).localName, 'x-a');
+      expect((doc.body.nodes[1] as Element).localName, 'y-b');
+      expect((doc.body.nodes[2] as Element).localName, 'y-c');
+      expect((doc.body.nodes[3] as Element).localName, 'x-c');
+      expect(doc.body.nodes.length, 4);
+    });
+
+    test('replaceRange', () {
+      var fragment = parseFragment('<y-b></y-b><y-c></y-c>');
+      var doc = parse('<body><x-a></x-a><x-b></x-b><x-c></x-c>');
+      doc.body.nodes.replaceRange(1, 2, fragment.nodes);
+      expect((doc.body.nodes[0] as Element).localName, 'x-a');
+      expect((doc.body.nodes[1] as Element).localName, 'y-b');
+      expect((doc.body.nodes[2] as Element).localName, 'y-c');
+      expect((doc.body.nodes[3] as Element).localName, 'x-c');
+      expect(doc.body.nodes.length, 4);
+
+      fragment = parseFragment('<y-b></y-b><y-c></y-c>');
+      doc = parse('<body><x-a></x-a><x-b></x-b><x-c></x-c>');
+      doc.body.nodes.replaceRange(1, 2, [fragment]);
+      expect((doc.body.nodes[0] as Element).localName, 'x-a');
+      expect((doc.body.nodes[1] as Element).localName, 'y-b');
+      expect((doc.body.nodes[2] as Element).localName, 'y-c');
+      expect((doc.body.nodes[3] as Element).localName, 'x-c');
+      expect(doc.body.nodes.length, 4);
+    });
+
+    test('replaceWith', () {
+      var fragment = parseFragment('<y-b></y-b><y-c></y-c>');
+      var doc = parse('<body><x-a></x-a><x-b></x-b><x-c></x-c>');
+      doc.body.nodes[1].replaceWith(fragment);
+      expect((doc.body.nodes[0] as Element).localName, 'x-a');
+      expect((doc.body.nodes[1] as Element).localName, 'y-b');
+      expect((doc.body.nodes[2] as Element).localName, 'y-c');
+      expect((doc.body.nodes[3] as Element).localName, 'x-c');
+      expect(doc.body.nodes.length, 4);
+    });
+  });
+}
diff --git a/html/test/parser_feature_test.dart b/html/test/parser_feature_test.dart
new file mode 100644
index 0000000..43a3426
--- /dev/null
+++ b/html/test/parser_feature_test.dart
@@ -0,0 +1,476 @@
+/// Additional feature tests that aren't based on test data.
+library parser_feature_test;
+
+import 'package:unittest/unittest.dart';
+import 'package:html/dom.dart';
+import 'package:html/parser.dart';
+import 'package:html/src/constants.dart';
+import 'package:html/src/encoding_parser.dart';
+import 'package:html/src/treebuilder.dart';
+import 'package:source_span/source_span.dart';
+
+main() {
+  _testElementSpans();
+  test('doctype is cloneable', () {
+    var doc = parse('<!doctype HTML>');
+    DocumentType doctype = doc.nodes[0];
+    expect(doctype.clone(false).toString(), '<!DOCTYPE html>');
+  });
+
+  test('line counter', () {
+    // http://groups.google.com/group/html5lib-discuss/browse_frm/thread/f4f00e4a2f26d5c0
+    var doc = parse("<pre>\nx\n&gt;\n</pre>");
+    expect(doc.body.innerHtml, "<pre>x\n&gt;\n</pre>");
+  });
+
+  test('namespace html elements on', () {
+    var doc = new HtmlParser('', tree: new TreeBuilder(true)).parse();
+    expect((doc.nodes[0] as Element).namespaceUri, Namespaces.html);
+  });
+
+  test('namespace html elements off', () {
+    var doc = new HtmlParser('', tree: new TreeBuilder(false)).parse();
+    expect((doc.nodes[0] as Element).namespaceUri, null);
+  });
+
+  test('parse error spans - full', () {
+    var parser = new HtmlParser('''
+<!DOCTYPE html>
+<html>
+  <body>
+  <!DOCTYPE html>
+  </body>
+</html>
+''', generateSpans: true, sourceUrl: 'ParseError');
+    var doc = parser.parse();
+    expect(doc.body.outerHtml, '<body>\n  \n  \n\n</body>');
+    expect(parser.errors.length, 1);
+    ParseError error = parser.errors[0];
+    expect(error.errorCode, 'unexpected-doctype');
+
+    // Note: these values are 0-based, but the printed format is 1-based.
+    expect(error.span.start.line, 3);
+    expect(error.span.end.line, 3);
+    expect(error.span.start.column, 2);
+    expect(error.span.end.column, 17);
+    expect(error.span.text, '<!DOCTYPE html>');
+
+    expect(error.toString(), '''
+On line 4, column 3 of ParseError: Unexpected DOCTYPE. Ignored.
+  <!DOCTYPE html>
+  ^^^^^^^^^^^^^^^''');
+  });
+
+  test('parse error spans - minimal', () {
+    var parser = new HtmlParser('''
+<!DOCTYPE html>
+<html>
+  <body>
+  <!DOCTYPE html>
+  </body>
+</html>
+''');
+    var doc = parser.parse();
+    expect(doc.body.outerHtml, '<body>\n  \n  \n\n</body>');
+    expect(parser.errors.length, 1);
+    ParseError error = parser.errors[0];
+    expect(error.errorCode, 'unexpected-doctype');
+    expect(error.span.start.line, 3);
+    // Note: error position is at the end, not the beginning
+    expect(error.span.start.column, 17);
+  });
+
+  test('text spans should have the correct length', () {
+    var textContent = '\n  hello {{name}}';
+    var html = '<body><div>$textContent</div>';
+    var doc = parse(html, generateSpans: true);
+    Text text = doc.body.nodes[0].nodes[0];
+    expect(text, new isInstanceOf<Text>());
+    expect(text.data, textContent);
+    expect(text.sourceSpan.start.offset, html.indexOf(textContent));
+    expect(text.sourceSpan.length, textContent.length);
+  });
+
+  test('attribute spans', () {
+    var text = '<element name="x-foo" extends="x-bar" constructor="Foo">';
+    var doc = parse(text, generateSpans: true);
+    var elem = doc.querySelector('element');
+    expect(elem.sourceSpan.start.offset, 0);
+    expect(elem.sourceSpan.end.offset, text.length);
+    expect(elem.sourceSpan.text, text);
+
+    expect(elem.attributeSpans['quux'], null);
+
+    var span = elem.attributeSpans['extends'];
+    expect(span.start.offset, text.indexOf('extends'));
+    expect(span.text, 'extends="x-bar"');
+  });
+
+  test('attribute value spans', () {
+    var text = '<element name="x-foo" extends="x-bar" constructor="Foo">';
+    var doc = parse(text, generateSpans: true);
+    var elem = doc.querySelector('element');
+
+    expect(elem.attributeValueSpans['quux'], null);
+
+    var span = elem.attributeValueSpans['extends'];
+    expect(span.start.offset, text.indexOf('x-bar'));
+    expect(span.text, 'x-bar');
+  });
+
+  test('attribute spans if no attributes', () {
+    var text = '<element>';
+    var doc = parse(text, generateSpans: true);
+    var elem = doc.querySelector('element');
+
+    expect(elem.attributeSpans['quux'], null);
+    expect(elem.attributeValueSpans['quux'], null);
+  });
+
+  test('attribute spans if no attribute value', () {
+    var text = '<foo template>';
+    var doc = parse(text, generateSpans: true);
+    var elem = doc.querySelector('foo');
+
+    expect(
+        elem.attributeSpans['template'].start.offset, text.indexOf('template'));
+    expect(elem.attributeValueSpans.containsKey('template'), false);
+  });
+
+  test('attribute spans null if code parsed without spans', () {
+    var text = '<element name="x-foo" extends="x-bar" constructor="Foo">';
+    var doc = parse(text);
+    var elem = doc.querySelector('element');
+    expect(elem.sourceSpan, null);
+    expect(elem.attributeSpans['quux'], null);
+    expect(elem.attributeSpans['extends'], null);
+  });
+
+  test('void element innerHTML', () {
+    var doc = parse('<div></div>');
+    expect(doc.body.innerHtml, '<div></div>');
+    doc = parse('<body><script></script></body>');
+    expect(doc.body.innerHtml, '<script></script>');
+    doc = parse('<br>');
+    expect(doc.body.innerHtml, '<br>');
+    doc = parse('<br><foo><bar>');
+    expect(doc.body.innerHtml, '<br><foo><bar></bar></foo>');
+  });
+
+  test('empty document has html, body, and head', () {
+    var doc = parse('');
+    var html = '<html><head></head><body></body></html>';
+    expect(doc.outerHtml, html);
+    expect(doc.documentElement.outerHtml, html);
+    expect(doc.head.outerHtml, '<head></head>');
+    expect(doc.body.outerHtml, '<body></body>');
+  });
+
+  test('strange table case', () {
+    var doc = parse('<table><tbody><foo>').body;
+    expect(doc.innerHtml, '<foo></foo><table><tbody></tbody></table>');
+  });
+
+  group('html serialization', () {
+    test('attribute order', () {
+      // Note: the spec only requires a stable order.
+      // However, we preserve the input order via LinkedHashMap
+      var body = parse('<foo d=1 a=2 c=3 b=4>').body;
+      expect(body.innerHtml, '<foo d="1" a="2" c="3" b="4"></foo>');
+      expect(body.querySelector('foo').attributes.remove('a'), '2');
+      expect(body.innerHtml, '<foo d="1" c="3" b="4"></foo>');
+      body.querySelector('foo').attributes['a'] = '0';
+      expect(body.innerHtml, '<foo d="1" c="3" b="4" a="0"></foo>');
+    });
+
+    test('escaping Text node in <script>', () {
+      Element e = parseFragment('<script>a && b</script>').firstChild;
+      expect(e.outerHtml, '<script>a && b</script>');
+    });
+
+    test('escaping Text node in <span>', () {
+      Element e = parseFragment('<span>a && b</span>').firstChild;
+      expect(e.outerHtml, '<span>a &amp;&amp; b</span>');
+    });
+
+    test('Escaping attributes', () {
+      Element e = parseFragment('<div class="a<b>">').firstChild;
+      expect(e.outerHtml, '<div class="a<b>"></div>');
+      e = parseFragment('<div class=\'a"b\'>').firstChild;
+      expect(e.outerHtml, '<div class="a&quot;b"></div>');
+    });
+
+    test('Escaping non-breaking space', () {
+      var text = '<span>foO\u00A0bar</span>';
+      expect(text.codeUnitAt(text.indexOf('O') + 1), 0xA0);
+      Element e = parseFragment(text).firstChild;
+      expect(e.outerHtml, '<span>foO&nbsp;bar</span>');
+    });
+
+    test('Newline after <pre>', () {
+      Element e = parseFragment('<pre>\n\nsome text</span>').firstChild;
+      expect((e.firstChild as Text).data, '\nsome text');
+      expect(e.outerHtml, '<pre>\n\nsome text</pre>');
+
+      e = parseFragment('<pre>\nsome text</span>').firstChild;
+      expect((e.firstChild as Text).data, 'some text');
+      expect(e.outerHtml, '<pre>some text</pre>');
+    });
+
+    test('xml namespaces', () {
+      // Note: this is a nonsensical example, but it triggers the behavior
+      // we're looking for with attribute names in foreign content.
+      var doc = parse('''
+        <body>
+        <svg>
+        <desc xlink:type="simple"
+              xlink:href="http://example.com/logo.png"
+              xlink:show="new"></desc>
+      ''');
+      var n = doc.querySelector('desc');
+      var keys = n.attributes.keys.toList();
+      expect(keys[0], new isInstanceOf<AttributeName>());
+      expect(keys[0].prefix, 'xlink');
+      expect(keys[0].namespace, 'http://www.w3.org/1999/xlink');
+      expect(keys[0].name, 'type');
+
+      expect(n.outerHtml, '<desc xlink:type="simple" '
+          'xlink:href="http://example.com/logo.png" xlink:show="new"></desc>');
+    });
+  });
+
+  test('error printing without spans', () {
+    var parser = new HtmlParser('foo');
+    var doc = parser.parse();
+    expect(doc.body.innerHtml, 'foo');
+    expect(parser.errors.length, 1);
+    expect(parser.errors[0].errorCode, 'expected-doctype-but-got-chars');
+    expect(parser.errors[0].message,
+        'Unexpected non-space characters. Expected DOCTYPE.');
+    expect(parser.errors[0].toString(),
+        'ParserError on line 1, column 4: Unexpected non-space characters. '
+        'Expected DOCTYPE.\n'
+        'foo\n'
+        '   ^');
+  });
+
+  test('Element.text', () {
+    var doc = parseFragment('<div>foo<div>bar</div>baz</div>');
+    var e = doc.firstChild;
+    var text = e.firstChild;
+    expect((text as Text).data, 'foo');
+    expect(e.text, 'foobarbaz');
+
+    e.text = 'FOO';
+    expect(e.nodes.length, 1);
+    expect(e.firstChild, isNot(text), reason: 'should create a new tree');
+    expect((e.firstChild as Text).data, 'FOO');
+    expect(e.text, 'FOO');
+  });
+
+  test('Text.text', () {
+    var doc = parseFragment('<div>foo<div>bar</div>baz</div>');
+    var e = doc.firstChild;
+    Text text = e.firstChild;
+    expect(text.data, 'foo');
+    expect(text.text, 'foo');
+
+    text.text = 'FOO';
+    expect(text.data, 'FOO');
+    expect(e.text, 'FOObarbaz');
+    expect(text.text, 'FOO');
+  });
+
+  test('Comment.text', () {
+    var doc = parseFragment('<div><!--foo-->bar</div>');
+    var e = doc.firstChild;
+    var c = e.firstChild;
+    expect((c as Comment).data, 'foo');
+    expect(c.text, 'foo');
+    expect(e.text, 'bar');
+
+    c.text = 'qux';
+    expect((c as Comment).data, 'qux');
+    expect(c.text, 'qux');
+    expect(e.text, 'bar');
+  });
+
+  test('foreignObject end tag', () {
+    var p = new HtmlParser('''
+<svg width="100%" height="100%" xmlns="http://www.w3.org/2000/svg"
+     version="1.1">
+    <foreignObject width="320px" height="200px">
+        <x-flow></x-flow>
+    </foreignObject>
+</svg>''');
+    var doc = p.parseFragment();
+    expect(p.errors, isEmpty);
+    var svg = doc.querySelector('svg');
+    expect(svg.children[0].children[0].localName, 'x-flow');
+  });
+
+  group('Encoding pre-parser', () {
+    getEncoding(String s) => new EncodingParser(s.codeUnits).getEncoding();
+
+    test('gets encoding from meta charset', () {
+      expect(getEncoding('<meta charset="utf-16">'), 'utf-16');
+    });
+
+    test('gets encoding from meta in head', () {
+      expect(getEncoding('<head><meta charset="utf-16">'), 'utf-16');
+    });
+
+    test('skips comments', () {
+      expect(getEncoding('<!--comment--><meta charset="utf-16">'), 'utf-16');
+    });
+
+    test('stops if no match', () {
+      // missing closing tag
+      expect(getEncoding('<meta charset="utf-16"'), null);
+    });
+
+    test('ignores whitespace', () {
+      expect(getEncoding('  <meta charset="utf-16">'), 'utf-16');
+    });
+  });
+}
+
+_testElementSpans() {
+  assertSpan(SourceSpan span, int offset, int end, String text) {
+    expect(span, isNotNull);
+    expect(span.start.offset, offset);
+    expect(span.end.offset, end);
+    expect(span.text, text);
+  }
+
+  group('element spans', () {
+    test('html and body', () {
+      var text = '<html><body>123</body></html>';
+      var doc = parse(text, generateSpans: true);
+      {
+        var elem = doc.querySelector('html');
+        assertSpan(elem.sourceSpan, 0, 6, '<html>');
+        assertSpan(elem.endSourceSpan, 22, 29, '</html>');
+      }
+      {
+        var elem = doc.querySelector('body');
+        assertSpan(elem.sourceSpan, 6, 12, '<body>');
+        assertSpan(elem.endSourceSpan, 15, 22, '</body>');
+      }
+    });
+
+    test('normal', () {
+      var text = '<div><element><span></span></element></div>';
+      var doc = parse(text, generateSpans: true);
+      var elem = doc.querySelector('element');
+      assertSpan(elem.sourceSpan, 5, 14, '<element>');
+      assertSpan(elem.endSourceSpan, 27, 37, '</element>');
+    });
+
+    test('block', () {
+      var text = '<div>123</div>';
+      var doc = parse(text, generateSpans: true);
+      var elem = doc.querySelector('div');
+      assertSpan(elem.sourceSpan, 0, 5, '<div>');
+      assertSpan(elem.endSourceSpan, 8, 14, '</div>');
+    });
+
+    test('form', () {
+      var text = '<form>123</form>';
+      var doc = parse(text, generateSpans: true);
+      var elem = doc.querySelector('form');
+      assertSpan(elem.sourceSpan, 0, 6, '<form>');
+      assertSpan(elem.endSourceSpan, 9, 16, '</form>');
+    });
+
+    test('p explicit end', () {
+      var text = '<p>123</p>';
+      var doc = parse(text, generateSpans: true);
+      var elem = doc.querySelector('p');
+      assertSpan(elem.sourceSpan, 0, 3, '<p>');
+      assertSpan(elem.endSourceSpan, 6, 10, '</p>');
+    });
+
+    test('p implicit end', () {
+      var text = '<div><p>123<p>456</div>';
+      var doc = parse(text, generateSpans: true);
+      var elem = doc.querySelector('p');
+      assertSpan(elem.sourceSpan, 5, 8, '<p>');
+      expect(elem.endSourceSpan, isNull);
+    });
+
+    test('li', () {
+      var text = '<li>123</li>';
+      var doc = parse(text, generateSpans: true);
+      var elem = doc.querySelector('li');
+      assertSpan(elem.sourceSpan, 0, 4, '<li>');
+      assertSpan(elem.endSourceSpan, 7, 12, '</li>');
+    });
+
+    test('heading', () {
+      var text = '<h1>123</h1>';
+      var doc = parse(text, generateSpans: true);
+      var elem = doc.querySelector('h1');
+      assertSpan(elem.sourceSpan, 0, 4, '<h1>');
+      assertSpan(elem.endSourceSpan, 7, 12, '</h1>');
+    });
+
+    test('formatting', () {
+      var text = '<b>123</b>';
+      var doc = parse(text, generateSpans: true);
+      var elem = doc.querySelector('b');
+      assertSpan(elem.sourceSpan, 0, 3, '<b>');
+      assertSpan(elem.endSourceSpan, 6, 10, '</b>');
+    });
+
+    test('table tbody', () {
+      var text = '<table><tbody>  </tbody></table>';
+      var doc = parse(text, generateSpans: true);
+      {
+        var elem = doc.querySelector('tbody');
+        assertSpan(elem.sourceSpan, 7, 14, '<tbody>');
+        assertSpan(elem.endSourceSpan, 16, 24, '</tbody>');
+      }
+    });
+
+    test('table tr td', () {
+      var text = '<table><tr><td>123</td></tr></table>';
+      var doc = parse(text, generateSpans: true);
+      {
+        var elem = doc.querySelector('table');
+        assertSpan(elem.sourceSpan, 0, 7, '<table>');
+        assertSpan(elem.endSourceSpan, 28, 36, '</table>');
+      }
+      {
+        var elem = doc.querySelector('tr');
+        assertSpan(elem.sourceSpan, 7, 11, '<tr>');
+        assertSpan(elem.endSourceSpan, 23, 28, '</tr>');
+      }
+      {
+        var elem = doc.querySelector('td');
+        assertSpan(elem.sourceSpan, 11, 15, '<td>');
+        assertSpan(elem.endSourceSpan, 18, 23, '</td>');
+      }
+    });
+
+    test('select optgroup option', () {
+      var text = '<select><optgroup><option>123</option></optgroup></select>';
+      var doc = parse(text, generateSpans: true);
+      {
+        var elem = doc.querySelector('select');
+        assertSpan(elem.sourceSpan, 0, 8, '<select>');
+        assertSpan(elem.endSourceSpan, 49, 58, '</select>');
+      }
+      {
+        var elem = doc.querySelector('optgroup');
+        assertSpan(elem.sourceSpan, 8, 18, '<optgroup>');
+        assertSpan(elem.endSourceSpan, 38, 49, '</optgroup>');
+      }
+      {
+        var elem = doc.querySelector('option');
+        assertSpan(elem.sourceSpan, 18, 26, '<option>');
+        assertSpan(elem.endSourceSpan, 29, 38, '</option>');
+      }
+    });
+  });
+}
diff --git a/html/test/parser_test.dart b/html/test/parser_test.dart
new file mode 100644
index 0000000..6f81086
--- /dev/null
+++ b/html/test/parser_test.dart
@@ -0,0 +1,116 @@
+library parser_test;
+
+import 'dart:convert';
+import 'dart:io';
+import 'package:path/path.dart' as pathos;
+import 'package:unittest/unittest.dart';
+import 'package:html/dom.dart';
+import 'package:html/parser.dart';
+import 'package:html/parser_console.dart' as parser_console;
+import 'package:html/src/inputstream.dart' as inputstream;
+import 'support.dart';
+
+// Run the parse error checks
+// TODO(jmesserly): presumably we want this on by default?
+final checkParseErrors = false;
+
+String namespaceHtml(String expected) {
+  // TODO(jmesserly): this is a workaround for http://dartbug.com/2979
+  // We can't do regex replace directly =\
+  // final namespaceExpected = new RegExp(@"^(\s*)<(\S+)>", multiLine: true);
+  // return expected.replaceAll(namespaceExpected, @"$1<html $2>");
+  final namespaceExpected = new RegExp(r"^(\|\s*)<(\S+)>");
+  var lines = expected.split("\n");
+  for (int i = 0; i < lines.length; i++) {
+    var match = namespaceExpected.firstMatch(lines[i]);
+    if (match != null) {
+      lines[i] = "${match[1]}<html ${match[2]}>";
+    }
+  }
+  return lines.join("\n");
+}
+
+void runParserTest(String groupName, String innerHTML, String input,
+    String expected, List errors, TreeBuilderFactory treeCtor,
+    bool namespaceHTMLElements) {
+
+  // XXX - move this out into the setup function
+  // concatenate all consecutive character tokens into a single token
+  var builder = treeCtor(namespaceHTMLElements);
+  var parser = new HtmlParser(input, tree: builder);
+
+  Node document;
+  if (innerHTML != null) {
+    document = parser.parseFragment(innerHTML);
+  } else {
+    document = parser.parse();
+  }
+
+  var output = testSerializer(document);
+
+  if (namespaceHTMLElements) {
+    expected = namespaceHtml(expected);
+  }
+
+  expect(output, equals(expected),
+      reason: "\n\nInput:\n$input\n\nExpected:\n$expected\n\nReceived:\n$output");
+
+  if (checkParseErrors) {
+    expect(parser.errors.length, equals(errors.length),
+        reason: "\n\nInput:\n$input\n\nExpected errors (${errors.length}):\n"
+        "${errors.join('\n')}\n\n"
+        "Actual errors (${parser.errors.length}):\n"
+        "${parser.errors.map((e) => '$e').join('\n')}");
+  }
+}
+
+void main() {
+  test('dart:io', () {
+    // ensure IO support is unregistered
+    expect(inputstream.consoleSupport,
+        new isInstanceOf<inputstream.ConsoleSupport>());
+    var file = new File('$testDataDir/parser_feature/raw_file.html').openSync();
+    expect(() => parse(file), throwsA(new isInstanceOf<ArgumentError>()));
+    parser_console.useConsole();
+    expect(parse(file).body.innerHtml.trim(), 'Hello world!');
+  });
+
+  for (var path in getDataFiles('tree-construction')) {
+    if (!path.endsWith('.dat')) continue;
+
+    var tests = new TestData(path, "data");
+    var testName = pathos.basenameWithoutExtension(path);
+
+    group(testName, () {
+      for (var testData in tests) {
+        var input = testData['data'];
+        var errors = testData['errors'];
+        var innerHTML = testData['document-fragment'];
+        var expected = testData['document'];
+        if (errors != null) {
+          errors = errors.split("\n");
+        }
+
+        for (var treeCtor in treeTypes.values) {
+          for (var namespaceHTMLElements in const [false, true]) {
+            test(_nameFor(input), () {
+              runParserTest(testName, innerHTML, input, expected, errors,
+                  treeCtor, namespaceHTMLElements);
+            });
+          }
+        }
+      }
+    });
+  }
+}
+
+/// Extract the name for the test based on the test input data.
+_nameFor(String input) {
+  // Using JSON.decode to unescape other unicode characters
+  var escapeQuote = input
+      .replaceAll(new RegExp('\\\\.'), '_')
+      .replaceAll(new RegExp('\u0000'), '_')
+      .replaceAll('"', '\\"')
+      .replaceAll(new RegExp('[\n\r\t]'), '_');
+  return JSON.decode('"$escapeQuote"');
+}
diff --git a/html/test/run.sh b/html/test/run.sh
new file mode 100755
index 0000000..c060bd7
--- /dev/null
+++ b/html/test/run.sh
@@ -0,0 +1,22 @@
+#!/bin/bash
+# Copyright (c) 2012, the Dart project authors.  Please see the LICENSE file
+# for details. All rights reserved. Use of this source code is governed by a
+# MIT-style license that can be found in the LICENSE file.
+
+# bail on error
+set -e
+
+# TODO(sigmund): replace with a real test runner
+DIR=$( cd $( dirname "${BASH_SOURCE[0]}" ) && pwd )
+
+# Note: dart_analyzer needs to be run from the root directory for proper path
+# canonicalization.
+pushd $DIR/..
+# TODO(jmesserly): switch to new analyzer. Note: it's missing a lot of the
+# tests for implemented members; we should get that fixed before switching.
+echo Analyzing library for warnings or type errors
+dartanalyzer --fatal-warnings lib/*.dart || \
+  echo "ignore analyzer errors"
+popd
+
+dart --checked test/run_all.dart $@
diff --git a/html/test/run_all.dart b/html/test/run_all.dart
new file mode 100644
index 0000000..d2bf9ce
--- /dev/null
+++ b/html/test/run_all.dart
@@ -0,0 +1,30 @@
+#!/usr/bin/env dart
+// 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 test.run_all;
+
+import 'package:unittest/compact_vm_config.dart';
+import 'package:unittest/unittest.dart';
+
+import 'dom_test.dart' as dom_test;
+import 'parser_feature_test.dart' as parser_feature_test;
+import 'parser_test.dart' as parser_test;
+import 'tokenizer_test.dart' as tokenizer_test;
+
+main(List<String> args) {
+  var pattern = new RegExp(args.length > 0 ? args[0] : '.');
+  useCompactVMConfiguration();
+
+  void addGroup(testFile, void testMain()) {
+    if (pattern.hasMatch(testFile)) {
+      group(testFile.replaceAll('_test.dart', ':'), testMain);
+    }
+  }
+
+  addGroup('dom_test.dart', dom_test.main);
+  addGroup('parser_feature_test.dart', parser_feature_test.main);
+  addGroup('parser_test.dart', parser_test.main);
+  addGroup('tokenizer_test.dart', tokenizer_test.main);
+}
diff --git a/html/test/selectors/LICENSE b/html/test/selectors/LICENSE
new file mode 100644
index 0000000..0dc0193
--- /dev/null
+++ b/html/test/selectors/LICENSE
@@ -0,0 +1,9 @@
+Contents of this folder are ported from
+https://github.com/w3c/web-platform-tests/tree/master/selectors-api
+
+It is based on commit 96c61ac7c21f7f37526d1c03c4c6087734524130
+
+The original code is covered by the dual-licensing approach described in:
+
+    http://www.w3.org/Consortium/Legal/2008/04-testsuite-copyright.html
+    
\ No newline at end of file
diff --git a/html/test/selectors/README b/html/test/selectors/README
new file mode 100644
index 0000000..d6e3852
--- /dev/null
+++ b/html/test/selectors/README
@@ -0,0 +1,9 @@
+Contents of this folder are ported from
+https://github.com/w3c/web-platform-tests/tree/master/selectors-api
+
+It is based on commit 96c61ac7c21f7f37526d1c03c4c6087734524130
+
+It is used to test the implementation of querySelector/querySelectorAll.
+
+Not all code was ported; as the current implementation doesn't yet support
+all features of those methods.
diff --git a/html/test/selectors/level1-content.html b/html/test/selectors/level1-content.html
new file mode 100644
index 0000000..b90d918
--- /dev/null
+++ b/html/test/selectors/level1-content.html
@@ -0,0 +1,377 @@
+<!DOCTYPE html>
+<html id="html" lang="en">
+<head id="head">
+	<meta id="meta" charset="UTF-8">
+	<title id="title">Selectors-API Test Suite: HTML with Selectors Level 2 using TestHarness: Test Document</title>
+
+	<!-- Links for :link and :visited pseudo-class test -->
+	<link id="pseudo-link-link1" href="">
+	<link id="pseudo-link-link2" href="http://example.org/">
+	<link id="pseudo-link-link3">
+	<style>
+	@namespace ns "http://www.w3.org/1999/xhtml";
+	 /* Declare the namespace prefix used in tests. This declaration should not be used by the API. */
+	</style>
+</head>
+<body id="body">
+<div id="root">
+	<div id="target"></div>
+
+	<div id="universal">
+		<p id="universal-p1">Universal selector tests inside element with <code id="universal-code1">id="universal"</code>.</p>
+		<hr id="universal-hr1">
+		<pre id="universal-pre1">Some preformatted text with some <span id="universal-span1">embedded code</span></pre>
+		<p id="universal-p2">This is a normal link: <a id="universal-a1" href="http://www.w3.org/">W3C</a></p>
+		<address id="universal-address1">Some more nested elements <code id="universal-code2"><a href="#" id="universal-a2">code hyperlink</a></code></address>
+	</div>
+
+	<div id="attr-presence">
+		<div class="attr-presence-div1" id="attr-presence-div1" align="center"></div>
+		<div class="attr-presence-div2" id="attr-presence-div2" align=""></div>
+		<div class="attr-presence-div3" id="attr-presence-div3" valign="center"></div>
+		<div class="attr-presence-div4" id="attr-presence-div4" alignv="center"></div>
+		<p id="attr-presence-p1"><a  id="attr-presence-a1" tItLe=""></a><span id="attr-presence-span1" TITLE="attr-presence-span1"></span></p>
+		<pre id="attr-presence-pre1" data-attr-presence="pre1"></pre>
+		<blockquote id="attr-presence-blockquote1" data-attr-presence="blockquote1"></blockquote>
+		<ul id="attr-presence-ul1" data-中文=""></ul>
+
+		<select id="attr-presence-select1">
+			<option id="attr-presence-select1-option1">A</option>
+			<option id="attr-presence-select1-option2">B</option>
+			<option id="attr-presence-select1-option3">C</option>
+			<option id="attr-presence-select1-option4">D</option>
+		</select>
+		<select id="attr-presence-select2">
+			<option id="attr-presence-select2-option1">A</option>
+			<option id="attr-presence-select2-option2">B</option>
+			<option id="attr-presence-select2-option3">C</option>
+			<option id="attr-presence-select2-option4" selected="selected">D</option>
+		</select>
+		<select id="attr-presence-select3" multiple="multiple">
+			<option id="attr-presence-select3-option1">A</option>
+			<option id="attr-presence-select3-option2" selected="">B</option>
+			<option id="attr-presence-select3-option3" selected="selected">C</option>
+			<option id="attr-presence-select3-option4">D</option>
+		</select>
+	</div>
+
+	<div id="attr-value">
+		<div id="attr-value-div1" align="center"></div>
+	    <div id="attr-value-div2" align=""></div>
+	    <div id="attr-value-div3" data-attr-value="&#xE9;"></div>
+	    <div id="attr-value-div4" data-attr-value_foo="&#xE9;"></div>
+
+		<form id="attr-value-form1">
+			<input id="attr-value-input1" type="text">
+			<input id="attr-value-input2" type="password">
+			<input id="attr-value-input3" type="hidden">
+			<input id="attr-value-input4" type="radio">
+			<input id="attr-value-input5" type="checkbox">
+			<input id="attr-value-input6" type="radio">
+			<input id="attr-value-input7" type="text">
+			<input id="attr-value-input8" type="hidden">
+			<input id="attr-value-input9" type="radio">
+		</form>
+
+		<div id="attr-value-div5" data-attr-value="中文"></div>
+	</div>
+
+	<div id="attr-whitespace">
+		<div id="attr-whitespace-div1" class="foo div1 bar"></div>
+	    <div id="attr-whitespace-div2" class=""></div>
+	    <div id="attr-whitespace-div3" class="foo div3 bar"></div>
+
+	    <div id="attr-whitespace-div4" data-attr-whitespace="foo &#xE9; bar"></div>
+	    <div id="attr-whitespace-div5" data-attr-whitespace_foo="&#xE9; foo"></div>
+
+		<a id="attr-whitespace-a1" rel="next bookmark"></a>
+		<a id="attr-whitespace-a2" rel="tag nofollow"></a>
+		<a id="attr-whitespace-a3" rel="tag bookmark"></a>
+		<a id="attr-whitespace-a4" rel="book mark"></a> <!-- Intentional space in "book mark" -->
+		<a id="attr-whitespace-a5" rel="nofollow"></a>
+		<a id="attr-whitespace-a6" rev="bookmark nofollow"></a>
+		<a id="attr-whitespace-a7" rel="prev next tag alternate nofollow author help icon noreferrer prefetch search stylesheet tag"></a>
+		
+		<p id="attr-whitespace-p1" title="Chinese 中文 characters"></p>
+	</div>
+
+	<div id="attr-hyphen">
+		<div id="attr-hyphen-div1"></div>
+	    <div id="attr-hyphen-div2" lang="fr"></div>
+	    <div id="attr-hyphen-div3" lang="en-AU"></div>
+	    <div id="attr-hyphen-div4" lang="es"></div>
+	</div>
+
+	<div id="attr-begins">
+		<a id="attr-begins-a1" href="http://www.example.org"></a>
+		<a id="attr-begins-a2" href="http://example.org/"></a>
+		<a id="attr-begins-a3" href="http://www.example.com/"></a>
+
+	    <div id="attr-begins-div1" lang="fr"></div>
+	    <div id="attr-begins-div2" lang="en-AU"></div>
+	    <div id="attr-begins-div3" lang="es"></div>
+	    <div id="attr-begins-div4" lang="en-US"></div>
+	    <div id="attr-begins-div5" lang="en"></div>
+
+		<p id="attr-begins-p1" class=" apple"></p> <!-- Intentional space in class value " apple". -->
+	</div>
+
+	<div id="attr-ends">
+		<a id="attr-ends-a1" href="http://www.example.org"></a>
+		<a id="attr-ends-a2" href="http://example.org/"></a>
+		<a id="attr-ends-a3" href="http://www.example.org"></a>
+
+	    <div id="attr-ends-div1" lang="fr"></div>
+	    <div id="attr-ends-div2" lang="de-CH"></div>
+	    <div id="attr-ends-div3" lang="es"></div>
+	    <div id="attr-ends-div4" lang="fr-CH"></div>
+
+		<p id="attr-ends-p1" class="apple "></p> <!-- Intentional space in class value "apple ". -->
+	</div>
+
+	<div id="attr-contains">
+		<a id="attr-contains-a1" href="http://www.example.org"></a>
+		<a id="attr-contains-a2" href="http://example.org/"></a>
+		<a id="attr-contains-a3" href="http://www.example.com/"></a>
+
+	    <div id="attr-contains-div1" lang="fr"></div>
+	    <div id="attr-contains-div2" lang="en-AU"></div>
+	    <div id="attr-contains-div3" lang="de-CH"></div>
+	    <div id="attr-contains-div4" lang="es"></div>
+	    <div id="attr-contains-div5" lang="fr-CH"></div>
+	    <div id="attr-contains-div6" lang="en-US"></div>
+
+		<p id="attr-contains-p1" class=" apple banana orange "></p>
+	</div>
+
+	<div id="pseudo-nth">
+		<table id="pseudo-nth-table1">
+			<tr id="pseudo-nth-tr1"><td id="pseudo-nth-td1"></td><td id="pseudo-nth-td2"></td><td id="pseudo-nth-td3"></td><td id="pseudo-nth-td4"></td><td id="pseudo-nth--td5"></td><td id="pseudo-nth-td6"></td></tr>
+			<tr id="pseudo-nth-tr2"><td id="pseudo-nth-td7"></td><td id="pseudo-nth-td8"></td><td id="pseudo-nth-td9"></td><td id="pseudo-nth-td10"></td><td id="pseudo-nth-td11"></td><td id="pseudo-nth-td12"></td></tr>
+			<tr id="pseudo-nth-tr3"><td id="pseudo-nth-td13"></td><td id="pseudo-nth-td14"></td><td id="pseudo-nth-td15"></td><td id="pseudo-nth-td16"></td><td id="pseudo-nth-td17"></td><td id="pseudo-nth-td18"></td></tr>
+		</table>
+		
+		<ol id="pseudo-nth-ol1">
+			<li id="pseudo-nth-li1"></li>
+			<li id="pseudo-nth-li2"></li>
+			<li id="pseudo-nth-li3"></li>
+			<li id="pseudo-nth-li4"></li>
+			<li id="pseudo-nth-li5"></li>
+			<li id="pseudo-nth-li6"></li>
+			<li id="pseudo-nth-li7"></li>
+			<li id="pseudo-nth-li8"></li>
+			<li id="pseudo-nth-li9"></li>
+			<li id="pseudo-nth-li10"></li>
+			<li id="pseudo-nth-li11"></li>
+			<li id="pseudo-nth-li12"></li>
+		</ol>
+
+		<p id="pseudo-nth-p1">
+			<span id="pseudo-nth-span1">span1</span>
+			<em id="pseudo-nth-em1">em1</em>
+			<!-- comment node-->
+			<em id="pseudo-nth-em2">em2</em>
+			<span id="pseudo-nth-span2">span2</span>
+			<strong id="pseudo-nth-strong1">strong1</strong>
+			<em id="pseudo-nth-em3">em3</em>
+			<span id="pseudo-nth-span3">span3</span>
+			<span id="pseudo-nth-span4">span4</span>
+			<strong id="pseudo-nth-strong2">strong2</strong>
+			<em id="pseudo-nth-em4">em4</em>
+		</p>
+	</div>
+
+	<div id="pseudo-first-child">
+		<div id="pseudo-first-child-div1"></div>
+		<div id="pseudo-first-child-div2"></div>
+		<div id="pseudo-first-child-div3"></div>
+
+		<p id="pseudo-first-child-p1"><span id="pseudo-first-child-span1"></span><span id="pseudo-first-child-span2"></span></p>
+		<p id="pseudo-first-child-p2"><span id="pseudo-first-child-span3"></span><span id="pseudo-first-child-span4"></span></p>
+		<p id="pseudo-first-child-p3"><span id="pseudo-first-child-span5"></span><span id="pseudo-first-child-span6"></span></p>
+	</div>
+
+	<div id="pseudo-last-child">
+		<p id="pseudo-last-child-p1"><span id="pseudo-last-child-span1"></span><span id="pseudo-last-child-span2"></span></p>
+		<p id="pseudo-last-child-p2"><span id="pseudo-last-child-span3"></span><span id="pseudo-last-child-span4"></span></p>
+		<p id="pseudo-last-child-p3"><span id="pseudo-last-child-span5"></span><span id="pseudo-last-child-span6"></span></p>
+
+		<div id="pseudo-last-child-div1"></div>
+		<div id="pseudo-last-child-div2"></div>
+		<div id="pseudo-last-child-div3"></div>
+	</div>
+
+	<div id="pseudo-only">
+		<p id="pseudo-only-p1">
+			<span id="pseudo-only-span1"></span>
+		</p>
+		<p id="pseudo-only-p2">
+			<span id="pseudo-only-span2"></span>
+			<span id="pseudo-only-span3"></span>
+		</p>
+		<p id="pseudo-only-p3">
+			<span id="pseudo-only-span4"></span>
+			<em id="pseudo-only-em1"></em>
+			<span id="pseudo-only-span5"></span>
+		</p>
+	</div>>
+
+	<div id="pseudo-empty">
+		<p id="pseudo-empty-p1"></p>
+		<p id="pseudo-empty-p2"><!-- comment node --></p>
+		<p id="pseudo-empty-p3"> </p>
+		<p id="pseudo-empty-p4">Text node</p>
+		<p id="pseudo-empty-p5"><span id="pseudo-empty-span1"></span></p>
+	</div>
+
+	<div id="pseudo-link">
+		<a id="pseudo-link-a1" href="">with href</a>
+		<a id="pseudo-link-a2" href="http://example.org/">with href</a>
+		<a id="pseudo-link-a3">without href</a>
+		<map name="pseudo-link-map1" id="pseudo-link-map1">
+			<area id="pseudo-link-area1" href="">
+			<area id="pseudo-link-area2">
+		</map>
+	</div>
+
+	<div id="pseudo-lang">
+		<div id="pseudo-lang-div1"></div>
+	    <div id="pseudo-lang-div2" lang="fr"></div>
+	    <div id="pseudo-lang-div3" lang="en-AU"></div>
+	    <div id="pseudo-lang-div4" lang="es"></div>
+	</div>
+
+	<div id="pseudo-ui">
+		<input id="pseudo-ui-input1" type="text">
+		<input id="pseudo-ui-input2" type="password">
+		<input id="pseudo-ui-input3" type="radio">
+		<input id="pseudo-ui-input4" type="radio" checked="checked">
+		<input id="pseudo-ui-input5" type="checkbox">
+		<input id="pseudo-ui-input6" type="checkbox" checked="checked">
+		<input id="pseudo-ui-input7" type="submit">
+		<input id="pseudo-ui-input8" type="button">
+		<input id="pseudo-ui-input9" type="hidden">
+		<textarea id="pseudo-ui-textarea1"></textarea>
+		<button id="pseudo-ui-button1">Enabled</button>
+
+		<input id="pseudo-ui-input10" disabled="disabled" type="text">
+		<input id="pseudo-ui-input11" disabled="disabled" type="password">
+		<input id="pseudo-ui-input12" disabled="disabled" type="radio">
+		<input id="pseudo-ui-input13" disabled="disabled" type="radio" checked="checked">
+		<input id="pseudo-ui-input14" disabled="disabled" type="checkbox">
+		<input id="pseudo-ui-input15" disabled="disabled" type="checkbox" checked="checked">
+		<input id="pseudo-ui-input16" disabled="disabled" type="submit">
+		<input id="pseudo-ui-input17" disabled="disabled" type="button">
+		<input id="pseudo-ui-input18" disabled="disabled" type="hidden">
+		<textarea id="pseudo-ui-textarea2" disabled="disabled"></textarea>
+		<button id="pseudo-ui-button2" disabled="disabled">Disabled</button>
+	</div>
+
+	<div id="not">
+		<div id="not-div1"></div>
+		<div id="not-div2"></div>
+		<div id="not-div3"></div>
+
+		<p id="not-p1"><span id="not-span1"></span><em id="not-em1"></em></p>
+		<p id="not-p2"><span id="not-span2"></span><em id="not-em2"></em></p>
+		<p id="not-p3"><span id="not-span3"></span><em id="not-em3"></em></p>
+	</div>
+
+	<div id="pseudo-element">All pseudo-element tests</div>
+
+	<div id="class">
+		<p id="class-p1" class="foo class-p bar"></p>
+		<p id="class-p2" class="class-p foo bar"></p>
+		<p id="class-p3" class="foo bar class-p"></p>
+
+		<!-- All permutations of the classes should match -->
+		<div id="class-div1" class="apple orange banana"></div>
+		<div id="class-div2" class="apple banana orange"></div>
+		<p id="class-p4" class="orange apple banana"></p>
+		<div id="class-div3" class="orange banana apple"></div>
+		<p id="class-p6" class="banana apple orange"></p>
+		<div id="class-div4" class="banana orange apple"></div>
+		<div id="class-div5" class="apple orange"></div>
+		<div id="class-div6" class="apple banana"></div>
+		<div id="class-div7" class="orange banana"></div>
+
+		<span id="class-span1" class="台北Táiběi 台北"></span>
+		<span id="class-span2" class="台北"></span>
+
+		<span id="class-span3" class="foo:bar"></span>
+		<span id="class-span4" class="test.foo[5]bar"></span>
+	</div>
+
+	<div id="id">
+		<div id="id-div1"></div>
+		<div id="id-div2"></div>
+
+		<ul id="id-ul1">
+			<li id="id-li-duplicate"></li>
+			<li id="id-li-duplicate"></li>
+			<li id="id-li-duplicate"></li>
+			<li id="id-li-duplicate"></li>
+		</ul>
+
+		<span id="台北Táiběi"></span>
+		<span id="台北"></span>
+
+		<span id="#foo:bar"></span>
+		<span id="test.foo[5]bar"></span>
+	</div>
+
+	<div id="descendant">
+		<div id="descendant-div1" class="descendant-div1">
+			<div id="descendant-div2" class="descendant-div2">
+				<div id="descendant-div3" class="descendant-div3">
+				</div>				
+			</div>
+		</div>
+		<div id="descendant-div4" class="descendant-div4"></div>
+	</div>
+
+	<div id="child">
+		<div id="child-div1" class="child-div1">
+			<div id="child-div2" class="child-div2">
+				<div id="child-div3" class="child-div3">
+				</div>				
+			</div>
+		</div>
+		<div id="child-div4" class="child-div4"></div>
+	</div>
+
+	<div id="adjacent">
+		<div id="adjacent-div1" class="adjacent-div1"></div>
+		<div id="adjacent-div2" class="adjacent-div2">
+			<div id="adjacent-div3" class="adjacent-div3"></div>
+		</div>
+		<div id="adjacent-div4" class="adjacent-div4">
+			<p id="adjacent-p1" class="adjacent-p1"></p>
+			<div id="adjacent-div5" class="adjacent-div5"></div>
+		</div>
+		<div id="adjacent-div6" class="adjacent-div6"></div>
+		<p id="adjacent-p2" class="adjacent-p2"></p>
+		<p id="adjacent-p3" class="adjacent-p3"></p>
+	</div>
+
+	<div id="sibling">
+		<div id="sibling-div1" class="sibling-div"></div>
+		<div id="sibling-div2" class="sibling-div">
+			<div id="sibling-div3" class="sibling-div"></div>
+		</div>
+		<div id="sibling-div4" class="sibling-div">
+			<p id="sibling-p1" class="sibling-p"></p>
+			<div id="sibling-div5" class="sibling-div"></div>
+		</div>
+		<div id="sibling-div6" class="sibling-div"></div>
+		<p id="sibling-p2" class="sibling-p"></p>
+		<p id="sibling-p3" class="sibling-p"></p>
+	</div>
+
+	<div id="group">
+		<em id="group-em1"></em>
+		<strong id="group-strong1"></strong>
+	</div>
+</div>
+</body>
+</html>
diff --git a/html/test/selectors/level1_baseline_test.dart b/html/test/selectors/level1_baseline_test.dart
new file mode 100644
index 0000000..e052843
--- /dev/null
+++ b/html/test/selectors/level1_baseline_test.dart
@@ -0,0 +1,122 @@
+/// Test for the Selectors API ported from
+/// <https://github.com/w3c/web-platform-tests/tree/master/selectors-api>
+///
+/// Note, unlike the original we don't operate in-browser on a DOM loaded into
+/// an iframe, but instead operate over a parsed DOM.
+library html.test.selectors.level1_baseline_test;
+
+import 'dart:io';
+import 'package:html/dom.dart';
+import 'package:html/parser.dart';
+import 'package:unittest/unittest.dart';
+import 'level1_lib.dart' hide test;
+import 'selectors.dart';
+
+Document getTestContentDocument() {
+  var testPath = Platform.script.resolve('level1-content.html').toFilePath();
+  return parse(new File(testPath).readAsStringSync());
+}
+
+var testType = TEST_QSA_BASELINE; // Only run baseline tests.
+var docType = "html"; // Only run tests suitable for HTML
+
+main() {
+  /*
+   * This test suite tests Selectors API methods in 4 different contexts:
+   * 1. Document node
+   * 2. In-document Element node
+   * 3. Detached Element node (an element with no parent, not in the document)
+   * 4. Document Fragment node
+   *
+   * For each context, the following tests are run:
+   *
+   * The interface check tests ensure that each type of node exposes the Selectors API methods
+   *
+   * The special selector tests verify the result of passing special values for the selector parameter,
+   * to ensure that the correct WebIDL processing is performed, such as stringification of null and
+   * undefined and missing parameter. The universal selector is also tested here, rather than with the
+   * rest of ordinary selectors for practical reasons.
+   *
+   * The static list verification tests ensure that the node lists returned by the method remain unchanged
+   * due to subsequent document modication, and that a new list is generated each time the method is
+   * invoked based on the current state of the document.
+   *
+   * The invalid selector tests ensure that SyntaxError is thrown for invalid forms of selectors
+   *
+   * The valid selector tests check the result from querying many different types of selectors, with a
+   * list of expected elements. This checks that querySelector() always returns the first result from
+   * querySelectorAll(), and that all matching elements are correctly returned in tree-order. The tests
+   * can be limited by specifying the test types to run, using the testType variable. The constants for this
+   * can be found in selectors.js.
+   *
+   * All the selectors tested for both the valid and invalid selector tests are found in selectors.js.
+   * See comments in that file for documentation of the format used.
+   *
+   * The level1-lib.js file contains all the common test functions for running each of the aforementioned tests
+   */
+
+  // Prepare the nodes for testing
+  //doc = frame.contentDocument;                 // Document Node tests
+  doc = getTestContentDocument();
+
+  var element = doc.getElementById("root"); // In-document Element Node tests
+
+  //Setup the namespace tests
+  setupSpecialElements(element);
+
+  var outOfScope = element
+      .clone(true); // Append this to the body before running the in-document
+  // Element tests, but after running the Document tests. This
+  // tests that no elements that are not descendants of element
+  // are selected.
+
+  traverse(outOfScope, (elem) {
+    // Annotate each element as being a clone; used for verifying
+    elem.attributes["data-clone"] =
+        ""; // that none of these elements ever match.
+  });
+
+  var detached = element.clone(true); // Detached Element Node tests
+
+  var fragment = doc.createDocumentFragment(); // Fragment Node tests
+  fragment.append(element.clone(true));
+
+  // Setup Tests
+  interfaceCheck("Document", doc);
+  interfaceCheck("Detached Element", detached);
+  interfaceCheck("Fragment", fragment);
+  interfaceCheck("In-document Element", element);
+
+  runSpecialSelectorTests("Document", doc);
+  runSpecialSelectorTests("Detached Element", detached);
+  runSpecialSelectorTests("Fragment", fragment);
+  runSpecialSelectorTests("In-document Element", element);
+
+  verifyStaticList("Document", doc);
+  verifyStaticList("Detached Element", detached);
+  verifyStaticList("Fragment", fragment);
+  verifyStaticList("In-document Element", element);
+
+  // TODO(jmesserly): fix negative tests
+  //runInvalidSelectorTest("Document", doc, invalidSelectors);
+  //runInvalidSelectorTest("Detached Element", detached, invalidSelectors);
+  //runInvalidSelectorTest("Fragment", fragment, invalidSelectors);
+  //runInvalidSelectorTest("In-document Element", element, invalidSelectors);
+
+  runValidSelectorTest("Document", doc, validSelectors, testType, docType);
+  runValidSelectorTest(
+      "Detached Element", detached, validSelectors, testType, docType);
+  runValidSelectorTest("Fragment", fragment, validSelectors, testType, docType);
+
+  group('out of scope', () {
+    setUp(() {
+      doc.body.append(outOfScope); // Append before in-document Element tests.
+      // None of these elements should match
+    });
+    tearDown(() {
+      outOfScope.remove();
+    });
+    runValidSelectorTest(
+        "In-document Element", element, validSelectors, testType, docType);
+  });
+}
diff --git a/html/test/selectors/level1_lib.dart b/html/test/selectors/level1_lib.dart
new file mode 100644
index 0000000..3191353
--- /dev/null
+++ b/html/test/selectors/level1_lib.dart
@@ -0,0 +1,303 @@
+/// Test for the Selectors API ported from
+/// <https://github.com/w3c/web-platform-tests/tree/master/selectors-api>
+///
+/// Note: tried to make minimal changes possible here. Hence some oddities such
+/// as [test] arguments having a different order, long lines, etc.
+///
+/// As usual with ports: being faithful to the original style is more important
+/// than other style goals, as it reduces friction to integrating changes
+/// from upstream.
+library html.test.selectors.level1_lib;
+
+import 'package:html/dom.dart';
+import 'package:unittest/unittest.dart' as unittest;
+
+Document doc;
+
+/*
+ * Create and append special elements that cannot be created correctly with HTML markup alone.
+ */
+setupSpecialElements(parent) {
+  // Setup null and undefined tests
+  parent.append(doc.createElement("null"));
+  parent.append(doc.createElement("undefined"));
+
+  // Setup namespace tests
+  var anyNS = doc.createElement("div");
+  var noNS = doc.createElement("div");
+  anyNS.id = "any-namespace";
+  noNS.id = "no-namespace";
+
+  var div;
+  div = [
+    doc.createElement("div"),
+    doc.createElementNS("http://www.w3.org/1999/xhtml", "div"),
+    doc.createElementNS("", "div"),
+    doc.createElementNS("http://www.example.org/ns", "div")
+  ];
+
+  div[0].id = "any-namespace-div1";
+  div[1].id = "any-namespace-div2";
+  div[2].attributes["id"] =
+      "any-namespace-div3"; // Non-HTML elements can't use .id property
+  div[3].attributes["id"] = "any-namespace-div4";
+
+  for (var i = 0; i < div.length; i++) {
+    anyNS.append(div[i]);
+  }
+
+  div = [
+    doc.createElement("div"),
+    doc.createElementNS("http://www.w3.org/1999/xhtml", "div"),
+    doc.createElementNS("", "div"),
+    doc.createElementNS("http://www.example.org/ns", "div")
+  ];
+
+  div[0].id = "no-namespace-div1";
+  div[1].id = "no-namespace-div2";
+  div[2].attributes["id"] =
+      "no-namespace-div3"; // Non-HTML elements can't use .id property
+  div[3].attributes["id"] = "no-namespace-div4";
+
+  for (var i = 0; i < div.length; i++) {
+    noNS.append(div[i]);
+  }
+
+  parent.append(anyNS);
+  parent.append(noNS);
+}
+
+/*
+ * Check that the querySelector and querySelectorAll methods exist on the given Node
+ */
+interfaceCheck(type, obj) {
+  test(() {
+    var q = obj.querySelector is Function;
+    assert_true(q, type + " supports querySelector.");
+  }, type + " supports querySelector");
+
+  test(() {
+    var qa = obj.querySelectorAll is Function;
+    assert_true(qa, type + " supports querySelectorAll.");
+  }, type + " supports querySelectorAll");
+
+  test(() {
+    var list = obj.querySelectorAll("div");
+    // TODO(jmesserly): testing List<Element> for now. It should return an
+    // ElementList which has extra properties. Needed for dart:html compat.
+    assert_true(list is List<Element>,
+        "The result should be an instance of a NodeList");
+  }, type + ".querySelectorAll returns NodeList instance");
+}
+
+/*
+ * Verify that the NodeList returned by querySelectorAll is static and and that a new list is created after
+ * each call. A static list should not be affected by subsequent changes to the DOM.
+ */
+verifyStaticList(type, root) {
+  var pre, post, preLength;
+
+  test(() {
+    pre = root.querySelectorAll("div");
+    preLength = pre.length;
+
+    var div = doc.createElement("div");
+    (root is Document ? root.body : root).append(div);
+
+    assert_equals(
+        pre.length, preLength, "The length of the NodeList should not change.");
+  }, type + ": static NodeList");
+
+  test(() {
+    post = root.querySelectorAll("div");
+    assert_equals(post.length, preLength + 1,
+        "The length of the new NodeList should be 1 more than the previous list.");
+  }, type + ": new NodeList");
+}
+
+/*
+ * Verify handling of special values for the selector parameter, including stringification of
+ * null and undefined, and the handling of the empty string.
+ */
+runSpecialSelectorTests(type, root) {
+  // Dart note: changed these tests because we don't have auto conversion to
+  // String like JavaScript does.
+  test(() {
+    // 1
+    assert_equals(root.querySelectorAll('null').length, 1,
+        "This should find one element with the tag name 'NULL'.");
+  }, type + ".querySelectorAll null");
+
+  test(() {
+    // 2
+    assert_equals(root.querySelectorAll('undefined').length, 1,
+        "This should find one element with the tag name 'UNDEFINED'.");
+  }, type + ".querySelectorAll undefined");
+
+  test(() {
+    // 3
+    assert_throws((e) => e is NoSuchMethodError, () {
+      root.querySelectorAll();
+    }, "This should throw a TypeError.");
+  }, type + ".querySelectorAll no parameter");
+
+  test(() {
+    // 4
+    var elm = root.querySelector('null');
+    assert_not_equals(elm, null, "This should find an element.");
+    // TODO(jmesserly): change "localName" back to "tagName" once implemented.
+    assert_equals(
+        elm.localName.toUpperCase(), "NULL", "The tag name should be 'NULL'.");
+  }, type + ".querySelector null");
+
+  test(() {
+    // 5
+    var elm = root.querySelector('undefined');
+    assert_not_equals(elm, 'undefined', "This should find an element.");
+    // TODO(jmesserly): change "localName" back to "tagName" once implemented.
+    assert_equals(elm.localName.toUpperCase(),
+        "UNDEFINED", "The tag name should be 'UNDEFINED'.");
+  }, type + ".querySelector undefined");
+
+  test(() {
+    // 6
+    assert_throws((e) => e is NoSuchMethodError, () {
+      root.querySelector();
+    }, "This should throw a TypeError.");
+  }, type + ".querySelector no parameter");
+
+  test(() {
+    // 7
+    var result = root.querySelectorAll("*");
+    var i = 0;
+    traverse(root, (elem) {
+      if (!identical(elem, root)) {
+        assert_equals(
+            elem, result[i], "The result in index $i should be in tree order.");
+        i++;
+      }
+    });
+  }, type + ".querySelectorAll tree order");
+}
+
+/*
+ * Execute queries with the specified valid selectors for both querySelector() and querySelectorAll()
+ * Only run these tests when results are expected. Don't run for syntax error tests.
+ */
+runValidSelectorTest(type, root, selectors, testType, docType) {
+  var nodeType = "";
+  switch (root.nodeType) {
+    case Node.DOCUMENT_NODE:
+      nodeType = "document";
+      break;
+    case Node.ELEMENT_NODE:
+      nodeType = root.parentNode != null ? "element" : "detached";
+      break;
+    case Node.DOCUMENT_FRAGMENT_NODE:
+      nodeType = "fragment";
+      break;
+    default:
+      throw new StateError("Reached unreachable code path.");
+  }
+
+  for (var i = 0; i < selectors.length; i++) {
+    var s = selectors[i];
+    var n = s["name"];
+    var q = s["selector"];
+    var e = s["expect"];
+
+    if ((s["exclude"] is! List ||
+            (s["exclude"].indexOf(nodeType) == -1 &&
+                s["exclude"].indexOf(docType) == -1)) &&
+        (s["testType"] & testType != 0)) {
+      //console.log("Running tests " + nodeType + ": " + s["testType"] + "&" + testType + "=" + (s["testType"] & testType) + ": " + JSON.stringify(s))
+      var foundall, found;
+
+      test(() {
+        foundall = root.querySelectorAll(q);
+        assert_not_equals(foundall, null, "The method should not return null.");
+        assert_equals(foundall.length, e.length,
+            "The method should return the expected number of matches.");
+
+        for (var i = 0; i < e.length; i++) {
+          assert_not_equals(
+              foundall[i], null, "The item in index $i should not be null.");
+          assert_equals(foundall[i].attributes["id"], e[i],
+              "The item in index $i should have the expected ID.");
+          assert_false(foundall[i].attributes.containsKey("data-clone"),
+              "This should not be a cloned element.");
+        }
+      }, type + ".querySelectorAll: " + n + ": " + q);
+
+      test(() {
+        found = root.querySelector(q);
+
+        if (e.length > 0) {
+          assert_not_equals(found, null, "The method should return a match.");
+          assert_equals(found.attributes["id"], e[0],
+              "The method should return the first match.");
+          assert_equals(found, foundall[0],
+              "The result should match the first item from querySelectorAll.");
+          assert_false(found.attributes.containsKey("data-clone"),
+              "This should not be annotated as a cloned element.");
+        } else {
+          assert_equals(found, null, "The method should not match anything.");
+        }
+      }, type + ".querySelector: " + n + ": " + q);
+    } else {
+      //console.log("Excluding for " + nodeType + ": " + s["testType"] + "&" + testType + "=" + (s["testType"] & testType) + ": " + JSON.stringify(s))
+    }
+  }
+}
+
+/*
+ * Execute queries with the specified invalid selectors for both querySelector() and querySelectorAll()
+ * Only run these tests when errors are expected. Don't run for valid selector tests.
+ */
+runInvalidSelectorTest(type, root, selectors) {
+  for (var i = 0; i < selectors.length; i++) {
+    var s = selectors[i];
+    var n = s["name"];
+    var q = s["selector"];
+
+    // Dart note: FormatException seems a reasonable mapping of SyntaxError
+    test(() {
+      assert_throws((e) => e is FormatException, () {
+        root.querySelector(q);
+      });
+    }, type + ".querySelector: " + n + ": " + q);
+
+    test(() {
+      assert_throws((e) => e is FormatException, () {
+        root.querySelectorAll(q);
+      });
+    }, type + ".querySelectorAll: " + n + ": " + q);
+  }
+}
+
+traverse(Node elem, fn) {
+  if (elem.nodeType == Node.ELEMENT_NODE) {
+    fn(elem);
+  }
+
+  // Dart note: changed this since our DOM API doesn't support nextNode yet.
+  for (var node in elem.nodes) {
+    traverse(node, fn);
+  }
+}
+
+test(Function body, String name) => unittest.test(name, body);
+
+assert_true(value, String reason) =>
+    unittest.expect(value, true, reason: reason);
+
+assert_false(value, String reason) =>
+    unittest.expect(value, false, reason: reason);
+
+assert_equals(x, y, reason) => unittest.expect(x, y, reason: reason);
+
+assert_not_equals(x, y, reason) =>
+    unittest.expect(x, unittest.isNot(y), reason: reason);
+
+assert_throws(exception, body, [reason]) =>
+    unittest.expect(body, unittest.throwsA(exception), reason: reason);
diff --git a/html/test/selectors/selectors.dart b/html/test/selectors/selectors.dart
new file mode 100644
index 0000000..d25b14b
--- /dev/null
+++ b/html/test/selectors/selectors.dart
@@ -0,0 +1,1875 @@
+/// Test for the Selectors API ported from
+/// <https://github.com/w3c/web-platform-tests/tree/master/selectors-api>
+library html.test.selectors.selectors;
+
+// Bit-mapped flags to indicate which tests the selector is suitable for
+var TEST_QSA_BASELINE =
+    0x01; // querySelector() and querySelectorAll() baseline tests
+var TEST_QSA_ADDITIONAL =
+    0x02; // querySelector() and querySelectorAll() additional tests
+var TEST_FIND_BASELINE =
+    0x04; // find() and findAll() baseline tests, may be unsuitable for querySelector[All]
+var TEST_FIND_ADDITIONAL =
+    0x08; // find() and findAll() additional tests, may be unsuitable for querySelector[All]
+var TEST_MATCH_BASELINE = 0x10; // matches() baseline tests
+var TEST_MATCH_ADDITIONAL = 0x20; // matches() additional tests
+
+/*
+ * All of these invalid selectors should result in a SyntaxError being thrown by the APIs.
+ *
+ *   name:     A descriptive name of the selector being tested
+ *   selector: The selector to test
+ */
+var invalidSelectors = [
+  {'name': "Empty String", 'selector': ""},
+  {'name': "Invalid character", 'selector': "["},
+  {'name': "Invalid character", 'selector': "]"},
+  {'name': "Invalid character", 'selector': "("},
+  {'name': "Invalid character", 'selector': ")"},
+  {'name': "Invalid character", 'selector': "{"},
+  {'name': "Invalid character", 'selector': "}"},
+  {'name': "Invalid character", 'selector': "<"},
+  {'name': "Invalid character", 'selector': ">"},
+  {'name': "Invalid ID", 'selector': "#"},
+  {'name': "Invalid group of selectors", 'selector': "div,"},
+  {'name': "Invalid class", 'selector': "."},
+  {'name': "Invalid class", 'selector': ".5cm"},
+  {'name': "Invalid class", 'selector': "..test"},
+  {'name': "Invalid class", 'selector': ".foo..quux"},
+  {'name': "Invalid class", 'selector': ".bar."},
+  {'name': "Invalid combinator", 'selector': "div & address, p"},
+  {'name': "Invalid combinator", 'selector': "div >> address, p"},
+  {'name': "Invalid combinator", 'selector': "div ++ address, p"},
+  {'name': "Invalid combinator", 'selector': "div ~~ address, p"},
+  {'name': "Invalid [att=value] selector", 'selector': "[*=test]"},
+  {'name': "Invalid [att=value] selector", 'selector': "[*|*=test]"},
+  {
+    'name': "Invalid [att=value] selector",
+    'selector': "[class= space unquoted ]"
+  },
+  {'name': "Unknown pseudo-class", 'selector': "div:example"},
+  {'name': "Unknown pseudo-class", 'selector': ":example"},
+  {'name': "Unknown pseudo-element", 'selector': "div::example"},
+  {'name': "Unknown pseudo-element", 'selector': "::example"},
+  {'name': "Invalid pseudo-element", 'selector': ":::before"},
+  {'name': "Undeclared namespace", 'selector': "ns|div"},
+  {'name': "Undeclared namespace", 'selector': ":not(ns|div)"},
+  {'name': "Invalid namespace", 'selector': "^|div"},
+  {'name': "Invalid namespace", 'selector': "\$|div"}
+];
+
+/*
+ * All of these should be valid selectors, expected to match zero or more elements in the document.
+ * None should throw any errors.
+ *
+ *   name:     A descriptive name of the selector being tested
+ *   selector: The selector to test
+ *   'expect':   A list of IDs of the elements expected to be matched. List must be given in tree order.
+ *   'exclude':  An array of contexts to exclude from testing. The valid values are:
+ *             ["document", "element", "fragment", "detached", "html", "xhtml"]
+ *             The "html" and "xhtml" values represent the type of document being queried. These are useful
+ *             for tests that are affected by differences between HTML and XML, such as case sensitivity.
+ *   'level':    An integer indicating the CSS or Selectors level in which the selector being tested was introduced.
+ *   'testType': A bit-mapped flag indicating the type of test.
+ *
+ * Note: Interactive pseudo-classes (:active :hover and :focus) have not been tested in this test suite.
+ */
+var validSelectors = [
+  // Type Selector
+  {
+    'name': "Type selector, matching html element",
+    'selector': "html",
+    'expect': ["html"],
+    'exclude': ["element", "fragment", "detached"],
+    'level': 1,
+    'testType': TEST_QSA_BASELINE | TEST_MATCH_BASELINE
+  },
+  {
+    'name': "Type selector, matching html element",
+    'selector': "html",
+    'expect': [] /*no matches*/,
+    'exclude': ["document"],
+    'level': 1,
+    'testType': TEST_QSA_BASELINE
+  },
+  {
+    'name': "Type selector, matching body element",
+    'selector': "body",
+    'expect': ["body"],
+    'exclude': ["element", "fragment", "detached"],
+    'level': 1,
+    'testType': TEST_QSA_BASELINE | TEST_MATCH_BASELINE
+  },
+  {
+    'name': "Type selector, matching body element",
+    'selector': "body",
+    'expect': [] /*no matches*/,
+    'exclude': ["document"],
+    'level': 1,
+    'testType': TEST_QSA_BASELINE
+  },
+
+  // Universal Selector
+  // Testing "*" for entire an entire context node is handled separately.
+  {
+    'name':
+        "Universal selector, matching all children of element with specified ID",
+    'selector': "#universal>*",
+    'expect': [
+      "universal-p1",
+      "universal-hr1",
+      "universal-pre1",
+      "universal-p2",
+      "universal-address1"
+    ],
+    'level': 2,
+    'testType': TEST_QSA_BASELINE | TEST_MATCH_BASELINE
+  },
+  {
+    'name':
+        "Universal selector, matching all grandchildren of element with specified ID",
+    'selector': "#universal>*>*",
+    'expect': [
+      "universal-code1",
+      "universal-span1",
+      "universal-a1",
+      "universal-code2"
+    ],
+    'level': 2,
+    'testType': TEST_QSA_BASELINE | TEST_MATCH_BASELINE
+  },
+  {
+    'name':
+        "Universal selector, matching all children of empty element with specified ID",
+    'selector': "#empty>*",
+    'expect': [] /*no matches*/,
+    'level': 2,
+    'testType': TEST_QSA_BASELINE
+  },
+  {
+    'name':
+        "Universal selector, matching all descendants of element with specified ID",
+    'selector': "#universal *",
+    'expect': [
+      "universal-p1",
+      "universal-code1",
+      "universal-hr1",
+      "universal-pre1",
+      "universal-span1",
+      "universal-p2",
+      "universal-a1",
+      "universal-address1",
+      "universal-code2",
+      "universal-a2"
+    ],
+    'level': 2,
+    'testType': TEST_QSA_BASELINE | TEST_MATCH_BASELINE
+  },
+
+  // Attribute Selectors
+  // - presence                  [att]
+  {
+    'name': "Attribute presence selector, matching align attribute with value",
+    'selector': ".attr-presence-div1[align]",
+    'expect': ["attr-presence-div1"],
+    'level': 2,
+    'testType': TEST_QSA_BASELINE | TEST_MATCH_BASELINE
+  },
+  {
+    'name':
+        "Attribute presence selector, matching align attribute with empty value",
+    'selector': ".attr-presence-div2[align]",
+    'expect': ["attr-presence-div2"],
+    'level': 2,
+    'testType': TEST_QSA_BASELINE | TEST_MATCH_BASELINE
+  },
+  {
+    'name':
+        "Attribute presence selector, matching title attribute, case insensitivity",
+    'selector': "#attr-presence [TiTlE]",
+    'expect': ["attr-presence-a1", "attr-presence-span1"],
+    'exclude': ["xhtml"],
+    'level': 2,
+    'testType': TEST_QSA_BASELINE | TEST_MATCH_BASELINE
+  },
+  {
+    'name':
+        "Attribute presence selector, not matching title attribute, case sensitivity",
+    'selector': "#attr-presence [TiTlE]",
+    'expect': [],
+    'exclude': ["html"],
+    'level': 2,
+    'testType': TEST_QSA_BASELINE | TEST_MATCH_BASELINE
+  },
+  {
+    'name': "Attribute presence selector, matching custom data-* attribute",
+    'selector': "[data-attr-presence]",
+    'expect': ["attr-presence-pre1", "attr-presence-blockquote1"],
+    'level': 2,
+    'testType': TEST_QSA_BASELINE | TEST_MATCH_BASELINE
+  },
+  {
+    'name':
+        "Attribute presence selector, not matching attribute with similar name",
+    'selector': ".attr-presence-div3[align], .attr-presence-div4[align]",
+    'expect': [] /*no matches*/,
+    'level': 2,
+    'testType': TEST_QSA_BASELINE
+  },
+  {
+    'name':
+        "Attribute presence selector, matching attribute with non-ASCII characters",
+    'selector': "ul[data-中文]",
+    'expect': ["attr-presence-ul1"],
+    'level': 2,
+    'testType': TEST_QSA_BASELINE | TEST_MATCH_BASELINE
+  },
+  {
+    'name':
+        "Attribute presence selector, not matching default option without selected attribute",
+    'selector': "#attr-presence-select1 option[selected]",
+    'expect': [] /* no matches */,
+    'level': 2,
+    'testType': TEST_QSA_BASELINE
+  },
+  {
+    'name':
+        "Attribute presence selector, matching option with selected attribute",
+    'selector': "#attr-presence-select2 option[selected]",
+    'expect': ["attr-presence-select2-option4"],
+    'level': 2,
+    'testType': TEST_QSA_BASELINE | TEST_MATCH_BASELINE
+  },
+  {
+    'name':
+        "Attribute presence selector, matching multiple options with selected attributes",
+    'selector': "#attr-presence-select3 option[selected]",
+    'expect': [
+      "attr-presence-select3-option2",
+      "attr-presence-select3-option3"
+    ],
+    'level': 2,
+    'testType': TEST_QSA_BASELINE | TEST_MATCH_BASELINE
+  },
+
+  // - value                     [att=val]
+  {
+    'name': "Attribute value selector, matching align attribute with value",
+    'selector': "#attr-value [align=\"center\"]",
+    'expect': ["attr-value-div1"],
+    'level': 2,
+    'testType': TEST_QSA_BASELINE | TEST_MATCH_BASELINE
+  },
+  {
+    'name':
+        "Attribute value selector, matching align attribute with empty value",
+    'selector': "#attr-value [align=\"\"]",
+    'expect': ["attr-value-div2"],
+    'level': 2,
+    'testType': TEST_QSA_BASELINE | TEST_MATCH_BASELINE
+  },
+  {
+    'name':
+        "Attribute value selector, not matching align attribute with partial value",
+    'selector': "#attr-value [align=\"c\"]",
+    'expect': [] /*no matches*/,
+    'level': 2,
+    'testType': TEST_QSA_BASELINE
+  },
+  {
+    'name':
+        "Attribute value selector, not matching align attribute with incorrect value",
+    'selector': "#attr-value [align=\"centera\"]",
+    'expect': [] /*no matches*/,
+    'level': 2,
+    'testType': TEST_QSA_BASELINE
+  },
+  {
+    'name':
+        "Attribute value selector, matching custom data-* attribute with unicode escaped value",
+    'selector': "[data-attr-value=\"\\e9\"]",
+    'expect': ["attr-value-div3"],
+    'level': 2,
+    'testType': TEST_QSA_BASELINE | TEST_MATCH_BASELINE
+  },
+  {
+    'name':
+        "Attribute value selector, matching custom data-* attribute with escaped character",
+    'selector': "[data-attr-value\_foo=\"\\e9\"]",
+    'expect': ["attr-value-div4"],
+    'level': 2,
+    'testType': TEST_QSA_BASELINE | TEST_MATCH_BASELINE
+  },
+  {
+    'name':
+        "Attribute value selector with single-quoted value, matching multiple inputs with type attributes",
+    'selector':
+        "#attr-value input[type='hidden'],#attr-value input[type='radio']",
+    'expect': [
+      "attr-value-input3",
+      "attr-value-input4",
+      "attr-value-input6",
+      "attr-value-input8",
+      "attr-value-input9"
+    ],
+    'level': 2,
+    'testType': TEST_QSA_BASELINE | TEST_MATCH_BASELINE
+  },
+  {
+    'name':
+        "Attribute value selector with double-quoted value, matching multiple inputs with type attributes",
+    'selector':
+        "#attr-value input[type=\"hidden\"],#attr-value input[type='radio']",
+    'expect': [
+      "attr-value-input3",
+      "attr-value-input4",
+      "attr-value-input6",
+      "attr-value-input8",
+      "attr-value-input9"
+    ],
+    'level': 2,
+    'testType': TEST_QSA_BASELINE | TEST_MATCH_BASELINE
+  },
+  {
+    'name':
+        "Attribute value selector with unquoted value, matching multiple inputs with type attributes",
+    'selector': "#attr-value input[type=hidden],#attr-value input[type=radio]",
+    'expect': [
+      "attr-value-input3",
+      "attr-value-input4",
+      "attr-value-input6",
+      "attr-value-input8",
+      "attr-value-input9"
+    ],
+    'level': 2,
+    'testType': TEST_QSA_BASELINE | TEST_MATCH_BASELINE
+  },
+  {
+    'name':
+        "Attribute value selector, matching attribute with value using non-ASCII characters",
+    'selector': "[data-attr-value=中文]",
+    'expect': ["attr-value-div5"],
+    'level': 2,
+    'testType': TEST_QSA_BASELINE | TEST_MATCH_BASELINE
+  },
+
+  // - whitespace-separated list [att~=val]
+  {
+    'name':
+        "Attribute whitespace-separated list selector, matching class attribute with value",
+    'selector': "#attr-whitespace [class~=\"div1\"]",
+    'expect': ["attr-whitespace-div1"],
+    'level': 2,
+    'testType': TEST_QSA_BASELINE | TEST_MATCH_BASELINE
+  },
+  {
+    'name':
+        "Attribute whitespace-separated list selector, not matching class attribute with empty value",
+    'selector': "#attr-whitespace [class~=\"\"]",
+    'expect': [] /*no matches*/,
+    'level': 2,
+    'testType': TEST_QSA_BASELINE
+  },
+  {
+    'name':
+        "Attribute whitespace-separated list selector, not matching class attribute with partial value",
+    'selector': "[data-attr-whitespace~=\"div\"]",
+    'expect': [] /*no matches*/,
+    'level': 2,
+    'testType': TEST_QSA_BASELINE
+  },
+  {
+    'name':
+        "Attribute whitespace-separated list selector, matching custom data-* attribute with unicode escaped value",
+    'selector': "[data-attr-whitespace~=\"\\0000e9\"]",
+    'expect': ["attr-whitespace-div4"],
+    'level': 2,
+    'testType': TEST_QSA_BASELINE | TEST_MATCH_BASELINE
+  },
+  {
+    'name':
+        "Attribute whitespace-separated list selector, matching custom data-* attribute with escaped character",
+    'selector': "[data-attr-whitespace\_foo~=\"\\e9\"]",
+    'expect': ["attr-whitespace-div5"],
+    'level': 2,
+    'testType': TEST_QSA_BASELINE | TEST_MATCH_BASELINE
+  },
+  {
+    'name':
+        "Attribute whitespace-separated list selector with single-quoted value, matching multiple links with rel attributes",
+    'selector':
+        "#attr-whitespace a[rel~='bookmark'],  #attr-whitespace a[rel~='nofollow']",
+    'expect': [
+      "attr-whitespace-a1",
+      "attr-whitespace-a2",
+      "attr-whitespace-a3",
+      "attr-whitespace-a5",
+      "attr-whitespace-a7"
+    ],
+    'level': 2,
+    'testType': TEST_QSA_BASELINE | TEST_MATCH_BASELINE
+  },
+  {
+    'name':
+        "Attribute whitespace-separated list selector with double-quoted value, matching multiple links with rel attributes",
+    'selector':
+        "#attr-whitespace a[rel~=\"bookmark\"],#attr-whitespace a[rel~='nofollow']",
+    'expect': [
+      "attr-whitespace-a1",
+      "attr-whitespace-a2",
+      "attr-whitespace-a3",
+      "attr-whitespace-a5",
+      "attr-whitespace-a7"
+    ],
+    'level': 2,
+    'testType': TEST_QSA_BASELINE | TEST_MATCH_BASELINE
+  },
+  {
+    'name':
+        "Attribute whitespace-separated list selector with unquoted value, matching multiple links with rel attributes",
+    'selector':
+        "#attr-whitespace a[rel~=bookmark],    #attr-whitespace a[rel~=nofollow]",
+    'expect': [
+      "attr-whitespace-a1",
+      "attr-whitespace-a2",
+      "attr-whitespace-a3",
+      "attr-whitespace-a5",
+      "attr-whitespace-a7"
+    ],
+    'level': 2,
+    'testType': TEST_QSA_BASELINE | TEST_MATCH_BASELINE
+  },
+  {
+    'name':
+        "Attribute whitespace-separated list selector with double-quoted value, not matching value with space",
+    'selector': "#attr-whitespace a[rel~=\"book mark\"]",
+    'expect': [] /* no matches */,
+    'level': 2,
+    'testType': TEST_QSA_BASELINE
+  },
+  {
+    'name':
+        "Attribute whitespace-separated list selector, matching title attribute with value using non-ASCII characters",
+    'selector': "#attr-whitespace [title~=中文]",
+    'expect': ["attr-whitespace-p1"],
+    'level': 2,
+    'testType': TEST_QSA_BASELINE | TEST_MATCH_BASELINE
+  },
+
+  // - hyphen-separated list     [att|=val]
+  {
+    'name':
+        "Attribute hyphen-separated list selector, not matching unspecified lang attribute",
+    'selector': "#attr-hyphen-div1[lang|=\"en\"]",
+    'expect': [] /*no matches*/,
+    'level': 2,
+    'testType': TEST_QSA_BASELINE
+  },
+  {
+    'name':
+        "Attribute hyphen-separated list selector, matching lang attribute with exact value",
+    'selector': "#attr-hyphen-div2[lang|=\"fr\"]",
+    'expect': ["attr-hyphen-div2"],
+    'level': 2,
+    'testType': TEST_QSA_BASELINE | TEST_MATCH_BASELINE
+  },
+  {
+    'name':
+        "Attribute hyphen-separated list selector, matching lang attribute with partial value",
+    'selector': "#attr-hyphen-div3[lang|=\"en\"]",
+    'expect': ["attr-hyphen-div3"],
+    'level': 2,
+    'testType': TEST_QSA_BASELINE | TEST_MATCH_BASELINE
+  },
+  {
+    'name':
+        "Attribute hyphen-separated list selector, not matching incorrect value",
+    'selector': "#attr-hyphen-div4[lang|=\"es-AR\"]",
+    'expect': [] /*no matches*/,
+    'level': 2,
+    'testType': TEST_QSA_BASELINE
+  },
+
+  // - substring begins-with     [att^=val] (Level 3)
+  {
+    'name':
+        "Attribute begins with selector, matching href attributes beginning with specified substring",
+    'selector': "#attr-begins a[href^=\"http://www\"]",
+    'expect': ["attr-begins-a1", "attr-begins-a3"],
+    'level': 3,
+    'testType': TEST_QSA_ADDITIONAL | TEST_MATCH_BASELINE
+  },
+  {
+    'name':
+        "Attribute begins with selector, matching lang attributes beginning with specified substring, ",
+    'selector': "#attr-begins [lang^=\"en-\"]",
+    'expect': ["attr-begins-div2", "attr-begins-div4"],
+    'level': 3,
+    'testType': TEST_QSA_ADDITIONAL | TEST_MATCH_BASELINE
+  },
+  {
+    'name':
+        "Attribute begins with selector, not matching class attribute not beginning with specified substring",
+    'selector': "#attr-begins [class^=apple]",
+    'expect': [] /*no matches*/,
+    'level': 3,
+    'testType': TEST_QSA_ADDITIONAL
+  },
+  {
+    'name':
+        "Attribute begins with selector with single-quoted value, matching class attribute beginning with specified substring",
+    'selector': "#attr-begins [class^=' apple']",
+    'expect': ["attr-begins-p1"],
+    'level': 3,
+    'testType': TEST_QSA_ADDITIONAL | TEST_MATCH_BASELINE
+  },
+  {
+    'name':
+        "Attribute begins with selector with double-quoted value, matching class attribute beginning with specified substring",
+    'selector': "#attr-begins [class^=\" apple\"]",
+    'expect': ["attr-begins-p1"],
+    'level': 3,
+    'testType': TEST_QSA_ADDITIONAL | TEST_MATCH_BASELINE
+  },
+  {
+    'name':
+        "Attribute begins with selector with unquoted value, not matching class attribute not beginning with specified substring",
+    'selector': "#attr-begins [class^= apple]",
+    'expect': [] /*no matches*/,
+    'level': 3,
+    'testType': TEST_QSA_ADDITIONAL
+  },
+
+  // - substring ends-with       [att\$=val] (Level 3)
+  {
+    'name':
+        "Attribute ends with selector, matching href attributes ending with specified substring",
+    'selector': "#attr-ends a[href\$=\".org\"]",
+    'expect': ["attr-ends-a1", "attr-ends-a3"],
+    'level': 3,
+    'testType': TEST_QSA_ADDITIONAL | TEST_MATCH_BASELINE
+  },
+  {
+    'name':
+        "Attribute ends with selector, matching lang attributes ending with specified substring, ",
+    'selector': "#attr-ends [lang\$=\"-CH\"]",
+    'expect': ["attr-ends-div2", "attr-ends-div4"],
+    'level': 3,
+    'testType': TEST_QSA_ADDITIONAL | TEST_MATCH_BASELINE
+  },
+  {
+    'name':
+        "Attribute ends with selector, not matching class attribute not ending with specified substring",
+    'selector': "#attr-ends [class\$=apple]",
+    'expect': [] /*no matches*/,
+    'level': 3,
+    'testType': TEST_QSA_ADDITIONAL
+  },
+  {
+    'name':
+        "Attribute ends with selector with single-quoted value, matching class attribute ending with specified substring",
+    'selector': "#attr-ends [class\$='apple ']",
+    'expect': ["attr-ends-p1"],
+    'level': 3,
+    'testType': TEST_QSA_ADDITIONAL | TEST_MATCH_BASELINE
+  },
+  {
+    'name':
+        "Attribute ends with selector with double-quoted value, matching class attribute ending with specified substring",
+    'selector': "#attr-ends [class\$=\"apple \"]",
+    'expect': ["attr-ends-p1"],
+    'level': 3,
+    'testType': TEST_QSA_ADDITIONAL | TEST_MATCH_BASELINE
+  },
+  {
+    'name':
+        "Attribute ends with selector with unquoted value, not matching class attribute not ending with specified substring",
+    'selector': "#attr-ends [class\$=apple ]",
+    'expect': [] /*no matches*/,
+    'level': 3,
+    'testType': TEST_QSA_ADDITIONAL
+  },
+
+  // - substring contains        [att*=val] (Level 3)
+  {
+    'name':
+        "Attribute contains selector, matching href attributes beginning with specified substring",
+    'selector': "#attr-contains a[href*=\"http://www\"]",
+    'expect': ["attr-contains-a1", "attr-contains-a3"],
+    'level': 3,
+    'testType': TEST_QSA_ADDITIONAL | TEST_MATCH_BASELINE
+  },
+  {
+    'name':
+        "Attribute contains selector, matching href attributes ending with specified substring",
+    'selector': "#attr-contains a[href*=\".org\"]",
+    'expect': ["attr-contains-a1", "attr-contains-a2"],
+    'level': 3,
+    'testType': TEST_QSA_ADDITIONAL | TEST_MATCH_BASELINE
+  },
+  {
+    'name':
+        "Attribute contains selector, matching href attributes containing specified substring",
+    'selector': "#attr-contains a[href*=\".example.\"]",
+    'expect': ["attr-contains-a1", "attr-contains-a3"],
+    'level': 3,
+    'testType': TEST_QSA_ADDITIONAL | TEST_MATCH_BASELINE
+  },
+  {
+    'name':
+        "Attribute contains selector, matching lang attributes beginning with specified substring, ",
+    'selector': "#attr-contains [lang*=\"en-\"]",
+    'expect': ["attr-contains-div2", "attr-contains-div6"],
+    'level': 3,
+    'testType': TEST_QSA_ADDITIONAL | TEST_MATCH_BASELINE
+  },
+  {
+    'name':
+        "Attribute contains selector, matching lang attributes ending with specified substring, ",
+    'selector': "#attr-contains [lang*=\"-CH\"]",
+    'expect': ["attr-contains-div3", "attr-contains-div5"],
+    'level': 3,
+    'testType': TEST_QSA_ADDITIONAL | TEST_MATCH_BASELINE
+  },
+  {
+    'name':
+        "Attribute contains selector with single-quoted value, matching class attribute beginning with specified substring",
+    'selector': "#attr-contains [class*=' apple']",
+    'expect': ["attr-contains-p1"],
+    'level': 3,
+    'testType': TEST_QSA_ADDITIONAL | TEST_MATCH_BASELINE
+  },
+  {
+    'name':
+        "Attribute contains selector with single-quoted value, matching class attribute ending with specified substring",
+    'selector': "#attr-contains [class*='orange ']",
+    'expect': ["attr-contains-p1"],
+    'level': 3,
+    'testType': TEST_QSA_ADDITIONAL | TEST_MATCH_BASELINE
+  },
+  {
+    'name':
+        "Attribute contains selector with single-quoted value, matching class attribute containing specified substring",
+    'selector': "#attr-contains [class*='ple banana ora']",
+    'expect': ["attr-contains-p1"],
+    'level': 3,
+    'testType': TEST_QSA_ADDITIONAL | TEST_MATCH_BASELINE
+  },
+  {
+    'name':
+        "Attribute contains selector with double-quoted value, matching class attribute beginning with specified substring",
+    'selector': "#attr-contains [class*=\" apple\"]",
+    'expect': ["attr-contains-p1"],
+    'level': 3,
+    'testType': TEST_QSA_ADDITIONAL | TEST_MATCH_BASELINE
+  },
+  {
+    'name':
+        "Attribute contains selector with double-quoted value, matching class attribute ending with specified substring",
+    'selector': "#attr-contains [class*=\"orange \"]",
+    'expect': ["attr-contains-p1"],
+    'level': 3,
+    'testType': TEST_QSA_ADDITIONAL | TEST_MATCH_BASELINE
+  },
+  {
+    'name':
+        "Attribute contains selector with double-quoted value, matching class attribute containing specified substring",
+    'selector': "#attr-contains [class*=\"ple banana ora\"]",
+    'expect': ["attr-contains-p1"],
+    'level': 3,
+    'testType': TEST_QSA_ADDITIONAL | TEST_MATCH_BASELINE
+  },
+  {
+    'name':
+        "Attribute contains selector with unquoted value, matching class attribute beginning with specified substring",
+    'selector': "#attr-contains [class*= apple]",
+    'expect': ["attr-contains-p1"],
+    'level': 3,
+    'testType': TEST_QSA_ADDITIONAL | TEST_MATCH_BASELINE
+  },
+  {
+    'name':
+        "Attribute contains selector with unquoted value, matching class attribute ending with specified substring",
+    'selector': "#attr-contains [class*=orange ]",
+    'expect': ["attr-contains-p1"],
+    'level': 3,
+    'testType': TEST_QSA_ADDITIONAL | TEST_MATCH_BASELINE
+  },
+  {
+    'name':
+        "Attribute contains selector with unquoted value, matching class attribute containing specified substring",
+    'selector': "#attr-contains [class*= banana ]",
+    'expect': ["attr-contains-p1"],
+    'level': 3,
+    'testType': TEST_QSA_ADDITIONAL | TEST_MATCH_BASELINE
+  },
+
+  // Pseudo-classes
+  // - :root                 (Level 3)
+  {
+    'name': ":root pseudo-class selector, matching document root element",
+    'selector': ":root",
+    'expect': ["html"],
+    'exclude': ["element", "fragment", "detached"],
+    'level': 3,
+    'testType': TEST_QSA_ADDITIONAL | TEST_MATCH_BASELINE
+  },
+  {
+    'name': ":root pseudo-class selector, not matching document root element",
+    'selector': ":root",
+    'expect': [] /*no matches*/,
+    'exclude': ["document"],
+    'level': 3,
+    'testType': TEST_QSA_ADDITIONAL
+  },
+
+  // - :nth-child(n)         (Level 3)
+  {
+    'name': ":nth-child selector, matching the third child element",
+    'selector': "#pseudo-nth-table1 :nth-child(3)",
+    'expect': [
+      "pseudo-nth-td3",
+      "pseudo-nth-td9",
+      "pseudo-nth-tr3",
+      "pseudo-nth-td15"
+    ],
+    'level': 3,
+    'testType': TEST_QSA_ADDITIONAL | TEST_MATCH_BASELINE
+  },
+  {
+    'name': ":nth-child selector, matching every third child element",
+    'selector': "#pseudo-nth li:nth-child(3n)",
+    'expect': [
+      "pseudo-nth-li3",
+      "pseudo-nth-li6",
+      "pseudo-nth-li9",
+      "pseudo-nth-li12"
+    ],
+    'level': 3,
+    'testType': TEST_QSA_ADDITIONAL | TEST_MATCH_BASELINE
+  },
+  {
+    'name':
+        ":nth-child selector, matching every second child element, starting from the fourth",
+    'selector': "#pseudo-nth li:nth-child(2n+4)",
+    'expect': [
+      "pseudo-nth-li4",
+      "pseudo-nth-li6",
+      "pseudo-nth-li8",
+      "pseudo-nth-li10",
+      "pseudo-nth-li12"
+    ],
+    'level': 3,
+    'testType': TEST_QSA_ADDITIONAL | TEST_MATCH_BASELINE
+  },
+  {
+    'name':
+        ":nth-child selector, matching every fourth child element, starting from the third",
+    'selector': "#pseudo-nth-p1 :nth-child(4n-1)",
+    'expect': ["pseudo-nth-em2", "pseudo-nth-span3"],
+    'level': 3,
+    'testType': TEST_QSA_ADDITIONAL | TEST_MATCH_BASELINE
+  },
+
+  // - :nth-last-child       (Level 3)
+  {
+    'name': ":nth-last-child selector, matching the third last child element",
+    'selector': "#pseudo-nth-table1 :nth-last-child(3)",
+    'expect': [
+      "pseudo-nth-tr1",
+      "pseudo-nth-td4",
+      "pseudo-nth-td10",
+      "pseudo-nth-td16"
+    ],
+    'level': 3,
+    'testType': TEST_QSA_ADDITIONAL | TEST_MATCH_BASELINE
+  },
+  {
+    'name':
+        ":nth-last-child selector, matching every third child element from the end",
+    'selector': "#pseudo-nth li:nth-last-child(3n)",
+    'expect': [
+      "pseudo-nth-li1",
+      "pseudo-nth-li4",
+      "pseudo-nth-li7",
+      "pseudo-nth-li10"
+    ],
+    'level': 3,
+    'testType': TEST_QSA_ADDITIONAL | TEST_MATCH_BASELINE
+  },
+  {
+    'name':
+        ":nth-last-child selector, matching every second child element from the end, starting from the fourth last",
+    'selector': "#pseudo-nth li:nth-last-child(2n+4)",
+    'expect': [
+      "pseudo-nth-li1",
+      "pseudo-nth-li3",
+      "pseudo-nth-li5",
+      "pseudo-nth-li7",
+      "pseudo-nth-li9"
+    ],
+    'level': 3,
+    'testType': TEST_QSA_ADDITIONAL | TEST_MATCH_BASELINE
+  },
+  {
+    'name':
+        ":nth-last-child selector, matching every fourth element from the end, starting from the third last",
+    'selector': "#pseudo-nth-p1 :nth-last-child(4n-1)",
+    'expect': ["pseudo-nth-span2", "pseudo-nth-span4"],
+    'level': 3,
+    'testType': TEST_QSA_ADDITIONAL | TEST_MATCH_BASELINE
+  },
+
+  // - :nth-of-type(n)       (Level 3)
+  {
+    'name': ":nth-of-type selector, matching the third em element",
+    'selector': "#pseudo-nth-p1 em:nth-of-type(3)",
+    'expect': ["pseudo-nth-em3"],
+    'level': 3,
+    'testType': TEST_QSA_ADDITIONAL | TEST_MATCH_BASELINE
+  },
+  {
+    'name':
+        ":nth-of-type selector, matching every second element of their type",
+    'selector': "#pseudo-nth-p1 :nth-of-type(2n)",
+    'expect': [
+      "pseudo-nth-em2",
+      "pseudo-nth-span2",
+      "pseudo-nth-span4",
+      "pseudo-nth-strong2",
+      "pseudo-nth-em4"
+    ],
+    'level': 3,
+    'testType': TEST_QSA_ADDITIONAL | TEST_MATCH_BASELINE
+  },
+  {
+    'name':
+        ":nth-of-type selector, matching every second elemetn of their type, starting from the first",
+    'selector': "#pseudo-nth-p1 span:nth-of-type(2n-1)",
+    'expect': ["pseudo-nth-span1", "pseudo-nth-span3"],
+    'level': 3,
+    'testType': TEST_QSA_ADDITIONAL | TEST_MATCH_BASELINE
+  },
+
+  // - :nth-last-of-type(n)  (Level 3)
+  {
+    'name': ":nth-last-of-type selector, matching the thrid last em element",
+    'selector': "#pseudo-nth-p1 em:nth-last-of-type(3)",
+    'expect': ["pseudo-nth-em2"],
+    'level': 3,
+    'testType': TEST_QSA_ADDITIONAL | TEST_MATCH_BASELINE
+  },
+  {
+    'name':
+        ":nth-last-of-type selector, matching every second last element of their type",
+    'selector': "#pseudo-nth-p1 :nth-last-of-type(2n)",
+    'expect': [
+      "pseudo-nth-span1",
+      "pseudo-nth-em1",
+      "pseudo-nth-strong1",
+      "pseudo-nth-em3",
+      "pseudo-nth-span3"
+    ],
+    'level': 3,
+    'testType': TEST_QSA_ADDITIONAL | TEST_MATCH_BASELINE
+  },
+  {
+    'name':
+        ":nth-last-of-type selector, matching every second last element of their type, starting from the last",
+    'selector': "#pseudo-nth-p1 span:nth-last-of-type(2n-1)",
+    'expect': ["pseudo-nth-span2", "pseudo-nth-span4"],
+    'level': 3,
+    'testType': TEST_QSA_ADDITIONAL | TEST_MATCH_BASELINE
+  },
+
+  // - :first-of-type        (Level 3)
+  {
+    'name': ":first-of-type selector, matching the first em element",
+    'selector': "#pseudo-nth-p1 em:first-of-type",
+    'expect': ["pseudo-nth-em1"],
+    'level': 3,
+    'testType': TEST_QSA_ADDITIONAL | TEST_MATCH_BASELINE
+  },
+  {
+    'name':
+        ":first-of-type selector, matching the first of every type of element",
+    'selector': "#pseudo-nth-p1 :first-of-type",
+    'expect': ["pseudo-nth-span1", "pseudo-nth-em1", "pseudo-nth-strong1"],
+    'level': 3,
+    'testType': TEST_QSA_ADDITIONAL | TEST_MATCH_BASELINE
+  },
+  {
+    'name':
+        ":first-of-type selector, matching the first td element in each table row",
+    'selector': "#pseudo-nth-table1 tr :first-of-type",
+    'expect': ["pseudo-nth-td1", "pseudo-nth-td7", "pseudo-nth-td13"],
+    'level': 3,
+    'testType': TEST_QSA_ADDITIONAL | TEST_MATCH_BASELINE
+  },
+
+  // - :last-of-type         (Level 3)
+  {
+    'name': ":last-of-type selector, matching the last em elemnet",
+    'selector': "#pseudo-nth-p1 em:last-of-type",
+    'expect': ["pseudo-nth-em4"],
+    'level': 3,
+    'testType': TEST_QSA_ADDITIONAL | TEST_MATCH_BASELINE
+  },
+  {
+    'name':
+        ":last-of-type selector, matching the last of every type of element",
+    'selector': "#pseudo-nth-p1 :last-of-type",
+    'expect': ["pseudo-nth-span4", "pseudo-nth-strong2", "pseudo-nth-em4"],
+    'level': 3,
+    'testType': TEST_QSA_ADDITIONAL | TEST_MATCH_BASELINE
+  },
+  {
+    'name':
+        ":last-of-type selector, matching the last td element in each table row",
+    'selector': "#pseudo-nth-table1 tr :last-of-type",
+    'expect': ["pseudo-nth-td6", "pseudo-nth-td12", "pseudo-nth-td18"],
+    'level': 3,
+    'testType': TEST_QSA_ADDITIONAL | TEST_MATCH_BASELINE
+  },
+
+  // - :first-child
+  {
+    'name':
+        ":first-child pseudo-class selector, matching first child div element",
+    'selector': "#pseudo-first-child div:first-child",
+    'expect': ["pseudo-first-child-div1"],
+    'level': 2,
+    'testType': TEST_QSA_BASELINE | TEST_MATCH_BASELINE
+  },
+  {
+    'name':
+        ":first-child pseudo-class selector, doesn't match non-first-child elements",
+    'selector':
+        ".pseudo-first-child-div2:first-child, .pseudo-first-child-div3:first-child",
+    'expect': [] /*no matches*/,
+    'level': 2,
+    'testType': TEST_QSA_BASELINE
+  },
+  {
+    'name':
+        ":first-child pseudo-class selector, matching first-child of multiple elements",
+    'selector': "#pseudo-first-child span:first-child",
+    'expect': [
+      "pseudo-first-child-span1",
+      "pseudo-first-child-span3",
+      "pseudo-first-child-span5"
+    ],
+    'level': 2,
+    'testType': TEST_QSA_BASELINE | TEST_MATCH_BASELINE
+  },
+
+  // - :last-child           (Level 3)
+  {
+    'name':
+        ":last-child pseudo-class selector, matching last child div element",
+    'selector': "#pseudo-last-child div:last-child",
+    'expect': ["pseudo-last-child-div3"],
+    'level': 3,
+    'testType': TEST_QSA_ADDITIONAL | TEST_MATCH_BASELINE
+  },
+  {
+    'name':
+        ":last-child pseudo-class selector, doesn't match non-last-child elements",
+    'selector':
+        ".pseudo-last-child-div1:last-child, .pseudo-last-child-div2:first-child",
+    'expect': [] /*no matches*/,
+    'level': 3,
+    'testType': TEST_QSA_ADDITIONAL
+  },
+  {
+    'name':
+        ":last-child pseudo-class selector, matching first-child of multiple elements",
+    'selector': "#pseudo-last-child span:last-child",
+    'expect': [
+      "pseudo-last-child-span2",
+      "pseudo-last-child-span4",
+      "pseudo-last-child-span6"
+    ],
+    'level': 3,
+    'testType': TEST_QSA_ADDITIONAL | TEST_MATCH_BASELINE
+  },
+
+  // - :only-child           (Level 3)
+  {
+    'name':
+        ":pseudo-only-child pseudo-class selector, matching all only-child elements",
+    'selector': "#pseudo-only :only-child",
+    'expect': ["pseudo-only-span1"],
+    'level': 3,
+    'testType': TEST_QSA_ADDITIONAL | TEST_MATCH_BASELINE
+  },
+  {
+    'name':
+        ":pseudo-only-child pseudo-class selector, matching only-child em elements",
+    'selector': "#pseudo-only em:only-child",
+    'expect': [] /*no matches*/,
+    'level': 3,
+    'testType': TEST_QSA_ADDITIONAL
+  },
+
+  // - :only-of-type         (Level 3)
+  {
+    'name':
+        ":pseudo-only-of-type pseudo-class selector, matching all elements with no siblings of the same type",
+    'selector': "#pseudo-only :only-of-type",
+    'expect': ["pseudo-only-span1", "pseudo-only-em1"],
+    'level': 3,
+    'testType': TEST_QSA_ADDITIONAL | TEST_MATCH_BASELINE
+  },
+  {
+    'name':
+        ":pseudo-only-of-type pseudo-class selector, matching em elements with no siblings of the same type",
+    'selector': "#pseudo-only em:only-of-type",
+    'expect': ["pseudo-only-em1"],
+    'level': 3,
+    'testType': TEST_QSA_ADDITIONAL | TEST_MATCH_BASELINE
+  },
+
+  // - :empty                (Level 3)
+  {
+    'name': ":empty pseudo-class selector, matching empty p elements",
+    'selector': "#pseudo-empty p:empty",
+    'expect': ["pseudo-empty-p1", "pseudo-empty-p2"],
+    'level': 3,
+    'testType': TEST_QSA_ADDITIONAL | TEST_MATCH_BASELINE
+  },
+  {
+    'name': ":empty pseudo-class selector, matching all empty elements",
+    'selector': "#pseudo-empty :empty",
+    'expect': ["pseudo-empty-p1", "pseudo-empty-p2", "pseudo-empty-span1"],
+    'level': 3,
+    'testType': TEST_QSA_ADDITIONAL | TEST_MATCH_BASELINE
+  },
+
+  // - :link and :visited
+  // Implementations may treat all visited links as unvisited, so these cannot be tested separately.
+  // The only guarantee is that ":link,:visited" matches the set of all visited and unvisited links and that they are individually mutually exclusive sets.
+  {
+    'name':
+        ":link and :visited pseudo-class selectors, matching a and area elements with href attributes",
+    'selector': "#pseudo-link :link, #pseudo-link :visited",
+    'expect': ["pseudo-link-a1", "pseudo-link-a2", "pseudo-link-area1"],
+    'level': 1,
+    'testType': TEST_QSA_BASELINE | TEST_MATCH_BASELINE
+  },
+  {
+    'name':
+        ":link and :visited pseudo-class selectors, matching link elements with href attributes",
+    'selector': "#head :link, #head :visited",
+    'expect': ["pseudo-link-link1", "pseudo-link-link2"],
+    'exclude': ["element", "fragment", "detached"],
+    'level': 1,
+    'testType': TEST_QSA_BASELINE | TEST_MATCH_BASELINE
+  },
+  {
+    'name':
+        ":link and :visited pseudo-class selectors, not matching link elements with href attributes",
+    'selector': "#head :link, #head :visited",
+    'expect': [] /*no matches*/,
+    'exclude': ["document"],
+    'level': 1,
+    'testType': TEST_QSA_BASELINE
+  },
+  {
+    'name':
+        ":link and :visited pseudo-class selectors, chained, mutually exclusive pseudo-classes match nothing",
+    'selector': ":link:visited",
+    'expect': [] /*no matches*/,
+    'exclude': ["document"],
+    'level': 1,
+    'testType': TEST_QSA_BASELINE
+  },
+
+  // - :target               (Level 3)
+  {
+    'name':
+        ":target pseudo-class selector, matching the element referenced by the URL fragment identifier",
+    'selector': ":target",
+    'expect': [] /*no matches*/,
+    'exclude': ["document", "element"],
+    'level': 3,
+    'testType': TEST_QSA_ADDITIONAL
+  },
+  {
+    'name':
+        ":target pseudo-class selector, matching the element referenced by the URL fragment identifier",
+    'selector': ":target",
+    'expect': ["target"],
+    'exclude': ["fragment", "detached"],
+    'level': 3,
+    'testType': TEST_QSA_ADDITIONAL | TEST_MATCH_BASELINE
+  },
+
+  // - :lang()
+  {
+    'name': ":lang pseudo-class selector, matching inherited language",
+    'selector': "#pseudo-lang-div1:lang(en)",
+    'expect': ["pseudo-lang-div1"],
+    'exclude': ["detached", "fragment"],
+    'level': 2,
+    'testType': TEST_QSA_BASELINE | TEST_MATCH_BASELINE
+  },
+  {
+    'name':
+        ":lang pseudo-class selector, not matching element with no inherited language",
+    'selector': "#pseudo-lang-div1:lang(en)",
+    'expect': [] /*no matches*/,
+    'exclude': ["document", "element"],
+    'level': 2,
+    'testType': TEST_QSA_BASELINE
+  },
+  {
+    'name':
+        ":lang pseudo-class selector, matching specified language with exact value",
+    'selector': "#pseudo-lang-div2:lang(fr)",
+    'expect': ["pseudo-lang-div2"],
+    'level': 2,
+    'testType': TEST_QSA_BASELINE | TEST_MATCH_BASELINE
+  },
+  {
+    'name':
+        ":lang pseudo-class selector, matching specified language with partial value",
+    'selector': "#pseudo-lang-div3:lang(en)",
+    'expect': ["pseudo-lang-div3"],
+    'level': 2,
+    'testType': TEST_QSA_BASELINE | TEST_MATCH_BASELINE
+  },
+  {
+    'name': ":lang pseudo-class selector, not matching incorrect language",
+    'selector': "#pseudo-lang-div4:lang(es-AR)",
+    'expect': [] /*no matches*/,
+    'level': 2,
+    'testType': TEST_QSA_BASELINE
+  },
+
+  // - :enabled              (Level 3)
+  {
+    'name':
+        ":enabled pseudo-class selector, matching all enabled form controls",
+    'selector': "#pseudo-ui :enabled",
+    'expect': [
+      "pseudo-ui-input1",
+      "pseudo-ui-input2",
+      "pseudo-ui-input3",
+      "pseudo-ui-input4",
+      "pseudo-ui-input5",
+      "pseudo-ui-input6",
+      "pseudo-ui-input7",
+      "pseudo-ui-input8",
+      "pseudo-ui-input9",
+      "pseudo-ui-textarea1",
+      "pseudo-ui-button1"
+    ],
+    'level': 3,
+    'testType': TEST_QSA_ADDITIONAL | TEST_MATCH_BASELINE
+  },
+
+  // - :disabled             (Level 3)
+  {
+    'name':
+        ":enabled pseudo-class selector, matching all disabled form controls",
+    'selector': "#pseudo-ui :disabled",
+    'expect': [
+      "pseudo-ui-input10",
+      "pseudo-ui-input11",
+      "pseudo-ui-input12",
+      "pseudo-ui-input13",
+      "pseudo-ui-input14",
+      "pseudo-ui-input15",
+      "pseudo-ui-input16",
+      "pseudo-ui-input17",
+      "pseudo-ui-input18",
+      "pseudo-ui-textarea2",
+      "pseudo-ui-button2"
+    ],
+    'level': 3,
+    'testType': TEST_QSA_ADDITIONAL | TEST_MATCH_BASELINE
+  },
+
+  // - :checked              (Level 3)
+  {
+    'name':
+        ":checked pseudo-class selector, matching checked radio buttons and checkboxes",
+    'selector': "#pseudo-ui :checked",
+    'expect': [
+      "pseudo-ui-input4",
+      "pseudo-ui-input6",
+      "pseudo-ui-input13",
+      "pseudo-ui-input15"
+    ],
+    'level': 3,
+    'testType': TEST_QSA_ADDITIONAL | TEST_MATCH_BASELINE
+  },
+
+  // - :not(s)               (Level 3)
+  {
+    'name': ":not pseudo-class selector, matching ",
+    'selector': "#not>:not(div)",
+    'expect': ["not-p1", "not-p2", "not-p3"],
+    'level': 3,
+    'testType': TEST_QSA_ADDITIONAL | TEST_MATCH_BASELINE
+  },
+  {
+    'name': ":not pseudo-class selector, matching ",
+    'selector': "#not * :not(:first-child)",
+    'expect': ["not-em1", "not-em2", "not-em3"],
+    'level': 3,
+    'testType': TEST_QSA_ADDITIONAL | TEST_MATCH_BASELINE
+  },
+  {
+    'name': ":not pseudo-class selector, matching nothing",
+    'selector': ":not(*)",
+    'expect': [] /* no matches */,
+    'level': 3,
+    'testType': TEST_QSA_ADDITIONAL
+  },
+  {
+    'name': ":not pseudo-class selector, matching nothing",
+    'selector': ":not(*|*)",
+    'expect': [] /* no matches */,
+    'level': 3,
+    'testType': TEST_QSA_ADDITIONAL
+  },
+
+  // Pseudo-elements
+  // - ::first-line
+  {
+    'name':
+        ":first-line pseudo-element (one-colon syntax) selector, not matching any elements",
+    'selector': "#pseudo-element:first-line",
+    'expect': [] /*no matches*/,
+    'level': 2,
+    'testType': TEST_QSA_BASELINE
+  },
+  {
+    'name':
+        "::first-line pseudo-element (two-colon syntax) selector, not matching any elements",
+    'selector': "#pseudo-element::first-line",
+    'expect': [] /*no matches*/,
+    'level': 3,
+    'testType': TEST_QSA_ADDITIONAL
+  },
+
+  // - ::first-letter
+  {
+    'name':
+        ":first-letter pseudo-element (one-colon syntax) selector, not matching any elements",
+    'selector': "#pseudo-element:first-letter",
+    'expect': [] /*no matches*/,
+    'level': 2,
+    'testType': TEST_QSA_BASELINE
+  },
+  {
+    'name':
+        "::first-letter pseudo-element (two-colon syntax) selector, not matching any elements",
+    'selector': "#pseudo-element::first-letter",
+    'expect': [] /*no matches*/,
+    'level': 3,
+    'testType': TEST_QSA_ADDITIONAL
+  },
+
+  // - ::before
+  {
+    'name':
+        ":before pseudo-element (one-colon syntax) selector, not matching any elements",
+    'selector': "#pseudo-element:before",
+    'expect': [] /*no matches*/,
+    'level': 2,
+    'testType': TEST_QSA_BASELINE
+  },
+  {
+    'name':
+        "::before pseudo-element (two-colon syntax) selector, not matching any elements",
+    'selector': "#pseudo-element::before",
+    'expect': [] /*no matches*/,
+    'level': 3,
+    'testType': TEST_QSA_ADDITIONAL
+  },
+
+  // - ::after
+  {
+    'name':
+        ":after pseudo-element (one-colon syntax) selector, not matching any elements",
+    'selector': "#pseudo-element:after",
+    'expect': [] /*no matches*/,
+    'level': 2,
+    'testType': TEST_QSA_BASELINE
+  },
+  {
+    'name':
+        "::after pseudo-element (two-colon syntax) selector, not matching any elements",
+    'selector': "#pseudo-element::after",
+    'expect': [] /*no matches*/,
+    'level': 3,
+    'testType': TEST_QSA_ADDITIONAL
+  },
+
+  // Class Selectors
+  {
+    'name': "Class selector, matching element with specified class",
+    'selector': ".class-p",
+    'expect': ["class-p1", "class-p2", "class-p3"],
+    'level': 1,
+    'testType': TEST_QSA_BASELINE | TEST_MATCH_BASELINE
+  },
+  {
+    'name':
+        "Class selector, chained, matching only elements with all specified classes",
+    'selector': "#class .apple.orange.banana",
+    'expect': [
+      "class-div1",
+      "class-div2",
+      "class-p4",
+      "class-div3",
+      "class-p6",
+      "class-div4"
+    ],
+    'level': 1,
+    'testType': TEST_QSA_BASELINE | TEST_MATCH_BASELINE
+  },
+  {
+    'name': "Class Selector, chained, with type selector",
+    'selector': "div.apple.banana.orange",
+    'expect': ["class-div1", "class-div2", "class-div3", "class-div4"],
+    'level': 1,
+    'testType': TEST_QSA_BASELINE | TEST_MATCH_BASELINE
+  },
+  // Caution: If copying and pasting the folowing non-ASCII classes, ensure unicode normalisation is not performed in the process.
+  {
+    'name':
+        "Class selector, matching element with class value using non-ASCII characters",
+    'selector': ".台北Táiběi",
+    'expect': ["class-span1"],
+    'level': 1,
+    'testType': TEST_QSA_BASELINE | TEST_MATCH_BASELINE
+  },
+  {
+    'name':
+        "Class selector, matching multiple elements with class value using non-ASCII characters",
+    'selector': ".台北",
+    'expect': ["class-span1", "class-span2"],
+    'level': 1,
+    'testType': TEST_QSA_BASELINE | TEST_MATCH_BASELINE
+  },
+  {
+    'name':
+        "Class selector, chained, matching element with multiple class values using non-ASCII characters",
+    'selector': ".台北Táiběi.台北",
+    'expect': ["class-span1"],
+    'level': 1,
+    'testType': TEST_QSA_BASELINE | TEST_MATCH_BASELINE
+  },
+  {
+    'name':
+        "Class selector, matching element with class with escaped character",
+    'selector': ".foo\\:bar",
+    'expect': ["class-span3"],
+    'level': 1,
+    'testType': TEST_QSA_BASELINE | TEST_MATCH_BASELINE
+  },
+  {
+    'name':
+        "Class selector, matching element with class with escaped character",
+    'selector': ".test\\.foo\\[5\\]bar",
+    'expect': ["class-span4"],
+    'level': 1,
+    'testType': TEST_QSA_BASELINE | TEST_MATCH_BASELINE
+  },
+
+  // ID Selectors
+  {
+    'name': "ID selector, matching element with specified id",
+    'selector': "#id #id-div1",
+    'expect': ["id-div1"],
+    'level': 1,
+    'testType': TEST_QSA_BASELINE | TEST_MATCH_BASELINE
+  },
+  {
+    'name': "ID selector, chained, matching element with specified id",
+    'selector': "#id-div1, #id-div1",
+    'expect': ["id-div1"],
+    'level': 1,
+    'testType': TEST_QSA_BASELINE | TEST_MATCH_BASELINE
+  },
+  {
+    'name': "ID selector, chained, matching element with specified id",
+    'selector': "#id-div1, #id-div2",
+    'expect': ["id-div1", "id-div2"],
+    'level': 1,
+    'testType': TEST_QSA_BASELINE | TEST_MATCH_BASELINE
+  },
+  {
+    'name': "ID Selector, chained, with type selector",
+    'selector': "div#id-div1, div#id-div2",
+    'expect': ["id-div1", "id-div2"],
+    'level': 1,
+    'testType': TEST_QSA_BASELINE | TEST_MATCH_BASELINE
+  },
+  {
+    'name': "ID selector, not matching non-existent descendant",
+    'selector': "#id #none",
+    'expect': [] /*no matches*/,
+    'level': 1,
+    'testType': TEST_QSA_BASELINE
+  },
+  {
+    'name': "ID selector, not matching non-existent ancestor",
+    'selector': "#none #id-div1",
+    'expect': [] /*no matches*/,
+    'level': 1,
+    'testType': TEST_QSA_BASELINE
+  },
+  {
+    'name': "ID selector, matching multiple elements with duplicate id",
+    'selector': "#id-li-duplicate",
+    'expect': [
+      "id-li-duplicate",
+      "id-li-duplicate",
+      "id-li-duplicate",
+      "id-li-duplicate"
+    ],
+    'level': 1,
+    'testType': TEST_QSA_BASELINE | TEST_MATCH_BASELINE
+  },
+
+  // Caution: If copying and pasting the folowing non-ASCII IDs, ensure unicode normalisation is not performed in the process.
+  {
+    'name': "ID selector, matching id value using non-ASCII characters",
+    'selector': "#台北Táiběi",
+    'expect': ["台北Táiběi"],
+    'level': 1,
+    'testType': TEST_QSA_BASELINE | TEST_MATCH_BASELINE
+  },
+  {
+    'name': "ID selector, matching id value using non-ASCII characters",
+    'selector': "#台北",
+    'expect': ["台北"],
+    'level': 1,
+    'testType': TEST_QSA_BASELINE | TEST_MATCH_BASELINE
+  },
+  {
+    'name': "ID selector, matching id values using non-ASCII characters",
+    'selector': "#台北Táiběi, #台北",
+    'expect': ["台北Táiběi", "台北"],
+    'level': 1,
+    'testType': TEST_QSA_BASELINE | TEST_MATCH_BASELINE
+  },
+
+  // XXX runMatchesTest() in level2-lib.js can't handle this because obtaining the expected nodes requires escaping characters when generating the selector from 'expect' values
+  {
+    'name': "ID selector, matching element with id with escaped character",
+    'selector': "#\\#foo\\:bar",
+    'expect': ["#foo:bar"],
+    'level': 1,
+    'testType': TEST_QSA_BASELINE
+  },
+  {
+    'name': "ID selector, matching element with id with escaped character",
+    'selector': "#test\\.foo\\[5\\]bar",
+    'expect': ["test.foo[5]bar"],
+    'level': 1,
+    'testType': TEST_QSA_BASELINE
+  },
+
+  // Namespaces
+  // XXX runMatchesTest() in level2-lib.js can't handle these because non-HTML elements don't have a recognised id
+  {
+    'name': "Namespace selector, matching element with any namespace",
+    'selector': "#any-namespace *|div",
+    'expect': [
+      "any-namespace-div1",
+      "any-namespace-div2",
+      "any-namespace-div3",
+      "any-namespace-div4"
+    ],
+    'level': 3,
+    'testType': TEST_QSA_BASELINE
+  },
+  {
+    'name': "Namespace selector, matching div elements in no namespace only",
+    'selector': "#no-namespace |div",
+    'expect': ["no-namespace-div3"],
+    'level': 3,
+    'testType': TEST_QSA_BASELINE
+  },
+  {
+    'name': "Namespace selector, matching any elements in no namespace only",
+    'selector': "#no-namespace |*",
+    'expect': ["no-namespace-div3"],
+    'level': 3,
+    'testType': TEST_QSA_BASELINE
+  },
+
+  // Combinators
+  // - Descendant combinator ' '
+  {
+    'name':
+        "Descendant combinator, matching element that is a descendant of an element with id",
+    'selector': "#descendant div",
+    'expect': [
+      "descendant-div1",
+      "descendant-div2",
+      "descendant-div3",
+      "descendant-div4"
+    ],
+    'level': 1,
+    'testType': TEST_QSA_BASELINE | TEST_MATCH_BASELINE
+  },
+  {
+    'name':
+        "Descendant combinator, matching element with id that is a descendant of an element",
+    'selector': "body #descendant-div1",
+    'expect': ["descendant-div1"],
+    'exclude': ["detached", "fragment"],
+    'level': 1,
+    'testType': TEST_QSA_BASELINE | TEST_MATCH_BASELINE
+  },
+  {
+    'name':
+        "Descendant combinator, matching element with id that is a descendant of an element",
+    'selector': "div #descendant-div1",
+    'expect': ["descendant-div1"],
+    'level': 1,
+    'testType': TEST_QSA_BASELINE | TEST_MATCH_BASELINE
+  },
+  {
+    'name':
+        "Descendant combinator, matching element with id that is a descendant of an element with id",
+    'selector': "#descendant #descendant-div2",
+    'expect': ["descendant-div2"],
+    'level': 1,
+    'testType': TEST_QSA_BASELINE | TEST_MATCH_BASELINE
+  },
+  {
+    'name':
+        "Descendant combinator, matching element with class that is a descendant of an element with id",
+    'selector': "#descendant .descendant-div2",
+    'expect': ["descendant-div2"],
+    'level': 1,
+    'testType': TEST_QSA_BASELINE | TEST_MATCH_BASELINE
+  },
+  {
+    'name':
+        "Descendant combinator, matching element with class that is a descendant of an element with class",
+    'selector': ".descendant-div1 .descendant-div3",
+    'expect': ["descendant-div3"],
+    'level': 1,
+    'testType': TEST_QSA_BASELINE | TEST_MATCH_BASELINE
+  },
+  {
+    'name':
+        "Descendant combinator, not matching element with id that is not a descendant of an element with id",
+    'selector': "#descendant-div1 #descendant-div4",
+    'expect': [] /*no matches*/,
+    'level': 1,
+    'testType': TEST_QSA_BASELINE
+  },
+  {
+    'name': "Descendant combinator, whitespace characters",
+    'selector': "#descendant\t\r\n#descendant-div2",
+    'expect': ["descendant-div2"],
+    'level': 1,
+    'testType': TEST_QSA_BASELINE | TEST_MATCH_BASELINE
+  },
+
+  // - Child combinator '>'
+  {
+    'name':
+        "Child combinator, matching element that is a child of an element with id",
+    'selector': "#child>div",
+    'expect': ["child-div1", "child-div4"],
+    'level': 2,
+    'testType': TEST_QSA_BASELINE | TEST_MATCH_BASELINE
+  },
+  {
+    'name':
+        "Child combinator, matching element with id that is a child of an element",
+    'selector': "div>#child-div1",
+    'expect': ["child-div1"],
+    'level': 2,
+    'testType': TEST_QSA_BASELINE | TEST_MATCH_BASELINE
+  },
+  {
+    'name':
+        "Child combinator, matching element with id that is a child of an element with id",
+    'selector': "#child>#child-div1",
+    'expect': ["child-div1"],
+    'level': 2,
+    'testType': TEST_QSA_BASELINE | TEST_MATCH_BASELINE
+  },
+  {
+    'name':
+        "Child combinator, matching element with id that is a child of an element with class",
+    'selector': "#child-div1>.child-div2",
+    'expect': ["child-div2"],
+    'level': 2,
+    'testType': TEST_QSA_BASELINE | TEST_MATCH_BASELINE
+  },
+  {
+    'name':
+        "Child combinator, matching element with class that is a child of an element with class",
+    'selector': ".child-div1>.child-div2",
+    'expect': ["child-div2"],
+    'level': 2,
+    'testType': TEST_QSA_BASELINE | TEST_MATCH_BASELINE
+  },
+  {
+    'name':
+        "Child combinator, not matching element with id that is not a child of an element with id",
+    'selector': "#child>#child-div3",
+    'expect': [] /*no matches*/,
+    'level': 2,
+    'testType': TEST_QSA_BASELINE
+  },
+  {
+    'name':
+        "Child combinator, not matching element with id that is not a child of an element with class",
+    'selector': "#child-div1>.child-div3",
+    'expect': [] /*no matches*/,
+    'level': 2,
+    'testType': TEST_QSA_BASELINE
+  },
+  {
+    'name':
+        "Child combinator, not matching element with class that is not a child of an element with class",
+    'selector': ".child-div1>.child-div3",
+    'expect': [] /*no matches*/,
+    'level': 2,
+    'testType': TEST_QSA_BASELINE
+  },
+  {
+    'name': "Child combinator, surrounded by whitespace",
+    'selector': "#child-div1\t\r\n>\t\r\n#child-div2",
+    'expect': ["child-div2"],
+    'level': 2,
+    'testType': TEST_QSA_BASELINE | TEST_MATCH_BASELINE
+  },
+  {
+    'name': "Child combinator, whitespace after",
+    'selector': "#child-div1>\t\r\n#child-div2",
+    'expect': ["child-div2"],
+    'level': 2,
+    'testType': TEST_QSA_BASELINE | TEST_MATCH_BASELINE
+  },
+  {
+    'name': "Child combinator, whitespace before",
+    'selector': "#child-div1\t\r\n>#child-div2",
+    'expect': ["child-div2"],
+    'level': 2,
+    'testType': TEST_QSA_BASELINE | TEST_MATCH_BASELINE
+  },
+  {
+    'name': "Child combinator, no whitespace",
+    'selector': "#child-div1>#child-div2",
+    'expect': ["child-div2"],
+    'level': 2,
+    'testType': TEST_QSA_BASELINE | TEST_MATCH_BASELINE
+  },
+
+  // - Adjacent sibling combinator '+'
+  {
+    'name':
+        "Adjacent sibling combinator, matching element that is an adjacent sibling of an element with id",
+    'selector': "#adjacent-div2+div",
+    'expect': ["adjacent-div4"],
+    'level': 2,
+    'testType': TEST_QSA_BASELINE | TEST_MATCH_BASELINE
+  },
+  {
+    'name':
+        "Adjacent sibling combinator, matching element with id that is an adjacent sibling of an element",
+    'selector': "div+#adjacent-div4",
+    'expect': ["adjacent-div4"],
+    'level': 2,
+    'testType': TEST_QSA_BASELINE | TEST_MATCH_BASELINE
+  },
+  {
+    'name':
+        "Adjacent sibling combinator, matching element with id that is an adjacent sibling of an element with id",
+    'selector': "#adjacent-div2+#adjacent-div4",
+    'expect': ["adjacent-div4"],
+    'level': 2,
+    'testType': TEST_QSA_BASELINE | TEST_MATCH_BASELINE
+  },
+  {
+    'name':
+        "Adjacent sibling combinator, matching element with class that is an adjacent sibling of an element with id",
+    'selector': "#adjacent-div2+.adjacent-div4",
+    'expect': ["adjacent-div4"],
+    'level': 2,
+    'testType': TEST_QSA_BASELINE | TEST_MATCH_BASELINE
+  },
+  {
+    'name':
+        "Adjacent sibling combinator, matching element with class that is an adjacent sibling of an element with class",
+    'selector': ".adjacent-div2+.adjacent-div4",
+    'expect': ["adjacent-div4"],
+    'level': 2,
+    'testType': TEST_QSA_BASELINE | TEST_MATCH_BASELINE
+  },
+  {
+    'name':
+        "Adjacent sibling combinator, matching p element that is an adjacent sibling of a div element",
+    'selector': "#adjacent div+p",
+    'expect': ["adjacent-p2"],
+    'level': 2,
+    'testType': TEST_QSA_BASELINE | TEST_MATCH_BASELINE
+  },
+  {
+    'name':
+        "Adjacent sibling combinator, not matching element with id that is not an adjacent sibling of an element with id",
+    'selector': "#adjacent-div2+#adjacent-p2, #adjacent-div2+#adjacent-div1",
+    'expect': [] /*no matches*/,
+    'level': 2,
+    'testType': TEST_QSA_BASELINE
+  },
+  {
+    'name': "Adjacent sibling combinator, surrounded by whitespace",
+    'selector': "#adjacent-p2\t\r\n+\t\r\n#adjacent-p3",
+    'expect': ["adjacent-p3"],
+    'level': 2,
+    'testType': TEST_QSA_BASELINE | TEST_MATCH_BASELINE
+  },
+  {
+    'name': "Adjacent sibling combinator, whitespace after",
+    'selector': "#adjacent-p2+\t\r\n#adjacent-p3",
+    'expect': ["adjacent-p3"],
+    'level': 2,
+    'testType': TEST_QSA_BASELINE | TEST_MATCH_BASELINE
+  },
+  {
+    'name': "Adjacent sibling combinator, whitespace before",
+    'selector': "#adjacent-p2\t\r\n+#adjacent-p3",
+    'expect': ["adjacent-p3"],
+    'level': 2,
+    'testType': TEST_QSA_BASELINE | TEST_MATCH_BASELINE
+  },
+  {
+    'name': "Adjacent sibling combinator, no whitespace",
+    'selector': "#adjacent-p2+#adjacent-p3",
+    'expect': ["adjacent-p3"],
+    'level': 2,
+    'testType': TEST_QSA_BASELINE | TEST_MATCH_BASELINE
+  },
+
+  // - General sibling combinator ~ (Level 3)
+  {
+    'name':
+        "General sibling combinator, matching element that is a sibling of an element with id",
+    'selector': "#sibling-div2~div",
+    'expect': ["sibling-div4", "sibling-div6"],
+    'level': 3,
+    'testType': TEST_QSA_ADDITIONAL | TEST_MATCH_BASELINE
+  },
+  {
+    'name':
+        "General sibling combinator, matching element with id that is a sibling of an element",
+    'selector': "div~#sibling-div4",
+    'expect': ["sibling-div4"],
+    'level': 3,
+    'testType': TEST_QSA_ADDITIONAL | TEST_MATCH_BASELINE
+  },
+  {
+    'name':
+        "General sibling combinator, matching element with id that is a sibling of an element with id",
+    'selector': "#sibling-div2~#sibling-div4",
+    'expect': ["sibling-div4"],
+    'level': 3,
+    'testType': TEST_QSA_ADDITIONAL | TEST_MATCH_BASELINE
+  },
+  {
+    'name':
+        "General sibling combinator, matching element with class that is a sibling of an element with id",
+    'selector': "#sibling-div2~.sibling-div",
+    'expect': ["sibling-div4", "sibling-div6"],
+    'level': 3,
+    'testType': TEST_QSA_ADDITIONAL | TEST_MATCH_BASELINE
+  },
+  {
+    'name':
+        "General sibling combinator, matching p element that is a sibling of a div element",
+    'selector': "#sibling div~p",
+    'expect': ["sibling-p2", "sibling-p3"],
+    'level': 3,
+    'testType': TEST_QSA_ADDITIONAL | TEST_MATCH_BASELINE
+  },
+  {
+    'name':
+        "General sibling combinator, not matching element with id that is not a sibling after a p element",
+    'selector': "#sibling>p~div",
+    'expect': [] /*no matches*/,
+    'level': 3,
+    'testType': TEST_QSA_ADDITIONAL
+  },
+  {
+    'name':
+        "General sibling combinator, not matching element with id that is not a sibling after an element with id",
+    'selector': "#sibling-div2~#sibling-div3, #sibling-div2~#sibling-div1",
+    'expect': [] /*no matches*/,
+    'level': 3,
+    'testType': TEST_QSA_ADDITIONAL
+  },
+  {
+    'name': "General sibling combinator, surrounded by whitespace",
+    'selector': "#sibling-p2\t\r\n~\t\r\n#sibling-p3",
+    'expect': ["sibling-p3"],
+    'level': 3,
+    'testType': TEST_QSA_ADDITIONAL | TEST_MATCH_BASELINE
+  },
+  {
+    'name': "General sibling combinator, whitespace after",
+    'selector': "#sibling-p2~\t\r\n#sibling-p3",
+    'expect': ["sibling-p3"],
+    'level': 3,
+    'testType': TEST_QSA_ADDITIONAL | TEST_MATCH_BASELINE
+  },
+  {
+    'name': "General sibling combinator, whitespace before",
+    'selector': "#sibling-p2\t\r\n~#sibling-p3",
+    'expect': ["sibling-p3"],
+    'level': 3,
+    'testType': TEST_QSA_ADDITIONAL | TEST_MATCH_BASELINE
+  },
+  {
+    'name': "General sibling combinator, no whitespace",
+    'selector': "#sibling-p2~#sibling-p3",
+    'expect': ["sibling-p3"],
+    'level': 3,
+    'testType': TEST_QSA_ADDITIONAL | TEST_MATCH_BASELINE
+  },
+
+  // Group of selectors (comma)
+  {
+    'name': "Syntax, group of selectors separator, surrounded by whitespace",
+    'selector': "#group em\t\r \n,\t\r \n#group strong",
+    'expect': ["group-em1", "group-strong1"],
+    'level': 1,
+    'testType': TEST_QSA_BASELINE | TEST_MATCH_BASELINE
+  },
+  {
+    'name': "Syntax, group of selectors separator, whitespace after",
+    'selector': "#group em,\t\r\n#group strong",
+    'expect': ["group-em1", "group-strong1"],
+    'level': 1,
+    'testType': TEST_QSA_BASELINE | TEST_MATCH_BASELINE
+  },
+  {
+    'name': "Syntax, group of selectors separator, whitespace before",
+    'selector': "#group em\t\r\n,#group strong",
+    'expect': ["group-em1", "group-strong1"],
+    'level': 1,
+    'testType': TEST_QSA_BASELINE | TEST_MATCH_BASELINE
+  },
+  {
+    'name': "Syntax, group of selectors separator, no whitespace",
+    'selector': "#group em,#group strong",
+    'expect': ["group-em1", "group-strong1"],
+    'level': 1,
+    'testType': TEST_QSA_BASELINE | TEST_MATCH_BASELINE
+  },
+];
diff --git a/html/test/support.dart b/html/test/support.dart
new file mode 100644
index 0000000..1bb2550
--- /dev/null
+++ b/html/test/support.dart
@@ -0,0 +1,167 @@
+/// Support code for the tests in this directory.
+library support;
+
+import 'dart:io';
+import 'dart:collection';
+import 'package:path/path.dart' as path;
+import 'package:html/src/treebuilder.dart';
+import 'package:html/dom.dart';
+import 'package:html/dom_parsing.dart';
+
+typedef TreeBuilder TreeBuilderFactory(bool namespaceHTMLElements);
+
+Map<String, TreeBuilderFactory> _treeTypes;
+Map<String, TreeBuilderFactory> get treeTypes {
+  if (_treeTypes == null) {
+    // TODO(jmesserly): add DOM here once it's implemented
+    _treeTypes = {"simpletree": (useNs) => new TreeBuilder(useNs)};
+  }
+  return _treeTypes;
+}
+
+final testDataDir = Platform.script.resolve('data').toFilePath();
+
+Iterable<String> getDataFiles(String subdirectory) {
+  var dir = new Directory(path.join(testDataDir, subdirectory));
+  return dir.listSync().where((f) => f is File).map((f) => f.path);
+}
+
+// TODO(jmesserly): make this class simpler. We could probably split on
+// "\n#" instead of newline and remove a lot of code.
+class TestData extends IterableBase<Map> {
+  final String _text;
+  final String newTestHeading;
+
+  TestData(String filename, [this.newTestHeading = "data"])
+      // Note: can't use readAsLinesSync here because it splits on \r
+      : _text = new File(filename).readAsStringSync();
+
+  // Note: in Python this was a generator, but since we can't do that in Dart,
+  // it's easier to convert it into an upfront computation.
+  Iterator<Map> get iterator => _getData().iterator;
+
+  List<Map> _getData() {
+    var data = <String, String>{};
+    var key = null;
+    var result = <Map>[];
+    var lines = _text.split('\n');
+    // Remove trailing newline to match Python
+    if (lines.last == '') {
+      lines.removeLast();
+    }
+    for (var line in lines) {
+      var heading = sectionHeading(line);
+      if (heading != null) {
+        if (data.length > 0 && heading == newTestHeading) {
+          // Remove trailing newline
+          data[key] = data[key].substring(0, data[key].length - 1);
+          result.add(normaliseOutput(data));
+          data = <String, String>{};
+        }
+        key = heading;
+        data[key] = "";
+      } else if (key != null) {
+        data[key] = '${data[key]}$line\n';
+      }
+    }
+
+    if (data.length > 0) {
+      result.add(normaliseOutput(data));
+    }
+    return result;
+  }
+
+  /// If the current heading is a test section heading return the heading,
+  /// otherwise return null.
+  static String sectionHeading(String line) {
+    return line.startsWith("#") ? line.substring(1).trim() : null;
+  }
+
+  static Map normaliseOutput(Map data) {
+    // Remove trailing newlines
+    data.forEach((key, value) {
+      if (value.endsWith("\n")) {
+        data[key] = value.substring(0, value.length - 1);
+      }
+    });
+    return data;
+  }
+}
+
+/// Serialize the [document] into the html5 test data format.
+testSerializer(document) {
+  return (new TestSerializer()..visit(document)).toString();
+}
+
+/// Serializes the DOM into test format. See [testSerializer].
+class TestSerializer extends TreeVisitor {
+  final StringBuffer _str;
+  int _indent = 0;
+  String _spaces = '';
+
+  TestSerializer() : _str = new StringBuffer();
+
+  String toString() => _str.toString();
+
+  int get indent => _indent;
+
+  set indent(int value) {
+    if (_indent == value) return;
+
+    var arr = new List<int>(value);
+    for (int i = 0; i < value; i++) {
+      arr[i] = 32;
+    }
+    _spaces = new String.fromCharCodes(arr);
+    _indent = value;
+  }
+
+  void _newline() {
+    if (_str.length > 0) _str.write('\n');
+    _str.write('|$_spaces');
+  }
+
+  visitNodeFallback(Node node) {
+    _newline();
+    _str.write(node);
+    visitChildren(node);
+  }
+
+  visitChildren(Node node) {
+    indent += 2;
+    for (var child in node.nodes) visit(child);
+    indent -= 2;
+  }
+
+  visitDocument(node) => _visitDocumentOrFragment(node);
+
+  _visitDocumentOrFragment(node) {
+    indent += 1;
+    for (var child in node.nodes) visit(child);
+    indent -= 1;
+  }
+
+  visitDocumentFragment(DocumentFragment node) =>
+      _visitDocumentOrFragment(node);
+
+  visitElement(Element node) {
+    _newline();
+    _str.write(node);
+    if (node.attributes.length > 0) {
+      indent += 2;
+      var keys = new List.from(node.attributes.keys);
+      keys.sort((x, y) => x.compareTo(y));
+      for (var key in keys) {
+        var v = node.attributes[key];
+        if (key is AttributeName) {
+          AttributeName attr = key;
+          key = "${attr.prefix} ${attr.name}";
+        }
+        _newline();
+        _str.write('$key="$v"');
+      }
+      indent -= 2;
+    }
+    visitChildren(node);
+  }
+}
diff --git a/html/test/tokenizer_test.dart b/html/test/tokenizer_test.dart
new file mode 100644
index 0000000..bdac1fd
--- /dev/null
+++ b/html/test/tokenizer_test.dart
@@ -0,0 +1,265 @@
+library tokenizer_test;
+
+// Note: mirrors used to match the getattr usage in the original test
+import 'dart:convert';
+import 'dart:io';
+import 'dart:mirrors';
+import 'package:path/path.dart' as pathos;
+import 'package:unittest/unittest.dart';
+import 'package:html/src/char_encodings.dart';
+import 'package:html/src/token.dart';
+import 'package:html/src/tokenizer.dart';
+import 'package:utf/utf.dart';
+import 'support.dart';
+
+class TokenizerTestParser {
+  String _state;
+  var _lastStartTag;
+  List outputTokens;
+
+  TokenizerTestParser(String initialState, [lastStartTag])
+      : _state = initialState,
+        _lastStartTag = lastStartTag;
+
+  List parse(String str) {
+    // Note: we need to pass bytes to the tokenizer if we want it to handle BOM.
+    var bytes = codepointsToUtf8(toCodepoints(str));
+    var tokenizer = new HtmlTokenizer(bytes, encoding: 'utf-8');
+    outputTokens = [];
+
+    // Note: we can't get a closure of the state method. However, we can
+    // create a new closure to invoke it via mirrors.
+    var mtok = reflect(tokenizer);
+    tokenizer.state = () => mtok.invoke(new Symbol(_state), const []).reflectee;
+
+    if (_lastStartTag != null) {
+      tokenizer.currentToken = new StartTagToken(_lastStartTag);
+    }
+
+    while (tokenizer.moveNext()) {
+      var token = tokenizer.current;
+      switch (token.kind) {
+        case TokenKind.characters:
+          processCharacters(token);
+          break;
+        case TokenKind.spaceCharacters:
+          processSpaceCharacters(token);
+          break;
+        case TokenKind.startTag:
+          processStartTag(token);
+          break;
+        case TokenKind.endTag:
+          processEndTag(token);
+          break;
+        case TokenKind.comment:
+          processComment(token);
+          break;
+        case TokenKind.doctype:
+          processDoctype(token);
+          break;
+        case TokenKind.parseError:
+          processParseError(token);
+          break;
+      }
+    }
+
+    return outputTokens;
+  }
+
+  void processDoctype(DoctypeToken token) {
+    outputTokens.add(
+        ["DOCTYPE", token.name, token.publicId, token.systemId, token.correct]);
+  }
+
+  void processStartTag(StartTagToken token) {
+    outputTokens.add(["StartTag", token.name, token.data, token.selfClosing]);
+  }
+
+  void processEndTag(EndTagToken token) {
+    outputTokens.add(["EndTag", token.name, token.selfClosing]);
+  }
+
+  void processComment(StringToken token) {
+    outputTokens.add(["Comment", token.data]);
+  }
+
+  void processSpaceCharacters(StringToken token) {
+    processCharacters(token);
+  }
+
+  void processCharacters(StringToken token) {
+    outputTokens.add(["Character", token.data]);
+  }
+
+  void processEOF(token) {}
+
+  void processParseError(StringToken token) {
+    // TODO(jmesserly): when debugging test failures it can be useful to add
+    // logging here like `print('ParseError $token');`. It would be nice to
+    // use the actual logging library.
+    outputTokens.add(["ParseError", token.data]);
+  }
+}
+
+List concatenateCharacterTokens(List tokens) {
+  var outputTokens = [];
+  for (var token in tokens) {
+    if (token.indexOf("ParseError") == -1 && token[0] == "Character") {
+      if (outputTokens.length > 0 &&
+          outputTokens.last.indexOf("ParseError") == -1 &&
+          outputTokens.last[0] == "Character") {
+        outputTokens.last[1] = '${outputTokens.last[1]}${token[1]}';
+      } else {
+        outputTokens.add(token);
+      }
+    } else {
+      outputTokens.add(token);
+    }
+  }
+  return outputTokens;
+}
+
+List normalizeTokens(List tokens) {
+  // TODO: convert tests to reflect arrays
+  for (int i = 0; i < tokens.length; i++) {
+    var token = tokens[i];
+    if (token[0] == 'ParseError') {
+      tokens[i] = token[0];
+    }
+  }
+  return tokens;
+}
+
+/// Test whether the test has passed or failed
+///
+/// If the ignoreErrorOrder flag is set to true we don't test the relative
+/// positions of parse errors and non parse errors.
+void expectTokensMatch(
+    List expectedTokens, List receivedTokens, bool ignoreErrorOrder,
+    [bool ignoreErrors = false, String message]) {
+  var checkSelfClosing = false;
+  for (var token in expectedTokens) {
+    if (token[0] == "StartTag" && token.length == 4 ||
+        token[0] == "EndTag" && token.length == 3) {
+      checkSelfClosing = true;
+      break;
+    }
+  }
+
+  if (!checkSelfClosing) {
+    for (var token in receivedTokens) {
+      if (token[0] == "StartTag" || token[0] == "EndTag") {
+        token.removeLast();
+      }
+    }
+  }
+
+  if (!ignoreErrorOrder && !ignoreErrors) {
+    expect(receivedTokens, equals(expectedTokens), reason: message);
+  } else {
+    // Sort the tokens into two groups; non-parse errors and parse errors
+    var expectedNonErrors = expectedTokens.where((t) => t != "ParseError");
+    var receivedNonErrors = receivedTokens.where((t) => t != "ParseError");
+
+    expect(receivedNonErrors, equals(expectedNonErrors), reason: message);
+    if (!ignoreErrors) {
+      var expectedParseErrors = expectedTokens.where((t) => t == "ParseError");
+      var receivedParseErrors = receivedTokens.where((t) => t == "ParseError");
+      expect(receivedParseErrors, equals(expectedParseErrors), reason: message);
+    }
+  }
+}
+
+void runTokenizerTest(Map testInfo) {
+  // XXX - move this out into the setup function
+  // concatenate all consecutive character tokens into a single token
+  if (testInfo.containsKey('doubleEscaped')) {
+    testInfo = unescape(testInfo);
+  }
+
+  var expected = concatenateCharacterTokens(testInfo['output']);
+  if (!testInfo.containsKey('lastStartTag')) {
+    testInfo['lastStartTag'] = null;
+  }
+  var parser = new TokenizerTestParser(
+      testInfo['initialState'], testInfo['lastStartTag']);
+  var tokens = parser.parse(testInfo['input']);
+  tokens = concatenateCharacterTokens(tokens);
+  var received = normalizeTokens(tokens);
+  var errorMsg = [
+    "\n\nInitial state:",
+    testInfo['initialState'],
+    "\nInput:",
+    testInfo['input'],
+    "\nExpected:",
+    expected,
+    "\nreceived:",
+    tokens
+  ].map((s) => '$s').join('\n');
+  var ignoreErrorOrder = testInfo['ignoreErrorOrder'];
+  if (ignoreErrorOrder == null) ignoreErrorOrder = false;
+
+  expectTokensMatch(expected, received, ignoreErrorOrder, true, errorMsg);
+}
+
+Map unescape(Map testInfo) {
+  // TODO(sigmundch,jmesserly): we currently use JSON.decode to unescape the
+  // unicode characters in the string, we should use a decoding that works with
+  // any control characters.
+  decode(inp) => inp == '\u0000' ? inp : JSON.decode('"$inp"');
+
+  testInfo["input"] = decode(testInfo["input"]);
+  for (var token in testInfo["output"]) {
+    if (token == "ParseError") {
+      continue;
+    } else {
+      token[1] = decode(token[1]);
+      if (token.length > 2) {
+        for (var pair in token[2]) {
+          var key = pair[0];
+          var value = pair[1];
+          token[2].remove(key);
+          token[2][decode(key)] = decode(value);
+        }
+      }
+    }
+  }
+  return testInfo;
+}
+
+String camelCase(String s) {
+  s = s.toLowerCase();
+  var result = new StringBuffer();
+  for (var match in new RegExp(r"\W+(\w)(\w+)").allMatches(s)) {
+    if (result.length == 0) result.write(s.substring(0, match.start));
+    result.write(match.group(1).toUpperCase());
+    result.write(match.group(2));
+  }
+  return result.toString();
+}
+
+void main() {
+  for (var path in getDataFiles('tokenizer')) {
+    if (!path.endsWith('.test')) continue;
+
+    var text = new File(path).readAsStringSync();
+    var tests = JSON.decode(text);
+    var testName = pathos.basenameWithoutExtension(path);
+    var testList = tests['tests'];
+    if (testList == null) continue;
+
+    group(testName, () {
+      for (int index = 0; index < testList.length; index++) {
+        final testInfo = testList[index];
+
+        testInfo.putIfAbsent("initialStates", () => ["Data state"]);
+        for (var initialState in testInfo["initialStates"]) {
+          test(testInfo["description"], () {
+            testInfo["initialState"] = camelCase(initialState);
+            runTokenizerTest(testInfo);
+          });
+        }
+      }
+    });
+  }
+}
diff --git a/pubspec.yaml b/pubspec.yaml
index 9a88faa..3f835aa 100644
--- a/pubspec.yaml
+++ b/pubspec.yaml
@@ -2,7 +2,8 @@
 description: A new flutter project.
 
 dependencies:
-  html: any
+  html:
+    path: ./html
   flutter:
     sdk: flutter