Decoding side builds.
diff --git a/api_c.go b/api_c.go
new file mode 100644
index 0000000..5d7a0f0
--- /dev/null
+++ b/api_c.go
@@ -0,0 +1,1164 @@
+package goyaml
+
+import (
+	"io"
+	"os"
+)
+
+///*
+// * Extend a string.
+// */
+//
+//YAML_DECLARE(int)
+//yaml_string_extend(yaml_char_t **start,
+//        yaml_char_t **pointer, yaml_char_t **end)
+//{
+//    yaml_char_t *new_start = yaml_realloc(*start, (*end - *start)*2);
+//
+//    if (!new_start) return 0;
+//
+//    memset(new_start + (*end - *start), 0, *end - *start);
+//
+//    *pointer = new_start + (*pointer - *start);
+//    *end = new_start + (*end - *start)*2;
+//    *start = new_start;
+//
+//    return 1;
+//}
+//
+///*
+// * Append a string B to a string A.
+// */
+//
+//YAML_DECLARE(int)
+//yaml_string_join(
+//        yaml_char_t **a_start, yaml_char_t **a_pointer, yaml_char_t **a_end,
+//        yaml_char_t **b_start, yaml_char_t **b_pointer, yaml_char_t **b_end)
+//{
+//    if (*b_start == *b_pointer)
+//        return 1;
+//
+//    while (*a_end - *a_pointer <= *b_pointer - *b_start) {
+//        if (!yaml_string_extend(a_start, a_pointer, a_end))
+//            return 0;
+//    }
+//
+//    memcpy(*a_pointer, *b_start, *b_pointer - *b_start);
+//    *a_pointer += *b_pointer - *b_start;
+//
+//    return 1;
+//}
+//
+///*
+// * Extend a stack.
+// */
+//
+//YAML_DECLARE(int)
+//yaml_stack_extend(void **start, void **top, void **end)
+//{
+//    void *new_start = yaml_realloc(*start, ((char *)*end - (char *)*start)*2);
+//
+//    if (!new_start) return 0;
+//
+//    *top = (char *)new_start + ((char *)*top - (char *)*start);
+//    *end = (char *)new_start + ((char *)*end - (char *)*start)*2;
+//    *start = new_start;
+//
+//    return 1;
+//}
+
+func yaml_insert_token(parser *yaml_parser_t, pos int, token *yaml_token_t) {
+	// 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, yaml_token_t{})
+	if pos < 0 {
+		return
+	}
+	copy(parser.tokens[parser.tokens_head+pos+1:], parser.tokens[parser.tokens_head+pos:])
+	parser.tokens[pos] = *token
+}
+
+// Create a new parser object.
+func yaml_parser_initialize(parser *yaml_parser_t) bool {
+	// [Go] These should be initialized lazily, and probably start with smaller sizes.
+	parser.raw_buffer = make([]byte, 0, input_raw_buffer_size)
+	parser.buffer = make([]byte, 0, input_buffer_size)
+	parser.tokens = make([]yaml_token_t, 0, initial_queue_size)
+	parser.indents = make([]int, 0, initial_stack_size)
+	parser.simple_keys = make([]yaml_simple_key_t, 0, initial_stack_size)
+	parser.states = make([]yaml_parser_state_t, 0, initial_stack_size)
+	parser.marks = make([]yaml_mark_t, 0, initial_stack_size)
+	parser.tag_directives = make([]yaml_tag_directive_t, 0, initial_stack_size)
+	return true
+}
+
+// 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.
+// */
+//
+//YAML_DECLARE(void)
+//yaml_parser_set_encoding(yaml_parser_t *parser, yaml_encoding_t encoding)
+//{
+//    assert(parser); // Non-NULL parser object expected.
+//    assert(!parser.encoding); // Encoding is already set or detected.
+//
+//    parser.encoding = encoding;
+//}
+//
+///*
+// * Create a new emitter object.
+// */
+//
+//YAML_DECLARE(int)
+//yaml_emitter_initialize(yaml_emitter_t *emitter)
+//{
+//    assert(emitter);    // Non-NULL emitter object expected.
+//
+//    memset(emitter, 0, sizeof(yaml_emitter_t));
+//    if (!BUFFER_INIT(emitter, emitter.buffer, OUTPUT_BUFFER_SIZE))
+//        goto error;
+//    if (!BUFFER_INIT(emitter, emitter.raw_buffer, OUTPUT_RAW_BUFFER_SIZE))
+//        goto error;
+//    if (!STACK_INIT(emitter, emitter.states, INITIAL_STACK_SIZE))
+//        goto error;
+//    if (!QUEUE_INIT(emitter, emitter.events, INITIAL_QUEUE_SIZE))
+//        goto error;
+//    if (!STACK_INIT(emitter, emitter.indents, INITIAL_STACK_SIZE))
+//        goto error;
+//    if (!STACK_INIT(emitter, emitter.tag_directives, INITIAL_STACK_SIZE))
+//        goto error;
+//
+//    return 1;
+//
+//error:
+//
+//    BUFFER_DEL(emitter, emitter.buffer);
+//    BUFFER_DEL(emitter, emitter.raw_buffer);
+//    STACK_DEL(emitter, emitter.states);
+//    QUEUE_DEL(emitter, emitter.events);
+//    STACK_DEL(emitter, emitter.indents);
+//    STACK_DEL(emitter, emitter.tag_directives);
+//
+//    return 0;
+//}
+//
+///*
+// * Destroy an emitter object.
+// */
+//
+//YAML_DECLARE(void)
+//yaml_emitter_delete(yaml_emitter_t *emitter)
+//{
+//    assert(emitter);    // Non-NULL emitter object expected.
+//
+//    BUFFER_DEL(emitter, emitter.buffer);
+//    BUFFER_DEL(emitter, emitter.raw_buffer);
+//    STACK_DEL(emitter, emitter.states);
+//    while (!QUEUE_EMPTY(emitter, emitter.events)) {
+//        yaml_event_delete(&DEQUEUE(emitter, emitter.events));
+//    }
+//    QUEUE_DEL(emitter, emitter.events);
+//    STACK_DEL(emitter, emitter.indents);
+//    while (!STACK_EMPTY(empty, emitter.tag_directives)) {
+//        yaml_tag_directive_t tag_directive = POP(emitter, emitter.tag_directives);
+//        yaml_free(tag_directive.handle);
+//        yaml_free(tag_directive.prefix);
+//    }
+//    STACK_DEL(emitter, emitter.tag_directives);
+//    yaml_free(emitter.anchors);
+//
+//    memset(emitter, 0, sizeof(yaml_emitter_t));
+//}
+//
+///*
+// * String write handler.
+// */
+//
+//static int
+//yaml_string_write_handler(void *data, unsigned char *buffer, size_t size)
+//{
+//    yaml_emitter_t *emitter = data;
+//
+//    if (emitter.output.string.size + *emitter.output.string.size_written
+//            < size) {
+//        memcpy(emitter.output.string.buffer
+//                + *emitter.output.string.size_written,
+//                buffer,
+//                emitter.output.string.size
+//                - *emitter.output.string.size_written);
+//        *emitter.output.string.size_written = emitter.output.string.size;
+//        return 0;
+//    }
+//
+//    memcpy(emitter.output.string.buffer
+//            + *emitter.output.string.size_written, buffer, size);
+//    *emitter.output.string.size_written += size;
+//    return 1;
+//}
+//
+///*
+// * File write handler.
+// */
+//
+//static int
+//yaml_file_write_handler(void *data, unsigned char *buffer, size_t size)
+//{
+//    yaml_emitter_t *emitter = data;
+//
+//    return (fwrite(buffer, 1, size, emitter.output.file) == size);
+//}
+///*
+// * Set a string output.
+// */
+//
+//YAML_DECLARE(void)
+//yaml_emitter_set_output_string(yaml_emitter_t *emitter,
+//        unsigned char *output, size_t size, size_t *size_written)
+//{
+//    assert(emitter);    // Non-NULL emitter object expected.
+//    assert(!emitter.write_handler);    // You can set the output only once.
+//    assert(output);     // Non-NULL output string expected.
+//
+//    emitter.write_handler = yaml_string_write_handler;
+//    emitter.write_handler_data = emitter;
+//
+//    emitter.output.string.buffer = output;
+//    emitter.output.string.size = size;
+//    emitter.output.string.size_written = size_written;
+//    *size_written = 0;
+//}
+//
+///*
+// * Set a file output.
+// */
+//
+//YAML_DECLARE(void)
+//yaml_emitter_set_output_file(yaml_emitter_t *emitter, FILE *file)
+//{
+//    assert(emitter);    // Non-NULL emitter object expected.
+//    assert(!emitter.write_handler);    // You can set the output only once.
+//    assert(file);       // Non-NULL file object expected.
+//
+//    emitter.write_handler = yaml_file_write_handler;
+//    emitter.write_handler_data = emitter;
+//
+//    emitter.output.file = file;
+//}
+//
+///*
+// * Set a generic output handler.
+// */
+//
+//YAML_DECLARE(void)
+//yaml_emitter_set_output(yaml_emitter_t *emitter,
+//        yaml_write_handler_t *handler, void *data)
+//{
+//    assert(emitter);    // Non-NULL emitter object expected.
+//    assert(!emitter.write_handler);    // You can set the output only once.
+//    assert(handler);    // Non-NULL handler object expected.
+//
+//    emitter.write_handler = handler;
+//    emitter.write_handler_data = data;
+//}
+//
+///*
+// * Set the output encoding.
+// */
+//
+//YAML_DECLARE(void)
+//yaml_emitter_set_encoding(yaml_emitter_t *emitter, yaml_encoding_t encoding)
+//{
+//    assert(emitter);    // Non-NULL emitter object expected.
+//    assert(!emitter.encoding);     // You can set encoding only once.
+//
+//    emitter.encoding = encoding;
+//}
+//
+///*
+// * Set the canonical output style.
+// */
+//
+//YAML_DECLARE(void)
+//yaml_emitter_set_canonical(yaml_emitter_t *emitter, int canonical)
+//{
+//    assert(emitter);    // Non-NULL emitter object expected.
+//
+//    emitter.canonical = (canonical != 0);
+//}
+//
+///*
+// * Set the indentation increment.
+// */
+//
+//YAML_DECLARE(void)
+//yaml_emitter_set_indent(yaml_emitter_t *emitter, int indent)
+//{
+//    assert(emitter);    // Non-NULL emitter object expected.
+//
+//    emitter.best_indent = (1 < indent && indent < 10) ? indent : 2;
+//}
+//
+///*
+// * Set the preferred line width.
+// */
+//
+//YAML_DECLARE(void)
+//yaml_emitter_set_width(yaml_emitter_t *emitter, int width)
+//{
+//    assert(emitter);    // Non-NULL emitter object expected.
+//
+//    emitter.best_width = (width >= 0) ? width : -1;
+//}
+//
+///*
+// * Set if unescaped non-ASCII characters are allowed.
+// */
+//
+//YAML_DECLARE(void)
+//yaml_emitter_set_unicode(yaml_emitter_t *emitter, int unicode)
+//{
+//    assert(emitter);    // Non-NULL emitter object expected.
+//
+//    emitter.unicode = (unicode != 0);
+//}
+//
+///*
+// * Set the preferred line break character.
+// */
+//
+//YAML_DECLARE(void)
+//yaml_emitter_set_break(yaml_emitter_t *emitter, yaml_break_t line_break)
+//{
+//    assert(emitter);    // Non-NULL emitter object expected.
+//
+//    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.
+// */
+//
+//YAML_DECLARE(int)
+//yaml_stream_start_event_initialize(yaml_event_t *event,
+//        yaml_encoding_t encoding)
+//{
+//    yaml_mark_t mark = { 0, 0, 0 };
+//
+//    assert(event);  // Non-NULL event object is expected.
+//
+//    STREAM_START_EVENT_INIT(*event, encoding, mark, mark);
+		//*event = yaml_event_t{
+		//	typ:        yaml_STREAM_START_EVENT,
+		//	start_mark: mark,
+		//	end_mark:   mark,
+		//}
+		//event.stream_start.encoding = encoding
+//
+//    return 1;
+//}
+//
+///*
+// * Create STREAM-END.
+// */
+//
+//YAML_DECLARE(int)
+//yaml_stream_end_event_initialize(yaml_event_t *event)
+//{
+//    yaml_mark_t mark = { 0, 0, 0 };
+//
+//    assert(event);  // Non-NULL event object is expected.
+//
+//    STREAM_END_EVENT_INIT(*event, mark, mark);
+	//*event = yaml_event_t{
+	//	typ: yaml_STREAM_END_EVENT,
+	//	start_mark: mark,
+	//	end_mark: mark,
+	//}
+//
+//    return 1;
+//}
+//
+///*
+// * Create DOCUMENT-START.
+// */
+//
+//YAML_DECLARE(int)
+//yaml_document_start_event_initialize(yaml_event_t *event,
+//        yaml_version_directive_t *version_directive,
+//        yaml_tag_directive_t *tag_directives_start,
+//        yaml_tag_directive_t *tag_directives_end,
+//        int implicit)
+//{
+//    struct {
+//        yaml_error_type_t error;
+//    } context;
+//    yaml_mark_t mark = { 0, 0, 0 };
+//    yaml_version_directive_t *version_directive_copy = NULL;
+//    struct {
+//        yaml_tag_directive_t *start;
+//        yaml_tag_directive_t *end;
+//        yaml_tag_directive_t *top;
+//    } tag_directives_copy = { NULL, NULL, NULL };
+//    yaml_tag_directive_t value = { NULL, NULL };
+//
+//    assert(event);          // Non-NULL event object is expected.
+//    assert((tag_directives_start && tag_directives_end) ||
+//            (tag_directives_start == tag_directives_end));
+//                            // Valid tag directives are expected.
+//
+//    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) {
+//        yaml_tag_directive_t *tag_directive;
+//        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_START_EVENT_INIT(*event, version_directive_copy,
+//            tag_directives_copy.start, tag_directives_copy.top,
+//            implicit, mark, mark);
+	//*event = yaml_event_t{
+	//	typ: yaml_DOCUMENT_START_EVENT,
+	//	start_mark: mark,
+	//	end_mark: mark,
+	//}
+	//event.document_start.version_directive = version_directive_copy
+	//event.document_start.tag_directives = tag_directives
+	//event.document_start.implicit = implicit
+//
+//    return 1;
+//
+//error:
+//    yaml_free(version_directive_copy);
+//    while (!STACK_EMPTY(context, tag_directives_copy)) {
+//        yaml_tag_directive_t value = 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;
+//}
+//
+///*
+// * Create DOCUMENT-END.
+// */
+//
+//YAML_DECLARE(int)
+//yaml_document_end_event_initialize(yaml_event_t *event, int implicit)
+//{
+//    yaml_mark_t mark = { 0, 0, 0 };
+//
+//    assert(event);      // Non-NULL emitter object is expected.
+//
+//    DOCUMENT_END_EVENT_INIT(*event, implicit, mark, mark);
+//
+//    return 1;
+//}
+//
+///*
+// * Create ALIAS.
+// */
+//
+//YAML_DECLARE(int)
+//yaml_alias_event_initialize(yaml_event_t *event, yaml_char_t *anchor)
+//{
+//    yaml_mark_t mark = { 0, 0, 0 };
+//    yaml_char_t *anchor_copy = 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.
+// */
+//
+//YAML_DECLARE(int)
+//yaml_scalar_event_initialize(yaml_event_t *event,
+//        yaml_char_t *anchor, yaml_char_t *tag,
+//        yaml_char_t *value, int length,
+//        int plain_implicit, int quoted_implicit,
+//        yaml_scalar_style_t style)
+//{
+//    yaml_mark_t mark = { 0, 0, 0 };
+//    yaml_char_t *anchor_copy = NULL;
+//    yaml_char_t *tag_copy = NULL;
+//    yaml_char_t *value_copy = NULL;
+//
+//    assert(event);      // Non-NULL event object is expected.
+//    assert(value);      // Non-NULL anchor is expected.
+//
+//    if (anchor) {
+//        if (!yaml_check_utf8(anchor, strlen((char *)anchor))) goto error;
+//        anchor_copy = yaml_strdup(anchor);
+//        if (!anchor_copy) goto error;
+//    }
+//
+//    if (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_EVENT_INIT(*event, anchor_copy, tag_copy, value_copy, length,
+//            plain_implicit, quoted_implicit, style, mark, mark);
+//
+//    return 1;
+//
+//error:
+//    yaml_free(anchor_copy);
+//    yaml_free(tag_copy);
+//    yaml_free(value_copy);
+//
+//    return 0;
+//}
+//
+///*
+// * Create SEQUENCE-START.
+// */
+//
+//YAML_DECLARE(int)
+//yaml_sequence_start_event_initialize(yaml_event_t *event,
+//        yaml_char_t *anchor, yaml_char_t *tag, int implicit,
+//        yaml_sequence_style_t style)
+//{
+//    yaml_mark_t mark = { 0, 0, 0 };
+//    yaml_char_t *anchor_copy = NULL;
+//    yaml_char_t *tag_copy = NULL;
+//
+//    assert(event);      // Non-NULL event object is expected.
+//
+//    if (anchor) {
+//        if (!yaml_check_utf8(anchor, strlen((char *)anchor))) goto error;
+//        anchor_copy = yaml_strdup(anchor);
+//        if (!anchor_copy) goto error;
+//    }
+//
+//    if (tag) {
+//        if (!yaml_check_utf8(tag, strlen((char *)tag))) goto error;
+//        tag_copy = yaml_strdup(tag);
+//        if (!tag_copy) goto error;
+//    }
+//
+//    SEQUENCE_START_EVENT_INIT(*event, anchor_copy, tag_copy,
+//            implicit, style, mark, mark);
+//
+//    return 1;
+//
+//error:
+//    yaml_free(anchor_copy);
+//    yaml_free(tag_copy);
+//
+//    return 0;
+//}
+//
+///*
+// * Create SEQUENCE-END.
+// */
+//
+//YAML_DECLARE(int)
+//yaml_sequence_end_event_initialize(yaml_event_t *event)
+//{
+//    yaml_mark_t mark = { 0, 0, 0 };
+//
+//    assert(event);      // Non-NULL event object is expected.
+//
+//    SEQUENCE_END_EVENT_INIT(*event, mark, mark);
+//
+//    return 1;
+//}
+//
+///*
+// * Create MAPPING-START.
+// */
+//
+//YAML_DECLARE(int)
+//yaml_mapping_start_event_initialize(yaml_event_t *event,
+//        yaml_char_t *anchor, yaml_char_t *tag, int implicit,
+//        yaml_mapping_style_t style)
+//{
+//    yaml_mark_t mark = { 0, 0, 0 };
+//    yaml_char_t *anchor_copy = NULL;
+//    yaml_char_t *tag_copy = NULL;
+//
+//    assert(event);      // Non-NULL event object is expected.
+//
+//    if (anchor) {
+//        if (!yaml_check_utf8(anchor, strlen((char *)anchor))) goto error;
+//        anchor_copy = yaml_strdup(anchor);
+//        if (!anchor_copy) goto error;
+//    }
+//
+//    if (tag) {
+//        if (!yaml_check_utf8(tag, strlen((char *)tag))) goto error;
+//        tag_copy = yaml_strdup(tag);
+//        if (!tag_copy) goto error;
+//    }
+//
+//    MAPPING_START_EVENT_INIT(*event, anchor_copy, tag_copy,
+//            implicit, style, mark, mark);
+//
+//    return 1;
+//
+//error:
+//    yaml_free(anchor_copy);
+//    yaml_free(tag_copy);
+//
+//    return 0;
+//}
+//
+///*
+// * Create MAPPING-END.
+// */
+//
+//YAML_DECLARE(int)
+//yaml_mapping_end_event_initialize(yaml_event_t *event)
+//{
+//    yaml_mark_t mark = { 0, 0, 0 };
+//
+//    assert(event);      // Non-NULL event object is expected.
+//
+//    MAPPING_END_EVENT_INIT(*event, mark, mark);
+//
+//    return 1;
+//}
+
+///*
+// * Create a document object.
+// */
+//
+//YAML_DECLARE(int)
+//yaml_document_initialize(yaml_document_t *document,
+//        yaml_version_directive_t *version_directive,
+//        yaml_tag_directive_t *tag_directives_start,
+//        yaml_tag_directive_t *tag_directives_end,
+//        int start_implicit, int end_implicit)
+//{
+//    struct {
+//        yaml_error_type_t error;
+//    } context;
+//    struct {
+//        yaml_node_t *start;
+//        yaml_node_t *end;
+//        yaml_node_t *top;
+//    } nodes = { NULL, NULL, NULL };
+//    yaml_version_directive_t *version_directive_copy = NULL;
+//    struct {
+//        yaml_tag_directive_t *start;
+//        yaml_tag_directive_t *end;
+//        yaml_tag_directive_t *top;
+//    } tag_directives_copy = { NULL, NULL, NULL };
+//    yaml_tag_directive_t value = { NULL, NULL };
+//    yaml_mark_t mark = { 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) {
+//        yaml_tag_directive_t *tag_directive;
+//        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)) {
+//        yaml_tag_directive_t value = 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(yaml_document_t *document)
+//{
+//    struct {
+//        yaml_error_type_t error;
+//    } context;
+//    yaml_tag_directive_t *tag_directive;
+//
+//    context.error = YAML_NO_ERROR;  // Eliminate a compliler warning.
+//
+//    assert(document);   // Non-NULL document object is expected.
+//
+//    while (!STACK_EMPTY(&context, document.nodes)) {
+//        yaml_node_t node = 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(yaml_document_t *document, int index)
+//{
+//    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(yaml_document_t *document)
+//{
+//    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(yaml_document_t *document,
+//        yaml_char_t *tag, yaml_char_t *value, int length,
+//        yaml_scalar_style_t style)
+//{
+//    struct {
+//        yaml_error_type_t error;
+//    } context;
+//    yaml_mark_t mark = { 0, 0, 0 };
+//    yaml_char_t *tag_copy = NULL;
+//    yaml_char_t *value_copy = NULL;
+//    yaml_node_t node;
+//
+//    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(yaml_document_t *document,
+//        yaml_char_t *tag, yaml_sequence_style_t style)
+//{
+//    struct {
+//        yaml_error_type_t error;
+//    } context;
+//    yaml_mark_t mark = { 0, 0, 0 };
+//    yaml_char_t *tag_copy = NULL;
+//    struct {
+//        yaml_node_item_t *start;
+//        yaml_node_item_t *end;
+//        yaml_node_item_t *top;
+//    } items = { NULL, NULL, NULL };
+//    yaml_node_t node;
+//
+//    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(yaml_document_t *document,
+//        yaml_char_t *tag, yaml_mapping_style_t style)
+//{
+//    struct {
+//        yaml_error_type_t error;
+//    } context;
+//    yaml_mark_t mark = { 0, 0, 0 };
+//    yaml_char_t *tag_copy = NULL;
+//    struct {
+//        yaml_node_pair_t *start;
+//        yaml_node_pair_t *end;
+//        yaml_node_pair_t *top;
+//    } pairs = { NULL, NULL, NULL };
+//    yaml_node_t node;
+//
+//    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(yaml_document_t *document,
+//        int sequence, int item)
+//{
+//    struct {
+//        yaml_error_type_t error;
+//    } 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(yaml_document_t *document,
+//        int mapping, int key, int value)
+//{
+//    struct {
+//        yaml_error_type_t error;
+//    } context;
+//
+//    yaml_node_pair_t pair;
+//
+//    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/parser_c.go b/parser_c.go
new file mode 100644
index 0000000..c965594
--- /dev/null
+++ b/parser_c.go
@@ -0,0 +1,1096 @@
+package goyaml
+
+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 {
+	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,
+	}
+	event.stream_start.encoding = token.stream_start.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 &&
+		// Parse an implicit document.
+		token.typ != yaml_TAG_DIRECTIVE_TOKEN &&
+		token.typ != yaml_DOCUMENT_START_TOKEN &&
+		token.typ != yaml_STREAM_END_TOKEN {
+		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,
+		}
+		event.document_start.version_directive = version_directive
+		event.document_start.tag_directives = tag_directives
+		event.document_start.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)
+	} else {
+		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,
+	}
+	event.document_start.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 {
+	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,
+		}
+		event.alias.anchor = token.alias.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.anchor.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.tag.handle
+			tag_suffix = token.tag.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.tag.handle
+		tag_suffix = token.tag.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.anchor.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,
+		}
+		event.sequence_start.anchor = anchor
+		event.sequence_start.tag = tag
+		event.sequence_start.implicit = implicit
+		event.sequence_start.style = 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.scalar.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,
+		}
+		event.scalar.anchor = anchor
+		event.scalar.tag = tag
+		event.scalar.value = token.scalar.value
+		event.scalar.plain_implicit = plain_implicit
+		event.scalar.quoted_implicit = quoted_implicit
+		event.scalar.style = token.scalar.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,
+		}
+		event.sequence_start.anchor = anchor
+		event.sequence_start.tag = tag
+		event.sequence_start.implicit = implicit
+		event.sequence_start.style = 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,
+		}
+		event.mapping_start.anchor = anchor
+		event.mapping_start.tag = tag
+		event.mapping_start.implicit = implicit
+		event.mapping_start.style = 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,
+		}
+		event.sequence_start.anchor = anchor
+		event.sequence_start.tag = tag
+		event.sequence_start.implicit = implicit
+		event.sequence_start.style = 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,
+		}
+		event.mapping_start.anchor = anchor
+		event.mapping_start.tag = tag
+		event.mapping_start.implicit = implicit
+		event.mapping_start.style = 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,
+		}
+		event.scalar.anchor = anchor
+		event.scalar.tag = tag
+		event.scalar.plain_implicit = implicit
+		event.scalar.quoted_implicit = false
+		event.scalar.style = 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)
+		} else {
+			parser.state = yaml_PARSE_INDENTLESS_SEQUENCE_ENTRY_STATE
+			return yaml_parser_process_empty_scalar(parser, event, mark)
+		}
+	} else {
+		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)
+		} else {
+			parser.state = yaml_PARSE_BLOCK_MAPPING_KEY_STATE
+			return yaml_parser_process_empty_scalar(parser, event, mark)
+		}
+	} else {
+		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,
+			}
+			event.mapping_start.implicit = true
+			event.mapping_start.style = 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)
+	} else {
+		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,
+	}
+	event.scalar.plain_implicit = true
+	event.scalar.style = yaml_PLAIN_SCALAR_STYLE
+	// Empty means len(event.scalar.value) == 0
+	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.version_directive.major != 1 || token.version_directive.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.version_directive.major,
+				minor: token.version_directive.minor,
+			}
+		} else if token.typ == yaml_TAG_DIRECTIVE_TOKEN {
+			value := yaml_tag_directive_t{
+				handle: token.tag_directive.handle,
+				prefix: token.tag_directive.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/reader_c.go b/reader_c.go
new file mode 100644
index 0000000..e3a8eae
--- /dev/null
+++ b/reader_c.go
@@ -0,0 +1,397 @@
+package goyaml
+
+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.
+	if parser.buffer_pos > 0 && parser.buffer_pos < len(parser.buffer) {
+		size := len(parser.buffer) - parser.buffer_pos
+		copy(parser.buffer, parser.buffer[parser.buffer_pos:])
+		parser.buffer_pos = 0
+		parser.buffer = parser.buffer[:size]
+	} else if parser.buffer_pos == len(parser.buffer) {
+		parser.buffer_pos = 0
+		parser.buffer = parser.buffer[:0]
+	}
+
+	// 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) {
+				return false
+			}
+		}
+		first = false
+
+		// Decode the raw buffer.
+		for parser.raw_buffer_pos != len(parser.raw_buffer) {
+			var value, value2 rune
+			var incomplete bool
+			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)
+					}
+					incomplete = true
+					break
+				}
+
+				// 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)
+					}
+					incomplete = true
+					break
+				}
+
+				// 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)
+						}
+						incomplete = true
+						break
+					}
+
+					// 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 raw buffer contains enough bytes to form a character.
+			if incomplete {
+				break
+			}
+
+			// 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
+
+			pos := len(parser.buffer)
+			parser.buffer = parser.buffer[:pos+width]
+
+			// Finally put the character into the buffer.
+			if value <= 0x7F {
+				// 0000 0000-0000 007F . 0xxxxxxx
+				parser.buffer[pos+0] = byte(value)
+			} else if value <= 0x7FF {
+				// 0000 0080-0000 07FF . 110xxxxx 10xxxxxx
+				parser.buffer[pos+0] = byte(0xC0 + (value >> 6))
+				parser.buffer[pos+1] = byte(0x80 + (value & 0x3F))
+			} else if value <= 0xFFFF {
+				// 0000 0800-0000 FFFF . 1110xxxx 10xxxxxx 10xxxxxx
+				parser.buffer[pos+0] = byte(0xE0 + (value >> 12))
+				parser.buffer[pos+1] = byte(0x80 + ((value >> 6) & 0x3F))
+				parser.buffer[pos+2] = byte(0x80 + (value & 0x3F))
+			} else {
+				// 0001 0000-0010 FFFF . 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
+				parser.buffer[pos+0] = byte(0xF0 + (value >> 18))
+				parser.buffer[pos+1] = byte(0x80 + ((value >> 12) & 0x3F))
+				parser.buffer[pos+2] = byte(0x80 + ((value >> 6) & 0x3F))
+				parser.buffer[pos+3] = byte(0x80 + (value & 0x3F))
+			}
+
+			parser.unread++
+		}
+
+		// On EOF, put NUL into the buffer and return.
+		if parser.eof {
+			parser.buffer = parser.buffer[:len(parser.buffer)+1]
+			parser.buffer[len(parser.buffer)-1] = 0x00
+			parser.unread++
+			return true
+		}
+	}
+
+	return true
+}
diff --git a/scanner_c.go b/scanner_c.go
new file mode 100644
index 0000000..e926272
--- /dev/null
+++ b/scanner_c.go
@@ -0,0 +1,2728 @@
+package goyaml
+
+import (
+	"bytes"
+)
+
+// 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 1 on success, 0 on failure (reader error or memory error).
+func cache(parser *yaml_parser_t, length int) bool {
+	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) bool {
+	buf := parser.buffer
+	pos := parser.buffer_pos
+	w := width(buf[0])
+	*s = append(*s, buf[pos:pos+w]...)
+	parser.buffer_pos += w
+	parser.mark.index++
+	parser.mark.column++
+	parser.unread--
+	return true
+}
+
+// Copy a line break character to a string buffer and advance pointers.
+func read_line(parser *yaml_parser_t, s *[]byte) bool {
+	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+1] == '\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 false
+	}
+	parser.mark.index++
+	parser.mark.column = 0
+	parser.mark.line++
+	parser.unread--
+	return true
+}
+
+// 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")
+}
+
+// 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 _, simple_key := range parser.simple_keys {
+				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 !cache(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 !cache(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.
+	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 _, simple_key := range parser.simple_keys {
+
+		// 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,
+	}
+	token.stream_start.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 !cache(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 !cache(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 !cache(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 !cache(parser, 1) {
+					return false
+				}
+			}
+		}
+
+		// If it is a line break, eat it.
+		if is_break(parser.buffer, parser.buffer_pos) {
+			if !cache(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 int
+		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,
+		}
+		token.version_directive.major = major
+		token.version_directive.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,
+		}
+		token.tag_directive.handle = handle
+		token.tag_directive.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 !cache(parser, 1) {
+		return false
+	}
+
+	for is_blank(parser.buffer, parser.buffer_pos) {
+		skip(parser)
+		if !cache(parser, 1) {
+			return false
+		}
+	}
+
+	if parser.buffer[parser.buffer_pos] == '#' {
+		for !is_breakz(parser.buffer, parser.buffer_pos) {
+			skip(parser)
+			if !cache(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 !cache(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 !cache(parser, 1) {
+		return false
+	}
+
+	var s []byte
+	for is_alpha(parser.buffer, parser.buffer_pos) {
+		if !read(parser, &s) {
+			return false
+		}
+		if !cache(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 *int) bool {
+	// Eat whitespaces.
+	if !cache(parser, 1) {
+		return false
+	}
+	for is_blank(parser.buffer, parser.buffer_pos) {
+		skip(parser)
+		if !cache(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 = 9
+
+// 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 *int) bool {
+
+	// Repeat while the next character is digit.
+	if !cache(parser, 1) {
+		return false
+	}
+	var value, length int
+	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 + as_digit(parser.buffer, parser.buffer_pos)
+		skip(parser)
+		if !cache(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 !cache(parser, 1) {
+		return false
+	}
+
+	for is_blank(parser.buffer, parser.buffer_pos) {
+		skip(parser)
+		if !cache(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 !cache(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 !cache(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 !cache(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 !cache(parser, 1) {
+		return false
+	}
+
+	for is_alpha(parser.buffer, parser.buffer_pos) {
+		if !read(parser, &s) {
+			return false
+		}
+		if !cache(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,
+	}
+	// [Go] Just use a single field instead.
+	if typ == yaml_ANCHOR_TOKEN {
+		token.anchor.value = s
+	} else {
+		token.alias.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 !cache(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 !cache(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,
+	}
+	token.tag.handle = handle
+	token.tag.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 !cache(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.
+	if !read(parser, &s) {
+		return false
+	}
+
+	// Copy all subsequent alphabetical and numerical characters.
+	if !cache(parser, 1) {
+		return false
+	}
+	for is_alpha(parser.buffer, parser.buffer_pos) {
+		if !read(parser, &s) {
+			return false
+		}
+		if !cache(parser, 1) {
+			return false
+		}
+	}
+
+	// Check if the trailing character is '!' and copy it.
+	if parser.buffer[parser.buffer_pos] == '!' {
+		if !read(parser, &s) {
+			return false
+		}
+	} 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 !cache(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 {
+			if !read(parser, &s) {
+				return false
+			}
+		}
+		if !cache(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 !cache(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 !cache(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 !cache(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 !cache(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 !cache(parser, 1) {
+		return false
+	}
+	for is_blank(parser.buffer, parser.buffer_pos) {
+		skip(parser)
+		if !cache(parser, 1) {
+			return false
+		}
+	}
+	if parser.buffer[parser.buffer_pos] == '#' {
+		for !is_breakz(parser.buffer, parser.buffer_pos) {
+			skip(parser)
+			if !cache(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 !cache(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 !cache(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 && 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) {
+			if !read(parser, &s) {
+				return false
+			}
+			if !cache(parser, 1) {
+				return false
+			}
+		}
+
+		// Consume the line break.
+		if !cache(parser, 2) {
+			return false
+		}
+
+		if !read_line(parser, &leading_break) {
+			return false
+		}
+
+		// 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,
+	}
+	token.scalar.value = s
+	if literal {
+		token.scalar.style = yaml_LITERAL_SCALAR_STYLE
+	} else {
+		token.scalar.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 !cache(parser, 1) {
+			return false
+		}
+		for *indent == 0 || parser.mark.column < *indent && is_space(parser.buffer, parser.buffer_pos) {
+			skip(parser)
+			if !cache(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 !cache(parser, 2) {
+			return false
+		}
+		if !read_line(parser, breaks) {
+			return false
+		}
+		*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 !cache(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.
+		if !cache(parser, 2) {
+			return false
+		}
+		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 !cache(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 !cache(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.
+				if !read(parser, &s) {
+					return false
+				}
+			}
+			if !cache(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 !cache(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 {
+					if !read(parser, &whitespaces) {
+						return false
+					}
+				} else {
+					skip(parser)
+				}
+			} else {
+				if !cache(parser, 2) {
+					return false
+				}
+
+				// Check if it is a first line break.
+				if !leading_blanks {
+					whitespaces = whitespaces[:0]
+					if !read_line(parser, &leading_break) {
+						return false
+					}
+					leading_blanks = true
+				} else {
+					if !read_line(parser, &trailing_breaks) {
+						return false
+					}
+				}
+			}
+			if !cache(parser, 1) {
+				return false
+			}
+		}
+
+		// Join the whitespaces or fold line breaks.
+		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]
+		} 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,
+	}
+	token.scalar.value = s
+	if single {
+		token.scalar.style = yaml_SINGLE_QUOTED_SCALAR_STYLE
+	} else {
+		token.scalar.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 !cache(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.
+			if !read(parser, &s) {
+				return false
+			}
+
+			end_mark = parser.mark
+			if !cache(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 !cache(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 {
+					if !read(parser, &whitespaces) {
+						return false
+					}
+				} else {
+					skip(parser)
+				}
+			} else {
+				if !cache(parser, 2) {
+					return false
+				}
+
+				// Check if it is a first line break.
+				if !leading_blanks {
+					whitespaces = whitespaces[:0]
+					if !read_line(parser, &leading_break) {
+						return false
+					}
+					leading_blanks = true
+				} else {
+					if !read_line(parser, &trailing_breaks) {
+						return false
+					}
+				}
+			}
+			if !cache(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,
+	}
+	token.scalar.value = s
+	token.scalar.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/yaml_h.go b/yaml_h.go
new file mode 100644
index 0000000..ad23067
--- /dev/null
+++ b/yaml_h.go
@@ -0,0 +1,1513 @@
+package goyaml
+
+import (
+	"io"
+)
+
+// The version directive data.
+type yaml_version_directive_t struct {
+	major int // The major version number.
+	minor int // 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_scalar_style_t int
+
+// 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 int
+
+// 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 int
+
+// 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.
+)
+
+// The token structure.
+type yaml_token_t struct {
+
+	// The token type.
+	typ yaml_token_type_t
+
+	// The token data.
+
+	// The stream start (for yaml_STREAM_START_TOKEN).
+	stream_start struct {
+		encoding yaml_encoding_t // The stream encoding.
+	}
+
+	// The alias (for yaml_ALIAS_TOKEN).
+	alias struct {
+		value []byte // The alias value.
+	}
+
+	// The anchor (for yaml_ANCHOR_TOKEN).
+	anchor struct {
+		value []byte // The anchor value.
+	}
+
+	// The tag (for yaml_TAG_TOKEN).
+	tag struct {
+		handle []byte // The tag handle.
+		suffix []byte // The tag suffix.
+	}
+
+	// The scalar value (for yaml_SCALAR_TOKEN).
+	scalar struct {
+		value []byte              // The scalar value.
+		style yaml_scalar_style_t // The scalar style.
+	}
+
+	// The version directive (for yaml_VERSION_DIRECTIVE_TOKEN).
+	version_directive struct {
+		major int // The major version number.
+		minor int // The minor version number.
+	}
+
+	// The tag directive (for yaml_TAG_DIRECTIVE_TOKEN).
+	tag_directive struct {
+		handle []byte // The tag handle.
+		prefix []byte // The tag prefix.
+	}
+
+	// The beginning of the token.
+	start_mark yaml_mark_t
+	// The end of the token.
+	end_mark yaml_mark_t
+}
+
+// Events
+
+type yaml_event_type_t int
+
+// 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 event data.
+
+	// The stream parameters (for yaml_STREAM_START_EVENT).
+	stream_start struct {
+		encoding yaml_encoding_t // The document encoding.
+	}
+
+	// The document parameters (for yaml_DOCUMENT_START_EVENT).
+	document_start struct {
+		version_directive *yaml_version_directive_t // The version directive.
+
+		// The list of tag directives.
+		tag_directives []yaml_tag_directive_t
+		implicit       bool // Is the document indicator implicit?
+	}
+
+	// The document end parameters (for yaml_DOCUMENT_END_EVENT).
+	document_end struct {
+		implicit bool // Is the document end indicator implicit?
+	}
+
+	// The alias parameters (for yaml_ALIAS_EVENT).
+	alias struct {
+		anchor []byte // The anchor.
+	}
+
+	// The scalar parameters (for yaml_SCALAR_EVENT).
+	scalar struct {
+		anchor          []byte              // The anchor.
+		tag             []byte              // The tag.
+		value           []byte              // The scalar value.
+		length          int                 // The length of the scalar value.
+		plain_implicit  bool                // Is the tag optional for the plain style?
+		quoted_implicit bool                // Is the tag optional for any non-plain style?
+		style           yaml_scalar_style_t // The scalar style.
+	}
+
+	// The sequence parameters (for yaml_SEQUENCE_START_EVENT).
+	sequence_start struct {
+		anchor   []byte                // The anchor.
+		tag      []byte                // The tag.
+		implicit bool                  // Is the tag optional?
+		style    yaml_sequence_style_t // The sequence style.
+	}
+
+	// The mapping parameters (for yaml_MAPPING_START_EVENT).
+	mapping_start struct {
+		anchor   []byte               // The anchor.
+		tag      []byte               // The tag.
+		implicit bool                 // Is the tag optional?
+		style    yaml_mapping_style_t // The mapping style.
+	}
+
+	start_mark yaml_mark_t // The beginning of the event.
+	end_mark   yaml_mark_t // The end of the event.
+
+}
+
+///**
+// * Create the STREAM-START event.
+// *
+// * @param[out]      event       An empty event object.
+// * @param[in]       encoding    The stream encoding.
+// *
+// * @returns @c 1 if the function succeeded, @c 0 on error.
+// */
+//
+//YAML_DECLARE(int)
+//yaml_stream_start_event_initialize(yaml_event_t *event,
+//        yaml_encoding_t encoding);
+//
+///**
+// * Create the STREAM-END event.
+// *
+// * @param[out]      event       An empty event object.
+// *
+// * @returns @c 1 if the function succeeded, @c 0 on error.
+// */
+//
+//YAML_DECLARE(int)
+//yaml_stream_end_event_initialize(yaml_event_t *event);
+//
+///**
+// * Create the DOCUMENT-START event.
+// *
+// * The @a implicit argument is considered as a stylistic parameter and may be
+// * ignored by the emitter.
+// *
+// * @param[out]      event                   An empty event object.
+// * @param[in]       version_directive       The %YAML directive value or
+// *                                          @c NULL.
+// * @param[in]       tag_directives_start    The beginning of the %TAG
+// *                                          directives list.
+// * @param[in]       tag_directives_end      The end of the %TAG directives
+// *                                          list.
+// * @param[in]       implicit                If the document start indicator is
+// *                                          implicit.
+// *
+// * @returns @c 1 if the function succeeded, @c 0 on error.
+// */
+//
+//YAML_DECLARE(int)
+//yaml_document_start_event_initialize(yaml_event_t *event,
+//        yaml_version_directive_t *version_directive,
+//        yaml_tag_directive_t *tag_directives_start,
+//        yaml_tag_directive_t *tag_directives_end,
+//        int implicit);
+//
+///**
+// * Create the DOCUMENT-END event.
+// *
+// * The @a implicit argument is considered as a stylistic parameter and may be
+// * ignored by the emitter.
+// *
+// * @param[out]      event       An empty event object.
+// * @param[in]       implicit    If the document end indicator is implicit.
+// *
+// * @returns @c 1 if the function succeeded, @c 0 on error.
+// */
+//
+//YAML_DECLARE(int)
+//yaml_document_end_event_initialize(yaml_event_t *event, int implicit);
+//
+///**
+// * Create an ALIAS event.
+// *
+// * @param[out]      event       An empty event object.
+// * @param[in]       anchor      The anchor value.
+// *
+// * @returns @c 1 if the function succeeded, @c 0 on error.
+// */
+//
+//YAML_DECLARE(int)
+//yaml_alias_event_initialize(yaml_event_t *event, yaml_char_t *anchor);
+//
+///**
+// * Create a SCALAR event.
+// *
+// * The @a style argument may be ignored by the emitter.
+// *
+// * Either the @a tag attribute or one of the @a plain_implicit and
+// * @a quoted_implicit flags must be set.
+// *
+// * @param[out]      event           An empty event object.
+// * @param[in]       anchor          The scalar anchor or @c NULL.
+// * @param[in]       tag             The scalar tag or @c NULL.
+// * @param[in]       value           The scalar value.
+// * @param[in]       length          The length of the scalar value.
+// * @param[in]       plain_implicit  If the tag may be omitted for the plain
+// *                                  style.
+// * @param[in]       quoted_implicit If the tag may be omitted for any
+// *                                  non-plain style.
+// * @param[in]       style           The scalar style.
+// *
+// * @returns @c 1 if the function succeeded, @c 0 on error.
+// */
+//
+//YAML_DECLARE(int)
+//yaml_scalar_event_initialize(yaml_event_t *event,
+//        yaml_char_t *anchor, yaml_char_t *tag,
+//        yaml_char_t *value, int length,
+//        int plain_implicit, int quoted_implicit,
+//        yaml_scalar_style_t style);
+//
+///**
+// * Create a SEQUENCE-START event.
+// *
+// * The @a style argument may be ignored by the emitter.
+// *
+// * Either the @a tag attribute or the @a implicit flag must be set.
+// *
+// * @param[out]      event       An empty event object.
+// * @param[in]       anchor      The sequence anchor or @c NULL.
+// * @param[in]       tag         The sequence tag or @c NULL.
+// * @param[in]       implicit    If the tag may be omitted.
+// * @param[in]       style       The sequence style.
+// *
+// * @returns @c 1 if the function succeeded, @c 0 on error.
+// */
+//
+//YAML_DECLARE(int)
+//yaml_sequence_start_event_initialize(yaml_event_t *event,
+//        yaml_char_t *anchor, yaml_char_t *tag, int implicit,
+//        yaml_sequence_style_t style);
+//
+///**
+// * Create a SEQUENCE-END event.
+// *
+// * @param[out]      event       An empty event object.
+// *
+// * @returns @c 1 if the function succeeded, @c 0 on error.
+// */
+//
+//YAML_DECLARE(int)
+//yaml_sequence_end_event_initialize(yaml_event_t *event);
+//
+///**
+// * Create a MAPPING-START event.
+// *
+// * The @a style argument may be ignored by the emitter.
+// *
+// * Either the @a tag attribute or the @a implicit flag must be set.
+// *
+// * @param[out]      event       An empty event object.
+// * @param[in]       anchor      The mapping anchor or @c NULL.
+// * @param[in]       tag         The mapping tag or @c NULL.
+// * @param[in]       implicit    If the tag may be omitted.
+// * @param[in]       style       The mapping style.
+// *
+// * @returns @c 1 if the function succeeded, @c 0 on error.
+// */
+//
+//YAML_DECLARE(int)
+//yaml_mapping_start_event_initialize(yaml_event_t *event,
+//        yaml_char_t *anchor, yaml_char_t *tag, int implicit,
+//        yaml_mapping_style_t style);
+//
+///**
+// * Create a MAPPING-END event.
+// *
+// * @param[out]      event       An empty event object.
+// *
+// * @returns @c 1 if the function succeeded, @c 0 on error.
+// */
+//
+//YAML_DECLARE(int)
+//yaml_mapping_end_event_initialize(yaml_event_t *event);
+//
+///**
+// * Free any memory allocated for an event object.
+// *
+// * @param[in,out]   event   An event object.
+// */
+//
+//YAML_DECLARE(void)
+//yaml_event_delete(yaml_event_t *event);
+//
+//// @}
+//
+
+// 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?
+
+	start_mark yaml_mark_t // The beginning of the document.
+	end_mark   yaml_mark_t // The end of the document.
+
+}
+
+///**
+// * Create a YAML document.
+// *
+// * @param[out]      document                An empty document object.
+// * @param[in]       version_directive       The %YAML directive value or
+// *                                          @c NULL.
+// * @param[in]       tag_directives_start    The beginning of the %TAG
+// *                                          directives list.
+// * @param[in]       tag_directives_end      The end of the %TAG directives
+// *                                          list.
+// * @param[in]       start_implicit          If the document start indicator is
+// *                                          implicit.
+// * @param[in]       end_implicit            If the document end indicator is
+// *                                          implicit.
+// *
+// * @returns @c 1 if the function succeeded, @c 0 on error.
+// */
+//
+//YAML_DECLARE(int)
+//yaml_document_initialize(yaml_document_t *document,
+//        yaml_version_directive_t *version_directive,
+//        yaml_tag_directive_t *tag_directives_start,
+//        yaml_tag_directive_t *tag_directives_end,
+//        int start_implicit, int end_implicit);
+//
+///**
+// * Delete a YAML document and all its nodes.
+// *
+// * @param[in,out]   document        A document object.
+// */
+//
+//YAML_DECLARE(void)
+//yaml_document_delete(yaml_document_t *document);
+//
+///**
+// * Get a node of a YAML document.
+// *
+// * The pointer returned by this function is valid until any of the functions
+// * modifying the documents are called.
+// *
+// * @param[in]       document        A document object.
+// * @param[in]       index           The node id.
+// *
+// * @returns the node objct or @c NULL if @c node_id is out of range.
+// */
+//
+//YAML_DECLARE(yaml_node_t *)
+//yaml_document_get_node(yaml_document_t *document, int index);
+//
+///**
+// * Get the root of a YAML document node.
+// *
+// * The root object is the first object added to the document.
+// *
+// * The pointer returned by this function is valid until any of the functions
+// * modifying the documents are called.
+// *
+// * An empty document produced by the parser signifies the end of a YAML
+// * stream.
+// *
+// * @param[in]       document        A document object.
+// *
+// * @returns the node object or @c NULL if the document is empty.
+// */
+//
+//YAML_DECLARE(yaml_node_t *)
+//yaml_document_get_root_node(yaml_document_t *document);
+//
+///**
+// * Create a SCALAR node and attach it to the document.
+// *
+// * The @a style argument may be ignored by the emitter.
+// *
+// * @param[in,out]   document        A document object.
+// * @param[in]       tag             The scalar tag.
+// * @param[in]       value           The scalar value.
+// * @param[in]       length          The length of the scalar value.
+// * @param[in]       style           The scalar style.
+// *
+// * @returns the node id or @c 0 on error.
+// */
+//
+//YAML_DECLARE(int)
+//yaml_document_add_scalar(yaml_document_t *document,
+//        yaml_char_t *tag, yaml_char_t *value, int length,
+//        yaml_scalar_style_t style);
+//
+///**
+// * Create a SEQUENCE node and attach it to the document.
+// *
+// * The @a style argument may be ignored by the emitter.
+// *
+// * @param[in,out]   document    A document object.
+// * @param[in]       tag         The sequence tag.
+// * @param[in]       style       The sequence style.
+// *
+// * @returns the node id or @c 0 on error.
+// */
+//
+//YAML_DECLARE(int)
+//yaml_document_add_sequence(yaml_document_t *document,
+//        yaml_char_t *tag, yaml_sequence_style_t style);
+//
+///**
+// * Create a MAPPING node and attach it to the document.
+// *
+// * The @a style argument may be ignored by the emitter.
+// *
+// * @param[in,out]   document    A document object.
+// * @param[in]       tag         The sequence tag.
+// * @param[in]       style       The sequence style.
+// *
+// * @returns the node id or @c 0 on error.
+// */
+//
+//YAML_DECLARE(int)
+//yaml_document_add_mapping(yaml_document_t *document,
+//        yaml_char_t *tag, yaml_mapping_style_t style);
+//
+///**
+// * Add an item to a SEQUENCE node.
+// *
+// * @param[in,out]   document    A document object.
+// * @param[in]       sequence    The sequence node id.
+// * @param[in]       item        The item node id.
+//*
+// * @returns @c 1 if the function succeeded, @c 0 on error.
+// */
+//
+//YAML_DECLARE(int)
+//yaml_document_append_sequence_item(yaml_document_t *document,
+//        int sequence, int item);
+//
+///**
+// * Add a pair of a key and a value to a MAPPING node.
+// *
+// * @param[in,out]   document    A document object.
+// * @param[in]       mapping     The mapping node id.
+// * @param[in]       key         The key node id.
+// * @param[in]       value       The value node id.
+//*
+// * @returns @c 1 if the function succeeded, @c 0 on error.
+// */
+//
+//YAML_DECLARE(int)
+//yaml_document_append_mapping_pair(yaml_document_t *document,
+//        int mapping, int key, int value);
+//
+
+// Parser Definitions
+
+// 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.
+)
+
+// 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.
+}
+
+//
+///**
+// * Initialize a parser.
+// *
+// * This function creates a new parser object.  An application is responsible
+// * for destroying the object using the yaml_parser_delete() function.
+// *
+// * @param[out]      parser  An empty parser object.
+// *
+// * @returns @c 1 if the function succeeded, @c 0 on error.
+// */
+//
+//YAML_DECLARE(int)
+//yaml_parser_initialize(yaml_parser_t *parser);
+//
+///**
+// * Destroy a parser.
+// *
+// * @param[in,out]   parser  A parser object.
+// */
+//
+//YAML_DECLARE(void)
+//yaml_parser_delete(yaml_parser_t *parser);
+//
+///**
+// * Set a string input.
+// *
+// * Note that the @a input pointer must be valid while the @a parser object
+// * exists.  The application is responsible for destroing @a input after
+// * destroying the @a parser.
+// *
+// * @param[in,out]   parser  A parser object.
+// * @param[in]       input   A source data.
+// * @param[in]       size    The length of the source data in bytes.
+// */
+//
+//YAML_DECLARE(void)
+//yaml_parser_set_input_string(yaml_parser_t *parser,
+//        unsigned char *input, int size);
+//
+///**
+// * Set a file input.
+// *
+// * @a file should be a file object open for reading.  The application is
+// * responsible for closing the @a file.
+// *
+// * @param[in,out]   parser  A parser object.
+// * @param[in]       file    An open file.
+// */
+//
+//YAML_DECLARE(void)
+//yaml_parser_set_input_file(yaml_parser_t *parser, FILE *file);
+//
+///**
+// * Set a generic input handler.
+// *
+// * @param[in,out]   parser  A parser object.
+// * @param[in]       handler A read handler.
+// * @param[in]       data    Any application data for passing to the read
+// *                          handler.
+// */
+//
+//YAML_DECLARE(void)
+//yaml_parser_set_input(yaml_parser_t *parser,
+//        yaml_read_handler_t *handler, void *data);
+//
+///**
+// * Set the source encoding.
+// *
+// * @param[in,out]   parser      A parser object.
+// * @param[in]       encoding    The source encoding.
+// */
+//
+//YAML_DECLARE(void)
+//yaml_parser_set_encoding(yaml_parser_t *parser, yaml_encoding_t encoding);
+//
+///**
+// * Scan the input stream and produce the next token.
+// *
+// * Call the function subsequently to produce a sequence of tokens corresponding
+// * to the input stream.  The initial token has the type
+// * yaml_STREAM_START_TOKEN while the ending token has the type
+// * yaml_STREAM_END_TOKEN.
+// *
+// * An application is responsible for freeing any buffers associated with the
+// * produced token object using the @c yaml_token_delete function.
+// *
+// * An application must not alternate the calls of yaml_parser_scan() with the
+// * calls of yaml_parser_parse() or yaml_parser_load(). Doing this will break
+// * the parser.
+// *
+// * @param[in,out]   parser      A parser object.
+// * @param[out]      token       An empty token object.
+// *
+// * @returns @c 1 if the function succeeded, @c 0 on error.
+// */
+//
+//YAML_DECLARE(int)
+//yaml_parser_scan(yaml_parser_t *parser, yaml_token_t *token);
+//
+///**
+// * Parse the input stream and produce the next parsing event.
+// *
+// * Call the function subsequently to produce a sequence of events corresponding
+// * to the input stream.  The initial event has the type
+// * yaml_STREAM_START_EVENT while the ending event has the type
+// * yaml_STREAM_END_EVENT.
+// *
+// * An application is responsible for freeing any buffers associated with the
+// * produced event object using the yaml_event_delete() function.
+// *
+// * An application must not alternate the calls of yaml_parser_parse() with the
+// * calls of yaml_parser_scan() or yaml_parser_load(). Doing this will break the
+// * parser.
+// *
+// * @param[in,out]   parser      A parser object.
+// * @param[out]      event       An empty event object.
+// *
+// * @returns @c 1 if the function succeeded, @c 0 on error.
+// */
+//
+//YAML_DECLARE(int)
+//yaml_parser_parse(yaml_parser_t *parser, yaml_event_t *event);
+//
+///**
+// * Parse the input stream and produce the next YAML document.
+// *
+// * Call this function subsequently to produce a sequence of documents
+// * constituting the input stream.
+// *
+// * If the produced document has no root node, it means that the document
+// * end has been reached.
+// *
+// * An application is responsible for freeing any data associated with the
+// * produced document object using the yaml_document_delete() function.
+// *
+// * An application must not alternate the calls of yaml_parser_load() with the
+// * calls of yaml_parser_scan() or yaml_parser_parse(). Doing this will break
+// * the parser.
+// *
+// * @param[in,out]   parser      A parser object.
+// * @param[out]      document    An empty document object.
+// *
+// * @return @c 1 if the function succeeded, @c 0 on error.
+// */
+//
+//YAML_DECLARE(int)
+//yaml_parser_load(yaml_parser_t *parser, yaml_document_t *document);
+//
+//// @}
+//
+///**
+// * @defgroup emitter 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.
+// */
+//
+//typedef int yaml_write_handler_t(void *data, unsigned char *buffer, int size);
+//
+//// The emitter states.
+//typedef enum yaml_emitter_state_e {
+//    // Expect STREAM-START.
+//    YAML_EMIT_STREAM_START_STATE,
+//    // Expect the first DOCUMENT-START or STREAM-END.
+//    YAML_EMIT_FIRST_DOCUMENT_START_STATE,
+//    // Expect DOCUMENT-START or STREAM-END.
+//    YAML_EMIT_DOCUMENT_START_STATE,
+//    // Expect the content of a document.
+//    YAML_EMIT_DOCUMENT_CONTENT_STATE,
+//    // Expect DOCUMENT-END.
+//    YAML_EMIT_DOCUMENT_END_STATE,
+//    // Expect the first item of a flow sequence.
+//    YAML_EMIT_FLOW_SEQUENCE_FIRST_ITEM_STATE,
+//    // Expect an item of a flow sequence.
+//    YAML_EMIT_FLOW_SEQUENCE_ITEM_STATE,
+//    // Expect the first key of a flow mapping.
+//    YAML_EMIT_FLOW_MAPPING_FIRST_KEY_STATE,
+//    // Expect a key of a flow mapping.
+//    YAML_EMIT_FLOW_MAPPING_KEY_STATE,
+//    // Expect a value for a simple key of a flow mapping.
+//    YAML_EMIT_FLOW_MAPPING_SIMPLE_VALUE_STATE,
+//    // Expect a value of a flow mapping.
+//    YAML_EMIT_FLOW_MAPPING_VALUE_STATE,
+//    // Expect the first item of a block sequence.
+//    YAML_EMIT_BLOCK_SEQUENCE_FIRST_ITEM_STATE,
+//    // Expect an item of a block sequence.
+//    YAML_EMIT_BLOCK_SEQUENCE_ITEM_STATE,
+//    // Expect the first key of a block mapping.
+//    YAML_EMIT_BLOCK_MAPPING_FIRST_KEY_STATE,
+//    // Expect the key of a block mapping.
+//    YAML_EMIT_BLOCK_MAPPING_KEY_STATE,
+//    // Expect a value for a simple key of a block mapping.
+//    YAML_EMIT_BLOCK_MAPPING_SIMPLE_VALUE_STATE,
+//    // Expect a value of a block mapping.
+//    YAML_EMIT_BLOCK_MAPPING_VALUE_STATE,
+//    // Expect nothing.
+//    YAML_EMIT_END_STATE
+//} yaml_emitter_state_t;
+//
+///**
+// * The emitter structure.
+// *
+// * All members are internal.  Manage the structure using the @c yaml_emitter_
+// * family of functions.
+// */
+//
+//typedef struct yaml_emitter_s {
+//
+//    /**
+//     * @name Error handling
+//     * @{
+//     */
+//
+//    // Error type.
+//    yaml_error_type_t error;
+//    // Error description.
+//    char *problem;
+//
+//    /**
+//     * @}
+//     */
+//
+//    /**
+//     * @name Writer stuff
+//     * @{
+//     */
+//
+//    // Write handler.
+//    yaml_write_handler_t *write_handler;
+//
+//    // A pointer for passing to the white handler.
+//    void *write_handler_data;
+//
+//    // Standard (string or file) output data.
+//    union {
+//        // String output data.
+//        struct {
+//            // The buffer pointer.
+//            unsigned char *buffer;
+//            // The buffer size.
+//            int size;
+//            // The number of written bytes.
+//            int *size_written;
+//        } string;
+//
+//        // File output data.
+//        FILE *file;
+//    } output;
+//
+//    // The working buffer.
+//    struct {
+//        // The beginning of the buffer.
+//        yaml_char_t *start;
+//        // The end of the buffer.
+//        yaml_char_t *end;
+//        // The current position of the buffer.
+//        yaml_char_t *pointer;
+//        // The last filled position of the buffer.
+//        yaml_char_t *last;
+//    } buffer;
+//
+//    // The raw buffer.
+//    struct {
+//        // The beginning of the buffer.
+//        unsigned char *start;
+//        // The end of the buffer.
+//        unsigned char *end;
+//        // The current position of the buffer.
+//        unsigned char *pointer;
+//        // The last filled position of the buffer.
+//        unsigned char *last;
+//    } raw_buffer;
+//
+//    // The stream encoding.
+//    yaml_encoding_t encoding;
+//
+//    /**
+//     * @}
+//     */
+//
+//    /**
+//     * @name Emitter stuff
+//     * @{
+//     */
+//
+//    // If the output is in the canonical style?
+//    int canonical;
+//    // The number of indentation spaces.
+//    int best_indent;
+//    // The preferred width of the output lines.
+//    int best_width;
+//    // Allow unescaped non-ASCII characters?
+//    int unicode;
+//    // The preferred line break.
+//    yaml_break_t line_break;
+//
+//    // The stack of states.
+//    struct {
+//        // The beginning of the stack.
+//        yaml_emitter_state_t *start;
+//        // The end of the stack.
+//        yaml_emitter_state_t *end;
+//        // The top of the stack.
+//        yaml_emitter_state_t *top;
+//    } states;
+//
+//    // The current emitter state.
+//    yaml_emitter_state_t state;
+//
+//    // The event queue.
+//    struct {
+//        // The beginning of the event queue.
+//        yaml_event_t *start;
+//        // The end of the event queue.
+//        yaml_event_t *end;
+//        // The head of the event queue.
+//        yaml_event_t *head;
+//        // The tail of the event queue.
+//        yaml_event_t *tail;
+//    } events;
+//
+//    // The stack of indentation levels.
+//    struct {
+//        // The beginning of the stack.
+//        int *start;
+//        // The end of the stack.
+//        int *end;
+//        // The top of the stack.
+//        int *top;
+//    } indents;
+//
+//    // The list of tag directives.
+//    struct {
+//        // The beginning of the list.
+//        yaml_tag_directive_t *start;
+//        // The end of the list.
+//        yaml_tag_directive_t *end;
+//        // The top of the list.
+//        yaml_tag_directive_t *top;
+//    } tag_directives;
+//
+//    // The current indentation level.
+//    int indent;
+//
+//    // The current flow level.
+//    int flow_level;
+//
+//    // Is it the document root context?
+//    int root_context;
+//    // Is it a sequence context?
+//    int sequence_context;
+//    // Is it a mapping context?
+//    int mapping_context;
+//    // Is it a simple mapping key context?
+//    int simple_key_context;
+//
+//    // The current line.
+//    int line;
+//    // The current column.
+//    int column;
+//    // If the last character was a whitespace?
+//    int whitespace;
+//    // If the last character was an indentation character (' ', '-', '?', ':')?
+//    int indention;
+//    // If an explicit document end is required?
+//    int open_ended;
+//
+//    // Anchor analysis.
+//    struct {
+//        // The anchor value.
+//        yaml_char_t *anchor;
+//        // The anchor length.
+//        int anchor_length;
+//        // Is it an alias?
+//        int alias;
+//    } anchor_data;
+//
+//    // Tag analysis.
+//    struct {
+//        // The tag handle.
+//        yaml_char_t *handle;
+//        // The tag handle length.
+//        int handle_length;
+//        // The tag suffix.
+//        yaml_char_t *suffix;
+//        // The tag suffix length.
+//        int suffix_length;
+//    } tag_data;
+//
+//    // Scalar analysis.
+//    struct {
+//        // The scalar value.
+//        yaml_char_t *value;
+//        // The scalar length.
+//        int length;
+//        // Does the scalar contain line breaks?
+//        int multiline;
+//        // Can the scalar be expessed in the flow plain style?
+//        int flow_plain_allowed;
+//        // Can the scalar be expressed in the block plain style?
+//        int block_plain_allowed;
+//        // Can the scalar be expressed in the single quoted style?
+//        int single_quoted_allowed;
+//        // Can the scalar be expressed in the literal or folded styles?
+//        int block_allowed;
+//        // The output style.
+//        yaml_scalar_style_t style;
+//    } scalar_data;
+//
+//    /**
+//     * @}
+//     */
+//
+//    /**
+//     * @name Dumper stuff
+//     * @{
+//     */
+//
+//    // If the stream was already opened?
+//    int opened;
+//    // If the stream was already closed?
+//    int closed;
+//
+//    // The information associated with the document nodes.
+//    struct {
+//        // The number of references.
+//        int references;
+//        // The anchor id.
+//        int anchor;
+//        // If the node has been emitted?
+//        int serialized;
+//    } *anchors;
+//
+//    // The last assigned anchor id.
+//    int last_anchor_id;
+//
+//    // The currently emitted document.
+//    yaml_document_t *document;
+//
+//    /**
+//     * @}
+//     */
+//
+//} yaml_emitter_t;
+//
+///**
+// * Initialize an emitter.
+// *
+// * This function creates a new emitter object.  An application is responsible
+// * for destroying the object using the yaml_emitter_delete() function.
+// *
+// * @param[out]      emitter     An empty parser object.
+// *
+// * @returns @c 1 if the function succeeded, @c 0 on error.
+// */
+//
+//YAML_DECLARE(int)
+//yaml_emitter_initialize(yaml_emitter_t *emitter);
+//
+///**
+// * Destroy an emitter.
+// *
+// * @param[in,out]   emitter     An emitter object.
+// */
+//
+//YAML_DECLARE(void)
+//yaml_emitter_delete(yaml_emitter_t *emitter);
+//
+///**
+// * Set a string output.
+// *
+// * The emitter will write the output characters to the @a output buffer of the
+// * size @a size.  The emitter will set @a size_written to the number of written
+// * bytes.  If the buffer is smaller than required, the emitter produces the
+// * YAML_WRITE_ERROR error.
+// *
+// * @param[in,out]   emitter         An emitter object.
+// * @param[in]       output          An output buffer.
+// * @param[in]       size            The buffer size.
+// * @param[in]       size_written    The pointer to save the number of written
+// *                                  bytes.
+// */
+//
+//YAML_DECLARE(void)
+//yaml_emitter_set_output_string(yaml_emitter_t *emitter,
+//        unsigned char *output, int size, size_t *size_written);
+//
+///**
+// * Set a file output.
+// *
+// * @a file should be a file object open for writing.  The application is
+// * responsible for closing the @a file.
+// *
+// * @param[in,out]   emitter     An emitter object.
+// * @param[in]       file        An open file.
+// */
+//
+//YAML_DECLARE(void)
+//yaml_emitter_set_output_file(yaml_emitter_t *emitter, FILE *file);
+//
+///**
+// * Set a generic output handler.
+// *
+// * @param[in,out]   emitter     An emitter object.
+// * @param[in]       handler     A write handler.
+// * @param[in]       data        Any application data for passing to the write
+// *                              handler.
+// */
+//
+//YAML_DECLARE(void)
+//yaml_emitter_set_output(yaml_emitter_t *emitter,
+//        yaml_write_handler_t *handler, void *data);
+//
+///**
+// * Set the output encoding.
+// *
+// * @param[in,out]   emitter     An emitter object.
+// * @param[in]       encoding    The output encoding.
+// */
+//
+//YAML_DECLARE(void)
+//yaml_emitter_set_encoding(yaml_emitter_t *emitter, yaml_encoding_t encoding);
+//
+///**
+// * Set if the output should be in the "canonical" format as in the YAML
+// * specification.
+// *
+// * @param[in,out]   emitter     An emitter object.
+// * @param[in]       canonical   If the output is canonical.
+// */
+//
+//YAML_DECLARE(void)
+//yaml_emitter_set_canonical(yaml_emitter_t *emitter, int canonical);
+//
+///**
+// * Set the intendation increment.
+// *
+// * @param[in,out]   emitter     An emitter object.
+// * @param[in]       indent      The indentation increment (1 < . < 10).
+// */
+//
+//YAML_DECLARE(void)
+//yaml_emitter_set_indent(yaml_emitter_t *emitter, int indent);
+//
+///**
+// * Set the preferred line width. @c -1 means unlimited.
+// *
+// * @param[in,out]   emitter     An emitter object.
+// * @param[in]       width       The preferred line width.
+// */
+//
+//YAML_DECLARE(void)
+//yaml_emitter_set_width(yaml_emitter_t *emitter, int width);
+//
+///**
+// * Set if unescaped non-ASCII characters are allowed.
+// *
+// * @param[in,out]   emitter     An emitter object.
+// * @param[in]       unicode     If unescaped Unicode characters are allowed.
+// */
+//
+//YAML_DECLARE(void)
+//yaml_emitter_set_unicode(yaml_emitter_t *emitter, int unicode);
+//
+///**
+// * Set the preferred line break.
+// *
+// * @param[in,out]   emitter     An emitter object.
+// * @param[in]       line_break  The preferred line break.
+// */
+//
+//YAML_DECLARE(void)
+//yaml_emitter_set_break(yaml_emitter_t *emitter, yaml_break_t line_break);
+//
+///**
+// * Emit an event.
+// *
+// * The event object may be generated using the yaml_parser_parse() function.
+// * The emitter takes the responsibility for the event object and destroys its
+// * content after it is emitted. The event object is destroyed even if the
+// * function fails.
+// *
+// * @param[in,out]   emitter     An emitter object.
+// * @param[in,out]   event       An event object.
+// *
+// * @returns @c 1 if the function succeeded, @c 0 on error.
+// */
+//
+//YAML_DECLARE(int)
+//yaml_emitter_emit(yaml_emitter_t *emitter, yaml_event_t *event);
+//
+///**
+// * Start a YAML stream.
+// *
+// * This function should be used before yaml_emitter_dump() is called.
+// *
+// * @param[in,out]   emitter     An emitter object.
+// *
+// * @returns @c 1 if the function succeeded, @c 0 on error.
+// */
+//
+//YAML_DECLARE(int)
+//yaml_emitter_open(yaml_emitter_t *emitter);
+//
+///**
+// * Finish a YAML stream.
+// *
+// * This function should be used after yaml_emitter_dump() is called.
+// *
+// * @param[in,out]   emitter     An emitter object.
+// *
+// * @returns @c 1 if the function succeeded, @c 0 on error.
+// */
+//
+//YAML_DECLARE(int)
+//yaml_emitter_close(yaml_emitter_t *emitter);
+//
+///**
+// * Emit a YAML document.
+// *
+// * The documen object may be generated using the yaml_parser_load() function
+// * or the yaml_document_initialize() function.  The emitter takes the
+// * responsibility for the document object and destoys its content after
+// * it is emitted. The document object is destroyedeven if the function fails.
+// *
+// * @param[in,out]   emitter     An emitter object.
+// * @param[in,out]   document    A document object.
+// *
+// * @returns @c 1 if the function succeeded, @c 0 on error.
+// */
+//
+//YAML_DECLARE(int)
+//yaml_emitter_dump(yaml_emitter_t *emitter, yaml_document_t *document);
+//
+///**
+// * Flush the accumulated characters to the output.
+// *
+// * @param[in,out]   emitter     An emitter object.
+// *
+// * @returns @c 1 if the function succeeded, @c 0 on error.
+// */
+//
+//YAML_DECLARE(int)
+//yaml_emitter_flush(yaml_emitter_t *emitter);
+//
+//// @}
+//
+//#ifdef __cplusplus
+//}
+//#endif
+//
+//#endif /* #ifndef YAML_H */
+//
diff --git a/yaml_private_h.go b/yaml_private_h.go
new file mode 100644
index 0000000..c01c7f3
--- /dev/null
+++ b/yaml_private_h.go
@@ -0,0 +1,249 @@
+package goyaml
+
+const (
+	// The size of the input raw buffer.
+	input_raw_buffer_size = 16384
+
+	// 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 = 16384
+
+	// 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)
+}
+
+// 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) || b[i] == 0x00
+}
+
+// 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)
+}
+
+// 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)
+}
+
+// Determine the width of the character.
+func width(b byte) int {
+	switch {
+	case b&0x80 == 0x00:
+		return 1
+	case b&0xE0 == 0xC0:
+		return 2
+	case b&0xF0 == 0xE0:
+		return 3
+	case b&0xF8 == 0xF0:
+		return 4
+	}
+	return 0
+}
+
+
+///*
+// * Event initializers.
+// */
+//
+//#define EVENT_INIT(event,event_type,event_start_mark,event_end_mark)
+//    (memset(&(event), 0, sizeof(yaml_event_t)),
+//     (event).type = (event_type),
+//     (event).start_mark = (event_start_mark),
+//     (event).end_mark = (event_end_mark))
+//
+
+//#define DOCUMENT_END_EVENT_INIT(event,event_implicit,start_mark,end_mark)
+//    (EVENT_INIT((event),YAML_DOCUMENT_END_EVENT,(start_mark),(end_mark)),
+//     (event).data.document_end.implicit = (event_implicit))
+//
+//#define ALIAS_EVENT_INIT(event,event_anchor,start_mark,end_mark)
+//    (EVENT_INIT((event),YAML_ALIAS_EVENT,(start_mark),(end_mark)),
+//     (event).data.alias.anchor = (event_anchor))
+//
+//#define SCALAR_EVENT_INIT(event,event_anchor,event_tag,event_value,event_length,
+//        event_plain_implicit, event_quoted_implicit,event_style,start_mark,end_mark)
+//    (EVENT_INIT((event),YAML_SCALAR_EVENT,(start_mark),(end_mark)),
+//     (event).data.scalar.anchor = (event_anchor),
+//     (event).data.scalar.tag = (event_tag),
+//     (event).data.scalar.value = (event_value),
+//     (event).data.scalar.length = (event_length),
+//     (event).data.scalar.plain_implicit = (event_plain_implicit),
+//     (event).data.scalar.quoted_implicit = (event_quoted_implicit),
+//     (event).data.scalar.style = (event_style))
+//
+//#define SEQUENCE_START_EVENT_INIT(event,event_anchor,event_tag,
+//        event_implicit,event_style,start_mark,end_mark)
+//    (EVENT_INIT((event),YAML_SEQUENCE_START_EVENT,(start_mark),(end_mark)),
+//     (event).data.sequence_start.anchor = (event_anchor),
+//     (event).data.sequence_start.tag = (event_tag),
+//     (event).data.sequence_start.implicit = (event_implicit),
+//     (event).data.sequence_start.style = (event_style))
+//
+//#define SEQUENCE_END_EVENT_INIT(event,start_mark,end_mark)
+//    (EVENT_INIT((event),YAML_SEQUENCE_END_EVENT,(start_mark),(end_mark)))
+//
+//#define MAPPING_START_EVENT_INIT(event,event_anchor,event_tag,
+//        event_implicit,event_style,start_mark,end_mark)
+//    (EVENT_INIT((event),YAML_MAPPING_START_EVENT,(start_mark),(end_mark)),
+//     (event).data.mapping_start.anchor = (event_anchor),
+//     (event).data.mapping_start.tag = (event_tag),
+//     (event).data.mapping_start.implicit = (event_implicit),
+//     (event).data.mapping_start.style = (event_style))
+//
+//#define MAPPING_END_EVENT_INIT(event,start_mark,end_mark)
+//    (EVENT_INIT((event),YAML_MAPPING_END_EVENT,(start_mark),(end_mark)))
+//
+///*
+// * Document initializer.
+// */
+//
+//#define DOCUMENT_INIT(document,document_nodes_start,document_nodes_end,
+//        document_version_directive,document_tag_directives_start,
+//        document_tag_directives_end,document_start_implicit,
+//        document_end_implicit,document_start_mark,document_end_mark)
+//    (memset(&(document), 0, sizeof(yaml_document_t)),
+//     (document).nodes.start = (document_nodes_start),
+//     (document).nodes.end = (document_nodes_end),
+//     (document).nodes.top = (document_nodes_start),
+//     (document).version_directive = (document_version_directive),
+//     (document).tag_directives.start = (document_tag_directives_start),
+//     (document).tag_directives.end = (document_tag_directives_end),
+//     (document).start_implicit = (document_start_implicit),
+//     (document).end_implicit = (document_end_implicit),
+//     (document).start_mark = (document_start_mark),
+//     (document).end_mark = (document_end_mark))
+//
+///*
+// * Node initializers.
+// */
+//
+//#define NODE_INIT(node,node_type,node_tag,node_start_mark,node_end_mark)
+//    (memset(&(node), 0, sizeof(yaml_node_t)),
+//     (node).type = (node_type),
+//     (node).tag = (node_tag),
+//     (node).start_mark = (node_start_mark),
+//     (node).end_mark = (node_end_mark))
+//
+//#define SCALAR_NODE_INIT(node,node_tag,node_value,node_length,
+//        node_style,start_mark,end_mark)
+//    (NODE_INIT((node),YAML_SCALAR_NODE,(node_tag),(start_mark),(end_mark)),
+//     (node).data.scalar.value = (node_value),
+//     (node).data.scalar.length = (node_length),
+//     (node).data.scalar.style = (node_style))
+//
+//#define SEQUENCE_NODE_INIT(node,node_tag,node_items_start,node_items_end,
+//        node_style,start_mark,end_mark)
+//    (NODE_INIT((node),YAML_SEQUENCE_NODE,(node_tag),(start_mark),(end_mark)),
+//     (node).data.sequence.items.start = (node_items_start),
+//     (node).data.sequence.items.end = (node_items_end),
+//     (node).data.sequence.items.top = (node_items_start),
+//     (node).data.sequence.style = (node_style))
+//
+//#define MAPPING_NODE_INIT(node,node_tag,node_pairs_start,node_pairs_end,
+//        node_style,start_mark,end_mark)
+//    (NODE_INIT((node),YAML_MAPPING_NODE,(node_tag),(start_mark),(end_mark)),
+//     (node).data.mapping.pairs.start = (node_pairs_start),
+//     (node).data.mapping.pairs.end = (node_pairs_end),
+//     (node).data.mapping.pairs.top = (node_pairs_start),
+//     (node).data.mapping.style = (node_style))
+//