diff --git a/api_c.go b/api_c.go
index 3212d0b..46a303d 100644
--- a/api_c.go
+++ b/api_c.go
@@ -68,6 +68,7 @@
 //}
 
 func yaml_insert_token(parser *yaml_parser_t, pos int, token *yaml_token_t) {
+	//fmt.Println("yaml_insert_token", "pos:", pos, "typ:", token.typ, "head:", parser.tokens_head, "len:", len(parser.tokens))
 	// Check if we can move the queue at the beginning of the buffer.
 	if parser.tokens_head > 0 && len(parser.tokens) == cap(parser.tokens) {
 		if parser.tokens_head != len(parser.tokens) {
@@ -76,12 +77,12 @@
 		parser.tokens = parser.tokens[:len(parser.tokens)-parser.tokens_head]
 		parser.tokens_head = 0
 	}
-	parser.tokens = append(parser.tokens, yaml_token_t{})
+	parser.tokens = append(parser.tokens, *token)
 	if pos < 0 {
 		return
 	}
 	copy(parser.tokens[parser.tokens_head+pos+1:], parser.tokens[parser.tokens_head+pos:])
-	parser.tokens[pos] = *token
+	parser.tokens[parser.tokens_head+pos] = *token
 }
 
 // Create a new parser object.
diff --git a/decode_test.go b/decode_test.go
index 83532f4..b341848 100644
--- a/decode_test.go
+++ b/decode_test.go
@@ -67,13 +67,28 @@
 	{"~: null key", map[interface{}]string{nil: "null key"}},
 	{"empty:", map[string]*bool{"empty": nil}},
 
-	// Sequence
+	// Flow sequence
 	{"seq: [A,B]", map[string]interface{}{"seq": []interface{}{"A", "B"}}},
-	{"seq: [A,B,C]", map[string][]string{"seq": []string{"A", "B", "C"}}},
+	{"seq: [A,B,C,]", map[string][]string{"seq": []string{"A", "B", "C"}}},
 	{"seq: [A,1,C]", map[string][]string{"seq": []string{"A", "1", "C"}}},
 	{"seq: [A,1,C]", map[string][]int{"seq": []int{1}}},
 	{"seq: [A,1,C]", map[string]interface{}{"seq": []interface{}{"A", 1, "C"}}},
 
+	// Block sequence
+	{"seq:\n - A\n - B", map[string]interface{}{"seq": []interface{}{"A", "B"}}},
+	{"seq:\n - A\n - B\n - C", map[string][]string{"seq": []string{"A", "B", "C"}}},
+	{"seq:\n - A\n - 1\n - C", map[string][]string{"seq": []string{"A", "1", "C"}}},
+	{"seq:\n - A\n - 1\n - C", map[string][]int{"seq": []int{1}}},
+	{"seq:\n - A\n - 1\n - C", map[string]interface{}{"seq": []interface{}{"A", 1, "C"}}},
+
+	// Literal block scalar
+	{"scalar: | # Comment\n\n literal\n\n \ttext\n\n",
+		map[string]string{"scalar": "\nliteral\n\n\ttext\n"}},
+
+	// Folded block scalar
+        {"scalar: > # Comment\n\n folded\n line\n \n next\n line\n  * one\n  * two\n\n last\n line\n\n",
+		map[string]string{"scalar": "\nfolded line\nnext line\n * one\n * two\n\nlast line\n"}},
+
 	// Map inside interface with no type hints.
 	{"a: {b: c}",
 		map[string]interface{}{"a": map[interface{}]interface{}{"b": "c"}}},
diff --git a/loader.c b/loader.c
deleted file mode 100644
index 9d3d912..0000000
--- a/loader.c
+++ /dev/null
@@ -1,432 +0,0 @@
-
-#include "yaml_private.h"
-
-/*
- * API functions.
- */
-
-YAML_DECLARE(int)
-yaml_parser_load(yaml_parser_t *parser, yaml_document_t *document);
-
-/*
- * Error handling.
- */
-
-static int
-yaml_parser_set_composer_error(yaml_parser_t *parser,
-        const char *problem, yaml_mark_t problem_mark);
-
-static int
-yaml_parser_set_composer_error_context(yaml_parser_t *parser,
-        const char *context, yaml_mark_t context_mark,
-        const char *problem, yaml_mark_t problem_mark);
-
-
-/*
- * Alias handling.
- */
-
-static int
-yaml_parser_register_anchor(yaml_parser_t *parser,
-        int index, yaml_char_t *anchor);
-
-/*
- * Clean up functions.
- */
-
-static void
-yaml_parser_delete_aliases(yaml_parser_t *parser);
-
-/*
- * Composer functions.
- */
-
-static int
-yaml_parser_load_document(yaml_parser_t *parser, yaml_event_t *first_event);
-
-static int
-yaml_parser_load_node(yaml_parser_t *parser, yaml_event_t *first_event);
-
-static int
-yaml_parser_load_alias(yaml_parser_t *parser, yaml_event_t *first_event);
-
-static int
-yaml_parser_load_scalar(yaml_parser_t *parser, yaml_event_t *first_event);
-
-static int
-yaml_parser_load_sequence(yaml_parser_t *parser, yaml_event_t *first_event);
-
-static int
-yaml_parser_load_mapping(yaml_parser_t *parser, yaml_event_t *first_event);
-
-/*
- * Load the next document of the stream.
- */
-
-YAML_DECLARE(int)
-yaml_parser_load(yaml_parser_t *parser, yaml_document_t *document)
-{
-    yaml_event_t event;
-
-    assert(parser);     /* Non-NULL parser object is expected. */
-    assert(document);   /* Non-NULL document object is expected. */
-
-    memset(document, 0, sizeof(yaml_document_t));
-    if (!STACK_INIT(parser, document->nodes, INITIAL_STACK_SIZE))
-        goto error;
-
-    if (!parser->stream_start_produced) {
-        if (!yaml_parser_parse(parser, &event)) goto error;
-        assert(event.type == YAML_STREAM_START_EVENT);
-                        /* STREAM-START is expected. */
-    }
-
-    if (parser->stream_end_produced) {
-        return 1;
-    }
-
-    if (!yaml_parser_parse(parser, &event)) goto error;
-    if (event.type == YAML_STREAM_END_EVENT) {
-        return 1;
-    }
-
-    if (!STACK_INIT(parser, parser->aliases, INITIAL_STACK_SIZE))
-        goto error;
-
-    parser->document = document;
-
-    if (!yaml_parser_load_document(parser, &event)) goto error;
-
-    yaml_parser_delete_aliases(parser);
-    parser->document = NULL;
-
-    return 1;
-
-error:
-
-    yaml_parser_delete_aliases(parser);
-    yaml_document_delete(document);
-    parser->document = NULL;
-
-    return 0;
-}
-
-/*
- * Set composer error.
- */
-
-static int
-yaml_parser_set_composer_error(yaml_parser_t *parser,
-        const char *problem, yaml_mark_t problem_mark)
-{
-    parser->error = YAML_COMPOSER_ERROR;
-    parser->problem = problem;
-    parser->problem_mark = problem_mark;
-
-    return 0;
-}
-
-/*
- * Set composer error with context.
- */
-
-static int
-yaml_parser_set_composer_error_context(yaml_parser_t *parser,
-        const char *context, yaml_mark_t context_mark,
-        const char *problem, yaml_mark_t problem_mark)
-{
-    parser->error = YAML_COMPOSER_ERROR;
-    parser->context = context;
-    parser->context_mark = context_mark;
-    parser->problem = problem;
-    parser->problem_mark = problem_mark;
-
-    return 0;
-}
-
-/*
- * Delete the stack of aliases.
- */
-
-static void
-yaml_parser_delete_aliases(yaml_parser_t *parser)
-{
-    while (!STACK_EMPTY(parser, parser->aliases)) {
-        yaml_free(POP(parser, parser->aliases).anchor);
-    }
-    STACK_DEL(parser, parser->aliases);
-}
-
-/*
- * Compose a document object.
- */
-
-static int
-yaml_parser_load_document(yaml_parser_t *parser, yaml_event_t *first_event)
-{
-    yaml_event_t event;
-
-    assert(first_event->type == YAML_DOCUMENT_START_EVENT);
-                        /* DOCUMENT-START is expected. */
-
-    parser->document->version_directive
-        = first_event->data.document_start.version_directive;
-    parser->document->tag_directives.start
-        = first_event->data.document_start.tag_directives.start;
-    parser->document->tag_directives.end
-        = first_event->data.document_start.tag_directives.end;
-    parser->document->start_implicit
-        = first_event->data.document_start.implicit;
-    parser->document->start_mark = first_event->start_mark;
-
-    if (!yaml_parser_parse(parser, &event)) return 0;
-
-    if (!yaml_parser_load_node(parser, &event)) return 0;
-
-    if (!yaml_parser_parse(parser, &event)) return 0;
-    assert(event.type == YAML_DOCUMENT_END_EVENT);
-                        /* DOCUMENT-END is expected. */
-
-    parser->document->end_implicit = event.data.document_end.implicit;
-    parser->document->end_mark = event.end_mark;
-
-    return 1;
-}
-
-/*
- * Compose a node.
- */
-
-static int
-yaml_parser_load_node(yaml_parser_t *parser, yaml_event_t *first_event)
-{
-    switch (first_event->type) {
-        case YAML_ALIAS_EVENT:
-            return yaml_parser_load_alias(parser, first_event);
-        case YAML_SCALAR_EVENT:
-            return yaml_parser_load_scalar(parser, first_event);
-        case YAML_SEQUENCE_START_EVENT:
-            return yaml_parser_load_sequence(parser, first_event);
-        case YAML_MAPPING_START_EVENT:
-            return yaml_parser_load_mapping(parser, first_event);
-        default:
-            assert(0);  /* Could not happen. */
-            return 0;
-    }
-
-    return 0;
-}
-
-/*
- * Add an anchor.
- */
-
-static int
-yaml_parser_register_anchor(yaml_parser_t *parser,
-        int index, yaml_char_t *anchor)
-{
-    yaml_alias_data_t data;
-    yaml_alias_data_t *alias_data;
-
-    if (!anchor) return 1;
-
-    data.anchor = anchor;
-    data.index = index;
-    data.mark = parser->document->nodes.start[index-1].start_mark;
-
-    for (alias_data = parser->aliases.start;
-            alias_data != parser->aliases.top; alias_data ++) {
-        if (strcmp((char *)alias_data->anchor, (char *)anchor) == 0) {
-            yaml_free(anchor);
-            return yaml_parser_set_composer_error_context(parser,
-                    "found duplicate anchor; first occurence",
-                    alias_data->mark, "second occurence", data.mark);
-        }
-    }
-
-    if (!PUSH(parser, parser->aliases, data)) {
-        yaml_free(anchor);
-        return 0;
-    }
-
-    return 1;
-}
-
-/*
- * Compose a node corresponding to an alias.
- */
-
-static int
-yaml_parser_load_alias(yaml_parser_t *parser, yaml_event_t *first_event)
-{
-    yaml_char_t *anchor = first_event->data.alias.anchor;
-    yaml_alias_data_t *alias_data;
-
-    for (alias_data = parser->aliases.start;
-            alias_data != parser->aliases.top; alias_data ++) {
-        if (strcmp((char *)alias_data->anchor, (char *)anchor) == 0) {
-            yaml_free(anchor);
-            return alias_data->index;
-        }
-    }
-
-    yaml_free(anchor);
-    return yaml_parser_set_composer_error(parser, "found undefined alias",
-            first_event->start_mark);
-}
-
-/*
- * Compose a scalar node.
- */
-
-static int
-yaml_parser_load_scalar(yaml_parser_t *parser, yaml_event_t *first_event)
-{
-    yaml_node_t node;
-    int index;
-    yaml_char_t *tag = first_event->data.scalar.tag;
-
-    if (!tag || strcmp((char *)tag, "!") == 0) {
-        yaml_free(tag);
-        tag = yaml_strdup((yaml_char_t *)YAML_DEFAULT_SCALAR_TAG);
-        if (!tag) goto error;
-    }
-
-    SCALAR_NODE_INIT(node, tag, first_event->data.scalar.value,
-            first_event->data.scalar.length, first_event->data.scalar.style,
-            first_event->start_mark, first_event->end_mark);
-
-    if (!PUSH(parser, parser->document->nodes, node)) goto error;
-
-    index = parser->document->nodes.top - parser->document->nodes.start;
-
-    if (!yaml_parser_register_anchor(parser, index,
-                first_event->data.scalar.anchor)) return 0;
-
-    return index;
-
-error:
-    yaml_free(tag);
-    yaml_free(first_event->data.scalar.anchor);
-    yaml_free(first_event->data.scalar.value);
-    return 0;
-}
-
-/*
- * Compose a sequence node.
- */
-
-static int
-yaml_parser_load_sequence(yaml_parser_t *parser, yaml_event_t *first_event)
-{
-    yaml_event_t event;
-    yaml_node_t node;
-    struct {
-        yaml_node_item_t *start;
-        yaml_node_item_t *end;
-        yaml_node_item_t *top;
-    } items = { NULL, NULL, NULL };
-    int index, item_index;
-    yaml_char_t *tag = first_event->data.sequence_start.tag;
-
-    if (!tag || strcmp((char *)tag, "!") == 0) {
-        yaml_free(tag);
-        tag = yaml_strdup((yaml_char_t *)YAML_DEFAULT_SEQUENCE_TAG);
-        if (!tag) goto error;
-    }
-
-    if (!STACK_INIT(parser, items, INITIAL_STACK_SIZE)) goto error;
-
-    SEQUENCE_NODE_INIT(node, tag, items.start, items.end,
-            first_event->data.sequence_start.style,
-            first_event->start_mark, first_event->end_mark);
-
-    if (!PUSH(parser, parser->document->nodes, node)) goto error;
-
-    index = parser->document->nodes.top - parser->document->nodes.start;
-
-    if (!yaml_parser_register_anchor(parser, index,
-                first_event->data.sequence_start.anchor)) return 0;
-
-    if (!yaml_parser_parse(parser, &event)) return 0;
-
-    while (event.type != YAML_SEQUENCE_END_EVENT) {
-        item_index = yaml_parser_load_node(parser, &event);
-        if (!item_index) return 0;
-        if (!PUSH(parser,
-                    parser->document->nodes.start[index-1].data.sequence.items,
-                    item_index)) return 0;
-        if (!yaml_parser_parse(parser, &event)) return 0;
-    }
-
-    parser->document->nodes.start[index-1].end_mark = event.end_mark;
-
-    return index;
-
-error:
-    yaml_free(tag);
-    yaml_free(first_event->data.sequence_start.anchor);
-    return 0;
-}
-
-/*
- * Compose a mapping node.
- */
-
-static int
-yaml_parser_load_mapping(yaml_parser_t *parser, yaml_event_t *first_event)
-{
-    yaml_event_t event;
-    yaml_node_t node;
-    struct {
-        yaml_node_pair_t *start;
-        yaml_node_pair_t *end;
-        yaml_node_pair_t *top;
-    } pairs = { NULL, NULL, NULL };
-    int index;
-    yaml_node_pair_t pair;
-    yaml_char_t *tag = first_event->data.mapping_start.tag;
-
-    if (!tag || strcmp((char *)tag, "!") == 0) {
-        yaml_free(tag);
-        tag = yaml_strdup((yaml_char_t *)YAML_DEFAULT_MAPPING_TAG);
-        if (!tag) goto error;
-    }
-
-    if (!STACK_INIT(parser, pairs, INITIAL_STACK_SIZE)) goto error;
-
-    MAPPING_NODE_INIT(node, tag, pairs.start, pairs.end,
-            first_event->data.mapping_start.style,
-            first_event->start_mark, first_event->end_mark);
-
-    if (!PUSH(parser, parser->document->nodes, node)) goto error;
-
-    index = parser->document->nodes.top - parser->document->nodes.start;
-
-    if (!yaml_parser_register_anchor(parser, index,
-                first_event->data.mapping_start.anchor)) return 0;
-
-    if (!yaml_parser_parse(parser, &event)) return 0;
-
-    while (event.type != YAML_MAPPING_END_EVENT) {
-        pair.key = yaml_parser_load_node(parser, &event);
-        if (!pair.key) return 0;
-        if (!yaml_parser_parse(parser, &event)) return 0;
-        pair.value = yaml_parser_load_node(parser, &event);
-        if (!pair.value) return 0;
-        if (!PUSH(parser,
-                    parser->document->nodes.start[index-1].data.mapping.pairs,
-                    pair)) return 0;
-        if (!yaml_parser_parse(parser, &event)) return 0;
-    }
-
-    parser->document->nodes.start[index-1].end_mark = event.end_mark;
-
-    return index;
-
-error:
-    yaml_free(tag);
-    yaml_free(first_event->data.mapping_start.anchor);
-    return 0;
-}
-
diff --git a/parser.c b/parser.c
deleted file mode 100644
index eb2a2c7..0000000
--- a/parser.c
+++ /dev/null
@@ -1,1374 +0,0 @@
-
-/*
- * 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?)?
- */
-
-#include "yaml_private.h"
-
-/*
- * Peek the next token in the token queue.
- */
-
-#define PEEK_TOKEN(parser)                                                      \
-    ((parser->token_available || yaml_parser_fetch_more_tokens(parser)) ?       \
-        parser->tokens.head : NULL)
-
-/*
- * Remove the next token from the queue (must be called after PEEK_TOKEN).
- */
-
-#define SKIP_TOKEN(parser)                                                      \
-    (parser->token_available = 0,                                               \
-     parser->tokens_parsed ++,                                                  \
-     parser->stream_end_produced =                                              \
-        (parser->tokens.head->type == YAML_STREAM_END_TOKEN),                   \
-     parser->tokens.head ++)
-
-/*
- * Public API declarations.
- */
-
-YAML_DECLARE(int)
-yaml_parser_parse(yaml_parser_t *parser, yaml_event_t *event);
-
-/*
- * Error handling.
- */
-
-static int
-yaml_parser_set_parser_error(yaml_parser_t *parser,
-        const char *problem, yaml_mark_t problem_mark);
-
-static int
-yaml_parser_set_parser_error_context(yaml_parser_t *parser,
-        const char *context, yaml_mark_t context_mark,
-        const char *problem, yaml_mark_t problem_mark);
-
-/*
- * State functions.
- */
-
-static int
-yaml_parser_state_machine(yaml_parser_t *parser, yaml_event_t *event);
-
-static int
-yaml_parser_parse_stream_start(yaml_parser_t *parser, yaml_event_t *event);
-
-static int
-yaml_parser_parse_document_start(yaml_parser_t *parser, yaml_event_t *event,
-        int implicit);
-
-static int
-yaml_parser_parse_document_content(yaml_parser_t *parser, yaml_event_t *event);
-
-static int
-yaml_parser_parse_document_end(yaml_parser_t *parser, yaml_event_t *event);
-
-static int
-yaml_parser_parse_node(yaml_parser_t *parser, yaml_event_t *event,
-        int block, int indentless_sequence);
-
-static int
-yaml_parser_parse_block_sequence_entry(yaml_parser_t *parser,
-        yaml_event_t *event, int first);
-
-static int
-yaml_parser_parse_indentless_sequence_entry(yaml_parser_t *parser,
-        yaml_event_t *event);
-
-static int
-yaml_parser_parse_block_mapping_key(yaml_parser_t *parser,
-        yaml_event_t *event, int first);
-
-static int
-yaml_parser_parse_block_mapping_value(yaml_parser_t *parser,
-        yaml_event_t *event);
-
-static int
-yaml_parser_parse_flow_sequence_entry(yaml_parser_t *parser,
-        yaml_event_t *event, int first);
-
-static int
-yaml_parser_parse_flow_sequence_entry_mapping_key(yaml_parser_t *parser,
-        yaml_event_t *event);
-
-static int
-yaml_parser_parse_flow_sequence_entry_mapping_value(yaml_parser_t *parser,
-        yaml_event_t *event);
-
-static int
-yaml_parser_parse_flow_sequence_entry_mapping_end(yaml_parser_t *parser,
-        yaml_event_t *event);
-
-static int
-yaml_parser_parse_flow_mapping_key(yaml_parser_t *parser,
-        yaml_event_t *event, int first);
-
-static int
-yaml_parser_parse_flow_mapping_value(yaml_parser_t *parser,
-        yaml_event_t *event, int empty);
-
-/*
- * Utility functions.
- */
-
-static int
-yaml_parser_process_empty_scalar(yaml_parser_t *parser,
-        yaml_event_t *event, yaml_mark_t mark);
-
-static int
-yaml_parser_process_directives(yaml_parser_t *parser,
-        yaml_version_directive_t **version_directive_ref,
-        yaml_tag_directive_t **tag_directives_start_ref,
-        yaml_tag_directive_t **tag_directives_end_ref);
-
-static int
-yaml_parser_append_tag_directive(yaml_parser_t *parser,
-        yaml_tag_directive_t value, int allow_duplicates, yaml_mark_t mark);
-
-/*
- * Get the next event.
- */
-
-YAML_DECLARE(int)
-yaml_parser_parse(yaml_parser_t *parser, yaml_event_t *event)
-{
-    assert(parser);     /* Non-NULL parser object is expected. */
-    assert(event);      /* Non-NULL event object is expected. */
-
-    /* Erase the event object. */
-
-    memset(event, 0, sizeof(yaml_event_t));
-
-    /* No events after the end of the stream or error. */
-
-    if (parser->stream_end_produced || parser->error ||
-            parser->state == YAML_PARSE_END_STATE) {
-        return 1;
-    }
-
-    /* Generate the next event. */
-
-    return yaml_parser_state_machine(parser, event);
-}
-
-/*
- * Set parser error.
- */
-
-static int
-yaml_parser_set_parser_error(yaml_parser_t *parser,
-        const char *problem, yaml_mark_t problem_mark)
-{
-    parser->error = YAML_PARSER_ERROR;
-    parser->problem = problem;
-    parser->problem_mark = problem_mark;
-
-    return 0;
-}
-
-static int
-yaml_parser_set_parser_error_context(yaml_parser_t *parser,
-        const char *context, yaml_mark_t context_mark,
-        const char *problem, yaml_mark_t problem_mark)
-{
-    parser->error = YAML_PARSER_ERROR;
-    parser->context = context;
-    parser->context_mark = context_mark;
-    parser->problem = problem;
-    parser->problem_mark = problem_mark;
-
-    return 0;
-}
-
-
-/*
- * State dispatcher.
- */
-
-static int
-yaml_parser_state_machine(yaml_parser_t *parser, yaml_event_t *event)
-{
-    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, 1);
-
-        case YAML_PARSE_DOCUMENT_START_STATE:
-            return yaml_parser_parse_document_start(parser, event, 0);
-
-        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, 1, 0);
-
-        case YAML_PARSE_BLOCK_NODE_OR_INDENTLESS_SEQUENCE_STATE:
-            return yaml_parser_parse_node(parser, event, 1, 1);
-
-        case YAML_PARSE_FLOW_NODE_STATE:
-            return yaml_parser_parse_node(parser, event, 0, 0);
-
-        case YAML_PARSE_BLOCK_SEQUENCE_FIRST_ENTRY_STATE:
-            return yaml_parser_parse_block_sequence_entry(parser, event, 1);
-
-        case YAML_PARSE_BLOCK_SEQUENCE_ENTRY_STATE:
-            return yaml_parser_parse_block_sequence_entry(parser, event, 0);
-
-        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, 1);
-
-        case YAML_PARSE_BLOCK_MAPPING_KEY_STATE:
-            return yaml_parser_parse_block_mapping_key(parser, event, 0);
-
-        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, 1);
-
-        case YAML_PARSE_FLOW_SEQUENCE_ENTRY_STATE:
-            return yaml_parser_parse_flow_sequence_entry(parser, event, 0);
-
-        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, 1);
-
-        case YAML_PARSE_FLOW_MAPPING_KEY_STATE:
-            return yaml_parser_parse_flow_mapping_key(parser, event, 0);
-
-        case YAML_PARSE_FLOW_MAPPING_VALUE_STATE:
-            return yaml_parser_parse_flow_mapping_value(parser, event, 0);
-
-        case YAML_PARSE_FLOW_MAPPING_EMPTY_VALUE_STATE:
-            return yaml_parser_parse_flow_mapping_value(parser, event, 1);
-
-        default:
-            assert(1);      /* Invalid state. */
-    }
-
-    return 0;
-}
-
-/*
- * Parse the production:
- * stream   ::= STREAM-START implicit_document? explicit_document* STREAM-END
- *              ************
- */
-
-static int
-yaml_parser_parse_stream_start(yaml_parser_t *parser, yaml_event_t *event)
-{
-    yaml_token_t *token;
-
-    token = PEEK_TOKEN(parser);
-    if (!token) return 0;
-
-    if (token->type != 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;
-    STREAM_START_EVENT_INIT(*event, token->data.stream_start.encoding,
-            token->start_mark, token->start_mark);
-    SKIP_TOKEN(parser);
-
-    return 1;
-}
-
-/*
- * Parse the productions:
- * implicit_document    ::= block_node DOCUMENT-END*
- *                          *
- * explicit_document    ::= DIRECTIVE* DOCUMENT-START block_node? DOCUMENT-END*
- *                          *************************
- */
-
-static int
-yaml_parser_parse_document_start(yaml_parser_t *parser, yaml_event_t *event,
-        int implicit)
-{
-    yaml_token_t *token;
-    yaml_version_directive_t *version_directive = NULL;
-    struct {
-        yaml_tag_directive_t *start;
-        yaml_tag_directive_t *end;
-    } tag_directives = { NULL, NULL };
-
-    token = PEEK_TOKEN(parser);
-    if (!token) return 0;
-
-    /* Parse extra document end indicators. */
-
-    if (!implicit)
-    {
-        while (token->type == YAML_DOCUMENT_END_TOKEN) {
-            SKIP_TOKEN(parser);
-            token = PEEK_TOKEN(parser);
-            if (!token) return 0;
-        }
-    }
-
-    /* Parse an implicit document. */
-
-    if (implicit && token->type != YAML_VERSION_DIRECTIVE_TOKEN &&
-            token->type != YAML_TAG_DIRECTIVE_TOKEN &&
-            token->type != YAML_DOCUMENT_START_TOKEN &&
-            token->type != YAML_STREAM_END_TOKEN)
-    {
-        if (!yaml_parser_process_directives(parser, NULL, NULL, NULL))
-            return 0;
-        if (!PUSH(parser, parser->states, YAML_PARSE_DOCUMENT_END_STATE))
-            return 0;
-        parser->state = YAML_PARSE_BLOCK_NODE_STATE;
-        DOCUMENT_START_EVENT_INIT(*event, NULL, NULL, NULL, 1,
-                token->start_mark, token->start_mark);
-        return 1;
-    }
-
-    /* Parse an explicit document. */
-
-    else if (token->type != YAML_STREAM_END_TOKEN)
-    {
-        yaml_mark_t start_mark, end_mark;
-        start_mark = token->start_mark;
-        if (!yaml_parser_process_directives(parser, &version_directive,
-                    &tag_directives.start, &tag_directives.end))
-            return 0;
-        token = PEEK_TOKEN(parser);
-        if (!token) goto error;
-        if (token->type != YAML_DOCUMENT_START_TOKEN) {
-            yaml_parser_set_parser_error(parser,
-                    "did not find expected <document start>", token->start_mark);
-            goto error;
-        }
-        if (!PUSH(parser, parser->states, YAML_PARSE_DOCUMENT_END_STATE))
-            goto error;
-        parser->state = YAML_PARSE_DOCUMENT_CONTENT_STATE;
-        end_mark = token->end_mark;
-        DOCUMENT_START_EVENT_INIT(*event, version_directive,
-                tag_directives.start, tag_directives.end, 0,
-                start_mark, end_mark);
-        SKIP_TOKEN(parser);
-        version_directive = NULL;
-        tag_directives.start = tag_directives.end = NULL;
-        return 1;
-    }
-
-    /* Parse the stream end. */
-
-    else
-    {
-        parser->state = YAML_PARSE_END_STATE;
-        STREAM_END_EVENT_INIT(*event, token->start_mark, token->end_mark);
-        SKIP_TOKEN(parser);
-        return 1;
-    }
-
-error:
-    yaml_free(version_directive);
-    while (tag_directives.start != tag_directives.end) {
-        yaml_free(tag_directives.end[-1].handle);
-        yaml_free(tag_directives.end[-1].prefix);
-        tag_directives.end --;
-    }
-    yaml_free(tag_directives.start);
-    return 0;
-}
-
-/*
- * Parse the productions:
- * explicit_document    ::= DIRECTIVE* DOCUMENT-START block_node? DOCUMENT-END*
- *                                                    ***********
- */
-
-static int
-yaml_parser_parse_document_content(yaml_parser_t *parser, yaml_event_t *event)
-{
-    yaml_token_t *token;
-
-    token = PEEK_TOKEN(parser);
-    if (!token) return 0;
-
-    if (token->type == YAML_VERSION_DIRECTIVE_TOKEN ||
-            token->type == YAML_TAG_DIRECTIVE_TOKEN ||
-            token->type == YAML_DOCUMENT_START_TOKEN ||
-            token->type == YAML_DOCUMENT_END_TOKEN ||
-            token->type == YAML_STREAM_END_TOKEN) {
-        parser->state = POP(parser, parser->states);
-        return yaml_parser_process_empty_scalar(parser, event,
-                token->start_mark);
-    }
-    else {
-        return yaml_parser_parse_node(parser, event, 1, 0);
-    }
-}
-
-/*
- * Parse the productions:
- * implicit_document    ::= block_node DOCUMENT-END*
- *                                     *************
- * explicit_document    ::= DIRECTIVE* DOCUMENT-START block_node? DOCUMENT-END*
- *                                                                *************
- */
-
-static int
-yaml_parser_parse_document_end(yaml_parser_t *parser, yaml_event_t *event)
-{
-    yaml_token_t *token;
-    yaml_mark_t start_mark, end_mark;
-    int implicit = 1;
-
-    token = PEEK_TOKEN(parser);
-    if (!token) return 0;
-
-    start_mark = end_mark = token->start_mark;
-
-    if (token->type == YAML_DOCUMENT_END_TOKEN) {
-        end_mark = token->end_mark;
-        SKIP_TOKEN(parser);
-        implicit = 0;
-    }
-
-    while (!STACK_EMPTY(parser, parser->tag_directives)) {
-        yaml_tag_directive_t tag_directive = POP(parser, parser->tag_directives);
-        yaml_free(tag_directive.handle);
-        yaml_free(tag_directive.prefix);
-    }
-
-    parser->state = YAML_PARSE_DOCUMENT_START_STATE;
-    DOCUMENT_END_EVENT_INIT(*event, implicit, start_mark, end_mark);
-
-    return 1;
-}
-
-/*
- * 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
- *                                            ******
- */
-
-static int
-yaml_parser_parse_node(yaml_parser_t *parser, yaml_event_t *event,
-        int block, int indentless_sequence)
-{
-    yaml_token_t *token;
-    yaml_char_t *anchor = NULL;
-    yaml_char_t *tag_handle = NULL;
-    yaml_char_t *tag_suffix = NULL;
-    yaml_char_t *tag = NULL;
-    yaml_mark_t start_mark, end_mark, tag_mark;
-    int implicit;
-
-    token = PEEK_TOKEN(parser);
-    if (!token) return 0;
-
-    if (token->type == YAML_ALIAS_TOKEN)
-    {
-        parser->state = POP(parser, parser->states);
-        ALIAS_EVENT_INIT(*event, token->data.alias.value,
-                token->start_mark, token->end_mark);
-        SKIP_TOKEN(parser);
-        return 1;
-    }
-
-    else
-    {
-        start_mark = end_mark = token->start_mark;
-
-        if (token->type == YAML_ANCHOR_TOKEN)
-        {
-            anchor = token->data.anchor.value;
-            start_mark = token->start_mark;
-            end_mark = token->end_mark;
-            SKIP_TOKEN(parser);
-            token = PEEK_TOKEN(parser);
-            if (!token) goto error;
-            if (token->type == YAML_TAG_TOKEN)
-            {
-                tag_handle = token->data.tag.handle;
-                tag_suffix = token->data.tag.suffix;
-                tag_mark = token->start_mark;
-                end_mark = token->end_mark;
-                SKIP_TOKEN(parser);
-                token = PEEK_TOKEN(parser);
-                if (!token) goto error;
-            }
-        }
-        else if (token->type == YAML_TAG_TOKEN)
-        {
-            tag_handle = token->data.tag.handle;
-            tag_suffix = token->data.tag.suffix;
-            start_mark = tag_mark = token->start_mark;
-            end_mark = token->end_mark;
-            SKIP_TOKEN(parser);
-            token = PEEK_TOKEN(parser);
-            if (!token) goto error;
-            if (token->type == YAML_ANCHOR_TOKEN)
-            {
-                anchor = token->data.anchor.value;
-                end_mark = token->end_mark;
-                SKIP_TOKEN(parser);
-                token = PEEK_TOKEN(parser);
-                if (!token) goto error;
-            }
-        }
-
-        if (tag_handle) {
-            if (!*tag_handle) {
-                tag = tag_suffix;
-                yaml_free(tag_handle);
-                tag_handle = tag_suffix = NULL;
-            }
-            else {
-                yaml_tag_directive_t *tag_directive;
-                for (tag_directive = parser->tag_directives.start;
-                        tag_directive != parser->tag_directives.top;
-                        tag_directive ++) {
-                    if (strcmp((char *)tag_directive->handle, (char *)tag_handle) == 0) {
-                        size_t prefix_len = strlen((char *)tag_directive->prefix);
-                        size_t suffix_len = strlen((char *)tag_suffix);
-                        tag = yaml_malloc(prefix_len+suffix_len+1);
-                        if (!tag) {
-                            parser->error = YAML_MEMORY_ERROR;
-                            goto error;
-                        }
-                        memcpy(tag, tag_directive->prefix, prefix_len);
-                        memcpy(tag+prefix_len, tag_suffix, suffix_len);
-                        tag[prefix_len+suffix_len] = '\0';
-                        yaml_free(tag_handle);
-                        yaml_free(tag_suffix);
-                        tag_handle = tag_suffix = NULL;
-                        break;
-                    }
-                }
-                if (!tag) {
-                    yaml_parser_set_parser_error_context(parser,
-                            "while parsing a node", start_mark,
-                            "found undefined tag handle", tag_mark);
-                    goto error;
-                }
-            }
-        }
-
-        implicit = (!tag || !*tag);
-        if (indentless_sequence && token->type == YAML_BLOCK_ENTRY_TOKEN) {
-            end_mark = token->end_mark;
-            parser->state = YAML_PARSE_INDENTLESS_SEQUENCE_ENTRY_STATE;
-            SEQUENCE_START_EVENT_INIT(*event, anchor, tag, implicit,
-                    YAML_BLOCK_SEQUENCE_STYLE, start_mark, end_mark);
-            return 1;
-        }
-        else {
-            if (token->type == YAML_SCALAR_TOKEN) {
-                int plain_implicit = 0;
-                int quoted_implicit = 0;
-                end_mark = token->end_mark;
-                if ((token->data.scalar.style == YAML_PLAIN_SCALAR_STYLE && !tag)
-                        || (tag && strcmp((char *)tag, "!") == 0)) {
-                    plain_implicit = 1;
-                }
-                else if (!tag) {
-                    quoted_implicit = 1;
-                }
-                parser->state = POP(parser, parser->states);
-                SCALAR_EVENT_INIT(*event, anchor, tag,
-                        token->data.scalar.value, token->data.scalar.length,
-                        plain_implicit, quoted_implicit,
-                        token->data.scalar.style, start_mark, end_mark);
-                SKIP_TOKEN(parser);
-                return 1;
-            }
-            else if (token->type == YAML_FLOW_SEQUENCE_START_TOKEN) {
-                end_mark = token->end_mark;
-                parser->state = YAML_PARSE_FLOW_SEQUENCE_FIRST_ENTRY_STATE;
-                SEQUENCE_START_EVENT_INIT(*event, anchor, tag, implicit,
-                        YAML_FLOW_SEQUENCE_STYLE, start_mark, end_mark);
-                return 1;
-            }
-            else if (token->type == YAML_FLOW_MAPPING_START_TOKEN) {
-                end_mark = token->end_mark;
-                parser->state = YAML_PARSE_FLOW_MAPPING_FIRST_KEY_STATE;
-                MAPPING_START_EVENT_INIT(*event, anchor, tag, implicit,
-                        YAML_FLOW_MAPPING_STYLE, start_mark, end_mark);
-                return 1;
-            }
-            else if (block && token->type == YAML_BLOCK_SEQUENCE_START_TOKEN) {
-                end_mark = token->end_mark;
-                parser->state = YAML_PARSE_BLOCK_SEQUENCE_FIRST_ENTRY_STATE;
-                SEQUENCE_START_EVENT_INIT(*event, anchor, tag, implicit,
-                        YAML_BLOCK_SEQUENCE_STYLE, start_mark, end_mark);
-                return 1;
-            }
-            else if (block && token->type == YAML_BLOCK_MAPPING_START_TOKEN) {
-                end_mark = token->end_mark;
-                parser->state = YAML_PARSE_BLOCK_MAPPING_FIRST_KEY_STATE;
-                MAPPING_START_EVENT_INIT(*event, anchor, tag, implicit,
-                        YAML_BLOCK_MAPPING_STYLE, start_mark, end_mark);
-                return 1;
-            }
-            else if (anchor || tag) {
-                yaml_char_t *value = yaml_malloc(1);
-                if (!value) {
-                    parser->error = YAML_MEMORY_ERROR;
-                    goto error;
-                }
-                value[0] = '\0';
-                parser->state = POP(parser, parser->states);
-                SCALAR_EVENT_INIT(*event, anchor, tag, value, 0,
-                        implicit, 0, YAML_PLAIN_SCALAR_STYLE,
-                        start_mark, end_mark);
-                return 1;
-            }
-            else {
-                yaml_parser_set_parser_error_context(parser,
-                        (block ? "while parsing a block node"
-                         : "while parsing a flow node"), start_mark,
-                        "did not find expected node content", token->start_mark);
-                goto error;
-            }
-        }
-    }
-
-error:
-    yaml_free(anchor);
-    yaml_free(tag_handle);
-    yaml_free(tag_suffix);
-    yaml_free(tag);
-
-    return 0;
-}
-
-/*
- * Parse the productions:
- * block_sequence ::= BLOCK-SEQUENCE-START (BLOCK-ENTRY block_node?)* BLOCK-END
- *                    ********************  *********** *             *********
- */
-
-static int
-yaml_parser_parse_block_sequence_entry(yaml_parser_t *parser,
-        yaml_event_t *event, int first)
-{
-    yaml_token_t *token;
-
-    if (first) {
-        token = PEEK_TOKEN(parser);
-        if (!PUSH(parser, parser->marks, token->start_mark))
-            return 0;
-        SKIP_TOKEN(parser);
-    }
-
-    token = PEEK_TOKEN(parser);
-    if (!token) return 0;
-
-    if (token->type == YAML_BLOCK_ENTRY_TOKEN)
-    {
-        yaml_mark_t mark = token->end_mark;
-        SKIP_TOKEN(parser);
-        token = PEEK_TOKEN(parser);
-        if (!token) return 0;
-        if (token->type != YAML_BLOCK_ENTRY_TOKEN &&
-                token->type != YAML_BLOCK_END_TOKEN) {
-            if (!PUSH(parser, parser->states,
-                        YAML_PARSE_BLOCK_SEQUENCE_ENTRY_STATE))
-                return 0;
-            return yaml_parser_parse_node(parser, event, 1, 0);
-        }
-        else {
-            parser->state = YAML_PARSE_BLOCK_SEQUENCE_ENTRY_STATE;
-            return yaml_parser_process_empty_scalar(parser, event, mark);
-        }
-    }
-
-    else if (token->type == YAML_BLOCK_END_TOKEN)
-    {
-        yaml_mark_t dummy_mark;     /* Used to eliminate a compiler warning. */
-        parser->state = POP(parser, parser->states);
-        dummy_mark = POP(parser, parser->marks);
-        SEQUENCE_END_EVENT_INIT(*event, token->start_mark, token->end_mark);
-        SKIP_TOKEN(parser);
-        return 1;
-    }
-
-    else
-    {
-        return yaml_parser_set_parser_error_context(parser,
-                "while parsing a block collection", POP(parser, parser->marks),
-                "did not find expected '-' indicator", token->start_mark);
-    }
-}
-
-/*
- * Parse the productions:
- * indentless_sequence  ::= (BLOCK-ENTRY block_node?)+
- *                           *********** *
- */
-
-static int
-yaml_parser_parse_indentless_sequence_entry(yaml_parser_t *parser,
-        yaml_event_t *event)
-{
-    yaml_token_t *token;
-
-    token = PEEK_TOKEN(parser);
-    if (!token) return 0;
-
-    if (token->type == YAML_BLOCK_ENTRY_TOKEN)
-    {
-        yaml_mark_t mark = token->end_mark;
-        SKIP_TOKEN(parser);
-        token = PEEK_TOKEN(parser);
-        if (!token) return 0;
-        if (token->type != YAML_BLOCK_ENTRY_TOKEN &&
-                token->type != YAML_KEY_TOKEN &&
-                token->type != YAML_VALUE_TOKEN &&
-                token->type != YAML_BLOCK_END_TOKEN) {
-            if (!PUSH(parser, parser->states,
-                        YAML_PARSE_INDENTLESS_SEQUENCE_ENTRY_STATE))
-                return 0;
-            return yaml_parser_parse_node(parser, event, 1, 0);
-        }
-        else {
-            parser->state = YAML_PARSE_INDENTLESS_SEQUENCE_ENTRY_STATE;
-            return yaml_parser_process_empty_scalar(parser, event, mark);
-        }
-    }
-
-    else
-    {
-        parser->state = POP(parser, parser->states);
-        SEQUENCE_END_EVENT_INIT(*event, token->start_mark, token->start_mark);
-        return 1;
-    }
-}
-
-/*
- * Parse the productions:
- * block_mapping        ::= BLOCK-MAPPING_START
- *                          *******************
- *                          ((KEY block_node_or_indentless_sequence?)?
- *                            *** *
- *                          (VALUE block_node_or_indentless_sequence?)?)*
- *
- *                          BLOCK-END
- *                          *********
- */
-
-static int
-yaml_parser_parse_block_mapping_key(yaml_parser_t *parser,
-        yaml_event_t *event, int first)
-{
-    yaml_token_t *token;
-
-    if (first) {
-        token = PEEK_TOKEN(parser);
-        if (!PUSH(parser, parser->marks, token->start_mark))
-            return 0;
-        SKIP_TOKEN(parser);
-    }
-
-    token = PEEK_TOKEN(parser);
-    if (!token) return 0;
-
-    if (token->type == YAML_KEY_TOKEN)
-    {
-        yaml_mark_t mark = token->end_mark;
-        SKIP_TOKEN(parser);
-        token = PEEK_TOKEN(parser);
-        if (!token) return 0;
-        if (token->type != YAML_KEY_TOKEN &&
-                token->type != YAML_VALUE_TOKEN &&
-                token->type != YAML_BLOCK_END_TOKEN) {
-            if (!PUSH(parser, parser->states,
-                        YAML_PARSE_BLOCK_MAPPING_VALUE_STATE))
-                return 0;
-            return yaml_parser_parse_node(parser, event, 1, 1);
-        }
-        else {
-            parser->state = YAML_PARSE_BLOCK_MAPPING_VALUE_STATE;
-            return yaml_parser_process_empty_scalar(parser, event, mark);
-        }
-    }
-
-    else if (token->type == YAML_BLOCK_END_TOKEN)
-    {
-        yaml_mark_t dummy_mark;     /* Used to eliminate a compiler warning. */
-        parser->state = POP(parser, parser->states);
-        dummy_mark = POP(parser, parser->marks);
-        MAPPING_END_EVENT_INIT(*event, token->start_mark, token->end_mark);
-        SKIP_TOKEN(parser);
-        return 1;
-    }
-
-    else
-    {
-        return yaml_parser_set_parser_error_context(parser,
-                "while parsing a block mapping", POP(parser, parser->marks),
-                "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
- *
- */
-
-static int
-yaml_parser_parse_block_mapping_value(yaml_parser_t *parser,
-        yaml_event_t *event)
-{
-    yaml_token_t *token;
-
-    token = PEEK_TOKEN(parser);
-    if (!token) return 0;
-
-    if (token->type == YAML_VALUE_TOKEN)
-    {
-        yaml_mark_t mark = token->end_mark;
-        SKIP_TOKEN(parser);
-        token = PEEK_TOKEN(parser);
-        if (!token) return 0;
-        if (token->type != YAML_KEY_TOKEN &&
-                token->type != YAML_VALUE_TOKEN &&
-                token->type != YAML_BLOCK_END_TOKEN) {
-            if (!PUSH(parser, parser->states,
-                        YAML_PARSE_BLOCK_MAPPING_KEY_STATE))
-                return 0;
-            return yaml_parser_parse_node(parser, event, 1, 1);
-        }
-        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?)?
- *                          *
- */
-
-static int
-yaml_parser_parse_flow_sequence_entry(yaml_parser_t *parser,
-        yaml_event_t *event, int first)
-{
-    yaml_token_t *token;
-    yaml_mark_t dummy_mark;     /* Used to eliminate a compiler warning. */
-
-    if (first) {
-        token = PEEK_TOKEN(parser);
-        if (!PUSH(parser, parser->marks, token->start_mark))
-            return 0;
-        SKIP_TOKEN(parser);
-    }
-
-    token = PEEK_TOKEN(parser);
-    if (!token) return 0;
-
-    if (token->type != YAML_FLOW_SEQUENCE_END_TOKEN)
-    {
-        if (!first) {
-            if (token->type == YAML_FLOW_ENTRY_TOKEN) {
-                SKIP_TOKEN(parser);
-                token = PEEK_TOKEN(parser);
-                if (!token) return 0;
-            }
-            else {
-                return yaml_parser_set_parser_error_context(parser,
-                        "while parsing a flow sequence", POP(parser, parser->marks),
-                        "did not find expected ',' or ']'", token->start_mark);
-            }
-        }
-
-        if (token->type == YAML_KEY_TOKEN) {
-            parser->state = YAML_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_KEY_STATE;
-            MAPPING_START_EVENT_INIT(*event, NULL, NULL,
-                    1, YAML_FLOW_MAPPING_STYLE,
-                    token->start_mark, token->end_mark);
-            SKIP_TOKEN(parser);
-            return 1;
-        }
-
-        else if (token->type != YAML_FLOW_SEQUENCE_END_TOKEN) {
-            if (!PUSH(parser, parser->states,
-                        YAML_PARSE_FLOW_SEQUENCE_ENTRY_STATE))
-                return 0;
-            return yaml_parser_parse_node(parser, event, 0, 0);
-        }
-    }
-
-    parser->state = POP(parser, parser->states);
-    dummy_mark = POP(parser, parser->marks);
-    SEQUENCE_END_EVENT_INIT(*event, token->start_mark, token->end_mark);
-    SKIP_TOKEN(parser);
-    return 1;
-}
-
-/*
- * Parse the productions:
- * flow_sequence_entry  ::= flow_node | KEY flow_node? (VALUE flow_node?)?
- *                                      *** *
- */
-
-static int
-yaml_parser_parse_flow_sequence_entry_mapping_key(yaml_parser_t *parser,
-        yaml_event_t *event)
-{
-    yaml_token_t *token;
-
-    token = PEEK_TOKEN(parser);
-    if (!token) return 0;
-
-    if (token->type != YAML_VALUE_TOKEN && token->type != YAML_FLOW_ENTRY_TOKEN
-            && token->type != YAML_FLOW_SEQUENCE_END_TOKEN) {
-        if (!PUSH(parser, parser->states,
-                    YAML_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_VALUE_STATE))
-            return 0;
-        return yaml_parser_parse_node(parser, event, 0, 0);
-    }
-    else {
-        yaml_mark_t 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?)?
- *                                                      ***** *
- */
-
-static int
-yaml_parser_parse_flow_sequence_entry_mapping_value(yaml_parser_t *parser,
-        yaml_event_t *event)
-{
-    yaml_token_t *token;
-
-    token = PEEK_TOKEN(parser);
-    if (!token) return 0;
-
-    if (token->type == YAML_VALUE_TOKEN) {
-        SKIP_TOKEN(parser);
-        token = PEEK_TOKEN(parser);
-        if (!token) return 0;
-        if (token->type != YAML_FLOW_ENTRY_TOKEN
-                && token->type != YAML_FLOW_SEQUENCE_END_TOKEN) {
-            if (!PUSH(parser, parser->states,
-                        YAML_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_END_STATE))
-                return 0;
-            return yaml_parser_parse_node(parser, event, 0, 0);
-        }
-    }
-    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?)?
- *                                                                      *
- */
-
-static int
-yaml_parser_parse_flow_sequence_entry_mapping_end(yaml_parser_t *parser,
-        yaml_event_t *event)
-{
-    yaml_token_t *token;
-
-    token = PEEK_TOKEN(parser);
-    if (!token) return 0;
-
-    parser->state = YAML_PARSE_FLOW_SEQUENCE_ENTRY_STATE;
-
-    MAPPING_END_EVENT_INIT(*event, token->start_mark, token->start_mark);
-    return 1;
-}
-
-/*
- * 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?)?
- *                          *           *** *
- */
-
-static int
-yaml_parser_parse_flow_mapping_key(yaml_parser_t *parser,
-        yaml_event_t *event, int first)
-{
-    yaml_token_t *token;
-    yaml_mark_t dummy_mark;     /* Used to eliminate a compiler warning. */
-
-    if (first) {
-        token = PEEK_TOKEN(parser);
-        if (!PUSH(parser, parser->marks, token->start_mark))
-            return 0;
-        SKIP_TOKEN(parser);
-    }
-
-    token = PEEK_TOKEN(parser);
-    if (!token) return 0;
-
-    if (token->type != YAML_FLOW_MAPPING_END_TOKEN)
-    {
-        if (!first) {
-            if (token->type == YAML_FLOW_ENTRY_TOKEN) {
-                SKIP_TOKEN(parser);
-                token = PEEK_TOKEN(parser);
-                if (!token) return 0;
-            }
-            else {
-                return yaml_parser_set_parser_error_context(parser,
-                        "while parsing a flow mapping", POP(parser, parser->marks),
-                        "did not find expected ',' or '}'", token->start_mark);
-            }
-        }
-
-        if (token->type == YAML_KEY_TOKEN) {
-            SKIP_TOKEN(parser);
-            token = PEEK_TOKEN(parser);
-            if (!token) return 0;
-            if (token->type != YAML_VALUE_TOKEN
-                    && token->type != YAML_FLOW_ENTRY_TOKEN
-                    && token->type != YAML_FLOW_MAPPING_END_TOKEN) {
-                if (!PUSH(parser, parser->states,
-                            YAML_PARSE_FLOW_MAPPING_VALUE_STATE))
-                    return 0;
-                return yaml_parser_parse_node(parser, event, 0, 0);
-            }
-            else {
-                parser->state = YAML_PARSE_FLOW_MAPPING_VALUE_STATE;
-                return yaml_parser_process_empty_scalar(parser, event,
-                        token->start_mark);
-            }
-        }
-        else if (token->type != YAML_FLOW_MAPPING_END_TOKEN) {
-            if (!PUSH(parser, parser->states,
-                        YAML_PARSE_FLOW_MAPPING_EMPTY_VALUE_STATE))
-                return 0;
-            return yaml_parser_parse_node(parser, event, 0, 0);
-        }
-    }
-
-    parser->state = POP(parser, parser->states);
-    dummy_mark = POP(parser, parser->marks);
-    MAPPING_END_EVENT_INIT(*event, token->start_mark, token->end_mark);
-    SKIP_TOKEN(parser);
-    return 1;
-}
-
-/*
- * Parse the productions:
- * flow_mapping_entry   ::= flow_node | KEY flow_node? (VALUE flow_node?)?
- *                                   *                  ***** *
- */
-
-static int
-yaml_parser_parse_flow_mapping_value(yaml_parser_t *parser,
-        yaml_event_t *event, int empty)
-{
-    yaml_token_t *token;
-
-    token = PEEK_TOKEN(parser);
-    if (!token) return 0;
-
-    if (empty) {
-        parser->state = YAML_PARSE_FLOW_MAPPING_KEY_STATE;
-        return yaml_parser_process_empty_scalar(parser, event,
-                token->start_mark);
-    }
-
-    if (token->type == YAML_VALUE_TOKEN) {
-        SKIP_TOKEN(parser);
-        token = PEEK_TOKEN(parser);
-        if (!token) return 0;
-        if (token->type != YAML_FLOW_ENTRY_TOKEN
-                && token->type != YAML_FLOW_MAPPING_END_TOKEN) {
-            if (!PUSH(parser, parser->states,
-                        YAML_PARSE_FLOW_MAPPING_KEY_STATE))
-                return 0;
-            return yaml_parser_parse_node(parser, event, 0, 0);
-        }
-    }
-
-    parser->state = YAML_PARSE_FLOW_MAPPING_KEY_STATE;
-    return yaml_parser_process_empty_scalar(parser, event, token->start_mark);
-}
-
-/*
- * Generate an empty scalar event.
- */
-
-static int
-yaml_parser_process_empty_scalar(yaml_parser_t *parser, yaml_event_t *event,
-        yaml_mark_t mark)
-{
-    yaml_char_t *value;
-
-    value = yaml_malloc(1);
-    if (!value) {
-        parser->error = YAML_MEMORY_ERROR;
-        return 0;
-    }
-    value[0] = '\0';
-
-    SCALAR_EVENT_INIT(*event, NULL, NULL, value, 0,
-            1, 0, YAML_PLAIN_SCALAR_STYLE, mark, mark);
-
-    return 1;
-}
-
-/*
- * Parse directives.
- */
-
-static int
-yaml_parser_process_directives(yaml_parser_t *parser,
-        yaml_version_directive_t **version_directive_ref,
-        yaml_tag_directive_t **tag_directives_start_ref,
-        yaml_tag_directive_t **tag_directives_end_ref)
-{
-    yaml_tag_directive_t default_tag_directives[] = {
-        {(yaml_char_t *)"!", (yaml_char_t *)"!"},
-        {(yaml_char_t *)"!!", (yaml_char_t *)"tag:yaml.org,2002:"},
-        {NULL, NULL}
-    };
-    yaml_tag_directive_t *default_tag_directive;
-    yaml_version_directive_t *version_directive = NULL;
-    struct {
-        yaml_tag_directive_t *start;
-        yaml_tag_directive_t *end;
-        yaml_tag_directive_t *top;
-    } tag_directives = { NULL, NULL, NULL };
-    yaml_token_t *token;
-
-    if (!STACK_INIT(parser, tag_directives, INITIAL_STACK_SIZE))
-        goto error;
-
-    token = PEEK_TOKEN(parser);
-    if (!token) goto error;
-
-    while (token->type == YAML_VERSION_DIRECTIVE_TOKEN ||
-            token->type == YAML_TAG_DIRECTIVE_TOKEN)
-    {
-        if (token->type == YAML_VERSION_DIRECTIVE_TOKEN) {
-            if (version_directive) {
-                yaml_parser_set_parser_error(parser,
-                        "found duplicate %YAML directive", token->start_mark);
-                goto error;
-            }
-            if (token->data.version_directive.major != 1
-                    || token->data.version_directive.minor != 1) {
-                yaml_parser_set_parser_error(parser,
-                        "found incompatible YAML document", token->start_mark);
-                goto error;
-            }
-            version_directive = yaml_malloc(sizeof(yaml_version_directive_t));
-            if (!version_directive) {
-                parser->error = YAML_MEMORY_ERROR;
-                goto error;
-            }
-            version_directive->major = token->data.version_directive.major;
-            version_directive->minor = token->data.version_directive.minor;
-        }
-
-        else if (token->type == YAML_TAG_DIRECTIVE_TOKEN) {
-            yaml_tag_directive_t value;
-            value.handle = token->data.tag_directive.handle;
-            value.prefix = token->data.tag_directive.prefix;
-
-            if (!yaml_parser_append_tag_directive(parser, value, 0,
-                        token->start_mark))
-                goto error;
-            if (!PUSH(parser, tag_directives, value))
-                goto error;
-        }
-
-        SKIP_TOKEN(parser);
-        token = PEEK_TOKEN(parser);
-        if (!token) goto error;
-    }
-    
-    for (default_tag_directive = default_tag_directives;
-            default_tag_directive->handle; default_tag_directive++) {
-        if (!yaml_parser_append_tag_directive(parser, *default_tag_directive, 1,
-                    token->start_mark))
-            goto error;
-    }
-
-    if (version_directive_ref) {
-        *version_directive_ref = version_directive;
-    }
-    if (tag_directives_start_ref) {
-        if (STACK_EMPTY(parser, tag_directives)) {
-            *tag_directives_start_ref = *tag_directives_end_ref = NULL;
-            STACK_DEL(parser, tag_directives);
-        }
-        else {
-            *tag_directives_start_ref = tag_directives.start;
-            *tag_directives_end_ref = tag_directives.top;
-        }
-    }
-    else {
-        STACK_DEL(parser, tag_directives);
-    }
-
-    return 1;
-
-error:
-    yaml_free(version_directive);
-    while (!STACK_EMPTY(parser, tag_directives)) {
-        yaml_tag_directive_t tag_directive = POP(parser, tag_directives);
-        yaml_free(tag_directive.handle);
-        yaml_free(tag_directive.prefix);
-    }
-    STACK_DEL(parser, tag_directives);
-    return 0;
-}
-
-/*
- * Append a tag directive to the directives stack.
- */
-
-static int
-yaml_parser_append_tag_directive(yaml_parser_t *parser,
-        yaml_tag_directive_t value, int allow_duplicates, yaml_mark_t mark)
-{
-    yaml_tag_directive_t *tag_directive;
-    yaml_tag_directive_t copy = { NULL, NULL };
-
-    for (tag_directive = parser->tag_directives.start;
-            tag_directive != parser->tag_directives.top; tag_directive ++) {
-        if (strcmp((char *)value.handle, (char *)tag_directive->handle) == 0) {
-            if (allow_duplicates)
-                return 1;
-            return yaml_parser_set_parser_error(parser,
-                    "found duplicate %TAG directive", mark);
-        }
-    }
-
-    copy.handle = yaml_strdup(value.handle);
-    copy.prefix = yaml_strdup(value.prefix);
-    if (!copy.handle || !copy.prefix) {
-        parser->error = YAML_MEMORY_ERROR;
-        goto error;
-    }
-
-    if (!PUSH(parser, parser->tag_directives, copy))
-        goto error;
-
-    return 1;
-
-error:
-    yaml_free(copy.handle);
-    yaml_free(copy.prefix);
-    return 0;
-}
-
diff --git a/parser_c.go b/parser_c.go
index c965594..da0c19f 100644
--- a/parser_c.go
+++ b/parser_c.go
@@ -91,6 +91,8 @@
 
 // State dispatcher.
 func yaml_parser_state_machine(parser *yaml_parser_t, event *yaml_event_t) bool {
+	//trace("yaml_parser_state_machine", "state:", parser.state.String())
+
 	switch parser.state {
 	case yaml_PARSE_STREAM_START_STATE:
 		return yaml_parser_parse_stream_start(parser, event)
@@ -195,6 +197,7 @@
 // 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
@@ -212,10 +215,10 @@
 	}
 
 	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 {
+		// Parse an implicit document.
 		if !yaml_parser_process_directives(parser, nil, nil) {
 			return false
 		}
@@ -356,10 +359,13 @@
 // flow_content         ::= flow_collection | SCALAR
 //                                            ******
 func yaml_parser_parse_node(parser *yaml_parser_t, event *yaml_event_t, block, indentless_sequence bool) bool {
+	//defer trace("yaml_parser_parse_node", "block:", block, "indentless_sequence:", indentless_sequence)()
+
 	token := peek_token(parser)
 	if token == nil {
 		return false
 	}
+
 	if token.typ == yaml_ALIAS_TOKEN {
 		parser.state = parser.states[len(parser.states)-1]
 		parser.states = parser.states[:len(parser.states)-1]
@@ -431,7 +437,7 @@
 		} 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([]byte(nil), parser.tag_directives[i].prefix...)
 					tag = append(tag, tag_suffix...)
 					break
 				}
diff --git a/reader.c b/reader.c
deleted file mode 100644
index 829e32d..0000000
--- a/reader.c
+++ /dev/null
@@ -1,465 +0,0 @@
-
-#include "yaml_private.h"
-
-/*
- * Declarations.
- */
-
-static int
-yaml_parser_set_reader_error(yaml_parser_t *parser, const char *problem,
-        size_t offset, int value);
-
-static int
-yaml_parser_update_raw_buffer(yaml_parser_t *parser);
-
-static int
-yaml_parser_determine_encoding(yaml_parser_t *parser);
-
-YAML_DECLARE(int)
-yaml_parser_update_buffer(yaml_parser_t *parser, size_t length);
-
-/*
- * Set the reader error and return 0.
- */
-
-static int
-yaml_parser_set_reader_error(yaml_parser_t *parser, const char *problem,
-        size_t offset, int value)
-{
-    parser->error = YAML_READER_ERROR;
-    parser->problem = problem;
-    parser->problem_offset = offset;
-    parser->problem_value = value;
-
-    return 0;
-}
-
-/*
- * Byte order marks.
- */
-
-#define BOM_UTF8    "\xef\xbb\xbf"
-#define BOM_UTF16LE "\xff\xfe"
-#define 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.
- */
-
-static int
-yaml_parser_determine_encoding(yaml_parser_t *parser)
-{
-    /* Ensure that we had enough bytes in the raw buffer. */
-
-    while (!parser->eof 
-            && parser->raw_buffer.last - parser->raw_buffer.pointer < 3) {
-        if (!yaml_parser_update_raw_buffer(parser)) {
-            return 0;
-        }
-    }
-
-    /* Determine the encoding. */
-
-    if (parser->raw_buffer.last - parser->raw_buffer.pointer >= 2
-            && !memcmp(parser->raw_buffer.pointer, BOM_UTF16LE, 2)) {
-        parser->encoding = YAML_UTF16LE_ENCODING;
-        parser->raw_buffer.pointer += 2;
-        parser->offset += 2;
-    }
-    else if (parser->raw_buffer.last - parser->raw_buffer.pointer >= 2
-            && !memcmp(parser->raw_buffer.pointer, BOM_UTF16BE, 2)) {
-        parser->encoding = YAML_UTF16BE_ENCODING;
-        parser->raw_buffer.pointer += 2;
-        parser->offset += 2;
-    }
-    else if (parser->raw_buffer.last - parser->raw_buffer.pointer >= 3
-            && !memcmp(parser->raw_buffer.pointer, BOM_UTF8, 3)) {
-        parser->encoding = YAML_UTF8_ENCODING;
-        parser->raw_buffer.pointer += 3;
-        parser->offset += 3;
-    }
-    else {
-        parser->encoding = YAML_UTF8_ENCODING;
-    }
-
-    return 1;
-}
-
-/*
- * Update the raw buffer.
- */
-
-static int
-yaml_parser_update_raw_buffer(yaml_parser_t *parser)
-{
-    size_t size_read = 0;
-
-    /* Return if the raw buffer is full. */
-
-    if (parser->raw_buffer.start == parser->raw_buffer.pointer
-            && parser->raw_buffer.last == parser->raw_buffer.end)
-        return 1;
-
-    /* Return on EOF. */
-
-    if (parser->eof) return 1;
-
-    /* Move the remaining bytes in the raw buffer to the beginning. */
-
-    if (parser->raw_buffer.start < parser->raw_buffer.pointer
-            && parser->raw_buffer.pointer < parser->raw_buffer.last) {
-        memmove(parser->raw_buffer.start, parser->raw_buffer.pointer,
-                parser->raw_buffer.last - parser->raw_buffer.pointer);
-    }
-    parser->raw_buffer.last -=
-        parser->raw_buffer.pointer - parser->raw_buffer.start;
-    parser->raw_buffer.pointer = parser->raw_buffer.start;
-
-    /* Call the read handler to fill the buffer. */
-
-    if (!parser->read_handler(parser->read_handler_data, parser->raw_buffer.last,
-                parser->raw_buffer.end - parser->raw_buffer.last, &size_read)) {
-        return yaml_parser_set_reader_error(parser, "input error",
-                parser->offset, -1);
-    }
-    parser->raw_buffer.last += size_read;
-    if (!size_read) {
-        parser->eof = 1;
-    }
-
-    return 1;
-}
-
-/*
- * Ensure that the buffer contains at least `length` characters.
- * Return 1 on success, 0 on failure.
- *
- * The length is supposed to be significantly less that the buffer size.
- */
-
-YAML_DECLARE(int)
-yaml_parser_update_buffer(yaml_parser_t *parser, size_t length)
-{
-    int first = 1;
-
-    assert(parser->read_handler);   /* 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.pointer == parser->raw_buffer.last)
-        return 1;
-
-    /* Return if the buffer contains enough characters. */
-
-    if (parser->unread >= length)
-        return 1;
-
-    /* Determine the input encoding if it is not known yet. */
-
-    if (!parser->encoding) {
-        if (!yaml_parser_determine_encoding(parser))
-            return 0;
-    }
-
-    /* Move the unread characters to the beginning of the buffer. */
-
-    if (parser->buffer.start < parser->buffer.pointer
-            && parser->buffer.pointer < parser->buffer.last) {
-        size_t size = parser->buffer.last - parser->buffer.pointer;
-        memmove(parser->buffer.start, parser->buffer.pointer, size);
-        parser->buffer.pointer = parser->buffer.start;
-        parser->buffer.last = parser->buffer.start + size;
-    }
-    else if (parser->buffer.pointer == parser->buffer.last) {
-        parser->buffer.pointer = parser->buffer.start;
-        parser->buffer.last = parser->buffer.start;
-    }
-
-    /* Fill the buffer until it has enough characters. */
-
-    while (parser->unread < length)
-    {
-        /* Fill the raw buffer if necessary. */
-
-        if (!first || parser->raw_buffer.pointer == parser->raw_buffer.last) {
-            if (!yaml_parser_update_raw_buffer(parser)) return 0;
-        }
-        first = 0;
-
-        /* Decode the raw buffer. */
-
-        while (parser->raw_buffer.pointer != parser->raw_buffer.last)
-        {
-            unsigned int value = 0, value2 = 0;
-            int incomplete = 0;
-            unsigned char octet;
-            unsigned int width = 0;
-            int low, high;
-            size_t k;
-            size_t raw_unread = parser->raw_buffer.last - parser->raw_buffer.pointer;
-
-            /* 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.pointer[0];
-                    width = (octet & 0x80) == 0x00 ? 1 :
-                            (octet & 0xE0) == 0xC0 ? 2 :
-                            (octet & 0xF0) == 0xE0 ? 3 :
-                            (octet & 0xF8) == 0xF0 ? 4 : 0;
-
-                    /* Check if the leading octet is valid. */
-
-                    if (!width)
-                        return yaml_parser_set_reader_error(parser,
-                                "invalid leading UTF-8 octet",
-                                parser->offset, 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 = 1;
-                        break;
-                    }
-
-                    /* Decode the leading octet. */
-
-                    value = (octet & 0x80) == 0x00 ? octet & 0x7F :
-                            (octet & 0xE0) == 0xC0 ? octet & 0x1F :
-                            (octet & 0xF0) == 0xE0 ? octet & 0x0F :
-                            (octet & 0xF8) == 0xF0 ? octet & 0x07 : 0;
-
-                    /* Check and decode the trailing octets. */
-
-                    for (k = 1; k < width; k ++)
-                    {
-                        octet = parser->raw_buffer.pointer[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, octet);
-
-                        /* Decode the octet. */
-
-                        value = (value << 6) + (octet & 0x3F);
-                    }
-
-                    /* Check the length of the sequence against the value. */
-
-                    if (!((width == 1) ||
-                            (width == 2 && value >= 0x80) ||
-                            (width == 3 && value >= 0x800) ||
-                            (width == 4 && value >= 0x10000)))
-                        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, value);
-
-                    break;
-                
-                case YAML_UTF16LE_ENCODING:
-                case YAML_UTF16BE_ENCODING:
-
-                    low = (parser->encoding == YAML_UTF16LE_ENCODING ? 0 : 1);
-                    high = (parser->encoding == YAML_UTF16LE_ENCODING ? 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 = 1;
-                        break;
-                    }
-
-                    /* Get the character. */
-
-                    value = parser->raw_buffer.pointer[low]
-                        + (parser->raw_buffer.pointer[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, 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 = 1;
-                            break;
-                        }
-
-                        /* Get the next character. */
-
-                        value2 = parser->raw_buffer.pointer[low+2]
-                            + (parser->raw_buffer.pointer[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, value2);
-
-                        /* Generate the value of the surrogate pair. */
-
-                        value = 0x10000 + ((value & 0x3FF) << 10) + (value2 & 0x3FF);
-                    }
-
-                    else {
-                        width = 2;
-                    }
-
-                    break;
-
-                default:
-                    assert(1);      /* 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)
-             */
-
-            if (! (value == 0x09 || value == 0x0A || value == 0x0D
-                        || (value >= 0x20 && value <= 0x7E)
-                        || (value == 0x85) || (value >= 0xA0 && value <= 0xD7FF)
-                        || (value >= 0xE000 && value <= 0xFFFD)
-                        || (value >= 0x10000 && value <= 0x10FFFF)))
-                return yaml_parser_set_reader_error(parser,
-                        "control characters are not allowed",
-                        parser->offset, value);
-
-            /* Move the raw pointers. */
-
-            parser->raw_buffer.pointer += width;
-            parser->offset += width;
-
-            /* Finally put the character into the buffer. */
-
-            /* 0000 0000-0000 007F -> 0xxxxxxx */
-            if (value <= 0x7F) {
-                *(parser->buffer.last++) = value;
-            }
-            /* 0000 0080-0000 07FF -> 110xxxxx 10xxxxxx */
-            else if (value <= 0x7FF) {
-                *(parser->buffer.last++) = 0xC0 + (value >> 6);
-                *(parser->buffer.last++) = 0x80 + (value & 0x3F);
-            }
-            /* 0000 0800-0000 FFFF -> 1110xxxx 10xxxxxx 10xxxxxx */
-            else if (value <= 0xFFFF) {
-                *(parser->buffer.last++) = 0xE0 + (value >> 12);
-                *(parser->buffer.last++) = 0x80 + ((value >> 6) & 0x3F);
-                *(parser->buffer.last++) = 0x80 + (value & 0x3F);
-            }
-            /* 0001 0000-0010 FFFF -> 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx */
-            else {
-                *(parser->buffer.last++) = 0xF0 + (value >> 18);
-                *(parser->buffer.last++) = 0x80 + ((value >> 12) & 0x3F);
-                *(parser->buffer.last++) = 0x80 + ((value >> 6) & 0x3F);
-                *(parser->buffer.last++) = 0x80 + (value & 0x3F);
-            }
-
-            parser->unread ++;
-        }
-
-        /* On EOF, put NUL into the buffer and return. */
-
-        if (parser->eof) {
-            *(parser->buffer.last++) = '\0';
-            parser->unread ++;
-            return 1;
-        }
-
-    }
-
-    return 1;
-}
-
diff --git a/scanner.c b/scanner.c
deleted file mode 100644
index a2e8619..0000000
--- a/scanner.c
+++ /dev/null
@@ -1,3570 +0,0 @@
-
-/*
- * 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
- */
-
-#include "yaml_private.h"
-
-/*
- * Ensure that the buffer contains the required number of characters.
- * Return 1 on success, 0 on failure (reader error or memory error).
- */
-
-#define CACHE(parser,length)                                                    \
-    (parser->unread >= (length)                                                 \
-        ? 1                                                                     \
-        : yaml_parser_update_buffer(parser, (length)))
-
-/*
- * Advance the buffer pointer.
- */
-
-#define SKIP(parser)                                                            \
-     (parser->mark.index ++,                                                    \
-      parser->mark.column ++,                                                   \
-      parser->unread --,                                                        \
-      parser->buffer.pointer += WIDTH(parser->buffer))
-
-#define SKIP_LINE(parser)                                                       \
-     (IS_CRLF(parser->buffer) ?                                                 \
-      (parser->mark.index += 2,                                                 \
-       parser->mark.column = 0,                                                 \
-       parser->mark.line ++,                                                    \
-       parser->unread -= 2,                                                     \
-       parser->buffer.pointer += 2) :                                           \
-      IS_BREAK(parser->buffer) ?                                                \
-      (parser->mark.index ++,                                                   \
-       parser->mark.column = 0,                                                 \
-       parser->mark.line ++,                                                    \
-       parser->unread --,                                                       \
-       parser->buffer.pointer += WIDTH(parser->buffer)) : 0)
-
-/*
- * Copy a character to a string buffer and advance pointers.
- */
-
-#define READ(parser,string)                                                     \
-     (STRING_EXTEND(parser,string) ?                                            \
-         (COPY(string,parser->buffer),                                          \
-          parser->mark.index ++,                                                \
-          parser->mark.column ++,                                               \
-          parser->unread --,                                                    \
-          1) : 0)
-
-/*
- * Copy a line break character to a string buffer and advance pointers.
- */
-
-#define READ_LINE(parser,string)                                                \
-    (STRING_EXTEND(parser,string) ?                                             \
-    (((CHECK_AT(parser->buffer,'\r',0)                                          \
-       && CHECK_AT(parser->buffer,'\n',1)) ?        /* CR LF -> LF */           \
-     (*((string).pointer++) = (yaml_char_t) '\n',                               \
-      parser->buffer.pointer += 2,                                              \
-      parser->mark.index += 2,                                                  \
-      parser->mark.column = 0,                                                  \
-      parser->mark.line ++,                                                     \
-      parser->unread -= 2) :                                                    \
-     (CHECK_AT(parser->buffer,'\r',0)                                           \
-      || CHECK_AT(parser->buffer,'\n',0)) ?         /* CR|LF -> LF */           \
-     (*((string).pointer++) = (yaml_char_t) '\n',                               \
-      parser->buffer.pointer ++,                                                \
-      parser->mark.index ++,                                                    \
-      parser->mark.column = 0,                                                  \
-      parser->mark.line ++,                                                     \
-      parser->unread --) :                                                      \
-     (CHECK_AT(parser->buffer,'\xC2',0)                                         \
-      && CHECK_AT(parser->buffer,'\x85',1)) ?       /* NEL -> LF */             \
-     (*((string).pointer++) = (yaml_char_t) '\n',                               \
-      parser->buffer.pointer += 2,                                              \
-      parser->mark.index ++,                                                    \
-      parser->mark.column = 0,                                                  \
-      parser->mark.line ++,                                                     \
-      parser->unread --) :                                                      \
-     (CHECK_AT(parser->buffer,'\xE2',0) &&                                      \
-      CHECK_AT(parser->buffer,'\x80',1) &&                                      \
-      (CHECK_AT(parser->buffer,'\xA8',2) ||                                     \
-       CHECK_AT(parser->buffer,'\xA9',2))) ?        /* LS|PS -> LS|PS */        \
-     (*((string).pointer++) = *(parser->buffer.pointer++),                      \
-      *((string).pointer++) = *(parser->buffer.pointer++),                      \
-      *((string).pointer++) = *(parser->buffer.pointer++),                      \
-      parser->mark.index ++,                                                    \
-      parser->mark.column = 0,                                                  \
-      parser->mark.line ++,                                                     \
-      parser->unread --) : 0),                                                  \
-    1) : 0)
-
-/*
- * Public API declarations.
- */
-
-YAML_DECLARE(int)
-yaml_parser_scan(yaml_parser_t *parser, yaml_token_t *token);
-
-/*
- * Error handling.
- */
-
-static int
-yaml_parser_set_scanner_error(yaml_parser_t *parser, const char *context,
-        yaml_mark_t context_mark, const char *problem);
-
-/*
- * High-level token API.
- */
-
-YAML_DECLARE(int)
-yaml_parser_fetch_more_tokens(yaml_parser_t *parser);
-
-static int
-yaml_parser_fetch_next_token(yaml_parser_t *parser);
-
-/*
- * Potential simple keys.
- */
-
-static int
-yaml_parser_stale_simple_keys(yaml_parser_t *parser);
-
-static int
-yaml_parser_save_simple_key(yaml_parser_t *parser);
-
-static int
-yaml_parser_remove_simple_key(yaml_parser_t *parser);
-
-static int
-yaml_parser_increase_flow_level(yaml_parser_t *parser);
-
-static int
-yaml_parser_decrease_flow_level(yaml_parser_t *parser);
-
-/*
- * Indentation treatment.
- */
-
-static int
-yaml_parser_roll_indent(yaml_parser_t *parser, int column,
-        int number, yaml_token_type_t type, yaml_mark_t mark);
-
-static int
-yaml_parser_unroll_indent(yaml_parser_t *parser, int column);
-
-/*
- * Token fetchers.
- */
-
-static int
-yaml_parser_fetch_stream_start(yaml_parser_t *parser);
-
-static int
-yaml_parser_fetch_stream_end(yaml_parser_t *parser);
-
-static int
-yaml_parser_fetch_directive(yaml_parser_t *parser);
-
-static int
-yaml_parser_fetch_document_indicator(yaml_parser_t *parser,
-        yaml_token_type_t type);
-
-static int
-yaml_parser_fetch_flow_collection_start(yaml_parser_t *parser,
-        yaml_token_type_t type);
-
-static int
-yaml_parser_fetch_flow_collection_end(yaml_parser_t *parser,
-        yaml_token_type_t type);
-
-static int
-yaml_parser_fetch_flow_entry(yaml_parser_t *parser);
-
-static int
-yaml_parser_fetch_block_entry(yaml_parser_t *parser);
-
-static int
-yaml_parser_fetch_key(yaml_parser_t *parser);
-
-static int
-yaml_parser_fetch_value(yaml_parser_t *parser);
-
-static int
-yaml_parser_fetch_anchor(yaml_parser_t *parser, yaml_token_type_t type);
-
-static int
-yaml_parser_fetch_tag(yaml_parser_t *parser);
-
-static int
-yaml_parser_fetch_block_scalar(yaml_parser_t *parser, int literal);
-
-static int
-yaml_parser_fetch_flow_scalar(yaml_parser_t *parser, int single);
-
-static int
-yaml_parser_fetch_plain_scalar(yaml_parser_t *parser);
-
-/*
- * Token scanners.
- */
-
-static int
-yaml_parser_scan_to_next_token(yaml_parser_t *parser);
-
-static int
-yaml_parser_scan_directive(yaml_parser_t *parser, yaml_token_t *token);
-
-static int
-yaml_parser_scan_directive_name(yaml_parser_t *parser,
-        yaml_mark_t start_mark, yaml_char_t **name);
-
-static int
-yaml_parser_scan_version_directive_value(yaml_parser_t *parser,
-        yaml_mark_t start_mark, int *major, int *minor);
-
-static int
-yaml_parser_scan_version_directive_number(yaml_parser_t *parser,
-        yaml_mark_t start_mark, int *number);
-
-static int
-yaml_parser_scan_tag_directive_value(yaml_parser_t *parser,
-        yaml_mark_t mark, yaml_char_t **handle, yaml_char_t **prefix);
-
-static int
-yaml_parser_scan_anchor(yaml_parser_t *parser, yaml_token_t *token,
-        yaml_token_type_t type);
-
-static int
-yaml_parser_scan_tag(yaml_parser_t *parser, yaml_token_t *token);
-
-static int
-yaml_parser_scan_tag_handle(yaml_parser_t *parser, int directive,
-        yaml_mark_t start_mark, yaml_char_t **handle);
-
-static int
-yaml_parser_scan_tag_uri(yaml_parser_t *parser, int directive,
-        yaml_char_t *head, yaml_mark_t start_mark, yaml_char_t **uri);
-
-static int
-yaml_parser_scan_uri_escapes(yaml_parser_t *parser, int directive,
-        yaml_mark_t start_mark, yaml_string_t *string);
-
-static int
-yaml_parser_scan_block_scalar(yaml_parser_t *parser, yaml_token_t *token,
-        int literal);
-
-static int
-yaml_parser_scan_block_scalar_breaks(yaml_parser_t *parser,
-        int *indent, yaml_string_t *breaks,
-        yaml_mark_t start_mark, yaml_mark_t *end_mark);
-
-static int
-yaml_parser_scan_flow_scalar(yaml_parser_t *parser, yaml_token_t *token,
-        int single);
-
-static int
-yaml_parser_scan_plain_scalar(yaml_parser_t *parser, yaml_token_t *token);
-
-/*
- * Get the next token.
- */
-
-YAML_DECLARE(int)
-yaml_parser_scan(yaml_parser_t *parser, yaml_token_t *token)
-{
-    assert(parser); /* Non-NULL parser object is expected. */
-    assert(token);  /* Non-NULL token object is expected. */
-
-    /* Erase the token object. */
-
-    memset(token, 0, sizeof(yaml_token_t));
-
-    /* No tokens after STREAM-END or error. */
-
-    if (parser->stream_end_produced || parser->error) {
-        return 1;
-    }
-
-    /* Ensure that the tokens queue contains enough tokens. */
-
-    if (!parser->token_available) {
-        if (!yaml_parser_fetch_more_tokens(parser))
-            return 0;
-    }
-
-    /* Fetch the next token from the queue. */
-    
-    *token = DEQUEUE(parser, parser->tokens);
-    parser->token_available = 0;
-    parser->tokens_parsed ++;
-
-    if (token->type == YAML_STREAM_END_TOKEN) {
-        parser->stream_end_produced = 1;
-    }
-
-    return 1;
-}
-
-/*
- * Set the scanner error and return 0.
- */
-
-static int
-yaml_parser_set_scanner_error(yaml_parser_t *parser, const char *context,
-        yaml_mark_t context_mark, const char *problem)
-{
-    parser->error = YAML_SCANNER_ERROR;
-    parser->context = context;
-    parser->context_mark = context_mark;
-    parser->problem = problem;
-    parser->problem_mark = parser->mark;
-
-    return 0;
-}
-
-/*
- * Ensure that the tokens queue contains at least one token which can be
- * returned to the Parser.
- */
-
-YAML_DECLARE(int)
-yaml_parser_fetch_more_tokens(yaml_parser_t *parser)
-{
-    int need_more_tokens;
-
-    /* While we need more tokens to fetch, do it. */
-
-    while (1)
-    {
-        /*
-         * Check if we really need to fetch more tokens.
-         */
-
-        need_more_tokens = 0;
-
-        if (parser->tokens.head == parser->tokens.tail)
-        {
-            /* Queue is empty. */
-
-            need_more_tokens = 1;
-        }
-        else
-        {
-            yaml_simple_key_t *simple_key;
-
-            /* Check if any potential simple key may occupy the head position. */
-
-            if (!yaml_parser_stale_simple_keys(parser))
-                return 0;
-
-            for (simple_key = parser->simple_keys.start;
-                    simple_key != parser->simple_keys.top; simple_key++) {
-                if (simple_key->possible
-                        && simple_key->token_number == parser->tokens_parsed) {
-                    need_more_tokens = 1;
-                    break;
-                }
-            }
-        }
-
-        /* We are finished. */
-
-        if (!need_more_tokens)
-            break;
-
-        /* Fetch the next token. */
-
-        if (!yaml_parser_fetch_next_token(parser))
-            return 0;
-    }
-
-    parser->token_available = 1;
-
-    return 1;
-}
-
-/*
- * The dispatcher for token fetchers.
- */
-
-static int
-yaml_parser_fetch_next_token(yaml_parser_t *parser)
-{
-    /* Ensure that the buffer is initialized. */
-
-    if (!CACHE(parser, 1))
-        return 0;
-
-    /* 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 0;
-
-    /* Remove obsolete potential simple keys. */
-
-    if (!yaml_parser_stale_simple_keys(parser))
-        return 0;
-
-    /* Check the indentation level against the current column. */
-
-    if (!yaml_parser_unroll_indent(parser, parser->mark.column))
-        return 0;
-
-    /*
-     * Ensure that the buffer contains at least 4 characters.  4 is the length
-     * of the longest indicators ('--- ' and '... ').
-     */
-
-    if (!CACHE(parser, 4))
-        return 0;
-
-    /* Is it the end of the stream? */
-
-    if (IS_Z(parser->buffer))
-        return yaml_parser_fetch_stream_end(parser);
-
-    /* Is it a directive? */
-
-    if (parser->mark.column == 0 && CHECK(parser->buffer, '%'))
-        return yaml_parser_fetch_directive(parser);
-
-    /* Is it the document start indicator? */
-
-    if (parser->mark.column == 0
-            && CHECK_AT(parser->buffer, '-', 0)
-            && CHECK_AT(parser->buffer, '-', 1)
-            && CHECK_AT(parser->buffer, '-', 2)
-            && IS_BLANKZ_AT(parser->buffer, 3))
-        return yaml_parser_fetch_document_indicator(parser,
-                YAML_DOCUMENT_START_TOKEN);
-
-    /* Is it the document end indicator? */
-
-    if (parser->mark.column == 0
-            && CHECK_AT(parser->buffer, '.', 0)
-            && CHECK_AT(parser->buffer, '.', 1)
-            && CHECK_AT(parser->buffer, '.', 2)
-            && IS_BLANKZ_AT(parser->buffer, 3))
-        return yaml_parser_fetch_document_indicator(parser,
-                YAML_DOCUMENT_END_TOKEN);
-
-    /* Is it the flow sequence start indicator? */
-
-    if (CHECK(parser->buffer, '['))
-        return yaml_parser_fetch_flow_collection_start(parser,
-                YAML_FLOW_SEQUENCE_START_TOKEN);
-
-    /* Is it the flow mapping start indicator? */
-
-    if (CHECK(parser->buffer, '{'))
-        return yaml_parser_fetch_flow_collection_start(parser,
-                YAML_FLOW_MAPPING_START_TOKEN);
-
-    /* Is it the flow sequence end indicator? */
-
-    if (CHECK(parser->buffer, ']'))
-        return yaml_parser_fetch_flow_collection_end(parser,
-                YAML_FLOW_SEQUENCE_END_TOKEN);
-
-    /* Is it the flow mapping end indicator? */
-
-    if (CHECK(parser->buffer, '}'))
-        return yaml_parser_fetch_flow_collection_end(parser,
-                YAML_FLOW_MAPPING_END_TOKEN);
-
-    /* Is it the flow entry indicator? */
-
-    if (CHECK(parser->buffer, ','))
-        return yaml_parser_fetch_flow_entry(parser);
-
-    /* Is it the block entry indicator? */
-
-    if (CHECK(parser->buffer, '-') && IS_BLANKZ_AT(parser->buffer, 1))
-        return yaml_parser_fetch_block_entry(parser);
-
-    /* Is it the key indicator? */
-
-    if (CHECK(parser->buffer, '?')
-            && (parser->flow_level || IS_BLANKZ_AT(parser->buffer, 1)))
-        return yaml_parser_fetch_key(parser);
-
-    /* Is it the value indicator? */
-
-    if (CHECK(parser->buffer, ':')
-            && (parser->flow_level || IS_BLANKZ_AT(parser->buffer, 1)))
-        return yaml_parser_fetch_value(parser);
-
-    /* Is it an alias? */
-
-    if (CHECK(parser->buffer, '*'))
-        return yaml_parser_fetch_anchor(parser, YAML_ALIAS_TOKEN);
-
-    /* Is it an anchor? */
-
-    if (CHECK(parser->buffer, '&'))
-        return yaml_parser_fetch_anchor(parser, YAML_ANCHOR_TOKEN);
-
-    /* Is it a tag? */
-
-    if (CHECK(parser->buffer, '!'))
-        return yaml_parser_fetch_tag(parser);
-
-    /* Is it a literal scalar? */
-
-    if (CHECK(parser->buffer, '|') && !parser->flow_level)
-        return yaml_parser_fetch_block_scalar(parser, 1);
-
-    /* Is it a folded scalar? */
-
-    if (CHECK(parser->buffer, '>') && !parser->flow_level)
-        return yaml_parser_fetch_block_scalar(parser, 0);
-
-    /* Is it a single-quoted scalar? */
-
-    if (CHECK(parser->buffer, '\''))
-        return yaml_parser_fetch_flow_scalar(parser, 1);
-
-    /* Is it a double-quoted scalar? */
-
-    if (CHECK(parser->buffer, '"'))
-        return yaml_parser_fetch_flow_scalar(parser, 0);
-
-    /*
-     * 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.
-     */
-
-    if (!(IS_BLANKZ(parser->buffer) || CHECK(parser->buffer, '-')
-                || CHECK(parser->buffer, '?') || CHECK(parser->buffer, ':')
-                || CHECK(parser->buffer, ',') || CHECK(parser->buffer, '[')
-                || CHECK(parser->buffer, ']') || CHECK(parser->buffer, '{')
-                || CHECK(parser->buffer, '}') || CHECK(parser->buffer, '#')
-                || CHECK(parser->buffer, '&') || CHECK(parser->buffer, '*')
-                || CHECK(parser->buffer, '!') || CHECK(parser->buffer, '|')
-                || CHECK(parser->buffer, '>') || CHECK(parser->buffer, '\'')
-                || CHECK(parser->buffer, '"') || CHECK(parser->buffer, '%')
-                || CHECK(parser->buffer, '@') || CHECK(parser->buffer, '`')) ||
-            (CHECK(parser->buffer, '-') && !IS_BLANK_AT(parser->buffer, 1)) ||
-            (!parser->flow_level &&
-             (CHECK(parser->buffer, '?') || CHECK(parser->buffer, ':'))
-             && !IS_BLANKZ_AT(parser->buffer, 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.
- */
-
-static int
-yaml_parser_stale_simple_keys(yaml_parser_t *parser)
-{
-    yaml_simple_key_t *simple_key;
-
-    /* Check for a potential simple key for each flow level. */
-
-    for (simple_key = parser->simple_keys.start;
-            simple_key != parser->simple_keys.top; simple_key ++)
-    {
-        /*
-         * 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 = 0;
-        }
-    }
-
-    return 1;
-}
-
-/*
- * Check if a simple key may start at the current position and add it if
- * needed.
- */
-
-static int
-yaml_parser_save_simple_key(yaml_parser_t *parser)
-{
-    /*
-     * 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.
-     */
-
-    int required = (!parser->flow_level
-            && parser->indent == (int)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.
-     */
-
-    assert(parser->simple_key_allowed || !required);    /* Impossible. */
-
-    /*
-     * If the current position may start a simple key, save it.
-     */
-
-    if (parser->simple_key_allowed)
-    {
-        yaml_simple_key_t simple_key;
-        simple_key.possible = 1;
-        simple_key.required = required;
-        simple_key.token_number = 
-            parser->tokens_parsed + (parser->tokens.tail - parser->tokens.head);
-        simple_key.mark = parser->mark;
-
-        if (!yaml_parser_remove_simple_key(parser)) return 0;
-
-        *(parser->simple_keys.top-1) = simple_key;
-    }
-
-    return 1;
-}
-
-/*
- * Remove a potential simple key at the current flow level.
- */
-
-static int
-yaml_parser_remove_simple_key(yaml_parser_t *parser)
-{
-    yaml_simple_key_t *simple_key = parser->simple_keys.top-1;
-
-    if (simple_key->possible)
-    {
-        /* If the key is required, it is an error. */
-
-        if (simple_key->required) {
-            return yaml_parser_set_scanner_error(parser,
-                    "while scanning a simple key", simple_key->mark,
-                    "could not find expected ':'");
-        }
-    }
-
-    /* Remove the key from the stack. */
-
-    simple_key->possible = 0;
-
-    return 1;
-}
-
-/*
- * Increase the flow level and resize the simple key list if needed.
- */
-
-static int
-yaml_parser_increase_flow_level(yaml_parser_t *parser)
-{
-    yaml_simple_key_t empty_simple_key = { 0, 0, 0, { 0, 0, 0 } };
-
-    /* Reset the simple key on the next level. */
-
-    if (!PUSH(parser, parser->simple_keys, empty_simple_key))
-        return 0;
-
-    /* Increase the flow level. */
-
-    parser->flow_level++;
-
-    return 1;
-}
-
-/*
- * Decrease the flow level.
- */
-
-static int
-yaml_parser_decrease_flow_level(yaml_parser_t *parser)
-{
-    yaml_simple_key_t dummy_key;    /* Used to eliminate a compiler warning. */
-
-    if (parser->flow_level) {
-        parser->flow_level --;
-        dummy_key = POP(parser, parser->simple_keys);
-    }
-
-    return 1;
-}
-
-/*
- * 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.
- * 
- */
-
-static int
-yaml_parser_roll_indent(yaml_parser_t *parser, int column,
-        int number, yaml_token_type_t type, yaml_mark_t mark)
-{
-    yaml_token_t token;
-
-    /* In the flow context, do nothing. */
-
-    if (parser->flow_level)
-        return 1;
-
-    if (parser->indent < column)
-    {
-        /*
-         * Push the current indentation level to the stack and set the new
-         * indentation level.
-         */
-
-        if (!PUSH(parser, parser->indents, parser->indent))
-            return 0;
-
-        parser->indent = column;
-
-        /* Create a token and insert it into the queue. */
-
-        TOKEN_INIT(token, type, mark, mark);
-
-        if (number == -1) {
-            if (!ENQUEUE(parser, parser->tokens, token))
-                return 0;
-        }
-        else {
-            if (!QUEUE_INSERT(parser,
-                        parser->tokens, number - parser->tokens_parsed, token))
-                return 0;
-        }
-    }
-
-    return 1;
-}
-
-/*
- * 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.
- */
-
-
-static int
-yaml_parser_unroll_indent(yaml_parser_t *parser, int column)
-{
-    yaml_token_t token;
-
-    /* In the flow context, do nothing. */
-
-    if (parser->flow_level)
-        return 1;
-
-    /* Loop through the intendation levels in the stack. */
-
-    while (parser->indent > column)
-    {
-        /* Create a token and append it to the queue. */
-
-        TOKEN_INIT(token, YAML_BLOCK_END_TOKEN, parser->mark, parser->mark);
-
-        if (!ENQUEUE(parser, parser->tokens, token))
-            return 0;
-
-        /* Pop the indentation level. */
-
-        parser->indent = POP(parser, parser->indents);
-    }
-
-    return 1;
-}
-
-/*
- * Initialize the scanner and produce the STREAM-START token.
- */
-
-static int
-yaml_parser_fetch_stream_start(yaml_parser_t *parser)
-{
-    yaml_simple_key_t simple_key = { 0, 0, 0, { 0, 0, 0 } };
-    yaml_token_t token;
-
-    /* Set the initial indentation. */
-
-    parser->indent = -1;
-
-    /* Initialize the simple key stack. */
-
-    if (!PUSH(parser, parser->simple_keys, simple_key))
-        return 0;
-
-    /* A simple key is allowed at the beginning of the stream. */
-
-    parser->simple_key_allowed = 1;
-
-    /* We have started. */
-
-    parser->stream_start_produced = 1;
-
-    /* Create the STREAM-START token and append it to the queue. */
-
-    STREAM_START_TOKEN_INIT(token, parser->encoding,
-            parser->mark, parser->mark);
-
-    if (!ENQUEUE(parser, parser->tokens, token))
-        return 0;
-
-    return 1;
-}
-
-/*
- * Produce the STREAM-END token and shut down the scanner.
- */
-
-static int
-yaml_parser_fetch_stream_end(yaml_parser_t *parser)
-{
-    yaml_token_t token;
-
-    /* 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 0;
-
-    /* Reset simple keys. */
-
-    if (!yaml_parser_remove_simple_key(parser))
-        return 0;
-
-    parser->simple_key_allowed = 0;
-
-    /* Create the STREAM-END token and append it to the queue. */
-
-    STREAM_END_TOKEN_INIT(token, parser->mark, parser->mark);
-
-    if (!ENQUEUE(parser, parser->tokens, token))
-        return 0;
-
-    return 1;
-}
-
-/*
- * Produce a VERSION-DIRECTIVE or TAG-DIRECTIVE token.
- */
-
-static int
-yaml_parser_fetch_directive(yaml_parser_t *parser)
-{
-    yaml_token_t token;
-
-    /* Reset the indentation level. */
-
-    if (!yaml_parser_unroll_indent(parser, -1))
-        return 0;
-
-    /* Reset simple keys. */
-
-    if (!yaml_parser_remove_simple_key(parser))
-        return 0;
-
-    parser->simple_key_allowed = 0;
-
-    /* Create the YAML-DIRECTIVE or TAG-DIRECTIVE token. */
-
-    if (!yaml_parser_scan_directive(parser, &token))
-        return 0;
-
-    /* Append the token to the queue. */
-
-    if (!ENQUEUE(parser, parser->tokens, token)) {
-        yaml_token_delete(&token);
-        return 0;
-    }
-
-    return 1;
-}
-
-/*
- * Produce the DOCUMENT-START or DOCUMENT-END token.
- */
-
-static int
-yaml_parser_fetch_document_indicator(yaml_parser_t *parser,
-        yaml_token_type_t type)
-{
-    yaml_mark_t start_mark, end_mark;
-    yaml_token_t token;
-
-    /* Reset the indentation level. */
-
-    if (!yaml_parser_unroll_indent(parser, -1))
-        return 0;
-
-    /* Reset simple keys. */
-
-    if (!yaml_parser_remove_simple_key(parser))
-        return 0;
-
-    parser->simple_key_allowed = 0;
-
-    /* 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_INIT(token, type, start_mark, end_mark);
-
-    /* Append the token to the queue. */
-
-    if (!ENQUEUE(parser, parser->tokens, token))
-        return 0;
-
-    return 1;
-}
-
-/*
- * Produce the FLOW-SEQUENCE-START or FLOW-MAPPING-START token.
- */
-
-static int
-yaml_parser_fetch_flow_collection_start(yaml_parser_t *parser,
-        yaml_token_type_t type)
-{
-    yaml_mark_t start_mark, end_mark;
-    yaml_token_t token;
-
-    /* The indicators '[' and '{' may start a simple key. */
-
-    if (!yaml_parser_save_simple_key(parser))
-        return 0;
-
-    /* Increase the flow level. */
-
-    if (!yaml_parser_increase_flow_level(parser))
-        return 0;
-
-    /* A simple key may follow the indicators '[' and '{'. */
-
-    parser->simple_key_allowed = 1;
-
-    /* Consume the token. */
-
-    start_mark = parser->mark;
-    SKIP(parser);
-    end_mark = parser->mark;
-
-    /* Create the FLOW-SEQUENCE-START of FLOW-MAPPING-START token. */
-
-    TOKEN_INIT(token, type, start_mark, end_mark);
-
-    /* Append the token to the queue. */
-
-    if (!ENQUEUE(parser, parser->tokens, token))
-        return 0;
-
-    return 1;
-}
-
-/*
- * Produce the FLOW-SEQUENCE-END or FLOW-MAPPING-END token.
- */
-
-static int
-yaml_parser_fetch_flow_collection_end(yaml_parser_t *parser,
-        yaml_token_type_t type)
-{
-    yaml_mark_t start_mark, end_mark;
-    yaml_token_t token;
-
-    /* Reset any potential simple key on the current flow level. */
-
-    if (!yaml_parser_remove_simple_key(parser))
-        return 0;
-
-    /* Decrease the flow level. */
-
-    if (!yaml_parser_decrease_flow_level(parser))
-        return 0;
-
-    /* No simple keys after the indicators ']' and '}'. */
-
-    parser->simple_key_allowed = 0;
-
-    /* Consume the token. */
-
-    start_mark = parser->mark;
-    SKIP(parser);
-    end_mark = parser->mark;
-
-    /* Create the FLOW-SEQUENCE-END of FLOW-MAPPING-END token. */
-
-    TOKEN_INIT(token, type, start_mark, end_mark);
-
-    /* Append the token to the queue. */
-
-    if (!ENQUEUE(parser, parser->tokens, token))
-        return 0;
-
-    return 1;
-}
-
-/*
- * Produce the FLOW-ENTRY token.
- */
-
-static int
-yaml_parser_fetch_flow_entry(yaml_parser_t *parser)
-{
-    yaml_mark_t start_mark, end_mark;
-    yaml_token_t token;
-
-    /* Reset any potential simple keys on the current flow level. */
-
-    if (!yaml_parser_remove_simple_key(parser))
-        return 0;
-
-    /* Simple keys are allowed after ','. */
-
-    parser->simple_key_allowed = 1;
-
-    /* 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_INIT(token, YAML_FLOW_ENTRY_TOKEN, start_mark, end_mark);
-
-    if (!ENQUEUE(parser, parser->tokens, token))
-        return 0;
-
-    return 1;
-}
-
-/*
- * Produce the BLOCK-ENTRY token.
- */
-
-static int
-yaml_parser_fetch_block_entry(yaml_parser_t *parser)
-{
-    yaml_mark_t start_mark, end_mark;
-    yaml_token_t token;
-
-    /* Check if the scanner is in the block context. */
-
-    if (!parser->flow_level)
-    {
-        /* Check if we are allowed to start a new entry. */
-
-        if (!parser->simple_key_allowed) {
-            return yaml_parser_set_scanner_error(parser, NULL, 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 0;
-    }
-    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 0;
-
-    /* Simple keys are allowed after '-'. */
-
-    parser->simple_key_allowed = 1;
-
-    /* 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_INIT(token, YAML_BLOCK_ENTRY_TOKEN, start_mark, end_mark);
-
-    if (!ENQUEUE(parser, parser->tokens, token))
-        return 0;
-
-    return 1;
-}
-
-/*
- * Produce the KEY token.
- */
-
-static int
-yaml_parser_fetch_key(yaml_parser_t *parser)
-{
-    yaml_mark_t start_mark, end_mark;
-    yaml_token_t token;
-
-    /* In the block context, additional checks are required. */
-
-    if (!parser->flow_level)
-    {
-        /* 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, NULL, 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 0;
-    }
-
-    /* Reset any potential simple keys on the current flow level. */
-
-    if (!yaml_parser_remove_simple_key(parser))
-        return 0;
-
-    /* Simple keys are allowed after '?' in the block context. */
-
-    parser->simple_key_allowed = (!parser->flow_level);
-
-    /* Consume the token. */
-
-    start_mark = parser->mark;
-    SKIP(parser);
-    end_mark = parser->mark;
-
-    /* Create the KEY token and append it to the queue. */
-
-    TOKEN_INIT(token, YAML_KEY_TOKEN, start_mark, end_mark);
-
-    if (!ENQUEUE(parser, parser->tokens, token))
-        return 0;
-
-    return 1;
-}
-
-/*
- * Produce the VALUE token.
- */
-
-static int
-yaml_parser_fetch_value(yaml_parser_t *parser)
-{
-    yaml_mark_t start_mark, end_mark;
-    yaml_token_t token;
-    yaml_simple_key_t *simple_key = parser->simple_keys.top-1;
-
-    /* Have we found a simple key? */
-
-    if (simple_key->possible)
-    {
-
-        /* Create the KEY token and insert it into the queue. */
-
-        TOKEN_INIT(token, YAML_KEY_TOKEN, simple_key->mark, simple_key->mark);
-
-        if (!QUEUE_INSERT(parser, parser->tokens,
-                    simple_key->token_number - parser->tokens_parsed, token))
-            return 0;
-
-        /* 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 0;
-
-        /* Remove the simple key. */
-
-        simple_key->possible = 0;
-
-        /* A simple key cannot follow another simple key. */
-
-        parser->simple_key_allowed = 0;
-    }
-    else
-    {
-        /* The ':' indicator follows a complex key. */
-
-        /* In the block context, extra checks are required. */
-
-        if (!parser->flow_level)
-        {
-            /* Check if we are allowed to start a complex value. */
-
-            if (!parser->simple_key_allowed) {
-                return yaml_parser_set_scanner_error(parser, NULL, 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 0;
-        }
-
-        /* Simple keys after ':' are allowed in the block context. */
-
-        parser->simple_key_allowed = (!parser->flow_level);
-    }
-
-    /* Consume the token. */
-
-    start_mark = parser->mark;
-    SKIP(parser);
-    end_mark = parser->mark;
-
-    /* Create the VALUE token and append it to the queue. */
-
-    TOKEN_INIT(token, YAML_VALUE_TOKEN, start_mark, end_mark);
-
-    if (!ENQUEUE(parser, parser->tokens, token))
-        return 0;
-
-    return 1;
-}
-
-/*
- * Produce the ALIAS or ANCHOR token.
- */
-
-static int
-yaml_parser_fetch_anchor(yaml_parser_t *parser, yaml_token_type_t type)
-{
-    yaml_token_t token;
-
-    /* An anchor or an alias could be a simple key. */
-
-    if (!yaml_parser_save_simple_key(parser))
-        return 0;
-
-    /* A simple key cannot follow an anchor or an alias. */
-
-    parser->simple_key_allowed = 0;
-
-    /* Create the ALIAS or ANCHOR token and append it to the queue. */
-
-    if (!yaml_parser_scan_anchor(parser, &token, type))
-        return 0;
-
-    if (!ENQUEUE(parser, parser->tokens, token)) {
-        yaml_token_delete(&token);
-        return 0;
-    }
-    return 1;
-}
-
-/*
- * Produce the TAG token.
- */
-
-static int
-yaml_parser_fetch_tag(yaml_parser_t *parser)
-{
-    yaml_token_t token;
-
-    /* A tag could be a simple key. */
-
-    if (!yaml_parser_save_simple_key(parser))
-        return 0;
-
-    /* A simple key cannot follow a tag. */
-
-    parser->simple_key_allowed = 0;
-
-    /* Create the TAG token and append it to the queue. */
-
-    if (!yaml_parser_scan_tag(parser, &token))
-        return 0;
-
-    if (!ENQUEUE(parser, parser->tokens, token)) {
-        yaml_token_delete(&token);
-        return 0;
-    }
-
-    return 1;
-}
-
-/*
- * Produce the SCALAR(...,literal) or SCALAR(...,folded) tokens.
- */
-
-static int
-yaml_parser_fetch_block_scalar(yaml_parser_t *parser, int literal)
-{
-    yaml_token_t token;
-
-    /* Remove any potential simple keys. */
-
-    if (!yaml_parser_remove_simple_key(parser))
-        return 0;
-
-    /* A simple key may follow a block scalar. */
-
-    parser->simple_key_allowed = 1;
-
-    /* Create the SCALAR token and append it to the queue. */
-
-    if (!yaml_parser_scan_block_scalar(parser, &token, literal))
-        return 0;
-
-    if (!ENQUEUE(parser, parser->tokens, token)) {
-        yaml_token_delete(&token);
-        return 0;
-    }
-
-    return 1;
-}
-
-/*
- * Produce the SCALAR(...,single-quoted) or SCALAR(...,double-quoted) tokens.
- */
-
-static int
-yaml_parser_fetch_flow_scalar(yaml_parser_t *parser, int single)
-{
-    yaml_token_t token;
-
-    /* A plain scalar could be a simple key. */
-
-    if (!yaml_parser_save_simple_key(parser))
-        return 0;
-
-    /* A simple key cannot follow a flow scalar. */
-
-    parser->simple_key_allowed = 0;
-
-    /* Create the SCALAR token and append it to the queue. */
-
-    if (!yaml_parser_scan_flow_scalar(parser, &token, single))
-        return 0;
-
-    if (!ENQUEUE(parser, parser->tokens, token)) {
-        yaml_token_delete(&token);
-        return 0;
-    }
-
-    return 1;
-}
-
-/*
- * Produce the SCALAR(...,plain) token.
- */
-
-static int
-yaml_parser_fetch_plain_scalar(yaml_parser_t *parser)
-{
-    yaml_token_t token;
-
-    /* A plain scalar could be a simple key. */
-
-    if (!yaml_parser_save_simple_key(parser))
-        return 0;
-
-    /* A simple key cannot follow a flow scalar. */
-
-    parser->simple_key_allowed = 0;
-
-    /* Create the SCALAR token and append it to the queue. */
-
-    if (!yaml_parser_scan_plain_scalar(parser, &token))
-        return 0;
-
-    if (!ENQUEUE(parser, parser->tokens, token)) {
-        yaml_token_delete(&token);
-        return 0;
-    }
-
-    return 1;
-}
-
-/*
- * Eat whitespaces and comments until the next token is found.
- */
-
-static int
-yaml_parser_scan_to_next_token(yaml_parser_t *parser)
-{
-    /* Until the next token is not found. */
-
-    while (1)
-    {
-        /* Allow the BOM mark to start a line. */
-
-        if (!CACHE(parser, 1)) return 0;
-
-        if (parser->mark.column == 0 && IS_BOM(parser->buffer))
-            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 0;
-
-        while (CHECK(parser->buffer,' ') ||
-                ((parser->flow_level || !parser->simple_key_allowed) &&
-                 CHECK(parser->buffer, '\t'))) {
-            SKIP(parser);
-            if (!CACHE(parser, 1)) return 0;
-        }
-
-        /* Eat a comment until a line break. */
-
-        if (CHECK(parser->buffer, '#')) {
-            while (!IS_BREAKZ(parser->buffer)) {
-                SKIP(parser);
-                if (!CACHE(parser, 1)) return 0;
-            }
-        }
-
-        /* If it is a line break, eat it. */
-
-        if (IS_BREAK(parser->buffer))
-        {
-            if (!CACHE(parser, 2)) return 0;
-            SKIP_LINE(parser);
-
-            /* In the block context, a new line may start a simple key. */
-
-            if (!parser->flow_level) {
-                parser->simple_key_allowed = 1;
-            }
-        }
-        else
-        {
-            /* We have found a token. */
-
-            break;
-        }
-    }
-
-    return 1;
-}
-
-/*
- * Scan a YAML-DIRECTIVE or TAG-DIRECTIVE token.
- *
- * Scope:
- *      %YAML    1.1    # a comment \n
- *      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
- *      %TAG    !yaml!  tag:yaml.org,2002:  \n
- *      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
- */
-
-int
-yaml_parser_scan_directive(yaml_parser_t *parser, yaml_token_t *token)
-{
-    yaml_mark_t start_mark, end_mark;
-    yaml_char_t *name = NULL;
-    int major, minor;
-    yaml_char_t *handle = NULL, *prefix = NULL;
-
-    /* Eat '%'. */
-
-    start_mark = parser->mark;
-
-    SKIP(parser);
-
-    /* Scan the directive name. */
-
-    if (!yaml_parser_scan_directive_name(parser, start_mark, &name))
-        goto error;
-
-    /* Is it a YAML directive? */
-
-    if (strcmp((char *)name, "YAML") == 0)
-    {
-        /* Scan the VERSION directive value. */
-
-        if (!yaml_parser_scan_version_directive_value(parser, start_mark,
-                    &major, &minor))
-            goto error;
-
-        end_mark = parser->mark;
-
-        /* Create a VERSION-DIRECTIVE token. */
-
-        VERSION_DIRECTIVE_TOKEN_INIT(*token, major, minor,
-                start_mark, end_mark);
-    }
-
-    /* Is it a TAG directive? */
-
-    else if (strcmp((char *)name, "TAG") == 0)
-    {
-        /* Scan the TAG directive value. */
-
-        if (!yaml_parser_scan_tag_directive_value(parser, start_mark,
-                    &handle, &prefix))
-            goto error;
-
-        end_mark = parser->mark;
-
-        /* Create a TAG-DIRECTIVE token. */
-
-        TAG_DIRECTIVE_TOKEN_INIT(*token, handle, prefix,
-                start_mark, end_mark);
-    }
-
-    /* Unknown directive. */
-
-    else
-    {
-        yaml_parser_set_scanner_error(parser, "while scanning a directive",
-                start_mark, "found uknown directive name");
-        goto error;
-    }
-
-    /* Eat the rest of the line including any comments. */
-
-    if (!CACHE(parser, 1)) goto error;
-
-    while (IS_BLANK(parser->buffer)) {
-        SKIP(parser);
-        if (!CACHE(parser, 1)) goto error;
-    }
-
-    if (CHECK(parser->buffer, '#')) {
-        while (!IS_BREAKZ(parser->buffer)) {
-            SKIP(parser);
-            if (!CACHE(parser, 1)) goto error;
-        }
-    }
-
-    /* Check if we are at the end of the line. */
-
-    if (!IS_BREAKZ(parser->buffer)) {
-        yaml_parser_set_scanner_error(parser, "while scanning a directive",
-                start_mark, "did not find expected comment or line break");
-        goto error;
-    }
-
-    /* Eat a line break. */
-
-    if (IS_BREAK(parser->buffer)) {
-        if (!CACHE(parser, 2)) goto error;
-        SKIP_LINE(parser);
-    }
-
-    yaml_free(name);
-
-    return 1;
-
-error:
-    yaml_free(prefix);
-    yaml_free(handle);
-    yaml_free(name);
-    return 0;
-}
-
-/*
- * Scan the directive name.
- *
- * Scope:
- *      %YAML   1.1     # a comment \n
- *       ^^^^
- *      %TAG    !yaml!  tag:yaml.org,2002:  \n
- *       ^^^
- */
-
-static int
-yaml_parser_scan_directive_name(yaml_parser_t *parser,
-        yaml_mark_t start_mark, yaml_char_t **name)
-{
-    yaml_string_t string = NULL_STRING;
-
-    if (!STRING_INIT(parser, string, INITIAL_STRING_SIZE)) goto error;
-
-    /* Consume the directive name. */
-
-    if (!CACHE(parser, 1)) goto error;
-
-    while (IS_ALPHA(parser->buffer))
-    {
-        if (!READ(parser, string)) goto error;
-        if (!CACHE(parser, 1)) goto error;
-    }
-
-    /* Check if the name is empty. */
-
-    if (string.start == string.pointer) {
-        yaml_parser_set_scanner_error(parser, "while scanning a directive",
-                start_mark, "could not find expected directive name");
-        goto error;
-    }
-
-    /* Check for an blank character after the name. */
-
-    if (!IS_BLANKZ(parser->buffer)) {
-        yaml_parser_set_scanner_error(parser, "while scanning a directive",
-                start_mark, "found unexpected non-alphabetical character");
-        goto error;
-    }
-
-    *name = string.start;
-
-    return 1;
-
-error:
-    STRING_DEL(parser, string);
-    return 0;
-}
-
-/*
- * Scan the value of VERSION-DIRECTIVE.
- *
- * Scope:
- *      %YAML   1.1     # a comment \n
- *           ^^^^^^
- */
-
-static int
-yaml_parser_scan_version_directive_value(yaml_parser_t *parser,
-        yaml_mark_t start_mark, int *major, int *minor)
-{
-    /* Eat whitespaces. */
-
-    if (!CACHE(parser, 1)) return 0;
-
-    while (IS_BLANK(parser->buffer)) {
-        SKIP(parser);
-        if (!CACHE(parser, 1)) return 0;
-    }
-
-    /* Consume the major version number. */
-
-    if (!yaml_parser_scan_version_directive_number(parser, start_mark, major))
-        return 0;
-
-    /* Eat '.'. */
-
-    if (!CHECK(parser->buffer, '.')) {
-        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 0;
-
-    return 1;
-}
-
-#define MAX_NUMBER_LENGTH   9
-
-/*
- * Scan the version number of VERSION-DIRECTIVE.
- *
- * Scope:
- *      %YAML   1.1     # a comment \n
- *              ^
- *      %YAML   1.1     # a comment \n
- *                ^
- */
-
-static int
-yaml_parser_scan_version_directive_number(yaml_parser_t *parser,
-        yaml_mark_t start_mark, int *number)
-{
-    int value = 0;
-    size_t length = 0;
-
-    /* Repeat while the next character is digit. */
-
-    if (!CACHE(parser, 1)) return 0;
-
-    while (IS_DIGIT(parser->buffer))
-    {
-        /* Check if the number is too long. */
-
-        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);
-
-        SKIP(parser);
-
-        if (!CACHE(parser, 1)) return 0;
-    }
-
-    /* Check if the number was present. */
-
-    if (!length) {
-        return yaml_parser_set_scanner_error(parser, "while scanning a %YAML directive",
-                start_mark, "did not find expected version number");
-    }
-
-    *number = value;
-
-    return 1;
-}
-
-/*
- * Scan the value of a TAG-DIRECTIVE token.
- *
- * Scope:
- *      %TAG    !yaml!  tag:yaml.org,2002:  \n
- *          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
- */
-
-static int
-yaml_parser_scan_tag_directive_value(yaml_parser_t *parser,
-        yaml_mark_t start_mark, yaml_char_t **handle, yaml_char_t **prefix)
-{
-    yaml_char_t *handle_value = NULL;
-    yaml_char_t *prefix_value = NULL;
-
-    /* Eat whitespaces. */
-
-    if (!CACHE(parser, 1)) goto error;
-
-    while (IS_BLANK(parser->buffer)) {
-        SKIP(parser);
-        if (!CACHE(parser, 1)) goto error;
-    }
-
-    /* Scan a handle. */
-
-    if (!yaml_parser_scan_tag_handle(parser, 1, start_mark, &handle_value))
-        goto error;
-
-    /* Expect a whitespace. */
-
-    if (!CACHE(parser, 1)) goto error;
-
-    if (!IS_BLANK(parser->buffer)) {
-        yaml_parser_set_scanner_error(parser, "while scanning a %TAG directive",
-                start_mark, "did not find expected whitespace");
-        goto error;
-    }
-
-    /* Eat whitespaces. */
-
-    while (IS_BLANK(parser->buffer)) {
-        SKIP(parser);
-        if (!CACHE(parser, 1)) goto error;
-    }
-
-    /* Scan a prefix. */
-
-    if (!yaml_parser_scan_tag_uri(parser, 1, NULL, start_mark, &prefix_value))
-        goto error;
-
-    /* Expect a whitespace or line break. */
-
-    if (!CACHE(parser, 1)) goto error;
-
-    if (!IS_BLANKZ(parser->buffer)) {
-        yaml_parser_set_scanner_error(parser, "while scanning a %TAG directive",
-                start_mark, "did not find expected whitespace or line break");
-        goto error;
-    }
-
-    *handle = handle_value;
-    *prefix = prefix_value;
-
-    return 1;
-
-error:
-    yaml_free(handle_value);
-    yaml_free(prefix_value);
-    return 0;
-}
-
-static int
-yaml_parser_scan_anchor(yaml_parser_t *parser, yaml_token_t *token,
-        yaml_token_type_t type)
-{
-    int length = 0;
-    yaml_mark_t start_mark, end_mark;
-    yaml_string_t string = NULL_STRING;
-
-    if (!STRING_INIT(parser, string, INITIAL_STRING_SIZE)) goto error;
-
-    /* Eat the indicator character. */
-
-    start_mark = parser->mark;
-
-    SKIP(parser);
-
-    /* Consume the value. */
-
-    if (!CACHE(parser, 1)) goto error;
-
-    while (IS_ALPHA(parser->buffer)) {
-        if (!READ(parser, string)) goto error;
-        if (!CACHE(parser, 1)) goto error;
-        length ++;
-    }
-
-    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 (!length || !(IS_BLANKZ(parser->buffer) || CHECK(parser->buffer, '?')
-                || CHECK(parser->buffer, ':') || CHECK(parser->buffer, ',')
-                || CHECK(parser->buffer, ']') || CHECK(parser->buffer, '}')
-                || CHECK(parser->buffer, '%') || CHECK(parser->buffer, '@')
-                || CHECK(parser->buffer, '`'))) {
-        yaml_parser_set_scanner_error(parser, type == YAML_ANCHOR_TOKEN ?
-                "while scanning an anchor" : "while scanning an alias", start_mark,
-                "did not find expected alphabetic or numeric character");
-        goto error;
-    }
-
-    /* Create a token. */
-
-    if (type == YAML_ANCHOR_TOKEN) {
-        ANCHOR_TOKEN_INIT(*token, string.start, start_mark, end_mark);
-    }
-    else {
-        ALIAS_TOKEN_INIT(*token, string.start, start_mark, end_mark);
-    }
-
-    return 1;
-
-error:
-    STRING_DEL(parser, string);
-    return 0;
-}
-
-/*
- * Scan a TAG token.
- */
-
-static int
-yaml_parser_scan_tag(yaml_parser_t *parser, yaml_token_t *token)
-{
-    yaml_char_t *handle = NULL;
-    yaml_char_t *suffix = NULL;
-    yaml_mark_t start_mark, end_mark;
-
-    start_mark = parser->mark;
-
-    /* Check if the tag is in the canonical form. */
-
-    if (!CACHE(parser, 2)) goto error;
-
-    if (CHECK_AT(parser->buffer, '<', 1))
-    {
-        /* Set the handle to '' */
-
-        handle = yaml_malloc(1);
-        if (!handle) goto error;
-        handle[0] = '\0';
-
-        /* Eat '!<' */
-
-        SKIP(parser);
-        SKIP(parser);
-
-        /* Consume the tag value. */
-
-        if (!yaml_parser_scan_tag_uri(parser, 0, NULL, start_mark, &suffix))
-            goto error;
-
-        /* Check for '>' and eat it. */
-
-        if (!CHECK(parser->buffer, '>')) {
-            yaml_parser_set_scanner_error(parser, "while scanning a tag",
-                    start_mark, "did not find the expected '>'");
-            goto error;
-        }
-
-        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, 0, start_mark, &handle))
-            goto error;
-
-        /* Check if it is, indeed, handle. */
-
-        if (handle[0] == '!' && handle[1] != '\0' && handle[strlen((char *)handle)-1] == '!')
-        {
-            /* Scan the suffix now. */
-
-            if (!yaml_parser_scan_tag_uri(parser, 0, NULL, start_mark, &suffix))
-                goto error;
-        }
-        else
-        {
-            /* It wasn't a handle after all.  Scan the rest of the tag. */
-
-            if (!yaml_parser_scan_tag_uri(parser, 0, handle, start_mark, &suffix))
-                goto error;
-
-            /* Set the handle to '!'. */
-
-            yaml_free(handle);
-            handle = yaml_malloc(2);
-            if (!handle) goto error;
-            handle[0] = '!';
-            handle[1] = '\0';
-
-            /*
-             * A special case: the '!' tag.  Set the handle to '' and the
-             * suffix to '!'.
-             */
-
-            if (suffix[0] == '\0') {
-                yaml_char_t *tmp = handle;
-                handle = suffix;
-                suffix = tmp;
-            }
-        }
-    }
-
-    /* Check the character which ends the tag. */
-
-    if (!CACHE(parser, 1)) goto error;
-
-    if (!IS_BLANKZ(parser->buffer)) {
-        yaml_parser_set_scanner_error(parser, "while scanning a tag",
-                start_mark, "did not find expected whitespace or line break");
-        goto error;
-    }
-
-    end_mark = parser->mark;
-
-    /* Create a token. */
-
-    TAG_TOKEN_INIT(*token, handle, suffix, start_mark, end_mark);
-
-    return 1;
-
-error:
-    yaml_free(handle);
-    yaml_free(suffix);
-    return 0;
-}
-
-/*
- * Scan a tag handle.
- */
-
-static int
-yaml_parser_scan_tag_handle(yaml_parser_t *parser, int directive,
-        yaml_mark_t start_mark, yaml_char_t **handle)
-{
-    yaml_string_t string = NULL_STRING;
-
-    if (!STRING_INIT(parser, string, INITIAL_STRING_SIZE)) goto error;
-
-    /* Check the initial '!' character. */
-
-    if (!CACHE(parser, 1)) goto error;
-
-    if (!CHECK(parser->buffer, '!')) {
-        yaml_parser_set_scanner_error(parser, directive ?
-                "while scanning a tag directive" : "while scanning a tag",
-                start_mark, "did not find expected '!'");
-        goto error;
-    }
-
-    /* Copy the '!' character. */
-
-    if (!READ(parser, string)) goto error;
-
-    /* Copy all subsequent alphabetical and numerical characters. */
-
-    if (!CACHE(parser, 1)) goto error;
-
-    while (IS_ALPHA(parser->buffer))
-    {
-        if (!READ(parser, string)) goto error;
-        if (!CACHE(parser, 1)) goto error;
-    }
-
-    /* Check if the trailing character is '!' and copy it. */
-
-    if (CHECK(parser->buffer, '!'))
-    {
-        if (!READ(parser, string)) goto error;
-    }
-    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 && !(string.start[0] == '!' && string.start[1] == '\0')) {
-            yaml_parser_set_scanner_error(parser, "while parsing a tag directive",
-                    start_mark, "did not find expected '!'");
-            goto error;
-        }
-    }
-
-    *handle = string.start;
-
-    return 1;
-
-error:
-    STRING_DEL(parser, string);
-    return 0;
-}
-
-/*
- * Scan a tag.
- */
-
-static int
-yaml_parser_scan_tag_uri(yaml_parser_t *parser, int directive,
-        yaml_char_t *head, yaml_mark_t start_mark, yaml_char_t **uri)
-{
-    size_t length = head ? strlen((char *)head) : 0;
-    yaml_string_t string = NULL_STRING;
-
-    if (!STRING_INIT(parser, string, INITIAL_STRING_SIZE)) goto error;
-
-    /* Resize the string to include the head. */
-
-    while (string.end - string.start <= (int)length) {
-        if (!yaml_string_extend(&string.start, &string.pointer, &string.end)) {
-            parser->error = YAML_MEMORY_ERROR;
-            goto error;
-        }
-    }
-
-    /*
-     * Copy the head if needed.
-     *
-     * Note that we don't copy the leading '!' character.
-     */
-
-    if (length > 1) {
-        memcpy(string.start, head+1, length-1);
-        string.pointer += length-1;
-    }
-
-    /* Scan the tag. */
-
-    if (!CACHE(parser, 1)) goto error;
-
-    /*
-     * The set of characters that may appear in URI is as follows:
-     *
-     *      '0'-'9', 'A'-'Z', 'a'-'z', '_', '-', ';', '/', '?', ':', '@', '&',
-     *      '=', '+', '$', ',', '.', '!', '~', '*', '\'', '(', ')', '[', ']',
-     *      '%'.
-     */
-
-    while (IS_ALPHA(parser->buffer) || CHECK(parser->buffer, ';')
-            || CHECK(parser->buffer, '/') || CHECK(parser->buffer, '?')
-            || CHECK(parser->buffer, ':') || CHECK(parser->buffer, '@')
-            || CHECK(parser->buffer, '&') || CHECK(parser->buffer, '=')
-            || CHECK(parser->buffer, '+') || CHECK(parser->buffer, '$')
-            || CHECK(parser->buffer, ',') || CHECK(parser->buffer, '.')
-            || CHECK(parser->buffer, '!') || CHECK(parser->buffer, '~')
-            || CHECK(parser->buffer, '*') || CHECK(parser->buffer, '\'')
-            || CHECK(parser->buffer, '(') || CHECK(parser->buffer, ')')
-            || CHECK(parser->buffer, '[') || CHECK(parser->buffer, ']')
-            || CHECK(parser->buffer, '%'))
-    {
-        /* Check if it is a URI-escape sequence. */
-
-        if (CHECK(parser->buffer, '%')) {
-            if (!yaml_parser_scan_uri_escapes(parser,
-                        directive, start_mark, &string)) goto error;
-        }
-        else {
-            if (!READ(parser, string)) goto error;
-        }
-
-        length ++;
-        if (!CACHE(parser, 1)) goto error;
-    }
-
-    /* Check if the tag is non-empty. */
-
-    if (!length) {
-        if (!STRING_EXTEND(parser, string))
-            goto error;
-
-        yaml_parser_set_scanner_error(parser, directive ?
-                "while parsing a %TAG directive" : "while parsing a tag",
-                start_mark, "did not find expected tag URI");
-        goto error;
-    }
-
-    *uri = string.start;
-
-    return 1;
-
-error:
-    STRING_DEL(parser, string);
-    return 0;
-}
-
-/*
- * Decode an URI-escape sequence corresponding to a single UTF-8 character.
- */
-
-static int
-yaml_parser_scan_uri_escapes(yaml_parser_t *parser, int directive,
-        yaml_mark_t start_mark, yaml_string_t *string)
-{
-    int width = 0;
-
-    /* Decode the required number of characters. */
-
-    do {
-
-        unsigned char octet = 0;
-
-        /* Check for a URI-escaped octet. */
-
-        if (!CACHE(parser, 3)) return 0;
-
-        if (!(CHECK(parser->buffer, '%')
-                    && IS_HEX_AT(parser->buffer, 1)
-                    && IS_HEX_AT(parser->buffer, 2))) {
-            return yaml_parser_set_scanner_error(parser, directive ?
-                    "while parsing a %TAG directive" : "while parsing a tag",
-                    start_mark, "did not find URI escaped octet");
-        }
-
-        /* Get the octet. */
-
-        octet = (AS_HEX_AT(parser->buffer, 1) << 4) + AS_HEX_AT(parser->buffer, 2);
-
-        /* If it is the leading octet, determine the length of the UTF-8 sequence. */
-
-        if (!width)
-        {
-            width = (octet & 0x80) == 0x00 ? 1 :
-                    (octet & 0xE0) == 0xC0 ? 2 :
-                    (octet & 0xF0) == 0xE0 ? 3 :
-                    (octet & 0xF8) == 0xF0 ? 4 : 0;
-            if (!width) {
-                return yaml_parser_set_scanner_error(parser, directive ?
-                        "while parsing a %TAG directive" : "while parsing a tag",
-                        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_error(parser, directive ?
-                        "while parsing a %TAG directive" : "while parsing a tag",
-                        start_mark, "found an incorrect trailing UTF-8 octet");
-            }
-        }
-
-        /* Copy the octet and move the pointers. */
-
-        *(string->pointer++) = octet;
-        SKIP(parser);
-        SKIP(parser);
-        SKIP(parser);
-
-    } while (--width);
-
-    return 1;
-}
-
-/*
- * Scan a block scalar.
- */
-
-static int
-yaml_parser_scan_block_scalar(yaml_parser_t *parser, yaml_token_t *token,
-        int literal)
-{
-    yaml_mark_t start_mark;
-    yaml_mark_t end_mark;
-    yaml_string_t string = NULL_STRING;
-    yaml_string_t leading_break = NULL_STRING;
-    yaml_string_t trailing_breaks = NULL_STRING;
-    int chomping = 0;
-    int increment = 0;
-    int indent = 0;
-    int leading_blank = 0;
-    int trailing_blank = 0;
-
-    if (!STRING_INIT(parser, string, INITIAL_STRING_SIZE)) goto error;
-    if (!STRING_INIT(parser, leading_break, INITIAL_STRING_SIZE)) goto error;
-    if (!STRING_INIT(parser, trailing_breaks, INITIAL_STRING_SIZE)) goto error;
-
-    /* Eat the indicator '|' or '>'. */
-
-    start_mark = parser->mark;
-
-    SKIP(parser);
-
-    /* Scan the additional block scalar indicators. */
-
-    if (!CACHE(parser, 1)) goto error;
-
-    /* Check for a chomping indicator. */
-
-    if (CHECK(parser->buffer, '+') || CHECK(parser->buffer, '-'))
-    {
-        /* Set the chomping method and eat the indicator. */
-
-        chomping = CHECK(parser->buffer, '+') ? +1 : -1;
-
-        SKIP(parser);
-
-        /* Check for an indentation indicator. */
-
-        if (!CACHE(parser, 1)) goto error;
-
-        if (IS_DIGIT(parser->buffer))
-        {
-            /* Check that the intendation is greater than 0. */
-
-            if (CHECK(parser->buffer, '0')) {
-                yaml_parser_set_scanner_error(parser, "while scanning a block scalar",
-                        start_mark, "found an intendation indicator equal to 0");
-                goto error;
-            }
-
-            /* Get the intendation level and eat the indicator. */
-
-            increment = AS_DIGIT(parser->buffer);
-
-            SKIP(parser);
-        }
-    }
-
-    /* Do the same as above, but in the opposite order. */
-
-    else if (IS_DIGIT(parser->buffer))
-    {
-        if (CHECK(parser->buffer, '0')) {
-            yaml_parser_set_scanner_error(parser, "while scanning a block scalar",
-                    start_mark, "found an intendation indicator equal to 0");
-            goto error;
-        }
-
-        increment = AS_DIGIT(parser->buffer);
-
-        SKIP(parser);
-
-        if (!CACHE(parser, 1)) goto error;
-
-        if (CHECK(parser->buffer, '+') || CHECK(parser->buffer, '-')) {
-            chomping = CHECK(parser->buffer, '+') ? +1 : -1;
-
-            SKIP(parser);
-        }
-    }
-
-    /* Eat whitespaces and comments to the end of the line. */
-
-    if (!CACHE(parser, 1)) goto error;
-
-    while (IS_BLANK(parser->buffer)) {
-        SKIP(parser);
-        if (!CACHE(parser, 1)) goto error;
-    }
-
-    if (CHECK(parser->buffer, '#')) {
-        while (!IS_BREAKZ(parser->buffer)) {
-            SKIP(parser);
-            if (!CACHE(parser, 1)) goto error;
-        }
-    }
-
-    /* Check if we are at the end of the line. */
-
-    if (!IS_BREAKZ(parser->buffer)) {
-        yaml_parser_set_scanner_error(parser, "while scanning a block scalar",
-                start_mark, "did not find expected comment or line break");
-        goto error;
-    }
-
-    /* Eat a line break. */
-
-    if (IS_BREAK(parser->buffer)) {
-        if (!CACHE(parser, 2)) goto error;
-        SKIP_LINE(parser);
-    }
-
-    end_mark = parser->mark;
-
-    /* Set the intendation level if it was specified. */
-
-    if (increment) {
-        indent = parser->indent >= 0 ? parser->indent+increment : increment;
-    }
-
-    /* Scan the leading line breaks and determine the indentation level if needed. */
-
-    if (!yaml_parser_scan_block_scalar_breaks(parser, &indent, &trailing_breaks,
-                start_mark, &end_mark)) goto error;
-
-    /* Scan the block scalar content. */
-
-    if (!CACHE(parser, 1)) goto error;
-
-    while ((int)parser->mark.column == indent && !IS_Z(parser->buffer))
-    {
-        /*
-         * We are at the beginning of a non-empty line.
-         */
-
-        /* Is it a trailing whitespace? */
-
-        trailing_blank = IS_BLANK(parser->buffer);
-
-        /* Check if we need to fold the leading line break. */
-
-        if (!literal && (*leading_break.start == '\n')
-                && !leading_blank && !trailing_blank)
-        {
-            /* Do we need to join the lines by space? */
-
-            if (*trailing_breaks.start == '\0') {
-                if (!STRING_EXTEND(parser, string)) goto error;
-                *(string.pointer ++) = ' ';
-            }
-
-            CLEAR(parser, leading_break);
-        }
-        else {
-            if (!JOIN(parser, string, leading_break)) goto error;
-            CLEAR(parser, leading_break);
-        }
-
-        /* Append the remaining line breaks. */
-
-        if (!JOIN(parser, string, trailing_breaks)) goto error;
-        CLEAR(parser, trailing_breaks);
-
-        /* Is it a leading whitespace? */
-
-        leading_blank = IS_BLANK(parser->buffer);
-
-        /* Consume the current line. */
-
-        while (!IS_BREAKZ(parser->buffer)) {
-            if (!READ(parser, string)) goto error;
-            if (!CACHE(parser, 1)) goto error;
-        }
-
-        /* Consume the line break. */
-
-        if (!CACHE(parser, 2)) goto error;
-
-        if (!READ_LINE(parser, leading_break)) goto error;
-
-        /* Eat the following intendation spaces and line breaks. */
-
-        if (!yaml_parser_scan_block_scalar_breaks(parser,
-                    &indent, &trailing_breaks, start_mark, &end_mark)) goto error;
-    }
-
-    /* Chomp the tail. */
-
-    if (chomping != -1) {
-        if (!JOIN(parser, string, leading_break)) goto error;
-    }
-    if (chomping == 1) {
-        if (!JOIN(parser, string, trailing_breaks)) goto error;
-    }
-
-    /* Create a token. */
-
-    SCALAR_TOKEN_INIT(*token, string.start, string.pointer-string.start,
-            literal ? YAML_LITERAL_SCALAR_STYLE : YAML_FOLDED_SCALAR_STYLE,
-            start_mark, end_mark);
-
-    STRING_DEL(parser, leading_break);
-    STRING_DEL(parser, trailing_breaks);
-
-    return 1;
-
-error:
-    STRING_DEL(parser, string);
-    STRING_DEL(parser, leading_break);
-    STRING_DEL(parser, trailing_breaks);
-
-    return 0;
-}
-
-/*
- * Scan intendation spaces and line breaks for a block scalar.  Determine the
- * intendation level if needed.
- */
-
-static int
-yaml_parser_scan_block_scalar_breaks(yaml_parser_t *parser,
-        int *indent, yaml_string_t *breaks,
-        yaml_mark_t start_mark, yaml_mark_t *end_mark)
-{
-    int max_indent = 0;
-
-    *end_mark = parser->mark;
-
-    /* Eat the intendation spaces and line breaks. */
-
-    while (1)
-    {
-        /* Eat the intendation spaces. */
-
-        if (!CACHE(parser, 1)) return 0;
-
-        while ((!*indent || (int)parser->mark.column < *indent)
-                && IS_SPACE(parser->buffer)) {
-            SKIP(parser);
-            if (!CACHE(parser, 1)) return 0;
-        }
-
-        if ((int)parser->mark.column > max_indent)
-            max_indent = (int)parser->mark.column;
-
-        /* Check for a tab character messing the intendation. */
-
-        if ((!*indent || (int)parser->mark.column < *indent)
-                && IS_TAB(parser->buffer)) {
-            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)) break;
-
-        /* Consume the line break. */
-
-        if (!CACHE(parser, 2)) return 0;
-        if (!READ_LINE(parser, *breaks)) return 0;
-        *end_mark = parser->mark;
-    }
-
-    /* Determine the indentation level if needed. */
-
-    if (!*indent) {
-        *indent = max_indent;
-        if (*indent < parser->indent + 1)
-            *indent = parser->indent + 1;
-        if (*indent < 1)
-            *indent = 1;
-    }
-
-   return 1; 
-}
-
-/*
- * Scan a quoted scalar.
- */
-
-static int
-yaml_parser_scan_flow_scalar(yaml_parser_t *parser, yaml_token_t *token,
-        int single)
-{
-    yaml_mark_t start_mark;
-    yaml_mark_t end_mark;
-    yaml_string_t string = NULL_STRING;
-    yaml_string_t leading_break = NULL_STRING;
-    yaml_string_t trailing_breaks = NULL_STRING;
-    yaml_string_t whitespaces = NULL_STRING;
-    int leading_blanks;
-
-    if (!STRING_INIT(parser, string, INITIAL_STRING_SIZE)) goto error;
-    if (!STRING_INIT(parser, leading_break, INITIAL_STRING_SIZE)) goto error;
-    if (!STRING_INIT(parser, trailing_breaks, INITIAL_STRING_SIZE)) goto error;
-    if (!STRING_INIT(parser, whitespaces, INITIAL_STRING_SIZE)) goto error;
-
-    /* Eat the left quote. */
-
-    start_mark = parser->mark;
-
-    SKIP(parser);
-
-    /* Consume the content of the quoted scalar. */
-
-    while (1)
-    {
-        /* Check that there are no document indicators at the beginning of the line. */
-
-        if (!CACHE(parser, 4)) goto error;
-
-        if (parser->mark.column == 0 &&
-            ((CHECK_AT(parser->buffer, '-', 0) &&
-              CHECK_AT(parser->buffer, '-', 1) &&
-              CHECK_AT(parser->buffer, '-', 2)) ||
-             (CHECK_AT(parser->buffer, '.', 0) &&
-              CHECK_AT(parser->buffer, '.', 1) &&
-              CHECK_AT(parser->buffer, '.', 2))) &&
-            IS_BLANKZ_AT(parser->buffer, 3))
-        {
-            yaml_parser_set_scanner_error(parser, "while scanning a quoted scalar",
-                    start_mark, "found unexpected document indicator");
-            goto error;
-        }
-
-        /* Check for EOF. */
-
-        if (IS_Z(parser->buffer)) {
-            yaml_parser_set_scanner_error(parser, "while scanning a quoted scalar",
-                    start_mark, "found unexpected end of stream");
-            goto error;
-        }
-
-        /* Consume non-blank characters. */
-
-        if (!CACHE(parser, 2)) goto error;
-
-        leading_blanks = 0;
-
-        while (!IS_BLANKZ(parser->buffer))
-        {
-            /* Check for an escaped single quote. */
-
-            if (single && CHECK_AT(parser->buffer, '\'', 0)
-                    && CHECK_AT(parser->buffer, '\'', 1))
-            {
-                if (!STRING_EXTEND(parser, string)) goto error;
-                *(string.pointer++) = '\'';
-                SKIP(parser);
-                SKIP(parser);
-            }
-
-            /* Check for the right quote. */
-
-            else if (CHECK(parser->buffer, single ? '\'' : '"'))
-            {
-                break;
-            }
-
-            /* Check for an escaped line break. */
-
-            else if (!single && CHECK(parser->buffer, '\\')
-                    && IS_BREAK_AT(parser->buffer, 1))
-            {
-                if (!CACHE(parser, 3)) goto error;
-                SKIP(parser);
-                SKIP_LINE(parser);
-                leading_blanks = 1;
-                break;
-            }
-
-            /* Check for an escape sequence. */
-
-            else if (!single && CHECK(parser->buffer, '\\'))
-            {
-                size_t code_length = 0;
-
-                if (!STRING_EXTEND(parser, string)) goto error;
-
-                /* Check the escape character. */
-
-                switch (parser->buffer.pointer[1])
-                {
-                    case '0':
-                        *(string.pointer++) = '\0';
-                        break;
-
-                    case 'a':
-                        *(string.pointer++) = '\x07';
-                        break;
-
-                    case 'b':
-                        *(string.pointer++) = '\x08';
-                        break;
-
-                    case 't':
-                    case '\t':
-                        *(string.pointer++) = '\x09';
-                        break;
-
-                    case 'n':
-                        *(string.pointer++) = '\x0A';
-                        break;
-
-                    case 'v':
-                        *(string.pointer++) = '\x0B';
-                        break;
-
-                    case 'f':
-                        *(string.pointer++) = '\x0C';
-                        break;
-
-                    case 'r':
-                        *(string.pointer++) = '\x0D';
-                        break;
-
-                    case 'e':
-                        *(string.pointer++) = '\x1B';
-                        break;
-
-                    case ' ':
-                        *(string.pointer++) = '\x20';
-                        break;
-
-                    case '"':
-                        *(string.pointer++) = '"';
-                        break;
-
-                    case '\'':
-                        *(string.pointer++) = '\'';
-                        break;
-
-                    case '\\':
-                        *(string.pointer++) = '\\';
-                        break;
-
-                    case 'N':   /* NEL (#x85) */
-                        *(string.pointer++) = '\xC2';
-                        *(string.pointer++) = '\x85';
-                        break;
-
-                    case '_':   /* #xA0 */
-                        *(string.pointer++) = '\xC2';
-                        *(string.pointer++) = '\xA0';
-                        break;
-
-                    case 'L':   /* LS (#x2028) */
-                        *(string.pointer++) = '\xE2';
-                        *(string.pointer++) = '\x80';
-                        *(string.pointer++) = '\xA8';
-                        break;
-
-                    case 'P':   /* PS (#x2029) */
-                        *(string.pointer++) = '\xE2';
-                        *(string.pointer++) = '\x80';
-                        *(string.pointer++) = '\xA9';
-                        break;
-
-                    case 'x':
-                        code_length = 2;
-                        break;
-
-                    case 'u':
-                        code_length = 4;
-                        break;
-
-                    case 'U':
-                        code_length = 8;
-                        break;
-
-                    default:
-                        yaml_parser_set_scanner_error(parser, "while parsing a quoted scalar",
-                                start_mark, "found unknown escape character");
-                        goto error;
-                }
-
-                SKIP(parser);
-                SKIP(parser);
-
-                /* Consume an arbitrary escape code. */
-
-                if (code_length)
-                {
-                    unsigned int value = 0;
-                    size_t k;
-
-                    /* Scan the character value. */
-
-                    if (!CACHE(parser, code_length)) goto error;
-
-                    for (k = 0; k < code_length; k ++) {
-                        if (!IS_HEX_AT(parser->buffer, k)) {
-                            yaml_parser_set_scanner_error(parser, "while parsing a quoted scalar",
-                                    start_mark, "did not find expected hexdecimal number");
-                            goto error;
-                        }
-                        value = (value << 4) + AS_HEX_AT(parser->buffer, 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");
-                        goto error;
-                    }
-
-                    if (value <= 0x7F) {
-                        *(string.pointer++) = value;
-                    }
-                    else if (value <= 0x7FF) {
-                        *(string.pointer++) = 0xC0 + (value >> 6);
-                        *(string.pointer++) = 0x80 + (value & 0x3F);
-                    }
-                    else if (value <= 0xFFFF) {
-                        *(string.pointer++) = 0xE0 + (value >> 12);
-                        *(string.pointer++) = 0x80 + ((value >> 6) & 0x3F);
-                        *(string.pointer++) = 0x80 + (value & 0x3F);
-                    }
-                    else {
-                        *(string.pointer++) = 0xF0 + (value >> 18);
-                        *(string.pointer++) = 0x80 + ((value >> 12) & 0x3F);
-                        *(string.pointer++) = 0x80 + ((value >> 6) & 0x3F);
-                        *(string.pointer++) = 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, string)) goto error;
-            }
-
-            if (!CACHE(parser, 2)) goto error;
-        }
-
-        /* Check if we are at the end of the scalar. */
-
-        if (CHECK(parser->buffer, single ? '\'' : '"'))
-            break;
-
-        /* Consume blank characters. */
-
-        if (!CACHE(parser, 1)) goto error;
-
-        while (IS_BLANK(parser->buffer) || IS_BREAK(parser->buffer))
-        {
-            if (IS_BLANK(parser->buffer))
-            {
-                /* Consume a space or a tab character. */
-
-                if (!leading_blanks) {
-                    if (!READ(parser, whitespaces)) goto error;
-                }
-                else {
-                    SKIP(parser);
-                }
-            }
-            else
-            {
-                if (!CACHE(parser, 2)) goto error;
-
-                /* Check if it is a first line break. */
-
-                if (!leading_blanks)
-                {
-                    CLEAR(parser, whitespaces);
-                    if (!READ_LINE(parser, leading_break)) goto error;
-                    leading_blanks = 1;
-                }
-                else
-                {
-                    if (!READ_LINE(parser, trailing_breaks)) goto error;
-                }
-            }
-            if (!CACHE(parser, 1)) goto error;
-        }
-
-        /* Join the whitespaces or fold line breaks. */
-
-        if (leading_blanks)
-        {
-            /* Do we need to fold line breaks? */
-
-            if (leading_break.start[0] == '\n') {
-                if (trailing_breaks.start[0] == '\0') {
-                    if (!STRING_EXTEND(parser, string)) goto error;
-                    *(string.pointer++) = ' ';
-                }
-                else {
-                    if (!JOIN(parser, string, trailing_breaks)) goto error;
-                    CLEAR(parser, trailing_breaks);
-                }
-                CLEAR(parser, leading_break);
-            }
-            else {
-                if (!JOIN(parser, string, leading_break)) goto error;
-                if (!JOIN(parser, string, trailing_breaks)) goto error;
-                CLEAR(parser, leading_break);
-                CLEAR(parser, trailing_breaks);
-            }
-        }
-        else
-        {
-            if (!JOIN(parser, string, whitespaces)) goto error;
-            CLEAR(parser, whitespaces);
-        }
-    }
-
-    /* Eat the right quote. */
-
-    SKIP(parser);
-
-    end_mark = parser->mark;
-
-    /* Create a token. */
-
-    SCALAR_TOKEN_INIT(*token, string.start, string.pointer-string.start,
-            single ? YAML_SINGLE_QUOTED_SCALAR_STYLE : YAML_DOUBLE_QUOTED_SCALAR_STYLE,
-            start_mark, end_mark);
-
-    STRING_DEL(parser, leading_break);
-    STRING_DEL(parser, trailing_breaks);
-    STRING_DEL(parser, whitespaces);
-
-    return 1;
-
-error:
-    STRING_DEL(parser, string);
-    STRING_DEL(parser, leading_break);
-    STRING_DEL(parser, trailing_breaks);
-    STRING_DEL(parser, whitespaces);
-
-    return 0;
-}
-
-/*
- * Scan a plain scalar.
- */
-
-static int
-yaml_parser_scan_plain_scalar(yaml_parser_t *parser, yaml_token_t *token)
-{
-    yaml_mark_t start_mark;
-    yaml_mark_t end_mark;
-    yaml_string_t string = NULL_STRING;
-    yaml_string_t leading_break = NULL_STRING;
-    yaml_string_t trailing_breaks = NULL_STRING;
-    yaml_string_t whitespaces = NULL_STRING;
-    int leading_blanks = 0;
-    int indent = parser->indent+1;
-
-    if (!STRING_INIT(parser, string, INITIAL_STRING_SIZE)) goto error;
-    if (!STRING_INIT(parser, leading_break, INITIAL_STRING_SIZE)) goto error;
-    if (!STRING_INIT(parser, trailing_breaks, INITIAL_STRING_SIZE)) goto error;
-    if (!STRING_INIT(parser, whitespaces, INITIAL_STRING_SIZE)) goto error;
-
-    start_mark = end_mark = parser->mark;
-
-    /* Consume the content of the plain scalar. */
-
-    while (1)
-    {
-        /* Check for a document indicator. */
-
-        if (!CACHE(parser, 4)) goto error;
-
-        if (parser->mark.column == 0 &&
-            ((CHECK_AT(parser->buffer, '-', 0) &&
-              CHECK_AT(parser->buffer, '-', 1) &&
-              CHECK_AT(parser->buffer, '-', 2)) ||
-             (CHECK_AT(parser->buffer, '.', 0) &&
-              CHECK_AT(parser->buffer, '.', 1) &&
-              CHECK_AT(parser->buffer, '.', 2))) &&
-            IS_BLANKZ_AT(parser->buffer, 3)) break;
-
-        /* Check for a comment. */
-
-        if (CHECK(parser->buffer, '#'))
-            break;
-
-        /* Consume non-blank characters. */
-
-        while (!IS_BLANKZ(parser->buffer))
-        {
-            /* Check for 'x:x' in the flow context. TODO: Fix the test "spec-08-13". */
-
-            if (parser->flow_level
-                    && CHECK(parser->buffer, ':')
-                    && !IS_BLANKZ_AT(parser->buffer, 1)) {
-                yaml_parser_set_scanner_error(parser, "while scanning a plain scalar",
-                        start_mark, "found unexpected ':'");
-                goto error;
-            }
-
-            /* Check for indicators that may end a plain scalar. */
-
-            if ((CHECK(parser->buffer, ':') && IS_BLANKZ_AT(parser->buffer, 1))
-                    || (parser->flow_level &&
-                        (CHECK(parser->buffer, ',') || CHECK(parser->buffer, ':')
-                         || CHECK(parser->buffer, '?') || CHECK(parser->buffer, '[')
-                         || CHECK(parser->buffer, ']') || CHECK(parser->buffer, '{')
-                         || CHECK(parser->buffer, '}'))))
-                break;
-
-            /* Check if we need to join whitespaces and breaks. */
-
-            if (leading_blanks || whitespaces.start != whitespaces.pointer)
-            {
-                if (leading_blanks)
-                {
-                    /* Do we need to fold line breaks? */
-
-                    if (leading_break.start[0] == '\n') {
-                        if (trailing_breaks.start[0] == '\0') {
-                            if (!STRING_EXTEND(parser, string)) goto error;
-                            *(string.pointer++) = ' ';
-                        }
-                        else {
-                            if (!JOIN(parser, string, trailing_breaks)) goto error;
-                            CLEAR(parser, trailing_breaks);
-                        }
-                        CLEAR(parser, leading_break);
-                    }
-                    else {
-                        if (!JOIN(parser, string, leading_break)) goto error;
-                        if (!JOIN(parser, string, trailing_breaks)) goto error;
-                        CLEAR(parser, leading_break);
-                        CLEAR(parser, trailing_breaks);
-                    }
-
-                    leading_blanks = 0;
-                }
-                else
-                {
-                    if (!JOIN(parser, string, whitespaces)) goto error;
-                    CLEAR(parser, whitespaces);
-                }
-            }
-
-            /* Copy the character. */
-
-            if (!READ(parser, string)) goto error;
-
-            end_mark = parser->mark;
-
-            if (!CACHE(parser, 2)) goto error;
-        }
-
-        /* Is it the end? */
-
-        if (!(IS_BLANK(parser->buffer) || IS_BREAK(parser->buffer)))
-            break;
-
-        /* Consume blank characters. */
-
-        if (!CACHE(parser, 1)) goto error;
-
-        while (IS_BLANK(parser->buffer) || IS_BREAK(parser->buffer))
-        {
-            if (IS_BLANK(parser->buffer))
-            {
-                /* Check for tab character that abuse intendation. */
-
-                if (leading_blanks && (int)parser->mark.column < indent
-                        && IS_TAB(parser->buffer)) {
-                    yaml_parser_set_scanner_error(parser, "while scanning a plain scalar",
-                            start_mark, "found a tab character that violate intendation");
-                    goto error;
-                }
-
-                /* Consume a space or a tab character. */
-
-                if (!leading_blanks) {
-                    if (!READ(parser, whitespaces)) goto error;
-                }
-                else {
-                    SKIP(parser);
-                }
-            }
-            else
-            {
-                if (!CACHE(parser, 2)) goto error;
-
-                /* Check if it is a first line break. */
-
-                if (!leading_blanks)
-                {
-                    CLEAR(parser, whitespaces);
-                    if (!READ_LINE(parser, leading_break)) goto error;
-                    leading_blanks = 1;
-                }
-                else
-                {
-                    if (!READ_LINE(parser, trailing_breaks)) goto error;
-                }
-            }
-            if (!CACHE(parser, 1)) goto error;
-        }
-
-        /* Check intendation level. */
-
-        if (!parser->flow_level && (int)parser->mark.column < indent)
-            break;
-    }
-
-    /* Create a token. */
-
-    SCALAR_TOKEN_INIT(*token, string.start, string.pointer-string.start,
-            YAML_PLAIN_SCALAR_STYLE, start_mark, end_mark);
-
-    /* Note that we change the 'simple_key_allowed' flag. */
-
-    if (leading_blanks) {
-        parser->simple_key_allowed = 1;
-    }
-
-    STRING_DEL(parser, leading_break);
-    STRING_DEL(parser, trailing_breaks);
-    STRING_DEL(parser, whitespaces);
-
-    return 1;
-
-error:
-    STRING_DEL(parser, string);
-    STRING_DEL(parser, leading_break);
-    STRING_DEL(parser, trailing_breaks);
-    STRING_DEL(parser, whitespaces);
-
-    return 0;
-}
-
diff --git a/scanner_c.go b/scanner_c.go
index e926272..9eeeffe 100644
--- a/scanner_c.go
+++ b/scanner_c.go
@@ -2,6 +2,7 @@
 
 import (
 	"bytes"
+	"fmt"
 )
 
 // Introduction
@@ -533,7 +534,7 @@
 		parser.buffer_pos += 2
 		parser.mark.index++
 		parser.unread--
-	case buf[pos] == '\r' || buf[pos+1] == '\n':
+	case buf[pos] == '\r' || buf[pos] == '\n':
 		// CR|LF . LF
 		*s = append(*s, '\n')
 		parser.buffer_pos += 1
@@ -546,7 +547,7 @@
 		*s = append(*s, buf[parser.buffer_pos:pos+3]...)
 		parser.buffer_pos += 3
 	default:
-		return false
+		return true
 	}
 	parser.mark.index++
 	parser.mark.column = 0
@@ -602,6 +603,13 @@
 	return yaml_parser_set_scanner_error(parser, context, context_mark, "did not find URI escaped octet")
 }
 
+func trace(args ...interface{}) func() {
+	pargs := append([]interface{}{"+++"}, args...)
+	fmt.Println(pargs...)
+	pargs = append([]interface{}{"---"}, args...)
+	return func() { fmt.Println(pargs...) }
+}
+
 // Ensure that the tokens queue contains at least one token which can be
 // returned to the Parser.
 func yaml_parser_fetch_more_tokens(parser *yaml_parser_t) bool {
@@ -619,7 +627,8 @@
 				return false
 			}
 
-			for _, simple_key := range parser.simple_keys {
+			for i := range parser.simple_keys {
+				simple_key := &parser.simple_keys[i]
 				if simple_key.possible && simple_key.token_number == parser.tokens_parsed {
 					need_more_tokens = true
 					break
@@ -643,7 +652,6 @@
 
 // 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
@@ -819,7 +827,8 @@
 // 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 {
+	for i := range parser.simple_keys {
+		simple_key := &parser.simple_keys[i]
 
 		// The specification requires that a simple key
 		//
@@ -965,6 +974,7 @@
 
 // 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
 
@@ -990,6 +1000,7 @@
 
 // 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
@@ -2177,7 +2188,7 @@
 		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' {
+		if !literal && !leading_blank && !trailing_blank && len(leading_break) > 0 && leading_break[0] == '\n' {
 			// Do we need to join the lines by space?
 			if len(trailing_breaks) == 0 {
 				s = append(s, ' ')
@@ -2255,7 +2266,7 @@
 		if !cache(parser, 1) {
 			return false
 		}
-		for *indent == 0 || parser.mark.column < *indent && is_space(parser.buffer, parser.buffer_pos) {
+		for (*indent == 0 || parser.mark.column < *indent) && is_space(parser.buffer, parser.buffer_pos) {
 			skip(parser)
 			if !cache(parser, 1) {
 				return false
@@ -2569,6 +2580,7 @@
 
 // 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
diff --git a/yaml_h.go b/yaml_h.go
index ad23067..0c1df00 100644
--- a/yaml_h.go
+++ b/yaml_h.go
@@ -138,6 +138,56 @@
 	yaml_SCALAR_TOKEN // A SCALAR token.
 )
 
+func (tt yaml_token_type_t) String() string {
+	switch tt {
+	case yaml_NO_TOKEN:
+		return "yaml_NO_TOKEN"
+	case yaml_STREAM_START_TOKEN:
+		return "yaml_STREAM_START_TOKEN"
+	case yaml_STREAM_END_TOKEN:
+		return "yaml_STREAM_END_TOKEN"
+	case yaml_VERSION_DIRECTIVE_TOKEN:
+		return "yaml_VERSION_DIRECTIVE_TOKEN"
+	case yaml_TAG_DIRECTIVE_TOKEN:
+		return "yaml_TAG_DIRECTIVE_TOKEN"
+	case yaml_DOCUMENT_START_TOKEN:
+		return "yaml_DOCUMENT_START_TOKEN"
+	case yaml_DOCUMENT_END_TOKEN:
+		return "yaml_DOCUMENT_END_TOKEN"
+	case yaml_BLOCK_SEQUENCE_START_TOKEN:
+		return "yaml_BLOCK_SEQUENCE_START_TOKEN"
+	case yaml_BLOCK_MAPPING_START_TOKEN:
+		return "yaml_BLOCK_MAPPING_START_TOKEN"
+	case yaml_BLOCK_END_TOKEN:
+		return "yaml_BLOCK_END_TOKEN"
+	case yaml_FLOW_SEQUENCE_START_TOKEN:
+		return "yaml_FLOW_SEQUENCE_START_TOKEN"
+	case yaml_FLOW_SEQUENCE_END_TOKEN:
+		return "yaml_FLOW_SEQUENCE_END_TOKEN"
+	case yaml_FLOW_MAPPING_START_TOKEN:
+		return "yaml_FLOW_MAPPING_START_TOKEN"
+	case yaml_FLOW_MAPPING_END_TOKEN:
+		return "yaml_FLOW_MAPPING_END_TOKEN"
+	case yaml_BLOCK_ENTRY_TOKEN:
+		return "yaml_BLOCK_ENTRY_TOKEN"
+	case yaml_FLOW_ENTRY_TOKEN:
+		return "yaml_FLOW_ENTRY_TOKEN"
+	case yaml_KEY_TOKEN:
+		return "yaml_KEY_TOKEN"
+	case yaml_VALUE_TOKEN:
+		return "yaml_VALUE_TOKEN"
+	case yaml_ALIAS_TOKEN:
+		return "yaml_ALIAS_TOKEN"
+	case yaml_ANCHOR_TOKEN:
+		return "yaml_ANCHOR_TOKEN"
+	case yaml_TAG_TOKEN:
+		return "yaml_TAG_TOKEN"
+	case yaml_SCALAR_TOKEN:
+		return "yaml_SCALAR_TOKEN"
+	}
+	return "<unknown token>"
+}
+
 // The token structure.
 type yaml_token_t struct {
 
@@ -553,157 +603,6 @@
 
 }
 
-///**
-// * 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
@@ -760,6 +659,60 @@
 	yaml_PARSE_END_STATE                               // Expect nothing.
 )
 
+func (ps yaml_parser_state_t) String() string {
+	switch ps {
+	case yaml_PARSE_STREAM_START_STATE:
+		return "yaml_PARSE_STREAM_START_STATE"
+	case yaml_PARSE_IMPLICIT_DOCUMENT_START_STATE:
+		return "yaml_PARSE_IMPLICIT_DOCUMENT_START_STATE"
+	case yaml_PARSE_DOCUMENT_START_STATE:
+		return "yaml_PARSE_DOCUMENT_START_STATE"
+	case yaml_PARSE_DOCUMENT_CONTENT_STATE:
+		return "yaml_PARSE_DOCUMENT_CONTENT_STATE"
+	case yaml_PARSE_DOCUMENT_END_STATE:
+		return "yaml_PARSE_DOCUMENT_END_STATE"
+	case yaml_PARSE_BLOCK_NODE_STATE:
+		return "yaml_PARSE_BLOCK_NODE_STATE"
+	case yaml_PARSE_BLOCK_NODE_OR_INDENTLESS_SEQUENCE_STATE:
+		return "yaml_PARSE_BLOCK_NODE_OR_INDENTLESS_SEQUENCE_STATE"
+	case yaml_PARSE_FLOW_NODE_STATE:
+		return "yaml_PARSE_FLOW_NODE_STATE"
+	case yaml_PARSE_BLOCK_SEQUENCE_FIRST_ENTRY_STATE:
+		return "yaml_PARSE_BLOCK_SEQUENCE_FIRST_ENTRY_STATE"
+	case yaml_PARSE_BLOCK_SEQUENCE_ENTRY_STATE:
+		return "yaml_PARSE_BLOCK_SEQUENCE_ENTRY_STATE"
+	case yaml_PARSE_INDENTLESS_SEQUENCE_ENTRY_STATE:
+		return "yaml_PARSE_INDENTLESS_SEQUENCE_ENTRY_STATE"
+	case yaml_PARSE_BLOCK_MAPPING_FIRST_KEY_STATE:
+		return "yaml_PARSE_BLOCK_MAPPING_FIRST_KEY_STATE"
+	case yaml_PARSE_BLOCK_MAPPING_KEY_STATE:
+		return "yaml_PARSE_BLOCK_MAPPING_KEY_STATE"
+	case yaml_PARSE_BLOCK_MAPPING_VALUE_STATE:
+		return "yaml_PARSE_BLOCK_MAPPING_VALUE_STATE"
+	case yaml_PARSE_FLOW_SEQUENCE_FIRST_ENTRY_STATE:
+		return "yaml_PARSE_FLOW_SEQUENCE_FIRST_ENTRY_STATE"
+	case yaml_PARSE_FLOW_SEQUENCE_ENTRY_STATE:
+		return "yaml_PARSE_FLOW_SEQUENCE_ENTRY_STATE"
+	case yaml_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_KEY_STATE:
+		return "yaml_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_KEY_STATE"
+	case yaml_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_VALUE_STATE:
+		return "yaml_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_VALUE_STATE"
+	case yaml_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_END_STATE:
+		return "yaml_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_END_STATE"
+	case yaml_PARSE_FLOW_MAPPING_FIRST_KEY_STATE:
+		return "yaml_PARSE_FLOW_MAPPING_FIRST_KEY_STATE"
+	case yaml_PARSE_FLOW_MAPPING_KEY_STATE:
+		return "yaml_PARSE_FLOW_MAPPING_KEY_STATE"
+	case yaml_PARSE_FLOW_MAPPING_VALUE_STATE:
+		return "yaml_PARSE_FLOW_MAPPING_VALUE_STATE"
+	case yaml_PARSE_FLOW_MAPPING_EMPTY_VALUE_STATE:
+		return "yaml_PARSE_FLOW_MAPPING_EMPTY_VALUE_STATE"
+	case yaml_PARSE_END_STATE:
+		return "yaml_PARSE_END_STATE"
+	}
+	return "<unknown parser state>"
+}
+
 // This structure holds aliases data.
 type yaml_alias_data_t struct {
 	anchor []byte      // The anchor.
@@ -843,157 +796,6 @@
 	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
 // * @{
