diff --git a/pimgen.py b/pimgen.py
index 072f7d6..e5771d6 100755
--- a/pimgen.py
+++ b/pimgen.py
@@ -1,122 +1,295 @@
 #!/usr/bin/env python
 
+'''Phosphor Inventory Manager YAML parser and code generator.
+
+The parser workflow is broken down as follows:
+  1 - Import YAML files as native python type(s) instance(s).
+  2 - Create an instance of the Everything class from the
+        native python type instance(s) with the Everything.load
+        method.
+  3 - The Everything class constructor orchestrates conversion of the
+        native python type(s) instances(s) to render helper types.
+        Each render helper type constructor imports its attributes
+        from the native python type(s) instances(s).
+  4 - Present the converted YAML to the command processing method
+        requested by the script user.
+'''
+
 import sys
 import os
-import re
 import argparse
-import yaml
 import subprocess
-from mako.template import Template
-
-valid_c_name_pattern = re.compile('[\W_]+')
+import yaml
+import mako.lookup
+import sdbusplus.property
+from sdbusplus.namedelement import NamedElement
+from sdbusplus.renderer import Renderer
 
 
-def parse_event(e):
-    e['name'] = valid_c_name_pattern.sub('_', e['name']).lower()
-    if e.get('filter') is None:
-        e.setdefault('filter', {}).setdefault('type', 'none')
-    if e.get('action') is None:
-        e.setdefault('action', {}).setdefault('type', 'noop')
-    return e
+class Interface(list):
+    '''Provide various interface transformations.'''
+
+    def __init__(self, iface):
+        super(Interface, self).__init__(iface.split('.'))
+
+    def namespace(self):
+        '''Represent as an sdbusplus namespace.'''
+        return '::'.join(['sdbusplus'] + self[:-1] + ['server', self[-1]])
+
+    def header(self):
+        '''Represent as an sdbusplus server binding header.'''
+        return os.sep.join(self + ['server.hpp'])
+
+    def __str__(self):
+        return '.'.join(self)
 
 
-def get_interfaces(args):
-    interfaces_dir = os.path.join(args.inputdir, 'interfaces.d')
-    yaml_files = filter(
-        lambda x: x.endswith('.yaml'),
-        os.listdir(interfaces_dir))
+class Argument(sdbusplus.property.Property):
+    '''Bridge sdbusplus property typenames to syntatically correct c++.'''
 
-    interfaces = []
-    for x in yaml_files:
-        with open(os.path.join(interfaces_dir, x), 'r') as fd:
-            for i in yaml.load(fd.read()):
-                interfaces.append(i)
+    def __init__(self, **kw):
+        self.value = kw.pop('value')
+        super(Argument, self).__init__(**kw)
 
-    return interfaces
+    def cppArg(self):
+        '''Transform string types to c++ string constants.'''
+        if self.typeName == 'string':
+            return '"%s"' % self.value
+
+        return self.value
 
 
-def list_interfaces(args):
-    print ' '.join(get_interfaces(args))
+class MethodCall(NamedElement, Renderer):
+    '''Render syntatically correct c++ method calls.'''
+
+    def __init__(self, **kw):
+        self.namespace = kw.pop('namespace', [])
+        self.pointer = kw.pop('pointer', False)
+        self.args = \
+            [Argument(**x) for x in kw.pop('args', [])]
+        super(MethodCall, self).__init__(**kw)
+
+    def bare_method(self):
+        '''Provide the method name and encompassing
+        namespace without any arguments.'''
+        return '::'.join(self.namespace + [self.name])
 
 
-def generate_cpp(args):
-    # Aggregate all the event YAML in the events.d directory
-    # into a single list of events.
-    events_dir = os.path.join(args.inputdir, 'events.d')
-    yaml_files = filter(
-        lambda x: x.endswith('.yaml'),
-        os.listdir(events_dir))
+class Filter(MethodCall):
+    '''Provide common attributes for any filter.'''
 
-    events = []
-    for x in yaml_files:
-        with open(os.path.join(events_dir, x), 'r') as fd:
-            for e in yaml.load(fd.read()).get('events', {}):
-                events.append(parse_event(e))
+    def __init__(self, **kw):
+        kw['namespace'] = ['filters']
+        super(Filter, self).__init__(**kw)
 
-    # Aggregate all the interface YAML in the interfaces.d
-    # directory into a single list of interfaces.
-    template = os.path.join(script_dir, 'generated.mako.cpp')
-    t = Template(filename=template)
 
-    interfaces = get_interfaces(args)
+class Action(MethodCall):
+    '''Provide common attributes for any action.'''
 
-    # Render the template with the provided events and interfaces.
-    template = os.path.join(script_dir, 'generated.mako.cpp')
-    t = Template(filename=template)
-    with open(os.path.join(args.outputdir, 'generated.cpp'), 'w') as fd:
-        fd.write(
-            t.render(
-                interfaces=interfaces,
-                events=events))
+    def __init__(self, **kw):
+        kw['namespace'] = ['actions']
+        super(Action, self).__init__(**kw)
 
-    # Invoke sdbus++ to generate any extra interface bindings for
-    # extra interfaces that aren't defined externally.
-    yaml_files = []
-    extra_ifaces_dir = os.path.join(args.inputdir, 'extra_interfaces.d')
-    if os.path.exists(extra_ifaces_dir):
-        for directory, _, files in os.walk(extra_ifaces_dir):
-            if not files:
-                continue
 
-            yaml_files += map(
-                lambda f: os.path.relpath(
-                    os.path.join(directory, f),
-                    extra_ifaces_dir),
-                filter(lambda f: f.endswith('.interface.yaml'), files))
+class DbusSignature(NamedElement, Renderer):
+    '''Represent a dbus signal match signature.'''
 
-    genfiles = {
-        'server-cpp': lambda x: '%s.cpp' % (
-            x.replace(os.sep, '.')),
-        'server-header': lambda x: os.path.join(
-            os.path.join(
-                *x.split('.')), 'server.hpp')
+    def __init__(self, **kw):
+        self.sig = {x: y for x, y in kw.iteritems()}
+        kw.clear()
+        super(DbusSignature, self).__init__(**kw)
+
+
+class DestroyObject(Action):
+    '''Render a destroyObject action.'''
+
+    def __init__(self, **kw):
+        mapped = kw.pop('args')
+        kw['args'] = [
+            {'value': mapped['path'], 'type':'string'},
+        ]
+        super(DestroyObject, self).__init__(**kw)
+
+
+class NoopAction(Action):
+    '''Render a noop action.'''
+
+    def __init__(self, **kw):
+        kw['pointer'] = True
+        super(NoopAction, self).__init__(**kw)
+
+
+class NoopFilter(Filter):
+    '''Render a noop filter.'''
+
+    def __init__(self, **kw):
+        kw['pointer'] = True
+        super(NoopFilter, self).__init__(**kw)
+
+
+class PropertyChanged(Filter):
+    '''Render a propertyChanged filter.'''
+
+    def __init__(self, **kw):
+        mapped = kw.pop('args')
+        kw['args'] = [
+            {'value': mapped['interface'], 'type':'string'},
+            {'value': mapped['property'], 'type':'string'},
+            mapped['value']
+        ]
+        super(PropertyChanged, self).__init__(**kw)
+
+
+class Event(NamedElement, Renderer):
+    '''Render an inventory manager event.'''
+
+    action_map = {
+        'noop': NoopAction,
+        'destroyObject': DestroyObject,
     }
 
-    for i in yaml_files:
-        iface = i.replace('.interface.yaml', '').replace(os.sep, '.')
-        for process, f in genfiles.iteritems():
+    def __init__(self, **kw):
+        self.cls = kw.pop('type')
+        self.actions = \
+            [self.action_map[x['name']](**x)
+                for x in kw.pop('actions', [{'name': 'noop'}])]
+        super(Event, self).__init__(**kw)
 
-            dest = os.path.join(args.outputdir, f(iface))
-            parent = os.path.dirname(dest)
-            if parent and not os.path.exists(parent):
-                os.makedirs(parent)
 
-            with open(dest, 'w') as fd:
-                subprocess.call([
-                    'sdbus++',
-                    '-r',
-                    extra_ifaces_dir,
-                    'interface',
-                    process,
-                    iface],
-                    stdout=fd)
+class MatchEvent(Event):
+    '''Associate one or more dbus signal match signatures with
+    a filter.'''
+
+    filter_map = {
+        'none': NoopFilter,
+        'propertyChangedTo': PropertyChanged,
+    }
+
+    def __init__(self, **kw):
+        self.signatures = \
+            [DbusSignature(**x) for x in kw.pop('signatures', [])]
+        self.filters = \
+            [self.filter_map[x['name']](**x)
+                for x in kw.pop('filters', [{'name': 'none'}])]
+        super(MatchEvent, self).__init__(**kw)
+
+
+class Everything(Renderer):
+    '''Parse/render entry point.'''
+
+    class_map = {
+        'match': MatchEvent,
+    }
+
+    @staticmethod
+    def load(args):
+        # Invoke sdbus++ to generate any extra interface bindings for
+        # extra interfaces that aren't defined externally.
+        yaml_files = []
+        extra_ifaces_dir = os.path.join(args.inputdir, 'extra_interfaces.d')
+        if os.path.exists(extra_ifaces_dir):
+            for directory, _, files in os.walk(extra_ifaces_dir):
+                if not files:
+                    continue
+
+                yaml_files += map(
+                    lambda f: os.path.relpath(
+                        os.path.join(directory, f),
+                        extra_ifaces_dir),
+                    filter(lambda f: f.endswith('.interface.yaml'), files))
+
+        genfiles = {
+            'server-cpp': lambda x: '%s.cpp' % (
+                x.replace(os.sep, '.')),
+            'server-header': lambda x: os.path.join(
+                os.path.join(
+                    *x.split('.')), 'server.hpp')
+        }
+
+        for i in yaml_files:
+            iface = i.replace('.interface.yaml', '').replace(os.sep, '.')
+            for process, f in genfiles.iteritems():
+
+                dest = os.path.join(args.outputdir, f(iface))
+                parent = os.path.dirname(dest)
+                if parent and not os.path.exists(parent):
+                    os.makedirs(parent)
+
+                with open(dest, 'w') as fd:
+                    subprocess.call([
+                        'sdbus++',
+                        '-r',
+                        extra_ifaces_dir,
+                        'interface',
+                        process,
+                        iface],
+                        stdout=fd)
+
+        # Aggregate all the event YAML in the events.d directory
+        # into a single list of events.
+
+        events_dir = os.path.join(args.inputdir, 'events.d')
+        yaml_files = filter(
+            lambda x: x.endswith('.yaml'),
+            os.listdir(events_dir))
+
+        events = []
+        for x in yaml_files:
+            with open(os.path.join(events_dir, x), 'r') as fd:
+                for e in yaml.load(fd.read()).get('events', {}):
+                    events.append(e)
+
+        return Everything(
+            *events,
+            interfaces=Everything.get_interfaces(args))
+
+    @staticmethod
+    def get_interfaces(args):
+        '''Aggregate all the interface YAML in the interfaces.d
+        directory into a single list of interfaces.'''
+
+        interfaces_dir = os.path.join(args.inputdir, 'interfaces.d')
+        yaml_files = filter(
+            lambda x: x.endswith('.yaml'),
+            os.listdir(interfaces_dir))
+
+        interfaces = []
+        for x in yaml_files:
+            with open(os.path.join(interfaces_dir, x), 'r') as fd:
+                for i in yaml.load(fd.read()):
+                    interfaces.append(i)
+
+        return interfaces
+
+    def __init__(self, *a, **kw):
+        self.interfaces = \
+            [Interface(x) for x in kw.pop('interfaces', [])]
+        self.events = [
+            self.class_map[x['type']](**x) for x in a]
+        super(Everything, self).__init__(**kw)
+
+    def list_interfaces(self, *a):
+        print ' '.join([str(i) for i in self.interfaces])
+
+    def generate_cpp(self, loader):
+        '''Render the template with the provided events and interfaces.'''
+        with open(os.path.join(
+                args.outputdir,
+                'generated.cpp'), 'w') as fd:
+            fd.write(
+                self.render(
+                    loader,
+                    'generated.mako.cpp',
+                    events=self.events,
+                    interfaces=self.interfaces))
 
 
 if __name__ == '__main__':
     script_dir = os.path.dirname(os.path.realpath(__file__))
     valid_commands = {
         'generate-cpp': 'generate_cpp',
-        'list-interfaces': 'list_interfaces'}
+        'list-interfaces': 'list_interfaces'
+    }
 
     parser = argparse.ArgumentParser(
         description='Phosphor Inventory Manager (PIM) YAML '
@@ -134,8 +307,19 @@
         help='Command to run.')
 
     args = parser.parse_args()
-    function = getattr(sys.modules[__name__], valid_commands[args.command])
-    function(args)
+
+    if sys.version_info < (3, 0):
+        lookup = mako.lookup.TemplateLookup(
+            directories=[script_dir],
+            disable_unicode=True)
+    else:
+        lookup = mako.lookup.TemplateLookup(
+            directories=[script_dir])
+
+    function = getattr(
+        Everything.load(args),
+        valid_commands[args.command])
+    function(lookup)
 
 
 # vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4
