diff --git a/gplugin-gtk-viewer/gplugin-gtk-viewer.c b/gplugin-gtk-viewer/gplugin-gtk-viewer.c
--- a/gplugin-gtk-viewer/gplugin-gtk-viewer.c
+++ b/gplugin-gtk-viewer/gplugin-gtk-viewer.c
@@ -181,6 +181,7 @@
 gint
 main(gint argc, gchar **argv)
 {
+	GPluginManager *manager = NULL;
 	GError *error = NULL;
 	GOptionContext *ctx = NULL;
 	GtkWidget *window = NULL;
@@ -209,17 +210,19 @@
 
 	gplugin_init(GPLUGIN_CORE_FLAGS_NONE);
 
+	manager = gplugin_manager_get_default();
+
 	if(add_default_paths)
-		gplugin_manager_add_default_paths();
+		gplugin_manager_add_default_paths(manager);
 
 	if(paths) {
 		gint i;
 
 		for(i = 0; paths[i]; i++)
-			gplugin_manager_prepend_path(paths[i]);
+			gplugin_manager_prepend_path(manager, paths[i]);
 	}
 
-	gplugin_manager_refresh();
+	gplugin_manager_refresh(manager);
 
 	/* now create and show the window */
 	window = create_window();
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
@@ -128,9 +128,12 @@
 static void
 gplugin_gtk_store_add_plugin_by_id(GPluginGtkStore *store, const gchar *id)
 {
+	GPluginManager *manager = NULL;
 	GSList *plugins = NULL, *l = NULL;
 
-	plugins = gplugin_manager_find_plugins(id);
+	manager = gplugin_manager_get_default();
+
+	plugins = gplugin_manager_find_plugins(manager, id);
 	for(l = plugins; l; l = l->next)
 		gplugin_gtk_store_add_plugin(store, GPLUGIN_PLUGIN(l->data));
 	g_slist_free_full(plugins, g_object_unref);
@@ -234,14 +237,15 @@
 
 	G_OBJECT_CLASS(gplugin_gtk_store_parent_class)->constructed(obj);
 
-	ids = gplugin_manager_list_plugins();
+	manager = gplugin_manager_get_default();
+
+	ids = gplugin_manager_list_plugins(manager);
 	for(l = ids; l; l = l->next)
 		gplugin_gtk_store_add_plugin_by_id(
 			GPLUGIN_GTK_STORE(obj),
 			(const gchar *)l->data);
 	g_list_free(ids);
 
-	manager = gplugin_manager_get_instance();
 	g_signal_connect_object(
 		manager,
 		"loaded-plugin",
diff --git a/gplugin-gtk/gplugin-gtk-view.c b/gplugin-gtk/gplugin-gtk-view.c
--- a/gplugin-gtk/gplugin-gtk-view.c
+++ b/gplugin-gtk/gplugin-gtk-view.c
@@ -71,12 +71,15 @@
 	gpointer data)
 {
 	GPluginGtkView *view = GPLUGIN_GTK_VIEW(data);
+	GPluginManager *manager = NULL;
 	GPluginPlugin *plugin = NULL;
 	GPluginPluginState state;
 	GtkTreeModel *model = NULL;
 	GtkTreeIter iter;
 	GtkTreePath *tree_path = NULL;
 
+	manager = gplugin_manager_get_default();
+
 	tree_path = gtk_tree_path_new_from_string(path);
 
 	model = gtk_tree_view_get_model(GTK_TREE_VIEW(view));
@@ -98,7 +101,7 @@
 	if(state == GPLUGIN_PLUGIN_STATE_LOADED) {
 		GError *error = NULL;
 
-		gplugin_manager_unload_plugin(plugin, &error);
+		gplugin_manager_unload_plugin(manager, plugin, &error);
 
 		if(error != NULL) {
 			g_warning("Failed to unload plugin: %s", error->message);
@@ -108,7 +111,7 @@
 	} else {
 		GError *error = NULL;
 
-		gplugin_manager_load_plugin(plugin, &error);
+		gplugin_manager_load_plugin(manager, plugin, &error);
 
 		if(error != NULL) {
 			g_warning("Failed to load plugin: %s", error->message);
diff --git a/gplugin-query/gplugin-query.c b/gplugin-query/gplugin-query.c
--- a/gplugin-query/gplugin-query.c
+++ b/gplugin-query/gplugin-query.c
@@ -100,6 +100,7 @@
 static gboolean
 output_plugin(const gchar *id)
 {
+	GPluginManager *manager = gplugin_manager_get_default();
 	GSList *plugins = NULL, *l = NULL;
 	gboolean first = TRUE, header_output = FALSE;
 
@@ -108,7 +109,7 @@
 #define MAIN_FORMAT MAIN_FORMAT_NEL "%s\n"
 #define STR_OR_EMPTY(str) ((str) ? (str) : "")
 
-	plugins = gplugin_manager_find_plugins(id);
+	plugins = gplugin_manager_find_plugins(manager, id);
 	if(plugins == NULL) {
 		printf("%s not found\n", id);
 
@@ -291,6 +292,7 @@
 gint
 main(gint argc, gchar **argv)
 {
+	GPluginManager *manager = NULL;
 	GError *error = NULL;
 	GOptionContext *ctx = NULL;
 	GOptionGroup *group = NULL;
@@ -322,10 +324,13 @@
 	 */
 	gplugin_init(GPLUGIN_CORE_FLAGS_NONE);
 
+	manager = gplugin_manager_get_default();
+
 	if(output_paths) {
 		GList *path = NULL;
 
-		for(path = gplugin_manager_get_paths(); path; path = path->next) {
+		for(path = gplugin_manager_get_paths(manager); path;
+			path = path->next) {
 			printf("%s\n", (gchar *)path->data);
 		}
 
@@ -338,7 +343,7 @@
 		return 0;
 	}
 
-	gplugin_manager_refresh();
+	gplugin_manager_refresh(manager);
 
 	/* check if the user gave us atleast one plugin, and output them */
 	if(argc > 1) {
@@ -359,7 +364,7 @@
 
 		g_queue_free(plugins);
 	} else {
-		GList *plugins = gplugin_manager_list_plugins();
+		GList *plugins = gplugin_manager_list_plugins(manager);
 
 		if(!output_plugins(plugins))
 			ret = EXIT_FAILURE;
diff --git a/gplugin/gplugin-loader-tests.c b/gplugin/gplugin-loader-tests.c
--- a/gplugin/gplugin-loader-tests.c
+++ b/gplugin/gplugin-loader-tests.c
@@ -36,6 +36,7 @@
 static void
 gplugin_test_loader_full(gconstpointer d)
 {
+	GPluginManager *manager = gplugin_manager_get_default();
 	GPluginPlugin *plugin = NULL;
 	GPluginPluginInfo *info = NULL;
 	GError *error = NULL;
@@ -45,7 +46,7 @@
 	gint i;
 
 	id = g_strdup_printf("gplugin/%s-basic-plugin", (const gchar *)d);
-	plugin = gplugin_manager_find_plugin(id);
+	plugin = gplugin_manager_find_plugin(manager, id);
 	g_assert_nonnull(plugin);
 
 	info = gplugin_plugin_get_info(plugin);
@@ -78,14 +79,14 @@
 		==,
 		GPLUGIN_PLUGIN_STATE_QUERIED);
 
-	gplugin_manager_load_plugin(plugin, &error);
+	gplugin_manager_load_plugin(manager, plugin, &error);
 	g_assert_no_error(error);
 	g_assert_cmpint(
 		gplugin_plugin_get_state(plugin),
 		==,
 		GPLUGIN_PLUGIN_STATE_LOADED);
 
-	gplugin_manager_unload_plugin(plugin, &error);
+	gplugin_manager_unload_plugin(manager, plugin, &error);
 	g_assert_no_error(error);
 	g_assert_cmpint(
 		gplugin_plugin_get_state(plugin),
@@ -98,17 +99,18 @@
 static void
 gplugin_test_loader_load_failed(gconstpointer d)
 {
+	GPluginManager *manager = gplugin_manager_get_default();
 	GPluginPlugin *plugin = NULL;
 	GError *error = NULL;
 	gchar *id = NULL;
 	gboolean ret = FALSE;
 
 	id = g_strdup_printf("gplugin/%s-load-failed", (const gchar *)d);
-	plugin = gplugin_manager_find_plugin(id);
+	plugin = gplugin_manager_find_plugin(manager, id);
 	g_free(id);
 	g_assert_nonnull(plugin);
 
-	ret = gplugin_manager_load_plugin(plugin, &error);
+	ret = gplugin_manager_load_plugin(manager, plugin, &error);
 	g_assert_false(ret);
 
 	g_assert_error(error, GPLUGIN_DOMAIN, 0);
@@ -130,17 +132,18 @@
 static void
 gplugin_test_loader_load_exception(gconstpointer d)
 {
+	GPluginManager *manager = gplugin_manager_get_default();
 	GPluginPlugin *plugin = NULL;
 	GError *error = NULL;
 	gchar *id = NULL;
 	gboolean ret = FALSE;
 
 	id = g_strdup_printf("gplugin/%s-load-exception", (const gchar *)d);
-	plugin = gplugin_manager_find_plugin(id);
+	plugin = gplugin_manager_find_plugin(manager, id);
 	g_free(id);
 	g_assert_nonnull(plugin);
 
-	ret = gplugin_manager_load_plugin(plugin, &error);
+	ret = gplugin_manager_load_plugin(manager, plugin, &error);
 	g_assert_false(ret);
 
 	g_assert_error(error, GPLUGIN_DOMAIN, 0);
@@ -162,17 +165,18 @@
 static void
 gplugin_test_loader_unload_failed(gconstpointer d)
 {
+	GPluginManager *manager = gplugin_manager_get_default();
 	GPluginPlugin *plugin = NULL;
 	GError *error = NULL;
 	gchar *id = NULL;
 	gboolean ret = FALSE;
 
 	id = g_strdup_printf("gplugin/%s-unload-failed", (const gchar *)d);
-	plugin = gplugin_manager_find_plugin(id);
+	plugin = gplugin_manager_find_plugin(manager, id);
 	g_free(id);
 	g_assert_nonnull(plugin);
 
-	ret = gplugin_manager_load_plugin(plugin, &error);
+	ret = gplugin_manager_load_plugin(manager, plugin, &error);
 	g_assert_no_error(error);
 	g_assert_true(ret);
 	g_assert_cmpint(
@@ -180,7 +184,7 @@
 		==,
 		GPLUGIN_PLUGIN_STATE_LOADED);
 
-	ret = gplugin_manager_unload_plugin(plugin, &error);
+	ret = gplugin_manager_unload_plugin(manager, plugin, &error);
 	g_assert_false(ret);
 
 	g_assert_error(error, GPLUGIN_DOMAIN, 0);
@@ -202,6 +206,7 @@
 static void
 gplugin_test_loader_dependencies(gconstpointer d)
 {
+	GPluginManager *manager = gplugin_manager_get_default();
 	GPluginPlugin *plugin = NULL;
 	GPluginPluginInfo *info = NULL;
 	gchar *id = NULL;
@@ -210,7 +215,7 @@
 	gint i = 0;
 
 	id = g_strdup_printf("gplugin/%s-dependent-plugin", (const gchar *)d);
-	plugin = gplugin_manager_find_plugin(id);
+	plugin = gplugin_manager_find_plugin(manager, id);
 	g_free(id);
 	g_assert_nonnull(plugin);
 
@@ -256,17 +261,23 @@
 	const gchar *plugin_dir,
 	const gchar *short_name)
 {
+	GPluginManager *manager = NULL;
+
 	gplugin_init(GPLUGIN_CORE_FLAGS_NONE);
 
+	manager = gplugin_manager_get_default();
+
 	g_setenv("GI_TYPELIB_PATH", GI_TYPELIB_PATH, TRUE);
 
-	if(loader_dir)
-		gplugin_manager_append_path(loader_dir);
+	if(loader_dir) {
+		gplugin_manager_append_path(manager, loader_dir);
+	}
 
-	if(plugin_dir)
-		gplugin_manager_append_path(plugin_dir);
+	if(plugin_dir) {
+		gplugin_manager_append_path(manager, plugin_dir);
+	}
 
-	gplugin_manager_refresh();
+	gplugin_manager_refresh(manager);
 
 	gplugin_loader_tests_add_tests(short_name);
 }
diff --git a/gplugin/gplugin-manager.h b/gplugin/gplugin-manager.h
--- a/gplugin/gplugin-manager.h
+++ b/gplugin/gplugin-manager.h
@@ -46,50 +46,6 @@
 	/*< 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,
@@ -109,44 +65,70 @@
 	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);
-void gplugin_manager_remove_paths(void);
+void gplugin_manager_append_path(GPluginManager *manager, const gchar *path);
+void gplugin_manager_prepend_path(GPluginManager *manager, const gchar *path);
+void gplugin_manager_remove_path(GPluginManager *manager, const gchar *path);
+void gplugin_manager_remove_paths(GPluginManager *manager);
 
-void gplugin_manager_add_default_paths(void);
-void gplugin_manager_add_app_paths(const gchar *prefix, const gchar *appname);
+void gplugin_manager_add_default_paths(GPluginManager *manager);
+void gplugin_manager_add_app_paths(
+	GPluginManager *manager,
+	const gchar *prefix,
+	const gchar *appname);
 
-GList *gplugin_manager_get_paths(void);
+GList *gplugin_manager_get_paths(GPluginManager *manager);
 
-gboolean gplugin_manager_register_loader(GType type, GError **error);
-gboolean gplugin_manager_unregister_loader(GType type, GError **error);
-GSList *gplugin_manager_get_loaders(void);
+gboolean gplugin_manager_register_loader(
+	GPluginManager *manager,
+	GType type,
+	GError **error);
+gboolean gplugin_manager_unregister_loader(
+	GPluginManager *manager,
+	GType type,
+	GError **error);
+GSList *gplugin_manager_get_loaders(GPluginManager *manager);
 
-void gplugin_manager_refresh(void);
+void gplugin_manager_refresh(GPluginManager *manager);
 
-void gplugin_manager_foreach(GPluginManagerForeachFunc func, gpointer data);
+void gplugin_manager_foreach(
+	GPluginManager *manager,
+	GPluginManagerForeachFunc func,
+	gpointer data);
 
-GSList *gplugin_manager_find_plugins(const gchar *id);
+GSList *gplugin_manager_find_plugins(GPluginManager *manager, const gchar *id);
 GSList *gplugin_manager_find_plugins_with_version(
+	GPluginManager *manager,
 	const gchar *id,
 	const gchar *op,
 	const gchar *version);
-GSList *gplugin_manager_find_plugins_with_state(GPluginPluginState state);
+GSList *gplugin_manager_find_plugins_with_state(
+	GPluginManager *manager,
+	GPluginPluginState state);
 
-GPluginPlugin *gplugin_manager_find_plugin(const gchar *id);
-GPluginPlugin *gplugin_manager_find_plugin_with_newest_version(const gchar *id);
+GPluginPlugin *gplugin_manager_find_plugin(
+	GPluginManager *manager,
+	const gchar *id);
+GPluginPlugin *gplugin_manager_find_plugin_with_newest_version(
+	GPluginManager *manager,
+	const gchar *id);
 
 GSList *gplugin_manager_get_plugin_dependencies(
+	GPluginManager *manager,
 	GPluginPlugin *plugin,
 	GError **error);
 
-gboolean gplugin_manager_load_plugin(GPluginPlugin *plugin, GError **error);
-gboolean gplugin_manager_unload_plugin(GPluginPlugin *plugin, GError **error);
+gboolean gplugin_manager_load_plugin(
+	GPluginManager *manager,
+	GPluginPlugin *plugin,
+	GError **error);
+gboolean gplugin_manager_unload_plugin(
+	GPluginManager *manager,
+	GPluginPlugin *plugin,
+	GError **error);
 
-GList *gplugin_manager_list_plugins(void);
+GList *gplugin_manager_list_plugins(GPluginManager *manager);
 
-GPluginManager *gplugin_manager_get_instance(void);
+GPluginManager *gplugin_manager_get_default(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
@@ -47,42 +47,6 @@
 
 /**
  * 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 path 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.
@@ -92,6 +56,7 @@
  *
  * Virtual function table for #GPluginManager.
  */
+
 /******************************************************************************
  * Enums
  *****************************************************************************/
@@ -126,7 +91,7 @@
 /******************************************************************************
  * Globals
  *****************************************************************************/
-GPluginManager *instance = NULL;
+GPluginManager *default_manager = NULL;
 static guint signals[N_SIGNALS] = {
 	0,
 };
@@ -249,19 +214,344 @@
 	return r;
 }
 
+static gboolean
+gplugin_manager_load_dependencies(
+	GPluginManager *manager,
+	GPluginPlugin *plugin,
+	GPluginPluginInfo *info,
+	GError **error)
+{
+	GSList *dependencies = NULL, *l = NULL;
+	GError *ourerror = NULL;
+	gboolean all_loaded = TRUE;
+
+	dependencies =
+		gplugin_manager_get_plugin_dependencies(manager, plugin, &ourerror);
+	if(ourerror != NULL) {
+		g_propagate_error(error, ourerror);
+
+		return FALSE;
+	}
+
+	for(l = dependencies; l != NULL; l = l->next) {
+		GPluginPlugin *dependency = GPLUGIN_PLUGIN(l->data);
+		gboolean loaded = FALSE;
+
+		loaded = gplugin_manager_load_plugin(manager, dependency, &ourerror);
+
+		if(!loaded || ourerror != NULL) {
+			if(ourerror != NULL) {
+				g_propagate_error(error, ourerror);
+			}
+
+			all_loaded = FALSE;
+			break;
+		}
+	}
+
+	g_slist_free_full(dependencies, g_object_unref);
+
+	return all_loaded;
+}
+
 /******************************************************************************
  * Manager implementation
  *****************************************************************************/
+static gboolean
+gplugin_manager_loading_cb(
+	G_GNUC_UNUSED GPluginManager *manager,
+	G_GNUC_UNUSED GPluginPlugin *plugin,
+	G_GNUC_UNUSED GError **error)
+{
+	return TRUE;
+}
+
+static gboolean
+gplugin_manager_unloading_cb(
+	G_GNUC_UNUSED GPluginManager *manager,
+	G_GNUC_UNUSED GPluginPlugin *plugin,
+	G_GNUC_UNUSED GError **error)
+{
+	return TRUE;
+}
+
+/******************************************************************************
+ * GObject Implementation
+ *****************************************************************************/
 static void
-gplugin_manager_real_append_path(GPluginManager *manager, const gchar *path)
+gplugin_manager_finalize(GObject *obj)
+{
+	GPluginManager *manager = GPLUGIN_MANAGER(obj);
+	GPluginManagerPrivate *priv = gplugin_manager_get_instance_private(manager);
+
+	g_queue_free_full(priv->paths, g_free);
+	priv->paths = NULL;
+
+	/* unload all of the loaded plugins */
+	g_hash_table_foreach(
+		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(
+		priv->plugins,
+		gplugin_manager_remove_list_value,
+		NULL);
+	g_clear_pointer(&priv->plugins, g_hash_table_destroy);
+
+	/* destroy the filename view */
+	g_clear_pointer(&priv->plugins_filename_view, g_hash_table_destroy);
+
+	/* clean up our list of loaders */
+	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(
+		priv->loaders_by_extension,
+		gplugin_manager_remove_list_value,
+		NULL);
+	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);
+}
+
+static void
+gplugin_manager_class_init(GPluginManagerClass *klass)
+{
+	GObjectClass *obj_class = G_OBJECT_CLASS(klass);
+	GPluginManagerClass *manager_class = GPLUGIN_MANAGER_CLASS(klass);
+
+	obj_class->finalize = gplugin_manager_finalize;
+
+	manager_class->loading_plugin = gplugin_manager_loading_cb;
+	manager_class->unloading_plugin = gplugin_manager_unloading_cb;
+
+	/* signals */
+
+	/**
+	 * GPluginManager::loading-plugin:
+	 * @manager: The #GPluginManager instance.
+	 * @plugin: The #GPluginPlugin that's about to be loaded.
+	 * @error: Return address for a #GError.
+	 *
+	 * Emitted before @plugin is loaded.
+	 *
+	 * Return FALSE to stop loading
+	 */
+	signals[SIG_LOADING] = g_signal_new(
+		"loading-plugin",
+		G_OBJECT_CLASS_TYPE(manager_class),
+		G_SIGNAL_RUN_LAST,
+		G_STRUCT_OFFSET(GPluginManagerClass, loading_plugin),
+		gplugin_boolean_accumulator,
+		NULL,
+		NULL,
+		G_TYPE_BOOLEAN,
+		2,
+		G_TYPE_OBJECT,
+		G_TYPE_POINTER);
+
+	/**
+	 * GPluginManager::loaded-plugin:
+	 * @manager: the #gpluginpluginmanager instance.
+	 * @plugin: the #gpluginplugin that's about to be loaded.
+	 *
+	 * emitted after a plugin is loaded.
+	 */
+	signals[SIG_LOADED] = g_signal_new(
+		"loaded-plugin",
+		G_OBJECT_CLASS_TYPE(manager_class),
+		G_SIGNAL_RUN_LAST,
+		G_STRUCT_OFFSET(GPluginManagerClass, loaded_plugin),
+		NULL,
+		NULL,
+		NULL,
+		G_TYPE_NONE,
+		1,
+		G_TYPE_OBJECT);
+
+	/**
+	 * GPluginManager::load-plugin-failed:
+	 * @manager: The #GPluginManager instance.
+	 * @plugin: The #GPluginPlugin that failed to load.
+	 *
+	 * emitted after a plugin fails to load.
+	 */
+	signals[SIG_LOAD_FAILED] = g_signal_new(
+		"load-plugin-failed",
+		G_OBJECT_CLASS_TYPE(manager_class),
+		G_SIGNAL_RUN_LAST,
+		G_STRUCT_OFFSET(GPluginManagerClass, load_failed),
+		NULL,
+		NULL,
+		NULL,
+		G_TYPE_NONE,
+		1,
+		G_TYPE_OBJECT);
+
+	/**
+	 * 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.
+	 *
+	 * Return FALSE to stop unloading
+	 */
+	signals[SIG_UNLOADING] = g_signal_new(
+		"unloading-plugin",
+		G_OBJECT_CLASS_TYPE(manager_class),
+		G_SIGNAL_RUN_LAST,
+		G_STRUCT_OFFSET(GPluginManagerClass, unloading_plugin),
+		gplugin_boolean_accumulator,
+		NULL,
+		NULL,
+		G_TYPE_BOOLEAN,
+		2,
+		G_TYPE_OBJECT,
+		G_TYPE_POINTER);
+
+	/**
+	 * GPluginManager::unloaded-plugin:
+	 * @manager: the #gpluginpluginmanager instance.
+	 * @plugin: the #gpluginplugin that's about to be loaded.
+	 *
+	 * emitted after a plugin is successfully unloaded.
+	 */
+	signals[SIG_UNLOADED] = g_signal_new(
+		"unloaded-plugin",
+		G_OBJECT_CLASS_TYPE(manager_class),
+		G_SIGNAL_RUN_LAST,
+		G_STRUCT_OFFSET(GPluginManagerClass, unloaded_plugin),
+		NULL,
+		NULL,
+		NULL,
+		G_TYPE_NONE,
+		1,
+		G_TYPE_OBJECT);
+
+	/**
+	 * GPluginManager::unload-plugin-failed:
+	 * @manager: The #GPluginManager instance.
+	 * @plugin: The #GPluginPlugin instance that failed to unload.
+	 * @error: A #GError instance.
+	 *
+	 * Emitted when @manager was asked to unload @plugin, but @plugin returned
+	 * %FALSE when its unload function was called.
+	 */
+	signals[SIG_UNLOAD_FAILED] = g_signal_new(
+		"unload-plugin-failed",
+		G_OBJECT_CLASS_TYPE(manager_class),
+		G_SIGNAL_RUN_LAST,
+		G_STRUCT_OFFSET(GPluginManagerClass, unload_plugin_failed),
+		NULL,
+		NULL,
+		NULL,
+		G_TYPE_NONE,
+		1,
+		G_TYPE_OBJECT);
+}
+
+static void
+gplugin_manager_init(GPluginManager *manager)
+{
+	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.
+	 */
+	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.
+	 */
+	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
+	 * of the loader.  Which means that a loader that supports multiple
+	 * extensions will be in the table multiple times.
+	 *
+	 * We deal with collisions by using a GSList for the value which will hold
+	 * references to instances of the actual loaders.
+	 *
+	 * Storing this in this method allows us to quickly figure out which loader
+	 * to use by the filename and helps us to avoid iterating the loaders table
+	 * again and again.
+	 */
+	priv->loaders_by_extension = g_hash_table_new_full(
+		gplugin_manager_str_hash,
+		g_str_equal,
+		g_free,
+		NULL);
+}
+
+/******************************************************************************
+ * Private API
+ *****************************************************************************/
+void
+gplugin_manager_private_init(gboolean register_native_loader)
+{
+	GError *error = NULL;
+
+	if(GPLUGIN_IS_MANAGER(default_manager)) {
+		return;
+	}
+
+	default_manager = g_object_new(GPLUGIN_TYPE_MANAGER, NULL);
+
+	if(register_native_loader) {
+		if(!gplugin_manager_register_loader(
+			   default_manager,
+			   GPLUGIN_TYPE_NATIVE_LOADER,
+			   &error)) {
+			if(error != NULL) {
+				g_error("failed to register loader: %s", error->message);
+				g_error_free(error);
+			} else {
+				g_error("failed to register loader: unknown failure");
+			}
+		}
+	}
+
+	dependency_regex = g_regex_new(dependency_pattern, 0, 0, NULL);
+}
+
+void
+gplugin_manager_private_uninit(void)
+{
+	g_regex_unref(dependency_regex);
+
+	g_clear_object(&default_manager);
+}
+
+/******************************************************************************
+ * API
+ *****************************************************************************/
+
+/**
+ * gplugin_manager_append_path:
+ * @manager: The #GPluginManager instance.
+ * @path: A path to add to the end of the plugin search paths.
+ *
+ * Adds @path to the end of the list of paths to search for plugins.
+ */
+void
+gplugin_manager_append_path(GPluginManager *manager, const gchar *path)
 {
 	GPluginManagerPrivate *priv = NULL;
 	GList *l = NULL;
 	gchar *normalized = NULL;
 
-	if(!path) {
-		return;
-	}
+	g_return_if_fail(GPLUGIN_IS_MANAGER(manager));
+	g_return_if_fail(path != NULL);
 
 	normalized = gplugin_manager_normalize_path(path);
 
@@ -278,16 +568,22 @@
 	}
 }
 
-static void
-gplugin_manager_real_prepend_path(GPluginManager *manager, const gchar *path)
+/**
+ * gplugin_manager_prepend_path:
+ * @manager: The #GPluginManager instance.
+ * @path: A path to add to the beginning of the plugin search paths.
+ *
+ * Adds @path to the beginning of the list of paths to search for plugins.
+ */
+void
+gplugin_manager_prepend_path(GPluginManager *manager, const gchar *path)
 {
 	GPluginManagerPrivate *priv = NULL;
 	GList *l = NULL;
 	gchar *normalized = NULL;
 
-	if(!path) {
-		return;
-	}
+	g_return_if_fail(GPLUGIN_IS_MANAGER(manager));
+	g_return_if_fail(path != NULL);
 
 	normalized = gplugin_manager_normalize_path(path);
 
@@ -304,13 +600,21 @@
 	}
 }
 
-static void
-gplugin_manager_real_remove_path(GPluginManager *manager, const gchar *path)
+/**
+ * gplugin_manager_remove_path:
+ * @manager: The #GPluginManager instance.
+ * @path: A path to remove from the plugin search paths.
+ *
+ * Removes @path from the list of paths to search for plugins.
+ */
+void
+gplugin_manager_remove_path(GPluginManager *manager, const gchar *path)
 {
 	GPluginManagerPrivate *priv = NULL;
 	GList *l = NULL;
 	gchar *normalized = NULL;
 
+	g_return_if_fail(GPLUGIN_IS_MANAGER(manager));
 	g_return_if_fail(path != NULL);
 
 	normalized = gplugin_manager_normalize_path(path);
@@ -329,26 +633,114 @@
 	g_free(normalized);
 }
 
-static void
-gplugin_manager_real_remove_paths(GPluginManager *manager)
+/**
+ * gplugin_manager_remove_paths:
+ * @manager: The #GPluginManager instance.
+ *
+ * Clears all paths that are set to search for plugins.
+ */
+void
+gplugin_manager_remove_paths(GPluginManager *manager)
 {
-	GPluginManagerPrivate *priv = gplugin_manager_get_instance_private(manager);
+	GPluginManagerPrivate *priv = NULL;
+
+	g_return_if_fail(GPLUGIN_IS_MANAGER(manager));
+
+	priv = gplugin_manager_get_instance_private(manager);
 
 	/* g_queue_clear_full was added in 2.60 but we require 2.40 */
 	g_queue_foreach(priv->paths, (GFunc)g_free, NULL);
 	g_queue_clear(priv->paths);
 }
 
-static GList *
-gplugin_manager_real_get_paths(GPluginManager *manager)
+/**
+ * gplugin_manager_add_default_paths:
+ * @manager: The #GPluginManager instance.
+ *
+ * Adds the path that GPlugin was installed to to the plugin search path, as
+ * well as `${XDG_CONFIG_HOME}/gplugin` so users can install additional loaders
+ * themselves.
+ */
+void
+gplugin_manager_add_default_paths(GPluginManager *manager)
 {
-	GPluginManagerPrivate *priv = gplugin_manager_get_instance_private(manager);
+	gchar *path;
+
+	g_return_if_fail(GPLUGIN_IS_MANAGER(manager));
+
+	path = g_build_filename(PREFIX, LIBDIR, "gplugin", NULL);
+	gplugin_manager_prepend_path(manager, path);
+	g_free(path);
+
+	path = g_build_filename(g_get_user_config_dir(), "gplugin", NULL);
+	gplugin_manager_prepend_path(manager, path);
+	g_free(path);
+}
+
+/**
+ * gplugin_manager_add_app_paths:
+ * @manager: The #GPluginManager instance.
+ * @prefix: The installation prefix for the application.
+ * @appname: The name of the application whose paths to add.
+ *
+ * Adds the application installation path for @appname.  This will add
+ * `@prefix/@appname/plugins` to the list as well as
+ * `${XDG_CONFIG_HOME}/@appname/plugins`.
+ */
+void
+gplugin_manager_add_app_paths(
+	GPluginManager *manager,
+	const gchar *prefix,
+	const gchar *appname)
+{
+	gchar *path;
+
+	g_return_if_fail(GPLUGIN_IS_MANAGER(manager));
+	g_return_if_fail(appname != NULL);
+
+	path = g_build_filename(prefix, LIBDIR, appname, NULL);
+	gplugin_manager_prepend_path(manager, path);
+	g_free(path);
+
+	path = g_build_filename(g_get_user_config_dir(), appname, "plugins", NULL);
+	gplugin_manager_prepend_path(manager, path);
+	g_free(path);
+}
+
+/**
+ * gplugin_manager_get_paths:
+ * @manager: The #GPluginManager instance.
+ *
+ * Gets the list of paths which will be searched for plugins.
+ *
+ * Returns: (element-type utf8) (transfer none): The list of paths which will
+ *          be searched for plugins.
+ */
+GList *
+gplugin_manager_get_paths(GPluginManager *manager)
+{
+	GPluginManagerPrivate *priv = NULL;
+
+	g_return_val_if_fail(GPLUGIN_IS_MANAGER(manager), NULL);
+
+	priv = gplugin_manager_get_instance_private(manager);
 
 	return priv->paths->head;
 }
 
-static gboolean
-gplugin_manager_real_register_loader(
+/**
+ * gplugin_manager_register_loader:
+ * @manager: The #GPluginManager instance.
+ * @type: #GType of a #GPluginLoader.
+ * @error: (out) (nullable): The return address for a #GError.
+ *
+ * Registers @type as an available loader.
+ *
+ * Returns: %TRUE if the loader was successfully register, %FALSE otherwise
+ *          with @error set.
+ */
+gboolean
+gplugin_manager_register_loader(
 	GPluginManager *manager,
 	GType type,
 	GError **error)
@@ -357,6 +749,7 @@
 	GPluginLoader *loader = NULL;
 	GSList *l = NULL, *exts = NULL;
 
+	g_return_val_if_fail(GPLUGIN_IS_MANAGER(manager), FALSE);
 	g_return_val_if_fail(g_type_is_a(type, GPLUGIN_TYPE_LOADER), FALSE);
 
 	loader = gplugin_manager_find_loader_by_type(manager, type);
@@ -429,8 +822,19 @@
 	return TRUE;
 }
 
-static gboolean
-gplugin_manager_real_unregister_loader(
+/**
+ * gplugin_manager_unregister_loader:
+ * @manager: The #GPluginManager instance.
+ * @type: #GType of a #GPluginLoader.
+ * @error: (out) (nullable): The return address for a #GError.
+ *
+ * Unregisters @type as an available loader.
+ *
+ * Returns: %TRUE if the loader was successfully unregistered, %FALSE
+ *          otherwise with @error set.
+ */
+gboolean
+gplugin_manager_unregister_loader(
 	GPluginManager *manager,
 	GType type,
 	GError **error)
@@ -439,6 +843,7 @@
 	GPluginLoader *loader = NULL;
 	GSList *l = NULL, *exts = NULL;
 
+	g_return_val_if_fail(GPLUGIN_IS_MANAGER(manager), FALSE);
 	g_return_val_if_fail(g_type_is_a(type, GPLUGIN_TYPE_LOADER), FALSE);
 
 	loader = gplugin_manager_find_loader_by_type(manager, type);
@@ -501,16 +906,35 @@
 	return TRUE;
 }
 
-static GSList *
-gplugin_manager_real_get_loaders(GPluginManager *manager)
+/**
+ * gplugin_manager_get_loaders:
+ * @manager: The #GPluginManager instance.
+ *
+ * Returns a list of all registered #GPluginLoader's.
+ *
+ * Returns: (element-type GPlugin.Loader) (transfer full): Returns a list of all
+ *          registered loaders.
+ */
+GSList *
+gplugin_manager_get_loaders(GPluginManager *manager)
 {
-	GPluginManagerPrivate *priv = gplugin_manager_get_instance_private(manager);
+	GPluginManagerPrivate *priv = NULL;
+
+	g_return_val_if_fail(GPLUGIN_IS_MANAGER(manager), FALSE);
+
+	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)
+/**
+ * gplugin_manager_refresh:
+ * @manager: The #GPluginManager instance.
+ *
+ * Forces a refresh of all plugins found in the search paths.
+ */
+void
+gplugin_manager_refresh(GPluginManager *manager)
 {
 	GPluginManagerPrivate *priv = NULL;
 	GNode *root = NULL;
@@ -518,6 +942,8 @@
 	gchar *error_message = NULL;
 	guint errors = 0;
 
+	g_return_if_fail(GPLUGIN_IS_MANAGER(manager));
+
 	priv = gplugin_manager_get_instance_private(manager);
 
 	/* build a tree of all possible plugins */
@@ -739,8 +1165,16 @@
 	gplugin_file_tree_free(root);
 }
 
-static void
-gplugin_manager_real_foreach(
+/**
+ * gplugin_manager_foreach:
+ * @manager: The #GPluginManager instance.
+ * @func: (scope call): The #GPluginManagerForeachFunc to call.
+ * @data: User data to pass to func.
+ *
+ * Calls @func for each plugin that is known.
+ */
+void
+gplugin_manager_foreach(
 	GPluginManager *manager,
 	GPluginManagerForeachFunc func,
 	gpointer data)
@@ -749,6 +1183,9 @@
 	GHashTableIter iter;
 	gpointer id = NULL, plugins = NULL;
 
+	g_return_if_fail(GPLUGIN_IS_MANAGER(manager));
+	g_return_if_fail(func != NULL);
+
 	priv = gplugin_manager_get_instance_private(manager);
 
 	g_hash_table_iter_init(&iter, priv->plugins);
@@ -757,12 +1194,25 @@
 	}
 }
 
-static GSList *
-gplugin_manager_real_find_plugins(GPluginManager *manager, const gchar *id)
+/**
+ * gplugin_manager_find_plugins:
+ * @manager: The #GPluginManager instance.
+ * @id: id string of the plugin to find.
+ *
+ * Finds all plugins matching @id.
+ *
+ * Returns: (element-type GPlugin.Plugin) (transfer full): A #GSList of
+ *          referenced #GPluginPlugin's matching @id.  Call
+ *          g_slist_free_full() with a `DestroyNotify` of g_object_unref() on
+ *          the returned value when you're done with it.
+ */
+GSList *
+gplugin_manager_find_plugins(GPluginManager *manager, const gchar *id)
 {
 	GPluginManagerPrivate *priv = NULL;
 	GSList *plugins_list = NULL, *l;
 
+	g_return_val_if_fail(GPLUGIN_IS_MANAGER(manager), NULL);
 	g_return_val_if_fail(id != NULL, NULL);
 
 	priv = gplugin_manager_get_instance_private(manager);
@@ -773,914 +1223,9 @@
 	return plugins_list;
 }
 
-static GSList *
-gplugin_manager_real_find_plugins_with_state(
-	GPluginManager *manager,
-	GPluginPluginState state)
-{
-	GPluginManagerPrivate *priv = NULL;
-	GSList *plugins = NULL;
-	GHashTableIter iter;
-	gpointer value = NULL;
-
-	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;
-
-		for(l = (GSList *)value; l != NULL; l = l->next) {
-			GPluginPlugin *plugin = GPLUGIN_PLUGIN(l->data);
-
-			if(gplugin_plugin_get_state(plugin) == state) {
-				plugins =
-					g_slist_prepend(plugins, g_object_ref(G_OBJECT(plugin)));
-			}
-		}
-	}
-
-	return plugins;
-}
-
-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;
-
-	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);
-	}
-
-	ret = g_list_copy(queue->head);
-
-	g_queue_free(queue);
-
-	return ret;
-}
-
-static gboolean
-gplugin_manager_load_dependencies(
-	GPluginPlugin *plugin,
-	GPluginPluginInfo *info,
-	GError **error)
-{
-	GSList *dependencies = NULL, *l = NULL;
-	GError *ourerror = NULL;
-	gboolean all_loaded = TRUE;
-
-	dependencies = gplugin_manager_get_plugin_dependencies(plugin, &ourerror);
-	if(ourerror != NULL) {
-		g_propagate_error(error, ourerror);
-
-		return FALSE;
-	}
-
-	for(l = dependencies; l != NULL; l = l->next) {
-		GPluginPlugin *dependency = GPLUGIN_PLUGIN(l->data);
-		gboolean loaded = FALSE;
-
-		loaded = gplugin_manager_load_plugin(dependency, &ourerror);
-
-		if(!loaded || ourerror != NULL) {
-			if(ourerror != NULL) {
-				g_propagate_error(error, ourerror);
-			}
-
-			all_loaded = FALSE;
-			break;
-		}
-	}
-
-	g_slist_free_full(dependencies, g_object_unref);
-
-	return all_loaded;
-}
-
-static GSList *
-gplugin_manager_real_get_plugin_dependencies(
-	G_GNUC_UNUSED GPluginManager *manager,
-	GPluginPlugin *plugin,
-	GError **error)
-{
-	GPluginPluginInfo *info = NULL;
-	GSList *ret = NULL;
-	const gchar *const *dependencies = NULL;
-	gint i = 0;
-
-	info = gplugin_plugin_get_info(plugin);
-	dependencies = gplugin_plugin_info_get_dependencies(info);
-	g_object_unref(G_OBJECT(info));
-
-	if(dependencies == NULL) {
-		return NULL;
-	}
-
-	for(i = 0; dependencies[i] != NULL; i++) {
-		gboolean found = FALSE;
-		gchar **ors = NULL;
-		gint o = 0;
-
-		ors = g_strsplit(dependencies[i], "|", 0);
-		for(o = 0; ors[o]; o++) {
-			GMatchInfo *match = NULL;
-			GSList *matches = NULL;
-			gchar *oid = NULL, *oop = NULL, *over = NULL;
-
-			if(!g_regex_match(dependency_regex, ors[o], 0, &match)) {
-				continue;
-			}
-
-			/* grab the or'd id, op, and version */
-			oid = g_match_info_fetch_named(match, "id");
-			oop = g_match_info_fetch_named(match, "op");
-			over = g_match_info_fetch_named(match, "version");
-
-			/* free the match info */
-			g_match_info_free(match);
-
-			/* now look for a plugin matching the id */
-			matches = gplugin_manager_find_plugins_with_version(oid, oop, over);
-			g_free(oid);
-			g_free(oop);
-			g_free(over);
-
-			if(matches == NULL) {
-				continue;
-			}
-
-			/* prepend the first found match to our return value */
-			ret = g_slist_prepend(ret, g_object_ref(matches->data));
-			g_slist_free_full(matches, g_object_unref);
-
-			found = TRUE;
-
-			break;
-		}
-		g_strfreev(ors);
-
-		if(!found) {
-			g_set_error(
-				error,
-				GPLUGIN_DOMAIN,
-				0,
-				_("failed to find dependency %s for %s"),
-				dependencies[i],
-				gplugin_plugin_info_get_id(info));
-
-			g_slist_free_full(ret, g_object_unref);
-
-			return NULL;
-		}
-	}
-
-	return ret;
-}
-
-static gboolean
-gplugin_manager_real_load_plugin(
-	GPluginManager *manager,
-	GPluginPlugin *plugin,
-	GError **ret_error)
-{
-	GPluginPluginInfo *info = NULL;
-	GPluginLoader *loader = NULL;
-	GError *error = NULL;
-	gboolean ret = TRUE;
-
-	g_return_val_if_fail(GPLUGIN_IS_PLUGIN(plugin), FALSE);
-
-	/* if the plugin is already loaded there's nothing for us to do */
-	if(gplugin_plugin_get_state(plugin) == GPLUGIN_PLUGIN_STATE_LOADED) {
-		return TRUE;
-	}
-
-	/* now try to get the plugin info from the plugin */
-	info = gplugin_plugin_get_info(plugin);
-	if(info == NULL) {
-		gchar *filename = gplugin_plugin_get_filename(plugin);
-
-		g_set_error(
-			ret_error,
-			GPLUGIN_DOMAIN,
-			0,
-			_("Plugin %s did not return value plugin info"),
-			filename);
-		g_free(filename);
-
-		gplugin_plugin_set_state(plugin, GPLUGIN_PLUGIN_STATE_LOAD_FAILED);
-
-		return FALSE;
-	}
-
-	if(!gplugin_manager_load_dependencies(plugin, info, ret_error)) {
-		g_object_unref(G_OBJECT(info));
-
-		return FALSE;
-	}
-
-	g_object_unref(G_OBJECT(info));
-
-	/* now load the actual plugin */
-	loader = gplugin_plugin_get_loader(plugin);
-
-	if(!GPLUGIN_IS_LOADER(loader)) {
-		gchar *filename = gplugin_plugin_get_filename(plugin);
-
-		g_set_error(
-			ret_error,
-			GPLUGIN_DOMAIN,
-			0,
-			_("The loader for %s is not a loader.  This "
-			  "should not happened!"),
-			filename);
-		g_free(filename);
-
-		gplugin_plugin_set_state(plugin, GPLUGIN_PLUGIN_STATE_LOAD_FAILED);
-
-		return FALSE;
-	}
-
-	g_signal_emit(manager, signals[SIG_LOADING], 0, plugin, &error, &ret);
-	if(!ret) {
-		/* Set the plugin's error. */
-		g_object_set(G_OBJECT(plugin), "error", error, NULL);
-
-		g_propagate_error(ret_error, error);
-
-		gplugin_plugin_set_state(plugin, GPLUGIN_PLUGIN_STATE_LOAD_FAILED);
-
-		return ret;
-	}
-
-	ret = gplugin_loader_load_plugin(loader, plugin, &error);
-	if(ret) {
-		g_signal_emit(manager, signals[SIG_LOADED], 0, plugin);
-	} else {
-		g_signal_emit(manager, signals[SIG_LOAD_FAILED], 0, plugin);
-
-		g_propagate_error(ret_error, error);
-	}
-
-	return ret;
-}
-
-static gboolean
-gplugin_manager_real_unload_plugin(
-	GPluginManager *manager,
-	GPluginPlugin *plugin,
-	GError **ret_error)
-{
-	GPluginLoader *loader = NULL;
-	GError *error = NULL;
-	gboolean ret = TRUE;
-
-	g_return_val_if_fail(GPLUGIN_IS_PLUGIN(plugin), FALSE);
-
-	if(gplugin_plugin_get_state(plugin) != GPLUGIN_PLUGIN_STATE_LOADED) {
-		return TRUE;
-	}
-
-	loader = gplugin_plugin_get_loader(plugin);
-	if(!GPLUGIN_IS_LOADER(loader)) {
-		g_set_error_literal(
-			ret_error,
-			GPLUGIN_DOMAIN,
-			0,
-			_("Plugin loader is not a loader"));
-
-		return FALSE;
-	}
-
-	g_signal_emit(manager, signals[SIG_UNLOADING], 0, plugin, &error, &ret);
-	if(!ret) {
-		/* Set the plugin's error. */
-		g_object_set(G_OBJECT(plugin), "error", error, NULL);
-
-		g_propagate_error(ret_error, error);
-
-		gplugin_plugin_set_state(plugin, GPLUGIN_PLUGIN_STATE_LOAD_FAILED);
-
-		return ret;
-	}
-
-	ret = gplugin_loader_unload_plugin(loader, plugin, &error);
-	if(ret) {
-		g_signal_emit(manager, signals[SIG_UNLOADED], 0, plugin);
-	} else {
-		g_signal_emit(manager, signals[SIG_UNLOAD_FAILED], 0, plugin);
-
-		g_propagate_error(ret_error, error);
-	}
-
-	return ret;
-}
-
-static gboolean
-gplugin_manager_loading_cb(
-	G_GNUC_UNUSED GPluginManager *manager,
-	G_GNUC_UNUSED GPluginPlugin *plugin,
-	G_GNUC_UNUSED GError **error)
-{
-	return TRUE;
-}
-
-static gboolean
-gplugin_manager_unloading_cb(
-	G_GNUC_UNUSED GPluginManager *manager,
-	G_GNUC_UNUSED GPluginPlugin *plugin,
-	G_GNUC_UNUSED GError **error)
-{
-	return TRUE;
-}
-
-/******************************************************************************
- * GObject Implementation
- *****************************************************************************/
-static void
-gplugin_manager_finalize(GObject *obj)
-{
-	GPluginManager *manager = GPLUGIN_MANAGER(obj);
-	GPluginManagerPrivate *priv = gplugin_manager_get_instance_private(manager);
-
-	g_queue_free_full(priv->paths, g_free);
-	priv->paths = NULL;
-
-	/* unload all of the loaded plugins */
-	g_hash_table_foreach(
-		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(
-		priv->plugins,
-		gplugin_manager_remove_list_value,
-		NULL);
-	g_clear_pointer(&priv->plugins, g_hash_table_destroy);
-
-	/* destroy the filename view */
-	g_clear_pointer(&priv->plugins_filename_view, g_hash_table_destroy);
-
-	/* clean up our list of loaders */
-	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(
-		priv->loaders_by_extension,
-		gplugin_manager_remove_list_value,
-		NULL);
-	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);
-}
-
-static void
-gplugin_manager_class_init(GPluginManagerClass *klass)
-{
-	GObjectClass *obj_class = G_OBJECT_CLASS(klass);
-	GPluginManagerClass *manager_class = GPLUGIN_MANAGER_CLASS(klass);
-
-	obj_class->finalize = gplugin_manager_finalize;
-
-	manager_class->append_path = gplugin_manager_real_append_path;
-	manager_class->prepend_path = gplugin_manager_real_prepend_path;
-	manager_class->remove_path = gplugin_manager_real_remove_path;
-	manager_class->remove_paths = gplugin_manager_real_remove_paths;
-	manager_class->get_paths = gplugin_manager_real_get_paths;
-
-	manager_class->register_loader = gplugin_manager_real_register_loader;
-	manager_class->unregister_loader = gplugin_manager_real_unregister_loader;
-	manager_class->get_loaders = gplugin_manager_real_get_loaders;
-
-	manager_class->refresh = gplugin_manager_real_refresh;
-
-	manager_class->foreach = gplugin_manager_real_foreach;
-
-	manager_class->find_plugins = gplugin_manager_real_find_plugins;
-	manager_class->find_plugins_with_state =
-		gplugin_manager_real_find_plugins_with_state;
-	manager_class->list_plugins = gplugin_manager_real_list_plugins;
-
-	manager_class->get_plugin_dependencies =
-		gplugin_manager_real_get_plugin_dependencies;
-
-	manager_class->load_plugin = gplugin_manager_real_load_plugin;
-	manager_class->unload_plugin = gplugin_manager_real_unload_plugin;
-
-	manager_class->loading_plugin = gplugin_manager_loading_cb;
-	manager_class->unloading_plugin = gplugin_manager_unloading_cb;
-
-	/* signals */
-
-	/**
-	 * GPluginManager::loading-plugin:
-	 * @manager: The #GPluginManager instance.
-	 * @plugin: The #GPluginPlugin that's about to be loaded.
-	 * @error: Return address for a #GError.
-	 *
-	 * Emitted before @plugin is loaded.
-	 *
-	 * Return FALSE to stop loading
-	 */
-	signals[SIG_LOADING] = g_signal_new(
-		"loading-plugin",
-		G_OBJECT_CLASS_TYPE(manager_class),
-		G_SIGNAL_RUN_LAST,
-		G_STRUCT_OFFSET(GPluginManagerClass, loading_plugin),
-		gplugin_boolean_accumulator,
-		NULL,
-		NULL,
-		G_TYPE_BOOLEAN,
-		2,
-		G_TYPE_OBJECT,
-		G_TYPE_POINTER);
-
-	/**
-	 * GPluginManager::loaded-plugin:
-	 * @manager: the #gpluginpluginmanager instance.
-	 * @plugin: the #gpluginplugin that's about to be loaded.
-	 *
-	 * emitted after a plugin is loaded.
-	 */
-	signals[SIG_LOADED] = g_signal_new(
-		"loaded-plugin",
-		G_OBJECT_CLASS_TYPE(manager_class),
-		G_SIGNAL_RUN_LAST,
-		G_STRUCT_OFFSET(GPluginManagerClass, loaded_plugin),
-		NULL,
-		NULL,
-		NULL,
-		G_TYPE_NONE,
-		1,
-		G_TYPE_OBJECT);
-
-	/**
-	 * GPluginManager::load-plugin-failed:
-	 * @manager: The #GPluginManager instance.
-	 * @plugin: The #GPluginPlugin that failed to load.
-	 *
-	 * emitted after a plugin fails to load.
-	 */
-	signals[SIG_LOAD_FAILED] = g_signal_new(
-		"load-plugin-failed",
-		G_OBJECT_CLASS_TYPE(manager_class),
-		G_SIGNAL_RUN_LAST,
-		G_STRUCT_OFFSET(GPluginManagerClass, load_failed),
-		NULL,
-		NULL,
-		NULL,
-		G_TYPE_NONE,
-		1,
-		G_TYPE_OBJECT);
-
-	/**
-	 * 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.
-	 *
-	 * Return FALSE to stop unloading
-	 */
-	signals[SIG_UNLOADING] = g_signal_new(
-		"unloading-plugin",
-		G_OBJECT_CLASS_TYPE(manager_class),
-		G_SIGNAL_RUN_LAST,
-		G_STRUCT_OFFSET(GPluginManagerClass, unloading_plugin),
-		gplugin_boolean_accumulator,
-		NULL,
-		NULL,
-		G_TYPE_BOOLEAN,
-		2,
-		G_TYPE_OBJECT,
-		G_TYPE_POINTER);
-
-	/**
-	 * GPluginManager::unloaded-plugin:
-	 * @manager: the #gpluginpluginmanager instance.
-	 * @plugin: the #gpluginplugin that's about to be loaded.
-	 *
-	 * emitted after a plugin is successfully unloaded.
-	 */
-	signals[SIG_UNLOADED] = g_signal_new(
-		"unloaded-plugin",
-		G_OBJECT_CLASS_TYPE(manager_class),
-		G_SIGNAL_RUN_LAST,
-		G_STRUCT_OFFSET(GPluginManagerClass, unloaded_plugin),
-		NULL,
-		NULL,
-		NULL,
-		G_TYPE_NONE,
-		1,
-		G_TYPE_OBJECT);
-
-	/**
-	 * GPluginManager::unload-plugin-failed:
-	 * @manager: The #GPluginManager instance.
-	 * @plugin: The #GPluginPlugin instance that failed to unload.
-	 * @error: A #GError instance.
-	 *
-	 * Emitted when @manager was asked to unload @plugin, but @plugin returned
-	 * %FALSE when its unload function was called.
-	 */
-	signals[SIG_UNLOAD_FAILED] = g_signal_new(
-		"unload-plugin-failed",
-		G_OBJECT_CLASS_TYPE(manager_class),
-		G_SIGNAL_RUN_LAST,
-		G_STRUCT_OFFSET(GPluginManagerClass, unload_plugin_failed),
-		NULL,
-		NULL,
-		NULL,
-		G_TYPE_NONE,
-		1,
-		G_TYPE_OBJECT);
-}
-
-static void
-gplugin_manager_init(GPluginManager *manager)
-{
-	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.
-	 */
-	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.
-	 */
-	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
-	 * of the loader.  Which means that a loader that supports multiple
-	 * extensions will be in the table multiple times.
-	 *
-	 * We deal with collisions by using a GSList for the value which will hold
-	 * references to instances of the actual loaders.
-	 *
-	 * Storing this in this method allows us to quickly figure out which loader
-	 * to use by the filename and helps us to avoid iterating the loaders table
-	 * again and again.
-	 */
-	priv->loaders_by_extension = g_hash_table_new_full(
-		gplugin_manager_str_hash,
-		g_str_equal,
-		g_free,
-		NULL);
-}
-
-/******************************************************************************
- * Private API
- *****************************************************************************/
-void
-gplugin_manager_private_init(gboolean register_native_loader)
-{
-	GError *error = NULL;
-
-	if(instance != NULL) {
-		return;
-	}
-
-	instance = g_object_new(GPLUGIN_TYPE_MANAGER, NULL);
-
-	if(register_native_loader) {
-		if(!gplugin_manager_register_loader(
-			   GPLUGIN_TYPE_NATIVE_LOADER,
-			   &error)) {
-			if(error != NULL) {
-				g_error("failed to register loader: %s", error->message);
-				g_error_free(error);
-			} else {
-				g_error("failed to register loader: unknown failure");
-			}
-		}
-	}
-
-	dependency_regex = g_regex_new(dependency_pattern, 0, 0, NULL);
-}
-
-void
-gplugin_manager_private_uninit(void)
-{
-	g_regex_unref(dependency_regex);
-
-	g_clear_object(&instance);
-}
-
-/******************************************************************************
- * API
- *****************************************************************************/
-
-/**
- * gplugin_manager_append_path:
- * @path: A path to add to the end of the plugin search paths.
- *
- * Adds @path to the end of the list of paths to search for plugins.
- */
-void
-gplugin_manager_append_path(const gchar *path)
-{
-	GPluginManagerClass *klass = NULL;
-
-	g_return_if_fail(GPLUGIN_IS_MANAGER(instance));
-
-	klass = GPLUGIN_MANAGER_GET_CLASS(instance);
-	if(klass && klass->append_path) {
-		klass->append_path(instance, path);
-	}
-}
-
-/**
- * gplugin_manager_prepend_path:
- * @path: A path to add to the beginning of the plugin search paths.
- *
- * Adds @path to the beginning of the list of paths to search for plugins.
- */
-void
-gplugin_manager_prepend_path(const gchar *path)
-{
-	GPluginManagerClass *klass = NULL;
-
-	g_return_if_fail(GPLUGIN_IS_MANAGER(instance));
-
-	klass = GPLUGIN_MANAGER_GET_CLASS(instance);
-	if(klass && klass->prepend_path) {
-		klass->prepend_path(instance, path);
-	}
-}
-
-/**
- * gplugin_manager_remove_path:
- * @path: A path to remove from the plugin search paths.
- *
- * Removes @path from the list of paths to search for plugins.
- */
-void
-gplugin_manager_remove_path(const gchar *path)
-{
-	GPluginManagerClass *klass = NULL;
-
-	g_return_if_fail(GPLUGIN_IS_MANAGER(instance));
-
-	klass = GPLUGIN_MANAGER_GET_CLASS(instance);
-	if(klass && klass->remove_path) {
-		klass->remove_path(instance, path);
-	}
-}
-
-/**
- * gplugin_manager_remove_paths:
- *
- * Clears all paths that are set to search for plugins.
- */
-void
-gplugin_manager_remove_paths(void)
-{
-	GPluginManagerClass *klass = NULL;
-
-	g_return_if_fail(GPLUGIN_IS_MANAGER(instance));
-
-	klass = GPLUGIN_MANAGER_GET_CLASS(instance);
-	if(klass && klass->remove_paths) {
-		klass->remove_paths(instance);
-	}
-}
-
-/**
- * gplugin_manager_add_default_paths:
- *
- * Adds the path that GPlugin was installed to to the plugin search path, as
- * well as `${XDG_CONFIG_HOME}/gplugin` so users can install additional loaders
- * themselves.
- */
-void
-gplugin_manager_add_default_paths(void)
-{
-	gchar *path;
-
-	path = g_build_filename(PREFIX, LIBDIR, "gplugin", NULL);
-	gplugin_manager_prepend_path(path);
-	g_free(path);
-
-	path = g_build_filename(g_get_user_config_dir(), "gplugin", NULL);
-	gplugin_manager_prepend_path(path);
-	g_free(path);
-}
-
-/**
- * gplugin_manager_add_app_paths:
- * @prefix: The installation prefix for the application.
- * @appname: The name of the application whose paths to add.
- *
- * Adds the application installation path for @appname.  This will add
- * `@prefix/@appname/plugins` to the list as well as
- * `${XDG_CONFIG_HOME}/@appname/plugins`.
- */
-void
-gplugin_manager_add_app_paths(const gchar *prefix, const gchar *appname)
-{
-	gchar *path;
-
-	g_return_if_fail(appname != NULL);
-
-	path = g_build_filename(prefix, LIBDIR, appname, NULL);
-	gplugin_manager_prepend_path(path);
-	g_free(path);
-
-	path = g_build_filename(g_get_user_config_dir(), appname, "plugins", NULL);
-	gplugin_manager_prepend_path(path);
-	g_free(path);
-}
-
-/**
- * gplugin_manager_get_paths:
- *
- * Gets the list of paths which will be searched for plugins.
- *
- * Returns: (element-type utf8) (transfer none): The list of paths which will
- *          be searched for plugins.
- */
-GList *
-gplugin_manager_get_paths(void)
-{
-	GPluginManagerClass *klass = NULL;
-
-	g_return_val_if_fail(GPLUGIN_IS_MANAGER(instance), NULL);
-
-	klass = GPLUGIN_MANAGER_GET_CLASS(instance);
-	if(klass && klass->get_paths) {
-		return klass->get_paths(instance);
-	}
-
-	return NULL;
-}
-
-/**
- * gplugin_manager_register_loader:
- * @type: #GType of a #GPluginLoader.
- * @error: (out) (nullable): The return address for a #GError.
- *
- * Registers @type as an available loader.
- *
- * Returns: %TRUE if the loader was successfully register, %FALSE otherwise
- *          with @error set.
- */
-gboolean
-gplugin_manager_register_loader(GType type, GError **error)
-{
-	GPluginManagerClass *klass = NULL;
-
-	g_return_val_if_fail(GPLUGIN_IS_MANAGER(instance), FALSE);
-
-	klass = GPLUGIN_MANAGER_GET_CLASS(instance);
-	if(klass && klass->register_loader) {
-		return klass->register_loader(instance, type, error);
-	}
-
-	g_set_error(
-		error,
-		GPLUGIN_DOMAIN,
-		0,
-		"register_loader method not implemented");
-
-	return FALSE;
-}
-
-/**
- * gplugin_manager_unregister_loader:
- * @type: #GType of a #GPluginLoader.
- * @error: (out) (nullable): The return address for a #GError.
- *
- * Unregisters @type as an available loader.
- *
- * Returns: %TRUE if the loader was successfully unregistered, %FALSE
- *          otherwise with @error set.
- */
-gboolean
-gplugin_manager_unregister_loader(GType type, GError **error)
-{
-	GPluginManagerClass *klass = NULL;
-
-	g_return_val_if_fail(GPLUGIN_IS_MANAGER(instance), FALSE);
-
-	klass = GPLUGIN_MANAGER_GET_CLASS(instance);
-	if(klass && klass->unregister_loader) {
-		return klass->unregister_loader(instance, type, error);
-	}
-
-	g_set_error(
-		error,
-		GPLUGIN_DOMAIN,
-		0,
-		"unregister_loader method not implemented");
-
-	return FALSE;
-}
-
-/**
- * gplugin_manager_get_loaders:
- *
- * Returns a list of all registered #GPluginLoader's.
- *
- * Returns: (element-type GPlugin.Loader) (transfer full): Returns a list of all
- *          registered loaders.
- */
-GSList *
-gplugin_manager_get_loaders(void)
-{
-	GPluginManagerClass *klass = NULL;
-
-	g_return_val_if_fail(GPLUGIN_IS_MANAGER(instance), FALSE);
-
-	klass = GPLUGIN_MANAGER_GET_CLASS(instance);
-	if(klass && klass->get_loaders) {
-		return klass->get_loaders(instance);
-	}
-
-	return NULL;
-}
-
-/**
- * gplugin_manager_refresh:
- *
- * Forces a refresh of all plugins found in the search paths.
- */
-void
-gplugin_manager_refresh(void)
-{
-	GPluginManagerClass *klass = NULL;
-
-	g_return_if_fail(GPLUGIN_IS_MANAGER(instance));
-
-	klass = GPLUGIN_MANAGER_GET_CLASS(instance);
-	if(klass && klass->refresh) {
-		klass->refresh(instance);
-	}
-}
-
-/**
- * gplugin_manager_foreach:
- * @func: (scope call): The #GPluginManagerForeachFunc to call.
- * @data: User data to pass to func.
- *
- * Calls @func for each plugin that is known.
- */
-void
-gplugin_manager_foreach(GPluginManagerForeachFunc func, gpointer data)
-{
-	GPluginManagerClass *klass = NULL;
-
-	g_return_if_fail(GPLUGIN_IS_MANAGER(instance));
-	g_return_if_fail(func != NULL);
-
-	klass = GPLUGIN_MANAGER_GET_CLASS(instance);
-	if(klass && klass->foreach) {
-		klass->foreach(instance, func, data);
-	}
-}
-
-/**
- * gplugin_manager_find_plugins:
- * @id: id string of the plugin to find.
- *
- * Finds all plugins matching @id.
- *
- * Returns: (element-type GPlugin.Plugin) (transfer full): A #GSList of
- *          referenced #GPluginPlugin's matching @id.  Call
- *          g_slist_free_full() with a `DestroyNotify` of g_object_unref() on
- *          the returned value when you're done with it.
- */
-GSList *
-gplugin_manager_find_plugins(const gchar *id)
-{
-	GPluginManagerClass *klass = NULL;
-
-	g_return_val_if_fail(GPLUGIN_IS_MANAGER(instance), NULL);
-
-	klass = GPLUGIN_MANAGER_GET_CLASS(instance);
-	if(klass && klass->find_plugins) {
-		return klass->find_plugins(instance, id);
-	}
-
-	return NULL;
-}
-
 /**
  * gplugin_manager_find_plugins_with_version:
+ * @manager: The #GPluginManager instance.
  * @id: The ID of the plugin to find.
  * @op: one of <, <=, =, ==, >=, >.
  * @version: The version to compare against.
@@ -1697,15 +1242,16 @@
  */
 GSList *
 gplugin_manager_find_plugins_with_version(
+	GPluginManager *manager,
 	const gchar *id,
 	const gchar *op,
 	const gchar *version)
 {
 	GSList *plugins = NULL, *filtered = NULL, *l = NULL;
 
-	g_return_val_if_fail(GPLUGIN_IS_MANAGER(instance), NULL);
+	g_return_val_if_fail(GPLUGIN_IS_MANAGER(manager), NULL);
 
-	plugins = gplugin_manager_find_plugins(id);
+	plugins = gplugin_manager_find_plugins(manager, id);
 
 	if((op == NULL || *op == '\0') && (version == NULL || *version == '\0')) {
 		/* we weren't actually passed an operator and a version so just return
@@ -1757,6 +1303,7 @@
 
 /**
  * gplugin_manager_find_plugins_with_state:
+ * @manager: The #GPluginManager instance.
  * @state: The #GPluginPluginState to look for.
  *
  * Finds all plugins that currently have a state of @state.
@@ -1767,22 +1314,39 @@
  *          the returned value when you're done with it.
  */
 GSList *
-gplugin_manager_find_plugins_with_state(GPluginPluginState state)
+gplugin_manager_find_plugins_with_state(
+	GPluginManager *manager,
+	GPluginPluginState state)
 {
-	GPluginManagerClass *klass = NULL;
+	GPluginManagerPrivate *priv = NULL;
+	GSList *plugins = NULL;
+	GHashTableIter iter;
+	gpointer value = NULL;
+
+	g_return_val_if_fail(GPLUGIN_IS_MANAGER(manager), NULL);
+
+	priv = gplugin_manager_get_instance_private(manager);
 
-	g_return_val_if_fail(GPLUGIN_IS_MANAGER(instance), NULL);
+	g_hash_table_iter_init(&iter, priv->plugins);
+	while(g_hash_table_iter_next(&iter, NULL, &value)) {
+		GSList *l = NULL;
 
-	klass = GPLUGIN_MANAGER_GET_CLASS(instance);
-	if(klass && klass->find_plugins_with_state) {
-		return klass->find_plugins_with_state(instance, state);
+		for(l = (GSList *)value; l != NULL; l = l->next) {
+			GPluginPlugin *plugin = GPLUGIN_PLUGIN(l->data);
+
+			if(gplugin_plugin_get_state(plugin) == state) {
+				plugins =
+					g_slist_prepend(plugins, g_object_ref(G_OBJECT(plugin)));
+			}
+		}
 	}
 
-	return NULL;
+	return plugins;
 }
 
 /**
  * gplugin_manager_find_plugin:
+ * @manager: The #GPluginManager instance.
  * @id: The id of the plugin to find.
  *
  * Finds the first plugin matching @id.  This function uses
@@ -1793,14 +1357,14 @@
  *               if no plugin matching @id was found.
  */
 GPluginPlugin *
-gplugin_manager_find_plugin(const gchar *id)
+gplugin_manager_find_plugin(GPluginManager *manager, const gchar *id)
 {
 	GSList *plugins_list = NULL;
 	GPluginPlugin *plugin = NULL;
 
 	g_return_val_if_fail(id != NULL, NULL);
 
-	plugins_list = gplugin_manager_find_plugins(id);
+	plugins_list = gplugin_manager_find_plugins(manager, id);
 	if(plugins_list == NULL) {
 		return NULL;
 	}
@@ -1814,6 +1378,7 @@
 
 /**
  * gplugin_manager_find_plugin_with_newest_version:
+ * @manager: The #GPluginManager instance.
  * @id: The id of the plugin to find.
  *
  * Calls gplugin_manager_find_plugins() with @id, and then returns the plugins
@@ -1823,7 +1388,9 @@
  *          highest version number, or %NULL if no plugins were found with @id.
  */
 GPluginPlugin *
-gplugin_manager_find_plugin_with_newest_version(const gchar *id)
+gplugin_manager_find_plugin_with_newest_version(
+	GPluginManager *manager,
+	const gchar *id)
 {
 	GPluginPlugin *plugin_a = NULL;
 	GPluginPluginInfo *info_a = NULL;
@@ -1832,7 +1399,7 @@
 
 	g_return_val_if_fail(id != NULL, NULL);
 
-	l = gplugin_manager_find_plugins(id);
+	l = gplugin_manager_find_plugins(manager, id);
 	for(; l != NULL; l = g_slist_delete_link(l, l)) {
 		GPluginPlugin *plugin_b = NULL;
 		GPluginPluginInfo *info_b = NULL;
@@ -1886,6 +1453,7 @@
 
 /**
  * gplugin_manager_get_plugin_dependencies:
+ * @manager: The #GPluginManager instance.
  * @plugin: The #GPluginPlugin whose dependencies to get.
  * @error: (out) (nullable): Return address for a #GError.
  *
@@ -1898,24 +1466,95 @@
  *               you're done with it.
  */
 GSList *
-gplugin_manager_get_plugin_dependencies(GPluginPlugin *plugin, GError **error)
+gplugin_manager_get_plugin_dependencies(
+	GPluginManager *manager,
+	GPluginPlugin *plugin,
+	GError **error)
 {
-	GPluginManagerClass *klass = NULL;
+	GPluginPluginInfo *info = NULL;
+	GSList *ret = NULL;
+	const gchar *const *dependencies = NULL;
+	gint i = 0;
 
+	g_return_val_if_fail(GPLUGIN_IS_MANAGER(manager), NULL);
 	g_return_val_if_fail(GPLUGIN_IS_PLUGIN(plugin), NULL);
 
-	g_return_val_if_fail(GPLUGIN_IS_MANAGER(instance), NULL);
+	info = gplugin_plugin_get_info(plugin);
+	dependencies = gplugin_plugin_info_get_dependencies(info);
+	g_object_unref(G_OBJECT(info));
 
-	klass = GPLUGIN_MANAGER_GET_CLASS(instance);
-	if(klass && klass->get_plugin_dependencies) {
-		return klass->get_plugin_dependencies(instance, plugin, error);
+	if(dependencies == NULL) {
+		return NULL;
 	}
 
-	return NULL;
+	for(i = 0; dependencies[i] != NULL; i++) {
+		gboolean found = FALSE;
+		gchar **ors = NULL;
+		gint o = 0;
+
+		ors = g_strsplit(dependencies[i], "|", 0);
+		for(o = 0; ors[o]; o++) {
+			GMatchInfo *match = NULL;
+			GSList *matches = NULL;
+			gchar *oid = NULL, *oop = NULL, *over = NULL;
+
+			if(!g_regex_match(dependency_regex, ors[o], 0, &match)) {
+				continue;
+			}
+
+			/* grab the or'd id, op, and version */
+			oid = g_match_info_fetch_named(match, "id");
+			oop = g_match_info_fetch_named(match, "op");
+			over = g_match_info_fetch_named(match, "version");
+
+			/* free the match info */
+			g_match_info_free(match);
+
+			/* now look for a plugin matching the id */
+			matches = gplugin_manager_find_plugins_with_version(
+				manager,
+				oid,
+				oop,
+				over);
+			g_free(oid);
+			g_free(oop);
+			g_free(over);
+
+			if(matches == NULL) {
+				continue;
+			}
+
+			/* prepend the first found match to our return value */
+			ret = g_slist_prepend(ret, g_object_ref(matches->data));
+			g_slist_free_full(matches, g_object_unref);
+
+			found = TRUE;
+
+			break;
+		}
+		g_strfreev(ors);
+
+		if(!found) {
+			g_set_error(
+				error,
+				GPLUGIN_DOMAIN,
+				0,
+				_("failed to find dependency %s for %s"),
+				dependencies[i],
+				gplugin_plugin_info_get_id(info));
+
+			g_slist_free_full(ret, g_object_unref);
+
+			return NULL;
+		}
+	}
+
+	return ret;
 }
 
 /**
  * gplugin_manager_load_plugin:
+ * @manager: The #GPluginManager instance.
  * @plugin: #GPluginPlugin instance.
  * @error: (out) (nullable): return location for a #GError or %NULL.
  *
@@ -1927,24 +1566,99 @@
  *               %FALSE otherwise.
  */
 gboolean
-gplugin_manager_load_plugin(GPluginPlugin *plugin, GError **error)
+gplugin_manager_load_plugin(
+	GPluginManager *manager,
+	GPluginPlugin *plugin,
+	GError **error)
 {
-	GPluginManagerClass *klass = NULL;
+	GPluginPluginInfo *info = NULL;
+	GPluginLoader *loader = NULL;
+	GError *real_error = NULL;
+	gboolean ret = TRUE;
 
+	g_return_val_if_fail(GPLUGIN_IS_MANAGER(manager), FALSE);
 	g_return_val_if_fail(GPLUGIN_IS_PLUGIN(plugin), FALSE);
 
-	g_return_val_if_fail(GPLUGIN_IS_MANAGER(instance), FALSE);
+	/* if the plugin is already loaded there's nothing for us to do */
+	if(gplugin_plugin_get_state(plugin) == GPLUGIN_PLUGIN_STATE_LOADED) {
+		return TRUE;
+	}
+
+	/* now try to get the plugin info from the plugin */
+	info = gplugin_plugin_get_info(plugin);
+	if(info == NULL) {
+		gchar *filename = gplugin_plugin_get_filename(plugin);
 
-	klass = GPLUGIN_MANAGER_GET_CLASS(instance);
-	if(klass && klass->load_plugin) {
-		return klass->load_plugin(instance, plugin, error);
+		g_set_error(
+			error,
+			GPLUGIN_DOMAIN,
+			0,
+			_("Plugin %s did not return value plugin info"),
+			filename);
+		g_free(filename);
+
+		gplugin_plugin_set_state(plugin, GPLUGIN_PLUGIN_STATE_LOAD_FAILED);
+
+		return FALSE;
+	}
+
+	if(!gplugin_manager_load_dependencies(manager, plugin, info, &real_error)) {
+		g_object_unref(G_OBJECT(info));
+
+		g_propagate_error(error, real_error);
+
+		return FALSE;
 	}
 
-	return FALSE;
+	g_object_unref(G_OBJECT(info));
+
+	/* now load the actual plugin */
+	loader = gplugin_plugin_get_loader(plugin);
+
+	if(!GPLUGIN_IS_LOADER(loader)) {
+		gchar *filename = gplugin_plugin_get_filename(plugin);
+
+		g_set_error(
+			error,
+			GPLUGIN_DOMAIN,
+			0,
+			_("The loader for %s is not a loader.  This "
+			  "should not happened!"),
+			filename);
+		g_free(filename);
+
+		gplugin_plugin_set_state(plugin, GPLUGIN_PLUGIN_STATE_LOAD_FAILED);
+
+		return FALSE;
+	}
+
+	g_signal_emit(manager, signals[SIG_LOADING], 0, plugin, &real_error, &ret);
+	if(!ret) {
+		/* Set the plugin's error. */
+		g_object_set(G_OBJECT(plugin), "error", real_error, NULL);
+
+		g_propagate_error(error, real_error);
+
+		gplugin_plugin_set_state(plugin, GPLUGIN_PLUGIN_STATE_LOAD_FAILED);
+
+		return ret;
+	}
+
+	ret = gplugin_loader_load_plugin(loader, plugin, &real_error);
+	if(ret) {
+		g_signal_emit(manager, signals[SIG_LOADED], 0, plugin);
+	} else {
+		g_signal_emit(manager, signals[SIG_LOAD_FAILED], 0, plugin);
+
+		g_propagate_error(error, real_error);
+	}
+
+	return ret;
 }
 
 /**
  * gplugin_manager_unload_plugin:
+ * @manager: The #GPluginManager instance.
  * @plugin: #GPluginPlugin instance.
  * @error: (out) (nullable): Return location for a #GError or %NULL.
  *
@@ -1954,24 +1668,67 @@
  *          otherwise.
  */
 gboolean
-gplugin_manager_unload_plugin(GPluginPlugin *plugin, GError **error)
+gplugin_manager_unload_plugin(
+	GPluginManager *manager,
+	GPluginPlugin *plugin,
+	GError **error)
 {
-	GPluginManagerClass *klass = NULL;
+	GPluginLoader *loader = NULL;
+	GError *real_error = NULL;
+	gboolean ret = TRUE;
 
+	g_return_val_if_fail(GPLUGIN_IS_MANAGER(manager), FALSE);
 	g_return_val_if_fail(GPLUGIN_IS_PLUGIN(plugin), FALSE);
 
-	g_return_val_if_fail(GPLUGIN_IS_MANAGER(instance), FALSE);
+	if(gplugin_plugin_get_state(plugin) != GPLUGIN_PLUGIN_STATE_LOADED) {
+		return TRUE;
+	}
 
-	klass = GPLUGIN_MANAGER_GET_CLASS(instance);
-	if(klass && klass->unload_plugin) {
-		return klass->unload_plugin(instance, plugin, error);
+	loader = gplugin_plugin_get_loader(plugin);
+	if(!GPLUGIN_IS_LOADER(loader)) {
+		g_set_error_literal(
+			error,
+			GPLUGIN_DOMAIN,
+			0,
+			_("Plugin loader is not a loader"));
+
+		return FALSE;
 	}
 
-	return FALSE;
+	g_signal_emit(
+		manager,
+		signals[SIG_UNLOADING],
+		0,
+		plugin,
+		&real_error,
+		&ret);
+	if(!ret) {
+		/* Set the plugin's error. */
+		g_object_set(G_OBJECT(plugin), "error", real_error, NULL);
+
+		g_propagate_error(error, real_error);
+
+		gplugin_plugin_set_state(plugin, GPLUGIN_PLUGIN_STATE_LOAD_FAILED);
+
+		return ret;
+	}
+
+	ret = gplugin_loader_unload_plugin(loader, plugin, &real_error);
+	if(ret) {
+		g_clear_error(&real_error);
+		g_signal_emit(manager, signals[SIG_UNLOADED], 0, plugin);
+	} else {
+		g_signal_emit(manager, signals[SIG_UNLOAD_FAILED], 0, plugin);
+
+		g_propagate_error(error, real_error);
+	}
+
+	return ret;
 }
 
 /**
  * gplugin_manager_list_plugins:
+ * @manager: The #GPluginManager instance.
  *
  * Returns a #GList of all plugin id's.  Each id should be queried directly
  * for more information.
@@ -1980,34 +1737,42 @@
  *               unique plugin id.
  */
 GList *
-gplugin_manager_list_plugins(void)
+gplugin_manager_list_plugins(GPluginManager *manager)
 {
-	GPluginManagerClass *klass = NULL;
+	GPluginManagerPrivate *priv = NULL;
+	GQueue *queue = NULL;
+	GList *ret = NULL;
+	GHashTableIter iter;
+	gpointer key = NULL;
 
-	g_return_val_if_fail(GPLUGIN_IS_MANAGER(instance), NULL);
+	g_return_val_if_fail(GPLUGIN_IS_MANAGER(manager), NULL);
 
-	klass = GPLUGIN_MANAGER_GET_CLASS(instance);
-	if(klass && klass->list_plugins) {
-		return klass->list_plugins(instance);
+	priv = gplugin_manager_get_instance_private(manager);
+	queue = g_queue_new();
+
+	g_hash_table_iter_init(&iter, priv->plugins);
+	while(g_hash_table_iter_next(&iter, &key, NULL)) {
+		g_queue_push_tail(queue, (gchar *)key);
 	}
 
-	return NULL;
+	ret = g_list_copy(queue->head);
+
+	g_queue_free(queue);
+
+	return ret;
 }
 
 /**
- * gplugin_manager_get_instance:
+ * gplugin_manager_get_default:
  *
- * Returns a #GObject that is the instance of the plugin manager that is being
- * used.
+ * Gets the default #GPluginManager in GPlugin.
  *
- * This is provided so that signals can be connected and should not be tinkered
- * with in any way.
+ * Returns: (transfer none): The default GPluginManager instance.
  *
- * Returns: (transfer none): The #GObject that is the instance of the plugin
- *                           manager.
+ * Since: 0.33.0
  */
 GPluginManager *
-gplugin_manager_get_instance(void)
+gplugin_manager_get_default(void)
 {
-	return instance;
+	return default_manager;
 }
diff --git a/gplugin/gplugin-options.c b/gplugin/gplugin-options.c
--- a/gplugin/gplugin-options.c
+++ b/gplugin/gplugin-options.c
@@ -91,6 +91,7 @@
 	G_GNUC_UNUSED gpointer data,
 	G_GNUC_UNUSED GError **error)
 {
+	GPluginManager *manager = NULL;
 	GPluginCoreFlags flags = GPLUGIN_CORE_FLAGS_NONE;
 
 	if(!register_native_loader) {
@@ -99,15 +100,17 @@
 
 	gplugin_init(flags);
 
+	manager = gplugin_manager_get_default();
+
 	if(add_default_paths) {
-		gplugin_manager_add_default_paths();
+		gplugin_manager_add_default_paths(manager);
 	}
 
 	if(paths != NULL) {
 		guint i = 0;
 
 		for(i = 0; paths[i] != NULL; i++) {
-			gplugin_manager_prepend_path(paths[i]);
+			gplugin_manager_prepend_path(manager, paths[i]);
 		}
 
 		g_clear_pointer(&paths, g_strfreev);
diff --git a/gplugin/tests/test-bind-global.c b/gplugin/tests/test-bind-global.c
--- a/gplugin/tests/test-bind-global.c
+++ b/gplugin/tests/test-bind-global.c
@@ -33,13 +33,14 @@
 static void
 test_bind_global(void)
 {
+	GPluginManager *manager = gplugin_manager_get_default();
 	GPluginPlugin *plugin = NULL;
 
-	gplugin_manager_remove_paths();
-	gplugin_manager_append_path(TEST_BIND_GLOBAL_DIR);
-	gplugin_manager_refresh();
+	gplugin_manager_remove_paths(manager);
+	gplugin_manager_append_path(manager, TEST_BIND_GLOBAL_DIR);
+	gplugin_manager_refresh(manager);
 
-	plugin = gplugin_manager_find_plugin("gplugin/bind-global");
+	plugin = gplugin_manager_find_plugin(manager, "gplugin/bind-global");
 	g_assert_nonnull(plugin);
 	g_assert_true(GPLUGIN_IS_PLUGIN(plugin));
 	g_assert_true(GPLUGIN_IS_NATIVE_PLUGIN(plugin));
diff --git a/gplugin/tests/test-core.c b/gplugin/tests/test-core.c
--- a/gplugin/tests/test-core.c
+++ b/gplugin/tests/test-core.c
@@ -25,17 +25,18 @@
 static void
 test_gplugin_count_ids_and_plugins(gint *n_ids, gint *n_plugins)
 {
+	GPluginManager *manager = gplugin_manager_get_default();
 	GList *l_ids = NULL, *l_id = NULL;
 	gint ids = 0, plugins = 0;
 
-	l_ids = gplugin_manager_list_plugins();
+	l_ids = gplugin_manager_list_plugins(manager);
 	for(l_id = l_ids; l_id; l_id = l_id->next) {
 		GSList *l_plugins = NULL, *l_plugin = NULL;
 		const gchar *id = (const gchar *)l_id->data;
 
 		ids += 1;
 
-		l_plugins = gplugin_manager_find_plugins(id);
+		l_plugins = gplugin_manager_find_plugins(manager, id);
 		for(l_plugin = l_plugins; l_plugin; l_plugin = l_plugin->next) {
 			plugins += 1;
 		}
@@ -73,35 +74,49 @@
 static void
 test_gplugin_init_uninit_with_refresh(void)
 {
+	GPluginManager *manager = NULL;
+
 	gplugin_init(GPLUGIN_CORE_FLAGS_NONE);
-	gplugin_manager_refresh();
+
+	manager = gplugin_manager_get_default();
+	gplugin_manager_refresh(manager);
+
 	gplugin_uninit();
 }
 
 static void
 test_gplugin_init_uninit_with_refresh_plugins(void)
 {
+	GPluginManager *manager = NULL;
+
 	gplugin_init(GPLUGIN_CORE_FLAGS_NONE);
-	gplugin_manager_append_path(TEST_DIR);
-	gplugin_manager_refresh();
+
+	manager = gplugin_manager_get_default();
+	gplugin_manager_append_path(manager, TEST_DIR);
+	gplugin_manager_refresh(manager);
+
 	gplugin_uninit();
 }
 
 static void
 test_gplugin_init_uninit_with_double_refresh_plugins(void)
 {
+	GPluginManager *manager = NULL;
 	gint f_ids = 0, s_ids = 0, f_plugins = 0, s_plugins = 0;
 
 	gplugin_init(GPLUGIN_CORE_FLAGS_NONE);
-	gplugin_manager_append_path(TEST_DIR);
-	gplugin_manager_append_path(TEST_ID_DIR);
+
+	manager = gplugin_manager_get_default();
+
+	gplugin_manager_append_path(manager, TEST_DIR);
+	gplugin_manager_append_path(manager, TEST_ID_DIR);
 
 	/* run the first refresh and count everything */
-	gplugin_manager_refresh();
+	gplugin_manager_refresh(manager);
 	test_gplugin_count_ids_and_plugins(&f_ids, &f_plugins);
 
 	/* now run the second refresh and make sure the counts match */
-	gplugin_manager_refresh();
+	gplugin_manager_refresh(manager);
 	test_gplugin_count_ids_and_plugins(&s_ids, &s_plugins);
 
 	g_assert_cmpint(f_ids, >, 0);
@@ -116,9 +131,13 @@
 static void
 test_gplugin_init_no_native_loader(void)
 {
+	GPluginManager *manager = NULL;
+
 	gplugin_init(GPLUGIN_CORE_FLAGS_DISABLE_NATIVE_LOADER);
 
-	g_assert_null(gplugin_manager_get_loaders());
+	manager = gplugin_manager_get_default();
+
+	g_assert_null(gplugin_manager_get_loaders(manager));
 
 	gplugin_uninit();
 }
diff --git a/gplugin/tests/test-dynamic-type.c b/gplugin/tests/test-dynamic-type.c
--- a/gplugin/tests/test-dynamic-type.c
+++ b/gplugin/tests/test-dynamic-type.c
@@ -29,28 +29,30 @@
 static void
 test_dynamic_type(void)
 {
+	GPluginManager *manager = gplugin_manager_get_default();
 	GPluginPlugin *provider = NULL, *user = NULL;
 	GPluginPluginState state;
 	GError *error = NULL;
 	gboolean ret = FALSE;
 
-	gplugin_manager_append_path(TEST_DYNAMIC_DIR);
-	gplugin_manager_refresh();
+	gplugin_manager_append_path(manager, TEST_DYNAMIC_DIR);
+	gplugin_manager_refresh(manager);
 
-	provider = gplugin_manager_find_plugin("gplugin/dynamic-type-provider");
+	provider =
+		gplugin_manager_find_plugin(manager, "gplugin/dynamic-type-provider");
 
 	g_assert_nonnull(provider);
-	ret = gplugin_manager_load_plugin(provider, &error);
+	ret = gplugin_manager_load_plugin(manager, provider, &error);
 	g_assert_no_error(error);
 	g_assert_true(ret);
 
 	state = gplugin_plugin_get_state(provider);
 	g_assert_cmpint(state, ==, GPLUGIN_PLUGIN_STATE_LOADED);
 
-	user = gplugin_manager_find_plugin("gplugin/dynamic-type-user");
+	user = gplugin_manager_find_plugin(manager, "gplugin/dynamic-type-user");
 
 	g_assert_nonnull(user);
-	ret = gplugin_manager_load_plugin(user, &error);
+	ret = gplugin_manager_load_plugin(manager, user, &error);
 	g_assert_no_error(error);
 	g_assert_true(ret);
 
@@ -58,14 +60,14 @@
 	g_assert_cmpint(state, ==, GPLUGIN_PLUGIN_STATE_LOADED);
 
 	/* now unload the plugin */
-	ret = gplugin_manager_unload_plugin(user, &error);
+	ret = gplugin_manager_unload_plugin(manager, user, &error);
 	g_assert_no_error(error);
 	g_assert_true(ret);
 
 	state = gplugin_plugin_get_state(user);
 	g_assert_cmpint(state, ==, GPLUGIN_PLUGIN_STATE_QUERIED);
 
-	ret = gplugin_manager_unload_plugin(provider, &error);
+	ret = gplugin_manager_unload_plugin(manager, provider, &error);
 	g_assert_no_error(error);
 	g_assert_true(ret);
 
diff --git a/gplugin/tests/test-find-plugins.c b/gplugin/tests/test-find-plugins.c
--- a/gplugin/tests/test-find-plugins.c
+++ b/gplugin/tests/test-find-plugins.c
@@ -28,10 +28,11 @@
 	GSList *plugins,
 	gpointer data)
 {
+	GPluginManager *manager = gplugin_manager_get_default();
 	GSList *l = NULL;
 
 	for(l = plugins; l != NULL; l = l->next) {
-		gplugin_manager_load_plugin(GPLUGIN_PLUGIN(l->data), NULL);
+		gplugin_manager_load_plugin(manager, GPLUGIN_PLUGIN(l->data), NULL);
 	}
 }
 
@@ -41,10 +42,11 @@
 	GSList *plugins,
 	gpointer data)
 {
+	GPluginManager *manager = gplugin_manager_get_default();
 	GSList *l = NULL;
 
 	for(l = plugins; l != NULL; l = l->next) {
-		gplugin_manager_unload_plugin(GPLUGIN_PLUGIN(l->data), NULL);
+		gplugin_manager_unload_plugin(manager, GPLUGIN_PLUGIN(l->data), NULL);
 	}
 }
 
@@ -64,6 +66,7 @@
 static void
 test_gplugin_manager_find_plugins_with_state(void)
 {
+	GPluginManager *manager = NULL;
 	GSList *plugins = NULL;
 
 	/* this is the list of the current plugins and the furthest state they can
@@ -84,41 +87,54 @@
 
 	gplugin_init(GPLUGIN_CORE_FLAGS_NONE);
 
-	gplugin_manager_append_path(TEST_DIR);
-	gplugin_manager_refresh();
+	manager = gplugin_manager_get_default();
+
+	gplugin_manager_append_path(manager, TEST_DIR);
+	gplugin_manager_refresh(manager);
 
 	/* make sure that all the plugins are queried */
-	plugins =
-		gplugin_manager_find_plugins_with_state(GPLUGIN_PLUGIN_STATE_QUERIED);
+	plugins = gplugin_manager_find_plugins_with_state(
+		manager,
+		GPLUGIN_PLUGIN_STATE_QUERIED);
 	g_assert_cmpint(g_slist_length(plugins), ==, QUERIED);
 	g_slist_free_full(plugins, g_object_unref);
 
 	/* now load all of the plugins */
-	gplugin_manager_foreach(test_gplugin_manager_foreach_load_plugins, NULL);
+	gplugin_manager_foreach(
+		manager,
+		test_gplugin_manager_foreach_load_plugins,
+		NULL);
 
 	/* make sure we have the proper number loaded */
-	plugins =
-		gplugin_manager_find_plugins_with_state(GPLUGIN_PLUGIN_STATE_LOADED);
+	plugins = gplugin_manager_find_plugins_with_state(
+		manager,
+		GPLUGIN_PLUGIN_STATE_LOADED);
 	g_assert_cmpint(g_slist_length(plugins), ==, LOADED);
 	g_slist_free_full(plugins, g_object_unref);
 
 	/* make sure we have the proper number of load failed */
 	plugins = gplugin_manager_find_plugins_with_state(
+		manager,
 		GPLUGIN_PLUGIN_STATE_LOAD_FAILED);
 	g_assert_cmpint(g_slist_length(plugins), ==, LOAD_FAILED);
 	g_slist_free_full(plugins, g_object_unref);
 
 	/* unload all of the plugins */
-	gplugin_manager_foreach(test_gplugin_manager_foreach_unload_plugins, NULL);
+	gplugin_manager_foreach(
+		manager,
+		test_gplugin_manager_foreach_unload_plugins,
+		NULL);
 
 	/* make sure we have the proper number unloaded */
-	plugins =
-		gplugin_manager_find_plugins_with_state(GPLUGIN_PLUGIN_STATE_QUERIED);
+	plugins = gplugin_manager_find_plugins_with_state(
+		manager,
+		GPLUGIN_PLUGIN_STATE_QUERIED);
 	g_assert_cmpint(g_slist_length(plugins), ==, UNLOADED);
 	g_slist_free_full(plugins, g_object_unref);
 
 	/* make sure we have the proper number of unload failed */
 	plugins = gplugin_manager_find_plugins_with_state(
+		manager,
 		GPLUGIN_PLUGIN_STATE_UNLOAD_FAILED);
 	g_assert_cmpint(g_slist_length(plugins), ==, UNLOAD_FAILED);
 	g_slist_free_full(plugins, g_object_unref);
diff --git a/gplugin/tests/test-id-collision.c b/gplugin/tests/test-id-collision.c
--- a/gplugin/tests/test-id-collision.c
+++ b/gplugin/tests/test-id-collision.c
@@ -29,12 +29,15 @@
 static void
 test_id_collision(void)
 {
+	GPluginManager *manager = NULL;
 	GSList *plugins = NULL;
 
-	gplugin_manager_append_path(TEST_ID_DIR);
-	gplugin_manager_refresh();
+	manager = gplugin_manager_get_default();
 
-	plugins = gplugin_manager_find_plugins("gplugin/id-collision");
+	gplugin_manager_append_path(manager, TEST_ID_DIR);
+	gplugin_manager_refresh(manager);
+
+	plugins = gplugin_manager_find_plugins(manager, "gplugin/id-collision");
 	g_assert_nonnull(plugins);
 
 	g_assert_cmpuint(g_slist_length(plugins), ==, 2);
@@ -48,7 +51,6 @@
 gint
 main(gint argc, gchar **argv)
 {
-
 	g_test_init(&argc, &argv, NULL);
 
 	gplugin_init(GPLUGIN_CORE_FLAGS_NONE);
diff --git a/gplugin/tests/test-load-on-query.c b/gplugin/tests/test-load-on-query.c
--- a/gplugin/tests/test-load-on-query.c
+++ b/gplugin/tests/test-load-on-query.c
@@ -29,13 +29,14 @@
 static void
 test_load_on_query(void)
 {
+	GPluginManager *manager = gplugin_manager_get_default();
 	GPluginPlugin *plugin = NULL;
 
-	gplugin_manager_remove_paths();
-	gplugin_manager_append_path(TEST_LOAD_ON_QUERY_PASS_DIR);
-	gplugin_manager_refresh();
+	gplugin_manager_remove_paths(manager);
+	gplugin_manager_append_path(manager, TEST_LOAD_ON_QUERY_PASS_DIR);
+	gplugin_manager_refresh(manager);
 
-	plugin = gplugin_manager_find_plugin("gplugin/load-on-query");
+	plugin = gplugin_manager_find_plugin(manager, "gplugin/load-on-query");
 	g_assert_nonnull(plugin);
 	g_assert_true(GPLUGIN_IS_PLUGIN(plugin));
 
@@ -48,6 +49,8 @@
 static void
 test_load_on_query_fail_subprocess(void)
 {
+	GPluginManager *manager = gplugin_manager_get_default();
+
 	/* this test is very simple since we can't get the exact error condition
 	 * that we want.
 	 *
@@ -57,10 +60,10 @@
 	 * plugin stored twice.  This has been fixed in the code, but it has to be
 	 * looked for manually.
 	 */
-	gplugin_manager_remove_paths();
-	gplugin_manager_append_path(TEST_DIR);
-	gplugin_manager_append_path(TEST_LOAD_ON_QUERY_FAIL_DIR);
-	gplugin_manager_refresh();
+	gplugin_manager_remove_paths(manager);
+	gplugin_manager_append_path(manager, TEST_DIR);
+	gplugin_manager_append_path(manager, TEST_LOAD_ON_QUERY_FAIL_DIR);
+	gplugin_manager_refresh(manager);
 }
 
 static void
diff --git a/gplugin/tests/test-loader-registration.c b/gplugin/tests/test-loader-registration.c
--- a/gplugin/tests/test-loader-registration.c
+++ b/gplugin/tests/test-loader-registration.c
@@ -94,17 +94,26 @@
 static void
 test_gplugin_manager_loader_register_unregister(void)
 {
+	GPluginManager *manager = NULL;
 	GError *error = NULL;
 	gboolean ret;
 
 	gplugin_manager_private_uninit();
 	gplugin_manager_private_init(TRUE);
 
-	ret = gplugin_manager_register_loader(TEST_GPLUGIN_TYPE_LOADER, &error);
+	manager = gplugin_manager_get_default();
+
+	ret = gplugin_manager_register_loader(
+		manager,
+		TEST_GPLUGIN_TYPE_LOADER,
+		&error);
 	g_assert_no_error(error);
 	g_assert_true(ret);
 
-	ret = gplugin_manager_unregister_loader(TEST_GPLUGIN_TYPE_LOADER, &error);
+	ret = gplugin_manager_unregister_loader(
+		manager,
+		TEST_GPLUGIN_TYPE_LOADER,
+		&error);
 	g_assert_no_error(error);
 	g_assert_true(ret);
 }
@@ -112,22 +121,34 @@
 static void
 test_gplugin_manager_loader_register_twice(void)
 {
+	GPluginManager *manager = NULL;
 	GError *error = NULL;
 	gboolean ret;
 
 	gplugin_manager_private_uninit();
 	gplugin_manager_private_init(TRUE);
 
-	ret = gplugin_manager_register_loader(TEST_GPLUGIN_TYPE_LOADER, &error);
+	manager = gplugin_manager_get_default();
+
+	ret = gplugin_manager_register_loader(
+		manager,
+		TEST_GPLUGIN_TYPE_LOADER,
+		&error);
 	g_assert_no_error(error);
 	g_assert_true(ret);
 
-	ret = gplugin_manager_register_loader(TEST_GPLUGIN_TYPE_LOADER, &error);
+	ret = gplugin_manager_register_loader(
+		manager,
+		TEST_GPLUGIN_TYPE_LOADER,
+		&error);
 	g_assert_false(ret);
 	g_assert_error(error, GPLUGIN_DOMAIN, 0);
 	g_clear_error(&error);
 
-	ret = gplugin_manager_unregister_loader(TEST_GPLUGIN_TYPE_LOADER, &error);
+	ret = gplugin_manager_unregister_loader(
+		manager,
+		TEST_GPLUGIN_TYPE_LOADER,
+		&error);
 	g_assert_no_error(error);
 	g_assert_true(ret);
 }
@@ -135,21 +156,33 @@
 static void
 test_gplugin_manager_loader_unregister_twice(void)
 {
+	GPluginManager *manager = NULL;
 	GError *error = NULL;
 	gboolean ret;
 
 	gplugin_manager_private_uninit();
 	gplugin_manager_private_init(TRUE);
 
-	ret = gplugin_manager_register_loader(TEST_GPLUGIN_TYPE_LOADER, &error);
+	manager = gplugin_manager_get_default();
+
+	ret = gplugin_manager_register_loader(
+		manager,
+		TEST_GPLUGIN_TYPE_LOADER,
+		&error);
 	g_assert_no_error(error);
 	g_assert_true(ret);
 
-	ret = gplugin_manager_unregister_loader(TEST_GPLUGIN_TYPE_LOADER, &error);
+	ret = gplugin_manager_unregister_loader(
+		manager,
+		TEST_GPLUGIN_TYPE_LOADER,
+		&error);
 	g_assert_no_error(error);
 	g_assert_true(ret);
 
-	ret = gplugin_manager_unregister_loader(TEST_GPLUGIN_TYPE_LOADER, &error);
+	ret = gplugin_manager_unregister_loader(
+		manager,
+		TEST_GPLUGIN_TYPE_LOADER,
+		&error);
 	g_assert_false(ret);
 	g_assert_error(error, GPLUGIN_DOMAIN, 0);
 	g_clear_error(&error);
diff --git a/gplugin/tests/test-native-loader.c b/gplugin/tests/test-native-loader.c
--- a/gplugin/tests/test-native-loader.c
+++ b/gplugin/tests/test-native-loader.c
@@ -29,26 +29,28 @@
 static void
 test_broken_depend_plugin_load(void)
 {
+	GPluginManager *manager = gplugin_manager_get_default();
 	GPluginPlugin *plugin = NULL;
 	GPluginPluginState state;
 	GError *error = NULL;
 
 	/* add the test directory to the plugin manager's search paths */
-	gplugin_manager_append_path(TEST_DIR);
+	gplugin_manager_append_path(manager, TEST_DIR);
 
 	/* refresh the plugin manager */
-	gplugin_manager_refresh();
+	gplugin_manager_refresh(manager);
 
 	/* find the dependent plugin and make sure it isn't loaded */
-	plugin =
-		gplugin_manager_find_plugin("gplugin/broken-dependent-native-plugin");
+	plugin = gplugin_manager_find_plugin(
+		manager,
+		"gplugin/broken-dependent-native-plugin");
 	g_assert_nonnull(plugin);
 
 	state = gplugin_plugin_get_state(plugin);
 	g_assert_cmpint(state, !=, GPLUGIN_PLUGIN_STATE_LOADED);
 
 	/* now attempt to load the dependent plugin, it's supposed to fail */
-	g_assert_false(gplugin_manager_load_plugin(plugin, &error));
+	g_assert_false(gplugin_manager_load_plugin(manager, plugin, &error));
 	g_assert_error(error, GPLUGIN_DOMAIN, 0);
 	g_error_free(error);
 }
@@ -59,16 +61,17 @@
 static void
 test_query_error_subprocess(void)
 {
+	GPluginManager *manager = gplugin_manager_get_default();
 	GPluginPlugin *plugin = NULL;
 
 	/* add the test directory to the plugin manager's search paths */
-	gplugin_manager_append_path(TEST_BAD_DIR);
+	gplugin_manager_append_path(manager, TEST_BAD_DIR);
 
 	/* refresh the plugin manager */
-	gplugin_manager_refresh();
+	gplugin_manager_refresh(manager);
 
 	/* find the query-error plugin */
-	plugin = gplugin_manager_find_plugin("gplugin/query-error");
+	plugin = gplugin_manager_find_plugin(manager, "gplugin/query-error");
 	g_assert_null(plugin);
 }
 
diff --git a/gplugin/tests/test-newest-version.c b/gplugin/tests/test-newest-version.c
--- a/gplugin/tests/test-newest-version.c
+++ b/gplugin/tests/test-newest-version.c
@@ -25,13 +25,14 @@
 static void
 test_newest_version(const gchar *id, const gchar *version)
 {
+	GPluginManager *manager = gplugin_manager_get_default();
 	GPluginPlugin *plugin = NULL;
 	GPluginPluginInfo *info = NULL;
 
-	gplugin_manager_append_path(TEST_DIR);
-	gplugin_manager_refresh();
+	gplugin_manager_append_path(manager, TEST_DIR);
+	gplugin_manager_refresh(manager);
 
-	plugin = gplugin_manager_find_plugin_with_newest_version(id);
+	plugin = gplugin_manager_find_plugin_with_newest_version(manager, id);
 	g_assert_nonnull(plugin);
 	g_assert_true(GPLUGIN_IS_PLUGIN(plugin));
 
diff --git a/gplugin/tests/test-option-group.c b/gplugin/tests/test-option-group.c
--- a/gplugin/tests/test-option-group.c
+++ b/gplugin/tests/test-option-group.c
@@ -25,6 +25,7 @@
 static void
 test_gplugin_option_group_paths(const gchar *args, GList *expected)
 {
+	GPluginManager *manager = NULL;
 	GError *error = NULL;
 	GOptionContext *ctx = NULL;
 	GOptionGroup *group = NULL;
@@ -41,7 +42,12 @@
 
 	g_strfreev(argv);
 
-	paths = gplugin_manager_get_paths();
+	/* the above gplugin_get_option_group will call gplugin_init if it hasn't
+	 * been called yet. Untill gplugin_init is called manager will be NULL.
+	 */
+	manager = gplugin_manager_get_default();
+
+	paths = gplugin_manager_get_paths(manager);
 	paths = g_list_sort(paths, g_str_equal);
 
 	expected = g_list_sort(expected, g_str_equal); //-V522
diff --git a/gplugin/tests/test-plugin-manager-paths.c b/gplugin/tests/test-plugin-manager-paths.c
--- a/gplugin/tests/test-plugin-manager-paths.c
+++ b/gplugin/tests/test-plugin-manager-paths.c
@@ -22,7 +22,8 @@
 #define test_path_count(e) \
 	G_STMT_START \
 		{ \
-			GList *paths = gplugin_manager_get_paths(); \
+			GPluginManager *manager = gplugin_manager_get_default(); \
+			GList *paths = gplugin_manager_get_paths(manager); \
 			g_assert_cmpint(g_list_length(paths), ==, (e)); \
 		} \
 	G_STMT_END
@@ -33,100 +34,113 @@
 static void
 test_gplugin_manager_paths_single(void)
 {
-	gplugin_manager_append_path("foo");
+	GPluginManager *manager = gplugin_manager_get_default();
+
+	gplugin_manager_append_path(manager, "foo");
 	test_path_count(1);
 
-	gplugin_manager_remove_path("foo");
+	gplugin_manager_remove_path(manager, "foo");
 	test_path_count(0);
 }
 
 static void
 test_gplugin_manager_paths_duplicate(void)
 {
-	gplugin_manager_append_path("foo");
-	gplugin_manager_append_path("foo");
+	GPluginManager *manager = gplugin_manager_get_default();
+
+	gplugin_manager_append_path(manager, "foo");
+	gplugin_manager_append_path(manager, "foo");
 
 	test_path_count(1);
 
-	gplugin_manager_remove_path("foo");
+	gplugin_manager_remove_path(manager, "foo");
 	test_path_count(0);
 }
 
 static void
 test_gplugin_manager_paths_multiple_fifo(void)
 {
+	GPluginManager *manager = gplugin_manager_get_default();
+
 	/* add */
-	gplugin_manager_append_path("foo");
+	gplugin_manager_append_path(manager, "foo");
 	test_path_count(1);
 
-	gplugin_manager_append_path("bar");
+	gplugin_manager_append_path(manager, "bar");
 	test_path_count(2);
 
 	/* remove */
-	gplugin_manager_remove_path("foo");
+	gplugin_manager_remove_path(manager, "foo");
 	test_path_count(1);
 
-	gplugin_manager_remove_path("bar");
+	gplugin_manager_remove_path(manager, "bar");
 	test_path_count(0);
 }
 
 static void
 test_gplugin_manager_paths_multiple_filo(void)
 {
+	GPluginManager *manager = gplugin_manager_get_default();
+
 	/* add */
-	gplugin_manager_append_path("foo");
+	gplugin_manager_append_path(manager, "foo");
 	test_path_count(1);
 
-	gplugin_manager_append_path("bar");
+	gplugin_manager_append_path(manager, "bar");
 	test_path_count(2);
 
 	/* remove */
-	gplugin_manager_remove_path("bar");
+	gplugin_manager_remove_path(manager, "bar");
 	test_path_count(1);
 
-	gplugin_manager_remove_path("foo");
+	gplugin_manager_remove_path(manager, "foo");
 	test_path_count(0);
 }
 
 static void
 test_gplugin_manager_paths_unicode(void)
 {
+	GPluginManager *manager = gplugin_manager_get_default();
+
 	test_path_count(0);
 
-	gplugin_manager_append_path("/home/🐦/.plugins");
+	gplugin_manager_append_path(manager, "/home/🐦/.plugins");
 	test_path_count(1);
 
-	gplugin_manager_append_path("/home/user/.plugins");
+	gplugin_manager_append_path(manager, "/home/user/.plugins");
 	test_path_count(2);
 
-	gplugin_manager_remove_path("/home/🐦/.plugins");
+	gplugin_manager_remove_path(manager, "/home/🐦/.plugins");
 	test_path_count(1);
 
-	gplugin_manager_remove_path("/home/user/.plugins");
+	gplugin_manager_remove_path(manager, "/home/user/.plugins");
 	test_path_count(0);
 }
 
 static void
 test_gplugin_manager_add_multiple_mixed_trailing_slashes(void)
 {
+	GPluginManager *manager = gplugin_manager_get_default();
+
 	test_path_count(0);
 
-	gplugin_manager_append_path("/home/user1/.plugins");
+	gplugin_manager_append_path(manager, "/home/user1/.plugins");
 	test_path_count(1);
 
-	gplugin_manager_append_path("/home/user2/.plugins/");
+	gplugin_manager_append_path(manager, "/home/user2/.plugins/");
 	test_path_count(2);
 
-	gplugin_manager_remove_path("/home/user1/.plugins/");
+	gplugin_manager_remove_path(manager, "/home/user1/.plugins/");
 	test_path_count(1);
 
-	gplugin_manager_remove_path("/home/user2/.plugins");
+	gplugin_manager_remove_path(manager, "/home/user2/.plugins");
 	test_path_count(0);
 }
 
 static void
 test_gplugin_manager_add_default_paths(void)
 {
+	GPluginManager *manager = gplugin_manager_get_default();
 	GHashTable *req = NULL;
 	GList *paths = NULL, *l = NULL;
 	gchar *path = NULL;
@@ -147,10 +161,10 @@
 	g_hash_table_insert(req, path, GINT_TO_POINTER(FALSE));
 
 	/* now tell the plugin manager to add the default paths */
-	gplugin_manager_add_default_paths();
+	gplugin_manager_add_default_paths(manager);
 
 	/* now remove each path that the manager knows about from our table */
-	paths = gplugin_manager_get_paths();
+	paths = gplugin_manager_get_paths(manager);
 	for(l = paths; l; l = l->next) {
 		g_hash_table_remove(req, l->data);
 	}
@@ -165,6 +179,7 @@
 static void
 test_gplugin_manager_add_app_paths(void)
 {
+	GPluginManager *manager = gplugin_manager_get_default();
 	GHashTable *req = NULL;
 	GList *paths = NULL, *l = NULL;
 	const gchar *prefix = "/usr/local/";
@@ -187,12 +202,12 @@
 	g_hash_table_insert(req, path, GINT_TO_POINTER(FALSE));
 
 	/* now add the app paths */
-	gplugin_manager_add_app_paths(prefix, "foo");
+	gplugin_manager_add_app_paths(manager, prefix, "foo");
 
 	/* now get all the paths that the manager is managing and remove them from
 	 * our required table.
 	 */
-	paths = gplugin_manager_get_paths();
+	paths = gplugin_manager_get_paths(manager);
 	for(l = paths; l != NULL; l = l->next)
 		g_hash_table_remove(req, l->data);
 
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;
-	GPluginManager *manager = gplugin_manager_get_instance();
+	GPluginManager *manager = gplugin_manager_get_default();
 	GError *error = NULL;
 	TestGPluginManagerSignalsData data = {
 		.loading = FALSE,
@@ -173,16 +173,17 @@
 		G_CALLBACK(test_gplugin_manager_signals_normal_unloaded),
 		&data);
 
-	gplugin_manager_append_path(TEST_DIR);
-	gplugin_manager_refresh();
+	gplugin_manager_append_path(manager, TEST_DIR);
+	gplugin_manager_refresh(manager);
 
-	plugin = gplugin_manager_find_plugin("gplugin/native-basic-plugin");
-	gplugin_manager_load_plugin(plugin, &error);
+	plugin =
+		gplugin_manager_find_plugin(manager, "gplugin/native-basic-plugin");
+	gplugin_manager_load_plugin(manager, plugin, &error);
 	g_assert_no_error(error);
 	g_assert_true(data.loading);
 	g_assert_true(data.loaded);
 
-	gplugin_manager_unload_plugin(plugin, &error);
+	gplugin_manager_unload_plugin(manager, plugin, &error);
 	g_assert_no_error(error);
 	g_assert_true(data.unloading);
 	g_assert_true(data.unloaded);
@@ -197,7 +198,7 @@
 test_gplugin_manager_signals_loading_stopped(void)
 {
 	GPluginPlugin *plugin = NULL;
-	GPluginManager *manager = gplugin_manager_get_instance();
+	GPluginManager *manager = gplugin_manager_get_default();
 	GError *error = NULL;
 	TestGPluginManagerSignalsData data = {
 		.loading = FALSE,
@@ -228,11 +229,12 @@
 		G_CALLBACK(test_gplugin_manager_signals_normal_unloaded),
 		&data);
 
-	gplugin_manager_append_path(TEST_DIR);
-	gplugin_manager_refresh();
+	gplugin_manager_append_path(manager, TEST_DIR);
+	gplugin_manager_refresh(manager);
 
-	plugin = gplugin_manager_find_plugin("gplugin/native-basic-plugin");
-	gplugin_manager_load_plugin(plugin, &error);
+	plugin =
+		gplugin_manager_find_plugin(manager, "gplugin/native-basic-plugin");
+	gplugin_manager_load_plugin(manager, plugin, &error);
 	g_assert_error(error, GPLUGIN_DOMAIN, 0);
 	g_error_free(error);
 
@@ -251,7 +253,7 @@
 test_gplugin_manager_signals_unloading_stopped(void)
 {
 	GPluginPlugin *plugin = NULL;
-	GPluginManager *manager = gplugin_manager_get_instance();
+	GPluginManager *manager = gplugin_manager_get_default();
 	GError *error = NULL;
 	TestGPluginManagerSignalsData data = {
 		.loading = FALSE,
@@ -282,16 +284,17 @@
 		G_CALLBACK(test_gplugin_manager_signals_normal_unloaded),
 		&data);
 
-	gplugin_manager_append_path(TEST_DIR);
-	gplugin_manager_refresh();
+	gplugin_manager_append_path(manager, TEST_DIR);
+	gplugin_manager_refresh(manager);
 
-	plugin = gplugin_manager_find_plugin("gplugin/native-basic-plugin");
-	gplugin_manager_load_plugin(plugin, &error);
+	plugin =
+		gplugin_manager_find_plugin(manager, "gplugin/native-basic-plugin");
+	gplugin_manager_load_plugin(manager, plugin, &error);
 	g_assert_no_error(error);
 	g_assert_true(data.loading);
 	g_assert_true(data.loaded);
 
-	gplugin_manager_unload_plugin(plugin, &error);
+	gplugin_manager_unload_plugin(manager, plugin, &error);
 	g_assert_error(error, GPLUGIN_DOMAIN, 0);
 	g_error_free(error);
 
@@ -308,7 +311,7 @@
 test_gplugin_manager_signals_load_failure(void)
 {
 	GPluginPlugin *plugin = NULL;
-	GPluginManager *manager = gplugin_manager_get_instance();
+	GPluginManager *manager = gplugin_manager_get_default();
 	GError *error = NULL;
 	TestGPluginManagerSignalsData data = {
 		.loading = FALSE,
@@ -327,11 +330,11 @@
 		G_CALLBACK(test_gplugin_manager_signals_load_failed),
 		&data);
 
-	gplugin_manager_append_path(TEST_DIR);
-	gplugin_manager_refresh();
+	gplugin_manager_append_path(manager, TEST_DIR);
+	gplugin_manager_refresh(manager);
 
-	plugin = gplugin_manager_find_plugin("gplugin/native-load-failed");
-	gplugin_manager_load_plugin(plugin, &error);
+	plugin = gplugin_manager_find_plugin(manager, "gplugin/native-load-failed");
+	gplugin_manager_load_plugin(manager, plugin, &error);
 	g_assert_error(error, GPLUGIN_DOMAIN, 0);
 	g_error_free(error);
 
@@ -346,7 +349,7 @@
 test_gplugin_manager_signals_unload_failure(void)
 {
 	GPluginPlugin *plugin = NULL;
-	GPluginManager *manager = gplugin_manager_get_instance();
+	GPluginManager *manager = gplugin_manager_get_default();
 	GError *error = NULL;
 	TestGPluginManagerSignalsData data = {
 		.loading = FALSE,
@@ -377,16 +380,17 @@
 		G_CALLBACK(test_gplugin_manager_signals_unload_failed),
 		&data);
 
-	gplugin_manager_append_path(TEST_DIR);
-	gplugin_manager_refresh();
+	gplugin_manager_append_path(manager, TEST_DIR);
+	gplugin_manager_refresh(manager);
 
-	plugin = gplugin_manager_find_plugin("gplugin/native-unload-failed");
-	gplugin_manager_load_plugin(plugin, &error);
+	plugin =
+		gplugin_manager_find_plugin(manager, "gplugin/native-unload-failed");
+	gplugin_manager_load_plugin(manager, plugin, &error);
 	g_assert_no_error(error);
 	g_assert_true(data.loading);
 	g_assert_true(data.loaded);
 
-	gplugin_manager_unload_plugin(plugin, &error);
+	gplugin_manager_unload_plugin(manager, plugin, &error);
 	g_assert_error(error, GPLUGIN_DOMAIN, 0);
 	g_error_free(error);
 
diff --git a/gplugin/tests/test-unresolved-symbol.c b/gplugin/tests/test-unresolved-symbol.c
--- a/gplugin/tests/test-unresolved-symbol.c
+++ b/gplugin/tests/test-unresolved-symbol.c
@@ -29,14 +29,16 @@
 static void
 test_unresolved_symbol(void)
 {
+	GPluginManager *manager = gplugin_manager_get_default();
+
 	g_test_expect_message(
 		G_LOG_DOMAIN,
 		G_LOG_LEVEL_WARNING,
 		"*some_unresolved_symbol*");
 
-	gplugin_manager_remove_paths();
-	gplugin_manager_append_path(PLUGIN_DIR);
-	gplugin_manager_refresh();
+	gplugin_manager_remove_paths(manager);
+	gplugin_manager_append_path(manager, PLUGIN_DIR);
+	gplugin_manager_refresh(manager);
 
 	g_test_assert_expected_messages();
 }
diff --git a/gplugin/tests/test-versioned-dependencies.c b/gplugin/tests/test-versioned-dependencies.c
--- a/gplugin/tests/test-versioned-dependencies.c
+++ b/gplugin/tests/test-versioned-dependencies.c
@@ -25,9 +25,10 @@
 static void
 _test_plugin_loaded(GPluginPlugin *dependent, const gchar *id)
 {
+	GPluginManager *manager = gplugin_manager_get_default();
 	GPluginPlugin *plugin = NULL;
 
-	plugin = gplugin_manager_find_plugin(id);
+	plugin = gplugin_manager_find_plugin(manager, id);
 	g_assert_cmpint(
 		gplugin_plugin_get_state(plugin),
 		==,
@@ -42,20 +43,23 @@
 static void
 test_load_with_dependencies(void)
 {
+	GPluginManager *manager = NULL;
 	GPluginPlugin *plugin = NULL;
 	GError *error = NULL;
 	gboolean ret = FALSE;
 
 	gplugin_init(GPLUGIN_CORE_FLAGS_NONE);
 
-	gplugin_manager_append_path(TEST_VERSIONED_DEPENDENCY_DIR);
-	gplugin_manager_refresh();
+	manager = gplugin_manager_get_default();
 
-	plugin = gplugin_manager_find_plugin("gplugin/super-dependent");
+	gplugin_manager_append_path(manager, TEST_VERSIONED_DEPENDENCY_DIR);
+	gplugin_manager_refresh(manager);
+
+	plugin = gplugin_manager_find_plugin(manager, "gplugin/super-dependent");
 	g_assert_nonnull(plugin);
 	g_assert_true(GPLUGIN_IS_PLUGIN(plugin));
 
-	ret = gplugin_manager_load_plugin(plugin, &error);
+	ret = gplugin_manager_load_plugin(manager, plugin, &error);
 	g_assert_no_error(error);
 	g_assert_true(ret);
 
diff --git a/lua/gplugin-lua-core.c b/lua/gplugin-lua-core.c
--- a/lua/gplugin-lua-core.c
+++ b/lua/gplugin-lua-core.c
@@ -56,10 +56,17 @@
 static gboolean
 gplugin_lua_load(GPluginPlugin *plugin, GError **error)
 {
+	GPluginManager *manager = NULL;
+
+	manager = gplugin_manager_get_default();
+
 	gplugin_lua_loader_register(G_TYPE_MODULE(plugin));
 	gplugin_lua_plugin_register(G_TYPE_MODULE(plugin));
 
-	return gplugin_manager_register_loader(GPLUGIN_LUA_TYPE_LOADER, error);
+	return gplugin_manager_register_loader(
+		manager,
+		GPLUGIN_LUA_TYPE_LOADER,
+		error);
 }
 
 static gboolean
diff --git a/perl5/gplugin-perl5-core.c b/perl5/gplugin-perl5-core.c
--- a/perl5/gplugin-perl5-core.c
+++ b/perl5/gplugin-perl5-core.c
@@ -55,10 +55,17 @@
 static gboolean
 gplugin_perl5_load(GPluginPlugin *plugin, GError **error)
 {
+	GPluginManager *manager = NULL;
+
+	manager = gplugin_manager_get_default();
+
 	gplugin_perl_plugin_register(G_TYPE_MODULE(plugin));
 	gplugin_perl_loader_register(G_TYPE_MODULE(plugin));
 
-	return gplugin_manager_register_loader(GPLUGIN_PERL_TYPE_LOADER, error);
+	return gplugin_manager_register_loader(
+		manager,
+		GPLUGIN_PERL_TYPE_LOADER,
+		error);
 }
 
 static gboolean
diff --git a/python3/gplugin-python3-core.c b/python3/gplugin-python3-core.c
--- a/python3/gplugin-python3-core.c
+++ b/python3/gplugin-python3-core.c
@@ -56,10 +56,17 @@
 static gboolean
 gplugin_python3_load(GPluginPlugin *plugin, GError **error)
 {
+	GPluginManager *manager = NULL;
+
+	manager = gplugin_manager_get_default();
+
 	gplugin_python3_plugin_register(G_TYPE_MODULE(plugin));
 	gplugin_python3_loader_register(G_TYPE_MODULE(plugin));
 
-	return gplugin_manager_register_loader(GPLUGIN_PYTHON3_TYPE_LOADER, error);
+	return gplugin_manager_register_loader(
+		manager,
+		GPLUGIN_PYTHON3_TYPE_LOADER,
+		error);
 }
 
 static gboolean
