[rygel-gst-0-10-plugins] More cleanup.



commit 96dd383e93ea103605bc3fe8e34f79af1f73345f
Author: Krzesimir Nowak <krnowak openismus com>
Date:   Mon Jan 28 16:11:52 2013 +0100

    More cleanup.

 src/media-export/Makefile.am                       |    1 +
 src/media-export/rygel-media-export-item-factory.c |    4 +-
 .../rygel-media-export-node-query-container.c      |   37 +-
 .../rygel-media-export-object-factory.c            |    4 +-
 .../rygel-media-export-query-container-factory.c   |   11 +-
 .../rygel-media-export-query-container-factory.h   |    2 -
 .../rygel-media-export-root-container.c            | 2793 ++++++--------------
 src/media-export/rygel-media-export-string-utils.c |   97 +
 src/media-export/rygel-media-export-string-utils.h |   41 +
 tests/test_simple.c                                |   16 +-
 10 files changed, 988 insertions(+), 2018 deletions(-)
---
diff --git a/src/media-export/Makefile.am b/src/media-export/Makefile.am
index 9694806..b0acb82 100644
--- a/src/media-export/Makefile.am
+++ b/src/media-export/Makefile.am
@@ -32,6 +32,7 @@ librygel_media_export_gst_0_10_la_SOURCES = \
 	rygel-media-export-sql-function.c \
 	rygel-media-export-sql-operator.c \
 	rygel-media-export-sqlite-wrapper.c \
+	rygel-media-export-string-utils.c \
 	rygel-media-export-video-item.c \
 	rygel-media-export-writable-db-container.c
 
diff --git a/src/media-export/rygel-media-export-item-factory.c b/src/media-export/rygel-media-export-item-factory.c
index 5cb6490..a2b9743 100644
--- a/src/media-export/rygel-media-export-item-factory.c
+++ b/src/media-export/rygel-media-export-item-factory.c
@@ -90,8 +90,8 @@ rygel_media_export_item_factory_create_from_info (RygelMediaContainer *parent, G
   id = rygel_media_export_media_cache_get_id (file);
   discoverer_info = gupnp_dlna_information_get_info (dlna_info);
 
-  audio_streams = gst_discoverer_info_get_audio_streams ((GstDiscovererInfo *)dlna_info);
-  video_streams = gst_discoverer_info_get_video_streams ((GstDiscovererInfo *)dlna_info);
+  audio_streams = gst_discoverer_info_get_audio_streams ((GstDiscovererInfo *) discoverer_info);
+  video_streams = gst_discoverer_info_get_video_streams ((GstDiscovererInfo *) discoverer_info);
 
   if( !audio_streams && !video_streams) {
     gchar *uri = g_file_get_uri (file);
diff --git a/src/media-export/rygel-media-export-node-query-container.c b/src/media-export/rygel-media-export-node-query-container.c
index 66f72d5..2ae9a9c 100644
--- a/src/media-export/rygel-media-export-node-query-container.c
+++ b/src/media-export/rygel-media-export-node-query-container.c
@@ -20,6 +20,7 @@
 
 #include "rygel-media-export-node-query-container.h"
 #include "rygel-media-export-query-container-factory.h"
+#include "rygel-media-export-string-utils.h"
 
 G_DEFINE_TYPE (RygelMediaExportNodeQueryContainer,
                rygel_media_export_node_query_container,
@@ -65,39 +66,6 @@ rygel_media_export_node_query_container_new (RygelSearchExpression *expression,
                                                                 NULL));
 }
 
-static gchar*
-string_replace (const gchar  *self,
-                const gchar  *old,
-                const gchar  *replacement,
-                GError      **error) {
-  gchar* result;
-  gchar *escaped;
-  GError *inner_error;
-  GRegex *regex;
-
-  g_return_val_if_fail (self != NULL, NULL);
-  g_return_val_if_fail (old != NULL, NULL);
-  g_return_val_if_fail (replacement != NULL, NULL);
-
-  result = NULL;
-  escaped = g_regex_escape_string (old, -1);
-  inner_error = NULL;
-  regex = g_regex_new (escaped, 0, 0, &inner_error);
-  g_free (escaped);
-  if (inner_error) {
-    g_propagate_error (error, inner_error);
-  } else {
-    result = g_regex_replace_literal (regex, self, -1, 0, replacement, 0, &inner_error);
-
-    if (inner_error) {
-      g_propagate_error (error, inner_error);
-    }
-    g_regex_unref (regex);
-  }
-
-  return result;
-}
-
 static void
 rygel_media_export_node_query_container_real_get_children (RygelMediaContainer *base,
                                                            guint                offset,
@@ -133,7 +101,7 @@ rygel_media_export_node_query_container_real_get_children (RygelMediaContainer *
     for (iter = 0; iter < collection_size; ++iter) {
       gchar *meta_data = gee_list_get (data, iter);
       gchar *tmp_id = g_uri_escape_string (meta_data, "", TRUE);
-      gchar *new_id = string_replace (priv->template, "%s", tmp_id, &error);
+      gchar *new_id = rygel_media_export_string_replace (priv->template, "%s", tmp_id, &error);
 
       if (error) {
         g_warning ("Failed to replace a %%s placeholder in template (%s) with an id (%s): %s",
@@ -144,7 +112,6 @@ rygel_media_export_node_query_container_real_get_children (RygelMediaContainer *
         error = NULL;
       } else {
         RygelMediaExportQueryContainer *container = rygel_media_export_query_container_factory_create_from_description (factory,
-                                                                                                                        cache,
                                                                                                                         new_id,
                                                                                                                         meta_data);
         RygelMediaObject *object = RYGEL_MEDIA_OBJECT (container);
diff --git a/src/media-export/rygel-media-export-object-factory.c b/src/media-export/rygel-media-export-object-factory.c
index b339104..1115e71 100644
--- a/src/media-export/rygel-media-export-object-factory.c
+++ b/src/media-export/rygel-media-export-object-factory.c
@@ -129,17 +129,15 @@ static RygelMediaExportDBContainer* rygel_media_export_object_factory_real_get_c
 		RygelMediaExportQueryContainerFactory* _tmp10_ = NULL;
 		RygelMediaExportQueryContainerFactory* factory;
 		RygelMediaExportQueryContainerFactory* _tmp11_;
-		RygelMediaExportMediaCache* _tmp12_;
 		const gchar* _tmp13_;
 		const gchar* _tmp14_;
 		RygelMediaExportQueryContainer* _tmp15_ = NULL;
 		_tmp10_ = rygel_media_export_query_container_factory_get_default ();
 		factory = _tmp10_;
 		_tmp11_ = factory;
-		_tmp12_ = media_db;
 		_tmp13_ = id;
 		_tmp14_ = title;
-		_tmp15_ = rygel_media_export_query_container_factory_create_from_id (_tmp11_, _tmp12_, _tmp13_, _tmp14_);
+		_tmp15_ = rygel_media_export_query_container_factory_create_from_id (_tmp11_, _tmp13_, _tmp14_);
 		result = (RygelMediaExportDBContainer*) _tmp15_;
 		g_object_unref (factory);
 		return result;
diff --git a/src/media-export/rygel-media-export-query-container-factory.c b/src/media-export/rygel-media-export-query-container-factory.c
index e4aa53a..75b8929 100644
--- a/src/media-export/rygel-media-export-query-container-factory.c
+++ b/src/media-export/rygel-media-export-query-container-factory.c
@@ -246,18 +246,16 @@ gchar* rygel_media_export_query_container_factory_get_virtual_container_definiti
      *              container
      * @return A new instance of QueryContainer or null if id does not exist
      */
-RygelMediaExportQueryContainer* rygel_media_export_query_container_factory_create_from_id (RygelMediaExportQueryContainerFactory* self, RygelMediaExportMediaCache* cache, const gchar* id, const gchar* name) {
+RygelMediaExportQueryContainer* rygel_media_export_query_container_factory_create_from_id (RygelMediaExportQueryContainerFactory* self, const gchar* id, const gchar* name) {
 	RygelMediaExportQueryContainer* result = NULL;
 	const gchar* _tmp0_;
 	gchar* _tmp1_ = NULL;
 	gchar* definition;
 	const gchar* _tmp2_;
-	RygelMediaExportMediaCache* _tmp3_;
 	const gchar* _tmp4_;
 	const gchar* _tmp5_;
 	RygelMediaExportQueryContainer* _tmp6_ = NULL;
 	g_return_val_if_fail (self != NULL, NULL);
-	g_return_val_if_fail (cache != NULL, NULL);
 	g_return_val_if_fail (id != NULL, NULL);
 	g_return_val_if_fail (name != NULL, NULL);
 	_tmp0_ = id;
@@ -269,10 +267,9 @@ RygelMediaExportQueryContainer* rygel_media_export_query_container_factory_creat
 		g_free (definition);
 		return result;
 	}
-	_tmp3_ = cache;
 	_tmp4_ = definition;
 	_tmp5_ = name;
-	_tmp6_ = rygel_media_export_query_container_factory_create_from_description (self, _tmp3_, _tmp4_, _tmp5_);
+	_tmp6_ = rygel_media_export_query_container_factory_create_from_description (self, _tmp4_, _tmp5_);
 	result = _tmp6_;
 	g_free (definition);
 	return result;
@@ -284,14 +281,13 @@ RygelMediaExportQueryContainer* rygel_media_export_query_container_factory_creat
      *
      * Create a QueryContainer from a plain-text description string.
      *
-     * @param cache      An instance of the meta-data cache
      * @param definition Plain-text defintion of the query-container
      * @param name       The title of the container. If not supplied, it
      *                   will be derived from the plain-text description of
      *                   the container
      * @return A new instance of QueryContainer
      */
-RygelMediaExportQueryContainer* rygel_media_export_query_container_factory_create_from_description (RygelMediaExportQueryContainerFactory* self, RygelMediaExportMediaCache* cache, const gchar* definition, const gchar* name) {
+RygelMediaExportQueryContainer* rygel_media_export_query_container_factory_create_from_description (RygelMediaExportQueryContainerFactory* self, const gchar* definition, const gchar* name) {
 	RygelMediaExportQueryContainer* result = NULL;
 	const gchar* _tmp0_;
 	gchar* _tmp1_;
@@ -314,7 +310,6 @@ RygelMediaExportQueryContainer* rygel_media_export_query_container_factory_creat
 	gboolean _tmp12_;
 	const gchar* _tmp25_;
 	g_return_val_if_fail (self != NULL, NULL);
-	g_return_val_if_fail (cache != NULL, NULL);
 	g_return_val_if_fail (definition != NULL, NULL);
 	g_return_val_if_fail (name != NULL, NULL);
 	_tmp0_ = name;
diff --git a/src/media-export/rygel-media-export-query-container-factory.h b/src/media-export/rygel-media-export-query-container-factory.h
index 0ea8362..f8af67d 100644
--- a/src/media-export/rygel-media-export-query-container-factory.h
+++ b/src/media-export/rygel-media-export-query-container-factory.h
@@ -57,13 +57,11 @@ rygel_media_export_query_container_factory_get_default (void);
 
 RygelMediaExportQueryContainer *
 rygel_media_export_query_container_factory_create_from_id (RygelMediaExportQueryContainerFactory *self,
-							   RygelMediaExportMediaCache            *cache,
 							   const gchar                           *id,
 							   const gchar                           *name);
 
 RygelMediaExportQueryContainer *
 rygel_media_export_query_container_factory_create_from_description (RygelMediaExportQueryContainerFactory *self,
-								    RygelMediaExportMediaCache            *cache,
 								    const gchar                           *definition,
 								    const gchar                           *name);
 
diff --git a/src/media-export/rygel-media-export-root-container.c b/src/media-export/rygel-media-export-root-container.c
index 684fe8f..1b4111d 100644
--- a/src/media-export/rygel-media-export-root-container.c
+++ b/src/media-export/rygel-media-export-root-container.c
@@ -26,6 +26,7 @@
 #include "rygel-media-export-query-container-factory.h"
 #include "rygel-media-export-query-container.h"
 #include "rygel-media-export-root-container.h"
+#include "rygel-media-export-string-utils.h"
 
 /**
  * Represents the root container.
@@ -40,2054 +41,920 @@ G_DEFINE_TYPE_WITH_CODE (RygelMediaExportRootContainer,
 			 G_IMPLEMENT_INTERFACE (RYGEL_TYPE_SEARCHABLE_CONTAINER,
 						rygel_media_export_root_container_rygel_searchable_container_interface_init))
 
-#define RYGEL_MEDIA_EXPORT_TYPE_FOLDER_DEFINITION (rygel_media_export_folder_definition_get_type ())
 typedef struct _RygelMediaExportFolderDefinition RygelMediaExportFolderDefinition;
 typedef struct _RygelMediaExportRootContainerFindObjectData RygelMediaExportRootContainerFindObjectData;
-#define rygel_search_expression_unref(var) ((var == NULL) ? NULL : (var = (rygel_search_expression_unref (var), NULL)))
 typedef struct _RygelMediaExportRootContainerSearchData RygelMediaExportRootContainerSearchData;
-#define g_regex_unref(var) ((var == NULL) ? NULL : (var = (g_regex_unref (var), NULL)))
 
 struct _RygelMediaExportFolderDefinition {
-	gchar* title;
-	gchar* definition;
+  gchar *title;
+  gchar *definition;
 };
 
-
 struct _RygelMediaExportRootContainerPrivate {
-	RygelMediaExportHarvester* harvester;
-	GCancellable* cancellable;
-	RygelMediaContainer* filesystem_container;
-	gulong harvester_signal_id;
+  RygelMediaExportHarvester *harvester;
+  GCancellable *cancellable;
+  RygelMediaContainer *filesystem_container;
+  gulong harvester_signal_id;
 };
 
 struct _RygelMediaExportRootContainerFindObjectData {
-	int _state_;
-	GObject* _source_object_;
-	GAsyncResult* _res_;
-	GSimpleAsyncResult* _async_result;
-	RygelMediaExportRootContainer* self;
-	gchar* id;
-	GCancellable* cancellable;
-	RygelMediaObject* result;
-	const gchar* _tmp0_;
-	GCancellable* _tmp1_;
-	RygelMediaObject* _tmp2_;
-	RygelMediaObject* object;
-	gboolean _tmp3_;
-	const gchar* _tmp4_;
-	gboolean _tmp5_;
-	gboolean _tmp6_;
-	RygelMediaExportQueryContainerFactory* _tmp7_;
-	RygelMediaExportQueryContainerFactory* factory;
-	RygelMediaExportQueryContainerFactory* _tmp8_;
-	RygelMediaExportMediaCache* _tmp9_;
-	const gchar* _tmp10_;
-	RygelMediaExportQueryContainer* _tmp11_;
-	RygelMediaExportQueryContainer* container;
-	RygelMediaExportQueryContainer* _tmp12_;
-	RygelMediaExportQueryContainer* _tmp13_;
-	GError * _inner_error_;
+  GSimpleAsyncResult *simple;
+  gchar *id;
 };
 
 struct _RygelMediaExportRootContainerSearchData {
-	int _state_;
-	GObject* _source_object_;
-	GAsyncResult* _res_;
-	GSimpleAsyncResult* _async_result;
-	RygelMediaExportRootContainer* self;
-	RygelSearchExpression* expression;
-	guint offset;
-	guint max_count;
-	guint total_matches;
-	gchar* sort_criteria;
-	GCancellable* cancellable;
-	RygelMediaObjects* result;
-	RygelSearchExpression* _tmp0_;
-	RygelSearchExpression* _tmp1_;
-	guint _tmp2_;
-	guint _tmp3_;
-	const gchar* _tmp4_;
-	GCancellable* _tmp5_;
-	guint _tmp6_;
-	RygelMediaObjects* _tmp7_;
-	RygelMediaObjects* _tmp8_;
-	RygelMediaObjects* list;
-	RygelMediaContainer* query_container;
-	gchar* upnp_class;
-	RygelSearchExpression* _tmp9_;
-	RygelSearchExpression* _tmp10_;
-	RygelRelationalExpression* _tmp11_;
-	RygelRelationalExpression* relational_expression;
-	RygelRelationalExpression* _tmp12_;
-	RygelMediaExportQueryContainer* _tmp13_;
-	RygelRelationalExpression* _tmp14_;
-	gconstpointer _tmp15_;
-	gchar* _tmp16_;
-	RygelSearchExpression* _tmp17_;
-	RygelMediaContainer* _tmp18_;
-	gboolean _tmp19_;
-	RygelMediaContainer* _tmp20_;
-	RygelMediaContainer* _tmp21_;
-	guint _tmp22_;
-	guint _tmp23_;
-	const gchar* _tmp24_;
-	GCancellable* _tmp25_;
-	RygelMediaObjects* _tmp26_;
-	RygelMediaObjects* _tmp27_;
-	RygelMediaContainer* _tmp28_;
-	gint _tmp29_;
-	const gchar* _tmp30_;
-	RygelMediaObjects* _tmp31_;
-	RygelMediaObjects* _tmp32_;
-	RygelMediaObjects* _object_list;
-	RygelMediaObjects* _tmp33_;
-	gint _tmp34_;
-	gint _tmp35_;
-	gint _object_size;
-	gint _object_index;
-	gint _tmp36_;
-	gint _tmp37_;
-	gint _tmp38_;
-	RygelMediaObjects* _tmp39_;
-	gint _tmp40_;
-	gpointer _tmp41_;
-	RygelMediaObject* object;
-	RygelMediaObject* _tmp42_;
-	const gchar* _tmp43_;
-	RygelSearchExpression* _tmp44_;
-	guint _tmp45_;
-	guint _tmp46_;
-	const gchar* _tmp47_;
-	GCancellable* _tmp48_;
-	guint _tmp49_;
-	RygelMediaObjects* _tmp50_;
-	RygelMediaObjects* _tmp51_;
-	GError * _inner_error_;
+  GSimpleAsyncResult *simple;
+  guint total_matches;
+  RygelMediaObjects *result;
+  RygelMediaContainer *query_container;
+  gchar *upnp_class;
 };
 
 
-static RygelMediaContainer* rygel_media_export_root_container_instance = NULL;
-static GError* rygel_media_export_root_container_creation_error = NULL;
+static RygelMediaContainer *rygel_media_export_root_container_instance = NULL;
+static GError *rygel_media_export_root_container_creation_error = NULL;
 static RygelSearchableContainerIface *parent_searchable_container_iface = NULL;
 
-GType rygel_media_export_folder_definition_get_type (void) G_GNUC_CONST;
-RygelMediaExportFolderDefinition* rygel_media_export_folder_definition_dup (const RygelMediaExportFolderDefinition* self);
-void rygel_media_export_folder_definition_free (RygelMediaExportFolderDefinition* self);
-void rygel_media_export_folder_definition_copy (const RygelMediaExportFolderDefinition* self, RygelMediaExportFolderDefinition* dest);
-void rygel_media_export_folder_definition_destroy (RygelMediaExportFolderDefinition* self);
-#define RYGEL_MEDIA_EXPORT_ROOT_CONTAINER_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), RYGEL_MEDIA_EXPORT_TYPE_ROOT_CONTAINER, RygelMediaExportRootContainerPrivate))
-enum  {
-	RYGEL_MEDIA_EXPORT_ROOT_CONTAINER_DUMMY_PROPERTY
-};
-
-static RygelMediaExportRootContainer *
-rygel_media_export_root_container_new (GError **error);
+#define RYGEL_MEDIA_EXPORT_ROOT_CONTAINER_GET_PRIVATE(o) \
+  (G_TYPE_INSTANCE_GET_PRIVATE ((o), \
+				RYGEL_MEDIA_EXPORT_TYPE_ROOT_CONTAINER, \
+				RygelMediaExportRootContainerPrivate))
 
 #define RYGEL_MEDIA_EXPORT_ROOT_CONTAINER_SEARCH_CONTAINER_PREFIX RYGEL_MEDIA_EXPORT_QUERY_CONTAINER_PREFIX "upnp:class," RYGEL_MUSIC_ITEM_UPNP_CLASS ","
-static RygelMediaExportRootContainer* rygel_media_export_root_container_construct (GType object_type, GError** error);
-static void rygel_media_export_root_container_real_find_object_data_free (gpointer _data);
-static void rygel_media_export_root_container_real_find_object (RygelMediaContainer* base, const gchar* id, GCancellable* cancellable, GAsyncReadyCallback _callback_, gpointer _user_data_);
-static gboolean rygel_media_export_root_container_real_find_object_co (RygelMediaExportRootContainerFindObjectData* _data_);
-static void rygel_media_export_root_container_find_object_ready (GObject* source_object, GAsyncResult* _res_, gpointer _user_data_);
-static void rygel_media_export_root_container_real_search_data_free (gpointer _data);
-static void rygel_media_export_root_container_real_search (RygelSearchableContainer* base, RygelSearchExpression* expression, guint offset, guint max_count, const gchar* sort_criteria, GCancellable* cancellable, GAsyncReadyCallback _callback_, gpointer _user_data_);
-static gboolean rygel_media_export_root_container_real_search_co (RygelMediaExportRootContainerSearchData* _data_);
-static void rygel_media_export_root_container_search_ready (GObject* source_object, GAsyncResult* _res_, gpointer _user_data_);
-static RygelMediaExportQueryContainer* rygel_media_export_root_container_search_to_virtual_container (RygelMediaExportRootContainer* self, RygelRelationalExpression* expression);
-static gboolean rygel_media_export_root_container_is_search_in_virtual_container (RygelMediaExportRootContainer* self, RygelSearchExpression* expression, RygelMediaContainer** container);
-static GeeArrayList* rygel_media_export_root_container_get_shared_uris (RygelMediaExportRootContainer* self);
-static void rygel_media_export_root_container_on_initial_harvesting_done (RygelMediaExportRootContainer* self);
-static void _rygel_media_export_root_container_on_initial_harvesting_done_rygel_media_export_harvester_done (RygelMediaExportHarvester* _sender, gpointer self);
-static void rygel_media_export_root_container_add_default_virtual_folders (RygelMediaExportRootContainer* self);
-static void __lambda6_ (RygelMediaExportRootContainer* self);
-static void ___lambda6__rygel_media_container_container_updated (RygelMediaContainer* _sender, RygelMediaContainer* container, RygelMediaObject* object, RygelObjectEventType event_type, gboolean sub_tree_update, gpointer self);
-static void rygel_media_export_root_container_add_virtual_containers_for_class (RygelMediaExportRootContainer* self, const gchar* parent, const gchar* item_class, const RygelMediaExportFolderDefinition* definitions, int definitions_length1, GError** error);
-static void rygel_media_export_root_container_add_folder_definition (RygelMediaExportRootContainer* self, RygelMediaContainer* container, const gchar* item_class, RygelMediaExportFolderDefinition* definition, GError** error);
-gint rygel_media_export_media_cache_get_child_count (RygelMediaExportMediaCache* self, const gchar* container_id, GError** error);
-static void rygel_media_export_root_container_finalize (GObject* obj);
 
 const RygelMediaExportFolderDefinition VIRTUAL_FOLDERS_DEFAULT[2] = {{"Year", "dc:date,?"}, {"All", ""}};
 const RygelMediaExportFolderDefinition VIRTUAL_FOLDERS_MUSIC[3] = {{"Artist", "upnp:artist,?,upnp:album,?"}, {"Album", "upnp:album,?"}, {"Genre", "dc:genre,?"}};
 
-void rygel_media_export_folder_definition_copy (const RygelMediaExportFolderDefinition* self, RygelMediaExportFolderDefinition* dest) {
-	const gchar* _tmp0_;
-	gchar* _tmp1_;
-	const gchar* _tmp2_;
-	gchar* _tmp3_;
-	_tmp0_ = (*self).title;
-	_tmp1_ = g_strdup (_tmp0_);
-	g_free ((*dest).title);
-	(*dest).title = _tmp1_;
-	_tmp2_ = (*self).definition;
-	_tmp3_ = g_strdup (_tmp2_);
-	g_free ((*dest).definition);
-	(*dest).definition = _tmp3_;
-}
-
-
-void rygel_media_export_folder_definition_destroy (RygelMediaExportFolderDefinition* self) {
-	g_free ((*self).title);
-	g_free ((*self).definition);
-}
-
-
-RygelMediaExportFolderDefinition* rygel_media_export_folder_definition_dup (const RygelMediaExportFolderDefinition* self) {
-	RygelMediaExportFolderDefinition* dup;
-	dup = g_new0 (RygelMediaExportFolderDefinition, 1);
-	rygel_media_export_folder_definition_copy (self, dup);
-	return dup;
-}
-
-
-void rygel_media_export_folder_definition_free (RygelMediaExportFolderDefinition* self) {
-	rygel_media_export_folder_definition_destroy (self);
-	g_free (self);
-}
-
-
-GType rygel_media_export_folder_definition_get_type (void) {
-	static volatile gsize rygel_media_export_folder_definition_type_id__volatile = 0;
-	if (g_once_init_enter (&rygel_media_export_folder_definition_type_id__volatile)) {
-		GType rygel_media_export_folder_definition_type_id;
-		rygel_media_export_folder_definition_type_id = g_boxed_type_register_static ("RygelMediaExportFolderDefinition", (GBoxedCopyFunc) rygel_media_export_folder_definition_dup, (GBoxedFreeFunc) rygel_media_export_folder_definition_free);
-		g_once_init_leave (&rygel_media_export_folder_definition_type_id__volatile, rygel_media_export_folder_definition_type_id);
-	}
-	return rygel_media_export_folder_definition_type_id__volatile;
-}
-
-RygelMediaContainer* rygel_media_export_root_container_get_instance (GError** error) {
-	RygelMediaContainer* result = NULL;
-	RygelMediaContainer* _tmp0_;
-	RygelMediaContainer* _tmp9_;
-	RygelMediaContainer* _tmp10_;
-	GError * _inner_error_ = NULL;
-	_tmp0_ = rygel_media_export_root_container_instance;
-	if (_tmp0_ == NULL) {
-		{
-			RygelMediaExportRootContainer* _tmp1_;
-			RygelMediaExportRootContainer* _tmp2_;
-			_tmp1_ = rygel_media_export_root_container_new (&_inner_error_);
-			_tmp2_ = _tmp1_;
-			if (_inner_error_ != NULL) {
-				goto __catch26_g_error;
-			}
-			g_object_unref (rygel_media_export_root_container_instance);
-			rygel_media_export_root_container_instance = (RygelMediaContainer*) _tmp2_;
-		}
-		goto __finally26;
-		__catch26_g_error:
-		{
-			GError* _error_ = NULL;
-			RygelMediaExportNullContainer* _tmp3_;
-			GError* _tmp4_;
-			GError* _tmp5_;
-			_error_ = _inner_error_;
-			_inner_error_ = NULL;
-			_tmp3_ = rygel_media_export_null_container_new ();
-			rygel_media_export_root_container_instance = (RygelMediaContainer*) _tmp3_;
-			_tmp4_ = _error_;
-			_tmp5_ = g_error_copy (_tmp4_);
-			rygel_media_export_root_container_creation_error = _tmp5_;
-			g_error_free (_error_);
-		}
-		__finally26:
-		if (_inner_error_ != NULL) {
-			g_propagate_error (error, _inner_error_);
-			return NULL;
-		}
-	} else {
-		GError* _tmp6_;
-		_tmp6_ = rygel_media_export_root_container_creation_error;
-		if (_tmp6_ != NULL) {
-			GError* _tmp7_;
-			GError* _tmp8_;
-			_tmp7_ = rygel_media_export_root_container_creation_error;
-			_tmp8_ = g_error_copy (_tmp7_);
-			_inner_error_ = _tmp8_;
-			g_propagate_error (error, _inner_error_);
-			return NULL;
-		}
-	}
-	_tmp9_ = rygel_media_export_root_container_instance;
-	_tmp10_ = g_object_ref (_tmp9_);
-	result = _tmp10_;
-	return result;
+static RygelMediaExportRootContainer *
+rygel_media_export_root_container_new (void) {
+  return RYGEL_MEDIA_EXPORT_ROOT_CONTAINER (g_object_new (RYGEL_MEDIA_EXPORT_TYPE_ROOT_CONTAINER,
+							  "id", "0",
+							  "parent", NULL,
+							  "title", _("@REALNAME@'s media"),
+							  "child-count", 0,
+							  NULL));
 }
 
+RygelMediaContainer *
+rygel_media_export_root_container_get_instance (GError **error) {
+  GError *inner_error = NULL;
 
-RygelMediaContainer* rygel_media_export_root_container_get_filesystem_container (RygelMediaExportRootContainer* self) {
-	RygelMediaContainer* result = NULL;
-	RygelMediaContainer* _tmp0_;
-	RygelMediaContainer* _tmp1_;
-	g_return_val_if_fail (self != NULL, NULL);
-	_tmp0_ = self->priv->filesystem_container;
-	_tmp1_ = g_object_ref (_tmp0_);
-	result = _tmp1_;
-	return result;
-}
+  if (!rygel_media_export_root_container_instance) {
+    RygelMediaExportRootContainer* root = rygel_media_export_root_container_new ();
+    if (inner_error) {
+      RygelMediaExportNullContainer *null_container = rygel_media_export_null_container_new ();
 
+      rygel_media_export_root_container_instance = RYGEL_MEDIA_CONTAINER (null_container);
+      rygel_media_export_root_container_creation_error = inner_error;
+      inner_error = NULL;
+    } else {
+      rygel_media_export_root_container_instance = RYGEL_MEDIA_CONTAINER (root);
+    }
+  } else if (rygel_media_export_root_container_creation_error) {
+    g_propagate_error (error, g_error_copy (rygel_media_export_root_container_creation_error));
+    return NULL;
+  }
 
-void rygel_media_export_root_container_shutdown (RygelMediaExportRootContainer* self) {
-	GCancellable* _tmp0_;
-	g_return_if_fail (self != NULL);
-	_tmp0_ = self->priv->cancellable;
-	g_cancellable_cancel (_tmp0_);
-}
-
-static void rygel_media_export_root_container_real_find_object_data_free (gpointer _data) {
-	RygelMediaExportRootContainerFindObjectData* _data_;
-	_data_ = _data;
-	g_free (_data_->id);
-	g_object_unref (_data_->cancellable);
-	g_object_unref (_data_->result);
-	g_object_unref (_data_->self);
-	g_slice_free (RygelMediaExportRootContainerFindObjectData, _data_);
+  return rygel_media_export_root_container_instance;
 }
 
+RygelMediaContainer *
+rygel_media_export_root_container_get_filesystem_container (RygelMediaExportRootContainer *self) {
+  RygelMediaContainer *container;
 
-static void rygel_media_export_root_container_real_find_object (RygelMediaContainer* base, const gchar* id, GCancellable* cancellable, GAsyncReadyCallback _callback_, gpointer _user_data_) {
-	RygelMediaExportRootContainer * self;
-	RygelMediaExportRootContainerFindObjectData* _data_;
-	RygelMediaExportRootContainer* _tmp0_;
-	const gchar* _tmp1_;
-	gchar* _tmp2_;
-	GCancellable* _tmp3_;
-	GCancellable* _tmp4_;
-	self = (RygelMediaExportRootContainer*) base;
-	_data_ = g_slice_new0 (RygelMediaExportRootContainerFindObjectData);
-	_data_->_async_result = g_simple_async_result_new (G_OBJECT (self), _callback_, _user_data_, rygel_media_export_root_container_real_find_object);
-	g_simple_async_result_set_op_res_gpointer (_data_->_async_result, _data_, rygel_media_export_root_container_real_find_object_data_free);
-	_tmp0_ = g_object_ref (self);
-	_data_->self = _tmp0_;
-	_tmp1_ = id;
-	_tmp2_ = g_strdup (_tmp1_);
-	g_free (_data_->id);
-	_data_->id = _tmp2_;
-	_tmp3_ = cancellable;
-	_tmp4_ = g_object_ref (_tmp3_);
-	g_object_unref (_data_->cancellable);
-	_data_->cancellable = _tmp4_;
-	rygel_media_export_root_container_real_find_object_co (_data_);
-}
+  g_return_val_if_fail (RYGEL_MEDIA_EXPORT_IS_ROOT_CONTAINER (self), NULL);
 
+  container = self->priv->filesystem_container;
+  if (container) {
+    g_object_ref (container);
+  }
 
-static RygelMediaObject* rygel_media_export_root_container_real_find_object_finish (RygelMediaContainer* base G_GNUC_UNUSED, GAsyncResult* _res_, GError** error) {
-	RygelMediaObject* result;
-	RygelMediaExportRootContainerFindObjectData* _data_;
-	if (g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (_res_), error)) {
-		return NULL;
-	}
-	_data_ = g_simple_async_result_get_op_res_gpointer (G_SIMPLE_ASYNC_RESULT (_res_));
-	result = _data_->result;
-	_data_->result = NULL;
-	return result;
+  return container;
 }
 
+void
+rygel_media_export_root_container_shutdown (RygelMediaExportRootContainer* self) {
+  g_return_if_fail (RYGEL_MEDIA_EXPORT_IS_ROOT_CONTAINER (self));
 
-static void rygel_media_export_root_container_find_object_ready (GObject* source_object, GAsyncResult* _res_, gpointer _user_data_) {
-	RygelMediaExportRootContainerFindObjectData* _data_;
-	_data_ = _user_data_;
-	_data_->_source_object_ = source_object;
-	_data_->_res_ = _res_;
-	rygel_media_export_root_container_real_find_object_co (_data_);
+  g_cancellable_cancel (self->priv->cancellable);
 }
 
-
-static gboolean rygel_media_export_root_container_real_find_object_co (RygelMediaExportRootContainerFindObjectData* _data_) {
-	switch (_data_->_state_) {
-		case 0:
-		goto _state_0;
-		case 1:
-		goto _state_1;
-		default:
-		g_assert_not_reached ();
-	}
-	_state_0:
-	_data_->_tmp0_ = _data_->id;
-	_data_->_tmp1_ = _data_->cancellable;
-	_data_->_state_ = 1;
-	RYGEL_MEDIA_CONTAINER_CLASS (rygel_media_export_root_container_parent_class)->find_object ((RygelMediaContainer*) G_TYPE_CHECK_INSTANCE_CAST (_data_->self, RYGEL_MEDIA_EXPORT_TYPE_DB_CONTAINER, RygelMediaExportDBContainer), _data_->_tmp0_, _data_->_tmp1_, rygel_media_export_root_container_find_object_ready, _data_);
-	return FALSE;
-	_state_1:
-	_data_->_tmp2_ = NULL;
-	_data_->_tmp2_ = RYGEL_MEDIA_CONTAINER_CLASS (rygel_media_export_root_container_parent_class)->find_object_finish ((RygelMediaContainer*) G_TYPE_CHECK_INSTANCE_CAST (_data_->self, RYGEL_MEDIA_EXPORT_TYPE_DB_CONTAINER, RygelMediaExportDBContainer), _data_->_res_, &_data_->_inner_error_);
-	_data_->object = _data_->_tmp2_;
-	if (_data_->_inner_error_ != NULL) {
-		g_simple_async_result_set_from_error (_data_->_async_result, _data_->_inner_error_);
-		g_error_free (_data_->_inner_error_);
-		if (_data_->_state_ == 0) {
-			g_simple_async_result_complete_in_idle (_data_->_async_result);
-		} else {
-			g_simple_async_result_complete (_data_->_async_result);
-		}
-		g_object_unref (_data_->_async_result);
-		return FALSE;
-	}
-	if (_data_->object == NULL) {
-		_data_->_tmp4_ = _data_->id;
-		_data_->_tmp5_ = FALSE;
-		_data_->_tmp5_ = g_str_has_prefix (_data_->_tmp4_, RYGEL_MEDIA_EXPORT_QUERY_CONTAINER_PREFIX);
-		_data_->_tmp3_ = _data_->_tmp5_;
-	} else {
-		_data_->_tmp3_ = FALSE;
-	}
-	_data_->_tmp6_ = _data_->_tmp3_;
-	if (_data_->_tmp6_) {
-		_data_->_tmp7_ = NULL;
-		_data_->_tmp7_ = rygel_media_export_query_container_factory_get_default ();
-		_data_->factory = _data_->_tmp7_;
-		_data_->_tmp8_ = _data_->factory;
-		_data_->_tmp9_ = rygel_media_export_db_container_get_media_db (RYGEL_MEDIA_EXPORT_DB_CONTAINER (_data_->self));
-		_data_->_tmp10_ = _data_->id;
-		_data_->_tmp11_ = NULL;
-		_data_->_tmp11_ = rygel_media_export_query_container_factory_create_from_id (_data_->_tmp8_, _data_->_tmp9_, _data_->_tmp10_, "");
-		_data_->container = _data_->_tmp11_;
-		_data_->_tmp12_ = _data_->container;
-		if (_data_->_tmp12_ != NULL) {
-			_data_->_tmp13_ = _data_->container;
-			rygel_media_object_set_parent ((RygelMediaObject*) _data_->_tmp13_, (RygelMediaContainer*) _data_->self);
-		}
-		_data_->result = (RygelMediaObject*) _data_->container;
-		g_object_unref (_data_->factory);
-		g_object_unref (_data_->object);
-		if (_data_->_state_ == 0) {
-			g_simple_async_result_complete_in_idle (_data_->_async_result);
-		} else {
-			g_simple_async_result_complete (_data_->_async_result);
-		}
-		g_object_unref (_data_->_async_result);
-		return FALSE;
-	}
-	_data_->result = _data_->object;
-	if (_data_->_state_ == 0) {
-		g_simple_async_result_complete_in_idle (_data_->_async_result);
-	} else {
-		g_simple_async_result_complete (_data_->_async_result);
-	}
-	g_object_unref (_data_->_async_result);
-	return FALSE;
-	g_object_unref (_data_->object);
-	if (_data_->_state_ == 0) {
-		g_simple_async_result_complete_in_idle (_data_->_async_result);
-	} else {
-		g_simple_async_result_complete (_data_->_async_result);
-	}
-	g_object_unref (_data_->_async_result);
-	return FALSE;
-}
-
-
-static void rygel_media_export_root_container_real_search_data_free (gpointer _data) {
-	RygelMediaExportRootContainerSearchData* _data_;
-	_data_ = _data;
-	rygel_search_expression_unref (_data_->expression);
-	g_free (_data_->sort_criteria);
-	g_object_unref (_data_->cancellable);
-	g_object_unref (_data_->result);
-	g_object_unref (_data_->self);
-	g_slice_free (RygelMediaExportRootContainerSearchData, _data_);
-}
-
-
-static gpointer _rygel_search_expression_ref0 (gpointer self) {
-	return self ? rygel_search_expression_ref (self) : NULL;
+static void
+rygel_media_export_root_container_real_find_object_data_free (RygelMediaExportRootContainerFindObjectData *data) {
+  g_free (data->id);
+  g_slice_free (RygelMediaExportRootContainerFindObjectData, data);
 }
 
-
-static void rygel_media_export_root_container_real_search (RygelSearchableContainer* base, RygelSearchExpression* expression, guint offset, guint max_count, const gchar* sort_criteria, GCancellable* cancellable, GAsyncReadyCallback _callback_, gpointer _user_data_) {
-	RygelMediaExportRootContainer * self;
-	RygelMediaExportRootContainerSearchData* _data_;
-	RygelMediaExportRootContainer* _tmp0_;
-	RygelSearchExpression* _tmp1_;
-	RygelSearchExpression* _tmp2_;
-	guint _tmp3_;
-	guint _tmp4_;
-	const gchar* _tmp5_;
-	gchar* _tmp6_;
-	GCancellable* _tmp7_;
-	GCancellable* _tmp8_;
-	self = (RygelMediaExportRootContainer*) base;
-	_data_ = g_slice_new0 (RygelMediaExportRootContainerSearchData);
-	_data_->_async_result = g_simple_async_result_new (G_OBJECT (self), _callback_, _user_data_, rygel_media_export_root_container_real_search);
-	g_simple_async_result_set_op_res_gpointer (_data_->_async_result, _data_, rygel_media_export_root_container_real_search_data_free);
-	_tmp0_ = g_object_ref (self);
-	_data_->self = _tmp0_;
-	_tmp1_ = expression;
-	_tmp2_ = _rygel_search_expression_ref0 (_tmp1_);
-	rygel_search_expression_unref (_data_->expression);
-	_data_->expression = _tmp2_;
-	_tmp3_ = offset;
-	_data_->offset = _tmp3_;
-	_tmp4_ = max_count;
-	_data_->max_count = _tmp4_;
-	_tmp5_ = sort_criteria;
-	_tmp6_ = g_strdup (_tmp5_);
-	g_free (_data_->sort_criteria);
-	_data_->sort_criteria = _tmp6_;
-	_tmp7_ = cancellable;
-	_tmp8_ = g_object_ref (_tmp7_);
-	g_object_unref (_data_->cancellable);
-	_data_->cancellable = _tmp8_;
-	rygel_media_export_root_container_real_search_co (_data_);
+static void
+rygel_media_export_root_container_find_object_ready (GObject      *source_object,
+						     GAsyncResult *res,
+						     gpointer      user_data) {
+  GError *error = NULL;
+  RygelMediaExportRootContainerFindObjectData *data = (RygelMediaExportRootContainerFindObjectData *) user_data;
+  RygelMediaObject *object = RYGEL_MEDIA_CONTAINER_CLASS (rygel_media_export_root_container_parent_class)->find_object_finish (RYGEL_MEDIA_CONTAINER (source_object),
+															       res,
+															       &error);
+
+  if (error) {
+    g_simple_async_result_take_error (data->simple, error);
+  } else {
+    if (!object &&
+	g_str_has_prefix (data->id, RYGEL_MEDIA_EXPORT_QUERY_CONTAINER_PREFIX)) {
+      RygelMediaExportQueryContainerFactory *factory = rygel_media_export_query_container_factory_get_default ();
+      RygelMediaExportQueryContainer *container = rygel_media_export_query_container_factory_create_from_id (factory,
+													     data->id,
+													     "");
+
+      if (container) {
+	object = RYGEL_MEDIA_OBJECT (container);
+	rygel_media_object_set_parent (object, RYGEL_MEDIA_CONTAINER (source_object));
+      }
+      g_object_unref (factory);
+    }
+    if (object) {
+      g_simple_async_result_set_op_res_gpointer (data->simple,
+						 object,
+						 g_object_unref);
+    }
+  }
+  g_simple_async_result_complete (data->simple);
+  g_object_unref (data->simple);
+  rygel_media_export_root_container_real_find_object_data_free (data);
 }
 
-
-static RygelMediaObjects* rygel_media_export_root_container_real_search_finish (RygelSearchableContainer* base G_GNUC_UNUSED, GAsyncResult* _res_, guint* total_matches, GError** error) {
-	RygelMediaObjects* result;
-	RygelMediaExportRootContainerSearchData* _data_;
-	if (g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (_res_), error)) {
-		return NULL;
-	}
-	_data_ = g_simple_async_result_get_op_res_gpointer (G_SIMPLE_ASYNC_RESULT (_res_));
-	if (total_matches) {
-		*total_matches = _data_->total_matches;
-	}
-	result = _data_->result;
-	_data_->result = NULL;
-	return result;
+static void
+rygel_media_export_root_container_real_find_object (RygelMediaContainer *base,
+						    const gchar         *id,
+						    GCancellable        *cancellable,
+						    GAsyncReadyCallback  callback,
+						    gpointer             user_data) {
+  RygelMediaExportRootContainerFindObjectData *data = g_slice_new0 (RygelMediaExportRootContainerFindObjectData);
+
+  data->simple = g_simple_async_result_new (G_OBJECT (base),
+					    callback,
+					    user_data,
+					    rygel_media_export_root_container_real_find_object);
+  data->id = g_strdup (id);
+  RYGEL_MEDIA_CONTAINER_CLASS (rygel_media_export_root_container_parent_class)->find_object (base,
+											     id,
+											     cancellable,
+											     rygel_media_export_root_container_find_object_ready,
+											     data);
+}
+
+static RygelMediaObject *
+rygel_media_export_root_container_real_find_object_finish (RygelMediaContainer  *base G_GNUC_UNUSED,
+							   GAsyncResult         *res,
+							   GError              **error) {
+  RygelMediaObject* result;
+  GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (res);
+
+  if (g_simple_async_result_propagate_error (simple, error)) {
+    return NULL;
+  }
+
+  result = RYGEL_MEDIA_OBJECT (g_simple_async_result_get_op_res_gpointer (simple));
+  if (result) {
+    g_object_ref (result);
+  }
+
+  return result;
 }
 
-
-static void rygel_media_export_root_container_search_ready (GObject* source_object, GAsyncResult* _res_, gpointer _user_data_) {
-	RygelMediaExportRootContainerSearchData* _data_;
-	_data_ = _user_data_;
-	_data_->_source_object_ = source_object;
-	_data_->_res_ = _res_;
-	rygel_media_export_root_container_real_search_co (_data_);
+static void
+rygel_media_export_root_container_real_search_data_free (gpointer user_data) {
+  RygelMediaExportRootContainerSearchData *data = (RygelMediaExportRootContainerSearchData *) user_data;
+  if (data->result) {
+    g_object_unref (data->result);
+  }
+  if (data->query_container) {
+    g_object_unref (data->query_container);
+  }
+  g_free (data->upnp_class);
+  g_slice_free (RygelMediaExportRootContainerSearchData, data);
 }
 
-
-static gboolean rygel_media_export_root_container_real_search_co (RygelMediaExportRootContainerSearchData* _data_) {
-	switch (_data_->_state_) {
-		case 0:
-		goto _state_0;
-		case 1:
-		goto _state_1;
-		case 2:
-		goto _state_2;
-		case 3:
-		goto _state_3;
-		default:
-		g_assert_not_reached ();
-	}
-	_state_0:
-	_data_->_tmp0_ = _data_->expression;
-	if (_data_->_tmp0_ == NULL) {
-		_data_->_tmp1_ = _data_->expression;
-		_data_->_tmp2_ = _data_->offset;
-		_data_->_tmp3_ = _data_->max_count;
-		_data_->_tmp4_ = _data_->sort_criteria;
-		_data_->_tmp5_ = _data_->cancellable;
-		_data_->_tmp6_ = 0U;
-		_data_->_state_ = 1;
-		parent_searchable_container_iface->search (RYGEL_SEARCHABLE_CONTAINER (_data_->self), _data_->_tmp1_, _data_->_tmp2_, _data_->_tmp3_, _data_->_tmp4_, _data_->_tmp5_, rygel_media_export_root_container_search_ready, _data_);
-		return FALSE;
-		_state_1:
-		_data_->_tmp7_ = NULL;
-		_data_->_tmp7_ = parent_searchable_container_iface->search_finish (RYGEL_SEARCHABLE_CONTAINER (_data_->self), _data_->_res_, &_data_->_tmp6_, &_data_->_inner_error_);
-		_data_->total_matches = _data_->_tmp6_;
-		_data_->_tmp8_ = _data_->_tmp7_;
-		if (_data_->_inner_error_ != NULL) {
-			g_simple_async_result_set_from_error (_data_->_async_result, _data_->_inner_error_);
-			g_error_free (_data_->_inner_error_);
-			if (_data_->_state_ == 0) {
-				g_simple_async_result_complete_in_idle (_data_->_async_result);
-			} else {
-				g_simple_async_result_complete (_data_->_async_result);
-			}
-			g_object_unref (_data_->_async_result);
-			return FALSE;
-		}
-		_data_->result = _data_->_tmp8_;
-		if (_data_->_state_ == 0) {
-			g_simple_async_result_complete_in_idle (_data_->_async_result);
-		} else {
-			g_simple_async_result_complete (_data_->_async_result);
-		}
-		g_object_unref (_data_->_async_result);
-		return FALSE;
-	}
-	_data_->query_container = NULL;
-	_data_->upnp_class = NULL;
-	_data_->_tmp9_ = _data_->expression;
-	if (G_TYPE_CHECK_INSTANCE_TYPE (_data_->_tmp9_, RYGEL_TYPE_RELATIONAL_EXPRESSION)) {
-		_data_->_tmp10_ = _data_->expression;
-		_data_->_tmp11_ = _rygel_search_expression_ref0 (G_TYPE_CHECK_INSTANCE_TYPE (_data_->_tmp10_, RYGEL_TYPE_RELATIONAL_EXPRESSION) ? ((RygelRelationalExpression*) _data_->_tmp10_) : NULL);
-		_data_->relational_expression = _data_->_tmp11_;
-		_data_->_tmp12_ = _data_->relational_expression;
-		_data_->_tmp13_ = NULL;
-		_data_->_tmp13_ = rygel_media_export_root_container_search_to_virtual_container (_data_->self, _data_->_tmp12_);
-		g_object_unref (_data_->query_container);
-		_data_->query_container = (RygelMediaContainer*) _data_->_tmp13_;
-		_data_->_tmp14_ = _data_->relational_expression;
-		_data_->_tmp15_ = ((RygelSearchExpression*) _data_->_tmp14_)->operand2;
-		_data_->_tmp16_ = g_strdup ((const gchar*) _data_->_tmp15_);
-		g_free (_data_->upnp_class);
-		_data_->upnp_class = _data_->_tmp16_;
-		rygel_search_expression_unref (_data_->relational_expression);
-	} else {
-		_data_->_tmp17_ = _data_->expression;
-		_data_->_tmp18_ = NULL;
-		_data_->_tmp19_ = FALSE;
-		_data_->_tmp19_ = rygel_media_export_root_container_is_search_in_virtual_container (_data_->self, _data_->_tmp17_, &_data_->_tmp18_);
-		g_object_unref (_data_->query_container);
-		_data_->query_container = _data_->_tmp18_;
-		if (_data_->_tmp19_) {
-		}
-	}
-	_data_->_tmp20_ = _data_->query_container;
-	if (_data_->_tmp20_ != NULL) {
-		_data_->_tmp21_ = _data_->query_container;
-		_data_->_tmp22_ = _data_->offset;
-		_data_->_tmp23_ = _data_->max_count;
-		_data_->_tmp24_ = _data_->sort_criteria;
-		_data_->_tmp25_ = _data_->cancellable;
-		_data_->_state_ = 2;
-		rygel_media_container_get_children (_data_->_tmp21_, _data_->_tmp22_, _data_->_tmp23_, _data_->_tmp24_, _data_->_tmp25_, rygel_media_export_root_container_search_ready, _data_);
-		return FALSE;
-		_state_2:
-		_data_->_tmp26_ = NULL;
-		_data_->_tmp26_ = rygel_media_container_get_children_finish (_data_->_tmp21_, _data_->_res_, &_data_->_inner_error_);
-		_data_->_tmp27_ = _data_->_tmp26_;
-		if (_data_->_inner_error_ != NULL) {
-			g_simple_async_result_set_from_error (_data_->_async_result, _data_->_inner_error_);
-			g_error_free (_data_->_inner_error_);
-			g_free (_data_->upnp_class);
-			g_object_unref (_data_->query_container);
-			g_object_unref (_data_->list);
-			if (_data_->_state_ == 0) {
-				g_simple_async_result_complete_in_idle (_data_->_async_result);
-			} else {
-				g_simple_async_result_complete (_data_->_async_result);
-			}
-			g_object_unref (_data_->_async_result);
-			return FALSE;
-		}
-		g_object_unref (_data_->list);
-		_data_->list = _data_->_tmp27_;
-		_data_->_tmp28_ = _data_->query_container;
-		_data_->_tmp29_ = rygel_media_container_get_child_count (_data_->_tmp28_);
-		_data_->total_matches = (guint) _data_->_tmp29_;
-		_data_->_tmp30_ = _data_->upnp_class;
-		if (_data_->_tmp30_ != NULL) {
-			{
-				_data_->_tmp31_ = _data_->list;
-				_data_->_tmp32_ = g_object_ref (_data_->_tmp31_);
-				_data_->_object_list = _data_->_tmp32_;
-				_data_->_tmp33_ = _data_->_object_list;
-				_data_->_tmp34_ = gee_abstract_collection_get_size ((GeeAbstractCollection*) _data_->_tmp33_);
-				_data_->_tmp35_ = _data_->_tmp34_;
-				_data_->_object_size = _data_->_tmp35_;
-				_data_->_object_index = -1;
-				while (TRUE) {
-					_data_->_tmp36_ = _data_->_object_index;
-					_data_->_object_index = _data_->_tmp36_ + 1;
-					_data_->_tmp37_ = _data_->_object_index;
-					_data_->_tmp38_ = _data_->_object_size;
-					if (!(_data_->_tmp37_ < _data_->_tmp38_)) {
-						break;
-					}
-					_data_->_tmp39_ = _data_->_object_list;
-					_data_->_tmp40_ = _data_->_object_index;
-					_data_->_tmp41_ = NULL;
-					_data_->_tmp41_ = gee_abstract_list_get ((GeeAbstractList*) _data_->_tmp39_, _data_->_tmp40_);
-					_data_->object = (RygelMediaObject*) _data_->_tmp41_;
-					_data_->_tmp42_ = _data_->object;
-					_data_->_tmp43_ = _data_->upnp_class;
-					rygel_media_object_set_upnp_class (_data_->_tmp42_, _data_->_tmp43_);
-					g_object_unref (_data_->object);
-				}
-				g_object_unref (_data_->_object_list);
-			}
-		}
-		_data_->result = _data_->list;
-		g_free (_data_->upnp_class);
-		g_object_unref (_data_->query_container);
-		if (_data_->_state_ == 0) {
-			g_simple_async_result_complete_in_idle (_data_->_async_result);
-		} else {
-			g_simple_async_result_complete (_data_->_async_result);
-		}
-		g_object_unref (_data_->_async_result);
-		return FALSE;
-	} else {
-		_data_->_tmp44_ = _data_->expression;
-		_data_->_tmp45_ = _data_->offset;
-		_data_->_tmp46_ = _data_->max_count;
-		_data_->_tmp47_ = _data_->sort_criteria;
-		_data_->_tmp48_ = _data_->cancellable;
-		_data_->_tmp49_ = 0U;
-		_data_->_state_ = 3;
-		parent_searchable_container_iface->search (RYGEL_SEARCHABLE_CONTAINER (_data_->self), _data_->_tmp44_, _data_->_tmp45_, _data_->_tmp46_, _data_->_tmp47_, _data_->_tmp48_, rygel_media_export_root_container_search_ready, _data_);
-		return FALSE;
-		_state_3:
-		_data_->_tmp50_ = NULL;
-		_data_->_tmp50_ = parent_searchable_container_iface->search_finish (RYGEL_SEARCHABLE_CONTAINER (_data_->self), _data_->_res_, &_data_->_tmp49_, &_data_->_inner_error_);
-		_data_->total_matches = _data_->_tmp49_;
-		_data_->_tmp51_ = _data_->_tmp50_;
-		if (_data_->_inner_error_ != NULL) {
-			g_simple_async_result_set_from_error (_data_->_async_result, _data_->_inner_error_);
-			g_error_free (_data_->_inner_error_);
-			g_free (_data_->upnp_class);
-			g_object_unref (_data_->query_container);
-			g_object_unref (_data_->list);
-			if (_data_->_state_ == 0) {
-				g_simple_async_result_complete_in_idle (_data_->_async_result);
-			} else {
-				g_simple_async_result_complete (_data_->_async_result);
-			}
-			g_object_unref (_data_->_async_result);
-			return FALSE;
-		}
-		_data_->result = _data_->_tmp51_;
-		g_free (_data_->upnp_class);
-		g_object_unref (_data_->query_container);
-		g_object_unref (_data_->list);
-		if (_data_->_state_ == 0) {
-			g_simple_async_result_complete_in_idle (_data_->_async_result);
-		} else {
-			g_simple_async_result_complete (_data_->_async_result);
-		}
-		g_object_unref (_data_->_async_result);
-		return FALSE;
-	}
-	g_free (_data_->upnp_class);
-	g_object_unref (_data_->query_container);
-	g_object_unref (_data_->list);
-	if (_data_->_state_ == 0) {
-		g_simple_async_result_complete_in_idle (_data_->_async_result);
-	} else {
-		g_simple_async_result_complete (_data_->_async_result);
-	}
-	g_object_unref (_data_->_async_result);
-	return FALSE;
+static void
+rygel_media_export_root_container_base_class_search_ready  (GObject      *source_object,
+							    GAsyncResult *res,
+							    gpointer      user_data) {
+  GError *error = NULL;
+  RygelMediaExportRootContainerSearchData *data = (RygelMediaExportRootContainerSearchData *) user_data;
+  guint total_matches = 0;
+  RygelMediaObjects *objects = parent_searchable_container_iface->search_finish (RYGEL_SEARCHABLE_CONTAINER (source_object),
+										 res,
+										 &total_matches,
+										 &error);
+
+  if (error) {
+    g_simple_async_result_take_error (data->simple, error);
+  } else {
+    data->result = objects;
+    data->total_matches = total_matches;
+  }
+  g_simple_async_result_complete (data->simple);
+  g_object_unref (data->simple);
 }
 
-
-static gchar* string_replace (const gchar* self, const gchar* old, const gchar* replacement) {
-	gchar* result = NULL;
-	GError * _inner_error_ = NULL;
-	g_return_val_if_fail (self != NULL, NULL);
-	g_return_val_if_fail (old != NULL, NULL);
-	g_return_val_if_fail (replacement != NULL, NULL);
-	{
-		const gchar* _tmp0_;
-		gchar* _tmp1_ = NULL;
-		gchar* _tmp2_;
-		GRegex* _tmp3_;
-		GRegex* _tmp4_;
-		GRegex* regex;
-		GRegex* _tmp5_;
-		const gchar* _tmp6_;
-		gchar* _tmp7_ = NULL;
-		gchar* _tmp8_;
-		_tmp0_ = old;
-		_tmp1_ = g_regex_escape_string (_tmp0_, -1);
-		_tmp2_ = _tmp1_;
-		_tmp3_ = g_regex_new (_tmp2_, 0, 0, &_inner_error_);
-		_tmp4_ = _tmp3_;
-		g_free (_tmp2_);
-		regex = _tmp4_;
-		if (_inner_error_ != NULL) {
-			if (_inner_error_->domain == G_REGEX_ERROR) {
-				goto __catch31_g_regex_error;
-			}
-			g_critical ("file %s: line %d: unexpected error: %s (%s, %d)", __FILE__, __LINE__, _inner_error_->message, g_quark_to_string (_inner_error_->domain), _inner_error_->code);
-			g_clear_error (&_inner_error_);
-			return NULL;
-		}
-		_tmp5_ = regex;
-		_tmp6_ = replacement;
-		_tmp7_ = g_regex_replace_literal (_tmp5_, self, (gssize) (-1), 0, _tmp6_, 0, &_inner_error_);
-		_tmp8_ = _tmp7_;
-		if (_inner_error_ != NULL) {
-			g_regex_unref (regex);
-			if (_inner_error_->domain == G_REGEX_ERROR) {
-				goto __catch31_g_regex_error;
-			}
-			g_regex_unref (regex);
-			g_critical ("file %s: line %d: unexpected error: %s (%s, %d)", __FILE__, __LINE__, _inner_error_->message, g_quark_to_string (_inner_error_->domain), _inner_error_->code);
-			g_clear_error (&_inner_error_);
-			return NULL;
-		}
-		result = _tmp8_;
-		g_regex_unref (regex);
-		return result;
-	}
-	goto __finally31;
-	__catch31_g_regex_error:
-	{
-		GError* e = NULL;
-		e = _inner_error_;
-		_inner_error_ = NULL;
-		g_assert_not_reached ();
-		g_error_free (e);
-	}
-	__finally31:
-	if (_inner_error_ != NULL) {
-		g_critical ("file %s: line %d: uncaught error: %s (%s, %d)", __FILE__, __LINE__, _inner_error_->message, g_quark_to_string (_inner_error_->domain), _inner_error_->code);
-		g_clear_error (&_inner_error_);
-		return NULL;
-	}
+static void
+rygel_media_export_root_container_get_children_from_container_ready (GObject      *source_object G_GNUC_UNUSED,
+								     GAsyncResult *res,
+								     gpointer      user_data) {
+  GError *error = NULL;
+  RygelMediaExportRootContainerSearchData *data = (RygelMediaExportRootContainerSearchData *) user_data;
+  guint total_matches = 0;
+  RygelMediaObjects *objects = rygel_media_container_get_children_finish (data->query_container,
+									  res,
+									  &error);
+
+  if (error) {
+    g_simple_async_result_take_error (data->simple, error);
+  } else {
+    total_matches = rygel_media_container_get_child_count (data->query_container);
+    if (data->upnp_class) {
+      gint size = gee_abstract_collection_get_size (GEE_ABSTRACT_COLLECTION (objects));
+      GeeAbstractList *list = GEE_ABSTRACT_LIST (objects);
+      gint iter;
+
+      for (iter = 0; iter < size; ++iter) {
+	RygelMediaObject *object = RYGEL_MEDIA_OBJECT (gee_abstract_list_get (list, iter));
+
+	if (object) {
+	  rygel_media_object_set_upnp_class (object, data->upnp_class);
+	  g_object_unref (object);
+	}
+      }
+    }
+
+    data->result = objects;
+    data->total_matches = total_matches;
+  }
+  g_simple_async_result_complete (data->simple);
+  g_object_unref (data->simple);
+  g_free (data->upnp_class);
+  data->upnp_class = NULL;
+  g_object_unref (data->query_container);
+  data->query_container = NULL;
+}
+
+static RygelMediaExportQueryContainer *
+rygel_media_export_root_container_search_to_virtual_container (RygelMediaExportRootContainer *self,
+							       RygelRelationalExpression     *expression) {
+  RygelSearchExpression *search_expression;
+
+  g_return_val_if_fail (RYGEL_MEDIA_EXPORT_IS_ROOT_CONTAINER (self), NULL);
+  g_return_val_if_fail (RYGEL_IS_RELATIONAL_EXPRESSION (expression), NULL);
+
+  search_expression = RYGEL_SEARCH_EXPRESSION (expression);
+
+  if (!g_strcmp0 (search_expression->operand1, "upnp:class") &&
+      ((GUPnPSearchCriteriaOp) ((gintptr) search_expression->op)) == GUPNP_SEARCH_CRITERIA_OP_EQ) {
+    gchar *id;
+    RygelMediaExportQueryContainerFactory *factory;
+    RygelMediaExportQueryContainer *container;
+
+    if (!g_strcmp0 (search_expression->operand2, "object.container.album.musicAlbum")) {
+      id = g_strdup_printf ("%supnp:album,?", RYGEL_MEDIA_EXPORT_ROOT_CONTAINER_SEARCH_CONTAINER_PREFIX);
+    } else if (!g_strcmp0 (search_expression->operand2, "object.container.person.musicArtist")) {
+      id = g_strdup_printf ("%sdc:creator,?,upnp:album,?", RYGEL_MEDIA_EXPORT_ROOT_CONTAINER_SEARCH_CONTAINER_PREFIX);
+    } else if (!g_strcmp0 (search_expression->operand2, "object.container.genre.musicGenre")) {
+      id = g_strdup_printf ("%sdc:genre,?", RYGEL_MEDIA_EXPORT_ROOT_CONTAINER_SEARCH_CONTAINER_PREFIX);
+    } else {
+      return NULL;
+    }
+
+    factory = rygel_media_export_query_container_factory_get_default ();
+    container = rygel_media_export_query_container_factory_create_from_description (factory, id, "");
+    g_object_unref (factory);
+    g_free (id);
+
+    return container;
+  }
+
+  return NULL;
 }
 
-
-static GeeArrayList* rygel_media_export_root_container_get_shared_uris (RygelMediaExportRootContainer* self) {
-	GeeArrayList* result = NULL;
-	GeeArrayList* uris = NULL;
-	GeeArrayList* actual_uris = NULL;
-	RygelMetaConfig* _tmp0_ = NULL;
-	RygelMetaConfig* config;
-	GeeArrayList* _tmp9_;
-	const gchar* _tmp10_ = NULL;
-	GFile* _tmp11_ = NULL;
-	GFile* home_dir;
-	const gchar* _tmp12_ = NULL;
-	const gchar* pictures_dir;
-	const gchar* _tmp13_ = NULL;
-	const gchar* videos_dir;
-	const gchar* _tmp14_ = NULL;
-	const gchar* music_dir;
-	GError * _inner_error_ = NULL;
-	g_return_val_if_fail (self != NULL, NULL);
-	_tmp0_ = rygel_meta_config_get_default ();
-	config = _tmp0_;
-	{
-		GeeArrayList* _tmp1_ = NULL;
-		GeeArrayList* _tmp2_;
-		_tmp1_ = rygel_configuration_get_string_list ((RygelConfiguration*) config, "MediaExport", "uris", &_inner_error_);
-		_tmp2_ = _tmp1_;
-		if (_inner_error_ != NULL) {
-			goto __catch29_g_error;
-		}
-		g_object_unref (uris);
-		uris = _tmp2_;
-	}
-	goto __finally29;
-	__catch29_g_error:
-	{
-		GError* _error_ = NULL;
-		GeeArrayList* _tmp3_;
-		_error_ = _inner_error_;
-		_inner_error_ = NULL;
-		_tmp3_ = gee_array_list_new (G_TYPE_STRING, (GBoxedCopyFunc) g_strdup, g_free, NULL, NULL, NULL);
-		g_object_unref (uris);
-		uris = _tmp3_;
-		g_error_free (_error_);
-	}
-	__finally29:
-	if (_inner_error_ != NULL) {
-		g_object_unref (config);
-		g_object_unref (actual_uris);
-		g_object_unref (uris);
-		g_critical ("file %s: line %d: uncaught error: %s (%s, %d)", __FILE__, __LINE__, _inner_error_->message, g_quark_to_string (_inner_error_->domain), _inner_error_->code);
-		g_clear_error (&_inner_error_);
-		return NULL;
-	}
-
-	goto __finally30;
-	{
-		GError* _error_ = NULL;
-		_error_ = _inner_error_;
-		_inner_error_ = NULL;
-		g_error_free (_error_);
-	}
-	__finally30:
-	if (_inner_error_ != NULL) {
-		g_object_unref (config);
-		g_object_unref (actual_uris);
-		g_object_unref (uris);
-		g_critical ("file %s: line %d: uncaught error: %s (%s, %d)", __FILE__, __LINE__, _inner_error_->message, g_quark_to_string (_inner_error_->domain), _inner_error_->code);
-		g_clear_error (&_inner_error_);
-		return NULL;
-	}
-	_tmp9_ = gee_array_list_new (G_TYPE_FILE, (GBoxedCopyFunc) g_object_ref, g_object_unref, NULL, NULL, NULL);
-	g_object_unref (actual_uris);
-	actual_uris = _tmp9_;
-	_tmp10_ = g_get_home_dir ();
-	_tmp11_ = g_file_new_for_path (_tmp10_);
-	home_dir = _tmp11_;
-	_tmp12_ = g_get_user_special_dir (G_USER_DIRECTORY_PICTURES);
-	pictures_dir = _tmp12_;
-	_tmp13_ = g_get_user_special_dir (G_USER_DIRECTORY_VIDEOS);
-	videos_dir = _tmp13_;
-	_tmp14_ = g_get_user_special_dir (G_USER_DIRECTORY_MUSIC);
-	music_dir = _tmp14_;
-	{
-		GeeArrayList* _tmp15_;
-		GeeArrayList* _tmp16_;
-		GeeArrayList* _uri_list;
-		GeeArrayList* _tmp17_;
-		gint _tmp18_;
-		gint _tmp19_;
-		gint _uri_size;
-		gint _uri_index;
-		_tmp15_ = uris;
-		_tmp16_ = g_object_ref (_tmp15_);
-		_uri_list = _tmp16_;
-		_tmp17_ = _uri_list;
-		_tmp18_ = gee_abstract_collection_get_size ((GeeAbstractCollection*) _tmp17_);
-		_tmp19_ = _tmp18_;
-		_uri_size = _tmp19_;
-		_uri_index = -1;
-		while (TRUE) {
-			gint _tmp20_;
-			gint _tmp21_;
-			gint _tmp22_;
-			GeeArrayList* _tmp23_;
-			gint _tmp24_;
-			gpointer _tmp25_ = NULL;
-			gchar* uri;
-			const gchar* _tmp26_;
-			GFile* _tmp27_ = NULL;
-			GFile* file;
-			GFile* _tmp28_;
-			GFile* _tmp29_;
-			gboolean _tmp30_ = FALSE;
-			GeeArrayList* _tmp52_;
-			GFile* _tmp53_;
-			_tmp20_ = _uri_index;
-			_uri_index = _tmp20_ + 1;
-			_tmp21_ = _uri_index;
-			_tmp22_ = _uri_size;
-			if (!(_tmp21_ < _tmp22_)) {
-				break;
-			}
-			_tmp23_ = _uri_list;
-			_tmp24_ = _uri_index;
-			_tmp25_ = gee_abstract_list_get ((GeeAbstractList*) _tmp23_, _tmp24_);
-			uri = (gchar*) _tmp25_;
-			_tmp26_ = uri;
-			_tmp27_ = g_file_new_for_commandline_arg (_tmp26_);
-			file = _tmp27_;
-			_tmp28_ = file;
-			_tmp29_ = home_dir;
-			_tmp30_ = G_LIKELY (_tmp28_ != _tmp29_);
-			if (_tmp30_) {
-				const gchar* _tmp31_;
-				gchar* _tmp32_;
-				gchar* actual_uri;
-				const gchar* _tmp33_;
-				gboolean _tmp34_ = FALSE;
-				const gchar* _tmp38_;
-				gboolean _tmp39_ = FALSE;
-				const gchar* _tmp43_;
-				gboolean _tmp44_ = FALSE;
-				const gchar* _tmp48_;
-				GFile* _tmp49_ = NULL;
-				GFile* _tmp50_;
-				GFile* _tmp51_;
-				_tmp31_ = uri;
-				_tmp32_ = g_strdup (_tmp31_);
-				actual_uri = _tmp32_;
-				_tmp33_ = pictures_dir;
-				_tmp34_ = G_LIKELY (_tmp33_ != NULL);
-				if (_tmp34_) {
-					const gchar* _tmp35_;
-					const gchar* _tmp36_;
-					gchar* _tmp37_ = NULL;
-					_tmp35_ = actual_uri;
-					_tmp36_ = pictures_dir;
-					_tmp37_ = string_replace (_tmp35_, "@PICTURES@", _tmp36_);
-					g_free (actual_uri);
-					actual_uri = _tmp37_;
-				}
-				_tmp38_ = videos_dir;
-				_tmp39_ = G_LIKELY (_tmp38_ != NULL);
-				if (_tmp39_) {
-					const gchar* _tmp40_;
-					const gchar* _tmp41_;
-					gchar* _tmp42_ = NULL;
-					_tmp40_ = actual_uri;
-					_tmp41_ = videos_dir;
-					_tmp42_ = string_replace (_tmp40_, "@VIDEOS@", _tmp41_);
-					g_free (actual_uri);
-					actual_uri = _tmp42_;
-				}
-				_tmp43_ = music_dir;
-				_tmp44_ = G_LIKELY (_tmp43_ != NULL);
-				if (_tmp44_) {
-					const gchar* _tmp45_;
-					const gchar* _tmp46_;
-					gchar* _tmp47_ = NULL;
-					_tmp45_ = actual_uri;
-					_tmp46_ = music_dir;
-					_tmp47_ = string_replace (_tmp45_, "@MUSIC@", _tmp46_);
-					g_free (actual_uri);
-					actual_uri = _tmp47_;
-				}
-				_tmp48_ = actual_uri;
-				_tmp49_ = g_file_new_for_commandline_arg (_tmp48_);
-				g_object_unref (file);
-				file = _tmp49_;
-				_tmp50_ = file;
-				_tmp51_ = home_dir;
-				if (_tmp50_ == _tmp51_) {
-					g_free (actual_uri);
-					g_object_unref (file);
-					g_free (uri);
-					continue;
-				}
-				g_free (actual_uri);
-			}
-			_tmp52_ = actual_uris;
-			_tmp53_ = file;
-			gee_abstract_collection_add ((GeeAbstractCollection*) _tmp52_, _tmp53_);
-			g_object_unref (file);
-			g_free (uri);
-		}
-		g_object_unref (_uri_list);
-	}
-	result = actual_uris;
-	g_object_unref (home_dir);
-	g_object_unref (config);
-	g_object_unref (uris);
-	return result;
+/**
+ * Check if a passed search expression is a simple search in a virtual
+ * container.
+ *
+ * @param expression the expression to check
+ * @param new_id contains the id of the virtual container constructed from
+ *               the search
+ * @param upnp_class contains the class of the container the search was
+ *                   looking in
+ * @return true if it was a search in virtual container, false otherwise.
+ * @note This works single level only. Enough to satisfy Xbox music
+ *       browsing, but may need refinement
+ */
+static gboolean
+rygel_media_export_root_container_is_search_in_virtual_container (RygelMediaExportRootContainer  *self,
+								  RygelSearchExpression          *expression,
+								  RygelMediaContainer           **container) {
+  RygelMediaExportQueryContainer *query_container;
+  RygelSearchExpression *virtual_expression;
+  RygelMediaExportQueryContainerFactory *factory;
+  RygelMediaContainer *temp_container;
+  gchar *plaintext_id;
+  const gchar *id;
+  gchar *last_argument;
+  gchar *escaped_detail;
+  gchar *new_id;
+  GError *error;
+  gboolean result;
+
+  g_return_val_if_fail (RYGEL_MEDIA_EXPORT_IS_ROOT_CONTAINER (self), FALSE);
+  g_return_val_if_fail (RYGEL_IS_SEARCH_EXPRESSION (expression), FALSE);
+
+  if (!RYGEL_IS_LOGICAL_EXPRESSION (expression)) {
+    return FALSE;
+  }
+
+  if (!(RYGEL_IS_RELATIONAL_EXPRESSION (expression->operand1) &&
+	RYGEL_IS_RELATIONAL_EXPRESSION (expression->operand2) &&
+	(expression->op == RYGEL_LOGICAL_OPERATOR_AND))) {
+    return FALSE;
+  }
+
+  query_container = rygel_media_export_root_container_search_to_virtual_container (self,
+										   RYGEL_RELATIONAL_EXPRESSION (expression->operand1));
+  if (!query_container) {
+    query_container = rygel_media_export_root_container_search_to_virtual_container (self,
+										     RYGEL_RELATIONAL_EXPRESSION (expression->operand2));
+    if (query_container) {
+      virtual_expression = expression->operand1;
+    } else {
+      return FALSE;
+    }
+  } else {
+    virtual_expression = expression->operand2;
+  }
+
+  error = NULL;
+  factory = rygel_media_export_query_container_factory_get_default ();
+  id = rygel_media_object_get_id (RYGEL_MEDIA_OBJECT (query_container));
+  plaintext_id = rygel_media_export_query_container_factory_get_virtual_container_definition (factory, id);
+  g_object_unref (query_container);
+  last_argument = rygel_media_export_string_replace (plaintext_id,
+						     RYGEL_MEDIA_EXPORT_QUERY_CONTAINER_PREFIX,
+						     "",
+						     &error);
+  if (error) {
+    g_warning ("Could not remove %s from %s: %s",
+	       RYGEL_MEDIA_EXPORT_QUERY_CONTAINER_PREFIX,
+	       plaintext_id,
+	       error->message);
+    g_error_free (error);
+    result = FALSE;
+    goto error_out;
+  }
+  escaped_detail = g_uri_escape_string (virtual_expression->operand2, "", TRUE);
+  new_id = g_strdup_printf ("%s%s,%s,%s",
+			    RYGEL_MEDIA_EXPORT_QUERY_CONTAINER_PREFIX,
+			    (const gchar *) virtual_expression->operand1,
+			    escaped_detail,
+			    last_argument);
+  temp_container = RYGEL_MEDIA_CONTAINER (rygel_media_export_query_container_factory_create_from_description (factory,
+													      new_id,
+													      ""));
+  if (container) {
+    *container = temp_container;
+  } else if (temp_container) {
+    g_object_unref (temp_container);
+  }
+  g_free (new_id);
+  g_free (escaped_detail);
+  g_free (last_argument);
+
+  result = TRUE;
+ error_out:
+  g_free (plaintext_id);
+  g_object_unref (factory);
+
+  return result;
 }
 
-
-static RygelMediaExportQueryContainer* rygel_media_export_root_container_search_to_virtual_container (RygelMediaExportRootContainer* self, RygelRelationalExpression* expression) {
-	RygelMediaExportQueryContainer* result = NULL;
-	gboolean _tmp0_ = FALSE;
-	RygelRelationalExpression* _tmp1_;
-	gconstpointer _tmp2_;
-	gboolean _tmp5_;
-	g_return_val_if_fail (self != NULL, NULL);
-	g_return_val_if_fail (expression != NULL, NULL);
-	_tmp1_ = expression;
-	_tmp2_ = ((RygelSearchExpression*) _tmp1_)->operand1;
-	if (g_strcmp0 ((const gchar*) _tmp2_, "upnp:class") == 0) {
-		RygelRelationalExpression* _tmp3_;
-		gconstpointer _tmp4_;
-		_tmp3_ = expression;
-		_tmp4_ = ((RygelSearchExpression*) _tmp3_)->op;
-		_tmp0_ = ((GUPnPSearchCriteriaOp) ((gintptr) _tmp4_)) == GUPNP_SEARCH_CRITERIA_OP_EQ;
-	} else {
-		_tmp0_ = FALSE;
-	}
-	_tmp5_ = _tmp0_;
-	if (_tmp5_) {
-		gchar* _tmp6_;
-		gchar* id;
-		RygelRelationalExpression* _tmp7_;
-		gconstpointer _tmp8_;
-		const gchar* _tmp9_;
-		GQuark _tmp11_ = 0U;
-		static GQuark _tmp10_label0 = 0;
-		static GQuark _tmp10_label1 = 0;
-		static GQuark _tmp10_label2 = 0;
-		RygelMediaExportQueryContainerFactory* _tmp18_ = NULL;
-		RygelMediaExportQueryContainerFactory* factory;
-		RygelMediaExportQueryContainerFactory* _tmp19_;
-		RygelMediaExportMediaCache* _tmp20_;
-		const gchar* _tmp21_;
-		RygelMediaExportQueryContainer* _tmp22_ = NULL;
-		_tmp6_ = g_strdup (RYGEL_MEDIA_EXPORT_ROOT_CONTAINER_SEARCH_CONTAINER_PREFIX);
-		id = _tmp6_;
-		_tmp7_ = expression;
-		_tmp8_ = ((RygelSearchExpression*) _tmp7_)->operand2;
-		_tmp9_ = (const gchar*) _tmp8_;
-		_tmp11_ = (NULL == _tmp9_) ? 0 : g_quark_from_string (_tmp9_);
-		if (_tmp11_ == ((0 != _tmp10_label0) ? _tmp10_label0 : (_tmp10_label0 = g_quark_from_static_string ("object.container.album.musicAlbum")))) {
-			switch (0) {
-				default:
-				{
-					const gchar* _tmp12_;
-					gchar* _tmp13_;
-					_tmp12_ = id;
-					_tmp13_ = g_strconcat (_tmp12_, "upnp:album,?", NULL);
-					g_free (id);
-					id = _tmp13_;
-					break;
-				}
-			}
-		} else if (_tmp11_ == ((0 != _tmp10_label1) ? _tmp10_label1 : (_tmp10_label1 = g_quark_from_static_string ("object.container.person.musicArtist")))) {
-			switch (0) {
-				default:
-				{
-					const gchar* _tmp14_;
-					gchar* _tmp15_;
-					_tmp14_ = id;
-					_tmp15_ = g_strconcat (_tmp14_, "dc:creator,?,upnp:album,?", NULL);
-					g_free (id);
-					id = _tmp15_;
-					break;
-				}
-			}
-		} else if (_tmp11_ == ((0 != _tmp10_label2) ? _tmp10_label2 : (_tmp10_label2 = g_quark_from_static_string ("object.container.genre.musicGenre")))) {
-			switch (0) {
-				default:
-				{
-					const gchar* _tmp16_;
-					gchar* _tmp17_;
-					_tmp16_ = id;
-					_tmp17_ = g_strconcat (_tmp16_, "dc:genre,?", NULL);
-					g_free (id);
-					id = _tmp17_;
-					break;
-				}
-			}
-		} else {
-			switch (0) {
-				default:
-				{
-					result = NULL;
-					g_free (id);
-					return result;
-				}
-			}
-		}
-		_tmp18_ = rygel_media_export_query_container_factory_get_default ();
-		factory = _tmp18_;
-		_tmp19_ = factory;
-		_tmp20_ = rygel_media_export_db_container_get_media_db (RYGEL_MEDIA_EXPORT_DB_CONTAINER (self));
-		_tmp21_ = id;
-		_tmp22_ = rygel_media_export_query_container_factory_create_from_description (_tmp19_, _tmp20_, _tmp21_, "");
-		result = _tmp22_;
-		g_object_unref (factory);
-		g_free (id);
-		return result;
-	}
-	result = NULL;
-	return result;
+static void
+rygel_media_export_root_container_real_search (RygelSearchableContainer *base,
+					       RygelSearchExpression    *expression,
+					       guint                     offset,
+					       guint                     max_count,
+					       const gchar              *sort_criteria,
+					       GCancellable             *cancellable,
+					       GAsyncReadyCallback       callback,
+					       gpointer                  user_data) {
+  RygelMediaExportRootContainer *self = RYGEL_MEDIA_EXPORT_ROOT_CONTAINER (base);
+  RygelMediaExportRootContainerSearchData *data = g_slice_new0 (RygelMediaExportRootContainerSearchData);
+
+  data->simple = g_simple_async_result_new (G_OBJECT (self),
+					    callback,
+					    user_data,
+					    rygel_media_export_root_container_real_search);
+  g_simple_async_result_set_op_res_gpointer (data->simple,
+					     data,
+					     rygel_media_export_root_container_real_search_data_free);
+  if (!expression) {
+    parent_searchable_container_iface->search (base,
+					       expression,
+					       offset,
+					       max_count,
+					       sort_criteria,
+					       cancellable,
+					       rygel_media_export_root_container_base_class_search_ready,
+					       data);
+  } else {
+    data->query_container = NULL;
+    data->upnp_class = NULL;
+    if (RYGEL_IS_RELATIONAL_EXPRESSION (expression)) {
+      data->query_container = RYGEL_MEDIA_CONTAINER (rygel_media_export_root_container_search_to_virtual_container (self,
+														    RYGEL_RELATIONAL_EXPRESSION (expression)));
+      data->upnp_class = g_strdup (expression->operand2);
+    } else {
+      rygel_media_export_root_container_is_search_in_virtual_container (self,
+									expression,
+									&data->query_container);
+    }
+    if (data->query_container) {
+      rygel_media_container_get_children (data->query_container,
+					  offset,
+					  max_count,
+					  sort_criteria,
+					  cancellable,
+					  rygel_media_export_root_container_get_children_from_container_ready,
+					  data);
+    } else {
+      parent_searchable_container_iface->search (base,
+						 expression,
+						 offset,
+						 max_count,
+						 sort_criteria,
+						 cancellable,
+						 rygel_media_export_root_container_base_class_search_ready,
+						 data);
+    }
+  }
+}
+
+static RygelMediaObjects *
+rygel_media_export_root_container_real_search_finish (RygelSearchableContainer  *base G_GNUC_UNUSED,
+						      GAsyncResult              *res,
+						      guint                     *total_matches,
+						      GError                   **error) {
+  RygelMediaObjects *result;
+  RygelMediaExportRootContainerSearchData *data;
+  GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (res);
+
+  if (g_simple_async_result_propagate_error (simple, error)) {
+    return NULL;
+  }
+  data = g_simple_async_result_get_op_res_gpointer (simple);
+  if (total_matches) {
+    *total_matches = data->total_matches;
+  }
+  result = data->result;
+  data->result = NULL;
+  return result;
 }
 
-
-/**
-     * Check if a passed search expression is a simple search in a virtual
-     * container.
-     *
-     * @param expression the expression to check
-     * @param new_id contains the id of the virtual container constructed from
-     *               the search
-     * @param upnp_class contains the class of the container the search was
-     *                   looking in
-     * @return true if it was a search in virtual container, false otherwise.
-     * @note This works single level only. Enough to satisfy Xbox music
-     *       browsing, but may need refinement
-     */
-static gboolean rygel_media_export_root_container_is_search_in_virtual_container (RygelMediaExportRootContainer* self, RygelSearchExpression* expression, RygelMediaContainer** container) {
-	RygelMediaContainer* _vala_container = NULL;
-	gboolean result = FALSE;
-	RygelRelationalExpression* virtual_expression;
-	RygelMediaExportQueryContainer* query_container = NULL;
-	RygelSearchExpression* _tmp0_;
-	RygelSearchExpression* _tmp1_;
-	RygelLogicalExpression* _tmp2_;
-	RygelLogicalExpression* logical_expression;
-	gboolean _tmp3_ = FALSE;
-	gboolean _tmp4_ = FALSE;
-	RygelLogicalExpression* _tmp5_;
-	gconstpointer _tmp6_;
-	gboolean _tmp9_;
-	gboolean _tmp12_;
-	RygelLogicalExpression* _tmp13_;
-	gconstpointer _tmp14_;
-	RygelRelationalExpression* _tmp15_;
-	RygelRelationalExpression* left_expression;
-	RygelLogicalExpression* _tmp16_;
-	gconstpointer _tmp17_;
-	RygelRelationalExpression* _tmp18_;
-	RygelRelationalExpression* right_expression;
-	RygelRelationalExpression* _tmp19_;
-	RygelMediaExportQueryContainer* _tmp20_ = NULL;
-	RygelMediaExportQueryContainer* _tmp21_;
-	RygelMediaExportQueryContainerFactory* _tmp29_ = NULL;
-	RygelMediaExportQueryContainerFactory* factory;
-	RygelMediaExportQueryContainerFactory* _tmp30_;
-	RygelMediaExportQueryContainer* _tmp31_;
-	const gchar* _tmp32_;
-	const gchar* _tmp33_;
-	gchar* _tmp34_ = NULL;
-	gchar* plaintext_id;
-	const gchar* _tmp35_;
-	gchar* _tmp36_ = NULL;
-	gchar* last_argument;
-	RygelRelationalExpression* _tmp37_;
-	gconstpointer _tmp38_;
-	gchar* _tmp39_ = NULL;
-	gchar* escaped_detail;
-	RygelRelationalExpression* _tmp40_;
-	gconstpointer _tmp41_;
-	const gchar* _tmp42_;
-	const gchar* _tmp43_;
-	gchar* _tmp44_ = NULL;
-	gchar* new_id;
-	RygelMediaExportQueryContainerFactory* _tmp45_;
-	RygelMediaExportMediaCache* _tmp46_;
-	const gchar* _tmp47_;
-	RygelMediaExportQueryContainer* _tmp48_ = NULL;
-	g_return_val_if_fail (self != NULL, FALSE);
-	g_return_val_if_fail (expression != NULL, FALSE);
-	virtual_expression = NULL;
-	g_object_unref (_vala_container);
-	_vala_container = NULL;
-	_tmp0_ = expression;
-	if (!G_TYPE_CHECK_INSTANCE_TYPE (_tmp0_, RYGEL_TYPE_LOGICAL_EXPRESSION)) {
-		result = FALSE;
-		g_object_unref (query_container);
-		rygel_search_expression_unref (virtual_expression);
-		if (container) {
-			*container = _vala_container;
-		} else {
-			g_object_unref (_vala_container);
-		}
-		return result;
-	}
-	_tmp1_ = expression;
-	_tmp2_ = _rygel_search_expression_ref0 (G_TYPE_CHECK_INSTANCE_TYPE (_tmp1_, RYGEL_TYPE_LOGICAL_EXPRESSION) ? ((RygelLogicalExpression*) _tmp1_) : NULL);
-	logical_expression = _tmp2_;
-	_tmp5_ = logical_expression;
-	_tmp6_ = ((RygelSearchExpression*) _tmp5_)->operand1;
-	if (G_TYPE_CHECK_INSTANCE_TYPE ((RygelSearchExpression*) _tmp6_, RYGEL_TYPE_RELATIONAL_EXPRESSION)) {
-		RygelLogicalExpression* _tmp7_;
-		gconstpointer _tmp8_;
-		_tmp7_ = logical_expression;
-		_tmp8_ = ((RygelSearchExpression*) _tmp7_)->operand2;
-		_tmp4_ = G_TYPE_CHECK_INSTANCE_TYPE ((RygelSearchExpression*) _tmp8_, RYGEL_TYPE_RELATIONAL_EXPRESSION);
-	} else {
-		_tmp4_ = FALSE;
-	}
-	_tmp9_ = _tmp4_;
-	if (_tmp9_) {
-		RygelLogicalExpression* _tmp10_;
-		gconstpointer _tmp11_;
-		_tmp10_ = logical_expression;
-		_tmp11_ = ((RygelSearchExpression*) _tmp10_)->op;
-		_tmp3_ = ((RygelLogicalOperator) ((gintptr) _tmp11_)) == RYGEL_LOGICAL_OPERATOR_AND;
-	} else {
-		_tmp3_ = FALSE;
-	}
-	_tmp12_ = _tmp3_;
-	if (!_tmp12_) {
-		result = FALSE;
-		rygel_search_expression_unref (logical_expression);
-		g_object_unref (query_container);
-		rygel_search_expression_unref (virtual_expression);
-		if (container) {
-			*container = _vala_container;
-		} else {
-			g_object_unref (_vala_container);
-		}
-		return result;
-	}
-	_tmp13_ = logical_expression;
-	_tmp14_ = ((RygelSearchExpression*) _tmp13_)->operand1;
-	_tmp15_ = _rygel_search_expression_ref0 (G_TYPE_CHECK_INSTANCE_TYPE ((RygelSearchExpression*) _tmp14_, RYGEL_TYPE_RELATIONAL_EXPRESSION) ? ((RygelRelationalExpression*) ((RygelSearchExpression*) _tmp14_)) : NULL);
-	left_expression = _tmp15_;
-	_tmp16_ = logical_expression;
-	_tmp17_ = ((RygelSearchExpression*) _tmp16_)->operand2;
-	_tmp18_ = _rygel_search_expression_ref0 (G_TYPE_CHECK_INSTANCE_TYPE ((RygelSearchExpression*) _tmp17_, RYGEL_TYPE_RELATIONAL_EXPRESSION) ? ((RygelRelationalExpression*) ((RygelSearchExpression*) _tmp17_)) : NULL);
-	right_expression = _tmp18_;
-	_tmp19_ = left_expression;
-	_tmp20_ = rygel_media_export_root_container_search_to_virtual_container (self, _tmp19_);
-	g_object_unref (query_container);
-	query_container = _tmp20_;
-	_tmp21_ = query_container;
-	if (_tmp21_ == NULL) {
-		RygelRelationalExpression* _tmp22_;
-		RygelMediaExportQueryContainer* _tmp23_ = NULL;
-		RygelMediaExportQueryContainer* _tmp24_;
-		_tmp22_ = right_expression;
-		_tmp23_ = rygel_media_export_root_container_search_to_virtual_container (self, _tmp22_);
-		g_object_unref (query_container);
-		query_container = _tmp23_;
-		_tmp24_ = query_container;
-		if (_tmp24_ != NULL) {
-			RygelRelationalExpression* _tmp25_;
-			RygelRelationalExpression* _tmp26_;
-			_tmp25_ = left_expression;
-			_tmp26_ = _rygel_search_expression_ref0 (_tmp25_);
-			rygel_search_expression_unref (virtual_expression);
-			virtual_expression = _tmp26_;
-		} else {
-			result = FALSE;
-			rygel_search_expression_unref (right_expression);
-			rygel_search_expression_unref (left_expression);
-			rygel_search_expression_unref (logical_expression);
-			g_object_unref (query_container);
-			rygel_search_expression_unref (virtual_expression);
-			if (container) {
-				*container = _vala_container;
-			} else {
-				g_object_unref (_vala_container);
-			}
-			return result;
-		}
-	} else {
-		RygelRelationalExpression* _tmp27_;
-		RygelRelationalExpression* _tmp28_;
-		_tmp27_ = right_expression;
-		_tmp28_ = _rygel_search_expression_ref0 (_tmp27_);
-		rygel_search_expression_unref (virtual_expression);
-		virtual_expression = _tmp28_;
-	}
-	_tmp29_ = rygel_media_export_query_container_factory_get_default ();
-	factory = _tmp29_;
-	_tmp30_ = factory;
-	_tmp31_ = query_container;
-	_tmp32_ = rygel_media_object_get_id ((RygelMediaObject*) _tmp31_);
-	_tmp33_ = _tmp32_;
-	_tmp34_ = rygel_media_export_query_container_factory_get_virtual_container_definition (_tmp30_, _tmp33_);
-	plaintext_id = _tmp34_;
-	_tmp35_ = plaintext_id;
-	_tmp36_ = string_replace (_tmp35_, RYGEL_MEDIA_EXPORT_QUERY_CONTAINER_PREFIX, "");
-	last_argument = _tmp36_;
-	_tmp37_ = virtual_expression;
-	_tmp38_ = ((RygelSearchExpression*) _tmp37_)->operand2;
-	_tmp39_ = g_uri_escape_string ((const gchar*) _tmp38_, "", TRUE);
-	escaped_detail = _tmp39_;
-	_tmp40_ = virtual_expression;
-	_tmp41_ = ((RygelSearchExpression*) _tmp40_)->operand1;
-	_tmp42_ = escaped_detail;
-	_tmp43_ = last_argument;
-	_tmp44_ = g_strdup_printf ("%s%s,%s,%s", RYGEL_MEDIA_EXPORT_QUERY_CONTAINER_PREFIX, (const gchar*) _tmp41_, _tmp42_, _tmp43_);
-	new_id = _tmp44_;
-	_tmp45_ = factory;
-	_tmp46_ = rygel_media_export_db_container_get_media_db (RYGEL_MEDIA_EXPORT_DB_CONTAINER (self));
-	_tmp47_ = new_id;
-	_tmp48_ = rygel_media_export_query_container_factory_create_from_description (_tmp45_, _tmp46_, _tmp47_, "");
-	g_object_unref (_vala_container);
-	_vala_container = (RygelMediaContainer*) _tmp48_;
-	result = TRUE;
-	g_free (new_id);
-	g_free (escaped_detail);
-	g_free (last_argument);
-	g_free (plaintext_id);
-	g_object_unref (factory);
-	rygel_search_expression_unref (right_expression);
-	rygel_search_expression_unref (left_expression);
-	rygel_search_expression_unref (logical_expression);
-	g_object_unref (query_container);
-	rygel_search_expression_unref (virtual_expression);
-	if (container) {
-		*container = _vala_container;
-	} else {
-		g_object_unref (_vala_container);
-	}
-	return result;
+static void
+replace_in_string (gchar       **self,
+		   const gchar  *old_part,
+		   const gchar  *new_part)
+{
+  g_return_if_fail (self != NULL && *self != NULL);
+  g_return_if_fail (old_part != NULL);
+
+  if (G_LIKELY (new_part)) {
+    gchar *temp_uri = *self;
+    GError *error = NULL;
+
+    *self = rygel_media_export_string_replace (temp_uri, old_part, new_part, &error);
+    if (error) {
+      *self = temp_uri;
+      g_warning ("Could not replace %s in %s with %s: %s",
+		 old_part,
+		 *self,
+		 new_part,
+		 error->message);
+      g_error_free (error);
+    } else {
+      g_free (temp_uri);
+    }
+  }
+}
+
+static GeeArrayList *
+rygel_media_export_root_container_get_shared_uris (RygelMediaExportRootContainer *self) {
+  GeeArrayList* uris;
+  GeeArrayList* actual_uris;
+  RygelConfiguration* config;
+  GFile* home_dir;
+  const gchar* pictures_dir;
+  const gchar* videos_dir;
+  const gchar* music_dir;
+  GError *error;
+  gint iter;
+  gint size;
+  GeeAbstractList *abstract_uris;
+  GeeAbstractCollection *abstract_actual_uris;
+
+  g_return_val_if_fail (RYGEL_MEDIA_EXPORT_IS_ROOT_CONTAINER (self), NULL);
+
+  error = NULL;
+  config = RYGEL_CONFIGURATION (rygel_meta_config_get_default ());
+  uris = rygel_configuration_get_string_list (config,
+					      "MediaExport",
+					      "uris",
+					      &error);
+  if (error) {
+    g_error_free (error);
+    error = NULL;
+    uris = gee_array_list_new (G_TYPE_STRING, (GBoxedCopyFunc) g_strdup, g_free, NULL, NULL, NULL);
+  }
+  actual_uris = gee_array_list_new (G_TYPE_FILE, (GBoxedCopyFunc) g_object_ref, g_object_unref, NULL, NULL, NULL);
+  home_dir = g_file_new_for_path (g_get_home_dir ());
+  pictures_dir = g_get_user_special_dir (G_USER_DIRECTORY_PICTURES);
+  videos_dir = g_get_user_special_dir (G_USER_DIRECTORY_VIDEOS);
+  music_dir = g_get_user_special_dir (G_USER_DIRECTORY_MUSIC);
+  size = gee_abstract_collection_get_size (GEE_ABSTRACT_COLLECTION (uris));
+  abstract_uris = GEE_ABSTRACT_LIST (uris);
+  abstract_actual_uris = GEE_ABSTRACT_COLLECTION (actual_uris);
+
+  for (iter = 0; iter < size; ++iter) {
+    gchar *uri = gee_abstract_list_get (abstract_uris, iter);
+    GFile *file = g_file_new_for_commandline_arg (uri);
+    gboolean add = TRUE;
+
+    if (G_LIKELY (!g_file_equal (file, home_dir))) {
+      gchar *actual_uri = g_strdup (uri);
+
+      replace_in_string (&actual_uri, "@PICTURES@", pictures_dir);
+      replace_in_string (&actual_uri, "@VIDEOS@", videos_dir);
+      replace_in_string (&actual_uri, "@MUSIC@", music_dir);
+
+      g_object_unref (file);
+      file = g_file_new_for_commandline_arg (actual_uri);
+      if (g_file_equal (file, home_dir)) {
+	add = FALSE;
+      }
+      g_free (actual_uri);
+    }
+
+    if (add) {
+      gee_abstract_collection_add (abstract_actual_uris, file);
+    }
+
+    g_object_unref (file);
+    g_free (uri);
+  }
+  g_object_unref (home_dir);
+  g_object_unref (config);
+  g_object_unref (uris);
+
+  return actual_uris;
 }
 
-
-/**
-     * Create a new root container.
-     */
-static void _rygel_media_export_root_container_on_initial_harvesting_done_rygel_media_export_harvester_done (RygelMediaExportHarvester* _sender G_GNUC_UNUSED, gpointer self) {
-	rygel_media_export_root_container_on_initial_harvesting_done (self);
+static void
+rygel_media_export_root_container_add_folder_definition (RygelMediaExportRootContainer           *self,
+							 RygelMediaContainer                     *container,
+							 const gchar                             *item_class,
+							 const RygelMediaExportFolderDefinition  *definition,
+							 GError                                 **error) {
+  gchar *id;
+  RygelMediaExportQueryContainerFactory *factory;
+  RygelMediaContainer *query_container;
+  RygelMediaExportMediaCache *db;
+  GError *inner_error;
+
+  g_return_if_fail (RYGEL_MEDIA_EXPORT_IS_ROOT_CONTAINER (self));
+  g_return_if_fail (RYGEL_IS_MEDIA_CONTAINER (container));
+  g_return_if_fail (item_class != NULL);
+  g_return_if_fail (definition != NULL);
+
+  id = g_strdup_printf ("%supnp:class,%s,%s", RYGEL_MEDIA_EXPORT_QUERY_CONTAINER_PREFIX, item_class, definition->definition);
+  if (g_str_has_suffix (id, ",")) {
+    gchar *tmp = id;
+
+    id = rygel_media_export_string_slice (tmp, 0, -1);
+    if (!id) {
+      g_warning ("Failed to remove the last character from '%s'.",
+		 tmp);
+    }
+    g_free (tmp);
+    if (!id) {
+      return;
+    }
+  }
+  factory = rygel_media_export_query_container_factory_get_default ();
+  query_container = RYGEL_MEDIA_CONTAINER (rygel_media_export_query_container_factory_create_from_description (factory,
+													       id,
+													       _(definition->title)));
+  db = rygel_media_export_db_container_get_media_db (RYGEL_MEDIA_EXPORT_DB_CONTAINER (self));
+  inner_error = NULL;
+  if (rygel_media_container_get_child_count (query_container) > 0) {
+    rygel_media_object_set_parent (RYGEL_MEDIA_OBJECT (query_container), container);
+    rygel_media_export_media_cache_save_container (db, query_container, &inner_error);
+  } else {
+    rygel_media_export_media_cache_remove_by_id (db, id, &inner_error);
+  }
+  if (inner_error) {
+    g_propagate_error (error, inner_error);
+  }
+  g_object_unref (query_container);
+  g_object_unref (factory);
+  g_free (id);
 }
 
-
-static RygelMediaExportRootContainer* rygel_media_export_root_container_construct (GType object_type, GError** error) {
-	RygelMediaExportRootContainer * self = NULL;
-	RygelMediaExportMediaCache* _tmp0_ = NULL;
-	RygelMediaExportMediaCache* db;
-	const gchar* _tmp1_ = NULL;
-	GCancellable* _tmp2_;
-	GeeArrayList* ids = NULL;
-	GCancellable* _tmp19_;
-	GeeArrayList* _tmp20_ = NULL;
-	GeeArrayList* _tmp21_;
-	RygelMediaExportHarvester* _tmp22_;
-	RygelMediaExportHarvester* _tmp23_;
-	gulong _tmp24_ = 0UL;
-	GError * _inner_error_ = NULL;
-	_tmp0_ = rygel_media_export_media_cache_get_default (&_inner_error_);
-	db = _tmp0_;
-	if (_inner_error_ != NULL) {
-		g_propagate_error (error, _inner_error_);
-		return NULL;
-	}
-	_tmp1_ = _ ("@REALNAME@'s media");
-	self = RYGEL_MEDIA_EXPORT_ROOT_CONTAINER (g_object_new (object_type,
-								"id", "0",
-								"parent", NULL,
-								"title", _tmp1_,
-								"child-count", 0,
-								NULL));
-	_tmp2_ = g_cancellable_new ();
-	g_object_unref (self->priv->cancellable);
-	self->priv->cancellable = _tmp2_;
-
-	goto __finally32;
-	{
-		GError* err = NULL;
-		const gchar* _tmp5_ = NULL;
-		GError* _tmp6_;
-		const gchar* _tmp7_;
-		err = _inner_error_;
-		_inner_error_ = NULL;
-		_tmp5_ = _ ("Failed to create MediaExport D-Bus service: %s");
-		_tmp6_ = err;
-		_tmp7_ = _tmp6_->message;
-		g_warning (_tmp5_, _tmp7_);
-		g_error_free (err);
-	}
-	__finally32:
-	if (_inner_error_ != NULL) {
-		g_propagate_error (error, _inner_error_);
-		g_object_unref (db);
-		g_object_unref (self);
-		return NULL;
-	}
-	{
-		RygelMediaExportMediaCache* _tmp8_;
-		_tmp8_ = rygel_media_export_db_container_get_media_db (RYGEL_MEDIA_EXPORT_DB_CONTAINER (self));
-		rygel_media_export_media_cache_save_container (_tmp8_, (RygelMediaContainer*) self, &_inner_error_);
-		if (_inner_error_ != NULL) {
-			goto __catch33_g_error;
-		}
-	}
-	goto __finally33;
-	__catch33_g_error:
-	{
-		GError* _error_ = NULL;
-		_error_ = _inner_error_;
-		_inner_error_ = NULL;
-		g_error_free (_error_);
-	}
-	__finally33:
-	if (_inner_error_ != NULL) {
-		g_propagate_error (error, _inner_error_);
-		g_object_unref (db);
-		g_object_unref (self);
-		return NULL;
-	}
-	{
-		const gchar* _tmp10_ = NULL;
-		RygelMediaExportDBContainer* _tmp11_;
-		RygelMediaContainer* _tmp12_;
-		RygelMediaExportMediaCache* _tmp13_;
-		RygelMediaContainer* _tmp14_;
-		_tmp10_ = _ (RYGEL_MEDIA_EXPORT_ROOT_CONTAINER_FILESYSTEM_FOLDER_NAME);
-		_tmp11_ = rygel_media_export_db_container_new (RYGEL_MEDIA_EXPORT_ROOT_CONTAINER_FILESYSTEM_FOLDER_ID, _tmp10_);
-		g_object_unref (self->priv->filesystem_container);
-		self->priv->filesystem_container = (RygelMediaContainer*) _tmp11_;
-		_tmp12_ = self->priv->filesystem_container;
-		rygel_media_object_set_parent ((RygelMediaObject*) _tmp12_, (RygelMediaContainer*) self);
-		_tmp13_ = rygel_media_export_db_container_get_media_db (RYGEL_MEDIA_EXPORT_DB_CONTAINER (self));
-		_tmp14_ = self->priv->filesystem_container;
-		rygel_media_export_media_cache_save_container (_tmp13_, _tmp14_, &_inner_error_);
-		if (_inner_error_ != NULL) {
-			goto __catch34_g_error;
-		}
-	}
-	goto __finally34;
-	__catch34_g_error:
-	{
-		GError* _error_ = NULL;
-		_error_ = _inner_error_;
-		_inner_error_ = NULL;
-		g_error_free (_error_);
-	}
-	__finally34:
-	if (_inner_error_ != NULL) {
-		g_propagate_error (error, _inner_error_);
-		g_object_unref (db);
-		g_object_unref (self);
-		return NULL;
-	}
-	{
-		RygelMediaExportMediaCache* _tmp15_;
-		GeeArrayList* _tmp16_ = NULL;
-		GeeArrayList* _tmp17_;
-		_tmp15_ = rygel_media_export_db_container_get_media_db (RYGEL_MEDIA_EXPORT_DB_CONTAINER (self));
-		_tmp16_ = rygel_media_export_media_cache_get_child_ids (_tmp15_, RYGEL_MEDIA_EXPORT_ROOT_CONTAINER_FILESYSTEM_FOLDER_ID, &_inner_error_);
-		_tmp17_ = _tmp16_;
-		if (_inner_error_ != NULL) {
-			if (_inner_error_->domain == RYGEL_MEDIA_EXPORT_DATABASE_ERROR) {
-				goto __catch35_rygel_media_export_database_error;
-			}
-			g_object_unref (ids);
-			g_object_unref (db);
-			g_critical ("file %s: line %d: unexpected error: %s (%s, %d)", __FILE__, __LINE__, _inner_error_->message, g_quark_to_string (_inner_error_->domain), _inner_error_->code);
-			g_clear_error (&_inner_error_);
-			return NULL;
-		}
-		g_object_unref (ids);
-		ids = _tmp17_;
-	}
-	goto __finally35;
-	__catch35_rygel_media_export_database_error:
-	{
-		GError* e = NULL;
-		GeeArrayList* _tmp18_;
-		e = _inner_error_;
-		_inner_error_ = NULL;
-		_tmp18_ = gee_array_list_new (G_TYPE_STRING, (GBoxedCopyFunc) g_strdup, g_free, NULL, NULL, NULL);
-		g_object_unref (ids);
-		ids = _tmp18_;
-		g_error_free (e);
-	}
-	__finally35:
-	if (_inner_error_ != NULL) {
-		g_propagate_error (error, _inner_error_);
-		g_object_unref (ids);
-		g_object_unref (db);
-		g_object_unref (self);
-		return NULL;
-	}
-	_tmp19_ = self->priv->cancellable;
-	_tmp20_ = rygel_media_export_root_container_get_shared_uris (self);
-	_tmp21_ = _tmp20_;
-	_tmp22_ = rygel_media_export_harvester_new (_tmp19_, _tmp21_);
-	g_object_unref (self->priv->harvester);
-	self->priv->harvester = _tmp22_;
-	g_object_unref (_tmp21_);
-	_tmp23_ = self->priv->harvester;
-	_tmp24_ = g_signal_connect_object (_tmp23_, "done", (GCallback) _rygel_media_export_root_container_on_initial_harvesting_done_rygel_media_export_harvester_done, self, 0);
-	self->priv->harvester_signal_id = _tmp24_;
-	{
-		RygelMediaExportHarvester* _tmp25_;
-		GeeArrayList* _tmp26_;
-		GeeArrayList* _tmp27_;
-		GeeArrayList* _tmp28_;
-		GeeArrayList* _file_list;
-		GeeArrayList* _tmp29_;
-		gint _tmp30_;
-		gint _tmp31_;
-		gint _file_size;
-		gint _file_index;
-		_tmp25_ = self->priv->harvester;
-		_tmp26_ = rygel_media_export_harvester_get_locations (_tmp25_);
-		_tmp27_ = _tmp26_;
-		_tmp28_ = g_object_ref (_tmp27_);
-		_file_list = _tmp28_;
-		_tmp29_ = _file_list;
-		_tmp30_ = gee_abstract_collection_get_size ((GeeAbstractCollection*) _tmp29_);
-		_tmp31_ = _tmp30_;
-		_file_size = _tmp31_;
-		_file_index = -1;
-		while (TRUE) {
-			gint _tmp32_;
-			gint _tmp33_;
-			gint _tmp34_;
-			GeeArrayList* _tmp35_;
-			gint _tmp36_;
-			gpointer _tmp37_ = NULL;
-			GFile* file;
-			GeeArrayList* _tmp38_;
-			GFile* _tmp39_;
-			gchar* _tmp40_ = NULL;
-			gchar* _tmp41_;
-			RygelMediaExportHarvester* _tmp42_;
-			GFile* _tmp43_;
-			RygelMediaContainer* _tmp44_;
-			_tmp32_ = _file_index;
-			_file_index = _tmp32_ + 1;
-			_tmp33_ = _file_index;
-			_tmp34_ = _file_size;
-			if (!(_tmp33_ < _tmp34_)) {
-				break;
-			}
-			_tmp35_ = _file_list;
-			_tmp36_ = _file_index;
-			_tmp37_ = gee_abstract_list_get ((GeeAbstractList*) _tmp35_, _tmp36_);
-			file = (GFile*) _tmp37_;
-			_tmp38_ = ids;
-			_tmp39_ = file;
-			_tmp40_ = rygel_media_export_media_cache_get_id (_tmp39_);
-			_tmp41_ = _tmp40_;
-			gee_abstract_collection_remove ((GeeAbstractCollection*) _tmp38_, _tmp41_);
-			g_free (_tmp41_);
-			_tmp42_ = self->priv->harvester;
-			_tmp43_ = file;
-			_tmp44_ = self->priv->filesystem_container;
-			rygel_media_export_harvester_schedule (_tmp42_, _tmp43_, _tmp44_, NULL);
-			g_object_unref (file);
-		}
-		g_object_unref (_file_list);
-	}
-	{
-		GeeArrayList* _tmp45_;
-		GeeArrayList* _tmp46_;
-		GeeArrayList* _id_list;
-		GeeArrayList* _tmp47_;
-		gint _tmp48_;
-		gint _tmp49_;
-		gint _id_size;
-		gint _id_index;
-		_tmp45_ = ids;
-		_tmp46_ = g_object_ref (_tmp45_);
-		_id_list = _tmp46_;
-		_tmp47_ = _id_list;
-		_tmp48_ = gee_abstract_collection_get_size ((GeeAbstractCollection*) _tmp47_);
-		_tmp49_ = _tmp48_;
-		_id_size = _tmp49_;
-		_id_index = -1;
-		while (TRUE) {
-			gint _tmp50_;
-			gint _tmp51_;
-			gint _tmp52_;
-			GeeArrayList* _tmp53_;
-			gint _tmp54_;
-			gpointer _tmp55_ = NULL;
-			gchar* id;
-			const gchar* _tmp56_;
-			_tmp50_ = _id_index;
-			_id_index = _tmp50_ + 1;
-			_tmp51_ = _id_index;
-			_tmp52_ = _id_size;
-			if (!(_tmp51_ < _tmp52_)) {
-				break;
-			}
-			_tmp53_ = _id_list;
-			_tmp54_ = _id_index;
-			_tmp55_ = gee_abstract_list_get ((GeeAbstractList*) _tmp53_, _tmp54_);
-			id = (gchar*) _tmp55_;
-			_tmp56_ = id;
-			g_debug ("rygel-media-export-root-container.vala:397: ID %s no longer in config;" \
-" deleting...", _tmp56_);
-			{
-				RygelMediaExportMediaCache* _tmp57_;
-				const gchar* _tmp58_;
-				_tmp57_ = rygel_media_export_db_container_get_media_db (RYGEL_MEDIA_EXPORT_DB_CONTAINER (self));
-				_tmp58_ = id;
-				rygel_media_export_media_cache_remove_by_id (_tmp57_, _tmp58_, &_inner_error_);
-				if (_inner_error_ != NULL) {
-					if (_inner_error_->domain == RYGEL_MEDIA_EXPORT_DATABASE_ERROR) {
-						goto __catch36_rygel_media_export_database_error;
-					}
-					g_free (id);
-					g_object_unref (_id_list);
-					g_object_unref (ids);
-					g_object_unref (db);
-					g_critical ("file %s: line %d: unexpected error: %s (%s, %d)", __FILE__, __LINE__, _inner_error_->message, g_quark_to_string (_inner_error_->domain), _inner_error_->code);
-					g_clear_error (&_inner_error_);
-					return NULL;
-				}
-			}
-			goto __finally36;
-			__catch36_rygel_media_export_database_error:
-			{
-				GError* _error_ = NULL;
-				const gchar* _tmp59_ = NULL;
-				GError* _tmp60_;
-				const gchar* _tmp61_;
-				_error_ = _inner_error_;
-				_inner_error_ = NULL;
-				_tmp59_ = _ ("Failed to remove entry: %s");
-				_tmp60_ = _error_;
-				_tmp61_ = _tmp60_->message;
-				g_warning (_tmp59_, _tmp61_);
-				g_error_free (_error_);
-			}
-			__finally36:
-			if (_inner_error_ != NULL) {
-				g_propagate_error (error, _inner_error_);
-				g_free (id);
-				g_object_unref (_id_list);
-				g_object_unref (ids);
-				g_object_unref (db);
-				g_object_unref (self);
-				return NULL;
-			}
-			g_free (id);
-		}
-		g_object_unref (_id_list);
-	}
-	rygel_media_container_updated ((RygelMediaContainer*) self, NULL, RYGEL_OBJECT_EVENT_TYPE_MODIFIED, FALSE);
-	g_object_unref (ids);
-	g_object_unref (db);
-	return self;
+static void
+rygel_media_export_root_container_add_virtual_containers_for_class (RygelMediaExportRootContainer           *self,
+								    const gchar                             *parent,
+								    const gchar                             *item_class,
+								    const RygelMediaExportFolderDefinition  *definitions,
+								    guint                                    definitions_length,
+								    GError                                 **error) {
+  RygelMediaContainer *container;
+  RygelMediaObject *object;
+  gchar *new_id;
+  const gchar *id;
+  RygelMediaExportMediaCache *db;
+  GError *inner_error;
+  gint child_count;
+  guint iter;
+
+  g_return_if_fail (RYGEL_MEDIA_EXPORT_IS_ROOT_CONTAINER (self));
+  g_return_if_fail (parent != NULL);
+  g_return_if_fail (item_class != NULL);
+
+  container = RYGEL_MEDIA_CONTAINER (rygel_media_export_null_container_new ());
+  object = RYGEL_MEDIA_OBJECT (container);
+  rygel_media_object_set_parent (object, RYGEL_MEDIA_CONTAINER (self));
+  rygel_media_object_set_title (object, parent);
+  new_id = g_strconcat ("virtual-parent:", item_class, NULL);
+  rygel_media_object_set_id (object, new_id);
+  g_free (new_id);
+  inner_error = NULL;
+  db = rygel_media_export_db_container_get_media_db (RYGEL_MEDIA_EXPORT_DB_CONTAINER (self));
+  rygel_media_export_media_cache_save_container (db, container, &inner_error);
+  if (inner_error) {
+    goto out;
+  }
+
+  for (iter = 0; iter < G_N_ELEMENTS (VIRTUAL_FOLDERS_DEFAULT); ++iter) {
+    rygel_media_export_root_container_add_folder_definition (self, container, item_class, &(VIRTUAL_FOLDERS_DEFAULT[iter]), &inner_error);
+    if (inner_error) {
+      goto out;
+    }
+  }
+
+  if (definitions) {
+    for (iter = 0; iter < definitions_length; ++iter) {
+      rygel_media_export_root_container_add_folder_definition (self, container, item_class, &(definitions[iter]), &inner_error);
+      if (inner_error) {
+	goto out;
+      }
+    }
+  }
+
+  id = rygel_media_object_get_id (object);
+  child_count = rygel_media_export_media_cache_get_child_count (db,
+								id,
+								&inner_error);
+  if (inner_error) {
+    goto out;
+  }
+
+  if (!child_count) {
+    rygel_media_export_media_cache_remove_by_id (db, id, &inner_error);
+    if (inner_error) {
+      goto out;
+    }
+  } else {
+    rygel_media_container_updated (container, NULL, RYGEL_OBJECT_EVENT_TYPE_MODIFIED, FALSE);
+  }
+
+ out:
+  if (inner_error) {
+    g_propagate_error (error, inner_error);
+  }
+  g_object_unref (container);
 }
 
-
-static RygelMediaExportRootContainer*
-rygel_media_export_root_container_new (GError** error) {
-	return rygel_media_export_root_container_construct (RYGEL_MEDIA_EXPORT_TYPE_ROOT_CONTAINER, error);
+static void
+rygel_media_export_root_container_add_default_virtual_folders (RygelMediaExportRootContainer *self) {
+  GError * error = NULL;
+
+  g_return_if_fail (RYGEL_MEDIA_EXPORT_IS_ROOT_CONTAINER (self));
+
+  rygel_media_export_root_container_add_virtual_containers_for_class (self,
+								      _("Music"),
+								      RYGEL_MUSIC_ITEM_UPNP_CLASS,
+								      VIRTUAL_FOLDERS_MUSIC,
+								      G_N_ELEMENTS (VIRTUAL_FOLDERS_MUSIC),
+								      &error);
+  if (error) {
+    goto out;
+  }
+  rygel_media_export_root_container_add_virtual_containers_for_class (self,
+								      _("Pictures"),
+								      RYGEL_PHOTO_ITEM_UPNP_CLASS,
+								      NULL,
+								      0,
+								      &error);
+  if (error) {
+    goto out;
+  }
+  rygel_media_export_root_container_add_virtual_containers_for_class (self,
+								      _("Videos"),
+								      RYGEL_VIDEO_ITEM_UPNP_CLASS,
+								      NULL,
+								      0,
+								      &error);
+ out:
+  if (error) {
+    g_error_free (error);
+  }
 }
 
+static void
+on_filesystem_container_updated (RygelMediaContainer *sender G_GNUC_UNUSED,
+				 RygelMediaContainer *container G_GNUC_UNUSED,
+				 RygelMediaObject *object G_GNUC_UNUSED,
+				 RygelObjectEventType event_type G_GNUC_UNUSED,
+				 gboolean sub_tree_update G_GNUC_UNUSED,
+				 gpointer user_data) {
+  RygelMediaExportRootContainer *self = RYGEL_MEDIA_EXPORT_ROOT_CONTAINER (user_data);
 
-static void __lambda6_ (RygelMediaExportRootContainer* self) {
-	rygel_media_export_root_container_add_default_virtual_folders (self);
-	rygel_media_container_updated ((RygelMediaContainer*) self, NULL, RYGEL_OBJECT_EVENT_TYPE_MODIFIED, FALSE);
+  rygel_media_export_root_container_add_default_virtual_folders (self);
+  rygel_media_container_updated (RYGEL_MEDIA_CONTAINER (self), NULL, RYGEL_OBJECT_EVENT_TYPE_MODIFIED, FALSE);
 }
 
+static void
+rygel_media_export_root_container_on_initial_harvesting_done (RygelMediaExportRootContainer *self) {
+  g_return_if_fail (self != NULL);
 
-static void ___lambda6__rygel_media_container_container_updated (RygelMediaContainer* _sender G_GNUC_UNUSED, RygelMediaContainer* container G_GNUC_UNUSED, RygelMediaObject* object G_GNUC_UNUSED, RygelObjectEventType event_type G_GNUC_UNUSED, gboolean sub_tree_update G_GNUC_UNUSED, gpointer self) {
-	__lambda6_ (self);
+  g_signal_handler_disconnect (G_OBJECT (self->priv->harvester), self->priv->harvester_signal_id);
+  rygel_media_export_media_cache_debug_statistics (rygel_media_export_db_container_get_media_db (RYGEL_MEDIA_EXPORT_DB_CONTAINER (self)));
+  rygel_media_export_root_container_add_default_virtual_folders (self);
+  rygel_media_container_updated (RYGEL_MEDIA_CONTAINER (self), NULL, RYGEL_OBJECT_EVENT_TYPE_MODIFIED, FALSE);
+  g_signal_connect_object (self->priv->filesystem_container,
+			   "container-updated",
+			   G_CALLBACK (on_filesystem_container_updated),
+			   self,
+			   0);
 }
 
-
-static void rygel_media_export_root_container_on_initial_harvesting_done (RygelMediaExportRootContainer* self) {
-	RygelMediaExportHarvester* _tmp0_;
-	gulong _tmp1_;
-	RygelMediaExportMediaCache* _tmp2_;
-	RygelMediaContainer* _tmp3_;
-	g_return_if_fail (self != NULL);
-	_tmp0_ = self->priv->harvester;
-	_tmp1_ = self->priv->harvester_signal_id;
-	g_signal_handler_disconnect ((GObject*) _tmp0_, _tmp1_);
-	_tmp2_ = rygel_media_export_db_container_get_media_db (RYGEL_MEDIA_EXPORT_DB_CONTAINER (self));
-	rygel_media_export_media_cache_debug_statistics (_tmp2_);
-	rygel_media_export_root_container_add_default_virtual_folders (self);
-	rygel_media_container_updated ((RygelMediaContainer*) self, NULL, RYGEL_OBJECT_EVENT_TYPE_MODIFIED, FALSE);
-	_tmp3_ = self->priv->filesystem_container;
-	g_signal_connect_object (_tmp3_, "container-updated", (GCallback) ___lambda6__rygel_media_container_container_updated, self, 0);
+static void
+rygel_media_export_root_container_on_initial_harvesting_done_rygel_media_export_harvester_done (RygelMediaExportHarvester *sender G_GNUC_UNUSED,
+												 gpointer                   self) {
+  rygel_media_export_root_container_on_initial_harvesting_done (self);
 }
 
-
-static void rygel_media_export_root_container_add_default_virtual_folders (RygelMediaExportRootContainer* self) {
-	GError * _inner_error_ = NULL;
-	g_return_if_fail (self != NULL);
-	{
-		const gchar* _tmp0_ = NULL;
-		const gchar* _tmp1_ = NULL;
-		const gchar* _tmp2_ = NULL;
-		_tmp0_ = _ ("Music");
-		rygel_media_export_root_container_add_virtual_containers_for_class (self, _tmp0_, RYGEL_MUSIC_ITEM_UPNP_CLASS, VIRTUAL_FOLDERS_MUSIC, G_N_ELEMENTS (VIRTUAL_FOLDERS_MUSIC), &_inner_error_);
-		if (_inner_error_ != NULL) {
-			goto __catch37_g_error;
-		}
-		_tmp1_ = _ ("Pictures");
-		rygel_media_export_root_container_add_virtual_containers_for_class (self, _tmp1_, RYGEL_PHOTO_ITEM_UPNP_CLASS, NULL, 0, &_inner_error_);
-		if (_inner_error_ != NULL) {
-			goto __catch37_g_error;
-		}
-		_tmp2_ = _ ("Videos");
-		rygel_media_export_root_container_add_virtual_containers_for_class (self, _tmp2_, RYGEL_VIDEO_ITEM_UPNP_CLASS, NULL, 0, &_inner_error_);
-		if (_inner_error_ != NULL) {
-			goto __catch37_g_error;
-		}
-	}
-	goto __finally37;
-	__catch37_g_error:
-	{
-		GError* _error_ = NULL;
-		_error_ = _inner_error_;
-		_inner_error_ = NULL;
-		g_error_free (_error_);
-	}
-	__finally37:
-	if (_inner_error_ != NULL) {
-		g_critical ("file %s: line %d: uncaught error: %s (%s, %d)", __FILE__, __LINE__, _inner_error_->message, g_quark_to_string (_inner_error_->domain), _inner_error_->code);
-		g_clear_error (&_inner_error_);
-		return;
-	}
+static void
+rygel_media_export_root_container_constructed (GObject *object) {
+  RygelMediaExportRootContainer *self = RYGEL_MEDIA_EXPORT_ROOT_CONTAINER (object);
+  RygelMediaExportRootContainerPrivate *priv = self->priv;
+  RygelMediaExportMediaCache* db;
+  GError *error = NULL;
+  GeeArrayList* ids;
+  GeeAbstractCollection *abstract_ids;
+  GeeAbstractList *abstract_list_ids;
+  RygelMediaContainer *media_container = RYGEL_MEDIA_CONTAINER (self);
+  GeeArrayList *shared_uris;
+  GeeArrayList *locations;
+  GeeAbstractList *abstract_locations;
+  gint iter;
+  gint size;
+
+  G_OBJECT_CLASS (rygel_media_export_root_container_parent_class)->constructed (object);
+
+  priv->cancellable = g_cancellable_new ();
+  db = rygel_media_export_db_container_get_media_db (RYGEL_MEDIA_EXPORT_DB_CONTAINER (self));
+  rygel_media_export_media_cache_save_container (db, media_container, &error);
+  if (error) {
+    g_warning ("Failed to save root container into db: %s",
+	       error->message);
+    g_error_free (error);
+    error = NULL;
+  }
+
+  priv->filesystem_container = RYGEL_MEDIA_CONTAINER (rygel_media_export_db_container_new (RYGEL_MEDIA_EXPORT_ROOT_CONTAINER_FILESYSTEM_FOLDER_ID,
+											   _(RYGEL_MEDIA_EXPORT_ROOT_CONTAINER_FILESYSTEM_FOLDER_NAME)));
+  rygel_media_object_set_parent (RYGEL_MEDIA_OBJECT (priv->filesystem_container),
+				 media_container);
+  rygel_media_export_media_cache_save_container (db, RYGEL_MEDIA_CONTAINER (priv->filesystem_container), &error);
+  if (error) {
+    g_warning ("Failed to save filesystem container into db: %s",
+	       error->message);
+    g_error_free (error);
+    error = NULL;
+  }
+
+  ids = rygel_media_export_media_cache_get_child_ids (db, RYGEL_MEDIA_EXPORT_ROOT_CONTAINER_FILESYSTEM_FOLDER_ID, &error);
+  if (error) {
+    g_warning ("Failed to get child ids of %s from db: %s",
+	       RYGEL_MEDIA_EXPORT_ROOT_CONTAINER_FILESYSTEM_FOLDER_ID,
+	       error->message);
+    g_error_free (error);
+    error = NULL;
+    ids = gee_array_list_new (G_TYPE_STRING, (GBoxedCopyFunc) g_strdup, g_free, NULL, NULL, NULL);
+  }
+  abstract_ids = GEE_ABSTRACT_COLLECTION (ids);
+
+  shared_uris = rygel_media_export_root_container_get_shared_uris (self);
+  priv->harvester = rygel_media_export_harvester_new (priv->cancellable, shared_uris);
+  if (shared_uris) {
+    g_object_unref (shared_uris);
+  }
+  priv->harvester_signal_id = g_signal_connect_object (priv->harvester,
+						       "done",
+						       G_CALLBACK (rygel_media_export_root_container_on_initial_harvesting_done_rygel_media_export_harvester_done),
+						       self,
+						       0);
+
+  locations = rygel_media_export_harvester_get_locations (priv->harvester);
+  abstract_locations = GEE_ABSTRACT_LIST (locations);
+  size = gee_abstract_collection_get_size (GEE_ABSTRACT_COLLECTION (locations));
+
+  for (iter = 0; iter < size; ++iter) {
+    GFile *file = gee_abstract_list_get (abstract_locations, iter);
+    gchar *file_id = rygel_media_export_media_cache_get_id (file);
+
+    gee_abstract_collection_remove (abstract_ids, file_id);
+    rygel_media_export_harvester_schedule (priv->harvester,
+					   file,
+					   priv->filesystem_container,
+					   NULL);
+    g_free (file_id);
+    g_object_unref (file);
+  }
+  g_object_unref (locations);
+
+  size = gee_abstract_collection_get_size (abstract_ids);
+  abstract_list_ids = GEE_ABSTRACT_LIST (ids);
+  for (iter = 0; iter < size; ++iter) {
+    gchar *id = gee_abstract_list_get (abstract_list_ids, iter);
+
+    g_debug ("rygel-media-export-root-container.vala:397: ID %s no longer in config; deleting...", id);
+    rygel_media_export_media_cache_remove_by_id (db, id, &error);
+    if (error) {
+      g_warning ("Failed to remove entry %s: %s",
+		 id,
+		 error->message);
+      g_error_free (error);
+      error = NULL;
+    }
+    g_free (id);
+  }
+  rygel_media_container_updated (media_container,
+				 NULL,
+				 RYGEL_OBJECT_EVENT_TYPE_MODIFIED,
+				 FALSE);
+  g_object_unref (ids);
 }
 
+static void
+rygel_media_export_root_container_dispose (GObject *object) {
+  RygelMediaExportRootContainer *self = RYGEL_MEDIA_EXPORT_ROOT_CONTAINER (object);
+  RygelMediaExportRootContainerPrivate *priv = self->priv;
 
-static gchar* string_slice (const gchar* self, glong start, glong end) {
-	gchar* result = NULL;
-	gint _tmp0_;
-	gint _tmp1_;
-	glong string_length;
-	glong _tmp2_;
-	glong _tmp5_;
-	gboolean _tmp8_ = FALSE;
-	glong _tmp9_;
-	gboolean _tmp12_;
-	gboolean _tmp13_ = FALSE;
-	glong _tmp14_;
-	gboolean _tmp17_;
-	glong _tmp18_;
-	glong _tmp19_;
-	glong _tmp20_;
-	glong _tmp21_;
-	glong _tmp22_;
-	gchar* _tmp23_ = NULL;
-	g_return_val_if_fail (self != NULL, NULL);
-	_tmp0_ = strlen (self);
-	_tmp1_ = _tmp0_;
-	string_length = (glong) _tmp1_;
-	_tmp2_ = start;
-	if (_tmp2_ < ((glong) 0)) {
-		glong _tmp3_;
-		glong _tmp4_;
-		_tmp3_ = string_length;
-		_tmp4_ = start;
-		start = _tmp3_ + _tmp4_;
-	}
-	_tmp5_ = end;
-	if (_tmp5_ < ((glong) 0)) {
-		glong _tmp6_;
-		glong _tmp7_;
-		_tmp6_ = string_length;
-		_tmp7_ = end;
-		end = _tmp6_ + _tmp7_;
-	}
-	_tmp9_ = start;
-	if (_tmp9_ >= ((glong) 0)) {
-		glong _tmp10_;
-		glong _tmp11_;
-		_tmp10_ = start;
-		_tmp11_ = string_length;
-		_tmp8_ = _tmp10_ <= _tmp11_;
-	} else {
-		_tmp8_ = FALSE;
-	}
-	_tmp12_ = _tmp8_;
-	g_return_val_if_fail (_tmp12_, NULL);
-	_tmp14_ = end;
-	if (_tmp14_ >= ((glong) 0)) {
-		glong _tmp15_;
-		glong _tmp16_;
-		_tmp15_ = end;
-		_tmp16_ = string_length;
-		_tmp13_ = _tmp15_ <= _tmp16_;
-	} else {
-		_tmp13_ = FALSE;
-	}
-	_tmp17_ = _tmp13_;
-	g_return_val_if_fail (_tmp17_, NULL);
-	_tmp18_ = start;
-	_tmp19_ = end;
-	g_return_val_if_fail (_tmp18_ <= _tmp19_, NULL);
-	_tmp20_ = start;
-	_tmp21_ = end;
-	_tmp22_ = start;
-	_tmp23_ = g_strndup (((gchar*) self) + _tmp20_, (gsize) (_tmp21_ - _tmp22_));
-	result = _tmp23_;
-	return result;
-}
+  if (priv->harvester) {
+    RygelMediaExportHarvester *harvester = priv->harvester;
 
+    priv->harvester = NULL;
+    g_object_unref (harvester);
+  }
+  if (priv->cancellable) {
+    GCancellable *cancellable = priv->cancellable;
 
-static void rygel_media_export_root_container_add_folder_definition (RygelMediaExportRootContainer* self, RygelMediaContainer* container, const gchar* item_class, RygelMediaExportFolderDefinition* definition, GError** error) {
-	const gchar* _tmp0_;
-	RygelMediaExportFolderDefinition _tmp1_;
-	const gchar* _tmp2_;
-	gchar* _tmp3_ = NULL;
-	gchar* id;
-	const gchar* _tmp4_;
-	gboolean _tmp5_ = FALSE;
-	RygelMediaExportQueryContainerFactory* _tmp8_ = NULL;
-	RygelMediaExportQueryContainerFactory* factory;
-	RygelMediaExportQueryContainerFactory* _tmp9_;
-	RygelMediaExportMediaCache* _tmp10_;
-	const gchar* _tmp11_;
-	RygelMediaExportFolderDefinition _tmp12_;
-	const gchar* _tmp13_;
-	const gchar* _tmp14_ = NULL;
-	RygelMediaExportQueryContainer* _tmp15_ = NULL;
-	RygelMediaExportQueryContainer* query_container;
-	RygelMediaExportQueryContainer* _tmp16_;
-	gint _tmp17_;
-	GError * _inner_error_ = NULL;
-	g_return_if_fail (self != NULL);
-	g_return_if_fail (container != NULL);
-	g_return_if_fail (item_class != NULL);
-	g_return_if_fail (definition != NULL);
-	_tmp0_ = item_class;
-	_tmp1_ = *definition;
-	_tmp2_ = _tmp1_.definition;
-	_tmp3_ = g_strdup_printf ("%supnp:class,%s,%s", RYGEL_MEDIA_EXPORT_QUERY_CONTAINER_PREFIX, _tmp0_, _tmp2_);
-	id = _tmp3_;
-	_tmp4_ = id;
-	_tmp5_ = g_str_has_suffix (_tmp4_, ",");
-	if (_tmp5_) {
-		const gchar* _tmp6_;
-		gchar* _tmp7_ = NULL;
-		_tmp6_ = id;
-		_tmp7_ = string_slice (_tmp6_, (glong) 0, (glong) (-1));
-		g_free (id);
-		id = _tmp7_;
-	}
-	_tmp8_ = rygel_media_export_query_container_factory_get_default ();
-	factory = _tmp8_;
-	_tmp9_ = factory;
-	_tmp10_ = rygel_media_export_db_container_get_media_db (RYGEL_MEDIA_EXPORT_DB_CONTAINER (self));
-	_tmp11_ = id;
-	_tmp12_ = *definition;
-	_tmp13_ = _tmp12_.title;
-	_tmp14_ = _ (_tmp13_);
-	_tmp15_ = rygel_media_export_query_container_factory_create_from_description (_tmp9_, _tmp10_, _tmp11_, _tmp14_);
-	query_container = _tmp15_;
-	_tmp16_ = query_container;
-	_tmp17_ = rygel_media_container_get_child_count ((RygelMediaContainer*) _tmp16_);
-	if (_tmp17_ > 0) {
-		RygelMediaExportQueryContainer* _tmp18_;
-		RygelMediaContainer* _tmp19_;
-		RygelMediaExportMediaCache* _tmp20_;
-		RygelMediaExportQueryContainer* _tmp21_;
-		_tmp18_ = query_container;
-		_tmp19_ = container;
-		rygel_media_object_set_parent ((RygelMediaObject*) _tmp18_, _tmp19_);
-		_tmp20_ = rygel_media_export_db_container_get_media_db (RYGEL_MEDIA_EXPORT_DB_CONTAINER (self));
-		_tmp21_ = query_container;
-		rygel_media_export_media_cache_save_container (_tmp20_, (RygelMediaContainer*) _tmp21_, &_inner_error_);
-		if (_inner_error_ != NULL) {
-			g_propagate_error (error, _inner_error_);
-			g_object_unref (query_container);
-			g_object_unref (factory);
-			g_free (id);
-			return;
-		}
-	} else {
-		RygelMediaExportMediaCache* _tmp22_;
-		const gchar* _tmp23_;
-		_tmp22_ = rygel_media_export_db_container_get_media_db (RYGEL_MEDIA_EXPORT_DB_CONTAINER (self));
-		_tmp23_ = id;
-		rygel_media_export_media_cache_remove_by_id (_tmp22_, _tmp23_, &_inner_error_);
-		if (_inner_error_ != NULL) {
-			g_propagate_error (error, _inner_error_);
-			g_object_unref (query_container);
-			g_object_unref (factory);
-			g_free (id);
-			return;
-		}
-	}
-	g_object_unref (query_container);
-	g_object_unref (factory);
-	g_free (id);
-}
+    priv->cancellable = NULL;
+    g_object_unref (cancellable);
+  }
+  if (priv->filesystem_container) {
+    RygelMediaContainer *container = priv->filesystem_container;
 
+    priv->filesystem_container = NULL;
+    g_object_unref (container);
+  }
 
-static void rygel_media_export_root_container_add_virtual_containers_for_class (RygelMediaExportRootContainer* self, const gchar* parent, const gchar* item_class, const RygelMediaExportFolderDefinition* definitions, int definitions_length1, GError** error) {
-	RygelMediaExportNullContainer* _tmp0_;
-	RygelMediaExportNullContainer* container;
-	RygelMediaExportNullContainer* _tmp1_;
-	RygelMediaExportNullContainer* _tmp2_;
-	const gchar* _tmp3_;
-	RygelMediaExportNullContainer* _tmp4_;
-	const gchar* _tmp5_;
-	gchar* _tmp6_;
-	gchar* _tmp7_;
-	RygelMediaExportMediaCache* _tmp8_;
-	RygelMediaExportNullContainer* _tmp9_;
-	const RygelMediaExportFolderDefinition* _tmp13_;
-	RygelMediaExportMediaCache* _tmp19_;
-	RygelMediaExportNullContainer* _tmp20_;
-	const gchar* _tmp21_;
-	const gchar* _tmp22_;
-	gint _tmp23_ = 0;
-	gint _tmp24_;
-	GError * _inner_error_ = NULL;
-	g_return_if_fail (self != NULL);
-	g_return_if_fail (parent != NULL);
-	g_return_if_fail (item_class != NULL);
-	_tmp0_ = rygel_media_export_null_container_new ();
-	container = _tmp0_;
-	_tmp1_ = container;
-	rygel_media_object_set_parent ((RygelMediaObject*) _tmp1_, (RygelMediaContainer*) self);
-	_tmp2_ = container;
-	_tmp3_ = parent;
-	rygel_media_object_set_title ((RygelMediaObject*) _tmp2_, _tmp3_);
-	_tmp4_ = container;
-	_tmp5_ = item_class;
-	_tmp6_ = g_strconcat ("virtual-parent:", _tmp5_, NULL);
-	_tmp7_ = _tmp6_;
-	rygel_media_object_set_id ((RygelMediaObject*) _tmp4_, _tmp7_);
-	g_free (_tmp7_);
-	_tmp8_ = rygel_media_export_db_container_get_media_db (RYGEL_MEDIA_EXPORT_DB_CONTAINER (self));
-	_tmp9_ = container;
-	rygel_media_export_media_cache_save_container (_tmp8_, (RygelMediaContainer*) _tmp9_, &_inner_error_);
-	if (_inner_error_ != NULL) {
-		g_propagate_error (error, _inner_error_);
-		g_object_unref (container);
-		return;
-	}
-	{
-		const RygelMediaExportFolderDefinition* definition_collection = NULL;
-		guint definition_it = 0;
-		definition_collection = VIRTUAL_FOLDERS_DEFAULT;
-		for (definition_it = 0; definition_it < G_N_ELEMENTS (VIRTUAL_FOLDERS_DEFAULT); ++definition_it) {
-			RygelMediaExportFolderDefinition definition = {0};
-			definition = definition_collection[definition_it];
-			{
-				RygelMediaExportNullContainer* _tmp10_;
-				const gchar* _tmp11_;
-				RygelMediaExportFolderDefinition _tmp12_;
-				_tmp10_ = container;
-				_tmp11_ = item_class;
-				_tmp12_ = definition;
-				rygel_media_export_root_container_add_folder_definition (self, (RygelMediaContainer*) _tmp10_, _tmp11_, &_tmp12_, &_inner_error_);
-				if (_inner_error_ != NULL) {
-					g_propagate_error (error, _inner_error_);
-					g_object_unref (container);
-					return;
-				}
-			}
-		}
-	}
-	_tmp13_ = definitions;
-	if (_tmp13_ != NULL) {
-		const RygelMediaExportFolderDefinition* _tmp14_;
-		gint _tmp14__length1;
-		_tmp14_ = definitions;
-		_tmp14__length1 = definitions_length1;
-		{
-			const RygelMediaExportFolderDefinition* definition_collection = NULL;
-			gint definition_it = 0;
-			definition_collection = _tmp14_;
-			for (definition_it = 0; definition_it < _tmp14__length1; ++definition_it) {
-				RygelMediaExportFolderDefinition _tmp15_ = {0};
-				RygelMediaExportFolderDefinition definition = {0};
-				rygel_media_export_folder_definition_copy (&definition_collection[definition_it], &_tmp15_);
-				definition = _tmp15_;
-				{
-					RygelMediaExportNullContainer* _tmp16_;
-					const gchar* _tmp17_;
-					RygelMediaExportFolderDefinition _tmp18_;
-					_tmp16_ = container;
-					_tmp17_ = item_class;
-					_tmp18_ = definition;
-					rygel_media_export_root_container_add_folder_definition (self, (RygelMediaContainer*) _tmp16_, _tmp17_, &_tmp18_, &_inner_error_);
-					if (_inner_error_ != NULL) {
-						g_propagate_error (error, _inner_error_);
-						rygel_media_export_folder_definition_destroy (&definition);
-						g_object_unref (container);
-						return;
-					}
-					rygel_media_export_folder_definition_destroy (&definition);
-				}
-			}
-		}
-	}
-	_tmp19_ = rygel_media_export_db_container_get_media_db (RYGEL_MEDIA_EXPORT_DB_CONTAINER (self));
-	_tmp20_ = container;
-	_tmp21_ = rygel_media_object_get_id ((RygelMediaObject*) _tmp20_);
-	_tmp22_ = _tmp21_;
-	_tmp23_ = rygel_media_export_media_cache_get_child_count (_tmp19_, _tmp22_, &_inner_error_);
-	_tmp24_ = _tmp23_;
-	if (_inner_error_ != NULL) {
-		g_propagate_error (error, _inner_error_);
-		g_object_unref (container);
-		return;
-	}
-	if (_tmp24_ == 0) {
-		RygelMediaExportMediaCache* _tmp25_;
-		RygelMediaExportNullContainer* _tmp26_;
-		const gchar* _tmp27_;
-		const gchar* _tmp28_;
-		_tmp25_ = rygel_media_export_db_container_get_media_db (RYGEL_MEDIA_EXPORT_DB_CONTAINER (self));
-		_tmp26_ = container;
-		_tmp27_ = rygel_media_object_get_id ((RygelMediaObject*) _tmp26_);
-		_tmp28_ = _tmp27_;
-		rygel_media_export_media_cache_remove_by_id (_tmp25_, _tmp28_, &_inner_error_);
-		if (_inner_error_ != NULL) {
-			g_propagate_error (error, _inner_error_);
-			g_object_unref (container);
-			return;
-		}
-	} else {
-		RygelMediaExportNullContainer* _tmp29_;
-		_tmp29_ = container;
-		rygel_media_container_updated ((RygelMediaContainer*) _tmp29_, NULL, RYGEL_OBJECT_EVENT_TYPE_MODIFIED, FALSE);
-	}
-	g_object_unref (container);
+  G_OBJECT_CLASS (rygel_media_export_root_container_parent_class)->dispose (object);
 }
 
+static void
+rygel_media_export_root_container_class_init (RygelMediaExportRootContainerClass *root_class) {
+  RygelMediaContainerClass *container_class = RYGEL_MEDIA_CONTAINER_CLASS (root_class);
+  GObjectClass *object_class = G_OBJECT_CLASS (root_class);
 
-static void rygel_media_export_root_container_class_init (RygelMediaExportRootContainerClass * klass) {
-	g_type_class_add_private (klass, sizeof (RygelMediaExportRootContainerPrivate));
-	RYGEL_MEDIA_CONTAINER_CLASS (klass)->find_object = rygel_media_export_root_container_real_find_object;
-	RYGEL_MEDIA_CONTAINER_CLASS (klass)->find_object_finish = rygel_media_export_root_container_real_find_object_finish;
-	G_OBJECT_CLASS (klass)->finalize = rygel_media_export_root_container_finalize;
-}
-
+  container_class->find_object = rygel_media_export_root_container_real_find_object;
+  container_class->find_object_finish = rygel_media_export_root_container_real_find_object_finish;
+  object_class->constructed = rygel_media_export_root_container_constructed;
+  object_class->dispose = rygel_media_export_root_container_dispose;
 
-static void rygel_media_export_root_container_init (RygelMediaExportRootContainer * self) {
-	self->priv = RYGEL_MEDIA_EXPORT_ROOT_CONTAINER_GET_PRIVATE (self);
+  g_type_class_add_private (root_class, sizeof (RygelMediaExportRootContainerPrivate));
 }
 
-
-static void rygel_media_export_root_container_finalize (GObject* obj) {
-	RygelMediaExportRootContainer * self;
-	self = G_TYPE_CHECK_INSTANCE_CAST (obj, RYGEL_MEDIA_EXPORT_TYPE_ROOT_CONTAINER, RygelMediaExportRootContainer);
-	g_object_unref (self->priv->harvester);
-	g_object_unref (self->priv->cancellable);
-	g_object_unref (self->priv->filesystem_container);
-	G_OBJECT_CLASS (rygel_media_export_root_container_parent_class)->finalize (obj);
+static void
+rygel_media_export_root_container_init (RygelMediaExportRootContainer *self) {
+  self->priv = RYGEL_MEDIA_EXPORT_ROOT_CONTAINER_GET_PRIVATE (self);
 }
 
 static void
diff --git a/src/media-export/rygel-media-export-string-utils.c b/src/media-export/rygel-media-export-string-utils.c
new file mode 100644
index 0000000..0de1a44
--- /dev/null
+++ b/src/media-export/rygel-media-export-string-utils.c
@@ -0,0 +1,97 @@
+/*
+ * Copyright (C) 2009,2010 Jens Georg <mail jensge org>.
+ *
+ * This file is part of Rygel.
+ *
+ * Rygel is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * Rygel is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include <string.h>
+
+#include "rygel-media-export-string-utils.h"
+
+gchar *
+rygel_media_export_string_replace (const gchar  *self,
+                                   const gchar  *old,
+                                   const gchar  *replacement,
+                                   GError      **error) {
+  gchar* result;
+  gchar *escaped;
+  GError *inner_error;
+  GRegex *regex;
+
+  g_return_val_if_fail (self != NULL, NULL);
+  g_return_val_if_fail (old != NULL, NULL);
+  g_return_val_if_fail (replacement != NULL, NULL);
+
+  result = NULL;
+  escaped = g_regex_escape_string (old, -1);
+  inner_error = NULL;
+  regex = g_regex_new (escaped, 0, 0, &inner_error);
+  g_free (escaped);
+  if (inner_error) {
+    g_propagate_error (error, inner_error);
+  } else {
+    result = g_regex_replace_literal (regex, self, -1, 0, replacement, 0, &inner_error);
+
+    if (inner_error) {
+      g_propagate_error (error, inner_error);
+    }
+    g_regex_unref (regex);
+  }
+
+  return result;
+}
+
+gchar *
+rygel_media_export_string_slice (const gchar *self,
+				 glong        start,
+				 glong        end) {
+  glong string_length;
+  gboolean outside;
+
+  g_return_val_if_fail (self != NULL, NULL);
+
+  string_length = strlen (self);
+  if (start < 0) {
+    start += string_length;
+  }
+  if (end < 0) {
+    end += string_length;
+  }
+  if (start >= 0) {
+    outside = (start > string_length);
+  } else {
+    outside = TRUE;
+  }
+  if (outside) {
+    g_warning ("Start offset (%ld) is outside string (%s).", start, self);
+    return NULL;
+  }
+  if (end >= 0) {
+    outside = (end > string_length);
+  } else {
+    outside = TRUE;
+  }
+  if (outside) {
+    g_warning ("End offset (%ld) is outside string (%s).", end, self);
+    return NULL;
+  }
+  if (start > end) {
+    g_warning ("Start offset (%ld) is later than end offset (%ld).", start, end);
+    return NULL;
+  }
+  return g_strndup (self + start, (gsize) (end - start));
+}
diff --git a/src/media-export/rygel-media-export-string-utils.h b/src/media-export/rygel-media-export-string-utils.h
new file mode 100644
index 0000000..1acbed9
--- /dev/null
+++ b/src/media-export/rygel-media-export-string-utils.h
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2009,2010 Jens Georg <mail jensge org>.
+ *
+ * This file is part of Rygel.
+ *
+ * Rygel is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * Rygel is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#ifndef __RYGEL_0_10_PLUGINS_MEDIA_EXPORT_STRING_UTILS_H__
+#define __RYGEL_0_10_PLUGINS_MEDIA_EXPORT_STRING_UTILS_H__
+
+#include <glib.h>
+
+G_BEGIN_DECLS
+
+gchar *
+rygel_media_export_string_replace (const gchar  *self,
+				   const gchar  *old,
+				   const gchar  *replacement,
+				   GError      **error);
+
+gchar *
+rygel_media_export_string_slice (const gchar *self,
+				 glong        start,
+				 glong        end);
+
+G_END_DECLS
+
+#endif
diff --git a/tests/test_simple.c b/tests/test_simple.c
index 7aab422..ae2a4f7 100644
--- a/tests/test_simple.c
+++ b/tests/test_simple.c
@@ -27,6 +27,12 @@
 
 int main(int argc, char *argv[])
 {
+  RygelPluginLoader *loader;
+  GeeCollection *list_plugins;
+  GeeIterator *iter;
+  RygelMediaServerPlugin *plugin;
+  RygelMediaContainer *root_container;
+
 #if !GLIB_CHECK_VERSION(2,35,0)
   g_type_init ();
 #endif
@@ -37,26 +43,26 @@ int main(int argc, char *argv[])
    */
 
   /* Call the plugin's module_init() to make it load itself: */
-  RygelPluginLoader* loader = rygel_plugin_loader_new ();
+  loader = rygel_plugin_loader_new ();
   g_assert (loader);
 
   module_init (loader);
 
   /* Get the loaded plugin: */
-  GeeCollection* list_plugins = rygel_plugin_loader_list_plugins (loader);
+  list_plugins = rygel_plugin_loader_list_plugins (loader);
   g_assert (list_plugins);
   g_assert (!gee_collection_get_is_empty (list_plugins));
   g_assert (gee_collection_get_size (list_plugins) == 1);
 
   /* Check the plugin: */
-  GeeIterator* iter = gee_iterable_iterator (GEE_ITERABLE (list_plugins));
+  iter = gee_iterable_iterator (GEE_ITERABLE (list_plugins));
   g_assert (gee_iterator_next (iter));
-  RygelMediaServerPlugin *plugin = gee_iterator_get (iter);
+  plugin = gee_iterator_get (iter);
   g_assert (plugin);
   g_assert (RYGEL_MEDIA_EXPORT_IS_PLUGIN (plugin));
 
   /* Check the plugin's root container: */
-  RygelMediaContainer *root_container = rygel_media_server_plugin_get_root_container (plugin);
+  root_container = rygel_media_server_plugin_get_root_container (plugin);
   g_assert (root_container);
   g_assert (RYGEL_MEDIA_EXPORT_IS_ROOT_CONTAINER (root_container) || RYGEL_MEDIA_EXPORT_IS_NULL_CONTAINER (root_container));
 



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]