From 923eb0aba2a083c59a67e79b98ddbe7001bf6d9c Mon Sep 17 00:00:00 2001
From: Manuel Bachmann <mbc@iot.bzh>
Date: Mon, 26 Oct 2015 03:33:24 +0000
Subject: [PATCH] Provide LightMediaScanner 0.5.1, Rygel LMS plugin

LightMediaScanner (https://github.com/profusion/
lightmediascanner) is a media indexation daemon, and a hard
dependency for GENIVI Media Manager *.

The Rygel media server, already present, uses a dedicated
plugin to collect media lists from LMS via D-Bus.

We are here :
- backporting a recipe recently submitted to the official
"meta-openembedded" layer :
http://lists.openembedded.org/pipermail/openembedded-devel/
2015-October/104022.html
- rebasing Tizen IVI patches, which have recently been
rebased on top of official Rygel code, on top of our own :
https://bugzilla.gnome.org/show_bug.cgi?id=757120

We can then pull Rygel LMS plugin and LightMediaScanner,
enabling only plugins associated with royalty-free formats.

* : https://github.com/konsulko/tizen-distro/blob/master/
meta-tizen/meta-open-ivi/recipes-apps/media-manager/
media-manager.bb

Change-Id: I42b375eb5c560daa1f8ea4052a782cdaac0cc1d6
Signed-off-by: Manuel Bachmann <mbc@iot.bzh>
---
 .../files/0001-Add-LightMediaScanner-plugin.patch  | 2541 ++++++
 .../rygel/files/0002-lms-add-C-source-files.patch  | 9455 ++++++++++++++++++++
 .../recipes-connectivity/rygel/rygel_%.bbappend    |   10 +-
 .../packagegroup-agl-ivi-connectivity.bb           |    1 +
 .../packagegroup-agl-ivi-multimedia.bb             |    1 +
 .../id3-plugin-support-out-of-tree-build.patch     |   11 +
 .../lightmediascanner/lightmediascanner_%.bbappend |    2 +
 .../lightmediascanner/lightmediascanner_0.5.1.bb   |   62 +
 8 files changed, 12081 insertions(+), 2 deletions(-)
 create mode 100644 meta-agl/recipes-connectivity/rygel/files/0001-Add-LightMediaScanner-plugin.patch
 create mode 100644 meta-agl/recipes-connectivity/rygel/files/0002-lms-add-C-source-files.patch
 create mode 100644 meta-agl/recipes-multimedia/lightmediascanner/files/id3-plugin-support-out-of-tree-build.patch
 create mode 100644 meta-agl/recipes-multimedia/lightmediascanner/lightmediascanner_%.bbappend
 create mode 100644 meta-agl/recipes-multimedia/lightmediascanner/lightmediascanner_0.5.1.bb

diff --git a/meta-agl/recipes-connectivity/rygel/files/0001-Add-LightMediaScanner-plugin.patch b/meta-agl/recipes-connectivity/rygel/files/0001-Add-LightMediaScanner-plugin.patch
new file mode 100644
index 000000000..eca08ee84
--- /dev/null
+++ b/meta-agl/recipes-connectivity/rygel/files/0001-Add-LightMediaScanner-plugin.patch
@@ -0,0 +1,2541 @@
+From 8bb9ae73464dd76f5fa94f2e9ba76b0bd88114df Mon Sep 17 00:00:00 2001
+From: Manuel Bachmann <manuel.bachmann@iot.bzh>
+Date: Mon, 26 Oct 2015 04:18:33 +0000
+Subject: [PATCH] Add LightMediaScanner plugin
+
+Add a new plugin based on LightMediaScanner :
+https://github.com/profusion/lightmediascanner
+
+Shorty put, this plugin does not do the indexing itself as
+"media-export" does, but defers this task to the
+"lightmediascannerd" daemon, with which it communicates
+via a D-Bus interface.
+The remote indexing daemon installs itself as a separate
+package, and is designed to be ultra-lightweight and fast.
+
+This commit is the rebase and fusion of all work done
+first on Maemo (lms.garage.maemo.org), then on Tizen IVI
+(review.tizen.org/git/?p=profile/ivi/rygel.git) and right
+now on AGL (automotivelinux.org) where several components
+depend on LightMediaScanner.
+A splitted version (13 commits) can also be seen on :
+https://github.com/Tarnyko/rygel
+
+It difffers mostly in that it lets "media-export" plugin
+as the default, just adding itself in "rygel.conf" as an
+alternative.
+
+(note : reporter is not code Author, see patch for details)
+(note 2 : rebased on top of 0.26.1)
+
+Author: Jussi Kukkonen <jussi.kukkonen@intel.com>
+Author: Alexander Kanavin <alex.kanavin@gmail.com>
+Signed-off-by: Manuel Bachmann <manuel.bachmann@iot.bzh>
+---
+ configure.ac                                      |   18 +
+ data/rygel.conf                                   |    6 +-
+ src/plugins/Makefile.am                           |    5 +
+ src/plugins/lms/Makefile.am                       |   46 +++
+ src/plugins/lms/README                            |   17 +
+ src/plugins/lms/lms.plugin.in                     |    7 +
+ src/plugins/lms/rygel-lms-album.vala              |  173 +++++++++
+ src/plugins/lms/rygel-lms-albums.vala             |  175 +++++++++
+ src/plugins/lms/rygel-lms-all-images.vala         |   95 +++++
+ src/plugins/lms/rygel-lms-all-music.vala          |  169 ++++++++
+ src/plugins/lms/rygel-lms-all-videos.vala         |  123 ++++++
+ src/plugins/lms/rygel-lms-artist.vala             |   75 ++++
+ src/plugins/lms/rygel-lms-artists.vala            |   62 +++
+ src/plugins/lms/rygel-lms-category-container.vala |  428 +++++++++++++++++++++
+ src/plugins/lms/rygel-lms-collate.c               |  49 +++
+ src/plugins/lms/rygel-lms-database.vala           |  294 ++++++++++++++
+ src/plugins/lms/rygel-lms-dbus-interfaces.vala    |   30 ++
+ src/plugins/lms/rygel-lms-image-root.vala         |   35 ++
+ src/plugins/lms/rygel-lms-image-year.vala         |  114 ++++++
+ src/plugins/lms/rygel-lms-image-years.vala        |   59 +++
+ src/plugins/lms/rygel-lms-music-root.vala         |   36 ++
+ src/plugins/lms/rygel-lms-plugin-factory.vala     |   40 ++
+ src/plugins/lms/rygel-lms-plugin.vala             |   35 ++
+ src/plugins/lms/rygel-lms-root-container.vala     |   58 +++
+ src/plugins/lms/rygel-lms-sql-function.vala       |   31 ++
+ src/plugins/lms/rygel-lms-sql-operator.vala       |   73 ++++
+ 26 files changed, 2252 insertions(+), 1 deletion(-)
+ create mode 100644 src/plugins/lms/Makefile.am
+ create mode 100644 src/plugins/lms/README
+ create mode 100644 src/plugins/lms/lms.plugin.in
+ create mode 100644 src/plugins/lms/rygel-lms-album.vala
+ create mode 100644 src/plugins/lms/rygel-lms-albums.vala
+ create mode 100644 src/plugins/lms/rygel-lms-all-images.vala
+ create mode 100644 src/plugins/lms/rygel-lms-all-music.vala
+ create mode 100644 src/plugins/lms/rygel-lms-all-videos.vala
+ create mode 100644 src/plugins/lms/rygel-lms-artist.vala
+ create mode 100644 src/plugins/lms/rygel-lms-artists.vala
+ create mode 100644 src/plugins/lms/rygel-lms-category-container.vala
+ create mode 100644 src/plugins/lms/rygel-lms-collate.c
+ create mode 100644 src/plugins/lms/rygel-lms-database.vala
+ create mode 100644 src/plugins/lms/rygel-lms-dbus-interfaces.vala
+ create mode 100644 src/plugins/lms/rygel-lms-image-root.vala
+ create mode 100644 src/plugins/lms/rygel-lms-image-year.vala
+ create mode 100644 src/plugins/lms/rygel-lms-image-years.vala
+ create mode 100644 src/plugins/lms/rygel-lms-music-root.vala
+ create mode 100644 src/plugins/lms/rygel-lms-plugin-factory.vala
+ create mode 100644 src/plugins/lms/rygel-lms-plugin.vala
+ create mode 100644 src/plugins/lms/rygel-lms-root-container.vala
+ create mode 100644 src/plugins/lms/rygel-lms-sql-function.vala
+ create mode 100644 src/plugins/lms/rygel-lms-sql-operator.vala
+
+diff --git a/configure.ac b/configure.ac
+index 7ae1105..275fd99 100644
+--- a/configure.ac
++++ b/configure.ac
+@@ -170,6 +170,18 @@ AS_IF([test "x$enable_ruih_plugin" = "xyes"],
+                        libxml-2.0 >= $LIBXML_REQUIRED])
+   ])
+ 
++
++RYGEL_ADD_PLUGIN([lms],[LightMediaScanner],[yes])
++AS_IF([test "x$enable_lms_plugin" = "xyes"],
++  [
++    PKG_CHECK_MODULES([RYGEL_PLUGIN_LMS_DEPS],
++                      [$RYGEL_COMMON_MODULES
++                       gio-2.0 >= $GIO_REQUIRED
++                       sqlite3 >= $LIBSQLITE3_REQUIRED])
++    RYGEL_PLUGIN_LMS_DEPS_VALAFLAGS="$RYGEL_COMMON_MODULES_VALAFLAGS --pkg gio-2.0 --pkg gee-0.8 --pkg sqlite3"
++    AC_SUBST([RYGEL_PLUGIN_LMS_DEPS_VALAFLAGS])
++  ])
++
+ AS_IF([test "x$with_media_engine" = "xgstreamer"],
+       [
+         RYGEL_ADD_PLUGIN([playbin],[GStreamer playbin],[yes])
+@@ -332,6 +344,11 @@ then
+     fi
+ fi
+ 
++dnl Check additional requirements for LMS plugin
++if test "x$enable_lms_plugin" = "xyes";
++then
++    RYGEL_CHECK_PACKAGES([sqlite3])
++fi
+ 
+ RYGEL_ADD_PLUGIN([tracker],[Tracker],[yes])
+ AS_IF([test "x$enable_tracker_plugin" = "xyes"],
+@@ -513,6 +530,7 @@ echo "
+             version:            ${tracker_api_version}
+         mediathek:              ${enable_mediathek_plugin}
+         media-export            ${enable_media_export_plugin}
++        lightmediascanner       ${enable_lms_plugin}
+         external:               ${enable_external_plugin}
+         MPRIS2:                 ${enable_mpris_plugin}
+         gst-launch:             ${enable_gst_launch_plugin}
+diff --git a/data/rygel.conf b/data/rygel.conf
+index 6b1c1c4..8677a0d 100644
+--- a/data/rygel.conf
++++ b/data/rygel.conf
+@@ -99,7 +99,7 @@ strict-sharing=false
+ title=@REALNAME@'s media on @PRETTY_HOSTNAME@
+ 
+ [MediaExport]
+-enabled=true
++enabled=false
+ title=@REALNAME@'s media on @PRETTY_HOSTNAME@
+ # List of URIs to export. Following variables are automatically substituted by
+ # the appropriate XDG standard media folders by Rygel for you.
+@@ -114,6 +114,10 @@ monitor-changes=true
+ monitor-grace-timeout=5
+ virtual-folders=true
+ 
++[LightMediaScanner]
++enabled=true
++title=My Media
++
+ [Playbin]
+ enabled=true
+ title=Audio/Video playback on @PRETTY_HOSTNAME@
+diff --git a/src/plugins/Makefile.am b/src/plugins/Makefile.am
+index d116f09..40791f0 100644
+--- a/src/plugins/Makefile.am
++++ b/src/plugins/Makefile.am
+@@ -10,6 +10,10 @@ if BUILD_MEDIA_EXPORT_PLUGIN
+ MEDIA_EXPORT_PLUGIN = media-export
+ endif
+ 
++if BUILD_LMS_PLUGIN
++LMS_PLUGIN = lms
++endif
++
+ if BUILD_EXTERNAL_PLUGIN
+ EXTERNAL_PLUGIN = external
+ endif
+@@ -33,6 +37,7 @@ endif
+ SUBDIRS = $(TRACKER_PLUGIN) \
+ 	  $(MEDIATHEK_PLUGIN) \
+ 	  $(MEDIA_EXPORT_PLUGIN) \
++	  $(LMS_PLUGIN) \
+ 	  $(EXTERNAL_PLUGIN) \
+ 	  $(MPRIS_PLUGIN) \
+ 	  $(GST_LAUNCH_PLUGIN) \
+diff --git a/src/plugins/lms/Makefile.am b/src/plugins/lms/Makefile.am
+new file mode 100644
+index 0000000..f96a2ab
+--- /dev/null
++++ b/src/plugins/lms/Makefile.am
+@@ -0,0 +1,46 @@
++include $(top_srcdir)/common.am
++
++plugin_LTLIBRARIES = librygel-lms.la
++plugin_DATA = lms.plugin
++
++librygel_lms_la_SOURCES = \
++	rygel-lms-plugin.vala \
++	rygel-lms-plugin-factory.vala \
++	rygel-lms-root-container.vala \
++	rygel-lms-music-root.vala \
++	rygel-lms-image-root.vala \
++	rygel-lms-category-container.vala \
++	rygel-lms-all-music.vala \
++	rygel-lms-album.vala \
++	rygel-lms-albums.vala \
++	rygel-lms-artist.vala \
++	rygel-lms-artists.vala \
++	rygel-lms-all-videos.vala \
++	rygel-lms-database.vala \
++	rygel-lms-all-images.vala \
++	rygel-lms-image-years.vala \
++	rygel-lms-image-year.vala \
++	rygel-lms-sql-function.vala \
++	rygel-lms-sql-operator.vala \
++	rygel-lms-collate.c \
++	rygel-lms-dbus-interfaces.vala
++
++librygel_lms_la_VALAFLAGS = \
++	--enable-experimental \
++	$(RYGEL_PLUGIN_LMS_DEPS_VALAFLAGS) \
++	$(RYGEL_COMMON_LIBRYGEL_SERVER_VALAFLAGS) \
++	$(RYGEL_COMMON_VALAFLAGS)
++
++librygel_lms_la_CFLAGS = \
++	$(RYGEL_PLUGIN_LMS_DEPS_CFLAGS) \
++	$(RYGEL_COMMON_LIBRYGEL_SERVER_CFLAGS) \
++	-DG_LOG_DOMAIN='"Lms"'
++
++librygel_lms_la_LIBADD = \
++	$(RYGEL_PLUGIN_LMS_DEPS_LIBS) \
++	$(RYGEL_COMMON_LIBRYGEL_SERVER_LIBS)
++
++librygel_lms_la_LDFLAGS = \
++	$(RYGEL_PLUGIN_LINKER_FLAGS)
++
++EXTRA_DIST = lms.plugin.in
+diff --git a/src/plugins/lms/README b/src/plugins/lms/README
+new file mode 100644
+index 0000000..b741806
+--- /dev/null
++++ b/src/plugins/lms/README
+@@ -0,0 +1,17 @@
++rygel-lms
++=========
++
++A rygel mediaserver plugin that exposes a lightmediascanner database
++as a Mediaserver.
++
++Configuration in rygel.conf:
++
++    [LightMediaScanner]
++    db-path=/path/to/lightmediascannerd.sqlite3
++    title=My Media
++
++* Supports browsing and searching (but in many cases searches will
++  still fall back to the inefficient simple_search()).
++* UpdateIDs are not yet supported as lightmediascanner seems to have
++  not change signal support yet
++* No real DLNA CTT testing has been done so far
+diff --git a/src/plugins/lms/lms.plugin.in b/src/plugins/lms/lms.plugin.in
+new file mode 100644
+index 0000000..9db9895
+--- /dev/null
++++ b/src/plugins/lms/lms.plugin.in
+@@ -0,0 +1,7 @@
++[Plugin]
++Version = @VERSION@
++Module = lms
++Name = LMS
++License = LGPL
++Description = LMS DMS plugin for Rygel
++Copyright = Copyright © Intel 
+diff --git a/src/plugins/lms/rygel-lms-album.vala b/src/plugins/lms/rygel-lms-album.vala
+new file mode 100644
+index 0000000..4fea17a
+--- /dev/null
++++ b/src/plugins/lms/rygel-lms-album.vala
+@@ -0,0 +1,173 @@
++/*
++ * Copyright (C) 2013 Intel Corporation.
++ *
++ * Author: Jussi Kukkonen <jussi.kukkonen@intel.com>
++ *
++ * 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.
++ */
++
++using Rygel;
++using Sqlite;
++
++public class Rygel.LMS.Album : Rygel.LMS.CategoryContainer {
++    private static const string SQL_ALL_TEMPLATE = 
++        "SELECT files.id, files.path, files.size, " +
++               "audios.title as title, audios.trackno, audios.length, audios.channels, audios.sampling_rate, audios.bitrate, audios.dlna_profile, audios.dlna_mime, " +
++               "audio_artists.name as artist, " +
++               "audio_albums.name " +
++        "FROM audios, files " +
++        "LEFT JOIN audio_artists " +
++        "ON audios.artist_id = audio_artists.id " +
++        "LEFT JOIN audio_albums " +
++        "ON audios.album_id = audio_albums.id " +
++        "WHERE dtime = 0 AND audios.id = files.id AND audios.album_id = %s " +
++        "LIMIT ? OFFSET ?;";
++
++    private static const string SQL_COUNT_TEMPLATE =
++        "SELECT COUNT(audios.id) " +
++        "FROM audios, files " +
++        "WHERE dtime = 0 AND audios.id = files.id AND audios.album_id = %s;";
++
++    private static const string SQL_COUNT_WITH_FILTER_TEMPLATE =
++        "SELECT COUNT(audios.id), audios.title as title, " +
++               "audio_artists.name as artist, " +
++               "audio_albums.name " +
++        "FROM audios, files " +
++        "LEFT JOIN audio_artists " +
++        "ON audios.artist_id = audio_artists.id " +
++        "LEFT JOIN audio_albums " +
++        "ON audios.album_id = audio_albums.id " +
++        "WHERE dtime = 0 AND audios.id = files.id AND audios.album_id = %s;";
++
++    private static const string SQL_FIND_OBJECT_TEMPLATE =
++        "SELECT files.id, files.path, files.size, " +
++               "audios.title, audios.trackno, audios.length, audios.channels, audios.sampling_rate, audios.bitrate, audios.dlna_profile, audios.dlna_mime, " + 
++               "audio_artists.name, " +
++               "audio_albums.name " +
++        "FROM audios, files " +
++        "LEFT JOIN audio_artists " +
++        "ON audios.artist_id = audio_artists.id " +
++        "LEFT JOIN audio_albums " +
++        "ON audios.album_id = audio_albums.id " +
++        "WHERE dtime = 0 AND files.id = ? AND audios.id = files.id AND audios.album_id = %s;";
++
++    private static const string SQL_ADDED_TEMPLATE =
++        "SELECT files.id, files.path, files.size, " +
++               "audios.title as title, audios.trackno, audios.length, audios.channels, audios.sampling_rate, audios.bitrate, audios.dlna_profile, audios.dlna_mime, " +
++               "audio_artists.name as artist, " +
++               "audio_albums.name " +
++        "FROM audios, files " +
++        "LEFT JOIN audio_artists " +
++        "ON audios.artist_id = audio_artists.id " +
++        "LEFT JOIN audio_albums " +
++        "ON audios.album_id = audio_albums.id " +
++        "WHERE dtime = 0 AND audios.id = files.id AND audios.album_id = %s " +
++        "AND update_id > ? AND update_id <= ?;";
++
++    private static const string SQL_REMOVED_TEMPLATE =
++        "SELECT files.id, files.path, files.size, " +
++               "audios.title as title, audios.trackno, audios.length, audios.channels, audios.sampling_rate, audios.bitrate, audios.dlna_profile, audios.dlna_mime, " +
++               "audio_artists.name as artist, " +
++               "audio_albums.name " +
++        "FROM audios, files " +
++        "LEFT JOIN audio_artists " +
++        "ON audios.artist_id = audio_artists.id " +
++        "LEFT JOIN audio_albums " +
++        "ON audios.album_id = audio_albums.id " +
++        "WHERE dtime <> 0 AND audios.id = files.id AND audios.album_id = %s " +
++        "AND update_id > ? AND update_id <= ?;";
++
++    protected override MediaObject? object_from_statement (Statement statement) {
++        var id = statement.column_int (0);
++        var path = statement.column_text (1);
++        var mime_type = statement.column_text(10);
++
++        if (mime_type == null || mime_type.length == 0) {
++            /* TODO is this correct? */
++            debug ("Music item %d (%s) has no MIME type",
++                   id,
++                   path);
++        }
++
++        var title = statement.column_text(3);
++        var song_id = this.build_child_id (id);
++        var song = new MusicItem (song_id, this, title);
++        song.ref_id = this.build_reference_id (id);
++        song.size = statement.column_int(2);
++        song.track_number = statement.column_int(4);
++        song.duration = statement.column_int(5);
++        song.channels = statement.column_int(6);
++        song.sample_freq = statement.column_int(7); 
++        song.bitrate = statement.column_int(8);
++        song.dlna_profile = statement.column_text(9);
++        song.mime_type = mime_type;
++        song.artist = statement.column_text(11);
++        song.album = statement.column_text(12);
++        File file = File.new_for_path (path);
++        song.add_uri (file.get_uri ());
++
++        return song;
++    }
++
++    private static string get_sql_all (string db_id) {
++        return (SQL_ALL_TEMPLATE.printf (db_id));
++    }
++    private static string get_sql_find_object (string db_id) {
++        return (SQL_FIND_OBJECT_TEMPLATE.printf (db_id));
++    }
++    private static string get_sql_count (string db_id) {
++        return (SQL_COUNT_TEMPLATE.printf (db_id));
++    }
++    private static string get_sql_added (string db_id) {
++        return (SQL_ADDED_TEMPLATE.printf (db_id));
++    }
++    private static string get_sql_removed (string db_id) {
++        return (SQL_REMOVED_TEMPLATE.printf (db_id));
++    }
++
++    protected override string get_sql_all_with_filter (string filter) {
++        if (filter.length == 0) {
++            return this.sql_all;
++        }
++        var filter_str = "%s AND %s".printf (this.db_id, filter);
++        return (SQL_ALL_TEMPLATE.printf (filter_str));
++    }
++
++    protected override string get_sql_count_with_filter (string filter) {
++        if (filter.length == 0) {
++            return this.sql_count;
++        }
++        var filter_str = "%s AND %s".printf (this.db_id, filter);
++        return (SQL_COUNT_WITH_FILTER_TEMPLATE.printf (filter_str));
++    }
++
++    public Album (string         db_id,
++                  MediaContainer parent,
++                  string         title,
++                  LMS.Database   lms_db) {
++        base (db_id,
++              parent,
++              title,
++              lms_db,
++              get_sql_all (db_id),
++              get_sql_find_object (db_id),
++              get_sql_count (db_id),
++              get_sql_added (db_id),
++              get_sql_removed (db_id)
++             );
++    }
++}
+diff --git a/src/plugins/lms/rygel-lms-albums.vala b/src/plugins/lms/rygel-lms-albums.vala
+new file mode 100644
+index 0000000..309a352
+--- /dev/null
++++ b/src/plugins/lms/rygel-lms-albums.vala
+@@ -0,0 +1,175 @@
++/*
++ * Copyright (C) 2013 Intel Corporation.
++ *
++ * Author: Jussi Kukkonen <jussi.kukkonen@intel.com>
++ *
++ * 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.
++ */
++
++using Rygel;
++using Sqlite;
++
++public class Rygel.LMS.Albums : Rygel.LMS.CategoryContainer {
++    private static const string SQL_ALL =
++        "SELECT audio_albums.id, audio_albums.name as title, " +
++               "audio_artists.name as artist " +
++        "FROM audio_albums " +
++        "LEFT JOIN audio_artists " +
++        "ON audio_albums.artist_id = audio_artists.id " +
++        "LIMIT ? OFFSET ?;";
++
++    private static const string SQL_ALL_WITH_FILTER_TEMPLATE =
++        "SELECT audio_albums.id, audio_albums.name as title, " +
++               "audio_artists.name as artist " +
++        "FROM audio_albums " +
++        "LEFT JOIN audio_artists " +
++        "ON audio_albums.artist_id = audio_artists.id " +
++        "WHERE %s " +
++        "LIMIT ? OFFSET ?;";
++
++    private static const string SQL_COUNT =
++        "SELECT COUNT(audio_albums.id) " +
++        "FROM audio_albums;";
++
++    private static const string SQL_COUNT_WITH_FILTER_TEMPLATE =
++        "SELECT COUNT(audio_albums.id), audio_albums.name as title, " +
++               "audio_artists.name as artist " +
++        "FROM audio_albums " +
++        "LEFT JOIN audio_artists " +
++        "ON audio_albums.artist_id = audio_artists.id " +
++        "WHERE %s;";
++
++    /* count songs inside albums */
++    private static const string SQL_CHILD_COUNT_WITH_FILTER_TEMPLATE =
++        "SELECT COUNT(audios.id), audios.title as title, " +
++               "audio_artists.name as artist " +
++        "FROM audios, files, audio_albums " +
++        "LEFT JOIN audio_artists " +
++        "ON audios.artist_id = audio_artists.id " +
++        "WHERE dtime = 0 AND audios.id = files.id AND audios.album_id = audio_albums.id %s;";
++
++    /* select songs inside albums */
++    private static const string SQL_CHILD_ALL_WITH_FILTER_TEMPLATE =
++        "SELECT files.id, files.path, files.size, " +
++               "audios.title as title, audios.trackno, audios.length, audios.channels, audios.sampling_rate, audios.bitrate, audios.dlna_profile, audios.dlna_mime, " +
++               "audio_artists.name as artist, " +
++               "audio_albums.name, audio_albums.id " +
++        "FROM audios, files, audio_albums " +
++        "LEFT JOIN audio_artists " +
++        "ON audios.artist_id = audio_artists.id " +
++        "WHERE dtime = 0 AND audios.id = files.id AND audios.album_id = audio_albums.id %s " +
++        "LIMIT ? OFFSET ?;";
++
++
++    private static const string SQL_FIND_OBJECT =
++        "SELECT audio_albums.id, audio_albums.name " +
++        "FROM audio_albums " +
++        "WHERE audio_albums.id = ?;";
++
++    protected override string get_sql_all_with_filter (string filter) {
++        if (filter.length == 0) {
++            return Albums.SQL_ALL;
++        }
++        return (Albums.SQL_ALL_WITH_FILTER_TEMPLATE.printf (filter));
++    }
++
++    protected override string get_sql_count_with_filter (string filter) {
++        if (filter.length == 0) {
++            return Albums.SQL_COUNT;
++        }
++        return (Albums.SQL_COUNT_WITH_FILTER_TEMPLATE.printf (filter));
++    }
++
++    protected override uint get_child_count_with_filter (string     where_filter,
++                                                        ValueArray args)
++    {
++
++        /* search the children (albums) as usual */
++        var count = base.get_child_count_with_filter (where_filter, args);
++
++        /* now search the album contents */
++        var filter = "";
++        if (where_filter.length > 0) {
++            filter = "AND %s".printf (where_filter);
++        }
++        var query = Albums.SQL_CHILD_COUNT_WITH_FILTER_TEMPLATE.printf (filter);
++        try {
++            var stmt = this.lms_db.prepare_and_init (query, args.values);
++            if (stmt.step () == Sqlite.ROW) {
++                count += stmt.column_int (0);
++            }
++        } catch (DatabaseError e) {
++            warning ("Query failed: %s", e.message);
++        }
++
++        return count;
++    }
++
++    protected override MediaObjects? get_children_with_filter (string     where_filter,
++                                                               ValueArray args,
++                                                               string     sort_criteria,
++                                                               uint       offset,
++                                                               uint       max_count) {
++        var children = base. get_children_with_filter (where_filter,
++                                                       args,
++                                                       sort_criteria,
++                                                       offset,
++                                                       max_count);
++        var filter = "";
++        if (where_filter.length > 0) {
++            filter = "AND %s".printf (where_filter);
++        }
++        var query = Albums.SQL_CHILD_ALL_WITH_FILTER_TEMPLATE.printf (filter);
++        try {
++            var stmt = this.lms_db.prepare_and_init (query, args.values);
++            while (Database.get_children_step (stmt)) {
++                var album_id = stmt.column_text (13);
++                var album = new Album (album_id, this, "", this.lms_db);
++
++                var song = album.object_from_statement (stmt);
++                song.parent_ref = song.parent;
++                children.add (song);
++                
++            }
++        } catch (DatabaseError e) {
++            warning ("Query failed: %s", e.message);
++        }
++
++        return children;
++    }
++
++    protected override MediaObject? object_from_statement (Statement statement) {
++        var id = "%d".printf (statement.column_int (0));
++        LMS.Album album = new LMS.Album (id,
++                                         this,
++                                         statement.column_text (1),
++                                         this.lms_db);
++        return album;
++    }
++
++    public Albums (MediaContainer parent,
++                   LMS.Database   lms_db) {
++        base ("albums",
++              parent,
++              _("Albums"),
++              lms_db,
++              Albums.SQL_ALL,
++              Albums.SQL_FIND_OBJECT,
++              Albums.SQL_COUNT,
++              null, null);
++    }
++}
+diff --git a/src/plugins/lms/rygel-lms-all-images.vala b/src/plugins/lms/rygel-lms-all-images.vala
+new file mode 100644
+index 0000000..0b54c7f
+--- /dev/null
++++ b/src/plugins/lms/rygel-lms-all-images.vala
+@@ -0,0 +1,95 @@
++/*
++ * Copyright (C) 2013 Intel Corporation.
++ *
++ * Author: Jussi Kukkonen <jussi.kukkonen@intel.com>
++ *
++ * 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.
++ */
++
++using Rygel;
++using Sqlite;
++
++public class Rygel.LMS.AllImages : Rygel.LMS.CategoryContainer {
++    private static const string SQL_ALL =
++        "SELECT images.id, title, artist, date, width, height, path, size, dlna_profile, dlna_mime " +
++        "FROM images, files " +
++        "WHERE dtime = 0 AND images.id = files.id " +
++        "LIMIT ? OFFSET ?;";
++
++    private static const string SQL_COUNT =
++        "SELECT count(images.id) " +
++        "FROM images, files " +
++        "WHERE dtime = 0 AND images.id = files.id;";
++
++    private static const string SQL_FIND_OBJECT =
++        "SELECT images.id, title, artist, date, width, height, path, size, dlna_profile, dlna_mime " +
++        "FROM images, files " +
++        "WHERE dtime = 0 AND files.id = ? AND images.id = files.id;";
++
++    private static const string SQL_ADDED =
++        "SELECT images.id, title, artist, date, width, height, path, size, dlna_profile, dlna_mime " +
++        "FROM images, files " +
++        "WHERE dtime = 0 AND images.id = files.id " +
++        "AND update_id > ? AND update_id <= ?;";
++
++    private static const string SQL_REMOVED =
++        "SELECT images.id, title, artist, date, width, height, path, size, dlna_profile, dlna_mime " +
++        "FROM images, files " +
++        "WHERE dtime <> 0 AND images.id = files.id " +
++        "AND update_id > ? AND update_id <= ?;";
++
++    protected override MediaObject? object_from_statement (Statement statement) {
++        var id = statement.column_int(0);
++        var path = statement.column_text(6);
++        var mime_type = statement.column_text(9);
++
++        if (mime_type == null || mime_type.length == 0){
++            /* TODO is this correct? */
++            debug ("Image item %d (%s) has no MIME type",
++                   id,
++                   path);
++        }
++
++        var title = statement.column_text(1);
++        var image = new ImageItem(this.build_child_id (id), this, title);
++        image.creator = statement.column_text(2);
++        TimeVal tv = { (long) statement.column_int(3), (long) 0 };
++        image.date = tv.to_iso8601 ();
++        image.width = statement.column_int(4);
++        image.height = statement.column_int(5);
++        image.size = statement.column_int(7);
++        image.mime_type = mime_type;
++        image.dlna_profile = statement.column_text(8);
++        File file = File.new_for_path(path);
++        image.add_uri (file.get_uri ());
++
++        return image;
++    }
++
++    public AllImages (MediaContainer parent, LMS.Database lms_db) {
++        base ("all",
++              parent,
++              _("All"),
++              lms_db,
++              AllImages.SQL_ALL,
++              AllImages.SQL_FIND_OBJECT,
++              AllImages.SQL_COUNT,
++              AllImages.SQL_ADDED,
++              AllImages.SQL_REMOVED
++             );
++    }
++}
+diff --git a/src/plugins/lms/rygel-lms-all-music.vala b/src/plugins/lms/rygel-lms-all-music.vala
+new file mode 100644
+index 0000000..2a7226f
+--- /dev/null
++++ b/src/plugins/lms/rygel-lms-all-music.vala
+@@ -0,0 +1,169 @@
++/*
++ * Copyright (C) 2013 Intel Corporation.
++ *
++ * Author: Jussi Kukkonen <jussi.kukkonen@intel.com>
++ *
++ * 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.
++ */
++
++using Rygel;
++using Sqlite;
++
++public class Rygel.LMS.AllMusic : Rygel.LMS.CategoryContainer {
++    private static const string SQL_ALL_TEMPLATE =
++        "SELECT files.id, files.path, files.size, " +
++               "audios.title as title, audios.trackno, audios.length, audios.channels, audios.sampling_rate, audios.bitrate, audios.dlna_profile, audios.dlna_mime, " +
++               "audio_artists.name as artist, " +
++               "audio_albums.name, " +
++               "files.mtime, " +
++               "audio_genres.name " +
++        "FROM audios, files " +
++        "LEFT JOIN audio_artists " +
++        "ON audios.artist_id = audio_artists.id " +
++        "LEFT JOIN audio_albums " +
++        "ON audios.album_id = audio_albums.id " +
++        "LEFT JOIN audio_genres " +
++        "ON audios.genre_id = audio_genres.id " +
++        "WHERE dtime = 0 AND audios.id = files.id %s " +
++        "LIMIT ? OFFSET ?;";
++
++    private static const string SQL_COUNT =
++        "SELECT COUNT(audios.id) " +
++        "FROM audios, files " +
++        "WHERE dtime = 0 AND audios.id = files.id;";
++
++    private static const string SQL_COUNT_WITH_FILTER_TEMPLATE =
++        "SELECT COUNT(audios.id), audios.title as title, " +
++               "audio_artists.name as artist " +
++        "FROM audios, files " +
++        "LEFT JOIN audio_artists " +
++        "ON audios.artist_id = audio_artists.id " +
++        "WHERE dtime = 0 AND audios.id = files.id %s;";
++
++    private static const string SQL_FIND_OBJECT =
++        "SELECT files.id, files.path, files.size, " +
++               "audios.title, audios.trackno, audios.length, audios.channels, audios.sampling_rate, audios.bitrate, audios.dlna_profile, audios.dlna_mime, " + 
++               "audio_artists.name, " +
++               "audio_albums.name, " +
++               "files.mtime, " +
++               "audio_genres.name " +
++        "FROM audios, files " +
++        "LEFT JOIN audio_artists " +
++        "ON audios.artist_id = audio_artists.id " +
++        "LEFT JOIN audio_albums " +
++        "ON audios.album_id = audio_albums.id " +
++        "LEFT JOIN audio_genres " +
++        "ON audios.genre_id = audio_genres.id " +
++        "WHERE dtime = 0 AND files.id = ? AND audios.id = files.id;";
++
++    private static const string SQL_ADDED =
++        "SELECT files.id, files.path, files.size, " +
++               "audios.title as title, audios.trackno, audios.length, audios.channels, audios.sampling_rate, audios.bitrate, audios.dlna_profile, audios.dlna_mime, " +
++               "audio_artists.name as artist, " +
++               "audio_albums.name, " +
++               "files.mtime, " +
++               "audio_genres.name " +
++        "FROM audios, files " +
++        "LEFT JOIN audio_artists " +
++        "ON audios.artist_id = audio_artists.id " +
++        "LEFT JOIN audio_albums " +
++        "ON audios.album_id = audio_albums.id " +
++        "LEFT JOIN audio_genres " +
++        "ON audios.genre_id = audio_genres.id " +
++        "WHERE dtime = 0 AND audios.id = files.id " +
++        "AND update_id > ? AND update_id <= ?;";
++
++    private static const string SQL_REMOVED =
++        "SELECT files.id, files.path, files.size, " +
++               "audios.title as title, audios.trackno, audios.length, audios.channels, audios.sampling_rate, audios.bitrate, audios.dlna_profile, audios.dlna_mime, " +
++               "audio_artists.name as artist, " +
++               "audio_albums.name, " +
++               "files.mtime, " +
++               "audio_genres.name " +
++        "FROM audios, files " +
++        "LEFT JOIN audio_artists " +
++        "ON audios.artist_id = audio_artists.id " +
++        "LEFT JOIN audio_albums " +
++        "ON audios.album_id = audio_albums.id " +
++        "LEFT JOIN audio_genres " +
++        "ON audios.genre_id = audio_genres.id " +
++        "WHERE dtime <> 0 AND audios.id = files.id " +
++        "AND update_id > ? AND update_id <= ?;";
++
++    protected override string get_sql_all_with_filter (string filter) {
++        if (filter.length == 0) {
++            return this.sql_all;
++        }
++        var filter_str = "AND %s".printf (filter);
++        return (AllMusic.SQL_ALL_TEMPLATE.printf (filter_str));
++    }
++
++    protected override string get_sql_count_with_filter (string filter) {
++        if (filter.length == 0) {
++            return this.sql_count;
++        }
++        var filter_str = "AND %s".printf (filter);
++        return (AllMusic.SQL_COUNT_WITH_FILTER_TEMPLATE.printf (filter_str));
++    }
++
++    protected override MediaObject? object_from_statement (Statement statement) {
++        var id = statement.column_int (0);
++        var path = statement.column_text (1);
++        var mime_type = statement.column_text(10);
++
++        if (mime_type == null || mime_type.length == 0) {
++            /* TODO is this correct? */
++            debug ("Music item %d (%s) has no MIME type",
++                   id,
++                   path);
++        }
++
++        var title = statement.column_text(3);
++        var song_id = this.build_child_id (id);
++        var song = new MusicItem (song_id, this, title);
++        song.size = statement.column_int(2);
++        song.track_number = statement.column_int(4);
++        song.duration = statement.column_int(5);
++        song.channels = statement.column_int(6);
++        song.sample_freq = statement.column_int(7); 
++        song.bitrate = statement.column_int(8);
++        song.dlna_profile = statement.column_text(9);
++        song.mime_type = mime_type;
++        song.artist = statement.column_text(11);
++        song.album = statement.column_text(12);
++        TimeVal tv = { (long) statement.column_int(13), (long) 0 };
++        song.date = tv.to_iso8601 ();
++        song.genre = statement.column_text(14);
++        File file = File.new_for_path (path);
++        song.add_uri (file.get_uri ());
++
++        return song;
++    }
++
++    public AllMusic (MediaContainer parent, LMS.Database lms_db) {
++        base("all",
++             parent,
++             _("All"),
++             lms_db,
++             AllMusic.SQL_ALL_TEMPLATE.printf (""),
++             AllMusic.SQL_FIND_OBJECT,
++             AllMusic.SQL_COUNT,
++             AllMusic.SQL_ADDED,
++             AllMusic.SQL_REMOVED
++            );
++    }
++}
+diff --git a/src/plugins/lms/rygel-lms-all-videos.vala b/src/plugins/lms/rygel-lms-all-videos.vala
+new file mode 100644
+index 0000000..dbde0db
+--- /dev/null
++++ b/src/plugins/lms/rygel-lms-all-videos.vala
+@@ -0,0 +1,123 @@
++/*
++ * Copyright (C) 2013 Intel Corporation.
++ *
++ * Author: Jussi Kukkonen <jussi.kukkonen@intel.com>
++ *
++ * 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.
++ */
++
++using Rygel;
++using Sqlite;
++
++public class Rygel.LMS.AllVideos : Rygel.LMS.CategoryContainer {
++    private static const string SQL_ALL =
++        "SELECT videos.id, title, artist, length, path, mtime, size, dlna_profile, dlna_mime " +
++        "FROM videos, files " +
++        "WHERE dtime = 0 AND videos.id = files.id " +
++        "LIMIT ? OFFSET ?;";
++
++   private static const string SQL_COUNT =
++        "SELECT count(videos.id) " +
++        "FROM videos, files " +
++        "WHERE dtime = 0 AND videos.id = files.id;";
++
++    private static const string SQL_FIND_OBJECT =
++        "SELECT videos.id, title, artist, length, path, mtime, size, dlna_profile, dlna_mime " +
++        "FROM videos, files " +
++        "WHERE dtime = 0 AND files.id = ? AND videos.id = files.id;";
++
++    private static const string SQL_ADDED =
++        "SELECT videos.id, title, artist, length, path, mtime, size, dlna_profile, dlna_mime " +
++        "FROM videos, files " +
++        "WHERE dtime = 0 AND videos.id = files.id " +
++        "AND update_id > ? AND update_id <= ?;";
++
++    private static const string SQL_REMOVED =
++        "SELECT videos.id, title, artist, length, path, mtime, size, dlna_profile, dlna_mime " +
++        "FROM videos, files " +
++        "WHERE dtime <> 0 AND videos.id = files.id " +
++        "AND update_id > ? AND update_id <= ?;";
++
++    protected override MediaObject? object_from_statement (Statement statement) {
++        var id = statement.column_int(0);
++        var mime_type = statement.column_text(8);
++        var path = statement.column_text(4);
++        var file = File.new_for_path(path);
++
++        /* TODO: Temporary code to extract the MIME TYPE.  LMS does not seem
++           to compute the mime type of videos.  Don't know why. */
++
++/*        if (mime_type == null || mime_type.length == 0) {
++            try {
++                FileInfo info = file.query_info(FileAttribute.STANDARD_CONTENT_TYPE,
++                                                FileQueryInfoFlags.NONE, null);
++                mime_type = info.get_content_type();
++            } catch {}
++        }
++*/
++
++        if (mime_type == null || mime_type.length == 0) {
++            /* TODO is this correct? */
++            debug ("Video item %d (%s) has no MIME type",
++                   id,
++                   path);
++            }
++
++        var title = statement.column_text(1);
++        var video = new VideoItem(this.build_child_id (id), this, title);
++        video.creator = statement.column_text(2);
++        video.duration = statement.column_int(3);
++        TimeVal tv = { (long) statement.column_int(5), (long) 0 };
++        video.date = tv.to_iso8601 ();
++        video.size = statement.column_int(6);
++        video.dlna_profile = statement.column_text(7);
++        video.mime_type = mime_type;
++        video.add_uri (file.get_uri ());
++
++        // Rygel does not support multiple video and audio tracks in a single file,
++        // so we just take the first one
++        var video_data = "select videos_videos.bitrate + videos_audios.bitrate, width, height, channels, sampling_rate " +
++            "from videos, videos_audios, videos_videos where videos.id = ? " +
++            "and videos.id = videos_audios.video_id and videos.id = videos_videos.video_id;";
++        try {
++            var stmt = this.lms_db.prepare(video_data);
++            Rygel.LMS.Database.find_object("%d".printf(id), stmt);
++            video.bitrate = stmt.column_int(0) / 8; //convert bits per second into bytes per second
++            video.width = stmt.column_int(1);
++            video.height = stmt.column_int(2);
++            video.channels = stmt.column_int(3);
++            video.sample_freq = stmt.column_int(4);
++        } catch (DatabaseError e) {
++            warning ("Query failed: %s", e.message);
++        }
++
++        return video;
++    }
++
++    public AllVideos (string id, MediaContainer parent, string title, LMS.Database lms_db){
++        base (id,
++              parent,
++              title,
++              lms_db,
++              AllVideos.SQL_ALL,
++              AllVideos.SQL_FIND_OBJECT,
++              AllVideos.SQL_COUNT,
++              AllVideos.SQL_ADDED,
++              AllVideos.SQL_REMOVED
++             );
++    }
++}
+diff --git a/src/plugins/lms/rygel-lms-artist.vala b/src/plugins/lms/rygel-lms-artist.vala
+new file mode 100644
+index 0000000..31e9070
+--- /dev/null
++++ b/src/plugins/lms/rygel-lms-artist.vala
+@@ -0,0 +1,75 @@
++/*
++ * Copyright (C) 2013 Intel Corporation.
++ *
++ * Author: Jussi Kukkonen <jussi.kukkonen@intel.com>
++ *
++ * 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.
++ */
++
++using Rygel;
++using Sqlite;
++
++public class Rygel.LMS.Artist : Rygel.LMS.CategoryContainer {
++    private static const string SQL_ALL_TEMPLATE =
++        "SELECT audio_albums.id, audio_albums.name " +
++        "FROM audio_albums " +
++        "WHERE audio_albums.artist_id = %s " +
++        "LIMIT ? OFFSET ?;";
++
++    private static const string SQL_COUNT_TEMPLATE =
++        "SELECT COUNT(audio_albums.id) " +
++        "FROM audio_albums " +
++        "WHERE audio_albums.artist_id = %s";
++
++    private static const string SQL_FIND_OBJECT_TEMPLATE =
++        "SELECT audio_albums.id, audio_albums.name " +
++        "FROM audio_albums " +
++        "WHERE audio_albums.id = ? AND audio_albums.artist_id = %s;";
++
++    private static string get_sql_all (string id) {
++        return (SQL_ALL_TEMPLATE.printf (id));
++    }
++    private static string get_sql_find_object (string id) {
++        return (SQL_FIND_OBJECT_TEMPLATE.printf (id));
++    }
++    private static string get_sql_count (string id) {
++        return (SQL_COUNT_TEMPLATE.printf (id));
++    }
++
++    protected override MediaObject? object_from_statement (Statement statement) {
++        var db_id = "%d".printf (statement.column_int (0));
++        var title = statement.column_text (1);
++        return new LMS.Album (db_id, this, title, this.lms_db);
++    }
++
++    public Artist (string         id,
++                   MediaContainer parent,
++                   string         title,
++                   LMS.Database   lms_db) {
++
++        base (id,
++              parent,
++              title,
++              lms_db,
++              get_sql_all (id),
++              get_sql_find_object (id),
++              get_sql_count (id),
++              null, // LMS does not track adding or removing albums
++              null
++             );
++    }
++}
+diff --git a/src/plugins/lms/rygel-lms-artists.vala b/src/plugins/lms/rygel-lms-artists.vala
+new file mode 100644
+index 0000000..a00b2ce
+--- /dev/null
++++ b/src/plugins/lms/rygel-lms-artists.vala
+@@ -0,0 +1,62 @@
++/*
++ * Copyright (C) 2013 Intel Corporation.
++ *
++ * Author: Jussi Kukkonen <jussi.kukkonen@intel.com>
++ *
++ * 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.
++ */
++
++using Rygel;
++using Sqlite;
++
++public class Rygel.LMS.Artists : Rygel.LMS.CategoryContainer {
++    private static const string SQL_ALL =
++        "SELECT audio_artists.id, audio_artists.name " +
++        "FROM audio_artists " +
++        "LIMIT ? OFFSET ?;";
++
++    private static const string SQL_COUNT =
++        "SELECT COUNT(audio_artists.id) " +
++        "FROM audio_artists;";
++
++    private static const string SQL_FIND_OBJECT =
++        "SELECT audio_artists.id, audio_artists.name " +
++        "FROM audio_artists " +
++        "WHERE audio_artists.id = ?;";
++
++    protected override MediaObject? object_from_statement (Statement statement) {
++        var db_id = "%d".printf (statement.column_int (0));
++        var title = statement.column_text (1);
++
++        return new LMS.Artist (db_id, this, title, this.lms_db);
++    }
++
++    public Artists (string id,
++                    MediaContainer parent,
++                    string title,
++                    LMS.Database   lms_db) {
++        base (id,
++              parent,
++              title,
++              lms_db,
++              Artists.SQL_ALL,
++              Artists.SQL_FIND_OBJECT,
++              Artists.SQL_COUNT,
++              null, null
++             );
++    }
++}
+diff --git a/src/plugins/lms/rygel-lms-category-container.vala b/src/plugins/lms/rygel-lms-category-container.vala
+new file mode 100644
+index 0000000..e5430d1
+--- /dev/null
++++ b/src/plugins/lms/rygel-lms-category-container.vala
+@@ -0,0 +1,428 @@
++/*
++ * Copyright (C) 2009,2010 Jens Georg <mail@jensge.org>,
++ *           (C) 2013 Intel Corporation.
++ *
++ * Author: Jussi Kukkonen <jussi.kukkonen@intel.com>
++ *
++ * 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.
++ */
++
++using Rygel;
++using Gee;
++using Sqlite;
++
++public errordomain Rygel.LMS.CategoryContainerError {
++    SQLITE_ERROR,
++    GENERAL_ERROR,
++    INVALID_TYPE,
++    UNSUPPORTED_SEARCH
++}
++
++public abstract class Rygel.LMS.CategoryContainer : Rygel.MediaContainer,
++                                                    Rygel.TrackableContainer,
++                                                    Rygel.SearchableContainer {
++    public ArrayList<string> search_classes { get; set; }
++
++    public unowned LMS.Database lms_db { get; construct; }
++
++    public string db_id { get; construct; }
++
++    public string sql_all { get; construct; }
++    public string sql_find_object { get; construct; }
++    public string sql_count { get; construct; }
++    public string sql_added { get; construct; }
++    public string sql_removed { get; construct; }
++
++    protected Statement stmt_all;
++    protected Statement stmt_find_object;
++    protected Statement stmt_added;
++    protected Statement stmt_removed;
++
++    protected string child_prefix;
++    protected string ref_prefix;
++
++    protected abstract MediaObject? object_from_statement (Statement statement);
++
++    /* TODO these should be abstract */
++    protected virtual string get_sql_all_with_filter (string filter) {
++        return this.sql_all;
++    }
++    protected virtual string get_sql_count_with_filter (string filter) {
++        return this.sql_count;
++    }
++
++    private static string? map_operand_to_column (string     operand,
++                                                  out string? collate = null,
++                                                  bool        for_sort = false)
++                                                  throws Error {
++        string column = null;
++        bool use_collation = false;
++
++        // TODO add all used aliases to sql queries
++        switch (operand) {
++            case "dc:title":
++                column = "title";
++                use_collation = true;
++                break;
++            case "upnp:artist":
++                column = "artist";
++                use_collation = true;
++                break;
++            case "dc:creator":
++                column = "creator";
++                use_collation = true;
++                break;
++            default:
++                var message = "Unsupported column %s".printf (operand);
++
++                throw new CategoryContainerError.UNSUPPORTED_SEARCH (message);
++        }
++
++        if (use_collation) {
++            collate = "COLLATE CASEFOLD";
++        } else {
++            collate = "";
++        }
++
++        return column;
++    }
++
++    private static string? relational_expression_to_sql
++                                        (RelationalExpression exp,
++                                         GLib.ValueArray      args)
++                                         throws Error {
++        GLib.Value? v = null;
++        string collate = null;
++
++        string column = CategoryContainer.map_operand_to_column (exp.operand1,
++                                                                 out collate);
++        SqlOperator operator;
++
++        switch (exp.op) {
++            case GUPnP.SearchCriteriaOp.EXISTS:
++                string sql_function;
++                if (exp.operand2 == "true") {
++                    sql_function = "%s IS NOT NULL AND %s != ''";
++                } else {
++                    sql_function = "%s IS NULL OR %s = ''";
++                }
++
++                return sql_function.printf (column, column);
++            case GUPnP.SearchCriteriaOp.EQ:
++            case GUPnP.SearchCriteriaOp.NEQ:
++            case GUPnP.SearchCriteriaOp.LESS:
++            case GUPnP.SearchCriteriaOp.LEQ:
++            case GUPnP.SearchCriteriaOp.GREATER:
++            case GUPnP.SearchCriteriaOp.GEQ:
++                v = exp.operand2;
++                operator = new SqlOperator.from_search_criteria_op
++                                            (exp.op, column, collate);
++                break;
++            case GUPnP.SearchCriteriaOp.CONTAINS:
++                operator = new SqlFunction ("contains", column);
++                v = exp.operand2;
++                break;
++            case GUPnP.SearchCriteriaOp.DOES_NOT_CONTAIN:
++                operator = new SqlFunction ("NOT contains", column);
++                v = exp.operand2;
++                break;
++            case GUPnP.SearchCriteriaOp.DERIVED_FROM:
++                operator = new SqlOperator ("LIKE", column);
++                v = "%s%%".printf (exp.operand2);
++                break;
++            default:
++                warning ("Unsupported op %d", exp.op);
++                return null;
++        }
++
++        if (v != null) {
++            args.append (v);
++        }
++
++        return operator.to_string ();
++    }
++
++    private static string logical_expression_to_sql
++                                        (LogicalExpression expression,
++                                         GLib.ValueArray   args)
++                                         throws Error {
++        string left_sql_string = CategoryContainer.search_expression_to_sql
++                                        (expression.operand1,
++                                         args);
++        string right_sql_string = CategoryContainer.search_expression_to_sql
++                                        (expression.operand2,
++                                         args);
++        unowned string operator_sql_string = "OR";
++
++        if (expression.op == LogicalOperator.AND) {
++            operator_sql_string = "AND";
++        }
++
++        return "(%s %s %s)".printf (left_sql_string,
++                                    operator_sql_string,
++                                    right_sql_string);
++    }
++
++    private static string? search_expression_to_sql
++                                        (SearchExpression? expression,
++                                         GLib.ValueArray   args)
++                                         throws Error {
++        if (expression == null) {
++            return "";
++        }
++
++        if (expression is LogicalExpression) {
++            return CategoryContainer.logical_expression_to_sql
++                                        (expression as LogicalExpression, args);
++        } else {
++            return CategoryContainer.relational_expression_to_sql
++                                        (expression as RelationalExpression,
++                                         args);
++        }
++    }
++
++    protected virtual uint get_child_count_with_filter (string     where_filter,
++                                                        ValueArray args)
++    {
++        var query = this.get_sql_count_with_filter (where_filter);
++        try {
++            var stmt = this.lms_db.prepare_and_init (query, args.values);
++            if (stmt.step () != Sqlite.ROW) {
++                return 0;
++            }
++            return stmt.column_int (0);
++        } catch (DatabaseError e) {
++            warning ("Query failed: %s", e.message);
++            return 0;
++        }
++    }
++
++    protected virtual MediaObjects? get_children_with_filter (string     where_filter,
++                                                              ValueArray args,
++                                                              string     sort_criteria,
++                                                              uint       offset,
++                                                              uint       max_count) {
++        var children = new MediaObjects ();
++        GLib.Value v = max_count;
++        args.append (v);
++        v = offset;
++        args.append (v);
++
++        var query = this.get_sql_all_with_filter (where_filter);
++        try {
++            var stmt = this.lms_db.prepare_and_init (query, args.values);
++            while (Database.get_children_step (stmt)) {
++                children.add (this.object_from_statement (stmt));
++            }
++        } catch (DatabaseError e) {
++            warning ("Query failed: %s", e.message);
++        }
++
++        return children;
++    }
++
++    public async MediaObjects? search (SearchExpression? expression,
++                                       uint offset,
++                                       uint max_count,
++                                       out uint total_matches,
++                                       string sort_criteria,
++                                       Cancellable? cancellable)
++                                        throws Error {
++        debug ("search()");
++        try {
++            var args = new GLib.ValueArray (0);
++            var filter = CategoryContainer.search_expression_to_sql (expression,
++                                                                     args);
++            total_matches = this.get_child_count_with_filter (filter, args);
++
++            if (expression != null) {
++                debug ("  Original search: %s", expression.to_string ());
++                debug ("  Parsed search expression: %s", filter);
++                debug ("  Filtered cild count is %u", total_matches);
++            }
++
++            if (max_count == 0) {
++                max_count = uint.MAX;
++            }
++            return this.get_children_with_filter (filter,
++                                                  args,
++                                                  sort_criteria,
++                                                  offset,
++                                                  max_count);
++        } catch (Error e) {
++            debug ("  Falling back to simple_search(): %s", e.message);
++            return yield this.simple_search (expression,
++                                             offset,
++                                             max_count,
++                                             out total_matches,
++                                             sort_criteria,
++                                             cancellable);
++        }
++    }
++
++    public async override MediaObjects? get_children (uint offset,
++                                                      uint max_count,
++                                                      string sort_criteria,
++                                                      Cancellable? cancellable)
++                                        throws Error {
++        MediaObjects retval = new MediaObjects ();
++
++        Database.get_children_init (this.stmt_all,
++                                    offset,
++                                    max_count,
++                                    sort_criteria);
++        while (Database.get_children_step (this.stmt_all)) {
++            retval.add (this.object_from_statement (this.stmt_all));
++        }
++
++        return retval;
++    }
++
++    public async override MediaObject? find_object (string id, 
++                                                    Cancellable? cancellable)
++                                        throws Error {
++        if (!id.has_prefix (this.child_prefix)) {
++            /* can't match anything in this container */
++            return null;
++        }
++
++        MediaObject object = null;
++
++        /* remove parent section from id */
++        var real_id = id.substring (this.child_prefix.length);
++        /* remove grandchildren from id */
++        var index = real_id.index_of_char (':');
++        if (index > 0) {
++            real_id = real_id.slice (0, index);
++        }
++
++        try {
++            Database.find_object (real_id, this.stmt_find_object);
++            var child = this.object_from_statement (this.stmt_find_object);
++            if (index < 0) {
++                object = child;
++            } else {
++                /* try grandchildren */
++                var container = child as CategoryContainer; 
++                object = yield container.find_object (id, cancellable);
++
++                /* tell object to keep a reference to the parent --
++                 * otherwise parent is freed before object is serialized */
++                object.parent_ref = object.parent;
++            }
++        } catch (DatabaseError e) {
++            debug ("find_object %s in %s: %s", id, this.id, e.message);
++            /* Happens e.g. if id is not an integer */
++        }
++
++        return object;
++    }
++
++    protected string build_child_id (int db_id) {
++        return "%s%d".printf (this.child_prefix, db_id);
++    }
++
++    protected string build_reference_id (int db_id) {
++        return "%s%d".printf (this.ref_prefix, db_id);
++    }
++
++    protected async void add_child (MediaObject object) {
++    }
++
++    protected async void remove_child (MediaObject object) {
++    }
++
++    private void on_db_updated(uint64 old_id, uint64 new_id) {
++        try {
++            var stmt_count = this.lms_db.prepare (this.sql_count);
++
++            if (stmt_count.step () == Sqlite.ROW) {
++                this.child_count = stmt_count.column_int (0);
++            }
++
++            Database.get_children_with_update_id_init (this.stmt_added,
++                                                       old_id,
++                                                       new_id);
++            while (Database.get_children_step (this.stmt_added)) {
++                this.add_child_tracked.begin(this.object_from_statement (this.stmt_added));
++            }
++
++            Database.get_children_with_update_id_init (this.stmt_removed,
++                                                       old_id,
++                                                       new_id);
++            while (Database.get_children_step (this.stmt_removed)) {
++                this.remove_child_tracked.begin(this.object_from_statement (this.stmt_removed));
++            }
++
++        } catch (DatabaseError e) {
++            warning ("Can't perform container update: %s", e.message);
++        }
++
++    }
++
++    public CategoryContainer (string db_id,
++                              MediaContainer parent,
++                              string title,
++                              LMS.Database lms_db,
++                              string sql_all,
++                              string sql_find_object,
++                              string sql_count,
++                              string? sql_added,
++                              string? sql_removed
++                             ) {
++        Object (id : "%s:%s".printf (parent.id, db_id),
++                db_id : db_id,
++                parent : parent,
++                title : title,
++                lms_db : lms_db,
++                sql_all : sql_all,
++                sql_find_object : sql_find_object,
++                sql_count : sql_count,
++                sql_added : sql_added,
++                sql_removed: sql_removed
++               );
++    }
++
++    construct {
++        this.search_classes = new ArrayList<string> ();
++
++        this.child_prefix = "%s:".printf (this.id);
++
++        var index = this.id.index_of_char (':');
++        this.ref_prefix = this.id.slice (0, index) + ":all:";
++
++        try {
++            this.stmt_all = this.lms_db.prepare (this.sql_all);
++            this.stmt_find_object = this.lms_db.prepare (this.sql_find_object);
++            var stmt_count = this.lms_db.prepare (this.sql_count);
++
++            if (stmt_count.step () == Sqlite.ROW) {
++                this.child_count = stmt_count.column_int (0);
++            }
++            // some container implementations don't have a reasonable way to provide
++            // id-based statements to fetch added or removed items
++            if (this.sql_added != null && this.sql_removed != null) {
++                this.stmt_added = this.lms_db.prepare (this.sql_added);
++                this.stmt_removed = this.lms_db.prepare (this.sql_removed);
++                lms_db.db_updated.connect(this.on_db_updated);
++            }
++        } catch (DatabaseError e) {
++            warning ("Container %s: %s", this.title, e.message);
++        }
++
++    }
++}
+diff --git a/src/plugins/lms/rygel-lms-collate.c b/src/plugins/lms/rygel-lms-collate.c
+new file mode 100644
+index 0000000..8eee80b
+--- /dev/null
++++ b/src/plugins/lms/rygel-lms-collate.c
+@@ -0,0 +1,49 @@
++/*
++ * Copyright (C) 2012 Jens Georg <mail@jensge.org>.
++ *
++ * Author: 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 <glib.h>
++
++#ifdef HAVE_UNISTRING
++#   include <unistr.h>
++#endif
++
++gint rygel_lms_utf8_collate_str (const char *a, gsize alen,
++                                 const char *b, gsize blen)
++{
++    char *a_str, *b_str;
++    gint result;
++
++    /* Make sure the passed strings are null terminated */
++    a_str = g_strndup (a, alen);
++    b_str = g_strndup (b, blen);
++
++#ifdef HAVE_UNISTRING
++    result = u8_strcoll (a_str, b_str);
++#else
++    return g_utf8_collate (a_str, b_str);
++#endif
++
++    g_free (a_str);
++    g_free (b_str);
++
++    return result;
++}
+diff --git a/src/plugins/lms/rygel-lms-database.vala b/src/plugins/lms/rygel-lms-database.vala
+new file mode 100644
+index 0000000..e898d66
+--- /dev/null
++++ b/src/plugins/lms/rygel-lms-database.vala
+@@ -0,0 +1,294 @@
++/*
++ * Copyright (C) 2009,2011 Jens Georg <mail@jensge.org>,
++ *           (C) 2013 Intel Corporation.
++ *
++ * Author: Jussi Kukkonen <jussi.kukkonen@intel.com>
++ *
++ * 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.
++ */
++
++using Rygel;
++using Gee;
++using Sqlite;
++
++public errordomain Rygel.LMS.DatabaseError {
++    OPEN,
++    PREPARE,
++    BIND,
++    STEP,
++    NOT_FOUND
++}
++
++namespace Rygel.LMS {
++    extern static int utf8_collate_str (uint8[] a, uint8[] b);
++}
++
++public class Rygel.LMS.Database {
++
++    public signal void db_updated(uint64 old_update_id, uint64 new_update_id);
++
++    private Sqlite.Database db;
++    private LMS.DBus lms_proxy;
++    private uint64 update_id;
++
++    /**
++     * Function to implement the custom SQL function 'contains'
++     */
++    private static void utf8_contains (Sqlite.Context context,
++                                       Sqlite.Value[] args)
++                                       requires (args.length == 2) {
++        if (args[0].to_text () == null ||
++            args[1].to_text () == null) {
++           context.result_int (0);
++
++           return;
++        }
++
++        var pattern = Regex.escape_string (args[1].to_text ());
++        if (Regex.match_simple (pattern,
++                                args[0].to_text (),
++                                RegexCompileFlags.CASELESS)) {
++            context.result_int (1);
++        } else {
++            context.result_int (0);
++        }
++    }
++
++    /**
++     * Function to implement the custom SQLite collation 'CASEFOLD'.
++     *
++     * Uses utf8 case-fold to compare the strings.
++     */
++    private static int utf8_collate (int alen, void* a, int blen, void* b) {
++        // unowned to prevent array copy
++        unowned uint8[] _a = (uint8[]) a;
++        _a.length = alen;
++
++        unowned uint8[] _b = (uint8[]) b;
++        _b.length = blen;
++
++        return LMS.utf8_collate_str (_a, _b);
++    }
++
++    public Database () throws DatabaseError {
++        string db_path;
++        try {
++            lms_proxy = Bus.get_proxy_sync (BusType.SESSION,
++                                            "org.lightmediascanner",
++                                            "/org/lightmediascanner/Scanner1");
++            db_path = lms_proxy.data_base_path;
++            debug ("Got db path %s from LMS over dbus", db_path);
++            update_id = lms_proxy.update_id;
++            debug ("Got updated id %lld from LMS over dbus", update_id);
++            lms_proxy.g_properties_changed.connect (this.on_lms_properties_changed);
++
++        } catch (IOError e) {
++            warning("Couldn't get LMS Dbus proxy: %s", e.message);
++            db_path = Environment.get_user_config_dir() +
++                      "/lightmediascannerd/db.sqlite3";
++            debug  ("Using default sqlite database location %s", db_path);
++        }
++
++        Sqlite.Database.open (db_path, out this.db);
++        if (this.db.errcode () != Sqlite.OK) {
++            throw new DatabaseError.OPEN ("Failed to open '%s': %d",
++                                          db_path,
++                                          this.db.errcode () );
++        }
++
++        this.db.create_function ("contains",
++                                 2,
++                                 Sqlite.UTF8,
++                                 null,
++                                 LMS.Database.utf8_contains,
++                                 null,
++                                 null);
++
++        this.db.create_collation ("CASEFOLD",
++                                  Sqlite.UTF8,
++                                  LMS.Database.utf8_collate);
++
++    }
++
++    private void on_lms_properties_changed (DBusProxy lms_proxy,
++                                        Variant   changed,
++                                        string[]  invalidated) {
++        if (!changed.get_type().equal (VariantType.VARDICT)) {
++            return;
++        }
++
++        foreach (var changed_prop in changed) {
++            var key = (string) changed_prop.get_child_value (0);
++            var value = changed_prop.get_child_value (1).get_child_value (0);
++
++            debug ("LMS property %s changed value to %s", key, value.print(true));
++
++            switch (key) {
++                case "UpdateID":
++                    db_updated(update_id, (uint64)value);
++                    update_id = (uint64)value;
++                    break;
++            }
++        }
++    }
++
++
++    public Statement prepare (string query_string) throws DatabaseError {
++        Statement statement;
++
++        var err = this.db.prepare_v2 (query_string, -1, out statement);
++        if (err != Sqlite.OK)
++            throw new DatabaseError.PREPARE ("Unable to create statement '%s': %d",
++                                             query_string,
++                                             err);
++        return statement;
++    }
++
++
++    public Statement prepare_and_init (string   query,
++                                       GLib.Value[]? arguments)
++                                        throws DatabaseError {
++
++        Statement statement;
++
++        var err = this.db.prepare_v2 (query, -1, out statement);
++        if (err != Sqlite.OK)
++            throw new DatabaseError.PREPARE ("Unable to create statement '%s': %d",
++                                             query,
++                                             err);
++
++        for (var i = 1; i <= arguments.length; ++i) {
++            int sqlite_err;
++            unowned GLib.Value current_value = arguments[i - 1];
++
++            if (current_value.holds (typeof (int))) {
++                sqlite_err = statement.bind_int (i, current_value.get_int ());
++                if (sqlite_err != Sqlite.OK)
++                    throw new DatabaseError.BIND("Unable to bind value %d",
++                                                 sqlite_err);
++            } else if (current_value.holds (typeof (int64))) {
++                sqlite_err = statement.bind_int64 (i, current_value.get_int64 ());
++                if (sqlite_err != Sqlite.OK)
++                    throw new DatabaseError.BIND("Unable to bind value %d",
++                                                 sqlite_err);
++            } else if (current_value.holds (typeof (uint64))) {
++                sqlite_err = statement.bind_int64 (i, (int64) current_value.get_uint64 ());
++                if (sqlite_err != Sqlite.OK)
++                    throw new DatabaseError.BIND("Unable to bind value %d",
++                                                 sqlite_err);
++            } else if (current_value.holds (typeof (long))) {
++                sqlite_err = statement.bind_int64 (i, current_value.get_long ());
++                if (sqlite_err != Sqlite.OK)
++                    throw new DatabaseError.BIND("Unable to bind value %d",
++                                                 sqlite_err);
++            } else if (current_value.holds (typeof (uint))) {
++                sqlite_err = statement.bind_int64 (i, current_value.get_uint ());
++                if (sqlite_err != Sqlite.OK)
++                    throw new DatabaseError.BIND("Unable to bind value %d",
++                                                 sqlite_err);
++            } else if (current_value.holds (typeof (string))) {
++                sqlite_err = statement.bind_text (i, current_value.get_string ());
++                if (sqlite_err != Sqlite.OK)
++                    throw new DatabaseError.BIND("Unable to bind value %d",
++                                                 sqlite_err);
++            } else if (current_value.holds (typeof (void *))) {
++                if (current_value.peek_pointer () == null) {
++                    sqlite_err = statement.bind_null (i);
++                    if (sqlite_err != Sqlite.OK)
++                        throw new DatabaseError.BIND("Unable to bind value %d",
++                                                     sqlite_err);
++                } else {
++                    assert_not_reached ();
++                }
++            } else {
++                var type = current_value.type ();
++                warning (_("Unsupported type %s"), type.name ());
++                assert_not_reached ();
++            }
++        }
++
++        return statement;
++    }
++
++    public static void find_object(string id, Statement stmt) throws DatabaseError {
++
++        (void) stmt.reset();
++
++        int integer_id = int.parse(id);
++        int sqlite_err = stmt.bind_int(1, integer_id);
++        if (sqlite_err != Sqlite.OK)
++            throw new DatabaseError.BIND("Unable to bind id %d", sqlite_err);
++
++        sqlite_err = stmt.step();
++        if (sqlite_err != Sqlite.ROW)
++            throw new DatabaseError.STEP("Unable to find id %s", id);
++    }
++
++    public static void get_children_init (Statement stmt,
++        uint offset, uint max_count, string sort_criteria) throws DatabaseError {
++
++        int sqlite_err;
++
++        (void) stmt.reset();
++
++        sqlite_err = stmt.bind_int(1, (int) max_count);
++        if (sqlite_err != Sqlite.OK)
++            throw new DatabaseError.BIND("Unable to bind max_count %d",
++                                         sqlite_err);
++
++        sqlite_err = stmt.bind_int(2, (int) offset);
++        if (sqlite_err != Sqlite.OK)
++            throw new DatabaseError.BIND("Unable to bind offset %d",
++                                         sqlite_err);
++    }
++
++    public static void get_children_with_update_id_init (Statement stmt,
++        uint64 old_id, uint64 new_id) throws DatabaseError {
++
++        int sqlite_err;
++
++        (void) stmt.reset();
++
++        if (new_id < old_id) // id value wrapped over
++            sqlite_err = stmt.bind_int64(1, 0);
++        else
++            sqlite_err = stmt.bind_int64(1, (int64)old_id);
++        if (sqlite_err != Sqlite.OK)
++            throw new DatabaseError.BIND("Unable to bind old_id %d",
++                                         sqlite_err);
++
++        sqlite_err = stmt.bind_int64(2, (int64)new_id);
++        if (sqlite_err != Sqlite.OK)
++            throw new DatabaseError.BIND("Unable to bind new_id %d",
++                                         sqlite_err);
++    }
++
++    public static bool get_children_step(Statement stmt) throws DatabaseError {
++
++        bool retval;
++        int sqlite_err;
++
++        sqlite_err = stmt.step();
++        retval = sqlite_err == Sqlite.ROW;
++
++        if (!retval && (sqlite_err != Sqlite.DONE))
++            throw new DatabaseError.STEP("Error iterating through rows %d",
++                                         sqlite_err);
++
++        return retval;
++    }
++}
+diff --git a/src/plugins/lms/rygel-lms-dbus-interfaces.vala b/src/plugins/lms/rygel-lms-dbus-interfaces.vala
+new file mode 100644
+index 0000000..13f00cb
+--- /dev/null
++++ b/src/plugins/lms/rygel-lms-dbus-interfaces.vala
+@@ -0,0 +1,30 @@
++/*
++ * Copyright (C) 2014 Intel Corporation.
++ *
++ * Author: Alexander Kanavin <alex.kanavin@gmail.com>
++ *
++ * 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.
++ */
++
++[DBus (name = "org.lightmediascanner.Scanner1")]
++interface Rygel.LMS.DBus : DBusProxy {
++    public abstract string data_base_path { owned get; }
++    [DBus (name = "UpdateID")]
++    public abstract uint64 update_id { get; }
++
++    //TODO: add all the other API items which are currently unused
++}
+\ No newline at end of file
+diff --git a/src/plugins/lms/rygel-lms-image-root.vala b/src/plugins/lms/rygel-lms-image-root.vala
+new file mode 100644
+index 0000000..466bbe2
+--- /dev/null
++++ b/src/plugins/lms/rygel-lms-image-root.vala
+@@ -0,0 +1,35 @@
++/*
++ * Copyright (C) 2013 Intel Corporation.
++ *
++ * Author: Jussi Kukkonen <jussi.kukkonen@intel.com>
++ *
++ * 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.
++ */
++
++using Rygel;
++
++public class Rygel.LMS.ImageRoot : Rygel.SimpleContainer {
++    public ImageRoot (string         id,
++                      MediaContainer parent,
++                      string         title,
++                      LMS.Database   lms_db) {
++        base (id, parent, title);
++
++        this.add_child_container (new AllImages (this, lms_db));
++        this.add_child_container (new ImageYears (this, lms_db));
++    }
++}
+diff --git a/src/plugins/lms/rygel-lms-image-year.vala b/src/plugins/lms/rygel-lms-image-year.vala
+new file mode 100644
+index 0000000..a7768f0
+--- /dev/null
++++ b/src/plugins/lms/rygel-lms-image-year.vala
+@@ -0,0 +1,114 @@
++/*
++ * Copyright (C) 2013 Intel Corporation.
++ *
++ * Author: Jussi Kukkonen <jussi.kukkonen@intel.com>
++ *
++ * 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.
++ */
++
++using Rygel;
++using Sqlite;
++
++public class Rygel.LMS.ImageYear : Rygel.LMS.CategoryContainer {
++    private static const string SQL_ALL_TEMPLATE =
++        "SELECT images.id, title, artist, date, width, height, path, size, dlna_profile, dlna_mime, strftime('%Y', date, 'unixepoch') as year " +
++        "FROM images, files " +
++        "WHERE dtime = 0 AND images.id = files.id AND year = '%s' " +
++        "LIMIT ? OFFSET ?;";
++
++    private static const string SQL_COUNT_TEMPLATE =
++        "SELECT count(images.id), strftime('%Y', date, 'unixepoch') as year " +
++        "FROM images, files " +
++        "WHERE dtime = 0 AND images.id = files.id AND year = '%s';";
++
++    private static const string SQL_FIND_OBJECT_TEMPLATE =
++        "SELECT images.id, title, artist, date, width, height, path, size, dlna_profile, dlna_mime, strftime('%Y', date, 'unixepoch') as year " +
++        "FROM images, files " +
++        "WHERE dtime = 0 AND files.id = ? AND images.id = files.id AND year = '%s';";
++
++    private static const string SQL_ADDED_TEMPLATE =
++        "SELECT images.id, title, artist, date, width, height, path, size, dlna_profile, dlna_mime, strftime('%Y', date, 'unixepoch') as year " +
++        "FROM images, files " +
++        "WHERE dtime = 0 AND images.id = files.id AND year = '%s' " +
++        "AND update_id > ? AND update_id <= ?;";
++
++    private static const string SQL_REMOVED_TEMPLATE =
++        "SELECT images.id, title, artist, date, width, height, path, size, dlna_profile, dlna_mime, strftime('%Y', date, 'unixepoch') as year " +
++        "FROM images, files " +
++        "WHERE dtime <> 0 AND images.id = files.id AND year = '%s' " +
++        "AND update_id > ? AND update_id <= ?;";
++
++    protected override MediaObject? object_from_statement (Statement statement) {
++        var id = statement.column_int(0);
++        var path = statement.column_text(6);
++        var mime_type = statement.column_text(9);
++
++        if (mime_type == null || mime_type.length == 0){
++            /* TODO is this correct? */
++            debug ("Image item %d (%s) has no MIME type",
++                   id,
++                   path);
++        }
++
++        var title = statement.column_text(1);
++        var image = new ImageItem(this.build_child_id (id), this, title);
++        image.ref_id = this.build_reference_id (id);
++        image.creator = statement.column_text(2);
++        TimeVal tv = { (long) statement.column_int(3), (long) 0 };
++        image.date = tv.to_iso8601 ();
++        image.width = statement.column_int(4);
++        image.height = statement.column_int(5);
++        image.size = statement.column_int(7);
++        image.mime_type = mime_type;
++        image.dlna_profile = statement.column_text(8);
++        File file = File.new_for_path(path);
++        image.add_uri (file.get_uri ());
++
++        return image;
++    }
++
++    private static string get_sql_all (string year) {
++        return (SQL_ALL_TEMPLATE.printf (year));
++    }
++    private static string get_sql_find_object (string year) {
++        return (SQL_FIND_OBJECT_TEMPLATE.printf (year));
++    }
++    private static string get_sql_count (string year) {
++        return (SQL_COUNT_TEMPLATE.printf (year));
++    }
++    private static string get_sql_added (string year) {
++        return (SQL_ADDED_TEMPLATE.printf (year));
++    }
++    private static string get_sql_removed (string year) {
++        return (SQL_REMOVED_TEMPLATE.printf (year));
++    }
++
++    public ImageYear (MediaContainer parent,
++                      string         year,
++                      LMS.Database   lms_db) {
++        base ("%s".printf (year),
++              parent,
++              year,
++              lms_db,
++              get_sql_all (year),
++              get_sql_find_object (year),
++              get_sql_count (year),
++              get_sql_added (year),
++              get_sql_removed (year)
++             );
++    }
++}
+diff --git a/src/plugins/lms/rygel-lms-image-years.vala b/src/plugins/lms/rygel-lms-image-years.vala
+new file mode 100644
+index 0000000..636f4d1
+--- /dev/null
++++ b/src/plugins/lms/rygel-lms-image-years.vala
+@@ -0,0 +1,59 @@
++/*
++ * Copyright (C) 2013 Intel Corporation.
++ *
++ * Author: Jussi Kukkonen <jussi.kukkonen@intel.com>
++ *
++ * 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.
++ */
++
++using Rygel;
++using Sqlite;
++
++public class Rygel.LMS.ImageYears : Rygel.LMS.CategoryContainer {
++    private static const string SQL_ALL =
++        "SELECT DISTINCT(strftime('%Y', images.date, 'unixepoch')) as year " +
++        "FROM images " + 
++        "LIMIT ? OFFSET ?;";
++
++    private static const string SQL_COUNT =
++        "SELECT COUNT(DISTINCT(strftime('%Y', images.date, 'unixepoch'))) " +
++        "FROM images;";
++
++    /* actually returns multiple times the same result (because no DISTINCT) */
++    /* Casting the year is a workaround so we can keep using
++     * Database.find_object() without making the argument a variant or something like it*/
++    private static const string SQL_FIND_OBJECT =
++        "SELECT strftime('%Y', images.date, 'unixepoch') as year " +
++        "FROM images " +
++        "WHERE year = CAST(? AS TEXT)";
++
++    protected override MediaObject? object_from_statement (Statement statement) {
++        return new LMS.ImageYear (this, statement.column_text (0), this.lms_db);
++    }
++
++    public ImageYears (MediaContainer parent, LMS.Database lms_db) {
++        base ("years",
++              parent,
++              _("Years"),
++              lms_db,
++              ImageYears.SQL_ALL,
++              ImageYears.SQL_FIND_OBJECT,
++              ImageYears.SQL_COUNT,
++              null, null
++             );
++    }
++}
+diff --git a/src/plugins/lms/rygel-lms-music-root.vala b/src/plugins/lms/rygel-lms-music-root.vala
+new file mode 100644
+index 0000000..7b1eb0f
+--- /dev/null
++++ b/src/plugins/lms/rygel-lms-music-root.vala
+@@ -0,0 +1,36 @@
++/*
++ * Copyright (C) 2013 Intel Corporation.
++ *
++ * Author: Jussi Kukkonen <jussi.kukkonen@intel.com>
++ *
++ * 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.
++ */
++
++using Rygel;
++
++public class Rygel.LMS.MusicRoot : Rygel.SimpleContainer {
++    public MusicRoot (string         id,
++                      MediaContainer parent,
++                      string         title,
++                      LMS.Database   lms_db) {
++        base (id, parent, title);
++
++        this.add_child_container (new AllMusic (this, lms_db));
++        this.add_child_container (new Artists ("artists", this, _("Artists"), lms_db));
++        this.add_child_container (new Albums (this, lms_db));
++    }
++}
+diff --git a/src/plugins/lms/rygel-lms-plugin-factory.vala b/src/plugins/lms/rygel-lms-plugin-factory.vala
+new file mode 100644
+index 0000000..9fa8ccd
+--- /dev/null
++++ b/src/plugins/lms/rygel-lms-plugin-factory.vala
+@@ -0,0 +1,40 @@
++/*
++ * Copyright (C) 2013 Intel Corporation.
++ *
++ * Author: Jussi Kukkonen <jussi.kukkonen@intel.com>
++ *
++ * 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.
++ */
++
++using Rygel;
++
++private Rygel.LMS.PluginFactory plugin_factory;
++
++public void module_init(PluginLoader loader) {
++        plugin_factory = new Rygel.LMS.PluginFactory(loader);
++}
++
++public class Rygel.LMS.PluginFactory {
++
++    PluginLoader loader;
++
++    public PluginFactory(PluginLoader loader) {
++        this.loader = loader;
++        this.loader.add_plugin(new LMS.Plugin());
++    }
++
++}
+diff --git a/src/plugins/lms/rygel-lms-plugin.vala b/src/plugins/lms/rygel-lms-plugin.vala
+new file mode 100644
+index 0000000..8bf1284
+--- /dev/null
++++ b/src/plugins/lms/rygel-lms-plugin.vala
+@@ -0,0 +1,35 @@
++/*
++ * Copyright (C) 2013 Intel Corporation.
++ *
++ * Author: Jussi Kukkonen <jussi.kukkonen@intel.com>
++ *
++ * 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.
++ */
++
++using Rygel;
++
++public class Rygel.LMS.Plugin : Rygel.MediaServerPlugin {
++    public const string NAME = "LMS";
++
++    private static RootContainer root;
++
++    public Plugin() {
++        if (root == null)
++            root = new RootContainer();
++        base(root, Plugin.NAME, null, PluginCapabilities.TRACK_CHANGES);
++    }
++}
+diff --git a/src/plugins/lms/rygel-lms-root-container.vala b/src/plugins/lms/rygel-lms-root-container.vala
+new file mode 100644
+index 0000000..1623fa3
+--- /dev/null
++++ b/src/plugins/lms/rygel-lms-root-container.vala
+@@ -0,0 +1,58 @@
++/*
++ * Copyright (C) 2013 Intel Corporation.
++ *
++ * Author: Jussi Kukkonen <jussi.kukkonen@intel.com>
++ *
++ * 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.
++ */
++
++using Rygel;
++
++using Sqlite;
++
++public class Rygel.LMS.RootContainer : Rygel.SimpleContainer {
++
++    private LMS.Database lms_db = null;
++
++    public RootContainer() {
++        var config = MetaConfig.get_default ();
++
++        var title = _("Shared media");
++        try {
++            title = config.get_string ("LightMediaScanner", "title");
++        } catch (GLib.Error error) {}
++
++        base.root(title);
++
++        try {
++            this.lms_db = new LMS.Database ();
++
++            this.add_child_container (new MusicRoot ("music", this, _("Music"), this.lms_db));
++            this.add_child_container (new AllVideos ("all-videos", this, _("Videos"), this.lms_db));
++            this.add_child_container (new ImageRoot ("images", this, _("Pictures"), this.lms_db));
++
++        } catch (DatabaseError e) {
++            warning ("%s\n", e.message);
++
++            /* TODO if db does not exist we should
++               wait for it to be created and then add folders.  Best to wait for the
++               LMS notification API. */
++        }
++
++    }
++
++}
+diff --git a/src/plugins/lms/rygel-lms-sql-function.vala b/src/plugins/lms/rygel-lms-sql-function.vala
+new file mode 100644
+index 0000000..e8580cc
+--- /dev/null
++++ b/src/plugins/lms/rygel-lms-sql-function.vala
+@@ -0,0 +1,31 @@
++/*
++ * Copyright (C) 2010 Jens Georg <mail@jensge.org>.
++ *
++ * Author: 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.
++ */
++
++internal class Rygel.LMS.SqlFunction : SqlOperator {
++    public SqlFunction (string name, string arg) {
++        base (name, arg);
++    }
++
++    public override string to_string () {
++        return "%s(%s,?)".printf (name, arg);
++    }
++}
+diff --git a/src/plugins/lms/rygel-lms-sql-operator.vala b/src/plugins/lms/rygel-lms-sql-operator.vala
+new file mode 100644
+index 0000000..fc4e907
+--- /dev/null
++++ b/src/plugins/lms/rygel-lms-sql-operator.vala
+@@ -0,0 +1,73 @@
++/*
++ * Copyright (C) 2010 Jens Georg <mail@jensge.org>.
++ *
++ * Author: 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.
++ */
++
++using GUPnP;
++
++internal class Rygel.LMS.SqlOperator : GLib.Object {
++    protected string name;
++    protected string arg;
++    protected string collate;
++
++    public SqlOperator (string name,
++                        string arg,
++                        string collate = "") {
++        this.name = name;
++        this.arg = arg;
++        this.collate = collate;
++    }
++
++    public SqlOperator.from_search_criteria_op (SearchCriteriaOp op,
++                                                string           arg,
++                                                string           collate) {
++        string sql = null;
++        switch (op) {
++            case SearchCriteriaOp.EQ:
++                sql = "=";
++                break;
++            case SearchCriteriaOp.NEQ:
++                sql = "!=";
++                break;
++            case SearchCriteriaOp.LESS:
++                sql = "<";
++                break;
++            case SearchCriteriaOp.LEQ:
++                sql = "<=";
++                break;
++            case SearchCriteriaOp.GREATER:
++                sql = ">";
++                break;
++            case SearchCriteriaOp.GEQ:
++                sql = ">=";
++                break;
++            default:
++                assert_not_reached ();
++        }
++
++        this (sql, arg, collate);
++    }
++
++    public virtual string to_string () {
++        return "(%s %s ? %s)".printf (arg, name, collate);
++    }
++}
++
++
+-- 
+1.7.10.4
+
diff --git a/meta-agl/recipes-connectivity/rygel/files/0002-lms-add-C-source-files.patch b/meta-agl/recipes-connectivity/rygel/files/0002-lms-add-C-source-files.patch
new file mode 100644
index 000000000..bbd61aa27
--- /dev/null
+++ b/meta-agl/recipes-connectivity/rygel/files/0002-lms-add-C-source-files.patch
@@ -0,0 +1,9455 @@
+From 5a91b6b6efdaf28a6640126a32e819aef7e10a74 Mon Sep 17 00:00:00 2001
+From: Manuel Bachmann <manuel.bachmann@iot.bzh>
+Date: Sun, 25 Oct 2015 14:21:28 +0100
+Subject: [PATCH] lms: add C source files
+
+C source files are normally generated by Vala at compile
+time, but we do not use Vala for Rygel under OpenEmbedded
+(because it requires GObject-Introspection support in
+dependencies such as GUPnP, and that is still buggy).
+
+A full tarball release would contain the C files anyway,
+so let us include them so the build succeeds with OE.
+
+Signed-off-by: Manuel Bachmann <manuel.bachmann@iot.bzh>
+---
+ src/plugins/lms/librygel_lms_la_vala.stamp     |    1 +
+ src/plugins/lms/rygel-lms-album.c              |  514 +++++
+ src/plugins/lms/rygel-lms-albums.c             |  569 +++++
+ src/plugins/lms/rygel-lms-all-images.c         |  305 +++
+ src/plugins/lms/rygel-lms-all-music.c          |  417 ++++
+ src/plugins/lms/rygel-lms-all-videos.c         |  456 ++++
+ src/plugins/lms/rygel-lms-artist.c             |  274 +++
+ src/plugins/lms/rygel-lms-artists.c            |  214 ++
+ src/plugins/lms/rygel-lms-category-container.c | 2772 ++++++++++++++++++++++++
+ src/plugins/lms/rygel-lms-database.c           | 1349 ++++++++++++
+ src/plugins/lms/rygel-lms-dbus-interfaces.c    |  261 +++
+ src/plugins/lms/rygel-lms-image-root.c         |  178 ++
+ src/plugins/lms/rygel-lms-image-year.c         |  422 ++++
+ src/plugins/lms/rygel-lms-image-years.c        |  196 ++
+ src/plugins/lms/rygel-lms-music-root.c         |  202 ++
+ src/plugins/lms/rygel-lms-plugin-factory.c     |  307 +++
+ src/plugins/lms/rygel-lms-plugin.c             |  134 ++
+ src/plugins/lms/rygel-lms-root-container.c     |  318 +++
+ src/plugins/lms/rygel-lms-sql-function.c       |  146 ++
+ src/plugins/lms/rygel-lms-sql-operator.c       |  240 ++
+ 21 files changed, 9276 insertions(+), 1 deletion(-)
+ create mode 100644 src/plugins/lms/librygel_lms_la_vala.stamp
+ create mode 100644 src/plugins/lms/rygel-lms-album.c
+ create mode 100644 src/plugins/lms/rygel-lms-albums.c
+ create mode 100644 src/plugins/lms/rygel-lms-all-images.c
+ create mode 100644 src/plugins/lms/rygel-lms-all-music.c
+ create mode 100644 src/plugins/lms/rygel-lms-all-videos.c
+ create mode 100644 src/plugins/lms/rygel-lms-artist.c
+ create mode 100644 src/plugins/lms/rygel-lms-artists.c
+ create mode 100644 src/plugins/lms/rygel-lms-category-container.c
+ create mode 100644 src/plugins/lms/rygel-lms-database.c
+ create mode 100644 src/plugins/lms/rygel-lms-dbus-interfaces.c
+ create mode 100644 src/plugins/lms/rygel-lms-image-root.c
+ create mode 100644 src/plugins/lms/rygel-lms-image-year.c
+ create mode 100644 src/plugins/lms/rygel-lms-image-years.c
+ create mode 100644 src/plugins/lms/rygel-lms-music-root.c
+ create mode 100644 src/plugins/lms/rygel-lms-plugin-factory.c
+ create mode 100644 src/plugins/lms/rygel-lms-plugin.c
+ create mode 100644 src/plugins/lms/rygel-lms-root-container.c
+ create mode 100644 src/plugins/lms/rygel-lms-sql-function.c
+ create mode 100644 src/plugins/lms/rygel-lms-sql-operator.c
+
+diff --git a/src/plugins/lms/librygel_lms_la_vala.stamp b/src/plugins/lms/librygel_lms_la_vala.stamp
+new file mode 100644
+index 0000000..859afb1
+--- /dev/null
++++ b/src/plugins/lms/librygel_lms_la_vala.stamp
+@@ -0,0 +1 @@
++stamp
+diff --git a/src/plugins/lms/rygel-lms-album.c b/src/plugins/lms/rygel-lms-album.c
+new file mode 100644
+index 0000000..9da60bc
+--- /dev/null
++++ b/src/plugins/lms/rygel-lms-album.c
+@@ -0,0 +1,514 @@
++/* rygel-lms-album.c generated by valac 0.28.0, the Vala compiler
++ * generated from rygel-lms-album.vala, do not modify */
++
++/*
++ * Copyright (C) 2013 Intel Corporation.
++ *
++ * Author: Jussi Kukkonen <jussi.kukkonen@intel.com>
++ *
++ * 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 <glib.h>
++#include <glib-object.h>
++#include <rygel-server.h>
++#include <sqlite3.h>
++#include <stdlib.h>
++#include <string.h>
++#include <gio/gio.h>
++
++
++#define RYGEL_LMS_TYPE_CATEGORY_CONTAINER (rygel_lms_category_container_get_type ())
++#define RYGEL_LMS_CATEGORY_CONTAINER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), RYGEL_LMS_TYPE_CATEGORY_CONTAINER, RygelLMSCategoryContainer))
++#define RYGEL_LMS_CATEGORY_CONTAINER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), RYGEL_LMS_TYPE_CATEGORY_CONTAINER, RygelLMSCategoryContainerClass))
++#define RYGEL_LMS_IS_CATEGORY_CONTAINER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), RYGEL_LMS_TYPE_CATEGORY_CONTAINER))
++#define RYGEL_LMS_IS_CATEGORY_CONTAINER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), RYGEL_LMS_TYPE_CATEGORY_CONTAINER))
++#define RYGEL_LMS_CATEGORY_CONTAINER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), RYGEL_LMS_TYPE_CATEGORY_CONTAINER, RygelLMSCategoryContainerClass))
++
++typedef struct _RygelLMSCategoryContainer RygelLMSCategoryContainer;
++typedef struct _RygelLMSCategoryContainerClass RygelLMSCategoryContainerClass;
++typedef struct _RygelLMSCategoryContainerPrivate RygelLMSCategoryContainerPrivate;
++
++#define RYGEL_LMS_TYPE_ALBUM (rygel_lms_album_get_type ())
++#define RYGEL_LMS_ALBUM(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), RYGEL_LMS_TYPE_ALBUM, RygelLMSAlbum))
++#define RYGEL_LMS_ALBUM_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), RYGEL_LMS_TYPE_ALBUM, RygelLMSAlbumClass))
++#define RYGEL_LMS_IS_ALBUM(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), RYGEL_LMS_TYPE_ALBUM))
++#define RYGEL_LMS_IS_ALBUM_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), RYGEL_LMS_TYPE_ALBUM))
++#define RYGEL_LMS_ALBUM_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), RYGEL_LMS_TYPE_ALBUM, RygelLMSAlbumClass))
++
++typedef struct _RygelLMSAlbum RygelLMSAlbum;
++typedef struct _RygelLMSAlbumClass RygelLMSAlbumClass;
++typedef struct _RygelLMSAlbumPrivate RygelLMSAlbumPrivate;
++#define _g_free0(var) (var = (g_free (var), NULL))
++#define _g_object_unref0(var) ((var == NULL) ? NULL : (var = (g_object_unref (var), NULL)))
++
++#define RYGEL_LMS_TYPE_DATABASE (rygel_lms_database_get_type ())
++#define RYGEL_LMS_DATABASE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), RYGEL_LMS_TYPE_DATABASE, RygelLMSDatabase))
++#define RYGEL_LMS_DATABASE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), RYGEL_LMS_TYPE_DATABASE, RygelLMSDatabaseClass))
++#define RYGEL_LMS_IS_DATABASE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), RYGEL_LMS_TYPE_DATABASE))
++#define RYGEL_LMS_IS_DATABASE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), RYGEL_LMS_TYPE_DATABASE))
++#define RYGEL_LMS_DATABASE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), RYGEL_LMS_TYPE_DATABASE, RygelLMSDatabaseClass))
++
++typedef struct _RygelLMSDatabase RygelLMSDatabase;
++typedef struct _RygelLMSDatabaseClass RygelLMSDatabaseClass;
++
++struct _RygelLMSCategoryContainer {
++	RygelMediaContainer parent_instance;
++	RygelLMSCategoryContainerPrivate * priv;
++	sqlite3_stmt* stmt_all;
++	sqlite3_stmt* stmt_find_object;
++	sqlite3_stmt* stmt_added;
++	sqlite3_stmt* stmt_removed;
++	gchar* child_prefix;
++	gchar* ref_prefix;
++};
++
++struct _RygelLMSCategoryContainerClass {
++	RygelMediaContainerClass parent_class;
++	RygelMediaObject* (*object_from_statement) (RygelLMSCategoryContainer* self, sqlite3_stmt* statement);
++	gchar* (*get_sql_all_with_filter) (RygelLMSCategoryContainer* self, const gchar* filter);
++	gchar* (*get_sql_count_with_filter) (RygelLMSCategoryContainer* self, const gchar* filter);
++	guint (*get_child_count_with_filter) (RygelLMSCategoryContainer* self, const gchar* where_filter, GValueArray* args);
++	RygelMediaObjects* (*get_children_with_filter) (RygelLMSCategoryContainer* self, const gchar* where_filter, GValueArray* args, const gchar* sort_criteria, guint offset, guint max_count);
++};
++
++struct _RygelLMSAlbum {
++	RygelLMSCategoryContainer parent_instance;
++	RygelLMSAlbumPrivate * priv;
++};
++
++struct _RygelLMSAlbumClass {
++	RygelLMSCategoryContainerClass parent_class;
++};
++
++
++static gpointer rygel_lms_album_parent_class = NULL;
++
++GType rygel_lms_category_container_get_type (void) G_GNUC_CONST;
++GType rygel_lms_album_get_type (void) G_GNUC_CONST;
++enum  {
++	RYGEL_LMS_ALBUM_DUMMY_PROPERTY
++};
++#define RYGEL_LMS_ALBUM_SQL_ALL_TEMPLATE "SELECT files.id, files.path, files.size, " "audios.title as title, audios.trackno, audios.length, audios.channels," \
++" audios.sampling_rate, audios.bitrate, audios.dlna_profile, audios.dln" \
++"a_mime, " "audio_artists.name as artist, " "audio_albums.name " "FROM audios, files " "LEFT JOIN audio_artists " "ON audios.artist_id = audio_artists.id " "LEFT JOIN audio_albums " "ON audios.album_id = audio_albums.id " "WHERE dtime = 0 AND audios.id = files.id AND audios.album_id = %s " "LIMIT ? OFFSET ?;"
++#define RYGEL_LMS_ALBUM_SQL_COUNT_TEMPLATE "SELECT COUNT(audios.id) " "FROM audios, files " "WHERE dtime = 0 AND audios.id = files.id AND audios.album_id = %s;"
++#define RYGEL_LMS_ALBUM_SQL_COUNT_WITH_FILTER_TEMPLATE "SELECT COUNT(audios.id), audios.title as title, " "audio_artists.name as artist, " "audio_albums.name " "FROM audios, files " "LEFT JOIN audio_artists " "ON audios.artist_id = audio_artists.id " "LEFT JOIN audio_albums " "ON audios.album_id = audio_albums.id " "WHERE dtime = 0 AND audios.id = files.id AND audios.album_id = %s;"
++#define RYGEL_LMS_ALBUM_SQL_FIND_OBJECT_TEMPLATE "SELECT files.id, files.path, files.size, " "audios.title, audios.trackno, audios.length, audios.channels, audios.s" \
++"ampling_rate, audios.bitrate, audios.dlna_profile, audios.dlna_mime, " "audio_artists.name, " "audio_albums.name " "FROM audios, files " "LEFT JOIN audio_artists " "ON audios.artist_id = audio_artists.id " "LEFT JOIN audio_albums " "ON audios.album_id = audio_albums.id " "WHERE dtime = 0 AND files.id = ? AND audios.id = files.id AND audios.a" \
++"lbum_id = %s;"
++#define RYGEL_LMS_ALBUM_SQL_ADDED_TEMPLATE "SELECT files.id, files.path, files.size, " "audios.title as title, audios.trackno, audios.length, audios.channels," \
++" audios.sampling_rate, audios.bitrate, audios.dlna_profile, audios.dln" \
++"a_mime, " "audio_artists.name as artist, " "audio_albums.name " "FROM audios, files " "LEFT JOIN audio_artists " "ON audios.artist_id = audio_artists.id " "LEFT JOIN audio_albums " "ON audios.album_id = audio_albums.id " "WHERE dtime = 0 AND audios.id = files.id AND audios.album_id = %s " "AND update_id > ? AND update_id <= ?;"
++#define RYGEL_LMS_ALBUM_SQL_REMOVED_TEMPLATE "SELECT files.id, files.path, files.size, " "audios.title as title, audios.trackno, audios.length, audios.channels," \
++" audios.sampling_rate, audios.bitrate, audios.dlna_profile, audios.dln" \
++"a_mime, " "audio_artists.name as artist, " "audio_albums.name " "FROM audios, files " "LEFT JOIN audio_artists " "ON audios.artist_id = audio_artists.id " "LEFT JOIN audio_albums " "ON audios.album_id = audio_albums.id " "WHERE dtime <> 0 AND audios.id = files.id AND audios.album_id = %s " "AND update_id > ? AND update_id <= ?;"
++static RygelMediaObject* rygel_lms_album_real_object_from_statement (RygelLMSCategoryContainer* base, sqlite3_stmt* statement);
++gchar* rygel_lms_category_container_build_child_id (RygelLMSCategoryContainer* self, gint db_id);
++gchar* rygel_lms_category_container_build_reference_id (RygelLMSCategoryContainer* self, gint db_id);
++static gchar* rygel_lms_album_get_sql_all (const gchar* db_id);
++static gchar* rygel_lms_album_get_sql_find_object (const gchar* db_id);
++static gchar* rygel_lms_album_get_sql_count (const gchar* db_id);
++static gchar* rygel_lms_album_get_sql_added (const gchar* db_id);
++static gchar* rygel_lms_album_get_sql_removed (const gchar* db_id);
++static gchar* rygel_lms_album_real_get_sql_all_with_filter (RygelLMSCategoryContainer* base, const gchar* filter);
++const gchar* rygel_lms_category_container_get_sql_all (RygelLMSCategoryContainer* self);
++const gchar* rygel_lms_category_container_get_db_id (RygelLMSCategoryContainer* self);
++static gchar* rygel_lms_album_real_get_sql_count_with_filter (RygelLMSCategoryContainer* base, const gchar* filter);
++const gchar* rygel_lms_category_container_get_sql_count (RygelLMSCategoryContainer* self);
++gpointer rygel_lms_database_ref (gpointer instance);
++void rygel_lms_database_unref (gpointer instance);
++GParamSpec* rygel_lms_param_spec_database (const gchar* name, const gchar* nick, const gchar* blurb, GType object_type, GParamFlags flags);
++void rygel_lms_value_set_database (GValue* value, gpointer v_object);
++void rygel_lms_value_take_database (GValue* value, gpointer v_object);
++gpointer rygel_lms_value_get_database (const GValue* value);
++GType rygel_lms_database_get_type (void) G_GNUC_CONST;
++RygelLMSAlbum* rygel_lms_album_new (const gchar* db_id, RygelMediaContainer* parent, const gchar* title, RygelLMSDatabase* lms_db);
++RygelLMSAlbum* rygel_lms_album_construct (GType object_type, const gchar* db_id, RygelMediaContainer* parent, const gchar* title, RygelLMSDatabase* lms_db);
++RygelLMSCategoryContainer* rygel_lms_category_container_construct (GType object_type, const gchar* db_id, RygelMediaContainer* parent, const gchar* title, RygelLMSDatabase* lms_db, const gchar* sql_all, const gchar* sql_find_object, const gchar* sql_count, const gchar* sql_added, const gchar* sql_removed);
++
++
++static RygelMediaObject* rygel_lms_album_real_object_from_statement (RygelLMSCategoryContainer* base, sqlite3_stmt* statement) {
++	RygelLMSAlbum * self;
++	RygelMediaObject* result = NULL;
++	gint id = 0;
++	sqlite3_stmt* _tmp0_ = NULL;
++	gint _tmp1_ = 0;
++	gchar* path = NULL;
++	sqlite3_stmt* _tmp2_ = NULL;
++	const gchar* _tmp3_ = NULL;
++	gchar* _tmp4_ = NULL;
++	gchar* mime_type = NULL;
++	sqlite3_stmt* _tmp5_ = NULL;
++	const gchar* _tmp6_ = NULL;
++	gchar* _tmp7_ = NULL;
++	gboolean _tmp8_ = FALSE;
++	const gchar* _tmp9_ = NULL;
++	gchar* title = NULL;
++	sqlite3_stmt* _tmp15_ = NULL;
++	const gchar* _tmp16_ = NULL;
++	gchar* _tmp17_ = NULL;
++	gchar* song_id = NULL;
++	gint _tmp18_ = 0;
++	gchar* _tmp19_ = NULL;
++	RygelMusicItem* song = NULL;
++	RygelMusicItem* _tmp20_ = NULL;
++	gint _tmp21_ = 0;
++	gchar* _tmp22_ = NULL;
++	gchar* _tmp23_ = NULL;
++	sqlite3_stmt* _tmp24_ = NULL;
++	gint _tmp25_ = 0;
++	sqlite3_stmt* _tmp26_ = NULL;
++	gint _tmp27_ = 0;
++	sqlite3_stmt* _tmp28_ = NULL;
++	gint _tmp29_ = 0;
++	sqlite3_stmt* _tmp30_ = NULL;
++	gint _tmp31_ = 0;
++	sqlite3_stmt* _tmp32_ = NULL;
++	gint _tmp33_ = 0;
++	sqlite3_stmt* _tmp34_ = NULL;
++	gint _tmp35_ = 0;
++	sqlite3_stmt* _tmp36_ = NULL;
++	const gchar* _tmp37_ = NULL;
++	const gchar* _tmp38_ = NULL;
++	sqlite3_stmt* _tmp39_ = NULL;
++	const gchar* _tmp40_ = NULL;
++	sqlite3_stmt* _tmp41_ = NULL;
++	const gchar* _tmp42_ = NULL;
++	GFile* file = NULL;
++	const gchar* _tmp43_ = NULL;
++	GFile* _tmp44_ = NULL;
++	gchar* _tmp45_ = NULL;
++	gchar* _tmp46_ = NULL;
++	self = (RygelLMSAlbum*) base;
++	g_return_val_if_fail (statement != NULL, NULL);
++	_tmp0_ = statement;
++	_tmp1_ = sqlite3_column_int (_tmp0_, 0);
++	id = _tmp1_;
++	_tmp2_ = statement;
++	_tmp3_ = sqlite3_column_text (_tmp2_, 1);
++	_tmp4_ = g_strdup (_tmp3_);
++	path = _tmp4_;
++	_tmp5_ = statement;
++	_tmp6_ = sqlite3_column_text (_tmp5_, 10);
++	_tmp7_ = g_strdup (_tmp6_);
++	mime_type = _tmp7_;
++	_tmp9_ = mime_type;
++	if (_tmp9_ == NULL) {
++		_tmp8_ = TRUE;
++	} else {
++		const gchar* _tmp10_ = NULL;
++		gint _tmp11_ = 0;
++		gint _tmp12_ = 0;
++		_tmp10_ = mime_type;
++		_tmp11_ = strlen (_tmp10_);
++		_tmp12_ = _tmp11_;
++		_tmp8_ = _tmp12_ == 0;
++	}
++	if (_tmp8_) {
++		gint _tmp13_ = 0;
++		const gchar* _tmp14_ = NULL;
++		_tmp13_ = id;
++		_tmp14_ = path;
++		g_debug ("rygel-lms-album.vala:101: Music item %d (%s) has no MIME type", _tmp13_, _tmp14_);
++	}
++	_tmp15_ = statement;
++	_tmp16_ = sqlite3_column_text (_tmp15_, 3);
++	_tmp17_ = g_strdup (_tmp16_);
++	title = _tmp17_;
++	_tmp18_ = id;
++	_tmp19_ = rygel_lms_category_container_build_child_id ((RygelLMSCategoryContainer*) self, _tmp18_);
++	song_id = _tmp19_;
++	_tmp20_ = rygel_music_item_new (song_id, (RygelMediaContainer*) self, title, RYGEL_MUSIC_ITEM_UPNP_CLASS);
++	song = _tmp20_;
++	_tmp21_ = id;
++	_tmp22_ = rygel_lms_category_container_build_reference_id ((RygelLMSCategoryContainer*) self, _tmp21_);
++	_tmp23_ = _tmp22_;
++	rygel_media_object_set_ref_id ((RygelMediaObject*) song, _tmp23_);
++	_g_free0 (_tmp23_);
++	_tmp24_ = statement;
++	_tmp25_ = sqlite3_column_int (_tmp24_, 2);
++	rygel_media_file_item_set_size ((RygelMediaFileItem*) song, (gint64) _tmp25_);
++	_tmp26_ = statement;
++	_tmp27_ = sqlite3_column_int (_tmp26_, 4);
++	rygel_music_item_set_track_number (song, _tmp27_);
++	_tmp28_ = statement;
++	_tmp29_ = sqlite3_column_int (_tmp28_, 5);
++	rygel_audio_item_set_duration ((RygelAudioItem*) song, (glong) _tmp29_);
++	_tmp30_ = statement;
++	_tmp31_ = sqlite3_column_int (_tmp30_, 6);
++	rygel_audio_item_set_channels ((RygelAudioItem*) song, _tmp31_);
++	_tmp32_ = statement;
++	_tmp33_ = sqlite3_column_int (_tmp32_, 7);
++	rygel_audio_item_set_sample_freq ((RygelAudioItem*) song, _tmp33_);
++	_tmp34_ = statement;
++	_tmp35_ = sqlite3_column_int (_tmp34_, 8);
++	rygel_audio_item_set_bitrate ((RygelAudioItem*) song, _tmp35_);
++	_tmp36_ = statement;
++	_tmp37_ = sqlite3_column_text (_tmp36_, 9);
++	rygel_media_file_item_set_dlna_profile ((RygelMediaFileItem*) song, _tmp37_);
++	_tmp38_ = mime_type;
++	rygel_media_file_item_set_mime_type ((RygelMediaFileItem*) song, _tmp38_);
++	_tmp39_ = statement;
++	_tmp40_ = sqlite3_column_text (_tmp39_, 11);
++	rygel_media_object_set_artist ((RygelMediaObject*) song, _tmp40_);
++	_tmp41_ = statement;
++	_tmp42_ = sqlite3_column_text (_tmp41_, 12);
++	rygel_audio_item_set_album ((RygelAudioItem*) song, _tmp42_);
++	_tmp43_ = path;
++	_tmp44_ = g_file_new_for_path (_tmp43_);
++	file = _tmp44_;
++	_tmp45_ = g_file_get_uri (file);
++	_tmp46_ = _tmp45_;
++	rygel_media_object_add_uri ((RygelMediaObject*) song, _tmp46_);
++	_g_free0 (_tmp46_);
++	result = (RygelMediaObject*) song;
++	_g_object_unref0 (file);
++	_g_free0 (song_id);
++	_g_free0 (title);
++	_g_free0 (mime_type);
++	_g_free0 (path);
++	return result;
++}
++
++
++static gchar* rygel_lms_album_get_sql_all (const gchar* db_id) {
++	gchar* result = NULL;
++	const gchar* _tmp0_ = NULL;
++	gchar* _tmp1_ = NULL;
++	g_return_val_if_fail (db_id != NULL, NULL);
++	_tmp0_ = db_id;
++	_tmp1_ = g_strdup_printf (RYGEL_LMS_ALBUM_SQL_ALL_TEMPLATE, _tmp0_);
++	result = _tmp1_;
++	return result;
++}
++
++
++static gchar* rygel_lms_album_get_sql_find_object (const gchar* db_id) {
++	gchar* result = NULL;
++	const gchar* _tmp0_ = NULL;
++	gchar* _tmp1_ = NULL;
++	g_return_val_if_fail (db_id != NULL, NULL);
++	_tmp0_ = db_id;
++	_tmp1_ = g_strdup_printf (RYGEL_LMS_ALBUM_SQL_FIND_OBJECT_TEMPLATE, _tmp0_);
++	result = _tmp1_;
++	return result;
++}
++
++
++static gchar* rygel_lms_album_get_sql_count (const gchar* db_id) {
++	gchar* result = NULL;
++	const gchar* _tmp0_ = NULL;
++	gchar* _tmp1_ = NULL;
++	g_return_val_if_fail (db_id != NULL, NULL);
++	_tmp0_ = db_id;
++	_tmp1_ = g_strdup_printf (RYGEL_LMS_ALBUM_SQL_COUNT_TEMPLATE, _tmp0_);
++	result = _tmp1_;
++	return result;
++}
++
++
++static gchar* rygel_lms_album_get_sql_added (const gchar* db_id) {
++	gchar* result = NULL;
++	const gchar* _tmp0_ = NULL;
++	gchar* _tmp1_ = NULL;
++	g_return_val_if_fail (db_id != NULL, NULL);
++	_tmp0_ = db_id;
++	_tmp1_ = g_strdup_printf (RYGEL_LMS_ALBUM_SQL_ADDED_TEMPLATE, _tmp0_);
++	result = _tmp1_;
++	return result;
++}
++
++
++static gchar* rygel_lms_album_get_sql_removed (const gchar* db_id) {
++	gchar* result = NULL;
++	const gchar* _tmp0_ = NULL;
++	gchar* _tmp1_ = NULL;
++	g_return_val_if_fail (db_id != NULL, NULL);
++	_tmp0_ = db_id;
++	_tmp1_ = g_strdup_printf (RYGEL_LMS_ALBUM_SQL_REMOVED_TEMPLATE, _tmp0_);
++	result = _tmp1_;
++	return result;
++}
++
++
++static gchar* rygel_lms_album_real_get_sql_all_with_filter (RygelLMSCategoryContainer* base, const gchar* filter) {
++	RygelLMSAlbum * self;
++	gchar* result = NULL;
++	const gchar* _tmp0_ = NULL;
++	gint _tmp1_ = 0;
++	gint _tmp2_ = 0;
++	gchar* filter_str = NULL;
++	const gchar* _tmp6_ = NULL;
++	const gchar* _tmp7_ = NULL;
++	const gchar* _tmp8_ = NULL;
++	gchar* _tmp9_ = NULL;
++	const gchar* _tmp10_ = NULL;
++	gchar* _tmp11_ = NULL;
++	self = (RygelLMSAlbum*) base;
++	g_return_val_if_fail (filter != NULL, NULL);
++	_tmp0_ = filter;
++	_tmp1_ = strlen (_tmp0_);
++	_tmp2_ = _tmp1_;
++	if (_tmp2_ == 0) {
++		const gchar* _tmp3_ = NULL;
++		const gchar* _tmp4_ = NULL;
++		gchar* _tmp5_ = NULL;
++		_tmp3_ = rygel_lms_category_container_get_sql_all ((RygelLMSCategoryContainer*) self);
++		_tmp4_ = _tmp3_;
++		_tmp5_ = g_strdup (_tmp4_);
++		result = _tmp5_;
++		return result;
++	}
++	_tmp6_ = rygel_lms_category_container_get_db_id ((RygelLMSCategoryContainer*) self);
++	_tmp7_ = _tmp6_;
++	_tmp8_ = filter;
++	_tmp9_ = g_strdup_printf ("%s AND %s", _tmp7_, _tmp8_);
++	filter_str = _tmp9_;
++	_tmp10_ = filter_str;
++	_tmp11_ = g_strdup_printf (RYGEL_LMS_ALBUM_SQL_ALL_TEMPLATE, _tmp10_);
++	result = _tmp11_;
++	_g_free0 (filter_str);
++	return result;
++}
++
++
++static gchar* rygel_lms_album_real_get_sql_count_with_filter (RygelLMSCategoryContainer* base, const gchar* filter) {
++	RygelLMSAlbum * self;
++	gchar* result = NULL;
++	const gchar* _tmp0_ = NULL;
++	gint _tmp1_ = 0;
++	gint _tmp2_ = 0;
++	gchar* filter_str = NULL;
++	const gchar* _tmp6_ = NULL;
++	const gchar* _tmp7_ = NULL;
++	const gchar* _tmp8_ = NULL;
++	gchar* _tmp9_ = NULL;
++	const gchar* _tmp10_ = NULL;
++	gchar* _tmp11_ = NULL;
++	self = (RygelLMSAlbum*) base;
++	g_return_val_if_fail (filter != NULL, NULL);
++	_tmp0_ = filter;
++	_tmp1_ = strlen (_tmp0_);
++	_tmp2_ = _tmp1_;
++	if (_tmp2_ == 0) {
++		const gchar* _tmp3_ = NULL;
++		const gchar* _tmp4_ = NULL;
++		gchar* _tmp5_ = NULL;
++		_tmp3_ = rygel_lms_category_container_get_sql_count ((RygelLMSCategoryContainer*) self);
++		_tmp4_ = _tmp3_;
++		_tmp5_ = g_strdup (_tmp4_);
++		result = _tmp5_;
++		return result;
++	}
++	_tmp6_ = rygel_lms_category_container_get_db_id ((RygelLMSCategoryContainer*) self);
++	_tmp7_ = _tmp6_;
++	_tmp8_ = filter;
++	_tmp9_ = g_strdup_printf ("%s AND %s", _tmp7_, _tmp8_);
++	filter_str = _tmp9_;
++	_tmp10_ = filter_str;
++	_tmp11_ = g_strdup_printf (RYGEL_LMS_ALBUM_SQL_COUNT_WITH_FILTER_TEMPLATE, _tmp10_);
++	result = _tmp11_;
++	_g_free0 (filter_str);
++	return result;
++}
++
++
++RygelLMSAlbum* rygel_lms_album_construct (GType object_type, const gchar* db_id, RygelMediaContainer* parent, const gchar* title, RygelLMSDatabase* lms_db) {
++	RygelLMSAlbum * self = NULL;
++	const gchar* _tmp0_ = NULL;
++	RygelMediaContainer* _tmp1_ = NULL;
++	const gchar* _tmp2_ = NULL;
++	RygelLMSDatabase* _tmp3_ = NULL;
++	const gchar* _tmp4_ = NULL;
++	gchar* _tmp5_ = NULL;
++	gchar* _tmp6_ = NULL;
++	const gchar* _tmp7_ = NULL;
++	gchar* _tmp8_ = NULL;
++	gchar* _tmp9_ = NULL;
++	const gchar* _tmp10_ = NULL;
++	gchar* _tmp11_ = NULL;
++	gchar* _tmp12_ = NULL;
++	const gchar* _tmp13_ = NULL;
++	gchar* _tmp14_ = NULL;
++	gchar* _tmp15_ = NULL;
++	const gchar* _tmp16_ = NULL;
++	gchar* _tmp17_ = NULL;
++	gchar* _tmp18_ = NULL;
++	g_return_val_if_fail (db_id != NULL, NULL);
++	g_return_val_if_fail (parent != NULL, NULL);
++	g_return_val_if_fail (title != NULL, NULL);
++	g_return_val_if_fail (lms_db != NULL, NULL);
++	_tmp0_ = db_id;
++	_tmp1_ = parent;
++	_tmp2_ = title;
++	_tmp3_ = lms_db;
++	_tmp4_ = db_id;
++	_tmp5_ = rygel_lms_album_get_sql_all (_tmp4_);
++	_tmp6_ = _tmp5_;
++	_tmp7_ = db_id;
++	_tmp8_ = rygel_lms_album_get_sql_find_object (_tmp7_);
++	_tmp9_ = _tmp8_;
++	_tmp10_ = db_id;
++	_tmp11_ = rygel_lms_album_get_sql_count (_tmp10_);
++	_tmp12_ = _tmp11_;
++	_tmp13_ = db_id;
++	_tmp14_ = rygel_lms_album_get_sql_added (_tmp13_);
++	_tmp15_ = _tmp14_;
++	_tmp16_ = db_id;
++	_tmp17_ = rygel_lms_album_get_sql_removed (_tmp16_);
++	_tmp18_ = _tmp17_;
++	self = (RygelLMSAlbum*) rygel_lms_category_container_construct (object_type, _tmp0_, _tmp1_, _tmp2_, _tmp3_, _tmp6_, _tmp9_, _tmp12_, _tmp15_, _tmp18_);
++	_g_free0 (_tmp18_);
++	_g_free0 (_tmp15_);
++	_g_free0 (_tmp12_);
++	_g_free0 (_tmp9_);
++	_g_free0 (_tmp6_);
++	return self;
++}
++
++
++RygelLMSAlbum* rygel_lms_album_new (const gchar* db_id, RygelMediaContainer* parent, const gchar* title, RygelLMSDatabase* lms_db) {
++	return rygel_lms_album_construct (RYGEL_LMS_TYPE_ALBUM, db_id, parent, title, lms_db);
++}
++
++
++static void rygel_lms_album_class_init (RygelLMSAlbumClass * klass) {
++	rygel_lms_album_parent_class = g_type_class_peek_parent (klass);
++	((RygelLMSCategoryContainerClass *) klass)->object_from_statement = rygel_lms_album_real_object_from_statement;
++	((RygelLMSCategoryContainerClass *) klass)->get_sql_all_with_filter = rygel_lms_album_real_get_sql_all_with_filter;
++	((RygelLMSCategoryContainerClass *) klass)->get_sql_count_with_filter = rygel_lms_album_real_get_sql_count_with_filter;
++}
++
++
++static void rygel_lms_album_instance_init (RygelLMSAlbum * self) {
++}
++
++
++GType rygel_lms_album_get_type (void) {
++	static volatile gsize rygel_lms_album_type_id__volatile = 0;
++	if (g_once_init_enter (&rygel_lms_album_type_id__volatile)) {
++		static const GTypeInfo g_define_type_info = { sizeof (RygelLMSAlbumClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) rygel_lms_album_class_init, (GClassFinalizeFunc) NULL, NULL, sizeof (RygelLMSAlbum), 0, (GInstanceInitFunc) rygel_lms_album_instance_init, NULL };
++		GType rygel_lms_album_type_id;
++		rygel_lms_album_type_id = g_type_register_static (RYGEL_LMS_TYPE_CATEGORY_CONTAINER, "RygelLMSAlbum", &g_define_type_info, 0);
++		g_once_init_leave (&rygel_lms_album_type_id__volatile, rygel_lms_album_type_id);
++	}
++	return rygel_lms_album_type_id__volatile;
++}
++
++
++
+diff --git a/src/plugins/lms/rygel-lms-albums.c b/src/plugins/lms/rygel-lms-albums.c
+new file mode 100644
+index 0000000..f9fabe7
+--- /dev/null
++++ b/src/plugins/lms/rygel-lms-albums.c
+@@ -0,0 +1,569 @@
++/* rygel-lms-albums.c generated by valac 0.28.0, the Vala compiler
++ * generated from rygel-lms-albums.vala, do not modify */
++
++/*
++ * Copyright (C) 2013 Intel Corporation.
++ *
++ * Author: Jussi Kukkonen <jussi.kukkonen@intel.com>
++ *
++ * 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 <glib.h>
++#include <glib-object.h>
++#include <rygel-server.h>
++#include <sqlite3.h>
++#include <stdlib.h>
++#include <string.h>
++#include <gee.h>
++#include <glib/gi18n-lib.h>
++
++
++#define RYGEL_LMS_TYPE_CATEGORY_CONTAINER (rygel_lms_category_container_get_type ())
++#define RYGEL_LMS_CATEGORY_CONTAINER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), RYGEL_LMS_TYPE_CATEGORY_CONTAINER, RygelLMSCategoryContainer))
++#define RYGEL_LMS_CATEGORY_CONTAINER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), RYGEL_LMS_TYPE_CATEGORY_CONTAINER, RygelLMSCategoryContainerClass))
++#define RYGEL_LMS_IS_CATEGORY_CONTAINER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), RYGEL_LMS_TYPE_CATEGORY_CONTAINER))
++#define RYGEL_LMS_IS_CATEGORY_CONTAINER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), RYGEL_LMS_TYPE_CATEGORY_CONTAINER))
++#define RYGEL_LMS_CATEGORY_CONTAINER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), RYGEL_LMS_TYPE_CATEGORY_CONTAINER, RygelLMSCategoryContainerClass))
++
++typedef struct _RygelLMSCategoryContainer RygelLMSCategoryContainer;
++typedef struct _RygelLMSCategoryContainerClass RygelLMSCategoryContainerClass;
++typedef struct _RygelLMSCategoryContainerPrivate RygelLMSCategoryContainerPrivate;
++
++#define RYGEL_LMS_TYPE_ALBUMS (rygel_lms_albums_get_type ())
++#define RYGEL_LMS_ALBUMS(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), RYGEL_LMS_TYPE_ALBUMS, RygelLMSAlbums))
++#define RYGEL_LMS_ALBUMS_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), RYGEL_LMS_TYPE_ALBUMS, RygelLMSAlbumsClass))
++#define RYGEL_LMS_IS_ALBUMS(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), RYGEL_LMS_TYPE_ALBUMS))
++#define RYGEL_LMS_IS_ALBUMS_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), RYGEL_LMS_TYPE_ALBUMS))
++#define RYGEL_LMS_ALBUMS_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), RYGEL_LMS_TYPE_ALBUMS, RygelLMSAlbumsClass))
++
++typedef struct _RygelLMSAlbums RygelLMSAlbums;
++typedef struct _RygelLMSAlbumsClass RygelLMSAlbumsClass;
++typedef struct _RygelLMSAlbumsPrivate RygelLMSAlbumsPrivate;
++#define _g_free0(var) (var = (g_free (var), NULL))
++
++#define RYGEL_LMS_TYPE_DATABASE (rygel_lms_database_get_type ())
++#define RYGEL_LMS_DATABASE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), RYGEL_LMS_TYPE_DATABASE, RygelLMSDatabase))
++#define RYGEL_LMS_DATABASE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), RYGEL_LMS_TYPE_DATABASE, RygelLMSDatabaseClass))
++#define RYGEL_LMS_IS_DATABASE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), RYGEL_LMS_TYPE_DATABASE))
++#define RYGEL_LMS_IS_DATABASE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), RYGEL_LMS_TYPE_DATABASE))
++#define RYGEL_LMS_DATABASE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), RYGEL_LMS_TYPE_DATABASE, RygelLMSDatabaseClass))
++
++typedef struct _RygelLMSDatabase RygelLMSDatabase;
++typedef struct _RygelLMSDatabaseClass RygelLMSDatabaseClass;
++#define _sqlite3_finalize0(var) ((var == NULL) ? NULL : (var = (sqlite3_finalize (var), NULL)))
++#define _g_error_free0(var) ((var == NULL) ? NULL : (var = (g_error_free (var), NULL)))
++#define _g_object_unref0(var) ((var == NULL) ? NULL : (var = (g_object_unref (var), NULL)))
++
++#define RYGEL_LMS_TYPE_ALBUM (rygel_lms_album_get_type ())
++#define RYGEL_LMS_ALBUM(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), RYGEL_LMS_TYPE_ALBUM, RygelLMSAlbum))
++#define RYGEL_LMS_ALBUM_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), RYGEL_LMS_TYPE_ALBUM, RygelLMSAlbumClass))
++#define RYGEL_LMS_IS_ALBUM(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), RYGEL_LMS_TYPE_ALBUM))
++#define RYGEL_LMS_IS_ALBUM_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), RYGEL_LMS_TYPE_ALBUM))
++#define RYGEL_LMS_ALBUM_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), RYGEL_LMS_TYPE_ALBUM, RygelLMSAlbumClass))
++
++typedef struct _RygelLMSAlbum RygelLMSAlbum;
++typedef struct _RygelLMSAlbumClass RygelLMSAlbumClass;
++
++struct _RygelLMSCategoryContainer {
++	RygelMediaContainer parent_instance;
++	RygelLMSCategoryContainerPrivate * priv;
++	sqlite3_stmt* stmt_all;
++	sqlite3_stmt* stmt_find_object;
++	sqlite3_stmt* stmt_added;
++	sqlite3_stmt* stmt_removed;
++	gchar* child_prefix;
++	gchar* ref_prefix;
++};
++
++struct _RygelLMSCategoryContainerClass {
++	RygelMediaContainerClass parent_class;
++	RygelMediaObject* (*object_from_statement) (RygelLMSCategoryContainer* self, sqlite3_stmt* statement);
++	gchar* (*get_sql_all_with_filter) (RygelLMSCategoryContainer* self, const gchar* filter);
++	gchar* (*get_sql_count_with_filter) (RygelLMSCategoryContainer* self, const gchar* filter);
++	guint (*get_child_count_with_filter) (RygelLMSCategoryContainer* self, const gchar* where_filter, GValueArray* args);
++	RygelMediaObjects* (*get_children_with_filter) (RygelLMSCategoryContainer* self, const gchar* where_filter, GValueArray* args, const gchar* sort_criteria, guint offset, guint max_count);
++};
++
++struct _RygelLMSAlbums {
++	RygelLMSCategoryContainer parent_instance;
++	RygelLMSAlbumsPrivate * priv;
++};
++
++struct _RygelLMSAlbumsClass {
++	RygelLMSCategoryContainerClass parent_class;
++};
++
++typedef enum  {
++	RYGEL_LMS_DATABASE_ERROR_OPEN,
++	RYGEL_LMS_DATABASE_ERROR_PREPARE,
++	RYGEL_LMS_DATABASE_ERROR_BIND,
++	RYGEL_LMS_DATABASE_ERROR_STEP,
++	RYGEL_LMS_DATABASE_ERROR_NOT_FOUND
++} RygelLMSDatabaseError;
++#define RYGEL_LMS_DATABASE_ERROR rygel_lms_database_error_quark ()
++
++static gpointer rygel_lms_albums_parent_class = NULL;
++
++GType rygel_lms_category_container_get_type (void) G_GNUC_CONST;
++GType rygel_lms_albums_get_type (void) G_GNUC_CONST;
++enum  {
++	RYGEL_LMS_ALBUMS_DUMMY_PROPERTY
++};
++#define RYGEL_LMS_ALBUMS_SQL_ALL "SELECT audio_albums.id, audio_albums.name as title, " "audio_artists.name as artist " "FROM audio_albums " "LEFT JOIN audio_artists " "ON audio_albums.artist_id = audio_artists.id " "LIMIT ? OFFSET ?;"
++#define RYGEL_LMS_ALBUMS_SQL_ALL_WITH_FILTER_TEMPLATE "SELECT audio_albums.id, audio_albums.name as title, " "audio_artists.name as artist " "FROM audio_albums " "LEFT JOIN audio_artists " "ON audio_albums.artist_id = audio_artists.id " "WHERE %s " "LIMIT ? OFFSET ?;"
++#define RYGEL_LMS_ALBUMS_SQL_COUNT "SELECT COUNT(audio_albums.id) " "FROM audio_albums;"
++#define RYGEL_LMS_ALBUMS_SQL_COUNT_WITH_FILTER_TEMPLATE "SELECT COUNT(audio_albums.id), audio_albums.name as title, " "audio_artists.name as artist " "FROM audio_albums " "LEFT JOIN audio_artists " "ON audio_albums.artist_id = audio_artists.id " "WHERE %s;"
++#define RYGEL_LMS_ALBUMS_SQL_CHILD_COUNT_WITH_FILTER_TEMPLATE "SELECT COUNT(audios.id), audios.title as title, " "audio_artists.name as artist " "FROM audios, files, audio_albums " "LEFT JOIN audio_artists " "ON audios.artist_id = audio_artists.id " "WHERE dtime = 0 AND audios.id = files.id AND audios.album_id = audio_a" \
++"lbums.id %s;"
++#define RYGEL_LMS_ALBUMS_SQL_CHILD_ALL_WITH_FILTER_TEMPLATE "SELECT files.id, files.path, files.size, " "audios.title as title, audios.trackno, audios.length, audios.channels," \
++" audios.sampling_rate, audios.bitrate, audios.dlna_profile, audios.dln" \
++"a_mime, " "audio_artists.name as artist, " "audio_albums.name, audio_albums.id " "FROM audios, files, audio_albums " "LEFT JOIN audio_artists " "ON audios.artist_id = audio_artists.id " "WHERE dtime = 0 AND audios.id = files.id AND audios.album_id = audio_a" \
++"lbums.id %s " "LIMIT ? OFFSET ?;"
++#define RYGEL_LMS_ALBUMS_SQL_FIND_OBJECT "SELECT audio_albums.id, audio_albums.name " "FROM audio_albums " "WHERE audio_albums.id = ?;"
++static gchar* rygel_lms_albums_real_get_sql_all_with_filter (RygelLMSCategoryContainer* base, const gchar* filter);
++static gchar* rygel_lms_albums_real_get_sql_count_with_filter (RygelLMSCategoryContainer* base, const gchar* filter);
++static guint rygel_lms_albums_real_get_child_count_with_filter (RygelLMSCategoryContainer* base, const gchar* where_filter, GValueArray* args);
++guint rygel_lms_category_container_get_child_count_with_filter (RygelLMSCategoryContainer* self, const gchar* where_filter, GValueArray* args);
++gpointer rygel_lms_database_ref (gpointer instance);
++void rygel_lms_database_unref (gpointer instance);
++GParamSpec* rygel_lms_param_spec_database (const gchar* name, const gchar* nick, const gchar* blurb, GType object_type, GParamFlags flags);
++void rygel_lms_value_set_database (GValue* value, gpointer v_object);
++void rygel_lms_value_take_database (GValue* value, gpointer v_object);
++gpointer rygel_lms_value_get_database (const GValue* value);
++GType rygel_lms_database_get_type (void) G_GNUC_CONST;
++RygelLMSDatabase* rygel_lms_category_container_get_lms_db (RygelLMSCategoryContainer* self);
++GQuark rygel_lms_database_error_quark (void);
++sqlite3_stmt* rygel_lms_database_prepare_and_init (RygelLMSDatabase* self, const gchar* query, GValue* arguments, int arguments_length1, GError** error);
++static RygelMediaObjects* rygel_lms_albums_real_get_children_with_filter (RygelLMSCategoryContainer* base, const gchar* where_filter, GValueArray* args, const gchar* sort_criteria, guint offset, guint max_count);
++RygelMediaObjects* rygel_lms_category_container_get_children_with_filter (RygelLMSCategoryContainer* self, const gchar* where_filter, GValueArray* args, const gchar* sort_criteria, guint offset, guint max_count);
++gboolean rygel_lms_database_get_children_step (sqlite3_stmt* stmt, GError** error);
++GType rygel_lms_album_get_type (void) G_GNUC_CONST;
++RygelLMSAlbum* rygel_lms_album_new (const gchar* db_id, RygelMediaContainer* parent, const gchar* title, RygelLMSDatabase* lms_db);
++RygelLMSAlbum* rygel_lms_album_construct (GType object_type, const gchar* db_id, RygelMediaContainer* parent, const gchar* title, RygelLMSDatabase* lms_db);
++RygelMediaObject* rygel_lms_category_container_object_from_statement (RygelLMSCategoryContainer* self, sqlite3_stmt* statement);
++static RygelMediaObject* rygel_lms_albums_real_object_from_statement (RygelLMSCategoryContainer* base, sqlite3_stmt* statement);
++RygelLMSAlbums* rygel_lms_albums_new (RygelMediaContainer* parent, RygelLMSDatabase* lms_db);
++RygelLMSAlbums* rygel_lms_albums_construct (GType object_type, RygelMediaContainer* parent, RygelLMSDatabase* lms_db);
++RygelLMSCategoryContainer* rygel_lms_category_container_construct (GType object_type, const gchar* db_id, RygelMediaContainer* parent, const gchar* title, RygelLMSDatabase* lms_db, const gchar* sql_all, const gchar* sql_find_object, const gchar* sql_count, const gchar* sql_added, const gchar* sql_removed);
++
++
++static gchar* rygel_lms_albums_real_get_sql_all_with_filter (RygelLMSCategoryContainer* base, const gchar* filter) {
++	RygelLMSAlbums * self;
++	gchar* result = NULL;
++	const gchar* _tmp0_ = NULL;
++	gint _tmp1_ = 0;
++	gint _tmp2_ = 0;
++	const gchar* _tmp4_ = NULL;
++	gchar* _tmp5_ = NULL;
++	self = (RygelLMSAlbums*) base;
++	g_return_val_if_fail (filter != NULL, NULL);
++	_tmp0_ = filter;
++	_tmp1_ = strlen (_tmp0_);
++	_tmp2_ = _tmp1_;
++	if (_tmp2_ == 0) {
++		gchar* _tmp3_ = NULL;
++		_tmp3_ = g_strdup (RYGEL_LMS_ALBUMS_SQL_ALL);
++		result = _tmp3_;
++		return result;
++	}
++	_tmp4_ = filter;
++	_tmp5_ = g_strdup_printf (RYGEL_LMS_ALBUMS_SQL_ALL_WITH_FILTER_TEMPLATE, _tmp4_);
++	result = _tmp5_;
++	return result;
++}
++
++
++static gchar* rygel_lms_albums_real_get_sql_count_with_filter (RygelLMSCategoryContainer* base, const gchar* filter) {
++	RygelLMSAlbums * self;
++	gchar* result = NULL;
++	const gchar* _tmp0_ = NULL;
++	gint _tmp1_ = 0;
++	gint _tmp2_ = 0;
++	const gchar* _tmp4_ = NULL;
++	gchar* _tmp5_ = NULL;
++	self = (RygelLMSAlbums*) base;
++	g_return_val_if_fail (filter != NULL, NULL);
++	_tmp0_ = filter;
++	_tmp1_ = strlen (_tmp0_);
++	_tmp2_ = _tmp1_;
++	if (_tmp2_ == 0) {
++		gchar* _tmp3_ = NULL;
++		_tmp3_ = g_strdup (RYGEL_LMS_ALBUMS_SQL_COUNT);
++		result = _tmp3_;
++		return result;
++	}
++	_tmp4_ = filter;
++	_tmp5_ = g_strdup_printf (RYGEL_LMS_ALBUMS_SQL_COUNT_WITH_FILTER_TEMPLATE, _tmp4_);
++	result = _tmp5_;
++	return result;
++}
++
++
++static guint rygel_lms_albums_real_get_child_count_with_filter (RygelLMSCategoryContainer* base, const gchar* where_filter, GValueArray* args) {
++	RygelLMSAlbums * self;
++	guint result = 0U;
++	guint count = 0U;
++	const gchar* _tmp0_ = NULL;
++	GValueArray* _tmp1_ = NULL;
++	guint _tmp2_ = 0U;
++	gchar* filter = NULL;
++	gchar* _tmp3_ = NULL;
++	const gchar* _tmp4_ = NULL;
++	gint _tmp5_ = 0;
++	gint _tmp6_ = 0;
++	gchar* query = NULL;
++	const gchar* _tmp9_ = NULL;
++	gchar* _tmp10_ = NULL;
++	GError * _inner_error_ = NULL;
++	self = (RygelLMSAlbums*) base;
++	g_return_val_if_fail (where_filter != NULL, 0U);
++	g_return_val_if_fail (args != NULL, 0U);
++	_tmp0_ = where_filter;
++	_tmp1_ = args;
++	_tmp2_ = RYGEL_LMS_CATEGORY_CONTAINER_CLASS (rygel_lms_albums_parent_class)->get_child_count_with_filter (G_TYPE_CHECK_INSTANCE_CAST (self, RYGEL_LMS_TYPE_CATEGORY_CONTAINER, RygelLMSCategoryContainer), _tmp0_, _tmp1_);
++	count = _tmp2_;
++	_tmp3_ = g_strdup ("");
++	filter = _tmp3_;
++	_tmp4_ = where_filter;
++	_tmp5_ = strlen (_tmp4_);
++	_tmp6_ = _tmp5_;
++	if (_tmp6_ > 0) {
++		const gchar* _tmp7_ = NULL;
++		gchar* _tmp8_ = NULL;
++		_tmp7_ = where_filter;
++		_tmp8_ = g_strdup_printf ("AND %s", _tmp7_);
++		_g_free0 (filter);
++		filter = _tmp8_;
++	}
++	_tmp9_ = filter;
++	_tmp10_ = g_strdup_printf (RYGEL_LMS_ALBUMS_SQL_CHILD_COUNT_WITH_FILTER_TEMPLATE, _tmp9_);
++	query = _tmp10_;
++	{
++		sqlite3_stmt* stmt = NULL;
++		RygelLMSDatabase* _tmp11_ = NULL;
++		RygelLMSDatabase* _tmp12_ = NULL;
++		GValueArray* _tmp13_ = NULL;
++		GValue* _tmp14_ = NULL;
++		gint _tmp14__length1 = 0;
++		sqlite3_stmt* _tmp15_ = NULL;
++		gint _tmp16_ = 0;
++		_tmp11_ = rygel_lms_category_container_get_lms_db ((RygelLMSCategoryContainer*) self);
++		_tmp12_ = _tmp11_;
++		_tmp13_ = args;
++		_tmp14_ = _tmp13_->values;
++		_tmp14__length1 = (gint) _tmp13_->n_values;
++		_tmp15_ = rygel_lms_database_prepare_and_init (_tmp12_, query, _tmp14_, _tmp14__length1, &_inner_error_);
++		stmt = _tmp15_;
++		if (G_UNLIKELY (_inner_error_ != NULL)) {
++			if (_inner_error_->domain == RYGEL_LMS_DATABASE_ERROR) {
++				goto __catch8_rygel_lms_database_error;
++			}
++			_g_free0 (query);
++			_g_free0 (filter);
++			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 0U;
++		}
++		_tmp16_ = sqlite3_step (stmt);
++		if (_tmp16_ == SQLITE_ROW) {
++			guint _tmp17_ = 0U;
++			gint _tmp18_ = 0;
++			_tmp17_ = count;
++			_tmp18_ = sqlite3_column_int (stmt, 0);
++			count = _tmp17_ + _tmp18_;
++		}
++		_sqlite3_finalize0 (stmt);
++	}
++	goto __finally8;
++	__catch8_rygel_lms_database_error:
++	{
++		GError* e = NULL;
++		GError* _tmp19_ = NULL;
++		const gchar* _tmp20_ = NULL;
++		e = _inner_error_;
++		_inner_error_ = NULL;
++		_tmp19_ = e;
++		_tmp20_ = _tmp19_->message;
++		g_warning ("rygel-lms-albums.vala:116: Query failed: %s", _tmp20_);
++		_g_error_free0 (e);
++	}
++	__finally8:
++	if (G_UNLIKELY (_inner_error_ != NULL)) {
++		_g_free0 (query);
++		_g_free0 (filter);
++		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 0U;
++	}
++	result = count;
++	_g_free0 (query);
++	_g_free0 (filter);
++	return result;
++}
++
++
++static RygelMediaObjects* rygel_lms_albums_real_get_children_with_filter (RygelLMSCategoryContainer* base, const gchar* where_filter, GValueArray* args, const gchar* sort_criteria, guint offset, guint max_count) {
++	RygelLMSAlbums * self;
++	RygelMediaObjects* result = NULL;
++	RygelMediaObjects* children = NULL;
++	const gchar* _tmp0_ = NULL;
++	GValueArray* _tmp1_ = NULL;
++	const gchar* _tmp2_ = NULL;
++	guint _tmp3_ = 0U;
++	guint _tmp4_ = 0U;
++	RygelMediaObjects* _tmp5_ = NULL;
++	gchar* filter = NULL;
++	gchar* _tmp6_ = NULL;
++	const gchar* _tmp7_ = NULL;
++	gint _tmp8_ = 0;
++	gint _tmp9_ = 0;
++	gchar* query = NULL;
++	const gchar* _tmp12_ = NULL;
++	gchar* _tmp13_ = NULL;
++	GError * _inner_error_ = NULL;
++	self = (RygelLMSAlbums*) base;
++	g_return_val_if_fail (where_filter != NULL, NULL);
++	g_return_val_if_fail (args != NULL, NULL);
++	g_return_val_if_fail (sort_criteria != NULL, NULL);
++	_tmp0_ = where_filter;
++	_tmp1_ = args;
++	_tmp2_ = sort_criteria;
++	_tmp3_ = offset;
++	_tmp4_ = max_count;
++	_tmp5_ = RYGEL_LMS_CATEGORY_CONTAINER_CLASS (rygel_lms_albums_parent_class)->get_children_with_filter (G_TYPE_CHECK_INSTANCE_CAST (self, RYGEL_LMS_TYPE_CATEGORY_CONTAINER, RygelLMSCategoryContainer), _tmp0_, _tmp1_, _tmp2_, _tmp3_, _tmp4_);
++	children = _tmp5_;
++	_tmp6_ = g_strdup ("");
++	filter = _tmp6_;
++	_tmp7_ = where_filter;
++	_tmp8_ = strlen (_tmp7_);
++	_tmp9_ = _tmp8_;
++	if (_tmp9_ > 0) {
++		const gchar* _tmp10_ = NULL;
++		gchar* _tmp11_ = NULL;
++		_tmp10_ = where_filter;
++		_tmp11_ = g_strdup_printf ("AND %s", _tmp10_);
++		_g_free0 (filter);
++		filter = _tmp11_;
++	}
++	_tmp12_ = filter;
++	_tmp13_ = g_strdup_printf (RYGEL_LMS_ALBUMS_SQL_CHILD_ALL_WITH_FILTER_TEMPLATE, _tmp12_);
++	query = _tmp13_;
++	{
++		sqlite3_stmt* stmt = NULL;
++		RygelLMSDatabase* _tmp14_ = NULL;
++		RygelLMSDatabase* _tmp15_ = NULL;
++		const gchar* _tmp16_ = NULL;
++		GValueArray* _tmp17_ = NULL;
++		GValue* _tmp18_ = NULL;
++		gint _tmp18__length1 = 0;
++		sqlite3_stmt* _tmp19_ = NULL;
++		_tmp14_ = rygel_lms_category_container_get_lms_db ((RygelLMSCategoryContainer*) self);
++		_tmp15_ = _tmp14_;
++		_tmp16_ = query;
++		_tmp17_ = args;
++		_tmp18_ = _tmp17_->values;
++		_tmp18__length1 = (gint) _tmp17_->n_values;
++		_tmp19_ = rygel_lms_database_prepare_and_init (_tmp15_, _tmp16_, _tmp18_, _tmp18__length1, &_inner_error_);
++		stmt = _tmp19_;
++		if (G_UNLIKELY (_inner_error_ != NULL)) {
++			if (_inner_error_->domain == RYGEL_LMS_DATABASE_ERROR) {
++				goto __catch9_rygel_lms_database_error;
++			}
++			_g_free0 (query);
++			_g_free0 (filter);
++			_g_object_unref0 (children);
++			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;
++		}
++		while (TRUE) {
++			gboolean _tmp20_ = FALSE;
++			sqlite3_stmt* _tmp21_ = NULL;
++			gboolean _tmp22_ = FALSE;
++			gchar* album_id = NULL;
++			sqlite3_stmt* _tmp23_ = NULL;
++			const gchar* _tmp24_ = NULL;
++			gchar* _tmp25_ = NULL;
++			RygelLMSAlbum* album = NULL;
++			const gchar* _tmp26_ = NULL;
++			RygelLMSDatabase* _tmp27_ = NULL;
++			RygelLMSDatabase* _tmp28_ = NULL;
++			RygelLMSAlbum* _tmp29_ = NULL;
++			RygelMediaObject* song = NULL;
++			RygelLMSAlbum* _tmp30_ = NULL;
++			sqlite3_stmt* _tmp31_ = NULL;
++			RygelMediaObject* _tmp32_ = NULL;
++			RygelMediaObject* _tmp33_ = NULL;
++			RygelMediaObject* _tmp34_ = NULL;
++			RygelMediaContainer* _tmp35_ = NULL;
++			RygelMediaContainer* _tmp36_ = NULL;
++			RygelMediaObjects* _tmp37_ = NULL;
++			RygelMediaObject* _tmp38_ = NULL;
++			_tmp21_ = stmt;
++			_tmp22_ = rygel_lms_database_get_children_step (_tmp21_, &_inner_error_);
++			_tmp20_ = _tmp22_;
++			if (G_UNLIKELY (_inner_error_ != NULL)) {
++				_sqlite3_finalize0 (stmt);
++				if (_inner_error_->domain == RYGEL_LMS_DATABASE_ERROR) {
++					goto __catch9_rygel_lms_database_error;
++				}
++				_sqlite3_finalize0 (stmt);
++				_g_free0 (query);
++				_g_free0 (filter);
++				_g_object_unref0 (children);
++				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;
++			}
++			if (!_tmp20_) {
++				break;
++			}
++			_tmp23_ = stmt;
++			_tmp24_ = sqlite3_column_text (_tmp23_, 13);
++			_tmp25_ = g_strdup (_tmp24_);
++			album_id = _tmp25_;
++			_tmp26_ = album_id;
++			_tmp27_ = rygel_lms_category_container_get_lms_db ((RygelLMSCategoryContainer*) self);
++			_tmp28_ = _tmp27_;
++			_tmp29_ = rygel_lms_album_new (_tmp26_, (RygelMediaContainer*) self, "", _tmp28_);
++			album = _tmp29_;
++			_tmp30_ = album;
++			_tmp31_ = stmt;
++			_tmp32_ = rygel_lms_category_container_object_from_statement ((RygelLMSCategoryContainer*) _tmp30_, _tmp31_);
++			song = _tmp32_;
++			_tmp33_ = song;
++			_tmp34_ = song;
++			_tmp35_ = rygel_media_object_get_parent (_tmp34_);
++			_tmp36_ = _tmp35_;
++			rygel_media_object_set_parent_ref (_tmp33_, _tmp36_);
++			_tmp37_ = children;
++			_tmp38_ = song;
++			gee_abstract_collection_add ((GeeAbstractCollection*) _tmp37_, _tmp38_);
++			_g_object_unref0 (song);
++			_g_object_unref0 (album);
++			_g_free0 (album_id);
++		}
++		_sqlite3_finalize0 (stmt);
++	}
++	goto __finally9;
++	__catch9_rygel_lms_database_error:
++	{
++		GError* e = NULL;
++		GError* _tmp39_ = NULL;
++		const gchar* _tmp40_ = NULL;
++		e = _inner_error_;
++		_inner_error_ = NULL;
++		_tmp39_ = e;
++		_tmp40_ = _tmp39_->message;
++		g_warning ("rygel-lms-albums.vala:149: Query failed: %s", _tmp40_);
++		_g_error_free0 (e);
++	}
++	__finally9:
++	if (G_UNLIKELY (_inner_error_ != NULL)) {
++		_g_free0 (query);
++		_g_free0 (filter);
++		_g_object_unref0 (children);
++		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;
++	}
++	result = children;
++	_g_free0 (query);
++	_g_free0 (filter);
++	return result;
++}
++
++
++static RygelMediaObject* rygel_lms_albums_real_object_from_statement (RygelLMSCategoryContainer* base, sqlite3_stmt* statement) {
++	RygelLMSAlbums * self;
++	RygelMediaObject* result = NULL;
++	gchar* id = NULL;
++	sqlite3_stmt* _tmp0_ = NULL;
++	gint _tmp1_ = 0;
++	gchar* _tmp2_ = NULL;
++	RygelLMSAlbum* album = NULL;
++	sqlite3_stmt* _tmp3_ = NULL;
++	const gchar* _tmp4_ = NULL;
++	RygelLMSDatabase* _tmp5_ = NULL;
++	RygelLMSDatabase* _tmp6_ = NULL;
++	RygelLMSAlbum* _tmp7_ = NULL;
++	self = (RygelLMSAlbums*) base;
++	g_return_val_if_fail (statement != NULL, NULL);
++	_tmp0_ = statement;
++	_tmp1_ = sqlite3_column_int (_tmp0_, 0);
++	_tmp2_ = g_strdup_printf ("%d", _tmp1_);
++	id = _tmp2_;
++	_tmp3_ = statement;
++	_tmp4_ = sqlite3_column_text (_tmp3_, 1);
++	_tmp5_ = rygel_lms_category_container_get_lms_db ((RygelLMSCategoryContainer*) self);
++	_tmp6_ = _tmp5_;
++	_tmp7_ = rygel_lms_album_new (id, (RygelMediaContainer*) self, _tmp4_, _tmp6_);
++	album = _tmp7_;
++	result = (RygelMediaObject*) album;
++	_g_free0 (id);
++	return result;
++}
++
++
++RygelLMSAlbums* rygel_lms_albums_construct (GType object_type, RygelMediaContainer* parent, RygelLMSDatabase* lms_db) {
++	RygelLMSAlbums * self = NULL;
++	RygelMediaContainer* _tmp0_ = NULL;
++	const gchar* _tmp1_ = NULL;
++	RygelLMSDatabase* _tmp2_ = NULL;
++	g_return_val_if_fail (parent != NULL, NULL);
++	g_return_val_if_fail (lms_db != NULL, NULL);
++	_tmp0_ = parent;
++	_tmp1_ = _ ("Albums");
++	_tmp2_ = lms_db;
++	self = (RygelLMSAlbums*) rygel_lms_category_container_construct (object_type, "albums", _tmp0_, _tmp1_, _tmp2_, RYGEL_LMS_ALBUMS_SQL_ALL, RYGEL_LMS_ALBUMS_SQL_FIND_OBJECT, RYGEL_LMS_ALBUMS_SQL_COUNT, NULL, NULL);
++	return self;
++}
++
++
++RygelLMSAlbums* rygel_lms_albums_new (RygelMediaContainer* parent, RygelLMSDatabase* lms_db) {
++	return rygel_lms_albums_construct (RYGEL_LMS_TYPE_ALBUMS, parent, lms_db);
++}
++
++
++static void rygel_lms_albums_class_init (RygelLMSAlbumsClass * klass) {
++	rygel_lms_albums_parent_class = g_type_class_peek_parent (klass);
++	((RygelLMSCategoryContainerClass *) klass)->get_sql_all_with_filter = rygel_lms_albums_real_get_sql_all_with_filter;
++	((RygelLMSCategoryContainerClass *) klass)->get_sql_count_with_filter = rygel_lms_albums_real_get_sql_count_with_filter;
++	((RygelLMSCategoryContainerClass *) klass)->get_child_count_with_filter = rygel_lms_albums_real_get_child_count_with_filter;
++	((RygelLMSCategoryContainerClass *) klass)->get_children_with_filter = rygel_lms_albums_real_get_children_with_filter;
++	((RygelLMSCategoryContainerClass *) klass)->object_from_statement = rygel_lms_albums_real_object_from_statement;
++}
++
++
++static void rygel_lms_albums_instance_init (RygelLMSAlbums * self) {
++}
++
++
++GType rygel_lms_albums_get_type (void) {
++	static volatile gsize rygel_lms_albums_type_id__volatile = 0;
++	if (g_once_init_enter (&rygel_lms_albums_type_id__volatile)) {
++		static const GTypeInfo g_define_type_info = { sizeof (RygelLMSAlbumsClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) rygel_lms_albums_class_init, (GClassFinalizeFunc) NULL, NULL, sizeof (RygelLMSAlbums), 0, (GInstanceInitFunc) rygel_lms_albums_instance_init, NULL };
++		GType rygel_lms_albums_type_id;
++		rygel_lms_albums_type_id = g_type_register_static (RYGEL_LMS_TYPE_CATEGORY_CONTAINER, "RygelLMSAlbums", &g_define_type_info, 0);
++		g_once_init_leave (&rygel_lms_albums_type_id__volatile, rygel_lms_albums_type_id);
++	}
++	return rygel_lms_albums_type_id__volatile;
++}
++
++
++
+diff --git a/src/plugins/lms/rygel-lms-all-images.c b/src/plugins/lms/rygel-lms-all-images.c
+new file mode 100644
+index 0000000..33fb8c1
+--- /dev/null
++++ b/src/plugins/lms/rygel-lms-all-images.c
+@@ -0,0 +1,305 @@
++/* rygel-lms-all-images.c generated by valac 0.28.0, the Vala compiler
++ * generated from rygel-lms-all-images.vala, do not modify */
++
++/*
++ * Copyright (C) 2013 Intel Corporation.
++ *
++ * Author: Jussi Kukkonen <jussi.kukkonen@intel.com>
++ *
++ * 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 <glib.h>
++#include <glib-object.h>
++#include <rygel-server.h>
++#include <sqlite3.h>
++#include <stdlib.h>
++#include <string.h>
++#include <gio/gio.h>
++#include <glib/gi18n-lib.h>
++
++
++#define RYGEL_LMS_TYPE_CATEGORY_CONTAINER (rygel_lms_category_container_get_type ())
++#define RYGEL_LMS_CATEGORY_CONTAINER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), RYGEL_LMS_TYPE_CATEGORY_CONTAINER, RygelLMSCategoryContainer))
++#define RYGEL_LMS_CATEGORY_CONTAINER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), RYGEL_LMS_TYPE_CATEGORY_CONTAINER, RygelLMSCategoryContainerClass))
++#define RYGEL_LMS_IS_CATEGORY_CONTAINER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), RYGEL_LMS_TYPE_CATEGORY_CONTAINER))
++#define RYGEL_LMS_IS_CATEGORY_CONTAINER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), RYGEL_LMS_TYPE_CATEGORY_CONTAINER))
++#define RYGEL_LMS_CATEGORY_CONTAINER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), RYGEL_LMS_TYPE_CATEGORY_CONTAINER, RygelLMSCategoryContainerClass))
++
++typedef struct _RygelLMSCategoryContainer RygelLMSCategoryContainer;
++typedef struct _RygelLMSCategoryContainerClass RygelLMSCategoryContainerClass;
++typedef struct _RygelLMSCategoryContainerPrivate RygelLMSCategoryContainerPrivate;
++
++#define RYGEL_LMS_TYPE_ALL_IMAGES (rygel_lms_all_images_get_type ())
++#define RYGEL_LMS_ALL_IMAGES(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), RYGEL_LMS_TYPE_ALL_IMAGES, RygelLMSAllImages))
++#define RYGEL_LMS_ALL_IMAGES_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), RYGEL_LMS_TYPE_ALL_IMAGES, RygelLMSAllImagesClass))
++#define RYGEL_LMS_IS_ALL_IMAGES(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), RYGEL_LMS_TYPE_ALL_IMAGES))
++#define RYGEL_LMS_IS_ALL_IMAGES_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), RYGEL_LMS_TYPE_ALL_IMAGES))
++#define RYGEL_LMS_ALL_IMAGES_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), RYGEL_LMS_TYPE_ALL_IMAGES, RygelLMSAllImagesClass))
++
++typedef struct _RygelLMSAllImages RygelLMSAllImages;
++typedef struct _RygelLMSAllImagesClass RygelLMSAllImagesClass;
++typedef struct _RygelLMSAllImagesPrivate RygelLMSAllImagesPrivate;
++#define _g_free0(var) (var = (g_free (var), NULL))
++#define _g_object_unref0(var) ((var == NULL) ? NULL : (var = (g_object_unref (var), NULL)))
++
++#define RYGEL_LMS_TYPE_DATABASE (rygel_lms_database_get_type ())
++#define RYGEL_LMS_DATABASE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), RYGEL_LMS_TYPE_DATABASE, RygelLMSDatabase))
++#define RYGEL_LMS_DATABASE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), RYGEL_LMS_TYPE_DATABASE, RygelLMSDatabaseClass))
++#define RYGEL_LMS_IS_DATABASE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), RYGEL_LMS_TYPE_DATABASE))
++#define RYGEL_LMS_IS_DATABASE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), RYGEL_LMS_TYPE_DATABASE))
++#define RYGEL_LMS_DATABASE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), RYGEL_LMS_TYPE_DATABASE, RygelLMSDatabaseClass))
++
++typedef struct _RygelLMSDatabase RygelLMSDatabase;
++typedef struct _RygelLMSDatabaseClass RygelLMSDatabaseClass;
++
++struct _RygelLMSCategoryContainer {
++	RygelMediaContainer parent_instance;
++	RygelLMSCategoryContainerPrivate * priv;
++	sqlite3_stmt* stmt_all;
++	sqlite3_stmt* stmt_find_object;
++	sqlite3_stmt* stmt_added;
++	sqlite3_stmt* stmt_removed;
++	gchar* child_prefix;
++	gchar* ref_prefix;
++};
++
++struct _RygelLMSCategoryContainerClass {
++	RygelMediaContainerClass parent_class;
++	RygelMediaObject* (*object_from_statement) (RygelLMSCategoryContainer* self, sqlite3_stmt* statement);
++	gchar* (*get_sql_all_with_filter) (RygelLMSCategoryContainer* self, const gchar* filter);
++	gchar* (*get_sql_count_with_filter) (RygelLMSCategoryContainer* self, const gchar* filter);
++	guint (*get_child_count_with_filter) (RygelLMSCategoryContainer* self, const gchar* where_filter, GValueArray* args);
++	RygelMediaObjects* (*get_children_with_filter) (RygelLMSCategoryContainer* self, const gchar* where_filter, GValueArray* args, const gchar* sort_criteria, guint offset, guint max_count);
++};
++
++struct _RygelLMSAllImages {
++	RygelLMSCategoryContainer parent_instance;
++	RygelLMSAllImagesPrivate * priv;
++};
++
++struct _RygelLMSAllImagesClass {
++	RygelLMSCategoryContainerClass parent_class;
++};
++
++
++static gpointer rygel_lms_all_images_parent_class = NULL;
++
++GType rygel_lms_category_container_get_type (void) G_GNUC_CONST;
++GType rygel_lms_all_images_get_type (void) G_GNUC_CONST;
++enum  {
++	RYGEL_LMS_ALL_IMAGES_DUMMY_PROPERTY
++};
++#define RYGEL_LMS_ALL_IMAGES_SQL_ALL "SELECT images.id, title, artist, date, width, height, path, size, dlna" \
++"_profile, dlna_mime " "FROM images, files " "WHERE dtime = 0 AND images.id = files.id " "LIMIT ? OFFSET ?;"
++#define RYGEL_LMS_ALL_IMAGES_SQL_COUNT "SELECT count(images.id) " "FROM images, files " "WHERE dtime = 0 AND images.id = files.id;"
++#define RYGEL_LMS_ALL_IMAGES_SQL_FIND_OBJECT "SELECT images.id, title, artist, date, width, height, path, size, dlna" \
++"_profile, dlna_mime " "FROM images, files " "WHERE dtime = 0 AND files.id = ? AND images.id = files.id;"
++#define RYGEL_LMS_ALL_IMAGES_SQL_ADDED "SELECT images.id, title, artist, date, width, height, path, size, dlna" \
++"_profile, dlna_mime " "FROM images, files " "WHERE dtime = 0 AND images.id = files.id " "AND update_id > ? AND update_id <= ?;"
++#define RYGEL_LMS_ALL_IMAGES_SQL_REMOVED "SELECT images.id, title, artist, date, width, height, path, size, dlna" \
++"_profile, dlna_mime " "FROM images, files " "WHERE dtime <> 0 AND images.id = files.id " "AND update_id > ? AND update_id <= ?;"
++static RygelMediaObject* rygel_lms_all_images_real_object_from_statement (RygelLMSCategoryContainer* base, sqlite3_stmt* statement);
++gchar* rygel_lms_category_container_build_child_id (RygelLMSCategoryContainer* self, gint db_id);
++gpointer rygel_lms_database_ref (gpointer instance);
++void rygel_lms_database_unref (gpointer instance);
++GParamSpec* rygel_lms_param_spec_database (const gchar* name, const gchar* nick, const gchar* blurb, GType object_type, GParamFlags flags);
++void rygel_lms_value_set_database (GValue* value, gpointer v_object);
++void rygel_lms_value_take_database (GValue* value, gpointer v_object);
++gpointer rygel_lms_value_get_database (const GValue* value);
++GType rygel_lms_database_get_type (void) G_GNUC_CONST;
++RygelLMSAllImages* rygel_lms_all_images_new (RygelMediaContainer* parent, RygelLMSDatabase* lms_db);
++RygelLMSAllImages* rygel_lms_all_images_construct (GType object_type, RygelMediaContainer* parent, RygelLMSDatabase* lms_db);
++RygelLMSCategoryContainer* rygel_lms_category_container_construct (GType object_type, const gchar* db_id, RygelMediaContainer* parent, const gchar* title, RygelLMSDatabase* lms_db, const gchar* sql_all, const gchar* sql_find_object, const gchar* sql_count, const gchar* sql_added, const gchar* sql_removed);
++
++
++static RygelMediaObject* rygel_lms_all_images_real_object_from_statement (RygelLMSCategoryContainer* base, sqlite3_stmt* statement) {
++	RygelLMSAllImages * self;
++	RygelMediaObject* result = NULL;
++	gint id = 0;
++	sqlite3_stmt* _tmp0_ = NULL;
++	gint _tmp1_ = 0;
++	gchar* path = NULL;
++	sqlite3_stmt* _tmp2_ = NULL;
++	const gchar* _tmp3_ = NULL;
++	gchar* _tmp4_ = NULL;
++	gchar* mime_type = NULL;
++	sqlite3_stmt* _tmp5_ = NULL;
++	const gchar* _tmp6_ = NULL;
++	gchar* _tmp7_ = NULL;
++	gboolean _tmp8_ = FALSE;
++	const gchar* _tmp9_ = NULL;
++	gchar* title = NULL;
++	sqlite3_stmt* _tmp15_ = NULL;
++	const gchar* _tmp16_ = NULL;
++	gchar* _tmp17_ = NULL;
++	RygelImageItem* image = NULL;
++	gint _tmp18_ = 0;
++	gchar* _tmp19_ = NULL;
++	gchar* _tmp20_ = NULL;
++	RygelImageItem* _tmp21_ = NULL;
++	RygelImageItem* _tmp22_ = NULL;
++	sqlite3_stmt* _tmp23_ = NULL;
++	const gchar* _tmp24_ = NULL;
++	GTimeVal tv = {0};
++	sqlite3_stmt* _tmp25_ = NULL;
++	gint _tmp26_ = 0;
++	GTimeVal _tmp27_ = {0};
++	gchar* _tmp28_ = NULL;
++	gchar* _tmp29_ = NULL;
++	sqlite3_stmt* _tmp30_ = NULL;
++	gint _tmp31_ = 0;
++	sqlite3_stmt* _tmp32_ = NULL;
++	gint _tmp33_ = 0;
++	sqlite3_stmt* _tmp34_ = NULL;
++	gint _tmp35_ = 0;
++	const gchar* _tmp36_ = NULL;
++	sqlite3_stmt* _tmp37_ = NULL;
++	const gchar* _tmp38_ = NULL;
++	GFile* file = NULL;
++	const gchar* _tmp39_ = NULL;
++	GFile* _tmp40_ = NULL;
++	gchar* _tmp41_ = NULL;
++	gchar* _tmp42_ = NULL;
++	self = (RygelLMSAllImages*) base;
++	g_return_val_if_fail (statement != NULL, NULL);
++	_tmp0_ = statement;
++	_tmp1_ = sqlite3_column_int (_tmp0_, 0);
++	id = _tmp1_;
++	_tmp2_ = statement;
++	_tmp3_ = sqlite3_column_text (_tmp2_, 6);
++	_tmp4_ = g_strdup (_tmp3_);
++	path = _tmp4_;
++	_tmp5_ = statement;
++	_tmp6_ = sqlite3_column_text (_tmp5_, 9);
++	_tmp7_ = g_strdup (_tmp6_);
++	mime_type = _tmp7_;
++	_tmp9_ = mime_type;
++	if (_tmp9_ == NULL) {
++		_tmp8_ = TRUE;
++	} else {
++		const gchar* _tmp10_ = NULL;
++		gint _tmp11_ = 0;
++		gint _tmp12_ = 0;
++		_tmp10_ = mime_type;
++		_tmp11_ = strlen (_tmp10_);
++		_tmp12_ = _tmp11_;
++		_tmp8_ = _tmp12_ == 0;
++	}
++	if (_tmp8_) {
++		gint _tmp13_ = 0;
++		const gchar* _tmp14_ = NULL;
++		_tmp13_ = id;
++		_tmp14_ = path;
++		g_debug ("rygel-lms-all-images.vala:62: Image item %d (%s) has no MIME type", _tmp13_, _tmp14_);
++	}
++	_tmp15_ = statement;
++	_tmp16_ = sqlite3_column_text (_tmp15_, 1);
++	_tmp17_ = g_strdup (_tmp16_);
++	title = _tmp17_;
++	_tmp18_ = id;
++	_tmp19_ = rygel_lms_category_container_build_child_id ((RygelLMSCategoryContainer*) self, _tmp18_);
++	_tmp20_ = _tmp19_;
++	_tmp21_ = rygel_image_item_new (_tmp20_, (RygelMediaContainer*) self, title, RYGEL_IMAGE_ITEM_UPNP_CLASS);
++	_tmp22_ = _tmp21_;
++	_g_free0 (_tmp20_);
++	image = _tmp22_;
++	_tmp23_ = statement;
++	_tmp24_ = sqlite3_column_text (_tmp23_, 2);
++	rygel_media_object_set_creator ((RygelMediaObject*) image, _tmp24_);
++	_tmp25_ = statement;
++	_tmp26_ = sqlite3_column_int (_tmp25_, 3);
++	_tmp27_.tv_sec = (glong) _tmp26_;
++	_tmp27_.tv_usec = (glong) 0;
++	tv = _tmp27_;
++	_tmp28_ = g_time_val_to_iso8601 (&tv);
++	_tmp29_ = _tmp28_;
++	rygel_media_object_set_date ((RygelMediaObject*) image, _tmp29_);
++	_g_free0 (_tmp29_);
++	_tmp30_ = statement;
++	_tmp31_ = sqlite3_column_int (_tmp30_, 4);
++	rygel_visual_item_set_width ((RygelVisualItem*) image, _tmp31_);
++	_tmp32_ = statement;
++	_tmp33_ = sqlite3_column_int (_tmp32_, 5);
++	rygel_visual_item_set_height ((RygelVisualItem*) image, _tmp33_);
++	_tmp34_ = statement;
++	_tmp35_ = sqlite3_column_int (_tmp34_, 7);
++	rygel_media_file_item_set_size ((RygelMediaFileItem*) image, (gint64) _tmp35_);
++	_tmp36_ = mime_type;
++	rygel_media_file_item_set_mime_type ((RygelMediaFileItem*) image, _tmp36_);
++	_tmp37_ = statement;
++	_tmp38_ = sqlite3_column_text (_tmp37_, 8);
++	rygel_media_file_item_set_dlna_profile ((RygelMediaFileItem*) image, _tmp38_);
++	_tmp39_ = path;
++	_tmp40_ = g_file_new_for_path (_tmp39_);
++	file = _tmp40_;
++	_tmp41_ = g_file_get_uri (file);
++	_tmp42_ = _tmp41_;
++	rygel_media_object_add_uri ((RygelMediaObject*) image, _tmp42_);
++	_g_free0 (_tmp42_);
++	result = (RygelMediaObject*) image;
++	_g_object_unref0 (file);
++	_g_free0 (title);
++	_g_free0 (mime_type);
++	_g_free0 (path);
++	return result;
++}
++
++
++RygelLMSAllImages* rygel_lms_all_images_construct (GType object_type, RygelMediaContainer* parent, RygelLMSDatabase* lms_db) {
++	RygelLMSAllImages * self = NULL;
++	RygelMediaContainer* _tmp0_ = NULL;
++	const gchar* _tmp1_ = NULL;
++	RygelLMSDatabase* _tmp2_ = NULL;
++	g_return_val_if_fail (parent != NULL, NULL);
++	g_return_val_if_fail (lms_db != NULL, NULL);
++	_tmp0_ = parent;
++	_tmp1_ = _ ("All");
++	_tmp2_ = lms_db;
++	self = (RygelLMSAllImages*) rygel_lms_category_container_construct (object_type, "all", _tmp0_, _tmp1_, _tmp2_, RYGEL_LMS_ALL_IMAGES_SQL_ALL, RYGEL_LMS_ALL_IMAGES_SQL_FIND_OBJECT, RYGEL_LMS_ALL_IMAGES_SQL_COUNT, RYGEL_LMS_ALL_IMAGES_SQL_ADDED, RYGEL_LMS_ALL_IMAGES_SQL_REMOVED);
++	return self;
++}
++
++
++RygelLMSAllImages* rygel_lms_all_images_new (RygelMediaContainer* parent, RygelLMSDatabase* lms_db) {
++	return rygel_lms_all_images_construct (RYGEL_LMS_TYPE_ALL_IMAGES, parent, lms_db);
++}
++
++
++static void rygel_lms_all_images_class_init (RygelLMSAllImagesClass * klass) {
++	rygel_lms_all_images_parent_class = g_type_class_peek_parent (klass);
++	((RygelLMSCategoryContainerClass *) klass)->object_from_statement = rygel_lms_all_images_real_object_from_statement;
++}
++
++
++static void rygel_lms_all_images_instance_init (RygelLMSAllImages * self) {
++}
++
++
++GType rygel_lms_all_images_get_type (void) {
++	static volatile gsize rygel_lms_all_images_type_id__volatile = 0;
++	if (g_once_init_enter (&rygel_lms_all_images_type_id__volatile)) {
++		static const GTypeInfo g_define_type_info = { sizeof (RygelLMSAllImagesClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) rygel_lms_all_images_class_init, (GClassFinalizeFunc) NULL, NULL, sizeof (RygelLMSAllImages), 0, (GInstanceInitFunc) rygel_lms_all_images_instance_init, NULL };
++		GType rygel_lms_all_images_type_id;
++		rygel_lms_all_images_type_id = g_type_register_static (RYGEL_LMS_TYPE_CATEGORY_CONTAINER, "RygelLMSAllImages", &g_define_type_info, 0);
++		g_once_init_leave (&rygel_lms_all_images_type_id__volatile, rygel_lms_all_images_type_id);
++	}
++	return rygel_lms_all_images_type_id__volatile;
++}
++
++
++
+diff --git a/src/plugins/lms/rygel-lms-all-music.c b/src/plugins/lms/rygel-lms-all-music.c
+new file mode 100644
+index 0000000..ee6118f
+--- /dev/null
++++ b/src/plugins/lms/rygel-lms-all-music.c
+@@ -0,0 +1,417 @@
++/* rygel-lms-all-music.c generated by valac 0.28.0, the Vala compiler
++ * generated from rygel-lms-all-music.vala, do not modify */
++
++/*
++ * Copyright (C) 2013 Intel Corporation.
++ *
++ * Author: Jussi Kukkonen <jussi.kukkonen@intel.com>
++ *
++ * 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 <glib.h>
++#include <glib-object.h>
++#include <rygel-server.h>
++#include <sqlite3.h>
++#include <stdlib.h>
++#include <string.h>
++#include <gio/gio.h>
++#include <glib/gi18n-lib.h>
++
++
++#define RYGEL_LMS_TYPE_CATEGORY_CONTAINER (rygel_lms_category_container_get_type ())
++#define RYGEL_LMS_CATEGORY_CONTAINER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), RYGEL_LMS_TYPE_CATEGORY_CONTAINER, RygelLMSCategoryContainer))
++#define RYGEL_LMS_CATEGORY_CONTAINER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), RYGEL_LMS_TYPE_CATEGORY_CONTAINER, RygelLMSCategoryContainerClass))
++#define RYGEL_LMS_IS_CATEGORY_CONTAINER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), RYGEL_LMS_TYPE_CATEGORY_CONTAINER))
++#define RYGEL_LMS_IS_CATEGORY_CONTAINER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), RYGEL_LMS_TYPE_CATEGORY_CONTAINER))
++#define RYGEL_LMS_CATEGORY_CONTAINER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), RYGEL_LMS_TYPE_CATEGORY_CONTAINER, RygelLMSCategoryContainerClass))
++
++typedef struct _RygelLMSCategoryContainer RygelLMSCategoryContainer;
++typedef struct _RygelLMSCategoryContainerClass RygelLMSCategoryContainerClass;
++typedef struct _RygelLMSCategoryContainerPrivate RygelLMSCategoryContainerPrivate;
++
++#define RYGEL_LMS_TYPE_ALL_MUSIC (rygel_lms_all_music_get_type ())
++#define RYGEL_LMS_ALL_MUSIC(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), RYGEL_LMS_TYPE_ALL_MUSIC, RygelLMSAllMusic))
++#define RYGEL_LMS_ALL_MUSIC_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), RYGEL_LMS_TYPE_ALL_MUSIC, RygelLMSAllMusicClass))
++#define RYGEL_LMS_IS_ALL_MUSIC(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), RYGEL_LMS_TYPE_ALL_MUSIC))
++#define RYGEL_LMS_IS_ALL_MUSIC_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), RYGEL_LMS_TYPE_ALL_MUSIC))
++#define RYGEL_LMS_ALL_MUSIC_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), RYGEL_LMS_TYPE_ALL_MUSIC, RygelLMSAllMusicClass))
++
++typedef struct _RygelLMSAllMusic RygelLMSAllMusic;
++typedef struct _RygelLMSAllMusicClass RygelLMSAllMusicClass;
++typedef struct _RygelLMSAllMusicPrivate RygelLMSAllMusicPrivate;
++#define _g_free0(var) (var = (g_free (var), NULL))
++#define _g_object_unref0(var) ((var == NULL) ? NULL : (var = (g_object_unref (var), NULL)))
++
++#define RYGEL_LMS_TYPE_DATABASE (rygel_lms_database_get_type ())
++#define RYGEL_LMS_DATABASE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), RYGEL_LMS_TYPE_DATABASE, RygelLMSDatabase))
++#define RYGEL_LMS_DATABASE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), RYGEL_LMS_TYPE_DATABASE, RygelLMSDatabaseClass))
++#define RYGEL_LMS_IS_DATABASE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), RYGEL_LMS_TYPE_DATABASE))
++#define RYGEL_LMS_IS_DATABASE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), RYGEL_LMS_TYPE_DATABASE))
++#define RYGEL_LMS_DATABASE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), RYGEL_LMS_TYPE_DATABASE, RygelLMSDatabaseClass))
++
++typedef struct _RygelLMSDatabase RygelLMSDatabase;
++typedef struct _RygelLMSDatabaseClass RygelLMSDatabaseClass;
++
++struct _RygelLMSCategoryContainer {
++	RygelMediaContainer parent_instance;
++	RygelLMSCategoryContainerPrivate * priv;
++	sqlite3_stmt* stmt_all;
++	sqlite3_stmt* stmt_find_object;
++	sqlite3_stmt* stmt_added;
++	sqlite3_stmt* stmt_removed;
++	gchar* child_prefix;
++	gchar* ref_prefix;
++};
++
++struct _RygelLMSCategoryContainerClass {
++	RygelMediaContainerClass parent_class;
++	RygelMediaObject* (*object_from_statement) (RygelLMSCategoryContainer* self, sqlite3_stmt* statement);
++	gchar* (*get_sql_all_with_filter) (RygelLMSCategoryContainer* self, const gchar* filter);
++	gchar* (*get_sql_count_with_filter) (RygelLMSCategoryContainer* self, const gchar* filter);
++	guint (*get_child_count_with_filter) (RygelLMSCategoryContainer* self, const gchar* where_filter, GValueArray* args);
++	RygelMediaObjects* (*get_children_with_filter) (RygelLMSCategoryContainer* self, const gchar* where_filter, GValueArray* args, const gchar* sort_criteria, guint offset, guint max_count);
++};
++
++struct _RygelLMSAllMusic {
++	RygelLMSCategoryContainer parent_instance;
++	RygelLMSAllMusicPrivate * priv;
++};
++
++struct _RygelLMSAllMusicClass {
++	RygelLMSCategoryContainerClass parent_class;
++};
++
++
++static gpointer rygel_lms_all_music_parent_class = NULL;
++
++GType rygel_lms_category_container_get_type (void) G_GNUC_CONST;
++GType rygel_lms_all_music_get_type (void) G_GNUC_CONST;
++enum  {
++	RYGEL_LMS_ALL_MUSIC_DUMMY_PROPERTY
++};
++#define RYGEL_LMS_ALL_MUSIC_SQL_ALL_TEMPLATE "SELECT files.id, files.path, files.size, " "audios.title as title, audios.trackno, audios.length, audios.channels," \
++" audios.sampling_rate, audios.bitrate, audios.dlna_profile, audios.dln" \
++"a_mime, " "audio_artists.name as artist, " "audio_albums.name, " "files.mtime, " "audio_genres.name " "FROM audios, files " "LEFT JOIN audio_artists " "ON audios.artist_id = audio_artists.id " "LEFT JOIN audio_albums " "ON audios.album_id = audio_albums.id " "LEFT JOIN audio_genres " "ON audios.genre_id = audio_genres.id " "WHERE dtime = 0 AND audios.id = files.id %s " "LIMIT ? OFFSET ?;"
++#define RYGEL_LMS_ALL_MUSIC_SQL_COUNT "SELECT COUNT(audios.id) " "FROM audios, files " "WHERE dtime = 0 AND audios.id = files.id;"
++#define RYGEL_LMS_ALL_MUSIC_SQL_COUNT_WITH_FILTER_TEMPLATE "SELECT COUNT(audios.id), audios.title as title, " "audio_artists.name as artist " "FROM audios, files " "LEFT JOIN audio_artists " "ON audios.artist_id = audio_artists.id " "WHERE dtime = 0 AND audios.id = files.id %s;"
++#define RYGEL_LMS_ALL_MUSIC_SQL_FIND_OBJECT "SELECT files.id, files.path, files.size, " "audios.title, audios.trackno, audios.length, audios.channels, audios.s" \
++"ampling_rate, audios.bitrate, audios.dlna_profile, audios.dlna_mime, " "audio_artists.name, " "audio_albums.name, " "files.mtime, " "audio_genres.name " "FROM audios, files " "LEFT JOIN audio_artists " "ON audios.artist_id = audio_artists.id " "LEFT JOIN audio_albums " "ON audios.album_id = audio_albums.id " "LEFT JOIN audio_genres " "ON audios.genre_id = audio_genres.id " "WHERE dtime = 0 AND files.id = ? AND audios.id = files.id;"
++#define RYGEL_LMS_ALL_MUSIC_SQL_ADDED "SELECT files.id, files.path, files.size, " "audios.title as title, audios.trackno, audios.length, audios.channels," \
++" audios.sampling_rate, audios.bitrate, audios.dlna_profile, audios.dln" \
++"a_mime, " "audio_artists.name as artist, " "audio_albums.name, " "files.mtime, " "audio_genres.name " "FROM audios, files " "LEFT JOIN audio_artists " "ON audios.artist_id = audio_artists.id " "LEFT JOIN audio_albums " "ON audios.album_id = audio_albums.id " "LEFT JOIN audio_genres " "ON audios.genre_id = audio_genres.id " "WHERE dtime = 0 AND audios.id = files.id " "AND update_id > ? AND update_id <= ?;"
++#define RYGEL_LMS_ALL_MUSIC_SQL_REMOVED "SELECT files.id, files.path, files.size, " "audios.title as title, audios.trackno, audios.length, audios.channels," \
++" audios.sampling_rate, audios.bitrate, audios.dlna_profile, audios.dln" \
++"a_mime, " "audio_artists.name as artist, " "audio_albums.name, " "files.mtime, " "audio_genres.name " "FROM audios, files " "LEFT JOIN audio_artists " "ON audios.artist_id = audio_artists.id " "LEFT JOIN audio_albums " "ON audios.album_id = audio_albums.id " "LEFT JOIN audio_genres " "ON audios.genre_id = audio_genres.id " "WHERE dtime <> 0 AND audios.id = files.id " "AND update_id > ? AND update_id <= ?;"
++static gchar* rygel_lms_all_music_real_get_sql_all_with_filter (RygelLMSCategoryContainer* base, const gchar* filter);
++const gchar* rygel_lms_category_container_get_sql_all (RygelLMSCategoryContainer* self);
++static gchar* rygel_lms_all_music_real_get_sql_count_with_filter (RygelLMSCategoryContainer* base, const gchar* filter);
++const gchar* rygel_lms_category_container_get_sql_count (RygelLMSCategoryContainer* self);
++static RygelMediaObject* rygel_lms_all_music_real_object_from_statement (RygelLMSCategoryContainer* base, sqlite3_stmt* statement);
++gchar* rygel_lms_category_container_build_child_id (RygelLMSCategoryContainer* self, gint db_id);
++gpointer rygel_lms_database_ref (gpointer instance);
++void rygel_lms_database_unref (gpointer instance);
++GParamSpec* rygel_lms_param_spec_database (const gchar* name, const gchar* nick, const gchar* blurb, GType object_type, GParamFlags flags);
++void rygel_lms_value_set_database (GValue* value, gpointer v_object);
++void rygel_lms_value_take_database (GValue* value, gpointer v_object);
++gpointer rygel_lms_value_get_database (const GValue* value);
++GType rygel_lms_database_get_type (void) G_GNUC_CONST;
++RygelLMSAllMusic* rygel_lms_all_music_new (RygelMediaContainer* parent, RygelLMSDatabase* lms_db);
++RygelLMSAllMusic* rygel_lms_all_music_construct (GType object_type, RygelMediaContainer* parent, RygelLMSDatabase* lms_db);
++RygelLMSCategoryContainer* rygel_lms_category_container_construct (GType object_type, const gchar* db_id, RygelMediaContainer* parent, const gchar* title, RygelLMSDatabase* lms_db, const gchar* sql_all, const gchar* sql_find_object, const gchar* sql_count, const gchar* sql_added, const gchar* sql_removed);
++
++
++static gchar* rygel_lms_all_music_real_get_sql_all_with_filter (RygelLMSCategoryContainer* base, const gchar* filter) {
++	RygelLMSAllMusic * self;
++	gchar* result = NULL;
++	const gchar* _tmp0_ = NULL;
++	gint _tmp1_ = 0;
++	gint _tmp2_ = 0;
++	gchar* filter_str = NULL;
++	const gchar* _tmp6_ = NULL;
++	gchar* _tmp7_ = NULL;
++	const gchar* _tmp8_ = NULL;
++	gchar* _tmp9_ = NULL;
++	self = (RygelLMSAllMusic*) base;
++	g_return_val_if_fail (filter != NULL, NULL);
++	_tmp0_ = filter;
++	_tmp1_ = strlen (_tmp0_);
++	_tmp2_ = _tmp1_;
++	if (_tmp2_ == 0) {
++		const gchar* _tmp3_ = NULL;
++		const gchar* _tmp4_ = NULL;
++		gchar* _tmp5_ = NULL;
++		_tmp3_ = rygel_lms_category_container_get_sql_all ((RygelLMSCategoryContainer*) self);
++		_tmp4_ = _tmp3_;
++		_tmp5_ = g_strdup (_tmp4_);
++		result = _tmp5_;
++		return result;
++	}
++	_tmp6_ = filter;
++	_tmp7_ = g_strdup_printf ("AND %s", _tmp6_);
++	filter_str = _tmp7_;
++	_tmp8_ = filter_str;
++	_tmp9_ = g_strdup_printf (RYGEL_LMS_ALL_MUSIC_SQL_ALL_TEMPLATE, _tmp8_);
++	result = _tmp9_;
++	_g_free0 (filter_str);
++	return result;
++}
++
++
++static gchar* rygel_lms_all_music_real_get_sql_count_with_filter (RygelLMSCategoryContainer* base, const gchar* filter) {
++	RygelLMSAllMusic * self;
++	gchar* result = NULL;
++	const gchar* _tmp0_ = NULL;
++	gint _tmp1_ = 0;
++	gint _tmp2_ = 0;
++	gchar* filter_str = NULL;
++	const gchar* _tmp6_ = NULL;
++	gchar* _tmp7_ = NULL;
++	const gchar* _tmp8_ = NULL;
++	gchar* _tmp9_ = NULL;
++	self = (RygelLMSAllMusic*) base;
++	g_return_val_if_fail (filter != NULL, NULL);
++	_tmp0_ = filter;
++	_tmp1_ = strlen (_tmp0_);
++	_tmp2_ = _tmp1_;
++	if (_tmp2_ == 0) {
++		const gchar* _tmp3_ = NULL;
++		const gchar* _tmp4_ = NULL;
++		gchar* _tmp5_ = NULL;
++		_tmp3_ = rygel_lms_category_container_get_sql_count ((RygelLMSCategoryContainer*) self);
++		_tmp4_ = _tmp3_;
++		_tmp5_ = g_strdup (_tmp4_);
++		result = _tmp5_;
++		return result;
++	}
++	_tmp6_ = filter;
++	_tmp7_ = g_strdup_printf ("AND %s", _tmp6_);
++	filter_str = _tmp7_;
++	_tmp8_ = filter_str;
++	_tmp9_ = g_strdup_printf (RYGEL_LMS_ALL_MUSIC_SQL_COUNT_WITH_FILTER_TEMPLATE, _tmp8_);
++	result = _tmp9_;
++	_g_free0 (filter_str);
++	return result;
++}
++
++
++static RygelMediaObject* rygel_lms_all_music_real_object_from_statement (RygelLMSCategoryContainer* base, sqlite3_stmt* statement) {
++	RygelLMSAllMusic * self;
++	RygelMediaObject* result = NULL;
++	gint id = 0;
++	sqlite3_stmt* _tmp0_ = NULL;
++	gint _tmp1_ = 0;
++	gchar* path = NULL;
++	sqlite3_stmt* _tmp2_ = NULL;
++	const gchar* _tmp3_ = NULL;
++	gchar* _tmp4_ = NULL;
++	gchar* mime_type = NULL;
++	sqlite3_stmt* _tmp5_ = NULL;
++	const gchar* _tmp6_ = NULL;
++	gchar* _tmp7_ = NULL;
++	gboolean _tmp8_ = FALSE;
++	const gchar* _tmp9_ = NULL;
++	gchar* title = NULL;
++	sqlite3_stmt* _tmp15_ = NULL;
++	const gchar* _tmp16_ = NULL;
++	gchar* _tmp17_ = NULL;
++	gchar* song_id = NULL;
++	gint _tmp18_ = 0;
++	gchar* _tmp19_ = NULL;
++	RygelMusicItem* song = NULL;
++	RygelMusicItem* _tmp20_ = NULL;
++	sqlite3_stmt* _tmp21_ = NULL;
++	gint _tmp22_ = 0;
++	sqlite3_stmt* _tmp23_ = NULL;
++	gint _tmp24_ = 0;
++	sqlite3_stmt* _tmp25_ = NULL;
++	gint _tmp26_ = 0;
++	sqlite3_stmt* _tmp27_ = NULL;
++	gint _tmp28_ = 0;
++	sqlite3_stmt* _tmp29_ = NULL;
++	gint _tmp30_ = 0;
++	sqlite3_stmt* _tmp31_ = NULL;
++	gint _tmp32_ = 0;
++	sqlite3_stmt* _tmp33_ = NULL;
++	const gchar* _tmp34_ = NULL;
++	const gchar* _tmp35_ = NULL;
++	sqlite3_stmt* _tmp36_ = NULL;
++	const gchar* _tmp37_ = NULL;
++	sqlite3_stmt* _tmp38_ = NULL;
++	const gchar* _tmp39_ = NULL;
++	GTimeVal tv = {0};
++	sqlite3_stmt* _tmp40_ = NULL;
++	gint _tmp41_ = 0;
++	GTimeVal _tmp42_ = {0};
++	gchar* _tmp43_ = NULL;
++	gchar* _tmp44_ = NULL;
++	sqlite3_stmt* _tmp45_ = NULL;
++	const gchar* _tmp46_ = NULL;
++	GFile* file = NULL;
++	const gchar* _tmp47_ = NULL;
++	GFile* _tmp48_ = NULL;
++	gchar* _tmp49_ = NULL;
++	gchar* _tmp50_ = NULL;
++	self = (RygelLMSAllMusic*) base;
++	g_return_val_if_fail (statement != NULL, NULL);
++	_tmp0_ = statement;
++	_tmp1_ = sqlite3_column_int (_tmp0_, 0);
++	id = _tmp1_;
++	_tmp2_ = statement;
++	_tmp3_ = sqlite3_column_text (_tmp2_, 1);
++	_tmp4_ = g_strdup (_tmp3_);
++	path = _tmp4_;
++	_tmp5_ = statement;
++	_tmp6_ = sqlite3_column_text (_tmp5_, 10);
++	_tmp7_ = g_strdup (_tmp6_);
++	mime_type = _tmp7_;
++	_tmp9_ = mime_type;
++	if (_tmp9_ == NULL) {
++		_tmp8_ = TRUE;
++	} else {
++		const gchar* _tmp10_ = NULL;
++		gint _tmp11_ = 0;
++		gint _tmp12_ = 0;
++		_tmp10_ = mime_type;
++		_tmp11_ = strlen (_tmp10_);
++		_tmp12_ = _tmp11_;
++		_tmp8_ = _tmp12_ == 0;
++	}
++	if (_tmp8_) {
++		gint _tmp13_ = 0;
++		const gchar* _tmp14_ = NULL;
++		_tmp13_ = id;
++		_tmp14_ = path;
++		g_debug ("rygel-lms-all-music.vala:130: Music item %d (%s) has no MIME type", _tmp13_, _tmp14_);
++	}
++	_tmp15_ = statement;
++	_tmp16_ = sqlite3_column_text (_tmp15_, 3);
++	_tmp17_ = g_strdup (_tmp16_);
++	title = _tmp17_;
++	_tmp18_ = id;
++	_tmp19_ = rygel_lms_category_container_build_child_id ((RygelLMSCategoryContainer*) self, _tmp18_);
++	song_id = _tmp19_;
++	_tmp20_ = rygel_music_item_new (song_id, (RygelMediaContainer*) self, title, RYGEL_MUSIC_ITEM_UPNP_CLASS);
++	song = _tmp20_;
++	_tmp21_ = statement;
++	_tmp22_ = sqlite3_column_int (_tmp21_, 2);
++	rygel_media_file_item_set_size ((RygelMediaFileItem*) song, (gint64) _tmp22_);
++	_tmp23_ = statement;
++	_tmp24_ = sqlite3_column_int (_tmp23_, 4);
++	rygel_music_item_set_track_number (song, _tmp24_);
++	_tmp25_ = statement;
++	_tmp26_ = sqlite3_column_int (_tmp25_, 5);
++	rygel_audio_item_set_duration ((RygelAudioItem*) song, (glong) _tmp26_);
++	_tmp27_ = statement;
++	_tmp28_ = sqlite3_column_int (_tmp27_, 6);
++	rygel_audio_item_set_channels ((RygelAudioItem*) song, _tmp28_);
++	_tmp29_ = statement;
++	_tmp30_ = sqlite3_column_int (_tmp29_, 7);
++	rygel_audio_item_set_sample_freq ((RygelAudioItem*) song, _tmp30_);
++	_tmp31_ = statement;
++	_tmp32_ = sqlite3_column_int (_tmp31_, 8);
++	rygel_audio_item_set_bitrate ((RygelAudioItem*) song, _tmp32_);
++	_tmp33_ = statement;
++	_tmp34_ = sqlite3_column_text (_tmp33_, 9);
++	rygel_media_file_item_set_dlna_profile ((RygelMediaFileItem*) song, _tmp34_);
++	_tmp35_ = mime_type;
++	rygel_media_file_item_set_mime_type ((RygelMediaFileItem*) song, _tmp35_);
++	_tmp36_ = statement;
++	_tmp37_ = sqlite3_column_text (_tmp36_, 11);
++	rygel_media_object_set_artist ((RygelMediaObject*) song, _tmp37_);
++	_tmp38_ = statement;
++	_tmp39_ = sqlite3_column_text (_tmp38_, 12);
++	rygel_audio_item_set_album ((RygelAudioItem*) song, _tmp39_);
++	_tmp40_ = statement;
++	_tmp41_ = sqlite3_column_int (_tmp40_, 13);
++	_tmp42_.tv_sec = (glong) _tmp41_;
++	_tmp42_.tv_usec = (glong) 0;
++	tv = _tmp42_;
++	_tmp43_ = g_time_val_to_iso8601 (&tv);
++	_tmp44_ = _tmp43_;
++	rygel_media_object_set_date ((RygelMediaObject*) song, _tmp44_);
++	_g_free0 (_tmp44_);
++	_tmp45_ = statement;
++	_tmp46_ = sqlite3_column_text (_tmp45_, 14);
++	rygel_media_object_set_genre ((RygelMediaObject*) song, _tmp46_);
++	_tmp47_ = path;
++	_tmp48_ = g_file_new_for_path (_tmp47_);
++	file = _tmp48_;
++	_tmp49_ = g_file_get_uri (file);
++	_tmp50_ = _tmp49_;
++	rygel_media_object_add_uri ((RygelMediaObject*) song, _tmp50_);
++	_g_free0 (_tmp50_);
++	result = (RygelMediaObject*) song;
++	_g_object_unref0 (file);
++	_g_free0 (song_id);
++	_g_free0 (title);
++	_g_free0 (mime_type);
++	_g_free0 (path);
++	return result;
++}
++
++
++RygelLMSAllMusic* rygel_lms_all_music_construct (GType object_type, RygelMediaContainer* parent, RygelLMSDatabase* lms_db) {
++	RygelLMSAllMusic * self = NULL;
++	RygelMediaContainer* _tmp0_ = NULL;
++	const gchar* _tmp1_ = NULL;
++	RygelLMSDatabase* _tmp2_ = NULL;
++	gchar* _tmp3_ = NULL;
++	gchar* _tmp4_ = NULL;
++	g_return_val_if_fail (parent != NULL, NULL);
++	g_return_val_if_fail (lms_db != NULL, NULL);
++	_tmp0_ = parent;
++	_tmp1_ = _ ("All");
++	_tmp2_ = lms_db;
++	_tmp3_ = g_strdup_printf (RYGEL_LMS_ALL_MUSIC_SQL_ALL_TEMPLATE, "");
++	_tmp4_ = _tmp3_;
++	self = (RygelLMSAllMusic*) rygel_lms_category_container_construct (object_type, "all", _tmp0_, _tmp1_, _tmp2_, _tmp4_, RYGEL_LMS_ALL_MUSIC_SQL_FIND_OBJECT, RYGEL_LMS_ALL_MUSIC_SQL_COUNT, RYGEL_LMS_ALL_MUSIC_SQL_ADDED, RYGEL_LMS_ALL_MUSIC_SQL_REMOVED);
++	_g_free0 (_tmp4_);
++	return self;
++}
++
++
++RygelLMSAllMusic* rygel_lms_all_music_new (RygelMediaContainer* parent, RygelLMSDatabase* lms_db) {
++	return rygel_lms_all_music_construct (RYGEL_LMS_TYPE_ALL_MUSIC, parent, lms_db);
++}
++
++
++static void rygel_lms_all_music_class_init (RygelLMSAllMusicClass * klass) {
++	rygel_lms_all_music_parent_class = g_type_class_peek_parent (klass);
++	((RygelLMSCategoryContainerClass *) klass)->get_sql_all_with_filter = rygel_lms_all_music_real_get_sql_all_with_filter;
++	((RygelLMSCategoryContainerClass *) klass)->get_sql_count_with_filter = rygel_lms_all_music_real_get_sql_count_with_filter;
++	((RygelLMSCategoryContainerClass *) klass)->object_from_statement = rygel_lms_all_music_real_object_from_statement;
++}
++
++
++static void rygel_lms_all_music_instance_init (RygelLMSAllMusic * self) {
++}
++
++
++GType rygel_lms_all_music_get_type (void) {
++	static volatile gsize rygel_lms_all_music_type_id__volatile = 0;
++	if (g_once_init_enter (&rygel_lms_all_music_type_id__volatile)) {
++		static const GTypeInfo g_define_type_info = { sizeof (RygelLMSAllMusicClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) rygel_lms_all_music_class_init, (GClassFinalizeFunc) NULL, NULL, sizeof (RygelLMSAllMusic), 0, (GInstanceInitFunc) rygel_lms_all_music_instance_init, NULL };
++		GType rygel_lms_all_music_type_id;
++		rygel_lms_all_music_type_id = g_type_register_static (RYGEL_LMS_TYPE_CATEGORY_CONTAINER, "RygelLMSAllMusic", &g_define_type_info, 0);
++		g_once_init_leave (&rygel_lms_all_music_type_id__volatile, rygel_lms_all_music_type_id);
++	}
++	return rygel_lms_all_music_type_id__volatile;
++}
++
++
++
+diff --git a/src/plugins/lms/rygel-lms-all-videos.c b/src/plugins/lms/rygel-lms-all-videos.c
+new file mode 100644
+index 0000000..51ba52c
+--- /dev/null
++++ b/src/plugins/lms/rygel-lms-all-videos.c
+@@ -0,0 +1,456 @@
++/* rygel-lms-all-videos.c generated by valac 0.28.0, the Vala compiler
++ * generated from rygel-lms-all-videos.vala, do not modify */
++
++/*
++ * Copyright (C) 2013 Intel Corporation.
++ *
++ * Author: Jussi Kukkonen <jussi.kukkonen@intel.com>
++ *
++ * 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 <glib.h>
++#include <glib-object.h>
++#include <rygel-server.h>
++#include <sqlite3.h>
++#include <stdlib.h>
++#include <string.h>
++#include <gio/gio.h>
++
++
++#define RYGEL_LMS_TYPE_CATEGORY_CONTAINER (rygel_lms_category_container_get_type ())
++#define RYGEL_LMS_CATEGORY_CONTAINER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), RYGEL_LMS_TYPE_CATEGORY_CONTAINER, RygelLMSCategoryContainer))
++#define RYGEL_LMS_CATEGORY_CONTAINER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), RYGEL_LMS_TYPE_CATEGORY_CONTAINER, RygelLMSCategoryContainerClass))
++#define RYGEL_LMS_IS_CATEGORY_CONTAINER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), RYGEL_LMS_TYPE_CATEGORY_CONTAINER))
++#define RYGEL_LMS_IS_CATEGORY_CONTAINER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), RYGEL_LMS_TYPE_CATEGORY_CONTAINER))
++#define RYGEL_LMS_CATEGORY_CONTAINER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), RYGEL_LMS_TYPE_CATEGORY_CONTAINER, RygelLMSCategoryContainerClass))
++
++typedef struct _RygelLMSCategoryContainer RygelLMSCategoryContainer;
++typedef struct _RygelLMSCategoryContainerClass RygelLMSCategoryContainerClass;
++typedef struct _RygelLMSCategoryContainerPrivate RygelLMSCategoryContainerPrivate;
++
++#define RYGEL_LMS_TYPE_ALL_VIDEOS (rygel_lms_all_videos_get_type ())
++#define RYGEL_LMS_ALL_VIDEOS(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), RYGEL_LMS_TYPE_ALL_VIDEOS, RygelLMSAllVideos))
++#define RYGEL_LMS_ALL_VIDEOS_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), RYGEL_LMS_TYPE_ALL_VIDEOS, RygelLMSAllVideosClass))
++#define RYGEL_LMS_IS_ALL_VIDEOS(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), RYGEL_LMS_TYPE_ALL_VIDEOS))
++#define RYGEL_LMS_IS_ALL_VIDEOS_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), RYGEL_LMS_TYPE_ALL_VIDEOS))
++#define RYGEL_LMS_ALL_VIDEOS_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), RYGEL_LMS_TYPE_ALL_VIDEOS, RygelLMSAllVideosClass))
++
++typedef struct _RygelLMSAllVideos RygelLMSAllVideos;
++typedef struct _RygelLMSAllVideosClass RygelLMSAllVideosClass;
++typedef struct _RygelLMSAllVideosPrivate RygelLMSAllVideosPrivate;
++#define _g_free0(var) (var = (g_free (var), NULL))
++
++#define RYGEL_LMS_TYPE_DATABASE (rygel_lms_database_get_type ())
++#define RYGEL_LMS_DATABASE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), RYGEL_LMS_TYPE_DATABASE, RygelLMSDatabase))
++#define RYGEL_LMS_DATABASE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), RYGEL_LMS_TYPE_DATABASE, RygelLMSDatabaseClass))
++#define RYGEL_LMS_IS_DATABASE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), RYGEL_LMS_TYPE_DATABASE))
++#define RYGEL_LMS_IS_DATABASE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), RYGEL_LMS_TYPE_DATABASE))
++#define RYGEL_LMS_DATABASE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), RYGEL_LMS_TYPE_DATABASE, RygelLMSDatabaseClass))
++
++typedef struct _RygelLMSDatabase RygelLMSDatabase;
++typedef struct _RygelLMSDatabaseClass RygelLMSDatabaseClass;
++#define _g_object_unref0(var) ((var == NULL) ? NULL : (var = (g_object_unref (var), NULL)))
++#define _sqlite3_finalize0(var) ((var == NULL) ? NULL : (var = (sqlite3_finalize (var), NULL)))
++#define _g_error_free0(var) ((var == NULL) ? NULL : (var = (g_error_free (var), NULL)))
++
++struct _RygelLMSCategoryContainer {
++	RygelMediaContainer parent_instance;
++	RygelLMSCategoryContainerPrivate * priv;
++	sqlite3_stmt* stmt_all;
++	sqlite3_stmt* stmt_find_object;
++	sqlite3_stmt* stmt_added;
++	sqlite3_stmt* stmt_removed;
++	gchar* child_prefix;
++	gchar* ref_prefix;
++};
++
++struct _RygelLMSCategoryContainerClass {
++	RygelMediaContainerClass parent_class;
++	RygelMediaObject* (*object_from_statement) (RygelLMSCategoryContainer* self, sqlite3_stmt* statement);
++	gchar* (*get_sql_all_with_filter) (RygelLMSCategoryContainer* self, const gchar* filter);
++	gchar* (*get_sql_count_with_filter) (RygelLMSCategoryContainer* self, const gchar* filter);
++	guint (*get_child_count_with_filter) (RygelLMSCategoryContainer* self, const gchar* where_filter, GValueArray* args);
++	RygelMediaObjects* (*get_children_with_filter) (RygelLMSCategoryContainer* self, const gchar* where_filter, GValueArray* args, const gchar* sort_criteria, guint offset, guint max_count);
++};
++
++struct _RygelLMSAllVideos {
++	RygelLMSCategoryContainer parent_instance;
++	RygelLMSAllVideosPrivate * priv;
++};
++
++struct _RygelLMSAllVideosClass {
++	RygelLMSCategoryContainerClass parent_class;
++};
++
++typedef enum  {
++	RYGEL_LMS_DATABASE_ERROR_OPEN,
++	RYGEL_LMS_DATABASE_ERROR_PREPARE,
++	RYGEL_LMS_DATABASE_ERROR_BIND,
++	RYGEL_LMS_DATABASE_ERROR_STEP,
++	RYGEL_LMS_DATABASE_ERROR_NOT_FOUND
++} RygelLMSDatabaseError;
++#define RYGEL_LMS_DATABASE_ERROR rygel_lms_database_error_quark ()
++
++static gpointer rygel_lms_all_videos_parent_class = NULL;
++
++GType rygel_lms_category_container_get_type (void) G_GNUC_CONST;
++GType rygel_lms_all_videos_get_type (void) G_GNUC_CONST;
++enum  {
++	RYGEL_LMS_ALL_VIDEOS_DUMMY_PROPERTY
++};
++#define RYGEL_LMS_ALL_VIDEOS_SQL_ALL "SELECT videos.id, title, artist, length, path, mtime, size, dlna_profi" \
++"le, dlna_mime " "FROM videos, files " "WHERE dtime = 0 AND videos.id = files.id " "LIMIT ? OFFSET ?;"
++#define RYGEL_LMS_ALL_VIDEOS_SQL_COUNT "SELECT count(videos.id) " "FROM videos, files " "WHERE dtime = 0 AND videos.id = files.id;"
++#define RYGEL_LMS_ALL_VIDEOS_SQL_FIND_OBJECT "SELECT videos.id, title, artist, length, path, mtime, size, dlna_profi" \
++"le, dlna_mime " "FROM videos, files " "WHERE dtime = 0 AND files.id = ? AND videos.id = files.id;"
++#define RYGEL_LMS_ALL_VIDEOS_SQL_ADDED "SELECT videos.id, title, artist, length, path, mtime, size, dlna_profi" \
++"le, dlna_mime " "FROM videos, files " "WHERE dtime = 0 AND videos.id = files.id " "AND update_id > ? AND update_id <= ?;"
++#define RYGEL_LMS_ALL_VIDEOS_SQL_REMOVED "SELECT videos.id, title, artist, length, path, mtime, size, dlna_profi" \
++"le, dlna_mime " "FROM videos, files " "WHERE dtime <> 0 AND videos.id = files.id " "AND update_id > ? AND update_id <= ?;"
++static RygelMediaObject* rygel_lms_all_videos_real_object_from_statement (RygelLMSCategoryContainer* base, sqlite3_stmt* statement);
++gchar* rygel_lms_category_container_build_child_id (RygelLMSCategoryContainer* self, gint db_id);
++gpointer rygel_lms_database_ref (gpointer instance);
++void rygel_lms_database_unref (gpointer instance);
++GParamSpec* rygel_lms_param_spec_database (const gchar* name, const gchar* nick, const gchar* blurb, GType object_type, GParamFlags flags);
++void rygel_lms_value_set_database (GValue* value, gpointer v_object);
++void rygel_lms_value_take_database (GValue* value, gpointer v_object);
++gpointer rygel_lms_value_get_database (const GValue* value);
++GType rygel_lms_database_get_type (void) G_GNUC_CONST;
++RygelLMSDatabase* rygel_lms_category_container_get_lms_db (RygelLMSCategoryContainer* self);
++GQuark rygel_lms_database_error_quark (void);
++sqlite3_stmt* rygel_lms_database_prepare (RygelLMSDatabase* self, const gchar* query_string, GError** error);
++void rygel_lms_database_find_object (const gchar* id, sqlite3_stmt* stmt, GError** error);
++RygelLMSAllVideos* rygel_lms_all_videos_new (const gchar* id, RygelMediaContainer* parent, const gchar* title, RygelLMSDatabase* lms_db);
++RygelLMSAllVideos* rygel_lms_all_videos_construct (GType object_type, const gchar* id, RygelMediaContainer* parent, const gchar* title, RygelLMSDatabase* lms_db);
++RygelLMSCategoryContainer* rygel_lms_category_container_construct (GType object_type, const gchar* db_id, RygelMediaContainer* parent, const gchar* title, RygelLMSDatabase* lms_db, const gchar* sql_all, const gchar* sql_find_object, const gchar* sql_count, const gchar* sql_added, const gchar* sql_removed);
++
++
++static RygelMediaObject* rygel_lms_all_videos_real_object_from_statement (RygelLMSCategoryContainer* base, sqlite3_stmt* statement) {
++	RygelLMSAllVideos * self;
++	RygelMediaObject* result = NULL;
++	gint id = 0;
++	sqlite3_stmt* _tmp0_ = NULL;
++	gint _tmp1_ = 0;
++	gchar* mime_type = NULL;
++	sqlite3_stmt* _tmp2_ = NULL;
++	const gchar* _tmp3_ = NULL;
++	gchar* _tmp4_ = NULL;
++	gchar* path = NULL;
++	sqlite3_stmt* _tmp5_ = NULL;
++	const gchar* _tmp6_ = NULL;
++	gchar* _tmp7_ = NULL;
++	GFile* file = NULL;
++	const gchar* _tmp8_ = NULL;
++	GFile* _tmp9_ = NULL;
++	gboolean _tmp10_ = FALSE;
++	const gchar* _tmp11_ = NULL;
++	gchar* title = NULL;
++	sqlite3_stmt* _tmp17_ = NULL;
++	const gchar* _tmp18_ = NULL;
++	gchar* _tmp19_ = NULL;
++	RygelVideoItem* video = NULL;
++	gint _tmp20_ = 0;
++	gchar* _tmp21_ = NULL;
++	gchar* _tmp22_ = NULL;
++	const gchar* _tmp23_ = NULL;
++	RygelVideoItem* _tmp24_ = NULL;
++	RygelVideoItem* _tmp25_ = NULL;
++	RygelVideoItem* _tmp26_ = NULL;
++	sqlite3_stmt* _tmp27_ = NULL;
++	const gchar* _tmp28_ = NULL;
++	RygelVideoItem* _tmp29_ = NULL;
++	sqlite3_stmt* _tmp30_ = NULL;
++	gint _tmp31_ = 0;
++	GTimeVal tv = {0};
++	sqlite3_stmt* _tmp32_ = NULL;
++	gint _tmp33_ = 0;
++	GTimeVal _tmp34_ = {0};
++	RygelVideoItem* _tmp35_ = NULL;
++	gchar* _tmp36_ = NULL;
++	gchar* _tmp37_ = NULL;
++	RygelVideoItem* _tmp38_ = NULL;
++	sqlite3_stmt* _tmp39_ = NULL;
++	gint _tmp40_ = 0;
++	RygelVideoItem* _tmp41_ = NULL;
++	sqlite3_stmt* _tmp42_ = NULL;
++	const gchar* _tmp43_ = NULL;
++	RygelVideoItem* _tmp44_ = NULL;
++	const gchar* _tmp45_ = NULL;
++	RygelVideoItem* _tmp46_ = NULL;
++	GFile* _tmp47_ = NULL;
++	gchar* _tmp48_ = NULL;
++	gchar* _tmp49_ = NULL;
++	gchar* video_data = NULL;
++	gchar* _tmp50_ = NULL;
++	GError * _inner_error_ = NULL;
++	self = (RygelLMSAllVideos*) base;
++	g_return_val_if_fail (statement != NULL, NULL);
++	_tmp0_ = statement;
++	_tmp1_ = sqlite3_column_int (_tmp0_, 0);
++	id = _tmp1_;
++	_tmp2_ = statement;
++	_tmp3_ = sqlite3_column_text (_tmp2_, 8);
++	_tmp4_ = g_strdup (_tmp3_);
++	mime_type = _tmp4_;
++	_tmp5_ = statement;
++	_tmp6_ = sqlite3_column_text (_tmp5_, 4);
++	_tmp7_ = g_strdup (_tmp6_);
++	path = _tmp7_;
++	_tmp8_ = path;
++	_tmp9_ = g_file_new_for_path (_tmp8_);
++	file = _tmp9_;
++	_tmp11_ = mime_type;
++	if (_tmp11_ == NULL) {
++		_tmp10_ = TRUE;
++	} else {
++		const gchar* _tmp12_ = NULL;
++		gint _tmp13_ = 0;
++		gint _tmp14_ = 0;
++		_tmp12_ = mime_type;
++		_tmp13_ = strlen (_tmp12_);
++		_tmp14_ = _tmp13_;
++		_tmp10_ = _tmp14_ == 0;
++	}
++	if (_tmp10_) {
++		gint _tmp15_ = 0;
++		const gchar* _tmp16_ = NULL;
++		_tmp15_ = id;
++		_tmp16_ = path;
++		g_debug ("rygel-lms-all-videos.vala:75: Video item %d (%s) has no MIME type", _tmp15_, _tmp16_);
++	}
++	_tmp17_ = statement;
++	_tmp18_ = sqlite3_column_text (_tmp17_, 1);
++	_tmp19_ = g_strdup (_tmp18_);
++	title = _tmp19_;
++	_tmp20_ = id;
++	_tmp21_ = rygel_lms_category_container_build_child_id ((RygelLMSCategoryContainer*) self, _tmp20_);
++	_tmp22_ = _tmp21_;
++	_tmp23_ = title;
++	_tmp24_ = rygel_video_item_new (_tmp22_, (RygelMediaContainer*) self, _tmp23_, RYGEL_VIDEO_ITEM_UPNP_CLASS);
++	_tmp25_ = _tmp24_;
++	_g_free0 (_tmp22_);
++	video = _tmp25_;
++	_tmp26_ = video;
++	_tmp27_ = statement;
++	_tmp28_ = sqlite3_column_text (_tmp27_, 2);
++	rygel_media_object_set_creator ((RygelMediaObject*) _tmp26_, _tmp28_);
++	_tmp29_ = video;
++	_tmp30_ = statement;
++	_tmp31_ = sqlite3_column_int (_tmp30_, 3);
++	rygel_audio_item_set_duration ((RygelAudioItem*) _tmp29_, (glong) _tmp31_);
++	_tmp32_ = statement;
++	_tmp33_ = sqlite3_column_int (_tmp32_, 5);
++	_tmp34_.tv_sec = (glong) _tmp33_;
++	_tmp34_.tv_usec = (glong) 0;
++	tv = _tmp34_;
++	_tmp35_ = video;
++	_tmp36_ = g_time_val_to_iso8601 (&tv);
++	_tmp37_ = _tmp36_;
++	rygel_media_object_set_date ((RygelMediaObject*) _tmp35_, _tmp37_);
++	_g_free0 (_tmp37_);
++	_tmp38_ = video;
++	_tmp39_ = statement;
++	_tmp40_ = sqlite3_column_int (_tmp39_, 6);
++	rygel_media_file_item_set_size ((RygelMediaFileItem*) _tmp38_, (gint64) _tmp40_);
++	_tmp41_ = video;
++	_tmp42_ = statement;
++	_tmp43_ = sqlite3_column_text (_tmp42_, 7);
++	rygel_media_file_item_set_dlna_profile ((RygelMediaFileItem*) _tmp41_, _tmp43_);
++	_tmp44_ = video;
++	_tmp45_ = mime_type;
++	rygel_media_file_item_set_mime_type ((RygelMediaFileItem*) _tmp44_, _tmp45_);
++	_tmp46_ = video;
++	_tmp47_ = file;
++	_tmp48_ = g_file_get_uri (_tmp47_);
++	_tmp49_ = _tmp48_;
++	rygel_media_object_add_uri ((RygelMediaObject*) _tmp46_, _tmp49_);
++	_g_free0 (_tmp49_);
++	_tmp50_ = g_strdup ("select videos_videos.bitrate + videos_audios.bitrate, width, height, c" \
++"hannels, sampling_rate " "from videos, videos_audios, videos_videos where videos.id = ? " "and videos.id = videos_audios.video_id and videos.id = videos_videos.v" \
++"ideo_id;");
++	video_data = _tmp50_;
++	{
++		sqlite3_stmt* stmt = NULL;
++		RygelLMSDatabase* _tmp51_ = NULL;
++		RygelLMSDatabase* _tmp52_ = NULL;
++		const gchar* _tmp53_ = NULL;
++		sqlite3_stmt* _tmp54_ = NULL;
++		gint _tmp55_ = 0;
++		gchar* _tmp56_ = NULL;
++		gchar* _tmp57_ = NULL;
++		sqlite3_stmt* _tmp58_ = NULL;
++		RygelVideoItem* _tmp59_ = NULL;
++		sqlite3_stmt* _tmp60_ = NULL;
++		gint _tmp61_ = 0;
++		RygelVideoItem* _tmp62_ = NULL;
++		sqlite3_stmt* _tmp63_ = NULL;
++		gint _tmp64_ = 0;
++		RygelVideoItem* _tmp65_ = NULL;
++		sqlite3_stmt* _tmp66_ = NULL;
++		gint _tmp67_ = 0;
++		RygelVideoItem* _tmp68_ = NULL;
++		sqlite3_stmt* _tmp69_ = NULL;
++		gint _tmp70_ = 0;
++		RygelVideoItem* _tmp71_ = NULL;
++		sqlite3_stmt* _tmp72_ = NULL;
++		gint _tmp73_ = 0;
++		_tmp51_ = rygel_lms_category_container_get_lms_db ((RygelLMSCategoryContainer*) self);
++		_tmp52_ = _tmp51_;
++		_tmp53_ = video_data;
++		_tmp54_ = rygel_lms_database_prepare (_tmp52_, _tmp53_, &_inner_error_);
++		stmt = _tmp54_;
++		if (G_UNLIKELY (_inner_error_ != NULL)) {
++			if (_inner_error_->domain == RYGEL_LMS_DATABASE_ERROR) {
++				goto __catch10_rygel_lms_database_error;
++			}
++			_g_free0 (video_data);
++			_g_object_unref0 (video);
++			_g_free0 (title);
++			_g_object_unref0 (file);
++			_g_free0 (path);
++			_g_free0 (mime_type);
++			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;
++		}
++		_tmp55_ = id;
++		_tmp56_ = g_strdup_printf ("%d", _tmp55_);
++		_tmp57_ = _tmp56_;
++		_tmp58_ = stmt;
++		rygel_lms_database_find_object (_tmp57_, _tmp58_, &_inner_error_);
++		_g_free0 (_tmp57_);
++		if (G_UNLIKELY (_inner_error_ != NULL)) {
++			_sqlite3_finalize0 (stmt);
++			if (_inner_error_->domain == RYGEL_LMS_DATABASE_ERROR) {
++				goto __catch10_rygel_lms_database_error;
++			}
++			_sqlite3_finalize0 (stmt);
++			_g_free0 (video_data);
++			_g_object_unref0 (video);
++			_g_free0 (title);
++			_g_object_unref0 (file);
++			_g_free0 (path);
++			_g_free0 (mime_type);
++			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;
++		}
++		_tmp59_ = video;
++		_tmp60_ = stmt;
++		_tmp61_ = sqlite3_column_int (_tmp60_, 0);
++		rygel_audio_item_set_bitrate ((RygelAudioItem*) _tmp59_, _tmp61_ / 8);
++		_tmp62_ = video;
++		_tmp63_ = stmt;
++		_tmp64_ = sqlite3_column_int (_tmp63_, 1);
++		rygel_visual_item_set_width ((RygelVisualItem*) _tmp62_, _tmp64_);
++		_tmp65_ = video;
++		_tmp66_ = stmt;
++		_tmp67_ = sqlite3_column_int (_tmp66_, 2);
++		rygel_visual_item_set_height ((RygelVisualItem*) _tmp65_, _tmp67_);
++		_tmp68_ = video;
++		_tmp69_ = stmt;
++		_tmp70_ = sqlite3_column_int (_tmp69_, 3);
++		rygel_audio_item_set_channels ((RygelAudioItem*) _tmp68_, _tmp70_);
++		_tmp71_ = video;
++		_tmp72_ = stmt;
++		_tmp73_ = sqlite3_column_int (_tmp72_, 4);
++		rygel_audio_item_set_sample_freq ((RygelAudioItem*) _tmp71_, _tmp73_);
++		_sqlite3_finalize0 (stmt);
++	}
++	goto __finally10;
++	__catch10_rygel_lms_database_error:
++	{
++		GError* e = NULL;
++		GError* _tmp74_ = NULL;
++		const gchar* _tmp75_ = NULL;
++		e = _inner_error_;
++		_inner_error_ = NULL;
++		_tmp74_ = e;
++		_tmp75_ = _tmp74_->message;
++		g_warning ("rygel-lms-all-videos.vala:105: Query failed: %s", _tmp75_);
++		_g_error_free0 (e);
++	}
++	__finally10:
++	if (G_UNLIKELY (_inner_error_ != NULL)) {
++		_g_free0 (video_data);
++		_g_object_unref0 (video);
++		_g_free0 (title);
++		_g_object_unref0 (file);
++		_g_free0 (path);
++		_g_free0 (mime_type);
++		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;
++	}
++	result = (RygelMediaObject*) video;
++	_g_free0 (video_data);
++	_g_free0 (title);
++	_g_object_unref0 (file);
++	_g_free0 (path);
++	_g_free0 (mime_type);
++	return result;
++}
++
++
++RygelLMSAllVideos* rygel_lms_all_videos_construct (GType object_type, const gchar* id, RygelMediaContainer* parent, const gchar* title, RygelLMSDatabase* lms_db) {
++	RygelLMSAllVideos * self = NULL;
++	const gchar* _tmp0_ = NULL;
++	RygelMediaContainer* _tmp1_ = NULL;
++	const gchar* _tmp2_ = NULL;
++	RygelLMSDatabase* _tmp3_ = NULL;
++	g_return_val_if_fail (id != NULL, NULL);
++	g_return_val_if_fail (parent != NULL, NULL);
++	g_return_val_if_fail (title != NULL, NULL);
++	g_return_val_if_fail (lms_db != NULL, NULL);
++	_tmp0_ = id;
++	_tmp1_ = parent;
++	_tmp2_ = title;
++	_tmp3_ = lms_db;
++	self = (RygelLMSAllVideos*) rygel_lms_category_container_construct (object_type, _tmp0_, _tmp1_, _tmp2_, _tmp3_, RYGEL_LMS_ALL_VIDEOS_SQL_ALL, RYGEL_LMS_ALL_VIDEOS_SQL_FIND_OBJECT, RYGEL_LMS_ALL_VIDEOS_SQL_COUNT, RYGEL_LMS_ALL_VIDEOS_SQL_ADDED, RYGEL_LMS_ALL_VIDEOS_SQL_REMOVED);
++	return self;
++}
++
++
++RygelLMSAllVideos* rygel_lms_all_videos_new (const gchar* id, RygelMediaContainer* parent, const gchar* title, RygelLMSDatabase* lms_db) {
++	return rygel_lms_all_videos_construct (RYGEL_LMS_TYPE_ALL_VIDEOS, id, parent, title, lms_db);
++}
++
++
++static void rygel_lms_all_videos_class_init (RygelLMSAllVideosClass * klass) {
++	rygel_lms_all_videos_parent_class = g_type_class_peek_parent (klass);
++	((RygelLMSCategoryContainerClass *) klass)->object_from_statement = rygel_lms_all_videos_real_object_from_statement;
++}
++
++
++static void rygel_lms_all_videos_instance_init (RygelLMSAllVideos * self) {
++}
++
++
++GType rygel_lms_all_videos_get_type (void) {
++	static volatile gsize rygel_lms_all_videos_type_id__volatile = 0;
++	if (g_once_init_enter (&rygel_lms_all_videos_type_id__volatile)) {
++		static const GTypeInfo g_define_type_info = { sizeof (RygelLMSAllVideosClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) rygel_lms_all_videos_class_init, (GClassFinalizeFunc) NULL, NULL, sizeof (RygelLMSAllVideos), 0, (GInstanceInitFunc) rygel_lms_all_videos_instance_init, NULL };
++		GType rygel_lms_all_videos_type_id;
++		rygel_lms_all_videos_type_id = g_type_register_static (RYGEL_LMS_TYPE_CATEGORY_CONTAINER, "RygelLMSAllVideos", &g_define_type_info, 0);
++		g_once_init_leave (&rygel_lms_all_videos_type_id__volatile, rygel_lms_all_videos_type_id);
++	}
++	return rygel_lms_all_videos_type_id__volatile;
++}
++
++
++
+diff --git a/src/plugins/lms/rygel-lms-artist.c b/src/plugins/lms/rygel-lms-artist.c
+new file mode 100644
+index 0000000..e686ea4
+--- /dev/null
++++ b/src/plugins/lms/rygel-lms-artist.c
+@@ -0,0 +1,274 @@
++/* rygel-lms-artist.c generated by valac 0.28.0, the Vala compiler
++ * generated from rygel-lms-artist.vala, do not modify */
++
++/*
++ * Copyright (C) 2013 Intel Corporation.
++ *
++ * Author: Jussi Kukkonen <jussi.kukkonen@intel.com>
++ *
++ * 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 <glib.h>
++#include <glib-object.h>
++#include <rygel-server.h>
++#include <sqlite3.h>
++#include <stdlib.h>
++#include <string.h>
++
++
++#define RYGEL_LMS_TYPE_CATEGORY_CONTAINER (rygel_lms_category_container_get_type ())
++#define RYGEL_LMS_CATEGORY_CONTAINER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), RYGEL_LMS_TYPE_CATEGORY_CONTAINER, RygelLMSCategoryContainer))
++#define RYGEL_LMS_CATEGORY_CONTAINER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), RYGEL_LMS_TYPE_CATEGORY_CONTAINER, RygelLMSCategoryContainerClass))
++#define RYGEL_LMS_IS_CATEGORY_CONTAINER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), RYGEL_LMS_TYPE_CATEGORY_CONTAINER))
++#define RYGEL_LMS_IS_CATEGORY_CONTAINER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), RYGEL_LMS_TYPE_CATEGORY_CONTAINER))
++#define RYGEL_LMS_CATEGORY_CONTAINER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), RYGEL_LMS_TYPE_CATEGORY_CONTAINER, RygelLMSCategoryContainerClass))
++
++typedef struct _RygelLMSCategoryContainer RygelLMSCategoryContainer;
++typedef struct _RygelLMSCategoryContainerClass RygelLMSCategoryContainerClass;
++typedef struct _RygelLMSCategoryContainerPrivate RygelLMSCategoryContainerPrivate;
++
++#define RYGEL_LMS_TYPE_ARTIST (rygel_lms_artist_get_type ())
++#define RYGEL_LMS_ARTIST(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), RYGEL_LMS_TYPE_ARTIST, RygelLMSArtist))
++#define RYGEL_LMS_ARTIST_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), RYGEL_LMS_TYPE_ARTIST, RygelLMSArtistClass))
++#define RYGEL_LMS_IS_ARTIST(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), RYGEL_LMS_TYPE_ARTIST))
++#define RYGEL_LMS_IS_ARTIST_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), RYGEL_LMS_TYPE_ARTIST))
++#define RYGEL_LMS_ARTIST_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), RYGEL_LMS_TYPE_ARTIST, RygelLMSArtistClass))
++
++typedef struct _RygelLMSArtist RygelLMSArtist;
++typedef struct _RygelLMSArtistClass RygelLMSArtistClass;
++typedef struct _RygelLMSArtistPrivate RygelLMSArtistPrivate;
++
++#define RYGEL_LMS_TYPE_DATABASE (rygel_lms_database_get_type ())
++#define RYGEL_LMS_DATABASE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), RYGEL_LMS_TYPE_DATABASE, RygelLMSDatabase))
++#define RYGEL_LMS_DATABASE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), RYGEL_LMS_TYPE_DATABASE, RygelLMSDatabaseClass))
++#define RYGEL_LMS_IS_DATABASE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), RYGEL_LMS_TYPE_DATABASE))
++#define RYGEL_LMS_IS_DATABASE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), RYGEL_LMS_TYPE_DATABASE))
++#define RYGEL_LMS_DATABASE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), RYGEL_LMS_TYPE_DATABASE, RygelLMSDatabaseClass))
++
++typedef struct _RygelLMSDatabase RygelLMSDatabase;
++typedef struct _RygelLMSDatabaseClass RygelLMSDatabaseClass;
++
++#define RYGEL_LMS_TYPE_ALBUM (rygel_lms_album_get_type ())
++#define RYGEL_LMS_ALBUM(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), RYGEL_LMS_TYPE_ALBUM, RygelLMSAlbum))
++#define RYGEL_LMS_ALBUM_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), RYGEL_LMS_TYPE_ALBUM, RygelLMSAlbumClass))
++#define RYGEL_LMS_IS_ALBUM(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), RYGEL_LMS_TYPE_ALBUM))
++#define RYGEL_LMS_IS_ALBUM_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), RYGEL_LMS_TYPE_ALBUM))
++#define RYGEL_LMS_ALBUM_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), RYGEL_LMS_TYPE_ALBUM, RygelLMSAlbumClass))
++
++typedef struct _RygelLMSAlbum RygelLMSAlbum;
++typedef struct _RygelLMSAlbumClass RygelLMSAlbumClass;
++#define _g_free0(var) (var = (g_free (var), NULL))
++
++struct _RygelLMSCategoryContainer {
++	RygelMediaContainer parent_instance;
++	RygelLMSCategoryContainerPrivate * priv;
++	sqlite3_stmt* stmt_all;
++	sqlite3_stmt* stmt_find_object;
++	sqlite3_stmt* stmt_added;
++	sqlite3_stmt* stmt_removed;
++	gchar* child_prefix;
++	gchar* ref_prefix;
++};
++
++struct _RygelLMSCategoryContainerClass {
++	RygelMediaContainerClass parent_class;
++	RygelMediaObject* (*object_from_statement) (RygelLMSCategoryContainer* self, sqlite3_stmt* statement);
++	gchar* (*get_sql_all_with_filter) (RygelLMSCategoryContainer* self, const gchar* filter);
++	gchar* (*get_sql_count_with_filter) (RygelLMSCategoryContainer* self, const gchar* filter);
++	guint (*get_child_count_with_filter) (RygelLMSCategoryContainer* self, const gchar* where_filter, GValueArray* args);
++	RygelMediaObjects* (*get_children_with_filter) (RygelLMSCategoryContainer* self, const gchar* where_filter, GValueArray* args, const gchar* sort_criteria, guint offset, guint max_count);
++};
++
++struct _RygelLMSArtist {
++	RygelLMSCategoryContainer parent_instance;
++	RygelLMSArtistPrivate * priv;
++};
++
++struct _RygelLMSArtistClass {
++	RygelLMSCategoryContainerClass parent_class;
++};
++
++
++static gpointer rygel_lms_artist_parent_class = NULL;
++
++GType rygel_lms_category_container_get_type (void) G_GNUC_CONST;
++GType rygel_lms_artist_get_type (void) G_GNUC_CONST;
++enum  {
++	RYGEL_LMS_ARTIST_DUMMY_PROPERTY
++};
++#define RYGEL_LMS_ARTIST_SQL_ALL_TEMPLATE "SELECT audio_albums.id, audio_albums.name " "FROM audio_albums " "WHERE audio_albums.artist_id = %s " "LIMIT ? OFFSET ?;"
++#define RYGEL_LMS_ARTIST_SQL_COUNT_TEMPLATE "SELECT COUNT(audio_albums.id) " "FROM audio_albums " "WHERE audio_albums.artist_id = %s"
++#define RYGEL_LMS_ARTIST_SQL_FIND_OBJECT_TEMPLATE "SELECT audio_albums.id, audio_albums.name " "FROM audio_albums " "WHERE audio_albums.id = ? AND audio_albums.artist_id = %s;"
++static gchar* rygel_lms_artist_get_sql_all (const gchar* id);
++static gchar* rygel_lms_artist_get_sql_find_object (const gchar* id);
++static gchar* rygel_lms_artist_get_sql_count (const gchar* id);
++static RygelMediaObject* rygel_lms_artist_real_object_from_statement (RygelLMSCategoryContainer* base, sqlite3_stmt* statement);
++gpointer rygel_lms_database_ref (gpointer instance);
++void rygel_lms_database_unref (gpointer instance);
++GParamSpec* rygel_lms_param_spec_database (const gchar* name, const gchar* nick, const gchar* blurb, GType object_type, GParamFlags flags);
++void rygel_lms_value_set_database (GValue* value, gpointer v_object);
++void rygel_lms_value_take_database (GValue* value, gpointer v_object);
++gpointer rygel_lms_value_get_database (const GValue* value);
++GType rygel_lms_database_get_type (void) G_GNUC_CONST;
++RygelLMSDatabase* rygel_lms_category_container_get_lms_db (RygelLMSCategoryContainer* self);
++RygelLMSAlbum* rygel_lms_album_new (const gchar* db_id, RygelMediaContainer* parent, const gchar* title, RygelLMSDatabase* lms_db);
++RygelLMSAlbum* rygel_lms_album_construct (GType object_type, const gchar* db_id, RygelMediaContainer* parent, const gchar* title, RygelLMSDatabase* lms_db);
++GType rygel_lms_album_get_type (void) G_GNUC_CONST;
++RygelLMSArtist* rygel_lms_artist_new (const gchar* id, RygelMediaContainer* parent, const gchar* title, RygelLMSDatabase* lms_db);
++RygelLMSArtist* rygel_lms_artist_construct (GType object_type, const gchar* id, RygelMediaContainer* parent, const gchar* title, RygelLMSDatabase* lms_db);
++RygelLMSCategoryContainer* rygel_lms_category_container_construct (GType object_type, const gchar* db_id, RygelMediaContainer* parent, const gchar* title, RygelLMSDatabase* lms_db, const gchar* sql_all, const gchar* sql_find_object, const gchar* sql_count, const gchar* sql_added, const gchar* sql_removed);
++
++
++static gchar* rygel_lms_artist_get_sql_all (const gchar* id) {
++	gchar* result = NULL;
++	const gchar* _tmp0_ = NULL;
++	gchar* _tmp1_ = NULL;
++	g_return_val_if_fail (id != NULL, NULL);
++	_tmp0_ = id;
++	_tmp1_ = g_strdup_printf (RYGEL_LMS_ARTIST_SQL_ALL_TEMPLATE, _tmp0_);
++	result = _tmp1_;
++	return result;
++}
++
++
++static gchar* rygel_lms_artist_get_sql_find_object (const gchar* id) {
++	gchar* result = NULL;
++	const gchar* _tmp0_ = NULL;
++	gchar* _tmp1_ = NULL;
++	g_return_val_if_fail (id != NULL, NULL);
++	_tmp0_ = id;
++	_tmp1_ = g_strdup_printf (RYGEL_LMS_ARTIST_SQL_FIND_OBJECT_TEMPLATE, _tmp0_);
++	result = _tmp1_;
++	return result;
++}
++
++
++static gchar* rygel_lms_artist_get_sql_count (const gchar* id) {
++	gchar* result = NULL;
++	const gchar* _tmp0_ = NULL;
++	gchar* _tmp1_ = NULL;
++	g_return_val_if_fail (id != NULL, NULL);
++	_tmp0_ = id;
++	_tmp1_ = g_strdup_printf (RYGEL_LMS_ARTIST_SQL_COUNT_TEMPLATE, _tmp0_);
++	result = _tmp1_;
++	return result;
++}
++
++
++static RygelMediaObject* rygel_lms_artist_real_object_from_statement (RygelLMSCategoryContainer* base, sqlite3_stmt* statement) {
++	RygelLMSArtist * self;
++	RygelMediaObject* result = NULL;
++	gchar* db_id = NULL;
++	sqlite3_stmt* _tmp0_ = NULL;
++	gint _tmp1_ = 0;
++	gchar* _tmp2_ = NULL;
++	gchar* title = NULL;
++	sqlite3_stmt* _tmp3_ = NULL;
++	const gchar* _tmp4_ = NULL;
++	gchar* _tmp5_ = NULL;
++	RygelLMSDatabase* _tmp6_ = NULL;
++	RygelLMSDatabase* _tmp7_ = NULL;
++	RygelLMSAlbum* _tmp8_ = NULL;
++	self = (RygelLMSArtist*) base;
++	g_return_val_if_fail (statement != NULL, NULL);
++	_tmp0_ = statement;
++	_tmp1_ = sqlite3_column_int (_tmp0_, 0);
++	_tmp2_ = g_strdup_printf ("%d", _tmp1_);
++	db_id = _tmp2_;
++	_tmp3_ = statement;
++	_tmp4_ = sqlite3_column_text (_tmp3_, 1);
++	_tmp5_ = g_strdup (_tmp4_);
++	title = _tmp5_;
++	_tmp6_ = rygel_lms_category_container_get_lms_db ((RygelLMSCategoryContainer*) self);
++	_tmp7_ = _tmp6_;
++	_tmp8_ = rygel_lms_album_new (db_id, (RygelMediaContainer*) self, title, _tmp7_);
++	result = (RygelMediaObject*) _tmp8_;
++	_g_free0 (title);
++	_g_free0 (db_id);
++	return result;
++}
++
++
++RygelLMSArtist* rygel_lms_artist_construct (GType object_type, const gchar* id, RygelMediaContainer* parent, const gchar* title, RygelLMSDatabase* lms_db) {
++	RygelLMSArtist * self = NULL;
++	const gchar* _tmp0_ = NULL;
++	RygelMediaContainer* _tmp1_ = NULL;
++	const gchar* _tmp2_ = NULL;
++	RygelLMSDatabase* _tmp3_ = NULL;
++	const gchar* _tmp4_ = NULL;
++	gchar* _tmp5_ = NULL;
++	gchar* _tmp6_ = NULL;
++	const gchar* _tmp7_ = NULL;
++	gchar* _tmp8_ = NULL;
++	gchar* _tmp9_ = NULL;
++	const gchar* _tmp10_ = NULL;
++	gchar* _tmp11_ = NULL;
++	gchar* _tmp12_ = NULL;
++	g_return_val_if_fail (id != NULL, NULL);
++	g_return_val_if_fail (parent != NULL, NULL);
++	g_return_val_if_fail (title != NULL, NULL);
++	g_return_val_if_fail (lms_db != NULL, NULL);
++	_tmp0_ = id;
++	_tmp1_ = parent;
++	_tmp2_ = title;
++	_tmp3_ = lms_db;
++	_tmp4_ = id;
++	_tmp5_ = rygel_lms_artist_get_sql_all (_tmp4_);
++	_tmp6_ = _tmp5_;
++	_tmp7_ = id;
++	_tmp8_ = rygel_lms_artist_get_sql_find_object (_tmp7_);
++	_tmp9_ = _tmp8_;
++	_tmp10_ = id;
++	_tmp11_ = rygel_lms_artist_get_sql_count (_tmp10_);
++	_tmp12_ = _tmp11_;
++	self = (RygelLMSArtist*) rygel_lms_category_container_construct (object_type, _tmp0_, _tmp1_, _tmp2_, _tmp3_, _tmp6_, _tmp9_, _tmp12_, NULL, NULL);
++	_g_free0 (_tmp12_);
++	_g_free0 (_tmp9_);
++	_g_free0 (_tmp6_);
++	return self;
++}
++
++
++RygelLMSArtist* rygel_lms_artist_new (const gchar* id, RygelMediaContainer* parent, const gchar* title, RygelLMSDatabase* lms_db) {
++	return rygel_lms_artist_construct (RYGEL_LMS_TYPE_ARTIST, id, parent, title, lms_db);
++}
++
++
++static void rygel_lms_artist_class_init (RygelLMSArtistClass * klass) {
++	rygel_lms_artist_parent_class = g_type_class_peek_parent (klass);
++	((RygelLMSCategoryContainerClass *) klass)->object_from_statement = rygel_lms_artist_real_object_from_statement;
++}
++
++
++static void rygel_lms_artist_instance_init (RygelLMSArtist * self) {
++}
++
++
++GType rygel_lms_artist_get_type (void) {
++	static volatile gsize rygel_lms_artist_type_id__volatile = 0;
++	if (g_once_init_enter (&rygel_lms_artist_type_id__volatile)) {
++		static const GTypeInfo g_define_type_info = { sizeof (RygelLMSArtistClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) rygel_lms_artist_class_init, (GClassFinalizeFunc) NULL, NULL, sizeof (RygelLMSArtist), 0, (GInstanceInitFunc) rygel_lms_artist_instance_init, NULL };
++		GType rygel_lms_artist_type_id;
++		rygel_lms_artist_type_id = g_type_register_static (RYGEL_LMS_TYPE_CATEGORY_CONTAINER, "RygelLMSArtist", &g_define_type_info, 0);
++		g_once_init_leave (&rygel_lms_artist_type_id__volatile, rygel_lms_artist_type_id);
++	}
++	return rygel_lms_artist_type_id__volatile;
++}
++
++
++
+diff --git a/src/plugins/lms/rygel-lms-artists.c b/src/plugins/lms/rygel-lms-artists.c
+new file mode 100644
+index 0000000..3ac85bc
+--- /dev/null
++++ b/src/plugins/lms/rygel-lms-artists.c
+@@ -0,0 +1,214 @@
++/* rygel-lms-artists.c generated by valac 0.28.0, the Vala compiler
++ * generated from rygel-lms-artists.vala, do not modify */
++
++/*
++ * Copyright (C) 2013 Intel Corporation.
++ *
++ * Author: Jussi Kukkonen <jussi.kukkonen@intel.com>
++ *
++ * 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 <glib.h>
++#include <glib-object.h>
++#include <rygel-server.h>
++#include <sqlite3.h>
++#include <stdlib.h>
++#include <string.h>
++
++
++#define RYGEL_LMS_TYPE_CATEGORY_CONTAINER (rygel_lms_category_container_get_type ())
++#define RYGEL_LMS_CATEGORY_CONTAINER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), RYGEL_LMS_TYPE_CATEGORY_CONTAINER, RygelLMSCategoryContainer))
++#define RYGEL_LMS_CATEGORY_CONTAINER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), RYGEL_LMS_TYPE_CATEGORY_CONTAINER, RygelLMSCategoryContainerClass))
++#define RYGEL_LMS_IS_CATEGORY_CONTAINER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), RYGEL_LMS_TYPE_CATEGORY_CONTAINER))
++#define RYGEL_LMS_IS_CATEGORY_CONTAINER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), RYGEL_LMS_TYPE_CATEGORY_CONTAINER))
++#define RYGEL_LMS_CATEGORY_CONTAINER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), RYGEL_LMS_TYPE_CATEGORY_CONTAINER, RygelLMSCategoryContainerClass))
++
++typedef struct _RygelLMSCategoryContainer RygelLMSCategoryContainer;
++typedef struct _RygelLMSCategoryContainerClass RygelLMSCategoryContainerClass;
++typedef struct _RygelLMSCategoryContainerPrivate RygelLMSCategoryContainerPrivate;
++
++#define RYGEL_LMS_TYPE_ARTISTS (rygel_lms_artists_get_type ())
++#define RYGEL_LMS_ARTISTS(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), RYGEL_LMS_TYPE_ARTISTS, RygelLMSArtists))
++#define RYGEL_LMS_ARTISTS_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), RYGEL_LMS_TYPE_ARTISTS, RygelLMSArtistsClass))
++#define RYGEL_LMS_IS_ARTISTS(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), RYGEL_LMS_TYPE_ARTISTS))
++#define RYGEL_LMS_IS_ARTISTS_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), RYGEL_LMS_TYPE_ARTISTS))
++#define RYGEL_LMS_ARTISTS_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), RYGEL_LMS_TYPE_ARTISTS, RygelLMSArtistsClass))
++
++typedef struct _RygelLMSArtists RygelLMSArtists;
++typedef struct _RygelLMSArtistsClass RygelLMSArtistsClass;
++typedef struct _RygelLMSArtistsPrivate RygelLMSArtistsPrivate;
++
++#define RYGEL_LMS_TYPE_DATABASE (rygel_lms_database_get_type ())
++#define RYGEL_LMS_DATABASE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), RYGEL_LMS_TYPE_DATABASE, RygelLMSDatabase))
++#define RYGEL_LMS_DATABASE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), RYGEL_LMS_TYPE_DATABASE, RygelLMSDatabaseClass))
++#define RYGEL_LMS_IS_DATABASE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), RYGEL_LMS_TYPE_DATABASE))
++#define RYGEL_LMS_IS_DATABASE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), RYGEL_LMS_TYPE_DATABASE))
++#define RYGEL_LMS_DATABASE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), RYGEL_LMS_TYPE_DATABASE, RygelLMSDatabaseClass))
++
++typedef struct _RygelLMSDatabase RygelLMSDatabase;
++typedef struct _RygelLMSDatabaseClass RygelLMSDatabaseClass;
++
++#define RYGEL_LMS_TYPE_ARTIST (rygel_lms_artist_get_type ())
++#define RYGEL_LMS_ARTIST(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), RYGEL_LMS_TYPE_ARTIST, RygelLMSArtist))
++#define RYGEL_LMS_ARTIST_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), RYGEL_LMS_TYPE_ARTIST, RygelLMSArtistClass))
++#define RYGEL_LMS_IS_ARTIST(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), RYGEL_LMS_TYPE_ARTIST))
++#define RYGEL_LMS_IS_ARTIST_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), RYGEL_LMS_TYPE_ARTIST))
++#define RYGEL_LMS_ARTIST_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), RYGEL_LMS_TYPE_ARTIST, RygelLMSArtistClass))
++
++typedef struct _RygelLMSArtist RygelLMSArtist;
++typedef struct _RygelLMSArtistClass RygelLMSArtistClass;
++#define _g_free0(var) (var = (g_free (var), NULL))
++
++struct _RygelLMSCategoryContainer {
++	RygelMediaContainer parent_instance;
++	RygelLMSCategoryContainerPrivate * priv;
++	sqlite3_stmt* stmt_all;
++	sqlite3_stmt* stmt_find_object;
++	sqlite3_stmt* stmt_added;
++	sqlite3_stmt* stmt_removed;
++	gchar* child_prefix;
++	gchar* ref_prefix;
++};
++
++struct _RygelLMSCategoryContainerClass {
++	RygelMediaContainerClass parent_class;
++	RygelMediaObject* (*object_from_statement) (RygelLMSCategoryContainer* self, sqlite3_stmt* statement);
++	gchar* (*get_sql_all_with_filter) (RygelLMSCategoryContainer* self, const gchar* filter);
++	gchar* (*get_sql_count_with_filter) (RygelLMSCategoryContainer* self, const gchar* filter);
++	guint (*get_child_count_with_filter) (RygelLMSCategoryContainer* self, const gchar* where_filter, GValueArray* args);
++	RygelMediaObjects* (*get_children_with_filter) (RygelLMSCategoryContainer* self, const gchar* where_filter, GValueArray* args, const gchar* sort_criteria, guint offset, guint max_count);
++};
++
++struct _RygelLMSArtists {
++	RygelLMSCategoryContainer parent_instance;
++	RygelLMSArtistsPrivate * priv;
++};
++
++struct _RygelLMSArtistsClass {
++	RygelLMSCategoryContainerClass parent_class;
++};
++
++
++static gpointer rygel_lms_artists_parent_class = NULL;
++
++GType rygel_lms_category_container_get_type (void) G_GNUC_CONST;
++GType rygel_lms_artists_get_type (void) G_GNUC_CONST;
++enum  {
++	RYGEL_LMS_ARTISTS_DUMMY_PROPERTY
++};
++#define RYGEL_LMS_ARTISTS_SQL_ALL "SELECT audio_artists.id, audio_artists.name " "FROM audio_artists " "LIMIT ? OFFSET ?;"
++#define RYGEL_LMS_ARTISTS_SQL_COUNT "SELECT COUNT(audio_artists.id) " "FROM audio_artists;"
++#define RYGEL_LMS_ARTISTS_SQL_FIND_OBJECT "SELECT audio_artists.id, audio_artists.name " "FROM audio_artists " "WHERE audio_artists.id = ?;"
++static RygelMediaObject* rygel_lms_artists_real_object_from_statement (RygelLMSCategoryContainer* base, sqlite3_stmt* statement);
++gpointer rygel_lms_database_ref (gpointer instance);
++void rygel_lms_database_unref (gpointer instance);
++GParamSpec* rygel_lms_param_spec_database (const gchar* name, const gchar* nick, const gchar* blurb, GType object_type, GParamFlags flags);
++void rygel_lms_value_set_database (GValue* value, gpointer v_object);
++void rygel_lms_value_take_database (GValue* value, gpointer v_object);
++gpointer rygel_lms_value_get_database (const GValue* value);
++GType rygel_lms_database_get_type (void) G_GNUC_CONST;
++RygelLMSDatabase* rygel_lms_category_container_get_lms_db (RygelLMSCategoryContainer* self);
++RygelLMSArtist* rygel_lms_artist_new (const gchar* id, RygelMediaContainer* parent, const gchar* title, RygelLMSDatabase* lms_db);
++RygelLMSArtist* rygel_lms_artist_construct (GType object_type, const gchar* id, RygelMediaContainer* parent, const gchar* title, RygelLMSDatabase* lms_db);
++GType rygel_lms_artist_get_type (void) G_GNUC_CONST;
++RygelLMSArtists* rygel_lms_artists_new (const gchar* id, RygelMediaContainer* parent, const gchar* title, RygelLMSDatabase* lms_db);
++RygelLMSArtists* rygel_lms_artists_construct (GType object_type, const gchar* id, RygelMediaContainer* parent, const gchar* title, RygelLMSDatabase* lms_db);
++RygelLMSCategoryContainer* rygel_lms_category_container_construct (GType object_type, const gchar* db_id, RygelMediaContainer* parent, const gchar* title, RygelLMSDatabase* lms_db, const gchar* sql_all, const gchar* sql_find_object, const gchar* sql_count, const gchar* sql_added, const gchar* sql_removed);
++
++
++static RygelMediaObject* rygel_lms_artists_real_object_from_statement (RygelLMSCategoryContainer* base, sqlite3_stmt* statement) {
++	RygelLMSArtists * self;
++	RygelMediaObject* result = NULL;
++	gchar* db_id = NULL;
++	sqlite3_stmt* _tmp0_ = NULL;
++	gint _tmp1_ = 0;
++	gchar* _tmp2_ = NULL;
++	gchar* title = NULL;
++	sqlite3_stmt* _tmp3_ = NULL;
++	const gchar* _tmp4_ = NULL;
++	gchar* _tmp5_ = NULL;
++	RygelLMSDatabase* _tmp6_ = NULL;
++	RygelLMSDatabase* _tmp7_ = NULL;
++	RygelLMSArtist* _tmp8_ = NULL;
++	self = (RygelLMSArtists*) base;
++	g_return_val_if_fail (statement != NULL, NULL);
++	_tmp0_ = statement;
++	_tmp1_ = sqlite3_column_int (_tmp0_, 0);
++	_tmp2_ = g_strdup_printf ("%d", _tmp1_);
++	db_id = _tmp2_;
++	_tmp3_ = statement;
++	_tmp4_ = sqlite3_column_text (_tmp3_, 1);
++	_tmp5_ = g_strdup (_tmp4_);
++	title = _tmp5_;
++	_tmp6_ = rygel_lms_category_container_get_lms_db ((RygelLMSCategoryContainer*) self);
++	_tmp7_ = _tmp6_;
++	_tmp8_ = rygel_lms_artist_new (db_id, (RygelMediaContainer*) self, title, _tmp7_);
++	result = (RygelMediaObject*) _tmp8_;
++	_g_free0 (title);
++	_g_free0 (db_id);
++	return result;
++}
++
++
++RygelLMSArtists* rygel_lms_artists_construct (GType object_type, const gchar* id, RygelMediaContainer* parent, const gchar* title, RygelLMSDatabase* lms_db) {
++	RygelLMSArtists * self = NULL;
++	const gchar* _tmp0_ = NULL;
++	RygelMediaContainer* _tmp1_ = NULL;
++	const gchar* _tmp2_ = NULL;
++	RygelLMSDatabase* _tmp3_ = NULL;
++	g_return_val_if_fail (id != NULL, NULL);
++	g_return_val_if_fail (parent != NULL, NULL);
++	g_return_val_if_fail (title != NULL, NULL);
++	g_return_val_if_fail (lms_db != NULL, NULL);
++	_tmp0_ = id;
++	_tmp1_ = parent;
++	_tmp2_ = title;
++	_tmp3_ = lms_db;
++	self = (RygelLMSArtists*) rygel_lms_category_container_construct (object_type, _tmp0_, _tmp1_, _tmp2_, _tmp3_, RYGEL_LMS_ARTISTS_SQL_ALL, RYGEL_LMS_ARTISTS_SQL_FIND_OBJECT, RYGEL_LMS_ARTISTS_SQL_COUNT, NULL, NULL);
++	return self;
++}
++
++
++RygelLMSArtists* rygel_lms_artists_new (const gchar* id, RygelMediaContainer* parent, const gchar* title, RygelLMSDatabase* lms_db) {
++	return rygel_lms_artists_construct (RYGEL_LMS_TYPE_ARTISTS, id, parent, title, lms_db);
++}
++
++
++static void rygel_lms_artists_class_init (RygelLMSArtistsClass * klass) {
++	rygel_lms_artists_parent_class = g_type_class_peek_parent (klass);
++	((RygelLMSCategoryContainerClass *) klass)->object_from_statement = rygel_lms_artists_real_object_from_statement;
++}
++
++
++static void rygel_lms_artists_instance_init (RygelLMSArtists * self) {
++}
++
++
++GType rygel_lms_artists_get_type (void) {
++	static volatile gsize rygel_lms_artists_type_id__volatile = 0;
++	if (g_once_init_enter (&rygel_lms_artists_type_id__volatile)) {
++		static const GTypeInfo g_define_type_info = { sizeof (RygelLMSArtistsClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) rygel_lms_artists_class_init, (GClassFinalizeFunc) NULL, NULL, sizeof (RygelLMSArtists), 0, (GInstanceInitFunc) rygel_lms_artists_instance_init, NULL };
++		GType rygel_lms_artists_type_id;
++		rygel_lms_artists_type_id = g_type_register_static (RYGEL_LMS_TYPE_CATEGORY_CONTAINER, "RygelLMSArtists", &g_define_type_info, 0);
++		g_once_init_leave (&rygel_lms_artists_type_id__volatile, rygel_lms_artists_type_id);
++	}
++	return rygel_lms_artists_type_id__volatile;
++}
++
++
++
+diff --git a/src/plugins/lms/rygel-lms-category-container.c b/src/plugins/lms/rygel-lms-category-container.c
+new file mode 100644
+index 0000000..21692d0
+--- /dev/null
++++ b/src/plugins/lms/rygel-lms-category-container.c
+@@ -0,0 +1,2772 @@
++/* rygel-lms-category-container.c generated by valac 0.28.0, the Vala compiler
++ * generated from rygel-lms-category-container.vala, do not modify */
++
++/*
++ * Copyright (C) 2009,2010 Jens Georg <mail@jensge.org>,
++ *           (C) 2013 Intel Corporation.
++ *
++ * Author: Jussi Kukkonen <jussi.kukkonen@intel.com>
++ *
++ * 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 <glib.h>
++#include <glib-object.h>
++#include <rygel-server.h>
++#include <sqlite3.h>
++#include <stdlib.h>
++#include <string.h>
++#include <gee.h>
++#include <libgupnp-av/gupnp-av.h>
++#include <gio/gio.h>
++
++
++#define RYGEL_LMS_TYPE_CATEGORY_CONTAINER (rygel_lms_category_container_get_type ())
++#define RYGEL_LMS_CATEGORY_CONTAINER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), RYGEL_LMS_TYPE_CATEGORY_CONTAINER, RygelLMSCategoryContainer))
++#define RYGEL_LMS_CATEGORY_CONTAINER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), RYGEL_LMS_TYPE_CATEGORY_CONTAINER, RygelLMSCategoryContainerClass))
++#define RYGEL_LMS_IS_CATEGORY_CONTAINER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), RYGEL_LMS_TYPE_CATEGORY_CONTAINER))
++#define RYGEL_LMS_IS_CATEGORY_CONTAINER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), RYGEL_LMS_TYPE_CATEGORY_CONTAINER))
++#define RYGEL_LMS_CATEGORY_CONTAINER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), RYGEL_LMS_TYPE_CATEGORY_CONTAINER, RygelLMSCategoryContainerClass))
++
++typedef struct _RygelLMSCategoryContainer RygelLMSCategoryContainer;
++typedef struct _RygelLMSCategoryContainerClass RygelLMSCategoryContainerClass;
++typedef struct _RygelLMSCategoryContainerPrivate RygelLMSCategoryContainerPrivate;
++
++#define RYGEL_LMS_TYPE_DATABASE (rygel_lms_database_get_type ())
++#define RYGEL_LMS_DATABASE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), RYGEL_LMS_TYPE_DATABASE, RygelLMSDatabase))
++#define RYGEL_LMS_DATABASE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), RYGEL_LMS_TYPE_DATABASE, RygelLMSDatabaseClass))
++#define RYGEL_LMS_IS_DATABASE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), RYGEL_LMS_TYPE_DATABASE))
++#define RYGEL_LMS_IS_DATABASE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), RYGEL_LMS_TYPE_DATABASE))
++#define RYGEL_LMS_DATABASE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), RYGEL_LMS_TYPE_DATABASE, RygelLMSDatabaseClass))
++
++typedef struct _RygelLMSDatabase RygelLMSDatabase;
++typedef struct _RygelLMSDatabaseClass RygelLMSDatabaseClass;
++#define _g_object_unref0(var) ((var == NULL) ? NULL : (var = (g_object_unref (var), NULL)))
++#define _g_free0(var) (var = (g_free (var), NULL))
++#define _sqlite3_finalize0(var) ((var == NULL) ? NULL : (var = (sqlite3_finalize (var), NULL)))
++#define __vala_GValue_free0(var) ((var == NULL) ? NULL : (var = (_vala_GValue_free (var), NULL)))
++
++#define RYGEL_LMS_TYPE_SQL_OPERATOR (rygel_lms_sql_operator_get_type ())
++#define RYGEL_LMS_SQL_OPERATOR(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), RYGEL_LMS_TYPE_SQL_OPERATOR, RygelLMSSqlOperator))
++#define RYGEL_LMS_SQL_OPERATOR_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), RYGEL_LMS_TYPE_SQL_OPERATOR, RygelLMSSqlOperatorClass))
++#define RYGEL_LMS_IS_SQL_OPERATOR(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), RYGEL_LMS_TYPE_SQL_OPERATOR))
++#define RYGEL_LMS_IS_SQL_OPERATOR_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), RYGEL_LMS_TYPE_SQL_OPERATOR))
++#define RYGEL_LMS_SQL_OPERATOR_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), RYGEL_LMS_TYPE_SQL_OPERATOR, RygelLMSSqlOperatorClass))
++
++typedef struct _RygelLMSSqlOperator RygelLMSSqlOperator;
++typedef struct _RygelLMSSqlOperatorClass RygelLMSSqlOperatorClass;
++
++#define RYGEL_LMS_TYPE_SQL_FUNCTION (rygel_lms_sql_function_get_type ())
++#define RYGEL_LMS_SQL_FUNCTION(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), RYGEL_LMS_TYPE_SQL_FUNCTION, RygelLMSSqlFunction))
++#define RYGEL_LMS_SQL_FUNCTION_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), RYGEL_LMS_TYPE_SQL_FUNCTION, RygelLMSSqlFunctionClass))
++#define RYGEL_LMS_IS_SQL_FUNCTION(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), RYGEL_LMS_TYPE_SQL_FUNCTION))
++#define RYGEL_LMS_IS_SQL_FUNCTION_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), RYGEL_LMS_TYPE_SQL_FUNCTION))
++#define RYGEL_LMS_SQL_FUNCTION_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), RYGEL_LMS_TYPE_SQL_FUNCTION, RygelLMSSqlFunctionClass))
++
++typedef struct _RygelLMSSqlFunction RygelLMSSqlFunction;
++typedef struct _RygelLMSSqlFunctionClass RygelLMSSqlFunctionClass;
++#define _g_error_free0(var) ((var == NULL) ? NULL : (var = (g_error_free (var), NULL)))
++#define _rygel_search_expression_unref0(var) ((var == NULL) ? NULL : (var = (rygel_search_expression_unref (var), NULL)))
++#define _g_value_array_free0(var) ((var == NULL) ? NULL : (var = (g_value_array_free (var), NULL)))
++typedef struct _RygelLmsCategoryContainerSearchData RygelLmsCategoryContainerSearchData;
++typedef struct _RygelLmsCategoryContainerGetChildrenData RygelLmsCategoryContainerGetChildrenData;
++typedef struct _RygelLmsCategoryContainerFindObjectData RygelLmsCategoryContainerFindObjectData;
++typedef struct _RygelLmsCategoryContainerAddChildData RygelLmsCategoryContainerAddChildData;
++typedef struct _RygelLmsCategoryContainerRemoveChildData RygelLmsCategoryContainerRemoveChildData;
++
++typedef enum  {
++	RYGEL_LMS_CATEGORY_CONTAINER_ERROR_SQLITE_ERROR,
++	RYGEL_LMS_CATEGORY_CONTAINER_ERROR_GENERAL_ERROR,
++	RYGEL_LMS_CATEGORY_CONTAINER_ERROR_INVALID_TYPE,
++	RYGEL_LMS_CATEGORY_CONTAINER_ERROR_UNSUPPORTED_SEARCH
++} RygelLMSCategoryContainerError;
++#define RYGEL_LMS_CATEGORY_CONTAINER_ERROR rygel_lms_category_container_error_quark ()
++struct _RygelLMSCategoryContainer {
++	RygelMediaContainer parent_instance;
++	RygelLMSCategoryContainerPrivate * priv;
++	sqlite3_stmt* stmt_all;
++	sqlite3_stmt* stmt_find_object;
++	sqlite3_stmt* stmt_added;
++	sqlite3_stmt* stmt_removed;
++	gchar* child_prefix;
++	gchar* ref_prefix;
++};
++
++struct _RygelLMSCategoryContainerClass {
++	RygelMediaContainerClass parent_class;
++	RygelMediaObject* (*object_from_statement) (RygelLMSCategoryContainer* self, sqlite3_stmt* statement);
++	gchar* (*get_sql_all_with_filter) (RygelLMSCategoryContainer* self, const gchar* filter);
++	gchar* (*get_sql_count_with_filter) (RygelLMSCategoryContainer* self, const gchar* filter);
++	guint (*get_child_count_with_filter) (RygelLMSCategoryContainer* self, const gchar* where_filter, GValueArray* args);
++	RygelMediaObjects* (*get_children_with_filter) (RygelLMSCategoryContainer* self, const gchar* where_filter, GValueArray* args, const gchar* sort_criteria, guint offset, guint max_count);
++};
++
++struct _RygelLMSCategoryContainerPrivate {
++	GeeArrayList* _search_classes;
++	RygelLMSDatabase* _lms_db;
++	gchar* _db_id;
++	gchar* _sql_all;
++	gchar* _sql_find_object;
++	gchar* _sql_count;
++	gchar* _sql_added;
++	gchar* _sql_removed;
++};
++
++typedef enum  {
++	RYGEL_LMS_DATABASE_ERROR_OPEN,
++	RYGEL_LMS_DATABASE_ERROR_PREPARE,
++	RYGEL_LMS_DATABASE_ERROR_BIND,
++	RYGEL_LMS_DATABASE_ERROR_STEP,
++	RYGEL_LMS_DATABASE_ERROR_NOT_FOUND
++} RygelLMSDatabaseError;
++#define RYGEL_LMS_DATABASE_ERROR rygel_lms_database_error_quark ()
++struct _RygelLmsCategoryContainerSearchData {
++	int _state_;
++	GObject* _source_object_;
++	GAsyncResult* _res_;
++	GSimpleAsyncResult* _async_result;
++	RygelLMSCategoryContainer* self;
++	RygelSearchExpression* expression;
++	guint offset;
++	guint max_count;
++	guint total_matches;
++	gchar* sort_criteria;
++	GCancellable* cancellable;
++	RygelMediaObjects* result;
++	GValueArray* args;
++	GValueArray* _tmp0_;
++	gchar* filter;
++	RygelSearchExpression* _tmp1_;
++	GValueArray* _tmp2_;
++	gchar* _tmp3_;
++	const gchar* _tmp4_;
++	GValueArray* _tmp5_;
++	guint _tmp6_;
++	RygelSearchExpression* _tmp7_;
++	RygelSearchExpression* _tmp8_;
++	gchar* _tmp9_;
++	gchar* _tmp10_;
++	const gchar* _tmp11_;
++	guint _tmp12_;
++	guint _tmp13_;
++	const gchar* _tmp14_;
++	GValueArray* _tmp15_;
++	const gchar* _tmp16_;
++	guint _tmp17_;
++	guint _tmp18_;
++	RygelMediaObjects* _tmp19_;
++	GError* e;
++	GError* _tmp20_;
++	const gchar* _tmp21_;
++	RygelMediaObjects* _tmp22_;
++	RygelSearchExpression* _tmp23_;
++	guint _tmp24_;
++	guint _tmp25_;
++	const gchar* _tmp26_;
++	GCancellable* _tmp27_;
++	guint _tmp28_;
++	RygelMediaObjects* _tmp29_;
++	RygelMediaObjects* _tmp30_;
++	GError * _inner_error_;
++};
++
++struct _RygelLmsCategoryContainerGetChildrenData {
++	int _state_;
++	GObject* _source_object_;
++	GAsyncResult* _res_;
++	GSimpleAsyncResult* _async_result;
++	RygelLMSCategoryContainer* self;
++	guint offset;
++	guint max_count;
++	gchar* sort_criteria;
++	GCancellable* cancellable;
++	RygelMediaObjects* result;
++	RygelMediaObjects* retval;
++	RygelMediaObjects* _tmp0_;
++	sqlite3_stmt* _tmp1_;
++	guint _tmp2_;
++	guint _tmp3_;
++	const gchar* _tmp4_;
++	gboolean _tmp5_;
++	sqlite3_stmt* _tmp6_;
++	gboolean _tmp7_;
++	RygelMediaObjects* _tmp8_;
++	sqlite3_stmt* _tmp9_;
++	RygelMediaObject* _tmp10_;
++	RygelMediaObject* _tmp11_;
++	GError * _inner_error_;
++};
++
++struct _RygelLmsCategoryContainerFindObjectData {
++	int _state_;
++	GObject* _source_object_;
++	GAsyncResult* _res_;
++	GSimpleAsyncResult* _async_result;
++	RygelLMSCategoryContainer* self;
++	gchar* id;
++	GCancellable* cancellable;
++	RygelMediaObject* result;
++	const gchar* _tmp0_;
++	const gchar* _tmp1_;
++	gboolean _tmp2_;
++	RygelMediaObject* object;
++	gchar* real_id;
++	const gchar* _tmp3_;
++	const gchar* _tmp4_;
++	gint _tmp5_;
++	gint _tmp6_;
++	gchar* _tmp7_;
++	gint index;
++	const gchar* _tmp8_;
++	gint _tmp9_;
++	gint _tmp10_;
++	const gchar* _tmp11_;
++	gint _tmp12_;
++	gchar* _tmp13_;
++	const gchar* _tmp14_;
++	sqlite3_stmt* _tmp15_;
++	RygelMediaObject* child;
++	sqlite3_stmt* _tmp16_;
++	RygelMediaObject* _tmp17_;
++	gint _tmp18_;
++	RygelMediaObject* _tmp19_;
++	RygelMediaObject* _tmp20_;
++	RygelLMSCategoryContainer* container;
++	RygelMediaObject* _tmp21_;
++	RygelLMSCategoryContainer* _tmp22_;
++	RygelMediaObject* _tmp23_;
++	RygelLMSCategoryContainer* _tmp24_;
++	const gchar* _tmp25_;
++	GCancellable* _tmp26_;
++	RygelMediaObject* _tmp27_;
++	RygelMediaObject* _tmp28_;
++	RygelMediaObject* _tmp29_;
++	RygelMediaObject* _tmp30_;
++	RygelMediaContainer* _tmp31_;
++	RygelMediaContainer* _tmp32_;
++	GError* e;
++	const gchar* _tmp33_;
++	const gchar* _tmp34_;
++	const gchar* _tmp35_;
++	GError* _tmp36_;
++	const gchar* _tmp37_;
++	GError * _inner_error_;
++};
++
++struct _RygelLmsCategoryContainerAddChildData {
++	int _state_;
++	GObject* _source_object_;
++	GAsyncResult* _res_;
++	GSimpleAsyncResult* _async_result;
++	RygelLMSCategoryContainer* self;
++	RygelMediaObject* object;
++};
++
++struct _RygelLmsCategoryContainerRemoveChildData {
++	int _state_;
++	GObject* _source_object_;
++	GAsyncResult* _res_;
++	GSimpleAsyncResult* _async_result;
++	RygelLMSCategoryContainer* self;
++	RygelMediaObject* object;
++};
++
++
++static gpointer rygel_lms_category_container_parent_class = NULL;
++static RygelTrackableContainerIface* rygel_lms_category_container_rygel_trackable_container_parent_iface = NULL;
++static RygelSearchableContainerIface* rygel_lms_category_container_rygel_searchable_container_parent_iface = NULL;
++
++GQuark rygel_lms_category_container_error_quark (void);
++GType rygel_lms_category_container_get_type (void) G_GNUC_CONST;
++gpointer rygel_lms_database_ref (gpointer instance);
++void rygel_lms_database_unref (gpointer instance);
++GParamSpec* rygel_lms_param_spec_database (const gchar* name, const gchar* nick, const gchar* blurb, GType object_type, GParamFlags flags);
++void rygel_lms_value_set_database (GValue* value, gpointer v_object);
++void rygel_lms_value_take_database (GValue* value, gpointer v_object);
++gpointer rygel_lms_value_get_database (const GValue* value);
++GType rygel_lms_database_get_type (void) G_GNUC_CONST;
++#define RYGEL_LMS_CATEGORY_CONTAINER_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), RYGEL_LMS_TYPE_CATEGORY_CONTAINER, RygelLMSCategoryContainerPrivate))
++enum  {
++	RYGEL_LMS_CATEGORY_CONTAINER_DUMMY_PROPERTY,
++	RYGEL_LMS_CATEGORY_CONTAINER_SEARCH_CLASSES,
++	RYGEL_LMS_CATEGORY_CONTAINER_LMS_DB,
++	RYGEL_LMS_CATEGORY_CONTAINER_DB_ID,
++	RYGEL_LMS_CATEGORY_CONTAINER_SQL_ALL,
++	RYGEL_LMS_CATEGORY_CONTAINER_SQL_FIND_OBJECT,
++	RYGEL_LMS_CATEGORY_CONTAINER_SQL_COUNT,
++	RYGEL_LMS_CATEGORY_CONTAINER_SQL_ADDED,
++	RYGEL_LMS_CATEGORY_CONTAINER_SQL_REMOVED
++};
++RygelMediaObject* rygel_lms_category_container_object_from_statement (RygelLMSCategoryContainer* self, sqlite3_stmt* statement);
++static RygelMediaObject* rygel_lms_category_container_real_object_from_statement (RygelLMSCategoryContainer* self, sqlite3_stmt* statement);
++gchar* rygel_lms_category_container_get_sql_all_with_filter (RygelLMSCategoryContainer* self, const gchar* filter);
++static gchar* rygel_lms_category_container_real_get_sql_all_with_filter (RygelLMSCategoryContainer* self, const gchar* filter);
++const gchar* rygel_lms_category_container_get_sql_all (RygelLMSCategoryContainer* self);
++gchar* rygel_lms_category_container_get_sql_count_with_filter (RygelLMSCategoryContainer* self, const gchar* filter);
++static gchar* rygel_lms_category_container_real_get_sql_count_with_filter (RygelLMSCategoryContainer* self, const gchar* filter);
++const gchar* rygel_lms_category_container_get_sql_count (RygelLMSCategoryContainer* self);
++static gchar* rygel_lms_category_container_map_operand_to_column (const gchar* operand, gchar** collate, gboolean for_sort, GError** error);
++static gchar* rygel_lms_category_container_relational_expression_to_sql (RygelRelationalExpression* exp, GValueArray* args, GError** error);
++static void _vala_GValue_free (GValue* self);
++GType rygel_lms_sql_operator_get_type (void) G_GNUC_CONST;
++RygelLMSSqlOperator* rygel_lms_sql_operator_new_from_search_criteria_op (GUPnPSearchCriteriaOp op, const gchar* arg, const gchar* collate);
++RygelLMSSqlOperator* rygel_lms_sql_operator_construct_from_search_criteria_op (GType object_type, GUPnPSearchCriteriaOp op, const gchar* arg, const gchar* collate);
++RygelLMSSqlFunction* rygel_lms_sql_function_new (const gchar* name, const gchar* arg);
++RygelLMSSqlFunction* rygel_lms_sql_function_construct (GType object_type, const gchar* name, const gchar* arg);
++GType rygel_lms_sql_function_get_type (void) G_GNUC_CONST;
++RygelLMSSqlOperator* rygel_lms_sql_operator_new (const gchar* name, const gchar* arg, const gchar* collate);
++RygelLMSSqlOperator* rygel_lms_sql_operator_construct (GType object_type, const gchar* name, const gchar* arg, const gchar* collate);
++gchar* rygel_lms_sql_operator_to_string (RygelLMSSqlOperator* self);
++static gchar* rygel_lms_category_container_logical_expression_to_sql (RygelLogicalExpression* expression, GValueArray* args, GError** error);
++static gchar* rygel_lms_category_container_search_expression_to_sql (RygelSearchExpression* expression, GValueArray* args, GError** error);
++guint rygel_lms_category_container_get_child_count_with_filter (RygelLMSCategoryContainer* self, const gchar* where_filter, GValueArray* args);
++static guint rygel_lms_category_container_real_get_child_count_with_filter (RygelLMSCategoryContainer* self, const gchar* where_filter, GValueArray* args);
++RygelLMSDatabase* rygel_lms_category_container_get_lms_db (RygelLMSCategoryContainer* self);
++GQuark rygel_lms_database_error_quark (void);
++sqlite3_stmt* rygel_lms_database_prepare_and_init (RygelLMSDatabase* self, const gchar* query, GValue* arguments, int arguments_length1, GError** error);
++RygelMediaObjects* rygel_lms_category_container_get_children_with_filter (RygelLMSCategoryContainer* self, const gchar* where_filter, GValueArray* args, const gchar* sort_criteria, guint offset, guint max_count);
++static RygelMediaObjects* rygel_lms_category_container_real_get_children_with_filter (RygelLMSCategoryContainer* self, const gchar* where_filter, GValueArray* args, const gchar* sort_criteria, guint offset, guint max_count);
++gboolean rygel_lms_database_get_children_step (sqlite3_stmt* stmt, GError** error);
++static void rygel_lms_category_container_real_search_data_free (gpointer _data);
++static void rygel_lms_category_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_lms_category_container_real_search_co (RygelLmsCategoryContainerSearchData* _data_);
++static void rygel_lms_category_container_search_ready (GObject* source_object, GAsyncResult* _res_, gpointer _user_data_);
++static void rygel_lms_category_container_real_get_children_data_free (gpointer _data);
++static void rygel_lms_category_container_real_get_children (RygelMediaContainer* base, guint offset, guint max_count, const gchar* sort_criteria, GCancellable* cancellable, GAsyncReadyCallback _callback_, gpointer _user_data_);
++static gboolean rygel_lms_category_container_real_get_children_co (RygelLmsCategoryContainerGetChildrenData* _data_);
++void rygel_lms_database_get_children_init (sqlite3_stmt* stmt, guint offset, guint max_count, const gchar* sort_criteria, GError** error);
++static void rygel_lms_category_container_real_find_object_data_free (gpointer _data);
++static void rygel_lms_category_container_real_find_object (RygelMediaContainer* base, const gchar* id, GCancellable* cancellable, GAsyncReadyCallback _callback_, gpointer _user_data_);
++static gboolean rygel_lms_category_container_real_find_object_co (RygelLmsCategoryContainerFindObjectData* _data_);
++void rygel_lms_database_find_object (const gchar* id, sqlite3_stmt* stmt, GError** error);
++static void rygel_lms_category_container_find_object_ready (GObject* source_object, GAsyncResult* _res_, gpointer _user_data_);
++gchar* rygel_lms_category_container_build_child_id (RygelLMSCategoryContainer* self, gint db_id);
++gchar* rygel_lms_category_container_build_reference_id (RygelLMSCategoryContainer* self, gint db_id);
++static void rygel_lms_category_container_real_add_child_data_free (gpointer _data);
++static void rygel_lms_category_container_real_add_child (RygelTrackableContainer* base, RygelMediaObject* object, GAsyncReadyCallback _callback_, gpointer _user_data_);
++static gboolean rygel_lms_category_container_real_add_child_co (RygelLmsCategoryContainerAddChildData* _data_);
++static void rygel_lms_category_container_real_remove_child_data_free (gpointer _data);
++static void rygel_lms_category_container_real_remove_child (RygelTrackableContainer* base, RygelMediaObject* object, GAsyncReadyCallback _callback_, gpointer _user_data_);
++static gboolean rygel_lms_category_container_real_remove_child_co (RygelLmsCategoryContainerRemoveChildData* _data_);
++static void rygel_lms_category_container_on_db_updated (RygelLMSCategoryContainer* self, guint64 old_id, guint64 new_id);
++sqlite3_stmt* rygel_lms_database_prepare (RygelLMSDatabase* self, const gchar* query_string, GError** error);
++void rygel_lms_database_get_children_with_update_id_init (sqlite3_stmt* stmt, guint64 old_id, guint64 new_id, GError** error);
++RygelLMSCategoryContainer* rygel_lms_category_container_construct (GType object_type, const gchar* db_id, RygelMediaContainer* parent, const gchar* title, RygelLMSDatabase* lms_db, const gchar* sql_all, const gchar* sql_find_object, const gchar* sql_count, const gchar* sql_added, const gchar* sql_removed);
++static void rygel_lms_category_container_set_lms_db (RygelLMSCategoryContainer* self, RygelLMSDatabase* value);
++const gchar* rygel_lms_category_container_get_db_id (RygelLMSCategoryContainer* self);
++static void rygel_lms_category_container_set_db_id (RygelLMSCategoryContainer* self, const gchar* value);
++static void rygel_lms_category_container_set_sql_all (RygelLMSCategoryContainer* self, const gchar* value);
++const gchar* rygel_lms_category_container_get_sql_find_object (RygelLMSCategoryContainer* self);
++static void rygel_lms_category_container_set_sql_find_object (RygelLMSCategoryContainer* self, const gchar* value);
++static void rygel_lms_category_container_set_sql_count (RygelLMSCategoryContainer* self, const gchar* value);
++const gchar* rygel_lms_category_container_get_sql_added (RygelLMSCategoryContainer* self);
++static void rygel_lms_category_container_set_sql_added (RygelLMSCategoryContainer* self, const gchar* value);
++const gchar* rygel_lms_category_container_get_sql_removed (RygelLMSCategoryContainer* self);
++static void rygel_lms_category_container_set_sql_removed (RygelLMSCategoryContainer* self, const gchar* value);
++static GObject * rygel_lms_category_container_constructor (GType type, guint n_construct_properties, GObjectConstructParam * construct_properties);
++static void _rygel_lms_category_container_on_db_updated_rygel_lms_database_db_updated (RygelLMSDatabase* _sender, guint64 old_update_id, guint64 new_update_id, gpointer self);
++static void rygel_lms_category_container_finalize (GObject* obj);
++static void _vala_rygel_lms_category_container_get_property (GObject * object, guint property_id, GValue * value, GParamSpec * pspec);
++static void _vala_rygel_lms_category_container_set_property (GObject * object, guint property_id, const GValue * value, GParamSpec * pspec);
++
++
++GQuark rygel_lms_category_container_error_quark (void) {
++	return g_quark_from_static_string ("rygel_lms_category_container_error-quark");
++}
++
++
++static RygelMediaObject* rygel_lms_category_container_real_object_from_statement (RygelLMSCategoryContainer* self, sqlite3_stmt* statement) {
++	g_critical ("Type `%s' does not implement abstract method `rygel_lms_category_container_object_from_statement'", g_type_name (G_TYPE_FROM_INSTANCE (self)));
++	return NULL;
++}
++
++
++RygelMediaObject* rygel_lms_category_container_object_from_statement (RygelLMSCategoryContainer* self, sqlite3_stmt* statement) {
++	g_return_val_if_fail (self != NULL, NULL);
++	return RYGEL_LMS_CATEGORY_CONTAINER_GET_CLASS (self)->object_from_statement (self, statement);
++}
++
++
++static gchar* rygel_lms_category_container_real_get_sql_all_with_filter (RygelLMSCategoryContainer* self, const gchar* filter) {
++	gchar* result = NULL;
++	const gchar* _tmp0_ = NULL;
++	gchar* _tmp1_ = NULL;
++	g_return_val_if_fail (filter != NULL, NULL);
++	_tmp0_ = self->priv->_sql_all;
++	_tmp1_ = g_strdup (_tmp0_);
++	result = _tmp1_;
++	return result;
++}
++
++
++gchar* rygel_lms_category_container_get_sql_all_with_filter (RygelLMSCategoryContainer* self, const gchar* filter) {
++	g_return_val_if_fail (self != NULL, NULL);
++	return RYGEL_LMS_CATEGORY_CONTAINER_GET_CLASS (self)->get_sql_all_with_filter (self, filter);
++}
++
++
++static gchar* rygel_lms_category_container_real_get_sql_count_with_filter (RygelLMSCategoryContainer* self, const gchar* filter) {
++	gchar* result = NULL;
++	const gchar* _tmp0_ = NULL;
++	gchar* _tmp1_ = NULL;
++	g_return_val_if_fail (filter != NULL, NULL);
++	_tmp0_ = self->priv->_sql_count;
++	_tmp1_ = g_strdup (_tmp0_);
++	result = _tmp1_;
++	return result;
++}
++
++
++gchar* rygel_lms_category_container_get_sql_count_with_filter (RygelLMSCategoryContainer* self, const gchar* filter) {
++	g_return_val_if_fail (self != NULL, NULL);
++	return RYGEL_LMS_CATEGORY_CONTAINER_GET_CLASS (self)->get_sql_count_with_filter (self, filter);
++}
++
++
++static gchar* rygel_lms_category_container_map_operand_to_column (const gchar* operand, gchar** collate, gboolean for_sort, GError** error) {
++	gchar* _vala_collate = NULL;
++	gchar* result = NULL;
++	gchar* column = NULL;
++	gboolean use_collation = FALSE;
++	const gchar* _tmp0_ = NULL;
++	const gchar* _tmp1_ = NULL;
++	GQuark _tmp3_ = 0U;
++	static GQuark _tmp2_label0 = 0;
++	static GQuark _tmp2_label1 = 0;
++	static GQuark _tmp2_label2 = 0;
++	gboolean _tmp11_ = FALSE;
++	GError * _inner_error_ = NULL;
++	g_return_val_if_fail (operand != NULL, NULL);
++	column = NULL;
++	use_collation = FALSE;
++	_tmp0_ = operand;
++	_tmp1_ = _tmp0_;
++	_tmp3_ = (NULL == _tmp1_) ? 0 : g_quark_from_string (_tmp1_);
++	if (_tmp3_ == ((0 != _tmp2_label0) ? _tmp2_label0 : (_tmp2_label0 = g_quark_from_static_string ("dc:title")))) {
++		switch (0) {
++			default:
++			{
++				gchar* _tmp4_ = NULL;
++				_tmp4_ = g_strdup ("title");
++				_g_free0 (column);
++				column = _tmp4_;
++				use_collation = TRUE;
++				break;
++			}
++		}
++	} else if (_tmp3_ == ((0 != _tmp2_label1) ? _tmp2_label1 : (_tmp2_label1 = g_quark_from_static_string ("upnp:artist")))) {
++		switch (0) {
++			default:
++			{
++				gchar* _tmp5_ = NULL;
++				_tmp5_ = g_strdup ("artist");
++				_g_free0 (column);
++				column = _tmp5_;
++				use_collation = TRUE;
++				break;
++			}
++		}
++	} else if (_tmp3_ == ((0 != _tmp2_label2) ? _tmp2_label2 : (_tmp2_label2 = g_quark_from_static_string ("dc:creator")))) {
++		switch (0) {
++			default:
++			{
++				gchar* _tmp6_ = NULL;
++				_tmp6_ = g_strdup ("creator");
++				_g_free0 (column);
++				column = _tmp6_;
++				use_collation = TRUE;
++				break;
++			}
++		}
++	} else {
++		switch (0) {
++			default:
++			{
++				gchar* message = NULL;
++				const gchar* _tmp7_ = NULL;
++				gchar* _tmp8_ = NULL;
++				const gchar* _tmp9_ = NULL;
++				GError* _tmp10_ = NULL;
++				_tmp7_ = operand;
++				_tmp8_ = g_strdup_printf ("Unsupported column %s", _tmp7_);
++				message = _tmp8_;
++				_tmp9_ = message;
++				_tmp10_ = g_error_new_literal (RYGEL_LMS_CATEGORY_CONTAINER_ERROR, RYGEL_LMS_CATEGORY_CONTAINER_ERROR_UNSUPPORTED_SEARCH, _tmp9_);
++				_inner_error_ = _tmp10_;
++				g_propagate_error (error, _inner_error_);
++				_g_free0 (message);
++				_g_free0 (column);
++				return NULL;
++			}
++		}
++	}
++	_tmp11_ = use_collation;
++	if (_tmp11_) {
++		gchar* _tmp12_ = NULL;
++		_tmp12_ = g_strdup ("COLLATE CASEFOLD");
++		_g_free0 (_vala_collate);
++		_vala_collate = _tmp12_;
++	} else {
++		gchar* _tmp13_ = NULL;
++		_tmp13_ = g_strdup ("");
++		_g_free0 (_vala_collate);
++		_vala_collate = _tmp13_;
++	}
++	result = column;
++	if (collate) {
++		*collate = _vala_collate;
++	} else {
++		_g_free0 (_vala_collate);
++	}
++	return result;
++}
++
++
++static void _vala_GValue_free (GValue* self) {
++	g_value_unset (self);
++	g_free (self);
++}
++
++
++static gchar* rygel_lms_category_container_relational_expression_to_sql (RygelRelationalExpression* exp, GValueArray* args, GError** error) {
++	gchar* result = NULL;
++	GValue* v = NULL;
++	gchar* collate = NULL;
++	gchar* column = NULL;
++	RygelRelationalExpression* _tmp0_ = NULL;
++	gconstpointer _tmp1_ = NULL;
++	gchar* _tmp2_ = NULL;
++	gchar* _tmp3_ = NULL;
++	RygelLMSSqlOperator* operator = NULL;
++	RygelRelationalExpression* _tmp4_ = NULL;
++	gconstpointer _tmp5_ = NULL;
++	GValue* _tmp40_ = NULL;
++	RygelLMSSqlOperator* _tmp44_ = NULL;
++	gchar* _tmp45_ = NULL;
++	GError * _inner_error_ = NULL;
++	g_return_val_if_fail (exp != NULL, NULL);
++	g_return_val_if_fail (args != NULL, NULL);
++	v = NULL;
++	collate = NULL;
++	_tmp0_ = exp;
++	_tmp1_ = ((RygelSearchExpression*) _tmp0_)->operand1;
++	_tmp3_ = rygel_lms_category_container_map_operand_to_column ((const gchar*) _tmp1_, &_tmp2_, FALSE, &_inner_error_);
++	_g_free0 (collate);
++	collate = _tmp2_;
++	column = _tmp3_;
++	if (G_UNLIKELY (_inner_error_ != NULL)) {
++		g_propagate_error (error, _inner_error_);
++		_g_free0 (collate);
++		__vala_GValue_free0 (v);
++		return NULL;
++	}
++	_tmp4_ = exp;
++	_tmp5_ = ((RygelSearchExpression*) _tmp4_)->op;
++	switch ((GUPnPSearchCriteriaOp) ((gintptr) _tmp5_)) {
++		case GUPNP_SEARCH_CRITERIA_OP_EXISTS:
++		{
++			gchar* sql_function = NULL;
++			RygelRelationalExpression* _tmp6_ = NULL;
++			gconstpointer _tmp7_ = NULL;
++			const gchar* _tmp10_ = NULL;
++			const gchar* _tmp11_ = NULL;
++			const gchar* _tmp12_ = NULL;
++			gchar* _tmp13_ = NULL;
++			_tmp6_ = exp;
++			_tmp7_ = ((RygelSearchExpression*) _tmp6_)->operand2;
++			if (g_strcmp0 ((const gchar*) _tmp7_, "true") == 0) {
++				gchar* _tmp8_ = NULL;
++				_tmp8_ = g_strdup ("%s IS NOT NULL AND %s != ''");
++				_g_free0 (sql_function);
++				sql_function = _tmp8_;
++			} else {
++				gchar* _tmp9_ = NULL;
++				_tmp9_ = g_strdup ("%s IS NULL OR %s = ''");
++				_g_free0 (sql_function);
++				sql_function = _tmp9_;
++			}
++			_tmp10_ = sql_function;
++			_tmp11_ = column;
++			_tmp12_ = column;
++			_tmp13_ = g_strdup_printf (_tmp10_, _tmp11_, _tmp12_);
++			result = _tmp13_;
++			_g_free0 (sql_function);
++			_g_object_unref0 (operator);
++			_g_free0 (column);
++			_g_free0 (collate);
++			__vala_GValue_free0 (v);
++			return result;
++		}
++		case GUPNP_SEARCH_CRITERIA_OP_EQ:
++		case GUPNP_SEARCH_CRITERIA_OP_NEQ:
++		case GUPNP_SEARCH_CRITERIA_OP_LESS:
++		case GUPNP_SEARCH_CRITERIA_OP_LEQ:
++		case GUPNP_SEARCH_CRITERIA_OP_GREATER:
++		case GUPNP_SEARCH_CRITERIA_OP_GEQ:
++		{
++			RygelRelationalExpression* _tmp14_ = NULL;
++			gconstpointer _tmp15_ = NULL;
++			GValue* _tmp16_ = NULL;
++			RygelRelationalExpression* _tmp17_ = NULL;
++			gconstpointer _tmp18_ = NULL;
++			const gchar* _tmp19_ = NULL;
++			const gchar* _tmp20_ = NULL;
++			RygelLMSSqlOperator* _tmp21_ = NULL;
++			_tmp14_ = exp;
++			_tmp15_ = ((RygelSearchExpression*) _tmp14_)->operand2;
++			_tmp16_ = g_new0 (GValue, 1);
++			g_value_init (_tmp16_, G_TYPE_STRING);
++			g_value_set_string (_tmp16_, (const gchar*) _tmp15_);
++			__vala_GValue_free0 (v);
++			v = _tmp16_;
++			_tmp17_ = exp;
++			_tmp18_ = ((RygelSearchExpression*) _tmp17_)->op;
++			_tmp19_ = column;
++			_tmp20_ = collate;
++			_tmp21_ = rygel_lms_sql_operator_new_from_search_criteria_op ((GUPnPSearchCriteriaOp) ((gintptr) _tmp18_), _tmp19_, _tmp20_);
++			_g_object_unref0 (operator);
++			operator = _tmp21_;
++			break;
++		}
++		case GUPNP_SEARCH_CRITERIA_OP_CONTAINS:
++		{
++			const gchar* _tmp22_ = NULL;
++			RygelLMSSqlFunction* _tmp23_ = NULL;
++			RygelRelationalExpression* _tmp24_ = NULL;
++			gconstpointer _tmp25_ = NULL;
++			GValue* _tmp26_ = NULL;
++			_tmp22_ = column;
++			_tmp23_ = rygel_lms_sql_function_new ("contains", _tmp22_);
++			_g_object_unref0 (operator);
++			operator = (RygelLMSSqlOperator*) _tmp23_;
++			_tmp24_ = exp;
++			_tmp25_ = ((RygelSearchExpression*) _tmp24_)->operand2;
++			_tmp26_ = g_new0 (GValue, 1);
++			g_value_init (_tmp26_, G_TYPE_STRING);
++			g_value_set_string (_tmp26_, (const gchar*) _tmp25_);
++			__vala_GValue_free0 (v);
++			v = _tmp26_;
++			break;
++		}
++		case GUPNP_SEARCH_CRITERIA_OP_DOES_NOT_CONTAIN:
++		{
++			const gchar* _tmp27_ = NULL;
++			RygelLMSSqlFunction* _tmp28_ = NULL;
++			RygelRelationalExpression* _tmp29_ = NULL;
++			gconstpointer _tmp30_ = NULL;
++			GValue* _tmp31_ = NULL;
++			_tmp27_ = column;
++			_tmp28_ = rygel_lms_sql_function_new ("NOT contains", _tmp27_);
++			_g_object_unref0 (operator);
++			operator = (RygelLMSSqlOperator*) _tmp28_;
++			_tmp29_ = exp;
++			_tmp30_ = ((RygelSearchExpression*) _tmp29_)->operand2;
++			_tmp31_ = g_new0 (GValue, 1);
++			g_value_init (_tmp31_, G_TYPE_STRING);
++			g_value_set_string (_tmp31_, (const gchar*) _tmp30_);
++			__vala_GValue_free0 (v);
++			v = _tmp31_;
++			break;
++		}
++		case GUPNP_SEARCH_CRITERIA_OP_DERIVED_FROM:
++		{
++			const gchar* _tmp32_ = NULL;
++			RygelLMSSqlOperator* _tmp33_ = NULL;
++			RygelRelationalExpression* _tmp34_ = NULL;
++			gconstpointer _tmp35_ = NULL;
++			gchar* _tmp36_ = NULL;
++			GValue* _tmp37_ = NULL;
++			_tmp32_ = column;
++			_tmp33_ = rygel_lms_sql_operator_new ("LIKE", _tmp32_, "");
++			_g_object_unref0 (operator);
++			operator = _tmp33_;
++			_tmp34_ = exp;
++			_tmp35_ = ((RygelSearchExpression*) _tmp34_)->operand2;
++			_tmp36_ = g_strdup_printf ("%s%%", (const gchar*) _tmp35_);
++			_tmp37_ = g_new0 (GValue, 1);
++			g_value_init (_tmp37_, G_TYPE_STRING);
++			g_value_take_string (_tmp37_, _tmp36_);
++			__vala_GValue_free0 (v);
++			v = _tmp37_;
++			break;
++		}
++		default:
++		{
++			RygelRelationalExpression* _tmp38_ = NULL;
++			gconstpointer _tmp39_ = NULL;
++			_tmp38_ = exp;
++			_tmp39_ = ((RygelSearchExpression*) _tmp38_)->op;
++			g_warning ("rygel-lms-category-container.vala:148: Unsupported op %d", (gint) ((GUPnPSearchCriteriaOp) ((gintptr) _tmp39_)));
++			result = NULL;
++			_g_object_unref0 (operator);
++			_g_free0 (column);
++			_g_free0 (collate);
++			__vala_GValue_free0 (v);
++			return result;
++		}
++	}
++	_tmp40_ = v;
++	if (_tmp40_ != NULL) {
++		GValueArray* _tmp41_ = NULL;
++		GValue* _tmp42_ = NULL;
++		GValue _tmp43_ = {0};
++		_tmp41_ = args;
++		_tmp42_ = v;
++		_tmp43_ = *_tmp42_;
++		g_value_array_append (_tmp41_, &_tmp43_);
++	}
++	_tmp44_ = operator;
++	_tmp45_ = rygel_lms_sql_operator_to_string (_tmp44_);
++	result = _tmp45_;
++	_g_object_unref0 (operator);
++	_g_free0 (column);
++	_g_free0 (collate);
++	__vala_GValue_free0 (v);
++	return result;
++}
++
++
++static gchar* rygel_lms_category_container_logical_expression_to_sql (RygelLogicalExpression* expression, GValueArray* args, GError** error) {
++	gchar* result = NULL;
++	gchar* left_sql_string = NULL;
++	RygelLogicalExpression* _tmp0_ = NULL;
++	gconstpointer _tmp1_ = NULL;
++	GValueArray* _tmp2_ = NULL;
++	gchar* _tmp3_ = NULL;
++	gchar* right_sql_string = NULL;
++	RygelLogicalExpression* _tmp4_ = NULL;
++	gconstpointer _tmp5_ = NULL;
++	GValueArray* _tmp6_ = NULL;
++	gchar* _tmp7_ = NULL;
++	const gchar* operator_sql_string = NULL;
++	RygelLogicalExpression* _tmp8_ = NULL;
++	gconstpointer _tmp9_ = NULL;
++	const gchar* _tmp10_ = NULL;
++	const gchar* _tmp11_ = NULL;
++	const gchar* _tmp12_ = NULL;
++	gchar* _tmp13_ = NULL;
++	GError * _inner_error_ = NULL;
++	g_return_val_if_fail (expression != NULL, NULL);
++	g_return_val_if_fail (args != NULL, NULL);
++	_tmp0_ = expression;
++	_tmp1_ = ((RygelSearchExpression*) _tmp0_)->operand1;
++	_tmp2_ = args;
++	_tmp3_ = rygel_lms_category_container_search_expression_to_sql ((RygelSearchExpression*) _tmp1_, _tmp2_, &_inner_error_);
++	left_sql_string = _tmp3_;
++	if (G_UNLIKELY (_inner_error_ != NULL)) {
++		g_propagate_error (error, _inner_error_);
++		return NULL;
++	}
++	_tmp4_ = expression;
++	_tmp5_ = ((RygelSearchExpression*) _tmp4_)->operand2;
++	_tmp6_ = args;
++	_tmp7_ = rygel_lms_category_container_search_expression_to_sql ((RygelSearchExpression*) _tmp5_, _tmp6_, &_inner_error_);
++	right_sql_string = _tmp7_;
++	if (G_UNLIKELY (_inner_error_ != NULL)) {
++		g_propagate_error (error, _inner_error_);
++		_g_free0 (left_sql_string);
++		return NULL;
++	}
++	operator_sql_string = "OR";
++	_tmp8_ = expression;
++	_tmp9_ = ((RygelSearchExpression*) _tmp8_)->op;
++	if (((RygelLogicalOperator) ((gintptr) _tmp9_)) == RYGEL_LOGICAL_OPERATOR_AND) {
++		operator_sql_string = "AND";
++	}
++	_tmp10_ = left_sql_string;
++	_tmp11_ = operator_sql_string;
++	_tmp12_ = right_sql_string;
++	_tmp13_ = g_strdup_printf ("(%s %s %s)", _tmp10_, _tmp11_, _tmp12_);
++	result = _tmp13_;
++	_g_free0 (right_sql_string);
++	_g_free0 (left_sql_string);
++	return result;
++}
++
++
++static gchar* rygel_lms_category_container_search_expression_to_sql (RygelSearchExpression* expression, GValueArray* args, GError** error) {
++	gchar* result = NULL;
++	RygelSearchExpression* _tmp0_ = NULL;
++	RygelSearchExpression* _tmp2_ = NULL;
++	GError * _inner_error_ = NULL;
++	g_return_val_if_fail (args != NULL, NULL);
++	_tmp0_ = expression;
++	if (_tmp0_ == NULL) {
++		gchar* _tmp1_ = NULL;
++		_tmp1_ = g_strdup ("");
++		result = _tmp1_;
++		return result;
++	}
++	_tmp2_ = expression;
++	if (G_TYPE_CHECK_INSTANCE_TYPE (_tmp2_, RYGEL_TYPE_LOGICAL_EXPRESSION)) {
++		gchar* _tmp3_ = NULL;
++		RygelSearchExpression* _tmp4_ = NULL;
++		GValueArray* _tmp5_ = NULL;
++		gchar* _tmp6_ = NULL;
++		gchar* _tmp7_ = NULL;
++		_tmp4_ = expression;
++		_tmp5_ = args;
++		_tmp6_ = rygel_lms_category_container_logical_expression_to_sql (G_TYPE_CHECK_INSTANCE_TYPE (_tmp4_, RYGEL_TYPE_LOGICAL_EXPRESSION) ? ((RygelLogicalExpression*) _tmp4_) : NULL, _tmp5_, &_inner_error_);
++		_tmp3_ = _tmp6_;
++		if (G_UNLIKELY (_inner_error_ != NULL)) {
++			g_propagate_error (error, _inner_error_);
++			return NULL;
++		}
++		_tmp7_ = _tmp3_;
++		_tmp3_ = NULL;
++		result = _tmp7_;
++		_g_free0 (_tmp3_);
++		return result;
++	} else {
++		gchar* _tmp8_ = NULL;
++		RygelSearchExpression* _tmp9_ = NULL;
++		GValueArray* _tmp10_ = NULL;
++		gchar* _tmp11_ = NULL;
++		gchar* _tmp12_ = NULL;
++		_tmp9_ = expression;
++		_tmp10_ = args;
++		_tmp11_ = rygel_lms_category_container_relational_expression_to_sql (G_TYPE_CHECK_INSTANCE_TYPE (_tmp9_, RYGEL_TYPE_RELATIONAL_EXPRESSION) ? ((RygelRelationalExpression*) _tmp9_) : NULL, _tmp10_, &_inner_error_);
++		_tmp8_ = _tmp11_;
++		if (G_UNLIKELY (_inner_error_ != NULL)) {
++			g_propagate_error (error, _inner_error_);
++			return NULL;
++		}
++		_tmp12_ = _tmp8_;
++		_tmp8_ = NULL;
++		result = _tmp12_;
++		_g_free0 (_tmp8_);
++		return result;
++	}
++}
++
++
++static guint rygel_lms_category_container_real_get_child_count_with_filter (RygelLMSCategoryContainer* self, const gchar* where_filter, GValueArray* args) {
++	guint result = 0U;
++	gchar* query = NULL;
++	const gchar* _tmp0_ = NULL;
++	gchar* _tmp1_ = NULL;
++	GError * _inner_error_ = NULL;
++	g_return_val_if_fail (where_filter != NULL, 0U);
++	g_return_val_if_fail (args != NULL, 0U);
++	_tmp0_ = where_filter;
++	_tmp1_ = rygel_lms_category_container_get_sql_count_with_filter (self, _tmp0_);
++	query = _tmp1_;
++	{
++		sqlite3_stmt* stmt = NULL;
++		RygelLMSDatabase* _tmp2_ = NULL;
++		const gchar* _tmp3_ = NULL;
++		GValueArray* _tmp4_ = NULL;
++		GValue* _tmp5_ = NULL;
++		gint _tmp5__length1 = 0;
++		sqlite3_stmt* _tmp6_ = NULL;
++		sqlite3_stmt* _tmp7_ = NULL;
++		gint _tmp8_ = 0;
++		sqlite3_stmt* _tmp9_ = NULL;
++		gint _tmp10_ = 0;
++		_tmp2_ = self->priv->_lms_db;
++		_tmp3_ = query;
++		_tmp4_ = args;
++		_tmp5_ = _tmp4_->values;
++		_tmp5__length1 = (gint) _tmp4_->n_values;
++		_tmp6_ = rygel_lms_database_prepare_and_init (_tmp2_, _tmp3_, _tmp5_, _tmp5__length1, &_inner_error_);
++		stmt = _tmp6_;
++		if (G_UNLIKELY (_inner_error_ != NULL)) {
++			if (_inner_error_->domain == RYGEL_LMS_DATABASE_ERROR) {
++				goto __catch2_rygel_lms_database_error;
++			}
++			_g_free0 (query);
++			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 0U;
++		}
++		_tmp7_ = stmt;
++		_tmp8_ = sqlite3_step (_tmp7_);
++		if (_tmp8_ != SQLITE_ROW) {
++			result = (guint) 0;
++			_sqlite3_finalize0 (stmt);
++			_g_free0 (query);
++			return result;
++		}
++		_tmp9_ = stmt;
++		_tmp10_ = sqlite3_column_int (_tmp9_, 0);
++		result = (guint) _tmp10_;
++		_sqlite3_finalize0 (stmt);
++		_g_free0 (query);
++		return result;
++	}
++	goto __finally2;
++	__catch2_rygel_lms_database_error:
++	{
++		GError* e = NULL;
++		GError* _tmp11_ = NULL;
++		const gchar* _tmp12_ = NULL;
++		e = _inner_error_;
++		_inner_error_ = NULL;
++		_tmp11_ = e;
++		_tmp12_ = _tmp11_->message;
++		g_warning ("rygel-lms-category-container.vala:209: Query failed: %s", _tmp12_);
++		result = (guint) 0;
++		_g_error_free0 (e);
++		_g_free0 (query);
++		return result;
++	}
++	__finally2:
++	_g_free0 (query);
++	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 0U;
++}
++
++
++guint rygel_lms_category_container_get_child_count_with_filter (RygelLMSCategoryContainer* self, const gchar* where_filter, GValueArray* args) {
++	g_return_val_if_fail (self != NULL, 0U);
++	return RYGEL_LMS_CATEGORY_CONTAINER_GET_CLASS (self)->get_child_count_with_filter (self, where_filter, args);
++}
++
++
++static RygelMediaObjects* rygel_lms_category_container_real_get_children_with_filter (RygelLMSCategoryContainer* self, const gchar* where_filter, GValueArray* args, const gchar* sort_criteria, guint offset, guint max_count) {
++	RygelMediaObjects* result = NULL;
++	RygelMediaObjects* children = NULL;
++	RygelMediaObjects* _tmp0_ = NULL;
++	GValue v = {0};
++	guint _tmp1_ = 0U;
++	GValue _tmp2_ = {0};
++	GValueArray* _tmp3_ = NULL;
++	GValue _tmp4_ = {0};
++	guint _tmp5_ = 0U;
++	GValue _tmp6_ = {0};
++	GValueArray* _tmp7_ = NULL;
++	GValue _tmp8_ = {0};
++	gchar* query = NULL;
++	const gchar* _tmp9_ = NULL;
++	gchar* _tmp10_ = NULL;
++	GError * _inner_error_ = NULL;
++	g_return_val_if_fail (where_filter != NULL, NULL);
++	g_return_val_if_fail (args != NULL, NULL);
++	g_return_val_if_fail (sort_criteria != NULL, NULL);
++	_tmp0_ = rygel_media_objects_new ();
++	children = _tmp0_;
++	_tmp1_ = max_count;
++	g_value_init (&_tmp2_, G_TYPE_UINT);
++	g_value_set_uint (&_tmp2_, _tmp1_);
++	v = _tmp2_;
++	_tmp3_ = args;
++	_tmp4_ = v;
++	g_value_array_append (_tmp3_, &_tmp4_);
++	_tmp5_ = offset;
++	g_value_init (&_tmp6_, G_TYPE_UINT);
++	g_value_set_uint (&_tmp6_, _tmp5_);
++	G_IS_VALUE (&v) ? (g_value_unset (&v), NULL) : NULL;
++	v = _tmp6_;
++	_tmp7_ = args;
++	_tmp8_ = v;
++	g_value_array_append (_tmp7_, &_tmp8_);
++	_tmp9_ = where_filter;
++	_tmp10_ = rygel_lms_category_container_get_sql_all_with_filter (self, _tmp9_);
++	query = _tmp10_;
++	{
++		sqlite3_stmt* stmt = NULL;
++		RygelLMSDatabase* _tmp11_ = NULL;
++		const gchar* _tmp12_ = NULL;
++		GValueArray* _tmp13_ = NULL;
++		GValue* _tmp14_ = NULL;
++		gint _tmp14__length1 = 0;
++		sqlite3_stmt* _tmp15_ = NULL;
++		_tmp11_ = self->priv->_lms_db;
++		_tmp12_ = query;
++		_tmp13_ = args;
++		_tmp14_ = _tmp13_->values;
++		_tmp14__length1 = (gint) _tmp13_->n_values;
++		_tmp15_ = rygel_lms_database_prepare_and_init (_tmp11_, _tmp12_, _tmp14_, _tmp14__length1, &_inner_error_);
++		stmt = _tmp15_;
++		if (G_UNLIKELY (_inner_error_ != NULL)) {
++			if (_inner_error_->domain == RYGEL_LMS_DATABASE_ERROR) {
++				goto __catch3_rygel_lms_database_error;
++			}
++			_g_free0 (query);
++			G_IS_VALUE (&v) ? (g_value_unset (&v), NULL) : NULL;
++			_g_object_unref0 (children);
++			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;
++		}
++		while (TRUE) {
++			gboolean _tmp16_ = FALSE;
++			sqlite3_stmt* _tmp17_ = NULL;
++			gboolean _tmp18_ = FALSE;
++			RygelMediaObjects* _tmp19_ = NULL;
++			sqlite3_stmt* _tmp20_ = NULL;
++			RygelMediaObject* _tmp21_ = NULL;
++			RygelMediaObject* _tmp22_ = NULL;
++			_tmp17_ = stmt;
++			_tmp18_ = rygel_lms_database_get_children_step (_tmp17_, &_inner_error_);
++			_tmp16_ = _tmp18_;
++			if (G_UNLIKELY (_inner_error_ != NULL)) {
++				_sqlite3_finalize0 (stmt);
++				if (_inner_error_->domain == RYGEL_LMS_DATABASE_ERROR) {
++					goto __catch3_rygel_lms_database_error;
++				}
++				_sqlite3_finalize0 (stmt);
++				_g_free0 (query);
++				G_IS_VALUE (&v) ? (g_value_unset (&v), NULL) : NULL;
++				_g_object_unref0 (children);
++				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;
++			}
++			if (!_tmp16_) {
++				break;
++			}
++			_tmp19_ = children;
++			_tmp20_ = stmt;
++			_tmp21_ = rygel_lms_category_container_object_from_statement (self, _tmp20_);
++			_tmp22_ = _tmp21_;
++			gee_abstract_collection_add ((GeeAbstractCollection*) _tmp19_, _tmp22_);
++			_g_object_unref0 (_tmp22_);
++		}
++		_sqlite3_finalize0 (stmt);
++	}
++	goto __finally3;
++	__catch3_rygel_lms_database_error:
++	{
++		GError* e = NULL;
++		GError* _tmp23_ = NULL;
++		const gchar* _tmp24_ = NULL;
++		e = _inner_error_;
++		_inner_error_ = NULL;
++		_tmp23_ = e;
++		_tmp24_ = _tmp23_->message;
++		g_warning ("rygel-lms-category-container.vala:232: Query failed: %s", _tmp24_);
++		_g_error_free0 (e);
++	}
++	__finally3:
++	if (G_UNLIKELY (_inner_error_ != NULL)) {
++		_g_free0 (query);
++		G_IS_VALUE (&v) ? (g_value_unset (&v), NULL) : NULL;
++		_g_object_unref0 (children);
++		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;
++	}
++	result = children;
++	_g_free0 (query);
++	G_IS_VALUE (&v) ? (g_value_unset (&v), NULL) : NULL;
++	return result;
++}
++
++
++RygelMediaObjects* rygel_lms_category_container_get_children_with_filter (RygelLMSCategoryContainer* self, const gchar* where_filter, GValueArray* args, const gchar* sort_criteria, guint offset, guint max_count) {
++	g_return_val_if_fail (self != NULL, NULL);
++	return RYGEL_LMS_CATEGORY_CONTAINER_GET_CLASS (self)->get_children_with_filter (self, where_filter, args, sort_criteria, offset, max_count);
++}
++
++
++static void rygel_lms_category_container_real_search_data_free (gpointer _data) {
++	RygelLmsCategoryContainerSearchData* _data_;
++	_data_ = _data;
++	_rygel_search_expression_unref0 (_data_->expression);
++	_g_free0 (_data_->sort_criteria);
++	_g_object_unref0 (_data_->cancellable);
++	_g_object_unref0 (_data_->result);
++	_g_object_unref0 (_data_->self);
++	g_slice_free (RygelLmsCategoryContainerSearchData, _data_);
++}
++
++
++static gpointer _g_object_ref0 (gpointer self) {
++	return self ? g_object_ref (self) : NULL;
++}
++
++
++static gpointer _rygel_search_expression_ref0 (gpointer self) {
++	return self ? rygel_search_expression_ref (self) : NULL;
++}
++
++
++static void rygel_lms_category_container_real_search (RygelSearchableContainer* base, RygelSearchExpression* expression, guint offset, guint max_count, const gchar* sort_criteria, GCancellable* cancellable, GAsyncReadyCallback _callback_, gpointer _user_data_) {
++	RygelLMSCategoryContainer * self;
++	RygelLmsCategoryContainerSearchData* _data_;
++	RygelLMSCategoryContainer* _tmp0_ = NULL;
++	RygelSearchExpression* _tmp1_ = NULL;
++	RygelSearchExpression* _tmp2_ = NULL;
++	guint _tmp3_ = 0U;
++	guint _tmp4_ = 0U;
++	const gchar* _tmp5_ = NULL;
++	gchar* _tmp6_ = NULL;
++	GCancellable* _tmp7_ = NULL;
++	GCancellable* _tmp8_ = NULL;
++	self = (RygelLMSCategoryContainer*) base;
++	_data_ = g_slice_new0 (RygelLmsCategoryContainerSearchData);
++	_data_->_async_result = g_simple_async_result_new (G_OBJECT (self), _callback_, _user_data_, rygel_lms_category_container_real_search);
++	g_simple_async_result_set_op_res_gpointer (_data_->_async_result, _data_, rygel_lms_category_container_real_search_data_free);
++	_tmp0_ = _g_object_ref0 (self);
++	_data_->self = _tmp0_;
++	_tmp1_ = expression;
++	_tmp2_ = _rygel_search_expression_ref0 (_tmp1_);
++	_rygel_search_expression_unref0 (_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_free0 (_data_->sort_criteria);
++	_data_->sort_criteria = _tmp6_;
++	_tmp7_ = cancellable;
++	_tmp8_ = _g_object_ref0 (_tmp7_);
++	_g_object_unref0 (_data_->cancellable);
++	_data_->cancellable = _tmp8_;
++	rygel_lms_category_container_real_search_co (_data_);
++}
++
++
++static RygelMediaObjects* rygel_lms_category_container_real_search_finish (RygelSearchableContainer* base, GAsyncResult* _res_, guint* total_matches, GError** error) {
++	RygelMediaObjects* result;
++	RygelLmsCategoryContainerSearchData* _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_lms_category_container_search_ready (GObject* source_object, GAsyncResult* _res_, gpointer _user_data_) {
++	RygelLmsCategoryContainerSearchData* _data_;
++	_data_ = _user_data_;
++	_data_->_source_object_ = source_object;
++	_data_->_res_ = _res_;
++	rygel_lms_category_container_real_search_co (_data_);
++}
++
++
++static gboolean rygel_lms_category_container_real_search_co (RygelLmsCategoryContainerSearchData* _data_) {
++	switch (_data_->_state_) {
++		case 0:
++		goto _state_0;
++		case 1:
++		goto _state_1;
++		default:
++		g_assert_not_reached ();
++	}
++	_state_0:
++	g_debug ("rygel-lms-category-container.vala:245: search()");
++	{
++		_data_->_tmp0_ = NULL;
++		_data_->_tmp0_ = g_value_array_new ((guint) 0);
++		_data_->args = _data_->_tmp0_;
++		_data_->_tmp1_ = NULL;
++		_data_->_tmp1_ = _data_->expression;
++		_data_->_tmp2_ = NULL;
++		_data_->_tmp2_ = _data_->args;
++		_data_->_tmp3_ = NULL;
++		_data_->_tmp3_ = rygel_lms_category_container_search_expression_to_sql (_data_->_tmp1_, _data_->_tmp2_, &_data_->_inner_error_);
++		_data_->filter = _data_->_tmp3_;
++		if (G_UNLIKELY (_data_->_inner_error_ != NULL)) {
++			_g_value_array_free0 (_data_->args);
++			goto __catch4_g_error;
++		}
++		_data_->_tmp4_ = NULL;
++		_data_->_tmp4_ = _data_->filter;
++		_data_->_tmp5_ = NULL;
++		_data_->_tmp5_ = _data_->args;
++		_data_->_tmp6_ = 0U;
++		_data_->_tmp6_ = rygel_lms_category_container_get_child_count_with_filter (_data_->self, _data_->_tmp4_, _data_->_tmp5_);
++		_data_->total_matches = _data_->_tmp6_;
++		_data_->_tmp7_ = NULL;
++		_data_->_tmp7_ = _data_->expression;
++		if (_data_->_tmp7_ != NULL) {
++			_data_->_tmp8_ = NULL;
++			_data_->_tmp8_ = _data_->expression;
++			_data_->_tmp9_ = NULL;
++			_data_->_tmp9_ = rygel_search_expression_to_string (_data_->_tmp8_);
++			_data_->_tmp10_ = NULL;
++			_data_->_tmp10_ = _data_->_tmp9_;
++			g_debug ("rygel-lms-category-container.vala:253:   Original search: %s", _data_->_tmp10_);
++			_g_free0 (_data_->_tmp10_);
++			_data_->_tmp11_ = NULL;
++			_data_->_tmp11_ = _data_->filter;
++			g_debug ("rygel-lms-category-container.vala:254:   Parsed search expression: %s", _data_->_tmp11_);
++			_data_->_tmp12_ = 0U;
++			_data_->_tmp12_ = _data_->total_matches;
++			g_debug ("rygel-lms-category-container.vala:255:   Filtered cild count is %u", _data_->_tmp12_);
++		}
++		_data_->_tmp13_ = 0U;
++		_data_->_tmp13_ = _data_->max_count;
++		if (_data_->_tmp13_ == ((guint) 0)) {
++			_data_->max_count = G_MAXUINT;
++		}
++		_data_->_tmp14_ = NULL;
++		_data_->_tmp14_ = _data_->filter;
++		_data_->_tmp15_ = NULL;
++		_data_->_tmp15_ = _data_->args;
++		_data_->_tmp16_ = NULL;
++		_data_->_tmp16_ = _data_->sort_criteria;
++		_data_->_tmp17_ = 0U;
++		_data_->_tmp17_ = _data_->offset;
++		_data_->_tmp18_ = 0U;
++		_data_->_tmp18_ = _data_->max_count;
++		_data_->_tmp19_ = NULL;
++		_data_->_tmp19_ = rygel_lms_category_container_get_children_with_filter (_data_->self, _data_->_tmp14_, _data_->_tmp15_, _data_->_tmp16_, _data_->_tmp17_, _data_->_tmp18_);
++		_data_->result = _data_->_tmp19_;
++		_g_free0 (_data_->filter);
++		_g_value_array_free0 (_data_->args);
++		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;
++	}
++	goto __finally4;
++	__catch4_g_error:
++	{
++		_data_->e = _data_->_inner_error_;
++		_data_->_inner_error_ = NULL;
++		_data_->_tmp20_ = NULL;
++		_data_->_tmp20_ = _data_->e;
++		_data_->_tmp21_ = NULL;
++		_data_->_tmp21_ = _data_->_tmp20_->message;
++		g_debug ("rygel-lms-category-container.vala:267:   Falling back to simple_search" \
++"(): %s", _data_->_tmp21_);
++		_data_->_tmp23_ = NULL;
++		_data_->_tmp23_ = _data_->expression;
++		_data_->_tmp24_ = 0U;
++		_data_->_tmp24_ = _data_->offset;
++		_data_->_tmp25_ = 0U;
++		_data_->_tmp25_ = _data_->max_count;
++		_data_->_tmp26_ = NULL;
++		_data_->_tmp26_ = _data_->sort_criteria;
++		_data_->_tmp27_ = NULL;
++		_data_->_tmp27_ = _data_->cancellable;
++		_data_->_tmp28_ = 0U;
++		_data_->_state_ = 1;
++		rygel_searchable_container_simple_search ((RygelSearchableContainer*) _data_->self, _data_->_tmp23_, _data_->_tmp24_, _data_->_tmp25_, _data_->_tmp26_, _data_->_tmp27_, rygel_lms_category_container_search_ready, _data_);
++		return FALSE;
++		_state_1:
++		_data_->_tmp29_ = NULL;
++		_data_->_tmp29_ = rygel_searchable_container_simple_search_finish ((RygelSearchableContainer*) _data_->self, _data_->_res_, &_data_->_tmp28_, &_data_->_inner_error_);
++		_data_->total_matches = _data_->_tmp28_;
++		_data_->_tmp22_ = _data_->_tmp29_;
++		if (G_UNLIKELY (_data_->_inner_error_ != NULL)) {
++			_g_error_free0 (_data_->e);
++			goto __finally4;
++		}
++		_data_->_tmp30_ = NULL;
++		_data_->_tmp30_ = _data_->_tmp22_;
++		_data_->_tmp22_ = NULL;
++		_data_->result = _data_->_tmp30_;
++		_g_object_unref0 (_data_->_tmp22_);
++		_g_error_free0 (_data_->e);
++		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;
++	}
++	__finally4:
++	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_->_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_lms_category_container_real_get_children_data_free (gpointer _data) {
++	RygelLmsCategoryContainerGetChildrenData* _data_;
++	_data_ = _data;
++	_g_free0 (_data_->sort_criteria);
++	_g_object_unref0 (_data_->cancellable);
++	_g_object_unref0 (_data_->result);
++	_g_object_unref0 (_data_->self);
++	g_slice_free (RygelLmsCategoryContainerGetChildrenData, _data_);
++}
++
++
++static void rygel_lms_category_container_real_get_children (RygelMediaContainer* base, guint offset, guint max_count, const gchar* sort_criteria, GCancellable* cancellable, GAsyncReadyCallback _callback_, gpointer _user_data_) {
++	RygelLMSCategoryContainer * self;
++	RygelLmsCategoryContainerGetChildrenData* _data_;
++	RygelLMSCategoryContainer* _tmp0_ = NULL;
++	guint _tmp1_ = 0U;
++	guint _tmp2_ = 0U;
++	const gchar* _tmp3_ = NULL;
++	gchar* _tmp4_ = NULL;
++	GCancellable* _tmp5_ = NULL;
++	GCancellable* _tmp6_ = NULL;
++	self = (RygelLMSCategoryContainer*) base;
++	_data_ = g_slice_new0 (RygelLmsCategoryContainerGetChildrenData);
++	_data_->_async_result = g_simple_async_result_new (G_OBJECT (self), _callback_, _user_data_, rygel_lms_category_container_real_get_children);
++	g_simple_async_result_set_op_res_gpointer (_data_->_async_result, _data_, rygel_lms_category_container_real_get_children_data_free);
++	_tmp0_ = _g_object_ref0 (self);
++	_data_->self = _tmp0_;
++	_tmp1_ = offset;
++	_data_->offset = _tmp1_;
++	_tmp2_ = max_count;
++	_data_->max_count = _tmp2_;
++	_tmp3_ = sort_criteria;
++	_tmp4_ = g_strdup (_tmp3_);
++	_g_free0 (_data_->sort_criteria);
++	_data_->sort_criteria = _tmp4_;
++	_tmp5_ = cancellable;
++	_tmp6_ = _g_object_ref0 (_tmp5_);
++	_g_object_unref0 (_data_->cancellable);
++	_data_->cancellable = _tmp6_;
++	rygel_lms_category_container_real_get_children_co (_data_);
++}
++
++
++static RygelMediaObjects* rygel_lms_category_container_real_get_children_finish (RygelMediaContainer* base, GAsyncResult* _res_, GError** error) {
++	RygelMediaObjects* result;
++	RygelLmsCategoryContainerGetChildrenData* _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;
++}
++
++
++static gboolean rygel_lms_category_container_real_get_children_co (RygelLmsCategoryContainerGetChildrenData* _data_) {
++	switch (_data_->_state_) {
++		case 0:
++		goto _state_0;
++		default:
++		g_assert_not_reached ();
++	}
++	_state_0:
++	_data_->_tmp0_ = NULL;
++	_data_->_tmp0_ = rygel_media_objects_new ();
++	_data_->retval = _data_->_tmp0_;
++	_data_->_tmp1_ = NULL;
++	_data_->_tmp1_ = _data_->self->stmt_all;
++	_data_->_tmp2_ = 0U;
++	_data_->_tmp2_ = _data_->offset;
++	_data_->_tmp3_ = 0U;
++	_data_->_tmp3_ = _data_->max_count;
++	_data_->_tmp4_ = NULL;
++	_data_->_tmp4_ = _data_->sort_criteria;
++	rygel_lms_database_get_children_init (_data_->_tmp1_, _data_->_tmp2_, _data_->_tmp3_, _data_->_tmp4_, &_data_->_inner_error_);
++	if (G_UNLIKELY (_data_->_inner_error_ != NULL)) {
++		g_simple_async_result_set_from_error (_data_->_async_result, _data_->_inner_error_);
++		g_error_free (_data_->_inner_error_);
++		_g_object_unref0 (_data_->retval);
++		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;
++	}
++	while (TRUE) {
++		_data_->_tmp6_ = NULL;
++		_data_->_tmp6_ = _data_->self->stmt_all;
++		_data_->_tmp7_ = FALSE;
++		_data_->_tmp7_ = rygel_lms_database_get_children_step (_data_->_tmp6_, &_data_->_inner_error_);
++		_data_->_tmp5_ = _data_->_tmp7_;
++		if (G_UNLIKELY (_data_->_inner_error_ != NULL)) {
++			g_simple_async_result_set_from_error (_data_->_async_result, _data_->_inner_error_);
++			g_error_free (_data_->_inner_error_);
++			_g_object_unref0 (_data_->retval);
++			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_->_tmp5_) {
++			break;
++		}
++		_data_->_tmp8_ = NULL;
++		_data_->_tmp8_ = _data_->retval;
++		_data_->_tmp9_ = NULL;
++		_data_->_tmp9_ = _data_->self->stmt_all;
++		_data_->_tmp10_ = NULL;
++		_data_->_tmp10_ = rygel_lms_category_container_object_from_statement (_data_->self, _data_->_tmp9_);
++		_data_->_tmp11_ = NULL;
++		_data_->_tmp11_ = _data_->_tmp10_;
++		gee_abstract_collection_add ((GeeAbstractCollection*) _data_->_tmp8_, _data_->_tmp11_);
++		_g_object_unref0 (_data_->_tmp11_);
++	}
++	_data_->result = _data_->retval;
++	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_unref0 (_data_->retval);
++	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_lms_category_container_real_find_object_data_free (gpointer _data) {
++	RygelLmsCategoryContainerFindObjectData* _data_;
++	_data_ = _data;
++	_g_free0 (_data_->id);
++	_g_object_unref0 (_data_->cancellable);
++	_g_object_unref0 (_data_->result);
++	_g_object_unref0 (_data_->self);
++	g_slice_free (RygelLmsCategoryContainerFindObjectData, _data_);
++}
++
++
++static void rygel_lms_category_container_real_find_object (RygelMediaContainer* base, const gchar* id, GCancellable* cancellable, GAsyncReadyCallback _callback_, gpointer _user_data_) {
++	RygelLMSCategoryContainer * self;
++	RygelLmsCategoryContainerFindObjectData* _data_;
++	RygelLMSCategoryContainer* _tmp0_ = NULL;
++	const gchar* _tmp1_ = NULL;
++	gchar* _tmp2_ = NULL;
++	GCancellable* _tmp3_ = NULL;
++	GCancellable* _tmp4_ = NULL;
++	self = (RygelLMSCategoryContainer*) base;
++	_data_ = g_slice_new0 (RygelLmsCategoryContainerFindObjectData);
++	_data_->_async_result = g_simple_async_result_new (G_OBJECT (self), _callback_, _user_data_, rygel_lms_category_container_real_find_object);
++	g_simple_async_result_set_op_res_gpointer (_data_->_async_result, _data_, rygel_lms_category_container_real_find_object_data_free);
++	_tmp0_ = _g_object_ref0 (self);
++	_data_->self = _tmp0_;
++	_tmp1_ = id;
++	_tmp2_ = g_strdup (_tmp1_);
++	_g_free0 (_data_->id);
++	_data_->id = _tmp2_;
++	_tmp3_ = cancellable;
++	_tmp4_ = _g_object_ref0 (_tmp3_);
++	_g_object_unref0 (_data_->cancellable);
++	_data_->cancellable = _tmp4_;
++	rygel_lms_category_container_real_find_object_co (_data_);
++}
++
++
++static RygelMediaObject* rygel_lms_category_container_real_find_object_finish (RygelMediaContainer* base, GAsyncResult* _res_, GError** error) {
++	RygelMediaObject* result;
++	RygelLmsCategoryContainerFindObjectData* _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;
++}
++
++
++static glong string_strnlen (gchar* str, glong maxlen) {
++	glong result = 0L;
++	gchar* end = NULL;
++	gchar* _tmp0_ = NULL;
++	glong _tmp1_ = 0L;
++	gchar* _tmp2_ = NULL;
++	gchar* _tmp3_ = NULL;
++	_tmp0_ = str;
++	_tmp1_ = maxlen;
++	_tmp2_ = memchr (_tmp0_, 0, (gsize) _tmp1_);
++	end = _tmp2_;
++	_tmp3_ = end;
++	if (_tmp3_ == NULL) {
++		glong _tmp4_ = 0L;
++		_tmp4_ = maxlen;
++		result = _tmp4_;
++		return result;
++	} else {
++		gchar* _tmp5_ = NULL;
++		gchar* _tmp6_ = NULL;
++		_tmp5_ = end;
++		_tmp6_ = str;
++		result = (glong) (_tmp5_ - _tmp6_);
++		return result;
++	}
++}
++
++
++static gchar* string_substring (const gchar* self, glong offset, glong len) {
++	gchar* result = NULL;
++	glong string_length = 0L;
++	gboolean _tmp0_ = FALSE;
++	glong _tmp1_ = 0L;
++	glong _tmp8_ = 0L;
++	glong _tmp14_ = 0L;
++	glong _tmp17_ = 0L;
++	glong _tmp18_ = 0L;
++	glong _tmp19_ = 0L;
++	glong _tmp20_ = 0L;
++	glong _tmp21_ = 0L;
++	gchar* _tmp22_ = NULL;
++	g_return_val_if_fail (self != NULL, NULL);
++	_tmp1_ = offset;
++	if (_tmp1_ >= ((glong) 0)) {
++		glong _tmp2_ = 0L;
++		_tmp2_ = len;
++		_tmp0_ = _tmp2_ >= ((glong) 0);
++	} else {
++		_tmp0_ = FALSE;
++	}
++	if (_tmp0_) {
++		glong _tmp3_ = 0L;
++		glong _tmp4_ = 0L;
++		glong _tmp5_ = 0L;
++		_tmp3_ = offset;
++		_tmp4_ = len;
++		_tmp5_ = string_strnlen ((gchar*) self, _tmp3_ + _tmp4_);
++		string_length = _tmp5_;
++	} else {
++		gint _tmp6_ = 0;
++		gint _tmp7_ = 0;
++		_tmp6_ = strlen (self);
++		_tmp7_ = _tmp6_;
++		string_length = (glong) _tmp7_;
++	}
++	_tmp8_ = offset;
++	if (_tmp8_ < ((glong) 0)) {
++		glong _tmp9_ = 0L;
++		glong _tmp10_ = 0L;
++		glong _tmp11_ = 0L;
++		_tmp9_ = string_length;
++		_tmp10_ = offset;
++		offset = _tmp9_ + _tmp10_;
++		_tmp11_ = offset;
++		g_return_val_if_fail (_tmp11_ >= ((glong) 0), NULL);
++	} else {
++		glong _tmp12_ = 0L;
++		glong _tmp13_ = 0L;
++		_tmp12_ = offset;
++		_tmp13_ = string_length;
++		g_return_val_if_fail (_tmp12_ <= _tmp13_, NULL);
++	}
++	_tmp14_ = len;
++	if (_tmp14_ < ((glong) 0)) {
++		glong _tmp15_ = 0L;
++		glong _tmp16_ = 0L;
++		_tmp15_ = string_length;
++		_tmp16_ = offset;
++		len = _tmp15_ - _tmp16_;
++	}
++	_tmp17_ = offset;
++	_tmp18_ = len;
++	_tmp19_ = string_length;
++	g_return_val_if_fail ((_tmp17_ + _tmp18_) <= _tmp19_, NULL);
++	_tmp20_ = offset;
++	_tmp21_ = len;
++	_tmp22_ = g_strndup (((gchar*) self) + _tmp20_, (gsize) _tmp21_);
++	result = _tmp22_;
++	return result;
++}
++
++
++static gint string_index_of_char (const gchar* self, gunichar c, gint start_index) {
++	gint result = 0;
++	gchar* _result_ = NULL;
++	gint _tmp0_ = 0;
++	gunichar _tmp1_ = 0U;
++	gchar* _tmp2_ = NULL;
++	gchar* _tmp3_ = NULL;
++	g_return_val_if_fail (self != NULL, 0);
++	_tmp0_ = start_index;
++	_tmp1_ = c;
++	_tmp2_ = g_utf8_strchr (((gchar*) self) + _tmp0_, (gssize) (-1), _tmp1_);
++	_result_ = _tmp2_;
++	_tmp3_ = _result_;
++	if (_tmp3_ != NULL) {
++		gchar* _tmp4_ = NULL;
++		_tmp4_ = _result_;
++		result = (gint) (_tmp4_ - ((gchar*) self));
++		return result;
++	} else {
++		result = -1;
++		return result;
++	}
++}
++
++
++static gchar* string_slice (const gchar* self, glong start, glong end) {
++	gchar* result = NULL;
++	glong string_length = 0L;
++	gint _tmp0_ = 0;
++	gint _tmp1_ = 0;
++	glong _tmp2_ = 0L;
++	glong _tmp5_ = 0L;
++	gboolean _tmp8_ = FALSE;
++	glong _tmp9_ = 0L;
++	gboolean _tmp12_ = FALSE;
++	glong _tmp13_ = 0L;
++	glong _tmp16_ = 0L;
++	glong _tmp17_ = 0L;
++	glong _tmp18_ = 0L;
++	glong _tmp19_ = 0L;
++	glong _tmp20_ = 0L;
++	gchar* _tmp21_ = 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_ = 0L;
++		glong _tmp4_ = 0L;
++		_tmp3_ = string_length;
++		_tmp4_ = start;
++		start = _tmp3_ + _tmp4_;
++	}
++	_tmp5_ = end;
++	if (_tmp5_ < ((glong) 0)) {
++		glong _tmp6_ = 0L;
++		glong _tmp7_ = 0L;
++		_tmp6_ = string_length;
++		_tmp7_ = end;
++		end = _tmp6_ + _tmp7_;
++	}
++	_tmp9_ = start;
++	if (_tmp9_ >= ((glong) 0)) {
++		glong _tmp10_ = 0L;
++		glong _tmp11_ = 0L;
++		_tmp10_ = start;
++		_tmp11_ = string_length;
++		_tmp8_ = _tmp10_ <= _tmp11_;
++	} else {
++		_tmp8_ = FALSE;
++	}
++	g_return_val_if_fail (_tmp8_, NULL);
++	_tmp13_ = end;
++	if (_tmp13_ >= ((glong) 0)) {
++		glong _tmp14_ = 0L;
++		glong _tmp15_ = 0L;
++		_tmp14_ = end;
++		_tmp15_ = string_length;
++		_tmp12_ = _tmp14_ <= _tmp15_;
++	} else {
++		_tmp12_ = FALSE;
++	}
++	g_return_val_if_fail (_tmp12_, NULL);
++	_tmp16_ = start;
++	_tmp17_ = end;
++	g_return_val_if_fail (_tmp16_ <= _tmp17_, NULL);
++	_tmp18_ = start;
++	_tmp19_ = end;
++	_tmp20_ = start;
++	_tmp21_ = g_strndup (((gchar*) self) + _tmp18_, (gsize) (_tmp19_ - _tmp20_));
++	result = _tmp21_;
++	return result;
++}
++
++
++static void rygel_lms_category_container_find_object_ready (GObject* source_object, GAsyncResult* _res_, gpointer _user_data_) {
++	RygelLmsCategoryContainerFindObjectData* _data_;
++	_data_ = _user_data_;
++	_data_->_source_object_ = source_object;
++	_data_->_res_ = _res_;
++	rygel_lms_category_container_real_find_object_co (_data_);
++}
++
++
++static gboolean rygel_lms_category_container_real_find_object_co (RygelLmsCategoryContainerFindObjectData* _data_) {
++	switch (_data_->_state_) {
++		case 0:
++		goto _state_0;
++		case 1:
++		goto _state_1;
++		default:
++		g_assert_not_reached ();
++	}
++	_state_0:
++	_data_->_tmp0_ = NULL;
++	_data_->_tmp0_ = _data_->id;
++	_data_->_tmp1_ = NULL;
++	_data_->_tmp1_ = _data_->self->child_prefix;
++	_data_->_tmp2_ = FALSE;
++	_data_->_tmp2_ = g_str_has_prefix (_data_->_tmp0_, _data_->_tmp1_);
++	if (!_data_->_tmp2_) {
++		_data_->result = NULL;
++		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_->object = NULL;
++	_data_->_tmp3_ = NULL;
++	_data_->_tmp3_ = _data_->id;
++	_data_->_tmp4_ = NULL;
++	_data_->_tmp4_ = _data_->self->child_prefix;
++	_data_->_tmp5_ = 0;
++	_data_->_tmp5_ = strlen (_data_->_tmp4_);
++	_data_->_tmp6_ = 0;
++	_data_->_tmp6_ = _data_->_tmp5_;
++	_data_->_tmp7_ = NULL;
++	_data_->_tmp7_ = string_substring (_data_->_tmp3_, (glong) _data_->_tmp6_, (glong) (-1));
++	_data_->real_id = _data_->_tmp7_;
++	_data_->_tmp8_ = NULL;
++	_data_->_tmp8_ = _data_->real_id;
++	_data_->_tmp9_ = 0;
++	_data_->_tmp9_ = string_index_of_char (_data_->_tmp8_, (gunichar) ':', 0);
++	_data_->index = _data_->_tmp9_;
++	_data_->_tmp10_ = 0;
++	_data_->_tmp10_ = _data_->index;
++	if (_data_->_tmp10_ > 0) {
++		_data_->_tmp11_ = NULL;
++		_data_->_tmp11_ = _data_->real_id;
++		_data_->_tmp12_ = 0;
++		_data_->_tmp12_ = _data_->index;
++		_data_->_tmp13_ = NULL;
++		_data_->_tmp13_ = string_slice (_data_->_tmp11_, (glong) 0, (glong) _data_->_tmp12_);
++		_g_free0 (_data_->real_id);
++		_data_->real_id = _data_->_tmp13_;
++	}
++	{
++		_data_->_tmp14_ = NULL;
++		_data_->_tmp14_ = _data_->real_id;
++		_data_->_tmp15_ = NULL;
++		_data_->_tmp15_ = _data_->self->stmt_find_object;
++		rygel_lms_database_find_object (_data_->_tmp14_, _data_->_tmp15_, &_data_->_inner_error_);
++		if (G_UNLIKELY (_data_->_inner_error_ != NULL)) {
++			if (_data_->_inner_error_->domain == RYGEL_LMS_DATABASE_ERROR) {
++				goto __catch5_rygel_lms_database_error;
++			}
++			_g_free0 (_data_->real_id);
++			_g_object_unref0 (_data_->object);
++			g_critical ("file %s: line %d: unexpected error: %s (%s, %d)", __FILE__, __LINE__, _data_->_inner_error_->message, g_quark_to_string (_data_->_inner_error_->domain), _data_->_inner_error_->code);
++			g_clear_error (&_data_->_inner_error_);
++			return FALSE;
++		}
++		_data_->_tmp16_ = NULL;
++		_data_->_tmp16_ = _data_->self->stmt_find_object;
++		_data_->_tmp17_ = NULL;
++		_data_->_tmp17_ = rygel_lms_category_container_object_from_statement (_data_->self, _data_->_tmp16_);
++		_data_->child = _data_->_tmp17_;
++		_data_->_tmp18_ = 0;
++		_data_->_tmp18_ = _data_->index;
++		if (_data_->_tmp18_ < 0) {
++			_data_->_tmp19_ = NULL;
++			_data_->_tmp19_ = _data_->child;
++			_data_->_tmp20_ = NULL;
++			_data_->_tmp20_ = _g_object_ref0 (_data_->_tmp19_);
++			_g_object_unref0 (_data_->object);
++			_data_->object = _data_->_tmp20_;
++		} else {
++			_data_->_tmp21_ = NULL;
++			_data_->_tmp21_ = _data_->child;
++			_data_->_tmp22_ = NULL;
++			_data_->_tmp22_ = _g_object_ref0 (G_TYPE_CHECK_INSTANCE_TYPE (_data_->_tmp21_, RYGEL_LMS_TYPE_CATEGORY_CONTAINER) ? ((RygelLMSCategoryContainer*) _data_->_tmp21_) : NULL);
++			_data_->container = _data_->_tmp22_;
++			_data_->_tmp24_ = NULL;
++			_data_->_tmp24_ = _data_->container;
++			_data_->_tmp25_ = NULL;
++			_data_->_tmp25_ = _data_->id;
++			_data_->_tmp26_ = NULL;
++			_data_->_tmp26_ = _data_->cancellable;
++			_data_->_state_ = 1;
++			rygel_media_container_find_object ((RygelMediaContainer*) _data_->_tmp24_, _data_->_tmp25_, _data_->_tmp26_, rygel_lms_category_container_find_object_ready, _data_);
++			return FALSE;
++			_state_1:
++			_data_->_tmp27_ = NULL;
++			_data_->_tmp27_ = rygel_media_container_find_object_finish ((RygelMediaContainer*) _data_->_tmp24_, _data_->_res_, &_data_->_inner_error_);
++			_data_->_tmp23_ = _data_->_tmp27_;
++			if (G_UNLIKELY (_data_->_inner_error_ != NULL)) {
++				_g_object_unref0 (_data_->container);
++				_g_object_unref0 (_data_->child);
++				if (_data_->_inner_error_->domain == RYGEL_LMS_DATABASE_ERROR) {
++					goto __catch5_rygel_lms_database_error;
++				}
++				goto __finally5;
++			}
++			_data_->_tmp28_ = NULL;
++			_data_->_tmp28_ = _data_->_tmp23_;
++			_data_->_tmp23_ = NULL;
++			_g_object_unref0 (_data_->object);
++			_data_->object = _data_->_tmp28_;
++			_data_->_tmp29_ = NULL;
++			_data_->_tmp29_ = _data_->object;
++			_data_->_tmp30_ = NULL;
++			_data_->_tmp30_ = _data_->object;
++			_data_->_tmp31_ = NULL;
++			_data_->_tmp31_ = rygel_media_object_get_parent (_data_->_tmp30_);
++			_data_->_tmp32_ = NULL;
++			_data_->_tmp32_ = _data_->_tmp31_;
++			rygel_media_object_set_parent_ref (_data_->_tmp29_, _data_->_tmp32_);
++			_g_object_unref0 (_data_->_tmp23_);
++			_g_object_unref0 (_data_->container);
++		}
++		_g_object_unref0 (_data_->child);
++	}
++	goto __finally5;
++	__catch5_rygel_lms_database_error:
++	{
++		_data_->e = _data_->_inner_error_;
++		_data_->_inner_error_ = NULL;
++		_data_->_tmp33_ = NULL;
++		_data_->_tmp33_ = _data_->id;
++		_data_->_tmp34_ = NULL;
++		_data_->_tmp34_ = rygel_media_object_get_id ((RygelMediaObject*) _data_->self);
++		_data_->_tmp35_ = NULL;
++		_data_->_tmp35_ = _data_->_tmp34_;
++		_data_->_tmp36_ = NULL;
++		_data_->_tmp36_ = _data_->e;
++		_data_->_tmp37_ = NULL;
++		_data_->_tmp37_ = _data_->_tmp36_->message;
++		g_debug ("rygel-lms-category-container.vala:328: find_object %s in %s: %s", _data_->_tmp33_, _data_->_tmp35_, _data_->_tmp37_);
++		_g_error_free0 (_data_->e);
++	}
++	__finally5:
++	if (G_UNLIKELY (_data_->_inner_error_ != NULL)) {
++		g_simple_async_result_set_from_error (_data_->_async_result, _data_->_inner_error_);
++		g_error_free (_data_->_inner_error_);
++		_g_free0 (_data_->real_id);
++		_g_object_unref0 (_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;
++	_g_free0 (_data_->real_id);
++	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_free0 (_data_->real_id);
++	_g_object_unref0 (_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;
++}
++
++
++gchar* rygel_lms_category_container_build_child_id (RygelLMSCategoryContainer* self, gint db_id) {
++	gchar* result = NULL;
++	const gchar* _tmp0_ = NULL;
++	gint _tmp1_ = 0;
++	gchar* _tmp2_ = NULL;
++	g_return_val_if_fail (self != NULL, NULL);
++	_tmp0_ = self->child_prefix;
++	_tmp1_ = db_id;
++	_tmp2_ = g_strdup_printf ("%s%d", _tmp0_, _tmp1_);
++	result = _tmp2_;
++	return result;
++}
++
++
++gchar* rygel_lms_category_container_build_reference_id (RygelLMSCategoryContainer* self, gint db_id) {
++	gchar* result = NULL;
++	const gchar* _tmp0_ = NULL;
++	gint _tmp1_ = 0;
++	gchar* _tmp2_ = NULL;
++	g_return_val_if_fail (self != NULL, NULL);
++	_tmp0_ = self->ref_prefix;
++	_tmp1_ = db_id;
++	_tmp2_ = g_strdup_printf ("%s%d", _tmp0_, _tmp1_);
++	result = _tmp2_;
++	return result;
++}
++
++
++static void rygel_lms_category_container_real_add_child_data_free (gpointer _data) {
++	RygelLmsCategoryContainerAddChildData* _data_;
++	_data_ = _data;
++	_g_object_unref0 (_data_->object);
++	_g_object_unref0 (_data_->self);
++	g_slice_free (RygelLmsCategoryContainerAddChildData, _data_);
++}
++
++
++static void rygel_lms_category_container_real_add_child (RygelTrackableContainer* base, RygelMediaObject* object, GAsyncReadyCallback _callback_, gpointer _user_data_) {
++	RygelLMSCategoryContainer * self;
++	RygelLmsCategoryContainerAddChildData* _data_;
++	RygelLMSCategoryContainer* _tmp0_ = NULL;
++	RygelMediaObject* _tmp1_ = NULL;
++	RygelMediaObject* _tmp2_ = NULL;
++	self = (RygelLMSCategoryContainer*) base;
++	_data_ = g_slice_new0 (RygelLmsCategoryContainerAddChildData);
++	_data_->_async_result = g_simple_async_result_new (G_OBJECT (self), _callback_, _user_data_, rygel_lms_category_container_real_add_child);
++	g_simple_async_result_set_op_res_gpointer (_data_->_async_result, _data_, rygel_lms_category_container_real_add_child_data_free);
++	_tmp0_ = _g_object_ref0 (self);
++	_data_->self = _tmp0_;
++	_tmp1_ = object;
++	_tmp2_ = _g_object_ref0 (_tmp1_);
++	_g_object_unref0 (_data_->object);
++	_data_->object = _tmp2_;
++	rygel_lms_category_container_real_add_child_co (_data_);
++}
++
++
++static void rygel_lms_category_container_real_add_child_finish (RygelTrackableContainer* base, GAsyncResult* _res_) {
++	RygelLmsCategoryContainerAddChildData* _data_;
++	_data_ = g_simple_async_result_get_op_res_gpointer (G_SIMPLE_ASYNC_RESULT (_res_));
++}
++
++
++static gboolean rygel_lms_category_container_real_add_child_co (RygelLmsCategoryContainerAddChildData* _data_) {
++	switch (_data_->_state_) {
++		case 0:
++		goto _state_0;
++		default:
++		g_assert_not_reached ();
++	}
++	_state_0:
++	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_lms_category_container_real_remove_child_data_free (gpointer _data) {
++	RygelLmsCategoryContainerRemoveChildData* _data_;
++	_data_ = _data;
++	_g_object_unref0 (_data_->object);
++	_g_object_unref0 (_data_->self);
++	g_slice_free (RygelLmsCategoryContainerRemoveChildData, _data_);
++}
++
++
++static void rygel_lms_category_container_real_remove_child (RygelTrackableContainer* base, RygelMediaObject* object, GAsyncReadyCallback _callback_, gpointer _user_data_) {
++	RygelLMSCategoryContainer * self;
++	RygelLmsCategoryContainerRemoveChildData* _data_;
++	RygelLMSCategoryContainer* _tmp0_ = NULL;
++	RygelMediaObject* _tmp1_ = NULL;
++	RygelMediaObject* _tmp2_ = NULL;
++	self = (RygelLMSCategoryContainer*) base;
++	_data_ = g_slice_new0 (RygelLmsCategoryContainerRemoveChildData);
++	_data_->_async_result = g_simple_async_result_new (G_OBJECT (self), _callback_, _user_data_, rygel_lms_category_container_real_remove_child);
++	g_simple_async_result_set_op_res_gpointer (_data_->_async_result, _data_, rygel_lms_category_container_real_remove_child_data_free);
++	_tmp0_ = _g_object_ref0 (self);
++	_data_->self = _tmp0_;
++	_tmp1_ = object;
++	_tmp2_ = _g_object_ref0 (_tmp1_);
++	_g_object_unref0 (_data_->object);
++	_data_->object = _tmp2_;
++	rygel_lms_category_container_real_remove_child_co (_data_);
++}
++
++
++static void rygel_lms_category_container_real_remove_child_finish (RygelTrackableContainer* base, GAsyncResult* _res_) {
++	RygelLmsCategoryContainerRemoveChildData* _data_;
++	_data_ = g_simple_async_result_get_op_res_gpointer (G_SIMPLE_ASYNC_RESULT (_res_));
++}
++
++
++static gboolean rygel_lms_category_container_real_remove_child_co (RygelLmsCategoryContainerRemoveChildData* _data_) {
++	switch (_data_->_state_) {
++		case 0:
++		goto _state_0;
++		default:
++		g_assert_not_reached ();
++	}
++	_state_0:
++	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_lms_category_container_on_db_updated (RygelLMSCategoryContainer* self, guint64 old_id, guint64 new_id) {
++	GError * _inner_error_ = NULL;
++	g_return_if_fail (self != NULL);
++	{
++		sqlite3_stmt* stmt_count = NULL;
++		RygelLMSDatabase* _tmp0_ = NULL;
++		const gchar* _tmp1_ = NULL;
++		sqlite3_stmt* _tmp2_ = NULL;
++		sqlite3_stmt* _tmp3_ = NULL;
++		gint _tmp4_ = 0;
++		sqlite3_stmt* _tmp7_ = NULL;
++		guint64 _tmp8_ = 0ULL;
++		guint64 _tmp9_ = 0ULL;
++		sqlite3_stmt* _tmp16_ = NULL;
++		guint64 _tmp17_ = 0ULL;
++		guint64 _tmp18_ = 0ULL;
++		_tmp0_ = self->priv->_lms_db;
++		_tmp1_ = self->priv->_sql_count;
++		_tmp2_ = rygel_lms_database_prepare (_tmp0_, _tmp1_, &_inner_error_);
++		stmt_count = _tmp2_;
++		if (G_UNLIKELY (_inner_error_ != NULL)) {
++			if (_inner_error_->domain == RYGEL_LMS_DATABASE_ERROR) {
++				goto __catch6_rygel_lms_database_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;
++		}
++		_tmp3_ = stmt_count;
++		_tmp4_ = sqlite3_step (_tmp3_);
++		if (_tmp4_ == SQLITE_ROW) {
++			sqlite3_stmt* _tmp5_ = NULL;
++			gint _tmp6_ = 0;
++			_tmp5_ = stmt_count;
++			_tmp6_ = sqlite3_column_int (_tmp5_, 0);
++			rygel_media_container_set_child_count ((RygelMediaContainer*) self, _tmp6_);
++		}
++		_tmp7_ = self->stmt_added;
++		_tmp8_ = old_id;
++		_tmp9_ = new_id;
++		rygel_lms_database_get_children_with_update_id_init (_tmp7_, _tmp8_, _tmp9_, &_inner_error_);
++		if (G_UNLIKELY (_inner_error_ != NULL)) {
++			_sqlite3_finalize0 (stmt_count);
++			if (_inner_error_->domain == RYGEL_LMS_DATABASE_ERROR) {
++				goto __catch6_rygel_lms_database_error;
++			}
++			_sqlite3_finalize0 (stmt_count);
++			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;
++		}
++		while (TRUE) {
++			gboolean _tmp10_ = FALSE;
++			sqlite3_stmt* _tmp11_ = NULL;
++			gboolean _tmp12_ = FALSE;
++			sqlite3_stmt* _tmp13_ = NULL;
++			RygelMediaObject* _tmp14_ = NULL;
++			RygelMediaObject* _tmp15_ = NULL;
++			_tmp11_ = self->stmt_added;
++			_tmp12_ = rygel_lms_database_get_children_step (_tmp11_, &_inner_error_);
++			_tmp10_ = _tmp12_;
++			if (G_UNLIKELY (_inner_error_ != NULL)) {
++				_sqlite3_finalize0 (stmt_count);
++				if (_inner_error_->domain == RYGEL_LMS_DATABASE_ERROR) {
++					goto __catch6_rygel_lms_database_error;
++				}
++				_sqlite3_finalize0 (stmt_count);
++				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;
++			}
++			if (!_tmp10_) {
++				break;
++			}
++			_tmp13_ = self->stmt_added;
++			_tmp14_ = rygel_lms_category_container_object_from_statement (self, _tmp13_);
++			_tmp15_ = _tmp14_;
++			rygel_trackable_container_add_child_tracked ((RygelTrackableContainer*) self, _tmp15_, NULL, NULL);
++			_g_object_unref0 (_tmp15_);
++		}
++		_tmp16_ = self->stmt_removed;
++		_tmp17_ = old_id;
++		_tmp18_ = new_id;
++		rygel_lms_database_get_children_with_update_id_init (_tmp16_, _tmp17_, _tmp18_, &_inner_error_);
++		if (G_UNLIKELY (_inner_error_ != NULL)) {
++			_sqlite3_finalize0 (stmt_count);
++			if (_inner_error_->domain == RYGEL_LMS_DATABASE_ERROR) {
++				goto __catch6_rygel_lms_database_error;
++			}
++			_sqlite3_finalize0 (stmt_count);
++			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;
++		}
++		while (TRUE) {
++			gboolean _tmp19_ = FALSE;
++			sqlite3_stmt* _tmp20_ = NULL;
++			gboolean _tmp21_ = FALSE;
++			sqlite3_stmt* _tmp22_ = NULL;
++			RygelMediaObject* _tmp23_ = NULL;
++			RygelMediaObject* _tmp24_ = NULL;
++			_tmp20_ = self->stmt_removed;
++			_tmp21_ = rygel_lms_database_get_children_step (_tmp20_, &_inner_error_);
++			_tmp19_ = _tmp21_;
++			if (G_UNLIKELY (_inner_error_ != NULL)) {
++				_sqlite3_finalize0 (stmt_count);
++				if (_inner_error_->domain == RYGEL_LMS_DATABASE_ERROR) {
++					goto __catch6_rygel_lms_database_error;
++				}
++				_sqlite3_finalize0 (stmt_count);
++				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;
++			}
++			if (!_tmp19_) {
++				break;
++			}
++			_tmp22_ = self->stmt_removed;
++			_tmp23_ = rygel_lms_category_container_object_from_statement (self, _tmp22_);
++			_tmp24_ = _tmp23_;
++			rygel_trackable_container_remove_child_tracked ((RygelTrackableContainer*) self, _tmp24_, NULL, NULL);
++			_g_object_unref0 (_tmp24_);
++		}
++		_sqlite3_finalize0 (stmt_count);
++	}
++	goto __finally6;
++	__catch6_rygel_lms_database_error:
++	{
++		GError* e = NULL;
++		GError* _tmp25_ = NULL;
++		const gchar* _tmp26_ = NULL;
++		e = _inner_error_;
++		_inner_error_ = NULL;
++		_tmp25_ = e;
++		_tmp26_ = _tmp25_->message;
++		g_warning ("rygel-lms-category-container.vala:372: Can't perform container update:" \
++" %s", _tmp26_);
++		_g_error_free0 (e);
++	}
++	__finally6:
++	if (G_UNLIKELY (_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;
++	}
++}
++
++
++RygelLMSCategoryContainer* rygel_lms_category_container_construct (GType object_type, const gchar* db_id, RygelMediaContainer* parent, const gchar* title, RygelLMSDatabase* lms_db, const gchar* sql_all, const gchar* sql_find_object, const gchar* sql_count, const gchar* sql_added, const gchar* sql_removed) {
++	RygelLMSCategoryContainer * self = NULL;
++	RygelMediaContainer* _tmp0_ = NULL;
++	const gchar* _tmp1_ = NULL;
++	const gchar* _tmp2_ = NULL;
++	const gchar* _tmp3_ = NULL;
++	gchar* _tmp4_ = NULL;
++	gchar* _tmp5_ = NULL;
++	const gchar* _tmp6_ = NULL;
++	RygelMediaContainer* _tmp7_ = NULL;
++	const gchar* _tmp8_ = NULL;
++	RygelLMSDatabase* _tmp9_ = NULL;
++	const gchar* _tmp10_ = NULL;
++	const gchar* _tmp11_ = NULL;
++	const gchar* _tmp12_ = NULL;
++	const gchar* _tmp13_ = NULL;
++	const gchar* _tmp14_ = NULL;
++	g_return_val_if_fail (db_id != NULL, NULL);
++	g_return_val_if_fail (parent != NULL, NULL);
++	g_return_val_if_fail (title != NULL, NULL);
++	g_return_val_if_fail (lms_db != NULL, NULL);
++	g_return_val_if_fail (sql_all != NULL, NULL);
++	g_return_val_if_fail (sql_find_object != NULL, NULL);
++	g_return_val_if_fail (sql_count != NULL, NULL);
++	_tmp0_ = parent;
++	_tmp1_ = rygel_media_object_get_id ((RygelMediaObject*) _tmp0_);
++	_tmp2_ = _tmp1_;
++	_tmp3_ = db_id;
++	_tmp4_ = g_strdup_printf ("%s:%s", _tmp2_, _tmp3_);
++	_tmp5_ = _tmp4_;
++	_tmp6_ = db_id;
++	_tmp7_ = parent;
++	_tmp8_ = title;
++	_tmp9_ = lms_db;
++	_tmp10_ = sql_all;
++	_tmp11_ = sql_find_object;
++	_tmp12_ = sql_count;
++	_tmp13_ = sql_added;
++	_tmp14_ = sql_removed;
++	self = (RygelLMSCategoryContainer*) g_object_new (object_type, "id", _tmp5_, "db-id", _tmp6_, "parent", _tmp7_, "title", _tmp8_, "lms-db", _tmp9_, "sql-all", _tmp10_, "sql-find-object", _tmp11_, "sql-count", _tmp12_, "sql-added", _tmp13_, "sql-removed", _tmp14_, NULL);
++	_g_free0 (_tmp5_);
++	return self;
++}
++
++
++static GeeArrayList* rygel_lms_category_container_real_get_search_classes (RygelSearchableContainer* base) {
++	GeeArrayList* result;
++	RygelLMSCategoryContainer* self;
++	GeeArrayList* _tmp0_ = NULL;
++	self = (RygelLMSCategoryContainer*) base;
++	_tmp0_ = self->priv->_search_classes;
++	result = _tmp0_;
++	return result;
++}
++
++
++static void rygel_lms_category_container_real_set_search_classes (RygelSearchableContainer* base, GeeArrayList* value) {
++	RygelLMSCategoryContainer* self;
++	GeeArrayList* _tmp0_ = NULL;
++	GeeArrayList* _tmp1_ = NULL;
++	self = (RygelLMSCategoryContainer*) base;
++	_tmp0_ = value;
++	_tmp1_ = _g_object_ref0 (_tmp0_);
++	_g_object_unref0 (self->priv->_search_classes);
++	self->priv->_search_classes = _tmp1_;
++	g_object_notify ((GObject *) self, "search-classes");
++}
++
++
++RygelLMSDatabase* rygel_lms_category_container_get_lms_db (RygelLMSCategoryContainer* self) {
++	RygelLMSDatabase* result;
++	RygelLMSDatabase* _tmp0_ = NULL;
++	g_return_val_if_fail (self != NULL, NULL);
++	_tmp0_ = self->priv->_lms_db;
++	result = _tmp0_;
++	return result;
++}
++
++
++static void rygel_lms_category_container_set_lms_db (RygelLMSCategoryContainer* self, RygelLMSDatabase* value) {
++	RygelLMSDatabase* _tmp0_ = NULL;
++	g_return_if_fail (self != NULL);
++	_tmp0_ = value;
++	self->priv->_lms_db = _tmp0_;
++	g_object_notify ((GObject *) self, "lms-db");
++}
++
++
++const gchar* rygel_lms_category_container_get_db_id (RygelLMSCategoryContainer* self) {
++	const gchar* result;
++	const gchar* _tmp0_ = NULL;
++	g_return_val_if_fail (self != NULL, NULL);
++	_tmp0_ = self->priv->_db_id;
++	result = _tmp0_;
++	return result;
++}
++
++
++static void rygel_lms_category_container_set_db_id (RygelLMSCategoryContainer* self, const gchar* value) {
++	const gchar* _tmp0_ = NULL;
++	gchar* _tmp1_ = NULL;
++	g_return_if_fail (self != NULL);
++	_tmp0_ = value;
++	_tmp1_ = g_strdup (_tmp0_);
++	_g_free0 (self->priv->_db_id);
++	self->priv->_db_id = _tmp1_;
++	g_object_notify ((GObject *) self, "db-id");
++}
++
++
++const gchar* rygel_lms_category_container_get_sql_all (RygelLMSCategoryContainer* self) {
++	const gchar* result;
++	const gchar* _tmp0_ = NULL;
++	g_return_val_if_fail (self != NULL, NULL);
++	_tmp0_ = self->priv->_sql_all;
++	result = _tmp0_;
++	return result;
++}
++
++
++static void rygel_lms_category_container_set_sql_all (RygelLMSCategoryContainer* self, const gchar* value) {
++	const gchar* _tmp0_ = NULL;
++	gchar* _tmp1_ = NULL;
++	g_return_if_fail (self != NULL);
++	_tmp0_ = value;
++	_tmp1_ = g_strdup (_tmp0_);
++	_g_free0 (self->priv->_sql_all);
++	self->priv->_sql_all = _tmp1_;
++	g_object_notify ((GObject *) self, "sql-all");
++}
++
++
++const gchar* rygel_lms_category_container_get_sql_find_object (RygelLMSCategoryContainer* self) {
++	const gchar* result;
++	const gchar* _tmp0_ = NULL;
++	g_return_val_if_fail (self != NULL, NULL);
++	_tmp0_ = self->priv->_sql_find_object;
++	result = _tmp0_;
++	return result;
++}
++
++
++static void rygel_lms_category_container_set_sql_find_object (RygelLMSCategoryContainer* self, const gchar* value) {
++	const gchar* _tmp0_ = NULL;
++	gchar* _tmp1_ = NULL;
++	g_return_if_fail (self != NULL);
++	_tmp0_ = value;
++	_tmp1_ = g_strdup (_tmp0_);
++	_g_free0 (self->priv->_sql_find_object);
++	self->priv->_sql_find_object = _tmp1_;
++	g_object_notify ((GObject *) self, "sql-find-object");
++}
++
++
++const gchar* rygel_lms_category_container_get_sql_count (RygelLMSCategoryContainer* self) {
++	const gchar* result;
++	const gchar* _tmp0_ = NULL;
++	g_return_val_if_fail (self != NULL, NULL);
++	_tmp0_ = self->priv->_sql_count;
++	result = _tmp0_;
++	return result;
++}
++
++
++static void rygel_lms_category_container_set_sql_count (RygelLMSCategoryContainer* self, const gchar* value) {
++	const gchar* _tmp0_ = NULL;
++	gchar* _tmp1_ = NULL;
++	g_return_if_fail (self != NULL);
++	_tmp0_ = value;
++	_tmp1_ = g_strdup (_tmp0_);
++	_g_free0 (self->priv->_sql_count);
++	self->priv->_sql_count = _tmp1_;
++	g_object_notify ((GObject *) self, "sql-count");
++}
++
++
++const gchar* rygel_lms_category_container_get_sql_added (RygelLMSCategoryContainer* self) {
++	const gchar* result;
++	const gchar* _tmp0_ = NULL;
++	g_return_val_if_fail (self != NULL, NULL);
++	_tmp0_ = self->priv->_sql_added;
++	result = _tmp0_;
++	return result;
++}
++
++
++static void rygel_lms_category_container_set_sql_added (RygelLMSCategoryContainer* self, const gchar* value) {
++	const gchar* _tmp0_ = NULL;
++	gchar* _tmp1_ = NULL;
++	g_return_if_fail (self != NULL);
++	_tmp0_ = value;
++	_tmp1_ = g_strdup (_tmp0_);
++	_g_free0 (self->priv->_sql_added);
++	self->priv->_sql_added = _tmp1_;
++	g_object_notify ((GObject *) self, "sql-added");
++}
++
++
++const gchar* rygel_lms_category_container_get_sql_removed (RygelLMSCategoryContainer* self) {
++	const gchar* result;
++	const gchar* _tmp0_ = NULL;
++	g_return_val_if_fail (self != NULL, NULL);
++	_tmp0_ = self->priv->_sql_removed;
++	result = _tmp0_;
++	return result;
++}
++
++
++static void rygel_lms_category_container_set_sql_removed (RygelLMSCategoryContainer* self, const gchar* value) {
++	const gchar* _tmp0_ = NULL;
++	gchar* _tmp1_ = NULL;
++	g_return_if_fail (self != NULL);
++	_tmp0_ = value;
++	_tmp1_ = g_strdup (_tmp0_);
++	_g_free0 (self->priv->_sql_removed);
++	self->priv->_sql_removed = _tmp1_;
++	g_object_notify ((GObject *) self, "sql-removed");
++}
++
++
++static void _rygel_lms_category_container_on_db_updated_rygel_lms_database_db_updated (RygelLMSDatabase* _sender, guint64 old_update_id, guint64 new_update_id, gpointer self) {
++	rygel_lms_category_container_on_db_updated ((RygelLMSCategoryContainer*) self, old_update_id, new_update_id);
++}
++
++
++static GObject * rygel_lms_category_container_constructor (GType type, guint n_construct_properties, GObjectConstructParam * construct_properties) {
++	GObject * obj;
++	GObjectClass * parent_class;
++	RygelLMSCategoryContainer * self;
++	GeeArrayList* _tmp0_ = NULL;
++	GeeArrayList* _tmp1_ = NULL;
++	const gchar* _tmp2_ = NULL;
++	const gchar* _tmp3_ = NULL;
++	gchar* _tmp4_ = NULL;
++	gint index = 0;
++	const gchar* _tmp5_ = NULL;
++	const gchar* _tmp6_ = NULL;
++	gint _tmp7_ = 0;
++	const gchar* _tmp8_ = NULL;
++	const gchar* _tmp9_ = NULL;
++	gint _tmp10_ = 0;
++	gchar* _tmp11_ = NULL;
++	gchar* _tmp12_ = NULL;
++	gchar* _tmp13_ = NULL;
++	GError * _inner_error_ = NULL;
++	parent_class = G_OBJECT_CLASS (rygel_lms_category_container_parent_class);
++	obj = parent_class->constructor (type, n_construct_properties, construct_properties);
++	self = G_TYPE_CHECK_INSTANCE_CAST (obj, RYGEL_LMS_TYPE_CATEGORY_CONTAINER, RygelLMSCategoryContainer);
++	_tmp0_ = gee_array_list_new (G_TYPE_STRING, (GBoxedCopyFunc) g_strdup, g_free, NULL, NULL, NULL);
++	_tmp1_ = _tmp0_;
++	rygel_searchable_container_set_search_classes ((RygelSearchableContainer*) self, _tmp1_);
++	_g_object_unref0 (_tmp1_);
++	_tmp2_ = rygel_media_object_get_id ((RygelMediaObject*) self);
++	_tmp3_ = _tmp2_;
++	_tmp4_ = g_strdup_printf ("%s:", _tmp3_);
++	_g_free0 (self->child_prefix);
++	self->child_prefix = _tmp4_;
++	_tmp5_ = rygel_media_object_get_id ((RygelMediaObject*) self);
++	_tmp6_ = _tmp5_;
++	_tmp7_ = string_index_of_char (_tmp6_, (gunichar) ':', 0);
++	index = _tmp7_;
++	_tmp8_ = rygel_media_object_get_id ((RygelMediaObject*) self);
++	_tmp9_ = _tmp8_;
++	_tmp10_ = index;
++	_tmp11_ = string_slice (_tmp9_, (glong) 0, (glong) _tmp10_);
++	_tmp12_ = _tmp11_;
++	_tmp13_ = g_strconcat (_tmp12_, ":all:", NULL);
++	_g_free0 (self->ref_prefix);
++	self->ref_prefix = _tmp13_;
++	_g_free0 (_tmp12_);
++	{
++		sqlite3_stmt* _tmp14_ = NULL;
++		RygelLMSDatabase* _tmp15_ = NULL;
++		const gchar* _tmp16_ = NULL;
++		sqlite3_stmt* _tmp17_ = NULL;
++		sqlite3_stmt* _tmp18_ = NULL;
++		sqlite3_stmt* _tmp19_ = NULL;
++		RygelLMSDatabase* _tmp20_ = NULL;
++		const gchar* _tmp21_ = NULL;
++		sqlite3_stmt* _tmp22_ = NULL;
++		sqlite3_stmt* _tmp23_ = NULL;
++		sqlite3_stmt* stmt_count = NULL;
++		RygelLMSDatabase* _tmp24_ = NULL;
++		const gchar* _tmp25_ = NULL;
++		sqlite3_stmt* _tmp26_ = NULL;
++		sqlite3_stmt* _tmp27_ = NULL;
++		gint _tmp28_ = 0;
++		gboolean _tmp31_ = FALSE;
++		const gchar* _tmp32_ = NULL;
++		_tmp15_ = self->priv->_lms_db;
++		_tmp16_ = self->priv->_sql_all;
++		_tmp17_ = rygel_lms_database_prepare (_tmp15_, _tmp16_, &_inner_error_);
++		_tmp14_ = _tmp17_;
++		if (G_UNLIKELY (_inner_error_ != NULL)) {
++			if (_inner_error_->domain == RYGEL_LMS_DATABASE_ERROR) {
++				goto __catch7_rygel_lms_database_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_);
++		}
++		_tmp18_ = _tmp14_;
++		_tmp14_ = NULL;
++		_sqlite3_finalize0 (self->stmt_all);
++		self->stmt_all = _tmp18_;
++		_tmp20_ = self->priv->_lms_db;
++		_tmp21_ = self->priv->_sql_find_object;
++		_tmp22_ = rygel_lms_database_prepare (_tmp20_, _tmp21_, &_inner_error_);
++		_tmp19_ = _tmp22_;
++		if (G_UNLIKELY (_inner_error_ != NULL)) {
++			_sqlite3_finalize0 (_tmp14_);
++			if (_inner_error_->domain == RYGEL_LMS_DATABASE_ERROR) {
++				goto __catch7_rygel_lms_database_error;
++			}
++			_sqlite3_finalize0 (_tmp14_);
++			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_);
++		}
++		_tmp23_ = _tmp19_;
++		_tmp19_ = NULL;
++		_sqlite3_finalize0 (self->stmt_find_object);
++		self->stmt_find_object = _tmp23_;
++		_tmp24_ = self->priv->_lms_db;
++		_tmp25_ = self->priv->_sql_count;
++		_tmp26_ = rygel_lms_database_prepare (_tmp24_, _tmp25_, &_inner_error_);
++		stmt_count = _tmp26_;
++		if (G_UNLIKELY (_inner_error_ != NULL)) {
++			_sqlite3_finalize0 (_tmp19_);
++			_sqlite3_finalize0 (_tmp14_);
++			if (_inner_error_->domain == RYGEL_LMS_DATABASE_ERROR) {
++				goto __catch7_rygel_lms_database_error;
++			}
++			_sqlite3_finalize0 (_tmp19_);
++			_sqlite3_finalize0 (_tmp14_);
++			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_);
++		}
++		_tmp27_ = stmt_count;
++		_tmp28_ = sqlite3_step (_tmp27_);
++		if (_tmp28_ == SQLITE_ROW) {
++			sqlite3_stmt* _tmp29_ = NULL;
++			gint _tmp30_ = 0;
++			_tmp29_ = stmt_count;
++			_tmp30_ = sqlite3_column_int (_tmp29_, 0);
++			rygel_media_container_set_child_count ((RygelMediaContainer*) self, _tmp30_);
++		}
++		_tmp32_ = self->priv->_sql_added;
++		if (_tmp32_ != NULL) {
++			const gchar* _tmp33_ = NULL;
++			_tmp33_ = self->priv->_sql_removed;
++			_tmp31_ = _tmp33_ != NULL;
++		} else {
++			_tmp31_ = FALSE;
++		}
++		if (_tmp31_) {
++			sqlite3_stmt* _tmp34_ = NULL;
++			RygelLMSDatabase* _tmp35_ = NULL;
++			const gchar* _tmp36_ = NULL;
++			sqlite3_stmt* _tmp37_ = NULL;
++			sqlite3_stmt* _tmp38_ = NULL;
++			sqlite3_stmt* _tmp39_ = NULL;
++			RygelLMSDatabase* _tmp40_ = NULL;
++			const gchar* _tmp41_ = NULL;
++			sqlite3_stmt* _tmp42_ = NULL;
++			sqlite3_stmt* _tmp43_ = NULL;
++			RygelLMSDatabase* _tmp44_ = NULL;
++			_tmp35_ = self->priv->_lms_db;
++			_tmp36_ = self->priv->_sql_added;
++			_tmp37_ = rygel_lms_database_prepare (_tmp35_, _tmp36_, &_inner_error_);
++			_tmp34_ = _tmp37_;
++			if (G_UNLIKELY (_inner_error_ != NULL)) {
++				_sqlite3_finalize0 (stmt_count);
++				_sqlite3_finalize0 (_tmp19_);
++				_sqlite3_finalize0 (_tmp14_);
++				if (_inner_error_->domain == RYGEL_LMS_DATABASE_ERROR) {
++					goto __catch7_rygel_lms_database_error;
++				}
++				_sqlite3_finalize0 (stmt_count);
++				_sqlite3_finalize0 (_tmp19_);
++				_sqlite3_finalize0 (_tmp14_);
++				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_);
++			}
++			_tmp38_ = _tmp34_;
++			_tmp34_ = NULL;
++			_sqlite3_finalize0 (self->stmt_added);
++			self->stmt_added = _tmp38_;
++			_tmp40_ = self->priv->_lms_db;
++			_tmp41_ = self->priv->_sql_removed;
++			_tmp42_ = rygel_lms_database_prepare (_tmp40_, _tmp41_, &_inner_error_);
++			_tmp39_ = _tmp42_;
++			if (G_UNLIKELY (_inner_error_ != NULL)) {
++				_sqlite3_finalize0 (_tmp34_);
++				_sqlite3_finalize0 (stmt_count);
++				_sqlite3_finalize0 (_tmp19_);
++				_sqlite3_finalize0 (_tmp14_);
++				if (_inner_error_->domain == RYGEL_LMS_DATABASE_ERROR) {
++					goto __catch7_rygel_lms_database_error;
++				}
++				_sqlite3_finalize0 (_tmp34_);
++				_sqlite3_finalize0 (stmt_count);
++				_sqlite3_finalize0 (_tmp19_);
++				_sqlite3_finalize0 (_tmp14_);
++				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_);
++			}
++			_tmp43_ = _tmp39_;
++			_tmp39_ = NULL;
++			_sqlite3_finalize0 (self->stmt_removed);
++			self->stmt_removed = _tmp43_;
++			_tmp44_ = self->priv->_lms_db;
++			g_signal_connect_object (_tmp44_, "db-updated", (GCallback) _rygel_lms_category_container_on_db_updated_rygel_lms_database_db_updated, self, 0);
++			_sqlite3_finalize0 (_tmp39_);
++			_sqlite3_finalize0 (_tmp34_);
++		}
++		_sqlite3_finalize0 (stmt_count);
++		_sqlite3_finalize0 (_tmp19_);
++		_sqlite3_finalize0 (_tmp14_);
++	}
++	goto __finally7;
++	__catch7_rygel_lms_database_error:
++	{
++		GError* e = NULL;
++		const gchar* _tmp45_ = NULL;
++		const gchar* _tmp46_ = NULL;
++		GError* _tmp47_ = NULL;
++		const gchar* _tmp48_ = NULL;
++		e = _inner_error_;
++		_inner_error_ = NULL;
++		_tmp45_ = rygel_media_object_get_title ((RygelMediaObject*) self);
++		_tmp46_ = _tmp45_;
++		_tmp47_ = e;
++		_tmp48_ = _tmp47_->message;
++		g_warning ("rygel-lms-category-container.vala:424: Container %s: %s", _tmp46_, _tmp48_);
++		_g_error_free0 (e);
++	}
++	__finally7:
++	if (G_UNLIKELY (_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 obj;
++}
++
++
++static void rygel_lms_category_container_class_init (RygelLMSCategoryContainerClass * klass) {
++	rygel_lms_category_container_parent_class = g_type_class_peek_parent (klass);
++	g_type_class_add_private (klass, sizeof (RygelLMSCategoryContainerPrivate));
++	((RygelLMSCategoryContainerClass *) klass)->object_from_statement = rygel_lms_category_container_real_object_from_statement;
++	((RygelLMSCategoryContainerClass *) klass)->get_sql_all_with_filter = rygel_lms_category_container_real_get_sql_all_with_filter;
++	((RygelLMSCategoryContainerClass *) klass)->get_sql_count_with_filter = rygel_lms_category_container_real_get_sql_count_with_filter;
++	((RygelLMSCategoryContainerClass *) klass)->get_child_count_with_filter = rygel_lms_category_container_real_get_child_count_with_filter;
++	((RygelLMSCategoryContainerClass *) klass)->get_children_with_filter = rygel_lms_category_container_real_get_children_with_filter;
++	((RygelMediaContainerClass *) klass)->get_children = rygel_lms_category_container_real_get_children;
++	((RygelMediaContainerClass *) klass)->get_children_finish = rygel_lms_category_container_real_get_children_finish;
++	((RygelMediaContainerClass *) klass)->find_object = rygel_lms_category_container_real_find_object;
++	((RygelMediaContainerClass *) klass)->find_object_finish = rygel_lms_category_container_real_find_object_finish;
++	G_OBJECT_CLASS (klass)->get_property = _vala_rygel_lms_category_container_get_property;
++	G_OBJECT_CLASS (klass)->set_property = _vala_rygel_lms_category_container_set_property;
++	G_OBJECT_CLASS (klass)->constructor = rygel_lms_category_container_constructor;
++	G_OBJECT_CLASS (klass)->finalize = rygel_lms_category_container_finalize;
++	g_object_class_install_property (G_OBJECT_CLASS (klass), RYGEL_LMS_CATEGORY_CONTAINER_SEARCH_CLASSES, g_param_spec_object ("search-classes", "search-classes", "search-classes", GEE_TYPE_ARRAY_LIST, G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB | G_PARAM_READABLE | G_PARAM_WRITABLE));
++	g_object_class_install_property (G_OBJECT_CLASS (klass), RYGEL_LMS_CATEGORY_CONTAINER_LMS_DB, rygel_lms_param_spec_database ("lms-db", "lms-db", "lms-db", RYGEL_LMS_TYPE_DATABASE, G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB | G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY));
++	g_object_class_install_property (G_OBJECT_CLASS (klass), RYGEL_LMS_CATEGORY_CONTAINER_DB_ID, g_param_spec_string ("db-id", "db-id", "db-id", NULL, G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB | G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY));
++	g_object_class_install_property (G_OBJECT_CLASS (klass), RYGEL_LMS_CATEGORY_CONTAINER_SQL_ALL, g_param_spec_string ("sql-all", "sql-all", "sql-all", NULL, G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB | G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY));
++	g_object_class_install_property (G_OBJECT_CLASS (klass), RYGEL_LMS_CATEGORY_CONTAINER_SQL_FIND_OBJECT, g_param_spec_string ("sql-find-object", "sql-find-object", "sql-find-object", NULL, G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB | G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY));
++	g_object_class_install_property (G_OBJECT_CLASS (klass), RYGEL_LMS_CATEGORY_CONTAINER_SQL_COUNT, g_param_spec_string ("sql-count", "sql-count", "sql-count", NULL, G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB | G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY));
++	g_object_class_install_property (G_OBJECT_CLASS (klass), RYGEL_LMS_CATEGORY_CONTAINER_SQL_ADDED, g_param_spec_string ("sql-added", "sql-added", "sql-added", NULL, G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB | G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY));
++	g_object_class_install_property (G_OBJECT_CLASS (klass), RYGEL_LMS_CATEGORY_CONTAINER_SQL_REMOVED, g_param_spec_string ("sql-removed", "sql-removed", "sql-removed", NULL, G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB | G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY));
++}
++
++
++static void rygel_lms_category_container_rygel_trackable_container_interface_init (RygelTrackableContainerIface * iface) {
++	rygel_lms_category_container_rygel_trackable_container_parent_iface = g_type_interface_peek_parent (iface);
++	iface->add_child = (void (*)(RygelTrackableContainer*, RygelMediaObject*)) rygel_lms_category_container_real_add_child;
++	iface->add_child_finish = rygel_lms_category_container_real_add_child_finish;
++	iface->remove_child = (void (*)(RygelTrackableContainer*, RygelMediaObject*)) rygel_lms_category_container_real_remove_child;
++	iface->remove_child_finish = rygel_lms_category_container_real_remove_child_finish;
++}
++
++
++static void rygel_lms_category_container_rygel_searchable_container_interface_init (RygelSearchableContainerIface * iface) {
++	rygel_lms_category_container_rygel_searchable_container_parent_iface = g_type_interface_peek_parent (iface);
++	iface->search = (RygelMediaObjects* (*)(RygelSearchableContainer*, RygelSearchExpression*, guint, guint, guint*, const gchar*, GCancellable*, GError**)) rygel_lms_category_container_real_search;
++	iface->search_finish = rygel_lms_category_container_real_search_finish;
++	iface->get_search_classes = rygel_lms_category_container_real_get_search_classes;
++	iface->set_search_classes = rygel_lms_category_container_real_set_search_classes;
++}
++
++
++static void rygel_lms_category_container_instance_init (RygelLMSCategoryContainer * self) {
++	self->priv = RYGEL_LMS_CATEGORY_CONTAINER_GET_PRIVATE (self);
++}
++
++
++static void rygel_lms_category_container_finalize (GObject* obj) {
++	RygelLMSCategoryContainer * self;
++	self = G_TYPE_CHECK_INSTANCE_CAST (obj, RYGEL_LMS_TYPE_CATEGORY_CONTAINER, RygelLMSCategoryContainer);
++	_g_object_unref0 (self->priv->_search_classes);
++	_g_free0 (self->priv->_db_id);
++	_g_free0 (self->priv->_sql_all);
++	_g_free0 (self->priv->_sql_find_object);
++	_g_free0 (self->priv->_sql_count);
++	_g_free0 (self->priv->_sql_added);
++	_g_free0 (self->priv->_sql_removed);
++	_sqlite3_finalize0 (self->stmt_all);
++	_sqlite3_finalize0 (self->stmt_find_object);
++	_sqlite3_finalize0 (self->stmt_added);
++	_sqlite3_finalize0 (self->stmt_removed);
++	_g_free0 (self->child_prefix);
++	_g_free0 (self->ref_prefix);
++	G_OBJECT_CLASS (rygel_lms_category_container_parent_class)->finalize (obj);
++}
++
++
++GType rygel_lms_category_container_get_type (void) {
++	static volatile gsize rygel_lms_category_container_type_id__volatile = 0;
++	if (g_once_init_enter (&rygel_lms_category_container_type_id__volatile)) {
++		static const GTypeInfo g_define_type_info = { sizeof (RygelLMSCategoryContainerClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) rygel_lms_category_container_class_init, (GClassFinalizeFunc) NULL, NULL, sizeof (RygelLMSCategoryContainer), 0, (GInstanceInitFunc) rygel_lms_category_container_instance_init, NULL };
++		static const GInterfaceInfo rygel_trackable_container_info = { (GInterfaceInitFunc) rygel_lms_category_container_rygel_trackable_container_interface_init, (GInterfaceFinalizeFunc) NULL, NULL};
++		static const GInterfaceInfo rygel_searchable_container_info = { (GInterfaceInitFunc) rygel_lms_category_container_rygel_searchable_container_interface_init, (GInterfaceFinalizeFunc) NULL, NULL};
++		GType rygel_lms_category_container_type_id;
++		rygel_lms_category_container_type_id = g_type_register_static (RYGEL_TYPE_MEDIA_CONTAINER, "RygelLMSCategoryContainer", &g_define_type_info, G_TYPE_FLAG_ABSTRACT);
++		g_type_add_interface_static (rygel_lms_category_container_type_id, RYGEL_TYPE_TRACKABLE_CONTAINER, &rygel_trackable_container_info);
++		g_type_add_interface_static (rygel_lms_category_container_type_id, RYGEL_TYPE_SEARCHABLE_CONTAINER, &rygel_searchable_container_info);
++		g_once_init_leave (&rygel_lms_category_container_type_id__volatile, rygel_lms_category_container_type_id);
++	}
++	return rygel_lms_category_container_type_id__volatile;
++}
++
++
++static void _vala_rygel_lms_category_container_get_property (GObject * object, guint property_id, GValue * value, GParamSpec * pspec) {
++	RygelLMSCategoryContainer * self;
++	self = G_TYPE_CHECK_INSTANCE_CAST (object, RYGEL_LMS_TYPE_CATEGORY_CONTAINER, RygelLMSCategoryContainer);
++	switch (property_id) {
++		case RYGEL_LMS_CATEGORY_CONTAINER_SEARCH_CLASSES:
++		g_value_set_object (value, rygel_searchable_container_get_search_classes ((RygelSearchableContainer*) self));
++		break;
++		case RYGEL_LMS_CATEGORY_CONTAINER_LMS_DB:
++		rygel_lms_value_set_database (value, rygel_lms_category_container_get_lms_db (self));
++		break;
++		case RYGEL_LMS_CATEGORY_CONTAINER_DB_ID:
++		g_value_set_string (value, rygel_lms_category_container_get_db_id (self));
++		break;
++		case RYGEL_LMS_CATEGORY_CONTAINER_SQL_ALL:
++		g_value_set_string (value, rygel_lms_category_container_get_sql_all (self));
++		break;
++		case RYGEL_LMS_CATEGORY_CONTAINER_SQL_FIND_OBJECT:
++		g_value_set_string (value, rygel_lms_category_container_get_sql_find_object (self));
++		break;
++		case RYGEL_LMS_CATEGORY_CONTAINER_SQL_COUNT:
++		g_value_set_string (value, rygel_lms_category_container_get_sql_count (self));
++		break;
++		case RYGEL_LMS_CATEGORY_CONTAINER_SQL_ADDED:
++		g_value_set_string (value, rygel_lms_category_container_get_sql_added (self));
++		break;
++		case RYGEL_LMS_CATEGORY_CONTAINER_SQL_REMOVED:
++		g_value_set_string (value, rygel_lms_category_container_get_sql_removed (self));
++		break;
++		default:
++		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
++		break;
++	}
++}
++
++
++static void _vala_rygel_lms_category_container_set_property (GObject * object, guint property_id, const GValue * value, GParamSpec * pspec) {
++	RygelLMSCategoryContainer * self;
++	self = G_TYPE_CHECK_INSTANCE_CAST (object, RYGEL_LMS_TYPE_CATEGORY_CONTAINER, RygelLMSCategoryContainer);
++	switch (property_id) {
++		case RYGEL_LMS_CATEGORY_CONTAINER_SEARCH_CLASSES:
++		rygel_searchable_container_set_search_classes ((RygelSearchableContainer*) self, g_value_get_object (value));
++		break;
++		case RYGEL_LMS_CATEGORY_CONTAINER_LMS_DB:
++		rygel_lms_category_container_set_lms_db (self, rygel_lms_value_get_database (value));
++		break;
++		case RYGEL_LMS_CATEGORY_CONTAINER_DB_ID:
++		rygel_lms_category_container_set_db_id (self, g_value_get_string (value));
++		break;
++		case RYGEL_LMS_CATEGORY_CONTAINER_SQL_ALL:
++		rygel_lms_category_container_set_sql_all (self, g_value_get_string (value));
++		break;
++		case RYGEL_LMS_CATEGORY_CONTAINER_SQL_FIND_OBJECT:
++		rygel_lms_category_container_set_sql_find_object (self, g_value_get_string (value));
++		break;
++		case RYGEL_LMS_CATEGORY_CONTAINER_SQL_COUNT:
++		rygel_lms_category_container_set_sql_count (self, g_value_get_string (value));
++		break;
++		case RYGEL_LMS_CATEGORY_CONTAINER_SQL_ADDED:
++		rygel_lms_category_container_set_sql_added (self, g_value_get_string (value));
++		break;
++		case RYGEL_LMS_CATEGORY_CONTAINER_SQL_REMOVED:
++		rygel_lms_category_container_set_sql_removed (self, g_value_get_string (value));
++		break;
++		default:
++		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
++		break;
++	}
++}
++
++
++
+diff --git a/src/plugins/lms/rygel-lms-database.c b/src/plugins/lms/rygel-lms-database.c
+new file mode 100644
+index 0000000..687ef64
+--- /dev/null
++++ b/src/plugins/lms/rygel-lms-database.c
+@@ -0,0 +1,1349 @@
++/* rygel-lms-database.c generated by valac 0.28.0, the Vala compiler
++ * generated from rygel-lms-database.vala, do not modify */
++
++/*
++ * Copyright (C) 2009,2011 Jens Georg <mail@jensge.org>,
++ *           (C) 2013 Intel Corporation.
++ *
++ * Author: Jussi Kukkonen <jussi.kukkonen@intel.com>
++ *
++ * 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 <glib.h>
++#include <glib-object.h>
++#include <sqlite3.h>
++#include <gio/gio.h>
++#include <stdlib.h>
++#include <string.h>
++#include <glib/gi18n-lib.h>
++#include <gobject/gvaluecollector.h>
++
++
++#define RYGEL_LMS_TYPE_DATABASE (rygel_lms_database_get_type ())
++#define RYGEL_LMS_DATABASE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), RYGEL_LMS_TYPE_DATABASE, RygelLMSDatabase))
++#define RYGEL_LMS_DATABASE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), RYGEL_LMS_TYPE_DATABASE, RygelLMSDatabaseClass))
++#define RYGEL_LMS_IS_DATABASE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), RYGEL_LMS_TYPE_DATABASE))
++#define RYGEL_LMS_IS_DATABASE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), RYGEL_LMS_TYPE_DATABASE))
++#define RYGEL_LMS_DATABASE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), RYGEL_LMS_TYPE_DATABASE, RygelLMSDatabaseClass))
++
++typedef struct _RygelLMSDatabase RygelLMSDatabase;
++typedef struct _RygelLMSDatabaseClass RygelLMSDatabaseClass;
++typedef struct _RygelLMSDatabasePrivate RygelLMSDatabasePrivate;
++
++#define RYGEL_LMS_TYPE_DBUS (rygel_lms_dbus_get_type ())
++#define RYGEL_LMS_DBUS(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), RYGEL_LMS_TYPE_DBUS, RygelLMSDBus))
++#define RYGEL_LMS_IS_DBUS(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), RYGEL_LMS_TYPE_DBUS))
++#define RYGEL_LMS_DBUS_GET_INTERFACE(obj) (G_TYPE_INSTANCE_GET_INTERFACE ((obj), RYGEL_LMS_TYPE_DBUS, RygelLMSDBusIface))
++
++typedef struct _RygelLMSDBus RygelLMSDBus;
++typedef struct _RygelLMSDBusIface RygelLMSDBusIface;
++
++#define RYGEL_LMS_TYPE_DBUS_PROXY (rygel_lms_dbus_proxy_get_type ())
++#define _sqlite3_close0(var) ((var == NULL) ? NULL : (var = (sqlite3_close (var), NULL)))
++#define _g_object_unref0(var) ((var == NULL) ? NULL : (var = (g_object_unref (var), NULL)))
++#define _g_free0(var) (var = (g_free (var), NULL))
++#define _g_error_free0(var) ((var == NULL) ? NULL : (var = (g_error_free (var), NULL)))
++#define _rygel_lms_database_unref0(var) ((var == NULL) ? NULL : (var = (rygel_lms_database_unref (var), NULL)))
++#define _g_variant_unref0(var) ((var == NULL) ? NULL : (var = (g_variant_unref (var), NULL)))
++#define _g_variant_iter_free0(var) ((var == NULL) ? NULL : (var = (g_variant_iter_free (var), NULL)))
++#define _sqlite3_finalize0(var) ((var == NULL) ? NULL : (var = (sqlite3_finalize (var), NULL)))
++typedef struct _RygelLMSParamSpecDatabase RygelLMSParamSpecDatabase;
++#define _vala_assert(expr, msg) if G_LIKELY (expr) ; else g_assertion_message_expr (G_LOG_DOMAIN, __FILE__, __LINE__, G_STRFUNC, msg);
++#define _vala_return_if_fail(expr, msg) if G_LIKELY (expr) ; else { g_return_if_fail_warning (G_LOG_DOMAIN, G_STRFUNC, msg); return; }
++#define _vala_return_val_if_fail(expr, msg, val) if G_LIKELY (expr) ; else { g_return_if_fail_warning (G_LOG_DOMAIN, G_STRFUNC, msg); return val; }
++#define _vala_warn_if_fail(expr, msg) if G_LIKELY (expr) ; else g_warn_message (G_LOG_DOMAIN, __FILE__, __LINE__, G_STRFUNC, msg);
++
++typedef enum  {
++	RYGEL_LMS_DATABASE_ERROR_OPEN,
++	RYGEL_LMS_DATABASE_ERROR_PREPARE,
++	RYGEL_LMS_DATABASE_ERROR_BIND,
++	RYGEL_LMS_DATABASE_ERROR_STEP,
++	RYGEL_LMS_DATABASE_ERROR_NOT_FOUND
++} RygelLMSDatabaseError;
++#define RYGEL_LMS_DATABASE_ERROR rygel_lms_database_error_quark ()
++struct _RygelLMSDatabase {
++	GTypeInstance parent_instance;
++	volatile int ref_count;
++	RygelLMSDatabasePrivate * priv;
++};
++
++struct _RygelLMSDatabaseClass {
++	GTypeClass parent_class;
++	void (*finalize) (RygelLMSDatabase *self);
++};
++
++struct _RygelLMSDBusIface {
++	GTypeInterface parent_iface;
++	gchar* (*get_data_base_path) (RygelLMSDBus* self);
++	guint64 (*get_update_id) (RygelLMSDBus* self);
++};
++
++struct _RygelLMSDatabasePrivate {
++	sqlite3* db;
++	RygelLMSDBus* lms_proxy;
++	guint64 update_id;
++};
++
++struct _RygelLMSParamSpecDatabase {
++	GParamSpec parent_instance;
++};
++
++
++static gpointer rygel_lms_database_parent_class = NULL;
++
++GQuark rygel_lms_database_error_quark (void);
++gint rygel_lms_utf8_collate_str (guint8* a, int a_length1, guint8* b, int b_length1);
++gpointer rygel_lms_database_ref (gpointer instance);
++void rygel_lms_database_unref (gpointer instance);
++GParamSpec* rygel_lms_param_spec_database (const gchar* name, const gchar* nick, const gchar* blurb, GType object_type, GParamFlags flags);
++void rygel_lms_value_set_database (GValue* value, gpointer v_object);
++void rygel_lms_value_take_database (GValue* value, gpointer v_object);
++gpointer rygel_lms_value_get_database (const GValue* value);
++GType rygel_lms_database_get_type (void) G_GNUC_CONST;
++GType rygel_lms_dbus_get_type (void) G_GNUC_CONST;
++GType rygel_lms_dbus_proxy_get_type (void) G_GNUC_CONST;
++guint rygel_lms_dbus_register_object (void* object, GDBusConnection* connection, const gchar* path, GError** error);
++#define RYGEL_LMS_DATABASE_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), RYGEL_LMS_TYPE_DATABASE, RygelLMSDatabasePrivate))
++enum  {
++	RYGEL_LMS_DATABASE_DUMMY_PROPERTY
++};
++static void rygel_lms_database_utf8_contains (sqlite3_context* context, sqlite3_value** args, int args_length1);
++static gint rygel_lms_database_utf8_collate (gint alen, void* a, gint blen, void* b);
++RygelLMSDatabase* rygel_lms_database_new (GError** error);
++RygelLMSDatabase* rygel_lms_database_construct (GType object_type, GError** error);
++gchar* rygel_lms_dbus_get_data_base_path (RygelLMSDBus* self);
++guint64 rygel_lms_dbus_get_update_id (RygelLMSDBus* self);
++static void rygel_lms_database_on_lms_properties_changed (RygelLMSDatabase* self, GDBusProxy* lms_proxy, GVariant* changed, gchar** invalidated, int invalidated_length1);
++static void _rygel_lms_database_on_lms_properties_changed_g_dbus_proxy_g_properties_changed (GDBusProxy* _sender, GVariant* changed_properties, gchar** invalidated_properties, gpointer self);
++static void _rygel_lms_database_utf8_contains_sqlite_user_func_callback (sqlite3_context* context, int values_length1, sqlite3_value** values);
++static gint _rygel_lms_database_utf8_collate_sqlite_compare_callback (gpointer self, gint alen, void* a, gint blen, void* b);
++static gchar* _variant_get1 (GVariant* value);
++static guint64 _variant_get2 (GVariant* value);
++static guint64 _variant_get3 (GVariant* value);
++sqlite3_stmt* rygel_lms_database_prepare (RygelLMSDatabase* self, const gchar* query_string, GError** error);
++sqlite3_stmt* rygel_lms_database_prepare_and_init (RygelLMSDatabase* self, const gchar* query, GValue* arguments, int arguments_length1, GError** error);
++void rygel_lms_database_find_object (const gchar* id, sqlite3_stmt* stmt, GError** error);
++void rygel_lms_database_get_children_init (sqlite3_stmt* stmt, guint offset, guint max_count, const gchar* sort_criteria, GError** error);
++void rygel_lms_database_get_children_with_update_id_init (sqlite3_stmt* stmt, guint64 old_id, guint64 new_id, GError** error);
++gboolean rygel_lms_database_get_children_step (sqlite3_stmt* stmt, GError** error);
++static void g_cclosure_user_marshal_VOID__UINT64_UINT64 (GClosure * closure, GValue * return_value, guint n_param_values, const GValue * param_values, gpointer invocation_hint, gpointer marshal_data);
++static void rygel_lms_database_finalize (RygelLMSDatabase* obj);
++static gint _vala_array_length (gpointer array);
++
++
++GQuark rygel_lms_database_error_quark (void) {
++	return g_quark_from_static_string ("rygel_lms_database_error-quark");
++}
++
++
++/**
++     * Function to implement the custom SQL function 'contains'
++     */
++static void rygel_lms_database_utf8_contains (sqlite3_context* context, sqlite3_value** args, int args_length1) {
++	sqlite3_value** _tmp0_ = NULL;
++	gint _tmp0__length1 = 0;
++	gboolean _tmp1_ = FALSE;
++	sqlite3_value** _tmp2_ = NULL;
++	gint _tmp2__length1 = 0;
++	sqlite3_value* _tmp3_ = NULL;
++	const gchar* _tmp4_ = NULL;
++	gchar* pattern = NULL;
++	sqlite3_value** _tmp9_ = NULL;
++	gint _tmp9__length1 = 0;
++	sqlite3_value* _tmp10_ = NULL;
++	const gchar* _tmp11_ = NULL;
++	gchar* _tmp12_ = NULL;
++	const gchar* _tmp13_ = NULL;
++	sqlite3_value** _tmp14_ = NULL;
++	gint _tmp14__length1 = 0;
++	sqlite3_value* _tmp15_ = NULL;
++	const gchar* _tmp16_ = NULL;
++	gboolean _tmp17_ = FALSE;
++	g_return_if_fail (context != NULL);
++	_tmp0_ = args;
++	_tmp0__length1 = args_length1;
++	_vala_return_if_fail (_tmp0__length1 == 2, "args.length == 2");
++	_tmp2_ = args;
++	_tmp2__length1 = args_length1;
++	_tmp3_ = _tmp2_[0];
++	_tmp4_ = sqlite3_value_text (_tmp3_);
++	if (_tmp4_ == NULL) {
++		_tmp1_ = TRUE;
++	} else {
++		sqlite3_value** _tmp5_ = NULL;
++		gint _tmp5__length1 = 0;
++		sqlite3_value* _tmp6_ = NULL;
++		const gchar* _tmp7_ = NULL;
++		_tmp5_ = args;
++		_tmp5__length1 = args_length1;
++		_tmp6_ = _tmp5_[1];
++		_tmp7_ = sqlite3_value_text (_tmp6_);
++		_tmp1_ = _tmp7_ == NULL;
++	}
++	if (_tmp1_) {
++		sqlite3_context* _tmp8_ = NULL;
++		_tmp8_ = context;
++		sqlite3_result_int (_tmp8_, 0);
++		return;
++	}
++	_tmp9_ = args;
++	_tmp9__length1 = args_length1;
++	_tmp10_ = _tmp9_[1];
++	_tmp11_ = sqlite3_value_text (_tmp10_);
++	_tmp12_ = g_regex_escape_string (_tmp11_, -1);
++	pattern = _tmp12_;
++	_tmp13_ = pattern;
++	_tmp14_ = args;
++	_tmp14__length1 = args_length1;
++	_tmp15_ = _tmp14_[0];
++	_tmp16_ = sqlite3_value_text (_tmp15_);
++	_tmp17_ = g_regex_match_simple (_tmp13_, _tmp16_, G_REGEX_CASELESS, 0);
++	if (_tmp17_) {
++		sqlite3_context* _tmp18_ = NULL;
++		_tmp18_ = context;
++		sqlite3_result_int (_tmp18_, 1);
++	} else {
++		sqlite3_context* _tmp19_ = NULL;
++		_tmp19_ = context;
++		sqlite3_result_int (_tmp19_, 0);
++	}
++	_g_free0 (pattern);
++}
++
++
++/**
++     * Function to implement the custom SQLite collation 'CASEFOLD'.
++     *
++     * Uses utf8 case-fold to compare the strings.
++     */
++static gint rygel_lms_database_utf8_collate (gint alen, void* a, gint blen, void* b) {
++	gint result = 0;
++	guint8* _a = NULL;
++	void* _tmp0_ = NULL;
++	gint _a_length1 = 0;
++	gint __a_size_ = 0;
++	gint _tmp1_ = 0;
++	gint _tmp2_ = 0;
++	guint8* _b = NULL;
++	void* _tmp3_ = NULL;
++	gint _b_length1 = 0;
++	gint __b_size_ = 0;
++	gint _tmp4_ = 0;
++	gint _tmp5_ = 0;
++	gint _tmp6_ = 0;
++	_tmp0_ = a;
++	_a = (guint8*) _tmp0_;
++	_a_length1 = -1;
++	__a_size_ = _a_length1;
++	_tmp1_ = alen;
++	_a_length1 = _tmp1_;
++	_tmp2_ = _a_length1;
++	_tmp3_ = b;
++	_b = (guint8*) _tmp3_;
++	_b_length1 = -1;
++	__b_size_ = _b_length1;
++	_tmp4_ = blen;
++	_b_length1 = _tmp4_;
++	_tmp5_ = _b_length1;
++	_tmp6_ = rygel_lms_utf8_collate_str (_a, _a_length1, _b, _b_length1);
++	result = _tmp6_;
++	return result;
++}
++
++
++static void _rygel_lms_database_on_lms_properties_changed_g_dbus_proxy_g_properties_changed (GDBusProxy* _sender, GVariant* changed_properties, gchar** invalidated_properties, gpointer self) {
++	rygel_lms_database_on_lms_properties_changed ((RygelLMSDatabase*) self, _sender, changed_properties, invalidated_properties, _vala_array_length (invalidated_properties));
++}
++
++
++static void _rygel_lms_database_utf8_contains_sqlite_user_func_callback (sqlite3_context* context, int values_length1, sqlite3_value** values) {
++	rygel_lms_database_utf8_contains (context, values, values_length1);
++}
++
++
++static gint _rygel_lms_database_utf8_collate_sqlite_compare_callback (gpointer self, gint alen, void* a, gint blen, void* b) {
++	gint result;
++	result = rygel_lms_database_utf8_collate (alen, a, blen, b);
++	return result;
++}
++
++
++RygelLMSDatabase* rygel_lms_database_construct (GType object_type, GError** error) {
++	RygelLMSDatabase* self = NULL;
++	gchar* db_path = NULL;
++	const gchar* _tmp17_ = NULL;
++	sqlite3* _tmp18_ = NULL;
++	sqlite3* _tmp19_ = NULL;
++	gint _tmp20_ = 0;
++	sqlite3* _tmp25_ = NULL;
++	sqlite3* _tmp26_ = NULL;
++	GError * _inner_error_ = NULL;
++	self = (RygelLMSDatabase*) g_type_create_instance (object_type);
++	{
++		RygelLMSDBus* _tmp0_ = NULL;
++		RygelLMSDBus* _tmp1_ = NULL;
++		RygelLMSDBus* _tmp2_ = NULL;
++		RygelLMSDBus* _tmp3_ = NULL;
++		gchar* _tmp4_ = NULL;
++		gchar* _tmp5_ = NULL;
++		const gchar* _tmp6_ = NULL;
++		RygelLMSDBus* _tmp7_ = NULL;
++		guint64 _tmp8_ = 0ULL;
++		guint64 _tmp9_ = 0ULL;
++		guint64 _tmp10_ = 0ULL;
++		RygelLMSDBus* _tmp11_ = NULL;
++		_tmp1_ = g_initable_new (RYGEL_LMS_TYPE_DBUS_PROXY, NULL, &_inner_error_, "g-flags", 0, "g-name", "org.lightmediascanner", "g-bus-type", G_BUS_TYPE_SESSION, "g-object-path", "/org/lightmediascanner/Scanner1", "g-interface-name", "org.lightmediascanner.Scanner1", "g-interface-info", g_type_get_qdata (RYGEL_LMS_TYPE_DBUS, g_quark_from_static_string ("vala-dbus-interface-info")), NULL);
++		_tmp0_ = (RygelLMSDBus*) _tmp1_;
++		if (G_UNLIKELY (_inner_error_ != NULL)) {
++			if (_inner_error_->domain == G_IO_ERROR) {
++				goto __catch11_g_io_error;
++			}
++			_g_free0 (db_path);
++			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;
++		}
++		_tmp2_ = _tmp0_;
++		_tmp0_ = NULL;
++		_g_object_unref0 (self->priv->lms_proxy);
++		self->priv->lms_proxy = _tmp2_;
++		_tmp3_ = self->priv->lms_proxy;
++		_tmp4_ = rygel_lms_dbus_get_data_base_path (_tmp3_);
++		_tmp5_ = _tmp4_;
++		_g_free0 (db_path);
++		db_path = _tmp5_;
++		_tmp6_ = db_path;
++		g_debug ("rygel-lms-database.vala:94: Got db path %s from LMS over dbus", _tmp6_);
++		_tmp7_ = self->priv->lms_proxy;
++		_tmp8_ = rygel_lms_dbus_get_update_id (_tmp7_);
++		_tmp9_ = _tmp8_;
++		self->priv->update_id = _tmp9_;
++		_tmp10_ = self->priv->update_id;
++		g_debug ("rygel-lms-database.vala:96: Got updated id %lld from LMS over dbus", _tmp10_);
++		_tmp11_ = self->priv->lms_proxy;
++		g_signal_connect ((GDBusProxy*) _tmp11_, "g-properties-changed", (GCallback) _rygel_lms_database_on_lms_properties_changed_g_dbus_proxy_g_properties_changed, self);
++		_g_object_unref0 (_tmp0_);
++	}
++	goto __finally11;
++	__catch11_g_io_error:
++	{
++		GError* e = NULL;
++		GError* _tmp12_ = NULL;
++		const gchar* _tmp13_ = NULL;
++		const gchar* _tmp14_ = NULL;
++		gchar* _tmp15_ = NULL;
++		const gchar* _tmp16_ = NULL;
++		e = _inner_error_;
++		_inner_error_ = NULL;
++		_tmp12_ = e;
++		_tmp13_ = _tmp12_->message;
++		g_warning ("rygel-lms-database.vala:100: Couldn't get LMS Dbus proxy: %s", _tmp13_);
++		_tmp14_ = g_get_user_config_dir ();
++		_tmp15_ = g_strconcat (_tmp14_, "/lightmediascannerd/db.sqlite3", NULL);
++		_g_free0 (db_path);
++		db_path = _tmp15_;
++		_tmp16_ = db_path;
++		g_debug ("rygel-lms-database.vala:103: Using default sqlite database location %s", _tmp16_);
++		_g_error_free0 (e);
++	}
++	__finally11:
++	if (G_UNLIKELY (_inner_error_ != NULL)) {
++		if (_inner_error_->domain == RYGEL_LMS_DATABASE_ERROR) {
++			g_propagate_error (error, _inner_error_);
++			_g_free0 (db_path);
++			_rygel_lms_database_unref0 (self);
++			return NULL;
++		} else {
++			_g_free0 (db_path);
++			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;
++		}
++	}
++	_tmp17_ = db_path;
++	sqlite3_open (_tmp17_, &_tmp18_);
++	_sqlite3_close0 (self->priv->db);
++	self->priv->db = _tmp18_;
++	_tmp19_ = self->priv->db;
++	_tmp20_ = sqlite3_errcode (_tmp19_);
++	if (_tmp20_ != SQLITE_OK) {
++		const gchar* _tmp21_ = NULL;
++		sqlite3* _tmp22_ = NULL;
++		gint _tmp23_ = 0;
++		GError* _tmp24_ = NULL;
++		_tmp21_ = db_path;
++		_tmp22_ = self->priv->db;
++		_tmp23_ = sqlite3_errcode (_tmp22_);
++		_tmp24_ = g_error_new (RYGEL_LMS_DATABASE_ERROR, RYGEL_LMS_DATABASE_ERROR_OPEN, "Failed to open '%s': %d", _tmp21_, _tmp23_);
++		_inner_error_ = _tmp24_;
++		if (_inner_error_->domain == RYGEL_LMS_DATABASE_ERROR) {
++			g_propagate_error (error, _inner_error_);
++			_g_free0 (db_path);
++			_rygel_lms_database_unref0 (self);
++			return NULL;
++		} else {
++			_g_free0 (db_path);
++			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;
++		}
++	}
++	_tmp25_ = self->priv->db;
++	sqlite3_create_function (_tmp25_, "contains", 2, SQLITE_UTF8, NULL, _rygel_lms_database_utf8_contains_sqlite_user_func_callback, NULL, NULL);
++	_tmp26_ = self->priv->db;
++	sqlite3_create_collation (_tmp26_, "CASEFOLD", SQLITE_UTF8, NULL, (int (*)(void *, int,  const void *, int,  const void *)) _rygel_lms_database_utf8_collate_sqlite_compare_callback);
++	_g_free0 (db_path);
++	return self;
++}
++
++
++RygelLMSDatabase* rygel_lms_database_new (GError** error) {
++	return rygel_lms_database_construct (RYGEL_LMS_TYPE_DATABASE, error);
++}
++
++
++static gchar* _variant_get1 (GVariant* value) {
++	return g_variant_dup_string (value, NULL);
++}
++
++
++static guint64 _variant_get2 (GVariant* value) {
++	return g_variant_get_uint64 (value);
++}
++
++
++static guint64 _variant_get3 (GVariant* value) {
++	return g_variant_get_uint64 (value);
++}
++
++
++static void rygel_lms_database_on_lms_properties_changed (RygelLMSDatabase* self, GDBusProxy* lms_proxy, GVariant* changed, gchar** invalidated, int invalidated_length1) {
++	GVariant* _tmp0_ = NULL;
++	const GVariantType* _tmp1_ = NULL;
++	const GVariantType* _tmp2_ = NULL;
++	gboolean _tmp3_ = FALSE;
++	g_return_if_fail (self != NULL);
++	g_return_if_fail (lms_proxy != NULL);
++	g_return_if_fail (changed != NULL);
++	_tmp0_ = changed;
++	_tmp1_ = g_variant_get_type (_tmp0_);
++	_tmp2_ = G_VARIANT_TYPE_VARDICT;
++	_tmp3_ = g_variant_type_equal (_tmp1_, _tmp2_);
++	if (!_tmp3_) {
++		return;
++	}
++	{
++		GVariantIter* _changed_prop_it = NULL;
++		GVariant* _tmp4_ = NULL;
++		GVariantIter* _tmp5_ = NULL;
++		GVariant* changed_prop = NULL;
++		_tmp4_ = changed;
++		_tmp5_ = g_variant_iter_new (_tmp4_);
++		_changed_prop_it = _tmp5_;
++		while (TRUE) {
++			GVariantIter* _tmp6_ = NULL;
++			GVariant* _tmp7_ = NULL;
++			GVariant* _tmp8_ = NULL;
++			gchar* key = NULL;
++			GVariant* _tmp9_ = NULL;
++			GVariant* _tmp10_ = NULL;
++			GVariant* _tmp11_ = NULL;
++			gchar* _tmp12_ = NULL;
++			gchar* _tmp13_ = NULL;
++			GVariant* value = NULL;
++			GVariant* _tmp14_ = NULL;
++			GVariant* _tmp15_ = NULL;
++			GVariant* _tmp16_ = NULL;
++			GVariant* _tmp17_ = NULL;
++			GVariant* _tmp18_ = NULL;
++			const gchar* _tmp19_ = NULL;
++			GVariant* _tmp20_ = NULL;
++			gchar* _tmp21_ = NULL;
++			gchar* _tmp22_ = NULL;
++			const gchar* _tmp23_ = NULL;
++			const gchar* _tmp24_ = NULL;
++			GQuark _tmp26_ = 0U;
++			static GQuark _tmp25_label0 = 0;
++			_tmp6_ = _changed_prop_it;
++			_tmp7_ = g_variant_iter_next_value (_tmp6_);
++			_g_variant_unref0 (changed_prop);
++			changed_prop = _tmp7_;
++			_tmp8_ = changed_prop;
++			if (!(_tmp8_ != NULL)) {
++				break;
++			}
++			_tmp9_ = changed_prop;
++			_tmp10_ = g_variant_get_child_value (_tmp9_, (gsize) 0);
++			_tmp11_ = _tmp10_;
++			_tmp12_ = _variant_get1 (_tmp11_);
++			_tmp13_ = _tmp12_;
++			_g_variant_unref0 (_tmp11_);
++			key = _tmp13_;
++			_tmp14_ = changed_prop;
++			_tmp15_ = g_variant_get_child_value (_tmp14_, (gsize) 1);
++			_tmp16_ = _tmp15_;
++			_tmp17_ = g_variant_get_child_value (_tmp16_, (gsize) 0);
++			_tmp18_ = _tmp17_;
++			_g_variant_unref0 (_tmp16_);
++			value = _tmp18_;
++			_tmp19_ = key;
++			_tmp20_ = value;
++			_tmp21_ = g_variant_print (_tmp20_, TRUE);
++			_tmp22_ = _tmp21_;
++			g_debug ("rygel-lms-database.vala:138: LMS property %s changed value to %s", _tmp19_, _tmp22_);
++			_g_free0 (_tmp22_);
++			_tmp23_ = key;
++			_tmp24_ = _tmp23_;
++			_tmp26_ = (NULL == _tmp24_) ? 0 : g_quark_from_string (_tmp24_);
++			if (_tmp26_ == ((0 != _tmp25_label0) ? _tmp25_label0 : (_tmp25_label0 = g_quark_from_static_string ("UpdateID")))) {
++				switch (0) {
++					default:
++					{
++						guint64 _tmp27_ = 0ULL;
++						GVariant* _tmp28_ = NULL;
++						guint64 _tmp29_ = 0ULL;
++						GVariant* _tmp30_ = NULL;
++						guint64 _tmp31_ = 0ULL;
++						_tmp27_ = self->priv->update_id;
++						_tmp28_ = value;
++						_tmp29_ = _variant_get2 (_tmp28_);
++						g_signal_emit_by_name (self, "db-updated", _tmp27_, _tmp29_);
++						_tmp30_ = value;
++						_tmp31_ = _variant_get3 (_tmp30_);
++						self->priv->update_id = _tmp31_;
++						break;
++					}
++				}
++			}
++			_g_variant_unref0 (value);
++			_g_free0 (key);
++		}
++		_g_variant_unref0 (changed_prop);
++		_g_variant_iter_free0 (_changed_prop_it);
++	}
++}
++
++
++sqlite3_stmt* rygel_lms_database_prepare (RygelLMSDatabase* self, const gchar* query_string, GError** error) {
++	sqlite3_stmt* result = NULL;
++	sqlite3_stmt* statement = NULL;
++	gint err = 0;
++	sqlite3* _tmp0_ = NULL;
++	const gchar* _tmp1_ = NULL;
++	sqlite3_stmt* _tmp2_ = NULL;
++	gint _tmp3_ = 0;
++	gint _tmp4_ = 0;
++	GError * _inner_error_ = NULL;
++	g_return_val_if_fail (self != NULL, NULL);
++	g_return_val_if_fail (query_string != NULL, NULL);
++	_tmp0_ = self->priv->db;
++	_tmp1_ = query_string;
++	_tmp3_ = sqlite3_prepare_v2 (_tmp0_, _tmp1_, -1, &_tmp2_, NULL);
++	_sqlite3_finalize0 (statement);
++	statement = _tmp2_;
++	err = _tmp3_;
++	_tmp4_ = err;
++	if (_tmp4_ != SQLITE_OK) {
++		const gchar* _tmp5_ = NULL;
++		gint _tmp6_ = 0;
++		GError* _tmp7_ = NULL;
++		_tmp5_ = query_string;
++		_tmp6_ = err;
++		_tmp7_ = g_error_new (RYGEL_LMS_DATABASE_ERROR, RYGEL_LMS_DATABASE_ERROR_PREPARE, "Unable to create statement '%s': %d", _tmp5_, _tmp6_);
++		_inner_error_ = _tmp7_;
++		if (_inner_error_->domain == RYGEL_LMS_DATABASE_ERROR) {
++			g_propagate_error (error, _inner_error_);
++			_sqlite3_finalize0 (statement);
++			return NULL;
++		} else {
++			_sqlite3_finalize0 (statement);
++			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;
++		}
++	}
++	result = statement;
++	return result;
++}
++
++
++sqlite3_stmt* rygel_lms_database_prepare_and_init (RygelLMSDatabase* self, const gchar* query, GValue* arguments, int arguments_length1, GError** error) {
++	sqlite3_stmt* result = NULL;
++	sqlite3_stmt* statement = NULL;
++	gint err = 0;
++	sqlite3* _tmp0_ = NULL;
++	const gchar* _tmp1_ = NULL;
++	sqlite3_stmt* _tmp2_ = NULL;
++	gint _tmp3_ = 0;
++	gint _tmp4_ = 0;
++	GError * _inner_error_ = NULL;
++	g_return_val_if_fail (self != NULL, NULL);
++	g_return_val_if_fail (query != NULL, NULL);
++	_tmp0_ = self->priv->db;
++	_tmp1_ = query;
++	_tmp3_ = sqlite3_prepare_v2 (_tmp0_, _tmp1_, -1, &_tmp2_, NULL);
++	_sqlite3_finalize0 (statement);
++	statement = _tmp2_;
++	err = _tmp3_;
++	_tmp4_ = err;
++	if (_tmp4_ != SQLITE_OK) {
++		const gchar* _tmp5_ = NULL;
++		gint _tmp6_ = 0;
++		GError* _tmp7_ = NULL;
++		_tmp5_ = query;
++		_tmp6_ = err;
++		_tmp7_ = g_error_new (RYGEL_LMS_DATABASE_ERROR, RYGEL_LMS_DATABASE_ERROR_PREPARE, "Unable to create statement '%s': %d", _tmp5_, _tmp6_);
++		_inner_error_ = _tmp7_;
++		if (_inner_error_->domain == RYGEL_LMS_DATABASE_ERROR) {
++			g_propagate_error (error, _inner_error_);
++			_sqlite3_finalize0 (statement);
++			return NULL;
++		} else {
++			_sqlite3_finalize0 (statement);
++			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;
++		}
++	}
++	{
++		gint i = 0;
++		i = 1;
++		{
++			gboolean _tmp8_ = FALSE;
++			_tmp8_ = TRUE;
++			while (TRUE) {
++				gint _tmp10_ = 0;
++				GValue* _tmp11_ = NULL;
++				gint _tmp11__length1 = 0;
++				gint sqlite_err = 0;
++				GValue current_value = {0};
++				GValue* _tmp12_ = NULL;
++				gint _tmp12__length1 = 0;
++				gint _tmp13_ = 0;
++				GValue _tmp14_ = {0};
++				gboolean _tmp15_ = FALSE;
++				if (!_tmp8_) {
++					gint _tmp9_ = 0;
++					_tmp9_ = i;
++					i = _tmp9_ + 1;
++				}
++				_tmp8_ = FALSE;
++				_tmp10_ = i;
++				_tmp11_ = arguments;
++				_tmp11__length1 = arguments_length1;
++				if (!(_tmp10_ <= _tmp11__length1)) {
++					break;
++				}
++				_tmp12_ = arguments;
++				_tmp12__length1 = arguments_length1;
++				_tmp13_ = i;
++				_tmp14_ = _tmp12_[_tmp13_ - 1];
++				current_value = _tmp14_;
++				_tmp15_ = G_VALUE_HOLDS (&current_value, G_TYPE_INT);
++				if (_tmp15_) {
++					sqlite3_stmt* _tmp16_ = NULL;
++					gint _tmp17_ = 0;
++					gint _tmp18_ = 0;
++					gint _tmp19_ = 0;
++					gint _tmp20_ = 0;
++					_tmp16_ = statement;
++					_tmp17_ = i;
++					_tmp18_ = g_value_get_int (&current_value);
++					_tmp19_ = sqlite3_bind_int (_tmp16_, _tmp17_, _tmp18_);
++					sqlite_err = _tmp19_;
++					_tmp20_ = sqlite_err;
++					if (_tmp20_ != SQLITE_OK) {
++						gint _tmp21_ = 0;
++						GError* _tmp22_ = NULL;
++						_tmp21_ = sqlite_err;
++						_tmp22_ = g_error_new (RYGEL_LMS_DATABASE_ERROR, RYGEL_LMS_DATABASE_ERROR_BIND, "Unable to bind value %d", _tmp21_);
++						_inner_error_ = _tmp22_;
++						if (_inner_error_->domain == RYGEL_LMS_DATABASE_ERROR) {
++							g_propagate_error (error, _inner_error_);
++							_sqlite3_finalize0 (statement);
++							return NULL;
++						} else {
++							_sqlite3_finalize0 (statement);
++							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;
++						}
++					}
++				} else {
++					gboolean _tmp23_ = FALSE;
++					_tmp23_ = G_VALUE_HOLDS (&current_value, G_TYPE_INT64);
++					if (_tmp23_) {
++						sqlite3_stmt* _tmp24_ = NULL;
++						gint _tmp25_ = 0;
++						gint64 _tmp26_ = 0LL;
++						gint _tmp27_ = 0;
++						gint _tmp28_ = 0;
++						_tmp24_ = statement;
++						_tmp25_ = i;
++						_tmp26_ = g_value_get_int64 (&current_value);
++						_tmp27_ = sqlite3_bind_int64 (_tmp24_, _tmp25_, _tmp26_);
++						sqlite_err = _tmp27_;
++						_tmp28_ = sqlite_err;
++						if (_tmp28_ != SQLITE_OK) {
++							gint _tmp29_ = 0;
++							GError* _tmp30_ = NULL;
++							_tmp29_ = sqlite_err;
++							_tmp30_ = g_error_new (RYGEL_LMS_DATABASE_ERROR, RYGEL_LMS_DATABASE_ERROR_BIND, "Unable to bind value %d", _tmp29_);
++							_inner_error_ = _tmp30_;
++							if (_inner_error_->domain == RYGEL_LMS_DATABASE_ERROR) {
++								g_propagate_error (error, _inner_error_);
++								_sqlite3_finalize0 (statement);
++								return NULL;
++							} else {
++								_sqlite3_finalize0 (statement);
++								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;
++							}
++						}
++					} else {
++						gboolean _tmp31_ = FALSE;
++						_tmp31_ = G_VALUE_HOLDS (&current_value, G_TYPE_UINT64);
++						if (_tmp31_) {
++							sqlite3_stmt* _tmp32_ = NULL;
++							gint _tmp33_ = 0;
++							guint64 _tmp34_ = 0ULL;
++							gint _tmp35_ = 0;
++							gint _tmp36_ = 0;
++							_tmp32_ = statement;
++							_tmp33_ = i;
++							_tmp34_ = g_value_get_uint64 (&current_value);
++							_tmp35_ = sqlite3_bind_int64 (_tmp32_, _tmp33_, (gint64) _tmp34_);
++							sqlite_err = _tmp35_;
++							_tmp36_ = sqlite_err;
++							if (_tmp36_ != SQLITE_OK) {
++								gint _tmp37_ = 0;
++								GError* _tmp38_ = NULL;
++								_tmp37_ = sqlite_err;
++								_tmp38_ = g_error_new (RYGEL_LMS_DATABASE_ERROR, RYGEL_LMS_DATABASE_ERROR_BIND, "Unable to bind value %d", _tmp37_);
++								_inner_error_ = _tmp38_;
++								if (_inner_error_->domain == RYGEL_LMS_DATABASE_ERROR) {
++									g_propagate_error (error, _inner_error_);
++									_sqlite3_finalize0 (statement);
++									return NULL;
++								} else {
++									_sqlite3_finalize0 (statement);
++									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;
++								}
++							}
++						} else {
++							gboolean _tmp39_ = FALSE;
++							_tmp39_ = G_VALUE_HOLDS (&current_value, G_TYPE_LONG);
++							if (_tmp39_) {
++								sqlite3_stmt* _tmp40_ = NULL;
++								gint _tmp41_ = 0;
++								glong _tmp42_ = 0L;
++								gint _tmp43_ = 0;
++								gint _tmp44_ = 0;
++								_tmp40_ = statement;
++								_tmp41_ = i;
++								_tmp42_ = g_value_get_long (&current_value);
++								_tmp43_ = sqlite3_bind_int64 (_tmp40_, _tmp41_, (gint64) _tmp42_);
++								sqlite_err = _tmp43_;
++								_tmp44_ = sqlite_err;
++								if (_tmp44_ != SQLITE_OK) {
++									gint _tmp45_ = 0;
++									GError* _tmp46_ = NULL;
++									_tmp45_ = sqlite_err;
++									_tmp46_ = g_error_new (RYGEL_LMS_DATABASE_ERROR, RYGEL_LMS_DATABASE_ERROR_BIND, "Unable to bind value %d", _tmp45_);
++									_inner_error_ = _tmp46_;
++									if (_inner_error_->domain == RYGEL_LMS_DATABASE_ERROR) {
++										g_propagate_error (error, _inner_error_);
++										_sqlite3_finalize0 (statement);
++										return NULL;
++									} else {
++										_sqlite3_finalize0 (statement);
++										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;
++									}
++								}
++							} else {
++								gboolean _tmp47_ = FALSE;
++								_tmp47_ = G_VALUE_HOLDS (&current_value, G_TYPE_UINT);
++								if (_tmp47_) {
++									sqlite3_stmt* _tmp48_ = NULL;
++									gint _tmp49_ = 0;
++									guint _tmp50_ = 0U;
++									gint _tmp51_ = 0;
++									gint _tmp52_ = 0;
++									_tmp48_ = statement;
++									_tmp49_ = i;
++									_tmp50_ = g_value_get_uint (&current_value);
++									_tmp51_ = sqlite3_bind_int64 (_tmp48_, _tmp49_, (gint64) _tmp50_);
++									sqlite_err = _tmp51_;
++									_tmp52_ = sqlite_err;
++									if (_tmp52_ != SQLITE_OK) {
++										gint _tmp53_ = 0;
++										GError* _tmp54_ = NULL;
++										_tmp53_ = sqlite_err;
++										_tmp54_ = g_error_new (RYGEL_LMS_DATABASE_ERROR, RYGEL_LMS_DATABASE_ERROR_BIND, "Unable to bind value %d", _tmp53_);
++										_inner_error_ = _tmp54_;
++										if (_inner_error_->domain == RYGEL_LMS_DATABASE_ERROR) {
++											g_propagate_error (error, _inner_error_);
++											_sqlite3_finalize0 (statement);
++											return NULL;
++										} else {
++											_sqlite3_finalize0 (statement);
++											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;
++										}
++									}
++								} else {
++									gboolean _tmp55_ = FALSE;
++									_tmp55_ = G_VALUE_HOLDS (&current_value, G_TYPE_STRING);
++									if (_tmp55_) {
++										sqlite3_stmt* _tmp56_ = NULL;
++										gint _tmp57_ = 0;
++										const gchar* _tmp58_ = NULL;
++										gchar* _tmp59_ = NULL;
++										GDestroyNotify _tmp60_ = NULL;
++										gint _tmp61_ = 0;
++										gint _tmp62_ = 0;
++										_tmp56_ = statement;
++										_tmp57_ = i;
++										_tmp58_ = g_value_get_string (&current_value);
++										_tmp59_ = g_strdup (_tmp58_);
++										_tmp60_ = g_free;
++										_tmp61_ = sqlite3_bind_text (_tmp56_, _tmp57_, _tmp59_, -1, _tmp60_);
++										sqlite_err = _tmp61_;
++										_tmp62_ = sqlite_err;
++										if (_tmp62_ != SQLITE_OK) {
++											gint _tmp63_ = 0;
++											GError* _tmp64_ = NULL;
++											_tmp63_ = sqlite_err;
++											_tmp64_ = g_error_new (RYGEL_LMS_DATABASE_ERROR, RYGEL_LMS_DATABASE_ERROR_BIND, "Unable to bind value %d", _tmp63_);
++											_inner_error_ = _tmp64_;
++											if (_inner_error_->domain == RYGEL_LMS_DATABASE_ERROR) {
++												g_propagate_error (error, _inner_error_);
++												_sqlite3_finalize0 (statement);
++												return NULL;
++											} else {
++												_sqlite3_finalize0 (statement);
++												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;
++											}
++										}
++									} else {
++										gboolean _tmp65_ = FALSE;
++										_tmp65_ = G_VALUE_HOLDS (&current_value, G_TYPE_POINTER);
++										if (_tmp65_) {
++											void* _tmp66_ = NULL;
++											_tmp66_ = g_value_peek_pointer (&current_value);
++											if (_tmp66_ == NULL) {
++												sqlite3_stmt* _tmp67_ = NULL;
++												gint _tmp68_ = 0;
++												gint _tmp69_ = 0;
++												gint _tmp70_ = 0;
++												_tmp67_ = statement;
++												_tmp68_ = i;
++												_tmp69_ = sqlite3_bind_null (_tmp67_, _tmp68_);
++												sqlite_err = _tmp69_;
++												_tmp70_ = sqlite_err;
++												if (_tmp70_ != SQLITE_OK) {
++													gint _tmp71_ = 0;
++													GError* _tmp72_ = NULL;
++													_tmp71_ = sqlite_err;
++													_tmp72_ = g_error_new (RYGEL_LMS_DATABASE_ERROR, RYGEL_LMS_DATABASE_ERROR_BIND, "Unable to bind value %d", _tmp71_);
++													_inner_error_ = _tmp72_;
++													if (_inner_error_->domain == RYGEL_LMS_DATABASE_ERROR) {
++														g_propagate_error (error, _inner_error_);
++														_sqlite3_finalize0 (statement);
++														return NULL;
++													} else {
++														_sqlite3_finalize0 (statement);
++														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;
++													}
++												}
++											} else {
++												g_assert_not_reached ();
++											}
++										} else {
++											GType type = 0UL;
++											GType _tmp73_ = 0UL;
++											const gchar* _tmp74_ = NULL;
++											const gchar* _tmp75_ = NULL;
++											_tmp73_ = G_VALUE_TYPE (&current_value);
++											type = _tmp73_;
++											_tmp74_ = _ ("Unsupported type %s");
++											_tmp75_ = g_type_name (type);
++											g_warning (_tmp74_, _tmp75_);
++											g_assert_not_reached ();
++										}
++									}
++								}
++							}
++						}
++					}
++				}
++			}
++		}
++	}
++	result = statement;
++	return result;
++}
++
++
++void rygel_lms_database_find_object (const gchar* id, sqlite3_stmt* stmt, GError** error) {
++	sqlite3_stmt* _tmp0_ = NULL;
++	gint _tmp1_ = 0;
++	gint integer_id = 0;
++	const gchar* _tmp2_ = NULL;
++	gint _tmp3_ = 0;
++	gint sqlite_err = 0;
++	sqlite3_stmt* _tmp4_ = NULL;
++	gint _tmp5_ = 0;
++	gint _tmp6_ = 0;
++	gint _tmp7_ = 0;
++	sqlite3_stmt* _tmp10_ = NULL;
++	gint _tmp11_ = 0;
++	gint _tmp12_ = 0;
++	GError * _inner_error_ = NULL;
++	g_return_if_fail (id != NULL);
++	g_return_if_fail (stmt != NULL);
++	_tmp0_ = stmt;
++	_tmp1_ = sqlite3_reset (_tmp0_);
++	_tmp2_ = id;
++	_tmp3_ = atoi (_tmp2_);
++	integer_id = _tmp3_;
++	_tmp4_ = stmt;
++	_tmp5_ = integer_id;
++	_tmp6_ = sqlite3_bind_int (_tmp4_, 1, _tmp5_);
++	sqlite_err = _tmp6_;
++	_tmp7_ = sqlite_err;
++	if (_tmp7_ != SQLITE_OK) {
++		gint _tmp8_ = 0;
++		GError* _tmp9_ = NULL;
++		_tmp8_ = sqlite_err;
++		_tmp9_ = g_error_new (RYGEL_LMS_DATABASE_ERROR, RYGEL_LMS_DATABASE_ERROR_BIND, "Unable to bind id %d", _tmp8_);
++		_inner_error_ = _tmp9_;
++		if (_inner_error_->domain == RYGEL_LMS_DATABASE_ERROR) {
++			g_propagate_error (error, _inner_error_);
++			return;
++		} else {
++			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;
++		}
++	}
++	_tmp10_ = stmt;
++	_tmp11_ = sqlite3_step (_tmp10_);
++	sqlite_err = _tmp11_;
++	_tmp12_ = sqlite_err;
++	if (_tmp12_ != SQLITE_ROW) {
++		const gchar* _tmp13_ = NULL;
++		GError* _tmp14_ = NULL;
++		_tmp13_ = id;
++		_tmp14_ = g_error_new (RYGEL_LMS_DATABASE_ERROR, RYGEL_LMS_DATABASE_ERROR_STEP, "Unable to find id %s", _tmp13_);
++		_inner_error_ = _tmp14_;
++		if (_inner_error_->domain == RYGEL_LMS_DATABASE_ERROR) {
++			g_propagate_error (error, _inner_error_);
++			return;
++		} else {
++			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;
++		}
++	}
++}
++
++
++void rygel_lms_database_get_children_init (sqlite3_stmt* stmt, guint offset, guint max_count, const gchar* sort_criteria, GError** error) {
++	gint sqlite_err = 0;
++	sqlite3_stmt* _tmp0_ = NULL;
++	gint _tmp1_ = 0;
++	sqlite3_stmt* _tmp2_ = NULL;
++	guint _tmp3_ = 0U;
++	gint _tmp4_ = 0;
++	gint _tmp5_ = 0;
++	sqlite3_stmt* _tmp8_ = NULL;
++	guint _tmp9_ = 0U;
++	gint _tmp10_ = 0;
++	gint _tmp11_ = 0;
++	GError * _inner_error_ = NULL;
++	g_return_if_fail (stmt != NULL);
++	g_return_if_fail (sort_criteria != NULL);
++	_tmp0_ = stmt;
++	_tmp1_ = sqlite3_reset (_tmp0_);
++	_tmp2_ = stmt;
++	_tmp3_ = max_count;
++	_tmp4_ = sqlite3_bind_int (_tmp2_, 1, (gint) _tmp3_);
++	sqlite_err = _tmp4_;
++	_tmp5_ = sqlite_err;
++	if (_tmp5_ != SQLITE_OK) {
++		gint _tmp6_ = 0;
++		GError* _tmp7_ = NULL;
++		_tmp6_ = sqlite_err;
++		_tmp7_ = g_error_new (RYGEL_LMS_DATABASE_ERROR, RYGEL_LMS_DATABASE_ERROR_BIND, "Unable to bind max_count %d", _tmp6_);
++		_inner_error_ = _tmp7_;
++		if (_inner_error_->domain == RYGEL_LMS_DATABASE_ERROR) {
++			g_propagate_error (error, _inner_error_);
++			return;
++		} else {
++			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;
++		}
++	}
++	_tmp8_ = stmt;
++	_tmp9_ = offset;
++	_tmp10_ = sqlite3_bind_int (_tmp8_, 2, (gint) _tmp9_);
++	sqlite_err = _tmp10_;
++	_tmp11_ = sqlite_err;
++	if (_tmp11_ != SQLITE_OK) {
++		gint _tmp12_ = 0;
++		GError* _tmp13_ = NULL;
++		_tmp12_ = sqlite_err;
++		_tmp13_ = g_error_new (RYGEL_LMS_DATABASE_ERROR, RYGEL_LMS_DATABASE_ERROR_BIND, "Unable to bind offset %d", _tmp12_);
++		_inner_error_ = _tmp13_;
++		if (_inner_error_->domain == RYGEL_LMS_DATABASE_ERROR) {
++			g_propagate_error (error, _inner_error_);
++			return;
++		} else {
++			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;
++		}
++	}
++}
++
++
++void rygel_lms_database_get_children_with_update_id_init (sqlite3_stmt* stmt, guint64 old_id, guint64 new_id, GError** error) {
++	gint sqlite_err = 0;
++	sqlite3_stmt* _tmp0_ = NULL;
++	gint _tmp1_ = 0;
++	guint64 _tmp2_ = 0ULL;
++	guint64 _tmp3_ = 0ULL;
++	gint _tmp9_ = 0;
++	sqlite3_stmt* _tmp12_ = NULL;
++	guint64 _tmp13_ = 0ULL;
++	gint _tmp14_ = 0;
++	gint _tmp15_ = 0;
++	GError * _inner_error_ = NULL;
++	g_return_if_fail (stmt != NULL);
++	_tmp0_ = stmt;
++	_tmp1_ = sqlite3_reset (_tmp0_);
++	_tmp2_ = new_id;
++	_tmp3_ = old_id;
++	if (_tmp2_ < _tmp3_) {
++		sqlite3_stmt* _tmp4_ = NULL;
++		gint _tmp5_ = 0;
++		_tmp4_ = stmt;
++		_tmp5_ = sqlite3_bind_int64 (_tmp4_, 1, (gint64) 0);
++		sqlite_err = _tmp5_;
++	} else {
++		sqlite3_stmt* _tmp6_ = NULL;
++		guint64 _tmp7_ = 0ULL;
++		gint _tmp8_ = 0;
++		_tmp6_ = stmt;
++		_tmp7_ = old_id;
++		_tmp8_ = sqlite3_bind_int64 (_tmp6_, 1, (gint64) _tmp7_);
++		sqlite_err = _tmp8_;
++	}
++	_tmp9_ = sqlite_err;
++	if (_tmp9_ != SQLITE_OK) {
++		gint _tmp10_ = 0;
++		GError* _tmp11_ = NULL;
++		_tmp10_ = sqlite_err;
++		_tmp11_ = g_error_new (RYGEL_LMS_DATABASE_ERROR, RYGEL_LMS_DATABASE_ERROR_BIND, "Unable to bind old_id %d", _tmp10_);
++		_inner_error_ = _tmp11_;
++		if (_inner_error_->domain == RYGEL_LMS_DATABASE_ERROR) {
++			g_propagate_error (error, _inner_error_);
++			return;
++		} else {
++			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;
++		}
++	}
++	_tmp12_ = stmt;
++	_tmp13_ = new_id;
++	_tmp14_ = sqlite3_bind_int64 (_tmp12_, 2, (gint64) _tmp13_);
++	sqlite_err = _tmp14_;
++	_tmp15_ = sqlite_err;
++	if (_tmp15_ != SQLITE_OK) {
++		gint _tmp16_ = 0;
++		GError* _tmp17_ = NULL;
++		_tmp16_ = sqlite_err;
++		_tmp17_ = g_error_new (RYGEL_LMS_DATABASE_ERROR, RYGEL_LMS_DATABASE_ERROR_BIND, "Unable to bind new_id %d", _tmp16_);
++		_inner_error_ = _tmp17_;
++		if (_inner_error_->domain == RYGEL_LMS_DATABASE_ERROR) {
++			g_propagate_error (error, _inner_error_);
++			return;
++		} else {
++			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;
++		}
++	}
++}
++
++
++gboolean rygel_lms_database_get_children_step (sqlite3_stmt* stmt, GError** error) {
++	gboolean result = FALSE;
++	gboolean retval = FALSE;
++	gint sqlite_err = 0;
++	sqlite3_stmt* _tmp0_ = NULL;
++	gint _tmp1_ = 0;
++	gint _tmp2_ = 0;
++	gboolean _tmp3_ = FALSE;
++	gboolean _tmp4_ = FALSE;
++	GError * _inner_error_ = NULL;
++	g_return_val_if_fail (stmt != NULL, FALSE);
++	_tmp0_ = stmt;
++	_tmp1_ = sqlite3_step (_tmp0_);
++	sqlite_err = _tmp1_;
++	_tmp2_ = sqlite_err;
++	retval = _tmp2_ == SQLITE_ROW;
++	_tmp4_ = retval;
++	if (!_tmp4_) {
++		gint _tmp5_ = 0;
++		_tmp5_ = sqlite_err;
++		_tmp3_ = _tmp5_ != SQLITE_DONE;
++	} else {
++		_tmp3_ = FALSE;
++	}
++	if (_tmp3_) {
++		gint _tmp6_ = 0;
++		GError* _tmp7_ = NULL;
++		_tmp6_ = sqlite_err;
++		_tmp7_ = g_error_new (RYGEL_LMS_DATABASE_ERROR, RYGEL_LMS_DATABASE_ERROR_STEP, "Error iterating through rows %d", _tmp6_);
++		_inner_error_ = _tmp7_;
++		if (_inner_error_->domain == RYGEL_LMS_DATABASE_ERROR) {
++			g_propagate_error (error, _inner_error_);
++			return FALSE;
++		} else {
++			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 FALSE;
++		}
++	}
++	result = retval;
++	return result;
++}
++
++
++static void g_cclosure_user_marshal_VOID__UINT64_UINT64 (GClosure * closure, GValue * return_value, guint n_param_values, const GValue * param_values, gpointer invocation_hint, gpointer marshal_data) {
++	typedef void (*GMarshalFunc_VOID__UINT64_UINT64) (gpointer data1, guint64 arg_1, guint64 arg_2, gpointer data2);
++	register GMarshalFunc_VOID__UINT64_UINT64 callback;
++	register GCClosure * cc;
++	register gpointer data1;
++	register gpointer data2;
++	cc = (GCClosure *) closure;
++	g_return_if_fail (n_param_values == 3);
++	if (G_CCLOSURE_SWAP_DATA (closure)) {
++		data1 = closure->data;
++		data2 = param_values->data[0].v_pointer;
++	} else {
++		data1 = param_values->data[0].v_pointer;
++		data2 = closure->data;
++	}
++	callback = (GMarshalFunc_VOID__UINT64_UINT64) (marshal_data ? marshal_data : cc->callback);
++	callback (data1, g_value_get_uint64 (param_values + 1), g_value_get_uint64 (param_values + 2), data2);
++}
++
++
++static void rygel_lms_value_database_init (GValue* value) {
++	value->data[0].v_pointer = NULL;
++}
++
++
++static void rygel_lms_value_database_free_value (GValue* value) {
++	if (value->data[0].v_pointer) {
++		rygel_lms_database_unref (value->data[0].v_pointer);
++	}
++}
++
++
++static void rygel_lms_value_database_copy_value (const GValue* src_value, GValue* dest_value) {
++	if (src_value->data[0].v_pointer) {
++		dest_value->data[0].v_pointer = rygel_lms_database_ref (src_value->data[0].v_pointer);
++	} else {
++		dest_value->data[0].v_pointer = NULL;
++	}
++}
++
++
++static gpointer rygel_lms_value_database_peek_pointer (const GValue* value) {
++	return value->data[0].v_pointer;
++}
++
++
++static gchar* rygel_lms_value_database_collect_value (GValue* value, guint n_collect_values, GTypeCValue* collect_values, guint collect_flags) {
++	if (collect_values[0].v_pointer) {
++		RygelLMSDatabase* object;
++		object = collect_values[0].v_pointer;
++		if (object->parent_instance.g_class == NULL) {
++			return g_strconcat ("invalid unclassed object pointer for value type `", G_VALUE_TYPE_NAME (value), "'", NULL);
++		} else if (!g_value_type_compatible (G_TYPE_FROM_INSTANCE (object), G_VALUE_TYPE (value))) {
++			return g_strconcat ("invalid object type `", g_type_name (G_TYPE_FROM_INSTANCE (object)), "' for value type `", G_VALUE_TYPE_NAME (value), "'", NULL);
++		}
++		value->data[0].v_pointer = rygel_lms_database_ref (object);
++	} else {
++		value->data[0].v_pointer = NULL;
++	}
++	return NULL;
++}
++
++
++static gchar* rygel_lms_value_database_lcopy_value (const GValue* value, guint n_collect_values, GTypeCValue* collect_values, guint collect_flags) {
++	RygelLMSDatabase** object_p;
++	object_p = collect_values[0].v_pointer;
++	if (!object_p) {
++		return g_strdup_printf ("value location for `%s' passed as NULL", G_VALUE_TYPE_NAME (value));
++	}
++	if (!value->data[0].v_pointer) {
++		*object_p = NULL;
++	} else if (collect_flags & G_VALUE_NOCOPY_CONTENTS) {
++		*object_p = value->data[0].v_pointer;
++	} else {
++		*object_p = rygel_lms_database_ref (value->data[0].v_pointer);
++	}
++	return NULL;
++}
++
++
++GParamSpec* rygel_lms_param_spec_database (const gchar* name, const gchar* nick, const gchar* blurb, GType object_type, GParamFlags flags) {
++	RygelLMSParamSpecDatabase* spec;
++	g_return_val_if_fail (g_type_is_a (object_type, RYGEL_LMS_TYPE_DATABASE), NULL);
++	spec = g_param_spec_internal (G_TYPE_PARAM_OBJECT, name, nick, blurb, flags);
++	G_PARAM_SPEC (spec)->value_type = object_type;
++	return G_PARAM_SPEC (spec);
++}
++
++
++gpointer rygel_lms_value_get_database (const GValue* value) {
++	g_return_val_if_fail (G_TYPE_CHECK_VALUE_TYPE (value, RYGEL_LMS_TYPE_DATABASE), NULL);
++	return value->data[0].v_pointer;
++}
++
++
++void rygel_lms_value_set_database (GValue* value, gpointer v_object) {
++	RygelLMSDatabase* old;
++	g_return_if_fail (G_TYPE_CHECK_VALUE_TYPE (value, RYGEL_LMS_TYPE_DATABASE));
++	old = value->data[0].v_pointer;
++	if (v_object) {
++		g_return_if_fail (G_TYPE_CHECK_INSTANCE_TYPE (v_object, RYGEL_LMS_TYPE_DATABASE));
++		g_return_if_fail (g_value_type_compatible (G_TYPE_FROM_INSTANCE (v_object), G_VALUE_TYPE (value)));
++		value->data[0].v_pointer = v_object;
++		rygel_lms_database_ref (value->data[0].v_pointer);
++	} else {
++		value->data[0].v_pointer = NULL;
++	}
++	if (old) {
++		rygel_lms_database_unref (old);
++	}
++}
++
++
++void rygel_lms_value_take_database (GValue* value, gpointer v_object) {
++	RygelLMSDatabase* old;
++	g_return_if_fail (G_TYPE_CHECK_VALUE_TYPE (value, RYGEL_LMS_TYPE_DATABASE));
++	old = value->data[0].v_pointer;
++	if (v_object) {
++		g_return_if_fail (G_TYPE_CHECK_INSTANCE_TYPE (v_object, RYGEL_LMS_TYPE_DATABASE));
++		g_return_if_fail (g_value_type_compatible (G_TYPE_FROM_INSTANCE (v_object), G_VALUE_TYPE (value)));
++		value->data[0].v_pointer = v_object;
++	} else {
++		value->data[0].v_pointer = NULL;
++	}
++	if (old) {
++		rygel_lms_database_unref (old);
++	}
++}
++
++
++static void rygel_lms_database_class_init (RygelLMSDatabaseClass * klass) {
++	rygel_lms_database_parent_class = g_type_class_peek_parent (klass);
++	((RygelLMSDatabaseClass *) klass)->finalize = rygel_lms_database_finalize;
++	g_type_class_add_private (klass, sizeof (RygelLMSDatabasePrivate));
++	g_signal_new ("db_updated", RYGEL_LMS_TYPE_DATABASE, G_SIGNAL_RUN_LAST, 0, NULL, NULL, g_cclosure_user_marshal_VOID__UINT64_UINT64, G_TYPE_NONE, 2, G_TYPE_UINT64, G_TYPE_UINT64);
++}
++
++
++static void rygel_lms_database_instance_init (RygelLMSDatabase * self) {
++	self->priv = RYGEL_LMS_DATABASE_GET_PRIVATE (self);
++	self->ref_count = 1;
++}
++
++
++static void rygel_lms_database_finalize (RygelLMSDatabase* obj) {
++	RygelLMSDatabase * self;
++	self = G_TYPE_CHECK_INSTANCE_CAST (obj, RYGEL_LMS_TYPE_DATABASE, RygelLMSDatabase);
++	g_signal_handlers_destroy (self);
++	_sqlite3_close0 (self->priv->db);
++	_g_object_unref0 (self->priv->lms_proxy);
++}
++
++
++GType rygel_lms_database_get_type (void) {
++	static volatile gsize rygel_lms_database_type_id__volatile = 0;
++	if (g_once_init_enter (&rygel_lms_database_type_id__volatile)) {
++		static const GTypeValueTable g_define_type_value_table = { rygel_lms_value_database_init, rygel_lms_value_database_free_value, rygel_lms_value_database_copy_value, rygel_lms_value_database_peek_pointer, "p", rygel_lms_value_database_collect_value, "p", rygel_lms_value_database_lcopy_value };
++		static const GTypeInfo g_define_type_info = { sizeof (RygelLMSDatabaseClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) rygel_lms_database_class_init, (GClassFinalizeFunc) NULL, NULL, sizeof (RygelLMSDatabase), 0, (GInstanceInitFunc) rygel_lms_database_instance_init, &g_define_type_value_table };
++		static const GTypeFundamentalInfo g_define_type_fundamental_info = { (G_TYPE_FLAG_CLASSED | G_TYPE_FLAG_INSTANTIATABLE | G_TYPE_FLAG_DERIVABLE | G_TYPE_FLAG_DEEP_DERIVABLE) };
++		GType rygel_lms_database_type_id;
++		rygel_lms_database_type_id = g_type_register_fundamental (g_type_fundamental_next (), "RygelLMSDatabase", &g_define_type_info, &g_define_type_fundamental_info, 0);
++		g_once_init_leave (&rygel_lms_database_type_id__volatile, rygel_lms_database_type_id);
++	}
++	return rygel_lms_database_type_id__volatile;
++}
++
++
++gpointer rygel_lms_database_ref (gpointer instance) {
++	RygelLMSDatabase* self;
++	self = instance;
++	g_atomic_int_inc (&self->ref_count);
++	return instance;
++}
++
++
++void rygel_lms_database_unref (gpointer instance) {
++	RygelLMSDatabase* self;
++	self = instance;
++	if (g_atomic_int_dec_and_test (&self->ref_count)) {
++		RYGEL_LMS_DATABASE_GET_CLASS (self)->finalize (self);
++		g_type_free_instance ((GTypeInstance *) self);
++	}
++}
++
++
++static gint _vala_array_length (gpointer array) {
++	int length;
++	length = 0;
++	if (array) {
++		while (((gpointer*) array)[length]) {
++			length++;
++		}
++	}
++	return length;
++}
++
++
++
+diff --git a/src/plugins/lms/rygel-lms-dbus-interfaces.c b/src/plugins/lms/rygel-lms-dbus-interfaces.c
+new file mode 100644
+index 0000000..b511b17
+--- /dev/null
++++ b/src/plugins/lms/rygel-lms-dbus-interfaces.c
+@@ -0,0 +1,261 @@
++/* rygel-lms-dbus-interfaces.c generated by valac 0.28.0, the Vala compiler
++ * generated from rygel-lms-dbus-interfaces.vala, do not modify */
++
++/*
++ * Copyright (C) 2014 Intel Corporation.
++ *
++ * Author: Alexander Kanavin <alex.kanavin@gmail.com>
++ *
++ * 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 <glib.h>
++#include <glib-object.h>
++#include <gio/gio.h>
++#include <stdlib.h>
++#include <string.h>
++
++
++#define RYGEL_LMS_TYPE_DBUS (rygel_lms_dbus_get_type ())
++#define RYGEL_LMS_DBUS(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), RYGEL_LMS_TYPE_DBUS, RygelLMSDBus))
++#define RYGEL_LMS_IS_DBUS(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), RYGEL_LMS_TYPE_DBUS))
++#define RYGEL_LMS_DBUS_GET_INTERFACE(obj) (G_TYPE_INSTANCE_GET_INTERFACE ((obj), RYGEL_LMS_TYPE_DBUS, RygelLMSDBusIface))
++
++typedef struct _RygelLMSDBus RygelLMSDBus;
++typedef struct _RygelLMSDBusIface RygelLMSDBusIface;
++
++#define RYGEL_LMS_TYPE_DBUS_PROXY (rygel_lms_dbus_proxy_get_type ())
++typedef GDBusProxy RygelLMSDBusProxy;
++typedef GDBusProxyClass RygelLMSDBusProxyClass;
++#define _g_free0(var) (var = (g_free (var), NULL))
++
++struct _RygelLMSDBusIface {
++	GTypeInterface parent_iface;
++	gchar* (*get_data_base_path) (RygelLMSDBus* self);
++	guint64 (*get_update_id) (RygelLMSDBus* self);
++};
++
++
++
++GType rygel_lms_dbus_get_type (void) G_GNUC_CONST;
++GType rygel_lms_dbus_proxy_get_type (void) G_GNUC_CONST;
++guint rygel_lms_dbus_register_object (void* object, GDBusConnection* connection, const gchar* path, GError** error);
++gchar* rygel_lms_dbus_get_data_base_path (RygelLMSDBus* self);
++guint64 rygel_lms_dbus_get_update_id (RygelLMSDBus* self);
++static void rygel_lms_dbus_proxy_g_signal (GDBusProxy* proxy, const gchar* sender_name, const gchar* signal_name, GVariant* parameters);
++static gchar* rygel_lms_dbus_dbus_proxy_get_data_base_path (RygelLMSDBus* self);
++static guint64 rygel_lms_dbus_dbus_proxy_get_update_id (RygelLMSDBus* self);
++static void rygel_lms_dbus_proxy_rygel_lms_dbus_interface_init (RygelLMSDBusIface* iface);
++static void rygel_lms_dbus_dbus_interface_method_call (GDBusConnection* connection, const gchar* sender, const gchar* object_path, const gchar* interface_name, const gchar* method_name, GVariant* parameters, GDBusMethodInvocation* invocation, gpointer user_data);
++static GVariant* rygel_lms_dbus_dbus_interface_get_property (GDBusConnection* connection, const gchar* sender, const gchar* object_path, const gchar* interface_name, const gchar* property_name, GError** error, gpointer user_data);
++static GVariant* _dbus_rygel_lms_dbus_get_data_base_path (RygelLMSDBus* self);
++static GVariant* _dbus_rygel_lms_dbus_get_update_id (RygelLMSDBus* self);
++static gboolean rygel_lms_dbus_dbus_interface_set_property (GDBusConnection* connection, const gchar* sender, const gchar* object_path, const gchar* interface_name, const gchar* property_name, GVariant* value, GError** error, gpointer user_data);
++static void _rygel_lms_dbus_unregister_object (gpointer user_data);
++
++static const GDBusMethodInfo * const _rygel_lms_dbus_dbus_method_info[] = {NULL};
++static const GDBusSignalInfo * const _rygel_lms_dbus_dbus_signal_info[] = {NULL};
++static const GDBusPropertyInfo _rygel_lms_dbus_dbus_property_info_data_base_path = {-1, "DataBasePath", "s", G_DBUS_PROPERTY_INFO_FLAGS_READABLE};
++static const GDBusPropertyInfo _rygel_lms_dbus_dbus_property_info_update_id = {-1, "UpdateID", "t", G_DBUS_PROPERTY_INFO_FLAGS_READABLE};
++static const GDBusPropertyInfo * const _rygel_lms_dbus_dbus_property_info[] = {&_rygel_lms_dbus_dbus_property_info_data_base_path, &_rygel_lms_dbus_dbus_property_info_update_id, NULL};
++static const GDBusInterfaceInfo _rygel_lms_dbus_dbus_interface_info = {-1, "org.lightmediascanner.Scanner1", (GDBusMethodInfo **) (&_rygel_lms_dbus_dbus_method_info), (GDBusSignalInfo **) (&_rygel_lms_dbus_dbus_signal_info), (GDBusPropertyInfo **) (&_rygel_lms_dbus_dbus_property_info)};
++static const GDBusInterfaceVTable _rygel_lms_dbus_dbus_interface_vtable = {rygel_lms_dbus_dbus_interface_method_call, rygel_lms_dbus_dbus_interface_get_property, rygel_lms_dbus_dbus_interface_set_property};
++
++gchar* rygel_lms_dbus_get_data_base_path (RygelLMSDBus* self) {
++	g_return_val_if_fail (self != NULL, NULL);
++	return RYGEL_LMS_DBUS_GET_INTERFACE (self)->get_data_base_path (self);
++}
++
++
++guint64 rygel_lms_dbus_get_update_id (RygelLMSDBus* self) {
++	g_return_val_if_fail (self != NULL, 0ULL);
++	return RYGEL_LMS_DBUS_GET_INTERFACE (self)->get_update_id (self);
++}
++
++
++static void rygel_lms_dbus_base_init (RygelLMSDBusIface * iface) {
++	static gboolean initialized = FALSE;
++	if (!initialized) {
++		initialized = TRUE;
++	}
++}
++
++
++GType rygel_lms_dbus_get_type (void) {
++	static volatile gsize rygel_lms_dbus_type_id__volatile = 0;
++	if (g_once_init_enter (&rygel_lms_dbus_type_id__volatile)) {
++		static const GTypeInfo g_define_type_info = { sizeof (RygelLMSDBusIface), (GBaseInitFunc) rygel_lms_dbus_base_init, (GBaseFinalizeFunc) NULL, (GClassInitFunc) NULL, (GClassFinalizeFunc) NULL, NULL, 0, 0, (GInstanceInitFunc) NULL, NULL };
++		GType rygel_lms_dbus_type_id;
++		rygel_lms_dbus_type_id = g_type_register_static (G_TYPE_INTERFACE, "RygelLMSDBus", &g_define_type_info, 0);
++		g_type_interface_add_prerequisite (rygel_lms_dbus_type_id, G_TYPE_DBUS_PROXY);
++		g_type_set_qdata (rygel_lms_dbus_type_id, g_quark_from_static_string ("vala-dbus-proxy-type"), (void*) rygel_lms_dbus_proxy_get_type);
++		g_type_set_qdata (rygel_lms_dbus_type_id, g_quark_from_static_string ("vala-dbus-interface-name"), "org.lightmediascanner.Scanner1");
++		g_type_set_qdata (rygel_lms_dbus_type_id, g_quark_from_static_string ("vala-dbus-interface-info"), (void*) (&_rygel_lms_dbus_dbus_interface_info));
++		g_type_set_qdata (rygel_lms_dbus_type_id, g_quark_from_static_string ("vala-dbus-register-object"), (void*) rygel_lms_dbus_register_object);
++		g_once_init_leave (&rygel_lms_dbus_type_id__volatile, rygel_lms_dbus_type_id);
++	}
++	return rygel_lms_dbus_type_id__volatile;
++}
++
++
++G_DEFINE_TYPE_EXTENDED (RygelLMSDBusProxy, rygel_lms_dbus_proxy, G_TYPE_DBUS_PROXY, 0, G_IMPLEMENT_INTERFACE (RYGEL_LMS_TYPE_DBUS, rygel_lms_dbus_proxy_rygel_lms_dbus_interface_init) )
++static void rygel_lms_dbus_proxy_class_init (RygelLMSDBusProxyClass* klass) {
++	G_DBUS_PROXY_CLASS (klass)->g_signal = rygel_lms_dbus_proxy_g_signal;
++}
++
++
++static void rygel_lms_dbus_proxy_g_signal (GDBusProxy* proxy, const gchar* sender_name, const gchar* signal_name, GVariant* parameters) {
++}
++
++
++static void rygel_lms_dbus_proxy_init (RygelLMSDBusProxy* self) {
++}
++
++
++static gchar* rygel_lms_dbus_dbus_proxy_get_data_base_path (RygelLMSDBus* self) {
++	GVariant *_inner_reply;
++	gchar* _result;
++	_inner_reply = g_dbus_proxy_get_cached_property ((GDBusProxy *) self, "DataBasePath");
++	if (!_inner_reply) {
++		GVariant *_arguments;
++		GVariant *_reply;
++		GVariantBuilder _arguments_builder;
++		g_variant_builder_init (&_arguments_builder, G_VARIANT_TYPE_TUPLE);
++		g_variant_builder_add_value (&_arguments_builder, g_variant_new_string ("org.lightmediascanner.Scanner1"));
++		g_variant_builder_add_value (&_arguments_builder, g_variant_new_string ("DataBasePath"));
++		_arguments = g_variant_builder_end (&_arguments_builder);
++		_reply = g_dbus_proxy_call_sync ((GDBusProxy *) self, "org.freedesktop.DBus.Properties.Get", _arguments, G_DBUS_CALL_FLAGS_NONE, -1, NULL, NULL);
++		if (!_reply) {
++			return NULL;
++		}
++		g_variant_get (_reply, "(v)", &_inner_reply);
++		g_variant_unref (_reply);
++	}
++	_result = g_variant_dup_string (_inner_reply, NULL);
++	g_variant_unref (_inner_reply);
++	return _result;
++}
++
++
++static guint64 rygel_lms_dbus_dbus_proxy_get_update_id (RygelLMSDBus* self) {
++	GVariant *_inner_reply;
++	guint64 _result;
++	_inner_reply = g_dbus_proxy_get_cached_property ((GDBusProxy *) self, "UpdateID");
++	if (!_inner_reply) {
++		GVariant *_arguments;
++		GVariant *_reply;
++		GVariantBuilder _arguments_builder;
++		g_variant_builder_init (&_arguments_builder, G_VARIANT_TYPE_TUPLE);
++		g_variant_builder_add_value (&_arguments_builder, g_variant_new_string ("org.lightmediascanner.Scanner1"));
++		g_variant_builder_add_value (&_arguments_builder, g_variant_new_string ("UpdateID"));
++		_arguments = g_variant_builder_end (&_arguments_builder);
++		_reply = g_dbus_proxy_call_sync ((GDBusProxy *) self, "org.freedesktop.DBus.Properties.Get", _arguments, G_DBUS_CALL_FLAGS_NONE, -1, NULL, NULL);
++		if (!_reply) {
++			return 0ULL;
++		}
++		g_variant_get (_reply, "(v)", &_inner_reply);
++		g_variant_unref (_reply);
++	}
++	_result = g_variant_get_uint64 (_inner_reply);
++	g_variant_unref (_inner_reply);
++	return _result;
++}
++
++
++static void rygel_lms_dbus_proxy_rygel_lms_dbus_interface_init (RygelLMSDBusIface* iface) {
++	iface->get_data_base_path = rygel_lms_dbus_dbus_proxy_get_data_base_path;
++	iface->get_update_id = rygel_lms_dbus_dbus_proxy_get_update_id;
++}
++
++
++static void rygel_lms_dbus_dbus_interface_method_call (GDBusConnection* connection, const gchar* sender, const gchar* object_path, const gchar* interface_name, const gchar* method_name, GVariant* parameters, GDBusMethodInvocation* invocation, gpointer user_data) {
++	gpointer* data;
++	gpointer object;
++	data = user_data;
++	object = data[0];
++	g_object_unref (invocation);
++}
++
++
++static GVariant* _dbus_rygel_lms_dbus_get_data_base_path (RygelLMSDBus* self) {
++	gchar* result;
++	GVariant* _reply;
++	result = rygel_lms_dbus_get_data_base_path (self);
++	_reply = g_variant_new_string (result);
++	_g_free0 (result);
++	return _reply;
++}
++
++
++static GVariant* _dbus_rygel_lms_dbus_get_update_id (RygelLMSDBus* self) {
++	guint64 result;
++	GVariant* _reply;
++	result = rygel_lms_dbus_get_update_id (self);
++	_reply = g_variant_new_uint64 (result);
++	return _reply;
++}
++
++
++static GVariant* rygel_lms_dbus_dbus_interface_get_property (GDBusConnection* connection, const gchar* sender, const gchar* object_path, const gchar* interface_name, const gchar* property_name, GError** error, gpointer user_data) {
++	gpointer* data;
++	gpointer object;
++	data = user_data;
++	object = data[0];
++	if (strcmp (property_name, "DataBasePath") == 0) {
++		return _dbus_rygel_lms_dbus_get_data_base_path (object);
++	} else if (strcmp (property_name, "UpdateID") == 0) {
++		return _dbus_rygel_lms_dbus_get_update_id (object);
++	}
++	return NULL;
++}
++
++
++static gboolean rygel_lms_dbus_dbus_interface_set_property (GDBusConnection* connection, const gchar* sender, const gchar* object_path, const gchar* interface_name, const gchar* property_name, GVariant* value, GError** error, gpointer user_data) {
++	gpointer* data;
++	gpointer object;
++	data = user_data;
++	object = data[0];
++	return FALSE;
++}
++
++
++guint rygel_lms_dbus_register_object (gpointer object, GDBusConnection* connection, const gchar* path, GError** error) {
++	guint result;
++	gpointer *data;
++	data = g_new (gpointer, 3);
++	data[0] = g_object_ref (object);
++	data[1] = g_object_ref (connection);
++	data[2] = g_strdup (path);
++	result = g_dbus_connection_register_object (connection, path, (GDBusInterfaceInfo *) (&_rygel_lms_dbus_dbus_interface_info), &_rygel_lms_dbus_dbus_interface_vtable, data, _rygel_lms_dbus_unregister_object, error);
++	if (!result) {
++		return 0;
++	}
++	return result;
++}
++
++
++static void _rygel_lms_dbus_unregister_object (gpointer user_data) {
++	gpointer* data;
++	data = user_data;
++	g_object_unref (data[0]);
++	g_object_unref (data[1]);
++	g_free (data[2]);
++	g_free (data);
++}
++
++
++
+diff --git a/src/plugins/lms/rygel-lms-image-root.c b/src/plugins/lms/rygel-lms-image-root.c
+new file mode 100644
+index 0000000..5ef358a
+--- /dev/null
++++ b/src/plugins/lms/rygel-lms-image-root.c
+@@ -0,0 +1,178 @@
++/* rygel-lms-image-root.c generated by valac 0.28.0, the Vala compiler
++ * generated from rygel-lms-image-root.vala, do not modify */
++
++/*
++ * Copyright (C) 2013 Intel Corporation.
++ *
++ * Author: Jussi Kukkonen <jussi.kukkonen@intel.com>
++ *
++ * 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 <glib.h>
++#include <glib-object.h>
++#include <rygel-server.h>
++#include <stdlib.h>
++#include <string.h>
++
++
++#define RYGEL_LMS_TYPE_IMAGE_ROOT (rygel_lms_image_root_get_type ())
++#define RYGEL_LMS_IMAGE_ROOT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), RYGEL_LMS_TYPE_IMAGE_ROOT, RygelLMSImageRoot))
++#define RYGEL_LMS_IMAGE_ROOT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), RYGEL_LMS_TYPE_IMAGE_ROOT, RygelLMSImageRootClass))
++#define RYGEL_LMS_IS_IMAGE_ROOT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), RYGEL_LMS_TYPE_IMAGE_ROOT))
++#define RYGEL_LMS_IS_IMAGE_ROOT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), RYGEL_LMS_TYPE_IMAGE_ROOT))
++#define RYGEL_LMS_IMAGE_ROOT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), RYGEL_LMS_TYPE_IMAGE_ROOT, RygelLMSImageRootClass))
++
++typedef struct _RygelLMSImageRoot RygelLMSImageRoot;
++typedef struct _RygelLMSImageRootClass RygelLMSImageRootClass;
++typedef struct _RygelLMSImageRootPrivate RygelLMSImageRootPrivate;
++
++#define RYGEL_LMS_TYPE_DATABASE (rygel_lms_database_get_type ())
++#define RYGEL_LMS_DATABASE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), RYGEL_LMS_TYPE_DATABASE, RygelLMSDatabase))
++#define RYGEL_LMS_DATABASE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), RYGEL_LMS_TYPE_DATABASE, RygelLMSDatabaseClass))
++#define RYGEL_LMS_IS_DATABASE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), RYGEL_LMS_TYPE_DATABASE))
++#define RYGEL_LMS_IS_DATABASE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), RYGEL_LMS_TYPE_DATABASE))
++#define RYGEL_LMS_DATABASE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), RYGEL_LMS_TYPE_DATABASE, RygelLMSDatabaseClass))
++
++typedef struct _RygelLMSDatabase RygelLMSDatabase;
++typedef struct _RygelLMSDatabaseClass RygelLMSDatabaseClass;
++
++#define RYGEL_LMS_TYPE_CATEGORY_CONTAINER (rygel_lms_category_container_get_type ())
++#define RYGEL_LMS_CATEGORY_CONTAINER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), RYGEL_LMS_TYPE_CATEGORY_CONTAINER, RygelLMSCategoryContainer))
++#define RYGEL_LMS_CATEGORY_CONTAINER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), RYGEL_LMS_TYPE_CATEGORY_CONTAINER, RygelLMSCategoryContainerClass))
++#define RYGEL_LMS_IS_CATEGORY_CONTAINER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), RYGEL_LMS_TYPE_CATEGORY_CONTAINER))
++#define RYGEL_LMS_IS_CATEGORY_CONTAINER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), RYGEL_LMS_TYPE_CATEGORY_CONTAINER))
++#define RYGEL_LMS_CATEGORY_CONTAINER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), RYGEL_LMS_TYPE_CATEGORY_CONTAINER, RygelLMSCategoryContainerClass))
++
++typedef struct _RygelLMSCategoryContainer RygelLMSCategoryContainer;
++typedef struct _RygelLMSCategoryContainerClass RygelLMSCategoryContainerClass;
++
++#define RYGEL_LMS_TYPE_ALL_IMAGES (rygel_lms_all_images_get_type ())
++#define RYGEL_LMS_ALL_IMAGES(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), RYGEL_LMS_TYPE_ALL_IMAGES, RygelLMSAllImages))
++#define RYGEL_LMS_ALL_IMAGES_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), RYGEL_LMS_TYPE_ALL_IMAGES, RygelLMSAllImagesClass))
++#define RYGEL_LMS_IS_ALL_IMAGES(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), RYGEL_LMS_TYPE_ALL_IMAGES))
++#define RYGEL_LMS_IS_ALL_IMAGES_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), RYGEL_LMS_TYPE_ALL_IMAGES))
++#define RYGEL_LMS_ALL_IMAGES_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), RYGEL_LMS_TYPE_ALL_IMAGES, RygelLMSAllImagesClass))
++
++typedef struct _RygelLMSAllImages RygelLMSAllImages;
++typedef struct _RygelLMSAllImagesClass RygelLMSAllImagesClass;
++#define _g_object_unref0(var) ((var == NULL) ? NULL : (var = (g_object_unref (var), NULL)))
++
++#define RYGEL_LMS_TYPE_IMAGE_YEARS (rygel_lms_image_years_get_type ())
++#define RYGEL_LMS_IMAGE_YEARS(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), RYGEL_LMS_TYPE_IMAGE_YEARS, RygelLMSImageYears))
++#define RYGEL_LMS_IMAGE_YEARS_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), RYGEL_LMS_TYPE_IMAGE_YEARS, RygelLMSImageYearsClass))
++#define RYGEL_LMS_IS_IMAGE_YEARS(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), RYGEL_LMS_TYPE_IMAGE_YEARS))
++#define RYGEL_LMS_IS_IMAGE_YEARS_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), RYGEL_LMS_TYPE_IMAGE_YEARS))
++#define RYGEL_LMS_IMAGE_YEARS_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), RYGEL_LMS_TYPE_IMAGE_YEARS, RygelLMSImageYearsClass))
++
++typedef struct _RygelLMSImageYears RygelLMSImageYears;
++typedef struct _RygelLMSImageYearsClass RygelLMSImageYearsClass;
++
++struct _RygelLMSImageRoot {
++	RygelSimpleContainer parent_instance;
++	RygelLMSImageRootPrivate * priv;
++};
++
++struct _RygelLMSImageRootClass {
++	RygelSimpleContainerClass parent_class;
++};
++
++
++static gpointer rygel_lms_image_root_parent_class = NULL;
++
++GType rygel_lms_image_root_get_type (void) G_GNUC_CONST;
++enum  {
++	RYGEL_LMS_IMAGE_ROOT_DUMMY_PROPERTY
++};
++gpointer rygel_lms_database_ref (gpointer instance);
++void rygel_lms_database_unref (gpointer instance);
++GParamSpec* rygel_lms_param_spec_database (const gchar* name, const gchar* nick, const gchar* blurb, GType object_type, GParamFlags flags);
++void rygel_lms_value_set_database (GValue* value, gpointer v_object);
++void rygel_lms_value_take_database (GValue* value, gpointer v_object);
++gpointer rygel_lms_value_get_database (const GValue* value);
++GType rygel_lms_database_get_type (void) G_GNUC_CONST;
++RygelLMSImageRoot* rygel_lms_image_root_new (const gchar* id, RygelMediaContainer* parent, const gchar* title, RygelLMSDatabase* lms_db);
++RygelLMSImageRoot* rygel_lms_image_root_construct (GType object_type, const gchar* id, RygelMediaContainer* parent, const gchar* title, RygelLMSDatabase* lms_db);
++RygelLMSAllImages* rygel_lms_all_images_new (RygelMediaContainer* parent, RygelLMSDatabase* lms_db);
++RygelLMSAllImages* rygel_lms_all_images_construct (GType object_type, RygelMediaContainer* parent, RygelLMSDatabase* lms_db);
++GType rygel_lms_category_container_get_type (void) G_GNUC_CONST;
++GType rygel_lms_all_images_get_type (void) G_GNUC_CONST;
++RygelLMSImageYears* rygel_lms_image_years_new (RygelMediaContainer* parent, RygelLMSDatabase* lms_db);
++RygelLMSImageYears* rygel_lms_image_years_construct (GType object_type, RygelMediaContainer* parent, RygelLMSDatabase* lms_db);
++GType rygel_lms_image_years_get_type (void) G_GNUC_CONST;
++
++
++RygelLMSImageRoot* rygel_lms_image_root_construct (GType object_type, const gchar* id, RygelMediaContainer* parent, const gchar* title, RygelLMSDatabase* lms_db) {
++	RygelLMSImageRoot * self = NULL;
++	const gchar* _tmp0_ = NULL;
++	RygelMediaContainer* _tmp1_ = NULL;
++	const gchar* _tmp2_ = NULL;
++	RygelLMSDatabase* _tmp3_ = NULL;
++	RygelLMSAllImages* _tmp4_ = NULL;
++	RygelLMSAllImages* _tmp5_ = NULL;
++	RygelLMSDatabase* _tmp6_ = NULL;
++	RygelLMSImageYears* _tmp7_ = NULL;
++	RygelLMSImageYears* _tmp8_ = NULL;
++	g_return_val_if_fail (id != NULL, NULL);
++	g_return_val_if_fail (parent != NULL, NULL);
++	g_return_val_if_fail (title != NULL, NULL);
++	g_return_val_if_fail (lms_db != NULL, NULL);
++	_tmp0_ = id;
++	_tmp1_ = parent;
++	_tmp2_ = title;
++	self = (RygelLMSImageRoot*) rygel_simple_container_construct (object_type, _tmp0_, _tmp1_, _tmp2_);
++	_tmp3_ = lms_db;
++	_tmp4_ = rygel_lms_all_images_new ((RygelMediaContainer*) self, _tmp3_);
++	_tmp5_ = _tmp4_;
++	rygel_simple_container_add_child_container ((RygelSimpleContainer*) self, (RygelMediaContainer*) _tmp5_);
++	_g_object_unref0 (_tmp5_);
++	_tmp6_ = lms_db;
++	_tmp7_ = rygel_lms_image_years_new ((RygelMediaContainer*) self, _tmp6_);
++	_tmp8_ = _tmp7_;
++	rygel_simple_container_add_child_container ((RygelSimpleContainer*) self, (RygelMediaContainer*) _tmp8_);
++	_g_object_unref0 (_tmp8_);
++	return self;
++}
++
++
++RygelLMSImageRoot* rygel_lms_image_root_new (const gchar* id, RygelMediaContainer* parent, const gchar* title, RygelLMSDatabase* lms_db) {
++	return rygel_lms_image_root_construct (RYGEL_LMS_TYPE_IMAGE_ROOT, id, parent, title, lms_db);
++}
++
++
++static void rygel_lms_image_root_class_init (RygelLMSImageRootClass * klass) {
++	rygel_lms_image_root_parent_class = g_type_class_peek_parent (klass);
++}
++
++
++static void rygel_lms_image_root_instance_init (RygelLMSImageRoot * self) {
++}
++
++
++GType rygel_lms_image_root_get_type (void) {
++	static volatile gsize rygel_lms_image_root_type_id__volatile = 0;
++	if (g_once_init_enter (&rygel_lms_image_root_type_id__volatile)) {
++		static const GTypeInfo g_define_type_info = { sizeof (RygelLMSImageRootClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) rygel_lms_image_root_class_init, (GClassFinalizeFunc) NULL, NULL, sizeof (RygelLMSImageRoot), 0, (GInstanceInitFunc) rygel_lms_image_root_instance_init, NULL };
++		GType rygel_lms_image_root_type_id;
++		rygel_lms_image_root_type_id = g_type_register_static (RYGEL_TYPE_SIMPLE_CONTAINER, "RygelLMSImageRoot", &g_define_type_info, 0);
++		g_once_init_leave (&rygel_lms_image_root_type_id__volatile, rygel_lms_image_root_type_id);
++	}
++	return rygel_lms_image_root_type_id__volatile;
++}
++
++
++
+diff --git a/src/plugins/lms/rygel-lms-image-year.c b/src/plugins/lms/rygel-lms-image-year.c
+new file mode 100644
+index 0000000..5eb2721
+--- /dev/null
++++ b/src/plugins/lms/rygel-lms-image-year.c
+@@ -0,0 +1,422 @@
++/* rygel-lms-image-year.c generated by valac 0.28.0, the Vala compiler
++ * generated from rygel-lms-image-year.vala, do not modify */
++
++/*
++ * Copyright (C) 2013 Intel Corporation.
++ *
++ * Author: Jussi Kukkonen <jussi.kukkonen@intel.com>
++ *
++ * 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 <glib.h>
++#include <glib-object.h>
++#include <rygel-server.h>
++#include <sqlite3.h>
++#include <stdlib.h>
++#include <string.h>
++#include <gio/gio.h>
++
++
++#define RYGEL_LMS_TYPE_CATEGORY_CONTAINER (rygel_lms_category_container_get_type ())
++#define RYGEL_LMS_CATEGORY_CONTAINER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), RYGEL_LMS_TYPE_CATEGORY_CONTAINER, RygelLMSCategoryContainer))
++#define RYGEL_LMS_CATEGORY_CONTAINER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), RYGEL_LMS_TYPE_CATEGORY_CONTAINER, RygelLMSCategoryContainerClass))
++#define RYGEL_LMS_IS_CATEGORY_CONTAINER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), RYGEL_LMS_TYPE_CATEGORY_CONTAINER))
++#define RYGEL_LMS_IS_CATEGORY_CONTAINER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), RYGEL_LMS_TYPE_CATEGORY_CONTAINER))
++#define RYGEL_LMS_CATEGORY_CONTAINER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), RYGEL_LMS_TYPE_CATEGORY_CONTAINER, RygelLMSCategoryContainerClass))
++
++typedef struct _RygelLMSCategoryContainer RygelLMSCategoryContainer;
++typedef struct _RygelLMSCategoryContainerClass RygelLMSCategoryContainerClass;
++typedef struct _RygelLMSCategoryContainerPrivate RygelLMSCategoryContainerPrivate;
++
++#define RYGEL_LMS_TYPE_IMAGE_YEAR (rygel_lms_image_year_get_type ())
++#define RYGEL_LMS_IMAGE_YEAR(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), RYGEL_LMS_TYPE_IMAGE_YEAR, RygelLMSImageYear))
++#define RYGEL_LMS_IMAGE_YEAR_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), RYGEL_LMS_TYPE_IMAGE_YEAR, RygelLMSImageYearClass))
++#define RYGEL_LMS_IS_IMAGE_YEAR(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), RYGEL_LMS_TYPE_IMAGE_YEAR))
++#define RYGEL_LMS_IS_IMAGE_YEAR_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), RYGEL_LMS_TYPE_IMAGE_YEAR))
++#define RYGEL_LMS_IMAGE_YEAR_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), RYGEL_LMS_TYPE_IMAGE_YEAR, RygelLMSImageYearClass))
++
++typedef struct _RygelLMSImageYear RygelLMSImageYear;
++typedef struct _RygelLMSImageYearClass RygelLMSImageYearClass;
++typedef struct _RygelLMSImageYearPrivate RygelLMSImageYearPrivate;
++#define _g_free0(var) (var = (g_free (var), NULL))
++#define _g_object_unref0(var) ((var == NULL) ? NULL : (var = (g_object_unref (var), NULL)))
++
++#define RYGEL_LMS_TYPE_DATABASE (rygel_lms_database_get_type ())
++#define RYGEL_LMS_DATABASE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), RYGEL_LMS_TYPE_DATABASE, RygelLMSDatabase))
++#define RYGEL_LMS_DATABASE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), RYGEL_LMS_TYPE_DATABASE, RygelLMSDatabaseClass))
++#define RYGEL_LMS_IS_DATABASE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), RYGEL_LMS_TYPE_DATABASE))
++#define RYGEL_LMS_IS_DATABASE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), RYGEL_LMS_TYPE_DATABASE))
++#define RYGEL_LMS_DATABASE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), RYGEL_LMS_TYPE_DATABASE, RygelLMSDatabaseClass))
++
++typedef struct _RygelLMSDatabase RygelLMSDatabase;
++typedef struct _RygelLMSDatabaseClass RygelLMSDatabaseClass;
++
++struct _RygelLMSCategoryContainer {
++	RygelMediaContainer parent_instance;
++	RygelLMSCategoryContainerPrivate * priv;
++	sqlite3_stmt* stmt_all;
++	sqlite3_stmt* stmt_find_object;
++	sqlite3_stmt* stmt_added;
++	sqlite3_stmt* stmt_removed;
++	gchar* child_prefix;
++	gchar* ref_prefix;
++};
++
++struct _RygelLMSCategoryContainerClass {
++	RygelMediaContainerClass parent_class;
++	RygelMediaObject* (*object_from_statement) (RygelLMSCategoryContainer* self, sqlite3_stmt* statement);
++	gchar* (*get_sql_all_with_filter) (RygelLMSCategoryContainer* self, const gchar* filter);
++	gchar* (*get_sql_count_with_filter) (RygelLMSCategoryContainer* self, const gchar* filter);
++	guint (*get_child_count_with_filter) (RygelLMSCategoryContainer* self, const gchar* where_filter, GValueArray* args);
++	RygelMediaObjects* (*get_children_with_filter) (RygelLMSCategoryContainer* self, const gchar* where_filter, GValueArray* args, const gchar* sort_criteria, guint offset, guint max_count);
++};
++
++struct _RygelLMSImageYear {
++	RygelLMSCategoryContainer parent_instance;
++	RygelLMSImageYearPrivate * priv;
++};
++
++struct _RygelLMSImageYearClass {
++	RygelLMSCategoryContainerClass parent_class;
++};
++
++
++static gpointer rygel_lms_image_year_parent_class = NULL;
++
++GType rygel_lms_category_container_get_type (void) G_GNUC_CONST;
++GType rygel_lms_image_year_get_type (void) G_GNUC_CONST;
++enum  {
++	RYGEL_LMS_IMAGE_YEAR_DUMMY_PROPERTY
++};
++#define RYGEL_LMS_IMAGE_YEAR_SQL_ALL_TEMPLATE "SELECT images.id, title, artist, date, width, height, path, size, dlna" \
++"_profile, dlna_mime, strftime('%Y', date, 'unixepoch') as year " "FROM images, files " "WHERE dtime = 0 AND images.id = files.id AND year = '%s' " "LIMIT ? OFFSET ?;"
++#define RYGEL_LMS_IMAGE_YEAR_SQL_COUNT_TEMPLATE "SELECT count(images.id), strftime('%Y', date, 'unixepoch') as year " "FROM images, files " "WHERE dtime = 0 AND images.id = files.id AND year = '%s';"
++#define RYGEL_LMS_IMAGE_YEAR_SQL_FIND_OBJECT_TEMPLATE "SELECT images.id, title, artist, date, width, height, path, size, dlna" \
++"_profile, dlna_mime, strftime('%Y', date, 'unixepoch') as year " "FROM images, files " "WHERE dtime = 0 AND files.id = ? AND images.id = files.id AND year = '" \
++"%s';"
++#define RYGEL_LMS_IMAGE_YEAR_SQL_ADDED_TEMPLATE "SELECT images.id, title, artist, date, width, height, path, size, dlna" \
++"_profile, dlna_mime, strftime('%Y', date, 'unixepoch') as year " "FROM images, files " "WHERE dtime = 0 AND images.id = files.id AND year = '%s' " "AND update_id > ? AND update_id <= ?;"
++#define RYGEL_LMS_IMAGE_YEAR_SQL_REMOVED_TEMPLATE "SELECT images.id, title, artist, date, width, height, path, size, dlna" \
++"_profile, dlna_mime, strftime('%Y', date, 'unixepoch') as year " "FROM images, files " "WHERE dtime <> 0 AND images.id = files.id AND year = '%s' " "AND update_id > ? AND update_id <= ?;"
++static RygelMediaObject* rygel_lms_image_year_real_object_from_statement (RygelLMSCategoryContainer* base, sqlite3_stmt* statement);
++gchar* rygel_lms_category_container_build_child_id (RygelLMSCategoryContainer* self, gint db_id);
++gchar* rygel_lms_category_container_build_reference_id (RygelLMSCategoryContainer* self, gint db_id);
++static gchar* rygel_lms_image_year_get_sql_all (const gchar* year);
++static gchar* rygel_lms_image_year_get_sql_find_object (const gchar* year);
++static gchar* rygel_lms_image_year_get_sql_count (const gchar* year);
++static gchar* rygel_lms_image_year_get_sql_added (const gchar* year);
++static gchar* rygel_lms_image_year_get_sql_removed (const gchar* year);
++gpointer rygel_lms_database_ref (gpointer instance);
++void rygel_lms_database_unref (gpointer instance);
++GParamSpec* rygel_lms_param_spec_database (const gchar* name, const gchar* nick, const gchar* blurb, GType object_type, GParamFlags flags);
++void rygel_lms_value_set_database (GValue* value, gpointer v_object);
++void rygel_lms_value_take_database (GValue* value, gpointer v_object);
++gpointer rygel_lms_value_get_database (const GValue* value);
++GType rygel_lms_database_get_type (void) G_GNUC_CONST;
++RygelLMSImageYear* rygel_lms_image_year_new (RygelMediaContainer* parent, const gchar* year, RygelLMSDatabase* lms_db);
++RygelLMSImageYear* rygel_lms_image_year_construct (GType object_type, RygelMediaContainer* parent, const gchar* year, RygelLMSDatabase* lms_db);
++RygelLMSCategoryContainer* rygel_lms_category_container_construct (GType object_type, const gchar* db_id, RygelMediaContainer* parent, const gchar* title, RygelLMSDatabase* lms_db, const gchar* sql_all, const gchar* sql_find_object, const gchar* sql_count, const gchar* sql_added, const gchar* sql_removed);
++
++
++static RygelMediaObject* rygel_lms_image_year_real_object_from_statement (RygelLMSCategoryContainer* base, sqlite3_stmt* statement) {
++	RygelLMSImageYear * self;
++	RygelMediaObject* result = NULL;
++	gint id = 0;
++	sqlite3_stmt* _tmp0_ = NULL;
++	gint _tmp1_ = 0;
++	gchar* path = NULL;
++	sqlite3_stmt* _tmp2_ = NULL;
++	const gchar* _tmp3_ = NULL;
++	gchar* _tmp4_ = NULL;
++	gchar* mime_type = NULL;
++	sqlite3_stmt* _tmp5_ = NULL;
++	const gchar* _tmp6_ = NULL;
++	gchar* _tmp7_ = NULL;
++	gboolean _tmp8_ = FALSE;
++	const gchar* _tmp9_ = NULL;
++	gchar* title = NULL;
++	sqlite3_stmt* _tmp15_ = NULL;
++	const gchar* _tmp16_ = NULL;
++	gchar* _tmp17_ = NULL;
++	RygelImageItem* image = NULL;
++	gint _tmp18_ = 0;
++	gchar* _tmp19_ = NULL;
++	gchar* _tmp20_ = NULL;
++	RygelImageItem* _tmp21_ = NULL;
++	RygelImageItem* _tmp22_ = NULL;
++	gint _tmp23_ = 0;
++	gchar* _tmp24_ = NULL;
++	gchar* _tmp25_ = NULL;
++	sqlite3_stmt* _tmp26_ = NULL;
++	const gchar* _tmp27_ = NULL;
++	GTimeVal tv = {0};
++	sqlite3_stmt* _tmp28_ = NULL;
++	gint _tmp29_ = 0;
++	GTimeVal _tmp30_ = {0};
++	gchar* _tmp31_ = NULL;
++	gchar* _tmp32_ = NULL;
++	sqlite3_stmt* _tmp33_ = NULL;
++	gint _tmp34_ = 0;
++	sqlite3_stmt* _tmp35_ = NULL;
++	gint _tmp36_ = 0;
++	sqlite3_stmt* _tmp37_ = NULL;
++	gint _tmp38_ = 0;
++	const gchar* _tmp39_ = NULL;
++	sqlite3_stmt* _tmp40_ = NULL;
++	const gchar* _tmp41_ = NULL;
++	GFile* file = NULL;
++	const gchar* _tmp42_ = NULL;
++	GFile* _tmp43_ = NULL;
++	gchar* _tmp44_ = NULL;
++	gchar* _tmp45_ = NULL;
++	self = (RygelLMSImageYear*) base;
++	g_return_val_if_fail (statement != NULL, NULL);
++	_tmp0_ = statement;
++	_tmp1_ = sqlite3_column_int (_tmp0_, 0);
++	id = _tmp1_;
++	_tmp2_ = statement;
++	_tmp3_ = sqlite3_column_text (_tmp2_, 6);
++	_tmp4_ = g_strdup (_tmp3_);
++	path = _tmp4_;
++	_tmp5_ = statement;
++	_tmp6_ = sqlite3_column_text (_tmp5_, 9);
++	_tmp7_ = g_strdup (_tmp6_);
++	mime_type = _tmp7_;
++	_tmp9_ = mime_type;
++	if (_tmp9_ == NULL) {
++		_tmp8_ = TRUE;
++	} else {
++		const gchar* _tmp10_ = NULL;
++		gint _tmp11_ = 0;
++		gint _tmp12_ = 0;
++		_tmp10_ = mime_type;
++		_tmp11_ = strlen (_tmp10_);
++		_tmp12_ = _tmp11_;
++		_tmp8_ = _tmp12_ == 0;
++	}
++	if (_tmp8_) {
++		gint _tmp13_ = 0;
++		const gchar* _tmp14_ = NULL;
++		_tmp13_ = id;
++		_tmp14_ = path;
++		g_debug ("rygel-lms-image-year.vala:62: Image item %d (%s) has no MIME type", _tmp13_, _tmp14_);
++	}
++	_tmp15_ = statement;
++	_tmp16_ = sqlite3_column_text (_tmp15_, 1);
++	_tmp17_ = g_strdup (_tmp16_);
++	title = _tmp17_;
++	_tmp18_ = id;
++	_tmp19_ = rygel_lms_category_container_build_child_id ((RygelLMSCategoryContainer*) self, _tmp18_);
++	_tmp20_ = _tmp19_;
++	_tmp21_ = rygel_image_item_new (_tmp20_, (RygelMediaContainer*) self, title, RYGEL_IMAGE_ITEM_UPNP_CLASS);
++	_tmp22_ = _tmp21_;
++	_g_free0 (_tmp20_);
++	image = _tmp22_;
++	_tmp23_ = id;
++	_tmp24_ = rygel_lms_category_container_build_reference_id ((RygelLMSCategoryContainer*) self, _tmp23_);
++	_tmp25_ = _tmp24_;
++	rygel_media_object_set_ref_id ((RygelMediaObject*) image, _tmp25_);
++	_g_free0 (_tmp25_);
++	_tmp26_ = statement;
++	_tmp27_ = sqlite3_column_text (_tmp26_, 2);
++	rygel_media_object_set_creator ((RygelMediaObject*) image, _tmp27_);
++	_tmp28_ = statement;
++	_tmp29_ = sqlite3_column_int (_tmp28_, 3);
++	_tmp30_.tv_sec = (glong) _tmp29_;
++	_tmp30_.tv_usec = (glong) 0;
++	tv = _tmp30_;
++	_tmp31_ = g_time_val_to_iso8601 (&tv);
++	_tmp32_ = _tmp31_;
++	rygel_media_object_set_date ((RygelMediaObject*) image, _tmp32_);
++	_g_free0 (_tmp32_);
++	_tmp33_ = statement;
++	_tmp34_ = sqlite3_column_int (_tmp33_, 4);
++	rygel_visual_item_set_width ((RygelVisualItem*) image, _tmp34_);
++	_tmp35_ = statement;
++	_tmp36_ = sqlite3_column_int (_tmp35_, 5);
++	rygel_visual_item_set_height ((RygelVisualItem*) image, _tmp36_);
++	_tmp37_ = statement;
++	_tmp38_ = sqlite3_column_int (_tmp37_, 7);
++	rygel_media_file_item_set_size ((RygelMediaFileItem*) image, (gint64) _tmp38_);
++	_tmp39_ = mime_type;
++	rygel_media_file_item_set_mime_type ((RygelMediaFileItem*) image, _tmp39_);
++	_tmp40_ = statement;
++	_tmp41_ = sqlite3_column_text (_tmp40_, 8);
++	rygel_media_file_item_set_dlna_profile ((RygelMediaFileItem*) image, _tmp41_);
++	_tmp42_ = path;
++	_tmp43_ = g_file_new_for_path (_tmp42_);
++	file = _tmp43_;
++	_tmp44_ = g_file_get_uri (file);
++	_tmp45_ = _tmp44_;
++	rygel_media_object_add_uri ((RygelMediaObject*) image, _tmp45_);
++	_g_free0 (_tmp45_);
++	result = (RygelMediaObject*) image;
++	_g_object_unref0 (file);
++	_g_free0 (title);
++	_g_free0 (mime_type);
++	_g_free0 (path);
++	return result;
++}
++
++
++static gchar* rygel_lms_image_year_get_sql_all (const gchar* year) {
++	gchar* result = NULL;
++	const gchar* _tmp0_ = NULL;
++	gchar* _tmp1_ = NULL;
++	g_return_val_if_fail (year != NULL, NULL);
++	_tmp0_ = year;
++	_tmp1_ = g_strdup_printf (RYGEL_LMS_IMAGE_YEAR_SQL_ALL_TEMPLATE, _tmp0_);
++	result = _tmp1_;
++	return result;
++}
++
++
++static gchar* rygel_lms_image_year_get_sql_find_object (const gchar* year) {
++	gchar* result = NULL;
++	const gchar* _tmp0_ = NULL;
++	gchar* _tmp1_ = NULL;
++	g_return_val_if_fail (year != NULL, NULL);
++	_tmp0_ = year;
++	_tmp1_ = g_strdup_printf (RYGEL_LMS_IMAGE_YEAR_SQL_FIND_OBJECT_TEMPLATE, _tmp0_);
++	result = _tmp1_;
++	return result;
++}
++
++
++static gchar* rygel_lms_image_year_get_sql_count (const gchar* year) {
++	gchar* result = NULL;
++	const gchar* _tmp0_ = NULL;
++	gchar* _tmp1_ = NULL;
++	g_return_val_if_fail (year != NULL, NULL);
++	_tmp0_ = year;
++	_tmp1_ = g_strdup_printf (RYGEL_LMS_IMAGE_YEAR_SQL_COUNT_TEMPLATE, _tmp0_);
++	result = _tmp1_;
++	return result;
++}
++
++
++static gchar* rygel_lms_image_year_get_sql_added (const gchar* year) {
++	gchar* result = NULL;
++	const gchar* _tmp0_ = NULL;
++	gchar* _tmp1_ = NULL;
++	g_return_val_if_fail (year != NULL, NULL);
++	_tmp0_ = year;
++	_tmp1_ = g_strdup_printf (RYGEL_LMS_IMAGE_YEAR_SQL_ADDED_TEMPLATE, _tmp0_);
++	result = _tmp1_;
++	return result;
++}
++
++
++static gchar* rygel_lms_image_year_get_sql_removed (const gchar* year) {
++	gchar* result = NULL;
++	const gchar* _tmp0_ = NULL;
++	gchar* _tmp1_ = NULL;
++	g_return_val_if_fail (year != NULL, NULL);
++	_tmp0_ = year;
++	_tmp1_ = g_strdup_printf (RYGEL_LMS_IMAGE_YEAR_SQL_REMOVED_TEMPLATE, _tmp0_);
++	result = _tmp1_;
++	return result;
++}
++
++
++RygelLMSImageYear* rygel_lms_image_year_construct (GType object_type, RygelMediaContainer* parent, const gchar* year, RygelLMSDatabase* lms_db) {
++	RygelLMSImageYear * self = NULL;
++	const gchar* _tmp0_ = NULL;
++	gchar* _tmp1_ = NULL;
++	gchar* _tmp2_ = NULL;
++	RygelMediaContainer* _tmp3_ = NULL;
++	const gchar* _tmp4_ = NULL;
++	RygelLMSDatabase* _tmp5_ = NULL;
++	const gchar* _tmp6_ = NULL;
++	gchar* _tmp7_ = NULL;
++	gchar* _tmp8_ = NULL;
++	const gchar* _tmp9_ = NULL;
++	gchar* _tmp10_ = NULL;
++	gchar* _tmp11_ = NULL;
++	const gchar* _tmp12_ = NULL;
++	gchar* _tmp13_ = NULL;
++	gchar* _tmp14_ = NULL;
++	const gchar* _tmp15_ = NULL;
++	gchar* _tmp16_ = NULL;
++	gchar* _tmp17_ = NULL;
++	const gchar* _tmp18_ = NULL;
++	gchar* _tmp19_ = NULL;
++	gchar* _tmp20_ = NULL;
++	g_return_val_if_fail (parent != NULL, NULL);
++	g_return_val_if_fail (year != NULL, NULL);
++	g_return_val_if_fail (lms_db != NULL, NULL);
++	_tmp0_ = year;
++	_tmp1_ = g_strdup_printf ("%s", _tmp0_);
++	_tmp2_ = _tmp1_;
++	_tmp3_ = parent;
++	_tmp4_ = year;
++	_tmp5_ = lms_db;
++	_tmp6_ = year;
++	_tmp7_ = rygel_lms_image_year_get_sql_all (_tmp6_);
++	_tmp8_ = _tmp7_;
++	_tmp9_ = year;
++	_tmp10_ = rygel_lms_image_year_get_sql_find_object (_tmp9_);
++	_tmp11_ = _tmp10_;
++	_tmp12_ = year;
++	_tmp13_ = rygel_lms_image_year_get_sql_count (_tmp12_);
++	_tmp14_ = _tmp13_;
++	_tmp15_ = year;
++	_tmp16_ = rygel_lms_image_year_get_sql_added (_tmp15_);
++	_tmp17_ = _tmp16_;
++	_tmp18_ = year;
++	_tmp19_ = rygel_lms_image_year_get_sql_removed (_tmp18_);
++	_tmp20_ = _tmp19_;
++	self = (RygelLMSImageYear*) rygel_lms_category_container_construct (object_type, _tmp2_, _tmp3_, _tmp4_, _tmp5_, _tmp8_, _tmp11_, _tmp14_, _tmp17_, _tmp20_);
++	_g_free0 (_tmp20_);
++	_g_free0 (_tmp17_);
++	_g_free0 (_tmp14_);
++	_g_free0 (_tmp11_);
++	_g_free0 (_tmp8_);
++	_g_free0 (_tmp2_);
++	return self;
++}
++
++
++RygelLMSImageYear* rygel_lms_image_year_new (RygelMediaContainer* parent, const gchar* year, RygelLMSDatabase* lms_db) {
++	return rygel_lms_image_year_construct (RYGEL_LMS_TYPE_IMAGE_YEAR, parent, year, lms_db);
++}
++
++
++static void rygel_lms_image_year_class_init (RygelLMSImageYearClass * klass) {
++	rygel_lms_image_year_parent_class = g_type_class_peek_parent (klass);
++	((RygelLMSCategoryContainerClass *) klass)->object_from_statement = rygel_lms_image_year_real_object_from_statement;
++}
++
++
++static void rygel_lms_image_year_instance_init (RygelLMSImageYear * self) {
++}
++
++
++GType rygel_lms_image_year_get_type (void) {
++	static volatile gsize rygel_lms_image_year_type_id__volatile = 0;
++	if (g_once_init_enter (&rygel_lms_image_year_type_id__volatile)) {
++		static const GTypeInfo g_define_type_info = { sizeof (RygelLMSImageYearClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) rygel_lms_image_year_class_init, (GClassFinalizeFunc) NULL, NULL, sizeof (RygelLMSImageYear), 0, (GInstanceInitFunc) rygel_lms_image_year_instance_init, NULL };
++		GType rygel_lms_image_year_type_id;
++		rygel_lms_image_year_type_id = g_type_register_static (RYGEL_LMS_TYPE_CATEGORY_CONTAINER, "RygelLMSImageYear", &g_define_type_info, 0);
++		g_once_init_leave (&rygel_lms_image_year_type_id__volatile, rygel_lms_image_year_type_id);
++	}
++	return rygel_lms_image_year_type_id__volatile;
++}
++
++
++
+diff --git a/src/plugins/lms/rygel-lms-image-years.c b/src/plugins/lms/rygel-lms-image-years.c
+new file mode 100644
+index 0000000..35033a0
+--- /dev/null
++++ b/src/plugins/lms/rygel-lms-image-years.c
+@@ -0,0 +1,196 @@
++/* rygel-lms-image-years.c generated by valac 0.28.0, the Vala compiler
++ * generated from rygel-lms-image-years.vala, do not modify */
++
++/*
++ * Copyright (C) 2013 Intel Corporation.
++ *
++ * Author: Jussi Kukkonen <jussi.kukkonen@intel.com>
++ *
++ * 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 <glib.h>
++#include <glib-object.h>
++#include <rygel-server.h>
++#include <sqlite3.h>
++#include <stdlib.h>
++#include <string.h>
++#include <glib/gi18n-lib.h>
++
++
++#define RYGEL_LMS_TYPE_CATEGORY_CONTAINER (rygel_lms_category_container_get_type ())
++#define RYGEL_LMS_CATEGORY_CONTAINER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), RYGEL_LMS_TYPE_CATEGORY_CONTAINER, RygelLMSCategoryContainer))
++#define RYGEL_LMS_CATEGORY_CONTAINER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), RYGEL_LMS_TYPE_CATEGORY_CONTAINER, RygelLMSCategoryContainerClass))
++#define RYGEL_LMS_IS_CATEGORY_CONTAINER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), RYGEL_LMS_TYPE_CATEGORY_CONTAINER))
++#define RYGEL_LMS_IS_CATEGORY_CONTAINER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), RYGEL_LMS_TYPE_CATEGORY_CONTAINER))
++#define RYGEL_LMS_CATEGORY_CONTAINER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), RYGEL_LMS_TYPE_CATEGORY_CONTAINER, RygelLMSCategoryContainerClass))
++
++typedef struct _RygelLMSCategoryContainer RygelLMSCategoryContainer;
++typedef struct _RygelLMSCategoryContainerClass RygelLMSCategoryContainerClass;
++typedef struct _RygelLMSCategoryContainerPrivate RygelLMSCategoryContainerPrivate;
++
++#define RYGEL_LMS_TYPE_IMAGE_YEARS (rygel_lms_image_years_get_type ())
++#define RYGEL_LMS_IMAGE_YEARS(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), RYGEL_LMS_TYPE_IMAGE_YEARS, RygelLMSImageYears))
++#define RYGEL_LMS_IMAGE_YEARS_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), RYGEL_LMS_TYPE_IMAGE_YEARS, RygelLMSImageYearsClass))
++#define RYGEL_LMS_IS_IMAGE_YEARS(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), RYGEL_LMS_TYPE_IMAGE_YEARS))
++#define RYGEL_LMS_IS_IMAGE_YEARS_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), RYGEL_LMS_TYPE_IMAGE_YEARS))
++#define RYGEL_LMS_IMAGE_YEARS_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), RYGEL_LMS_TYPE_IMAGE_YEARS, RygelLMSImageYearsClass))
++
++typedef struct _RygelLMSImageYears RygelLMSImageYears;
++typedef struct _RygelLMSImageYearsClass RygelLMSImageYearsClass;
++typedef struct _RygelLMSImageYearsPrivate RygelLMSImageYearsPrivate;
++
++#define RYGEL_LMS_TYPE_DATABASE (rygel_lms_database_get_type ())
++#define RYGEL_LMS_DATABASE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), RYGEL_LMS_TYPE_DATABASE, RygelLMSDatabase))
++#define RYGEL_LMS_DATABASE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), RYGEL_LMS_TYPE_DATABASE, RygelLMSDatabaseClass))
++#define RYGEL_LMS_IS_DATABASE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), RYGEL_LMS_TYPE_DATABASE))
++#define RYGEL_LMS_IS_DATABASE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), RYGEL_LMS_TYPE_DATABASE))
++#define RYGEL_LMS_DATABASE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), RYGEL_LMS_TYPE_DATABASE, RygelLMSDatabaseClass))
++
++typedef struct _RygelLMSDatabase RygelLMSDatabase;
++typedef struct _RygelLMSDatabaseClass RygelLMSDatabaseClass;
++
++#define RYGEL_LMS_TYPE_IMAGE_YEAR (rygel_lms_image_year_get_type ())
++#define RYGEL_LMS_IMAGE_YEAR(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), RYGEL_LMS_TYPE_IMAGE_YEAR, RygelLMSImageYear))
++#define RYGEL_LMS_IMAGE_YEAR_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), RYGEL_LMS_TYPE_IMAGE_YEAR, RygelLMSImageYearClass))
++#define RYGEL_LMS_IS_IMAGE_YEAR(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), RYGEL_LMS_TYPE_IMAGE_YEAR))
++#define RYGEL_LMS_IS_IMAGE_YEAR_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), RYGEL_LMS_TYPE_IMAGE_YEAR))
++#define RYGEL_LMS_IMAGE_YEAR_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), RYGEL_LMS_TYPE_IMAGE_YEAR, RygelLMSImageYearClass))
++
++typedef struct _RygelLMSImageYear RygelLMSImageYear;
++typedef struct _RygelLMSImageYearClass RygelLMSImageYearClass;
++
++struct _RygelLMSCategoryContainer {
++	RygelMediaContainer parent_instance;
++	RygelLMSCategoryContainerPrivate * priv;
++	sqlite3_stmt* stmt_all;
++	sqlite3_stmt* stmt_find_object;
++	sqlite3_stmt* stmt_added;
++	sqlite3_stmt* stmt_removed;
++	gchar* child_prefix;
++	gchar* ref_prefix;
++};
++
++struct _RygelLMSCategoryContainerClass {
++	RygelMediaContainerClass parent_class;
++	RygelMediaObject* (*object_from_statement) (RygelLMSCategoryContainer* self, sqlite3_stmt* statement);
++	gchar* (*get_sql_all_with_filter) (RygelLMSCategoryContainer* self, const gchar* filter);
++	gchar* (*get_sql_count_with_filter) (RygelLMSCategoryContainer* self, const gchar* filter);
++	guint (*get_child_count_with_filter) (RygelLMSCategoryContainer* self, const gchar* where_filter, GValueArray* args);
++	RygelMediaObjects* (*get_children_with_filter) (RygelLMSCategoryContainer* self, const gchar* where_filter, GValueArray* args, const gchar* sort_criteria, guint offset, guint max_count);
++};
++
++struct _RygelLMSImageYears {
++	RygelLMSCategoryContainer parent_instance;
++	RygelLMSImageYearsPrivate * priv;
++};
++
++struct _RygelLMSImageYearsClass {
++	RygelLMSCategoryContainerClass parent_class;
++};
++
++
++static gpointer rygel_lms_image_years_parent_class = NULL;
++
++GType rygel_lms_category_container_get_type (void) G_GNUC_CONST;
++GType rygel_lms_image_years_get_type (void) G_GNUC_CONST;
++enum  {
++	RYGEL_LMS_IMAGE_YEARS_DUMMY_PROPERTY
++};
++#define RYGEL_LMS_IMAGE_YEARS_SQL_ALL "SELECT DISTINCT(strftime('%Y', images.date, 'unixepoch')) as year " "FROM images " "LIMIT ? OFFSET ?;"
++#define RYGEL_LMS_IMAGE_YEARS_SQL_COUNT "SELECT COUNT(DISTINCT(strftime('%Y', images.date, 'unixepoch'))) " "FROM images;"
++#define RYGEL_LMS_IMAGE_YEARS_SQL_FIND_OBJECT "SELECT strftime('%Y', images.date, 'unixepoch') as year " "FROM images " "WHERE year = CAST(? AS TEXT)"
++static RygelMediaObject* rygel_lms_image_years_real_object_from_statement (RygelLMSCategoryContainer* base, sqlite3_stmt* statement);
++gpointer rygel_lms_database_ref (gpointer instance);
++void rygel_lms_database_unref (gpointer instance);
++GParamSpec* rygel_lms_param_spec_database (const gchar* name, const gchar* nick, const gchar* blurb, GType object_type, GParamFlags flags);
++void rygel_lms_value_set_database (GValue* value, gpointer v_object);
++void rygel_lms_value_take_database (GValue* value, gpointer v_object);
++gpointer rygel_lms_value_get_database (const GValue* value);
++GType rygel_lms_database_get_type (void) G_GNUC_CONST;
++RygelLMSDatabase* rygel_lms_category_container_get_lms_db (RygelLMSCategoryContainer* self);
++RygelLMSImageYear* rygel_lms_image_year_new (RygelMediaContainer* parent, const gchar* year, RygelLMSDatabase* lms_db);
++RygelLMSImageYear* rygel_lms_image_year_construct (GType object_type, RygelMediaContainer* parent, const gchar* year, RygelLMSDatabase* lms_db);
++GType rygel_lms_image_year_get_type (void) G_GNUC_CONST;
++RygelLMSImageYears* rygel_lms_image_years_new (RygelMediaContainer* parent, RygelLMSDatabase* lms_db);
++RygelLMSImageYears* rygel_lms_image_years_construct (GType object_type, RygelMediaContainer* parent, RygelLMSDatabase* lms_db);
++RygelLMSCategoryContainer* rygel_lms_category_container_construct (GType object_type, const gchar* db_id, RygelMediaContainer* parent, const gchar* title, RygelLMSDatabase* lms_db, const gchar* sql_all, const gchar* sql_find_object, const gchar* sql_count, const gchar* sql_added, const gchar* sql_removed);
++
++
++static RygelMediaObject* rygel_lms_image_years_real_object_from_statement (RygelLMSCategoryContainer* base, sqlite3_stmt* statement) {
++	RygelLMSImageYears * self;
++	RygelMediaObject* result = NULL;
++	sqlite3_stmt* _tmp0_ = NULL;
++	const gchar* _tmp1_ = NULL;
++	RygelLMSDatabase* _tmp2_ = NULL;
++	RygelLMSDatabase* _tmp3_ = NULL;
++	RygelLMSImageYear* _tmp4_ = NULL;
++	self = (RygelLMSImageYears*) base;
++	g_return_val_if_fail (statement != NULL, NULL);
++	_tmp0_ = statement;
++	_tmp1_ = sqlite3_column_text (_tmp0_, 0);
++	_tmp2_ = rygel_lms_category_container_get_lms_db ((RygelLMSCategoryContainer*) self);
++	_tmp3_ = _tmp2_;
++	_tmp4_ = rygel_lms_image_year_new ((RygelMediaContainer*) self, _tmp1_, _tmp3_);
++	result = (RygelMediaObject*) _tmp4_;
++	return result;
++}
++
++
++RygelLMSImageYears* rygel_lms_image_years_construct (GType object_type, RygelMediaContainer* parent, RygelLMSDatabase* lms_db) {
++	RygelLMSImageYears * self = NULL;
++	RygelMediaContainer* _tmp0_ = NULL;
++	const gchar* _tmp1_ = NULL;
++	RygelLMSDatabase* _tmp2_ = NULL;
++	g_return_val_if_fail (parent != NULL, NULL);
++	g_return_val_if_fail (lms_db != NULL, NULL);
++	_tmp0_ = parent;
++	_tmp1_ = _ ("Years");
++	_tmp2_ = lms_db;
++	self = (RygelLMSImageYears*) rygel_lms_category_container_construct (object_type, "years", _tmp0_, _tmp1_, _tmp2_, RYGEL_LMS_IMAGE_YEARS_SQL_ALL, RYGEL_LMS_IMAGE_YEARS_SQL_FIND_OBJECT, RYGEL_LMS_IMAGE_YEARS_SQL_COUNT, NULL, NULL);
++	return self;
++}
++
++
++RygelLMSImageYears* rygel_lms_image_years_new (RygelMediaContainer* parent, RygelLMSDatabase* lms_db) {
++	return rygel_lms_image_years_construct (RYGEL_LMS_TYPE_IMAGE_YEARS, parent, lms_db);
++}
++
++
++static void rygel_lms_image_years_class_init (RygelLMSImageYearsClass * klass) {
++	rygel_lms_image_years_parent_class = g_type_class_peek_parent (klass);
++	((RygelLMSCategoryContainerClass *) klass)->object_from_statement = rygel_lms_image_years_real_object_from_statement;
++}
++
++
++static void rygel_lms_image_years_instance_init (RygelLMSImageYears * self) {
++}
++
++
++GType rygel_lms_image_years_get_type (void) {
++	static volatile gsize rygel_lms_image_years_type_id__volatile = 0;
++	if (g_once_init_enter (&rygel_lms_image_years_type_id__volatile)) {
++		static const GTypeInfo g_define_type_info = { sizeof (RygelLMSImageYearsClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) rygel_lms_image_years_class_init, (GClassFinalizeFunc) NULL, NULL, sizeof (RygelLMSImageYears), 0, (GInstanceInitFunc) rygel_lms_image_years_instance_init, NULL };
++		GType rygel_lms_image_years_type_id;
++		rygel_lms_image_years_type_id = g_type_register_static (RYGEL_LMS_TYPE_CATEGORY_CONTAINER, "RygelLMSImageYears", &g_define_type_info, 0);
++		g_once_init_leave (&rygel_lms_image_years_type_id__volatile, rygel_lms_image_years_type_id);
++	}
++	return rygel_lms_image_years_type_id__volatile;
++}
++
++
++
+diff --git a/src/plugins/lms/rygel-lms-music-root.c b/src/plugins/lms/rygel-lms-music-root.c
+new file mode 100644
+index 0000000..753906d
+--- /dev/null
++++ b/src/plugins/lms/rygel-lms-music-root.c
+@@ -0,0 +1,202 @@
++/* rygel-lms-music-root.c generated by valac 0.28.0, the Vala compiler
++ * generated from rygel-lms-music-root.vala, do not modify */
++
++/*
++ * Copyright (C) 2013 Intel Corporation.
++ *
++ * Author: Jussi Kukkonen <jussi.kukkonen@intel.com>
++ *
++ * 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 <glib.h>
++#include <glib-object.h>
++#include <rygel-server.h>
++#include <stdlib.h>
++#include <string.h>
++#include <glib/gi18n-lib.h>
++
++
++#define RYGEL_LMS_TYPE_MUSIC_ROOT (rygel_lms_music_root_get_type ())
++#define RYGEL_LMS_MUSIC_ROOT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), RYGEL_LMS_TYPE_MUSIC_ROOT, RygelLMSMusicRoot))
++#define RYGEL_LMS_MUSIC_ROOT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), RYGEL_LMS_TYPE_MUSIC_ROOT, RygelLMSMusicRootClass))
++#define RYGEL_LMS_IS_MUSIC_ROOT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), RYGEL_LMS_TYPE_MUSIC_ROOT))
++#define RYGEL_LMS_IS_MUSIC_ROOT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), RYGEL_LMS_TYPE_MUSIC_ROOT))
++#define RYGEL_LMS_MUSIC_ROOT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), RYGEL_LMS_TYPE_MUSIC_ROOT, RygelLMSMusicRootClass))
++
++typedef struct _RygelLMSMusicRoot RygelLMSMusicRoot;
++typedef struct _RygelLMSMusicRootClass RygelLMSMusicRootClass;
++typedef struct _RygelLMSMusicRootPrivate RygelLMSMusicRootPrivate;
++
++#define RYGEL_LMS_TYPE_DATABASE (rygel_lms_database_get_type ())
++#define RYGEL_LMS_DATABASE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), RYGEL_LMS_TYPE_DATABASE, RygelLMSDatabase))
++#define RYGEL_LMS_DATABASE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), RYGEL_LMS_TYPE_DATABASE, RygelLMSDatabaseClass))
++#define RYGEL_LMS_IS_DATABASE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), RYGEL_LMS_TYPE_DATABASE))
++#define RYGEL_LMS_IS_DATABASE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), RYGEL_LMS_TYPE_DATABASE))
++#define RYGEL_LMS_DATABASE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), RYGEL_LMS_TYPE_DATABASE, RygelLMSDatabaseClass))
++
++typedef struct _RygelLMSDatabase RygelLMSDatabase;
++typedef struct _RygelLMSDatabaseClass RygelLMSDatabaseClass;
++
++#define RYGEL_LMS_TYPE_CATEGORY_CONTAINER (rygel_lms_category_container_get_type ())
++#define RYGEL_LMS_CATEGORY_CONTAINER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), RYGEL_LMS_TYPE_CATEGORY_CONTAINER, RygelLMSCategoryContainer))
++#define RYGEL_LMS_CATEGORY_CONTAINER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), RYGEL_LMS_TYPE_CATEGORY_CONTAINER, RygelLMSCategoryContainerClass))
++#define RYGEL_LMS_IS_CATEGORY_CONTAINER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), RYGEL_LMS_TYPE_CATEGORY_CONTAINER))
++#define RYGEL_LMS_IS_CATEGORY_CONTAINER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), RYGEL_LMS_TYPE_CATEGORY_CONTAINER))
++#define RYGEL_LMS_CATEGORY_CONTAINER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), RYGEL_LMS_TYPE_CATEGORY_CONTAINER, RygelLMSCategoryContainerClass))
++
++typedef struct _RygelLMSCategoryContainer RygelLMSCategoryContainer;
++typedef struct _RygelLMSCategoryContainerClass RygelLMSCategoryContainerClass;
++
++#define RYGEL_LMS_TYPE_ALL_MUSIC (rygel_lms_all_music_get_type ())
++#define RYGEL_LMS_ALL_MUSIC(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), RYGEL_LMS_TYPE_ALL_MUSIC, RygelLMSAllMusic))
++#define RYGEL_LMS_ALL_MUSIC_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), RYGEL_LMS_TYPE_ALL_MUSIC, RygelLMSAllMusicClass))
++#define RYGEL_LMS_IS_ALL_MUSIC(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), RYGEL_LMS_TYPE_ALL_MUSIC))
++#define RYGEL_LMS_IS_ALL_MUSIC_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), RYGEL_LMS_TYPE_ALL_MUSIC))
++#define RYGEL_LMS_ALL_MUSIC_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), RYGEL_LMS_TYPE_ALL_MUSIC, RygelLMSAllMusicClass))
++
++typedef struct _RygelLMSAllMusic RygelLMSAllMusic;
++typedef struct _RygelLMSAllMusicClass RygelLMSAllMusicClass;
++#define _g_object_unref0(var) ((var == NULL) ? NULL : (var = (g_object_unref (var), NULL)))
++
++#define RYGEL_LMS_TYPE_ARTISTS (rygel_lms_artists_get_type ())
++#define RYGEL_LMS_ARTISTS(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), RYGEL_LMS_TYPE_ARTISTS, RygelLMSArtists))
++#define RYGEL_LMS_ARTISTS_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), RYGEL_LMS_TYPE_ARTISTS, RygelLMSArtistsClass))
++#define RYGEL_LMS_IS_ARTISTS(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), RYGEL_LMS_TYPE_ARTISTS))
++#define RYGEL_LMS_IS_ARTISTS_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), RYGEL_LMS_TYPE_ARTISTS))
++#define RYGEL_LMS_ARTISTS_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), RYGEL_LMS_TYPE_ARTISTS, RygelLMSArtistsClass))
++
++typedef struct _RygelLMSArtists RygelLMSArtists;
++typedef struct _RygelLMSArtistsClass RygelLMSArtistsClass;
++
++#define RYGEL_LMS_TYPE_ALBUMS (rygel_lms_albums_get_type ())
++#define RYGEL_LMS_ALBUMS(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), RYGEL_LMS_TYPE_ALBUMS, RygelLMSAlbums))
++#define RYGEL_LMS_ALBUMS_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), RYGEL_LMS_TYPE_ALBUMS, RygelLMSAlbumsClass))
++#define RYGEL_LMS_IS_ALBUMS(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), RYGEL_LMS_TYPE_ALBUMS))
++#define RYGEL_LMS_IS_ALBUMS_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), RYGEL_LMS_TYPE_ALBUMS))
++#define RYGEL_LMS_ALBUMS_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), RYGEL_LMS_TYPE_ALBUMS, RygelLMSAlbumsClass))
++
++typedef struct _RygelLMSAlbums RygelLMSAlbums;
++typedef struct _RygelLMSAlbumsClass RygelLMSAlbumsClass;
++
++struct _RygelLMSMusicRoot {
++	RygelSimpleContainer parent_instance;
++	RygelLMSMusicRootPrivate * priv;
++};
++
++struct _RygelLMSMusicRootClass {
++	RygelSimpleContainerClass parent_class;
++};
++
++
++static gpointer rygel_lms_music_root_parent_class = NULL;
++
++GType rygel_lms_music_root_get_type (void) G_GNUC_CONST;
++enum  {
++	RYGEL_LMS_MUSIC_ROOT_DUMMY_PROPERTY
++};
++gpointer rygel_lms_database_ref (gpointer instance);
++void rygel_lms_database_unref (gpointer instance);
++GParamSpec* rygel_lms_param_spec_database (const gchar* name, const gchar* nick, const gchar* blurb, GType object_type, GParamFlags flags);
++void rygel_lms_value_set_database (GValue* value, gpointer v_object);
++void rygel_lms_value_take_database (GValue* value, gpointer v_object);
++gpointer rygel_lms_value_get_database (const GValue* value);
++GType rygel_lms_database_get_type (void) G_GNUC_CONST;
++RygelLMSMusicRoot* rygel_lms_music_root_new (const gchar* id, RygelMediaContainer* parent, const gchar* title, RygelLMSDatabase* lms_db);
++RygelLMSMusicRoot* rygel_lms_music_root_construct (GType object_type, const gchar* id, RygelMediaContainer* parent, const gchar* title, RygelLMSDatabase* lms_db);
++RygelLMSAllMusic* rygel_lms_all_music_new (RygelMediaContainer* parent, RygelLMSDatabase* lms_db);
++RygelLMSAllMusic* rygel_lms_all_music_construct (GType object_type, RygelMediaContainer* parent, RygelLMSDatabase* lms_db);
++GType rygel_lms_category_container_get_type (void) G_GNUC_CONST;
++GType rygel_lms_all_music_get_type (void) G_GNUC_CONST;
++RygelLMSArtists* rygel_lms_artists_new (const gchar* id, RygelMediaContainer* parent, const gchar* title, RygelLMSDatabase* lms_db);
++RygelLMSArtists* rygel_lms_artists_construct (GType object_type, const gchar* id, RygelMediaContainer* parent, const gchar* title, RygelLMSDatabase* lms_db);
++GType rygel_lms_artists_get_type (void) G_GNUC_CONST;
++RygelLMSAlbums* rygel_lms_albums_new (RygelMediaContainer* parent, RygelLMSDatabase* lms_db);
++RygelLMSAlbums* rygel_lms_albums_construct (GType object_type, RygelMediaContainer* parent, RygelLMSDatabase* lms_db);
++GType rygel_lms_albums_get_type (void) G_GNUC_CONST;
++
++
++RygelLMSMusicRoot* rygel_lms_music_root_construct (GType object_type, const gchar* id, RygelMediaContainer* parent, const gchar* title, RygelLMSDatabase* lms_db) {
++	RygelLMSMusicRoot * self = NULL;
++	const gchar* _tmp0_ = NULL;
++	RygelMediaContainer* _tmp1_ = NULL;
++	const gchar* _tmp2_ = NULL;
++	RygelLMSDatabase* _tmp3_ = NULL;
++	RygelLMSAllMusic* _tmp4_ = NULL;
++	RygelLMSAllMusic* _tmp5_ = NULL;
++	const gchar* _tmp6_ = NULL;
++	RygelLMSDatabase* _tmp7_ = NULL;
++	RygelLMSArtists* _tmp8_ = NULL;
++	RygelLMSArtists* _tmp9_ = NULL;
++	RygelLMSDatabase* _tmp10_ = NULL;
++	RygelLMSAlbums* _tmp11_ = NULL;
++	RygelLMSAlbums* _tmp12_ = NULL;
++	g_return_val_if_fail (id != NULL, NULL);
++	g_return_val_if_fail (parent != NULL, NULL);
++	g_return_val_if_fail (title != NULL, NULL);
++	g_return_val_if_fail (lms_db != NULL, NULL);
++	_tmp0_ = id;
++	_tmp1_ = parent;
++	_tmp2_ = title;
++	self = (RygelLMSMusicRoot*) rygel_simple_container_construct (object_type, _tmp0_, _tmp1_, _tmp2_);
++	_tmp3_ = lms_db;
++	_tmp4_ = rygel_lms_all_music_new ((RygelMediaContainer*) self, _tmp3_);
++	_tmp5_ = _tmp4_;
++	rygel_simple_container_add_child_container ((RygelSimpleContainer*) self, (RygelMediaContainer*) _tmp5_);
++	_g_object_unref0 (_tmp5_);
++	_tmp6_ = _ ("Artists");
++	_tmp7_ = lms_db;
++	_tmp8_ = rygel_lms_artists_new ("artists", (RygelMediaContainer*) self, _tmp6_, _tmp7_);
++	_tmp9_ = _tmp8_;
++	rygel_simple_container_add_child_container ((RygelSimpleContainer*) self, (RygelMediaContainer*) _tmp9_);
++	_g_object_unref0 (_tmp9_);
++	_tmp10_ = lms_db;
++	_tmp11_ = rygel_lms_albums_new ((RygelMediaContainer*) self, _tmp10_);
++	_tmp12_ = _tmp11_;
++	rygel_simple_container_add_child_container ((RygelSimpleContainer*) self, (RygelMediaContainer*) _tmp12_);
++	_g_object_unref0 (_tmp12_);
++	return self;
++}
++
++
++RygelLMSMusicRoot* rygel_lms_music_root_new (const gchar* id, RygelMediaContainer* parent, const gchar* title, RygelLMSDatabase* lms_db) {
++	return rygel_lms_music_root_construct (RYGEL_LMS_TYPE_MUSIC_ROOT, id, parent, title, lms_db);
++}
++
++
++static void rygel_lms_music_root_class_init (RygelLMSMusicRootClass * klass) {
++	rygel_lms_music_root_parent_class = g_type_class_peek_parent (klass);
++}
++
++
++static void rygel_lms_music_root_instance_init (RygelLMSMusicRoot * self) {
++}
++
++
++GType rygel_lms_music_root_get_type (void) {
++	static volatile gsize rygel_lms_music_root_type_id__volatile = 0;
++	if (g_once_init_enter (&rygel_lms_music_root_type_id__volatile)) {
++		static const GTypeInfo g_define_type_info = { sizeof (RygelLMSMusicRootClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) rygel_lms_music_root_class_init, (GClassFinalizeFunc) NULL, NULL, sizeof (RygelLMSMusicRoot), 0, (GInstanceInitFunc) rygel_lms_music_root_instance_init, NULL };
++		GType rygel_lms_music_root_type_id;
++		rygel_lms_music_root_type_id = g_type_register_static (RYGEL_TYPE_SIMPLE_CONTAINER, "RygelLMSMusicRoot", &g_define_type_info, 0);
++		g_once_init_leave (&rygel_lms_music_root_type_id__volatile, rygel_lms_music_root_type_id);
++	}
++	return rygel_lms_music_root_type_id__volatile;
++}
++
++
++
+diff --git a/src/plugins/lms/rygel-lms-plugin-factory.c b/src/plugins/lms/rygel-lms-plugin-factory.c
+new file mode 100644
+index 0000000..de4a5ab
+--- /dev/null
++++ b/src/plugins/lms/rygel-lms-plugin-factory.c
+@@ -0,0 +1,307 @@
++/* rygel-lms-plugin-factory.c generated by valac 0.28.0, the Vala compiler
++ * generated from rygel-lms-plugin-factory.vala, do not modify */
++
++/*
++ * Copyright (C) 2013 Intel Corporation.
++ *
++ * Author: Jussi Kukkonen <jussi.kukkonen@intel.com>
++ *
++ * 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 <glib.h>
++#include <glib-object.h>
++#include <rygel-core.h>
++#include <rygel-server.h>
++#include <gobject/gvaluecollector.h>
++
++
++#define RYGEL_LMS_TYPE_PLUGIN_FACTORY (rygel_lms_plugin_factory_get_type ())
++#define RYGEL_LMS_PLUGIN_FACTORY(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), RYGEL_LMS_TYPE_PLUGIN_FACTORY, RygelLMSPluginFactory))
++#define RYGEL_LMS_PLUGIN_FACTORY_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), RYGEL_LMS_TYPE_PLUGIN_FACTORY, RygelLMSPluginFactoryClass))
++#define RYGEL_LMS_IS_PLUGIN_FACTORY(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), RYGEL_LMS_TYPE_PLUGIN_FACTORY))
++#define RYGEL_LMS_IS_PLUGIN_FACTORY_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), RYGEL_LMS_TYPE_PLUGIN_FACTORY))
++#define RYGEL_LMS_PLUGIN_FACTORY_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), RYGEL_LMS_TYPE_PLUGIN_FACTORY, RygelLMSPluginFactoryClass))
++
++typedef struct _RygelLMSPluginFactory RygelLMSPluginFactory;
++typedef struct _RygelLMSPluginFactoryClass RygelLMSPluginFactoryClass;
++#define _rygel_lms_plugin_factory_unref0(var) ((var == NULL) ? NULL : (var = (rygel_lms_plugin_factory_unref (var), NULL)))
++typedef struct _RygelLMSPluginFactoryPrivate RygelLMSPluginFactoryPrivate;
++#define _g_object_unref0(var) ((var == NULL) ? NULL : (var = (g_object_unref (var), NULL)))
++
++#define RYGEL_LMS_TYPE_PLUGIN (rygel_lms_plugin_get_type ())
++#define RYGEL_LMS_PLUGIN(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), RYGEL_LMS_TYPE_PLUGIN, RygelLMSPlugin))
++#define RYGEL_LMS_PLUGIN_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), RYGEL_LMS_TYPE_PLUGIN, RygelLMSPluginClass))
++#define RYGEL_LMS_IS_PLUGIN(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), RYGEL_LMS_TYPE_PLUGIN))
++#define RYGEL_LMS_IS_PLUGIN_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), RYGEL_LMS_TYPE_PLUGIN))
++#define RYGEL_LMS_PLUGIN_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), RYGEL_LMS_TYPE_PLUGIN, RygelLMSPluginClass))
++
++typedef struct _RygelLMSPlugin RygelLMSPlugin;
++typedef struct _RygelLMSPluginClass RygelLMSPluginClass;
++typedef struct _RygelLMSParamSpecPluginFactory RygelLMSParamSpecPluginFactory;
++
++struct _RygelLMSPluginFactory {
++	GTypeInstance parent_instance;
++	volatile int ref_count;
++	RygelLMSPluginFactoryPrivate * priv;
++};
++
++struct _RygelLMSPluginFactoryClass {
++	GTypeClass parent_class;
++	void (*finalize) (RygelLMSPluginFactory *self);
++};
++
++struct _RygelLMSPluginFactoryPrivate {
++	RygelPluginLoader* loader;
++};
++
++struct _RygelLMSParamSpecPluginFactory {
++	GParamSpec parent_instance;
++};
++
++
++extern RygelLMSPluginFactory* plugin_factory;
++RygelLMSPluginFactory* plugin_factory = NULL;
++static gpointer rygel_lms_plugin_factory_parent_class = NULL;
++
++gpointer rygel_lms_plugin_factory_ref (gpointer instance);
++void rygel_lms_plugin_factory_unref (gpointer instance);
++GParamSpec* rygel_lms_param_spec_plugin_factory (const gchar* name, const gchar* nick, const gchar* blurb, GType object_type, GParamFlags flags);
++void rygel_lms_value_set_plugin_factory (GValue* value, gpointer v_object);
++void rygel_lms_value_take_plugin_factory (GValue* value, gpointer v_object);
++gpointer rygel_lms_value_get_plugin_factory (const GValue* value);
++GType rygel_lms_plugin_factory_get_type (void) G_GNUC_CONST;
++void module_init (RygelPluginLoader* loader);
++RygelLMSPluginFactory* rygel_lms_plugin_factory_new (RygelPluginLoader* loader);
++RygelLMSPluginFactory* rygel_lms_plugin_factory_construct (GType object_type, RygelPluginLoader* loader);
++#define RYGEL_LMS_PLUGIN_FACTORY_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), RYGEL_LMS_TYPE_PLUGIN_FACTORY, RygelLMSPluginFactoryPrivate))
++enum  {
++	RYGEL_LMS_PLUGIN_FACTORY_DUMMY_PROPERTY
++};
++RygelLMSPlugin* rygel_lms_plugin_new (void);
++RygelLMSPlugin* rygel_lms_plugin_construct (GType object_type);
++GType rygel_lms_plugin_get_type (void) G_GNUC_CONST;
++static void rygel_lms_plugin_factory_finalize (RygelLMSPluginFactory* obj);
++
++
++void module_init (RygelPluginLoader* loader) {
++	RygelPluginLoader* _tmp0_ = NULL;
++	RygelLMSPluginFactory* _tmp1_ = NULL;
++	g_return_if_fail (loader != NULL);
++	_tmp0_ = loader;
++	_tmp1_ = rygel_lms_plugin_factory_new (_tmp0_);
++	_rygel_lms_plugin_factory_unref0 (plugin_factory);
++	plugin_factory = _tmp1_;
++}
++
++
++static gpointer _g_object_ref0 (gpointer self) {
++	return self ? g_object_ref (self) : NULL;
++}
++
++
++RygelLMSPluginFactory* rygel_lms_plugin_factory_construct (GType object_type, RygelPluginLoader* loader) {
++	RygelLMSPluginFactory* self = NULL;
++	RygelPluginLoader* _tmp0_ = NULL;
++	RygelPluginLoader* _tmp1_ = NULL;
++	RygelPluginLoader* _tmp2_ = NULL;
++	RygelLMSPlugin* _tmp3_ = NULL;
++	RygelLMSPlugin* _tmp4_ = NULL;
++	g_return_val_if_fail (loader != NULL, NULL);
++	self = (RygelLMSPluginFactory*) g_type_create_instance (object_type);
++	_tmp0_ = loader;
++	_tmp1_ = _g_object_ref0 (_tmp0_);
++	_g_object_unref0 (self->priv->loader);
++	self->priv->loader = _tmp1_;
++	_tmp2_ = self->priv->loader;
++	_tmp3_ = rygel_lms_plugin_new ();
++	_tmp4_ = _tmp3_;
++	rygel_plugin_loader_add_plugin (_tmp2_, (RygelPlugin*) _tmp4_);
++	_g_object_unref0 (_tmp4_);
++	return self;
++}
++
++
++RygelLMSPluginFactory* rygel_lms_plugin_factory_new (RygelPluginLoader* loader) {
++	return rygel_lms_plugin_factory_construct (RYGEL_LMS_TYPE_PLUGIN_FACTORY, loader);
++}
++
++
++static void rygel_lms_value_plugin_factory_init (GValue* value) {
++	value->data[0].v_pointer = NULL;
++}
++
++
++static void rygel_lms_value_plugin_factory_free_value (GValue* value) {
++	if (value->data[0].v_pointer) {
++		rygel_lms_plugin_factory_unref (value->data[0].v_pointer);
++	}
++}
++
++
++static void rygel_lms_value_plugin_factory_copy_value (const GValue* src_value, GValue* dest_value) {
++	if (src_value->data[0].v_pointer) {
++		dest_value->data[0].v_pointer = rygel_lms_plugin_factory_ref (src_value->data[0].v_pointer);
++	} else {
++		dest_value->data[0].v_pointer = NULL;
++	}
++}
++
++
++static gpointer rygel_lms_value_plugin_factory_peek_pointer (const GValue* value) {
++	return value->data[0].v_pointer;
++}
++
++
++static gchar* rygel_lms_value_plugin_factory_collect_value (GValue* value, guint n_collect_values, GTypeCValue* collect_values, guint collect_flags) {
++	if (collect_values[0].v_pointer) {
++		RygelLMSPluginFactory* object;
++		object = collect_values[0].v_pointer;
++		if (object->parent_instance.g_class == NULL) {
++			return g_strconcat ("invalid unclassed object pointer for value type `", G_VALUE_TYPE_NAME (value), "'", NULL);
++		} else if (!g_value_type_compatible (G_TYPE_FROM_INSTANCE (object), G_VALUE_TYPE (value))) {
++			return g_strconcat ("invalid object type `", g_type_name (G_TYPE_FROM_INSTANCE (object)), "' for value type `", G_VALUE_TYPE_NAME (value), "'", NULL);
++		}
++		value->data[0].v_pointer = rygel_lms_plugin_factory_ref (object);
++	} else {
++		value->data[0].v_pointer = NULL;
++	}
++	return NULL;
++}
++
++
++static gchar* rygel_lms_value_plugin_factory_lcopy_value (const GValue* value, guint n_collect_values, GTypeCValue* collect_values, guint collect_flags) {
++	RygelLMSPluginFactory** object_p;
++	object_p = collect_values[0].v_pointer;
++	if (!object_p) {
++		return g_strdup_printf ("value location for `%s' passed as NULL", G_VALUE_TYPE_NAME (value));
++	}
++	if (!value->data[0].v_pointer) {
++		*object_p = NULL;
++	} else if (collect_flags & G_VALUE_NOCOPY_CONTENTS) {
++		*object_p = value->data[0].v_pointer;
++	} else {
++		*object_p = rygel_lms_plugin_factory_ref (value->data[0].v_pointer);
++	}
++	return NULL;
++}
++
++
++GParamSpec* rygel_lms_param_spec_plugin_factory (const gchar* name, const gchar* nick, const gchar* blurb, GType object_type, GParamFlags flags) {
++	RygelLMSParamSpecPluginFactory* spec;
++	g_return_val_if_fail (g_type_is_a (object_type, RYGEL_LMS_TYPE_PLUGIN_FACTORY), NULL);
++	spec = g_param_spec_internal (G_TYPE_PARAM_OBJECT, name, nick, blurb, flags);
++	G_PARAM_SPEC (spec)->value_type = object_type;
++	return G_PARAM_SPEC (spec);
++}
++
++
++gpointer rygel_lms_value_get_plugin_factory (const GValue* value) {
++	g_return_val_if_fail (G_TYPE_CHECK_VALUE_TYPE (value, RYGEL_LMS_TYPE_PLUGIN_FACTORY), NULL);
++	return value->data[0].v_pointer;
++}
++
++
++void rygel_lms_value_set_plugin_factory (GValue* value, gpointer v_object) {
++	RygelLMSPluginFactory* old;
++	g_return_if_fail (G_TYPE_CHECK_VALUE_TYPE (value, RYGEL_LMS_TYPE_PLUGIN_FACTORY));
++	old = value->data[0].v_pointer;
++	if (v_object) {
++		g_return_if_fail (G_TYPE_CHECK_INSTANCE_TYPE (v_object, RYGEL_LMS_TYPE_PLUGIN_FACTORY));
++		g_return_if_fail (g_value_type_compatible (G_TYPE_FROM_INSTANCE (v_object), G_VALUE_TYPE (value)));
++		value->data[0].v_pointer = v_object;
++		rygel_lms_plugin_factory_ref (value->data[0].v_pointer);
++	} else {
++		value->data[0].v_pointer = NULL;
++	}
++	if (old) {
++		rygel_lms_plugin_factory_unref (old);
++	}
++}
++
++
++void rygel_lms_value_take_plugin_factory (GValue* value, gpointer v_object) {
++	RygelLMSPluginFactory* old;
++	g_return_if_fail (G_TYPE_CHECK_VALUE_TYPE (value, RYGEL_LMS_TYPE_PLUGIN_FACTORY));
++	old = value->data[0].v_pointer;
++	if (v_object) {
++		g_return_if_fail (G_TYPE_CHECK_INSTANCE_TYPE (v_object, RYGEL_LMS_TYPE_PLUGIN_FACTORY));
++		g_return_if_fail (g_value_type_compatible (G_TYPE_FROM_INSTANCE (v_object), G_VALUE_TYPE (value)));
++		value->data[0].v_pointer = v_object;
++	} else {
++		value->data[0].v_pointer = NULL;
++	}
++	if (old) {
++		rygel_lms_plugin_factory_unref (old);
++	}
++}
++
++
++static void rygel_lms_plugin_factory_class_init (RygelLMSPluginFactoryClass * klass) {
++	rygel_lms_plugin_factory_parent_class = g_type_class_peek_parent (klass);
++	((RygelLMSPluginFactoryClass *) klass)->finalize = rygel_lms_plugin_factory_finalize;
++	g_type_class_add_private (klass, sizeof (RygelLMSPluginFactoryPrivate));
++}
++
++
++static void rygel_lms_plugin_factory_instance_init (RygelLMSPluginFactory * self) {
++	self->priv = RYGEL_LMS_PLUGIN_FACTORY_GET_PRIVATE (self);
++	self->ref_count = 1;
++}
++
++
++static void rygel_lms_plugin_factory_finalize (RygelLMSPluginFactory* obj) {
++	RygelLMSPluginFactory * self;
++	self = G_TYPE_CHECK_INSTANCE_CAST (obj, RYGEL_LMS_TYPE_PLUGIN_FACTORY, RygelLMSPluginFactory);
++	g_signal_handlers_destroy (self);
++	_g_object_unref0 (self->priv->loader);
++}
++
++
++GType rygel_lms_plugin_factory_get_type (void) {
++	static volatile gsize rygel_lms_plugin_factory_type_id__volatile = 0;
++	if (g_once_init_enter (&rygel_lms_plugin_factory_type_id__volatile)) {
++		static const GTypeValueTable g_define_type_value_table = { rygel_lms_value_plugin_factory_init, rygel_lms_value_plugin_factory_free_value, rygel_lms_value_plugin_factory_copy_value, rygel_lms_value_plugin_factory_peek_pointer, "p", rygel_lms_value_plugin_factory_collect_value, "p", rygel_lms_value_plugin_factory_lcopy_value };
++		static const GTypeInfo g_define_type_info = { sizeof (RygelLMSPluginFactoryClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) rygel_lms_plugin_factory_class_init, (GClassFinalizeFunc) NULL, NULL, sizeof (RygelLMSPluginFactory), 0, (GInstanceInitFunc) rygel_lms_plugin_factory_instance_init, &g_define_type_value_table };
++		static const GTypeFundamentalInfo g_define_type_fundamental_info = { (G_TYPE_FLAG_CLASSED | G_TYPE_FLAG_INSTANTIATABLE | G_TYPE_FLAG_DERIVABLE | G_TYPE_FLAG_DEEP_DERIVABLE) };
++		GType rygel_lms_plugin_factory_type_id;
++		rygel_lms_plugin_factory_type_id = g_type_register_fundamental (g_type_fundamental_next (), "RygelLMSPluginFactory", &g_define_type_info, &g_define_type_fundamental_info, 0);
++		g_once_init_leave (&rygel_lms_plugin_factory_type_id__volatile, rygel_lms_plugin_factory_type_id);
++	}
++	return rygel_lms_plugin_factory_type_id__volatile;
++}
++
++
++gpointer rygel_lms_plugin_factory_ref (gpointer instance) {
++	RygelLMSPluginFactory* self;
++	self = instance;
++	g_atomic_int_inc (&self->ref_count);
++	return instance;
++}
++
++
++void rygel_lms_plugin_factory_unref (gpointer instance) {
++	RygelLMSPluginFactory* self;
++	self = instance;
++	if (g_atomic_int_dec_and_test (&self->ref_count)) {
++		RYGEL_LMS_PLUGIN_FACTORY_GET_CLASS (self)->finalize (self);
++		g_type_free_instance ((GTypeInstance *) self);
++	}
++}
++
++
++
+diff --git a/src/plugins/lms/rygel-lms-plugin.c b/src/plugins/lms/rygel-lms-plugin.c
+new file mode 100644
+index 0000000..980de64
+--- /dev/null
++++ b/src/plugins/lms/rygel-lms-plugin.c
+@@ -0,0 +1,134 @@
++/* rygel-lms-plugin.c generated by valac 0.28.0, the Vala compiler
++ * generated from rygel-lms-plugin.vala, do not modify */
++
++/*
++ * Copyright (C) 2013 Intel Corporation.
++ *
++ * Author: Jussi Kukkonen <jussi.kukkonen@intel.com>
++ *
++ * 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 <glib.h>
++#include <glib-object.h>
++#include <rygel-server.h>
++#include <stdlib.h>
++#include <string.h>
++#include <rygel-core.h>
++
++
++#define RYGEL_LMS_TYPE_PLUGIN (rygel_lms_plugin_get_type ())
++#define RYGEL_LMS_PLUGIN(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), RYGEL_LMS_TYPE_PLUGIN, RygelLMSPlugin))
++#define RYGEL_LMS_PLUGIN_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), RYGEL_LMS_TYPE_PLUGIN, RygelLMSPluginClass))
++#define RYGEL_LMS_IS_PLUGIN(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), RYGEL_LMS_TYPE_PLUGIN))
++#define RYGEL_LMS_IS_PLUGIN_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), RYGEL_LMS_TYPE_PLUGIN))
++#define RYGEL_LMS_PLUGIN_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), RYGEL_LMS_TYPE_PLUGIN, RygelLMSPluginClass))
++
++typedef struct _RygelLMSPlugin RygelLMSPlugin;
++typedef struct _RygelLMSPluginClass RygelLMSPluginClass;
++typedef struct _RygelLMSPluginPrivate RygelLMSPluginPrivate;
++
++#define RYGEL_LMS_TYPE_ROOT_CONTAINER (rygel_lms_root_container_get_type ())
++#define RYGEL_LMS_ROOT_CONTAINER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), RYGEL_LMS_TYPE_ROOT_CONTAINER, RygelLMSRootContainer))
++#define RYGEL_LMS_ROOT_CONTAINER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), RYGEL_LMS_TYPE_ROOT_CONTAINER, RygelLMSRootContainerClass))
++#define RYGEL_LMS_IS_ROOT_CONTAINER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), RYGEL_LMS_TYPE_ROOT_CONTAINER))
++#define RYGEL_LMS_IS_ROOT_CONTAINER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), RYGEL_LMS_TYPE_ROOT_CONTAINER))
++#define RYGEL_LMS_ROOT_CONTAINER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), RYGEL_LMS_TYPE_ROOT_CONTAINER, RygelLMSRootContainerClass))
++
++typedef struct _RygelLMSRootContainer RygelLMSRootContainer;
++typedef struct _RygelLMSRootContainerClass RygelLMSRootContainerClass;
++#define _g_object_unref0(var) ((var == NULL) ? NULL : (var = (g_object_unref (var), NULL)))
++
++struct _RygelLMSPlugin {
++	RygelMediaServerPlugin parent_instance;
++	RygelLMSPluginPrivate * priv;
++};
++
++struct _RygelLMSPluginClass {
++	RygelMediaServerPluginClass parent_class;
++};
++
++
++static gpointer rygel_lms_plugin_parent_class = NULL;
++static RygelLMSRootContainer* rygel_lms_plugin_root;
++static RygelLMSRootContainer* rygel_lms_plugin_root = NULL;
++
++GType rygel_lms_plugin_get_type (void) G_GNUC_CONST;
++enum  {
++	RYGEL_LMS_PLUGIN_DUMMY_PROPERTY
++};
++GType rygel_lms_root_container_get_type (void) G_GNUC_CONST;
++#define RYGEL_LMS_PLUGIN_NAME "LMS"
++RygelLMSPlugin* rygel_lms_plugin_new (void);
++RygelLMSPlugin* rygel_lms_plugin_construct (GType object_type);
++RygelLMSRootContainer* rygel_lms_root_container_new (void);
++RygelLMSRootContainer* rygel_lms_root_container_construct (GType object_type);
++static void rygel_lms_plugin_finalize (GObject* obj);
++
++
++RygelLMSPlugin* rygel_lms_plugin_construct (GType object_type) {
++	RygelLMSPlugin * self = NULL;
++	RygelLMSRootContainer* _tmp0_ = NULL;
++	RygelLMSRootContainer* _tmp2_ = NULL;
++	_tmp0_ = rygel_lms_plugin_root;
++	if (_tmp0_ == NULL) {
++		RygelLMSRootContainer* _tmp1_ = NULL;
++		_tmp1_ = rygel_lms_root_container_new ();
++		_g_object_unref0 (rygel_lms_plugin_root);
++		rygel_lms_plugin_root = _tmp1_;
++	}
++	_tmp2_ = rygel_lms_plugin_root;
++	self = (RygelLMSPlugin*) rygel_media_server_plugin_construct (object_type, (RygelMediaContainer*) _tmp2_, RYGEL_LMS_PLUGIN_NAME, NULL, RYGEL_PLUGIN_CAPABILITIES_TRACK_CHANGES);
++	return self;
++}
++
++
++RygelLMSPlugin* rygel_lms_plugin_new (void) {
++	return rygel_lms_plugin_construct (RYGEL_LMS_TYPE_PLUGIN);
++}
++
++
++static void rygel_lms_plugin_class_init (RygelLMSPluginClass * klass) {
++	rygel_lms_plugin_parent_class = g_type_class_peek_parent (klass);
++	G_OBJECT_CLASS (klass)->finalize = rygel_lms_plugin_finalize;
++}
++
++
++static void rygel_lms_plugin_instance_init (RygelLMSPlugin * self) {
++}
++
++
++static void rygel_lms_plugin_finalize (GObject* obj) {
++	RygelLMSPlugin * self;
++	self = G_TYPE_CHECK_INSTANCE_CAST (obj, RYGEL_LMS_TYPE_PLUGIN, RygelLMSPlugin);
++	G_OBJECT_CLASS (rygel_lms_plugin_parent_class)->finalize (obj);
++}
++
++
++GType rygel_lms_plugin_get_type (void) {
++	static volatile gsize rygel_lms_plugin_type_id__volatile = 0;
++	if (g_once_init_enter (&rygel_lms_plugin_type_id__volatile)) {
++		static const GTypeInfo g_define_type_info = { sizeof (RygelLMSPluginClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) rygel_lms_plugin_class_init, (GClassFinalizeFunc) NULL, NULL, sizeof (RygelLMSPlugin), 0, (GInstanceInitFunc) rygel_lms_plugin_instance_init, NULL };
++		GType rygel_lms_plugin_type_id;
++		rygel_lms_plugin_type_id = g_type_register_static (RYGEL_TYPE_MEDIA_SERVER_PLUGIN, "RygelLMSPlugin", &g_define_type_info, 0);
++		g_once_init_leave (&rygel_lms_plugin_type_id__volatile, rygel_lms_plugin_type_id);
++	}
++	return rygel_lms_plugin_type_id__volatile;
++}
++
++
++
+diff --git a/src/plugins/lms/rygel-lms-root-container.c b/src/plugins/lms/rygel-lms-root-container.c
+new file mode 100644
+index 0000000..625ed2f
+--- /dev/null
++++ b/src/plugins/lms/rygel-lms-root-container.c
+@@ -0,0 +1,318 @@
++/* rygel-lms-root-container.c generated by valac 0.28.0, the Vala compiler
++ * generated from rygel-lms-root-container.vala, do not modify */
++
++/*
++ * Copyright (C) 2013 Intel Corporation.
++ *
++ * Author: Jussi Kukkonen <jussi.kukkonen@intel.com>
++ *
++ * 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 <glib.h>
++#include <glib-object.h>
++#include <rygel-server.h>
++#include <rygel-core.h>
++#include <stdlib.h>
++#include <string.h>
++#include <glib/gi18n-lib.h>
++
++
++#define RYGEL_LMS_TYPE_ROOT_CONTAINER (rygel_lms_root_container_get_type ())
++#define RYGEL_LMS_ROOT_CONTAINER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), RYGEL_LMS_TYPE_ROOT_CONTAINER, RygelLMSRootContainer))
++#define RYGEL_LMS_ROOT_CONTAINER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), RYGEL_LMS_TYPE_ROOT_CONTAINER, RygelLMSRootContainerClass))
++#define RYGEL_LMS_IS_ROOT_CONTAINER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), RYGEL_LMS_TYPE_ROOT_CONTAINER))
++#define RYGEL_LMS_IS_ROOT_CONTAINER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), RYGEL_LMS_TYPE_ROOT_CONTAINER))
++#define RYGEL_LMS_ROOT_CONTAINER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), RYGEL_LMS_TYPE_ROOT_CONTAINER, RygelLMSRootContainerClass))
++
++typedef struct _RygelLMSRootContainer RygelLMSRootContainer;
++typedef struct _RygelLMSRootContainerClass RygelLMSRootContainerClass;
++typedef struct _RygelLMSRootContainerPrivate RygelLMSRootContainerPrivate;
++
++#define RYGEL_LMS_TYPE_DATABASE (rygel_lms_database_get_type ())
++#define RYGEL_LMS_DATABASE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), RYGEL_LMS_TYPE_DATABASE, RygelLMSDatabase))
++#define RYGEL_LMS_DATABASE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), RYGEL_LMS_TYPE_DATABASE, RygelLMSDatabaseClass))
++#define RYGEL_LMS_IS_DATABASE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), RYGEL_LMS_TYPE_DATABASE))
++#define RYGEL_LMS_IS_DATABASE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), RYGEL_LMS_TYPE_DATABASE))
++#define RYGEL_LMS_DATABASE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), RYGEL_LMS_TYPE_DATABASE, RygelLMSDatabaseClass))
++
++typedef struct _RygelLMSDatabase RygelLMSDatabase;
++typedef struct _RygelLMSDatabaseClass RygelLMSDatabaseClass;
++#define _rygel_lms_database_unref0(var) ((var == NULL) ? NULL : (var = (rygel_lms_database_unref (var), NULL)))
++#define _g_free0(var) (var = (g_free (var), NULL))
++#define _g_error_free0(var) ((var == NULL) ? NULL : (var = (g_error_free (var), NULL)))
++#define _g_object_unref0(var) ((var == NULL) ? NULL : (var = (g_object_unref (var), NULL)))
++
++#define RYGEL_LMS_TYPE_MUSIC_ROOT (rygel_lms_music_root_get_type ())
++#define RYGEL_LMS_MUSIC_ROOT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), RYGEL_LMS_TYPE_MUSIC_ROOT, RygelLMSMusicRoot))
++#define RYGEL_LMS_MUSIC_ROOT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), RYGEL_LMS_TYPE_MUSIC_ROOT, RygelLMSMusicRootClass))
++#define RYGEL_LMS_IS_MUSIC_ROOT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), RYGEL_LMS_TYPE_MUSIC_ROOT))
++#define RYGEL_LMS_IS_MUSIC_ROOT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), RYGEL_LMS_TYPE_MUSIC_ROOT))
++#define RYGEL_LMS_MUSIC_ROOT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), RYGEL_LMS_TYPE_MUSIC_ROOT, RygelLMSMusicRootClass))
++
++typedef struct _RygelLMSMusicRoot RygelLMSMusicRoot;
++typedef struct _RygelLMSMusicRootClass RygelLMSMusicRootClass;
++
++#define RYGEL_LMS_TYPE_CATEGORY_CONTAINER (rygel_lms_category_container_get_type ())
++#define RYGEL_LMS_CATEGORY_CONTAINER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), RYGEL_LMS_TYPE_CATEGORY_CONTAINER, RygelLMSCategoryContainer))
++#define RYGEL_LMS_CATEGORY_CONTAINER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), RYGEL_LMS_TYPE_CATEGORY_CONTAINER, RygelLMSCategoryContainerClass))
++#define RYGEL_LMS_IS_CATEGORY_CONTAINER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), RYGEL_LMS_TYPE_CATEGORY_CONTAINER))
++#define RYGEL_LMS_IS_CATEGORY_CONTAINER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), RYGEL_LMS_TYPE_CATEGORY_CONTAINER))
++#define RYGEL_LMS_CATEGORY_CONTAINER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), RYGEL_LMS_TYPE_CATEGORY_CONTAINER, RygelLMSCategoryContainerClass))
++
++typedef struct _RygelLMSCategoryContainer RygelLMSCategoryContainer;
++typedef struct _RygelLMSCategoryContainerClass RygelLMSCategoryContainerClass;
++
++#define RYGEL_LMS_TYPE_ALL_VIDEOS (rygel_lms_all_videos_get_type ())
++#define RYGEL_LMS_ALL_VIDEOS(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), RYGEL_LMS_TYPE_ALL_VIDEOS, RygelLMSAllVideos))
++#define RYGEL_LMS_ALL_VIDEOS_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), RYGEL_LMS_TYPE_ALL_VIDEOS, RygelLMSAllVideosClass))
++#define RYGEL_LMS_IS_ALL_VIDEOS(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), RYGEL_LMS_TYPE_ALL_VIDEOS))
++#define RYGEL_LMS_IS_ALL_VIDEOS_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), RYGEL_LMS_TYPE_ALL_VIDEOS))
++#define RYGEL_LMS_ALL_VIDEOS_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), RYGEL_LMS_TYPE_ALL_VIDEOS, RygelLMSAllVideosClass))
++
++typedef struct _RygelLMSAllVideos RygelLMSAllVideos;
++typedef struct _RygelLMSAllVideosClass RygelLMSAllVideosClass;
++
++#define RYGEL_LMS_TYPE_IMAGE_ROOT (rygel_lms_image_root_get_type ())
++#define RYGEL_LMS_IMAGE_ROOT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), RYGEL_LMS_TYPE_IMAGE_ROOT, RygelLMSImageRoot))
++#define RYGEL_LMS_IMAGE_ROOT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), RYGEL_LMS_TYPE_IMAGE_ROOT, RygelLMSImageRootClass))
++#define RYGEL_LMS_IS_IMAGE_ROOT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), RYGEL_LMS_TYPE_IMAGE_ROOT))
++#define RYGEL_LMS_IS_IMAGE_ROOT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), RYGEL_LMS_TYPE_IMAGE_ROOT))
++#define RYGEL_LMS_IMAGE_ROOT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), RYGEL_LMS_TYPE_IMAGE_ROOT, RygelLMSImageRootClass))
++
++typedef struct _RygelLMSImageRoot RygelLMSImageRoot;
++typedef struct _RygelLMSImageRootClass RygelLMSImageRootClass;
++
++struct _RygelLMSRootContainer {
++	RygelSimpleContainer parent_instance;
++	RygelLMSRootContainerPrivate * priv;
++};
++
++struct _RygelLMSRootContainerClass {
++	RygelSimpleContainerClass parent_class;
++};
++
++struct _RygelLMSRootContainerPrivate {
++	RygelLMSDatabase* lms_db;
++};
++
++typedef enum  {
++	RYGEL_LMS_DATABASE_ERROR_OPEN,
++	RYGEL_LMS_DATABASE_ERROR_PREPARE,
++	RYGEL_LMS_DATABASE_ERROR_BIND,
++	RYGEL_LMS_DATABASE_ERROR_STEP,
++	RYGEL_LMS_DATABASE_ERROR_NOT_FOUND
++} RygelLMSDatabaseError;
++#define RYGEL_LMS_DATABASE_ERROR rygel_lms_database_error_quark ()
++
++static gpointer rygel_lms_root_container_parent_class = NULL;
++
++GType rygel_lms_root_container_get_type (void) G_GNUC_CONST;
++gpointer rygel_lms_database_ref (gpointer instance);
++void rygel_lms_database_unref (gpointer instance);
++GParamSpec* rygel_lms_param_spec_database (const gchar* name, const gchar* nick, const gchar* blurb, GType object_type, GParamFlags flags);
++void rygel_lms_value_set_database (GValue* value, gpointer v_object);
++void rygel_lms_value_take_database (GValue* value, gpointer v_object);
++gpointer rygel_lms_value_get_database (const GValue* value);
++GType rygel_lms_database_get_type (void) G_GNUC_CONST;
++#define RYGEL_LMS_ROOT_CONTAINER_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), RYGEL_LMS_TYPE_ROOT_CONTAINER, RygelLMSRootContainerPrivate))
++enum  {
++	RYGEL_LMS_ROOT_CONTAINER_DUMMY_PROPERTY
++};
++RygelLMSRootContainer* rygel_lms_root_container_new (void);
++RygelLMSRootContainer* rygel_lms_root_container_construct (GType object_type);
++GQuark rygel_lms_database_error_quark (void);
++RygelLMSDatabase* rygel_lms_database_new (GError** error);
++RygelLMSDatabase* rygel_lms_database_construct (GType object_type, GError** error);
++RygelLMSMusicRoot* rygel_lms_music_root_new (const gchar* id, RygelMediaContainer* parent, const gchar* title, RygelLMSDatabase* lms_db);
++RygelLMSMusicRoot* rygel_lms_music_root_construct (GType object_type, const gchar* id, RygelMediaContainer* parent, const gchar* title, RygelLMSDatabase* lms_db);
++GType rygel_lms_music_root_get_type (void) G_GNUC_CONST;
++RygelLMSAllVideos* rygel_lms_all_videos_new (const gchar* id, RygelMediaContainer* parent, const gchar* title, RygelLMSDatabase* lms_db);
++RygelLMSAllVideos* rygel_lms_all_videos_construct (GType object_type, const gchar* id, RygelMediaContainer* parent, const gchar* title, RygelLMSDatabase* lms_db);
++GType rygel_lms_category_container_get_type (void) G_GNUC_CONST;
++GType rygel_lms_all_videos_get_type (void) G_GNUC_CONST;
++RygelLMSImageRoot* rygel_lms_image_root_new (const gchar* id, RygelMediaContainer* parent, const gchar* title, RygelLMSDatabase* lms_db);
++RygelLMSImageRoot* rygel_lms_image_root_construct (GType object_type, const gchar* id, RygelMediaContainer* parent, const gchar* title, RygelLMSDatabase* lms_db);
++GType rygel_lms_image_root_get_type (void) G_GNUC_CONST;
++static void rygel_lms_root_container_finalize (GObject* obj);
++
++
++RygelLMSRootContainer* rygel_lms_root_container_construct (GType object_type) {
++	RygelLMSRootContainer * self = NULL;
++	RygelMetaConfig* config = NULL;
++	RygelMetaConfig* _tmp0_ = NULL;
++	gchar* title = NULL;
++	const gchar* _tmp1_ = NULL;
++	gchar* _tmp2_ = NULL;
++	const gchar* _tmp6_ = NULL;
++	GError * _inner_error_ = NULL;
++	_tmp0_ = rygel_meta_config_get_default ();
++	config = _tmp0_;
++	_tmp1_ = _ ("Shared media");
++	_tmp2_ = g_strdup (_tmp1_);
++	title = _tmp2_;
++	{
++		gchar* _tmp3_ = NULL;
++		gchar* _tmp4_ = NULL;
++		gchar* _tmp5_ = NULL;
++		_tmp4_ = rygel_configuration_get_string ((RygelConfiguration*) config, "LightMediaScanner", "title", &_inner_error_);
++		_tmp3_ = _tmp4_;
++		if (G_UNLIKELY (_inner_error_ != NULL)) {
++			goto __catch0_g_error;
++		}
++		_tmp5_ = _tmp3_;
++		_tmp3_ = NULL;
++		_g_free0 (title);
++		title = _tmp5_;
++		_g_free0 (_tmp3_);
++	}
++	goto __finally0;
++	__catch0_g_error:
++	{
++		GError* _error_ = NULL;
++		_error_ = _inner_error_;
++		_inner_error_ = NULL;
++		_g_error_free0 (_error_);
++	}
++	__finally0:
++	if (G_UNLIKELY (_inner_error_ != NULL)) {
++		_g_free0 (title);
++		_g_object_unref0 (config);
++		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;
++	}
++	_tmp6_ = title;
++	self = (RygelLMSRootContainer*) rygel_simple_container_construct_root (object_type, _tmp6_);
++	{
++		RygelLMSDatabase* _tmp7_ = NULL;
++		RygelLMSDatabase* _tmp8_ = NULL;
++		RygelLMSDatabase* _tmp9_ = NULL;
++		const gchar* _tmp10_ = NULL;
++		RygelLMSDatabase* _tmp11_ = NULL;
++		RygelLMSMusicRoot* _tmp12_ = NULL;
++		RygelLMSMusicRoot* _tmp13_ = NULL;
++		const gchar* _tmp14_ = NULL;
++		RygelLMSDatabase* _tmp15_ = NULL;
++		RygelLMSAllVideos* _tmp16_ = NULL;
++		RygelLMSAllVideos* _tmp17_ = NULL;
++		const gchar* _tmp18_ = NULL;
++		RygelLMSDatabase* _tmp19_ = NULL;
++		RygelLMSImageRoot* _tmp20_ = NULL;
++		RygelLMSImageRoot* _tmp21_ = NULL;
++		_tmp8_ = rygel_lms_database_new (&_inner_error_);
++		_tmp7_ = _tmp8_;
++		if (G_UNLIKELY (_inner_error_ != NULL)) {
++			if (_inner_error_->domain == RYGEL_LMS_DATABASE_ERROR) {
++				goto __catch1_rygel_lms_database_error;
++			}
++			_g_free0 (title);
++			_g_object_unref0 (config);
++			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;
++		}
++		_tmp9_ = _tmp7_;
++		_tmp7_ = NULL;
++		_rygel_lms_database_unref0 (self->priv->lms_db);
++		self->priv->lms_db = _tmp9_;
++		_tmp10_ = _ ("Music");
++		_tmp11_ = self->priv->lms_db;
++		_tmp12_ = rygel_lms_music_root_new ("music", (RygelMediaContainer*) self, _tmp10_, _tmp11_);
++		_tmp13_ = _tmp12_;
++		rygel_simple_container_add_child_container ((RygelSimpleContainer*) self, (RygelMediaContainer*) _tmp13_);
++		_g_object_unref0 (_tmp13_);
++		_tmp14_ = _ ("Videos");
++		_tmp15_ = self->priv->lms_db;
++		_tmp16_ = rygel_lms_all_videos_new ("all-videos", (RygelMediaContainer*) self, _tmp14_, _tmp15_);
++		_tmp17_ = _tmp16_;
++		rygel_simple_container_add_child_container ((RygelSimpleContainer*) self, (RygelMediaContainer*) _tmp17_);
++		_g_object_unref0 (_tmp17_);
++		_tmp18_ = _ ("Pictures");
++		_tmp19_ = self->priv->lms_db;
++		_tmp20_ = rygel_lms_image_root_new ("images", (RygelMediaContainer*) self, _tmp18_, _tmp19_);
++		_tmp21_ = _tmp20_;
++		rygel_simple_container_add_child_container ((RygelSimpleContainer*) self, (RygelMediaContainer*) _tmp21_);
++		_g_object_unref0 (_tmp21_);
++		_rygel_lms_database_unref0 (_tmp7_);
++	}
++	goto __finally1;
++	__catch1_rygel_lms_database_error:
++	{
++		GError* e = NULL;
++		GError* _tmp22_ = NULL;
++		const gchar* _tmp23_ = NULL;
++		e = _inner_error_;
++		_inner_error_ = NULL;
++		_tmp22_ = e;
++		_tmp23_ = _tmp22_->message;
++		g_warning ("rygel-lms-root-container.vala:49: %s\n", _tmp23_);
++		_g_error_free0 (e);
++	}
++	__finally1:
++	if (G_UNLIKELY (_inner_error_ != NULL)) {
++		_g_free0 (title);
++		_g_object_unref0 (config);
++		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;
++	}
++	_g_free0 (title);
++	_g_object_unref0 (config);
++	return self;
++}
++
++
++RygelLMSRootContainer* rygel_lms_root_container_new (void) {
++	return rygel_lms_root_container_construct (RYGEL_LMS_TYPE_ROOT_CONTAINER);
++}
++
++
++static void rygel_lms_root_container_class_init (RygelLMSRootContainerClass * klass) {
++	rygel_lms_root_container_parent_class = g_type_class_peek_parent (klass);
++	g_type_class_add_private (klass, sizeof (RygelLMSRootContainerPrivate));
++	G_OBJECT_CLASS (klass)->finalize = rygel_lms_root_container_finalize;
++}
++
++
++static void rygel_lms_root_container_instance_init (RygelLMSRootContainer * self) {
++	self->priv = RYGEL_LMS_ROOT_CONTAINER_GET_PRIVATE (self);
++	self->priv->lms_db = NULL;
++}
++
++
++static void rygel_lms_root_container_finalize (GObject* obj) {
++	RygelLMSRootContainer * self;
++	self = G_TYPE_CHECK_INSTANCE_CAST (obj, RYGEL_LMS_TYPE_ROOT_CONTAINER, RygelLMSRootContainer);
++	_rygel_lms_database_unref0 (self->priv->lms_db);
++	G_OBJECT_CLASS (rygel_lms_root_container_parent_class)->finalize (obj);
++}
++
++
++GType rygel_lms_root_container_get_type (void) {
++	static volatile gsize rygel_lms_root_container_type_id__volatile = 0;
++	if (g_once_init_enter (&rygel_lms_root_container_type_id__volatile)) {
++		static const GTypeInfo g_define_type_info = { sizeof (RygelLMSRootContainerClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) rygel_lms_root_container_class_init, (GClassFinalizeFunc) NULL, NULL, sizeof (RygelLMSRootContainer), 0, (GInstanceInitFunc) rygel_lms_root_container_instance_init, NULL };
++		GType rygel_lms_root_container_type_id;
++		rygel_lms_root_container_type_id = g_type_register_static (RYGEL_TYPE_SIMPLE_CONTAINER, "RygelLMSRootContainer", &g_define_type_info, 0);
++		g_once_init_leave (&rygel_lms_root_container_type_id__volatile, rygel_lms_root_container_type_id);
++	}
++	return rygel_lms_root_container_type_id__volatile;
++}
++
++
++
+diff --git a/src/plugins/lms/rygel-lms-sql-function.c b/src/plugins/lms/rygel-lms-sql-function.c
+new file mode 100644
+index 0000000..a56c7be
+--- /dev/null
++++ b/src/plugins/lms/rygel-lms-sql-function.c
+@@ -0,0 +1,146 @@
++/* rygel-lms-sql-function.c generated by valac 0.28.0, the Vala compiler
++ * generated from rygel-lms-sql-function.vala, do not modify */
++
++/*
++ * Copyright (C) 2010 Jens Georg <mail@jensge.org>.
++ *
++ * Author: 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 <glib.h>
++#include <glib-object.h>
++#include <stdlib.h>
++#include <string.h>
++
++
++#define RYGEL_LMS_TYPE_SQL_OPERATOR (rygel_lms_sql_operator_get_type ())
++#define RYGEL_LMS_SQL_OPERATOR(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), RYGEL_LMS_TYPE_SQL_OPERATOR, RygelLMSSqlOperator))
++#define RYGEL_LMS_SQL_OPERATOR_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), RYGEL_LMS_TYPE_SQL_OPERATOR, RygelLMSSqlOperatorClass))
++#define RYGEL_LMS_IS_SQL_OPERATOR(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), RYGEL_LMS_TYPE_SQL_OPERATOR))
++#define RYGEL_LMS_IS_SQL_OPERATOR_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), RYGEL_LMS_TYPE_SQL_OPERATOR))
++#define RYGEL_LMS_SQL_OPERATOR_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), RYGEL_LMS_TYPE_SQL_OPERATOR, RygelLMSSqlOperatorClass))
++
++typedef struct _RygelLMSSqlOperator RygelLMSSqlOperator;
++typedef struct _RygelLMSSqlOperatorClass RygelLMSSqlOperatorClass;
++typedef struct _RygelLMSSqlOperatorPrivate RygelLMSSqlOperatorPrivate;
++
++#define RYGEL_LMS_TYPE_SQL_FUNCTION (rygel_lms_sql_function_get_type ())
++#define RYGEL_LMS_SQL_FUNCTION(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), RYGEL_LMS_TYPE_SQL_FUNCTION, RygelLMSSqlFunction))
++#define RYGEL_LMS_SQL_FUNCTION_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), RYGEL_LMS_TYPE_SQL_FUNCTION, RygelLMSSqlFunctionClass))
++#define RYGEL_LMS_IS_SQL_FUNCTION(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), RYGEL_LMS_TYPE_SQL_FUNCTION))
++#define RYGEL_LMS_IS_SQL_FUNCTION_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), RYGEL_LMS_TYPE_SQL_FUNCTION))
++#define RYGEL_LMS_SQL_FUNCTION_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), RYGEL_LMS_TYPE_SQL_FUNCTION, RygelLMSSqlFunctionClass))
++
++typedef struct _RygelLMSSqlFunction RygelLMSSqlFunction;
++typedef struct _RygelLMSSqlFunctionClass RygelLMSSqlFunctionClass;
++typedef struct _RygelLMSSqlFunctionPrivate RygelLMSSqlFunctionPrivate;
++
++struct _RygelLMSSqlOperator {
++	GObject parent_instance;
++	RygelLMSSqlOperatorPrivate * priv;
++	gchar* name;
++	gchar* arg;
++	gchar* collate;
++};
++
++struct _RygelLMSSqlOperatorClass {
++	GObjectClass parent_class;
++	gchar* (*to_string) (RygelLMSSqlOperator* self);
++};
++
++struct _RygelLMSSqlFunction {
++	RygelLMSSqlOperator parent_instance;
++	RygelLMSSqlFunctionPrivate * priv;
++};
++
++struct _RygelLMSSqlFunctionClass {
++	RygelLMSSqlOperatorClass parent_class;
++};
++
++
++static gpointer rygel_lms_sql_function_parent_class = NULL;
++
++GType rygel_lms_sql_operator_get_type (void) G_GNUC_CONST;
++GType rygel_lms_sql_function_get_type (void) G_GNUC_CONST;
++enum  {
++	RYGEL_LMS_SQL_FUNCTION_DUMMY_PROPERTY
++};
++RygelLMSSqlFunction* rygel_lms_sql_function_new (const gchar* name, const gchar* arg);
++RygelLMSSqlFunction* rygel_lms_sql_function_construct (GType object_type, const gchar* name, const gchar* arg);
++RygelLMSSqlOperator* rygel_lms_sql_operator_new (const gchar* name, const gchar* arg, const gchar* collate);
++RygelLMSSqlOperator* rygel_lms_sql_operator_construct (GType object_type, const gchar* name, const gchar* arg, const gchar* collate);
++static gchar* rygel_lms_sql_function_real_to_string (RygelLMSSqlOperator* base);
++
++
++RygelLMSSqlFunction* rygel_lms_sql_function_construct (GType object_type, const gchar* name, const gchar* arg) {
++	RygelLMSSqlFunction * self = NULL;
++	const gchar* _tmp0_ = NULL;
++	const gchar* _tmp1_ = NULL;
++	g_return_val_if_fail (name != NULL, NULL);
++	g_return_val_if_fail (arg != NULL, NULL);
++	_tmp0_ = name;
++	_tmp1_ = arg;
++	self = (RygelLMSSqlFunction*) rygel_lms_sql_operator_construct (object_type, _tmp0_, _tmp1_, "");
++	return self;
++}
++
++
++RygelLMSSqlFunction* rygel_lms_sql_function_new (const gchar* name, const gchar* arg) {
++	return rygel_lms_sql_function_construct (RYGEL_LMS_TYPE_SQL_FUNCTION, name, arg);
++}
++
++
++static gchar* rygel_lms_sql_function_real_to_string (RygelLMSSqlOperator* base) {
++	RygelLMSSqlFunction * self;
++	gchar* result = NULL;
++	const gchar* _tmp0_ = NULL;
++	const gchar* _tmp1_ = NULL;
++	gchar* _tmp2_ = NULL;
++	self = (RygelLMSSqlFunction*) base;
++	_tmp0_ = ((RygelLMSSqlOperator*) self)->name;
++	_tmp1_ = ((RygelLMSSqlOperator*) self)->arg;
++	_tmp2_ = g_strdup_printf ("%s(%s,?)", _tmp0_, _tmp1_);
++	result = _tmp2_;
++	return result;
++}
++
++
++static void rygel_lms_sql_function_class_init (RygelLMSSqlFunctionClass * klass) {
++	rygel_lms_sql_function_parent_class = g_type_class_peek_parent (klass);
++	((RygelLMSSqlOperatorClass *) klass)->to_string = rygel_lms_sql_function_real_to_string;
++}
++
++
++static void rygel_lms_sql_function_instance_init (RygelLMSSqlFunction * self) {
++}
++
++
++GType rygel_lms_sql_function_get_type (void) {
++	static volatile gsize rygel_lms_sql_function_type_id__volatile = 0;
++	if (g_once_init_enter (&rygel_lms_sql_function_type_id__volatile)) {
++		static const GTypeInfo g_define_type_info = { sizeof (RygelLMSSqlFunctionClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) rygel_lms_sql_function_class_init, (GClassFinalizeFunc) NULL, NULL, sizeof (RygelLMSSqlFunction), 0, (GInstanceInitFunc) rygel_lms_sql_function_instance_init, NULL };
++		GType rygel_lms_sql_function_type_id;
++		rygel_lms_sql_function_type_id = g_type_register_static (RYGEL_LMS_TYPE_SQL_OPERATOR, "RygelLMSSqlFunction", &g_define_type_info, 0);
++		g_once_init_leave (&rygel_lms_sql_function_type_id__volatile, rygel_lms_sql_function_type_id);
++	}
++	return rygel_lms_sql_function_type_id__volatile;
++}
++
++
++
+diff --git a/src/plugins/lms/rygel-lms-sql-operator.c b/src/plugins/lms/rygel-lms-sql-operator.c
+new file mode 100644
+index 0000000..90db1a9
+--- /dev/null
++++ b/src/plugins/lms/rygel-lms-sql-operator.c
+@@ -0,0 +1,240 @@
++/* rygel-lms-sql-operator.c generated by valac 0.28.0, the Vala compiler
++ * generated from rygel-lms-sql-operator.vala, do not modify */
++
++/*
++ * Copyright (C) 2010 Jens Georg <mail@jensge.org>.
++ *
++ * Author: 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 <glib.h>
++#include <glib-object.h>
++#include <stdlib.h>
++#include <string.h>
++#include <libgupnp-av/gupnp-av.h>
++
++
++#define RYGEL_LMS_TYPE_SQL_OPERATOR (rygel_lms_sql_operator_get_type ())
++#define RYGEL_LMS_SQL_OPERATOR(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), RYGEL_LMS_TYPE_SQL_OPERATOR, RygelLMSSqlOperator))
++#define RYGEL_LMS_SQL_OPERATOR_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), RYGEL_LMS_TYPE_SQL_OPERATOR, RygelLMSSqlOperatorClass))
++#define RYGEL_LMS_IS_SQL_OPERATOR(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), RYGEL_LMS_TYPE_SQL_OPERATOR))
++#define RYGEL_LMS_IS_SQL_OPERATOR_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), RYGEL_LMS_TYPE_SQL_OPERATOR))
++#define RYGEL_LMS_SQL_OPERATOR_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), RYGEL_LMS_TYPE_SQL_OPERATOR, RygelLMSSqlOperatorClass))
++
++typedef struct _RygelLMSSqlOperator RygelLMSSqlOperator;
++typedef struct _RygelLMSSqlOperatorClass RygelLMSSqlOperatorClass;
++typedef struct _RygelLMSSqlOperatorPrivate RygelLMSSqlOperatorPrivate;
++#define _g_free0(var) (var = (g_free (var), NULL))
++
++struct _RygelLMSSqlOperator {
++	GObject parent_instance;
++	RygelLMSSqlOperatorPrivate * priv;
++	gchar* name;
++	gchar* arg;
++	gchar* collate;
++};
++
++struct _RygelLMSSqlOperatorClass {
++	GObjectClass parent_class;
++	gchar* (*to_string) (RygelLMSSqlOperator* self);
++};
++
++
++static gpointer rygel_lms_sql_operator_parent_class = NULL;
++
++GType rygel_lms_sql_operator_get_type (void) G_GNUC_CONST;
++enum  {
++	RYGEL_LMS_SQL_OPERATOR_DUMMY_PROPERTY
++};
++RygelLMSSqlOperator* rygel_lms_sql_operator_new (const gchar* name, const gchar* arg, const gchar* collate);
++RygelLMSSqlOperator* rygel_lms_sql_operator_construct (GType object_type, const gchar* name, const gchar* arg, const gchar* collate);
++RygelLMSSqlOperator* rygel_lms_sql_operator_new_from_search_criteria_op (GUPnPSearchCriteriaOp op, const gchar* arg, const gchar* collate);
++RygelLMSSqlOperator* rygel_lms_sql_operator_construct_from_search_criteria_op (GType object_type, GUPnPSearchCriteriaOp op, const gchar* arg, const gchar* collate);
++gchar* rygel_lms_sql_operator_to_string (RygelLMSSqlOperator* self);
++static gchar* rygel_lms_sql_operator_real_to_string (RygelLMSSqlOperator* self);
++static void rygel_lms_sql_operator_finalize (GObject* obj);
++
++
++RygelLMSSqlOperator* rygel_lms_sql_operator_construct (GType object_type, const gchar* name, const gchar* arg, const gchar* collate) {
++	RygelLMSSqlOperator * self = NULL;
++	const gchar* _tmp0_ = NULL;
++	gchar* _tmp1_ = NULL;
++	const gchar* _tmp2_ = NULL;
++	gchar* _tmp3_ = NULL;
++	const gchar* _tmp4_ = NULL;
++	gchar* _tmp5_ = NULL;
++	g_return_val_if_fail (name != NULL, NULL);
++	g_return_val_if_fail (arg != NULL, NULL);
++	g_return_val_if_fail (collate != NULL, NULL);
++	self = (RygelLMSSqlOperator*) g_object_new (object_type, NULL);
++	_tmp0_ = name;
++	_tmp1_ = g_strdup (_tmp0_);
++	_g_free0 (self->name);
++	self->name = _tmp1_;
++	_tmp2_ = arg;
++	_tmp3_ = g_strdup (_tmp2_);
++	_g_free0 (self->arg);
++	self->arg = _tmp3_;
++	_tmp4_ = collate;
++	_tmp5_ = g_strdup (_tmp4_);
++	_g_free0 (self->collate);
++	self->collate = _tmp5_;
++	return self;
++}
++
++
++RygelLMSSqlOperator* rygel_lms_sql_operator_new (const gchar* name, const gchar* arg, const gchar* collate) {
++	return rygel_lms_sql_operator_construct (RYGEL_LMS_TYPE_SQL_OPERATOR, name, arg, collate);
++}
++
++
++RygelLMSSqlOperator* rygel_lms_sql_operator_construct_from_search_criteria_op (GType object_type, GUPnPSearchCriteriaOp op, const gchar* arg, const gchar* collate) {
++	RygelLMSSqlOperator * self = NULL;
++	gchar* sql = NULL;
++	GUPnPSearchCriteriaOp _tmp0_ = 0;
++	const gchar* _tmp7_ = NULL;
++	const gchar* _tmp8_ = NULL;
++	const gchar* _tmp9_ = NULL;
++	g_return_val_if_fail (arg != NULL, NULL);
++	g_return_val_if_fail (collate != NULL, NULL);
++	sql = NULL;
++	_tmp0_ = op;
++	switch (_tmp0_) {
++		case GUPNP_SEARCH_CRITERIA_OP_EQ:
++		{
++			gchar* _tmp1_ = NULL;
++			_tmp1_ = g_strdup ("=");
++			_g_free0 (sql);
++			sql = _tmp1_;
++			break;
++		}
++		case GUPNP_SEARCH_CRITERIA_OP_NEQ:
++		{
++			gchar* _tmp2_ = NULL;
++			_tmp2_ = g_strdup ("!=");
++			_g_free0 (sql);
++			sql = _tmp2_;
++			break;
++		}
++		case GUPNP_SEARCH_CRITERIA_OP_LESS:
++		{
++			gchar* _tmp3_ = NULL;
++			_tmp3_ = g_strdup ("<");
++			_g_free0 (sql);
++			sql = _tmp3_;
++			break;
++		}
++		case GUPNP_SEARCH_CRITERIA_OP_LEQ:
++		{
++			gchar* _tmp4_ = NULL;
++			_tmp4_ = g_strdup ("<=");
++			_g_free0 (sql);
++			sql = _tmp4_;
++			break;
++		}
++		case GUPNP_SEARCH_CRITERIA_OP_GREATER:
++		{
++			gchar* _tmp5_ = NULL;
++			_tmp5_ = g_strdup (">");
++			_g_free0 (sql);
++			sql = _tmp5_;
++			break;
++		}
++		case GUPNP_SEARCH_CRITERIA_OP_GEQ:
++		{
++			gchar* _tmp6_ = NULL;
++			_tmp6_ = g_strdup (">=");
++			_g_free0 (sql);
++			sql = _tmp6_;
++			break;
++		}
++		default:
++		{
++			g_assert_not_reached ();
++		}
++	}
++	_tmp7_ = sql;
++	_tmp8_ = arg;
++	_tmp9_ = collate;
++	self = (RygelLMSSqlOperator*) rygel_lms_sql_operator_construct (object_type, _tmp7_, _tmp8_, _tmp9_);
++	_g_free0 (sql);
++	return self;
++}
++
++
++RygelLMSSqlOperator* rygel_lms_sql_operator_new_from_search_criteria_op (GUPnPSearchCriteriaOp op, const gchar* arg, const gchar* collate) {
++	return rygel_lms_sql_operator_construct_from_search_criteria_op (RYGEL_LMS_TYPE_SQL_OPERATOR, op, arg, collate);
++}
++
++
++static gchar* rygel_lms_sql_operator_real_to_string (RygelLMSSqlOperator* self) {
++	gchar* result = NULL;
++	const gchar* _tmp0_ = NULL;
++	const gchar* _tmp1_ = NULL;
++	const gchar* _tmp2_ = NULL;
++	gchar* _tmp3_ = NULL;
++	_tmp0_ = self->arg;
++	_tmp1_ = self->name;
++	_tmp2_ = self->collate;
++	_tmp3_ = g_strdup_printf ("(%s %s ? %s)", _tmp0_, _tmp1_, _tmp2_);
++	result = _tmp3_;
++	return result;
++}
++
++
++gchar* rygel_lms_sql_operator_to_string (RygelLMSSqlOperator* self) {
++	g_return_val_if_fail (self != NULL, NULL);
++	return RYGEL_LMS_SQL_OPERATOR_GET_CLASS (self)->to_string (self);
++}
++
++
++static void rygel_lms_sql_operator_class_init (RygelLMSSqlOperatorClass * klass) {
++	rygel_lms_sql_operator_parent_class = g_type_class_peek_parent (klass);
++	((RygelLMSSqlOperatorClass *) klass)->to_string = rygel_lms_sql_operator_real_to_string;
++	G_OBJECT_CLASS (klass)->finalize = rygel_lms_sql_operator_finalize;
++}
++
++
++static void rygel_lms_sql_operator_instance_init (RygelLMSSqlOperator * self) {
++}
++
++
++static void rygel_lms_sql_operator_finalize (GObject* obj) {
++	RygelLMSSqlOperator * self;
++	self = G_TYPE_CHECK_INSTANCE_CAST (obj, RYGEL_LMS_TYPE_SQL_OPERATOR, RygelLMSSqlOperator);
++	_g_free0 (self->name);
++	_g_free0 (self->arg);
++	_g_free0 (self->collate);
++	G_OBJECT_CLASS (rygel_lms_sql_operator_parent_class)->finalize (obj);
++}
++
++
++GType rygel_lms_sql_operator_get_type (void) {
++	static volatile gsize rygel_lms_sql_operator_type_id__volatile = 0;
++	if (g_once_init_enter (&rygel_lms_sql_operator_type_id__volatile)) {
++		static const GTypeInfo g_define_type_info = { sizeof (RygelLMSSqlOperatorClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) rygel_lms_sql_operator_class_init, (GClassFinalizeFunc) NULL, NULL, sizeof (RygelLMSSqlOperator), 0, (GInstanceInitFunc) rygel_lms_sql_operator_instance_init, NULL };
++		GType rygel_lms_sql_operator_type_id;
++		rygel_lms_sql_operator_type_id = g_type_register_static (G_TYPE_OBJECT, "RygelLMSSqlOperator", &g_define_type_info, 0);
++		g_once_init_leave (&rygel_lms_sql_operator_type_id__volatile, rygel_lms_sql_operator_type_id);
++	}
++	return rygel_lms_sql_operator_type_id__volatile;
++}
++
++
++
+-- 
+1.8.3.1
+
diff --git a/meta-agl/recipes-connectivity/rygel/rygel_%.bbappend b/meta-agl/recipes-connectivity/rygel/rygel_%.bbappend
index 56ccbd936..9363c3cdc 100644
--- a/meta-agl/recipes-connectivity/rygel/rygel_%.bbappend
+++ b/meta-agl/recipes-connectivity/rygel/rygel_%.bbappend
@@ -1,2 +1,8 @@
-# Disable everything but the media-export plugin
-PACKAGECONFIG = "media-export"
+# Disable everything but the media-export plugin, add the lms plugin
+PACKAGECONFIG = "media-export lms"
+PACKAGECONFIG[lms] = "--enable-lms-plugin,--disable-lms-plugin,sqlite3"
+
+# LightMediaScanner plugin patches
+SRC_URI += "file://0001-Add-LightMediaScanner-plugin.patch \
+            file://0002-lms-add-C-source-files.patch \
+            "
diff --git a/meta-agl/recipes-ivi/packagegroups/packagegroup-agl-ivi-connectivity.bb b/meta-agl/recipes-ivi/packagegroups/packagegroup-agl-ivi-connectivity.bb
index b197814f8..405c0fbe6 100644
--- a/meta-agl/recipes-ivi/packagegroups/packagegroup-agl-ivi-connectivity.bb
+++ b/meta-agl/recipes-ivi/packagegroups/packagegroup-agl-ivi-connectivity.bb
@@ -14,4 +14,5 @@ RDEPENDS_${PN} += "\
     ofono \
     rygel \
     rygel-plugin-media-export \
+    rygel-plugin-lms \
     "
diff --git a/meta-agl/recipes-ivi/packagegroups/packagegroup-agl-ivi-multimedia.bb b/meta-agl/recipes-ivi/packagegroups/packagegroup-agl-ivi-multimedia.bb
index b91b21a4e..11536405e 100644
--- a/meta-agl/recipes-ivi/packagegroups/packagegroup-agl-ivi-multimedia.bb
+++ b/meta-agl/recipes-ivi/packagegroups/packagegroup-agl-ivi-multimedia.bb
@@ -13,4 +13,5 @@ ALLOW_EMPTY_${PN} = "1"
 RDEPENDS_${PN} += "\
     gstreamer1.0-plugins-base-meta \
     gstreamer1.0-plugins-good-meta \
+    lightmediascanner-meta \
     "
diff --git a/meta-agl/recipes-multimedia/lightmediascanner/files/id3-plugin-support-out-of-tree-build.patch b/meta-agl/recipes-multimedia/lightmediascanner/files/id3-plugin-support-out-of-tree-build.patch
new file mode 100644
index 000000000..9528bec79
--- /dev/null
+++ b/meta-agl/recipes-multimedia/lightmediascanner/files/id3-plugin-support-out-of-tree-build.patch
@@ -0,0 +1,11 @@
+--- a/src/plugins/Makefile.am	2015-10-25 16:12:29.331415823 +0000
++++ b/src/plugins/Makefile.am	2015-10-25 16:14:37.593415808 +0000
+@@ -93,7 +93,7 @@
+ id3_id3_la_SOURCES = id3/id3.c id3/id3v1_genres.c
+ id3_id3_la_LIBADD = $(PLUGINS_LIBADD)
+ 
+-id3/id3v1_genres.c: $(srcdir)/id3/id3v1_genres.def $(srcdir)/id3/id3v1_genres_gen.awk
++$(srcdir)/id3/id3v1_genres.c: $(srcdir)/id3/id3v1_genres.def $(srcdir)/id3/id3v1_genres_gen.awk
+ 	$(AWK) -f $(srcdir)/id3/id3v1_genres_gen.awk $(srcdir)/id3/id3v1_genres.def > $@
+ 
+ EXTRA_DIST += id3/id3v1_genres.def id3/id3v1_genres_gen.awk
diff --git a/meta-agl/recipes-multimedia/lightmediascanner/lightmediascanner_%.bbappend b/meta-agl/recipes-multimedia/lightmediascanner/lightmediascanner_%.bbappend
new file mode 100644
index 000000000..7e6381113
--- /dev/null
+++ b/meta-agl/recipes-multimedia/lightmediascanner/lightmediascanner_%.bbappend
@@ -0,0 +1,2 @@
+# Disable everything but the roygalty-free formats
+PACKAGECONFIG = "ogg flac wave m3u pls jpeg png"
diff --git a/meta-agl/recipes-multimedia/lightmediascanner/lightmediascanner_0.5.1.bb b/meta-agl/recipes-multimedia/lightmediascanner/lightmediascanner_0.5.1.bb
new file mode 100644
index 000000000..9870fac3d
--- /dev/null
+++ b/meta-agl/recipes-multimedia/lightmediascanner/lightmediascanner_0.5.1.bb
@@ -0,0 +1,62 @@
+SUMMARY = "Lightweight media scanner"
+DESCRIPTION = "Lightweight media scanner meant to be used in not-so-powerful devices, like embedded systems or old machines."
+SECTION = "libs/multimedia"
+
+LICENSE = "LGPLv2.1+"
+LIC_FILES_CHKSUM = "file://COPYING;md5=a6f89e2100d9b6cdffcea4f398e37343 \
+                    file://src/lib/lightmediascanner.c;endline=21;md5=6d8889bccb4c6c27e8b786342a3eb267"
+
+DEPENDS = "file gawk glib-2.0 sqlite3"
+
+PV = "0.5.1+git${SRCPV}"
+SRCREV = "adfddb3486276a5ed2f5008c9e43a811e1271cc9"
+SRC_URI = "git://github.com/profusion/lightmediascanner.git \
+           file://id3-plugin-support-out-of-tree-build.patch \
+          "
+
+S = "${WORKDIR}/git"
+
+inherit autotools pkgconfig
+
+EXTRA_OECONF = "--enable-static --disable-mp4"
+
+PACKAGECONFIG ??= "ogg flac wave id3 m3u pls asf rm jpeg png"
+PACKAGECONFIG[generic] = "--enable-generic,--disable-generic,libav"
+PACKAGECONFIG[ogg] = "--enable-ogg,--disable-ogg,libogg libvorbis libtheora"
+PACKAGECONFIG[flac] = "--enable-flac,--disable-flac,flac"
+PACKAGECONFIG[wave] = "--enable-wave,--disable-wave"
+PACKAGECONFIG[id3] = "--enable-id3,--disable-id3"
+PACKAGECONFIG[m3u] = "--enable-m3u,--disable-m3u"
+PACKAGECONFIG[pls] = "--enable-pls,--disable-pls"
+PACKAGECONFIG[asf] = "--enable-asf,--disable-asf"
+PACKAGECONFIG[rm] = "--enable-rm,--disable-rm"
+PACKAGECONFIG[jpeg] = "--enable-jpeg,--disable-jpeg"
+PACKAGECONFIG[png] = "--enable-png,--disable-png"
+
+do_install_append() {
+       # Install "test" binary for corresponding package
+       install -d ${D}/${bindir}
+       install -m 755 ${B}/src/bin/.libs/test ${D}/${bindir}/test-lms
+       # Remove .la files for loadable modules
+       rm -f ${D}/${libdir}/${PN}/plugins/*.la
+}
+
+FILES_${PN} += "${datadir}/dbus-1"
+FILES_${PN}-dbg += "${libdir}/${PN}/plugins/.debug"
+
+PACKAGES_prepend = "${PN}-test "
+FILES_${PN}-test_prepend = "${bindir}/test-lms "
+
+PACKAGES += "${PN}-meta"
+ALLOW_EMPTY_${PN}-meta = "1"
+
+PACKAGES_DYNAMIC = "${PN}-plugin-*"
+
+python populate_packages_prepend () {
+    lms_libdir = d.expand('${libdir}/${PN}')
+    pkgs = []
+
+    pkgs += do_split_packages(d, oe.path.join(lms_libdir, "plugins"), '^(.*)\.so$', d.expand('${PN}-plugin-%s'), 'LightMediaScanner plugin for %s', prepend=True, extra_depends=d.expand('${PN}'))
+    metapkg = d.getVar('PN', True) + '-meta'
+    d.setVar('RDEPENDS_' + metapkg, ' '.join(pkgs))
+}
-- 
2.16.6