Add a skeleton of the emitter.
diff --git a/lib/yaml/__init__.py b/lib/yaml/__init__.py
index 55e3f38..bf07a0e 100644
--- a/lib/yaml/__init__.py
+++ b/lib/yaml/__init__.py
@@ -7,6 +7,8 @@
 from resolver import *
 from constructor import *
 
+from emitter import *
+
 from tokens import *
 from events import *
 from nodes import *
diff --git a/lib/yaml/emitter.py b/lib/yaml/emitter.py
new file mode 100644
index 0000000..4f33cb8
--- /dev/null
+++ b/lib/yaml/emitter.py
@@ -0,0 +1,180 @@
+
+# Events should obey the following grammar:
+# stream ::= STREAM-START document* STREAM-END
+# document ::= DOCUMENT-START node DOCUMENT-END
+# node ::= SCALAR | sequence | mapping
+# sequence ::= SEQUENCE-START node* SEQUENCE-END
+# mapping ::= MAPPING-START (node node)* MAPPING-END
+
+__all__ = ['Emitter', 'EmitterError']
+
+from error import YAMLError
+from events import *
+
+class EmitterError(YAMLError):
+    pass
+
+class Emitter:
+
+    def __init__(self, writer):
+        self.writer = writer
+        self.states = []
+        self.state = self.expect_stream_start
+        self.levels = []
+        self.level = 0
+        self.soft_space = False
+
+    def emit(self, event):
+        self.state(event)
+
+    def expect_stream_start(self, event):
+        if isinstance(event, StreamStartEvent):
+            self.state = self.expect_document_start
+        else:
+            raise EmitterError("expected StreamStartEvent, but got %s" % event.__class__.__name__)
+
+    def expect_document_start(self, event):
+        if isinstance(event, DocumentStartEvent):
+            self.write_document_start()
+            self.states.append(self.expect_document_end)
+            self.state = self.expect_root_node
+        elif isinstance(event, StreamEndEvent):
+            self.writer.flush()
+            self.state = self.expect_nothing
+        else:
+            raise EmitterError("expected DocumentStartEvent, but got %s" % event.__class__.__name__)
+
+    def expect_document_end(self, event):
+        if isinstance(event, DocumentEndEvent):
+            self.write_document_end()
+            self.state = self.expect_document_start
+        else:
+            raiseEmitterError("expected DocumentEndEvent, but got %s" % event.__class__.__name__)
+
+    def expect_root_node(self, event):
+        self.expect_node(event)
+
+    def expect_node(self, event):
+        if isinstance(event, AliasEvent):
+            self.write_anchor("*", event.anchor)
+            self.state = self.states.pop()
+        elif isinstance(event, NodeEvent):
+            if event.anchor:
+                self.write_anchor("&", event.anchor)
+            if event.tag:
+                self.write_tag(event.tag)
+            if isinstance(event, ScalarEvent):
+                self.write_scalar(event.value)
+                self.state = self.states.pop()
+            elif isinstance(event, SequenceEvent):
+                self.write_collection_start("[")
+                self.level += 1
+                self.state = self.expect_first_sequence_item
+            elif isinstance(event, MappingEvent):
+                self.write_collection_start("{")
+                self.level += 1
+                self.state = self.expect_first_mapping_key
+        else:
+            raise EmitterError("Expected NodeEvent, but got %s" % event.__class__.__name__)
+
+    def expect_first_sequence_item(self, event):
+        if isinstance(event, CollectionEndEvent):
+            self.write_collection_end("]")
+            self.state = self.states.pop()
+        else:
+            self.write_indent()
+            self.states.append(self.expect_sequence_item)
+            self.expect_node(event)
+
+    def expect_sequence_item(self, event):
+        if isinstance(event, CollectionEndEvent):
+            self.level -= 1
+            self.write_indent()
+            self.write_collection_end("]")
+            self.state = self.states.pop()
+        else:
+            self.write_indicator(",")
+            self.write_indent()
+            self.states.append(self.expect_sequence_item)
+            self.expect_node(event)
+        
+    def expect_first_mapping_key(self, event):
+        if isinstance(event, CollectionEndEvent):
+            self.write_collection_end("}")
+            self.state = self.states.pop()
+        else:
+            self.write_indent()
+            self.write_indicator("?")
+            self.states.append(self.expect_mapping_value)
+            self.expect_node(event)
+
+    def expect_mapping_key(self, event):
+        if isinstance(event, CollectionEndEvent):
+            self.level -= 1
+            self.write_indent()
+            self.write_collection_end("}")
+            self.state = self.states.pop()
+        else:
+            self.write_indicator(",")
+            self.write_indent()
+            self.write_indicator("?")
+            self.states.append(self.expect_mapping_value)
+            self.expect_node(event)
+
+    def expect_mapping_value(self, event):
+        self.write_indent()
+        self.write_indicator(":")
+        self.states.append(self.expect_mapping_key)
+        self.expect_node(event)
+
+    def expect_nothing(self, event):
+        raise EmitterError("expected nothing, but got %s" % event.__class__.__name__)
+
+    def write_document_start(self):
+        self.writer.write("%YAML 1.1\n")
+        self.writer.write("---")
+        self.soft_space = True
+
+    def write_document_end(self):
+        self.writer.write("\n...\n")
+        self.soft_space = False
+
+    def write_collection_start(self, indicator):
+        if self.soft_space:
+            self.writer.write(" ")
+        self.writer.write(indicator)
+        self.soft_space = False
+
+    def write_collection_end(self, indicator):
+        self.writer.write(indicator)
+        self.soft_space = True
+
+    def write_anchor(self, indicator, name):
+        if self.soft_space:
+            self.writer.write(" ")
+        self.writer.write("%s%s" % (indicator, name))
+        self.soft_space = True
+
+    def write_tag(self, tag):
+        if self.soft_space:
+            self.writer.write(" ")
+        if tag.startswith("tag:yaml.org,2002:"):
+            self.writer.write("!!%s" % tag[len("tag.yaml.org,2002:"):])
+        else:
+            self.writer.write("!<%s>" % tag)
+        self.soft_space = True
+
+    def write_scalar(self, value):
+        if self.soft_space:
+            self.writer.write(" ")
+        self.writer.write("\"%s\"" % value.encode('utf-8'))
+        self.soft_space = True
+
+    def write_indicator(self, indicator):
+        self.writer.write(indicator)
+        self.soft_space = True
+
+    def write_indent(self):
+        self.writer.write("\n"+" "*(self.level*4))
+        self.soft_space = False
+
diff --git a/lib/yaml/events.py b/lib/yaml/events.py
index 8837633..97bccb3 100644
--- a/lib/yaml/events.py
+++ b/lib/yaml/events.py
@@ -1,18 +1,17 @@
 
 class Event:
-    def __init__(self, start_mark, end_mark):
+    def __init__(self, start_mark=None, end_mark=None):
         self.start_mark = start_mark
         self.end_mark = end_mark
     def __repr__(self):
-        attributes = [key for key in self.__dict__
-                if not key.endswith('_mark')]
-        attributes.sort()
+        attributes = [key for key in ['anchor', 'tag', 'value']
+                if hasattr(self, key)]
         arguments = ', '.join(['%s=%r' % (key, getattr(self, key))
                 for key in attributes])
         return '%s(%s)' % (self.__class__.__name__, arguments)
 
 class NodeEvent(Event):
-    def __init__(self, anchor, start_mark, end_mark):
+    def __init__(self, anchor, start_mark=None, end_mark=None):
         self.anchor = anchor
         self.start_mark = start_mark
         self.end_mark = end_mark
@@ -21,7 +20,7 @@
     pass
 
 class ScalarEvent(NodeEvent):
-    def __init__(self, anchor, tag, value, start_mark, end_mark):
+    def __init__(self, anchor, tag, value, start_mark=None, end_mark=None):
         self.anchor = anchor
         self.tag = tag
         self.value = value
@@ -29,7 +28,7 @@
         self.end_mark = end_mark
 
 class CollectionEvent(NodeEvent):
-    def __init__(self, anchor, tag, start_mark, end_mark):
+    def __init__(self, anchor, tag, start_mark=None, end_mark=None):
         self.anchor = anchor
         self.tag = tag
         self.start_mark = start_mark
diff --git a/lib/yaml/tokens.py b/lib/yaml/tokens.py
index 59b36af..93c3005 100644
--- a/lib/yaml/tokens.py
+++ b/lib/yaml/tokens.py
@@ -1,6 +1,6 @@
 
 class Token:
-    def __init__(self, start_mark, end_mark):
+    def __init__(self, start_mark=None, end_mark=None):
         self.start_mark = start_mark
         self.end_mark = end_mark
     def __repr__(self):
@@ -16,7 +16,7 @@
 
 class DirectiveToken(Token):
     id = '<directive>'
-    def __init__(self, name, value, start_mark, end_mark):
+    def __init__(self, name, value, start_mark=None, end_mark=None):
         self.name = name
         self.value = value
         self.start_mark = start_mark
@@ -69,28 +69,28 @@
 
 class AliasToken(Token):
     id = '<alias>'
-    def __init__(self, value, start_mark, end_mark):
+    def __init__(self, value, start_mark=None, end_mark=None):
         self.value = value
         self.start_mark = start_mark
         self.end_mark = end_mark
 
 class AnchorToken(Token):
     id = '<anchor>'
-    def __init__(self, value, start_mark, end_mark):
+    def __init__(self, value, start_mark=None, end_mark=None):
         self.value = value
         self.start_mark = start_mark
         self.end_mark = end_mark
 
 class TagToken(Token):
     id = '<tag>'
-    def __init__(self, value, start_mark, end_mark):
+    def __init__(self, value, start_mark=None, end_mark=None):
         self.value = value
         self.start_mark = start_mark
         self.end_mark = end_mark
 
 class ScalarToken(Token):
     id = '<scalar>'
-    def __init__(self, value, plain, start_mark, end_mark):
+    def __init__(self, value, plain, start_mark=None, end_mark=None):
         self.value = value
         self.plain = plain
         self.start_mark = start_mark
diff --git a/tests/test_emitter.py b/tests/test_emitter.py
new file mode 100644
index 0000000..1ff0ecc
--- /dev/null
+++ b/tests/test_emitter.py
@@ -0,0 +1,19 @@
+
+import test_appliance, sys
+
+from yaml import *
+
+class TestEmitterOnCanonical(test_appliance.TestAppliance):
+
+    def _testEmitterOnCanonical(self, test_name, canonical_filename):
+        events = list(iter(Parser(Scanner(Reader(file(canonical_filename, 'rb'))))))
+        writer = sys.stdout
+        emitter = Emitter(writer)
+        print "-"*30
+        print "ORIGINAL DATA:"
+        print file(canonical_filename, 'rb').read()
+        for event in events:
+            emitter.emit(event)
+
+TestEmitterOnCanonical.add_tests('testEmitterOnCanonical', '.canonical')
+
diff --git a/tests/test_yaml.py b/tests/test_yaml.py
index bb5a9f1..99e8b72 100644
--- a/tests/test_yaml.py
+++ b/tests/test_yaml.py
@@ -9,6 +9,7 @@
 from test_errors import *
 from test_detector import *
 from test_constructor import *
+from test_emitter import *
 from test_syck import *
 
 def main(module='__main__'):