diff --git a/c_gen/c_code_gen.py b/c_gen/c_code_gen.py
new file mode 100644
index 0000000..0a10715
--- /dev/null
+++ b/c_gen/c_code_gen.py
@@ -0,0 +1,3616 @@
+# Copyright 2013, Big Switch Networks, Inc.
+#
+# LoxiGen is licensed under the Eclipse Public License, version 1.0 (EPL), with
+# the following special exception:
+#
+# LOXI Exception
+#
+# As a special exception to the terms of the EPL, you may distribute libraries
+# generated by LoxiGen (LoxiGen Libraries) under the terms of your choice, provided
+# that copyright and licensing notices generated by LoxiGen are not altered or removed
+# from the LoxiGen Libraries and the notice provided below is (i) included in
+# the LoxiGen Libraries, if distributed in source code form and (ii) included in any
+# documentation for the LoxiGen Libraries, if distributed in binary form.
+#
+# Notice: "Copyright 2013, Big Switch Networks, Inc. This library was generated by the LoxiGen Compiler."
+#
+# You may not use this file except in compliance with the EPL or LOXI Exception. You may obtain
+# a copy of the EPL at:
+#
+# http://www.eclipse.org/legal/epl-v10.html
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# EPL for the specific language governing permissions and limitations
+# under the EPL.
+
+"""
+@file code_gen.py
+Code generation functions for LOCI
+"""
+
+import sys
+import of_g
+import c_match
+from generic_utils import *
+import c_gen.c_type_maps as c_type_maps
+import loxi_front_end.type_maps as type_maps
+import loxi_front_end.flags as flags
+import loxi_utils.loxi_utils as loxi_utils
+import loxi_front_end.identifiers as identifiers
+
+# 'property' is for queues. Could be trouble
+
+
+################################################################
+#
+# Misc helper functions
+#
+################################################################
+
+def h_file_to_define(name):
+    """
+    Convert a .h file name to the define used for the header
+    """
+    h_name = name[:-2].upper()
+    h_name = "_" + h_name + "_H_"
+    return h_name
+
+def enum_name(cls):
+    """
+    Return the name used for an enum identifier for the given class
+    @param cls The class name
+    """
+    return loxi_utils.enum_name(cls)
+
+def member_returns_val(cls, m_name):
+    """
+    Should get accessor return a value rather than void
+    @param cls The class name
+    @param m_name The member name
+    @return True if of_g config and the specific member allow a 
+    return value.  Otherwise False
+    """
+    m_type = of_g.unified[cls]["union"][m_name]["m_type"]
+    return (config_check("get_returns") =="value" and 
+            m_type in of_g.of_scalar_types)
+
+# TODO serialize match outside accessor?
+def accessor_return_type(a_type, m_type):
+    if loxi_utils.accessor_returns_error(a_type, m_type):
+        return "int WARN_UNUSED_RESULT"
+    else:
+        return "void"
+
+def accessor_return_success(a_type, m_type):
+    if loxi_utils.accessor_returns_error(a_type, m_type):
+        return "OF_ERROR_NONE"
+    else:
+        return ""
+
+################################################################
+#
+# Per-file generators, mapped to jump table below
+#
+################################################################
+
+def base_h_gen(out, name):
+    """
+    Generate code for base header file
+    @param out The file handle to write to
+    @param name The name of the file
+    """
+    common_top_matter(out, name)
+    base_h_content(out)
+    gen_object_enum(out)
+    out.write("""
+/****************************************************************
+ *
+ * Experimenter IDs
+ *
+ ****************************************************************/
+
+""")
+    for name, val in of_g.experimenter_name_to_id.items():
+        out.write("#define OF_EXPERIMENTER_ID_%s 0x%08x\n" %
+                  (name.upper(), val))
+
+    out.write("""
+/****************************************************************
+ *
+ * OpenFlow Match version specific and generic defines
+ *
+ ****************************************************************/
+""")
+    c_match.gen_v4_match_compat(out)
+    c_match.gen_match_macros(out)
+    c_match.gen_oxm_defines(out)
+    out.write("\n#endif /* Base header file */\n")
+
+def identifiers_gen(out, filename):
+    """
+    Generate the macros for LOCI identifiers
+    @param out The file handle to write to
+    @param filename The name of the file
+    """
+    common_top_matter(out, filename)
+    out.write("""
+/**
+ * For each identifier from an OpenFlow header file, a Loxi version
+ * of the identifier is generated.  For example, ofp_port_flood becomes
+ * OF_PORT_DEST_FLOOD.  Loxi provides the following macros related to 
+ * OpenFlow identifiers (using OF_IDENT_ as an example below):
+ *     OF_IDENT_BY_VERSION(version) Get the value for the specific version
+ *     OF_IDENT_SUPPORTED(version) Boolean: Is OF_IDENT defined for version
+ *     OF_IDENT The common value across all versions if defined
+ *     OF_IDENT_GENERIC A unique value across all OF identifiers
+ *
+ * For identifiers marked as flags, the following are also defined
+ *     OF_IDENT_SET(flags, version)
+ *     OF_IDENT_CLEAR(flags, version)
+ *     OF_IDENT_TEST(flags, version)
+ *
+ * Notes:
+ *
+ *     OF_IDENT_BY_VERSION(version) returns an undefined value
+ * if the passed version does not define OF_IDENT.  It does not generate an
+ * error, nor record anything to the log file.  If the value is the same
+ * across all defined versions, the version is ignored.
+ *
+ *     OF_IDENT is only defined if the value is the same across all
+ * target LOXI versions FOR WHICH IT IS DEFINED.  No error checking is
+ * done.  This allows code to be written without requiring the version
+ * to be known or referenced when it doesn't matter.  It does mean
+ * that when porting to a new version of OpenFlow, compile errors may
+ * occur.  However, this is an indication that the existing code must
+ * be updated to account for a change in the semantics with the newly
+ * supported OpenFlow version.
+ *
+ * @fixme Currently we do not handle multi-bit flags or field values; for
+ * example, OF_TABLE_CONFIG_TABLE_MISS_CONTROLLER is the meaning for
+ * a zero value in the bits indicated by OF_TABLE_CONFIG_TABLE_MISS_MASK.
+ *
+ * @fixme Need to decide (or make a code gen option) on the requirement
+ * for defining OF_IDENT:  Is it that all target versions define it and
+ * the agree?  Or only that the versions which define it agree?
+ */
+""")
+
+    # Build value-by-version parameters and c_code
+    if len(of_g.target_version_list) > 1: # Supporting more than one version
+        vbv_params = []
+        vbv_code = ""
+        first = True
+        for version in of_g.target_version_list:
+            vbv_params.append("value_%s" % of_g.short_version_names[version])
+            if not first:
+                vbv_code += "\\\n     "
+            else:
+                first = False
+            last_value = "value_%s" % of_g.short_version_names[version]
+            vbv_code += "((version) == %s) ? (%s) : " % \
+                (of_g.of_version_wire2name[version], last_value)
+        # @todo Using last value, can optimize out last ?
+        vbv_code += "(%s)" % last_value
+
+    out.write("""
+/**
+ * @brief True for the special case of all versions supported
+ */
+#define OF_IDENT_IN_ALL_VERSIONS 1 /* Indicates identifier in all versions */
+
+/**
+ * @brief General macro to map version to value where values given as params
+ *
+ * If unknown version is passed, use the latest version's value
+ */
+#define OF_VALUE_BY_VERSION(version, %s) \\
+    (%s)
+
+/**
+ * @brief Generic set a flag
+ */
+#define OF_FLAG_SET(flags, mask) (flags) = (flags) | (mask)
+
+/**
+ * @brief Generic test if a flag is set
+ */
+#define OF_FLAG_CLEAR(flags, mask) (flags) = (flags) & ~(mask)
+
+/**
+ * @brief Generic test if a flag is set
+ */
+#define OF_FLAG_TEST(flags, mask) ((flags) & (mask) ? 1 : 0)
+
+/**
+ * @brief Set a flag where the value is an enum indication of bit shift
+ */
+#define OF_FLAG_ENUM_SET(flags, e_val) OF_FLAG_SET(flags, 1 << (e_val))
+
+/**
+ * @brief Clear a flag where the value is an enum indication of bit shift
+ */
+#define OF_FLAG_ENUM_CLEAR(flags, e_val) OF_FLAG_CLEAR(flags, 1 << (e_val))
+
+/**
+ * @brief Test a flag where the value is an enum indication of bit shift
+ */
+#define OF_FLAG_ENUM_TEST(flags, e_val) OF_FLAG_TEST(flags, 1 << (e_val))
+""" % (", ".join(vbv_params), vbv_code))
+
+    # For each group of identifiers, bunch ident defns
+    count = 1
+    keys = of_g.identifiers_by_group.keys()
+    keys.sort()
+    for group in keys:
+        idents = of_g.identifiers_by_group[group]
+        idents.sort()
+        out.write("""
+/****************************************************************
+ * Identifiers from %s 
+ *****************************************************************/
+""" % group)
+        for ident in idents:
+            info = of_g.identifiers[ident]
+
+            keys = info["values_by_version"].keys()
+            keys.sort()
+
+            out.write("""
+/*
+ * Defines for %(ident)s
+ * Original name %(ofp_name)s
+ */
+""" % dict(ident=ident, ofp_name=info["ofp_name"]))
+
+            # Generate supported versions macro
+            if len(keys) == len(of_g.target_version_list): # Defined for all
+                out.write("""\
+#define %(ident)s_SUPPORTED(version) OF_IDENT_IN_ALL_VERSIONS
+""" % dict(ident=ident))
+            else: # Undefined for some version
+                sup_list = []
+                for version in keys:
+                    sup_list.append("((version) == %s)" %
+                                    of_g.of_version_wire2name[version])
+                out.write("""\
+#define %(ident)s_SUPPORTED(version)      \\
+    (%(sup_str)s)
+""" % dict(ident=ident, sup_str=" || \\\n     ".join(sup_list)))
+
+            # Generate value macro
+            if identifiers.defined_versions_agree(of_g.identifiers,
+                                                  of_g.target_version_list,
+                                                  ident):
+                out.write("""\
+#define %(ident)s (%(value)s)
+#define %(ident)s_BY_VERSION(version) (%(value)s)
+""" % dict(ident=ident,value=info["common_value"]))
+            else: # Values differ between versions
+                # Generate version check and value by version
+                val_list = []
+                # Order of params matters
+                for version in of_g.target_version_list:
+                    if version in info["values_by_version"]:
+                        value = info["values_by_version"][version]
+                    else:
+                        value = identifiers.UNDEFINED_IDENT_VALUE
+                    val_list.append("%s" % value)
+                out.write("""\
+#define %(ident)s_BY_VERSION(version)     \\
+    OF_VALUE_BY_VERSION(version, %(val_str)s)
+""" % dict(ident=ident, val_str=", ".join(val_list)))
+            if flags.ident_is_flag(ident):
+                log("Treating %s as a flag" % ident)
+                out.write("""
+#define %(ident)s_SET(flags, version)     \\
+    OF_FLAG_SET(flags, %(ident)s_BY_VERSION(version))
+#define %(ident)s_TEST(flags, version)    \\
+    OF_FLAG_TEST(flags, %(ident)s_BY_VERSION(version))
+#define %(ident)s_CLEAR(flags, version)   \\
+    OF_FLAG_CLEAR(flags, %(ident)s_BY_VERSION(version))
+""" % dict(ident=ident))
+
+            out.write("#define %(ident)s_GENERIC %(count)d\n"
+                      % dict(ident=ident, count=count))
+            count += 1 # This count should probably be promoted higher
+
+    log("Generated %d identifiers" % (count - 1))
+    out.write("\n#endif /* Loci identifiers header file */\n")
+
+def base_h_external(out, filename):
+    """
+    Copy contents of external file to base header
+
+    The contents of the filename are copied literally into the
+    out file handler.  This allows openflow common defines to
+    be entered into the LoxiGen code base.  The content of this
+    code must depend only on standard C headers.
+    """
+    infile = open(filename, "r")
+    contents = infile.read()
+    out.write(contents)
+    infile.close()
+
+def match_h_gen(out, name):
+    """
+    Generate code for
+    @param out The file handle to write to
+    @param name The name of the file
+    """
+    c_match.match_h_top_matter(out, name)
+    c_match.gen_incompat_members(out)
+    c_match.gen_match_struct(out)
+    c_match.gen_match_comp(out)
+#    c_match.gen_match_accessors(out)
+    out.write("\n#endif /* Match header file */\n")
+
+def top_h_gen(out, name):
+    """
+    Generate code for
+    @param out The file handle to write to
+    @param name The name of the file
+    """
+    external_h_top_matter(out, name)
+    out.write("""
+
+typedef enum loci_log_level {
+    LOCI_LOG_LEVEL_TRACE,
+    LOCI_LOG_LEVEL_VERBOSE,
+    LOCI_LOG_LEVEL_INFO,
+    LOCI_LOG_LEVEL_WARN,
+    LOCI_LOG_LEVEL_ERROR,
+    LOCI_LOG_LEVEL_MSG
+} loci_log_level_t;
+
+/**
+ * @brief Output a log message.
+ * @param level The log level.
+ * @param fname The function name.
+ * @param file The file name.
+ * @param line The line number.
+ * @param format The message format string.
+ */
+typedef int (*loci_logger_f)(loci_log_level_t level,
+                             const char *fname, const char *file, int line,
+                             const char *format, ...);
+
+/*
+ * This variable should be set by the user of the library to redirect logs to
+ * their log infrastructure. The default drops all logs.
+ */
+extern loci_logger_f loci_logger;
+
+/**
+ * Map a generic object to the underlying wire buffer
+ *
+ * Treat as private
+ */
+#define OF_OBJECT_TO_MESSAGE(obj) \\
+    ((of_message_t)(WBUF_BUF((obj)->wire_object.wbuf)))
+
+/**
+ * Macro for the fixed length part of an object
+ *
+ * @param obj The object whose extended length is being calculated
+ * @returns length in bytes of non-variable part of the object
+ */
+#define OF_OBJECT_FIXED_LENGTH(obj) \\
+    (of_object_fixed_len[(obj)->version][(obj)->object_id])
+
+/**
+ * Return the length of the object beyond its fixed length
+ *
+ * @param obj The object whose extended length is being calculated
+ * @returns length in bytes of non-variable part of the object
+ *
+ * Most variable length fields are alone at the end of a structure.
+ * Their length is a simple calculation, just the total length of
+ * the parent minus the length of the non-variable part of the
+ * parent's class type.
+ */
+
+#define OF_OBJECT_VARIABLE_LENGTH(obj) \\
+    ((obj)->length - OF_OBJECT_FIXED_LENGTH(obj))
+
+/* FIXME: Where do these go? */
+/* Low level maps btwn wire version + type and object ids */
+extern int of_message_is_stats_request(int type, int w_ver);
+extern int of_message_is_stats_reply(int type, int w_ver);
+extern int of_message_stats_reply_to_object_id(int stats_type, int w_ver);
+extern int of_message_stats_request_to_object_id(int stats_type, int w_ver);
+extern int of_message_type_to_object_id(int type, int w_ver);
+
+extern int of_wire_buffer_of_match_get(of_object_t *obj, int offset,
+                                    of_match_t *match);
+extern int of_wire_buffer_of_match_set(of_object_t *obj, int offset,
+                                    of_match_t *match, int cur_len);
+extern void of_extension_object_id_set(of_object_t *obj, of_object_id_t id);
+""")
+
+    # gen_base_types(out)
+
+    gen_struct_typedefs(out)
+    gen_acc_pointer_typedefs(out)
+    gen_new_function_declarations(out)
+    if config_check("gen_unified_fns"):
+        gen_accessor_declarations(out)
+
+    gen_common_struct_definitions(out)
+    gen_flow_add_setup_function_declarations(out)
+    if config_check("gen_fn_ptrs"): # Otherwise, all classes are from generic cls
+        gen_struct_definitions(out)
+    gen_generic_union(out)
+    gen_generics(out)
+    gen_top_static_functions(out)
+    out.write("""
+/****************************************************************
+ *
+ * Declarations of maps between on-the-wire type values and LOCI identifiers
+ *
+ ****************************************************************/
+""")
+    c_type_maps.gen_type_maps_header(out)
+    c_type_maps.gen_type_data_header(out)
+    c_match.gen_declarations(out)
+    # @fixme Move debug stuff to own fn
+    out.write("""
+/**
+ * Macro to check consistency of length for top level objects
+ *
+ * If the object has no parent then its length should match the
+ * underlying wire buffer's current bytes.
+ */
+#define OF_LENGTH_CHECK_ASSERT(obj) \\
+    ASSERT(((obj)->parent != NULL) || \\
+     ((obj)->wire_object.wbuf == NULL) || \\
+     (WBUF_CURRENT_BYTES((obj)->wire_object.wbuf) == (obj)->length))
+
+#define OF_DEBUG_DUMP
+#if defined(OF_DEBUG_DUMP)
+extern void dump_match(of_match_t *match);
+#endif /* OF_DEBUG_DUMP */
+""")
+
+    out.write("\n#endif /* Top header file */\n")
+
+def match_c_gen(out, name):
+    """
+    Generate code for
+    @param out The file handle to write to
+    @param name The name of the file
+    """
+    c_match.match_c_top_matter(out, name)
+    c_match.gen_match_conversions(out)
+    c_match.gen_serialize(out)
+    c_match.gen_deserialize(out)
+
+def gen_len_offset_macros(out):
+    """
+    Special case length and offset calculations put directly into
+    loci.c as they are private.
+    """
+
+    out.write("""
+/****************************************************************
+ * Special case macros for calculating variable lengths and offsets
+ ****************************************************************/
+
+/**
+ * Get a u16 directly from an offset in an object's wire buffer
+ * @param obj An of_object_t object
+ * @param offset Base offset of the uint16 relative to the object
+ *
+ */
+
+static inline int
+of_object_u16_get(of_object_t *obj, int offset) {
+    uint16_t val16;
+
+    of_wire_buffer_u16_get(obj->wire_object.wbuf,
+        obj->wire_object.obj_offset + offset, &val16);
+
+    return (int)val16;
+}
+
+/**
+ * Set a u16 directly at an offset in an object's wire buffer
+ * @param obj An of_object_t object
+ * @param offset Base offset of the uint16 relative to the object
+ * @param val The value to store
+ *
+ */
+
+static inline void
+of_object_u16_set(of_object_t *obj, int offset, int value) {
+    uint16_t val16;
+
+    val16 = (uint16_t)value;
+    of_wire_buffer_u16_set(obj->wire_object.wbuf,
+        obj->wire_object.obj_offset + offset, val16);
+}
+
+/**
+ * Get length of an object with a TLV header with uint16_t
+ * @param obj An object with a match member
+ * @param offset The wire offset of the start of the object
+ *
+ * The length field follows the type field.
+ */
+
+#define _TLV16_LEN(obj, offset) \\
+    (of_object_u16_get((of_object_t *)(obj), (offset) + 2))
+
+/**
+ * Get length of an object that is the "rest" of the object
+ * @param obj An object with a match member
+ * @param offset The wire offset of the start of the object
+ *
+ */
+
+#define _END_LEN(obj, offset) ((obj)->length - (offset))
+
+/**
+ * Get length of the action list object in a packet_out object
+ * @param obj An object of type of_packet_out
+ *
+ * The length field is just before the end of the fixed length
+ * part of the object in all versions.
+ */
+
+#define _PACKET_OUT_ACTION_LEN(obj) \\
+    (of_object_u16_get((of_object_t *)(obj), \\
+     of_object_fixed_len[(obj)->version][OF_PACKET_OUT] - 2))
+
+/**
+ * Set length of the action list object in a packet_out object
+ * @param obj An object of type of_packet_out
+ *
+ * The length field is just before the end of the fixed length
+ * part of the object in all versions.
+ */
+
+#define _PACKET_OUT_ACTION_LEN_SET(obj, len) \\
+    (of_object_u16_set((of_object_t *)(obj), \\
+     of_object_fixed_len[(obj)->version][OF_PACKET_OUT] - 2, len))
+
+/*
+ * Match structs in 1.2 come at the end of the fixed length part
+ * of structures.  They add 8 bytes to the minimal length of the
+ * message, but are also variable length.  This means that the 
+ * type/length offsets are 8 bytes back from the end of the fixed 
+ * length part of the object.  The right way to handle this is to 
+ * expose the offset of the match member more explicitly.  For now, 
+ * we make the calculation as described here.
+ */
+
+/* 1.2 min length of match is 8 bytes */
+#define _MATCH_MIN_LENGTH_V3 8
+
+/**
+ * The offset of a 1.2 match object relative to fixed length of obj
+ */
+#define _MATCH_OFFSET_V3(fixed_obj_len) \\
+    ((fixed_obj_len) - _MATCH_MIN_LENGTH_V3)
+
+/**
+ * The "extra" length beyond the minimal 8 bytes of a match struct
+ * in an object
+ */
+#define _MATCH_EXTRA_LENGTH_V3(obj, fixed_obj_len) \\
+    (OF_MATCH_BYTES(_TLV16_LEN(obj, _MATCH_OFFSET_V3(fixed_obj_len))) - \\
+     _MATCH_MIN_LENGTH_V3)
+
+/**
+ * The offset of an object following a match object for 1.2
+ */
+#define _OFFSET_FOLLOWING_MATCH_V3(obj, fixed_obj_len) \\
+    ((fixed_obj_len) + _MATCH_EXTRA_LENGTH_V3(obj, fixed_obj_len))
+
+/**
+ * Get length of a match object from its wire representation
+ * @param obj An object with a match member
+ * @param match_offset The wire offset of the match object.
+ *
+ * See above; for 1.2, 
+ * The match length is raw bytes but the actual space it takes
+ * up is padded for alignment to 64-bits
+ */
+#define _WIRE_MATCH_LEN(obj, match_offset) \\
+    (((obj)->version == OF_VERSION_1_0) ? %(match1)d : \\
+     (((obj)->version == OF_VERSION_1_1) ? %(match2)d : \\
+      _TLV16_LEN(obj, match_offset)))
+
+#define _WIRE_LEN_MIN 4
+
+/*
+ * Wrapper function for match len.  There are cases where the wire buffer
+ * has not been set with the proper minimum length.  In this case, the
+ * wire match len is interpretted as its minimum length, 4 bytes.
+ */
+
+static inline int
+wire_match_len(of_object_t *obj, int match_offset) {
+    int len;
+
+    len = _WIRE_MATCH_LEN(obj, match_offset);
+
+    return (len == 0) ? _WIRE_LEN_MIN : len;
+}
+
+#define _WIRE_MATCH_PADDED_LEN(obj, match_offset) \\
+    OF_MATCH_BYTES(wire_match_len((of_object_t *)(obj), (match_offset)))
+
+/**
+ * Macro to calculate variable offset of instructions member in flow mod
+ * @param obj An object of some type of flow modify/add/delete
+ *
+ * Get length of preceding match object and add to fixed length
+ * Applies only to version 1.2
+ */
+
+#define _FLOW_MOD_INSTRUCTIONS_OFFSET(obj) \\
+    _OFFSET_FOLLOWING_MATCH_V3(obj, %(flow_mod)d)
+
+/* The different flavors of flow mod all use the above */
+#define _FLOW_ADD_INSTRUCTIONS_OFFSET(obj) \\
+    _FLOW_MOD_INSTRUCTIONS_OFFSET(obj)
+#define _FLOW_MODIFY_INSTRUCTIONS_OFFSET(obj) \\
+    _FLOW_MOD_INSTRUCTIONS_OFFSET(obj)
+#define _FLOW_MODIFY_STRICT_INSTRUCTIONS_OFFSET(obj) \\
+    _FLOW_MOD_INSTRUCTIONS_OFFSET(obj)
+#define _FLOW_DELETE_INSTRUCTIONS_OFFSET(obj) \\
+    _FLOW_MOD_INSTRUCTIONS_OFFSET(obj)
+#define _FLOW_DELETE_STRICT_INSTRUCTIONS_OFFSET(obj) \\
+    _FLOW_MOD_INSTRUCTIONS_OFFSET(obj)
+
+/**
+ * Macro to calculate variable offset of instructions member in flow stats
+ * @param obj An object of type of_flow_mod_t
+ *
+ * Get length of preceding match object and add to fixed length
+ * Applies only to version 1.2 and 1.3
+ */
+
+#define _FLOW_STATS_ENTRY_INSTRUCTIONS_OFFSET(obj) \\
+    _OFFSET_FOLLOWING_MATCH_V3(obj, %(flow_stats)d)
+
+/**
+ * Macro to calculate variable offset of data (packet) member in packet_in
+ * @param obj An object of type of_packet_in_t
+ *
+ * Get length of preceding match object and add to fixed length
+ * Applies only to version 1.2 and 1.3
+ */
+
+#define _PACKET_IN_DATA_OFFSET(obj) \\
+    _OFFSET_FOLLOWING_MATCH_V3((obj), (obj)->version == OF_VERSION_1_2 ? \
+%(packet_in)d : %(packet_in_1_3)d)
+
+/**
+ * Macro to calculate variable offset of data (packet) member in packet_out
+ * @param obj An object of type of_packet_out_t
+ *
+ * Find the length in the actions_len variable and add to the fixed len
+ * Applies only to version 1.2 and 1.3
+ */
+
+#define _PACKET_OUT_DATA_OFFSET(obj) (_PACKET_OUT_ACTION_LEN(obj) + \\
+     of_object_fixed_len[(obj)->version][OF_PACKET_OUT])
+
+/**
+ * Macro to map port numbers that changed across versions
+ * @param port The port_no_t variable holding the value
+ * @param ver The OpenFlow version from which the value was extracted
+ */
+#define OF_PORT_NO_VALUE_CHECK(port, ver) \\
+    if (((ver) == OF_VERSION_1_0) && ((port) > 0xff00)) (port) += 0xffff0000
+
+""" % dict(flow_mod=of_g.base_length[("of_flow_modify",of_g.VERSION_1_2)],
+           packet_in=of_g.base_length[("of_packet_in",of_g.VERSION_1_2)],
+           packet_in_1_3=of_g.base_length[("of_packet_in",of_g.VERSION_1_3)],
+           flow_stats=of_g.base_length[("of_flow_stats_entry",
+                                        of_g.VERSION_1_2)],
+           match1=of_g.base_length[("of_match_v1",of_g.VERSION_1_0)],
+           match2=of_g.base_length[("of_match_v2",of_g.VERSION_1_1)]))
+
+def gen_obj_id_macros(out):
+    """
+    Flow modify (add, delete) messages (and maybe others) use ID checks allowing
+    inheritance to use common accessor functions.
+    """
+    out.write("""
+/**
+ * Macro to detect if an object ID falls in the "flow mod" family of objects
+ * This includes add, modify, modify_strict, delete and delete_strict
+ */
+#define IS_FLOW_MOD_SUBTYPE(object_id)                 \\
+    (((object_id) == OF_FLOW_MODIFY) ||                \\
+     ((object_id) == OF_FLOW_MODIFY_STRICT) ||         \\
+     ((object_id) == OF_FLOW_DELETE) ||                \\
+     ((object_id) == OF_FLOW_DELETE_STRICT) ||         \\
+     ((object_id) == OF_FLOW_ADD))
+""")
+
+
+def top_c_gen(out, name):
+    """
+    Generate code for
+    @param out The file handle to write to
+    @param name The name of the file
+    """
+    common_top_matter(out, name)
+    # Generic C code that needs to go into loci.c can go here.
+    out.write("""
+/****************************************************************
+ *
+ * This file is divided into the following sections.
+ *
+ * Instantiate strings such as object names
+ * Special case macros for low level object access
+ * Per-class, per-member accessor definitions
+ * Per-class new/init function definitions
+ * Per-class new/init pointer instantiations
+ * Instantiate "set map" for pointer set fns
+ *
+ ****************************************************************/
+
+#include <loci/loci.h>
+#include <loci/of_object.h>
+#include "loci_log.h"
+
+""")
+    gen_object_enum_str(out)
+    gen_len_offset_macros(out)
+    gen_obj_id_macros(out)
+    if config_check("gen_unified_fns"):
+        gen_accessor_definitions(out)
+    gen_new_function_definitions(out)
+    gen_init_map(out)
+    out.write("\n/* This code should be broken out to a different file */\n")
+    gen_setup_from_add_fns(out)
+
+def type_data_c_gen(out, name):
+    common_top_matter(out, name)
+    c_type_maps.gen_type_maps(out)
+    c_type_maps.gen_length_array(out)
+
+################################################################
+# Top Matter
+################################################################
+
+def common_top_matter(out, name):
+    loxi_utils.gen_c_copy_license(out)
+    out.write("""\
+/****************************************************************
+ * File: %s
+ *
+ * DO NOT EDIT
+ *
+ * This file is automatically generated
+ *
+ ****************************************************************/
+
+""" % name)
+
+    if name[-2:] == ".h":
+        out.write("""
+#if !defined(%(h)s)
+#define %(h)s
+
+""" % dict(h=h_file_to_define(name)))
+
+def base_h_content(out):
+    """
+    Generate base header file content
+
+    @param out The output file object
+    """
+
+    # @fixme Supported version should be generated based on input to LoxiGen
+
+    out.write("""
+/*
+ * Base OpenFlow definitions.  These depend only on standard C headers
+ */
+#include <string.h>
+#include <stdint.h>
+
+/* g++ requires this to pick up PRI, etc.
+ * See  http://gcc.gnu.org/ml/gcc-help/2006-10/msg00223.html
+ */
+#if !defined(__STDC_FORMAT_MACROS)
+#define __STDC_FORMAT_MACROS
+#endif
+#include <inttypes.h>
+
+#include <stdlib.h>
+#include <assert.h>
+#include <loci/loci_idents.h>
+
+/**
+ * Macro to enable debugging for LOCI.
+ *
+ * This enables debug output to stdout.
+ */
+#define OF_DEBUG_ENABLE
+
+#if defined(OF_DEBUG_ENABLE)
+#include <stdio.h> /* Currently for debugging */
+#define FIXME(str) do {                 \\
+        fprintf(stderr, "%s\\n", str);  \\
+        exit(1);                        \\
+    } while (0)
+#define debug printf
+#else
+#define FIXME(str)
+#define debug(str, ...)
+#endif /* OF_DEBUG_ENABLE */
+
+/**
+ * The type of a function used by the LOCI dump/show functions to
+ * output text. Essentially the same signature as fprintf. May
+ * be called many times per invocation of e.g. of_object_show().
+ */
+typedef int (*loci_writer_f)(void *cookie, const char *fmt, ...);
+
+/**
+ * Check if a version is supported
+ */
+#define OF_VERSION_OKAY(v) ((v) >= OF_VERSION_1_0 && (v) <= OF_VERSION_1_3)
+
+""")
+    gen_version_enum(out)
+    out.write("\n")
+
+    # for c_name in of_g.ofp_constants:
+    #     val = str(of_g.ofp_constants[c_name])
+    #     out.write("#define %s %s\n" % (c_name, val))
+    # out.write("\n")
+
+    out.write("""
+typedef enum of_error_codes_e {
+    OF_ERROR_NONE        = 0,
+    OF_ERROR_RESOURCE    = -1,    /* Could not allocate space */
+    OF_ERROR_PARAM       = -2,    /* Bad parameter */
+    OF_ERROR_VERSION     = -3,    /* Version not supported */
+    OF_ERROR_RANGE       = -4,    /* End of list indication */
+    OF_ERROR_COMPAT      = -5,    /* Incompatible assignment */
+    OF_ERROR_PARSE       = -6,    /* Error in parsing data */
+    OF_ERROR_INIT        = -7,    /* Uninitialized data */
+    OF_ERROR_UNKNOWN     = -8     /* Unknown error */
+} of_error_codes_t;
+
+#define OF_ERROR_STRINGS "none", \\
+    "resource", \\
+    "parameter", \\
+    "version", \\
+    "range", \\
+    "incompatible", \\
+    "parse", \\
+    "init", \\
+    "unknown"
+
+extern const char *of_error_strings[];
+
+/* #define ASSERT(val) assert(val) */
+#define FORCE_FAULT *(volatile int *)0 = 1
+#define ASSERT(val) if (!(val)) \\
+    fprintf(stderr, "\\nASSERT %s. %s:%d\\n", #val, __FILE__, __LINE__), \\
+    FORCE_FAULT
+
+/*
+ * Some LOCI object accessors can fail, and it's easy to forget to check.
+ * On certain compilers we can trigger a warning if the error code
+ * is ignored.
+ */
+#ifndef DISABLE_WARN_UNUSED_RESULT
+#ifdef __GNUC__
+#define WARN_UNUSED_RESULT __attribute__ ((warn_unused_result))
+#else
+#define WARN_UNUSED_RESULT
+#endif
+#else
+#define WARN_UNUSED_RESULT
+#endif
+
+typedef union of_generic_u of_generic_t;
+typedef struct of_object_s of_object_t;
+
+/* Define ipv4 address as uint32 */
+typedef uint32_t of_ipv4_t;
+
+/* Table ID is the OF standard uint8 */
+typedef uint8_t of_table_id_t;
+
+#define OF_MAC_ADDR_BYTES 6
+typedef struct of_mac_addr_s {
+   uint8_t addr[OF_MAC_ADDR_BYTES];
+} of_mac_addr_t;
+
+#define OF_IPV6_BYTES 16
+typedef struct of_ipv6_s {
+   uint8_t addr[OF_IPV6_BYTES];
+} of_ipv6_t;
+
+extern const of_mac_addr_t of_mac_addr_all_ones;
+extern const of_mac_addr_t of_mac_addr_all_zeros;
+
+extern const of_ipv6_t of_ipv6_all_ones;
+extern const of_ipv6_t of_ipv6_all_zeros;
+
+/**
+ * Generic zero and all-ones values of size 16 bytes.
+ *
+ * IPv6 is longest data type we worry about for comparisons
+ */
+#define of_all_zero_value of_ipv6_all_zeros
+#define of_all_ones_value of_ipv6_all_ones
+
+/**
+ * Non-zero/all ones check for arbitrary type of size <= 16 bytes
+ */
+#define OF_VARIABLE_IS_NON_ZERO(_ptr) \\
+    (MEMCMP(&of_all_zero_value, (_ptr), sizeof(*(_ptr))))
+#define OF_VARIABLE_IS_ALL_ONES(_ptr) \\
+    (!MEMCMP(&of_all_ones_value, (_ptr), sizeof(*(_ptr))))
+
+/* The octets object is a struct holding pointer and length */
+typedef struct of_octets_s {
+    uint8_t *data;
+    int bytes;
+} of_octets_t;
+
+/* Macro to convert an octet object to a pointer; currently trivial */
+#define OF_OCTETS_POINTER_GET(octet_ptr) ((octet_ptr)->data)
+#define OF_OCTETS_POINTER_SET(octet_ptr, ptr) (octet_ptr)->data = (ptr)
+#define OF_OCTETS_BYTES_GET(octet_ptr) ((octet_ptr)->bytes)
+#define OF_OCTETS_BYTES_SET(octet_ptr, bytes) (octet_ptr)->bytes = (bytes)
+
+/* Currently these are categorized as scalars */
+typedef char of_port_name_t[OF_MAX_PORT_NAME_LEN];
+typedef char of_table_name_t[OF_MAX_TABLE_NAME_LEN];
+typedef char of_desc_str_t[OF_DESC_STR_LEN];
+typedef char of_serial_num_t[OF_SERIAL_NUM_LEN];
+
+/* These are types which change across versions.  */
+typedef uint32_t of_port_no_t;
+typedef uint16_t of_fm_cmd_t;
+typedef uint64_t of_wc_bmap_t;
+typedef uint64_t of_match_bmap_t;
+
+#define MEMMOVE(dest, src, bytes) memmove(dest, src, bytes)
+#define MEMSET(dest, val, bytes) memset(dest, val, bytes)
+#define MEMCPY(dest, src, bytes) memcpy(dest, src, bytes)
+#define MEMCMP(a, b, bytes) memcmp(a, b, bytes)
+#define MALLOC(bytes) malloc(bytes)
+#define FREE(ptr) free(ptr)
+
+/** Try an operation and return on failure. */
+#define OF_TRY(op) do {                                                      \\
+        int _rv;                                                             \\
+        if ((_rv = (op)) < 0) {                                              \\
+            LOCI_LOG_ERROR("ERROR %d at %s:%d\\n", _rv, __FILE__, __LINE__); \\
+            return _rv;                                                      \\
+        }                                                                    \\
+    } while (0)
+
+/* The extent of an OF match object is determined by its length field, but
+ * aligned to 8 bytes
+ */
+
+#define OF_MATCH_BYTES(length) (((length) + 7) & 0xfff8)
+
+#if __BYTE_ORDER == __BIG_ENDIAN
+#define U16_NTOH(val) (val)
+#define U32_NTOH(val) (val)
+#define U64_NTOH(val) (val)
+#define IPV6_NTOH(dst, src) /* NOTE different syntax; currently no-op */
+#define U16_HTON(val) (val)
+#define U32_HTON(val) (val)
+#define U64_HTON(val) (val)
+#define IPV6_HTON(dst, src) /* NOTE different syntax; currently no-op */
+#else /* Little Endian */
+#define U16_NTOH(val) (((val) >> 8) | ((val) << 8))
+#define U32_NTOH(val) ((((val) & 0xff000000) >> 24) |                   \\
+                       (((val) & 0x00ff0000) >>  8) |                   \\
+                       (((val) & 0x0000ff00) <<  8) |                   \\
+                       (((val) & 0x000000ff) << 24))
+#define U64_NTOH(val) ((((val) & 0xff00000000000000LL) >> 56) |         \\
+                       (((val) & 0x00ff000000000000LL) >> 40) |         \\
+                       (((val) & 0x0000ff0000000000LL) >> 24) |         \\
+                       (((val) & 0x000000ff00000000LL) >>  8) |         \\
+                       (((val) & 0x00000000ff000000LL) <<  8) |         \\
+                       (((val) & 0x0000000000ff0000LL) << 24) |         \\
+                       (((val) & 0x000000000000ff00LL) << 40) |         \\
+                       (((val) & 0x00000000000000ffLL) << 56))
+#define IPV6_NTOH(dst, src) /* NOTE different syntax; currently no-op */
+#define U16_HTON(val) U16_NTOH(val)
+#define U32_HTON(val) U32_NTOH(val)
+#define U64_HTON(val) U64_NTOH(val)
+#define IPV6_HTON(dst, src) /* NOTE different syntax; currently no-op */
+#endif
+
+/****************************************************************
+ *
+ * The following are internal definitions used by the automatically
+ * generated code.  Users should not reference these definitions
+ * as they may change between versions of this code
+ *
+ ****************************************************************/
+
+#define OF_MESSAGE_IN_MATCH_POINTER(obj)                            \\
+    (WIRE_BUF_POINTER(&((obj)->wire_buffer), OF_MESSAGE_IN_MATCH_OFFSET))
+#define OF_MESSAGE_IN_MATCH_LEN(ptr) BUF_U16_GET(&ptr[2])
+#define OF_MESSAGE_IN_DATA_OFFSET(obj) \\
+    (FIXED_LEN + OF_MESSAGE_IN_MATCH_LEN(OF_MESSAGE_IN_MATCH_POINTER(obj)) + 2)
+
+#define OF_MESSAGE_OUT_DATA_OFFSET(obj) \\
+    (FIXED_LEN + of_message_out_actions_len_get(obj))
+
+""")
+
+def external_h_top_matter(out, name):
+    """
+    Generate top matter for external header file
+
+    @param name The name of the output file
+    @param out The output file object
+    """
+    common_top_matter(out, name)
+    out.write("""
+#include <loci/loci_base.h>
+#include <loci/of_message.h>
+#include <loci/of_match.h>
+#include <loci/of_object.h>
+#include <loci/of_wire_buf.h>
+
+/****************************************************************
+ *
+ * This file is divided into the following sections.
+ *
+ * A few object specific macros
+ * Class typedefs (no struct definitions)
+ * Per-data type accessor function typedefs
+ * Per-class new/delete function typedefs
+ * Per-class static delete functions
+ * Per-class, per-member accessor declarations
+ * Per-class structure definitions
+ * Generic union (inheritance) definitions
+ * Pointer set function declarations
+ * Some special case macros
+ *
+ ****************************************************************/
+""")
+
+def gen_top_static_functions(out):
+    out.write("""
+
+#define _MAX_PARENT_ITERATIONS 4
+/**
+ * Iteratively update parent lengths thru hierarchy
+ * @param obj The object whose length is being updated
+ * @param delta The difference between the current and new lengths
+ *
+ * Note that this includes updating the object itself.  It will
+ * iterate thru parents.
+ *
+ * Assumes delta > 0.
+ */
+static inline void
+of_object_parent_length_update(of_object_t *obj, int delta)
+{
+    int count = 0;
+    of_wire_buffer_t *wbuf;  /* For debug asserts only */
+
+    while (obj != NULL) {
+        ASSERT(count++ < _MAX_PARENT_ITERATIONS);
+        obj->length += delta;
+        if (obj->wire_length_set != NULL) {
+            obj->wire_length_set(obj, obj->length);
+        }
+        wbuf = obj->wire_object.wbuf;
+
+        /* Asserts for wire length checking */
+        ASSERT(obj->length + obj->wire_object.obj_offset <=
+               WBUF_CURRENT_BYTES(wbuf));
+        if (obj->parent == NULL) {
+            ASSERT(obj->length + obj->wire_object.obj_offset ==
+                   WBUF_CURRENT_BYTES(wbuf));
+        }
+
+        obj = obj->parent;
+    }
+}
+""")
+
+################################################################
+#
+################################################################
+
+def gen_version_enum(out):
+    """
+    Generate the enumerated type for versions in LoxiGen
+    @param out The file object to which to write the decs
+
+    This just uses the wire versions for now
+    """
+    out.write("""
+/**
+ * Enumeration of OpenFlow versions
+ *
+ * The wire protocol numbers are currently used for values of the corresponding
+ * version identifiers.
+ */
+typedef enum of_version_e {
+    OF_VERSION_UNKNOWN = 0,
+""")
+
+    is_first = True
+    max = 0
+    for v in of_g.wire_ver_map:
+        if is_first:
+            is_first = False
+        else:
+            out.write(",\n")
+        if v > max:
+            max = v
+        out.write("    %s = %d" % (of_g.wire_ver_map[v], v))
+
+    out.write("""
+} of_version_t;
+
+/**
+ * @brief Use this when declaring arrays indexed by wire version
+ */
+#define OF_VERSION_ARRAY_MAX %d
+""" % (max + 1))
+    
+def gen_object_enum(out):
+    """
+    Generate the enumerated type for object identification in LoxiGen
+    @param out The file object to which to write the decs
+    """
+    out.write("""
+
+/**
+ * Enumeration of OpenFlow objects
+ *
+ * We enumerate the OpenFlow objects used internally.  Note that some
+ * message types are determined both by an outer type (message type like
+ * stats_request) and an inner type (port stats).  These are different
+ * messages in ofC.
+ *
+ * These values are for internal use only.  They will change with
+ * different versions of ofC.
+ */
+
+typedef enum of_object_id_e {
+    /* Root object type */
+    OF_OBJECT_INVALID = -1, /* "invalid" return value for mappings */
+    OF_OBJECT = 0, /* Generic, untyped object */
+
+    /* OpenFlow message objects */
+""")
+    last = 0
+    msg_count = 0
+    for cls in of_g.ordered_messages:
+        out.write("    %s = %d,\n" % (enum_name(cls),
+                                   of_g.unified[cls]["object_id"]))
+        msg_count = of_g.unified[cls]["object_id"] + 1
+
+    out.write("\n    /* Non-message objects */\n")
+    for cls in of_g.ordered_non_messages:
+        out.write("    %s = %d,\n" % (enum_name(cls),
+                                   of_g.unified[cls]["object_id"]))
+        last = of_g.unified[cls]["object_id"]
+    out.write("\n    /* List objects */\n")
+    for cls in of_g.ordered_list_objects:
+        out.write("    %s = %d,\n" % (enum_name(cls),
+                                   of_g.unified[cls]["object_id"]))
+        last = of_g.unified[cls]["object_id"]
+
+    out.write("\n    /* Generic stats request/reply types; pseudo objects */\n")
+    for cls in of_g.ordered_pseudo_objects:
+        out.write("    %s = %d,\n" % (enum_name(cls),
+                                   of_g.unified[cls]["object_id"]))
+        last = of_g.unified[cls]["object_id"]
+
+    out.write("""
+    OF_OBJECT_COUNT = %d
+} of_object_id_t;
+
+extern const char *of_object_id_str[];
+
+#define OF_MESSAGE_OBJECT_COUNT %d
+""" % ((last + 1), msg_count))
+
+    # Generate object type range checking for inheritance classes
+
+    # @fixme These should be determined algorithmicly
+    out.write("""
+/*
+ * Macros to check if an object ID is within an inheritance class range
+ */
+""")
+    # Alphabetical order for 'last'
+    last_ids = dict(of_action="OF_ACTION_STRIP_VLAN",
+                    of_oxm="OF_OXM_VLAN_VID_MASKED",
+                    of_instruction="OF_INSTRUCTION_WRITE_METADATA",
+                    of_queue_prop="OF_QUEUE_PROP_MIN_RATE",
+                    of_table_feature_prop="OF_TABLE_FEATURE_PROP_WRITE_SETFIELD_MISS",
+                    # @FIXME add meter_band ?
+                    )
+    for cls, last in last_ids.items():
+        out.write("""
+#define %(enum)s_FIRST_ID      (%(enum)s + 1)
+#define %(enum)s_LAST_ID       %(last)s
+#define %(enum)s_VALID_ID(id) \\
+    ((id) >= %(enum)s_FIRST_ID && \\
+     (id) <= %(enum)s_LAST_ID)
+""" % dict(enum=enum_name(cls), last=last))
+    out.write("""
+/**
+ * Function to check a wire ID
+ * @param object_id The ID to check
+ * @param base_object_id The inheritance parent, if applicable
+ * @returns boolean: If base_object_id is an inheritance class, check if
+ * object_id is valid as a subclass.  Otherwise return 1.
+ *
+ * Note: Could check that object_id == base_object_id in the
+ * second case.
+ */
+static inline int
+of_wire_id_valid(int object_id, int base_object_id) {
+    switch (base_object_id) {
+    case OF_ACTION:
+        return OF_ACTION_VALID_ID(object_id);
+    case OF_OXM:
+        return OF_OXM_VALID_ID(object_id);
+    case OF_QUEUE_PROP:
+        return OF_QUEUE_PROP_VALID_ID(object_id);
+    case OF_TABLE_FEATURE_PROP:
+        return OF_TABLE_FEATURE_PROP_VALID_ID(object_id);
+    case OF_INSTRUCTION:
+        return OF_INSTRUCTION_VALID_ID(object_id);
+    default:
+        break;
+    }
+    return 1;
+}
+""")
+
+def gen_object_enum_str(out):
+    out.write("\nconst char *of_object_id_str[] = {\n")
+    out.write("    \"of_object\",\n")
+    for cls in of_g.ordered_messages:
+        out.write("    \"%s\",\n" % cls)
+    out.write("\n    /* Non-message objects */\n")
+    for cls in of_g.ordered_non_messages:
+        out.write("    \"%s\",\n" % cls)
+    out.write("\n    /* List objects */\n")
+    for cls in of_g.ordered_list_objects:
+        out.write("    \"%s\",\n" % cls)
+    out.write("\n    /* Generic stats request/reply types; pseudo objects */\n")
+    for cls in of_g.ordered_pseudo_objects:
+        out.write("    \"%s\",\n" % cls)
+    out.write("\n    \"of_unknown_object\"\n};\n")
+
+    # We'll do version strings while we're at it
+    out.write("""
+ const char *of_version_str[] = {
+    "Unknown OpenFlow Version",
+    "OpenFlow-1.0",
+    "OpenFlow-1.1",
+    "OpenFlow-1.2"
+};
+
+const of_mac_addr_t of_mac_addr_all_ones = {
+    {
+        0xff, 0xff, 0xff, 0xff, 0xff, 0xff
+    }
+};
+/* Just to be explicit; static duration vars are init'd to 0 */
+const of_mac_addr_t of_mac_addr_all_zeros = {
+    {
+        0, 0, 0, 0, 0, 0
+    }
+};
+
+const of_ipv6_t of_ipv6_all_ones = {
+    {
+        0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+        0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
+    }
+};
+/* Just to be explicit; static duration vars are init'd to 0 */
+const of_ipv6_t of_ipv6_all_zeros = {
+    {
+        0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0
+    }
+};
+
+/** @var of_error_strings
+ * The error string map; use abs value to index
+ */
+const char *of_error_strings[] = { OF_ERROR_STRINGS };
+""")
+
+################################################################
+#
+# Internal Utility Functions
+#
+################################################################
+
+
+def acc_name(cls, m_name):
+    """
+    Generate the root name of an accessor function for typedef
+    @param cls The class name
+    @param m_name The member name
+    """
+    (m_type, get_rv) = get_acc_rv(cls, m_name)
+    return "%s_%s" % (cls, m_type)
+
+def get_acc_rv(cls, m_name):
+    """
+    Determine the data type and return type for a get accessor.
+
+    The return type may be "void" or it may be the accessor type
+    depending on the system configuration and on the data type.
+
+    @param cls The class name
+    @param m_name The member name
+    @return A pair (m_type, rv) where m_type is the unified type of the
+    member and rv is the get_accessor return type
+    """
+    member = of_g.unified[cls]["union"][m_name]
+    m_type = member["m_type"]
+    rv = "int"
+    if member_returns_val(cls, m_name):
+        rv = m_type
+    if m_type[-2:] == "_t":
+        m_type = m_type[:-2]
+
+    return (m_type, rv)
+
+def param_list(cls, m_name, a_type):
+    """
+    Generate the parameter list (no parens) for an a_type accessor
+    @param cls The class name
+    @param m_name The member name
+    @param a_type One of "set" or "get" or TBD
+    """
+    member = of_g.unified[cls]["union"][m_name]
+    m_type = member["m_type"]
+    params = ["%s_t *obj" % cls]
+    if a_type == "set":
+        if loxi_utils.type_is_scalar(m_type):
+            params.append("%s %s" % (m_type, m_name))
+        else:
+            params.append("%s *%s" % (m_type, m_name))
+    elif a_type in ["get", "bind"]:
+        params.append("%s *%s" % (m_type, m_name))
+    else:
+        debug("Class %s, name %s Bad param list a_type: %s" %
+            (cls, m_name, a_type))
+        sys.exit(1)
+    return params
+
+def typed_function_base(cls, m_name):
+    """
+    Generate the core name for accessors based on the type
+    @param cls The class name
+    @param m_name The member name
+    """
+    (m_type, get_rv) = get_acc_rv(cls, m_name)
+    return "%s_%s" % (cls, m_type)
+
+def member_function_base(cls, m_name):
+    """
+    Generate the core name for accessors based on the member name
+    @param cls The class name
+    @param m_name The member name
+    """
+    return "%s_%s" % (cls, m_name)
+
+def field_ver_get(cls, m_name):
+    """
+    Generate a dict, indexed by wire version, giving a pair (type, offset)
+
+    @param cls The class name
+    @param m_name The name of the class member
+
+    If offset is not known for m_name, the type
+    A dict is used for more convenient indexing.
+    """
+    result = {}
+
+    for ver in of_g.unified[cls]:
+        if type(ver) == type(0): # It's a version
+            if "use_version" in of_g.unified[cls][ver]: # deref version ref
+                ref_ver = of_g.unified[cls][ver]["use_version"]
+                members = of_g.unified[cls][ref_ver]["members"]
+            else:
+                members = of_g.unified[cls][ver]["members"]
+            idx = loxi_utils.member_to_index(m_name, members)
+            if (idx < 0):
+                continue # Member not in this version
+            m_type = members[idx]["m_type"]
+            offset = members[idx]["offset"]
+
+            # If m_type is mixed, get wire version type from global data
+            if m_type in of_g.of_mixed_types and \
+                    ver in of_g.of_mixed_types[m_type]:
+                m_type = of_g.of_mixed_types[m_type][ver]
+
+            # add version to result list
+            result[ver] = (m_type, offset)
+
+    return result
+
+def v3_match_offset_get(cls):
+    """
+    Return the offset of an OF 1.2 match in an object if it has such; 
+    otherwise return -1
+    """
+    result = field_ver_get(cls, "match")
+    if of_g.VERSION_1_2 in result:
+        if result[of_g.VERSION_1_2][0] == "of_match_v3_t":
+            return result[of_g.VERSION_1_2][1]
+    return -1
+
+################################################################
+#
+# OpenFlow Object Definitions
+#
+################################################################
+
+
+def gen_of_object_defs(out):
+    """
+    Generate low level of_object core operations
+    @param out The file for output, already open
+    """
+
+def gen_generics(out):
+    for (cls, subclasses) in type_maps.inheritance_map.items():
+        out.write("""
+/**
+ * Inheritance super class for %(cls)s
+ *
+ * This class is the union of %(cls)s classes.  You can refer
+ * to it untyped by refering to the member 'header' whose structure
+ * is common across all sub-classes.
+ */
+
+union %(cls)s_u {
+    %(cls)s_header_t header; /* Generic instance */
+""" % dict(cls=cls))
+        for subcls in sorted(subclasses):
+            out.write("    %s_%s_t %s;\n" % (cls, subcls, subcls))
+        out.write("};\n")
+
+def gen_struct_typedefs(out):
+    """
+    Generate typedefs for all struct objects
+    @param out The file for output, already open
+    """
+
+    out.write("\n/* LOCI inheritance parent typedefs */\n")
+    for cls in type_maps.inheritance_map:
+        out.write("typedef union %(cls)s_u %(cls)s_t;\n" % dict(cls=cls))
+    out.write("\n/* LOCI object typedefs */\n")
+    for cls in of_g.standard_class_order:
+        if cls in type_maps.inheritance_map:
+            continue
+        if config_check("gen_fn_ptrs"):
+            out.write("typedef struct %(cls)s_s %(cls)s_t;\n" % dict(cls=cls))
+        else:
+            template = "typedef of_object_t %(cls)s_t;\n"
+            out.write(template % dict(cls=cls))
+
+    out.write("""
+/****************************************************************
+ *
+ * Additional of_object defines
+ * These are needed for some static inline ops, so we put them here.
+ *
+ ****************************************************************/
+
+/* Delete an OpenFlow object without reference to its type */
+extern void of_object_delete(of_object_t *obj);
+
+""")
+
+def gen_generic_union(out):
+    """
+    Generate the generic union object composing all LOCI objects
+
+    @param out The file to which to write the decs
+    """
+    out.write("""
+/**
+ * The common LOCI object is a union of all possible objects.
+ */
+union of_generic_u {
+    of_object_t object;  /* Common base class with fundamental accessors */
+
+    /* Message objects */
+""")
+    for cls in of_g.ordered_messages:
+        out.write("    %s_t %s;\n" % (cls, cls))
+    out.write("\n    /* Non-message composite objects */\n")
+    for cls in of_g.ordered_non_messages:
+        if cls in type_maps.inheritance_map:
+            continue
+        out.write("    %s_t %s;\n" % (cls, cls))
+    out.write("\n    /* List objects */\n")
+    for cls in of_g.ordered_list_objects:
+        out.write("    %s_t %s;\n" % (cls, cls))
+    out.write("};\n")
+
+def gen_common_struct_definitions(out):
+    out.write("""
+/****************************************************************
+ *
+ * Unified structure definitions
+ *
+ ****************************************************************/
+
+struct of_object_s {
+    /* Common members */
+%(common)s
+};
+""" % dict(common=of_g.base_object_members))
+
+def gen_flow_add_setup_function_declarations(out):
+    """
+    Add the declarations for functions that can be initialized
+    by a flow add.  These are defined external to LOXI.
+    """
+
+    out.write("""
+/****************************************************************
+ * Functions for objects that can be initialized by a flow add message.
+ * These are defined in a non-autogenerated file
+ ****************************************************************/
+
+/**
+ * @brief Set up a flow removed message from the original add
+ * @param obj The flow removed message being updated
+ * @param flow_add The flow_add message to use
+ *
+ * Initialize the following fields of obj to be identical
+ * to what was originally on the wire from the flow_add object:
+ *     match
+ *     cookie
+ *     priority
+ *     idle_timeout
+ *     hard_timeout
+ *
+ */
+
+extern int
+of_flow_removed_setup_from_flow_add(of_flow_removed_t *obj,
+                                    of_flow_add_t *flow_add);
+
+
+/**
+ * @brief Set up the packet in match structure from the original add
+ * @param obj The packet in message being updated
+ * @param flow_add The flow_add message to use
+ * @returns Indigo error code.  Does not return a version error if
+ * the version does not require initializing obj.
+ *
+ * Initialize the match member of obj to be identical to what was originally
+ * on the wire from the flow_add object.  If applicable, the table ID is also
+ * initialized from the flow_add object.
+ *
+ * This API applies to 1.2 and later only.
+ */
+
+extern int
+of_packet_in_setup_from_flow_add(of_packet_in_t *obj,
+                                 of_flow_add_t *flow_add);
+
+
+/**
+ * @brief Set up the flow stats entry from the original add
+ * @param obj The packet in message being updated
+ * @param flow_add The flow_add message to use
+ * @param effects Optional actions or instructions; see below.
+ *
+ * Initialize the following fields of obj to be identical
+ * to what was originally on the wire from the flow_add object:
+ *     match
+ *     actions/instructions (effects)
+ *     cookie
+ *     priority
+ *     idle_timeout
+ *     hard_timeout
+ *
+ * Note that the actions/instructions of a flow may be modified by a 
+ * subsequent flow modify message.  To facilitate implementations,
+ * the "effects" parameter is provided.  If effects is NULL, the
+ * actions/instructions are taken from the flow_add message.
+ * Otherwise, effects is coerced to the proper type (actions or
+ * instructions) and used to init obj.
+ */
+
+extern int
+of_flow_stats_entry_setup_from_flow_add(of_flow_stats_entry_t *obj,
+                                        of_flow_add_t *flow_add,
+                                        of_object_t *effects);
+""")
+
+def gen_struct_definitions(out):
+    """
+    Generate the declaration of all of_ C structures
+
+    @param out The file to which to write the decs
+    """
+
+    # This should only get called if gen_fn_ptr is true in code_gen_config
+    if not config_check("gen_fn_ptrs"):
+        debug("Error: gen_struct_defs called, but no fn ptrs set")
+        return
+
+    for cls in of_g.standard_class_order:
+        if cls in type_maps.inheritance_map:
+            continue # These are generated elsewhere
+        note = ""
+        if loxi_utils.class_is_message(cls):
+            note = " /* Class is message */"
+        out.write("struct %s_s {%s\n" % (cls, note))
+        out.write("""    /* Common members */
+%s
+    /* Class specific members */
+""" % of_g.base_object_members)
+        if loxi_utils.class_is_list(cls):
+            out.write("""
+    %(cls)s_first_f first;
+    %(cls)s_next_f next;
+    %(cls)s_append_bind_f append_bind;
+    %(cls)s_append_f append;
+};
+
+""" % {"cls": cls})
+            continue   # All done with list object
+
+        # Else, not a list instance; add accessors for all data members
+        for m_name in of_g.ordered_members[cls]:
+            if m_name in of_g.skip_members:
+                # These members (length, etc) are handled internally
+                continue
+            f_name = acc_name(cls, m_name)
+            out.write("    %s_get_f %s;\n" % (f_name, m_name + "_get"))
+            out.write("    %s_set_f %s;\n" % (f_name, m_name + "_set"))
+        out.write("};\n\n")
+
+
+################################################################
+#
+# List accessor code generation
+#
+# Currently these all implement copy on read semantics
+#
+################################################################
+
+def init_call(e_type, obj, ver, length, cw):
+    """
+    Generate the init call given the strings for params
+    """
+    hdr = "" # If inheritance type, coerce to hdr object
+    obj_name = obj
+    if e_type in type_maps.inheritance_map:
+        hdr = "_header"
+        obj_name = "(%s_header_t *)" % e_type + obj
+
+    return """\
+%(e_type)s%(hdr)s_init(%(obj_name)s,
+            %(ver)s, %(length)s, %(cw)s)\
+""" % dict(e_type=e_type, hdr=hdr, obj_name=obj_name, ver=ver,
+           length=length, cw=cw)
+
+def gen_list_first(out, cls, e_type):
+    """
+    Generate the body of a list_first operation
+    @param cls The class name for which code is being generated
+    @param e_type The element type of the list
+    @param out The file to which to write
+    """
+    i_call = init_call(e_type, "obj", "list->version", "0", "1")
+    if e_type in type_maps.inheritance_map:
+        len_str = "obj->header.length"
+    else:
+        len_str = "obj->length"
+
+    out.write("""
+/**
+ * Associate an iterator with a list
+ * @param list The list to iterate over
+ * @param obj The list entry iteration pointer
+ * @return OF_ERROR_RANGE if the list is empty (end of list)
+ *
+ * The obj instance is completely initialized.  The caller is responsible
+ * for cleaning up any wire buffers associated with obj before this call
+ */
+
+int
+%(cls)s_first(%(cls)s_t *list,
+    %(e_type)s_t *obj)
+{
+    int rv;
+
+    %(i_call)s;
+    if ((rv = of_list_first((of_object_t *)list, (of_object_t *)obj)) < 0) {
+        return rv;
+    }
+""" % dict(cls=cls, e_type=e_type, i_call=i_call))
+
+    # Special case flow_stats_entry lists
+
+    out.write("""
+    of_object_wire_init((of_object_t *) obj, %(u_type)s,
+                        list->length);
+    if (%(len_str)s == 0) {
+        return OF_ERROR_PARSE;
+    }
+
+    return rv;
+}
+""" % dict(cls=cls, e_type=e_type, u_type=enum_name(e_type), len_str=len_str))
+
+
+def gen_bind(out, cls, m_name, m_type):
+    """
+    Generate the body of a bind function
+    @param out The file to which to write
+    @param cls The class name for which code is being generated
+    @param m_name The name of the data member
+    @param m_type The type of the data member
+    """
+
+    bparams = ",\n    ".join(param_list(cls, m_name, "bind"))
+
+    i_call = init_call(e_type, "child", "parent->version", "0", "1")
+
+    out.write("""
+/**
+ * Bind the child object to the parent object for read processing
+ * @param parent The parent object
+ * @param child The child object
+ *
+ * The child obj instance is completely initialized.
+ */
+
+int
+%(cls)s_%(m_name)_bind(%(cls)s_t *parent,
+    %(e_type)s_t *child)
+{
+    int rv;
+
+    %(i_call)s;
+
+    /* Derive offset and length of child in parent */
+    OF_TRY(of_object_child_attach(parent, child, 
+    if ((rv = of_list_first((of_object_t *)list, (of_object_t *)obj)) < 0) {
+        return rv;
+    }
+""" % dict(cls=cls, e_type=e_type, i_call=i_call))
+
+    # Special case flow_stats_entry lists
+
+    out.write("""
+    rv = of_object_wire_init((of_object_t *) obj, %(u_type)s,
+                               list->length);
+    if ((rv == OF_ERROR_NONE) && (%(len_str)s == 0)) {
+        return OF_ERROR_PARSE;
+    }
+
+    return rv;
+}
+""" % dict(cls=cls, e_type=e_type, u_type=enum_name(e_type), len_str=len_str))
+
+
+def gen_list_next(out, cls, e_type):
+    """
+    Generate the body of a list_next operation
+    @param cls The class name for which code is being generated
+    @param e_type The element type of the list
+    @param out The file to which to write
+    """
+
+    if e_type in type_maps.inheritance_map:
+        len_str = "obj->header.length"
+    else:
+        len_str = "obj->length"
+        
+    out.write("""
+/**
+ * Advance an iterator to the next element in a list
+ * @param list The list being iterated
+ * @param obj The list entry iteration pointer
+ * @return OF_ERROR_RANGE if already at the last entry on the list
+ *
+ */
+
+int
+%(cls)s_next(%(cls)s_t *list,
+    %(e_type)s_t *obj)
+{
+    int rv;
+
+    if ((rv = of_list_next((of_object_t *)list, (of_object_t *)obj)) < 0) {
+        return rv;
+    }
+
+    rv = of_object_wire_init((of_object_t *) obj, %(u_type)s,
+        list->length);
+
+    if ((rv == OF_ERROR_NONE) && (%(len_str)s == 0)) {
+        return OF_ERROR_PARSE;
+    }
+
+    return rv;
+}
+""" % dict(cls=cls, e_type=e_type, u_type=enum_name(e_type), len_str=len_str))
+
+def gen_list_append(out, cls, e_type):
+    """
+    Generate the body of a list append functions
+    @param cls The class name for which code is being generated
+    @param e_type The element type of the list
+    @param out The file to which to write
+    """
+
+    out.write("""
+/**
+ * Set up to append an object of type %(e_type)s to an %(cls)s.
+ * @param list The list that is prepared for append
+ * @param obj Pointer to object to hold data to append
+ *
+ * The obj instance is completely initialized.  The caller is responsible
+ * for cleaning up any wire buffers associated with obj before this call.
+ *
+ * See the generic documentation for of_list_append_bind.
+ */
+
+int
+%(cls)s_append_bind(%(cls)s_t *list,
+    %(e_type)s_t *obj)
+{
+    return of_list_append_bind((of_object_t *)list, (of_object_t *)obj);
+}
+
+/**
+ * Append an item to a %(cls)s list.
+ *
+ * This copies data from item and leaves item untouched.
+ *
+ * See the generic documentation for of_list_append.
+ */
+
+int
+%(cls)s_append(%(cls)s_t *list,
+    %(e_type)s_t *item)
+{
+    return of_list_append((of_object_t *)list, (of_object_t *)item);
+}
+
+""" % dict(cls=cls, e_type=e_type))
+
+def gen_list_accessors(out, cls):
+    e_type = loxi_utils.list_to_entry_type(cls)
+    gen_list_first(out, cls, e_type)
+    gen_list_next(out, cls, e_type)
+    gen_list_append(out, cls, e_type)
+
+################################################################
+#
+# Accessor Functions
+#
+################################################################
+
+    
+def gen_accessor_declarations(out):
+    """
+    Generate the declaration of each version independent accessor
+
+    @param out The file to which to write the decs
+    """
+
+    out.write("""
+/****************************************************************
+ *
+ * Unified, per-member accessor function declarations
+ *
+ ****************************************************************/
+""")
+    for cls in of_g.standard_class_order:
+        if cls in type_maps.inheritance_map:
+            continue
+        out.write("\n/* Unified accessor functions for %s */\n" % cls)
+        for m_name in of_g.ordered_members[cls]:
+            if m_name in of_g.skip_members:
+                continue
+            m_type = loxi_utils.member_base_type(cls, m_name)
+            base_name = "%s_%s" % (cls, m_name)
+            gparams = ",\n    ".join(param_list(cls, m_name, "get"))
+            get_ret_type = accessor_return_type("get", m_type)
+            sparams = ",\n    ".join(param_list(cls, m_name, "set"))
+            set_ret_type = accessor_return_type("set", m_type)
+            bparams = ",\n    ".join(param_list(cls, m_name, "bind"))
+            bind_ret_type = accessor_return_type("bind", m_type)
+
+            if loxi_utils.type_is_of_object(m_type):
+                # Generate bind accessors, but not get accessor
+                out.write("""
+extern %(set_ret_type)s %(base_name)s_set(
+    %(sparams)s);
+extern %(bind_ret_type)s %(base_name)s_bind(
+    %(bparams)s);
+extern %(m_type)s *%(cls)s_%(m_name)s_get(
+    %(cls)s_t *obj);
+""" % dict(base_name=base_name, sparams=sparams, bparams=bparams,
+           m_name=m_name, m_type=m_type, cls=cls,
+           set_ret_type=set_ret_type, bind_ret_type=bind_ret_type))
+            else:
+                out.write("""
+extern %(set_ret_type)s %(base_name)s_set(
+    %(sparams)s);
+extern %(get_ret_type)s %(base_name)s_get(
+    %(gparams)s);
+""" % dict(base_name=base_name, gparams=gparams, sparams=sparams,
+           get_ret_type=get_ret_type, set_ret_type=set_ret_type))
+            
+        if loxi_utils.class_is_list(cls):
+            e_type = loxi_utils.list_to_entry_type(cls)
+            out.write("""
+extern int %(cls)s_first(
+    %(cls)s_t *list, %(e_type)s_t *obj);
+extern int %(cls)s_next(
+    %(cls)s_t *list, %(e_type)s_t *obj);
+extern int %(cls)s_append_bind(
+    %(cls)s_t *list, %(e_type)s_t *obj);
+extern int %(cls)s_append(
+    %(cls)s_t *list, %(e_type)s_t *obj);
+
+/**
+ * Iteration macro for list of type %(cls)s
+ * @param list Pointer to the list being iterated over of
+ * type %(cls)s
+ * @param elt Pointer to an element of type %(e_type)s
+ * @param rv On exiting the loop will have the value OF_ERROR_RANGE.
+ */
+#define %(u_cls)s_ITER(list, elt, rv)  \\
+    for ((rv) = %(cls)s_first((list), (elt));   \\
+         (rv) == OF_ERROR_NONE;   \\
+         (rv) = %(cls)s_next((list), (elt)))
+""" % dict(u_cls=cls.upper(), cls=cls, e_type=e_type))
+
+
+def wire_accessor(m_type, a_type):
+    """
+    Returns the name of the a_type accessor for low level wire buff offset
+    @param m_type The member type
+    @param a_type The accessor type (set or get)
+    """
+    # Strip off _t if present
+    if m_type in of_g.of_base_types:
+        m_type = of_g.of_base_types[m_type]["short_name"]
+    if m_type in of_g.of_mixed_types:
+        m_type = of_g.of_mixed_types[m_type]["short_name"]
+    if m_type[-2:] == "_t":
+        m_type = m_type[:-2]
+    if m_type == "octets":
+        m_type = "octets_data"
+    return "of_wire_buffer_%s_%s" % (m_type, a_type)
+
+def get_len_macro(cls, m_type, version):
+    """
+    Get the length macro for m_type in cls
+    """
+    if m_type.find("of_match") == 0:
+        return "_WIRE_MATCH_PADDED_LEN(obj, offset)"
+    if m_type.find("of_list_oxm") == 0:
+        return "wire_match_len(obj, 0) - 4"
+    if loxi_utils.class_is_tlv16(m_type):
+        return "_TLV16_LEN(obj, offset)"
+    if cls == "of_packet_out" and m_type == "of_list_action_t":
+        return "_PACKET_OUT_ACTION_LEN(obj)"
+    # Default is everything to the end of the object
+    return "_END_LEN(obj, offset)"
+
+def gen_accessor_offsets(out, cls, m_name, version, a_type, m_type, offset):
+    """
+    Generate the sub-object offset and length calculations for accessors
+    @param out File being written
+    @param m_name Name of member
+    @param version Wire version being processed
+    @param a_type The accessor type (set or get)
+    @param m_type The original member type
+    @param offset The offset of the object or -1 if not fixed
+    """
+    # determine offset
+    o_str = "%d" % offset  # Default is fixed length
+    if offset == -1:
+        # There are currently 4 special cases for this
+        # In general, get offset and length of predecessor
+        if (loxi_utils.cls_is_flow_mod(cls) and m_name == "instructions"):
+            pass
+        elif (cls == "of_flow_stats_entry" and m_name == "instructions"):
+            pass
+        elif (cls == "of_packet_in" and m_name == "data"):
+            pass
+        elif (cls == "of_packet_out" and m_name == "data"):
+            pass
+        else:
+            debug("Error: Unknown member with offset == -1")
+            debug("  cls %s, m_name %s, version %d" % (cls, m_name, version))
+            sys.exit(1)
+        o_str = "_%s_%s_OFFSET(obj)" % (cls.upper()[3:], m_name.upper())
+
+    out.write("""\
+        offset = %s;
+""" % o_str);
+
+    # This could be moved to main body but for version check
+    if not loxi_utils.type_is_scalar(m_type):
+        if loxi_utils.class_is_var_len(m_type[:-2], version) or \
+                m_type == "of_match_t":
+            len_macro = get_len_macro(cls, m_type, version)
+        else:
+            len_macro = "%d" % of_g.base_length[(m_type[:-2], version)]
+        out.write("        cur_len = %s;\n" % len_macro)
+    out.write("        break;\n")
+
+def length_of(m_type, version):
+    """
+    Return the length of a type based on the version
+    """
+    if m_type in of_g.of_mixed_types:
+        m_type = of_g.of_mixed_types[m_type][version]
+    if m_type in of_g.of_base_types:
+        return of_g.of_base_types[m_type]["bytes"]
+    if (m_type[:-2], version) in of_g.base_length:
+        return of_g.base_length[(m_type[:-2], version)]
+    print "Unknown length request", m_type, version
+    sys.exit(1)
+        
+
+def gen_get_accessor_body(out, cls, m_type, m_name):
+    """
+    Generate the common operations for a get accessor
+    """
+    if loxi_utils.type_is_scalar(m_type):
+        ver = ""      # See if version required for scalar update
+        if m_type in of_g.of_mixed_types:
+            ver = "ver, "
+        out.write("""\
+    %(wa)s(%(ver)swbuf, abs_offset, %(m_name)s);
+""" % dict(wa=wire_accessor(m_type, "get"), ver=ver, m_name=m_name))
+
+        if m_type == "of_port_no_t":
+           out.write("    OF_PORT_NO_VALUE_CHECK(*%s, ver);\n" % m_name)
+    elif m_type == "of_octets_t":
+        out.write("""\
+    ASSERT(cur_len + abs_offset <= WBUF_CURRENT_BYTES(wbuf));
+    %(m_name)s->bytes = cur_len;
+    %(m_name)s->data = OF_WIRE_BUFFER_INDEX(wbuf, abs_offset);
+""" % dict(m_name=m_name))
+    elif m_type == "of_match_t":
+        out.write("""
+    ASSERT(cur_len + abs_offset <= WBUF_CURRENT_BYTES(wbuf));
+    match_octets.bytes = cur_len;
+    match_octets.data = OF_OBJECT_BUFFER_INDEX(obj, offset);
+    OF_TRY(of_match_deserialize(ver, %(m_name)s, &match_octets));
+""" % dict(m_name=m_name))
+    else:
+        out.write("""
+    /* Initialize child */
+    %(m_type)s_init(%(m_name)s, obj->version, 0, 1);
+    /* Attach to parent */
+    %(m_name)s->parent = (of_object_t *)obj;
+    %(m_name)s->wire_object.wbuf = obj->wire_object.wbuf;
+    %(m_name)s->wire_object.obj_offset = abs_offset;
+    %(m_name)s->wire_object.owned = 0;
+    %(m_name)s->length = cur_len;
+""" % dict(m_type=m_type[:-2], m_name=m_name))
+
+
+def gen_set_accessor_body(out, cls, m_type, m_name):
+    """
+    Generate the contents of a set accessor
+    """
+    if loxi_utils.type_is_scalar(m_type) or m_type == "of_octets_t":
+        ver = "" # See if version required for scalar update
+        if m_type in of_g.of_mixed_types:
+            ver = "ver, "
+        cur_len = "" # See if version required for scalar update
+        if m_type == "of_octets_t":
+            cur_len = ", cur_len"
+            out.write("""\
+    new_len = %(m_name)s->bytes;
+    of_wire_buffer_grow(wbuf, abs_offset + (new_len - cur_len));
+""" % dict(m_name=m_name))
+        out.write("""\
+    %(wa)s(%(ver)swbuf, abs_offset, %(m_name)s%(cur_len)s);
+""" % dict(wa=wire_accessor(m_type, "set"), ver=ver, cur_len=cur_len,
+           m_name=m_name))
+
+    elif m_type == "of_match_t":
+        out.write("""
+    /* Match object */
+    OF_TRY(of_match_serialize(ver, %(m_name)s, &match_octets));
+    new_len = match_octets.bytes;
+    of_wire_buffer_replace_data(wbuf, abs_offset, cur_len,
+        match_octets.data, new_len);
+    /* Free match serialized octets */
+    FREE(match_octets.data);
+""" % dict(m_name=m_name))
+
+    else:  # Other object type
+        out.write("\n    /* LOCI object type */")
+        # Need to special case OXM list
+        out.write("""
+    new_len = %(m_name)s->length;
+    /* If underlying buffer already shared; nothing to do */
+    if (obj->wire_object.wbuf == %(m_name)s->wire_object.wbuf) {
+        of_wire_buffer_grow(wbuf, abs_offset + new_len);
+        /* Verify that the offsets are correct */
+        ASSERT(abs_offset == OF_OBJECT_ABSOLUTE_OFFSET(%(m_name)s, 0));
+        /* ASSERT(new_len == cur_len); */ /* fixme: may fail for OXM lists */
+        return %(ret_success)s;
+    }
+
+    /* Otherwise, replace existing object in data buffer */
+    of_wire_buffer_replace_data(wbuf, abs_offset, cur_len,
+        OF_OBJECT_BUFFER_INDEX(%(m_name)s, 0), new_len);
+""" % dict(m_name=m_name, ret_success=accessor_return_success("set", m_type)))
+
+    if not loxi_utils.type_is_scalar(m_type):
+        if cls == "of_packet_out" and m_type == "of_list_action_t":
+            out.write("""
+    /* Special case for setting action lengths */
+    _PACKET_OUT_ACTION_LEN_SET(obj, %(m_name)s->length);
+""" % dict(m_name=m_name))
+        elif m_type not in ["of_match_t", "of_octets_t"]:
+            out.write("""
+    /* @fixme Shouldn't this precede copying value's data to buffer? */
+    if (%(m_name)s->wire_length_set != NULL) {
+        %(m_name)s->wire_length_set((of_object_t *)%(m_name)s, %(m_name)s->length);
+    }
+""" % dict(m_name=m_name))
+        out.write("""
+    /* Not scalar, update lengths if needed */
+    delta = new_len - cur_len;
+    if (delta != 0) {
+        /* Update parent(s) */
+        of_object_parent_length_update((of_object_t *)obj, delta);
+    }
+""")
+
+def obj_assert_check(cls):
+    """
+    The body of the assert check for an accessor
+    We allow all versions of add/delete/modify to use the same accessors
+    """
+    if cls in ["of_flow_modify", "of_flow_modify_strict",
+               "of_flow_delete", "of_flow_delete_strict",
+               "of_flow_add"]:
+        return "IS_FLOW_MOD_SUBTYPE(obj->object_id)"
+    else:
+        return "obj->object_id == %s" % cls.upper()
+
+def gen_of_object_get(out, cls, m_name, m_type):
+    sub_cls = m_type[:-2]
+    out.write("""
+/**
+ * Create a copy of %(m_name)s into a new variable of type %(m_type)s from 
+ * a %(cls)s instance.
+ *
+ * @param obj Pointer to the source of type %(cls)s_t
+ * @returns A pointer to a new instance of type %(m_type)s whose contents
+ * match that of %(m_name)s from source
+ * @returns NULL if an error occurs
+ */
+%(m_type)s *
+%(cls)s_%(m_name)s_get(%(cls)s_t *obj) {
+    %(m_type)s _%(m_name)s;
+    %(m_type)s *_%(m_name)s_ptr;
+
+    %(cls)s_%(m_name)s_bind(obj, &_%(m_name)s);
+    _%(m_name)s_ptr = (%(m_type)s *)of_object_dup(&_%(m_name)s);
+    return _%(m_name)s_ptr;
+}
+""" % dict(m_name=m_name, m_type=m_type, cls=cls, sub_cls=sub_cls))
+
+def gen_unified_acc_body(out, cls, m_name, ver_type_map, a_type, m_type):
+    """
+    Generate the body of a set or get accessor function
+
+    @param out The file to which to write the decs
+    @param cls The class name
+    @param m_name The member name
+    @param ver_type_map Maps (type, offset) pairs to a list of versions
+    @param a_type The accessor type, set or get
+    @param m_type The original member type
+
+    The type values in ver_type_map are now ignored as we've pushed down
+    the type munging to the lower level.
+
+    This is unified because the version switch case processing is the
+    same for both set and get
+    """
+    out.write("""{
+    of_wire_buffer_t *wbuf;
+    int offset = 0; /* Offset of value relative to the start obj */
+    int abs_offset; /* Offset of value relative to start of wbuf */
+    of_version_t ver;
+""")
+
+    if not loxi_utils.type_is_scalar(m_type):
+        out.write("""\
+    int cur_len = 0; /* Current length of object data */
+""")
+        if a_type == "set":
+            out.write("""\
+    int new_len, delta; /* For set, need new length and delta */
+""")
+
+    # For match, need octet string for set/get
+    if m_type == "of_match_t":
+        out.write("""\
+    of_octets_t match_octets; /* Serialized string for match */
+""")
+
+    out.write("""
+    ASSERT(%(assert_str)s);
+    ver = obj->version;
+    wbuf = OF_OBJECT_TO_WBUF(obj);
+    ASSERT(wbuf != NULL);
+
+    /* By version, determine offset and current length (where needed) */
+    switch (ver) {
+""" % dict(assert_str=obj_assert_check(cls)))
+
+    for first in sorted(ver_type_map):
+        (prev_t, prev_o) = ver_type_map[first]
+        prev_len = length_of(prev_t, first)
+        prev = first
+        out.write("    case %s:\n" % of_g.wire_ver_map[first])
+        break
+
+    for next in sorted(ver_type_map):
+        if next == first:
+            continue
+
+        (t, o) = ver_type_map[next]
+        cur_len = length_of(t, next)
+        if o == prev_o and cur_len == prev_len:
+            out.write("    case %s:\n" % of_g.wire_ver_map[next])
+            continue
+        gen_accessor_offsets(out, cls, m_name, prev, a_type, m_type, prev_o)
+        out.write("    case %s:\n" % of_g.wire_ver_map[next])
+        (prev_t, prev_o, prev_len, prev) = (t, o, cur_len, next)
+
+    gen_accessor_offsets(out, cls, m_name, next, a_type, m_type, prev_o)
+    out.write("""\
+    default:
+        ASSERT(0);
+    }
+
+    abs_offset = OF_OBJECT_ABSOLUTE_OFFSET(obj, offset);
+    ASSERT(abs_offset >= 0);
+""")
+    if not loxi_utils.type_is_scalar(m_type):
+        out.write("    ASSERT(cur_len >= 0 && cur_len < 64 * 1024);\n")
+
+    # Now generate the common accessor code
+    if a_type in ["get", "bind"]:
+        gen_get_accessor_body(out, cls, m_type, m_name)
+    else:
+        gen_set_accessor_body(out, cls, m_type, m_name)
+
+    out.write("""
+    OF_LENGTH_CHECK_ASSERT(obj);
+
+    return %s;
+}
+""" % accessor_return_success(a_type, m_type))
+
+def gen_of_obj_bind(out, cls, m_name, m_type, ver_type_map):
+    """
+    For generating the bind call for OF sub-objects
+    """
+
+    params = ",\n    ".join(param_list(cls, m_name, "bind"))
+    out.write("""
+/**
+ * Bind an object of type %(m_type)s to the parent of type %(cls)s for
+ * member %(m_name)s
+ * @param obj Pointer to an object of type %(cls)s.
+ * @param %(m_name)s Pointer to the child object of type
+ * %(m_type)s to be filled out.
+ * \ingroup %(cls)s
+ *
+ * The parameter %(m_name)s is filled out to point to the same underlying
+ * wire buffer as its parent.
+ *
+ */
+""" % dict(m_name=m_name, cls=cls, m_type=m_type))
+
+    ret_type = accessor_return_type("bind", m_type)
+    out.write("%s\n%s_%s_bind(\n    %s)\n" % (ret_type, cls, m_name, params))
+    gen_unified_acc_body(out, cls, m_name, ver_type_map, "bind", m_type)
+
+def gen_get_accessor(out, cls, m_name, m_type, ver_type_map):
+    """
+    For generating the get call for non- OF sub-objects
+    """
+    params = ",\n    ".join(param_list(cls, m_name, "get"))
+    out.write("""
+/**
+ * Get %(m_name)s from an object of type %(cls)s.
+ * @param obj Pointer to an object of type %(cls)s.
+ * @param %(m_name)s Pointer to the child object of type
+ * %(m_type)s to be filled out.
+ *
+ */
+""" % dict(m_name=m_name, cls=cls, m_type=m_type))
+
+    ret_type =  accessor_return_type("get", m_type)
+    out.write("%s\n%s_%s_get(\n    %s)\n" % (ret_type, cls, m_name, params))
+    gen_unified_acc_body(out, cls, m_name, ver_type_map, "get", m_type)
+
+def gen_accessor_definitions(out):
+    """
+    Generate the body of each version independent accessor
+
+    @param out The file to which to write the decs
+    """
+
+    out.write("""
+/****************************************************************
+ *
+ * Unified accessor function definitions
+ *
+ ****************************************************************/
+""")
+    for cls in of_g.standard_class_order:
+        if cls in type_maps.inheritance_map:
+            continue
+        out.write("\n/* Unified accessor functions for %s */\n" % cls)
+        if loxi_utils.class_is_list(cls):
+            gen_list_accessors(out, cls)
+            continue
+        out.write("/** \\ingroup %s \n * @{ */\n" % cls)
+        for m_name in of_g.ordered_members[cls]:
+            if m_name in of_g.skip_members:
+                continue
+            m_type = loxi_utils.member_base_type(cls, m_name)
+            ver_type_map = field_ver_get(cls, m_name)
+
+            # Generate get/bind pending on member type
+            # FIXME:  Does this do the right thing for match?
+            if loxi_utils.type_is_of_object(m_type):
+                gen_of_obj_bind(out, cls, m_name, m_type, ver_type_map)
+                gen_of_object_get(out, cls, m_name, m_type)
+            else:
+                gen_get_accessor(out, cls, m_name, m_type, ver_type_map)
+
+            # Now generate set accessor for all objects
+            params = ",\n    ".join(param_list(cls, m_name, "set"))
+            out.write("""
+/**
+ * Set %(m_name)s in an object of type %(cls)s.
+ * @param obj Pointer to an object of type %(cls)s.
+""" % dict(m_name=m_name, cls=cls, m_type=m_type))
+            if loxi_utils.type_is_scalar(m_type) or m_type == "of_octets_t":
+                out.write("""\
+ * @param %(m_name)s The value to write into the object
+ */
+""" % dict(m_name=m_name, cls=cls, m_type=m_type))
+            else:
+                out.write("""\
+ * @param %(m_name)s Pointer to the child of type %(m_type)s.
+ *
+ * If the child's wire buffer is the same as the parent's, then
+ * nothing is done as the changes have already been registered in the
+ * parent.  Otherwise, the data in the child's wire buffer is inserted
+ * into the parent's and the appropriate lengths are updated.
+ */
+""" % dict(m_name=m_name, cls=cls, m_type=m_type))
+            ret_type = accessor_return_type("set", m_type)
+            out.write("%s\n%s_%s_set(\n    %s)\n" % (ret_type, cls, m_name, params))
+            gen_unified_acc_body(out, cls, m_name, ver_type_map, "set", m_type)
+
+        out.write("\n/** @} */\n")
+
+def gen_acc_pointer_typedefs(out):
+    """
+    Generate the function pointer typedefs for in-struct accessors
+    @param out The file to which to write the typedefs
+    """
+
+    out.write("""
+/****************************************************************
+ *
+ * Accessor function pointer typedefs
+ *
+ ****************************************************************/
+
+/*
+ * Generic accessors:
+ *
+ * Many objects have a length represented in the wire buffer
+ * wire_length_get and wire_length_set access these values directly on the
+ * wire.
+ *
+ * Many objects have a length represented in the wire buffer
+ * wire_length_get and wire_length_set access these values directly on the
+ * wire.
+ *
+ * FIXME: TBD if wire_length_set and wire_type_set are required.
+ */
+typedef void (*of_wire_length_get_f)(of_object_t *obj, int *bytes);
+typedef void (*of_wire_length_set_f)(of_object_t *obj, int bytes);
+typedef void (*of_wire_type_get_f)(of_object_t *obj, of_object_id_t *id);
+typedef void (*of_wire_type_set_f)(of_object_t *obj, of_object_id_t id);
+""")
+    # If not using function pointers in classes, don't gen typedefs below
+    if not config_check("gen_fn_ptrs"):
+        return
+
+    # For each class, for each type it uses, generate a typedef
+    for cls in of_g.standard_class_order:
+        if cls in type_maps.inheritance_map:
+            continue
+        out.write("\n/* Accessor function pointer typedefs for %s */\n" % cls)
+        types_done = list()
+        for m_name in of_g.ordered_members[cls]:
+            (m_type, get_rv) = get_acc_rv(cls, m_name)
+            if (m_type, get_rv) in types_done:
+                continue
+            types_done.append((m_type, get_rv))
+            fn = "%s_%s" % (cls, m_type)
+            params = ", ".join(param_list(cls, m_name, "get"))
+            out.write("typedef int (*%s_get_f)(\n    %s);\n" %
+                      (fn, params))
+
+            params = ", ".join(param_list(cls, m_name, "set"))
+            out.write("typedef int (*%s_set_f)(\n    %s);\n" %
+                      (fn, params))
+        if loxi_utils.class_is_list(cls):
+            obj_type = loxi_utils.list_to_entry_type(cls)
+            out.write("""typedef int (*%(cls)s_first_f)(
+    %(cls)s_t *list,
+    %(obj_type)s_t *obj);
+typedef int (*%(cls)s_next_f)(
+    %(cls)s_t *list,
+    %(obj_type)s_t *obj);
+typedef int (*%(cls)s_append_bind_f)(
+    %(cls)s_t *list,
+    %(obj_type)s_t *obj);
+typedef int (*%(cls)s_append_f)(
+    %(cls)s_t *list,
+    %(obj_type)s_t *obj);
+""" % {"cls":cls, "obj_type":obj_type})
+
+#             out.write("""
+# typedef int (*%(cls)s_get_f)(
+#     %(cls)s_t *list,
+#     %(obj_type)s_t *obj, int index);
+# typedef int (*%(cls)s_set_f)(
+#     %(cls)s_t *list,
+#     %(obj_type)s_t *obj, int index);
+# typedef int (*%(cls)s_append_f)(
+#     %(cls)s_t *list,
+#     %(obj_type)s_t *obj, int index);
+# typedef int (*%(cls)s_insert_f)(
+#     %(cls)s_t *list,
+#     %(obj_type)s_t *obj, int index);
+# typedef int (*%(cls)s_remove_f)(
+#     %(cls)s_t *list,
+#     int index);
+# """ % {"cls":cls, "obj_type":obj_type})
+
+################################################################
+#
+# New/Delete Function Definitions
+#
+################################################################
+
+
+################################################################
+# First, some utility functions for new/delete
+################################################################
+
+def del_function_proto(cls):
+    """
+    Return the prototype for the delete operator for the given class
+    @param cls The class name
+    """
+    fn = "void\n"
+    return fn
+
+
+def instantiate_fn_ptrs(cls, ilvl, out):
+    """
+    Generate the C code to instantiate function pointers for a class
+    @param cls The class name
+    @param ilvl The base indentation level
+    @param out The file to which to write the functions
+    """
+    for m_name in of_g.ordered_members[cls]:
+        if m_name in of_g.skip_members:
+            continue
+        out.write(" " * ilvl + "obj->%s_get = %s_%s_get;\n" %
+                  (m_name, cls, m_name))
+        out.write(" " * ilvl + "obj->%s_set = %s_%s_set;\n" %
+                  (m_name, cls, m_name))
+
+################################################################
+# Routines to generate the body of new/delete functions
+################################################################
+
+def gen_init_fn_body(cls, out):
+    """
+    Generate function body for init function
+    @param cls The class name for the function
+    @param out The file to which to write
+    """
+    if cls in type_maps.inheritance_map:
+        param = "obj_p"
+    else:
+        param = "obj"
+
+    out.write("""
+/**
+ * Initialize an object of type %(cls)s.
+ *
+ * @param obj Pointer to the object to initialize
+ * @param version The wire version to use for the object
+ * @param bytes How many bytes in the object
+ * @param clean_wire Boolean: If true, clear the wire object control struct
+ *
+ * If bytes < 0, then the default fixed length is used for the object
+ *
+ * This is a "coerce" function that sets up the pointers for the
+ * accessors properly.  
+ *
+ * If anything other than 0 is passed in for the buffer size, the underlying
+ * wire buffer will have 'grow' called.
+ */
+
+void
+%(cls)s_init(%(cls)s_t *%(param)s,
+    of_version_t version, int bytes, int clean_wire)
+{
+""" % dict(cls=cls, param=param))
+
+    # Use an extra pointer to deal with inheritance classes
+    if cls in type_maps.inheritance_map:
+        out.write("""\
+    %s_header_t *obj;
+
+    obj = &obj_p->header;  /* Need instantiable subclass */
+""" % cls)
+
+    out.write("""
+    ASSERT(of_object_fixed_len[version][%(enum)s] >= 0);
+    if (clean_wire) {
+        MEMSET(obj, 0, sizeof(*obj));
+    }
+    if (bytes < 0) {
+        bytes = of_object_fixed_len[version][%(enum)s];
+    }
+    obj->version = version;
+    obj->length = bytes;
+    obj->object_id = %(enum)s;
+""" % dict(cls=cls, enum=enum_name(cls)))
+    gen_coerce_ops(out, cls)
+
+    out.write("""
+    /* Grow the wire buffer */
+    if (obj->wire_object.wbuf != NULL) {
+        int tot_bytes;
+
+        tot_bytes = bytes + obj->wire_object.obj_offset;
+        of_wire_buffer_grow(obj->wire_object.wbuf, tot_bytes);
+    }
+}
+
+""")
+
+## @fixme This should also be updated once there is a map from
+# class instance to wire length/type accessors
+def gen_wire_push_fn(cls, out):
+    """
+    Generate the calls to push values into the wire buffer
+    """
+    if type_maps.class_is_virtual(cls):
+        print "Push fn gen called for virtual class " + cls
+        return
+
+    out.write("""
+/**
+ * Helper function to push values into the wire buffer
+ */
+static inline int
+%(cls)s_push_wire_values(%(cls)s_t *obj)
+{
+""" % dict(cls=cls))
+
+    if loxi_utils.class_is_message(cls):
+        out.write("""
+    /* Message obj; push version, length and type to wire */
+    of_message_t msg;
+
+    if ((msg = OF_OBJECT_TO_MESSAGE(obj)) != NULL) {
+        of_message_version_set(msg, obj->version);
+        of_message_length_set(msg, obj->length);
+        OF_TRY(of_wire_message_object_id_set(OF_OBJECT_TO_WBUF(obj),
+                 %(name)s));
+    }
+""" % dict(name = enum_name(cls)))
+ 
+        for version in of_g.of_version_range:
+            if type_maps.class_is_extension(cls, version):
+                exp_name = type_maps.extension_to_experimenter_macro_name(cls)
+                subtype = type_maps.extension_message_to_subtype(cls, version)
+                if subtype is None or exp_name is None:
+                    print "Error in mapping extension message"
+                    print cls, version
+                    sys.exit(1)
+                out.write("""
+    if (obj->version == %(version)s) {
+        of_message_experimenter_id_set(OF_OBJECT_TO_MESSAGE(obj),
+                                       %(exp_name)s);
+        of_message_experimenter_subtype_set(OF_OBJECT_TO_MESSAGE(obj),
+                                            %(subtype)s);
+    }
+""" % dict(exp_name=exp_name, version=of_g.wire_ver_map[version],
+           subtype=str(subtype)))
+           
+    else: # Not a message
+        if loxi_utils.class_is_tlv16(cls):
+            out.write("""
+    /* TLV obj; set length and type */
+    of_tlv16_wire_length_set((of_object_t *)obj, obj->length);
+    of_tlv16_wire_object_id_set((of_object_t *)obj,
+           %(enum)s);
+""" % dict(enum=enum_name(cls)))
+            # Some tlv16 types may be extensions requiring more work
+            if cls in ["of_action_bsn_mirror", "of_action_id_bsn_mirror",
+                       "of_action_bsn_set_tunnel_dst", "of_action_id_bsn_set_tunnel_dst",
+                       "of_action_nicira_dec_ttl", "of_action_id_nicira_dec_ttl"]:
+                out.write("""
+    /* Extended TLV obj; Call specific accessor */
+    of_extension_object_id_set(obj, %(enum)s);
+""" % dict(cls=cls, enum=enum_name(cls)))
+                
+
+        if loxi_utils.class_is_oxm(cls):
+            out.write("""\
+    /* OXM obj; set length and type */
+    of_oxm_wire_length_set((of_object_t *)obj, obj->length);
+    of_oxm_wire_object_id_set((of_object_t *)obj, %(enum)s);
+""" % dict(enum=enum_name(cls)))
+        if loxi_utils.class_is_u16_len(cls) or cls == "of_packet_queue":
+            out.write("""
+    obj->wire_length_set((of_object_t *)obj, obj->length);
+""")
+
+        if cls == "of_meter_stats":
+            out.write("""
+    of_meter_stats_wire_length_set((of_object_t *)obj, obj->length);
+""" % dict(enum=enum_name(cls)))
+
+    out.write("""
+    return OF_ERROR_NONE;
+}
+""")
+
+def gen_new_fn_body(cls, out):
+    """
+    Generate function body for new function
+    @param cls The class name for the function
+    @param out The file to which to write
+    """
+
+    out.write("""
+/**
+ * \\defgroup %(cls)s %(cls)s
+ */
+""" % dict(cls=cls))
+
+    if not type_maps.class_is_virtual(cls):
+        gen_wire_push_fn(cls, out)
+
+    out.write("""
+/**
+ * Create a new %(cls)s object
+ *
+ * @param version The wire version to use for the object
+ * @return Pointer to the newly create object or NULL on error
+ *
+ * Initializes the new object with it's default fixed length associating
+ * a new underlying wire buffer.
+ *
+ * Use new_from_message to bind an existing message to a message object,
+ * or a _get function for non-message objects.
+ *
+ * \\ingroup %(cls)s
+ */
+
+%(cls)s_t *
+%(cls)s_new_(of_version_t version)
+{
+    %(cls)s_t *obj;
+    int bytes;
+
+    bytes = of_object_fixed_len[version][%(enum)s];
+
+    /* Allocate a maximum-length wire buffer assuming we'll be appending to it. */
+    if ((obj = (%(cls)s_t *)of_object_new(OF_WIRE_BUFFER_MAX_LENGTH)) == NULL) {
+        return NULL;
+    }
+
+    %(cls)s_init(obj, version, bytes, 0);
+""" % dict(cls=cls, enum=enum_name(cls)))
+    if not type_maps.class_is_virtual(cls):
+        out.write("""
+    if (%(cls)s_push_wire_values(obj) < 0) {
+        FREE(obj);
+        return NULL;
+    }
+""" % dict(cls=cls))
+
+    match_offset = v3_match_offset_get(cls)
+    if match_offset >= 0:
+        # Init length field for match object
+        out.write("""
+    /* Initialize match TLV for 1.2 */
+    /* FIXME: Check 1.3 below */
+    if ((version == OF_VERSION_1_2) || (version == OF_VERSION_1_3)) {
+        of_object_u16_set((of_object_t *)obj, %(match_offset)d + 2, 4);
+    }
+""" % dict(match_offset=match_offset))
+    out.write("""
+    return obj;
+}
+
+#if defined(OF_OBJECT_TRACKING)
+
+/*
+ * Tracking objects.  Call the new function and then record location
+ */
+
+%(cls)s_t *
+%(cls)s_new_tracking(of_version_t version,
+     const char *file, int line)
+{
+    %(cls)s_t *obj;
+
+    obj = %(cls)s_new_(version);
+    of_object_track((of_object_t *)obj, file, line);
+
+    return obj;
+}
+#endif
+""" % dict(cls=cls))
+
+
+def gen_from_message_fn_body(cls, out):
+    """
+    Generate function body for from_message function
+    @param cls The class name for the function
+    @param out The file to which to write
+    """
+    out.write("""
+/**
+ * Create a new %(cls)s object and bind it to an existing message
+ *
+ * @param msg The message to bind the new object to
+ * @return Pointer to the newly create object or NULL on error
+ *
+ * \ingroup %(cls)s
+ */
+
+%(cls)s_t *
+%(cls)s_new_from_message_(of_message_t msg)
+{
+    %(cls)s_t *obj = NULL;
+    of_version_t version;
+    int length;
+
+    if (msg == NULL) return NULL;
+
+    version = of_message_version_get(msg);
+    if (!OF_VERSION_OKAY(version)) return NULL;
+
+    length = of_message_length_get(msg);
+
+    if ((obj = (%(cls)s_t *)of_object_new(-1)) == NULL) {
+        return NULL;
+    }
+
+    %(cls)s_init(obj, version, 0, 0);
+
+    if ((of_object_buffer_bind((of_object_t *)obj, OF_MESSAGE_TO_BUFFER(msg),
+                               length, OF_MESSAGE_FREE_FUNCTION)) < 0) {
+       FREE(obj);
+       return NULL;
+    }
+    obj->length = length;
+    obj->version = version;
+
+    return obj;
+}
+
+#if defined(OF_OBJECT_TRACKING)
+
+/*
+ * Tracking objects.  Call the new function and then record location
+ */
+
+%(cls)s_t *
+%(cls)s_new_from_message_tracking(of_message_t msg,
+    const char *file, int line)
+{
+    %(cls)s_t *obj;
+
+    obj = %(cls)s_new_from_message_(msg);
+    of_object_track((of_object_t *)obj, file, line);
+
+    return obj;
+}
+#endif
+""" % dict(cls=cls))
+
+
+################################################################
+# Now the top level generator functions
+################################################################
+
+def gen_new_function_declarations(out):
+    """
+    Gerenate the header file declarations for new operators for all classes
+    @param out The file to which to write the decs
+    """
+
+    out.write("""
+/****************************************************************
+ *
+ * New operator declarations
+ *
+ * _new: Create a new object for writing; includes init
+ * _new_from_message: Create a new instance of the object and bind the
+ *    message data to the object
+ * _init: Initialize and optionally allocate buffer space for an
+ *    automatic instance
+ *
+ * _new and _from_message require a delete operation to be called
+ * on the object.
+ *
+ ****************************************************************/
+""")
+    out.write("""
+/*
+ * If object tracking is enabled, map "new" and "new from msg"
+ * calls to tracking versions; otherwise, directly to internal
+ * versions of fns which have the same name but end in _.
+ */
+
+#if defined(OF_OBJECT_TRACKING)
+""")
+    for cls in of_g.standard_class_order:
+        out.write("""
+extern %(cls)s_t *
+    %(cls)s_new_tracking(of_version_t version,
+        const char *file, int line);
+#define %(cls)s_new(version) \\
+    %(cls)s_new_tracking(version, \\
+        __FILE__, __LINE__)
+""" % dict(cls=cls))
+        if loxi_utils.class_is_message(cls):
+            out.write("""extern %(cls)s_t *
+    %(cls)s_new_from_message_tracking(of_message_t msg,
+        const char *file, int line);
+#define %(cls)s_new_from_message(msg) \\
+    %(cls)s_new_from_message_tracking(msg, \\
+        __FILE__, __LINE__)
+""" % dict(cls=cls))
+
+    out.write("""
+#else /* No object tracking */
+""")
+    for cls in of_g.standard_class_order:
+        out.write("""
+#define %(cls)s_new(version) \\
+    %(cls)s_new_(version)
+""" % dict(cls=cls))
+        if loxi_utils.class_is_message(cls):
+            out.write("""#define %(cls)s_new_from_message(msg) \\
+    %(cls)s_new_from_message_(msg)
+""" % dict(cls=cls))
+
+    out.write("""
+#endif /* Object tracking */
+""")
+
+    for cls in of_g.standard_class_order:
+        out.write("""
+extern %(cls)s_t *
+    %(cls)s_new_(of_version_t version);
+""" % dict(cls=cls))
+        if loxi_utils.class_is_message(cls):
+            out.write("""extern %(cls)s_t *
+    %(cls)s_new_from_message_(of_message_t msg);
+""" % dict(cls=cls))
+        out.write("""extern void %(cls)s_init(
+    %(cls)s_t *obj, of_version_t version, int bytes, int clean_wire);
+""" % dict(cls=cls))
+
+    out.write("""
+/****************************************************************
+ *
+ * Delete operator static inline definitions.
+ * These are here for type checking purposes only
+ *
+ ****************************************************************/
+""")
+    for cls in of_g.standard_class_order:
+#        if cls in type_maps.inheritance_map:
+#            continue
+        out.write("""
+/**
+ * Delete an object of type %(cls)s_t
+ * @param obj An instance of type %(cls)s_t
+ *
+ * \ingroup %(cls)s
+ */
+static inline void
+%(cls)s_delete(%(cls)s_t *obj) {
+    of_object_delete((of_object_t *)(obj));
+}
+""" % dict(cls=cls))
+
+    out.write("""
+typedef void (*of_object_init_f)(of_object_t *obj, of_version_t version,
+    int bytes, int clean_wire);
+extern of_object_init_f of_object_init_map[];
+""")
+
+    out.write("""
+/****************************************************************
+ *
+ * Function pointer initialization functions
+ * These are part of the "coerce" type casting for objects
+ *
+ ****************************************************************/
+""")
+
+#
+# @fixme Not clear that these should all be set for virtual fns
+#
+# @fixme Clean up.  should have a (language specific) map from class
+# to length and type get/set functions
+#
+
+def gen_coerce_ops(out, cls):
+    out.write("""
+    /* Set up the object's function pointers */
+""")
+
+    if loxi_utils.class_is_message(cls):
+        out.write("""
+    obj->wire_length_get = of_object_message_wire_length_get;
+    obj->wire_length_set = of_object_message_wire_length_set;
+""")
+    else:
+        if loxi_utils.class_is_tlv16(cls):
+            if not (cls in type_maps.inheritance_map): # Don't set for super
+                out.write("""
+    obj->wire_length_set = of_tlv16_wire_length_set;
+    obj->wire_type_set = of_tlv16_wire_object_id_set;\
+""")
+            out.write("""
+    obj->wire_length_get = of_tlv16_wire_length_get;
+""")
+            if loxi_utils.class_is_action(cls):
+                out.write("""
+    obj->wire_type_get = of_action_wire_object_id_get;
+""")
+            if loxi_utils.class_is_action_id(cls):
+                out.write("""
+    obj->wire_type_get = of_action_id_wire_object_id_get;
+""")
+            if loxi_utils.class_is_instruction(cls):
+                out.write("""
+    obj->wire_type_get = of_instruction_wire_object_id_get;
+""")
+            if loxi_utils.class_is_queue_prop(cls):
+                    out.write("""
+    obj->wire_type_get = of_queue_prop_wire_object_id_get;
+""")
+            if loxi_utils.class_is_table_feature_prop(cls):
+                    out.write("""
+    obj->wire_type_get = of_table_feature_prop_wire_object_id_get;
+""")
+            if loxi_utils.class_is_meter_band(cls):
+                    out.write("""
+    obj->wire_type_get = of_meter_band_wire_object_id_get;
+""")
+            if loxi_utils.class_is_hello_elem(cls):
+                    out.write("""
+    obj->wire_type_get = of_hello_elem_wire_object_id_get;
+""")
+        if loxi_utils.class_is_oxm(cls):
+            out.write("""
+    obj->wire_length_get = of_oxm_wire_length_get;
+    obj->wire_length_set = of_oxm_wire_length_set;
+    obj->wire_type_get = of_oxm_wire_object_id_get;
+    obj->wire_type_set = of_oxm_wire_object_id_set;
+""")
+        if loxi_utils.class_is_u16_len(cls):
+            out.write("""
+    obj->wire_length_get = of_u16_len_wire_length_get;
+    obj->wire_length_set = of_u16_len_wire_length_set;
+""")
+        if cls == "of_packet_queue":
+            out.write("""
+    obj->wire_length_get = of_packet_queue_wire_length_get;
+    obj->wire_length_set = of_packet_queue_wire_length_set;
+""")
+#        if cls == "of_list_meter_band_stats":
+#            out.write("""
+#    obj->wire_length_get = of_list_meter_band_stats_wire_length_get;
+#""")
+        if cls == "of_meter_stats":
+            out.write("""
+    obj->wire_length_get = of_meter_stats_wire_length_get;
+    obj->wire_length_set = of_meter_stats_wire_length_set;
+""")
+
+    if config_check("gen_fn_ptrs"):
+        if loxi_utils.class_is_list(cls):
+            out.write("""
+    obj->first = %(cls)s_first;
+    obj->next = %(cls)s_next;
+    obj->append = %(cls)s_append;
+    obj->append_bind = %(cls)s_append_bind;
+""" % dict(cls=cls))
+        else:
+            instantiate_fn_ptrs(cls, 4, out)
+
+def gen_new_function_definitions(out):
+    """
+    Generate the new operator for all classes
+
+    @param out The file to which to write the functions
+    """
+
+    out.write("\n/* New operators for each message class */\n")
+    for cls in of_g.standard_class_order:
+        out.write("\n/* New operators for %s */\n" % cls)
+        gen_new_fn_body(cls, out)
+        gen_init_fn_body(cls, out)
+        if loxi_utils.class_is_message(cls):
+            gen_from_message_fn_body(cls, out)
+
+def gen_init_map(out):
+    """
+    Generate map from object ID to type coerce function
+    """
+    out.write("""
+/**
+ * Map from object ID to type coerce function
+ */
+of_object_init_f of_object_init_map[] = {
+    (of_object_init_f)NULL,
+""")
+    count = 1
+    for i, cls in enumerate(of_g.standard_class_order):
+        if count != of_g.unified[cls]["object_id"]:
+            print "Error in class mapping: object IDs not sequential"
+            print cls, count, of_g.unified[cls]["object_id"]
+            sys.exit(1)
+        s = "(of_object_init_f)%s_init" % cls
+        if cls in type_maps.inheritance_map:
+            s = "(of_object_init_f)%s_header_init" % cls
+        if i < len(of_g.standard_class_order) - 1:
+            s += ","
+        out.write("    %-65s /* %d */\n" % (s, count))
+        count += 1
+    out.write("};\n")
+
+"""
+Document generation functions
+
+The main reason this is here is to generate documentation per
+accessor that indicates the versions that support the interface.
+"""
+
+
+def gen_accessor_doc(out, name):
+    """
+    Generate documentation for each accessor function that indicates
+    the versions supporting the accessor.
+    """
+
+    common_top_matter(out, name)
+
+    out.write("/* DOCUMENTATION ONLY */\n")
+
+    for cls in of_g.standard_class_order:
+        if cls in type_maps.inheritance_map:
+            pass # Check this
+
+        out.write("""
+/**
+ * Structure for %(cls)s object.  Get/set 
+ * accessors available in all versions unless noted otherwise
+ *
+""" % dict(cls=cls))
+        if loxi_utils.class_is_list(cls):
+            out.write("""\
+ * @param first Function of type %(cls)s_first_f.
+ * Setup a TBD class object to the first entry in the list
+ * @param next Function of type %(cls)s_next_f.
+ * Advance a TBD class object to the next entry in the list
+ * @param append_bind Function of type %(cls)s_append_bind_f
+ * Setup a TBD class object for append to the end of the current list
+ * @param append  Function of type @ref %(cls)s_append_f.
+ * Copy an item to the end of a list
+""" % dict(cls=cls))
+
+        for m_name in of_g.ordered_members[cls]:
+            if m_name in of_g.skip_members:
+                continue
+            ver_type_map = field_ver_get(cls, m_name)
+            (m_type, get_rv) = get_acc_rv(cls, m_name)
+            if len(ver_type_map) == 3:
+                # ver_string = "Available in all versions"
+                ver_string = ""
+            else:
+                ver_string = "("
+                for ver in sorted(ver_type_map):
+                    ver_string += " " + of_g.short_version_names[ver]
+                ver_string += ")."
+
+            f_name = acc_name(cls, m_name)
+            out.write("""\
+ * @param %(m_name)s_get/set %(ver_string)s
+ *   Accessors for %(m_name)s, a variable of type %(m_type)s.  Functions
+ *   are of type %(f_name)s_get_f and _set_f.
+ *
+""" % dict(f_name=f_name, m_name=m_name, ver_string=ver_string, m_type=m_type))
+
+        out.write("""\
+ */
+typedef struct %(cls)s_s %(cls)s_t;
+""" % dict(cls=cls))
+
+    out.write("#endif /* _LOCI_DOC_H_ */\n")
+
+################################################################
+#
+# For fun, here are some unified, traditional C structure representation
+#
+################################################################
+
+def gen_cof_to_wire(out):
+    pass
+
+def gen_wire_to_cof(out):
+    pass
+
+def gen_cof_instance(out, cls):
+    out.write("struct c%s_s {\n" % cls)
+    for m in of_g.ordered_members[cls]:
+        if m in of_g.skip_members:
+            continue
+        entry = of_g.unified[cls]["union"][m]
+        cof_type = type_to_cof_type(entry["m_type"])
+        out.write("    %-20s %s;\n" % (cof_type, m))
+    out.write("};\n\n");
+
+def gen_cof_structs(out):
+    """
+    Generate non-version specific (common) representation of structures
+
+    @param out The file to which to write the functions
+    """
+
+    out.write("\n/* Common, unified OpenFlow structure representations */\n")
+    for cls in of_g.standard_class_order:
+        if cls in type_maps.inheritance_map:
+            continue
+        gen_cof_instance(out, cls)
+
+################################################################
+#
+# Generate code samples for applications.
+#
+################################################################
+
+def gen_code_samples(out, name):
+    out.write("""
+#if 0 /* Do not compile in */
+/**
+ * @file %(name)s
+ *
+ * These are code samples for inclusion in other components
+ */
+
+""" % dict(name=name))
+
+    gen_jump_table_template(out)
+    # These are messages that a switch might expect.
+    msg_list = ["of_echo_request",
+                "of_hello",
+                "of_packet_in",
+                "of_packet_out",
+                "of_port_mod",
+                "of_port_stats_request",
+                "of_queue_get_config_request",
+                "of_queue_stats_request",
+                "of_flow_add",
+                "of_flow_modify",
+                "of_flow_modify_strict",
+                "of_flow_delete",
+                "of_flow_delete_strict",
+                "of_get_config_request",
+                "of_flow_stats_request",
+                "of_barrier_request",
+                "of_echo_reply",
+                "of_aggregate_stats_request",
+                "of_desc_stats_request",
+                "of_table_stats_request",
+                "of_features_request",
+                "of_table_mod",
+                "of_set_config",
+                "of_experimenter",
+                "of_experimenter_stats_request",
+                "of_group_desc_stats_request",
+                "of_group_features_stats_request",
+                "of_role_request"]
+
+    gen_message_handler_templates(out, msgs=msg_list)
+
+    out.write("""
+#endif
+""")
+
+def gen_jump_table_template(out=sys.stdout, all_unhandled=True,
+                            cxn_type="ls_cxn_handle_t", 
+                            unhandled="unhandled_message"):
+    """
+    Generate a template for a jump table.
+    @param out The file to which to write the functions
+    """
+    out.write("""
+/*
+ * Simple jump table definition for message handling
+ */
+typedef int (*msg_handler_f)(%(cxn_type)s cxn, of_object_t *obj);
+typedef msg_handler_f msg_jump_table_t[OF_MESSAGE_OBJECT_COUNT];
+
+/* Jump table template for message objects */
+extern msg_jump_table_t jump_table;
+
+/* C-code template */
+msg_jump_table_t jump_table = {
+    %(unhandled)s, /* OF_OBJECT; place holder for generic object  */
+""" % dict(unhandled=unhandled, cxn_type=cxn_type))
+    count = 0
+    fn_name = unhandled
+    for cls in of_g.ordered_messages:
+        comma = ","
+        count += 1
+        if count == len(of_g.ordered_messages):
+            comma = " "
+        if not all_unhandled:
+            fn_name = "%s_handler" % cls[3:]
+        out.write("    %s%s /* %s */\n" % (fn_name, comma, enum_name(cls)))
+            
+    out.write("};\n")
+
+def gen_message_switch_stmt_tmeplate(out=sys.stdout, all_unhandled=True,
+                                     cxn_type="ls_cxn_handle_t", 
+                                     unhandled="unhandled_message"):
+    out.write("""
+/*
+ * Simple switch statement for message handling
+ */
+
+    switch (obj->object_id):
+""")
+    fn_name = unhandled
+    for cls in of_g.ordered_messages:
+        if not all_unhandled:
+            fn_name = "%s_handler" % cls[3:]
+        out.write("""
+    case %(enum)s:
+        rv = %(fn_name)s(cxn, obj);
+        break;
+""" % dict(fn_name=fn_name, cls=cls, enum=enum_name(cls)))
+    out.write("""
+    default:
+        rv = LS_ERROR_PARAM;
+        break;
+    }
+
+    TRACE("Handled msg %p with rv %d (%s)", obj, rv, ls_error_strings[rv]);
+
+    return rv;
+""")
+
+
+def gen_message_handler_templates(out=sys.stdout, cxn_type="ls_cxn_handle_t",
+                                  unhandled="unhandled_message", msgs=None):
+    gen_jump_table_template(out, False, cxn_type)
+    out.write("""
+/**
+ * Function for unhandled message
+ */
+static int
+unhandled_message(%(cxn_type)s cxn, of_object_t *obj)
+{
+    (void)cxn;
+    (void)obj;
+    TRACE("Unhandled message %%p.  Object id %%d", obj, obj->object_id);
+
+    return LS_ERROR_UNAVAIL;
+}
+""" % dict(unhandled=unhandled, cxn_type=cxn_type))
+
+    if not msgs:
+        msgs = of_g.ordered_messages
+    for cls in msgs:
+        out.write("""
+/**
+ * Handle a %(s_cls)s message
+ * @param cxn Connection handler for the owning connection
+ * @param _obj Generic type object for the message to be coerced
+ * @returns Error code
+ */
+
+static int
+%(s_cls)s_handler(%(cxn_type)s cxn, of_object_t *_obj)
+{
+    %(cls)s_t *obj;
+
+    TRACE("Handling %(cls)s message: %%p.", obj);
+    obj = (%(cls)s_t *)_obj;
+
+    /* Handle object of type %(cls)s_t */
+
+    return LS_ERROR_NONE;
+}
+""" % dict(s_cls=cls[3:], cls=cls, cxn_type=cxn_type))
+    gen_message_switch_stmt_tmeplate(out, False, cxn_type)
+
+def gen_setup_from_add_fns(out):
+    """
+    Generate functions that setup up objects based on an add
+
+    Okay, this is getting out of hand.  We need to refactor the code
+    so that this can be done without so much pain.
+    """
+    out.write("""
+
+/* Flow stats entry setup for all versions */
+
+static int
+flow_stats_entry_setup_from_flow_add_common(of_flow_stats_entry_t *obj,
+                                            of_flow_add_t *flow_add,
+                                            of_object_t *effects,
+                                            int entry_match_offset,
+                                            int add_match_offset)
+{
+    of_list_action_t actions;
+    int entry_len, add_len;
+    of_wire_buffer_t *wbuf;
+    int abs_offset;
+    int delta;
+    uint16_t val16;
+    uint64_t cookie;
+    of_octets_t match_octets;
+
+    /* Effects may come from different places */
+    if (effects != NULL) {
+        OF_TRY(of_flow_stats_entry_actions_set(obj,
+               (of_list_action_t *)effects));
+    } else {
+        of_flow_add_actions_bind(flow_add, &actions);
+        OF_TRY(of_flow_stats_entry_actions_set(obj, &actions));
+    }
+
+    /* Transfer the match underlying object from add to stats entry */
+    wbuf = OF_OBJECT_TO_WBUF(obj);
+    entry_len = _WIRE_MATCH_PADDED_LEN(obj, entry_match_offset);
+    add_len = _WIRE_MATCH_PADDED_LEN(flow_add, add_match_offset);
+
+    match_octets.bytes = add_len;
+    match_octets.data = OF_OBJECT_BUFFER_INDEX(flow_add, add_match_offset);
+
+    /* Copy data into flow entry */
+    abs_offset = OF_OBJECT_ABSOLUTE_OFFSET(obj, entry_match_offset);
+    of_wire_buffer_replace_data(wbuf, abs_offset, entry_len,
+                                match_octets.data, add_len);
+
+    /* Not scalar, update lengths if needed */
+    delta = add_len - entry_len;
+    if (delta != 0) {
+        /* Update parent(s) */
+        of_object_parent_length_update((of_object_t *)obj, delta);
+    }
+
+    of_flow_add_cookie_get(flow_add, &cookie);
+    of_flow_stats_entry_cookie_set(obj, cookie);
+
+    of_flow_add_priority_get(flow_add, &val16);
+    of_flow_stats_entry_priority_set(obj, val16);
+
+    of_flow_add_idle_timeout_get(flow_add, &val16);
+    of_flow_stats_entry_idle_timeout_set(obj, val16);
+
+    of_flow_add_hard_timeout_get(flow_add, &val16);
+    of_flow_stats_entry_hard_timeout_set(obj, val16);
+
+    return OF_ERROR_NONE;
+}
+
+/* Flow removed setup for all versions */
+
+static int
+flow_removed_setup_from_flow_add_common(of_flow_removed_t *obj,
+                                        of_flow_add_t *flow_add,
+                                        int removed_match_offset,
+                                        int add_match_offset)
+{
+    int add_len, removed_len;
+    of_wire_buffer_t *wbuf;
+    int abs_offset;
+    int delta;
+    uint16_t val16;
+    uint64_t cookie;
+    of_octets_t match_octets;
+
+    /* Transfer the match underlying object from add to removed obj */
+    wbuf = OF_OBJECT_TO_WBUF(obj);
+    removed_len = _WIRE_MATCH_PADDED_LEN(obj, removed_match_offset);
+    add_len = _WIRE_MATCH_PADDED_LEN(flow_add, add_match_offset);
+
+    match_octets.bytes = add_len;
+    match_octets.data = OF_OBJECT_BUFFER_INDEX(flow_add, add_match_offset);
+
+    /* Copy data into flow removed */
+    abs_offset = OF_OBJECT_ABSOLUTE_OFFSET(obj, removed_match_offset);
+    of_wire_buffer_replace_data(wbuf, abs_offset, removed_len,
+                                match_octets.data, add_len);
+
+    /* Not scalar, update lengths if needed */
+    delta = add_len - removed_len;
+    if (delta != 0) {
+        /* Update parent(s) */
+        of_object_parent_length_update((of_object_t *)obj, delta);
+    }
+
+    of_flow_add_cookie_get(flow_add, &cookie);
+    of_flow_removed_cookie_set(obj, cookie);
+
+    of_flow_add_priority_get(flow_add, &val16);
+    of_flow_removed_priority_set(obj, val16);
+
+    of_flow_add_idle_timeout_get(flow_add, &val16);
+    of_flow_removed_idle_timeout_set(obj, val16);
+ 
+    if (obj->version >= OF_VERSION_1_2) {
+        of_flow_add_hard_timeout_get(flow_add, &val16);
+        of_flow_removed_hard_timeout_set(obj, val16);
+    }
+
+    return OF_ERROR_NONE;
+}
+
+/* Set up a flow removed message from the original add */
+
+int
+of_flow_removed_setup_from_flow_add(of_flow_removed_t *obj,
+                                    of_flow_add_t *flow_add)
+{
+    switch (obj->version) {
+    case OF_VERSION_1_0:
+        return flow_removed_setup_from_flow_add_common(obj, flow_add, 
+                                                       8, 8);
+        break;
+    case OF_VERSION_1_1:
+    case OF_VERSION_1_2:
+    case OF_VERSION_1_3:
+        return flow_removed_setup_from_flow_add_common(obj, flow_add, 
+                                                       48, 48);
+        break;
+    default:
+        return OF_ERROR_VERSION;
+        break;
+    }
+
+    return OF_ERROR_NONE;
+}
+
+
+/* Set up a packet in message from the original add */
+
+int
+of_packet_in_setup_from_flow_add(of_packet_in_t *obj,
+                                 of_flow_add_t *flow_add)
+{
+    int add_len, pkt_in_len;
+    of_wire_buffer_t *wbuf;
+    int abs_offset;
+    int delta;
+    const int pkt_in_match_offset = 16;
+    const int add_match_offset = 48;
+    of_octets_t match_octets;
+
+    if (obj->version < OF_VERSION_1_2) {
+        /* Nothing to be done before OF 1.2 */
+        return OF_ERROR_NONE;
+    }
+
+    /* Transfer match struct from flow add to packet in object */
+    wbuf = OF_OBJECT_TO_WBUF(obj);
+    pkt_in_len = _WIRE_MATCH_PADDED_LEN(obj, pkt_in_match_offset);
+    add_len = _WIRE_MATCH_PADDED_LEN(flow_add, add_match_offset);
+
+    match_octets.bytes = add_len;
+    match_octets.data = OF_OBJECT_BUFFER_INDEX(flow_add, add_match_offset);
+
+    /* Copy data into pkt_in msg */
+    abs_offset = OF_OBJECT_ABSOLUTE_OFFSET(obj, pkt_in_match_offset);
+    of_wire_buffer_replace_data(wbuf, abs_offset, pkt_in_len,
+                                match_octets.data, add_len);
+
+    /* Not scalar, update lengths if needed */
+    delta = add_len - pkt_in_len;
+    if (delta != 0) {
+        /* Update parent(s) */
+        of_object_parent_length_update((of_object_t *)obj, delta);
+    }
+
+    return OF_ERROR_NONE;
+}
+
+/* Set up a stats entry from the original add */
+
+int
+of_flow_stats_entry_setup_from_flow_add(of_flow_stats_entry_t *obj,
+                                        of_flow_add_t *flow_add,
+                                        of_object_t *effects)
+{
+    switch (obj->version) {
+    case OF_VERSION_1_0:
+        return flow_stats_entry_setup_from_flow_add_common(obj, flow_add,
+                                                           effects, 4, 8);
+        break;
+    case OF_VERSION_1_1:
+    case OF_VERSION_1_2:
+    case OF_VERSION_1_3:
+        return flow_stats_entry_setup_from_flow_add_common(obj, flow_add, 
+                                                           effects, 48, 48);
+        break;
+    default:
+        return OF_ERROR_VERSION;
+    }
+
+    return OF_ERROR_NONE;
+}
+""")
