Index: /pyyaml/trunk/tests/test_structure.py
===================================================================
--- /pyyaml/trunk/tests/test_structure.py	(revision 146)
+++ /pyyaml/trunk/tests/test_structure.py	(revision 222)
@@ -154,4 +154,5 @@
         return self.construct_scalar(node)
 
+MyLoader.add_constructor(u'tag:yaml.org,2002:map', MyLoader.construct_mapping)
 MyLoader.add_constructor(None, MyLoader.construct_undefined)
 
@@ -169,4 +170,5 @@
         return self.construct_scalar(node)
 
+MyCanonicalLoader.add_constructor(u'tag:yaml.org,2002:map', MyCanonicalLoader.construct_mapping)
 MyCanonicalLoader.add_constructor(None, MyCanonicalLoader.construct_undefined)
 
Index: /pyyaml/trunk/tests/test_resolver.py
===================================================================
--- /pyyaml/trunk/tests/test_resolver.py	(revision 166)
+++ /pyyaml/trunk/tests/test_resolver.py	(revision 222)
@@ -73,6 +73,5 @@
         elif isinstance(node, MappingNode):
             value = []
-            for key in node.value:
-                item = node.value[key]
+            for key, item in node.value:
                 value.append((self._convert(key), self._convert(item)))
             value.sort()
Index: /pyyaml/trunk/tests/test_recursive.py
===================================================================
--- /pyyaml/trunk/tests/test_recursive.py	(revision 142)
+++ /pyyaml/trunk/tests/test_recursive.py	(revision 222)
@@ -1,22 +1,52 @@
 
-import unittest
+import test_appliance
+
 from yaml import *
 
-RECURSIVE = """
---- &A
-- *A: *A
-"""
+class AnInstance:
 
-class TestRecursive(unittest.TestCase):
+    def __init__(self, foo, bar):
+        self.foo = foo
+        self.bar = bar
 
-    def testRecursive(self):
-        node = compose(RECURSIVE)
-        self._check(node)
-        document = serialize(node)
-        node = compose(document)
-        self._check(node)
+    def __repr__(self):
+        try:
+            return "%s(foo=%r, bar=%r)" % (self.__class__.__name__,
+                    self.foo, self.bar)
+        except RuntimeError:
+            return "%s(foo=..., bar=...)" % self.__class__.__name__
 
-    def _check(self, node):
-        self.failUnless(node in node.value[0].value)
-        self.failUnless(node.value[0].value[node] is node)
+class AnInstanceWithState(AnInstance):
 
+    def __getstate__(self):
+        return {'attributes': [self.foo, self.bar]}
+
+    def __setstate__(self, state):
+        self.foo, self.bar = state['attributes']
+
+class TestRecursive(test_appliance.TestAppliance):
+
+    def _testRecursive(self, test_name, recursive_filename):
+        exec file(recursive_filename, 'r').read()
+        value1 = value
+        output1 = None
+        value2 = None
+        output2 = None
+        try:
+            output1 = dump(value1)
+            #print "OUTPUT %s:" % test_name
+            #print output1
+            value2 = load(output1)
+            output2 = dump(value2)
+            self.failUnlessEqual(output1, output2)
+        except:
+            print "VALUE1:", value1
+            print "VALUE2:", value2
+            print "OUTPUT1:"
+            print output1
+            print "OUTPUT2:"
+            print output2
+            raise
+
+TestRecursive.add_tests('testRecursive', '.recursive')
+
Index: /pyyaml/trunk/tests/data/duplicate-mapping-key.former-loader-error.code
===================================================================
--- /pyyaml/trunk/tests/data/duplicate-mapping-key.former-loader-error.code	(revision 222)
+++ /pyyaml/trunk/tests/data/duplicate-mapping-key.former-loader-error.code	(revision 222)
@@ -0,0 +1,1 @@
+{ 'foo': { 'baz': 'bat', 'foo': 'duplicate key' } }
Index: /pyyaml/trunk/tests/data/duplicate-key.former-loader-error.code
===================================================================
--- /pyyaml/trunk/tests/data/duplicate-key.former-loader-error.code	(revision 222)
+++ /pyyaml/trunk/tests/data/duplicate-key.former-loader-error.code	(revision 222)
@@ -0,0 +1,1 @@
+{ 'foo': 'baz' }
Index: /pyyaml/trunk/tests/data/duplicate-value-key.former-loader-error.code
===================================================================
--- /pyyaml/trunk/tests/data/duplicate-value-key.former-loader-error.code	(revision 222)
+++ /pyyaml/trunk/tests/data/duplicate-value-key.former-loader-error.code	(revision 222)
@@ -0,0 +1,1 @@
+{ 'foo': 'bar', '=': 2 }
Index: /pyyaml/trunk/tests/data/recursive-set.recursive
===================================================================
--- /pyyaml/trunk/tests/data/recursive-set.recursive	(revision 222)
+++ /pyyaml/trunk/tests/data/recursive-set.recursive	(revision 222)
@@ -0,0 +1,3 @@
+value = set()
+value.add(AnInstance(foo=value, bar=value))
+value.add(AnInstance(foo=value, bar=value))
Index: /pyyaml/trunk/tests/data/duplicate-merge-key.former-loader-error.data
===================================================================
--- /pyyaml/trunk/tests/data/duplicate-merge-key.former-loader-error.data	(revision 222)
+++ /pyyaml/trunk/tests/data/duplicate-merge-key.former-loader-error.data	(revision 222)
@@ -0,0 +1,4 @@
+---
+<<: {x: 1, y: 2}
+foo: bar
+<<: {z: 3, t: 4}
Index: /pyyaml/trunk/tests/data/recursive-tuple.recursive
===================================================================
--- /pyyaml/trunk/tests/data/recursive-tuple.recursive	(revision 222)
+++ /pyyaml/trunk/tests/data/recursive-tuple.recursive	(revision 222)
@@ -0,0 +1,3 @@
+value = ([], [])
+value[0].append(value)
+value[1].append(value[0])
Index: /pyyaml/trunk/tests/data/recursive-anchor.former-loader-error
===================================================================
--- /pyyaml/trunk/tests/data/recursive-anchor.former-loader-error	(revision 222)
+++ /pyyaml/trunk/tests/data/recursive-anchor.former-loader-error	(revision 222)
@@ -0,0 +1,4 @@
+- &foo [1
+    2,
+    3,
+    *foo]
Index: /pyyaml/trunk/tests/data/recursive.former-dumper-error
===================================================================
--- /pyyaml/trunk/tests/data/recursive.former-dumper-error	(revision 222)
+++ /pyyaml/trunk/tests/data/recursive.former-dumper-error	(revision 222)
@@ -0,0 +1,3 @@
+data = []
+data.append(data)
+dump(data)
Index: /pyyaml/trunk/tests/data/recursive-dict.recursive
===================================================================
--- /pyyaml/trunk/tests/data/recursive-dict.recursive	(revision 222)
+++ /pyyaml/trunk/tests/data/recursive-dict.recursive	(revision 222)
@@ -0,0 +1,3 @@
+value = {}
+instance = AnInstance(value, value)
+value[instance] = instance
Index: /pyyaml/trunk/tests/data/duplicate-merge-key.former-loader-error.code
===================================================================
--- /pyyaml/trunk/tests/data/duplicate-merge-key.former-loader-error.code	(revision 222)
+++ /pyyaml/trunk/tests/data/duplicate-merge-key.former-loader-error.code	(revision 222)
@@ -0,0 +1,1 @@
+{ 'x': 1, 'y': 2, 'foo': 'bar', 'z': 3, 't': 4 }
Index: /pyyaml/trunk/tests/data/recursive-state.recursive
===================================================================
--- /pyyaml/trunk/tests/data/recursive-state.recursive	(revision 222)
+++ /pyyaml/trunk/tests/data/recursive-state.recursive	(revision 222)
@@ -0,0 +1,2 @@
+value = []
+value.append(AnInstanceWithState(value, value))
Index: /pyyaml/trunk/tests/data/recurive-list.recursive
===================================================================
--- /pyyaml/trunk/tests/data/recurive-list.recursive	(revision 222)
+++ /pyyaml/trunk/tests/data/recurive-list.recursive	(revision 222)
@@ -0,0 +1,2 @@
+value = []
+value.append(value)
Index: /pyyaml/trunk/tests/data/duplicate-mapping-key.former-loader-error.data
===================================================================
--- /pyyaml/trunk/tests/data/duplicate-mapping-key.former-loader-error.data	(revision 222)
+++ /pyyaml/trunk/tests/data/duplicate-mapping-key.former-loader-error.data	(revision 222)
@@ -0,0 +1,6 @@
+---
+&anchor foo:
+    foo: bar
+    *anchor: duplicate key
+    baz: bat
+    *anchor: duplicate key
Index: /pyyaml/trunk/tests/data/duplicate-key.former-loader-error.data
===================================================================
--- /pyyaml/trunk/tests/data/duplicate-key.former-loader-error.data	(revision 222)
+++ /pyyaml/trunk/tests/data/duplicate-key.former-loader-error.data	(revision 222)
@@ -0,0 +1,3 @@
+---
+foo: bar
+foo: baz
Index: /pyyaml/trunk/tests/data/duplicate-value-key.former-loader-error.data
===================================================================
--- /pyyaml/trunk/tests/data/duplicate-value-key.former-loader-error.data	(revision 222)
+++ /pyyaml/trunk/tests/data/duplicate-value-key.former-loader-error.data	(revision 222)
@@ -0,0 +1,4 @@
+---
+=: 1
+foo: bar
+=: 2
Index: yaml/trunk/tests/data/duplicate-value-key.loader-error
===================================================================
--- /pyyaml/trunk/tests/data/duplicate-value-key.loader-error	(revision 140)
+++ 	(revision )
@@ -1,4 +1,0 @@
----
-=: 1
-foo: bar
-=: 2
Index: yaml/trunk/tests/data/recursive-anchor.loader-error
===================================================================
--- /pyyaml/trunk/tests/data/recursive-anchor.loader-error	(revision 140)
+++ 	(revision )
@@ -1,4 +1,0 @@
-- &foo [1
-    2,
-    3,
-    *foo]
Index: yaml/trunk/tests/data/duplicate-mapping-key.loader-error
===================================================================
--- /pyyaml/trunk/tests/data/duplicate-mapping-key.loader-error	(revision 140)
+++ 	(revision )
@@ -1,6 +1,0 @@
----
-&anchor foo:
-    foo: bar
-    *anchor: duplicate key
-    baz: bat
-    *anchor: duplicate key
Index: yaml/trunk/tests/data/recursive.dumper-error
===================================================================
--- /pyyaml/trunk/tests/data/recursive.dumper-error	(revision 141)
+++ 	(revision )
@@ -1,3 +1,0 @@
-data = []
-data.append(data)
-dump(data)
Index: yaml/trunk/tests/data/duplicate-merge-key.loader-error
===================================================================
--- /pyyaml/trunk/tests/data/duplicate-merge-key.loader-error	(revision 140)
+++ 	(revision )
@@ -1,4 +1,0 @@
----
-<<: {x: 1, y: 2}
-foo: bar
-<<: {z: 3, t: 4}
Index: yaml/trunk/tests/data/duplicate-key.loader-error
===================================================================
--- /pyyaml/trunk/tests/data/duplicate-key.loader-error	(revision 140)
+++ 	(revision )
@@ -1,3 +1,0 @@
----
-foo: bar
-foo: baz
Index: /pyyaml/trunk/tests/test_constructor.py
===================================================================
--- /pyyaml/trunk/tests/test_constructor.py	(revision 173)
+++ /pyyaml/trunk/tests/test_constructor.py	(revision 222)
@@ -240,4 +240,8 @@
     def __eq__(self, other):
         return type(self) is type(other) and dict(self) == dict(other)
+
+def execute(code):
+    exec code
+    return value
 
 class TestConstructorTypes(test_appliance.TestAppliance):
Index: /pyyaml/trunk/lib/yaml/parser.py
===================================================================
--- /pyyaml/trunk/lib/yaml/parser.py	(revision 204)
+++ /pyyaml/trunk/lib/yaml/parser.py	(revision 222)
@@ -70,5 +70,5 @@
     pass
 
-class Parser:
+class Parser(object):
     # Since writing a recursive-descendant parser is a straightforward task, we
     # do not give many comments here.
Index: /pyyaml/trunk/lib/yaml/representer.py
===================================================================
--- /pyyaml/trunk/lib/yaml/representer.py	(revision 206)
+++ /pyyaml/trunk/lib/yaml/representer.py	(revision 222)
@@ -22,5 +22,5 @@
     pass
 
-class BaseRepresenter:
+class BaseRepresenter(object):
 
     yaml_representers = {}
@@ -31,4 +31,6 @@
         self.default_flow_style = default_flow_style
         self.represented_objects = {}
+        self.object_keeper = []
+        self.alias_key = None
 
     def represent(self, data):
@@ -36,14 +38,18 @@
         self.serialize(node)
         self.represented_objects = {}
+        self.object_keeper = []
+        self.alias_key = None
 
     class C: pass
     c = C()
     def f(): pass
+    def g(): yield None
     classobj_type = type(C)
     instance_type = type(c)
     function_type = type(f)
+    generator_type = type(g())
     builtin_function_type = type(abs)
     module_type = type(sys)
-    del C, c, f
+    del C, c, f, g
 
     def get_classobj_bases(self, cls):
@@ -55,14 +61,15 @@
     def represent_data(self, data):
         if self.ignore_aliases(data):
-            alias_key = None
-        else:
-            alias_key = id(data)
-        if alias_key is not None:
-            if alias_key in self.represented_objects:
-                node = self.represented_objects[alias_key]
-                if node is None:
-                    raise RepresenterError("recursive objects are not allowed: %r" % data)
+            self.alias_key = None
+        else:
+            self.alias_key = id(data)
+        if self.alias_key is not None:
+            if self.alias_key in self.represented_objects:
+                node = self.represented_objects[self.alias_key]
+                #if node is None:
+                #    raise RepresenterError("recursive objects are not allowed: %r" % data)
                 return node
-            self.represented_objects[alias_key] = None
+            #self.represented_objects[alias_key] = None
+            self.object_keeper.append(data)
         data_types = type(data).__mro__
         if type(data) is self.instance_type:
@@ -82,6 +89,6 @@
                 else:
                     node = ScalarNode(None, unicode(data))
-        if alias_key is not None:
-            self.represented_objects[alias_key] = node
+        #if alias_key is not None:
+        #    self.represented_objects[alias_key] = node
         return node
 
@@ -101,48 +108,50 @@
         if style is None:
             style = self.default_style
-        return ScalarNode(tag, value, style=style)
+        node = ScalarNode(tag, value, style=style)
+        if self.alias_key is not None:
+            self.represented_objects[self.alias_key] = node
+        return node
 
     def represent_sequence(self, tag, sequence, flow_style=None):
+        value = []
+        node = SequenceNode(tag, value, flow_style=flow_style)
+        if self.alias_key is not None:
+            self.represented_objects[self.alias_key] = node
         best_style = True
-        value = []
         for item in sequence:
             node_item = self.represent_data(item)
             if not (isinstance(node_item, ScalarNode) and not node_item.style):
                 best_style = False
-            value.append(self.represent_data(item))
+            value.append(node_item)
         if flow_style is None:
-            flow_style = self.default_flow_style
+            if self.default_flow_style is not None:
+                node.flow_style = self.default_flow_style
+            else:
+                node.flow_style = best_style
+        return node
+
+    def represent_mapping(self, tag, mapping, flow_style=None):
+        value = []
+        node = MappingNode(tag, value, flow_style=flow_style)
+        if self.alias_key is not None:
+            self.represented_objects[self.alias_key] = node
+        best_style = True
+        if hasattr(mapping, 'items'):
+            mapping = mapping.items()
+            mapping.sort()
+        for item_key, item_value in mapping:
+            node_key = self.represent_data(item_key)
+            node_value = self.represent_data(item_value)
+            if not (isinstance(node_key, ScalarNode) and not node_key.style):
+                best_style = False
+            if not (isinstance(node_value, ScalarNode) and not node_value.style):
+                best_style = False
+            value.append((node_key, node_value))
         if flow_style is None:
-            flow_style = best_style
-        return SequenceNode(tag, value, flow_style=flow_style)
-
-    def represent_mapping(self, tag, mapping, flow_style=None):
-        best_style = True
-        if hasattr(mapping, 'keys'):
-            value = {}
-            for item_key in mapping.keys():
-                item_value = mapping[item_key]
-                node_key = self.represent_data(item_key)
-                node_value = self.represent_data(item_value)
-                if not (isinstance(node_key, ScalarNode) and not node_key.style):
-                    best_style = False
-                if not (isinstance(node_value, ScalarNode) and not node_value.style):
-                    best_style = False
-                value[node_key] = node_value
-        else:
-            value = []
-            for item_key, item_value in mapping:
-                node_key = self.represent_data(item_key)
-                node_value = self.represent_data(item_value)
-                if not (isinstance(node_key, ScalarNode) and not node_key.style):
-                    best_style = False
-                if not (isinstance(node_value, ScalarNode) and not node_value.style):
-                    best_style = False
-                value.append((node_key, node_value))
-        if flow_style is None:
-            flow_style = self.default_flow_style
-        if flow_style is None:
-            flow_style = best_style
-        return MappingNode(tag, value, flow_style=flow_style)
+            if self.default_flow_style is not None:
+                node.flow_style = self.default_flow_style
+            else:
+                node.flow_style = best_style
+        return node
 
     def ignore_aliases(self, data):
@@ -209,17 +218,17 @@
 
     def represent_list(self, data):
-        pairs = (len(data) > 0 and isinstance(data, list))
-        if pairs:
-            for item in data:
-                if not isinstance(item, tuple) or len(item) != 2:
-                    pairs = False
-                    break
-        if not pairs:
+        #pairs = (len(data) > 0 and isinstance(data, list))
+        #if pairs:
+        #    for item in data:
+        #        if not isinstance(item, tuple) or len(item) != 2:
+        #            pairs = False
+        #            break
+        #if not pairs:
             return self.represent_sequence(u'tag:yaml.org,2002:seq', data)
-        value = []
-        for item_key, item_value in data:
-            value.append(self.represent_mapping(u'tag:yaml.org,2002:map',
-                [(item_key, item_value)]))
-        return SequenceNode(u'tag:yaml.org,2002:pairs', value)
+        #value = []
+        #for item_key, item_value in data:
+        #    value.append(self.represent_mapping(u'tag:yaml.org,2002:map',
+        #        [(item_key, item_value)]))
+        #return SequenceNode(u'tag:yaml.org,2002:pairs', value)
 
     def represent_dict(self, data):
@@ -251,7 +260,4 @@
         else:
             state = data.__dict__.copy()
-        if isinstance(state, dict):
-            state = state.items()
-            state.sort()
         return self.represent_mapping(tag, state, flow_style=flow_style)
 
@@ -385,6 +391,4 @@
             state = data.__dict__
         if args is None and isinstance(state, dict):
-            state = state.items()
-            state.sort()
             return self.represent_mapping(
                     u'tag:yaml.org,2002:python/object:'+class_name, state)
@@ -445,6 +449,4 @@
         if not args and not listitems and not dictitems \
                 and isinstance(state, dict) and newobj:
-            state = state.items()
-            state.sort()
             return self.represent_mapping(
                     u'tag:yaml.org,2002:python/object:'+function_name, state)
Index: /pyyaml/trunk/lib/yaml/resolver.py
===================================================================
--- /pyyaml/trunk/lib/yaml/resolver.py	(revision 158)
+++ /pyyaml/trunk/lib/yaml/resolver.py	(revision 222)
@@ -10,5 +10,5 @@
     pass
 
-class BaseResolver:
+class BaseResolver(object):
 
     DEFAULT_SCALAR_TAG = u'tag:yaml.org,2002:str'
Index: /pyyaml/trunk/lib/yaml/reader.py
===================================================================
--- /pyyaml/trunk/lib/yaml/reader.py	(revision 188)
+++ /pyyaml/trunk/lib/yaml/reader.py	(revision 222)
@@ -78,5 +78,5 @@
                             self.name, self.position)
 
-class Reader:
+class Reader(object):
     # Reader:
     # - determines the data encoding and converts it to unicode,
Index: /pyyaml/trunk/lib/yaml/tokens.py
===================================================================
--- /pyyaml/trunk/lib/yaml/tokens.py	(revision 137)
+++ /pyyaml/trunk/lib/yaml/tokens.py	(revision 222)
@@ -1,4 +1,4 @@
 
-class Token:
+class Token(object):
     def __init__(self, start_mark, end_mark):
         self.start_mark = start_mark
Index: /pyyaml/trunk/lib/yaml/events.py
===================================================================
--- /pyyaml/trunk/lib/yaml/events.py	(revision 137)
+++ /pyyaml/trunk/lib/yaml/events.py	(revision 222)
@@ -2,5 +2,5 @@
 # Abstract classes.
 
-class Event:
+class Event(object):
     def __init__(self, start_mark=None, end_mark=None):
         self.start_mark = start_mark
Index: /pyyaml/trunk/lib/yaml/nodes.py
===================================================================
--- /pyyaml/trunk/lib/yaml/nodes.py	(revision 153)
+++ /pyyaml/trunk/lib/yaml/nodes.py	(revision 222)
@@ -1,4 +1,4 @@
 
-class Node:
+class Node(object):
     def __init__(self, tag, value, start_mark, end_mark):
         self.tag = tag
Index: /pyyaml/trunk/lib/yaml/emitter.py
===================================================================
--- /pyyaml/trunk/lib/yaml/emitter.py	(revision 218)
+++ /pyyaml/trunk/lib/yaml/emitter.py	(revision 222)
@@ -17,5 +17,5 @@
     pass
 
-class ScalarAnalysis:
+class ScalarAnalysis(object):
     def __init__(self, scalar, empty, multiline,
             allow_flow_plain, allow_block_plain,
@@ -31,5 +31,5 @@
         self.allow_block = allow_block
 
-class Emitter:
+class Emitter(object):
 
     DEFAULT_TAG_PREFIXES = {
Index: /pyyaml/trunk/lib/yaml/serializer.py
===================================================================
--- /pyyaml/trunk/lib/yaml/serializer.py	(revision 139)
+++ /pyyaml/trunk/lib/yaml/serializer.py	(revision 222)
@@ -9,5 +9,5 @@
     pass
 
-class Serializer:
+class Serializer(object):
 
     ANCHOR_TEMPLATE = u'id%03d'
@@ -68,12 +68,7 @@
                     self.anchor_node(item)
             elif isinstance(node, MappingNode):
-                if hasattr(node.value, 'keys'):
-                    for key in node.value.keys():
-                        self.anchor_node(key)
-                        self.anchor_node(node.value[key])
-                else:
-                    for key, value in node.value:
-                        self.anchor_node(key)
-                        self.anchor_node(value)
+                for key, value in node.value:
+                    self.anchor_node(key)
+                    self.anchor_node(value)
 
     def generate_anchor(self, node):
@@ -109,12 +104,7 @@
                 self.emit(MappingStartEvent(alias, node.tag, implicit,
                     flow_style=node.flow_style))
-                if hasattr(node.value, 'keys'):
-                    for key in node.value.keys():
-                        self.serialize_node(key, node, None)
-                        self.serialize_node(node.value[key], node, key)
-                else:
-                    for key, value in node.value:
-                        self.serialize_node(key, node, None)
-                        self.serialize_node(value, node, key)
+                for key, value in node.value:
+                    self.serialize_node(key, node, None)
+                    self.serialize_node(value, node, key)
                 self.emit(MappingEndEvent())
             self.ascend_resolver()
Index: /pyyaml/trunk/lib/yaml/constructor.py
===================================================================
--- /pyyaml/trunk/lib/yaml/constructor.py	(revision 198)
+++ /pyyaml/trunk/lib/yaml/constructor.py	(revision 222)
@@ -22,5 +22,5 @@
     pass
 
-class BaseConstructor:
+class BaseConstructor(object):
 
     yaml_constructors = {}
@@ -30,4 +30,6 @@
         self.constructed_objects = {}
         self.recursive_objects = {}
+        self.state_generators = []
+        self.deep_construct = False
 
     def check_data(self):
@@ -40,53 +42,74 @@
             return self.construct_document(self.get_node())
 
+    def g(): yield None
+    generator_type = type(g())
+    del g
+
     def construct_document(self, node):
         data = self.construct_object(node)
+        while self.state_generators:
+            state_generators = self.state_generators
+            self.state_generators = []
+            for generator in state_generators:
+                for dummy in generator:
+                    pass
         self.constructed_objects = {}
         self.recursive_objects = {}
+        self.deep_construct = False
         return data
 
-    def construct_object(self, node):
+    def construct_object(self, node, deep=False):
+        if deep:
+            old_deep = self.deep_construct
+            self.deep_construct = True
         if node in self.constructed_objects:
             return self.constructed_objects[node]
         if node in self.recursive_objects:
             raise ConstructorError(None, None,
-                    "found recursive node", node.start_mark)
+                    "found unconstructable recursive node", node.start_mark)
         self.recursive_objects[node] = None
         constructor = None
+        state_constructor = None
+        tag_suffix = None
         if node.tag in self.yaml_constructors:
-            constructor = lambda node: self.yaml_constructors[node.tag](self, node)
+            constructor = self.yaml_constructors[node.tag]
         else:
             for tag_prefix in self.yaml_multi_constructors:
                 if node.tag.startswith(tag_prefix):
                     tag_suffix = node.tag[len(tag_prefix):]
-                    constructor = lambda node:  \
-                            self.yaml_multi_constructors[tag_prefix](self, tag_suffix, node)
+                    constructor = self.yaml_multi_constructors[tag_prefix]
                     break
             else:
                 if None in self.yaml_multi_constructors:
-                    constructor = lambda node:  \
-                            self.yaml_multi_constructors[None](self, node.tag, node)
+                    tag_suffix = node.tag
+                    constructor = self.yaml_multi_constructors[None]
                 elif None in self.yaml_constructors:
-                    constructor = lambda node:  \
-                            self.yaml_constructors[None](self, node)
+                    constructor = self.yaml_constructors[None]
                 elif isinstance(node, ScalarNode):
-                    constructor = self.construct_scalar
+                    constructor = self.__class__.construct_scalar
                 elif isinstance(node, SequenceNode):
-                    constructor = self.construct_sequence
+                    constructor = self.__class__.construct_sequence
                 elif isinstance(node, MappingNode):
-                    constructor = self.construct_mapping
-                else:
-                    print node.tag
-        data = constructor(node)
+                    constructor = self.__class__.construct_mapping
+        if tag_suffix is None:
+            data = constructor(self, node)
+        else:
+            data = constructor(self, tag_suffix, node)
+        if isinstance(data, self.generator_type):
+            generator = data
+            data = generator.next()
+            if self.deep_construct:
+                for dummy in generator:
+                    pass
+            else:
+                self.state_generators.append(generator)
         self.constructed_objects[node] = data
         del self.recursive_objects[node]
+        if deep:
+            self.deep_construct = old_deep
         return data
 
     def construct_scalar(self, node):
         if not isinstance(node, ScalarNode):
-            if isinstance(node, MappingNode):
-                for key_node in node.value:
-                    if key_node.tag == u'tag:yaml.org,2002:value':
-                        return self.construct_scalar(node.value[key_node])
             raise ConstructorError(None, None,
                     "expected a scalar node, but found %s" % node.id,
@@ -94,12 +117,13 @@
         return node.value
 
-    def construct_sequence(self, node):
+    def construct_sequence(self, node, deep=False):
         if not isinstance(node, SequenceNode):
             raise ConstructorError(None, None,
                     "expected a sequence node, but found %s" % node.id,
                     node.start_mark)
-        return [self.construct_object(child) for child in node.value]
-
-    def construct_mapping(self, node):
+        return [self.construct_object(child, deep=deep)
+                for child in node.value]
+
+    def construct_mapping(self, node, deep=False):
         if not isinstance(node, MappingNode):
             raise ConstructorError(None, None,
@@ -107,15 +131,60 @@
                     node.start_mark)
         mapping = {}
-        merge = None
-        for key_node in node.value:
+        for key_node, value_node in node.value:
+            key = self.construct_object(key_node, deep=deep)
+            try:
+                hash(key)
+            except TypeError, exc:
+                raise ConstructorError("while constructing a mapping", node.start_mark,
+                        "found unacceptable key (%s)" % exc, key_node.start_mark)
+            value = self.construct_object(value_node, deep=deep)
+            mapping[key] = value
+        return mapping
+
+    def construct_pairs(self, node, deep=False):
+        if not isinstance(node, MappingNode):
+            raise ConstructorError(None, None,
+                    "expected a mapping node, but found %s" % node.id,
+                    node.start_mark)
+        pairs = []
+        for key_node, value_node in node.value:
+            key = self.construct_object(key_node, deep=deep)
+            value = self.construct_object(value_node, deep=deep)
+            pairs.append((key, value))
+        return pairs
+
+    def add_constructor(cls, tag, constructor):
+        if not 'yaml_constructors' in cls.__dict__:
+            cls.yaml_constructors = cls.yaml_constructors.copy()
+        cls.yaml_constructors[tag] = constructor
+    add_constructor = classmethod(add_constructor)
+
+    def add_multi_constructor(cls, tag_prefix, multi_constructor):
+        if not 'yaml_multi_constructors' in cls.__dict__:
+            cls.yaml_multi_constructors = cls.yaml_multi_constructors.copy()
+        cls.yaml_multi_constructors[tag_prefix] = multi_constructor
+    add_multi_constructor = classmethod(add_multi_constructor)
+
+class SafeConstructor(BaseConstructor):
+
+    def construct_scalar(self, node):
+        if isinstance(node, MappingNode):
+            for key_node, value_node in node.value:
+                if key_node.tag == u'tag:yaml.org,2002:value':
+                    return self.construct_scalar(value_node)
+        return BaseConstructor.construct_scalar(self, node)
+
+    def flatten_mapping(self, node):
+        merge = []
+        index = 0
+        while index < len(node.value):
+            key_node, value_node = node.value[index]
             if key_node.tag == u'tag:yaml.org,2002:merge':
-                if merge is not None:
-                    raise ConstructorError("while constructing a mapping", node.start_mark,
-                            "found duplicate merge key", key_node.start_mark)
-                value_node = node.value[key_node]
+                del node.value[index]
                 if isinstance(value_node, MappingNode):
-                    merge = [self.construct_mapping(value_node)]
+                    self.flatten_mapping(value_node)
+                    merge.extend(value_node.value)
                 elif isinstance(value_node, SequenceNode):
-                    merge = []
+                    submerge = []
                     for subnode in value_node.value:
                         if not isinstance(subnode, MappingNode):
@@ -124,6 +193,9 @@
                                     "expected a mapping for merging, but found %s"
                                     % subnode.id, subnode.start_mark)
-                        merge.append(self.construct_mapping(subnode))
-                    merge.reverse()
+                        self.flatten_mapping(subnode)
+                        submerge.append(subnode.value)
+                    submerge.reverse()
+                    for value in submerge:
+                        merge.extend(value)
                 else:
                     raise ConstructorError("while constructing a mapping", node.start_mark,
@@ -131,53 +203,15 @@
                             % value_node.id, value_node.start_mark)
             elif key_node.tag == u'tag:yaml.org,2002:value':
-                if '=' in mapping:
-                    raise ConstructorError("while construction a mapping", node.start_mark,
-                            "found duplicate value key", key_node.start_mark)
-                value = self.construct_object(node.value[key_node])
-                mapping['='] = value
+                key_node.tag = u'tag:yaml.org,2002:str'
+                index += 1
             else:
-                key = self.construct_object(key_node)
-                try:
-                    duplicate_key = key in mapping
-                except TypeError, exc:
-                    raise ConstructorError("while constructing a mapping", node.start_mark,
-                            "found unacceptable key (%s)" % exc, key_node.start_mark)
-                if duplicate_key:
-                    raise ConstructorError("while constructing a mapping", node.start_mark,
-                            "found duplicate key", key_node.start_mark)
-                value = self.construct_object(node.value[key_node])
-                mapping[key] = value
-        if merge is not None:
-            merge.append(mapping)
-            mapping = {}
-            for submapping in merge:
-                mapping.update(submapping)
-        return mapping
-
-    def construct_pairs(self, node):
-        if not isinstance(node, MappingNode):
-            raise ConstructorError(None, None,
-                    "expected a mapping node, but found %s" % node.id,
-                    node.start_mark)
-        pairs = []
-        for key_node in node.value:
-            key = self.construct_object(key_node)
-            value = self.construct_object(node.value[key_node])
-            pairs.append((key, value))
-        return pairs
-
-    def add_constructor(cls, tag, constructor):
-        if not 'yaml_constructors' in cls.__dict__:
-            cls.yaml_constructors = cls.yaml_constructors.copy()
-        cls.yaml_constructors[tag] = constructor
-    add_constructor = classmethod(add_constructor)
-
-    def add_multi_constructor(cls, tag_prefix, multi_constructor):
-        if not 'yaml_multi_constructors' in cls.__dict__:
-            cls.yaml_multi_constructors = cls.yaml_multi_constructors.copy()
-        cls.yaml_multi_constructors[tag_prefix] = multi_constructor
-    add_multi_constructor = classmethod(add_multi_constructor)
-
-class SafeConstructor(BaseConstructor):
+                index += 1
+        if merge:
+            node.value = merge + node.value
+
+    def construct_mapping(self, node, deep=False):
+        if isinstance(node, MappingNode):
+            self.flatten_mapping(node)
+        return BaseConstructor.construct_mapping(self, node, deep=deep)
 
     def construct_yaml_null(self, node):
@@ -297,8 +331,9 @@
         # Note: we do not check for duplicate keys, because it's too
         # CPU-expensive.
+        omap = []
+        yield omap
         if not isinstance(node, SequenceNode):
             raise ConstructorError("while constructing an ordered map", node.start_mark,
                     "expected a sequence, but found %s" % node.id, node.start_mark)
-        omap = []
         for subnode in node.value:
             if not isinstance(subnode, MappingNode):
@@ -310,16 +345,16 @@
                         "expected a single mapping item, but found %d items" % len(subnode.value),
                         subnode.start_mark)
-            key_node = subnode.value.keys()[0]
+            key_node, value_node = subnode.value[0]
             key = self.construct_object(key_node)
-            value = self.construct_object(subnode.value[key_node])
+            value = self.construct_object(value_node)
             omap.append((key, value))
-        return omap
 
     def construct_yaml_pairs(self, node):
         # Note: the same code as `construct_yaml_omap`.
+        pairs = []
+        yield pairs
         if not isinstance(node, SequenceNode):
             raise ConstructorError("while constructing pairs", node.start_mark,
                     "expected a sequence, but found %s" % node.id, node.start_mark)
-        pairs = []
         for subnode in node.value:
             if not isinstance(subnode, MappingNode):
@@ -331,13 +366,14 @@
                         "expected a single mapping item, but found %d items" % len(subnode.value),
                         subnode.start_mark)
-            key_node = subnode.value.keys()[0]
+            key_node, value_node = subnode.value[0]
             key = self.construct_object(key_node)
-            value = self.construct_object(subnode.value[key_node])
+            value = self.construct_object(value_node)
             pairs.append((key, value))
-        return pairs
 
     def construct_yaml_set(self, node):
+        data = set()
+        yield data
         value = self.construct_mapping(node)
-        return set(value)
+        data.update(value)
 
     def construct_yaml_str(self, node):
@@ -349,17 +385,23 @@
 
     def construct_yaml_seq(self, node):
-        return self.construct_sequence(node)
+        data = []
+        yield data
+        data.extend(self.construct_sequence(node))
 
     def construct_yaml_map(self, node):
-        return self.construct_mapping(node)
+        data = {}
+        yield data
+        value = self.construct_mapping(node)
+        data.update(value)
 
     def construct_yaml_object(self, node, cls):
-        state = self.construct_mapping(node)
         data = cls.__new__(cls)
+        yield data
         if hasattr(data, '__setstate__'):
+            state = self.construct_mapping(node, deep=True)
             data.__setstate__(state)
         else:
+            state = self.construct_mapping(node)
             data.__dict__.update(state)
-        return data
 
     def construct_undefined(self, node):
@@ -435,5 +477,5 @@
 
     def construct_python_tuple(self, node):
-        return tuple(self.construct_yaml_seq(node))
+        return tuple(self.construct_sequence(node))
 
     def find_python_module(self, name, mark):
@@ -526,7 +568,8 @@
         #   !!python/object:module.name { ... state ... }
         instance = self.make_python_instance(suffix, node, newobj=True)
-        state = self.construct_mapping(node)
+        yield instance
+        deep = hasattr(instance, '__setstate__')
+        state = self.construct_mapping(node, deep=deep)
         self.set_python_instance_state(instance, state)
-        return instance
 
     def construct_python_object_apply(self, suffix, node, newobj=False):
@@ -543,5 +586,5 @@
         # is how an object is created, check make_python_instance for details.
         if isinstance(node, SequenceNode):
-            args = self.construct_sequence(node)
+            args = self.construct_sequence(node, deep=True)
             kwds = {}
             state = {}
@@ -549,5 +592,5 @@
             dictitems = {}
         else:
-            value = self.construct_mapping(node)
+            value = self.construct_mapping(node, deep=True)
             args = value.get('args', [])
             kwds = value.get('kwds', {})
@@ -568,5 +611,4 @@
         return self.construct_python_object_apply(suffix, node, newobj=True)
 
-
 Constructor.add_constructor(
     u'tag:yaml.org,2002:python/none',
Index: /pyyaml/trunk/lib/yaml/composer.py
===================================================================
--- /pyyaml/trunk/lib/yaml/composer.py	(revision 198)
+++ /pyyaml/trunk/lib/yaml/composer.py	(revision 222)
@@ -9,5 +9,5 @@
     pass
 
-class Composer:
+class Composer(object):
 
     def __init__(self):
@@ -100,5 +100,5 @@
         if tag is None or tag == u'!':
             tag = self.resolve(MappingNode, None, start_event.implicit)
-        node = MappingNode(tag, {},
+        node = MappingNode(tag, [],
                 start_event.start_mark, None,
                 flow_style=start_event.flow_style)
@@ -106,11 +106,12 @@
             self.anchors[anchor] = node
         while not self.check_event(MappingEndEvent):
-            key_event = self.peek_event()
+            #key_event = self.peek_event()
             item_key = self.compose_node(node, None)
-            if item_key in node.value:
-                raise ComposerError("while composing a mapping", start_event.start_mark,
-                        "found duplicate key", key_event.start_mark)
+            #if item_key in node.value:
+            #    raise ComposerError("while composing a mapping", start_event.start_mark,
+            #            "found duplicate key", key_event.start_mark)
             item_value = self.compose_node(node, item_key)
-            node.value[item_key] = item_value
+            #node.value[item_key] = item_value
+            node.value.append((item_key, item_value))
         end_event = self.get_event()
         node.end_mark = end_event.end_mark
Index: /pyyaml/trunk/lib/yaml/error.py
===================================================================
--- /pyyaml/trunk/lib/yaml/error.py	(revision 136)
+++ /pyyaml/trunk/lib/yaml/error.py	(revision 222)
@@ -2,5 +2,5 @@
 __all__ = ['Mark', 'YAMLError', 'MarkedYAMLError']
 
-class Mark:
+class Mark(object):
 
     def __init__(self, name, index, line, column, buffer, pointer):
Index: /pyyaml/trunk/lib/yaml/scanner.py
===================================================================
--- /pyyaml/trunk/lib/yaml/scanner.py	(revision 198)
+++ /pyyaml/trunk/lib/yaml/scanner.py	(revision 222)
@@ -20,5 +20,5 @@
 # ANCHOR(value)
 # TAG(value)
-# SCALAR(value, plain)
+# SCALAR(value, plain, style)
 #
 # Read comments in the Scanner code for more details.
@@ -33,5 +33,5 @@
     pass
 
-class SimpleKey:
+class SimpleKey(object):
     # See below simple keys treatment.
 
@@ -44,5 +44,5 @@
         self.mark = mark
 
-class Scanner:
+class Scanner(object):
 
     def __init__(self):
