diff --git a/Data/Yaml/Syck.hsc b/Data/Yaml/Syck.hsc
--- a/Data/Yaml/Syck.hsc
+++ b/Data/Yaml/Syck.hsc
@@ -11,6 +11,7 @@
 
 import Control.Exception (bracket)
 import Data.IORef
+import Data.Maybe (fromJust)
 import Data.Generics
 import Foreign.Ptr
 import Foreign.StablePtr
@@ -19,6 +20,7 @@
 import Foreign.Marshal.Alloc
 import Foreign.Marshal.Utils
 import Foreign.Storable
+import System.IO.Unsafe
 import GHC.Ptr (Ptr(..))
 import qualified Data.HashTable as Hash
 import qualified Data.ByteString.Char8 as Buf
@@ -60,7 +62,7 @@
 type SyckParser = Ptr ()
 type SyckNodeHandler = SyckParser -> SyckNode -> IO SYMID
 type SyckErrorHandler = SyckParser -> CString -> IO ()
-type SyckBadAnchorHandler = SyckParser -> CString -> IO SyckNode
+type SyckBadAnchorHandler = SyckParser -> CString -> IO SyckNodePtr
 type SyckNodePtr = Ptr CString
 type SyckEmitter = Ptr ()  
 type SyckEmitterHandler = SyckEmitter -> Ptr () -> IO ()
@@ -68,8 +70,11 @@
 data SyckKind = SyckMap | SyckSeq | SyckStr
     deriving (Show, Ord, Eq, Enum)
 
+maxId :: SYMID
+maxId = maxBound
+
 nilNode :: YamlNode
-nilNode = MkNode 0 ENil Nothing ASingleton
+nilNode = MkNode maxId ENil Nothing ASingleton
 
 {-# INLINE unpackBuf #-}
 unpackBuf :: Buf -> String
@@ -84,10 +89,10 @@
 tagNode tag node               = node{n_tag = tag}
 
 mkNode :: YamlElem -> YamlNode
-mkNode x = MkNode 0 x Nothing ASingleton
+mkNode x = MkNode maxId x Nothing ASingleton
 
 mkTagNode :: String -> YamlElem -> YamlNode
-mkTagNode tag e = MkNode 0 e (Just $! packBuf tag) ASingleton
+mkTagNode tag e = MkNode maxId e (Just $! packBuf tag) ASingleton
 
 mkTagStrNode :: String -> String -> YamlNode
 mkTagStrNode tag str = mkTagNode tag (EStr $! packBuf str)
@@ -182,12 +187,14 @@
 
 emitNode freeze e n | ESeq sq <- n_elem n = do
     withTag n (Ptr "array"##) $ \tag ->
+--      syck_emit_seq e tag seqInline
         syck_emit_seq e tag seqNone
     mapM_ (syck_emit_item e) =<< mapM freeze sq
     syck_emit_end e
 
 emitNode freeze e n | EMap m <- n_elem n = do
     withTag n (Ptr "map"##) $ \tag ->
+--      syck_emit_map e tag mapInline
         syck_emit_map e tag mapNone
     flip mapM_ m (\(k,v) -> do
         syck_emit_item e =<< freeze k
@@ -209,11 +216,12 @@
 parseYamlCStr :: CString -> IO YamlNode
 parseYamlCStr cstr = do
     bracket syck_new_parser syck_free_parser $ \parser -> do
-        err <- newIORef Nothing
+        err     <- newIORef Nothing
+        badancs <- Hash.new (==) Hash.hashInt
         syck_parser_str_auto parser cstr nullFunPtr
-        syck_parser_handler parser =<< mkNodeCallback nodeCallback
+        syck_parser_handler parser =<< mkNodeCallback (nodeCallback badancs)
         syck_parser_error_handler parser =<< mkErrorCallback (errorCallback err)
-        syck_parser_bad_anchor_handler parser =<< mkBadHandlerCallback badAnchorHandlerCallback
+        syck_parser_bad_anchor_handler parser =<< mkBadHandlerCallback (badAnchorHandlerCallback badancs)
         syck_parser_implicit_typing parser 0
         syck_parser_taguri_expansion parser 0
         symId <- syck_parse parser
@@ -223,19 +231,50 @@
             Nothing     -> return nilNode
             Just e      -> fail e
 
-nodeCallback :: SyckParser -> SyckNode -> IO SYMID
-nodeCallback parser syckNode = do
+type BadAnchorTable = Hash.HashTable Int YamlNode
+
+
+nodeCallback :: BadAnchorTable -> SyckParser -> SyckNode -> IO SYMID
+nodeCallback badancs parser syckNode = mdo
+    nodeId  <- #{peek SyckNode, id} syckNode
     kind    <- syckNodeKind syckNode
-    len     <- syckNodeLength kind syckNode
-    node    <- parseNode kind parser syckNode len
+
+    let makeRegularNode = do
+        len     <- syckNodeLength kind syckNode
+        parseNode kind parser syckNode len symId
+
+    node    <- case kind of
+        SyckMap -> do
+            rv  <- Hash.lookup badancs (syckNode `minusPtr` nullPtr)
+            case rv of
+                Just{}  -> do
+                    -- print ("bad anchor wanted", syckNode)
+                    unsafeInterleaveIO (fmap fromJust (Hash.lookup badancs (nodePtr `minusPtr` nullPtr)))
+                _       -> makeRegularNode
+        _       -> makeRegularNode
     nodePtr <- writeNode node
-    symId   <- syck_add_sym parser nodePtr
-    return (fromIntegral symId)
 
-badAnchorHandlerCallback :: SyckBadAnchorHandler
-badAnchorHandlerCallback _parser _cstr = do
-    fail "moose!"
+    -- Do something here about circular refs.
+    case nodeId :: SYMID of
+        0   -> return False
+        _   -> alloca $ \origPtr -> do
+            syck_lookup_sym parser nodeId origPtr
+            ptr <- peek origPtr
+            -- print ("bad anchor handled", nodeId, ptr)
+            Hash.update badancs (ptr `minusPtr` nullPtr) node
 
+    symId   <- fmap fromIntegral (syck_add_sym parser nodePtr)
+
+    return symId
+
+badAnchorHandlerCallback :: BadAnchorTable -> SyckBadAnchorHandler
+badAnchorHandlerCallback badancs parser cstr = do
+    syckNode    <- syck_alloc_map
+    -- msg         <- peekCString cstr
+    -- print ("bad anchor encountered", syckNode)
+    Hash.insert badancs (syckNode `minusPtr` nullPtr) (error "unhandled bad anchor")
+    return syckNode
+
 errorCallback :: IORef (Maybe String) -> SyckErrorHandler
 errorCallback err parser cstr = do
     msg     <- peekCString cstr
@@ -250,8 +289,10 @@
 
 freezeNode :: Hash.HashTable Int (Ptr a) -> YamlNode -> IO (Ptr a)
 freezeNode nodes MkNode{ n_anchor = AReference n } = do
-    Just ptr <- Hash.lookup nodes n
-    return ptr
+    rv <- Hash.lookup nodes n
+    case rv of
+        Just ptr    -> return ptr
+        _           -> fail $ "Failed to resolve reference: " ++ show n
 freezeNode nodes node = do
     ptr     <- newStablePtr node
     case n_anchor node of
@@ -308,8 +349,8 @@
 syckNodeLength SyckSeq = (#{peek struct SyckSeq, idx} =<<) . #{peek SyckNode, data}
 syckNodeLength SyckStr = (#{peek struct SyckStr, len} =<<) . #{peek SyckNode, data}
 
-parseNode :: SyckKind -> SyckParser -> SyckNode -> CLong -> IO YamlNode
-parseNode SyckMap parser syckNode len = do
+parseNode :: SyckKind -> SyckParser -> SyckNode -> CLong -> SYMID -> IO YamlNode
+parseNode SyckMap parser syckNode len nid = do
     tag   <- syckNodeTag syckNode
     pairs <- (`mapM` [0..len-1]) $ \idx -> do
         keyId   <- syck_map_read syckNode 0 idx
@@ -317,20 +358,20 @@
         valId   <- syck_map_read syckNode 1 idx
         val     <- readNode parser valId
         return (key, val)
-    return $ nilNode{ n_elem = EMap pairs, n_tag = tag}
+    return $ nilNode{ n_elem = EMap pairs, n_tag = tag, n_id = nid }
 
-parseNode SyckSeq parser syckNode len = do
+parseNode SyckSeq parser syckNode len nid = do
     tag   <- syckNodeTag syckNode
     nodes <- (`mapM` [0..len-1]) $ \idx -> do
         symId   <- syck_seq_read syckNode idx
         readNode parser symId
-    return $ nilNode{ n_elem = ESeq nodes, n_tag = tag }
+    return $ nilNode{ n_elem = ESeq nodes, n_tag = tag, n_id = nid }
 
-parseNode SyckStr _ syckNode len = do
+parseNode SyckStr _ syckNode len nid = do
     tag   <- syckNodeTag syckNode
     cstr  <- syck_str_read syckNode
     buf   <- copyCStringLen (cstr, fromEnum len)
-    let node = nilNode{ n_elem = EStr buf, n_tag = tag }
+    let node = nilNode{ n_elem = EStr buf, n_tag = tag, n_id = nid }
     if tag == Nothing && Buf.length buf == 1 && Buf.index buf 0 == '~'
         then do
             style <- syck_str_style syckNode
@@ -356,6 +397,9 @@
 
 foreign import ccall
     syck_new_parser :: IO SyckParser
+
+foreign import ccall
+    syck_alloc_map :: IO SyckNodePtr
 
 foreign import ccall
     syck_parser_str_auto :: SyckParser -> CString -> FunPtr () -> IO ()
diff --git a/HsSyck.cabal b/HsSyck.cabal
--- a/HsSyck.cabal
+++ b/HsSyck.cabal
@@ -1,5 +1,5 @@
 Name:                HsSyck
-Version:             0.2
+Version:             0.3
 Category:            Data
 Synopsis:            Fast, lightweight YAML loader and dumper
 Description:         Fast, lightweight YAML loader and dumper
@@ -15,4 +15,5 @@
 c-sources:           syck/bytecode.c syck/emitter.c syck/gram.c syck/handler.c
                      syck/implicit.c syck/node.c syck/syck.c syck/syck_st.c syck/token.c
                      syck/yaml2byte.c 
+extra-source-files:  syck/syck.h syck/syck_st.h syck/gram.h syck/yamlbyte.h
 include-dirs:        syck
diff --git a/syck/gram.h b/syck/gram.h
new file mode 100644
--- /dev/null
+++ b/syck/gram.h
@@ -0,0 +1,79 @@
+/* A Bison parser, made by GNU Bison 1.875d.  */
+
+/* Skeleton parser for Yacc-like parsing with Bison,
+   Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.  */
+
+/* As a special exception, when this file is copied by Bison into a
+   Bison output file, you may use that output file without restriction.
+   This special exception was added by the Free Software Foundation
+   in version 1.24 of Bison.  */
+
+/* Tokens.  */
+#ifndef YYTOKENTYPE
+# define YYTOKENTYPE
+   /* Put the tokens into the symbol table, so that GDB and other debuggers
+      know about them.  */
+   enum yytokentype {
+     YAML_ANCHOR = 258,
+     YAML_ALIAS = 259,
+     YAML_TRANSFER = 260,
+     YAML_TAGURI = 261,
+     YAML_ITRANSFER = 262,
+     YAML_WORD = 263,
+     YAML_PLAIN = 264,
+     YAML_BLOCK = 265,
+     YAML_DOCSEP = 266,
+     YAML_IOPEN = 267,
+     YAML_INDENT = 268,
+     YAML_IEND = 269
+   };
+#endif
+#define YAML_ANCHOR 258
+#define YAML_ALIAS 259
+#define YAML_TRANSFER 260
+#define YAML_TAGURI 261
+#define YAML_ITRANSFER 262
+#define YAML_WORD 263
+#define YAML_PLAIN 264
+#define YAML_BLOCK 265
+#define YAML_DOCSEP 266
+#define YAML_IOPEN 267
+#define YAML_INDENT 268
+#define YAML_IEND 269
+
+
+
+
+#if ! defined (YYSTYPE) && ! defined (YYSTYPE_IS_DECLARED)
+#line 35 "gram.y"
+typedef union YYSTYPE {
+    SYMID nodeId;
+    SyckNode *nodeData;
+    char *name;
+} YYSTYPE;
+/* Line 1285 of yacc.c.  */
+#line 71 "gram.h"
+# define yystype YYSTYPE /* obsolescent; will be withdrawn */
+# define YYSTYPE_IS_DECLARED 1
+# define YYSTYPE_IS_TRIVIAL 1
+#endif
+
+
+
+
+
diff --git a/syck/syck.h b/syck/syck.h
new file mode 100644
--- /dev/null
+++ b/syck/syck.h
@@ -0,0 +1,481 @@
+/*
+ * syck.h
+ *
+ * $Author: why $
+ * $Date: 2005-11-14 07:43:56 +0800 (一, 14 11 2005) $
+ *
+ * Copyright (C) 2003 why the lucky stiff
+ */
+
+#ifndef SYCK_H
+#define SYCK_H
+
+#ifndef HAVE_STDLIB_H
+#define HAVE_STDLIB_H
+#endif
+
+#ifndef HAVE_STRING_H
+#define HAVE_STRING_H
+#endif
+
+#define SYCK_YAML_MAJOR 1
+#define SYCK_YAML_MINOR 0
+
+#define SYCK_VERSION    "0.61"
+#define YAML_DOMAIN     "yaml.org,2002"
+
+#ifdef HAVE_STDLIB_H
+# include <stdlib.h>
+#endif
+
+#ifdef HAVE_STRING_H
+# include <string.h>
+#else
+# include <strings.h>
+#endif
+
+#ifdef HAVE_INTRINSICS_H
+# include <intrinsics.h>
+#endif
+
+#include <stddef.h>
+#include <stdio.h>
+#include <ctype.h>
+#ifdef HAVE_ST_H
+#include <st.h>
+#else
+#include "syck_st.h"
+#endif
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+/*
+ * Memory Allocation
+ */
+#if defined(HAVE_ALLOCA_H) && !defined(__GNUC__)
+#include <alloca.h>
+#endif
+
+#if DEBUG
+  void syck_assert( char *, unsigned );
+# define ASSERT(f) \
+    if ( f ) \
+        {}   \
+    else     \
+        syck_assert( __FILE__, __LINE__ )
+#else
+# define ASSERT(f)
+#endif
+
+#ifndef NULL
+# define NULL (void *)0
+#endif
+
+#define ALLOC_CT 8
+#define SYCK_BUFFERSIZE 4096
+#define S_ALLOC_N(type,n) (type*)malloc(sizeof(type)*(n))
+#define S_ALLOC(type) (type*)malloc(sizeof(type))
+#define S_REALLOC_N(var,type,n) (var)=(type*)realloc((char*)(var),sizeof(type)*(n))
+#define S_FREE(n) free(n); n = NULL;
+
+#define S_ALLOCA_N(type,n) (type*)alloca(sizeof(type)*(n))
+
+#define S_MEMZERO(p,type,n) memset((p), 0, sizeof(type)*(n))
+#define S_MEMCPY(p1,p2,type,n) memcpy((p1), (p2), sizeof(type)*(n))
+#define S_MEMMOVE(p1,p2,type,n) memmove((p1), (p2), sizeof(type)*(n))
+#define S_MEMCMP(p1,p2,type,n) memcmp((p1), (p2), sizeof(type)*(n))
+
+#define BLOCK_FOLD  10
+#define BLOCK_LIT   20
+#define BLOCK_PLAIN 30
+#define NL_CHOMP    40
+#define NL_KEEP     50
+
+/*
+ * Node definitions
+ */
+#ifndef ST_DATA_T_DEFINED
+typedef long st_data_t;
+#endif
+
+#define SYMID unsigned long
+
+typedef struct _syck_node SyckNode;
+
+enum syck_kind_tag {
+    syck_map_kind,
+    syck_seq_kind,
+    syck_str_kind
+};
+
+enum map_part {
+    map_key,
+    map_value
+};
+
+enum map_style {
+    map_none,
+    map_inline
+};
+
+enum seq_style {
+    seq_none,
+    seq_inline
+};
+
+enum scalar_style {
+    scalar_none,
+    scalar_1quote,
+    scalar_2quote,
+    scalar_fold,
+    scalar_literal,
+    scalar_plain
+};
+
+/*
+ * Node metadata struct
+ */
+struct _syck_node {
+    /* Symbol table ID */
+    SYMID id;
+    /* Underlying kind */
+    enum syck_kind_tag kind;
+    /* Fully qualified tag-uri for type */
+    char *type_id;
+    /* Anchor name */
+    char *anchor;
+    union {
+        /* Storage for map data */
+        struct SyckMap {
+            enum map_style style;
+            SYMID *keys;
+            SYMID *values;
+            long capa;
+            long idx;
+        } *pairs;
+        /* Storage for sequence data */
+        struct SyckSeq {
+            enum seq_style style;
+            SYMID *items;
+            long capa;
+            long idx;
+        } *list;
+        /* Storage for string data */
+        struct SyckStr {
+            enum scalar_style style;
+            char *ptr;
+            long len;
+        } *str;
+    } data;
+    /* Shortcut node */
+    void *shortcut;
+};
+
+/*
+ * Parser definitions
+ */
+typedef struct _syck_parser SyckParser;
+typedef struct _syck_file SyckIoFile;
+typedef struct _syck_str SyckIoStr;
+typedef struct _syck_level SyckLevel;
+
+typedef SYMID (*SyckNodeHandler)(SyckParser *, SyckNode *);
+typedef void (*SyckErrorHandler)(SyckParser *, char *);
+typedef SyckNode * (*SyckBadAnchorHandler)(SyckParser *, char *);
+typedef long (*SyckIoFileRead)(char *, SyckIoFile *, long, long); 
+typedef long (*SyckIoStrRead)(char *, SyckIoStr *, long, long);
+
+enum syck_io_type {
+    syck_io_str,
+    syck_io_file
+};
+
+enum syck_parser_input {
+    syck_yaml_utf8,
+    syck_yaml_utf16,
+    syck_yaml_utf32,
+    syck_bytecode_utf8
+};
+
+enum syck_level_status {
+    syck_lvl_header,
+    syck_lvl_doc,
+    syck_lvl_open,
+    syck_lvl_seq,
+    syck_lvl_map,
+    syck_lvl_block,
+    syck_lvl_str,
+    syck_lvl_iseq,
+    syck_lvl_imap,
+    syck_lvl_end,
+    syck_lvl_pause,
+    syck_lvl_anctag,
+    syck_lvl_mapx,
+    syck_lvl_seqx
+};
+
+/*
+ * Parser structs
+ */
+struct _syck_file {
+    /* File pointer */
+    FILE *ptr;
+    /* Function which FILE -> buffer */
+    SyckIoFileRead read;
+};
+
+struct _syck_str {
+    /* String buffer pointers */
+    char *beg, *ptr, *end;
+    /* Function which string -> buffer */
+    SyckIoStrRead read;
+};
+
+struct _syck_level {
+    /* Indent */
+    int spaces;
+    /* Counts nodes emitted at this level, useful for parsing 
+     * keys and pairs in bytecode */
+    int ncount;
+    /* Does node have anchors or tags? */
+    int anctag;
+    /* Domain prefixing at the given level */
+    char *domain;
+    /* Keeps a node status */
+    enum syck_level_status status;
+};
+
+struct _syck_parser {
+    /* Root node */
+    SYMID root, root_on_error;
+    /* Implicit typing flag */
+    int implicit_typing, taguri_expansion;
+    /* Scripting language function to handle nodes */
+    SyckNodeHandler handler;
+    /* Error handler */
+    SyckErrorHandler error_handler;
+    /* InvalidAnchor handler */
+    SyckBadAnchorHandler bad_anchor_handler;
+    /* Parser input type */
+    enum syck_parser_input input_type;
+    /* IO type */
+    enum syck_io_type io_type;
+    /* Custom buffer size */
+    size_t bufsize;
+    /* Buffer pointers */
+    char *buffer, *linectptr, *lineptr, *toktmp, *token, *cursor, *marker, *limit;
+    /* Line counter */
+    int linect;
+    /* Last token from yylex() */
+    int last_token;
+    /* Force a token upon next call to yylex() */
+    int force_token;
+    /* EOF flag */
+    int eof;
+    union {
+        SyckIoFile *file;
+        SyckIoStr *str;
+    } io;
+    /* Symbol table for anchors */
+    st_table *anchors, *bad_anchors;
+    /* Optional symbol table for SYMIDs */
+    st_table *syms;
+    /* Levels of indentation */
+    SyckLevel *levels;
+    int lvl_idx;
+    int lvl_capa;
+    /* Pointer for extension's use */
+    void *bonus;
+};
+
+/*
+ * Emitter definitions
+ */
+typedef struct _syck_emitter SyckEmitter;
+typedef struct _syck_emitter_node SyckEmitterNode;
+
+typedef void (*SyckOutputHandler)(SyckEmitter *, char *, long); 
+typedef void (*SyckEmitterHandler)(SyckEmitter *, st_data_t); 
+
+enum doc_stage {
+    doc_open,
+    doc_processing
+};
+
+/*
+ * Emitter struct
+ */
+struct _syck_emitter {
+    /* Headerless doc flag */
+    int headless;
+    /* Force header? */
+    int use_header;
+    /* Force version? */
+    int use_version;
+    /* Sort hash keys */
+    int sort_keys;
+    /* Anchor format */
+    char *anchor_format;
+    /* Explicit typing on all collections? */
+    int explicit_typing;
+    /* Best width on folded scalars */
+    int best_width;
+    /* Use literal[1] or folded[2] blocks on all text? */
+    enum scalar_style style;
+    /* Stage of written document */
+    enum doc_stage stage;
+    /* Level counter */
+    int level;
+    /* Default indentation */
+    int indent;
+    /* Object ignore ID */
+    SYMID ignore_id;
+    /* Symbol table for anchors */
+    st_table *markers, *anchors, *anchored;
+    /* Custom buffer size */
+    size_t bufsize;
+    /* Buffer */
+    char *buffer, *marker;
+    /* Absolute position of the buffer */
+    long bufpos;
+    /* Handler for emitter nodes */
+    SyckEmitterHandler emitter_handler;
+    /* Handler for output */
+    SyckOutputHandler output_handler;
+    /* Levels of indentation */
+    SyckLevel *levels;
+    int lvl_idx;
+    int lvl_capa;
+    /* Pointer for extension's use */
+    void *bonus;
+};
+
+/*
+ * Emitter node metadata struct
+ */
+struct _syck_emitter_node {
+    /* Node buffer position */
+    long pos;
+    /* Current indent */
+    long indent;
+    /* Collection? */
+    int is_shortcut;
+};
+
+/*
+ * Handler prototypes
+ */
+SYMID syck_hdlr_add_node( SyckParser *, SyckNode * );
+SyckNode *syck_hdlr_add_anchor( SyckParser *, char *, SyckNode * );
+void syck_hdlr_remove_anchor( SyckParser *, char * );
+SyckNode *syck_hdlr_get_anchor( SyckParser *, char * );
+void syck_add_transfer( char *, SyckNode *, int );
+char *syck_xprivate( char *, int );
+char *syck_taguri( char *, char *, int );
+int syck_tagcmp( char *, char * );
+int syck_add_sym( SyckParser *, char * );
+int syck_lookup_sym( SyckParser *, SYMID, char ** );
+int syck_try_implicit( SyckNode * );
+char *syck_type_id_to_uri( char * );
+void try_tag_implicit( SyckNode *, int );
+char *syck_match_implicit( char *, size_t );
+
+/*
+ * API prototypes
+ */
+char *syck_strndup( char *, long );
+long syck_io_file_read( char *, SyckIoFile *, long, long );
+long syck_io_str_read( char *, SyckIoStr *, long, long );
+char *syck_base64enc( char *, long );
+char *syck_base64dec( char *, long, long * );
+SyckEmitter *syck_new_emitter();
+SYMID syck_emitter_mark_node( SyckEmitter *, st_data_t );
+void syck_emitter_ignore_id( SyckEmitter *, SYMID );
+void syck_output_handler( SyckEmitter *, SyckOutputHandler );
+void syck_emitter_handler( SyckEmitter *, SyckEmitterHandler );
+void syck_free_emitter( SyckEmitter * );
+void syck_emitter_clear( SyckEmitter * );
+void syck_emitter_write( SyckEmitter *, char *, long );
+void syck_emitter_escape( SyckEmitter *, char *, long );
+void syck_emitter_flush( SyckEmitter *, long );
+void syck_emit( SyckEmitter *, st_data_t );
+void syck_emit_scalar( SyckEmitter *, char *, enum scalar_style, int, int, char, char *, long );
+void syck_emit_1quoted( SyckEmitter *, int, char *, long );
+void syck_emit_2quoted( SyckEmitter *, int, char *, long );
+void syck_emit_folded( SyckEmitter *, int, char, char *, long );
+void syck_emit_literal( SyckEmitter *, char, char *, long );
+void syck_emit_seq( SyckEmitter *, char *, enum seq_style );
+void syck_emit_item( SyckEmitter *, st_data_t );
+void syck_emit_map( SyckEmitter *, char *, enum map_style );
+void syck_emit_end( SyckEmitter * );
+void syck_emit_tag( SyckEmitter *, char *, char * );
+void syck_emit_indent( SyckEmitter * );
+SyckLevel *syck_emitter_current_level( SyckEmitter * );
+SyckLevel *syck_emitter_parent_level( SyckEmitter * );
+void syck_emitter_pop_level( SyckEmitter * );
+void syck_emitter_add_level( SyckEmitter *, int, enum syck_level_status );
+void syck_emitter_reset_levels( SyckEmitter * );
+SyckParser *syck_new_parser();
+void syck_free_parser( SyckParser * );
+void syck_parser_set_root_on_error( SyckParser *, SYMID );
+void syck_parser_implicit_typing( SyckParser *, int );
+void syck_parser_taguri_expansion( SyckParser *, int );
+int syck_scan_scalar( int, char *, long );
+void syck_parser_handler( SyckParser *, SyckNodeHandler );
+void syck_parser_error_handler( SyckParser *, SyckErrorHandler );
+void syck_parser_bad_anchor_handler( SyckParser *, SyckBadAnchorHandler );
+void syck_parser_file( SyckParser *, FILE *, SyckIoFileRead );
+void syck_parser_str( SyckParser *, char *, long, SyckIoStrRead );
+void syck_parser_str_auto( SyckParser *, char *, SyckIoStrRead );
+SyckLevel *syck_parser_current_level( SyckParser * );
+void syck_parser_add_level( SyckParser *, int, enum syck_level_status );
+void syck_parser_pop_level( SyckParser * );
+void free_any_io( SyckParser * );
+long syck_parser_read( SyckParser * );
+long syck_parser_readlen( SyckParser *, long );
+SYMID syck_parse( SyckParser * );
+void syck_default_error_handler( SyckParser *, char * );
+SYMID syck_yaml2byte_handler( SyckParser *, SyckNode * );
+char *syck_yaml2byte( char * );
+
+/*
+ * Allocation prototypes
+ */
+SyckNode *syck_alloc_map();
+SyckNode *syck_alloc_seq();
+SyckNode *syck_alloc_str();
+void syck_free_node( SyckNode * );
+void syck_free_members( SyckNode * );
+SyckNode *syck_new_str( char *, enum scalar_style );
+SyckNode *syck_new_str2( char *, long, enum scalar_style );
+void syck_replace_str( SyckNode *, char *, enum scalar_style );
+void syck_replace_str2( SyckNode *, char *, long, enum scalar_style );
+void syck_str_blow_away_commas( SyckNode * );
+char *syck_str_read( SyckNode * );
+SyckNode *syck_new_map( SYMID, SYMID );
+void syck_map_empty( SyckNode * );
+void syck_map_add( SyckNode *, SYMID, SYMID );
+SYMID syck_map_read( SyckNode *, enum map_part, long );
+void syck_map_assign( SyckNode *, enum map_part, long, SYMID );
+long syck_map_count( SyckNode * );
+void syck_map_update( SyckNode *, SyckNode * );
+SyckNode *syck_new_seq( SYMID );
+void syck_seq_empty( SyckNode * );
+void syck_seq_add( SyckNode *, SYMID );
+void syck_seq_assign( SyckNode *, long, SYMID );
+SYMID syck_seq_read( SyckNode *, long );
+long syck_seq_count( SyckNode * );
+
+/*
+ * Lexer prototypes
+ */
+void syckerror( char * );
+int syckparse( void * );
+
+#if defined(__cplusplus)
+}  /* extern "C" { */
+#endif
+
+#endif /* ifndef SYCK_H */
diff --git a/syck/syck_st.h b/syck/syck_st.h
new file mode 100644
--- /dev/null
+++ b/syck/syck_st.h
@@ -0,0 +1,46 @@
+/* This is a public domain general purpose hash table package written by Peter Moore @ UCB. */
+
+/* @(#) st.h 5.1 89/12/14 */
+
+#ifndef ST_INCLUDED
+
+#define ST_INCLUDED
+
+typedef struct st_table st_table;
+
+struct st_hash_type {
+    int (*compare)();
+    int (*hash)();
+};
+
+struct st_table {
+    struct st_hash_type *type;
+    int num_bins;
+    int num_entries;
+    struct st_table_entry **bins;
+};
+
+#define st_is_member(table,key) st_lookup(table,key,(char **)0)
+
+enum st_retval {ST_CONTINUE, ST_STOP, ST_DELETE};
+
+st_table *st_init_table();
+st_table *st_init_table_with_size();
+st_table *st_init_numtable();
+st_table *st_init_numtable_with_size();
+st_table *st_init_strtable();
+st_table *st_init_strtable_with_size();
+int st_delete(), st_delete_safe();
+int st_insert(), st_lookup();
+void st_foreach(), st_add_direct(), st_free_table(), st_cleanup_safe();
+st_table *st_copy();
+
+#define ST_NUMCMP	((int (*)()) 0)
+#define ST_NUMHASH	((int (*)()) -2)
+
+#define st_numcmp	ST_NUMCMP
+#define st_numhash	ST_NUMHASH
+
+int st_strhash();
+
+#endif /* ST_INCLUDED */
diff --git a/syck/yamlbyte.h b/syck/yamlbyte.h
new file mode 100644
--- /dev/null
+++ b/syck/yamlbyte.h
@@ -0,0 +1,170 @@
+/*  yamlbyte.h
+ *
+ *  The YAML bytecode "C" interface header file.   See the YAML bytecode
+ *  reference for bytecode sequence rules and for the meaning of each
+ *  bytecode.
+ */
+
+#ifndef YAMLBYTE_H
+#define YAMLBYTE_H
+#include <stddef.h>
+
+/* define what a character is */
+typedef unsigned char yamlbyte_utf8_t;
+typedef unsigned short yamlbyte_utf16_t;
+#ifdef YAMLBYTE_UTF8
+  #ifdef YAMLBYTE_UTF16
+    #error Must only define YAMLBYTE_UTF8 or YAMLBYTE_UTF16
+  #endif
+  typedef yamlbyte_utf8_t yamlbyte_char_t;
+#else
+  #ifdef YAMLBYTE_UTF16
+    typedef yamlbyte_utf16_t yamlbyte_char_t;
+  #else
+    #error Must define YAMLBYTE_UTF8 or YAMLBYTE_UTF16
+  #endif
+#endif
+
+/* specify list of bytecodes */
+#define YAMLBYTE_FINISH          ((yamlbyte_char_t) 0)
+#define YAMLBYTE_DOCUMENT        ((yamlbyte_char_t)'D')
+#define YAMLBYTE_DIRECTIVE       ((yamlbyte_char_t)'V')
+#define YAMLBYTE_PAUSE           ((yamlbyte_char_t)'P')
+#define YAMLBYTE_MAPPING         ((yamlbyte_char_t)'M')
+#define YAMLBYTE_SEQUENCE        ((yamlbyte_char_t)'Q')
+#define YAMLBYTE_END_BRANCH      ((yamlbyte_char_t)'E')
+#define YAMLBYTE_SCALAR          ((yamlbyte_char_t)'S')
+#define YAMLBYTE_CONTINUE        ((yamlbyte_char_t)'C')
+#define YAMLBYTE_NEWLINE         ((yamlbyte_char_t)'N')
+#define YAMLBYTE_NULLCHAR        ((yamlbyte_char_t)'Z')
+#define YAMLBYTE_ANCHOR          ((yamlbyte_char_t)'A')
+#define YAMLBYTE_ALIAS           ((yamlbyte_char_t)'R')
+#define YAMLBYTE_TRANSFER        ((yamlbyte_char_t)'T')
+/* formatting bytecodes */
+#define YAMLBYTE_COMMENT         ((yamlbyte_char_t)'c')
+#define YAMLBYTE_INDENT          ((yamlbyte_char_t)'i')
+#define YAMLBYTE_STYLE           ((yamlbyte_char_t)'s')
+/* other bytecodes */
+#define YAMLBYTE_LINE_NUMBER     ((yamlbyte_char_t)'#')
+#define YAMLBYTE_WHOLE_SCALAR    ((yamlbyte_char_t)'<')
+#define YAMLBYTE_NOTICE          ((yamlbyte_char_t)'!')
+#define YAMLBYTE_SPAN            ((yamlbyte_char_t)')')
+#define YAMLBYTE_ALLOC           ((yamlbyte_char_t)'@')
+
+/* second level style bytecodes, ie "s>" */
+#define YAMLBYTE_FLOW            ((yamlbyte_char_t)'>')
+#define YAMLBYTE_LITERAL         ((yamlbyte_char_t)'|')
+#define YAMLBYTE_BLOCK           ((yamlbyte_char_t)'b')
+#define YAMLBYTE_PLAIN           ((yamlbyte_char_t)'p')
+#define YAMLBYTE_INLINE_MAPPING  ((yamlbyte_char_t)'{')
+#define YAMLBYTE_INLINE_SEQUENCE ((yamlbyte_char_t)'[')
+#define YAMLBYTE_SINGLE_QUOTED   ((yamlbyte_char_t)39)
+#define YAMLBYTE_DOUBLE_QUOTED   ((yamlbyte_char_t)'"')
+
+/*
+ * The "C" API has two variants, one based on instructions,
+ * with events delivered via pointers; and the other one
+ * is character based where one or more instructions are
+ * serialized into a buffer.
+ *
+ * Note: In the instruction based API, WHOLE_SCALAR does
+ *       not have the '<here' marshalling stuff.
+ */
+
+typedef void * yamlbyte_consumer_t;
+typedef void * yamlbyte_producer_t;
+
+/* push and pull APIs need a way to communicate results */
+typedef enum {
+    YAMLBYTE_OK          = 0,     /* proceed                        */
+    YAMLBYTE_E_MEMORY    = 'M',   /* could not allocate memory      */
+    YAMLBYTE_E_READ      = 'R',   /* input stream read error        */
+    YAMLBYTE_E_WRITE     = 'W',   /* output stream write error      */
+    YAMLBYTE_E_OTHER     = '?',   /* some other error condition     */
+    YAMLBYTE_E_PARSE     = 'P',   /* parse error, check bytecodes   */
+} yamlbyte_result_t;
+ 
+typedef const yamlbyte_char_t *yamlbyte_buff_t; 
+
+/* 
+ *  The "Instruction" API 
+ */
+
+typedef struct yaml_instruction {
+    yamlbyte_char_t bytecode;
+    yamlbyte_buff_t start;
+    yamlbyte_buff_t finish;  /* open range, *finish is _not_ part */
+} *yamlbyte_inst_t;
+
+/* producer pushes the instruction with one bytecode event to the 
+ * consumer; if the consumer's result is not YAMLBYTE_OK, then
+ * the producer should stop */
+typedef
+  yamlbyte_result_t
+   (*yamlbyte_push_t)(
+     yamlbyte_consumer_t self,
+     yamlbyte_inst_t  inst
+   );
+
+/* consumer pulls a bytecode instruction from the producer; in this
+ * case the instruction (and is buffer) are owned by the producer and
+ * will remain valid till the pull function is called once again;
+ * if the instruction is NULL, then there are no more results; and
+ * it is important to call the pull function till it returns NULL so 
+ * that the producer can clean up its memory allocations */
+typedef 
+   yamlbyte_result_t
+    (*yamlbyte_pull_t)(
+      yamlbyte_producer_t self,
+      yamlbyte_inst_t *inst   /* to be filled in by the producer */
+    ); 
+
+/*
+ *  Buffer based API
+ */
+
+/* producer pushes a null terminated buffer filled with one or more
+ * bytecode events to the consumer; if the consumer's result is not
+ * YAMLBYTE_OK, then the producer should stop */
+typedef
+  yamlbyte_result_t
+   (*yamlbyte_pushbuff_t)(
+     yamlbyte_consumer_t self,
+     yamlbyte_buff_t  buff
+   );
+
+/* consumer pulls bytecode events from the producer; in this case
+ * the buffer is owned by the producer, and will remain valid till
+ * the pull function is called once again; if the buffer pointer
+ * is set to NULL, then there are no more results; it is important
+ * to call the pull function till it returns NULL so that the
+ * producer can clean up its memory allocations */
+typedef 
+   yamlbyte_result_t
+    (*yamlbyte_pullbuff_t)(
+      yamlbyte_producer_t self,
+      yamlbyte_buff_t *buff   /* to be filled in by the producer */
+    ); 
+
+/* convert a pull interface to a push interface; the reverse process
+ * requires threads and thus is language dependent */
+#define YAMLBYTE_PULL2PUSH(pull,producer,push,consumer,result)       \
+    do {                                                         \
+        yamlbyte_pullbuff_t _pull = (pull);                              \
+        yamlbyte_pushbuff_t _push = (push);                              \
+        yamlbyte_result_t _result = YAMLBYTE_OK;                         \
+        yamlbyte_producer_t _producer = (producer);                  \
+        yamlbyte_consumer_t _consumer = (consumer);                  \
+        while(1) {                                               \
+            yamlbyte_buff_t buff = NULL;                           \
+            _result = _pull(_producer,&buff);                    \
+            if(YAMLBYTE_OK != result || NULL == buff)                \
+                break;                                           \
+            _result = _push(_consumer,buff);                     \
+            if(YAMLBYTE_OK != result)                                \
+                break;                                           \
+        }                                                        \
+        (result) = _result;                                      \
+    } while(0)
+
+#endif
