diff --git a/LICENSE b/LICENSE
deleted file mode 100644
index 53320c3..0000000
--- a/LICENSE
+++ /dev/null
@@ -1,185 +0,0 @@
-This software is licensed under the LGPLv3, included below.
-
-As a special exception to the GNU Lesser General Public License version 3
-("LGPL3"), the copyright holders of this Library give you permission to
-convey to a third party a Combined Work that links statically or dynamically
-to this Library without providing any Minimal Corresponding Source or
-Minimal Application Code as set out in 4d or providing the installation
-information set out in section 4e, provided that you comply with the other
-provisions of LGPL3 and provided that you meet, for the Application the
-terms and conditions of the license(s) which apply to the Application.
-
-Except as stated in this special exception, the provisions of LGPL3 will
-continue to comply in full to this Library. If you modify this Library, you
-may apply this exception to your version of this Library, but you are not
-obliged to do so. If you do not wish to do so, delete this exception
-statement from your version. This exception does not (and cannot) modify any
-license terms which apply to the Application, with which you must still
-comply.
-
-
-                   GNU LESSER GENERAL PUBLIC LICENSE
-                       Version 3, 29 June 2007
-
- Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
- Everyone is permitted to copy and distribute verbatim copies
- of this license document, but changing it is not allowed.
-
-
-  This version of the GNU Lesser General Public License incorporates
-the terms and conditions of version 3 of the GNU General Public
-License, supplemented by the additional permissions listed below.
-
-  0. Additional Definitions.
-
-  As used herein, "this License" refers to version 3 of the GNU Lesser
-General Public License, and the "GNU GPL" refers to version 3 of the GNU
-General Public License.
-
-  "The Library" refers to a covered work governed by this License,
-other than an Application or a Combined Work as defined below.
-
-  An "Application" is any work that makes use of an interface provided
-by the Library, but which is not otherwise based on the Library.
-Defining a subclass of a class defined by the Library is deemed a mode
-of using an interface provided by the Library.
-
-  A "Combined Work" is a work produced by combining or linking an
-Application with the Library.  The particular version of the Library
-with which the Combined Work was made is also called the "Linked
-Version".
-
-  The "Minimal Corresponding Source" for a Combined Work means the
-Corresponding Source for the Combined Work, excluding any source code
-for portions of the Combined Work that, considered in isolation, are
-based on the Application, and not on the Linked Version.
-
-  The "Corresponding Application Code" for a Combined Work means the
-object code and/or source code for the Application, including any data
-and utility programs needed for reproducing the Combined Work from the
-Application, but excluding the System Libraries of the Combined Work.
-
-  1. Exception to Section 3 of the GNU GPL.
-
-  You may convey a covered work under sections 3 and 4 of this License
-without being bound by section 3 of the GNU GPL.
-
-  2. Conveying Modified Versions.
-
-  If you modify a copy of the Library, and, in your modifications, a
-facility refers to a function or data to be supplied by an Application
-that uses the facility (other than as an argument passed when the
-facility is invoked), then you may convey a copy of the modified
-version:
-
-   a) under this License, provided that you make a good faith effort to
-   ensure that, in the event an Application does not supply the
-   function or data, the facility still operates, and performs
-   whatever part of its purpose remains meaningful, or
-
-   b) under the GNU GPL, with none of the additional permissions of
-   this License applicable to that copy.
-
-  3. Object Code Incorporating Material from Library Header Files.
-
-  The object code form of an Application may incorporate material from
-a header file that is part of the Library.  You may convey such object
-code under terms of your choice, provided that, if the incorporated
-material is not limited to numerical parameters, data structure
-layouts and accessors, or small macros, inline functions and templates
-(ten or fewer lines in length), you do both of the following:
-
-   a) Give prominent notice with each copy of the object code that the
-   Library is used in it and that the Library and its use are
-   covered by this License.
-
-   b) Accompany the object code with a copy of the GNU GPL and this license
-   document.
-
-  4. Combined Works.
-
-  You may convey a Combined Work under terms of your choice that,
-taken together, effectively do not restrict modification of the
-portions of the Library contained in the Combined Work and reverse
-engineering for debugging such modifications, if you also do each of
-the following:
-
-   a) Give prominent notice with each copy of the Combined Work that
-   the Library is used in it and that the Library and its use are
-   covered by this License.
-
-   b) Accompany the Combined Work with a copy of the GNU GPL and this license
-   document.
-
-   c) For a Combined Work that displays copyright notices during
-   execution, include the copyright notice for the Library among
-   these notices, as well as a reference directing the user to the
-   copies of the GNU GPL and this license document.
-
-   d) Do one of the following:
-
-       0) Convey the Minimal Corresponding Source under the terms of this
-       License, and the Corresponding Application Code in a form
-       suitable for, and under terms that permit, the user to
-       recombine or relink the Application with a modified version of
-       the Linked Version to produce a modified Combined Work, in the
-       manner specified by section 6 of the GNU GPL for conveying
-       Corresponding Source.
-
-       1) Use a suitable shared library mechanism for linking with the
-       Library.  A suitable mechanism is one that (a) uses at run time
-       a copy of the Library already present on the user's computer
-       system, and (b) will operate properly with a modified version
-       of the Library that is interface-compatible with the Linked
-       Version.
-
-   e) Provide Installation Information, but only if you would otherwise
-   be required to provide such information under section 6 of the
-   GNU GPL, and only to the extent that such information is
-   necessary to install and execute a modified version of the
-   Combined Work produced by recombining or relinking the
-   Application with a modified version of the Linked Version. (If
-   you use option 4d0, the Installation Information must accompany
-   the Minimal Corresponding Source and Corresponding Application
-   Code. If you use option 4d1, you must provide the Installation
-   Information in the manner specified by section 6 of the GNU GPL
-   for conveying Corresponding Source.)
-
-  5. Combined Libraries.
-
-  You may place library facilities that are a work based on the
-Library side by side in a single library together with other library
-facilities that are not Applications and are not covered by this
-License, and convey such a combined library under terms of your
-choice, if you do both of the following:
-
-   a) Accompany the combined library with a copy of the same work based
-   on the Library, uncombined with any other library facilities,
-   conveyed under the terms of this License.
-
-   b) Give prominent notice with the combined library that part of it
-   is a work based on the Library, and explaining where to find the
-   accompanying uncombined form of the same work.
-
-  6. Revised Versions of the GNU Lesser General Public License.
-
-  The Free Software Foundation may publish revised and/or new versions
-of the GNU Lesser General Public License from time to time. Such new
-versions will be similar in spirit to the present version, but may
-differ in detail to address new problems or concerns.
-
-  Each version is given a distinguishing version number. If the
-Library as you received it specifies that a certain numbered version
-of the GNU Lesser General Public License "or any later version"
-applies to it, you have the option of following the terms and
-conditions either of that published version or of any later version
-published by the Free Software Foundation. If the Library as you
-received it does not specify a version number of the GNU Lesser
-General Public License, you may choose any version of the GNU Lesser
-General Public License ever published by the Free Software Foundation.
-
-  If the Library as you received it specifies that a proxy can decide
-whether future versions of the GNU Lesser General Public License shall
-apply, that proxy's public statement of acceptance of any version is
-permanent authorization for you to choose that version for the
-Library.
diff --git a/LICENSE.libyaml b/LICENSE.libyaml
deleted file mode 100644
index 050ced2..0000000
--- a/LICENSE.libyaml
+++ /dev/null
@@ -1,19 +0,0 @@
-Copyright (c) 2006 Kirill Simonov
-
-Permission is hereby granted, free of charge, to any person obtaining a copy of
-this software and associated documentation files (the "Software"), to deal in
-the Software without restriction, including without limitation the rights to
-use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
-of the Software, and to permit persons to whom the Software is furnished to do
-so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-SOFTWARE.
diff --git a/README.md b/README.md
deleted file mode 100644
index 896687b..0000000
--- a/README.md
+++ /dev/null
@@ -1,128 +0,0 @@
-# YAML support for the Go language
-
-Introduction
-------------
-
-The yaml package enables Go programs to comfortably encode and decode YAML
-values. It was developed within [Canonical](https://www.canonical.com) as
-part of the [juju](https://juju.ubuntu.com) project, and is based on a
-pure Go port of the well-known [libyaml](http://pyyaml.org/wiki/LibYAML)
-C library to parse and generate YAML data quickly and reliably.
-
-Compatibility
--------------
-
-The yaml package is almost compatible with YAML 1.1, including support for
-anchors, tags, etc. There are still a few missing bits, such as document
-merging, base-60 floats (huh?), and multi-document unmarshalling. These
-features are not hard to add, and will be introduced as necessary.
-
-Installation and usage
-----------------------
-
-The import path for the package is *gopkg.in/yaml.v1*.
-
-To install it, run:
-
-    go get gopkg.in/yaml.v1
-
-API documentation
------------------
-
-If opened in a browser, the import path itself leads to the API documentation:
-
-  * [https://gopkg.in/yaml.v1](https://gopkg.in/yaml.v1)
-
-API stability
--------------
-
-The package API for yaml v1 will remain stable as described in [gopkg.in](https://gopkg.in).
-
-
-License
--------
-
-The yaml package is licensed under the LGPL with an exception that allows it to be linked statically. Please see the LICENSE file for details.
-
-
-Example
--------
-
-```Go
-package main
-
-import (
-        "fmt"
-        "log"
-
-        "gopkg.in/yaml.v1"
-)
-
-var data = `
-a: Easy!
-b:
-  c: 2
-  d: [3, 4]
-`
-
-type T struct {
-        A string
-        B struct{C int; D []int ",flow"}
-}
-
-func main() {
-        t := T{}
-    
-        err := yaml.Unmarshal([]byte(data), &t)
-        if err != nil {
-                log.Fatalf("error: %v", err)
-        }
-        fmt.Printf("--- t:\n%v\n\n", t)
-    
-        d, err := yaml.Marshal(&t)
-        if err != nil {
-                log.Fatalf("error: %v", err)
-        }
-        fmt.Printf("--- t dump:\n%s\n\n", string(d))
-    
-        m := make(map[interface{}]interface{})
-    
-        err = yaml.Unmarshal([]byte(data), &m)
-        if err != nil {
-                log.Fatalf("error: %v", err)
-        }
-        fmt.Printf("--- m:\n%v\n\n", m)
-    
-        d, err = yaml.Marshal(&m)
-        if err != nil {
-                log.Fatalf("error: %v", err)
-        }
-        fmt.Printf("--- m dump:\n%s\n\n", string(d))
-}
-```
-
-This example will generate the following output:
-
-```
---- t:
-{Easy! {2 [3 4]}}
-
---- t dump:
-a: Easy!
-b:
-  c: 2
-  d: [3, 4]
-
-
---- m:
-map[a:Easy! b:map[c:2 d:[3 4]]]
-
---- m dump:
-a: Easy!
-b:
-  c: 2
-  d:
-  - 3
-  - 4
-```
-
diff --git a/apic.go b/apic.go
deleted file mode 100644
index 95ec014..0000000
--- a/apic.go
+++ /dev/null
@@ -1,742 +0,0 @@
-package yaml
-
-import (
-	"io"
-	"os"
-)
-
-func yaml_insert_token(parser *yaml_parser_t, pos int, token *yaml_token_t) {
-	//fmt.Println("yaml_insert_token", "pos:", pos, "typ:", token.typ, "head:", parser.tokens_head, "len:", len(parser.tokens))
-
-	// Check if we can move the queue at the beginning of the buffer.
-	if parser.tokens_head > 0 && len(parser.tokens) == cap(parser.tokens) {
-		if parser.tokens_head != len(parser.tokens) {
-			copy(parser.tokens, parser.tokens[parser.tokens_head:])
-		}
-		parser.tokens = parser.tokens[:len(parser.tokens)-parser.tokens_head]
-		parser.tokens_head = 0
-	}
-	parser.tokens = append(parser.tokens, *token)
-	if pos < 0 {
-		return
-	}
-	copy(parser.tokens[parser.tokens_head+pos+1:], parser.tokens[parser.tokens_head+pos:])
-	parser.tokens[parser.tokens_head+pos] = *token
-}
-
-// Create a new parser object.
-func yaml_parser_initialize(parser *yaml_parser_t) bool {
-	*parser = yaml_parser_t{
-		raw_buffer: make([]byte, 0, input_raw_buffer_size),
-		buffer:     make([]byte, 0, input_buffer_size),
-	}
-	return true
-}
-
-// Destroy a parser object.
-func yaml_parser_delete(parser *yaml_parser_t) {
-	*parser = yaml_parser_t{}
-}
-
-// String read handler.
-func yaml_string_read_handler(parser *yaml_parser_t, buffer []byte) (n int, err error) {
-	if parser.input_pos == len(parser.input) {
-		return 0, io.EOF
-	}
-	n = copy(buffer, parser.input[parser.input_pos:])
-	parser.input_pos += n
-	return n, nil
-}
-
-// File read handler.
-func yaml_file_read_handler(parser *yaml_parser_t, buffer []byte) (n int, err error) {
-	return parser.input_file.Read(buffer)
-}
-
-// Set a string input.
-func yaml_parser_set_input_string(parser *yaml_parser_t, input []byte) {
-	if parser.read_handler != nil {
-		panic("must set the input source only once")
-	}
-	parser.read_handler = yaml_string_read_handler
-	parser.input = input
-	parser.input_pos = 0
-}
-
-// Set a file input.
-func yaml_parser_set_input_file(parser *yaml_parser_t, file *os.File) {
-	if parser.read_handler != nil {
-		panic("must set the input source only once")
-	}
-	parser.read_handler = yaml_file_read_handler
-	parser.input_file = file
-}
-
-// Set the source encoding.
-func yaml_parser_set_encoding(parser *yaml_parser_t, encoding yaml_encoding_t) {
-	if parser.encoding != yaml_ANY_ENCODING {
-		panic("must set the encoding only once")
-	}
-	parser.encoding = encoding
-}
-
-// Create a new emitter object.
-func yaml_emitter_initialize(emitter *yaml_emitter_t) bool {
-	*emitter = yaml_emitter_t{
-		buffer:     make([]byte, output_buffer_size),
-		raw_buffer: make([]byte, 0, output_raw_buffer_size),
-		states:     make([]yaml_emitter_state_t, 0, initial_stack_size),
-		events:     make([]yaml_event_t, 0, initial_queue_size),
-	}
-	return true
-}
-
-// Destroy an emitter object.
-func yaml_emitter_delete(emitter *yaml_emitter_t) {
-	*emitter = yaml_emitter_t{}
-}
-
-// String write handler.
-func yaml_string_write_handler(emitter *yaml_emitter_t, buffer []byte) error {
-	*emitter.output_buffer = append(*emitter.output_buffer, buffer...)
-	return nil
-}
-
-// File write handler.
-func yaml_file_write_handler(emitter *yaml_emitter_t, buffer []byte) error {
-	_, err := emitter.output_file.Write(buffer)
-	return err
-}
-
-// Set a string output.
-func yaml_emitter_set_output_string(emitter *yaml_emitter_t, output_buffer *[]byte) {
-	if emitter.write_handler != nil {
-		panic("must set the output target only once")
-	}
-	emitter.write_handler = yaml_string_write_handler
-	emitter.output_buffer = output_buffer
-}
-
-// Set a file output.
-func yaml_emitter_set_output_file(emitter *yaml_emitter_t, file io.Writer) {
-	if emitter.write_handler != nil {
-		panic("must set the output target only once")
-	}
-	emitter.write_handler = yaml_file_write_handler
-	emitter.output_file = file
-}
-
-// Set the output encoding.
-func yaml_emitter_set_encoding(emitter *yaml_emitter_t, encoding yaml_encoding_t) {
-	if emitter.encoding != yaml_ANY_ENCODING {
-		panic("must set the output encoding only once")
-	}
-	emitter.encoding = encoding
-}
-
-// Set the canonical output style.
-func yaml_emitter_set_canonical(emitter *yaml_emitter_t, canonical bool) {
-	emitter.canonical = canonical
-}
-
-//// Set the indentation increment.
-func yaml_emitter_set_indent(emitter *yaml_emitter_t, indent int) {
-	if indent < 2 || indent > 9 {
-		indent = 2
-	}
-	emitter.best_indent = indent
-}
-
-// Set the preferred line width.
-func yaml_emitter_set_width(emitter *yaml_emitter_t, width int) {
-	if width < 0 {
-		width = -1
-	}
-	emitter.best_width = width
-}
-
-// Set if unescaped non-ASCII characters are allowed.
-func yaml_emitter_set_unicode(emitter *yaml_emitter_t, unicode bool) {
-	emitter.unicode = unicode
-}
-
-// Set the preferred line break character.
-func yaml_emitter_set_break(emitter *yaml_emitter_t, line_break yaml_break_t) {
-	emitter.line_break = line_break
-}
-
-///*
-// * Destroy a token object.
-// */
-//
-//YAML_DECLARE(void)
-//yaml_token_delete(yaml_token_t *token)
-//{
-//    assert(token);  // Non-NULL token object expected.
-//
-//    switch (token.type)
-//    {
-//        case YAML_TAG_DIRECTIVE_TOKEN:
-//            yaml_free(token.data.tag_directive.handle);
-//            yaml_free(token.data.tag_directive.prefix);
-//            break;
-//
-//        case YAML_ALIAS_TOKEN:
-//            yaml_free(token.data.alias.value);
-//            break;
-//
-//        case YAML_ANCHOR_TOKEN:
-//            yaml_free(token.data.anchor.value);
-//            break;
-//
-//        case YAML_TAG_TOKEN:
-//            yaml_free(token.data.tag.handle);
-//            yaml_free(token.data.tag.suffix);
-//            break;
-//
-//        case YAML_SCALAR_TOKEN:
-//            yaml_free(token.data.scalar.value);
-//            break;
-//
-//        default:
-//            break;
-//    }
-//
-//    memset(token, 0, sizeof(yaml_token_t));
-//}
-//
-///*
-// * Check if a string is a valid UTF-8 sequence.
-// *
-// * Check 'reader.c' for more details on UTF-8 encoding.
-// */
-//
-//static int
-//yaml_check_utf8(yaml_char_t *start, size_t length)
-//{
-//    yaml_char_t *end = start+length;
-//    yaml_char_t *pointer = start;
-//
-//    while (pointer < end) {
-//        unsigned char octet;
-//        unsigned int width;
-//        unsigned int value;
-//        size_t k;
-//
-//        octet = pointer[0];
-//        width = (octet & 0x80) == 0x00 ? 1 :
-//                (octet & 0xE0) == 0xC0 ? 2 :
-//                (octet & 0xF0) == 0xE0 ? 3 :
-//                (octet & 0xF8) == 0xF0 ? 4 : 0;
-//        value = (octet & 0x80) == 0x00 ? octet & 0x7F :
-//                (octet & 0xE0) == 0xC0 ? octet & 0x1F :
-//                (octet & 0xF0) == 0xE0 ? octet & 0x0F :
-//                (octet & 0xF8) == 0xF0 ? octet & 0x07 : 0;
-//        if (!width) return 0;
-//        if (pointer+width > end) return 0;
-//        for (k = 1; k < width; k ++) {
-//            octet = pointer[k];
-//            if ((octet & 0xC0) != 0x80) return 0;
-//            value = (value << 6) + (octet & 0x3F);
-//        }
-//        if (!((width == 1) ||
-//            (width == 2 && value >= 0x80) ||
-//            (width == 3 && value >= 0x800) ||
-//            (width == 4 && value >= 0x10000))) return 0;
-//
-//        pointer += width;
-//    }
-//
-//    return 1;
-//}
-//
-
-// Create STREAM-START.
-func yaml_stream_start_event_initialize(event *yaml_event_t, encoding yaml_encoding_t) bool {
-	*event = yaml_event_t{
-		typ:      yaml_STREAM_START_EVENT,
-		encoding: encoding,
-	}
-	return true
-}
-
-// Create STREAM-END.
-func yaml_stream_end_event_initialize(event *yaml_event_t) bool {
-	*event = yaml_event_t{
-		typ: yaml_STREAM_END_EVENT,
-	}
-	return true
-}
-
-// Create DOCUMENT-START.
-func yaml_document_start_event_initialize(event *yaml_event_t, version_directive *yaml_version_directive_t,
-	tag_directives []yaml_tag_directive_t, implicit bool) bool {
-	*event = yaml_event_t{
-		typ:               yaml_DOCUMENT_START_EVENT,
-		version_directive: version_directive,
-		tag_directives:    tag_directives,
-		implicit:          implicit,
-	}
-	return true
-}
-
-// Create DOCUMENT-END.
-func yaml_document_end_event_initialize(event *yaml_event_t, implicit bool) bool {
-	*event = yaml_event_t{
-		typ:      yaml_DOCUMENT_END_EVENT,
-		implicit: implicit,
-	}
-	return true
-}
-
-///*
-// * Create ALIAS.
-// */
-//
-//YAML_DECLARE(int)
-//yaml_alias_event_initialize(event *yaml_event_t, anchor *yaml_char_t)
-//{
-//    mark yaml_mark_t = { 0, 0, 0 }
-//    anchor_copy *yaml_char_t = NULL
-//
-//    assert(event) // Non-NULL event object is expected.
-//    assert(anchor) // Non-NULL anchor is expected.
-//
-//    if (!yaml_check_utf8(anchor, strlen((char *)anchor))) return 0
-//
-//    anchor_copy = yaml_strdup(anchor)
-//    if (!anchor_copy)
-//        return 0
-//
-//    ALIAS_EVENT_INIT(*event, anchor_copy, mark, mark)
-//
-//    return 1
-//}
-
-// Create SCALAR.
-func yaml_scalar_event_initialize(event *yaml_event_t, anchor, tag, value []byte, plain_implicit, quoted_implicit bool, style yaml_scalar_style_t) bool {
-	*event = yaml_event_t{
-		typ:             yaml_SCALAR_EVENT,
-		anchor:          anchor,
-		tag:             tag,
-		value:           value,
-		implicit:        plain_implicit,
-		quoted_implicit: quoted_implicit,
-		style:           yaml_style_t(style),
-	}
-	return true
-}
-
-// Create SEQUENCE-START.
-func yaml_sequence_start_event_initialize(event *yaml_event_t, anchor, tag []byte, implicit bool, style yaml_sequence_style_t) bool {
-	*event = yaml_event_t{
-		typ:      yaml_SEQUENCE_START_EVENT,
-		anchor:   anchor,
-		tag:      tag,
-		implicit: implicit,
-		style:    yaml_style_t(style),
-	}
-	return true
-}
-
-// Create SEQUENCE-END.
-func yaml_sequence_end_event_initialize(event *yaml_event_t) bool {
-	*event = yaml_event_t{
-		typ: yaml_SEQUENCE_END_EVENT,
-	}
-	return true
-}
-
-// Create MAPPING-START.
-func yaml_mapping_start_event_initialize(event *yaml_event_t, anchor, tag []byte, implicit bool, style yaml_mapping_style_t) bool {
-	*event = yaml_event_t{
-		typ:      yaml_MAPPING_START_EVENT,
-		anchor:   anchor,
-		tag:      tag,
-		implicit: implicit,
-		style:    yaml_style_t(style),
-	}
-	return true
-}
-
-// Create MAPPING-END.
-func yaml_mapping_end_event_initialize(event *yaml_event_t) bool {
-	*event = yaml_event_t{
-		typ: yaml_MAPPING_END_EVENT,
-	}
-	return true
-}
-
-// Destroy an event object.
-func yaml_event_delete(event *yaml_event_t) {
-	*event = yaml_event_t{}
-}
-
-///*
-// * Create a document object.
-// */
-//
-//YAML_DECLARE(int)
-//yaml_document_initialize(document *yaml_document_t,
-//        version_directive *yaml_version_directive_t,
-//        tag_directives_start *yaml_tag_directive_t,
-//        tag_directives_end *yaml_tag_directive_t,
-//        start_implicit int, end_implicit int)
-//{
-//    struct {
-//        error yaml_error_type_t
-//    } context
-//    struct {
-//        start *yaml_node_t
-//        end *yaml_node_t
-//        top *yaml_node_t
-//    } nodes = { NULL, NULL, NULL }
-//    version_directive_copy *yaml_version_directive_t = NULL
-//    struct {
-//        start *yaml_tag_directive_t
-//        end *yaml_tag_directive_t
-//        top *yaml_tag_directive_t
-//    } tag_directives_copy = { NULL, NULL, NULL }
-//    value yaml_tag_directive_t = { NULL, NULL }
-//    mark yaml_mark_t = { 0, 0, 0 }
-//
-//    assert(document) // Non-NULL document object is expected.
-//    assert((tag_directives_start && tag_directives_end) ||
-//            (tag_directives_start == tag_directives_end))
-//                            // Valid tag directives are expected.
-//
-//    if (!STACK_INIT(&context, nodes, INITIAL_STACK_SIZE)) goto error
-//
-//    if (version_directive) {
-//        version_directive_copy = yaml_malloc(sizeof(yaml_version_directive_t))
-//        if (!version_directive_copy) goto error
-//        version_directive_copy.major = version_directive.major
-//        version_directive_copy.minor = version_directive.minor
-//    }
-//
-//    if (tag_directives_start != tag_directives_end) {
-//        tag_directive *yaml_tag_directive_t
-//        if (!STACK_INIT(&context, tag_directives_copy, INITIAL_STACK_SIZE))
-//            goto error
-//        for (tag_directive = tag_directives_start
-//                tag_directive != tag_directives_end; tag_directive ++) {
-//            assert(tag_directive.handle)
-//            assert(tag_directive.prefix)
-//            if (!yaml_check_utf8(tag_directive.handle,
-//                        strlen((char *)tag_directive.handle)))
-//                goto error
-//            if (!yaml_check_utf8(tag_directive.prefix,
-//                        strlen((char *)tag_directive.prefix)))
-//                goto error
-//            value.handle = yaml_strdup(tag_directive.handle)
-//            value.prefix = yaml_strdup(tag_directive.prefix)
-//            if (!value.handle || !value.prefix) goto error
-//            if (!PUSH(&context, tag_directives_copy, value))
-//                goto error
-//            value.handle = NULL
-//            value.prefix = NULL
-//        }
-//    }
-//
-//    DOCUMENT_INIT(*document, nodes.start, nodes.end, version_directive_copy,
-//            tag_directives_copy.start, tag_directives_copy.top,
-//            start_implicit, end_implicit, mark, mark)
-//
-//    return 1
-//
-//error:
-//    STACK_DEL(&context, nodes)
-//    yaml_free(version_directive_copy)
-//    while (!STACK_EMPTY(&context, tag_directives_copy)) {
-//        value yaml_tag_directive_t = POP(&context, tag_directives_copy)
-//        yaml_free(value.handle)
-//        yaml_free(value.prefix)
-//    }
-//    STACK_DEL(&context, tag_directives_copy)
-//    yaml_free(value.handle)
-//    yaml_free(value.prefix)
-//
-//    return 0
-//}
-//
-///*
-// * Destroy a document object.
-// */
-//
-//YAML_DECLARE(void)
-//yaml_document_delete(document *yaml_document_t)
-//{
-//    struct {
-//        error yaml_error_type_t
-//    } context
-//    tag_directive *yaml_tag_directive_t
-//
-//    context.error = YAML_NO_ERROR // Eliminate a compliler warning.
-//
-//    assert(document) // Non-NULL document object is expected.
-//
-//    while (!STACK_EMPTY(&context, document.nodes)) {
-//        node yaml_node_t = POP(&context, document.nodes)
-//        yaml_free(node.tag)
-//        switch (node.type) {
-//            case YAML_SCALAR_NODE:
-//                yaml_free(node.data.scalar.value)
-//                break
-//            case YAML_SEQUENCE_NODE:
-//                STACK_DEL(&context, node.data.sequence.items)
-//                break
-//            case YAML_MAPPING_NODE:
-//                STACK_DEL(&context, node.data.mapping.pairs)
-//                break
-//            default:
-//                assert(0) // Should not happen.
-//        }
-//    }
-//    STACK_DEL(&context, document.nodes)
-//
-//    yaml_free(document.version_directive)
-//    for (tag_directive = document.tag_directives.start
-//            tag_directive != document.tag_directives.end
-//            tag_directive++) {
-//        yaml_free(tag_directive.handle)
-//        yaml_free(tag_directive.prefix)
-//    }
-//    yaml_free(document.tag_directives.start)
-//
-//    memset(document, 0, sizeof(yaml_document_t))
-//}
-//
-///**
-// * Get a document node.
-// */
-//
-//YAML_DECLARE(yaml_node_t *)
-//yaml_document_get_node(document *yaml_document_t, index int)
-//{
-//    assert(document) // Non-NULL document object is expected.
-//
-//    if (index > 0 && document.nodes.start + index <= document.nodes.top) {
-//        return document.nodes.start + index - 1
-//    }
-//    return NULL
-//}
-//
-///**
-// * Get the root object.
-// */
-//
-//YAML_DECLARE(yaml_node_t *)
-//yaml_document_get_root_node(document *yaml_document_t)
-//{
-//    assert(document) // Non-NULL document object is expected.
-//
-//    if (document.nodes.top != document.nodes.start) {
-//        return document.nodes.start
-//    }
-//    return NULL
-//}
-//
-///*
-// * Add a scalar node to a document.
-// */
-//
-//YAML_DECLARE(int)
-//yaml_document_add_scalar(document *yaml_document_t,
-//        tag *yaml_char_t, value *yaml_char_t, length int,
-//        style yaml_scalar_style_t)
-//{
-//    struct {
-//        error yaml_error_type_t
-//    } context
-//    mark yaml_mark_t = { 0, 0, 0 }
-//    tag_copy *yaml_char_t = NULL
-//    value_copy *yaml_char_t = NULL
-//    node yaml_node_t
-//
-//    assert(document) // Non-NULL document object is expected.
-//    assert(value) // Non-NULL value is expected.
-//
-//    if (!tag) {
-//        tag = (yaml_char_t *)YAML_DEFAULT_SCALAR_TAG
-//    }
-//
-//    if (!yaml_check_utf8(tag, strlen((char *)tag))) goto error
-//    tag_copy = yaml_strdup(tag)
-//    if (!tag_copy) goto error
-//
-//    if (length < 0) {
-//        length = strlen((char *)value)
-//    }
-//
-//    if (!yaml_check_utf8(value, length)) goto error
-//    value_copy = yaml_malloc(length+1)
-//    if (!value_copy) goto error
-//    memcpy(value_copy, value, length)
-//    value_copy[length] = '\0'
-//
-//    SCALAR_NODE_INIT(node, tag_copy, value_copy, length, style, mark, mark)
-//    if (!PUSH(&context, document.nodes, node)) goto error
-//
-//    return document.nodes.top - document.nodes.start
-//
-//error:
-//    yaml_free(tag_copy)
-//    yaml_free(value_copy)
-//
-//    return 0
-//}
-//
-///*
-// * Add a sequence node to a document.
-// */
-//
-//YAML_DECLARE(int)
-//yaml_document_add_sequence(document *yaml_document_t,
-//        tag *yaml_char_t, style yaml_sequence_style_t)
-//{
-//    struct {
-//        error yaml_error_type_t
-//    } context
-//    mark yaml_mark_t = { 0, 0, 0 }
-//    tag_copy *yaml_char_t = NULL
-//    struct {
-//        start *yaml_node_item_t
-//        end *yaml_node_item_t
-//        top *yaml_node_item_t
-//    } items = { NULL, NULL, NULL }
-//    node yaml_node_t
-//
-//    assert(document) // Non-NULL document object is expected.
-//
-//    if (!tag) {
-//        tag = (yaml_char_t *)YAML_DEFAULT_SEQUENCE_TAG
-//    }
-//
-//    if (!yaml_check_utf8(tag, strlen((char *)tag))) goto error
-//    tag_copy = yaml_strdup(tag)
-//    if (!tag_copy) goto error
-//
-//    if (!STACK_INIT(&context, items, INITIAL_STACK_SIZE)) goto error
-//
-//    SEQUENCE_NODE_INIT(node, tag_copy, items.start, items.end,
-//            style, mark, mark)
-//    if (!PUSH(&context, document.nodes, node)) goto error
-//
-//    return document.nodes.top - document.nodes.start
-//
-//error:
-//    STACK_DEL(&context, items)
-//    yaml_free(tag_copy)
-//
-//    return 0
-//}
-//
-///*
-// * Add a mapping node to a document.
-// */
-//
-//YAML_DECLARE(int)
-//yaml_document_add_mapping(document *yaml_document_t,
-//        tag *yaml_char_t, style yaml_mapping_style_t)
-//{
-//    struct {
-//        error yaml_error_type_t
-//    } context
-//    mark yaml_mark_t = { 0, 0, 0 }
-//    tag_copy *yaml_char_t = NULL
-//    struct {
-//        start *yaml_node_pair_t
-//        end *yaml_node_pair_t
-//        top *yaml_node_pair_t
-//    } pairs = { NULL, NULL, NULL }
-//    node yaml_node_t
-//
-//    assert(document) // Non-NULL document object is expected.
-//
-//    if (!tag) {
-//        tag = (yaml_char_t *)YAML_DEFAULT_MAPPING_TAG
-//    }
-//
-//    if (!yaml_check_utf8(tag, strlen((char *)tag))) goto error
-//    tag_copy = yaml_strdup(tag)
-//    if (!tag_copy) goto error
-//
-//    if (!STACK_INIT(&context, pairs, INITIAL_STACK_SIZE)) goto error
-//
-//    MAPPING_NODE_INIT(node, tag_copy, pairs.start, pairs.end,
-//            style, mark, mark)
-//    if (!PUSH(&context, document.nodes, node)) goto error
-//
-//    return document.nodes.top - document.nodes.start
-//
-//error:
-//    STACK_DEL(&context, pairs)
-//    yaml_free(tag_copy)
-//
-//    return 0
-//}
-//
-///*
-// * Append an item to a sequence node.
-// */
-//
-//YAML_DECLARE(int)
-//yaml_document_append_sequence_item(document *yaml_document_t,
-//        sequence int, item int)
-//{
-//    struct {
-//        error yaml_error_type_t
-//    } context
-//
-//    assert(document) // Non-NULL document is required.
-//    assert(sequence > 0
-//            && document.nodes.start + sequence <= document.nodes.top)
-//                            // Valid sequence id is required.
-//    assert(document.nodes.start[sequence-1].type == YAML_SEQUENCE_NODE)
-//                            // A sequence node is required.
-//    assert(item > 0 && document.nodes.start + item <= document.nodes.top)
-//                            // Valid item id is required.
-//
-//    if (!PUSH(&context,
-//                document.nodes.start[sequence-1].data.sequence.items, item))
-//        return 0
-//
-//    return 1
-//}
-//
-///*
-// * Append a pair of a key and a value to a mapping node.
-// */
-//
-//YAML_DECLARE(int)
-//yaml_document_append_mapping_pair(document *yaml_document_t,
-//        mapping int, key int, value int)
-//{
-//    struct {
-//        error yaml_error_type_t
-//    } context
-//
-//    pair yaml_node_pair_t
-//
-//    assert(document) // Non-NULL document is required.
-//    assert(mapping > 0
-//            && document.nodes.start + mapping <= document.nodes.top)
-//                            // Valid mapping id is required.
-//    assert(document.nodes.start[mapping-1].type == YAML_MAPPING_NODE)
-//                            // A mapping node is required.
-//    assert(key > 0 && document.nodes.start + key <= document.nodes.top)
-//                            // Valid key id is required.
-//    assert(value > 0 && document.nodes.start + value <= document.nodes.top)
-//                            // Valid value id is required.
-//
-//    pair.key = key
-//    pair.value = value
-//
-//    if (!PUSH(&context,
-//                document.nodes.start[mapping-1].data.mapping.pairs, pair))
-//        return 0
-//
-//    return 1
-//}
-//
-//
diff --git a/decode.go b/decode.go
deleted file mode 100644
index fd1ff96..0000000
--- a/decode.go
+++ /dev/null
@@ -1,473 +0,0 @@
-package yaml
-
-import (
-	"reflect"
-	"strconv"
-)
-
-const (
-	documentNode = 1 << iota
-	mappingNode
-	sequenceNode
-	scalarNode
-	aliasNode
-)
-
-type node struct {
-	kind         int
-	line, column int
-	tag          string
-	value        string
-	implicit     bool
-	children     []*node
-	anchors      map[string]*node
-}
-
-// ----------------------------------------------------------------------------
-// Parser, produces a node tree out of a libyaml event stream.
-
-type parser struct {
-	parser yaml_parser_t
-	event  yaml_event_t
-	doc    *node
-}
-
-func newParser(b []byte) *parser {
-	p := parser{}
-	if !yaml_parser_initialize(&p.parser) {
-		panic("Failed to initialize YAML emitter")
-	}
-
-	if len(b) == 0 {
-		b = []byte{'\n'}
-	}
-
-	yaml_parser_set_input_string(&p.parser, b)
-
-	p.skip()
-	if p.event.typ != yaml_STREAM_START_EVENT {
-		panic("Expected stream start event, got " + strconv.Itoa(int(p.event.typ)))
-	}
-	p.skip()
-	return &p
-}
-
-func (p *parser) destroy() {
-	if p.event.typ != yaml_NO_EVENT {
-		yaml_event_delete(&p.event)
-	}
-	yaml_parser_delete(&p.parser)
-}
-
-func (p *parser) skip() {
-	if p.event.typ != yaml_NO_EVENT {
-		if p.event.typ == yaml_STREAM_END_EVENT {
-			panic("Attempted to go past the end of stream. Corrupted value?")
-		}
-		yaml_event_delete(&p.event)
-	}
-	if !yaml_parser_parse(&p.parser, &p.event) {
-		p.fail()
-	}
-}
-
-func (p *parser) fail() {
-	var where string
-	var line int
-	if p.parser.problem_mark.line != 0 {
-		line = p.parser.problem_mark.line
-	} else if p.parser.context_mark.line != 0 {
-		line = p.parser.context_mark.line
-	}
-	if line != 0 {
-		where = "line " + strconv.Itoa(line) + ": "
-	}
-	var msg string
-	if len(p.parser.problem) > 0 {
-		msg = p.parser.problem
-	} else {
-		msg = "Unknown problem parsing YAML content"
-	}
-	panic(where + msg)
-}
-
-func (p *parser) anchor(n *node, anchor []byte) {
-	if anchor != nil {
-		p.doc.anchors[string(anchor)] = n
-	}
-}
-
-func (p *parser) parse() *node {
-	switch p.event.typ {
-	case yaml_SCALAR_EVENT:
-		return p.scalar()
-	case yaml_ALIAS_EVENT:
-		return p.alias()
-	case yaml_MAPPING_START_EVENT:
-		return p.mapping()
-	case yaml_SEQUENCE_START_EVENT:
-		return p.sequence()
-	case yaml_DOCUMENT_START_EVENT:
-		return p.document()
-	case yaml_STREAM_END_EVENT:
-		// Happens when attempting to decode an empty buffer.
-		return nil
-	default:
-		panic("Attempted to parse unknown event: " +
-			strconv.Itoa(int(p.event.typ)))
-	}
-	panic("Unreachable")
-}
-
-func (p *parser) node(kind int) *node {
-	return &node{
-		kind:   kind,
-		line:   p.event.start_mark.line,
-		column: p.event.start_mark.column,
-	}
-}
-
-func (p *parser) document() *node {
-	n := p.node(documentNode)
-	n.anchors = make(map[string]*node)
-	p.doc = n
-	p.skip()
-	n.children = append(n.children, p.parse())
-	if p.event.typ != yaml_DOCUMENT_END_EVENT {
-		panic("Expected end of document event but got " +
-			strconv.Itoa(int(p.event.typ)))
-	}
-	p.skip()
-	return n
-}
-
-func (p *parser) alias() *node {
-	n := p.node(aliasNode)
-	n.value = string(p.event.anchor)
-	p.skip()
-	return n
-}
-
-func (p *parser) scalar() *node {
-	n := p.node(scalarNode)
-	n.value = string(p.event.value)
-	n.tag = string(p.event.tag)
-	n.implicit = p.event.implicit
-	p.anchor(n, p.event.anchor)
-	p.skip()
-	return n
-}
-
-func (p *parser) sequence() *node {
-	n := p.node(sequenceNode)
-	p.anchor(n, p.event.anchor)
-	p.skip()
-	for p.event.typ != yaml_SEQUENCE_END_EVENT {
-		n.children = append(n.children, p.parse())
-	}
-	p.skip()
-	return n
-}
-
-func (p *parser) mapping() *node {
-	n := p.node(mappingNode)
-	p.anchor(n, p.event.anchor)
-	p.skip()
-	for p.event.typ != yaml_MAPPING_END_EVENT {
-		n.children = append(n.children, p.parse(), p.parse())
-	}
-	p.skip()
-	return n
-}
-
-// ----------------------------------------------------------------------------
-// Decoder, unmarshals a node into a provided value.
-
-type decoder struct {
-	doc     *node
-	aliases map[string]bool
-}
-
-func newDecoder() *decoder {
-	d := &decoder{}
-	d.aliases = make(map[string]bool)
-	return d
-}
-
-// d.setter deals with setters and pointer dereferencing and initialization.
-//
-// It's a slightly convoluted case to handle properly:
-//
-// - nil pointers should be initialized, unless being set to nil
-// - we don't know at this point yet what's the value to SetYAML() with.
-// - we can't separate pointer deref/init and setter checking, because
-//   a setter may be found while going down a pointer chain.
-//
-// Thus, here is how it takes care of it:
-//
-// - out is provided as a pointer, so that it can be replaced.
-// - when looking at a non-setter ptr, *out=ptr.Elem(), unless tag=!!null
-// - when a setter is found, *out=interface{}, and a set() function is
-//   returned to call SetYAML() with the value of *out once it's defined.
-//
-func (d *decoder) setter(tag string, out *reflect.Value, good *bool) (set func()) {
-	again := true
-	for again {
-		again = false
-		setter, _ := (*out).Interface().(Setter)
-		if tag != "!!null" || setter != nil {
-			if pv := (*out); pv.Kind() == reflect.Ptr {
-				if pv.IsNil() {
-					*out = reflect.New(pv.Type().Elem()).Elem()
-					pv.Set((*out).Addr())
-				} else {
-					*out = pv.Elem()
-				}
-				setter, _ = pv.Interface().(Setter)
-				again = true
-			}
-		}
-		if setter != nil {
-			var arg interface{}
-			*out = reflect.ValueOf(&arg).Elem()
-			return func() {
-				*good = setter.SetYAML(tag, arg)
-			}
-		}
-	}
-	return nil
-}
-
-func (d *decoder) unmarshal(n *node, out reflect.Value) (good bool) {
-	switch n.kind {
-	case documentNode:
-		good = d.document(n, out)
-	case scalarNode:
-		good = d.scalar(n, out)
-	case aliasNode:
-		good = d.alias(n, out)
-	case mappingNode:
-		good = d.mapping(n, out)
-	case sequenceNode:
-		good = d.sequence(n, out)
-	default:
-		panic("Internal error: unknown node kind: " + strconv.Itoa(n.kind))
-	}
-	return
-}
-
-func (d *decoder) document(n *node, out reflect.Value) (good bool) {
-	if len(n.children) == 1 {
-		d.doc = n
-		d.unmarshal(n.children[0], out)
-		return true
-	}
-	return false
-}
-
-func (d *decoder) alias(n *node, out reflect.Value) (good bool) {
-	an, ok := d.doc.anchors[n.value]
-	if !ok {
-		panic("Unknown anchor '" + n.value + "' referenced")
-	}
-	if d.aliases[n.value] {
-		panic("Anchor '" + n.value + "' value contains itself")
-	}
-	d.aliases[n.value] = true
-	good = d.unmarshal(an, out)
-	delete(d.aliases, n.value)
-	return good
-}
-
-func (d *decoder) scalar(n *node, out reflect.Value) (good bool) {
-	var tag string
-	var resolved interface{}
-	if n.tag == "" && !n.implicit {
-		resolved = n.value
-	} else {
-		tag, resolved = resolve(n.tag, n.value)
-		if set := d.setter(tag, &out, &good); set != nil {
-			defer set()
-		}
-	}
-	switch out.Kind() {
-	case reflect.String:
-		if resolved != nil {
-			out.SetString(n.value)
-			good = true
-		}
-	case reflect.Interface:
-		if resolved == nil {
-			out.Set(reflect.Zero(out.Type()))
-		} else {
-			out.Set(reflect.ValueOf(resolved))
-		}
-		good = true
-	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
-		switch resolved := resolved.(type) {
-		case int:
-			if !out.OverflowInt(int64(resolved)) {
-				out.SetInt(int64(resolved))
-				good = true
-			}
-		case int64:
-			if !out.OverflowInt(resolved) {
-				out.SetInt(resolved)
-				good = true
-			}
-		case float64:
-			if resolved < 1<<63-1 && !out.OverflowInt(int64(resolved)) {
-				out.SetInt(int64(resolved))
-				good = true
-			}
-		}
-	case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
-		switch resolved := resolved.(type) {
-		case int:
-			if resolved >= 0 {
-				out.SetUint(uint64(resolved))
-				good = true
-			}
-		case int64:
-			if resolved >= 0 {
-				out.SetUint(uint64(resolved))
-				good = true
-			}
-		case float64:
-			if resolved < 1<<64-1 && !out.OverflowUint(uint64(resolved)) {
-				out.SetUint(uint64(resolved))
-				good = true
-			}
-		}
-	case reflect.Bool:
-		switch resolved := resolved.(type) {
-		case bool:
-			out.SetBool(resolved)
-			good = true
-		}
-	case reflect.Float32, reflect.Float64:
-		switch resolved := resolved.(type) {
-		case int:
-			out.SetFloat(float64(resolved))
-			good = true
-		case int64:
-			out.SetFloat(float64(resolved))
-			good = true
-		case float64:
-			out.SetFloat(resolved)
-			good = true
-		}
-	case reflect.Ptr:
-		switch resolved.(type) {
-		case nil:
-			out.Set(reflect.Zero(out.Type()))
-			good = true
-		default:
-			if out.Type().Elem() == reflect.TypeOf(resolved) {
-				elem := reflect.New(out.Type().Elem())
-				elem.Elem().Set(reflect.ValueOf(resolved))
-				out.Set(elem)
-				good = true
-			}
-		}
-	}
-	return good
-}
-
-func settableValueOf(i interface{}) reflect.Value {
-	v := reflect.ValueOf(i)
-	sv := reflect.New(v.Type()).Elem()
-	sv.Set(v)
-	return sv
-}
-
-func (d *decoder) sequence(n *node, out reflect.Value) (good bool) {
-	if set := d.setter("!!seq", &out, &good); set != nil {
-		defer set()
-	}
-	var iface reflect.Value
-	if out.Kind() == reflect.Interface {
-		// No type hints. Will have to use a generic sequence.
-		iface = out
-		out = settableValueOf(make([]interface{}, 0))
-	}
-
-	if out.Kind() != reflect.Slice {
-		return false
-	}
-	et := out.Type().Elem()
-
-	l := len(n.children)
-	for i := 0; i < l; i++ {
-		e := reflect.New(et).Elem()
-		if ok := d.unmarshal(n.children[i], e); ok {
-			out.Set(reflect.Append(out, e))
-		}
-	}
-	if iface.IsValid() {
-		iface.Set(out)
-	}
-	return true
-}
-
-func (d *decoder) mapping(n *node, out reflect.Value) (good bool) {
-	if set := d.setter("!!map", &out, &good); set != nil {
-		defer set()
-	}
-	if out.Kind() == reflect.Struct {
-		return d.mappingStruct(n, out)
-	}
-
-	if out.Kind() == reflect.Interface {
-		// No type hints. Will have to use a generic map.
-		iface := out
-		out = settableValueOf(make(map[interface{}]interface{}))
-		iface.Set(out)
-	}
-
-	if out.Kind() != reflect.Map {
-		return false
-	}
-	outt := out.Type()
-	kt := outt.Key()
-	et := outt.Elem()
-
-	if out.IsNil() {
-		out.Set(reflect.MakeMap(outt))
-	}
-	l := len(n.children)
-	for i := 0; i < l; i += 2 {
-		k := reflect.New(kt).Elem()
-		if d.unmarshal(n.children[i], k) {
-			e := reflect.New(et).Elem()
-			if d.unmarshal(n.children[i+1], e) {
-				out.SetMapIndex(k, e)
-			}
-		}
-	}
-	return true
-}
-
-func (d *decoder) mappingStruct(n *node, out reflect.Value) (good bool) {
-	sinfo, err := getStructInfo(out.Type())
-	if err != nil {
-		panic(err)
-	}
-	name := settableValueOf("")
-	l := len(n.children)
-	for i := 0; i < l; i += 2 {
-		if !d.unmarshal(n.children[i], name) {
-			continue
-		}
-		if info, ok := sinfo.FieldsMap[name.String()]; ok {
-			var field reflect.Value
-			if info.Inline == nil {
-				field = out.Field(info.Num)
-			} else {
-				field = out.FieldByIndex(info.Inline)
-			}
-			d.unmarshal(n.children[i+1], field)
-		}
-	}
-	return true
-}
diff --git a/decode_test.go b/decode_test.go
deleted file mode 100644
index 224e369..0000000
--- a/decode_test.go
+++ /dev/null
@@ -1,533 +0,0 @@
-package yaml_test
-
-import (
-	. "launchpad.net/gocheck"
-	"gopkg.in/yaml.v1"
-	"math"
-	"reflect"
-)
-
-var unmarshalIntTest = 123
-
-var unmarshalTests = []struct {
-	data  string
-	value interface{}
-}{
-	{
-		"",
-		&struct{}{},
-	}, {
-		"{}", &struct{}{},
-	}, {
-		"v: hi",
-		map[string]string{"v": "hi"},
-	}, {
-		"v: hi", map[string]interface{}{"v": "hi"},
-	}, {
-		"v: true",
-		map[string]string{"v": "true"},
-	}, {
-		"v: true",
-		map[string]interface{}{"v": true},
-	}, {
-		"v: 10",
-		map[string]interface{}{"v": 10},
-	}, {
-		"v: 0b10",
-		map[string]interface{}{"v": 2},
-	}, {
-		"v: 0xA",
-		map[string]interface{}{"v": 10},
-	}, {
-		"v: 4294967296",
-		map[string]int64{"v": 4294967296},
-	}, {
-		"v: 0.1",
-		map[string]interface{}{"v": 0.1},
-	}, {
-		"v: .1",
-		map[string]interface{}{"v": 0.1},
-	}, {
-		"v: .Inf",
-		map[string]interface{}{"v": math.Inf(+1)},
-	}, {
-		"v: -.Inf",
-		map[string]interface{}{"v": math.Inf(-1)},
-	}, {
-		"v: -10",
-		map[string]interface{}{"v": -10},
-	}, {
-		"v: -.1",
-		map[string]interface{}{"v": -0.1},
-	},
-
-	// Simple values.
-	{
-		"123",
-		&unmarshalIntTest,
-	},
-
-	// Floats from spec
-	{
-		"canonical: 6.8523e+5",
-		map[string]interface{}{"canonical": 6.8523e+5},
-	}, {
-		"expo: 685.230_15e+03",
-		map[string]interface{}{"expo": 685.23015e+03},
-	}, {
-		"fixed: 685_230.15",
-		map[string]interface{}{"fixed": 685230.15},
-	}, {
-		"neginf: -.inf",
-		map[string]interface{}{"neginf": math.Inf(-1)},
-	}, {
-		"fixed: 685_230.15",
-		map[string]float64{"fixed": 685230.15},
-	},
-	//{"sexa: 190:20:30.15", map[string]interface{}{"sexa": 0}}, // Unsupported
-	//{"notanum: .NaN", map[string]interface{}{"notanum": math.NaN()}}, // Equality of NaN fails.
-
-	// Bools from spec
-	{
-		"canonical: y",
-		map[string]interface{}{"canonical": true},
-	}, {
-		"answer: NO",
-		map[string]interface{}{"answer": false},
-	}, {
-		"logical: True",
-		map[string]interface{}{"logical": true},
-	}, {
-		"option: on",
-		map[string]interface{}{"option": true},
-	}, {
-		"option: on",
-		map[string]bool{"option": true},
-	},
-	// Ints from spec
-	{
-		"canonical: 685230",
-		map[string]interface{}{"canonical": 685230},
-	}, {
-		"decimal: +685_230",
-		map[string]interface{}{"decimal": 685230},
-	}, {
-		"octal: 02472256",
-		map[string]interface{}{"octal": 685230},
-	}, {
-		"hexa: 0x_0A_74_AE",
-		map[string]interface{}{"hexa": 685230},
-	}, {
-		"bin: 0b1010_0111_0100_1010_1110",
-		map[string]interface{}{"bin": 685230},
-	}, {
-		"bin: -0b101010",
-		map[string]interface{}{"bin": -42},
-	}, {
-		"decimal: +685_230",
-		map[string]int{"decimal": 685230},
-	},
-
-	//{"sexa: 190:20:30", map[string]interface{}{"sexa": 0}}, // Unsupported
-
-	// Nulls from spec
-	{
-		"empty:",
-		map[string]interface{}{"empty": nil},
-	}, {
-		"canonical: ~",
-		map[string]interface{}{"canonical": nil},
-	}, {
-		"english: null",
-		map[string]interface{}{"english": nil},
-	}, {
-		"~: null key",
-		map[interface{}]string{nil: "null key"},
-	}, {
-		"empty:",
-		map[string]*bool{"empty": nil},
-	},
-
-	// Flow sequence
-	{
-		"seq: [A,B]",
-		map[string]interface{}{"seq": []interface{}{"A", "B"}},
-	}, {
-		"seq: [A,B,C,]",
-		map[string][]string{"seq": []string{"A", "B", "C"}},
-	}, {
-		"seq: [A,1,C]",
-		map[string][]string{"seq": []string{"A", "1", "C"}},
-	}, {
-		"seq: [A,1,C]",
-		map[string][]int{"seq": []int{1}},
-	}, {
-		"seq: [A,1,C]",
-		map[string]interface{}{"seq": []interface{}{"A", 1, "C"}},
-	},
-	// Block sequence
-	{
-		"seq:\n - A\n - B",
-		map[string]interface{}{"seq": []interface{}{"A", "B"}},
-	}, {
-		"seq:\n - A\n - B\n - C",
-		map[string][]string{"seq": []string{"A", "B", "C"}},
-	}, {
-		"seq:\n - A\n - 1\n - C",
-		map[string][]string{"seq": []string{"A", "1", "C"}},
-	}, {
-		"seq:\n - A\n - 1\n - C",
-		map[string][]int{"seq": []int{1}},
-	}, {
-		"seq:\n - A\n - 1\n - C",
-		map[string]interface{}{"seq": []interface{}{"A", 1, "C"}},
-	},
-
-	// Literal block scalar
-	{
-		"scalar: | # Comment\n\n literal\n\n \ttext\n\n",
-		map[string]string{"scalar": "\nliteral\n\n\ttext\n"},
-	},
-
-	// Folded block scalar
-	{
-		"scalar: > # Comment\n\n folded\n line\n \n next\n line\n  * one\n  * two\n\n last\n line\n\n",
-		map[string]string{"scalar": "\nfolded line\nnext line\n * one\n * two\n\nlast line\n"},
-	},
-
-	// Map inside interface with no type hints.
-	{
-		"a: {b: c}",
-		map[string]interface{}{"a": map[interface{}]interface{}{"b": "c"}},
-	},
-
-	// Structs and type conversions.
-	{
-		"hello: world",
-		&struct{ Hello string }{"world"},
-	}, {
-		"a: {b: c}",
-		&struct{ A struct{ B string } }{struct{ B string }{"c"}},
-	}, {
-		"a: {b: c}",
-		&struct{ A *struct{ B string } }{&struct{ B string }{"c"}},
-	}, {
-		"a: {b: c}",
-		&struct{ A map[string]string }{map[string]string{"b": "c"}},
-	}, {
-		"a: {b: c}",
-		&struct{ A *map[string]string }{&map[string]string{"b": "c"}},
-	}, {
-		"a:",
-		&struct{ A map[string]string }{},
-	}, {
-		"a: 1",
-		&struct{ A int }{1},
-	}, {
-		"a: 1",
-		&struct{ A float64 }{1},
-	}, {
-		"a: 1.0",
-		&struct{ A int }{1},
-	}, {
-		"a: 1.0",
-		&struct{ A uint }{1},
-	}, {
-		"a: [1, 2]",
-		&struct{ A []int }{[]int{1, 2}},
-	}, {
-		"a: 1",
-		&struct{ B int }{0},
-	}, {
-		"a: 1",
-		&struct {
-			B int "a"
-		}{1},
-	}, {
-		"a: y",
-		&struct{ A bool }{true},
-	},
-
-	// Some cross type conversions
-	{
-		"v: 42",
-		map[string]uint{"v": 42},
-	}, {
-		"v: -42",
-		map[string]uint{},
-	}, {
-		"v: 4294967296",
-		map[string]uint64{"v": 4294967296},
-	}, {
-		"v: -4294967296",
-		map[string]uint64{},
-	},
-
-	// Overflow cases.
-	{
-		"v: 4294967297",
-		map[string]int32{},
-	}, {
-		"v: 128",
-		map[string]int8{},
-	},
-
-	// Quoted values.
-	{
-		"'1': '\"2\"'",
-		map[interface{}]interface{}{"1": "\"2\""},
-	}, {
-		"v:\n- A\n- 'B\n\n  C'\n",
-		map[string][]string{"v": []string{"A", "B\nC"}},
-	},
-
-	// Explicit tags.
-	{
-		"v: !!float '1.1'",
-		map[string]interface{}{"v": 1.1},
-	}, {
-		"v: !!null ''",
-		map[string]interface{}{"v": nil},
-	}, {
-		"%TAG !y! tag:yaml.org,2002:\n---\nv: !y!int '1'",
-		map[string]interface{}{"v": 1},
-	},
-
-	// Anchors and aliases.
-	{
-		"a: &x 1\nb: &y 2\nc: *x\nd: *y\n",
-		&struct{ A, B, C, D int }{1, 2, 1, 2},
-	}, {
-		"a: &a {c: 1}\nb: *a",
-		&struct {
-			A, B struct {
-				C int
-			}
-		}{struct{ C int }{1}, struct{ C int }{1}},
-	}, {
-		"a: &a [1, 2]\nb: *a",
-		&struct{ B []int }{[]int{1, 2}},
-	},
-
-	// Bug #1133337
-	{
-		"foo: ''",
-		map[string]*string{"foo": new(string)},
-	}, {
-		"foo: null",
-		map[string]string{},
-	},
-
-	// Ignored field
-	{
-		"a: 1\nb: 2\n",
-		&struct {
-			A int
-			B int "-"
-		}{1, 0},
-	},
-
-	// Bug #1191981
-	{
-		"" +
-			"%YAML 1.1\n" +
-			"--- !!str\n" +
-			`"Generic line break (no glyph)\n\` + "\n" +
-			` Generic line break (glyphed)\n\` + "\n" +
-			` Line separator\u2028\` + "\n" +
-			` Paragraph separator\u2029"` + "\n",
-		"" +
-			"Generic line break (no glyph)\n" +
-			"Generic line break (glyphed)\n" +
-			"Line separator\u2028Paragraph separator\u2029",
-	},
-
-	// Struct inlining
-	{
-		"a: 1\nb: 2\nc: 3\n",
-		&struct {
-			A int
-			C inlineB `yaml:",inline"`
-		}{1, inlineB{2, inlineC{3}}},
-	},
-
-	// bug 1243827
-	{
-		"a: -b_c",
-		map[string]interface{}{"a": "-b_c"},
-	},
-	{
-		"a: +b_c",
-		map[string]interface{}{"a": "+b_c"},
-	},
-	{
-		"a: 50cent_of_dollar",
-		map[string]interface{}{"a": "50cent_of_dollar"},
-	},
-}
-
-type inlineB struct {
-	B       int
-	inlineC `yaml:",inline"`
-}
-
-type inlineC struct {
-	C int
-}
-
-func (s *S) TestUnmarshal(c *C) {
-	for i, item := range unmarshalTests {
-		t := reflect.ValueOf(item.value).Type()
-		var value interface{}
-		switch t.Kind() {
-		case reflect.Map:
-			value = reflect.MakeMap(t).Interface()
-		case reflect.String:
-			t := reflect.ValueOf(item.value).Type()
-			v := reflect.New(t)
-			value = v.Interface()
-		default:
-			pt := reflect.ValueOf(item.value).Type()
-			pv := reflect.New(pt.Elem())
-			value = pv.Interface()
-		}
-		err := yaml.Unmarshal([]byte(item.data), value)
-		c.Assert(err, IsNil, Commentf("Item #%d", i))
-		if t.Kind() == reflect.String {
-			c.Assert(*value.(*string), Equals, item.value, Commentf("Item #%d", i))
-		} else {
-			c.Assert(value, DeepEquals, item.value, Commentf("Item #%d", i))
-		}
-	}
-}
-
-func (s *S) TestUnmarshalNaN(c *C) {
-	value := map[string]interface{}{}
-	err := yaml.Unmarshal([]byte("notanum: .NaN"), &value)
-	c.Assert(err, IsNil)
-	c.Assert(math.IsNaN(value["notanum"].(float64)), Equals, true)
-}
-
-var unmarshalErrorTests = []struct {
-	data, error string
-}{
-	{"v: !!float 'error'", "YAML error: Can't decode !!str 'error' as a !!float"},
-	{"v: [A,", "YAML error: line 1: did not find expected node content"},
-	{"v:\n- [A,", "YAML error: line 2: did not find expected node content"},
-	{"a: *b\n", "YAML error: Unknown anchor 'b' referenced"},
-	{"a: &a\n  b: *a\n", "YAML error: Anchor 'a' value contains itself"},
-	{"value: -", "YAML error: block sequence entries are not allowed in this context"},
-}
-
-func (s *S) TestUnmarshalErrors(c *C) {
-	for _, item := range unmarshalErrorTests {
-		var value interface{}
-		err := yaml.Unmarshal([]byte(item.data), &value)
-		c.Assert(err, ErrorMatches, item.error, Commentf("Partial unmarshal: %#v", value))
-	}
-}
-
-var setterTests = []struct {
-	data, tag string
-	value     interface{}
-}{
-	{"_: {hi: there}", "!!map", map[interface{}]interface{}{"hi": "there"}},
-	{"_: [1,A]", "!!seq", []interface{}{1, "A"}},
-	{"_: 10", "!!int", 10},
-	{"_: null", "!!null", nil},
-	{"_: !!foo 'BAR!'", "!!foo", "BAR!"},
-}
-
-var setterResult = map[int]bool{}
-
-type typeWithSetter struct {
-	tag   string
-	value interface{}
-}
-
-func (o *typeWithSetter) SetYAML(tag string, value interface{}) (ok bool) {
-	o.tag = tag
-	o.value = value
-	if i, ok := value.(int); ok {
-		if result, ok := setterResult[i]; ok {
-			return result
-		}
-	}
-	return true
-}
-
-type typeWithSetterField struct {
-	Field *typeWithSetter "_"
-}
-
-func (s *S) TestUnmarshalWithSetter(c *C) {
-	for _, item := range setterTests {
-		obj := &typeWithSetterField{}
-		err := yaml.Unmarshal([]byte(item.data), obj)
-		c.Assert(err, IsNil)
-		c.Assert(obj.Field, NotNil,
-			Commentf("Pointer not initialized (%#v)", item.value))
-		c.Assert(obj.Field.tag, Equals, item.tag)
-		c.Assert(obj.Field.value, DeepEquals, item.value)
-	}
-}
-
-func (s *S) TestUnmarshalWholeDocumentWithSetter(c *C) {
-	obj := &typeWithSetter{}
-	err := yaml.Unmarshal([]byte(setterTests[0].data), obj)
-	c.Assert(err, IsNil)
-	c.Assert(obj.tag, Equals, setterTests[0].tag)
-	value, ok := obj.value.(map[interface{}]interface{})
-	c.Assert(ok, Equals, true)
-	c.Assert(value["_"], DeepEquals, setterTests[0].value)
-}
-
-func (s *S) TestUnmarshalWithFalseSetterIgnoresValue(c *C) {
-	setterResult[2] = false
-	setterResult[4] = false
-	defer func() {
-		delete(setterResult, 2)
-		delete(setterResult, 4)
-	}()
-
-	m := map[string]*typeWithSetter{}
-	data := "{abc: 1, def: 2, ghi: 3, jkl: 4}"
-	err := yaml.Unmarshal([]byte(data), m)
-	c.Assert(err, IsNil)
-	c.Assert(m["abc"], NotNil)
-	c.Assert(m["def"], IsNil)
-	c.Assert(m["ghi"], NotNil)
-	c.Assert(m["jkl"], IsNil)
-
-	c.Assert(m["abc"].value, Equals, 1)
-	c.Assert(m["ghi"].value, Equals, 3)
-}
-
-//var data []byte
-//func init() {
-//	var err error
-//	data, err = ioutil.ReadFile("/tmp/file.yaml")
-//	if err != nil {
-//		panic(err)
-//	}
-//}
-//
-//func (s *S) BenchmarkUnmarshal(c *C) {
-//	var err error
-//	for i := 0; i < c.N; i++ {
-//		var v map[string]interface{}
-//		err = yaml.Unmarshal(data, &v)
-//	}
-//	if err != nil {
-//		panic(err)
-//	}
-//}
-//
-//func (s *S) BenchmarkMarshal(c *C) {
-//	var v map[string]interface{}
-//	yaml.Unmarshal(data, &v)
-//	c.ResetTimer()
-//	for i := 0; i < c.N; i++ {
-//		yaml.Marshal(&v)
-//	}
-//}
diff --git a/emitterc.go b/emitterc.go
deleted file mode 100644
index 542ffd2..0000000
--- a/emitterc.go
+++ /dev/null
@@ -1,1682 +0,0 @@
-package yaml
-
-import (
-	"bytes"
-)
-
-// Flush the buffer if needed.
-func flush(emitter *yaml_emitter_t) bool {
-	if emitter.buffer_pos+5 >= len(emitter.buffer) {
-		return yaml_emitter_flush(emitter)
-	}
-	return true
-}
-
-// Put a character to the output buffer.
-func put(emitter *yaml_emitter_t, value byte) bool {
-	if emitter.buffer_pos+5 >= len(emitter.buffer) && !yaml_emitter_flush(emitter) {
-		return false
-	}
-	emitter.buffer[emitter.buffer_pos] = value
-	emitter.buffer_pos++
-	emitter.column++
-	return true
-}
-
-// Put a line break to the output buffer.
-func put_break(emitter *yaml_emitter_t) bool {
-	if emitter.buffer_pos+5 >= len(emitter.buffer) && !yaml_emitter_flush(emitter) {
-		return false
-	}
-	switch emitter.line_break {
-	case yaml_CR_BREAK:
-		emitter.buffer[emitter.buffer_pos] = '\r'
-		emitter.buffer_pos += 1
-	case yaml_LN_BREAK:
-		emitter.buffer[emitter.buffer_pos] = '\n'
-		emitter.buffer_pos += 1
-	case yaml_CRLN_BREAK:
-		emitter.buffer[emitter.buffer_pos+0] = '\r'
-		emitter.buffer[emitter.buffer_pos+1] = '\n'
-		emitter.buffer_pos += 2
-	default:
-		panic("unknown line break setting")
-	}
-	emitter.column = 0
-	emitter.line++
-	return true
-}
-
-// Copy a character from a string into buffer.
-func write(emitter *yaml_emitter_t, s []byte, i *int) bool {
-	if emitter.buffer_pos+5 >= len(emitter.buffer) && !yaml_emitter_flush(emitter) {
-		return false
-	}
-	p := emitter.buffer_pos
-	w := width(s[*i])
-	switch w {
-	case 4:
-		emitter.buffer[p+3] = s[*i+3]
-		fallthrough
-	case 3:
-		emitter.buffer[p+2] = s[*i+2]
-		fallthrough
-	case 2:
-		emitter.buffer[p+1] = s[*i+1]
-		fallthrough
-	case 1:
-		emitter.buffer[p+0] = s[*i+0]
-	default:
-		panic("unknown character width")
-	}
-	emitter.column++
-	emitter.buffer_pos += w
-	*i += w
-	return true
-}
-
-// Write a whole string into buffer.
-func write_all(emitter *yaml_emitter_t, s []byte) bool {
-	for i := 0; i < len(s); {
-		if !write(emitter, s, &i) {
-			return false
-		}
-	}
-	return true
-}
-
-// Copy a line break character from a string into buffer.
-func write_break(emitter *yaml_emitter_t, s []byte, i *int) bool {
-	if s[*i] == '\n' {
-		if !put_break(emitter) {
-			return false
-		}
-		*i++
-	} else {
-		if !write(emitter, s, i) {
-			return false
-		}
-		emitter.column = 0
-		emitter.line++
-	}
-	return true
-}
-
-// Set an emitter error and return false.
-func yaml_emitter_set_emitter_error(emitter *yaml_emitter_t, problem string) bool {
-	emitter.error = yaml_EMITTER_ERROR
-	emitter.problem = problem
-	return false
-}
-
-// Emit an event.
-func yaml_emitter_emit(emitter *yaml_emitter_t, event *yaml_event_t) bool {
-	emitter.events = append(emitter.events, *event)
-	for !yaml_emitter_need_more_events(emitter) {
-		event := &emitter.events[emitter.events_head]
-		if !yaml_emitter_analyze_event(emitter, event) {
-			return false
-		}
-		if !yaml_emitter_state_machine(emitter, event) {
-			return false
-		}
-		yaml_event_delete(event)
-		emitter.events_head++
-	}
-	return true
-}
-
-// Check if we need to accumulate more events before emitting.
-//
-// We accumulate extra
-//  - 1 event for DOCUMENT-START
-//  - 2 events for SEQUENCE-START
-//  - 3 events for MAPPING-START
-//
-func yaml_emitter_need_more_events(emitter *yaml_emitter_t) bool {
-	if emitter.events_head == len(emitter.events) {
-		return true
-	}
-	var accumulate int
-	switch emitter.events[emitter.events_head].typ {
-	case yaml_DOCUMENT_START_EVENT:
-		accumulate = 1
-		break
-	case yaml_SEQUENCE_START_EVENT:
-		accumulate = 2
-		break
-	case yaml_MAPPING_START_EVENT:
-		accumulate = 3
-		break
-	default:
-		return false
-	}
-	if len(emitter.events)-emitter.events_head > accumulate {
-		return false
-	}
-	var level int
-	for i := emitter.events_head; i < len(emitter.events); i++ {
-		switch emitter.events[i].typ {
-		case yaml_STREAM_START_EVENT, yaml_DOCUMENT_START_EVENT, yaml_SEQUENCE_START_EVENT, yaml_MAPPING_START_EVENT:
-			level++
-		case yaml_STREAM_END_EVENT, yaml_DOCUMENT_END_EVENT, yaml_SEQUENCE_END_EVENT, yaml_MAPPING_END_EVENT:
-			level--
-		}
-		if level == 0 {
-			return false
-		}
-	}
-	return true
-}
-
-// Append a directive to the directives stack.
-func yaml_emitter_append_tag_directive(emitter *yaml_emitter_t, value *yaml_tag_directive_t, allow_duplicates bool) bool {
-	for i := 0; i < len(emitter.tag_directives); i++ {
-		if bytes.Equal(value.handle, emitter.tag_directives[i].handle) {
-			if allow_duplicates {
-				return true
-			}
-			return yaml_emitter_set_emitter_error(emitter, "duplicate %TAG directive")
-		}
-	}
-
-	// [Go] Do we actually need to copy this given garbage collection
-	// and the lack of deallocating destructors?
-	tag_copy := yaml_tag_directive_t{
-		handle: make([]byte, len(value.handle)),
-		prefix: make([]byte, len(value.prefix)),
-	}
-	copy(tag_copy.handle, value.handle)
-	copy(tag_copy.prefix, value.prefix)
-	emitter.tag_directives = append(emitter.tag_directives, tag_copy)
-	return true
-}
-
-// Increase the indentation level.
-func yaml_emitter_increase_indent(emitter *yaml_emitter_t, flow, indentless bool) bool {
-	emitter.indents = append(emitter.indents, emitter.indent)
-	if emitter.indent < 0 {
-		if flow {
-			emitter.indent = emitter.best_indent
-		} else {
-			emitter.indent = 0
-		}
-	} else if !indentless {
-		emitter.indent += emitter.best_indent
-	}
-	return true
-}
-
-// State dispatcher.
-func yaml_emitter_state_machine(emitter *yaml_emitter_t, event *yaml_event_t) bool {
-	switch emitter.state {
-	default:
-	case yaml_EMIT_STREAM_START_STATE:
-		return yaml_emitter_emit_stream_start(emitter, event)
-
-	case yaml_EMIT_FIRST_DOCUMENT_START_STATE:
-		return yaml_emitter_emit_document_start(emitter, event, true)
-
-	case yaml_EMIT_DOCUMENT_START_STATE:
-		return yaml_emitter_emit_document_start(emitter, event, false)
-
-	case yaml_EMIT_DOCUMENT_CONTENT_STATE:
-		return yaml_emitter_emit_document_content(emitter, event)
-
-	case yaml_EMIT_DOCUMENT_END_STATE:
-		return yaml_emitter_emit_document_end(emitter, event)
-
-	case yaml_EMIT_FLOW_SEQUENCE_FIRST_ITEM_STATE:
-		return yaml_emitter_emit_flow_sequence_item(emitter, event, true)
-
-	case yaml_EMIT_FLOW_SEQUENCE_ITEM_STATE:
-		return yaml_emitter_emit_flow_sequence_item(emitter, event, false)
-
-	case yaml_EMIT_FLOW_MAPPING_FIRST_KEY_STATE:
-		return yaml_emitter_emit_flow_mapping_key(emitter, event, true)
-
-	case yaml_EMIT_FLOW_MAPPING_KEY_STATE:
-		return yaml_emitter_emit_flow_mapping_key(emitter, event, false)
-
-	case yaml_EMIT_FLOW_MAPPING_SIMPLE_VALUE_STATE:
-		return yaml_emitter_emit_flow_mapping_value(emitter, event, true)
-
-	case yaml_EMIT_FLOW_MAPPING_VALUE_STATE:
-		return yaml_emitter_emit_flow_mapping_value(emitter, event, false)
-
-	case yaml_EMIT_BLOCK_SEQUENCE_FIRST_ITEM_STATE:
-		return yaml_emitter_emit_block_sequence_item(emitter, event, true)
-
-	case yaml_EMIT_BLOCK_SEQUENCE_ITEM_STATE:
-		return yaml_emitter_emit_block_sequence_item(emitter, event, false)
-
-	case yaml_EMIT_BLOCK_MAPPING_FIRST_KEY_STATE:
-		return yaml_emitter_emit_block_mapping_key(emitter, event, true)
-
-	case yaml_EMIT_BLOCK_MAPPING_KEY_STATE:
-		return yaml_emitter_emit_block_mapping_key(emitter, event, false)
-
-	case yaml_EMIT_BLOCK_MAPPING_SIMPLE_VALUE_STATE:
-		return yaml_emitter_emit_block_mapping_value(emitter, event, true)
-
-	case yaml_EMIT_BLOCK_MAPPING_VALUE_STATE:
-		return yaml_emitter_emit_block_mapping_value(emitter, event, false)
-
-	case yaml_EMIT_END_STATE:
-		return yaml_emitter_set_emitter_error(emitter, "expected nothing after STREAM-END")
-	}
-	panic("invalid emitter state")
-}
-
-// Expect STREAM-START.
-func yaml_emitter_emit_stream_start(emitter *yaml_emitter_t, event *yaml_event_t) bool {
-	if event.typ != yaml_STREAM_START_EVENT {
-		return yaml_emitter_set_emitter_error(emitter, "expected STREAM-START")
-	}
-	if emitter.encoding == yaml_ANY_ENCODING {
-		emitter.encoding = event.encoding
-		if emitter.encoding == yaml_ANY_ENCODING {
-			emitter.encoding = yaml_UTF8_ENCODING
-		}
-	}
-	if emitter.best_indent < 2 || emitter.best_indent > 9 {
-		emitter.best_indent = 2
-	}
-	if emitter.best_width >= 0 && emitter.best_width <= emitter.best_indent*2 {
-		emitter.best_width = 80
-	}
-	if emitter.best_width < 0 {
-		emitter.best_width = 1<<31 - 1
-	}
-	if emitter.line_break == yaml_ANY_BREAK {
-		emitter.line_break = yaml_LN_BREAK
-	}
-
-	emitter.indent = -1
-	emitter.line = 0
-	emitter.column = 0
-	emitter.whitespace = true
-	emitter.indention = true
-
-	if emitter.encoding != yaml_UTF8_ENCODING {
-		if !yaml_emitter_write_bom(emitter) {
-			return false
-		}
-	}
-	emitter.state = yaml_EMIT_FIRST_DOCUMENT_START_STATE
-	return true
-}
-
-// Expect DOCUMENT-START or STREAM-END.
-func yaml_emitter_emit_document_start(emitter *yaml_emitter_t, event *yaml_event_t, first bool) bool {
-
-	if event.typ == yaml_DOCUMENT_START_EVENT {
-
-		if event.version_directive != nil {
-			if !yaml_emitter_analyze_version_directive(emitter, event.version_directive) {
-				return false
-			}
-		}
-
-		for i := 0; i < len(event.tag_directives); i++ {
-			tag_directive := &event.tag_directives[i]
-			if !yaml_emitter_analyze_tag_directive(emitter, tag_directive) {
-				return false
-			}
-			if !yaml_emitter_append_tag_directive(emitter, tag_directive, false) {
-				return false
-			}
-		}
-
-		for i := 0; i < len(default_tag_directives); i++ {
-			tag_directive := &default_tag_directives[i]
-			if !yaml_emitter_append_tag_directive(emitter, tag_directive, true) {
-				return false
-			}
-		}
-
-		implicit := event.implicit
-		if !first || emitter.canonical {
-			implicit = false
-		}
-
-		if emitter.open_ended && (event.version_directive != nil || len(event.tag_directives) > 0) {
-			if !yaml_emitter_write_indicator(emitter, []byte("..."), true, false, false) {
-				return false
-			}
-			if !yaml_emitter_write_indent(emitter) {
-				return false
-			}
-		}
-
-		if event.version_directive != nil {
-			implicit = false
-			if !yaml_emitter_write_indicator(emitter, []byte("%YAML"), true, false, false) {
-				return false
-			}
-			if !yaml_emitter_write_indicator(emitter, []byte("1.1"), true, false, false) {
-				return false
-			}
-			if !yaml_emitter_write_indent(emitter) {
-				return false
-			}
-		}
-
-		if len(event.tag_directives) > 0 {
-			implicit = false
-			for i := 0; i < len(event.tag_directives); i++ {
-				tag_directive := &event.tag_directives[i]
-				if !yaml_emitter_write_indicator(emitter, []byte("%TAG"), true, false, false) {
-					return false
-				}
-				if !yaml_emitter_write_tag_handle(emitter, tag_directive.handle) {
-					return false
-				}
-				if !yaml_emitter_write_tag_content(emitter, tag_directive.prefix, true) {
-					return false
-				}
-				if !yaml_emitter_write_indent(emitter) {
-					return false
-				}
-			}
-		}
-
-		if yaml_emitter_check_empty_document(emitter) {
-			implicit = false
-		}
-		if !implicit {
-			if !yaml_emitter_write_indent(emitter) {
-				return false
-			}
-			if !yaml_emitter_write_indicator(emitter, []byte("---"), true, false, false) {
-				return false
-			}
-			if emitter.canonical {
-				if !yaml_emitter_write_indent(emitter) {
-					return false
-				}
-			}
-		}
-
-		emitter.state = yaml_EMIT_DOCUMENT_CONTENT_STATE
-		return true
-	}
-
-	if event.typ == yaml_STREAM_END_EVENT {
-		if emitter.open_ended {
-			if !yaml_emitter_write_indicator(emitter, []byte("..."), true, false, false) {
-				return false
-			}
-			if !yaml_emitter_write_indent(emitter) {
-				return false
-			}
-		}
-		if !yaml_emitter_flush(emitter) {
-			return false
-		}
-		emitter.state = yaml_EMIT_END_STATE
-		return true
-	}
-
-	return yaml_emitter_set_emitter_error(emitter, "expected DOCUMENT-START or STREAM-END")
-}
-
-// Expect the root node.
-func yaml_emitter_emit_document_content(emitter *yaml_emitter_t, event *yaml_event_t) bool {
-	emitter.states = append(emitter.states, yaml_EMIT_DOCUMENT_END_STATE)
-	return yaml_emitter_emit_node(emitter, event, true, false, false, false)
-}
-
-// Expect DOCUMENT-END.
-func yaml_emitter_emit_document_end(emitter *yaml_emitter_t, event *yaml_event_t) bool {
-	if event.typ != yaml_DOCUMENT_END_EVENT {
-		return yaml_emitter_set_emitter_error(emitter, "expected DOCUMENT-END")
-	}
-	if !yaml_emitter_write_indent(emitter) {
-		return false
-	}
-	if !event.implicit {
-		// [Go] Allocate the slice elsewhere.
-		if !yaml_emitter_write_indicator(emitter, []byte("..."), true, false, false) {
-			return false
-		}
-		if !yaml_emitter_write_indent(emitter) {
-			return false
-		}
-	}
-	if !yaml_emitter_flush(emitter) {
-		return false
-	}
-	emitter.state = yaml_EMIT_DOCUMENT_START_STATE
-	emitter.tag_directives = emitter.tag_directives[:0]
-	return true
-}
-
-// Expect a flow item node.
-func yaml_emitter_emit_flow_sequence_item(emitter *yaml_emitter_t, event *yaml_event_t, first bool) bool {
-	if first {
-		if !yaml_emitter_write_indicator(emitter, []byte{'['}, true, true, false) {
-			return false
-		}
-		if !yaml_emitter_increase_indent(emitter, true, false) {
-			return false
-		}
-		emitter.flow_level++
-	}
-
-	if event.typ == yaml_SEQUENCE_END_EVENT {
-		emitter.flow_level--
-		emitter.indent = emitter.indents[len(emitter.indents)-1]
-		emitter.indents = emitter.indents[:len(emitter.indents)-1]
-		if emitter.canonical && !first {
-			if !yaml_emitter_write_indicator(emitter, []byte{','}, false, false, false) {
-				return false
-			}
-			if !yaml_emitter_write_indent(emitter) {
-				return false
-			}
-		}
-		if !yaml_emitter_write_indicator(emitter, []byte{']'}, false, false, false) {
-			return false
-		}
-		emitter.state = emitter.states[len(emitter.states)-1]
-		emitter.states = emitter.states[:len(emitter.states)-1]
-
-		return true
-	}
-
-	if !first {
-		if !yaml_emitter_write_indicator(emitter, []byte{','}, false, false, false) {
-			return false
-		}
-	}
-
-	if emitter.canonical || emitter.column > emitter.best_width {
-		if !yaml_emitter_write_indent(emitter) {
-			return false
-		}
-	}
-	emitter.states = append(emitter.states, yaml_EMIT_FLOW_SEQUENCE_ITEM_STATE)
-	return yaml_emitter_emit_node(emitter, event, false, true, false, false)
-}
-
-// Expect a flow key node.
-func yaml_emitter_emit_flow_mapping_key(emitter *yaml_emitter_t, event *yaml_event_t, first bool) bool {
-	if first {
-		if !yaml_emitter_write_indicator(emitter, []byte{'{'}, true, true, false) {
-			return false
-		}
-		if !yaml_emitter_increase_indent(emitter, true, false) {
-			return false
-		}
-		emitter.flow_level++
-	}
-
-	if event.typ == yaml_MAPPING_END_EVENT {
-		emitter.flow_level--
-		emitter.indent = emitter.indents[len(emitter.indents)-1]
-		emitter.indents = emitter.indents[:len(emitter.indents)-1]
-		if emitter.canonical && !first {
-			if !yaml_emitter_write_indicator(emitter, []byte{','}, false, false, false) {
-				return false
-			}
-			if !yaml_emitter_write_indent(emitter) {
-				return false
-			}
-		}
-		if !yaml_emitter_write_indicator(emitter, []byte{'}'}, false, false, false) {
-			return false
-		}
-		emitter.state = emitter.states[len(emitter.states)-1]
-		emitter.states = emitter.states[:len(emitter.states)-1]
-		return true
-	}
-
-	if !first {
-		if !yaml_emitter_write_indicator(emitter, []byte{','}, false, false, false) {
-			return false
-		}
-	}
-	if emitter.canonical || emitter.column > emitter.best_width {
-		if !yaml_emitter_write_indent(emitter) {
-			return false
-		}
-	}
-
-	if !emitter.canonical && yaml_emitter_check_simple_key(emitter) {
-		emitter.states = append(emitter.states, yaml_EMIT_FLOW_MAPPING_SIMPLE_VALUE_STATE)
-		return yaml_emitter_emit_node(emitter, event, false, false, true, true)
-	}
-	if !yaml_emitter_write_indicator(emitter, []byte{'?'}, true, false, false) {
-		return false
-	}
-	emitter.states = append(emitter.states, yaml_EMIT_FLOW_MAPPING_VALUE_STATE)
-	return yaml_emitter_emit_node(emitter, event, false, false, true, false)
-}
-
-// Expect a flow value node.
-func yaml_emitter_emit_flow_mapping_value(emitter *yaml_emitter_t, event *yaml_event_t, simple bool) bool {
-	if simple {
-		if !yaml_emitter_write_indicator(emitter, []byte{':'}, false, false, false) {
-			return false
-		}
-	} else {
-		if emitter.canonical || emitter.column > emitter.best_width {
-			if !yaml_emitter_write_indent(emitter) {
-				return false
-			}
-		}
-		if !yaml_emitter_write_indicator(emitter, []byte{':'}, true, false, false) {
-			return false
-		}
-	}
-	emitter.states = append(emitter.states, yaml_EMIT_FLOW_MAPPING_KEY_STATE)
-	return yaml_emitter_emit_node(emitter, event, false, false, true, false)
-}
-
-// Expect a block item node.
-func yaml_emitter_emit_block_sequence_item(emitter *yaml_emitter_t, event *yaml_event_t, first bool) bool {
-	if first {
-		if !yaml_emitter_increase_indent(emitter, false, emitter.mapping_context && !emitter.indention) {
-			return false
-		}
-	}
-	if event.typ == yaml_SEQUENCE_END_EVENT {
-		emitter.indent = emitter.indents[len(emitter.indents)-1]
-		emitter.indents = emitter.indents[:len(emitter.indents)-1]
-		emitter.state = emitter.states[len(emitter.states)-1]
-		emitter.states = emitter.states[:len(emitter.states)-1]
-		return true
-	}
-	if !yaml_emitter_write_indent(emitter) {
-		return false
-	}
-	if !yaml_emitter_write_indicator(emitter, []byte{'-'}, true, false, true) {
-		return false
-	}
-	emitter.states = append(emitter.states, yaml_EMIT_BLOCK_SEQUENCE_ITEM_STATE)
-	return yaml_emitter_emit_node(emitter, event, false, true, false, false)
-}
-
-// Expect a block key node.
-func yaml_emitter_emit_block_mapping_key(emitter *yaml_emitter_t, event *yaml_event_t, first bool) bool {
-	if first {
-		if !yaml_emitter_increase_indent(emitter, false, false) {
-			return false
-		}
-	}
-	if event.typ == yaml_MAPPING_END_EVENT {
-		emitter.indent = emitter.indents[len(emitter.indents)-1]
-		emitter.indents = emitter.indents[:len(emitter.indents)-1]
-		emitter.state = emitter.states[len(emitter.states)-1]
-		emitter.states = emitter.states[:len(emitter.states)-1]
-		return true
-	}
-	if !yaml_emitter_write_indent(emitter) {
-		return false
-	}
-	if yaml_emitter_check_simple_key(emitter) {
-		emitter.states = append(emitter.states, yaml_EMIT_BLOCK_MAPPING_SIMPLE_VALUE_STATE)
-		return yaml_emitter_emit_node(emitter, event, false, false, true, true)
-	}
-	if !yaml_emitter_write_indicator(emitter, []byte{'?'}, true, false, true) {
-		return false
-	}
-	emitter.states = append(emitter.states, yaml_EMIT_BLOCK_MAPPING_VALUE_STATE)
-	return yaml_emitter_emit_node(emitter, event, false, false, true, false)
-}
-
-// Expect a block value node.
-func yaml_emitter_emit_block_mapping_value(emitter *yaml_emitter_t, event *yaml_event_t, simple bool) bool {
-	if simple {
-		if !yaml_emitter_write_indicator(emitter, []byte{':'}, false, false, false) {
-			return false
-		}
-	} else {
-		if !yaml_emitter_write_indent(emitter) {
-			return false
-		}
-		if !yaml_emitter_write_indicator(emitter, []byte{':'}, true, false, true) {
-			return false
-		}
-	}
-	emitter.states = append(emitter.states, yaml_EMIT_BLOCK_MAPPING_KEY_STATE)
-	return yaml_emitter_emit_node(emitter, event, false, false, true, false)
-}
-
-// Expect a node.
-func yaml_emitter_emit_node(emitter *yaml_emitter_t, event *yaml_event_t,
-	root bool, sequence bool, mapping bool, simple_key bool) bool {
-
-	emitter.root_context = root
-	emitter.sequence_context = sequence
-	emitter.mapping_context = mapping
-	emitter.simple_key_context = simple_key
-
-	switch event.typ {
-	case yaml_ALIAS_EVENT:
-		return yaml_emitter_emit_alias(emitter, event)
-	case yaml_SCALAR_EVENT:
-		return yaml_emitter_emit_scalar(emitter, event)
-	case yaml_SEQUENCE_START_EVENT:
-		return yaml_emitter_emit_sequence_start(emitter, event)
-	case yaml_MAPPING_START_EVENT:
-		return yaml_emitter_emit_mapping_start(emitter, event)
-	default:
-		return yaml_emitter_set_emitter_error(emitter,
-			"expected SCALAR, SEQUENCE-START, MAPPING-START, or ALIAS")
-	}
-	return false
-}
-
-// Expect ALIAS.
-func yaml_emitter_emit_alias(emitter *yaml_emitter_t, event *yaml_event_t) bool {
-	if !yaml_emitter_process_anchor(emitter) {
-		return false
-	}
-	emitter.state = emitter.states[len(emitter.states)-1]
-	emitter.states = emitter.states[:len(emitter.states)-1]
-	return true
-}
-
-// Expect SCALAR.
-func yaml_emitter_emit_scalar(emitter *yaml_emitter_t, event *yaml_event_t) bool {
-	if !yaml_emitter_select_scalar_style(emitter, event) {
-		return false
-	}
-	if !yaml_emitter_process_anchor(emitter) {
-		return false
-	}
-	if !yaml_emitter_process_tag(emitter) {
-		return false
-	}
-	if !yaml_emitter_increase_indent(emitter, true, false) {
-		return false
-	}
-	if !yaml_emitter_process_scalar(emitter) {
-		return false
-	}
-	emitter.indent = emitter.indents[len(emitter.indents)-1]
-	emitter.indents = emitter.indents[:len(emitter.indents)-1]
-	emitter.state = emitter.states[len(emitter.states)-1]
-	emitter.states = emitter.states[:len(emitter.states)-1]
-	return true
-}
-
-// Expect SEQUENCE-START.
-func yaml_emitter_emit_sequence_start(emitter *yaml_emitter_t, event *yaml_event_t) bool {
-	if !yaml_emitter_process_anchor(emitter) {
-		return false
-	}
-	if !yaml_emitter_process_tag(emitter) {
-		return false
-	}
-	if emitter.flow_level > 0 || emitter.canonical || event.sequence_style() == yaml_FLOW_SEQUENCE_STYLE ||
-		yaml_emitter_check_empty_sequence(emitter) {
-		emitter.state = yaml_EMIT_FLOW_SEQUENCE_FIRST_ITEM_STATE
-	} else {
-		emitter.state = yaml_EMIT_BLOCK_SEQUENCE_FIRST_ITEM_STATE
-	}
-	return true
-}
-
-// Expect MAPPING-START.
-func yaml_emitter_emit_mapping_start(emitter *yaml_emitter_t, event *yaml_event_t) bool {
-	if !yaml_emitter_process_anchor(emitter) {
-		return false
-	}
-	if !yaml_emitter_process_tag(emitter) {
-		return false
-	}
-	if emitter.flow_level > 0 || emitter.canonical || event.mapping_style() == yaml_FLOW_MAPPING_STYLE ||
-		yaml_emitter_check_empty_mapping(emitter) {
-		emitter.state = yaml_EMIT_FLOW_MAPPING_FIRST_KEY_STATE
-	} else {
-		emitter.state = yaml_EMIT_BLOCK_MAPPING_FIRST_KEY_STATE
-	}
-	return true
-}
-
-// Check if the document content is an empty scalar.
-func yaml_emitter_check_empty_document(emitter *yaml_emitter_t) bool {
-	return false // [Go] Huh?
-}
-
-// Check if the next events represent an empty sequence.
-func yaml_emitter_check_empty_sequence(emitter *yaml_emitter_t) bool {
-	if len(emitter.events)-emitter.events_head < 2 {
-		return false
-	}
-	return emitter.events[emitter.events_head].typ == yaml_SEQUENCE_START_EVENT &&
-		emitter.events[emitter.events_head+1].typ == yaml_SEQUENCE_END_EVENT
-}
-
-// Check if the next events represent an empty mapping.
-func yaml_emitter_check_empty_mapping(emitter *yaml_emitter_t) bool {
-	if len(emitter.events)-emitter.events_head < 2 {
-		return false
-	}
-	return emitter.events[emitter.events_head].typ == yaml_MAPPING_START_EVENT &&
-		emitter.events[emitter.events_head+1].typ == yaml_MAPPING_END_EVENT
-}
-
-// Check if the next node can be expressed as a simple key.
-func yaml_emitter_check_simple_key(emitter *yaml_emitter_t) bool {
-	length := 0
-	switch emitter.events[emitter.events_head].typ {
-	case yaml_ALIAS_EVENT:
-		length += len(emitter.anchor_data.anchor)
-	case yaml_SCALAR_EVENT:
-		if emitter.scalar_data.multiline {
-			return false
-		}
-		length += len(emitter.anchor_data.anchor) +
-			len(emitter.tag_data.handle) +
-			len(emitter.tag_data.suffix) +
-			len(emitter.scalar_data.value)
-	case yaml_SEQUENCE_START_EVENT:
-		if !yaml_emitter_check_empty_sequence(emitter) {
-			return false
-		}
-		length += len(emitter.anchor_data.anchor) +
-			len(emitter.tag_data.handle) +
-			len(emitter.tag_data.suffix)
-	case yaml_MAPPING_START_EVENT:
-		if !yaml_emitter_check_empty_mapping(emitter) {
-			return false
-		}
-		length += len(emitter.anchor_data.anchor) +
-			len(emitter.tag_data.handle) +
-			len(emitter.tag_data.suffix)
-	default:
-		return false
-	}
-	return length <= 128
-}
-
-// Determine an acceptable scalar style.
-func yaml_emitter_select_scalar_style(emitter *yaml_emitter_t, event *yaml_event_t) bool {
-
-	no_tag := len(emitter.tag_data.handle) == 0 && len(emitter.tag_data.suffix) == 0
-	if no_tag && !event.implicit && !event.quoted_implicit {
-		return yaml_emitter_set_emitter_error(emitter, "neither tag nor implicit flags are specified")
-	}
-
-	style := event.scalar_style()
-	if style == yaml_ANY_SCALAR_STYLE {
-		style = yaml_PLAIN_SCALAR_STYLE
-	}
-	if emitter.canonical {
-		style = yaml_DOUBLE_QUOTED_SCALAR_STYLE
-	}
-	if emitter.simple_key_context && emitter.scalar_data.multiline {
-		style = yaml_DOUBLE_QUOTED_SCALAR_STYLE
-	}
-
-	if style == yaml_PLAIN_SCALAR_STYLE {
-		if emitter.flow_level > 0 && !emitter.scalar_data.flow_plain_allowed ||
-			emitter.flow_level == 0 && !emitter.scalar_data.block_plain_allowed {
-			style = yaml_SINGLE_QUOTED_SCALAR_STYLE
-		}
-		if len(emitter.scalar_data.value) == 0 && (emitter.flow_level > 0 || emitter.simple_key_context) {
-			style = yaml_SINGLE_QUOTED_SCALAR_STYLE
-		}
-		if no_tag && !event.implicit {
-			style = yaml_SINGLE_QUOTED_SCALAR_STYLE
-		}
-	}
-	if style == yaml_SINGLE_QUOTED_SCALAR_STYLE {
-		if !emitter.scalar_data.single_quoted_allowed {
-			style = yaml_DOUBLE_QUOTED_SCALAR_STYLE
-		}
-	}
-	if style == yaml_LITERAL_SCALAR_STYLE || style == yaml_FOLDED_SCALAR_STYLE {
-		if !emitter.scalar_data.block_allowed || emitter.flow_level > 0 || emitter.simple_key_context {
-			style = yaml_DOUBLE_QUOTED_SCALAR_STYLE
-		}
-	}
-
-	if no_tag && !event.quoted_implicit && style != yaml_PLAIN_SCALAR_STYLE {
-		emitter.tag_data.handle = []byte{'!'}
-	}
-	emitter.scalar_data.style = style
-	return true
-}
-
-// Write an achor.
-func yaml_emitter_process_anchor(emitter *yaml_emitter_t) bool {
-	if emitter.anchor_data.anchor == nil {
-		return true
-	}
-	c := []byte{'&'}
-	if emitter.anchor_data.alias {
-		c[0] = '*'
-	}
-	if !yaml_emitter_write_indicator(emitter, c, true, false, false) {
-		return false
-	}
-	return yaml_emitter_write_anchor(emitter, emitter.anchor_data.anchor)
-}
-
-// Write a tag.
-func yaml_emitter_process_tag(emitter *yaml_emitter_t) bool {
-	if len(emitter.tag_data.handle) == 0 && len(emitter.tag_data.suffix) == 0 {
-		return true
-	}
-	if len(emitter.tag_data.handle) > 0 {
-		if !yaml_emitter_write_tag_handle(emitter, emitter.tag_data.handle) {
-			return false
-		}
-		if len(emitter.tag_data.suffix) > 0 {
-			if !yaml_emitter_write_tag_content(emitter, emitter.tag_data.suffix, false) {
-				return false
-			}
-		}
-	} else {
-		// [Go] Allocate these slices elsewhere.
-		if !yaml_emitter_write_indicator(emitter, []byte("!<"), true, false, false) {
-			return false
-		}
-		if !yaml_emitter_write_tag_content(emitter, emitter.tag_data.suffix, false) {
-			return false
-		}
-		if !yaml_emitter_write_indicator(emitter, []byte{'>'}, false, false, false) {
-			return false
-		}
-	}
-	return true
-}
-
-// Write a scalar.
-func yaml_emitter_process_scalar(emitter *yaml_emitter_t) bool {
-	switch emitter.scalar_data.style {
-	case yaml_PLAIN_SCALAR_STYLE:
-		return yaml_emitter_write_plain_scalar(emitter, emitter.scalar_data.value, !emitter.simple_key_context)
-
-	case yaml_SINGLE_QUOTED_SCALAR_STYLE:
-		return yaml_emitter_write_single_quoted_scalar(emitter, emitter.scalar_data.value, !emitter.simple_key_context)
-
-	case yaml_DOUBLE_QUOTED_SCALAR_STYLE:
-		return yaml_emitter_write_double_quoted_scalar(emitter, emitter.scalar_data.value, !emitter.simple_key_context)
-
-	case yaml_LITERAL_SCALAR_STYLE:
-		return yaml_emitter_write_literal_scalar(emitter, emitter.scalar_data.value)
-
-	case yaml_FOLDED_SCALAR_STYLE:
-		return yaml_emitter_write_folded_scalar(emitter, emitter.scalar_data.value)
-	}
-	panic("unknown scalar style")
-}
-
-// Check if a %YAML directive is valid.
-func yaml_emitter_analyze_version_directive(emitter *yaml_emitter_t, version_directive *yaml_version_directive_t) bool {
-	if version_directive.major != 1 || version_directive.minor != 1 {
-		return yaml_emitter_set_emitter_error(emitter, "incompatible %YAML directive")
-	}
-	return true
-}
-
-// Check if a %TAG directive is valid.
-func yaml_emitter_analyze_tag_directive(emitter *yaml_emitter_t, tag_directive *yaml_tag_directive_t) bool {
-	handle := tag_directive.handle
-	prefix := tag_directive.prefix
-	if len(handle) == 0 {
-		return yaml_emitter_set_emitter_error(emitter, "tag handle must not be empty")
-	}
-	if handle[0] != '!' {
-		return yaml_emitter_set_emitter_error(emitter, "tag handle must start with '!'")
-	}
-	if handle[len(handle)-1] != '!' {
-		return yaml_emitter_set_emitter_error(emitter, "tag handle must end with '!'")
-	}
-	for i := 1; i < len(handle)-1; i += width(handle[i]) {
-		if !is_alpha(handle, i) {
-			return yaml_emitter_set_emitter_error(emitter, "tag handle must contain alphanumerical characters only")
-		}
-	}
-	if len(prefix) == 0 {
-		return yaml_emitter_set_emitter_error(emitter, "tag prefix must not be empty")
-	}
-	return true
-}
-
-// Check if an anchor is valid.
-func yaml_emitter_analyze_anchor(emitter *yaml_emitter_t, anchor []byte, alias bool) bool {
-	if len(anchor) == 0 {
-		problem := "anchor value must not be empty"
-		if alias {
-			problem = "alias value must not be empty"
-		}
-		return yaml_emitter_set_emitter_error(emitter, problem)
-	}
-	for i := 0; i < len(anchor); i += width(anchor[i]) {
-		if !is_alpha(anchor, i) {
-			problem := "anchor value must contain alphanumerical characters only"
-			if alias {
-				problem = "alias value must contain alphanumerical characters only"
-			}
-			return yaml_emitter_set_emitter_error(emitter, problem)
-		}
-	}
-	emitter.anchor_data.anchor = anchor
-	emitter.anchor_data.alias = alias
-	return true
-}
-
-// Check if a tag is valid.
-func yaml_emitter_analyze_tag(emitter *yaml_emitter_t, tag []byte) bool {
-	if len(tag) == 0 {
-		return yaml_emitter_set_emitter_error(emitter, "tag value must not be empty")
-	}
-	for i := 0; i < len(emitter.tag_directives); i++ {
-		tag_directive := &emitter.tag_directives[i]
-		if bytes.HasPrefix(tag, tag_directive.prefix) {
-			emitter.tag_data.handle = tag_directive.handle
-			emitter.tag_data.suffix = tag[len(tag_directive.prefix):]
-		}
-		return true
-	}
-	emitter.tag_data.suffix = tag
-	return true
-}
-
-// Check if a scalar is valid.
-func yaml_emitter_analyze_scalar(emitter *yaml_emitter_t, value []byte) bool {
-	var (
-		block_indicators   = false
-		flow_indicators    = false
-		line_breaks        = false
-		special_characters = false
-
-		leading_space  = false
-		leading_break  = false
-		trailing_space = false
-		trailing_break = false
-		break_space    = false
-		space_break    = false
-
-		preceeded_by_whitespace = false
-		followed_by_whitespace  = false
-		previous_space          = false
-		previous_break          = false
-	)
-
-	emitter.scalar_data.value = value
-
-	if len(value) == 0 {
-		emitter.scalar_data.multiline = false
-		emitter.scalar_data.flow_plain_allowed = false
-		emitter.scalar_data.block_plain_allowed = true
-		emitter.scalar_data.single_quoted_allowed = true
-		emitter.scalar_data.block_allowed = false
-		return true
-	}
-
-	if len(value) >= 3 && ((value[0] == '-' && value[1] == '-' && value[2] == '-') || (value[0] == '.' && value[1] == '.' && value[2] == '.')) {
-		block_indicators = true
-		flow_indicators = true
-	}
-
-	preceeded_by_whitespace = true
-	for i, w := 0, 0; i < len(value); i += w {
-		w = width(value[0])
-		followed_by_whitespace = i+w >= len(value) || is_blank(value, i+w)
-
-		if i == 0 {
-			switch value[i] {
-			case '#', ',', '[', ']', '{', '}', '&', '*', '!', '|', '>', '\'', '"', '%', '@', '`':
-				flow_indicators = true
-				block_indicators = true
-			case '?', ':':
-				flow_indicators = true
-				if followed_by_whitespace {
-					block_indicators = true
-				}
-			case '-':
-				if followed_by_whitespace {
-					flow_indicators = true
-					block_indicators = true
-				}
-			}
-		} else {
-			switch value[i] {
-			case ',', '?', '[', ']', '{', '}':
-				flow_indicators = true
-			case ':':
-				flow_indicators = true
-				if followed_by_whitespace {
-					block_indicators = true
-				}
-			case '#':
-				if preceeded_by_whitespace {
-					flow_indicators = true
-					block_indicators = true
-				}
-			}
-		}
-
-		if !is_printable(value, i) || !is_ascii(value, i) && !emitter.unicode {
-			special_characters = true
-		}
-		if is_space(value, i) {
-			if i == 0 {
-				leading_space = true
-			}
-			if i+width(value[i]) == len(value) {
-				trailing_space = true
-			}
-			if previous_break {
-				break_space = true
-			}
-			previous_space = true
-			previous_break = false
-		} else if is_break(value, i) {
-			line_breaks = true
-			if i == 0 {
-				leading_break = true
-			}
-			if i+width(value[i]) == len(value) {
-				trailing_break = true
-			}
-			if previous_space {
-				space_break = true
-			}
-			previous_space = false
-			previous_break = true
-		} else {
-			previous_space = false
-			previous_break = false
-		}
-
-		// [Go]: Why 'z'? Couldn't be the end of the string as that's the loop condition.
-		preceeded_by_whitespace = is_blankz(value, i)
-	}
-
-	emitter.scalar_data.multiline = line_breaks
-	emitter.scalar_data.flow_plain_allowed = true
-	emitter.scalar_data.block_plain_allowed = true
-	emitter.scalar_data.single_quoted_allowed = true
-	emitter.scalar_data.block_allowed = true
-
-	if leading_space || leading_break || trailing_space || trailing_break {
-		emitter.scalar_data.flow_plain_allowed = false
-		emitter.scalar_data.block_plain_allowed = false
-	}
-	if trailing_space {
-		emitter.scalar_data.block_allowed = false
-	}
-	if break_space {
-		emitter.scalar_data.flow_plain_allowed = false
-		emitter.scalar_data.block_plain_allowed = false
-		emitter.scalar_data.single_quoted_allowed = false
-	}
-	if space_break || special_characters {
-		emitter.scalar_data.flow_plain_allowed = false
-		emitter.scalar_data.block_plain_allowed = false
-		emitter.scalar_data.single_quoted_allowed = false
-		emitter.scalar_data.block_allowed = false
-	}
-	if line_breaks {
-		emitter.scalar_data.flow_plain_allowed = false
-		emitter.scalar_data.block_plain_allowed = false
-	}
-	if flow_indicators {
-		emitter.scalar_data.flow_plain_allowed = false
-	}
-	if block_indicators {
-		emitter.scalar_data.block_plain_allowed = false
-	}
-	return true
-}
-
-// Check if the event data is valid.
-func yaml_emitter_analyze_event(emitter *yaml_emitter_t, event *yaml_event_t) bool {
-
-	emitter.anchor_data.anchor = nil
-	emitter.tag_data.handle = nil
-	emitter.tag_data.suffix = nil
-	emitter.scalar_data.value = nil
-
-	switch event.typ {
-	case yaml_ALIAS_EVENT:
-		if !yaml_emitter_analyze_anchor(emitter, event.anchor, true) {
-			return false
-		}
-
-	case yaml_SCALAR_EVENT:
-		if len(event.anchor) > 0 {
-			if !yaml_emitter_analyze_anchor(emitter, event.anchor, false) {
-				return false
-			}
-		}
-		if len(event.tag) > 0 && (emitter.canonical || (!event.implicit && !event.quoted_implicit)) {
-			if !yaml_emitter_analyze_tag(emitter, event.tag) {
-				return false
-			}
-		}
-		if !yaml_emitter_analyze_scalar(emitter, event.value) {
-			return false
-		}
-
-	case yaml_SEQUENCE_START_EVENT:
-		if len(event.anchor) > 0 {
-			if !yaml_emitter_analyze_anchor(emitter, event.anchor, false) {
-				return false
-			}
-		}
-		if len(event.tag) > 0 && (emitter.canonical || !event.implicit) {
-			if !yaml_emitter_analyze_tag(emitter, event.tag) {
-				return false
-			}
-		}
-
-	case yaml_MAPPING_START_EVENT:
-		if len(event.anchor) > 0 {
-			if !yaml_emitter_analyze_anchor(emitter, event.anchor, false) {
-				return false
-			}
-		}
-		if len(event.tag) > 0 && (emitter.canonical || !event.implicit) {
-			if !yaml_emitter_analyze_tag(emitter, event.tag) {
-				return false
-			}
-		}
-	}
-	return true
-}
-
-// Write the BOM character.
-func yaml_emitter_write_bom(emitter *yaml_emitter_t) bool {
-	if !flush(emitter) {
-		return false
-	}
-	pos := emitter.buffer_pos
-	emitter.buffer[pos+0] = '\xEF'
-	emitter.buffer[pos+1] = '\xBB'
-	emitter.buffer[pos+2] = '\xBF'
-	emitter.buffer_pos += 3
-	return true
-}
-
-func yaml_emitter_write_indent(emitter *yaml_emitter_t) bool {
-	indent := emitter.indent
-	if indent < 0 {
-		indent = 0
-	}
-	if !emitter.indention || emitter.column > indent || (emitter.column == indent && !emitter.whitespace) {
-		if !put_break(emitter) {
-			return false
-		}
-	}
-	for emitter.column < indent {
-		if !put(emitter, ' ') {
-			return false
-		}
-	}
-	emitter.whitespace = true
-	emitter.indention = true
-	return true
-}
-
-func yaml_emitter_write_indicator(emitter *yaml_emitter_t, indicator []byte, need_whitespace, is_whitespace, is_indention bool) bool {
-	if need_whitespace && !emitter.whitespace {
-		if !put(emitter, ' ') {
-			return false
-		}
-	}
-	if !write_all(emitter, indicator) {
-		return false
-	}
-	emitter.whitespace = is_whitespace
-	emitter.indention = (emitter.indention && is_indention)
-	emitter.open_ended = false
-	return true
-}
-
-func yaml_emitter_write_anchor(emitter *yaml_emitter_t, value []byte) bool {
-	if !write_all(emitter, value) {
-		return false
-	}
-	emitter.whitespace = false
-	emitter.indention = false
-	return true
-}
-
-func yaml_emitter_write_tag_handle(emitter *yaml_emitter_t, value []byte) bool {
-	if !emitter.whitespace {
-		if !put(emitter, ' ') {
-			return false
-		}
-	}
-	if !write_all(emitter, value) {
-		return false
-	}
-	emitter.whitespace = false
-	emitter.indention = false
-	return true
-}
-
-func yaml_emitter_write_tag_content(emitter *yaml_emitter_t, value []byte, need_whitespace bool) bool {
-	if need_whitespace && !emitter.whitespace {
-		if !put(emitter, ' ') {
-			return false
-		}
-	}
-	for i := 0; i < len(value); {
-		var must_write bool
-		switch value[i] {
-		case ';', '/', '?', ':', '@', '&', '=', '+', '$', ',', '_', '.', '~', '*', '\'', '(', ')', '[', ']':
-			must_write = true
-		default:
-			must_write = is_alpha(value, i)
-		}
-		if must_write {
-			if !write(emitter, value, &i) {
-				return false
-			}
-		} else {
-			w := width(value[i])
-			for k := 0; k < w; k++ {
-				octet := value[i]
-				i++
-
-				c := octet >> 4
-				if c < 10 {
-					c += '0'
-				} else {
-					c += 'A' - 10
-				}
-				if !put(emitter, c) {
-					return false
-				}
-
-				c = octet & 0x0f
-				if c < 10 {
-					c += '0'
-				} else {
-					c += 'A' - 10
-				}
-				if !put(emitter, c) {
-					return false
-				}
-			}
-		}
-	}
-	emitter.whitespace = false
-	emitter.indention = false
-	return true
-}
-
-func yaml_emitter_write_plain_scalar(emitter *yaml_emitter_t, value []byte, allow_breaks bool) bool {
-	if !emitter.whitespace {
-		if !put(emitter, ' ') {
-			return false
-		}
-	}
-
-	spaces := false
-	breaks := false
-	for i := 0; i < len(value); {
-		if is_space(value, i) {
-			if allow_breaks && !spaces && emitter.column > emitter.best_width && !is_space(value, i+1) {
-				if !yaml_emitter_write_indent(emitter) {
-					return false
-				}
-				i += width(value[i])
-			} else {
-				if !write(emitter, value, &i) {
-					return false
-				}
-			}
-			spaces = true
-		} else if is_break(value, i) {
-			if !breaks && value[i] == '\n' {
-				if !put_break(emitter) {
-					return false
-				}
-			}
-			if !write_break(emitter, value, &i) {
-				return false
-			}
-			emitter.indention = true
-			breaks = true
-		} else {
-			if breaks {
-				if !yaml_emitter_write_indent(emitter) {
-					return false
-				}
-			}
-			if !write(emitter, value, &i) {
-				return false
-			}
-			emitter.indention = false
-			spaces = false
-			breaks = false
-		}
-	}
-
-	emitter.whitespace = false
-	emitter.indention = false
-	if emitter.root_context {
-		emitter.open_ended = true
-	}
-
-	return true
-}
-
-func yaml_emitter_write_single_quoted_scalar(emitter *yaml_emitter_t, value []byte, allow_breaks bool) bool {
-
-	if !yaml_emitter_write_indicator(emitter, []byte{'\''}, true, false, false) {
-		return false
-	}
-
-	spaces := false
-	breaks := false
-	for i := 0; i < len(value); {
-		if is_space(value, i) {
-			if allow_breaks && !spaces && emitter.column > emitter.best_width && i > 0 && i < len(value)-1 && !is_space(value, i+1) {
-				if !yaml_emitter_write_indent(emitter) {
-					return false
-				}
-				i += width(value[i])
-			} else {
-				if !write(emitter, value, &i) {
-					return false
-				}
-			}
-			spaces = true
-		} else if is_break(value, i) {
-			if !breaks && value[i] == '\n' {
-				if !put_break(emitter) {
-					return false
-				}
-			}
-			if !write_break(emitter, value, &i) {
-				return false
-			}
-			emitter.indention = true
-			breaks = true
-		} else {
-			if breaks {
-				if !yaml_emitter_write_indent(emitter) {
-					return false
-				}
-			}
-			if value[i] == '\'' {
-				if !put(emitter, '\'') {
-					return false
-				}
-			}
-			if !write(emitter, value, &i) {
-				return false
-			}
-			emitter.indention = false
-			spaces = false
-			breaks = false
-		}
-	}
-	if !yaml_emitter_write_indicator(emitter, []byte{'\''}, false, false, false) {
-		return false
-	}
-	emitter.whitespace = false
-	emitter.indention = false
-	return true
-}
-
-func yaml_emitter_write_double_quoted_scalar(emitter *yaml_emitter_t, value []byte, allow_breaks bool) bool {
-	spaces := false
-	if !yaml_emitter_write_indicator(emitter, []byte{'"'}, true, false, false) {
-		return false
-	}
-
-	for i := 0; i < len(value); {
-		if !is_printable(value, i) || (!emitter.unicode && !is_ascii(value, i)) ||
-			is_bom(value, i) || is_break(value, i) ||
-			value[i] == '"' || value[i] == '\\' {
-
-			octet := value[i]
-
-			var w int
-			var v rune
-			switch {
-			case octet&0x80 == 0x00:
-				w, v = 1, rune(octet&0x7F)
-			case octet&0xE0 == 0xC0:
-				w, v = 2, rune(octet&0x1F)
-			case octet&0xF0 == 0xE0:
-				w, v = 3, rune(octet&0x0F)
-			case octet&0xF8 == 0xF0:
-				w, v = 4, rune(octet&0x07)
-			}
-			for k := 1; k < w; k++ {
-				octet = value[i+k]
-				v = (v << 6) + (rune(octet) & 0x3F)
-			}
-			i += w
-
-			if !put(emitter, '\\') {
-				return false
-			}
-
-			var ok bool
-			switch v {
-			case 0x00:
-				ok = put(emitter, '0')
-			case 0x07:
-				ok = put(emitter, 'a')
-			case 0x08:
-				ok = put(emitter, 'b')
-			case 0x09:
-				ok = put(emitter, 't')
-			case 0x0A:
-				ok = put(emitter, 'n')
-			case 0x0b:
-				ok = put(emitter, 'v')
-			case 0x0c:
-				ok = put(emitter, 'f')
-			case 0x0d:
-				ok = put(emitter, 'r')
-			case 0x1b:
-				ok = put(emitter, 'e')
-			case 0x22:
-				ok = put(emitter, '"')
-			case 0x5c:
-				ok = put(emitter, '\\')
-			case 0x85:
-				ok = put(emitter, 'N')
-			case 0xA0:
-				ok = put(emitter, '_')
-			case 0x2028:
-				ok = put(emitter, 'L')
-			case 0x2029:
-				ok = put(emitter, 'P')
-			default:
-				if v <= 0xFF {
-					ok = put(emitter, 'x')
-					w = 2
-				} else if v <= 0xFFFF {
-					ok = put(emitter, 'u')
-					w = 4
-				} else {
-					ok = put(emitter, 'U')
-					w = 8
-				}
-				for k := (w - 1) * 4; ok && k >= 0; k -= 4 {
-					digit := byte((v >> uint(k)) & 0x0F)
-					if digit < 10 {
-						ok = put(emitter, digit+'0')
-					} else {
-						ok = put(emitter, digit+'A'-10)
-					}
-				}
-			}
-			if !ok {
-				return false
-			}
-			spaces = false
-		} else if is_space(value, i) {
-			if allow_breaks && !spaces && emitter.column > emitter.best_width && i > 0 && i < len(value)-1 {
-				if !yaml_emitter_write_indent(emitter) {
-					return false
-				}
-				if is_space(value, i+1) {
-					if !put(emitter, '\\') {
-						return false
-					}
-				}
-				i += width(value[i])
-			} else if !write(emitter, value, &i) {
-				return false
-			}
-			spaces = true
-		} else {
-			if !write(emitter, value, &i) {
-				return false
-			}
-			spaces = false
-		}
-	}
-	if !yaml_emitter_write_indicator(emitter, []byte{'"'}, false, false, false) {
-		return false
-	}
-	emitter.whitespace = false
-	emitter.indention = false
-	return true
-}
-
-func yaml_emitter_write_block_scalar_hints(emitter *yaml_emitter_t, value []byte) bool {
-	if is_space(value, 0) || is_break(value, 0) {
-		indent_hint := []byte{'0' + byte(emitter.best_indent)}
-		if !yaml_emitter_write_indicator(emitter, indent_hint, false, false, false) {
-			return false
-		}
-	}
-
-	emitter.open_ended = false
-
-	var chomp_hint [1]byte
-	if len(value) == 0 {
-		chomp_hint[0] = '-'
-	} else {
-		i := len(value) - 1
-		for value[i]&0xC0 == 0x80 {
-			i--
-		}
-		if !is_break(value, i) {
-			chomp_hint[0] = '-'
-		} else if i == 0 {
-			chomp_hint[0] = '+'
-			emitter.open_ended = true
-		} else {
-			i--
-			for value[i]&0xC0 == 0x80 {
-				i--
-			}
-			if is_break(value, i) {
-				chomp_hint[0] = '+'
-				emitter.open_ended = true
-			}
-		}
-	}
-	if chomp_hint[0] != 0 {
-		if !yaml_emitter_write_indicator(emitter, chomp_hint[:], false, false, false) {
-			return false
-		}
-	}
-	return true
-}
-
-func yaml_emitter_write_literal_scalar(emitter *yaml_emitter_t, value []byte) bool {
-	if !yaml_emitter_write_indicator(emitter, []byte{'|'}, true, false, false) {
-		return false
-	}
-	if !yaml_emitter_write_block_scalar_hints(emitter, value) {
-		return false
-	}
-	if !put_break(emitter) {
-		return false
-	}
-	emitter.indention = true
-	emitter.whitespace = true
-	breaks := true
-	for i := 0; i < len(value); {
-		if is_break(value, i) {
-			if !write_break(emitter, value, &i) {
-				return false
-			}
-			emitter.indention = true
-			breaks = true
-		} else {
-			if breaks {
-				if !yaml_emitter_write_indent(emitter) {
-					return false
-				}
-			}
-			if !write(emitter, value, &i) {
-				return false
-			}
-			emitter.indention = false
-			breaks = false
-		}
-	}
-
-	return true
-}
-
-func yaml_emitter_write_folded_scalar(emitter *yaml_emitter_t, value []byte) bool {
-	if !yaml_emitter_write_indicator(emitter, []byte{'>'}, true, false, false) {
-		return false
-	}
-	if !yaml_emitter_write_block_scalar_hints(emitter, value) {
-		return false
-	}
-
-	if !put_break(emitter) {
-		return false
-	}
-	emitter.indention = true
-	emitter.whitespace = true
-
-	breaks := true
-	leading_spaces := true
-	for i := 0; i < len(value); {
-		if is_break(value, i) {
-			if !breaks && !leading_spaces && value[i] == '\n' {
-				k := 0
-				for is_break(value, k) {
-					k += width(value[k])
-				}
-				if !is_blankz(value, k) {
-					if !put_break(emitter) {
-						return false
-					}
-				}
-			}
-			if !write_break(emitter, value, &i) {
-				return false
-			}
-			emitter.indention = true
-			breaks = true
-		} else {
-			if breaks {
-				if !yaml_emitter_write_indent(emitter) {
-					return false
-				}
-				leading_spaces = is_blank(value, i)
-			}
-			if !breaks && is_space(value, i) && !is_space(value, i+1) && emitter.column > emitter.best_width {
-				if !yaml_emitter_write_indent(emitter) {
-					return false
-				}
-				i += width(value[i])
-			} else {
-				if !write(emitter, value, &i) {
-					return false
-				}
-			}
-			emitter.indention = false
-			breaks = false
-		}
-	}
-	return true
-}
diff --git a/encode.go b/encode.go
deleted file mode 100644
index c700443..0000000
--- a/encode.go
+++ /dev/null
@@ -1,221 +0,0 @@
-package yaml
-
-import (
-	"reflect"
-	"sort"
-	"strconv"
-)
-
-type encoder struct {
-	emitter yaml_emitter_t
-	event   yaml_event_t
-	out     []byte
-	flow    bool
-}
-
-func newEncoder() (e *encoder) {
-	e = &encoder{}
-	e.must(yaml_emitter_initialize(&e.emitter))
-	yaml_emitter_set_output_string(&e.emitter, &e.out)
-	e.must(yaml_stream_start_event_initialize(&e.event, yaml_UTF8_ENCODING))
-	e.emit()
-	e.must(yaml_document_start_event_initialize(&e.event, nil, nil, true))
-	e.emit()
-	return e
-}
-
-func (e *encoder) finish() {
-	e.must(yaml_document_end_event_initialize(&e.event, true))
-	e.emit()
-	e.emitter.open_ended = false
-	e.must(yaml_stream_end_event_initialize(&e.event))
-	e.emit()
-}
-
-func (e *encoder) destroy() {
-	yaml_emitter_delete(&e.emitter)
-}
-
-func (e *encoder) emit() {
-	// This will internally delete the e.event value.
-	if !yaml_emitter_emit(&e.emitter, &e.event) && e.event.typ != yaml_DOCUMENT_END_EVENT && e.event.typ != yaml_STREAM_END_EVENT {
-		e.must(false)
-	}
-}
-
-func (e *encoder) must(ok bool) {
-	if !ok {
-		msg := e.emitter.problem
-		if msg == "" {
-			msg = "Unknown problem generating YAML content"
-		}
-		panic(msg)
-	}
-}
-
-func (e *encoder) marshal(tag string, in reflect.Value) {
-	var value interface{}
-	if getter, ok := in.Interface().(Getter); ok {
-		tag, value = getter.GetYAML()
-		if value == nil {
-			e.nilv()
-			return
-		}
-		in = reflect.ValueOf(value)
-	}
-	switch in.Kind() {
-	case reflect.Interface:
-		if in.IsNil() {
-			e.nilv()
-		} else {
-			e.marshal(tag, in.Elem())
-		}
-	case reflect.Map:
-		e.mapv(tag, in)
-	case reflect.Ptr:
-		if in.IsNil() {
-			e.nilv()
-		} else {
-			e.marshal(tag, in.Elem())
-		}
-	case reflect.Struct:
-		e.structv(tag, in)
-	case reflect.Slice:
-		e.slicev(tag, in)
-	case reflect.String:
-		e.stringv(tag, in)
-	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
-		e.intv(tag, in)
-	case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
-		e.uintv(tag, in)
-	case reflect.Float32, reflect.Float64:
-		e.floatv(tag, in)
-	case reflect.Bool:
-		e.boolv(tag, in)
-	default:
-		panic("Can't marshal type yet: " + in.Type().String())
-	}
-}
-
-func (e *encoder) mapv(tag string, in reflect.Value) {
-	e.mappingv(tag, func() {
-		keys := keyList(in.MapKeys())
-		sort.Sort(keys)
-		for _, k := range keys {
-			e.marshal("", k)
-			e.marshal("", in.MapIndex(k))
-		}
-	})
-}
-
-func (e *encoder) structv(tag string, in reflect.Value) {
-	sinfo, err := getStructInfo(in.Type())
-	if err != nil {
-		panic(err)
-	}
-	e.mappingv(tag, func() {
-		for _, info := range sinfo.FieldsList {
-			var value reflect.Value
-			if info.Inline == nil {
-				value = in.Field(info.Num)
-			} else {
-				value = in.FieldByIndex(info.Inline)
-			}
-			if info.OmitEmpty && isZero(value) {
-				continue
-			}
-			e.marshal("", reflect.ValueOf(info.Key))
-			e.flow = info.Flow
-			e.marshal("", value)
-		}
-	})
-}
-
-func (e *encoder) mappingv(tag string, f func()) {
-	implicit := tag == ""
-	style := yaml_BLOCK_MAPPING_STYLE
-	if e.flow {
-		e.flow = false
-		style = yaml_FLOW_MAPPING_STYLE
-	}
-	e.must(yaml_mapping_start_event_initialize(&e.event, nil, []byte(tag), implicit, style))
-	e.emit()
-	f()
-	e.must(yaml_mapping_end_event_initialize(&e.event))
-	e.emit()
-}
-
-func (e *encoder) slicev(tag string, in reflect.Value) {
-	implicit := tag == ""
-	style := yaml_BLOCK_SEQUENCE_STYLE
-	if e.flow {
-		e.flow = false
-		style = yaml_FLOW_SEQUENCE_STYLE
-	}
-	e.must(yaml_sequence_start_event_initialize(&e.event, nil, []byte(tag), implicit, style))
-	e.emit()
-	n := in.Len()
-	for i := 0; i < n; i++ {
-		e.marshal("", in.Index(i))
-	}
-	e.must(yaml_sequence_end_event_initialize(&e.event))
-	e.emit()
-}
-
-func (e *encoder) stringv(tag string, in reflect.Value) {
-	var style yaml_scalar_style_t
-	s := in.String()
-	if rtag, _ := resolve("", s); rtag != "!!str" {
-		style = yaml_DOUBLE_QUOTED_SCALAR_STYLE
-	} else {
-		style = yaml_PLAIN_SCALAR_STYLE
-	}
-	e.emitScalar(s, "", tag, style)
-}
-
-func (e *encoder) boolv(tag string, in reflect.Value) {
-	var s string
-	if in.Bool() {
-		s = "true"
-	} else {
-		s = "false"
-	}
-	e.emitScalar(s, "", tag, yaml_PLAIN_SCALAR_STYLE)
-}
-
-func (e *encoder) intv(tag string, in reflect.Value) {
-	s := strconv.FormatInt(in.Int(), 10)
-	e.emitScalar(s, "", tag, yaml_PLAIN_SCALAR_STYLE)
-}
-
-func (e *encoder) uintv(tag string, in reflect.Value) {
-	s := strconv.FormatUint(in.Uint(), 10)
-	e.emitScalar(s, "", tag, yaml_PLAIN_SCALAR_STYLE)
-}
-
-func (e *encoder) floatv(tag string, in reflect.Value) {
-	// FIXME: Handle 64 bits here.
-	s := strconv.FormatFloat(float64(in.Float()), 'g', -1, 32)
-	switch s {
-	case "+Inf":
-		s = ".inf"
-	case "-Inf":
-		s = "-.inf"
-	case "NaN":
-		s = ".nan"
-	}
-	e.emitScalar(s, "", tag, yaml_PLAIN_SCALAR_STYLE)
-}
-
-func (e *encoder) nilv() {
-	e.emitScalar("null", "", "", yaml_PLAIN_SCALAR_STYLE)
-}
-
-func (e *encoder) emitScalar(value, anchor, tag string, style yaml_scalar_style_t) {
-	implicit := tag == ""
-	if !implicit {
-		style = yaml_PLAIN_SCALAR_STYLE
-	}
-	e.must(yaml_scalar_event_initialize(&e.event, []byte(anchor), []byte(tag), []byte(value), implicit, implicit, style))
-	e.emit()
-}
diff --git a/encode_test.go b/encode_test.go
deleted file mode 100644
index 0ab65b9..0000000
--- a/encode_test.go
+++ /dev/null
@@ -1,379 +0,0 @@
-package yaml_test
-
-import (
-	"fmt"
-	. "launchpad.net/gocheck"
-	"gopkg.in/yaml.v1"
-	"math"
-	"strconv"
-	"strings"
-)
-
-var marshalIntTest = 123
-
-var marshalTests = []struct {
-	value interface{}
-	data  string
-}{
-	{
-		&struct{}{},
-		"{}\n",
-	}, {
-		map[string]string{"v": "hi"},
-		"v: hi\n",
-	}, {
-		map[string]interface{}{"v": "hi"},
-		"v: hi\n",
-	}, {
-		map[string]string{"v": "true"},
-		"v: \"true\"\n",
-	}, {
-		map[string]string{"v": "false"},
-		"v: \"false\"\n",
-	}, {
-		map[string]interface{}{"v": true},
-		"v: true\n",
-	}, {
-		map[string]interface{}{"v": false},
-		"v: false\n",
-	}, {
-		map[string]interface{}{"v": 10},
-		"v: 10\n",
-	}, {
-		map[string]interface{}{"v": -10},
-		"v: -10\n",
-	}, {
-		map[string]uint{"v": 42},
-		"v: 42\n",
-	}, {
-		map[string]interface{}{"v": int64(4294967296)},
-		"v: 4294967296\n",
-	}, {
-		map[string]int64{"v": int64(4294967296)},
-		"v: 4294967296\n",
-	}, {
-		map[string]uint64{"v": 4294967296},
-		"v: 4294967296\n",
-	}, {
-		map[string]interface{}{"v": "10"},
-		"v: \"10\"\n",
-	}, {
-		map[string]interface{}{"v": 0.1},
-		"v: 0.1\n",
-	}, {
-		map[string]interface{}{"v": float64(0.1)},
-		"v: 0.1\n",
-	}, {
-		map[string]interface{}{"v": -0.1},
-		"v: -0.1\n",
-	}, {
-		map[string]interface{}{"v": math.Inf(+1)},
-		"v: .inf\n",
-	}, {
-		map[string]interface{}{"v": math.Inf(-1)},
-		"v: -.inf\n",
-	}, {
-		map[string]interface{}{"v": math.NaN()},
-		"v: .nan\n",
-	}, {
-		map[string]interface{}{"v": nil},
-		"v: null\n",
-	}, {
-		map[string]interface{}{"v": ""},
-		"v: \"\"\n",
-	}, {
-		map[string][]string{"v": []string{"A", "B"}},
-		"v:\n- A\n- B\n",
-	}, {
-		map[string][]string{"v": []string{"A", "B\nC"}},
-		"v:\n- A\n- 'B\n\n  C'\n",
-	}, {
-		map[string][]interface{}{"v": []interface{}{"A", 1, map[string][]int{"B": []int{2, 3}}}},
-		"v:\n- A\n- 1\n- B:\n  - 2\n  - 3\n",
-	}, {
-		map[string]interface{}{"a": map[interface{}]interface{}{"b": "c"}},
-		"a:\n  b: c\n",
-	}, {
-		map[string]interface{}{"a": "-"},
-		"a: '-'\n",
-	},
-
-	// Simple values.
-	{
-		&marshalIntTest,
-		"123\n",
-	},
-
-	// Structures
-	{
-		&struct{ Hello string }{"world"},
-		"hello: world\n",
-	}, {
-		&struct {
-			A struct {
-				B string
-			}
-		}{struct{ B string }{"c"}},
-		"a:\n  b: c\n",
-	}, {
-		&struct {
-			A *struct {
-				B string
-			}
-		}{&struct{ B string }{"c"}},
-		"a:\n  b: c\n",
-	}, {
-		&struct {
-			A *struct {
-				B string
-			}
-		}{},
-		"a: null\n",
-	}, {
-		&struct{ A int }{1},
-		"a: 1\n",
-	}, {
-		&struct{ A []int }{[]int{1, 2}},
-		"a:\n- 1\n- 2\n",
-	}, {
-		&struct {
-			B int "a"
-		}{1},
-		"a: 1\n",
-	}, {
-		&struct{ A bool }{true},
-		"a: true\n",
-	},
-
-	// Conditional flag
-	{
-		&struct {
-			A int "a,omitempty"
-			B int "b,omitempty"
-		}{1, 0},
-		"a: 1\n",
-	}, {
-		&struct {
-			A int "a,omitempty"
-			B int "b,omitempty"
-		}{0, 0},
-		"{}\n",
-	}, {
-		&struct {
-			A *struct{ X int } "a,omitempty"
-			B int              "b,omitempty"
-		}{nil, 0},
-		"{}\n",
-	},
-
-	// Flow flag
-	{
-		&struct {
-			A []int "a,flow"
-		}{[]int{1, 2}},
-		"a: [1, 2]\n",
-	}, {
-		&struct {
-			A map[string]string "a,flow"
-		}{map[string]string{"b": "c", "d": "e"}},
-		"a: {b: c, d: e}\n",
-	}, {
-		&struct {
-			A struct {
-				B, D string
-			} "a,flow"
-		}{struct{ B, D string }{"c", "e"}},
-		"a: {b: c, d: e}\n",
-	},
-
-	// Unexported field
-	{
-		&struct {
-			u int
-			A int
-		}{0, 1},
-		"a: 1\n",
-	},
-
-	// Ignored field
-	{
-		&struct {
-			A int
-			B int "-"
-		}{1, 2},
-		"a: 1\n",
-	},
-
-	// Struct inlining
-	{
-		&struct {
-			A int
-			C inlineB `yaml:",inline"`
-		}{1, inlineB{2, inlineC{3}}},
-		"a: 1\nb: 2\nc: 3\n",
-	},
-}
-
-func (s *S) TestMarshal(c *C) {
-	for _, item := range marshalTests {
-		data, err := yaml.Marshal(item.value)
-		c.Assert(err, IsNil)
-		c.Assert(string(data), Equals, item.data)
-	}
-}
-
-var marshalErrorTests = []struct {
-	value interface{}
-	error string
-}{
-	{
-		&struct {
-			B       int
-			inlineB ",inline"
-		}{1, inlineB{2, inlineC{3}}},
-		`Duplicated key 'b' in struct struct \{ B int; .*`,
-	},
-}
-
-func (s *S) TestMarshalErrors(c *C) {
-	for _, item := range marshalErrorTests {
-		_, err := yaml.Marshal(item.value)
-		c.Assert(err, ErrorMatches, item.error)
-	}
-}
-
-var marshalTaggedIfaceTest interface{} = &struct{ A string }{"B"}
-
-var getterTests = []struct {
-	data, tag string
-	value     interface{}
-}{
-	{"_:\n  hi: there\n", "", map[interface{}]interface{}{"hi": "there"}},
-	{"_:\n- 1\n- A\n", "", []interface{}{1, "A"}},
-	{"_: 10\n", "", 10},
-	{"_: null\n", "", nil},
-	{"_: !foo BAR!\n", "!foo", "BAR!"},
-	{"_: !foo 1\n", "!foo", "1"},
-	{"_: !foo '\"1\"'\n", "!foo", "\"1\""},
-	{"_: !foo 1.1\n", "!foo", 1.1},
-	{"_: !foo 1\n", "!foo", 1},
-	{"_: !foo 1\n", "!foo", uint(1)},
-	{"_: !foo true\n", "!foo", true},
-	{"_: !foo\n- A\n- B\n", "!foo", []string{"A", "B"}},
-	{"_: !foo\n  A: B\n", "!foo", map[string]string{"A": "B"}},
-	{"_: !foo\n  a: B\n", "!foo", &marshalTaggedIfaceTest},
-}
-
-func (s *S) TestMarshalTypeCache(c *C) {
-	var data []byte
-	var err error
-	func() {
-		type T struct{ A int }
-		data, err = yaml.Marshal(&T{})
-		c.Assert(err, IsNil)
-	}()
-	func() {
-		type T struct{ B int }
-		data, err = yaml.Marshal(&T{})
-		c.Assert(err, IsNil)
-	}()
-	c.Assert(string(data), Equals, "b: 0\n")
-}
-
-type typeWithGetter struct {
-	tag   string
-	value interface{}
-}
-
-func (o typeWithGetter) GetYAML() (tag string, value interface{}) {
-	return o.tag, o.value
-}
-
-type typeWithGetterField struct {
-	Field typeWithGetter "_"
-}
-
-func (s *S) TestMashalWithGetter(c *C) {
-	for _, item := range getterTests {
-		obj := &typeWithGetterField{}
-		obj.Field.tag = item.tag
-		obj.Field.value = item.value
-		data, err := yaml.Marshal(obj)
-		c.Assert(err, IsNil)
-		c.Assert(string(data), Equals, string(item.data))
-	}
-}
-
-func (s *S) TestUnmarshalWholeDocumentWithGetter(c *C) {
-	obj := &typeWithGetter{}
-	obj.tag = ""
-	obj.value = map[string]string{"hello": "world!"}
-	data, err := yaml.Marshal(obj)
-	c.Assert(err, IsNil)
-	c.Assert(string(data), Equals, "hello: world!\n")
-}
-
-func (s *S) TestSortedOutput(c *C) {
-	order := []interface{}{
-		false,
-		true,
-		1,
-		uint(1),
-		1.0,
-		1.1,
-		1.2,
-		2,
-		uint(2),
-		2.0,
-		2.1,
-		"",
-		".1",
-		".2",
-		".a",
-		"1",
-		"2",
-		"a!10",
-		"a/2",
-		"a/10",
-		"a~10",
-		"ab/1",
-		"b/1",
-		"b/01",
-		"b/2",
-		"b/02",
-		"b/3",
-		"b/03",
-		"b1",
-		"b01",
-		"b3",
-		"c2.10",
-		"c10.2",
-		"d1",
-		"d12",
-		"d12a",
-	}
-	m := make(map[interface{}]int)
-	for _, k := range order {
-		m[k] = 1
-	}
-	data, err := yaml.Marshal(m)
-	c.Assert(err, IsNil)
-	out := "\n" + string(data)
-	last := 0
-	for i, k := range order {
-		repr := fmt.Sprint(k)
-		if s, ok := k.(string); ok {
-			if _, err = strconv.ParseFloat(repr, 32); s == "" || err == nil {
-				repr = `"` + repr + `"`
-			}
-		}
-		index := strings.Index(out, "\n"+repr+":")
-		if index == -1 {
-			c.Fatalf("%#v is not in the output: %#v", k, out)
-		}
-		if index < last {
-			c.Fatalf("%#v was generated before %#v: %q", k, order[i-1], out)
-		}
-		last = index
-	}
-}
diff --git a/error.go b/error.go
new file mode 100644
index 0000000..6be5c58
--- /dev/null
+++ b/error.go
@@ -0,0 +1,5 @@
+package error
+
+func error() {
+	`ERROR: the correct import path is gopkg.in/yaml.v1 ... `
+}
diff --git a/parserc.go b/parserc.go
deleted file mode 100644
index 0a7037a..0000000
--- a/parserc.go
+++ /dev/null
@@ -1,1096 +0,0 @@
-package yaml
-
-import (
-	"bytes"
-)
-
-// The parser implements the following grammar:
-//
-// stream               ::= STREAM-START implicit_document? explicit_document* STREAM-END
-// implicit_document    ::= block_node DOCUMENT-END*
-// explicit_document    ::= DIRECTIVE* DOCUMENT-START block_node? DOCUMENT-END*
-// block_node_or_indentless_sequence    ::=
-//                          ALIAS
-//                          | properties (block_content | indentless_block_sequence)?
-//                          | block_content
-//                          | indentless_block_sequence
-// block_node           ::= ALIAS
-//                          | properties block_content?
-//                          | block_content
-// flow_node            ::= ALIAS
-//                          | properties flow_content?
-//                          | flow_content
-// properties           ::= TAG ANCHOR? | ANCHOR TAG?
-// block_content        ::= block_collection | flow_collection | SCALAR
-// flow_content         ::= flow_collection | SCALAR
-// block_collection     ::= block_sequence | block_mapping
-// flow_collection      ::= flow_sequence | flow_mapping
-// block_sequence       ::= BLOCK-SEQUENCE-START (BLOCK-ENTRY block_node?)* BLOCK-END
-// indentless_sequence  ::= (BLOCK-ENTRY block_node?)+
-// block_mapping        ::= BLOCK-MAPPING_START
-//                          ((KEY block_node_or_indentless_sequence?)?
-//                          (VALUE block_node_or_indentless_sequence?)?)*
-//                          BLOCK-END
-// flow_sequence        ::= FLOW-SEQUENCE-START
-//                          (flow_sequence_entry FLOW-ENTRY)*
-//                          flow_sequence_entry?
-//                          FLOW-SEQUENCE-END
-// flow_sequence_entry  ::= flow_node | KEY flow_node? (VALUE flow_node?)?
-// flow_mapping         ::= FLOW-MAPPING-START
-//                          (flow_mapping_entry FLOW-ENTRY)*
-//                          flow_mapping_entry?
-//                          FLOW-MAPPING-END
-// flow_mapping_entry   ::= flow_node | KEY flow_node? (VALUE flow_node?)?
-
-// Peek the next token in the token queue.
-func peek_token(parser *yaml_parser_t) *yaml_token_t {
-	if parser.token_available || yaml_parser_fetch_more_tokens(parser) {
-		return &parser.tokens[parser.tokens_head]
-	}
-	return nil
-}
-
-// Remove the next token from the queue (must be called after peek_token).
-func skip_token(parser *yaml_parser_t) {
-	parser.token_available = false
-	parser.tokens_parsed++
-	parser.stream_end_produced = parser.tokens[parser.tokens_head].typ == yaml_STREAM_END_TOKEN
-	parser.tokens_head++
-}
-
-// Get the next event.
-func yaml_parser_parse(parser *yaml_parser_t, event *yaml_event_t) bool {
-	// Erase the event object.
-	*event = yaml_event_t{}
-
-	// No events after the end of the stream or error.
-	if parser.stream_end_produced || parser.error != yaml_NO_ERROR || parser.state == yaml_PARSE_END_STATE {
-		return true
-	}
-
-	// Generate the next event.
-	return yaml_parser_state_machine(parser, event)
-}
-
-// Set parser error.
-func yaml_parser_set_parser_error(parser *yaml_parser_t, problem string, problem_mark yaml_mark_t) bool {
-	parser.error = yaml_PARSER_ERROR
-	parser.problem = problem
-	parser.problem_mark = problem_mark
-	return false
-}
-
-func yaml_parser_set_parser_error_context(parser *yaml_parser_t, context string, context_mark yaml_mark_t, problem string, problem_mark yaml_mark_t) bool {
-	parser.error = yaml_PARSER_ERROR
-	parser.context = context
-	parser.context_mark = context_mark
-	parser.problem = problem
-	parser.problem_mark = problem_mark
-	return false
-}
-
-// State dispatcher.
-func yaml_parser_state_machine(parser *yaml_parser_t, event *yaml_event_t) bool {
-	//trace("yaml_parser_state_machine", "state:", parser.state.String())
-
-	switch parser.state {
-	case yaml_PARSE_STREAM_START_STATE:
-		return yaml_parser_parse_stream_start(parser, event)
-
-	case yaml_PARSE_IMPLICIT_DOCUMENT_START_STATE:
-		return yaml_parser_parse_document_start(parser, event, true)
-
-	case yaml_PARSE_DOCUMENT_START_STATE:
-		return yaml_parser_parse_document_start(parser, event, false)
-
-	case yaml_PARSE_DOCUMENT_CONTENT_STATE:
-		return yaml_parser_parse_document_content(parser, event)
-
-	case yaml_PARSE_DOCUMENT_END_STATE:
-		return yaml_parser_parse_document_end(parser, event)
-
-	case yaml_PARSE_BLOCK_NODE_STATE:
-		return yaml_parser_parse_node(parser, event, true, false)
-
-	case yaml_PARSE_BLOCK_NODE_OR_INDENTLESS_SEQUENCE_STATE:
-		return yaml_parser_parse_node(parser, event, true, true)
-
-	case yaml_PARSE_FLOW_NODE_STATE:
-		return yaml_parser_parse_node(parser, event, false, false)
-
-	case yaml_PARSE_BLOCK_SEQUENCE_FIRST_ENTRY_STATE:
-		return yaml_parser_parse_block_sequence_entry(parser, event, true)
-
-	case yaml_PARSE_BLOCK_SEQUENCE_ENTRY_STATE:
-		return yaml_parser_parse_block_sequence_entry(parser, event, false)
-
-	case yaml_PARSE_INDENTLESS_SEQUENCE_ENTRY_STATE:
-		return yaml_parser_parse_indentless_sequence_entry(parser, event)
-
-	case yaml_PARSE_BLOCK_MAPPING_FIRST_KEY_STATE:
-		return yaml_parser_parse_block_mapping_key(parser, event, true)
-
-	case yaml_PARSE_BLOCK_MAPPING_KEY_STATE:
-		return yaml_parser_parse_block_mapping_key(parser, event, false)
-
-	case yaml_PARSE_BLOCK_MAPPING_VALUE_STATE:
-		return yaml_parser_parse_block_mapping_value(parser, event)
-
-	case yaml_PARSE_FLOW_SEQUENCE_FIRST_ENTRY_STATE:
-		return yaml_parser_parse_flow_sequence_entry(parser, event, true)
-
-	case yaml_PARSE_FLOW_SEQUENCE_ENTRY_STATE:
-		return yaml_parser_parse_flow_sequence_entry(parser, event, false)
-
-	case yaml_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_KEY_STATE:
-		return yaml_parser_parse_flow_sequence_entry_mapping_key(parser, event)
-
-	case yaml_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_VALUE_STATE:
-		return yaml_parser_parse_flow_sequence_entry_mapping_value(parser, event)
-
-	case yaml_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_END_STATE:
-		return yaml_parser_parse_flow_sequence_entry_mapping_end(parser, event)
-
-	case yaml_PARSE_FLOW_MAPPING_FIRST_KEY_STATE:
-		return yaml_parser_parse_flow_mapping_key(parser, event, true)
-
-	case yaml_PARSE_FLOW_MAPPING_KEY_STATE:
-		return yaml_parser_parse_flow_mapping_key(parser, event, false)
-
-	case yaml_PARSE_FLOW_MAPPING_VALUE_STATE:
-		return yaml_parser_parse_flow_mapping_value(parser, event, false)
-
-	case yaml_PARSE_FLOW_MAPPING_EMPTY_VALUE_STATE:
-		return yaml_parser_parse_flow_mapping_value(parser, event, true)
-
-	default:
-		panic("invalid parser state")
-	}
-	return false
-}
-
-// Parse the production:
-// stream   ::= STREAM-START implicit_document? explicit_document* STREAM-END
-//              ************
-func yaml_parser_parse_stream_start(parser *yaml_parser_t, event *yaml_event_t) bool {
-	token := peek_token(parser)
-	if token == nil {
-		return false
-	}
-	if token.typ != yaml_STREAM_START_TOKEN {
-		return yaml_parser_set_parser_error(parser, "did not find expected <stream-start>", token.start_mark)
-	}
-	parser.state = yaml_PARSE_IMPLICIT_DOCUMENT_START_STATE
-	*event = yaml_event_t{
-		typ:        yaml_STREAM_START_EVENT,
-		start_mark: token.start_mark,
-		end_mark:   token.end_mark,
-		encoding:   token.encoding,
-	}
-	skip_token(parser)
-	return true
-}
-
-// Parse the productions:
-// implicit_document    ::= block_node DOCUMENT-END*
-//                          *
-// explicit_document    ::= DIRECTIVE* DOCUMENT-START block_node? DOCUMENT-END*
-//                          *************************
-func yaml_parser_parse_document_start(parser *yaml_parser_t, event *yaml_event_t, implicit bool) bool {
-
-	token := peek_token(parser)
-	if token == nil {
-		return false
-	}
-
-	// Parse extra document end indicators.
-	if !implicit {
-		for token.typ == yaml_DOCUMENT_END_TOKEN {
-			skip_token(parser)
-			token = peek_token(parser)
-			if token == nil {
-				return false
-			}
-		}
-	}
-
-	if implicit && token.typ != yaml_VERSION_DIRECTIVE_TOKEN &&
-		token.typ != yaml_TAG_DIRECTIVE_TOKEN &&
-		token.typ != yaml_DOCUMENT_START_TOKEN &&
-		token.typ != yaml_STREAM_END_TOKEN {
-		// Parse an implicit document.
-		if !yaml_parser_process_directives(parser, nil, nil) {
-			return false
-		}
-		parser.states = append(parser.states, yaml_PARSE_DOCUMENT_END_STATE)
-		parser.state = yaml_PARSE_BLOCK_NODE_STATE
-
-		*event = yaml_event_t{
-			typ:        yaml_DOCUMENT_START_EVENT,
-			start_mark: token.start_mark,
-			end_mark:   token.end_mark,
-		}
-
-	} else if token.typ != yaml_STREAM_END_TOKEN {
-		// Parse an explicit document.
-		var version_directive *yaml_version_directive_t
-		var tag_directives []yaml_tag_directive_t
-		start_mark := token.start_mark
-		if !yaml_parser_process_directives(parser, &version_directive, &tag_directives) {
-			return false
-		}
-		token = peek_token(parser)
-		if token == nil {
-			return false
-		}
-		if token.typ != yaml_DOCUMENT_START_TOKEN {
-			yaml_parser_set_parser_error(parser,
-				"did not find expected <document start>", token.start_mark)
-			return false
-		}
-		parser.states = append(parser.states, yaml_PARSE_DOCUMENT_END_STATE)
-		parser.state = yaml_PARSE_DOCUMENT_CONTENT_STATE
-		end_mark := token.end_mark
-
-		*event = yaml_event_t{
-			typ:               yaml_DOCUMENT_START_EVENT,
-			start_mark:        start_mark,
-			end_mark:          end_mark,
-			version_directive: version_directive,
-			tag_directives:    tag_directives,
-			implicit:          false,
-		}
-		skip_token(parser)
-
-	} else {
-		// Parse the stream end.
-		parser.state = yaml_PARSE_END_STATE
-		*event = yaml_event_t{
-			typ:        yaml_STREAM_END_EVENT,
-			start_mark: token.start_mark,
-			end_mark:   token.end_mark,
-		}
-		skip_token(parser)
-	}
-
-	return true
-}
-
-// Parse the productions:
-// explicit_document    ::= DIRECTIVE* DOCUMENT-START block_node? DOCUMENT-END*
-//                                                    ***********
-//
-func yaml_parser_parse_document_content(parser *yaml_parser_t, event *yaml_event_t) bool {
-	token := peek_token(parser)
-	if token == nil {
-		return false
-	}
-	if token.typ == yaml_VERSION_DIRECTIVE_TOKEN ||
-		token.typ == yaml_TAG_DIRECTIVE_TOKEN ||
-		token.typ == yaml_DOCUMENT_START_TOKEN ||
-		token.typ == yaml_DOCUMENT_END_TOKEN ||
-		token.typ == yaml_STREAM_END_TOKEN {
-		parser.state = parser.states[len(parser.states)-1]
-		parser.states = parser.states[:len(parser.states)-1]
-		return yaml_parser_process_empty_scalar(parser, event,
-			token.start_mark)
-	}
-	return yaml_parser_parse_node(parser, event, true, false)
-}
-
-// Parse the productions:
-// implicit_document    ::= block_node DOCUMENT-END*
-//                                     *************
-// explicit_document    ::= DIRECTIVE* DOCUMENT-START block_node? DOCUMENT-END*
-//
-func yaml_parser_parse_document_end(parser *yaml_parser_t, event *yaml_event_t) bool {
-	token := peek_token(parser)
-	if token == nil {
-		return false
-	}
-
-	start_mark := token.start_mark
-	end_mark := token.start_mark
-
-	implicit := true
-	if token.typ == yaml_DOCUMENT_END_TOKEN {
-		end_mark = token.end_mark
-		skip_token(parser)
-		implicit = false
-	}
-
-	parser.tag_directives = parser.tag_directives[:0]
-
-	parser.state = yaml_PARSE_DOCUMENT_START_STATE
-	*event = yaml_event_t{
-		typ:        yaml_DOCUMENT_END_EVENT,
-		start_mark: start_mark,
-		end_mark:   end_mark,
-		implicit:   implicit,
-	}
-	return true
-}
-
-// Parse the productions:
-// block_node_or_indentless_sequence    ::=
-//                          ALIAS
-//                          *****
-//                          | properties (block_content | indentless_block_sequence)?
-//                            **********  *
-//                          | block_content | indentless_block_sequence
-//                            *
-// block_node           ::= ALIAS
-//                          *****
-//                          | properties block_content?
-//                            ********** *
-//                          | block_content
-//                            *
-// flow_node            ::= ALIAS
-//                          *****
-//                          | properties flow_content?
-//                            ********** *
-//                          | flow_content
-//                            *
-// properties           ::= TAG ANCHOR? | ANCHOR TAG?
-//                          *************************
-// block_content        ::= block_collection | flow_collection | SCALAR
-//                                                               ******
-// flow_content         ::= flow_collection | SCALAR
-//                                            ******
-func yaml_parser_parse_node(parser *yaml_parser_t, event *yaml_event_t, block, indentless_sequence bool) bool {
-	//defer trace("yaml_parser_parse_node", "block:", block, "indentless_sequence:", indentless_sequence)()
-
-	token := peek_token(parser)
-	if token == nil {
-		return false
-	}
-
-	if token.typ == yaml_ALIAS_TOKEN {
-		parser.state = parser.states[len(parser.states)-1]
-		parser.states = parser.states[:len(parser.states)-1]
-		*event = yaml_event_t{
-			typ:        yaml_ALIAS_EVENT,
-			start_mark: token.start_mark,
-			end_mark:   token.end_mark,
-			anchor:     token.value,
-		}
-		skip_token(parser)
-		return true
-	}
-
-	start_mark := token.start_mark
-	end_mark := token.start_mark
-
-	var tag_token bool
-	var tag_handle, tag_suffix, anchor []byte
-	var tag_mark yaml_mark_t
-	if token.typ == yaml_ANCHOR_TOKEN {
-		anchor = token.value
-		start_mark = token.start_mark
-		end_mark = token.end_mark
-		skip_token(parser)
-		token = peek_token(parser)
-		if token == nil {
-			return false
-		}
-		if token.typ == yaml_TAG_TOKEN {
-			tag_token = true
-			tag_handle = token.value
-			tag_suffix = token.suffix
-			tag_mark = token.start_mark
-			end_mark = token.end_mark
-			skip_token(parser)
-			token = peek_token(parser)
-			if token == nil {
-				return false
-			}
-		}
-	} else if token.typ == yaml_TAG_TOKEN {
-		tag_token = true
-		tag_handle = token.value
-		tag_suffix = token.suffix
-		start_mark = token.start_mark
-		tag_mark = token.start_mark
-		end_mark = token.end_mark
-		skip_token(parser)
-		token = peek_token(parser)
-		if token == nil {
-			return false
-		}
-		if token.typ == yaml_ANCHOR_TOKEN {
-			anchor = token.value
-			end_mark = token.end_mark
-			skip_token(parser)
-			token = peek_token(parser)
-			if token == nil {
-				return false
-			}
-		}
-	}
-
-	var tag []byte
-	if tag_token {
-		if len(tag_handle) == 0 {
-			tag = tag_suffix
-			tag_suffix = nil
-		} else {
-			for i := range parser.tag_directives {
-				if bytes.Equal(parser.tag_directives[i].handle, tag_handle) {
-					tag = append([]byte(nil), parser.tag_directives[i].prefix...)
-					tag = append(tag, tag_suffix...)
-					break
-				}
-			}
-			if len(tag) == 0 {
-				yaml_parser_set_parser_error_context(parser,
-					"while parsing a node", start_mark,
-					"found undefined tag handle", tag_mark)
-				return false
-			}
-		}
-	}
-
-	implicit := len(tag) == 0
-	if indentless_sequence && token.typ == yaml_BLOCK_ENTRY_TOKEN {
-		end_mark = token.end_mark
-		parser.state = yaml_PARSE_INDENTLESS_SEQUENCE_ENTRY_STATE
-		*event = yaml_event_t{
-			typ:        yaml_SEQUENCE_START_EVENT,
-			start_mark: start_mark,
-			end_mark:   end_mark,
-			anchor:     anchor,
-			tag:        tag,
-			implicit:   implicit,
-			style:      yaml_style_t(yaml_BLOCK_SEQUENCE_STYLE),
-		}
-		return true
-	}
-	if token.typ == yaml_SCALAR_TOKEN {
-		var plain_implicit, quoted_implicit bool
-		end_mark = token.end_mark
-		if (len(tag) == 0 && token.style == yaml_PLAIN_SCALAR_STYLE) || (len(tag) == 1 && tag[0] == '!') {
-			plain_implicit = true
-		} else if len(tag) == 0 {
-			quoted_implicit = true
-		}
-		parser.state = parser.states[len(parser.states)-1]
-		parser.states = parser.states[:len(parser.states)-1]
-
-		*event = yaml_event_t{
-			typ:             yaml_SCALAR_EVENT,
-			start_mark:      start_mark,
-			end_mark:        end_mark,
-			anchor:          anchor,
-			tag:             tag,
-			value:           token.value,
-			implicit:        plain_implicit,
-			quoted_implicit: quoted_implicit,
-			style:           yaml_style_t(token.style),
-		}
-		skip_token(parser)
-		return true
-	}
-	if token.typ == yaml_FLOW_SEQUENCE_START_TOKEN {
-		// [Go] Some of the events below can be merged as they differ only on style.
-		end_mark = token.end_mark
-		parser.state = yaml_PARSE_FLOW_SEQUENCE_FIRST_ENTRY_STATE
-		*event = yaml_event_t{
-			typ:        yaml_SEQUENCE_START_EVENT,
-			start_mark: start_mark,
-			end_mark:   end_mark,
-			anchor:     anchor,
-			tag:        tag,
-			implicit:   implicit,
-			style:      yaml_style_t(yaml_FLOW_SEQUENCE_STYLE),
-		}
-		return true
-	}
-	if token.typ == yaml_FLOW_MAPPING_START_TOKEN {
-		end_mark = token.end_mark
-		parser.state = yaml_PARSE_FLOW_MAPPING_FIRST_KEY_STATE
-		*event = yaml_event_t{
-			typ:        yaml_MAPPING_START_EVENT,
-			start_mark: start_mark,
-			end_mark:   end_mark,
-			anchor:     anchor,
-			tag:        tag,
-			implicit:   implicit,
-			style:      yaml_style_t(yaml_FLOW_MAPPING_STYLE),
-		}
-		return true
-	}
-	if block && token.typ == yaml_BLOCK_SEQUENCE_START_TOKEN {
-		end_mark = token.end_mark
-		parser.state = yaml_PARSE_BLOCK_SEQUENCE_FIRST_ENTRY_STATE
-		*event = yaml_event_t{
-			typ:        yaml_SEQUENCE_START_EVENT,
-			start_mark: start_mark,
-			end_mark:   end_mark,
-			anchor:     anchor,
-			tag:        tag,
-			implicit:   implicit,
-			style:      yaml_style_t(yaml_BLOCK_SEQUENCE_STYLE),
-		}
-		return true
-	}
-	if block && token.typ == yaml_BLOCK_MAPPING_START_TOKEN {
-		end_mark = token.end_mark
-		parser.state = yaml_PARSE_BLOCK_MAPPING_FIRST_KEY_STATE
-		*event = yaml_event_t{
-			typ:        yaml_MAPPING_START_EVENT,
-			start_mark: start_mark,
-			end_mark:   end_mark,
-			anchor:     anchor,
-			tag:        tag,
-			implicit:   implicit,
-			style:      yaml_style_t(yaml_BLOCK_MAPPING_STYLE),
-		}
-		return true
-	}
-	if len(anchor) > 0 || len(tag) > 0 {
-		parser.state = parser.states[len(parser.states)-1]
-		parser.states = parser.states[:len(parser.states)-1]
-
-		*event = yaml_event_t{
-			typ:             yaml_SCALAR_EVENT,
-			start_mark:      start_mark,
-			end_mark:        end_mark,
-			anchor:          anchor,
-			tag:             tag,
-			implicit:        implicit,
-			quoted_implicit: false,
-			style:           yaml_style_t(yaml_PLAIN_SCALAR_STYLE),
-		}
-		return true
-	}
-
-	context := "while parsing a flow node"
-	if block {
-		context = "while parsing a block node"
-	}
-	yaml_parser_set_parser_error_context(parser, context, start_mark,
-		"did not find expected node content", token.start_mark)
-	return false
-}
-
-// Parse the productions:
-// block_sequence ::= BLOCK-SEQUENCE-START (BLOCK-ENTRY block_node?)* BLOCK-END
-//                    ********************  *********** *             *********
-//
-func yaml_parser_parse_block_sequence_entry(parser *yaml_parser_t, event *yaml_event_t, first bool) bool {
-	if first {
-		token := peek_token(parser)
-		parser.marks = append(parser.marks, token.start_mark)
-		skip_token(parser)
-	}
-
-	token := peek_token(parser)
-	if token == nil {
-		return false
-	}
-
-	if token.typ == yaml_BLOCK_ENTRY_TOKEN {
-		mark := token.end_mark
-		skip_token(parser)
-		token = peek_token(parser)
-		if token == nil {
-			return false
-		}
-		if token.typ != yaml_BLOCK_ENTRY_TOKEN && token.typ != yaml_BLOCK_END_TOKEN {
-			parser.states = append(parser.states, yaml_PARSE_BLOCK_SEQUENCE_ENTRY_STATE)
-			return yaml_parser_parse_node(parser, event, true, false)
-		} else {
-			parser.state = yaml_PARSE_BLOCK_SEQUENCE_ENTRY_STATE
-			return yaml_parser_process_empty_scalar(parser, event, mark)
-		}
-	}
-	if token.typ == yaml_BLOCK_END_TOKEN {
-		parser.state = parser.states[len(parser.states)-1]
-		parser.states = parser.states[:len(parser.states)-1]
-		parser.marks = parser.marks[:len(parser.marks)-1]
-
-		*event = yaml_event_t{
-			typ:        yaml_SEQUENCE_END_EVENT,
-			start_mark: token.start_mark,
-			end_mark:   token.end_mark,
-		}
-
-		skip_token(parser)
-		return true
-	}
-
-	context_mark := parser.marks[len(parser.marks)-1]
-	parser.marks = parser.marks[:len(parser.marks)-1]
-	return yaml_parser_set_parser_error_context(parser,
-		"while parsing a block collection", context_mark,
-		"did not find expected '-' indicator", token.start_mark)
-}
-
-// Parse the productions:
-// indentless_sequence  ::= (BLOCK-ENTRY block_node?)+
-//                           *********** *
-func yaml_parser_parse_indentless_sequence_entry(parser *yaml_parser_t, event *yaml_event_t) bool {
-	token := peek_token(parser)
-	if token == nil {
-		return false
-	}
-
-	if token.typ == yaml_BLOCK_ENTRY_TOKEN {
-		mark := token.end_mark
-		skip_token(parser)
-		token = peek_token(parser)
-		if token == nil {
-			return false
-		}
-		if token.typ != yaml_BLOCK_ENTRY_TOKEN &&
-			token.typ != yaml_KEY_TOKEN &&
-			token.typ != yaml_VALUE_TOKEN &&
-			token.typ != yaml_BLOCK_END_TOKEN {
-			parser.states = append(parser.states, yaml_PARSE_INDENTLESS_SEQUENCE_ENTRY_STATE)
-			return yaml_parser_parse_node(parser, event, true, false)
-		}
-		parser.state = yaml_PARSE_INDENTLESS_SEQUENCE_ENTRY_STATE
-		return yaml_parser_process_empty_scalar(parser, event, mark)
-	}
-	parser.state = parser.states[len(parser.states)-1]
-	parser.states = parser.states[:len(parser.states)-1]
-
-	*event = yaml_event_t{
-		typ:        yaml_SEQUENCE_END_EVENT,
-		start_mark: token.start_mark,
-		end_mark:   token.start_mark, // [Go] Shouldn't this be token.end_mark?
-	}
-	return true
-}
-
-// Parse the productions:
-// block_mapping        ::= BLOCK-MAPPING_START
-//                          *******************
-//                          ((KEY block_node_or_indentless_sequence?)?
-//                            *** *
-//                          (VALUE block_node_or_indentless_sequence?)?)*
-//
-//                          BLOCK-END
-//                          *********
-//
-func yaml_parser_parse_block_mapping_key(parser *yaml_parser_t, event *yaml_event_t, first bool) bool {
-	if first {
-		token := peek_token(parser)
-		parser.marks = append(parser.marks, token.start_mark)
-		skip_token(parser)
-	}
-
-	token := peek_token(parser)
-	if token == nil {
-		return false
-	}
-
-	if token.typ == yaml_KEY_TOKEN {
-		mark := token.end_mark
-		skip_token(parser)
-		token = peek_token(parser)
-		if token == nil {
-			return false
-		}
-		if token.typ != yaml_KEY_TOKEN &&
-			token.typ != yaml_VALUE_TOKEN &&
-			token.typ != yaml_BLOCK_END_TOKEN {
-			parser.states = append(parser.states, yaml_PARSE_BLOCK_MAPPING_VALUE_STATE)
-			return yaml_parser_parse_node(parser, event, true, true)
-		} else {
-			parser.state = yaml_PARSE_BLOCK_MAPPING_VALUE_STATE
-			return yaml_parser_process_empty_scalar(parser, event, mark)
-		}
-	} else if token.typ == yaml_BLOCK_END_TOKEN {
-		parser.state = parser.states[len(parser.states)-1]
-		parser.states = parser.states[:len(parser.states)-1]
-		parser.marks = parser.marks[:len(parser.marks)-1]
-		*event = yaml_event_t{
-			typ:        yaml_MAPPING_END_EVENT,
-			start_mark: token.start_mark,
-			end_mark:   token.end_mark,
-		}
-		skip_token(parser)
-		return true
-	}
-
-	context_mark := parser.marks[len(parser.marks)-1]
-	parser.marks = parser.marks[:len(parser.marks)-1]
-	return yaml_parser_set_parser_error_context(parser,
-		"while parsing a block mapping", context_mark,
-		"did not find expected key", token.start_mark)
-}
-
-// Parse the productions:
-// block_mapping        ::= BLOCK-MAPPING_START
-//
-//                          ((KEY block_node_or_indentless_sequence?)?
-//
-//                          (VALUE block_node_or_indentless_sequence?)?)*
-//                           ***** *
-//                          BLOCK-END
-//
-//
-func yaml_parser_parse_block_mapping_value(parser *yaml_parser_t, event *yaml_event_t) bool {
-	token := peek_token(parser)
-	if token == nil {
-		return false
-	}
-	if token.typ == yaml_VALUE_TOKEN {
-		mark := token.end_mark
-		skip_token(parser)
-		token = peek_token(parser)
-		if token == nil {
-			return false
-		}
-		if token.typ != yaml_KEY_TOKEN &&
-			token.typ != yaml_VALUE_TOKEN &&
-			token.typ != yaml_BLOCK_END_TOKEN {
-			parser.states = append(parser.states, yaml_PARSE_BLOCK_MAPPING_KEY_STATE)
-			return yaml_parser_parse_node(parser, event, true, true)
-		}
-		parser.state = yaml_PARSE_BLOCK_MAPPING_KEY_STATE
-		return yaml_parser_process_empty_scalar(parser, event, mark)
-	}
-	parser.state = yaml_PARSE_BLOCK_MAPPING_KEY_STATE
-	return yaml_parser_process_empty_scalar(parser, event, token.start_mark)
-}
-
-// Parse the productions:
-// flow_sequence        ::= FLOW-SEQUENCE-START
-//                          *******************
-//                          (flow_sequence_entry FLOW-ENTRY)*
-//                           *                   **********
-//                          flow_sequence_entry?
-//                          *
-//                          FLOW-SEQUENCE-END
-//                          *****************
-// flow_sequence_entry  ::= flow_node | KEY flow_node? (VALUE flow_node?)?
-//                          *
-//
-func yaml_parser_parse_flow_sequence_entry(parser *yaml_parser_t, event *yaml_event_t, first bool) bool {
-	if first {
-		token := peek_token(parser)
-		parser.marks = append(parser.marks, token.start_mark)
-		skip_token(parser)
-	}
-	token := peek_token(parser)
-	if token == nil {
-		return false
-	}
-	if token.typ != yaml_FLOW_SEQUENCE_END_TOKEN {
-		if !first {
-			if token.typ == yaml_FLOW_ENTRY_TOKEN {
-				skip_token(parser)
-				token = peek_token(parser)
-				if token == nil {
-					return false
-				}
-			} else {
-				context_mark := parser.marks[len(parser.marks)-1]
-				parser.marks = parser.marks[:len(parser.marks)-1]
-				return yaml_parser_set_parser_error_context(parser,
-					"while parsing a flow sequence", context_mark,
-					"did not find expected ',' or ']'", token.start_mark)
-			}
-		}
-
-		if token.typ == yaml_KEY_TOKEN {
-			parser.state = yaml_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_KEY_STATE
-			*event = yaml_event_t{
-				typ:        yaml_MAPPING_START_EVENT,
-				start_mark: token.start_mark,
-				end_mark:   token.end_mark,
-				implicit:   true,
-				style:      yaml_style_t(yaml_FLOW_MAPPING_STYLE),
-			}
-			skip_token(parser)
-			return true
-		} else if token.typ != yaml_FLOW_SEQUENCE_END_TOKEN {
-			parser.states = append(parser.states, yaml_PARSE_FLOW_SEQUENCE_ENTRY_STATE)
-			return yaml_parser_parse_node(parser, event, false, false)
-		}
-	}
-
-	parser.state = parser.states[len(parser.states)-1]
-	parser.states = parser.states[:len(parser.states)-1]
-	parser.marks = parser.marks[:len(parser.marks)-1]
-
-	*event = yaml_event_t{
-		typ:        yaml_SEQUENCE_END_EVENT,
-		start_mark: token.start_mark,
-		end_mark:   token.end_mark,
-	}
-
-	skip_token(parser)
-	return true
-}
-
-//
-// Parse the productions:
-// flow_sequence_entry  ::= flow_node | KEY flow_node? (VALUE flow_node?)?
-//                                      *** *
-//
-func yaml_parser_parse_flow_sequence_entry_mapping_key(parser *yaml_parser_t, event *yaml_event_t) bool {
-	token := peek_token(parser)
-	if token == nil {
-		return false
-	}
-	if token.typ != yaml_VALUE_TOKEN &&
-		token.typ != yaml_FLOW_ENTRY_TOKEN &&
-		token.typ != yaml_FLOW_SEQUENCE_END_TOKEN {
-		parser.states = append(parser.states, yaml_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_VALUE_STATE)
-		return yaml_parser_parse_node(parser, event, false, false)
-	}
-	mark := token.end_mark
-	skip_token(parser)
-	parser.state = yaml_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_VALUE_STATE
-	return yaml_parser_process_empty_scalar(parser, event, mark)
-}
-
-// Parse the productions:
-// flow_sequence_entry  ::= flow_node | KEY flow_node? (VALUE flow_node?)?
-//                                                      ***** *
-//
-func yaml_parser_parse_flow_sequence_entry_mapping_value(parser *yaml_parser_t, event *yaml_event_t) bool {
-	token := peek_token(parser)
-	if token == nil {
-		return false
-	}
-	if token.typ == yaml_VALUE_TOKEN {
-		skip_token(parser)
-		token := peek_token(parser)
-		if token == nil {
-			return false
-		}
-		if token.typ != yaml_FLOW_ENTRY_TOKEN && token.typ != yaml_FLOW_SEQUENCE_END_TOKEN {
-			parser.states = append(parser.states, yaml_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_END_STATE)
-			return yaml_parser_parse_node(parser, event, false, false)
-		}
-	}
-	parser.state = yaml_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_END_STATE
-	return yaml_parser_process_empty_scalar(parser, event, token.start_mark)
-}
-
-// Parse the productions:
-// flow_sequence_entry  ::= flow_node | KEY flow_node? (VALUE flow_node?)?
-//                                                                      *
-//
-func yaml_parser_parse_flow_sequence_entry_mapping_end(parser *yaml_parser_t, event *yaml_event_t) bool {
-	token := peek_token(parser)
-	if token == nil {
-		return false
-	}
-	parser.state = yaml_PARSE_FLOW_SEQUENCE_ENTRY_STATE
-	*event = yaml_event_t{
-		typ:        yaml_MAPPING_END_EVENT,
-		start_mark: token.start_mark,
-		end_mark:   token.start_mark, // [Go] Shouldn't this be end_mark?
-	}
-	return true
-}
-
-// Parse the productions:
-// flow_mapping         ::= FLOW-MAPPING-START
-//                          ******************
-//                          (flow_mapping_entry FLOW-ENTRY)*
-//                           *                  **********
-//                          flow_mapping_entry?
-//                          ******************
-//                          FLOW-MAPPING-END
-//                          ****************
-// flow_mapping_entry   ::= flow_node | KEY flow_node? (VALUE flow_node?)?
-//                          *           *** *
-//
-func yaml_parser_parse_flow_mapping_key(parser *yaml_parser_t, event *yaml_event_t, first bool) bool {
-	if first {
-		token := peek_token(parser)
-		parser.marks = append(parser.marks, token.start_mark)
-		skip_token(parser)
-	}
-
-	token := peek_token(parser)
-	if token == nil {
-		return false
-	}
-
-	if token.typ != yaml_FLOW_MAPPING_END_TOKEN {
-		if !first {
-			if token.typ == yaml_FLOW_ENTRY_TOKEN {
-				skip_token(parser)
-				token = peek_token(parser)
-				if token == nil {
-					return false
-				}
-			} else {
-				context_mark := parser.marks[len(parser.marks)-1]
-				parser.marks = parser.marks[:len(parser.marks)-1]
-				return yaml_parser_set_parser_error_context(parser,
-					"while parsing a flow mapping", context_mark,
-					"did not find expected ',' or '}'", token.start_mark)
-			}
-		}
-
-		if token.typ == yaml_KEY_TOKEN {
-			skip_token(parser)
-			token = peek_token(parser)
-			if token == nil {
-				return false
-			}
-			if token.typ != yaml_VALUE_TOKEN &&
-				token.typ != yaml_FLOW_ENTRY_TOKEN &&
-				token.typ != yaml_FLOW_MAPPING_END_TOKEN {
-				parser.states = append(parser.states, yaml_PARSE_FLOW_MAPPING_VALUE_STATE)
-				return yaml_parser_parse_node(parser, event, false, false)
-			} else {
-				parser.state = yaml_PARSE_FLOW_MAPPING_VALUE_STATE
-				return yaml_parser_process_empty_scalar(parser, event, token.start_mark)
-			}
-		} else if token.typ != yaml_FLOW_MAPPING_END_TOKEN {
-			parser.states = append(parser.states, yaml_PARSE_FLOW_MAPPING_EMPTY_VALUE_STATE)
-			return yaml_parser_parse_node(parser, event, false, false)
-		}
-	}
-
-	parser.state = parser.states[len(parser.states)-1]
-	parser.states = parser.states[:len(parser.states)-1]
-	parser.marks = parser.marks[:len(parser.marks)-1]
-	*event = yaml_event_t{
-		typ:        yaml_MAPPING_END_EVENT,
-		start_mark: token.start_mark,
-		end_mark:   token.end_mark,
-	}
-	skip_token(parser)
-	return true
-}
-
-// Parse the productions:
-// flow_mapping_entry   ::= flow_node | KEY flow_node? (VALUE flow_node?)?
-//                                   *                  ***** *
-//
-func yaml_parser_parse_flow_mapping_value(parser *yaml_parser_t, event *yaml_event_t, empty bool) bool {
-	token := peek_token(parser)
-	if token == nil {
-		return false
-	}
-	if empty {
-		parser.state = yaml_PARSE_FLOW_MAPPING_KEY_STATE
-		return yaml_parser_process_empty_scalar(parser, event, token.start_mark)
-	}
-	if token.typ == yaml_VALUE_TOKEN {
-		skip_token(parser)
-		token = peek_token(parser)
-		if token == nil {
-			return false
-		}
-		if token.typ != yaml_FLOW_ENTRY_TOKEN && token.typ != yaml_FLOW_MAPPING_END_TOKEN {
-			parser.states = append(parser.states, yaml_PARSE_FLOW_MAPPING_KEY_STATE)
-			return yaml_parser_parse_node(parser, event, false, false)
-		}
-	}
-	parser.state = yaml_PARSE_FLOW_MAPPING_KEY_STATE
-	return yaml_parser_process_empty_scalar(parser, event, token.start_mark)
-}
-
-// Generate an empty scalar event.
-func yaml_parser_process_empty_scalar(parser *yaml_parser_t, event *yaml_event_t, mark yaml_mark_t) bool {
-	*event = yaml_event_t{
-		typ:        yaml_SCALAR_EVENT,
-		start_mark: mark,
-		end_mark:   mark,
-		value:      nil, // Empty
-		implicit:   true,
-		style:      yaml_style_t(yaml_PLAIN_SCALAR_STYLE),
-	}
-	return true
-}
-
-var default_tag_directives = []yaml_tag_directive_t{
-	{[]byte("!"), []byte("!")},
-	{[]byte("!!"), []byte("tag:yaml.org,2002:")},
-}
-
-// Parse directives.
-func yaml_parser_process_directives(parser *yaml_parser_t,
-	version_directive_ref **yaml_version_directive_t,
-	tag_directives_ref *[]yaml_tag_directive_t) bool {
-
-	var version_directive *yaml_version_directive_t
-	var tag_directives []yaml_tag_directive_t
-
-	token := peek_token(parser)
-	if token == nil {
-		return false
-	}
-
-	for token.typ == yaml_VERSION_DIRECTIVE_TOKEN || token.typ == yaml_TAG_DIRECTIVE_TOKEN {
-		if token.typ == yaml_VERSION_DIRECTIVE_TOKEN {
-			if version_directive != nil {
-				yaml_parser_set_parser_error(parser,
-					"found duplicate %YAML directive", token.start_mark)
-				return false
-			}
-			if token.major != 1 || token.minor != 1 {
-				yaml_parser_set_parser_error(parser,
-					"found incompatible YAML document", token.start_mark)
-				return false
-			}
-			version_directive = &yaml_version_directive_t{
-				major: token.major,
-				minor: token.minor,
-			}
-		} else if token.typ == yaml_TAG_DIRECTIVE_TOKEN {
-			value := yaml_tag_directive_t{
-				handle: token.value,
-				prefix: token.prefix,
-			}
-			if !yaml_parser_append_tag_directive(parser, value, false, token.start_mark) {
-				return false
-			}
-			tag_directives = append(tag_directives, value)
-		}
-
-		skip_token(parser)
-		token = peek_token(parser)
-		if token == nil {
-			return false
-		}
-	}
-
-	for i := range default_tag_directives {
-		if !yaml_parser_append_tag_directive(parser, default_tag_directives[i], true, token.start_mark) {
-			return false
-		}
-	}
-
-	if version_directive_ref != nil {
-		*version_directive_ref = version_directive
-	}
-	if tag_directives_ref != nil {
-		*tag_directives_ref = tag_directives
-	}
-	return true
-}
-
-// Append a tag directive to the directives stack.
-func yaml_parser_append_tag_directive(parser *yaml_parser_t, value yaml_tag_directive_t, allow_duplicates bool, mark yaml_mark_t) bool {
-	for i := range parser.tag_directives {
-		if bytes.Equal(value.handle, parser.tag_directives[i].handle) {
-			if allow_duplicates {
-				return true
-			}
-			return yaml_parser_set_parser_error(parser, "found duplicate %TAG directive", mark)
-		}
-	}
-
-	// [Go] I suspect the copy is unnecessary. This was likely done
-	// because there was no way to track ownership of the data.
-	value_copy := yaml_tag_directive_t{
-		handle: make([]byte, len(value.handle)),
-		prefix: make([]byte, len(value.prefix)),
-	}
-	copy(value_copy.handle, value.handle)
-	copy(value_copy.prefix, value.prefix)
-	parser.tag_directives = append(parser.tag_directives, value_copy)
-	return true
-}
diff --git a/readerc.go b/readerc.go
deleted file mode 100644
index d5fb097..0000000
--- a/readerc.go
+++ /dev/null
@@ -1,391 +0,0 @@
-package yaml
-
-import (
-	"io"
-)
-
-// Set the reader error and return 0.
-func yaml_parser_set_reader_error(parser *yaml_parser_t, problem string, offset int, value int) bool {
-	parser.error = yaml_READER_ERROR
-	parser.problem = problem
-	parser.problem_offset = offset
-	parser.problem_value = value
-	return false
-}
-
-// Byte order marks.
-const (
-	bom_UTF8    = "\xef\xbb\xbf"
-	bom_UTF16LE = "\xff\xfe"
-	bom_UTF16BE = "\xfe\xff"
-)
-
-// Determine the input stream encoding by checking the BOM symbol. If no BOM is
-// found, the UTF-8 encoding is assumed. Return 1 on success, 0 on failure.
-func yaml_parser_determine_encoding(parser *yaml_parser_t) bool {
-	// Ensure that we had enough bytes in the raw buffer.
-	for !parser.eof && len(parser.raw_buffer)-parser.raw_buffer_pos < 3 {
-		if !yaml_parser_update_raw_buffer(parser) {
-			return false
-		}
-	}
-
-	// Determine the encoding.
-	buf := parser.raw_buffer
-	pos := parser.raw_buffer_pos
-	avail := len(buf) - pos
-	if avail >= 2 && buf[pos] == bom_UTF16LE[0] && buf[pos+1] == bom_UTF16LE[1] {
-		parser.encoding = yaml_UTF16LE_ENCODING
-		parser.raw_buffer_pos += 2
-		parser.offset += 2
-	} else if avail >= 2 && buf[pos] == bom_UTF16BE[0] && buf[pos+1] == bom_UTF16BE[1] {
-		parser.encoding = yaml_UTF16BE_ENCODING
-		parser.raw_buffer_pos += 2
-		parser.offset += 2
-	} else if avail >= 3 && buf[pos] == bom_UTF8[0] && buf[pos+1] == bom_UTF8[1] && buf[pos+2] == bom_UTF8[2] {
-		parser.encoding = yaml_UTF8_ENCODING
-		parser.raw_buffer_pos += 3
-		parser.offset += 3
-	} else {
-		parser.encoding = yaml_UTF8_ENCODING
-	}
-	return true
-}
-
-// Update the raw buffer.
-func yaml_parser_update_raw_buffer(parser *yaml_parser_t) bool {
-	size_read := 0
-
-	// Return if the raw buffer is full.
-	if parser.raw_buffer_pos == 0 && len(parser.raw_buffer) == cap(parser.raw_buffer) {
-		return true
-	}
-
-	// Return on EOF.
-	if parser.eof {
-		return true
-	}
-
-	// Move the remaining bytes in the raw buffer to the beginning.
-	if parser.raw_buffer_pos > 0 && parser.raw_buffer_pos < len(parser.raw_buffer) {
-		copy(parser.raw_buffer, parser.raw_buffer[parser.raw_buffer_pos:])
-	}
-	parser.raw_buffer = parser.raw_buffer[:len(parser.raw_buffer)-parser.raw_buffer_pos]
-	parser.raw_buffer_pos = 0
-
-	// Call the read handler to fill the buffer.
-	size_read, err := parser.read_handler(parser, parser.raw_buffer[len(parser.raw_buffer):cap(parser.raw_buffer)])
-	parser.raw_buffer = parser.raw_buffer[:len(parser.raw_buffer)+size_read]
-	if err == io.EOF {
-		parser.eof = true
-	} else if err != nil {
-		return yaml_parser_set_reader_error(parser, "input error: "+err.Error(), parser.offset, -1)
-	}
-	return true
-}
-
-// Ensure that the buffer contains at least `length` characters.
-// Return true on success, false on failure.
-//
-// The length is supposed to be significantly less that the buffer size.
-func yaml_parser_update_buffer(parser *yaml_parser_t, length int) bool {
-	if parser.read_handler == nil {
-		panic("read handler must be set")
-	}
-
-	// If the EOF flag is set and the raw buffer is empty, do nothing.
-	if parser.eof && parser.raw_buffer_pos == len(parser.raw_buffer) {
-		return true
-	}
-
-	// Return if the buffer contains enough characters.
-	if parser.unread >= length {
-		return true
-	}
-
-	// Determine the input encoding if it is not known yet.
-	if parser.encoding == yaml_ANY_ENCODING {
-		if !yaml_parser_determine_encoding(parser) {
-			return false
-		}
-	}
-
-	// Move the unread characters to the beginning of the buffer.
-	buffer_len := len(parser.buffer)
-	if parser.buffer_pos > 0 && parser.buffer_pos < buffer_len {
-		copy(parser.buffer, parser.buffer[parser.buffer_pos:])
-		buffer_len -= parser.buffer_pos
-		parser.buffer_pos = 0
-	} else if parser.buffer_pos == buffer_len {
-		buffer_len = 0
-		parser.buffer_pos = 0
-	}
-
-	// Open the whole buffer for writing, and cut it before returning.
-	parser.buffer = parser.buffer[:cap(parser.buffer)]
-
-	// Fill the buffer until it has enough characters.
-	first := true
-	for parser.unread < length {
-
-		// Fill the raw buffer if necessary.
-		if !first || parser.raw_buffer_pos == len(parser.raw_buffer) {
-			if !yaml_parser_update_raw_buffer(parser) {
-				parser.buffer = parser.buffer[:buffer_len]
-				return false
-			}
-		}
-		first = false
-
-		// Decode the raw buffer.
-	inner:
-		for parser.raw_buffer_pos != len(parser.raw_buffer) {
-			var value rune
-			var width int
-
-			raw_unread := len(parser.raw_buffer) - parser.raw_buffer_pos
-
-			// Decode the next character.
-			switch parser.encoding {
-			case yaml_UTF8_ENCODING:
-				// Decode a UTF-8 character.  Check RFC 3629
-				// (http://www.ietf.org/rfc/rfc3629.txt) for more details.
-				//
-				// The following table (taken from the RFC) is used for
-				// decoding.
-				//
-				//    Char. number range |        UTF-8 octet sequence
-				//      (hexadecimal)    |              (binary)
-				//   --------------------+------------------------------------
-				//   0000 0000-0000 007F | 0xxxxxxx
-				//   0000 0080-0000 07FF | 110xxxxx 10xxxxxx
-				//   0000 0800-0000 FFFF | 1110xxxx 10xxxxxx 10xxxxxx
-				//   0001 0000-0010 FFFF | 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
-				//
-				// Additionally, the characters in the range 0xD800-0xDFFF
-				// are prohibited as they are reserved for use with UTF-16
-				// surrogate pairs.
-
-				// Determine the length of the UTF-8 sequence.
-				octet := parser.raw_buffer[parser.raw_buffer_pos]
-				switch {
-				case octet&0x80 == 0x00:
-					width = 1
-				case octet&0xE0 == 0xC0:
-					width = 2
-				case octet&0xF0 == 0xE0:
-					width = 3
-				case octet&0xF8 == 0xF0:
-					width = 4
-				default:
-					// The leading octet is invalid.
-					return yaml_parser_set_reader_error(parser,
-						"invalid leading UTF-8 octet",
-						parser.offset, int(octet))
-				}
-
-				// Check if the raw buffer contains an incomplete character.
-				if width > raw_unread {
-					if parser.eof {
-						return yaml_parser_set_reader_error(parser,
-							"incomplete UTF-8 octet sequence",
-							parser.offset, -1)
-					}
-					break inner
-				}
-
-				// Decode the leading octet.
-				switch {
-				case octet&0x80 == 0x00:
-					value = rune(octet & 0x7F)
-				case octet&0xE0 == 0xC0:
-					value = rune(octet & 0x1F)
-				case octet&0xF0 == 0xE0:
-					value = rune(octet & 0x0F)
-				case octet&0xF8 == 0xF0:
-					value = rune(octet & 0x07)
-				default:
-					value = 0
-				}
-
-				// Check and decode the trailing octets.
-				for k := 1; k < width; k++ {
-					octet = parser.raw_buffer[parser.raw_buffer_pos+k]
-
-					// Check if the octet is valid.
-					if (octet & 0xC0) != 0x80 {
-						return yaml_parser_set_reader_error(parser,
-							"invalid trailing UTF-8 octet",
-							parser.offset+k, int(octet))
-					}
-
-					// Decode the octet.
-					value = (value << 6) + rune(octet&0x3F)
-				}
-
-				// Check the length of the sequence against the value.
-				switch {
-				case width == 1:
-				case width == 2 && value >= 0x80:
-				case width == 3 && value >= 0x800:
-				case width == 4 && value >= 0x10000:
-				default:
-					return yaml_parser_set_reader_error(parser,
-						"invalid length of a UTF-8 sequence",
-						parser.offset, -1)
-				}
-
-				// Check the range of the value.
-				if value >= 0xD800 && value <= 0xDFFF || value > 0x10FFFF {
-					return yaml_parser_set_reader_error(parser,
-						"invalid Unicode character",
-						parser.offset, int(value))
-				}
-
-			case yaml_UTF16LE_ENCODING, yaml_UTF16BE_ENCODING:
-				var low, high int
-				if parser.encoding == yaml_UTF16LE_ENCODING {
-					low, high = 0, 1
-				} else {
-					high, low = 1, 0
-				}
-
-				// The UTF-16 encoding is not as simple as one might
-				// naively think.  Check RFC 2781
-				// (http://www.ietf.org/rfc/rfc2781.txt).
-				//
-				// Normally, two subsequent bytes describe a Unicode
-				// character.  However a special technique (called a
-				// surrogate pair) is used for specifying character
-				// values larger than 0xFFFF.
-				//
-				// A surrogate pair consists of two pseudo-characters:
-				//      high surrogate area (0xD800-0xDBFF)
-				//      low surrogate area (0xDC00-0xDFFF)
-				//
-				// The following formulas are used for decoding
-				// and encoding characters using surrogate pairs:
-				//
-				//  U  = U' + 0x10000   (0x01 00 00 <= U <= 0x10 FF FF)
-				//  U' = yyyyyyyyyyxxxxxxxxxx   (0 <= U' <= 0x0F FF FF)
-				//  W1 = 110110yyyyyyyyyy
-				//  W2 = 110111xxxxxxxxxx
-				//
-				// where U is the character value, W1 is the high surrogate
-				// area, W2 is the low surrogate area.
-
-				// Check for incomplete UTF-16 character.
-				if raw_unread < 2 {
-					if parser.eof {
-						return yaml_parser_set_reader_error(parser,
-							"incomplete UTF-16 character",
-							parser.offset, -1)
-					}
-					break inner
-				}
-
-				// Get the character.
-				value = rune(parser.raw_buffer[parser.raw_buffer_pos+low]) +
-					(rune(parser.raw_buffer[parser.raw_buffer_pos+high]) << 8)
-
-				// Check for unexpected low surrogate area.
-				if value&0xFC00 == 0xDC00 {
-					return yaml_parser_set_reader_error(parser,
-						"unexpected low surrogate area",
-						parser.offset, int(value))
-				}
-
-				// Check for a high surrogate area.
-				if value&0xFC00 == 0xD800 {
-					width = 4
-
-					// Check for incomplete surrogate pair.
-					if raw_unread < 4 {
-						if parser.eof {
-							return yaml_parser_set_reader_error(parser,
-								"incomplete UTF-16 surrogate pair",
-								parser.offset, -1)
-						}
-						break inner
-					}
-
-					// Get the next character.
-					value2 := rune(parser.raw_buffer[parser.raw_buffer_pos+low+2]) +
-						(rune(parser.raw_buffer[parser.raw_buffer_pos+high+2]) << 8)
-
-					// Check for a low surrogate area.
-					if value2&0xFC00 != 0xDC00 {
-						return yaml_parser_set_reader_error(parser,
-							"expected low surrogate area",
-							parser.offset+2, int(value2))
-					}
-
-					// Generate the value of the surrogate pair.
-					value = 0x10000 + ((value & 0x3FF) << 10) + (value2 & 0x3FF)
-				} else {
-					width = 2
-				}
-
-			default:
-				panic("impossible")
-			}
-
-			// Check if the character is in the allowed range:
-			//      #x9 | #xA | #xD | [#x20-#x7E]               (8 bit)
-			//      | #x85 | [#xA0-#xD7FF] | [#xE000-#xFFFD]    (16 bit)
-			//      | [#x10000-#x10FFFF]                        (32 bit)
-			switch {
-			case value == 0x09:
-			case value == 0x0A:
-			case value == 0x0D:
-			case value >= 0x20 && value <= 0x7E:
-			case value == 0x85:
-			case value >= 0xA0 && value <= 0xD7FF:
-			case value >= 0xE000 && value <= 0xFFFD:
-			case value >= 0x10000 && value <= 0x10FFFF:
-			default:
-				return yaml_parser_set_reader_error(parser,
-					"control characters are not allowed",
-					parser.offset, int(value))
-			}
-
-			// Move the raw pointers.
-			parser.raw_buffer_pos += width
-			parser.offset += width
-
-			// Finally put the character into the buffer.
-			if value <= 0x7F {
-				// 0000 0000-0000 007F . 0xxxxxxx
-				parser.buffer[buffer_len+0] = byte(value)
-			} else if value <= 0x7FF {
-				// 0000 0080-0000 07FF . 110xxxxx 10xxxxxx
-				parser.buffer[buffer_len+0] = byte(0xC0 + (value >> 6))
-				parser.buffer[buffer_len+1] = byte(0x80 + (value & 0x3F))
-			} else if value <= 0xFFFF {
-				// 0000 0800-0000 FFFF . 1110xxxx 10xxxxxx 10xxxxxx
-				parser.buffer[buffer_len+0] = byte(0xE0 + (value >> 12))
-				parser.buffer[buffer_len+1] = byte(0x80 + ((value >> 6) & 0x3F))
-				parser.buffer[buffer_len+2] = byte(0x80 + (value & 0x3F))
-			} else {
-				// 0001 0000-0010 FFFF . 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
-				parser.buffer[buffer_len+0] = byte(0xF0 + (value >> 18))
-				parser.buffer[buffer_len+1] = byte(0x80 + ((value >> 12) & 0x3F))
-				parser.buffer[buffer_len+2] = byte(0x80 + ((value >> 6) & 0x3F))
-				parser.buffer[buffer_len+3] = byte(0x80 + (value & 0x3F))
-			}
-			buffer_len += width
-
-			parser.unread++
-		}
-
-		// On EOF, put NUL into the buffer and return.
-		if parser.eof {
-			parser.buffer[buffer_len] = 0
-			buffer_len++
-			parser.unread++
-			break
-		}
-	}
-	parser.buffer = parser.buffer[:buffer_len]
-	return true
-}
diff --git a/resolve.go b/resolve.go
deleted file mode 100644
index dbda017..0000000
--- a/resolve.go
+++ /dev/null
@@ -1,150 +0,0 @@
-package yaml
-
-import (
-	"math"
-	"strconv"
-	"strings"
-)
-
-// TODO: merge, timestamps, base 60 floats, omap.
-
-type resolveMapItem struct {
-	value interface{}
-	tag   string
-}
-
-var resolveTable = make([]byte, 256)
-var resolveMap = make(map[string]resolveMapItem)
-
-func init() {
-	t := resolveTable
-	t[int('+')] = 'S' // Sign
-	t[int('-')] = 'S'
-	for _, c := range "0123456789" {
-		t[int(c)] = 'D' // Digit
-	}
-	for _, c := range "yYnNtTfFoO~" {
-		t[int(c)] = 'M' // In map
-	}
-	t[int('.')] = '.' // Float (potentially in map)
-	t[int('<')] = '<' // Merge
-
-	var resolveMapList = []struct {
-		v   interface{}
-		tag string
-		l   []string
-	}{
-		{true, "!!bool", []string{"y", "Y", "yes", "Yes", "YES"}},
-		{true, "!!bool", []string{"true", "True", "TRUE"}},
-		{true, "!!bool", []string{"on", "On", "ON"}},
-		{false, "!!bool", []string{"n", "N", "no", "No", "NO"}},
-		{false, "!!bool", []string{"false", "False", "FALSE"}},
-		{false, "!!bool", []string{"off", "Off", "OFF"}},
-		{nil, "!!null", []string{"~", "null", "Null", "NULL"}},
-		{math.NaN(), "!!float", []string{".nan", ".NaN", ".NAN"}},
-		{math.Inf(+1), "!!float", []string{".inf", ".Inf", ".INF"}},
-		{math.Inf(+1), "!!float", []string{"+.inf", "+.Inf", "+.INF"}},
-		{math.Inf(-1), "!!float", []string{"-.inf", "-.Inf", "-.INF"}},
-	}
-
-	m := resolveMap
-	for _, item := range resolveMapList {
-		for _, s := range item.l {
-			m[s] = resolveMapItem{item.v, item.tag}
-		}
-	}
-}
-
-const longTagPrefix = "tag:yaml.org,2002:"
-
-func shortTag(tag string) string {
-	if strings.HasPrefix(tag, longTagPrefix) {
-		return "!!" + tag[len(longTagPrefix):]
-	}
-	return tag
-}
-
-func resolvableTag(tag string) bool {
-	switch tag {
-	case "", "!!str", "!!bool", "!!int", "!!float", "!!null":
-		return true
-	}
-	return false
-}
-
-func resolve(tag string, in string) (rtag string, out interface{}) {
-	tag = shortTag(tag)
-	if !resolvableTag(tag) {
-		return tag, in
-	}
-
-	defer func() {
-		if tag != "" && tag != rtag {
-			panic("Can't decode " + rtag + " '" + in + "' as a " + tag)
-		}
-	}()
-
-	if in == "" {
-		return "!!null", nil
-	}
-
-	c := resolveTable[in[0]]
-	if c == 0 {
-		// It's a string for sure. Nothing to do.
-		return "!!str", in
-	}
-
-	// Handle things we can lookup in a map.
-	if item, ok := resolveMap[in]; ok {
-		return item.tag, item.value
-	}
-
-	switch c {
-	case 'M':
-		// We've already checked the map above.
-
-	case '.':
-		// Not in the map, so maybe a normal float.
-		floatv, err := strconv.ParseFloat(in, 64)
-		if err == nil {
-			return "!!float", floatv
-		}
-	// XXX Handle base 60 floats here (WTF!)
-
-	case 'D', 'S':
-		// Int, float, or timestamp.
-		plain := strings.Replace(in, "_", "", -1)
-		intv, err := strconv.ParseInt(plain, 0, 64)
-		if err == nil {
-			if intv == int64(int(intv)) {
-				return "!!int", int(intv)
-			} else {
-				return "!!int", intv
-			}
-		}
-		floatv, err := strconv.ParseFloat(plain, 64)
-		if err == nil {
-			return "!!float", floatv
-		}
-		if strings.HasPrefix(plain, "0b") {
-			intv, err := strconv.ParseInt(plain[2:], 2, 64)
-			if err == nil {
-				return "!!int", int(intv)
-			}
-		} else if strings.HasPrefix(plain, "-0b") {
-			intv, err := strconv.ParseInt(plain[3:], 2, 64)
-			if err == nil {
-				return "!!int", -int(intv)
-			}
-		}
-	// XXX Handle timestamps here.
-
-	case '<':
-		// XXX Handle merge (<<) here.
-
-	default:
-		panic("resolveTable item not yet handled: " +
-			string([]byte{c}) + " (with " + in + ")")
-	}
-	return "!!str", in
-}
diff --git a/scannerc.go b/scannerc.go
deleted file mode 100644
index fe93b19..0000000
--- a/scannerc.go
+++ /dev/null
@@ -1,2710 +0,0 @@
-package yaml
-
-import (
-	"bytes"
-	"fmt"
-)
-
-// Introduction
-// ************
-//
-// The following notes assume that you are familiar with the YAML specification
-// (http://yaml.org/spec/cvs/current.html).  We mostly follow it, although in
-// some cases we are less restrictive that it requires.
-//
-// The process of transforming a YAML stream into a sequence of events is
-// divided on two steps: Scanning and Parsing.
-//
-// The Scanner transforms the input stream into a sequence of tokens, while the
-// parser transform the sequence of tokens produced by the Scanner into a
-// sequence of parsing events.
-//
-// The Scanner is rather clever and complicated. The Parser, on the contrary,
-// is a straightforward implementation of a recursive-descendant parser (or,
-// LL(1) parser, as it is usually called).
-//
-// Actually there are two issues of Scanning that might be called "clever", the
-// rest is quite straightforward.  The issues are "block collection start" and
-// "simple keys".  Both issues are explained below in details.
-//
-// Here the Scanning step is explained and implemented.  We start with the list
-// of all the tokens produced by the Scanner together with short descriptions.
-//
-// Now, tokens:
-//
-//      STREAM-START(encoding)          # The stream start.
-//      STREAM-END                      # The stream end.
-//      VERSION-DIRECTIVE(major,minor)  # The '%YAML' directive.
-//      TAG-DIRECTIVE(handle,prefix)    # The '%TAG' directive.
-//      DOCUMENT-START                  # '---'
-//      DOCUMENT-END                    # '...'
-//      BLOCK-SEQUENCE-START            # Indentation increase denoting a block
-//      BLOCK-MAPPING-START             # sequence or a block mapping.
-//      BLOCK-END                       # Indentation decrease.
-//      FLOW-SEQUENCE-START             # '['
-//      FLOW-SEQUENCE-END               # ']'
-//      BLOCK-SEQUENCE-START            # '{'
-//      BLOCK-SEQUENCE-END              # '}'
-//      BLOCK-ENTRY                     # '-'
-//      FLOW-ENTRY                      # ','
-//      KEY                             # '?' or nothing (simple keys).
-//      VALUE                           # ':'
-//      ALIAS(anchor)                   # '*anchor'
-//      ANCHOR(anchor)                  # '&anchor'
-//      TAG(handle,suffix)              # '!handle!suffix'
-//      SCALAR(value,style)             # A scalar.
-//
-// The following two tokens are "virtual" tokens denoting the beginning and the
-// end of the stream:
-//
-//      STREAM-START(encoding)
-//      STREAM-END
-//
-// We pass the information about the input stream encoding with the
-// STREAM-START token.
-//
-// The next two tokens are responsible for tags:
-//
-//      VERSION-DIRECTIVE(major,minor)
-//      TAG-DIRECTIVE(handle,prefix)
-//
-// Example:
-//
-//      %YAML   1.1
-//      %TAG    !   !foo
-//      %TAG    !yaml!  tag:yaml.org,2002:
-//      ---
-//
-// The correspoding sequence of tokens:
-//
-//      STREAM-START(utf-8)
-//      VERSION-DIRECTIVE(1,1)
-//      TAG-DIRECTIVE("!","!foo")
-//      TAG-DIRECTIVE("!yaml","tag:yaml.org,2002:")
-//      DOCUMENT-START
-//      STREAM-END
-//
-// Note that the VERSION-DIRECTIVE and TAG-DIRECTIVE tokens occupy a whole
-// line.
-//
-// The document start and end indicators are represented by:
-//
-//      DOCUMENT-START
-//      DOCUMENT-END
-//
-// Note that if a YAML stream contains an implicit document (without '---'
-// and '...' indicators), no DOCUMENT-START and DOCUMENT-END tokens will be
-// produced.
-//
-// In the following examples, we present whole documents together with the
-// produced tokens.
-//
-//      1. An implicit document:
-//
-//          'a scalar'
-//
-//      Tokens:
-//
-//          STREAM-START(utf-8)
-//          SCALAR("a scalar",single-quoted)
-//          STREAM-END
-//
-//      2. An explicit document:
-//
-//          ---
-//          'a scalar'
-//          ...
-//
-//      Tokens:
-//
-//          STREAM-START(utf-8)
-//          DOCUMENT-START
-//          SCALAR("a scalar",single-quoted)
-//          DOCUMENT-END
-//          STREAM-END
-//
-//      3. Several documents in a stream:
-//
-//          'a scalar'
-//          ---
-//          'another scalar'
-//          ---
-//          'yet another scalar'
-//
-//      Tokens:
-//
-//          STREAM-START(utf-8)
-//          SCALAR("a scalar",single-quoted)
-//          DOCUMENT-START
-//          SCALAR("another scalar",single-quoted)
-//          DOCUMENT-START
-//          SCALAR("yet another scalar",single-quoted)
-//          STREAM-END
-//
-// We have already introduced the SCALAR token above.  The following tokens are
-// used to describe aliases, anchors, tag, and scalars:
-//
-//      ALIAS(anchor)
-//      ANCHOR(anchor)
-//      TAG(handle,suffix)
-//      SCALAR(value,style)
-//
-// The following series of examples illustrate the usage of these tokens:
-//
-//      1. A recursive sequence:
-//
-//          &A [ *A ]
-//
-//      Tokens:
-//
-//          STREAM-START(utf-8)
-//          ANCHOR("A")
-//          FLOW-SEQUENCE-START
-//          ALIAS("A")
-//          FLOW-SEQUENCE-END
-//          STREAM-END
-//
-//      2. A tagged scalar:
-//
-//          !!float "3.14"  # A good approximation.
-//
-//      Tokens:
-//
-//          STREAM-START(utf-8)
-//          TAG("!!","float")
-//          SCALAR("3.14",double-quoted)
-//          STREAM-END
-//
-//      3. Various scalar styles:
-//
-//          --- # Implicit empty plain scalars do not produce tokens.
-//          --- a plain scalar
-//          --- 'a single-quoted scalar'
-//          --- "a double-quoted scalar"
-//          --- |-
-//            a literal scalar
-//          --- >-
-//            a folded
-//            scalar
-//
-//      Tokens:
-//
-//          STREAM-START(utf-8)
-//          DOCUMENT-START
-//          DOCUMENT-START
-//          SCALAR("a plain scalar",plain)
-//          DOCUMENT-START
-//          SCALAR("a single-quoted scalar",single-quoted)
-//          DOCUMENT-START
-//          SCALAR("a double-quoted scalar",double-quoted)
-//          DOCUMENT-START
-//          SCALAR("a literal scalar",literal)
-//          DOCUMENT-START
-//          SCALAR("a folded scalar",folded)
-//          STREAM-END
-//
-// Now it's time to review collection-related tokens. We will start with
-// flow collections:
-//
-//      FLOW-SEQUENCE-START
-//      FLOW-SEQUENCE-END
-//      FLOW-MAPPING-START
-//      FLOW-MAPPING-END
-//      FLOW-ENTRY
-//      KEY
-//      VALUE
-//
-// The tokens FLOW-SEQUENCE-START, FLOW-SEQUENCE-END, FLOW-MAPPING-START, and
-// FLOW-MAPPING-END represent the indicators '[', ']', '{', and '}'
-// correspondingly.  FLOW-ENTRY represent the ',' indicator.  Finally the
-// indicators '?' and ':', which are used for denoting mapping keys and values,
-// are represented by the KEY and VALUE tokens.
-//
-// The following examples show flow collections:
-//
-//      1. A flow sequence:
-//
-//          [item 1, item 2, item 3]
-//
-//      Tokens:
-//
-//          STREAM-START(utf-8)
-//          FLOW-SEQUENCE-START
-//          SCALAR("item 1",plain)
-//          FLOW-ENTRY
-//          SCALAR("item 2",plain)
-//          FLOW-ENTRY
-//          SCALAR("item 3",plain)
-//          FLOW-SEQUENCE-END
-//          STREAM-END
-//
-//      2. A flow mapping:
-//
-//          {
-//              a simple key: a value,  # Note that the KEY token is produced.
-//              ? a complex key: another value,
-//          }
-//
-//      Tokens:
-//
-//          STREAM-START(utf-8)
-//          FLOW-MAPPING-START
-//          KEY
-//          SCALAR("a simple key",plain)
-//          VALUE
-//          SCALAR("a value",plain)
-//          FLOW-ENTRY
-//          KEY
-//          SCALAR("a complex key",plain)
-//          VALUE
-//          SCALAR("another value",plain)
-//          FLOW-ENTRY
-//          FLOW-MAPPING-END
-//          STREAM-END
-//
-// A simple key is a key which is not denoted by the '?' indicator.  Note that
-// the Scanner still produce the KEY token whenever it encounters a simple key.
-//
-// For scanning block collections, the following tokens are used (note that we
-// repeat KEY and VALUE here):
-//
-//      BLOCK-SEQUENCE-START
-//      BLOCK-MAPPING-START
-//      BLOCK-END
-//      BLOCK-ENTRY
-//      KEY
-//      VALUE
-//
-// The tokens BLOCK-SEQUENCE-START and BLOCK-MAPPING-START denote indentation
-// increase that precedes a block collection (cf. the INDENT token in Python).
-// The token BLOCK-END denote indentation decrease that ends a block collection
-// (cf. the DEDENT token in Python).  However YAML has some syntax pecularities
-// that makes detections of these tokens more complex.
-//
-// The tokens BLOCK-ENTRY, KEY, and VALUE are used to represent the indicators
-// '-', '?', and ':' correspondingly.
-//
-// The following examples show how the tokens BLOCK-SEQUENCE-START,
-// BLOCK-MAPPING-START, and BLOCK-END are emitted by the Scanner:
-//
-//      1. Block sequences:
-//
-//          - item 1
-//          - item 2
-//          -
-//            - item 3.1
-//            - item 3.2
-//          -
-//            key 1: value 1
-//            key 2: value 2
-//
-//      Tokens:
-//
-//          STREAM-START(utf-8)
-//          BLOCK-SEQUENCE-START
-//          BLOCK-ENTRY
-//          SCALAR("item 1",plain)
-//          BLOCK-ENTRY
-//          SCALAR("item 2",plain)
-//          BLOCK-ENTRY
-//          BLOCK-SEQUENCE-START
-//          BLOCK-ENTRY
-//          SCALAR("item 3.1",plain)
-//          BLOCK-ENTRY
-//          SCALAR("item 3.2",plain)
-//          BLOCK-END
-//          BLOCK-ENTRY
-//          BLOCK-MAPPING-START
-//          KEY
-//          SCALAR("key 1",plain)
-//          VALUE
-//          SCALAR("value 1",plain)
-//          KEY
-//          SCALAR("key 2",plain)
-//          VALUE
-//          SCALAR("value 2",plain)
-//          BLOCK-END
-//          BLOCK-END
-//          STREAM-END
-//
-//      2. Block mappings:
-//
-//          a simple key: a value   # The KEY token is produced here.
-//          ? a complex key
-//          : another value
-//          a mapping:
-//            key 1: value 1
-//            key 2: value 2
-//          a sequence:
-//            - item 1
-//            - item 2
-//
-//      Tokens:
-//
-//          STREAM-START(utf-8)
-//          BLOCK-MAPPING-START
-//          KEY
-//          SCALAR("a simple key",plain)
-//          VALUE
-//          SCALAR("a value",plain)
-//          KEY
-//          SCALAR("a complex key",plain)
-//          VALUE
-//          SCALAR("another value",plain)
-//          KEY
-//          SCALAR("a mapping",plain)
-//          BLOCK-MAPPING-START
-//          KEY
-//          SCALAR("key 1",plain)
-//          VALUE
-//          SCALAR("value 1",plain)
-//          KEY
-//          SCALAR("key 2",plain)
-//          VALUE
-//          SCALAR("value 2",plain)
-//          BLOCK-END
-//          KEY
-//          SCALAR("a sequence",plain)
-//          VALUE
-//          BLOCK-SEQUENCE-START
-//          BLOCK-ENTRY
-//          SCALAR("item 1",plain)
-//          BLOCK-ENTRY
-//          SCALAR("item 2",plain)
-//          BLOCK-END
-//          BLOCK-END
-//          STREAM-END
-//
-// YAML does not always require to start a new block collection from a new
-// line.  If the current line contains only '-', '?', and ':' indicators, a new
-// block collection may start at the current line.  The following examples
-// illustrate this case:
-//
-//      1. Collections in a sequence:
-//
-//          - - item 1
-//            - item 2
-//          - key 1: value 1
-//            key 2: value 2
-//          - ? complex key
-//            : complex value
-//
-//      Tokens:
-//
-//          STREAM-START(utf-8)
-//          BLOCK-SEQUENCE-START
-//          BLOCK-ENTRY
-//          BLOCK-SEQUENCE-START
-//          BLOCK-ENTRY
-//          SCALAR("item 1",plain)
-//          BLOCK-ENTRY
-//          SCALAR("item 2",plain)
-//          BLOCK-END
-//          BLOCK-ENTRY
-//          BLOCK-MAPPING-START
-//          KEY
-//          SCALAR("key 1",plain)
-//          VALUE
-//          SCALAR("value 1",plain)
-//          KEY
-//          SCALAR("key 2",plain)
-//          VALUE
-//          SCALAR("value 2",plain)
-//          BLOCK-END
-//          BLOCK-ENTRY
-//          BLOCK-MAPPING-START
-//          KEY
-//          SCALAR("complex key")
-//          VALUE
-//          SCALAR("complex value")
-//          BLOCK-END
-//          BLOCK-END
-//          STREAM-END
-//
-//      2. Collections in a mapping:
-//
-//          ? a sequence
-//          : - item 1
-//            - item 2
-//          ? a mapping
-//          : key 1: value 1
-//            key 2: value 2
-//
-//      Tokens:
-//
-//          STREAM-START(utf-8)
-//          BLOCK-MAPPING-START
-//          KEY
-//          SCALAR("a sequence",plain)
-//          VALUE
-//          BLOCK-SEQUENCE-START
-//          BLOCK-ENTRY
-//          SCALAR("item 1",plain)
-//          BLOCK-ENTRY
-//          SCALAR("item 2",plain)
-//          BLOCK-END
-//          KEY
-//          SCALAR("a mapping",plain)
-//          VALUE
-//          BLOCK-MAPPING-START
-//          KEY
-//          SCALAR("key 1",plain)
-//          VALUE
-//          SCALAR("value 1",plain)
-//          KEY
-//          SCALAR("key 2",plain)
-//          VALUE
-//          SCALAR("value 2",plain)
-//          BLOCK-END
-//          BLOCK-END
-//          STREAM-END
-//
-// YAML also permits non-indented sequences if they are included into a block
-// mapping.  In this case, the token BLOCK-SEQUENCE-START is not produced:
-//
-//      key:
-//      - item 1    # BLOCK-SEQUENCE-START is NOT produced here.
-//      - item 2
-//
-// Tokens:
-//
-//      STREAM-START(utf-8)
-//      BLOCK-MAPPING-START
-//      KEY
-//      SCALAR("key",plain)
-//      VALUE
-//      BLOCK-ENTRY
-//      SCALAR("item 1",plain)
-//      BLOCK-ENTRY
-//      SCALAR("item 2",plain)
-//      BLOCK-END
-//
-
-// Ensure that the buffer contains the required number of characters.
-// Return true on success, false on failure (reader error or memory error).
-func cache(parser *yaml_parser_t, length int) bool {
-	// [Go] This was inlined: !cache(A, B) -> unread < B && !update(A, B)
-	return parser.unread >= length || yaml_parser_update_buffer(parser, length)
-}
-
-// Advance the buffer pointer.
-func skip(parser *yaml_parser_t) {
-	parser.mark.index++
-	parser.mark.column++
-	parser.unread--
-	parser.buffer_pos += width(parser.buffer[parser.buffer_pos])
-}
-
-func skip_line(parser *yaml_parser_t) {
-	if is_crlf(parser.buffer, parser.buffer_pos) {
-		parser.mark.index += 2
-		parser.mark.column = 0
-		parser.mark.line++
-		parser.unread -= 2
-		parser.buffer_pos += 2
-	} else if is_break(parser.buffer, parser.buffer_pos) {
-		parser.mark.index++
-		parser.mark.column = 0
-		parser.mark.line++
-		parser.unread--
-		parser.buffer_pos += width(parser.buffer[parser.buffer_pos])
-	}
-}
-
-// Copy a character to a string buffer and advance pointers.
-func read(parser *yaml_parser_t, s []byte) []byte {
-	w := width(parser.buffer[parser.buffer_pos])
-	if w == 0 {
-		panic("invalid character sequence")
-	}
-	if len(s) == 0 {
-		s = make([]byte, 0, 32)
-	}
-	if w == 1 && len(s)+w <= cap(s) {
-		s = s[:len(s)+1]
-		s[len(s)-1] = parser.buffer[parser.buffer_pos]
-		parser.buffer_pos++
-	} else {
-		s = append(s, parser.buffer[parser.buffer_pos:parser.buffer_pos+w]...)
-		parser.buffer_pos += w
-	}
-	parser.mark.index++
-	parser.mark.column++
-	parser.unread--
-	return s
-}
-
-// Copy a line break character to a string buffer and advance pointers.
-func read_line(parser *yaml_parser_t, s []byte) []byte {
-	buf := parser.buffer
-	pos := parser.buffer_pos
-	switch {
-	case buf[pos] == '\r' && buf[pos+1] == '\n':
-		// CR LF . LF
-		s = append(s, '\n')
-		parser.buffer_pos += 2
-		parser.mark.index++
-		parser.unread--
-	case buf[pos] == '\r' || buf[pos] == '\n':
-		// CR|LF . LF
-		s = append(s, '\n')
-		parser.buffer_pos += 1
-	case buf[pos] == '\xC2' && buf[pos+1] == '\x85':
-		// NEL . LF
-		s = append(s, '\n')
-		parser.buffer_pos += 2
-	case buf[pos] == '\xE2' && buf[pos+1] == '\x80' && (buf[pos+2] == '\xA8' || buf[pos+2] == '\xA9'):
-		// LS|PS . LS|PS
-		s = append(s, buf[parser.buffer_pos:pos+3]...)
-		parser.buffer_pos += 3
-	default:
-		return s
-	}
-	parser.mark.index++
-	parser.mark.column = 0
-	parser.mark.line++
-	parser.unread--
-	return s
-}
-
-// Get the next token.
-func yaml_parser_scan(parser *yaml_parser_t, token *yaml_token_t) bool {
-	// Erase the token object.
-	*token = yaml_token_t{} // [Go] Is this necessary?
-
-	// No tokens after STREAM-END or error.
-	if parser.stream_end_produced || parser.error != yaml_NO_ERROR {
-		return true
-	}
-
-	// Ensure that the tokens queue contains enough tokens.
-	if !parser.token_available {
-		if !yaml_parser_fetch_more_tokens(parser) {
-			return false
-		}
-	}
-
-	// Fetch the next token from the queue.
-	*token = parser.tokens[parser.tokens_head]
-	parser.tokens_head++
-	parser.tokens_parsed++
-	parser.token_available = false
-
-	if token.typ == yaml_STREAM_END_TOKEN {
-		parser.stream_end_produced = true
-	}
-	return true
-}
-
-// Set the scanner error and return false.
-func yaml_parser_set_scanner_error(parser *yaml_parser_t, context string, context_mark yaml_mark_t, problem string) bool {
-	parser.error = yaml_SCANNER_ERROR
-	parser.context = context
-	parser.context_mark = context_mark
-	parser.problem = problem
-	parser.problem_mark = parser.mark
-	return false
-}
-
-func yaml_parser_set_scanner_tag_error(parser *yaml_parser_t, directive bool, context_mark yaml_mark_t, problem string) bool {
-	context := "while parsing a tag"
-	if directive {
-		context = "while parsing a %TAG directive"
-	}
-	return yaml_parser_set_scanner_error(parser, context, context_mark, "did not find URI escaped octet")
-}
-
-func trace(args ...interface{}) func() {
-	pargs := append([]interface{}{"+++"}, args...)
-	fmt.Println(pargs...)
-	pargs = append([]interface{}{"---"}, args...)
-	return func() { fmt.Println(pargs...) }
-}
-
-// Ensure that the tokens queue contains at least one token which can be
-// returned to the Parser.
-func yaml_parser_fetch_more_tokens(parser *yaml_parser_t) bool {
-	// While we need more tokens to fetch, do it.
-	for {
-		// Check if we really need to fetch more tokens.
-		need_more_tokens := false
-
-		if parser.tokens_head == len(parser.tokens) {
-			// Queue is empty.
-			need_more_tokens = true
-		} else {
-			// Check if any potential simple key may occupy the head position.
-			if !yaml_parser_stale_simple_keys(parser) {
-				return false
-			}
-
-			for i := range parser.simple_keys {
-				simple_key := &parser.simple_keys[i]
-				if simple_key.possible && simple_key.token_number == parser.tokens_parsed {
-					need_more_tokens = true
-					break
-				}
-			}
-		}
-
-		// We are finished.
-		if !need_more_tokens {
-			break
-		}
-		// Fetch the next token.
-		if !yaml_parser_fetch_next_token(parser) {
-			return false
-		}
-	}
-
-	parser.token_available = true
-	return true
-}
-
-// The dispatcher for token fetchers.
-func yaml_parser_fetch_next_token(parser *yaml_parser_t) bool {
-	// Ensure that the buffer is initialized.
-	if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
-		return false
-	}
-
-	// Check if we just started scanning.  Fetch STREAM-START then.
-	if !parser.stream_start_produced {
-		return yaml_parser_fetch_stream_start(parser)
-	}
-
-	// Eat whitespaces and comments until we reach the next token.
-	if !yaml_parser_scan_to_next_token(parser) {
-		return false
-	}
-
-	// Remove obsolete potential simple keys.
-	if !yaml_parser_stale_simple_keys(parser) {
-		return false
-	}
-
-	// Check the indentation level against the current column.
-	if !yaml_parser_unroll_indent(parser, parser.mark.column) {
-		return false
-	}
-
-	// Ensure that the buffer contains at least 4 characters.  4 is the length
-	// of the longest indicators ('--- ' and '... ').
-	if parser.unread < 4 && !yaml_parser_update_buffer(parser, 4) {
-		return false
-	}
-
-	// Is it the end of the stream?
-	if is_z(parser.buffer, parser.buffer_pos) {
-		return yaml_parser_fetch_stream_end(parser)
-	}
-
-	// Is it a directive?
-	if parser.mark.column == 0 && parser.buffer[parser.buffer_pos] == '%' {
-		return yaml_parser_fetch_directive(parser)
-	}
-
-	buf := parser.buffer
-	pos := parser.buffer_pos
-
-	// Is it the document start indicator?
-	if parser.mark.column == 0 && buf[pos] == '-' && buf[pos+1] == '-' && buf[pos+2] == '-' && is_blankz(buf, pos+3) {
-		return yaml_parser_fetch_document_indicator(parser, yaml_DOCUMENT_START_TOKEN)
-	}
-
-	// Is it the document end indicator?
-	if parser.mark.column == 0 && buf[pos] == '.' && buf[pos+1] == '.' && buf[pos+2] == '.' && is_blankz(buf, pos+3) {
-		return yaml_parser_fetch_document_indicator(parser, yaml_DOCUMENT_END_TOKEN)
-	}
-
-	// Is it the flow sequence start indicator?
-	if buf[pos] == '[' {
-		return yaml_parser_fetch_flow_collection_start(parser, yaml_FLOW_SEQUENCE_START_TOKEN)
-	}
-
-	// Is it the flow mapping start indicator?
-	if parser.buffer[parser.buffer_pos] == '{' {
-		return yaml_parser_fetch_flow_collection_start(parser, yaml_FLOW_MAPPING_START_TOKEN)
-	}
-
-	// Is it the flow sequence end indicator?
-	if parser.buffer[parser.buffer_pos] == ']' {
-		return yaml_parser_fetch_flow_collection_end(parser,
-			yaml_FLOW_SEQUENCE_END_TOKEN)
-	}
-
-	// Is it the flow mapping end indicator?
-	if parser.buffer[parser.buffer_pos] == '}' {
-		return yaml_parser_fetch_flow_collection_end(parser,
-			yaml_FLOW_MAPPING_END_TOKEN)
-	}
-
-	// Is it the flow entry indicator?
-	if parser.buffer[parser.buffer_pos] == ',' {
-		return yaml_parser_fetch_flow_entry(parser)
-	}
-
-	// Is it the block entry indicator?
-	if parser.buffer[parser.buffer_pos] == '-' && is_blankz(parser.buffer, parser.buffer_pos+1) {
-		return yaml_parser_fetch_block_entry(parser)
-	}
-
-	// Is it the key indicator?
-	if parser.buffer[parser.buffer_pos] == '?' && (parser.flow_level > 0 || is_blankz(parser.buffer, parser.buffer_pos+1)) {
-		return yaml_parser_fetch_key(parser)
-	}
-
-	// Is it the value indicator?
-	if parser.buffer[parser.buffer_pos] == ':' && (parser.flow_level > 0 || is_blankz(parser.buffer, parser.buffer_pos+1)) {
-		return yaml_parser_fetch_value(parser)
-	}
-
-	// Is it an alias?
-	if parser.buffer[parser.buffer_pos] == '*' {
-		return yaml_parser_fetch_anchor(parser, yaml_ALIAS_TOKEN)
-	}
-
-	// Is it an anchor?
-	if parser.buffer[parser.buffer_pos] == '&' {
-		return yaml_parser_fetch_anchor(parser, yaml_ANCHOR_TOKEN)
-	}
-
-	// Is it a tag?
-	if parser.buffer[parser.buffer_pos] == '!' {
-		return yaml_parser_fetch_tag(parser)
-	}
-
-	// Is it a literal scalar?
-	if parser.buffer[parser.buffer_pos] == '|' && parser.flow_level == 0 {
-		return yaml_parser_fetch_block_scalar(parser, true)
-	}
-
-	// Is it a folded scalar?
-	if parser.buffer[parser.buffer_pos] == '>' && parser.flow_level == 0 {
-		return yaml_parser_fetch_block_scalar(parser, false)
-	}
-
-	// Is it a single-quoted scalar?
-	if parser.buffer[parser.buffer_pos] == '\'' {
-		return yaml_parser_fetch_flow_scalar(parser, true)
-	}
-
-	// Is it a double-quoted scalar?
-	if parser.buffer[parser.buffer_pos] == '"' {
-		return yaml_parser_fetch_flow_scalar(parser, false)
-	}
-
-	// Is it a plain scalar?
-	//
-	// A plain scalar may start with any non-blank characters except
-	//
-	//      '-', '?', ':', ',', '[', ']', '{', '}',
-	//      '#', '&', '*', '!', '|', '>', '\'', '\"',
-	//      '%', '@', '`'.
-	//
-	// In the block context (and, for the '-' indicator, in the flow context
-	// too), it may also start with the characters
-	//
-	//      '-', '?', ':'
-	//
-	// if it is followed by a non-space character.
-	//
-	// The last rule is more restrictive than the specification requires.
-	// [Go] Make this logic more reasonable.
-	//switch parser.buffer[parser.buffer_pos] {
-	//case '-', '?', ':', ',', '?', '-', ',', ':', ']', '[', '}', '{', '&', '#', '!', '*', '>', '|', '"', '\'', '@', '%', '-', '`':
-	//}
-	if !(is_blankz(parser.buffer, parser.buffer_pos) || parser.buffer[parser.buffer_pos] == '-' ||
-		parser.buffer[parser.buffer_pos] == '?' || parser.buffer[parser.buffer_pos] == ':' ||
-		parser.buffer[parser.buffer_pos] == ',' || parser.buffer[parser.buffer_pos] == '[' ||
-		parser.buffer[parser.buffer_pos] == ']' || parser.buffer[parser.buffer_pos] == '{' ||
-		parser.buffer[parser.buffer_pos] == '}' || parser.buffer[parser.buffer_pos] == '#' ||
-		parser.buffer[parser.buffer_pos] == '&' || parser.buffer[parser.buffer_pos] == '*' ||
-		parser.buffer[parser.buffer_pos] == '!' || parser.buffer[parser.buffer_pos] == '|' ||
-		parser.buffer[parser.buffer_pos] == '>' || parser.buffer[parser.buffer_pos] == '\'' ||
-		parser.buffer[parser.buffer_pos] == '"' || parser.buffer[parser.buffer_pos] == '%' ||
-		parser.buffer[parser.buffer_pos] == '@' || parser.buffer[parser.buffer_pos] == '`') ||
-		(parser.buffer[parser.buffer_pos] == '-' && !is_blank(parser.buffer, parser.buffer_pos+1)) ||
-		(parser.flow_level == 0 &&
-			(parser.buffer[parser.buffer_pos] == '?' || parser.buffer[parser.buffer_pos] == ':') &&
-			!is_blankz(parser.buffer, parser.buffer_pos+1)) {
-		return yaml_parser_fetch_plain_scalar(parser)
-	}
-
-	// If we don't determine the token type so far, it is an error.
-	return yaml_parser_set_scanner_error(parser,
-		"while scanning for the next token", parser.mark,
-		"found character that cannot start any token")
-}
-
-// Check the list of potential simple keys and remove the positions that
-// cannot contain simple keys anymore.
-func yaml_parser_stale_simple_keys(parser *yaml_parser_t) bool {
-	// Check for a potential simple key for each flow level.
-	for i := range parser.simple_keys {
-		simple_key := &parser.simple_keys[i]
-
-		// The specification requires that a simple key
-		//
-		//  - is limited to a single line,
-		//  - is shorter than 1024 characters.
-		if simple_key.possible && (simple_key.mark.line < parser.mark.line || simple_key.mark.index+1024 < parser.mark.index) {
-
-			// Check if the potential simple key to be removed is required.
-			if simple_key.required {
-				return yaml_parser_set_scanner_error(parser,
-					"while scanning a simple key", simple_key.mark,
-					"could not find expected ':'")
-			}
-			simple_key.possible = false
-		}
-	}
-	return true
-}
-
-// Check if a simple key may start at the current position and add it if
-// needed.
-func yaml_parser_save_simple_key(parser *yaml_parser_t) bool {
-	// A simple key is required at the current position if the scanner is in
-	// the block context and the current column coincides with the indentation
-	// level.
-
-	required := parser.flow_level == 0 && parser.indent == parser.mark.column
-
-	// A simple key is required only when it is the first token in the current
-	// line.  Therefore it is always allowed.  But we add a check anyway.
-	if required && !parser.simple_key_allowed {
-		panic("should not happen")
-	}
-
-	//
-	// If the current position may start a simple key, save it.
-	//
-	if parser.simple_key_allowed {
-		simple_key := yaml_simple_key_t{
-			possible:     true,
-			required:     required,
-			token_number: parser.tokens_parsed + (len(parser.tokens) - parser.tokens_head),
-		}
-		simple_key.mark = parser.mark
-
-		if !yaml_parser_remove_simple_key(parser) {
-			return false
-		}
-		parser.simple_keys[len(parser.simple_keys)-1] = simple_key
-	}
-	return true
-}
-
-// Remove a potential simple key at the current flow level.
-func yaml_parser_remove_simple_key(parser *yaml_parser_t) bool {
-	i := len(parser.simple_keys) - 1
-	if parser.simple_keys[i].possible {
-		// If the key is required, it is an error.
-		if parser.simple_keys[i].required {
-			return yaml_parser_set_scanner_error(parser,
-				"while scanning a simple key", parser.simple_keys[i].mark,
-				"could not find expected ':'")
-		}
-	}
-	// Remove the key from the stack.
-	parser.simple_keys[i].possible = false
-	return true
-}
-
-// Increase the flow level and resize the simple key list if needed.
-func yaml_parser_increase_flow_level(parser *yaml_parser_t) bool {
-	// Reset the simple key on the next level.
-	parser.simple_keys = append(parser.simple_keys, yaml_simple_key_t{})
-
-	// Increase the flow level.
-	parser.flow_level++
-	return true
-}
-
-// Decrease the flow level.
-func yaml_parser_decrease_flow_level(parser *yaml_parser_t) bool {
-	if parser.flow_level > 0 {
-		parser.flow_level--
-		parser.simple_keys = parser.simple_keys[:len(parser.simple_keys)-1]
-	}
-	return true
-}
-
-// Push the current indentation level to the stack and set the new level
-// the current column is greater than the indentation level.  In this case,
-// append or insert the specified token into the token queue.
-func yaml_parser_roll_indent(parser *yaml_parser_t, column, number int, typ yaml_token_type_t, mark yaml_mark_t) bool {
-	// In the flow context, do nothing.
-	if parser.flow_level > 0 {
-		return true
-	}
-
-	if parser.indent < column {
-		// Push the current indentation level to the stack and set the new
-		// indentation level.
-		parser.indents = append(parser.indents, parser.indent)
-		parser.indent = column
-
-		// Create a token and insert it into the queue.
-		token := yaml_token_t{
-			typ:        typ,
-			start_mark: mark,
-			end_mark:   mark,
-		}
-		if number > -1 {
-			number -= parser.tokens_parsed
-		}
-		yaml_insert_token(parser, number, &token)
-	}
-	return true
-}
-
-// Pop indentation levels from the indents stack until the current level
-// becomes less or equal to the column.  For each intendation level, append
-// the BLOCK-END token.
-func yaml_parser_unroll_indent(parser *yaml_parser_t, column int) bool {
-	// In the flow context, do nothing.
-	if parser.flow_level > 0 {
-		return true
-	}
-
-	// Loop through the intendation levels in the stack.
-	for parser.indent > column {
-		// Create a token and append it to the queue.
-		token := yaml_token_t{
-			typ:        yaml_BLOCK_END_TOKEN,
-			start_mark: parser.mark,
-			end_mark:   parser.mark,
-		}
-		yaml_insert_token(parser, -1, &token)
-
-		// Pop the indentation level.
-		parser.indent = parser.indents[len(parser.indents)-1]
-		parser.indents = parser.indents[:len(parser.indents)-1]
-	}
-	return true
-}
-
-// Initialize the scanner and produce the STREAM-START token.
-func yaml_parser_fetch_stream_start(parser *yaml_parser_t) bool {
-
-	// Set the initial indentation.
-	parser.indent = -1
-
-	// Initialize the simple key stack.
-	parser.simple_keys = append(parser.simple_keys, yaml_simple_key_t{})
-
-	// A simple key is allowed at the beginning of the stream.
-	parser.simple_key_allowed = true
-
-	// We have started.
-	parser.stream_start_produced = true
-
-	// Create the STREAM-START token and append it to the queue.
-	token := yaml_token_t{
-		typ:        yaml_STREAM_START_TOKEN,
-		start_mark: parser.mark,
-		end_mark:   parser.mark,
-		encoding:   parser.encoding,
-	}
-	yaml_insert_token(parser, -1, &token)
-	return true
-}
-
-// Produce the STREAM-END token and shut down the scanner.
-func yaml_parser_fetch_stream_end(parser *yaml_parser_t) bool {
-
-	// Force new line.
-	if parser.mark.column != 0 {
-		parser.mark.column = 0
-		parser.mark.line++
-	}
-
-	// Reset the indentation level.
-	if !yaml_parser_unroll_indent(parser, -1) {
-		return false
-	}
-
-	// Reset simple keys.
-	if !yaml_parser_remove_simple_key(parser) {
-		return false
-	}
-
-	parser.simple_key_allowed = false
-
-	// Create the STREAM-END token and append it to the queue.
-	token := yaml_token_t{
-		typ:        yaml_STREAM_END_TOKEN,
-		start_mark: parser.mark,
-		end_mark:   parser.mark,
-	}
-	yaml_insert_token(parser, -1, &token)
-	return true
-}
-
-// Produce a VERSION-DIRECTIVE or TAG-DIRECTIVE token.
-func yaml_parser_fetch_directive(parser *yaml_parser_t) bool {
-	// Reset the indentation level.
-	if !yaml_parser_unroll_indent(parser, -1) {
-		return false
-	}
-
-	// Reset simple keys.
-	if !yaml_parser_remove_simple_key(parser) {
-		return false
-	}
-
-	parser.simple_key_allowed = false
-
-	// Create the YAML-DIRECTIVE or TAG-DIRECTIVE token.
-	token := yaml_token_t{}
-	if !yaml_parser_scan_directive(parser, &token) {
-		return false
-	}
-	// Append the token to the queue.
-	yaml_insert_token(parser, -1, &token)
-	return true
-}
-
-// Produce the DOCUMENT-START or DOCUMENT-END token.
-func yaml_parser_fetch_document_indicator(parser *yaml_parser_t, typ yaml_token_type_t) bool {
-	// Reset the indentation level.
-	if !yaml_parser_unroll_indent(parser, -1) {
-		return false
-	}
-
-	// Reset simple keys.
-	if !yaml_parser_remove_simple_key(parser) {
-		return false
-	}
-
-	parser.simple_key_allowed = false
-
-	// Consume the token.
-	start_mark := parser.mark
-
-	skip(parser)
-	skip(parser)
-	skip(parser)
-
-	end_mark := parser.mark
-
-	// Create the DOCUMENT-START or DOCUMENT-END token.
-	token := yaml_token_t{
-		typ:        typ,
-		start_mark: start_mark,
-		end_mark:   end_mark,
-	}
-	// Append the token to the queue.
-	yaml_insert_token(parser, -1, &token)
-	return true
-}
-
-// Produce the FLOW-SEQUENCE-START or FLOW-MAPPING-START token.
-func yaml_parser_fetch_flow_collection_start(parser *yaml_parser_t, typ yaml_token_type_t) bool {
-	// The indicators '[' and '{' may start a simple key.
-	if !yaml_parser_save_simple_key(parser) {
-		return false
-	}
-
-	// Increase the flow level.
-	if !yaml_parser_increase_flow_level(parser) {
-		return false
-	}
-
-	// A simple key may follow the indicators '[' and '{'.
-	parser.simple_key_allowed = true
-
-	// Consume the token.
-	start_mark := parser.mark
-	skip(parser)
-	end_mark := parser.mark
-
-	// Create the FLOW-SEQUENCE-START of FLOW-MAPPING-START token.
-	token := yaml_token_t{
-		typ:        typ,
-		start_mark: start_mark,
-		end_mark:   end_mark,
-	}
-	// Append the token to the queue.
-	yaml_insert_token(parser, -1, &token)
-	return true
-}
-
-// Produce the FLOW-SEQUENCE-END or FLOW-MAPPING-END token.
-func yaml_parser_fetch_flow_collection_end(parser *yaml_parser_t, typ yaml_token_type_t) bool {
-	// Reset any potential simple key on the current flow level.
-	if !yaml_parser_remove_simple_key(parser) {
-		return false
-	}
-
-	// Decrease the flow level.
-	if !yaml_parser_decrease_flow_level(parser) {
-		return false
-	}
-
-	// No simple keys after the indicators ']' and '}'.
-	parser.simple_key_allowed = false
-
-	// Consume the token.
-
-	start_mark := parser.mark
-	skip(parser)
-	end_mark := parser.mark
-
-	// Create the FLOW-SEQUENCE-END of FLOW-MAPPING-END token.
-	token := yaml_token_t{
-		typ:        typ,
-		start_mark: start_mark,
-		end_mark:   end_mark,
-	}
-	// Append the token to the queue.
-	yaml_insert_token(parser, -1, &token)
-	return true
-}
-
-// Produce the FLOW-ENTRY token.
-func yaml_parser_fetch_flow_entry(parser *yaml_parser_t) bool {
-	// Reset any potential simple keys on the current flow level.
-	if !yaml_parser_remove_simple_key(parser) {
-		return false
-	}
-
-	// Simple keys are allowed after ','.
-	parser.simple_key_allowed = true
-
-	// Consume the token.
-	start_mark := parser.mark
-	skip(parser)
-	end_mark := parser.mark
-
-	// Create the FLOW-ENTRY token and append it to the queue.
-	token := yaml_token_t{
-		typ:        yaml_FLOW_ENTRY_TOKEN,
-		start_mark: start_mark,
-		end_mark:   end_mark,
-	}
-	yaml_insert_token(parser, -1, &token)
-	return true
-}
-
-// Produce the BLOCK-ENTRY token.
-func yaml_parser_fetch_block_entry(parser *yaml_parser_t) bool {
-	// Check if the scanner is in the block context.
-	if parser.flow_level == 0 {
-		// Check if we are allowed to start a new entry.
-		if !parser.simple_key_allowed {
-			return yaml_parser_set_scanner_error(parser, "", parser.mark,
-				"block sequence entries are not allowed in this context")
-		}
-		// Add the BLOCK-SEQUENCE-START token if needed.
-		if !yaml_parser_roll_indent(parser, parser.mark.column, -1, yaml_BLOCK_SEQUENCE_START_TOKEN, parser.mark) {
-			return false
-		}
-	} else {
-		// It is an error for the '-' indicator to occur in the flow context,
-		// but we let the Parser detect and report about it because the Parser
-		// is able to point to the context.
-	}
-
-	// Reset any potential simple keys on the current flow level.
-	if !yaml_parser_remove_simple_key(parser) {
-		return false
-	}
-
-	// Simple keys are allowed after '-'.
-	parser.simple_key_allowed = true
-
-	// Consume the token.
-	start_mark := parser.mark
-	skip(parser)
-	end_mark := parser.mark
-
-	// Create the BLOCK-ENTRY token and append it to the queue.
-	token := yaml_token_t{
-		typ:        yaml_BLOCK_ENTRY_TOKEN,
-		start_mark: start_mark,
-		end_mark:   end_mark,
-	}
-	yaml_insert_token(parser, -1, &token)
-	return true
-}
-
-// Produce the KEY token.
-func yaml_parser_fetch_key(parser *yaml_parser_t) bool {
-
-	// In the block context, additional checks are required.
-	if parser.flow_level == 0 {
-		// Check if we are allowed to start a new key (not nessesary simple).
-		if !parser.simple_key_allowed {
-			return yaml_parser_set_scanner_error(parser, "", parser.mark,
-				"mapping keys are not allowed in this context")
-		}
-		// Add the BLOCK-MAPPING-START token if needed.
-		if !yaml_parser_roll_indent(parser, parser.mark.column, -1, yaml_BLOCK_MAPPING_START_TOKEN, parser.mark) {
-			return false
-		}
-	}
-
-	// Reset any potential simple keys on the current flow level.
-	if !yaml_parser_remove_simple_key(parser) {
-		return false
-	}
-
-	// Simple keys are allowed after '?' in the block context.
-	parser.simple_key_allowed = parser.flow_level == 0
-
-	// Consume the token.
-	start_mark := parser.mark
-	skip(parser)
-	end_mark := parser.mark
-
-	// Create the KEY token and append it to the queue.
-	token := yaml_token_t{
-		typ:        yaml_KEY_TOKEN,
-		start_mark: start_mark,
-		end_mark:   end_mark,
-	}
-	yaml_insert_token(parser, -1, &token)
-	return true
-}
-
-// Produce the VALUE token.
-func yaml_parser_fetch_value(parser *yaml_parser_t) bool {
-
-	simple_key := &parser.simple_keys[len(parser.simple_keys)-1]
-
-	// Have we found a simple key?
-	if simple_key.possible {
-		// Create the KEY token and insert it into the queue.
-		token := yaml_token_t{
-			typ:        yaml_KEY_TOKEN,
-			start_mark: simple_key.mark,
-			end_mark:   simple_key.mark,
-		}
-		yaml_insert_token(parser, simple_key.token_number-parser.tokens_parsed, &token)
-
-		// In the block context, we may need to add the BLOCK-MAPPING-START token.
-		if !yaml_parser_roll_indent(parser, simple_key.mark.column,
-			simple_key.token_number,
-			yaml_BLOCK_MAPPING_START_TOKEN, simple_key.mark) {
-			return false
-		}
-
-		// Remove the simple key.
-		simple_key.possible = false
-
-		// A simple key cannot follow another simple key.
-		parser.simple_key_allowed = false
-
-	} else {
-		// The ':' indicator follows a complex key.
-
-		// In the block context, extra checks are required.
-		if parser.flow_level == 0 {
-
-			// Check if we are allowed to start a complex value.
-			if !parser.simple_key_allowed {
-				return yaml_parser_set_scanner_error(parser, "", parser.mark,
-					"mapping values are not allowed in this context")
-			}
-
-			// Add the BLOCK-MAPPING-START token if needed.
-			if !yaml_parser_roll_indent(parser, parser.mark.column, -1, yaml_BLOCK_MAPPING_START_TOKEN, parser.mark) {
-				return false
-			}
-		}
-
-		// Simple keys after ':' are allowed in the block context.
-		parser.simple_key_allowed = parser.flow_level == 0
-	}
-
-	// Consume the token.
-	start_mark := parser.mark
-	skip(parser)
-	end_mark := parser.mark
-
-	// Create the VALUE token and append it to the queue.
-	token := yaml_token_t{
-		typ:        yaml_VALUE_TOKEN,
-		start_mark: start_mark,
-		end_mark:   end_mark,
-	}
-	yaml_insert_token(parser, -1, &token)
-	return true
-}
-
-// Produce the ALIAS or ANCHOR token.
-func yaml_parser_fetch_anchor(parser *yaml_parser_t, typ yaml_token_type_t) bool {
-	// An anchor or an alias could be a simple key.
-	if !yaml_parser_save_simple_key(parser) {
-		return false
-	}
-
-	// A simple key cannot follow an anchor or an alias.
-	parser.simple_key_allowed = false
-
-	// Create the ALIAS or ANCHOR token and append it to the queue.
-	var token yaml_token_t
-	if !yaml_parser_scan_anchor(parser, &token, typ) {
-		return false
-	}
-	yaml_insert_token(parser, -1, &token)
-	return true
-}
-
-// Produce the TAG token.
-func yaml_parser_fetch_tag(parser *yaml_parser_t) bool {
-	// A tag could be a simple key.
-	if !yaml_parser_save_simple_key(parser) {
-		return false
-	}
-
-	// A simple key cannot follow a tag.
-	parser.simple_key_allowed = false
-
-	// Create the TAG token and append it to the queue.
-	var token yaml_token_t
-	if !yaml_parser_scan_tag(parser, &token) {
-		return false
-	}
-	yaml_insert_token(parser, -1, &token)
-	return true
-}
-
-// Produce the SCALAR(...,literal) or SCALAR(...,folded) tokens.
-func yaml_parser_fetch_block_scalar(parser *yaml_parser_t, literal bool) bool {
-	// Remove any potential simple keys.
-	if !yaml_parser_remove_simple_key(parser) {
-		return false
-	}
-
-	// A simple key may follow a block scalar.
-	parser.simple_key_allowed = true
-
-	// Create the SCALAR token and append it to the queue.
-	var token yaml_token_t
-	if !yaml_parser_scan_block_scalar(parser, &token, literal) {
-		return false
-	}
-	yaml_insert_token(parser, -1, &token)
-	return true
-}
-
-// Produce the SCALAR(...,single-quoted) or SCALAR(...,double-quoted) tokens.
-func yaml_parser_fetch_flow_scalar(parser *yaml_parser_t, single bool) bool {
-	// A plain scalar could be a simple key.
-	if !yaml_parser_save_simple_key(parser) {
-		return false
-	}
-
-	// A simple key cannot follow a flow scalar.
-	parser.simple_key_allowed = false
-
-	// Create the SCALAR token and append it to the queue.
-	var token yaml_token_t
-	if !yaml_parser_scan_flow_scalar(parser, &token, single) {
-		return false
-	}
-	yaml_insert_token(parser, -1, &token)
-	return true
-}
-
-// Produce the SCALAR(...,plain) token.
-func yaml_parser_fetch_plain_scalar(parser *yaml_parser_t) bool {
-	// A plain scalar could be a simple key.
-	if !yaml_parser_save_simple_key(parser) {
-		return false
-	}
-
-	// A simple key cannot follow a flow scalar.
-	parser.simple_key_allowed = false
-
-	// Create the SCALAR token and append it to the queue.
-	var token yaml_token_t
-	if !yaml_parser_scan_plain_scalar(parser, &token) {
-		return false
-	}
-	yaml_insert_token(parser, -1, &token)
-	return true
-}
-
-// Eat whitespaces and comments until the next token is found.
-func yaml_parser_scan_to_next_token(parser *yaml_parser_t) bool {
-
-	// Until the next token is not found.
-	for {
-		// Allow the BOM mark to start a line.
-		if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
-			return false
-		}
-		if parser.mark.column == 0 && is_bom(parser.buffer, parser.buffer_pos) {
-			skip(parser)
-		}
-
-		// Eat whitespaces.
-		// Tabs are allowed:
-		//  - in the flow context
-		//  - in the block context, but not at the beginning of the line or
-		//  after '-', '?', or ':' (complex value).
-		if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
-			return false
-		}
-
-		for parser.buffer[parser.buffer_pos] == ' ' || ((parser.flow_level > 0 || !parser.simple_key_allowed) && parser.buffer[parser.buffer_pos] == '\t') {
-			skip(parser)
-			if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
-				return false
-			}
-		}
-
-		// Eat a comment until a line break.
-		if parser.buffer[parser.buffer_pos] == '#' {
-			for !is_breakz(parser.buffer, parser.buffer_pos) {
-				skip(parser)
-				if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
-					return false
-				}
-			}
-		}
-
-		// If it is a line break, eat it.
-		if is_break(parser.buffer, parser.buffer_pos) {
-			if parser.unread < 2 && !yaml_parser_update_buffer(parser, 2) {
-				return false
-			}
-			skip_line(parser)
-
-			// In the block context, a new line may start a simple key.
-			if parser.flow_level == 0 {
-				parser.simple_key_allowed = true
-			}
-		} else {
-			break // We have found a token.
-		}
-	}
-
-	return true
-}
-
-// Scan a YAML-DIRECTIVE or TAG-DIRECTIVE token.
-//
-// Scope:
-//      %YAML    1.1    # a comment \n
-//      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-//      %TAG    !yaml!  tag:yaml.org,2002:  \n
-//      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-//
-func yaml_parser_scan_directive(parser *yaml_parser_t, token *yaml_token_t) bool {
-	// Eat '%'.
-	start_mark := parser.mark
-	skip(parser)
-
-	// Scan the directive name.
-	var name []byte
-	if !yaml_parser_scan_directive_name(parser, start_mark, &name) {
-		return false
-	}
-
-	// Is it a YAML directive?
-	if bytes.Equal(name, []byte("YAML")) {
-		// Scan the VERSION directive value.
-		var major, minor int8
-		if !yaml_parser_scan_version_directive_value(parser, start_mark, &major, &minor) {
-			return false
-		}
-		end_mark := parser.mark
-
-		// Create a VERSION-DIRECTIVE token.
-		*token = yaml_token_t{
-			typ:        yaml_VERSION_DIRECTIVE_TOKEN,
-			start_mark: start_mark,
-			end_mark:   end_mark,
-			major:      major,
-			minor:      minor,
-		}
-
-		// Is it a TAG directive?
-	} else if bytes.Equal(name, []byte("TAG")) {
-		// Scan the TAG directive value.
-		var handle, prefix []byte
-		if !yaml_parser_scan_tag_directive_value(parser, start_mark, &handle, &prefix) {
-			return false
-		}
-		end_mark := parser.mark
-
-		// Create a TAG-DIRECTIVE token.
-		*token = yaml_token_t{
-			typ:        yaml_TAG_DIRECTIVE_TOKEN,
-			start_mark: start_mark,
-			end_mark:   end_mark,
-			value:      handle,
-			prefix:     prefix,
-		}
-
-		// Unknown directive.
-	} else {
-		yaml_parser_set_scanner_error(parser, "while scanning a directive",
-			start_mark, "found uknown directive name")
-		return false
-	}
-
-	// Eat the rest of the line including any comments.
-	if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
-		return false
-	}
-
-	for is_blank(parser.buffer, parser.buffer_pos) {
-		skip(parser)
-		if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
-			return false
-		}
-	}
-
-	if parser.buffer[parser.buffer_pos] == '#' {
-		for !is_breakz(parser.buffer, parser.buffer_pos) {
-			skip(parser)
-			if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
-				return false
-			}
-		}
-	}
-
-	// Check if we are at the end of the line.
-	if !is_breakz(parser.buffer, parser.buffer_pos) {
-		yaml_parser_set_scanner_error(parser, "while scanning a directive",
-			start_mark, "did not find expected comment or line break")
-		return false
-	}
-
-	// Eat a line break.
-	if is_break(parser.buffer, parser.buffer_pos) {
-		if parser.unread < 2 && !yaml_parser_update_buffer(parser, 2) {
-			return false
-		}
-		skip_line(parser)
-	}
-
-	return true
-}
-
-// Scan the directive name.
-//
-// Scope:
-//      %YAML   1.1     # a comment \n
-//       ^^^^
-//      %TAG    !yaml!  tag:yaml.org,2002:  \n
-//       ^^^
-//
-func yaml_parser_scan_directive_name(parser *yaml_parser_t, start_mark yaml_mark_t, name *[]byte) bool {
-	// Consume the directive name.
-	if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
-		return false
-	}
-
-	var s []byte
-	for is_alpha(parser.buffer, parser.buffer_pos) {
-		s = read(parser, s)
-		if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
-			return false
-		}
-	}
-
-	// Check if the name is empty.
-	if len(s) == 0 {
-		yaml_parser_set_scanner_error(parser, "while scanning a directive",
-			start_mark, "could not find expected directive name")
-		return false
-	}
-
-	// Check for an blank character after the name.
-	if !is_blankz(parser.buffer, parser.buffer_pos) {
-		yaml_parser_set_scanner_error(parser, "while scanning a directive",
-			start_mark, "found unexpected non-alphabetical character")
-		return false
-	}
-	*name = s
-	return true
-}
-
-// Scan the value of VERSION-DIRECTIVE.
-//
-// Scope:
-//      %YAML   1.1     # a comment \n
-//           ^^^^^^
-func yaml_parser_scan_version_directive_value(parser *yaml_parser_t, start_mark yaml_mark_t, major, minor *int8) bool {
-	// Eat whitespaces.
-	if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
-		return false
-	}
-	for is_blank(parser.buffer, parser.buffer_pos) {
-		skip(parser)
-		if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
-			return false
-		}
-	}
-
-	// Consume the major version number.
-	if !yaml_parser_scan_version_directive_number(parser, start_mark, major) {
-		return false
-	}
-
-	// Eat '.'.
-	if parser.buffer[parser.buffer_pos] != '.' {
-		return yaml_parser_set_scanner_error(parser, "while scanning a %YAML directive",
-			start_mark, "did not find expected digit or '.' character")
-	}
-
-	skip(parser)
-
-	// Consume the minor version number.
-	if !yaml_parser_scan_version_directive_number(parser, start_mark, minor) {
-		return false
-	}
-	return true
-}
-
-const max_number_length = 2
-
-// Scan the version number of VERSION-DIRECTIVE.
-//
-// Scope:
-//      %YAML   1.1     # a comment \n
-//              ^
-//      %YAML   1.1     # a comment \n
-//                ^
-func yaml_parser_scan_version_directive_number(parser *yaml_parser_t, start_mark yaml_mark_t, number *int8) bool {
-
-	// Repeat while the next character is digit.
-	if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
-		return false
-	}
-	var value, length int8
-	for is_digit(parser.buffer, parser.buffer_pos) {
-		// Check if the number is too long.
-		length++
-		if length > max_number_length {
-			return yaml_parser_set_scanner_error(parser, "while scanning a %YAML directive",
-				start_mark, "found extremely long version number")
-		}
-		value = value*10 + int8(as_digit(parser.buffer, parser.buffer_pos))
-		skip(parser)
-		if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
-			return false
-		}
-	}
-
-	// Check if the number was present.
-	if length == 0 {
-		return yaml_parser_set_scanner_error(parser, "while scanning a %YAML directive",
-			start_mark, "did not find expected version number")
-	}
-	*number = value
-	return true
-}
-
-// Scan the value of a TAG-DIRECTIVE token.
-//
-// Scope:
-//      %TAG    !yaml!  tag:yaml.org,2002:  \n
-//          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-//
-func yaml_parser_scan_tag_directive_value(parser *yaml_parser_t, start_mark yaml_mark_t, handle, prefix *[]byte) bool {
-	var handle_value, prefix_value []byte
-
-	// Eat whitespaces.
-	if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
-		return false
-	}
-
-	for is_blank(parser.buffer, parser.buffer_pos) {
-		skip(parser)
-		if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
-			return false
-		}
-	}
-
-	// Scan a handle.
-	if !yaml_parser_scan_tag_handle(parser, true, start_mark, &handle_value) {
-		return false
-	}
-
-	// Expect a whitespace.
-	if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
-		return false
-	}
-	if !is_blank(parser.buffer, parser.buffer_pos) {
-		yaml_parser_set_scanner_error(parser, "while scanning a %TAG directive",
-			start_mark, "did not find expected whitespace")
-		return false
-	}
-
-	// Eat whitespaces.
-	for is_blank(parser.buffer, parser.buffer_pos) {
-		skip(parser)
-		if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
-			return false
-		}
-	}
-
-	// Scan a prefix.
-	if !yaml_parser_scan_tag_uri(parser, true, nil, start_mark, &prefix_value) {
-		return false
-	}
-
-	// Expect a whitespace or line break.
-	if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
-		return false
-	}
-	if !is_blankz(parser.buffer, parser.buffer_pos) {
-		yaml_parser_set_scanner_error(parser, "while scanning a %TAG directive",
-			start_mark, "did not find expected whitespace or line break")
-		return false
-	}
-
-	*handle = handle_value
-	*prefix = prefix_value
-	return true
-}
-
-func yaml_parser_scan_anchor(parser *yaml_parser_t, token *yaml_token_t, typ yaml_token_type_t) bool {
-	var s []byte
-
-	// Eat the indicator character.
-	start_mark := parser.mark
-	skip(parser)
-
-	// Consume the value.
-	if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
-		return false
-	}
-
-	for is_alpha(parser.buffer, parser.buffer_pos) {
-		s = read(parser, s)
-		if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
-			return false
-		}
-	}
-
-	end_mark := parser.mark
-
-	/*
-	 * Check if length of the anchor is greater than 0 and it is followed by
-	 * a whitespace character or one of the indicators:
-	 *
-	 *      '?', ':', ',', ']', '}', '%', '@', '`'.
-	 */
-
-	if len(s) == 0 ||
-		!(is_blankz(parser.buffer, parser.buffer_pos) || parser.buffer[parser.buffer_pos] == '?' ||
-			parser.buffer[parser.buffer_pos] == ':' || parser.buffer[parser.buffer_pos] == ',' ||
-			parser.buffer[parser.buffer_pos] == ']' || parser.buffer[parser.buffer_pos] == '}' ||
-			parser.buffer[parser.buffer_pos] == '%' || parser.buffer[parser.buffer_pos] == '@' ||
-			parser.buffer[parser.buffer_pos] == '`') {
-		context := "while scanning an alias"
-		if typ == yaml_ANCHOR_TOKEN {
-			context = "while scanning an anchor"
-		}
-		yaml_parser_set_scanner_error(parser, context, start_mark,
-			"did not find expected alphabetic or numeric character")
-		return false
-	}
-
-	// Create a token.
-	*token = yaml_token_t{
-		typ:        typ,
-		start_mark: start_mark,
-		end_mark:   end_mark,
-		value:      s,
-	}
-
-	return true
-}
-
-/*
- * Scan a TAG token.
- */
-
-func yaml_parser_scan_tag(parser *yaml_parser_t, token *yaml_token_t) bool {
-	var handle, suffix []byte
-
-	start_mark := parser.mark
-
-	// Check if the tag is in the canonical form.
-	if parser.unread < 2 && !yaml_parser_update_buffer(parser, 2) {
-		return false
-	}
-
-	if parser.buffer[parser.buffer_pos+1] == '<' {
-		// Keep the handle as ''
-
-		// Eat '!<'
-		skip(parser)
-		skip(parser)
-
-		// Consume the tag value.
-		if !yaml_parser_scan_tag_uri(parser, false, nil, start_mark, &suffix) {
-			return false
-		}
-
-		// Check for '>' and eat it.
-		if parser.buffer[parser.buffer_pos] != '>' {
-			yaml_parser_set_scanner_error(parser, "while scanning a tag",
-				start_mark, "did not find the expected '>'")
-			return false
-		}
-
-		skip(parser)
-	} else {
-		// The tag has either the '!suffix' or the '!handle!suffix' form.
-
-		// First, try to scan a handle.
-		if !yaml_parser_scan_tag_handle(parser, false, start_mark, &handle) {
-			return false
-		}
-
-		// Check if it is, indeed, handle.
-		if handle[0] == '!' && len(handle) > 1 && handle[len(handle)-1] == '!' {
-			// Scan the suffix now.
-			if !yaml_parser_scan_tag_uri(parser, false, nil, start_mark, &suffix) {
-				return false
-			}
-		} else {
-			// It wasn't a handle after all.  Scan the rest of the tag.
-			if !yaml_parser_scan_tag_uri(parser, false, handle, start_mark, &suffix) {
-				return false
-			}
-
-			// Set the handle to '!'.
-			handle = []byte{'!'}
-
-			// A special case: the '!' tag.  Set the handle to '' and the
-			// suffix to '!'.
-			if len(suffix) == 0 {
-				handle, suffix = suffix, handle
-			}
-		}
-	}
-
-	// Check the character which ends the tag.
-	if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
-		return false
-	}
-	if !is_blankz(parser.buffer, parser.buffer_pos) {
-		yaml_parser_set_scanner_error(parser, "while scanning a tag",
-			start_mark, "did not find expected whitespace or line break")
-		return false
-	}
-
-	end_mark := parser.mark
-
-	// Create a token.
-	*token = yaml_token_t{
-		typ:        yaml_TAG_TOKEN,
-		start_mark: start_mark,
-		end_mark:   end_mark,
-		value:      handle,
-		suffix:     suffix,
-	}
-	return true
-}
-
-// Scan a tag handle.
-func yaml_parser_scan_tag_handle(parser *yaml_parser_t, directive bool, start_mark yaml_mark_t, handle *[]byte) bool {
-	// Check the initial '!' character.
-	if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
-		return false
-	}
-	if parser.buffer[parser.buffer_pos] != '!' {
-		yaml_parser_set_scanner_tag_error(parser, directive,
-			start_mark, "did not find expected '!'")
-		return false
-	}
-
-	var s []byte
-
-	// Copy the '!' character.
-	s = read(parser, s)
-
-	// Copy all subsequent alphabetical and numerical characters.
-	if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
-		return false
-	}
-	for is_alpha(parser.buffer, parser.buffer_pos) {
-		s = read(parser, s)
-		if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
-			return false
-		}
-	}
-
-	// Check if the trailing character is '!' and copy it.
-	if parser.buffer[parser.buffer_pos] == '!' {
-		s = read(parser, s)
-	} else {
-		// It's either the '!' tag or not really a tag handle.  If it's a %TAG
-		// directive, it's an error.  If it's a tag token, it must be a part of URI.
-		if directive && !(s[0] == '!' && s[1] == 0) {
-			yaml_parser_set_scanner_tag_error(parser, directive,
-				start_mark, "did not find expected '!'")
-			return false
-		}
-	}
-
-	*handle = s
-	return true
-}
-
-// Scan a tag.
-func yaml_parser_scan_tag_uri(parser *yaml_parser_t, directive bool, head []byte, start_mark yaml_mark_t, uri *[]byte) bool {
-	//size_t length = head ? strlen((char *)head) : 0
-	var s []byte
-
-	// Copy the head if needed.
-	//
-	// Note that we don't copy the leading '!' character.
-	if len(head) > 1 {
-		s = append(s, head[1:]...)
-	}
-
-	// Scan the tag.
-	if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
-		return false
-	}
-
-	// The set of characters that may appear in URI is as follows:
-	//
-	//      '0'-'9', 'A'-'Z', 'a'-'z', '_', '-', ';', '/', '?', ':', '@', '&',
-	//      '=', '+', '$', ',', '.', '!', '~', '*', '\'', '(', ')', '[', ']',
-	//      '%'.
-	// [Go] Convert this into more reasonable logic.
-	for is_alpha(parser.buffer, parser.buffer_pos) || parser.buffer[parser.buffer_pos] == ';' ||
-		parser.buffer[parser.buffer_pos] == '/' || parser.buffer[parser.buffer_pos] == '?' ||
-		parser.buffer[parser.buffer_pos] == ':' || parser.buffer[parser.buffer_pos] == '@' ||
-		parser.buffer[parser.buffer_pos] == '&' || parser.buffer[parser.buffer_pos] == '=' ||
-		parser.buffer[parser.buffer_pos] == '+' || parser.buffer[parser.buffer_pos] == '$' ||
-		parser.buffer[parser.buffer_pos] == ',' || parser.buffer[parser.buffer_pos] == '.' ||
-		parser.buffer[parser.buffer_pos] == '!' || parser.buffer[parser.buffer_pos] == '~' ||
-		parser.buffer[parser.buffer_pos] == '*' || parser.buffer[parser.buffer_pos] == '\'' ||
-		parser.buffer[parser.buffer_pos] == '(' || parser.buffer[parser.buffer_pos] == ')' ||
-		parser.buffer[parser.buffer_pos] == '[' || parser.buffer[parser.buffer_pos] == ']' ||
-		parser.buffer[parser.buffer_pos] == '%' {
-		// Check if it is a URI-escape sequence.
-		if parser.buffer[parser.buffer_pos] == '%' {
-			if !yaml_parser_scan_uri_escapes(parser, directive, start_mark, &s) {
-				return false
-			}
-		} else {
-			s = read(parser, s)
-		}
-		if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
-			return false
-		}
-	}
-
-	// Check if the tag is non-empty.
-	if len(s) == 0 {
-		yaml_parser_set_scanner_tag_error(parser, directive,
-			start_mark, "did not find expected tag URI")
-		return false
-	}
-	*uri = s
-	return true
-}
-
-// Decode an URI-escape sequence corresponding to a single UTF-8 character.
-func yaml_parser_scan_uri_escapes(parser *yaml_parser_t, directive bool, start_mark yaml_mark_t, s *[]byte) bool {
-
-	// Decode the required number of characters.
-	w := 1024
-	for w > 0 {
-		// Check for a URI-escaped octet.
-		if parser.unread < 3 && !yaml_parser_update_buffer(parser, 3) {
-			return false
-		}
-
-		if !(parser.buffer[parser.buffer_pos] == '%' &&
-			is_hex(parser.buffer, parser.buffer_pos+1) &&
-			is_hex(parser.buffer, parser.buffer_pos+2)) {
-			return yaml_parser_set_scanner_tag_error(parser, directive,
-				start_mark, "did not find URI escaped octet")
-		}
-
-		// Get the octet.
-		octet := byte((as_hex(parser.buffer, parser.buffer_pos+1) << 4) + as_hex(parser.buffer, parser.buffer_pos+2))
-
-		// If it is the leading octet, determine the length of the UTF-8 sequence.
-		if w == 1024 {
-			w = width(octet)
-			if w == 0 {
-				return yaml_parser_set_scanner_tag_error(parser, directive,
-					start_mark, "found an incorrect leading UTF-8 octet")
-			}
-		} else {
-			// Check if the trailing octet is correct.
-			if octet&0xC0 != 0x80 {
-				return yaml_parser_set_scanner_tag_error(parser, directive,
-					start_mark, "found an incorrect trailing UTF-8 octet")
-			}
-		}
-
-		// Copy the octet and move the pointers.
-		*s = append(*s, octet)
-		skip(parser)
-		skip(parser)
-		skip(parser)
-		w--
-	}
-	return true
-}
-
-// Scan a block scalar.
-func yaml_parser_scan_block_scalar(parser *yaml_parser_t, token *yaml_token_t, literal bool) bool {
-	// Eat the indicator '|' or '>'.
-	start_mark := parser.mark
-	skip(parser)
-
-	// Scan the additional block scalar indicators.
-	if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
-		return false
-	}
-
-	// Check for a chomping indicator.
-	var chomping, increment int
-	if parser.buffer[parser.buffer_pos] == '+' || parser.buffer[parser.buffer_pos] == '-' {
-		// Set the chomping method and eat the indicator.
-		if parser.buffer[parser.buffer_pos] == '+' {
-			chomping = +1
-		} else {
-			chomping = -1
-		}
-		skip(parser)
-
-		// Check for an indentation indicator.
-		if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
-			return false
-		}
-		if is_digit(parser.buffer, parser.buffer_pos) {
-			// Check that the intendation is greater than 0.
-			if parser.buffer[parser.buffer_pos] == '0' {
-				yaml_parser_set_scanner_error(parser, "while scanning a block scalar",
-					start_mark, "found an intendation indicator equal to 0")
-				return false
-			}
-
-			// Get the intendation level and eat the indicator.
-			increment = as_digit(parser.buffer, parser.buffer_pos)
-			skip(parser)
-		}
-
-	} else if is_digit(parser.buffer, parser.buffer_pos) {
-		// Do the same as above, but in the opposite order.
-
-		if parser.buffer[parser.buffer_pos] == '0' {
-			yaml_parser_set_scanner_error(parser, "while scanning a block scalar",
-				start_mark, "found an intendation indicator equal to 0")
-			return false
-		}
-		increment = as_digit(parser.buffer, parser.buffer_pos)
-		skip(parser)
-
-		if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
-			return false
-		}
-		if parser.buffer[parser.buffer_pos] == '+' || parser.buffer[parser.buffer_pos] == '-' {
-			if parser.buffer[parser.buffer_pos] == '+' {
-				chomping = +1
-			} else {
-				chomping = -1
-			}
-			skip(parser)
-		}
-	}
-
-	// Eat whitespaces and comments to the end of the line.
-	if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
-		return false
-	}
-	for is_blank(parser.buffer, parser.buffer_pos) {
-		skip(parser)
-		if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
-			return false
-		}
-	}
-	if parser.buffer[parser.buffer_pos] == '#' {
-		for !is_breakz(parser.buffer, parser.buffer_pos) {
-			skip(parser)
-			if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
-				return false
-			}
-		}
-	}
-
-	// Check if we are at the end of the line.
-	if !is_breakz(parser.buffer, parser.buffer_pos) {
-		yaml_parser_set_scanner_error(parser, "while scanning a block scalar",
-			start_mark, "did not find expected comment or line break")
-		return false
-	}
-
-	// Eat a line break.
-	if is_break(parser.buffer, parser.buffer_pos) {
-		if parser.unread < 2 && !yaml_parser_update_buffer(parser, 2) {
-			return false
-		}
-		skip_line(parser)
-	}
-
-	end_mark := parser.mark
-
-	// Set the intendation level if it was specified.
-	var indent int
-	if increment > 0 {
-		if parser.indent >= 0 {
-			indent = parser.indent + increment
-		} else {
-			indent = increment
-		}
-	}
-
-	// Scan the leading line breaks and determine the indentation level if needed.
-	var s, leading_break, trailing_breaks []byte
-	if !yaml_parser_scan_block_scalar_breaks(parser, &indent, &trailing_breaks, start_mark, &end_mark) {
-		return false
-	}
-
-	// Scan the block scalar content.
-	if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
-		return false
-	}
-	var leading_blank, trailing_blank bool
-	for parser.mark.column == indent && !is_z(parser.buffer, parser.buffer_pos) {
-		// We are at the beginning of a non-empty line.
-
-		// Is it a trailing whitespace?
-		trailing_blank = is_blank(parser.buffer, parser.buffer_pos)
-
-		// Check if we need to fold the leading line break.
-		if !literal && !leading_blank && !trailing_blank && len(leading_break) > 0 && leading_break[0] == '\n' {
-			// Do we need to join the lines by space?
-			if len(trailing_breaks) == 0 {
-				s = append(s, ' ')
-			}
-		} else {
-			s = append(s, leading_break...)
-		}
-		leading_break = leading_break[:0]
-
-		// Append the remaining line breaks.
-		s = append(s, trailing_breaks...)
-		trailing_breaks = trailing_breaks[:0]
-
-		// Is it a leading whitespace?
-		leading_blank = is_blank(parser.buffer, parser.buffer_pos)
-
-		// Consume the current line.
-		for !is_breakz(parser.buffer, parser.buffer_pos) {
-			s = read(parser, s)
-			if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
-				return false
-			}
-		}
-
-		// Consume the line break.
-		if parser.unread < 2 && !yaml_parser_update_buffer(parser, 2) {
-			return false
-		}
-
-		leading_break = read_line(parser, leading_break)
-
-		// Eat the following intendation spaces and line breaks.
-		if !yaml_parser_scan_block_scalar_breaks(parser, &indent, &trailing_breaks, start_mark, &end_mark) {
-			return false
-		}
-	}
-
-	// Chomp the tail.
-	if chomping != -1 {
-		s = append(s, leading_break...)
-	}
-	if chomping == 1 {
-		s = append(s, trailing_breaks...)
-	}
-
-	// Create a token.
-	*token = yaml_token_t{
-		typ:        yaml_SCALAR_TOKEN,
-		start_mark: start_mark,
-		end_mark:   end_mark,
-		value:      s,
-		style:      yaml_LITERAL_SCALAR_STYLE,
-	}
-	if !literal {
-		token.style = yaml_FOLDED_SCALAR_STYLE
-	}
-	return true
-}
-
-// Scan intendation spaces and line breaks for a block scalar.  Determine the
-// intendation level if needed.
-func yaml_parser_scan_block_scalar_breaks(parser *yaml_parser_t, indent *int, breaks *[]byte, start_mark yaml_mark_t, end_mark *yaml_mark_t) bool {
-	*end_mark = parser.mark
-
-	// Eat the intendation spaces and line breaks.
-	max_indent := 0
-	for {
-		// Eat the intendation spaces.
-		if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
-			return false
-		}
-		for (*indent == 0 || parser.mark.column < *indent) && is_space(parser.buffer, parser.buffer_pos) {
-			skip(parser)
-			if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
-				return false
-			}
-		}
-		if parser.mark.column > max_indent {
-			max_indent = parser.mark.column
-		}
-
-		// Check for a tab character messing the intendation.
-		if (*indent == 0 || parser.mark.column < *indent) && is_tab(parser.buffer, parser.buffer_pos) {
-			return yaml_parser_set_scanner_error(parser, "while scanning a block scalar",
-				start_mark, "found a tab character where an intendation space is expected")
-		}
-
-		// Have we found a non-empty line?
-		if !is_break(parser.buffer, parser.buffer_pos) {
-			break
-		}
-
-		// Consume the line break.
-		if parser.unread < 2 && !yaml_parser_update_buffer(parser, 2) {
-			return false
-		}
-		// [Go] Should really be returning breaks instead.
-		*breaks = read_line(parser, *breaks)
-		*end_mark = parser.mark
-	}
-
-	// Determine the indentation level if needed.
-	if *indent == 0 {
-		*indent = max_indent
-		if *indent < parser.indent+1 {
-			*indent = parser.indent + 1
-		}
-		if *indent < 1 {
-			*indent = 1
-		}
-	}
-	return true
-}
-
-// Scan a quoted scalar.
-func yaml_parser_scan_flow_scalar(parser *yaml_parser_t, token *yaml_token_t, single bool) bool {
-	// Eat the left quote.
-	start_mark := parser.mark
-	skip(parser)
-
-	// Consume the content of the quoted scalar.
-	var s, leading_break, trailing_breaks, whitespaces []byte
-	for {
-		// Check that there are no document indicators at the beginning of the line.
-		if parser.unread < 4 && !yaml_parser_update_buffer(parser, 4) {
-			return false
-		}
-
-		if parser.mark.column == 0 &&
-			((parser.buffer[parser.buffer_pos+0] == '-' &&
-				parser.buffer[parser.buffer_pos+1] == '-' &&
-				parser.buffer[parser.buffer_pos+2] == '-') ||
-				(parser.buffer[parser.buffer_pos+0] == '.' &&
-					parser.buffer[parser.buffer_pos+1] == '.' &&
-					parser.buffer[parser.buffer_pos+2] == '.')) &&
-			is_blankz(parser.buffer, parser.buffer_pos+3) {
-			yaml_parser_set_scanner_error(parser, "while scanning a quoted scalar",
-				start_mark, "found unexpected document indicator")
-			return false
-		}
-
-		// Check for EOF.
-		if is_z(parser.buffer, parser.buffer_pos) {
-			yaml_parser_set_scanner_error(parser, "while scanning a quoted scalar",
-				start_mark, "found unexpected end of stream")
-			return false
-		}
-
-		// Consume non-blank characters.
-		leading_blanks := false
-		for !is_blankz(parser.buffer, parser.buffer_pos) {
-			if single && parser.buffer[parser.buffer_pos] == '\'' && parser.buffer[parser.buffer_pos+1] == '\'' {
-				// Is is an escaped single quote.
-				s = append(s, '\'')
-				skip(parser)
-				skip(parser)
-
-			} else if single && parser.buffer[parser.buffer_pos] == '\'' {
-				// It is a right single quote.
-				break
-			} else if !single && parser.buffer[parser.buffer_pos] == '"' {
-				// It is a right double quote.
-				break
-
-			} else if !single && parser.buffer[parser.buffer_pos] == '\\' && is_break(parser.buffer, parser.buffer_pos+1) {
-				// It is an escaped line break.
-				if parser.unread < 3 && !yaml_parser_update_buffer(parser, 3) {
-					return false
-				}
-				skip(parser)
-				skip_line(parser)
-				leading_blanks = true
-				break
-
-			} else if !single && parser.buffer[parser.buffer_pos] == '\\' {
-				// It is an escape sequence.
-				code_length := 0
-
-				// Check the escape character.
-				switch parser.buffer[parser.buffer_pos+1] {
-				case '0':
-					s = append(s, 0)
-				case 'a':
-					s = append(s, '\x07')
-				case 'b':
-					s = append(s, '\x08')
-				case 't', '\t':
-					s = append(s, '\x09')
-				case 'n':
-					s = append(s, '\x0A')
-				case 'v':
-					s = append(s, '\x0B')
-				case 'f':
-					s = append(s, '\x0C')
-				case 'r':
-					s = append(s, '\x0D')
-				case 'e':
-					s = append(s, '\x1B')
-				case ' ':
-					s = append(s, '\x20')
-				case '"':
-					s = append(s, '"')
-				case '\'':
-					s = append(s, '\'')
-				case '\\':
-					s = append(s, '\\')
-				case 'N': // NEL (#x85)
-					s = append(s, '\xC2')
-					s = append(s, '\x85')
-				case '_': // #xA0
-					s = append(s, '\xC2')
-					s = append(s, '\xA0')
-				case 'L': // LS (#x2028)
-					s = append(s, '\xE2')
-					s = append(s, '\x80')
-					s = append(s, '\xA8')
-				case 'P': // PS (#x2029)
-					s = append(s, '\xE2')
-					s = append(s, '\x80')
-					s = append(s, '\xA9')
-				case 'x':
-					code_length = 2
-				case 'u':
-					code_length = 4
-				case 'U':
-					code_length = 8
-				default:
-					yaml_parser_set_scanner_error(parser, "while parsing a quoted scalar",
-						start_mark, "found unknown escape character")
-					return false
-				}
-
-				skip(parser)
-				skip(parser)
-
-				// Consume an arbitrary escape code.
-				if code_length > 0 {
-					var value int
-
-					// Scan the character value.
-					if parser.unread < code_length && !yaml_parser_update_buffer(parser, code_length) {
-						return false
-					}
-					for k := 0; k < code_length; k++ {
-						if !is_hex(parser.buffer, parser.buffer_pos+k) {
-							yaml_parser_set_scanner_error(parser, "while parsing a quoted scalar",
-								start_mark, "did not find expected hexdecimal number")
-							return false
-						}
-						value = (value << 4) + as_hex(parser.buffer, parser.buffer_pos+k)
-					}
-
-					// Check the value and write the character.
-					if (value >= 0xD800 && value <= 0xDFFF) || value > 0x10FFFF {
-						yaml_parser_set_scanner_error(parser, "while parsing a quoted scalar",
-							start_mark, "found invalid Unicode character escape code")
-						return false
-					}
-					if value <= 0x7F {
-						s = append(s, byte(value))
-					} else if value <= 0x7FF {
-						s = append(s, byte(0xC0+(value>>6)))
-						s = append(s, byte(0x80+(value&0x3F)))
-					} else if value <= 0xFFFF {
-						s = append(s, byte(0xE0+(value>>12)))
-						s = append(s, byte(0x80+((value>>6)&0x3F)))
-						s = append(s, byte(0x80+(value&0x3F)))
-					} else {
-						s = append(s, byte(0xF0+(value>>18)))
-						s = append(s, byte(0x80+((value>>12)&0x3F)))
-						s = append(s, byte(0x80+((value>>6)&0x3F)))
-						s = append(s, byte(0x80+(value&0x3F)))
-					}
-
-					// Advance the pointer.
-					for k := 0; k < code_length; k++ {
-						skip(parser)
-					}
-				}
-			} else {
-				// It is a non-escaped non-blank character.
-				s = read(parser, s)
-			}
-			if parser.unread < 2 && !yaml_parser_update_buffer(parser, 2) {
-				return false
-			}
-		}
-
-		// Check if we are at the end of the scalar.
-		if single {
-			if parser.buffer[parser.buffer_pos] == '\'' {
-				break
-			}
-		} else {
-			if parser.buffer[parser.buffer_pos] == '"' {
-				break
-			}
-		}
-
-		// Consume blank characters.
-		if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
-			return false
-		}
-
-		for is_blank(parser.buffer, parser.buffer_pos) || is_break(parser.buffer, parser.buffer_pos) {
-			if is_blank(parser.buffer, parser.buffer_pos) {
-				// Consume a space or a tab character.
-				if !leading_blanks {
-					whitespaces = read(parser, whitespaces)
-				} else {
-					skip(parser)
-				}
-			} else {
-				if parser.unread < 2 && !yaml_parser_update_buffer(parser, 2) {
-					return false
-				}
-
-				// Check if it is a first line break.
-				if !leading_blanks {
-					whitespaces = whitespaces[:0]
-					leading_break = read_line(parser, leading_break)
-					leading_blanks = true
-				} else {
-					trailing_breaks = read_line(parser, trailing_breaks)
-				}
-			}
-			if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
-				return false
-			}
-		}
-
-		// Join the whitespaces or fold line breaks.
-		if leading_blanks {
-			// Do we need to fold line breaks?
-			if len(leading_break) > 0 && leading_break[0] == '\n' {
-				if len(trailing_breaks) == 0 {
-					s = append(s, ' ')
-				} else {
-					s = append(s, trailing_breaks...)
-				}
-			} else {
-				s = append(s, leading_break...)
-				s = append(s, trailing_breaks...)
-			}
-			trailing_breaks = trailing_breaks[:0]
-			leading_break = leading_break[:0]
-		} else {
-			s = append(s, whitespaces...)
-			whitespaces = whitespaces[:0]
-		}
-	}
-
-	// Eat the right quote.
-	skip(parser)
-	end_mark := parser.mark
-
-	// Create a token.
-	*token = yaml_token_t{
-		typ:        yaml_SCALAR_TOKEN,
-		start_mark: start_mark,
-		end_mark:   end_mark,
-		value:      s,
-		style:      yaml_SINGLE_QUOTED_SCALAR_STYLE,
-	}
-	if !single {
-		token.style = yaml_DOUBLE_QUOTED_SCALAR_STYLE
-	}
-	return true
-}
-
-// Scan a plain scalar.
-func yaml_parser_scan_plain_scalar(parser *yaml_parser_t, token *yaml_token_t) bool {
-
-	var s, leading_break, trailing_breaks, whitespaces []byte
-	var leading_blanks bool
-	var indent = parser.indent + 1
-
-	start_mark := parser.mark
-	end_mark := parser.mark
-
-	// Consume the content of the plain scalar.
-	for {
-		// Check for a document indicator.
-		if parser.unread < 4 && !yaml_parser_update_buffer(parser, 4) {
-			return false
-		}
-		if parser.mark.column == 0 &&
-			((parser.buffer[parser.buffer_pos+0] == '-' &&
-				parser.buffer[parser.buffer_pos+1] == '-' &&
-				parser.buffer[parser.buffer_pos+2] == '-') ||
-				(parser.buffer[parser.buffer_pos+0] == '.' &&
-					parser.buffer[parser.buffer_pos+1] == '.' &&
-					parser.buffer[parser.buffer_pos+2] == '.')) &&
-			is_blankz(parser.buffer, parser.buffer_pos+3) {
-			break
-		}
-
-		// Check for a comment.
-		if parser.buffer[parser.buffer_pos] == '#' {
-			break
-		}
-
-		// Consume non-blank characters.
-		for !is_blankz(parser.buffer, parser.buffer_pos) {
-
-			// Check for 'x:x' in the flow context. TODO: Fix the test "spec-08-13".
-			if parser.flow_level > 0 &&
-				parser.buffer[parser.buffer_pos] == ':' &&
-				!is_blankz(parser.buffer, parser.buffer_pos+1) {
-				yaml_parser_set_scanner_error(parser, "while scanning a plain scalar",
-					start_mark, "found unexpected ':'")
-				return false
-			}
-
-			// Check for indicators that may end a plain scalar.
-			if (parser.buffer[parser.buffer_pos] == ':' && is_blankz(parser.buffer, parser.buffer_pos+1)) ||
-				(parser.flow_level > 0 &&
-					(parser.buffer[parser.buffer_pos] == ',' || parser.buffer[parser.buffer_pos] == ':' ||
-						parser.buffer[parser.buffer_pos] == '?' || parser.buffer[parser.buffer_pos] == '[' ||
-						parser.buffer[parser.buffer_pos] == ']' || parser.buffer[parser.buffer_pos] == '{' ||
-						parser.buffer[parser.buffer_pos] == '}')) {
-				break
-			}
-
-			// Check if we need to join whitespaces and breaks.
-			if leading_blanks || len(whitespaces) > 0 {
-				if leading_blanks {
-					// Do we need to fold line breaks?
-					if leading_break[0] == '\n' {
-						if len(trailing_breaks) == 0 {
-							s = append(s, ' ')
-						} else {
-							s = append(s, trailing_breaks...)
-						}
-					} else {
-						s = append(s, leading_break...)
-						s = append(s, trailing_breaks...)
-					}
-					trailing_breaks = trailing_breaks[:0]
-					leading_break = leading_break[:0]
-					leading_blanks = false
-				} else {
-					s = append(s, whitespaces...)
-					whitespaces = whitespaces[:0]
-				}
-			}
-
-			// Copy the character.
-			s = read(parser, s)
-
-			end_mark = parser.mark
-			if parser.unread < 2 && !yaml_parser_update_buffer(parser, 2) {
-				return false
-			}
-		}
-
-		// Is it the end?
-		if !(is_blank(parser.buffer, parser.buffer_pos) || is_break(parser.buffer, parser.buffer_pos)) {
-			break
-		}
-
-		// Consume blank characters.
-		if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
-			return false
-		}
-
-		for is_blank(parser.buffer, parser.buffer_pos) || is_break(parser.buffer, parser.buffer_pos) {
-			if is_blank(parser.buffer, parser.buffer_pos) {
-
-				// Check for tab character that abuse intendation.
-				if leading_blanks && parser.mark.column < indent && is_tab(parser.buffer, parser.buffer_pos) {
-					yaml_parser_set_scanner_error(parser, "while scanning a plain scalar",
-						start_mark, "found a tab character that violate intendation")
-					return false
-				}
-
-				// Consume a space or a tab character.
-				if !leading_blanks {
-					whitespaces = read(parser, whitespaces)
-				} else {
-					skip(parser)
-				}
-			} else {
-				if parser.unread < 2 && !yaml_parser_update_buffer(parser, 2) {
-					return false
-				}
-
-				// Check if it is a first line break.
-				if !leading_blanks {
-					whitespaces = whitespaces[:0]
-					leading_break = read_line(parser, leading_break)
-					leading_blanks = true
-				} else {
-					trailing_breaks = read_line(parser, trailing_breaks)
-				}
-			}
-			if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
-				return false
-			}
-		}
-
-		// Check intendation level.
-		if parser.flow_level == 0 && parser.mark.column < indent {
-			break
-		}
-	}
-
-	// Create a token.
-	*token = yaml_token_t{
-		typ:        yaml_SCALAR_TOKEN,
-		start_mark: start_mark,
-		end_mark:   end_mark,
-		value:      s,
-		style:      yaml_PLAIN_SCALAR_STYLE,
-	}
-
-	// Note that we change the 'simple_key_allowed' flag.
-	if leading_blanks {
-		parser.simple_key_allowed = true
-	}
-	return true
-}
diff --git a/sorter.go b/sorter.go
deleted file mode 100644
index 5958822..0000000
--- a/sorter.go
+++ /dev/null
@@ -1,104 +0,0 @@
-package yaml
-
-import (
-	"reflect"
-	"unicode"
-)
-
-type keyList []reflect.Value
-
-func (l keyList) Len() int      { return len(l) }
-func (l keyList) Swap(i, j int) { l[i], l[j] = l[j], l[i] }
-func (l keyList) Less(i, j int) bool {
-	a := l[i]
-	b := l[j]
-	ak := a.Kind()
-	bk := b.Kind()
-	for (ak == reflect.Interface || ak == reflect.Ptr) && !a.IsNil() {
-		a = a.Elem()
-		ak = a.Kind()
-	}
-	for (bk == reflect.Interface || bk == reflect.Ptr) && !b.IsNil() {
-		b = b.Elem()
-		bk = b.Kind()
-	}
-	af, aok := keyFloat(a)
-	bf, bok := keyFloat(b)
-	if aok && bok {
-		if af != bf {
-			return af < bf
-		}
-		if ak != bk {
-			return ak < bk
-		}
-		return numLess(a, b)
-	}
-	if ak != reflect.String || bk != reflect.String {
-		return ak < bk
-	}
-	ar, br := []rune(a.String()), []rune(b.String())
-	for i := 0; i < len(ar) && i < len(br); i++ {
-		if ar[i] == br[i] {
-			continue
-		}
-		al := unicode.IsLetter(ar[i])
-		bl := unicode.IsLetter(br[i])
-		if al && bl {
-			return ar[i] < br[i]
-		}
-		if al || bl {
-			return bl
-		}
-		var ai, bi int
-		var an, bn int64
-		for ai = i; ai < len(ar) && unicode.IsDigit(ar[ai]); ai++ {
-			an = an*10 + int64(ar[ai]-'0')
-		}
-		for bi = i; bi < len(br) && unicode.IsDigit(br[bi]); bi++ {
-			bn = bn*10 + int64(br[bi]-'0')
-		}
-		if an != bn {
-			return an < bn
-		}
-		if ai != bi {
-			return ai < bi
-		}
-		return ar[i] < br[i]
-	}
-	return len(ar) < len(br)
-}
-
-// keyFloat returns a float value for v if it is a number/bool
-// and whether it is a number/bool or not.
-func keyFloat(v reflect.Value) (f float64, ok bool) {
-	switch v.Kind() {
-	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
-		return float64(v.Int()), true
-	case reflect.Float32, reflect.Float64:
-		return v.Float(), true
-	case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
-		return float64(v.Uint()), true
-	case reflect.Bool:
-		if v.Bool() {
-			return 1, true
-		}
-		return 0, true
-	}
-	return 0, false
-}
-
-// numLess returns whether a < b.
-// a and b must necessarily have the same kind.
-func numLess(a, b reflect.Value) bool {
-	switch a.Kind() {
-	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
-		return a.Int() < b.Int()
-	case reflect.Float32, reflect.Float64:
-		return a.Float() < b.Float()
-	case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
-		return a.Uint() < b.Uint()
-	case reflect.Bool:
-		return !a.Bool() && b.Bool()
-	}
-	panic("not a number")
-}
diff --git a/suite_test.go b/suite_test.go
deleted file mode 100644
index 111d756..0000000
--- a/suite_test.go
+++ /dev/null
@@ -1,12 +0,0 @@
-package yaml_test
-
-import (
-	. "launchpad.net/gocheck"
-	"testing"
-)
-
-func Test(t *testing.T) { TestingT(t) }
-
-type S struct{}
-
-var _ = Suite(&S{})
diff --git a/writerc.go b/writerc.go
deleted file mode 100644
index 190362f..0000000
--- a/writerc.go
+++ /dev/null
@@ -1,89 +0,0 @@
-package yaml
-
-// Set the writer error and return false.
-func yaml_emitter_set_writer_error(emitter *yaml_emitter_t, problem string) bool {
-	emitter.error = yaml_WRITER_ERROR
-	emitter.problem = problem
-	return false
-}
-
-// Flush the output buffer.
-func yaml_emitter_flush(emitter *yaml_emitter_t) bool {
-	if emitter.write_handler == nil {
-		panic("write handler not set")
-	}
-
-	// Check if the buffer is empty.
-	if emitter.buffer_pos == 0 {
-		return true
-	}
-
-	// If the output encoding is UTF-8, we don't need to recode the buffer.
-	if emitter.encoding == yaml_UTF8_ENCODING {
-		if err := emitter.write_handler(emitter, emitter.buffer[:emitter.buffer_pos]); err != nil {
-			return yaml_emitter_set_writer_error(emitter, "write error: "+err.Error())
-		}
-		emitter.buffer_pos = 0
-		return true
-	}
-
-	// Recode the buffer into the raw buffer.
-	var low, high int
-	if emitter.encoding == yaml_UTF16LE_ENCODING {
-		low, high = 0, 1
-	} else {
-		high, low = 1, 0
-	}
-
-	pos := 0
-	for pos < emitter.buffer_pos {
-		// See the "reader.c" code for more details on UTF-8 encoding.  Note
-		// that we assume that the buffer contains a valid UTF-8 sequence.
-
-		// Read the next UTF-8 character.
-		octet := emitter.buffer[pos]
-
-		var w int
-		var value rune
-		switch {
-		case octet&0x80 == 0x00:
-			w, value = 1, rune(octet&0x7F)
-		case octet&0xE0 == 0xC0:
-			w, value = 2, rune(octet&0x1F)
-		case octet&0xF0 == 0xE0:
-			w, value = 3, rune(octet&0x0F)
-		case octet&0xF8 == 0xF0:
-			w, value = 4, rune(octet&0x07)
-		}
-		for k := 1; k < w; k++ {
-			octet = emitter.buffer[pos+k]
-			value = (value << 6) + (rune(octet) & 0x3F)
-		}
-		pos += w
-
-		// Write the character.
-		if value < 0x10000 {
-			var b [2]byte
-			b[high] = byte(value >> 8)
-			b[low] = byte(value & 0xFF)
-			emitter.raw_buffer = append(emitter.raw_buffer, b[0], b[1])
-		} else {
-			// Write the character using a surrogate pair (check "reader.c").
-			var b [4]byte
-			value -= 0x10000
-			b[high] = byte(0xD8 + (value >> 18))
-			b[low] = byte((value >> 10) & 0xFF)
-			b[high+2] = byte(0xDC + ((value >> 8) & 0xFF))
-			b[low+2] = byte(value & 0xFF)
-			emitter.raw_buffer = append(emitter.raw_buffer, b[0], b[1], b[2], b[3])
-		}
-	}
-
-	// Write the raw buffer.
-	if err := emitter.write_handler(emitter, emitter.raw_buffer); err != nil {
-		return yaml_emitter_set_writer_error(emitter, "write error: "+err.Error())
-	}
-	emitter.buffer_pos = 0
-	emitter.raw_buffer = emitter.raw_buffer[:0]
-	return true
-}
diff --git a/yaml.go b/yaml.go
deleted file mode 100644
index 810a74c..0000000
--- a/yaml.go
+++ /dev/null
@@ -1,306 +0,0 @@
-// Package yaml implements YAML support for the Go language.
-//
-// Source code and other details for the project are available at GitHub:
-//
-//   https://github.com/go-yaml/yaml
-//
-package yaml
-
-import (
-	"errors"
-	"fmt"
-	"reflect"
-	"runtime"
-	"strings"
-	"sync"
-)
-
-func handleErr(err *error) {
-	if r := recover(); r != nil {
-		if _, ok := r.(runtime.Error); ok {
-			panic(r)
-		} else if _, ok := r.(*reflect.ValueError); ok {
-			panic(r)
-		} else if _, ok := r.(externalPanic); ok {
-			panic(r)
-		} else if s, ok := r.(string); ok {
-			*err = errors.New("YAML error: " + s)
-		} else if e, ok := r.(error); ok {
-			*err = e
-		} else {
-			panic(r)
-		}
-	}
-}
-
-// The Setter interface may be implemented by types to do their own custom
-// unmarshalling of YAML values, rather than being implicitly assigned by
-// the yaml package machinery. If setting the value works, the method should
-// return true.  If it returns false, the value is considered unsupported
-// and is omitted from maps and slices.
-type Setter interface {
-	SetYAML(tag string, value interface{}) bool
-}
-
-// The Setter interface is implemented by types to do their own custom
-// marshalling into a YAML tag and value.
-type Getter interface {
-	GetYAML() (tag string, value interface{})
-}
-
-// Unmarshal decodes the first document found within the in byte slice
-// and assigns decoded values into the out value.
-//
-// Maps and pointers (to a struct, string, int, etc) are accepted as out
-// values.  If an internal pointer within a struct is not initialized,
-// the yaml package will initialize it if necessary for unmarshalling
-// the provided data. The out parameter must not be nil.
-//
-// The type of the decoded values and the type of out will be considered,
-// and Unmarshal will do the best possible job to unmarshal values
-// appropriately.  It is NOT considered an error, though, to skip values
-// because they are not available in the decoded YAML, or if they are not
-// compatible with the out value. To ensure something was properly
-// unmarshaled use a map or compare against the previous value for the
-// field (usually the zero value).
-//
-// Struct fields are only unmarshalled if they are exported (have an
-// upper case first letter), and are unmarshalled using the field name
-// lowercased as the default key. Custom keys may be defined via the
-// "yaml" name in the field tag: the content preceding the first comma
-// is used as the key, and the following comma-separated options are
-// used to tweak the marshalling process (see Marshal).
-// Conflicting names result in a runtime error.
-//
-// For example:
-//
-//     type T struct {
-//         F int `yaml:"a,omitempty"`
-//         B int
-//     }
-//     var T t
-//     yaml.Unmarshal([]byte("a: 1\nb: 2"), &t)
-//
-// See the documentation of Marshal for the format of tags and a list of
-// supported tag options.
-//
-func Unmarshal(in []byte, out interface{}) (err error) {
-	defer handleErr(&err)
-	d := newDecoder()
-	p := newParser(in)
-	defer p.destroy()
-	node := p.parse()
-	if node != nil {
-		d.unmarshal(node, reflect.ValueOf(out))
-	}
-	return nil
-}
-
-// Marshal serializes the value provided into a YAML document. The structure
-// of the generated document will reflect the structure of the value itself.
-// Maps and pointers (to struct, string, int, etc) are accepted as the in value.
-//
-// Struct fields are only unmarshalled if they are exported (have an upper case
-// first letter), and are unmarshalled using the field name lowercased as the
-// default key. Custom keys may be defined via the "yaml" name in the field
-// tag: the content preceding the first comma is used as the key, and the
-// following comma-separated options are used to tweak the marshalling process.
-// Conflicting names result in a runtime error.
-//
-// The field tag format accepted is:
-//
-//     `(...) yaml:"[<key>][,<flag1>[,<flag2>]]" (...)`
-//
-// The following flags are currently supported:
-//
-//     omitempty    Only include the field if it's not set to the zero
-//                  value for the type or to empty slices or maps.
-//                  Does not apply to zero valued structs.
-//
-//     flow         Marshal using a flow style (useful for structs,
-//                  sequences and maps.
-//
-//     inline       Inline the struct it's applied to, so its fields
-//                  are processed as if they were part of the outer
-//                  struct.
-//
-// In addition, if the key is "-", the field is ignored.
-//
-// For example:
-//
-//     type T struct {
-//         F int "a,omitempty"
-//         B int
-//     }
-//     yaml.Marshal(&T{B: 2}) // Returns "b: 2\n"
-//     yaml.Marshal(&T{F: 1}} // Returns "a: 1\nb: 0\n"
-//
-func Marshal(in interface{}) (out []byte, err error) {
-	defer handleErr(&err)
-	e := newEncoder()
-	defer e.destroy()
-	e.marshal("", reflect.ValueOf(in))
-	e.finish()
-	out = e.out
-	return
-}
-
-// --------------------------------------------------------------------------
-// Maintain a mapping of keys to structure field indexes
-
-// The code in this section was copied from mgo/bson.
-
-// structInfo holds details for the serialization of fields of
-// a given struct.
-type structInfo struct {
-	FieldsMap  map[string]fieldInfo
-	FieldsList []fieldInfo
-
-	// InlineMap is the number of the field in the struct that
-	// contains an ,inline map, or -1 if there's none.
-	InlineMap int
-}
-
-type fieldInfo struct {
-	Key       string
-	Num       int
-	OmitEmpty bool
-	Flow      bool
-
-	// Inline holds the field index if the field is part of an inlined struct.
-	Inline []int
-}
-
-var structMap = make(map[reflect.Type]*structInfo)
-var fieldMapMutex sync.RWMutex
-
-type externalPanic string
-
-func (e externalPanic) String() string {
-	return string(e)
-}
-
-func getStructInfo(st reflect.Type) (*structInfo, error) {
-	fieldMapMutex.RLock()
-	sinfo, found := structMap[st]
-	fieldMapMutex.RUnlock()
-	if found {
-		return sinfo, nil
-	}
-
-	n := st.NumField()
-	fieldsMap := make(map[string]fieldInfo)
-	fieldsList := make([]fieldInfo, 0, n)
-	inlineMap := -1
-	for i := 0; i != n; i++ {
-		field := st.Field(i)
-		if field.PkgPath != "" {
-			continue // Private field
-		}
-
-		info := fieldInfo{Num: i}
-
-		tag := field.Tag.Get("yaml")
-		if tag == "" && strings.Index(string(field.Tag), ":") < 0 {
-			tag = string(field.Tag)
-		}
-		if tag == "-" {
-			continue
-		}
-
-		inline := false
-		fields := strings.Split(tag, ",")
-		if len(fields) > 1 {
-			for _, flag := range fields[1:] {
-				switch flag {
-				case "omitempty":
-					info.OmitEmpty = true
-				case "flow":
-					info.Flow = true
-				case "inline":
-					inline = true
-				default:
-					msg := fmt.Sprintf("Unsupported flag %q in tag %q of type %s", flag, tag, st)
-					panic(externalPanic(msg))
-				}
-			}
-			tag = fields[0]
-		}
-
-		if inline {
-			switch field.Type.Kind() {
-			//case reflect.Map:
-			//	if inlineMap >= 0 {
-			//		return nil, errors.New("Multiple ,inline maps in struct " + st.String())
-			//	}
-			//	if field.Type.Key() != reflect.TypeOf("") {
-			//		return nil, errors.New("Option ,inline needs a map with string keys in struct " + st.String())
-			//	}
-			//	inlineMap = info.Num
-			case reflect.Struct:
-				sinfo, err := getStructInfo(field.Type)
-				if err != nil {
-					return nil, err
-				}
-				for _, finfo := range sinfo.FieldsList {
-					if _, found := fieldsMap[finfo.Key]; found {
-						msg := "Duplicated key '" + finfo.Key + "' in struct " + st.String()
-						return nil, errors.New(msg)
-					}
-					if finfo.Inline == nil {
-						finfo.Inline = []int{i, finfo.Num}
-					} else {
-						finfo.Inline = append([]int{i}, finfo.Inline...)
-					}
-					fieldsMap[finfo.Key] = finfo
-					fieldsList = append(fieldsList, finfo)
-				}
-			default:
-				//panic("Option ,inline needs a struct value or map field")
-				panic("Option ,inline needs a struct value field")
-			}
-			continue
-		}
-
-		if tag != "" {
-			info.Key = tag
-		} else {
-			info.Key = strings.ToLower(field.Name)
-		}
-
-		if _, found = fieldsMap[info.Key]; found {
-			msg := "Duplicated key '" + info.Key + "' in struct " + st.String()
-			return nil, errors.New(msg)
-		}
-
-		fieldsList = append(fieldsList, info)
-		fieldsMap[info.Key] = info
-	}
-
-	sinfo = &structInfo{fieldsMap, fieldsList, inlineMap}
-
-	fieldMapMutex.Lock()
-	structMap[st] = sinfo
-	fieldMapMutex.Unlock()
-	return sinfo, nil
-}
-
-func isZero(v reflect.Value) bool {
-	switch v.Kind() {
-	case reflect.String:
-		return len(v.String()) == 0
-	case reflect.Interface, reflect.Ptr:
-		return v.IsNil()
-	case reflect.Slice:
-		return v.Len() == 0
-	case reflect.Map:
-		return v.Len() == 0
-	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
-		return v.Int() == 0
-	case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
-		return v.Uint() == 0
-	case reflect.Bool:
-		return !v.Bool()
-	}
-	return false
-}
diff --git a/yamlh.go b/yamlh.go
deleted file mode 100644
index 6624d6c..0000000
--- a/yamlh.go
+++ /dev/null
@@ -1,712 +0,0 @@
-package yaml
-
-import (
-	"io"
-)
-
-// The version directive data.
-type yaml_version_directive_t struct {
-	major int8 // The major version number.
-	minor int8 // The minor version number.
-}
-
-// The tag directive data.
-type yaml_tag_directive_t struct {
-	handle []byte // The tag handle.
-	prefix []byte // The tag prefix.
-}
-
-type yaml_encoding_t int
-
-// The stream encoding.
-const (
-	// Let the parser choose the encoding.
-	yaml_ANY_ENCODING yaml_encoding_t = iota
-
-	yaml_UTF8_ENCODING    // The default UTF-8 encoding.
-	yaml_UTF16LE_ENCODING // The UTF-16-LE encoding with BOM.
-	yaml_UTF16BE_ENCODING // The UTF-16-BE encoding with BOM.
-)
-
-type yaml_break_t int
-
-// Line break types.
-const (
-	// Let the parser choose the break type.
-	yaml_ANY_BREAK yaml_break_t = iota
-
-	yaml_CR_BREAK   // Use CR for line breaks (Mac style).
-	yaml_LN_BREAK   // Use LN for line breaks (Unix style).
-	yaml_CRLN_BREAK // Use CR LN for line breaks (DOS style).
-)
-
-type yaml_error_type_t int
-
-// Many bad things could happen with the parser and emitter.
-const (
-	// No error is produced.
-	yaml_NO_ERROR yaml_error_type_t = iota
-
-	yaml_MEMORY_ERROR   // Cannot allocate or reallocate a block of memory.
-	yaml_READER_ERROR   // Cannot read or decode the input stream.
-	yaml_SCANNER_ERROR  // Cannot scan the input stream.
-	yaml_PARSER_ERROR   // Cannot parse the input stream.
-	yaml_COMPOSER_ERROR // Cannot compose a YAML document.
-	yaml_WRITER_ERROR   // Cannot write to the output stream.
-	yaml_EMITTER_ERROR  // Cannot emit a YAML stream.
-)
-
-// The pointer position.
-type yaml_mark_t struct {
-	index  int // The position index.
-	line   int // The position line.
-	column int // The position column.
-}
-
-// Node Styles
-
-type yaml_style_t int8
-
-type yaml_scalar_style_t yaml_style_t
-
-// Scalar styles.
-const (
-	// Let the emitter choose the style.
-	yaml_ANY_SCALAR_STYLE yaml_scalar_style_t = iota
-
-	yaml_PLAIN_SCALAR_STYLE         // The plain scalar style.
-	yaml_SINGLE_QUOTED_SCALAR_STYLE // The single-quoted scalar style.
-	yaml_DOUBLE_QUOTED_SCALAR_STYLE // The double-quoted scalar style.
-	yaml_LITERAL_SCALAR_STYLE       // The literal scalar style.
-	yaml_FOLDED_SCALAR_STYLE        // The folded scalar style.
-)
-
-type yaml_sequence_style_t yaml_style_t
-
-// Sequence styles.
-const (
-	// Let the emitter choose the style.
-	yaml_ANY_SEQUENCE_STYLE yaml_sequence_style_t = iota
-
-	yaml_BLOCK_SEQUENCE_STYLE // The block sequence style.
-	yaml_FLOW_SEQUENCE_STYLE  // The flow sequence style.
-)
-
-type yaml_mapping_style_t yaml_style_t
-
-// Mapping styles.
-const (
-	// Let the emitter choose the style.
-	yaml_ANY_MAPPING_STYLE yaml_mapping_style_t = iota
-
-	yaml_BLOCK_MAPPING_STYLE // The block mapping style.
-	yaml_FLOW_MAPPING_STYLE  // The flow mapping style.
-)
-
-// Tokens
-
-type yaml_token_type_t int
-
-// Token types.
-const (
-	// An empty token.
-	yaml_NO_TOKEN yaml_token_type_t = iota
-
-	yaml_STREAM_START_TOKEN // A STREAM-START token.
-	yaml_STREAM_END_TOKEN   // A STREAM-END token.
-
-	yaml_VERSION_DIRECTIVE_TOKEN // A VERSION-DIRECTIVE token.
-	yaml_TAG_DIRECTIVE_TOKEN     // A TAG-DIRECTIVE token.
-	yaml_DOCUMENT_START_TOKEN    // A DOCUMENT-START token.
-	yaml_DOCUMENT_END_TOKEN      // A DOCUMENT-END token.
-
-	yaml_BLOCK_SEQUENCE_START_TOKEN // A BLOCK-SEQUENCE-START token.
-	yaml_BLOCK_MAPPING_START_TOKEN  // A BLOCK-SEQUENCE-END token.
-	yaml_BLOCK_END_TOKEN            // A BLOCK-END token.
-
-	yaml_FLOW_SEQUENCE_START_TOKEN // A FLOW-SEQUENCE-START token.
-	yaml_FLOW_SEQUENCE_END_TOKEN   // A FLOW-SEQUENCE-END token.
-	yaml_FLOW_MAPPING_START_TOKEN  // A FLOW-MAPPING-START token.
-	yaml_FLOW_MAPPING_END_TOKEN    // A FLOW-MAPPING-END token.
-
-	yaml_BLOCK_ENTRY_TOKEN // A BLOCK-ENTRY token.
-	yaml_FLOW_ENTRY_TOKEN  // A FLOW-ENTRY token.
-	yaml_KEY_TOKEN         // A KEY token.
-	yaml_VALUE_TOKEN       // A VALUE token.
-
-	yaml_ALIAS_TOKEN  // An ALIAS token.
-	yaml_ANCHOR_TOKEN // An ANCHOR token.
-	yaml_TAG_TOKEN    // A TAG token.
-	yaml_SCALAR_TOKEN // A SCALAR token.
-)
-
-func (tt yaml_token_type_t) String() string {
-	switch tt {
-	case yaml_NO_TOKEN:
-		return "yaml_NO_TOKEN"
-	case yaml_STREAM_START_TOKEN:
-		return "yaml_STREAM_START_TOKEN"
-	case yaml_STREAM_END_TOKEN:
-		return "yaml_STREAM_END_TOKEN"
-	case yaml_VERSION_DIRECTIVE_TOKEN:
-		return "yaml_VERSION_DIRECTIVE_TOKEN"
-	case yaml_TAG_DIRECTIVE_TOKEN:
-		return "yaml_TAG_DIRECTIVE_TOKEN"
-	case yaml_DOCUMENT_START_TOKEN:
-		return "yaml_DOCUMENT_START_TOKEN"
-	case yaml_DOCUMENT_END_TOKEN:
-		return "yaml_DOCUMENT_END_TOKEN"
-	case yaml_BLOCK_SEQUENCE_START_TOKEN:
-		return "yaml_BLOCK_SEQUENCE_START_TOKEN"
-	case yaml_BLOCK_MAPPING_START_TOKEN:
-		return "yaml_BLOCK_MAPPING_START_TOKEN"
-	case yaml_BLOCK_END_TOKEN:
-		return "yaml_BLOCK_END_TOKEN"
-	case yaml_FLOW_SEQUENCE_START_TOKEN:
-		return "yaml_FLOW_SEQUENCE_START_TOKEN"
-	case yaml_FLOW_SEQUENCE_END_TOKEN:
-		return "yaml_FLOW_SEQUENCE_END_TOKEN"
-	case yaml_FLOW_MAPPING_START_TOKEN:
-		return "yaml_FLOW_MAPPING_START_TOKEN"
-	case yaml_FLOW_MAPPING_END_TOKEN:
-		return "yaml_FLOW_MAPPING_END_TOKEN"
-	case yaml_BLOCK_ENTRY_TOKEN:
-		return "yaml_BLOCK_ENTRY_TOKEN"
-	case yaml_FLOW_ENTRY_TOKEN:
-		return "yaml_FLOW_ENTRY_TOKEN"
-	case yaml_KEY_TOKEN:
-		return "yaml_KEY_TOKEN"
-	case yaml_VALUE_TOKEN:
-		return "yaml_VALUE_TOKEN"
-	case yaml_ALIAS_TOKEN:
-		return "yaml_ALIAS_TOKEN"
-	case yaml_ANCHOR_TOKEN:
-		return "yaml_ANCHOR_TOKEN"
-	case yaml_TAG_TOKEN:
-		return "yaml_TAG_TOKEN"
-	case yaml_SCALAR_TOKEN:
-		return "yaml_SCALAR_TOKEN"
-	}
-	return "<unknown token>"
-}
-
-// The token structure.
-type yaml_token_t struct {
-	// The token type.
-	typ yaml_token_type_t
-
-	// The start/end of the token.
-	start_mark, end_mark yaml_mark_t
-
-	// The stream encoding (for yaml_STREAM_START_TOKEN).
-	encoding yaml_encoding_t
-
-	// The alias/anchor/scalar value or tag/tag directive handle
-	// (for yaml_ALIAS_TOKEN, yaml_ANCHOR_TOKEN, yaml_SCALAR_TOKEN, yaml_TAG_TOKEN, yaml_TAG_DIRECTIVE_TOKEN).
-	value []byte
-
-	// The tag suffix (for yaml_TAG_TOKEN).
-	suffix []byte
-
-	// The tag directive prefix (for yaml_TAG_DIRECTIVE_TOKEN).
-	prefix []byte
-
-	// The scalar style (for yaml_SCALAR_TOKEN).
-	style yaml_scalar_style_t
-
-	// The version directive major/minor (for yaml_VERSION_DIRECTIVE_TOKEN).
-	major, minor int8
-}
-
-// Events
-
-type yaml_event_type_t int8
-
-// Event types.
-const (
-	// An empty event.
-	yaml_NO_EVENT yaml_event_type_t = iota
-
-	yaml_STREAM_START_EVENT   // A STREAM-START event.
-	yaml_STREAM_END_EVENT     // A STREAM-END event.
-	yaml_DOCUMENT_START_EVENT // A DOCUMENT-START event.
-	yaml_DOCUMENT_END_EVENT   // A DOCUMENT-END event.
-	yaml_ALIAS_EVENT          // An ALIAS event.
-	yaml_SCALAR_EVENT         // A SCALAR event.
-	yaml_SEQUENCE_START_EVENT // A SEQUENCE-START event.
-	yaml_SEQUENCE_END_EVENT   // A SEQUENCE-END event.
-	yaml_MAPPING_START_EVENT  // A MAPPING-START event.
-	yaml_MAPPING_END_EVENT    // A MAPPING-END event.
-)
-
-// The event structure.
-type yaml_event_t struct {
-
-	// The event type.
-	typ yaml_event_type_t
-
-	// The start and end of the event.
-	start_mark, end_mark yaml_mark_t
-
-	// The document encoding (for yaml_STREAM_START_EVENT).
-	encoding yaml_encoding_t
-
-	// The version directive (for yaml_DOCUMENT_START_EVENT).
-	version_directive *yaml_version_directive_t
-
-	// The list of tag directives (for yaml_DOCUMENT_START_EVENT).
-	tag_directives []yaml_tag_directive_t
-
-	// The anchor (for yaml_SCALAR_EVENT, yaml_SEQUENCE_START_EVENT, yaml_MAPPING_START_EVENT, yaml_ALIAS_EVENT).
-	anchor []byte
-
-	// The tag (for yaml_SCALAR_EVENT, yaml_SEQUENCE_START_EVENT, yaml_MAPPING_START_EVENT).
-	tag []byte
-
-	// The scalar value (for yaml_SCALAR_EVENT).
-	value []byte
-
-	// Is the document start/end indicator implicit, or the tag optional?
-	// (for yaml_DOCUMENT_START_EVENT, yaml_DOCUMENT_END_EVENT, yaml_SEQUENCE_START_EVENT, yaml_MAPPING_START_EVENT, yaml_SCALAR_EVENT).
-	implicit bool
-
-	// Is the tag optional for any non-plain style? (for yaml_SCALAR_EVENT).
-	quoted_implicit bool
-
-	// The style (for yaml_SCALAR_EVENT, yaml_SEQUENCE_START_EVENT, yaml_MAPPING_START_EVENT).
-	style yaml_style_t
-}
-
-func (e *yaml_event_t) scalar_style() yaml_scalar_style_t     { return yaml_scalar_style_t(e.style) }
-func (e *yaml_event_t) sequence_style() yaml_sequence_style_t { return yaml_sequence_style_t(e.style) }
-func (e *yaml_event_t) mapping_style() yaml_mapping_style_t   { return yaml_mapping_style_t(e.style) }
-
-// Nodes
-
-const (
-	yaml_NULL_TAG      = "tag:yaml.org,2002:null"      // The tag !!null with the only possible value: null.
-	yaml_BOOL_TAG      = "tag:yaml.org,2002:bool"      // The tag !!bool with the values: true and false.
-	yaml_STR_TAG       = "tag:yaml.org,2002:str"       // The tag !!str for string values.
-	yaml_INT_TAG       = "tag:yaml.org,2002:int"       // The tag !!int for integer values.
-	yaml_FLOAT_TAG     = "tag:yaml.org,2002:float"     // The tag !!float for float values.
-	yaml_TIMESTAMP_TAG = "tag:yaml.org,2002:timestamp" // The tag !!timestamp for date and time values.
-
-	yaml_SEQ_TAG = "tag:yaml.org,2002:seq" // The tag !!seq is used to denote sequences.
-	yaml_MAP_TAG = "tag:yaml.org,2002:map" // The tag !!map is used to denote mapping.
-
-	yaml_DEFAULT_SCALAR_TAG   = yaml_STR_TAG // The default scalar tag is !!str.
-	yaml_DEFAULT_SEQUENCE_TAG = yaml_SEQ_TAG // The default sequence tag is !!seq.
-	yaml_DEFAULT_MAPPING_TAG  = yaml_MAP_TAG // The default mapping tag is !!map.
-)
-
-type yaml_node_type_t int
-
-// Node types.
-const (
-	// An empty node.
-	yaml_NO_NODE yaml_node_type_t = iota
-
-	yaml_SCALAR_NODE   // A scalar node.
-	yaml_SEQUENCE_NODE // A sequence node.
-	yaml_MAPPING_NODE  // A mapping node.
-)
-
-// An element of a sequence node.
-type yaml_node_item_t int
-
-// An element of a mapping node.
-type yaml_node_pair_t struct {
-	key   int // The key of the element.
-	value int // The value of the element.
-}
-
-// The node structure.
-type yaml_node_t struct {
-	typ yaml_node_type_t // The node type.
-	tag []byte           // The node tag.
-
-	// The node data.
-
-	// The scalar parameters (for yaml_SCALAR_NODE).
-	scalar struct {
-		value  []byte              // The scalar value.
-		length int                 // The length of the scalar value.
-		style  yaml_scalar_style_t // The scalar style.
-	}
-
-	// The sequence parameters (for YAML_SEQUENCE_NODE).
-	sequence struct {
-		items_data []yaml_node_item_t    // The stack of sequence items.
-		style      yaml_sequence_style_t // The sequence style.
-	}
-
-	// The mapping parameters (for yaml_MAPPING_NODE).
-	mapping struct {
-		pairs_data  []yaml_node_pair_t   // The stack of mapping pairs (key, value).
-		pairs_start *yaml_node_pair_t    // The beginning of the stack.
-		pairs_end   *yaml_node_pair_t    // The end of the stack.
-		pairs_top   *yaml_node_pair_t    // The top of the stack.
-		style       yaml_mapping_style_t // The mapping style.
-	}
-
-	start_mark yaml_mark_t // The beginning of the node.
-	end_mark   yaml_mark_t // The end of the node.
-
-}
-
-// The document structure.
-type yaml_document_t struct {
-
-	// The document nodes.
-	nodes []yaml_node_t
-
-	// The version directive.
-	version_directive *yaml_version_directive_t
-
-	// The list of tag directives.
-	tag_directives_data  []yaml_tag_directive_t
-	tag_directives_start int // The beginning of the tag directives list.
-	tag_directives_end   int // The end of the tag directives list.
-
-	start_implicit int // Is the document start indicator implicit?
-	end_implicit   int // Is the document end indicator implicit?
-
-	// The start/end of the document.
-	start_mark, end_mark yaml_mark_t
-}
-
-// The prototype of a read handler.
-//
-// The read handler is called when the parser needs to read more bytes from the
-// source. The handler should write not more than size bytes to the buffer.
-// The number of written bytes should be set to the size_read variable.
-//
-// [in,out]   data        A pointer to an application data specified by
-//                        yaml_parser_set_input().
-// [out]      buffer      The buffer to write the data from the source.
-// [in]       size        The size of the buffer.
-// [out]      size_read   The actual number of bytes read from the source.
-//
-// On success, the handler should return 1.  If the handler failed,
-// the returned value should be 0. On EOF, the handler should set the
-// size_read to 0 and return 1.
-type yaml_read_handler_t func(parser *yaml_parser_t, buffer []byte) (n int, err error)
-
-// This structure holds information about a potential simple key.
-type yaml_simple_key_t struct {
-	possible     bool        // Is a simple key possible?
-	required     bool        // Is a simple key required?
-	token_number int         // The number of the token.
-	mark         yaml_mark_t // The position mark.
-}
-
-// The states of the parser.
-type yaml_parser_state_t int
-
-const (
-	yaml_PARSE_STREAM_START_STATE yaml_parser_state_t = iota
-
-	yaml_PARSE_IMPLICIT_DOCUMENT_START_STATE           // Expect the beginning of an implicit document.
-	yaml_PARSE_DOCUMENT_START_STATE                    // Expect DOCUMENT-START.
-	yaml_PARSE_DOCUMENT_CONTENT_STATE                  // Expect the content of a document.
-	yaml_PARSE_DOCUMENT_END_STATE                      // Expect DOCUMENT-END.
-	yaml_PARSE_BLOCK_NODE_STATE                        // Expect a block node.
-	yaml_PARSE_BLOCK_NODE_OR_INDENTLESS_SEQUENCE_STATE // Expect a block node or indentless sequence.
-	yaml_PARSE_FLOW_NODE_STATE                         // Expect a flow node.
-	yaml_PARSE_BLOCK_SEQUENCE_FIRST_ENTRY_STATE        // Expect the first entry of a block sequence.
-	yaml_PARSE_BLOCK_SEQUENCE_ENTRY_STATE              // Expect an entry of a block sequence.
-	yaml_PARSE_INDENTLESS_SEQUENCE_ENTRY_STATE         // Expect an entry of an indentless sequence.
-	yaml_PARSE_BLOCK_MAPPING_FIRST_KEY_STATE           // Expect the first key of a block mapping.
-	yaml_PARSE_BLOCK_MAPPING_KEY_STATE                 // Expect a block mapping key.
-	yaml_PARSE_BLOCK_MAPPING_VALUE_STATE               // Expect a block mapping value.
-	yaml_PARSE_FLOW_SEQUENCE_FIRST_ENTRY_STATE         // Expect the first entry of a flow sequence.
-	yaml_PARSE_FLOW_SEQUENCE_ENTRY_STATE               // Expect an entry of a flow sequence.
-	yaml_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_KEY_STATE   // Expect a key of an ordered mapping.
-	yaml_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_VALUE_STATE // Expect a value of an ordered mapping.
-	yaml_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_END_STATE   // Expect the and of an ordered mapping entry.
-	yaml_PARSE_FLOW_MAPPING_FIRST_KEY_STATE            // Expect the first key of a flow mapping.
-	yaml_PARSE_FLOW_MAPPING_KEY_STATE                  // Expect a key of a flow mapping.
-	yaml_PARSE_FLOW_MAPPING_VALUE_STATE                // Expect a value of a flow mapping.
-	yaml_PARSE_FLOW_MAPPING_EMPTY_VALUE_STATE          // Expect an empty value of a flow mapping.
-	yaml_PARSE_END_STATE                               // Expect nothing.
-)
-
-func (ps yaml_parser_state_t) String() string {
-	switch ps {
-	case yaml_PARSE_STREAM_START_STATE:
-		return "yaml_PARSE_STREAM_START_STATE"
-	case yaml_PARSE_IMPLICIT_DOCUMENT_START_STATE:
-		return "yaml_PARSE_IMPLICIT_DOCUMENT_START_STATE"
-	case yaml_PARSE_DOCUMENT_START_STATE:
-		return "yaml_PARSE_DOCUMENT_START_STATE"
-	case yaml_PARSE_DOCUMENT_CONTENT_STATE:
-		return "yaml_PARSE_DOCUMENT_CONTENT_STATE"
-	case yaml_PARSE_DOCUMENT_END_STATE:
-		return "yaml_PARSE_DOCUMENT_END_STATE"
-	case yaml_PARSE_BLOCK_NODE_STATE:
-		return "yaml_PARSE_BLOCK_NODE_STATE"
-	case yaml_PARSE_BLOCK_NODE_OR_INDENTLESS_SEQUENCE_STATE:
-		return "yaml_PARSE_BLOCK_NODE_OR_INDENTLESS_SEQUENCE_STATE"
-	case yaml_PARSE_FLOW_NODE_STATE:
-		return "yaml_PARSE_FLOW_NODE_STATE"
-	case yaml_PARSE_BLOCK_SEQUENCE_FIRST_ENTRY_STATE:
-		return "yaml_PARSE_BLOCK_SEQUENCE_FIRST_ENTRY_STATE"
-	case yaml_PARSE_BLOCK_SEQUENCE_ENTRY_STATE:
-		return "yaml_PARSE_BLOCK_SEQUENCE_ENTRY_STATE"
-	case yaml_PARSE_INDENTLESS_SEQUENCE_ENTRY_STATE:
-		return "yaml_PARSE_INDENTLESS_SEQUENCE_ENTRY_STATE"
-	case yaml_PARSE_BLOCK_MAPPING_FIRST_KEY_STATE:
-		return "yaml_PARSE_BLOCK_MAPPING_FIRST_KEY_STATE"
-	case yaml_PARSE_BLOCK_MAPPING_KEY_STATE:
-		return "yaml_PARSE_BLOCK_MAPPING_KEY_STATE"
-	case yaml_PARSE_BLOCK_MAPPING_VALUE_STATE:
-		return "yaml_PARSE_BLOCK_MAPPING_VALUE_STATE"
-	case yaml_PARSE_FLOW_SEQUENCE_FIRST_ENTRY_STATE:
-		return "yaml_PARSE_FLOW_SEQUENCE_FIRST_ENTRY_STATE"
-	case yaml_PARSE_FLOW_SEQUENCE_ENTRY_STATE:
-		return "yaml_PARSE_FLOW_SEQUENCE_ENTRY_STATE"
-	case yaml_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_KEY_STATE:
-		return "yaml_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_KEY_STATE"
-	case yaml_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_VALUE_STATE:
-		return "yaml_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_VALUE_STATE"
-	case yaml_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_END_STATE:
-		return "yaml_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_END_STATE"
-	case yaml_PARSE_FLOW_MAPPING_FIRST_KEY_STATE:
-		return "yaml_PARSE_FLOW_MAPPING_FIRST_KEY_STATE"
-	case yaml_PARSE_FLOW_MAPPING_KEY_STATE:
-		return "yaml_PARSE_FLOW_MAPPING_KEY_STATE"
-	case yaml_PARSE_FLOW_MAPPING_VALUE_STATE:
-		return "yaml_PARSE_FLOW_MAPPING_VALUE_STATE"
-	case yaml_PARSE_FLOW_MAPPING_EMPTY_VALUE_STATE:
-		return "yaml_PARSE_FLOW_MAPPING_EMPTY_VALUE_STATE"
-	case yaml_PARSE_END_STATE:
-		return "yaml_PARSE_END_STATE"
-	}
-	return "<unknown parser state>"
-}
-
-// This structure holds aliases data.
-type yaml_alias_data_t struct {
-	anchor []byte      // The anchor.
-	index  int         // The node id.
-	mark   yaml_mark_t // The anchor mark.
-}
-
-// The parser structure.
-//
-// All members are internal. Manage the structure using the
-// yaml_parser_ family of functions.
-type yaml_parser_t struct {
-
-	// Error handling
-
-	error yaml_error_type_t // Error type.
-
-	problem string // Error description.
-
-	// The byte about which the problem occured.
-	problem_offset int
-	problem_value  int
-	problem_mark   yaml_mark_t
-
-	// The error context.
-	context      string
-	context_mark yaml_mark_t
-
-	// Reader stuff
-
-	read_handler yaml_read_handler_t // Read handler.
-
-	input_file io.Reader // File input data.
-	input      []byte    // String input data.
-	input_pos  int
-
-	eof bool // EOF flag
-
-	buffer     []byte // The working buffer.
-	buffer_pos int    // The current position of the buffer.
-
-	unread int // The number of unread characters in the buffer.
-
-	raw_buffer     []byte // The raw buffer.
-	raw_buffer_pos int    // The current position of the buffer.
-
-	encoding yaml_encoding_t // The input encoding.
-
-	offset int         // The offset of the current position (in bytes).
-	mark   yaml_mark_t // The mark of the current position.
-
-	// Scanner stuff
-
-	stream_start_produced bool // Have we started to scan the input stream?
-	stream_end_produced   bool // Have we reached the end of the input stream?
-
-	flow_level int // The number of unclosed '[' and '{' indicators.
-
-	tokens          []yaml_token_t // The tokens queue.
-	tokens_head     int            // The head of the tokens queue.
-	tokens_parsed   int            // The number of tokens fetched from the queue.
-	token_available bool           // Does the tokens queue contain a token ready for dequeueing.
-
-	indent  int   // The current indentation level.
-	indents []int // The indentation levels stack.
-
-	simple_key_allowed bool                // May a simple key occur at the current position?
-	simple_keys        []yaml_simple_key_t // The stack of simple keys.
-
-	// Parser stuff
-
-	state          yaml_parser_state_t    // The current parser state.
-	states         []yaml_parser_state_t  // The parser states stack.
-	marks          []yaml_mark_t          // The stack of marks.
-	tag_directives []yaml_tag_directive_t // The list of TAG directives.
-
-	// Dumper stuff
-
-	aliases []yaml_alias_data_t // The alias data.
-
-	document *yaml_document_t // The currently parsed document.
-}
-
-// Emitter Definitions
-
-// The prototype of a write handler.
-//
-// The write handler is called when the emitter needs to flush the accumulated
-// characters to the output.  The handler should write @a size bytes of the
-// @a buffer to the output.
-//
-// @param[in,out]   data        A pointer to an application data specified by
-//                              yaml_emitter_set_output().
-// @param[in]       buffer      The buffer with bytes to be written.
-// @param[in]       size        The size of the buffer.
-//
-// @returns On success, the handler should return @c 1.  If the handler failed,
-// the returned value should be @c 0.
-//
-type yaml_write_handler_t func(emitter *yaml_emitter_t, buffer []byte) error
-
-type yaml_emitter_state_t int
-
-// The emitter states.
-const (
-	// Expect STREAM-START.
-	yaml_EMIT_STREAM_START_STATE yaml_emitter_state_t = iota
-
-	yaml_EMIT_FIRST_DOCUMENT_START_STATE       // Expect the first DOCUMENT-START or STREAM-END.
-	yaml_EMIT_DOCUMENT_START_STATE             // Expect DOCUMENT-START or STREAM-END.
-	yaml_EMIT_DOCUMENT_CONTENT_STATE           // Expect the content of a document.
-	yaml_EMIT_DOCUMENT_END_STATE               // Expect DOCUMENT-END.
-	yaml_EMIT_FLOW_SEQUENCE_FIRST_ITEM_STATE   // Expect the first item of a flow sequence.
-	yaml_EMIT_FLOW_SEQUENCE_ITEM_STATE         // Expect an item of a flow sequence.
-	yaml_EMIT_FLOW_MAPPING_FIRST_KEY_STATE     // Expect the first key of a flow mapping.
-	yaml_EMIT_FLOW_MAPPING_KEY_STATE           // Expect a key of a flow mapping.
-	yaml_EMIT_FLOW_MAPPING_SIMPLE_VALUE_STATE  // Expect a value for a simple key of a flow mapping.
-	yaml_EMIT_FLOW_MAPPING_VALUE_STATE         // Expect a value of a flow mapping.
-	yaml_EMIT_BLOCK_SEQUENCE_FIRST_ITEM_STATE  // Expect the first item of a block sequence.
-	yaml_EMIT_BLOCK_SEQUENCE_ITEM_STATE        // Expect an item of a block sequence.
-	yaml_EMIT_BLOCK_MAPPING_FIRST_KEY_STATE    // Expect the first key of a block mapping.
-	yaml_EMIT_BLOCK_MAPPING_KEY_STATE          // Expect the key of a block mapping.
-	yaml_EMIT_BLOCK_MAPPING_SIMPLE_VALUE_STATE // Expect a value for a simple key of a block mapping.
-	yaml_EMIT_BLOCK_MAPPING_VALUE_STATE        // Expect a value of a block mapping.
-	yaml_EMIT_END_STATE                        // Expect nothing.
-)
-
-// The emitter structure.
-//
-// All members are internal.  Manage the structure using the @c yaml_emitter_
-// family of functions.
-type yaml_emitter_t struct {
-
-	// Error handling
-
-	error   yaml_error_type_t // Error type.
-	problem string            // Error description.
-
-	// Writer stuff
-
-	write_handler yaml_write_handler_t // Write handler.
-
-	output_buffer *[]byte   // String output data.
-	output_file   io.Writer // File output data.
-
-	buffer     []byte // The working buffer.
-	buffer_pos int    // The current position of the buffer.
-
-	raw_buffer     []byte // The raw buffer.
-	raw_buffer_pos int    // The current position of the buffer.
-
-	encoding yaml_encoding_t // The stream encoding.
-
-	// Emitter stuff
-
-	canonical   bool         // If the output is in the canonical style?
-	best_indent int          // The number of indentation spaces.
-	best_width  int          // The preferred width of the output lines.
-	unicode     bool         // Allow unescaped non-ASCII characters?
-	line_break  yaml_break_t // The preferred line break.
-
-	state  yaml_emitter_state_t   // The current emitter state.
-	states []yaml_emitter_state_t // The stack of states.
-
-	events      []yaml_event_t // The event queue.
-	events_head int            // The head of the event queue.
-
-	indents []int // The stack of indentation levels.
-
-	tag_directives []yaml_tag_directive_t // The list of tag directives.
-
-	indent int // The current indentation level.
-
-	flow_level int // The current flow level.
-
-	root_context       bool // Is it the document root context?
-	sequence_context   bool // Is it a sequence context?
-	mapping_context    bool // Is it a mapping context?
-	simple_key_context bool // Is it a simple mapping key context?
-
-	line       int  // The current line.
-	column     int  // The current column.
-	whitespace bool // If the last character was a whitespace?
-	indention  bool // If the last character was an indentation character (' ', '-', '?', ':')?
-	open_ended bool // If an explicit document end is required?
-
-	// Anchor analysis.
-	anchor_data struct {
-		anchor []byte // The anchor value.
-		alias  bool   // Is it an alias?
-	}
-
-	// Tag analysis.
-	tag_data struct {
-		handle []byte // The tag handle.
-		suffix []byte // The tag suffix.
-	}
-
-	// Scalar analysis.
-	scalar_data struct {
-		value                 []byte              // The scalar value.
-		multiline             bool                // Does the scalar contain line breaks?
-		flow_plain_allowed    bool                // Can the scalar be expessed in the flow plain style?
-		block_plain_allowed   bool                // Can the scalar be expressed in the block plain style?
-		single_quoted_allowed bool                // Can the scalar be expressed in the single quoted style?
-		block_allowed         bool                // Can the scalar be expressed in the literal or folded styles?
-		style                 yaml_scalar_style_t // The output style.
-	}
-
-	// Dumper stuff
-
-	opened bool // If the stream was already opened?
-	closed bool // If the stream was already closed?
-
-	// The information associated with the document nodes.
-	anchors *struct {
-		references int  // The number of references.
-		anchor     int  // The anchor id.
-		serialized bool // If the node has been emitted?
-	}
-
-	last_anchor_id int // The last assigned anchor id.
-
-	document *yaml_document_t // The currently emitted document.
-}
diff --git a/yamlprivateh.go b/yamlprivateh.go
deleted file mode 100644
index 8110ce3..0000000
--- a/yamlprivateh.go
+++ /dev/null
@@ -1,173 +0,0 @@
-package yaml
-
-const (
-	// The size of the input raw buffer.
-	input_raw_buffer_size = 512
-
-	// The size of the input buffer.
-	// It should be possible to decode the whole raw buffer.
-	input_buffer_size = input_raw_buffer_size * 3
-
-	// The size of the output buffer.
-	output_buffer_size = 128
-
-	// The size of the output raw buffer.
-	// It should be possible to encode the whole output buffer.
-	output_raw_buffer_size = (output_buffer_size*2 + 2)
-
-	// The size of other stacks and queues.
-	initial_stack_size  = 16
-	initial_queue_size  = 16
-	initial_string_size = 16
-)
-
-// Check if the character at the specified position is an alphabetical
-// character, a digit, '_', or '-'.
-func is_alpha(b []byte, i int) bool {
-	return b[i] >= '0' && b[i] <= '9' || b[i] >= 'A' && b[i] <= 'Z' || b[i] >= 'a' && b[i] <= 'z' || b[i] == '_' || b[i] == '-'
-}
-
-// Check if the character at the specified position is a digit.
-func is_digit(b []byte, i int) bool {
-	return b[i] >= '0' && b[i] <= '9'
-}
-
-// Get the value of a digit.
-func as_digit(b []byte, i int) int {
-	return int(b[i]) - '0'
-}
-
-// Check if the character at the specified position is a hex-digit.
-func is_hex(b []byte, i int) bool {
-	return b[i] >= '0' && b[i] <= '9' || b[i] >= 'A' && b[i] <= 'F' || b[i] >= 'a' && b[i] <= 'f'
-}
-
-// Get the value of a hex-digit.
-func as_hex(b []byte, i int) int {
-	bi := b[i]
-	if bi >= 'A' && bi <= 'F' {
-		return int(bi) - 'A' + 10
-	}
-	if bi >= 'a' && bi <= 'f' {
-		return int(bi) - 'a' + 10
-	}
-	return int(bi) - '0'
-}
-
-// Check if the character is ASCII.
-func is_ascii(b []byte, i int) bool {
-	return b[i] <= 0x7F
-}
-
-// Check if the character at the start of the buffer can be printed unescaped.
-func is_printable(b []byte, i int) bool {
-	return ((b[i] == 0x0A) || // . == #x0A
-		(b[i] >= 0x20 && b[i] <= 0x7E) || // #x20 <= . <= #x7E
-		(b[i] == 0xC2 && b[i+1] >= 0xA0) || // #0xA0 <= . <= #xD7FF
-		(b[i] > 0xC2 && b[i] < 0xED) ||
-		(b[i] == 0xED && b[i+1] < 0xA0) ||
-		(b[i] == 0xEE) ||
-		(b[i] == 0xEF && // #xE000 <= . <= #xFFFD
-			!(b[i+1] == 0xBB && b[i+2] == 0xBF) && // && . != #xFEFF
-			!(b[i+1] == 0xBF && (b[i+2] == 0xBE || b[i+2] == 0xBF))))
-}
-
-// Check if the character at the specified position is NUL.
-func is_z(b []byte, i int) bool {
-	return b[i] == 0x00
-}
-
-// Check if the beginning of the buffer is a BOM.
-func is_bom(b []byte, i int) bool {
-	return b[0] == 0xEF && b[1] == 0xBB && b[2] == 0xBF
-}
-
-// Check if the character at the specified position is space.
-func is_space(b []byte, i int) bool {
-	return b[i] == ' '
-}
-
-// Check if the character at the specified position is tab.
-func is_tab(b []byte, i int) bool {
-	return b[i] == '\t'
-}
-
-// Check if the character at the specified position is blank (space or tab).
-func is_blank(b []byte, i int) bool {
-	//return is_space(b, i) || is_tab(b, i)
-	return b[i] == ' ' || b[i] == '\t'
-}
-
-// Check if the character at the specified position is a line break.
-func is_break(b []byte, i int) bool {
-	return (b[i] == '\r' || // CR (#xD)
-		b[i] == '\n' || // LF (#xA)
-		b[i] == 0xC2 && b[i+1] == 0x85 || // NEL (#x85)
-		b[i] == 0xE2 && b[i+1] == 0x80 && b[i+2] == 0xA8 || // LS (#x2028)
-		b[i] == 0xE2 && b[i+1] == 0x80 && b[i+2] == 0xA9) // PS (#x2029)
-}
-
-func is_crlf(b []byte, i int) bool {
-	return b[i] == '\r' && b[i+1] == '\n'
-}
-
-// Check if the character is a line break or NUL.
-func is_breakz(b []byte, i int) bool {
-	//return is_break(b, i) || is_z(b, i)
-	return (        // is_break:
-	b[i] == '\r' || // CR (#xD)
-		b[i] == '\n' || // LF (#xA)
-		b[i] == 0xC2 && b[i+1] == 0x85 || // NEL (#x85)
-		b[i] == 0xE2 && b[i+1] == 0x80 && b[i+2] == 0xA8 || // LS (#x2028)
-		b[i] == 0xE2 && b[i+1] == 0x80 && b[i+2] == 0xA9 || // PS (#x2029)
-		// is_z:
-		b[i] == 0)
-}
-
-// Check if the character is a line break, space, or NUL.
-func is_spacez(b []byte, i int) bool {
-	//return is_space(b, i) || is_breakz(b, i)
-	return ( // is_space:
-	b[i] == ' ' ||
-		// is_breakz:
-		b[i] == '\r' || // CR (#xD)
-		b[i] == '\n' || // LF (#xA)
-		b[i] == 0xC2 && b[i+1] == 0x85 || // NEL (#x85)
-		b[i] == 0xE2 && b[i+1] == 0x80 && b[i+2] == 0xA8 || // LS (#x2028)
-		b[i] == 0xE2 && b[i+1] == 0x80 && b[i+2] == 0xA9 || // PS (#x2029)
-		b[i] == 0)
-}
-
-// Check if the character is a line break, space, tab, or NUL.
-func is_blankz(b []byte, i int) bool {
-	//return is_blank(b, i) || is_breakz(b, i)
-	return ( // is_blank:
-	b[i] == ' ' || b[i] == '\t' ||
-		// is_breakz:
-		b[i] == '\r' || // CR (#xD)
-		b[i] == '\n' || // LF (#xA)
-		b[i] == 0xC2 && b[i+1] == 0x85 || // NEL (#x85)
-		b[i] == 0xE2 && b[i+1] == 0x80 && b[i+2] == 0xA8 || // LS (#x2028)
-		b[i] == 0xE2 && b[i+1] == 0x80 && b[i+2] == 0xA9 || // PS (#x2029)
-		b[i] == 0)
-}
-
-// Determine the width of the character.
-func width(b byte) int {
-	// Don't replace these by a switch without first
-	// confirming that it is being inlined.
-	if b&0x80 == 0x00 {
-		return 1
-	}
-	if b&0xE0 == 0xC0 {
-		return 2
-	}
-	if b&0xF0 == 0xE0 {
-		return 3
-	}
-	if b&0xF8 == 0xF0 {
-		return 4
-	}
-	return 0
-
-}
