[virt-tools-list] [PATCH 01/47] Move all source & headers into osinfo/ directory

Daniel P. Berrange berrange at redhat.com
Wed Aug 25 19:36:56 UTC 2010


The GLib/GObject standard practice is to have all source and
header files in the same directory, named after the library
prefix. Move all headers from api/ and inc/ into src/, then
rename src/ to osinfo/

* src/*, api/*, inc/*: Move to osinfo/
* Makefile.am: Update build rules for changed locations
* configure.ac: change AC_CONFIG_SRCDIR
---
 Makefile.am                    |   48 +-
 api/osinfo.h                   |   17 -
 api/osinfo_db.h                |   87 ----
 api/osinfo_device.h            |   49 ---
 api/osinfo_devicelist.h        |   50 ---
 api/osinfo_entity.h            |   51 ---
 api/osinfo_filter.h            |   64 ---
 api/osinfo_hypervisor.h        |   52 ---
 api/osinfo_hypervisorlist.h    |   50 ---
 api/osinfo_list.h              |   51 ---
 api/osinfo_os.h                |   55 ---
 api/osinfo_oslist.h            |   51 ---
 configure.ac                   |    2 +-
 inc/osinfo_common.h            |  258 -----------
 osinfo/osinfo.h                |   17 +
 osinfo/osinfo_common.c         |  349 +++++++++++++++
 osinfo/osinfo_common.h         |  258 +++++++++++
 osinfo/osinfo_dataread.c       |  915 ++++++++++++++++++++++++++++++++++++++++
 osinfo/osinfo_db.c             |  555 ++++++++++++++++++++++++
 osinfo/osinfo_db.h             |   87 ++++
 osinfo/osinfo_device.c         |   94 ++++
 osinfo/osinfo_device.h         |   49 +++
 osinfo/osinfo_devicelist.c     |  121 ++++++
 osinfo/osinfo_devicelist.h     |   50 +++
 osinfo/osinfo_entity.c         |  321 ++++++++++++++
 osinfo/osinfo_entity.h         |   51 +++
 osinfo/osinfo_filter.c         |  298 +++++++++++++
 osinfo/osinfo_filter.h         |   64 +++
 osinfo/osinfo_hypervisor.c     |  122 ++++++
 osinfo/osinfo_hypervisor.h     |   52 +++
 osinfo/osinfo_hypervisorlist.c |  121 ++++++
 osinfo/osinfo_hypervisorlist.h |   50 +++
 osinfo/osinfo_list.c           |  219 ++++++++++
 osinfo/osinfo_list.h           |   51 +++
 osinfo/osinfo_os.c             |  402 ++++++++++++++++++
 osinfo/osinfo_os.h             |   55 +++
 osinfo/osinfo_oslist.c         |  121 ++++++
 osinfo/osinfo_oslist.h         |   51 +++
 src/osinfo_common.c            |  349 ---------------
 src/osinfo_dataread.c          |  915 ----------------------------------------
 src/osinfo_db.c                |  555 ------------------------
 src/osinfo_device.c            |   94 ----
 src/osinfo_devicelist.c        |  121 ------
 src/osinfo_entity.c            |  321 --------------
 src/osinfo_filter.c            |  298 -------------
 src/osinfo_hypervisor.c        |  122 ------
 src/osinfo_hypervisorlist.c    |  121 ------
 src/osinfo_list.c              |  219 ----------
 src/osinfo_os.c                |  402 ------------------
 src/osinfo_oslist.c            |  121 ------
 50 files changed, 4498 insertions(+), 4498 deletions(-)
 delete mode 100644 api/osinfo.h
 delete mode 100644 api/osinfo_db.h
 delete mode 100644 api/osinfo_device.h
 delete mode 100644 api/osinfo_devicelist.h
 delete mode 100644 api/osinfo_entity.h
 delete mode 100644 api/osinfo_filter.h
 delete mode 100644 api/osinfo_hypervisor.h
 delete mode 100644 api/osinfo_hypervisorlist.h
 delete mode 100644 api/osinfo_list.h
 delete mode 100644 api/osinfo_os.h
 delete mode 100644 api/osinfo_oslist.h
 delete mode 100644 inc/osinfo_common.h
 create mode 100644 osinfo/osinfo.h
 create mode 100644 osinfo/osinfo_common.c
 create mode 100644 osinfo/osinfo_common.h
 create mode 100644 osinfo/osinfo_dataread.c
 create mode 100644 osinfo/osinfo_db.c
 create mode 100644 osinfo/osinfo_db.h
 create mode 100644 osinfo/osinfo_device.c
 create mode 100644 osinfo/osinfo_device.h
 create mode 100644 osinfo/osinfo_devicelist.c
 create mode 100644 osinfo/osinfo_devicelist.h
 create mode 100644 osinfo/osinfo_entity.c
 create mode 100644 osinfo/osinfo_entity.h
 create mode 100644 osinfo/osinfo_filter.c
 create mode 100644 osinfo/osinfo_filter.h
 create mode 100644 osinfo/osinfo_hypervisor.c
 create mode 100644 osinfo/osinfo_hypervisor.h
 create mode 100644 osinfo/osinfo_hypervisorlist.c
 create mode 100644 osinfo/osinfo_hypervisorlist.h
 create mode 100644 osinfo/osinfo_list.c
 create mode 100644 osinfo/osinfo_list.h
 create mode 100644 osinfo/osinfo_os.c
 create mode 100644 osinfo/osinfo_os.h
 create mode 100644 osinfo/osinfo_oslist.c
 create mode 100644 osinfo/osinfo_oslist.h
 delete mode 100644 src/osinfo_common.c
 delete mode 100644 src/osinfo_dataread.c
 delete mode 100644 src/osinfo_db.c
 delete mode 100644 src/osinfo_device.c
 delete mode 100644 src/osinfo_devicelist.c
 delete mode 100644 src/osinfo_entity.c
 delete mode 100644 src/osinfo_filter.c
 delete mode 100644 src/osinfo_hypervisor.c
 delete mode 100644 src/osinfo_hypervisorlist.c
 delete mode 100644 src/osinfo_list.c
 delete mode 100644 src/osinfo_os.c
 delete mode 100644 src/osinfo_oslist.c

diff --git a/Makefile.am b/Makefile.am
index f424d4c..22acdcb 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -1,33 +1,33 @@
 
-AM_CPPFLAGS = -I$(top_srcdir)/inc -I$(top_srcdir)/api $(LIBXML_CFLAGS) $(GOBJECT_CFLAGS)
+AM_CPPFLAGS = -I$(top_srcdir) $(LIBXML_CFLAGS) $(GOBJECT_CFLAGS)
 libosinfo_la_LDFLAGS = $(LIBXML_LIBS) $(GOBJECT_LIBS)
 
 lib_LTLIBRARIES = libosinfo.la
 
 libosinfo_la_SOURCES =		\
-  api/osinfo_db.h		\
-  api/osinfo_device.h		\
-  api/osinfo_devicelist.h		\
-  api/osinfo_entity.h		\
-  api/osinfo_filter.h		\
-  api/osinfo_hypervisor.h		\
-  api/osinfo_hypervisorlist.h		\
-  api/osinfo_list.h		\
-  api/osinfo_os.h		\
-  api/osinfo_oslist.h		\
-  inc/osinfo_common.h		\
-  src/osinfo_common.c		\
-  src/osinfo_dataread.c		\
-  src/osinfo_device.c		\
-  src/osinfo_devicelist.c		\
-  src/osinfo_entity.c		\
-  src/osinfo_filter.c		\
-  src/osinfo_hypervisor.c	\
-  src/osinfo_hypervisorlist.c	\
-  src/osinfo_list.c	\
-  src/osinfo_oslist.c	\
-  src/osinfo_db.c			\
-  src/osinfo_os.c
+  osinfo/osinfo_db.h		\
+  osinfo/osinfo_device.h		\
+  osinfo/osinfo_devicelist.h		\
+  osinfo/osinfo_entity.h		\
+  osinfo/osinfo_filter.h		\
+  osinfo/osinfo_hypervisor.h		\
+  osinfo/osinfo_hypervisorlist.h		\
+  osinfo/osinfo_list.h		\
+  osinfo/osinfo_os.h		\
+  osinfo/osinfo_oslist.h		\
+  osinfo/osinfo_common.h		\
+  osinfo/osinfo_common.c		\
+  osinfo/osinfo_dataread.c		\
+  osinfo/osinfo_device.c		\
+  osinfo/osinfo_devicelist.c		\
+  osinfo/osinfo_entity.c		\
+  osinfo/osinfo_filter.c		\
+  osinfo/osinfo_hypervisor.c	\
+  osinfo/osinfo_hypervisorlist.c	\
+  osinfo/osinfo_list.c	\
+  osinfo/osinfo_oslist.c	\
+  osinfo/osinfo_db.c			\
+  osinfo/osinfo_os.c
 
 check_PROGRAMS =			\
   test/test-skeleton
diff --git a/api/osinfo.h b/api/osinfo.h
deleted file mode 100644
index 63a06e4..0000000
--- a/api/osinfo.h
+++ /dev/null
@@ -1,17 +0,0 @@
-#ifndef __OSINFO_H__
-#define __OSINFO_H__
-
-#include <glib-object.h>
-#include <osinfo_common.h>
-#include <osinfo_db.h>
-#include <osinfo_entity.h>
-#include <osinfo_device.h>
-#include <osinfo_os.h>
-#include <osinfo_hypervisor.h>
-#include <osinfo_filter.h>
-#include <osinfo_list.h>
-#include <osinfo_devicelist.h>
-#include <osinfo_oslist.h>
-#include <osinfo_hypervisorlist.h>
-
-#endif
diff --git a/api/osinfo_db.h b/api/osinfo_db.h
deleted file mode 100644
index 305ed29..0000000
--- a/api/osinfo_db.h
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
- * libosinfo
- *
- * osinfo_db.h
- * Represents the main entry point to data contained by libosinfo.
- */
-
-#ifndef __OSINFO_DB_H__
-#define __OSINFO_DB_H__
-
-#include "osinfo_devicelist.h"
-#include "osinfo_hypervisorlist.h"
-#include "osinfo_oslist.h"
-
-/*
- * Type macros.
- */
-#define OSINFO_TYPE_DB                  (osinfo_db_get_type ())
-#define OSINFO_DB(obj)                  (G_TYPE_CHECK_INSTANCE_CAST ((obj), OSINFO_TYPE_DB, OsinfoDb))
-#define OSINFO_IS_DB(obj)               (G_TYPE_CHECK_INSTANCE_TYPE ((obj), OSINFO_TYPE_DB))
-#define OSINFO_DB_CLASS(klass)          (G_TYPE_CHECK_CLASS_CAST ((klass), OSINFO_TYPE_DB, OsinfoDbClass))
-#define OSINFO_IS_DB_CLASS(klass)       (G_TYPE_CHECK_CLASS_TYPE ((klass), OSINFO_TYPE_DB))
-#define OSINFO_DB_GET_CLASS(obj)        (G_TYPE_INSTANCE_GET_CLASS ((obj), OSINFO_TYPE_DB, OsinfoDbClass))
-
-//typedef struct _OsinfoDb        OsinfoDb;
-// (defined in osinfo_objects.h)
-
-typedef struct _OsinfoDbClass   OsinfoDbClass;
-
-typedef struct _OsinfoDbPrivate OsinfoDbPrivate;
-
-/*
- * To get a db handle, we construct one with a construct-time only
- * backing data directory. It is already considered to be initialized
- * on return from the constructor, and ready to do work.
- *
- * To close it, we call the destructor on it.
- * Setting parameters on it will work if it's not a construct-time only
- * parameter. Reading will always work. Currently the backing directory and
- * libvirt version are the only parameters.
- *
- * The db object contains information related to three main classes of
- * objects: hypervisors, operating systems and devices.
- */
-
-/* object */
-struct _OsinfoDb
-{
-    GObject parent_instance;
-
-    /* public */
-
-    /* private */
-    OsinfoDbPrivate *priv;
-};
-
-/* class */
-struct _OsinfoDbClass
-{
-    GObjectClass parent_class;
-
-    /* class members */
-};
-
-int osinfoInitializeDb(OsinfoDb *self, GError **err);
-
-OsinfoHypervisor *osinfoGetHypervisorById(OsinfoDb *self, gchar *hvId, GError **err);
-OsinfoDevice *osinfoGetDeviceById(OsinfoDb *self, gchar *devId, GError **err);
-OsinfoOs *osinfoGetOsById(OsinfoDb *self, gchar *osId, GError **err);
-
-OsinfoOsList *osinfoGetOsList(OsinfoDb *self, OsinfoFilter *filter, GError **err);
-OsinfoHypervisorList *osinfoGetHypervisorList(OsinfoDb *self, OsinfoFilter *filter, GError **err);
-OsinfoDeviceList *osinfoGetDeviceList(OsinfoDb *self, OsinfoFilter *filter, GError **err);
-
-// Get me all unique values for property "vendor" among operating systems
-GPtrArray *osinfoUniqueValuesForPropertyInOs(OsinfoDb *self, gchar *propName, GError **err);
-
-// Get me all unique values for property "vendor" among hypervisors
-GPtrArray *osinfoUniqueValuesForPropertyInHv(OsinfoDb *self, gchar *propName, GError **err);
-
-// Get me all unique values for property "vendor" among devices
-GPtrArray *osinfoUniqueValuesForPropertyInDev(OsinfoDb *self, gchar *propName, GError **err);
-
-// Get me all OSes that 'upgrade' another OS (or whatever relationship is specified)
-OsinfoOsList *osinfoUniqueValuesForOsRelationship(OsinfoDb *self, osinfoRelationship relshp, GError **err);
-
-#endif /* __OSINFO_DB_H__ */
diff --git a/api/osinfo_device.h b/api/osinfo_device.h
deleted file mode 100644
index 9f10e6b..0000000
--- a/api/osinfo_device.h
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * libosinfo
- *
- * osinfo_device.h
- * Represents a device in libosinfo.
- */
-
-#ifndef __OSINFO_DEVICE_H__
-#define __OSINFO_DEVICE_H__
-
-/*
- * Type macros.
- */
-#define OSINFO_TYPE_DEVICE                  (osinfo_device_get_type ())
-#define OSINFO_DEVICE(obj)                  (G_TYPE_CHECK_INSTANCE_CAST ((obj), OSINFO_TYPE_DEVICE, OsinfoDevice))
-#define OSINFO_IS_DEVICE(obj)               (G_TYPE_CHECK_INSTANCE_TYPE ((obj), OSINFO_TYPE_DEVICE))
-#define OSINFO_DEVICE_CLASS(klass)          (G_TYPE_CHECK_CLASS_CAST ((klass), OSINFO_TYPE_DEVICE, OsinfoDeviceClass))
-#define OSINFO_IS_DEVICE_CLASS(klass)       (G_TYPE_CHECK_CLASS_TYPE ((klass), OSINFO_TYPE_DEVICE))
-#define OSINFO_DEVICE_GET_CLASS(obj)        (G_TYPE_INSTANCE_GET_CLASS ((obj), OSINFO_TYPE_DEVICE, OsinfoDeviceClass))
-
-//typedef struct _OsinfoDevice        OsinfoDevice;
-// (defined in osinfo_objects.h)
-
-typedef struct _OsinfoDeviceClass   OsinfoDeviceClass;
-
-typedef struct _OsinfoDevicePrivate OsinfoDevicePrivate;
-
-/* object */
-struct _OsinfoDevice
-{
-    OsinfoEntity parent_instance;
-
-    /* public */
-
-    /* private */
-    OsinfoDevicePrivate *priv;
-};
-
-/* class */
-struct _OsinfoDeviceClass
-{
-    OsinfoEntityClass parent_class;
-
-    /* class members */
-};
-
-gchar *osinfoGetDeviceDriver(OsinfoDevice *self, gchar *devType, OsinfoOs *os, OsinfoHypervisor *hv, GError **err);
-
-#endif /* __OSINFO_DEVICE_H__ */
diff --git a/api/osinfo_devicelist.h b/api/osinfo_devicelist.h
deleted file mode 100644
index 49e2715..0000000
--- a/api/osinfo_devicelist.h
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * libosinfo
- *
- * osinfo_devicelist.h
- */
-
-#ifndef __OSINFO_DEVICELIST_H__
-#define __OSINFO_DEVICELIST_H__
-
-/*
- * Type macros.
- */
-#define OSINFO_TYPE_DEVICELIST                  (osinfo_devicelist_get_type ())
-#define OSINFO_DEVICELIST(obj)                  (G_TYPE_CHECK_INSTANCE_CAST ((obj), OSINFO_TYPE_DEVICELIST, OsinfoDeviceList))
-#define OSINFO_IS_DEVICELIST(obj)               (G_TYPE_CHECK_INSTANCE_TYPE ((obj), OSINFO_TYPE_DEVICELIST))
-#define OSINFO_DEVICELIST_CLASS(klass)          (G_TYPE_CHECK_CLASS_CAST ((klass), OSINFO_TYPE_DEVICELIST, OsinfoDeviceListClass))
-#define OSINFO_IS_DEVICELIST_CLASS(klass)       (G_TYPE_CHECK_CLASS_TYPE ((klass), OSINFO_TYPE_DEVICELIST))
-#define OSINFO_DEVICELIST_GET_CLASS(obj)        (G_TYPE_INSTANCE_GET_CLASS ((obj), OSINFO_TYPE_DEVICELIST, OsinfoDeviceListClass))
-
-typedef struct _OsinfoDeviceList        OsinfoDeviceList;
-
-typedef struct _OsinfoDeviceListClass   OsinfoDeviceListClass;
-
-typedef struct _OsinfoDeviceListPrivate OsinfoDeviceListPrivate;
-
-/* object */
-struct _OsinfoDeviceList
-{
-    GObject parent_instance;
-
-    /* public */
-
-    /* private */
-    OsinfoDeviceListPrivate *priv;
-};
-
-/* class */
-struct _OsinfoDeviceListClass
-{
-    GObjectClass parent_class;
-
-    /* class members */
-};
-
-OsinfoDeviceList *osinfoDeviceListFilter(OsinfoDeviceList *self, OsinfoFilter *filter, GError **err);
-OsinfoDevice *osinfoGetDeviceAtIndex(OsinfoDeviceList *self, gint idx, GError **err);
-OsinfoDeviceList *osinfoDeviceListIntersect(OsinfoDeviceList *self, OsinfoDeviceList *otherDeviceList, GError **err);
-OsinfoDeviceList *osinfoDeviceListUnion(OsinfoDeviceList *self, OsinfoDeviceList *otherDeviceList, GError **err);
-
-#endif /* __OSINFO_DEVICELIST_H__ */
diff --git a/api/osinfo_entity.h b/api/osinfo_entity.h
deleted file mode 100644
index 0c8047c..0000000
--- a/api/osinfo_entity.h
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * libosinfo
- *
- * osinfo_entity.h
- * All entities represented in libosinfo are derived from this class.
- */
-
-#ifndef __OSINFO_ENTITY_H__
-#define __OSINFO_ENTITY_H__
-
-/*
- * Type macros.
- */
-#define OSINFO_TYPE_ENTITY                  (osinfo_entity_get_type ())
-#define OSINFO_ENTITY(obj)                  (G_TYPE_CHECK_INSTANCE_CAST ((obj), OSINFO_TYPE_ENTITY, OsinfoEntity))
-#define OSINFO_IS_ENTITY(obj)               (G_TYPE_CHECK_INSTANCE_TYPE ((obj), OSINFO_TYPE_ENTITY))
-#define OSINFO_ENTITY_CLASS(klass)          (G_TYPE_CHECK_CLASS_CAST ((klass), OSINFO_TYPE_ENTITY, OsinfoEntityClass))
-#define OSINFO_IS_ENTITY_CLASS(klass)       (G_TYPE_CHECK_CLASS_TYPE ((klass), OSINFO_TYPE_ENTITY))
-#define OSINFO_ENTITY_GET_CLASS(obj)        (G_TYPE_INSTANCE_GET_CLASS ((obj), OSINFO_TYPE_ENTITY, OsinfoEntityClass))
-
-typedef struct _OsinfoEntity        OsinfoEntity;
-
-typedef struct _OsinfoEntityClass   OsinfoEntityClass;
-
-typedef struct _OsinfoEntityPrivate OsinfoEntityPrivate;
-
-/* object */
-struct _OsinfoEntity
-{
-    GObject parent_instance;
-
-    /* public */
-
-    /* private */
-    OsinfoEntityPrivate *priv;
-};
-
-/* class */
-struct _OsinfoEntityClass
-{
-    GObjectClass parent_class;
-
-    /* class members */
-};
-
-gchar *osinfoGetId(OsinfoEntity *self, GError **err);
-GPtrArray *osinfoGetParams(OsinfoEntity *self, GError **err);
-gchar *osinfoGetParamValue(OsinfoEntity *self, gchar *key, GError **err);
-GPtrArray *osinfoGetParamAllValues(OsinfoEntity *self, gchar *key, GError **err);
-
-#endif /* __OSINFO_ENTITY_H__ */
diff --git a/api/osinfo_filter.h b/api/osinfo_filter.h
deleted file mode 100644
index 9a60fcd..0000000
--- a/api/osinfo_filter.h
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * libosinfo
- *
- * osinfo_filter.h
- * Represents a filter in libosinfo.
- */
-
-#ifndef __OSINFO_FILTER_H__
-#define __OSINFO_FILTER_H__
-
-/*
- * Type macros.
- */
-#define OSINFO_TYPE_FILTER                  (osinfo_filter_get_type ())
-#define OSINFO_FILTER(obj)                  (G_TYPE_CHECK_INSTANCE_CAST ((obj), OSINFO_TYPE_FILTER, OsinfoFilter))
-#define OSINFO_IS_FILTER(obj)               (G_TYPE_CHECK_INSTANCE_TYPE ((obj), OSINFO_TYPE_FILTER))
-#define OSINFO_FILTER_CLASS(klass)          (G_TYPE_CHECK_CLASS_CAST ((klass), OSINFO_TYPE_FILTER, OsinfoFilterClass))
-#define OSINFO_IS_FILTER_CLASS(klass)       (G_TYPE_CHECK_CLASS_TYPE ((klass), OSINFO_TYPE_FILTER))
-#define OSINFO_FILTER_GET_CLASS(obj)        (G_TYPE_INSTANCE_GET_CLASS ((obj), OSINFO_TYPE_FILTER, OsinfoFilterClass))
-
-//typedef struct _OsinfoFilter        OsinfoFilter;
-// (defined in osinfo_objects.h)
-
-#include "osinfo_oslist.h"
-
-typedef struct _OsinfoFilterClass  OsinfoFilterClass;
-
-typedef struct _OsinfoFilterPrivate OsinfoFilterPrivate;
-
-/* object */
-struct _OsinfoFilter
-{
-    OsinfoEntity parent_instance;
-
-    /* public */
-
-    /* private */
-    OsinfoFilterPrivate *priv;
-};
-
-/* class */
-struct _OsinfoFilterClass
-{
-    OsinfoEntityClass parent_class;
-
-    /* class members */
-};
-
-void osinfoFreeFilter(OsinfoFilter *self);
-
-gint osinfoAddFilterContstraint(OsinfoFilter *self, gchar *propName, gchar *propVal, GError **err);
-
-// Only applicable to OSes, ignored by other types of objects
-gint osinfoAddRelationConstraint(OsinfoFilter *self, osinfoRelationship relshp, OsinfoOs *os, GError **err);
-
-void osinfoClearFilterConstraint(OsinfoFilter *self, gchar *propName);
-void osinfoClearRelationshipConstraint(OsinfoFilter *self, osinfoRelationship relshp);
-void osinfoClearAllFilterConstraints(OsinfoFilter *self);
-
-GPtrArray *osinfoGetFilterConstraintKeys(OsinfoFilter *self, GError **err);
-gchar *osinfoGetFilterConstraintValue(OsinfoFilter *self, GError **err);
-OsinfoOsList *osinfoGetRelationshipConstraintValue(OsinfoFilter *self, osinfoRelationship relshp, GError **err);
-
-#endif /* __OSINFO_FILTER_H__ */
diff --git a/api/osinfo_hypervisor.h b/api/osinfo_hypervisor.h
deleted file mode 100644
index 65c78dc..0000000
--- a/api/osinfo_hypervisor.h
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * libosinfo
- *
- * osinfo_hypervisor.h
- * Represents a hypervisor in libosinfo.
- */
-
-#ifndef __OSINFO_HYPERVISOR_H__
-#define __OSINFO_HYPERVISOR_H__
-
-#include "osinfo_devicelist.h"
-
-/*
- * Type macros.
- */
-#define OSINFO_TYPE_HYPERVISOR                  (osinfo_hypervisor_get_type ())
-#define OSINFO_HYPERVISOR(obj)                  (G_TYPE_CHECK_INSTANCE_CAST ((obj), OSINFO_TYPE_HYPERVISOR, OsinfoHypervisor))
-#define OSINFO_IS_HYPERVISOR(obj)               (G_TYPE_CHECK_INSTANCE_TYPE ((obj), OSINFO_TYPE_HYPERVISOR))
-#define OSINFO_HYPERVISOR_CLASS(klass)          (G_TYPE_CHECK_CLASS_CAST ((klass), OSINFO_TYPE_HYPERVISOR, OsinfoHypervisorClass))
-#define OSINFO_IS_HYPERVISOR_CLASS(klass)       (G_TYPE_CHECK_CLASS_TYPE ((klass), OSINFO_TYPE_HYPERVISOR))
-#define OSINFO_HYPERVISOR_GET_CLASS(obj)        (G_TYPE_INSTANCE_GET_CLASS ((obj), OSINFO_TYPE_HYPERVISOR, OsinfoHypervisorClass))
-
-//typedef struct _OsinfoHypervisor        OsinfoHypervisor;
-// (defined in osinfo_objects.h)
-
-typedef struct _OsinfoHypervisorClass   OsinfoHypervisorClass;
-
-typedef struct _OsinfoHypervisorPrivate OsinfoHypervisorPrivate;
-
-/* object */
-struct _OsinfoHypervisor
-{
-    OsinfoEntity parent_instance;
-
-    /* public */
-
-    /* private */
-    OsinfoHypervisorPrivate *priv;
-};
-
-/* class */
-struct _OsinfoHypervisorClass
-{
-    OsinfoEntityClass parent_class;
-
-    /* class members */
-};
-
-GPtrArray *osinfoGetHypervisorDeviceTypes(OsinfoHypervisor *self, GError **err);
-OsinfoDeviceList *osinfoGetHypervisorDevicesByType(OsinfoHypervisor *self, gchar *devType, OsinfoFilter *filter, GError **err);
-
-#endif /* __OSINFO_HYPERVISOR_H__ */
diff --git a/api/osinfo_hypervisorlist.h b/api/osinfo_hypervisorlist.h
deleted file mode 100644
index bdc7f03..0000000
--- a/api/osinfo_hypervisorlist.h
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * libosinfo
- *
- * osinfo_hypervisorlist.h
- */
-
-#ifndef __OSINFO_HYPERVISORLIST_H__
-#define __OSINFO_HYPERVISORLIST_H__
-
-/*
- * Type macros.
- */
-#define OSINFO_TYPE_HYPERVISORLIST                  (osinfo_hypervisorlist_get_type ())
-#define OSINFO_HYPERVISORLIST(obj)                  (G_TYPE_CHECK_INSTANCE_CAST ((obj), OSINFO_TYPE_HYPERVISORLIST, OsinfoHypervisorList))
-#define OSINFO_IS_HYPERVISORLIST(obj)               (G_TYPE_CHECK_INSTANCE_TYPE ((obj), OSINFO_TYPE_HYPERVISORLIST))
-#define OSINFO_HYPERVISORLIST_CLASS(klass)          (G_TYPE_CHECK_CLASS_CAST ((klass), OSINFO_TYPE_HYPERVISORLIST, OsinfoHypervisorListClass))
-#define OSINFO_IS_HYPERVISORLIST_CLASS(klass)       (G_TYPE_CHECK_CLASS_TYPE ((klass), OSINFO_TYPE_HYPERVISORLIST))
-#define OSINFO_HYPERVISORLIST_GET_CLASS(obj)        (G_TYPE_INSTANCE_GET_CLASS ((obj), OSINFO_TYPE_HYPERVISORLIST, OsinfoHypervisorListClass))
-
-typedef struct _OsinfoHypervisorList        OsinfoHypervisorList;
-
-typedef struct _OsinfoHypervisorListClass   OsinfoHypervisorListClass;
-
-typedef struct _OsinfoHypervisorListPrivate OsinfoHypervisorListPrivate;
-
-/* object */
-struct _OsinfoHypervisorList
-{
-    GObject parent_instance;
-
-    /* public */
-
-    /* private */
-    OsinfoHypervisorListPrivate *priv;
-};
-
-/* class */
-struct _OsinfoHypervisorListClass
-{
-    GObjectClass parent_class;
-
-    /* class members */
-};
-
-OsinfoHypervisorList *osinfoHypervisorListFilter(OsinfoHypervisorList *self, OsinfoFilter *filter, GError **err);
-OsinfoHypervisor *osinfoGetHypervisorAtIndex(OsinfoHypervisorList *self, gint idx, GError **err);
-OsinfoHypervisorList *osinfoHypervisorListIntersect(OsinfoHypervisorList *self, OsinfoHypervisorList *otherHypervisorList, GError **err);
-OsinfoHypervisorList *osinfoHypervisorListUnion(OsinfoHypervisorList *self, OsinfoHypervisorList *otherHypervisorList, GError **err);
-
-#endif /* __OSINFO_HYPERVISORLIST_H__ */
diff --git a/api/osinfo_list.h b/api/osinfo_list.h
deleted file mode 100644
index 81a2bc7..0000000
--- a/api/osinfo_list.h
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * libosinfo
- *
- * osinfo_list.h
- */
-
-#ifndef __OSINFO_LIST_H__
-#define __OSINFO_LIST_H__
-
-/*
- * Type macros.
- */
-#define OSINFO_TYPE_LIST                  (osinfo_list_get_type ())
-#define OSINFO_LIST(obj)                  (G_TYPE_CHECK_INSTANCE_CAST ((obj), OSINFO_TYPE_LIST, OsinfoList))
-#define OSINFO_IS_LIST(obj)               (G_TYPE_CHECK_INSTANCE_TYPE ((obj), OSINFO_TYPE_LIST))
-#define OSINFO_LIST_CLASS(klass)          (G_TYPE_CHECK_CLASS_CAST ((klass), OSINFO_TYPE_LIST, OsinfoListClass))
-#define OSINFO_IS_LIST_CLASS(klass)       (G_TYPE_CHECK_CLASS_TYPE ((klass), OSINFO_TYPE_LIST))
-#define OSINFO_LIST_GET_CLASS(obj)        (G_TYPE_INSTANCE_GET_CLASS ((obj), OSINFO_TYPE_LIST, OsinfoListClass))
-
-typedef struct _OsinfoListClass   OsinfoListClass;
-
-typedef struct _OsinfoListPrivate OsinfoListPrivate;
-
-/* object */
-struct _OsinfoList
-{
-    GObject parent_instance;
-
-    /* public */
-
-    /* private */
-    OsinfoListPrivate *priv;
-};
-
-/* class */
-struct _OsinfoListClass
-{
-    GObjectClass parent_class;
-
-    /* class members */
-};
-
-void osinfoFreeList(OsinfoList *self);
-gint osinfoListLength(OsinfoList *self);
-
-OsinfoList *osinfoListFilter(OsinfoList *self, OsinfoFilter *filter, GError **err);
-OsinfoEntity *osinfoGetEntityAtIndex(OsinfoList *self, gint idx);
-OsinfoList *osinfoListIntersect(OsinfoList *self, OsinfoList *otherList, GError **err);
-OsinfoList *osinfoListUnion(OsinfoList *self, OsinfoList *otherList, GError **err);
-
-#endif /* __OSINFO_LIST_H__ */
diff --git a/api/osinfo_os.h b/api/osinfo_os.h
deleted file mode 100644
index 83241c9..0000000
--- a/api/osinfo_os.h
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * libosinfo
- *
- * osinfo_os.h
- * Represents an operating system in libosinfo.
- */
-
-#ifndef __OSINFO_OS_H__
-#define __OSINFO_OS_H__
-
-#include <glib-object.h>
-#include "osinfo_oslist.h"
-#include "osinfo_devicelist.h"
-
-/*
- * Type macros.
- */
-#define OSINFO_TYPE_OS                  (osinfo_os_get_type ())
-#define OSINFO_OS(obj)                  (G_TYPE_CHECK_INSTANCE_CAST ((obj), OSINFO_TYPE_OS, OsinfoOs))
-#define OSINFO_IS_OS(obj)               (G_TYPE_CHECK_INSTANCE_TYPE ((obj), OSINFO_TYPE_OS))
-#define OSINFO_OS_CLASS(klass)          (G_TYPE_CHECK_CLASS_CAST ((klass), OSINFO_TYPE_OS, OsinfoOsClass))
-#define OSINFO_IS_OS_CLASS(klass)       (G_TYPE_CHECK_CLASS_TYPE ((klass), OSINFO_TYPE_OS))
-#define OSINFO_OS_GET_CLASS(obj)        (G_TYPE_INSTANCE_GET_CLASS ((obj), OSINFO_TYPE_OS, OsinfoOsClass))
-
-//typedef struct _OsinfoOs        OsinfoOs;
-// (defined in osinfo_objects.h)
-
-typedef struct _OsinfoOsClass   OsinfoOsClass;
-
-typedef struct _OsinfoOsPrivate OsinfoOsPrivate;
-
-/* object */
-struct _OsinfoOs
-{
-    OsinfoEntity parent_instance;
-
-    /* public */
-
-    /* private */
-    OsinfoOsPrivate *priv;
-};
-
-/* class */
-struct _OsinfoOsClass
-{
-    OsinfoEntityClass parent_class;
-
-    /* class members */
-};
-
-OsinfoDevice *osinfoGetPreferredDeviceForOs(OsinfoOs *self, OsinfoHypervisor *hv, gchar *devType, OsinfoFilter *filter, GError **err);
-OsinfoOsList *osinfoGetRelatedOs(OsinfoOs *self, osinfoRelationship relshp, GError **err);
-OsinfoDeviceList *osinfoGetDevicesForOs(OsinfoOs *self, OsinfoHypervisor *hv, gchar *devType, OsinfoFilter *filter, GError **err);
-
-#endif /* __OSINFO_OS_H__ */
diff --git a/api/osinfo_oslist.h b/api/osinfo_oslist.h
deleted file mode 100644
index 168f5a5..0000000
--- a/api/osinfo_oslist.h
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * libosinfo
- *
- * osinfo_oslist.h
- * All entities represented in libosinfo are derived from this class.
- */
-
-#ifndef __OSINFO_OSLIST_H__
-#define __OSINFO_OSLIST_H__
-
-/*
- * Type macros.
- */
-#define OSINFO_TYPE_OSLIST                  (osinfo_oslist_get_type ())
-#define OSINFO_OSLIST(obj)                  (G_TYPE_CHECK_INSTANCE_CAST ((obj), OSINFO_TYPE_OSLIST, OsinfoOsList))
-#define OSINFO_IS_OSLIST(obj)               (G_TYPE_CHECK_INSTANCE_TYPE ((obj), OSINFO_TYPE_OSLIST))
-#define OSINFO_OSLIST_CLASS(klass)          (G_TYPE_CHECK_CLASS_CAST ((klass), OSINFO_TYPE_OSLIST, OsinfoOsListClass))
-#define OSINFO_IS_OSLIST_CLASS(klass)       (G_TYPE_CHECK_CLASS_TYPE ((klass), OSINFO_TYPE_OSLIST))
-#define OSINFO_OSLIST_GET_CLASS(obj)        (G_TYPE_INSTANCE_GET_CLASS ((obj), OSINFO_TYPE_OSLIST, OsinfoOsListClass))
-
-typedef struct _OsinfoOsList        OsinfoOsList;
-
-typedef struct _OsinfoOsListClass   OsinfoOsListClass;
-
-typedef struct _OsinfoOsListPrivate OsinfoOsListPrivate;
-
-/* object */
-struct _OsinfoOsList
-{
-    GObject parent_instance;
-
-    /* public */
-
-    /* private */
-    OsinfoOsListPrivate *priv;
-};
-
-/* class */
-struct _OsinfoOsListClass
-{
-    GObjectClass parent_class;
-
-    /* class members */
-};
-
-OsinfoOsList *osinfoOsListFilter(OsinfoOsList *self, OsinfoFilter *filter, GError **err);
-OsinfoOs *osinfoGetOsAtIndex(OsinfoOsList *self, gint idx, GError **err);
-OsinfoOsList *osinfoOsListIntersect(OsinfoOsList *self, OsinfoOsList *otherOsList, GError **err);
-OsinfoOsList *osinfoOsListUnion(OsinfoOsList *self, OsinfoOsList *otherOsList, GError **err);
-
-#endif /* __OSINFO_OSLIST_H__ */
diff --git a/configure.ac b/configure.ac
index 845c3f3..9a182be 100644
--- a/configure.ac
+++ b/configure.ac
@@ -3,7 +3,7 @@ AC_CONFIG_AUX_DIR([build-aux])
 AC_CONFIG_MACRO_DIR([m4])
 AM_INIT_AUTOMAKE([1.11.1 -Wall -Werror foreign color-tests])
 AC_PREREQ([2.61])
-AC_CONFIG_SRCDIR([src/osinfo_common.c])
+AC_CONFIG_SRCDIR([osinfo/osinfo_common.c])
 AC_CONFIG_HEADERS([config.h])
 AC_PROG_LIBTOOL
 AC_PROG_CC
diff --git a/inc/osinfo_common.h b/inc/osinfo_common.h
deleted file mode 100644
index 8f80c91..0000000
--- a/inc/osinfo_common.h
+++ /dev/null
@@ -1,258 +0,0 @@
-/*
- * libosinfo
- *
- * osinfo_objects.h
- * Contains forward declarations of our main object types, and definitions
- * of our internal data structures not exposed in the API as libosinfo objects.
- */
-
-#ifndef __OSINFO_OBJECTS_H__
-#define __OSINFO_OBJECTS_H__
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <glib-object.h>
-#include <errno.h>
-#include "osinfo_entity.h"
-
-#define FREE_N(x) free(x); x = null;
-
-typedef struct _OsinfoDb         OsinfoDb;
-typedef struct _OsinfoDevice     OsinfoDevice;
-typedef struct _OsinfoHypervisor OsinfoHypervisor;
-typedef struct _OsinfoOs         OsinfoOs;
-typedef struct _OsinfoFilter     OsinfoFilter;
-typedef struct _OsinfoList       OsinfoList;
-
-typedef enum OSI_RELATIONSHIP {
-    RELATIONSHIP_MIN = 0,
-    DERIVES_FROM,
-    UPGRADES,
-    CLONES,
-    RELATIONSHIP_MAX
-} osinfoRelationship;
-
-
-/** ****************************************************************************
- * Internal data structures
- ******************************************************************************/
-
-struct __osinfoDeviceLink {
-    OsinfoDevice *dev;
-    gchar *driver;
-};
-
-struct __osinfoHvSection {
-    OsinfoHypervisor *hv;
-    OsinfoOs *os;
-
-    GTree *sections; // Mapping GString key (device type) to GTree of deviceLink structs
-    GTree *sectionsAsList; // Mapping GString key (device type) to Array of deviceLink structs
-};
-
-struct __osinfoOsLink {
-    /* <subject_os> 'verbs' <direct_object_os>
-     * fedora11 upgrades fedora10
-     * centos clones rhel
-     * scientificlinux derives from rhel
-     */
-    OsinfoOs *subjectOs;
-    osinfoRelationship verb;
-    OsinfoOs *directObjectOs;
-};
-
-struct __osinfoPtrArrayErr {
-    GPtrArray *array;
-    int err;
-};
-
-struct __osinfoPopulateListArgs {
-    GError **err;
-    int errcode;
-    OsinfoFilter *filter;
-    OsinfoList *list;
-};
-
-struct __osinfoPopulateValuesArgs {
-    GError **err;
-    int errcode;
-    GTree *values;
-    gchar *property;
-};
-
-struct __osinfoOsCheckRelationshipArgs {
-    OsinfoList *list;
-    int errcode;
-    GError **err;
-    osinfoRelationship relshp;
-};
-
-struct __osinfoFilterPassArgs {
-    int passed;
-    OsinfoEntity *entity;
-};
-
-/** ****************************************************************************
- *      Convenience methods
- ******************************************************************************/
-
-gint __osinfoIntCompareBase(gconstpointer a,
-                            gconstpointer b);
-gint __osinfoIntCompare(gconstpointer a,
-                        gconstpointer b,
-                        gpointer data);
-gint __osinfoStringCompareBase(gconstpointer a,
-                               gconstpointer b);
-gint __osinfoStringCompare(gconstpointer a,
-                           gconstpointer b,
-                           gpointer data);
-
-void __osinfoFreePtrArray(gpointer ptrarray);
-void __osinfoFreeRelationship(gpointer ptrarray);
-void __osinfoFreeParamVals(gpointer ptrarray);
-void __osinfoFreeDeviceSection(gpointer tree);
-void __osinfoFreeHvSection(gpointer hvSection);
-void __osinfoFreeDeviceLink(gpointer ptr);
-void __osinfoFreeOsLink(gpointer ptr);
-
-void __osinfoListAdd(OsinfoList *self, OsinfoEntity *entity);
-
-int __osinfoAddDeviceToSection(GTree *allSections, GTree *allSectionsAsList, gchar *sectionName, gchar *id, gchar *driver);
-void __osinfoClearDeviceSection(GTree *allSections, GTree *allSectionsAsList, gchar *section);
-
-gboolean __osinfoGetKeys(gpointer key, gpointer value, gpointer data);
-void __osinfoDupArray(gpointer data, gpointer user_data);
-
-int __osinfoEntityPassesFilter(OsinfoFilter *filter, OsinfoEntity *device);
-int __osinfoDevicePassesFilter(OsinfoFilter *filter, OsinfoDevice *device);
-int __osinfoOsPassesFilter(OsinfoFilter *filter, OsinfoOs *device);
-int __osinfoHypervisorPassesFilter(OsinfoFilter *filter, OsinfoHypervisor *device);
-
-int __osinfoCheckGErrorParamValid(GError **err);
-int __osinfoCheckRelationshipValid(osinfoRelationship relshp);
-
-/** ****************************************************************************
- *      Private structures for objects
- ******************************************************************************/
-
-struct _OsinfoFilterPrivate
-{
-    // Key: Constraint name
-    // Value: Array of constraint values
-    GTree *propertyConstraints;
-
-    // Key: relationship type
-    // Value: Array of OsinfoOs *
-    // Note: Only used when filtering OsinfoOs objects
-    GTree *relationshipConstraints;
-};
-
-struct _OsinfoDbPrivate
-{
-    int ready;
-
-    gchar *backing_dir;
-    gchar *libvirt_ver;
-
-    GTree *devices;
-    GTree *hypervisors;
-    GTree *oses;
-
-    GError *error;
-};
-
-struct _OsinfoDevicePrivate
-{
-    int tmp;
-};
-
-struct _OsinfoHypervisorPrivate
-{
-    // Key: gchar* (device type)
-    // Value: Tree of device_link structs (multiple devices per type)
-    GTree *sections;
-    GTree *sectionsAsList; // Mapping GString key (device type) to Array of deviceLink structs
-};
-
-struct _OsinfoOsPrivate
-{
-    // OS-Hypervisor specific information
-    // Key: gchar* (hypervisor id)
-    // Value: hv_section struct
-    GTree *hypervisors;
-
-    // Key: gchar* (device type)
-    // Value: Tree of device_link structs (multiple devices per type)
-    GTree *sections;
-    GTree *sectionsAsList; // Mapping GString key (device type) to Array of deviceLink structs
-
-    // OS-OS relationships
-    // Key: gchar* (other os id)
-    // Value: Array of os_link structs
-    GTree *relationshipsByOs;
-    // Key: relationship type
-    // Value: Array of os_link structs
-    GTree *relationshipsByType;
-};
-
-struct _OsinfoEntityPrivate
-{
-    gchar *id;
-
-    // Key: gchar*
-    // Value: Array of gchar* values for key (multiple values allowed)
-    GTree *params;
-
-    OsinfoDb *db; // Backpointer to db object
-};
-
-/** ****************************************************************************
- *      Error strings
- ******************************************************************************/
-
-gchar *__osinfoErrorToString(int err);
-
-#define OSINFO_OTHER "An unspecified error occured"
-#define OSINFO_OBJ_NOT_DB "Object is wrong type (expected OsInfoDb)"
-#define OSINFO_OBJ_NOT_ENTITY "Object is wrong type (expected OsInfoEntity)"
-#define OSINFO_OBJ_NOT_DEVICE "Object is wrong type (expected OsInfoDevice)"
-#define OSINFO_OBJ_NOT_OS "Object is wrong type (expected OsInfoOs)"
-#define OSINFO_OBJ_NOT_HV "Object is wrong type (expected OsInfoHypervisor)"
-#define OSINFO_OBJ_NOT_LIST "Object is wrong type (expected OsInfoList)"
-#define OSINFO_OBJ_NOT_HYPERVISORLIST "Object is wrong type (expected OsInfoHypervisorList)"
-#define OSINFO_OBJ_NOT_DEVICELIST "Object is wrong type (expected OsInfoDeviceList)"
-#define OSINFO_OBJ_NOT_OSLIST "Object is wrong type (expected OsInfoOsList)"
-#define OSINFO_OBJ_NOT_FILTER "Object is wrong type (expected OsInfoFilter)"
-#define OSINFO_NO_ID "No object id specified"
-#define OSINFO_NO_DEVTYPE "No device type specified"
-#define OSINFO_NO_MEM "Not enough memory to complete operation"
-#define OSINFO_NO_PROPNAME "No property specified"
-#define OSINFO_NO_PROPVAL "No value specified for property"
-#define OSINFO_INVALID_RELATIONSHIP "Invalid relationship specified"
-#endif /* __OSINFO_OBJECTS_H__ */
-
-/** ****************************************************************************
- *      Private Methods
- ******************************************************************************/
-
-void __osinfoAddDeviceToDb(OsinfoDb *db, OsinfoDevice *dev);
-void __osinfoAddHypervisorToDb(OsinfoDb *db, OsinfoHypervisor *hv);
-void __osinfoAddOsToDb(OsinfoDb *db, OsinfoOs *os);
-
-// Private
-int __osinfoAddDeviceToSectionOs(OsinfoOs *self, gchar *section, gchar *id, gchar *driver);
-void __osinfoClearDeviceSectionOs(OsinfoOs *self, gchar *section);
-
-int __osinfoAddOsRelationship (OsinfoOs *self, gchar *otherOsId, osinfoRelationship rel);
-void __osinfoClearOsRelationships (OsinfoOs *self, gchar *otherOsId);
-
-struct __osinfoHvSection *__osinfoAddHypervisorSectionToOs(OsinfoOs *self, gchar *hvId);
-void __osinfoRemoveHvSectionFromOs(OsinfoOs *self, gchar *hvId);
-
-// Private
-int __osinfoAddDeviceToSectionHv(OsinfoHypervisor *self, gchar *section, gchar *id, gchar *driver);
-void __osinfoClearDeviceSectionHv(OsinfoHypervisor *self, gchar *section);
-
-// Private
-int __osinfoAddParam(OsinfoEntity *self, gchar *key, gchar *value);
-void __osinfoClearParam(OsinfoEntity *self, gchar *key);
diff --git a/osinfo/osinfo.h b/osinfo/osinfo.h
new file mode 100644
index 0000000..7591487
--- /dev/null
+++ b/osinfo/osinfo.h
@@ -0,0 +1,17 @@
+#ifndef __OSINFO_H__
+#define __OSINFO_H__
+
+#include <glib-object.h>
+#include <osinfo/osinfo_common.h>
+#include <osinfo/osinfo_db.h>
+#include <osinfo/osinfo_entity.h>
+#include <osinfo/osinfo_device.h>
+#include <osinfo/osinfo_os.h>
+#include <osinfo/osinfo_hypervisor.h>
+#include <osinfo/osinfo_filter.h>
+#include <osinfo/osinfo_list.h>
+#include <osinfo/osinfo_devicelist.h>
+#include <osinfo/osinfo_oslist.h>
+#include <osinfo/osinfo_hypervisorlist.h>
+
+#endif
diff --git a/osinfo/osinfo_common.c b/osinfo/osinfo_common.c
new file mode 100644
index 0000000..15eb8cd
--- /dev/null
+++ b/osinfo/osinfo_common.c
@@ -0,0 +1,349 @@
+#include <osinfo/osinfo.h>
+
+static int __osinfoAddDeviceToList(GTree *allSectionsAsList,
+                                   gchar *sectionName,
+                                   struct __osinfoDeviceLink *deviceLink)
+{
+    if (!allSectionsAsList || !sectionName || !deviceLink)
+        return -EINVAL;
+
+    gboolean found;
+    gpointer origKey, foundValue;
+    GPtrArray *sectionList;
+    gchar *sectionNameDup = NULL;
+
+    found = g_tree_lookup_extended(allSectionsAsList, sectionName, &origKey, &foundValue);
+    if (!found) {
+        sectionList = g_ptr_array_new();
+        sectionNameDup = g_strdup(sectionName);
+
+        if (!sectionList)
+            goto error_free;
+        if (!sectionNameDup) {
+            g_ptr_array_free(sectionList, TRUE);
+            goto error_free;
+        }
+
+        g_tree_insert(allSectionsAsList, sectionNameDup, sectionList);
+    }
+    else
+        sectionList = (GPtrArray *) foundValue;
+
+    g_ptr_array_add(sectionList, deviceLink);
+    return 0;
+
+error_free:
+    g_free(sectionNameDup);
+    return -ENOMEM;
+}
+
+int __osinfoAddDeviceToSection(GTree *allSections, GTree *allSectionsAsList, gchar *sectionName, gchar *id, gchar *driver)
+{
+    if (!allSections || !sectionName || !id)
+        return -EINVAL;
+
+    gboolean found;
+    gpointer origKey, foundValue;
+    gchar *sectionNameDup = NULL, *idDup = NULL, *driverDup = NULL;
+    GTree *section;
+    struct __osinfoDeviceLink *deviceLink;
+    int ret;
+
+    idDup = g_strdup(id);
+    driverDup = g_strdup(driver);
+    deviceLink = g_malloc(sizeof(*deviceLink));
+
+    if (!idDup || g_strcmp0(driverDup, driver) != 0 || !deviceLink)
+        goto error_free;
+
+    found = g_tree_lookup_extended(allSections, sectionName, &origKey, &foundValue);
+    if (!found) {
+        section = g_tree_new_full(__osinfoStringCompare, NULL, g_free, __osinfoFreeDeviceLink);
+        sectionNameDup = g_strdup(sectionName);
+
+        if (!section)
+            goto error_free;
+        if (!sectionNameDup) {
+            g_tree_destroy(section);
+            goto error_free;
+        }
+
+        g_tree_insert(allSections, sectionNameDup, section);
+    }
+    else
+        section = (GTree *) foundValue;
+
+    deviceLink->driver = driverDup;
+    g_tree_insert(section, idDup, deviceLink);
+
+    ret = 0;
+    if (allSectionsAsList)
+        ret = __osinfoAddDeviceToList(allSectionsAsList, sectionName, deviceLink);
+
+    return ret;
+
+error_free:
+    g_free(sectionNameDup);
+    g_free(idDup);
+    g_free(driverDup);
+    g_free(deviceLink);
+    return -ENOMEM;
+}
+
+void __osinfoClearDeviceSection(GTree *allSections, GTree *allSectionsAsList, gchar *section)
+{
+    if (!allSections || !section)
+        return;
+
+    g_tree_remove(allSections, section);
+    g_tree_remove(allSectionsAsList, section);
+}
+
+void __osinfoFreeDeviceLink(gpointer ptr)
+{
+    if (!ptr)
+        return;
+    struct __osinfoDeviceLink *devLink = (struct __osinfoDeviceLink *) ptr;
+    g_free(devLink->driver);
+    g_free(devLink);
+}
+
+void __osinfoFreeDeviceSection(gpointer tree)
+{
+    if (!tree)
+        return;
+    g_tree_destroy((GTree *)tree);
+}
+
+gint __osinfoStringCompare(gconstpointer a,
+                           gconstpointer b,
+                           gpointer data)
+{
+    // a and b are each gchar *, data is ignored
+    gchar *str1 = (gchar *) a;
+    gchar *str2 = (gchar *) b;
+    return g_strcmp0(str1, str2);
+}
+
+gint __osinfoStringCompareBase(gconstpointer a,
+                               gconstpointer b)
+{
+    // a and b are each gchar *, data is ignored
+    gchar *str1 = (gchar *) a;
+    gchar *str2 = (gchar *) b;
+    return g_strcmp0(str1, str2);
+}
+
+gint __osinfoIntCompareBase(gconstpointer a,
+                            gconstpointer b)
+{
+    // a and b are each gchar *, data is ignored
+    unsigned long int1 = (unsigned long) a;
+    unsigned long int2 = (unsigned long) b;
+    return a - b;
+}
+
+gint __osinfoIntCompare(gconstpointer a,
+                        gconstpointer b,
+                        gpointer data)
+{
+    // a and b are each gchar *, data is ignored
+    unsigned long int1 = (unsigned long) a;
+    unsigned long int2 = (unsigned long) b;
+    return a - b;
+}
+
+void __osinfoFreePtrArray(gpointer ptrarray)
+{
+    g_ptr_array_free(ptrarray, TRUE);
+}
+
+void __osinfoFreeRelationship(gpointer ptrarray)
+{
+    if (!ptrarray)
+        return;
+    __osinfoFreePtrArray(ptrarray);
+}
+
+void __osinfoFreeParamVals(gpointer ptrarray)
+{
+    if (!ptrarray)
+        return;
+    __osinfoFreePtrArray(ptrarray);
+}
+
+void __osinfoFreeOsLink(gpointer ptr)
+{
+    if (!ptr)
+        return;
+    struct __osinfoOsLink *osLink = (struct __osinfoOsLink *) ptr;
+    g_free(osLink);
+}
+
+void __osinfoFreeHvSection(gpointer ptr)
+{
+    if (!ptr)
+        return;
+    struct __osinfoHvSection * hvSection = (struct __osinfoHvSection *) ptr;
+    g_tree_destroy(hvSection->sections);
+    g_tree_destroy(hvSection->sectionsAsList);
+    g_free(hvSection);
+}
+
+gboolean __osinfoFilterCheckProperty(gpointer key, gpointer value, gpointer data)
+{
+    struct __osinfoFilterPassArgs *args;
+    args = (struct __osinfoFilterPassArgs *) data;
+    OsinfoEntity *entity = args->entity;
+
+    // Key is property to filter on
+    // Value is array of values for property
+
+    GPtrArray *filterValues = (GPtrArray *) value;
+    GPtrArray *entityValues = NULL;
+
+    entityValues = g_tree_lookup(entity->priv->params, key);
+    if (!entityValues && filterValues->len > 0) {
+        args->passed = 0;
+        return TRUE; // not passed
+    }
+
+    int i;
+    for (i = 0; i < filterValues->len; i++) {
+        gchar *currValue = g_ptr_array_index(filterValues, i);
+        int j, found = 0;
+        for (j = 0; j < entityValues->len; j++) {
+            gchar *testValue = g_ptr_array_index(entityValues, j);
+            if (g_strcmp0(currValue, testValue) == 0) {
+                found = 1;
+                break;
+            }
+        }
+        if (found)
+            continue;
+        else {
+            args->passed = 0;
+            return TRUE; // not passed
+        }
+    }
+
+    args->passed = 1;
+    return FALSE; // continue iterating
+}
+
+int __osinfoEntityPassesFilter(OsinfoFilter *filter, OsinfoEntity *entity)
+{
+    if (!OSINFO_IS_ENTITY(entity))
+        return 0;
+
+    if (!filter)
+        return 1;
+
+    if (!OSINFO_IS_FILTER(filter))
+        return 0;
+
+    struct __osinfoFilterPassArgs args = {0, entity};
+    g_tree_foreach(filter->priv->propertyConstraints, __osinfoFilterCheckProperty, &args);
+    if (args.passed)
+        return 1;
+    else
+        return 0;
+}
+
+int __osinfoDevicePassesFilter(OsinfoFilter *filter, OsinfoDevice *device)
+{
+    // Check is device
+    return __osinfoEntityPassesFilter(filter, OSINFO_ENTITY (device));
+}
+
+gboolean __osinfoFilterCheckRelationships(gpointer key, gpointer value, gpointer data)
+{
+    struct __osinfoFilterPassArgs *args;
+    args = (struct __osinfoFilterPassArgs *) data;
+    OsinfoOs *os = (OsinfoOs *) args->entity;
+
+    // Key is relationship to filter on
+    // Value is array of oses for relationship
+
+    GPtrArray *filterOses = (GPtrArray *) value;
+    GPtrArray *oses = NULL;
+
+    oses = g_tree_lookup(os->priv->relationshipsByType, key);
+    if (!oses && filterOses->len > 0) {
+        args->passed = 0;
+        return TRUE; // not passed
+    }
+
+    int i;
+    for (i = 0; i < filterOses->len; i++) {
+        OsinfoOs *currOs = g_ptr_array_index(filterOses, i);
+        int j, found = 0;
+        for (j = 0; j < oses->len; j++) {
+            OsinfoOs *testOs = g_ptr_array_index(oses, j);
+            if (testOs == currOs) {
+                found = 1;
+                break;
+            }
+        }
+        if (found)
+            continue;
+        else {
+            args->passed = 0;
+            return TRUE; // not passed
+        }
+    }
+
+    args->passed = 1;
+    return FALSE; // continue iterating
+}
+
+int __osinfoOsPassesFilter(OsinfoFilter *filter, OsinfoOs *os)
+{
+    if (!OSINFO_IS_OS(os))
+        return 0;
+
+    if (!filter)
+        return 1;
+
+    if (!OSINFO_IS_FILTER(filter))
+        return 0;
+
+    int pass = __osinfoEntityPassesFilter(filter, OSINFO_ENTITY (os));
+    if (!pass)
+        return 0;
+
+    struct __osinfoFilterPassArgs args = {0, (OsinfoEntity *) os};
+    g_tree_foreach(filter->priv->relationshipConstraints, __osinfoFilterCheckRelationships, &args);
+    if (args.passed)
+        return 1;
+    else
+        return 0;
+}
+
+int __osinfoHypervisorPassesFilter(OsinfoFilter *filter, OsinfoHypervisor *hypervisor)
+{
+    return __osinfoEntityPassesFilter(filter, OSINFO_ENTITY (hypervisor));
+}
+
+int __osinfoCheckGErrorParamValid(GError **err)
+{
+    // If err is not null and *err is not null, then invalid
+    if (err && *err)
+        return 0;
+    else return 1;
+}
+
+int __osinfoCheckRelationshipValid(osinfoRelationship relshp)
+{
+    return (relshp > RELATIONSHIP_MIN && relshp < RELATIONSHIP_MAX);
+}
+
+gchar *__osinfoErrorToString(int err)
+{
+    switch (err) {
+        case -ENOMEM:
+            return OSINFO_NO_MEM;
+        default:
+            return OSINFO_OTHER;
+    }
+}
diff --git a/osinfo/osinfo_common.h b/osinfo/osinfo_common.h
new file mode 100644
index 0000000..8f80c91
--- /dev/null
+++ b/osinfo/osinfo_common.h
@@ -0,0 +1,258 @@
+/*
+ * libosinfo
+ *
+ * osinfo_objects.h
+ * Contains forward declarations of our main object types, and definitions
+ * of our internal data structures not exposed in the API as libosinfo objects.
+ */
+
+#ifndef __OSINFO_OBJECTS_H__
+#define __OSINFO_OBJECTS_H__
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <glib-object.h>
+#include <errno.h>
+#include "osinfo_entity.h"
+
+#define FREE_N(x) free(x); x = null;
+
+typedef struct _OsinfoDb         OsinfoDb;
+typedef struct _OsinfoDevice     OsinfoDevice;
+typedef struct _OsinfoHypervisor OsinfoHypervisor;
+typedef struct _OsinfoOs         OsinfoOs;
+typedef struct _OsinfoFilter     OsinfoFilter;
+typedef struct _OsinfoList       OsinfoList;
+
+typedef enum OSI_RELATIONSHIP {
+    RELATIONSHIP_MIN = 0,
+    DERIVES_FROM,
+    UPGRADES,
+    CLONES,
+    RELATIONSHIP_MAX
+} osinfoRelationship;
+
+
+/** ****************************************************************************
+ * Internal data structures
+ ******************************************************************************/
+
+struct __osinfoDeviceLink {
+    OsinfoDevice *dev;
+    gchar *driver;
+};
+
+struct __osinfoHvSection {
+    OsinfoHypervisor *hv;
+    OsinfoOs *os;
+
+    GTree *sections; // Mapping GString key (device type) to GTree of deviceLink structs
+    GTree *sectionsAsList; // Mapping GString key (device type) to Array of deviceLink structs
+};
+
+struct __osinfoOsLink {
+    /* <subject_os> 'verbs' <direct_object_os>
+     * fedora11 upgrades fedora10
+     * centos clones rhel
+     * scientificlinux derives from rhel
+     */
+    OsinfoOs *subjectOs;
+    osinfoRelationship verb;
+    OsinfoOs *directObjectOs;
+};
+
+struct __osinfoPtrArrayErr {
+    GPtrArray *array;
+    int err;
+};
+
+struct __osinfoPopulateListArgs {
+    GError **err;
+    int errcode;
+    OsinfoFilter *filter;
+    OsinfoList *list;
+};
+
+struct __osinfoPopulateValuesArgs {
+    GError **err;
+    int errcode;
+    GTree *values;
+    gchar *property;
+};
+
+struct __osinfoOsCheckRelationshipArgs {
+    OsinfoList *list;
+    int errcode;
+    GError **err;
+    osinfoRelationship relshp;
+};
+
+struct __osinfoFilterPassArgs {
+    int passed;
+    OsinfoEntity *entity;
+};
+
+/** ****************************************************************************
+ *      Convenience methods
+ ******************************************************************************/
+
+gint __osinfoIntCompareBase(gconstpointer a,
+                            gconstpointer b);
+gint __osinfoIntCompare(gconstpointer a,
+                        gconstpointer b,
+                        gpointer data);
+gint __osinfoStringCompareBase(gconstpointer a,
+                               gconstpointer b);
+gint __osinfoStringCompare(gconstpointer a,
+                           gconstpointer b,
+                           gpointer data);
+
+void __osinfoFreePtrArray(gpointer ptrarray);
+void __osinfoFreeRelationship(gpointer ptrarray);
+void __osinfoFreeParamVals(gpointer ptrarray);
+void __osinfoFreeDeviceSection(gpointer tree);
+void __osinfoFreeHvSection(gpointer hvSection);
+void __osinfoFreeDeviceLink(gpointer ptr);
+void __osinfoFreeOsLink(gpointer ptr);
+
+void __osinfoListAdd(OsinfoList *self, OsinfoEntity *entity);
+
+int __osinfoAddDeviceToSection(GTree *allSections, GTree *allSectionsAsList, gchar *sectionName, gchar *id, gchar *driver);
+void __osinfoClearDeviceSection(GTree *allSections, GTree *allSectionsAsList, gchar *section);
+
+gboolean __osinfoGetKeys(gpointer key, gpointer value, gpointer data);
+void __osinfoDupArray(gpointer data, gpointer user_data);
+
+int __osinfoEntityPassesFilter(OsinfoFilter *filter, OsinfoEntity *device);
+int __osinfoDevicePassesFilter(OsinfoFilter *filter, OsinfoDevice *device);
+int __osinfoOsPassesFilter(OsinfoFilter *filter, OsinfoOs *device);
+int __osinfoHypervisorPassesFilter(OsinfoFilter *filter, OsinfoHypervisor *device);
+
+int __osinfoCheckGErrorParamValid(GError **err);
+int __osinfoCheckRelationshipValid(osinfoRelationship relshp);
+
+/** ****************************************************************************
+ *      Private structures for objects
+ ******************************************************************************/
+
+struct _OsinfoFilterPrivate
+{
+    // Key: Constraint name
+    // Value: Array of constraint values
+    GTree *propertyConstraints;
+
+    // Key: relationship type
+    // Value: Array of OsinfoOs *
+    // Note: Only used when filtering OsinfoOs objects
+    GTree *relationshipConstraints;
+};
+
+struct _OsinfoDbPrivate
+{
+    int ready;
+
+    gchar *backing_dir;
+    gchar *libvirt_ver;
+
+    GTree *devices;
+    GTree *hypervisors;
+    GTree *oses;
+
+    GError *error;
+};
+
+struct _OsinfoDevicePrivate
+{
+    int tmp;
+};
+
+struct _OsinfoHypervisorPrivate
+{
+    // Key: gchar* (device type)
+    // Value: Tree of device_link structs (multiple devices per type)
+    GTree *sections;
+    GTree *sectionsAsList; // Mapping GString key (device type) to Array of deviceLink structs
+};
+
+struct _OsinfoOsPrivate
+{
+    // OS-Hypervisor specific information
+    // Key: gchar* (hypervisor id)
+    // Value: hv_section struct
+    GTree *hypervisors;
+
+    // Key: gchar* (device type)
+    // Value: Tree of device_link structs (multiple devices per type)
+    GTree *sections;
+    GTree *sectionsAsList; // Mapping GString key (device type) to Array of deviceLink structs
+
+    // OS-OS relationships
+    // Key: gchar* (other os id)
+    // Value: Array of os_link structs
+    GTree *relationshipsByOs;
+    // Key: relationship type
+    // Value: Array of os_link structs
+    GTree *relationshipsByType;
+};
+
+struct _OsinfoEntityPrivate
+{
+    gchar *id;
+
+    // Key: gchar*
+    // Value: Array of gchar* values for key (multiple values allowed)
+    GTree *params;
+
+    OsinfoDb *db; // Backpointer to db object
+};
+
+/** ****************************************************************************
+ *      Error strings
+ ******************************************************************************/
+
+gchar *__osinfoErrorToString(int err);
+
+#define OSINFO_OTHER "An unspecified error occured"
+#define OSINFO_OBJ_NOT_DB "Object is wrong type (expected OsInfoDb)"
+#define OSINFO_OBJ_NOT_ENTITY "Object is wrong type (expected OsInfoEntity)"
+#define OSINFO_OBJ_NOT_DEVICE "Object is wrong type (expected OsInfoDevice)"
+#define OSINFO_OBJ_NOT_OS "Object is wrong type (expected OsInfoOs)"
+#define OSINFO_OBJ_NOT_HV "Object is wrong type (expected OsInfoHypervisor)"
+#define OSINFO_OBJ_NOT_LIST "Object is wrong type (expected OsInfoList)"
+#define OSINFO_OBJ_NOT_HYPERVISORLIST "Object is wrong type (expected OsInfoHypervisorList)"
+#define OSINFO_OBJ_NOT_DEVICELIST "Object is wrong type (expected OsInfoDeviceList)"
+#define OSINFO_OBJ_NOT_OSLIST "Object is wrong type (expected OsInfoOsList)"
+#define OSINFO_OBJ_NOT_FILTER "Object is wrong type (expected OsInfoFilter)"
+#define OSINFO_NO_ID "No object id specified"
+#define OSINFO_NO_DEVTYPE "No device type specified"
+#define OSINFO_NO_MEM "Not enough memory to complete operation"
+#define OSINFO_NO_PROPNAME "No property specified"
+#define OSINFO_NO_PROPVAL "No value specified for property"
+#define OSINFO_INVALID_RELATIONSHIP "Invalid relationship specified"
+#endif /* __OSINFO_OBJECTS_H__ */
+
+/** ****************************************************************************
+ *      Private Methods
+ ******************************************************************************/
+
+void __osinfoAddDeviceToDb(OsinfoDb *db, OsinfoDevice *dev);
+void __osinfoAddHypervisorToDb(OsinfoDb *db, OsinfoHypervisor *hv);
+void __osinfoAddOsToDb(OsinfoDb *db, OsinfoOs *os);
+
+// Private
+int __osinfoAddDeviceToSectionOs(OsinfoOs *self, gchar *section, gchar *id, gchar *driver);
+void __osinfoClearDeviceSectionOs(OsinfoOs *self, gchar *section);
+
+int __osinfoAddOsRelationship (OsinfoOs *self, gchar *otherOsId, osinfoRelationship rel);
+void __osinfoClearOsRelationships (OsinfoOs *self, gchar *otherOsId);
+
+struct __osinfoHvSection *__osinfoAddHypervisorSectionToOs(OsinfoOs *self, gchar *hvId);
+void __osinfoRemoveHvSectionFromOs(OsinfoOs *self, gchar *hvId);
+
+// Private
+int __osinfoAddDeviceToSectionHv(OsinfoHypervisor *self, gchar *section, gchar *id, gchar *driver);
+void __osinfoClearDeviceSectionHv(OsinfoHypervisor *self, gchar *section);
+
+// Private
+int __osinfoAddParam(OsinfoEntity *self, gchar *key, gchar *value);
+void __osinfoClearParam(OsinfoEntity *self, gchar *key);
diff --git a/osinfo/osinfo_dataread.c b/osinfo/osinfo_dataread.c
new file mode 100644
index 0000000..b77119f
--- /dev/null
+++ b/osinfo/osinfo_dataread.c
@@ -0,0 +1,915 @@
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <dirent.h>
+#include <errno.h>
+#include <unistd.h>
+#include <libxml/xmlreader.h>
+
+#include <osinfo/osinfo.h>
+
+#ifdef LIBXML_READER_ENABLED
+
+#define TEXT_NODE 3
+#define ELEMENT_NODE 1
+#define END_NODE 15
+#define WHITESPACE_NODE 14
+#define COMMENT_NODE 8
+
+/*
+ * TODO:
+ * 1. More robust handling of files that are in bad format
+ * 2. Error messages for parsing
+ */
+
+/*
+ * Notes regarding parsing XML Data:
+ *
+ * The top level tag is <libosinfo>. The next highest level consists of
+ * <device>, <hypervisor> and <os>. Each tag may be empty (of the form <tag />)
+ * or containing data (of the form <tag>...</tag>). After parsing an object, the
+ * cursor will be located at the closing tag for the object (which, for an empty
+ * object, is the same as the starting tag for the object).
+ */
+
+struct __osinfoDbRet {
+    OsinfoDb *db;
+    int *ret;
+};
+
+static gboolean __osinfoResolveDeviceLink(gpointer key, gpointer value, gpointer data)
+{
+    gchar *id = (gchar *) key;
+    struct __osinfoDeviceLink *devLink = (struct __osinfoDeviceLink *) value;
+    struct __osinfoDbRet *dbRet = (struct __osinfoDbRet *) data;
+    OsinfoDb *db = dbRet->db;
+    int *ret = dbRet->ret;
+
+    OsinfoDevice *dev = g_tree_lookup(db->priv->devices, id);
+    if (!dev) {
+        *ret = -EINVAL;
+        return TRUE;
+    }
+
+    devLink->dev = dev;
+    *ret = 0;
+    return FALSE;
+}
+
+static gboolean __osinfoResolveSectionDevices(gpointer key, gpointer value, gpointer data)
+{
+    struct __osinfoDbRet *dbRet = (struct __osinfoDbRet *) data;
+    OsinfoDb *db = dbRet->db;
+    int *ret = dbRet->ret;
+    GTree *section = (GTree *) value;
+    if (!section) {
+        *ret = -EINVAL;
+        return TRUE;
+    }
+
+    g_tree_foreach(section, __osinfoResolveDeviceLink, dbRet);
+    if (*ret)
+        return TRUE;
+    return FALSE;
+}
+
+static gboolean __osinfoResolveHvLink(gpointer key, gpointer value, gpointer data)
+{
+    gchar *hvId = (gchar *) key;
+    struct __osinfoDbRet *dbRet = (struct __osinfoDbRet *) data;
+    OsinfoDb *db = dbRet->db;
+    int *ret = dbRet->ret;
+    struct __osinfoHvSection *hvSection = (struct __osinfoHvSection *) value;
+    OsinfoHypervisor *hv;
+
+    g_tree_foreach(hvSection->sections, __osinfoResolveSectionDevices, dbRet);
+    if (*ret)
+        return TRUE;
+
+    hv = g_tree_lookup(db->priv->hypervisors, hvId);
+    if (!hv) {
+        *ret = -EINVAL;
+        return TRUE;
+    }
+
+    hvSection->hv = hv;
+    *ret = 0;
+    return FALSE;
+}
+
+static gboolean __osinfoResolveOsLink(gpointer key, gpointer value, gpointer data)
+{
+    gchar *targetOsId = (gchar *) key;
+    struct __osinfoDbRet *dbRet = (struct __osinfoDbRet *) data;
+    OsinfoDb *db = dbRet->db;
+    int *ret = dbRet->ret;
+    struct __osinfoOsLink *osLink = (struct __osinfoOsLink *) value;
+
+    OsinfoOs *targetOs;
+    targetOs = g_tree_lookup(db->priv->oses, targetOsId);
+    if (!targetOs) {
+        *ret = -EINVAL;
+        return TRUE;
+    }
+
+    osLink->directObjectOs = targetOs;
+    *ret = 0;
+    return FALSE;
+}
+
+static gboolean __osinfoFixOsLinks(gpointer key, gpointer value, gpointer data)
+{
+    struct __osinfoDbRet *dbRet = (struct __osinfoDbRet *) data;
+    OsinfoDb *db = dbRet->db;
+    int *ret = dbRet->ret;
+    OsinfoOs *os = OSINFO_OS(value);
+    if (!os) {
+        *ret = -EINVAL;
+        return TRUE;
+    }
+
+    g_tree_foreach(os->priv->sections, __osinfoResolveSectionDevices, dbRet);
+    if (*ret)
+        return TRUE;
+
+    g_tree_foreach(os->priv->relationshipsByOs, __osinfoResolveOsLink, dbRet);
+    if (*ret)
+        return TRUE;
+
+    g_tree_foreach(os->priv->hypervisors, __osinfoResolveHvLink, dbRet);
+    if (*ret)
+        return TRUE;
+
+    *ret = 0;
+    return FALSE;
+}
+
+static gboolean __osinfoFixHvLinks(gpointer key, gpointer value, gpointer data)
+{
+    struct __osinfoDbRet *dbRet = (struct __osinfoDbRet *) data;
+    OsinfoDb *db = dbRet->db;
+    int *ret = dbRet->ret;
+    OsinfoHypervisor *hv = OSINFO_HYPERVISOR(value);
+    if (!hv) {
+        *ret = -EINVAL;
+        return TRUE;
+    }
+
+    g_tree_foreach(hv->priv->sections, __osinfoResolveSectionDevices, dbRet);
+    if (*ret)
+        return TRUE;
+    return FALSE;
+}
+
+static int __osinfoFixObjLinks(OsinfoDb *db)
+{
+    OsinfoHypervisor *hv;
+    OsinfoOs *os;
+    int ret;
+
+    if (!OSINFO_IS_DB(db))
+        return -EINVAL;
+
+    struct __osinfoDbRet dbRet = {db, &ret};
+
+    g_tree_foreach(db->priv->hypervisors, __osinfoFixHvLinks, &dbRet);
+    if (ret)
+        return ret;
+    g_tree_foreach(db->priv->oses, __osinfoFixOsLinks, &dbRet);
+
+    return ret;
+}
+
+static int __osinfoProcessTag(xmlTextReaderPtr reader, char** ptr_to_key, char** ptr_to_val)
+{
+    int node_type, ret, err = 0;
+    char* key = NULL;
+    char* val = NULL;
+    const xmlChar* node_name, * end_node_name, * xml_value;
+
+    node_name = xmlTextReaderConstName(reader);
+    if (!node_name)
+        goto error;
+
+    key = strdup(node_name);
+    if (!key) {
+        err = -ENOMEM;
+        goto error;
+    }
+
+    /* Advance to next node */
+    ret = xmlTextReaderRead(reader);
+    if (ret != 1)
+        goto error;
+
+    /* Ensure node is a text node */
+    node_type = xmlTextReaderNodeType(reader);
+    if (node_type != TEXT_NODE)
+        goto error;
+
+    /* Store the value of the text node */
+    xml_value = xmlTextReaderConstValue(reader);
+    if (!xml_value)
+        goto error;
+
+    val = strdup(xml_value);
+    if (!val) {
+        err = -ENOMEM;
+        goto error;
+    }
+
+    /* Advance to the next node */
+    ret = xmlTextReaderRead(reader);
+    if (ret != 1)
+        goto error;
+
+    /* Ensure the node is an end node for the tracked start node */
+    node_type = xmlTextReaderNodeType(reader);
+    end_node_name = xmlTextReaderConstName(reader);
+    if (node_type != END_NODE ||
+        !end_node_name ||
+        strcmp(end_node_name, node_name) != 0)
+            goto error;
+
+    /* Now we have key and val with no errors so we return with success */
+    *ptr_to_key = key;
+    *ptr_to_val = val;
+    return 0;
+
+error:
+    free(key);
+    free(val);
+    *ptr_to_key = NULL;
+    *ptr_to_val = NULL;
+    if (err == 0)
+        err = -EINVAL;
+    return err;
+}
+
+static int __osinfoProcessDevSection(xmlTextReaderPtr reader,
+                                     GTree *section, GTree *sectionAsList)
+{
+    int err, empty, node_type;
+    char * sectionType, * id, * key = NULL, * driver = NULL;
+    const char * name;
+
+    if (!section)
+        return -EINVAL;
+
+    sectionType = xmlTextReaderGetAttribute(reader, "type");
+    empty = xmlTextReaderIsEmptyElement(reader);
+
+    if (!sectionType)
+        return -EINVAL;
+
+    /* If no devices in section then we are done */
+    if (empty)
+        return 0;
+
+    /* Otherwise, read in devices and add to section */
+    for (;;) {
+        /* Advance to next node */
+        err = xmlTextReaderRead(reader);
+        if (err != 1) {
+            err = -EINVAL;
+            goto error;
+        }
+
+        node_type = xmlTextReaderNodeType(reader);
+        name = xmlTextReaderConstName(reader);
+
+        /* If end of section, break */
+        if (node_type == END_NODE && strcmp(name, "section") == 0)
+            break;
+
+        /* If node is not start of an element, continue */
+        if (node_type != ELEMENT_NODE)
+            continue;
+
+        /* Element within section needs to be of type device */
+        if (strcmp(name, "device") != 0) {
+            err = -EINVAL;
+            goto error;
+        }
+
+        id = xmlTextReaderGetAttribute(reader, "id");
+        empty = xmlTextReaderIsEmptyElement(reader);
+
+        if (!id) {
+            err = -EINVAL;
+            goto error;
+        }
+
+        if (!empty) {
+            err = __osinfoProcessTag(reader, &key, &driver);
+            if (err != 0 || !key || !driver)
+                goto error;
+            free(key);
+            key = NULL; /* In case the next malloc fails, avoid a double free */
+        }
+
+        // Alright, we have the id and driver
+        err = __osinfoAddDeviceToSection(section, sectionAsList, sectionType, id, driver);
+        free (driver);
+        driver = NULL;
+        free (id);
+        id = NULL;
+        if (err != 0)
+            goto error;
+    }
+    free(sectionType);
+
+finished:
+    return 0;
+
+error:
+    free(sectionType);
+    free(key);
+    free(driver);
+    return err;
+}
+
+static int __osinfoProcessOsHvLink(xmlTextReaderPtr reader,
+                                   OsinfoOs *os)
+{
+    /*
+     * Get id for hypervisor else fail
+     * While true:
+     *   Advance to next node
+     *   If node is end of hypervisor break
+     *   If node is not element type continue
+     *   If node is element type and not section fail
+     *   Else handle section and add to hv_link
+     * If fail delete hv_link so far
+     * On success add hv_link to os
+     */
+    int empty, node_type, err;
+    char* id;
+    const xmlChar* name;
+    struct __osinfoHvSection *hvSection;
+
+    id = xmlTextReaderGetAttribute(reader, "id");
+    empty = xmlTextReaderIsEmptyElement(reader);
+
+    if (!id)
+        return -EINVAL;
+
+    hvSection = __osinfoAddHypervisorSectionToOs(os, id);
+    free(id);
+    if (!hvSection)
+        return -EINVAL;
+
+    if (empty)
+        goto finished;
+
+    for (;;) {
+        /* Advance to next node */
+        err = xmlTextReaderRead(reader);
+        if (err != 1) {
+            err = -EINVAL;
+            goto error;
+        }
+
+        node_type = xmlTextReaderNodeType(reader);
+        name = xmlTextReaderConstName(reader);
+        if (node_type == -1 || !name) {
+            err = -EINVAL;
+            goto error;
+        }
+
+        /* If end of hv link, break */
+        if (node_type == END_NODE && strcmp(name, "hypervisor") == 0)
+            break;
+
+        /* If node is not start of an element, continue */
+        if (node_type != ELEMENT_NODE)
+            continue;
+
+        /* Ensure it is element node of type 'section' else fail */
+        if (strcmp(name, "section") != 0) {
+            err = -EINVAL;
+            goto error;
+        }
+
+        /* Process device type info for this <os, hv> combination */
+        err = __osinfoProcessDevSection(reader, hvSection->sections, hvSection->sectionsAsList);
+        if (err != 0)
+            goto error;
+    }
+
+finished:
+    return 0;
+
+error:
+    return err;
+}
+
+static int __osinfoProcessOsRelationship(xmlTextReaderPtr reader,
+                                         OsinfoOs *os,
+                                         osinfoRelationship relationship)
+{
+    int empty, ret;
+    char* id;
+    struct osi_os_link * os_link;
+
+    id = xmlTextReaderGetAttribute(reader, "id");
+    empty = xmlTextReaderIsEmptyElement(reader);
+    if (!empty || !id) {
+        free(id);
+        return -EINVAL;
+    }
+
+    ret = __osinfoAddOsRelationship (os, id, relationship);
+    free(id);
+    return ret;
+}
+
+static int __osinfoProcessOs(OsinfoDb *db,
+                          xmlTextReaderPtr reader)
+{
+    /* Cursor is at start of (possibly empty) os node */
+    /*
+     * First, determine if hv has ID or not, and if tag is empty or not.
+     * The following cases can occur:
+     * 1. No ID: Return invalid. Parse fails overall.
+     * 2. Empty, ID: Make hv with given ID and no data and return.
+     * 3. Non-Empty, ID: Make hv, parse data till closing tag, return.
+     */
+
+    int empty, node_type, err, ret;
+    char* id, * key = NULL, * val = NULL;
+    const xmlChar* name;
+    OsinfoOs *os;
+
+    id = xmlTextReaderGetAttribute(reader, "id");
+    empty = xmlTextReaderIsEmptyElement(reader);
+
+    if (!id)
+        return -EINVAL;
+
+    os = g_object_new(OSINFO_TYPE_OS, "id", id, "db", db, NULL);
+    free(id);
+    if (!os)
+        return -ENOMEM;
+
+    if (empty)
+        goto finished;
+
+    /* Current node is start of non empty os
+     * While true:
+     *   Advance to next node
+     *   If node == end of os break
+     *   If node is not element, continue
+     *   If node is element and not section or hypervisor:
+     *     Note element name
+     *     Advance to next node, ensure type is text else error
+     *     Store value, advance to next node
+     *     Ensure node is end of current name
+     *     Store <key, val> in params list for object
+     *   If node is start of section handle section and track device driver
+     *   If node is hypervisor handle hypervisor link
+     */
+
+    for (;;) {
+        /* Advance to next node */
+        ret = xmlTextReaderRead(reader);
+        if (ret != 1) {
+            err = -EINVAL;
+            goto cleanup_error;
+        }
+
+        node_type = xmlTextReaderNodeType(reader);
+        name = xmlTextReaderConstName(reader);
+        if (node_type == -1 || !name) {
+            err = -EINVAL;
+            goto cleanup_error;
+        }
+        /* If end of os, break */
+        if (node_type == END_NODE && strcmp(name, "os") == 0)
+            break;
+
+        /* If node is not start of an element, continue */
+        if (node_type != ELEMENT_NODE)
+            continue;
+
+        if (strcmp(name, "section") == 0) {
+            /* Node is start of device section for os */
+            err = __osinfoProcessDevSection(reader, (OSINFO_OS(os))->priv->sections, (OSINFO_OS(os))->priv->sectionsAsList);
+            if (err != 0)
+                goto cleanup_error;
+        }
+        else if (strcmp(name, "hypervisor") == 0) {
+            err = __osinfoProcessOsHvLink(reader, os);
+            if (err != 0)
+                goto cleanup_error;
+        }
+        else if (strcmp(name, "upgrades") == 0) {
+            err = __osinfoProcessOsRelationship(reader, os, UPGRADES);
+            if (err != 0)
+                goto cleanup_error;
+        }
+        else if (strcmp(name, "clones") == 0) {
+            err = __osinfoProcessOsRelationship(reader, os, CLONES);
+            if (err != 0)
+                goto cleanup_error;
+        }
+        else if (strcmp(name, "derives-from") == 0) {
+            err = __osinfoProcessOsRelationship(reader, os, DERIVES_FROM);
+            if (err != 0)
+                goto cleanup_error;
+        }
+        else {
+            /* Node is start of element of known name */
+            err = __osinfoProcessTag(reader, &key, &val);
+            if (err != 0 || !key || !val)
+                goto cleanup_error;
+
+            err = __osinfoAddParam(OSINFO_ENTITY(os), key, val);
+            if (err != 0)
+                goto cleanup_error;
+
+            free(key);
+            free(val);
+        }
+    }
+
+finished:
+    __osinfoAddOsToDb(db, os);
+    return 0;
+    /* At end, cursor is at end of os node */
+
+cleanup_error:
+    g_object_unref(os);
+    return err;
+}
+
+static int __osinfoProcessHypervisor(OsinfoDb *db,
+                                  xmlTextReaderPtr reader)
+{
+    /* Cursor is at start of (possibly empty) hypervisor node */
+
+    /*
+     * First, determine if hv has ID or not, and if tag is empty or not.
+     * The following cases can occur:
+     * 1. No ID: Return invalid. Parse fails overall.
+     * 2. Empty, ID: Make hv with given ID and no data and return.
+     * 3. Non-Empty, ID: Make hv, parse data till closing tag, return.
+     */
+
+    int empty, node_type, err, ret;
+    char* id;
+    const xmlChar* name;
+    OsinfoHypervisor *hv;
+
+    id = xmlTextReaderGetAttribute(reader, "id");
+    empty = xmlTextReaderIsEmptyElement(reader);
+
+    if (!id)
+        return -EINVAL;
+
+
+    hv = g_object_new(OSINFO_TYPE_HYPERVISOR, "id", id, "db", db, NULL);
+    free(id);
+    if (!hv) {
+        return -ENOMEM;
+    }
+
+    if (empty)
+        goto finished;
+
+    /* Current node is start of non empty hv
+     * While true:
+     *   Advance to next node
+     *   If node == end of hv break
+     *   If node is not element, continue
+     *   If node is element and not section:
+     *     Note element name
+     *     Advance to next node, ensure type is text else error
+     *     Store value, advance to next node
+     *     Ensure node is end of current name
+     *     Store <key, val> in params list for object
+     *   If node is start of section:
+     *     Note section type
+     *     While true:
+     *       Advance to next node
+     *       If node is not element continue
+     *       If end of section, break
+     *       If not empty device node, parse error
+     *       If id not defined, parse error
+     *       Store id
+     *     Store all ids for given section in the HV
+     */
+
+    for (;;) {
+        /* Advance to next node */
+        ret = xmlTextReaderRead(reader);
+        if (ret != 1) {
+            err = -EINVAL;
+            goto cleanup_error;
+        }
+
+        node_type = xmlTextReaderNodeType(reader);
+        name = xmlTextReaderConstName(reader);
+        if (node_type == -1 || !name) {
+            err = -EINVAL;
+            goto cleanup_error;
+        }
+        /* If end of hv, break */
+        if (node_type == END_NODE && strcmp(name, "hypervisor") == 0)
+            break;
+
+        /* If node is not start of an element, continue */
+        if (node_type != ELEMENT_NODE)
+            continue;
+
+        if (strcmp(name, "section") == 0) {
+            /* Node is start of device section for hv */
+            err = __osinfoProcessDevSection(reader, (OSINFO_HYPERVISOR(hv))->priv->sections, (OSINFO_HYPERVISOR(hv))->priv->sectionsAsList);
+            if (err != 0)
+                goto cleanup_error;
+        }
+        else {
+            /* Node is start of element of known name */
+            char *key = NULL, *val = NULL;
+            err = __osinfoProcessTag(reader, &key, &val);
+            if (err != 0)
+                goto cleanup_error;
+
+
+            err = __osinfoAddParam(OSINFO_ENTITY(hv), key, val);
+            free(key);
+            free(val);
+            if (err != 0)
+                goto cleanup_error;
+        }
+    }
+
+finished:
+    __osinfoAddHypervisorToDb(db, hv);
+    return 0;
+    /* At end, cursor is at end of hv node */
+
+cleanup_error:
+    g_object_unref(hv);
+    return err;
+}
+
+static int __osinfoProcessDevice(OsinfoDb *db,
+                                 xmlTextReaderPtr reader)
+{
+    /* Cursor is at start of (possibly empty) device node */
+
+    /*
+     * First, determine if device has ID or not, and if tag is empty or not.
+     * The following cases can occur:
+     * 1. No ID: Return invalid. Parse fails overall.
+     * 2. Empty, ID: Make device with given ID and no data and return.
+     * 3. Non-Empty, ID: Make device, parse data till closing tag, return.
+     */
+
+    int empty, node_type, err, ret;
+    char* id, * key, * val;
+    const xmlChar* name;
+    OsinfoDevice *dev;
+
+    id = xmlTextReaderGetAttribute(reader, "id");
+    empty = xmlTextReaderIsEmptyElement(reader);
+
+    if (!id)
+        return -EINVAL;
+
+    dev = g_object_new(OSINFO_TYPE_DEVICE, "id", id, "db", db, NULL);
+    free(id);
+    if (!dev) {
+        // TODO: How do errors in gobject creation manifest themselves?
+        return -ENOMEM;
+    }
+
+    if (empty)
+        goto finished;
+
+    /* Current node is start of non empty device
+     * While true:
+     *   Advance to next node
+     *   If node == end of device break
+     *   If node is not element, continue
+     *   If node is element:
+     *     Note element name
+     *     Advance to next node, ensure type is text else error
+     *     Store value, advance to next node
+     *     Ensure node is end of current name
+     *     Store <key, val> in params list for object
+     */
+
+    for (;;) {
+        /* Advance to next node */
+        ret = xmlTextReaderRead(reader);
+        if (ret != 1) {
+            err = -EINVAL;
+            goto cleanup_error;
+        }
+
+        node_type = xmlTextReaderNodeType(reader);
+        name = xmlTextReaderConstName(reader);
+
+        if (node_type == -1 || !name) {
+            err = -EINVAL;
+            goto cleanup_error;
+        }
+
+        /* If end of device, break */
+        if (node_type == END_NODE && strcmp(name, "device") == 0)
+            break;
+
+        /* If node is not start of an element, continue */
+        if (node_type != ELEMENT_NODE)
+            continue;
+
+        /* Node is start of element of known name */
+        err = __osinfoProcessTag(reader, &key, &val);
+        if (err != 0 || !key || !val)
+            goto cleanup_error;
+
+        err = __osinfoAddParam(OSINFO_ENTITY(dev), key, val);
+        if (err != 0)
+            goto cleanup_error;
+
+        free(key);
+        free(val);
+    }
+
+finished:
+    // Add dev to db
+    __osinfoAddDeviceToDb(db, dev);
+    return 0;
+    /* At end, cursor is at end of device node */
+
+cleanup_error:
+    free(key);
+    free(val);
+    g_object_unref(dev);
+    return err;
+}
+
+static int __osinfoProcessFile(OsinfoDb *db,
+                               xmlTextReaderPtr reader)
+{
+    /*
+     * File assumed to contain data in XML format. All data
+     * is within <libosinfo>...</libosinfo>. The following steps are taken
+     * to process the data within the file:
+     *
+     * Advance till we are at opening <libosinfo> tag.
+     * While true:
+     *   Advance tag
+     *   If closing libosinfo tag, break
+     *   If non element tag, continue
+     *   If element tag, and element is not os, hypervisor or device, error
+     *   Else, switch on tag type and handle reading in data
+     * After loop, return success if no error
+     * If there was an error, clean up lib data acquired so far
+     */
+
+    int err, node_type, ret;
+    const char* name;
+
+    /* Advance to starting libosinfo tag */
+    for (;;) {
+        err = xmlTextReaderRead(reader);
+        if (err != 1) {
+            err = -EINVAL;
+            goto cleanup_error;
+        }
+
+        node_type = xmlTextReaderNodeType(reader);
+        if (node_type != ELEMENT_NODE)
+            continue;
+
+        name = xmlTextReaderConstName(reader);
+        if (strcmp(name, "libosinfo") == 0)
+            break;
+    }
+
+    /* Now read and handle each tag of interest */
+    for (;;) {
+        /* Advance to next node */
+        ret = xmlTextReaderRead(reader);
+        if (ret != 1) {
+            err = -EINVAL;
+            goto cleanup_error;
+        }
+
+        node_type = xmlTextReaderNodeType(reader);
+        name = xmlTextReaderConstName(reader);
+
+        if (node_type == -1 || !name) {
+            err = -EINVAL;
+            goto cleanup_error;
+        }
+
+        /* If end of libosinfo, break */
+        if (node_type == END_NODE && strcmp(name, "libosinfo") == 0)
+            break;
+
+        /* If node is not start of an element, continue */
+        if (node_type != ELEMENT_NODE)
+            continue;
+
+        /* Process element node */
+        if (strcmp(name, "device") == 0) {
+            err = __osinfoProcessDevice(db, reader);
+            if (err != 0)
+                goto cleanup_error;
+        }
+        else if (strcmp(name, "hypervisor") == 0) {
+            err = __osinfoProcessHypervisor(db, reader);
+            if (err != 0)
+                goto cleanup_error;
+        }
+        else if (strcmp(name, "os") == 0) {
+            err = __osinfoProcessOs(db, reader);
+            if (err != 0)
+                goto cleanup_error;
+        }
+        else {
+            err = -EINVAL;
+            goto cleanup_error;
+        }
+    }
+
+    /* And we are done, successfully */
+    return 0;
+
+cleanup_error:
+    // Db will be unsatisfactorily initiated, caller will call unref to clean it
+    return err;
+}
+
+static int __osinfoReadDataFile(OsinfoDb *db,
+                                const char *dir,
+                                const char *filename)
+{
+    int ret;
+    xmlTextReaderPtr reader;
+    char *rel_name = malloc (strlen(dir) + 1 + strlen(filename) + 1);
+    if (!rel_name)
+      return -errno;
+
+    stpcpy(stpcpy(stpcpy(rel_name, dir), "/"), filename);
+
+    reader = xmlReaderForFile(rel_name, NULL, 0);
+    free(rel_name);
+    if (!reader) {
+        return -EINVAL;
+    }
+    ret = __osinfoProcessFile(db, reader);
+    xmlFreeTextReader(reader);
+    return ret;
+}
+
+int __osinfoInitializeData(OsinfoDb *db)
+{
+    int ret;
+    DIR* dir;
+    struct dirent *dp;
+
+    char *backingDir;
+    g_object_get(G_OBJECT(db), "backing-dir", &backingDir, NULL);
+
+    /* Initialize library and check version */
+    LIBXML_TEST_VERSION
+
+    /* Get directory with backing data. Defaults to CWD */
+    if (!backingDir)
+      backingDir = ".";
+
+    /* Get XML files in directory */
+    dir = opendir(backingDir);
+    if (!dir) {
+        ret = errno;
+        goto cleanup;
+    }
+
+    while ((dp=readdir(dir)) != NULL) {
+        if (dp->d_type != DT_REG)
+            continue;
+        ret = __osinfoReadDataFile(db, backingDir, dp->d_name);
+        if (ret != 0)
+            break;
+    }
+    closedir(dir);
+    if (ret == 0)
+        ret = __osinfoFixObjLinks(db);
+
+cleanup:
+    xmlCleanupParser();
+    g_free(backingDir);
+    return ret;
+}
+
+#else
+int __osinfoInitializeData(OsinfoDb *db)
+{
+    return -ENOSYS;
+}
+#endif
diff --git a/osinfo/osinfo_db.c b/osinfo/osinfo_db.c
new file mode 100644
index 0000000..e669f78
--- /dev/null
+++ b/osinfo/osinfo_db.c
@@ -0,0 +1,555 @@
+#include <osinfo/osinfo.h>
+
+G_DEFINE_TYPE (OsinfoDb, osinfo_db, G_TYPE_OBJECT);
+
+#define OSINFO_DB_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), OSINFO_TYPE_DB, OsinfoDbPrivate))
+
+static void osinfo_db_set_property(GObject * object, guint prop_id,
+                                         const GValue * value,
+                                         GParamSpec * pspec);
+static void osinfo_db_get_property(GObject * object, guint prop_id,
+                                         GValue * value,
+                                         GParamSpec * pspec);
+static void osinfo_db_finalize (GObject *object);
+
+enum OSI_DB_PROPERTIES {
+    OSI_DB_PROP_0,
+
+    OSI_DB_BACKING_DIR,
+    OSI_DB_LIBVIRT_VER,
+    OSI_DB_ERROR
+};
+
+static void
+osinfo_db_finalize (GObject *object)
+{
+    OsinfoDb *self = OSINFO_DB (object);
+
+    g_free (self->priv->backing_dir);
+    g_free (self->priv->libvirt_ver);
+
+    g_tree_destroy(self->priv->devices);
+    g_tree_destroy(self->priv->hypervisors);
+    g_tree_destroy(self->priv->oses);
+
+    /* Chain up to the parent class */
+    G_OBJECT_CLASS (osinfo_db_parent_class)->finalize (object);
+}
+
+static void
+osinfo_db_set_property (GObject      *object,
+                        guint         property_id,
+                        const GValue *value,
+                        GParamSpec   *pspec)
+{
+    OsinfoDb *self = OSINFO_DB (object);
+
+    switch (property_id)
+      {
+      case OSI_DB_BACKING_DIR:
+        g_free(self->priv->backing_dir);
+        self->priv->backing_dir = g_value_dup_string (value);
+        break;
+
+      case OSI_DB_LIBVIRT_VER:
+        g_free(self->priv->libvirt_ver);
+        self->priv->libvirt_ver = g_value_dup_string (value);
+        break;
+
+      case OSI_DB_ERROR:
+        break;
+
+      default:
+        /* We don't have any other property... */
+        G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+        break;
+      }
+}
+
+static void
+osinfo_db_get_property (GObject    *object,
+                        guint       property_id,
+                        GValue     *value,
+                        GParamSpec *pspec)
+{
+    OsinfoDb *self = OSINFO_DB (object);
+
+    switch (property_id)
+      {
+      case OSI_DB_BACKING_DIR:
+        g_value_set_string (value, self->priv->backing_dir);
+        break;
+
+      case OSI_DB_LIBVIRT_VER:
+        g_value_set_string (value, self->priv->libvirt_ver);
+        break;
+
+      case OSI_DB_ERROR:
+        g_value_set_pointer(value, self->priv->error);
+        break;
+
+      default:
+        /* We don't have any other property... */
+        G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+        break;
+      }
+}
+
+/* Init functions */
+static void
+osinfo_db_class_init (OsinfoDbClass *klass)
+{
+    GObjectClass *g_klass = G_OBJECT_CLASS (klass);
+    GParamSpec *pspec;
+
+    g_klass->set_property = osinfo_db_set_property;
+    g_klass->get_property = osinfo_db_get_property;
+    g_klass->finalize = osinfo_db_finalize;
+
+    pspec = g_param_spec_string ("backing-dir",
+                                 "Backing directory",
+                                 "Contains backing data store.",
+                                 NULL /* default value */,
+                                 G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE);
+    g_object_class_install_property (g_klass,
+                                     OSI_DB_BACKING_DIR,
+                                     pspec);
+
+    pspec = g_param_spec_string ("libvirt-ver",
+                                 "Libvirt version",
+                                 "Libvirt version user is interested in",
+                                 NULL /* default value */,
+                                 G_PARAM_READWRITE);
+    g_object_class_install_property (g_klass,
+                                     OSI_DB_LIBVIRT_VER,
+                                     pspec);
+
+    pspec = g_param_spec_pointer ("error",
+                                  "Error",
+                                  "GError object for db",
+                                  G_PARAM_READABLE);
+    g_object_class_install_property (g_klass,
+                                     OSI_DB_ERROR,
+                                     pspec);
+
+    g_type_class_add_private (klass, sizeof (OsinfoDbPrivate));
+}
+
+
+static void
+osinfo_db_init (OsinfoDb *self)
+{
+    OsinfoDbPrivate *priv;
+    int ret;
+    self->priv = priv = OSINFO_DB_GET_PRIVATE(self);
+
+    self->priv->devices = g_tree_new_full(__osinfoStringCompare, NULL, g_free, g_object_unref);
+    self->priv->hypervisors = g_tree_new_full(__osinfoStringCompare, NULL, g_free, g_object_unref);
+    self->priv->oses = g_tree_new_full(__osinfoStringCompare, NULL, g_free, g_object_unref);
+
+    self->priv->error = NULL;
+    self->priv->ready = 0;
+}
+
+/** PUBLIC METHODS */
+
+int osinfoInitializeDb(OsinfoDb *self, GError **err)
+{
+    int ret;
+    // And now read in data.
+    ret = __osinfoInitializeData(self);
+    if (ret != 0) {
+        self->priv->ready = 0;
+        g_set_error_literal(err, g_quark_from_static_string("libosinfo"), ret, "Error during reading data");
+    }
+    else
+        self->priv->ready = 1;
+    return ret;
+}
+
+OsinfoHypervisor *osinfoGetHypervisorById(OsinfoDb *self, gchar *id, GError **err)
+{
+    if (!__osinfoCheckGErrorParamValid(err))
+        return NULL;
+
+    if (!OSINFO_IS_DB(self)) {
+        g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -EINVAL, OSINFO_OBJ_NOT_DB);
+        return NULL;
+    }
+
+    if (!id) {
+        g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -EINVAL, OSINFO_NO_ID);
+        return NULL;
+    }
+
+    return g_tree_lookup(self->priv->hypervisors, id);
+}
+
+OsinfoDevice *osinfoGetDeviceById(OsinfoDb *self, gchar *id, GError **err)
+{
+    if (!__osinfoCheckGErrorParamValid(err))
+        return NULL;
+
+    if (!OSINFO_IS_DB(self)) {
+        g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -EINVAL, OSINFO_OBJ_NOT_DB);
+        return NULL;
+    }
+
+    if (!id) {
+        g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -EINVAL, OSINFO_NO_ID);
+        return NULL;
+    }
+
+    return g_tree_lookup(self->priv->devices, id);
+}
+
+OsinfoOs *osinfoGetOsById(OsinfoDb *self, gchar *id, GError **err)
+{
+    if (!__osinfoCheckGErrorParamValid(err))
+        return NULL;
+
+    if (!OSINFO_IS_DB(self)) {
+        g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -EINVAL, OSINFO_OBJ_NOT_DB);
+        return NULL;
+    }
+
+    if (!id) {
+        g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -EINVAL, OSINFO_NO_ID);
+        return NULL;
+    }
+
+    return g_tree_lookup(self->priv->oses, id);
+}
+
+static gboolean __osinfoFilteredAddToList(gpointer key, gpointer value, gpointer data)
+{
+    struct __osinfoPopulateListArgs *args;
+    args = (struct __osinfoPopulateListArgs *) data;
+    OsinfoFilter *filter = args->filter;
+    OsinfoList *list = args->list;
+    GError **err = args->err;
+
+    // Key is string ID, value is pointer to entity
+    OsinfoEntity *entity = (OsinfoEntity *) value;
+    if (__osinfoEntityPassesFilter(filter, entity)) {
+        __osinfoListAdd(list, entity);
+    }
+
+    args->errcode = 0;
+
+    return FALSE; // continue iteration
+}
+
+static int __osinfoPopulateList(GTree *entities, OsinfoList *newList, OsinfoFilter *filter, GError **err)
+{
+    struct __osinfoPopulateListArgs args = {err, 0, filter, newList};
+    g_tree_foreach(entities, __osinfoFilteredAddToList, &args);
+    return args.errcode;
+}
+
+OsinfoOsList *osinfoGetOsList(OsinfoDb *self, OsinfoFilter *filter, GError **err)
+{
+    if (!__osinfoCheckGErrorParamValid(err))
+        return NULL;
+
+    if (!OSINFO_IS_DB(self)) {
+        g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -EINVAL, OSINFO_OBJ_NOT_DB);
+        return NULL;
+    }
+
+    if (filter && !OSINFO_IS_FILTER(filter)) {
+        g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -EINVAL, OSINFO_OBJ_NOT_FILTER);
+        return NULL;
+    }
+
+    // Create list
+    OsinfoOsList *newList = g_object_new(OSINFO_TYPE_OSLIST, NULL);
+    if (!newList) {
+        g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -ENOMEM, OSINFO_NO_MEM);
+        return NULL;
+    }
+
+    int ret;
+    ret = __osinfoPopulateList(self->priv->oses, OSINFO_LIST (newList), filter, err);
+    if (ret != 0) {
+        g_object_unref(newList);
+        g_set_error_literal(err, g_quark_from_static_string("libosinfo"), ret, __osinfoErrorToString(ret));
+        return NULL;
+    }
+
+    return newList;
+}
+
+OsinfoHypervisorList *osinfoGetHypervisorList(OsinfoDb *self, OsinfoFilter *filter, GError **err)
+{
+    if (!OSINFO_IS_DB(self)) {
+        g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -EINVAL, OSINFO_OBJ_NOT_DB);
+        return NULL;
+    }
+
+    if (filter && !OSINFO_IS_FILTER(filter)) {
+        g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -EINVAL, OSINFO_OBJ_NOT_FILTER);
+        return NULL;
+    }
+
+    // Create list
+    OsinfoHypervisorList *newList = g_object_new(OSINFO_TYPE_HYPERVISORLIST, NULL);
+    if (!newList) {
+        g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -ENOMEM, OSINFO_NO_MEM);
+        return NULL;
+    }
+
+    int ret;
+    ret = __osinfoPopulateList(self->priv->hypervisors, OSINFO_LIST (newList), filter, err);
+    if (ret != 0) {
+        g_object_unref(newList);
+        g_set_error_literal(err, g_quark_from_static_string("libosinfo"), ret, __osinfoErrorToString(ret));
+        return NULL;
+    }
+
+    return newList;
+}
+
+OsinfoDeviceList *osinfoGetDeviceList(OsinfoDb *self, OsinfoFilter *filter, GError **err)
+{
+    if (!OSINFO_IS_DB(self)) {
+        g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -EINVAL, OSINFO_OBJ_NOT_DB);
+        return NULL;
+    }
+
+    if (filter && !OSINFO_IS_FILTER(filter)) {
+        g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -EINVAL, OSINFO_OBJ_NOT_FILTER);
+        return NULL;
+    }
+
+    // Create list
+    OsinfoDeviceList *newList = g_object_new(OSINFO_TYPE_DEVICELIST, NULL);
+    if (!newList) {
+        g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -ENOMEM, OSINFO_NO_MEM);
+        return NULL;
+    }
+
+    int ret;
+    ret = __osinfoPopulateList(self->priv->devices, OSINFO_LIST (newList), filter, err);
+    if (ret != 0) {
+        g_object_unref(newList);
+        g_set_error_literal(err, g_quark_from_static_string("libosinfo"), ret, __osinfoErrorToString(ret));
+        return NULL;
+    }
+
+    return newList;
+}
+
+gboolean __osinfoGetPropertyValuesInEntity(gpointer key, gpointer value, gpointer data)
+{
+    struct __osinfoPopulateValuesArgs *args;
+    args = (struct __osinfoPopulateValuesArgs *) data;
+    GTree *values = args->values;
+    GError **err = args->err;
+    gchar *property = args->property;
+
+    OsinfoEntity *entity = OSINFO_ENTITY (value);
+    GPtrArray *valueArray = NULL;
+
+    valueArray = g_tree_lookup(entity->priv->params, property);
+    if (valueArray)
+        return FALSE; // No values here, skip
+
+    int i;
+    for (i = 0; i < valueArray->len; i++) {
+        gchar *currValue = g_ptr_array_index(valueArray, i);
+        void *test = g_tree_lookup(values, currValue);
+        if (test)
+            continue;
+        gchar *dupValue = g_strdup(currValue);
+        if (!dupValue) {
+            g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -ENOMEM, OSINFO_NO_MEM);
+            args->errcode = -ENOMEM;
+            return TRUE;
+        }
+
+        // Add to tree with dummy value
+        g_tree_insert(values, dupValue, (gpointer) 1);
+    }
+
+    return FALSE; // Continue iterating
+}
+
+static gboolean __osinfoPutKeysInList(gpointer key, gpointer value, gpointer data)
+{
+    gchar *currValue = (gchar *) key;
+    GPtrArray *valuesList = (GPtrArray *) data;
+
+    g_ptr_array_add(valuesList, currValue);
+    return FALSE; // keep iterating
+}
+
+static gboolean __osinfoFreeKeys(gpointer key, gpointer value, gpointer data)
+{
+    g_free(key);
+    return FALSE; // keep iterating
+}
+
+static GPtrArray *__osinfoUniqueValuesForPropertyInEntity(GTree *entities, gchar *propName, GError **err)
+{
+    GTree *values = g_tree_new(__osinfoStringCompareBase);
+    if (!values) {
+        g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -ENOMEM, OSINFO_NO_MEM);
+        return NULL;
+    }
+
+    struct __osinfoPopulateValuesArgs args = {err, 0, values, propName};
+    g_tree_foreach(entities, __osinfoGetPropertyValuesInEntity, &args);
+
+    if (args.errcode != 0) {
+        g_set_error_literal(err, g_quark_from_static_string("libosinfo"), args.errcode, __osinfoErrorToString(args.errcode));
+        g_tree_foreach(values, __osinfoFreeKeys, NULL);
+        g_tree_destroy(values);
+        return NULL;
+    }
+
+    // For each key in tree, add to gptrarray
+    GPtrArray *valuesList = g_ptr_array_sized_new(g_tree_nnodes(values));
+    if (!valuesList) {
+        g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -ENOMEM, OSINFO_NO_MEM);
+        g_tree_foreach(values, __osinfoFreeKeys, NULL);
+        g_tree_destroy(values);
+        return NULL;
+    }
+
+    g_tree_foreach(values, __osinfoPutKeysInList, valuesList);
+    g_tree_destroy(values);
+    return valuesList;
+}
+
+// Get me all unique values for property "vendor" among operating systems
+GPtrArray *osinfoUniqueValuesForPropertyInOs(OsinfoDb *self, gchar *propName, GError **err)
+{
+    if (!__osinfoCheckGErrorParamValid(err))
+        return NULL;
+
+    if (!OSINFO_IS_DB(self)) {
+        g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -EINVAL, OSINFO_OBJ_NOT_DB);
+        return NULL;
+    }
+
+    if (!propName) {
+        g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -EINVAL, OSINFO_NO_PROPNAME);
+        return NULL;
+    }
+
+    return __osinfoUniqueValuesForPropertyInEntity(self->priv->oses, propName, err);
+}
+
+// Get me all unique values for property "vendor" among hypervisors
+GPtrArray *osinfoUniqueValuesForPropertyInHv(OsinfoDb *self, gchar *propName, GError **err)
+{
+    if (!__osinfoCheckGErrorParamValid(err))
+        return NULL;
+
+    if (!OSINFO_IS_DB(self)) {
+        g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -EINVAL, OSINFO_OBJ_NOT_DB);
+        return NULL;
+    }
+
+    if (!propName) {
+        g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -EINVAL, OSINFO_NO_PROPNAME);
+        return NULL;
+    }
+
+    return __osinfoUniqueValuesForPropertyInEntity(self->priv->hypervisors, propName, err);
+}
+
+// Get me all unique values for property "vendor" among devices
+GPtrArray *osinfoUniqueValuesForPropertyInDev(OsinfoDb *self, gchar *propName, GError **err)
+{
+    if (!__osinfoCheckGErrorParamValid(err))
+        return NULL;
+
+    if (!OSINFO_IS_DB(self)) {
+        g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -EINVAL, OSINFO_OBJ_NOT_DB);
+        return NULL;
+    }
+
+    if (!propName) {
+        g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -EINVAL, OSINFO_NO_PROPNAME);
+        return NULL;
+    }
+
+    return __osinfoUniqueValuesForPropertyInEntity(self->priv->devices, propName, err);
+}
+
+static gboolean __osinfoAddOsIfRelationship(gpointer key, gpointer value, gpointer data)
+{
+    OsinfoOs *os = (OsinfoOs *) value;
+    struct __osinfoOsCheckRelationshipArgs *args;
+    args = (struct __osinfoOsCheckRelationshipArgs *) data;
+    GError **err = args->err;
+    OsinfoList *list = args->list;
+
+    GPtrArray *relatedOses = NULL;
+    relatedOses = g_tree_lookup(os->priv->relationshipsByType, (gpointer) args->relshp);
+    if (relatedOses) {
+        __osinfoListAdd(list, OSINFO_ENTITY (os));
+    }
+
+    return FALSE;
+}
+
+// Get me all OSes that 'upgrade' another OS (or whatever relationship is specified)
+OsinfoOsList *osinfoUniqueValuesForOsRelationship(OsinfoDb *self, osinfoRelationship relshp, GError **err)
+{
+    if (!__osinfoCheckGErrorParamValid(err))
+        return NULL;
+
+    if (!OSINFO_IS_DB(self)) {
+        g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -EINVAL, OSINFO_OBJ_NOT_DB);
+        return NULL;
+    }
+
+    if (!__osinfoCheckRelationshipValid(relshp)) {
+        g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -EINVAL, OSINFO_INVALID_RELATIONSHIP);
+        return NULL;
+    }
+
+    // Create list
+    OsinfoOsList *newList = g_object_new(OSINFO_TYPE_OSLIST, NULL);
+    if (!newList) {
+        g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -ENOMEM, OSINFO_NO_MEM);
+        return NULL;
+    }
+
+    struct __osinfoOsCheckRelationshipArgs args = {OSINFO_LIST (newList), 0, err, relshp};
+
+    g_tree_foreach(self->priv->oses, __osinfoAddOsIfRelationship, &args);
+    if (args.errcode != 0) {
+        g_set_error_literal(err, g_quark_from_static_string("libosinfo"), args.errcode, __osinfoErrorToString(args.errcode));
+        g_object_unref(newList);
+        return NULL;
+    }
+
+    return newList;
+}
+
+/**  PRIVATE */
+
+void __osinfoAddDeviceToDb(OsinfoDb *db, OsinfoDevice *dev)
+{
+    gchar *id;
+    g_object_get(G_OBJECT(dev), "id", &id, NULL);
+    g_tree_insert(db->priv->devices, id, dev);
+}
+
+void __osinfoAddHypervisorToDb(OsinfoDb *db, OsinfoHypervisor *hv)
+{
+    gchar *id;
+    g_object_get(G_OBJECT(hv), "id", &id, NULL);
+    g_tree_insert(db->priv->hypervisors, id, hv);
+}
+
+void __osinfoAddOsToDb(OsinfoDb *db, OsinfoOs *os)
+{
+    gchar *id;
+    g_object_get(G_OBJECT(os), "id", &id, NULL);
+    g_tree_insert(db->priv->oses, id, os);
+}
diff --git a/osinfo/osinfo_db.h b/osinfo/osinfo_db.h
new file mode 100644
index 0000000..305ed29
--- /dev/null
+++ b/osinfo/osinfo_db.h
@@ -0,0 +1,87 @@
+/*
+ * libosinfo
+ *
+ * osinfo_db.h
+ * Represents the main entry point to data contained by libosinfo.
+ */
+
+#ifndef __OSINFO_DB_H__
+#define __OSINFO_DB_H__
+
+#include "osinfo_devicelist.h"
+#include "osinfo_hypervisorlist.h"
+#include "osinfo_oslist.h"
+
+/*
+ * Type macros.
+ */
+#define OSINFO_TYPE_DB                  (osinfo_db_get_type ())
+#define OSINFO_DB(obj)                  (G_TYPE_CHECK_INSTANCE_CAST ((obj), OSINFO_TYPE_DB, OsinfoDb))
+#define OSINFO_IS_DB(obj)               (G_TYPE_CHECK_INSTANCE_TYPE ((obj), OSINFO_TYPE_DB))
+#define OSINFO_DB_CLASS(klass)          (G_TYPE_CHECK_CLASS_CAST ((klass), OSINFO_TYPE_DB, OsinfoDbClass))
+#define OSINFO_IS_DB_CLASS(klass)       (G_TYPE_CHECK_CLASS_TYPE ((klass), OSINFO_TYPE_DB))
+#define OSINFO_DB_GET_CLASS(obj)        (G_TYPE_INSTANCE_GET_CLASS ((obj), OSINFO_TYPE_DB, OsinfoDbClass))
+
+//typedef struct _OsinfoDb        OsinfoDb;
+// (defined in osinfo_objects.h)
+
+typedef struct _OsinfoDbClass   OsinfoDbClass;
+
+typedef struct _OsinfoDbPrivate OsinfoDbPrivate;
+
+/*
+ * To get a db handle, we construct one with a construct-time only
+ * backing data directory. It is already considered to be initialized
+ * on return from the constructor, and ready to do work.
+ *
+ * To close it, we call the destructor on it.
+ * Setting parameters on it will work if it's not a construct-time only
+ * parameter. Reading will always work. Currently the backing directory and
+ * libvirt version are the only parameters.
+ *
+ * The db object contains information related to three main classes of
+ * objects: hypervisors, operating systems and devices.
+ */
+
+/* object */
+struct _OsinfoDb
+{
+    GObject parent_instance;
+
+    /* public */
+
+    /* private */
+    OsinfoDbPrivate *priv;
+};
+
+/* class */
+struct _OsinfoDbClass
+{
+    GObjectClass parent_class;
+
+    /* class members */
+};
+
+int osinfoInitializeDb(OsinfoDb *self, GError **err);
+
+OsinfoHypervisor *osinfoGetHypervisorById(OsinfoDb *self, gchar *hvId, GError **err);
+OsinfoDevice *osinfoGetDeviceById(OsinfoDb *self, gchar *devId, GError **err);
+OsinfoOs *osinfoGetOsById(OsinfoDb *self, gchar *osId, GError **err);
+
+OsinfoOsList *osinfoGetOsList(OsinfoDb *self, OsinfoFilter *filter, GError **err);
+OsinfoHypervisorList *osinfoGetHypervisorList(OsinfoDb *self, OsinfoFilter *filter, GError **err);
+OsinfoDeviceList *osinfoGetDeviceList(OsinfoDb *self, OsinfoFilter *filter, GError **err);
+
+// Get me all unique values for property "vendor" among operating systems
+GPtrArray *osinfoUniqueValuesForPropertyInOs(OsinfoDb *self, gchar *propName, GError **err);
+
+// Get me all unique values for property "vendor" among hypervisors
+GPtrArray *osinfoUniqueValuesForPropertyInHv(OsinfoDb *self, gchar *propName, GError **err);
+
+// Get me all unique values for property "vendor" among devices
+GPtrArray *osinfoUniqueValuesForPropertyInDev(OsinfoDb *self, gchar *propName, GError **err);
+
+// Get me all OSes that 'upgrade' another OS (or whatever relationship is specified)
+OsinfoOsList *osinfoUniqueValuesForOsRelationship(OsinfoDb *self, osinfoRelationship relshp, GError **err);
+
+#endif /* __OSINFO_DB_H__ */
diff --git a/osinfo/osinfo_device.c b/osinfo/osinfo_device.c
new file mode 100644
index 0000000..d43c405
--- /dev/null
+++ b/osinfo/osinfo_device.c
@@ -0,0 +1,94 @@
+#include <osinfo/osinfo.h>
+
+G_DEFINE_TYPE (OsinfoDevice, osinfo_device, OSINFO_TYPE_ENTITY);
+
+#define OSINFO_DEVICE_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), OSINFO_TYPE_DEVICE, OsinfoDevicePrivate))
+
+static void osinfo_device_finalize (GObject *object);
+
+static void
+osinfo_device_finalize (GObject *object)
+{
+    OsinfoDevice *self = OSINFO_DEVICE (object);
+
+    /* Chain up to the parent class */
+    G_OBJECT_CLASS (osinfo_device_parent_class)->finalize (object);
+}
+
+/* Init functions */
+static void
+osinfo_device_class_init (OsinfoDeviceClass *klass)
+{
+    GObjectClass *g_klass = G_OBJECT_CLASS (klass);
+
+    g_klass->finalize = osinfo_device_finalize;
+    g_type_class_add_private (klass, sizeof (OsinfoDevicePrivate));
+}
+
+static void
+osinfo_device_init (OsinfoDevice *self)
+{
+    OsinfoDevicePrivate *priv;
+    self->priv = priv = OSINFO_DEVICE_GET_PRIVATE(self);
+}
+
+gchar *osinfoGetDeviceDriver(OsinfoDevice *self,
+                             gchar *devType,
+                             OsinfoOs *os,
+                             OsinfoHypervisor *hv,
+                             GError **err)
+{
+    if (!__osinfoCheckGErrorParamValid(err))
+        return NULL;
+
+    if (!OSINFO_IS_DEVICE(self)) {
+        g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -EINVAL, OSINFO_OBJ_NOT_DEVICE);
+        return NULL;
+    }
+
+    if (!OSINFO_IS_OS(os)) {
+        g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -EINVAL, OSINFO_OBJ_NOT_OS);
+        return NULL;
+    }
+
+    if (!OSINFO_IS_HYPERVISOR(hv)) {
+        g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -EINVAL, OSINFO_OBJ_NOT_HV);
+        return NULL;
+    }
+
+    if (!devType) {
+        g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -EINVAL, OSINFO_NO_DEVTYPE);
+        return NULL;
+    }
+
+    gchar *driver = NULL;
+
+    // For os, get hypervisor specific info. If not present, return NULL.
+    struct __osinfoHvSection *hvSection = NULL;
+    hvSection = g_tree_lookup(os->priv->hypervisors, (OSINFO_ENTITY(hv))->priv->id);
+    if (!hvSection)
+        return NULL;
+
+    // Check for info for type of devices in <os,hv>. If not found, return NULL.
+    GTree *section = NULL;
+    section = g_tree_lookup(hvSection->sections, devType);
+    if (!section)
+        return NULL;
+
+    // Check device section for device. If not found, return NULL.
+    struct __osinfoDeviceLink *deviceLink = NULL;
+    deviceLink = g_tree_lookup(section, (OSINFO_ENTITY(self))->priv->id);
+    if (!deviceLink)
+        return NULL;
+
+    if (!deviceLink->driver)
+        return NULL;
+
+    driver = g_strdup(deviceLink->driver);
+    if (!driver) {
+        g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -ENOMEM, OSINFO_NO_MEM);
+        return NULL;
+    }
+
+    return driver;
+}
diff --git a/osinfo/osinfo_device.h b/osinfo/osinfo_device.h
new file mode 100644
index 0000000..9f10e6b
--- /dev/null
+++ b/osinfo/osinfo_device.h
@@ -0,0 +1,49 @@
+/*
+ * libosinfo
+ *
+ * osinfo_device.h
+ * Represents a device in libosinfo.
+ */
+
+#ifndef __OSINFO_DEVICE_H__
+#define __OSINFO_DEVICE_H__
+
+/*
+ * Type macros.
+ */
+#define OSINFO_TYPE_DEVICE                  (osinfo_device_get_type ())
+#define OSINFO_DEVICE(obj)                  (G_TYPE_CHECK_INSTANCE_CAST ((obj), OSINFO_TYPE_DEVICE, OsinfoDevice))
+#define OSINFO_IS_DEVICE(obj)               (G_TYPE_CHECK_INSTANCE_TYPE ((obj), OSINFO_TYPE_DEVICE))
+#define OSINFO_DEVICE_CLASS(klass)          (G_TYPE_CHECK_CLASS_CAST ((klass), OSINFO_TYPE_DEVICE, OsinfoDeviceClass))
+#define OSINFO_IS_DEVICE_CLASS(klass)       (G_TYPE_CHECK_CLASS_TYPE ((klass), OSINFO_TYPE_DEVICE))
+#define OSINFO_DEVICE_GET_CLASS(obj)        (G_TYPE_INSTANCE_GET_CLASS ((obj), OSINFO_TYPE_DEVICE, OsinfoDeviceClass))
+
+//typedef struct _OsinfoDevice        OsinfoDevice;
+// (defined in osinfo_objects.h)
+
+typedef struct _OsinfoDeviceClass   OsinfoDeviceClass;
+
+typedef struct _OsinfoDevicePrivate OsinfoDevicePrivate;
+
+/* object */
+struct _OsinfoDevice
+{
+    OsinfoEntity parent_instance;
+
+    /* public */
+
+    /* private */
+    OsinfoDevicePrivate *priv;
+};
+
+/* class */
+struct _OsinfoDeviceClass
+{
+    OsinfoEntityClass parent_class;
+
+    /* class members */
+};
+
+gchar *osinfoGetDeviceDriver(OsinfoDevice *self, gchar *devType, OsinfoOs *os, OsinfoHypervisor *hv, GError **err);
+
+#endif /* __OSINFO_DEVICE_H__ */
diff --git a/osinfo/osinfo_devicelist.c b/osinfo/osinfo_devicelist.c
new file mode 100644
index 0000000..af6f6c0
--- /dev/null
+++ b/osinfo/osinfo_devicelist.c
@@ -0,0 +1,121 @@
+#include <osinfo/osinfo.h>
+
+G_DEFINE_TYPE (OsinfoDeviceList, osinfo_devicelist, OSINFO_TYPE_LIST);
+
+#define OSINFO_DEVICELIST_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), OSINFO_TYPE_DEVICELIST, OsinfoDeviceListPrivate))
+
+static void osinfo_devicelist_finalize (GObject *object);
+
+struct _OsinfoDeviceListPrivate
+{
+    int tmp;
+};
+
+static void
+osinfo_devicelist_finalize (GObject *object)
+{
+    /* Chain up to the parent class */
+    G_OBJECT_CLASS (osinfo_devicelist_parent_class)->finalize (object);
+}
+
+/* Init functions */
+static void
+osinfo_devicelist_class_init (OsinfoDeviceListClass *klass)
+{
+    GObjectClass *g_klass = G_OBJECT_CLASS (klass);
+
+    g_klass->finalize = osinfo_devicelist_finalize;
+    g_type_class_add_private (klass, sizeof (OsinfoDeviceListPrivate));
+}
+
+static void
+osinfo_devicelist_init (OsinfoDeviceList *self)
+{
+    OsinfoDeviceListPrivate *priv;
+    self->priv = priv = OSINFO_DEVICELIST_GET_PRIVATE(self);
+
+}
+
+OsinfoDevice *osinfoGetDeviceAtIndex(OsinfoDeviceList *self, gint idx, GError **err)
+{
+    if (!OSINFO_IS_DEVICELIST(self)) {
+        g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -EINVAL, OSINFO_OBJ_NOT_DEVICELIST);
+        return NULL;
+    }
+
+    OsinfoList *selfAsList = OSINFO_LIST (self);
+    OsinfoEntity *entity = osinfoGetEntityAtIndex(selfAsList, idx);
+    return OSINFO_DEVICE (entity);
+}
+
+OsinfoDeviceList *osinfoDeviceListFilter(OsinfoDeviceList *self, OsinfoFilter *filter, GError **err)
+{
+    if (!OSINFO_IS_DEVICELIST(self)) {
+        g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -EINVAL, OSINFO_OBJ_NOT_DEVICELIST);
+        return NULL;
+    }
+
+    if (filter && !OSINFO_IS_FILTER(filter)) {
+        g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -EINVAL, OSINFO_OBJ_NOT_FILTER);
+        return NULL;
+    }
+
+    // For each element in self, if passes filter, add to new list.
+    OsinfoDeviceList *newList = g_object_new(OSINFO_TYPE_DEVICELIST, NULL);
+    if (!newList) {
+        g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -ENOMEM, OSINFO_NO_MEM);
+        return NULL;
+    }
+
+    __osinfoDoFilter(OSINFO_LIST (self), OSINFO_LIST (newList), filter);
+    return newList;
+}
+
+OsinfoDeviceList *osinfoDeviceListIntersect(OsinfoDeviceList *self, OsinfoDeviceList *otherList, GError **err)
+{
+    if (!OSINFO_IS_DEVICELIST(self) || !OSINFO_IS_DEVICELIST(otherList)) {
+        g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -EINVAL, OSINFO_OBJ_NOT_DEVICELIST);
+        return NULL;
+    }
+
+    OsinfoDeviceList *newList = g_object_new(OSINFO_TYPE_DEVICELIST, NULL);
+    if (!newList) {
+        g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -ENOMEM, OSINFO_NO_MEM);
+        return NULL;
+    }
+
+    int ret;
+
+    ret = __osinfoDoIntersect(self, otherList, newList);
+    if (ret != 0) {
+        g_object_unref(newList);
+        g_set_error_literal(err, g_quark_from_static_string("libosinfo"), ret, __osinfoErrorToString(ret));
+        return NULL;
+    }
+
+    return newList;
+}
+
+OsinfoDeviceList *osinfoDeviceListUnion(OsinfoDeviceList *self, OsinfoDeviceList *otherList, GError **err)
+{
+    if (!OSINFO_IS_DEVICELIST(self) || !OSINFO_IS_DEVICELIST(otherList)) {
+        g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -EINVAL, OSINFO_OBJ_NOT_DEVICELIST);
+        return NULL;
+    }
+
+    OsinfoDeviceList *newList = g_object_new(OSINFO_TYPE_DEVICELIST, NULL);
+    if (!newList) {
+        g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -ENOMEM, OSINFO_NO_MEM);
+        return NULL;
+    }
+
+    int ret;
+    ret = __osinfoDoUnion(self, otherList, newList);
+    if (ret != 0) {
+        g_object_unref(newList);
+        g_set_error_literal(err, g_quark_from_static_string("libosinfo"), ret, __osinfoErrorToString(ret));
+        return NULL;
+    }
+
+    return newList;
+}
diff --git a/osinfo/osinfo_devicelist.h b/osinfo/osinfo_devicelist.h
new file mode 100644
index 0000000..49e2715
--- /dev/null
+++ b/osinfo/osinfo_devicelist.h
@@ -0,0 +1,50 @@
+/*
+ * libosinfo
+ *
+ * osinfo_devicelist.h
+ */
+
+#ifndef __OSINFO_DEVICELIST_H__
+#define __OSINFO_DEVICELIST_H__
+
+/*
+ * Type macros.
+ */
+#define OSINFO_TYPE_DEVICELIST                  (osinfo_devicelist_get_type ())
+#define OSINFO_DEVICELIST(obj)                  (G_TYPE_CHECK_INSTANCE_CAST ((obj), OSINFO_TYPE_DEVICELIST, OsinfoDeviceList))
+#define OSINFO_IS_DEVICELIST(obj)               (G_TYPE_CHECK_INSTANCE_TYPE ((obj), OSINFO_TYPE_DEVICELIST))
+#define OSINFO_DEVICELIST_CLASS(klass)          (G_TYPE_CHECK_CLASS_CAST ((klass), OSINFO_TYPE_DEVICELIST, OsinfoDeviceListClass))
+#define OSINFO_IS_DEVICELIST_CLASS(klass)       (G_TYPE_CHECK_CLASS_TYPE ((klass), OSINFO_TYPE_DEVICELIST))
+#define OSINFO_DEVICELIST_GET_CLASS(obj)        (G_TYPE_INSTANCE_GET_CLASS ((obj), OSINFO_TYPE_DEVICELIST, OsinfoDeviceListClass))
+
+typedef struct _OsinfoDeviceList        OsinfoDeviceList;
+
+typedef struct _OsinfoDeviceListClass   OsinfoDeviceListClass;
+
+typedef struct _OsinfoDeviceListPrivate OsinfoDeviceListPrivate;
+
+/* object */
+struct _OsinfoDeviceList
+{
+    GObject parent_instance;
+
+    /* public */
+
+    /* private */
+    OsinfoDeviceListPrivate *priv;
+};
+
+/* class */
+struct _OsinfoDeviceListClass
+{
+    GObjectClass parent_class;
+
+    /* class members */
+};
+
+OsinfoDeviceList *osinfoDeviceListFilter(OsinfoDeviceList *self, OsinfoFilter *filter, GError **err);
+OsinfoDevice *osinfoGetDeviceAtIndex(OsinfoDeviceList *self, gint idx, GError **err);
+OsinfoDeviceList *osinfoDeviceListIntersect(OsinfoDeviceList *self, OsinfoDeviceList *otherDeviceList, GError **err);
+OsinfoDeviceList *osinfoDeviceListUnion(OsinfoDeviceList *self, OsinfoDeviceList *otherDeviceList, GError **err);
+
+#endif /* __OSINFO_DEVICELIST_H__ */
diff --git a/osinfo/osinfo_entity.c b/osinfo/osinfo_entity.c
new file mode 100644
index 0000000..cbf33e0
--- /dev/null
+++ b/osinfo/osinfo_entity.c
@@ -0,0 +1,321 @@
+#include <osinfo/osinfo.h>
+
+G_DEFINE_ABSTRACT_TYPE (OsinfoEntity, osinfo_entity, G_TYPE_OBJECT);
+
+#define OSINFO_ENTITY_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), OSINFO_TYPE_ENTITY, OsinfoEntityPrivate))
+
+static void osinfo_entity_finalize (GObject *object);
+
+enum OSI_ENTITY_PROPERTIES {
+    OSI_ENTITY_PROP_0,
+
+    OSI_ENTITY_ID,
+    OSI_DB_PTR
+};
+
+static void
+osinfo_entity_set_property (GObject      *object,
+                            guint         property_id,
+                            const GValue *value,
+                            GParamSpec   *pspec)
+{
+    OsinfoEntity *self = OSINFO_ENTITY (object);
+
+    switch (property_id)
+      {
+      case OSI_ENTITY_ID:
+        g_free(self->priv->id);
+        self->priv->id = g_value_dup_string (value);
+        break;
+      case OSI_DB_PTR:
+        self->priv->db = g_value_get_pointer (value);
+        break;
+      default:
+        /* We don't have any other property... */
+        G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+        break;
+      }
+}
+
+static void
+osinfo_entity_get_property (GObject    *object,
+                            guint       property_id,
+                            GValue     *value,
+                            GParamSpec *pspec)
+{
+    OsinfoEntity *self = OSINFO_ENTITY (object);
+
+    switch (property_id)
+      {
+      case OSI_ENTITY_ID:
+        g_value_set_string (value, self->priv->id);
+        break;
+      case OSI_DB_PTR:
+        g_value_set_pointer(value, self->priv->db);
+        break;
+      default:
+        /* We don't have any other property... */
+        G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+        break;
+      }
+}
+
+static void
+osinfo_entity_finalize (GObject *object)
+{
+    OsinfoEntity *self = OSINFO_ENTITY (object);
+
+    g_free (self->priv->id);
+    g_tree_destroy (self->priv->params);
+
+    /* Chain up to the parent class */
+    G_OBJECT_CLASS (osinfo_entity_parent_class)->finalize (object);
+}
+
+/* Init functions */
+static void
+osinfo_entity_class_init (OsinfoEntityClass *klass)
+{
+    GObjectClass *g_klass = G_OBJECT_CLASS (klass);
+    GParamSpec *pspec;
+
+    g_klass->set_property = osinfo_entity_set_property;
+    g_klass->get_property = osinfo_entity_get_property;
+
+    pspec = g_param_spec_string ("id",
+                                 "ID",
+                                 "Contains unique identifier for entity.",
+                                 NULL /* default value */,
+                                 G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE);
+    g_object_class_install_property (g_klass,
+                                     OSI_ENTITY_ID,
+                                     pspec);
+    pspec = g_param_spec_pointer ("db",
+                                 "Db pointer",
+                                 "Contains backpointer to libosinfo db object.",
+                                 G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE);
+    g_object_class_install_property (g_klass,
+                                     OSI_DB_PTR,
+                                     pspec);
+
+    g_klass->finalize = osinfo_entity_finalize;
+    g_type_class_add_private (klass, sizeof (OsinfoEntityPrivate));
+}
+
+static void
+osinfo_entity_init (OsinfoEntity *self)
+{
+    OsinfoEntityPrivate *priv;
+    self->priv = priv = OSINFO_ENTITY_GET_PRIVATE(self);
+
+    self->priv->params = g_tree_new_full(__osinfoStringCompare, NULL, g_free, __osinfoFreeParamVals);
+}
+
+int __osinfoAddParam(OsinfoEntity *self, gchar *key, gchar *value)
+{
+    if (!OSINFO_IS_ENTITY(self) || !key || !value)
+        return -EINVAL;
+
+    // First check if there exists an existing array of entries for this key
+    // If not, create a ptrarray of strings for this key and insert into map
+    gboolean found;
+    gpointer origKey, foundValue;
+    GPtrArray *valueArray;
+    gchar *valueDup = NULL, *keyDup = NULL;
+
+    valueDup = g_strdup(value);
+
+    if (!valueDup)
+        goto error_free;
+
+    found = g_tree_lookup_extended(self->priv->params, key, &origKey, &foundValue);
+    if (!found) {
+        keyDup = g_strdup(key);
+        valueArray = g_ptr_array_new_with_free_func(g_free);
+
+        if (!valueArray)
+            goto error_free;
+        if (!keyDup) {
+            g_ptr_array_free(valueArray, TRUE);
+            goto error_free;
+        }
+
+        g_tree_insert(self->priv->params, keyDup, valueArray);
+    }
+    else
+        valueArray = (GPtrArray *) foundValue;
+
+    // Add a copy of the value to the array
+    g_ptr_array_add(valueArray, valueDup);
+    return 0;
+
+error_free:
+    g_free(keyDup);
+    g_free(valueDup);
+    return -ENOMEM;
+}
+
+void __osinfoClearParam(OsinfoEntity *self, gchar *key)
+{
+    g_tree_remove(self->priv->params, key);
+}
+
+gboolean __osinfoGetKeys(gpointer key, gpointer value, gpointer data)
+{
+    struct __osinfoPtrArrayErr *arrayErr = (struct __osinfoPtrArrayErr *) data;
+    GPtrArray *results = arrayErr->array;
+    gchar *keyDup = g_strdup(key);
+
+    if (!keyDup) {
+        arrayErr->err = -ENOMEM;
+        return TRUE;
+    }
+    g_ptr_array_add(results, keyDup);
+    return FALSE; // Continue iterating
+}
+
+void __osinfoDupArray(gpointer data, gpointer user_data)
+{
+    struct __osinfoPtrArrayErr *arrayErr = (struct __osinfoPtrArrayErr *) data;
+    GPtrArray *results = arrayErr->array;
+
+    if (arrayErr->err != 0)
+        return;
+
+    gchar *valueDup = g_strdup((gchar *)data);
+    if (!valueDup) {
+        arrayErr->err = -ENOMEM;
+        return;
+    }
+    g_ptr_array_add(results, valueDup);
+}
+
+gchar *osinfoGetId(OsinfoEntity *self, GError **err)
+{
+    if (!__osinfoCheckGErrorParamValid(err))
+        return NULL;
+
+    if (!OSINFO_IS_ENTITY(self)) {
+        g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -EINVAL, OSINFO_OBJ_NOT_ENTITY);
+        return NULL;
+    }
+
+    gchar *dupId = g_strdup(self->priv->id);
+    if (!dupId) {
+        g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -ENOMEM, OSINFO_NO_MEM);
+        return NULL;
+    }
+    return dupId;
+}
+
+GPtrArray *osinfoGetParams(OsinfoEntity *self, GError **err)
+{
+    if (!__osinfoCheckGErrorParamValid(err))
+        return NULL;
+
+    if (!OSINFO_IS_ENTITY(self)) {
+        g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -EINVAL, OSINFO_OBJ_NOT_ENTITY);
+        return NULL;
+    }
+
+    GPtrArray *params = g_ptr_array_new();
+    if (!params) {
+        g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -ENOMEM, OSINFO_NO_MEM);
+        return NULL;
+    }
+
+    struct __osinfoPtrArrayErr arrayErr = {params, 0};
+    g_tree_foreach(self->priv->params, __osinfoGetKeys, &arrayErr);
+
+    // If we had an error, cleanup and return NULL
+    if (arrayErr.err != 0) {
+        int i;
+        for (i = 0; i < params->len; i++)
+            g_free(g_ptr_array_index(params, i));
+        g_ptr_array_free(params, TRUE);
+        g_set_error_literal(err, g_quark_from_static_string("libosinfo"), arrayErr.err, __osinfoErrorToString(arrayErr.err));
+        return NULL;
+    }
+
+    return params;
+}
+
+gchar *osinfoGetParamValue(OsinfoEntity *self, gchar *key, GError **err)
+{
+    if (!__osinfoCheckGErrorParamValid(err))
+        return NULL;
+
+    if (!OSINFO_IS_ENTITY(self)) {
+        g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -EINVAL, OSINFO_OBJ_NOT_ENTITY);
+        return NULL;
+    }
+
+    if (!key) {
+        g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -EINVAL, OSINFO_NO_PROPNAME);
+        return NULL;
+    }
+
+    gboolean found;
+    gpointer origKey, value;
+    gchar *firstValueDup;
+    GPtrArray *array;
+
+    found = g_tree_lookup_extended(self->priv->params, key, &origKey, &value);
+    if (!found)
+        return NULL;
+    array = (GPtrArray *) value;
+    if (array->len == 0)
+        return NULL;
+
+    firstValueDup = g_strdup(g_ptr_array_index(array, 0));
+    if (!firstValueDup) {
+        g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -ENOMEM, OSINFO_NO_MEM);
+        return NULL;
+    }
+
+    return firstValueDup;
+}
+
+GPtrArray *osinfoGetParamAllValues(OsinfoEntity *self, gchar *key, GError **err)
+{
+    if (!__osinfoCheckGErrorParamValid(err))
+        return NULL;
+
+    if (!OSINFO_IS_ENTITY(self)) {
+        g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -EINVAL, OSINFO_OBJ_NOT_ENTITY);
+        return NULL;
+    }
+
+    if (!key) {
+        g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -EINVAL, OSINFO_NO_PROPNAME);
+        return NULL;
+    }
+
+    gboolean found;
+    gpointer origKey, value;
+    GPtrArray *srcArray, *retArray;
+
+    retArray = g_ptr_array_new();
+    if (!retArray) {
+        g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -ENOMEM, OSINFO_NO_MEM);
+        return NULL;
+    }
+
+    found = g_tree_lookup_extended(self->priv->params, key, &origKey, &value);
+    if (!found)
+        return retArray;
+    srcArray = (GPtrArray *) value;
+    if (srcArray->len == 0)
+        return retArray;
+
+    struct __osinfoPtrArrayErr arrayErr = {retArray, 0};
+    g_ptr_array_foreach(srcArray, __osinfoDupArray, &arrayErr);
+    if (arrayErr.err) {
+        g_set_error_literal(err, g_quark_from_static_string("libosinfo"), arrayErr.err, __osinfoErrorToString(arrayErr.err));
+        g_ptr_array_set_free_func(retArray, g_free);
+        g_ptr_array_free(retArray, TRUE);
+        return NULL;
+    }
+
+    return retArray;
+}
diff --git a/osinfo/osinfo_entity.h b/osinfo/osinfo_entity.h
new file mode 100644
index 0000000..0c8047c
--- /dev/null
+++ b/osinfo/osinfo_entity.h
@@ -0,0 +1,51 @@
+/*
+ * libosinfo
+ *
+ * osinfo_entity.h
+ * All entities represented in libosinfo are derived from this class.
+ */
+
+#ifndef __OSINFO_ENTITY_H__
+#define __OSINFO_ENTITY_H__
+
+/*
+ * Type macros.
+ */
+#define OSINFO_TYPE_ENTITY                  (osinfo_entity_get_type ())
+#define OSINFO_ENTITY(obj)                  (G_TYPE_CHECK_INSTANCE_CAST ((obj), OSINFO_TYPE_ENTITY, OsinfoEntity))
+#define OSINFO_IS_ENTITY(obj)               (G_TYPE_CHECK_INSTANCE_TYPE ((obj), OSINFO_TYPE_ENTITY))
+#define OSINFO_ENTITY_CLASS(klass)          (G_TYPE_CHECK_CLASS_CAST ((klass), OSINFO_TYPE_ENTITY, OsinfoEntityClass))
+#define OSINFO_IS_ENTITY_CLASS(klass)       (G_TYPE_CHECK_CLASS_TYPE ((klass), OSINFO_TYPE_ENTITY))
+#define OSINFO_ENTITY_GET_CLASS(obj)        (G_TYPE_INSTANCE_GET_CLASS ((obj), OSINFO_TYPE_ENTITY, OsinfoEntityClass))
+
+typedef struct _OsinfoEntity        OsinfoEntity;
+
+typedef struct _OsinfoEntityClass   OsinfoEntityClass;
+
+typedef struct _OsinfoEntityPrivate OsinfoEntityPrivate;
+
+/* object */
+struct _OsinfoEntity
+{
+    GObject parent_instance;
+
+    /* public */
+
+    /* private */
+    OsinfoEntityPrivate *priv;
+};
+
+/* class */
+struct _OsinfoEntityClass
+{
+    GObjectClass parent_class;
+
+    /* class members */
+};
+
+gchar *osinfoGetId(OsinfoEntity *self, GError **err);
+GPtrArray *osinfoGetParams(OsinfoEntity *self, GError **err);
+gchar *osinfoGetParamValue(OsinfoEntity *self, gchar *key, GError **err);
+GPtrArray *osinfoGetParamAllValues(OsinfoEntity *self, gchar *key, GError **err);
+
+#endif /* __OSINFO_ENTITY_H__ */
diff --git a/osinfo/osinfo_filter.c b/osinfo/osinfo_filter.c
new file mode 100644
index 0000000..c8dae31
--- /dev/null
+++ b/osinfo/osinfo_filter.c
@@ -0,0 +1,298 @@
+#include <osinfo/osinfo.h>
+
+G_DEFINE_TYPE (OsinfoFilter, osinfo_filter, G_TYPE_OBJECT);
+
+#define OSINFO_FILTER_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), OSINFO_TYPE_FILTER, OsinfoFilterPrivate))
+
+static void osinfo_filter_finalize (GObject *object);
+
+static void
+osinfo_filter_finalize (GObject *object)
+{
+    OsinfoFilter *self = OSINFO_FILTER (object);
+
+    g_tree_destroy(self->priv->propertyConstraints);
+    g_tree_destroy(self->priv->relationshipConstraints);
+
+    /* Chain up to the parent class */
+    G_OBJECT_CLASS (osinfo_filter_parent_class)->finalize (object);
+}
+
+/* Init functions */
+static void
+osinfo_filter_class_init (OsinfoFilterClass *klass)
+{
+    GObjectClass *g_klass = G_OBJECT_CLASS (klass);
+
+    g_klass->finalize = osinfo_filter_finalize;
+    g_type_class_add_private (klass, sizeof (OsinfoFilterPrivate));
+}
+
+static void
+osinfo_filter_init (OsinfoFilter *self)
+{
+    OsinfoFilterPrivate *priv;
+    priv = OSINFO_FILTER_GET_PRIVATE(self);
+    self->priv = priv;
+
+    self->priv->propertyConstraints = g_tree_new_full(__osinfoStringCompare,
+                                                     NULL,
+                                                     g_free,
+                                                     __osinfoFreePtrArray);
+
+
+    self->priv->relationshipConstraints = g_tree_new_full(__osinfoIntCompare,
+                                                         NULL,
+                                                         NULL,
+                                                         __osinfoFreePtrArray);
+}
+
+void osinfoFreeFilter(OsinfoFilter *self)
+{
+    g_object_unref(self);
+}
+
+gint osinfoAddFilterConstraint(OsinfoFilter *self, gchar *propName, gchar *propVal, GError **err)
+{
+    if (!__osinfoCheckGErrorParamValid(err))
+        return -EINVAL;
+
+    if (!OSINFO_IS_FILTER(self)) {
+        g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -EINVAL, OSINFO_OBJ_NOT_FILTER);
+        return -EINVAL;
+    }
+
+    if (!propName) {
+        g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -EINVAL, OSINFO_NO_PROPNAME);
+        return -EINVAL;
+    }
+
+    if (!propVal) {
+        g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -EINVAL, OSINFO_NO_PROPVAL);
+        return -EINVAL;
+    }
+
+    // First check if there exists an array of entries for this key
+    // If not, create a ptrarray of strings for this key and insert into map
+    gboolean found;
+    gpointer origKey, foundValue;
+    GPtrArray *valueArray;
+    gchar *valueDup = NULL, *keyDup = NULL;
+
+    valueDup = g_strdup(propVal);
+
+    if (!valueDup)
+        goto error_free;
+
+    found = g_tree_lookup_extended(self->priv->propertyConstraints, propName, &origKey, &foundValue);
+    if (!found) {
+        keyDup = g_strdup(propName);
+        valueArray = g_ptr_array_new_with_free_func(g_free);
+
+        if (!valueArray)
+            goto error_free;
+        if (!keyDup) {
+            g_ptr_array_free(valueArray, TRUE);
+            goto error_free;
+        }
+
+        g_tree_insert(self->priv->propertyConstraints, keyDup, valueArray);
+    }
+    else
+        valueArray = (GPtrArray *) foundValue;
+
+    // Add a copy of the value to the array
+    g_ptr_array_add(valueArray, valueDup);
+    return 0;
+
+error_free:
+    g_free(keyDup);
+    g_free(valueDup);
+    g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -ENOMEM, OSINFO_NO_MEM);
+    return -ENOMEM;
+}
+
+// Only applicable to OSes, ignored by other types of objects
+gint osinfoAddRelationConstraint(OsinfoFilter *self, osinfoRelationship relshp, OsinfoOs *os, GError **err)
+{
+    if (!__osinfoCheckGErrorParamValid(err))
+        return -EINVAL;
+
+    if (!OSINFO_IS_FILTER(self)) {
+        g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -EINVAL, OSINFO_OBJ_NOT_FILTER);
+        return -EINVAL;
+    }
+
+    if (!__osinfoCheckRelationshipValid(relshp)) {
+        g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -EINVAL, OSINFO_INVALID_RELATIONSHIP);
+        return -EINVAL;
+    }
+
+    if (!OSINFO_IS_OS(os)) {
+        g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -EINVAL, OSINFO_OBJ_NOT_OS);
+        return -EINVAL;
+    }
+
+    // First check if there exists an array of entries for this key
+    // If not, create a ptrarray of strings for this key and insert into map
+    gboolean found;
+    gpointer origKey, foundValue;
+    GPtrArray *valueArray;
+
+    found = g_tree_lookup_extended(self->priv->relationshipConstraints, (gpointer) relshp, &origKey, &foundValue);
+    if (!found) {
+        valueArray = g_ptr_array_new();
+        if (!valueArray)
+            goto error_nomem;
+
+        g_tree_insert(self->priv->relationshipConstraints, (gpointer) relshp, valueArray);
+    }
+    else
+        valueArray = (GPtrArray *) foundValue;
+
+    // Add to the array
+    g_ptr_array_add(valueArray, os);
+    return 0;
+
+error_nomem:
+    g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -ENOMEM, OSINFO_NO_MEM);
+    return -ENOMEM;
+}
+
+void osinfoClearFilterConstraint(OsinfoFilter *self, gchar *propName)
+{
+    g_tree_remove(self->priv->propertyConstraints, propName);
+}
+
+void osinfoClearRelationshipConstraint(OsinfoFilter *self, osinfoRelationship relshp)
+{
+    g_tree_remove(self->priv->relationshipConstraints, (gpointer) relshp);
+}
+
+static gboolean __osinfoRemoveTreeEntry(gpointer key, gpointer value, gpointer data)
+{
+    GTree *tree = (GTree *) data;
+    g_tree_remove(tree, key);
+    return FALSE; // continue iterating
+}
+
+void osinfoClearAllFilterConstraints(OsinfoFilter *self)
+{
+    g_tree_foreach(self->priv->propertyConstraints, __osinfoRemoveTreeEntry, self->priv->propertyConstraints);
+    g_tree_foreach(self->priv->relationshipConstraints, __osinfoRemoveTreeEntry, self->priv->relationshipConstraints);
+}
+
+// get keyset for constraints map
+GPtrArray *osinfoGetFilterConstraintKeys(OsinfoFilter *self, GError **err)
+{
+    if (!__osinfoCheckGErrorParamValid(err))
+        return NULL;
+
+    if (!OSINFO_IS_FILTER(self)) {
+        g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -EINVAL, OSINFO_OBJ_NOT_FILTER);
+        return NULL;
+    }
+
+    GPtrArray *constraints = g_ptr_array_new();
+    if (!constraints) {
+        g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -ENOMEM, OSINFO_NO_MEM);
+        return NULL;
+    }
+
+    struct __osinfoPtrArrayErr arrayErr = {constraints, 0};
+    g_tree_foreach(self->priv->propertyConstraints, __osinfoGetKeys, &arrayErr);
+
+    // If we had an error, cleanup and return NULL
+    if (arrayErr.err != 0) {
+        int i;
+        for (i = 0; i < constraints->len; i++)
+            g_free(g_ptr_array_index(constraints, i));
+        g_ptr_array_free(constraints, TRUE);
+        g_set_error_literal(err, g_quark_from_static_string("libosinfo"), arrayErr.err, __osinfoErrorToString(arrayErr.err));
+        return NULL;
+    }
+
+    return constraints;
+}
+
+// get values for given key
+GPtrArray *osinfoGetFilterConstraintValues(OsinfoFilter *self, gchar *propName, GError **err)
+{
+    if (!__osinfoCheckGErrorParamValid(err))
+        return NULL;
+
+    if (!OSINFO_IS_FILTER(self)) {
+        g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -EINVAL, OSINFO_OBJ_NOT_FILTER);
+        return NULL;
+    }
+
+    if (!propName) {
+        g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -EINVAL, OSINFO_NO_PROPNAME);
+        return NULL;
+    }
+
+    gboolean found;
+    gpointer origKey, value;
+    GPtrArray *srcArray, *retArray;
+
+    retArray = g_ptr_array_new();
+    if (!retArray) {
+        g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -ENOMEM, OSINFO_NO_MEM);
+        return NULL;
+    }
+
+    found = g_tree_lookup_extended(self->priv->propertyConstraints, propName, &origKey, &value);
+    if (!found)
+        return retArray;
+    srcArray = (GPtrArray *) value;
+    if (srcArray->len == 0)
+        return retArray;
+
+    struct __osinfoPtrArrayErr arrayErr = {retArray, 0};
+    g_ptr_array_foreach(srcArray, __osinfoDupArray, &arrayErr);
+    if (arrayErr.err) {
+        g_set_error_literal(err, g_quark_from_static_string("libosinfo"), arrayErr.err, __osinfoErrorToString(arrayErr.err));
+        g_ptr_array_set_free_func(retArray, g_free);
+        g_ptr_array_free(retArray, TRUE);
+        return NULL;
+    }
+
+    return retArray;
+}
+
+// get oses for given relshp
+OsinfoOsList *osinfoGetRelationshipConstraintValue(OsinfoFilter *self, osinfoRelationship relshp, GError **err)
+{
+    if (!__osinfoCheckGErrorParamValid(err))
+        return NULL;
+
+    if (!OSINFO_IS_FILTER(self)) {
+        g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -EINVAL, OSINFO_OBJ_NOT_FILTER);
+        return NULL;
+    }
+
+    if (!__osinfoCheckRelationshipValid(relshp)) {
+        g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -EINVAL, OSINFO_INVALID_RELATIONSHIP);
+        return NULL;
+    }
+
+    // Create our list
+    OsinfoOsList *newList = g_object_new(OSINFO_TYPE_OSLIST, NULL);
+    if (!newList) {
+        g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -ENOMEM, OSINFO_NO_MEM);
+        return NULL;
+    }
+
+    GPtrArray *relatedOses = NULL;
+    relatedOses = g_tree_lookup(self->priv->relationshipConstraints, (gpointer) relshp);
+    if (relatedOses) {
+        int i, len;
+        len = relatedOses->len;
+        for (i = 0; i < len; i++) {
+             OsinfoOs *os = g_ptr_array_index(relatedOses, i);
+            __osinfoListAdd(OSINFO_LIST (newList), OSINFO_ENTITY (os));
+        }
+    }
+
+    return newList;
+}
diff --git a/osinfo/osinfo_filter.h b/osinfo/osinfo_filter.h
new file mode 100644
index 0000000..9a60fcd
--- /dev/null
+++ b/osinfo/osinfo_filter.h
@@ -0,0 +1,64 @@
+/*
+ * libosinfo
+ *
+ * osinfo_filter.h
+ * Represents a filter in libosinfo.
+ */
+
+#ifndef __OSINFO_FILTER_H__
+#define __OSINFO_FILTER_H__
+
+/*
+ * Type macros.
+ */
+#define OSINFO_TYPE_FILTER                  (osinfo_filter_get_type ())
+#define OSINFO_FILTER(obj)                  (G_TYPE_CHECK_INSTANCE_CAST ((obj), OSINFO_TYPE_FILTER, OsinfoFilter))
+#define OSINFO_IS_FILTER(obj)               (G_TYPE_CHECK_INSTANCE_TYPE ((obj), OSINFO_TYPE_FILTER))
+#define OSINFO_FILTER_CLASS(klass)          (G_TYPE_CHECK_CLASS_CAST ((klass), OSINFO_TYPE_FILTER, OsinfoFilterClass))
+#define OSINFO_IS_FILTER_CLASS(klass)       (G_TYPE_CHECK_CLASS_TYPE ((klass), OSINFO_TYPE_FILTER))
+#define OSINFO_FILTER_GET_CLASS(obj)        (G_TYPE_INSTANCE_GET_CLASS ((obj), OSINFO_TYPE_FILTER, OsinfoFilterClass))
+
+//typedef struct _OsinfoFilter        OsinfoFilter;
+// (defined in osinfo_objects.h)
+
+#include "osinfo_oslist.h"
+
+typedef struct _OsinfoFilterClass  OsinfoFilterClass;
+
+typedef struct _OsinfoFilterPrivate OsinfoFilterPrivate;
+
+/* object */
+struct _OsinfoFilter
+{
+    OsinfoEntity parent_instance;
+
+    /* public */
+
+    /* private */
+    OsinfoFilterPrivate *priv;
+};
+
+/* class */
+struct _OsinfoFilterClass
+{
+    OsinfoEntityClass parent_class;
+
+    /* class members */
+};
+
+void osinfoFreeFilter(OsinfoFilter *self);
+
+gint osinfoAddFilterContstraint(OsinfoFilter *self, gchar *propName, gchar *propVal, GError **err);
+
+// Only applicable to OSes, ignored by other types of objects
+gint osinfoAddRelationConstraint(OsinfoFilter *self, osinfoRelationship relshp, OsinfoOs *os, GError **err);
+
+void osinfoClearFilterConstraint(OsinfoFilter *self, gchar *propName);
+void osinfoClearRelationshipConstraint(OsinfoFilter *self, osinfoRelationship relshp);
+void osinfoClearAllFilterConstraints(OsinfoFilter *self);
+
+GPtrArray *osinfoGetFilterConstraintKeys(OsinfoFilter *self, GError **err);
+gchar *osinfoGetFilterConstraintValue(OsinfoFilter *self, GError **err);
+OsinfoOsList *osinfoGetRelationshipConstraintValue(OsinfoFilter *self, osinfoRelationship relshp, GError **err);
+
+#endif /* __OSINFO_FILTER_H__ */
diff --git a/osinfo/osinfo_hypervisor.c b/osinfo/osinfo_hypervisor.c
new file mode 100644
index 0000000..712766f
--- /dev/null
+++ b/osinfo/osinfo_hypervisor.c
@@ -0,0 +1,122 @@
+#include <osinfo/osinfo.h>
+
+G_DEFINE_TYPE (OsinfoHypervisor, osinfo_hypervisor, OSINFO_TYPE_ENTITY);
+
+#define OSINFO_HYPERVISOR_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), OSINFO_TYPE_HYPERVISOR, OsinfoHypervisorPrivate))
+
+static void osinfo_hypervisor_finalize (GObject *object);
+
+static void
+osinfo_hypervisor_finalize (GObject *object)
+{
+    OsinfoHypervisor *self = OSINFO_HYPERVISOR (object);
+
+    g_tree_destroy (self->priv->sections);
+    g_tree_destroy (self->priv->sectionsAsList);
+
+    /* Chain up to the parent class */
+    G_OBJECT_CLASS (osinfo_hypervisor_parent_class)->finalize (object);
+}
+
+/* Init functions */
+static void
+osinfo_hypervisor_class_init (OsinfoHypervisorClass *klass)
+{
+    GObjectClass *g_klass = G_OBJECT_CLASS (klass);
+
+    g_klass->finalize = osinfo_hypervisor_finalize;
+    g_type_class_add_private (klass, sizeof (OsinfoHypervisorPrivate));
+}
+
+static void
+osinfo_hypervisor_init (OsinfoHypervisor *self)
+{
+    OsinfoHypervisorPrivate *priv;
+    self->priv = priv = OSINFO_HYPERVISOR_GET_PRIVATE(self);
+
+    self->priv->sections = g_tree_new_full(__osinfoStringCompare, NULL, g_free, __osinfoFreeDeviceSection);
+    self->priv->sectionsAsList = g_tree_new_full(__osinfoStringCompare, NULL, g_free, __osinfoFreePtrArray);
+}
+
+int __osinfoAddDeviceToSectionHv(OsinfoHypervisor *self, gchar *section, gchar *id, gchar *driver)
+{
+    if( !OSINFO_IS_HYPERVISOR(self) || !section || !id || !driver)
+        return -EINVAL;
+
+    return __osinfoAddDeviceToSection(self->priv->sections, self->priv->sectionsAsList, section, id, driver);
+}
+
+void __osinfoClearDeviceSectionHv(OsinfoHypervisor *self, gchar *section)
+{
+    if (!OSINFO_IS_HYPERVISOR(self) || !section)
+        return;
+
+    __osinfoClearDeviceSection(self->priv->sections, self->priv->sectionsAsList, section);
+}
+
+GPtrArray *osinfoGetHypervisorDeviceTypes(OsinfoHypervisor *self, GError **err)
+{
+    if (!__osinfoCheckGErrorParamValid(err))
+        return NULL;
+
+    if (!OSINFO_IS_HYPERVISOR(self)) {
+        g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -EINVAL, OSINFO_OBJ_NOT_HV);
+        return NULL;
+    }
+
+    GPtrArray *deviceTypes = g_ptr_array_sized_new(g_tree_nnodes(self->priv->sections));
+    if (!deviceTypes) {
+        g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -ENOMEM, OSINFO_NO_MEM);
+        return NULL;
+    }
+
+    // For each key in our tree of device sections, dup and add to the array
+    struct __osinfoPtrArrayErr arrayErr = {deviceTypes, 0};
+    g_tree_foreach(self->priv->sections, __osinfoGetKeys, &arrayErr);
+    return deviceTypes;
+}
+
+OsinfoDeviceList *osinfoGetHypervisorDevicesByType(OsinfoHypervisor *self, gchar *devType, OsinfoFilter *filter, GError **err)
+{
+    if (!__osinfoCheckGErrorParamValid(err))
+        return NULL;
+
+    if (!OSINFO_IS_HYPERVISOR(self)) {
+        g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -EINVAL, OSINFO_OBJ_NOT_HV);
+        return NULL;
+    }
+
+    if (filter && !OSINFO_IS_FILTER(filter)) {
+        g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -EINVAL, OSINFO_OBJ_NOT_FILTER);
+        return NULL;
+    }
+
+    if (!devType) {
+        g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -EINVAL, OSINFO_NO_DEVTYPE);
+        return NULL;
+    }
+
+    // Create our device list
+    OsinfoDeviceList *newList = g_object_new(OSINFO_TYPE_DEVICELIST, NULL);
+    if (!newList) {
+        g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -ENOMEM, OSINFO_NO_MEM);
+        return NULL;
+    }
+
+    // If section does not exist, return empty list
+    GPtrArray *sectionList = NULL;
+    sectionList = g_tree_lookup(self->priv->sectionsAsList, devType);
+    if (!sectionList)
+        return newList;
+
+    // For each device in section list, apply filter. If filter passes, add device to list.
+    int i;
+    struct __osinfoDeviceLink *deviceLink;
+    for (i = 0; i < sectionList->len; i++) {
+        deviceLink = g_ptr_array_index(sectionList, i);
+        if (__osinfoDevicePassesFilter(filter, deviceLink->dev))
+            __osinfoListAdd(OSINFO_LIST (newList), OSINFO_ENTITY (deviceLink->dev));
+    }
+
+    return newList;
+}
diff --git a/osinfo/osinfo_hypervisor.h b/osinfo/osinfo_hypervisor.h
new file mode 100644
index 0000000..65c78dc
--- /dev/null
+++ b/osinfo/osinfo_hypervisor.h
@@ -0,0 +1,52 @@
+/*
+ * libosinfo
+ *
+ * osinfo_hypervisor.h
+ * Represents a hypervisor in libosinfo.
+ */
+
+#ifndef __OSINFO_HYPERVISOR_H__
+#define __OSINFO_HYPERVISOR_H__
+
+#include "osinfo_devicelist.h"
+
+/*
+ * Type macros.
+ */
+#define OSINFO_TYPE_HYPERVISOR                  (osinfo_hypervisor_get_type ())
+#define OSINFO_HYPERVISOR(obj)                  (G_TYPE_CHECK_INSTANCE_CAST ((obj), OSINFO_TYPE_HYPERVISOR, OsinfoHypervisor))
+#define OSINFO_IS_HYPERVISOR(obj)               (G_TYPE_CHECK_INSTANCE_TYPE ((obj), OSINFO_TYPE_HYPERVISOR))
+#define OSINFO_HYPERVISOR_CLASS(klass)          (G_TYPE_CHECK_CLASS_CAST ((klass), OSINFO_TYPE_HYPERVISOR, OsinfoHypervisorClass))
+#define OSINFO_IS_HYPERVISOR_CLASS(klass)       (G_TYPE_CHECK_CLASS_TYPE ((klass), OSINFO_TYPE_HYPERVISOR))
+#define OSINFO_HYPERVISOR_GET_CLASS(obj)        (G_TYPE_INSTANCE_GET_CLASS ((obj), OSINFO_TYPE_HYPERVISOR, OsinfoHypervisorClass))
+
+//typedef struct _OsinfoHypervisor        OsinfoHypervisor;
+// (defined in osinfo_objects.h)
+
+typedef struct _OsinfoHypervisorClass   OsinfoHypervisorClass;
+
+typedef struct _OsinfoHypervisorPrivate OsinfoHypervisorPrivate;
+
+/* object */
+struct _OsinfoHypervisor
+{
+    OsinfoEntity parent_instance;
+
+    /* public */
+
+    /* private */
+    OsinfoHypervisorPrivate *priv;
+};
+
+/* class */
+struct _OsinfoHypervisorClass
+{
+    OsinfoEntityClass parent_class;
+
+    /* class members */
+};
+
+GPtrArray *osinfoGetHypervisorDeviceTypes(OsinfoHypervisor *self, GError **err);
+OsinfoDeviceList *osinfoGetHypervisorDevicesByType(OsinfoHypervisor *self, gchar *devType, OsinfoFilter *filter, GError **err);
+
+#endif /* __OSINFO_HYPERVISOR_H__ */
diff --git a/osinfo/osinfo_hypervisorlist.c b/osinfo/osinfo_hypervisorlist.c
new file mode 100644
index 0000000..147f4b4
--- /dev/null
+++ b/osinfo/osinfo_hypervisorlist.c
@@ -0,0 +1,121 @@
+#include <osinfo/osinfo.h>
+
+G_DEFINE_TYPE (OsinfoHypervisorList, osinfo_hypervisorlist, OSINFO_TYPE_LIST);
+
+#define OSINFO_HYPERVISORLIST_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), OSINFO_TYPE_HYPERVISORLIST, OsinfoHypervisorListPrivate))
+
+static void osinfo_hypervisorlist_finalize (GObject *object);
+
+struct _OsinfoHypervisorListPrivate
+{
+    int tmp;
+};
+
+static void
+osinfo_hypervisorlist_finalize (GObject *object)
+{
+    /* Chain up to the parent class */
+    G_OBJECT_CLASS (osinfo_hypervisorlist_parent_class)->finalize (object);
+}
+
+/* Init functions */
+static void
+osinfo_hypervisorlist_class_init (OsinfoHypervisorListClass *klass)
+{
+    GObjectClass *g_klass = G_OBJECT_CLASS (klass);
+
+    g_klass->finalize = osinfo_hypervisorlist_finalize;
+    g_type_class_add_private (klass, sizeof (OsinfoHypervisorListPrivate));
+}
+
+static void
+osinfo_hypervisorlist_init (OsinfoHypervisorList *self)
+{
+    OsinfoHypervisorListPrivate *priv;
+    self->priv = priv = OSINFO_HYPERVISORLIST_GET_PRIVATE(self);
+
+}
+
+OsinfoHypervisor *osinfoGetHypervisorAtIndex(OsinfoHypervisorList *self, gint idx, GError **err)
+{
+    if (!OSINFO_IS_HYPERVISORLIST(self)) {
+        g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -EINVAL, OSINFO_OBJ_NOT_HYPERVISORLIST);
+        return NULL;
+    }
+
+    OsinfoList *selfAsList = OSINFO_LIST (self);
+    OsinfoEntity *entity = osinfoGetEntityAtIndex(selfAsList, idx);
+    return OSINFO_HYPERVISOR (entity);
+}
+
+OsinfoHypervisorList *osinfoHypervisorListFilter(OsinfoHypervisorList *self, OsinfoFilter *filter, GError **err)
+{
+    if (!OSINFO_IS_HYPERVISORLIST(self)) {
+        g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -EINVAL, OSINFO_OBJ_NOT_HYPERVISORLIST);
+        return NULL;
+    }
+
+    if (filter && !OSINFO_IS_FILTER(self)) {
+        g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -EINVAL, OSINFO_OBJ_NOT_FILTER);
+        return NULL;
+    }
+
+    // For each element in self, if passes filter, add to new list.
+    OsinfoHypervisorList *newList = g_object_new(OSINFO_TYPE_HYPERVISORLIST, NULL);
+    if (!newList) {
+        g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -ENOMEM, OSINFO_NO_MEM);
+        return NULL;
+    }
+
+    __osinfoDoFilter(OSINFO_LIST (self), OSINFO_LIST (newList), filter);
+    return newList;
+}
+
+OsinfoHypervisorList *osinfoHypervisorListIntersect(OsinfoHypervisorList *self, OsinfoHypervisorList *otherList, GError **err)
+{
+    if (!OSINFO_IS_HYPERVISORLIST(self) || !OSINFO_IS_HYPERVISORLIST(otherList)) {
+        g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -EINVAL, OSINFO_OBJ_NOT_HYPERVISORLIST);
+        return NULL;
+    }
+
+    OsinfoHypervisorList *newList = g_object_new(OSINFO_TYPE_HYPERVISORLIST, NULL);
+    if (!newList) {
+        g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -ENOMEM, OSINFO_NO_MEM);
+        return NULL;
+    }
+
+    int ret;
+
+    ret = __osinfoDoIntersect(self, otherList, newList);
+    if (ret != 0) {
+        g_object_unref(newList);
+        g_set_error_literal(err, g_quark_from_static_string("libosinfo"), ret, __osinfoErrorToString(ret));
+        return NULL;
+    }
+
+    return newList;
+}
+
+OsinfoHypervisorList *osinfoHypervisorListUnion(OsinfoHypervisorList *self, OsinfoHypervisorList *otherList, GError **err)
+{
+    if (!OSINFO_IS_HYPERVISORLIST(self) || !OSINFO_IS_HYPERVISORLIST(otherList)) {
+        g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -EINVAL, OSINFO_OBJ_NOT_HYPERVISORLIST);
+        return NULL;
+    }
+
+    OsinfoHypervisorList *newList = g_object_new(OSINFO_TYPE_HYPERVISORLIST, NULL);
+    if (!newList) {
+        g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -ENOMEM, OSINFO_NO_MEM);
+        return NULL;
+    }
+
+    int ret;
+    ret = __osinfoDoUnion(self, otherList, newList);
+    if (ret != 0) {
+        g_object_unref(newList);
+        g_set_error_literal(err, g_quark_from_static_string("libosinfo"), ret, __osinfoErrorToString(ret));
+        return NULL;
+    }
+
+    return newList;
+}
diff --git a/osinfo/osinfo_hypervisorlist.h b/osinfo/osinfo_hypervisorlist.h
new file mode 100644
index 0000000..bdc7f03
--- /dev/null
+++ b/osinfo/osinfo_hypervisorlist.h
@@ -0,0 +1,50 @@
+/*
+ * libosinfo
+ *
+ * osinfo_hypervisorlist.h
+ */
+
+#ifndef __OSINFO_HYPERVISORLIST_H__
+#define __OSINFO_HYPERVISORLIST_H__
+
+/*
+ * Type macros.
+ */
+#define OSINFO_TYPE_HYPERVISORLIST                  (osinfo_hypervisorlist_get_type ())
+#define OSINFO_HYPERVISORLIST(obj)                  (G_TYPE_CHECK_INSTANCE_CAST ((obj), OSINFO_TYPE_HYPERVISORLIST, OsinfoHypervisorList))
+#define OSINFO_IS_HYPERVISORLIST(obj)               (G_TYPE_CHECK_INSTANCE_TYPE ((obj), OSINFO_TYPE_HYPERVISORLIST))
+#define OSINFO_HYPERVISORLIST_CLASS(klass)          (G_TYPE_CHECK_CLASS_CAST ((klass), OSINFO_TYPE_HYPERVISORLIST, OsinfoHypervisorListClass))
+#define OSINFO_IS_HYPERVISORLIST_CLASS(klass)       (G_TYPE_CHECK_CLASS_TYPE ((klass), OSINFO_TYPE_HYPERVISORLIST))
+#define OSINFO_HYPERVISORLIST_GET_CLASS(obj)        (G_TYPE_INSTANCE_GET_CLASS ((obj), OSINFO_TYPE_HYPERVISORLIST, OsinfoHypervisorListClass))
+
+typedef struct _OsinfoHypervisorList        OsinfoHypervisorList;
+
+typedef struct _OsinfoHypervisorListClass   OsinfoHypervisorListClass;
+
+typedef struct _OsinfoHypervisorListPrivate OsinfoHypervisorListPrivate;
+
+/* object */
+struct _OsinfoHypervisorList
+{
+    GObject parent_instance;
+
+    /* public */
+
+    /* private */
+    OsinfoHypervisorListPrivate *priv;
+};
+
+/* class */
+struct _OsinfoHypervisorListClass
+{
+    GObjectClass parent_class;
+
+    /* class members */
+};
+
+OsinfoHypervisorList *osinfoHypervisorListFilter(OsinfoHypervisorList *self, OsinfoFilter *filter, GError **err);
+OsinfoHypervisor *osinfoGetHypervisorAtIndex(OsinfoHypervisorList *self, gint idx, GError **err);
+OsinfoHypervisorList *osinfoHypervisorListIntersect(OsinfoHypervisorList *self, OsinfoHypervisorList *otherHypervisorList, GError **err);
+OsinfoHypervisorList *osinfoHypervisorListUnion(OsinfoHypervisorList *self, OsinfoHypervisorList *otherHypervisorList, GError **err);
+
+#endif /* __OSINFO_HYPERVISORLIST_H__ */
diff --git a/osinfo/osinfo_list.c b/osinfo/osinfo_list.c
new file mode 100644
index 0000000..9e88993
--- /dev/null
+++ b/osinfo/osinfo_list.c
@@ -0,0 +1,219 @@
+#include <osinfo/osinfo.h>
+
+G_DEFINE_TYPE (OsinfoList, osinfo_list, G_TYPE_OBJECT);
+
+#define OSINFO_LIST_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), OSINFO_TYPE_LIST, OsinfoListPrivate))
+
+static void osinfo_list_finalize (GObject *object);
+
+struct _OsinfoListPrivate
+{
+    GPtrArray *array;
+};
+
+static void
+osinfo_list_finalize (GObject *object)
+{
+    OsinfoList *self = OSINFO_LIST (object);
+
+    g_ptr_array_free(self->priv->array, TRUE);
+
+    /* Chain up to the parent class */
+    G_OBJECT_CLASS (osinfo_list_parent_class)->finalize (object);
+}
+
+/* Init functions */
+static void
+osinfo_list_class_init (OsinfoListClass *klass)
+{
+    GObjectClass *g_klass = G_OBJECT_CLASS (klass);
+
+    g_klass->finalize = osinfo_list_finalize;
+    g_type_class_add_private (klass, sizeof (OsinfoListPrivate));
+}
+
+static void
+osinfo_list_init (OsinfoList *self)
+{
+    OsinfoListPrivate *priv;
+    self->priv = priv = OSINFO_LIST_GET_PRIVATE(self);
+
+    self->priv->array = g_ptr_array_new();
+}
+
+void osinfoFreeList(OsinfoList *self)
+{
+    g_object_unref(self);
+}
+
+gint osinfoListLength(OsinfoList *self)
+{
+    return self->priv->array->len;
+}
+
+OsinfoEntity *osinfoGetEntityAtIndex(OsinfoList *self, gint idx)
+{
+    return g_ptr_array_index(self->priv->array, idx);
+}
+
+void __osinfoListAdd(OsinfoList *self, OsinfoEntity *entity)
+{
+    g_ptr_array_add(self->priv->array, entity);
+}
+
+void __osinfoDoFilter(OsinfoList *src, OsinfoList *dst, OsinfoFilter *filter)
+{
+    int i, len;
+    len = osinfoListLength(src);
+    for (i = 0; i < len; i++) {
+        OsinfoEntity *entity = osinfoGetEntityAtIndex(src, i);
+        if (__osinfoEntityPassesFilter(filter, entity))
+            __osinfoListAdd(dst, entity);
+    }
+}
+
+OsinfoList *osinfoListFilter(OsinfoList *self, OsinfoFilter *filter, GError **err)
+{
+    if (!OSINFO_IS_LIST(self)) {
+        g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -EINVAL, OSINFO_OBJ_NOT_LIST);
+        return NULL;
+    }
+
+    if (filter && !OSINFO_IS_FILTER(filter)) {
+        g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -EINVAL, OSINFO_OBJ_NOT_FILTER);
+        return NULL;
+    }
+
+    // For each element in self, if passes filter, add to new list.
+    OsinfoList *newList = g_object_new(OSINFO_TYPE_LIST, NULL);
+    if (!newList) {
+        g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -ENOMEM, OSINFO_NO_MEM);
+        return NULL;
+    }
+
+    __osinfoDoFilter(self, newList, filter);
+    return newList;
+}
+
+int __osinfoDoIntersect(OsinfoList *src1, OsinfoList *src2, OsinfoList *dst)
+{
+    int i, len;
+
+    // Make set representation of otherList and newList
+    GTree *otherSet = g_tree_new(__osinfoStringCompareBase);
+    if (!otherSet)
+        return -ENOMEM;
+
+    GTree *newSet = g_tree_new(__osinfoStringCompareBase);
+    if (!newSet) {
+        g_tree_destroy(otherSet);
+        return -ENOMEM;
+    }
+
+    // Add all from otherList to otherSet
+    len = osinfoListLength(src2);
+    for (i = 0; i < len; i++) {
+        OsinfoEntity *entity = osinfoGetEntityAtIndex(src2, i);
+        gchar *id = entity->priv->id;
+        g_tree_insert(otherSet, id, entity);
+    }
+
+    // If other contains entity, and new list does not, add to new list
+    len = osinfoListLength(src1);
+    for (i = 0; i < len; i++) {
+        OsinfoEntity *entity = osinfoGetEntityAtIndex(src1, i);
+        gchar *id = entity->priv->id;
+
+        if (g_tree_lookup(otherSet, entity->priv->id) &&
+            !g_tree_lookup(newSet, entity->priv->id)) {
+            g_tree_insert(newSet, id, entity);
+            __osinfoListAdd(dst, entity);
+        }
+    }
+
+    g_tree_destroy(otherSet);
+    g_tree_destroy(newSet);
+    return 0;
+}
+
+OsinfoList *osinfoListIntersect(OsinfoList *self, OsinfoList *otherList, GError **err)
+{
+    if (!OSINFO_IS_LIST(self) || !OSINFO_IS_LIST(otherList)) {
+        g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -EINVAL, OSINFO_OBJ_NOT_LIST);
+        return NULL;
+    }
+
+    OsinfoList *newList = g_object_new(OSINFO_TYPE_LIST, NULL);
+    if (!newList) {
+        g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -ENOMEM, OSINFO_NO_MEM);
+        return NULL;
+    }
+
+    int ret;
+
+    ret = __osinfoDoIntersect(self, otherList, newList);
+    if (ret != 0) {
+        g_object_unref(newList);
+        g_set_error_literal(err, g_quark_from_static_string("libosinfo"), ret, __osinfoErrorToString(ret));
+        return NULL;
+    }
+
+    return newList;
+}
+
+int __osinfoDoUnion(OsinfoList *src1, OsinfoList *src2, OsinfoList *dst)
+{
+    // Make set version of new list
+    GTree *newSet = g_tree_new(__osinfoStringCompareBase);
+    if (!newSet)
+        return -ENOMEM;
+
+    // Add all from other list to new list
+    int i, len;
+    len = osinfoListLength(src2);
+    for (i = 0; i < len; i++) {
+        OsinfoEntity *entity = osinfoGetEntityAtIndex(src2, i);
+        gchar *id = entity->priv->id;
+        __osinfoListAdd(dst, entity);
+        g_tree_insert(newSet, id, entity);
+    }
+
+    // Add remaining elements from this list to new list
+    len = osinfoListLength(src1);
+    for (i = 0; i < len; i++) {
+        OsinfoEntity *entity = osinfoGetEntityAtIndex(src1, i);
+        gchar *id = entity->priv->id;
+        // If new list does not contain element, add to new list
+        if (!g_tree_lookup(newSet, id)) {
+            __osinfoListAdd(dst, entity);
+            g_tree_insert(newSet, id, entity);
+        }
+    }
+
+    g_tree_destroy(newSet);
+    return 0;
+}
+
+OsinfoList *osinfoListUnion(OsinfoList *self, OsinfoList *otherList, GError **err)
+{
+    if (!OSINFO_IS_LIST(self) || !OSINFO_IS_LIST(otherList)) {
+        g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -EINVAL, OSINFO_OBJ_NOT_LIST);
+        return NULL;
+    }
+
+    OsinfoList *newList = g_object_new(OSINFO_TYPE_LIST, NULL);
+    if (!newList) {
+        g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -ENOMEM, OSINFO_NO_MEM);
+        return NULL;
+    }
+
+    int ret;
+    ret = __osinfoDoUnion(self, otherList, newList);
+    if (ret != 0) {
+        g_object_unref(newList);
+        g_set_error_literal(err, g_quark_from_static_string("libosinfo"), ret, __osinfoErrorToString(ret));
+        return NULL;
+    }
+
+    return newList;
+}
diff --git a/osinfo/osinfo_list.h b/osinfo/osinfo_list.h
new file mode 100644
index 0000000..81a2bc7
--- /dev/null
+++ b/osinfo/osinfo_list.h
@@ -0,0 +1,51 @@
+/*
+ * libosinfo
+ *
+ * osinfo_list.h
+ */
+
+#ifndef __OSINFO_LIST_H__
+#define __OSINFO_LIST_H__
+
+/*
+ * Type macros.
+ */
+#define OSINFO_TYPE_LIST                  (osinfo_list_get_type ())
+#define OSINFO_LIST(obj)                  (G_TYPE_CHECK_INSTANCE_CAST ((obj), OSINFO_TYPE_LIST, OsinfoList))
+#define OSINFO_IS_LIST(obj)               (G_TYPE_CHECK_INSTANCE_TYPE ((obj), OSINFO_TYPE_LIST))
+#define OSINFO_LIST_CLASS(klass)          (G_TYPE_CHECK_CLASS_CAST ((klass), OSINFO_TYPE_LIST, OsinfoListClass))
+#define OSINFO_IS_LIST_CLASS(klass)       (G_TYPE_CHECK_CLASS_TYPE ((klass), OSINFO_TYPE_LIST))
+#define OSINFO_LIST_GET_CLASS(obj)        (G_TYPE_INSTANCE_GET_CLASS ((obj), OSINFO_TYPE_LIST, OsinfoListClass))
+
+typedef struct _OsinfoListClass   OsinfoListClass;
+
+typedef struct _OsinfoListPrivate OsinfoListPrivate;
+
+/* object */
+struct _OsinfoList
+{
+    GObject parent_instance;
+
+    /* public */
+
+    /* private */
+    OsinfoListPrivate *priv;
+};
+
+/* class */
+struct _OsinfoListClass
+{
+    GObjectClass parent_class;
+
+    /* class members */
+};
+
+void osinfoFreeList(OsinfoList *self);
+gint osinfoListLength(OsinfoList *self);
+
+OsinfoList *osinfoListFilter(OsinfoList *self, OsinfoFilter *filter, GError **err);
+OsinfoEntity *osinfoGetEntityAtIndex(OsinfoList *self, gint idx);
+OsinfoList *osinfoListIntersect(OsinfoList *self, OsinfoList *otherList, GError **err);
+OsinfoList *osinfoListUnion(OsinfoList *self, OsinfoList *otherList, GError **err);
+
+#endif /* __OSINFO_LIST_H__ */
diff --git a/osinfo/osinfo_os.c b/osinfo/osinfo_os.c
new file mode 100644
index 0000000..a3ba4fe
--- /dev/null
+++ b/osinfo/osinfo_os.c
@@ -0,0 +1,402 @@
+#include <osinfo/osinfo.h>
+
+G_DEFINE_TYPE (OsinfoOs, osinfo_os, OSINFO_TYPE_ENTITY);
+
+#define OSINFO_OS_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), OSINFO_TYPE_OS, OsinfoOsPrivate))
+
+static void osinfo_os_finalize (GObject *object);
+
+static void
+osinfo_os_finalize (GObject *object)
+{
+    OsinfoOs *self = OSINFO_OS (object);
+
+    g_tree_destroy (self->priv->sections);
+    g_tree_destroy (self->priv->sectionsAsList);
+    g_tree_destroy (self->priv->hypervisors);
+    g_tree_destroy (self->priv->relationshipsByOs);
+    g_tree_destroy (self->priv->relationshipsByType);
+
+    /* Chain up to the parent class */
+    G_OBJECT_CLASS (osinfo_os_parent_class)->finalize (object);
+}
+
+/* Init functions */
+static void
+osinfo_os_class_init (OsinfoOsClass *klass)
+{
+    GObjectClass *g_klass = G_OBJECT_CLASS (klass);
+
+    g_klass->finalize = osinfo_os_finalize;
+    g_type_class_add_private (klass, sizeof (OsinfoOsPrivate));
+}
+
+static void
+osinfo_os_init (OsinfoOs *self)
+{
+    OsinfoOsPrivate *priv;
+    self->priv = priv = OSINFO_OS_GET_PRIVATE(self);
+
+    self->priv->sections = g_tree_new_full(__osinfoStringCompare,
+                                           NULL,
+                                           g_free,
+                                           __osinfoFreeDeviceSection);
+
+    self->priv->sectionsAsList = g_tree_new_full(__osinfoStringCompare,
+                                                 NULL,
+                                                 g_free,
+                                                 __osinfoFreePtrArray);
+
+    self->priv->relationshipsByOs = g_tree_new_full(__osinfoStringCompare,
+                                                NULL,
+                                                g_free,
+                                                __osinfoFreeRelationship);
+    self->priv->relationshipsByType = g_tree_new(__osinfoIntCompareBase);
+
+    self->priv->hypervisors = g_tree_new_full(__osinfoStringCompare,
+                                              NULL,
+                                              g_free,
+                                              __osinfoFreeHvSection);
+}
+
+static int __osinfoAddOsRelationshipByOs(OsinfoOs *self,
+                                         gchar *otherOsId,
+                                         osinfoRelationship rel,
+                                         struct __osinfoOsLink *osLink)
+{
+    gboolean found;
+    gpointer origKey, foundValue;
+    GPtrArray *relationshipsForOs;
+    gchar *otherOsIdDup = NULL;
+
+    found = g_tree_lookup_extended(self->priv->relationshipsByOs, otherOsId, &origKey, &foundValue);
+    if (!found) {
+        otherOsIdDup = g_strdup(otherOsId);
+        relationshipsForOs = g_ptr_array_new_with_free_func(__osinfoFreeOsLink);
+
+        if (!relationshipsForOs)
+            return -ENOMEM;
+        if (!otherOsIdDup) {
+            g_ptr_array_free(relationshipsForOs, TRUE);
+            return -ENOMEM;
+        }
+        g_tree_insert(self->priv->relationshipsByOs, otherOsIdDup, relationshipsForOs);
+    }
+    else
+        relationshipsForOs = (GPtrArray *) foundValue;
+
+    g_ptr_array_add(relationshipsForOs, osLink);
+    return 0;
+}
+
+static int __osinfoAddOsRelationshipByType(OsinfoOs *self,
+                                           osinfoRelationship relshp,
+                                           struct __osinfoOsLink *osLink)
+{
+    gboolean found;
+    gpointer origKey, foundValue;
+    GPtrArray *relationshipsForType;
+
+    found = g_tree_lookup_extended(self->priv->relationshipsByType, (gpointer) relshp, &origKey, &foundValue);
+    if (!found) {
+        relationshipsForType = g_ptr_array_new();
+        if (!relationshipsForType)
+            return -ENOMEM;
+
+        g_tree_insert(self->priv->relationshipsByType, (gpointer) relshp, relationshipsForType);
+    }
+    else
+        relationshipsForType = (GPtrArray *) foundValue;
+
+    g_ptr_array_add(relationshipsForType, osLink);
+    return 0;
+}
+
+static void __osinfoRemoveOsLink(OsinfoOs *self,
+                                 gchar *otherOsId,
+                                 osinfoRelationship relshp,
+                                 struct __osinfoOsLink *osLink)
+{
+    gboolean found;
+    gpointer origKey, foundValue;
+    GPtrArray *relationshipsForOs;
+    GPtrArray *relationshipsForType;
+
+    // First from by-os list
+    found = g_tree_lookup_extended(self->priv->relationshipsByOs, otherOsId, &origKey, &foundValue);
+    if (found) {
+        relationshipsForOs = (GPtrArray *) foundValue;
+        g_ptr_array_remove(relationshipsForOs, osLink);
+    }
+
+    // Now from by-relshp list
+    found = g_tree_lookup_extended(self->priv->relationshipsByType, (gpointer) relshp, &origKey, &foundValue);
+    if (found) {
+        relationshipsForType = (GPtrArray *) foundValue;
+        g_ptr_array_remove(relationshipsForType, osLink);
+    }
+}
+
+int __osinfoAddOsRelationship (OsinfoOs *self, gchar *otherOsId, osinfoRelationship rel)
+{
+    if ( !OSINFO_IS_OS(self) || !otherOsId)
+        return -EINVAL;
+
+    struct __osinfoOsLink *osLink = NULL;
+    osLink = g_malloc(sizeof(*osLink));
+    if (!osLink)
+        return -ENOMEM;
+
+    osLink->subjectOs = self;
+    osLink->verb = rel;
+
+    int ret;
+    ret = __osinfoAddOsRelationshipByOs(self, otherOsId, rel, osLink);
+    if (ret != 0)
+        goto error_free;
+
+    ret = __osinfoAddOsRelationshipByType(self, rel, osLink);
+    if (ret != 0)
+        goto error_cleanup;
+
+    return ret;
+
+error_cleanup:
+    __osinfoRemoveOsLink(self, otherOsId, rel, osLink);
+error_free:
+    g_free(osLink);
+    return ret;
+}
+
+int __osinfoAddDeviceToSectionOs(OsinfoOs *self, gchar *section, gchar *id, gchar *driver)
+{
+    if( !OSINFO_IS_OS(self) || !section || !id || !driver)
+        return -EINVAL;
+
+    return __osinfoAddDeviceToSection(self->priv->sections, self->priv->sectionsAsList, section, id, driver);
+}
+
+void __osinfoClearDeviceSectionOs(OsinfoOs *self, gchar *section)
+{
+    if (!OSINFO_IS_OS(self) || !section)
+        return;
+
+    __osinfoClearDeviceSection(self->priv->sections, self->priv->sectionsAsList, section);
+}
+
+struct __osinfoHvSection *__osinfoAddHypervisorSectionToOs(OsinfoOs *self, gchar *hvId)
+{
+    if (!OSINFO_IS_OS(self) || !hvId)
+        return NULL;
+
+    gboolean found;
+    gpointer origKey, foundValue;
+    struct __osinfoHvSection *hvSection = NULL;
+    gchar *hvIdDup = NULL;
+    GTree *deviceSections;
+    GTree *deviceSectionsAsList;
+
+    found = g_tree_lookup_extended(self->priv->hypervisors, hvId, &origKey, &foundValue);
+    if (!found) {
+        hvSection = g_malloc(sizeof(*hvSection));
+        hvIdDup = g_strdup(hvId);
+        deviceSections = g_tree_new_full(__osinfoStringCompare,
+                                        NULL,
+                                        g_free,
+                                        __osinfoFreeDeviceSection);
+
+        if (!deviceSections)
+            goto error_free;
+
+        deviceSectionsAsList = g_tree_new_full(__osinfoStringCompare,
+                                               NULL,
+                                               g_free,
+                                               __osinfoFreePtrArray);
+        if (!deviceSectionsAsList) {
+            g_tree_destroy(deviceSections);
+            goto error_free;
+        }
+
+        if (!hvSection || !hvIdDup) {
+            g_tree_destroy(deviceSectionsAsList);
+            g_tree_destroy(deviceSections);
+            goto error_free;
+        }
+
+        hvSection->os = self;
+        // Will set hv link later
+        hvSection->sections = deviceSections;
+        hvSection->sectionsAsList = deviceSectionsAsList;
+
+        g_tree_insert(self->priv->hypervisors, hvIdDup, hvSection);
+        return hvSection;
+    }
+    else
+        return (struct __osinfoHvSection *) foundValue;
+
+error_free:
+    g_free(hvSection);
+    g_free(hvIdDup);
+    return NULL;
+}
+
+void __osinfoRemoveHvSectionFromOs(OsinfoOs *self, gchar *hvId)
+{
+    g_tree_remove(self->priv->hypervisors, hvId);
+}
+
+OsinfoDevice *osinfoGetPreferredDeviceForOs(OsinfoOs *self, OsinfoHypervisor *hv, gchar *devType, OsinfoFilter *filter, GError **err)
+{
+    if (!__osinfoCheckGErrorParamValid(err))
+        return NULL;
+
+    if (!OSINFO_IS_OS(self)) {
+        g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -EINVAL, OSINFO_OBJ_NOT_OS);
+        return NULL;
+    }
+
+    if (hv && !OSINFO_IS_HYPERVISOR(hv)) {
+        g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -EINVAL, OSINFO_OBJ_NOT_HV);
+        return NULL;
+    }
+
+    if (!devType) {
+        g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -EINVAL, OSINFO_NO_DEVTYPE);
+        return NULL;
+    }
+
+    if (filter && !OSINFO_IS_FILTER(filter)) {
+        g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -EINVAL, OSINFO_OBJ_NOT_FILTER);
+        return NULL;
+    }
+
+    // Check if device type info present for <os,hv>, else return NULL.
+
+    GPtrArray *sectionList = NULL;
+    if (hv) {
+        // Check if hypervisor specific info present for Os, else return NULL.
+        struct __osinfoHvSection *hvSection = NULL;
+        hvSection = g_tree_lookup(self->priv->hypervisors, (OSINFO_ENTITY(hv))->priv->id);
+        if (!hvSection)
+            return NULL;
+
+        sectionList = g_tree_lookup(hvSection->sectionsAsList, devType);
+        if (!sectionList)
+            return NULL;
+    }
+    else {
+        sectionList = g_tree_lookup(self->priv->sectionsAsList, devType);
+        if (!sectionList)
+            return NULL;
+    }
+
+    // For each device in section list, apply filter. If filter passes, return device.
+    int i;
+    struct __osinfoDeviceLink *deviceLink;
+    for (i = 0; i < sectionList->len; i++) {
+        deviceLink = g_ptr_array_index(sectionList, i);
+        if (__osinfoDevicePassesFilter(filter, deviceLink->dev))
+            return deviceLink->dev;
+    }
+
+    // If no devices pass filter, return NULL.
+    return NULL;
+}
+
+OsinfoOsList *osinfoGetRelatedOs(OsinfoOs *self, osinfoRelationship relshp, GError **err)
+{
+    if (!__osinfoCheckGErrorParamValid(err))
+        return NULL;
+
+    if (!OSINFO_IS_OS(self)) {
+        g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -EINVAL, OSINFO_OBJ_NOT_OS);
+        return NULL;
+    }
+
+    if (!__osinfoCheckRelationshipValid(relshp)) {
+        g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -EINVAL, OSINFO_INVALID_RELATIONSHIP);
+        return NULL;
+    }
+
+    // Create our list
+    OsinfoOsList *newList = g_object_new(OSINFO_TYPE_OSLIST, NULL);
+    if (!newList) {
+        g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -ENOMEM, OSINFO_NO_MEM);
+        return NULL;
+    }
+
+    GPtrArray *relatedOses = NULL;
+    relatedOses = g_tree_lookup(self->priv->relationshipsByType, (gpointer) relshp);
+    if (relatedOses) {
+        int i, len;
+        len = relatedOses->len;
+        for (i = 0; i < len; i++) {
+            struct __osinfoOsLink *osLink = g_ptr_array_index(relatedOses, i);
+            __osinfoListAdd(OSINFO_LIST (newList), OSINFO_ENTITY (osLink->directObjectOs));
+        }
+    }
+
+    return newList;
+}
+
+OsinfoDeviceList *osinfoGetDevicesForOs(OsinfoOs *self, OsinfoHypervisor *hv, gchar *devType, OsinfoFilter *filter, GError **err)
+{
+    if (!__osinfoCheckGErrorParamValid(err))
+        return NULL;
+
+    if (!OSINFO_IS_OS(self)) {
+        g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -EINVAL, OSINFO_OBJ_NOT_OS);
+        return NULL;
+    }
+
+    if (!OSINFO_IS_HYPERVISOR(hv)) {
+        g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -EINVAL, OSINFO_OBJ_NOT_HV);
+        return NULL;
+    }
+
+    if (!devType) {
+        g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -EINVAL, OSINFO_NO_DEVTYPE);
+        return NULL;
+    }
+
+    if (filter && !OSINFO_IS_FILTER(filter)) {
+        g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -EINVAL, OSINFO_OBJ_NOT_FILTER);
+        return NULL;
+    }
+
+    GPtrArray *sectionList = NULL;
+
+    // Create our device list
+    OsinfoDeviceList *newList = g_object_new(OSINFO_TYPE_DEVICELIST, NULL);
+    if (!newList) {
+        g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -ENOMEM, OSINFO_NO_MEM);
+        return NULL;
+    }
+
+    if (hv) {
+        struct __osinfoHvSection *hvSection = NULL;
+        hvSection = g_tree_lookup(self->priv->hypervisors, (OSINFO_ENTITY(hv))->priv->id);
+        if (!hvSection)
+            return newList;
+
+        sectionList = g_tree_lookup(hvSection->sectionsAsList, devType);
+        if (!sectionList)
+            return newList;
+    }
+    else {
+        sectionList = g_tree_lookup(self->priv->sectionsAsList, devType);
+        if (!sectionList)
+            return newList;
+    }
+
+    // For each device in section list, apply filter. If filter passes, add device to list.
+    int i;
+    struct __osinfoDeviceLink *deviceLink;
+    for (i = 0; i < sectionList->len; i++) {
+        deviceLink = g_ptr_array_index(sectionList, i);
+        if (__osinfoDevicePassesFilter(filter, deviceLink->dev))
+            __osinfoListAdd(OSINFO_LIST (newList), OSINFO_ENTITY (deviceLink->dev));
+    }
+
+    return NULL;
+}
diff --git a/osinfo/osinfo_os.h b/osinfo/osinfo_os.h
new file mode 100644
index 0000000..83241c9
--- /dev/null
+++ b/osinfo/osinfo_os.h
@@ -0,0 +1,55 @@
+/*
+ * libosinfo
+ *
+ * osinfo_os.h
+ * Represents an operating system in libosinfo.
+ */
+
+#ifndef __OSINFO_OS_H__
+#define __OSINFO_OS_H__
+
+#include <glib-object.h>
+#include "osinfo_oslist.h"
+#include "osinfo_devicelist.h"
+
+/*
+ * Type macros.
+ */
+#define OSINFO_TYPE_OS                  (osinfo_os_get_type ())
+#define OSINFO_OS(obj)                  (G_TYPE_CHECK_INSTANCE_CAST ((obj), OSINFO_TYPE_OS, OsinfoOs))
+#define OSINFO_IS_OS(obj)               (G_TYPE_CHECK_INSTANCE_TYPE ((obj), OSINFO_TYPE_OS))
+#define OSINFO_OS_CLASS(klass)          (G_TYPE_CHECK_CLASS_CAST ((klass), OSINFO_TYPE_OS, OsinfoOsClass))
+#define OSINFO_IS_OS_CLASS(klass)       (G_TYPE_CHECK_CLASS_TYPE ((klass), OSINFO_TYPE_OS))
+#define OSINFO_OS_GET_CLASS(obj)        (G_TYPE_INSTANCE_GET_CLASS ((obj), OSINFO_TYPE_OS, OsinfoOsClass))
+
+//typedef struct _OsinfoOs        OsinfoOs;
+// (defined in osinfo_objects.h)
+
+typedef struct _OsinfoOsClass   OsinfoOsClass;
+
+typedef struct _OsinfoOsPrivate OsinfoOsPrivate;
+
+/* object */
+struct _OsinfoOs
+{
+    OsinfoEntity parent_instance;
+
+    /* public */
+
+    /* private */
+    OsinfoOsPrivate *priv;
+};
+
+/* class */
+struct _OsinfoOsClass
+{
+    OsinfoEntityClass parent_class;
+
+    /* class members */
+};
+
+OsinfoDevice *osinfoGetPreferredDeviceForOs(OsinfoOs *self, OsinfoHypervisor *hv, gchar *devType, OsinfoFilter *filter, GError **err);
+OsinfoOsList *osinfoGetRelatedOs(OsinfoOs *self, osinfoRelationship relshp, GError **err);
+OsinfoDeviceList *osinfoGetDevicesForOs(OsinfoOs *self, OsinfoHypervisor *hv, gchar *devType, OsinfoFilter *filter, GError **err);
+
+#endif /* __OSINFO_OS_H__ */
diff --git a/osinfo/osinfo_oslist.c b/osinfo/osinfo_oslist.c
new file mode 100644
index 0000000..4a3d1ce
--- /dev/null
+++ b/osinfo/osinfo_oslist.c
@@ -0,0 +1,121 @@
+#include <osinfo/osinfo.h>
+
+G_DEFINE_TYPE (OsinfoOsList, osinfo_oslist, OSINFO_TYPE_LIST);
+
+#define OSINFO_OSLIST_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), OSINFO_TYPE_OSLIST, OsinfoOsListPrivate))
+
+static void osinfo_oslist_finalize (GObject *object);
+
+struct _OsinfoOsListPrivate
+{
+    int tmp;
+};
+
+static void
+osinfo_oslist_finalize (GObject *object)
+{
+    /* Chain up to the parent class */
+    G_OBJECT_CLASS (osinfo_oslist_parent_class)->finalize (object);
+}
+
+/* Init functions */
+static void
+osinfo_oslist_class_init (OsinfoOsListClass *klass)
+{
+    GObjectClass *g_klass = G_OBJECT_CLASS (klass);
+
+    g_klass->finalize = osinfo_oslist_finalize;
+    g_type_class_add_private (klass, sizeof (OsinfoOsListPrivate));
+}
+
+static void
+osinfo_oslist_init (OsinfoOsList *self)
+{
+    OsinfoOsListPrivate *priv;
+    self->priv = priv = OSINFO_OSLIST_GET_PRIVATE(self);
+
+}
+
+OsinfoOs *osinfoGetOsAtIndex(OsinfoOsList *self, gint idx, GError **err)
+{
+    if (!OSINFO_IS_OSLIST(self)) {
+        g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -EINVAL, OSINFO_OBJ_NOT_OSLIST);
+        return NULL;
+    }
+
+    OsinfoList *selfAsList = OSINFO_LIST (self);
+    OsinfoEntity *entity = osinfoGetEntityAtIndex(selfAsList, idx);
+    return OSINFO_OS (entity);
+}
+
+OsinfoOsList *osinfoOsListFilter(OsinfoOsList *self, OsinfoFilter *filter, GError **err)
+{
+    if (!OSINFO_IS_OSLIST(self)) {
+        g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -EINVAL, OSINFO_OBJ_NOT_OSLIST);
+        return NULL;
+    }
+
+    if (filter && !OSINFO_IS_FILTER(self)) {
+        g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -EINVAL, OSINFO_OBJ_NOT_FILTER);
+        return NULL;
+    }
+
+    // For each element in self, if passes filter, add to new list.
+    OsinfoOsList *newList = g_object_new(OSINFO_TYPE_OSLIST, NULL);
+    if (!newList) {
+        g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -ENOMEM, OSINFO_NO_MEM);
+        return NULL;
+    }
+
+    __osinfoDoFilter(OSINFO_LIST (self), OSINFO_LIST (newList), filter);
+    return newList;
+}
+
+OsinfoOsList *osinfoOsListIntersect(OsinfoOsList *self, OsinfoOsList *otherList, GError **err)
+{
+    if (!OSINFO_IS_OSLIST(self) || !OSINFO_IS_OSLIST(otherList)) {
+        g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -EINVAL, OSINFO_OBJ_NOT_OSLIST);
+        return NULL;
+    }
+
+    OsinfoOsList *newList = g_object_new(OSINFO_TYPE_OSLIST, NULL);
+    if (!newList) {
+        g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -ENOMEM, OSINFO_NO_MEM);
+        return NULL;
+    }
+
+    int ret;
+
+    ret = __osinfoDoIntersect(self, otherList, newList);
+    if (ret != 0) {
+        g_object_unref(newList);
+        g_set_error_literal(err, g_quark_from_static_string("libosinfo"), ret, __osinfoErrorToString(ret));
+        return NULL;
+    }
+
+    return newList;
+}
+
+OsinfoOsList *osinfoOsListUnion(OsinfoOsList *self, OsinfoOsList *otherList, GError **err)
+{
+    if (!OSINFO_IS_OSLIST(self) || !OSINFO_IS_OSLIST(otherList)) {
+        g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -EINVAL, OSINFO_OBJ_NOT_OSLIST);
+        return NULL;
+    }
+
+    OsinfoOsList *newList = g_object_new(OSINFO_TYPE_OSLIST, NULL);
+    if (!newList) {
+        g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -ENOMEM, OSINFO_NO_MEM);
+        return NULL;
+    }
+
+    int ret;
+    ret = __osinfoDoUnion(self, otherList, newList);
+    if (ret != 0) {
+        g_object_unref(newList);
+        g_set_error_literal(err, g_quark_from_static_string("libosinfo"), ret, __osinfoErrorToString(ret));
+        return NULL;
+    }
+
+    return newList;
+}
diff --git a/osinfo/osinfo_oslist.h b/osinfo/osinfo_oslist.h
new file mode 100644
index 0000000..168f5a5
--- /dev/null
+++ b/osinfo/osinfo_oslist.h
@@ -0,0 +1,51 @@
+/*
+ * libosinfo
+ *
+ * osinfo_oslist.h
+ * All entities represented in libosinfo are derived from this class.
+ */
+
+#ifndef __OSINFO_OSLIST_H__
+#define __OSINFO_OSLIST_H__
+
+/*
+ * Type macros.
+ */
+#define OSINFO_TYPE_OSLIST                  (osinfo_oslist_get_type ())
+#define OSINFO_OSLIST(obj)                  (G_TYPE_CHECK_INSTANCE_CAST ((obj), OSINFO_TYPE_OSLIST, OsinfoOsList))
+#define OSINFO_IS_OSLIST(obj)               (G_TYPE_CHECK_INSTANCE_TYPE ((obj), OSINFO_TYPE_OSLIST))
+#define OSINFO_OSLIST_CLASS(klass)          (G_TYPE_CHECK_CLASS_CAST ((klass), OSINFO_TYPE_OSLIST, OsinfoOsListClass))
+#define OSINFO_IS_OSLIST_CLASS(klass)       (G_TYPE_CHECK_CLASS_TYPE ((klass), OSINFO_TYPE_OSLIST))
+#define OSINFO_OSLIST_GET_CLASS(obj)        (G_TYPE_INSTANCE_GET_CLASS ((obj), OSINFO_TYPE_OSLIST, OsinfoOsListClass))
+
+typedef struct _OsinfoOsList        OsinfoOsList;
+
+typedef struct _OsinfoOsListClass   OsinfoOsListClass;
+
+typedef struct _OsinfoOsListPrivate OsinfoOsListPrivate;
+
+/* object */
+struct _OsinfoOsList
+{
+    GObject parent_instance;
+
+    /* public */
+
+    /* private */
+    OsinfoOsListPrivate *priv;
+};
+
+/* class */
+struct _OsinfoOsListClass
+{
+    GObjectClass parent_class;
+
+    /* class members */
+};
+
+OsinfoOsList *osinfoOsListFilter(OsinfoOsList *self, OsinfoFilter *filter, GError **err);
+OsinfoOs *osinfoGetOsAtIndex(OsinfoOsList *self, gint idx, GError **err);
+OsinfoOsList *osinfoOsListIntersect(OsinfoOsList *self, OsinfoOsList *otherOsList, GError **err);
+OsinfoOsList *osinfoOsListUnion(OsinfoOsList *self, OsinfoOsList *otherOsList, GError **err);
+
+#endif /* __OSINFO_OSLIST_H__ */
diff --git a/src/osinfo_common.c b/src/osinfo_common.c
deleted file mode 100644
index 3dc1cc0..0000000
--- a/src/osinfo_common.c
+++ /dev/null
@@ -1,349 +0,0 @@
-#include <osinfo.h>
-
-static int __osinfoAddDeviceToList(GTree *allSectionsAsList,
-                                   gchar *sectionName,
-                                   struct __osinfoDeviceLink *deviceLink)
-{
-    if (!allSectionsAsList || !sectionName || !deviceLink)
-        return -EINVAL;
-
-    gboolean found;
-    gpointer origKey, foundValue;
-    GPtrArray *sectionList;
-    gchar *sectionNameDup = NULL;
-
-    found = g_tree_lookup_extended(allSectionsAsList, sectionName, &origKey, &foundValue);
-    if (!found) {
-        sectionList = g_ptr_array_new();
-        sectionNameDup = g_strdup(sectionName);
-
-        if (!sectionList)
-            goto error_free;
-        if (!sectionNameDup) {
-            g_ptr_array_free(sectionList, TRUE);
-            goto error_free;
-        }
-
-        g_tree_insert(allSectionsAsList, sectionNameDup, sectionList);
-    }
-    else
-        sectionList = (GPtrArray *) foundValue;
-
-    g_ptr_array_add(sectionList, deviceLink);
-    return 0;
-
-error_free:
-    g_free(sectionNameDup);
-    return -ENOMEM;
-}
-
-int __osinfoAddDeviceToSection(GTree *allSections, GTree *allSectionsAsList, gchar *sectionName, gchar *id, gchar *driver)
-{
-    if (!allSections || !sectionName || !id)
-        return -EINVAL;
-
-    gboolean found;
-    gpointer origKey, foundValue;
-    gchar *sectionNameDup = NULL, *idDup = NULL, *driverDup = NULL;
-    GTree *section;
-    struct __osinfoDeviceLink *deviceLink;
-    int ret;
-
-    idDup = g_strdup(id);
-    driverDup = g_strdup(driver);
-    deviceLink = g_malloc(sizeof(*deviceLink));
-
-    if (!idDup || g_strcmp0(driverDup, driver) != 0 || !deviceLink)
-        goto error_free;
-
-    found = g_tree_lookup_extended(allSections, sectionName, &origKey, &foundValue);
-    if (!found) {
-        section = g_tree_new_full(__osinfoStringCompare, NULL, g_free, __osinfoFreeDeviceLink);
-        sectionNameDup = g_strdup(sectionName);
-
-        if (!section)
-            goto error_free;
-        if (!sectionNameDup) {
-            g_tree_destroy(section);
-            goto error_free;
-        }
-
-        g_tree_insert(allSections, sectionNameDup, section);
-    }
-    else
-        section = (GTree *) foundValue;
-
-    deviceLink->driver = driverDup;
-    g_tree_insert(section, idDup, deviceLink);
-
-    ret = 0;
-    if (allSectionsAsList)
-        ret = __osinfoAddDeviceToList(allSectionsAsList, sectionName, deviceLink);
-
-    return ret;
-
-error_free:
-    g_free(sectionNameDup);
-    g_free(idDup);
-    g_free(driverDup);
-    g_free(deviceLink);
-    return -ENOMEM;
-}
-
-void __osinfoClearDeviceSection(GTree *allSections, GTree *allSectionsAsList, gchar *section)
-{
-    if (!allSections || !section)
-        return;
-
-    g_tree_remove(allSections, section);
-    g_tree_remove(allSectionsAsList, section);
-}
-
-void __osinfoFreeDeviceLink(gpointer ptr)
-{
-    if (!ptr)
-        return;
-    struct __osinfoDeviceLink *devLink = (struct __osinfoDeviceLink *) ptr;
-    g_free(devLink->driver);
-    g_free(devLink);
-}
-
-void __osinfoFreeDeviceSection(gpointer tree)
-{
-    if (!tree)
-        return;
-    g_tree_destroy((GTree *)tree);
-}
-
-gint __osinfoStringCompare(gconstpointer a,
-                           gconstpointer b,
-                           gpointer data)
-{
-    // a and b are each gchar *, data is ignored
-    gchar *str1 = (gchar *) a;
-    gchar *str2 = (gchar *) b;
-    return g_strcmp0(str1, str2);
-}
-
-gint __osinfoStringCompareBase(gconstpointer a,
-                               gconstpointer b)
-{
-    // a and b are each gchar *, data is ignored
-    gchar *str1 = (gchar *) a;
-    gchar *str2 = (gchar *) b;
-    return g_strcmp0(str1, str2);
-}
-
-gint __osinfoIntCompareBase(gconstpointer a,
-                            gconstpointer b)
-{
-    // a and b are each gchar *, data is ignored
-    unsigned long int1 = (unsigned long) a;
-    unsigned long int2 = (unsigned long) b;
-    return a - b;
-}
-
-gint __osinfoIntCompare(gconstpointer a,
-                        gconstpointer b,
-                        gpointer data)
-{
-    // a and b are each gchar *, data is ignored
-    unsigned long int1 = (unsigned long) a;
-    unsigned long int2 = (unsigned long) b;
-    return a - b;
-}
-
-void __osinfoFreePtrArray(gpointer ptrarray)
-{
-    g_ptr_array_free(ptrarray, TRUE);
-}
-
-void __osinfoFreeRelationship(gpointer ptrarray)
-{
-    if (!ptrarray)
-        return;
-    __osinfoFreePtrArray(ptrarray);
-}
-
-void __osinfoFreeParamVals(gpointer ptrarray)
-{
-    if (!ptrarray)
-        return;
-    __osinfoFreePtrArray(ptrarray);
-}
-
-void __osinfoFreeOsLink(gpointer ptr)
-{
-    if (!ptr)
-        return;
-    struct __osinfoOsLink *osLink = (struct __osinfoOsLink *) ptr;
-    g_free(osLink);
-}
-
-void __osinfoFreeHvSection(gpointer ptr)
-{
-    if (!ptr)
-        return;
-    struct __osinfoHvSection * hvSection = (struct __osinfoHvSection *) ptr;
-    g_tree_destroy(hvSection->sections);
-    g_tree_destroy(hvSection->sectionsAsList);
-    g_free(hvSection);
-}
-
-gboolean __osinfoFilterCheckProperty(gpointer key, gpointer value, gpointer data)
-{
-    struct __osinfoFilterPassArgs *args;
-    args = (struct __osinfoFilterPassArgs *) data;
-    OsinfoEntity *entity = args->entity;
-
-    // Key is property to filter on
-    // Value is array of values for property
-
-    GPtrArray *filterValues = (GPtrArray *) value;
-    GPtrArray *entityValues = NULL;
-
-    entityValues = g_tree_lookup(entity->priv->params, key);
-    if (!entityValues && filterValues->len > 0) {
-        args->passed = 0;
-        return TRUE; // not passed
-    }
-
-    int i;
-    for (i = 0; i < filterValues->len; i++) {
-        gchar *currValue = g_ptr_array_index(filterValues, i);
-        int j, found = 0;
-        for (j = 0; j < entityValues->len; j++) {
-            gchar *testValue = g_ptr_array_index(entityValues, j);
-            if (g_strcmp0(currValue, testValue) == 0) {
-                found = 1;
-                break;
-            }
-        }
-        if (found)
-            continue;
-        else {
-            args->passed = 0;
-            return TRUE; // not passed
-        }
-    }
-
-    args->passed = 1;
-    return FALSE; // continue iterating
-}
-
-int __osinfoEntityPassesFilter(OsinfoFilter *filter, OsinfoEntity *entity)
-{
-    if (!OSINFO_IS_ENTITY(entity))
-        return 0;
-
-    if (!filter)
-        return 1;
-
-    if (!OSINFO_IS_FILTER(filter))
-        return 0;
-
-    struct __osinfoFilterPassArgs args = {0, entity};
-    g_tree_foreach(filter->priv->propertyConstraints, __osinfoFilterCheckProperty, &args);
-    if (args.passed)
-        return 1;
-    else
-        return 0;
-}
-
-int __osinfoDevicePassesFilter(OsinfoFilter *filter, OsinfoDevice *device)
-{
-    // Check is device
-    return __osinfoEntityPassesFilter(filter, OSINFO_ENTITY (device));
-}
-
-gboolean __osinfoFilterCheckRelationships(gpointer key, gpointer value, gpointer data)
-{
-    struct __osinfoFilterPassArgs *args;
-    args = (struct __osinfoFilterPassArgs *) data;
-    OsinfoOs *os = (OsinfoOs *) args->entity;
-
-    // Key is relationship to filter on
-    // Value is array of oses for relationship
-
-    GPtrArray *filterOses = (GPtrArray *) value;
-    GPtrArray *oses = NULL;
-
-    oses = g_tree_lookup(os->priv->relationshipsByType, key);
-    if (!oses && filterOses->len > 0) {
-        args->passed = 0;
-        return TRUE; // not passed
-    }
-
-    int i;
-    for (i = 0; i < filterOses->len; i++) {
-        OsinfoOs *currOs = g_ptr_array_index(filterOses, i);
-        int j, found = 0;
-        for (j = 0; j < oses->len; j++) {
-            OsinfoOs *testOs = g_ptr_array_index(oses, j);
-            if (testOs == currOs) {
-                found = 1;
-                break;
-            }
-        }
-        if (found)
-            continue;
-        else {
-            args->passed = 0;
-            return TRUE; // not passed
-        }
-    }
-
-    args->passed = 1;
-    return FALSE; // continue iterating
-}
-
-int __osinfoOsPassesFilter(OsinfoFilter *filter, OsinfoOs *os)
-{
-    if (!OSINFO_IS_OS(os))
-        return 0;
-
-    if (!filter)
-        return 1;
-
-    if (!OSINFO_IS_FILTER(filter))
-        return 0;
-
-    int pass = __osinfoEntityPassesFilter(filter, OSINFO_ENTITY (os));
-    if (!pass)
-        return 0;
-
-    struct __osinfoFilterPassArgs args = {0, (OsinfoEntity *) os};
-    g_tree_foreach(filter->priv->relationshipConstraints, __osinfoFilterCheckRelationships, &args);
-    if (args.passed)
-        return 1;
-    else
-        return 0;
-}
-
-int __osinfoHypervisorPassesFilter(OsinfoFilter *filter, OsinfoHypervisor *hypervisor)
-{
-    return __osinfoEntityPassesFilter(filter, OSINFO_ENTITY (hypervisor));
-}
-
-int __osinfoCheckGErrorParamValid(GError **err)
-{
-    // If err is not null and *err is not null, then invalid
-    if (err && *err)
-        return 0;
-    else return 1;
-}
-
-int __osinfoCheckRelationshipValid(osinfoRelationship relshp)
-{
-    return (relshp > RELATIONSHIP_MIN && relshp < RELATIONSHIP_MAX);
-}
-
-gchar *__osinfoErrorToString(int err)
-{
-    switch (err) {
-        case -ENOMEM:
-            return OSINFO_NO_MEM;
-        default:
-            return OSINFO_OTHER;
-    }
-}
diff --git a/src/osinfo_dataread.c b/src/osinfo_dataread.c
deleted file mode 100644
index e1e0d52..0000000
--- a/src/osinfo_dataread.c
+++ /dev/null
@@ -1,915 +0,0 @@
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-#include <dirent.h>
-#include <errno.h>
-#include <unistd.h>
-#include <libxml/xmlreader.h>
-
-#include <osinfo.h>
-
-#ifdef LIBXML_READER_ENABLED
-
-#define TEXT_NODE 3
-#define ELEMENT_NODE 1
-#define END_NODE 15
-#define WHITESPACE_NODE 14
-#define COMMENT_NODE 8
-
-/*
- * TODO:
- * 1. More robust handling of files that are in bad format
- * 2. Error messages for parsing
- */
-
-/*
- * Notes regarding parsing XML Data:
- *
- * The top level tag is <libosinfo>. The next highest level consists of
- * <device>, <hypervisor> and <os>. Each tag may be empty (of the form <tag />)
- * or containing data (of the form <tag>...</tag>). After parsing an object, the
- * cursor will be located at the closing tag for the object (which, for an empty
- * object, is the same as the starting tag for the object).
- */
-
-struct __osinfoDbRet {
-    OsinfoDb *db;
-    int *ret;
-};
-
-static gboolean __osinfoResolveDeviceLink(gpointer key, gpointer value, gpointer data)
-{
-    gchar *id = (gchar *) key;
-    struct __osinfoDeviceLink *devLink = (struct __osinfoDeviceLink *) value;
-    struct __osinfoDbRet *dbRet = (struct __osinfoDbRet *) data;
-    OsinfoDb *db = dbRet->db;
-    int *ret = dbRet->ret;
-
-    OsinfoDevice *dev = g_tree_lookup(db->priv->devices, id);
-    if (!dev) {
-        *ret = -EINVAL;
-        return TRUE;
-    }
-
-    devLink->dev = dev;
-    *ret = 0;
-    return FALSE;
-}
-
-static gboolean __osinfoResolveSectionDevices(gpointer key, gpointer value, gpointer data)
-{
-    struct __osinfoDbRet *dbRet = (struct __osinfoDbRet *) data;
-    OsinfoDb *db = dbRet->db;
-    int *ret = dbRet->ret;
-    GTree *section = (GTree *) value;
-    if (!section) {
-        *ret = -EINVAL;
-        return TRUE;
-    }
-
-    g_tree_foreach(section, __osinfoResolveDeviceLink, dbRet);
-    if (*ret)
-        return TRUE;
-    return FALSE;
-}
-
-static gboolean __osinfoResolveHvLink(gpointer key, gpointer value, gpointer data)
-{
-    gchar *hvId = (gchar *) key;
-    struct __osinfoDbRet *dbRet = (struct __osinfoDbRet *) data;
-    OsinfoDb *db = dbRet->db;
-    int *ret = dbRet->ret;
-    struct __osinfoHvSection *hvSection = (struct __osinfoHvSection *) value;
-    OsinfoHypervisor *hv;
-
-    g_tree_foreach(hvSection->sections, __osinfoResolveSectionDevices, dbRet);
-    if (*ret)
-        return TRUE;
-
-    hv = g_tree_lookup(db->priv->hypervisors, hvId);
-    if (!hv) {
-        *ret = -EINVAL;
-        return TRUE;
-    }
-
-    hvSection->hv = hv;
-    *ret = 0;
-    return FALSE;
-}
-
-static gboolean __osinfoResolveOsLink(gpointer key, gpointer value, gpointer data)
-{
-    gchar *targetOsId = (gchar *) key;
-    struct __osinfoDbRet *dbRet = (struct __osinfoDbRet *) data;
-    OsinfoDb *db = dbRet->db;
-    int *ret = dbRet->ret;
-    struct __osinfoOsLink *osLink = (struct __osinfoOsLink *) value;
-
-    OsinfoOs *targetOs;
-    targetOs = g_tree_lookup(db->priv->oses, targetOsId);
-    if (!targetOs) {
-        *ret = -EINVAL;
-        return TRUE;
-    }
-
-    osLink->directObjectOs = targetOs;
-    *ret = 0;
-    return FALSE;
-}
-
-static gboolean __osinfoFixOsLinks(gpointer key, gpointer value, gpointer data)
-{
-    struct __osinfoDbRet *dbRet = (struct __osinfoDbRet *) data;
-    OsinfoDb *db = dbRet->db;
-    int *ret = dbRet->ret;
-    OsinfoOs *os = OSINFO_OS(value);
-    if (!os) {
-        *ret = -EINVAL;
-        return TRUE;
-    }
-
-    g_tree_foreach(os->priv->sections, __osinfoResolveSectionDevices, dbRet);
-    if (*ret)
-        return TRUE;
-
-    g_tree_foreach(os->priv->relationshipsByOs, __osinfoResolveOsLink, dbRet);
-    if (*ret)
-        return TRUE;
-
-    g_tree_foreach(os->priv->hypervisors, __osinfoResolveHvLink, dbRet);
-    if (*ret)
-        return TRUE;
-
-    *ret = 0;
-    return FALSE;
-}
-
-static gboolean __osinfoFixHvLinks(gpointer key, gpointer value, gpointer data)
-{
-    struct __osinfoDbRet *dbRet = (struct __osinfoDbRet *) data;
-    OsinfoDb *db = dbRet->db;
-    int *ret = dbRet->ret;
-    OsinfoHypervisor *hv = OSINFO_HYPERVISOR(value);
-    if (!hv) {
-        *ret = -EINVAL;
-        return TRUE;
-    }
-
-    g_tree_foreach(hv->priv->sections, __osinfoResolveSectionDevices, dbRet);
-    if (*ret)
-        return TRUE;
-    return FALSE;
-}
-
-static int __osinfoFixObjLinks(OsinfoDb *db)
-{
-    OsinfoHypervisor *hv;
-    OsinfoOs *os;
-    int ret;
-
-    if (!OSINFO_IS_DB(db))
-        return -EINVAL;
-
-    struct __osinfoDbRet dbRet = {db, &ret};
-
-    g_tree_foreach(db->priv->hypervisors, __osinfoFixHvLinks, &dbRet);
-    if (ret)
-        return ret;
-    g_tree_foreach(db->priv->oses, __osinfoFixOsLinks, &dbRet);
-
-    return ret;
-}
-
-static int __osinfoProcessTag(xmlTextReaderPtr reader, char** ptr_to_key, char** ptr_to_val)
-{
-    int node_type, ret, err = 0;
-    char* key = NULL;
-    char* val = NULL;
-    const xmlChar* node_name, * end_node_name, * xml_value;
-
-    node_name = xmlTextReaderConstName(reader);
-    if (!node_name)
-        goto error;
-
-    key = strdup(node_name);
-    if (!key) {
-        err = -ENOMEM;
-        goto error;
-    }
-
-    /* Advance to next node */
-    ret = xmlTextReaderRead(reader);
-    if (ret != 1)
-        goto error;
-
-    /* Ensure node is a text node */
-    node_type = xmlTextReaderNodeType(reader);
-    if (node_type != TEXT_NODE)
-        goto error;
-
-    /* Store the value of the text node */
-    xml_value = xmlTextReaderConstValue(reader);
-    if (!xml_value)
-        goto error;
-
-    val = strdup(xml_value);
-    if (!val) {
-        err = -ENOMEM;
-        goto error;
-    }
-
-    /* Advance to the next node */
-    ret = xmlTextReaderRead(reader);
-    if (ret != 1)
-        goto error;
-
-    /* Ensure the node is an end node for the tracked start node */
-    node_type = xmlTextReaderNodeType(reader);
-    end_node_name = xmlTextReaderConstName(reader);
-    if (node_type != END_NODE ||
-        !end_node_name ||
-        strcmp(end_node_name, node_name) != 0)
-            goto error;
-
-    /* Now we have key and val with no errors so we return with success */
-    *ptr_to_key = key;
-    *ptr_to_val = val;
-    return 0;
-
-error:
-    free(key);
-    free(val);
-    *ptr_to_key = NULL;
-    *ptr_to_val = NULL;
-    if (err == 0)
-        err = -EINVAL;
-    return err;
-}
-
-static int __osinfoProcessDevSection(xmlTextReaderPtr reader,
-                                     GTree *section, GTree *sectionAsList)
-{
-    int err, empty, node_type;
-    char * sectionType, * id, * key = NULL, * driver = NULL;
-    const char * name;
-
-    if (!section)
-        return -EINVAL;
-
-    sectionType = xmlTextReaderGetAttribute(reader, "type");
-    empty = xmlTextReaderIsEmptyElement(reader);
-
-    if (!sectionType)
-        return -EINVAL;
-
-    /* If no devices in section then we are done */
-    if (empty)
-        return 0;
-
-    /* Otherwise, read in devices and add to section */
-    for (;;) {
-        /* Advance to next node */
-        err = xmlTextReaderRead(reader);
-        if (err != 1) {
-            err = -EINVAL;
-            goto error;
-        }
-
-        node_type = xmlTextReaderNodeType(reader);
-        name = xmlTextReaderConstName(reader);
-
-        /* If end of section, break */
-        if (node_type == END_NODE && strcmp(name, "section") == 0)
-            break;
-
-        /* If node is not start of an element, continue */
-        if (node_type != ELEMENT_NODE)
-            continue;
-
-        /* Element within section needs to be of type device */
-        if (strcmp(name, "device") != 0) {
-            err = -EINVAL;
-            goto error;
-        }
-
-        id = xmlTextReaderGetAttribute(reader, "id");
-        empty = xmlTextReaderIsEmptyElement(reader);
-
-        if (!id) {
-            err = -EINVAL;
-            goto error;
-        }
-
-        if (!empty) {
-            err = __osinfoProcessTag(reader, &key, &driver);
-            if (err != 0 || !key || !driver)
-                goto error;
-            free(key);
-            key = NULL; /* In case the next malloc fails, avoid a double free */
-        }
-
-        // Alright, we have the id and driver
-        err = __osinfoAddDeviceToSection(section, sectionAsList, sectionType, id, driver);
-        free (driver);
-        driver = NULL;
-        free (id);
-        id = NULL;
-        if (err != 0)
-            goto error;
-    }
-    free(sectionType);
-
-finished:
-    return 0;
-
-error:
-    free(sectionType);
-    free(key);
-    free(driver);
-    return err;
-}
-
-static int __osinfoProcessOsHvLink(xmlTextReaderPtr reader,
-                                   OsinfoOs *os)
-{
-    /*
-     * Get id for hypervisor else fail
-     * While true:
-     *   Advance to next node
-     *   If node is end of hypervisor break
-     *   If node is not element type continue
-     *   If node is element type and not section fail
-     *   Else handle section and add to hv_link
-     * If fail delete hv_link so far
-     * On success add hv_link to os
-     */
-    int empty, node_type, err;
-    char* id;
-    const xmlChar* name;
-    struct __osinfoHvSection *hvSection;
-
-    id = xmlTextReaderGetAttribute(reader, "id");
-    empty = xmlTextReaderIsEmptyElement(reader);
-
-    if (!id)
-        return -EINVAL;
-
-    hvSection = __osinfoAddHypervisorSectionToOs(os, id);
-    free(id);
-    if (!hvSection)
-        return -EINVAL;
-
-    if (empty)
-        goto finished;
-
-    for (;;) {
-        /* Advance to next node */
-        err = xmlTextReaderRead(reader);
-        if (err != 1) {
-            err = -EINVAL;
-            goto error;
-        }
-
-        node_type = xmlTextReaderNodeType(reader);
-        name = xmlTextReaderConstName(reader);
-        if (node_type == -1 || !name) {
-            err = -EINVAL;
-            goto error;
-        }
-
-        /* If end of hv link, break */
-        if (node_type == END_NODE && strcmp(name, "hypervisor") == 0)
-            break;
-
-        /* If node is not start of an element, continue */
-        if (node_type != ELEMENT_NODE)
-            continue;
-
-        /* Ensure it is element node of type 'section' else fail */
-        if (strcmp(name, "section") != 0) {
-            err = -EINVAL;
-            goto error;
-        }
-
-        /* Process device type info for this <os, hv> combination */
-        err = __osinfoProcessDevSection(reader, hvSection->sections, hvSection->sectionsAsList);
-        if (err != 0)
-            goto error;
-    }
-
-finished:
-    return 0;
-
-error:
-    return err;
-}
-
-static int __osinfoProcessOsRelationship(xmlTextReaderPtr reader,
-                                         OsinfoOs *os,
-                                         osinfoRelationship relationship)
-{
-    int empty, ret;
-    char* id;
-    struct osi_os_link * os_link;
-
-    id = xmlTextReaderGetAttribute(reader, "id");
-    empty = xmlTextReaderIsEmptyElement(reader);
-    if (!empty || !id) {
-        free(id);
-        return -EINVAL;
-    }
-
-    ret = __osinfoAddOsRelationship (os, id, relationship);
-    free(id);
-    return ret;
-}
-
-static int __osinfoProcessOs(OsinfoDb *db,
-                          xmlTextReaderPtr reader)
-{
-    /* Cursor is at start of (possibly empty) os node */
-    /*
-     * First, determine if hv has ID or not, and if tag is empty or not.
-     * The following cases can occur:
-     * 1. No ID: Return invalid. Parse fails overall.
-     * 2. Empty, ID: Make hv with given ID and no data and return.
-     * 3. Non-Empty, ID: Make hv, parse data till closing tag, return.
-     */
-
-    int empty, node_type, err, ret;
-    char* id, * key = NULL, * val = NULL;
-    const xmlChar* name;
-    OsinfoOs *os;
-
-    id = xmlTextReaderGetAttribute(reader, "id");
-    empty = xmlTextReaderIsEmptyElement(reader);
-
-    if (!id)
-        return -EINVAL;
-
-    os = g_object_new(OSINFO_TYPE_OS, "id", id, "db", db, NULL);
-    free(id);
-    if (!os)
-        return -ENOMEM;
-
-    if (empty)
-        goto finished;
-
-    /* Current node is start of non empty os
-     * While true:
-     *   Advance to next node
-     *   If node == end of os break
-     *   If node is not element, continue
-     *   If node is element and not section or hypervisor:
-     *     Note element name
-     *     Advance to next node, ensure type is text else error
-     *     Store value, advance to next node
-     *     Ensure node is end of current name
-     *     Store <key, val> in params list for object
-     *   If node is start of section handle section and track device driver
-     *   If node is hypervisor handle hypervisor link
-     */
-
-    for (;;) {
-        /* Advance to next node */
-        ret = xmlTextReaderRead(reader);
-        if (ret != 1) {
-            err = -EINVAL;
-            goto cleanup_error;
-        }
-
-        node_type = xmlTextReaderNodeType(reader);
-        name = xmlTextReaderConstName(reader);
-        if (node_type == -1 || !name) {
-            err = -EINVAL;
-            goto cleanup_error;
-        }
-        /* If end of os, break */
-        if (node_type == END_NODE && strcmp(name, "os") == 0)
-            break;
-
-        /* If node is not start of an element, continue */
-        if (node_type != ELEMENT_NODE)
-            continue;
-
-        if (strcmp(name, "section") == 0) {
-            /* Node is start of device section for os */
-            err = __osinfoProcessDevSection(reader, (OSINFO_OS(os))->priv->sections, (OSINFO_OS(os))->priv->sectionsAsList);
-            if (err != 0)
-                goto cleanup_error;
-        }
-        else if (strcmp(name, "hypervisor") == 0) {
-            err = __osinfoProcessOsHvLink(reader, os);
-            if (err != 0)
-                goto cleanup_error;
-        }
-        else if (strcmp(name, "upgrades") == 0) {
-            err = __osinfoProcessOsRelationship(reader, os, UPGRADES);
-            if (err != 0)
-                goto cleanup_error;
-        }
-        else if (strcmp(name, "clones") == 0) {
-            err = __osinfoProcessOsRelationship(reader, os, CLONES);
-            if (err != 0)
-                goto cleanup_error;
-        }
-        else if (strcmp(name, "derives-from") == 0) {
-            err = __osinfoProcessOsRelationship(reader, os, DERIVES_FROM);
-            if (err != 0)
-                goto cleanup_error;
-        }
-        else {
-            /* Node is start of element of known name */
-            err = __osinfoProcessTag(reader, &key, &val);
-            if (err != 0 || !key || !val)
-                goto cleanup_error;
-
-            err = __osinfoAddParam(OSINFO_ENTITY(os), key, val);
-            if (err != 0)
-                goto cleanup_error;
-
-            free(key);
-            free(val);
-        }
-    }
-
-finished:
-    __osinfoAddOsToDb(db, os);
-    return 0;
-    /* At end, cursor is at end of os node */
-
-cleanup_error:
-    g_object_unref(os);
-    return err;
-}
-
-static int __osinfoProcessHypervisor(OsinfoDb *db,
-                                  xmlTextReaderPtr reader)
-{
-    /* Cursor is at start of (possibly empty) hypervisor node */
-
-    /*
-     * First, determine if hv has ID or not, and if tag is empty or not.
-     * The following cases can occur:
-     * 1. No ID: Return invalid. Parse fails overall.
-     * 2. Empty, ID: Make hv with given ID and no data and return.
-     * 3. Non-Empty, ID: Make hv, parse data till closing tag, return.
-     */
-
-    int empty, node_type, err, ret;
-    char* id;
-    const xmlChar* name;
-    OsinfoHypervisor *hv;
-
-    id = xmlTextReaderGetAttribute(reader, "id");
-    empty = xmlTextReaderIsEmptyElement(reader);
-
-    if (!id)
-        return -EINVAL;
-
-
-    hv = g_object_new(OSINFO_TYPE_HYPERVISOR, "id", id, "db", db, NULL);
-    free(id);
-    if (!hv) {
-        return -ENOMEM;
-    }
-
-    if (empty)
-        goto finished;
-
-    /* Current node is start of non empty hv
-     * While true:
-     *   Advance to next node
-     *   If node == end of hv break
-     *   If node is not element, continue
-     *   If node is element and not section:
-     *     Note element name
-     *     Advance to next node, ensure type is text else error
-     *     Store value, advance to next node
-     *     Ensure node is end of current name
-     *     Store <key, val> in params list for object
-     *   If node is start of section:
-     *     Note section type
-     *     While true:
-     *       Advance to next node
-     *       If node is not element continue
-     *       If end of section, break
-     *       If not empty device node, parse error
-     *       If id not defined, parse error
-     *       Store id
-     *     Store all ids for given section in the HV
-     */
-
-    for (;;) {
-        /* Advance to next node */
-        ret = xmlTextReaderRead(reader);
-        if (ret != 1) {
-            err = -EINVAL;
-            goto cleanup_error;
-        }
-
-        node_type = xmlTextReaderNodeType(reader);
-        name = xmlTextReaderConstName(reader);
-        if (node_type == -1 || !name) {
-            err = -EINVAL;
-            goto cleanup_error;
-        }
-        /* If end of hv, break */
-        if (node_type == END_NODE && strcmp(name, "hypervisor") == 0)
-            break;
-
-        /* If node is not start of an element, continue */
-        if (node_type != ELEMENT_NODE)
-            continue;
-
-        if (strcmp(name, "section") == 0) {
-            /* Node is start of device section for hv */
-            err = __osinfoProcessDevSection(reader, (OSINFO_HYPERVISOR(hv))->priv->sections, (OSINFO_HYPERVISOR(hv))->priv->sectionsAsList);
-            if (err != 0)
-                goto cleanup_error;
-        }
-        else {
-            /* Node is start of element of known name */
-            char *key = NULL, *val = NULL;
-            err = __osinfoProcessTag(reader, &key, &val);
-            if (err != 0)
-                goto cleanup_error;
-
-
-            err = __osinfoAddParam(OSINFO_ENTITY(hv), key, val);
-            free(key);
-            free(val);
-            if (err != 0)
-                goto cleanup_error;
-        }
-    }
-
-finished:
-    __osinfoAddHypervisorToDb(db, hv);
-    return 0;
-    /* At end, cursor is at end of hv node */
-
-cleanup_error:
-    g_object_unref(hv);
-    return err;
-}
-
-static int __osinfoProcessDevice(OsinfoDb *db,
-                                 xmlTextReaderPtr reader)
-{
-    /* Cursor is at start of (possibly empty) device node */
-
-    /*
-     * First, determine if device has ID or not, and if tag is empty or not.
-     * The following cases can occur:
-     * 1. No ID: Return invalid. Parse fails overall.
-     * 2. Empty, ID: Make device with given ID and no data and return.
-     * 3. Non-Empty, ID: Make device, parse data till closing tag, return.
-     */
-
-    int empty, node_type, err, ret;
-    char* id, * key, * val;
-    const xmlChar* name;
-    OsinfoDevice *dev;
-
-    id = xmlTextReaderGetAttribute(reader, "id");
-    empty = xmlTextReaderIsEmptyElement(reader);
-
-    if (!id)
-        return -EINVAL;
-
-    dev = g_object_new(OSINFO_TYPE_DEVICE, "id", id, "db", db, NULL);
-    free(id);
-    if (!dev) {
-        // TODO: How do errors in gobject creation manifest themselves?
-        return -ENOMEM;
-    }
-
-    if (empty)
-        goto finished;
-
-    /* Current node is start of non empty device
-     * While true:
-     *   Advance to next node
-     *   If node == end of device break
-     *   If node is not element, continue
-     *   If node is element:
-     *     Note element name
-     *     Advance to next node, ensure type is text else error
-     *     Store value, advance to next node
-     *     Ensure node is end of current name
-     *     Store <key, val> in params list for object
-     */
-
-    for (;;) {
-        /* Advance to next node */
-        ret = xmlTextReaderRead(reader);
-        if (ret != 1) {
-            err = -EINVAL;
-            goto cleanup_error;
-        }
-
-        node_type = xmlTextReaderNodeType(reader);
-        name = xmlTextReaderConstName(reader);
-
-        if (node_type == -1 || !name) {
-            err = -EINVAL;
-            goto cleanup_error;
-        }
-
-        /* If end of device, break */
-        if (node_type == END_NODE && strcmp(name, "device") == 0)
-            break;
-
-        /* If node is not start of an element, continue */
-        if (node_type != ELEMENT_NODE)
-            continue;
-
-        /* Node is start of element of known name */
-        err = __osinfoProcessTag(reader, &key, &val);
-        if (err != 0 || !key || !val)
-            goto cleanup_error;
-
-        err = __osinfoAddParam(OSINFO_ENTITY(dev), key, val);
-        if (err != 0)
-            goto cleanup_error;
-
-        free(key);
-        free(val);
-    }
-
-finished:
-    // Add dev to db
-    __osinfoAddDeviceToDb(db, dev);
-    return 0;
-    /* At end, cursor is at end of device node */
-
-cleanup_error:
-    free(key);
-    free(val);
-    g_object_unref(dev);
-    return err;
-}
-
-static int __osinfoProcessFile(OsinfoDb *db,
-                               xmlTextReaderPtr reader)
-{
-    /*
-     * File assumed to contain data in XML format. All data
-     * is within <libosinfo>...</libosinfo>. The following steps are taken
-     * to process the data within the file:
-     *
-     * Advance till we are at opening <libosinfo> tag.
-     * While true:
-     *   Advance tag
-     *   If closing libosinfo tag, break
-     *   If non element tag, continue
-     *   If element tag, and element is not os, hypervisor or device, error
-     *   Else, switch on tag type and handle reading in data
-     * After loop, return success if no error
-     * If there was an error, clean up lib data acquired so far
-     */
-
-    int err, node_type, ret;
-    const char* name;
-
-    /* Advance to starting libosinfo tag */
-    for (;;) {
-        err = xmlTextReaderRead(reader);
-        if (err != 1) {
-            err = -EINVAL;
-            goto cleanup_error;
-        }
-
-        node_type = xmlTextReaderNodeType(reader);
-        if (node_type != ELEMENT_NODE)
-            continue;
-
-        name = xmlTextReaderConstName(reader);
-        if (strcmp(name, "libosinfo") == 0)
-            break;
-    }
-
-    /* Now read and handle each tag of interest */
-    for (;;) {
-        /* Advance to next node */
-        ret = xmlTextReaderRead(reader);
-        if (ret != 1) {
-            err = -EINVAL;
-            goto cleanup_error;
-        }
-
-        node_type = xmlTextReaderNodeType(reader);
-        name = xmlTextReaderConstName(reader);
-
-        if (node_type == -1 || !name) {
-            err = -EINVAL;
-            goto cleanup_error;
-        }
-
-        /* If end of libosinfo, break */
-        if (node_type == END_NODE && strcmp(name, "libosinfo") == 0)
-            break;
-
-        /* If node is not start of an element, continue */
-        if (node_type != ELEMENT_NODE)
-            continue;
-
-        /* Process element node */
-        if (strcmp(name, "device") == 0) {
-            err = __osinfoProcessDevice(db, reader);
-            if (err != 0)
-                goto cleanup_error;
-        }
-        else if (strcmp(name, "hypervisor") == 0) {
-            err = __osinfoProcessHypervisor(db, reader);
-            if (err != 0)
-                goto cleanup_error;
-        }
-        else if (strcmp(name, "os") == 0) {
-            err = __osinfoProcessOs(db, reader);
-            if (err != 0)
-                goto cleanup_error;
-        }
-        else {
-            err = -EINVAL;
-            goto cleanup_error;
-        }
-    }
-
-    /* And we are done, successfully */
-    return 0;
-
-cleanup_error:
-    // Db will be unsatisfactorily initiated, caller will call unref to clean it
-    return err;
-}
-
-static int __osinfoReadDataFile(OsinfoDb *db,
-                                const char *dir,
-                                const char *filename)
-{
-    int ret;
-    xmlTextReaderPtr reader;
-    char *rel_name = malloc (strlen(dir) + 1 + strlen(filename) + 1);
-    if (!rel_name)
-      return -errno;
-
-    stpcpy(stpcpy(stpcpy(rel_name, dir), "/"), filename);
-
-    reader = xmlReaderForFile(rel_name, NULL, 0);
-    free(rel_name);
-    if (!reader) {
-        return -EINVAL;
-    }
-    ret = __osinfoProcessFile(db, reader);
-    xmlFreeTextReader(reader);
-    return ret;
-}
-
-int __osinfoInitializeData(OsinfoDb *db)
-{
-    int ret;
-    DIR* dir;
-    struct dirent *dp;
-
-    char *backingDir;
-    g_object_get(G_OBJECT(db), "backing-dir", &backingDir, NULL);
-
-    /* Initialize library and check version */
-    LIBXML_TEST_VERSION
-
-    /* Get directory with backing data. Defaults to CWD */
-    if (!backingDir)
-      backingDir = ".";
-
-    /* Get XML files in directory */
-    dir = opendir(backingDir);
-    if (!dir) {
-        ret = errno;
-        goto cleanup;
-    }
-
-    while ((dp=readdir(dir)) != NULL) {
-        if (dp->d_type != DT_REG)
-            continue;
-        ret = __osinfoReadDataFile(db, backingDir, dp->d_name);
-        if (ret != 0)
-            break;
-    }
-    closedir(dir);
-    if (ret == 0)
-        ret = __osinfoFixObjLinks(db);
-
-cleanup:
-    xmlCleanupParser();
-    g_free(backingDir);
-    return ret;
-}
-
-#else
-int __osinfoInitializeData(OsinfoDb *db)
-{
-    return -ENOSYS;
-}
-#endif
diff --git a/src/osinfo_db.c b/src/osinfo_db.c
deleted file mode 100644
index f78d241..0000000
--- a/src/osinfo_db.c
+++ /dev/null
@@ -1,555 +0,0 @@
-#include <osinfo.h>
-
-G_DEFINE_TYPE (OsinfoDb, osinfo_db, G_TYPE_OBJECT);
-
-#define OSINFO_DB_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), OSINFO_TYPE_DB, OsinfoDbPrivate))
-
-static void osinfo_db_set_property(GObject * object, guint prop_id,
-                                         const GValue * value,
-                                         GParamSpec * pspec);
-static void osinfo_db_get_property(GObject * object, guint prop_id,
-                                         GValue * value,
-                                         GParamSpec * pspec);
-static void osinfo_db_finalize (GObject *object);
-
-enum OSI_DB_PROPERTIES {
-    OSI_DB_PROP_0,
-
-    OSI_DB_BACKING_DIR,
-    OSI_DB_LIBVIRT_VER,
-    OSI_DB_ERROR
-};
-
-static void
-osinfo_db_finalize (GObject *object)
-{
-    OsinfoDb *self = OSINFO_DB (object);
-
-    g_free (self->priv->backing_dir);
-    g_free (self->priv->libvirt_ver);
-
-    g_tree_destroy(self->priv->devices);
-    g_tree_destroy(self->priv->hypervisors);
-    g_tree_destroy(self->priv->oses);
-
-    /* Chain up to the parent class */
-    G_OBJECT_CLASS (osinfo_db_parent_class)->finalize (object);
-}
-
-static void
-osinfo_db_set_property (GObject      *object,
-                        guint         property_id,
-                        const GValue *value,
-                        GParamSpec   *pspec)
-{
-    OsinfoDb *self = OSINFO_DB (object);
-
-    switch (property_id)
-      {
-      case OSI_DB_BACKING_DIR:
-        g_free(self->priv->backing_dir);
-        self->priv->backing_dir = g_value_dup_string (value);
-        break;
-
-      case OSI_DB_LIBVIRT_VER:
-        g_free(self->priv->libvirt_ver);
-        self->priv->libvirt_ver = g_value_dup_string (value);
-        break;
-
-      case OSI_DB_ERROR:
-        break;
-
-      default:
-        /* We don't have any other property... */
-        G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
-        break;
-      }
-}
-
-static void
-osinfo_db_get_property (GObject    *object,
-                        guint       property_id,
-                        GValue     *value,
-                        GParamSpec *pspec)
-{
-    OsinfoDb *self = OSINFO_DB (object);
-
-    switch (property_id)
-      {
-      case OSI_DB_BACKING_DIR:
-        g_value_set_string (value, self->priv->backing_dir);
-        break;
-
-      case OSI_DB_LIBVIRT_VER:
-        g_value_set_string (value, self->priv->libvirt_ver);
-        break;
-
-      case OSI_DB_ERROR:
-        g_value_set_pointer(value, self->priv->error);
-        break;
-
-      default:
-        /* We don't have any other property... */
-        G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
-        break;
-      }
-}
-
-/* Init functions */
-static void
-osinfo_db_class_init (OsinfoDbClass *klass)
-{
-    GObjectClass *g_klass = G_OBJECT_CLASS (klass);
-    GParamSpec *pspec;
-
-    g_klass->set_property = osinfo_db_set_property;
-    g_klass->get_property = osinfo_db_get_property;
-    g_klass->finalize = osinfo_db_finalize;
-
-    pspec = g_param_spec_string ("backing-dir",
-                                 "Backing directory",
-                                 "Contains backing data store.",
-                                 NULL /* default value */,
-                                 G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE);
-    g_object_class_install_property (g_klass,
-                                     OSI_DB_BACKING_DIR,
-                                     pspec);
-
-    pspec = g_param_spec_string ("libvirt-ver",
-                                 "Libvirt version",
-                                 "Libvirt version user is interested in",
-                                 NULL /* default value */,
-                                 G_PARAM_READWRITE);
-    g_object_class_install_property (g_klass,
-                                     OSI_DB_LIBVIRT_VER,
-                                     pspec);
-
-    pspec = g_param_spec_pointer ("error",
-                                  "Error",
-                                  "GError object for db",
-                                  G_PARAM_READABLE);
-    g_object_class_install_property (g_klass,
-                                     OSI_DB_ERROR,
-                                     pspec);
-
-    g_type_class_add_private (klass, sizeof (OsinfoDbPrivate));
-}
-
-
-static void
-osinfo_db_init (OsinfoDb *self)
-{
-    OsinfoDbPrivate *priv;
-    int ret;
-    self->priv = priv = OSINFO_DB_GET_PRIVATE(self);
-
-    self->priv->devices = g_tree_new_full(__osinfoStringCompare, NULL, g_free, g_object_unref);
-    self->priv->hypervisors = g_tree_new_full(__osinfoStringCompare, NULL, g_free, g_object_unref);
-    self->priv->oses = g_tree_new_full(__osinfoStringCompare, NULL, g_free, g_object_unref);
-
-    self->priv->error = NULL;
-    self->priv->ready = 0;
-}
-
-/** PUBLIC METHODS */
-
-int osinfoInitializeDb(OsinfoDb *self, GError **err)
-{
-    int ret;
-    // And now read in data.
-    ret = __osinfoInitializeData(self);
-    if (ret != 0) {
-        self->priv->ready = 0;
-        g_set_error_literal(err, g_quark_from_static_string("libosinfo"), ret, "Error during reading data");
-    }
-    else
-        self->priv->ready = 1;
-    return ret;
-}
-
-OsinfoHypervisor *osinfoGetHypervisorById(OsinfoDb *self, gchar *id, GError **err)
-{
-    if (!__osinfoCheckGErrorParamValid(err))
-        return NULL;
-
-    if (!OSINFO_IS_DB(self)) {
-        g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -EINVAL, OSINFO_OBJ_NOT_DB);
-        return NULL;
-    }
-
-    if (!id) {
-        g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -EINVAL, OSINFO_NO_ID);
-        return NULL;
-    }
-
-    return g_tree_lookup(self->priv->hypervisors, id);
-}
-
-OsinfoDevice *osinfoGetDeviceById(OsinfoDb *self, gchar *id, GError **err)
-{
-    if (!__osinfoCheckGErrorParamValid(err))
-        return NULL;
-
-    if (!OSINFO_IS_DB(self)) {
-        g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -EINVAL, OSINFO_OBJ_NOT_DB);
-        return NULL;
-    }
-
-    if (!id) {
-        g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -EINVAL, OSINFO_NO_ID);
-        return NULL;
-    }
-
-    return g_tree_lookup(self->priv->devices, id);
-}
-
-OsinfoOs *osinfoGetOsById(OsinfoDb *self, gchar *id, GError **err)
-{
-    if (!__osinfoCheckGErrorParamValid(err))
-        return NULL;
-
-    if (!OSINFO_IS_DB(self)) {
-        g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -EINVAL, OSINFO_OBJ_NOT_DB);
-        return NULL;
-    }
-
-    if (!id) {
-        g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -EINVAL, OSINFO_NO_ID);
-        return NULL;
-    }
-
-    return g_tree_lookup(self->priv->oses, id);
-}
-
-static gboolean __osinfoFilteredAddToList(gpointer key, gpointer value, gpointer data)
-{
-    struct __osinfoPopulateListArgs *args;
-    args = (struct __osinfoPopulateListArgs *) data;
-    OsinfoFilter *filter = args->filter;
-    OsinfoList *list = args->list;
-    GError **err = args->err;
-
-    // Key is string ID, value is pointer to entity
-    OsinfoEntity *entity = (OsinfoEntity *) value;
-    if (__osinfoEntityPassesFilter(filter, entity)) {
-        __osinfoListAdd(list, entity);
-    }
-
-    args->errcode = 0;
-
-    return FALSE; // continue iteration
-}
-
-static int __osinfoPopulateList(GTree *entities, OsinfoList *newList, OsinfoFilter *filter, GError **err)
-{
-    struct __osinfoPopulateListArgs args = {err, 0, filter, newList};
-    g_tree_foreach(entities, __osinfoFilteredAddToList, &args);
-    return args.errcode;
-}
-
-OsinfoOsList *osinfoGetOsList(OsinfoDb *self, OsinfoFilter *filter, GError **err)
-{
-    if (!__osinfoCheckGErrorParamValid(err))
-        return NULL;
-
-    if (!OSINFO_IS_DB(self)) {
-        g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -EINVAL, OSINFO_OBJ_NOT_DB);
-        return NULL;
-    }
-
-    if (filter && !OSINFO_IS_FILTER(filter)) {
-        g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -EINVAL, OSINFO_OBJ_NOT_FILTER);
-        return NULL;
-    }
-
-    // Create list
-    OsinfoOsList *newList = g_object_new(OSINFO_TYPE_OSLIST, NULL);
-    if (!newList) {
-        g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -ENOMEM, OSINFO_NO_MEM);
-        return NULL;
-    }
-
-    int ret;
-    ret = __osinfoPopulateList(self->priv->oses, OSINFO_LIST (newList), filter, err);
-    if (ret != 0) {
-        g_object_unref(newList);
-        g_set_error_literal(err, g_quark_from_static_string("libosinfo"), ret, __osinfoErrorToString(ret));
-        return NULL;
-    }
-
-    return newList;
-}
-
-OsinfoHypervisorList *osinfoGetHypervisorList(OsinfoDb *self, OsinfoFilter *filter, GError **err)
-{
-    if (!OSINFO_IS_DB(self)) {
-        g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -EINVAL, OSINFO_OBJ_NOT_DB);
-        return NULL;
-    }
-
-    if (filter && !OSINFO_IS_FILTER(filter)) {
-        g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -EINVAL, OSINFO_OBJ_NOT_FILTER);
-        return NULL;
-    }
-
-    // Create list
-    OsinfoHypervisorList *newList = g_object_new(OSINFO_TYPE_HYPERVISORLIST, NULL);
-    if (!newList) {
-        g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -ENOMEM, OSINFO_NO_MEM);
-        return NULL;
-    }
-
-    int ret;
-    ret = __osinfoPopulateList(self->priv->hypervisors, OSINFO_LIST (newList), filter, err);
-    if (ret != 0) {
-        g_object_unref(newList);
-        g_set_error_literal(err, g_quark_from_static_string("libosinfo"), ret, __osinfoErrorToString(ret));
-        return NULL;
-    }
-
-    return newList;
-}
-
-OsinfoDeviceList *osinfoGetDeviceList(OsinfoDb *self, OsinfoFilter *filter, GError **err)
-{
-    if (!OSINFO_IS_DB(self)) {
-        g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -EINVAL, OSINFO_OBJ_NOT_DB);
-        return NULL;
-    }
-
-    if (filter && !OSINFO_IS_FILTER(filter)) {
-        g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -EINVAL, OSINFO_OBJ_NOT_FILTER);
-        return NULL;
-    }
-
-    // Create list
-    OsinfoDeviceList *newList = g_object_new(OSINFO_TYPE_DEVICELIST, NULL);
-    if (!newList) {
-        g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -ENOMEM, OSINFO_NO_MEM);
-        return NULL;
-    }
-
-    int ret;
-    ret = __osinfoPopulateList(self->priv->devices, OSINFO_LIST (newList), filter, err);
-    if (ret != 0) {
-        g_object_unref(newList);
-        g_set_error_literal(err, g_quark_from_static_string("libosinfo"), ret, __osinfoErrorToString(ret));
-        return NULL;
-    }
-
-    return newList;
-}
-
-gboolean __osinfoGetPropertyValuesInEntity(gpointer key, gpointer value, gpointer data)
-{
-    struct __osinfoPopulateValuesArgs *args;
-    args = (struct __osinfoPopulateValuesArgs *) data;
-    GTree *values = args->values;
-    GError **err = args->err;
-    gchar *property = args->property;
-
-    OsinfoEntity *entity = OSINFO_ENTITY (value);
-    GPtrArray *valueArray = NULL;
-
-    valueArray = g_tree_lookup(entity->priv->params, property);
-    if (valueArray)
-        return FALSE; // No values here, skip
-
-    int i;
-    for (i = 0; i < valueArray->len; i++) {
-        gchar *currValue = g_ptr_array_index(valueArray, i);
-        void *test = g_tree_lookup(values, currValue);
-        if (test)
-            continue;
-        gchar *dupValue = g_strdup(currValue);
-        if (!dupValue) {
-            g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -ENOMEM, OSINFO_NO_MEM);
-            args->errcode = -ENOMEM;
-            return TRUE;
-        }
-
-        // Add to tree with dummy value
-        g_tree_insert(values, dupValue, (gpointer) 1);
-    }
-
-    return FALSE; // Continue iterating
-}
-
-static gboolean __osinfoPutKeysInList(gpointer key, gpointer value, gpointer data)
-{
-    gchar *currValue = (gchar *) key;
-    GPtrArray *valuesList = (GPtrArray *) data;
-
-    g_ptr_array_add(valuesList, currValue);
-    return FALSE; // keep iterating
-}
-
-static gboolean __osinfoFreeKeys(gpointer key, gpointer value, gpointer data)
-{
-    g_free(key);
-    return FALSE; // keep iterating
-}
-
-static GPtrArray *__osinfoUniqueValuesForPropertyInEntity(GTree *entities, gchar *propName, GError **err)
-{
-    GTree *values = g_tree_new(__osinfoStringCompareBase);
-    if (!values) {
-        g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -ENOMEM, OSINFO_NO_MEM);
-        return NULL;
-    }
-
-    struct __osinfoPopulateValuesArgs args = {err, 0, values, propName};
-    g_tree_foreach(entities, __osinfoGetPropertyValuesInEntity, &args);
-
-    if (args.errcode != 0) {
-        g_set_error_literal(err, g_quark_from_static_string("libosinfo"), args.errcode, __osinfoErrorToString(args.errcode));
-        g_tree_foreach(values, __osinfoFreeKeys, NULL);
-        g_tree_destroy(values);
-        return NULL;
-    }
-
-    // For each key in tree, add to gptrarray
-    GPtrArray *valuesList = g_ptr_array_sized_new(g_tree_nnodes(values));
-    if (!valuesList) {
-        g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -ENOMEM, OSINFO_NO_MEM);
-        g_tree_foreach(values, __osinfoFreeKeys, NULL);
-        g_tree_destroy(values);
-        return NULL;
-    }
-
-    g_tree_foreach(values, __osinfoPutKeysInList, valuesList);
-    g_tree_destroy(values);
-    return valuesList;
-}
-
-// Get me all unique values for property "vendor" among operating systems
-GPtrArray *osinfoUniqueValuesForPropertyInOs(OsinfoDb *self, gchar *propName, GError **err)
-{
-    if (!__osinfoCheckGErrorParamValid(err))
-        return NULL;
-
-    if (!OSINFO_IS_DB(self)) {
-        g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -EINVAL, OSINFO_OBJ_NOT_DB);
-        return NULL;
-    }
-
-    if (!propName) {
-        g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -EINVAL, OSINFO_NO_PROPNAME);
-        return NULL;
-    }
-
-    return __osinfoUniqueValuesForPropertyInEntity(self->priv->oses, propName, err);
-}
-
-// Get me all unique values for property "vendor" among hypervisors
-GPtrArray *osinfoUniqueValuesForPropertyInHv(OsinfoDb *self, gchar *propName, GError **err)
-{
-    if (!__osinfoCheckGErrorParamValid(err))
-        return NULL;
-
-    if (!OSINFO_IS_DB(self)) {
-        g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -EINVAL, OSINFO_OBJ_NOT_DB);
-        return NULL;
-    }
-
-    if (!propName) {
-        g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -EINVAL, OSINFO_NO_PROPNAME);
-        return NULL;
-    }
-
-    return __osinfoUniqueValuesForPropertyInEntity(self->priv->hypervisors, propName, err);
-}
-
-// Get me all unique values for property "vendor" among devices
-GPtrArray *osinfoUniqueValuesForPropertyInDev(OsinfoDb *self, gchar *propName, GError **err)
-{
-    if (!__osinfoCheckGErrorParamValid(err))
-        return NULL;
-
-    if (!OSINFO_IS_DB(self)) {
-        g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -EINVAL, OSINFO_OBJ_NOT_DB);
-        return NULL;
-    }
-
-    if (!propName) {
-        g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -EINVAL, OSINFO_NO_PROPNAME);
-        return NULL;
-    }
-
-    return __osinfoUniqueValuesForPropertyInEntity(self->priv->devices, propName, err);
-}
-
-static gboolean __osinfoAddOsIfRelationship(gpointer key, gpointer value, gpointer data)
-{
-    OsinfoOs *os = (OsinfoOs *) value;
-    struct __osinfoOsCheckRelationshipArgs *args;
-    args = (struct __osinfoOsCheckRelationshipArgs *) data;
-    GError **err = args->err;
-    OsinfoList *list = args->list;
-
-    GPtrArray *relatedOses = NULL;
-    relatedOses = g_tree_lookup(os->priv->relationshipsByType, (gpointer) args->relshp);
-    if (relatedOses) {
-        __osinfoListAdd(list, OSINFO_ENTITY (os));
-    }
-
-    return FALSE;
-}
-
-// Get me all OSes that 'upgrade' another OS (or whatever relationship is specified)
-OsinfoOsList *osinfoUniqueValuesForOsRelationship(OsinfoDb *self, osinfoRelationship relshp, GError **err)
-{
-    if (!__osinfoCheckGErrorParamValid(err))
-        return NULL;
-
-    if (!OSINFO_IS_DB(self)) {
-        g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -EINVAL, OSINFO_OBJ_NOT_DB);
-        return NULL;
-    }
-
-    if (!__osinfoCheckRelationshipValid(relshp)) {
-        g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -EINVAL, OSINFO_INVALID_RELATIONSHIP);
-        return NULL;
-    }
-
-    // Create list
-    OsinfoOsList *newList = g_object_new(OSINFO_TYPE_OSLIST, NULL);
-    if (!newList) {
-        g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -ENOMEM, OSINFO_NO_MEM);
-        return NULL;
-    }
-
-    struct __osinfoOsCheckRelationshipArgs args = {OSINFO_LIST (newList), 0, err, relshp};
-
-    g_tree_foreach(self->priv->oses, __osinfoAddOsIfRelationship, &args);
-    if (args.errcode != 0) {
-        g_set_error_literal(err, g_quark_from_static_string("libosinfo"), args.errcode, __osinfoErrorToString(args.errcode));
-        g_object_unref(newList);
-        return NULL;
-    }
-
-    return newList;
-}
-
-/**  PRIVATE */
-
-void __osinfoAddDeviceToDb(OsinfoDb *db, OsinfoDevice *dev)
-{
-    gchar *id;
-    g_object_get(G_OBJECT(dev), "id", &id, NULL);
-    g_tree_insert(db->priv->devices, id, dev);
-}
-
-void __osinfoAddHypervisorToDb(OsinfoDb *db, OsinfoHypervisor *hv)
-{
-    gchar *id;
-    g_object_get(G_OBJECT(hv), "id", &id, NULL);
-    g_tree_insert(db->priv->hypervisors, id, hv);
-}
-
-void __osinfoAddOsToDb(OsinfoDb *db, OsinfoOs *os)
-{
-    gchar *id;
-    g_object_get(G_OBJECT(os), "id", &id, NULL);
-    g_tree_insert(db->priv->oses, id, os);
-}
diff --git a/src/osinfo_device.c b/src/osinfo_device.c
deleted file mode 100644
index cae6f1b..0000000
--- a/src/osinfo_device.c
+++ /dev/null
@@ -1,94 +0,0 @@
-#include <osinfo.h>
-
-G_DEFINE_TYPE (OsinfoDevice, osinfo_device, OSINFO_TYPE_ENTITY);
-
-#define OSINFO_DEVICE_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), OSINFO_TYPE_DEVICE, OsinfoDevicePrivate))
-
-static void osinfo_device_finalize (GObject *object);
-
-static void
-osinfo_device_finalize (GObject *object)
-{
-    OsinfoDevice *self = OSINFO_DEVICE (object);
-
-    /* Chain up to the parent class */
-    G_OBJECT_CLASS (osinfo_device_parent_class)->finalize (object);
-}
-
-/* Init functions */
-static void
-osinfo_device_class_init (OsinfoDeviceClass *klass)
-{
-    GObjectClass *g_klass = G_OBJECT_CLASS (klass);
-
-    g_klass->finalize = osinfo_device_finalize;
-    g_type_class_add_private (klass, sizeof (OsinfoDevicePrivate));
-}
-
-static void
-osinfo_device_init (OsinfoDevice *self)
-{
-    OsinfoDevicePrivate *priv;
-    self->priv = priv = OSINFO_DEVICE_GET_PRIVATE(self);
-}
-
-gchar *osinfoGetDeviceDriver(OsinfoDevice *self,
-                             gchar *devType,
-                             OsinfoOs *os,
-                             OsinfoHypervisor *hv,
-                             GError **err)
-{
-    if (!__osinfoCheckGErrorParamValid(err))
-        return NULL;
-
-    if (!OSINFO_IS_DEVICE(self)) {
-        g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -EINVAL, OSINFO_OBJ_NOT_DEVICE);
-        return NULL;
-    }
-
-    if (!OSINFO_IS_OS(os)) {
-        g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -EINVAL, OSINFO_OBJ_NOT_OS);
-        return NULL;
-    }
-
-    if (!OSINFO_IS_HYPERVISOR(hv)) {
-        g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -EINVAL, OSINFO_OBJ_NOT_HV);
-        return NULL;
-    }
-
-    if (!devType) {
-        g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -EINVAL, OSINFO_NO_DEVTYPE);
-        return NULL;
-    }
-
-    gchar *driver = NULL;
-
-    // For os, get hypervisor specific info. If not present, return NULL.
-    struct __osinfoHvSection *hvSection = NULL;
-    hvSection = g_tree_lookup(os->priv->hypervisors, (OSINFO_ENTITY(hv))->priv->id);
-    if (!hvSection)
-        return NULL;
-
-    // Check for info for type of devices in <os,hv>. If not found, return NULL.
-    GTree *section = NULL;
-    section = g_tree_lookup(hvSection->sections, devType);
-    if (!section)
-        return NULL;
-
-    // Check device section for device. If not found, return NULL.
-    struct __osinfoDeviceLink *deviceLink = NULL;
-    deviceLink = g_tree_lookup(section, (OSINFO_ENTITY(self))->priv->id);
-    if (!deviceLink)
-        return NULL;
-
-    if (!deviceLink->driver)
-        return NULL;
-
-    driver = g_strdup(deviceLink->driver);
-    if (!driver) {
-        g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -ENOMEM, OSINFO_NO_MEM);
-        return NULL;
-    }
-
-    return driver;
-}
diff --git a/src/osinfo_devicelist.c b/src/osinfo_devicelist.c
deleted file mode 100644
index db8a059..0000000
--- a/src/osinfo_devicelist.c
+++ /dev/null
@@ -1,121 +0,0 @@
-#include <osinfo.h>
-
-G_DEFINE_TYPE (OsinfoDeviceList, osinfo_devicelist, OSINFO_TYPE_LIST);
-
-#define OSINFO_DEVICELIST_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), OSINFO_TYPE_DEVICELIST, OsinfoDeviceListPrivate))
-
-static void osinfo_devicelist_finalize (GObject *object);
-
-struct _OsinfoDeviceListPrivate
-{
-    int tmp;
-};
-
-static void
-osinfo_devicelist_finalize (GObject *object)
-{
-    /* Chain up to the parent class */
-    G_OBJECT_CLASS (osinfo_devicelist_parent_class)->finalize (object);
-}
-
-/* Init functions */
-static void
-osinfo_devicelist_class_init (OsinfoDeviceListClass *klass)
-{
-    GObjectClass *g_klass = G_OBJECT_CLASS (klass);
-
-    g_klass->finalize = osinfo_devicelist_finalize;
-    g_type_class_add_private (klass, sizeof (OsinfoDeviceListPrivate));
-}
-
-static void
-osinfo_devicelist_init (OsinfoDeviceList *self)
-{
-    OsinfoDeviceListPrivate *priv;
-    self->priv = priv = OSINFO_DEVICELIST_GET_PRIVATE(self);
-
-}
-
-OsinfoDevice *osinfoGetDeviceAtIndex(OsinfoDeviceList *self, gint idx, GError **err)
-{
-    if (!OSINFO_IS_DEVICELIST(self)) {
-        g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -EINVAL, OSINFO_OBJ_NOT_DEVICELIST);
-        return NULL;
-    }
-
-    OsinfoList *selfAsList = OSINFO_LIST (self);
-    OsinfoEntity *entity = osinfoGetEntityAtIndex(selfAsList, idx);
-    return OSINFO_DEVICE (entity);
-}
-
-OsinfoDeviceList *osinfoDeviceListFilter(OsinfoDeviceList *self, OsinfoFilter *filter, GError **err)
-{
-    if (!OSINFO_IS_DEVICELIST(self)) {
-        g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -EINVAL, OSINFO_OBJ_NOT_DEVICELIST);
-        return NULL;
-    }
-
-    if (filter && !OSINFO_IS_FILTER(filter)) {
-        g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -EINVAL, OSINFO_OBJ_NOT_FILTER);
-        return NULL;
-    }
-
-    // For each element in self, if passes filter, add to new list.
-    OsinfoDeviceList *newList = g_object_new(OSINFO_TYPE_DEVICELIST, NULL);
-    if (!newList) {
-        g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -ENOMEM, OSINFO_NO_MEM);
-        return NULL;
-    }
-
-    __osinfoDoFilter(OSINFO_LIST (self), OSINFO_LIST (newList), filter);
-    return newList;
-}
-
-OsinfoDeviceList *osinfoDeviceListIntersect(OsinfoDeviceList *self, OsinfoDeviceList *otherList, GError **err)
-{
-    if (!OSINFO_IS_DEVICELIST(self) || !OSINFO_IS_DEVICELIST(otherList)) {
-        g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -EINVAL, OSINFO_OBJ_NOT_DEVICELIST);
-        return NULL;
-    }
-
-    OsinfoDeviceList *newList = g_object_new(OSINFO_TYPE_DEVICELIST, NULL);
-    if (!newList) {
-        g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -ENOMEM, OSINFO_NO_MEM);
-        return NULL;
-    }
-
-    int ret;
-
-    ret = __osinfoDoIntersect(self, otherList, newList);
-    if (ret != 0) {
-        g_object_unref(newList);
-        g_set_error_literal(err, g_quark_from_static_string("libosinfo"), ret, __osinfoErrorToString(ret));
-        return NULL;
-    }
-
-    return newList;
-}
-
-OsinfoDeviceList *osinfoDeviceListUnion(OsinfoDeviceList *self, OsinfoDeviceList *otherList, GError **err)
-{
-    if (!OSINFO_IS_DEVICELIST(self) || !OSINFO_IS_DEVICELIST(otherList)) {
-        g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -EINVAL, OSINFO_OBJ_NOT_DEVICELIST);
-        return NULL;
-    }
-
-    OsinfoDeviceList *newList = g_object_new(OSINFO_TYPE_DEVICELIST, NULL);
-    if (!newList) {
-        g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -ENOMEM, OSINFO_NO_MEM);
-        return NULL;
-    }
-
-    int ret;
-    ret = __osinfoDoUnion(self, otherList, newList);
-    if (ret != 0) {
-        g_object_unref(newList);
-        g_set_error_literal(err, g_quark_from_static_string("libosinfo"), ret, __osinfoErrorToString(ret));
-        return NULL;
-    }
-
-    return newList;
-}
diff --git a/src/osinfo_entity.c b/src/osinfo_entity.c
deleted file mode 100644
index f052277..0000000
--- a/src/osinfo_entity.c
+++ /dev/null
@@ -1,321 +0,0 @@
-#include <osinfo.h>
-
-G_DEFINE_ABSTRACT_TYPE (OsinfoEntity, osinfo_entity, G_TYPE_OBJECT);
-
-#define OSINFO_ENTITY_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), OSINFO_TYPE_ENTITY, OsinfoEntityPrivate))
-
-static void osinfo_entity_finalize (GObject *object);
-
-enum OSI_ENTITY_PROPERTIES {
-    OSI_ENTITY_PROP_0,
-
-    OSI_ENTITY_ID,
-    OSI_DB_PTR
-};
-
-static void
-osinfo_entity_set_property (GObject      *object,
-                            guint         property_id,
-                            const GValue *value,
-                            GParamSpec   *pspec)
-{
-    OsinfoEntity *self = OSINFO_ENTITY (object);
-
-    switch (property_id)
-      {
-      case OSI_ENTITY_ID:
-        g_free(self->priv->id);
-        self->priv->id = g_value_dup_string (value);
-        break;
-      case OSI_DB_PTR:
-        self->priv->db = g_value_get_pointer (value);
-        break;
-      default:
-        /* We don't have any other property... */
-        G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
-        break;
-      }
-}
-
-static void
-osinfo_entity_get_property (GObject    *object,
-                            guint       property_id,
-                            GValue     *value,
-                            GParamSpec *pspec)
-{
-    OsinfoEntity *self = OSINFO_ENTITY (object);
-
-    switch (property_id)
-      {
-      case OSI_ENTITY_ID:
-        g_value_set_string (value, self->priv->id);
-        break;
-      case OSI_DB_PTR:
-        g_value_set_pointer(value, self->priv->db);
-        break;
-      default:
-        /* We don't have any other property... */
-        G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
-        break;
-      }
-}
-
-static void
-osinfo_entity_finalize (GObject *object)
-{
-    OsinfoEntity *self = OSINFO_ENTITY (object);
-
-    g_free (self->priv->id);
-    g_tree_destroy (self->priv->params);
-
-    /* Chain up to the parent class */
-    G_OBJECT_CLASS (osinfo_entity_parent_class)->finalize (object);
-}
-
-/* Init functions */
-static void
-osinfo_entity_class_init (OsinfoEntityClass *klass)
-{
-    GObjectClass *g_klass = G_OBJECT_CLASS (klass);
-    GParamSpec *pspec;
-
-    g_klass->set_property = osinfo_entity_set_property;
-    g_klass->get_property = osinfo_entity_get_property;
-
-    pspec = g_param_spec_string ("id",
-                                 "ID",
-                                 "Contains unique identifier for entity.",
-                                 NULL /* default value */,
-                                 G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE);
-    g_object_class_install_property (g_klass,
-                                     OSI_ENTITY_ID,
-                                     pspec);
-    pspec = g_param_spec_pointer ("db",
-                                 "Db pointer",
-                                 "Contains backpointer to libosinfo db object.",
-                                 G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE);
-    g_object_class_install_property (g_klass,
-                                     OSI_DB_PTR,
-                                     pspec);
-
-    g_klass->finalize = osinfo_entity_finalize;
-    g_type_class_add_private (klass, sizeof (OsinfoEntityPrivate));
-}
-
-static void
-osinfo_entity_init (OsinfoEntity *self)
-{
-    OsinfoEntityPrivate *priv;
-    self->priv = priv = OSINFO_ENTITY_GET_PRIVATE(self);
-
-    self->priv->params = g_tree_new_full(__osinfoStringCompare, NULL, g_free, __osinfoFreeParamVals);
-}
-
-int __osinfoAddParam(OsinfoEntity *self, gchar *key, gchar *value)
-{
-    if (!OSINFO_IS_ENTITY(self) || !key || !value)
-        return -EINVAL;
-
-    // First check if there exists an existing array of entries for this key
-    // If not, create a ptrarray of strings for this key and insert into map
-    gboolean found;
-    gpointer origKey, foundValue;
-    GPtrArray *valueArray;
-    gchar *valueDup = NULL, *keyDup = NULL;
-
-    valueDup = g_strdup(value);
-
-    if (!valueDup)
-        goto error_free;
-
-    found = g_tree_lookup_extended(self->priv->params, key, &origKey, &foundValue);
-    if (!found) {
-        keyDup = g_strdup(key);
-        valueArray = g_ptr_array_new_with_free_func(g_free);
-
-        if (!valueArray)
-            goto error_free;
-        if (!keyDup) {
-            g_ptr_array_free(valueArray, TRUE);
-            goto error_free;
-        }
-
-        g_tree_insert(self->priv->params, keyDup, valueArray);
-    }
-    else
-        valueArray = (GPtrArray *) foundValue;
-
-    // Add a copy of the value to the array
-    g_ptr_array_add(valueArray, valueDup);
-    return 0;
-
-error_free:
-    g_free(keyDup);
-    g_free(valueDup);
-    return -ENOMEM;
-}
-
-void __osinfoClearParam(OsinfoEntity *self, gchar *key)
-{
-    g_tree_remove(self->priv->params, key);
-}
-
-gboolean __osinfoGetKeys(gpointer key, gpointer value, gpointer data)
-{
-    struct __osinfoPtrArrayErr *arrayErr = (struct __osinfoPtrArrayErr *) data;
-    GPtrArray *results = arrayErr->array;
-    gchar *keyDup = g_strdup(key);
-
-    if (!keyDup) {
-        arrayErr->err = -ENOMEM;
-        return TRUE;
-    }
-    g_ptr_array_add(results, keyDup);
-    return FALSE; // Continue iterating
-}
-
-void __osinfoDupArray(gpointer data, gpointer user_data)
-{
-    struct __osinfoPtrArrayErr *arrayErr = (struct __osinfoPtrArrayErr *) data;
-    GPtrArray *results = arrayErr->array;
-
-    if (arrayErr->err != 0)
-        return;
-
-    gchar *valueDup = g_strdup((gchar *)data);
-    if (!valueDup) {
-        arrayErr->err = -ENOMEM;
-        return;
-    }
-    g_ptr_array_add(results, valueDup);
-}
-
-gchar *osinfoGetId(OsinfoEntity *self, GError **err)
-{
-    if (!__osinfoCheckGErrorParamValid(err))
-        return NULL;
-
-    if (!OSINFO_IS_ENTITY(self)) {
-        g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -EINVAL, OSINFO_OBJ_NOT_ENTITY);
-        return NULL;
-    }
-
-    gchar *dupId = g_strdup(self->priv->id);
-    if (!dupId) {
-        g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -ENOMEM, OSINFO_NO_MEM);
-        return NULL;
-    }
-    return dupId;
-}
-
-GPtrArray *osinfoGetParams(OsinfoEntity *self, GError **err)
-{
-    if (!__osinfoCheckGErrorParamValid(err))
-        return NULL;
-
-    if (!OSINFO_IS_ENTITY(self)) {
-        g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -EINVAL, OSINFO_OBJ_NOT_ENTITY);
-        return NULL;
-    }
-
-    GPtrArray *params = g_ptr_array_new();
-    if (!params) {
-        g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -ENOMEM, OSINFO_NO_MEM);
-        return NULL;
-    }
-
-    struct __osinfoPtrArrayErr arrayErr = {params, 0};
-    g_tree_foreach(self->priv->params, __osinfoGetKeys, &arrayErr);
-
-    // If we had an error, cleanup and return NULL
-    if (arrayErr.err != 0) {
-        int i;
-        for (i = 0; i < params->len; i++)
-            g_free(g_ptr_array_index(params, i));
-        g_ptr_array_free(params, TRUE);
-        g_set_error_literal(err, g_quark_from_static_string("libosinfo"), arrayErr.err, __osinfoErrorToString(arrayErr.err));
-        return NULL;
-    }
-
-    return params;
-}
-
-gchar *osinfoGetParamValue(OsinfoEntity *self, gchar *key, GError **err)
-{
-    if (!__osinfoCheckGErrorParamValid(err))
-        return NULL;
-
-    if (!OSINFO_IS_ENTITY(self)) {
-        g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -EINVAL, OSINFO_OBJ_NOT_ENTITY);
-        return NULL;
-    }
-
-    if (!key) {
-        g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -EINVAL, OSINFO_NO_PROPNAME);
-        return NULL;
-    }
-
-    gboolean found;
-    gpointer origKey, value;
-    gchar *firstValueDup;
-    GPtrArray *array;
-
-    found = g_tree_lookup_extended(self->priv->params, key, &origKey, &value);
-    if (!found)
-        return NULL;
-    array = (GPtrArray *) value;
-    if (array->len == 0)
-        return NULL;
-
-    firstValueDup = g_strdup(g_ptr_array_index(array, 0));
-    if (!firstValueDup) {
-        g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -ENOMEM, OSINFO_NO_MEM);
-        return NULL;
-    }
-
-    return firstValueDup;
-}
-
-GPtrArray *osinfoGetParamAllValues(OsinfoEntity *self, gchar *key, GError **err)
-{
-    if (!__osinfoCheckGErrorParamValid(err))
-        return NULL;
-
-    if (!OSINFO_IS_ENTITY(self)) {
-        g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -EINVAL, OSINFO_OBJ_NOT_ENTITY);
-        return NULL;
-    }
-
-    if (!key) {
-        g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -EINVAL, OSINFO_NO_PROPNAME);
-        return NULL;
-    }
-
-    gboolean found;
-    gpointer origKey, value;
-    GPtrArray *srcArray, *retArray;
-
-    retArray = g_ptr_array_new();
-    if (!retArray) {
-        g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -ENOMEM, OSINFO_NO_MEM);
-        return NULL;
-    }
-
-    found = g_tree_lookup_extended(self->priv->params, key, &origKey, &value);
-    if (!found)
-        return retArray;
-    srcArray = (GPtrArray *) value;
-    if (srcArray->len == 0)
-        return retArray;
-
-    struct __osinfoPtrArrayErr arrayErr = {retArray, 0};
-    g_ptr_array_foreach(srcArray, __osinfoDupArray, &arrayErr);
-    if (arrayErr.err) {
-        g_set_error_literal(err, g_quark_from_static_string("libosinfo"), arrayErr.err, __osinfoErrorToString(arrayErr.err));
-        g_ptr_array_set_free_func(retArray, g_free);
-        g_ptr_array_free(retArray, TRUE);
-        return NULL;
-    }
-
-    return retArray;
-}
diff --git a/src/osinfo_filter.c b/src/osinfo_filter.c
deleted file mode 100644
index fe65e45..0000000
--- a/src/osinfo_filter.c
+++ /dev/null
@@ -1,298 +0,0 @@
-#include <osinfo.h>
-
-G_DEFINE_TYPE (OsinfoFilter, osinfo_filter, G_TYPE_OBJECT);
-
-#define OSINFO_FILTER_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), OSINFO_TYPE_FILTER, OsinfoFilterPrivate))
-
-static void osinfo_filter_finalize (GObject *object);
-
-static void
-osinfo_filter_finalize (GObject *object)
-{
-    OsinfoFilter *self = OSINFO_FILTER (object);
-
-    g_tree_destroy(self->priv->propertyConstraints);
-    g_tree_destroy(self->priv->relationshipConstraints);
-
-    /* Chain up to the parent class */
-    G_OBJECT_CLASS (osinfo_filter_parent_class)->finalize (object);
-}
-
-/* Init functions */
-static void
-osinfo_filter_class_init (OsinfoFilterClass *klass)
-{
-    GObjectClass *g_klass = G_OBJECT_CLASS (klass);
-
-    g_klass->finalize = osinfo_filter_finalize;
-    g_type_class_add_private (klass, sizeof (OsinfoFilterPrivate));
-}
-
-static void
-osinfo_filter_init (OsinfoFilter *self)
-{
-    OsinfoFilterPrivate *priv;
-    priv = OSINFO_FILTER_GET_PRIVATE(self);
-    self->priv = priv;
-
-    self->priv->propertyConstraints = g_tree_new_full(__osinfoStringCompare,
-                                                     NULL,
-                                                     g_free,
-                                                     __osinfoFreePtrArray);
-
-
-    self->priv->relationshipConstraints = g_tree_new_full(__osinfoIntCompare,
-                                                         NULL,
-                                                         NULL,
-                                                         __osinfoFreePtrArray);
-}
-
-void osinfoFreeFilter(OsinfoFilter *self)
-{
-    g_object_unref(self);
-}
-
-gint osinfoAddFilterConstraint(OsinfoFilter *self, gchar *propName, gchar *propVal, GError **err)
-{
-    if (!__osinfoCheckGErrorParamValid(err))
-        return -EINVAL;
-
-    if (!OSINFO_IS_FILTER(self)) {
-        g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -EINVAL, OSINFO_OBJ_NOT_FILTER);
-        return -EINVAL;
-    }
-
-    if (!propName) {
-        g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -EINVAL, OSINFO_NO_PROPNAME);
-        return -EINVAL;
-    }
-
-    if (!propVal) {
-        g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -EINVAL, OSINFO_NO_PROPVAL);
-        return -EINVAL;
-    }
-
-    // First check if there exists an array of entries for this key
-    // If not, create a ptrarray of strings for this key and insert into map
-    gboolean found;
-    gpointer origKey, foundValue;
-    GPtrArray *valueArray;
-    gchar *valueDup = NULL, *keyDup = NULL;
-
-    valueDup = g_strdup(propVal);
-
-    if (!valueDup)
-        goto error_free;
-
-    found = g_tree_lookup_extended(self->priv->propertyConstraints, propName, &origKey, &foundValue);
-    if (!found) {
-        keyDup = g_strdup(propName);
-        valueArray = g_ptr_array_new_with_free_func(g_free);
-
-        if (!valueArray)
-            goto error_free;
-        if (!keyDup) {
-            g_ptr_array_free(valueArray, TRUE);
-            goto error_free;
-        }
-
-        g_tree_insert(self->priv->propertyConstraints, keyDup, valueArray);
-    }
-    else
-        valueArray = (GPtrArray *) foundValue;
-
-    // Add a copy of the value to the array
-    g_ptr_array_add(valueArray, valueDup);
-    return 0;
-
-error_free:
-    g_free(keyDup);
-    g_free(valueDup);
-    g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -ENOMEM, OSINFO_NO_MEM);
-    return -ENOMEM;
-}
-
-// Only applicable to OSes, ignored by other types of objects
-gint osinfoAddRelationConstraint(OsinfoFilter *self, osinfoRelationship relshp, OsinfoOs *os, GError **err)
-{
-    if (!__osinfoCheckGErrorParamValid(err))
-        return -EINVAL;
-
-    if (!OSINFO_IS_FILTER(self)) {
-        g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -EINVAL, OSINFO_OBJ_NOT_FILTER);
-        return -EINVAL;
-    }
-
-    if (!__osinfoCheckRelationshipValid(relshp)) {
-        g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -EINVAL, OSINFO_INVALID_RELATIONSHIP);
-        return -EINVAL;
-    }
-
-    if (!OSINFO_IS_OS(os)) {
-        g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -EINVAL, OSINFO_OBJ_NOT_OS);
-        return -EINVAL;
-    }
-
-    // First check if there exists an array of entries for this key
-    // If not, create a ptrarray of strings for this key and insert into map
-    gboolean found;
-    gpointer origKey, foundValue;
-    GPtrArray *valueArray;
-
-    found = g_tree_lookup_extended(self->priv->relationshipConstraints, (gpointer) relshp, &origKey, &foundValue);
-    if (!found) {
-        valueArray = g_ptr_array_new();
-        if (!valueArray)
-            goto error_nomem;
-
-        g_tree_insert(self->priv->relationshipConstraints, (gpointer) relshp, valueArray);
-    }
-    else
-        valueArray = (GPtrArray *) foundValue;
-
-    // Add to the array
-    g_ptr_array_add(valueArray, os);
-    return 0;
-
-error_nomem:
-    g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -ENOMEM, OSINFO_NO_MEM);
-    return -ENOMEM;
-}
-
-void osinfoClearFilterConstraint(OsinfoFilter *self, gchar *propName)
-{
-    g_tree_remove(self->priv->propertyConstraints, propName);
-}
-
-void osinfoClearRelationshipConstraint(OsinfoFilter *self, osinfoRelationship relshp)
-{
-    g_tree_remove(self->priv->relationshipConstraints, (gpointer) relshp);
-}
-
-static gboolean __osinfoRemoveTreeEntry(gpointer key, gpointer value, gpointer data)
-{
-    GTree *tree = (GTree *) data;
-    g_tree_remove(tree, key);
-    return FALSE; // continue iterating
-}
-
-void osinfoClearAllFilterConstraints(OsinfoFilter *self)
-{
-    g_tree_foreach(self->priv->propertyConstraints, __osinfoRemoveTreeEntry, self->priv->propertyConstraints);
-    g_tree_foreach(self->priv->relationshipConstraints, __osinfoRemoveTreeEntry, self->priv->relationshipConstraints);
-}
-
-// get keyset for constraints map
-GPtrArray *osinfoGetFilterConstraintKeys(OsinfoFilter *self, GError **err)
-{
-    if (!__osinfoCheckGErrorParamValid(err))
-        return NULL;
-
-    if (!OSINFO_IS_FILTER(self)) {
-        g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -EINVAL, OSINFO_OBJ_NOT_FILTER);
-        return NULL;
-    }
-
-    GPtrArray *constraints = g_ptr_array_new();
-    if (!constraints) {
-        g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -ENOMEM, OSINFO_NO_MEM);
-        return NULL;
-    }
-
-    struct __osinfoPtrArrayErr arrayErr = {constraints, 0};
-    g_tree_foreach(self->priv->propertyConstraints, __osinfoGetKeys, &arrayErr);
-
-    // If we had an error, cleanup and return NULL
-    if (arrayErr.err != 0) {
-        int i;
-        for (i = 0; i < constraints->len; i++)
-            g_free(g_ptr_array_index(constraints, i));
-        g_ptr_array_free(constraints, TRUE);
-        g_set_error_literal(err, g_quark_from_static_string("libosinfo"), arrayErr.err, __osinfoErrorToString(arrayErr.err));
-        return NULL;
-    }
-
-    return constraints;
-}
-
-// get values for given key
-GPtrArray *osinfoGetFilterConstraintValues(OsinfoFilter *self, gchar *propName, GError **err)
-{
-    if (!__osinfoCheckGErrorParamValid(err))
-        return NULL;
-
-    if (!OSINFO_IS_FILTER(self)) {
-        g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -EINVAL, OSINFO_OBJ_NOT_FILTER);
-        return NULL;
-    }
-
-    if (!propName) {
-        g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -EINVAL, OSINFO_NO_PROPNAME);
-        return NULL;
-    }
-
-    gboolean found;
-    gpointer origKey, value;
-    GPtrArray *srcArray, *retArray;
-
-    retArray = g_ptr_array_new();
-    if (!retArray) {
-        g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -ENOMEM, OSINFO_NO_MEM);
-        return NULL;
-    }
-
-    found = g_tree_lookup_extended(self->priv->propertyConstraints, propName, &origKey, &value);
-    if (!found)
-        return retArray;
-    srcArray = (GPtrArray *) value;
-    if (srcArray->len == 0)
-        return retArray;
-
-    struct __osinfoPtrArrayErr arrayErr = {retArray, 0};
-    g_ptr_array_foreach(srcArray, __osinfoDupArray, &arrayErr);
-    if (arrayErr.err) {
-        g_set_error_literal(err, g_quark_from_static_string("libosinfo"), arrayErr.err, __osinfoErrorToString(arrayErr.err));
-        g_ptr_array_set_free_func(retArray, g_free);
-        g_ptr_array_free(retArray, TRUE);
-        return NULL;
-    }
-
-    return retArray;
-}
-
-// get oses for given relshp
-OsinfoOsList *osinfoGetRelationshipConstraintValue(OsinfoFilter *self, osinfoRelationship relshp, GError **err)
-{
-    if (!__osinfoCheckGErrorParamValid(err))
-        return NULL;
-
-    if (!OSINFO_IS_FILTER(self)) {
-        g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -EINVAL, OSINFO_OBJ_NOT_FILTER);
-        return NULL;
-    }
-
-    if (!__osinfoCheckRelationshipValid(relshp)) {
-        g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -EINVAL, OSINFO_INVALID_RELATIONSHIP);
-        return NULL;
-    }
-
-    // Create our list
-    OsinfoOsList *newList = g_object_new(OSINFO_TYPE_OSLIST, NULL);
-    if (!newList) {
-        g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -ENOMEM, OSINFO_NO_MEM);
-        return NULL;
-    }
-
-    GPtrArray *relatedOses = NULL;
-    relatedOses = g_tree_lookup(self->priv->relationshipConstraints, (gpointer) relshp);
-    if (relatedOses) {
-        int i, len;
-        len = relatedOses->len;
-        for (i = 0; i < len; i++) {
-             OsinfoOs *os = g_ptr_array_index(relatedOses, i);
-            __osinfoListAdd(OSINFO_LIST (newList), OSINFO_ENTITY (os));
-        }
-    }
-
-    return newList;
-}
diff --git a/src/osinfo_hypervisor.c b/src/osinfo_hypervisor.c
deleted file mode 100644
index 30eb445..0000000
--- a/src/osinfo_hypervisor.c
+++ /dev/null
@@ -1,122 +0,0 @@
-#include <osinfo.h>
-
-G_DEFINE_TYPE (OsinfoHypervisor, osinfo_hypervisor, OSINFO_TYPE_ENTITY);
-
-#define OSINFO_HYPERVISOR_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), OSINFO_TYPE_HYPERVISOR, OsinfoHypervisorPrivate))
-
-static void osinfo_hypervisor_finalize (GObject *object);
-
-static void
-osinfo_hypervisor_finalize (GObject *object)
-{
-    OsinfoHypervisor *self = OSINFO_HYPERVISOR (object);
-
-    g_tree_destroy (self->priv->sections);
-    g_tree_destroy (self->priv->sectionsAsList);
-
-    /* Chain up to the parent class */
-    G_OBJECT_CLASS (osinfo_hypervisor_parent_class)->finalize (object);
-}
-
-/* Init functions */
-static void
-osinfo_hypervisor_class_init (OsinfoHypervisorClass *klass)
-{
-    GObjectClass *g_klass = G_OBJECT_CLASS (klass);
-
-    g_klass->finalize = osinfo_hypervisor_finalize;
-    g_type_class_add_private (klass, sizeof (OsinfoHypervisorPrivate));
-}
-
-static void
-osinfo_hypervisor_init (OsinfoHypervisor *self)
-{
-    OsinfoHypervisorPrivate *priv;
-    self->priv = priv = OSINFO_HYPERVISOR_GET_PRIVATE(self);
-
-    self->priv->sections = g_tree_new_full(__osinfoStringCompare, NULL, g_free, __osinfoFreeDeviceSection);
-    self->priv->sectionsAsList = g_tree_new_full(__osinfoStringCompare, NULL, g_free, __osinfoFreePtrArray);
-}
-
-int __osinfoAddDeviceToSectionHv(OsinfoHypervisor *self, gchar *section, gchar *id, gchar *driver)
-{
-    if( !OSINFO_IS_HYPERVISOR(self) || !section || !id || !driver)
-        return -EINVAL;
-
-    return __osinfoAddDeviceToSection(self->priv->sections, self->priv->sectionsAsList, section, id, driver);
-}
-
-void __osinfoClearDeviceSectionHv(OsinfoHypervisor *self, gchar *section)
-{
-    if (!OSINFO_IS_HYPERVISOR(self) || !section)
-        return;
-
-    __osinfoClearDeviceSection(self->priv->sections, self->priv->sectionsAsList, section);
-}
-
-GPtrArray *osinfoGetHypervisorDeviceTypes(OsinfoHypervisor *self, GError **err)
-{
-    if (!__osinfoCheckGErrorParamValid(err))
-        return NULL;
-
-    if (!OSINFO_IS_HYPERVISOR(self)) {
-        g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -EINVAL, OSINFO_OBJ_NOT_HV);
-        return NULL;
-    }
-
-    GPtrArray *deviceTypes = g_ptr_array_sized_new(g_tree_nnodes(self->priv->sections));
-    if (!deviceTypes) {
-        g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -ENOMEM, OSINFO_NO_MEM);
-        return NULL;
-    }
-
-    // For each key in our tree of device sections, dup and add to the array
-    struct __osinfoPtrArrayErr arrayErr = {deviceTypes, 0};
-    g_tree_foreach(self->priv->sections, __osinfoGetKeys, &arrayErr);
-    return deviceTypes;
-}
-
-OsinfoDeviceList *osinfoGetHypervisorDevicesByType(OsinfoHypervisor *self, gchar *devType, OsinfoFilter *filter, GError **err)
-{
-    if (!__osinfoCheckGErrorParamValid(err))
-        return NULL;
-
-    if (!OSINFO_IS_HYPERVISOR(self)) {
-        g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -EINVAL, OSINFO_OBJ_NOT_HV);
-        return NULL;
-    }
-
-    if (filter && !OSINFO_IS_FILTER(filter)) {
-        g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -EINVAL, OSINFO_OBJ_NOT_FILTER);
-        return NULL;
-    }
-
-    if (!devType) {
-        g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -EINVAL, OSINFO_NO_DEVTYPE);
-        return NULL;
-    }
-
-    // Create our device list
-    OsinfoDeviceList *newList = g_object_new(OSINFO_TYPE_DEVICELIST, NULL);
-    if (!newList) {
-        g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -ENOMEM, OSINFO_NO_MEM);
-        return NULL;
-    }
-
-    // If section does not exist, return empty list
-    GPtrArray *sectionList = NULL;
-    sectionList = g_tree_lookup(self->priv->sectionsAsList, devType);
-    if (!sectionList)
-        return newList;
-
-    // For each device in section list, apply filter. If filter passes, add device to list.
-    int i;
-    struct __osinfoDeviceLink *deviceLink;
-    for (i = 0; i < sectionList->len; i++) {
-        deviceLink = g_ptr_array_index(sectionList, i);
-        if (__osinfoDevicePassesFilter(filter, deviceLink->dev))
-            __osinfoListAdd(OSINFO_LIST (newList), OSINFO_ENTITY (deviceLink->dev));
-    }
-
-    return newList;
-}
diff --git a/src/osinfo_hypervisorlist.c b/src/osinfo_hypervisorlist.c
deleted file mode 100644
index be42df7..0000000
--- a/src/osinfo_hypervisorlist.c
+++ /dev/null
@@ -1,121 +0,0 @@
-#include <osinfo.h>
-
-G_DEFINE_TYPE (OsinfoHypervisorList, osinfo_hypervisorlist, OSINFO_TYPE_LIST);
-
-#define OSINFO_HYPERVISORLIST_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), OSINFO_TYPE_HYPERVISORLIST, OsinfoHypervisorListPrivate))
-
-static void osinfo_hypervisorlist_finalize (GObject *object);
-
-struct _OsinfoHypervisorListPrivate
-{
-    int tmp;
-};
-
-static void
-osinfo_hypervisorlist_finalize (GObject *object)
-{
-    /* Chain up to the parent class */
-    G_OBJECT_CLASS (osinfo_hypervisorlist_parent_class)->finalize (object);
-}
-
-/* Init functions */
-static void
-osinfo_hypervisorlist_class_init (OsinfoHypervisorListClass *klass)
-{
-    GObjectClass *g_klass = G_OBJECT_CLASS (klass);
-
-    g_klass->finalize = osinfo_hypervisorlist_finalize;
-    g_type_class_add_private (klass, sizeof (OsinfoHypervisorListPrivate));
-}
-
-static void
-osinfo_hypervisorlist_init (OsinfoHypervisorList *self)
-{
-    OsinfoHypervisorListPrivate *priv;
-    self->priv = priv = OSINFO_HYPERVISORLIST_GET_PRIVATE(self);
-
-}
-
-OsinfoHypervisor *osinfoGetHypervisorAtIndex(OsinfoHypervisorList *self, gint idx, GError **err)
-{
-    if (!OSINFO_IS_HYPERVISORLIST(self)) {
-        g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -EINVAL, OSINFO_OBJ_NOT_HYPERVISORLIST);
-        return NULL;
-    }
-
-    OsinfoList *selfAsList = OSINFO_LIST (self);
-    OsinfoEntity *entity = osinfoGetEntityAtIndex(selfAsList, idx);
-    return OSINFO_HYPERVISOR (entity);
-}
-
-OsinfoHypervisorList *osinfoHypervisorListFilter(OsinfoHypervisorList *self, OsinfoFilter *filter, GError **err)
-{
-    if (!OSINFO_IS_HYPERVISORLIST(self)) {
-        g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -EINVAL, OSINFO_OBJ_NOT_HYPERVISORLIST);
-        return NULL;
-    }
-
-    if (filter && !OSINFO_IS_FILTER(self)) {
-        g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -EINVAL, OSINFO_OBJ_NOT_FILTER);
-        return NULL;
-    }
-
-    // For each element in self, if passes filter, add to new list.
-    OsinfoHypervisorList *newList = g_object_new(OSINFO_TYPE_HYPERVISORLIST, NULL);
-    if (!newList) {
-        g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -ENOMEM, OSINFO_NO_MEM);
-        return NULL;
-    }
-
-    __osinfoDoFilter(OSINFO_LIST (self), OSINFO_LIST (newList), filter);
-    return newList;
-}
-
-OsinfoHypervisorList *osinfoHypervisorListIntersect(OsinfoHypervisorList *self, OsinfoHypervisorList *otherList, GError **err)
-{
-    if (!OSINFO_IS_HYPERVISORLIST(self) || !OSINFO_IS_HYPERVISORLIST(otherList)) {
-        g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -EINVAL, OSINFO_OBJ_NOT_HYPERVISORLIST);
-        return NULL;
-    }
-
-    OsinfoHypervisorList *newList = g_object_new(OSINFO_TYPE_HYPERVISORLIST, NULL);
-    if (!newList) {
-        g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -ENOMEM, OSINFO_NO_MEM);
-        return NULL;
-    }
-
-    int ret;
-
-    ret = __osinfoDoIntersect(self, otherList, newList);
-    if (ret != 0) {
-        g_object_unref(newList);
-        g_set_error_literal(err, g_quark_from_static_string("libosinfo"), ret, __osinfoErrorToString(ret));
-        return NULL;
-    }
-
-    return newList;
-}
-
-OsinfoHypervisorList *osinfoHypervisorListUnion(OsinfoHypervisorList *self, OsinfoHypervisorList *otherList, GError **err)
-{
-    if (!OSINFO_IS_HYPERVISORLIST(self) || !OSINFO_IS_HYPERVISORLIST(otherList)) {
-        g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -EINVAL, OSINFO_OBJ_NOT_HYPERVISORLIST);
-        return NULL;
-    }
-
-    OsinfoHypervisorList *newList = g_object_new(OSINFO_TYPE_HYPERVISORLIST, NULL);
-    if (!newList) {
-        g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -ENOMEM, OSINFO_NO_MEM);
-        return NULL;
-    }
-
-    int ret;
-    ret = __osinfoDoUnion(self, otherList, newList);
-    if (ret != 0) {
-        g_object_unref(newList);
-        g_set_error_literal(err, g_quark_from_static_string("libosinfo"), ret, __osinfoErrorToString(ret));
-        return NULL;
-    }
-
-    return newList;
-}
diff --git a/src/osinfo_list.c b/src/osinfo_list.c
deleted file mode 100644
index 964e01d..0000000
--- a/src/osinfo_list.c
+++ /dev/null
@@ -1,219 +0,0 @@
-#include <osinfo.h>
-
-G_DEFINE_TYPE (OsinfoList, osinfo_list, G_TYPE_OBJECT);
-
-#define OSINFO_LIST_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), OSINFO_TYPE_LIST, OsinfoListPrivate))
-
-static void osinfo_list_finalize (GObject *object);
-
-struct _OsinfoListPrivate
-{
-    GPtrArray *array;
-};
-
-static void
-osinfo_list_finalize (GObject *object)
-{
-    OsinfoList *self = OSINFO_LIST (object);
-
-    g_ptr_array_free(self->priv->array, TRUE);
-
-    /* Chain up to the parent class */
-    G_OBJECT_CLASS (osinfo_list_parent_class)->finalize (object);
-}
-
-/* Init functions */
-static void
-osinfo_list_class_init (OsinfoListClass *klass)
-{
-    GObjectClass *g_klass = G_OBJECT_CLASS (klass);
-
-    g_klass->finalize = osinfo_list_finalize;
-    g_type_class_add_private (klass, sizeof (OsinfoListPrivate));
-}
-
-static void
-osinfo_list_init (OsinfoList *self)
-{
-    OsinfoListPrivate *priv;
-    self->priv = priv = OSINFO_LIST_GET_PRIVATE(self);
-
-    self->priv->array = g_ptr_array_new();
-}
-
-void osinfoFreeList(OsinfoList *self)
-{
-    g_object_unref(self);
-}
-
-gint osinfoListLength(OsinfoList *self)
-{
-    return self->priv->array->len;
-}
-
-OsinfoEntity *osinfoGetEntityAtIndex(OsinfoList *self, gint idx)
-{
-    return g_ptr_array_index(self->priv->array, idx);
-}
-
-void __osinfoListAdd(OsinfoList *self, OsinfoEntity *entity)
-{
-    g_ptr_array_add(self->priv->array, entity);
-}
-
-void __osinfoDoFilter(OsinfoList *src, OsinfoList *dst, OsinfoFilter *filter)
-{
-    int i, len;
-    len = osinfoListLength(src);
-    for (i = 0; i < len; i++) {
-        OsinfoEntity *entity = osinfoGetEntityAtIndex(src, i);
-        if (__osinfoEntityPassesFilter(filter, entity))
-            __osinfoListAdd(dst, entity);
-    }
-}
-
-OsinfoList *osinfoListFilter(OsinfoList *self, OsinfoFilter *filter, GError **err)
-{
-    if (!OSINFO_IS_LIST(self)) {
-        g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -EINVAL, OSINFO_OBJ_NOT_LIST);
-        return NULL;
-    }
-
-    if (filter && !OSINFO_IS_FILTER(filter)) {
-        g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -EINVAL, OSINFO_OBJ_NOT_FILTER);
-        return NULL;
-    }
-
-    // For each element in self, if passes filter, add to new list.
-    OsinfoList *newList = g_object_new(OSINFO_TYPE_LIST, NULL);
-    if (!newList) {
-        g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -ENOMEM, OSINFO_NO_MEM);
-        return NULL;
-    }
-
-    __osinfoDoFilter(self, newList, filter);
-    return newList;
-}
-
-int __osinfoDoIntersect(OsinfoList *src1, OsinfoList *src2, OsinfoList *dst)
-{
-    int i, len;
-
-    // Make set representation of otherList and newList
-    GTree *otherSet = g_tree_new(__osinfoStringCompareBase);
-    if (!otherSet)
-        return -ENOMEM;
-
-    GTree *newSet = g_tree_new(__osinfoStringCompareBase);
-    if (!newSet) {
-        g_tree_destroy(otherSet);
-        return -ENOMEM;
-    }
-
-    // Add all from otherList to otherSet
-    len = osinfoListLength(src2);
-    for (i = 0; i < len; i++) {
-        OsinfoEntity *entity = osinfoGetEntityAtIndex(src2, i);
-        gchar *id = entity->priv->id;
-        g_tree_insert(otherSet, id, entity);
-    }
-
-    // If other contains entity, and new list does not, add to new list
-    len = osinfoListLength(src1);
-    for (i = 0; i < len; i++) {
-        OsinfoEntity *entity = osinfoGetEntityAtIndex(src1, i);
-        gchar *id = entity->priv->id;
-
-        if (g_tree_lookup(otherSet, entity->priv->id) &&
-            !g_tree_lookup(newSet, entity->priv->id)) {
-            g_tree_insert(newSet, id, entity);
-            __osinfoListAdd(dst, entity);
-        }
-    }
-
-    g_tree_destroy(otherSet);
-    g_tree_destroy(newSet);
-    return 0;
-}
-
-OsinfoList *osinfoListIntersect(OsinfoList *self, OsinfoList *otherList, GError **err)
-{
-    if (!OSINFO_IS_LIST(self) || !OSINFO_IS_LIST(otherList)) {
-        g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -EINVAL, OSINFO_OBJ_NOT_LIST);
-        return NULL;
-    }
-
-    OsinfoList *newList = g_object_new(OSINFO_TYPE_LIST, NULL);
-    if (!newList) {
-        g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -ENOMEM, OSINFO_NO_MEM);
-        return NULL;
-    }
-
-    int ret;
-
-    ret = __osinfoDoIntersect(self, otherList, newList);
-    if (ret != 0) {
-        g_object_unref(newList);
-        g_set_error_literal(err, g_quark_from_static_string("libosinfo"), ret, __osinfoErrorToString(ret));
-        return NULL;
-    }
-
-    return newList;
-}
-
-int __osinfoDoUnion(OsinfoList *src1, OsinfoList *src2, OsinfoList *dst)
-{
-    // Make set version of new list
-    GTree *newSet = g_tree_new(__osinfoStringCompareBase);
-    if (!newSet)
-        return -ENOMEM;
-
-    // Add all from other list to new list
-    int i, len;
-    len = osinfoListLength(src2);
-    for (i = 0; i < len; i++) {
-        OsinfoEntity *entity = osinfoGetEntityAtIndex(src2, i);
-        gchar *id = entity->priv->id;
-        __osinfoListAdd(dst, entity);
-        g_tree_insert(newSet, id, entity);
-    }
-
-    // Add remaining elements from this list to new list
-    len = osinfoListLength(src1);
-    for (i = 0; i < len; i++) {
-        OsinfoEntity *entity = osinfoGetEntityAtIndex(src1, i);
-        gchar *id = entity->priv->id;
-        // If new list does not contain element, add to new list
-        if (!g_tree_lookup(newSet, id)) {
-            __osinfoListAdd(dst, entity);
-            g_tree_insert(newSet, id, entity);
-        }
-    }
-
-    g_tree_destroy(newSet);
-    return 0;
-}
-
-OsinfoList *osinfoListUnion(OsinfoList *self, OsinfoList *otherList, GError **err)
-{
-    if (!OSINFO_IS_LIST(self) || !OSINFO_IS_LIST(otherList)) {
-        g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -EINVAL, OSINFO_OBJ_NOT_LIST);
-        return NULL;
-    }
-
-    OsinfoList *newList = g_object_new(OSINFO_TYPE_LIST, NULL);
-    if (!newList) {
-        g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -ENOMEM, OSINFO_NO_MEM);
-        return NULL;
-    }
-
-    int ret;
-    ret = __osinfoDoUnion(self, otherList, newList);
-    if (ret != 0) {
-        g_object_unref(newList);
-        g_set_error_literal(err, g_quark_from_static_string("libosinfo"), ret, __osinfoErrorToString(ret));
-        return NULL;
-    }
-
-    return newList;
-}
diff --git a/src/osinfo_os.c b/src/osinfo_os.c
deleted file mode 100644
index db02271..0000000
--- a/src/osinfo_os.c
+++ /dev/null
@@ -1,402 +0,0 @@
-#include <osinfo.h>
-
-G_DEFINE_TYPE (OsinfoOs, osinfo_os, OSINFO_TYPE_ENTITY);
-
-#define OSINFO_OS_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), OSINFO_TYPE_OS, OsinfoOsPrivate))
-
-static void osinfo_os_finalize (GObject *object);
-
-static void
-osinfo_os_finalize (GObject *object)
-{
-    OsinfoOs *self = OSINFO_OS (object);
-
-    g_tree_destroy (self->priv->sections);
-    g_tree_destroy (self->priv->sectionsAsList);
-    g_tree_destroy (self->priv->hypervisors);
-    g_tree_destroy (self->priv->relationshipsByOs);
-    g_tree_destroy (self->priv->relationshipsByType);
-
-    /* Chain up to the parent class */
-    G_OBJECT_CLASS (osinfo_os_parent_class)->finalize (object);
-}
-
-/* Init functions */
-static void
-osinfo_os_class_init (OsinfoOsClass *klass)
-{
-    GObjectClass *g_klass = G_OBJECT_CLASS (klass);
-
-    g_klass->finalize = osinfo_os_finalize;
-    g_type_class_add_private (klass, sizeof (OsinfoOsPrivate));
-}
-
-static void
-osinfo_os_init (OsinfoOs *self)
-{
-    OsinfoOsPrivate *priv;
-    self->priv = priv = OSINFO_OS_GET_PRIVATE(self);
-
-    self->priv->sections = g_tree_new_full(__osinfoStringCompare,
-                                           NULL,
-                                           g_free,
-                                           __osinfoFreeDeviceSection);
-
-    self->priv->sectionsAsList = g_tree_new_full(__osinfoStringCompare,
-                                                 NULL,
-                                                 g_free,
-                                                 __osinfoFreePtrArray);
-
-    self->priv->relationshipsByOs = g_tree_new_full(__osinfoStringCompare,
-                                                NULL,
-                                                g_free,
-                                                __osinfoFreeRelationship);
-    self->priv->relationshipsByType = g_tree_new(__osinfoIntCompareBase);
-
-    self->priv->hypervisors = g_tree_new_full(__osinfoStringCompare,
-                                              NULL,
-                                              g_free,
-                                              __osinfoFreeHvSection);
-}
-
-static int __osinfoAddOsRelationshipByOs(OsinfoOs *self,
-                                         gchar *otherOsId,
-                                         osinfoRelationship rel,
-                                         struct __osinfoOsLink *osLink)
-{
-    gboolean found;
-    gpointer origKey, foundValue;
-    GPtrArray *relationshipsForOs;
-    gchar *otherOsIdDup = NULL;
-
-    found = g_tree_lookup_extended(self->priv->relationshipsByOs, otherOsId, &origKey, &foundValue);
-    if (!found) {
-        otherOsIdDup = g_strdup(otherOsId);
-        relationshipsForOs = g_ptr_array_new_with_free_func(__osinfoFreeOsLink);
-
-        if (!relationshipsForOs)
-            return -ENOMEM;
-        if (!otherOsIdDup) {
-            g_ptr_array_free(relationshipsForOs, TRUE);
-            return -ENOMEM;
-        }
-        g_tree_insert(self->priv->relationshipsByOs, otherOsIdDup, relationshipsForOs);
-    }
-    else
-        relationshipsForOs = (GPtrArray *) foundValue;
-
-    g_ptr_array_add(relationshipsForOs, osLink);
-    return 0;
-}
-
-static int __osinfoAddOsRelationshipByType(OsinfoOs *self,
-                                           osinfoRelationship relshp,
-                                           struct __osinfoOsLink *osLink)
-{
-    gboolean found;
-    gpointer origKey, foundValue;
-    GPtrArray *relationshipsForType;
-
-    found = g_tree_lookup_extended(self->priv->relationshipsByType, (gpointer) relshp, &origKey, &foundValue);
-    if (!found) {
-        relationshipsForType = g_ptr_array_new();
-        if (!relationshipsForType)
-            return -ENOMEM;
-
-        g_tree_insert(self->priv->relationshipsByType, (gpointer) relshp, relationshipsForType);
-    }
-    else
-        relationshipsForType = (GPtrArray *) foundValue;
-
-    g_ptr_array_add(relationshipsForType, osLink);
-    return 0;
-}
-
-static void __osinfoRemoveOsLink(OsinfoOs *self,
-                                 gchar *otherOsId,
-                                 osinfoRelationship relshp,
-                                 struct __osinfoOsLink *osLink)
-{
-    gboolean found;
-    gpointer origKey, foundValue;
-    GPtrArray *relationshipsForOs;
-    GPtrArray *relationshipsForType;
-
-    // First from by-os list
-    found = g_tree_lookup_extended(self->priv->relationshipsByOs, otherOsId, &origKey, &foundValue);
-    if (found) {
-        relationshipsForOs = (GPtrArray *) foundValue;
-        g_ptr_array_remove(relationshipsForOs, osLink);
-    }
-
-    // Now from by-relshp list
-    found = g_tree_lookup_extended(self->priv->relationshipsByType, (gpointer) relshp, &origKey, &foundValue);
-    if (found) {
-        relationshipsForType = (GPtrArray *) foundValue;
-        g_ptr_array_remove(relationshipsForType, osLink);
-    }
-}
-
-int __osinfoAddOsRelationship (OsinfoOs *self, gchar *otherOsId, osinfoRelationship rel)
-{
-    if ( !OSINFO_IS_OS(self) || !otherOsId)
-        return -EINVAL;
-
-    struct __osinfoOsLink *osLink = NULL;
-    osLink = g_malloc(sizeof(*osLink));
-    if (!osLink)
-        return -ENOMEM;
-
-    osLink->subjectOs = self;
-    osLink->verb = rel;
-
-    int ret;
-    ret = __osinfoAddOsRelationshipByOs(self, otherOsId, rel, osLink);
-    if (ret != 0)
-        goto error_free;
-
-    ret = __osinfoAddOsRelationshipByType(self, rel, osLink);
-    if (ret != 0)
-        goto error_cleanup;
-
-    return ret;
-
-error_cleanup:
-    __osinfoRemoveOsLink(self, otherOsId, rel, osLink);
-error_free:
-    g_free(osLink);
-    return ret;
-}
-
-int __osinfoAddDeviceToSectionOs(OsinfoOs *self, gchar *section, gchar *id, gchar *driver)
-{
-    if( !OSINFO_IS_OS(self) || !section || !id || !driver)
-        return -EINVAL;
-
-    return __osinfoAddDeviceToSection(self->priv->sections, self->priv->sectionsAsList, section, id, driver);
-}
-
-void __osinfoClearDeviceSectionOs(OsinfoOs *self, gchar *section)
-{
-    if (!OSINFO_IS_OS(self) || !section)
-        return;
-
-    __osinfoClearDeviceSection(self->priv->sections, self->priv->sectionsAsList, section);
-}
-
-struct __osinfoHvSection *__osinfoAddHypervisorSectionToOs(OsinfoOs *self, gchar *hvId)
-{
-    if (!OSINFO_IS_OS(self) || !hvId)
-        return NULL;
-
-    gboolean found;
-    gpointer origKey, foundValue;
-    struct __osinfoHvSection *hvSection = NULL;
-    gchar *hvIdDup = NULL;
-    GTree *deviceSections;
-    GTree *deviceSectionsAsList;
-
-    found = g_tree_lookup_extended(self->priv->hypervisors, hvId, &origKey, &foundValue);
-    if (!found) {
-        hvSection = g_malloc(sizeof(*hvSection));
-        hvIdDup = g_strdup(hvId);
-        deviceSections = g_tree_new_full(__osinfoStringCompare,
-                                        NULL,
-                                        g_free,
-                                        __osinfoFreeDeviceSection);
-
-        if (!deviceSections)
-            goto error_free;
-
-        deviceSectionsAsList = g_tree_new_full(__osinfoStringCompare,
-                                               NULL,
-                                               g_free,
-                                               __osinfoFreePtrArray);
-        if (!deviceSectionsAsList) {
-            g_tree_destroy(deviceSections);
-            goto error_free;
-        }
-
-        if (!hvSection || !hvIdDup) {
-            g_tree_destroy(deviceSectionsAsList);
-            g_tree_destroy(deviceSections);
-            goto error_free;
-        }
-
-        hvSection->os = self;
-        // Will set hv link later
-        hvSection->sections = deviceSections;
-        hvSection->sectionsAsList = deviceSectionsAsList;
-
-        g_tree_insert(self->priv->hypervisors, hvIdDup, hvSection);
-        return hvSection;
-    }
-    else
-        return (struct __osinfoHvSection *) foundValue;
-
-error_free:
-    g_free(hvSection);
-    g_free(hvIdDup);
-    return NULL;
-}
-
-void __osinfoRemoveHvSectionFromOs(OsinfoOs *self, gchar *hvId)
-{
-    g_tree_remove(self->priv->hypervisors, hvId);
-}
-
-OsinfoDevice *osinfoGetPreferredDeviceForOs(OsinfoOs *self, OsinfoHypervisor *hv, gchar *devType, OsinfoFilter *filter, GError **err)
-{
-    if (!__osinfoCheckGErrorParamValid(err))
-        return NULL;
-
-    if (!OSINFO_IS_OS(self)) {
-        g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -EINVAL, OSINFO_OBJ_NOT_OS);
-        return NULL;
-    }
-
-    if (hv && !OSINFO_IS_HYPERVISOR(hv)) {
-        g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -EINVAL, OSINFO_OBJ_NOT_HV);
-        return NULL;
-    }
-
-    if (!devType) {
-        g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -EINVAL, OSINFO_NO_DEVTYPE);
-        return NULL;
-    }
-
-    if (filter && !OSINFO_IS_FILTER(filter)) {
-        g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -EINVAL, OSINFO_OBJ_NOT_FILTER);
-        return NULL;
-    }
-
-    // Check if device type info present for <os,hv>, else return NULL.
-
-    GPtrArray *sectionList = NULL;
-    if (hv) {
-        // Check if hypervisor specific info present for Os, else return NULL.
-        struct __osinfoHvSection *hvSection = NULL;
-        hvSection = g_tree_lookup(self->priv->hypervisors, (OSINFO_ENTITY(hv))->priv->id);
-        if (!hvSection)
-            return NULL;
-
-        sectionList = g_tree_lookup(hvSection->sectionsAsList, devType);
-        if (!sectionList)
-            return NULL;
-    }
-    else {
-        sectionList = g_tree_lookup(self->priv->sectionsAsList, devType);
-        if (!sectionList)
-            return NULL;
-    }
-
-    // For each device in section list, apply filter. If filter passes, return device.
-    int i;
-    struct __osinfoDeviceLink *deviceLink;
-    for (i = 0; i < sectionList->len; i++) {
-        deviceLink = g_ptr_array_index(sectionList, i);
-        if (__osinfoDevicePassesFilter(filter, deviceLink->dev))
-            return deviceLink->dev;
-    }
-
-    // If no devices pass filter, return NULL.
-    return NULL;
-}
-
-OsinfoOsList *osinfoGetRelatedOs(OsinfoOs *self, osinfoRelationship relshp, GError **err)
-{
-    if (!__osinfoCheckGErrorParamValid(err))
-        return NULL;
-
-    if (!OSINFO_IS_OS(self)) {
-        g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -EINVAL, OSINFO_OBJ_NOT_OS);
-        return NULL;
-    }
-
-    if (!__osinfoCheckRelationshipValid(relshp)) {
-        g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -EINVAL, OSINFO_INVALID_RELATIONSHIP);
-        return NULL;
-    }
-
-    // Create our list
-    OsinfoOsList *newList = g_object_new(OSINFO_TYPE_OSLIST, NULL);
-    if (!newList) {
-        g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -ENOMEM, OSINFO_NO_MEM);
-        return NULL;
-    }
-
-    GPtrArray *relatedOses = NULL;
-    relatedOses = g_tree_lookup(self->priv->relationshipsByType, (gpointer) relshp);
-    if (relatedOses) {
-        int i, len;
-        len = relatedOses->len;
-        for (i = 0; i < len; i++) {
-            struct __osinfoOsLink *osLink = g_ptr_array_index(relatedOses, i);
-            __osinfoListAdd(OSINFO_LIST (newList), OSINFO_ENTITY (osLink->directObjectOs));
-        }
-    }
-
-    return newList;
-}
-
-OsinfoDeviceList *osinfoGetDevicesForOs(OsinfoOs *self, OsinfoHypervisor *hv, gchar *devType, OsinfoFilter *filter, GError **err)
-{
-    if (!__osinfoCheckGErrorParamValid(err))
-        return NULL;
-
-    if (!OSINFO_IS_OS(self)) {
-        g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -EINVAL, OSINFO_OBJ_NOT_OS);
-        return NULL;
-    }
-
-    if (!OSINFO_IS_HYPERVISOR(hv)) {
-        g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -EINVAL, OSINFO_OBJ_NOT_HV);
-        return NULL;
-    }
-
-    if (!devType) {
-        g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -EINVAL, OSINFO_NO_DEVTYPE);
-        return NULL;
-    }
-
-    if (filter && !OSINFO_IS_FILTER(filter)) {
-        g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -EINVAL, OSINFO_OBJ_NOT_FILTER);
-        return NULL;
-    }
-
-    GPtrArray *sectionList = NULL;
-
-    // Create our device list
-    OsinfoDeviceList *newList = g_object_new(OSINFO_TYPE_DEVICELIST, NULL);
-    if (!newList) {
-        g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -ENOMEM, OSINFO_NO_MEM);
-        return NULL;
-    }
-
-    if (hv) {
-        struct __osinfoHvSection *hvSection = NULL;
-        hvSection = g_tree_lookup(self->priv->hypervisors, (OSINFO_ENTITY(hv))->priv->id);
-        if (!hvSection)
-            return newList;
-
-        sectionList = g_tree_lookup(hvSection->sectionsAsList, devType);
-        if (!sectionList)
-            return newList;
-    }
-    else {
-        sectionList = g_tree_lookup(self->priv->sectionsAsList, devType);
-        if (!sectionList)
-            return newList;
-    }
-
-    // For each device in section list, apply filter. If filter passes, add device to list.
-    int i;
-    struct __osinfoDeviceLink *deviceLink;
-    for (i = 0; i < sectionList->len; i++) {
-        deviceLink = g_ptr_array_index(sectionList, i);
-        if (__osinfoDevicePassesFilter(filter, deviceLink->dev))
-            __osinfoListAdd(OSINFO_LIST (newList), OSINFO_ENTITY (deviceLink->dev));
-    }
-
-    return NULL;
-}
diff --git a/src/osinfo_oslist.c b/src/osinfo_oslist.c
deleted file mode 100644
index d723703..0000000
--- a/src/osinfo_oslist.c
+++ /dev/null
@@ -1,121 +0,0 @@
-#include <osinfo.h>
-
-G_DEFINE_TYPE (OsinfoOsList, osinfo_oslist, OSINFO_TYPE_LIST);
-
-#define OSINFO_OSLIST_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), OSINFO_TYPE_OSLIST, OsinfoOsListPrivate))
-
-static void osinfo_oslist_finalize (GObject *object);
-
-struct _OsinfoOsListPrivate
-{
-    int tmp;
-};
-
-static void
-osinfo_oslist_finalize (GObject *object)
-{
-    /* Chain up to the parent class */
-    G_OBJECT_CLASS (osinfo_oslist_parent_class)->finalize (object);
-}
-
-/* Init functions */
-static void
-osinfo_oslist_class_init (OsinfoOsListClass *klass)
-{
-    GObjectClass *g_klass = G_OBJECT_CLASS (klass);
-
-    g_klass->finalize = osinfo_oslist_finalize;
-    g_type_class_add_private (klass, sizeof (OsinfoOsListPrivate));
-}
-
-static void
-osinfo_oslist_init (OsinfoOsList *self)
-{
-    OsinfoOsListPrivate *priv;
-    self->priv = priv = OSINFO_OSLIST_GET_PRIVATE(self);
-
-}
-
-OsinfoOs *osinfoGetOsAtIndex(OsinfoOsList *self, gint idx, GError **err)
-{
-    if (!OSINFO_IS_OSLIST(self)) {
-        g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -EINVAL, OSINFO_OBJ_NOT_OSLIST);
-        return NULL;
-    }
-
-    OsinfoList *selfAsList = OSINFO_LIST (self);
-    OsinfoEntity *entity = osinfoGetEntityAtIndex(selfAsList, idx);
-    return OSINFO_OS (entity);
-}
-
-OsinfoOsList *osinfoOsListFilter(OsinfoOsList *self, OsinfoFilter *filter, GError **err)
-{
-    if (!OSINFO_IS_OSLIST(self)) {
-        g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -EINVAL, OSINFO_OBJ_NOT_OSLIST);
-        return NULL;
-    }
-
-    if (filter && !OSINFO_IS_FILTER(self)) {
-        g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -EINVAL, OSINFO_OBJ_NOT_FILTER);
-        return NULL;
-    }
-
-    // For each element in self, if passes filter, add to new list.
-    OsinfoOsList *newList = g_object_new(OSINFO_TYPE_OSLIST, NULL);
-    if (!newList) {
-        g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -ENOMEM, OSINFO_NO_MEM);
-        return NULL;
-    }
-
-    __osinfoDoFilter(OSINFO_LIST (self), OSINFO_LIST (newList), filter);
-    return newList;
-}
-
-OsinfoOsList *osinfoOsListIntersect(OsinfoOsList *self, OsinfoOsList *otherList, GError **err)
-{
-    if (!OSINFO_IS_OSLIST(self) || !OSINFO_IS_OSLIST(otherList)) {
-        g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -EINVAL, OSINFO_OBJ_NOT_OSLIST);
-        return NULL;
-    }
-
-    OsinfoOsList *newList = g_object_new(OSINFO_TYPE_OSLIST, NULL);
-    if (!newList) {
-        g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -ENOMEM, OSINFO_NO_MEM);
-        return NULL;
-    }
-
-    int ret;
-
-    ret = __osinfoDoIntersect(self, otherList, newList);
-    if (ret != 0) {
-        g_object_unref(newList);
-        g_set_error_literal(err, g_quark_from_static_string("libosinfo"), ret, __osinfoErrorToString(ret));
-        return NULL;
-    }
-
-    return newList;
-}
-
-OsinfoOsList *osinfoOsListUnion(OsinfoOsList *self, OsinfoOsList *otherList, GError **err)
-{
-    if (!OSINFO_IS_OSLIST(self) || !OSINFO_IS_OSLIST(otherList)) {
-        g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -EINVAL, OSINFO_OBJ_NOT_OSLIST);
-        return NULL;
-    }
-
-    OsinfoOsList *newList = g_object_new(OSINFO_TYPE_OSLIST, NULL);
-    if (!newList) {
-        g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -ENOMEM, OSINFO_NO_MEM);
-        return NULL;
-    }
-
-    int ret;
-    ret = __osinfoDoUnion(self, otherList, newList);
-    if (ret != 0) {
-        g_object_unref(newList);
-        g_set_error_literal(err, g_quark_from_static_string("libosinfo"), ret, __osinfoErrorToString(ret));
-        return NULL;
-    }
-
-    return newList;
-}
-- 
1.7.2.1




More information about the virt-tools-list mailing list