diff --git a/loxi_ir/ir.py b/loxi_ir/ir.py
new file mode 100644
index 0000000..21f760c
--- /dev/null
+++ b/loxi_ir/ir.py
@@ -0,0 +1,412 @@
+# 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.
+
+from itertools import chain
+import logging
+import re
+import sys
+
+from collections import namedtuple, OrderedDict
+from generic_utils import find, memoize, OrderedSet
+from loxi_ir import ir_offset
+
+logger = logging.getLogger(__name__)
+
+# This module is intended to be imported like this: from loxi_ir import *
+# All public names are prefixed with 'OF'.
+__all__ = [
+    'OFVersion',
+    'OFProtocol',
+    'OFClass',
+    'OFUnifiedClass',
+    'OFDataMember',
+    'OFTypeMember',
+    'OFDiscriminatorMember',
+    'OFLengthMember',
+    'OFFieldLengthMember',
+    'OFPadMember',
+    'OFEnum',
+    'OFEnumEntry'
+]
+
+"""
+One version of the OpenFlow protocol
+@param version Official dotted version number (e.g., "1.0", "1.3")
+@param wire_version Integer wire version (1 for 1.0, 4 for 1.3)
+"""
+class OFVersion(namedtuple("OFVersion", ("version", "wire_version"))):
+    @property
+    @memoize
+    def constant(self):
+        """ return this version as an uppercase string suitable
+            for use as a c constant, e.g., "VERSION_1_3"
+        """
+        return self.constant_version(prefix="VERSION_")
+
+    @property
+    @memoize
+    def short_constant(self):
+        """ return this version as an uppercase string suitable
+            for use as a c constant, e.g., "OF_"
+        """
+        return self.constant_version(prefix="OF_")
+
+    def constant_version(self, prefix="VERSION_"):
+        return prefix + self.version.replace(".", "_")
+
+    def __repr__(self):
+        return "OFVersion(%s)" % self.version
+
+    def __str__(self):
+        return self.version
+
+    def __cmp__(self, other):
+        return cmp(self.wire_version, other.wire_version)
+
+"""
+One version of the OpenFlow protocol
+
+Combination of multiple OFInput objects.
+
+@param wire_version
+@param classes List of OFClass objects
+@param enums List of Enum objects
+"""
+class OFProtocol(namedtuple('OFProtocol', ['version', 'classes', 'enums'])):
+    def __init__(self, version, classes, enums):
+        super(OFProtocol, self).__init__(self, version, classes, enums)
+        assert version is None or isinstance(version, OFVersion)
+
+    def class_by_name(self, name):
+        return find(lambda ofclass: ofclass.name == name, self.classes)
+
+    def enum_by_name(self, name):
+        return find(lambda enum: enum.name == name, self.enums)
+
+"""
+An OpenFlow class
+
+All compound objects like messages, actions, instructions, etc are
+uniformly represented by this class.
+
+The members are in the same order as on the wire.
+
+@param name
+@param superclass_name of this classes' super class
+@param members List of *Member objects
+@param params optional dictionary of parameters
+"""
+class OFClass(namedtuple('OFClass', ['name', 'superclass', 'members', 'virtual', 'params', 'is_fixed_length', 'base_length'])):
+    def __init__(self, *a, **kw):
+        super(OFClass, self).__init__(self, *a, **kw)
+        # Back reference will be added by assignment
+        self.protocol = None
+
+    def member_by_name(self, name):
+        return find(lambda m: hasattr(m, "name") and m.name == name, self.members)
+
+    @property
+    def discriminator(self):
+        return find(lambda m: type(m) == OFDiscriminatorMember, self.members)
+
+    def is_instanceof(self, super_class_name):
+        if self.name == super_class_name:
+            return True
+        elif self.superclass is None:
+            return False
+        else:
+            return self.superclass.is_instanceof(super_class_name)
+
+    def is_subclassof(self, super_class_name):
+        return self.name != super_class_name and self.is_instanceof(super_class_name)
+
+    @property
+    def is_message(self):
+        return self.is_instanceof("of_header")
+
+    @property
+    def is_oxm(self):
+        return self.is_instanceof("of_oxm")
+
+    @property
+    def is_action(self):
+        return self.is_instanceof("of_action")
+
+    @property
+    def is_action_id(self):
+        return self.is_instanceof("of_action_id")
+
+    @property
+    def is_instruction(self):
+        return self.is_instanceof("of_instruction")
+
+    def __hash__(self):
+        return hash((self.name, self.protocol.wire_version if self.protocol else None))
+
+    @property
+    def length(self):
+        if self.is_fixed_length:
+            return self.base_length
+        else:
+            raise Exception("Not a fixed length class: {}".self.name)
+
+""" one class unified across openflow versions. Keeps around a map version->versioned_class """
+class OFUnifiedClass(OFClass):
+    def __new__(cls, version_classes, *a, **kw):
+        return super(OFUnifiedClass, cls).__new__(cls, *a, **kw)
+
+    def __init__(self, version_classes, *a, **kw):
+        super(OFUnifiedClass, self).__init__(*a, **kw)
+        self.version_classes = version_classes
+
+    def class_by_version(version):
+        return self.version_classes[version]
+
+
+
+""" A mixin for member classes. Keeps around the back reference of_class (for assignment by
+    build_protocol, and additional methods shared across Members. """
+class MemberMixin(object):
+    def __init__(self, *a, **kw):
+        super(MemberMixin, self).__init__(*a, **kw)
+        # Back reference will be added by assignment in build_protocol below
+        self.of_class = None
+
+    @property
+    def length(self):
+        if self.is_fixed_length:
+            return self.base_length
+        else:
+            raise Exception("Not a fixed length member: {}.{} [{}]".format(
+                self.of_class.name,
+                self.name if hasattr("self", name) else "(unnnamed)",
+                type(self).__name__))
+
+"""
+Normal field
+
+@param name
+@param oftype C-like type string
+
+Example: packet_in.buffer_id
+"""
+class OFDataMember(namedtuple('OFDataMember', ['name', 'oftype', 'is_fixed_length', 'base_length', 'offset']), MemberMixin):
+    pass
+
+"""
+Field that declares that this is an abstract super-class and
+that the sub classes will be discriminated based on this field.
+E.g., 'type' is the discriminator member of the abstract superclass
+of_action.
+
+@param name
+"""
+class OFDiscriminatorMember (namedtuple('OFDiscriminatorMember', ['name', 'oftype', 'is_fixed_length', 'base_length', 'offset']), MemberMixin):
+    pass
+
+"""
+Field used to determine the type of an OpenFlow object
+
+@param name
+@param oftype C-like type string
+@param value Fixed type value
+
+Example: packet_in.type, flow_add._command
+"""
+class OFTypeMember (namedtuple('OFTypeMember', ['name', 'oftype', 'value', 'is_fixed_length', 'base_length', 'offset']), MemberMixin):
+    pass
+
+"""
+Field with the length of the containing object
+
+@param name
+@param oftype C-like type string
+
+Example: packet_in.length, action_output.len
+"""
+class OFLengthMember (namedtuple('OFLengthMember', ['name', 'oftype', 'is_fixed_length', 'base_length', 'offset']), MemberMixin):
+    pass
+
+"""
+Field with the length of another field in the containing object
+
+@param name
+@param oftype C-like type string
+@param field_name Peer field whose length this field contains
+
+Example: packet_out.actions_len (only usage)
+"""
+class OFFieldLengthMember (namedtuple('OFFieldLengthMember', ['name', 'oftype', 'field_name', 'is_fixed_length', 'base_length', 'offset']), MemberMixin):
+    pass
+
+"""
+Zero-filled padding
+
+@param length Length in bytes
+
+Example: packet_in.pad
+"""
+class OFPadMember (namedtuple('OFPadMember', ['pad_length', 'is_fixed_length', 'base_length', 'offset']), MemberMixin):
+    pass
+
+"""
+An OpenFlow enumeration
+
+All values are Python ints.
+
+@param name
+@param entries List of OFEnumEntry objects in input order
+@params dict of optional params. Currently defined:
+       - wire_type: the low_level type of the enum values (uint8,...)
+"""
+class OFEnum(namedtuple('OFEnum', ['name', 'entries', 'params'])):
+    def __init__(self, *a, **kw):
+        super(OFEnum, self).__init__(*a, **kw)
+        # Back reference will be added by assignment
+        self.protocol = None
+
+    @property
+    def values(self):
+        return [(e.name, e.value) for e in self.entries]
+
+    @property
+    def is_bitmask(self):
+        return "bitmask" in self.params and self.params['bitmask']
+
+    @property
+    def wire_type(self):
+        return self.params['wire_type'] if 'wire_type' in self.params else self.name
+
+class OFEnumEntry(namedtuple('OFEnumEntry', ['name', 'value', 'params'])):
+    def __init__(self, *a, **kw):
+        super(OFEnumEntry, self).__init__(*a, **kw)
+        # Back reference will be added by assignment
+        self.enum = None
+
+class RedefinedException(Exception):
+    pass
+
+class ClassNotFoundException(Exception):
+    pass
+
+class DependencyCycleException(Exception):
+    pass
+
+def build_protocol(version, ofinputs):
+    name_frontend_classes = OrderedDict()
+    name_frontend_enums = OrderedDict()
+
+    for ofinput in ofinputs:
+        for c in ofinput.classes:
+            name = c.name
+            if name in name_frontend_classes:
+                raise RedefinedException("Error parsing {}. Class {} redefined (already defined in {})"
+                        .format(ofinput.filename, name,
+                            name_frontend_classes[name][1].filename))
+            else:
+                name_frontend_classes[name] = (c, ofinput)
+        for e in ofinput.enums:
+            name = e.name
+            if name in name_frontend_enums:
+                raise RedefinedException("Error parsing {}. Enum {} redefined (already defined in {})"
+                        .format(ofinput.filename, name,
+                            name_frontend_enums[name][1].filename))
+            else:
+                name_frontend_enums[name] = (e, ofinput)
+
+    name_enums = {}
+    for fe, _ in name_frontend_enums.values():
+        entries = tuple(OFEnumEntry(name=e.name, value=e.value,
+                        params=e.params) for e in fe.entries)
+        enum = OFEnum(name=fe.name,
+                      entries=entries,
+                      params=fe.params)
+        for e in entries:
+            e.enum = enum
+        name_enums[enum.name] = enum
+
+    name_classes = OrderedDict()
+    build_touch_classes = OrderedSet()
+
+    def convert_member_properties(props):
+        return { name if name != "length" else "pad_length" : value for name, value in props.items() }
+
+    def build_member(of_class, fe_member, length_info):
+        ir_class = globals()[type(fe_member).__name__]
+        member = ir_class(offset = length_info.offset,
+                        base_length = length_info.base_length,
+                        is_fixed_length=length_info.is_fixed_length,
+                        **convert_member_properties(vars(fe_member)))
+        member.of_class = of_class
+        return member
+
+    def build_class(name):
+        if name in name_classes:
+            return name_classes[name]
+        if name in build_touch_classes:
+            raise DependencyCycleException( "Dependency cycle: {}"
+                    .format(" -> ".join(list(build_touch_classes) + [name])))
+        if not name in name_frontend_classes:
+            raise ClassNotFoundException("Class not found: {}".format(name))
+
+        build_touch_classes.add(name)
+
+        fe, _ = name_frontend_classes[name]
+
+        superclass = build_class(fe.superclass) if fe.superclass else None
+
+        # make sure members on which we depend are built first (for calc_length)
+        for m in fe.members:
+            if not hasattr(m, "oftype"):
+                continue
+            for m_name in re.sub(r'_t$', '', m.oftype), m.oftype:
+                logger.debug("Checking {}".format(m_name))
+                if m_name in name_frontend_classes:
+                    build_class(m_name)
+
+        base_length, is_fixed_length, member_lengths = \
+           ir_offset.calc_lengths(version, fe, name_classes, name_enums)
+
+        members = []
+        c = OFClass(name=fe.name, superclass=superclass,
+                members=members, virtual=fe.virtual, params=fe.params,
+                is_fixed_length=is_fixed_length, base_length=base_length)
+
+        members.extend( build_member(c, fe_member, member_lengths[fe_member])
+                  for fe_member in fe.members)
+
+        name_classes[name] = c
+        build_touch_classes.remove(name)
+        return c
+
+    for name in sorted(name_frontend_classes.keys()):
+        c = build_class(name)
+
+    protocol = OFProtocol(version=version, classes=tuple(name_classes.values()), enums=tuple(name_enums.values()))
+    for e in chain(protocol.classes, protocol.enums):
+        e.protocol = protocol
+    return protocol
