diff --git a/README.md b/README.md
index 1c7e049f56f12167f83f1d9e160f1b28cc7fcc2e..ec4bf1b7ce1c4ed040c826bb93a244c3b90638e7 100644
--- a/README.md
+++ b/README.md
@@ -8,31 +8,13 @@ CoolAMQP
 [![PyPI](https://img.shields.io/pypi/pyversions/CoolAMQP.svg)]()
 [![PyPI](https://img.shields.io/pypi/implementation/CoolAMQP.svg)]()
 
-When you're tired of fucking with AMQP reconnects.
+A **magical** AMQP client, that uses **heavy sorcery** to achieve speeds that other AMQP clients cannot even hope to match.
 
-When a connection made by CoolAMQP to your broker fails, it will pick another
-node, redeclare exchanges, queues, consumers, QoS and all the other shit, and tell
-your application that a disconnect happened.
+tl;dr - [this](coolamqp/framing/definitions.py) is **machine-generated** compile-time.
+[this](coolamqp/framing/compilation/content_property.py) **generates classes run-time**.
 
-You only need to remember that:
-
-1. Reconnects and redefinitions take a while. Things will happen during that time. It is your responsibility to ensure that your distributed system is built to handle this
-2. CoolAMQP will tell you when it senses losing broker connection. It will also tell you when it regains the connection (that means that everything is redefined and ready to go)
-3. Delivering messages multiple times may happen. Ensure you know when it happens. Keywords: message acknowledgement, amqp specification
-4. CoolAMQP won't touch your messages. You send bags of bytes and properties, you get bags of bytes and their properties. This is by design - the postman shouldn't mess with your mail.
 
 The project is actively maintained and used in a commercial project. Tests can run
 either on Vagrant (Vagrantfile attached) or Travis CI, and run against RabbitMQ.
 
 Enjoy!
-
-# Changelog
-## v0.12
-* ACCESS_REFUSED/RESOURCE_LOCKED on reconnect is properly handled
-* reason for consumer cancel is provided
-* can read error code and reply text from failed orders
-* test suite refactored and improved
-## v0.11
-* added *no_ack* to *consume*
-* can pass other non-text types to Message
-* can set global bit in *qos*
diff --git a/coolamqp/framing/base.py b/coolamqp/framing/base.py
index 6ddeddf3e8f5d79a3079492ed240351d0b42ff37..f9c33bb697e90b38cbd80b075314e853d1e90607 100644
--- a/coolamqp/framing/base.py
+++ b/coolamqp/framing/base.py
@@ -86,6 +86,43 @@ class AMQPContentPropertyList(object):
     """
     PROPERTIES = []
 
+    @staticmethod
+    def zero_property_flags(property_flags):
+        """
+        Given a binary property_flags, set all bit properties to 0.
+
+        This leaves us with a canonical representation, that can be used
+        in obtaining a particular property list
+        :param property_flags: binary
+        :return: binary
+        """
+        # this is a default implementation.
+        # compiler should emit it's own when the content property list has a
+        # possible bit field
+        return property_flags
+
+    def write_to(self, buf):
+        """Serialize itself (flags + values) to a buffer"""
+        raise NotImplementedError
+
+    @staticmethod
+    def from_buffer(self, buf, start_offset):
+        """
+        Return an instance of self, loaded from a buffer.
+
+        This does not have to return length, because it is always passed exactly enough of a buffer.
+
+        Buffer HAS TO start at property_flags
+        """
+        raise NotImplementedError
+
+    def get_size(self):
+        """
+        How long is property_flags + property_values
+        :return: int
+        """
+        raise NotImplementedError
+
 
 class AMQPMethodPayload(AMQPPayload):
     RESPONSE_TO = None
diff --git a/coolamqp/framing/compilation/compile_definitions.py b/coolamqp/framing/compilation/compile_definitions.py
index 1d2f91ee5aa7b39fd95a0ce3ef6a69716070b335..3ded538b3b618d8d2ed2bb0e4e4689f5c4c5239f 100644
--- a/coolamqp/framing/compilation/compile_definitions.py
+++ b/coolamqp/framing/compilation/compile_definitions.py
@@ -42,13 +42,15 @@ AMQP is copyright (c) 2016 OASIS
 CoolAMQP is copyright (c) 2016 DMS Serwis s.c.
 """
 
-import struct
-import collections
+import struct, collections, warnings, logging, six
 
-from coolamqp.framing.base_definitions import AMQPClass, AMQPMethodPayload, AMQPContentPropertyList
+from coolamqp.framing.base import AMQPClass, AMQPMethodPayload, AMQPContentPropertyList
 from coolamqp.framing.field_table import enframe_table, deframe_table, frame_table_size
+from coolamqp.framing.compilation.content_property import compile_particular_content_property_list_class
+
+logger = logging.getLogger(__name__)
 
-Field = collections.namedtuple('Field', ('name', 'type', 'reserved'))
+Field = collections.namedtuple('Field', ('name', 'type', 'basic_type', 'reserved'))
 
 ''')
 
@@ -91,6 +93,10 @@ Field = collections.namedtuple('Field', ('name', 'type', 'reserved'))
 
     class_id_to_contentpropertylist = {}
 
+    # below are stored as strings!
+    methods_that_are_reply_reasons_for = {}   # eg. ConnectionOpenOk: ConnectionOk
+    methods_that_are_replies_for = {}    # eg. ConnectionOk: [ConnectionOpenOk]
+
     # Output classes
     for cls in get_classes(xml):
 
@@ -121,13 +127,100 @@ Field = collections.namedtuple('Field', ('name', 'type', 'reserved'))
             is_static = all(property.basic_type not in ('table', 'longstr', 'shortstr') for property in cls.properties)
 
             for property in cls.properties:
-                line('        Field(%s, %s, %s),\n', frepr(property.name), frepr(property.basic_type), repr(property.reserved))
-            line('    ]\n\n')
-
-
-
+                if property.basic_type == 'bit':
+                    raise ValueError('bit properties are not supported!'
+                                     )
+                line('        Field(%s, %s, %s, %s),\n', frepr(property.name), frepr(property.type), frepr(property.basic_type), repr(property.reserved))
+            line('''    ]
+    # A dictionary from a zero property list to a class typized with
+    # some fields
+    PARTICULAR_CLASSES = {}
+\n''',
+                 name_class(cls.name))
+
+            if any(prop.basic_type == 'bit' for prop in cls.properties):
+                raise NotImplementedError('I should emit a custom zero_property_list staticmethod :(')
+            line(u'''    def __new__(self, **kwargs):
+        """
+        Return a property list.
+''')
+            property_strs = []
 
+            my_props = [prop for prop in cls.properties if (not prop.reserved)]
+            for property in my_props:
+                line('        :param %s: %s\n', format_field_name(property.name), property.label)
+                line('        :type %s: %s (AMQP as %s)\n', format_field_name(property.name), TYPE_TRANSLATOR[property.basic_type], property.basic_type)
+            line('        """\n')
+            zpf_len = int(math.ceil(len(cls.properties) // 15))
+
+            first_byte = True   # in 2-byte group
+            piece_index = 7 # from 7 downto 0
+            fields_remaining = len(cls.properties)
+
+            byte_chunk = []
+            line(u'        zpf = bytearray([\n')
+
+            for field in cls.properties:
+                # a bit
+                if piece_index > 0:
+                    if field.reserved or field.basic_type == 'bit':
+                        byte_chunk.append(u"kwargs['%s']" % (2**piece_index, ))
+                    else:
+                        byte_chunk.append(u"(('%s' in kwargs) << %s)" % (format_field_name(field.name), piece_index))
+                    piece_index -= 1
+                else:
+                    if first_byte:
+                        if field.reserved or field.basic_type == 'bit':
+                            byte_chunk.append(u'0')
+                        else:
+                            byte_chunk.append(u"int('%s' in kwargs)" % (format_field_name(field.name),))
+                    else:
+                       # this is the "do we need moar flags" section
+                        byte_chunk.append(u"kwargs['%s']" % (
+                            int(fields_remaining > 1)
+                        ))
+
+                    # Emit the byte
+                    line(u'            %s,\n', u' | '.join(byte_chunk))
+                    byte_chunk = []
+                    first_byte = not first_byte
+                    piece_index = 7
+                fields_remaining -= 1
+
+            if len(byte_chunk) > 0:
+                line(u'            %s\n', u' | '.join(byte_chunk))    # We did not finish
+
+            line(u'        ])\n        zpf = six.binary_type(zpf)\n')
+            line(u'''
+        if zpf in %s.PARTICULAR_CLASSES:
+            warnings.warn(u"""You could go faster.
+
+        If you know in advance what properties you will be using, use typized constructors like
+
+            # runs once
+            my_type = BasicContentPropertyList.typize('content_type', 'content_encoding')
+            # runs many times
+            props = my_type('text/plain', 'utf8')
+
+        instead of
+
+            # runs many times
+            props = BasicContentPropertyList(content_type='text/plain', content_encoding='utf8')
+
+        This way you will be faster.
+
+        If you do not know in advance what properties you will be using, it is correct to use
+        this constructor.
+        """)
+
+            return %s.PARTICULAR_CLASSES[zpf](**kwargs)
+        else:
+            logger.debug('Property field (%s:%d) not seen yet, compiling', repr(zpf))
+            c = compile_particular_content_property_list_class(zpf, %s.FIELDS)
+            %s.PARTICULAR_CLASSES[zpf] = c
+            return c(**kwargs)
 
+'''.replace('%s', name_class(cls.name) + 'ContentPropertyList').replace('%d', '%s'))
 
 
         # ============================================ Do methods for this class
@@ -153,7 +246,6 @@ Field = collections.namedtuple('Field', ('name', 'type', 'reserved'))
     BINARY_HEADER = %s      # CLASS ID + METHOD ID
 
     SENT_BY_CLIENT, SENT_BY_SERVER = %s, %s
-    REPLY_WITH = [%s]       # methods you can reply with to this one
 
     IS_SIZE_STATIC = %s     # this means that argument part has always the same length
     IS_CONTENT_STATIC = %s  # this means that argument part has always the same content
@@ -165,11 +257,16 @@ Field = collections.namedtuple('Field', ('name', 'type', 'reserved'))
                  to_code_binary(chr(cls.index)+chr(method.index)),
                  repr(method.sent_by_client),
                  repr(method.sent_by_server),
-                 u', '.join([name_class(cls.name) + format_method_class_name(kidname) for kidname in method.response]),
                  repr(is_static),
                  repr(is_content_static)
                  )
 
+            _namify = lambda x: name_class(cls.name) + format_method_class_name(x)
+
+            methods_that_are_replies_for[full_class_name] = []
+            for response in method.response:
+                methods_that_are_reply_reasons_for[_namify(response)] = full_class_name
+                methods_that_are_replies_for[full_class_name].append(_namify(response))
 
             if is_content_static:
 
@@ -179,20 +276,13 @@ Field = collections.namedtuple('Field', ('name', 'type', 'reserved'))
                                     method.get_static_body() + \
                                     struct.pack('!B', FRAME_END)))
 
-            # Am I a response somewhere?
-            for paren in cls.methods:
-                if method.name in paren.response:
-                    line('    RESPONSE_TO = %s%s # this is sent in response to %s\n', name_class(cls.name), format_method_class_name(paren.name),
-                         cls.name +'.' + paren.name
-                         )
-
             # fields
             if len(method.fields) > 0:
                 line('\n    # See constructor pydoc for details\n')
                 line('    FIELDS = [ \n')
 
                 for field in method.fields:
-                    line('        Field(%s, %s, reserved=%s),\n', frepr(field.name), frepr(field.basic_type), repr(field.reserved))
+                    line('        Field(%s, %s, %s, reserved=%s),\n', frepr(field.name), frepr(field.type), frepr(field.basic_type), repr(field.reserved))
 
                 line('    ]\n')
 
@@ -209,6 +299,7 @@ Field = collections.namedtuple('Field', ('name', 'type', 'reserved'))
 
             if len(non_reserved_fields) > 0:
                 line('\n')
+
             for field in non_reserved_fields:
                 if (field.label is not None) or (field.docs is not None):
                     line('        :param %s: %s\n', format_field_name(field.name),
@@ -268,6 +359,23 @@ Field = collections.namedtuple('Field', ('name', 'type', 'reserved'))
         line('    %s: %s,\n', k, v)
     line('}\n\n')
 
+    line(u'''# Methods that are sent as replies to other methods, ie. ConnectionOpenOk: ConnectionOpen
+# if a method is NOT a reply, it will not be in this dict
+# a method may be a reply for AT MOST one method
+REPLY_REASONS_FOR = {\n''')
+    for k,v in methods_that_are_reply_reasons_for.items():
+        line(u'    %s: %s,\n' % (k, v))
+
+    line(u'''}
+
+# Methods that are replies for other, ie. ConnectionOpenOk: ConnectionOpen
+# a method may be a reply for ONE or NONE other methods
+# if a method has no replies, it will have an empty list as value here
+REPLIES_FOR= {\n''')
+
+    for k,v in methods_that_are_replies_for.items():
+        line(u'    %s: [%s],\n' % (k, u', '.join(map(str, v))))
+    line(u'}\n')
 
     out.close()
 
diff --git a/coolamqp/framing/compilation/content_property.py b/coolamqp/framing/compilation/content_property.py
index ab85174b937600be8bb6fe49926fe0f996e898c6..4bd50c0d2572c65d35d32543bc3f6dbb363cbd7e 100644
--- a/coolamqp/framing/compilation/content_property.py
+++ b/coolamqp/framing/compilation/content_property.py
@@ -1,27 +1,106 @@
 # coding=UTF-8
 from __future__ import absolute_import, division, print_function
-"""
-Generate serializers/unserializers/length getters for given property_flags
-"""
+"""Generate serializers/unserializers/length getters for given property_flags"""
+import six
+import struct
+import logging
+from coolamqp.framing.compilation.textcode_fields import get_counter, get_from_buffer, get_serializer
+from coolamqp.framing.base import AMQPContentPropertyList
+from coolamqp.framing.field_table import enframe_table, deframe_table, frame_table_size
+
 
-class ContentPropertyListCompiler(object):
+logger = logging.getLogger(__name__)
+
+
+def _compile_particular_content_property_list_class(zpf, fields):
     """
-    This produces serializers, unserializers and size getters for any property_flags combinations.
+    Compile a particular content property list.
 
-    Sure you could do that by hand, but how much faster is it to have most common messages precompiled?
+    Particularity stems from
+    :param zpf: zero property list, as bytearray
+    :param fields: list of all possible fields in this content property
     """
+    from coolamqp.framing.compilation.utilities import format_field_name
 
-    MAX_COMPILERS_TO_KEEP = 8
+    if any(field.basic_type == 'bit' for field in fields):
+        return u"raise NotImplementedError('I don't support bits in properties yet')"
 
-    def __init__(self, content_property_list_class):
+    # Convert ZPF to a list of [if_exists::bool]
+    even = True
+    zpf_bits = []
+    for q in bytearray(zpf):
+        p = bin(q)[2:]
+        p = (u'0' * (8 - len(p))) + p
 
+        if not even:
+            p = p[:7]
 
-def compile_for(fields):
-    """Compile a serializer, unserializer and length calculator for a list of fields"""
+        zpf_bits.extend(map(lambda x: bool(int(x)), p))
+
+    zpf_length = len(zpf)
+
+    # 1 here does not mean that field is present. All bit fields are present, but 0 in a ZPF. Fix this.
+    zpf_bits = [zpf_bit or field.type == 'bit' for zpf_bit, field in zip(zpf_bits, fields)]
+
+    mod = [u'''class ParticularContentTypeList(AMQPContentPropertyList):
+    """
+    For fields:
+''']
+
+    for field in fields:
+        mod.append(u'    * %s::%s' % (format_field_name(field.name), field.type))
+        if field.reserved:
+            mod.append(u' (reserved)')
+        mod.append(u'\n')
+
+    x = repr(six.binary_type(zpf))
+    if not x.startswith('b'):
+        x = 'b'+x
+
+    present_fields = [field for field, present in zip(fields, zpf_bits) if present]
+
+    mod.append(u'''
+    """
+    # A value for property flags that is used, assuming all bit fields are FALSE (0)
+    ZERO_PROPERTY_FLAGS = %s
+
+    def __init__(self, %s):
+''' % (x, u', '.join(format_field_name(field.name) for field in present_fields)))
+
+    for field in present_fields:
+        mod.append(u'        self.%s = %s\n'.replace(u'%s', format_field_name(field.name)))
+
+    # Let's do write_to
+    mod.append(u'\n    def write_to(self, buf):\n')
+    mod.append(u'        buf.write(')
+    repred_zpf = repr(zpf)
+    if not zpf.startswith('b'):
+        repred_zpf = 'b' + repred_zpf
+    mod.append(repred_zpf)
+    mod.append(u')\n')
+
+    mod.append(get_serializer(present_fields, prefix='self.', indent_level=2))
+
+    # from_buffer
+    # note that non-bit values
+    mod.append(u'    def from_buffer(self, buf, start_offset):\n        offset = start_offset + %s\n' % (zpf_length, ))
+    mod.append(get_from_buffer(
+        present_fields
+        , prefix='', indent_level=2))
+    mod.append(u'        return ParticularContentTypeList(%s)\n' %
+               u', '.join(format_field_name(field.name) for field in present_fields))
+
+
+    # get_size
+    mod.append(u'\n    def get_size(self):\n')
+    mod.append(get_counter(present_fields, prefix='self.', indent_level=2)[:-1])    # skip eol
+    mod.append(u' + %s\n' % (zpf_length, ))   # account for pf length
+
+    return u''.join(mod)
 
-    mod = u'''# coding=UTF-8
-import struct
-from coolamqp.framing.field_table import enframe_table, deframe_table, frame_table_size
 
-def write_to(
-'''
\ No newline at end of file
+def compile_particular_content_property_list_class(zpf, fields):
+    q = _compile_particular_content_property_list_class(zpf, fields)
+    logger.debug('Compiling\n%s', q)
+    exec(q)
+    return ParticularContentTypeList
diff --git a/coolamqp/framing/compilation/utilities.py b/coolamqp/framing/compilation/utilities.py
index f847007c2a2ccdf9f53b4be492210815fb6fda99..550f6605a2aa15804d799e57880084161a049db6 100644
--- a/coolamqp/framing/compilation/utilities.py
+++ b/coolamqp/framing/compilation/utilities.py
@@ -160,7 +160,6 @@ def format_method_class_name(methodname):
 
 @as_unicode
 def format_field_name(field):
-    print(repr(field))
     if field in (u'global', u'type'):
         field = field + '_'
     return field.replace('-', '_')
diff --git a/coolamqp/framing/definitions.py b/coolamqp/framing/definitions.py
index c7a5d57839c0a89f24b81bc132d7952263ccac11..895b13396b77a0dfef6142f921a16f0697cc0827 100644
--- a/coolamqp/framing/definitions.py
+++ b/coolamqp/framing/definitions.py
@@ -10,13 +10,15 @@ AMQP is copyright (c) 2016 OASIS
 CoolAMQP is copyright (c) 2016 DMS Serwis s.c.
 """
 
-import struct
-import collections
+import struct, collections, warnings, logging, six
 
-from coolamqp.framing.base_definitions import AMQPClass, AMQPMethodPayload, AMQPContentPropertyList
+from coolamqp.framing.base import AMQPClass, AMQPMethodPayload, AMQPContentPropertyList
 from coolamqp.framing.field_table import enframe_table, deframe_table, frame_table_size
+from coolamqp.framing.compilation.content_property import compile_particular_content_property_list_class
 
-Field = collections.namedtuple('Field', ('name', 'type', 'reserved'))
+logger = logging.getLogger(__name__)
+
+Field = collections.namedtuple('Field', ('name', 'type', 'basic_type', 'reserved'))
 
 # Core constants
 FRAME_METHOD = 1
@@ -122,17 +124,16 @@ class ConnectionClose(AMQPMethodPayload):
     BINARY_HEADER = b'\x0A\x32'      # CLASS ID + METHOD ID
 
     SENT_BY_CLIENT, SENT_BY_SERVER = True, True
-    REPLY_WITH = [ConnectionCloseOk]       # methods you can reply with to this one
 
     IS_SIZE_STATIC = False     # this means that argument part has always the same length
     IS_CONTENT_STATIC = False  # this means that argument part has always the same content
 
     # See constructor pydoc for details
     FIELDS = [ 
-        Field(u'reply-code', u'short', reserved=False),
-        Field(u'reply-text', u'shortstr', reserved=False),
-        Field(u'class-id', u'short', reserved=False),
-        Field(u'method-id', u'short', reserved=False),
+        Field(u'reply-code', u'reply-code', u'short', reserved=False),
+        Field(u'reply-text', u'reply-text', u'shortstr', reserved=False),
+        Field(u'class-id', u'class-id', u'short', reserved=False),
+        Field(u'method-id', u'method-id', u'short', reserved=False),
     ]
 
     def __init__(self, reply_code, reply_text, class_id, method_id):
@@ -187,12 +188,10 @@ class ConnectionCloseOk(AMQPMethodPayload):
     BINARY_HEADER = b'\x0A\x33'      # CLASS ID + METHOD ID
 
     SENT_BY_CLIENT, SENT_BY_SERVER = True, True
-    REPLY_WITH = []       # methods you can reply with to this one
 
     IS_SIZE_STATIC = True     # this means that argument part has always the same length
     IS_CONTENT_STATIC = True  # this means that argument part has always the same content
     STATIC_CONTENT = b'\x00\x00\x00\x04\x0A\x33\xCE'  # spans LENGTH, CLASS ID, METHOD ID, ....., FRAME_END
-    RESPONSE_TO = ConnectionClose # this is sent in response to connection.close
 
     def __init__(self):
         """
@@ -221,16 +220,15 @@ class ConnectionOpen(AMQPMethodPayload):
     BINARY_HEADER = b'\x0A\x28'      # CLASS ID + METHOD ID
 
     SENT_BY_CLIENT, SENT_BY_SERVER = True, False
-    REPLY_WITH = [ConnectionOpenOk]       # methods you can reply with to this one
 
     IS_SIZE_STATIC = False     # this means that argument part has always the same length
     IS_CONTENT_STATIC = False  # this means that argument part has always the same content
 
     # See constructor pydoc for details
     FIELDS = [ 
-        Field(u'virtual-host', u'shortstr', reserved=False),
-        Field(u'reserved-1', u'shortstr', reserved=True),
-        Field(u'reserved-2', u'bit', reserved=True),
+        Field(u'virtual-host', u'path', u'shortstr', reserved=False),
+        Field(u'reserved-1', u'shortstr', u'shortstr', reserved=True),
+        Field(u'reserved-2', u'bit', u'bit', reserved=True),
     ]
 
     def __init__(self, virtual_host):
@@ -279,16 +277,14 @@ class ConnectionOpenOk(AMQPMethodPayload):
     BINARY_HEADER = b'\x0A\x29'      # CLASS ID + METHOD ID
 
     SENT_BY_CLIENT, SENT_BY_SERVER = False, True
-    REPLY_WITH = []       # methods you can reply with to this one
 
     IS_SIZE_STATIC = False     # this means that argument part has always the same length
     IS_CONTENT_STATIC = True  # this means that argument part has always the same content
     STATIC_CONTENT = b'\x00\x00\x00\x04\x0A\x29\x00\xCE'  # spans LENGTH, CLASS ID, METHOD ID, ....., FRAME_END
-    RESPONSE_TO = ConnectionOpen # this is sent in response to connection.open
 
     # See constructor pydoc for details
     FIELDS = [ 
-        Field(u'reserved-1', u'shortstr', reserved=True),
+        Field(u'reserved-1', u'shortstr', u'shortstr', reserved=True),
     ]
 
     def __init__(self):
@@ -320,18 +316,17 @@ class ConnectionStart(AMQPMethodPayload):
     BINARY_HEADER = b'\x0A\x0A'      # CLASS ID + METHOD ID
 
     SENT_BY_CLIENT, SENT_BY_SERVER = False, True
-    REPLY_WITH = [ConnectionStartOk]       # methods you can reply with to this one
 
     IS_SIZE_STATIC = False     # this means that argument part has always the same length
     IS_CONTENT_STATIC = False  # this means that argument part has always the same content
 
     # See constructor pydoc for details
     FIELDS = [ 
-        Field(u'version-major', u'octet', reserved=False),
-        Field(u'version-minor', u'octet', reserved=False),
-        Field(u'server-properties', u'table', reserved=False),
-        Field(u'mechanisms', u'longstr', reserved=False),
-        Field(u'locales', u'longstr', reserved=False),
+        Field(u'version-major', u'octet', u'octet', reserved=False),
+        Field(u'version-minor', u'octet', u'octet', reserved=False),
+        Field(u'server-properties', u'peer-properties', u'table', reserved=False),
+        Field(u'mechanisms', u'longstr', u'longstr', reserved=False),
+        Field(u'locales', u'longstr', u'longstr', reserved=False),
     ]
 
     def __init__(self, version_major, version_minor, server_properties, mechanisms, locales):
@@ -407,14 +402,13 @@ class ConnectionSecure(AMQPMethodPayload):
     BINARY_HEADER = b'\x0A\x14'      # CLASS ID + METHOD ID
 
     SENT_BY_CLIENT, SENT_BY_SERVER = False, True
-    REPLY_WITH = [ConnectionSecureOk]       # methods you can reply with to this one
 
     IS_SIZE_STATIC = False     # this means that argument part has always the same length
     IS_CONTENT_STATIC = False  # this means that argument part has always the same content
 
     # See constructor pydoc for details
     FIELDS = [ 
-        Field(u'challenge', u'longstr', reserved=False),
+        Field(u'challenge', u'longstr', u'longstr', reserved=False),
     ]
 
     def __init__(self, challenge):
@@ -457,18 +451,16 @@ class ConnectionStartOk(AMQPMethodPayload):
     BINARY_HEADER = b'\x0A\x0B'      # CLASS ID + METHOD ID
 
     SENT_BY_CLIENT, SENT_BY_SERVER = True, False
-    REPLY_WITH = []       # methods you can reply with to this one
 
     IS_SIZE_STATIC = False     # this means that argument part has always the same length
     IS_CONTENT_STATIC = False  # this means that argument part has always the same content
-    RESPONSE_TO = ConnectionStart # this is sent in response to connection.start
 
     # See constructor pydoc for details
     FIELDS = [ 
-        Field(u'client-properties', u'table', reserved=False),
-        Field(u'mechanism', u'shortstr', reserved=False),
-        Field(u'response', u'longstr', reserved=False),
-        Field(u'locale', u'shortstr', reserved=False),
+        Field(u'client-properties', u'peer-properties', u'table', reserved=False),
+        Field(u'mechanism', u'shortstr', u'shortstr', reserved=False),
+        Field(u'response', u'longstr', u'longstr', reserved=False),
+        Field(u'locale', u'shortstr', u'shortstr', reserved=False),
     ]
 
     def __init__(self, client_properties, mechanism, response, locale):
@@ -544,15 +536,13 @@ class ConnectionSecureOk(AMQPMethodPayload):
     BINARY_HEADER = b'\x0A\x15'      # CLASS ID + METHOD ID
 
     SENT_BY_CLIENT, SENT_BY_SERVER = True, False
-    REPLY_WITH = []       # methods you can reply with to this one
 
     IS_SIZE_STATIC = False     # this means that argument part has always the same length
     IS_CONTENT_STATIC = False  # this means that argument part has always the same content
-    RESPONSE_TO = ConnectionSecure # this is sent in response to connection.secure
 
     # See constructor pydoc for details
     FIELDS = [ 
-        Field(u'response', u'longstr', reserved=False),
+        Field(u'response', u'longstr', u'longstr', reserved=False),
     ]
 
     def __init__(self, response):
@@ -596,16 +586,15 @@ class ConnectionTune(AMQPMethodPayload):
     BINARY_HEADER = b'\x0A\x1E'      # CLASS ID + METHOD ID
 
     SENT_BY_CLIENT, SENT_BY_SERVER = False, True
-    REPLY_WITH = [ConnectionTuneOk]       # methods you can reply with to this one
 
     IS_SIZE_STATIC = True     # this means that argument part has always the same length
     IS_CONTENT_STATIC = False  # this means that argument part has always the same content
 
     # See constructor pydoc for details
     FIELDS = [ 
-        Field(u'channel-max', u'short', reserved=False),
-        Field(u'frame-max', u'long', reserved=False),
-        Field(u'heartbeat', u'short', reserved=False),
+        Field(u'channel-max', u'short', u'short', reserved=False),
+        Field(u'frame-max', u'long', u'long', reserved=False),
+        Field(u'heartbeat', u'short', u'short', reserved=False),
     ]
 
     def __init__(self, channel_max, frame_max, heartbeat):
@@ -658,17 +647,15 @@ class ConnectionTuneOk(AMQPMethodPayload):
     BINARY_HEADER = b'\x0A\x1F'      # CLASS ID + METHOD ID
 
     SENT_BY_CLIENT, SENT_BY_SERVER = True, False
-    REPLY_WITH = []       # methods you can reply with to this one
 
     IS_SIZE_STATIC = True     # this means that argument part has always the same length
     IS_CONTENT_STATIC = False  # this means that argument part has always the same content
-    RESPONSE_TO = ConnectionTune # this is sent in response to connection.tune
 
     # See constructor pydoc for details
     FIELDS = [ 
-        Field(u'channel-max', u'short', reserved=False),
-        Field(u'frame-max', u'long', reserved=False),
-        Field(u'heartbeat', u'short', reserved=False),
+        Field(u'channel-max', u'short', u'short', reserved=False),
+        Field(u'frame-max', u'long', u'long', reserved=False),
+        Field(u'heartbeat', u'short', u'short', reserved=False),
     ]
 
     def __init__(self, channel_max, frame_max, heartbeat):
@@ -733,17 +720,16 @@ class ChannelClose(AMQPMethodPayload):
     BINARY_HEADER = b'\x14\x28'      # CLASS ID + METHOD ID
 
     SENT_BY_CLIENT, SENT_BY_SERVER = True, True
-    REPLY_WITH = [ChannelCloseOk]       # methods you can reply with to this one
 
     IS_SIZE_STATIC = False     # this means that argument part has always the same length
     IS_CONTENT_STATIC = False  # this means that argument part has always the same content
 
     # See constructor pydoc for details
     FIELDS = [ 
-        Field(u'reply-code', u'short', reserved=False),
-        Field(u'reply-text', u'shortstr', reserved=False),
-        Field(u'class-id', u'short', reserved=False),
-        Field(u'method-id', u'short', reserved=False),
+        Field(u'reply-code', u'reply-code', u'short', reserved=False),
+        Field(u'reply-text', u'reply-text', u'shortstr', reserved=False),
+        Field(u'class-id', u'class-id', u'short', reserved=False),
+        Field(u'method-id', u'method-id', u'short', reserved=False),
     ]
 
     def __init__(self, reply_code, reply_text, class_id, method_id):
@@ -798,12 +784,10 @@ class ChannelCloseOk(AMQPMethodPayload):
     BINARY_HEADER = b'\x14\x29'      # CLASS ID + METHOD ID
 
     SENT_BY_CLIENT, SENT_BY_SERVER = True, True
-    REPLY_WITH = []       # methods you can reply with to this one
 
     IS_SIZE_STATIC = True     # this means that argument part has always the same length
     IS_CONTENT_STATIC = True  # this means that argument part has always the same content
     STATIC_CONTENT = b'\x00\x00\x00\x04\x14\x29\xCE'  # spans LENGTH, CLASS ID, METHOD ID, ....., FRAME_END
-    RESPONSE_TO = ChannelClose # this is sent in response to channel.close
 
     def __init__(self):
         """
@@ -833,14 +817,13 @@ class ChannelFlow(AMQPMethodPayload):
     BINARY_HEADER = b'\x14\x14'      # CLASS ID + METHOD ID
 
     SENT_BY_CLIENT, SENT_BY_SERVER = True, True
-    REPLY_WITH = [ChannelFlowOk]       # methods you can reply with to this one
 
     IS_SIZE_STATIC = True     # this means that argument part has always the same length
     IS_CONTENT_STATIC = False  # this means that argument part has always the same content
 
     # See constructor pydoc for details
     FIELDS = [ 
-        Field(u'active', u'bit', reserved=False),
+        Field(u'active', u'bit', u'bit', reserved=False),
     ]
 
     def __init__(self, active):
@@ -881,15 +864,13 @@ class ChannelFlowOk(AMQPMethodPayload):
     BINARY_HEADER = b'\x14\x15'      # CLASS ID + METHOD ID
 
     SENT_BY_CLIENT, SENT_BY_SERVER = True, True
-    REPLY_WITH = []       # methods you can reply with to this one
 
     IS_SIZE_STATIC = True     # this means that argument part has always the same length
     IS_CONTENT_STATIC = False  # this means that argument part has always the same content
-    RESPONSE_TO = ChannelFlow # this is sent in response to channel.flow
 
     # See constructor pydoc for details
     FIELDS = [ 
-        Field(u'active', u'bit', reserved=False),
+        Field(u'active', u'bit', u'bit', reserved=False),
     ]
 
     def __init__(self, active):
@@ -930,7 +911,6 @@ class ChannelOpen(AMQPMethodPayload):
     BINARY_HEADER = b'\x14\x0A'      # CLASS ID + METHOD ID
 
     SENT_BY_CLIENT, SENT_BY_SERVER = True, False
-    REPLY_WITH = [ChannelOpenOk]       # methods you can reply with to this one
 
     IS_SIZE_STATIC = False     # this means that argument part has always the same length
     IS_CONTENT_STATIC = True  # this means that argument part has always the same content
@@ -938,7 +918,7 @@ class ChannelOpen(AMQPMethodPayload):
 
     # See constructor pydoc for details
     FIELDS = [ 
-        Field(u'reserved-1', u'shortstr', reserved=True),
+        Field(u'reserved-1', u'shortstr', u'shortstr', reserved=True),
     ]
 
     def __init__(self):
@@ -968,16 +948,14 @@ class ChannelOpenOk(AMQPMethodPayload):
     BINARY_HEADER = b'\x14\x0B'      # CLASS ID + METHOD ID
 
     SENT_BY_CLIENT, SENT_BY_SERVER = False, True
-    REPLY_WITH = []       # methods you can reply with to this one
 
     IS_SIZE_STATIC = False     # this means that argument part has always the same length
     IS_CONTENT_STATIC = True  # this means that argument part has always the same content
     STATIC_CONTENT = b'\x00\x00\x00\x05\x14\x0B\x00\x00\x00\x00\xCE'  # spans LENGTH, CLASS ID, METHOD ID, ....., FRAME_END
-    RESPONSE_TO = ChannelOpen # this is sent in response to channel.open
 
     # See constructor pydoc for details
     FIELDS = [ 
-        Field(u'reserved-1', u'longstr', reserved=True),
+        Field(u'reserved-1', u'longstr', u'longstr', reserved=True),
     ]
 
     def __init__(self):
@@ -1018,22 +996,21 @@ class ExchangeDeclare(AMQPMethodPayload):
     BINARY_HEADER = b'\x28\x0A'      # CLASS ID + METHOD ID
 
     SENT_BY_CLIENT, SENT_BY_SERVER = True, False
-    REPLY_WITH = [ExchangeDeclareOk]       # methods you can reply with to this one
 
     IS_SIZE_STATIC = False     # this means that argument part has always the same length
     IS_CONTENT_STATIC = False  # this means that argument part has always the same content
 
     # See constructor pydoc for details
     FIELDS = [ 
-        Field(u'reserved-1', u'short', reserved=True),
-        Field(u'exchange', u'shortstr', reserved=False),
-        Field(u'type', u'shortstr', reserved=False),
-        Field(u'passive', u'bit', reserved=False),
-        Field(u'durable', u'bit', reserved=False),
-        Field(u'reserved-2', u'bit', reserved=True),
-        Field(u'reserved-3', u'bit', reserved=True),
-        Field(u'no-wait', u'bit', reserved=False),
-        Field(u'arguments', u'table', reserved=False),
+        Field(u'reserved-1', u'short', u'short', reserved=True),
+        Field(u'exchange', u'exchange-name', u'shortstr', reserved=False),
+        Field(u'type', u'shortstr', u'shortstr', reserved=False),
+        Field(u'passive', u'bit', u'bit', reserved=False),
+        Field(u'durable', u'bit', u'bit', reserved=False),
+        Field(u'reserved-2', u'bit', u'bit', reserved=True),
+        Field(u'reserved-3', u'bit', u'bit', reserved=True),
+        Field(u'no-wait', u'no-wait', u'bit', reserved=False),
+        Field(u'arguments', u'table', u'table', reserved=False),
     ]
 
     def __init__(self, exchange, type_, passive, durable, no_wait, arguments):
@@ -1121,17 +1098,16 @@ class ExchangeDelete(AMQPMethodPayload):
     BINARY_HEADER = b'\x28\x14'      # CLASS ID + METHOD ID
 
     SENT_BY_CLIENT, SENT_BY_SERVER = True, False
-    REPLY_WITH = [ExchangeDeleteOk]       # methods you can reply with to this one
 
     IS_SIZE_STATIC = False     # this means that argument part has always the same length
     IS_CONTENT_STATIC = False  # this means that argument part has always the same content
 
     # See constructor pydoc for details
     FIELDS = [ 
-        Field(u'reserved-1', u'short', reserved=True),
-        Field(u'exchange', u'shortstr', reserved=False),
-        Field(u'if-unused', u'bit', reserved=False),
-        Field(u'no-wait', u'bit', reserved=False),
+        Field(u'reserved-1', u'short', u'short', reserved=True),
+        Field(u'exchange', u'exchange-name', u'shortstr', reserved=False),
+        Field(u'if-unused', u'bit', u'bit', reserved=False),
+        Field(u'no-wait', u'no-wait', u'bit', reserved=False),
     ]
 
     def __init__(self, exchange, if_unused, no_wait):
@@ -1186,12 +1162,10 @@ class ExchangeDeclareOk(AMQPMethodPayload):
     BINARY_HEADER = b'\x28\x0B'      # CLASS ID + METHOD ID
 
     SENT_BY_CLIENT, SENT_BY_SERVER = False, True
-    REPLY_WITH = []       # methods you can reply with to this one
 
     IS_SIZE_STATIC = True     # this means that argument part has always the same length
     IS_CONTENT_STATIC = True  # this means that argument part has always the same content
     STATIC_CONTENT = b'\x00\x00\x00\x04\x28\x0B\xCE'  # spans LENGTH, CLASS ID, METHOD ID, ....., FRAME_END
-    RESPONSE_TO = ExchangeDeclare # this is sent in response to exchange.declare
 
     def __init__(self):
         """
@@ -1217,12 +1191,10 @@ class ExchangeDeleteOk(AMQPMethodPayload):
     BINARY_HEADER = b'\x28\x15'      # CLASS ID + METHOD ID
 
     SENT_BY_CLIENT, SENT_BY_SERVER = False, True
-    REPLY_WITH = []       # methods you can reply with to this one
 
     IS_SIZE_STATIC = True     # this means that argument part has always the same length
     IS_CONTENT_STATIC = True  # this means that argument part has always the same content
     STATIC_CONTENT = b'\x00\x00\x00\x04\x28\x15\xCE'  # spans LENGTH, CLASS ID, METHOD ID, ....., FRAME_END
-    RESPONSE_TO = ExchangeDelete # this is sent in response to exchange.delete
 
     def __init__(self):
         """
@@ -1262,19 +1234,18 @@ class QueueBind(AMQPMethodPayload):
     BINARY_HEADER = b'\x32\x14'      # CLASS ID + METHOD ID
 
     SENT_BY_CLIENT, SENT_BY_SERVER = True, False
-    REPLY_WITH = [QueueBindOk]       # methods you can reply with to this one
 
     IS_SIZE_STATIC = False     # this means that argument part has always the same length
     IS_CONTENT_STATIC = False  # this means that argument part has always the same content
 
     # See constructor pydoc for details
     FIELDS = [ 
-        Field(u'reserved-1', u'short', reserved=True),
-        Field(u'queue', u'shortstr', reserved=False),
-        Field(u'exchange', u'shortstr', reserved=False),
-        Field(u'routing-key', u'shortstr', reserved=False),
-        Field(u'no-wait', u'bit', reserved=False),
-        Field(u'arguments', u'table', reserved=False),
+        Field(u'reserved-1', u'short', u'short', reserved=True),
+        Field(u'queue', u'queue-name', u'shortstr', reserved=False),
+        Field(u'exchange', u'exchange-name', u'shortstr', reserved=False),
+        Field(u'routing-key', u'shortstr', u'shortstr', reserved=False),
+        Field(u'no-wait', u'no-wait', u'bit', reserved=False),
+        Field(u'arguments', u'table', u'table', reserved=False),
     ]
 
     def __init__(self, queue, exchange, routing_key, no_wait, arguments):
@@ -1356,12 +1327,10 @@ class QueueBindOk(AMQPMethodPayload):
     BINARY_HEADER = b'\x32\x15'      # CLASS ID + METHOD ID
 
     SENT_BY_CLIENT, SENT_BY_SERVER = False, True
-    REPLY_WITH = []       # methods you can reply with to this one
 
     IS_SIZE_STATIC = True     # this means that argument part has always the same length
     IS_CONTENT_STATIC = True  # this means that argument part has always the same content
     STATIC_CONTENT = b'\x00\x00\x00\x04\x32\x15\xCE'  # spans LENGTH, CLASS ID, METHOD ID, ....., FRAME_END
-    RESPONSE_TO = QueueBind # this is sent in response to queue.bind
 
     def __init__(self):
         """
@@ -1389,21 +1358,20 @@ class QueueDeclare(AMQPMethodPayload):
     BINARY_HEADER = b'\x32\x0A'      # CLASS ID + METHOD ID
 
     SENT_BY_CLIENT, SENT_BY_SERVER = True, False
-    REPLY_WITH = [QueueDeclareOk]       # methods you can reply with to this one
 
     IS_SIZE_STATIC = False     # this means that argument part has always the same length
     IS_CONTENT_STATIC = False  # this means that argument part has always the same content
 
     # See constructor pydoc for details
     FIELDS = [ 
-        Field(u'reserved-1', u'short', reserved=True),
-        Field(u'queue', u'shortstr', reserved=False),
-        Field(u'passive', u'bit', reserved=False),
-        Field(u'durable', u'bit', reserved=False),
-        Field(u'exclusive', u'bit', reserved=False),
-        Field(u'auto-delete', u'bit', reserved=False),
-        Field(u'no-wait', u'bit', reserved=False),
-        Field(u'arguments', u'table', reserved=False),
+        Field(u'reserved-1', u'short', u'short', reserved=True),
+        Field(u'queue', u'queue-name', u'shortstr', reserved=False),
+        Field(u'passive', u'bit', u'bit', reserved=False),
+        Field(u'durable', u'bit', u'bit', reserved=False),
+        Field(u'exclusive', u'bit', u'bit', reserved=False),
+        Field(u'auto-delete', u'bit', u'bit', reserved=False),
+        Field(u'no-wait', u'no-wait', u'bit', reserved=False),
+        Field(u'arguments', u'table', u'table', reserved=False),
     ]
 
     def __init__(self, queue, passive, durable, exclusive, auto_delete, no_wait, arguments):
@@ -1496,18 +1464,17 @@ class QueueDelete(AMQPMethodPayload):
     BINARY_HEADER = b'\x32\x28'      # CLASS ID + METHOD ID
 
     SENT_BY_CLIENT, SENT_BY_SERVER = True, False
-    REPLY_WITH = [QueueDeleteOk]       # methods you can reply with to this one
 
     IS_SIZE_STATIC = False     # this means that argument part has always the same length
     IS_CONTENT_STATIC = False  # this means that argument part has always the same content
 
     # See constructor pydoc for details
     FIELDS = [ 
-        Field(u'reserved-1', u'short', reserved=True),
-        Field(u'queue', u'shortstr', reserved=False),
-        Field(u'if-unused', u'bit', reserved=False),
-        Field(u'if-empty', u'bit', reserved=False),
-        Field(u'no-wait', u'bit', reserved=False),
+        Field(u'reserved-1', u'short', u'short', reserved=True),
+        Field(u'queue', u'queue-name', u'shortstr', reserved=False),
+        Field(u'if-unused', u'bit', u'bit', reserved=False),
+        Field(u'if-empty', u'bit', u'bit', reserved=False),
+        Field(u'no-wait', u'no-wait', u'bit', reserved=False),
     ]
 
     def __init__(self, queue, if_unused, if_empty, no_wait):
@@ -1567,17 +1534,15 @@ class QueueDeclareOk(AMQPMethodPayload):
     BINARY_HEADER = b'\x32\x0B'      # CLASS ID + METHOD ID
 
     SENT_BY_CLIENT, SENT_BY_SERVER = False, True
-    REPLY_WITH = []       # methods you can reply with to this one
 
     IS_SIZE_STATIC = False     # this means that argument part has always the same length
     IS_CONTENT_STATIC = False  # this means that argument part has always the same content
-    RESPONSE_TO = QueueDeclare # this is sent in response to queue.declare
 
     # See constructor pydoc for details
     FIELDS = [ 
-        Field(u'queue', u'shortstr', reserved=False),
-        Field(u'message-count', u'long', reserved=False),
-        Field(u'consumer-count', u'long', reserved=False),
+        Field(u'queue', u'queue-name', u'shortstr', reserved=False),
+        Field(u'message-count', u'message-count', u'long', reserved=False),
+        Field(u'consumer-count', u'long', u'long', reserved=False),
     ]
 
     def __init__(self, queue, message_count, consumer_count):
@@ -1629,15 +1594,13 @@ class QueueDeleteOk(AMQPMethodPayload):
     BINARY_HEADER = b'\x32\x29'      # CLASS ID + METHOD ID
 
     SENT_BY_CLIENT, SENT_BY_SERVER = False, True
-    REPLY_WITH = []       # methods you can reply with to this one
 
     IS_SIZE_STATIC = True     # this means that argument part has always the same length
     IS_CONTENT_STATIC = False  # this means that argument part has always the same content
-    RESPONSE_TO = QueueDelete # this is sent in response to queue.delete
 
     # See constructor pydoc for details
     FIELDS = [ 
-        Field(u'message-count', u'long', reserved=False),
+        Field(u'message-count', u'message-count', u'long', reserved=False),
     ]
 
     def __init__(self, message_count):
@@ -1676,16 +1639,15 @@ class QueuePurge(AMQPMethodPayload):
     BINARY_HEADER = b'\x32\x1E'      # CLASS ID + METHOD ID
 
     SENT_BY_CLIENT, SENT_BY_SERVER = True, False
-    REPLY_WITH = [QueuePurgeOk]       # methods you can reply with to this one
 
     IS_SIZE_STATIC = False     # this means that argument part has always the same length
     IS_CONTENT_STATIC = False  # this means that argument part has always the same content
 
     # See constructor pydoc for details
     FIELDS = [ 
-        Field(u'reserved-1', u'short', reserved=True),
-        Field(u'queue', u'shortstr', reserved=False),
-        Field(u'no-wait', u'bit', reserved=False),
+        Field(u'reserved-1', u'short', u'short', reserved=True),
+        Field(u'queue', u'queue-name', u'shortstr', reserved=False),
+        Field(u'no-wait', u'no-wait', u'bit', reserved=False),
     ]
 
     def __init__(self, queue, no_wait):
@@ -1732,15 +1694,13 @@ class QueuePurgeOk(AMQPMethodPayload):
     BINARY_HEADER = b'\x32\x1F'      # CLASS ID + METHOD ID
 
     SENT_BY_CLIENT, SENT_BY_SERVER = False, True
-    REPLY_WITH = []       # methods you can reply with to this one
 
     IS_SIZE_STATIC = True     # this means that argument part has always the same length
     IS_CONTENT_STATIC = False  # this means that argument part has always the same content
-    RESPONSE_TO = QueuePurge # this is sent in response to queue.purge
 
     # See constructor pydoc for details
     FIELDS = [ 
-        Field(u'message-count', u'long', reserved=False),
+        Field(u'message-count', u'message-count', u'long', reserved=False),
     ]
 
     def __init__(self, message_count):
@@ -1778,18 +1738,17 @@ class QueueUnbind(AMQPMethodPayload):
     BINARY_HEADER = b'\x32\x32'      # CLASS ID + METHOD ID
 
     SENT_BY_CLIENT, SENT_BY_SERVER = True, False
-    REPLY_WITH = [QueueUnbindOk]       # methods you can reply with to this one
 
     IS_SIZE_STATIC = False     # this means that argument part has always the same length
     IS_CONTENT_STATIC = False  # this means that argument part has always the same content
 
     # See constructor pydoc for details
     FIELDS = [ 
-        Field(u'reserved-1', u'short', reserved=True),
-        Field(u'queue', u'shortstr', reserved=False),
-        Field(u'exchange', u'shortstr', reserved=False),
-        Field(u'routing-key', u'shortstr', reserved=False),
-        Field(u'arguments', u'table', reserved=False),
+        Field(u'reserved-1', u'short', u'short', reserved=True),
+        Field(u'queue', u'queue-name', u'shortstr', reserved=False),
+        Field(u'exchange', u'exchange-name', u'shortstr', reserved=False),
+        Field(u'routing-key', u'shortstr', u'shortstr', reserved=False),
+        Field(u'arguments', u'table', u'table', reserved=False),
     ]
 
     def __init__(self, queue, exchange, routing_key, arguments):
@@ -1856,12 +1815,10 @@ class QueueUnbindOk(AMQPMethodPayload):
     BINARY_HEADER = b'\x32\x33'      # CLASS ID + METHOD ID
 
     SENT_BY_CLIENT, SENT_BY_SERVER = False, True
-    REPLY_WITH = []       # methods you can reply with to this one
 
     IS_SIZE_STATIC = True     # this means that argument part has always the same length
     IS_CONTENT_STATIC = True  # this means that argument part has always the same content
     STATIC_CONTENT = b'\x00\x00\x00\x04\x32\x33\xCE'  # spans LENGTH, CLASS ID, METHOD ID, ....., FRAME_END
-    RESPONSE_TO = QueueUnbind # this is sent in response to queue.unbind
 
     def __init__(self):
         """
@@ -1888,21 +1845,90 @@ class BasicContentPropertyList(AMQPContentPropertyList):
     The basic class provides methods that support an industry-standard messaging model.
     """
     FIELDS = [
-        Field(u'content-type', u'shortstr', False),
-        Field(u'content-encoding', u'shortstr', False),
-        Field(u'headers', u'table', False),
-        Field(u'delivery-mode', u'octet', False),
-        Field(u'priority', u'octet', False),
-        Field(u'correlation-id', u'shortstr', False),
-        Field(u'reply-to', u'shortstr', False),
-        Field(u'expiration', u'shortstr', False),
-        Field(u'message-id', u'shortstr', False),
-        Field(u'timestamp', u'timestamp', False),
-        Field(u'type', u'shortstr', False),
-        Field(u'user-id', u'shortstr', False),
-        Field(u'app-id', u'shortstr', False),
-        Field(u'reserved', u'shortstr', False),
+        Field(u'content-type', u'shortstr', u'shortstr', False),
+        Field(u'content-encoding', u'shortstr', u'shortstr', False),
+        Field(u'headers', u'table', u'table', False),
+        Field(u'delivery-mode', u'octet', u'octet', False),
+        Field(u'priority', u'octet', u'octet', False),
+        Field(u'correlation-id', u'shortstr', u'shortstr', False),
+        Field(u'reply-to', u'shortstr', u'shortstr', False),
+        Field(u'expiration', u'shortstr', u'shortstr', False),
+        Field(u'message-id', u'shortstr', u'shortstr', False),
+        Field(u'timestamp', u'timestamp', u'timestamp', False),
+        Field(u'type', u'shortstr', u'shortstr', False),
+        Field(u'user-id', u'shortstr', u'shortstr', False),
+        Field(u'app-id', u'shortstr', u'shortstr', False),
+        Field(u'reserved', u'shortstr', u'shortstr', False),
     ]
+    # A dictionary from a zero property list to a class typized with
+    # some fields
+    PARTICULAR_CLASSES = {}
+
+    def __new__(self, **kwargs):
+        """
+        Return a property list.
+        :param content_type: MIME content type
+        :type content_type: binary type (max length 255) (AMQP as shortstr)
+        :param content_encoding: MIME content encoding
+        :type content_encoding: binary type (max length 255) (AMQP as shortstr)
+        :param headers: message header field table
+        :type headers: table. See coolamqp.uplink.framing.field_table (AMQP as table)
+        :param delivery_mode: non-persistent (1) or persistent (2)
+        :type delivery_mode: int, 8 bit unsigned (AMQP as octet)
+        :param priority: message priority, 0 to 9
+        :type priority: int, 8 bit unsigned (AMQP as octet)
+        :param correlation_id: application correlation identifier
+        :type correlation_id: binary type (max length 255) (AMQP as shortstr)
+        :param reply_to: address to reply to
+        :type reply_to: binary type (max length 255) (AMQP as shortstr)
+        :param expiration: message expiration specification
+        :type expiration: binary type (max length 255) (AMQP as shortstr)
+        :param message_id: application message identifier
+        :type message_id: binary type (max length 255) (AMQP as shortstr)
+        :param timestamp: message timestamp
+        :type timestamp: 64 bit signed POSIX timestamp (in seconds) (AMQP as timestamp)
+        :param type_: message type name
+        :type type_: binary type (max length 255) (AMQP as shortstr)
+        :param user_id: creating user id
+        :type user_id: binary type (max length 255) (AMQP as shortstr)
+        :param app_id: creating application id
+        :type app_id: binary type (max length 255) (AMQP as shortstr)
+        :param reserved: reserved, must be empty
+        :type reserved: binary type (max length 255) (AMQP as shortstr)
+        """
+        zpf = bytearray([
+            (('content_type' in kwargs) << 7) | (('content_encoding' in kwargs) << 6) | (('headers' in kwargs) << 5) | (('delivery_mode' in kwargs) << 4) | (('priority' in kwargs) << 3) | (('correlation_id' in kwargs) << 2) | (('reply_to' in kwargs) << 1) | int('expiration' in kwargs),
+            (('message_id' in kwargs) << 7) | (('timestamp' in kwargs) << 6) | (('type_' in kwargs) << 5) | (('user_id' in kwargs) << 4) | (('app_id' in kwargs) << 3) | (('reserved' in kwargs) << 2)
+        ])
+        zpf = six.binary_type(zpf)
+
+        if zpf in BasicContentPropertyList.PARTICULAR_CLASSES:
+            warnings.warn(u"""You could go faster.
+
+        If you know in advance what properties you will be using, use typized constructors like
+
+            # runs once
+            my_type = BasicContentPropertyList.typize('content_type', 'content_encoding')
+            # runs many times
+            props = my_type('text/plain', 'utf8')
+
+        instead of
+
+            # runs many times
+            props = BasicContentPropertyList(content_type='text/plain', content_encoding='utf8')
+
+        This way you will be faster.
+
+        If you do not know in advance what properties you will be using, it is correct to use
+        this constructor.
+        """)
+
+            return BasicContentPropertyList.PARTICULAR_CLASSES[zpf](**kwargs)
+        else:
+            logger.debug('Property field (BasicContentPropertyList:%s) not seen yet, compiling', repr(zpf))
+            c = compile_particular_content_property_list_class(zpf, BasicContentPropertyList.FIELDS)
+            BasicContentPropertyList.PARTICULAR_CLASSES[zpf] = c
+            return c(**kwargs)
 
 
 class BasicAck(AMQPMethodPayload):
@@ -1919,15 +1945,14 @@ class BasicAck(AMQPMethodPayload):
     BINARY_HEADER = b'\x3C\x50'      # CLASS ID + METHOD ID
 
     SENT_BY_CLIENT, SENT_BY_SERVER = True, False
-    REPLY_WITH = []       # methods you can reply with to this one
 
     IS_SIZE_STATIC = True     # this means that argument part has always the same length
     IS_CONTENT_STATIC = False  # this means that argument part has always the same content
 
     # See constructor pydoc for details
     FIELDS = [ 
-        Field(u'delivery-tag', u'longlong', reserved=False),
-        Field(u'multiple', u'bit', reserved=False),
+        Field(u'delivery-tag', u'delivery-tag', u'longlong', reserved=False),
+        Field(u'multiple', u'bit', u'bit', reserved=False),
     ]
 
     def __init__(self, delivery_tag, multiple):
@@ -1976,21 +2001,20 @@ class BasicConsume(AMQPMethodPayload):
     BINARY_HEADER = b'\x3C\x14'      # CLASS ID + METHOD ID
 
     SENT_BY_CLIENT, SENT_BY_SERVER = True, False
-    REPLY_WITH = [BasicConsumeOk]       # methods you can reply with to this one
 
     IS_SIZE_STATIC = False     # this means that argument part has always the same length
     IS_CONTENT_STATIC = False  # this means that argument part has always the same content
 
     # See constructor pydoc for details
     FIELDS = [ 
-        Field(u'reserved-1', u'short', reserved=True),
-        Field(u'queue', u'shortstr', reserved=False),
-        Field(u'consumer-tag', u'shortstr', reserved=False),
-        Field(u'no-local', u'bit', reserved=False),
-        Field(u'no-ack', u'bit', reserved=False),
-        Field(u'exclusive', u'bit', reserved=False),
-        Field(u'no-wait', u'bit', reserved=False),
-        Field(u'arguments', u'table', reserved=False),
+        Field(u'reserved-1', u'short', u'short', reserved=True),
+        Field(u'queue', u'queue-name', u'shortstr', reserved=False),
+        Field(u'consumer-tag', u'consumer-tag', u'shortstr', reserved=False),
+        Field(u'no-local', u'no-local', u'bit', reserved=False),
+        Field(u'no-ack', u'no-ack', u'bit', reserved=False),
+        Field(u'exclusive', u'bit', u'bit', reserved=False),
+        Field(u'no-wait', u'no-wait', u'bit', reserved=False),
+        Field(u'arguments', u'table', u'table', reserved=False),
     ]
 
     def __init__(self, queue, consumer_tag, no_local, no_ack, exclusive, no_wait, arguments):
@@ -2071,15 +2095,14 @@ class BasicCancel(AMQPMethodPayload):
     BINARY_HEADER = b'\x3C\x1E'      # CLASS ID + METHOD ID
 
     SENT_BY_CLIENT, SENT_BY_SERVER = True, False
-    REPLY_WITH = [BasicCancelOk]       # methods you can reply with to this one
 
     IS_SIZE_STATIC = False     # this means that argument part has always the same length
     IS_CONTENT_STATIC = False  # this means that argument part has always the same content
 
     # See constructor pydoc for details
     FIELDS = [ 
-        Field(u'consumer-tag', u'shortstr', reserved=False),
-        Field(u'no-wait', u'bit', reserved=False),
+        Field(u'consumer-tag', u'consumer-tag', u'shortstr', reserved=False),
+        Field(u'no-wait', u'no-wait', u'bit', reserved=False),
     ]
 
     def __init__(self, consumer_tag, no_wait):
@@ -2126,15 +2149,13 @@ class BasicConsumeOk(AMQPMethodPayload):
     BINARY_HEADER = b'\x3C\x15'      # CLASS ID + METHOD ID
 
     SENT_BY_CLIENT, SENT_BY_SERVER = False, True
-    REPLY_WITH = []       # methods you can reply with to this one
 
     IS_SIZE_STATIC = False     # this means that argument part has always the same length
     IS_CONTENT_STATIC = False  # this means that argument part has always the same content
-    RESPONSE_TO = BasicConsume # this is sent in response to basic.consume
 
     # See constructor pydoc for details
     FIELDS = [ 
-        Field(u'consumer-tag', u'shortstr', reserved=False),
+        Field(u'consumer-tag', u'consumer-tag', u'shortstr', reserved=False),
     ]
 
     def __init__(self, consumer_tag):
@@ -2175,15 +2196,13 @@ class BasicCancelOk(AMQPMethodPayload):
     BINARY_HEADER = b'\x3C\x1F'      # CLASS ID + METHOD ID
 
     SENT_BY_CLIENT, SENT_BY_SERVER = False, True
-    REPLY_WITH = []       # methods you can reply with to this one
 
     IS_SIZE_STATIC = False     # this means that argument part has always the same length
     IS_CONTENT_STATIC = False  # this means that argument part has always the same content
-    RESPONSE_TO = BasicCancel # this is sent in response to basic.cancel
 
     # See constructor pydoc for details
     FIELDS = [ 
-        Field(u'consumer-tag', u'shortstr', reserved=False),
+        Field(u'consumer-tag', u'consumer-tag', u'shortstr', reserved=False),
     ]
 
     def __init__(self, consumer_tag):
@@ -2226,18 +2245,17 @@ class BasicDeliver(AMQPMethodPayload):
     BINARY_HEADER = b'\x3C\x3C'      # CLASS ID + METHOD ID
 
     SENT_BY_CLIENT, SENT_BY_SERVER = False, True
-    REPLY_WITH = []       # methods you can reply with to this one
 
     IS_SIZE_STATIC = False     # this means that argument part has always the same length
     IS_CONTENT_STATIC = False  # this means that argument part has always the same content
 
     # See constructor pydoc for details
     FIELDS = [ 
-        Field(u'consumer-tag', u'shortstr', reserved=False),
-        Field(u'delivery-tag', u'longlong', reserved=False),
-        Field(u'redelivered', u'bit', reserved=False),
-        Field(u'exchange', u'shortstr', reserved=False),
-        Field(u'routing-key', u'shortstr', reserved=False),
+        Field(u'consumer-tag', u'consumer-tag', u'shortstr', reserved=False),
+        Field(u'delivery-tag', u'delivery-tag', u'longlong', reserved=False),
+        Field(u'redelivered', u'redelivered', u'bit', reserved=False),
+        Field(u'exchange', u'exchange-name', u'shortstr', reserved=False),
+        Field(u'routing-key', u'shortstr', u'shortstr', reserved=False),
     ]
 
     def __init__(self, consumer_tag, delivery_tag, redelivered, exchange, routing_key):
@@ -2306,16 +2324,15 @@ class BasicGet(AMQPMethodPayload):
     BINARY_HEADER = b'\x3C\x46'      # CLASS ID + METHOD ID
 
     SENT_BY_CLIENT, SENT_BY_SERVER = True, False
-    REPLY_WITH = [BasicGetOk, BasicGetEmpty]       # methods you can reply with to this one
 
     IS_SIZE_STATIC = False     # this means that argument part has always the same length
     IS_CONTENT_STATIC = False  # this means that argument part has always the same content
 
     # See constructor pydoc for details
     FIELDS = [ 
-        Field(u'reserved-1', u'short', reserved=True),
-        Field(u'queue', u'shortstr', reserved=False),
-        Field(u'no-ack', u'bit', reserved=False),
+        Field(u'reserved-1', u'short', u'short', reserved=True),
+        Field(u'queue', u'queue-name', u'shortstr', reserved=False),
+        Field(u'no-ack', u'no-ack', u'bit', reserved=False),
     ]
 
     def __init__(self, queue, no_ack):
@@ -2364,19 +2381,17 @@ class BasicGetOk(AMQPMethodPayload):
     BINARY_HEADER = b'\x3C\x47'      # CLASS ID + METHOD ID
 
     SENT_BY_CLIENT, SENT_BY_SERVER = False, True
-    REPLY_WITH = []       # methods you can reply with to this one
 
     IS_SIZE_STATIC = False     # this means that argument part has always the same length
     IS_CONTENT_STATIC = False  # this means that argument part has always the same content
-    RESPONSE_TO = BasicGet # this is sent in response to basic.get
 
     # See constructor pydoc for details
     FIELDS = [ 
-        Field(u'delivery-tag', u'longlong', reserved=False),
-        Field(u'redelivered', u'bit', reserved=False),
-        Field(u'exchange', u'shortstr', reserved=False),
-        Field(u'routing-key', u'shortstr', reserved=False),
-        Field(u'message-count', u'long', reserved=False),
+        Field(u'delivery-tag', u'delivery-tag', u'longlong', reserved=False),
+        Field(u'redelivered', u'redelivered', u'bit', reserved=False),
+        Field(u'exchange', u'exchange-name', u'shortstr', reserved=False),
+        Field(u'routing-key', u'shortstr', u'shortstr', reserved=False),
+        Field(u'message-count', u'message-count', u'long', reserved=False),
     ]
 
     def __init__(self, delivery_tag, redelivered, exchange, routing_key, message_count):
@@ -2441,16 +2456,14 @@ class BasicGetEmpty(AMQPMethodPayload):
     BINARY_HEADER = b'\x3C\x48'      # CLASS ID + METHOD ID
 
     SENT_BY_CLIENT, SENT_BY_SERVER = False, True
-    REPLY_WITH = []       # methods you can reply with to this one
 
     IS_SIZE_STATIC = False     # this means that argument part has always the same length
     IS_CONTENT_STATIC = True  # this means that argument part has always the same content
     STATIC_CONTENT = b'\x00\x00\x00\x0D\x3C\x48\x00\xCE'  # spans LENGTH, CLASS ID, METHOD ID, ....., FRAME_END
-    RESPONSE_TO = BasicGet # this is sent in response to basic.get
 
     # See constructor pydoc for details
     FIELDS = [ 
-        Field(u'reserved-1', u'shortstr', reserved=True),
+        Field(u'reserved-1', u'shortstr', u'shortstr', reserved=True),
     ]
 
     def __init__(self):
@@ -2482,18 +2495,17 @@ class BasicPublish(AMQPMethodPayload):
     BINARY_HEADER = b'\x3C\x28'      # CLASS ID + METHOD ID
 
     SENT_BY_CLIENT, SENT_BY_SERVER = True, False
-    REPLY_WITH = []       # methods you can reply with to this one
 
     IS_SIZE_STATIC = False     # this means that argument part has always the same length
     IS_CONTENT_STATIC = False  # this means that argument part has always the same content
 
     # See constructor pydoc for details
     FIELDS = [ 
-        Field(u'reserved-1', u'short', reserved=True),
-        Field(u'exchange', u'shortstr', reserved=False),
-        Field(u'routing-key', u'shortstr', reserved=False),
-        Field(u'mandatory', u'bit', reserved=False),
-        Field(u'immediate', u'bit', reserved=False),
+        Field(u'reserved-1', u'short', u'short', reserved=True),
+        Field(u'exchange', u'exchange-name', u'shortstr', reserved=False),
+        Field(u'routing-key', u'shortstr', u'shortstr', reserved=False),
+        Field(u'mandatory', u'bit', u'bit', reserved=False),
+        Field(u'immediate', u'bit', u'bit', reserved=False),
     ]
 
     def __init__(self, exchange, routing_key, mandatory, immediate):
@@ -2569,16 +2581,15 @@ class BasicQos(AMQPMethodPayload):
     BINARY_HEADER = b'\x3C\x0A'      # CLASS ID + METHOD ID
 
     SENT_BY_CLIENT, SENT_BY_SERVER = True, False
-    REPLY_WITH = [BasicQosOk]       # methods you can reply with to this one
 
     IS_SIZE_STATIC = True     # this means that argument part has always the same length
     IS_CONTENT_STATIC = False  # this means that argument part has always the same content
 
     # See constructor pydoc for details
     FIELDS = [ 
-        Field(u'prefetch-size', u'long', reserved=False),
-        Field(u'prefetch-count', u'short', reserved=False),
-        Field(u'global', u'bit', reserved=False),
+        Field(u'prefetch-size', u'long', u'long', reserved=False),
+        Field(u'prefetch-count', u'short', u'short', reserved=False),
+        Field(u'global', u'bit', u'bit', reserved=False),
     ]
 
     def __init__(self, prefetch_size, prefetch_count, global_):
@@ -2641,12 +2652,10 @@ class BasicQosOk(AMQPMethodPayload):
     BINARY_HEADER = b'\x3C\x0B'      # CLASS ID + METHOD ID
 
     SENT_BY_CLIENT, SENT_BY_SERVER = False, True
-    REPLY_WITH = []       # methods you can reply with to this one
 
     IS_SIZE_STATIC = True     # this means that argument part has always the same length
     IS_CONTENT_STATIC = True  # this means that argument part has always the same content
     STATIC_CONTENT = b'\x00\x00\x00\x04\x3C\x0B\xCE'  # spans LENGTH, CLASS ID, METHOD ID, ....., FRAME_END
-    RESPONSE_TO = BasicQos # this is sent in response to basic.qos
 
     def __init__(self):
         """
@@ -2675,17 +2684,16 @@ class BasicReturn(AMQPMethodPayload):
     BINARY_HEADER = b'\x3C\x32'      # CLASS ID + METHOD ID
 
     SENT_BY_CLIENT, SENT_BY_SERVER = False, True
-    REPLY_WITH = []       # methods you can reply with to this one
 
     IS_SIZE_STATIC = False     # this means that argument part has always the same length
     IS_CONTENT_STATIC = False  # this means that argument part has always the same content
 
     # See constructor pydoc for details
     FIELDS = [ 
-        Field(u'reply-code', u'short', reserved=False),
-        Field(u'reply-text', u'shortstr', reserved=False),
-        Field(u'exchange', u'shortstr', reserved=False),
-        Field(u'routing-key', u'shortstr', reserved=False),
+        Field(u'reply-code', u'reply-code', u'short', reserved=False),
+        Field(u'reply-text', u'reply-text', u'shortstr', reserved=False),
+        Field(u'exchange', u'exchange-name', u'shortstr', reserved=False),
+        Field(u'routing-key', u'shortstr', u'shortstr', reserved=False),
     ]
 
     def __init__(self, reply_code, reply_text, exchange, routing_key):
@@ -2749,15 +2757,14 @@ class BasicReject(AMQPMethodPayload):
     BINARY_HEADER = b'\x3C\x5A'      # CLASS ID + METHOD ID
 
     SENT_BY_CLIENT, SENT_BY_SERVER = True, False
-    REPLY_WITH = []       # methods you can reply with to this one
 
     IS_SIZE_STATIC = True     # this means that argument part has always the same length
     IS_CONTENT_STATIC = False  # this means that argument part has always the same content
 
     # See constructor pydoc for details
     FIELDS = [ 
-        Field(u'delivery-tag', u'longlong', reserved=False),
-        Field(u'requeue', u'bit', reserved=False),
+        Field(u'delivery-tag', u'delivery-tag', u'longlong', reserved=False),
+        Field(u'requeue', u'bit', u'bit', reserved=False),
     ]
 
     def __init__(self, delivery_tag, requeue):
@@ -2804,14 +2811,13 @@ class BasicRecoverAsync(AMQPMethodPayload):
     BINARY_HEADER = b'\x3C\x64'      # CLASS ID + METHOD ID
 
     SENT_BY_CLIENT, SENT_BY_SERVER = True, False
-    REPLY_WITH = []       # methods you can reply with to this one
 
     IS_SIZE_STATIC = True     # this means that argument part has always the same length
     IS_CONTENT_STATIC = False  # this means that argument part has always the same content
 
     # See constructor pydoc for details
     FIELDS = [ 
-        Field(u'requeue', u'bit', reserved=False),
+        Field(u'requeue', u'bit', u'bit', reserved=False),
     ]
 
     def __init__(self, requeue):
@@ -2855,14 +2861,13 @@ class BasicRecover(AMQPMethodPayload):
     BINARY_HEADER = b'\x3C\x6E'      # CLASS ID + METHOD ID
 
     SENT_BY_CLIENT, SENT_BY_SERVER = True, False
-    REPLY_WITH = []       # methods you can reply with to this one
 
     IS_SIZE_STATIC = True     # this means that argument part has always the same length
     IS_CONTENT_STATIC = False  # this means that argument part has always the same content
 
     # See constructor pydoc for details
     FIELDS = [ 
-        Field(u'requeue', u'bit', reserved=False),
+        Field(u'requeue', u'bit', u'bit', reserved=False),
     ]
 
     def __init__(self, requeue):
@@ -2904,7 +2909,6 @@ class BasicRecoverOk(AMQPMethodPayload):
     BINARY_HEADER = b'\x3C\x6F'      # CLASS ID + METHOD ID
 
     SENT_BY_CLIENT, SENT_BY_SERVER = False, True
-    REPLY_WITH = []       # methods you can reply with to this one
 
     IS_SIZE_STATIC = True     # this means that argument part has always the same length
     IS_CONTENT_STATIC = True  # this means that argument part has always the same content
@@ -2952,7 +2956,6 @@ class TxCommit(AMQPMethodPayload):
     BINARY_HEADER = b'\x5A\x14'      # CLASS ID + METHOD ID
 
     SENT_BY_CLIENT, SENT_BY_SERVER = True, False
-    REPLY_WITH = [TxCommitOk]       # methods you can reply with to this one
 
     IS_SIZE_STATIC = True     # this means that argument part has always the same length
     IS_CONTENT_STATIC = True  # this means that argument part has always the same content
@@ -2983,12 +2986,10 @@ class TxCommitOk(AMQPMethodPayload):
     BINARY_HEADER = b'\x5A\x15'      # CLASS ID + METHOD ID
 
     SENT_BY_CLIENT, SENT_BY_SERVER = False, True
-    REPLY_WITH = []       # methods you can reply with to this one
 
     IS_SIZE_STATIC = True     # this means that argument part has always the same length
     IS_CONTENT_STATIC = True  # this means that argument part has always the same content
     STATIC_CONTENT = b'\x00\x00\x00\x04\x5A\x15\xCE'  # spans LENGTH, CLASS ID, METHOD ID, ....., FRAME_END
-    RESPONSE_TO = TxCommit # this is sent in response to tx.commit
 
     def __init__(self):
         """
@@ -3017,7 +3018,6 @@ class TxRollback(AMQPMethodPayload):
     BINARY_HEADER = b'\x5A\x1E'      # CLASS ID + METHOD ID
 
     SENT_BY_CLIENT, SENT_BY_SERVER = True, False
-    REPLY_WITH = [TxRollbackOk]       # methods you can reply with to this one
 
     IS_SIZE_STATIC = True     # this means that argument part has always the same length
     IS_CONTENT_STATIC = True  # this means that argument part has always the same content
@@ -3048,12 +3048,10 @@ class TxRollbackOk(AMQPMethodPayload):
     BINARY_HEADER = b'\x5A\x1F'      # CLASS ID + METHOD ID
 
     SENT_BY_CLIENT, SENT_BY_SERVER = False, True
-    REPLY_WITH = []       # methods you can reply with to this one
 
     IS_SIZE_STATIC = True     # this means that argument part has always the same length
     IS_CONTENT_STATIC = True  # this means that argument part has always the same content
     STATIC_CONTENT = b'\x00\x00\x00\x04\x5A\x1F\xCE'  # spans LENGTH, CLASS ID, METHOD ID, ....., FRAME_END
-    RESPONSE_TO = TxRollback # this is sent in response to tx.rollback
 
     def __init__(self):
         """
@@ -3080,7 +3078,6 @@ class TxSelect(AMQPMethodPayload):
     BINARY_HEADER = b'\x5A\x0A'      # CLASS ID + METHOD ID
 
     SENT_BY_CLIENT, SENT_BY_SERVER = True, False
-    REPLY_WITH = [TxSelectOk]       # methods you can reply with to this one
 
     IS_SIZE_STATIC = True     # this means that argument part has always the same length
     IS_CONTENT_STATIC = True  # this means that argument part has always the same content
@@ -3111,12 +3108,10 @@ class TxSelectOk(AMQPMethodPayload):
     BINARY_HEADER = b'\x5A\x0B'      # CLASS ID + METHOD ID
 
     SENT_BY_CLIENT, SENT_BY_SERVER = False, True
-    REPLY_WITH = []       # methods you can reply with to this one
 
     IS_SIZE_STATIC = True     # this means that argument part has always the same length
     IS_CONTENT_STATIC = True  # this means that argument part has always the same content
     STATIC_CONTENT = b'\x00\x00\x00\x04\x5A\x0B\xCE'  # spans LENGTH, CLASS ID, METHOD ID, ....., FRAME_END
-    RESPONSE_TO = TxSelect # this is sent in response to tx.select
 
     def __init__(self):
         """
@@ -3248,3 +3243,90 @@ CLASS_ID_TO_CONTENT_PROPERTY_LIST = {
     60: BasicContentPropertyList,
 }
 
+# Methods that are sent as replies to other methods, ie. ConnectionOpenOk: ConnectionOpen
+# if a method is NOT a reply, it will not be in this dict
+# a method may be a reply for AT MOST one method
+REPLY_REASONS_FOR = {
+    BasicGetEmpty: BasicGet,
+    BasicGetOk: BasicGet,
+    ExchangeDeleteOk: ExchangeDelete,
+    TxSelectOk: TxSelect,
+    QueueBindOk: QueueBind,
+    BasicConsumeOk: BasicConsume,
+    BasicCancelOk: BasicCancel,
+    TxRollbackOk: TxRollback,
+    ChannelOpenOk: ChannelOpen,
+    QueueDeleteOk: QueueDelete,
+    ChannelCloseOk: ChannelClose,
+    BasicQosOk: BasicQos,
+    ConnectionStartOk: ConnectionStart,
+    QueueUnbindOk: QueueUnbind,
+    TxCommitOk: TxCommit,
+    QueuePurgeOk: QueuePurge,
+    QueueDeclareOk: QueueDeclare,
+    ExchangeDeclareOk: ExchangeDeclare,
+    ConnectionTuneOk: ConnectionTune,
+    ConnectionSecureOk: ConnectionSecure,
+    ConnectionOpenOk: ConnectionOpen,
+    ChannelFlowOk: ChannelFlow,
+    ConnectionCloseOk: ConnectionClose,
+}
+
+# Methods that are replies for other, ie. ConnectionOpenOk: ConnectionOpen
+# a method may be a reply for ONE or NONE other methods
+# if a method has no replies, it will have an empty list as value here
+REPLIES_FOR= {
+    BasicGetEmpty: [],
+    BasicRecoverOk: [],
+    BasicReturn: [],
+    QueueDeclare: [QueueDeclareOk],
+    BasicGetOk: [],
+    ConnectionSecure: [ConnectionSecureOk],
+    ExchangeDeleteOk: [],
+    TxRollback: [TxRollbackOk],
+    TxSelectOk: [],
+    QueueBindOk: [],
+    ChannelFlow: [ChannelFlowOk],
+    BasicConsumeOk: [],
+    BasicRecover: [],
+    BasicCancelOk: [],
+    BasicGet: [BasicGetOk, BasicGetEmpty],
+    TxRollbackOk: [],
+    BasicAck: [],
+    ExchangeDelete: [ExchangeDeleteOk],
+    BasicConsume: [BasicConsumeOk],
+    ConnectionClose: [ConnectionCloseOk],
+    ChannelOpenOk: [],
+    QueueDeleteOk: [],
+    QueueBind: [QueueBindOk],
+    ConnectionStart: [ConnectionStartOk],
+    BasicQos: [BasicQosOk],
+    QueueUnbind: [QueueUnbindOk],
+    BasicQosOk: [],
+    BasicReject: [],
+    ChannelCloseOk: [],
+    ExchangeDeclare: [ExchangeDeclareOk],
+    BasicPublish: [],
+    ConnectionTune: [ConnectionTuneOk],
+    ConnectionStartOk: [],
+    QueueUnbindOk: [],
+    QueueDelete: [QueueDeleteOk],
+    ConnectionCloseOk: [],
+    QueuePurge: [QueuePurgeOk],
+    ChannelOpen: [ChannelOpenOk],
+    ChannelClose: [ChannelCloseOk],
+    QueuePurgeOk: [],
+    QueueDeclareOk: [],
+    BasicCancel: [BasicCancelOk],
+    ExchangeDeclareOk: [],
+    TxCommitOk: [],
+    ConnectionTuneOk: [],
+    ConnectionSecureOk: [],
+    ConnectionOpenOk: [],
+    ChannelFlowOk: [],
+    BasicRecoverAsync: [],
+    TxSelect: [TxSelectOk],
+    BasicDeliver: [],
+    TxCommit: [TxCommitOk],
+    ConnectionOpen: [ConnectionOpenOk],
+}
diff --git a/coolamqp/framing/frames.py b/coolamqp/framing/frames.py
index dad0c7dc06d39dd105dc65135a7c7a2fd10740d5..3f8e9bbca52d232ca88f7656ea4413477dc59233 100644
--- a/coolamqp/framing/frames.py
+++ b/coolamqp/framing/frames.py
@@ -52,8 +52,8 @@ class AMQPHeaderFrame(AMQPFrame):
         :param class_id: class ID
         :param weight: weight (lol wut?)
         :param body_size: size of the body to follow
-        :param property_flags:
-        :param property_list:
+        :param property_flags: binary
+        :param property_list: a list of properties
         """
         AMQPFrame.__init__(self, channel)
         self.class_id = class_id
@@ -64,7 +64,9 @@ class AMQPHeaderFrame(AMQPFrame):
 
     def write_to(self, buf):
         AMQPFrame.write_to(self, buf)
-        buf.write(struct.pack('!HHQH'))
+        buf.write(struct.pack('!HHQ', self.class_id, 0, self.body_size))
+        buf.write(self.property_flags)
+
 
     @staticmethod
     def unserialize(channel, payload_as_buffer):
diff --git a/setup.py b/setup.py
index 4b387b77bd470ba383663fd152dad00d7bb927f1..94c0c3c419fdaedf1c032fc45d47242864dfd47b 100644
--- a/setup.py
+++ b/setup.py
@@ -2,6 +2,7 @@
 # coding=UTF-8
 from setuptools import setup
 
+
 setup(name='CoolAMQP',
       version='0.12',
       description='AMQP client with sane reconnects',
diff --git a/tests/test_framing/__init__.py b/tests/test_framing/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..9f2b35b38d89264ee25685611d0a65a192e165f6
--- /dev/null
+++ b/tests/test_framing/__init__.py
@@ -0,0 +1,2 @@
+# coding=UTF-8
+from __future__ import absolute_import, division, print_function
diff --git a/tests/test_framing/test_definitions/__init__.py b/tests/test_framing/test_definitions/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..9f2b35b38d89264ee25685611d0a65a192e165f6
--- /dev/null
+++ b/tests/test_framing/test_definitions/__init__.py
@@ -0,0 +1,2 @@
+# coding=UTF-8
+from __future__ import absolute_import, division, print_function
diff --git a/tests/test_framing/test_definitions/test_cpl.py b/tests/test_framing/test_definitions/test_cpl.py
new file mode 100644
index 0000000000000000000000000000000000000000..03b8e9f12830f200aa25a6cc9823acb856ee4acf
--- /dev/null
+++ b/tests/test_framing/test_definitions/test_cpl.py
@@ -0,0 +1,32 @@
+# coding=UTF-8
+from __future__ import absolute_import, division, print_function
+import unittest
+import io
+
+
+from coolamqp.framing.definitions import BasicContentPropertyList
+
+
+class TestBasicContentPropertyList(unittest.TestCase):
+    def test_bcpl1(self):
+        bcpl = BasicContentPropertyList(content_type='text/plain', content_encoding='utf8')
+
+        self.assertEquals(bcpl.content_type, 'text/plain')
+        self.assertEquals(bcpl.content_encoding, 'utf8')
+
+        buf = io.BytesIO()
+        bcpl.write_to(buf)
+
+        ser = buf.getvalue()
+        self.assertEquals(ser, '\xC0\x00' + chr(len('text/plain')) + b'text/plain\x04utf8')
+
+    def test_bcpl2(self):
+        bcpl = BasicContentPropertyList(content_type='text/plain')
+
+        self.assertEquals(bcpl.content_type, 'text/plain')
+
+        buf = io.BytesIO()
+        bcpl.write_to(buf)
+
+        ser = buf.getvalue()
+        self.assertEquals(ser, '\x80\x00' + chr(len('text/plain')) + b'text/plain')