scanner: use infinitive verb after auxiliary word could

Could, as well as should, shall, must, may, can, might, etc.
are auxiliary words. After an auxiliary word should come an
infinitive verb.
diff --git a/tests/data/a-nasty-libyaml-bug.loader-error b/tests/data/a-nasty-libyaml-bug.loader-error
new file mode 100644
index 0000000..f97d49f
--- /dev/null
+++ b/tests/data/a-nasty-libyaml-bug.loader-error
@@ -0,0 +1 @@
+[ [
\ No newline at end of file
diff --git a/tests/data/aliases-cdumper-bug.code b/tests/data/aliases-cdumper-bug.code
new file mode 100644
index 0000000..0168441
--- /dev/null
+++ b/tests/data/aliases-cdumper-bug.code
@@ -0,0 +1 @@
+[ today, today ]
diff --git a/tests/data/aliases.events b/tests/data/aliases.events
new file mode 100644
index 0000000..9139b51
--- /dev/null
+++ b/tests/data/aliases.events
@@ -0,0 +1,8 @@
+- !StreamStart
+- !DocumentStart
+- !SequenceStart
+- !Scalar { anchor: 'myanchor', tag: '!mytag', value: 'data' }
+- !Alias { anchor: 'myanchor' }
+- !SequenceEnd
+- !DocumentEnd
+- !StreamEnd
diff --git a/tests/data/bool.data b/tests/data/bool.data
new file mode 100644
index 0000000..0988b63
--- /dev/null
+++ b/tests/data/bool.data
@@ -0,0 +1,4 @@
+- yes
+- NO
+- True
+- on
diff --git a/tests/data/bool.detect b/tests/data/bool.detect
new file mode 100644
index 0000000..947ebbb
--- /dev/null
+++ b/tests/data/bool.detect
@@ -0,0 +1 @@
+tag:yaml.org,2002:bool
diff --git a/tests/data/colon-in-flow-context.loader-error b/tests/data/colon-in-flow-context.loader-error
new file mode 100644
index 0000000..13d5087
--- /dev/null
+++ b/tests/data/colon-in-flow-context.loader-error
@@ -0,0 +1 @@
+{ foo:bar }
diff --git a/tests/data/construct-binary-py2.code b/tests/data/construct-binary-py2.code
new file mode 100644
index 0000000..67ac0d5
--- /dev/null
+++ b/tests/data/construct-binary-py2.code
@@ -0,0 +1,7 @@
+{
+    "canonical":
+        "GIF89a\x0c\x00\x0c\x00\x84\x00\x00\xff\xff\xf7\xf5\xf5\xee\xe9\xe9\xe5fff\x00\x00\x00\xe7\xe7\xe7^^^\xf3\xf3\xed\x8e\x8e\x8e\xe0\xe0\xe0\x9f\x9f\x9f\x93\x93\x93\xa7\xa7\xa7\x9e\x9e\x9eiiiccc\xa3\xa3\xa3\x84\x84\x84\xff\xfe\xf9\xff\xfe\xf9\xff\xfe\xf9\xff\xfe\xf9\xff\xfe\xf9\xff\xfe\xf9\xff\xfe\xf9\xff\xfe\xf9\xff\xfe\xf9\xff\xfe\xf9\xff\xfe\xf9\xff\xfe\xf9\xff\xfe\xf9\xff\xfe\xf9!\xfe\x0eMade with GIMP\x00,\x00\x00\x00\x00\x0c\x00\x0c\x00\x00\x05,  \x8e\x810\x9e\xe3@\x14\xe8i\x10\xc4\xd1\x8a\x08\x1c\xcf\x80M$z\xef\xff0\x85p\xb8\xb01f\r\x1b\xce\x01\xc3\x01\x1e\x10' \x82\n\x01\x00;",
+    "generic":
+        "GIF89a\x0c\x00\x0c\x00\x84\x00\x00\xff\xff\xf7\xf5\xf5\xee\xe9\xe9\xe5fff\x00\x00\x00\xe7\xe7\xe7^^^\xf3\xf3\xed\x8e\x8e\x8e\xe0\xe0\xe0\x9f\x9f\x9f\x93\x93\x93\xa7\xa7\xa7\x9e\x9e\x9eiiiccc\xa3\xa3\xa3\x84\x84\x84\xff\xfe\xf9\xff\xfe\xf9\xff\xfe\xf9\xff\xfe\xf9\xff\xfe\xf9\xff\xfe\xf9\xff\xfe\xf9\xff\xfe\xf9\xff\xfe\xf9\xff\xfe\xf9\xff\xfe\xf9\xff\xfe\xf9\xff\xfe\xf9\xff\xfe\xf9!\xfe\x0eMade with GIMP\x00,\x00\x00\x00\x00\x0c\x00\x0c\x00\x00\x05,  \x8e\x810\x9e\xe3@\x14\xe8i\x10\xc4\xd1\x8a\x08\x1c\xcf\x80M$z\xef\xff0\x85p\xb8\xb01f\r\x1b\xce\x01\xc3\x01\x1e\x10' \x82\n\x01\x00;",
+    "description": "The binary value above is a tiny arrow encoded as a gif image.",
+}
diff --git a/tests/data/construct-binary-py2.data b/tests/data/construct-binary-py2.data
new file mode 100644
index 0000000..dcdb16f
--- /dev/null
+++ b/tests/data/construct-binary-py2.data
@@ -0,0 +1,12 @@
+canonical: !!binary "\
+ R0lGODlhDAAMAIQAAP//9/X17unp5WZmZgAAAOfn515eXvPz7Y6OjuDg4J+fn5\
+ OTk6enp56enmlpaWNjY6Ojo4SEhP/++f/++f/++f/++f/++f/++f/++f/++f/+\
+ +f/++f/++f/++f/++f/++SH+Dk1hZGUgd2l0aCBHSU1QACwAAAAADAAMAAAFLC\
+ AgjoEwnuNAFOhpEMTRiggcz4BNJHrv/zCFcLiwMWYNG84BwwEeECcgggoBADs="
+generic: !!binary |
+ R0lGODlhDAAMAIQAAP//9/X17unp5WZmZgAAAOfn515eXvPz7Y6OjuDg4J+fn5
+ OTk6enp56enmlpaWNjY6Ojo4SEhP/++f/++f/++f/++f/++f/++f/++f/++f/+
+ +f/++f/++f/++f/++f/++SH+Dk1hZGUgd2l0aCBHSU1QACwAAAAADAAMAAAFLC
+ AgjoEwnuNAFOhpEMTRiggcz4BNJHrv/zCFcLiwMWYNG84BwwEeECcgggoBADs=
+description:
+ The binary value above is a tiny arrow encoded as a gif image.
diff --git a/tests/data/construct-binary-py3.code b/tests/data/construct-binary-py3.code
new file mode 100644
index 0000000..30bfc3f
--- /dev/null
+++ b/tests/data/construct-binary-py3.code
@@ -0,0 +1,7 @@
+{
+    "canonical":
+        b"GIF89a\x0c\x00\x0c\x00\x84\x00\x00\xff\xff\xf7\xf5\xf5\xee\xe9\xe9\xe5fff\x00\x00\x00\xe7\xe7\xe7^^^\xf3\xf3\xed\x8e\x8e\x8e\xe0\xe0\xe0\x9f\x9f\x9f\x93\x93\x93\xa7\xa7\xa7\x9e\x9e\x9eiiiccc\xa3\xa3\xa3\x84\x84\x84\xff\xfe\xf9\xff\xfe\xf9\xff\xfe\xf9\xff\xfe\xf9\xff\xfe\xf9\xff\xfe\xf9\xff\xfe\xf9\xff\xfe\xf9\xff\xfe\xf9\xff\xfe\xf9\xff\xfe\xf9\xff\xfe\xf9\xff\xfe\xf9\xff\xfe\xf9!\xfe\x0eMade with GIMP\x00,\x00\x00\x00\x00\x0c\x00\x0c\x00\x00\x05,  \x8e\x810\x9e\xe3@\x14\xe8i\x10\xc4\xd1\x8a\x08\x1c\xcf\x80M$z\xef\xff0\x85p\xb8\xb01f\r\x1b\xce\x01\xc3\x01\x1e\x10' \x82\n\x01\x00;",
+    "generic":
+        b"GIF89a\x0c\x00\x0c\x00\x84\x00\x00\xff\xff\xf7\xf5\xf5\xee\xe9\xe9\xe5fff\x00\x00\x00\xe7\xe7\xe7^^^\xf3\xf3\xed\x8e\x8e\x8e\xe0\xe0\xe0\x9f\x9f\x9f\x93\x93\x93\xa7\xa7\xa7\x9e\x9e\x9eiiiccc\xa3\xa3\xa3\x84\x84\x84\xff\xfe\xf9\xff\xfe\xf9\xff\xfe\xf9\xff\xfe\xf9\xff\xfe\xf9\xff\xfe\xf9\xff\xfe\xf9\xff\xfe\xf9\xff\xfe\xf9\xff\xfe\xf9\xff\xfe\xf9\xff\xfe\xf9\xff\xfe\xf9\xff\xfe\xf9!\xfe\x0eMade with GIMP\x00,\x00\x00\x00\x00\x0c\x00\x0c\x00\x00\x05,  \x8e\x810\x9e\xe3@\x14\xe8i\x10\xc4\xd1\x8a\x08\x1c\xcf\x80M$z\xef\xff0\x85p\xb8\xb01f\r\x1b\xce\x01\xc3\x01\x1e\x10' \x82\n\x01\x00;",
+    "description": "The binary value above is a tiny arrow encoded as a gif image.",
+}
diff --git a/tests/data/construct-binary-py3.data b/tests/data/construct-binary-py3.data
new file mode 100644
index 0000000..dcdb16f
--- /dev/null
+++ b/tests/data/construct-binary-py3.data
@@ -0,0 +1,12 @@
+canonical: !!binary "\
+ R0lGODlhDAAMAIQAAP//9/X17unp5WZmZgAAAOfn515eXvPz7Y6OjuDg4J+fn5\
+ OTk6enp56enmlpaWNjY6Ojo4SEhP/++f/++f/++f/++f/++f/++f/++f/++f/+\
+ +f/++f/++f/++f/++f/++SH+Dk1hZGUgd2l0aCBHSU1QACwAAAAADAAMAAAFLC\
+ AgjoEwnuNAFOhpEMTRiggcz4BNJHrv/zCFcLiwMWYNG84BwwEeECcgggoBADs="
+generic: !!binary |
+ R0lGODlhDAAMAIQAAP//9/X17unp5WZmZgAAAOfn515eXvPz7Y6OjuDg4J+fn5
+ OTk6enp56enmlpaWNjY6Ojo4SEhP/++f/++f/++f/++f/++f/++f/++f/++f/+
+ +f/++f/++f/++f/++f/++SH+Dk1hZGUgd2l0aCBHSU1QACwAAAAADAAMAAAFLC
+ AgjoEwnuNAFOhpEMTRiggcz4BNJHrv/zCFcLiwMWYNG84BwwEeECcgggoBADs=
+description:
+ The binary value above is a tiny arrow encoded as a gif image.
diff --git a/tests/data/construct-bool.code b/tests/data/construct-bool.code
new file mode 100644
index 0000000..3d02580
--- /dev/null
+++ b/tests/data/construct-bool.code
@@ -0,0 +1,7 @@
+{
+    "canonical": True,
+    "answer": False,
+    "logical": True,
+    "option": True,
+    "but": { "y": "is a string", "n": "is a string" },
+}
diff --git a/tests/data/construct-bool.data b/tests/data/construct-bool.data
new file mode 100644
index 0000000..36d6519
--- /dev/null
+++ b/tests/data/construct-bool.data
@@ -0,0 +1,9 @@
+canonical: yes
+answer: NO
+logical: True
+option: on
+
+
+but:
+    y: is a string
+    n: is a string
diff --git a/tests/data/construct-custom.code b/tests/data/construct-custom.code
new file mode 100644
index 0000000..2d5f063
--- /dev/null
+++ b/tests/data/construct-custom.code
@@ -0,0 +1,10 @@
+[
+    MyTestClass1(x=1),
+    MyTestClass1(x=1, y=2, z=3),
+    MyTestClass2(x=10),
+    MyTestClass2(x=10, y=20, z=30),
+    MyTestClass3(x=1),
+    MyTestClass3(x=1, y=2, z=3),
+    MyTestClass3(x=1, y=2, z=3),
+    YAMLObject1(my_parameter='foo', my_another_parameter=[1,2,3])
+]
diff --git a/tests/data/construct-custom.data b/tests/data/construct-custom.data
new file mode 100644
index 0000000..9db0f64
--- /dev/null
+++ b/tests/data/construct-custom.data
@@ -0,0 +1,26 @@
+---
+- !tag1
+  x: 1
+- !tag1
+  x: 1
+  'y': 2
+  z: 3
+- !tag2
+  10
+- !tag2
+  =: 10
+  'y': 20
+  z: 30
+- !tag3
+  x: 1
+- !tag3
+  x: 1
+  'y': 2
+  z: 3
+- !tag3
+  =: 1
+  'y': 2
+  z: 3
+- !foo
+  my-parameter: foo
+  my-another-parameter: [1,2,3]
diff --git a/tests/data/construct-float.code b/tests/data/construct-float.code
new file mode 100644
index 0000000..8493bf2
--- /dev/null
+++ b/tests/data/construct-float.code
@@ -0,0 +1,8 @@
+{
+    "canonical": 685230.15,
+    "exponential": 685230.15,
+    "fixed": 685230.15,
+    "sexagesimal": 685230.15,
+    "negative infinity": -1e300000,
+    "not a number": 1e300000/1e300000,
+}
diff --git a/tests/data/construct-float.data b/tests/data/construct-float.data
new file mode 100644
index 0000000..b662c62
--- /dev/null
+++ b/tests/data/construct-float.data
@@ -0,0 +1,6 @@
+canonical: 6.8523015e+5
+exponential: 685.230_15e+03
+fixed: 685_230.15
+sexagesimal: 190:20:30.15
+negative infinity: -.inf
+not a number: .NaN
diff --git a/tests/data/construct-int.code b/tests/data/construct-int.code
new file mode 100644
index 0000000..1058f7b
--- /dev/null
+++ b/tests/data/construct-int.code
@@ -0,0 +1,8 @@
+{
+    "canonical": 685230,
+    "decimal": 685230,
+    "octal": 685230,
+    "hexadecimal": 685230,
+    "binary": 685230,
+    "sexagesimal": 685230,
+}
diff --git a/tests/data/construct-int.data b/tests/data/construct-int.data
new file mode 100644
index 0000000..852c314
--- /dev/null
+++ b/tests/data/construct-int.data
@@ -0,0 +1,6 @@
+canonical: 685230
+decimal: +685_230
+octal: 02472256
+hexadecimal: 0x_0A_74_AE
+binary: 0b1010_0111_0100_1010_1110
+sexagesimal: 190:20:30
diff --git a/tests/data/construct-map.code b/tests/data/construct-map.code
new file mode 100644
index 0000000..736ba48
--- /dev/null
+++ b/tests/data/construct-map.code
@@ -0,0 +1,6 @@
+{
+    "Block style":
+        { "Clark" : "Evans", "Brian" : "Ingerson", "Oren" : "Ben-Kiki" },
+    "Flow style":
+        { "Clark" : "Evans", "Brian" : "Ingerson", "Oren" : "Ben-Kiki" },
+}
diff --git a/tests/data/construct-map.data b/tests/data/construct-map.data
new file mode 100644
index 0000000..022446d
--- /dev/null
+++ b/tests/data/construct-map.data
@@ -0,0 +1,6 @@
+# Unordered set of key: value pairs.
+Block style: !!map
+  Clark : Evans
+  Brian : Ingerson
+  Oren  : Ben-Kiki
+Flow style: !!map { Clark: Evans, Brian: Ingerson, Oren: Ben-Kiki }
diff --git a/tests/data/construct-merge.code b/tests/data/construct-merge.code
new file mode 100644
index 0000000..6cd419d
--- /dev/null
+++ b/tests/data/construct-merge.code
@@ -0,0 +1,10 @@
+[
+    { "x": 1, "y": 2 },
+    { "x": 0, "y": 2 },
+    { "r": 10 },
+    { "r": 1 },
+    { "x": 1, "y": 2, "r": 10, "label": "center/big" },
+    { "x": 1, "y": 2, "r": 10, "label": "center/big" },
+    { "x": 1, "y": 2, "r": 10, "label": "center/big" },
+    { "x": 1, "y": 2, "r": 10, "label": "center/big" },
+]
diff --git a/tests/data/construct-merge.data b/tests/data/construct-merge.data
new file mode 100644
index 0000000..3fdb2e2
--- /dev/null
+++ b/tests/data/construct-merge.data
@@ -0,0 +1,27 @@
+---
+- &CENTER { x: 1, 'y': 2 }
+- &LEFT { x: 0, 'y': 2 }
+- &BIG { r: 10 }
+- &SMALL { r: 1 }
+
+# All the following maps are equal:
+
+- # Explicit keys
+  x: 1
+  'y': 2
+  r: 10
+  label: center/big
+
+- # Merge one map
+  << : *CENTER
+  r: 10
+  label: center/big
+
+- # Merge multiple maps
+  << : [ *CENTER, *BIG ]
+  label: center/big
+
+- # Override
+  << : [ *BIG, *LEFT, *SMALL ]
+  x: 1
+  label: center/big
diff --git a/tests/data/construct-null.code b/tests/data/construct-null.code
new file mode 100644
index 0000000..a895eaa
--- /dev/null
+++ b/tests/data/construct-null.code
@@ -0,0 +1,13 @@
+[
+    None,
+    { "empty": None, "canonical": None, "english": None, None: "null key" },
+    {
+        "sparse": [
+            None,
+            "2nd entry",
+            None,
+            "4th entry",
+            None,
+        ],
+    },
+]
diff --git a/tests/data/construct-null.data b/tests/data/construct-null.data
new file mode 100644
index 0000000..9ad0344
--- /dev/null
+++ b/tests/data/construct-null.data
@@ -0,0 +1,18 @@
+# A document may be null.
+---
+---
+# This mapping has four keys,
+# one has a value.
+empty:
+canonical: ~
+english: null
+~: null key
+---
+# This sequence has five
+# entries, two have values.
+sparse:
+  - ~
+  - 2nd entry
+  -
+  - 4th entry
+  - Null
diff --git a/tests/data/construct-omap.code b/tests/data/construct-omap.code
new file mode 100644
index 0000000..f4cf1b8
--- /dev/null
+++ b/tests/data/construct-omap.code
@@ -0,0 +1,8 @@
+{
+    "Bestiary": [
+        ("aardvark", "African pig-like ant eater. Ugly."),
+        ("anteater", "South-American ant eater. Two species."),
+        ("anaconda", "South-American constrictor snake. Scaly."),
+    ],
+    "Numbers": [ ("one", 1), ("two", 2), ("three", 3) ],
+}
diff --git a/tests/data/construct-omap.data b/tests/data/construct-omap.data
new file mode 100644
index 0000000..4fa0f45
--- /dev/null
+++ b/tests/data/construct-omap.data
@@ -0,0 +1,8 @@
+# Explicitly typed ordered map (dictionary).
+Bestiary: !!omap
+  - aardvark: African pig-like ant eater. Ugly.
+  - anteater: South-American ant eater. Two species.
+  - anaconda: South-American constrictor snake. Scaly.
+  # Etc.
+# Flow style
+Numbers: !!omap [ one: 1, two: 2, three : 3 ]
diff --git a/tests/data/construct-pairs.code b/tests/data/construct-pairs.code
new file mode 100644
index 0000000..64f86ee
--- /dev/null
+++ b/tests/data/construct-pairs.code
@@ -0,0 +1,9 @@
+{
+    "Block tasks": [
+        ("meeting", "with team."),
+        ("meeting", "with boss."),
+        ("break", "lunch."),
+        ("meeting", "with client."),
+    ],
+    "Flow tasks": [ ("meeting", "with team"), ("meeting", "with boss") ],
+}
diff --git a/tests/data/construct-pairs.data b/tests/data/construct-pairs.data
new file mode 100644
index 0000000..05f55b9
--- /dev/null
+++ b/tests/data/construct-pairs.data
@@ -0,0 +1,7 @@
+# Explicitly typed pairs.
+Block tasks: !!pairs
+  - meeting: with team.
+  - meeting: with boss.
+  - break: lunch.
+  - meeting: with client.
+Flow tasks: !!pairs [ meeting: with team, meeting: with boss ]
diff --git a/tests/data/construct-python-bool.code b/tests/data/construct-python-bool.code
new file mode 100644
index 0000000..170da01
--- /dev/null
+++ b/tests/data/construct-python-bool.code
@@ -0,0 +1 @@
+[ True, False ]
diff --git a/tests/data/construct-python-bool.data b/tests/data/construct-python-bool.data
new file mode 100644
index 0000000..0068869
--- /dev/null
+++ b/tests/data/construct-python-bool.data
@@ -0,0 +1 @@
+[ !!python/bool True, !!python/bool False ]
diff --git a/tests/data/construct-python-bytes-py3.code b/tests/data/construct-python-bytes-py3.code
new file mode 100644
index 0000000..b9051d8
--- /dev/null
+++ b/tests/data/construct-python-bytes-py3.code
@@ -0,0 +1 @@
+b'some binary data'
diff --git a/tests/data/construct-python-bytes-py3.data b/tests/data/construct-python-bytes-py3.data
new file mode 100644
index 0000000..9528725
--- /dev/null
+++ b/tests/data/construct-python-bytes-py3.data
@@ -0,0 +1 @@
+--- !!python/bytes 'c29tZSBiaW5hcnkgZGF0YQ=='
diff --git a/tests/data/construct-python-complex.code b/tests/data/construct-python-complex.code
new file mode 100644
index 0000000..e582dff
--- /dev/null
+++ b/tests/data/construct-python-complex.code
@@ -0,0 +1 @@
+[0.5+0j, 0.5+0.5j, 0.5j, -0.5+0.5j, -0.5+0j, -0.5-0.5j, -0.5j, 0.5-0.5j]
diff --git a/tests/data/construct-python-complex.data b/tests/data/construct-python-complex.data
new file mode 100644
index 0000000..17ebad4
--- /dev/null
+++ b/tests/data/construct-python-complex.data
@@ -0,0 +1,8 @@
+- !!python/complex 0.5+0j
+- !!python/complex 0.5+0.5j
+- !!python/complex 0.5j
+- !!python/complex -0.5+0.5j
+- !!python/complex -0.5+0j
+- !!python/complex -0.5-0.5j
+- !!python/complex -0.5j
+- !!python/complex 0.5-0.5j
diff --git a/tests/data/construct-python-float.code b/tests/data/construct-python-float.code
new file mode 100644
index 0000000..d5910a0
--- /dev/null
+++ b/tests/data/construct-python-float.code
@@ -0,0 +1 @@
+123.456
diff --git a/tests/data/construct-python-float.data b/tests/data/construct-python-float.data
new file mode 100644
index 0000000..b460eb8
--- /dev/null
+++ b/tests/data/construct-python-float.data
@@ -0,0 +1 @@
+!!python/float 123.456
diff --git a/tests/data/construct-python-int.code b/tests/data/construct-python-int.code
new file mode 100644
index 0000000..190a180
--- /dev/null
+++ b/tests/data/construct-python-int.code
@@ -0,0 +1 @@
+123
diff --git a/tests/data/construct-python-int.data b/tests/data/construct-python-int.data
new file mode 100644
index 0000000..741d669
--- /dev/null
+++ b/tests/data/construct-python-int.data
@@ -0,0 +1 @@
+!!python/int 123
diff --git a/tests/data/construct-python-long-short-py2.code b/tests/data/construct-python-long-short-py2.code
new file mode 100644
index 0000000..fafc3f1
--- /dev/null
+++ b/tests/data/construct-python-long-short-py2.code
@@ -0,0 +1 @@
+123L
diff --git a/tests/data/construct-python-long-short-py2.data b/tests/data/construct-python-long-short-py2.data
new file mode 100644
index 0000000..4bd5dc2
--- /dev/null
+++ b/tests/data/construct-python-long-short-py2.data
@@ -0,0 +1 @@
+!!python/long 123
diff --git a/tests/data/construct-python-long-short-py3.code b/tests/data/construct-python-long-short-py3.code
new file mode 100644
index 0000000..190a180
--- /dev/null
+++ b/tests/data/construct-python-long-short-py3.code
@@ -0,0 +1 @@
+123
diff --git a/tests/data/construct-python-long-short-py3.data b/tests/data/construct-python-long-short-py3.data
new file mode 100644
index 0000000..4bd5dc2
--- /dev/null
+++ b/tests/data/construct-python-long-short-py3.data
@@ -0,0 +1 @@
+!!python/long 123
diff --git a/tests/data/construct-python-name-module.code b/tests/data/construct-python-name-module.code
new file mode 100644
index 0000000..6f39148
--- /dev/null
+++ b/tests/data/construct-python-name-module.code
@@ -0,0 +1 @@
+[str, yaml.Loader, yaml.dump, abs, yaml.tokens]
diff --git a/tests/data/construct-python-name-module.data b/tests/data/construct-python-name-module.data
new file mode 100644
index 0000000..f0c9712
--- /dev/null
+++ b/tests/data/construct-python-name-module.data
@@ -0,0 +1,5 @@
+- !!python/name:str
+- !!python/name:yaml.Loader
+- !!python/name:yaml.dump
+- !!python/name:abs
+- !!python/module:yaml.tokens
diff --git a/tests/data/construct-python-none.code b/tests/data/construct-python-none.code
new file mode 100644
index 0000000..b0047fa
--- /dev/null
+++ b/tests/data/construct-python-none.code
@@ -0,0 +1 @@
+None
diff --git a/tests/data/construct-python-none.data b/tests/data/construct-python-none.data
new file mode 100644
index 0000000..7907ec3
--- /dev/null
+++ b/tests/data/construct-python-none.data
@@ -0,0 +1 @@
+!!python/none
diff --git a/tests/data/construct-python-object.code b/tests/data/construct-python-object.code
new file mode 100644
index 0000000..7f1edf1
--- /dev/null
+++ b/tests/data/construct-python-object.code
@@ -0,0 +1,23 @@
+[
+AnObject(1, 'two', [3,3,3]),
+AnInstance(1, 'two', [3,3,3]),
+
+AnObject(1, 'two', [3,3,3]),
+AnInstance(1, 'two', [3,3,3]),
+
+AState(1, 'two', [3,3,3]),
+ACustomState(1, 'two', [3,3,3]),
+
+InitArgs(1, 'two', [3,3,3]),
+InitArgsWithState(1, 'two', [3,3,3]),
+
+NewArgs(1, 'two', [3,3,3]),
+NewArgsWithState(1, 'two', [3,3,3]),
+
+Reduce(1, 'two', [3,3,3]),
+ReduceWithState(1, 'two', [3,3,3]),
+
+MyInt(3),
+MyList(3),
+MyDict(3),
+]
diff --git a/tests/data/construct-python-object.data b/tests/data/construct-python-object.data
new file mode 100644
index 0000000..bce8b2e
--- /dev/null
+++ b/tests/data/construct-python-object.data
@@ -0,0 +1,21 @@
+- !!python/object:test_constructor.AnObject { foo: 1, bar: two, baz: [3,3,3] }
+- !!python/object:test_constructor.AnInstance { foo: 1, bar: two, baz: [3,3,3] }
+
+- !!python/object/new:test_constructor.AnObject { args: [1, two], kwds: {baz: [3,3,3]} }
+- !!python/object/apply:test_constructor.AnInstance { args: [1, two], kwds: {baz: [3,3,3]} }
+
+- !!python/object:test_constructor.AState { _foo: 1, _bar: two, _baz: [3,3,3] }
+- !!python/object/new:test_constructor.ACustomState { state: !!python/tuple [1, two, [3,3,3]] }
+
+- !!python/object/new:test_constructor.InitArgs [1, two, [3,3,3]]
+- !!python/object/new:test_constructor.InitArgsWithState { args: [1, two], state: [3,3,3] }
+
+- !!python/object/new:test_constructor.NewArgs [1, two, [3,3,3]]
+- !!python/object/new:test_constructor.NewArgsWithState { args: [1, two], state: [3,3,3] }
+
+- !!python/object/apply:test_constructor.Reduce [1, two, [3,3,3]]
+- !!python/object/apply:test_constructor.ReduceWithState { args: [1, two], state: [3,3,3] }
+
+- !!python/object/new:test_constructor.MyInt [3]
+- !!python/object/new:test_constructor.MyList { listitems: [~, ~, ~] }
+- !!python/object/new:test_constructor.MyDict { dictitems: {0, 1, 2} }
diff --git a/tests/data/construct-python-str-ascii.code b/tests/data/construct-python-str-ascii.code
new file mode 100644
index 0000000..d9d62f6
--- /dev/null
+++ b/tests/data/construct-python-str-ascii.code
@@ -0,0 +1 @@
+"ascii string"
diff --git a/tests/data/construct-python-str-ascii.data b/tests/data/construct-python-str-ascii.data
new file mode 100644
index 0000000..a83349e
--- /dev/null
+++ b/tests/data/construct-python-str-ascii.data
@@ -0,0 +1 @@
+--- !!python/str "ascii string"
diff --git a/tests/data/construct-python-str-utf8-py2.code b/tests/data/construct-python-str-utf8-py2.code
new file mode 100644
index 0000000..47b28ab
--- /dev/null
+++ b/tests/data/construct-python-str-utf8-py2.code
@@ -0,0 +1 @@
+u'\u042d\u0442\u043e \u0443\u043d\u0438\u043a\u043e\u0434\u043d\u0430\u044f \u0441\u0442\u0440\u043e\u043a\u0430'.encode('utf-8')
diff --git a/tests/data/construct-python-str-utf8-py2.data b/tests/data/construct-python-str-utf8-py2.data
new file mode 100644
index 0000000..9ef2c72
--- /dev/null
+++ b/tests/data/construct-python-str-utf8-py2.data
@@ -0,0 +1 @@
+--- !!python/str "Это уникодная строка"
diff --git a/tests/data/construct-python-str-utf8-py3.code b/tests/data/construct-python-str-utf8-py3.code
new file mode 100644
index 0000000..9f66032
--- /dev/null
+++ b/tests/data/construct-python-str-utf8-py3.code
@@ -0,0 +1 @@
+'\u042d\u0442\u043e \u0443\u043d\u0438\u043a\u043e\u0434\u043d\u0430\u044f \u0441\u0442\u0440\u043e\u043a\u0430'
diff --git a/tests/data/construct-python-str-utf8-py3.data b/tests/data/construct-python-str-utf8-py3.data
new file mode 100644
index 0000000..9ef2c72
--- /dev/null
+++ b/tests/data/construct-python-str-utf8-py3.data
@@ -0,0 +1 @@
+--- !!python/str "Это уникодная строка"
diff --git a/tests/data/construct-python-tuple-list-dict.code b/tests/data/construct-python-tuple-list-dict.code
new file mode 100644
index 0000000..20ced98
--- /dev/null
+++ b/tests/data/construct-python-tuple-list-dict.code
@@ -0,0 +1,6 @@
+[
+    [1, 2, 3, 4],
+    (1, 2, 3, 4),
+    {1: 2, 3: 4},
+    {(0,0): 0, (0,1): 1, (1,0): 1, (1,1): 0},
+]
diff --git a/tests/data/construct-python-tuple-list-dict.data b/tests/data/construct-python-tuple-list-dict.data
new file mode 100644
index 0000000..c56159b
--- /dev/null
+++ b/tests/data/construct-python-tuple-list-dict.data
@@ -0,0 +1,8 @@
+- !!python/list [1, 2, 3, 4]
+- !!python/tuple [1, 2, 3, 4]
+- !!python/dict {1: 2, 3: 4}
+- !!python/dict
+    !!python/tuple [0,0]: 0
+    !!python/tuple [0,1]: 1
+    !!python/tuple [1,0]: 1
+    !!python/tuple [1,1]: 0
diff --git a/tests/data/construct-python-unicode-ascii-py2.code b/tests/data/construct-python-unicode-ascii-py2.code
new file mode 100644
index 0000000..d4cd82c
--- /dev/null
+++ b/tests/data/construct-python-unicode-ascii-py2.code
@@ -0,0 +1 @@
+u"ascii string"
diff --git a/tests/data/construct-python-unicode-ascii-py2.data b/tests/data/construct-python-unicode-ascii-py2.data
new file mode 100644
index 0000000..3a0647b
--- /dev/null
+++ b/tests/data/construct-python-unicode-ascii-py2.data
@@ -0,0 +1 @@
+--- !!python/unicode "ascii string"
diff --git a/tests/data/construct-python-unicode-ascii-py3.code b/tests/data/construct-python-unicode-ascii-py3.code
new file mode 100644
index 0000000..d9d62f6
--- /dev/null
+++ b/tests/data/construct-python-unicode-ascii-py3.code
@@ -0,0 +1 @@
+"ascii string"
diff --git a/tests/data/construct-python-unicode-ascii-py3.data b/tests/data/construct-python-unicode-ascii-py3.data
new file mode 100644
index 0000000..3a0647b
--- /dev/null
+++ b/tests/data/construct-python-unicode-ascii-py3.data
@@ -0,0 +1 @@
+--- !!python/unicode "ascii string"
diff --git a/tests/data/construct-python-unicode-utf8-py2.code b/tests/data/construct-python-unicode-utf8-py2.code
new file mode 100644
index 0000000..2793ac7
--- /dev/null
+++ b/tests/data/construct-python-unicode-utf8-py2.code
@@ -0,0 +1 @@
+u'\u042d\u0442\u043e \u0443\u043d\u0438\u043a\u043e\u0434\u043d\u0430\u044f \u0441\u0442\u0440\u043e\u043a\u0430'
diff --git a/tests/data/construct-python-unicode-utf8-py2.data b/tests/data/construct-python-unicode-utf8-py2.data
new file mode 100644
index 0000000..5a980ea
--- /dev/null
+++ b/tests/data/construct-python-unicode-utf8-py2.data
@@ -0,0 +1 @@
+--- !!python/unicode "Это уникодная строка"
diff --git a/tests/data/construct-python-unicode-utf8-py3.code b/tests/data/construct-python-unicode-utf8-py3.code
new file mode 100644
index 0000000..9f66032
--- /dev/null
+++ b/tests/data/construct-python-unicode-utf8-py3.code
@@ -0,0 +1 @@
+'\u042d\u0442\u043e \u0443\u043d\u0438\u043a\u043e\u0434\u043d\u0430\u044f \u0441\u0442\u0440\u043e\u043a\u0430'
diff --git a/tests/data/construct-python-unicode-utf8-py3.data b/tests/data/construct-python-unicode-utf8-py3.data
new file mode 100644
index 0000000..5a980ea
--- /dev/null
+++ b/tests/data/construct-python-unicode-utf8-py3.data
@@ -0,0 +1 @@
+--- !!python/unicode "Это уникодная строка"
diff --git a/tests/data/construct-seq.code b/tests/data/construct-seq.code
new file mode 100644
index 0000000..0c90c05
--- /dev/null
+++ b/tests/data/construct-seq.code
@@ -0,0 +1,4 @@
+{
+    "Block style": ["Mercury", "Venus", "Earth", "Mars", "Jupiter", "Saturn", "Uranus", "Neptune", "Pluto"],
+    "Flow style": ["Mercury", "Venus", "Earth", "Mars", "Jupiter", "Saturn", "Uranus", "Neptune", "Pluto"],
+}
diff --git a/tests/data/construct-seq.data b/tests/data/construct-seq.data
new file mode 100644
index 0000000..bb92fd1
--- /dev/null
+++ b/tests/data/construct-seq.data
@@ -0,0 +1,15 @@
+# Ordered sequence of nodes
+Block style: !!seq
+- Mercury   # Rotates - no light/dark sides.
+- Venus     # Deadliest. Aptly named.
+- Earth     # Mostly dirt.
+- Mars      # Seems empty.
+- Jupiter   # The king.
+- Saturn    # Pretty.
+- Uranus    # Where the sun hardly shines.
+- Neptune   # Boring. No rings.
+- Pluto     # You call this a planet?
+Flow style: !!seq [ Mercury, Venus, Earth, Mars,      # Rocks
+                    Jupiter, Saturn, Uranus, Neptune, # Gas
+                    Pluto ]                           # Overrated
+
diff --git a/tests/data/construct-set.code b/tests/data/construct-set.code
new file mode 100644
index 0000000..aa090e8
--- /dev/null
+++ b/tests/data/construct-set.code
@@ -0,0 +1,4 @@
+{
+    "baseball players": set(["Mark McGwire", "Sammy Sosa", "Ken Griffey"]),
+    "baseball teams": set(["Boston Red Sox", "Detroit Tigers", "New York Yankees"]),
+}
diff --git a/tests/data/construct-set.data b/tests/data/construct-set.data
new file mode 100644
index 0000000..e05dc88
--- /dev/null
+++ b/tests/data/construct-set.data
@@ -0,0 +1,7 @@
+# Explicitly typed set.
+baseball players: !!set
+  ? Mark McGwire
+  ? Sammy Sosa
+  ? Ken Griffey
+# Flow style
+baseball teams: !!set { Boston Red Sox, Detroit Tigers, New York Yankees }
diff --git a/tests/data/construct-str-ascii.code b/tests/data/construct-str-ascii.code
new file mode 100644
index 0000000..d9d62f6
--- /dev/null
+++ b/tests/data/construct-str-ascii.code
@@ -0,0 +1 @@
+"ascii string"
diff --git a/tests/data/construct-str-ascii.data b/tests/data/construct-str-ascii.data
new file mode 100644
index 0000000..0d93013
--- /dev/null
+++ b/tests/data/construct-str-ascii.data
@@ -0,0 +1 @@
+--- !!str "ascii string"
diff --git a/tests/data/construct-str-utf8-py2.code b/tests/data/construct-str-utf8-py2.code
new file mode 100644
index 0000000..2793ac7
--- /dev/null
+++ b/tests/data/construct-str-utf8-py2.code
@@ -0,0 +1 @@
+u'\u042d\u0442\u043e \u0443\u043d\u0438\u043a\u043e\u0434\u043d\u0430\u044f \u0441\u0442\u0440\u043e\u043a\u0430'
diff --git a/tests/data/construct-str-utf8-py2.data b/tests/data/construct-str-utf8-py2.data
new file mode 100644
index 0000000..e355f18
--- /dev/null
+++ b/tests/data/construct-str-utf8-py2.data
@@ -0,0 +1 @@
+--- !!str "Это уникодная строка"
diff --git a/tests/data/construct-str-utf8-py3.code b/tests/data/construct-str-utf8-py3.code
new file mode 100644
index 0000000..9f66032
--- /dev/null
+++ b/tests/data/construct-str-utf8-py3.code
@@ -0,0 +1 @@
+'\u042d\u0442\u043e \u0443\u043d\u0438\u043a\u043e\u0434\u043d\u0430\u044f \u0441\u0442\u0440\u043e\u043a\u0430'
diff --git a/tests/data/construct-str-utf8-py3.data b/tests/data/construct-str-utf8-py3.data
new file mode 100644
index 0000000..e355f18
--- /dev/null
+++ b/tests/data/construct-str-utf8-py3.data
@@ -0,0 +1 @@
+--- !!str "Это уникодная строка"
diff --git a/tests/data/construct-str.code b/tests/data/construct-str.code
new file mode 100644
index 0000000..8d57214
--- /dev/null
+++ b/tests/data/construct-str.code
@@ -0,0 +1 @@
+{ "string": "abcd" }
diff --git a/tests/data/construct-str.data b/tests/data/construct-str.data
new file mode 100644
index 0000000..606ac6b
--- /dev/null
+++ b/tests/data/construct-str.data
@@ -0,0 +1 @@
+string: abcd
diff --git a/tests/data/construct-timestamp.code b/tests/data/construct-timestamp.code
new file mode 100644
index 0000000..ffc3b2f
--- /dev/null
+++ b/tests/data/construct-timestamp.code
@@ -0,0 +1,7 @@
+{
+    "canonical": datetime.datetime(2001, 12, 15, 2, 59, 43, 100000),
+    "valid iso8601": datetime.datetime(2001, 12, 15, 2, 59, 43, 100000),
+    "space separated": datetime.datetime(2001, 12, 15, 2, 59, 43, 100000),
+    "no time zone (Z)": datetime.datetime(2001, 12, 15, 2, 59, 43, 100000),
+    "date (00:00:00Z)": datetime.date(2002, 12, 14),
+}
diff --git a/tests/data/construct-timestamp.data b/tests/data/construct-timestamp.data
new file mode 100644
index 0000000..c5f3840
--- /dev/null
+++ b/tests/data/construct-timestamp.data
@@ -0,0 +1,5 @@
+canonical:        2001-12-15T02:59:43.1Z
+valid iso8601:    2001-12-14t21:59:43.10-05:00
+space separated:  2001-12-14 21:59:43.10 -5
+no time zone (Z): 2001-12-15 2:59:43.10
+date (00:00:00Z): 2002-12-14
diff --git a/tests/data/construct-value.code b/tests/data/construct-value.code
new file mode 100644
index 0000000..f1f015e
--- /dev/null
+++ b/tests/data/construct-value.code
@@ -0,0 +1,9 @@
+[
+    { "link with": [ "library1.dll", "library2.dll" ] },
+    {
+        "link with": [
+            { "=": "library1.dll", "version": 1.2 },
+            { "=": "library2.dll", "version": 2.3 },
+        ],
+    },
+]
diff --git a/tests/data/construct-value.data b/tests/data/construct-value.data
new file mode 100644
index 0000000..3eb7919
--- /dev/null
+++ b/tests/data/construct-value.data
@@ -0,0 +1,10 @@
+---     # Old schema
+link with:
+  - library1.dll
+  - library2.dll
+---     # New schema
+link with:
+  - = : library1.dll
+    version: 1.2
+  - = : library2.dll
+    version: 2.3
diff --git a/tests/data/document-separator-in-quoted-scalar.loader-error b/tests/data/document-separator-in-quoted-scalar.loader-error
new file mode 100644
index 0000000..9eeb0d6
--- /dev/null
+++ b/tests/data/document-separator-in-quoted-scalar.loader-error
@@ -0,0 +1,11 @@
+---
+"this --- is correct"
+---
+"this
+...is also
+correct"
+---
+"a quoted scalar
+cannot contain
+---
+document separators"
diff --git a/tests/data/documents.events b/tests/data/documents.events
new file mode 100644
index 0000000..775a51a
--- /dev/null
+++ b/tests/data/documents.events
@@ -0,0 +1,11 @@
+- !StreamStart
+- !DocumentStart { explicit: false }
+- !Scalar { implicit: [true,false], value: 'data' }
+- !DocumentEnd
+- !DocumentStart
+- !Scalar { implicit: [true,false] }
+- !DocumentEnd
+- !DocumentStart { version: [1,1], tags: { '!': '!foo', '!yaml!': 'tag:yaml.org,2002:', '!ugly!': '!!!!!!!' } }
+- !Scalar { implicit: [true,false] }
+- !DocumentEnd
+- !StreamEnd
diff --git a/tests/data/duplicate-anchor-1.loader-error b/tests/data/duplicate-anchor-1.loader-error
new file mode 100644
index 0000000..906cf29
--- /dev/null
+++ b/tests/data/duplicate-anchor-1.loader-error
@@ -0,0 +1,3 @@
+- &foo bar
+- &bar bar
+- &foo bar
diff --git a/tests/data/duplicate-anchor-2.loader-error b/tests/data/duplicate-anchor-2.loader-error
new file mode 100644
index 0000000..62b4389
--- /dev/null
+++ b/tests/data/duplicate-anchor-2.loader-error
@@ -0,0 +1 @@
+&foo [1, 2, 3, &foo 4]
diff --git a/tests/data/duplicate-key.former-loader-error.code b/tests/data/duplicate-key.former-loader-error.code
new file mode 100644
index 0000000..cb73906
--- /dev/null
+++ b/tests/data/duplicate-key.former-loader-error.code
@@ -0,0 +1 @@
+{ 'foo': 'baz' }
diff --git a/tests/data/duplicate-key.former-loader-error.data b/tests/data/duplicate-key.former-loader-error.data
new file mode 100644
index 0000000..84deb8f
--- /dev/null
+++ b/tests/data/duplicate-key.former-loader-error.data
@@ -0,0 +1,3 @@
+---
+foo: bar
+foo: baz
diff --git a/tests/data/duplicate-mapping-key.former-loader-error.code b/tests/data/duplicate-mapping-key.former-loader-error.code
new file mode 100644
index 0000000..17a6285
--- /dev/null
+++ b/tests/data/duplicate-mapping-key.former-loader-error.code
@@ -0,0 +1 @@
+{ 'foo': { 'baz': 'bat', 'foo': 'duplicate key' } }
diff --git a/tests/data/duplicate-mapping-key.former-loader-error.data b/tests/data/duplicate-mapping-key.former-loader-error.data
new file mode 100644
index 0000000..7e7b4d1
--- /dev/null
+++ b/tests/data/duplicate-mapping-key.former-loader-error.data
@@ -0,0 +1,6 @@
+---
+&anchor foo:
+    foo: bar
+    *anchor: duplicate key
+    baz: bat
+    *anchor: duplicate key
diff --git a/tests/data/duplicate-merge-key.former-loader-error.code b/tests/data/duplicate-merge-key.former-loader-error.code
new file mode 100644
index 0000000..6a757f3
--- /dev/null
+++ b/tests/data/duplicate-merge-key.former-loader-error.code
@@ -0,0 +1 @@
+{ 'x': 1, 'y': 2, 'foo': 'bar', 'z': 3, 't': 4 }
diff --git a/tests/data/duplicate-merge-key.former-loader-error.data b/tests/data/duplicate-merge-key.former-loader-error.data
new file mode 100644
index 0000000..cebc3a1
--- /dev/null
+++ b/tests/data/duplicate-merge-key.former-loader-error.data
@@ -0,0 +1,4 @@
+---
+<<: {x: 1, y: 2}
+foo: bar
+<<: {z: 3, t: 4}
diff --git a/tests/data/duplicate-tag-directive.loader-error b/tests/data/duplicate-tag-directive.loader-error
new file mode 100644
index 0000000..50c81a0
--- /dev/null
+++ b/tests/data/duplicate-tag-directive.loader-error
@@ -0,0 +1,3 @@
+%TAG    !foo!   bar
+%TAG    !foo!   baz
+--- foo
diff --git a/tests/data/duplicate-value-key.former-loader-error.code b/tests/data/duplicate-value-key.former-loader-error.code
new file mode 100644
index 0000000..12f48c1
--- /dev/null
+++ b/tests/data/duplicate-value-key.former-loader-error.code
@@ -0,0 +1 @@
+{ 'foo': 'bar', '=': 2 }
diff --git a/tests/data/duplicate-value-key.former-loader-error.data b/tests/data/duplicate-value-key.former-loader-error.data
new file mode 100644
index 0000000..b34a1d6
--- /dev/null
+++ b/tests/data/duplicate-value-key.former-loader-error.data
@@ -0,0 +1,4 @@
+---
+=: 1
+foo: bar
+=: 2
diff --git a/tests/data/duplicate-yaml-directive.loader-error b/tests/data/duplicate-yaml-directive.loader-error
new file mode 100644
index 0000000..9b72390
--- /dev/null
+++ b/tests/data/duplicate-yaml-directive.loader-error
@@ -0,0 +1,3 @@
+%YAML   1.1
+%YAML   1.1
+--- foo
diff --git a/tests/data/emit-block-scalar-in-simple-key-context-bug.canonical b/tests/data/emit-block-scalar-in-simple-key-context-bug.canonical
new file mode 100644
index 0000000..473bed5
--- /dev/null
+++ b/tests/data/emit-block-scalar-in-simple-key-context-bug.canonical
@@ -0,0 +1,6 @@
+%YAML 1.1
+--- !!map
+{
+  ? !!str "foo"
+  : !!str "bar"
+}
diff --git a/tests/data/emit-block-scalar-in-simple-key-context-bug.data b/tests/data/emit-block-scalar-in-simple-key-context-bug.data
new file mode 100644
index 0000000..b6b42ba
--- /dev/null
+++ b/tests/data/emit-block-scalar-in-simple-key-context-bug.data
@@ -0,0 +1,4 @@
+? |-
+  foo
+: |-
+  bar
diff --git a/tests/data/emitting-unacceptable-unicode-character-bug-py2.code b/tests/data/emitting-unacceptable-unicode-character-bug-py2.code
new file mode 100644
index 0000000..4b92854
--- /dev/null
+++ b/tests/data/emitting-unacceptable-unicode-character-bug-py2.code
@@ -0,0 +1 @@
+u"\udd00"
diff --git a/tests/data/emitting-unacceptable-unicode-character-bug-py2.data b/tests/data/emitting-unacceptable-unicode-character-bug-py2.data
new file mode 100644
index 0000000..2a5df00
--- /dev/null
+++ b/tests/data/emitting-unacceptable-unicode-character-bug-py2.data
@@ -0,0 +1 @@
+"\udd00"
diff --git a/tests/data/emitting-unacceptable-unicode-character-bug-py2.skip-ext b/tests/data/emitting-unacceptable-unicode-character-bug-py2.skip-ext
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/tests/data/emitting-unacceptable-unicode-character-bug-py2.skip-ext
diff --git a/tests/data/emitting-unacceptable-unicode-character-bug-py3.code b/tests/data/emitting-unacceptable-unicode-character-bug-py3.code
new file mode 100644
index 0000000..2a5df00
--- /dev/null
+++ b/tests/data/emitting-unacceptable-unicode-character-bug-py3.code
@@ -0,0 +1 @@
+"\udd00"
diff --git a/tests/data/emitting-unacceptable-unicode-character-bug-py3.data b/tests/data/emitting-unacceptable-unicode-character-bug-py3.data
new file mode 100644
index 0000000..2a5df00
--- /dev/null
+++ b/tests/data/emitting-unacceptable-unicode-character-bug-py3.data
@@ -0,0 +1 @@
+"\udd00"
diff --git a/tests/data/emitting-unacceptable-unicode-character-bug-py3.skip-ext b/tests/data/emitting-unacceptable-unicode-character-bug-py3.skip-ext
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/tests/data/emitting-unacceptable-unicode-character-bug-py3.skip-ext
diff --git a/tests/data/empty-anchor.emitter-error b/tests/data/empty-anchor.emitter-error
new file mode 100644
index 0000000..ce663b6
--- /dev/null
+++ b/tests/data/empty-anchor.emitter-error
@@ -0,0 +1,5 @@
+- !StreamStart
+- !DocumentStart
+- !Scalar { anchor: '', value: 'foo' }
+- !DocumentEnd
+- !StreamEnd
diff --git a/tests/data/empty-document-bug.canonical b/tests/data/empty-document-bug.canonical
new file mode 100644
index 0000000..28a6cf1
--- /dev/null
+++ b/tests/data/empty-document-bug.canonical
@@ -0,0 +1 @@
+# This YAML stream contains no YAML documents.
diff --git a/tests/data/empty-document-bug.data b/tests/data/empty-document-bug.data
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/tests/data/empty-document-bug.data
diff --git a/tests/data/empty-document-bug.empty b/tests/data/empty-document-bug.empty
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/tests/data/empty-document-bug.empty
diff --git a/tests/data/empty-documents.single-loader-error b/tests/data/empty-documents.single-loader-error
new file mode 100644
index 0000000..f8dba8d
--- /dev/null
+++ b/tests/data/empty-documents.single-loader-error
@@ -0,0 +1,2 @@
+--- # first document
+--- # second document
diff --git a/tests/data/empty-python-module.loader-error b/tests/data/empty-python-module.loader-error
new file mode 100644
index 0000000..83d3232
--- /dev/null
+++ b/tests/data/empty-python-module.loader-error
@@ -0,0 +1 @@
+--- !!python:module:
diff --git a/tests/data/empty-python-name.loader-error b/tests/data/empty-python-name.loader-error
new file mode 100644
index 0000000..6162957
--- /dev/null
+++ b/tests/data/empty-python-name.loader-error
@@ -0,0 +1 @@
+--- !!python/name: empty
diff --git a/tests/data/empty-tag-handle.emitter-error b/tests/data/empty-tag-handle.emitter-error
new file mode 100644
index 0000000..235c899
--- /dev/null
+++ b/tests/data/empty-tag-handle.emitter-error
@@ -0,0 +1,5 @@
+- !StreamStart
+- !DocumentStart { tags: { '': 'bar' } }
+- !Scalar { value: 'foo' }
+- !DocumentEnd
+- !StreamEnd
diff --git a/tests/data/empty-tag-prefix.emitter-error b/tests/data/empty-tag-prefix.emitter-error
new file mode 100644
index 0000000..c6c0e95
--- /dev/null
+++ b/tests/data/empty-tag-prefix.emitter-error
@@ -0,0 +1,5 @@
+- !StreamStart
+- !DocumentStart { tags: { '!': '' } }
+- !Scalar { value: 'foo' }
+- !DocumentEnd
+- !StreamEnd
diff --git a/tests/data/empty-tag.emitter-error b/tests/data/empty-tag.emitter-error
new file mode 100644
index 0000000..b7ca593
--- /dev/null
+++ b/tests/data/empty-tag.emitter-error
@@ -0,0 +1,5 @@
+- !StreamStart
+- !DocumentStart
+- !Scalar { tag: '', value: 'key', implicit: [false,false] }
+- !DocumentEnd
+- !StreamEnd
diff --git a/tests/data/expected-document-end.emitter-error b/tests/data/expected-document-end.emitter-error
new file mode 100644
index 0000000..0cbab89
--- /dev/null
+++ b/tests/data/expected-document-end.emitter-error
@@ -0,0 +1,6 @@
+- !StreamStart
+- !DocumentStart
+- !Scalar { value: 'data 1' }
+- !Scalar { value: 'data 2' }
+- !DocumentEnd
+- !StreamEnd
diff --git a/tests/data/expected-document-start.emitter-error b/tests/data/expected-document-start.emitter-error
new file mode 100644
index 0000000..8ce575e
--- /dev/null
+++ b/tests/data/expected-document-start.emitter-error
@@ -0,0 +1,4 @@
+- !StreamStart
+- !MappingStart
+- !MappingEnd
+- !StreamEnd
diff --git a/tests/data/expected-mapping.loader-error b/tests/data/expected-mapping.loader-error
new file mode 100644
index 0000000..82aed98
--- /dev/null
+++ b/tests/data/expected-mapping.loader-error
@@ -0,0 +1 @@
+--- !!map [not, a, map]
diff --git a/tests/data/expected-node-1.emitter-error b/tests/data/expected-node-1.emitter-error
new file mode 100644
index 0000000..36ceca3
--- /dev/null
+++ b/tests/data/expected-node-1.emitter-error
@@ -0,0 +1,4 @@
+- !StreamStart
+- !DocumentStart
+- !DocumentEnd
+- !StreamEnd
diff --git a/tests/data/expected-node-2.emitter-error b/tests/data/expected-node-2.emitter-error
new file mode 100644
index 0000000..891ee37
--- /dev/null
+++ b/tests/data/expected-node-2.emitter-error
@@ -0,0 +1,7 @@
+- !StreamStart
+- !DocumentStart
+- !MappingStart
+- !Scalar { value: 'key' }
+- !MappingEnd
+- !DocumentEnd
+- !StreamEnd
diff --git a/tests/data/expected-nothing.emitter-error b/tests/data/expected-nothing.emitter-error
new file mode 100644
index 0000000..62c54d3
--- /dev/null
+++ b/tests/data/expected-nothing.emitter-error
@@ -0,0 +1,4 @@
+- !StreamStart
+- !StreamEnd
+- !StreamStart
+- !StreamEnd
diff --git a/tests/data/expected-scalar.loader-error b/tests/data/expected-scalar.loader-error
new file mode 100644
index 0000000..7b3171e
--- /dev/null
+++ b/tests/data/expected-scalar.loader-error
@@ -0,0 +1 @@
+--- !!str [not a scalar]
diff --git a/tests/data/expected-sequence.loader-error b/tests/data/expected-sequence.loader-error
new file mode 100644
index 0000000..08074ea
--- /dev/null
+++ b/tests/data/expected-sequence.loader-error
@@ -0,0 +1 @@
+--- !!seq {foo, bar, baz}
diff --git a/tests/data/expected-stream-start.emitter-error b/tests/data/expected-stream-start.emitter-error
new file mode 100644
index 0000000..480dc2e
--- /dev/null
+++ b/tests/data/expected-stream-start.emitter-error
@@ -0,0 +1,2 @@
+- !DocumentStart
+- !DocumentEnd
diff --git a/tests/data/explicit-document.single-loader-error b/tests/data/explicit-document.single-loader-error
new file mode 100644
index 0000000..46c6f8b
--- /dev/null
+++ b/tests/data/explicit-document.single-loader-error
@@ -0,0 +1,4 @@
+---
+foo: bar
+---
+foo: bar
diff --git a/tests/data/fetch-complex-value-bug.loader-error b/tests/data/fetch-complex-value-bug.loader-error
new file mode 100644
index 0000000..25fac24
--- /dev/null
+++ b/tests/data/fetch-complex-value-bug.loader-error
@@ -0,0 +1,2 @@
+? "foo"
+ : "bar"
diff --git a/tests/data/float-representer-2.3-bug.code b/tests/data/float-representer-2.3-bug.code
new file mode 100644
index 0000000..d8db834
--- /dev/null
+++ b/tests/data/float-representer-2.3-bug.code
@@ -0,0 +1,7 @@
+{
+#    0.0: 0,
+    1.0: 1,
+    1e300000: +10,
+    -1e300000: -10,
+    1e300000/1e300000: 100,
+}
diff --git a/tests/data/float-representer-2.3-bug.data b/tests/data/float-representer-2.3-bug.data
new file mode 100644
index 0000000..efd1716
--- /dev/null
+++ b/tests/data/float-representer-2.3-bug.data
@@ -0,0 +1,5 @@
+#0.0:   # hash(0) == hash(nan) and 0 == nan in Python 2.3
+1.0: 1
++.inf: 10
+-.inf: -10
+.nan: 100
diff --git a/tests/data/float.data b/tests/data/float.data
new file mode 100644
index 0000000..524d5db
--- /dev/null
+++ b/tests/data/float.data
@@ -0,0 +1,6 @@
+- 6.8523015e+5
+- 685.230_15e+03
+- 685_230.15
+- 190:20:30.15
+- -.inf
+- .NaN
diff --git a/tests/data/float.detect b/tests/data/float.detect
new file mode 100644
index 0000000..1e12343
--- /dev/null
+++ b/tests/data/float.detect
@@ -0,0 +1 @@
+tag:yaml.org,2002:float
diff --git a/tests/data/forbidden-entry.loader-error b/tests/data/forbidden-entry.loader-error
new file mode 100644
index 0000000..f2e3079
--- /dev/null
+++ b/tests/data/forbidden-entry.loader-error
@@ -0,0 +1,2 @@
+test: - foo
+      - bar
diff --git a/tests/data/forbidden-key.loader-error b/tests/data/forbidden-key.loader-error
new file mode 100644
index 0000000..da9b471
--- /dev/null
+++ b/tests/data/forbidden-key.loader-error
@@ -0,0 +1,2 @@
+test: ? foo
+      : bar
diff --git a/tests/data/forbidden-value.loader-error b/tests/data/forbidden-value.loader-error
new file mode 100644
index 0000000..efd7ce5
--- /dev/null
+++ b/tests/data/forbidden-value.loader-error
@@ -0,0 +1 @@
+test: key: value
diff --git a/tests/data/implicit-document.single-loader-error b/tests/data/implicit-document.single-loader-error
new file mode 100644
index 0000000..f8c9a5c
--- /dev/null
+++ b/tests/data/implicit-document.single-loader-error
@@ -0,0 +1,3 @@
+foo: bar
+---
+foo: bar
diff --git a/tests/data/int.data b/tests/data/int.data
new file mode 100644
index 0000000..d44d376
--- /dev/null
+++ b/tests/data/int.data
@@ -0,0 +1,6 @@
+- 685230
+- +685_230
+- 02472256
+- 0x_0A_74_AE
+- 0b1010_0111_0100_1010_1110
+- 190:20:30
diff --git a/tests/data/int.detect b/tests/data/int.detect
new file mode 100644
index 0000000..575c9eb
--- /dev/null
+++ b/tests/data/int.detect
@@ -0,0 +1 @@
+tag:yaml.org,2002:int
diff --git a/tests/data/invalid-anchor-1.loader-error b/tests/data/invalid-anchor-1.loader-error
new file mode 100644
index 0000000..fcf7d0f
--- /dev/null
+++ b/tests/data/invalid-anchor-1.loader-error
@@ -0,0 +1 @@
+--- &?  foo # we allow only ascii and numeric characters in anchor names.
diff --git a/tests/data/invalid-anchor-2.loader-error b/tests/data/invalid-anchor-2.loader-error
new file mode 100644
index 0000000..bfc4ff0
--- /dev/null
+++ b/tests/data/invalid-anchor-2.loader-error
@@ -0,0 +1,8 @@
+---
+- [
+    &correct foo,
+    *correct,
+    *correct]   # still correct
+- *correct: still correct
+- &correct-or-not[foo, bar]
+
diff --git a/tests/data/invalid-anchor.emitter-error b/tests/data/invalid-anchor.emitter-error
new file mode 100644
index 0000000..3d2a814
--- /dev/null
+++ b/tests/data/invalid-anchor.emitter-error
@@ -0,0 +1,5 @@
+- !StreamStart
+- !DocumentStart
+- !Scalar { anchor: '5*5=25', value: 'foo' }
+- !DocumentEnd
+- !StreamEnd
diff --git a/tests/data/invalid-base64-data-2.loader-error b/tests/data/invalid-base64-data-2.loader-error
new file mode 100644
index 0000000..2553a4f
--- /dev/null
+++ b/tests/data/invalid-base64-data-2.loader-error
@@ -0,0 +1,2 @@
+--- !!binary
+    двоичные данные в base64
diff --git a/tests/data/invalid-base64-data.loader-error b/tests/data/invalid-base64-data.loader-error
new file mode 100644
index 0000000..798abba
--- /dev/null
+++ b/tests/data/invalid-base64-data.loader-error
@@ -0,0 +1,2 @@
+--- !!binary
+    binary data encoded in base64 should be here.
diff --git a/tests/data/invalid-block-scalar-indicator.loader-error b/tests/data/invalid-block-scalar-indicator.loader-error
new file mode 100644
index 0000000..16a6db1
--- /dev/null
+++ b/tests/data/invalid-block-scalar-indicator.loader-error
@@ -0,0 +1,2 @@
+--- > what is this?  # a comment
+data
diff --git a/tests/data/invalid-character.loader-error b/tests/data/invalid-character.loader-error
new file mode 100644
index 0000000..03687b0
--- /dev/null
+++ b/tests/data/invalid-character.loader-error
Binary files differ
diff --git a/tests/data/invalid-character.stream-error b/tests/data/invalid-character.stream-error
new file mode 100644
index 0000000..171face
--- /dev/null
+++ b/tests/data/invalid-character.stream-error
Binary files differ
diff --git a/tests/data/invalid-directive-line.loader-error b/tests/data/invalid-directive-line.loader-error
new file mode 100644
index 0000000..0892eb6
--- /dev/null
+++ b/tests/data/invalid-directive-line.loader-error
@@ -0,0 +1,2 @@
+%YAML   1.1 ?   # extra symbol
+---
diff --git a/tests/data/invalid-directive-name-1.loader-error b/tests/data/invalid-directive-name-1.loader-error
new file mode 100644
index 0000000..153fd88
--- /dev/null
+++ b/tests/data/invalid-directive-name-1.loader-error
@@ -0,0 +1,2 @@
+%   # no name at all
+---
diff --git a/tests/data/invalid-directive-name-2.loader-error b/tests/data/invalid-directive-name-2.loader-error
new file mode 100644
index 0000000..3732a06
--- /dev/null
+++ b/tests/data/invalid-directive-name-2.loader-error
@@ -0,0 +1,2 @@
+%invalid-characters:in-directive name
+---
diff --git a/tests/data/invalid-escape-character.loader-error b/tests/data/invalid-escape-character.loader-error
new file mode 100644
index 0000000..a95ab76
--- /dev/null
+++ b/tests/data/invalid-escape-character.loader-error
@@ -0,0 +1 @@
+"some escape characters are \ncorrect, but this one \?\nis not\n"
diff --git a/tests/data/invalid-escape-numbers.loader-error b/tests/data/invalid-escape-numbers.loader-error
new file mode 100644
index 0000000..614ec9f
--- /dev/null
+++ b/tests/data/invalid-escape-numbers.loader-error
@@ -0,0 +1 @@
+"hm.... \u123?"
diff --git a/tests/data/invalid-indentation-indicator-1.loader-error b/tests/data/invalid-indentation-indicator-1.loader-error
new file mode 100644
index 0000000..a3cd12f
--- /dev/null
+++ b/tests/data/invalid-indentation-indicator-1.loader-error
@@ -0,0 +1,2 @@
+--- >0  # not valid
+data
diff --git a/tests/data/invalid-indentation-indicator-2.loader-error b/tests/data/invalid-indentation-indicator-2.loader-error
new file mode 100644
index 0000000..eefb6ec
--- /dev/null
+++ b/tests/data/invalid-indentation-indicator-2.loader-error
@@ -0,0 +1,2 @@
+--- >-0
+data
diff --git a/tests/data/invalid-item-without-trailing-break.loader-error b/tests/data/invalid-item-without-trailing-break.loader-error
new file mode 100644
index 0000000..fdcf6c6
--- /dev/null
+++ b/tests/data/invalid-item-without-trailing-break.loader-error
@@ -0,0 +1,2 @@
+-
+-0
\ No newline at end of file
diff --git a/tests/data/invalid-merge-1.loader-error b/tests/data/invalid-merge-1.loader-error
new file mode 100644
index 0000000..fc3c284
--- /dev/null
+++ b/tests/data/invalid-merge-1.loader-error
@@ -0,0 +1,2 @@
+foo: bar
+<<: baz
diff --git a/tests/data/invalid-merge-2.loader-error b/tests/data/invalid-merge-2.loader-error
new file mode 100644
index 0000000..8e88615
--- /dev/null
+++ b/tests/data/invalid-merge-2.loader-error
@@ -0,0 +1,2 @@
+foo: bar
+<<: [x: 1, y: 2, z, t: 4]
diff --git a/tests/data/invalid-omap-1.loader-error b/tests/data/invalid-omap-1.loader-error
new file mode 100644
index 0000000..2863392
--- /dev/null
+++ b/tests/data/invalid-omap-1.loader-error
@@ -0,0 +1,3 @@
+--- !!omap
+foo: bar
+baz: bat
diff --git a/tests/data/invalid-omap-2.loader-error b/tests/data/invalid-omap-2.loader-error
new file mode 100644
index 0000000..c377dfb
--- /dev/null
+++ b/tests/data/invalid-omap-2.loader-error
@@ -0,0 +1,3 @@
+--- !!omap
+- foo: bar
+- baz
diff --git a/tests/data/invalid-omap-3.loader-error b/tests/data/invalid-omap-3.loader-error
new file mode 100644
index 0000000..2a4f50d
--- /dev/null
+++ b/tests/data/invalid-omap-3.loader-error
@@ -0,0 +1,4 @@
+--- !!omap
+- foo: bar
+- baz: bar
+  bar: bar
diff --git a/tests/data/invalid-pairs-1.loader-error b/tests/data/invalid-pairs-1.loader-error
new file mode 100644
index 0000000..42d19ae
--- /dev/null
+++ b/tests/data/invalid-pairs-1.loader-error
@@ -0,0 +1,3 @@
+--- !!pairs
+foo: bar
+baz: bat
diff --git a/tests/data/invalid-pairs-2.loader-error b/tests/data/invalid-pairs-2.loader-error
new file mode 100644
index 0000000..31389ea
--- /dev/null
+++ b/tests/data/invalid-pairs-2.loader-error
@@ -0,0 +1,3 @@
+--- !!pairs
+- foo: bar
+- baz
diff --git a/tests/data/invalid-pairs-3.loader-error b/tests/data/invalid-pairs-3.loader-error
new file mode 100644
index 0000000..f8d7704
--- /dev/null
+++ b/tests/data/invalid-pairs-3.loader-error
@@ -0,0 +1,4 @@
+--- !!pairs
+- foo: bar
+- baz: bar
+  bar: bar
diff --git a/tests/data/invalid-python-bytes-2-py3.loader-error b/tests/data/invalid-python-bytes-2-py3.loader-error
new file mode 100644
index 0000000..f43af59
--- /dev/null
+++ b/tests/data/invalid-python-bytes-2-py3.loader-error
@@ -0,0 +1,2 @@
+--- !!python/bytes
+    двоичные данные в base64
diff --git a/tests/data/invalid-python-bytes-py3.loader-error b/tests/data/invalid-python-bytes-py3.loader-error
new file mode 100644
index 0000000..a19dfd0
--- /dev/null
+++ b/tests/data/invalid-python-bytes-py3.loader-error
@@ -0,0 +1,2 @@
+--- !!python/bytes
+    binary data encoded in base64 should be here.
diff --git a/tests/data/invalid-python-module-kind.loader-error b/tests/data/invalid-python-module-kind.loader-error
new file mode 100644
index 0000000..4f71cb5
--- /dev/null
+++ b/tests/data/invalid-python-module-kind.loader-error
@@ -0,0 +1 @@
+--- !!python/module:sys { must, be, scalar }
diff --git a/tests/data/invalid-python-module-value.loader-error b/tests/data/invalid-python-module-value.loader-error
new file mode 100644
index 0000000..f6797fc
--- /dev/null
+++ b/tests/data/invalid-python-module-value.loader-error
@@ -0,0 +1 @@
+--- !!python/module:sys "non-empty value"
diff --git a/tests/data/invalid-python-module.loader-error b/tests/data/invalid-python-module.loader-error
new file mode 100644
index 0000000..4e24072
--- /dev/null
+++ b/tests/data/invalid-python-module.loader-error
@@ -0,0 +1 @@
+--- !!python/module:no.such.module
diff --git a/tests/data/invalid-python-name-kind.loader-error b/tests/data/invalid-python-name-kind.loader-error
new file mode 100644
index 0000000..6ff8eb6
--- /dev/null
+++ b/tests/data/invalid-python-name-kind.loader-error
@@ -0,0 +1 @@
+--- !!python/name:sys.modules {}
diff --git a/tests/data/invalid-python-name-module-2.loader-error b/tests/data/invalid-python-name-module-2.loader-error
new file mode 100644
index 0000000..debc313
--- /dev/null
+++ b/tests/data/invalid-python-name-module-2.loader-error
@@ -0,0 +1 @@
+--- !!python/name:xml.parsers
diff --git a/tests/data/invalid-python-name-module.loader-error b/tests/data/invalid-python-name-module.loader-error
new file mode 100644
index 0000000..1966f6a
--- /dev/null
+++ b/tests/data/invalid-python-name-module.loader-error
@@ -0,0 +1 @@
+--- !!python/name:sys.modules.keys
diff --git a/tests/data/invalid-python-name-object.loader-error b/tests/data/invalid-python-name-object.loader-error
new file mode 100644
index 0000000..50f386f
--- /dev/null
+++ b/tests/data/invalid-python-name-object.loader-error
@@ -0,0 +1 @@
+--- !!python/name:os.path.rm_rf
diff --git a/tests/data/invalid-python-name-value.loader-error b/tests/data/invalid-python-name-value.loader-error
new file mode 100644
index 0000000..7be1401
--- /dev/null
+++ b/tests/data/invalid-python-name-value.loader-error
@@ -0,0 +1 @@
+--- !!python/name:sys.modules 5
diff --git a/tests/data/invalid-simple-key.loader-error b/tests/data/invalid-simple-key.loader-error
new file mode 100644
index 0000000..a58deec
--- /dev/null
+++ b/tests/data/invalid-simple-key.loader-error
@@ -0,0 +1,3 @@
+key: value
+invalid simple key
+next key: next value
diff --git a/tests/data/invalid-single-quote-bug.code b/tests/data/invalid-single-quote-bug.code
new file mode 100644
index 0000000..5558945
--- /dev/null
+++ b/tests/data/invalid-single-quote-bug.code
@@ -0,0 +1 @@
+["foo 'bar'", "foo\n'bar'"]
diff --git a/tests/data/invalid-single-quote-bug.data b/tests/data/invalid-single-quote-bug.data
new file mode 100644
index 0000000..76ef7ae
--- /dev/null
+++ b/tests/data/invalid-single-quote-bug.data
@@ -0,0 +1,2 @@
+- "foo 'bar'"
+- "foo\n'bar'"
diff --git a/tests/data/invalid-starting-character.loader-error b/tests/data/invalid-starting-character.loader-error
new file mode 100644
index 0000000..bb81c60
--- /dev/null
+++ b/tests/data/invalid-starting-character.loader-error
@@ -0,0 +1 @@
+@@@@@@@@@@@@@@@@@@@
diff --git a/tests/data/invalid-tag-1.loader-error b/tests/data/invalid-tag-1.loader-error
new file mode 100644
index 0000000..a68cd38
--- /dev/null
+++ b/tests/data/invalid-tag-1.loader-error
@@ -0,0 +1 @@
+- !<foo#bar> baz
diff --git a/tests/data/invalid-tag-2.loader-error b/tests/data/invalid-tag-2.loader-error
new file mode 100644
index 0000000..3a36700
--- /dev/null
+++ b/tests/data/invalid-tag-2.loader-error
@@ -0,0 +1 @@
+- !prefix!foo#bar baz
diff --git a/tests/data/invalid-tag-directive-handle.loader-error b/tests/data/invalid-tag-directive-handle.loader-error
new file mode 100644
index 0000000..42b5d7e
--- /dev/null
+++ b/tests/data/invalid-tag-directive-handle.loader-error
@@ -0,0 +1,2 @@
+%TAG !!! !!!
+---
diff --git a/tests/data/invalid-tag-directive-prefix.loader-error b/tests/data/invalid-tag-directive-prefix.loader-error
new file mode 100644
index 0000000..0cb482c
--- /dev/null
+++ b/tests/data/invalid-tag-directive-prefix.loader-error
@@ -0,0 +1,2 @@
+%TAG    !   tag:zz.com/foo#bar  # '#' is not allowed in URLs
+---
diff --git a/tests/data/invalid-tag-handle-1.emitter-error b/tests/data/invalid-tag-handle-1.emitter-error
new file mode 100644
index 0000000..d5df9a2
--- /dev/null
+++ b/tests/data/invalid-tag-handle-1.emitter-error
@@ -0,0 +1,5 @@
+- !StreamStart
+- !DocumentStart { tags: { '!foo': 'bar' } }
+- !Scalar { value: 'foo' }
+- !DocumentEnd
+- !StreamEnd
diff --git a/tests/data/invalid-tag-handle-1.loader-error b/tests/data/invalid-tag-handle-1.loader-error
new file mode 100644
index 0000000..ef0d143
--- /dev/null
+++ b/tests/data/invalid-tag-handle-1.loader-error
@@ -0,0 +1,2 @@
+%TAG    foo bar
+---
diff --git a/tests/data/invalid-tag-handle-2.emitter-error b/tests/data/invalid-tag-handle-2.emitter-error
new file mode 100644
index 0000000..d1831d5
--- /dev/null
+++ b/tests/data/invalid-tag-handle-2.emitter-error
@@ -0,0 +1,5 @@
+- !StreamStart
+- !DocumentStart { tags: { '!!!': 'bar' } }
+- !Scalar { value: 'foo' }
+- !DocumentEnd
+- !StreamEnd
diff --git a/tests/data/invalid-tag-handle-2.loader-error b/tests/data/invalid-tag-handle-2.loader-error
new file mode 100644
index 0000000..06c7f0e
--- /dev/null
+++ b/tests/data/invalid-tag-handle-2.loader-error
@@ -0,0 +1,2 @@
+%TAG    !foo    bar
+---
diff --git a/tests/data/invalid-uri-escapes-1.loader-error b/tests/data/invalid-uri-escapes-1.loader-error
new file mode 100644
index 0000000..a6ecb36
--- /dev/null
+++ b/tests/data/invalid-uri-escapes-1.loader-error
@@ -0,0 +1 @@
+--- !<tag:%x?y> foo
diff --git a/tests/data/invalid-uri-escapes-2.loader-error b/tests/data/invalid-uri-escapes-2.loader-error
new file mode 100644
index 0000000..b89e8f6
--- /dev/null
+++ b/tests/data/invalid-uri-escapes-2.loader-error
@@ -0,0 +1 @@
+--- !<%FF> foo
diff --git a/tests/data/invalid-uri-escapes-3.loader-error b/tests/data/invalid-uri-escapes-3.loader-error
new file mode 100644
index 0000000..f2e4cb8
--- /dev/null
+++ b/tests/data/invalid-uri-escapes-3.loader-error
@@ -0,0 +1 @@
+--- !<foo%d0%af%d0%af%d0bar> baz
diff --git a/tests/data/invalid-uri.loader-error b/tests/data/invalid-uri.loader-error
new file mode 100644
index 0000000..06307e0
--- /dev/null
+++ b/tests/data/invalid-uri.loader-error
@@ -0,0 +1 @@
+--- !foo!   bar
diff --git a/tests/data/invalid-utf8-byte.loader-error b/tests/data/invalid-utf8-byte.loader-error
new file mode 100644
index 0000000..0a58c70
--- /dev/null
+++ b/tests/data/invalid-utf8-byte.loader-error
@@ -0,0 +1,66 @@
+###############################################################
+###############################################################
+###############################################################
+###############################################################
+###############################################################
+###############################################################
+###############################################################
+###############################################################
+###############################################################
+###############################################################
+###############################################################
+###############################################################
+###############################################################
+###############################################################
+###############################################################
+###############################################################
+###############################################################
+###############################################################
+###############################################################
+###############################################################
+###############################################################
+###############################################################
+###############################################################
+###############################################################
+###############################################################
+###############################################################
+###############################################################
+###############################################################
+###############################################################
+###############################################################
+###############################################################
+###############################################################
+###############################################################
+###############################################################
+###############################################################
+###############################################################
+###############################################################
+###############################################################
+###############################################################
+###############################################################
+###############################################################
+###############################################################
+###############################################################
+###############################################################
+###############################################################
+###############################################################
+###############################################################
+###############################################################
+###############################################################
+###############################################################
+###############################################################
+###############################################################
+###############################################################
+###############################################################
+###############################################################
+###############################################################
+###############################################################
+###############################################################
+###############################################################
+###############################################################
+###############################################################
+###############################################################
+###############################################################
+###############################################################
+Invalid byte ('\xFF'): ÿ <--
+###############################################################
diff --git a/tests/data/invalid-utf8-byte.stream-error b/tests/data/invalid-utf8-byte.stream-error
new file mode 100644
index 0000000..0a58c70
--- /dev/null
+++ b/tests/data/invalid-utf8-byte.stream-error
@@ -0,0 +1,66 @@
+###############################################################
+###############################################################
+###############################################################
+###############################################################
+###############################################################
+###############################################################
+###############################################################
+###############################################################
+###############################################################
+###############################################################
+###############################################################
+###############################################################
+###############################################################
+###############################################################
+###############################################################
+###############################################################
+###############################################################
+###############################################################
+###############################################################
+###############################################################
+###############################################################
+###############################################################
+###############################################################
+###############################################################
+###############################################################
+###############################################################
+###############################################################
+###############################################################
+###############################################################
+###############################################################
+###############################################################
+###############################################################
+###############################################################
+###############################################################
+###############################################################
+###############################################################
+###############################################################
+###############################################################
+###############################################################
+###############################################################
+###############################################################
+###############################################################
+###############################################################
+###############################################################
+###############################################################
+###############################################################
+###############################################################
+###############################################################
+###############################################################
+###############################################################
+###############################################################
+###############################################################
+###############################################################
+###############################################################
+###############################################################
+###############################################################
+###############################################################
+###############################################################
+###############################################################
+###############################################################
+###############################################################
+###############################################################
+###############################################################
+###############################################################
+Invalid byte ('\xFF'): ÿ <--
+###############################################################
diff --git a/tests/data/invalid-yaml-directive-version-1.loader-error b/tests/data/invalid-yaml-directive-version-1.loader-error
new file mode 100644
index 0000000..e9b4e3a
--- /dev/null
+++ b/tests/data/invalid-yaml-directive-version-1.loader-error
@@ -0,0 +1,3 @@
+# No version at all.
+%YAML
+---
diff --git a/tests/data/invalid-yaml-directive-version-2.loader-error b/tests/data/invalid-yaml-directive-version-2.loader-error
new file mode 100644
index 0000000..6aa7740
--- /dev/null
+++ b/tests/data/invalid-yaml-directive-version-2.loader-error
@@ -0,0 +1,2 @@
+%YAML   1e-5
+---
diff --git a/tests/data/invalid-yaml-directive-version-3.loader-error b/tests/data/invalid-yaml-directive-version-3.loader-error
new file mode 100644
index 0000000..345e784
--- /dev/null
+++ b/tests/data/invalid-yaml-directive-version-3.loader-error
@@ -0,0 +1,2 @@
+%YAML 1.
+---
diff --git a/tests/data/invalid-yaml-directive-version-4.loader-error b/tests/data/invalid-yaml-directive-version-4.loader-error
new file mode 100644
index 0000000..b35ca82
--- /dev/null
+++ b/tests/data/invalid-yaml-directive-version-4.loader-error
@@ -0,0 +1,2 @@
+%YAML 1.132.435
+---
diff --git a/tests/data/invalid-yaml-directive-version-5.loader-error b/tests/data/invalid-yaml-directive-version-5.loader-error
new file mode 100644
index 0000000..7c2b49f
--- /dev/null
+++ b/tests/data/invalid-yaml-directive-version-5.loader-error
@@ -0,0 +1,2 @@
+%YAML A.0
+---
diff --git a/tests/data/invalid-yaml-directive-version-6.loader-error b/tests/data/invalid-yaml-directive-version-6.loader-error
new file mode 100644
index 0000000..bae714f
--- /dev/null
+++ b/tests/data/invalid-yaml-directive-version-6.loader-error
@@ -0,0 +1,2 @@
+%YAML 123.C
+---
diff --git a/tests/data/invalid-yaml-version.loader-error b/tests/data/invalid-yaml-version.loader-error
new file mode 100644
index 0000000..dd01948
--- /dev/null
+++ b/tests/data/invalid-yaml-version.loader-error
@@ -0,0 +1,2 @@
+%YAML   2.0
+--- foo
diff --git a/tests/data/latin.unicode b/tests/data/latin.unicode
new file mode 100644
index 0000000..4fb799c
--- /dev/null
+++ b/tests/data/latin.unicode
@@ -0,0 +1,384 @@
+ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzªµºÀÁÂÃÄÅÆÇÈÉÊ
+ËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõöøùúûüýþÿĀāĂ㥹ĆćĈĉĊċČčĎ
+ďĐđĒēĔĕĖėĘęĚěĜĝĞğĠġĢģĤĥĦħĨĩĪīĬĭĮįİıIJijĴĵĶķĸĹĺĻļĽľĿŀŁłŃńŅņŇňʼnŊŋŌōŎŏŐ
+őŒœŔŕŖŗŘřŚśŜŝŞşŠšŢţŤťŦŧŨũŪūŬŭŮůŰűŲųŴŵŶŷŸŹźŻżŽžſƀƁƂƃƄƅƆƇƈƉƊƋƌƍƎƏƐƑƒ
+ƓƔƕƖƗƘƙƚƛƜƝƞƟƠơƢƣƤƥƦƧƨƩƪƫƬƭƮƯưƱƲƳƴƵƶƷƸƹƺƼƽƾƿDŽdžLJljNJnjǍǎǏǐǑǒǓǔǕǖǗǘǙǚǛǜ
+ǝǞǟǠǡǢǣǤǥǦǧǨǩǪǫǬǭǮǯǰDZdzǴǵǶǷǸǹǺǻǼǽǾǿȀȁȂȃȄȅȆȇȈȉȊȋȌȍȎȏȐȑȒȓȔȕȖȗȘșȚțȜȝȞȟ
+ȠȡȢȣȤȥȦȧȨȩȪȫȬȭȮȯȰȱȲȳȴȵȶȷȸȹȺȻȼȽȾȿɀɁɐɑɒɓɔɕɖɗɘəɚɛɜɝɞɟɠɡɢɣɤɥɦɧɨɩɪɫɬɭɮɯ
+ɰɱɲɳɴɵɶɷɸɹɺɻɼɽɾɿʀʁʂʃʄʅʆʇʈʉʊʋʌʍʎʏʐʑʒʓʔʕʖʗʘʙʚʛʜʝʞʟʠʡʢʣʤʥʦʧʨʩʪʫʬʭʮʯΆΈ
+ΉΊΌΎΏΐΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡΣΤΥΦΧΨΩΪΫάέήίΰαβγδεζηθικλμνξοπρςστυφχψωϊϋόύ
+ώϐϑϒϓϔϕϖϗϘϙϚϛϜϝϞϟϠϡϢϣϤϥϦϧϨϩϪϫϬϭϮϯϰϱϲϳϴϵϷϸϹϺϻϼϽϾϿЀЁЂЃЄЅІЇЈЉЊЋЌЍЎЏАБ
+ВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯабвгдежзийклмнопрстуфхцчшщъыьэюяѐёђѓ
+єѕіїјљњћќѝўџѠѡѢѣѤѥѦѧѨѩѪѫѬѭѮѯѰѱѲѳѴѵѶѷѸѹѺѻѼѽѾѿҀҁҊҋҌҍҎҏҐґҒғҔҕҖҗҘҙҚқҜҝ
+ҞҟҠҡҢңҤҥҦҧҨҩҪҫҬҭҮүҰұҲҳҴҵҶҷҸҹҺһҼҽҾҿӀӁӂӃӄӅӆӇӈӉӊӋӌӍӎӐӑӒӓӔӕӖӗӘәӚӛӜӝӞӟӠ
+ӡӢӣӤӥӦӧӨөӪӫӬӭӮӯӰӱӲӳӴӵӶӷӸӹԀԁԂԃԄԅԆԇԈԉԊԋԌԍԎԏԱԲԳԴԵԶԷԸԹԺԻԼԽԾԿՀՁՂՃՄՅՆՇՈՉ
+ՊՋՌՍՎՏՐՑՒՓՔՕՖաբգդեզէըթժիլխծկհձղճմյնշոչպջռսվտրցւփքօֆևႠႡႢႣႤႥႦႧႨႩႪႫႬႭ
+ႮႯႰႱႲႳႴႵႶႷႸႹႺႻႼႽႾႿჀჁჂჃჄჅᴀᴁᴂᴃᴄᴅᴆᴇᴈᴉᴊᴋᴌᴍᴎᴏᴐᴑᴒᴓᴔᴕᴖᴗᴘᴙᴚᴛᴜᴝᴞᴟᴠᴡᴢᴣᴤᴥᴦᴧᴨᴩ
+ᴪᴫᵢᵣᵤᵥᵦᵧᵨᵩᵪᵫᵬᵭᵮᵯᵰᵱᵲᵳᵴᵵᵶᵷᵹᵺᵻᵼᵽᵾᵿᶀᶁᶂᶃᶄᶅᶆᶇᶈᶉᶊᶋᶌᶍᶎᶏᶐᶑᶒᶓᶔᶕᶖᶗᶘᶙᶚḀḁḂḃḄḅḆḇ
+ḈḉḊḋḌḍḎḏḐḑḒḓḔḕḖḗḘḙḚḛḜḝḞḟḠḡḢḣḤḥḦḧḨḩḪḫḬḭḮḯḰḱḲḳḴḵḶḷḸḹḺḻḼḽḾḿṀṁṂṃṄṅṆṇṈṉ
+ṊṋṌṍṎṏṐṑṒṓṔṕṖṗṘṙṚṛṜṝṞṟṠṡṢṣṤṥṦṧṨṩṪṫṬṭṮṯṰṱṲṳṴṵṶṷṸṹṺṻṼṽṾṿẀẁẂẃẄẅẆẇẈẉẊẋ
+ẌẍẎẏẐẑẒẓẔẕẖẗẘẙẚẛẠạẢảẤấẦầẨẩẪẫẬậẮắẰằẲẳẴẵẶặẸẹẺẻẼẽẾếỀềỂểỄễỆệỈỉỊịỌọỎỏỐố
+ỒồỔổỖỗỘộỚớỜờỞởỠỡỢợỤụỦủỨứỪừỬửỮữỰựỲỳỴỵỶỷỸỹἀἁἂἃἄἅἆἇἈἉἊἋἌἍἎἏἐἑἒἓἔἕἘἙἚἛ
+ἜἝἠἡἢἣἤἥἦἧἨἩἪἫἬἭἮἯἰἱἲἳἴἵἶἷἸἹἺἻἼἽἾἿὀὁὂὃὄὅὈὉὊὋὌὍὐὑὒὓὔὕὖὗὙὛὝὟὠὡὢὣὤὥὦὧ
+ὨὩὪὫὬὭὮὯὰάὲέὴήὶίὸόὺύὼώᾀᾁᾂᾃᾄᾅᾆᾇᾐᾑᾒᾓᾔᾕᾖᾗᾠᾡᾢᾣᾤᾥᾦᾧᾰᾱᾲᾳᾴᾶᾷᾸᾹᾺΆιῂῃῄῆῇῈΈῊ
+ΉῐῑῒΐῖῗῘῙῚΊῠῡῢΰῤῥῦῧῨῩῪΎῬῲῳῴῶῷῸΌῺΏⁱⁿℂℇℊℋℌℍℎℏℐℑℒℓℕℙℚℛℜℝℤΩℨKÅℬℭℯℰℱℳℴℹ
+ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzªµºÀÁÂÃÄÅÆÇÈÉÊ
+ËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõöøùúûüýþÿĀāĂ㥹ĆćĈĉĊċČčĎ
+ďĐđĒēĔĕĖėĘęĚěĜĝĞğĠġĢģĤĥĦħĨĩĪīĬĭĮįİıIJijĴĵĶķĸĹĺĻļĽľĿŀŁłŃńŅņŇňʼnŊŋŌōŎŏŐ
+őŒœŔŕŖŗŘřŚśŜŝŞşŠšŢţŤťŦŧŨũŪūŬŭŮůŰűŲųŴŵŶŷŸŹźŻżŽžſƀƁƂƃƄƅƆƇƈƉƊƋƌƍƎƏƐƑƒ
+ƓƔƕƖƗƘƙƚƛƜƝƞƟƠơƢƣƤƥƦƧƨƩƪƫƬƭƮƯưƱƲƳƴƵƶƷƸƹƺƼƽƾƿDŽdžLJljNJnjǍǎǏǐǑǒǓǔǕǖǗǘǙǚǛǜ
+ǝǞǟǠǡǢǣǤǥǦǧǨǩǪǫǬǭǮǯǰDZdzǴǵǶǷǸǹǺǻǼǽǾǿȀȁȂȃȄȅȆȇȈȉȊȋȌȍȎȏȐȑȒȓȔȕȖȗȘșȚțȜȝȞȟ
+ȠȡȢȣȤȥȦȧȨȩȪȫȬȭȮȯȰȱȲȳȴȵȶȷȸȹȺȻȼȽȾȿɀɁɐɑɒɓɔɕɖɗɘəɚɛɜɝɞɟɠɡɢɣɤɥɦɧɨɩɪɫɬɭɮɯ
+ɰɱɲɳɴɵɶɷɸɹɺɻɼɽɾɿʀʁʂʃʄʅʆʇʈʉʊʋʌʍʎʏʐʑʒʓʔʕʖʗʘʙʚʛʜʝʞʟʠʡʢʣʤʥʦʧʨʩʪʫʬʭʮʯΆΈ
+ΉΊΌΎΏΐΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡΣΤΥΦΧΨΩΪΫάέήίΰαβγδεζηθικλμνξοπρςστυφχψωϊϋόύ
+ώϐϑϒϓϔϕϖϗϘϙϚϛϜϝϞϟϠϡϢϣϤϥϦϧϨϩϪϫϬϭϮϯϰϱϲϳϴϵϷϸϹϺϻϼϽϾϿЀЁЂЃЄЅІЇЈЉЊЋЌЍЎЏАБ
+ВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯабвгдежзийклмнопрстуфхцчшщъыьэюяѐёђѓ
+єѕіїјљњћќѝўџѠѡѢѣѤѥѦѧѨѩѪѫѬѭѮѯѰѱѲѳѴѵѶѷѸѹѺѻѼѽѾѿҀҁҊҋҌҍҎҏҐґҒғҔҕҖҗҘҙҚқҜҝ
+ҞҟҠҡҢңҤҥҦҧҨҩҪҫҬҭҮүҰұҲҳҴҵҶҷҸҹҺһҼҽҾҿӀӁӂӃӄӅӆӇӈӉӊӋӌӍӎӐӑӒӓӔӕӖӗӘәӚӛӜӝӞӟӠ
+ӡӢӣӤӥӦӧӨөӪӫӬӭӮӯӰӱӲӳӴӵӶӷӸӹԀԁԂԃԄԅԆԇԈԉԊԋԌԍԎԏԱԲԳԴԵԶԷԸԹԺԻԼԽԾԿՀՁՂՃՄՅՆՇՈՉ
+ՊՋՌՍՎՏՐՑՒՓՔՕՖաբգդեզէըթժիլխծկհձղճմյնշոչպջռսվտրցւփքօֆևႠႡႢႣႤႥႦႧႨႩႪႫႬႭ
+ႮႯႰႱႲႳႴႵႶႷႸႹႺႻႼႽႾႿჀჁჂჃჄჅᴀᴁᴂᴃᴄᴅᴆᴇᴈᴉᴊᴋᴌᴍᴎᴏᴐᴑᴒᴓᴔᴕᴖᴗᴘᴙᴚᴛᴜᴝᴞᴟᴠᴡᴢᴣᴤᴥᴦᴧᴨᴩ
+ᴪᴫᵢᵣᵤᵥᵦᵧᵨᵩᵪᵫᵬᵭᵮᵯᵰᵱᵲᵳᵴᵵᵶᵷᵹᵺᵻᵼᵽᵾᵿᶀᶁᶂᶃᶄᶅᶆᶇᶈᶉᶊᶋᶌᶍᶎᶏᶐᶑᶒᶓᶔᶕᶖᶗᶘᶙᶚḀḁḂḃḄḅḆḇ
+ḈḉḊḋḌḍḎḏḐḑḒḓḔḕḖḗḘḙḚḛḜḝḞḟḠḡḢḣḤḥḦḧḨḩḪḫḬḭḮḯḰḱḲḳḴḵḶḷḸḹḺḻḼḽḾḿṀṁṂṃṄṅṆṇṈṉ
+ṊṋṌṍṎṏṐṑṒṓṔṕṖṗṘṙṚṛṜṝṞṟṠṡṢṣṤṥṦṧṨṩṪṫṬṭṮṯṰṱṲṳṴṵṶṷṸṹṺṻṼṽṾṿẀẁẂẃẄẅẆẇẈẉẊẋ
+ẌẍẎẏẐẑẒẓẔẕẖẗẘẙẚẛẠạẢảẤấẦầẨẩẪẫẬậẮắẰằẲẳẴẵẶặẸẹẺẻẼẽẾếỀềỂểỄễỆệỈỉỊịỌọỎỏỐố
+ỒồỔổỖỗỘộỚớỜờỞởỠỡỢợỤụỦủỨứỪừỬửỮữỰựỲỳỴỵỶỷỸỹἀἁἂἃἄἅἆἇἈἉἊἋἌἍἎἏἐἑἒἓἔἕἘἙἚἛ
+ἜἝἠἡἢἣἤἥἦἧἨἩἪἫἬἭἮἯἰἱἲἳἴἵἶἷἸἹἺἻἼἽἾἿὀὁὂὃὄὅὈὉὊὋὌὍὐὑὒὓὔὕὖὗὙὛὝὟὠὡὢὣὤὥὦὧ
+ὨὩὪὫὬὭὮὯὰάὲέὴήὶίὸόὺύὼώᾀᾁᾂᾃᾄᾅᾆᾇᾐᾑᾒᾓᾔᾕᾖᾗᾠᾡᾢᾣᾤᾥᾦᾧᾰᾱᾲᾳᾴᾶᾷᾸᾹᾺΆιῂῃῄῆῇῈΈῊ
+ΉῐῑῒΐῖῗῘῙῚΊῠῡῢΰῤῥῦῧῨῩῪΎῬῲῳῴῶῷῸΌῺΏⁱⁿℂℇℊℋℌℍℎℏℐℑℒℓℕℙℚℛℜℝℤΩℨKÅℬℭℯℰℱℳℴℹ
+ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzªµºÀÁÂÃÄÅÆÇÈÉÊ
+ËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõöøùúûüýþÿĀāĂ㥹ĆćĈĉĊċČčĎ
+ďĐđĒēĔĕĖėĘęĚěĜĝĞğĠġĢģĤĥĦħĨĩĪīĬĭĮįİıIJijĴĵĶķĸĹĺĻļĽľĿŀŁłŃńŅņŇňʼnŊŋŌōŎŏŐ
+őŒœŔŕŖŗŘřŚśŜŝŞşŠšŢţŤťŦŧŨũŪūŬŭŮůŰűŲųŴŵŶŷŸŹźŻżŽžſƀƁƂƃƄƅƆƇƈƉƊƋƌƍƎƏƐƑƒ
+ƓƔƕƖƗƘƙƚƛƜƝƞƟƠơƢƣƤƥƦƧƨƩƪƫƬƭƮƯưƱƲƳƴƵƶƷƸƹƺƼƽƾƿDŽdžLJljNJnjǍǎǏǐǑǒǓǔǕǖǗǘǙǚǛǜ
+ǝǞǟǠǡǢǣǤǥǦǧǨǩǪǫǬǭǮǯǰDZdzǴǵǶǷǸǹǺǻǼǽǾǿȀȁȂȃȄȅȆȇȈȉȊȋȌȍȎȏȐȑȒȓȔȕȖȗȘșȚțȜȝȞȟ
+ȠȡȢȣȤȥȦȧȨȩȪȫȬȭȮȯȰȱȲȳȴȵȶȷȸȹȺȻȼȽȾȿɀɁɐɑɒɓɔɕɖɗɘəɚɛɜɝɞɟɠɡɢɣɤɥɦɧɨɩɪɫɬɭɮɯ
+ɰɱɲɳɴɵɶɷɸɹɺɻɼɽɾɿʀʁʂʃʄʅʆʇʈʉʊʋʌʍʎʏʐʑʒʓʔʕʖʗʘʙʚʛʜʝʞʟʠʡʢʣʤʥʦʧʨʩʪʫʬʭʮʯΆΈ
+ΉΊΌΎΏΐΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡΣΤΥΦΧΨΩΪΫάέήίΰαβγδεζηθικλμνξοπρςστυφχψωϊϋόύ
+ώϐϑϒϓϔϕϖϗϘϙϚϛϜϝϞϟϠϡϢϣϤϥϦϧϨϩϪϫϬϭϮϯϰϱϲϳϴϵϷϸϹϺϻϼϽϾϿЀЁЂЃЄЅІЇЈЉЊЋЌЍЎЏАБ
+ВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯабвгдежзийклмнопрстуфхцчшщъыьэюяѐёђѓ
+єѕіїјљњћќѝўџѠѡѢѣѤѥѦѧѨѩѪѫѬѭѮѯѰѱѲѳѴѵѶѷѸѹѺѻѼѽѾѿҀҁҊҋҌҍҎҏҐґҒғҔҕҖҗҘҙҚқҜҝ
+ҞҟҠҡҢңҤҥҦҧҨҩҪҫҬҭҮүҰұҲҳҴҵҶҷҸҹҺһҼҽҾҿӀӁӂӃӄӅӆӇӈӉӊӋӌӍӎӐӑӒӓӔӕӖӗӘәӚӛӜӝӞӟӠ
+ӡӢӣӤӥӦӧӨөӪӫӬӭӮӯӰӱӲӳӴӵӶӷӸӹԀԁԂԃԄԅԆԇԈԉԊԋԌԍԎԏԱԲԳԴԵԶԷԸԹԺԻԼԽԾԿՀՁՂՃՄՅՆՇՈՉ
+ՊՋՌՍՎՏՐՑՒՓՔՕՖաբգդեզէըթժիլխծկհձղճմյնշոչպջռսվտրցւփքօֆևႠႡႢႣႤႥႦႧႨႩႪႫႬႭ
+ႮႯႰႱႲႳႴႵႶႷႸႹႺႻႼႽႾႿჀჁჂჃჄჅᴀᴁᴂᴃᴄᴅᴆᴇᴈᴉᴊᴋᴌᴍᴎᴏᴐᴑᴒᴓᴔᴕᴖᴗᴘᴙᴚᴛᴜᴝᴞᴟᴠᴡᴢᴣᴤᴥᴦᴧᴨᴩ
+ᴪᴫᵢᵣᵤᵥᵦᵧᵨᵩᵪᵫᵬᵭᵮᵯᵰᵱᵲᵳᵴᵵᵶᵷᵹᵺᵻᵼᵽᵾᵿᶀᶁᶂᶃᶄᶅᶆᶇᶈᶉᶊᶋᶌᶍᶎᶏᶐᶑᶒᶓᶔᶕᶖᶗᶘᶙᶚḀḁḂḃḄḅḆḇ
+ḈḉḊḋḌḍḎḏḐḑḒḓḔḕḖḗḘḙḚḛḜḝḞḟḠḡḢḣḤḥḦḧḨḩḪḫḬḭḮḯḰḱḲḳḴḵḶḷḸḹḺḻḼḽḾḿṀṁṂṃṄṅṆṇṈṉ
+ṊṋṌṍṎṏṐṑṒṓṔṕṖṗṘṙṚṛṜṝṞṟṠṡṢṣṤṥṦṧṨṩṪṫṬṭṮṯṰṱṲṳṴṵṶṷṸṹṺṻṼṽṾṿẀẁẂẃẄẅẆẇẈẉẊẋ
+ẌẍẎẏẐẑẒẓẔẕẖẗẘẙẚẛẠạẢảẤấẦầẨẩẪẫẬậẮắẰằẲẳẴẵẶặẸẹẺẻẼẽẾếỀềỂểỄễỆệỈỉỊịỌọỎỏỐố
+ỒồỔổỖỗỘộỚớỜờỞởỠỡỢợỤụỦủỨứỪừỬửỮữỰựỲỳỴỵỶỷỸỹἀἁἂἃἄἅἆἇἈἉἊἋἌἍἎἏἐἑἒἓἔἕἘἙἚἛ
+ἜἝἠἡἢἣἤἥἦἧἨἩἪἫἬἭἮἯἰἱἲἳἴἵἶἷἸἹἺἻἼἽἾἿὀὁὂὃὄὅὈὉὊὋὌὍὐὑὒὓὔὕὖὗὙὛὝὟὠὡὢὣὤὥὦὧ
+ὨὩὪὫὬὭὮὯὰάὲέὴήὶίὸόὺύὼώᾀᾁᾂᾃᾄᾅᾆᾇᾐᾑᾒᾓᾔᾕᾖᾗᾠᾡᾢᾣᾤᾥᾦᾧᾰᾱᾲᾳᾴᾶᾷᾸᾹᾺΆιῂῃῄῆῇῈΈῊ
+ΉῐῑῒΐῖῗῘῙῚΊῠῡῢΰῤῥῦῧῨῩῪΎῬῲῳῴῶῷῸΌῺΏⁱⁿℂℇℊℋℌℍℎℏℐℑℒℓℕℙℚℛℜℝℤΩℨKÅℬℭℯℰℱℳℴℹ
+ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzªµºÀÁÂÃÄÅÆÇÈÉÊ
+ËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõöøùúûüýþÿĀāĂ㥹ĆćĈĉĊċČčĎ
+ďĐđĒēĔĕĖėĘęĚěĜĝĞğĠġĢģĤĥĦħĨĩĪīĬĭĮįİıIJijĴĵĶķĸĹĺĻļĽľĿŀŁłŃńŅņŇňʼnŊŋŌōŎŏŐ
+őŒœŔŕŖŗŘřŚśŜŝŞşŠšŢţŤťŦŧŨũŪūŬŭŮůŰűŲųŴŵŶŷŸŹźŻżŽžſƀƁƂƃƄƅƆƇƈƉƊƋƌƍƎƏƐƑƒ
+ƓƔƕƖƗƘƙƚƛƜƝƞƟƠơƢƣƤƥƦƧƨƩƪƫƬƭƮƯưƱƲƳƴƵƶƷƸƹƺƼƽƾƿDŽdžLJljNJnjǍǎǏǐǑǒǓǔǕǖǗǘǙǚǛǜ
+ǝǞǟǠǡǢǣǤǥǦǧǨǩǪǫǬǭǮǯǰDZdzǴǵǶǷǸǹǺǻǼǽǾǿȀȁȂȃȄȅȆȇȈȉȊȋȌȍȎȏȐȑȒȓȔȕȖȗȘșȚțȜȝȞȟ
+ȠȡȢȣȤȥȦȧȨȩȪȫȬȭȮȯȰȱȲȳȴȵȶȷȸȹȺȻȼȽȾȿɀɁɐɑɒɓɔɕɖɗɘəɚɛɜɝɞɟɠɡɢɣɤɥɦɧɨɩɪɫɬɭɮɯ
+ɰɱɲɳɴɵɶɷɸɹɺɻɼɽɾɿʀʁʂʃʄʅʆʇʈʉʊʋʌʍʎʏʐʑʒʓʔʕʖʗʘʙʚʛʜʝʞʟʠʡʢʣʤʥʦʧʨʩʪʫʬʭʮʯΆΈ
+ΉΊΌΎΏΐΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡΣΤΥΦΧΨΩΪΫάέήίΰαβγδεζηθικλμνξοπρςστυφχψωϊϋόύ
+ώϐϑϒϓϔϕϖϗϘϙϚϛϜϝϞϟϠϡϢϣϤϥϦϧϨϩϪϫϬϭϮϯϰϱϲϳϴϵϷϸϹϺϻϼϽϾϿЀЁЂЃЄЅІЇЈЉЊЋЌЍЎЏАБ
+ВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯабвгдежзийклмнопрстуфхцчшщъыьэюяѐёђѓ
+єѕіїјљњћќѝўџѠѡѢѣѤѥѦѧѨѩѪѫѬѭѮѯѰѱѲѳѴѵѶѷѸѹѺѻѼѽѾѿҀҁҊҋҌҍҎҏҐґҒғҔҕҖҗҘҙҚқҜҝ
+ҞҟҠҡҢңҤҥҦҧҨҩҪҫҬҭҮүҰұҲҳҴҵҶҷҸҹҺһҼҽҾҿӀӁӂӃӄӅӆӇӈӉӊӋӌӍӎӐӑӒӓӔӕӖӗӘәӚӛӜӝӞӟӠ
+ӡӢӣӤӥӦӧӨөӪӫӬӭӮӯӰӱӲӳӴӵӶӷӸӹԀԁԂԃԄԅԆԇԈԉԊԋԌԍԎԏԱԲԳԴԵԶԷԸԹԺԻԼԽԾԿՀՁՂՃՄՅՆՇՈՉ
+ՊՋՌՍՎՏՐՑՒՓՔՕՖաբգդեզէըթժիլխծկհձղճմյնշոչպջռսվտրցւփքօֆևႠႡႢႣႤႥႦႧႨႩႪႫႬႭ
+ႮႯႰႱႲႳႴႵႶႷႸႹႺႻႼႽႾႿჀჁჂჃჄჅᴀᴁᴂᴃᴄᴅᴆᴇᴈᴉᴊᴋᴌᴍᴎᴏᴐᴑᴒᴓᴔᴕᴖᴗᴘᴙᴚᴛᴜᴝᴞᴟᴠᴡᴢᴣᴤᴥᴦᴧᴨᴩ
+ᴪᴫᵢᵣᵤᵥᵦᵧᵨᵩᵪᵫᵬᵭᵮᵯᵰᵱᵲᵳᵴᵵᵶᵷᵹᵺᵻᵼᵽᵾᵿᶀᶁᶂᶃᶄᶅᶆᶇᶈᶉᶊᶋᶌᶍᶎᶏᶐᶑᶒᶓᶔᶕᶖᶗᶘᶙᶚḀḁḂḃḄḅḆḇ
+ḈḉḊḋḌḍḎḏḐḑḒḓḔḕḖḗḘḙḚḛḜḝḞḟḠḡḢḣḤḥḦḧḨḩḪḫḬḭḮḯḰḱḲḳḴḵḶḷḸḹḺḻḼḽḾḿṀṁṂṃṄṅṆṇṈṉ
+ṊṋṌṍṎṏṐṑṒṓṔṕṖṗṘṙṚṛṜṝṞṟṠṡṢṣṤṥṦṧṨṩṪṫṬṭṮṯṰṱṲṳṴṵṶṷṸṹṺṻṼṽṾṿẀẁẂẃẄẅẆẇẈẉẊẋ
+ẌẍẎẏẐẑẒẓẔẕẖẗẘẙẚẛẠạẢảẤấẦầẨẩẪẫẬậẮắẰằẲẳẴẵẶặẸẹẺẻẼẽẾếỀềỂểỄễỆệỈỉỊịỌọỎỏỐố
+ỒồỔổỖỗỘộỚớỜờỞởỠỡỢợỤụỦủỨứỪừỬửỮữỰựỲỳỴỵỶỷỸỹἀἁἂἃἄἅἆἇἈἉἊἋἌἍἎἏἐἑἒἓἔἕἘἙἚἛ
+ἜἝἠἡἢἣἤἥἦἧἨἩἪἫἬἭἮἯἰἱἲἳἴἵἶἷἸἹἺἻἼἽἾἿὀὁὂὃὄὅὈὉὊὋὌὍὐὑὒὓὔὕὖὗὙὛὝὟὠὡὢὣὤὥὦὧ
+ὨὩὪὫὬὭὮὯὰάὲέὴήὶίὸόὺύὼώᾀᾁᾂᾃᾄᾅᾆᾇᾐᾑᾒᾓᾔᾕᾖᾗᾠᾡᾢᾣᾤᾥᾦᾧᾰᾱᾲᾳᾴᾶᾷᾸᾹᾺΆιῂῃῄῆῇῈΈῊ
+ΉῐῑῒΐῖῗῘῙῚΊῠῡῢΰῤῥῦῧῨῩῪΎῬῲῳῴῶῷῸΌῺΏⁱⁿℂℇℊℋℌℍℎℏℐℑℒℓℕℙℚℛℜℝℤΩℨKÅℬℭℯℰℱℳℴℹ
+ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzªµºÀÁÂÃÄÅÆÇÈÉÊ
+ËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõöøùúûüýþÿĀāĂ㥹ĆćĈĉĊċČčĎ
+ďĐđĒēĔĕĖėĘęĚěĜĝĞğĠġĢģĤĥĦħĨĩĪīĬĭĮįİıIJijĴĵĶķĸĹĺĻļĽľĿŀŁłŃńŅņŇňʼnŊŋŌōŎŏŐ
+őŒœŔŕŖŗŘřŚśŜŝŞşŠšŢţŤťŦŧŨũŪūŬŭŮůŰűŲųŴŵŶŷŸŹźŻżŽžſƀƁƂƃƄƅƆƇƈƉƊƋƌƍƎƏƐƑƒ
+ƓƔƕƖƗƘƙƚƛƜƝƞƟƠơƢƣƤƥƦƧƨƩƪƫƬƭƮƯưƱƲƳƴƵƶƷƸƹƺƼƽƾƿDŽdžLJljNJnjǍǎǏǐǑǒǓǔǕǖǗǘǙǚǛǜ
+ǝǞǟǠǡǢǣǤǥǦǧǨǩǪǫǬǭǮǯǰDZdzǴǵǶǷǸǹǺǻǼǽǾǿȀȁȂȃȄȅȆȇȈȉȊȋȌȍȎȏȐȑȒȓȔȕȖȗȘșȚțȜȝȞȟ
+ȠȡȢȣȤȥȦȧȨȩȪȫȬȭȮȯȰȱȲȳȴȵȶȷȸȹȺȻȼȽȾȿɀɁɐɑɒɓɔɕɖɗɘəɚɛɜɝɞɟɠɡɢɣɤɥɦɧɨɩɪɫɬɭɮɯ
+ɰɱɲɳɴɵɶɷɸɹɺɻɼɽɾɿʀʁʂʃʄʅʆʇʈʉʊʋʌʍʎʏʐʑʒʓʔʕʖʗʘʙʚʛʜʝʞʟʠʡʢʣʤʥʦʧʨʩʪʫʬʭʮʯΆΈ
+ΉΊΌΎΏΐΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡΣΤΥΦΧΨΩΪΫάέήίΰαβγδεζηθικλμνξοπρςστυφχψωϊϋόύ
+ώϐϑϒϓϔϕϖϗϘϙϚϛϜϝϞϟϠϡϢϣϤϥϦϧϨϩϪϫϬϭϮϯϰϱϲϳϴϵϷϸϹϺϻϼϽϾϿЀЁЂЃЄЅІЇЈЉЊЋЌЍЎЏАБ
+ВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯабвгдежзийклмнопрстуфхцчшщъыьэюяѐёђѓ
+єѕіїјљњћќѝўџѠѡѢѣѤѥѦѧѨѩѪѫѬѭѮѯѰѱѲѳѴѵѶѷѸѹѺѻѼѽѾѿҀҁҊҋҌҍҎҏҐґҒғҔҕҖҗҘҙҚқҜҝ
+ҞҟҠҡҢңҤҥҦҧҨҩҪҫҬҭҮүҰұҲҳҴҵҶҷҸҹҺһҼҽҾҿӀӁӂӃӄӅӆӇӈӉӊӋӌӍӎӐӑӒӓӔӕӖӗӘәӚӛӜӝӞӟӠ
+ӡӢӣӤӥӦӧӨөӪӫӬӭӮӯӰӱӲӳӴӵӶӷӸӹԀԁԂԃԄԅԆԇԈԉԊԋԌԍԎԏԱԲԳԴԵԶԷԸԹԺԻԼԽԾԿՀՁՂՃՄՅՆՇՈՉ
+ՊՋՌՍՎՏՐՑՒՓՔՕՖաբգդեզէըթժիլխծկհձղճմյնշոչպջռսվտրցւփքօֆևႠႡႢႣႤႥႦႧႨႩႪႫႬႭ
+ႮႯႰႱႲႳႴႵႶႷႸႹႺႻႼႽႾႿჀჁჂჃჄჅᴀᴁᴂᴃᴄᴅᴆᴇᴈᴉᴊᴋᴌᴍᴎᴏᴐᴑᴒᴓᴔᴕᴖᴗᴘᴙᴚᴛᴜᴝᴞᴟᴠᴡᴢᴣᴤᴥᴦᴧᴨᴩ
+ᴪᴫᵢᵣᵤᵥᵦᵧᵨᵩᵪᵫᵬᵭᵮᵯᵰᵱᵲᵳᵴᵵᵶᵷᵹᵺᵻᵼᵽᵾᵿᶀᶁᶂᶃᶄᶅᶆᶇᶈᶉᶊᶋᶌᶍᶎᶏᶐᶑᶒᶓᶔᶕᶖᶗᶘᶙᶚḀḁḂḃḄḅḆḇ
+ḈḉḊḋḌḍḎḏḐḑḒḓḔḕḖḗḘḙḚḛḜḝḞḟḠḡḢḣḤḥḦḧḨḩḪḫḬḭḮḯḰḱḲḳḴḵḶḷḸḹḺḻḼḽḾḿṀṁṂṃṄṅṆṇṈṉ
+ṊṋṌṍṎṏṐṑṒṓṔṕṖṗṘṙṚṛṜṝṞṟṠṡṢṣṤṥṦṧṨṩṪṫṬṭṮṯṰṱṲṳṴṵṶṷṸṹṺṻṼṽṾṿẀẁẂẃẄẅẆẇẈẉẊẋ
+ẌẍẎẏẐẑẒẓẔẕẖẗẘẙẚẛẠạẢảẤấẦầẨẩẪẫẬậẮắẰằẲẳẴẵẶặẸẹẺẻẼẽẾếỀềỂểỄễỆệỈỉỊịỌọỎỏỐố
+ỒồỔổỖỗỘộỚớỜờỞởỠỡỢợỤụỦủỨứỪừỬửỮữỰựỲỳỴỵỶỷỸỹἀἁἂἃἄἅἆἇἈἉἊἋἌἍἎἏἐἑἒἓἔἕἘἙἚἛ
+ἜἝἠἡἢἣἤἥἦἧἨἩἪἫἬἭἮἯἰἱἲἳἴἵἶἷἸἹἺἻἼἽἾἿὀὁὂὃὄὅὈὉὊὋὌὍὐὑὒὓὔὕὖὗὙὛὝὟὠὡὢὣὤὥὦὧ
+ὨὩὪὫὬὭὮὯὰάὲέὴήὶίὸόὺύὼώᾀᾁᾂᾃᾄᾅᾆᾇᾐᾑᾒᾓᾔᾕᾖᾗᾠᾡᾢᾣᾤᾥᾦᾧᾰᾱᾲᾳᾴᾶᾷᾸᾹᾺΆιῂῃῄῆῇῈΈῊ
+ΉῐῑῒΐῖῗῘῙῚΊῠῡῢΰῤῥῦῧῨῩῪΎῬῲῳῴῶῷῸΌῺΏⁱⁿℂℇℊℋℌℍℎℏℐℑℒℓℕℙℚℛℜℝℤΩℨKÅℬℭℯℰℱℳℴℹ
+ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzªµºÀÁÂÃÄÅÆÇÈÉÊ
+ËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõöøùúûüýþÿĀāĂ㥹ĆćĈĉĊċČčĎ
+ďĐđĒēĔĕĖėĘęĚěĜĝĞğĠġĢģĤĥĦħĨĩĪīĬĭĮįİıIJijĴĵĶķĸĹĺĻļĽľĿŀŁłŃńŅņŇňʼnŊŋŌōŎŏŐ
+őŒœŔŕŖŗŘřŚśŜŝŞşŠšŢţŤťŦŧŨũŪūŬŭŮůŰűŲųŴŵŶŷŸŹźŻżŽžſƀƁƂƃƄƅƆƇƈƉƊƋƌƍƎƏƐƑƒ
+ƓƔƕƖƗƘƙƚƛƜƝƞƟƠơƢƣƤƥƦƧƨƩƪƫƬƭƮƯưƱƲƳƴƵƶƷƸƹƺƼƽƾƿDŽdžLJljNJnjǍǎǏǐǑǒǓǔǕǖǗǘǙǚǛǜ
+ǝǞǟǠǡǢǣǤǥǦǧǨǩǪǫǬǭǮǯǰDZdzǴǵǶǷǸǹǺǻǼǽǾǿȀȁȂȃȄȅȆȇȈȉȊȋȌȍȎȏȐȑȒȓȔȕȖȗȘșȚțȜȝȞȟ
+ȠȡȢȣȤȥȦȧȨȩȪȫȬȭȮȯȰȱȲȳȴȵȶȷȸȹȺȻȼȽȾȿɀɁɐɑɒɓɔɕɖɗɘəɚɛɜɝɞɟɠɡɢɣɤɥɦɧɨɩɪɫɬɭɮɯ
+ɰɱɲɳɴɵɶɷɸɹɺɻɼɽɾɿʀʁʂʃʄʅʆʇʈʉʊʋʌʍʎʏʐʑʒʓʔʕʖʗʘʙʚʛʜʝʞʟʠʡʢʣʤʥʦʧʨʩʪʫʬʭʮʯΆΈ
+ΉΊΌΎΏΐΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡΣΤΥΦΧΨΩΪΫάέήίΰαβγδεζηθικλμνξοπρςστυφχψωϊϋόύ
+ώϐϑϒϓϔϕϖϗϘϙϚϛϜϝϞϟϠϡϢϣϤϥϦϧϨϩϪϫϬϭϮϯϰϱϲϳϴϵϷϸϹϺϻϼϽϾϿЀЁЂЃЄЅІЇЈЉЊЋЌЍЎЏАБ
+ВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯабвгдежзийклмнопрстуфхцчшщъыьэюяѐёђѓ
+єѕіїјљњћќѝўџѠѡѢѣѤѥѦѧѨѩѪѫѬѭѮѯѰѱѲѳѴѵѶѷѸѹѺѻѼѽѾѿҀҁҊҋҌҍҎҏҐґҒғҔҕҖҗҘҙҚқҜҝ
+ҞҟҠҡҢңҤҥҦҧҨҩҪҫҬҭҮүҰұҲҳҴҵҶҷҸҹҺһҼҽҾҿӀӁӂӃӄӅӆӇӈӉӊӋӌӍӎӐӑӒӓӔӕӖӗӘәӚӛӜӝӞӟӠ
+ӡӢӣӤӥӦӧӨөӪӫӬӭӮӯӰӱӲӳӴӵӶӷӸӹԀԁԂԃԄԅԆԇԈԉԊԋԌԍԎԏԱԲԳԴԵԶԷԸԹԺԻԼԽԾԿՀՁՂՃՄՅՆՇՈՉ
+ՊՋՌՍՎՏՐՑՒՓՔՕՖաբգդեզէըթժիլխծկհձղճմյնշոչպջռսվտրցւփքօֆևႠႡႢႣႤႥႦႧႨႩႪႫႬႭ
+ႮႯႰႱႲႳႴႵႶႷႸႹႺႻႼႽႾႿჀჁჂჃჄჅᴀᴁᴂᴃᴄᴅᴆᴇᴈᴉᴊᴋᴌᴍᴎᴏᴐᴑᴒᴓᴔᴕᴖᴗᴘᴙᴚᴛᴜᴝᴞᴟᴠᴡᴢᴣᴤᴥᴦᴧᴨᴩ
+ᴪᴫᵢᵣᵤᵥᵦᵧᵨᵩᵪᵫᵬᵭᵮᵯᵰᵱᵲᵳᵴᵵᵶᵷᵹᵺᵻᵼᵽᵾᵿᶀᶁᶂᶃᶄᶅᶆᶇᶈᶉᶊᶋᶌᶍᶎᶏᶐᶑᶒᶓᶔᶕᶖᶗᶘᶙᶚḀḁḂḃḄḅḆḇ
+ḈḉḊḋḌḍḎḏḐḑḒḓḔḕḖḗḘḙḚḛḜḝḞḟḠḡḢḣḤḥḦḧḨḩḪḫḬḭḮḯḰḱḲḳḴḵḶḷḸḹḺḻḼḽḾḿṀṁṂṃṄṅṆṇṈṉ
+ṊṋṌṍṎṏṐṑṒṓṔṕṖṗṘṙṚṛṜṝṞṟṠṡṢṣṤṥṦṧṨṩṪṫṬṭṮṯṰṱṲṳṴṵṶṷṸṹṺṻṼṽṾṿẀẁẂẃẄẅẆẇẈẉẊẋ
+ẌẍẎẏẐẑẒẓẔẕẖẗẘẙẚẛẠạẢảẤấẦầẨẩẪẫẬậẮắẰằẲẳẴẵẶặẸẹẺẻẼẽẾếỀềỂểỄễỆệỈỉỊịỌọỎỏỐố
+ỒồỔổỖỗỘộỚớỜờỞởỠỡỢợỤụỦủỨứỪừỬửỮữỰựỲỳỴỵỶỷỸỹἀἁἂἃἄἅἆἇἈἉἊἋἌἍἎἏἐἑἒἓἔἕἘἙἚἛ
+ἜἝἠἡἢἣἤἥἦἧἨἩἪἫἬἭἮἯἰἱἲἳἴἵἶἷἸἹἺἻἼἽἾἿὀὁὂὃὄὅὈὉὊὋὌὍὐὑὒὓὔὕὖὗὙὛὝὟὠὡὢὣὤὥὦὧ
+ὨὩὪὫὬὭὮὯὰάὲέὴήὶίὸόὺύὼώᾀᾁᾂᾃᾄᾅᾆᾇᾐᾑᾒᾓᾔᾕᾖᾗᾠᾡᾢᾣᾤᾥᾦᾧᾰᾱᾲᾳᾴᾶᾷᾸᾹᾺΆιῂῃῄῆῇῈΈῊ
+ΉῐῑῒΐῖῗῘῙῚΊῠῡῢΰῤῥῦῧῨῩῪΎῬῲῳῴῶῷῸΌῺΏⁱⁿℂℇℊℋℌℍℎℏℐℑℒℓℕℙℚℛℜℝℤΩℨKÅℬℭℯℰℱℳℴℹ
+ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzªµºÀÁÂÃÄÅÆÇÈÉÊ
+ËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõöøùúûüýþÿĀāĂ㥹ĆćĈĉĊċČčĎ
+ďĐđĒēĔĕĖėĘęĚěĜĝĞğĠġĢģĤĥĦħĨĩĪīĬĭĮįİıIJijĴĵĶķĸĹĺĻļĽľĿŀŁłŃńŅņŇňʼnŊŋŌōŎŏŐ
+őŒœŔŕŖŗŘřŚśŜŝŞşŠšŢţŤťŦŧŨũŪūŬŭŮůŰűŲųŴŵŶŷŸŹźŻżŽžſƀƁƂƃƄƅƆƇƈƉƊƋƌƍƎƏƐƑƒ
+ƓƔƕƖƗƘƙƚƛƜƝƞƟƠơƢƣƤƥƦƧƨƩƪƫƬƭƮƯưƱƲƳƴƵƶƷƸƹƺƼƽƾƿDŽdžLJljNJnjǍǎǏǐǑǒǓǔǕǖǗǘǙǚǛǜ
+ǝǞǟǠǡǢǣǤǥǦǧǨǩǪǫǬǭǮǯǰDZdzǴǵǶǷǸǹǺǻǼǽǾǿȀȁȂȃȄȅȆȇȈȉȊȋȌȍȎȏȐȑȒȓȔȕȖȗȘșȚțȜȝȞȟ
+ȠȡȢȣȤȥȦȧȨȩȪȫȬȭȮȯȰȱȲȳȴȵȶȷȸȹȺȻȼȽȾȿɀɁɐɑɒɓɔɕɖɗɘəɚɛɜɝɞɟɠɡɢɣɤɥɦɧɨɩɪɫɬɭɮɯ
+ɰɱɲɳɴɵɶɷɸɹɺɻɼɽɾɿʀʁʂʃʄʅʆʇʈʉʊʋʌʍʎʏʐʑʒʓʔʕʖʗʘʙʚʛʜʝʞʟʠʡʢʣʤʥʦʧʨʩʪʫʬʭʮʯΆΈ
+ΉΊΌΎΏΐΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡΣΤΥΦΧΨΩΪΫάέήίΰαβγδεζηθικλμνξοπρςστυφχψωϊϋόύ
+ώϐϑϒϓϔϕϖϗϘϙϚϛϜϝϞϟϠϡϢϣϤϥϦϧϨϩϪϫϬϭϮϯϰϱϲϳϴϵϷϸϹϺϻϼϽϾϿЀЁЂЃЄЅІЇЈЉЊЋЌЍЎЏАБ
+ВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯабвгдежзийклмнопрстуфхцчшщъыьэюяѐёђѓ
+єѕіїјљњћќѝўџѠѡѢѣѤѥѦѧѨѩѪѫѬѭѮѯѰѱѲѳѴѵѶѷѸѹѺѻѼѽѾѿҀҁҊҋҌҍҎҏҐґҒғҔҕҖҗҘҙҚқҜҝ
+ҞҟҠҡҢңҤҥҦҧҨҩҪҫҬҭҮүҰұҲҳҴҵҶҷҸҹҺһҼҽҾҿӀӁӂӃӄӅӆӇӈӉӊӋӌӍӎӐӑӒӓӔӕӖӗӘәӚӛӜӝӞӟӠ
+ӡӢӣӤӥӦӧӨөӪӫӬӭӮӯӰӱӲӳӴӵӶӷӸӹԀԁԂԃԄԅԆԇԈԉԊԋԌԍԎԏԱԲԳԴԵԶԷԸԹԺԻԼԽԾԿՀՁՂՃՄՅՆՇՈՉ
+ՊՋՌՍՎՏՐՑՒՓՔՕՖաբգդեզէըթժիլխծկհձղճմյնշոչպջռսվտրցւփքօֆևႠႡႢႣႤႥႦႧႨႩႪႫႬႭ
+ႮႯႰႱႲႳႴႵႶႷႸႹႺႻႼႽႾႿჀჁჂჃჄჅᴀᴁᴂᴃᴄᴅᴆᴇᴈᴉᴊᴋᴌᴍᴎᴏᴐᴑᴒᴓᴔᴕᴖᴗᴘᴙᴚᴛᴜᴝᴞᴟᴠᴡᴢᴣᴤᴥᴦᴧᴨᴩ
+ᴪᴫᵢᵣᵤᵥᵦᵧᵨᵩᵪᵫᵬᵭᵮᵯᵰᵱᵲᵳᵴᵵᵶᵷᵹᵺᵻᵼᵽᵾᵿᶀᶁᶂᶃᶄᶅᶆᶇᶈᶉᶊᶋᶌᶍᶎᶏᶐᶑᶒᶓᶔᶕᶖᶗᶘᶙᶚḀḁḂḃḄḅḆḇ
+ḈḉḊḋḌḍḎḏḐḑḒḓḔḕḖḗḘḙḚḛḜḝḞḟḠḡḢḣḤḥḦḧḨḩḪḫḬḭḮḯḰḱḲḳḴḵḶḷḸḹḺḻḼḽḾḿṀṁṂṃṄṅṆṇṈṉ
+ṊṋṌṍṎṏṐṑṒṓṔṕṖṗṘṙṚṛṜṝṞṟṠṡṢṣṤṥṦṧṨṩṪṫṬṭṮṯṰṱṲṳṴṵṶṷṸṹṺṻṼṽṾṿẀẁẂẃẄẅẆẇẈẉẊẋ
+ẌẍẎẏẐẑẒẓẔẕẖẗẘẙẚẛẠạẢảẤấẦầẨẩẪẫẬậẮắẰằẲẳẴẵẶặẸẹẺẻẼẽẾếỀềỂểỄễỆệỈỉỊịỌọỎỏỐố
+ỒồỔổỖỗỘộỚớỜờỞởỠỡỢợỤụỦủỨứỪừỬửỮữỰựỲỳỴỵỶỷỸỹἀἁἂἃἄἅἆἇἈἉἊἋἌἍἎἏἐἑἒἓἔἕἘἙἚἛ
+ἜἝἠἡἢἣἤἥἦἧἨἩἪἫἬἭἮἯἰἱἲἳἴἵἶἷἸἹἺἻἼἽἾἿὀὁὂὃὄὅὈὉὊὋὌὍὐὑὒὓὔὕὖὗὙὛὝὟὠὡὢὣὤὥὦὧ
+ὨὩὪὫὬὭὮὯὰάὲέὴήὶίὸόὺύὼώᾀᾁᾂᾃᾄᾅᾆᾇᾐᾑᾒᾓᾔᾕᾖᾗᾠᾡᾢᾣᾤᾥᾦᾧᾰᾱᾲᾳᾴᾶᾷᾸᾹᾺΆιῂῃῄῆῇῈΈῊ
+ΉῐῑῒΐῖῗῘῙῚΊῠῡῢΰῤῥῦῧῨῩῪΎῬῲῳῴῶῷῸΌῺΏⁱⁿℂℇℊℋℌℍℎℏℐℑℒℓℕℙℚℛℜℝℤΩℨKÅℬℭℯℰℱℳℴℹ
+ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzªµºÀÁÂÃÄÅÆÇÈÉÊ
+ËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõöøùúûüýþÿĀāĂ㥹ĆćĈĉĊċČčĎ
+ďĐđĒēĔĕĖėĘęĚěĜĝĞğĠġĢģĤĥĦħĨĩĪīĬĭĮįİıIJijĴĵĶķĸĹĺĻļĽľĿŀŁłŃńŅņŇňʼnŊŋŌōŎŏŐ
+őŒœŔŕŖŗŘřŚśŜŝŞşŠšŢţŤťŦŧŨũŪūŬŭŮůŰűŲųŴŵŶŷŸŹźŻżŽžſƀƁƂƃƄƅƆƇƈƉƊƋƌƍƎƏƐƑƒ
+ƓƔƕƖƗƘƙƚƛƜƝƞƟƠơƢƣƤƥƦƧƨƩƪƫƬƭƮƯưƱƲƳƴƵƶƷƸƹƺƼƽƾƿDŽdžLJljNJnjǍǎǏǐǑǒǓǔǕǖǗǘǙǚǛǜ
+ǝǞǟǠǡǢǣǤǥǦǧǨǩǪǫǬǭǮǯǰDZdzǴǵǶǷǸǹǺǻǼǽǾǿȀȁȂȃȄȅȆȇȈȉȊȋȌȍȎȏȐȑȒȓȔȕȖȗȘșȚțȜȝȞȟ
+ȠȡȢȣȤȥȦȧȨȩȪȫȬȭȮȯȰȱȲȳȴȵȶȷȸȹȺȻȼȽȾȿɀɁɐɑɒɓɔɕɖɗɘəɚɛɜɝɞɟɠɡɢɣɤɥɦɧɨɩɪɫɬɭɮɯ
+ɰɱɲɳɴɵɶɷɸɹɺɻɼɽɾɿʀʁʂʃʄʅʆʇʈʉʊʋʌʍʎʏʐʑʒʓʔʕʖʗʘʙʚʛʜʝʞʟʠʡʢʣʤʥʦʧʨʩʪʫʬʭʮʯΆΈ
+ΉΊΌΎΏΐΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡΣΤΥΦΧΨΩΪΫάέήίΰαβγδεζηθικλμνξοπρςστυφχψωϊϋόύ
+ώϐϑϒϓϔϕϖϗϘϙϚϛϜϝϞϟϠϡϢϣϤϥϦϧϨϩϪϫϬϭϮϯϰϱϲϳϴϵϷϸϹϺϻϼϽϾϿЀЁЂЃЄЅІЇЈЉЊЋЌЍЎЏАБ
+ВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯабвгдежзийклмнопрстуфхцчшщъыьэюяѐёђѓ
+єѕіїјљњћќѝўџѠѡѢѣѤѥѦѧѨѩѪѫѬѭѮѯѰѱѲѳѴѵѶѷѸѹѺѻѼѽѾѿҀҁҊҋҌҍҎҏҐґҒғҔҕҖҗҘҙҚқҜҝ
+ҞҟҠҡҢңҤҥҦҧҨҩҪҫҬҭҮүҰұҲҳҴҵҶҷҸҹҺһҼҽҾҿӀӁӂӃӄӅӆӇӈӉӊӋӌӍӎӐӑӒӓӔӕӖӗӘәӚӛӜӝӞӟӠ
+ӡӢӣӤӥӦӧӨөӪӫӬӭӮӯӰӱӲӳӴӵӶӷӸӹԀԁԂԃԄԅԆԇԈԉԊԋԌԍԎԏԱԲԳԴԵԶԷԸԹԺԻԼԽԾԿՀՁՂՃՄՅՆՇՈՉ
+ՊՋՌՍՎՏՐՑՒՓՔՕՖաբգդեզէըթժիլխծկհձղճմյնշոչպջռսվտրցւփքօֆևႠႡႢႣႤႥႦႧႨႩႪႫႬႭ
+ႮႯႰႱႲႳႴႵႶႷႸႹႺႻႼႽႾႿჀჁჂჃჄჅᴀᴁᴂᴃᴄᴅᴆᴇᴈᴉᴊᴋᴌᴍᴎᴏᴐᴑᴒᴓᴔᴕᴖᴗᴘᴙᴚᴛᴜᴝᴞᴟᴠᴡᴢᴣᴤᴥᴦᴧᴨᴩ
+ᴪᴫᵢᵣᵤᵥᵦᵧᵨᵩᵪᵫᵬᵭᵮᵯᵰᵱᵲᵳᵴᵵᵶᵷᵹᵺᵻᵼᵽᵾᵿᶀᶁᶂᶃᶄᶅᶆᶇᶈᶉᶊᶋᶌᶍᶎᶏᶐᶑᶒᶓᶔᶕᶖᶗᶘᶙᶚḀḁḂḃḄḅḆḇ
+ḈḉḊḋḌḍḎḏḐḑḒḓḔḕḖḗḘḙḚḛḜḝḞḟḠḡḢḣḤḥḦḧḨḩḪḫḬḭḮḯḰḱḲḳḴḵḶḷḸḹḺḻḼḽḾḿṀṁṂṃṄṅṆṇṈṉ
+ṊṋṌṍṎṏṐṑṒṓṔṕṖṗṘṙṚṛṜṝṞṟṠṡṢṣṤṥṦṧṨṩṪṫṬṭṮṯṰṱṲṳṴṵṶṷṸṹṺṻṼṽṾṿẀẁẂẃẄẅẆẇẈẉẊẋ
+ẌẍẎẏẐẑẒẓẔẕẖẗẘẙẚẛẠạẢảẤấẦầẨẩẪẫẬậẮắẰằẲẳẴẵẶặẸẹẺẻẼẽẾếỀềỂểỄễỆệỈỉỊịỌọỎỏỐố
+ỒồỔổỖỗỘộỚớỜờỞởỠỡỢợỤụỦủỨứỪừỬửỮữỰựỲỳỴỵỶỷỸỹἀἁἂἃἄἅἆἇἈἉἊἋἌἍἎἏἐἑἒἓἔἕἘἙἚἛ
+ἜἝἠἡἢἣἤἥἦἧἨἩἪἫἬἭἮἯἰἱἲἳἴἵἶἷἸἹἺἻἼἽἾἿὀὁὂὃὄὅὈὉὊὋὌὍὐὑὒὓὔὕὖὗὙὛὝὟὠὡὢὣὤὥὦὧ
+ὨὩὪὫὬὭὮὯὰάὲέὴήὶίὸόὺύὼώᾀᾁᾂᾃᾄᾅᾆᾇᾐᾑᾒᾓᾔᾕᾖᾗᾠᾡᾢᾣᾤᾥᾦᾧᾰᾱᾲᾳᾴᾶᾷᾸᾹᾺΆιῂῃῄῆῇῈΈῊ
+ΉῐῑῒΐῖῗῘῙῚΊῠῡῢΰῤῥῦῧῨῩῪΎῬῲῳῴῶῷῸΌῺΏⁱⁿℂℇℊℋℌℍℎℏℐℑℒℓℕℙℚℛℜℝℤΩℨKÅℬℭℯℰℱℳℴℹ
+ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzªµºÀÁÂÃÄÅÆÇÈÉÊ
+ËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõöøùúûüýþÿĀāĂ㥹ĆćĈĉĊċČčĎ
+ďĐđĒēĔĕĖėĘęĚěĜĝĞğĠġĢģĤĥĦħĨĩĪīĬĭĮįİıIJijĴĵĶķĸĹĺĻļĽľĿŀŁłŃńŅņŇňʼnŊŋŌōŎŏŐ
+őŒœŔŕŖŗŘřŚśŜŝŞşŠšŢţŤťŦŧŨũŪūŬŭŮůŰűŲųŴŵŶŷŸŹźŻżŽžſƀƁƂƃƄƅƆƇƈƉƊƋƌƍƎƏƐƑƒ
+ƓƔƕƖƗƘƙƚƛƜƝƞƟƠơƢƣƤƥƦƧƨƩƪƫƬƭƮƯưƱƲƳƴƵƶƷƸƹƺƼƽƾƿDŽdžLJljNJnjǍǎǏǐǑǒǓǔǕǖǗǘǙǚǛǜ
+ǝǞǟǠǡǢǣǤǥǦǧǨǩǪǫǬǭǮǯǰDZdzǴǵǶǷǸǹǺǻǼǽǾǿȀȁȂȃȄȅȆȇȈȉȊȋȌȍȎȏȐȑȒȓȔȕȖȗȘșȚțȜȝȞȟ
+ȠȡȢȣȤȥȦȧȨȩȪȫȬȭȮȯȰȱȲȳȴȵȶȷȸȹȺȻȼȽȾȿɀɁɐɑɒɓɔɕɖɗɘəɚɛɜɝɞɟɠɡɢɣɤɥɦɧɨɩɪɫɬɭɮɯ
+ɰɱɲɳɴɵɶɷɸɹɺɻɼɽɾɿʀʁʂʃʄʅʆʇʈʉʊʋʌʍʎʏʐʑʒʓʔʕʖʗʘʙʚʛʜʝʞʟʠʡʢʣʤʥʦʧʨʩʪʫʬʭʮʯΆΈ
+ΉΊΌΎΏΐΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡΣΤΥΦΧΨΩΪΫάέήίΰαβγδεζηθικλμνξοπρςστυφχψωϊϋόύ
+ώϐϑϒϓϔϕϖϗϘϙϚϛϜϝϞϟϠϡϢϣϤϥϦϧϨϩϪϫϬϭϮϯϰϱϲϳϴϵϷϸϹϺϻϼϽϾϿЀЁЂЃЄЅІЇЈЉЊЋЌЍЎЏАБ
+ВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯабвгдежзийклмнопрстуфхцчшщъыьэюяѐёђѓ
+єѕіїјљњћќѝўџѠѡѢѣѤѥѦѧѨѩѪѫѬѭѮѯѰѱѲѳѴѵѶѷѸѹѺѻѼѽѾѿҀҁҊҋҌҍҎҏҐґҒғҔҕҖҗҘҙҚқҜҝ
+ҞҟҠҡҢңҤҥҦҧҨҩҪҫҬҭҮүҰұҲҳҴҵҶҷҸҹҺһҼҽҾҿӀӁӂӃӄӅӆӇӈӉӊӋӌӍӎӐӑӒӓӔӕӖӗӘәӚӛӜӝӞӟӠ
+ӡӢӣӤӥӦӧӨөӪӫӬӭӮӯӰӱӲӳӴӵӶӷӸӹԀԁԂԃԄԅԆԇԈԉԊԋԌԍԎԏԱԲԳԴԵԶԷԸԹԺԻԼԽԾԿՀՁՂՃՄՅՆՇՈՉ
+ՊՋՌՍՎՏՐՑՒՓՔՕՖաբգդեզէըթժիլխծկհձղճմյնշոչպջռսվտրցւփքօֆևႠႡႢႣႤႥႦႧႨႩႪႫႬႭ
+ႮႯႰႱႲႳႴႵႶႷႸႹႺႻႼႽႾႿჀჁჂჃჄჅᴀᴁᴂᴃᴄᴅᴆᴇᴈᴉᴊᴋᴌᴍᴎᴏᴐᴑᴒᴓᴔᴕᴖᴗᴘᴙᴚᴛᴜᴝᴞᴟᴠᴡᴢᴣᴤᴥᴦᴧᴨᴩ
+ᴪᴫᵢᵣᵤᵥᵦᵧᵨᵩᵪᵫᵬᵭᵮᵯᵰᵱᵲᵳᵴᵵᵶᵷᵹᵺᵻᵼᵽᵾᵿᶀᶁᶂᶃᶄᶅᶆᶇᶈᶉᶊᶋᶌᶍᶎᶏᶐᶑᶒᶓᶔᶕᶖᶗᶘᶙᶚḀḁḂḃḄḅḆḇ
+ḈḉḊḋḌḍḎḏḐḑḒḓḔḕḖḗḘḙḚḛḜḝḞḟḠḡḢḣḤḥḦḧḨḩḪḫḬḭḮḯḰḱḲḳḴḵḶḷḸḹḺḻḼḽḾḿṀṁṂṃṄṅṆṇṈṉ
+ṊṋṌṍṎṏṐṑṒṓṔṕṖṗṘṙṚṛṜṝṞṟṠṡṢṣṤṥṦṧṨṩṪṫṬṭṮṯṰṱṲṳṴṵṶṷṸṹṺṻṼṽṾṿẀẁẂẃẄẅẆẇẈẉẊẋ
+ẌẍẎẏẐẑẒẓẔẕẖẗẘẙẚẛẠạẢảẤấẦầẨẩẪẫẬậẮắẰằẲẳẴẵẶặẸẹẺẻẼẽẾếỀềỂểỄễỆệỈỉỊịỌọỎỏỐố
+ỒồỔổỖỗỘộỚớỜờỞởỠỡỢợỤụỦủỨứỪừỬửỮữỰựỲỳỴỵỶỷỸỹἀἁἂἃἄἅἆἇἈἉἊἋἌἍἎἏἐἑἒἓἔἕἘἙἚἛ
+ἜἝἠἡἢἣἤἥἦἧἨἩἪἫἬἭἮἯἰἱἲἳἴἵἶἷἸἹἺἻἼἽἾἿὀὁὂὃὄὅὈὉὊὋὌὍὐὑὒὓὔὕὖὗὙὛὝὟὠὡὢὣὤὥὦὧ
+ὨὩὪὫὬὭὮὯὰάὲέὴήὶίὸόὺύὼώᾀᾁᾂᾃᾄᾅᾆᾇᾐᾑᾒᾓᾔᾕᾖᾗᾠᾡᾢᾣᾤᾥᾦᾧᾰᾱᾲᾳᾴᾶᾷᾸᾹᾺΆιῂῃῄῆῇῈΈῊ
+ΉῐῑῒΐῖῗῘῙῚΊῠῡῢΰῤῥῦῧῨῩῪΎῬῲῳῴῶῷῸΌῺΏⁱⁿℂℇℊℋℌℍℎℏℐℑℒℓℕℙℚℛℜℝℤΩℨKÅℬℭℯℰℱℳℴℹ
+ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzªµºÀÁÂÃÄÅÆÇÈÉÊ
+ËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõöøùúûüýþÿĀāĂ㥹ĆćĈĉĊċČčĎ
+ďĐđĒēĔĕĖėĘęĚěĜĝĞğĠġĢģĤĥĦħĨĩĪīĬĭĮįİıIJijĴĵĶķĸĹĺĻļĽľĿŀŁłŃńŅņŇňʼnŊŋŌōŎŏŐ
+őŒœŔŕŖŗŘřŚśŜŝŞşŠšŢţŤťŦŧŨũŪūŬŭŮůŰűŲųŴŵŶŷŸŹźŻżŽžſƀƁƂƃƄƅƆƇƈƉƊƋƌƍƎƏƐƑƒ
+ƓƔƕƖƗƘƙƚƛƜƝƞƟƠơƢƣƤƥƦƧƨƩƪƫƬƭƮƯưƱƲƳƴƵƶƷƸƹƺƼƽƾƿDŽdžLJljNJnjǍǎǏǐǑǒǓǔǕǖǗǘǙǚǛǜ
+ǝǞǟǠǡǢǣǤǥǦǧǨǩǪǫǬǭǮǯǰDZdzǴǵǶǷǸǹǺǻǼǽǾǿȀȁȂȃȄȅȆȇȈȉȊȋȌȍȎȏȐȑȒȓȔȕȖȗȘșȚțȜȝȞȟ
+ȠȡȢȣȤȥȦȧȨȩȪȫȬȭȮȯȰȱȲȳȴȵȶȷȸȹȺȻȼȽȾȿɀɁɐɑɒɓɔɕɖɗɘəɚɛɜɝɞɟɠɡɢɣɤɥɦɧɨɩɪɫɬɭɮɯ
+ɰɱɲɳɴɵɶɷɸɹɺɻɼɽɾɿʀʁʂʃʄʅʆʇʈʉʊʋʌʍʎʏʐʑʒʓʔʕʖʗʘʙʚʛʜʝʞʟʠʡʢʣʤʥʦʧʨʩʪʫʬʭʮʯΆΈ
+ΉΊΌΎΏΐΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡΣΤΥΦΧΨΩΪΫάέήίΰαβγδεζηθικλμνξοπρςστυφχψωϊϋόύ
+ώϐϑϒϓϔϕϖϗϘϙϚϛϜϝϞϟϠϡϢϣϤϥϦϧϨϩϪϫϬϭϮϯϰϱϲϳϴϵϷϸϹϺϻϼϽϾϿЀЁЂЃЄЅІЇЈЉЊЋЌЍЎЏАБ
+ВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯабвгдежзийклмнопрстуфхцчшщъыьэюяѐёђѓ
+єѕіїјљњћќѝўџѠѡѢѣѤѥѦѧѨѩѪѫѬѭѮѯѰѱѲѳѴѵѶѷѸѹѺѻѼѽѾѿҀҁҊҋҌҍҎҏҐґҒғҔҕҖҗҘҙҚқҜҝ
+ҞҟҠҡҢңҤҥҦҧҨҩҪҫҬҭҮүҰұҲҳҴҵҶҷҸҹҺһҼҽҾҿӀӁӂӃӄӅӆӇӈӉӊӋӌӍӎӐӑӒӓӔӕӖӗӘәӚӛӜӝӞӟӠ
+ӡӢӣӤӥӦӧӨөӪӫӬӭӮӯӰӱӲӳӴӵӶӷӸӹԀԁԂԃԄԅԆԇԈԉԊԋԌԍԎԏԱԲԳԴԵԶԷԸԹԺԻԼԽԾԿՀՁՂՃՄՅՆՇՈՉ
+ՊՋՌՍՎՏՐՑՒՓՔՕՖաբգդեզէըթժիլխծկհձղճմյնշոչպջռսվտրցւփքօֆևႠႡႢႣႤႥႦႧႨႩႪႫႬႭ
+ႮႯႰႱႲႳႴႵႶႷႸႹႺႻႼႽႾႿჀჁჂჃჄჅᴀᴁᴂᴃᴄᴅᴆᴇᴈᴉᴊᴋᴌᴍᴎᴏᴐᴑᴒᴓᴔᴕᴖᴗᴘᴙᴚᴛᴜᴝᴞᴟᴠᴡᴢᴣᴤᴥᴦᴧᴨᴩ
+ᴪᴫᵢᵣᵤᵥᵦᵧᵨᵩᵪᵫᵬᵭᵮᵯᵰᵱᵲᵳᵴᵵᵶᵷᵹᵺᵻᵼᵽᵾᵿᶀᶁᶂᶃᶄᶅᶆᶇᶈᶉᶊᶋᶌᶍᶎᶏᶐᶑᶒᶓᶔᶕᶖᶗᶘᶙᶚḀḁḂḃḄḅḆḇ
+ḈḉḊḋḌḍḎḏḐḑḒḓḔḕḖḗḘḙḚḛḜḝḞḟḠḡḢḣḤḥḦḧḨḩḪḫḬḭḮḯḰḱḲḳḴḵḶḷḸḹḺḻḼḽḾḿṀṁṂṃṄṅṆṇṈṉ
+ṊṋṌṍṎṏṐṑṒṓṔṕṖṗṘṙṚṛṜṝṞṟṠṡṢṣṤṥṦṧṨṩṪṫṬṭṮṯṰṱṲṳṴṵṶṷṸṹṺṻṼṽṾṿẀẁẂẃẄẅẆẇẈẉẊẋ
+ẌẍẎẏẐẑẒẓẔẕẖẗẘẙẚẛẠạẢảẤấẦầẨẩẪẫẬậẮắẰằẲẳẴẵẶặẸẹẺẻẼẽẾếỀềỂểỄễỆệỈỉỊịỌọỎỏỐố
+ỒồỔổỖỗỘộỚớỜờỞởỠỡỢợỤụỦủỨứỪừỬửỮữỰựỲỳỴỵỶỷỸỹἀἁἂἃἄἅἆἇἈἉἊἋἌἍἎἏἐἑἒἓἔἕἘἙἚἛ
+ἜἝἠἡἢἣἤἥἦἧἨἩἪἫἬἭἮἯἰἱἲἳἴἵἶἷἸἹἺἻἼἽἾἿὀὁὂὃὄὅὈὉὊὋὌὍὐὑὒὓὔὕὖὗὙὛὝὟὠὡὢὣὤὥὦὧ
+ὨὩὪὫὬὭὮὯὰάὲέὴήὶίὸόὺύὼώᾀᾁᾂᾃᾄᾅᾆᾇᾐᾑᾒᾓᾔᾕᾖᾗᾠᾡᾢᾣᾤᾥᾦᾧᾰᾱᾲᾳᾴᾶᾷᾸᾹᾺΆιῂῃῄῆῇῈΈῊ
+ΉῐῑῒΐῖῗῘῙῚΊῠῡῢΰῤῥῦῧῨῩῪΎῬῲῳῴῶῷῸΌῺΏⁱⁿℂℇℊℋℌℍℎℏℐℑℒℓℕℙℚℛℜℝℤΩℨKÅℬℭℯℰℱℳℴℹ
+ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzªµºÀÁÂÃÄÅÆÇÈÉÊ
+ËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõöøùúûüýþÿĀāĂ㥹ĆćĈĉĊċČčĎ
+ďĐđĒēĔĕĖėĘęĚěĜĝĞğĠġĢģĤĥĦħĨĩĪīĬĭĮįİıIJijĴĵĶķĸĹĺĻļĽľĿŀŁłŃńŅņŇňʼnŊŋŌōŎŏŐ
+őŒœŔŕŖŗŘřŚśŜŝŞşŠšŢţŤťŦŧŨũŪūŬŭŮůŰűŲųŴŵŶŷŸŹźŻżŽžſƀƁƂƃƄƅƆƇƈƉƊƋƌƍƎƏƐƑƒ
+ƓƔƕƖƗƘƙƚƛƜƝƞƟƠơƢƣƤƥƦƧƨƩƪƫƬƭƮƯưƱƲƳƴƵƶƷƸƹƺƼƽƾƿDŽdžLJljNJnjǍǎǏǐǑǒǓǔǕǖǗǘǙǚǛǜ
+ǝǞǟǠǡǢǣǤǥǦǧǨǩǪǫǬǭǮǯǰDZdzǴǵǶǷǸǹǺǻǼǽǾǿȀȁȂȃȄȅȆȇȈȉȊȋȌȍȎȏȐȑȒȓȔȕȖȗȘșȚțȜȝȞȟ
+ȠȡȢȣȤȥȦȧȨȩȪȫȬȭȮȯȰȱȲȳȴȵȶȷȸȹȺȻȼȽȾȿɀɁɐɑɒɓɔɕɖɗɘəɚɛɜɝɞɟɠɡɢɣɤɥɦɧɨɩɪɫɬɭɮɯ
+ɰɱɲɳɴɵɶɷɸɹɺɻɼɽɾɿʀʁʂʃʄʅʆʇʈʉʊʋʌʍʎʏʐʑʒʓʔʕʖʗʘʙʚʛʜʝʞʟʠʡʢʣʤʥʦʧʨʩʪʫʬʭʮʯΆΈ
+ΉΊΌΎΏΐΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡΣΤΥΦΧΨΩΪΫάέήίΰαβγδεζηθικλμνξοπρςστυφχψωϊϋόύ
+ώϐϑϒϓϔϕϖϗϘϙϚϛϜϝϞϟϠϡϢϣϤϥϦϧϨϩϪϫϬϭϮϯϰϱϲϳϴϵϷϸϹϺϻϼϽϾϿЀЁЂЃЄЅІЇЈЉЊЋЌЍЎЏАБ
+ВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯабвгдежзийклмнопрстуфхцчшщъыьэюяѐёђѓ
+єѕіїјљњћќѝўџѠѡѢѣѤѥѦѧѨѩѪѫѬѭѮѯѰѱѲѳѴѵѶѷѸѹѺѻѼѽѾѿҀҁҊҋҌҍҎҏҐґҒғҔҕҖҗҘҙҚқҜҝ
+ҞҟҠҡҢңҤҥҦҧҨҩҪҫҬҭҮүҰұҲҳҴҵҶҷҸҹҺһҼҽҾҿӀӁӂӃӄӅӆӇӈӉӊӋӌӍӎӐӑӒӓӔӕӖӗӘәӚӛӜӝӞӟӠ
+ӡӢӣӤӥӦӧӨөӪӫӬӭӮӯӰӱӲӳӴӵӶӷӸӹԀԁԂԃԄԅԆԇԈԉԊԋԌԍԎԏԱԲԳԴԵԶԷԸԹԺԻԼԽԾԿՀՁՂՃՄՅՆՇՈՉ
+ՊՋՌՍՎՏՐՑՒՓՔՕՖաբգդեզէըթժիլխծկհձղճմյնշոչպջռսվտրցւփքօֆևႠႡႢႣႤႥႦႧႨႩႪႫႬႭ
+ႮႯႰႱႲႳႴႵႶႷႸႹႺႻႼႽႾႿჀჁჂჃჄჅᴀᴁᴂᴃᴄᴅᴆᴇᴈᴉᴊᴋᴌᴍᴎᴏᴐᴑᴒᴓᴔᴕᴖᴗᴘᴙᴚᴛᴜᴝᴞᴟᴠᴡᴢᴣᴤᴥᴦᴧᴨᴩ
+ᴪᴫᵢᵣᵤᵥᵦᵧᵨᵩᵪᵫᵬᵭᵮᵯᵰᵱᵲᵳᵴᵵᵶᵷᵹᵺᵻᵼᵽᵾᵿᶀᶁᶂᶃᶄᶅᶆᶇᶈᶉᶊᶋᶌᶍᶎᶏᶐᶑᶒᶓᶔᶕᶖᶗᶘᶙᶚḀḁḂḃḄḅḆḇ
+ḈḉḊḋḌḍḎḏḐḑḒḓḔḕḖḗḘḙḚḛḜḝḞḟḠḡḢḣḤḥḦḧḨḩḪḫḬḭḮḯḰḱḲḳḴḵḶḷḸḹḺḻḼḽḾḿṀṁṂṃṄṅṆṇṈṉ
+ṊṋṌṍṎṏṐṑṒṓṔṕṖṗṘṙṚṛṜṝṞṟṠṡṢṣṤṥṦṧṨṩṪṫṬṭṮṯṰṱṲṳṴṵṶṷṸṹṺṻṼṽṾṿẀẁẂẃẄẅẆẇẈẉẊẋ
+ẌẍẎẏẐẑẒẓẔẕẖẗẘẙẚẛẠạẢảẤấẦầẨẩẪẫẬậẮắẰằẲẳẴẵẶặẸẹẺẻẼẽẾếỀềỂểỄễỆệỈỉỊịỌọỎỏỐố
+ỒồỔổỖỗỘộỚớỜờỞởỠỡỢợỤụỦủỨứỪừỬửỮữỰựỲỳỴỵỶỷỸỹἀἁἂἃἄἅἆἇἈἉἊἋἌἍἎἏἐἑἒἓἔἕἘἙἚἛ
+ἜἝἠἡἢἣἤἥἦἧἨἩἪἫἬἭἮἯἰἱἲἳἴἵἶἷἸἹἺἻἼἽἾἿὀὁὂὃὄὅὈὉὊὋὌὍὐὑὒὓὔὕὖὗὙὛὝὟὠὡὢὣὤὥὦὧ
+ὨὩὪὫὬὭὮὯὰάὲέὴήὶίὸόὺύὼώᾀᾁᾂᾃᾄᾅᾆᾇᾐᾑᾒᾓᾔᾕᾖᾗᾠᾡᾢᾣᾤᾥᾦᾧᾰᾱᾲᾳᾴᾶᾷᾸᾹᾺΆιῂῃῄῆῇῈΈῊ
+ΉῐῑῒΐῖῗῘῙῚΊῠῡῢΰῤῥῦῧῨῩῪΎῬῲῳῴῶῷῸΌῺΏⁱⁿℂℇℊℋℌℍℎℏℐℑℒℓℕℙℚℛℜℝℤΩℨKÅℬℭℯℰℱℳℴℹ
+ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzªµºÀÁÂÃÄÅÆÇÈÉÊ
+ËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõöøùúûüýþÿĀāĂ㥹ĆćĈĉĊċČčĎ
+ďĐđĒēĔĕĖėĘęĚěĜĝĞğĠġĢģĤĥĦħĨĩĪīĬĭĮįİıIJijĴĵĶķĸĹĺĻļĽľĿŀŁłŃńŅņŇňʼnŊŋŌōŎŏŐ
+őŒœŔŕŖŗŘřŚśŜŝŞşŠšŢţŤťŦŧŨũŪūŬŭŮůŰűŲųŴŵŶŷŸŹźŻżŽžſƀƁƂƃƄƅƆƇƈƉƊƋƌƍƎƏƐƑƒ
+ƓƔƕƖƗƘƙƚƛƜƝƞƟƠơƢƣƤƥƦƧƨƩƪƫƬƭƮƯưƱƲƳƴƵƶƷƸƹƺƼƽƾƿDŽdžLJljNJnjǍǎǏǐǑǒǓǔǕǖǗǘǙǚǛǜ
+ǝǞǟǠǡǢǣǤǥǦǧǨǩǪǫǬǭǮǯǰDZdzǴǵǶǷǸǹǺǻǼǽǾǿȀȁȂȃȄȅȆȇȈȉȊȋȌȍȎȏȐȑȒȓȔȕȖȗȘșȚțȜȝȞȟ
+ȠȡȢȣȤȥȦȧȨȩȪȫȬȭȮȯȰȱȲȳȴȵȶȷȸȹȺȻȼȽȾȿɀɁɐɑɒɓɔɕɖɗɘəɚɛɜɝɞɟɠɡɢɣɤɥɦɧɨɩɪɫɬɭɮɯ
+ɰɱɲɳɴɵɶɷɸɹɺɻɼɽɾɿʀʁʂʃʄʅʆʇʈʉʊʋʌʍʎʏʐʑʒʓʔʕʖʗʘʙʚʛʜʝʞʟʠʡʢʣʤʥʦʧʨʩʪʫʬʭʮʯΆΈ
+ΉΊΌΎΏΐΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡΣΤΥΦΧΨΩΪΫάέήίΰαβγδεζηθικλμνξοπρςστυφχψωϊϋόύ
+ώϐϑϒϓϔϕϖϗϘϙϚϛϜϝϞϟϠϡϢϣϤϥϦϧϨϩϪϫϬϭϮϯϰϱϲϳϴϵϷϸϹϺϻϼϽϾϿЀЁЂЃЄЅІЇЈЉЊЋЌЍЎЏАБ
+ВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯабвгдежзийклмнопрстуфхцчшщъыьэюяѐёђѓ
+єѕіїјљњћќѝўџѠѡѢѣѤѥѦѧѨѩѪѫѬѭѮѯѰѱѲѳѴѵѶѷѸѹѺѻѼѽѾѿҀҁҊҋҌҍҎҏҐґҒғҔҕҖҗҘҙҚқҜҝ
+ҞҟҠҡҢңҤҥҦҧҨҩҪҫҬҭҮүҰұҲҳҴҵҶҷҸҹҺһҼҽҾҿӀӁӂӃӄӅӆӇӈӉӊӋӌӍӎӐӑӒӓӔӕӖӗӘәӚӛӜӝӞӟӠ
+ӡӢӣӤӥӦӧӨөӪӫӬӭӮӯӰӱӲӳӴӵӶӷӸӹԀԁԂԃԄԅԆԇԈԉԊԋԌԍԎԏԱԲԳԴԵԶԷԸԹԺԻԼԽԾԿՀՁՂՃՄՅՆՇՈՉ
+ՊՋՌՍՎՏՐՑՒՓՔՕՖաբգդեզէըթժիլխծկհձղճմյնշոչպջռսվտրցւփքօֆևႠႡႢႣႤႥႦႧႨႩႪႫႬႭ
+ႮႯႰႱႲႳႴႵႶႷႸႹႺႻႼႽႾႿჀჁჂჃჄჅᴀᴁᴂᴃᴄᴅᴆᴇᴈᴉᴊᴋᴌᴍᴎᴏᴐᴑᴒᴓᴔᴕᴖᴗᴘᴙᴚᴛᴜᴝᴞᴟᴠᴡᴢᴣᴤᴥᴦᴧᴨᴩ
+ᴪᴫᵢᵣᵤᵥᵦᵧᵨᵩᵪᵫᵬᵭᵮᵯᵰᵱᵲᵳᵴᵵᵶᵷᵹᵺᵻᵼᵽᵾᵿᶀᶁᶂᶃᶄᶅᶆᶇᶈᶉᶊᶋᶌᶍᶎᶏᶐᶑᶒᶓᶔᶕᶖᶗᶘᶙᶚḀḁḂḃḄḅḆḇ
+ḈḉḊḋḌḍḎḏḐḑḒḓḔḕḖḗḘḙḚḛḜḝḞḟḠḡḢḣḤḥḦḧḨḩḪḫḬḭḮḯḰḱḲḳḴḵḶḷḸḹḺḻḼḽḾḿṀṁṂṃṄṅṆṇṈṉ
+ṊṋṌṍṎṏṐṑṒṓṔṕṖṗṘṙṚṛṜṝṞṟṠṡṢṣṤṥṦṧṨṩṪṫṬṭṮṯṰṱṲṳṴṵṶṷṸṹṺṻṼṽṾṿẀẁẂẃẄẅẆẇẈẉẊẋ
+ẌẍẎẏẐẑẒẓẔẕẖẗẘẙẚẛẠạẢảẤấẦầẨẩẪẫẬậẮắẰằẲẳẴẵẶặẸẹẺẻẼẽẾếỀềỂểỄễỆệỈỉỊịỌọỎỏỐố
+ỒồỔổỖỗỘộỚớỜờỞởỠỡỢợỤụỦủỨứỪừỬửỮữỰựỲỳỴỵỶỷỸỹἀἁἂἃἄἅἆἇἈἉἊἋἌἍἎἏἐἑἒἓἔἕἘἙἚἛ
+ἜἝἠἡἢἣἤἥἦἧἨἩἪἫἬἭἮἯἰἱἲἳἴἵἶἷἸἹἺἻἼἽἾἿὀὁὂὃὄὅὈὉὊὋὌὍὐὑὒὓὔὕὖὗὙὛὝὟὠὡὢὣὤὥὦὧ
+ὨὩὪὫὬὭὮὯὰάὲέὴήὶίὸόὺύὼώᾀᾁᾂᾃᾄᾅᾆᾇᾐᾑᾒᾓᾔᾕᾖᾗᾠᾡᾢᾣᾤᾥᾦᾧᾰᾱᾲᾳᾴᾶᾷᾸᾹᾺΆιῂῃῄῆῇῈΈῊ
+ΉῐῑῒΐῖῗῘῙῚΊῠῡῢΰῤῥῦῧῨῩῪΎῬῲῳῴῶῷῸΌῺΏⁱⁿℂℇℊℋℌℍℎℏℐℑℒℓℕℙℚℛℜℝℤΩℨKÅℬℭℯℰℱℳℴℹ
+ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzªµºÀÁÂÃÄÅÆÇÈÉÊ
+ËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõöøùúûüýþÿĀāĂ㥹ĆćĈĉĊċČčĎ
+ďĐđĒēĔĕĖėĘęĚěĜĝĞğĠġĢģĤĥĦħĨĩĪīĬĭĮįİıIJijĴĵĶķĸĹĺĻļĽľĿŀŁłŃńŅņŇňʼnŊŋŌōŎŏŐ
+őŒœŔŕŖŗŘřŚśŜŝŞşŠšŢţŤťŦŧŨũŪūŬŭŮůŰűŲųŴŵŶŷŸŹźŻżŽžſƀƁƂƃƄƅƆƇƈƉƊƋƌƍƎƏƐƑƒ
+ƓƔƕƖƗƘƙƚƛƜƝƞƟƠơƢƣƤƥƦƧƨƩƪƫƬƭƮƯưƱƲƳƴƵƶƷƸƹƺƼƽƾƿDŽdžLJljNJnjǍǎǏǐǑǒǓǔǕǖǗǘǙǚǛǜ
+ǝǞǟǠǡǢǣǤǥǦǧǨǩǪǫǬǭǮǯǰDZdzǴǵǶǷǸǹǺǻǼǽǾǿȀȁȂȃȄȅȆȇȈȉȊȋȌȍȎȏȐȑȒȓȔȕȖȗȘșȚțȜȝȞȟ
+ȠȡȢȣȤȥȦȧȨȩȪȫȬȭȮȯȰȱȲȳȴȵȶȷȸȹȺȻȼȽȾȿɀɁɐɑɒɓɔɕɖɗɘəɚɛɜɝɞɟɠɡɢɣɤɥɦɧɨɩɪɫɬɭɮɯ
+ɰɱɲɳɴɵɶɷɸɹɺɻɼɽɾɿʀʁʂʃʄʅʆʇʈʉʊʋʌʍʎʏʐʑʒʓʔʕʖʗʘʙʚʛʜʝʞʟʠʡʢʣʤʥʦʧʨʩʪʫʬʭʮʯΆΈ
+ΉΊΌΎΏΐΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡΣΤΥΦΧΨΩΪΫάέήίΰαβγδεζηθικλμνξοπρςστυφχψωϊϋόύ
+ώϐϑϒϓϔϕϖϗϘϙϚϛϜϝϞϟϠϡϢϣϤϥϦϧϨϩϪϫϬϭϮϯϰϱϲϳϴϵϷϸϹϺϻϼϽϾϿЀЁЂЃЄЅІЇЈЉЊЋЌЍЎЏАБ
+ВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯабвгдежзийклмнопрстуфхцчшщъыьэюяѐёђѓ
+єѕіїјљњћќѝўџѠѡѢѣѤѥѦѧѨѩѪѫѬѭѮѯѰѱѲѳѴѵѶѷѸѹѺѻѼѽѾѿҀҁҊҋҌҍҎҏҐґҒғҔҕҖҗҘҙҚқҜҝ
+ҞҟҠҡҢңҤҥҦҧҨҩҪҫҬҭҮүҰұҲҳҴҵҶҷҸҹҺһҼҽҾҿӀӁӂӃӄӅӆӇӈӉӊӋӌӍӎӐӑӒӓӔӕӖӗӘәӚӛӜӝӞӟӠ
+ӡӢӣӤӥӦӧӨөӪӫӬӭӮӯӰӱӲӳӴӵӶӷӸӹԀԁԂԃԄԅԆԇԈԉԊԋԌԍԎԏԱԲԳԴԵԶԷԸԹԺԻԼԽԾԿՀՁՂՃՄՅՆՇՈՉ
+ՊՋՌՍՎՏՐՑՒՓՔՕՖաբգդեզէըթժիլխծկհձղճմյնշոչպջռսվտրցւփքօֆևႠႡႢႣႤႥႦႧႨႩႪႫႬႭ
+ႮႯႰႱႲႳႴႵႶႷႸႹႺႻႼႽႾႿჀჁჂჃჄჅᴀᴁᴂᴃᴄᴅᴆᴇᴈᴉᴊᴋᴌᴍᴎᴏᴐᴑᴒᴓᴔᴕᴖᴗᴘᴙᴚᴛᴜᴝᴞᴟᴠᴡᴢᴣᴤᴥᴦᴧᴨᴩ
+ᴪᴫᵢᵣᵤᵥᵦᵧᵨᵩᵪᵫᵬᵭᵮᵯᵰᵱᵲᵳᵴᵵᵶᵷᵹᵺᵻᵼᵽᵾᵿᶀᶁᶂᶃᶄᶅᶆᶇᶈᶉᶊᶋᶌᶍᶎᶏᶐᶑᶒᶓᶔᶕᶖᶗᶘᶙᶚḀḁḂḃḄḅḆḇ
+ḈḉḊḋḌḍḎḏḐḑḒḓḔḕḖḗḘḙḚḛḜḝḞḟḠḡḢḣḤḥḦḧḨḩḪḫḬḭḮḯḰḱḲḳḴḵḶḷḸḹḺḻḼḽḾḿṀṁṂṃṄṅṆṇṈṉ
+ṊṋṌṍṎṏṐṑṒṓṔṕṖṗṘṙṚṛṜṝṞṟṠṡṢṣṤṥṦṧṨṩṪṫṬṭṮṯṰṱṲṳṴṵṶṷṸṹṺṻṼṽṾṿẀẁẂẃẄẅẆẇẈẉẊẋ
+ẌẍẎẏẐẑẒẓẔẕẖẗẘẙẚẛẠạẢảẤấẦầẨẩẪẫẬậẮắẰằẲẳẴẵẶặẸẹẺẻẼẽẾếỀềỂểỄễỆệỈỉỊịỌọỎỏỐố
+ỒồỔổỖỗỘộỚớỜờỞởỠỡỢợỤụỦủỨứỪừỬửỮữỰựỲỳỴỵỶỷỸỹἀἁἂἃἄἅἆἇἈἉἊἋἌἍἎἏἐἑἒἓἔἕἘἙἚἛ
+ἜἝἠἡἢἣἤἥἦἧἨἩἪἫἬἭἮἯἰἱἲἳἴἵἶἷἸἹἺἻἼἽἾἿὀὁὂὃὄὅὈὉὊὋὌὍὐὑὒὓὔὕὖὗὙὛὝὟὠὡὢὣὤὥὦὧ
+ὨὩὪὫὬὭὮὯὰάὲέὴήὶίὸόὺύὼώᾀᾁᾂᾃᾄᾅᾆᾇᾐᾑᾒᾓᾔᾕᾖᾗᾠᾡᾢᾣᾤᾥᾦᾧᾰᾱᾲᾳᾴᾶᾷᾸᾹᾺΆιῂῃῄῆῇῈΈῊ
+ΉῐῑῒΐῖῗῘῙῚΊῠῡῢΰῤῥῦῧῨῩῪΎῬῲῳῴῶῷῸΌῺΏⁱⁿℂℇℊℋℌℍℎℏℐℑℒℓℕℙℚℛℜℝℤΩℨKÅℬℭℯℰℱℳℴℹ
+ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzªµºÀÁÂÃÄÅÆÇÈÉÊ
+ËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõöøùúûüýþÿĀāĂ㥹ĆćĈĉĊċČčĎ
+ďĐđĒēĔĕĖėĘęĚěĜĝĞğĠġĢģĤĥĦħĨĩĪīĬĭĮįİıIJijĴĵĶķĸĹĺĻļĽľĿŀŁłŃńŅņŇňʼnŊŋŌōŎŏŐ
+őŒœŔŕŖŗŘřŚśŜŝŞşŠšŢţŤťŦŧŨũŪūŬŭŮůŰűŲųŴŵŶŷŸŹźŻżŽžſƀƁƂƃƄƅƆƇƈƉƊƋƌƍƎƏƐƑƒ
+ƓƔƕƖƗƘƙƚƛƜƝƞƟƠơƢƣƤƥƦƧƨƩƪƫƬƭƮƯưƱƲƳƴƵƶƷƸƹƺƼƽƾƿDŽdžLJljNJnjǍǎǏǐǑǒǓǔǕǖǗǘǙǚǛǜ
+ǝǞǟǠǡǢǣǤǥǦǧǨǩǪǫǬǭǮǯǰDZdzǴǵǶǷǸǹǺǻǼǽǾǿȀȁȂȃȄȅȆȇȈȉȊȋȌȍȎȏȐȑȒȓȔȕȖȗȘșȚțȜȝȞȟ
+ȠȡȢȣȤȥȦȧȨȩȪȫȬȭȮȯȰȱȲȳȴȵȶȷȸȹȺȻȼȽȾȿɀɁɐɑɒɓɔɕɖɗɘəɚɛɜɝɞɟɠɡɢɣɤɥɦɧɨɩɪɫɬɭɮɯ
+ɰɱɲɳɴɵɶɷɸɹɺɻɼɽɾɿʀʁʂʃʄʅʆʇʈʉʊʋʌʍʎʏʐʑʒʓʔʕʖʗʘʙʚʛʜʝʞʟʠʡʢʣʤʥʦʧʨʩʪʫʬʭʮʯΆΈ
+ΉΊΌΎΏΐΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡΣΤΥΦΧΨΩΪΫάέήίΰαβγδεζηθικλμνξοπρςστυφχψωϊϋόύ
+ώϐϑϒϓϔϕϖϗϘϙϚϛϜϝϞϟϠϡϢϣϤϥϦϧϨϩϪϫϬϭϮϯϰϱϲϳϴϵϷϸϹϺϻϼϽϾϿЀЁЂЃЄЅІЇЈЉЊЋЌЍЎЏАБ
+ВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯабвгдежзийклмнопрстуфхцчшщъыьэюяѐёђѓ
+єѕіїјљњћќѝўџѠѡѢѣѤѥѦѧѨѩѪѫѬѭѮѯѰѱѲѳѴѵѶѷѸѹѺѻѼѽѾѿҀҁҊҋҌҍҎҏҐґҒғҔҕҖҗҘҙҚқҜҝ
+ҞҟҠҡҢңҤҥҦҧҨҩҪҫҬҭҮүҰұҲҳҴҵҶҷҸҹҺһҼҽҾҿӀӁӂӃӄӅӆӇӈӉӊӋӌӍӎӐӑӒӓӔӕӖӗӘәӚӛӜӝӞӟӠ
+ӡӢӣӤӥӦӧӨөӪӫӬӭӮӯӰӱӲӳӴӵӶӷӸӹԀԁԂԃԄԅԆԇԈԉԊԋԌԍԎԏԱԲԳԴԵԶԷԸԹԺԻԼԽԾԿՀՁՂՃՄՅՆՇՈՉ
+ՊՋՌՍՎՏՐՑՒՓՔՕՖաբգդեզէըթժիլխծկհձղճմյնշոչպջռսվտրցւփքօֆևႠႡႢႣႤႥႦႧႨႩႪႫႬႭ
+ႮႯႰႱႲႳႴႵႶႷႸႹႺႻႼႽႾႿჀჁჂჃჄჅᴀᴁᴂᴃᴄᴅᴆᴇᴈᴉᴊᴋᴌᴍᴎᴏᴐᴑᴒᴓᴔᴕᴖᴗᴘᴙᴚᴛᴜᴝᴞᴟᴠᴡᴢᴣᴤᴥᴦᴧᴨᴩ
+ᴪᴫᵢᵣᵤᵥᵦᵧᵨᵩᵪᵫᵬᵭᵮᵯᵰᵱᵲᵳᵴᵵᵶᵷᵹᵺᵻᵼᵽᵾᵿᶀᶁᶂᶃᶄᶅᶆᶇᶈᶉᶊᶋᶌᶍᶎᶏᶐᶑᶒᶓᶔᶕᶖᶗᶘᶙᶚḀḁḂḃḄḅḆḇ
+ḈḉḊḋḌḍḎḏḐḑḒḓḔḕḖḗḘḙḚḛḜḝḞḟḠḡḢḣḤḥḦḧḨḩḪḫḬḭḮḯḰḱḲḳḴḵḶḷḸḹḺḻḼḽḾḿṀṁṂṃṄṅṆṇṈṉ
+ṊṋṌṍṎṏṐṑṒṓṔṕṖṗṘṙṚṛṜṝṞṟṠṡṢṣṤṥṦṧṨṩṪṫṬṭṮṯṰṱṲṳṴṵṶṷṸṹṺṻṼṽṾṿẀẁẂẃẄẅẆẇẈẉẊẋ
+ẌẍẎẏẐẑẒẓẔẕẖẗẘẙẚẛẠạẢảẤấẦầẨẩẪẫẬậẮắẰằẲẳẴẵẶặẸẹẺẻẼẽẾếỀềỂểỄễỆệỈỉỊịỌọỎỏỐố
+ỒồỔổỖỗỘộỚớỜờỞởỠỡỢợỤụỦủỨứỪừỬửỮữỰựỲỳỴỵỶỷỸỹἀἁἂἃἄἅἆἇἈἉἊἋἌἍἎἏἐἑἒἓἔἕἘἙἚἛ
+ἜἝἠἡἢἣἤἥἦἧἨἩἪἫἬἭἮἯἰἱἲἳἴἵἶἷἸἹἺἻἼἽἾἿὀὁὂὃὄὅὈὉὊὋὌὍὐὑὒὓὔὕὖὗὙὛὝὟὠὡὢὣὤὥὦὧ
+ὨὩὪὫὬὭὮὯὰάὲέὴήὶίὸόὺύὼώᾀᾁᾂᾃᾄᾅᾆᾇᾐᾑᾒᾓᾔᾕᾖᾗᾠᾡᾢᾣᾤᾥᾦᾧᾰᾱᾲᾳᾴᾶᾷᾸᾹᾺΆιῂῃῄῆῇῈΈῊ
+ΉῐῑῒΐῖῗῘῙῚΊῠῡῢΰῤῥῦῧῨῩῪΎῬῲῳῴῶῷῸΌῺΏⁱⁿℂℇℊℋℌℍℎℏℐℑℒℓℕℙℚℛℜℝℤΩℨKÅℬℭℯℰℱℳℴℹ
+ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzªµºÀÁÂÃÄÅÆÇÈÉÊ
+ËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõöøùúûüýþÿĀāĂ㥹ĆćĈĉĊċČčĎ
+ďĐđĒēĔĕĖėĘęĚěĜĝĞğĠġĢģĤĥĦħĨĩĪīĬĭĮįİıIJijĴĵĶķĸĹĺĻļĽľĿŀŁłŃńŅņŇňʼnŊŋŌōŎŏŐ
+őŒœŔŕŖŗŘřŚśŜŝŞşŠšŢţŤťŦŧŨũŪūŬŭŮůŰűŲųŴŵŶŷŸŹźŻżŽžſƀƁƂƃƄƅƆƇƈƉƊƋƌƍƎƏƐƑƒ
+ƓƔƕƖƗƘƙƚƛƜƝƞƟƠơƢƣƤƥƦƧƨƩƪƫƬƭƮƯưƱƲƳƴƵƶƷƸƹƺƼƽƾƿDŽdžLJljNJnjǍǎǏǐǑǒǓǔǕǖǗǘǙǚǛǜ
+ǝǞǟǠǡǢǣǤǥǦǧǨǩǪǫǬǭǮǯǰDZdzǴǵǶǷǸǹǺǻǼǽǾǿȀȁȂȃȄȅȆȇȈȉȊȋȌȍȎȏȐȑȒȓȔȕȖȗȘșȚțȜȝȞȟ
+ȠȡȢȣȤȥȦȧȨȩȪȫȬȭȮȯȰȱȲȳȴȵȶȷȸȹȺȻȼȽȾȿɀɁɐɑɒɓɔɕɖɗɘəɚɛɜɝɞɟɠɡɢɣɤɥɦɧɨɩɪɫɬɭɮɯ
+ɰɱɲɳɴɵɶɷɸɹɺɻɼɽɾɿʀʁʂʃʄʅʆʇʈʉʊʋʌʍʎʏʐʑʒʓʔʕʖʗʘʙʚʛʜʝʞʟʠʡʢʣʤʥʦʧʨʩʪʫʬʭʮʯΆΈ
+ΉΊΌΎΏΐΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡΣΤΥΦΧΨΩΪΫάέήίΰαβγδεζηθικλμνξοπρςστυφχψωϊϋόύ
+ώϐϑϒϓϔϕϖϗϘϙϚϛϜϝϞϟϠϡϢϣϤϥϦϧϨϩϪϫϬϭϮϯϰϱϲϳϴϵϷϸϹϺϻϼϽϾϿЀЁЂЃЄЅІЇЈЉЊЋЌЍЎЏАБ
+ВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯабвгдежзийклмнопрстуфхцчшщъыьэюяѐёђѓ
+єѕіїјљњћќѝўџѠѡѢѣѤѥѦѧѨѩѪѫѬѭѮѯѰѱѲѳѴѵѶѷѸѹѺѻѼѽѾѿҀҁҊҋҌҍҎҏҐґҒғҔҕҖҗҘҙҚқҜҝ
+ҞҟҠҡҢңҤҥҦҧҨҩҪҫҬҭҮүҰұҲҳҴҵҶҷҸҹҺһҼҽҾҿӀӁӂӃӄӅӆӇӈӉӊӋӌӍӎӐӑӒӓӔӕӖӗӘәӚӛӜӝӞӟӠ
+ӡӢӣӤӥӦӧӨөӪӫӬӭӮӯӰӱӲӳӴӵӶӷӸӹԀԁԂԃԄԅԆԇԈԉԊԋԌԍԎԏԱԲԳԴԵԶԷԸԹԺԻԼԽԾԿՀՁՂՃՄՅՆՇՈՉ
+ՊՋՌՍՎՏՐՑՒՓՔՕՖաբգդեզէըթժիլխծկհձղճմյնշոչպջռսվտրցւփքօֆևႠႡႢႣႤႥႦႧႨႩႪႫႬႭ
+ႮႯႰႱႲႳႴႵႶႷႸႹႺႻႼႽႾႿჀჁჂჃჄჅᴀᴁᴂᴃᴄᴅᴆᴇᴈᴉᴊᴋᴌᴍᴎᴏᴐᴑᴒᴓᴔᴕᴖᴗᴘᴙᴚᴛᴜᴝᴞᴟᴠᴡᴢᴣᴤᴥᴦᴧᴨᴩ
+ᴪᴫᵢᵣᵤᵥᵦᵧᵨᵩᵪᵫᵬᵭᵮᵯᵰᵱᵲᵳᵴᵵᵶᵷᵹᵺᵻᵼᵽᵾᵿᶀᶁᶂᶃᶄᶅᶆᶇᶈᶉᶊᶋᶌᶍᶎᶏᶐᶑᶒᶓᶔᶕᶖᶗᶘᶙᶚḀḁḂḃḄḅḆḇ
+ḈḉḊḋḌḍḎḏḐḑḒḓḔḕḖḗḘḙḚḛḜḝḞḟḠḡḢḣḤḥḦḧḨḩḪḫḬḭḮḯḰḱḲḳḴḵḶḷḸḹḺḻḼḽḾḿṀṁṂṃṄṅṆṇṈṉ
+ṊṋṌṍṎṏṐṑṒṓṔṕṖṗṘṙṚṛṜṝṞṟṠṡṢṣṤṥṦṧṨṩṪṫṬṭṮṯṰṱṲṳṴṵṶṷṸṹṺṻṼṽṾṿẀẁẂẃẄẅẆẇẈẉẊẋ
+ẌẍẎẏẐẑẒẓẔẕẖẗẘẙẚẛẠạẢảẤấẦầẨẩẪẫẬậẮắẰằẲẳẴẵẶặẸẹẺẻẼẽẾếỀềỂểỄễỆệỈỉỊịỌọỎỏỐố
+ỒồỔổỖỗỘộỚớỜờỞởỠỡỢợỤụỦủỨứỪừỬửỮữỰựỲỳỴỵỶỷỸỹἀἁἂἃἄἅἆἇἈἉἊἋἌἍἎἏἐἑἒἓἔἕἘἙἚἛ
+ἜἝἠἡἢἣἤἥἦἧἨἩἪἫἬἭἮἯἰἱἲἳἴἵἶἷἸἹἺἻἼἽἾἿὀὁὂὃὄὅὈὉὊὋὌὍὐὑὒὓὔὕὖὗὙὛὝὟὠὡὢὣὤὥὦὧ
+ὨὩὪὫὬὭὮὯὰάὲέὴήὶίὸόὺύὼώᾀᾁᾂᾃᾄᾅᾆᾇᾐᾑᾒᾓᾔᾕᾖᾗᾠᾡᾢᾣᾤᾥᾦᾧᾰᾱᾲᾳᾴᾶᾷᾸᾹᾺΆιῂῃῄῆῇῈΈῊ
+ΉῐῑῒΐῖῗῘῙῚΊῠῡῢΰῤῥῦῧῨῩῪΎῬῲῳῴῶῷῸΌῺΏⁱⁿℂℇℊℋℌℍℎℏℐℑℒℓℕℙℚℛℜℝℤΩℨKÅℬℭℯℰℱℳℴℹ
+ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzªµºÀÁÂÃÄÅÆÇÈÉÊ
+ËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõöøùúûüýþÿĀāĂ㥹ĆćĈĉĊċČčĎ
+ďĐđĒēĔĕĖėĘęĚěĜĝĞğĠġĢģĤĥĦħĨĩĪīĬĭĮįİıIJijĴĵĶķĸĹĺĻļĽľĿŀŁłŃńŅņŇňʼnŊŋŌōŎŏŐ
+őŒœŔŕŖŗŘřŚśŜŝŞşŠšŢţŤťŦŧŨũŪūŬŭŮůŰűŲųŴŵŶŷŸŹźŻżŽžſƀƁƂƃƄƅƆƇƈƉƊƋƌƍƎƏƐƑƒ
+ƓƔƕƖƗƘƙƚƛƜƝƞƟƠơƢƣƤƥƦƧƨƩƪƫƬƭƮƯưƱƲƳƴƵƶƷƸƹƺƼƽƾƿDŽdžLJljNJnjǍǎǏǐǑǒǓǔǕǖǗǘǙǚǛǜ
+ǝǞǟǠǡǢǣǤǥǦǧǨǩǪǫǬǭǮǯǰDZdzǴǵǶǷǸǹǺǻǼǽǾǿȀȁȂȃȄȅȆȇȈȉȊȋȌȍȎȏȐȑȒȓȔȕȖȗȘșȚțȜȝȞȟ
+ȠȡȢȣȤȥȦȧȨȩȪȫȬȭȮȯȰȱȲȳȴȵȶȷȸȹȺȻȼȽȾȿɀɁɐɑɒɓɔɕɖɗɘəɚɛɜɝɞɟɠɡɢɣɤɥɦɧɨɩɪɫɬɭɮɯ
+ɰɱɲɳɴɵɶɷɸɹɺɻɼɽɾɿʀʁʂʃʄʅʆʇʈʉʊʋʌʍʎʏʐʑʒʓʔʕʖʗʘʙʚʛʜʝʞʟʠʡʢʣʤʥʦʧʨʩʪʫʬʭʮʯΆΈ
+ΉΊΌΎΏΐΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡΣΤΥΦΧΨΩΪΫάέήίΰαβγδεζηθικλμνξοπρςστυφχψωϊϋόύ
+ώϐϑϒϓϔϕϖϗϘϙϚϛϜϝϞϟϠϡϢϣϤϥϦϧϨϩϪϫϬϭϮϯϰϱϲϳϴϵϷϸϹϺϻϼϽϾϿЀЁЂЃЄЅІЇЈЉЊЋЌЍЎЏАБ
+ВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯабвгдежзийклмнопрстуфхцчшщъыьэюяѐёђѓ
+єѕіїјљњћќѝўџѠѡѢѣѤѥѦѧѨѩѪѫѬѭѮѯѰѱѲѳѴѵѶѷѸѹѺѻѼѽѾѿҀҁҊҋҌҍҎҏҐґҒғҔҕҖҗҘҙҚқҜҝ
+ҞҟҠҡҢңҤҥҦҧҨҩҪҫҬҭҮүҰұҲҳҴҵҶҷҸҹҺһҼҽҾҿӀӁӂӃӄӅӆӇӈӉӊӋӌӍӎӐӑӒӓӔӕӖӗӘәӚӛӜӝӞӟӠ
+ӡӢӣӤӥӦӧӨөӪӫӬӭӮӯӰӱӲӳӴӵӶӷӸӹԀԁԂԃԄԅԆԇԈԉԊԋԌԍԎԏԱԲԳԴԵԶԷԸԹԺԻԼԽԾԿՀՁՂՃՄՅՆՇՈՉ
+ՊՋՌՍՎՏՐՑՒՓՔՕՖաբգդեզէըթժիլխծկհձղճմյնշոչպջռսվտրցւփքօֆևႠႡႢႣႤႥႦႧႨႩႪႫႬႭ
+ႮႯႰႱႲႳႴႵႶႷႸႹႺႻႼႽႾႿჀჁჂჃჄჅᴀᴁᴂᴃᴄᴅᴆᴇᴈᴉᴊᴋᴌᴍᴎᴏᴐᴑᴒᴓᴔᴕᴖᴗᴘᴙᴚᴛᴜᴝᴞᴟᴠᴡᴢᴣᴤᴥᴦᴧᴨᴩ
+ᴪᴫᵢᵣᵤᵥᵦᵧᵨᵩᵪᵫᵬᵭᵮᵯᵰᵱᵲᵳᵴᵵᵶᵷᵹᵺᵻᵼᵽᵾᵿᶀᶁᶂᶃᶄᶅᶆᶇᶈᶉᶊᶋᶌᶍᶎᶏᶐᶑᶒᶓᶔᶕᶖᶗᶘᶙᶚḀḁḂḃḄḅḆḇ
+ḈḉḊḋḌḍḎḏḐḑḒḓḔḕḖḗḘḙḚḛḜḝḞḟḠḡḢḣḤḥḦḧḨḩḪḫḬḭḮḯḰḱḲḳḴḵḶḷḸḹḺḻḼḽḾḿṀṁṂṃṄṅṆṇṈṉ
+ṊṋṌṍṎṏṐṑṒṓṔṕṖṗṘṙṚṛṜṝṞṟṠṡṢṣṤṥṦṧṨṩṪṫṬṭṮṯṰṱṲṳṴṵṶṷṸṹṺṻṼṽṾṿẀẁẂẃẄẅẆẇẈẉẊẋ
+ẌẍẎẏẐẑẒẓẔẕẖẗẘẙẚẛẠạẢảẤấẦầẨẩẪẫẬậẮắẰằẲẳẴẵẶặẸẹẺẻẼẽẾếỀềỂểỄễỆệỈỉỊịỌọỎỏỐố
+ỒồỔổỖỗỘộỚớỜờỞởỠỡỢợỤụỦủỨứỪừỬửỮữỰựỲỳỴỵỶỷỸỹἀἁἂἃἄἅἆἇἈἉἊἋἌἍἎἏἐἑἒἓἔἕἘἙἚἛ
+ἜἝἠἡἢἣἤἥἦἧἨἩἪἫἬἭἮἯἰἱἲἳἴἵἶἷἸἹἺἻἼἽἾἿὀὁὂὃὄὅὈὉὊὋὌὍὐὑὒὓὔὕὖὗὙὛὝὟὠὡὢὣὤὥὦὧ
+ὨὩὪὫὬὭὮὯὰάὲέὴήὶίὸόὺύὼώᾀᾁᾂᾃᾄᾅᾆᾇᾐᾑᾒᾓᾔᾕᾖᾗᾠᾡᾢᾣᾤᾥᾦᾧᾰᾱᾲᾳᾴᾶᾷᾸᾹᾺΆιῂῃῄῆῇῈΈῊ
+ΉῐῑῒΐῖῗῘῙῚΊῠῡῢΰῤῥῦῧῨῩῪΎῬῲῳῴῶῷῸΌῺΏⁱⁿℂℇℊℋℌℍℎℏℐℑℒℓℕℙℚℛℜℝℤΩℨKÅℬℭℯℰℱℳℴℹ
diff --git a/tests/data/mappings.events b/tests/data/mappings.events
new file mode 100644
index 0000000..3cb5579
--- /dev/null
+++ b/tests/data/mappings.events
@@ -0,0 +1,44 @@
+- !StreamStart
+
+- !DocumentStart
+- !MappingStart
+- !Scalar { implicit: [true,true], value: 'key' }
+- !Scalar { implicit: [true,true], value: 'value' }
+- !Scalar { implicit: [true,true], value: 'empty mapping' }
+- !MappingStart
+- !MappingEnd
+- !Scalar { implicit: [true,true], value: 'empty mapping with tag' }
+- !MappingStart { tag: '!mytag', implicit: false }
+- !MappingEnd
+- !Scalar { implicit: [true,true], value: 'block mapping' }
+- !MappingStart
+- !MappingStart
+- !Scalar { implicit: [true,true], value: 'complex' }
+- !Scalar { implicit: [true,true], value: 'key' }
+- !Scalar { implicit: [true,true], value: 'complex' }
+- !Scalar { implicit: [true,true], value: 'key' }
+- !MappingEnd
+- !MappingStart
+- !Scalar { implicit: [true,true], value: 'complex' }
+- !Scalar { implicit: [true,true], value: 'key' }
+- !MappingEnd
+- !MappingEnd
+- !Scalar { implicit: [true,true], value: 'flow mapping' }
+- !MappingStart { flow_style: true }
+- !Scalar { implicit: [true,true], value: 'key' }
+- !Scalar { implicit: [true,true], value: 'value' }
+- !MappingStart
+- !Scalar { implicit: [true,true], value: 'complex' }
+- !Scalar { implicit: [true,true], value: 'key' }
+- !Scalar { implicit: [true,true], value: 'complex' }
+- !Scalar { implicit: [true,true], value: 'key' }
+- !MappingEnd
+- !MappingStart
+- !Scalar { implicit: [true,true], value: 'complex' }
+- !Scalar { implicit: [true,true], value: 'key' }
+- !MappingEnd
+- !MappingEnd
+- !MappingEnd
+- !DocumentEnd
+
+- !StreamEnd
diff --git a/tests/data/merge.data b/tests/data/merge.data
new file mode 100644
index 0000000..e455bbc
--- /dev/null
+++ b/tests/data/merge.data
@@ -0,0 +1 @@
+- <<
diff --git a/tests/data/merge.detect b/tests/data/merge.detect
new file mode 100644
index 0000000..1672d0d
--- /dev/null
+++ b/tests/data/merge.detect
@@ -0,0 +1 @@
+tag:yaml.org,2002:merge
diff --git a/tests/data/more-floats.code b/tests/data/more-floats.code
new file mode 100644
index 0000000..e3e444e
--- /dev/null
+++ b/tests/data/more-floats.code
@@ -0,0 +1 @@
+[0.0, +1.0, -1.0, +1e300000, -1e300000, 1e300000/1e300000, -(1e300000/1e300000)] # last two items are ind and qnan respectively.
diff --git a/tests/data/more-floats.data b/tests/data/more-floats.data
new file mode 100644
index 0000000..399eb17
--- /dev/null
+++ b/tests/data/more-floats.data
@@ -0,0 +1 @@
+[0.0, +1.0, -1.0, +.inf, -.inf, .nan, .nan]
diff --git a/tests/data/negative-float-bug.code b/tests/data/negative-float-bug.code
new file mode 100644
index 0000000..18e16e3
--- /dev/null
+++ b/tests/data/negative-float-bug.code
@@ -0,0 +1 @@
+-1.0
diff --git a/tests/data/negative-float-bug.data b/tests/data/negative-float-bug.data
new file mode 100644
index 0000000..18e16e3
--- /dev/null
+++ b/tests/data/negative-float-bug.data
@@ -0,0 +1 @@
+-1.0
diff --git a/tests/data/no-alias-anchor.emitter-error b/tests/data/no-alias-anchor.emitter-error
new file mode 100644
index 0000000..5ff065c
--- /dev/null
+++ b/tests/data/no-alias-anchor.emitter-error
@@ -0,0 +1,8 @@
+- !StreamStart
+- !DocumentStart
+- !SequenceStart
+- !Scalar { anchor: A, value: data }
+- !Alias { }
+- !SequenceEnd
+- !DocumentEnd
+- !StreamEnd
diff --git a/tests/data/no-alias-anchor.skip-ext b/tests/data/no-alias-anchor.skip-ext
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/tests/data/no-alias-anchor.skip-ext
diff --git a/tests/data/no-block-collection-end.loader-error b/tests/data/no-block-collection-end.loader-error
new file mode 100644
index 0000000..02d4d37
--- /dev/null
+++ b/tests/data/no-block-collection-end.loader-error
@@ -0,0 +1,3 @@
+- foo
+- bar
+baz: bar
diff --git a/tests/data/no-block-mapping-end-2.loader-error b/tests/data/no-block-mapping-end-2.loader-error
new file mode 100644
index 0000000..be63571
--- /dev/null
+++ b/tests/data/no-block-mapping-end-2.loader-error
@@ -0,0 +1,3 @@
+? foo
+: bar
+: baz
diff --git a/tests/data/no-block-mapping-end.loader-error b/tests/data/no-block-mapping-end.loader-error
new file mode 100644
index 0000000..1ea921c
--- /dev/null
+++ b/tests/data/no-block-mapping-end.loader-error
@@ -0,0 +1 @@
+foo: "bar" "baz"
diff --git a/tests/data/no-document-start.loader-error b/tests/data/no-document-start.loader-error
new file mode 100644
index 0000000..c725ec8
--- /dev/null
+++ b/tests/data/no-document-start.loader-error
@@ -0,0 +1,3 @@
+%YAML   1.1
+# no ---
+foo: bar
diff --git a/tests/data/no-flow-mapping-end.loader-error b/tests/data/no-flow-mapping-end.loader-error
new file mode 100644
index 0000000..8bd1403
--- /dev/null
+++ b/tests/data/no-flow-mapping-end.loader-error
@@ -0,0 +1 @@
+{ foo: bar ]
diff --git a/tests/data/no-flow-sequence-end.loader-error b/tests/data/no-flow-sequence-end.loader-error
new file mode 100644
index 0000000..750d973
--- /dev/null
+++ b/tests/data/no-flow-sequence-end.loader-error
@@ -0,0 +1 @@
+[foo, bar}
diff --git a/tests/data/no-node-1.loader-error b/tests/data/no-node-1.loader-error
new file mode 100644
index 0000000..07b1500
--- /dev/null
+++ b/tests/data/no-node-1.loader-error
@@ -0,0 +1 @@
+- !foo ]
diff --git a/tests/data/no-node-2.loader-error b/tests/data/no-node-2.loader-error
new file mode 100644
index 0000000..563e3b3
--- /dev/null
+++ b/tests/data/no-node-2.loader-error
@@ -0,0 +1 @@
+- [ !foo } ]
diff --git a/tests/data/no-tag.emitter-error b/tests/data/no-tag.emitter-error
new file mode 100644
index 0000000..384c62f
--- /dev/null
+++ b/tests/data/no-tag.emitter-error
@@ -0,0 +1,5 @@
+- !StreamStart
+- !DocumentStart
+- !Scalar { value: 'foo', implicit: [false,false] }
+- !DocumentEnd
+- !StreamEnd
diff --git a/tests/data/null.data b/tests/data/null.data
new file mode 100644
index 0000000..ad12528
--- /dev/null
+++ b/tests/data/null.data
@@ -0,0 +1,3 @@
+-
+- ~
+- null
diff --git a/tests/data/null.detect b/tests/data/null.detect
new file mode 100644
index 0000000..19110c7
--- /dev/null
+++ b/tests/data/null.detect
@@ -0,0 +1 @@
+tag:yaml.org,2002:null
diff --git a/tests/data/odd-utf16.stream-error b/tests/data/odd-utf16.stream-error
new file mode 100644
index 0000000..b59e434
--- /dev/null
+++ b/tests/data/odd-utf16.stream-error
Binary files differ
diff --git a/tests/data/recursive-anchor.former-loader-error b/tests/data/recursive-anchor.former-loader-error
new file mode 100644
index 0000000..661166c
--- /dev/null
+++ b/tests/data/recursive-anchor.former-loader-error
@@ -0,0 +1,4 @@
+- &foo [1
+    2,
+    3,
+    *foo]
diff --git a/tests/data/recursive-dict.recursive b/tests/data/recursive-dict.recursive
new file mode 100644
index 0000000..8f326f5
--- /dev/null
+++ b/tests/data/recursive-dict.recursive
@@ -0,0 +1,3 @@
+value = {}
+instance = AnInstance(value, value)
+value[instance] = instance
diff --git a/tests/data/recursive-list.recursive b/tests/data/recursive-list.recursive
new file mode 100644
index 0000000..27a4ae5
--- /dev/null
+++ b/tests/data/recursive-list.recursive
@@ -0,0 +1,2 @@
+value = []
+value.append(value)
diff --git a/tests/data/recursive-set.recursive b/tests/data/recursive-set.recursive
new file mode 100644
index 0000000..457c50d
--- /dev/null
+++ b/tests/data/recursive-set.recursive
@@ -0,0 +1,7 @@
+try:
+    set
+except NameError:
+    from sets import Set as set
+value = set()
+value.add(AnInstance(foo=value, bar=value))
+value.add(AnInstance(foo=value, bar=value))
diff --git a/tests/data/recursive-state.recursive b/tests/data/recursive-state.recursive
new file mode 100644
index 0000000..bffe61e
--- /dev/null
+++ b/tests/data/recursive-state.recursive
@@ -0,0 +1,2 @@
+value = []
+value.append(AnInstanceWithState(value, value))
diff --git a/tests/data/recursive-tuple.recursive b/tests/data/recursive-tuple.recursive
new file mode 100644
index 0000000..dc08d02
--- /dev/null
+++ b/tests/data/recursive-tuple.recursive
@@ -0,0 +1,3 @@
+value = ([], [])
+value[0].append(value)
+value[1].append(value[0])
diff --git a/tests/data/recursive.former-dumper-error b/tests/data/recursive.former-dumper-error
new file mode 100644
index 0000000..3c7cc2f
--- /dev/null
+++ b/tests/data/recursive.former-dumper-error
@@ -0,0 +1,3 @@
+data = []
+data.append(data)
+dump(data)
diff --git a/tests/data/remove-possible-simple-key-bug.loader-error b/tests/data/remove-possible-simple-key-bug.loader-error
new file mode 100644
index 0000000..fe1bc6c
--- /dev/null
+++ b/tests/data/remove-possible-simple-key-bug.loader-error
@@ -0,0 +1,3 @@
+foo: &A bar
+*A ]    # The ']' indicator triggers remove_possible_simple_key,
+        # which should raise an error.
diff --git a/tests/data/resolver.data b/tests/data/resolver.data
new file mode 100644
index 0000000..a296404
--- /dev/null
+++ b/tests/data/resolver.data
@@ -0,0 +1,30 @@
+---
+"this scalar should be selected"
+---
+key11: !foo
+    key12:
+        is: [selected]
+    key22:
+        key13: [not, selected]
+        key23: [not, selected]
+    key32:
+        key31: [not, selected]
+        key32: [not, selected]
+        key33: {not: selected}
+key21: !bar
+    - not selected
+    - selected
+    - not selected
+key31: !baz
+    key12:
+        key13:
+            key14: {selected}
+        key23:
+            key14: [not, selected]
+        key33:
+            key14: {selected}
+            key24: {not: selected}
+    key22:
+        -   key14: {selected}
+            key24: {not: selected}
+        -   key14: {selected}
diff --git a/tests/data/resolver.path b/tests/data/resolver.path
new file mode 100644
index 0000000..ec677d2
--- /dev/null
+++ b/tests/data/resolver.path
@@ -0,0 +1,30 @@
+--- !root/scalar
+"this scalar should be selected"
+--- !root
+key11: !foo
+    key12: !root/key11/key12/*
+        is: [selected]
+    key22:
+        key13: [not, selected]
+        key23: [not, selected]
+    key32:
+        key31: [not, selected]
+        key32: [not, selected]
+        key33: {not: selected}
+key21: !bar
+    - not selected
+    - !root/key21/1/* selected
+    - not selected
+key31: !baz
+    key12:
+        key13:
+            key14: !root/key31/*/*/key14/map {selected}
+        key23:
+            key14: [not, selected]
+        key33:
+            key14: !root/key31/*/*/key14/map {selected}
+            key24: {not: selected}
+    key22:
+        -   key14: !root/key31/*/*/key14/map {selected}
+            key24: {not: selected}
+        -   key14: !root/key31/*/*/key14/map {selected}
diff --git a/tests/data/run-parser-crash-bug.data b/tests/data/run-parser-crash-bug.data
new file mode 100644
index 0000000..fe01734
--- /dev/null
+++ b/tests/data/run-parser-crash-bug.data
@@ -0,0 +1,8 @@
+---
+- Harry Potter and the Prisoner of Azkaban
+- Harry Potter and the Goblet of Fire
+- Harry Potter and the Order of the Phoenix
+---
+- Memoirs Found in a Bathtub
+- Snow Crash
+- Ghost World
diff --git a/tests/data/scalars.events b/tests/data/scalars.events
new file mode 100644
index 0000000..32c40f4
--- /dev/null
+++ b/tests/data/scalars.events
@@ -0,0 +1,28 @@
+- !StreamStart
+
+- !DocumentStart
+- !MappingStart
+- !Scalar { implicit: [true,true], value: 'empty scalar' }
+- !Scalar { implicit: [true,false], value: '' }
+- !Scalar { implicit: [true,true], value: 'implicit scalar' }
+- !Scalar { implicit: [true,true], value: 'data' }
+- !Scalar { implicit: [true,true], value: 'quoted scalar' }
+- !Scalar { value: 'data', style: '"' }
+- !Scalar { implicit: [true,true], value: 'block scalar' }
+- !Scalar { value: 'data', style: '|' }
+- !Scalar { implicit: [true,true], value: 'empty scalar with tag' }
+- !Scalar { implicit: [false,false], tag: '!mytag', value: '' }
+- !Scalar { implicit: [true,true], value: 'implicit scalar with tag' }
+- !Scalar { implicit: [false,false], tag: '!mytag', value: 'data' }
+- !Scalar { implicit: [true,true], value: 'quoted scalar with tag' }
+- !Scalar { value: 'data', style: '"', tag: '!mytag', implicit: [false,false] }
+- !Scalar { implicit: [true,true], value: 'block scalar with tag' }
+- !Scalar { value: 'data', style: '|', tag: '!mytag', implicit: [false,false] }
+- !Scalar { implicit: [true,true], value: 'single character' }
+- !Scalar { value: 'a', implicit: [true,true] }
+- !Scalar { implicit: [true,true], value: 'single digit' }
+- !Scalar { value: '1', implicit: [true,false] }
+- !MappingEnd
+- !DocumentEnd
+
+- !StreamEnd
diff --git a/tests/data/scan-document-end-bug.canonical b/tests/data/scan-document-end-bug.canonical
new file mode 100644
index 0000000..4a0e8a8
--- /dev/null
+++ b/tests/data/scan-document-end-bug.canonical
@@ -0,0 +1,3 @@
+%YAML 1.1
+---
+!!null ""
diff --git a/tests/data/scan-document-end-bug.data b/tests/data/scan-document-end-bug.data
new file mode 100644
index 0000000..3c70543
--- /dev/null
+++ b/tests/data/scan-document-end-bug.data
@@ -0,0 +1,3 @@
+# Ticket #4
+---
+...
\ No newline at end of file
diff --git a/tests/data/scan-line-break-bug.canonical b/tests/data/scan-line-break-bug.canonical
new file mode 100644
index 0000000..79f08b7
--- /dev/null
+++ b/tests/data/scan-line-break-bug.canonical
@@ -0,0 +1,3 @@
+%YAML 1.1
+---
+!!map { ? !!str "foo" : !!str "bar baz" }
diff --git a/tests/data/scan-line-break-bug.data b/tests/data/scan-line-break-bug.data
new file mode 100644
index 0000000..c974fab
--- /dev/null
+++ b/tests/data/scan-line-break-bug.data
@@ -0,0 +1,3 @@
+foo:

+    bar

+    baz

diff --git a/tests/data/sequences.events b/tests/data/sequences.events
new file mode 100644
index 0000000..692a329
--- /dev/null
+++ b/tests/data/sequences.events
@@ -0,0 +1,81 @@
+- !StreamStart
+
+- !DocumentStart
+- !SequenceStart
+- !SequenceEnd
+- !DocumentEnd
+
+- !DocumentStart
+- !SequenceStart { tag: '!mytag', implicit: false }
+- !SequenceEnd
+- !DocumentEnd
+
+- !DocumentStart
+- !SequenceStart
+- !SequenceStart
+- !SequenceEnd
+- !SequenceStart { tag: '!mytag', implicit: false }
+- !SequenceEnd
+- !SequenceStart
+- !Scalar
+- !Scalar { value: 'data' }
+- !Scalar { tag: '!mytag', implicit: [false,false], value: 'data' }
+- !SequenceEnd
+- !SequenceStart
+- !SequenceStart
+- !SequenceStart
+- !Scalar
+- !SequenceEnd
+- !SequenceEnd
+- !SequenceEnd
+- !SequenceStart
+- !SequenceStart { tag: '!mytag', implicit: false }
+- !SequenceStart
+- !Scalar { value: 'data' }
+- !SequenceEnd
+- !SequenceEnd
+- !SequenceEnd
+- !SequenceEnd
+- !DocumentEnd
+
+- !DocumentStart
+- !SequenceStart
+- !MappingStart
+- !Scalar { value: 'key1' }
+- !SequenceStart
+- !Scalar { value: 'data1' }
+- !Scalar { value: 'data2' }
+- !SequenceEnd
+- !Scalar { value: 'key2' }
+- !SequenceStart { tag: '!mytag1', implicit: false }
+- !Scalar { value: 'data3' }
+- !SequenceStart
+- !Scalar { value: 'data4' }
+- !Scalar { value: 'data5' }
+- !SequenceEnd
+- !SequenceStart { tag: '!mytag2', implicit: false }
+- !Scalar { value: 'data6' }
+- !Scalar { value: 'data7' }
+- !SequenceEnd
+- !SequenceEnd
+- !MappingEnd
+- !SequenceEnd
+- !DocumentEnd
+
+- !DocumentStart
+- !SequenceStart
+- !SequenceStart { flow_style: true }
+- !SequenceStart
+- !SequenceEnd
+- !Scalar
+- !Scalar { value: 'data' }
+- !Scalar { tag: '!mytag', implicit: [false,false], value: 'data' }
+- !SequenceStart { tag: '!mytag', implicit: false }
+- !Scalar { value: 'data' }
+- !Scalar { value: 'data' }
+- !SequenceEnd
+- !SequenceEnd
+- !SequenceEnd
+- !DocumentEnd
+
+- !StreamEnd
diff --git a/tests/data/serializer-is-already-opened.dumper-error b/tests/data/serializer-is-already-opened.dumper-error
new file mode 100644
index 0000000..9a23525
--- /dev/null
+++ b/tests/data/serializer-is-already-opened.dumper-error
@@ -0,0 +1,3 @@
+dumper = yaml.Dumper(StringIO())
+dumper.open()
+dumper.open()
diff --git a/tests/data/serializer-is-closed-1.dumper-error b/tests/data/serializer-is-closed-1.dumper-error
new file mode 100644
index 0000000..8e7e600
--- /dev/null
+++ b/tests/data/serializer-is-closed-1.dumper-error
@@ -0,0 +1,4 @@
+dumper = yaml.Dumper(StringIO())
+dumper.open()
+dumper.close()
+dumper.open()
diff --git a/tests/data/serializer-is-closed-2.dumper-error b/tests/data/serializer-is-closed-2.dumper-error
new file mode 100644
index 0000000..89aef7e
--- /dev/null
+++ b/tests/data/serializer-is-closed-2.dumper-error
@@ -0,0 +1,4 @@
+dumper = yaml.Dumper(StringIO())
+dumper.open()
+dumper.close()
+dumper.serialize(yaml.ScalarNode(tag='!foo', value='bar'))
diff --git a/tests/data/serializer-is-not-opened-1.dumper-error b/tests/data/serializer-is-not-opened-1.dumper-error
new file mode 100644
index 0000000..8f22e73
--- /dev/null
+++ b/tests/data/serializer-is-not-opened-1.dumper-error
@@ -0,0 +1,2 @@
+dumper = yaml.Dumper(StringIO())
+dumper.close()
diff --git a/tests/data/serializer-is-not-opened-2.dumper-error b/tests/data/serializer-is-not-opened-2.dumper-error
new file mode 100644
index 0000000..ebd9df1
--- /dev/null
+++ b/tests/data/serializer-is-not-opened-2.dumper-error
@@ -0,0 +1,2 @@
+dumper = yaml.Dumper(StringIO())
+dumper.serialize(yaml.ScalarNode(tag='!foo', value='bar'))
diff --git a/tests/data/single-dot-is-not-float-bug.code b/tests/data/single-dot-is-not-float-bug.code
new file mode 100644
index 0000000..dcd0c2f
--- /dev/null
+++ b/tests/data/single-dot-is-not-float-bug.code
@@ -0,0 +1 @@
+'.'
diff --git a/tests/data/single-dot-is-not-float-bug.data b/tests/data/single-dot-is-not-float-bug.data
new file mode 100644
index 0000000..9c558e3
--- /dev/null
+++ b/tests/data/single-dot-is-not-float-bug.data
@@ -0,0 +1 @@
+.
diff --git a/tests/data/sloppy-indentation.canonical b/tests/data/sloppy-indentation.canonical
new file mode 100644
index 0000000..438bc04
--- /dev/null
+++ b/tests/data/sloppy-indentation.canonical
@@ -0,0 +1,18 @@
+%YAML 1.1
+---
+!!map { 
+    ? !!str "in the block context"
+    : !!map {
+        ? !!str "indentation should be kept"
+        : !!map {
+            ? !!str "but in the flow context"
+            : !!seq [ !!str "it may be violated" ]
+        }
+    }
+}
+--- !!str
+"the parser does not require scalars to be indented with at least one space"
+--- !!str
+"the parser does not require scalars to be indented with at least one space"
+--- !!map
+{ ? !!str "foo": { ? !!str "bar" : !!str "quoted scalars may not adhere indentation" } }
diff --git a/tests/data/sloppy-indentation.data b/tests/data/sloppy-indentation.data
new file mode 100644
index 0000000..2eb4f5a
--- /dev/null
+++ b/tests/data/sloppy-indentation.data
@@ -0,0 +1,17 @@
+---
+in the block context:
+    indentation should be kept: { 
+    but in the flow context: [
+it may be violated]
+}
+---
+the parser does not require scalars
+to be indented with at least one space
+...
+---
+"the parser does not require scalars
+to be indented with at least one space"
+---
+foo:
+    bar: 'quoted scalars
+may not adhere indentation'
diff --git a/tests/data/spec-02-01.data b/tests/data/spec-02-01.data
new file mode 100644
index 0000000..d12e671
--- /dev/null
+++ b/tests/data/spec-02-01.data
@@ -0,0 +1,3 @@
+- Mark McGwire
+- Sammy Sosa
+- Ken Griffey
diff --git a/tests/data/spec-02-01.structure b/tests/data/spec-02-01.structure
new file mode 100644
index 0000000..f532f4a
--- /dev/null
+++ b/tests/data/spec-02-01.structure
@@ -0,0 +1 @@
+[True, True, True]
diff --git a/tests/data/spec-02-01.tokens b/tests/data/spec-02-01.tokens
new file mode 100644
index 0000000..ce44cac
--- /dev/null
+++ b/tests/data/spec-02-01.tokens
@@ -0,0 +1 @@
+[[ , _ , _ , _ ]}
diff --git a/tests/data/spec-02-02.data b/tests/data/spec-02-02.data
new file mode 100644
index 0000000..7b7ec94
--- /dev/null
+++ b/tests/data/spec-02-02.data
@@ -0,0 +1,3 @@
+hr:  65    # Home runs
+avg: 0.278 # Batting average
+rbi: 147   # Runs Batted In
diff --git a/tests/data/spec-02-02.structure b/tests/data/spec-02-02.structure
new file mode 100644
index 0000000..aba1ced
--- /dev/null
+++ b/tests/data/spec-02-02.structure
@@ -0,0 +1 @@
+[(True, True), (True, True), (True, True)]
diff --git a/tests/data/spec-02-02.tokens b/tests/data/spec-02-02.tokens
new file mode 100644
index 0000000..e4e381b
--- /dev/null
+++ b/tests/data/spec-02-02.tokens
@@ -0,0 +1,5 @@
+{{
+? _ : _
+? _ : _
+? _ : _
+]}
diff --git a/tests/data/spec-02-03.data b/tests/data/spec-02-03.data
new file mode 100644
index 0000000..656d628
--- /dev/null
+++ b/tests/data/spec-02-03.data
@@ -0,0 +1,8 @@
+american:
+  - Boston Red Sox
+  - Detroit Tigers
+  - New York Yankees
+national:
+  - New York Mets
+  - Chicago Cubs
+  - Atlanta Braves
diff --git a/tests/data/spec-02-03.structure b/tests/data/spec-02-03.structure
new file mode 100644
index 0000000..25de5d2
--- /dev/null
+++ b/tests/data/spec-02-03.structure
@@ -0,0 +1 @@
+[(True, [True, True, True]), (True, [True, True, True])]
diff --git a/tests/data/spec-02-03.tokens b/tests/data/spec-02-03.tokens
new file mode 100644
index 0000000..89815f2
--- /dev/null
+++ b/tests/data/spec-02-03.tokens
@@ -0,0 +1,4 @@
+{{
+? _ : [[ , _ , _ , _ ]}
+? _ : [[ , _ , _ , _ ]}
+]}
diff --git a/tests/data/spec-02-04.data b/tests/data/spec-02-04.data
new file mode 100644
index 0000000..430f6b3
--- /dev/null
+++ b/tests/data/spec-02-04.data
@@ -0,0 +1,8 @@
+-
+  name: Mark McGwire
+  hr:   65
+  avg:  0.278
+-
+  name: Sammy Sosa
+  hr:   63
+  avg:  0.288
diff --git a/tests/data/spec-02-04.structure b/tests/data/spec-02-04.structure
new file mode 100644
index 0000000..e7b526c
--- /dev/null
+++ b/tests/data/spec-02-04.structure
@@ -0,0 +1,4 @@
+[
+    [(True, True), (True, True), (True, True)],
+    [(True, True), (True, True), (True, True)],
+]
diff --git a/tests/data/spec-02-04.tokens b/tests/data/spec-02-04.tokens
new file mode 100644
index 0000000..9cb9815
--- /dev/null
+++ b/tests/data/spec-02-04.tokens
@@ -0,0 +1,4 @@
+[[
+, {{ ? _ : _ ? _ : _ ? _ : _ ]}
+, {{ ? _ : _ ? _ : _ ? _ : _ ]}
+]}
diff --git a/tests/data/spec-02-05.data b/tests/data/spec-02-05.data
new file mode 100644
index 0000000..cdd7770
--- /dev/null
+++ b/tests/data/spec-02-05.data
@@ -0,0 +1,3 @@
+- [name        , hr, avg  ]
+- [Mark McGwire, 65, 0.278]
+- [Sammy Sosa  , 63, 0.288]
diff --git a/tests/data/spec-02-05.structure b/tests/data/spec-02-05.structure
new file mode 100644
index 0000000..e06b75a
--- /dev/null
+++ b/tests/data/spec-02-05.structure
@@ -0,0 +1,5 @@
+[
+    [True, True, True],
+    [True, True, True],
+    [True, True, True],
+]
diff --git a/tests/data/spec-02-05.tokens b/tests/data/spec-02-05.tokens
new file mode 100644
index 0000000..3f6f1ab
--- /dev/null
+++ b/tests/data/spec-02-05.tokens
@@ -0,0 +1,5 @@
+[[
+, [ _ , _ , _ ]
+, [ _ , _ , _ ]
+, [ _ , _ , _ ]
+]}
diff --git a/tests/data/spec-02-06.data b/tests/data/spec-02-06.data
new file mode 100644
index 0000000..7a957b2
--- /dev/null
+++ b/tests/data/spec-02-06.data
@@ -0,0 +1,5 @@
+Mark McGwire: {hr: 65, avg: 0.278}
+Sammy Sosa: {
+    hr: 63,
+    avg: 0.288
+  }
diff --git a/tests/data/spec-02-06.structure b/tests/data/spec-02-06.structure
new file mode 100644
index 0000000..3ef0f4b
--- /dev/null
+++ b/tests/data/spec-02-06.structure
@@ -0,0 +1,4 @@
+[
+    (True, [(True, True), (True, True)]),
+    (True, [(True, True), (True, True)]),
+]
diff --git a/tests/data/spec-02-06.tokens b/tests/data/spec-02-06.tokens
new file mode 100644
index 0000000..a1a5eef
--- /dev/null
+++ b/tests/data/spec-02-06.tokens
@@ -0,0 +1,4 @@
+{{
+? _ : { ? _ : _ , ? _ : _ }
+? _ : { ? _ : _ , ? _ : _ }
+]}
diff --git a/tests/data/spec-02-07.data b/tests/data/spec-02-07.data
new file mode 100644
index 0000000..bc711d5
--- /dev/null
+++ b/tests/data/spec-02-07.data
@@ -0,0 +1,10 @@
+# Ranking of 1998 home runs
+---
+- Mark McGwire
+- Sammy Sosa
+- Ken Griffey
+
+# Team ranking
+---
+- Chicago Cubs
+- St Louis Cardinals
diff --git a/tests/data/spec-02-07.structure b/tests/data/spec-02-07.structure
new file mode 100644
index 0000000..c5d72a3
--- /dev/null
+++ b/tests/data/spec-02-07.structure
@@ -0,0 +1,4 @@
+[
+[True, True, True],
+[True, True],
+]
diff --git a/tests/data/spec-02-07.tokens b/tests/data/spec-02-07.tokens
new file mode 100644
index 0000000..ed48883
--- /dev/null
+++ b/tests/data/spec-02-07.tokens
@@ -0,0 +1,12 @@
+---
+[[
+, _
+, _
+, _
+]}
+
+---
+[[
+, _
+, _
+]}
diff --git a/tests/data/spec-02-08.data b/tests/data/spec-02-08.data
new file mode 100644
index 0000000..05e102d
--- /dev/null
+++ b/tests/data/spec-02-08.data
@@ -0,0 +1,10 @@
+---
+time: 20:03:20
+player: Sammy Sosa
+action: strike (miss)
+...
+---
+time: 20:03:47
+player: Sammy Sosa
+action: grand slam
+...
diff --git a/tests/data/spec-02-08.structure b/tests/data/spec-02-08.structure
new file mode 100644
index 0000000..24cff73
--- /dev/null
+++ b/tests/data/spec-02-08.structure
@@ -0,0 +1,4 @@
+[
+[(True, True), (True, True), (True, True)],
+[(True, True), (True, True), (True, True)],
+]
diff --git a/tests/data/spec-02-08.tokens b/tests/data/spec-02-08.tokens
new file mode 100644
index 0000000..7d2c03d
--- /dev/null
+++ b/tests/data/spec-02-08.tokens
@@ -0,0 +1,15 @@
+---
+{{
+? _ : _
+? _ : _
+? _ : _
+]}
+...
+
+---
+{{
+? _ : _
+? _ : _
+? _ : _
+]}
+...
diff --git a/tests/data/spec-02-09.data b/tests/data/spec-02-09.data
new file mode 100644
index 0000000..e264180
--- /dev/null
+++ b/tests/data/spec-02-09.data
@@ -0,0 +1,8 @@
+---
+hr: # 1998 hr ranking
+  - Mark McGwire
+  - Sammy Sosa
+rbi:
+  # 1998 rbi ranking
+  - Sammy Sosa
+  - Ken Griffey
diff --git a/tests/data/spec-02-09.structure b/tests/data/spec-02-09.structure
new file mode 100644
index 0000000..b4c9914
--- /dev/null
+++ b/tests/data/spec-02-09.structure
@@ -0,0 +1 @@
+[(True, [True, True]), (True, [True, True])]
diff --git a/tests/data/spec-02-09.tokens b/tests/data/spec-02-09.tokens
new file mode 100644
index 0000000..b2ec10e
--- /dev/null
+++ b/tests/data/spec-02-09.tokens
@@ -0,0 +1,5 @@
+---
+{{
+? _ : [[ , _ , _ ]}
+? _ : [[ , _ , _ ]}
+]}
diff --git a/tests/data/spec-02-10.data b/tests/data/spec-02-10.data
new file mode 100644
index 0000000..61808f6
--- /dev/null
+++ b/tests/data/spec-02-10.data
@@ -0,0 +1,8 @@
+---
+hr:
+  - Mark McGwire
+  # Following node labeled SS
+  - &SS Sammy Sosa
+rbi:
+  - *SS # Subsequent occurrence
+  - Ken Griffey
diff --git a/tests/data/spec-02-10.structure b/tests/data/spec-02-10.structure
new file mode 100644
index 0000000..ff8f4c3
--- /dev/null
+++ b/tests/data/spec-02-10.structure
@@ -0,0 +1 @@
+[(True, [True, True]), (True, ['*', True])]
diff --git a/tests/data/spec-02-10.tokens b/tests/data/spec-02-10.tokens
new file mode 100644
index 0000000..26caa2b
--- /dev/null
+++ b/tests/data/spec-02-10.tokens
@@ -0,0 +1,5 @@
+---
+{{
+? _ : [[ , _ , & _ ]}
+? _ : [[ , * , _ ]}
+]}
diff --git a/tests/data/spec-02-11.data b/tests/data/spec-02-11.data
new file mode 100644
index 0000000..9123ce2
--- /dev/null
+++ b/tests/data/spec-02-11.data
@@ -0,0 +1,9 @@
+? - Detroit Tigers
+  - Chicago cubs
+:
+  - 2001-07-23
+
+? [ New York Yankees,
+    Atlanta Braves ]
+: [ 2001-07-02, 2001-08-12,
+    2001-08-14 ]
diff --git a/tests/data/spec-02-11.structure b/tests/data/spec-02-11.structure
new file mode 100644
index 0000000..3d8f1ff
--- /dev/null
+++ b/tests/data/spec-02-11.structure
@@ -0,0 +1,4 @@
+[
+([True, True], [True]),
+([True, True], [True, True, True]),
+]
diff --git a/tests/data/spec-02-11.tokens b/tests/data/spec-02-11.tokens
new file mode 100644
index 0000000..fe24203
--- /dev/null
+++ b/tests/data/spec-02-11.tokens
@@ -0,0 +1,6 @@
+{{
+? [[ , _ , _ ]}
+: [[ , _ ]}
+? [ _ , _ ]
+: [ _ , _ , _ ]
+]}
diff --git a/tests/data/spec-02-12.data b/tests/data/spec-02-12.data
new file mode 100644
index 0000000..1fc33f9
--- /dev/null
+++ b/tests/data/spec-02-12.data
@@ -0,0 +1,8 @@
+---
+# products purchased
+- item    : Super Hoop
+  quantity: 1
+- item    : Basketball
+  quantity: 4
+- item    : Big Shoes
+  quantity: 1
diff --git a/tests/data/spec-02-12.structure b/tests/data/spec-02-12.structure
new file mode 100644
index 0000000..e9c5359
--- /dev/null
+++ b/tests/data/spec-02-12.structure
@@ -0,0 +1,5 @@
+[
+[(True, True), (True, True)],
+[(True, True), (True, True)],
+[(True, True), (True, True)],
+]
diff --git a/tests/data/spec-02-12.tokens b/tests/data/spec-02-12.tokens
new file mode 100644
index 0000000..ea21e50
--- /dev/null
+++ b/tests/data/spec-02-12.tokens
@@ -0,0 +1,6 @@
+---
+[[
+, {{ ? _ : _ ? _ : _ ]}
+, {{ ? _ : _ ? _ : _ ]}
+, {{ ? _ : _ ? _ : _ ]}
+]}
diff --git a/tests/data/spec-02-13.data b/tests/data/spec-02-13.data
new file mode 100644
index 0000000..13fb656
--- /dev/null
+++ b/tests/data/spec-02-13.data
@@ -0,0 +1,4 @@
+# ASCII Art
+--- |
+  \//||\/||
+  // ||  ||__
diff --git a/tests/data/spec-02-13.structure b/tests/data/spec-02-13.structure
new file mode 100644
index 0000000..0ca9514
--- /dev/null
+++ b/tests/data/spec-02-13.structure
@@ -0,0 +1 @@
+True
diff --git a/tests/data/spec-02-13.tokens b/tests/data/spec-02-13.tokens
new file mode 100644
index 0000000..7456c05
--- /dev/null
+++ b/tests/data/spec-02-13.tokens
@@ -0,0 +1 @@
+--- _
diff --git a/tests/data/spec-02-14.data b/tests/data/spec-02-14.data
new file mode 100644
index 0000000..59943de
--- /dev/null
+++ b/tests/data/spec-02-14.data
@@ -0,0 +1,4 @@
+---
+  Mark McGwire's
+  year was crippled
+  by a knee injury.
diff --git a/tests/data/spec-02-14.structure b/tests/data/spec-02-14.structure
new file mode 100644
index 0000000..0ca9514
--- /dev/null
+++ b/tests/data/spec-02-14.structure
@@ -0,0 +1 @@
+True
diff --git a/tests/data/spec-02-14.tokens b/tests/data/spec-02-14.tokens
new file mode 100644
index 0000000..7456c05
--- /dev/null
+++ b/tests/data/spec-02-14.tokens
@@ -0,0 +1 @@
+--- _
diff --git a/tests/data/spec-02-15.data b/tests/data/spec-02-15.data
new file mode 100644
index 0000000..80b89a6
--- /dev/null
+++ b/tests/data/spec-02-15.data
@@ -0,0 +1,8 @@
+>
+ Sammy Sosa completed another
+ fine season with great stats.
+
+   63 Home Runs
+   0.288 Batting Average
+
+ What a year!
diff --git a/tests/data/spec-02-15.structure b/tests/data/spec-02-15.structure
new file mode 100644
index 0000000..0ca9514
--- /dev/null
+++ b/tests/data/spec-02-15.structure
@@ -0,0 +1 @@
+True
diff --git a/tests/data/spec-02-15.tokens b/tests/data/spec-02-15.tokens
new file mode 100644
index 0000000..31354ec
--- /dev/null
+++ b/tests/data/spec-02-15.tokens
@@ -0,0 +1 @@
+_
diff --git a/tests/data/spec-02-16.data b/tests/data/spec-02-16.data
new file mode 100644
index 0000000..9f66d88
--- /dev/null
+++ b/tests/data/spec-02-16.data
@@ -0,0 +1,7 @@
+name: Mark McGwire
+accomplishment: >
+  Mark set a major league
+  home run record in 1998.
+stats: |
+  65 Home Runs
+  0.278 Batting Average
diff --git a/tests/data/spec-02-16.structure b/tests/data/spec-02-16.structure
new file mode 100644
index 0000000..aba1ced
--- /dev/null
+++ b/tests/data/spec-02-16.structure
@@ -0,0 +1 @@
+[(True, True), (True, True), (True, True)]
diff --git a/tests/data/spec-02-16.tokens b/tests/data/spec-02-16.tokens
new file mode 100644
index 0000000..e4e381b
--- /dev/null
+++ b/tests/data/spec-02-16.tokens
@@ -0,0 +1,5 @@
+{{
+? _ : _
+? _ : _
+? _ : _
+]}
diff --git a/tests/data/spec-02-17.data b/tests/data/spec-02-17.data
new file mode 100644
index 0000000..b2870c5
--- /dev/null
+++ b/tests/data/spec-02-17.data
@@ -0,0 +1,7 @@
+unicode: "Sosa did fine.\u263A"
+control: "\b1998\t1999\t2000\n"
+hexesc:  "\x13\x10 is \r\n"
+
+single: '"Howdy!" he cried.'
+quoted: ' # not a ''comment''.'
+tie-fighter: '|\-*-/|'
diff --git a/tests/data/spec-02-17.structure b/tests/data/spec-02-17.structure
new file mode 100644
index 0000000..933646d
--- /dev/null
+++ b/tests/data/spec-02-17.structure
@@ -0,0 +1 @@
+[(True, True), (True, True), (True, True), (True, True), (True, True), (True, True)]
diff --git a/tests/data/spec-02-17.tokens b/tests/data/spec-02-17.tokens
new file mode 100644
index 0000000..db65540
--- /dev/null
+++ b/tests/data/spec-02-17.tokens
@@ -0,0 +1,8 @@
+{{
+? _ : _
+? _ : _
+? _ : _
+? _ : _
+? _ : _
+? _ : _
+]}
diff --git a/tests/data/spec-02-18.data b/tests/data/spec-02-18.data
new file mode 100644
index 0000000..e0a8bfa
--- /dev/null
+++ b/tests/data/spec-02-18.data
@@ -0,0 +1,6 @@
+plain:
+  This unquoted scalar
+  spans many lines.
+
+quoted: "So does this
+  quoted scalar.\n"
diff --git a/tests/data/spec-02-18.structure b/tests/data/spec-02-18.structure
new file mode 100644
index 0000000..0ca4991
--- /dev/null
+++ b/tests/data/spec-02-18.structure
@@ -0,0 +1 @@
+[(True, True), (True, True)]
diff --git a/tests/data/spec-02-18.tokens b/tests/data/spec-02-18.tokens
new file mode 100644
index 0000000..83b31dc
--- /dev/null
+++ b/tests/data/spec-02-18.tokens
@@ -0,0 +1,4 @@
+{{
+? _ : _
+? _ : _
+]}
diff --git a/tests/data/spec-02-19.data b/tests/data/spec-02-19.data
new file mode 100644
index 0000000..bf69de6
--- /dev/null
+++ b/tests/data/spec-02-19.data
@@ -0,0 +1,5 @@
+canonical: 12345
+decimal: +12,345
+sexagesimal: 3:25:45
+octal: 014
+hexadecimal: 0xC
diff --git a/tests/data/spec-02-19.structure b/tests/data/spec-02-19.structure
new file mode 100644
index 0000000..48ca99d
--- /dev/null
+++ b/tests/data/spec-02-19.structure
@@ -0,0 +1 @@
+[(True, True), (True, True), (True, True), (True, True), (True, True)]
diff --git a/tests/data/spec-02-19.tokens b/tests/data/spec-02-19.tokens
new file mode 100644
index 0000000..5bda68f
--- /dev/null
+++ b/tests/data/spec-02-19.tokens
@@ -0,0 +1,7 @@
+{{
+? _ : _
+? _ : _
+? _ : _
+? _ : _
+? _ : _
+]}
diff --git a/tests/data/spec-02-20.data b/tests/data/spec-02-20.data
new file mode 100644
index 0000000..1d4897f
--- /dev/null
+++ b/tests/data/spec-02-20.data
@@ -0,0 +1,6 @@
+canonical: 1.23015e+3
+exponential: 12.3015e+02
+sexagesimal: 20:30.15
+fixed: 1,230.15
+negative infinity: -.inf
+not a number: .NaN
diff --git a/tests/data/spec-02-20.structure b/tests/data/spec-02-20.structure
new file mode 100644
index 0000000..933646d
--- /dev/null
+++ b/tests/data/spec-02-20.structure
@@ -0,0 +1 @@
+[(True, True), (True, True), (True, True), (True, True), (True, True), (True, True)]
diff --git a/tests/data/spec-02-20.tokens b/tests/data/spec-02-20.tokens
new file mode 100644
index 0000000..db65540
--- /dev/null
+++ b/tests/data/spec-02-20.tokens
@@ -0,0 +1,8 @@
+{{
+? _ : _
+? _ : _
+? _ : _
+? _ : _
+? _ : _
+? _ : _
+]}
diff --git a/tests/data/spec-02-21.data b/tests/data/spec-02-21.data
new file mode 100644
index 0000000..dec6a56
--- /dev/null
+++ b/tests/data/spec-02-21.data
@@ -0,0 +1,4 @@
+null: ~
+true: y
+false: n
+string: '12345'
diff --git a/tests/data/spec-02-21.structure b/tests/data/spec-02-21.structure
new file mode 100644
index 0000000..021635f
--- /dev/null
+++ b/tests/data/spec-02-21.structure
@@ -0,0 +1 @@
+[(True, True), (True, True), (True, True), (True, True)]
diff --git a/tests/data/spec-02-21.tokens b/tests/data/spec-02-21.tokens
new file mode 100644
index 0000000..aeccbaf
--- /dev/null
+++ b/tests/data/spec-02-21.tokens
@@ -0,0 +1,6 @@
+{{
+? _ : _
+? _ : _
+? _ : _
+? _ : _
+]}
diff --git a/tests/data/spec-02-22.data b/tests/data/spec-02-22.data
new file mode 100644
index 0000000..aaac185
--- /dev/null
+++ b/tests/data/spec-02-22.data
@@ -0,0 +1,4 @@
+canonical: 2001-12-15T02:59:43.1Z
+iso8601: 2001-12-14t21:59:43.10-05:00
+spaced: 2001-12-14 21:59:43.10 -5
+date: 2002-12-14
diff --git a/tests/data/spec-02-22.structure b/tests/data/spec-02-22.structure
new file mode 100644
index 0000000..021635f
--- /dev/null
+++ b/tests/data/spec-02-22.structure
@@ -0,0 +1 @@
+[(True, True), (True, True), (True, True), (True, True)]
diff --git a/tests/data/spec-02-22.tokens b/tests/data/spec-02-22.tokens
new file mode 100644
index 0000000..aeccbaf
--- /dev/null
+++ b/tests/data/spec-02-22.tokens
@@ -0,0 +1,6 @@
+{{
+? _ : _
+? _ : _
+? _ : _
+? _ : _
+]}
diff --git a/tests/data/spec-02-23.data b/tests/data/spec-02-23.data
new file mode 100644
index 0000000..5dbd992
--- /dev/null
+++ b/tests/data/spec-02-23.data
@@ -0,0 +1,13 @@
+---
+not-date: !!str 2002-04-28
+
+picture: !!binary |
+ R0lGODlhDAAMAIQAAP//9/X
+ 17unp5WZmZgAAAOfn515eXv
+ Pz7Y6OjuDg4J+fn5OTk6enp
+ 56enmleECcgggoBADs=
+
+application specific tag: !something |
+ The semantics of the tag
+ above may be different for
+ different documents.
diff --git a/tests/data/spec-02-23.structure b/tests/data/spec-02-23.structure
new file mode 100644
index 0000000..aba1ced
--- /dev/null
+++ b/tests/data/spec-02-23.structure
@@ -0,0 +1 @@
+[(True, True), (True, True), (True, True)]
diff --git a/tests/data/spec-02-23.tokens b/tests/data/spec-02-23.tokens
new file mode 100644
index 0000000..9ac54aa
--- /dev/null
+++ b/tests/data/spec-02-23.tokens
@@ -0,0 +1,6 @@
+---
+{{
+? _ : ! _
+? _ : ! _
+? _ : ! _
+]}
diff --git a/tests/data/spec-02-24.data b/tests/data/spec-02-24.data
new file mode 100644
index 0000000..1180757
--- /dev/null
+++ b/tests/data/spec-02-24.data
@@ -0,0 +1,14 @@
+%TAG ! tag:clarkevans.com,2002:
+--- !shape
+  # Use the ! handle for presenting
+  # tag:clarkevans.com,2002:circle
+- !circle
+  center: &ORIGIN {x: 73, y: 129}
+  radius: 7
+- !line
+  start: *ORIGIN
+  finish: { x: 89, y: 102 }
+- !label
+  start: *ORIGIN
+  color: 0xFFEEBB
+  text: Pretty vector drawing.
diff --git a/tests/data/spec-02-24.structure b/tests/data/spec-02-24.structure
new file mode 100644
index 0000000..a800729
--- /dev/null
+++ b/tests/data/spec-02-24.structure
@@ -0,0 +1,5 @@
+[
+[(True, [(True, True), (True, True)]), (True, True)],
+[(True, '*'), (True, [(True, True), (True, True)])],
+[(True, '*'), (True, True), (True, True)],
+]
diff --git a/tests/data/spec-02-24.tokens b/tests/data/spec-02-24.tokens
new file mode 100644
index 0000000..039c385
--- /dev/null
+++ b/tests/data/spec-02-24.tokens
@@ -0,0 +1,20 @@
+%
+--- !
+[[
+, !
+    {{
+    ? _ : & { ? _ : _ , ? _ : _ }
+    ? _ : _
+    ]}
+, !
+    {{
+    ? _ : *
+    ? _ : { ? _ : _ , ? _ : _ }
+    ]}
+, !
+    {{
+    ? _ : *
+    ? _ : _
+    ? _ : _
+    ]}
+]}
diff --git a/tests/data/spec-02-25.data b/tests/data/spec-02-25.data
new file mode 100644
index 0000000..769ac31
--- /dev/null
+++ b/tests/data/spec-02-25.data
@@ -0,0 +1,7 @@
+# sets are represented as a
+# mapping where each key is
+# associated with the empty string
+--- !!set
+? Mark McGwire
+? Sammy Sosa
+? Ken Griff
diff --git a/tests/data/spec-02-25.structure b/tests/data/spec-02-25.structure
new file mode 100644
index 0000000..0b40e61
--- /dev/null
+++ b/tests/data/spec-02-25.structure
@@ -0,0 +1 @@
+[(True, None), (True, None), (True, None)]
diff --git a/tests/data/spec-02-25.tokens b/tests/data/spec-02-25.tokens
new file mode 100644
index 0000000..b700236
--- /dev/null
+++ b/tests/data/spec-02-25.tokens
@@ -0,0 +1,6 @@
+--- !
+{{
+? _
+? _
+? _
+]}
diff --git a/tests/data/spec-02-26.data b/tests/data/spec-02-26.data
new file mode 100644
index 0000000..3143763
--- /dev/null
+++ b/tests/data/spec-02-26.data
@@ -0,0 +1,7 @@
+# ordered maps are represented as
+# a sequence of mappings, with
+# each mapping having one key
+--- !!omap
+- Mark McGwire: 65
+- Sammy Sosa: 63
+- Ken Griffy: 58
diff --git a/tests/data/spec-02-26.structure b/tests/data/spec-02-26.structure
new file mode 100644
index 0000000..cf429b9
--- /dev/null
+++ b/tests/data/spec-02-26.structure
@@ -0,0 +1,5 @@
+[
+[(True, True)],
+[(True, True)],
+[(True, True)],
+]
diff --git a/tests/data/spec-02-26.tokens b/tests/data/spec-02-26.tokens
new file mode 100644
index 0000000..7bee492
--- /dev/null
+++ b/tests/data/spec-02-26.tokens
@@ -0,0 +1,6 @@
+--- !
+[[
+, {{ ? _ : _ ]}
+, {{ ? _ : _ ]}
+, {{ ? _ : _ ]}
+]}
diff --git a/tests/data/spec-02-27.data b/tests/data/spec-02-27.data
new file mode 100644
index 0000000..4625739
--- /dev/null
+++ b/tests/data/spec-02-27.data
@@ -0,0 +1,29 @@
+--- !<tag:clarkevans.com,2002:invoice>
+invoice: 34843
+date   : 2001-01-23
+bill-to: &id001
+    given  : Chris
+    family : Dumars
+    address:
+        lines: |
+            458 Walkman Dr.
+            Suite #292
+        city    : Royal Oak
+        state   : MI
+        postal  : 48046
+ship-to: *id001
+product:
+    - sku         : BL394D
+      quantity    : 4
+      description : Basketball
+      price       : 450.00
+    - sku         : BL4438H
+      quantity    : 1
+      description : Super Hoop
+      price       : 2392.00
+tax  : 251.42
+total: 4443.52
+comments:
+    Late afternoon is best.
+    Backup contact is Nancy
+    Billsmer @ 338-4338.
diff --git a/tests/data/spec-02-27.structure b/tests/data/spec-02-27.structure
new file mode 100644
index 0000000..a2113b9
--- /dev/null
+++ b/tests/data/spec-02-27.structure
@@ -0,0 +1,17 @@
+[
+(True, True),
+(True, True),
+(True, [
+    (True, True),
+    (True, True),
+    (True, [(True, True), (True, True), (True, True), (True, True)]),
+    ]),
+(True, '*'),
+(True, [
+        [(True, True), (True, True), (True, True), (True, True)],
+        [(True, True), (True, True), (True, True), (True, True)],
+    ]),
+(True, True),
+(True, True),
+(True, True),
+]
diff --git a/tests/data/spec-02-27.tokens b/tests/data/spec-02-27.tokens
new file mode 100644
index 0000000..2dc1c25
--- /dev/null
+++ b/tests/data/spec-02-27.tokens
@@ -0,0 +1,20 @@
+--- !
+{{
+? _ : _
+? _ : _
+? _ : &
+    {{
+    ? _ : _
+    ? _ : _
+    ? _ : {{ ? _ : _ ? _ : _ ? _ : _ ? _ : _ ]}
+    ]}
+? _ : *
+? _ :
+    [[
+    , {{ ? _ : _ ? _ : _ ? _ : _ ? _ : _ ]}
+    , {{ ? _ : _ ? _ : _ ? _ : _ ? _ : _ ]}
+    ]}
+? _ : _
+? _ : _
+? _ : _
+]}
diff --git a/tests/data/spec-02-28.data b/tests/data/spec-02-28.data
new file mode 100644
index 0000000..a5c8dc8
--- /dev/null
+++ b/tests/data/spec-02-28.data
@@ -0,0 +1,26 @@
+---
+Time: 2001-11-23 15:01:42 -5
+User: ed
+Warning:
+  This is an error message
+  for the log file
+---
+Time: 2001-11-23 15:02:31 -5
+User: ed
+Warning:
+  A slightly different error
+  message.
+---
+Date: 2001-11-23 15:03:17 -5
+User: ed
+Fatal:
+  Unknown variable "bar"
+Stack:
+  - file: TopClass.py
+    line: 23
+    code: |
+      x = MoreObject("345\n")
+  - file: MoreClass.py
+    line: 58
+    code: |-
+      foo = bar
diff --git a/tests/data/spec-02-28.structure b/tests/data/spec-02-28.structure
new file mode 100644
index 0000000..8ec0b56
--- /dev/null
+++ b/tests/data/spec-02-28.structure
@@ -0,0 +1,10 @@
+[
+[(True, True), (True, True), (True, True)],
+[(True, True), (True, True), (True, True)],
+[(True, True), (True, True), (True, True),
+(True, [
+    [(True, True), (True, True), (True, True)],
+    [(True, True), (True, True), (True, True)],
+    ]),
+]
+]
diff --git a/tests/data/spec-02-28.tokens b/tests/data/spec-02-28.tokens
new file mode 100644
index 0000000..8d5e1bc
--- /dev/null
+++ b/tests/data/spec-02-28.tokens
@@ -0,0 +1,23 @@
+---
+{{
+? _ : _
+? _ : _
+? _ : _
+]}
+---
+{{
+? _ : _
+? _ : _
+? _ : _
+]}
+---
+{{
+? _ : _
+? _ : _
+? _ : _
+? _ :
+    [[
+        , {{ ? _ : _ ? _ : _ ? _ : _ ]}
+        , {{ ? _ : _ ? _ : _ ? _ : _ ]}
+    ]}
+]}
diff --git a/tests/data/spec-05-01-utf16be.data b/tests/data/spec-05-01-utf16be.data
new file mode 100644
index 0000000..3525062
--- /dev/null
+++ b/tests/data/spec-05-01-utf16be.data
Binary files differ
diff --git a/tests/data/spec-05-01-utf16be.empty b/tests/data/spec-05-01-utf16be.empty
new file mode 100644
index 0000000..bfffa8b
--- /dev/null
+++ b/tests/data/spec-05-01-utf16be.empty
@@ -0,0 +1,2 @@
+# This stream contains no
+# documents, only comments.
diff --git a/tests/data/spec-05-01-utf16le.data b/tests/data/spec-05-01-utf16le.data
new file mode 100644
index 0000000..0823f74
--- /dev/null
+++ b/tests/data/spec-05-01-utf16le.data
Binary files differ
diff --git a/tests/data/spec-05-01-utf16le.empty b/tests/data/spec-05-01-utf16le.empty
new file mode 100644
index 0000000..bfffa8b
--- /dev/null
+++ b/tests/data/spec-05-01-utf16le.empty
@@ -0,0 +1,2 @@
+# This stream contains no
+# documents, only comments.
diff --git a/tests/data/spec-05-01-utf8.data b/tests/data/spec-05-01-utf8.data
new file mode 100644
index 0000000..780d25b
--- /dev/null
+++ b/tests/data/spec-05-01-utf8.data
@@ -0,0 +1 @@
+# Comment only.
diff --git a/tests/data/spec-05-01-utf8.empty b/tests/data/spec-05-01-utf8.empty
new file mode 100644
index 0000000..bfffa8b
--- /dev/null
+++ b/tests/data/spec-05-01-utf8.empty
@@ -0,0 +1,2 @@
+# This stream contains no
+# documents, only comments.
diff --git a/tests/data/spec-05-02-utf16be.data b/tests/data/spec-05-02-utf16be.data
new file mode 100644
index 0000000..5ebbb04
--- /dev/null
+++ b/tests/data/spec-05-02-utf16be.data
Binary files differ
diff --git a/tests/data/spec-05-02-utf16be.error b/tests/data/spec-05-02-utf16be.error
new file mode 100644
index 0000000..1df3616
--- /dev/null
+++ b/tests/data/spec-05-02-utf16be.error
@@ -0,0 +1,3 @@
+ERROR:
+ A BOM must not appear
+ inside a document.
diff --git a/tests/data/spec-05-02-utf16le.data b/tests/data/spec-05-02-utf16le.data
new file mode 100644
index 0000000..0cd90a2
--- /dev/null
+++ b/tests/data/spec-05-02-utf16le.data
Binary files differ
diff --git a/tests/data/spec-05-02-utf16le.error b/tests/data/spec-05-02-utf16le.error
new file mode 100644
index 0000000..1df3616
--- /dev/null
+++ b/tests/data/spec-05-02-utf16le.error
@@ -0,0 +1,3 @@
+ERROR:
+ A BOM must not appear
+ inside a document.
diff --git a/tests/data/spec-05-02-utf8.data b/tests/data/spec-05-02-utf8.data
new file mode 100644
index 0000000..fb74866
--- /dev/null
+++ b/tests/data/spec-05-02-utf8.data
@@ -0,0 +1,3 @@
+# Invalid use of BOM
+# inside a
+# document.
diff --git a/tests/data/spec-05-02-utf8.error b/tests/data/spec-05-02-utf8.error
new file mode 100644
index 0000000..1df3616
--- /dev/null
+++ b/tests/data/spec-05-02-utf8.error
@@ -0,0 +1,3 @@
+ERROR:
+ A BOM must not appear
+ inside a document.
diff --git a/tests/data/spec-05-03.canonical b/tests/data/spec-05-03.canonical
new file mode 100644
index 0000000..a143a73
--- /dev/null
+++ b/tests/data/spec-05-03.canonical
@@ -0,0 +1,14 @@
+%YAML 1.1
+---
+!!map {
+  ? !!str "sequence"
+  : !!seq [
+    !!str "one", !!str "two"
+  ],
+  ? !!str "mapping"
+  : !!map {
+    ? !!str "sky" : !!str "blue",
+#    ? !!str "sea" : !!str "green",
+    ? !!map { ? !!str "sea" : !!str "green" } : !!null "",
+  }
+}
diff --git a/tests/data/spec-05-03.data b/tests/data/spec-05-03.data
new file mode 100644
index 0000000..4661f33
--- /dev/null
+++ b/tests/data/spec-05-03.data
@@ -0,0 +1,7 @@
+sequence:
+- one
+- two
+mapping:
+  ? sky
+  : blue
+  ? sea : green
diff --git a/tests/data/spec-05-04.canonical b/tests/data/spec-05-04.canonical
new file mode 100644
index 0000000..00c9723
--- /dev/null
+++ b/tests/data/spec-05-04.canonical
@@ -0,0 +1,13 @@
+%YAML 1.1
+---
+!!map {
+  ? !!str "sequence"
+  : !!seq [
+    !!str "one", !!str "two"
+  ],
+  ? !!str "mapping"
+  : !!map {
+    ? !!str "sky" : !!str "blue",
+    ? !!str "sea" : !!str "green",
+  }
+}
diff --git a/tests/data/spec-05-04.data b/tests/data/spec-05-04.data
new file mode 100644
index 0000000..df33847
--- /dev/null
+++ b/tests/data/spec-05-04.data
@@ -0,0 +1,2 @@
+sequence: [ one, two, ]
+mapping: { sky: blue, sea: green }
diff --git a/tests/data/spec-05-05.data b/tests/data/spec-05-05.data
new file mode 100644
index 0000000..62524c0
--- /dev/null
+++ b/tests/data/spec-05-05.data
@@ -0,0 +1 @@
+# Comment only.
diff --git a/tests/data/spec-05-05.empty b/tests/data/spec-05-05.empty
new file mode 100644
index 0000000..bfffa8b
--- /dev/null
+++ b/tests/data/spec-05-05.empty
@@ -0,0 +1,2 @@
+# This stream contains no
+# documents, only comments.
diff --git a/tests/data/spec-05-06.canonical b/tests/data/spec-05-06.canonical
new file mode 100644
index 0000000..4f30c11
--- /dev/null
+++ b/tests/data/spec-05-06.canonical
@@ -0,0 +1,8 @@
+%YAML 1.1
+---
+!!map {
+  ? !!str "anchored"
+  : &A1 !local "value",
+  ? !!str "alias"
+  : *A1,
+}
diff --git a/tests/data/spec-05-06.data b/tests/data/spec-05-06.data
new file mode 100644
index 0000000..7a1f9b3
--- /dev/null
+++ b/tests/data/spec-05-06.data
@@ -0,0 +1,2 @@
+anchored: !local &anchor value
+alias: *anchor
diff --git a/tests/data/spec-05-07.canonical b/tests/data/spec-05-07.canonical
new file mode 100644
index 0000000..dc3732a
--- /dev/null
+++ b/tests/data/spec-05-07.canonical
@@ -0,0 +1,8 @@
+%YAML 1.1
+---
+!!map {
+  ? !!str "literal"
+  : !!str "text\n",
+  ? !!str "folded"
+  : !!str "text\n",
+}
diff --git a/tests/data/spec-05-07.data b/tests/data/spec-05-07.data
new file mode 100644
index 0000000..97eb3a3
--- /dev/null
+++ b/tests/data/spec-05-07.data
@@ -0,0 +1,4 @@
+literal: |
+  text
+folded: >
+  text
diff --git a/tests/data/spec-05-08.canonical b/tests/data/spec-05-08.canonical
new file mode 100644
index 0000000..610bd68
--- /dev/null
+++ b/tests/data/spec-05-08.canonical
@@ -0,0 +1,8 @@
+%YAML 1.1
+---
+!!map {
+  ? !!str "single"
+  : !!str "text",
+  ? !!str "double"
+  : !!str "text",
+}
diff --git a/tests/data/spec-05-08.data b/tests/data/spec-05-08.data
new file mode 100644
index 0000000..04ebf69
--- /dev/null
+++ b/tests/data/spec-05-08.data
@@ -0,0 +1,2 @@
+single: 'text'
+double: "text"
diff --git a/tests/data/spec-05-09.canonical b/tests/data/spec-05-09.canonical
new file mode 100644
index 0000000..597e3de
--- /dev/null
+++ b/tests/data/spec-05-09.canonical
@@ -0,0 +1,3 @@
+%YAML 1.1
+---
+!!str "text"
diff --git a/tests/data/spec-05-09.data b/tests/data/spec-05-09.data
new file mode 100644
index 0000000..a43431b
--- /dev/null
+++ b/tests/data/spec-05-09.data
@@ -0,0 +1,2 @@
+%YAML 1.1
+--- text
diff --git a/tests/data/spec-05-10.data b/tests/data/spec-05-10.data
new file mode 100644
index 0000000..a4caf91
--- /dev/null
+++ b/tests/data/spec-05-10.data
@@ -0,0 +1,2 @@
+commercial-at: @text
+grave-accent: `text
diff --git a/tests/data/spec-05-10.error b/tests/data/spec-05-10.error
new file mode 100644
index 0000000..46f776e
--- /dev/null
+++ b/tests/data/spec-05-10.error
@@ -0,0 +1,3 @@
+ERROR:
+ Reserved indicators can't
+ start a plain scalar.
diff --git a/tests/data/spec-05-11.canonical b/tests/data/spec-05-11.canonical
new file mode 100644
index 0000000..fc25bef
--- /dev/null
+++ b/tests/data/spec-05-11.canonical
@@ -0,0 +1,6 @@
+%YAML 1.1
+--- !!str
+"Generic line break (no glyph)\n\
+ Generic line break (glyphed)\n\
+ Line separator\u2028\
+ Paragraph separator\u2029"
diff --git a/tests/data/spec-05-11.data b/tests/data/spec-05-11.data
new file mode 100644
index 0000000..b448b75
--- /dev/null
+++ b/tests/data/spec-05-11.data
@@ -0,0 +1,3 @@
+|
+  Generic line break (no glyph)
+  Generic line break (glyphed)…  Line separator
  Paragraph separator

\ No newline at end of file
diff --git a/tests/data/spec-05-12.data b/tests/data/spec-05-12.data
new file mode 100644
index 0000000..7c3ad7f
--- /dev/null
+++ b/tests/data/spec-05-12.data
@@ -0,0 +1,9 @@
+# Tabs do's and don'ts:
+# comment: 	
+quoted: "Quoted		"
+block: |
+  void main() {
+  	printf("Hello, world!\n");
+  }
+elsewhere:	# separation
+	indentation, in	plain scalar
diff --git a/tests/data/spec-05-12.error b/tests/data/spec-05-12.error
new file mode 100644
index 0000000..8aad4c8
--- /dev/null
+++ b/tests/data/spec-05-12.error
@@ -0,0 +1,8 @@
+ERROR:
+ Tabs may appear inside
+ comments and quoted or
+ block scalar content.
+ Tabs must not appear
+ elsewhere, such as
+ in indentation and
+ separation spaces.
diff --git a/tests/data/spec-05-13.canonical b/tests/data/spec-05-13.canonical
new file mode 100644
index 0000000..90c1c5c
--- /dev/null
+++ b/tests/data/spec-05-13.canonical
@@ -0,0 +1,5 @@
+%YAML 1.1
+--- !!str
+"Text containing \
+ both space and \
+ tab	characters"
diff --git a/tests/data/spec-05-13.data b/tests/data/spec-05-13.data
new file mode 100644
index 0000000..fce7951
--- /dev/null
+++ b/tests/data/spec-05-13.data
@@ -0,0 +1,3 @@
+  "Text containing   
+  both space and	
+  	tab	characters"
diff --git a/tests/data/spec-05-14.canonical b/tests/data/spec-05-14.canonical
new file mode 100644
index 0000000..4bff01c
--- /dev/null
+++ b/tests/data/spec-05-14.canonical
@@ -0,0 +1,7 @@
+%YAML 1.1
+---
+"Fun with \x5C
+ \x22 \x07 \x08 \x1B \x0C
+ \x0A \x0D \x09 \x0B \x00
+ \x20 \xA0 \x85 \u2028 \u2029
+ A A A"
diff --git a/tests/data/spec-05-14.data b/tests/data/spec-05-14.data
new file mode 100644
index 0000000..d6e8ce4
--- /dev/null
+++ b/tests/data/spec-05-14.data
@@ -0,0 +1,2 @@
+"Fun with \\
+ \" \a \b \e \f \… \n \r \t \v \0 \
 \  \_ \N \L \P \
 \x41 \u0041 \U00000041"
diff --git a/tests/data/spec-05-15.data b/tests/data/spec-05-15.data
new file mode 100644
index 0000000..7bf12b6
--- /dev/null
+++ b/tests/data/spec-05-15.data
@@ -0,0 +1,3 @@
+Bad escapes:
+  "\c
+  \xq-"
diff --git a/tests/data/spec-05-15.error b/tests/data/spec-05-15.error
new file mode 100644
index 0000000..71ffbd9
--- /dev/null
+++ b/tests/data/spec-05-15.error
@@ -0,0 +1,3 @@
+ERROR:
+- c is an invalid escaped character.
+- q and - are invalid hex digits.
diff --git a/tests/data/spec-06-01.canonical b/tests/data/spec-06-01.canonical
new file mode 100644
index 0000000..f17ec92
--- /dev/null
+++ b/tests/data/spec-06-01.canonical
@@ -0,0 +1,15 @@
+%YAML 1.1
+---
+!!map {
+  ? !!str "Not indented"
+  : !!map {
+      ? !!str "By one space"
+      : !!str "By four\n  spaces\n",
+      ? !!str "Flow style"
+      : !!seq [
+          !!str "By two",
+          !!str "Also by two",
+          !!str "Still by two",
+        ]
+    }
+}
diff --git a/tests/data/spec-06-01.data b/tests/data/spec-06-01.data
new file mode 100644
index 0000000..6134ba1
--- /dev/null
+++ b/tests/data/spec-06-01.data
@@ -0,0 +1,14 @@
+  # Leading comment line spaces are
+   # neither content nor indentation.
+    
+Not indented:
+ By one space: |
+    By four
+      spaces
+ Flow style: [    # Leading spaces
+   By two,        # in flow style
+  Also by two,    # are neither
+# Tabs are not allowed:
+#  	Still by two   # content nor
+    Still by two   # content nor
+    ]             # indentation.
diff --git a/tests/data/spec-06-02.data b/tests/data/spec-06-02.data
new file mode 100644
index 0000000..ff741e5
--- /dev/null
+++ b/tests/data/spec-06-02.data
@@ -0,0 +1,3 @@
+  # Comment
+   
+
diff --git a/tests/data/spec-06-02.empty b/tests/data/spec-06-02.empty
new file mode 100644
index 0000000..bfffa8b
--- /dev/null
+++ b/tests/data/spec-06-02.empty
@@ -0,0 +1,2 @@
+# This stream contains no
+# documents, only comments.
diff --git a/tests/data/spec-06-03.canonical b/tests/data/spec-06-03.canonical
new file mode 100644
index 0000000..ec26902
--- /dev/null
+++ b/tests/data/spec-06-03.canonical
@@ -0,0 +1,6 @@
+%YAML 1.1
+---
+!!map {
+  ? !!str "key"
+  : !!str "value"
+}
diff --git a/tests/data/spec-06-03.data b/tests/data/spec-06-03.data
new file mode 100644
index 0000000..9db0912
--- /dev/null
+++ b/tests/data/spec-06-03.data
@@ -0,0 +1,2 @@
+key:    # Comment
+  value
diff --git a/tests/data/spec-06-04.canonical b/tests/data/spec-06-04.canonical
new file mode 100644
index 0000000..ec26902
--- /dev/null
+++ b/tests/data/spec-06-04.canonical
@@ -0,0 +1,6 @@
+%YAML 1.1
+---
+!!map {
+  ? !!str "key"
+  : !!str "value"
+}
diff --git a/tests/data/spec-06-04.data b/tests/data/spec-06-04.data
new file mode 100644
index 0000000..86308dd
--- /dev/null
+++ b/tests/data/spec-06-04.data
@@ -0,0 +1,4 @@
+key:    # Comment
+        # lines
+  value
+
diff --git a/tests/data/spec-06-05.canonical b/tests/data/spec-06-05.canonical
new file mode 100644
index 0000000..8da431d
--- /dev/null
+++ b/tests/data/spec-06-05.canonical
@@ -0,0 +1,16 @@
+%YAML 1.1
+---
+!!map {
+  ? !!map {
+    ? !!str "first"
+    : !!str "Sammy",
+    ? !!str "last"
+    : !!str "Sosa"
+  }
+  : !!map {
+    ? !!str "hr"
+    : !!int "65",
+    ? !!str "avg"
+    : !!float "0.278"
+  }
+}
diff --git a/tests/data/spec-06-05.data b/tests/data/spec-06-05.data
new file mode 100644
index 0000000..37613f5
--- /dev/null
+++ b/tests/data/spec-06-05.data
@@ -0,0 +1,6 @@
+{ first: Sammy, last: Sosa }:
+# Statistics:
+  hr:  # Home runs
+    65
+  avg: # Average
+    0.278
diff --git a/tests/data/spec-06-06.canonical b/tests/data/spec-06-06.canonical
new file mode 100644
index 0000000..513d07a
--- /dev/null
+++ b/tests/data/spec-06-06.canonical
@@ -0,0 +1,10 @@
+%YAML 1.1
+---
+!!map {
+  ? !!str "plain"
+  : !!str "text lines",
+  ? !!str "quoted"
+  : !!str "text lines",
+  ? !!str "block"
+  : !!str "text\n 	lines\n"
+}
diff --git a/tests/data/spec-06-06.data b/tests/data/spec-06-06.data
new file mode 100644
index 0000000..2f62d08
--- /dev/null
+++ b/tests/data/spec-06-06.data
@@ -0,0 +1,7 @@
+plain: text
+  lines
+quoted: "text
+  	lines"
+block: |
+  text
+   	lines
diff --git a/tests/data/spec-06-07.canonical b/tests/data/spec-06-07.canonical
new file mode 100644
index 0000000..11357e4
--- /dev/null
+++ b/tests/data/spec-06-07.canonical
@@ -0,0 +1,6 @@
+%YAML 1.1
+---
+!!seq [
+  !!str "foo\nbar",
+  !!str "foo\n\nbar"
+]
diff --git a/tests/data/spec-06-07.data b/tests/data/spec-06-07.data
new file mode 100644
index 0000000..130cfa7
--- /dev/null
+++ b/tests/data/spec-06-07.data
@@ -0,0 +1,8 @@
+- foo
+ 
+  bar
+- |-
+  foo
+ 
+  bar
+  
diff --git a/tests/data/spec-06-08.canonical b/tests/data/spec-06-08.canonical
new file mode 100644
index 0000000..cc72bc8
--- /dev/null
+++ b/tests/data/spec-06-08.canonical
@@ -0,0 +1,5 @@
+%YAML 1.1
+--- !!str
+"specific\L\
+ trimmed\n\n\n\
+ as space"
diff --git a/tests/data/spec-06-08.data b/tests/data/spec-06-08.data
new file mode 100644
index 0000000..f2896ed
--- /dev/null
+++ b/tests/data/spec-06-08.data
@@ -0,0 +1,2 @@
+>-
+  specific
  trimmed…  … ……  as…  space
diff --git a/tests/data/spec-07-01.canonical b/tests/data/spec-07-01.canonical
new file mode 100644
index 0000000..8c8c48d
--- /dev/null
+++ b/tests/data/spec-07-01.canonical
@@ -0,0 +1,3 @@
+%YAML 1.1
+--- !!str
+"foo"
diff --git a/tests/data/spec-07-01.data b/tests/data/spec-07-01.data
new file mode 100644
index 0000000..2113eb6
--- /dev/null
+++ b/tests/data/spec-07-01.data
@@ -0,0 +1,3 @@
+%FOO  bar baz # Should be ignored
+               # with a warning.
+--- "foo"
diff --git a/tests/data/spec-07-01.skip-ext b/tests/data/spec-07-01.skip-ext
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/tests/data/spec-07-01.skip-ext
diff --git a/tests/data/spec-07-02.canonical b/tests/data/spec-07-02.canonical
new file mode 100644
index 0000000..cb7dd1c
--- /dev/null
+++ b/tests/data/spec-07-02.canonical
@@ -0,0 +1,3 @@
+%YAML 1.1
+---
+!!str "foo"
diff --git a/tests/data/spec-07-02.data b/tests/data/spec-07-02.data
new file mode 100644
index 0000000..c8b7322
--- /dev/null
+++ b/tests/data/spec-07-02.data
@@ -0,0 +1,4 @@
+%YAML 1.2 # Attempt parsing
+           # with a warning
+---
+"foo"
diff --git a/tests/data/spec-07-02.skip-ext b/tests/data/spec-07-02.skip-ext
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/tests/data/spec-07-02.skip-ext
diff --git a/tests/data/spec-07-03.data b/tests/data/spec-07-03.data
new file mode 100644
index 0000000..4bfa07a
--- /dev/null
+++ b/tests/data/spec-07-03.data
@@ -0,0 +1,3 @@
+%YAML 1.1
+%YAML 1.1
+foo
diff --git a/tests/data/spec-07-03.error b/tests/data/spec-07-03.error
new file mode 100644
index 0000000..b0ac446
--- /dev/null
+++ b/tests/data/spec-07-03.error
@@ -0,0 +1,3 @@
+ERROR:
+The YAML directive must only be
+given at most once per document.
diff --git a/tests/data/spec-07-04.canonical b/tests/data/spec-07-04.canonical
new file mode 100644
index 0000000..cb7dd1c
--- /dev/null
+++ b/tests/data/spec-07-04.canonical
@@ -0,0 +1,3 @@
+%YAML 1.1
+---
+!!str "foo"
diff --git a/tests/data/spec-07-04.data b/tests/data/spec-07-04.data
new file mode 100644
index 0000000..50f5ab9
--- /dev/null
+++ b/tests/data/spec-07-04.data
@@ -0,0 +1,3 @@
+%TAG !yaml! tag:yaml.org,2002:
+---
+!yaml!str "foo"
diff --git a/tests/data/spec-07-05.data b/tests/data/spec-07-05.data
new file mode 100644
index 0000000..7276eae
--- /dev/null
+++ b/tests/data/spec-07-05.data
@@ -0,0 +1,3 @@
+%TAG ! !foo
+%TAG ! !foo
+bar
diff --git a/tests/data/spec-07-05.error b/tests/data/spec-07-05.error
new file mode 100644
index 0000000..5601b19
--- /dev/null
+++ b/tests/data/spec-07-05.error
@@ -0,0 +1,4 @@
+ERROR:
+The TAG directive must only
+be given at most once per
+handle in the same document.
diff --git a/tests/data/spec-07-06.canonical b/tests/data/spec-07-06.canonical
new file mode 100644
index 0000000..bddf616
--- /dev/null
+++ b/tests/data/spec-07-06.canonical
@@ -0,0 +1,6 @@
+%YAML 1.1
+---
+!!seq [
+  !<!foobar> "baz",
+  !<tag:yaml.org,2002:str> "string"
+]
diff --git a/tests/data/spec-07-06.data b/tests/data/spec-07-06.data
new file mode 100644
index 0000000..d9854cb
--- /dev/null
+++ b/tests/data/spec-07-06.data
@@ -0,0 +1,5 @@
+%TAG !      !foo
+%TAG !yaml! tag:yaml.org,2002:
+---
+- !bar "baz"
+- !yaml!str "string"
diff --git a/tests/data/spec-07-07a.canonical b/tests/data/spec-07-07a.canonical
new file mode 100644
index 0000000..fa086df
--- /dev/null
+++ b/tests/data/spec-07-07a.canonical
@@ -0,0 +1,3 @@
+%YAML 1.1
+---
+!<!foo> "bar"
diff --git a/tests/data/spec-07-07a.data b/tests/data/spec-07-07a.data
new file mode 100644
index 0000000..9d42ec3
--- /dev/null
+++ b/tests/data/spec-07-07a.data
@@ -0,0 +1,2 @@
+# Private application:
+!foo "bar"
diff --git a/tests/data/spec-07-07b.canonical b/tests/data/spec-07-07b.canonical
new file mode 100644
index 0000000..fe917d8
--- /dev/null
+++ b/tests/data/spec-07-07b.canonical
@@ -0,0 +1,3 @@
+%YAML 1.1
+---
+!<tag:ben-kiki.org,2000:app/foo> "bar"
diff --git a/tests/data/spec-07-07b.data b/tests/data/spec-07-07b.data
new file mode 100644
index 0000000..2d36d0e
--- /dev/null
+++ b/tests/data/spec-07-07b.data
@@ -0,0 +1,4 @@
+# Migrated to global:
+%TAG ! tag:ben-kiki.org,2000:app/
+---
+!foo "bar"
diff --git a/tests/data/spec-07-08.canonical b/tests/data/spec-07-08.canonical
new file mode 100644
index 0000000..703aa7b
--- /dev/null
+++ b/tests/data/spec-07-08.canonical
@@ -0,0 +1,7 @@
+%YAML 1.1
+---
+!!seq [
+  !<!foo> "bar",
+  !<tag:yaml.org,2002:str> "string",
+  !<tag:ben-kiki.org,2000:type> "baz"
+]
diff --git a/tests/data/spec-07-08.data b/tests/data/spec-07-08.data
new file mode 100644
index 0000000..e2c6d9e
--- /dev/null
+++ b/tests/data/spec-07-08.data
@@ -0,0 +1,9 @@
+# Explicitly specify default settings:
+%TAG !     !
+%TAG !!    tag:yaml.org,2002:
+# Named handles have no default:
+%TAG !o! tag:ben-kiki.org,2000:
+---
+- !foo "bar"
+- !!str "string"
+- !o!type "baz"
diff --git a/tests/data/spec-07-09.canonical b/tests/data/spec-07-09.canonical
new file mode 100644
index 0000000..32d9e94
--- /dev/null
+++ b/tests/data/spec-07-09.canonical
@@ -0,0 +1,9 @@
+%YAML 1.1
+---
+!!str "foo"
+%YAML 1.1
+---
+!!str "bar"
+%YAML 1.1
+---
+!!str "baz"
diff --git a/tests/data/spec-07-09.data b/tests/data/spec-07-09.data
new file mode 100644
index 0000000..1209d47
--- /dev/null
+++ b/tests/data/spec-07-09.data
@@ -0,0 +1,11 @@
+---
+foo
+...
+# Repeated end marker.
+...
+---
+bar
+# No end marker.
+---
+baz
+...
diff --git a/tests/data/spec-07-10.canonical b/tests/data/spec-07-10.canonical
new file mode 100644
index 0000000..1db650a
--- /dev/null
+++ b/tests/data/spec-07-10.canonical
@@ -0,0 +1,15 @@
+%YAML 1.1
+---
+!!str "Root flow scalar"
+%YAML 1.1
+---
+!!str "Root block scalar\n"
+%YAML 1.1
+---
+!!map {
+  ? !!str "foo"
+  : !!str "bar"
+}
+---
+#!!str ""
+!!null ""
diff --git a/tests/data/spec-07-10.data b/tests/data/spec-07-10.data
new file mode 100644
index 0000000..6939b39
--- /dev/null
+++ b/tests/data/spec-07-10.data
@@ -0,0 +1,11 @@
+"Root flow
+ scalar"
+--- !!str >
+ Root block
+ scalar
+---
+# Root collection:
+foo : bar
+... # Is optional.
+---
+# Explicit document may be empty.
diff --git a/tests/data/spec-07-11.data b/tests/data/spec-07-11.data
new file mode 100644
index 0000000..d11302d
--- /dev/null
+++ b/tests/data/spec-07-11.data
@@ -0,0 +1,2 @@
+# A stream may contain
+# no documents.
diff --git a/tests/data/spec-07-11.empty b/tests/data/spec-07-11.empty
new file mode 100644
index 0000000..bfffa8b
--- /dev/null
+++ b/tests/data/spec-07-11.empty
@@ -0,0 +1,2 @@
+# This stream contains no
+# documents, only comments.
diff --git a/tests/data/spec-07-12a.canonical b/tests/data/spec-07-12a.canonical
new file mode 100644
index 0000000..efc116f
--- /dev/null
+++ b/tests/data/spec-07-12a.canonical
@@ -0,0 +1,6 @@
+%YAML 1.1
+---
+!!map {
+  ? !!str "foo"
+  : !!str "bar"
+}
diff --git a/tests/data/spec-07-12a.data b/tests/data/spec-07-12a.data
new file mode 100644
index 0000000..3807d57
--- /dev/null
+++ b/tests/data/spec-07-12a.data
@@ -0,0 +1,3 @@
+# Implicit document. Root
+# collection (mapping) node.
+foo : bar
diff --git a/tests/data/spec-07-12b.canonical b/tests/data/spec-07-12b.canonical
new file mode 100644
index 0000000..04bcffc
--- /dev/null
+++ b/tests/data/spec-07-12b.canonical
@@ -0,0 +1,3 @@
+%YAML 1.1
+---
+!!str "Text content\n"
diff --git a/tests/data/spec-07-12b.data b/tests/data/spec-07-12b.data
new file mode 100644
index 0000000..43250db
--- /dev/null
+++ b/tests/data/spec-07-12b.data
@@ -0,0 +1,4 @@
+# Explicit document. Root
+# scalar (literal) node.
+--- |
+ Text content
diff --git a/tests/data/spec-07-13.canonical b/tests/data/spec-07-13.canonical
new file mode 100644
index 0000000..5af71e9
--- /dev/null
+++ b/tests/data/spec-07-13.canonical
@@ -0,0 +1,9 @@
+%YAML 1.1
+---
+!!str "First document"
+---
+!<!foo> "No directives"
+---
+!<!foobar> "With directives"
+---
+!<!baz> "Reset settings"
diff --git a/tests/data/spec-07-13.data b/tests/data/spec-07-13.data
new file mode 100644
index 0000000..ba7ec63
--- /dev/null
+++ b/tests/data/spec-07-13.data
@@ -0,0 +1,9 @@
+! "First document"
+---
+!foo "No directives"
+%TAG ! !foo
+---
+!bar "With directives"
+%YAML 1.1
+---
+!baz "Reset settings"
diff --git a/tests/data/spec-08-01.canonical b/tests/data/spec-08-01.canonical
new file mode 100644
index 0000000..69e4161
--- /dev/null
+++ b/tests/data/spec-08-01.canonical
@@ -0,0 +1,8 @@
+%YAML 1.1
+---
+!!map {
+  ? &A1 !!str "foo"
+  : !!str "bar",
+  ? &A2 !!str "baz"
+  : *A1
+}
diff --git a/tests/data/spec-08-01.data b/tests/data/spec-08-01.data
new file mode 100644
index 0000000..48986ec
--- /dev/null
+++ b/tests/data/spec-08-01.data
@@ -0,0 +1,2 @@
+!!str &a1 "foo" : !!str bar
+&a2 baz : *a1
diff --git a/tests/data/spec-08-02.canonical b/tests/data/spec-08-02.canonical
new file mode 100644
index 0000000..dd6f76e
--- /dev/null
+++ b/tests/data/spec-08-02.canonical
@@ -0,0 +1,8 @@
+%YAML 1.1
+---
+!!map {
+  ? !!str "First occurrence"
+  : &A !!str "Value",
+  ? !!str "Second occurrence"
+  : *A
+}
diff --git a/tests/data/spec-08-02.data b/tests/data/spec-08-02.data
new file mode 100644
index 0000000..600d179
--- /dev/null
+++ b/tests/data/spec-08-02.data
@@ -0,0 +1,2 @@
+First occurrence: &anchor Value
+Second occurrence: *anchor
diff --git a/tests/data/spec-08-03.canonical b/tests/data/spec-08-03.canonical
new file mode 100644
index 0000000..be7ea8f
--- /dev/null
+++ b/tests/data/spec-08-03.canonical
@@ -0,0 +1,6 @@
+%YAML 1.1
+---
+!!map {
+  ? !<tag:yaml.org,2002:str> "foo"
+  : !<!bar> "baz"
+}
diff --git a/tests/data/spec-08-03.data b/tests/data/spec-08-03.data
new file mode 100644
index 0000000..8e51f52
--- /dev/null
+++ b/tests/data/spec-08-03.data
@@ -0,0 +1,2 @@
+!<tag:yaml.org,2002:str> foo :
+  !<!bar> baz
diff --git a/tests/data/spec-08-04.data b/tests/data/spec-08-04.data
new file mode 100644
index 0000000..f7d1b01
--- /dev/null
+++ b/tests/data/spec-08-04.data
@@ -0,0 +1,2 @@
+- !<!> foo
+- !<$:?> bar
diff --git a/tests/data/spec-08-04.error b/tests/data/spec-08-04.error
new file mode 100644
index 0000000..6066375
--- /dev/null
+++ b/tests/data/spec-08-04.error
@@ -0,0 +1,6 @@
+ERROR:
+- Verbatim tags aren't resolved,
+  so ! is invalid.
+- The $:? tag is neither a global
+  URI tag nor a local tag starting
+  with “!”.
diff --git a/tests/data/spec-08-05.canonical b/tests/data/spec-08-05.canonical
new file mode 100644
index 0000000..a5c710a
--- /dev/null
+++ b/tests/data/spec-08-05.canonical
@@ -0,0 +1,7 @@
+%YAML 1.1
+---
+!!seq [
+  !<!local> "foo",
+  !<tag:yaml.org,2002:str> "bar",
+  !<tag:ben-kiki.org,2000:type> "baz",
+]
diff --git a/tests/data/spec-08-05.data b/tests/data/spec-08-05.data
new file mode 100644
index 0000000..93576ed
--- /dev/null
+++ b/tests/data/spec-08-05.data
@@ -0,0 +1,5 @@
+%TAG !o! tag:ben-kiki.org,2000:
+---
+- !local foo
+- !!str bar
+- !o!type baz
diff --git a/tests/data/spec-08-06.data b/tests/data/spec-08-06.data
new file mode 100644
index 0000000..8580010
--- /dev/null
+++ b/tests/data/spec-08-06.data
@@ -0,0 +1,5 @@
+%TAG !o! tag:ben-kiki.org,2000:
+---
+- !$a!b foo
+- !o! bar
+- !h!type baz
diff --git a/tests/data/spec-08-06.error b/tests/data/spec-08-06.error
new file mode 100644
index 0000000..fb76f42
--- /dev/null
+++ b/tests/data/spec-08-06.error
@@ -0,0 +1,4 @@
+ERROR:
+- The !$a! looks like a handle.
+- The !o! handle has no suffix.
+- The !h! handle wasn't declared.
diff --git a/tests/data/spec-08-07.canonical b/tests/data/spec-08-07.canonical
new file mode 100644
index 0000000..e2f43d9
--- /dev/null
+++ b/tests/data/spec-08-07.canonical
@@ -0,0 +1,8 @@
+%YAML 1.1
+---
+!!seq [
+  !<tag:yaml.org,2002:str> "12",
+  !<tag:yaml.org,2002:int> "12",
+#  !<tag:yaml.org,2002:str> "12",
+  !<tag:yaml.org,2002:int> "12",
+]
diff --git a/tests/data/spec-08-07.data b/tests/data/spec-08-07.data
new file mode 100644
index 0000000..98aa565
--- /dev/null
+++ b/tests/data/spec-08-07.data
@@ -0,0 +1,4 @@
+# Assuming conventional resolution:
+- "12"
+- 12
+- ! 12
diff --git a/tests/data/spec-08-08.canonical b/tests/data/spec-08-08.canonical
new file mode 100644
index 0000000..d3f8b1a
--- /dev/null
+++ b/tests/data/spec-08-08.canonical
@@ -0,0 +1,15 @@
+%YAML 1.1
+---
+!!map {
+  ? !!str "foo"
+  : !!str "bar baz"
+}
+%YAML 1.1
+---
+!!str "foo bar"
+%YAML 1.1
+---
+!!str "foo bar"
+%YAML 1.1
+---
+!!str "foo\n"
diff --git a/tests/data/spec-08-08.data b/tests/data/spec-08-08.data
new file mode 100644
index 0000000..757a93d
--- /dev/null
+++ b/tests/data/spec-08-08.data
@@ -0,0 +1,13 @@
+---
+foo:
+ "bar
+ baz"
+---
+"foo
+ bar"
+---
+foo
+ bar
+--- |
+ foo
+...
diff --git a/tests/data/spec-08-09.canonical b/tests/data/spec-08-09.canonical
new file mode 100644
index 0000000..3805daf
--- /dev/null
+++ b/tests/data/spec-08-09.canonical
@@ -0,0 +1,21 @@
+%YAML 1.1
+--- !!map {
+  ? !!str "scalars" : !!map {
+      ? !!str "plain"
+      : !!str "some text",
+      ? !!str "quoted"
+      : !!map {
+        ? !!str "single"
+        : !!str "some text",
+        ? !!str "double"
+        : !!str "some text"
+  } },
+  ? !!str "collections" : !!map {
+    ? !!str "sequence" : !!seq [
+      !!str "entry",
+      !!map {
+        ? !!str "key" : !!str "value"
+    } ],
+    ? !!str "mapping" : !!map {
+      ? !!str "key" : !!str "value"
+} } }
diff --git a/tests/data/spec-08-09.data b/tests/data/spec-08-09.data
new file mode 100644
index 0000000..69da042
--- /dev/null
+++ b/tests/data/spec-08-09.data
@@ -0,0 +1,11 @@
+---
+scalars:
+  plain: !!str some text
+  quoted:
+    single: 'some text'
+    double: "some text"
+collections:
+  sequence: !!seq [ !!str entry,
+    # Mapping entry:
+      key: value ]
+  mapping: { key: value }
diff --git a/tests/data/spec-08-10.canonical b/tests/data/spec-08-10.canonical
new file mode 100644
index 0000000..8281c5e
--- /dev/null
+++ b/tests/data/spec-08-10.canonical
@@ -0,0 +1,23 @@
+%YAML 1.1
+---
+!!map {
+  ? !!str "block styles" : !!map {
+    ? !!str "scalars" : !!map {
+      ? !!str "literal"
+      : !!str "#!/usr/bin/perl\n\
+          print \"Hello,
+          world!\\n\";\n",
+      ? !!str "folded"
+      : !!str "This sentence
+          is false.\n"
+    },
+    ? !!str "collections" : !!map {
+      ? !!str "sequence" : !!seq [
+        !!str "entry",
+        !!map {
+          ? !!str "key" : !!str "value"
+        }
+      ],
+      ? !!str "mapping" : !!map {
+        ? !!str "key" : !!str "value"
+} } } }
diff --git a/tests/data/spec-08-10.data b/tests/data/spec-08-10.data
new file mode 100644
index 0000000..72acc56
--- /dev/null
+++ b/tests/data/spec-08-10.data
@@ -0,0 +1,15 @@
+block styles:
+  scalars:
+    literal: !!str |
+      #!/usr/bin/perl
+      print "Hello, world!\n";
+    folded: >
+      This sentence
+      is false.
+  collections: !!map
+    sequence: !!seq # Entry:
+      - entry # Plain
+      # Mapping entry:
+      - key: value
+    mapping: 
+      key: value
diff --git a/tests/data/spec-08-11.canonical b/tests/data/spec-08-11.canonical
new file mode 100644
index 0000000..dd6f76e
--- /dev/null
+++ b/tests/data/spec-08-11.canonical
@@ -0,0 +1,8 @@
+%YAML 1.1
+---
+!!map {
+  ? !!str "First occurrence"
+  : &A !!str "Value",
+  ? !!str "Second occurrence"
+  : *A
+}
diff --git a/tests/data/spec-08-11.data b/tests/data/spec-08-11.data
new file mode 100644
index 0000000..600d179
--- /dev/null
+++ b/tests/data/spec-08-11.data
@@ -0,0 +1,2 @@
+First occurrence: &anchor Value
+Second occurrence: *anchor
diff --git a/tests/data/spec-08-12.canonical b/tests/data/spec-08-12.canonical
new file mode 100644
index 0000000..93899f4
--- /dev/null
+++ b/tests/data/spec-08-12.canonical
@@ -0,0 +1,10 @@
+%YAML 1.1
+---
+!!seq [
+  !!str "Without properties",
+  &A !!str "Anchored",
+  !!str "Tagged",
+  *A,
+  !!str "",
+  !!str "",
+]
diff --git a/tests/data/spec-08-12.data b/tests/data/spec-08-12.data
new file mode 100644
index 0000000..3d4c6b7
--- /dev/null
+++ b/tests/data/spec-08-12.data
@@ -0,0 +1,8 @@
+[
+  Without properties,
+  &anchor "Anchored",
+  !!str 'Tagged',
+  *anchor, # Alias node
+  !!str ,  # Empty plain scalar
+  '',   # Empty plain scalar
+]
diff --git a/tests/data/spec-08-13.canonical b/tests/data/spec-08-13.canonical
new file mode 100644
index 0000000..618bb7b
--- /dev/null
+++ b/tests/data/spec-08-13.canonical
@@ -0,0 +1,10 @@
+%YAML 1.1
+---
+!!map {
+  ? !!str "foo"
+#  : !!str "",
+#  ? !!str ""
+  : !!null "",
+  ? !!null ""
+  : !!str "bar",
+}
diff --git a/tests/data/spec-08-13.data b/tests/data/spec-08-13.data
new file mode 100644
index 0000000..ebe663a
--- /dev/null
+++ b/tests/data/spec-08-13.data
@@ -0,0 +1,4 @@
+{
+  ? foo :,
+  ? : bar,
+}
diff --git a/tests/data/spec-08-13.skip-ext b/tests/data/spec-08-13.skip-ext
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/tests/data/spec-08-13.skip-ext
diff --git a/tests/data/spec-08-14.canonical b/tests/data/spec-08-14.canonical
new file mode 100644
index 0000000..11db439
--- /dev/null
+++ b/tests/data/spec-08-14.canonical
@@ -0,0 +1,10 @@
+%YAML 1.1
+---
+!!seq [
+  !!str "flow in block",
+  !!str "Block scalar\n",
+  !!map {
+    ? !!str "foo"
+    : !!str "bar"
+  }
+]
diff --git a/tests/data/spec-08-14.data b/tests/data/spec-08-14.data
new file mode 100644
index 0000000..2fbb1f7
--- /dev/null
+++ b/tests/data/spec-08-14.data
@@ -0,0 +1,5 @@
+- "flow in block"
+- >
+ Block scalar
+- !!map # Block collection
+  foo : bar
diff --git a/tests/data/spec-08-15.canonical b/tests/data/spec-08-15.canonical
new file mode 100644
index 0000000..76f028e
--- /dev/null
+++ b/tests/data/spec-08-15.canonical
@@ -0,0 +1,11 @@
+%YAML 1.1
+---
+!!seq [
+  !!null "",
+  !!map {
+    ? !!str "foo"
+    : !!null "",
+    ? !!null ""
+    : !!str "bar",
+  }
+]
diff --git a/tests/data/spec-08-15.data b/tests/data/spec-08-15.data
new file mode 100644
index 0000000..7c86bcf
--- /dev/null
+++ b/tests/data/spec-08-15.data
@@ -0,0 +1,5 @@
+- # Empty plain scalar
+- ? foo
+  :
+  ?
+  : bar
diff --git a/tests/data/spec-09-01.canonical b/tests/data/spec-09-01.canonical
new file mode 100644
index 0000000..e71a548
--- /dev/null
+++ b/tests/data/spec-09-01.canonical
@@ -0,0 +1,11 @@
+%YAML 1.1
+---
+!!map {
+  ? !!str "simple key"
+  : !!map {
+    ? !!str "also simple"
+    : !!str "value",
+    ? !!str "not a simple key"
+    : !!str "any value"
+  }
+}
diff --git a/tests/data/spec-09-01.data b/tests/data/spec-09-01.data
new file mode 100644
index 0000000..9e83eaf
--- /dev/null
+++ b/tests/data/spec-09-01.data
@@ -0,0 +1,6 @@
+"simple key" : {
+  "also simple" : value,
+  ? "not a
+  simple key" : "any
+  value"
+}
diff --git a/tests/data/spec-09-02.canonical b/tests/data/spec-09-02.canonical
new file mode 100644
index 0000000..6f8f41a
--- /dev/null
+++ b/tests/data/spec-09-02.canonical
@@ -0,0 +1,7 @@
+%YAML 1.1
+---
+!!str "as space \
+  trimmed\n\
+  specific\L\n\
+  escaped\t\n\
+  none"
diff --git a/tests/data/spec-09-02.data b/tests/data/spec-09-02.data
new file mode 100644
index 0000000..d84883d
--- /dev/null
+++ b/tests/data/spec-09-02.data
@@ -0,0 +1,6 @@
+ "as space	
+ trimmed 
+
+ specific

+ escaped	\
 
+ none"
diff --git a/tests/data/spec-09-03.canonical b/tests/data/spec-09-03.canonical
new file mode 100644
index 0000000..658c6df
--- /dev/null
+++ b/tests/data/spec-09-03.canonical
@@ -0,0 +1,7 @@
+%YAML 1.1
+---
+!!seq [
+  !!str " last",
+  !!str " last",
+  !!str " \tfirst last",
+]
diff --git a/tests/data/spec-09-03.data b/tests/data/spec-09-03.data
new file mode 100644
index 0000000..e0b914d
--- /dev/null
+++ b/tests/data/spec-09-03.data
@@ -0,0 +1,6 @@
+- "
+  last"
+- " 	
+  last"
+- " 	first
+  last"
diff --git a/tests/data/spec-09-04.canonical b/tests/data/spec-09-04.canonical
new file mode 100644
index 0000000..fa46632
--- /dev/null
+++ b/tests/data/spec-09-04.canonical
@@ -0,0 +1,6 @@
+%YAML 1.1
+---
+!!str "first \
+  inner 1  \
+  inner 2 \
+  last"
diff --git a/tests/data/spec-09-04.data b/tests/data/spec-09-04.data
new file mode 100644
index 0000000..313a91b
--- /dev/null
+++ b/tests/data/spec-09-04.data
@@ -0,0 +1,4 @@
+ "first
+ 	inner 1	
+ \ inner 2 \
+ last"
diff --git a/tests/data/spec-09-05.canonical b/tests/data/spec-09-05.canonical
new file mode 100644
index 0000000..24d1052
--- /dev/null
+++ b/tests/data/spec-09-05.canonical
@@ -0,0 +1,7 @@
+%YAML 1.1
+---
+!!seq [
+  !!str "first ",
+  !!str "first\nlast",
+  !!str "first inner  \tlast",
+]
diff --git a/tests/data/spec-09-05.data b/tests/data/spec-09-05.data
new file mode 100644
index 0000000..624c30e
--- /dev/null
+++ b/tests/data/spec-09-05.data
@@ -0,0 +1,8 @@
+- "first
+  	"
+- "first
+
+  	last"
+- "first
+ inner
+ \ 	last"
diff --git a/tests/data/spec-09-06.canonical b/tests/data/spec-09-06.canonical
new file mode 100644
index 0000000..5028772
--- /dev/null
+++ b/tests/data/spec-09-06.canonical
@@ -0,0 +1,3 @@
+%YAML 1.1
+---
+!!str "here's to \"quotes\""
diff --git a/tests/data/spec-09-06.data b/tests/data/spec-09-06.data
new file mode 100644
index 0000000..b038078
--- /dev/null
+++ b/tests/data/spec-09-06.data
@@ -0,0 +1 @@
+ 'here''s to "quotes"'
diff --git a/tests/data/spec-09-07.canonical b/tests/data/spec-09-07.canonical
new file mode 100644
index 0000000..e71a548
--- /dev/null
+++ b/tests/data/spec-09-07.canonical
@@ -0,0 +1,11 @@
+%YAML 1.1
+---
+!!map {
+  ? !!str "simple key"
+  : !!map {
+    ? !!str "also simple"
+    : !!str "value",
+    ? !!str "not a simple key"
+    : !!str "any value"
+  }
+}
diff --git a/tests/data/spec-09-07.data b/tests/data/spec-09-07.data
new file mode 100644
index 0000000..755b54a
--- /dev/null
+++ b/tests/data/spec-09-07.data
@@ -0,0 +1,6 @@
+'simple key' : {
+  'also simple' : value,
+  ? 'not a
+  simple key' : 'any
+  value'
+}
diff --git a/tests/data/spec-09-08.canonical b/tests/data/spec-09-08.canonical
new file mode 100644
index 0000000..06abdb5
--- /dev/null
+++ b/tests/data/spec-09-08.canonical
@@ -0,0 +1,6 @@
+%YAML 1.1
+---
+!!str "as space \
+  trimmed\n\
+  specific\L\n\
+  none"
diff --git a/tests/data/spec-09-08.data b/tests/data/spec-09-08.data
new file mode 100644
index 0000000..aa4d458
--- /dev/null
+++ b/tests/data/spec-09-08.data
@@ -0,0 +1 @@
+ 'as space	… trimmed …… specific
… none'
diff --git a/tests/data/spec-09-09.canonical b/tests/data/spec-09-09.canonical
new file mode 100644
index 0000000..658c6df
--- /dev/null
+++ b/tests/data/spec-09-09.canonical
@@ -0,0 +1,7 @@
+%YAML 1.1
+---
+!!seq [
+  !!str " last",
+  !!str " last",
+  !!str " \tfirst last",
+]
diff --git a/tests/data/spec-09-09.data b/tests/data/spec-09-09.data
new file mode 100644
index 0000000..52171df
--- /dev/null
+++ b/tests/data/spec-09-09.data
@@ -0,0 +1,6 @@
+- '
+  last'
+- ' 	
+  last'
+- ' 	first
+  last'
diff --git a/tests/data/spec-09-10.canonical b/tests/data/spec-09-10.canonical
new file mode 100644
index 0000000..2028d04
--- /dev/null
+++ b/tests/data/spec-09-10.canonical
@@ -0,0 +1,5 @@
+%YAML 1.1
+---
+!!str "first \
+  inner \
+  last"
diff --git a/tests/data/spec-09-10.data b/tests/data/spec-09-10.data
new file mode 100644
index 0000000..0e41449
--- /dev/null
+++ b/tests/data/spec-09-10.data
@@ -0,0 +1,3 @@
+ 'first
+ 	inner	
+ last'
diff --git a/tests/data/spec-09-11.canonical b/tests/data/spec-09-11.canonical
new file mode 100644
index 0000000..4eb222c
--- /dev/null
+++ b/tests/data/spec-09-11.canonical
@@ -0,0 +1,6 @@
+%YAML 1.1
+---
+!!seq [
+  !!str "first ",
+  !!str "first\nlast",
+]
diff --git a/tests/data/spec-09-11.data b/tests/data/spec-09-11.data
new file mode 100644
index 0000000..5efa873
--- /dev/null
+++ b/tests/data/spec-09-11.data
@@ -0,0 +1,5 @@
+- 'first
+  	'
+- 'first
+
+  	last'
diff --git a/tests/data/spec-09-12.canonical b/tests/data/spec-09-12.canonical
new file mode 100644
index 0000000..d8e6dce
--- /dev/null
+++ b/tests/data/spec-09-12.canonical
@@ -0,0 +1,12 @@
+%YAML 1.1
+---
+!!seq [
+  !!str "::std::vector",
+  !!str "Up, up, and away!",
+  !!int "-123",
+  !!seq [
+    !!str "::std::vector",
+    !!str "Up, up, and away!",
+    !!int "-123",
+  ]
+]
diff --git a/tests/data/spec-09-12.data b/tests/data/spec-09-12.data
new file mode 100644
index 0000000..b9a3ac5
--- /dev/null
+++ b/tests/data/spec-09-12.data
@@ -0,0 +1,8 @@
+# Outside flow collection:
+- ::std::vector
+- Up, up, and away!
+- -123
+# Inside flow collection:
+- [ '::std::vector',
+  "Up, up, and away!",
+  -123 ]
diff --git a/tests/data/spec-09-13.canonical b/tests/data/spec-09-13.canonical
new file mode 100644
index 0000000..e71a548
--- /dev/null
+++ b/tests/data/spec-09-13.canonical
@@ -0,0 +1,11 @@
+%YAML 1.1
+---
+!!map {
+  ? !!str "simple key"
+  : !!map {
+    ? !!str "also simple"
+    : !!str "value",
+    ? !!str "not a simple key"
+    : !!str "any value"
+  }
+}
diff --git a/tests/data/spec-09-13.data b/tests/data/spec-09-13.data
new file mode 100644
index 0000000..b156386
--- /dev/null
+++ b/tests/data/spec-09-13.data
@@ -0,0 +1,6 @@
+simple key : {
+  also simple : value,
+  ? not a
+  simple key : any
+  value
+}
diff --git a/tests/data/spec-09-14.data b/tests/data/spec-09-14.data
new file mode 100644
index 0000000..97f2316
--- /dev/null
+++ b/tests/data/spec-09-14.data
@@ -0,0 +1,14 @@
+---
+--- ||| : foo
+... >>>: bar
+---
+[
+---
+,
+... ,
+{
+--- :
+... # Nested
+}
+]
+...
diff --git a/tests/data/spec-09-14.error b/tests/data/spec-09-14.error
new file mode 100644
index 0000000..9f3db7b
--- /dev/null
+++ b/tests/data/spec-09-14.error
@@ -0,0 +1,6 @@
+ERROR:
+ The --- and ... document
+ start and end markers must
+ not be specified as the
+ first content line of a
+ non-indented plain scalar.
diff --git a/tests/data/spec-09-15.canonical b/tests/data/spec-09-15.canonical
new file mode 100644
index 0000000..df02040
--- /dev/null
+++ b/tests/data/spec-09-15.canonical
@@ -0,0 +1,18 @@
+%YAML 1.1
+---
+!!map {
+  ? !!str "---"
+  : !!str "foo",
+  ? !!str "..."
+  : !!str "bar"
+}
+%YAML 1.1
+---
+!!seq [
+  !!str "---",
+  !!str "...",
+  !!map {
+    ? !!str "---"
+    : !!str "..."
+  }
+]
diff --git a/tests/data/spec-09-15.data b/tests/data/spec-09-15.data
new file mode 100644
index 0000000..e6863b0
--- /dev/null
+++ b/tests/data/spec-09-15.data
@@ -0,0 +1,13 @@
+---
+"---" : foo
+...: bar
+---
+[
+---,
+...,
+{
+? ---
+: ...
+}
+]
+...
diff --git a/tests/data/spec-09-16.canonical b/tests/data/spec-09-16.canonical
new file mode 100644
index 0000000..06abdb5
--- /dev/null
+++ b/tests/data/spec-09-16.canonical
@@ -0,0 +1,6 @@
+%YAML 1.1
+---
+!!str "as space \
+  trimmed\n\
+  specific\L\n\
+  none"
diff --git a/tests/data/spec-09-16.data b/tests/data/spec-09-16.data
new file mode 100644
index 0000000..473beb9
--- /dev/null
+++ b/tests/data/spec-09-16.data
@@ -0,0 +1,3 @@
+# Tabs are confusing:
+# as space/trimmed/specific/none
+ as space … trimmed …… specific
… none
diff --git a/tests/data/spec-09-17.canonical b/tests/data/spec-09-17.canonical
new file mode 100644
index 0000000..68cb70d
--- /dev/null
+++ b/tests/data/spec-09-17.canonical
@@ -0,0 +1,4 @@
+%YAML 1.1
+---
+!!str "first line\n\
+      more line"
diff --git a/tests/data/spec-09-17.data b/tests/data/spec-09-17.data
new file mode 100644
index 0000000..97bc46c
--- /dev/null
+++ b/tests/data/spec-09-17.data
@@ -0,0 +1,3 @@
+ first line 
+   
+  more line
diff --git a/tests/data/spec-09-18.canonical b/tests/data/spec-09-18.canonical
new file mode 100644
index 0000000..f21428f
--- /dev/null
+++ b/tests/data/spec-09-18.canonical
@@ -0,0 +1,8 @@
+%YAML 1.1
+---
+!!seq [
+  !!str "literal\n",
+  !!str " folded\n",
+  !!str "keep\n\n",
+  !!str " strip",
+]
diff --git a/tests/data/spec-09-18.data b/tests/data/spec-09-18.data
new file mode 100644
index 0000000..68c5d7c
--- /dev/null
+++ b/tests/data/spec-09-18.data
@@ -0,0 +1,9 @@
+- | # Just the style
+ literal
+- >1 # Indentation indicator
+  folded
+- |+ # Chomping indicator
+ keep
+
+- >-1 # Both indicators
+  strip
diff --git a/tests/data/spec-09-19.canonical b/tests/data/spec-09-19.canonical
new file mode 100644
index 0000000..3e828d7
--- /dev/null
+++ b/tests/data/spec-09-19.canonical
@@ -0,0 +1,6 @@
+%YAML 1.1
+---
+!!seq [
+  !!str "literal\n",
+  !!str "folded\n",
+]
diff --git a/tests/data/spec-09-19.data b/tests/data/spec-09-19.data
new file mode 100644
index 0000000..f0e589d
--- /dev/null
+++ b/tests/data/spec-09-19.data
@@ -0,0 +1,4 @@
+- |
+ literal
+- >
+ folded
diff --git a/tests/data/spec-09-20.canonical b/tests/data/spec-09-20.canonical
new file mode 100644
index 0000000..d03bef5
--- /dev/null
+++ b/tests/data/spec-09-20.canonical
@@ -0,0 +1,8 @@
+%YAML 1.1
+---
+!!seq [
+  !!str "detected\n",
+  !!str "\n\n# detected\n",
+  !!str " explicit\n",
+  !!str "\t\ndetected\n",
+]
diff --git a/tests/data/spec-09-20.data b/tests/data/spec-09-20.data
new file mode 100644
index 0000000..39bee04
--- /dev/null
+++ b/tests/data/spec-09-20.data
@@ -0,0 +1,11 @@
+- |
+ detected
+- >
+ 
+  
+  # detected
+- |1
+  explicit
+- >
+ 	
+ detected
diff --git a/tests/data/spec-09-20.skip-ext b/tests/data/spec-09-20.skip-ext
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/tests/data/spec-09-20.skip-ext
diff --git a/tests/data/spec-09-21.data b/tests/data/spec-09-21.data
new file mode 100644
index 0000000..0fdd14f
--- /dev/null
+++ b/tests/data/spec-09-21.data
@@ -0,0 +1,8 @@
+- |
+  
+ text
+- >
+  text
+ text
+- |1
+ text
diff --git a/tests/data/spec-09-21.error b/tests/data/spec-09-21.error
new file mode 100644
index 0000000..1379ca5
--- /dev/null
+++ b/tests/data/spec-09-21.error
@@ -0,0 +1,7 @@
+ERROR:
+- A leading all-space line must
+  not have too many spaces.
+- A following text line must
+  not be less indented.
+- The text is less indented
+  than the indicated level.
diff --git a/tests/data/spec-09-22.canonical b/tests/data/spec-09-22.canonical
new file mode 100644
index 0000000..c1bbcd2
--- /dev/null
+++ b/tests/data/spec-09-22.canonical
@@ -0,0 +1,10 @@
+%YAML 1.1
+---
+!!map {
+  ? !!str "strip"
+  : !!str "text",
+  ? !!str "clip"
+  : !!str "text\n",
+  ? !!str "keep"
+  : !!str "text\L",
+}
diff --git a/tests/data/spec-09-22.data b/tests/data/spec-09-22.data
new file mode 100644
index 0000000..0dd51eb
--- /dev/null
+++ b/tests/data/spec-09-22.data
@@ -0,0 +1,4 @@
+strip: |-
+  text
clip: |
+  text…keep: |+
+  text

\ No newline at end of file
diff --git a/tests/data/spec-09-23.canonical b/tests/data/spec-09-23.canonical
new file mode 100644
index 0000000..c4444ca
--- /dev/null
+++ b/tests/data/spec-09-23.canonical
@@ -0,0 +1,10 @@
+%YAML 1.1
+---
+!!map {
+  ? !!str "strip"
+  : !!str "# text",
+  ? !!str "clip"
+  : !!str "# text\n",
+  ? !!str "keep"
+  : !!str "# text\L\n",
+}
diff --git a/tests/data/spec-09-23.data b/tests/data/spec-09-23.data
new file mode 100644
index 0000000..8972d2b
--- /dev/null
+++ b/tests/data/spec-09-23.data
@@ -0,0 +1,11 @@
+ # Strip
+  # Comments:
+strip: |-
+  # text
  
 # Clip
+  # comments:
+…clip: |
+  # text… 
 # Keep
+  # comments:
+…keep: |+
+  # text
… # Trail
+  # comments.
diff --git a/tests/data/spec-09-24.canonical b/tests/data/spec-09-24.canonical
new file mode 100644
index 0000000..45a99b0
--- /dev/null
+++ b/tests/data/spec-09-24.canonical
@@ -0,0 +1,10 @@
+%YAML 1.1
+---
+!!map {
+  ? !!str "strip"
+  : !!str "",
+  ? !!str "clip"
+  : !!str "",
+  ? !!str "keep"
+  : !!str "\n",
+}
diff --git a/tests/data/spec-09-24.data b/tests/data/spec-09-24.data
new file mode 100644
index 0000000..de0b64b
--- /dev/null
+++ b/tests/data/spec-09-24.data
@@ -0,0 +1,6 @@
+strip: >-
+
+clip: >
+
+keep: |+
+
diff --git a/tests/data/spec-09-25.canonical b/tests/data/spec-09-25.canonical
new file mode 100644
index 0000000..9d2327b
--- /dev/null
+++ b/tests/data/spec-09-25.canonical
@@ -0,0 +1,4 @@
+%YAML 1.1
+---
+!!str "literal\n\
+      \ttext\n"
diff --git a/tests/data/spec-09-25.data b/tests/data/spec-09-25.data
new file mode 100644
index 0000000..f6303a1
--- /dev/null
+++ b/tests/data/spec-09-25.data
@@ -0,0 +1,3 @@
+| # Simple block scalar
+ literal
+ 	text
diff --git a/tests/data/spec-09-26.canonical b/tests/data/spec-09-26.canonical
new file mode 100644
index 0000000..3029a11
--- /dev/null
+++ b/tests/data/spec-09-26.canonical
@@ -0,0 +1,3 @@
+%YAML 1.1
+---
+!!str "\n\nliteral\n\ntext\n"
diff --git a/tests/data/spec-09-26.data b/tests/data/spec-09-26.data
new file mode 100644
index 0000000..f28555a
--- /dev/null
+++ b/tests/data/spec-09-26.data
@@ -0,0 +1,8 @@
+|
+ 
+  
+  literal
+ 
+  text
+
+ # Comment
diff --git a/tests/data/spec-09-27.canonical b/tests/data/spec-09-27.canonical
new file mode 100644
index 0000000..3029a11
--- /dev/null
+++ b/tests/data/spec-09-27.canonical
@@ -0,0 +1,3 @@
+%YAML 1.1
+---
+!!str "\n\nliteral\n\ntext\n"
diff --git a/tests/data/spec-09-27.data b/tests/data/spec-09-27.data
new file mode 100644
index 0000000..f28555a
--- /dev/null
+++ b/tests/data/spec-09-27.data
@@ -0,0 +1,8 @@
+|
+ 
+  
+  literal
+ 
+  text
+
+ # Comment
diff --git a/tests/data/spec-09-28.canonical b/tests/data/spec-09-28.canonical
new file mode 100644
index 0000000..3029a11
--- /dev/null
+++ b/tests/data/spec-09-28.canonical
@@ -0,0 +1,3 @@
+%YAML 1.1
+---
+!!str "\n\nliteral\n\ntext\n"
diff --git a/tests/data/spec-09-28.data b/tests/data/spec-09-28.data
new file mode 100644
index 0000000..f28555a
--- /dev/null
+++ b/tests/data/spec-09-28.data
@@ -0,0 +1,8 @@
+|
+ 
+  
+  literal
+ 
+  text
+
+ # Comment
diff --git a/tests/data/spec-09-29.canonical b/tests/data/spec-09-29.canonical
new file mode 100644
index 0000000..0980789
--- /dev/null
+++ b/tests/data/spec-09-29.canonical
@@ -0,0 +1,4 @@
+%YAML 1.1
+---
+!!str "folded text\n\
+      \tlines\n"
diff --git a/tests/data/spec-09-29.data b/tests/data/spec-09-29.data
new file mode 100644
index 0000000..82e611f
--- /dev/null
+++ b/tests/data/spec-09-29.data
@@ -0,0 +1,4 @@
+> # Simple folded scalar
+ folded
+ text
+ 	lines
diff --git a/tests/data/spec-09-30.canonical b/tests/data/spec-09-30.canonical
new file mode 100644
index 0000000..fc37db1
--- /dev/null
+++ b/tests/data/spec-09-30.canonical
@@ -0,0 +1,7 @@
+%YAML 1.1
+---
+!!str "folded line\n\
+      next line\n\n\
+      \  * bullet\n\
+      \  * list\n\n\
+      last line\n"
diff --git a/tests/data/spec-09-30.data b/tests/data/spec-09-30.data
new file mode 100644
index 0000000..a4d8c36
--- /dev/null
+++ b/tests/data/spec-09-30.data
@@ -0,0 +1,14 @@
+>
+ folded
+ line
+
+ next
+ line
+
+   * bullet
+   * list
+
+ last
+ line
+
+# Comment
diff --git a/tests/data/spec-09-31.canonical b/tests/data/spec-09-31.canonical
new file mode 100644
index 0000000..fc37db1
--- /dev/null
+++ b/tests/data/spec-09-31.canonical
@@ -0,0 +1,7 @@
+%YAML 1.1
+---
+!!str "folded line\n\
+      next line\n\n\
+      \  * bullet\n\
+      \  * list\n\n\
+      last line\n"
diff --git a/tests/data/spec-09-31.data b/tests/data/spec-09-31.data
new file mode 100644
index 0000000..a4d8c36
--- /dev/null
+++ b/tests/data/spec-09-31.data
@@ -0,0 +1,14 @@
+>
+ folded
+ line
+
+ next
+ line
+
+   * bullet
+   * list
+
+ last
+ line
+
+# Comment
diff --git a/tests/data/spec-09-32.canonical b/tests/data/spec-09-32.canonical
new file mode 100644
index 0000000..fc37db1
--- /dev/null
+++ b/tests/data/spec-09-32.canonical
@@ -0,0 +1,7 @@
+%YAML 1.1
+---
+!!str "folded line\n\
+      next line\n\n\
+      \  * bullet\n\
+      \  * list\n\n\
+      last line\n"
diff --git a/tests/data/spec-09-32.data b/tests/data/spec-09-32.data
new file mode 100644
index 0000000..a4d8c36
--- /dev/null
+++ b/tests/data/spec-09-32.data
@@ -0,0 +1,14 @@
+>
+ folded
+ line
+
+ next
+ line
+
+   * bullet
+   * list
+
+ last
+ line
+
+# Comment
diff --git a/tests/data/spec-09-33.canonical b/tests/data/spec-09-33.canonical
new file mode 100644
index 0000000..fc37db1
--- /dev/null
+++ b/tests/data/spec-09-33.canonical
@@ -0,0 +1,7 @@
+%YAML 1.1
+---
+!!str "folded line\n\
+      next line\n\n\
+      \  * bullet\n\
+      \  * list\n\n\
+      last line\n"
diff --git a/tests/data/spec-09-33.data b/tests/data/spec-09-33.data
new file mode 100644
index 0000000..a4d8c36
--- /dev/null
+++ b/tests/data/spec-09-33.data
@@ -0,0 +1,14 @@
+>
+ folded
+ line
+
+ next
+ line
+
+   * bullet
+   * list
+
+ last
+ line
+
+# Comment
diff --git a/tests/data/spec-10-01.canonical b/tests/data/spec-10-01.canonical
new file mode 100644
index 0000000..d08cdd4
--- /dev/null
+++ b/tests/data/spec-10-01.canonical
@@ -0,0 +1,12 @@
+%YAML 1.1
+---
+!!seq [
+  !!seq [
+    !!str "inner",
+    !!str "inner",
+  ],
+  !!seq [
+    !!str "inner",
+    !!str "last",
+  ],
+]
diff --git a/tests/data/spec-10-01.data b/tests/data/spec-10-01.data
new file mode 100644
index 0000000..e668d38
--- /dev/null
+++ b/tests/data/spec-10-01.data
@@ -0,0 +1,2 @@
+- [ inner, inner, ]
+- [inner,last]
diff --git a/tests/data/spec-10-02.canonical b/tests/data/spec-10-02.canonical
new file mode 100644
index 0000000..82fe0d9
--- /dev/null
+++ b/tests/data/spec-10-02.canonical
@@ -0,0 +1,14 @@
+%YAML 1.1
+---
+!!seq [
+  !!str "double quoted",
+  !!str "single quoted",
+  !!str "plain text",
+  !!seq [
+    !!str "nested",
+  ],
+  !!map {
+    ? !!str "single"
+    : !!str "pair"
+  }
+]
diff --git a/tests/data/spec-10-02.data b/tests/data/spec-10-02.data
new file mode 100644
index 0000000..3b23351
--- /dev/null
+++ b/tests/data/spec-10-02.data
@@ -0,0 +1,8 @@
+[
+"double
+ quoted", 'single
+           quoted',
+plain
+ text, [ nested ],
+single: pair ,
+]
diff --git a/tests/data/spec-10-03.canonical b/tests/data/spec-10-03.canonical
new file mode 100644
index 0000000..1443395
--- /dev/null
+++ b/tests/data/spec-10-03.canonical
@@ -0,0 +1,12 @@
+%YAML 1.1
+---
+!!map {
+  ? !!str "block"
+  : !!seq [
+    !!str "one",
+    !!map {
+      ? !!str "two"
+      : !!str "three"
+    }
+  ]
+}
diff --git a/tests/data/spec-10-03.data b/tests/data/spec-10-03.data
new file mode 100644
index 0000000..9e15f83
--- /dev/null
+++ b/tests/data/spec-10-03.data
@@ -0,0 +1,4 @@
+block: # Block
+       # sequence
+- one
+- two : three
diff --git a/tests/data/spec-10-04.canonical b/tests/data/spec-10-04.canonical
new file mode 100644
index 0000000..ae486a3
--- /dev/null
+++ b/tests/data/spec-10-04.canonical
@@ -0,0 +1,11 @@
+%YAML 1.1
+---
+!!map {
+  ? !!str "block"
+  : !!seq [
+    !!str "one",
+    !!seq [
+      !!str "two"
+    ]
+  ]
+}
diff --git a/tests/data/spec-10-04.data b/tests/data/spec-10-04.data
new file mode 100644
index 0000000..2905b0d
--- /dev/null
+++ b/tests/data/spec-10-04.data
@@ -0,0 +1,4 @@
+block:
+- one
+-
+ - two
diff --git a/tests/data/spec-10-05.canonical b/tests/data/spec-10-05.canonical
new file mode 100644
index 0000000..07cc0c9
--- /dev/null
+++ b/tests/data/spec-10-05.canonical
@@ -0,0 +1,14 @@
+%YAML 1.1
+---
+!!seq [
+  !!null "",
+  !!str "block node\n",
+  !!seq [
+    !!str "one",
+    !!str "two",
+  ],
+  !!map {
+    ? !!str "one"
+    : !!str "two",
+  }
+]
diff --git a/tests/data/spec-10-05.data b/tests/data/spec-10-05.data
new file mode 100644
index 0000000..f19a99e
--- /dev/null
+++ b/tests/data/spec-10-05.data
@@ -0,0 +1,7 @@
+- # Empty
+- |
+ block node
+- - one # in-line
+  - two # sequence
+- one: two # in-line
+           # mapping
diff --git a/tests/data/spec-10-06.canonical b/tests/data/spec-10-06.canonical
new file mode 100644
index 0000000..d9986c2
--- /dev/null
+++ b/tests/data/spec-10-06.canonical
@@ -0,0 +1,16 @@
+%YAML 1.1
+---
+!!seq [
+  !!map {
+    ? !!str "inner"
+    : !!str "entry",
+    ? !!str "also"
+    : !!str "inner"
+  },
+  !!map {
+    ? !!str "inner"
+    : !!str "entry",
+    ? !!str "last"
+    : !!str "entry"
+  }
+]
diff --git a/tests/data/spec-10-06.data b/tests/data/spec-10-06.data
new file mode 100644
index 0000000..860ba25
--- /dev/null
+++ b/tests/data/spec-10-06.data
@@ -0,0 +1,2 @@
+- { inner : entry , also: inner , }
+- {inner: entry,last : entry}
diff --git a/tests/data/spec-10-07.canonical b/tests/data/spec-10-07.canonical
new file mode 100644
index 0000000..ec74230
--- /dev/null
+++ b/tests/data/spec-10-07.canonical
@@ -0,0 +1,16 @@
+%YAML 1.1
+---
+!!map {
+  ? !!null ""
+  : !!str "value",
+  ? !!str "explicit key"
+  : !!str "value",
+  ? !!str "simple key"
+  : !!str "value",
+  ? !!seq [
+    !!str "collection",
+    !!str "simple",
+    !!str "key"
+  ]
+  : !!str "value"
+}
diff --git a/tests/data/spec-10-07.data b/tests/data/spec-10-07.data
new file mode 100644
index 0000000..ff943fb
--- /dev/null
+++ b/tests/data/spec-10-07.data
@@ -0,0 +1,7 @@
+{
+? : value, # Empty key
+? explicit
+ key: value,
+simple key : value,
+[ collection, simple, key ]: value
+}
diff --git a/tests/data/spec-10-08.data b/tests/data/spec-10-08.data
new file mode 100644
index 0000000..55bd788
--- /dev/null
+++ b/tests/data/spec-10-08.data
@@ -0,0 +1,5 @@
+{
+multi-line
+ simple key : value,
+very long ...................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................(>1KB)................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................... key: value
+}
diff --git a/tests/data/spec-10-08.error b/tests/data/spec-10-08.error
new file mode 100644
index 0000000..3979e1f
--- /dev/null
+++ b/tests/data/spec-10-08.error
@@ -0,0 +1,5 @@
+ERROR:
+- A simple key is restricted
+  to only one line.
+- A simple key must not be
+  longer than 1024 characters.
diff --git a/tests/data/spec-10-09.canonical b/tests/data/spec-10-09.canonical
new file mode 100644
index 0000000..4d9827b
--- /dev/null
+++ b/tests/data/spec-10-09.canonical
@@ -0,0 +1,8 @@
+%YAML 1.1
+---
+!!map {
+  ? !!str "key"
+  : !!str "value",
+  ? !!str "empty"
+  : !!null "",
+}
diff --git a/tests/data/spec-10-09.data b/tests/data/spec-10-09.data
new file mode 100644
index 0000000..4d55e21
--- /dev/null
+++ b/tests/data/spec-10-09.data
@@ -0,0 +1,4 @@
+{
+key : value,
+empty: # empty value↓
+}
diff --git a/tests/data/spec-10-10.canonical b/tests/data/spec-10-10.canonical
new file mode 100644
index 0000000..016fb64
--- /dev/null
+++ b/tests/data/spec-10-10.canonical
@@ -0,0 +1,16 @@
+%YAML 1.1
+---
+!!map {
+  ? !!str "explicit key1"
+  : !!str "explicit value",
+  ? !!str "explicit key2"
+  : !!null "",
+  ? !!str "explicit key3"
+  : !!null "",
+  ? !!str "simple key1"
+  : !!str "explicit value",
+  ? !!str "simple key2"
+  : !!null "",
+  ? !!str "simple key3"
+  : !!null "",
+}
diff --git a/tests/data/spec-10-10.data b/tests/data/spec-10-10.data
new file mode 100644
index 0000000..0888b05
--- /dev/null
+++ b/tests/data/spec-10-10.data
@@ -0,0 +1,8 @@
+{
+? explicit key1 : explicit value,
+? explicit key2 : , # Explicit empty
+? explicit key3,     # Empty value
+simple key1 : explicit value,
+simple key2 : ,     # Explicit empty
+simple key3,         # Empty value
+}
diff --git a/tests/data/spec-10-11.canonical b/tests/data/spec-10-11.canonical
new file mode 100644
index 0000000..7309544
--- /dev/null
+++ b/tests/data/spec-10-11.canonical
@@ -0,0 +1,24 @@
+%YAML 1.1
+---
+!!seq [
+  !!map {
+    ? !!str "explicit key1"
+    : !!str "explicit value",
+  },
+  !!map {
+    ? !!str "explicit key2"
+    : !!null "",
+  },
+  !!map {
+    ? !!str "explicit key3"
+    : !!null "",
+  },
+  !!map {
+    ? !!str "simple key1"
+    : !!str "explicit value",
+  },
+  !!map {
+    ? !!str "simple key2"
+    : !!null "",
+  },
+]
diff --git a/tests/data/spec-10-11.data b/tests/data/spec-10-11.data
new file mode 100644
index 0000000..9f05568
--- /dev/null
+++ b/tests/data/spec-10-11.data
@@ -0,0 +1,7 @@
+[
+? explicit key1 : explicit value,
+? explicit key2 : , # Explicit empty
+? explicit key3,     # Implicit empty
+simple key1 : explicit value,
+simple key2 : ,     # Explicit empty
+]
diff --git a/tests/data/spec-10-12.canonical b/tests/data/spec-10-12.canonical
new file mode 100644
index 0000000..a95dd40
--- /dev/null
+++ b/tests/data/spec-10-12.canonical
@@ -0,0 +1,9 @@
+%YAML 1.1
+---
+!!map {
+  ? !!str "block"
+  : !!map {
+    ? !!str "key"
+    : !!str "value"
+  }
+}
diff --git a/tests/data/spec-10-12.data b/tests/data/spec-10-12.data
new file mode 100644
index 0000000..5521443
--- /dev/null
+++ b/tests/data/spec-10-12.data
@@ -0,0 +1,3 @@
+block: # Block
+    # mapping
+ key: value
diff --git a/tests/data/spec-10-13.canonical b/tests/data/spec-10-13.canonical
new file mode 100644
index 0000000..e183c50
--- /dev/null
+++ b/tests/data/spec-10-13.canonical
@@ -0,0 +1,11 @@
+%YAML 1.1
+---
+!!map {
+  ? !!str "explicit key"
+  : !!null "",
+  ? !!str "block key\n"
+  : !!seq [
+    !!str "one",
+    !!str "two",
+  ]
+}
diff --git a/tests/data/spec-10-13.data b/tests/data/spec-10-13.data
new file mode 100644
index 0000000..b5b97db
--- /dev/null
+++ b/tests/data/spec-10-13.data
@@ -0,0 +1,5 @@
+? explicit key # implicit value
+? |
+  block key
+: - one # explicit in-line
+  - two # block value
diff --git a/tests/data/spec-10-14.canonical b/tests/data/spec-10-14.canonical
new file mode 100644
index 0000000..e87c880
--- /dev/null
+++ b/tests/data/spec-10-14.canonical
@@ -0,0 +1,11 @@
+%YAML 1.1
+---
+!!map {
+  ? !!str "plain key"
+  : !!null "",
+  ? !!str "quoted key"
+  : !!seq [
+    !!str "one",
+    !!str "two",
+  ]
+}
diff --git a/tests/data/spec-10-14.data b/tests/data/spec-10-14.data
new file mode 100644
index 0000000..7f5995c
--- /dev/null
+++ b/tests/data/spec-10-14.data
@@ -0,0 +1,4 @@
+plain key: # empty value
+"quoted key":
+- one # explicit next-line
+- two # block value
diff --git a/tests/data/spec-10-15.canonical b/tests/data/spec-10-15.canonical
new file mode 100644
index 0000000..85fbbd0
--- /dev/null
+++ b/tests/data/spec-10-15.canonical
@@ -0,0 +1,18 @@
+%YAML 1.1
+---
+!!seq [
+  !!map {
+    ? !!str "sun"
+    : !!str "yellow"
+  },
+  !!map {
+    ? !!map {
+      ? !!str "earth"
+      : !!str "blue"
+    }
+    : !!map {
+      ? !!str "moon"
+      : !!str "white"
+    }
+  }
+]
diff --git a/tests/data/spec-10-15.data b/tests/data/spec-10-15.data
new file mode 100644
index 0000000..d675cfd
--- /dev/null
+++ b/tests/data/spec-10-15.data
@@ -0,0 +1,3 @@
+- sun: yellow
+- ? earth: blue
+  : moon: white
diff --git a/tests/data/str.data b/tests/data/str.data
new file mode 100644
index 0000000..7cbdb7c
--- /dev/null
+++ b/tests/data/str.data
@@ -0,0 +1 @@
+- abcd
diff --git a/tests/data/str.detect b/tests/data/str.detect
new file mode 100644
index 0000000..7d5026f
--- /dev/null
+++ b/tests/data/str.detect
@@ -0,0 +1 @@
+tag:yaml.org,2002:str
diff --git a/tests/data/tags.events b/tests/data/tags.events
new file mode 100644
index 0000000..bb93dce
--- /dev/null
+++ b/tests/data/tags.events
@@ -0,0 +1,12 @@
+- !StreamStart
+- !DocumentStart
+- !SequenceStart
+- !Scalar { value: 'data' }
+#- !Scalar { tag: '!', value: 'data' }
+- !Scalar { tag: 'tag:yaml.org,2002:str', value: 'data' }
+- !Scalar { tag: '!myfunnytag', value: 'data' }
+- !Scalar { tag: '!my!ugly!tag', value: 'data' }
+- !Scalar { tag: 'tag:my.domain.org,2002:data!? #', value: 'data' }
+- !SequenceEnd
+- !DocumentEnd
+- !StreamEnd
diff --git a/tests/data/test_mark.marks b/tests/data/test_mark.marks
new file mode 100644
index 0000000..7b08ee4
--- /dev/null
+++ b/tests/data/test_mark.marks
@@ -0,0 +1,38 @@
+---
+*The first line.
+The last line.
+---
+The first*line.
+The last line.
+---
+The first line.*
+The last line.
+---
+The first line.
+*The last line.
+---
+The first line.
+The last*line.
+---
+The first line.
+The last line.*
+---
+The first line.
+*The selected line.
+The last line.
+---
+The first line.
+The selected*line.
+The last line.
+---
+The first line.
+The selected line.*
+The last line.
+---
+*The only line.
+---
+The only*line.
+---
+The only line.*
+---
+Loooooooooooooooooooooooooooooooooooooooooooooong*Liiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiine
diff --git a/tests/data/timestamp-bugs.code b/tests/data/timestamp-bugs.code
new file mode 100644
index 0000000..b1d6e9c
--- /dev/null
+++ b/tests/data/timestamp-bugs.code
@@ -0,0 +1,8 @@
+[
+    datetime.datetime(2001, 12, 15, 3, 29, 43, 100000),
+    datetime.datetime(2001, 12, 14, 16, 29, 43, 100000),
+    datetime.datetime(2001, 12, 14, 21, 59, 43, 1010),
+    datetime.datetime(2001, 12, 14, 21, 59, 43, 0, FixedOffset(60, "+1")),
+    datetime.datetime(2001, 12, 14, 21, 59, 43, 0, FixedOffset(-90, "-1:30")),
+    datetime.datetime(2005, 7, 8, 17, 35, 4, 517600),
+]
diff --git a/tests/data/timestamp-bugs.data b/tests/data/timestamp-bugs.data
new file mode 100644
index 0000000..721d290
--- /dev/null
+++ b/tests/data/timestamp-bugs.data
@@ -0,0 +1,6 @@
+- 2001-12-14 21:59:43.10 -5:30
+- 2001-12-14 21:59:43.10 +5:30
+- 2001-12-14 21:59:43.00101
+- 2001-12-14 21:59:43+1
+- 2001-12-14 21:59:43-1:30
+- 2005-07-08 17:35:04.517600
diff --git a/tests/data/timestamp.data b/tests/data/timestamp.data
new file mode 100644
index 0000000..7d214ce
--- /dev/null
+++ b/tests/data/timestamp.data
@@ -0,0 +1,5 @@
+- 2001-12-15T02:59:43.1Z
+- 2001-12-14t21:59:43.10-05:00
+- 2001-12-14 21:59:43.10 -5
+- 2001-12-15 2:59:43.10
+- 2002-12-14
diff --git a/tests/data/timestamp.detect b/tests/data/timestamp.detect
new file mode 100644
index 0000000..2013936
--- /dev/null
+++ b/tests/data/timestamp.detect
@@ -0,0 +1 @@
+tag:yaml.org,2002:timestamp
diff --git a/tests/data/unacceptable-key.loader-error b/tests/data/unacceptable-key.loader-error
new file mode 100644
index 0000000..d748e37
--- /dev/null
+++ b/tests/data/unacceptable-key.loader-error
@@ -0,0 +1,4 @@
+---
+? - foo
+  - bar
+: baz
diff --git a/tests/data/unclosed-bracket.loader-error b/tests/data/unclosed-bracket.loader-error
new file mode 100644
index 0000000..8c82077
--- /dev/null
+++ b/tests/data/unclosed-bracket.loader-error
@@ -0,0 +1,6 @@
+test:
+    - [ foo: bar
+# comment the rest of the stream to let the scanner detect the problem.
+#    - baz
+#"we could have detected the unclosed bracket on the above line, but this would forbid such syntax as": {
+#}
diff --git a/tests/data/unclosed-quoted-scalar.loader-error b/tests/data/unclosed-quoted-scalar.loader-error
new file mode 100644
index 0000000..8537429
--- /dev/null
+++ b/tests/data/unclosed-quoted-scalar.loader-error
@@ -0,0 +1,2 @@
+'foo
+ bar
diff --git a/tests/data/undefined-anchor.loader-error b/tests/data/undefined-anchor.loader-error
new file mode 100644
index 0000000..9469103
--- /dev/null
+++ b/tests/data/undefined-anchor.loader-error
@@ -0,0 +1,3 @@
+- foo
+- &bar baz
+- *bat
diff --git a/tests/data/undefined-constructor.loader-error b/tests/data/undefined-constructor.loader-error
new file mode 100644
index 0000000..9a37ccc
--- /dev/null
+++ b/tests/data/undefined-constructor.loader-error
@@ -0,0 +1 @@
+--- !foo bar
diff --git a/tests/data/undefined-tag-handle.loader-error b/tests/data/undefined-tag-handle.loader-error
new file mode 100644
index 0000000..82ba335
--- /dev/null
+++ b/tests/data/undefined-tag-handle.loader-error
@@ -0,0 +1 @@
+--- !foo!bar    baz
diff --git a/tests/data/unknown.dumper-error b/tests/data/unknown.dumper-error
new file mode 100644
index 0000000..83204d2
--- /dev/null
+++ b/tests/data/unknown.dumper-error
@@ -0,0 +1 @@
+yaml.safe_dump(object)
diff --git a/tests/data/unsupported-version.emitter-error b/tests/data/unsupported-version.emitter-error
new file mode 100644
index 0000000..f9c6197
--- /dev/null
+++ b/tests/data/unsupported-version.emitter-error
@@ -0,0 +1,5 @@
+- !StreamStart
+- !DocumentStart { version: [5,6] }
+- !Scalar { value: foo }
+- !DocumentEnd
+- !StreamEnd
diff --git a/tests/data/utf16be.code b/tests/data/utf16be.code
new file mode 100644
index 0000000..c45b371
--- /dev/null
+++ b/tests/data/utf16be.code
@@ -0,0 +1 @@
+"UTF-16-BE"
diff --git a/tests/data/utf16be.data b/tests/data/utf16be.data
new file mode 100644
index 0000000..50dcfae
--- /dev/null
+++ b/tests/data/utf16be.data
Binary files differ
diff --git a/tests/data/utf16le.code b/tests/data/utf16le.code
new file mode 100644
index 0000000..400530a
--- /dev/null
+++ b/tests/data/utf16le.code
@@ -0,0 +1 @@
+"UTF-16-LE"
diff --git a/tests/data/utf16le.data b/tests/data/utf16le.data
new file mode 100644
index 0000000..76f5e73
--- /dev/null
+++ b/tests/data/utf16le.data
Binary files differ
diff --git a/tests/data/utf8-implicit.code b/tests/data/utf8-implicit.code
new file mode 100644
index 0000000..29326db
--- /dev/null
+++ b/tests/data/utf8-implicit.code
@@ -0,0 +1 @@
+"implicit UTF-8"
diff --git a/tests/data/utf8-implicit.data b/tests/data/utf8-implicit.data
new file mode 100644
index 0000000..9d8081e
--- /dev/null
+++ b/tests/data/utf8-implicit.data
@@ -0,0 +1 @@
+--- implicit UTF-8
diff --git a/tests/data/utf8.code b/tests/data/utf8.code
new file mode 100644
index 0000000..dcf11cc
--- /dev/null
+++ b/tests/data/utf8.code
@@ -0,0 +1 @@
+"UTF-8"
diff --git a/tests/data/utf8.data b/tests/data/utf8.data
new file mode 100644
index 0000000..686f48a
--- /dev/null
+++ b/tests/data/utf8.data
@@ -0,0 +1 @@
+--- UTF-8
diff --git a/tests/data/value.data b/tests/data/value.data
new file mode 100644
index 0000000..c5b7680
--- /dev/null
+++ b/tests/data/value.data
@@ -0,0 +1 @@
+- =
diff --git a/tests/data/value.detect b/tests/data/value.detect
new file mode 100644
index 0000000..7c37d02
--- /dev/null
+++ b/tests/data/value.detect
@@ -0,0 +1 @@
+tag:yaml.org,2002:value
diff --git a/tests/data/yaml.data b/tests/data/yaml.data
new file mode 100644
index 0000000..a4bb3f8
--- /dev/null
+++ b/tests/data/yaml.data
@@ -0,0 +1,3 @@
+- !!yaml '!'
+- !!yaml '&'
+- !!yaml '*'
diff --git a/tests/data/yaml.detect b/tests/data/yaml.detect
new file mode 100644
index 0000000..e2cf189
--- /dev/null
+++ b/tests/data/yaml.detect
@@ -0,0 +1 @@
+tag:yaml.org,2002:yaml
diff --git a/tests/lib/canonical.py b/tests/lib/canonical.py
new file mode 100644
index 0000000..020e6db
--- /dev/null
+++ b/tests/lib/canonical.py
@@ -0,0 +1,360 @@
+
+import yaml, yaml.composer, yaml.constructor, yaml.resolver
+
+class CanonicalError(yaml.YAMLError):
+    pass
+
+class CanonicalScanner:
+
+    def __init__(self, data):
+        try:
+            self.data = unicode(data, 'utf-8')+u'\0'
+        except UnicodeDecodeError:
+            raise CanonicalError("utf-8 stream is expected")
+        self.index = 0
+        self.tokens = []
+        self.scanned = False
+
+    def check_token(self, *choices):
+        if not self.scanned:
+            self.scan()
+        if self.tokens:
+            if not choices:
+                return True
+            for choice in choices:
+                if isinstance(self.tokens[0], choice):
+                    return True
+        return False
+
+    def peek_token(self):
+        if not self.scanned:
+            self.scan()
+        if self.tokens:
+            return self.tokens[0]
+
+    def get_token(self, choice=None):
+        if not self.scanned:
+            self.scan()
+        token = self.tokens.pop(0)
+        if choice and not isinstance(token, choice):
+            raise CanonicalError("unexpected token "+repr(token))
+        return token
+
+    def get_token_value(self):
+        token = self.get_token()
+        return token.value
+
+    def scan(self):
+        self.tokens.append(yaml.StreamStartToken(None, None))
+        while True:
+            self.find_token()
+            ch = self.data[self.index]
+            if ch == u'\0':
+                self.tokens.append(yaml.StreamEndToken(None, None))
+                break
+            elif ch == u'%':
+                self.tokens.append(self.scan_directive())
+            elif ch == u'-' and self.data[self.index:self.index+3] == u'---':
+                self.index += 3
+                self.tokens.append(yaml.DocumentStartToken(None, None))
+            elif ch == u'[':
+                self.index += 1
+                self.tokens.append(yaml.FlowSequenceStartToken(None, None))
+            elif ch == u'{':
+                self.index += 1
+                self.tokens.append(yaml.FlowMappingStartToken(None, None))
+            elif ch == u']':
+                self.index += 1
+                self.tokens.append(yaml.FlowSequenceEndToken(None, None))
+            elif ch == u'}':
+                self.index += 1
+                self.tokens.append(yaml.FlowMappingEndToken(None, None))
+            elif ch == u'?':
+                self.index += 1
+                self.tokens.append(yaml.KeyToken(None, None))
+            elif ch == u':':
+                self.index += 1
+                self.tokens.append(yaml.ValueToken(None, None))
+            elif ch == u',':
+                self.index += 1
+                self.tokens.append(yaml.FlowEntryToken(None, None))
+            elif ch == u'*' or ch == u'&':
+                self.tokens.append(self.scan_alias())
+            elif ch == u'!':
+                self.tokens.append(self.scan_tag())
+            elif ch == u'"':
+                self.tokens.append(self.scan_scalar())
+            else:
+                raise CanonicalError("invalid token")
+        self.scanned = True
+
+    DIRECTIVE = u'%YAML 1.1'
+
+    def scan_directive(self):
+        if self.data[self.index:self.index+len(self.DIRECTIVE)] == self.DIRECTIVE and \
+                self.data[self.index+len(self.DIRECTIVE)] in u' \n\0':
+            self.index += len(self.DIRECTIVE)
+            return yaml.DirectiveToken('YAML', (1, 1), None, None)
+        else:
+            raise CanonicalError("invalid directive")
+
+    def scan_alias(self):
+        if self.data[self.index] == u'*':
+            TokenClass = yaml.AliasToken
+        else:
+            TokenClass = yaml.AnchorToken
+        self.index += 1
+        start = self.index
+        while self.data[self.index] not in u', \n\0':
+            self.index += 1
+        value = self.data[start:self.index]
+        return TokenClass(value, None, None)
+
+    def scan_tag(self):
+        self.index += 1
+        start = self.index
+        while self.data[self.index] not in u' \n\0':
+            self.index += 1
+        value = self.data[start:self.index]
+        if not value:
+            value = u'!'
+        elif value[0] == u'!':
+            value = 'tag:yaml.org,2002:'+value[1:]
+        elif value[0] == u'<' and value[-1] == u'>':
+            value = value[1:-1]
+        else:
+            value = u'!'+value
+        return yaml.TagToken(value, None, None)
+
+    QUOTE_CODES = {
+        'x': 2,
+        'u': 4,
+        'U': 8,
+    }
+
+    QUOTE_REPLACES = {
+        u'\\': u'\\',
+        u'\"': u'\"',
+        u' ': u' ',
+        u'a': u'\x07',
+        u'b': u'\x08',
+        u'e': u'\x1B',
+        u'f': u'\x0C',
+        u'n': u'\x0A',
+        u'r': u'\x0D',
+        u't': u'\x09',
+        u'v': u'\x0B',
+        u'N': u'\u0085',
+        u'L': u'\u2028',
+        u'P': u'\u2029',
+        u'_': u'_',
+        u'0': u'\x00',
+
+    }
+
+    def scan_scalar(self):
+        self.index += 1
+        chunks = []
+        start = self.index
+        ignore_spaces = False
+        while self.data[self.index] != u'"':
+            if self.data[self.index] == u'\\':
+                ignore_spaces = False
+                chunks.append(self.data[start:self.index])
+                self.index += 1
+                ch = self.data[self.index]
+                self.index += 1
+                if ch == u'\n':
+                    ignore_spaces = True
+                elif ch in self.QUOTE_CODES:
+                    length = self.QUOTE_CODES[ch]
+                    code = int(self.data[self.index:self.index+length], 16)
+                    chunks.append(unichr(code))
+                    self.index += length
+                else:
+                    if ch not in self.QUOTE_REPLACES:
+                        raise CanonicalError("invalid escape code")
+                    chunks.append(self.QUOTE_REPLACES[ch])
+                start = self.index
+            elif self.data[self.index] == u'\n':
+                chunks.append(self.data[start:self.index])
+                chunks.append(u' ')
+                self.index += 1
+                start = self.index
+                ignore_spaces = True
+            elif ignore_spaces and self.data[self.index] == u' ':
+                self.index += 1
+                start = self.index
+            else:
+                ignore_spaces = False
+                self.index += 1
+        chunks.append(self.data[start:self.index])
+        self.index += 1
+        return yaml.ScalarToken(u''.join(chunks), False, None, None)
+
+    def find_token(self):
+        found = False
+        while not found:
+            while self.data[self.index] in u' \t':
+                self.index += 1
+            if self.data[self.index] == u'#':
+                while self.data[self.index] != u'\n':
+                    self.index += 1
+            if self.data[self.index] == u'\n':
+                self.index += 1
+            else:
+                found = True
+
+class CanonicalParser:
+
+    def __init__(self):
+        self.events = []
+        self.parsed = False
+
+    def dispose(self):
+        pass
+
+    # stream: STREAM-START document* STREAM-END
+    def parse_stream(self):
+        self.get_token(yaml.StreamStartToken)
+        self.events.append(yaml.StreamStartEvent(None, None))
+        while not self.check_token(yaml.StreamEndToken):
+            if self.check_token(yaml.DirectiveToken, yaml.DocumentStartToken):
+                self.parse_document()
+            else:
+                raise CanonicalError("document is expected, got "+repr(self.tokens[0]))
+        self.get_token(yaml.StreamEndToken)
+        self.events.append(yaml.StreamEndEvent(None, None))
+
+    # document: DIRECTIVE? DOCUMENT-START node
+    def parse_document(self):
+        node = None
+        if self.check_token(yaml.DirectiveToken):
+            self.get_token(yaml.DirectiveToken)
+        self.get_token(yaml.DocumentStartToken)
+        self.events.append(yaml.DocumentStartEvent(None, None))
+        self.parse_node()
+        self.events.append(yaml.DocumentEndEvent(None, None))
+
+    # node: ALIAS | ANCHOR? TAG? (SCALAR|sequence|mapping)
+    def parse_node(self):
+        if self.check_token(yaml.AliasToken):
+            self.events.append(yaml.AliasEvent(self.get_token_value(), None, None))
+        else:
+            anchor = None
+            if self.check_token(yaml.AnchorToken):
+                anchor = self.get_token_value()
+            tag = None
+            if self.check_token(yaml.TagToken):
+                tag = self.get_token_value()
+            if self.check_token(yaml.ScalarToken):
+                self.events.append(yaml.ScalarEvent(anchor, tag, (False, False), self.get_token_value(), None, None))
+            elif self.check_token(yaml.FlowSequenceStartToken):
+                self.events.append(yaml.SequenceStartEvent(anchor, tag, None, None))
+                self.parse_sequence()
+            elif self.check_token(yaml.FlowMappingStartToken):
+                self.events.append(yaml.MappingStartEvent(anchor, tag, None, None))
+                self.parse_mapping()
+            else:
+                raise CanonicalError("SCALAR, '[', or '{' is expected, got "+repr(self.tokens[0]))
+
+    # sequence: SEQUENCE-START (node (ENTRY node)*)? ENTRY? SEQUENCE-END
+    def parse_sequence(self):
+        self.get_token(yaml.FlowSequenceStartToken)
+        if not self.check_token(yaml.FlowSequenceEndToken):
+            self.parse_node()
+            while not self.check_token(yaml.FlowSequenceEndToken):
+                self.get_token(yaml.FlowEntryToken)
+                if not self.check_token(yaml.FlowSequenceEndToken):
+                    self.parse_node()
+        self.get_token(yaml.FlowSequenceEndToken)
+        self.events.append(yaml.SequenceEndEvent(None, None))
+
+    # mapping: MAPPING-START (map_entry (ENTRY map_entry)*)? ENTRY? MAPPING-END
+    def parse_mapping(self):
+        self.get_token(yaml.FlowMappingStartToken)
+        if not self.check_token(yaml.FlowMappingEndToken):
+            self.parse_map_entry()
+            while not self.check_token(yaml.FlowMappingEndToken):
+                self.get_token(yaml.FlowEntryToken)
+                if not self.check_token(yaml.FlowMappingEndToken):
+                    self.parse_map_entry()
+        self.get_token(yaml.FlowMappingEndToken)
+        self.events.append(yaml.MappingEndEvent(None, None))
+
+    # map_entry: KEY node VALUE node
+    def parse_map_entry(self):
+        self.get_token(yaml.KeyToken)
+        self.parse_node()
+        self.get_token(yaml.ValueToken)
+        self.parse_node()
+
+    def parse(self):
+        self.parse_stream()
+        self.parsed = True
+
+    def get_event(self):
+        if not self.parsed:
+            self.parse()
+        return self.events.pop(0)
+
+    def check_event(self, *choices):
+        if not self.parsed:
+            self.parse()
+        if self.events:
+            if not choices:
+                return True
+            for choice in choices:
+                if isinstance(self.events[0], choice):
+                    return True
+        return False
+
+    def peek_event(self):
+        if not self.parsed:
+            self.parse()
+        return self.events[0]
+
+class CanonicalLoader(CanonicalScanner, CanonicalParser,
+        yaml.composer.Composer, yaml.constructor.Constructor, yaml.resolver.Resolver):
+
+    def __init__(self, stream):
+        if hasattr(stream, 'read'):
+            stream = stream.read()
+        CanonicalScanner.__init__(self, stream)
+        CanonicalParser.__init__(self)
+        yaml.composer.Composer.__init__(self)
+        yaml.constructor.Constructor.__init__(self)
+        yaml.resolver.Resolver.__init__(self)
+
+yaml.CanonicalLoader = CanonicalLoader
+
+def canonical_scan(stream):
+    return yaml.scan(stream, Loader=CanonicalLoader)
+
+yaml.canonical_scan = canonical_scan
+
+def canonical_parse(stream):
+    return yaml.parse(stream, Loader=CanonicalLoader)
+
+yaml.canonical_parse = canonical_parse
+
+def canonical_compose(stream):
+    return yaml.compose(stream, Loader=CanonicalLoader)
+
+yaml.canonical_compose = canonical_compose
+
+def canonical_compose_all(stream):
+    return yaml.compose_all(stream, Loader=CanonicalLoader)
+
+yaml.canonical_compose_all = canonical_compose_all
+
+def canonical_load(stream):
+    return yaml.load(stream, Loader=CanonicalLoader)
+
+yaml.canonical_load = canonical_load
+
+def canonical_load_all(stream):
+    return yaml.load_all(stream, Loader=CanonicalLoader)
+
+yaml.canonical_load_all = canonical_load_all
+
diff --git a/tests/lib/test_all.py b/tests/lib/test_all.py
new file mode 100644
index 0000000..fec4ae4
--- /dev/null
+++ b/tests/lib/test_all.py
@@ -0,0 +1,15 @@
+
+import sys, yaml, test_appliance
+
+def main(args=None):
+    collections = []
+    import test_yaml
+    collections.append(test_yaml)
+    if yaml.__with_libyaml__:
+        import test_yaml_ext
+        collections.append(test_yaml_ext)
+    test_appliance.run(collections, args)
+
+if __name__ == '__main__':
+    main()
+
diff --git a/tests/lib/test_appliance.py b/tests/lib/test_appliance.py
new file mode 100644
index 0000000..d50d5a2
--- /dev/null
+++ b/tests/lib/test_appliance.py
@@ -0,0 +1,151 @@
+
+import sys, os, os.path, types, traceback, pprint
+
+DATA = 'tests/data'
+
+def find_test_functions(collections):
+    if not isinstance(collections, list):
+        collections = [collections]
+    functions = []
+    for collection in collections:
+        if not isinstance(collection, dict):
+            collection = vars(collection)
+        keys = collection.keys()
+        keys.sort()
+        for key in keys:
+            value = collection[key]
+            if isinstance(value, types.FunctionType) and hasattr(value, 'unittest'):
+                functions.append(value)
+    return functions
+
+def find_test_filenames(directory):
+    filenames = {}
+    for filename in os.listdir(directory):
+        if os.path.isfile(os.path.join(directory, filename)):
+            base, ext = os.path.splitext(filename)
+            if base.endswith('-py3'):
+                continue
+            filenames.setdefault(base, []).append(ext)
+    filenames = filenames.items()
+    filenames.sort()
+    return filenames
+
+def parse_arguments(args):
+    if args is None:
+        args = sys.argv[1:]
+    verbose = False
+    if '-v' in args:
+        verbose = True
+        args.remove('-v')
+    if '--verbose' in args:
+        verbose = True
+    if 'YAML_TEST_VERBOSE' in os.environ:
+        verbose = True
+    include_functions = []
+    if args:
+        include_functions.append(args.pop(0))
+    if 'YAML_TEST_FUNCTIONS' in os.environ:
+        include_functions.extend(os.environ['YAML_TEST_FUNCTIONS'].split())
+    include_filenames = []
+    include_filenames.extend(args)
+    if 'YAML_TEST_FILENAMES' in os.environ:
+        include_filenames.extend(os.environ['YAML_TEST_FILENAMES'].split())
+    return include_functions, include_filenames, verbose
+
+def execute(function, filenames, verbose):
+    if hasattr(function, 'unittest_name'):
+        name = function.unittest_name
+    else:
+        name = function.func_name
+    if verbose:
+        sys.stdout.write('='*75+'\n')
+        sys.stdout.write('%s(%s)...\n' % (name, ', '.join(filenames)))
+    try:
+        function(verbose=verbose, *filenames)
+    except Exception, exc:
+        info = sys.exc_info()
+        if isinstance(exc, AssertionError):
+            kind = 'FAILURE'
+        else:
+            kind = 'ERROR'
+        if verbose:
+            traceback.print_exc(limit=1, file=sys.stdout)
+        else:
+            sys.stdout.write(kind[0])
+            sys.stdout.flush()
+    else:
+        kind = 'SUCCESS'
+        info = None
+        if not verbose:
+            sys.stdout.write('.')
+    sys.stdout.flush()
+    return (name, filenames, kind, info)
+
+def display(results, verbose):
+    if results and not verbose:
+        sys.stdout.write('\n')
+    total = len(results)
+    failures = 0
+    errors = 0
+    for name, filenames, kind, info in results:
+        if kind == 'SUCCESS':
+            continue
+        if kind == 'FAILURE':
+            failures += 1
+        if kind == 'ERROR':
+            errors += 1
+        sys.stdout.write('='*75+'\n')
+        sys.stdout.write('%s(%s): %s\n' % (name, ', '.join(filenames), kind))
+        if kind == 'ERROR':
+            traceback.print_exception(file=sys.stdout, *info)
+        else:
+            sys.stdout.write('Traceback (most recent call last):\n')
+            traceback.print_tb(info[2], file=sys.stdout)
+            sys.stdout.write('%s: see below\n' % info[0].__name__)
+            sys.stdout.write('~'*75+'\n')
+            for arg in info[1].args:
+                pprint.pprint(arg, stream=sys.stdout)
+        for filename in filenames:
+            sys.stdout.write('-'*75+'\n')
+            sys.stdout.write('%s:\n' % filename)
+            data = open(filename, 'rb').read()
+            sys.stdout.write(data)
+            if data and data[-1] != '\n':
+                sys.stdout.write('\n')
+    sys.stdout.write('='*75+'\n')
+    sys.stdout.write('TESTS: %s\n' % total)
+    if failures:
+        sys.stdout.write('FAILURES: %s\n' % failures)
+    if errors:
+        sys.stdout.write('ERRORS: %s\n' % errors)
+
+def run(collections, args=None):
+    test_functions = find_test_functions(collections)
+    test_filenames = find_test_filenames(DATA)
+    include_functions, include_filenames, verbose = parse_arguments(args)
+    results = []
+    for function in test_functions:
+        if include_functions and function.func_name not in include_functions:
+            continue
+        if function.unittest:
+            for base, exts in test_filenames:
+                if include_filenames and base not in include_filenames:
+                    continue
+                filenames = []
+                for ext in function.unittest:
+                    if ext not in exts:
+                        break
+                    filenames.append(os.path.join(DATA, base+ext))
+                else:
+                    skip_exts = getattr(function, 'skip', [])
+                    for skip_ext in skip_exts:
+                        if skip_ext in exts:
+                            break
+                    else:
+                        result = execute(function, filenames, verbose)
+                        results.append(result)
+        else:
+            result = execute(function, [], verbose)
+            results.append(result)
+    display(results, verbose=verbose)
+
diff --git a/tests/lib/test_build.py b/tests/lib/test_build.py
new file mode 100644
index 0000000..901e8ed
--- /dev/null
+++ b/tests/lib/test_build.py
@@ -0,0 +1,10 @@
+
+if __name__ == '__main__':
+    import sys, os, distutils.util
+    build_lib = 'build/lib'
+    build_lib_ext = os.path.join('build', 'lib.%s-%s' % (distutils.util.get_platform(), sys.version[0:3]))
+    sys.path.insert(0, build_lib)
+    sys.path.insert(0, build_lib_ext)
+    import test_yaml, test_appliance
+    test_appliance.run(test_yaml)
+
diff --git a/tests/lib/test_build_ext.py b/tests/lib/test_build_ext.py
new file mode 100644
index 0000000..ff195d5
--- /dev/null
+++ b/tests/lib/test_build_ext.py
@@ -0,0 +1,11 @@
+
+
+if __name__ == '__main__':
+    import sys, os, distutils.util
+    build_lib = 'build/lib'
+    build_lib_ext = os.path.join('build', 'lib.%s-%s' % (distutils.util.get_platform(), sys.version[0:3]))
+    sys.path.insert(0, build_lib)
+    sys.path.insert(0, build_lib_ext)
+    import test_yaml_ext, test_appliance
+    test_appliance.run(test_yaml_ext)
+
diff --git a/tests/lib/test_canonical.py b/tests/lib/test_canonical.py
new file mode 100644
index 0000000..a851ef2
--- /dev/null
+++ b/tests/lib/test_canonical.py
@@ -0,0 +1,40 @@
+
+import yaml, canonical
+
+def test_canonical_scanner(canonical_filename, verbose=False):
+    data = open(canonical_filename, 'rb').read()
+    tokens = list(yaml.canonical_scan(data))
+    assert tokens, tokens
+    if verbose:
+        for token in tokens:
+            print token
+
+test_canonical_scanner.unittest = ['.canonical']
+
+def test_canonical_parser(canonical_filename, verbose=False):
+    data = open(canonical_filename, 'rb').read()
+    events = list(yaml.canonical_parse(data))
+    assert events, events
+    if verbose:
+        for event in events:
+            print event
+
+test_canonical_parser.unittest = ['.canonical']
+
+def test_canonical_error(data_filename, canonical_filename, verbose=False):
+    data = open(data_filename, 'rb').read()
+    try:
+        output = list(yaml.canonical_load_all(data))
+    except yaml.YAMLError, exc:
+        if verbose:
+            print exc
+    else:
+        raise AssertionError("expected an exception")
+
+test_canonical_error.unittest = ['.data', '.canonical']
+test_canonical_error.skip = ['.empty']
+
+if __name__ == '__main__':
+    import test_appliance
+    test_appliance.run(globals())
+
diff --git a/tests/lib/test_constructor.py b/tests/lib/test_constructor.py
new file mode 100644
index 0000000..beee7b0
--- /dev/null
+++ b/tests/lib/test_constructor.py
@@ -0,0 +1,275 @@
+
+import yaml
+import pprint
+
+import datetime
+try:
+    set
+except NameError:
+    from sets import Set as set
+import yaml.tokens
+
+def execute(code):
+    exec code
+    return value
+
+def _make_objects():
+    global MyLoader, MyDumper, MyTestClass1, MyTestClass2, MyTestClass3, YAMLObject1, YAMLObject2,  \
+            AnObject, AnInstance, AState, ACustomState, InitArgs, InitArgsWithState,    \
+            NewArgs, NewArgsWithState, Reduce, ReduceWithState, MyInt, MyList, MyDict,  \
+            FixedOffset, today, execute
+
+    class MyLoader(yaml.Loader):
+        pass
+    class MyDumper(yaml.Dumper):
+        pass
+
+    class MyTestClass1:
+        def __init__(self, x, y=0, z=0):
+            self.x = x
+            self.y = y
+            self.z = z
+        def __eq__(self, other):
+            if isinstance(other, MyTestClass1):
+                return self.__class__, self.__dict__ == other.__class__, other.__dict__
+            else:
+                return False
+
+    def construct1(constructor, node):
+        mapping = constructor.construct_mapping(node)
+        return MyTestClass1(**mapping)
+    def represent1(representer, native):
+        return representer.represent_mapping("!tag1", native.__dict__)
+
+    yaml.add_constructor("!tag1", construct1, Loader=MyLoader)
+    yaml.add_representer(MyTestClass1, represent1, Dumper=MyDumper)
+
+    class MyTestClass2(MyTestClass1, yaml.YAMLObject):
+        yaml_loader = MyLoader
+        yaml_dumper = MyDumper
+        yaml_tag = "!tag2"
+        def from_yaml(cls, constructor, node):
+            x = constructor.construct_yaml_int(node)
+            return cls(x=x)
+        from_yaml = classmethod(from_yaml)
+        def to_yaml(cls, representer, native):
+            return representer.represent_scalar(cls.yaml_tag, str(native.x))
+        to_yaml = classmethod(to_yaml)
+
+    class MyTestClass3(MyTestClass2):
+        yaml_tag = "!tag3"
+        def from_yaml(cls, constructor, node):
+            mapping = constructor.construct_mapping(node)
+            if '=' in mapping:
+                x = mapping['=']
+                del mapping['=']
+                mapping['x'] = x
+            return cls(**mapping)
+        from_yaml = classmethod(from_yaml)
+        def to_yaml(cls, representer, native):
+            return representer.represent_mapping(cls.yaml_tag, native.__dict__)
+        to_yaml = classmethod(to_yaml)
+
+    class YAMLObject1(yaml.YAMLObject):
+        yaml_loader = MyLoader
+        yaml_dumper = MyDumper
+        yaml_tag = '!foo'
+        def __init__(self, my_parameter=None, my_another_parameter=None):
+            self.my_parameter = my_parameter
+            self.my_another_parameter = my_another_parameter
+        def __eq__(self, other):
+            if isinstance(other, YAMLObject1):
+                return self.__class__, self.__dict__ == other.__class__, other.__dict__
+            else:
+                return False
+
+    class YAMLObject2(yaml.YAMLObject):
+        yaml_loader = MyLoader
+        yaml_dumper = MyDumper
+        yaml_tag = '!bar'
+        def __init__(self, foo=1, bar=2, baz=3):
+            self.foo = foo
+            self.bar = bar
+            self.baz = baz
+        def __getstate__(self):
+            return {1: self.foo, 2: self.bar, 3: self.baz}
+        def __setstate__(self, state):
+            self.foo = state[1]
+            self.bar = state[2]
+            self.baz = state[3]
+        def __eq__(self, other):
+            if isinstance(other, YAMLObject2):
+                return self.__class__, self.__dict__ == other.__class__, other.__dict__
+            else:
+                return False
+
+    class AnObject(object):
+        def __new__(cls, foo=None, bar=None, baz=None):
+            self = object.__new__(cls)
+            self.foo = foo
+            self.bar = bar
+            self.baz = baz
+            return self
+        def __cmp__(self, other):
+            return cmp((type(self), self.foo, self.bar, self.baz),
+                    (type(other), other.foo, other.bar, other.baz))
+        def __eq__(self, other):
+            return type(self) is type(other) and    \
+                    (self.foo, self.bar, self.baz) == (other.foo, other.bar, other.baz)
+
+    class AnInstance:
+        def __init__(self, foo=None, bar=None, baz=None):
+            self.foo = foo
+            self.bar = bar
+            self.baz = baz
+        def __cmp__(self, other):
+            return cmp((type(self), self.foo, self.bar, self.baz),
+                    (type(other), other.foo, other.bar, other.baz))
+        def __eq__(self, other):
+            return type(self) is type(other) and    \
+                    (self.foo, self.bar, self.baz) == (other.foo, other.bar, other.baz)
+
+    class AState(AnInstance):
+        def __getstate__(self):
+            return {
+                '_foo': self.foo,
+                '_bar': self.bar,
+                '_baz': self.baz,
+            }
+        def __setstate__(self, state):
+            self.foo = state['_foo']
+            self.bar = state['_bar']
+            self.baz = state['_baz']
+
+    class ACustomState(AnInstance):
+        def __getstate__(self):
+            return (self.foo, self.bar, self.baz)
+        def __setstate__(self, state):
+            self.foo, self.bar, self.baz = state
+
+    class InitArgs(AnInstance):
+        def __getinitargs__(self):
+            return (self.foo, self.bar, self.baz)
+        def __getstate__(self):
+            return {}
+
+    class InitArgsWithState(AnInstance):
+        def __getinitargs__(self):
+            return (self.foo, self.bar)
+        def __getstate__(self):
+            return self.baz
+        def __setstate__(self, state):
+            self.baz = state
+
+    class NewArgs(AnObject):
+        def __getnewargs__(self):
+            return (self.foo, self.bar, self.baz)
+        def __getstate__(self):
+            return {}
+
+    class NewArgsWithState(AnObject):
+        def __getnewargs__(self):
+            return (self.foo, self.bar)
+        def __getstate__(self):
+            return self.baz
+        def __setstate__(self, state):
+            self.baz = state
+
+    class Reduce(AnObject):
+        def __reduce__(self):
+            return self.__class__, (self.foo, self.bar, self.baz)
+
+    class ReduceWithState(AnObject):
+        def __reduce__(self):
+            return self.__class__, (self.foo, self.bar), self.baz
+        def __setstate__(self, state):
+            self.baz = state
+
+    class MyInt(int):
+        def __eq__(self, other):
+            return type(self) is type(other) and int(self) == int(other)
+
+    class MyList(list):
+        def __init__(self, n=1):
+            self.extend([None]*n)
+        def __eq__(self, other):
+            return type(self) is type(other) and list(self) == list(other)
+
+    class MyDict(dict):
+        def __init__(self, n=1):
+            for k in range(n):
+                self[k] = None
+        def __eq__(self, other):
+            return type(self) is type(other) and dict(self) == dict(other)
+
+    class FixedOffset(datetime.tzinfo):
+        def __init__(self, offset, name):
+            self.__offset = datetime.timedelta(minutes=offset)
+            self.__name = name
+        def utcoffset(self, dt):
+            return self.__offset
+        def tzname(self, dt):
+            return self.__name
+        def dst(self, dt):
+            return datetime.timedelta(0)
+
+    today = datetime.date.today()
+
+def _load_code(expression):
+    return eval(expression)
+
+def _serialize_value(data):
+    if isinstance(data, list):
+        return '[%s]' % ', '.join(map(_serialize_value, data))
+    elif isinstance(data, dict):
+        items = []
+        for key, value in data.items():
+            key = _serialize_value(key)
+            value = _serialize_value(value)
+            items.append("%s: %s" % (key, value))
+        items.sort()
+        return '{%s}' % ', '.join(items)
+    elif isinstance(data, datetime.datetime):
+        return repr(data.utctimetuple())
+    elif isinstance(data, unicode):
+        return data.encode('utf-8')
+    elif isinstance(data, float) and data != data:
+        return '?'
+    else:
+        return str(data)
+
+def test_constructor_types(data_filename, code_filename, verbose=False):
+    _make_objects()
+    native1 = None
+    native2 = None
+    try:
+        native1 = list(yaml.load_all(open(data_filename, 'rb'), Loader=MyLoader))
+        if len(native1) == 1:
+            native1 = native1[0]
+        native2 = _load_code(open(code_filename, 'rb').read())
+        try:
+            if native1 == native2:
+                return
+        except TypeError:
+            pass
+        if verbose:
+            print "SERIALIZED NATIVE1:"
+            print _serialize_value(native1)
+            print "SERIALIZED NATIVE2:"
+            print _serialize_value(native2)
+        assert _serialize_value(native1) == _serialize_value(native2), (native1, native2)
+    finally:
+        if verbose:
+            print "NATIVE1:"
+            pprint.pprint(native1)
+            print "NATIVE2:"
+            pprint.pprint(native2)
+
+test_constructor_types.unittest = ['.data', '.code']
+
+if __name__ == '__main__':
+    import sys, test_constructor
+    sys.modules['test_constructor'] = sys.modules['__main__']
+    import test_appliance
+    test_appliance.run(globals())
+
diff --git a/tests/lib/test_emitter.py b/tests/lib/test_emitter.py
new file mode 100644
index 0000000..61fd941
--- /dev/null
+++ b/tests/lib/test_emitter.py
@@ -0,0 +1,100 @@
+
+import yaml
+
+def _compare_events(events1, events2):
+    assert len(events1) == len(events2), (events1, events2)
+    for event1, event2 in zip(events1, events2):
+        assert event1.__class__ == event2.__class__, (event1, event2)
+        if isinstance(event1, yaml.NodeEvent):
+            assert event1.anchor == event2.anchor, (event1, event2)
+        if isinstance(event1, yaml.CollectionStartEvent):
+            assert event1.tag == event2.tag, (event1, event2)
+        if isinstance(event1, yaml.ScalarEvent):
+            if True not in event1.implicit+event2.implicit:
+                assert event1.tag == event2.tag, (event1, event2)
+            assert event1.value == event2.value, (event1, event2)
+
+def test_emitter_on_data(data_filename, canonical_filename, verbose=False):
+    events = list(yaml.parse(open(data_filename, 'rb')))
+    output = yaml.emit(events)
+    if verbose:
+        print "OUTPUT:"
+        print output
+    new_events = list(yaml.parse(output))
+    _compare_events(events, new_events)
+
+test_emitter_on_data.unittest = ['.data', '.canonical']
+
+def test_emitter_on_canonical(canonical_filename, verbose=False):
+    events = list(yaml.parse(open(canonical_filename, 'rb')))
+    for canonical in [False, True]:
+        output = yaml.emit(events, canonical=canonical)
+        if verbose:
+            print "OUTPUT (canonical=%s):" % canonical
+            print output
+        new_events = list(yaml.parse(output))
+        _compare_events(events, new_events)
+
+test_emitter_on_canonical.unittest = ['.canonical']
+
+def test_emitter_styles(data_filename, canonical_filename, verbose=False):
+    for filename in [data_filename, canonical_filename]:
+        events = list(yaml.parse(open(filename, 'rb')))
+        for flow_style in [False, True]:
+            for style in ['|', '>', '"', '\'', '']:
+                styled_events = []
+                for event in events:
+                    if isinstance(event, yaml.ScalarEvent):
+                        event = yaml.ScalarEvent(event.anchor, event.tag,
+                                event.implicit, event.value, style=style)
+                    elif isinstance(event, yaml.SequenceStartEvent):
+                        event = yaml.SequenceStartEvent(event.anchor, event.tag,
+                                event.implicit, flow_style=flow_style)
+                    elif isinstance(event, yaml.MappingStartEvent):
+                        event = yaml.MappingStartEvent(event.anchor, event.tag,
+                                event.implicit, flow_style=flow_style)
+                    styled_events.append(event)
+                output = yaml.emit(styled_events)
+                if verbose:
+                    print "OUTPUT (filename=%r, flow_style=%r, style=%r)" % (filename, flow_style, style)
+                    print output
+                new_events = list(yaml.parse(output))
+                _compare_events(events, new_events)
+
+test_emitter_styles.unittest = ['.data', '.canonical']
+
+class EventsLoader(yaml.Loader):
+
+    def construct_event(self, node):
+        if isinstance(node, yaml.ScalarNode):
+            mapping = {}
+        else:
+            mapping = self.construct_mapping(node)
+        class_name = str(node.tag[1:])+'Event'
+        if class_name in ['AliasEvent', 'ScalarEvent', 'SequenceStartEvent', 'MappingStartEvent']:
+            mapping.setdefault('anchor', None)
+        if class_name in ['ScalarEvent', 'SequenceStartEvent', 'MappingStartEvent']:
+            mapping.setdefault('tag', None)
+        if class_name in ['SequenceStartEvent', 'MappingStartEvent']:
+            mapping.setdefault('implicit', True)
+        if class_name == 'ScalarEvent':
+            mapping.setdefault('implicit', (False, True))
+            mapping.setdefault('value', '')
+        value = getattr(yaml, class_name)(**mapping)
+        return value
+
+EventsLoader.add_constructor(None, EventsLoader.construct_event)
+
+def test_emitter_events(events_filename, verbose=False):
+    events = list(yaml.load(open(events_filename, 'rb'), Loader=EventsLoader))
+    output = yaml.emit(events)
+    if verbose:
+        print "OUTPUT:"
+        print output
+    new_events = list(yaml.parse(output))
+    _compare_events(events, new_events)
+
+if __name__ == '__main__':
+    import test_appliance
+    test_appliance.run(globals())
+
diff --git a/tests/lib/test_errors.py b/tests/lib/test_errors.py
new file mode 100644
index 0000000..7dc9388
--- /dev/null
+++ b/tests/lib/test_errors.py
@@ -0,0 +1,67 @@
+
+import yaml, test_emitter
+
+def test_loader_error(error_filename, verbose=False):
+    try:
+        list(yaml.load_all(open(error_filename, 'rb')))
+    except yaml.YAMLError, exc:
+        if verbose:
+            print "%s:" % exc.__class__.__name__, exc
+    else:
+        raise AssertionError("expected an exception")
+
+test_loader_error.unittest = ['.loader-error']
+
+def test_loader_error_string(error_filename, verbose=False):
+    try:
+        list(yaml.load_all(open(error_filename, 'rb').read()))
+    except yaml.YAMLError, exc:
+        if verbose:
+            print "%s:" % exc.__class__.__name__, exc
+    else:
+        raise AssertionError("expected an exception")
+
+test_loader_error_string.unittest = ['.loader-error']
+
+def test_loader_error_single(error_filename, verbose=False):
+    try:
+        yaml.load(open(error_filename, 'rb').read())
+    except yaml.YAMLError, exc:
+        if verbose:
+            print "%s:" % exc.__class__.__name__, exc
+    else:
+        raise AssertionError("expected an exception")
+
+test_loader_error_single.unittest = ['.single-loader-error']
+
+def test_emitter_error(error_filename, verbose=False):
+    events = list(yaml.load(open(error_filename, 'rb'),
+                    Loader=test_emitter.EventsLoader))
+    try:
+        yaml.emit(events)
+    except yaml.YAMLError, exc:
+        if verbose:
+            print "%s:" % exc.__class__.__name__, exc
+    else:
+        raise AssertionError("expected an exception")
+
+test_emitter_error.unittest = ['.emitter-error']
+
+def test_dumper_error(error_filename, verbose=False):
+    code = open(error_filename, 'rb').read()
+    try:
+        import yaml
+        from StringIO import StringIO
+        exec code
+    except yaml.YAMLError, exc:
+        if verbose:
+            print "%s:" % exc.__class__.__name__, exc
+    else:
+        raise AssertionError("expected an exception")
+
+test_dumper_error.unittest = ['.dumper-error']
+
+if __name__ == '__main__':
+    import test_appliance
+    test_appliance.run(globals())
+
diff --git a/tests/lib/test_input_output.py b/tests/lib/test_input_output.py
new file mode 100644
index 0000000..9ccc8fc
--- /dev/null
+++ b/tests/lib/test_input_output.py
@@ -0,0 +1,151 @@
+
+import yaml
+import codecs, StringIO, tempfile, os, os.path
+
+def _unicode_open(file, encoding, errors='strict'):
+    info = codecs.lookup(encoding)
+    if isinstance(info, tuple):
+        reader = info[2]
+        writer = info[3]
+    else:
+        reader = info.streamreader
+        writer = info.streamwriter
+    srw = codecs.StreamReaderWriter(file, reader, writer, errors)
+    srw.encoding = encoding
+    return srw
+
+def test_unicode_input(unicode_filename, verbose=False):
+    data = open(unicode_filename, 'rb').read().decode('utf-8')
+    value = ' '.join(data.split())
+    output = yaml.load(_unicode_open(StringIO.StringIO(data.encode('utf-8')), 'utf-8'))
+    assert output == value, (output, value)
+    for input in [data, data.encode('utf-8'),
+                    codecs.BOM_UTF8+data.encode('utf-8'),
+                    codecs.BOM_UTF16_BE+data.encode('utf-16-be'),
+                    codecs.BOM_UTF16_LE+data.encode('utf-16-le')]:
+        if verbose:
+            print "INPUT:", repr(input[:10]), "..."
+        output = yaml.load(input)
+        assert output == value, (output, value)
+        output = yaml.load(StringIO.StringIO(input))
+        assert output == value, (output, value)
+
+test_unicode_input.unittest = ['.unicode']
+
+def test_unicode_input_errors(unicode_filename, verbose=False):
+    data = open(unicode_filename, 'rb').read().decode('utf-8')
+    for input in [data.encode('latin1', 'ignore'),
+                    data.encode('utf-16-be'), data.encode('utf-16-le'),
+                    codecs.BOM_UTF8+data.encode('utf-16-be'),
+                    codecs.BOM_UTF16_BE+data.encode('utf-16-le'),
+                    codecs.BOM_UTF16_LE+data.encode('utf-8')+'!']:
+        try:
+            yaml.load(input)
+        except yaml.YAMLError, exc:
+            if verbose:
+                print exc
+        else:
+            raise AssertionError("expected an exception")
+        try:
+            yaml.load(StringIO.StringIO(input))
+        except yaml.YAMLError, exc:
+            if verbose:
+                print exc
+        else:
+            raise AssertionError("expected an exception")
+
+test_unicode_input_errors.unittest = ['.unicode']
+
+def test_unicode_output(unicode_filename, verbose=False):
+    data = open(unicode_filename, 'rb').read().decode('utf-8')
+    value = ' '.join(data.split())
+    for allow_unicode in [False, True]:
+        data1 = yaml.dump(value, allow_unicode=allow_unicode)
+        for encoding in [None, 'utf-8', 'utf-16-be', 'utf-16-le']:
+            stream = StringIO.StringIO()
+            yaml.dump(value, _unicode_open(stream, 'utf-8'), encoding=encoding, allow_unicode=allow_unicode)
+            data2 = stream.getvalue()
+            data3 = yaml.dump(value, encoding=encoding, allow_unicode=allow_unicode)
+            stream = StringIO.StringIO()
+            yaml.dump(value, stream, encoding=encoding, allow_unicode=allow_unicode)
+            data4 = stream.getvalue()
+            for copy in [data1, data2, data3, data4]:
+                if allow_unicode:
+                    try:
+                        copy[4:].encode('ascii')
+                    except (UnicodeDecodeError, UnicodeEncodeError), exc:
+                        if verbose:
+                            print exc
+                    else:
+                        raise AssertionError("expected an exception")
+                else:
+                    copy[4:].encode('ascii')
+            assert isinstance(data1, str), (type(data1), encoding)
+            data1.decode('utf-8')
+            assert isinstance(data2, str), (type(data2), encoding)
+            data2.decode('utf-8')
+            if encoding is None:
+                assert isinstance(data3, unicode), (type(data3), encoding)
+                assert isinstance(data4, unicode), (type(data4), encoding)
+            else:
+                assert isinstance(data3, str), (type(data3), encoding)
+                data3.decode(encoding)
+                assert isinstance(data4, str), (type(data4), encoding)
+                data4.decode(encoding)
+
+test_unicode_output.unittest = ['.unicode']
+
+def test_file_output(unicode_filename, verbose=False):
+    data = open(unicode_filename, 'rb').read().decode('utf-8')
+    handle, filename = tempfile.mkstemp()
+    os.close(handle)
+    try:
+        stream = StringIO.StringIO()
+        yaml.dump(data, stream, allow_unicode=True)
+        data1 = stream.getvalue()
+        stream = open(filename, 'wb')
+        yaml.dump(data, stream, allow_unicode=True)
+        stream.close()
+        data2 = open(filename, 'rb').read()
+        stream = open(filename, 'wb')
+        yaml.dump(data, stream, encoding='utf-16-le', allow_unicode=True)
+        stream.close()
+        data3 = open(filename, 'rb').read().decode('utf-16-le')[1:].encode('utf-8')
+        stream = _unicode_open(open(filename, 'wb'), 'utf-8')
+        yaml.dump(data, stream, allow_unicode=True)
+        stream.close()
+        data4 = open(filename, 'rb').read()
+        assert data1 == data2, (data1, data2)
+        assert data1 == data3, (data1, data3)
+        assert data1 == data4, (data1, data4)
+    finally:
+        if os.path.exists(filename):
+            os.unlink(filename)
+
+test_file_output.unittest = ['.unicode']
+
+def test_unicode_transfer(unicode_filename, verbose=False):
+    data = open(unicode_filename, 'rb').read().decode('utf-8')
+    for encoding in [None, 'utf-8', 'utf-16-be', 'utf-16-le']:
+        input = data
+        if encoding is not None:
+            input = (u'\ufeff'+input).encode(encoding)
+        output1 = yaml.emit(yaml.parse(input), allow_unicode=True)
+        stream = StringIO.StringIO()
+        yaml.emit(yaml.parse(input), _unicode_open(stream, 'utf-8'),
+                            allow_unicode=True)
+        output2 = stream.getvalue()
+        if encoding is None:
+            assert isinstance(output1, unicode), (type(output1), encoding)
+        else:
+            assert isinstance(output1, str), (type(output1), encoding)
+            output1.decode(encoding)
+        assert isinstance(output2, str), (type(output2), encoding)
+        output2.decode('utf-8')
+
+test_unicode_transfer.unittest = ['.unicode']
+
+if __name__ == '__main__':
+    import test_appliance
+    test_appliance.run(globals())
+
diff --git a/tests/lib/test_mark.py b/tests/lib/test_mark.py
new file mode 100644
index 0000000..f30a121
--- /dev/null
+++ b/tests/lib/test_mark.py
@@ -0,0 +1,32 @@
+
+import yaml
+
+def test_marks(marks_filename, verbose=False):
+    inputs = open(marks_filename, 'rb').read().split('---\n')[1:]
+    for input in inputs:
+        index = 0
+        line = 0
+        column = 0
+        while input[index] != '*':
+            if input[index] == '\n':
+                line += 1
+                column = 0
+            else:
+                column += 1
+            index += 1
+        mark = yaml.Mark(marks_filename, index, line, column, unicode(input), index)
+        snippet = mark.get_snippet(indent=2, max_length=79)
+        if verbose:
+            print snippet
+        assert isinstance(snippet, str), type(snippet)
+        assert snippet.count('\n') == 1, snippet.count('\n')
+        data, pointer = snippet.split('\n')
+        assert len(data) < 82, len(data)
+        assert data[len(pointer)-1] == '*', data[len(pointer)-1]
+
+test_marks.unittest = ['.marks']
+
+if __name__ == '__main__':
+    import test_appliance
+    test_appliance.run(globals())
+
diff --git a/tests/lib/test_reader.py b/tests/lib/test_reader.py
new file mode 100644
index 0000000..3576ae6
--- /dev/null
+++ b/tests/lib/test_reader.py
@@ -0,0 +1,35 @@
+
+import yaml.reader
+import codecs
+
+def _run_reader(data, verbose):
+    try:
+        stream = yaml.reader.Reader(data)
+        while stream.peek() != u'\0':
+            stream.forward()
+    except yaml.reader.ReaderError, exc:
+        if verbose:
+            print exc
+    else:
+        raise AssertionError("expected an exception")
+
+def test_stream_error(error_filename, verbose=False):
+    _run_reader(open(error_filename, 'rb'), verbose)
+    _run_reader(open(error_filename, 'rb').read(), verbose)
+    for encoding in ['utf-8', 'utf-16-le', 'utf-16-be']:
+        try:
+            data = unicode(open(error_filename, 'rb').read(), encoding)
+            break
+        except UnicodeDecodeError:
+            pass
+    else:
+        return
+    _run_reader(data, verbose)
+    _run_reader(codecs.open(error_filename, encoding=encoding), verbose)
+
+test_stream_error.unittest = ['.stream-error']
+
+if __name__ == '__main__':
+    import test_appliance
+    test_appliance.run(globals())
+
diff --git a/tests/lib/test_recursive.py b/tests/lib/test_recursive.py
new file mode 100644
index 0000000..6707fd4
--- /dev/null
+++ b/tests/lib/test_recursive.py
@@ -0,0 +1,50 @@
+
+import yaml
+
+class AnInstance:
+
+    def __init__(self, foo, bar):
+        self.foo = foo
+        self.bar = bar
+
+    def __repr__(self):
+        try:
+            return "%s(foo=%r, bar=%r)" % (self.__class__.__name__,
+                    self.foo, self.bar)
+        except RuntimeError:
+            return "%s(foo=..., bar=...)" % self.__class__.__name__
+
+class AnInstanceWithState(AnInstance):
+
+    def __getstate__(self):
+        return {'attributes': [self.foo, self.bar]}
+
+    def __setstate__(self, state):
+        self.foo, self.bar = state['attributes']
+
+def test_recursive(recursive_filename, verbose=False):
+    exec open(recursive_filename, 'rb').read()
+    value1 = value
+    output1 = None
+    value2 = None
+    output2 = None
+    try:
+        output1 = yaml.dump(value1)
+        value2 = yaml.load(output1)
+        output2 = yaml.dump(value2)
+        assert output1 == output2, (output1, output2)
+    finally:
+        if verbose:
+            #print "VALUE1:", value1
+            #print "VALUE2:", value2
+            print "OUTPUT1:"
+            print output1
+            print "OUTPUT2:"
+            print output2
+
+test_recursive.unittest = ['.recursive']
+
+if __name__ == '__main__':
+    import test_appliance
+    test_appliance.run(globals())
+
diff --git a/tests/lib/test_representer.py b/tests/lib/test_representer.py
new file mode 100644
index 0000000..a82a32a
--- /dev/null
+++ b/tests/lib/test_representer.py
@@ -0,0 +1,43 @@
+
+import yaml
+import test_constructor
+import pprint
+
+def test_representer_types(code_filename, verbose=False):
+    test_constructor._make_objects()
+    for allow_unicode in [False, True]:
+        for encoding in ['utf-8', 'utf-16-be', 'utf-16-le']:
+            native1 = test_constructor._load_code(open(code_filename, 'rb').read())
+            native2 = None
+            try:
+                output = yaml.dump(native1, Dumper=test_constructor.MyDumper,
+                            allow_unicode=allow_unicode, encoding=encoding)
+                native2 = yaml.load(output, Loader=test_constructor.MyLoader)
+                try:
+                    if native1 == native2:
+                        continue
+                except TypeError:
+                    pass
+                value1 = test_constructor._serialize_value(native1)
+                value2 = test_constructor._serialize_value(native2)
+                if verbose:
+                    print "SERIALIZED NATIVE1:"
+                    print value1
+                    print "SERIALIZED NATIVE2:"
+                    print value2
+                assert value1 == value2, (native1, native2)
+            finally:
+                if verbose:
+                    print "NATIVE1:"
+                    pprint.pprint(native1)
+                    print "NATIVE2:"
+                    pprint.pprint(native2)
+                    print "OUTPUT:"
+                    print output
+
+test_representer_types.unittest = ['.code']
+
+if __name__ == '__main__':
+    import test_appliance
+    test_appliance.run(globals())
+
diff --git a/tests/lib/test_resolver.py b/tests/lib/test_resolver.py
new file mode 100644
index 0000000..5566750
--- /dev/null
+++ b/tests/lib/test_resolver.py
@@ -0,0 +1,92 @@
+
+import yaml
+import pprint
+
+def test_implicit_resolver(data_filename, detect_filename, verbose=False):
+    correct_tag = None
+    node = None
+    try:
+        correct_tag = open(detect_filename, 'rb').read().strip()
+        node = yaml.compose(open(data_filename, 'rb'))
+        assert isinstance(node, yaml.SequenceNode), node
+        for scalar in node.value:
+            assert isinstance(scalar, yaml.ScalarNode), scalar
+            assert scalar.tag == correct_tag, (scalar.tag, correct_tag)
+    finally:
+        if verbose:
+            print "CORRECT TAG:", correct_tag
+            if hasattr(node, 'value'):
+                print "CHILDREN:"
+                pprint.pprint(node.value)
+
+test_implicit_resolver.unittest = ['.data', '.detect']
+
+def _make_path_loader_and_dumper():
+    global MyLoader, MyDumper
+
+    class MyLoader(yaml.Loader):
+        pass
+    class MyDumper(yaml.Dumper):
+        pass
+
+    yaml.add_path_resolver(u'!root', [],
+            Loader=MyLoader, Dumper=MyDumper)
+    yaml.add_path_resolver(u'!root/scalar', [], str,
+            Loader=MyLoader, Dumper=MyDumper)
+    yaml.add_path_resolver(u'!root/key11/key12/*', ['key11', 'key12'],
+            Loader=MyLoader, Dumper=MyDumper)
+    yaml.add_path_resolver(u'!root/key21/1/*', ['key21', 1],
+            Loader=MyLoader, Dumper=MyDumper)
+    yaml.add_path_resolver(u'!root/key31/*/*/key14/map', ['key31', None, None, 'key14'], dict,
+            Loader=MyLoader, Dumper=MyDumper)
+
+    return MyLoader, MyDumper
+
+def _convert_node(node):
+    if isinstance(node, yaml.ScalarNode):
+        return (node.tag, node.value)
+    elif isinstance(node, yaml.SequenceNode):
+        value = []
+        for item in node.value:
+            value.append(_convert_node(item))
+        return (node.tag, value)
+    elif isinstance(node, yaml.MappingNode):
+        value = []
+        for key, item in node.value:
+            value.append((_convert_node(key), _convert_node(item)))
+        return (node.tag, value)
+
+def test_path_resolver_loader(data_filename, path_filename, verbose=False):
+    _make_path_loader_and_dumper()
+    nodes1 = list(yaml.compose_all(open(data_filename, 'rb').read(), Loader=MyLoader))
+    nodes2 = list(yaml.compose_all(open(path_filename, 'rb').read()))
+    try:
+        for node1, node2 in zip(nodes1, nodes2):
+            data1 = _convert_node(node1)
+            data2 = _convert_node(node2)
+            assert data1 == data2, (data1, data2)
+    finally:
+        if verbose:
+            print yaml.serialize_all(nodes1)
+
+test_path_resolver_loader.unittest = ['.data', '.path']
+
+def test_path_resolver_dumper(data_filename, path_filename, verbose=False):
+    _make_path_loader_and_dumper()
+    for filename in [data_filename, path_filename]:
+        output = yaml.serialize_all(yaml.compose_all(open(filename, 'rb')), Dumper=MyDumper)
+        if verbose:
+            print output
+        nodes1 = yaml.compose_all(output)
+        nodes2 = yaml.compose_all(open(data_filename, 'rb'))
+        for node1, node2 in zip(nodes1, nodes2):
+            data1 = _convert_node(node1)
+            data2 = _convert_node(node2)
+            assert data1 == data2, (data1, data2)
+
+test_path_resolver_dumper.unittest = ['.data', '.path']
+
+if __name__ == '__main__':
+    import test_appliance
+    test_appliance.run(globals())
+
diff --git a/tests/lib/test_structure.py b/tests/lib/test_structure.py
new file mode 100644
index 0000000..61bcb80
--- /dev/null
+++ b/tests/lib/test_structure.py
@@ -0,0 +1,187 @@
+
+import yaml, canonical
+import pprint
+
+def _convert_structure(loader):
+    if loader.check_event(yaml.ScalarEvent):
+        event = loader.get_event()
+        if event.tag or event.anchor or event.value:
+            return True
+        else:
+            return None
+    elif loader.check_event(yaml.SequenceStartEvent):
+        loader.get_event()
+        sequence = []
+        while not loader.check_event(yaml.SequenceEndEvent):
+            sequence.append(_convert_structure(loader))
+        loader.get_event()
+        return sequence
+    elif loader.check_event(yaml.MappingStartEvent):
+        loader.get_event()
+        mapping = []
+        while not loader.check_event(yaml.MappingEndEvent):
+            key = _convert_structure(loader)
+            value = _convert_structure(loader)
+            mapping.append((key, value))
+        loader.get_event()
+        return mapping
+    elif loader.check_event(yaml.AliasEvent):
+        loader.get_event()
+        return '*'
+    else:
+        loader.get_event()
+        return '?'
+
+def test_structure(data_filename, structure_filename, verbose=False):
+    nodes1 = []
+    nodes2 = eval(open(structure_filename, 'rb').read())
+    try:
+        loader = yaml.Loader(open(data_filename, 'rb'))
+        while loader.check_event():
+            if loader.check_event(yaml.StreamStartEvent, yaml.StreamEndEvent,
+                                yaml.DocumentStartEvent, yaml.DocumentEndEvent):
+                loader.get_event()
+                continue
+            nodes1.append(_convert_structure(loader))
+        if len(nodes1) == 1:
+            nodes1 = nodes1[0]
+        assert nodes1 == nodes2, (nodes1, nodes2)
+    finally:
+        if verbose:
+            print "NODES1:"
+            pprint.pprint(nodes1)
+            print "NODES2:"
+            pprint.pprint(nodes2)
+
+test_structure.unittest = ['.data', '.structure']
+
+def _compare_events(events1, events2, full=False):
+    assert len(events1) == len(events2), (len(events1), len(events2))
+    for event1, event2 in zip(events1, events2):
+        assert event1.__class__ == event2.__class__, (event1, event2)
+        if isinstance(event1, yaml.AliasEvent) and full:
+            assert event1.anchor == event2.anchor, (event1, event2)
+        if isinstance(event1, (yaml.ScalarEvent, yaml.CollectionStartEvent)):
+            if (event1.tag not in [None, u'!'] and event2.tag not in [None, u'!']) or full:
+                assert event1.tag == event2.tag, (event1, event2)
+        if isinstance(event1, yaml.ScalarEvent):
+            assert event1.value == event2.value, (event1, event2)
+
+def test_parser(data_filename, canonical_filename, verbose=False):
+    events1 = None
+    events2 = None
+    try:
+        events1 = list(yaml.parse(open(data_filename, 'rb')))
+        events2 = list(yaml.canonical_parse(open(canonical_filename, 'rb')))
+        _compare_events(events1, events2)
+    finally:
+        if verbose:
+            print "EVENTS1:"
+            pprint.pprint(events1)
+            print "EVENTS2:"
+            pprint.pprint(events2)
+
+test_parser.unittest = ['.data', '.canonical']
+
+def test_parser_on_canonical(canonical_filename, verbose=False):
+    events1 = None
+    events2 = None
+    try:
+        events1 = list(yaml.parse(open(canonical_filename, 'rb')))
+        events2 = list(yaml.canonical_parse(open(canonical_filename, 'rb')))
+        _compare_events(events1, events2, full=True)
+    finally:
+        if verbose:
+            print "EVENTS1:"
+            pprint.pprint(events1)
+            print "EVENTS2:"
+            pprint.pprint(events2)
+
+test_parser_on_canonical.unittest = ['.canonical']
+
+def _compare_nodes(node1, node2):
+    assert node1.__class__ == node2.__class__, (node1, node2)
+    assert node1.tag == node2.tag, (node1, node2)
+    if isinstance(node1, yaml.ScalarNode):
+        assert node1.value == node2.value, (node1, node2)
+    else:
+        assert len(node1.value) == len(node2.value), (node1, node2)
+        for item1, item2 in zip(node1.value, node2.value):
+            if not isinstance(item1, tuple):
+                item1 = (item1,)
+                item2 = (item2,)
+            for subnode1, subnode2 in zip(item1, item2):
+                _compare_nodes(subnode1, subnode2)
+
+def test_composer(data_filename, canonical_filename, verbose=False):
+    nodes1 = None
+    nodes2 = None
+    try:
+        nodes1 = list(yaml.compose_all(open(data_filename, 'rb')))
+        nodes2 = list(yaml.canonical_compose_all(open(canonical_filename, 'rb')))
+        assert len(nodes1) == len(nodes2), (len(nodes1), len(nodes2))
+        for node1, node2 in zip(nodes1, nodes2):
+            _compare_nodes(node1, node2)
+    finally:
+        if verbose:
+            print "NODES1:"
+            pprint.pprint(nodes1)
+            print "NODES2:"
+            pprint.pprint(nodes2)
+
+test_composer.unittest = ['.data', '.canonical']
+
+def _make_loader():
+    global MyLoader
+
+    class MyLoader(yaml.Loader):
+        def construct_sequence(self, node):
+            return tuple(yaml.Loader.construct_sequence(self, node))
+        def construct_mapping(self, node):
+            pairs = self.construct_pairs(node)
+            pairs.sort()
+            return pairs
+        def construct_undefined(self, node):
+            return self.construct_scalar(node)
+
+    MyLoader.add_constructor(u'tag:yaml.org,2002:map', MyLoader.construct_mapping)
+    MyLoader.add_constructor(None, MyLoader.construct_undefined)
+
+def _make_canonical_loader():
+    global MyCanonicalLoader
+
+    class MyCanonicalLoader(yaml.CanonicalLoader):
+        def construct_sequence(self, node):
+            return tuple(yaml.CanonicalLoader.construct_sequence(self, node))
+        def construct_mapping(self, node):
+            pairs = self.construct_pairs(node)
+            pairs.sort()
+            return pairs
+        def construct_undefined(self, node):
+            return self.construct_scalar(node)
+
+    MyCanonicalLoader.add_constructor(u'tag:yaml.org,2002:map', MyCanonicalLoader.construct_mapping)
+    MyCanonicalLoader.add_constructor(None, MyCanonicalLoader.construct_undefined)
+
+def test_constructor(data_filename, canonical_filename, verbose=False):
+    _make_loader()
+    _make_canonical_loader()
+    native1 = None
+    native2 = None
+    try:
+        native1 = list(yaml.load_all(open(data_filename, 'rb'), Loader=MyLoader))
+        native2 = list(yaml.load_all(open(canonical_filename, 'rb'), Loader=MyCanonicalLoader))
+        assert native1 == native2, (native1, native2)
+    finally:
+        if verbose:
+            print "NATIVE1:"
+            pprint.pprint(native1)
+            print "NATIVE2:"
+            pprint.pprint(native2)
+
+test_constructor.unittest = ['.data', '.canonical']
+
+if __name__ == '__main__':
+    import test_appliance
+    test_appliance.run(globals())
+
diff --git a/tests/lib/test_tokens.py b/tests/lib/test_tokens.py
new file mode 100644
index 0000000..9613fa0
--- /dev/null
+++ b/tests/lib/test_tokens.py
@@ -0,0 +1,77 @@
+
+import yaml
+import pprint
+
+# Tokens mnemonic:
+# directive:            %
+# document_start:       ---
+# document_end:         ...
+# alias:                *
+# anchor:               &
+# tag:                  !
+# scalar                _
+# block_sequence_start: [[
+# block_mapping_start:  {{
+# block_end:            ]}
+# flow_sequence_start:  [
+# flow_sequence_end:    ]
+# flow_mapping_start:   {
+# flow_mapping_end:     }
+# entry:                ,
+# key:                  ?
+# value:                :
+
+_replaces = {
+    yaml.DirectiveToken: '%',
+    yaml.DocumentStartToken: '---',
+    yaml.DocumentEndToken: '...',
+    yaml.AliasToken: '*',
+    yaml.AnchorToken: '&',
+    yaml.TagToken: '!',
+    yaml.ScalarToken: '_',
+    yaml.BlockSequenceStartToken: '[[',
+    yaml.BlockMappingStartToken: '{{',
+    yaml.BlockEndToken: ']}',
+    yaml.FlowSequenceStartToken: '[',
+    yaml.FlowSequenceEndToken: ']',
+    yaml.FlowMappingStartToken: '{',
+    yaml.FlowMappingEndToken: '}',
+    yaml.BlockEntryToken: ',',
+    yaml.FlowEntryToken: ',',
+    yaml.KeyToken: '?',
+    yaml.ValueToken: ':',
+}
+
+def test_tokens(data_filename, tokens_filename, verbose=False):
+    tokens1 = []
+    tokens2 = open(tokens_filename, 'rb').read().split()
+    try:
+        for token in yaml.scan(open(data_filename, 'rb')):
+            if not isinstance(token, (yaml.StreamStartToken, yaml.StreamEndToken)):
+                tokens1.append(_replaces[token.__class__])
+    finally:
+        if verbose:
+            print "TOKENS1:", ' '.join(tokens1)
+            print "TOKENS2:", ' '.join(tokens2)
+    assert len(tokens1) == len(tokens2), (tokens1, tokens2)
+    for token1, token2 in zip(tokens1, tokens2):
+        assert token1 == token2, (token1, token2)
+
+test_tokens.unittest = ['.data', '.tokens']
+
+def test_scanner(data_filename, canonical_filename, verbose=False):
+    for filename in [data_filename, canonical_filename]:
+        tokens = []
+        try:
+            for token in yaml.scan(open(filename, 'rb')):
+                tokens.append(token.__class__.__name__)
+        finally:
+            if verbose:
+                pprint.pprint(tokens)
+
+test_scanner.unittest = ['.data', '.canonical']
+
+if __name__ == '__main__':
+    import test_appliance
+    test_appliance.run(globals())
+
diff --git a/tests/lib/test_yaml.py b/tests/lib/test_yaml.py
new file mode 100644
index 0000000..0927368
--- /dev/null
+++ b/tests/lib/test_yaml.py
@@ -0,0 +1,18 @@
+
+from test_mark import *
+from test_reader import *
+from test_canonical import *
+from test_tokens import *
+from test_structure import *
+from test_errors import *
+from test_resolver import *
+from test_constructor import *
+from test_emitter import *
+from test_representer import *
+from test_recursive import *
+from test_input_output import *
+
+if __name__ == '__main__':
+    import test_appliance
+    test_appliance.run(globals())
+
diff --git a/tests/lib/test_yaml_ext.py b/tests/lib/test_yaml_ext.py
new file mode 100644
index 0000000..bdfda3e
--- /dev/null
+++ b/tests/lib/test_yaml_ext.py
@@ -0,0 +1,277 @@
+
+import _yaml, yaml
+import types, pprint
+
+yaml.PyBaseLoader = yaml.BaseLoader
+yaml.PySafeLoader = yaml.SafeLoader
+yaml.PyLoader = yaml.Loader
+yaml.PyBaseDumper = yaml.BaseDumper
+yaml.PySafeDumper = yaml.SafeDumper
+yaml.PyDumper = yaml.Dumper
+
+old_scan = yaml.scan
+def new_scan(stream, Loader=yaml.CLoader):
+    return old_scan(stream, Loader)
+
+old_parse = yaml.parse
+def new_parse(stream, Loader=yaml.CLoader):
+    return old_parse(stream, Loader)
+
+old_compose = yaml.compose
+def new_compose(stream, Loader=yaml.CLoader):
+    return old_compose(stream, Loader)
+
+old_compose_all = yaml.compose_all
+def new_compose_all(stream, Loader=yaml.CLoader):
+    return old_compose_all(stream, Loader)
+
+old_load = yaml.load
+def new_load(stream, Loader=yaml.CLoader):
+    return old_load(stream, Loader)
+
+old_load_all = yaml.load_all
+def new_load_all(stream, Loader=yaml.CLoader):
+    return old_load_all(stream, Loader)
+
+old_safe_load = yaml.safe_load
+def new_safe_load(stream):
+    return old_load(stream, yaml.CSafeLoader)
+
+old_safe_load_all = yaml.safe_load_all
+def new_safe_load_all(stream):
+    return old_load_all(stream, yaml.CSafeLoader)
+
+old_emit = yaml.emit
+def new_emit(events, stream=None, Dumper=yaml.CDumper, **kwds):
+    return old_emit(events, stream, Dumper, **kwds)
+
+old_serialize = yaml.serialize
+def new_serialize(node, stream, Dumper=yaml.CDumper, **kwds):
+    return old_serialize(node, stream, Dumper, **kwds)
+
+old_serialize_all = yaml.serialize_all
+def new_serialize_all(nodes, stream=None, Dumper=yaml.CDumper, **kwds):
+    return old_serialize_all(nodes, stream, Dumper, **kwds)
+
+old_dump = yaml.dump
+def new_dump(data, stream=None, Dumper=yaml.CDumper, **kwds):
+    return old_dump(data, stream, Dumper, **kwds)
+
+old_dump_all = yaml.dump_all
+def new_dump_all(documents, stream=None, Dumper=yaml.CDumper, **kwds):
+    return old_dump_all(documents, stream, Dumper, **kwds)
+
+old_safe_dump = yaml.safe_dump
+def new_safe_dump(data, stream=None, **kwds):
+    return old_dump(data, stream, yaml.CSafeDumper, **kwds)
+
+old_safe_dump_all = yaml.safe_dump_all
+def new_safe_dump_all(documents, stream=None, **kwds):
+    return old_dump_all(documents, stream, yaml.CSafeDumper, **kwds)
+
+def _set_up():
+    yaml.BaseLoader = yaml.CBaseLoader
+    yaml.SafeLoader = yaml.CSafeLoader
+    yaml.Loader = yaml.CLoader
+    yaml.BaseDumper = yaml.CBaseDumper
+    yaml.SafeDumper = yaml.CSafeDumper
+    yaml.Dumper = yaml.CDumper
+    yaml.scan = new_scan
+    yaml.parse = new_parse
+    yaml.compose = new_compose
+    yaml.compose_all = new_compose_all
+    yaml.load = new_load
+    yaml.load_all = new_load_all
+    yaml.safe_load = new_safe_load
+    yaml.safe_load_all = new_safe_load_all
+    yaml.emit = new_emit
+    yaml.serialize = new_serialize
+    yaml.serialize_all = new_serialize_all
+    yaml.dump = new_dump
+    yaml.dump_all = new_dump_all
+    yaml.safe_dump = new_safe_dump
+    yaml.safe_dump_all = new_safe_dump_all
+
+def _tear_down():
+    yaml.BaseLoader = yaml.PyBaseLoader
+    yaml.SafeLoader = yaml.PySafeLoader
+    yaml.Loader = yaml.PyLoader
+    yaml.BaseDumper = yaml.PyBaseDumper
+    yaml.SafeDumper = yaml.PySafeDumper
+    yaml.Dumper = yaml.PyDumper
+    yaml.scan = old_scan
+    yaml.parse = old_parse
+    yaml.compose = old_compose
+    yaml.compose_all = old_compose_all
+    yaml.load = old_load
+    yaml.load_all = old_load_all
+    yaml.safe_load = old_safe_load
+    yaml.safe_load_all = old_safe_load_all
+    yaml.emit = old_emit
+    yaml.serialize = old_serialize
+    yaml.serialize_all = old_serialize_all
+    yaml.dump = old_dump
+    yaml.dump_all = old_dump_all
+    yaml.safe_dump = old_safe_dump
+    yaml.safe_dump_all = old_safe_dump_all
+
+def test_c_version(verbose=False):
+    if verbose:
+        print _yaml.get_version()
+        print _yaml.get_version_string()
+    assert ("%s.%s.%s" % _yaml.get_version()) == _yaml.get_version_string(),    \
+            (_yaml.get_version(), _yaml.get_version_string())
+
+def _compare_scanners(py_data, c_data, verbose):
+    py_tokens = list(yaml.scan(py_data, Loader=yaml.PyLoader))
+    c_tokens = []
+    try:
+        for token in yaml.scan(c_data, Loader=yaml.CLoader):
+            c_tokens.append(token)
+        assert len(py_tokens) == len(c_tokens), (len(py_tokens), len(c_tokens))
+        for py_token, c_token in zip(py_tokens, c_tokens):
+            assert py_token.__class__ == c_token.__class__, (py_token, c_token)
+            if hasattr(py_token, 'value'):
+                assert py_token.value == c_token.value, (py_token, c_token)
+            if isinstance(py_token, yaml.StreamEndToken):
+                continue
+            py_start = (py_token.start_mark.index, py_token.start_mark.line, py_token.start_mark.column)
+            py_end = (py_token.end_mark.index, py_token.end_mark.line, py_token.end_mark.column)
+            c_start = (c_token.start_mark.index, c_token.start_mark.line, c_token.start_mark.column)
+            c_end = (c_token.end_mark.index, c_token.end_mark.line, c_token.end_mark.column)
+            assert py_start == c_start, (py_start, c_start)
+            assert py_end == c_end, (py_end, c_end)
+    finally:
+        if verbose:
+            print "PY_TOKENS:"
+            pprint.pprint(py_tokens)
+            print "C_TOKENS:"
+            pprint.pprint(c_tokens)
+
+def test_c_scanner(data_filename, canonical_filename, verbose=False):
+    _compare_scanners(open(data_filename, 'rb'),
+            open(data_filename, 'rb'), verbose)
+    _compare_scanners(open(data_filename, 'rb').read(),
+            open(data_filename, 'rb').read(), verbose)
+    _compare_scanners(open(canonical_filename, 'rb'),
+            open(canonical_filename, 'rb'), verbose)
+    _compare_scanners(open(canonical_filename, 'rb').read(),
+            open(canonical_filename, 'rb').read(), verbose)
+
+test_c_scanner.unittest = ['.data', '.canonical']
+test_c_scanner.skip = ['.skip-ext']
+
+def _compare_parsers(py_data, c_data, verbose):
+    py_events = list(yaml.parse(py_data, Loader=yaml.PyLoader))
+    c_events = []
+    try:
+        for event in yaml.parse(c_data, Loader=yaml.CLoader):
+            c_events.append(event)
+        assert len(py_events) == len(c_events), (len(py_events), len(c_events))
+        for py_event, c_event in zip(py_events, c_events):
+            for attribute in ['__class__', 'anchor', 'tag', 'implicit',
+                                'value', 'explicit', 'version', 'tags']:
+                py_value = getattr(py_event, attribute, None)
+                c_value = getattr(c_event, attribute, None)
+                assert py_value == c_value, (py_event, c_event, attribute)
+    finally:
+        if verbose:
+            print "PY_EVENTS:"
+            pprint.pprint(py_events)
+            print "C_EVENTS:"
+            pprint.pprint(c_events)
+
+def test_c_parser(data_filename, canonical_filename, verbose=False):
+    _compare_parsers(open(data_filename, 'rb'),
+            open(data_filename, 'rb'), verbose)
+    _compare_parsers(open(data_filename, 'rb').read(),
+            open(data_filename, 'rb').read(), verbose)
+    _compare_parsers(open(canonical_filename, 'rb'),
+            open(canonical_filename, 'rb'), verbose)
+    _compare_parsers(open(canonical_filename, 'rb').read(),
+            open(canonical_filename, 'rb').read(), verbose)
+
+test_c_parser.unittest = ['.data', '.canonical']
+test_c_parser.skip = ['.skip-ext']
+
+def _compare_emitters(data, verbose):
+    events = list(yaml.parse(data, Loader=yaml.PyLoader))
+    c_data = yaml.emit(events, Dumper=yaml.CDumper)
+    if verbose:
+        print c_data
+    py_events = list(yaml.parse(c_data, Loader=yaml.PyLoader))
+    c_events = list(yaml.parse(c_data, Loader=yaml.CLoader))
+    try:
+        assert len(events) == len(py_events), (len(events), len(py_events))
+        assert len(events) == len(c_events), (len(events), len(c_events))
+        for event, py_event, c_event in zip(events, py_events, c_events):
+            for attribute in ['__class__', 'anchor', 'tag', 'implicit',
+                                'value', 'explicit', 'version', 'tags']:
+                value = getattr(event, attribute, None)
+                py_value = getattr(py_event, attribute, None)
+                c_value = getattr(c_event, attribute, None)
+                if attribute == 'tag' and value in [None, u'!'] \
+                        and py_value in [None, u'!'] and c_value in [None, u'!']:
+                    continue
+                if attribute == 'explicit' and (py_value or c_value):
+                    continue
+                assert value == py_value, (event, py_event, attribute)
+                assert value == c_value, (event, c_event, attribute)
+    finally:
+        if verbose:
+            print "EVENTS:"
+            pprint.pprint(events)
+            print "PY_EVENTS:"
+            pprint.pprint(py_events)
+            print "C_EVENTS:"
+            pprint.pprint(c_events)
+
+def test_c_emitter(data_filename, canonical_filename, verbose=False):
+    _compare_emitters(open(data_filename, 'rb').read(), verbose)
+    _compare_emitters(open(canonical_filename, 'rb').read(), verbose)
+
+test_c_emitter.unittest = ['.data', '.canonical']
+test_c_emitter.skip = ['.skip-ext']
+
+def wrap_ext_function(function):
+    def wrapper(*args, **kwds):
+        _set_up()
+        try:
+            function(*args, **kwds)
+        finally:
+            _tear_down()
+    try:
+        wrapper.func_name = '%s_ext' % function.func_name
+    except TypeError:
+        pass
+    wrapper.unittest_name = '%s_ext' % function.func_name
+    wrapper.unittest = function.unittest
+    wrapper.skip = getattr(function, 'skip', [])+['.skip-ext']
+    return wrapper
+
+def wrap_ext(collections):
+    functions = []
+    if not isinstance(collections, list):
+        collections = [collections]
+    for collection in collections:
+        if not isinstance(collection, dict):
+            collection = vars(collection)
+        keys = collection.keys()
+        keys.sort()
+        for key in keys:
+            value = collection[key]
+            if isinstance(value, types.FunctionType) and hasattr(value, 'unittest'):
+                functions.append(wrap_ext_function(value))
+    for function in functions:
+        assert function.unittest_name not in globals()
+        globals()[function.unittest_name] = function
+
+import test_tokens, test_structure, test_errors, test_resolver, test_constructor,   \
+        test_emitter, test_representer, test_recursive, test_input_output
+wrap_ext([test_tokens, test_structure, test_errors, test_resolver, test_constructor,
+        test_emitter, test_representer, test_recursive, test_input_output])
+
+if __name__ == '__main__':
+    import test_appliance
+    test_appliance.run(globals())
+
diff --git a/tests/lib3/canonical.py b/tests/lib3/canonical.py
new file mode 100644
index 0000000..a8b4e3a
--- /dev/null
+++ b/tests/lib3/canonical.py
@@ -0,0 +1,361 @@
+
+import yaml, yaml.composer, yaml.constructor, yaml.resolver
+
+class CanonicalError(yaml.YAMLError):
+    pass
+
+class CanonicalScanner:
+
+    def __init__(self, data):
+        if isinstance(data, bytes):
+            try:
+                data = data.decode('utf-8')
+            except UnicodeDecodeError:
+                raise CanonicalError("utf-8 stream is expected")
+        self.data = data+'\0'
+        self.index = 0
+        self.tokens = []
+        self.scanned = False
+
+    def check_token(self, *choices):
+        if not self.scanned:
+            self.scan()
+        if self.tokens:
+            if not choices:
+                return True
+            for choice in choices:
+                if isinstance(self.tokens[0], choice):
+                    return True
+        return False
+
+    def peek_token(self):
+        if not self.scanned:
+            self.scan()
+        if self.tokens:
+            return self.tokens[0]
+
+    def get_token(self, choice=None):
+        if not self.scanned:
+            self.scan()
+        token = self.tokens.pop(0)
+        if choice and not isinstance(token, choice):
+            raise CanonicalError("unexpected token "+repr(token))
+        return token
+
+    def get_token_value(self):
+        token = self.get_token()
+        return token.value
+
+    def scan(self):
+        self.tokens.append(yaml.StreamStartToken(None, None))
+        while True:
+            self.find_token()
+            ch = self.data[self.index]
+            if ch == '\0':
+                self.tokens.append(yaml.StreamEndToken(None, None))
+                break
+            elif ch == '%':
+                self.tokens.append(self.scan_directive())
+            elif ch == '-' and self.data[self.index:self.index+3] == '---':
+                self.index += 3
+                self.tokens.append(yaml.DocumentStartToken(None, None))
+            elif ch == '[':
+                self.index += 1
+                self.tokens.append(yaml.FlowSequenceStartToken(None, None))
+            elif ch == '{':
+                self.index += 1
+                self.tokens.append(yaml.FlowMappingStartToken(None, None))
+            elif ch == ']':
+                self.index += 1
+                self.tokens.append(yaml.FlowSequenceEndToken(None, None))
+            elif ch == '}':
+                self.index += 1
+                self.tokens.append(yaml.FlowMappingEndToken(None, None))
+            elif ch == '?':
+                self.index += 1
+                self.tokens.append(yaml.KeyToken(None, None))
+            elif ch == ':':
+                self.index += 1
+                self.tokens.append(yaml.ValueToken(None, None))
+            elif ch == ',':
+                self.index += 1
+                self.tokens.append(yaml.FlowEntryToken(None, None))
+            elif ch == '*' or ch == '&':
+                self.tokens.append(self.scan_alias())
+            elif ch == '!':
+                self.tokens.append(self.scan_tag())
+            elif ch == '"':
+                self.tokens.append(self.scan_scalar())
+            else:
+                raise CanonicalError("invalid token")
+        self.scanned = True
+
+    DIRECTIVE = '%YAML 1.1'
+
+    def scan_directive(self):
+        if self.data[self.index:self.index+len(self.DIRECTIVE)] == self.DIRECTIVE and \
+                self.data[self.index+len(self.DIRECTIVE)] in ' \n\0':
+            self.index += len(self.DIRECTIVE)
+            return yaml.DirectiveToken('YAML', (1, 1), None, None)
+        else:
+            raise CanonicalError("invalid directive")
+
+    def scan_alias(self):
+        if self.data[self.index] == '*':
+            TokenClass = yaml.AliasToken
+        else:
+            TokenClass = yaml.AnchorToken
+        self.index += 1
+        start = self.index
+        while self.data[self.index] not in ', \n\0':
+            self.index += 1
+        value = self.data[start:self.index]
+        return TokenClass(value, None, None)
+
+    def scan_tag(self):
+        self.index += 1
+        start = self.index
+        while self.data[self.index] not in ' \n\0':
+            self.index += 1
+        value = self.data[start:self.index]
+        if not value:
+            value = '!'
+        elif value[0] == '!':
+            value = 'tag:yaml.org,2002:'+value[1:]
+        elif value[0] == '<' and value[-1] == '>':
+            value = value[1:-1]
+        else:
+            value = '!'+value
+        return yaml.TagToken(value, None, None)
+
+    QUOTE_CODES = {
+        'x': 2,
+        'u': 4,
+        'U': 8,
+    }
+
+    QUOTE_REPLACES = {
+        '\\': '\\',
+        '\"': '\"',
+        ' ': ' ',
+        'a': '\x07',
+        'b': '\x08',
+        'e': '\x1B',
+        'f': '\x0C',
+        'n': '\x0A',
+        'r': '\x0D',
+        't': '\x09',
+        'v': '\x0B',
+        'N': '\u0085',
+        'L': '\u2028',
+        'P': '\u2029',
+        '_': '_',
+        '0': '\x00',
+    }
+
+    def scan_scalar(self):
+        self.index += 1
+        chunks = []
+        start = self.index
+        ignore_spaces = False
+        while self.data[self.index] != '"':
+            if self.data[self.index] == '\\':
+                ignore_spaces = False
+                chunks.append(self.data[start:self.index])
+                self.index += 1
+                ch = self.data[self.index]
+                self.index += 1
+                if ch == '\n':
+                    ignore_spaces = True
+                elif ch in self.QUOTE_CODES:
+                    length = self.QUOTE_CODES[ch]
+                    code = int(self.data[self.index:self.index+length], 16)
+                    chunks.append(chr(code))
+                    self.index += length
+                else:
+                    if ch not in self.QUOTE_REPLACES:
+                        raise CanonicalError("invalid escape code")
+                    chunks.append(self.QUOTE_REPLACES[ch])
+                start = self.index
+            elif self.data[self.index] == '\n':
+                chunks.append(self.data[start:self.index])
+                chunks.append(' ')
+                self.index += 1
+                start = self.index
+                ignore_spaces = True
+            elif ignore_spaces and self.data[self.index] == ' ':
+                self.index += 1
+                start = self.index
+            else:
+                ignore_spaces = False
+                self.index += 1
+        chunks.append(self.data[start:self.index])
+        self.index += 1
+        return yaml.ScalarToken(''.join(chunks), False, None, None)
+
+    def find_token(self):
+        found = False
+        while not found:
+            while self.data[self.index] in ' \t':
+                self.index += 1
+            if self.data[self.index] == '#':
+                while self.data[self.index] != '\n':
+                    self.index += 1
+            if self.data[self.index] == '\n':
+                self.index += 1
+            else:
+                found = True
+
+class CanonicalParser:
+
+    def __init__(self):
+        self.events = []
+        self.parsed = False
+
+    def dispose(self):
+        pass
+
+    # stream: STREAM-START document* STREAM-END
+    def parse_stream(self):
+        self.get_token(yaml.StreamStartToken)
+        self.events.append(yaml.StreamStartEvent(None, None))
+        while not self.check_token(yaml.StreamEndToken):
+            if self.check_token(yaml.DirectiveToken, yaml.DocumentStartToken):
+                self.parse_document()
+            else:
+                raise CanonicalError("document is expected, got "+repr(self.tokens[0]))
+        self.get_token(yaml.StreamEndToken)
+        self.events.append(yaml.StreamEndEvent(None, None))
+
+    # document: DIRECTIVE? DOCUMENT-START node
+    def parse_document(self):
+        node = None
+        if self.check_token(yaml.DirectiveToken):
+            self.get_token(yaml.DirectiveToken)
+        self.get_token(yaml.DocumentStartToken)
+        self.events.append(yaml.DocumentStartEvent(None, None))
+        self.parse_node()
+        self.events.append(yaml.DocumentEndEvent(None, None))
+
+    # node: ALIAS | ANCHOR? TAG? (SCALAR|sequence|mapping)
+    def parse_node(self):
+        if self.check_token(yaml.AliasToken):
+            self.events.append(yaml.AliasEvent(self.get_token_value(), None, None))
+        else:
+            anchor = None
+            if self.check_token(yaml.AnchorToken):
+                anchor = self.get_token_value()
+            tag = None
+            if self.check_token(yaml.TagToken):
+                tag = self.get_token_value()
+            if self.check_token(yaml.ScalarToken):
+                self.events.append(yaml.ScalarEvent(anchor, tag, (False, False), self.get_token_value(), None, None))
+            elif self.check_token(yaml.FlowSequenceStartToken):
+                self.events.append(yaml.SequenceStartEvent(anchor, tag, None, None))
+                self.parse_sequence()
+            elif self.check_token(yaml.FlowMappingStartToken):
+                self.events.append(yaml.MappingStartEvent(anchor, tag, None, None))
+                self.parse_mapping()
+            else:
+                raise CanonicalError("SCALAR, '[', or '{' is expected, got "+repr(self.tokens[0]))
+
+    # sequence: SEQUENCE-START (node (ENTRY node)*)? ENTRY? SEQUENCE-END
+    def parse_sequence(self):
+        self.get_token(yaml.FlowSequenceStartToken)
+        if not self.check_token(yaml.FlowSequenceEndToken):
+            self.parse_node()
+            while not self.check_token(yaml.FlowSequenceEndToken):
+                self.get_token(yaml.FlowEntryToken)
+                if not self.check_token(yaml.FlowSequenceEndToken):
+                    self.parse_node()
+        self.get_token(yaml.FlowSequenceEndToken)
+        self.events.append(yaml.SequenceEndEvent(None, None))
+
+    # mapping: MAPPING-START (map_entry (ENTRY map_entry)*)? ENTRY? MAPPING-END
+    def parse_mapping(self):
+        self.get_token(yaml.FlowMappingStartToken)
+        if not self.check_token(yaml.FlowMappingEndToken):
+            self.parse_map_entry()
+            while not self.check_token(yaml.FlowMappingEndToken):
+                self.get_token(yaml.FlowEntryToken)
+                if not self.check_token(yaml.FlowMappingEndToken):
+                    self.parse_map_entry()
+        self.get_token(yaml.FlowMappingEndToken)
+        self.events.append(yaml.MappingEndEvent(None, None))
+
+    # map_entry: KEY node VALUE node
+    def parse_map_entry(self):
+        self.get_token(yaml.KeyToken)
+        self.parse_node()
+        self.get_token(yaml.ValueToken)
+        self.parse_node()
+
+    def parse(self):
+        self.parse_stream()
+        self.parsed = True
+
+    def get_event(self):
+        if not self.parsed:
+            self.parse()
+        return self.events.pop(0)
+
+    def check_event(self, *choices):
+        if not self.parsed:
+            self.parse()
+        if self.events:
+            if not choices:
+                return True
+            for choice in choices:
+                if isinstance(self.events[0], choice):
+                    return True
+        return False
+
+    def peek_event(self):
+        if not self.parsed:
+            self.parse()
+        return self.events[0]
+
+class CanonicalLoader(CanonicalScanner, CanonicalParser,
+        yaml.composer.Composer, yaml.constructor.Constructor, yaml.resolver.Resolver):
+
+    def __init__(self, stream):
+        if hasattr(stream, 'read'):
+            stream = stream.read()
+        CanonicalScanner.__init__(self, stream)
+        CanonicalParser.__init__(self)
+        yaml.composer.Composer.__init__(self)
+        yaml.constructor.Constructor.__init__(self)
+        yaml.resolver.Resolver.__init__(self)
+
+yaml.CanonicalLoader = CanonicalLoader
+
+def canonical_scan(stream):
+    return yaml.scan(stream, Loader=CanonicalLoader)
+
+yaml.canonical_scan = canonical_scan
+
+def canonical_parse(stream):
+    return yaml.parse(stream, Loader=CanonicalLoader)
+
+yaml.canonical_parse = canonical_parse
+
+def canonical_compose(stream):
+    return yaml.compose(stream, Loader=CanonicalLoader)
+
+yaml.canonical_compose = canonical_compose
+
+def canonical_compose_all(stream):
+    return yaml.compose_all(stream, Loader=CanonicalLoader)
+
+yaml.canonical_compose_all = canonical_compose_all
+
+def canonical_load(stream):
+    return yaml.load(stream, Loader=CanonicalLoader)
+
+yaml.canonical_load = canonical_load
+
+def canonical_load_all(stream):
+    return yaml.load_all(stream, Loader=CanonicalLoader)
+
+yaml.canonical_load_all = canonical_load_all
+
diff --git a/tests/lib3/test_all.py b/tests/lib3/test_all.py
new file mode 100644
index 0000000..fec4ae4
--- /dev/null
+++ b/tests/lib3/test_all.py
@@ -0,0 +1,15 @@
+
+import sys, yaml, test_appliance
+
+def main(args=None):
+    collections = []
+    import test_yaml
+    collections.append(test_yaml)
+    if yaml.__with_libyaml__:
+        import test_yaml_ext
+        collections.append(test_yaml_ext)
+    test_appliance.run(collections, args)
+
+if __name__ == '__main__':
+    main()
+
diff --git a/tests/lib3/test_appliance.py b/tests/lib3/test_appliance.py
new file mode 100644
index 0000000..81ff00b
--- /dev/null
+++ b/tests/lib3/test_appliance.py
@@ -0,0 +1,145 @@
+
+import sys, os, os.path, types, traceback, pprint
+
+DATA = 'tests/data'
+
+def find_test_functions(collections):
+    if not isinstance(collections, list):
+        collections = [collections]
+    functions = []
+    for collection in collections:
+        if not isinstance(collection, dict):
+            collection = vars(collection)
+        for key in sorted(collection):
+            value = collection[key]
+            if isinstance(value, types.FunctionType) and hasattr(value, 'unittest'):
+                functions.append(value)
+    return functions
+
+def find_test_filenames(directory):
+    filenames = {}
+    for filename in os.listdir(directory):
+        if os.path.isfile(os.path.join(directory, filename)):
+            base, ext = os.path.splitext(filename)
+            if base.endswith('-py2'):
+                continue
+            filenames.setdefault(base, []).append(ext)
+    filenames = sorted(filenames.items())
+    return filenames
+
+def parse_arguments(args):
+    if args is None:
+        args = sys.argv[1:]
+    verbose = False
+    if '-v' in args:
+        verbose = True
+        args.remove('-v')
+    if '--verbose' in args:
+        verbose = True
+    if 'YAML_TEST_VERBOSE' in os.environ:
+        verbose = True
+    include_functions = []
+    if args:
+        include_functions.append(args.pop(0))
+    if 'YAML_TEST_FUNCTIONS' in os.environ:
+        include_functions.extend(os.environ['YAML_TEST_FUNCTIONS'].split())
+    include_filenames = []
+    include_filenames.extend(args)
+    if 'YAML_TEST_FILENAMES' in os.environ:
+        include_filenames.extend(os.environ['YAML_TEST_FILENAMES'].split())
+    return include_functions, include_filenames, verbose
+
+def execute(function, filenames, verbose):
+    name = function.__name__
+    if verbose:
+        sys.stdout.write('='*75+'\n')
+        sys.stdout.write('%s(%s)...\n' % (name, ', '.join(filenames)))
+    try:
+        function(verbose=verbose, *filenames)
+    except Exception as exc:
+        info = sys.exc_info()
+        if isinstance(exc, AssertionError):
+            kind = 'FAILURE'
+        else:
+            kind = 'ERROR'
+        if verbose:
+            traceback.print_exc(limit=1, file=sys.stdout)
+        else:
+            sys.stdout.write(kind[0])
+            sys.stdout.flush()
+    else:
+        kind = 'SUCCESS'
+        info = None
+        if not verbose:
+            sys.stdout.write('.')
+    sys.stdout.flush()
+    return (name, filenames, kind, info)
+
+def display(results, verbose):
+    if results and not verbose:
+        sys.stdout.write('\n')
+    total = len(results)
+    failures = 0
+    errors = 0
+    for name, filenames, kind, info in results:
+        if kind == 'SUCCESS':
+            continue
+        if kind == 'FAILURE':
+            failures += 1
+        if kind == 'ERROR':
+            errors += 1
+        sys.stdout.write('='*75+'\n')
+        sys.stdout.write('%s(%s): %s\n' % (name, ', '.join(filenames), kind))
+        if kind == 'ERROR':
+            traceback.print_exception(file=sys.stdout, *info)
+        else:
+            sys.stdout.write('Traceback (most recent call last):\n')
+            traceback.print_tb(info[2], file=sys.stdout)
+            sys.stdout.write('%s: see below\n' % info[0].__name__)
+            sys.stdout.write('~'*75+'\n')
+            for arg in info[1].args:
+                pprint.pprint(arg, stream=sys.stdout)
+        for filename in filenames:
+            sys.stdout.write('-'*75+'\n')
+            sys.stdout.write('%s:\n' % filename)
+            data = open(filename, 'r', errors='replace').read()
+            sys.stdout.write(data)
+            if data and data[-1] != '\n':
+                sys.stdout.write('\n')
+    sys.stdout.write('='*75+'\n')
+    sys.stdout.write('TESTS: %s\n' % total)
+    if failures:
+        sys.stdout.write('FAILURES: %s\n' % failures)
+    if errors:
+        sys.stdout.write('ERRORS: %s\n' % errors)
+
+def run(collections, args=None):
+    test_functions = find_test_functions(collections)
+    test_filenames = find_test_filenames(DATA)
+    include_functions, include_filenames, verbose = parse_arguments(args)
+    results = []
+    for function in test_functions:
+        if include_functions and function.__name__ not in include_functions:
+            continue
+        if function.unittest:
+            for base, exts in test_filenames:
+                if include_filenames and base not in include_filenames:
+                    continue
+                filenames = []
+                for ext in function.unittest:
+                    if ext not in exts:
+                        break
+                    filenames.append(os.path.join(DATA, base+ext))
+                else:
+                    skip_exts = getattr(function, 'skip', [])
+                    for skip_ext in skip_exts:
+                        if skip_ext in exts:
+                            break
+                    else:
+                        result = execute(function, filenames, verbose)
+                        results.append(result)
+        else:
+            result = execute(function, [], verbose)
+            results.append(result)
+    display(results, verbose=verbose)
+
diff --git a/tests/lib3/test_build.py b/tests/lib3/test_build.py
new file mode 100644
index 0000000..901e8ed
--- /dev/null
+++ b/tests/lib3/test_build.py
@@ -0,0 +1,10 @@
+
+if __name__ == '__main__':
+    import sys, os, distutils.util
+    build_lib = 'build/lib'
+    build_lib_ext = os.path.join('build', 'lib.%s-%s' % (distutils.util.get_platform(), sys.version[0:3]))
+    sys.path.insert(0, build_lib)
+    sys.path.insert(0, build_lib_ext)
+    import test_yaml, test_appliance
+    test_appliance.run(test_yaml)
+
diff --git a/tests/lib3/test_build_ext.py b/tests/lib3/test_build_ext.py
new file mode 100644
index 0000000..ff195d5
--- /dev/null
+++ b/tests/lib3/test_build_ext.py
@@ -0,0 +1,11 @@
+
+
+if __name__ == '__main__':
+    import sys, os, distutils.util
+    build_lib = 'build/lib'
+    build_lib_ext = os.path.join('build', 'lib.%s-%s' % (distutils.util.get_platform(), sys.version[0:3]))
+    sys.path.insert(0, build_lib)
+    sys.path.insert(0, build_lib_ext)
+    import test_yaml_ext, test_appliance
+    test_appliance.run(test_yaml_ext)
+
diff --git a/tests/lib3/test_canonical.py b/tests/lib3/test_canonical.py
new file mode 100644
index 0000000..a3b1153
--- /dev/null
+++ b/tests/lib3/test_canonical.py
@@ -0,0 +1,40 @@
+
+import yaml, canonical
+
+def test_canonical_scanner(canonical_filename, verbose=False):
+    data = open(canonical_filename, 'rb').read()
+    tokens = list(yaml.canonical_scan(data))
+    assert tokens, tokens
+    if verbose:
+        for token in tokens:
+            print(token)
+
+test_canonical_scanner.unittest = ['.canonical']
+
+def test_canonical_parser(canonical_filename, verbose=False):
+    data = open(canonical_filename, 'rb').read()
+    events = list(yaml.canonical_parse(data))
+    assert events, events
+    if verbose:
+        for event in events:
+            print(event)
+
+test_canonical_parser.unittest = ['.canonical']
+
+def test_canonical_error(data_filename, canonical_filename, verbose=False):
+    data = open(data_filename, 'rb').read()
+    try:
+        output = list(yaml.canonical_load_all(data))
+    except yaml.YAMLError as exc:
+        if verbose:
+            print(exc)
+    else:
+        raise AssertionError("expected an exception")
+
+test_canonical_error.unittest = ['.data', '.canonical']
+test_canonical_error.skip = ['.empty']
+
+if __name__ == '__main__':
+    import test_appliance
+    test_appliance.run(globals())
+
diff --git a/tests/lib3/test_constructor.py b/tests/lib3/test_constructor.py
new file mode 100644
index 0000000..427f53c
--- /dev/null
+++ b/tests/lib3/test_constructor.py
@@ -0,0 +1,260 @@
+
+import yaml
+import pprint
+
+import datetime
+import yaml.tokens
+
+def execute(code):
+    global value
+    exec(code)
+    return value
+
+def _make_objects():
+    global MyLoader, MyDumper, MyTestClass1, MyTestClass2, MyTestClass3, YAMLObject1, YAMLObject2,  \
+            AnObject, AnInstance, AState, ACustomState, InitArgs, InitArgsWithState,    \
+            NewArgs, NewArgsWithState, Reduce, ReduceWithState, MyInt, MyList, MyDict,  \
+            FixedOffset, today, execute
+
+    class MyLoader(yaml.Loader):
+        pass
+    class MyDumper(yaml.Dumper):
+        pass
+
+    class MyTestClass1:
+        def __init__(self, x, y=0, z=0):
+            self.x = x
+            self.y = y
+            self.z = z
+        def __eq__(self, other):
+            if isinstance(other, MyTestClass1):
+                return self.__class__, self.__dict__ == other.__class__, other.__dict__
+            else:
+                return False
+
+    def construct1(constructor, node):
+        mapping = constructor.construct_mapping(node)
+        return MyTestClass1(**mapping)
+    def represent1(representer, native):
+        return representer.represent_mapping("!tag1", native.__dict__)
+
+    yaml.add_constructor("!tag1", construct1, Loader=MyLoader)
+    yaml.add_representer(MyTestClass1, represent1, Dumper=MyDumper)
+
+    class MyTestClass2(MyTestClass1, yaml.YAMLObject):
+        yaml_loader = MyLoader
+        yaml_dumper = MyDumper
+        yaml_tag = "!tag2"
+        def from_yaml(cls, constructor, node):
+            x = constructor.construct_yaml_int(node)
+            return cls(x=x)
+        from_yaml = classmethod(from_yaml)
+        def to_yaml(cls, representer, native):
+            return representer.represent_scalar(cls.yaml_tag, str(native.x))
+        to_yaml = classmethod(to_yaml)
+
+    class MyTestClass3(MyTestClass2):
+        yaml_tag = "!tag3"
+        def from_yaml(cls, constructor, node):
+            mapping = constructor.construct_mapping(node)
+            if '=' in mapping:
+                x = mapping['=']
+                del mapping['=']
+                mapping['x'] = x
+            return cls(**mapping)
+        from_yaml = classmethod(from_yaml)
+        def to_yaml(cls, representer, native):
+            return representer.represent_mapping(cls.yaml_tag, native.__dict__)
+        to_yaml = classmethod(to_yaml)
+
+    class YAMLObject1(yaml.YAMLObject):
+        yaml_loader = MyLoader
+        yaml_dumper = MyDumper
+        yaml_tag = '!foo'
+        def __init__(self, my_parameter=None, my_another_parameter=None):
+            self.my_parameter = my_parameter
+            self.my_another_parameter = my_another_parameter
+        def __eq__(self, other):
+            if isinstance(other, YAMLObject1):
+                return self.__class__, self.__dict__ == other.__class__, other.__dict__
+            else:
+                return False
+
+    class YAMLObject2(yaml.YAMLObject):
+        yaml_loader = MyLoader
+        yaml_dumper = MyDumper
+        yaml_tag = '!bar'
+        def __init__(self, foo=1, bar=2, baz=3):
+            self.foo = foo
+            self.bar = bar
+            self.baz = baz
+        def __getstate__(self):
+            return {1: self.foo, 2: self.bar, 3: self.baz}
+        def __setstate__(self, state):
+            self.foo = state[1]
+            self.bar = state[2]
+            self.baz = state[3]
+        def __eq__(self, other):
+            if isinstance(other, YAMLObject2):
+                return self.__class__, self.__dict__ == other.__class__, other.__dict__
+            else:
+                return False
+
+    class AnObject:
+        def __new__(cls, foo=None, bar=None, baz=None):
+            self = object.__new__(cls)
+            self.foo = foo
+            self.bar = bar
+            self.baz = baz
+            return self
+        def __cmp__(self, other):
+            return cmp((type(self), self.foo, self.bar, self.baz),
+                    (type(other), other.foo, other.bar, other.baz))
+        def __eq__(self, other):
+            return type(self) is type(other) and    \
+                    (self.foo, self.bar, self.baz) == (other.foo, other.bar, other.baz)
+
+    class AnInstance:
+        def __init__(self, foo=None, bar=None, baz=None):
+            self.foo = foo
+            self.bar = bar
+            self.baz = baz
+        def __cmp__(self, other):
+            return cmp((type(self), self.foo, self.bar, self.baz),
+                    (type(other), other.foo, other.bar, other.baz))
+        def __eq__(self, other):
+            return type(self) is type(other) and    \
+                    (self.foo, self.bar, self.baz) == (other.foo, other.bar, other.baz)
+
+    class AState(AnInstance):
+        def __getstate__(self):
+            return {
+                '_foo': self.foo,
+                '_bar': self.bar,
+                '_baz': self.baz,
+            }
+        def __setstate__(self, state):
+            self.foo = state['_foo']
+            self.bar = state['_bar']
+            self.baz = state['_baz']
+
+    class ACustomState(AnInstance):
+        def __getstate__(self):
+            return (self.foo, self.bar, self.baz)
+        def __setstate__(self, state):
+            self.foo, self.bar, self.baz = state
+
+    class NewArgs(AnObject):
+        def __getnewargs__(self):
+            return (self.foo, self.bar, self.baz)
+        def __getstate__(self):
+            return {}
+
+    class NewArgsWithState(AnObject):
+        def __getnewargs__(self):
+            return (self.foo, self.bar)
+        def __getstate__(self):
+            return self.baz
+        def __setstate__(self, state):
+            self.baz = state
+
+    InitArgs = NewArgs
+
+    InitArgsWithState = NewArgsWithState
+
+    class Reduce(AnObject):
+        def __reduce__(self):
+            return self.__class__, (self.foo, self.bar, self.baz)
+
+    class ReduceWithState(AnObject):
+        def __reduce__(self):
+            return self.__class__, (self.foo, self.bar), self.baz
+        def __setstate__(self, state):
+            self.baz = state
+
+    class MyInt(int):
+        def __eq__(self, other):
+            return type(self) is type(other) and int(self) == int(other)
+
+    class MyList(list):
+        def __init__(self, n=1):
+            self.extend([None]*n)
+        def __eq__(self, other):
+            return type(self) is type(other) and list(self) == list(other)
+
+    class MyDict(dict):
+        def __init__(self, n=1):
+            for k in range(n):
+                self[k] = None
+        def __eq__(self, other):
+            return type(self) is type(other) and dict(self) == dict(other)
+
+    class FixedOffset(datetime.tzinfo):
+        def __init__(self, offset, name):
+            self.__offset = datetime.timedelta(minutes=offset)
+            self.__name = name
+        def utcoffset(self, dt):
+            return self.__offset
+        def tzname(self, dt):
+            return self.__name
+        def dst(self, dt):
+            return datetime.timedelta(0)
+
+    today = datetime.date.today()
+
+def _load_code(expression):
+    return eval(expression)
+
+def _serialize_value(data):
+    if isinstance(data, list):
+        return '[%s]' % ', '.join(map(_serialize_value, data))
+    elif isinstance(data, dict):
+        items = []
+        for key, value in data.items():
+            key = _serialize_value(key)
+            value = _serialize_value(value)
+            items.append("%s: %s" % (key, value))
+        items.sort()
+        return '{%s}' % ', '.join(items)
+    elif isinstance(data, datetime.datetime):
+        return repr(data.utctimetuple())
+    elif isinstance(data, float) and data != data:
+        return '?'
+    else:
+        return str(data)
+
+def test_constructor_types(data_filename, code_filename, verbose=False):
+    _make_objects()
+    native1 = None
+    native2 = None
+    try:
+        native1 = list(yaml.load_all(open(data_filename, 'rb'), Loader=MyLoader))
+        if len(native1) == 1:
+            native1 = native1[0]
+        native2 = _load_code(open(code_filename, 'rb').read())
+        try:
+            if native1 == native2:
+                return
+        except TypeError:
+            pass
+        if verbose:
+            print("SERIALIZED NATIVE1:")
+            print(_serialize_value(native1))
+            print("SERIALIZED NATIVE2:")
+            print(_serialize_value(native2))
+        assert _serialize_value(native1) == _serialize_value(native2), (native1, native2)
+    finally:
+        if verbose:
+            print("NATIVE1:")
+            pprint.pprint(native1)
+            print("NATIVE2:")
+            pprint.pprint(native2)
+
+test_constructor_types.unittest = ['.data', '.code']
+
+if __name__ == '__main__':
+    import sys, test_constructor
+    sys.modules['test_constructor'] = sys.modules['__main__']
+    import test_appliance
+    test_appliance.run(globals())
+
diff --git a/tests/lib3/test_emitter.py b/tests/lib3/test_emitter.py
new file mode 100644
index 0000000..90d1652
--- /dev/null
+++ b/tests/lib3/test_emitter.py
@@ -0,0 +1,100 @@
+
+import yaml
+
+def _compare_events(events1, events2):
+    assert len(events1) == len(events2), (events1, events2)
+    for event1, event2 in zip(events1, events2):
+        assert event1.__class__ == event2.__class__, (event1, event2)
+        if isinstance(event1, yaml.NodeEvent):
+            assert event1.anchor == event2.anchor, (event1, event2)
+        if isinstance(event1, yaml.CollectionStartEvent):
+            assert event1.tag == event2.tag, (event1, event2)
+        if isinstance(event1, yaml.ScalarEvent):
+            if True not in event1.implicit+event2.implicit:
+                assert event1.tag == event2.tag, (event1, event2)
+            assert event1.value == event2.value, (event1, event2)
+
+def test_emitter_on_data(data_filename, canonical_filename, verbose=False):
+    events = list(yaml.parse(open(data_filename, 'rb')))
+    output = yaml.emit(events)
+    if verbose:
+        print("OUTPUT:")
+        print(output)
+    new_events = list(yaml.parse(output))
+    _compare_events(events, new_events)
+
+test_emitter_on_data.unittest = ['.data', '.canonical']
+
+def test_emitter_on_canonical(canonical_filename, verbose=False):
+    events = list(yaml.parse(open(canonical_filename, 'rb')))
+    for canonical in [False, True]:
+        output = yaml.emit(events, canonical=canonical)
+        if verbose:
+            print("OUTPUT (canonical=%s):" % canonical)
+            print(output)
+        new_events = list(yaml.parse(output))
+        _compare_events(events, new_events)
+
+test_emitter_on_canonical.unittest = ['.canonical']
+
+def test_emitter_styles(data_filename, canonical_filename, verbose=False):
+    for filename in [data_filename, canonical_filename]:
+        events = list(yaml.parse(open(filename, 'rb')))
+        for flow_style in [False, True]:
+            for style in ['|', '>', '"', '\'', '']:
+                styled_events = []
+                for event in events:
+                    if isinstance(event, yaml.ScalarEvent):
+                        event = yaml.ScalarEvent(event.anchor, event.tag,
+                                event.implicit, event.value, style=style)
+                    elif isinstance(event, yaml.SequenceStartEvent):
+                        event = yaml.SequenceStartEvent(event.anchor, event.tag,
+                                event.implicit, flow_style=flow_style)
+                    elif isinstance(event, yaml.MappingStartEvent):
+                        event = yaml.MappingStartEvent(event.anchor, event.tag,
+                                event.implicit, flow_style=flow_style)
+                    styled_events.append(event)
+                output = yaml.emit(styled_events)
+                if verbose:
+                    print("OUTPUT (filename=%r, flow_style=%r, style=%r)" % (filename, flow_style, style))
+                    print(output)
+                new_events = list(yaml.parse(output))
+                _compare_events(events, new_events)
+
+test_emitter_styles.unittest = ['.data', '.canonical']
+
+class EventsLoader(yaml.Loader):
+
+    def construct_event(self, node):
+        if isinstance(node, yaml.ScalarNode):
+            mapping = {}
+        else:
+            mapping = self.construct_mapping(node)
+        class_name = str(node.tag[1:])+'Event'
+        if class_name in ['AliasEvent', 'ScalarEvent', 'SequenceStartEvent', 'MappingStartEvent']:
+            mapping.setdefault('anchor', None)
+        if class_name in ['ScalarEvent', 'SequenceStartEvent', 'MappingStartEvent']:
+            mapping.setdefault('tag', None)
+        if class_name in ['SequenceStartEvent', 'MappingStartEvent']:
+            mapping.setdefault('implicit', True)
+        if class_name == 'ScalarEvent':
+            mapping.setdefault('implicit', (False, True))
+            mapping.setdefault('value', '')
+        value = getattr(yaml, class_name)(**mapping)
+        return value
+
+EventsLoader.add_constructor(None, EventsLoader.construct_event)
+
+def test_emitter_events(events_filename, verbose=False):
+    events = list(yaml.load(open(events_filename, 'rb'), Loader=EventsLoader))
+    output = yaml.emit(events)
+    if verbose:
+        print("OUTPUT:")
+        print(output)
+    new_events = list(yaml.parse(output))
+    _compare_events(events, new_events)
+
+if __name__ == '__main__':
+    import test_appliance
+    test_appliance.run(globals())
+
diff --git a/tests/lib3/test_errors.py b/tests/lib3/test_errors.py
new file mode 100644
index 0000000..a3f86af
--- /dev/null
+++ b/tests/lib3/test_errors.py
@@ -0,0 +1,67 @@
+
+import yaml, test_emitter
+
+def test_loader_error(error_filename, verbose=False):
+    try:
+        list(yaml.load_all(open(error_filename, 'rb')))
+    except yaml.YAMLError as exc:
+        if verbose:
+            print("%s:" % exc.__class__.__name__, exc)
+    else:
+        raise AssertionError("expected an exception")
+
+test_loader_error.unittest = ['.loader-error']
+
+def test_loader_error_string(error_filename, verbose=False):
+    try:
+        list(yaml.load_all(open(error_filename, 'rb').read()))
+    except yaml.YAMLError as exc:
+        if verbose:
+            print("%s:" % exc.__class__.__name__, exc)
+    else:
+        raise AssertionError("expected an exception")
+
+test_loader_error_string.unittest = ['.loader-error']
+
+def test_loader_error_single(error_filename, verbose=False):
+    try:
+        yaml.load(open(error_filename, 'rb').read())
+    except yaml.YAMLError as exc:
+        if verbose:
+            print("%s:" % exc.__class__.__name__, exc)
+    else:
+        raise AssertionError("expected an exception")
+
+test_loader_error_single.unittest = ['.single-loader-error']
+
+def test_emitter_error(error_filename, verbose=False):
+    events = list(yaml.load(open(error_filename, 'rb'),
+                    Loader=test_emitter.EventsLoader))
+    try:
+        yaml.emit(events)
+    except yaml.YAMLError as exc:
+        if verbose:
+            print("%s:" % exc.__class__.__name__, exc)
+    else:
+        raise AssertionError("expected an exception")
+
+test_emitter_error.unittest = ['.emitter-error']
+
+def test_dumper_error(error_filename, verbose=False):
+    code = open(error_filename, 'rb').read()
+    try:
+        import yaml
+        from io import StringIO
+        exec(code)
+    except yaml.YAMLError as exc:
+        if verbose:
+            print("%s:" % exc.__class__.__name__, exc)
+    else:
+        raise AssertionError("expected an exception")
+
+test_dumper_error.unittest = ['.dumper-error']
+
+if __name__ == '__main__':
+    import test_appliance
+    test_appliance.run(globals())
+
diff --git a/tests/lib3/test_input_output.py b/tests/lib3/test_input_output.py
new file mode 100644
index 0000000..70a945a
--- /dev/null
+++ b/tests/lib3/test_input_output.py
@@ -0,0 +1,150 @@
+
+import yaml
+import codecs, io, tempfile, os, os.path
+
+def test_unicode_input(unicode_filename, verbose=False):
+    data = open(unicode_filename, 'rb').read().decode('utf-8')
+    value = ' '.join(data.split())
+    output = yaml.load(data)
+    assert output == value, (output, value)
+    output = yaml.load(io.StringIO(data))
+    assert output == value, (output, value)
+    for input in [data.encode('utf-8'),
+                    codecs.BOM_UTF8+data.encode('utf-8'),
+                    codecs.BOM_UTF16_BE+data.encode('utf-16-be'),
+                    codecs.BOM_UTF16_LE+data.encode('utf-16-le')]:
+        if verbose:
+            print("INPUT:", repr(input[:10]), "...")
+        output = yaml.load(input)
+        assert output == value, (output, value)
+        output = yaml.load(io.BytesIO(input))
+        assert output == value, (output, value)
+
+test_unicode_input.unittest = ['.unicode']
+
+def test_unicode_input_errors(unicode_filename, verbose=False):
+    data = open(unicode_filename, 'rb').read().decode('utf-8')
+    for input in [data.encode('latin1', 'ignore'),
+                    data.encode('utf-16-be'), data.encode('utf-16-le'),
+                    codecs.BOM_UTF8+data.encode('utf-16-be'),
+                    codecs.BOM_UTF16_BE+data.encode('utf-16-le'),
+                    codecs.BOM_UTF16_LE+data.encode('utf-8')+b'!']:
+        try:
+            yaml.load(input)
+        except yaml.YAMLError as exc:
+            if verbose:
+                print(exc)
+        else:
+            raise AssertionError("expected an exception")
+        try:
+            yaml.load(io.BytesIO(input))
+        except yaml.YAMLError as exc:
+            if verbose:
+                print(exc)
+        else:
+            raise AssertionError("expected an exception")
+
+test_unicode_input_errors.unittest = ['.unicode']
+
+def test_unicode_output(unicode_filename, verbose=False):
+    data = open(unicode_filename, 'rb').read().decode('utf-8')
+    value = ' '.join(data.split())
+    for allow_unicode in [False, True]:
+        data1 = yaml.dump(value, allow_unicode=allow_unicode)
+        for encoding in [None, 'utf-8', 'utf-16-be', 'utf-16-le']:
+            stream = io.StringIO()
+            yaml.dump(value, stream, encoding=encoding, allow_unicode=allow_unicode)
+            data2 = stream.getvalue()
+            data3 = yaml.dump(value, encoding=encoding, allow_unicode=allow_unicode)
+            if encoding is not None:
+                assert isinstance(data3, bytes)
+                data3 = data3.decode(encoding)
+            stream = io.BytesIO()
+            if encoding is None:
+                try:
+                    yaml.dump(value, stream, encoding=encoding, allow_unicode=allow_unicode)
+                except TypeError as exc:
+                    if verbose:
+                        print(exc)
+                    data4 = None
+                else:
+                    raise AssertionError("expected an exception")
+            else:
+                yaml.dump(value, stream, encoding=encoding, allow_unicode=allow_unicode)
+                data4 = stream.getvalue()
+                if verbose:
+                    print("BYTES:", data4[:50])
+                data4 = data4.decode(encoding)
+            for copy in [data1, data2, data3, data4]:
+                if copy is None:
+                    continue
+                assert isinstance(copy, str)
+                if allow_unicode:
+                    try:
+                        copy[4:].encode('ascii')
+                    except UnicodeEncodeError as exc:
+                        if verbose:
+                            print(exc)
+                    else:
+                        raise AssertionError("expected an exception")
+                else:
+                    copy[4:].encode('ascii')
+            assert isinstance(data1, str), (type(data1), encoding)
+            assert isinstance(data2, str), (type(data2), encoding)
+
+test_unicode_output.unittest = ['.unicode']
+
+def test_file_output(unicode_filename, verbose=False):
+    data = open(unicode_filename, 'rb').read().decode('utf-8')
+    handle, filename = tempfile.mkstemp()
+    os.close(handle)
+    try:
+        stream = io.StringIO()
+        yaml.dump(data, stream, allow_unicode=True)
+        data1 = stream.getvalue()
+        stream = io.BytesIO()
+        yaml.dump(data, stream, encoding='utf-16-le', allow_unicode=True)
+        data2 = stream.getvalue().decode('utf-16-le')[1:]
+        stream = open(filename, 'w', encoding='utf-16-le')
+        yaml.dump(data, stream, allow_unicode=True)
+        stream.close()
+        data3 = open(filename, 'r', encoding='utf-16-le').read()
+        stream = open(filename, 'wb')
+        yaml.dump(data, stream, encoding='utf-8', allow_unicode=True)
+        stream.close()
+        data4 = open(filename, 'r', encoding='utf-8').read()
+        assert data1 == data2, (data1, data2)
+        assert data1 == data3, (data1, data3)
+        assert data1 == data4, (data1, data4)
+    finally:
+        if os.path.exists(filename):
+            os.unlink(filename)
+
+test_file_output.unittest = ['.unicode']
+
+def test_unicode_transfer(unicode_filename, verbose=False):
+    data = open(unicode_filename, 'rb').read().decode('utf-8')
+    for encoding in [None, 'utf-8', 'utf-16-be', 'utf-16-le']:
+        input = data
+        if encoding is not None:
+            input = ('\ufeff'+input).encode(encoding)
+        output1 = yaml.emit(yaml.parse(input), allow_unicode=True)
+        if encoding is None:
+            stream = io.StringIO()
+        else:
+            stream = io.BytesIO()
+        yaml.emit(yaml.parse(input), stream, allow_unicode=True)
+        output2 = stream.getvalue()
+        assert isinstance(output1, str), (type(output1), encoding)
+        if encoding is None:
+            assert isinstance(output2, str), (type(output1), encoding)
+        else:
+            assert isinstance(output2, bytes), (type(output1), encoding)
+            output2.decode(encoding)
+
+test_unicode_transfer.unittest = ['.unicode']
+
+if __name__ == '__main__':
+    import test_appliance
+    test_appliance.run(globals())
+
diff --git a/tests/lib3/test_mark.py b/tests/lib3/test_mark.py
new file mode 100644
index 0000000..09eea2e
--- /dev/null
+++ b/tests/lib3/test_mark.py
@@ -0,0 +1,32 @@
+
+import yaml
+
+def test_marks(marks_filename, verbose=False):
+    inputs = open(marks_filename, 'r').read().split('---\n')[1:]
+    for input in inputs:
+        index = 0
+        line = 0
+        column = 0
+        while input[index] != '*':
+            if input[index] == '\n':
+                line += 1
+                column = 0
+            else:
+                column += 1
+            index += 1
+        mark = yaml.Mark(marks_filename, index, line, column, input, index)
+        snippet = mark.get_snippet(indent=2, max_length=79)
+        if verbose:
+            print(snippet)
+        assert isinstance(snippet, str), type(snippet)
+        assert snippet.count('\n') == 1, snippet.count('\n')
+        data, pointer = snippet.split('\n')
+        assert len(data) < 82, len(data)
+        assert data[len(pointer)-1] == '*', data[len(pointer)-1]
+
+test_marks.unittest = ['.marks']
+
+if __name__ == '__main__':
+    import test_appliance
+    test_appliance.run(globals())
+
diff --git a/tests/lib3/test_reader.py b/tests/lib3/test_reader.py
new file mode 100644
index 0000000..c07b346
--- /dev/null
+++ b/tests/lib3/test_reader.py
@@ -0,0 +1,34 @@
+
+import yaml.reader
+
+def _run_reader(data, verbose):
+    try:
+        stream = yaml.reader.Reader(data)
+        while stream.peek() != '\0':
+            stream.forward()
+    except yaml.reader.ReaderError as exc:
+        if verbose:
+            print(exc)
+    else:
+        raise AssertionError("expected an exception")
+
+def test_stream_error(error_filename, verbose=False):
+    _run_reader(open(error_filename, 'rb'), verbose)
+    _run_reader(open(error_filename, 'rb').read(), verbose)
+    for encoding in ['utf-8', 'utf-16-le', 'utf-16-be']:
+        try:
+            data = open(error_filename, 'rb').read().decode(encoding)
+            break
+        except UnicodeDecodeError:
+            pass
+    else:
+        return
+    _run_reader(data, verbose)
+    _run_reader(open(error_filename, encoding=encoding), verbose)
+
+test_stream_error.unittest = ['.stream-error']
+
+if __name__ == '__main__':
+    import test_appliance
+    test_appliance.run(globals())
+
diff --git a/tests/lib3/test_recursive.py b/tests/lib3/test_recursive.py
new file mode 100644
index 0000000..321a75f
--- /dev/null
+++ b/tests/lib3/test_recursive.py
@@ -0,0 +1,51 @@
+
+import yaml
+
+class AnInstance:
+
+    def __init__(self, foo, bar):
+        self.foo = foo
+        self.bar = bar
+
+    def __repr__(self):
+        try:
+            return "%s(foo=%r, bar=%r)" % (self.__class__.__name__,
+                    self.foo, self.bar)
+        except RuntimeError:
+            return "%s(foo=..., bar=...)" % self.__class__.__name__
+
+class AnInstanceWithState(AnInstance):
+
+    def __getstate__(self):
+        return {'attributes': [self.foo, self.bar]}
+
+    def __setstate__(self, state):
+        self.foo, self.bar = state['attributes']
+
+def test_recursive(recursive_filename, verbose=False):
+    context = globals().copy()
+    exec(open(recursive_filename, 'rb').read(), context)
+    value1 = context['value']
+    output1 = None
+    value2 = None
+    output2 = None
+    try:
+        output1 = yaml.dump(value1)
+        value2 = yaml.load(output1)
+        output2 = yaml.dump(value2)
+        assert output1 == output2, (output1, output2)
+    finally:
+        if verbose:
+            print("VALUE1:", value1)
+            print("VALUE2:", value2)
+            print("OUTPUT1:")
+            print(output1)
+            print("OUTPUT2:")
+            print(output2)
+
+test_recursive.unittest = ['.recursive']
+
+if __name__ == '__main__':
+    import test_appliance
+    test_appliance.run(globals())
+
diff --git a/tests/lib3/test_representer.py b/tests/lib3/test_representer.py
new file mode 100644
index 0000000..10d4a8f
--- /dev/null
+++ b/tests/lib3/test_representer.py
@@ -0,0 +1,43 @@
+
+import yaml
+import test_constructor
+import pprint
+
+def test_representer_types(code_filename, verbose=False):
+    test_constructor._make_objects()
+    for allow_unicode in [False, True]:
+        for encoding in ['utf-8', 'utf-16-be', 'utf-16-le']:
+            native1 = test_constructor._load_code(open(code_filename, 'rb').read())
+            native2 = None
+            try:
+                output = yaml.dump(native1, Dumper=test_constructor.MyDumper,
+                            allow_unicode=allow_unicode, encoding=encoding)
+                native2 = yaml.load(output, Loader=test_constructor.MyLoader)
+                try:
+                    if native1 == native2:
+                        continue
+                except TypeError:
+                    pass
+                value1 = test_constructor._serialize_value(native1)
+                value2 = test_constructor._serialize_value(native2)
+                if verbose:
+                    print("SERIALIZED NATIVE1:")
+                    print(value1)
+                    print("SERIALIZED NATIVE2:")
+                    print(value2)
+                assert value1 == value2, (native1, native2)
+            finally:
+                if verbose:
+                    print("NATIVE1:")
+                    pprint.pprint(native1)
+                    print("NATIVE2:")
+                    pprint.pprint(native2)
+                    print("OUTPUT:")
+                    print(output)
+
+test_representer_types.unittest = ['.code']
+
+if __name__ == '__main__':
+    import test_appliance
+    test_appliance.run(globals())
+
diff --git a/tests/lib3/test_resolver.py b/tests/lib3/test_resolver.py
new file mode 100644
index 0000000..f059dab
--- /dev/null
+++ b/tests/lib3/test_resolver.py
@@ -0,0 +1,92 @@
+
+import yaml
+import pprint
+
+def test_implicit_resolver(data_filename, detect_filename, verbose=False):
+    correct_tag = None
+    node = None
+    try:
+        correct_tag = open(detect_filename, 'r').read().strip()
+        node = yaml.compose(open(data_filename, 'rb'))
+        assert isinstance(node, yaml.SequenceNode), node
+        for scalar in node.value:
+            assert isinstance(scalar, yaml.ScalarNode), scalar
+            assert scalar.tag == correct_tag, (scalar.tag, correct_tag)
+    finally:
+        if verbose:
+            print("CORRECT TAG:", correct_tag)
+            if hasattr(node, 'value'):
+                print("CHILDREN:")
+                pprint.pprint(node.value)
+
+test_implicit_resolver.unittest = ['.data', '.detect']
+
+def _make_path_loader_and_dumper():
+    global MyLoader, MyDumper
+
+    class MyLoader(yaml.Loader):
+        pass
+    class MyDumper(yaml.Dumper):
+        pass
+
+    yaml.add_path_resolver('!root', [],
+            Loader=MyLoader, Dumper=MyDumper)
+    yaml.add_path_resolver('!root/scalar', [], str,
+            Loader=MyLoader, Dumper=MyDumper)
+    yaml.add_path_resolver('!root/key11/key12/*', ['key11', 'key12'],
+            Loader=MyLoader, Dumper=MyDumper)
+    yaml.add_path_resolver('!root/key21/1/*', ['key21', 1],
+            Loader=MyLoader, Dumper=MyDumper)
+    yaml.add_path_resolver('!root/key31/*/*/key14/map', ['key31', None, None, 'key14'], dict,
+            Loader=MyLoader, Dumper=MyDumper)
+
+    return MyLoader, MyDumper
+
+def _convert_node(node):
+    if isinstance(node, yaml.ScalarNode):
+        return (node.tag, node.value)
+    elif isinstance(node, yaml.SequenceNode):
+        value = []
+        for item in node.value:
+            value.append(_convert_node(item))
+        return (node.tag, value)
+    elif isinstance(node, yaml.MappingNode):
+        value = []
+        for key, item in node.value:
+            value.append((_convert_node(key), _convert_node(item)))
+        return (node.tag, value)
+
+def test_path_resolver_loader(data_filename, path_filename, verbose=False):
+    _make_path_loader_and_dumper()
+    nodes1 = list(yaml.compose_all(open(data_filename, 'rb').read(), Loader=MyLoader))
+    nodes2 = list(yaml.compose_all(open(path_filename, 'rb').read()))
+    try:
+        for node1, node2 in zip(nodes1, nodes2):
+            data1 = _convert_node(node1)
+            data2 = _convert_node(node2)
+            assert data1 == data2, (data1, data2)
+    finally:
+        if verbose:
+            print(yaml.serialize_all(nodes1))
+
+test_path_resolver_loader.unittest = ['.data', '.path']
+
+def test_path_resolver_dumper(data_filename, path_filename, verbose=False):
+    _make_path_loader_and_dumper()
+    for filename in [data_filename, path_filename]:
+        output = yaml.serialize_all(yaml.compose_all(open(filename, 'rb')), Dumper=MyDumper)
+        if verbose:
+            print(output)
+        nodes1 = yaml.compose_all(output)
+        nodes2 = yaml.compose_all(open(data_filename, 'rb'))
+        for node1, node2 in zip(nodes1, nodes2):
+            data1 = _convert_node(node1)
+            data2 = _convert_node(node2)
+            assert data1 == data2, (data1, data2)
+
+test_path_resolver_dumper.unittest = ['.data', '.path']
+
+if __name__ == '__main__':
+    import test_appliance
+    test_appliance.run(globals())
+
diff --git a/tests/lib3/test_structure.py b/tests/lib3/test_structure.py
new file mode 100644
index 0000000..6d6f59d
--- /dev/null
+++ b/tests/lib3/test_structure.py
@@ -0,0 +1,187 @@
+
+import yaml, canonical
+import pprint
+
+def _convert_structure(loader):
+    if loader.check_event(yaml.ScalarEvent):
+        event = loader.get_event()
+        if event.tag or event.anchor or event.value:
+            return True
+        else:
+            return None
+    elif loader.check_event(yaml.SequenceStartEvent):
+        loader.get_event()
+        sequence = []
+        while not loader.check_event(yaml.SequenceEndEvent):
+            sequence.append(_convert_structure(loader))
+        loader.get_event()
+        return sequence
+    elif loader.check_event(yaml.MappingStartEvent):
+        loader.get_event()
+        mapping = []
+        while not loader.check_event(yaml.MappingEndEvent):
+            key = _convert_structure(loader)
+            value = _convert_structure(loader)
+            mapping.append((key, value))
+        loader.get_event()
+        return mapping
+    elif loader.check_event(yaml.AliasEvent):
+        loader.get_event()
+        return '*'
+    else:
+        loader.get_event()
+        return '?'
+
+def test_structure(data_filename, structure_filename, verbose=False):
+    nodes1 = []
+    nodes2 = eval(open(structure_filename, 'r').read())
+    try:
+        loader = yaml.Loader(open(data_filename, 'rb'))
+        while loader.check_event():
+            if loader.check_event(yaml.StreamStartEvent, yaml.StreamEndEvent,
+                                yaml.DocumentStartEvent, yaml.DocumentEndEvent):
+                loader.get_event()
+                continue
+            nodes1.append(_convert_structure(loader))
+        if len(nodes1) == 1:
+            nodes1 = nodes1[0]
+        assert nodes1 == nodes2, (nodes1, nodes2)
+    finally:
+        if verbose:
+            print("NODES1:")
+            pprint.pprint(nodes1)
+            print("NODES2:")
+            pprint.pprint(nodes2)
+
+test_structure.unittest = ['.data', '.structure']
+
+def _compare_events(events1, events2, full=False):
+    assert len(events1) == len(events2), (len(events1), len(events2))
+    for event1, event2 in zip(events1, events2):
+        assert event1.__class__ == event2.__class__, (event1, event2)
+        if isinstance(event1, yaml.AliasEvent) and full:
+            assert event1.anchor == event2.anchor, (event1, event2)
+        if isinstance(event1, (yaml.ScalarEvent, yaml.CollectionStartEvent)):
+            if (event1.tag not in [None, '!'] and event2.tag not in [None, '!']) or full:
+                assert event1.tag == event2.tag, (event1, event2)
+        if isinstance(event1, yaml.ScalarEvent):
+            assert event1.value == event2.value, (event1, event2)
+
+def test_parser(data_filename, canonical_filename, verbose=False):
+    events1 = None
+    events2 = None
+    try:
+        events1 = list(yaml.parse(open(data_filename, 'rb')))
+        events2 = list(yaml.canonical_parse(open(canonical_filename, 'rb')))
+        _compare_events(events1, events2)
+    finally:
+        if verbose:
+            print("EVENTS1:")
+            pprint.pprint(events1)
+            print("EVENTS2:")
+            pprint.pprint(events2)
+
+test_parser.unittest = ['.data', '.canonical']
+
+def test_parser_on_canonical(canonical_filename, verbose=False):
+    events1 = None
+    events2 = None
+    try:
+        events1 = list(yaml.parse(open(canonical_filename, 'rb')))
+        events2 = list(yaml.canonical_parse(open(canonical_filename, 'rb')))
+        _compare_events(events1, events2, full=True)
+    finally:
+        if verbose:
+            print("EVENTS1:")
+            pprint.pprint(events1)
+            print("EVENTS2:")
+            pprint.pprint(events2)
+
+test_parser_on_canonical.unittest = ['.canonical']
+
+def _compare_nodes(node1, node2):
+    assert node1.__class__ == node2.__class__, (node1, node2)
+    assert node1.tag == node2.tag, (node1, node2)
+    if isinstance(node1, yaml.ScalarNode):
+        assert node1.value == node2.value, (node1, node2)
+    else:
+        assert len(node1.value) == len(node2.value), (node1, node2)
+        for item1, item2 in zip(node1.value, node2.value):
+            if not isinstance(item1, tuple):
+                item1 = (item1,)
+                item2 = (item2,)
+            for subnode1, subnode2 in zip(item1, item2):
+                _compare_nodes(subnode1, subnode2)
+
+def test_composer(data_filename, canonical_filename, verbose=False):
+    nodes1 = None
+    nodes2 = None
+    try:
+        nodes1 = list(yaml.compose_all(open(data_filename, 'rb')))
+        nodes2 = list(yaml.canonical_compose_all(open(canonical_filename, 'rb')))
+        assert len(nodes1) == len(nodes2), (len(nodes1), len(nodes2))
+        for node1, node2 in zip(nodes1, nodes2):
+            _compare_nodes(node1, node2)
+    finally:
+        if verbose:
+            print("NODES1:")
+            pprint.pprint(nodes1)
+            print("NODES2:")
+            pprint.pprint(nodes2)
+
+test_composer.unittest = ['.data', '.canonical']
+
+def _make_loader():
+    global MyLoader
+
+    class MyLoader(yaml.Loader):
+        def construct_sequence(self, node):
+            return tuple(yaml.Loader.construct_sequence(self, node))
+        def construct_mapping(self, node):
+            pairs = self.construct_pairs(node)
+            pairs.sort(key=(lambda i: str(i)))
+            return pairs
+        def construct_undefined(self, node):
+            return self.construct_scalar(node)
+
+    MyLoader.add_constructor('tag:yaml.org,2002:map', MyLoader.construct_mapping)
+    MyLoader.add_constructor(None, MyLoader.construct_undefined)
+
+def _make_canonical_loader():
+    global MyCanonicalLoader
+
+    class MyCanonicalLoader(yaml.CanonicalLoader):
+        def construct_sequence(self, node):
+            return tuple(yaml.CanonicalLoader.construct_sequence(self, node))
+        def construct_mapping(self, node):
+            pairs = self.construct_pairs(node)
+            pairs.sort(key=(lambda i: str(i)))
+            return pairs
+        def construct_undefined(self, node):
+            return self.construct_scalar(node)
+
+    MyCanonicalLoader.add_constructor('tag:yaml.org,2002:map', MyCanonicalLoader.construct_mapping)
+    MyCanonicalLoader.add_constructor(None, MyCanonicalLoader.construct_undefined)
+
+def test_constructor(data_filename, canonical_filename, verbose=False):
+    _make_loader()
+    _make_canonical_loader()
+    native1 = None
+    native2 = None
+    try:
+        native1 = list(yaml.load_all(open(data_filename, 'rb'), Loader=MyLoader))
+        native2 = list(yaml.load_all(open(canonical_filename, 'rb'), Loader=MyCanonicalLoader))
+        assert native1 == native2, (native1, native2)
+    finally:
+        if verbose:
+            print("NATIVE1:")
+            pprint.pprint(native1)
+            print("NATIVE2:")
+            pprint.pprint(native2)
+
+test_constructor.unittest = ['.data', '.canonical']
+
+if __name__ == '__main__':
+    import test_appliance
+    test_appliance.run(globals())
+
diff --git a/tests/lib3/test_tokens.py b/tests/lib3/test_tokens.py
new file mode 100644
index 0000000..828945a
--- /dev/null
+++ b/tests/lib3/test_tokens.py
@@ -0,0 +1,77 @@
+
+import yaml
+import pprint
+
+# Tokens mnemonic:
+# directive:            %
+# document_start:       ---
+# document_end:         ...
+# alias:                *
+# anchor:               &
+# tag:                  !
+# scalar                _
+# block_sequence_start: [[
+# block_mapping_start:  {{
+# block_end:            ]}
+# flow_sequence_start:  [
+# flow_sequence_end:    ]
+# flow_mapping_start:   {
+# flow_mapping_end:     }
+# entry:                ,
+# key:                  ?
+# value:                :
+
+_replaces = {
+    yaml.DirectiveToken: '%',
+    yaml.DocumentStartToken: '---',
+    yaml.DocumentEndToken: '...',
+    yaml.AliasToken: '*',
+    yaml.AnchorToken: '&',
+    yaml.TagToken: '!',
+    yaml.ScalarToken: '_',
+    yaml.BlockSequenceStartToken: '[[',
+    yaml.BlockMappingStartToken: '{{',
+    yaml.BlockEndToken: ']}',
+    yaml.FlowSequenceStartToken: '[',
+    yaml.FlowSequenceEndToken: ']',
+    yaml.FlowMappingStartToken: '{',
+    yaml.FlowMappingEndToken: '}',
+    yaml.BlockEntryToken: ',',
+    yaml.FlowEntryToken: ',',
+    yaml.KeyToken: '?',
+    yaml.ValueToken: ':',
+}
+
+def test_tokens(data_filename, tokens_filename, verbose=False):
+    tokens1 = []
+    tokens2 = open(tokens_filename, 'r').read().split()
+    try:
+        for token in yaml.scan(open(data_filename, 'rb')):
+            if not isinstance(token, (yaml.StreamStartToken, yaml.StreamEndToken)):
+                tokens1.append(_replaces[token.__class__])
+    finally:
+        if verbose:
+            print("TOKENS1:", ' '.join(tokens1))
+            print("TOKENS2:", ' '.join(tokens2))
+    assert len(tokens1) == len(tokens2), (tokens1, tokens2)
+    for token1, token2 in zip(tokens1, tokens2):
+        assert token1 == token2, (token1, token2)
+
+test_tokens.unittest = ['.data', '.tokens']
+
+def test_scanner(data_filename, canonical_filename, verbose=False):
+    for filename in [data_filename, canonical_filename]:
+        tokens = []
+        try:
+            for token in yaml.scan(open(filename, 'rb')):
+                tokens.append(token.__class__.__name__)
+        finally:
+            if verbose:
+                pprint.pprint(tokens)
+
+test_scanner.unittest = ['.data', '.canonical']
+
+if __name__ == '__main__':
+    import test_appliance
+    test_appliance.run(globals())
+
diff --git a/tests/lib3/test_yaml.py b/tests/lib3/test_yaml.py
new file mode 100644
index 0000000..0927368
--- /dev/null
+++ b/tests/lib3/test_yaml.py
@@ -0,0 +1,18 @@
+
+from test_mark import *
+from test_reader import *
+from test_canonical import *
+from test_tokens import *
+from test_structure import *
+from test_errors import *
+from test_resolver import *
+from test_constructor import *
+from test_emitter import *
+from test_representer import *
+from test_recursive import *
+from test_input_output import *
+
+if __name__ == '__main__':
+    import test_appliance
+    test_appliance.run(globals())
+
diff --git a/tests/lib3/test_yaml_ext.py b/tests/lib3/test_yaml_ext.py
new file mode 100644
index 0000000..93d397b
--- /dev/null
+++ b/tests/lib3/test_yaml_ext.py
@@ -0,0 +1,271 @@
+
+import _yaml, yaml
+import types, pprint
+
+yaml.PyBaseLoader = yaml.BaseLoader
+yaml.PySafeLoader = yaml.SafeLoader
+yaml.PyLoader = yaml.Loader
+yaml.PyBaseDumper = yaml.BaseDumper
+yaml.PySafeDumper = yaml.SafeDumper
+yaml.PyDumper = yaml.Dumper
+
+old_scan = yaml.scan
+def new_scan(stream, Loader=yaml.CLoader):
+    return old_scan(stream, Loader)
+
+old_parse = yaml.parse
+def new_parse(stream, Loader=yaml.CLoader):
+    return old_parse(stream, Loader)
+
+old_compose = yaml.compose
+def new_compose(stream, Loader=yaml.CLoader):
+    return old_compose(stream, Loader)
+
+old_compose_all = yaml.compose_all
+def new_compose_all(stream, Loader=yaml.CLoader):
+    return old_compose_all(stream, Loader)
+
+old_load = yaml.load
+def new_load(stream, Loader=yaml.CLoader):
+    return old_load(stream, Loader)
+
+old_load_all = yaml.load_all
+def new_load_all(stream, Loader=yaml.CLoader):
+    return old_load_all(stream, Loader)
+
+old_safe_load = yaml.safe_load
+def new_safe_load(stream):
+    return old_load(stream, yaml.CSafeLoader)
+
+old_safe_load_all = yaml.safe_load_all
+def new_safe_load_all(stream):
+    return old_load_all(stream, yaml.CSafeLoader)
+
+old_emit = yaml.emit
+def new_emit(events, stream=None, Dumper=yaml.CDumper, **kwds):
+    return old_emit(events, stream, Dumper, **kwds)
+
+old_serialize = yaml.serialize
+def new_serialize(node, stream, Dumper=yaml.CDumper, **kwds):
+    return old_serialize(node, stream, Dumper, **kwds)
+
+old_serialize_all = yaml.serialize_all
+def new_serialize_all(nodes, stream=None, Dumper=yaml.CDumper, **kwds):
+    return old_serialize_all(nodes, stream, Dumper, **kwds)
+
+old_dump = yaml.dump
+def new_dump(data, stream=None, Dumper=yaml.CDumper, **kwds):
+    return old_dump(data, stream, Dumper, **kwds)
+
+old_dump_all = yaml.dump_all
+def new_dump_all(documents, stream=None, Dumper=yaml.CDumper, **kwds):
+    return old_dump_all(documents, stream, Dumper, **kwds)
+
+old_safe_dump = yaml.safe_dump
+def new_safe_dump(data, stream=None, **kwds):
+    return old_dump(data, stream, yaml.CSafeDumper, **kwds)
+
+old_safe_dump_all = yaml.safe_dump_all
+def new_safe_dump_all(documents, stream=None, **kwds):
+    return old_dump_all(documents, stream, yaml.CSafeDumper, **kwds)
+
+def _set_up():
+    yaml.BaseLoader = yaml.CBaseLoader
+    yaml.SafeLoader = yaml.CSafeLoader
+    yaml.Loader = yaml.CLoader
+    yaml.BaseDumper = yaml.CBaseDumper
+    yaml.SafeDumper = yaml.CSafeDumper
+    yaml.Dumper = yaml.CDumper
+    yaml.scan = new_scan
+    yaml.parse = new_parse
+    yaml.compose = new_compose
+    yaml.compose_all = new_compose_all
+    yaml.load = new_load
+    yaml.load_all = new_load_all
+    yaml.safe_load = new_safe_load
+    yaml.safe_load_all = new_safe_load_all
+    yaml.emit = new_emit
+    yaml.serialize = new_serialize
+    yaml.serialize_all = new_serialize_all
+    yaml.dump = new_dump
+    yaml.dump_all = new_dump_all
+    yaml.safe_dump = new_safe_dump
+    yaml.safe_dump_all = new_safe_dump_all
+
+def _tear_down():
+    yaml.BaseLoader = yaml.PyBaseLoader
+    yaml.SafeLoader = yaml.PySafeLoader
+    yaml.Loader = yaml.PyLoader
+    yaml.BaseDumper = yaml.PyBaseDumper
+    yaml.SafeDumper = yaml.PySafeDumper
+    yaml.Dumper = yaml.PyDumper
+    yaml.scan = old_scan
+    yaml.parse = old_parse
+    yaml.compose = old_compose
+    yaml.compose_all = old_compose_all
+    yaml.load = old_load
+    yaml.load_all = old_load_all
+    yaml.safe_load = old_safe_load
+    yaml.safe_load_all = old_safe_load_all
+    yaml.emit = old_emit
+    yaml.serialize = old_serialize
+    yaml.serialize_all = old_serialize_all
+    yaml.dump = old_dump
+    yaml.dump_all = old_dump_all
+    yaml.safe_dump = old_safe_dump
+    yaml.safe_dump_all = old_safe_dump_all
+
+def test_c_version(verbose=False):
+    if verbose:
+        print(_yaml.get_version())
+        print(_yaml.get_version_string())
+    assert ("%s.%s.%s" % _yaml.get_version()) == _yaml.get_version_string(),    \
+            (_yaml.get_version(), _yaml.get_version_string())
+
+def _compare_scanners(py_data, c_data, verbose):
+    py_tokens = list(yaml.scan(py_data, Loader=yaml.PyLoader))
+    c_tokens = []
+    try:
+        for token in yaml.scan(c_data, Loader=yaml.CLoader):
+            c_tokens.append(token)
+        assert len(py_tokens) == len(c_tokens), (len(py_tokens), len(c_tokens))
+        for py_token, c_token in zip(py_tokens, c_tokens):
+            assert py_token.__class__ == c_token.__class__, (py_token, c_token)
+            if hasattr(py_token, 'value'):
+                assert py_token.value == c_token.value, (py_token, c_token)
+            if isinstance(py_token, yaml.StreamEndToken):
+                continue
+            py_start = (py_token.start_mark.index, py_token.start_mark.line, py_token.start_mark.column)
+            py_end = (py_token.end_mark.index, py_token.end_mark.line, py_token.end_mark.column)
+            c_start = (c_token.start_mark.index, c_token.start_mark.line, c_token.start_mark.column)
+            c_end = (c_token.end_mark.index, c_token.end_mark.line, c_token.end_mark.column)
+            assert py_start == c_start, (py_start, c_start)
+            assert py_end == c_end, (py_end, c_end)
+    finally:
+        if verbose:
+            print("PY_TOKENS:")
+            pprint.pprint(py_tokens)
+            print("C_TOKENS:")
+            pprint.pprint(c_tokens)
+
+def test_c_scanner(data_filename, canonical_filename, verbose=False):
+    _compare_scanners(open(data_filename, 'rb'),
+            open(data_filename, 'rb'), verbose)
+    _compare_scanners(open(data_filename, 'rb').read(),
+            open(data_filename, 'rb').read(), verbose)
+    _compare_scanners(open(canonical_filename, 'rb'),
+            open(canonical_filename, 'rb'), verbose)
+    _compare_scanners(open(canonical_filename, 'rb').read(),
+            open(canonical_filename, 'rb').read(), verbose)
+
+test_c_scanner.unittest = ['.data', '.canonical']
+test_c_scanner.skip = ['.skip-ext']
+
+def _compare_parsers(py_data, c_data, verbose):
+    py_events = list(yaml.parse(py_data, Loader=yaml.PyLoader))
+    c_events = []
+    try:
+        for event in yaml.parse(c_data, Loader=yaml.CLoader):
+            c_events.append(event)
+        assert len(py_events) == len(c_events), (len(py_events), len(c_events))
+        for py_event, c_event in zip(py_events, c_events):
+            for attribute in ['__class__', 'anchor', 'tag', 'implicit',
+                                'value', 'explicit', 'version', 'tags']:
+                py_value = getattr(py_event, attribute, None)
+                c_value = getattr(c_event, attribute, None)
+                assert py_value == c_value, (py_event, c_event, attribute)
+    finally:
+        if verbose:
+            print("PY_EVENTS:")
+            pprint.pprint(py_events)
+            print("C_EVENTS:")
+            pprint.pprint(c_events)
+
+def test_c_parser(data_filename, canonical_filename, verbose=False):
+    _compare_parsers(open(data_filename, 'rb'),
+            open(data_filename, 'rb'), verbose)
+    _compare_parsers(open(data_filename, 'rb').read(),
+            open(data_filename, 'rb').read(), verbose)
+    _compare_parsers(open(canonical_filename, 'rb'),
+            open(canonical_filename, 'rb'), verbose)
+    _compare_parsers(open(canonical_filename, 'rb').read(),
+            open(canonical_filename, 'rb').read(), verbose)
+
+test_c_parser.unittest = ['.data', '.canonical']
+test_c_parser.skip = ['.skip-ext']
+
+def _compare_emitters(data, verbose):
+    events = list(yaml.parse(data, Loader=yaml.PyLoader))
+    c_data = yaml.emit(events, Dumper=yaml.CDumper)
+    if verbose:
+        print(c_data)
+    py_events = list(yaml.parse(c_data, Loader=yaml.PyLoader))
+    c_events = list(yaml.parse(c_data, Loader=yaml.CLoader))
+    try:
+        assert len(events) == len(py_events), (len(events), len(py_events))
+        assert len(events) == len(c_events), (len(events), len(c_events))
+        for event, py_event, c_event in zip(events, py_events, c_events):
+            for attribute in ['__class__', 'anchor', 'tag', 'implicit',
+                                'value', 'explicit', 'version', 'tags']:
+                value = getattr(event, attribute, None)
+                py_value = getattr(py_event, attribute, None)
+                c_value = getattr(c_event, attribute, None)
+                if attribute == 'tag' and value in [None, '!'] \
+                        and py_value in [None, '!'] and c_value in [None, '!']:
+                    continue
+                if attribute == 'explicit' and (py_value or c_value):
+                    continue
+                assert value == py_value, (event, py_event, attribute)
+                assert value == c_value, (event, c_event, attribute)
+    finally:
+        if verbose:
+            print("EVENTS:")
+            pprint.pprint(events)
+            print("PY_EVENTS:")
+            pprint.pprint(py_events)
+            print("C_EVENTS:")
+            pprint.pprint(c_events)
+
+def test_c_emitter(data_filename, canonical_filename, verbose=False):
+    _compare_emitters(open(data_filename, 'rb').read(), verbose)
+    _compare_emitters(open(canonical_filename, 'rb').read(), verbose)
+
+test_c_emitter.unittest = ['.data', '.canonical']
+test_c_emitter.skip = ['.skip-ext']
+
+def wrap_ext_function(function):
+    def wrapper(*args, **kwds):
+        _set_up()
+        try:
+            function(*args, **kwds)
+        finally:
+            _tear_down()
+    wrapper.__name__ = '%s_ext' % function.__name__
+    wrapper.unittest = function.unittest
+    wrapper.skip = getattr(function, 'skip', [])+['.skip-ext']
+    return wrapper
+
+def wrap_ext(collections):
+    functions = []
+    if not isinstance(collections, list):
+        collections = [collections]
+    for collection in collections:
+        if not isinstance(collection, dict):
+            collection = vars(collection)
+        for key in sorted(collection):
+            value = collection[key]
+            if isinstance(value, types.FunctionType) and hasattr(value, 'unittest'):
+                functions.append(wrap_ext_function(value))
+    for function in functions:
+        assert function.__name__ not in globals()
+        globals()[function.__name__] = function
+
+import test_tokens, test_structure, test_errors, test_resolver, test_constructor,   \
+        test_emitter, test_representer, test_recursive, test_input_output
+wrap_ext([test_tokens, test_structure, test_errors, test_resolver, test_constructor,
+        test_emitter, test_representer, test_recursive, test_input_output])
+
+if __name__ == '__main__':
+    import test_appliance
+    test_appliance.run(globals())
+