reader.c fully ported.
diff --git a/api_c.go b/api_c.go
index 46a303d..50b162d 100644
--- a/api_c.go
+++ b/api_c.go
@@ -5,70 +5,9 @@
 	"os"
 )
 
-///*
-// * Extend a string.
-// */
-//
-//YAML_DECLARE(int)
-//yaml_string_extend(yaml_char_t **start,
-//        yaml_char_t **pointer, yaml_char_t **end)
-//{
-//    yaml_char_t *new_start = yaml_realloc(*start, (*end - *start)*2);
-//
-//    if (!new_start) return 0;
-//
-//    memset(new_start + (*end - *start), 0, *end - *start);
-//
-//    *pointer = new_start + (*pointer - *start);
-//    *end = new_start + (*end - *start)*2;
-//    *start = new_start;
-//
-//    return 1;
-//}
-//
-///*
-// * Append a string B to a string A.
-// */
-//
-//YAML_DECLARE(int)
-//yaml_string_join(
-//        yaml_char_t **a_start, yaml_char_t **a_pointer, yaml_char_t **a_end,
-//        yaml_char_t **b_start, yaml_char_t **b_pointer, yaml_char_t **b_end)
-//{
-//    if (*b_start == *b_pointer)
-//        return 1;
-//
-//    while (*a_end - *a_pointer <= *b_pointer - *b_start) {
-//        if (!yaml_string_extend(a_start, a_pointer, a_end))
-//            return 0;
-//    }
-//
-//    memcpy(*a_pointer, *b_start, *b_pointer - *b_start);
-//    *a_pointer += *b_pointer - *b_start;
-//
-//    return 1;
-//}
-//
-///*
-// * Extend a stack.
-// */
-//
-//YAML_DECLARE(int)
-//yaml_stack_extend(void **start, void **top, void **end)
-//{
-//    void *new_start = yaml_realloc(*start, ((char *)*end - (char *)*start)*2);
-//
-//    if (!new_start) return 0;
-//
-//    *top = (char *)new_start + ((char *)*top - (char *)*start);
-//    *end = (char *)new_start + ((char *)*end - (char *)*start)*2;
-//    *start = new_start;
-//
-//    return 1;
-//}
-
 func yaml_insert_token(parser *yaml_parser_t, pos int, token *yaml_token_t) {
 	//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) {
@@ -87,21 +26,23 @@
 
 // Create a new parser object.
 func yaml_parser_initialize(parser *yaml_parser_t) bool {
-	// [Go] These should be initialized lazily, and probably start with smaller sizes.
-	parser.raw_buffer = make([]byte, 0, input_raw_buffer_size)
-	parser.buffer = make([]byte, 0, input_buffer_size)
-	parser.tokens = make([]yaml_token_t, 0, initial_queue_size)
-	parser.indents = make([]int, 0, initial_stack_size)
-	parser.simple_keys = make([]yaml_simple_key_t, 0, initial_stack_size)
-	parser.states = make([]yaml_parser_state_t, 0, initial_stack_size)
-	parser.marks = make([]yaml_mark_t, 0, initial_stack_size)
-	parser.tag_directives = make([]yaml_tag_directive_t, 0, initial_stack_size)
+	// [Go] These should be initialized lazily instead.
+	*parser = yaml_parser_t{
+		raw_buffer:     make([]byte, 0, input_raw_buffer_size),
+		buffer:         make([]byte, 0, input_buffer_size),
+		tokens:         make([]yaml_token_t, 0, initial_queue_size),
+		indents:        make([]int, 0, initial_stack_size),
+		simple_keys:    make([]yaml_simple_key_t, 0, initial_stack_size),
+		states:         make([]yaml_parser_state_t, 0, initial_stack_size),
+		marks:          make([]yaml_mark_t, 0, initial_stack_size),
+		tag_directives: make([]yaml_tag_directive_t, 0, initial_stack_size),
+	}
 	return true
 }
 
 // Destroy a parser object.
 func yaml_parser_delete(parser *yaml_parser_t) {
-    *parser = yaml_parser_t{}
+	*parser = yaml_parser_t{}
 }
 
 // String read handler.
@@ -138,248 +79,102 @@
 	parser.input_file = file
 }
 
-///*
-// * Set the source encoding.
-// */
-//
-//YAML_DECLARE(void)
-//yaml_parser_set_encoding(yaml_parser_t *parser, yaml_encoding_t encoding)
-//{
-//    assert(parser); // Non-NULL parser object expected.
-//    assert(!parser.encoding); // Encoding is already set or detected.
-//
-//    parser.encoding = encoding;
-//}
-//
-///*
-// * Create a new emitter object.
-// */
-//
-//YAML_DECLARE(int)
-//yaml_emitter_initialize(yaml_emitter_t *emitter)
-//{
-//    assert(emitter);    // Non-NULL emitter object expected.
-//
-//    memset(emitter, 0, sizeof(yaml_emitter_t));
-//    if (!BUFFER_INIT(emitter, emitter.buffer, OUTPUT_BUFFER_SIZE))
-//        goto error;
-//    if (!BUFFER_INIT(emitter, emitter.raw_buffer, OUTPUT_RAW_BUFFER_SIZE))
-//        goto error;
-//    if (!STACK_INIT(emitter, emitter.states, INITIAL_STACK_SIZE))
-//        goto error;
-//    if (!QUEUE_INIT(emitter, emitter.events, INITIAL_QUEUE_SIZE))
-//        goto error;
-//    if (!STACK_INIT(emitter, emitter.indents, INITIAL_STACK_SIZE))
-//        goto error;
-//    if (!STACK_INIT(emitter, emitter.tag_directives, INITIAL_STACK_SIZE))
-//        goto error;
-//
-//    return 1;
-//
-//error:
-//
-//    BUFFER_DEL(emitter, emitter.buffer);
-//    BUFFER_DEL(emitter, emitter.raw_buffer);
-//    STACK_DEL(emitter, emitter.states);
-//    QUEUE_DEL(emitter, emitter.events);
-//    STACK_DEL(emitter, emitter.indents);
-//    STACK_DEL(emitter, emitter.tag_directives);
-//
-//    return 0;
-//}
-//
-///*
-// * Destroy an emitter object.
-// */
-//
-//YAML_DECLARE(void)
-//yaml_emitter_delete(yaml_emitter_t *emitter)
-//{
-//    assert(emitter);    // Non-NULL emitter object expected.
-//
-//    BUFFER_DEL(emitter, emitter.buffer);
-//    BUFFER_DEL(emitter, emitter.raw_buffer);
-//    STACK_DEL(emitter, emitter.states);
-//    while (!QUEUE_EMPTY(emitter, emitter.events)) {
-//        yaml_event_delete(&DEQUEUE(emitter, emitter.events));
-//    }
-//    QUEUE_DEL(emitter, emitter.events);
-//    STACK_DEL(emitter, emitter.indents);
-//    while (!STACK_EMPTY(empty, emitter.tag_directives)) {
-//        yaml_tag_directive_t tag_directive = POP(emitter, emitter.tag_directives);
-//        yaml_free(tag_directive.handle);
-//        yaml_free(tag_directive.prefix);
-//    }
-//    STACK_DEL(emitter, emitter.tag_directives);
-//    yaml_free(emitter.anchors);
-//
-//    memset(emitter, 0, sizeof(yaml_emitter_t));
-//}
-//
-///*
-// * String write handler.
-// */
-//
-//static int
-//yaml_string_write_handler(void *data, unsigned char *buffer, size_t size)
-//{
-//    yaml_emitter_t *emitter = data;
-//
-//    if (emitter.output.string.size + *emitter.output.string.size_written
-//            < size) {
-//        memcpy(emitter.output.string.buffer
-//                + *emitter.output.string.size_written,
-//                buffer,
-//                emitter.output.string.size
-//                - *emitter.output.string.size_written);
-//        *emitter.output.string.size_written = emitter.output.string.size;
-//        return 0;
-//    }
-//
-//    memcpy(emitter.output.string.buffer
-//            + *emitter.output.string.size_written, buffer, size);
-//    *emitter.output.string.size_written += size;
-//    return 1;
-//}
-//
-///*
-// * File write handler.
-// */
-//
-//static int
-//yaml_file_write_handler(void *data, unsigned char *buffer, size_t size)
-//{
-//    yaml_emitter_t *emitter = data;
-//
-//    return (fwrite(buffer, 1, size, emitter.output.file) == size);
-//}
-///*
-// * Set a string output.
-// */
-//
-//YAML_DECLARE(void)
-//yaml_emitter_set_output_string(yaml_emitter_t *emitter,
-//        unsigned char *output, size_t size, size_t *size_written)
-//{
-//    assert(emitter);    // Non-NULL emitter object expected.
-//    assert(!emitter.write_handler);    // You can set the output only once.
-//    assert(output);     // Non-NULL output string expected.
-//
-//    emitter.write_handler = yaml_string_write_handler;
-//    emitter.write_handler_data = emitter;
-//
-//    emitter.output.string.buffer = output;
-//    emitter.output.string.size = size;
-//    emitter.output.string.size_written = size_written;
-//    *size_written = 0;
-//}
-//
-///*
-// * Set a file output.
-// */
-//
-//YAML_DECLARE(void)
-//yaml_emitter_set_output_file(yaml_emitter_t *emitter, FILE *file)
-//{
-//    assert(emitter);    // Non-NULL emitter object expected.
-//    assert(!emitter.write_handler);    // You can set the output only once.
-//    assert(file);       // Non-NULL file object expected.
-//
-//    emitter.write_handler = yaml_file_write_handler;
-//    emitter.write_handler_data = emitter;
-//
-//    emitter.output.file = file;
-//}
-//
-///*
-// * Set a generic output handler.
-// */
-//
-//YAML_DECLARE(void)
-//yaml_emitter_set_output(yaml_emitter_t *emitter,
-//        yaml_write_handler_t *handler, void *data)
-//{
-//    assert(emitter);    // Non-NULL emitter object expected.
-//    assert(!emitter.write_handler);    // You can set the output only once.
-//    assert(handler);    // Non-NULL handler object expected.
-//
-//    emitter.write_handler = handler;
-//    emitter.write_handler_data = data;
-//}
-//
-///*
-// * Set the output encoding.
-// */
-//
-//YAML_DECLARE(void)
-//yaml_emitter_set_encoding(yaml_emitter_t *emitter, yaml_encoding_t encoding)
-//{
-//    assert(emitter);    // Non-NULL emitter object expected.
-//    assert(!emitter.encoding);     // You can set encoding only once.
-//
-//    emitter.encoding = encoding;
-//}
-//
-///*
-// * Set the canonical output style.
-// */
-//
-//YAML_DECLARE(void)
-//yaml_emitter_set_canonical(yaml_emitter_t *emitter, int canonical)
-//{
-//    assert(emitter);    // Non-NULL emitter object expected.
-//
-//    emitter.canonical = (canonical != 0);
-//}
-//
-///*
-// * Set the indentation increment.
-// */
-//
-//YAML_DECLARE(void)
-//yaml_emitter_set_indent(yaml_emitter_t *emitter, int indent)
-//{
-//    assert(emitter);    // Non-NULL emitter object expected.
-//
-//    emitter.best_indent = (1 < indent && indent < 10) ? indent : 2;
-//}
-//
-///*
-// * Set the preferred line width.
-// */
-//
-//YAML_DECLARE(void)
-//yaml_emitter_set_width(yaml_emitter_t *emitter, int width)
-//{
-//    assert(emitter);    // Non-NULL emitter object expected.
-//
-//    emitter.best_width = (width >= 0) ? width : -1;
-//}
-//
-///*
-// * Set if unescaped non-ASCII characters are allowed.
-// */
-//
-//YAML_DECLARE(void)
-//yaml_emitter_set_unicode(yaml_emitter_t *emitter, int unicode)
-//{
-//    assert(emitter);    // Non-NULL emitter object expected.
-//
-//    emitter.unicode = (unicode != 0);
-//}
-//
-///*
-// * Set the preferred line break character.
-// */
-//
-//YAML_DECLARE(void)
-//yaml_emitter_set_break(yaml_emitter_t *emitter, yaml_break_t line_break)
-//{
-//    assert(emitter);    // Non-NULL emitter object expected.
-//
-//    emitter.line_break = line_break;
-//}
-//
+// Set the source encoding.
+func yaml_parser_set_encoding(parser *yaml_parser_t, encoding yaml_encoding_t) {
+	if parser.encoding != yaml_ANY_ENCODING {
+		panic("must set the encoding only once")
+	}
+	parser.encoding = encoding
+}
+
+// Create a new emitter object.
+func yaml_emitter_initialize(emitter *yaml_emitter_t) bool {
+	// [Go] These should be initialized lazily instead.
+	*emitter = yaml_emitter_t{
+		buffer:         make([]byte, 0, output_buffer_size),
+		raw_buffer:     make([]byte, 0, output_raw_buffer_size),
+		states:         make([]yaml_emitter_state_t, 0, initial_stack_size),
+		events:         make([]yaml_event_t, 0, initial_queue_size),
+		indents:        make([]int, 0, initial_stack_size),
+		tag_directives: make([]yaml_tag_directive_t, 0, initial_stack_size),
+	}
+	return true
+}
+
+// Destroy an emitter object.
+func yaml_emitter_delete(emitter *yaml_emitter_t) {
+	*emitter = yaml_emitter_t{}
+}
+
+// String write handler.
+func yaml_string_write_handler(emitter *yaml_emitter_t, buffer []byte) error {
+	*emitter.output_buffer = append(*emitter.output_buffer, buffer...)
+	return nil
+}
+
+// File write handler.
+func yaml_file_write_handler(emitter *yaml_emitter_t, buffer []byte) error {
+	_, err := emitter.output_file.Write(buffer)
+	return err
+}
+
+// Set a string output.
+func yaml_emitter_set_output_string(emitter *yaml_emitter_t, output_buffer *[]byte) {
+	if emitter.write_handler != nil {
+		panic("must set the output target only once")
+	}
+	emitter.write_handler = yaml_string_write_handler
+	emitter.output_buffer = output_buffer
+}
+
+// Set a file output.
+func yaml_emitter_set_output_file(emitter *yaml_emitter_t, file io.Writer) {
+	if emitter.write_handler != nil {
+		panic("must set the output target only once")
+	}
+	emitter.write_handler = yaml_file_write_handler
+	emitter.output_file = file
+}
+
+// Set the output encoding.
+func yaml_emitter_set_encoding(emitter *yaml_emitter_t, encoding yaml_encoding_t) {
+	if emitter.encoding != yaml_ANY_ENCODING {
+		panic("must set the output encoding only once")
+	}
+	emitter.encoding = encoding
+}
+
+// Set the canonical output style.
+func yaml_emitter_set_canonical(emitter *yaml_emitter_t, canonical bool) {
+	emitter.canonical = canonical
+}
+
+//// Set the indentation increment.
+func yaml_emitter_set_indent(emitter *yaml_emitter_t, indent int) {
+	if indent < 2 || indent > 9 {
+		indent = 2
+	}
+	emitter.best_indent = indent
+}
+
+// Set the preferred line width.
+func yaml_emitter_set_width(emitter *yaml_emitter_t, width int) {
+	if width < 0 {
+		width = -1
+	}
+	emitter.best_width = width
+}
+
+// Set if unescaped non-ASCII characters are allowed.
+func yaml_emitter_set_unicode(emitter *yaml_emitter_t, unicode bool) {
+	emitter.unicode = unicode
+}
+
+// Set the preferred line break character.
+func yaml_emitter_set_break(emitter *yaml_emitter_t, line_break yaml_break_t) {
+	emitter.line_break = line_break
+}
+
 ///*
 // * Destroy a token object.
 // */
@@ -465,340 +260,175 @@
 //    return 1;
 //}
 //
-///*
-// * Create STREAM-START.
-// */
-//
-//YAML_DECLARE(int)
-//yaml_stream_start_event_initialize(yaml_event_t *event,
-//        yaml_encoding_t encoding)
-//{
-//    yaml_mark_t mark = { 0, 0, 0 };
-//
-//    assert(event);  // Non-NULL event object is expected.
-//
-//    STREAM_START_EVENT_INIT(*event, encoding, mark, mark);
-		//*event = yaml_event_t{
-		//	typ:        yaml_STREAM_START_EVENT,
-		//	start_mark: mark,
-		//	end_mark:   mark,
-		//}
-		//event.stream_start.encoding = encoding
-//
-//    return 1;
-//}
-//
-///*
-// * Create STREAM-END.
-// */
-//
-//YAML_DECLARE(int)
-//yaml_stream_end_event_initialize(yaml_event_t *event)
-//{
-//    yaml_mark_t mark = { 0, 0, 0 };
-//
-//    assert(event);  // Non-NULL event object is expected.
-//
-//    STREAM_END_EVENT_INIT(*event, mark, mark);
-	//*event = yaml_event_t{
-	//	typ: yaml_STREAM_END_EVENT,
-	//	start_mark: mark,
-	//	end_mark: mark,
-	//}
-//
-//    return 1;
-//}
-//
-///*
-// * Create DOCUMENT-START.
-// */
-//
-//YAML_DECLARE(int)
-//yaml_document_start_event_initialize(yaml_event_t *event,
-//        yaml_version_directive_t *version_directive,
-//        yaml_tag_directive_t *tag_directives_start,
-//        yaml_tag_directive_t *tag_directives_end,
-//        int implicit)
-//{
-//    struct {
-//        yaml_error_type_t error;
-//    } context;
-//    yaml_mark_t mark = { 0, 0, 0 };
-//    yaml_version_directive_t *version_directive_copy = NULL;
-//    struct {
-//        yaml_tag_directive_t *start;
-//        yaml_tag_directive_t *end;
-//        yaml_tag_directive_t *top;
-//    } tag_directives_copy = { NULL, NULL, NULL };
-//    yaml_tag_directive_t value = { NULL, NULL };
-//
-//    assert(event);          // Non-NULL event object is expected.
-//    assert((tag_directives_start && tag_directives_end) ||
-//            (tag_directives_start == tag_directives_end));
-//                            // Valid tag directives are expected.
-//
-//    if (version_directive) {
-//        version_directive_copy = yaml_malloc(sizeof(yaml_version_directive_t));
-//        if (!version_directive_copy) goto error;
-//        version_directive_copy.major = version_directive.major;
-//        version_directive_copy.minor = version_directive.minor;
-//    }
-//
-//    if (tag_directives_start != tag_directives_end) {
-//        yaml_tag_directive_t *tag_directive;
-//        if (!STACK_INIT(&context, tag_directives_copy, INITIAL_STACK_SIZE))
-//            goto error;
-//        for (tag_directive = tag_directives_start;
-//                tag_directive != tag_directives_end; tag_directive ++) {
-//            assert(tag_directive.handle);
-//            assert(tag_directive.prefix);
-//            if (!yaml_check_utf8(tag_directive.handle,
-//                        strlen((char *)tag_directive.handle)))
-//                goto error;
-//            if (!yaml_check_utf8(tag_directive.prefix,
-//                        strlen((char *)tag_directive.prefix)))
-//                goto error;
-//            value.handle = yaml_strdup(tag_directive.handle);
-//            value.prefix = yaml_strdup(tag_directive.prefix);
-//            if (!value.handle || !value.prefix) goto error;
-//            if (!PUSH(&context, tag_directives_copy, value))
-//                goto error;
-//            value.handle = NULL;
-//            value.prefix = NULL;
-//        }
-//    }
-//
-//    DOCUMENT_START_EVENT_INIT(*event, version_directive_copy,
-//            tag_directives_copy.start, tag_directives_copy.top,
-//            implicit, mark, mark);
-	//*event = yaml_event_t{
-	//	typ: yaml_DOCUMENT_START_EVENT,
-	//	start_mark: mark,
-	//	end_mark: mark,
-	//}
-	//event.document_start.version_directive = version_directive_copy
-	//event.document_start.tag_directives = tag_directives
-	//event.document_start.implicit = implicit
-//
-//    return 1;
-//
-//error:
-//    yaml_free(version_directive_copy);
-//    while (!STACK_EMPTY(context, tag_directives_copy)) {
-//        yaml_tag_directive_t value = POP(context, tag_directives_copy);
-//        yaml_free(value.handle);
-//        yaml_free(value.prefix);
-//    }
-//    STACK_DEL(context, tag_directives_copy);
-//    yaml_free(value.handle);
-//    yaml_free(value.prefix);
-//
-//    return 0;
-//}
-//
-///*
-// * Create DOCUMENT-END.
-// */
-//
-//YAML_DECLARE(int)
-//yaml_document_end_event_initialize(yaml_event_t *event, int implicit)
-//{
-//    yaml_mark_t mark = { 0, 0, 0 };
-//
-//    assert(event);      // Non-NULL emitter object is expected.
-//
-//    DOCUMENT_END_EVENT_INIT(*event, implicit, mark, mark);
-//
-//    return 1;
-//}
-//
+
+// Create STREAM-START.
+func yaml_stream_start_event_initialize(event *yaml_event_t, encoding yaml_encoding_t) bool {
+	*event = yaml_event_t{
+		typ: yaml_STREAM_START_EVENT,
+	}
+	event.stream_start.encoding = encoding
+	return true
+}
+
+// Create STREAM-END.
+func yaml_stream_end_event_initialize(event *yaml_event_t) bool {
+	*event = yaml_event_t{
+		typ: yaml_STREAM_END_EVENT,
+	}
+	return true
+}
+
+// Create DOCUMENT-START.
+func yaml_document_start_event_initialize(event *yaml_event_t, version_directive *yaml_version_directive_t,
+	tag_directives []yaml_tag_directive_t, implicit bool) bool {
+
+	// [Go] It doesn't sound necessary to perform these copies
+	// given that with garbage collection ownership is handled.
+	var version_directive_copy *yaml_version_directive_t
+	var tag_directives_copy []yaml_tag_directive_t
+	if version_directive != nil {
+		copy := *version_directive
+		version_directive_copy = &copy
+	}
+	if len(tag_directives) > 0 {
+		tag_directives_copy = append([]yaml_tag_directive_t(nil), tag_directives...)
+	}
+
+	*event = yaml_event_t{
+		typ: yaml_DOCUMENT_START_EVENT,
+	}
+	event.document_start.version_directive = version_directive_copy
+	event.document_start.tag_directives = tag_directives_copy
+	event.document_start.implicit = implicit
+	return true
+}
+
+// Create DOCUMENT-END.
+func yaml_document_end_event_initialize(event *yaml_event_t, implicit bool) bool {
+	*event = yaml_event_t{
+		typ: yaml_DOCUMENT_END_EVENT,
+	}
+	event.document_end.implicit = implicit
+	return true
+}
+
 ///*
 // * Create ALIAS.
 // */
 //
 //YAML_DECLARE(int)
-//yaml_alias_event_initialize(yaml_event_t *event, yaml_char_t *anchor)
+//yaml_alias_event_initialize(event *yaml_event_t, anchor *yaml_char_t)
 //{
-//    yaml_mark_t mark = { 0, 0, 0 };
-//    yaml_char_t *anchor_copy = NULL;
+//    mark yaml_mark_t = { 0, 0, 0 }
+//    anchor_copy *yaml_char_t = NULL
 //
-//    assert(event);      // Non-NULL event object is expected.
-//    assert(anchor);     // Non-NULL anchor is expected.
+//    assert(event) // Non-NULL event object is expected.
+//    assert(anchor) // Non-NULL anchor is expected.
 //
-//    if (!yaml_check_utf8(anchor, strlen((char *)anchor))) return 0;
+//    if (!yaml_check_utf8(anchor, strlen((char *)anchor))) return 0
 //
-//    anchor_copy = yaml_strdup(anchor);
+//    anchor_copy = yaml_strdup(anchor)
 //    if (!anchor_copy)
-//        return 0;
+//        return 0
 //
-//    ALIAS_EVENT_INIT(*event, anchor_copy, mark, mark);
+//    ALIAS_EVENT_INIT(*event, anchor_copy, mark, mark)
 //
-//    return 1;
+//    return 1
 //}
-//
-///*
-// * Create SCALAR.
-// */
-//
-//YAML_DECLARE(int)
-//yaml_scalar_event_initialize(yaml_event_t *event,
-//        yaml_char_t *anchor, yaml_char_t *tag,
-//        yaml_char_t *value, int length,
-//        int plain_implicit, int quoted_implicit,
-//        yaml_scalar_style_t style)
-//{
-//    yaml_mark_t mark = { 0, 0, 0 };
-//    yaml_char_t *anchor_copy = NULL;
-//    yaml_char_t *tag_copy = NULL;
-//    yaml_char_t *value_copy = NULL;
-//
-//    assert(event);      // Non-NULL event object is expected.
-//    assert(value);      // Non-NULL anchor is expected.
-//
-//    if (anchor) {
-//        if (!yaml_check_utf8(anchor, strlen((char *)anchor))) goto error;
-//        anchor_copy = yaml_strdup(anchor);
-//        if (!anchor_copy) goto error;
-//    }
-//
-//    if (tag) {
-//        if (!yaml_check_utf8(tag, strlen((char *)tag))) goto error;
-//        tag_copy = yaml_strdup(tag);
-//        if (!tag_copy) goto error;
-//    }
-//
-//    if (length < 0) {
-//        length = strlen((char *)value);
-//    }
-//
-//    if (!yaml_check_utf8(value, length)) goto error;
-//    value_copy = yaml_malloc(length+1);
-//    if (!value_copy) goto error;
-//    memcpy(value_copy, value, length);
-//    value_copy[length] = '\0';
-//
-//    SCALAR_EVENT_INIT(*event, anchor_copy, tag_copy, value_copy, length,
-//            plain_implicit, quoted_implicit, style, mark, mark);
-//
-//    return 1;
-//
-//error:
-//    yaml_free(anchor_copy);
-//    yaml_free(tag_copy);
-//    yaml_free(value_copy);
-//
-//    return 0;
-//}
-//
-///*
-// * Create SEQUENCE-START.
-// */
-//
-//YAML_DECLARE(int)
-//yaml_sequence_start_event_initialize(yaml_event_t *event,
-//        yaml_char_t *anchor, yaml_char_t *tag, int implicit,
-//        yaml_sequence_style_t style)
-//{
-//    yaml_mark_t mark = { 0, 0, 0 };
-//    yaml_char_t *anchor_copy = NULL;
-//    yaml_char_t *tag_copy = NULL;
-//
-//    assert(event);      // Non-NULL event object is expected.
-//
-//    if (anchor) {
-//        if (!yaml_check_utf8(anchor, strlen((char *)anchor))) goto error;
-//        anchor_copy = yaml_strdup(anchor);
-//        if (!anchor_copy) goto error;
-//    }
-//
-//    if (tag) {
-//        if (!yaml_check_utf8(tag, strlen((char *)tag))) goto error;
-//        tag_copy = yaml_strdup(tag);
-//        if (!tag_copy) goto error;
-//    }
-//
-//    SEQUENCE_START_EVENT_INIT(*event, anchor_copy, tag_copy,
-//            implicit, style, mark, mark);
-//
-//    return 1;
-//
-//error:
-//    yaml_free(anchor_copy);
-//    yaml_free(tag_copy);
-//
-//    return 0;
-//}
-//
-///*
-// * Create SEQUENCE-END.
-// */
-//
-//YAML_DECLARE(int)
-//yaml_sequence_end_event_initialize(yaml_event_t *event)
-//{
-//    yaml_mark_t mark = { 0, 0, 0 };
-//
-//    assert(event);      // Non-NULL event object is expected.
-//
-//    SEQUENCE_END_EVENT_INIT(*event, mark, mark);
-//
-//    return 1;
-//}
-//
-///*
-// * Create MAPPING-START.
-// */
-//
-//YAML_DECLARE(int)
-//yaml_mapping_start_event_initialize(yaml_event_t *event,
-//        yaml_char_t *anchor, yaml_char_t *tag, int implicit,
-//        yaml_mapping_style_t style)
-//{
-//    yaml_mark_t mark = { 0, 0, 0 };
-//    yaml_char_t *anchor_copy = NULL;
-//    yaml_char_t *tag_copy = NULL;
-//
-//    assert(event);      // Non-NULL event object is expected.
-//
-//    if (anchor) {
-//        if (!yaml_check_utf8(anchor, strlen((char *)anchor))) goto error;
-//        anchor_copy = yaml_strdup(anchor);
-//        if (!anchor_copy) goto error;
-//    }
-//
-//    if (tag) {
-//        if (!yaml_check_utf8(tag, strlen((char *)tag))) goto error;
-//        tag_copy = yaml_strdup(tag);
-//        if (!tag_copy) goto error;
-//    }
-//
-//    MAPPING_START_EVENT_INIT(*event, anchor_copy, tag_copy,
-//            implicit, style, mark, mark);
-//
-//    return 1;
-//
-//error:
-//    yaml_free(anchor_copy);
-//    yaml_free(tag_copy);
-//
-//    return 0;
-//}
-//
-///*
-// * Create MAPPING-END.
-// */
-//
-//YAML_DECLARE(int)
-//yaml_mapping_end_event_initialize(yaml_event_t *event)
-//{
-//    yaml_mark_t mark = { 0, 0, 0 };
-//
-//    assert(event);      // Non-NULL event object is expected.
-//
-//    MAPPING_END_EVENT_INIT(*event, mark, mark);
-//
-//    return 1;
-//}
+
+// Create SCALAR.
+func yaml_scalar_event_initialize(event *yaml_event_t, anchor, tag, value []byte,
+	plain_implicit, quoted_implicit bool, style yaml_scalar_style_t) bool {
+	var anchor_copy, tag_copy, value_copy []byte
+
+	// [Go] These copies are probably not necessary in Go, where
+	// ownership of data is more flexible due to garbage collection.
+	if len(anchor) > 0 {
+		//if !yaml_check_utf8(anchor) { return false }
+		anchor_copy = append([]byte(nil), anchor...)
+	}
+	if len(tag) > 0 {
+		//if !yaml_check_utf8(tag) { return false }
+		tag_copy = append([]byte(nil), tag...)
+	}
+	//if !yaml_check_utf8(value) { return false }
+	value_copy = append([]byte(nil), value...)
+
+	*event = yaml_event_t{
+		typ: yaml_SCALAR_EVENT,
+	}
+	event.scalar.anchor = anchor_copy
+	event.scalar.tag = tag_copy
+	event.scalar.value = value_copy
+	event.scalar.plain_implicit = plain_implicit
+	event.scalar.quoted_implicit = quoted_implicit
+	event.scalar.style = style
+	return true
+}
+
+// Create SEQUENCE-START.
+func yaml_sequence_start_event_initialize(event *yaml_event_t, anchor, tag []byte, implicit bool, style yaml_sequence_style_t) bool {
+	// [Go] These copies are probably not necessary in Go, where
+	// ownership of data is more flexible due to garbage collection.
+	var anchor_copy, tag_copy []byte
+	if len(anchor) > 0 {
+		//if !yaml_check_utf8(anchor) { return false }
+		anchor_copy = append([]byte(nil), anchor...)
+	}
+	if len(tag) > 0 {
+		//if !yaml_check_utf8(tag) { return false }
+		tag_copy = append([]byte(nil), tag...)
+	}
+
+	*event = yaml_event_t{
+		typ: yaml_SEQUENCE_START_EVENT,
+	}
+	event.sequence_start.anchor = anchor_copy
+	event.sequence_start.tag = tag_copy
+	event.sequence_start.implicit = implicit
+	event.sequence_start.style = style
+	return true
+}
+
+// Create SEQUENCE-END.
+func yaml_sequence_end_event_initialize(event *yaml_event_t) bool {
+	*event = yaml_event_t{
+		typ: yaml_SEQUENCE_END_EVENT,
+	}
+	return true
+}
+
+// Create MAPPING-START.
+func yaml_mapping_start_event_initialize(event *yaml_event_t, anchor, tag []byte, implicit bool, style yaml_mapping_style_t) bool {
+	// [Go] These copies are probably not necessary in Go, where
+	// ownership of data is more flexible due to garbage collection.
+	var anchor_copy, tag_copy []byte
+	if len(anchor) > 0 {
+		//if !yaml_check_utf8(anchor) { return false }
+		anchor_copy = append([]byte(nil), anchor...)
+	}
+	if len(tag) > 0 {
+		//if !yaml_check_utf8(tag) { return false }
+		tag_copy = append([]byte(nil), tag...)
+	}
+
+	*event = yaml_event_t{
+		typ: yaml_MAPPING_START_EVENT,
+	}
+	event.mapping_start.anchor = anchor_copy
+	event.mapping_start.tag = tag_copy
+	event.mapping_start.implicit = implicit
+	event.mapping_start.style = style
+	return true
+}
+
+// Create MAPPING-END.
+func yaml_mapping_end_event_initialize(event *yaml_event_t) bool {
+	*event = yaml_event_t{
+		typ: yaml_MAPPING_END_EVENT,
+	}
+	return true
+}
 
 // Destroy an event object.
 func yaml_event_delete(event *yaml_event_t) {
@@ -810,86 +440,86 @@
 // */
 //
 //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)
+//yaml_document_initialize(document *yaml_document_t,
+//        version_directive *yaml_version_directive_t,
+//        tag_directives_start *yaml_tag_directive_t,
+//        tag_directives_end *yaml_tag_directive_t,
+//        start_implicit int, end_implicit int)
 //{
 //    struct {
-//        yaml_error_type_t error;
-//    } context;
+//        error yaml_error_type_t
+//    } context
 //    struct {
-//        yaml_node_t *start;
-//        yaml_node_t *end;
-//        yaml_node_t *top;
-//    } nodes = { NULL, NULL, NULL };
-//    yaml_version_directive_t *version_directive_copy = NULL;
+//        start *yaml_node_t
+//        end *yaml_node_t
+//        top *yaml_node_t
+//    } nodes = { NULL, NULL, NULL }
+//    version_directive_copy *yaml_version_directive_t = NULL
 //    struct {
-//        yaml_tag_directive_t *start;
-//        yaml_tag_directive_t *end;
-//        yaml_tag_directive_t *top;
-//    } tag_directives_copy = { NULL, NULL, NULL };
-//    yaml_tag_directive_t value = { NULL, NULL };
-//    yaml_mark_t mark = { 0, 0, 0 };
+//        start *yaml_tag_directive_t
+//        end *yaml_tag_directive_t
+//        top *yaml_tag_directive_t
+//    } tag_directives_copy = { NULL, NULL, NULL }
+//    value yaml_tag_directive_t = { NULL, NULL }
+//    mark yaml_mark_t = { 0, 0, 0 }
 //
-//    assert(document);       // Non-NULL document object is expected.
+//    assert(document) // Non-NULL document object is expected.
 //    assert((tag_directives_start && tag_directives_end) ||
-//            (tag_directives_start == tag_directives_end));
+//            (tag_directives_start == tag_directives_end))
 //                            // Valid tag directives are expected.
 //
-//    if (!STACK_INIT(&context, nodes, INITIAL_STACK_SIZE)) goto error;
+//    if (!STACK_INIT(&context, nodes, INITIAL_STACK_SIZE)) goto error
 //
 //    if (version_directive) {
-//        version_directive_copy = yaml_malloc(sizeof(yaml_version_directive_t));
-//        if (!version_directive_copy) goto error;
-//        version_directive_copy.major = version_directive.major;
-//        version_directive_copy.minor = version_directive.minor;
+//        version_directive_copy = yaml_malloc(sizeof(yaml_version_directive_t))
+//        if (!version_directive_copy) goto error
+//        version_directive_copy.major = version_directive.major
+//        version_directive_copy.minor = version_directive.minor
 //    }
 //
 //    if (tag_directives_start != tag_directives_end) {
-//        yaml_tag_directive_t *tag_directive;
+//        tag_directive *yaml_tag_directive_t
 //        if (!STACK_INIT(&context, tag_directives_copy, INITIAL_STACK_SIZE))
-//            goto error;
-//        for (tag_directive = tag_directives_start;
+//            goto error
+//        for (tag_directive = tag_directives_start
 //                tag_directive != tag_directives_end; tag_directive ++) {
-//            assert(tag_directive.handle);
-//            assert(tag_directive.prefix);
+//            assert(tag_directive.handle)
+//            assert(tag_directive.prefix)
 //            if (!yaml_check_utf8(tag_directive.handle,
 //                        strlen((char *)tag_directive.handle)))
-//                goto error;
+//                goto error
 //            if (!yaml_check_utf8(tag_directive.prefix,
 //                        strlen((char *)tag_directive.prefix)))
-//                goto error;
-//            value.handle = yaml_strdup(tag_directive.handle);
-//            value.prefix = yaml_strdup(tag_directive.prefix);
-//            if (!value.handle || !value.prefix) goto error;
+//                goto error
+//            value.handle = yaml_strdup(tag_directive.handle)
+//            value.prefix = yaml_strdup(tag_directive.prefix)
+//            if (!value.handle || !value.prefix) goto error
 //            if (!PUSH(&context, tag_directives_copy, value))
-//                goto error;
-//            value.handle = NULL;
-//            value.prefix = NULL;
+//                goto error
+//            value.handle = NULL
+//            value.prefix = NULL
 //        }
 //    }
 //
 //    DOCUMENT_INIT(*document, nodes.start, nodes.end, version_directive_copy,
 //            tag_directives_copy.start, tag_directives_copy.top,
-//            start_implicit, end_implicit, mark, mark);
+//            start_implicit, end_implicit, mark, mark)
 //
-//    return 1;
+//    return 1
 //
 //error:
-//    STACK_DEL(&context, nodes);
-//    yaml_free(version_directive_copy);
+//    STACK_DEL(&context, nodes)
+//    yaml_free(version_directive_copy)
 //    while (!STACK_EMPTY(&context, tag_directives_copy)) {
-//        yaml_tag_directive_t value = POP(&context, tag_directives_copy);
-//        yaml_free(value.handle);
-//        yaml_free(value.prefix);
+//        value yaml_tag_directive_t = POP(&context, tag_directives_copy)
+//        yaml_free(value.handle)
+//        yaml_free(value.prefix)
 //    }
-//    STACK_DEL(&context, tag_directives_copy);
-//    yaml_free(value.handle);
-//    yaml_free(value.prefix);
+//    STACK_DEL(&context, tag_directives_copy)
+//    yaml_free(value.handle)
+//    yaml_free(value.prefix)
 //
-//    return 0;
+//    return 0
 //}
 //
 ///*
@@ -897,46 +527,46 @@
 // */
 //
 //YAML_DECLARE(void)
-//yaml_document_delete(yaml_document_t *document)
+//yaml_document_delete(document *yaml_document_t)
 //{
 //    struct {
-//        yaml_error_type_t error;
-//    } context;
-//    yaml_tag_directive_t *tag_directive;
+//        error yaml_error_type_t
+//    } context
+//    tag_directive *yaml_tag_directive_t
 //
-//    context.error = YAML_NO_ERROR;  // Eliminate a compliler warning.
+//    context.error = YAML_NO_ERROR // Eliminate a compliler warning.
 //
-//    assert(document);   // Non-NULL document object is expected.
+//    assert(document) // Non-NULL document object is expected.
 //
 //    while (!STACK_EMPTY(&context, document.nodes)) {
-//        yaml_node_t node = POP(&context, document.nodes);
-//        yaml_free(node.tag);
+//        node yaml_node_t = POP(&context, document.nodes)
+//        yaml_free(node.tag)
 //        switch (node.type) {
 //            case YAML_SCALAR_NODE:
-//                yaml_free(node.data.scalar.value);
-//                break;
+//                yaml_free(node.data.scalar.value)
+//                break
 //            case YAML_SEQUENCE_NODE:
-//                STACK_DEL(&context, node.data.sequence.items);
-//                break;
+//                STACK_DEL(&context, node.data.sequence.items)
+//                break
 //            case YAML_MAPPING_NODE:
-//                STACK_DEL(&context, node.data.mapping.pairs);
-//                break;
+//                STACK_DEL(&context, node.data.mapping.pairs)
+//                break
 //            default:
-//                assert(0);  // Should not happen.
+//                assert(0) // Should not happen.
 //        }
 //    }
-//    STACK_DEL(&context, document.nodes);
+//    STACK_DEL(&context, document.nodes)
 //
-//    yaml_free(document.version_directive);
-//    for (tag_directive = document.tag_directives.start;
-//            tag_directive != document.tag_directives.end;
+//    yaml_free(document.version_directive)
+//    for (tag_directive = document.tag_directives.start
+//            tag_directive != document.tag_directives.end
 //            tag_directive++) {
-//        yaml_free(tag_directive.handle);
-//        yaml_free(tag_directive.prefix);
+//        yaml_free(tag_directive.handle)
+//        yaml_free(tag_directive.prefix)
 //    }
-//    yaml_free(document.tag_directives.start);
+//    yaml_free(document.tag_directives.start)
 //
-//    memset(document, 0, sizeof(yaml_document_t));
+//    memset(document, 0, sizeof(yaml_document_t))
 //}
 //
 ///**
@@ -944,14 +574,14 @@
 // */
 //
 //YAML_DECLARE(yaml_node_t *)
-//yaml_document_get_node(yaml_document_t *document, int index)
+//yaml_document_get_node(document *yaml_document_t, index int)
 //{
-//    assert(document);   // Non-NULL document object is expected.
+//    assert(document) // Non-NULL document object is expected.
 //
 //    if (index > 0 && document.nodes.start + index <= document.nodes.top) {
-//        return document.nodes.start + index - 1;
+//        return document.nodes.start + index - 1
 //    }
-//    return NULL;
+//    return NULL
 //}
 //
 ///**
@@ -959,14 +589,14 @@
 // */
 //
 //YAML_DECLARE(yaml_node_t *)
-//yaml_document_get_root_node(yaml_document_t *document)
+//yaml_document_get_root_node(document *yaml_document_t)
 //{
-//    assert(document);   // Non-NULL document object is expected.
+//    assert(document) // Non-NULL document object is expected.
 //
 //    if (document.nodes.top != document.nodes.start) {
-//        return document.nodes.start;
+//        return document.nodes.start
 //    }
-//    return NULL;
+//    return NULL
 //}
 //
 ///*
@@ -974,49 +604,49 @@
 // */
 //
 //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)
+//yaml_document_add_scalar(document *yaml_document_t,
+//        tag *yaml_char_t, value *yaml_char_t, length int,
+//        style yaml_scalar_style_t)
 //{
 //    struct {
-//        yaml_error_type_t error;
-//    } context;
-//    yaml_mark_t mark = { 0, 0, 0 };
-//    yaml_char_t *tag_copy = NULL;
-//    yaml_char_t *value_copy = NULL;
-//    yaml_node_t node;
+//        error yaml_error_type_t
+//    } context
+//    mark yaml_mark_t = { 0, 0, 0 }
+//    tag_copy *yaml_char_t = NULL
+//    value_copy *yaml_char_t = NULL
+//    node yaml_node_t
 //
-//    assert(document);   // Non-NULL document object is expected.
-//    assert(value);      // Non-NULL value is expected.
+//    assert(document) // Non-NULL document object is expected.
+//    assert(value) // Non-NULL value is expected.
 //
 //    if (!tag) {
-//        tag = (yaml_char_t *)YAML_DEFAULT_SCALAR_TAG;
+//        tag = (yaml_char_t *)YAML_DEFAULT_SCALAR_TAG
 //    }
 //
-//    if (!yaml_check_utf8(tag, strlen((char *)tag))) goto error;
-//    tag_copy = yaml_strdup(tag);
-//    if (!tag_copy) goto error;
+//    if (!yaml_check_utf8(tag, strlen((char *)tag))) goto error
+//    tag_copy = yaml_strdup(tag)
+//    if (!tag_copy) goto error
 //
 //    if (length < 0) {
-//        length = strlen((char *)value);
+//        length = strlen((char *)value)
 //    }
 //
-//    if (!yaml_check_utf8(value, length)) goto error;
-//    value_copy = yaml_malloc(length+1);
-//    if (!value_copy) goto error;
-//    memcpy(value_copy, value, length);
-//    value_copy[length] = '\0';
+//    if (!yaml_check_utf8(value, length)) goto error
+//    value_copy = yaml_malloc(length+1)
+//    if (!value_copy) goto error
+//    memcpy(value_copy, value, length)
+//    value_copy[length] = '\0'
 //
-//    SCALAR_NODE_INIT(node, tag_copy, value_copy, length, style, mark, mark);
-//    if (!PUSH(&context, document.nodes, node)) goto error;
+//    SCALAR_NODE_INIT(node, tag_copy, value_copy, length, style, mark, mark)
+//    if (!PUSH(&context, document.nodes, node)) goto error
 //
-//    return document.nodes.top - document.nodes.start;
+//    return document.nodes.top - document.nodes.start
 //
 //error:
-//    yaml_free(tag_copy);
-//    yaml_free(value_copy);
+//    yaml_free(tag_copy)
+//    yaml_free(value_copy)
 //
-//    return 0;
+//    return 0
 //}
 //
 ///*
@@ -1024,44 +654,44 @@
 // */
 //
 //YAML_DECLARE(int)
-//yaml_document_add_sequence(yaml_document_t *document,
-//        yaml_char_t *tag, yaml_sequence_style_t style)
+//yaml_document_add_sequence(document *yaml_document_t,
+//        tag *yaml_char_t, style yaml_sequence_style_t)
 //{
 //    struct {
-//        yaml_error_type_t error;
-//    } context;
-//    yaml_mark_t mark = { 0, 0, 0 };
-//    yaml_char_t *tag_copy = NULL;
+//        error yaml_error_type_t
+//    } context
+//    mark yaml_mark_t = { 0, 0, 0 }
+//    tag_copy *yaml_char_t = NULL
 //    struct {
-//        yaml_node_item_t *start;
-//        yaml_node_item_t *end;
-//        yaml_node_item_t *top;
-//    } items = { NULL, NULL, NULL };
-//    yaml_node_t node;
+//        start *yaml_node_item_t
+//        end *yaml_node_item_t
+//        top *yaml_node_item_t
+//    } items = { NULL, NULL, NULL }
+//    node yaml_node_t
 //
-//    assert(document);   // Non-NULL document object is expected.
+//    assert(document) // Non-NULL document object is expected.
 //
 //    if (!tag) {
-//        tag = (yaml_char_t *)YAML_DEFAULT_SEQUENCE_TAG;
+//        tag = (yaml_char_t *)YAML_DEFAULT_SEQUENCE_TAG
 //    }
 //
-//    if (!yaml_check_utf8(tag, strlen((char *)tag))) goto error;
-//    tag_copy = yaml_strdup(tag);
-//    if (!tag_copy) goto error;
+//    if (!yaml_check_utf8(tag, strlen((char *)tag))) goto error
+//    tag_copy = yaml_strdup(tag)
+//    if (!tag_copy) goto error
 //
-//    if (!STACK_INIT(&context, items, INITIAL_STACK_SIZE)) goto error;
+//    if (!STACK_INIT(&context, items, INITIAL_STACK_SIZE)) goto error
 //
 //    SEQUENCE_NODE_INIT(node, tag_copy, items.start, items.end,
-//            style, mark, mark);
-//    if (!PUSH(&context, document.nodes, node)) goto error;
+//            style, mark, mark)
+//    if (!PUSH(&context, document.nodes, node)) goto error
 //
-//    return document.nodes.top - document.nodes.start;
+//    return document.nodes.top - document.nodes.start
 //
 //error:
-//    STACK_DEL(&context, items);
-//    yaml_free(tag_copy);
+//    STACK_DEL(&context, items)
+//    yaml_free(tag_copy)
 //
-//    return 0;
+//    return 0
 //}
 //
 ///*
@@ -1069,44 +699,44 @@
 // */
 //
 //YAML_DECLARE(int)
-//yaml_document_add_mapping(yaml_document_t *document,
-//        yaml_char_t *tag, yaml_mapping_style_t style)
+//yaml_document_add_mapping(document *yaml_document_t,
+//        tag *yaml_char_t, style yaml_mapping_style_t)
 //{
 //    struct {
-//        yaml_error_type_t error;
-//    } context;
-//    yaml_mark_t mark = { 0, 0, 0 };
-//    yaml_char_t *tag_copy = NULL;
+//        error yaml_error_type_t
+//    } context
+//    mark yaml_mark_t = { 0, 0, 0 }
+//    tag_copy *yaml_char_t = NULL
 //    struct {
-//        yaml_node_pair_t *start;
-//        yaml_node_pair_t *end;
-//        yaml_node_pair_t *top;
-//    } pairs = { NULL, NULL, NULL };
-//    yaml_node_t node;
+//        start *yaml_node_pair_t
+//        end *yaml_node_pair_t
+//        top *yaml_node_pair_t
+//    } pairs = { NULL, NULL, NULL }
+//    node yaml_node_t
 //
-//    assert(document);   // Non-NULL document object is expected.
+//    assert(document) // Non-NULL document object is expected.
 //
 //    if (!tag) {
-//        tag = (yaml_char_t *)YAML_DEFAULT_MAPPING_TAG;
+//        tag = (yaml_char_t *)YAML_DEFAULT_MAPPING_TAG
 //    }
 //
-//    if (!yaml_check_utf8(tag, strlen((char *)tag))) goto error;
-//    tag_copy = yaml_strdup(tag);
-//    if (!tag_copy) goto error;
+//    if (!yaml_check_utf8(tag, strlen((char *)tag))) goto error
+//    tag_copy = yaml_strdup(tag)
+//    if (!tag_copy) goto error
 //
-//    if (!STACK_INIT(&context, pairs, INITIAL_STACK_SIZE)) goto error;
+//    if (!STACK_INIT(&context, pairs, INITIAL_STACK_SIZE)) goto error
 //
 //    MAPPING_NODE_INIT(node, tag_copy, pairs.start, pairs.end,
-//            style, mark, mark);
-//    if (!PUSH(&context, document.nodes, node)) goto error;
+//            style, mark, mark)
+//    if (!PUSH(&context, document.nodes, node)) goto error
 //
-//    return document.nodes.top - document.nodes.start;
+//    return document.nodes.top - document.nodes.start
 //
 //error:
-//    STACK_DEL(&context, pairs);
-//    yaml_free(tag_copy);
+//    STACK_DEL(&context, pairs)
+//    yaml_free(tag_copy)
 //
-//    return 0;
+//    return 0
 //}
 //
 ///*
@@ -1114,27 +744,27 @@
 // */
 //
 //YAML_DECLARE(int)
-//yaml_document_append_sequence_item(yaml_document_t *document,
-//        int sequence, int item)
+//yaml_document_append_sequence_item(document *yaml_document_t,
+//        sequence int, item int)
 //{
 //    struct {
-//        yaml_error_type_t error;
-//    } context;
+//        error yaml_error_type_t
+//    } context
 //
-//    assert(document);       // Non-NULL document is required.
+//    assert(document) // Non-NULL document is required.
 //    assert(sequence > 0
-//            && document.nodes.start + sequence <= document.nodes.top);
+//            && document.nodes.start + sequence <= document.nodes.top)
 //                            // Valid sequence id is required.
-//    assert(document.nodes.start[sequence-1].type == YAML_SEQUENCE_NODE);
+//    assert(document.nodes.start[sequence-1].type == YAML_SEQUENCE_NODE)
 //                            // A sequence node is required.
-//    assert(item > 0 && document.nodes.start + item <= document.nodes.top);
+//    assert(item > 0 && document.nodes.start + item <= document.nodes.top)
 //                            // Valid item id is required.
 //
 //    if (!PUSH(&context,
 //                document.nodes.start[sequence-1].data.sequence.items, item))
-//        return 0;
+//        return 0
 //
-//    return 1;
+//    return 1
 //}
 //
 ///*
@@ -1142,34 +772,34 @@
 // */
 //
 //YAML_DECLARE(int)
-//yaml_document_append_mapping_pair(yaml_document_t *document,
-//        int mapping, int key, int value)
+//yaml_document_append_mapping_pair(document *yaml_document_t,
+//        mapping int, key int, value int)
 //{
 //    struct {
-//        yaml_error_type_t error;
-//    } context;
+//        error yaml_error_type_t
+//    } context
 //
-//    yaml_node_pair_t pair;
+//    pair yaml_node_pair_t
 //
-//    assert(document);       // Non-NULL document is required.
+//    assert(document) // Non-NULL document is required.
 //    assert(mapping > 0
-//            && document.nodes.start + mapping <= document.nodes.top);
+//            && document.nodes.start + mapping <= document.nodes.top)
 //                            // Valid mapping id is required.
-//    assert(document.nodes.start[mapping-1].type == YAML_MAPPING_NODE);
+//    assert(document.nodes.start[mapping-1].type == YAML_MAPPING_NODE)
 //                            // A mapping node is required.
-//    assert(key > 0 && document.nodes.start + key <= document.nodes.top);
+//    assert(key > 0 && document.nodes.start + key <= document.nodes.top)
 //                            // Valid key id is required.
-//    assert(value > 0 && document.nodes.start + value <= document.nodes.top);
+//    assert(value > 0 && document.nodes.start + value <= document.nodes.top)
 //                            // Valid value id is required.
 //
-//    pair.key = key;
-//    pair.value = value;
+//    pair.key = key
+//    pair.value = value
 //
 //    if (!PUSH(&context,
 //                document.nodes.start[mapping-1].data.mapping.pairs, pair))
-//        return 0;
+//        return 0
 //
-//    return 1;
+//    return 1
 //}
 //
 //
diff --git a/emitter_c.go b/emitter_c.go
new file mode 100644
index 0000000..a97d406
--- /dev/null
+++ b/emitter_c.go
@@ -0,0 +1,2330 @@
+package goyaml
+
+//#include "yaml_private.h"
+//
+///*
+// * Flush the buffer if needed.
+// */
+//
+//#define FLUSH(emitter)                                                          \
+//    ((emitter->buffer.pointer+5 < emitter->buffer.end)                          \
+//     || yaml_emitter_flush(emitter))
+//
+///*
+// * Put a character to the output buffer.
+// */
+//
+//#define PUT(emitter,value)                                                      \
+//    (FLUSH(emitter)                                                             \
+//     && (*(emitter->buffer.pointer++) = (yaml_char_t)(value),                   \
+//         emitter->column ++,                                                    \
+//         1))
+//
+///*
+// * Put a line break to the output buffer.
+// */
+//
+//#define PUT_BREAK(emitter)                                                      \
+//    (FLUSH(emitter)                                                             \
+//     && ((emitter->line_break == YAML_CR_BREAK ?                                \
+//             (*(emitter->buffer.pointer++) = (yaml_char_t) '\r') :              \
+//          emitter->line_break == YAML_LN_BREAK ?                                \
+//             (*(emitter->buffer.pointer++) = (yaml_char_t) '\n') :              \
+//          emitter->line_break == YAML_CRLN_BREAK ?                              \
+//             (*(emitter->buffer.pointer++) = (yaml_char_t) '\r',                \
+//              *(emitter->buffer.pointer++) = (yaml_char_t) '\n') : 0),          \
+//         emitter->column = 0,                                                   \
+//         emitter->line ++,                                                      \
+//         1))
+//
+///*
+// * Copy a character from a string into buffer.
+// */
+//
+//#define WRITE(emitter,string)                                                   \
+//    (FLUSH(emitter)                                                             \
+//     && (COPY(emitter->buffer,string),                                          \
+//         emitter->column ++,                                                    \
+//         1))
+//
+///*
+// * Copy a line break character from a string into buffer.
+// */
+//
+//#define WRITE_BREAK(emitter,string)                                             \
+//    (FLUSH(emitter)                                                             \
+//     && (CHECK(string,'\n') ?                                                   \
+//         (PUT_BREAK(emitter),                                                   \
+//          string.pointer ++,                                                    \
+//          1) :                                                                  \
+//         (COPY(emitter->buffer,string),                                         \
+//          emitter->column = 0,                                                  \
+//          emitter->line ++,                                                     \
+//          1)))
+//
+///*
+// * API functions.
+// */
+//
+//YAML_DECLARE(int)
+//yaml_emitter_emit(yaml_emitter_t *emitter, yaml_event_t *event);
+//
+///*
+// * Utility functions.
+// */
+//
+//static int
+//yaml_emitter_set_emitter_error(yaml_emitter_t *emitter, const char *problem);
+//
+//static int
+//yaml_emitter_need_more_events(yaml_emitter_t *emitter);
+//
+//static int
+//yaml_emitter_append_tag_directive(yaml_emitter_t *emitter,
+//        yaml_tag_directive_t value, int allow_duplicates);
+//
+//static int
+//yaml_emitter_increase_indent(yaml_emitter_t *emitter,
+//        int flow, int indentless);
+//
+///*
+// * State functions.
+// */
+//
+//static int
+//yaml_emitter_state_machine(yaml_emitter_t *emitter, yaml_event_t *event);
+//
+//static int
+//yaml_emitter_emit_stream_start(yaml_emitter_t *emitter,
+//        yaml_event_t *event);
+//
+//static int
+//yaml_emitter_emit_document_start(yaml_emitter_t *emitter,
+//        yaml_event_t *event, int first);
+//
+//static int
+//yaml_emitter_emit_document_content(yaml_emitter_t *emitter,
+//        yaml_event_t *event);
+//
+//static int
+//yaml_emitter_emit_document_end(yaml_emitter_t *emitter,
+//        yaml_event_t *event);
+//
+//static int
+//yaml_emitter_emit_flow_sequence_item(yaml_emitter_t *emitter,
+//        yaml_event_t *event, int first);
+//
+//static int
+//yaml_emitter_emit_flow_mapping_key(yaml_emitter_t *emitter,
+//        yaml_event_t *event, int first);
+//
+//static int
+//yaml_emitter_emit_flow_mapping_value(yaml_emitter_t *emitter,
+//        yaml_event_t *event, int simple);
+//
+//static int
+//yaml_emitter_emit_block_sequence_item(yaml_emitter_t *emitter,
+//        yaml_event_t *event, int first);
+//
+//static int
+//yaml_emitter_emit_block_mapping_key(yaml_emitter_t *emitter,
+//        yaml_event_t *event, int first);
+//
+//static int
+//yaml_emitter_emit_block_mapping_value(yaml_emitter_t *emitter,
+//        yaml_event_t *event, int simple);
+//
+//static int
+//yaml_emitter_emit_node(yaml_emitter_t *emitter, yaml_event_t *event,
+//        int root, int sequence, int mapping, int simple_key);
+//
+//static int
+//yaml_emitter_emit_alias(yaml_emitter_t *emitter, yaml_event_t *event);
+//
+//static int
+//yaml_emitter_emit_scalar(yaml_emitter_t *emitter, yaml_event_t *event);
+//
+//static int
+//yaml_emitter_emit_sequence_start(yaml_emitter_t *emitter, yaml_event_t *event);
+//
+//static int
+//yaml_emitter_emit_mapping_start(yaml_emitter_t *emitter, yaml_event_t *event);
+//
+///*
+// * Checkers.
+// */
+//
+//static int
+//yaml_emitter_check_empty_document(yaml_emitter_t *emitter);
+//
+//static int
+//yaml_emitter_check_empty_sequence(yaml_emitter_t *emitter);
+//
+//static int
+//yaml_emitter_check_empty_mapping(yaml_emitter_t *emitter);
+//
+//static int
+//yaml_emitter_check_simple_key(yaml_emitter_t *emitter);
+//
+//static int
+//yaml_emitter_select_scalar_style(yaml_emitter_t *emitter, yaml_event_t *event);
+//
+///*
+// * Processors.
+// */
+//
+//static int
+//yaml_emitter_process_anchor(yaml_emitter_t *emitter);
+//
+//static int
+//yaml_emitter_process_tag(yaml_emitter_t *emitter);
+//
+//static int
+//yaml_emitter_process_scalar(yaml_emitter_t *emitter);
+//
+///*
+// * Analyzers.
+// */
+//
+//static int
+//yaml_emitter_analyze_version_directive(yaml_emitter_t *emitter,
+//        yaml_version_directive_t version_directive);
+//
+//static int
+//yaml_emitter_analyze_tag_directive(yaml_emitter_t *emitter,
+//        yaml_tag_directive_t tag_directive);
+//
+//static int
+//yaml_emitter_analyze_anchor(yaml_emitter_t *emitter,
+//        yaml_char_t *anchor, int alias);
+//
+//static int
+//yaml_emitter_analyze_tag(yaml_emitter_t *emitter,
+//        yaml_char_t *tag);
+//
+//static int
+//yaml_emitter_analyze_scalar(yaml_emitter_t *emitter,
+//        yaml_char_t *value, size_t length);
+//
+//static int
+//yaml_emitter_analyze_event(yaml_emitter_t *emitter,
+//        yaml_event_t *event);
+//
+///*
+// * Writers.
+// */
+//
+//static int
+//yaml_emitter_write_bom(yaml_emitter_t *emitter);
+//
+//static int
+//yaml_emitter_write_indent(yaml_emitter_t *emitter);
+//
+//static int
+//yaml_emitter_write_indicator(yaml_emitter_t *emitter,
+//        char *indicator, int need_whitespace,
+//        int is_whitespace, int is_indention);
+//
+//static int
+//yaml_emitter_write_anchor(yaml_emitter_t *emitter,
+//        yaml_char_t *value, size_t length);
+//
+//static int
+//yaml_emitter_write_tag_handle(yaml_emitter_t *emitter,
+//        yaml_char_t *value, size_t length);
+//
+//static int
+//yaml_emitter_write_tag_content(yaml_emitter_t *emitter,
+//        yaml_char_t *value, size_t length, int need_whitespace);
+//
+//static int
+//yaml_emitter_write_plain_scalar(yaml_emitter_t *emitter,
+//        yaml_char_t *value, size_t length, int allow_breaks);
+//
+//static int
+//yaml_emitter_write_single_quoted_scalar(yaml_emitter_t *emitter,
+//        yaml_char_t *value, size_t length, int allow_breaks);
+//
+//static int
+//yaml_emitter_write_double_quoted_scalar(yaml_emitter_t *emitter,
+//        yaml_char_t *value, size_t length, int allow_breaks);
+//
+//static int
+//yaml_emitter_write_block_scalar_hints(yaml_emitter_t *emitter,
+//        yaml_string_t string);
+//
+//static int
+//yaml_emitter_write_literal_scalar(yaml_emitter_t *emitter,
+//        yaml_char_t *value, size_t length);
+//
+//static int
+//yaml_emitter_write_folded_scalar(yaml_emitter_t *emitter,
+//        yaml_char_t *value, size_t length);
+//
+///*
+// * Set an emitter error and return 0.
+// */
+//
+//static int
+//yaml_emitter_set_emitter_error(yaml_emitter_t *emitter, const char *problem)
+//{
+//    emitter->error = YAML_EMITTER_ERROR;
+//    emitter->problem = problem;
+//
+//    return 0;
+//}
+//
+///*
+// * Emit an event.
+// */
+//
+//YAML_DECLARE(int)
+//yaml_emitter_emit(yaml_emitter_t *emitter, yaml_event_t *event)
+//{
+//    if (!ENQUEUE(emitter, emitter->events, *event)) {
+//        yaml_event_delete(event);
+//        return 0;
+//    }
+//
+//    while (!yaml_emitter_need_more_events(emitter)) {
+//        if (!yaml_emitter_analyze_event(emitter, emitter->events.head))
+//            return 0;
+//        if (!yaml_emitter_state_machine(emitter, emitter->events.head))
+//            return 0;
+//        yaml_event_delete(&DEQUEUE(emitter, emitter->events));
+//    }
+//
+//    return 1;
+//}
+//
+///*
+// * Check if we need to accumulate more events before emitting.
+// *
+// * We accumulate extra
+// *  - 1 event for DOCUMENT-START
+// *  - 2 events for SEQUENCE-START
+// *  - 3 events for MAPPING-START
+// */
+//
+//static int
+//yaml_emitter_need_more_events(yaml_emitter_t *emitter)
+//{
+//    int level = 0;
+//    int accumulate = 0;
+//    yaml_event_t *event;
+//
+//    if (QUEUE_EMPTY(emitter, emitter->events))
+//        return 1;
+//
+//    switch (emitter->events.head->type) {
+//        case YAML_DOCUMENT_START_EVENT:
+//            accumulate = 1;
+//            break;
+//        case YAML_SEQUENCE_START_EVENT:
+//            accumulate = 2;
+//            break;
+//        case YAML_MAPPING_START_EVENT:
+//            accumulate = 3;
+//            break;
+//        default:
+//            return 0;
+//    }
+//
+//    if (emitter->events.tail - emitter->events.head > accumulate)
+//        return 0;
+//
+//    for (event = emitter->events.head; event != emitter->events.tail; event ++) {
+//        switch (event->type) {
+//            case YAML_STREAM_START_EVENT:
+//            case YAML_DOCUMENT_START_EVENT:
+//            case YAML_SEQUENCE_START_EVENT:
+//            case YAML_MAPPING_START_EVENT:
+//                level += 1;
+//                break;
+//            case YAML_STREAM_END_EVENT:
+//            case YAML_DOCUMENT_END_EVENT:
+//            case YAML_SEQUENCE_END_EVENT:
+//            case YAML_MAPPING_END_EVENT:
+//                level -= 1;
+//                break;
+//            default:
+//                break;
+//        }
+//        if (!level)
+//            return 0;
+//    }
+//
+//    return 1;
+//}
+//
+///*
+// * Append a directive to the directives stack.
+// */
+//
+//static int
+//yaml_emitter_append_tag_directive(yaml_emitter_t *emitter,
+//        yaml_tag_directive_t value, int allow_duplicates)
+//{
+//    yaml_tag_directive_t *tag_directive;
+//    yaml_tag_directive_t copy = { NULL, NULL };
+//
+//    for (tag_directive = emitter->tag_directives.start;
+//            tag_directive != emitter->tag_directives.top; tag_directive ++) {
+//        if (strcmp((char *)value.handle, (char *)tag_directive->handle) == 0) {
+//            if (allow_duplicates)
+//                return 1;
+//            return yaml_emitter_set_emitter_error(emitter,
+//                    "duplicate %TAG directive");
+//        }
+//    }
+//
+//    copy.handle = yaml_strdup(value.handle);
+//    copy.prefix = yaml_strdup(value.prefix);
+//    if (!copy.handle || !copy.prefix) {
+//        emitter->error = YAML_MEMORY_ERROR;
+//        goto error;
+//    }
+//
+//    if (!PUSH(emitter, emitter->tag_directives, copy))
+//        goto error;
+//
+//    return 1;
+//
+//error:
+//    yaml_free(copy.handle);
+//    yaml_free(copy.prefix);
+//    return 0;
+//}
+//
+///*
+// * Increase the indentation level.
+// */
+//
+//static int
+//yaml_emitter_increase_indent(yaml_emitter_t *emitter,
+//        int flow, int indentless)
+//{
+//    if (!PUSH(emitter, emitter->indents, emitter->indent))
+//        return 0;
+//
+//    if (emitter->indent < 0) {
+//        emitter->indent = flow ? emitter->best_indent : 0;
+//    }
+//    else if (!indentless) {
+//        emitter->indent += emitter->best_indent;
+//    }
+//
+//    return 1;
+//}
+//
+///*
+// * State dispatcher.
+// */
+//
+//static int
+//yaml_emitter_state_machine(yaml_emitter_t *emitter, yaml_event_t *event)
+//{
+//    switch (emitter->state)
+//    {
+//        case YAML_EMIT_STREAM_START_STATE:
+//            return yaml_emitter_emit_stream_start(emitter, event);
+//
+//        case YAML_EMIT_FIRST_DOCUMENT_START_STATE:
+//            return yaml_emitter_emit_document_start(emitter, event, 1);
+//
+//        case YAML_EMIT_DOCUMENT_START_STATE:
+//            return yaml_emitter_emit_document_start(emitter, event, 0);
+//
+//        case YAML_EMIT_DOCUMENT_CONTENT_STATE:
+//            return yaml_emitter_emit_document_content(emitter, event);
+//
+//        case YAML_EMIT_DOCUMENT_END_STATE:
+//            return yaml_emitter_emit_document_end(emitter, event);
+//
+//        case YAML_EMIT_FLOW_SEQUENCE_FIRST_ITEM_STATE:
+//            return yaml_emitter_emit_flow_sequence_item(emitter, event, 1);
+//
+//        case YAML_EMIT_FLOW_SEQUENCE_ITEM_STATE:
+//            return yaml_emitter_emit_flow_sequence_item(emitter, event, 0);
+//
+//        case YAML_EMIT_FLOW_MAPPING_FIRST_KEY_STATE:
+//            return yaml_emitter_emit_flow_mapping_key(emitter, event, 1);
+//
+//        case YAML_EMIT_FLOW_MAPPING_KEY_STATE:
+//            return yaml_emitter_emit_flow_mapping_key(emitter, event, 0);
+//
+//        case YAML_EMIT_FLOW_MAPPING_SIMPLE_VALUE_STATE:
+//            return yaml_emitter_emit_flow_mapping_value(emitter, event, 1);
+//
+//        case YAML_EMIT_FLOW_MAPPING_VALUE_STATE:
+//            return yaml_emitter_emit_flow_mapping_value(emitter, event, 0);
+//
+//        case YAML_EMIT_BLOCK_SEQUENCE_FIRST_ITEM_STATE:
+//            return yaml_emitter_emit_block_sequence_item(emitter, event, 1);
+//
+//        case YAML_EMIT_BLOCK_SEQUENCE_ITEM_STATE:
+//            return yaml_emitter_emit_block_sequence_item(emitter, event, 0);
+//
+//        case YAML_EMIT_BLOCK_MAPPING_FIRST_KEY_STATE:
+//            return yaml_emitter_emit_block_mapping_key(emitter, event, 1);
+//
+//        case YAML_EMIT_BLOCK_MAPPING_KEY_STATE:
+//            return yaml_emitter_emit_block_mapping_key(emitter, event, 0);
+//
+//        case YAML_EMIT_BLOCK_MAPPING_SIMPLE_VALUE_STATE:
+//            return yaml_emitter_emit_block_mapping_value(emitter, event, 1);
+//
+//        case YAML_EMIT_BLOCK_MAPPING_VALUE_STATE:
+//            return yaml_emitter_emit_block_mapping_value(emitter, event, 0);
+//
+//        case YAML_EMIT_END_STATE:
+//            return yaml_emitter_set_emitter_error(emitter,
+//                    "expected nothing after STREAM-END");
+//
+//        default:
+//            assert(1);      /* Invalid state. */
+//    }
+//
+//    return 0;
+//}
+//
+///*
+// * Expect STREAM-START.
+// */
+//
+//static int
+//yaml_emitter_emit_stream_start(yaml_emitter_t *emitter,
+//        yaml_event_t *event)
+//{
+//    if (event->type == YAML_STREAM_START_EVENT)
+//    {
+//        if (!emitter->encoding) {
+//            emitter->encoding = event->data.stream_start.encoding;
+//        }
+//
+//        if (!emitter->encoding) {
+//            emitter->encoding = YAML_UTF8_ENCODING;
+//        }
+//
+//        if (emitter->best_indent < 2 || emitter->best_indent > 9) {
+//            emitter->best_indent  = 2;
+//        }
+//
+//        if (emitter->best_width >= 0
+//                && emitter->best_width <= emitter->best_indent*2) {
+//            emitter->best_width = 80;
+//        }
+//
+//        if (emitter->best_width < 0) {
+//            emitter->best_width = INT_MAX;
+//        }
+//        
+//        if (!emitter->line_break) {
+//            emitter->line_break = YAML_LN_BREAK;
+//        }
+//
+//        emitter->indent = -1;
+//
+//        emitter->line = 0;
+//        emitter->column = 0;
+//        emitter->whitespace = 1;
+//        emitter->indention = 1;
+//
+//        if (emitter->encoding != YAML_UTF8_ENCODING) {
+//            if (!yaml_emitter_write_bom(emitter))
+//                return 0;
+//        }
+//
+//        emitter->state = YAML_EMIT_FIRST_DOCUMENT_START_STATE;
+//
+//        return 1;
+//    }
+//
+//    return yaml_emitter_set_emitter_error(emitter,
+//            "expected STREAM-START");
+//}
+//
+///*
+// * Expect DOCUMENT-START or STREAM-END.
+// */
+//
+//static int
+//yaml_emitter_emit_document_start(yaml_emitter_t *emitter,
+//        yaml_event_t *event, int first)
+//{
+//    if (event->type == YAML_DOCUMENT_START_EVENT)
+//    {
+//        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 *tag_directive;
+//        int implicit;
+//
+//        if (event->data.document_start.version_directive) {
+//            if (!yaml_emitter_analyze_version_directive(emitter,
+//                        *event->data.document_start.version_directive))
+//                return 0;
+//        }
+//
+//        for (tag_directive = event->data.document_start.tag_directives.start;
+//                tag_directive != event->data.document_start.tag_directives.end;
+//                tag_directive ++) {
+//            if (!yaml_emitter_analyze_tag_directive(emitter, *tag_directive))
+//                return 0;
+//            if (!yaml_emitter_append_tag_directive(emitter, *tag_directive, 0))
+//                return 0;
+//        }
+//
+//        for (tag_directive = default_tag_directives;
+//                tag_directive->handle; tag_directive ++) {
+//            if (!yaml_emitter_append_tag_directive(emitter, *tag_directive, 1))
+//                return 0;
+//        }
+//
+//        implicit = event->data.document_start.implicit;
+//        if (!first || emitter->canonical) {
+//            implicit = 0;
+//        }
+//
+//        if ((event->data.document_start.version_directive ||
+//                    (event->data.document_start.tag_directives.start
+//                     != event->data.document_start.tag_directives.end)) &&
+//                emitter->open_ended)
+//        {
+//            if (!yaml_emitter_write_indicator(emitter, "...", 1, 0, 0))
+//                return 0;
+//            if (!yaml_emitter_write_indent(emitter))
+//                return 0;
+//        }
+//
+//        if (event->data.document_start.version_directive) {
+//            implicit = 0;
+//            if (!yaml_emitter_write_indicator(emitter, "%YAML", 1, 0, 0))
+//                return 0;
+//            if (!yaml_emitter_write_indicator(emitter, "1.1", 1, 0, 0))
+//                return 0;
+//            if (!yaml_emitter_write_indent(emitter))
+//                return 0;
+//        }
+//        
+//        if (event->data.document_start.tag_directives.start
+//                != event->data.document_start.tag_directives.end) {
+//            implicit = 0;
+//            for (tag_directive = event->data.document_start.tag_directives.start;
+//                    tag_directive != event->data.document_start.tag_directives.end;
+//                    tag_directive ++) {
+//                if (!yaml_emitter_write_indicator(emitter, "%TAG", 1, 0, 0))
+//                    return 0;
+//                if (!yaml_emitter_write_tag_handle(emitter, tag_directive->handle,
+//                            strlen((char *)tag_directive->handle)))
+//                    return 0;
+//                if (!yaml_emitter_write_tag_content(emitter, tag_directive->prefix,
+//                            strlen((char *)tag_directive->prefix), 1))
+//                    return 0;
+//                if (!yaml_emitter_write_indent(emitter))
+//                    return 0;
+//            }
+//        }
+//
+//        if (yaml_emitter_check_empty_document(emitter)) {
+//            implicit = 0;
+//        }
+//
+//        if (!implicit) {
+//            if (!yaml_emitter_write_indent(emitter))
+//                return 0;
+//            if (!yaml_emitter_write_indicator(emitter, "---", 1, 0, 0))
+//                return 0;
+//            if (emitter->canonical) {
+//                if (!yaml_emitter_write_indent(emitter))
+//                    return 0;
+//            }
+//        }
+//
+//        emitter->state = YAML_EMIT_DOCUMENT_CONTENT_STATE;
+//
+//        return 1;
+//    }
+//
+//    else if (event->type == YAML_STREAM_END_EVENT)
+//    {
+//        if (emitter->open_ended)
+//        {
+//            if (!yaml_emitter_write_indicator(emitter, "...", 1, 0, 0))
+//                return 0;
+//            if (!yaml_emitter_write_indent(emitter))
+//                return 0;
+//        }
+//
+//        if (!yaml_emitter_flush(emitter))
+//            return 0;
+//
+//        emitter->state = YAML_EMIT_END_STATE;
+//
+//        return 1;
+//    }
+//
+//    return yaml_emitter_set_emitter_error(emitter,
+//            "expected DOCUMENT-START or STREAM-END");
+//}
+//
+///*
+// * Expect the root node.
+// */
+//
+//static int
+//yaml_emitter_emit_document_content(yaml_emitter_t *emitter,
+//        yaml_event_t *event)
+//{
+//    if (!PUSH(emitter, emitter->states, YAML_EMIT_DOCUMENT_END_STATE))
+//        return 0;
+//
+//    return yaml_emitter_emit_node(emitter, event, 1, 0, 0, 0);
+//}
+//
+///*
+// * Expect DOCUMENT-END.
+// */
+//
+//static int
+//yaml_emitter_emit_document_end(yaml_emitter_t *emitter,
+//        yaml_event_t *event)
+//{
+//    if (event->type == YAML_DOCUMENT_END_EVENT)
+//    {
+//        if (!yaml_emitter_write_indent(emitter))
+//            return 0;
+//        if (!event->data.document_end.implicit) {
+//            if (!yaml_emitter_write_indicator(emitter, "...", 1, 0, 0))
+//                return 0;
+//            if (!yaml_emitter_write_indent(emitter))
+//                return 0;
+//        }
+//        if (!yaml_emitter_flush(emitter))
+//            return 0;
+//
+//        emitter->state = YAML_EMIT_DOCUMENT_START_STATE;
+//
+//        while (!STACK_EMPTY(emitter, emitter->tag_directives)) {
+//            yaml_tag_directive_t tag_directive = POP(emitter,
+//                    emitter->tag_directives);
+//            yaml_free(tag_directive.handle);
+//            yaml_free(tag_directive.prefix);
+//        }
+//
+//        return 1;
+//    }
+//
+//    return yaml_emitter_set_emitter_error(emitter,
+//            "expected DOCUMENT-END");
+//}
+//
+///*
+// * 
+// * Expect a flow item node.
+// */
+//
+//static int
+//yaml_emitter_emit_flow_sequence_item(yaml_emitter_t *emitter,
+//        yaml_event_t *event, int first)
+//{
+//    if (first)
+//    {
+//        if (!yaml_emitter_write_indicator(emitter, "[", 1, 1, 0))
+//            return 0;
+//        if (!yaml_emitter_increase_indent(emitter, 1, 0))
+//            return 0;
+//        emitter->flow_level ++;
+//    }
+//
+//    if (event->type == YAML_SEQUENCE_END_EVENT)
+//    {
+//        emitter->flow_level --;
+//        emitter->indent = POP(emitter, emitter->indents);
+//        if (emitter->canonical && !first) {
+//            if (!yaml_emitter_write_indicator(emitter, ",", 0, 0, 0))
+//                return 0;
+//            if (!yaml_emitter_write_indent(emitter))
+//                return 0;
+//        }
+//        if (!yaml_emitter_write_indicator(emitter, "]", 0, 0, 0))
+//            return 0;
+//        emitter->state = POP(emitter, emitter->states);
+//
+//        return 1;
+//    }
+//
+//    if (!first) {
+//        if (!yaml_emitter_write_indicator(emitter, ",", 0, 0, 0))
+//            return 0;
+//    }
+//
+//    if (emitter->canonical || emitter->column > emitter->best_width) {
+//        if (!yaml_emitter_write_indent(emitter))
+//            return 0;
+//    }
+//    if (!PUSH(emitter, emitter->states, YAML_EMIT_FLOW_SEQUENCE_ITEM_STATE))
+//        return 0;
+//
+//    return yaml_emitter_emit_node(emitter, event, 0, 1, 0, 0);
+//}
+//
+///*
+// * Expect a flow key node.
+// */
+//
+//static int
+//yaml_emitter_emit_flow_mapping_key(yaml_emitter_t *emitter,
+//        yaml_event_t *event, int first)
+//{
+//    if (first)
+//    {
+//        if (!yaml_emitter_write_indicator(emitter, "{", 1, 1, 0))
+//            return 0;
+//        if (!yaml_emitter_increase_indent(emitter, 1, 0))
+//            return 0;
+//        emitter->flow_level ++;
+//    }
+//
+//    if (event->type == YAML_MAPPING_END_EVENT)
+//    {
+//        emitter->flow_level --;
+//        emitter->indent = POP(emitter, emitter->indents);
+//        if (emitter->canonical && !first) {
+//            if (!yaml_emitter_write_indicator(emitter, ",", 0, 0, 0))
+//                return 0;
+//            if (!yaml_emitter_write_indent(emitter))
+//                return 0;
+//        }
+//        if (!yaml_emitter_write_indicator(emitter, "}", 0, 0, 0))
+//            return 0;
+//        emitter->state = POP(emitter, emitter->states);
+//
+//        return 1;
+//    }
+//
+//    if (!first) {
+//        if (!yaml_emitter_write_indicator(emitter, ",", 0, 0, 0))
+//            return 0;
+//    }
+//    if (emitter->canonical || emitter->column > emitter->best_width) {
+//        if (!yaml_emitter_write_indent(emitter))
+//            return 0;
+//    }
+//
+//    if (!emitter->canonical && yaml_emitter_check_simple_key(emitter))
+//    {
+//        if (!PUSH(emitter, emitter->states,
+//                    YAML_EMIT_FLOW_MAPPING_SIMPLE_VALUE_STATE))
+//            return 0;
+//
+//        return yaml_emitter_emit_node(emitter, event, 0, 0, 1, 1);
+//    }
+//    else
+//    {
+//        if (!yaml_emitter_write_indicator(emitter, "?", 1, 0, 0))
+//            return 0;
+//        if (!PUSH(emitter, emitter->states,
+//                    YAML_EMIT_FLOW_MAPPING_VALUE_STATE))
+//            return 0;
+//
+//        return yaml_emitter_emit_node(emitter, event, 0, 0, 1, 0);
+//    }
+//}
+//
+///*
+// * Expect a flow value node.
+// */
+//
+//static int
+//yaml_emitter_emit_flow_mapping_value(yaml_emitter_t *emitter,
+//        yaml_event_t *event, int simple)
+//{
+//    if (simple) {
+//        if (!yaml_emitter_write_indicator(emitter, ":", 0, 0, 0))
+//            return 0;
+//    }
+//    else {
+//        if (emitter->canonical || emitter->column > emitter->best_width) {
+//            if (!yaml_emitter_write_indent(emitter))
+//                return 0;
+//        }
+//        if (!yaml_emitter_write_indicator(emitter, ":", 1, 0, 0))
+//            return 0;
+//    }
+//    if (!PUSH(emitter, emitter->states, YAML_EMIT_FLOW_MAPPING_KEY_STATE))
+//        return 0;
+//    return yaml_emitter_emit_node(emitter, event, 0, 0, 1, 0);
+//}
+//
+///*
+// * Expect a block item node.
+// */
+//
+//static int
+//yaml_emitter_emit_block_sequence_item(yaml_emitter_t *emitter,
+//        yaml_event_t *event, int first)
+//{
+//    if (first)
+//    {
+//        if (!yaml_emitter_increase_indent(emitter, 0,
+//                    (emitter->mapping_context && !emitter->indention)))
+//            return 0;
+//    }
+//
+//    if (event->type == YAML_SEQUENCE_END_EVENT)
+//    {
+//        emitter->indent = POP(emitter, emitter->indents);
+//        emitter->state = POP(emitter, emitter->states);
+//
+//        return 1;
+//    }
+//
+//    if (!yaml_emitter_write_indent(emitter))
+//        return 0;
+//    if (!yaml_emitter_write_indicator(emitter, "-", 1, 0, 1))
+//        return 0;
+//    if (!PUSH(emitter, emitter->states,
+//                YAML_EMIT_BLOCK_SEQUENCE_ITEM_STATE))
+//        return 0;
+//
+//    return yaml_emitter_emit_node(emitter, event, 0, 1, 0, 0);
+//}
+//
+///*
+// * Expect a block key node.
+// */
+//
+//static int
+//yaml_emitter_emit_block_mapping_key(yaml_emitter_t *emitter,
+//        yaml_event_t *event, int first)
+//{
+//    if (first)
+//    {
+//        if (!yaml_emitter_increase_indent(emitter, 0, 0))
+//            return 0;
+//    }
+//
+//    if (event->type == YAML_MAPPING_END_EVENT)
+//    {
+//        emitter->indent = POP(emitter, emitter->indents);
+//        emitter->state = POP(emitter, emitter->states);
+//
+//        return 1;
+//    }
+//
+//    if (!yaml_emitter_write_indent(emitter))
+//        return 0;
+//
+//    if (yaml_emitter_check_simple_key(emitter))
+//    {
+//        if (!PUSH(emitter, emitter->states,
+//                    YAML_EMIT_BLOCK_MAPPING_SIMPLE_VALUE_STATE))
+//            return 0;
+//
+//        return yaml_emitter_emit_node(emitter, event, 0, 0, 1, 1);
+//    }
+//    else
+//    {
+//        if (!yaml_emitter_write_indicator(emitter, "?", 1, 0, 1))
+//            return 0;
+//        if (!PUSH(emitter, emitter->states,
+//                    YAML_EMIT_BLOCK_MAPPING_VALUE_STATE))
+//            return 0;
+//
+//        return yaml_emitter_emit_node(emitter, event, 0, 0, 1, 0);
+//    }
+//}
+//
+///*
+// * Expect a block value node.
+// */
+//
+//static int
+//yaml_emitter_emit_block_mapping_value(yaml_emitter_t *emitter,
+//        yaml_event_t *event, int simple)
+//{
+//    if (simple) {
+//        if (!yaml_emitter_write_indicator(emitter, ":", 0, 0, 0))
+//            return 0;
+//    }
+//    else {
+//        if (!yaml_emitter_write_indent(emitter))
+//            return 0;
+//        if (!yaml_emitter_write_indicator(emitter, ":", 1, 0, 1))
+//            return 0;
+//    }
+//    if (!PUSH(emitter, emitter->states,
+//                YAML_EMIT_BLOCK_MAPPING_KEY_STATE))
+//        return 0;
+//
+//    return yaml_emitter_emit_node(emitter, event, 0, 0, 1, 0);
+//}
+//
+///*
+// * Expect a node.
+// */
+//
+//static int
+//yaml_emitter_emit_node(yaml_emitter_t *emitter, yaml_event_t *event,
+//        int root, int sequence, int mapping, int simple_key)
+//{
+//    emitter->root_context = root;
+//    emitter->sequence_context = sequence;
+//    emitter->mapping_context = mapping;
+//    emitter->simple_key_context = simple_key;
+//
+//    switch (event->type)
+//    {
+//        case YAML_ALIAS_EVENT:
+//            return yaml_emitter_emit_alias(emitter, event);
+//
+//        case YAML_SCALAR_EVENT:
+//            return yaml_emitter_emit_scalar(emitter, event);
+//
+//        case YAML_SEQUENCE_START_EVENT:
+//            return yaml_emitter_emit_sequence_start(emitter, event);
+//
+//        case YAML_MAPPING_START_EVENT:
+//            return yaml_emitter_emit_mapping_start(emitter, event);
+//
+//        default:
+//            return yaml_emitter_set_emitter_error(emitter,
+//                    "expected SCALAR, SEQUENCE-START, MAPPING-START, or ALIAS");
+//    }
+//
+//    return 0;
+//}
+//
+///*
+// * Expect ALIAS.
+// */
+//
+//static int
+//yaml_emitter_emit_alias(yaml_emitter_t *emitter, yaml_event_t *event)
+//{
+//    if (!yaml_emitter_process_anchor(emitter))
+//        return 0;
+//    emitter->state = POP(emitter, emitter->states);
+//
+//    return 1;
+//}
+//
+///*
+// * Expect SCALAR.
+// */
+//
+//static int
+//yaml_emitter_emit_scalar(yaml_emitter_t *emitter, yaml_event_t *event)
+//{
+//    if (!yaml_emitter_select_scalar_style(emitter, event))
+//        return 0;
+//    if (!yaml_emitter_process_anchor(emitter))
+//        return 0;
+//    if (!yaml_emitter_process_tag(emitter))
+//        return 0;
+//    if (!yaml_emitter_increase_indent(emitter, 1, 0))
+//        return 0;
+//    if (!yaml_emitter_process_scalar(emitter))
+//        return 0;
+//    emitter->indent = POP(emitter, emitter->indents);
+//    emitter->state = POP(emitter, emitter->states);
+//
+//    return 1;
+//}
+//
+///*
+// * Expect SEQUENCE-START.
+// */
+//
+//static int
+//yaml_emitter_emit_sequence_start(yaml_emitter_t *emitter, yaml_event_t *event)
+//{
+//    if (!yaml_emitter_process_anchor(emitter))
+//        return 0;
+//    if (!yaml_emitter_process_tag(emitter))
+//        return 0;
+//
+//    if (emitter->flow_level || emitter->canonical
+//            || event->data.sequence_start.style == YAML_FLOW_SEQUENCE_STYLE
+//            || yaml_emitter_check_empty_sequence(emitter)) {
+//        emitter->state = YAML_EMIT_FLOW_SEQUENCE_FIRST_ITEM_STATE;
+//    }
+//    else {
+//        emitter->state = YAML_EMIT_BLOCK_SEQUENCE_FIRST_ITEM_STATE;
+//    }
+//
+//    return 1;
+//}
+//
+///*
+// * Expect MAPPING-START.
+// */
+//
+//static int
+//yaml_emitter_emit_mapping_start(yaml_emitter_t *emitter, yaml_event_t *event)
+//{
+//    if (!yaml_emitter_process_anchor(emitter))
+//        return 0;
+//    if (!yaml_emitter_process_tag(emitter))
+//        return 0;
+//
+//    if (emitter->flow_level || emitter->canonical
+//            || event->data.mapping_start.style == YAML_FLOW_MAPPING_STYLE
+//            || yaml_emitter_check_empty_mapping(emitter)) {
+//        emitter->state = YAML_EMIT_FLOW_MAPPING_FIRST_KEY_STATE;
+//    }
+//    else {
+//        emitter->state = YAML_EMIT_BLOCK_MAPPING_FIRST_KEY_STATE;
+//    }
+//
+//    return 1;
+//}
+//
+///*
+// * Check if the document content is an empty scalar.
+// */
+//
+//static int
+//yaml_emitter_check_empty_document(yaml_emitter_t *emitter)
+//{
+//    return 0;
+//}
+//
+///*
+// * Check if the next events represent an empty sequence.
+// */
+//
+//static int
+//yaml_emitter_check_empty_sequence(yaml_emitter_t *emitter)
+//{
+//    if (emitter->events.tail - emitter->events.head < 2)
+//        return 0;
+//
+//    return (emitter->events.head[0].type == YAML_SEQUENCE_START_EVENT
+//            && emitter->events.head[1].type == YAML_SEQUENCE_END_EVENT);
+//}
+//
+///*
+// * Check if the next events represent an empty mapping.
+// */
+//
+//static int
+//yaml_emitter_check_empty_mapping(yaml_emitter_t *emitter)
+//{
+//    if (emitter->events.tail - emitter->events.head < 2)
+//        return 0;
+//
+//    return (emitter->events.head[0].type == YAML_MAPPING_START_EVENT
+//            && emitter->events.head[1].type == YAML_MAPPING_END_EVENT);
+//}
+//
+///*
+// * Check if the next node can be expressed as a simple key.
+// */
+//
+//static int
+//yaml_emitter_check_simple_key(yaml_emitter_t *emitter)
+//{
+//    yaml_event_t *event = emitter->events.head;
+//    size_t length = 0;
+//
+//    switch (event->type)
+//    {
+//        case YAML_ALIAS_EVENT:
+//            length += emitter->anchor_data.anchor_length;
+//            break;
+//
+//        case YAML_SCALAR_EVENT:
+//            if (emitter->scalar_data.multiline)
+//                return 0;
+//            length += emitter->anchor_data.anchor_length
+//                + emitter->tag_data.handle_length
+//                + emitter->tag_data.suffix_length
+//                + emitter->scalar_data.length;
+//            break;
+//
+//        case YAML_SEQUENCE_START_EVENT:
+//            if (!yaml_emitter_check_empty_sequence(emitter))
+//                return 0;
+//            length += emitter->anchor_data.anchor_length
+//                + emitter->tag_data.handle_length
+//                + emitter->tag_data.suffix_length;
+//            break;
+//
+//        case YAML_MAPPING_START_EVENT:
+//            if (!yaml_emitter_check_empty_mapping(emitter))
+//                return 0;
+//            length += emitter->anchor_data.anchor_length
+//                + emitter->tag_data.handle_length
+//                + emitter->tag_data.suffix_length;
+//            break;
+//
+//        default:
+//            return 0;
+//    }
+//
+//    if (length > 128)
+//        return 0;
+//
+//    return 1;
+//}
+//
+///*
+// * Determine an acceptable scalar style.
+// */
+//
+//static int
+//yaml_emitter_select_scalar_style(yaml_emitter_t *emitter, yaml_event_t *event)
+//{
+//    yaml_scalar_style_t style = event->data.scalar.style;
+//    int no_tag = (!emitter->tag_data.handle && !emitter->tag_data.suffix);
+//
+//    if (no_tag && !event->data.scalar.plain_implicit
+//            && !event->data.scalar.quoted_implicit) {
+//        return yaml_emitter_set_emitter_error(emitter,
+//                "neither tag nor implicit flags are specified");
+//    }
+//
+//    if (style == YAML_ANY_SCALAR_STYLE)
+//        style = YAML_PLAIN_SCALAR_STYLE;
+//
+//    if (emitter->canonical)
+//        style = YAML_DOUBLE_QUOTED_SCALAR_STYLE;
+//
+//    if (emitter->simple_key_context && emitter->scalar_data.multiline)
+//        style = YAML_DOUBLE_QUOTED_SCALAR_STYLE;
+//
+//    if (style == YAML_PLAIN_SCALAR_STYLE)
+//    {
+//        if ((emitter->flow_level && !emitter->scalar_data.flow_plain_allowed)
+//                || (!emitter->flow_level && !emitter->scalar_data.block_plain_allowed))
+//            style = YAML_SINGLE_QUOTED_SCALAR_STYLE;
+//        if (!emitter->scalar_data.length
+//                && (emitter->flow_level || emitter->simple_key_context))
+//            style = YAML_SINGLE_QUOTED_SCALAR_STYLE;
+//        if (no_tag && !event->data.scalar.plain_implicit)
+//            style = YAML_SINGLE_QUOTED_SCALAR_STYLE;
+//    }
+//
+//    if (style == YAML_SINGLE_QUOTED_SCALAR_STYLE)
+//    {
+//        if (!emitter->scalar_data.single_quoted_allowed)
+//            style = YAML_DOUBLE_QUOTED_SCALAR_STYLE;
+//    }
+//
+//    if (style == YAML_LITERAL_SCALAR_STYLE || style == YAML_FOLDED_SCALAR_STYLE)
+//    {
+//        if (!emitter->scalar_data.block_allowed
+//                || emitter->flow_level || emitter->simple_key_context)
+//            style = YAML_DOUBLE_QUOTED_SCALAR_STYLE;
+//    }
+//
+//    if (no_tag && !event->data.scalar.quoted_implicit
+//            && style != YAML_PLAIN_SCALAR_STYLE)
+//    {
+//        emitter->tag_data.handle = (yaml_char_t *)"!";
+//        emitter->tag_data.handle_length = 1;
+//    }
+//
+//    emitter->scalar_data.style = style;
+//
+//    return 1;
+//}
+//
+///*
+// * Write an achor.
+// */
+//
+//static int
+//yaml_emitter_process_anchor(yaml_emitter_t *emitter)
+//{
+//    if (!emitter->anchor_data.anchor)
+//        return 1;
+//
+//    if (!yaml_emitter_write_indicator(emitter,
+//                (emitter->anchor_data.alias ? "*" : "&"), 1, 0, 0))
+//        return 0;
+//
+//    return yaml_emitter_write_anchor(emitter,
+//            emitter->anchor_data.anchor, emitter->anchor_data.anchor_length);
+//}
+//
+///*
+// * Write a tag.
+// */
+//
+//static int
+//yaml_emitter_process_tag(yaml_emitter_t *emitter)
+//{
+//    if (!emitter->tag_data.handle && !emitter->tag_data.suffix)
+//        return 1;
+//
+//    if (emitter->tag_data.handle)
+//    {
+//        if (!yaml_emitter_write_tag_handle(emitter, emitter->tag_data.handle,
+//                    emitter->tag_data.handle_length))
+//            return 0;
+//        if (emitter->tag_data.suffix) {
+//            if (!yaml_emitter_write_tag_content(emitter, emitter->tag_data.suffix,
+//                        emitter->tag_data.suffix_length, 0))
+//                return 0;
+//        }
+//    }
+//    else
+//    {
+//        if (!yaml_emitter_write_indicator(emitter, "!<", 1, 0, 0))
+//            return 0;
+//        if (!yaml_emitter_write_tag_content(emitter, emitter->tag_data.suffix,
+//                    emitter->tag_data.suffix_length, 0))
+//            return 0;
+//        if (!yaml_emitter_write_indicator(emitter, ">", 0, 0, 0))
+//            return 0;
+//    }
+//
+//    return 1;
+//}
+//
+///*
+// * Write a scalar.
+// */
+//
+//static int
+//yaml_emitter_process_scalar(yaml_emitter_t *emitter)
+//{
+//    switch (emitter->scalar_data.style)
+//    {
+//        case YAML_PLAIN_SCALAR_STYLE:
+//            return yaml_emitter_write_plain_scalar(emitter,
+//                    emitter->scalar_data.value, emitter->scalar_data.length,
+//                    !emitter->simple_key_context);
+//
+//        case YAML_SINGLE_QUOTED_SCALAR_STYLE:
+//            return yaml_emitter_write_single_quoted_scalar(emitter,
+//                    emitter->scalar_data.value, emitter->scalar_data.length,
+//                    !emitter->simple_key_context);
+//
+//        case YAML_DOUBLE_QUOTED_SCALAR_STYLE:
+//            return yaml_emitter_write_double_quoted_scalar(emitter,
+//                    emitter->scalar_data.value, emitter->scalar_data.length,
+//                    !emitter->simple_key_context);
+//
+//        case YAML_LITERAL_SCALAR_STYLE:
+//            return yaml_emitter_write_literal_scalar(emitter,
+//                    emitter->scalar_data.value, emitter->scalar_data.length);
+//
+//        case YAML_FOLDED_SCALAR_STYLE:
+//            return yaml_emitter_write_folded_scalar(emitter,
+//                    emitter->scalar_data.value, emitter->scalar_data.length);
+//
+//        default:
+//            assert(1);      /* Impossible. */
+//    }
+//
+//    return 0;
+//}
+//
+///*
+// * Check if a %YAML directive is valid.
+// */
+//
+//static int
+//yaml_emitter_analyze_version_directive(yaml_emitter_t *emitter,
+//        yaml_version_directive_t version_directive)
+//{
+//    if (version_directive.major != 1 || version_directive.minor != 1) {
+//        return yaml_emitter_set_emitter_error(emitter,
+//                "incompatible %YAML directive");
+//    }
+//
+//    return 1;
+//}
+//
+///*
+// * Check if a %TAG directive is valid.
+// */
+//
+//static int
+//yaml_emitter_analyze_tag_directive(yaml_emitter_t *emitter,
+//        yaml_tag_directive_t tag_directive)
+//{
+//    yaml_string_t handle;
+//    yaml_string_t prefix;
+//    size_t handle_length;
+//    size_t prefix_length;
+//
+//    handle_length = strlen((char *)tag_directive.handle);
+//    prefix_length = strlen((char *)tag_directive.prefix);
+//    STRING_ASSIGN(handle, tag_directive.handle, handle_length);
+//    STRING_ASSIGN(prefix, tag_directive.prefix, prefix_length);
+//
+//    if (handle.start == handle.end) {
+//        return yaml_emitter_set_emitter_error(emitter,
+//                "tag handle must not be empty");
+//    }
+//
+//    if (handle.start[0] != '!') {
+//        return yaml_emitter_set_emitter_error(emitter,
+//                "tag handle must start with '!'");
+//    }
+//
+//    if (handle.end[-1] != '!') {
+//        return yaml_emitter_set_emitter_error(emitter,
+//                "tag handle must end with '!'");
+//    }
+//
+//    handle.pointer ++;
+//
+//    while (handle.pointer < handle.end-1) {
+//        if (!IS_ALPHA(handle)) {
+//            return yaml_emitter_set_emitter_error(emitter,
+//                    "tag handle must contain alphanumerical characters only");
+//        }
+//        MOVE(handle);
+//    }
+//
+//    if (prefix.start == prefix.end) {
+//        return yaml_emitter_set_emitter_error(emitter,
+//                "tag prefix must not be empty");
+//    }
+//
+//    return 1;
+//}
+//
+///*
+// * Check if an anchor is valid.
+// */
+//
+//static int
+//yaml_emitter_analyze_anchor(yaml_emitter_t *emitter,
+//        yaml_char_t *anchor, int alias)
+//{
+//    size_t anchor_length;
+//    yaml_string_t string;
+//    
+//    anchor_length = strlen((char *)anchor);
+//    STRING_ASSIGN(string, anchor, anchor_length);
+//
+//    if (string.start == string.end) {
+//        return yaml_emitter_set_emitter_error(emitter, alias ?
+//                "alias value must not be empty" :
+//                "anchor value must not be empty");
+//    }
+//
+//    while (string.pointer != string.end) {
+//        if (!IS_ALPHA(string)) {
+//            return yaml_emitter_set_emitter_error(emitter, alias ?
+//                    "alias value must contain alphanumerical characters only" :
+//                    "anchor value must contain alphanumerical characters only");
+//        }
+//        MOVE(string);
+//    }
+//
+//    emitter->anchor_data.anchor = string.start;
+//    emitter->anchor_data.anchor_length = string.end - string.start;
+//    emitter->anchor_data.alias = alias;
+//
+//    return 1;
+//}
+//
+///*
+// * Check if a tag is valid.
+// */
+//
+//static int
+//yaml_emitter_analyze_tag(yaml_emitter_t *emitter,
+//        yaml_char_t *tag)
+//{
+//    size_t tag_length;
+//    yaml_string_t string;
+//    yaml_tag_directive_t *tag_directive;
+//
+//    tag_length = strlen((char *)tag);
+//    STRING_ASSIGN(string, tag, tag_length);
+//
+//    if (string.start == string.end) {
+//        return yaml_emitter_set_emitter_error(emitter,
+//                "tag value must not be empty");
+//    }
+//
+//    for (tag_directive = emitter->tag_directives.start;
+//            tag_directive != emitter->tag_directives.top; tag_directive ++) {
+//        size_t prefix_length = strlen((char *)tag_directive->prefix);
+//        if (prefix_length < (size_t)(string.end - string.start)
+//                && strncmp((char *)tag_directive->prefix, (char *)string.start,
+//                    prefix_length) == 0)
+//        {
+//            emitter->tag_data.handle = tag_directive->handle;
+//            emitter->tag_data.handle_length =
+//                strlen((char *)tag_directive->handle);
+//            emitter->tag_data.suffix = string.start + prefix_length;
+//            emitter->tag_data.suffix_length =
+//                (string.end - string.start) - prefix_length;
+//            return 1;
+//        }
+//    }
+//
+//    emitter->tag_data.suffix = string.start;
+//    emitter->tag_data.suffix_length = string.end - string.start;
+//
+//    return 1;
+//}
+//
+///*
+// * Check if a scalar is valid.
+// */
+//
+//static int
+//yaml_emitter_analyze_scalar(yaml_emitter_t *emitter,
+//        yaml_char_t *value, size_t length)
+//{
+//    yaml_string_t string;
+//
+//    int block_indicators = 0;
+//    int flow_indicators = 0;
+//    int line_breaks = 0;
+//    int special_characters = 0;
+//
+//    int leading_space = 0;
+//    int leading_break = 0;
+//    int trailing_space = 0;
+//    int trailing_break = 0;
+//    int break_space = 0;
+//    int space_break = 0;
+//
+//    int preceeded_by_whitespace = 0;
+//    int followed_by_whitespace = 0;
+//    int previous_space = 0;
+//    int previous_break = 0;
+//
+//    STRING_ASSIGN(string, value, length);
+//
+//    emitter->scalar_data.value = value;
+//    emitter->scalar_data.length = length;
+//
+//    if (string.start == string.end)
+//    {
+//        emitter->scalar_data.multiline = 0;
+//        emitter->scalar_data.flow_plain_allowed = 0;
+//        emitter->scalar_data.block_plain_allowed = 1;
+//        emitter->scalar_data.single_quoted_allowed = 1;
+//        emitter->scalar_data.block_allowed = 0;
+//
+//        return 1;
+//    }
+//
+//    if ((CHECK_AT(string, '-', 0)
+//                && CHECK_AT(string, '-', 1)
+//                && CHECK_AT(string, '-', 2))
+//            || (CHECK_AT(string, '.', 0)
+//                && CHECK_AT(string, '.', 1)
+//                && CHECK_AT(string, '.', 2))) {
+//        block_indicators = 1;
+//        flow_indicators = 1;
+//    }
+//
+//    preceeded_by_whitespace = 1;
+//    followed_by_whitespace = IS_BLANKZ_AT(string, WIDTH(string));
+//
+//    while (string.pointer != string.end)
+//    {
+//        if (string.start == string.pointer)
+//        {
+//            if (CHECK(string, '#') || CHECK(string, ',')
+//                    || CHECK(string, '[') || CHECK(string, ']')
+//                    || CHECK(string, '{') || CHECK(string, '}')
+//                    || CHECK(string, '&') || CHECK(string, '*')
+//                    || CHECK(string, '!') || CHECK(string, '|')
+//                    || CHECK(string, '>') || CHECK(string, '\'')
+//                    || CHECK(string, '"') || CHECK(string, '%')
+//                    || CHECK(string, '@') || CHECK(string, '`')) {
+//                flow_indicators = 1;
+//                block_indicators = 1;
+//            }
+//
+//            if (CHECK(string, '?') || CHECK(string, ':')) {
+//                flow_indicators = 1;
+//                if (followed_by_whitespace) {
+//                    block_indicators = 1;
+//                }
+//            }
+//
+//            if (CHECK(string, '-') && followed_by_whitespace) {
+//                flow_indicators = 1;
+//                block_indicators = 1;
+//            }
+//        }
+//        else
+//        {
+//            if (CHECK(string, ',') || CHECK(string, '?')
+//                    || CHECK(string, '[') || CHECK(string, ']')
+//                    || CHECK(string, '{') || CHECK(string, '}')) {
+//                flow_indicators = 1;
+//            }
+//
+//            if (CHECK(string, ':')) {
+//                flow_indicators = 1;
+//                if (followed_by_whitespace) {
+//                    block_indicators = 1;
+//                }
+//            }
+//
+//            if (CHECK(string, '#') && preceeded_by_whitespace) {
+//                flow_indicators = 1;
+//                block_indicators = 1;
+//            }
+//        }
+//
+//        if (!IS_PRINTABLE(string)
+//                || (!IS_ASCII(string) && !emitter->unicode)) {
+//            special_characters = 1;
+//        }
+//
+//        if (IS_BREAK(string)) {
+//            line_breaks = 1;
+//        }
+//
+//        if (IS_SPACE(string))
+//        {
+//            if (string.start == string.pointer) {
+//                leading_space = 1;
+//            }
+//            if (string.pointer+WIDTH(string) == string.end) {
+//                trailing_space = 1;
+//            }
+//            if (previous_break) {
+//                break_space = 1;
+//            }
+//            previous_space = 1;
+//            previous_break = 0;
+//        }
+//        else if (IS_BREAK(string))
+//        {
+//            if (string.start == string.pointer) {
+//                leading_break = 1;
+//            }
+//            if (string.pointer+WIDTH(string) == string.end) {
+//                trailing_break = 1;
+//            }
+//            if (previous_space) {
+//                space_break = 1;
+//            }
+//            previous_space = 0;
+//            previous_break = 1;
+//        }
+//        else
+//        {
+//            previous_space = 0;
+//            previous_break = 0;
+//        }
+//
+//        preceeded_by_whitespace = IS_BLANKZ(string);
+//        MOVE(string);
+//        if (string.pointer != string.end) {
+//            followed_by_whitespace = IS_BLANKZ_AT(string, WIDTH(string));
+//        }
+//    }
+//
+//    emitter->scalar_data.multiline = line_breaks;
+//
+//    emitter->scalar_data.flow_plain_allowed = 1;
+//    emitter->scalar_data.block_plain_allowed = 1;
+//    emitter->scalar_data.single_quoted_allowed = 1;
+//    emitter->scalar_data.block_allowed = 1;
+//
+//    if (leading_space || leading_break || trailing_space || trailing_break) {
+//        emitter->scalar_data.flow_plain_allowed = 0;
+//        emitter->scalar_data.block_plain_allowed = 0;
+//    }
+//
+//    if (trailing_space) {
+//        emitter->scalar_data.block_allowed = 0;
+//    }
+//
+//    if (break_space) {
+//        emitter->scalar_data.flow_plain_allowed = 0;
+//        emitter->scalar_data.block_plain_allowed = 0;
+//        emitter->scalar_data.single_quoted_allowed = 0;
+//    }
+//
+//    if (space_break || special_characters) {
+//        emitter->scalar_data.flow_plain_allowed = 0;
+//        emitter->scalar_data.block_plain_allowed = 0;
+//        emitter->scalar_data.single_quoted_allowed = 0;
+//        emitter->scalar_data.block_allowed = 0;
+//    }
+//
+//    if (line_breaks) {
+//        emitter->scalar_data.flow_plain_allowed = 0;
+//        emitter->scalar_data.block_plain_allowed = 0;
+//    }
+//
+//    if (flow_indicators) {
+//        emitter->scalar_data.flow_plain_allowed = 0;
+//    }
+//
+//    if (block_indicators) {
+//        emitter->scalar_data.block_plain_allowed = 0;
+//    }
+//
+//    return 1;
+//}
+//
+///*
+// * Check if the event data is valid.
+// */
+//
+//static int
+//yaml_emitter_analyze_event(yaml_emitter_t *emitter,
+//        yaml_event_t *event)
+//{
+//    emitter->anchor_data.anchor = NULL;
+//    emitter->anchor_data.anchor_length = 0;
+//    emitter->tag_data.handle = NULL;
+//    emitter->tag_data.handle_length = 0;
+//    emitter->tag_data.suffix = NULL;
+//    emitter->tag_data.suffix_length = 0;
+//    emitter->scalar_data.value = NULL;
+//    emitter->scalar_data.length = 0;
+//
+//    switch (event->type)
+//    {
+//        case YAML_ALIAS_EVENT:
+//            if (!yaml_emitter_analyze_anchor(emitter,
+//                        event->data.alias.anchor, 1))
+//                return 0;
+//            return 1;
+//
+//        case YAML_SCALAR_EVENT:
+//            if (event->data.scalar.anchor) {
+//                if (!yaml_emitter_analyze_anchor(emitter,
+//                            event->data.scalar.anchor, 0))
+//                    return 0;
+//            }
+//            if (event->data.scalar.tag && (emitter->canonical ||
+//                        (!event->data.scalar.plain_implicit
+//                         && !event->data.scalar.quoted_implicit))) {
+//                if (!yaml_emitter_analyze_tag(emitter, event->data.scalar.tag))
+//                    return 0;
+//            }
+//            if (!yaml_emitter_analyze_scalar(emitter,
+//                        event->data.scalar.value, event->data.scalar.length))
+//                return 0;
+//            return 1;
+//
+//        case YAML_SEQUENCE_START_EVENT:
+//            if (event->data.sequence_start.anchor) {
+//                if (!yaml_emitter_analyze_anchor(emitter,
+//                            event->data.sequence_start.anchor, 0))
+//                    return 0;
+//            }
+//            if (event->data.sequence_start.tag && (emitter->canonical ||
+//                        !event->data.sequence_start.implicit)) {
+//                if (!yaml_emitter_analyze_tag(emitter,
+//                            event->data.sequence_start.tag))
+//                    return 0;
+//            }
+//            return 1;
+//
+//        case YAML_MAPPING_START_EVENT:
+//            if (event->data.mapping_start.anchor) {
+//                if (!yaml_emitter_analyze_anchor(emitter,
+//                            event->data.mapping_start.anchor, 0))
+//                    return 0;
+//            }
+//            if (event->data.mapping_start.tag && (emitter->canonical ||
+//                        !event->data.mapping_start.implicit)) {
+//                if (!yaml_emitter_analyze_tag(emitter,
+//                            event->data.mapping_start.tag))
+//                    return 0;
+//            }
+//            return 1;
+//
+//        default:
+//            return 1;
+//    }
+//}
+//
+///*
+// * Write the BOM character.
+// */
+//
+//static int
+//yaml_emitter_write_bom(yaml_emitter_t *emitter)
+//{
+//    if (!FLUSH(emitter)) return 0;
+//
+//    *(emitter->buffer.pointer++) = (yaml_char_t) '\xEF';
+//    *(emitter->buffer.pointer++) = (yaml_char_t) '\xBB';
+//    *(emitter->buffer.pointer++) = (yaml_char_t) '\xBF';
+//
+//    return 1;
+//}
+//
+//static int
+//yaml_emitter_write_indent(yaml_emitter_t *emitter)
+//{
+//    int indent = (emitter->indent >= 0) ? emitter->indent : 0;
+//
+//    if (!emitter->indention || emitter->column > indent
+//            || (emitter->column == indent && !emitter->whitespace)) {
+//        if (!PUT_BREAK(emitter)) return 0;
+//    }
+//
+//    while (emitter->column < indent) {
+//        if (!PUT(emitter, ' ')) return 0;
+//    }
+//
+//    emitter->whitespace = 1;
+//    emitter->indention = 1;
+//
+//    return 1;
+//}
+//
+//static int
+//yaml_emitter_write_indicator(yaml_emitter_t *emitter,
+//        char *indicator, int need_whitespace,
+//        int is_whitespace, int is_indention)
+//{
+//    size_t indicator_length;
+//    yaml_string_t string;
+//
+//    indicator_length = strlen(indicator);
+//    STRING_ASSIGN(string, (yaml_char_t *)indicator, indicator_length);
+//
+//    if (need_whitespace && !emitter->whitespace) {
+//        if (!PUT(emitter, ' ')) return 0;
+//    }
+//
+//    while (string.pointer != string.end) {
+//        if (!WRITE(emitter, string)) return 0;
+//    }
+//
+//    emitter->whitespace = is_whitespace;
+//    emitter->indention = (emitter->indention && is_indention);
+//    emitter->open_ended = 0;
+//
+//    return 1;
+//}
+//
+//static int
+//yaml_emitter_write_anchor(yaml_emitter_t *emitter,
+//        yaml_char_t *value, size_t length)
+//{
+//    yaml_string_t string;
+//    STRING_ASSIGN(string, value, length);
+//
+//    while (string.pointer != string.end) {
+//        if (!WRITE(emitter, string)) return 0;
+//    }
+//
+//    emitter->whitespace = 0;
+//    emitter->indention = 0;
+//
+//    return 1;
+//}
+//
+//static int
+//yaml_emitter_write_tag_handle(yaml_emitter_t *emitter,
+//        yaml_char_t *value, size_t length)
+//{
+//    yaml_string_t string;
+//    STRING_ASSIGN(string, value, length);
+//
+//    if (!emitter->whitespace) {
+//        if (!PUT(emitter, ' ')) return 0;
+//    }
+//
+//    while (string.pointer != string.end) {
+//        if (!WRITE(emitter, string)) return 0;
+//    }
+//
+//    emitter->whitespace = 0;
+//    emitter->indention = 0;
+//
+//    return 1;
+//}
+//
+//static int
+//yaml_emitter_write_tag_content(yaml_emitter_t *emitter,
+//        yaml_char_t *value, size_t length,
+//        int need_whitespace)
+//{
+//    yaml_string_t string;
+//    STRING_ASSIGN(string, value, length);
+//
+//    if (need_whitespace && !emitter->whitespace) {
+//        if (!PUT(emitter, ' ')) return 0;
+//    }
+//
+//    while (string.pointer != string.end) {
+//        if (IS_ALPHA(string)
+//                || CHECK(string, ';') || CHECK(string, '/')
+//                || CHECK(string, '?') || CHECK(string, ':')
+//                || CHECK(string, '@') || CHECK(string, '&')
+//                || CHECK(string, '=') || CHECK(string, '+')
+//                || CHECK(string, '$') || CHECK(string, ',')
+//                || CHECK(string, '_') || CHECK(string, '.')
+//                || CHECK(string, '~') || CHECK(string, '*')
+//                || CHECK(string, '\'') || CHECK(string, '(')
+//                || CHECK(string, ')') || CHECK(string, '[')
+//                || CHECK(string, ']')) {
+//            if (!WRITE(emitter, string)) return 0;
+//        }
+//        else {
+//            int width = WIDTH(string);
+//            unsigned int value;
+//            while (width --) {
+//                value = *(string.pointer++);
+//                if (!PUT(emitter, '%')) return 0;
+//                if (!PUT(emitter, (value >> 4)
+//                            + ((value >> 4) < 10 ? '0' : 'A' - 10)))
+//                    return 0;
+//                if (!PUT(emitter, (value & 0x0F)
+//                            + ((value & 0x0F) < 10 ? '0' : 'A' - 10)))
+//                    return 0;
+//            }
+//        }
+//    }
+//
+//    emitter->whitespace = 0;
+//    emitter->indention = 0;
+//
+//    return 1;
+//}
+//
+//static int
+//yaml_emitter_write_plain_scalar(yaml_emitter_t *emitter,
+//        yaml_char_t *value, size_t length, int allow_breaks)
+//{
+//    yaml_string_t string;
+//    int spaces = 0;
+//    int breaks = 0;
+//
+//    STRING_ASSIGN(string, value, length);
+//
+//    if (!emitter->whitespace) {
+//        if (!PUT(emitter, ' ')) return 0;
+//    }
+//
+//    while (string.pointer != string.end)
+//    {
+//        if (IS_SPACE(string))
+//        {
+//            if (allow_breaks && !spaces
+//                    && emitter->column > emitter->best_width
+//                    && !IS_SPACE_AT(string, 1)) {
+//                if (!yaml_emitter_write_indent(emitter)) return 0;
+//                MOVE(string);
+//            }
+//            else {
+//                if (!WRITE(emitter, string)) return 0;
+//            }
+//            spaces = 1;
+//        }
+//        else if (IS_BREAK(string))
+//        {
+//            if (!breaks && CHECK(string, '\n')) {
+//                if (!PUT_BREAK(emitter)) return 0;
+//            }
+//            if (!WRITE_BREAK(emitter, string)) return 0;
+//            emitter->indention = 1;
+//            breaks = 1;
+//        }
+//        else
+//        {
+//            if (breaks) {
+//                if (!yaml_emitter_write_indent(emitter)) return 0;
+//            }
+//            if (!WRITE(emitter, string)) return 0;
+//            emitter->indention = 0;
+//            spaces = 0;
+//            breaks = 0;
+//        }
+//    }
+//
+//    emitter->whitespace = 0;
+//    emitter->indention = 0;
+//    if (emitter->root_context)
+//    {
+//        emitter->open_ended = 1;
+//    }
+//
+//    return 1;
+//}
+//
+//static int
+//yaml_emitter_write_single_quoted_scalar(yaml_emitter_t *emitter,
+//        yaml_char_t *value, size_t length, int allow_breaks)
+//{
+//    yaml_string_t string;
+//    int spaces = 0;
+//    int breaks = 0;
+//
+//    STRING_ASSIGN(string, value, length);
+//
+//    if (!yaml_emitter_write_indicator(emitter, "'", 1, 0, 0))
+//        return 0;
+//
+//    while (string.pointer != string.end)
+//    {
+//        if (IS_SPACE(string))
+//        {
+//            if (allow_breaks && !spaces
+//                    && emitter->column > emitter->best_width
+//                    && string.pointer != string.start
+//                    && string.pointer != string.end - 1
+//                    && !IS_SPACE_AT(string, 1)) {
+//                if (!yaml_emitter_write_indent(emitter)) return 0;
+//                MOVE(string);
+//            }
+//            else {
+//                if (!WRITE(emitter, string)) return 0;
+//            }
+//            spaces = 1;
+//        }
+//        else if (IS_BREAK(string))
+//        {
+//            if (!breaks && CHECK(string, '\n')) {
+//                if (!PUT_BREAK(emitter)) return 0;
+//            }
+//            if (!WRITE_BREAK(emitter, string)) return 0;
+//            emitter->indention = 1;
+//            breaks = 1;
+//        }
+//        else
+//        {
+//            if (breaks) {
+//                if (!yaml_emitter_write_indent(emitter)) return 0;
+//            }
+//            if (CHECK(string, '\'')) {
+//                if (!PUT(emitter, '\'')) return 0;
+//            }
+//            if (!WRITE(emitter, string)) return 0;
+//            emitter->indention = 0;
+//            spaces = 0;
+//            breaks = 0;
+//        }
+//    }
+//
+//    if (!yaml_emitter_write_indicator(emitter, "'", 0, 0, 0))
+//        return 0;
+//
+//    emitter->whitespace = 0;
+//    emitter->indention = 0;
+//
+//    return 1;
+//}
+//
+//static int
+//yaml_emitter_write_double_quoted_scalar(yaml_emitter_t *emitter,
+//        yaml_char_t *value, size_t length, int allow_breaks)
+//{
+//    yaml_string_t string;
+//    int spaces = 0;
+//
+//    STRING_ASSIGN(string, value, length);
+//
+//    if (!yaml_emitter_write_indicator(emitter, "\"", 1, 0, 0))
+//        return 0;
+//
+//    while (string.pointer != string.end)
+//    {
+//        if (!IS_PRINTABLE(string) || (!emitter->unicode && !IS_ASCII(string))
+//                || IS_BOM(string) || IS_BREAK(string)
+//                || CHECK(string, '"') || CHECK(string, '\\'))
+//        {
+//            unsigned char octet;
+//            unsigned int width;
+//            unsigned int value;
+//            int k;
+//
+//            octet = string.pointer[0];
+//            width = (octet & 0x80) == 0x00 ? 1 :
+//                    (octet & 0xE0) == 0xC0 ? 2 :
+//                    (octet & 0xF0) == 0xE0 ? 3 :
+//                    (octet & 0xF8) == 0xF0 ? 4 : 0;
+//            value = (octet & 0x80) == 0x00 ? octet & 0x7F :
+//                    (octet & 0xE0) == 0xC0 ? octet & 0x1F :
+//                    (octet & 0xF0) == 0xE0 ? octet & 0x0F :
+//                    (octet & 0xF8) == 0xF0 ? octet & 0x07 : 0;
+//            for (k = 1; k < (int)width; k ++) {
+//                octet = string.pointer[k];
+//                value = (value << 6) + (octet & 0x3F);
+//            }
+//            string.pointer += width;
+//
+//            if (!PUT(emitter, '\\')) return 0;
+//
+//            switch (value)
+//            {
+//                case 0x00:
+//                    if (!PUT(emitter, '0')) return 0;
+//                    break;
+//
+//                case 0x07:
+//                    if (!PUT(emitter, 'a')) return 0;
+//                    break;
+//
+//                case 0x08:
+//                    if (!PUT(emitter, 'b')) return 0;
+//                    break;
+//
+//                case 0x09:
+//                    if (!PUT(emitter, 't')) return 0;
+//                    break;
+//
+//                case 0x0A:
+//                    if (!PUT(emitter, 'n')) return 0;
+//                    break;
+//
+//                case 0x0B:
+//                    if (!PUT(emitter, 'v')) return 0;
+//                    break;
+//
+//                case 0x0C:
+//                    if (!PUT(emitter, 'f')) return 0;
+//                    break;
+//
+//                case 0x0D:
+//                    if (!PUT(emitter, 'r')) return 0;
+//                    break;
+//
+//                case 0x1B:
+//                    if (!PUT(emitter, 'e')) return 0;
+//                    break;
+//
+//                case 0x22:
+//                    if (!PUT(emitter, '\"')) return 0;
+//                    break;
+//
+//                case 0x5C:
+//                    if (!PUT(emitter, '\\')) return 0;
+//                    break;
+//
+//                case 0x85:
+//                    if (!PUT(emitter, 'N')) return 0;
+//                    break;
+//
+//                case 0xA0:
+//                    if (!PUT(emitter, '_')) return 0;
+//                    break;
+//
+//                case 0x2028:
+//                    if (!PUT(emitter, 'L')) return 0;
+//                    break;
+//
+//                case 0x2029:
+//                    if (!PUT(emitter, 'P')) return 0;
+//                    break;
+//
+//                default:
+//                    if (value <= 0xFF) {
+//                        if (!PUT(emitter, 'x')) return 0;
+//                        width = 2;
+//                    }
+//                    else if (value <= 0xFFFF) {
+//                        if (!PUT(emitter, 'u')) return 0;
+//                        width = 4;
+//                    }
+//                    else {
+//                        if (!PUT(emitter, 'U')) return 0;
+//                        width = 8;
+//                    }
+//                    for (k = (width-1)*4; k >= 0; k -= 4) {
+//                        int digit = (value >> k) & 0x0F;
+//                        if (!PUT(emitter, digit + (digit < 10 ? '0' : 'A'-10)))
+//                            return 0;
+//                    }
+//            }
+//            spaces = 0;
+//        }
+//        else if (IS_SPACE(string))
+//        {
+//            if (allow_breaks && !spaces
+//                    && emitter->column > emitter->best_width
+//                    && string.pointer != string.start
+//                    && string.pointer != string.end - 1) {
+//                if (!yaml_emitter_write_indent(emitter)) return 0;
+//                if (IS_SPACE_AT(string, 1)) {
+//                    if (!PUT(emitter, '\\')) return 0;
+//                }
+//                MOVE(string);
+//            }
+//            else {
+//                if (!WRITE(emitter, string)) return 0;
+//            }
+//            spaces = 1;
+//        }
+//        else
+//        {
+//            if (!WRITE(emitter, string)) return 0;
+//            spaces = 0;
+//        }
+//    }
+//
+//    if (!yaml_emitter_write_indicator(emitter, "\"", 0, 0, 0))
+//        return 0;
+//
+//    emitter->whitespace = 0;
+//    emitter->indention = 0;
+//
+//    return 1;
+//}
+//
+//static int
+//yaml_emitter_write_block_scalar_hints(yaml_emitter_t *emitter,
+//        yaml_string_t string)
+//{
+//    char indent_hint[2];
+//    char *chomp_hint = NULL;
+//
+//    if (IS_SPACE(string) || IS_BREAK(string))
+//    {
+//        indent_hint[0] = '0' + (char)emitter->best_indent;
+//        indent_hint[1] = '\0';
+//        if (!yaml_emitter_write_indicator(emitter, indent_hint, 0, 0, 0))
+//            return 0;
+//    }
+//
+//    emitter->open_ended = 0;
+//
+//    string.pointer = string.end;
+//    if (string.start == string.pointer)
+//    {
+//        chomp_hint = "-";
+//    }
+//    else
+//    {
+//        do {
+//            string.pointer --;
+//        } while ((*string.pointer & 0xC0) == 0x80);
+//        if (!IS_BREAK(string))
+//        {
+//            chomp_hint = "-";
+//        }
+//        else if (string.start == string.pointer)
+//        {
+//            chomp_hint = "+";
+//            emitter->open_ended = 1;
+//        }
+//        else
+//        {
+//            do {
+//                string.pointer --;
+//            } while ((*string.pointer & 0xC0) == 0x80);
+//            if (IS_BREAK(string))
+//            {
+//                chomp_hint = "+";
+//                emitter->open_ended = 1;
+//            }
+//        }
+//    }
+//
+//    if (chomp_hint)
+//    {
+//        if (!yaml_emitter_write_indicator(emitter, chomp_hint, 0, 0, 0))
+//            return 0;
+//    }
+//
+//    return 1;
+//}
+//
+//static int
+//yaml_emitter_write_literal_scalar(yaml_emitter_t *emitter,
+//        yaml_char_t *value, size_t length)
+//{
+//    yaml_string_t string;
+//    int breaks = 1;
+//
+//    STRING_ASSIGN(string, value, length);
+//
+//    if (!yaml_emitter_write_indicator(emitter, "|", 1, 0, 0))
+//        return 0;
+//    if (!yaml_emitter_write_block_scalar_hints(emitter, string))
+//        return 0;
+//    if (!PUT_BREAK(emitter)) return 0;
+//    emitter->indention = 1;
+//    emitter->whitespace = 1;
+//
+//    while (string.pointer != string.end)
+//    {
+//        if (IS_BREAK(string))
+//        {
+//            if (!WRITE_BREAK(emitter, string)) return 0;
+//            emitter->indention = 1;
+//            breaks = 1;
+//        }
+//        else
+//        {
+//            if (breaks) {
+//                if (!yaml_emitter_write_indent(emitter)) return 0;
+//            }
+//            if (!WRITE(emitter, string)) return 0;
+//            emitter->indention = 0;
+//            breaks = 0;
+//        }
+//    }
+//
+//    return 1;
+//}
+//
+//static int
+//yaml_emitter_write_folded_scalar(yaml_emitter_t *emitter,
+//        yaml_char_t *value, size_t length)
+//{
+//    yaml_string_t string;
+//    int breaks = 1;
+//    int leading_spaces = 1;
+//
+//    STRING_ASSIGN(string, value, length);
+//
+//    if (!yaml_emitter_write_indicator(emitter, ">", 1, 0, 0))
+//        return 0;
+//    if (!yaml_emitter_write_block_scalar_hints(emitter, string))
+//        return 0;
+//    if (!PUT_BREAK(emitter)) return 0;
+//    emitter->indention = 1;
+//    emitter->whitespace = 1;
+//
+//    while (string.pointer != string.end)
+//    {
+//        if (IS_BREAK(string))
+//        {
+//            if (!breaks && !leading_spaces && CHECK(string, '\n')) {
+//                int k = 0;
+//                while (IS_BREAK_AT(string, k)) {
+//                    k += WIDTH_AT(string, k);
+//                }
+//                if (!IS_BLANKZ_AT(string, k)) {
+//                    if (!PUT_BREAK(emitter)) return 0;
+//                }
+//            }
+//            if (!WRITE_BREAK(emitter, string)) return 0;
+//            emitter->indention = 1;
+//            breaks = 1;
+//        }
+//        else
+//        {
+//            if (breaks) {
+//                if (!yaml_emitter_write_indent(emitter)) return 0;
+//                leading_spaces = IS_BLANK(string);
+//            }
+//            if (!breaks && IS_SPACE(string) && !IS_SPACE_AT(string, 1)
+//                    && emitter->column > emitter->best_width) {
+//                if (!yaml_emitter_write_indent(emitter)) return 0;
+//                MOVE(string);
+//            }
+//            else {
+//                if (!WRITE(emitter, string)) return 0;
+//            }
+//            emitter->indention = 0;
+//            breaks = 0;
+//        }
+//    }
+//
+//    return 1;
+//}
+//
diff --git a/writer_c.go b/writer_c.go
new file mode 100644
index 0000000..5d1afaa
--- /dev/null
+++ b/writer_c.go
@@ -0,0 +1,89 @@
+package goyaml
+
+// Set the writer error and return false.
+func yaml_emitter_set_writer_error(emitter *yaml_emitter_t, problem string) bool {
+	emitter.error = yaml_WRITER_ERROR
+	emitter.problem = problem
+	return false
+}
+
+// Flush the output buffer.
+func yaml_emitter_flush(emitter *yaml_emitter_t) bool {
+	if emitter.write_handler == nil {
+		panic("write handler not set")
+	}
+
+	// Check if the buffer is empty.
+	if len(emitter.buffer) == 0 {
+		return true
+	}
+
+	// If the output encoding is UTF-8, we don't need to recode the buffer.
+	if emitter.encoding == yaml_UTF8_ENCODING {
+		if err := emitter.write_handler(emitter, emitter.buffer); err != nil {
+			return yaml_emitter_set_writer_error(emitter, "write error: "+err.Error())
+		}
+		emitter.buffer = emitter.buffer[:0]
+		return true
+	}
+
+	// Recode the buffer into the raw buffer.
+	var low, high int
+	if emitter.encoding == yaml_UTF16LE_ENCODING {
+		low, high = 0, 1
+	} else {
+		high, low = 1, 0
+	}
+
+	pos := 0
+	for pos < len(emitter.buffer) {
+		// See the "reader.c" code for more details on UTF-8 encoding.  Note
+		// that we assume that the buffer contains a valid UTF-8 sequence.
+
+		// Read the next UTF-8 character.
+		octet := emitter.buffer[pos]
+
+		var w int
+		var value rune
+		switch {
+		case octet&0x80 == 0x00:
+			w, value = 1, rune(octet&0x7F)
+		case octet&0xE0 == 0xC0:
+			w, value = 2, rune(octet&0x1F)
+		case octet&0xF0 == 0xE0:
+			w, value = 3, rune(octet&0x0F)
+		case octet&0xF8 == 0xF0:
+			w, value = 4, rune(octet&0x07)
+		}
+		for k := 1; k < w; k++ {
+			octet = emitter.buffer[pos+k]
+			value = (value << 6) + (rune(octet) & 0x3F)
+		}
+		pos += w
+
+		// Write the character.
+		if value < 0x10000 {
+			var b [2]byte
+			b[high] = byte(value >> 8)
+			b[low] = byte(value & 0xFF)
+			emitter.raw_buffer = append(emitter.raw_buffer, b[0], b[1])
+		} else {
+			// Write the character using a surrogate pair (check "reader.c").
+			var b [4]byte
+			value -= 0x10000
+			b[high] = byte(0xD8 + (value >> 18))
+			b[low] = byte((value >> 10) & 0xFF)
+			b[high+2] = byte(0xDC + ((value >> 8) & 0xFF))
+			b[low+2] = byte(value & 0xFF)
+			emitter.raw_buffer = append(emitter.raw_buffer, b[0], b[1], b[2], b[3])
+		}
+	}
+
+	// Write the raw buffer.
+	if err := emitter.write_handler(emitter, emitter.raw_buffer); err != nil {
+		return yaml_emitter_set_writer_error(emitter, "write error: "+err.Error())
+	}
+	emitter.buffer = emitter.buffer[:0]
+	emitter.raw_buffer = emitter.raw_buffer[:0]
+	return true
+}
diff --git a/yaml_h.go b/yaml_h.go
index 0c1df00..1e95b96 100644
--- a/yaml_h.go
+++ b/yaml_h.go
@@ -326,188 +326,6 @@
 
 }
 
-///**
-// * Create the STREAM-START event.
-// *
-// * @param[out]      event       An empty event object.
-// * @param[in]       encoding    The stream encoding.
-// *
-// * @returns @c 1 if the function succeeded, @c 0 on error.
-// */
-//
-//YAML_DECLARE(int)
-//yaml_stream_start_event_initialize(yaml_event_t *event,
-//        yaml_encoding_t encoding);
-//
-///**
-// * Create the STREAM-END event.
-// *
-// * @param[out]      event       An empty event object.
-// *
-// * @returns @c 1 if the function succeeded, @c 0 on error.
-// */
-//
-//YAML_DECLARE(int)
-//yaml_stream_end_event_initialize(yaml_event_t *event);
-//
-///**
-// * Create the DOCUMENT-START event.
-// *
-// * The @a implicit argument is considered as a stylistic parameter and may be
-// * ignored by the emitter.
-// *
-// * @param[out]      event                   An empty event object.
-// * @param[in]       version_directive       The %YAML directive value or
-// *                                          @c NULL.
-// * @param[in]       tag_directives_start    The beginning of the %TAG
-// *                                          directives list.
-// * @param[in]       tag_directives_end      The end of the %TAG directives
-// *                                          list.
-// * @param[in]       implicit                If the document start indicator is
-// *                                          implicit.
-// *
-// * @returns @c 1 if the function succeeded, @c 0 on error.
-// */
-//
-//YAML_DECLARE(int)
-//yaml_document_start_event_initialize(yaml_event_t *event,
-//        yaml_version_directive_t *version_directive,
-//        yaml_tag_directive_t *tag_directives_start,
-//        yaml_tag_directive_t *tag_directives_end,
-//        int implicit);
-//
-///**
-// * Create the DOCUMENT-END event.
-// *
-// * The @a implicit argument is considered as a stylistic parameter and may be
-// * ignored by the emitter.
-// *
-// * @param[out]      event       An empty event object.
-// * @param[in]       implicit    If the document end indicator is implicit.
-// *
-// * @returns @c 1 if the function succeeded, @c 0 on error.
-// */
-//
-//YAML_DECLARE(int)
-//yaml_document_end_event_initialize(yaml_event_t *event, int implicit);
-//
-///**
-// * Create an ALIAS event.
-// *
-// * @param[out]      event       An empty event object.
-// * @param[in]       anchor      The anchor value.
-// *
-// * @returns @c 1 if the function succeeded, @c 0 on error.
-// */
-//
-//YAML_DECLARE(int)
-//yaml_alias_event_initialize(yaml_event_t *event, yaml_char_t *anchor);
-//
-///**
-// * Create a SCALAR event.
-// *
-// * The @a style argument may be ignored by the emitter.
-// *
-// * Either the @a tag attribute or one of the @a plain_implicit and
-// * @a quoted_implicit flags must be set.
-// *
-// * @param[out]      event           An empty event object.
-// * @param[in]       anchor          The scalar anchor or @c NULL.
-// * @param[in]       tag             The scalar tag or @c NULL.
-// * @param[in]       value           The scalar value.
-// * @param[in]       length          The length of the scalar value.
-// * @param[in]       plain_implicit  If the tag may be omitted for the plain
-// *                                  style.
-// * @param[in]       quoted_implicit If the tag may be omitted for any
-// *                                  non-plain style.
-// * @param[in]       style           The scalar style.
-// *
-// * @returns @c 1 if the function succeeded, @c 0 on error.
-// */
-//
-//YAML_DECLARE(int)
-//yaml_scalar_event_initialize(yaml_event_t *event,
-//        yaml_char_t *anchor, yaml_char_t *tag,
-//        yaml_char_t *value, int length,
-//        int plain_implicit, int quoted_implicit,
-//        yaml_scalar_style_t style);
-//
-///**
-// * Create a SEQUENCE-START event.
-// *
-// * The @a style argument may be ignored by the emitter.
-// *
-// * Either the @a tag attribute or the @a implicit flag must be set.
-// *
-// * @param[out]      event       An empty event object.
-// * @param[in]       anchor      The sequence anchor or @c NULL.
-// * @param[in]       tag         The sequence tag or @c NULL.
-// * @param[in]       implicit    If the tag may be omitted.
-// * @param[in]       style       The sequence style.
-// *
-// * @returns @c 1 if the function succeeded, @c 0 on error.
-// */
-//
-//YAML_DECLARE(int)
-//yaml_sequence_start_event_initialize(yaml_event_t *event,
-//        yaml_char_t *anchor, yaml_char_t *tag, int implicit,
-//        yaml_sequence_style_t style);
-//
-///**
-// * Create a SEQUENCE-END event.
-// *
-// * @param[out]      event       An empty event object.
-// *
-// * @returns @c 1 if the function succeeded, @c 0 on error.
-// */
-//
-//YAML_DECLARE(int)
-//yaml_sequence_end_event_initialize(yaml_event_t *event);
-//
-///**
-// * Create a MAPPING-START event.
-// *
-// * The @a style argument may be ignored by the emitter.
-// *
-// * Either the @a tag attribute or the @a implicit flag must be set.
-// *
-// * @param[out]      event       An empty event object.
-// * @param[in]       anchor      The mapping anchor or @c NULL.
-// * @param[in]       tag         The mapping tag or @c NULL.
-// * @param[in]       implicit    If the tag may be omitted.
-// * @param[in]       style       The mapping style.
-// *
-// * @returns @c 1 if the function succeeded, @c 0 on error.
-// */
-//
-//YAML_DECLARE(int)
-//yaml_mapping_start_event_initialize(yaml_event_t *event,
-//        yaml_char_t *anchor, yaml_char_t *tag, int implicit,
-//        yaml_mapping_style_t style);
-//
-///**
-// * Create a MAPPING-END event.
-// *
-// * @param[out]      event       An empty event object.
-// *
-// * @returns @c 1 if the function succeeded, @c 0 on error.
-// */
-//
-//YAML_DECLARE(int)
-//yaml_mapping_end_event_initialize(yaml_event_t *event);
-//
-///**
-// * Free any memory allocated for an event object.
-// *
-// * @param[in,out]   event   An event object.
-// */
-//
-//YAML_DECLARE(void)
-//yaml_event_delete(yaml_event_t *event);
-//
-//// @}
-//
-
 // Nodes
 
 const (
@@ -796,520 +614,145 @@
 	document *yaml_document_t // The currently parsed document.
 }
 
-///**
-// * @defgroup emitter Emitter Definitions
-// * @{
-// */
+// Emitter Definitions
+
+// The prototype of a write handler.
 //
-///**
-// * The prototype of a write handler.
-// *
-// * The write handler is called when the emitter needs to flush the accumulated
-// * characters to the output.  The handler should write @a size bytes of the
-// * @a buffer to the output.
-// *
-// * @param[in,out]   data        A pointer to an application data specified by
-// *                              yaml_emitter_set_output().
-// * @param[in]       buffer      The buffer with bytes to be written.
-// * @param[in]       size        The size of the buffer.
-// *
-// * @returns On success, the handler should return @c 1.  If the handler failed,
-// * the returned value should be @c 0.
-// */
+// The write handler is called when the emitter needs to flush the accumulated
+// characters to the output.  The handler should write @a size bytes of the
+// @a buffer to the output.
 //
-//typedef int yaml_write_handler_t(void *data, unsigned char *buffer, int size);
+// @param[in,out]   data        A pointer to an application data specified by
+//                              yaml_emitter_set_output().
+// @param[in]       buffer      The buffer with bytes to be written.
+// @param[in]       size        The size of the buffer.
 //
-//// The emitter states.
-//typedef enum yaml_emitter_state_e {
-//    // Expect STREAM-START.
-//    YAML_EMIT_STREAM_START_STATE,
-//    // Expect the first DOCUMENT-START or STREAM-END.
-//    YAML_EMIT_FIRST_DOCUMENT_START_STATE,
-//    // Expect DOCUMENT-START or STREAM-END.
-//    YAML_EMIT_DOCUMENT_START_STATE,
-//    // Expect the content of a document.
-//    YAML_EMIT_DOCUMENT_CONTENT_STATE,
-//    // Expect DOCUMENT-END.
-//    YAML_EMIT_DOCUMENT_END_STATE,
-//    // Expect the first item of a flow sequence.
-//    YAML_EMIT_FLOW_SEQUENCE_FIRST_ITEM_STATE,
-//    // Expect an item of a flow sequence.
-//    YAML_EMIT_FLOW_SEQUENCE_ITEM_STATE,
-//    // Expect the first key of a flow mapping.
-//    YAML_EMIT_FLOW_MAPPING_FIRST_KEY_STATE,
-//    // Expect a key of a flow mapping.
-//    YAML_EMIT_FLOW_MAPPING_KEY_STATE,
-//    // Expect a value for a simple key of a flow mapping.
-//    YAML_EMIT_FLOW_MAPPING_SIMPLE_VALUE_STATE,
-//    // Expect a value of a flow mapping.
-//    YAML_EMIT_FLOW_MAPPING_VALUE_STATE,
-//    // Expect the first item of a block sequence.
-//    YAML_EMIT_BLOCK_SEQUENCE_FIRST_ITEM_STATE,
-//    // Expect an item of a block sequence.
-//    YAML_EMIT_BLOCK_SEQUENCE_ITEM_STATE,
-//    // Expect the first key of a block mapping.
-//    YAML_EMIT_BLOCK_MAPPING_FIRST_KEY_STATE,
-//    // Expect the key of a block mapping.
-//    YAML_EMIT_BLOCK_MAPPING_KEY_STATE,
-//    // Expect a value for a simple key of a block mapping.
-//    YAML_EMIT_BLOCK_MAPPING_SIMPLE_VALUE_STATE,
-//    // Expect a value of a block mapping.
-//    YAML_EMIT_BLOCK_MAPPING_VALUE_STATE,
-//    // Expect nothing.
-//    YAML_EMIT_END_STATE
-//} yaml_emitter_state_t;
+// @returns On success, the handler should return @c 1.  If the handler failed,
+// the returned value should be @c 0.
 //
-///**
-// * The emitter structure.
-// *
-// * All members are internal.  Manage the structure using the @c yaml_emitter_
-// * family of functions.
-// */
+type yaml_write_handler_t func(emitter *yaml_emitter_t, buffer []byte) error
+
+type yaml_emitter_state_t int
+
+// The emitter states.
+const (
+	// Expect STREAM-START.
+	yaml_EMIT_STREAM_START_STATE yaml_emitter_state_t = iota
+
+	yaml_EMIT_FIRST_DOCUMENT_START_STATE       // Expect the first DOCUMENT-START or STREAM-END.
+	yaml_EMIT_DOCUMENT_START_STATE             // Expect DOCUMENT-START or STREAM-END.
+	yaml_EMIT_DOCUMENT_CONTENT_STATE           // Expect the content of a document.
+	yaml_EMIT_DOCUMENT_END_STATE               // Expect DOCUMENT-END.
+	yaml_EMIT_FLOW_SEQUENCE_FIRST_ITEM_STATE   // Expect the first item of a flow sequence.
+	yaml_EMIT_FLOW_SEQUENCE_ITEM_STATE         // Expect an item of a flow sequence.
+	yaml_EMIT_FLOW_MAPPING_FIRST_KEY_STATE     // Expect the first key of a flow mapping.
+	yaml_EMIT_FLOW_MAPPING_KEY_STATE           // Expect a key of a flow mapping.
+	yaml_EMIT_FLOW_MAPPING_SIMPLE_VALUE_STATE  // Expect a value for a simple key of a flow mapping.
+	yaml_EMIT_FLOW_MAPPING_VALUE_STATE         // Expect a value of a flow mapping.
+	yaml_EMIT_BLOCK_SEQUENCE_FIRST_ITEM_STATE  // Expect the first item of a block sequence.
+	yaml_EMIT_BLOCK_SEQUENCE_ITEM_STATE        // Expect an item of a block sequence.
+	yaml_EMIT_BLOCK_MAPPING_FIRST_KEY_STATE    // Expect the first key of a block mapping.
+	yaml_EMIT_BLOCK_MAPPING_KEY_STATE          // Expect the key of a block mapping.
+	yaml_EMIT_BLOCK_MAPPING_SIMPLE_VALUE_STATE // Expect a value for a simple key of a block mapping.
+	yaml_EMIT_BLOCK_MAPPING_VALUE_STATE        // Expect a value of a block mapping.
+	yaml_EMIT_END_STATE                        // Expect nothing.
+)
+
+// The emitter structure.
 //
-//typedef struct yaml_emitter_s {
-//
-//    /**
-//     * @name Error handling
-//     * @{
-//     */
-//
-//    // Error type.
-//    yaml_error_type_t error;
-//    // Error description.
-//    char *problem;
-//
-//    /**
-//     * @}
-//     */
-//
-//    /**
-//     * @name Writer stuff
-//     * @{
-//     */
-//
-//    // Write handler.
-//    yaml_write_handler_t *write_handler;
-//
-//    // A pointer for passing to the white handler.
-//    void *write_handler_data;
-//
-//    // Standard (string or file) output data.
-//    union {
-//        // String output data.
-//        struct {
-//            // The buffer pointer.
-//            unsigned char *buffer;
-//            // The buffer size.
-//            int size;
-//            // The number of written bytes.
-//            int *size_written;
-//        } string;
-//
-//        // File output data.
-//        FILE *file;
-//    } output;
-//
-//    // The working buffer.
-//    struct {
-//        // The beginning of the buffer.
-//        yaml_char_t *start;
-//        // The end of the buffer.
-//        yaml_char_t *end;
-//        // The current position of the buffer.
-//        yaml_char_t *pointer;
-//        // The last filled position of the buffer.
-//        yaml_char_t *last;
-//    } buffer;
-//
-//    // The raw buffer.
-//    struct {
-//        // The beginning of the buffer.
-//        unsigned char *start;
-//        // The end of the buffer.
-//        unsigned char *end;
-//        // The current position of the buffer.
-//        unsigned char *pointer;
-//        // The last filled position of the buffer.
-//        unsigned char *last;
-//    } raw_buffer;
-//
-//    // The stream encoding.
-//    yaml_encoding_t encoding;
-//
-//    /**
-//     * @}
-//     */
-//
-//    /**
-//     * @name Emitter stuff
-//     * @{
-//     */
-//
-//    // If the output is in the canonical style?
-//    int canonical;
-//    // The number of indentation spaces.
-//    int best_indent;
-//    // The preferred width of the output lines.
-//    int best_width;
-//    // Allow unescaped non-ASCII characters?
-//    int unicode;
-//    // The preferred line break.
-//    yaml_break_t line_break;
-//
-//    // The stack of states.
-//    struct {
-//        // The beginning of the stack.
-//        yaml_emitter_state_t *start;
-//        // The end of the stack.
-//        yaml_emitter_state_t *end;
-//        // The top of the stack.
-//        yaml_emitter_state_t *top;
-//    } states;
-//
-//    // The current emitter state.
-//    yaml_emitter_state_t state;
-//
-//    // The event queue.
-//    struct {
-//        // The beginning of the event queue.
-//        yaml_event_t *start;
-//        // The end of the event queue.
-//        yaml_event_t *end;
-//        // The head of the event queue.
-//        yaml_event_t *head;
-//        // The tail of the event queue.
-//        yaml_event_t *tail;
-//    } events;
-//
-//    // The stack of indentation levels.
-//    struct {
-//        // The beginning of the stack.
-//        int *start;
-//        // The end of the stack.
-//        int *end;
-//        // The top of the stack.
-//        int *top;
-//    } indents;
-//
-//    // The list of tag directives.
-//    struct {
-//        // The beginning of the list.
-//        yaml_tag_directive_t *start;
-//        // The end of the list.
-//        yaml_tag_directive_t *end;
-//        // The top of the list.
-//        yaml_tag_directive_t *top;
-//    } tag_directives;
-//
-//    // The current indentation level.
-//    int indent;
-//
-//    // The current flow level.
-//    int flow_level;
-//
-//    // Is it the document root context?
-//    int root_context;
-//    // Is it a sequence context?
-//    int sequence_context;
-//    // Is it a mapping context?
-//    int mapping_context;
-//    // Is it a simple mapping key context?
-//    int simple_key_context;
-//
-//    // The current line.
-//    int line;
-//    // The current column.
-//    int column;
-//    // If the last character was a whitespace?
-//    int whitespace;
-//    // If the last character was an indentation character (' ', '-', '?', ':')?
-//    int indention;
-//    // If an explicit document end is required?
-//    int open_ended;
-//
-//    // Anchor analysis.
-//    struct {
-//        // The anchor value.
-//        yaml_char_t *anchor;
-//        // The anchor length.
-//        int anchor_length;
-//        // Is it an alias?
-//        int alias;
-//    } anchor_data;
-//
-//    // Tag analysis.
-//    struct {
-//        // The tag handle.
-//        yaml_char_t *handle;
-//        // The tag handle length.
-//        int handle_length;
-//        // The tag suffix.
-//        yaml_char_t *suffix;
-//        // The tag suffix length.
-//        int suffix_length;
-//    } tag_data;
-//
-//    // Scalar analysis.
-//    struct {
-//        // The scalar value.
-//        yaml_char_t *value;
-//        // The scalar length.
-//        int length;
-//        // Does the scalar contain line breaks?
-//        int multiline;
-//        // Can the scalar be expessed in the flow plain style?
-//        int flow_plain_allowed;
-//        // Can the scalar be expressed in the block plain style?
-//        int block_plain_allowed;
-//        // Can the scalar be expressed in the single quoted style?
-//        int single_quoted_allowed;
-//        // Can the scalar be expressed in the literal or folded styles?
-//        int block_allowed;
-//        // The output style.
-//        yaml_scalar_style_t style;
-//    } scalar_data;
-//
-//    /**
-//     * @}
-//     */
-//
-//    /**
-//     * @name Dumper stuff
-//     * @{
-//     */
-//
-//    // If the stream was already opened?
-//    int opened;
-//    // If the stream was already closed?
-//    int closed;
-//
-//    // The information associated with the document nodes.
-//    struct {
-//        // The number of references.
-//        int references;
-//        // The anchor id.
-//        int anchor;
-//        // If the node has been emitted?
-//        int serialized;
-//    } *anchors;
-//
-//    // The last assigned anchor id.
-//    int last_anchor_id;
-//
-//    // The currently emitted document.
-//    yaml_document_t *document;
-//
-//    /**
-//     * @}
-//     */
-//
-//} yaml_emitter_t;
-//
-///**
-// * Initialize an emitter.
-// *
-// * This function creates a new emitter object.  An application is responsible
-// * for destroying the object using the yaml_emitter_delete() function.
-// *
-// * @param[out]      emitter     An empty parser object.
-// *
-// * @returns @c 1 if the function succeeded, @c 0 on error.
-// */
-//
-//YAML_DECLARE(int)
-//yaml_emitter_initialize(yaml_emitter_t *emitter);
-//
-///**
-// * Destroy an emitter.
-// *
-// * @param[in,out]   emitter     An emitter object.
-// */
-//
-//YAML_DECLARE(void)
-//yaml_emitter_delete(yaml_emitter_t *emitter);
-//
-///**
-// * Set a string output.
-// *
-// * The emitter will write the output characters to the @a output buffer of the
-// * size @a size.  The emitter will set @a size_written to the number of written
-// * bytes.  If the buffer is smaller than required, the emitter produces the
-// * YAML_WRITE_ERROR error.
-// *
-// * @param[in,out]   emitter         An emitter object.
-// * @param[in]       output          An output buffer.
-// * @param[in]       size            The buffer size.
-// * @param[in]       size_written    The pointer to save the number of written
-// *                                  bytes.
-// */
-//
-//YAML_DECLARE(void)
-//yaml_emitter_set_output_string(yaml_emitter_t *emitter,
-//        unsigned char *output, int size, size_t *size_written);
-//
-///**
-// * Set a file output.
-// *
-// * @a file should be a file object open for writing.  The application is
-// * responsible for closing the @a file.
-// *
-// * @param[in,out]   emitter     An emitter object.
-// * @param[in]       file        An open file.
-// */
-//
-//YAML_DECLARE(void)
-//yaml_emitter_set_output_file(yaml_emitter_t *emitter, FILE *file);
-//
-///**
-// * Set a generic output handler.
-// *
-// * @param[in,out]   emitter     An emitter object.
-// * @param[in]       handler     A write handler.
-// * @param[in]       data        Any application data for passing to the write
-// *                              handler.
-// */
-//
-//YAML_DECLARE(void)
-//yaml_emitter_set_output(yaml_emitter_t *emitter,
-//        yaml_write_handler_t *handler, void *data);
-//
-///**
-// * Set the output encoding.
-// *
-// * @param[in,out]   emitter     An emitter object.
-// * @param[in]       encoding    The output encoding.
-// */
-//
-//YAML_DECLARE(void)
-//yaml_emitter_set_encoding(yaml_emitter_t *emitter, yaml_encoding_t encoding);
-//
-///**
-// * Set if the output should be in the "canonical" format as in the YAML
-// * specification.
-// *
-// * @param[in,out]   emitter     An emitter object.
-// * @param[in]       canonical   If the output is canonical.
-// */
-//
-//YAML_DECLARE(void)
-//yaml_emitter_set_canonical(yaml_emitter_t *emitter, int canonical);
-//
-///**
-// * Set the intendation increment.
-// *
-// * @param[in,out]   emitter     An emitter object.
-// * @param[in]       indent      The indentation increment (1 < . < 10).
-// */
-//
-//YAML_DECLARE(void)
-//yaml_emitter_set_indent(yaml_emitter_t *emitter, int indent);
-//
-///**
-// * Set the preferred line width. @c -1 means unlimited.
-// *
-// * @param[in,out]   emitter     An emitter object.
-// * @param[in]       width       The preferred line width.
-// */
-//
-//YAML_DECLARE(void)
-//yaml_emitter_set_width(yaml_emitter_t *emitter, int width);
-//
-///**
-// * Set if unescaped non-ASCII characters are allowed.
-// *
-// * @param[in,out]   emitter     An emitter object.
-// * @param[in]       unicode     If unescaped Unicode characters are allowed.
-// */
-//
-//YAML_DECLARE(void)
-//yaml_emitter_set_unicode(yaml_emitter_t *emitter, int unicode);
-//
-///**
-// * Set the preferred line break.
-// *
-// * @param[in,out]   emitter     An emitter object.
-// * @param[in]       line_break  The preferred line break.
-// */
-//
-//YAML_DECLARE(void)
-//yaml_emitter_set_break(yaml_emitter_t *emitter, yaml_break_t line_break);
-//
-///**
-// * Emit an event.
-// *
-// * The event object may be generated using the yaml_parser_parse() function.
-// * The emitter takes the responsibility for the event object and destroys its
-// * content after it is emitted. The event object is destroyed even if the
-// * function fails.
-// *
-// * @param[in,out]   emitter     An emitter object.
-// * @param[in,out]   event       An event object.
-// *
-// * @returns @c 1 if the function succeeded, @c 0 on error.
-// */
-//
-//YAML_DECLARE(int)
-//yaml_emitter_emit(yaml_emitter_t *emitter, yaml_event_t *event);
-//
-///**
-// * Start a YAML stream.
-// *
-// * This function should be used before yaml_emitter_dump() is called.
-// *
-// * @param[in,out]   emitter     An emitter object.
-// *
-// * @returns @c 1 if the function succeeded, @c 0 on error.
-// */
-//
-//YAML_DECLARE(int)
-//yaml_emitter_open(yaml_emitter_t *emitter);
-//
-///**
-// * Finish a YAML stream.
-// *
-// * This function should be used after yaml_emitter_dump() is called.
-// *
-// * @param[in,out]   emitter     An emitter object.
-// *
-// * @returns @c 1 if the function succeeded, @c 0 on error.
-// */
-//
-//YAML_DECLARE(int)
-//yaml_emitter_close(yaml_emitter_t *emitter);
-//
-///**
-// * Emit a YAML document.
-// *
-// * The documen object may be generated using the yaml_parser_load() function
-// * or the yaml_document_initialize() function.  The emitter takes the
-// * responsibility for the document object and destoys its content after
-// * it is emitted. The document object is destroyedeven if the function fails.
-// *
-// * @param[in,out]   emitter     An emitter object.
-// * @param[in,out]   document    A document object.
-// *
-// * @returns @c 1 if the function succeeded, @c 0 on error.
-// */
-//
-//YAML_DECLARE(int)
-//yaml_emitter_dump(yaml_emitter_t *emitter, yaml_document_t *document);
-//
-///**
-// * Flush the accumulated characters to the output.
-// *
-// * @param[in,out]   emitter     An emitter object.
-// *
-// * @returns @c 1 if the function succeeded, @c 0 on error.
-// */
-//
-//YAML_DECLARE(int)
-//yaml_emitter_flush(yaml_emitter_t *emitter);
-//
-//// @}
-//
-//#ifdef __cplusplus
-//}
-//#endif
-//
-//#endif /* #ifndef YAML_H */
-//
+// All members are internal.  Manage the structure using the @c yaml_emitter_
+// family of functions.
+type yaml_emitter_t struct {
+
+	// Error handling
+
+	error   yaml_error_type_t // Error type.
+	problem string            // Error description.
+
+	// Writer stuff
+
+	write_handler yaml_write_handler_t // Write handler.
+
+	output_buffer *[]byte   // String output data.
+	output_file   io.Writer // File output data.
+
+	buffer     []byte // The working buffer.
+	buffer_pos int    // The current position of the buffer.
+
+	raw_buffer     []byte // The raw buffer.
+	raw_buffer_pos int    // The current position of the buffer.
+
+	encoding yaml_encoding_t // The stream encoding.
+
+	// Emitter stuff
+
+	canonical   bool         // If the output is in the canonical style?
+	best_indent int          // The number of indentation spaces.
+	best_width  int          // The preferred width of the output lines.
+	unicode     bool         // Allow unescaped non-ASCII characters?
+	line_break  yaml_break_t // The preferred line break.
+
+	state  yaml_emitter_state_t   // The current emitter state.
+	states []yaml_emitter_state_t // The stack of states.
+
+	events      []yaml_event_t // The event queue.
+	events_head int            // The head of the event queue.
+
+	indents []int // The stack of indentation levels.
+
+	tag_directives []yaml_tag_directive_t // The list of tag directives.
+
+	indent int // The current indentation level.
+
+	flow_level int // The current flow level.
+
+	root_context       bool // Is it the document root context?
+	sequence_context   bool // Is it a sequence context?
+	mapping_context    bool // Is it a mapping context?
+	simple_key_context bool // Is it a simple mapping key context?
+
+	line       int  // The current line.
+	column     int  // The current column.
+	whitespace bool // If the last character was a whitespace?
+	indention  bool // If the last character was an indentation character (' ', '-', '?', ':')?
+	open_ended bool // If an explicit document end is required?
+
+	// Anchor analysis.
+	anchor_data struct {
+		anchor []byte // The anchor value.
+		alias  bool   // Is it an alias?
+	}
+
+	// Tag analysis.
+	tag_data struct {
+		handle []byte // The tag handle.
+		suffix []byte // The tag suffix.
+	}
+
+	// Scalar analysis.
+	scalar_data struct {
+		value                 []byte              // The scalar value.
+		multiline             bool                // Does the scalar contain line breaks?
+		flow_plain_allowed    bool                // Can the scalar be expessed in the flow plain style?
+		block_plain_allowed   bool                // Can the scalar be expressed in the block plain style?
+		single_quoted_allowed bool                // Can the scalar be expressed in the single quoted style?
+		block_allowed         bool                // Can the scalar be expressed in the literal or folded styles?
+		style                 yaml_scalar_style_t // The output style.
+	}
+
+	// Dumper stuff
+
+	opened bool // If the stream was already opened?
+	closed bool // If the stream was already closed?
+
+	// The information associated with the document nodes.
+	anchors *struct {
+		references int  // The number of references.
+		anchor     int  // The anchor id.
+		serialized bool // If the node has been emitted?
+	}
+
+	last_anchor_id int // The last assigned anchor id.
+
+	document *yaml_document_t // The currently emitted document.
+}