diff --git a/gplugin-gtk/gplugin-gtk-store.c b/gplugin-gtk/gplugin-gtk-store.c
--- a/gplugin-gtk/gplugin-gtk-store.c
+++ b/gplugin-gtk/gplugin-gtk-store.c
@@ -229,7 +229,7 @@
 static void
 gplugin_gtk_store_constructed(GObject *obj)
 {
-	GObject *manager = NULL;
+	GPluginManager *manager = NULL;
 	GList *l, *ids = NULL;
 
 	G_OBJECT_CLASS(gplugin_gtk_store_parent_class)->constructed(obj);
diff --git a/gplugin/gplugin-manager.h b/gplugin/gplugin-manager.h
--- a/gplugin/gplugin-manager.h
+++ b/gplugin/gplugin-manager.h
@@ -29,11 +29,86 @@
 
 G_BEGIN_DECLS
 
+#define GPLUGIN_TYPE_MANAGER (gplugin_manager_get_type())
+G_DECLARE_DERIVABLE_TYPE(
+	GPluginManager,
+	gplugin_manager,
+	GPLUGIN,
+	MANAGER,
+	GObject);
+
 typedef void (*GPluginManagerForeachFunc)(
 	const gchar *id,
 	GSList *plugins,
 	gpointer data);
 
+struct _GPluginManagerClass {
+	/*< private >*/
+	GObjectClass parent;
+
+	/*< public >*/
+	void (*append_path)(GPluginManager *manager, const gchar *path);
+	void (*prepend_path)(GPluginManager *manager, const gchar *path);
+	void (*remove_path)(GPluginManager *manager, const gchar *path);
+	void (*remove_paths)(GPluginManager *manager);
+
+	GList *(*get_paths)(GPluginManager *manager);
+
+	gboolean (
+		*register_loader)(GPluginManager *manager, GType type, GError **error);
+	gboolean (*unregister_loader)(
+		GPluginManager *manager,
+		GType type,
+		GError **error);
+	GSList *(*get_loaders)(GPluginManager *manager);
+
+	void (*refresh)(GPluginManager *manager);
+
+	void (*foreach)(
+		GPluginManager *manager,
+		GPluginManagerForeachFunc func,
+		gpointer data);
+
+	GSList *(*find_plugins)(GPluginManager *manager, const gchar *id);
+	GSList *(*find_plugins_with_state)(
+		GPluginManager *manager,
+		GPluginPluginState state);
+
+	GList *(*list_plugins)(GPluginManager *manager);
+
+	GSList *(*get_plugin_dependencies)(
+		GPluginManager *manager,
+		GPluginPlugin *plugin,
+		GError **error);
+
+	gboolean (*load_plugin)(
+		GPluginManager *manager,
+		GPluginPlugin *plugin,
+		GError **error);
+	gboolean (*unload_plugin)(
+		GPluginManager *manager,
+		GPluginPlugin *plugin,
+		GError **error);
+
+	/* signals */
+	gboolean (*loading_plugin)(
+		GPluginManager *manager,
+		GPluginPlugin *plugin,
+		GError **error);
+	void (*loaded_plugin)(GPluginManager *manager, GPluginPlugin *plugin);
+	void (*load_failed)(GPluginManager *manager, GPluginPlugin *plugin);
+	gboolean (*unloading_plugin)(
+		GPluginManager *manager,
+		GPluginPlugin *plugin,
+		GError **error);
+	void (*unloaded_plugin)(GPluginManager *manager, GPluginPlugin *plugin);
+	void (
+		*unload_plugin_failed)(GPluginManager *manager, GPluginPlugin *plugin);
+
+	/*< private >*/
+	gpointer reserved[8];
+};
+
 void gplugin_manager_append_path(const gchar *path);
 void gplugin_manager_prepend_path(const gchar *path);
 void gplugin_manager_remove_path(const gchar *path);
@@ -71,7 +146,7 @@
 
 GList *gplugin_manager_list_plugins(void);
 
-GObject *gplugin_manager_get_instance(void);
+GPluginManager *gplugin_manager_get_instance(void);
 
 G_END_DECLS
 
diff --git a/gplugin/gplugin-manager.c b/gplugin/gplugin-manager.c
--- a/gplugin/gplugin-manager.c
+++ b/gplugin/gplugin-manager.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2011-2020 Gary Kramlich <grim@reaperworld.com>
+ * Copyright (C) 2011-2021 Gary Kramlich <grim@reaperworld.com>
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -45,6 +45,53 @@
  * A callback function for gplugin_manager_foreach().
  */
 
+/**
+ * GPluginManagerClass:
+ * @append_path: The <literal>append_path</literal> function is responsible for
+ *               adding a path to the end of the list of plugin search paths.
+ * @prepend_path: The <literal>prepend_path</literal> function is responsible
+ *                for adding a path to the beginning of the list of plugin
+ *                search paths.
+ * @remove_path: The <literal>remove_path</literal> function is responsible
+ *               for removing a patch from the list of plugin search paths.
+ * @remove_paths: The <literal>remove_paths</literal> function is responsible
+ *                for clearing the list of plugin search paths.
+ * @get_paths: The <literal>get_paths</literal> function is reponsible for
+ *             returning a list of plugin search paths.
+ * @register_loader: The <literal>register_loader</literal> function is
+ *                   responsible for registering plugin loaders.
+ * @unregister_loader: The <literal>unregister_loader</literal> function is
+ *                     responsible for unregistering plugin loaders.
+ * @get_loaders: The <literal>get_loaders</literal> function is responsible
+ *               for returning a list of all registered plugin loaders.
+ * @refresh: The <literal>refresh</literal> function is responsible for
+ *           refreshing the state of all plugins by searching the plugin search
+ *           paths.
+ * @foreach: The <literal>foreach</literal> function is responsible for calling
+ *           the given #GPluginManagerForeachFunc for each plugin.
+ * @find_plugins: The <literal>find_plugins</literal> function is responsible
+ *                for returning a list of all plugins that match the given id.
+ * @find_plugins_with_state: The <literal>find_plugins_with_state</literal>
+ *                           function is responsible for returning a list of
+ *                           all plugins matching the given #GPluginPluginState.
+ * @list_plugins: The <literal>list_plugins</literal> function is responsible
+ *                for returning a list of all known plugin ids.
+ * @get_plugin_dependencies: The <literal>get_plugin_dependencies</literal>
+ *                           function is responsible for returning a list of
+ *                           #GPluginPlugin's that the given plugin depends on.
+ * @load_plugin: The <literal>load_plugin</literal> method is responsible for
+ *               loading plugins.
+ * @unload_plugin: The <literal>unload_plugin</literal> method is responsible
+ *                 for unloading plugins.
+ * @loading_plugin: Signal emitted before a plugin is loaded.
+ * @loaded_plugin: Signal emitted after a plugin is loaded.
+ * @load_failed: Signal emitted when a plugin fails to load.
+ * @unloading_plugin: Signal emitted before a plugin is unloaded.
+ * @unloaded_plugin: Signal emitted after a plugin is unloaded.
+ * @unload_plugin_failed: Signal emitted when a plugin fails to unload.
+ *
+ * Virtual function table for #GPluginManager.
+ */
 /******************************************************************************
  * Enums
  *****************************************************************************/
@@ -72,91 +119,9 @@
 	GHashTable *loaders_by_extension;
 
 	gboolean refresh_needed;
-} GPluginManager;
-
-typedef struct {
-	GObjectClass parent;
-
-	void (*append_path)(GPluginManager *manager, const gchar *path);
-	void (*prepend_path)(GPluginManager *manager, const gchar *path);
-	void (*remove_path)(GPluginManager *manager, const gchar *path);
-	void (*remove_paths)(GPluginManager *manager);
-
-	GList *(*get_paths)(GPluginManager *manager);
-
-	gboolean (
-		*register_loader)(GPluginManager *manager, GType type, GError **error);
-	gboolean (*unregister_loader)(
-		GPluginManager *manager,
-		GType type,
-		GError **error);
-	GSList *(*get_loaders)(GPluginManager *manager);
-
-	void (*refresh)(GPluginManager *manager);
-
-	void (*foreach)(
-		GPluginManager *manager,
-		GPluginManagerForeachFunc func,
-		gpointer data);
-
-	GSList *(*find_plugins)(GPluginManager *manager, const gchar *id);
-	GSList *(*find_plugins_with_state)(
-		GPluginManager *manager,
-		GPluginPluginState state);
-
-	GList *(*list_plugins)(GPluginManager *manager);
-
-	GSList *(*get_plugin_dependencies)(
-		GPluginManager *manager,
-		GPluginPlugin *plugin,
-		GError **error);
+} GPluginManagerPrivate;
 
-	gboolean (*load_plugin)(
-		GPluginManager *manager,
-		GPluginPlugin *plugin,
-		GError **error);
-	gboolean (*unload_plugin)(
-		GPluginManager *manager,
-		GPluginPlugin *plugin,
-		GError **error);
-
-	/* signals */
-	gboolean (*loading_plugin)(
-		GObject *manager,
-		GPluginPlugin *plugin,
-		GError **error);
-	void (*loaded_plugin)(GObject *manager, GPluginPlugin *plugin);
-	void (*load_failed)(GObject *manager, GPluginPlugin *plugin);
-	gboolean (*unloading_plugin)(
-		GObject *manager,
-		GPluginPlugin *plugin,
-		GError **error);
-	void (*unloaded_plugin)(GObject *manager, GPluginPlugin *plugin);
-	void (*unload_plugin_failed)(GObject *manager, GPluginPlugin *plugin);
-} GPluginManagerClass;
-
-#define GPLUGIN_TYPE_MANAGER (gplugin_manager_get_type())
-#define GPLUGIN_MANAGER(obj) \
-	(G_TYPE_CHECK_INSTANCE_CAST((obj), GPLUGIN_TYPE_MANAGER, GPluginManager))
-#define GPLUGIN_MANAGER_CLASS(klass) \
-	(G_TYPE_CHECK_CLASS_CAST( \
-		(klass), \
-		GPLUGIN_TYPE_MANAGER, \
-		GPluginManagerClass))
-#define GPLUGIN_IS_MANAGER(obj) \
-	(G_TYPE_CHECK_INSTANCE_TYPE((obj), GPLUGIN_TYPE_MANAGER))
-#define GPLUGIN_IS_MANAGER_CLASS(klass) \
-	(G_TYPE_CHECK_CLASS_TYPE((klass), GPLUGIN_TYPE_MANAGER))
-#define GPLUGIN_MANAGER_GET_CLASS(obj) \
-	(G_TYPE_INSTANCE_GET_CLASS( \
-		(obj), \
-		GPLUGIN_TYPE_MANAGER, \
-		GPluginManagerClass))
-
-#define GPLUGIN_MANAGER_INSTANCE \
-	(GPLUGIN_MANAGER(gplugin_manager_get_instance()))
-
-G_DEFINE_TYPE(GPluginManager, gplugin_manager, G_TYPE_OBJECT);
+G_DEFINE_TYPE_WITH_PRIVATE(GPluginManager, gplugin_manager, G_TYPE_OBJECT);
 
 /******************************************************************************
  * Globals
@@ -211,12 +176,14 @@
 static GPluginLoader *
 gplugin_manager_find_loader_by_type(GPluginManager *manager, GType type)
 {
+	GPluginManagerPrivate *priv = NULL;
 	GSList *l = NULL;
 
 	g_return_val_if_fail(GPLUGIN_IS_MANAGER(manager), NULL);
 	g_return_val_if_fail(g_type_is_a(type, GPLUGIN_TYPE_LOADER), NULL);
 
-	for(l = manager->loaders; l; l = l->next) {
+	priv = gplugin_manager_get_instance_private(manager);
+	for(l = priv->loaders; l; l = l->next) {
 		if(G_OBJECT_TYPE(l->data) == type) {
 			return GPLUGIN_LOADER(l->data);
 		}
@@ -288,6 +255,7 @@
 static void
 gplugin_manager_real_append_path(GPluginManager *manager, const gchar *path)
 {
+	GPluginManagerPrivate *priv = NULL;
 	GList *l = NULL;
 	gchar *normalized = NULL;
 
@@ -297,12 +265,14 @@
 
 	normalized = gplugin_manager_normalize_path(path);
 
+	priv = gplugin_manager_get_instance_private(manager);
+
 	l = g_queue_find_custom(
-		manager->paths,
+		priv->paths,
 		normalized,
 		gplugin_manager_compare_paths);
 	if(l == NULL) {
-		g_queue_push_tail(manager->paths, normalized);
+		g_queue_push_tail(priv->paths, normalized);
 	} else {
 		g_free(normalized);
 	}
@@ -311,6 +281,7 @@
 static void
 gplugin_manager_real_prepend_path(GPluginManager *manager, const gchar *path)
 {
+	GPluginManagerPrivate *priv = NULL;
 	GList *l = NULL;
 	gchar *normalized = NULL;
 
@@ -320,12 +291,14 @@
 
 	normalized = gplugin_manager_normalize_path(path);
 
+	priv = gplugin_manager_get_instance_private(manager);
+
 	l = g_queue_find_custom(
-		manager->paths,
+		priv->paths,
 		normalized,
 		gplugin_manager_compare_paths);
 	if(l == NULL) {
-		g_queue_push_head(manager->paths, normalized);
+		g_queue_push_head(priv->paths, normalized);
 	} else {
 		g_free(normalized);
 	}
@@ -334,6 +307,7 @@
 static void
 gplugin_manager_real_remove_path(GPluginManager *manager, const gchar *path)
 {
+	GPluginManagerPrivate *priv = NULL;
 	GList *l = NULL;
 	gchar *normalized = NULL;
 
@@ -341,13 +315,15 @@
 
 	normalized = gplugin_manager_normalize_path(path);
 
+	priv = gplugin_manager_get_instance_private(manager);
+
 	l = g_queue_find_custom(
-		manager->paths,
+		priv->paths,
 		normalized,
 		gplugin_manager_compare_paths);
 	if(l != NULL) {
 		g_free(l->data);
-		g_queue_delete_link(manager->paths, l);
+		g_queue_delete_link(priv->paths, l);
 	}
 
 	g_free(normalized);
@@ -356,15 +332,19 @@
 static void
 gplugin_manager_real_remove_paths(GPluginManager *manager)
 {
+	GPluginManagerPrivate *priv = gplugin_manager_get_instance_private(manager);
+
 	/* g_queue_clear_full was added in 2.60 but we require 2.40 */
-	g_queue_foreach(manager->paths, (GFunc)g_free, NULL);
-	g_queue_clear(manager->paths);
+	g_queue_foreach(priv->paths, (GFunc)g_free, NULL);
+	g_queue_clear(priv->paths);
 }
 
 static GList *
 gplugin_manager_real_get_paths(GPluginManager *manager)
 {
-	return manager->paths->head;
+	GPluginManagerPrivate *priv = gplugin_manager_get_instance_private(manager);
+
+	return priv->paths->head;
 }
 
 static gboolean
@@ -373,6 +353,7 @@
 	GType type,
 	GError **error)
 {
+	GPluginManagerPrivate *priv = NULL;
 	GPluginLoader *loader = NULL;
 	GSList *l = NULL, *exts = NULL;
 
@@ -402,8 +383,10 @@
 		return FALSE;
 	}
 
-	manager->loaders =
-		g_slist_prepend(manager->loaders, g_object_ref(G_OBJECT(loader)));
+	priv = gplugin_manager_get_instance_private(manager);
+
+	priv->loaders =
+		g_slist_prepend(priv->loaders, g_object_ref(G_OBJECT(loader)));
 
 	exts = gplugin_loader_get_supported_extensions(loader);
 	for(l = exts; l; l = l->next) {
@@ -414,7 +397,7 @@
 		 * we can prepend our loader.  But before we add ours, we remove any
 		 * old copies we might have of ours.
 		 */
-		existing = g_hash_table_lookup(manager->loaders_by_extension, ext);
+		existing = g_hash_table_lookup(priv->loaders_by_extension, ext);
 		for(ll = existing; ll; ll = ll->next) {
 			if(G_OBJECT_TYPE(ll->data) == type) {
 				GPluginLoader *old = GPLUGIN_LOADER(ll->data);
@@ -431,14 +414,14 @@
 
 		/* Now insert the updated slist back into the hash table */
 		g_hash_table_insert(
-			manager->loaders_by_extension,
+			priv->loaders_by_extension,
 			g_strdup(ext),
 			existing);
 	}
 	g_slist_free(exts);
 
 	/* make a note that we need to refresh */
-	manager->refresh_needed = TRUE;
+	priv->refresh_needed = TRUE;
 
 	/* we remove our initial reference from the loader now to avoid a leak */
 	g_object_unref(G_OBJECT(loader));
@@ -452,6 +435,7 @@
 	GType type,
 	GError **error)
 {
+	GPluginManagerPrivate *priv = NULL;
 	GPluginLoader *loader = NULL;
 	GSList *l = NULL, *exts = NULL;
 
@@ -469,6 +453,8 @@
 		return FALSE;
 	}
 
+	priv = gplugin_manager_get_instance_private(manager);
+
 	exts = gplugin_loader_get_supported_extensions(loader);
 	for(l = exts; l; l = l->next) {
 		GSList *los = NULL;
@@ -476,7 +462,7 @@
 		const gchar *ext = NULL;
 
 		ext = (const gchar *)exts->data;
-		los = g_hash_table_lookup(manager->loaders_by_extension, ext);
+		los = g_hash_table_lookup(priv->loaders_by_extension, ext);
 
 		for(ll = los; ll; ll = ll->next) {
 			GPluginLoader *lo = GPLUGIN_LOADER(ll->data);
@@ -493,11 +479,11 @@
 			los = g_slist_remove(los, lo);
 			if(los) {
 				g_hash_table_insert(
-					manager->loaders_by_extension,
+					priv->loaders_by_extension,
 					g_strdup(ext),
 					los);
 			} else {
-				g_hash_table_remove(manager->loaders_by_extension, ext);
+				g_hash_table_remove(priv->loaders_by_extension, ext);
 			}
 
 			/* kill our ref to the loader */
@@ -509,7 +495,7 @@
 	}
 	g_slist_free(exts);
 
-	manager->loaders = g_slist_remove(manager->loaders, loader);
+	priv->loaders = g_slist_remove(priv->loaders, loader);
 	g_object_unref(G_OBJECT(loader));
 
 	return TRUE;
@@ -518,23 +504,28 @@
 static GSList *
 gplugin_manager_real_get_loaders(GPluginManager *manager)
 {
-	return g_slist_copy_deep(manager->loaders, (GCopyFunc)g_object_ref, NULL);
+	GPluginManagerPrivate *priv = gplugin_manager_get_instance_private(manager);
+
+	return g_slist_copy_deep(priv->loaders, (GCopyFunc)g_object_ref, NULL);
 }
 
 static void
 gplugin_manager_real_refresh(GPluginManager *manager)
 {
+	GPluginManagerPrivate *priv = NULL;
 	GNode *root = NULL;
 	GList *error_messages = NULL, *l = NULL;
 	gchar *error_message = NULL;
 	guint errors = 0;
 
-	/* build a tree of all possible plugins */
-	root = gplugin_file_tree_new(manager->paths->head);
+	priv = gplugin_manager_get_instance_private(manager);
 
-	manager->refresh_needed = TRUE;
+	/* build a tree of all possible plugins */
+	root = gplugin_file_tree_new(priv->paths->head);
 
-	while(manager->refresh_needed) {
+	priv->refresh_needed = TRUE;
+
+	while(priv->refresh_needed) {
 		GNode *dir = NULL;
 
 		if(error_messages) {
@@ -544,7 +535,7 @@
 			error_messages = NULL;
 		}
 
-		manager->refresh_needed = FALSE;
+		priv->refresh_needed = FALSE;
 
 		for(dir = root->children; dir; dir = dir->next) {
 			GPluginFileTreeEntry *e = dir->data;
@@ -562,9 +553,8 @@
 
 				/* Build the path and see if we need to probe it! */
 				filename = g_build_filename(path, e->filename, NULL);
-				plugin = g_hash_table_lookup(
-					manager->plugins_filename_view,
-					filename);
+				plugin =
+					g_hash_table_lookup(priv->plugins_filename_view, filename);
 
 				if(plugin && GPLUGIN_IS_PLUGIN(plugin)) {
 					GPluginPluginState state = gplugin_plugin_get_state(plugin);
@@ -581,7 +571,7 @@
 
 				/* grab the list of loaders for this extension */
 				l = g_hash_table_lookup(
-					manager->loaders_by_extension,
+					priv->loaders_by_extension,
 					e->extension);
 				for(; l; l = l->next) {
 					if(!GPLUGIN_IS_LOADER(l->data)) {
@@ -668,14 +658,14 @@
 
 					/* now insert into our view */
 					g_hash_table_replace(
-						manager->plugins_filename_view,
+						priv->plugins_filename_view,
 						real_filename,
 						g_object_ref(G_OBJECT(plugin)));
 
 					/* Grab the list of plugins with our id and prepend the new
 					 * plugin to it before updating it.
 					 */
-					l = g_hash_table_lookup(manager->plugins, id);
+					l = g_hash_table_lookup(priv->plugins, id);
 					for(ll = l; ll; ll = ll->next) {
 						GPluginPlugin *splugin = GPLUGIN_PLUGIN(ll->data);
 						gchar *sfilename = gplugin_plugin_get_filename(splugin);
@@ -687,7 +677,7 @@
 					}
 					if(!seen) {
 						l = g_slist_prepend(l, g_object_ref(plugin));
-						g_hash_table_insert(manager->plugins, g_strdup(id), l);
+						g_hash_table_insert(priv->plugins, g_strdup(id), l);
 					}
 
 					/* check if the plugin is supposed to be loaded on query,
@@ -727,7 +717,7 @@
 						 */
 						if(errors > 0) {
 							errors = 0;
-							manager->refresh_needed = TRUE;
+							priv->refresh_needed = TRUE;
 						}
 					}
 
@@ -764,10 +754,13 @@
 	GPluginManagerForeachFunc func,
 	gpointer data)
 {
+	GPluginManagerPrivate *priv = NULL;
 	GHashTableIter iter;
 	gpointer id = NULL, plugins = NULL;
 
-	g_hash_table_iter_init(&iter, manager->plugins);
+	priv = gplugin_manager_get_instance_private(manager);
+
+	g_hash_table_iter_init(&iter, priv->plugins);
 	while(g_hash_table_iter_next(&iter, &id, &plugins)) {
 		func((gchar *)id, (GSList *)plugins, data);
 	}
@@ -776,11 +769,14 @@
 static GSList *
 gplugin_manager_real_find_plugins(GPluginManager *manager, const gchar *id)
 {
+	GPluginManagerPrivate *priv = NULL;
 	GSList *plugins_list = NULL, *l;
 
 	g_return_val_if_fail(id != NULL, NULL);
 
-	l = g_hash_table_lookup(manager->plugins, id);
+	priv = gplugin_manager_get_instance_private(manager);
+
+	l = g_hash_table_lookup(priv->plugins, id);
 	plugins_list = g_slist_copy_deep(l, (GCopyFunc)g_object_ref, NULL);
 
 	return plugins_list;
@@ -791,11 +787,14 @@
 	GPluginManager *manager,
 	GPluginPluginState state)
 {
+	GPluginManagerPrivate *priv = NULL;
 	GSList *plugins = NULL;
 	GHashTableIter iter;
 	gpointer value = NULL;
 
-	g_hash_table_iter_init(&iter, manager->plugins);
+	priv = gplugin_manager_get_instance_private(manager);
+
+	g_hash_table_iter_init(&iter, priv->plugins);
 	while(g_hash_table_iter_next(&iter, NULL, &value)) {
 		GSList *l = NULL;
 
@@ -815,12 +814,15 @@
 static GList *
 gplugin_manager_real_list_plugins(GPluginManager *manager)
 {
+	GPluginManagerPrivate *priv = NULL;
 	GQueue *queue = g_queue_new();
 	GList *ret = NULL;
 	GHashTableIter iter;
 	gpointer key = NULL;
 
-	g_hash_table_iter_init(&iter, manager->plugins);
+	priv = gplugin_manager_get_instance_private(manager);
+
+	g_hash_table_iter_init(&iter, priv->plugins);
 	while(g_hash_table_iter_next(&iter, &key, NULL)) {
 		g_queue_push_tail(queue, (gchar *)key);
 	}
@@ -1125,7 +1127,7 @@
 
 static gboolean
 gplugin_manager_loading_cb(
-	G_GNUC_UNUSED GObject *manager,
+	G_GNUC_UNUSED GPluginManager *manager,
 	G_GNUC_UNUSED GPluginPlugin *plugin,
 	G_GNUC_UNUSED GError **error)
 {
@@ -1134,7 +1136,7 @@
 
 static gboolean
 gplugin_manager_unloading_cb(
-	G_GNUC_UNUSED GObject *manager,
+	G_GNUC_UNUSED GPluginManager *manager,
 	G_GNUC_UNUSED GPluginPlugin *plugin,
 	G_GNUC_UNUSED GError **error)
 {
@@ -1148,36 +1150,37 @@
 gplugin_manager_finalize(GObject *obj)
 {
 	GPluginManager *manager = GPLUGIN_MANAGER(obj);
+	GPluginManagerPrivate *priv = gplugin_manager_get_instance_private(manager);
 
-	g_queue_free_full(manager->paths, g_free);
-	manager->paths = NULL;
+	g_queue_free_full(priv->paths, g_free);
+	priv->paths = NULL;
 
 	/* unload all of the loaded plugins */
 	g_hash_table_foreach(
-		manager->plugins,
+		priv->plugins,
 		gplugin_manager_foreach_unload_plugin,
 		NULL);
 
 	/* free all the data in the plugins hash table and destroy it */
 	g_hash_table_foreach_remove(
-		manager->plugins,
+		priv->plugins,
 		gplugin_manager_remove_list_value,
 		NULL);
-	g_clear_pointer(&manager->plugins, g_hash_table_destroy);
+	g_clear_pointer(&priv->plugins, g_hash_table_destroy);
 
 	/* destroy the filename view */
-	g_clear_pointer(&manager->plugins_filename_view, g_hash_table_destroy);
+	g_clear_pointer(&priv->plugins_filename_view, g_hash_table_destroy);
 
 	/* clean up our list of loaders */
-	g_slist_free_full(manager->loaders, g_object_unref);
-	manager->loaders = NULL;
+	g_slist_free_full(priv->loaders, g_object_unref);
+	priv->loaders = NULL;
 
 	/* free all the data in the loaders hash table and destroy it */
 	g_hash_table_foreach_remove(
-		manager->loaders_by_extension,
+		priv->loaders_by_extension,
 		gplugin_manager_remove_list_value,
 		NULL);
-	g_clear_pointer(&manager->loaders_by_extension, g_hash_table_destroy);
+	g_clear_pointer(&priv->loaders_by_extension, g_hash_table_destroy);
 
 	/* call the base class's destructor */
 	G_OBJECT_CLASS(gplugin_manager_parent_class)->finalize(obj);
@@ -1223,7 +1226,7 @@
 
 	/**
 	 * GPluginManager::loading-plugin:
-	 * @manager: The #GPluginManager instance.  Treat as a #GObject.
+	 * @manager: The #GPluginManager instance.
 	 * @plugin: The #GPluginPlugin that's about to be loaded.
 	 * @error: Return address for a #GError.
 	 *
@@ -1246,7 +1249,7 @@
 
 	/**
 	 * GPluginManager::loaded-plugin:
-	 * @manager: the #gpluginpluginmanager instance.  treat as a #gobject.
+	 * @manager: the #gpluginpluginmanager instance.
 	 * @plugin: the #gpluginplugin that's about to be loaded.
 	 *
 	 * emitted after a plugin is loaded.
@@ -1265,7 +1268,7 @@
 
 	/**
 	 * GPluginManager::load-plugin-failed:
-	 * @manager: The #GPluginPluginManager instance.
+	 * @manager: The #GPluginManager instance.
 	 * @plugin: The #GPluginPlugin that failed to load.
 	 *
 	 * emitted after a plugin fails to load.
@@ -1283,9 +1286,10 @@
 		G_TYPE_OBJECT);
 
 	/**
-	 * GPluginManager::unloading-plugin:
-	 * @manager: the #GPluginPluginManager instance.  treat as a #GObject.
-	 * @plugin: the #GPluginPlugin that's about to be loaded.
+	 * GPluginManager::unloading-plugin
+	 * @manager: the #GPluginManager instance.
+	 * @plugin: the #GPluginPlugin that's about to be unloaded.
+	 * @error: Return address for a #GError.
 	 *
 	 * emitted before a plugin is unloaded.
 	 *
@@ -1306,7 +1310,7 @@
 
 	/**
 	 * GPluginManager::unloaded-plugin:
-	 * @manager: the #gpluginpluginmanager instance.  treat as a #gobject.
+	 * @manager: the #gpluginpluginmanager instance.
 	 * @plugin: the #gpluginplugin that's about to be loaded.
 	 *
 	 * emitted after a plugin is successfully unloaded.
@@ -1348,18 +1352,20 @@
 static void
 gplugin_manager_init(GPluginManager *manager)
 {
-	manager->paths = g_queue_new();
+	GPluginManagerPrivate *priv = gplugin_manager_get_instance_private(manager);
+
+	priv->paths = g_queue_new();
 
 	/* the plugins hashtable is keyed on a plugin id and holds a GSList of all
 	 * plugins that share that id.
 	 */
-	manager->plugins =
+	priv->plugins =
 		g_hash_table_new_full(g_str_hash, g_str_equal, g_free, NULL);
 
 	/* the filename view is hash table keyed on the filename of the plugin with
 	 * a value of the plugin itself.
 	 */
-	manager->plugins_filename_view =
+	priv->plugins_filename_view =
 		g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_object_unref);
 
 	/* The loaders_by_extension hash table is keyed on the supported extensions
@@ -1373,7 +1379,7 @@
 	 * to use by the filename and helps us to avoid iterating the loaders table
 	 * again and again.
 	 */
-	manager->loaders_by_extension = g_hash_table_new_full(
+	priv->loaders_by_extension = g_hash_table_new_full(
 		gplugin_manager_str_hash,
 		g_str_equal,
 		g_free,
@@ -1431,15 +1437,13 @@
 void
 gplugin_manager_append_path(const gchar *path)
 {
-	GPluginManager *manager = GPLUGIN_MANAGER_INSTANCE;
 	GPluginManagerClass *klass = NULL;
 
-	g_return_if_fail(GPLUGIN_IS_MANAGER(manager));
+	g_return_if_fail(GPLUGIN_IS_MANAGER(instance));
 
-	klass = GPLUGIN_MANAGER_GET_CLASS(manager);
-
+	klass = GPLUGIN_MANAGER_GET_CLASS(instance);
 	if(klass && klass->append_path)
-		klass->append_path(manager, path);
+		klass->append_path(instance, path);
 }
 
 /**
@@ -1451,15 +1455,13 @@
 void
 gplugin_manager_prepend_path(const gchar *path)
 {
-	GPluginManager *manager = GPLUGIN_MANAGER_INSTANCE;
 	GPluginManagerClass *klass = NULL;
 
-	g_return_if_fail(GPLUGIN_IS_MANAGER(manager));
+	g_return_if_fail(GPLUGIN_IS_MANAGER(instance));
 
-	klass = GPLUGIN_MANAGER_GET_CLASS(manager);
-
+	klass = GPLUGIN_MANAGER_GET_CLASS(instance);
 	if(klass && klass->prepend_path)
-		klass->prepend_path(manager, path);
+		klass->prepend_path(instance, path);
 }
 
 /**
@@ -1471,15 +1473,13 @@
 void
 gplugin_manager_remove_path(const gchar *path)
 {
-	GPluginManager *manager = GPLUGIN_MANAGER_INSTANCE;
 	GPluginManagerClass *klass = NULL;
 
-	g_return_if_fail(GPLUGIN_IS_MANAGER(manager));
+	g_return_if_fail(GPLUGIN_IS_MANAGER(instance));
 
-	klass = GPLUGIN_MANAGER_GET_CLASS(manager);
-
+	klass = GPLUGIN_MANAGER_GET_CLASS(instance);
 	if(klass && klass->remove_path)
-		klass->remove_path(manager, path);
+		klass->remove_path(instance, path);
 }
 
 /**
@@ -1490,15 +1490,13 @@
 void
 gplugin_manager_remove_paths(void)
 {
-	GPluginManager *manager = GPLUGIN_MANAGER_INSTANCE;
 	GPluginManagerClass *klass = NULL;
 
-	g_return_if_fail(GPLUGIN_IS_MANAGER(manager));
+	g_return_if_fail(GPLUGIN_IS_MANAGER(instance));
 
-	klass = GPLUGIN_MANAGER_GET_CLASS(manager);
-
+	klass = GPLUGIN_MANAGER_GET_CLASS(instance);
 	if(klass && klass->remove_paths)
-		klass->remove_paths(manager);
+		klass->remove_paths(instance);
 }
 
 /**
@@ -1558,14 +1556,13 @@
 GList *
 gplugin_manager_get_paths(void)
 {
-	GPluginManager *manager = GPLUGIN_MANAGER_INSTANCE;
 	GPluginManagerClass *klass = NULL;
 
-	g_return_val_if_fail(GPLUGIN_IS_MANAGER(manager), NULL);
+	g_return_val_if_fail(GPLUGIN_IS_MANAGER(instance), NULL);
 
-	klass = GPLUGIN_MANAGER_GET_CLASS(manager);
+	klass = GPLUGIN_MANAGER_GET_CLASS(instance);
 	if(klass && klass->get_paths)
-		return klass->get_paths(manager);
+		return klass->get_paths(instance);
 
 	return NULL;
 }
@@ -1583,14 +1580,13 @@
 gboolean
 gplugin_manager_register_loader(GType type, GError **error)
 {
-	GPluginManager *manager = GPLUGIN_MANAGER_INSTANCE;
 	GPluginManagerClass *klass = NULL;
 
-	g_return_val_if_fail(GPLUGIN_IS_MANAGER(manager), FALSE);
+	g_return_val_if_fail(GPLUGIN_IS_MANAGER(instance), FALSE);
 
-	klass = GPLUGIN_MANAGER_GET_CLASS(manager);
+	klass = GPLUGIN_MANAGER_GET_CLASS(instance);
 	if(klass && klass->register_loader)
-		return klass->register_loader(manager, type, error);
+		return klass->register_loader(instance, type, error);
 
 	g_set_error(
 		error,
@@ -1614,14 +1610,13 @@
 gboolean
 gplugin_manager_unregister_loader(GType type, GError **error)
 {
-	GPluginManager *manager = GPLUGIN_MANAGER_INSTANCE;
 	GPluginManagerClass *klass = NULL;
 
-	g_return_val_if_fail(GPLUGIN_IS_MANAGER(manager), FALSE);
+	g_return_val_if_fail(GPLUGIN_IS_MANAGER(instance), FALSE);
 
-	klass = GPLUGIN_MANAGER_GET_CLASS(manager);
+	klass = GPLUGIN_MANAGER_GET_CLASS(instance);
 	if(klass && klass->unregister_loader)
-		return klass->unregister_loader(manager, type, error);
+		return klass->unregister_loader(instance, type, error);
 
 	g_set_error(
 		error,
@@ -1643,14 +1638,13 @@
 GSList *
 gplugin_manager_get_loaders(void)
 {
-	GPluginManager *manager = GPLUGIN_MANAGER_INSTANCE;
 	GPluginManagerClass *klass = NULL;
 
-	g_return_val_if_fail(GPLUGIN_IS_MANAGER(manager), FALSE);
+	g_return_val_if_fail(GPLUGIN_IS_MANAGER(instance), FALSE);
 
-	klass = GPLUGIN_MANAGER_GET_CLASS(manager);
+	klass = GPLUGIN_MANAGER_GET_CLASS(instance);
 	if(klass && klass->get_loaders)
-		return klass->get_loaders(manager);
+		return klass->get_loaders(instance);
 
 	return NULL;
 }
@@ -1663,14 +1657,13 @@
 void
 gplugin_manager_refresh(void)
 {
-	GPluginManager *manager = GPLUGIN_MANAGER_INSTANCE;
 	GPluginManagerClass *klass = NULL;
 
-	g_return_if_fail(GPLUGIN_IS_MANAGER(manager));
+	g_return_if_fail(GPLUGIN_IS_MANAGER(instance));
 
-	klass = GPLUGIN_MANAGER_GET_CLASS(manager);
+	klass = GPLUGIN_MANAGER_GET_CLASS(instance);
 	if(klass && klass->refresh)
-		klass->refresh(manager);
+		klass->refresh(instance);
 }
 
 /**
@@ -1683,15 +1676,14 @@
 void
 gplugin_manager_foreach(GPluginManagerForeachFunc func, gpointer data)
 {
-	GPluginManager *manager = GPLUGIN_MANAGER_INSTANCE;
 	GPluginManagerClass *klass = NULL;
 
-	g_return_if_fail(GPLUGIN_IS_MANAGER(manager));
+	g_return_if_fail(GPLUGIN_IS_MANAGER(instance));
 	g_return_if_fail(func != NULL);
 
-	klass = GPLUGIN_MANAGER_GET_CLASS(manager);
+	klass = GPLUGIN_MANAGER_GET_CLASS(instance);
 	if(klass && klass->foreach)
-		klass->foreach(manager, func, data);
+		klass->foreach(instance, func, data);
 }
 
 /**
@@ -1708,14 +1700,13 @@
 GSList *
 gplugin_manager_find_plugins(const gchar *id)
 {
-	GPluginManager *manager = GPLUGIN_MANAGER_INSTANCE;
 	GPluginManagerClass *klass = NULL;
 
-	g_return_val_if_fail(GPLUGIN_IS_MANAGER(manager), NULL);
+	g_return_val_if_fail(GPLUGIN_IS_MANAGER(instance), NULL);
 
-	klass = GPLUGIN_MANAGER_GET_CLASS(manager);
+	klass = GPLUGIN_MANAGER_GET_CLASS(instance);
 	if(klass && klass->find_plugins)
-		return klass->find_plugins(manager, id);
+		return klass->find_plugins(instance, id);
 
 	return NULL;
 }
@@ -1742,10 +1733,9 @@
 	const gchar *op,
 	const gchar *version)
 {
-	GPluginManager *manager = GPLUGIN_MANAGER_INSTANCE;
 	GSList *plugins = NULL, *filtered = NULL, *l = NULL;
 
-	g_return_val_if_fail(GPLUGIN_IS_MANAGER(manager), NULL);
+	g_return_val_if_fail(GPLUGIN_IS_MANAGER(instance), NULL);
 
 	plugins = gplugin_manager_find_plugins(id);
 
@@ -1811,14 +1801,13 @@
 GSList *
 gplugin_manager_find_plugins_with_state(GPluginPluginState state)
 {
-	GPluginManager *manager = GPLUGIN_MANAGER_INSTANCE;
 	GPluginManagerClass *klass = NULL;
 
-	g_return_val_if_fail(GPLUGIN_IS_MANAGER(manager), NULL);
+	g_return_val_if_fail(GPLUGIN_IS_MANAGER(instance), NULL);
 
-	klass = GPLUGIN_MANAGER_GET_CLASS(manager);
+	klass = GPLUGIN_MANAGER_GET_CLASS(instance);
 	if(klass && klass->find_plugins_with_state)
-		return klass->find_plugins_with_state(manager, state);
+		return klass->find_plugins_with_state(instance, state);
 
 	return NULL;
 }
@@ -1941,17 +1930,15 @@
 GSList *
 gplugin_manager_get_plugin_dependencies(GPluginPlugin *plugin, GError **error)
 {
-	GPluginManager *manager = NULL;
 	GPluginManagerClass *klass = NULL;
 
 	g_return_val_if_fail(GPLUGIN_IS_PLUGIN(plugin), NULL);
 
-	manager = GPLUGIN_MANAGER_INSTANCE;
-	g_return_val_if_fail(GPLUGIN_IS_MANAGER(manager), NULL);
+	g_return_val_if_fail(GPLUGIN_IS_MANAGER(instance), NULL);
 
-	klass = GPLUGIN_MANAGER_GET_CLASS(manager);
+	klass = GPLUGIN_MANAGER_GET_CLASS(instance);
 	if(klass && klass->get_plugin_dependencies) {
-		return klass->get_plugin_dependencies(manager, plugin, error);
+		return klass->get_plugin_dependencies(instance, plugin, error);
 	}
 
 	return NULL;
@@ -1972,17 +1959,15 @@
 gboolean
 gplugin_manager_load_plugin(GPluginPlugin *plugin, GError **error)
 {
-	GPluginManager *manager = NULL;
 	GPluginManagerClass *klass = NULL;
 
 	g_return_val_if_fail(GPLUGIN_IS_PLUGIN(plugin), FALSE);
 
-	manager = GPLUGIN_MANAGER_INSTANCE;
-	g_return_val_if_fail(GPLUGIN_IS_MANAGER(manager), FALSE);
+	g_return_val_if_fail(GPLUGIN_IS_MANAGER(instance), FALSE);
 
-	klass = GPLUGIN_MANAGER_GET_CLASS(manager);
+	klass = GPLUGIN_MANAGER_GET_CLASS(instance);
 	if(klass && klass->load_plugin)
-		return klass->load_plugin(manager, plugin, error);
+		return klass->load_plugin(instance, plugin, error);
 
 	return FALSE;
 }
@@ -2000,17 +1985,15 @@
 gboolean
 gplugin_manager_unload_plugin(GPluginPlugin *plugin, GError **error)
 {
-	GPluginManager *manager = NULL;
 	GPluginManagerClass *klass = NULL;
 
 	g_return_val_if_fail(GPLUGIN_IS_PLUGIN(plugin), FALSE);
 
-	manager = GPLUGIN_MANAGER_INSTANCE;
-	g_return_val_if_fail(GPLUGIN_IS_MANAGER(manager), FALSE);
+	g_return_val_if_fail(GPLUGIN_IS_MANAGER(instance), FALSE);
 
-	klass = GPLUGIN_MANAGER_GET_CLASS(manager);
+	klass = GPLUGIN_MANAGER_GET_CLASS(instance);
 	if(klass && klass->unload_plugin)
-		return klass->unload_plugin(manager, plugin, error);
+		return klass->unload_plugin(instance, plugin, error);
 
 	return FALSE;
 }
@@ -2027,14 +2010,13 @@
 GList *
 gplugin_manager_list_plugins(void)
 {
-	GPluginManager *manager = GPLUGIN_MANAGER_INSTANCE;
 	GPluginManagerClass *klass = NULL;
 
-	g_return_val_if_fail(GPLUGIN_IS_MANAGER(manager), NULL);
+	g_return_val_if_fail(GPLUGIN_IS_MANAGER(instance), NULL);
 
-	klass = GPLUGIN_MANAGER_GET_CLASS(manager);
+	klass = GPLUGIN_MANAGER_GET_CLASS(instance);
 	if(klass && klass->list_plugins)
-		return klass->list_plugins(manager);
+		return klass->list_plugins(instance);
 
 	return NULL;
 }
@@ -2051,11 +2033,8 @@
  * Returns: (transfer none): The #GObject that is the instance of the plugin
  *                           manager.
  */
-GObject *
+GPluginManager *
 gplugin_manager_get_instance(void)
 {
-	if(instance)
-		return G_OBJECT(instance);
-
-	return NULL;
+	return instance;
 }
diff --git a/gplugin/tests/test-signals.c b/gplugin/tests/test-signals.c
--- a/gplugin/tests/test-signals.c
+++ b/gplugin/tests/test-signals.c
@@ -142,7 +142,7 @@
 test_gplugin_manager_signals_normal(void)
 {
 	GPluginPlugin *plugin = NULL;
-	GObject *manager = gplugin_manager_get_instance();
+	GPluginManager *manager = gplugin_manager_get_instance();
 	GError *error = NULL;
 	TestGPluginManagerSignalsData data = {
 		.loading = FALSE,
@@ -197,7 +197,7 @@
 test_gplugin_manager_signals_loading_stopped(void)
 {
 	GPluginPlugin *plugin = NULL;
-	GObject *manager = gplugin_manager_get_instance();
+	GPluginManager *manager = gplugin_manager_get_instance();
 	GError *error = NULL;
 	TestGPluginManagerSignalsData data = {
 		.loading = FALSE,
@@ -251,7 +251,7 @@
 test_gplugin_manager_signals_unloading_stopped(void)
 {
 	GPluginPlugin *plugin = NULL;
-	GObject *manager = gplugin_manager_get_instance();
+	GPluginManager *manager = gplugin_manager_get_instance();
 	GError *error = NULL;
 	TestGPluginManagerSignalsData data = {
 		.loading = FALSE,
@@ -308,7 +308,7 @@
 test_gplugin_manager_signals_load_failure(void)
 {
 	GPluginPlugin *plugin = NULL;
-	GObject *manager = gplugin_manager_get_instance();
+	GPluginManager *manager = gplugin_manager_get_instance();
 	GError *error = NULL;
 	TestGPluginManagerSignalsData data = {
 		.loading = FALSE,
@@ -346,7 +346,7 @@
 test_gplugin_manager_signals_unload_failure(void)
 {
 	GPluginPlugin *plugin = NULL;
-	GObject *manager = gplugin_manager_get_instance();
+	GPluginManager *manager = gplugin_manager_get_instance();
 	GError *error = NULL;
 	TestGPluginManagerSignalsData data = {
 		.loading = FALSE,
