Merge remote-tracking branch 'agl/sandbox/locust2001/rocko' into HEAD 27/13427/1
authorJan-Simon Möller <jsmoeller@linuxfoundation.org>
Wed, 14 Feb 2018 09:54:52 +0000 (10:54 +0100)
committerJan-Simon Möller <jsmoeller@linuxfoundation.org>
Wed, 14 Feb 2018 09:54:52 +0000 (10:54 +0100)
* agl/sandbox/locust2001/rocko: (33 commits)
  most: remove skb_put_data patch from SRC_URI
  linux-linaro-qcomlt: update to kernel 4.14
  dragonboard-410c: update 96boards-tools recipe
  dragonboard-410c: remove ACCEPT_EULA setting
  00_local.conf.agl.inc: Disable GObject Introspection Data
  linux-ti-staging: Remove linux-dtb.inc
  geoclue: Remove unnecessary dependency
  u-boot-ota: Fix build error with gcc7
  linux-firmware: Remove duplicated lines
  Change image type to wic.vmdk
  glibc: Arrange patch file
  netboot.bbclass: Remove image_types_uboot inheritance
  meta-agl-bsp/classes: Remove bbclass files
  rygel: Arrange rocko
  security-manager: Fix build error that causes gcc v7.0
  cynara: Fix build error that causes gcc v7.0
  libcap: Fix warning
  mesa: Arrange the recipe
  libmicrohttpd: Remove the recipe
  connman: Arrange patch file
  ...

Bug-AGL: SPEC-1181

Change-Id: I8fa84553664fd3d7495b42c7198744f05eebcce0
Signed-off-by: Jan-Simon Möller <jsmoeller@linuxfoundation.org>
66 files changed:
README-AGL.md
README.md
meta-agl-bsp/classes/image-vm.bbclass [deleted file]
meta-agl-bsp/classes/image.bbclass [deleted file]
meta-agl-bsp/classes/sdcard_image-rpi.bbclass [deleted file]
meta-agl-bsp/conf/include/agl_qemux86-64.inc
meta-agl-bsp/meta-intel/recipes-kernel/linux-firmware/linux-firmware_git.bbappend
meta-agl-bsp/meta-qcom/recipes-bsp/96boards-tools/96boards-tools_0.11.bb [moved from meta-agl-bsp/meta-qcom/recipes-bsp/96boards-tools/96boards-tools_0.7.bb with 75% similarity]
meta-agl-bsp/meta-qcom/recipes-kernel/linux/linux-linaro-qcomlt_4.14.bbappend [moved from meta-agl-bsp/meta-qcom/recipes-kernel/linux/linux-linaro-qcomlt_4.9.bbappend with 65% similarity]
meta-agl-bsp/meta-qcom/recipes-kernel/most/most.bbappend [new file with mode: 0644]
meta-agl-bsp/meta-ti/recipes-kernel/linux/linux-ti-staging_%.bbappend
meta-agl-bsp/recipes-bsp/u-boot/u-boot-ota/0002-fixup-build-with-gcc7.patch [new file with mode: 0644]
meta-agl-bsp/recipes-bsp/u-boot/u-boot-ota_2015.07.bb
meta-agl-bsp/recipes-graphics/harfbuzz/harfbuzz_1.4.8.bbappend [moved from meta-agl-bsp/recipes-graphics/harfbuzz/harfbuzz_1.4.1.bbappend with 100% similarity]
meta-agl-bsp/recipes-graphics/mesa/mesa/0001-Use-llvm_prefix-variable-directly.patch [deleted file]
meta-agl-bsp/recipes-graphics/mesa/mesa_%.bbappend
meta-agl-bsp/recipes-kernel/linux/linux-yocto/0001-fanotify-fix-notification-of-groups-with-inode-mount.patch [deleted file]
meta-agl-bsp/recipes-kernel/linux/linux-yocto/4.4-0001-mm-larger-stack-guard-gap-between-vmas.patch [deleted file]
meta-agl-bsp/recipes-kernel/linux/linux-yocto/4.4-0002-Allow-stack-to-grow-up-to-address-space-limit.patch [deleted file]
meta-agl-bsp/recipes-kernel/linux/linux-yocto/4.4-0003-mm-fix-new-crash-in-unmapped_area_topdown.patch [deleted file]
meta-agl-bsp/recipes-kernel/linux/linux-yocto_4.4.bbappend [deleted file]
meta-agl-distro/conf/distro/poky-agl.conf
meta-agl/conf/include/agl-devel.inc
meta-agl/files/group
meta-agl/files/passwd
meta-agl/recipes-connectivity/bluez5/bluez5/cve-2017-1000250.patch [deleted file]
meta-agl/recipes-connectivity/bluez5/bluez5_%.bbappend
meta-agl/recipes-connectivity/connman/files/0001-disable-when-booting-over-nfs.patch
meta-agl/recipes-connectivity/rygel/files/0001-Add-LightMediaScanner-plugin.patch [deleted file]
meta-agl/recipes-connectivity/rygel/files/0002-lms-add-C-source-files.patch [deleted file]
meta-agl/recipes-connectivity/rygel/rygel_%.bbappend
meta-agl/recipes-core/glibc/glibc/arm/local-arm-futex.diff
meta-agl/recipes-core/systemd/systemd/backport-v234-e266c06.patch [deleted file]
meta-agl/recipes-core/systemd/systemd_%.bbappend
meta-agl/recipes-devtools/autogen/autogen-native_5.18.12.bbappend [deleted file]
meta-agl/recipes-devtools/autogen/files/0003-autoopts-mk-tpl-config.sh-fix-shell-path.patch [deleted file]
meta-agl/recipes-multimedia/lightmediascanner/files/0001-Define-comparison_fn_t-for-non-glibc-systems.patch [new file with mode: 0644]
meta-agl/recipes-multimedia/lightmediascanner/files/id3-plugin-support-out-of-tree-build.patch [new file with mode: 0644]
meta-agl/recipes-multimedia/lightmediascanner/lightmediascanner_0.5.1.bb [new file with mode: 0644]
meta-agl/recipes-navigation/geoclue/geoclue_%.bbappend
meta-app-framework/conf/include/agl-appfw-smack.inc
meta-app-framework/recipes-core/security-manager/security-manager/0001-gcc-7-requires-include-functional-for-std-function.patch [new file with mode: 0644]
meta-app-framework/recipes-core/security-manager/security-manager_%.bbappend
meta-app-framework/recipes-kernel/linux/linux-yocto_4.1.bbappend [deleted file]
meta-app-framework/recipes-kernel/linux/linux-yocto_4.12.bbappend [moved from meta-app-framework/recipes-kernel/linux/linux-yocto_4.4.bbappend with 84% similarity]
meta-app-framework/recipes-kernel/linux/linux/linux-yocto-4.1/0001-Smack-File-receive-for-sockets.patch [deleted file]
meta-app-framework/recipes-kernel/linux/linux/linux-yocto-4.1/0002-smack-fix-cache-of-access-labels.patch [deleted file]
meta-app-framework/recipes-kernel/linux/linux/linux-yocto-4.1/0003-Smack-ignore-null-signal-in-smack_task_kill.patch [deleted file]
meta-app-framework/recipes-kernel/linux/linux/linux-yocto-4.1/0004-Smack-Assign-smack_known_web-label-for-kernel-thread.patch [deleted file]
meta-app-framework/recipes-kernel/linux/linux/linux-yocto-4.12/0001-Smack-File-receive-for-sockets.patch [moved from meta-app-framework/recipes-kernel/linux/linux/linux-yocto-4.4/0001-Smack-File-receive-for-sockets.patch with 100% similarity]
meta-app-framework/recipes-kernel/linux/linux/linux-yocto-4.12/0002-smack-fix-cache-of-access-labels.patch [moved from meta-app-framework/recipes-kernel/linux/linux/linux-yocto-4.4/0002-smack-fix-cache-of-access-labels.patch with 100% similarity]
meta-app-framework/recipes-kernel/linux/linux/linux-yocto-4.12/0003-Smack-ignore-null-signal-in-smack_task_kill.patch [moved from meta-app-framework/recipes-kernel/linux/linux/linux-yocto-4.4/0003-Smack-ignore-null-signal-in-smack_task_kill.patch with 100% similarity]
meta-app-framework/recipes-kernel/linux/linux/linux-yocto-4.12/0004-Smack-Assign-smack_known_web-label-for-kernel-thread.patch [moved from meta-app-framework/recipes-kernel/linux/linux/linux-yocto-4.4/0004-Smack-Assign-smack_known_web-label-for-kernel-thread.patch with 100% similarity]
meta-app-framework/recipes-security/cynara/cynara/0001-gcc-7-requires-include-functional-for-std-function.patch [new file with mode: 0644]
meta-app-framework/recipes-security/cynara/cynara_git.bbappend
meta-app-framework/recipes-support/libcap/libcap_%.bbappend
meta-app-framework/recipes-support/libmicrohttpd/libmicrohttpd_0.9.55.bb [deleted file]
meta-ivi-common/recipes-test/freetype/freetype_2.8.bbappend [moved from meta-ivi-common/recipes-test/freetype/freetype_2.7.1.bbappend with 83% similarity]
meta-ivi-common/recipes-test/packagegroups/packagegroup-ivi-common-test.bb
meta-ivi-common/recipes-test/wayland/wayland-fits_%.bbappend [deleted file]
meta-ivi-common/recipes-test/wayland/wayland-fits_git.bbappend [deleted file]
meta-netboot/classes/netboot.bbclass
templates/base/00_local.conf.agl.inc
templates/base/bblayers.conf.sample
templates/feature/agl-sota/50_bblayers.conf.inc
templates/machine/dragonboard-410c/50_setup.sh [deleted file]

index bb6e8aa..146d6ff 100644 (file)
@@ -173,7 +173,7 @@ To build an image from 'meta-agl'
      >      $ bitbake agl-demo-platform
 
  - If you want to run QEMU directly as VM in Virtual Box or your other favorite VM software then add this line to your "conf/local.conf" file.
-     >      IMAGE_FSTYPES += "vmdk"
+     >      IMAGE_FSTYPES += "wic.vmdk"
 
 5. Run in the emulator
      >      $ runqemu agl-image-ivi qemux86-64
@@ -194,7 +194,7 @@ To build an image from 'meta-agl'
      >      $ runqemu agl-image-ivi qemux86-64 bootparams="uvesafb.mode_option=1280x720-32" serial
 
        **Or use the virtual disk in Virtual Box from this location:**
-       > tmp/deploy/images/qemux86-64/agl-demo-platform-qemux86-64.vmdk
+       > tmp/deploy/images/qemux86-64/agl-demo-platform-qemux86-64.wic.vmdk
 
 6.  Some weston samples are available from weston terminal (click top left icon).
    Check the folder `/opt/AGL/ALS2016`.
index fc6a069..8c98eda 100644 (file)
--- a/README.md
+++ b/README.md
@@ -52,7 +52,6 @@ See README-AGL.md
  Specifically out of meta-openembedded these sub-layers are used:
        * meta-openembedded/meta-oe
        * meta-openembedded/meta-multimedia
-       * meta-openembedded/meta-efl
        * meta-openembedded/meta-networking
        * meta-openembedded/meta-python
 
diff --git a/meta-agl-bsp/classes/image-vm.bbclass b/meta-agl-bsp/classes/image-vm.bbclass
deleted file mode 100644 (file)
index ec8f0cb..0000000
+++ /dev/null
@@ -1,181 +0,0 @@
-# image-vm.bbclass
-# (loosly based off image-live.bbclass Copyright (C) 2004, Advanced Micro Devices, Inc.)
-#
-# Create an image which can be placed directly onto a harddisk using dd and then
-# booted.
-#
-# This uses syslinux. extlinux would have been nice but required the ext2/3
-# partition to be mounted. grub requires to run itself as part of the install
-# process.
-#
-# The end result is a 512 boot sector populated with an MBR and partition table
-# followed by an msdos fat16 partition containing syslinux and a linux kernel
-# completed by the ext2/3 rootfs.
-#
-# We have to push the msdos parition table size > 16MB so fat 16 is used as parted
-# won't touch fat12 partitions.
-
-inherit live-vm-common
-
-do_bootdirectdisk[depends] += "dosfstools-native:do_populate_sysroot \
-                               virtual/kernel:do_deploy \
-                               syslinux:do_populate_sysroot \
-                               syslinux-native:do_populate_sysroot \
-                               parted-native:do_populate_sysroot \
-                               mtools-native:do_populate_sysroot \
-                               ${PN}:do_image_${VM_ROOTFS_TYPE} \
-                               "
-
-IMAGE_TYPEDEP_vmdk = "${VM_ROOTFS_TYPE}"
-IMAGE_TYPEDEP_vmdk.xz = "${VM_ROOTFS_TYPE}"
-IMAGE_TYPEDEP_vdi = "${VM_ROOTFS_TYPE}"
-IMAGE_TYPEDEP_qcow2 = "${VM_ROOTFS_TYPE}"
-IMAGE_TYPEDEP_hdddirect = "${VM_ROOTFS_TYPE}"
-IMAGE_TYPES_MASKED += "vmdk vmdk.xz vdi qcow2 hdddirect"
-
-VM_ROOTFS_TYPE ?= "ext4"
-ROOTFS ?= "${IMGDEPLOYDIR}/${IMAGE_LINK_NAME}.${VM_ROOTFS_TYPE}"
-
-# Used by bootloader
-LABELS_VM ?= "boot"
-ROOT_VM ?= "root=/dev/sda2"
-# Using an initramfs is optional. Enable it by setting INITRD_IMAGE_VM.
-INITRD_IMAGE_VM ?= ""
-INITRD_VM ?= "${@'${IMGDEPLOYDIR}/${INITRD_IMAGE_VM}-${MACHINE}.cpio.gz' if '${INITRD_IMAGE_VM}' else ''}"
-do_bootdirectdisk[depends] += "${@'${INITRD_IMAGE_VM}:do_image_complete' if '${INITRD_IMAGE_VM}' else ''}"
-
-BOOTDD_VOLUME_ID   ?= "boot"
-BOOTDD_EXTRA_SPACE ?= "16384"
-
-DISK_SIGNATURE ?= "${DISK_SIGNATURE_GENERATED}"
-DISK_SIGNATURE[vardepsexclude] = "DISK_SIGNATURE_GENERATED"
-
-build_boot_dd() {
-       HDDDIR="${S}/hdd/boot"
-       HDDIMG="${S}/hdd.image"
-       IMAGE=${IMGDEPLOYDIR}/${IMAGE_NAME}.hdddirect
-
-       populate_kernel $HDDDIR
-
-       if [ "${PCBIOS}" = "1" ]; then
-               syslinux_hddimg_populate $HDDDIR
-       fi
-       if [ "${EFI}" = "1" ]; then
-               efi_hddimg_populate $HDDDIR
-       fi
-
-       BLOCKS=`du -bks $HDDDIR | cut -f 1`
-       BLOCKS=`expr $BLOCKS + ${BOOTDD_EXTRA_SPACE}`
-
-       # Remove it since mkdosfs would fail when it exists
-       rm -f $HDDIMG
-       mkdosfs -n ${BOOTDD_VOLUME_ID} -S 512 -C $HDDIMG $BLOCKS 
-       mcopy -i $HDDIMG -s $HDDDIR/* ::/
-
-       if [ "${PCBIOS}" = "1" ]; then
-               syslinux_hdddirect_install $HDDIMG
-       fi      
-       chmod 644 $HDDIMG
-
-       ROOTFSBLOCKS=`du -Lbks ${ROOTFS} | cut -f 1`
-       TOTALSIZE=`expr $BLOCKS + $ROOTFSBLOCKS`
-       END1=`expr $BLOCKS \* 1024`
-       END2=`expr $END1 + 512`
-       END3=`expr \( $ROOTFSBLOCKS \* 1024 \) + $END1`
-
-       echo $ROOTFSBLOCKS $TOTALSIZE $END1 $END2 $END3
-       rm -rf $IMAGE
-       dd if=/dev/zero of=$IMAGE bs=1024 seek=$TOTALSIZE count=1
-
-       parted $IMAGE mklabel msdos
-       parted $IMAGE mkpart primary fat16 0 ${END1}B
-       parted $IMAGE unit B mkpart primary ext2 ${END2}B ${END3}B
-       parted $IMAGE set 1 boot on 
-
-       parted $IMAGE print
-
-       awk "BEGIN { printf \"$(echo ${DISK_SIGNATURE} | sed 's/\(..\)\(..\)\(..\)\(..\)/\\x\4\\x\3\\x\2\\x\1/')\" }" | \
-               dd of=$IMAGE bs=1 seek=440 conv=notrunc
-
-       OFFSET=`expr $END2 / 512`
-       if [ "${PCBIOS}" = "1" ]; then
-               dd if=${STAGING_DATADIR}/syslinux/mbr.bin of=$IMAGE conv=notrunc
-       fi
-
-       dd if=$HDDIMG of=$IMAGE conv=notrunc seek=1 bs=512
-       dd if=${ROOTFS} of=$IMAGE conv=notrunc seek=$OFFSET bs=512
-
-       cd ${IMGDEPLOYDIR}
-
-       ln -sf ${IMAGE_NAME}.hdddirect ${IMGDEPLOYDIR}/${IMAGE_LINK_NAME}.hdddirect
-} 
-
-python do_bootdirectdisk() {
-    validate_disk_signature(d)
-    set_live_vm_vars(d, 'VM')
-    if d.getVar("PCBIOS") == "1":
-        bb.build.exec_func('build_syslinux_cfg', d)
-    if d.getVar("EFI") == "1":
-        bb.build.exec_func('build_efi_cfg', d)
-    bb.build.exec_func('build_boot_dd', d)
-}
-
-def generate_disk_signature():
-    import uuid
-
-    signature = str(uuid.uuid4())[:8]
-
-    if signature != '00000000':
-        return signature
-    else:
-        return 'ffffffff'
-
-def validate_disk_signature(d):
-    import re
-
-    disk_signature = d.getVar("DISK_SIGNATURE")
-
-    if not re.match(r'^[0-9a-fA-F]{8}$', disk_signature):
-        bb.fatal("DISK_SIGNATURE '%s' must be an 8 digit hex string" % disk_signature)
-
-DISK_SIGNATURE_GENERATED := "${@generate_disk_signature()}"
-
-run_qemu_img (){
-    type="$1"
-    qemu-img convert -O $type ${IMGDEPLOYDIR}/${IMAGE_LINK_NAME}.hdddirect ${IMGDEPLOYDIR}/${IMAGE_NAME}.$type
-
-    ln -sf ${IMAGE_NAME}.$type ${IMGDEPLOYDIR}/${IMAGE_LINK_NAME}.$type
-}
-create_vmdk_image () {
-    run_qemu_img vmdk
-}
-
-create_vmdkxz_image () {
-    run_qemu_img vmdk
-    xz -f ${XZ_COMPRESSION_LEVEL} ${XZ_THREADS} --check=${XZ_INTEGRITY_CHECK} ${IMGDEPLOYDIR}/${IMAGE_NAME}.vmdk
-    ln -sf ${IMAGE_NAME}.vmdk.xz ${IMGDEPLOYDIR}/${IMAGE_LINK_NAME}.vmdk.xz
-    rm -f ${IMGDEPLOYDIR}/${IMAGE_LINK_NAME}.vmdk
-}
-
-create_vdi_image () {
-    run_qemu_img vdi
-}
-
-create_qcow2_image () {
-    run_qemu_img qcow2
-}
-
-python do_vmimg() {
-    if bb.utils.contains('IMAGE_FSTYPES', 'vmdk.xz', True, False, d):
-        bb.build.exec_func('create_vmdkxz_image', d)
-    if bb.utils.contains('IMAGE_FSTYPES', 'vmdk', True, False, d):
-        bb.build.exec_func('create_vmdk_image', d)
-    if 'vdi' in d.getVar('IMAGE_FSTYPES', True):
-        bb.build.exec_func('create_vdi_image', d)
-    if 'qcow2' in d.getVar('IMAGE_FSTYPES', True):
-        bb.build.exec_func('create_qcow2_image', d)
-}
-
-addtask bootdirectdisk before do_vmimg
-addtask vmimg after do_bootdirectdisk before do_image_complete
-do_vmimg[depends] += "qemu-native:do_populate_sysroot"
diff --git a/meta-agl-bsp/classes/image.bbclass b/meta-agl-bsp/classes/image.bbclass
deleted file mode 100644 (file)
index ccaffce..0000000
+++ /dev/null
@@ -1,624 +0,0 @@
-inherit rootfs_${IMAGE_PKGTYPE}
-
-# Only Linux SDKs support populate_sdk_ext, fall back to populate_sdk_base
-# in the non-Linux SDK_OS case, such as mingw32
-SDKEXTCLASS ?= "${@['populate_sdk_base', 'populate_sdk_ext']['linux' in d.getVar("SDK_OS")]}"
-inherit ${SDKEXTCLASS}
-
-TOOLCHAIN_TARGET_TASK += "${PACKAGE_INSTALL}"
-TOOLCHAIN_TARGET_TASK_ATTEMPTONLY += "${PACKAGE_INSTALL_ATTEMPTONLY}"
-POPULATE_SDK_POST_TARGET_COMMAND += "rootfs_sysroot_relativelinks; "
-
-LICENSE = "MIT"
-PACKAGES = ""
-DEPENDS += "${MLPREFIX}qemuwrapper-cross depmodwrapper-cross"
-RDEPENDS += "${PACKAGE_INSTALL} ${LINGUAS_INSTALL}"
-RRECOMMENDS += "${PACKAGE_INSTALL_ATTEMPTONLY}"
-
-INHIBIT_DEFAULT_DEPS = "1"
-
-TESTIMAGECLASS = "${@base_conditional('TEST_IMAGE', '1', 'testimage-auto', '', d)}"
-inherit ${TESTIMAGECLASS}
-
-# IMAGE_FEATURES may contain any available package group
-IMAGE_FEATURES ?= ""
-IMAGE_FEATURES[type] = "list"
-IMAGE_FEATURES[validitems] += "debug-tweaks read-only-rootfs empty-root-password allow-empty-password post-install-logging"
-
-# Generate companion debugfs?
-IMAGE_GEN_DEBUGFS ?= "0"
-
-# rootfs bootstrap install
-ROOTFS_BOOTSTRAP_INSTALL = "run-postinsts"
-
-# These packages will be removed from a read-only rootfs after all other
-# packages have been installed
-ROOTFS_RO_UNNEEDED = "update-rc.d base-passwd shadow ${VIRTUAL-RUNTIME_update-alternatives} ${ROOTFS_BOOTSTRAP_INSTALL}"
-
-# packages to install from features
-FEATURE_INSTALL = "${@' '.join(oe.packagegroup.required_packages(oe.data.typed_value('IMAGE_FEATURES', d), d))}"
-FEATURE_INSTALL[vardepvalue] = "${FEATURE_INSTALL}"
-FEATURE_INSTALL_OPTIONAL = "${@' '.join(oe.packagegroup.optional_packages(oe.data.typed_value('IMAGE_FEATURES', d), d))}"
-FEATURE_INSTALL_OPTIONAL[vardepvalue] = "${FEATURE_INSTALL_OPTIONAL}"
-
-# Define some very basic feature package groups
-FEATURE_PACKAGES_package-management = "${ROOTFS_PKGMANAGE}"
-SPLASH ?= "psplash"
-FEATURE_PACKAGES_splash = "${SPLASH}"
-
-IMAGE_INSTALL_COMPLEMENTARY = '${@complementary_globs("IMAGE_FEATURES", d)}'
-
-def check_image_features(d):
-    valid_features = (d.getVarFlag('IMAGE_FEATURES', 'validitems') or "").split()
-    valid_features += d.getVarFlags('COMPLEMENTARY_GLOB').keys()
-    for var in d:
-       if var.startswith("PACKAGE_GROUP_"):
-           bb.warn("PACKAGE_GROUP is deprecated, please use FEATURE_PACKAGES instead")
-           valid_features.append(var[14:])
-       elif var.startswith("FEATURE_PACKAGES_"):
-           valid_features.append(var[17:])
-    valid_features.sort()
-
-    features = set(oe.data.typed_value('IMAGE_FEATURES', d))
-    for feature in features:
-        if feature not in valid_features:
-            if bb.utils.contains('EXTRA_IMAGE_FEATURES', feature, True, False, d):
-                raise bb.parse.SkipRecipe("'%s' in IMAGE_FEATURES (added via EXTRA_IMAGE_FEATURES) is not a valid image feature. Valid features: %s" % (feature, ' '.join(valid_features)))
-            else:
-                raise bb.parse.SkipRecipe("'%s' in IMAGE_FEATURES is not a valid image feature. Valid features: %s" % (feature, ' '.join(valid_features)))
-
-IMAGE_INSTALL ?= ""
-IMAGE_INSTALL[type] = "list"
-export PACKAGE_INSTALL ?= "${IMAGE_INSTALL} ${ROOTFS_BOOTSTRAP_INSTALL} ${FEATURE_INSTALL}"
-PACKAGE_INSTALL_ATTEMPTONLY ?= "${FEATURE_INSTALL_OPTIONAL}"
-
-IMGDEPLOYDIR = "${WORKDIR}/deploy-${PN}-image-complete"
-
-# Images are generally built explicitly, do not need to be part of world.
-EXCLUDE_FROM_WORLD = "1"
-
-USE_DEVFS ?= "1"
-USE_DEPMOD ?= "1"
-
-PID = "${@os.getpid()}"
-
-PACKAGE_ARCH = "${MACHINE_ARCH}"
-
-LDCONFIGDEPEND ?= "ldconfig-native:do_populate_sysroot"
-LDCONFIGDEPEND_libc-uclibc = ""
-LDCONFIGDEPEND_libc-musl = ""
-
-# This is needed to have depmod data in PKGDATA_DIR,
-# but if you're building small initramfs image
-# e.g. to include it in your kernel, you probably
-# don't want this dependency, which is causing dependency loop
-KERNELDEPMODDEPEND ?= "virtual/kernel:do_packagedata"
-
-do_rootfs[depends] += " \
-    makedevs-native:do_populate_sysroot virtual/fakeroot-native:do_populate_sysroot ${LDCONFIGDEPEND} \
-    virtual/update-alternatives-native:do_populate_sysroot update-rc.d-native:do_populate_sysroot \
-    ${KERNELDEPMODDEPEND} \
-"
-do_rootfs[recrdeptask] += "do_packagedata"
-
-def rootfs_command_variables(d):
-    return ['ROOTFS_POSTPROCESS_COMMAND','ROOTFS_PREPROCESS_COMMAND','ROOTFS_POSTINSTALL_COMMAND','ROOTFS_POSTUNINSTALL_COMMAND','OPKG_PREPROCESS_COMMANDS','OPKG_POSTPROCESS_COMMANDS','IMAGE_POSTPROCESS_COMMAND',
-            'IMAGE_PREPROCESS_COMMAND','RPM_PREPROCESS_COMMANDS','RPM_POSTPROCESS_COMMANDS','DEB_PREPROCESS_COMMANDS','DEB_POSTPROCESS_COMMANDS']
-
-python () {
-    variables = rootfs_command_variables(d) + sdk_command_variables(d)
-    for var in variables:
-        if d.getVar(var, False):
-            d.setVarFlag(var, 'func', '1')
-}
-
-def rootfs_variables(d):
-    from oe.rootfs import variable_depends
-    variables = ['IMAGE_DEVICE_TABLE','IMAGE_DEVICE_TABLES','BUILD_IMAGES_FROM_FEEDS','IMAGE_TYPES_MASKED','IMAGE_ROOTFS_ALIGNMENT','IMAGE_OVERHEAD_FACTOR','IMAGE_ROOTFS_SIZE','IMAGE_ROOTFS_EXTRA_SPACE',
-                 'IMAGE_ROOTFS_MAXSIZE','IMAGE_NAME','IMAGE_LINK_NAME','IMAGE_MANIFEST','DEPLOY_DIR_IMAGE','IMAGE_FSTYPES','IMAGE_INSTALL_COMPLEMENTARY','IMAGE_LINGUAS',
-                 'MULTILIBRE_ALLOW_REP','MULTILIB_TEMP_ROOTFS','MULTILIB_VARIANTS','MULTILIBS','ALL_MULTILIB_PACKAGE_ARCHS','MULTILIB_GLOBAL_VARIANTS','BAD_RECOMMENDATIONS','NO_RECOMMENDATIONS',
-                 'PACKAGE_ARCHS','PACKAGE_CLASSES','TARGET_VENDOR','TARGET_ARCH','TARGET_OS','OVERRIDES','BBEXTENDVARIANT','FEED_DEPLOYDIR_BASE_URI','INTERCEPT_DIR','USE_DEVFS',
-                 'CONVERSIONTYPES', 'IMAGE_GEN_DEBUGFS', 'ROOTFS_RO_UNNEEDED', 'IMGDEPLOYDIR', 'PACKAGE_EXCLUDE_COMPLEMENTARY']
-    variables.extend(rootfs_command_variables(d))
-    variables.extend(variable_depends(d))
-    return " ".join(variables)
-
-do_rootfs[vardeps] += "${@rootfs_variables(d)}"
-
-do_build[depends] += "virtual/kernel:do_deploy"
-
-def build_live(d):
-    if bb.utils.contains("IMAGE_FSTYPES", "live", "live", "0", d) == "0": # live is not set but hob might set iso or hddimg
-        d.setVar('NOISO', bb.utils.contains('IMAGE_FSTYPES', "iso", "0", "1", d))
-        d.setVar('NOHDD', bb.utils.contains('IMAGE_FSTYPES', "hddimg", "0", "1", d))
-        if d.getVar('NOISO') == "0" or d.getVar('NOHDD') == "0":
-            return "image-live"
-        return ""
-    return "image-live"
-
-IMAGE_TYPE_live = "${@build_live(d)}"
-inherit ${IMAGE_TYPE_live}
-
-IMAGE_TYPE_vm = '${@bb.utils.contains_any("IMAGE_FSTYPES", ["vmdk", "vmdk.xz", "vdi", "qcow2", "hdddirect"], "image-vm", "", d)}'
-
-inherit ${IMAGE_TYPE_vm}
-
-IMAGE_TYPE_container = '${@bb.utils.contains("IMAGE_FSTYPES", "container", "image-container", "", d)}'
-inherit ${IMAGE_TYPE_container}
-
-def build_uboot(d):
-    if 'u-boot' in (d.getVar('IMAGE_FSTYPES') or ''):
-        return "image_types_uboot"
-    else:
-        return ""
-
-IMAGE_TYPE_uboot = "${@build_uboot(d)}"
-inherit ${IMAGE_TYPE_uboot}
-
-IMAGE_TYPE_wic = "image_types_wic"
-inherit ${IMAGE_TYPE_wic}
-
-python () {
-    def extraimage_getdepends(task):
-        deps = ""
-        for dep in (d.getVar('EXTRA_IMAGEDEPENDS') or "").split():
-            deps += " %s:%s" % (dep, task)
-        return deps
-
-    d.appendVarFlag('do_image', 'depends', extraimage_getdepends('do_populate_lic'))
-    d.appendVarFlag('do_image_complete', 'depends', extraimage_getdepends('do_populate_sysroot'))
-
-    deps = " " + imagetypes_getdepends(d)
-    d.appendVarFlag('do_rootfs', 'depends', deps)
-
-    #process IMAGE_FEATURES, we must do this before runtime_mapping_rename
-    #Check for replaces image features
-    features = set(oe.data.typed_value('IMAGE_FEATURES', d))
-    remain_features = features.copy()
-    for feature in features:
-        replaces = set((d.getVar("IMAGE_FEATURES_REPLACES_%s" % feature) or "").split())
-        remain_features -= replaces
-
-    #Check for conflict image features
-    for feature in remain_features:
-        conflicts = set((d.getVar("IMAGE_FEATURES_CONFLICTS_%s" % feature) or "").split())
-        temp = conflicts & remain_features
-        if temp:
-            bb.fatal("%s contains conflicting IMAGE_FEATURES %s %s" % (d.getVar('PN'), feature, ' '.join(list(temp))))
-
-    d.setVar('IMAGE_FEATURES', ' '.join(sorted(list(remain_features))))
-
-    check_image_features(d)
-    initramfs_image = d.getVar('INITRAMFS_IMAGE') or ""
-    if initramfs_image != "":
-        d.appendVarFlag('do_build', 'depends', " %s:do_bundle_initramfs" %  d.getVar('PN'))
-        d.appendVarFlag('do_bundle_initramfs', 'depends', " %s:do_image_complete" % initramfs_image)
-}
-
-IMAGE_CLASSES += "image_types"
-inherit ${IMAGE_CLASSES}
-
-IMAGE_POSTPROCESS_COMMAND ?= ""
-
-# some default locales
-IMAGE_LINGUAS ?= "de-de fr-fr en-gb"
-
-LINGUAS_INSTALL ?= "${@" ".join(map(lambda s: "locale-base-%s" % s, d.getVar('IMAGE_LINGUAS').split()))}"
-
-# Prefer image, but use the fallback files for lookups if the image ones
-# aren't yet available.
-PSEUDO_PASSWD = "${IMAGE_ROOTFS}:${STAGING_DIR_NATIVE}"
-
-inherit rootfs-postcommands
-
-PACKAGE_EXCLUDE ??= ""
-PACKAGE_EXCLUDE[type] = "list"
-
-fakeroot python do_rootfs () {
-    from oe.rootfs import create_rootfs
-    from oe.manifest import create_manifest
-    import logging
-
-    logger = d.getVar('BB_TASK_LOGGER', False)
-    if logger:
-        logcatcher = bb.utils.LogCatcher()
-        logger.addHandler(logcatcher)
-    else:
-        logcatcher = None
-
-    # NOTE: if you add, remove or significantly refactor the stages of this
-    # process then you should recalculate the weightings here. This is quite
-    # easy to do - just change the MultiStageProgressReporter line temporarily
-    # to pass debug=True as the last parameter and you'll get a printout of
-    # the weightings as well as a map to the lines where next_stage() was
-    # called. Of course this isn't critical, but it helps to keep the progress
-    # reporting accurate.
-    stage_weights = [1, 203, 354, 186, 65, 4228, 1, 353, 49, 330, 382, 23, 1]
-    progress_reporter = bb.progress.MultiStageProgressReporter(d, stage_weights)
-    progress_reporter.next_stage()
-
-    # Handle package exclusions
-    excl_pkgs = d.getVar("PACKAGE_EXCLUDE").split()
-    inst_pkgs = d.getVar("PACKAGE_INSTALL").split()
-    inst_attempt_pkgs = d.getVar("PACKAGE_INSTALL_ATTEMPTONLY").split()
-
-    d.setVar('PACKAGE_INSTALL_ORIG', ' '.join(inst_pkgs))
-    d.setVar('PACKAGE_INSTALL_ATTEMPTONLY', ' '.join(inst_attempt_pkgs))
-
-    for pkg in excl_pkgs:
-        if pkg in inst_pkgs:
-            bb.warn("Package %s, set to be excluded, is in %s PACKAGE_INSTALL (%s).  It will be removed from the list." % (pkg, d.getVar('PN'), inst_pkgs))
-            inst_pkgs.remove(pkg)
-
-        if pkg in inst_attempt_pkgs:
-            bb.warn("Package %s, set to be excluded, is in %s PACKAGE_INSTALL_ATTEMPTONLY (%s).  It will be removed from the list." % (pkg, d.getVar('PN'), inst_pkgs))
-            inst_attempt_pkgs.remove(pkg)
-
-    d.setVar("PACKAGE_INSTALL", ' '.join(inst_pkgs))
-    d.setVar("PACKAGE_INSTALL_ATTEMPTONLY", ' '.join(inst_attempt_pkgs))
-
-    # Ensure we handle package name remapping
-    # We have to delay the runtime_mapping_rename until just before rootfs runs
-    # otherwise, the multilib renaming could step in and squash any fixups that
-    # may have occurred.
-    pn = d.getVar('PN')
-    runtime_mapping_rename("PACKAGE_INSTALL", pn, d)
-    runtime_mapping_rename("PACKAGE_INSTALL_ATTEMPTONLY", pn, d)
-    runtime_mapping_rename("BAD_RECOMMENDATIONS", pn, d)
-
-    # Generate the initial manifest
-    create_manifest(d)
-
-    progress_reporter.next_stage()
-
-    # generate rootfs
-    create_rootfs(d, progress_reporter=progress_reporter, logcatcher=logcatcher)
-
-    progress_reporter.finish()
-}
-do_rootfs[dirs] = "${TOPDIR}"
-do_rootfs[cleandirs] += "${S} ${IMGDEPLOYDIR}"
-do_rootfs[umask] = "022"
-addtask rootfs before do_build after do_prepare_recipe_sysroot
-
-fakeroot python do_image () {
-    from oe.utils import execute_pre_post_process
-
-    pre_process_cmds = d.getVar("IMAGE_PREPROCESS_COMMAND")
-
-    execute_pre_post_process(d, pre_process_cmds)
-}
-do_image[dirs] = "${TOPDIR}"
-do_image[umask] = "022"
-addtask do_image after do_rootfs before do_build
-
-fakeroot python do_image_complete () {
-    from oe.utils import execute_pre_post_process
-
-    post_process_cmds = d.getVar("IMAGE_POSTPROCESS_COMMAND")
-
-    execute_pre_post_process(d, post_process_cmds)
-}
-do_image_complete[dirs] = "${TOPDIR}"
-do_image_complete[umask] = "022"
-SSTATETASKS += "do_image_complete"
-SSTATE_SKIP_CREATION_task-image-complete = '1'
-do_image_complete[sstate-inputdirs] = "${IMGDEPLOYDIR}"
-do_image_complete[sstate-outputdirs] = "${DEPLOY_DIR_IMAGE}"
-do_image_complete[stamp-extra-info] = "${MACHINE}"
-addtask do_image_complete after do_image before do_build
-
-# Add image-level QA/sanity checks to IMAGE_QA_COMMANDS
-#
-# IMAGE_QA_COMMANDS += " \
-#     image_check_everything_ok \
-# "
-# This task runs all functions in IMAGE_QA_COMMANDS after the image
-# construction has completed in order to validate the resulting image.
-fakeroot python do_image_qa () {
-    from oe.utils import ImageQAFailed
-
-    qa_cmds = (d.getVar('IMAGE_QA_COMMANDS') or '').split()
-    qamsg = ""
-
-    for cmd in qa_cmds:
-        try:
-            bb.build.exec_func(cmd, d)
-        except oe.utils.ImageQAFailed as e:
-            qamsg = qamsg + '\tImage QA function %s failed: %s\n' % (e.name, e.description)
-        except bb.build.FuncFailed as e:
-            qamsg = qamsg + '\tImage QA function %s failed' % e.name
-            if e.logfile:
-                qamsg = qamsg + ' (log file is located at %s)' % e.logfile
-            qamsg = qamsg + '\n'
-
-    if qamsg:
-        imgname = d.getVar('IMAGE_NAME')
-        bb.fatal("QA errors found whilst validating image: %s\n%s" % (imgname, qamsg))
-}
-addtask do_image_qa after do_image_complete before do_build
-
-def setup_debugfs_variables(d):
-    d.appendVar('IMAGE_ROOTFS', '-dbg')
-    d.appendVar('IMAGE_LINK_NAME', '-dbg')
-    d.appendVar('IMAGE_NAME','-dbg')
-    d.setVar('IMAGE_BUILDING_DEBUGFS', 'true')
-    debugfs_image_fstypes = d.getVar('IMAGE_FSTYPES_DEBUGFS')
-    if debugfs_image_fstypes:
-        d.setVar('IMAGE_FSTYPES', debugfs_image_fstypes)
-
-python setup_debugfs () {
-    setup_debugfs_variables(d)
-}
-
-python () {
-    vardeps = set()
-    # We allow CONVERSIONTYPES to have duplicates. That avoids breaking
-    # derived distros when OE-core or some other layer independently adds
-    # the same type. There is still only one command for each type, but
-    # presumably the commands will do the same when the type is the same,
-    # even when added in different places.
-    #
-    # Without de-duplication, gen_conversion_cmds() below
-    # would create the same compression command multiple times.
-    ctypes = set(d.getVar('CONVERSIONTYPES').split())
-    old_overrides = d.getVar('OVERRIDES', False)
-
-    def _image_base_type(type):
-        basetype = type
-        for ctype in ctypes:
-            if type.endswith("." + ctype):
-                basetype = type[:-len("." + ctype)]
-                break
-
-        if basetype != type:
-            # New base type itself might be generated by a conversion command.
-            basetype = _image_base_type(basetype)
-
-        return basetype
-
-    basetypes = {}
-    alltypes = d.getVar('IMAGE_FSTYPES').split()
-    typedeps = {}
-
-    if d.getVar('IMAGE_GEN_DEBUGFS') == "1":
-        debugfs_fstypes = d.getVar('IMAGE_FSTYPES_DEBUGFS').split()
-        for t in debugfs_fstypes:
-            alltypes.append("debugfs_" + t)
-
-    def _add_type(t):
-        baset = _image_base_type(t)
-        input_t = t
-        if baset not in basetypes:
-            basetypes[baset]= []
-        if t not in basetypes[baset]:
-            basetypes[baset].append(t)
-        debug = ""
-        if t.startswith("debugfs_"):
-            t = t[8:]
-            debug = "debugfs_"
-        deps = (d.getVar('IMAGE_TYPEDEP_' + t) or "").split()
-        vardeps.add('IMAGE_TYPEDEP_' + t)
-        if baset not in typedeps:
-            typedeps[baset] = set()
-        deps = [debug + dep for dep in deps]
-        for dep in deps:
-            if dep not in alltypes:
-                alltypes.append(dep)
-            _add_type(dep)
-            basedep = _image_base_type(dep)
-            typedeps[baset].add(basedep)
-
-        if baset != input_t:
-            _add_type(baset)
-
-    for t in alltypes[:]:
-        _add_type(t)
-
-    d.appendVarFlag('do_image', 'vardeps', ' '.join(vardeps))
-
-    maskedtypes = (d.getVar('IMAGE_TYPES_MASKED') or "").split()
-    maskedtypes = [dbg + t for t in maskedtypes for dbg in ("", "debugfs_")]
-
-    for t in basetypes:
-        vardeps = set()
-        cmds = []
-        subimages = []
-        realt = t
-
-        if t in maskedtypes:
-            continue
-
-        localdata = bb.data.createCopy(d)
-        debug = ""
-        if t.startswith("debugfs_"):
-            setup_debugfs_variables(localdata)
-            debug = "setup_debugfs "
-            realt = t[8:]
-        localdata.setVar('OVERRIDES', '%s:%s' % (realt, old_overrides))
-        localdata.setVar('type', realt)
-        # Delete DATETIME so we don't expand any references to it now
-        # This means the task's hash can be stable rather than having hardcoded
-        # date/time values. It will get expanded at execution time.
-        # Similarly TMPDIR since otherwise we see QA stamp comparision problems
-        localdata.delVar('DATETIME')
-        localdata.delVar('TMPDIR')
-
-        image_cmd = localdata.getVar("IMAGE_CMD")
-        vardeps.add('IMAGE_CMD_' + realt)
-        if image_cmd:
-            cmds.append("\t" + image_cmd)
-        else:
-            bb.fatal("No IMAGE_CMD defined for IMAGE_FSTYPES entry '%s' - possibly invalid type name or missing support class" % t)
-        cmds.append(localdata.expand("\tcd ${IMGDEPLOYDIR}"))
-
-        # Since a copy of IMAGE_CMD_xxx will be inlined within do_image_xxx,
-        # prevent a redundant copy of IMAGE_CMD_xxx being emitted as a function.
-        d.delVarFlag('IMAGE_CMD_' + realt, 'func')
-
-        rm_tmp_images = set()
-        def gen_conversion_cmds(bt):
-            for ctype in sorted(ctypes):
-                if bt.endswith("." + ctype):
-                    type = bt[0:-len(ctype) - 1]
-                    if type.startswith("debugfs_"):
-                        type = type[8:]
-                    # Create input image first.
-                    gen_conversion_cmds(type)
-                    localdata.setVar('type', type)
-                    cmd = "\t" + (localdata.getVar("CONVERSION_CMD_" + ctype) or localdata.getVar("COMPRESS_CMD_" + ctype))
-                    if cmd not in cmds:
-                        cmds.append(cmd)
-                    vardeps.add('CONVERSION_CMD_' + ctype)
-                    vardeps.add('COMPRESS_CMD_' + ctype)
-                    subimage = type + "." + ctype
-                    if subimage not in subimages:
-                        subimages.append(subimage)
-                    if type not in alltypes:
-                        rm_tmp_images.add(localdata.expand("${IMAGE_NAME}${IMAGE_NAME_SUFFIX}.${type}"))
-
-        for bt in basetypes[t]:
-            gen_conversion_cmds(bt)
-
-        localdata.setVar('type', realt)
-        if t not in alltypes:
-            rm_tmp_images.add(localdata.expand("${IMAGE_NAME}${IMAGE_NAME_SUFFIX}.${type}"))
-        else:
-            subimages.append(realt)
-
-        # Clean up after applying all conversion commands. Some of them might
-        # use the same input, therefore we cannot delete sooner without applying
-        # some complex dependency analysis.
-        for image in sorted(rm_tmp_images):
-            cmds.append("\trm " + image)
-
-        after = 'do_image'
-        for dep in typedeps[t]:
-            after += ' do_image_%s' % dep.replace("-", "_").replace(".", "_")
-
-        t = t.replace("-", "_").replace(".", "_")
-
-        d.setVar('do_image_%s' % t, '\n'.join(cmds))
-        d.setVarFlag('do_image_%s' % t, 'func', '1')
-        d.setVarFlag('do_image_%s' % t, 'fakeroot', '1')
-        d.setVarFlag('do_image_%s' % t, 'prefuncs', debug + 'set_image_size')
-        d.setVarFlag('do_image_%s' % t, 'postfuncs', 'create_symlinks')
-        d.setVarFlag('do_image_%s' % t, 'subimages', ' '.join(subimages))
-        d.appendVarFlag('do_image_%s' % t, 'vardeps', ' '.join(vardeps))
-        d.appendVarFlag('do_image_%s' % t, 'vardepsexclude', 'DATETIME')
-
-        bb.debug(2, "Adding type %s before %s, after %s" % (t, 'do_image_complete', after))
-        bb.build.addtask('do_image_%s' % t, 'do_image_complete', after, d)
-}
-
-#
-# Compute the rootfs size
-#
-def get_rootfs_size(d):
-    import subprocess
-
-    rootfs_alignment = int(d.getVar('IMAGE_ROOTFS_ALIGNMENT'))
-    overhead_factor = float(d.getVar('IMAGE_OVERHEAD_FACTOR'))
-    rootfs_req_size = int(d.getVar('IMAGE_ROOTFS_SIZE'))
-    rootfs_extra_space = eval(d.getVar('IMAGE_ROOTFS_EXTRA_SPACE'))
-    rootfs_maxsize = d.getVar('IMAGE_ROOTFS_MAXSIZE')
-    image_fstypes = d.getVar('IMAGE_FSTYPES') or ''
-    initramfs_fstypes = d.getVar('INITRAMFS_FSTYPES') or ''
-    initramfs_maxsize = d.getVar('INITRAMFS_MAXSIZE')
-
-    output = subprocess.check_output(['du', '-ks',
-                                      d.getVar('IMAGE_ROOTFS')])
-    size_kb = int(output.split()[0])
-    base_size = size_kb * overhead_factor
-    base_size = max(base_size, rootfs_req_size) + rootfs_extra_space
-
-    if base_size != int(base_size):
-        base_size = int(base_size + 1)
-    else:
-        base_size = int(base_size)
-
-    base_size += rootfs_alignment - 1
-    base_size -= base_size % rootfs_alignment
-
-    # Do not check image size of the debugfs image. This is not supposed
-    # to be deployed, etc. so it doesn't make sense to limit the size
-    # of the debug.
-    if (d.getVar('IMAGE_BUILDING_DEBUGFS') or "") == "true":
-        return base_size
-
-    # Check the rootfs size against IMAGE_ROOTFS_MAXSIZE (if set)
-    if rootfs_maxsize:
-        rootfs_maxsize_int = int(rootfs_maxsize)
-        if base_size > rootfs_maxsize_int:
-            bb.fatal("The rootfs size %d(K) overrides IMAGE_ROOTFS_MAXSIZE: %d(K)" % \
-                (base_size, rootfs_maxsize_int))
-
-    # Check the initramfs size against INITRAMFS_MAXSIZE (if set)
-    if image_fstypes == initramfs_fstypes != ''  and initramfs_maxsize:
-        initramfs_maxsize_int = int(initramfs_maxsize)
-        if base_size > initramfs_maxsize_int:
-            bb.error("The initramfs size %d(K) overrides INITRAMFS_MAXSIZE: %d(K)" % \
-                (base_size, initramfs_maxsize_int))
-            bb.error("You can set INITRAMFS_MAXSIZE a larger value. Usually, it should")
-            bb.fatal("be less than 1/2 of ram size, or you may fail to boot it.\n")
-    return base_size
-
-python set_image_size () {
-        rootfs_size = get_rootfs_size(d)
-        d.setVar('ROOTFS_SIZE', str(rootfs_size))
-        d.setVarFlag('ROOTFS_SIZE', 'export', '1')
-}
-
-#
-# Create symlinks to the newly created image
-#
-python create_symlinks() {
-
-    deploy_dir = d.getVar('IMGDEPLOYDIR')
-    img_name = d.getVar('IMAGE_NAME')
-    link_name = d.getVar('IMAGE_LINK_NAME')
-    manifest_name = d.getVar('IMAGE_MANIFEST')
-    taskname = d.getVar("BB_CURRENTTASK")
-    subimages = (d.getVarFlag("do_" + taskname, 'subimages', False) or "").split()
-    imgsuffix = d.getVarFlag("do_" + taskname, 'imgsuffix') or d.expand("${IMAGE_NAME_SUFFIX}.")
-
-    if not link_name:
-        return
-    for type in subimages:
-        dst = os.path.join(deploy_dir, link_name + "." + type)
-        src = img_name + imgsuffix + type
-        if os.path.exists(os.path.join(deploy_dir, src)):
-            bb.note("Creating symlink: %s -> %s" % (dst, src))
-            if os.path.islink(dst):
-                os.remove(dst)
-            os.symlink(src, dst)
-        else:
-            bb.note("Skipping symlink, source does not exist: %s -> %s" % (dst, src))
-}
-
-MULTILIBRE_ALLOW_REP =. "${base_bindir}|${base_sbindir}|${bindir}|${sbindir}|${libexecdir}|${sysconfdir}|${nonarch_base_libdir}/udev|/lib/modules/[^/]*/modules.*|"
-MULTILIB_CHECK_FILE = "${WORKDIR}/multilib_check.py"
-MULTILIB_TEMP_ROOTFS = "${WORKDIR}/multilib"
-
-do_fetch[noexec] = "1"
-do_unpack[noexec] = "1"
-do_patch[noexec] = "1"
-do_configure[noexec] = "1"
-do_compile[noexec] = "1"
-do_install[noexec] = "1"
-deltask do_populate_sysroot
-do_package[noexec] = "1"
-deltask do_package_qa
-do_packagedata[noexec] = "1"
-do_package_write_ipk[noexec] = "1"
-do_package_write_deb[noexec] = "1"
-do_package_write_rpm[noexec] = "1"
-
-# Allow the kernel to be repacked with the initramfs and boot image file as a single file
-do_bundle_initramfs[depends] += "virtual/kernel:do_bundle_initramfs"
-do_bundle_initramfs[nostamp] = "1"
-do_bundle_initramfs[noexec] = "1"
-do_bundle_initramfs () {
-       :
-}
-addtask bundle_initramfs after do_image_complete
diff --git a/meta-agl-bsp/classes/sdcard_image-rpi.bbclass b/meta-agl-bsp/classes/sdcard_image-rpi.bbclass
deleted file mode 100644 (file)
index c22a6f8..0000000
+++ /dev/null
@@ -1,184 +0,0 @@
-inherit image_types
-inherit linux-raspberrypi-base
-
-#
-# Create an image that can by written onto a SD card using dd.
-#
-# The disk layout used is:
-#
-#    0                      -> IMAGE_ROOTFS_ALIGNMENT         - reserved for other data
-#    IMAGE_ROOTFS_ALIGNMENT -> BOOT_SPACE                     - bootloader and kernel
-#    BOOT_SPACE             -> SDIMG_SIZE                     - rootfs
-#
-
-#                                                     Default Free space = 1.3x
-#                                                     Use IMAGE_OVERHEAD_FACTOR to add more space
-#                                                     <--------->
-#            4MiB              40MiB           SDIMG_ROOTFS
-# <-----------------------> <----------> <---------------------->
-#  ------------------------ ------------ ------------------------
-# | IMAGE_ROOTFS_ALIGNMENT | BOOT_SPACE | ROOTFS_SIZE            |
-#  ------------------------ ------------ ------------------------
-# ^                        ^            ^                        ^
-# |                        |            |                        |
-# 0                      4MiB     4MiB + 40MiB       4MiB + 40Mib + SDIMG_ROOTFS
-
-# This image depends on the rootfs image
-IMAGE_TYPEDEP_rpi-sdimg = "${SDIMG_ROOTFS_TYPE}"
-
-# Set kernel and boot loader
-IMAGE_BOOTLOADER ?= "bcm2835-bootfiles"
-
-# Set initramfs extension
-KERNEL_INITRAMFS ?= ""
-
-# Kernel image name
-SDIMG_KERNELIMAGE_raspberrypi  ?= "kernel.img"
-SDIMG_KERNELIMAGE_raspberrypi2 ?= "kernel7.img"
-SDIMG_KERNELIMAGE_raspberrypi3-64 ?= "kernel8.img"
-
-# Boot partition volume id
-BOOTDD_VOLUME_ID ?= "${MACHINE}"
-
-# Boot partition size [in KiB] (will be rounded up to IMAGE_ROOTFS_ALIGNMENT)
-BOOT_SPACE ?= "40960"
-
-# Set alignment to 4MB [in KiB]
-IMAGE_ROOTFS_ALIGNMENT = "4096"
-
-# Use an uncompressed ext3 by default as rootfs
-SDIMG_ROOTFS_TYPE ?= "ext3"
-SDIMG_ROOTFS = "${IMGDEPLOYDIR}/${IMAGE_NAME}.rootfs.${SDIMG_ROOTFS_TYPE}"
-
-IMAGE_DEPENDS_rpi-sdimg = " \
-                       parted-native \
-                       mtools-native \
-                       dosfstools-native \
-                       virtual/kernel:do_deploy \
-                       ${IMAGE_BOOTLOADER} \
-                       ${@bb.utils.contains('KERNEL_IMAGETYPE', 'uImage', 'u-boot', '',d)} \
-                       "
-
-# SD card image name
-SDIMG = "${IMGDEPLOYDIR}/${IMAGE_NAME}.rootfs.rpi-sdimg"
-
-# Compression method to apply to SDIMG after it has been created. Supported
-# compression formats are "gzip", "bzip2" or "xz". The original .rpi-sdimg file
-# is kept and a new compressed file is created if one of these compression
-# formats is chosen. If SDIMG_COMPRESSION is set to any other value it is
-# silently ignored.
-#SDIMG_COMPRESSION ?= ""
-
-# Additional files and/or directories to be copied into the vfat partition from the IMAGE_ROOTFS.
-FATPAYLOAD ?= ""
-
-IMAGE_CMD_rpi-sdimg () {
-
-       # Align partitions
-       BOOT_SPACE_ALIGNED=$(expr ${BOOT_SPACE} + ${IMAGE_ROOTFS_ALIGNMENT} - 1)
-       BOOT_SPACE_ALIGNED=$(expr ${BOOT_SPACE_ALIGNED} - ${BOOT_SPACE_ALIGNED} % ${IMAGE_ROOTFS_ALIGNMENT})
-       SDIMG_SIZE=$(expr ${IMAGE_ROOTFS_ALIGNMENT} + ${BOOT_SPACE_ALIGNED} + $ROOTFS_SIZE)
-
-       echo "Creating filesystem with Boot partition ${BOOT_SPACE_ALIGNED} KiB and RootFS $ROOTFS_SIZE KiB"
-
-       # Check if we are building with device tree support
-       DTS="${@get_dts(d)}"
-
-       # Initialize sdcard image file
-       dd if=/dev/zero of=${SDIMG} bs=1024 count=0 seek=${SDIMG_SIZE}
-
-       # Create partition table
-       parted -s ${SDIMG} mklabel msdos
-       # Create boot partition and mark it as bootable
-       parted -s ${SDIMG} unit KiB mkpart primary fat32 ${IMAGE_ROOTFS_ALIGNMENT} $(expr ${BOOT_SPACE_ALIGNED} \+ ${IMAGE_ROOTFS_ALIGNMENT})
-       parted -s ${SDIMG} set 1 boot on
-       # Create rootfs partition to the end of disk
-       parted -s ${SDIMG} -- unit KiB mkpart primary ext2 $(expr ${BOOT_SPACE_ALIGNED} \+ ${IMAGE_ROOTFS_ALIGNMENT}) -1s
-       parted ${SDIMG} print
-
-       # Create a vfat image with boot files
-       BOOT_BLOCKS=$(LC_ALL=C parted -s ${SDIMG} unit b print | awk '/ 1 / { print substr($4, 1, length($4 -1)) / 512 /2 }')
-       rm -f ${WORKDIR}/boot.img
-       mkfs.vfat -n "${BOOTDD_VOLUME_ID}" -S 512 -C ${WORKDIR}/boot.img $BOOT_BLOCKS
-       mcopy -i ${WORKDIR}/boot.img -s ${DEPLOY_DIR_IMAGE}/bcm2835-bootfiles/* ::/
-       if test -n "${DTS}"; then
-               # Device Tree Overlays are assumed to be suffixed by '-overlay.dtb' (4.1.x) or by '.dtbo' (4.4.9+) string and will be put in a dedicated folder
-               DT_OVERLAYS="${@split_overlays(d, 0)}"
-               DT_ROOT="${@split_overlays(d, 1)}"
-
-               # Copy board device trees to root folder
-               for DTB in ${DT_ROOT}; do
-                       DTB_BASE_NAME=`basename ${DTB} .dtb`
-
-                       mcopy -i ${WORKDIR}/boot.img -s ${DEPLOY_DIR_IMAGE}/${KERNEL_IMAGETYPE}-${DTB_BASE_NAME}.dtb ::${DTB_BASE_NAME}.dtb
-               done
-
-               # Copy device tree overlays to dedicated folder
-               mmd -i ${WORKDIR}/boot.img overlays
-               for DTB in ${DT_OVERLAYS}; do
-                               DTB_EXT=${DTB##*.}
-                               DTB_BASE_NAME=`basename ${DTB} ."${DTB_EXT}"`
-
-                       mcopy -i ${WORKDIR}/boot.img -s ${DEPLOY_DIR_IMAGE}/${KERNEL_IMAGETYPE}-${DTB_BASE_NAME}.${DTB_EXT} ::overlays/${DTB_BASE_NAME}.${DTB_EXT}
-               done
-       fi
-       case "${KERNEL_IMAGETYPE}" in
-       "uImage")
-               mcopy -i ${WORKDIR}/boot.img -s ${DEPLOY_DIR_IMAGE}/u-boot.bin ::${SDIMG_KERNELIMAGE}
-               mcopy -i ${WORKDIR}/boot.img -s ${DEPLOY_DIR_IMAGE}/${KERNEL_IMAGETYPE}${KERNEL_INITRAMFS}-${MACHINE}.bin ::uImage
-               mcopy -o -i ${WORKDIR}/boot.img -s ${DEPLOY_DIR_IMAGE}/boot.scr ::boot.scr
-               ;;
-       *)
-               mcopy -i ${WORKDIR}/boot.img -s ${DEPLOY_DIR_IMAGE}/${KERNEL_IMAGETYPE}${KERNEL_INITRAMFS}-${MACHINE}.bin ::${SDIMG_KERNELIMAGE}
-               ;;
-       esac
-
-       if [ -n ${FATPAYLOAD} ] ; then
-               echo "Copying payload into VFAT"
-               for entry in ${FATPAYLOAD} ; do
-                               # add the || true to stop aborting on vfat issues like not supporting .~lock files
-                               mcopy -i ${WORKDIR}/boot.img -s -v ${IMAGE_ROOTFS}$entry :: || true
-               done
-       fi
-
-       # Add stamp file
-       echo "${IMAGE_NAME}" > ${WORKDIR}/image-version-info
-       mcopy -i ${WORKDIR}/boot.img -v ${WORKDIR}/image-version-info ::
-
-       # Burn Partitions
-       dd if=${WORKDIR}/boot.img of=${SDIMG} conv=notrunc seek=1 bs=$(expr ${IMAGE_ROOTFS_ALIGNMENT} \* 1024) && sync && sync
-       # If SDIMG_ROOTFS_TYPE is a .xz file use xzcat
-       if echo "${SDIMG_ROOTFS_TYPE}" | egrep -q "*\.xz"
-       then
-               xzcat ${SDIMG_ROOTFS} | dd of=${SDIMG} conv=notrunc seek=1 bs=$(expr 1024 \* ${BOOT_SPACE_ALIGNED} + ${IMAGE_ROOTFS_ALIGNMENT} \* 1024) && sync && sync
-       else
-               dd if=${SDIMG_ROOTFS} of=${SDIMG} conv=notrunc seek=1 bs=$(expr 1024 \* ${BOOT_SPACE_ALIGNED} + ${IMAGE_ROOTFS_ALIGNMENT} \* 1024) && sync && sync
-       fi
-
-       # Optionally apply compression
-       case "${SDIMG_COMPRESSION}" in
-       "gzip")
-               gzip -k9 "${SDIMG}"
-               ;;
-       "bzip2")
-               bzip2 -k9 "${SDIMG}"
-               ;;
-       "xz")
-               xz -k "${SDIMG}"
-               ;;
-       esac
-}
-
-ROOTFS_POSTPROCESS_COMMAND += " rpi_generate_sysctl_config ; "
-
-rpi_generate_sysctl_config() {
-       # systemd sysctl config
-       test -d ${IMAGE_ROOTFS}${sysconfdir}/sysctl.d && \
-               echo "vm.min_free_kbytes = 8192" > ${IMAGE_ROOTFS}${sysconfdir}/sysctl.d/rpi-vm.conf
-
-       # sysv sysctl config
-       IMAGE_SYSCTL_CONF="${IMAGE_ROOTFS}${sysconfdir}/sysctl.conf"
-       test -e ${IMAGE_ROOTFS}${sysconfdir}/sysctl.conf && \
-               sed -e "/vm.min_free_kbytes/d" -i ${IMAGE_SYSCTL_CONF}
-       echo "" >> ${IMAGE_SYSCTL_CONF} && echo "vm.min_free_kbytes = 8192" >> ${IMAGE_SYSCTL_CONF}
-}
index 3ad9c51..165deae 100644 (file)
@@ -21,7 +21,8 @@ APPEND += "quiet"
 DISTRO_FEATURES_append = " sota"
 
 # Image support
-AGL_EXTRA_IMAGE_FSTYPES = "vmdk.xz"
+AGL_EXTRA_IMAGE_FSTYPES = "wic.vmdk"
+IMAGE_BOOT_FILES_sota = "u-boot-qemux86-64.rom"
 
 # Root device
 ROOT_VM = "root=PARTUUID=${DISK_SIGNATURE}-02"
index a34159c..824f393 100644 (file)
@@ -1,8 +1,3 @@
-LICENSE_${PN}-ibt-license              = "Firmware-ibt_firmware"
-LICENSE_${PN}-ibt-11-5                 = "Firmware-ibt_firmware"
-FILES_${PN}-ibt-license                = "/lib/firmware/LICENCE.ibt_firmware"
 FILES_${PN}-ibt                 = "/lib/firmware/intel"
 
 RDEPENDS_${PN}-ibt      += "${PN}-ibt-license"
-
-PACKAGES =+ " ${PN}-ibt-license ${PN}-ibt "
@@ -5,16 +5,18 @@ SECTION = "devel"
 LICENSE = "GPLv2+"
 LIC_FILES_CHKSUM = "file://${COREBASE}/meta/files/common-licenses/GPL-2.0;md5=801f80980d171dd6425610833a22dbe6"
 
-SRCREV = "193f355823d9dc38f370759153ac950a2833b0e2"
+SRCREV = "395b5994a5fa52f9db10f480fce74e9acdbe3318"
 SRC_URI = "git://github.com/96boards/96boards-tools;branch=master;protocol=https"
 
 S = "${WORKDIR}/git"
 
-inherit systemd allarch
+inherit systemd allarch update-rc.d
 
 do_install () {
     install -d ${D}${sysconfdir}/udev/rules.d
     install -m 0755 ${S}/*.rules ${D}${sysconfdir}/udev/rules.d/
+    install -d ${D}${sysconfdir}/init.d
+    install -m 0755 ${S}/resize-disk ${D}${sysconfdir}/init.d/
 
     install -d ${D}${systemd_unitdir}/system
     install -m 0644 ${S}/resize-helper.service ${D}${systemd_unitdir}/system
@@ -23,5 +25,8 @@ do_install () {
     install -m 0755 ${S}/resize-helper ${D}${sbindir}
 }
 
+INITSCRIPT_NAME = "resize-disk"
+INITSCRIPT_PARAMS = "start 99 5 2 . stop 20 0 1 6 ."
+
 SYSTEMD_SERVICE_${PN} = "resize-helper.service"
 RDEPENDS_${PN} += "e2fsprogs-resize2fs gptfdisk parted util-linux udev"
diff --git a/meta-agl-bsp/meta-qcom/recipes-kernel/most/most.bbappend b/meta-agl-bsp/meta-qcom/recipes-kernel/most/most.bbappend
new file mode 100644 (file)
index 0000000..6b4444a
--- /dev/null
@@ -0,0 +1,5 @@
+FILESEXTRAPATHS_prepend := "${THISDIR}/files:"
+
+SRC_URI_remove = " \
+           file://0001-src-most-net-add-skb_put_data-function.patch \
+          "
index 283e8b7..0216141 100644 (file)
@@ -1,4 +1,2 @@
-require recipes-kernel/linux/linux-dtb.inc
-
 require recipes-kernel/linux/linux-agl.inc
 require recipes-kernel/linux/linux-agl-4.9.inc
diff --git a/meta-agl-bsp/recipes-bsp/u-boot/u-boot-ota/0002-fixup-build-with-gcc7.patch b/meta-agl-bsp/recipes-bsp/u-boot/u-boot-ota/0002-fixup-build-with-gcc7.patch
new file mode 100644 (file)
index 0000000..fc7933e
--- /dev/null
@@ -0,0 +1,101 @@
+From eea58226f0b604d3047c495985197113838d3a7a Mon Sep 17 00:00:00 2001
+From: Trevor Woerner <twoerner@gmail.com>
+Date: Tue, 20 Jun 2017 13:25:20 -0400
+Subject: [PATCH] fix build for gcc7
+
+| In file included from .../include/linux/compiler.h:54:0,
+|                  from .../include/uapi/linux/stddef.h:1,
+|                  from .../include/linux/stddef.h:4,
+|                  from .../include/uapi/linux/posix_types.h:4,
+|                  from .../include/uapi/linux/types.h:13,
+|                  from .../include/linux/types.h:5,
+|                  from .../include/linux/mod_devicetable.h:11,
+|                  from .../scripts/mod/devicetable-offsets.c:2:
+| .../include/linux/compiler-gcc.h:121:1: fatal error: linux/compiler-gcc7.h: No such file or directory
+|  #include gcc_header(__GNUC__)
+
+Upstream-Status: Pending
+
+Signed-off-by: Trevor Woerner <twoerner@gmail.com>
+Signed-off-by: Fabio Berton <fabio.berton@gmail.com>
+Signed-off-by: Leon Anavi <leon.anavi@konsulko.com>
+---
+ include/linux/compiler-gcc7.h | 66 +++++++++++++++++++++++++++++++++++++++++++
+ 1 file changed, 66 insertions(+)
+ create mode 100644 include/linux/compiler-gcc7.h
+
+diff --git a/include/linux/compiler-gcc7.h b/include/linux/compiler-gcc7.h
+new file mode 100644
+index 0000000..cdd1cc2
+--- /dev/null
++++ b/include/linux/compiler-gcc7.h
+@@ -0,0 +1,66 @@
++#ifndef __LINUX_COMPILER_H
++#error "Please don't include <linux/compiler-gcc5.h> directly, include <linux/compiler.h> instead."
++#endif
++
++#define __used                                __attribute__((__used__))
++#define __must_check                  __attribute__((warn_unused_result))
++#define __compiler_offsetof(a, b)     __builtin_offsetof(a, b)
++
++/* Mark functions as cold. gcc will assume any path leading to a call
++   to them will be unlikely.  This means a lot of manual unlikely()s
++   are unnecessary now for any paths leading to the usual suspects
++   like BUG(), printk(), panic() etc. [but let's keep them for now for
++   older compilers]
++
++   Early snapshots of gcc 4.3 don't support this and we can't detect this
++   in the preprocessor, but we can live with this because they're unreleased.
++   Maketime probing would be overkill here.
++
++   gcc also has a __attribute__((__hot__)) to move hot functions into
++   a special section, but I don't see any sense in this right now in
++   the kernel context */
++#define __cold                        __attribute__((__cold__))
++
++#define __UNIQUE_ID(prefix) __PASTE(__PASTE(__UNIQUE_ID_, prefix), __COUNTER__)
++
++#ifndef __CHECKER__
++# define __compiletime_warning(message) __attribute__((warning(message)))
++# define __compiletime_error(message) __attribute__((error(message)))
++#endif /* __CHECKER__ */
++
++/*
++ * Mark a position in code as unreachable.  This can be used to
++ * suppress control flow warnings after asm blocks that transfer
++ * control elsewhere.
++ *
++ * Early snapshots of gcc 4.5 don't support this and we can't detect
++ * this in the preprocessor, but we can live with this because they're
++ * unreleased.  Really, we need to have autoconf for the kernel.
++ */
++#define unreachable() __builtin_unreachable()
++
++/* Mark a function definition as prohibited from being cloned. */
++#define __noclone     __attribute__((__noclone__))
++
++/*
++ * Tell the optimizer that something else uses this function or variable.
++ */
++#define __visible __attribute__((externally_visible))
++
++/*
++ * GCC 'asm goto' miscompiles certain code sequences:
++ *
++ *   http://gcc.gnu.org/bugzilla/show_bug.cgi?id=58670
++ *
++ * Work it around via a compiler barrier quirk suggested by Jakub Jelinek.
++ * Fixed in GCC 4.8.2 and later versions.
++ *
++ * (asm goto is automatically volatile - the naming reflects this.)
++ */
++#define asm_volatile_goto(x...)       do { asm goto(x); asm (""); } while (0)
++
++#ifdef CONFIG_ARCH_USE_BUILTIN_BSWAP
++#define __HAVE_BUILTIN_BSWAP32__
++#define __HAVE_BUILTIN_BSWAP64__
++#define __HAVE_BUILTIN_BSWAP16__
++#endif /* CONFIG_ARCH_USE_BUILTIN_BSWAP */
+-- 
+2.7.4
+
index 37abc5a..7ef3cac 100644 (file)
@@ -14,6 +14,7 @@ SRC_URI = "\
     file://0001-Set-up-environment-for-OSTree-integration.patch \
     file://0002-Replace-wraps-with-built-in-code-to-remove-dependenc.patch \
     file://0001-fixup-build-with-gcc6.patch \
+    file://0002-fixup-build-with-gcc7.patch \
 "
 S = "${WORKDIR}/git"
 
diff --git a/meta-agl-bsp/recipes-graphics/mesa/mesa/0001-Use-llvm_prefix-variable-directly.patch b/meta-agl-bsp/recipes-graphics/mesa/mesa/0001-Use-llvm_prefix-variable-directly.patch
deleted file mode 100644 (file)
index 4f19054..0000000
+++ /dev/null
@@ -1,25 +0,0 @@
-From 0b316ee830765eb1d68cdece5fd4c991e9fba96c Mon Sep 17 00:00:00 2001
-From: Changhyeok Bae <changhyeok.bae@gmail.com>
-Date: Sat, 8 Jul 2017 15:22:09 +0900
-Subject: [PATCH] Use $llvm_prefix variable directly
-
----
- configure.ac | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-diff --git a/configure.ac b/configure.ac
-index ac110e8..d094ca6 100644
---- a/configure.ac
-+++ b/configure.ac
-@@ -896,7 +896,7 @@ fi
- if test -z "$LLVM_CONFIG"; then
-     if test -n "$llvm_prefix"; then
--        AC_PATH_TOOL([LLVM_CONFIG], [llvm-config], [no], ["$llvm_prefix/bin"])
-+        AC_PATH_TOOL([LLVM_CONFIG], [llvm-config], [no], ["$llvm_prefix"])
-     else
-         AC_PATH_TOOL([LLVM_CONFIG], [llvm-config], [no])
-     fi
--- 
-1.9.1
-
index 1327379..49e5277 100644 (file)
@@ -1,7 +1,3 @@
-FILESEXTRAPATHS_prepend_qemux86-64 := "${THISDIR}/${BPN}:"
-SRC_URI_append_qemux86-64 = " file://0001-Use-llvm_prefix-variable-directly.patch"
-EXTRA_OECONF_qemux86-64 = "--enable-shared-glapi --with-llvm-prefix=${STAGING_BINDIR_CROSS}"
-
 # The gallium-llvm is recommended as software 3D graphics renderer
 GALLIUM_LLVM = "gallium-llvm"
 PACKAGECONFIG_append_qemux86 = " gallium ${GALLIUM_LLVM}"
diff --git a/meta-agl-bsp/recipes-kernel/linux/linux-yocto/0001-fanotify-fix-notification-of-groups-with-inode-mount.patch b/meta-agl-bsp/recipes-kernel/linux/linux-yocto/0001-fanotify-fix-notification-of-groups-with-inode-mount.patch
deleted file mode 100644 (file)
index c50c152..0000000
+++ /dev/null
@@ -1,206 +0,0 @@
-From 8edc6e1688fc8f02c8c1f53a2ec4928cb1055f4d Mon Sep 17 00:00:00 2001
-From: Jan Kara <jack@suse.cz>
-Date: Thu, 13 Nov 2014 15:19:33 -0800
-Subject: [PATCH] fanotify: fix notification of groups with inode & mount marks
-
-fsnotify() needs to merge inode and mount marks lists when notifying
-groups about events so that ignore masks from inode marks are reflected
-in mount mark notifications and groups are notified in proper order
-(according to priorities).
-
-Currently the sorting of the lists done by fsnotify_add_inode_mark() /
-fsnotify_add_vfsmount_mark() and fsnotify() differed which resulted
-ignore masks not being used in some cases.
-
-Fix the problem by always using the same comparison function when
-sorting / merging the mark lists.
-
-Thanks to Heinrich Schuchardt for improvements of my patch.
-
-Link: https://bugzilla.kernel.org/show_bug.cgi?id=87721
-Signed-off-by: Jan Kara <jack@suse.cz>
-Reported-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
-Tested-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
-Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
-Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
----
- fs/notify/fsnotify.c      | 36 +++++++++++++++++++++---------------
- fs/notify/fsnotify.h      |  4 ++++
- fs/notify/inode_mark.c    |  8 +++-----
- fs/notify/mark.c          | 36 ++++++++++++++++++++++++++++++++++++
- fs/notify/vfsmount_mark.c |  8 +++-----
- 5 files changed, 67 insertions(+), 25 deletions(-)
-
-diff --git a/fs/notify/fsnotify.c b/fs/notify/fsnotify.c
-index 9d3e9c5..89326ac 100644
---- a/fs/notify/fsnotify.c
-+++ b/fs/notify/fsnotify.c
-@@ -229,8 +229,16 @@ int fsnotify(struct inode *to_tell, __u32 mask, void *data, int data_is,
-                                             &fsnotify_mark_srcu);
-       }
-+      /*
-+       * We need to merge inode & vfsmount mark lists so that inode mark
-+       * ignore masks are properly reflected for mount mark notifications.
-+       * That's why this traversal is so complicated...
-+       */
-       while (inode_node || vfsmount_node) {
--              inode_group = vfsmount_group = NULL;
-+              inode_group = NULL;
-+              inode_mark = NULL;
-+              vfsmount_group = NULL;
-+              vfsmount_mark = NULL;
-               if (inode_node) {
-                       inode_mark = hlist_entry(srcu_dereference(inode_node, &fsnotify_mark_srcu),
-@@ -244,21 +252,19 @@ int fsnotify(struct inode *to_tell, __u32 mask, void *data, int data_is,
-                       vfsmount_group = vfsmount_mark->group;
-               }
--              if (inode_group > vfsmount_group) {
--                      /* handle inode */
--                      ret = send_to_group(to_tell, inode_mark, NULL, mask,
--                                          data, data_is, cookie, file_name);
--                      /* we didn't use the vfsmount_mark */
--                      vfsmount_group = NULL;
--              } else if (vfsmount_group > inode_group) {
--                      ret = send_to_group(to_tell, NULL, vfsmount_mark, mask,
--                                          data, data_is, cookie, file_name);
--                      inode_group = NULL;
--              } else {
--                      ret = send_to_group(to_tell, inode_mark, vfsmount_mark,
--                                          mask, data, data_is, cookie,
--                                          file_name);
-+              if (inode_group && vfsmount_group) {
-+                      int cmp = fsnotify_compare_groups(inode_group,
-+                                                        vfsmount_group);
-+                      if (cmp > 0) {
-+                              inode_group = NULL;
-+                              inode_mark = NULL;
-+                      } else if (cmp < 0) {
-+                              vfsmount_group = NULL;
-+                              vfsmount_mark = NULL;
-+                      }
-               }
-+              ret = send_to_group(to_tell, inode_mark, vfsmount_mark, mask,
-+                                  data, data_is, cookie, file_name);
-               if (ret && (mask & ALL_FSNOTIFY_PERM_EVENTS))
-                       goto out;
-diff --git a/fs/notify/fsnotify.h b/fs/notify/fsnotify.h
-index 9c0898c..3b68b0a 100644
---- a/fs/notify/fsnotify.h
-+++ b/fs/notify/fsnotify.h
-@@ -12,6 +12,10 @@ extern void fsnotify_flush_notify(struct fsnotify_group *group);
- /* protects reads of inode and vfsmount marks list */
- extern struct srcu_struct fsnotify_mark_srcu;
-+/* compare two groups for sorting of marks lists */
-+extern int fsnotify_compare_groups(struct fsnotify_group *a,
-+                                 struct fsnotify_group *b);
-+
- extern void fsnotify_set_inode_mark_mask_locked(struct fsnotify_mark *fsn_mark,
-                                               __u32 mask);
- /* add a mark to an inode */
-diff --git a/fs/notify/inode_mark.c b/fs/notify/inode_mark.c
-index e849714..dfbf544 100644
---- a/fs/notify/inode_mark.c
-+++ b/fs/notify/inode_mark.c
-@@ -194,6 +194,7 @@ int fsnotify_add_inode_mark(struct fsnotify_mark *mark,
- {
-       struct fsnotify_mark *lmark, *last = NULL;
-       int ret = 0;
-+      int cmp;
-       mark->flags |= FSNOTIFY_MARK_FLAG_INODE;
-@@ -219,11 +220,8 @@ int fsnotify_add_inode_mark(struct fsnotify_mark *mark,
-                       goto out;
-               }
--              if (mark->group->priority < lmark->group->priority)
--                      continue;
--
--              if ((mark->group->priority == lmark->group->priority) &&
--                  (mark->group < lmark->group))
-+              cmp = fsnotify_compare_groups(lmark->group, mark->group);
-+              if (cmp < 0)
-                       continue;
-               hlist_add_before_rcu(&mark->i.i_list, &lmark->i.i_list);
-diff --git a/fs/notify/mark.c b/fs/notify/mark.c
-index d90deaa..34c38fa 100644
---- a/fs/notify/mark.c
-+++ b/fs/notify/mark.c
-@@ -210,6 +210,42 @@ void fsnotify_set_mark_ignored_mask_locked(struct fsnotify_mark *mark, __u32 mas
- }
- /*
-+ * Sorting function for lists of fsnotify marks.
-+ *
-+ * Fanotify supports different notification classes (reflected as priority of
-+ * notification group). Events shall be passed to notification groups in
-+ * decreasing priority order. To achieve this marks in notification lists for
-+ * inodes and vfsmounts are sorted so that priorities of corresponding groups
-+ * are descending.
-+ *
-+ * Furthermore correct handling of the ignore mask requires processing inode
-+ * and vfsmount marks of each group together. Using the group address as
-+ * further sort criterion provides a unique sorting order and thus we can
-+ * merge inode and vfsmount lists of marks in linear time and find groups
-+ * present in both lists.
-+ *
-+ * A return value of 1 signifies that b has priority over a.
-+ * A return value of 0 signifies that the two marks have to be handled together.
-+ * A return value of -1 signifies that a has priority over b.
-+ */
-+int fsnotify_compare_groups(struct fsnotify_group *a, struct fsnotify_group *b)
-+{
-+      if (a == b)
-+              return 0;
-+      if (!a)
-+              return 1;
-+      if (!b)
-+              return -1;
-+      if (a->priority < b->priority)
-+              return 1;
-+      if (a->priority > b->priority)
-+              return -1;
-+      if (a < b)
-+              return 1;
-+      return -1;
-+}
-+
-+/*
-  * Attach an initialized mark to a given group and fs object.
-  * These marks may be used for the fsnotify backend to determine which
-  * event types should be delivered to which group.
-diff --git a/fs/notify/vfsmount_mark.c b/fs/notify/vfsmount_mark.c
-index ac851e8..faefa72 100644
---- a/fs/notify/vfsmount_mark.c
-+++ b/fs/notify/vfsmount_mark.c
-@@ -153,6 +153,7 @@ int fsnotify_add_vfsmount_mark(struct fsnotify_mark *mark,
-       struct mount *m = real_mount(mnt);
-       struct fsnotify_mark *lmark, *last = NULL;
-       int ret = 0;
-+      int cmp;
-       mark->flags |= FSNOTIFY_MARK_FLAG_VFSMOUNT;
-@@ -178,11 +179,8 @@ int fsnotify_add_vfsmount_mark(struct fsnotify_mark *mark,
-                       goto out;
-               }
--              if (mark->group->priority < lmark->group->priority)
--                      continue;
--
--              if ((mark->group->priority == lmark->group->priority) &&
--                  (mark->group < lmark->group))
-+              cmp = fsnotify_compare_groups(lmark->group, mark->group);
-+              if (cmp < 0)
-                       continue;
-               hlist_add_before_rcu(&mark->m.m_list, &lmark->m.m_list);
--- 
-1.8.3.1
-
diff --git a/meta-agl-bsp/recipes-kernel/linux/linux-yocto/4.4-0001-mm-larger-stack-guard-gap-between-vmas.patch b/meta-agl-bsp/recipes-kernel/linux/linux-yocto/4.4-0001-mm-larger-stack-guard-gap-between-vmas.patch
deleted file mode 100644 (file)
index e9fafad..0000000
+++ /dev/null
@@ -1,900 +0,0 @@
-From 3982d0807e02909957990f194c5ed2ffb6ab6c35 Mon Sep 17 00:00:00 2001
-From: Hugh Dickins <hughd@google.com>
-Date: Mon, 19 Jun 2017 04:03:24 -0700
-Subject: [PATCH 1/3] mm: larger stack guard gap, between vmas
-
-commit 1be7107fbe18eed3e319a6c3e83c78254b693acb upstream.
-
-Stack guard page is a useful feature to reduce a risk of stack smashing
-into a different mapping. We have been using a single page gap which
-is sufficient to prevent having stack adjacent to a different mapping.
-But this seems to be insufficient in the light of the stack usage in
-userspace. E.g. glibc uses as large as 64kB alloca() in many commonly
-used functions. Others use constructs liks gid_t buffer[NGROUPS_MAX]
-which is 256kB or stack strings with MAX_ARG_STRLEN.
-
-This will become especially dangerous for suid binaries and the default
-no limit for the stack size limit because those applications can be
-tricked to consume a large portion of the stack and a single glibc call
-could jump over the guard page. These attacks are not theoretical,
-unfortunatelly.
-
-Make those attacks less probable by increasing the stack guard gap
-to 1MB (on systems with 4k pages; but make it depend on the page size
-because systems with larger base pages might cap stack allocations in
-the PAGE_SIZE units) which should cover larger alloca() and VLA stack
-allocations. It is obviously not a full fix because the problem is
-somehow inherent, but it should reduce attack space a lot.
-
-One could argue that the gap size should be configurable from userspace,
-but that can be done later when somebody finds that the new 1MB is wrong
-for some special case applications.  For now, add a kernel command line
-option (stack_guard_gap) to specify the stack gap size (in page units).
-
-Implementation wise, first delete all the old code for stack guard page:
-because although we could get away with accounting one extra page in a
-stack vma, accounting a larger gap can break userspace - case in point,
-a program run with "ulimit -S -v 20000" failed when the 1MB gap was
-counted for RLIMIT_AS; similar problems could come with RLIMIT_MLOCK
-and strict non-overcommit mode.
-
-Instead of keeping gap inside the stack vma, maintain the stack guard
-gap as a gap between vmas: using vm_start_gap() in place of vm_start
-(or vm_end_gap() in place of vm_end if VM_GROWSUP) in just those few
-places which need to respect the gap - mainly arch_get_unmapped_area(),
-and and the vma tree's subtree_gap support for that.
-
-Original-patch-by: Oleg Nesterov <oleg@redhat.com>
-Original-patch-by: Michal Hocko <mhocko@suse.com>
-Signed-off-by: Hugh Dickins <hughd@google.com>
-Acked-by: Michal Hocko <mhocko@suse.com>
-Tested-by: Helge Deller <deller@gmx.de> # parisc
-Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-[wt: backport to 4.11: adjust context]
-[wt: backport to 4.9: adjust context ; kernel doc was not in admin-guide]
-[wt: backport to 4.4: adjust context ; drop ppc hugetlb_radix changes]
-Signed-off-by: Willy Tarreau <w@1wt.eu>
-[gkh: minor build fixes for 4.4]
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- Documentation/kernel-parameters.txt |   7 ++
- arch/arc/mm/mmap.c                  |   2 +-
- arch/arm/mm/mmap.c                  |   4 +-
- arch/frv/mm/elf-fdpic.c             |   2 +-
- arch/mips/mm/mmap.c                 |   2 +-
- arch/parisc/kernel/sys_parisc.c     |  15 ++--
- arch/powerpc/mm/slice.c             |   2 +-
- arch/s390/mm/mmap.c                 |   4 +-
- arch/sh/mm/mmap.c                   |   4 +-
- arch/sparc/kernel/sys_sparc_64.c    |   4 +-
- arch/sparc/mm/hugetlbpage.c         |   2 +-
- arch/tile/mm/hugetlbpage.c          |   2 +-
- arch/x86/kernel/sys_x86_64.c        |   4 +-
- arch/x86/mm/hugetlbpage.c           |   2 +-
- arch/xtensa/kernel/syscall.c        |   2 +-
- fs/hugetlbfs/inode.c                |   2 +-
- fs/proc/task_mmu.c                  |   4 -
- include/linux/mm.h                  |  53 ++++++-------
- mm/gup.c                            |   5 --
- mm/memory.c                         |  38 ---------
- mm/mmap.c                           | 149 +++++++++++++++++++++---------------
- 21 files changed, 149 insertions(+), 160 deletions(-)
-
-diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt
-index c360f80..9738c8b 100644
---- a/Documentation/kernel-parameters.txt
-+++ b/Documentation/kernel-parameters.txt
-@@ -3576,6 +3576,13 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
-       spia_pedr=
-       spia_peddr=
-+      stack_guard_gap=        [MM]
-+                      override the default stack gap protection. The value
-+                      is in page units and it defines how many pages prior
-+                      to (for stacks growing down) resp. after (for stacks
-+                      growing up) the main stack are reserved for no other
-+                      mapping. Default value is 256 pages.
-+
-       stacktrace      [FTRACE]
-                       Enabled the stack tracer on boot up.
-diff --git a/arch/arc/mm/mmap.c b/arch/arc/mm/mmap.c
-index 2e06d56..cf4ae69 100644
---- a/arch/arc/mm/mmap.c
-+++ b/arch/arc/mm/mmap.c
-@@ -64,7 +64,7 @@ arch_get_unmapped_area(struct file *filp, unsigned long addr,
-               vma = find_vma(mm, addr);
-               if (TASK_SIZE - len >= addr &&
--                  (!vma || addr + len <= vma->vm_start))
-+                  (!vma || addr + len <= vm_start_gap(vma)))
-                       return addr;
-       }
-diff --git a/arch/arm/mm/mmap.c b/arch/arm/mm/mmap.c
-index 407dc78..c469c06 100644
---- a/arch/arm/mm/mmap.c
-+++ b/arch/arm/mm/mmap.c
-@@ -89,7 +89,7 @@ arch_get_unmapped_area(struct file *filp, unsigned long addr,
-               vma = find_vma(mm, addr);
-               if (TASK_SIZE - len >= addr &&
--                  (!vma || addr + len <= vma->vm_start))
-+                  (!vma || addr + len <= vm_start_gap(vma)))
-                       return addr;
-       }
-@@ -140,7 +140,7 @@ arch_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0,
-                       addr = PAGE_ALIGN(addr);
-               vma = find_vma(mm, addr);
-               if (TASK_SIZE - len >= addr &&
--                              (!vma || addr + len <= vma->vm_start))
-+                              (!vma || addr + len <= vm_start_gap(vma)))
-                       return addr;
-       }
-diff --git a/arch/frv/mm/elf-fdpic.c b/arch/frv/mm/elf-fdpic.c
-index 836f147..efa59f1 100644
---- a/arch/frv/mm/elf-fdpic.c
-+++ b/arch/frv/mm/elf-fdpic.c
-@@ -74,7 +74,7 @@ unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr, unsi
-               addr = PAGE_ALIGN(addr);
-               vma = find_vma(current->mm, addr);
-               if (TASK_SIZE - len >= addr &&
--                  (!vma || addr + len <= vma->vm_start))
-+                  (!vma || addr + len <= vm_start_gap(vma)))
-                       goto success;
-       }
-diff --git a/arch/mips/mm/mmap.c b/arch/mips/mm/mmap.c
-index 5c81fdd..025cb31 100644
---- a/arch/mips/mm/mmap.c
-+++ b/arch/mips/mm/mmap.c
-@@ -92,7 +92,7 @@ static unsigned long arch_get_unmapped_area_common(struct file *filp,
-               vma = find_vma(mm, addr);
-               if (TASK_SIZE - len >= addr &&
--                  (!vma || addr + len <= vma->vm_start))
-+                  (!vma || addr + len <= vm_start_gap(vma)))
-                       return addr;
-       }
-diff --git a/arch/parisc/kernel/sys_parisc.c b/arch/parisc/kernel/sys_parisc.c
-index 5aba01a..4dda73c 100644
---- a/arch/parisc/kernel/sys_parisc.c
-+++ b/arch/parisc/kernel/sys_parisc.c
-@@ -88,7 +88,7 @@ unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr,
-               unsigned long len, unsigned long pgoff, unsigned long flags)
- {
-       struct mm_struct *mm = current->mm;
--      struct vm_area_struct *vma;
-+      struct vm_area_struct *vma, *prev;
-       unsigned long task_size = TASK_SIZE;
-       int do_color_align, last_mmap;
-       struct vm_unmapped_area_info info;
-@@ -115,9 +115,10 @@ unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr,
-               else
-                       addr = PAGE_ALIGN(addr);
--              vma = find_vma(mm, addr);
-+              vma = find_vma_prev(mm, addr, &prev);
-               if (task_size - len >= addr &&
--                  (!vma || addr + len <= vma->vm_start))
-+                  (!vma || addr + len <= vm_start_gap(vma)) &&
-+                  (!prev || addr >= vm_end_gap(prev)))
-                       goto found_addr;
-       }
-@@ -141,7 +142,7 @@ arch_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0,
-                         const unsigned long len, const unsigned long pgoff,
-                         const unsigned long flags)
- {
--      struct vm_area_struct *vma;
-+      struct vm_area_struct *vma, *prev;
-       struct mm_struct *mm = current->mm;
-       unsigned long addr = addr0;
-       int do_color_align, last_mmap;
-@@ -175,9 +176,11 @@ arch_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0,
-                       addr = COLOR_ALIGN(addr, last_mmap, pgoff);
-               else
-                       addr = PAGE_ALIGN(addr);
--              vma = find_vma(mm, addr);
-+
-+              vma = find_vma_prev(mm, addr, &prev);
-               if (TASK_SIZE - len >= addr &&
--                  (!vma || addr + len <= vma->vm_start))
-+                  (!vma || addr + len <= vm_start_gap(vma)) &&
-+                  (!prev || addr >= vm_end_gap(prev)))
-                       goto found_addr;
-       }
-diff --git a/arch/powerpc/mm/slice.c b/arch/powerpc/mm/slice.c
-index 0f432a7..6ad12b2 100644
---- a/arch/powerpc/mm/slice.c
-+++ b/arch/powerpc/mm/slice.c
-@@ -105,7 +105,7 @@ static int slice_area_is_free(struct mm_struct *mm, unsigned long addr,
-       if ((mm->task_size - len) < addr)
-               return 0;
-       vma = find_vma(mm, addr);
--      return (!vma || (addr + len) <= vma->vm_start);
-+      return (!vma || (addr + len) <= vm_start_gap(vma));
- }
- static int slice_low_has_vma(struct mm_struct *mm, unsigned long slice)
-diff --git a/arch/s390/mm/mmap.c b/arch/s390/mm/mmap.c
-index f2b6b1d..126c4a9 100644
---- a/arch/s390/mm/mmap.c
-+++ b/arch/s390/mm/mmap.c
-@@ -97,7 +97,7 @@ arch_get_unmapped_area(struct file *filp, unsigned long addr,
-               addr = PAGE_ALIGN(addr);
-               vma = find_vma(mm, addr);
-               if (TASK_SIZE - len >= addr && addr >= mmap_min_addr &&
--                  (!vma || addr + len <= vma->vm_start))
-+                  (!vma || addr + len <= vm_start_gap(vma)))
-                       return addr;
-       }
-@@ -135,7 +135,7 @@ arch_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0,
-               addr = PAGE_ALIGN(addr);
-               vma = find_vma(mm, addr);
-               if (TASK_SIZE - len >= addr && addr >= mmap_min_addr &&
--                              (!vma || addr + len <= vma->vm_start))
-+                              (!vma || addr + len <= vm_start_gap(vma)))
-                       return addr;
-       }
-diff --git a/arch/sh/mm/mmap.c b/arch/sh/mm/mmap.c
-index 6777177..7df7d59 100644
---- a/arch/sh/mm/mmap.c
-+++ b/arch/sh/mm/mmap.c
-@@ -63,7 +63,7 @@ unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr,
-               vma = find_vma(mm, addr);
-               if (TASK_SIZE - len >= addr &&
--                  (!vma || addr + len <= vma->vm_start))
-+                  (!vma || addr + len <= vm_start_gap(vma)))
-                       return addr;
-       }
-@@ -113,7 +113,7 @@ arch_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0,
-               vma = find_vma(mm, addr);
-               if (TASK_SIZE - len >= addr &&
--                  (!vma || addr + len <= vma->vm_start))
-+                  (!vma || addr + len <= vm_start_gap(vma)))
-                       return addr;
-       }
-diff --git a/arch/sparc/kernel/sys_sparc_64.c b/arch/sparc/kernel/sys_sparc_64.c
-index c690c8e..7f0f7c01 100644
---- a/arch/sparc/kernel/sys_sparc_64.c
-+++ b/arch/sparc/kernel/sys_sparc_64.c
-@@ -118,7 +118,7 @@ unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr, unsi
-               vma = find_vma(mm, addr);
-               if (task_size - len >= addr &&
--                  (!vma || addr + len <= vma->vm_start))
-+                  (!vma || addr + len <= vm_start_gap(vma)))
-                       return addr;
-       }
-@@ -181,7 +181,7 @@ arch_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0,
-               vma = find_vma(mm, addr);
-               if (task_size - len >= addr &&
--                  (!vma || addr + len <= vma->vm_start))
-+                  (!vma || addr + len <= vm_start_gap(vma)))
-                       return addr;
-       }
-diff --git a/arch/sparc/mm/hugetlbpage.c b/arch/sparc/mm/hugetlbpage.c
-index da11424..ffa842b 100644
---- a/arch/sparc/mm/hugetlbpage.c
-+++ b/arch/sparc/mm/hugetlbpage.c
-@@ -115,7 +115,7 @@ hugetlb_get_unmapped_area(struct file *file, unsigned long addr,
-               addr = ALIGN(addr, HPAGE_SIZE);
-               vma = find_vma(mm, addr);
-               if (task_size - len >= addr &&
--                  (!vma || addr + len <= vma->vm_start))
-+                  (!vma || addr + len <= vm_start_gap(vma)))
-                       return addr;
-       }
-       if (mm->get_unmapped_area == arch_get_unmapped_area)
-diff --git a/arch/tile/mm/hugetlbpage.c b/arch/tile/mm/hugetlbpage.c
-index c034dc3..c97ee6c 100644
---- a/arch/tile/mm/hugetlbpage.c
-+++ b/arch/tile/mm/hugetlbpage.c
-@@ -232,7 +232,7 @@ unsigned long hugetlb_get_unmapped_area(struct file *file, unsigned long addr,
-               addr = ALIGN(addr, huge_page_size(h));
-               vma = find_vma(mm, addr);
-               if (TASK_SIZE - len >= addr &&
--                  (!vma || addr + len <= vma->vm_start))
-+                  (!vma || addr + len <= vm_start_gap(vma)))
-                       return addr;
-       }
-       if (current->mm->get_unmapped_area == arch_get_unmapped_area)
-diff --git a/arch/x86/kernel/sys_x86_64.c b/arch/x86/kernel/sys_x86_64.c
-index 10e0272..136ad7c 100644
---- a/arch/x86/kernel/sys_x86_64.c
-+++ b/arch/x86/kernel/sys_x86_64.c
-@@ -143,7 +143,7 @@ arch_get_unmapped_area(struct file *filp, unsigned long addr,
-               addr = PAGE_ALIGN(addr);
-               vma = find_vma(mm, addr);
-               if (end - len >= addr &&
--                  (!vma || addr + len <= vma->vm_start))
-+                  (!vma || addr + len <= vm_start_gap(vma)))
-                       return addr;
-       }
-@@ -186,7 +186,7 @@ arch_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0,
-               addr = PAGE_ALIGN(addr);
-               vma = find_vma(mm, addr);
-               if (TASK_SIZE - len >= addr &&
--                              (!vma || addr + len <= vma->vm_start))
-+                              (!vma || addr + len <= vm_start_gap(vma)))
-                       return addr;
-       }
-diff --git a/arch/x86/mm/hugetlbpage.c b/arch/x86/mm/hugetlbpage.c
-index 42982b2..39bdaf3 100644
---- a/arch/x86/mm/hugetlbpage.c
-+++ b/arch/x86/mm/hugetlbpage.c
-@@ -144,7 +144,7 @@ hugetlb_get_unmapped_area(struct file *file, unsigned long addr,
-               addr = ALIGN(addr, huge_page_size(h));
-               vma = find_vma(mm, addr);
-               if (TASK_SIZE - len >= addr &&
--                  (!vma || addr + len <= vma->vm_start))
-+                  (!vma || addr + len <= vm_start_gap(vma)))
-                       return addr;
-       }
-       if (mm->get_unmapped_area == arch_get_unmapped_area)
-diff --git a/arch/xtensa/kernel/syscall.c b/arch/xtensa/kernel/syscall.c
-index 83cf496..3aaaae1 100644
---- a/arch/xtensa/kernel/syscall.c
-+++ b/arch/xtensa/kernel/syscall.c
-@@ -87,7 +87,7 @@ unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr,
-               /* At this point:  (!vmm || addr < vmm->vm_end). */
-               if (TASK_SIZE - len < addr)
-                       return -ENOMEM;
--              if (!vmm || addr + len <= vmm->vm_start)
-+              if (!vmm || addr + len <= vm_start_gap(vmm))
-                       return addr;
-               addr = vmm->vm_end;
-               if (flags & MAP_SHARED)
-diff --git a/fs/hugetlbfs/inode.c b/fs/hugetlbfs/inode.c
-index 595ebdb..a17da8b5 100644
---- a/fs/hugetlbfs/inode.c
-+++ b/fs/hugetlbfs/inode.c
-@@ -191,7 +191,7 @@ hugetlb_get_unmapped_area(struct file *file, unsigned long addr,
-               addr = ALIGN(addr, huge_page_size(h));
-               vma = find_vma(mm, addr);
-               if (TASK_SIZE - len >= addr &&
--                  (!vma || addr + len <= vma->vm_start))
-+                  (!vma || addr + len <= vm_start_gap(vma)))
-                       return addr;
-       }
-diff --git a/fs/proc/task_mmu.c b/fs/proc/task_mmu.c
-index d598b9c..cb7020c 100644
---- a/fs/proc/task_mmu.c
-+++ b/fs/proc/task_mmu.c
-@@ -295,11 +295,7 @@ show_map_vma(struct seq_file *m, struct vm_area_struct *vma, int is_pid)
-       /* We don't show the stack guard page in /proc/maps */
-       start = vma->vm_start;
--      if (stack_guard_page_start(vma, start))
--              start += PAGE_SIZE;
-       end = vma->vm_end;
--      if (stack_guard_page_end(vma, end))
--              end -= PAGE_SIZE;
-       seq_setwidth(m, 25 + sizeof(void *) * 6 - 1);
-       seq_printf(m, "%08lx-%08lx %c%c%c%c %08llx %02x:%02x %lu ",
-diff --git a/include/linux/mm.h b/include/linux/mm.h
-index f0ffa01..55f950a 100644
---- a/include/linux/mm.h
-+++ b/include/linux/mm.h
-@@ -1278,39 +1278,11 @@ int clear_page_dirty_for_io(struct page *page);
- int get_cmdline(struct task_struct *task, char *buffer, int buflen);
--/* Is the vma a continuation of the stack vma above it? */
--static inline int vma_growsdown(struct vm_area_struct *vma, unsigned long addr)
--{
--      return vma && (vma->vm_end == addr) && (vma->vm_flags & VM_GROWSDOWN);
--}
--
- static inline bool vma_is_anonymous(struct vm_area_struct *vma)
- {
-       return !vma->vm_ops;
- }
--static inline int stack_guard_page_start(struct vm_area_struct *vma,
--                                           unsigned long addr)
--{
--      return (vma->vm_flags & VM_GROWSDOWN) &&
--              (vma->vm_start == addr) &&
--              !vma_growsdown(vma->vm_prev, addr);
--}
--
--/* Is the vma a continuation of the stack vma below it? */
--static inline int vma_growsup(struct vm_area_struct *vma, unsigned long addr)
--{
--      return vma && (vma->vm_start == addr) && (vma->vm_flags & VM_GROWSUP);
--}
--
--static inline int stack_guard_page_end(struct vm_area_struct *vma,
--                                         unsigned long addr)
--{
--      return (vma->vm_flags & VM_GROWSUP) &&
--              (vma->vm_end == addr) &&
--              !vma_growsup(vma->vm_next, addr);
--}
--
- int vma_is_stack_for_task(struct vm_area_struct *vma, struct task_struct *t);
- extern unsigned long move_page_tables(struct vm_area_struct *vma,
-@@ -2012,6 +1984,7 @@ void page_cache_async_readahead(struct address_space *mapping,
-                               pgoff_t offset,
-                               unsigned long size);
-+extern unsigned long stack_guard_gap;
- /* Generic expand stack which grows the stack according to GROWS{UP,DOWN} */
- extern int expand_stack(struct vm_area_struct *vma, unsigned long address);
-@@ -2040,6 +2013,30 @@ static inline struct vm_area_struct * find_vma_intersection(struct mm_struct * m
-       return vma;
- }
-+static inline unsigned long vm_start_gap(struct vm_area_struct *vma)
-+{
-+      unsigned long vm_start = vma->vm_start;
-+
-+      if (vma->vm_flags & VM_GROWSDOWN) {
-+              vm_start -= stack_guard_gap;
-+              if (vm_start > vma->vm_start)
-+                      vm_start = 0;
-+      }
-+      return vm_start;
-+}
-+
-+static inline unsigned long vm_end_gap(struct vm_area_struct *vma)
-+{
-+      unsigned long vm_end = vma->vm_end;
-+
-+      if (vma->vm_flags & VM_GROWSUP) {
-+              vm_end += stack_guard_gap;
-+              if (vm_end < vma->vm_end)
-+                      vm_end = -PAGE_SIZE;
-+      }
-+      return vm_end;
-+}
-+
- static inline unsigned long vma_pages(struct vm_area_struct *vma)
- {
-       return (vma->vm_end - vma->vm_start) >> PAGE_SHIFT;
-diff --git a/mm/gup.c b/mm/gup.c
-index 4b0b7e7..b599526 100644
---- a/mm/gup.c
-+++ b/mm/gup.c
-@@ -312,11 +312,6 @@ static int faultin_page(struct task_struct *tsk, struct vm_area_struct *vma,
-       /* mlock all present pages, but do not fault in new pages */
-       if ((*flags & (FOLL_POPULATE | FOLL_MLOCK)) == FOLL_MLOCK)
-               return -ENOENT;
--      /* For mm_populate(), just skip the stack guard page. */
--      if ((*flags & FOLL_POPULATE) &&
--                      (stack_guard_page_start(vma, address) ||
--                       stack_guard_page_end(vma, address + PAGE_SIZE)))
--              return -ENOENT;
-       if (*flags & FOLL_WRITE)
-               fault_flags |= FAULT_FLAG_WRITE;
-       if (nonblocking)
-diff --git a/mm/memory.c b/mm/memory.c
-index 76dcee3..e6fa134 100644
---- a/mm/memory.c
-+++ b/mm/memory.c
-@@ -2662,40 +2662,6 @@ out_release:
- }
- /*
-- * This is like a special single-page "expand_{down|up}wards()",
-- * except we must first make sure that 'address{-|+}PAGE_SIZE'
-- * doesn't hit another vma.
-- */
--static inline int check_stack_guard_page(struct vm_area_struct *vma, unsigned long address)
--{
--      address &= PAGE_MASK;
--      if ((vma->vm_flags & VM_GROWSDOWN) && address == vma->vm_start) {
--              struct vm_area_struct *prev = vma->vm_prev;
--
--              /*
--               * Is there a mapping abutting this one below?
--               *
--               * That's only ok if it's the same stack mapping
--               * that has gotten split..
--               */
--              if (prev && prev->vm_end == address)
--                      return prev->vm_flags & VM_GROWSDOWN ? 0 : -ENOMEM;
--
--              return expand_downwards(vma, address - PAGE_SIZE);
--      }
--      if ((vma->vm_flags & VM_GROWSUP) && address + PAGE_SIZE == vma->vm_end) {
--              struct vm_area_struct *next = vma->vm_next;
--
--              /* As VM_GROWSDOWN but s/below/above/ */
--              if (next && next->vm_start == address + PAGE_SIZE)
--                      return next->vm_flags & VM_GROWSUP ? 0 : -ENOMEM;
--
--              return expand_upwards(vma, address + PAGE_SIZE);
--      }
--      return 0;
--}
--
--/*
-  * We enter with non-exclusive mmap_sem (to exclude vma changes,
-  * but allow concurrent faults), and pte mapped but not yet locked.
-  * We return with mmap_sem still held, but pte unmapped and unlocked.
-@@ -2715,10 +2681,6 @@ static int do_anonymous_page(struct mm_struct *mm, struct vm_area_struct *vma,
-       if (vma->vm_flags & VM_SHARED)
-               return VM_FAULT_SIGBUS;
--      /* Check if we need to add a guard page to the stack */
--      if (check_stack_guard_page(vma, address) < 0)
--              return VM_FAULT_SIGSEGV;
--
-       /* Use the zero-page for reads */
-       if (!(flags & FAULT_FLAG_WRITE) && !mm_forbids_zeropage(mm)) {
-               entry = pte_mkspecial(pfn_pte(my_zero_pfn(address),
-diff --git a/mm/mmap.c b/mm/mmap.c
-index 455772a..5e043dd 100644
---- a/mm/mmap.c
-+++ b/mm/mmap.c
-@@ -288,6 +288,7 @@ SYSCALL_DEFINE1(brk, unsigned long, brk)
-       unsigned long retval;
-       unsigned long newbrk, oldbrk;
-       struct mm_struct *mm = current->mm;
-+      struct vm_area_struct *next;
-       unsigned long min_brk;
-       bool populate;
-@@ -332,7 +333,8 @@ SYSCALL_DEFINE1(brk, unsigned long, brk)
-       }
-       /* Check against existing mmap mappings. */
--      if (find_vma_intersection(mm, oldbrk, newbrk+PAGE_SIZE))
-+      next = find_vma(mm, oldbrk);
-+      if (next && newbrk + PAGE_SIZE > vm_start_gap(next))
-               goto out;
-       /* Ok, looks good - let it rip. */
-@@ -355,10 +357,22 @@ out:
- static long vma_compute_subtree_gap(struct vm_area_struct *vma)
- {
--      unsigned long max, subtree_gap;
--      max = vma->vm_start;
--      if (vma->vm_prev)
--              max -= vma->vm_prev->vm_end;
-+      unsigned long max, prev_end, subtree_gap;
-+
-+      /*
-+       * Note: in the rare case of a VM_GROWSDOWN above a VM_GROWSUP, we
-+       * allow two stack_guard_gaps between them here, and when choosing
-+       * an unmapped area; whereas when expanding we only require one.
-+       * That's a little inconsistent, but keeps the code here simpler.
-+       */
-+      max = vm_start_gap(vma);
-+      if (vma->vm_prev) {
-+              prev_end = vm_end_gap(vma->vm_prev);
-+              if (max > prev_end)
-+                      max -= prev_end;
-+              else
-+                      max = 0;
-+      }
-       if (vma->vm_rb.rb_left) {
-               subtree_gap = rb_entry(vma->vm_rb.rb_left,
-                               struct vm_area_struct, vm_rb)->rb_subtree_gap;
-@@ -451,7 +465,7 @@ static void validate_mm(struct mm_struct *mm)
-                       anon_vma_unlock_read(anon_vma);
-               }
--              highest_address = vma->vm_end;
-+              highest_address = vm_end_gap(vma);
-               vma = vma->vm_next;
-               i++;
-       }
-@@ -620,7 +634,7 @@ void __vma_link_rb(struct mm_struct *mm, struct vm_area_struct *vma,
-       if (vma->vm_next)
-               vma_gap_update(vma->vm_next);
-       else
--              mm->highest_vm_end = vma->vm_end;
-+              mm->highest_vm_end = vm_end_gap(vma);
-       /*
-        * vma->vm_prev wasn't known when we followed the rbtree to find the
-@@ -866,7 +880,7 @@ again:                     remove_next = 1 + (end > next->vm_end);
-                       vma_gap_update(vma);
-               if (end_changed) {
-                       if (!next)
--                              mm->highest_vm_end = end;
-+                              mm->highest_vm_end = vm_end_gap(vma);
-                       else if (!adjust_next)
-                               vma_gap_update(next);
-               }
-@@ -909,7 +923,7 @@ again:                     remove_next = 1 + (end > next->vm_end);
-               else if (next)
-                       vma_gap_update(next);
-               else
--                      mm->highest_vm_end = end;
-+                      VM_WARN_ON(mm->highest_vm_end != vm_end_gap(vma));
-       }
-       if (insert && file)
-               uprobe_mmap(insert);
-@@ -1741,7 +1755,7 @@ unsigned long unmapped_area(struct vm_unmapped_area_info *info)
-       while (true) {
-               /* Visit left subtree if it looks promising */
--              gap_end = vma->vm_start;
-+              gap_end = vm_start_gap(vma);
-               if (gap_end >= low_limit && vma->vm_rb.rb_left) {
-                       struct vm_area_struct *left =
-                               rb_entry(vma->vm_rb.rb_left,
-@@ -1752,7 +1766,7 @@ unsigned long unmapped_area(struct vm_unmapped_area_info *info)
-                       }
-               }
--              gap_start = vma->vm_prev ? vma->vm_prev->vm_end : 0;
-+              gap_start = vma->vm_prev ? vm_end_gap(vma->vm_prev) : 0;
- check_current:
-               /* Check if current node has a suitable gap */
-               if (gap_start > high_limit)
-@@ -1779,8 +1793,8 @@ check_current:
-                       vma = rb_entry(rb_parent(prev),
-                                      struct vm_area_struct, vm_rb);
-                       if (prev == vma->vm_rb.rb_left) {
--                              gap_start = vma->vm_prev->vm_end;
--                              gap_end = vma->vm_start;
-+                              gap_start = vm_end_gap(vma->vm_prev);
-+                              gap_end = vm_start_gap(vma);
-                               goto check_current;
-                       }
-               }
-@@ -1844,7 +1858,7 @@ unsigned long unmapped_area_topdown(struct vm_unmapped_area_info *info)
-       while (true) {
-               /* Visit right subtree if it looks promising */
--              gap_start = vma->vm_prev ? vma->vm_prev->vm_end : 0;
-+              gap_start = vma->vm_prev ? vm_end_gap(vma->vm_prev) : 0;
-               if (gap_start <= high_limit && vma->vm_rb.rb_right) {
-                       struct vm_area_struct *right =
-                               rb_entry(vma->vm_rb.rb_right,
-@@ -1857,7 +1871,7 @@ unsigned long unmapped_area_topdown(struct vm_unmapped_area_info *info)
- check_current:
-               /* Check if current node has a suitable gap */
--              gap_end = vma->vm_start;
-+              gap_end = vm_start_gap(vma);
-               if (gap_end < low_limit)
-                       return -ENOMEM;
-               if (gap_start <= high_limit && gap_end - gap_start >= length)
-@@ -1883,7 +1897,7 @@ check_current:
-                                      struct vm_area_struct, vm_rb);
-                       if (prev == vma->vm_rb.rb_right) {
-                               gap_start = vma->vm_prev ?
--                                      vma->vm_prev->vm_end : 0;
-+                                      vm_end_gap(vma->vm_prev) : 0;
-                               goto check_current;
-                       }
-               }
-@@ -1921,7 +1935,7 @@ arch_get_unmapped_area(struct file *filp, unsigned long addr,
-               unsigned long len, unsigned long pgoff, unsigned long flags)
- {
-       struct mm_struct *mm = current->mm;
--      struct vm_area_struct *vma;
-+      struct vm_area_struct *vma, *prev;
-       struct vm_unmapped_area_info info;
-       if (len > TASK_SIZE - mmap_min_addr)
-@@ -1932,9 +1946,10 @@ arch_get_unmapped_area(struct file *filp, unsigned long addr,
-       if (addr) {
-               addr = PAGE_ALIGN(addr);
--              vma = find_vma(mm, addr);
-+              vma = find_vma_prev(mm, addr, &prev);
-               if (TASK_SIZE - len >= addr && addr >= mmap_min_addr &&
--                  (!vma || addr + len <= vma->vm_start))
-+                  (!vma || addr + len <= vm_start_gap(vma)) &&
-+                  (!prev || addr >= vm_end_gap(prev)))
-                       return addr;
-       }
-@@ -1957,7 +1972,7 @@ arch_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0,
-                         const unsigned long len, const unsigned long pgoff,
-                         const unsigned long flags)
- {
--      struct vm_area_struct *vma;
-+      struct vm_area_struct *vma, *prev;
-       struct mm_struct *mm = current->mm;
-       unsigned long addr = addr0;
-       struct vm_unmapped_area_info info;
-@@ -1972,9 +1987,10 @@ arch_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0,
-       /* requesting a specific address */
-       if (addr) {
-               addr = PAGE_ALIGN(addr);
--              vma = find_vma(mm, addr);
-+              vma = find_vma_prev(mm, addr, &prev);
-               if (TASK_SIZE - len >= addr && addr >= mmap_min_addr &&
--                              (!vma || addr + len <= vma->vm_start))
-+                              (!vma || addr + len <= vm_start_gap(vma)) &&
-+                              (!prev || addr >= vm_end_gap(prev)))
-                       return addr;
-       }
-@@ -2099,21 +2115,19 @@ find_vma_prev(struct mm_struct *mm, unsigned long addr,
-  * update accounting. This is shared with both the
-  * grow-up and grow-down cases.
-  */
--static int acct_stack_growth(struct vm_area_struct *vma, unsigned long size, unsigned long grow)
-+static int acct_stack_growth(struct vm_area_struct *vma,
-+                           unsigned long size, unsigned long grow)
- {
-       struct mm_struct *mm = vma->vm_mm;
-       struct rlimit *rlim = current->signal->rlim;
--      unsigned long new_start, actual_size;
-+      unsigned long new_start;
-       /* address space limit tests */
-       if (!may_expand_vm(mm, grow))
-               return -ENOMEM;
-       /* Stack limit test */
--      actual_size = size;
--      if (size && (vma->vm_flags & (VM_GROWSUP | VM_GROWSDOWN)))
--              actual_size -= PAGE_SIZE;
--      if (actual_size > READ_ONCE(rlim[RLIMIT_STACK].rlim_cur))
-+      if (size > READ_ONCE(rlim[RLIMIT_STACK].rlim_cur))
-               return -ENOMEM;
-       /* mlock limit tests */
-@@ -2151,17 +2165,30 @@ static int acct_stack_growth(struct vm_area_struct *vma, unsigned long size, uns
- int expand_upwards(struct vm_area_struct *vma, unsigned long address)
- {
-       struct mm_struct *mm = vma->vm_mm;
-+      struct vm_area_struct *next;
-+      unsigned long gap_addr;
-       int error = 0;
-       if (!(vma->vm_flags & VM_GROWSUP))
-               return -EFAULT;
-       /* Guard against wrapping around to address 0. */
--      if (address < PAGE_ALIGN(address+4))
--              address = PAGE_ALIGN(address+4);
--      else
-+      address &= PAGE_MASK;
-+      address += PAGE_SIZE;
-+      if (!address)
-               return -ENOMEM;
-+      /* Enforce stack_guard_gap */
-+      gap_addr = address + stack_guard_gap;
-+      if (gap_addr < address)
-+              return -ENOMEM;
-+      next = vma->vm_next;
-+      if (next && next->vm_start < gap_addr) {
-+              if (!(next->vm_flags & VM_GROWSUP))
-+                      return -ENOMEM;
-+              /* Check that both stack segments have the same anon_vma? */
-+      }
-+
-       /* We must make sure the anon_vma is allocated. */
-       if (unlikely(anon_vma_prepare(vma)))
-               return -ENOMEM;
-@@ -2206,7 +2233,7 @@ int expand_upwards(struct vm_area_struct *vma, unsigned long address)
-                               if (vma->vm_next)
-                                       vma_gap_update(vma->vm_next);
-                               else
--                                      mm->highest_vm_end = address;
-+                                      mm->highest_vm_end = vm_end_gap(vma);
-                               spin_unlock(&mm->page_table_lock);
-                               perf_event_mmap(vma);
-@@ -2227,6 +2254,8 @@ int expand_downwards(struct vm_area_struct *vma,
-                                  unsigned long address)
- {
-       struct mm_struct *mm = vma->vm_mm;
-+      struct vm_area_struct *prev;
-+      unsigned long gap_addr;
-       int error;
-       address &= PAGE_MASK;
-@@ -2234,6 +2263,17 @@ int expand_downwards(struct vm_area_struct *vma,
-       if (error)
-               return error;
-+      /* Enforce stack_guard_gap */
-+      gap_addr = address - stack_guard_gap;
-+      if (gap_addr > address)
-+              return -ENOMEM;
-+      prev = vma->vm_prev;
-+      if (prev && prev->vm_end > gap_addr) {
-+              if (!(prev->vm_flags & VM_GROWSDOWN))
-+                      return -ENOMEM;
-+              /* Check that both stack segments have the same anon_vma? */
-+      }
-+
-       /* We must make sure the anon_vma is allocated. */
-       if (unlikely(anon_vma_prepare(vma)))
-               return -ENOMEM;
-@@ -2289,28 +2329,25 @@ int expand_downwards(struct vm_area_struct *vma,
-       return error;
- }
--/*
-- * Note how expand_stack() refuses to expand the stack all the way to
-- * abut the next virtual mapping, *unless* that mapping itself is also
-- * a stack mapping. We want to leave room for a guard page, after all
-- * (the guard page itself is not added here, that is done by the
-- * actual page faulting logic)
-- *
-- * This matches the behavior of the guard page logic (see mm/memory.c:
-- * check_stack_guard_page()), which only allows the guard page to be
-- * removed under these circumstances.
-- */
-+/* enforced gap between the expanding stack and other mappings. */
-+unsigned long stack_guard_gap = 256UL<<PAGE_SHIFT;
-+
-+static int __init cmdline_parse_stack_guard_gap(char *p)
-+{
-+      unsigned long val;
-+      char *endptr;
-+
-+      val = simple_strtoul(p, &endptr, 10);
-+      if (!*endptr)
-+              stack_guard_gap = val << PAGE_SHIFT;
-+
-+      return 0;
-+}
-+__setup("stack_guard_gap=", cmdline_parse_stack_guard_gap);
-+
- #ifdef CONFIG_STACK_GROWSUP
- int expand_stack(struct vm_area_struct *vma, unsigned long address)
- {
--      struct vm_area_struct *next;
--
--      address &= PAGE_MASK;
--      next = vma->vm_next;
--      if (next && next->vm_start == address + PAGE_SIZE) {
--              if (!(next->vm_flags & VM_GROWSUP))
--                      return -ENOMEM;
--      }
-       return expand_upwards(vma, address);
- }
-@@ -2332,14 +2369,6 @@ find_extend_vma(struct mm_struct *mm, unsigned long addr)
- #else
- int expand_stack(struct vm_area_struct *vma, unsigned long address)
- {
--      struct vm_area_struct *prev;
--
--      address &= PAGE_MASK;
--      prev = vma->vm_prev;
--      if (prev && prev->vm_end == address) {
--              if (!(prev->vm_flags & VM_GROWSDOWN))
--                      return -ENOMEM;
--      }
-       return expand_downwards(vma, address);
- }
-@@ -2437,7 +2466,7 @@ detach_vmas_to_be_unmapped(struct mm_struct *mm, struct vm_area_struct *vma,
-               vma->vm_prev = prev;
-               vma_gap_update(vma);
-       } else
--              mm->highest_vm_end = prev ? prev->vm_end : 0;
-+              mm->highest_vm_end = prev ? vm_end_gap(prev) : 0;
-       tail_vma->vm_next = NULL;
-       /* Kill the cache */
--- 
-2.1.4
-
diff --git a/meta-agl-bsp/recipes-kernel/linux/linux-yocto/4.4-0002-Allow-stack-to-grow-up-to-address-space-limit.patch b/meta-agl-bsp/recipes-kernel/linux/linux-yocto/4.4-0002-Allow-stack-to-grow-up-to-address-space-limit.patch
deleted file mode 100644 (file)
index d0c94ce..0000000
+++ /dev/null
@@ -1,51 +0,0 @@
-From cd20f002742028366c33b38b3ca613eaee4582c9 Mon Sep 17 00:00:00 2001
-From: Helge Deller <deller@gmx.de>
-Date: Mon, 19 Jun 2017 17:34:05 +0200
-Subject: [PATCH 2/3] Allow stack to grow up to address space limit
-
-commit bd726c90b6b8ce87602208701b208a208e6d5600 upstream.
-
-Fix expand_upwards() on architectures with an upward-growing stack (parisc,
-metag and partly IA-64) to allow the stack to reliably grow exactly up to
-the address space limit given by TASK_SIZE.
-
-Signed-off-by: Helge Deller <deller@gmx.de>
-Acked-by: Hugh Dickins <hughd@google.com>
-Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- mm/mmap.c | 13 ++++++++-----
- 1 file changed, 8 insertions(+), 5 deletions(-)
-
-diff --git a/mm/mmap.c b/mm/mmap.c
-index 5e043dd..fcf4c88 100644
---- a/mm/mmap.c
-+++ b/mm/mmap.c
-@@ -2172,16 +2172,19 @@ int expand_upwards(struct vm_area_struct *vma, unsigned long address)
-       if (!(vma->vm_flags & VM_GROWSUP))
-               return -EFAULT;
--      /* Guard against wrapping around to address 0. */
-+      /* Guard against exceeding limits of the address space. */
-       address &= PAGE_MASK;
--      address += PAGE_SIZE;
--      if (!address)
-+      if (address >= TASK_SIZE)
-               return -ENOMEM;
-+      address += PAGE_SIZE;
-       /* Enforce stack_guard_gap */
-       gap_addr = address + stack_guard_gap;
--      if (gap_addr < address)
--              return -ENOMEM;
-+
-+      /* Guard against overflow */
-+      if (gap_addr < address || gap_addr > TASK_SIZE)
-+              gap_addr = TASK_SIZE;
-+
-       next = vma->vm_next;
-       if (next && next->vm_start < gap_addr) {
-               if (!(next->vm_flags & VM_GROWSUP))
--- 
-2.1.4
-
diff --git a/meta-agl-bsp/recipes-kernel/linux/linux-yocto/4.4-0003-mm-fix-new-crash-in-unmapped_area_topdown.patch b/meta-agl-bsp/recipes-kernel/linux/linux-yocto/4.4-0003-mm-fix-new-crash-in-unmapped_area_topdown.patch
deleted file mode 100644 (file)
index 3f0acfa..0000000
+++ /dev/null
@@ -1,52 +0,0 @@
-From 1c182004bcb1cd619b58ba6631b9d88052d18e02 Mon Sep 17 00:00:00 2001
-From: Hugh Dickins <hughd@google.com>
-Date: Tue, 20 Jun 2017 02:10:44 -0700
-Subject: [PATCH 3/3] mm: fix new crash in unmapped_area_topdown()
-
-commit f4cb767d76cf7ee72f97dd76f6cfa6c76a5edc89 upstream.
-
-Trinity gets kernel BUG at mm/mmap.c:1963! in about 3 minutes of
-mmap testing.  That's the VM_BUG_ON(gap_end < gap_start) at the
-end of unmapped_area_topdown().  Linus points out how MAP_FIXED
-(which does not have to respect our stack guard gap intentions)
-could result in gap_end below gap_start there.  Fix that, and
-the similar case in its alternative, unmapped_area().
-
-Fixes: 1be7107fbe18 ("mm: larger stack guard gap, between vmas")
-Reported-by: Dave Jones <davej@codemonkey.org.uk>
-Debugged-by: Linus Torvalds <torvalds@linux-foundation.org>
-Signed-off-by: Hugh Dickins <hughd@google.com>
-Acked-by: Michal Hocko <mhocko@suse.com>
-Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- mm/mmap.c | 6 ++++--
- 1 file changed, 4 insertions(+), 2 deletions(-)
-
-diff --git a/mm/mmap.c b/mm/mmap.c
-index fcf4c88..0990f8b 100644
---- a/mm/mmap.c
-+++ b/mm/mmap.c
-@@ -1771,7 +1771,8 @@ check_current:
-               /* Check if current node has a suitable gap */
-               if (gap_start > high_limit)
-                       return -ENOMEM;
--              if (gap_end >= low_limit && gap_end - gap_start >= length)
-+              if (gap_end >= low_limit &&
-+                  gap_end > gap_start && gap_end - gap_start >= length)
-                       goto found;
-               /* Visit right subtree if it looks promising */
-@@ -1874,7 +1875,8 @@ check_current:
-               gap_end = vm_start_gap(vma);
-               if (gap_end < low_limit)
-                       return -ENOMEM;
--              if (gap_start <= high_limit && gap_end - gap_start >= length)
-+              if (gap_start <= high_limit &&
-+                  gap_end > gap_start && gap_end - gap_start >= length)
-                       goto found;
-               /* Visit left subtree if it looks promising */
--- 
-2.1.4
-
diff --git a/meta-agl-bsp/recipes-kernel/linux/linux-yocto_4.4.bbappend b/meta-agl-bsp/recipes-kernel/linux/linux-yocto_4.4.bbappend
deleted file mode 100644 (file)
index 45c1706..0000000
+++ /dev/null
@@ -1,14 +0,0 @@
-FILESEXTRAPATHS_prepend := "${THISDIR}/linux-yocto:"
-
-# Backported fix for CVE-2017-1000364
-SRC_URI_append_core2-32-intel-common = "\
-    file://4.4-0001-mm-larger-stack-guard-gap-between-vmas.patch \
-    file://4.4-0002-Allow-stack-to-grow-up-to-address-space-limit.patch \
-    file://4.4-0003-mm-fix-new-crash-in-unmapped_area_topdown.patch \
-"
-
-SRC_URI_append_corei7-64-intel-common = "\
-    file://4.4-0001-mm-larger-stack-guard-gap-between-vmas.patch \
-    file://4.4-0002-Allow-stack-to-grow-up-to-address-space-limit.patch \
-    file://4.4-0003-mm-fix-new-crash-in-unmapped_area_topdown.patch \
-"
index d7a12e3..d4ff01b 100644 (file)
@@ -69,13 +69,13 @@ DISTRO_FEATURES_BACKFILL_CONSIDERED = "sysvinit"
 PREFERRED_VERSION_wayland-ivi-extension ?= "1.1%"
 
 # Prefer GStreamer 1.10.x by default
-PREFERRED_VERSION_gstreamer1.0              ?= "1.10.%"
-PREFERRED_VERSION_gstreamer1.0-plugins-bad  ?= "1.10.%"
-PREFERRED_VERSION_gstreamer1.0-plugins-base ?= "1.10.%"
-PREFERRED_VERSION_gstreamer1.0-plugins-good ?= "1.10.%"
-PREFERRED_VERSION_gstreamer1.0-plugins-ugly ?= "1.10.%"
-PREFERRED_VERSION_gstreamer1.0-libav        ?= "1.10.%"
-PREFERRED_VERSION_gstreamer1.0-omx          ?= "1.2.%"
+PREFERRED_VERSION_gstreamer1.0              ?= "1.12.%"
+PREFERRED_VERSION_gstreamer1.0-plugins-bad  ?= "1.12.%"
+PREFERRED_VERSION_gstreamer1.0-plugins-base ?= "1.12.%"
+PREFERRED_VERSION_gstreamer1.0-plugins-good ?= "1.12.%"
+PREFERRED_VERSION_gstreamer1.0-plugins-ugly ?= "1.12.%"
+PREFERRED_VERSION_gstreamer1.0-libav        ?= "1.12.%"
+PREFERRED_VERSION_gstreamer1.0-omx          ?= "1.12.%"
 
 # Prefer libjpeg-turbo
 PREFERRED_PROVIDER_jpeg = "libjpeg-turbo"
index c241435..fd11ade 100644 (file)
@@ -4,7 +4,7 @@ IMAGE_INSTALL_append = " \
     packagegroup-agl-devel \
 "
 
-IMAGE_INSTALL_append = "${@bb.utils.contains_any('IMAGE_FSTYPES', [ 'vmdk', 'vmdk.xz' ], ' open-vm-tools vboxguestdrivers', '', d)}"
+IMAGE_INSTALL_append = "${@bb.utils.contains('IMAGE_FSTYPES', 'wic.vmdk', ' open-vm-tools vboxguestdrivers', '', d)}"
 
 # disable install of debug files in SDK
 # initial value: SDKIMAGE_FEATURES="dev-pkgs dbg-pkgs staticdev-pkgs"
index d910f0f..f8a3843 100644 (file)
@@ -86,3 +86,5 @@ postdrop::954:
 display::200:
 agl-driver::1001:
 agl-passenger::1002:
+systemd-network::1005:
+systemd-resolve::1006:
index df4c23e..754cb81 100644 (file)
@@ -56,3 +56,5 @@ opensaf::957:957:::
 lldpd::956:956:::
 cyrus::955:8:::
 display::200:200:::
+systemd-network::1005:1005:::
+systemd-resolve::1006:1006:::
diff --git a/meta-agl/recipes-connectivity/bluez5/bluez5/cve-2017-1000250.patch b/meta-agl/recipes-connectivity/bluez5/bluez5/cve-2017-1000250.patch
deleted file mode 100644 (file)
index 9fac961..0000000
+++ /dev/null
@@ -1,34 +0,0 @@
-All versions of the SDP server in BlueZ 5.46 and earlier are vulnerable to an
-information disclosure vulnerability which allows remote attackers to obtain
-sensitive information from the bluetoothd process memory. This vulnerability
-lies in the processing of SDP search attribute requests.
-
-CVE: CVE-2017-1000250
-Upstream-Status: Backport
-Signed-off-by: Ross Burton <ross.burton@intel.com>
-
-From 9e009647b14e810e06626dde7f1bb9ea3c375d09 Mon Sep 17 00:00:00 2001
-From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
-Date: Wed, 13 Sep 2017 10:01:40 +0300
-Subject: sdp: Fix Out-of-bounds heap read in service_search_attr_req function
-
-Check if there is enough data to continue otherwise return an error.
----
- src/sdpd-request.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-diff --git a/src/sdpd-request.c b/src/sdpd-request.c
-index 1eefdce..318d044 100644
---- a/src/sdpd-request.c
-+++ b/src/sdpd-request.c
-@@ -917,7 +917,7 @@ static int service_search_attr_req(sdp_req_t *req, sdp_buf_t *buf)
-       } else {
-               /* continuation State exists -> get from cache */
-               sdp_buf_t *pCache = sdp_get_cached_rsp(cstate);
--              if (pCache) {
-+              if (pCache && cstate->cStateValue.maxBytesSent < pCache->data_size) {
-                       uint16_t sent = MIN(max, pCache->data_size - cstate->cStateValue.maxBytesSent);
-                       pResponse = pCache->data;
-                       memcpy(buf->data, pResponse + cstate->cStateValue.maxBytesSent, sent);
--- 
-cgit v1.1
index 5436815..ffb9d5b 100644 (file)
@@ -1,6 +1,5 @@
 FILESEXTRAPATHS_prepend := "${THISDIR}/${BPN}:"
-SRC_URI_append = " file://bluetooth.conf \
-                   file://cve-2017-1000250.patch"
+SRC_URI_append = " file://bluetooth.conf"
 
 do_install_append() {
     install -m 0644 ${WORKDIR}/bluetooth.conf ${D}${sysconfdir}/dbus-1/system.d/bluetooth.conf
index b4704de..95fc0a9 100644 (file)
@@ -1,9 +1,10 @@
 --- a/src/connman.service.in   2016-08-15 13:51:03.479478140 +0200
 +++ b/src/connman.service.in   2016-08-15 13:51:33.469478267 +0200
-@@ -6,6 +6,7 @@ RequiresMountsFor=@localstatedir@/lib/co
+@@ -7,6 +7,7 @@ RequiresMountsFor=@localstatedir@/lib/co
  After=dbus.service network-pre.target systemd-sysusers.service
  Before=network.target multi-user.target shutdown.target
  Wants=network.target
+ Conflicts=systemd-resolved.service
 +ConditionKernelCommandLine=!root=/dev/nfs
  
  [Service]
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
deleted file mode 100644 (file)
index eca08ee..0000000
+++ /dev/null
@@ -1,2541 +0,0 @@
-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
deleted file mode 100644 (file)
index bbd61aa..0000000
+++ /dev/null
@@ -1,9455 +0,0 @@
-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
-
index bfee4f5..4ae5925 100644 (file)
@@ -5,28 +5,21 @@ 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 \
-            file://0001-Fix-missing-link-to-unistring-for-lms-plugin.patch \
-            file://rygel.service \
-            "
+SRC_URI += "\
+    file://0001-Fix-missing-link-to-unistring-for-lms-plugin.patch \
+    file://rygel.service \
+"
 
-inherit systemd
+do_install_prepend() {
+    # Install rygel systemd service
+    if ${@bb.utils.contains('DISTRO_FEATURES', 'systemd', 'true', 'false', d)}; then
+        install -m 644 -p -D ${WORKDIR}/rygel.service ${D}${systemd_user_unitdir}/rygel.service
 
-do_install_append() {
-       # Install rygel systemd service
-       if ${@bb.utils.contains('DISTRO_FEATURES', 'systemd', 'true', 'false', d)}; then
-              install -m 644 -p -D ${WORKDIR}/rygel.service ${D}${systemd_user_unitdir}/rygel.service
-
-              # Execute these manually on behalf of systemctl script (from systemd-systemctl-native.bb)
-              # because it does not support systemd's user mode.
-              # However, systemctl --global should be checked
-              #mkdir -p ${D}/etc/systemd/user/default.target.wants/
-              #ln -sf ${systemd_user_unitdir}/rygel.service ${D}/etc/systemd/user/dbus-org.gnome.Rygel1.service
-              #ln -sf ${systemd_user_unitdir}/rygel.service ${D}/etc/systemd/user/default.target.wants/rygel.service
-       fi
+        # Execute these manually on behalf of systemctl script (from systemd-systemctl-native.bb)
+        # because it does not support systemd's user mode.
+        # However, systemctl --global should be checked
+        #mkdir -p ${D}/etc/systemd/user/default.target.wants/
+        #ln -sf ${systemd_user_unitdir}/rygel.service ${D}/etc/systemd/user/dbus-org.gnome.Rygel1.service
+        #ln -sf ${systemd_user_unitdir}/rygel.service ${D}/etc/systemd/user/default.target.wants/rygel.service
+    fi
 }
-
-FILES_${PN} += " \
-    ${@bb.utils.contains('DISTRO_FEATURES', 'systemd', '${systemd_user_unitdir}/rygel.service', '', d)} \
-    "
index c6b9d53..27d1144 100644 (file)
@@ -18,6 +18,5 @@ Last-Update: 2015-03-25
     configuration.  */
 -#if __LINUX_KERNEL_VERSION < 0x030E03
 +#if __LINUX_KERNEL_VERSION < 0x020620
- # undef __ASSUME_REQUEUE_PI
  # undef __ASSUME_SET_ROBUST_LIST
  #endif
diff --git a/meta-agl/recipes-core/systemd/systemd/backport-v234-e266c06.patch b/meta-agl/recipes-core/systemd/systemd/backport-v234-e266c06.patch
deleted file mode 100644 (file)
index 1f4a23e..0000000
+++ /dev/null
@@ -1,315 +0,0 @@
-commit e266c068b5597e18b2299f9c9d3ee6cf04198c41
-Author: Michal Sekletar <msekleta@redhat.com>
-Date:   Mon Jan 23 17:12:35 2017 +0100
-
-    service: serialize information about currently executing command
-    
-    Stored information will help us to resume execution after the
-    daemon-reload.
-    
-    This commit implements following scheme,
-    
-    * On serialization:
-      - we count rank of the currently executing command
-      - we store command type, its rank and command line arguments
-    
-    * On deserialization:
-      - configuration is parsed and loaded
-      - we deserialize stored data, command type, rank and arguments
-      - we look at the given rank in the list and if command there has same
-        arguments then we restore execution at that point
-      - otherwise we search respective command list and we look for command
-        that has the same arguments
-      - if both methods fail we do not do not resume execution at all
-    
-    To better illustrate how does above scheme works, please consider
-    following cases (<<< denotes position where we resume execution after reload)
-    
-    ; Original unit file
-    [Service]
-    ExecStart=/bin/true <<<
-    ExecStart=/bin/false
-    
-    ; Swapped commands
-    ; Second command is not going to be executed
-    [Service]
-    ExecStart=/bin/false
-    ExecStart=/bin/true <<<
-    
-    ; Commands added before
-    ; Same commands are problematic and execution could be restarted at wrong place
-    [Service]
-    ExecStart=/bin/foo
-    ExecStart=/bin/bar
-    ExecStart=/bin/true <<<
-    ExecStart=/bin/false
-    
-    ; Commands added after
-    ; Same commands are not an issue in this case
-    [Service]
-    ExecStart=/bin/true <<<
-    ExecStart=/bin/false
-    ExecStart=/bin/foo
-    ExecStart=/bin/bar
-    
-    ; New commands interleaved with old commands
-    ; Some new commands will be executed while others won't
-    ExecStart=/bin/foo
-    ExecStart=/bin/true <<<
-    ExecStart=/bin/bar
-    ExecStart=/bin/false
-    
-    As you can see, above scheme has some drawbacks. However, in most
-    cases (we assume that in most common case unit file command list is not
-    changed while some other command is running for the same unit) it
-    should cause that systemd does the right thing, which is restoring
-    execution exactly at the point we were before daemon-reload.
-    
-    Fixes #518
-
-Signed-off-by: Scott Murray <scott.murray@konsulko.com>
-
-Upstream-Status: backport
-
-diff --git a/src/core/service.c b/src/core/service.c
-index 74054887b..5e681fb71 100644
---- a/src/core/service.c
-+++ b/src/core/service.c
-@@ -45,6 +45,7 @@
- #include "service.h"
- #include "signal-util.h"
- #include "special.h"
-+#include "stdio-util.h"
- #include "string-table.h"
- #include "string-util.h"
- #include "strv.h"
-@@ -2140,6 +2141,80 @@ _pure_ static bool service_can_reload(Unit *u) {
-         return !!s->exec_command[SERVICE_EXEC_RELOAD];
- }
-+static unsigned service_exec_command_index(Unit *u, ServiceExecCommand id, ExecCommand *current) {
-+        Service *s = SERVICE(u);
-+        unsigned idx = 0;
-+        ExecCommand *first, *c;
-+
-+        assert(s);
-+
-+        first = s->exec_command[id];
-+
-+        /* Figure out where we are in the list by walking back to the beginning */
-+        for (c = current; c != first; c = c->command_prev)
-+                idx++;
-+
-+        return idx;
-+}
-+
-+static int service_serialize_exec_command(Unit *u, FILE *f, ExecCommand *command) {
-+        Service *s = SERVICE(u);
-+        ServiceExecCommand id;
-+        unsigned idx;
-+        const char *type;
-+        char **arg;
-+        _cleanup_strv_free_ char **escaped_args = NULL;
-+        _cleanup_free_ char *args = NULL, *p = NULL;
-+        size_t allocated = 0, length = 0;
-+
-+        assert(s);
-+        assert(f);
-+
-+        if (!command)
-+                return 0;
-+
-+        if (command == s->control_command) {
-+                type = "control";
-+                id = s->control_command_id;
-+        } else {
-+                type = "main";
-+                id = SERVICE_EXEC_START;
-+        }
-+
-+        idx = service_exec_command_index(u, id, command);
-+
-+        STRV_FOREACH(arg, command->argv) {
-+                size_t n;
-+                _cleanup_free_ char *e = NULL;
-+
-+                e = xescape(*arg, WHITESPACE);
-+                if (!e)
-+                        return -ENOMEM;
-+
-+                n = strlen(e);
-+                if (!GREEDY_REALLOC(args, allocated, length + 1 + n + 1))
-+                        return -ENOMEM;
-+
-+                if (length > 0)
-+                        args[length++] = ' ';
-+
-+                memcpy(args + length, e, n);
-+                length += n;
-+        }
-+
-+        if (!GREEDY_REALLOC(args, allocated, length + 1))
-+                return -ENOMEM;
-+        args[length++] = 0;
-+
-+        p = xescape(command->path, WHITESPACE);
-+        if (!p)
-+                return -ENOMEM;
-+
-+        fprintf(f, "%s-command=%s %u %s %s\n", type, service_exec_command_to_string(id), idx, p, args);
-+
-+        return 0;
-+}
-+
- static int service_serialize(Unit *u, FILE *f, FDSet *fds) {
-         Service *s = SERVICE(u);
-         ServiceFDStore *fs;
-@@ -2167,11 +2242,8 @@ static int service_serialize(Unit *u, FILE *f, FDSet *fds) {
-         if (r < 0)
-                 return r;
--        /* FIXME: There's a minor uncleanliness here: if there are
--         * multiple commands attached here, we will start from the
--         * first one again */
--        if (s->control_command_id >= 0)
--                unit_serialize_item(u, f, "control-command", service_exec_command_to_string(s->control_command_id));
-+        service_serialize_exec_command(u, f, s->control_command);
-+        service_serialize_exec_command(u, f, s->main_command);
-         r = unit_serialize_item_fd(u, f, fds, "stdin-fd", s->stdin_fd);
-         if (r < 0)
-@@ -2227,6 +2299,106 @@ static int service_serialize(Unit *u, FILE *f, FDSet *fds) {
-         return 0;
- }
-+static int service_deserialize_exec_command(Unit *u, const char *key, const char *value) {
-+        Service *s = SERVICE(u);
-+        int r;
-+        unsigned idx = 0, i;
-+        bool control, found = false;
-+        ServiceExecCommand id = _SERVICE_EXEC_COMMAND_INVALID;
-+        ExecCommand *command = NULL;
-+        _cleanup_free_ char *args = NULL, *path = NULL;
-+        _cleanup_strv_free_ char **argv = NULL;
-+
-+        enum ExecCommandState {
-+                STATE_EXEC_COMMAND_TYPE,
-+                STATE_EXEC_COMMAND_INDEX,
-+                STATE_EXEC_COMMAND_PATH,
-+                STATE_EXEC_COMMAND_ARGS,
-+                _STATE_EXEC_COMMAND_MAX,
-+                _STATE_EXEC_COMMAND_INVALID = -1,
-+        } state;
-+
-+        assert(s);
-+        assert(key);
-+        assert(value);
-+
-+        control = streq(key, "control-command");
-+
-+        state = STATE_EXEC_COMMAND_TYPE;
-+
-+        for (;;) {
-+                _cleanup_free_ char *arg = NULL;
-+
-+                r = extract_first_word(&value, &arg, NULL, EXTRACT_CUNESCAPE);
-+                if (r == 0)
-+                        break;
-+                else if (r < 0)
-+                        return r;
-+
-+                switch (state) {
-+                case STATE_EXEC_COMMAND_TYPE:
-+                        id = service_exec_command_from_string(arg);
-+                        if (id < 0)
-+                                return -EINVAL;
-+
-+                        state = STATE_EXEC_COMMAND_INDEX;
-+                        break;
-+                case STATE_EXEC_COMMAND_INDEX:
-+                        r = safe_atou(arg, &idx);
-+                        if (r < 0)
-+                                return -EINVAL;
-+
-+                        state = STATE_EXEC_COMMAND_PATH;
-+                        break;
-+                case STATE_EXEC_COMMAND_PATH:
-+                        path = arg;
-+                        arg = NULL;
-+                        state = STATE_EXEC_COMMAND_ARGS;
-+
-+                        if (!path_is_absolute(path))
-+                                return -EINVAL;
-+                        break;
-+                case STATE_EXEC_COMMAND_ARGS:
-+                        r = strv_extend(&argv, arg);
-+                        if (r < 0)
-+                                return -ENOMEM;
-+                        break;
-+                default:
-+                        assert_not_reached("Unknown error at deserialization of exec command");
-+                        break;
-+                }
-+        }
-+
-+        if (state != STATE_EXEC_COMMAND_ARGS)
-+                return -EINVAL;
-+
-+        /* Let's check whether exec command on given offset matches data that we just deserialized */
-+        for (command = s->exec_command[id], i = 0; command; command = command->command_next, i++) {
-+                if (i != idx)
-+                        continue;
-+
-+                found = strv_equal(argv, command->argv) && streq(command->path, path);
-+                break;
-+        }
-+
-+        if (!found) {
-+                /* Command at the index we serialized is different, let's look for command that exactly
-+                 * matches but is on different index. If there is no such command we will not resume execution. */
-+                for (command = s->exec_command[id]; command; command = command->command_next)
-+                        if (strv_equal(command->argv, argv) && streq(command->path, path))
-+                                break;
-+        }
-+
-+        if (command && control)
-+                s->control_command = command;
-+        else if (command)
-+                s->main_command = command;
-+        else
-+                log_unit_warning(u, "Current command vanished from the unit file, execution of the command list won't be resumed.");
-+
-+        return 0;
-+}
-+
- static int service_deserialize_item(Unit *u, const char *key, const char *value, FDSet *fds) {
-         Service *s = SERVICE(u);
-         int r;
-@@ -2309,16 +2481,6 @@ static int service_deserialize_item(Unit *u, const char *key, const char *value,
-                         s->status_text = t;
-                 }
--        } else if (streq(key, "control-command")) {
--                ServiceExecCommand id;
--
--                id = service_exec_command_from_string(value);
--                if (id < 0)
--                        log_unit_debug(u, "Failed to parse exec-command value: %s", value);
--                else {
--                        s->control_command_id = id;
--                        s->control_command = s->exec_command[id];
--                }
-         } else if (streq(key, "accept-socket")) {
-                 Unit *socket;
-@@ -2437,6 +2599,10 @@ static int service_deserialize_item(Unit *u, const char *key, const char *value,
-                         s->watchdog_override_enable = true;
-                         s->watchdog_override_usec = watchdog_override_usec;
-                 }
-+        } else if (STR_IN_SET(key, "main-command", "control-command")) {
-+                r = service_deserialize_exec_command(u, key, value);
-+                if (r < 0)
-+                        log_unit_debug_errno(u, r, "Failed to parse serialized command \"%s\": %m", value);
-         } else
-                 log_unit_debug(u, "Unknown serialization key: %s", key);
index 354464c..f64ca8c 100644 (file)
@@ -1,9 +1,9 @@
 FILESEXTRAPATHS_prepend := "${THISDIR}/${PN}:"
 
-SRC_URI += "file://backport-v234-e266c06.patch \
-            file://e2fsck.conf \
-            ${@bb.utils.contains('VIRTUAL-RUNTIME_net_manager','systemd','file://wired.network','',d)} \
-           "
+SRC_URI += "\
+    file://e2fsck.conf \
+    ${@bb.utils.contains('VIRTUAL-RUNTIME_net_manager','systemd','file://wired.network','',d)} \
+"
 
 # enable networkd/resolved support
 PACKAGECONFIG_append_pn-systemd = " \
diff --git a/meta-agl/recipes-devtools/autogen/autogen-native_5.18.12.bbappend b/meta-agl/recipes-devtools/autogen/autogen-native_5.18.12.bbappend
deleted file mode 100644 (file)
index a6f697c..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-FILESEXTRAPATHS_prepend := "${THISDIR}/files:"
-SRC_URI_append = "file://0003-autoopts-mk-tpl-config.sh-fix-shell-path.patch"
diff --git a/meta-agl/recipes-devtools/autogen/files/0003-autoopts-mk-tpl-config.sh-fix-shell-path.patch b/meta-agl/recipes-devtools/autogen/files/0003-autoopts-mk-tpl-config.sh-fix-shell-path.patch
deleted file mode 100644 (file)
index db6b0cd..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-From df4f5ccc376a630b1a587a8ca3b1f35a305867dd Mon Sep 17 00:00:00 2001
-From: Robert Berger <robert.berger@ReliableEmbeddedSystems.com>
-Date: Wed, 23 Aug 2017 07:19:03 +0000
-Subject: [PATCH] autoopts/mk-tpl-config.sh: fix shell path
-
-POSIX_SHELL as shebang doesn't work when it is longer than
-BINPRM_BUF_SIZE which is 128 usually. So use "/bin/sh".
-
-Signed-off-by: Robert Berger <robert.berger@ReliableEmbeddedSystems.com>
----
- autoopts/mk-tpl-config.sh | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-diff --git a/autoopts/mk-tpl-config.sh b/autoopts/mk-tpl-config.sh
-index c4708a2..550870e 100755
---- a/autoopts/mk-tpl-config.sh
-+++ b/autoopts/mk-tpl-config.sh
-@@ -102,7 +102,7 @@ fix_scripts() {
-                  sed 1d $f
-                  ;;
--        */sh )   echo '#!' ${POSIX_SHELL}
-+        */sh )   echo '#!/bin/sh'
-                  sed 1d $f
-                  ;;
--- 
-2.7.4
-
diff --git a/meta-agl/recipes-multimedia/lightmediascanner/files/0001-Define-comparison_fn_t-for-non-glibc-systems.patch b/meta-agl/recipes-multimedia/lightmediascanner/files/0001-Define-comparison_fn_t-for-non-glibc-systems.patch
new file mode 100644 (file)
index 0000000..15d4b3f
--- /dev/null
@@ -0,0 +1,33 @@
+From 5bc5b8c5dad3edec6736fd7e7ce61250c4ce3725 Mon Sep 17 00:00:00 2001
+From: Khem Raj <raj.khem@gmail.com>
+Date: Wed, 12 Jul 2017 17:13:19 -0700
+Subject: [PATCH] Define comparison_fn_t for non-glibc systems
+
+lightmediascanner.c:324:12: error: 'comparison_fn_t' undeclared (first use in this function)
+           (comparison_fn_t)_plugin_sort);
+            ^~~~~~~~~~~~~~~
+
+Signed-off-by: Khem Raj <raj.khem@gmail.com>
+---
+ src/lib/lightmediascanner.c | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+diff --git a/src/lib/lightmediascanner.c b/src/lib/lightmediascanner.c
+index 344b247..b866883 100644
+--- a/src/lib/lightmediascanner.c
++++ b/src/lib/lightmediascanner.c
+@@ -37,6 +37,11 @@
+ #define DEFAULT_SLAVE_TIMEOUT 1000
+ #define DEFAULT_COMMIT_INTERVAL 100
++#if !defined(__GLIBC__)
++typedef int (*__compar_fn_t) (const void*, const void*);
++typedef __compar_fn_t comparison_fn_t;
++#endif
++
+ #ifdef HAVE_MAGIC_H
+ static magic_t _magic_handle;
+-- 
+2.13.2
+
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 (file)
index 0000000..9528bec
--- /dev/null
@@ -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_0.5.1.bb b/meta-agl/recipes-multimedia/lightmediascanner/lightmediascanner_0.5.1.bb
new file mode 100644 (file)
index 0000000..f215876
--- /dev/null
@@ -0,0 +1,63 @@
+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 \
+           file://0001-Define-comparison_fn_t-for-non-glibc-systems.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') + '-meta'
+    d.setVar('RDEPENDS_' + metapkg, ' '.join(pkgs))
+}
index 1025e0e..9d61a9f 100644 (file)
@@ -1,4 +1,3 @@
-DEPENDS += "gobject-introspection-native"
 inherit gobject-introspection
 
 FILESEXTRAPATHS_prepend := "${THISDIR}/files:"
index 1d8ab0a..b77a5d1 100644 (file)
@@ -4,7 +4,7 @@ DISTRO_FEATURES_append = " smack dbus-cynara xattr"
 
 # use tar-native to support SMACK extended attributes independently of host config
 IMAGE_CMD_TAR = "tar --xattrs --xattrs-include='*'"
-IMAGE_DEPENDS_tar_append = " tar-replacement-native"
+do_image_tar[depends] += "tar-replacement-native:do_populate_sysroot"
 EXTRANATIVEPATH += "tar-native"
 
 # security: enable ssh server in place of dropbear to support PAM on user sessions
diff --git a/meta-app-framework/recipes-core/security-manager/security-manager/0001-gcc-7-requires-include-functional-for-std-function.patch b/meta-app-framework/recipes-core/security-manager/security-manager/0001-gcc-7-requires-include-functional-for-std-function.patch
new file mode 100644 (file)
index 0000000..7b6845a
--- /dev/null
@@ -0,0 +1,51 @@
+From ed1c105db9d7b1ceb52ec16f35b0a2c959c19c6d Mon Sep 17 00:00:00 2001
+From: Changhyeok Bae <changhyeok.bae@gmail.com>
+Date: Sun, 17 Dec 2017 15:40:58 +0000
+Subject: [PATCH] gcc-7 requires include <functional> for std::function
+
+Signed-off-by: Changhyeok Bae <changhyeok.bae@gmail.com>
+---
+ src/client/client-common.cpp      | 1 +
+ src/common/smack-labels.cpp       | 1 +
+ src/dpl/core/src/binary_queue.cpp | 1 +
+ 3 files changed, 3 insertions(+)
+
+diff --git a/src/client/client-common.cpp b/src/client/client-common.cpp
+index 883ab8d..1babdf7 100644
+--- a/src/client/client-common.cpp
++++ b/src/client/client-common.cpp
+@@ -31,6 +31,7 @@
+ #include <sys/xattr.h>
+ #include <linux/xattr.h>
+ #include <unistd.h>
++#include <functional>
+ #include <dpl/log/log.h>
+ #include <dpl/serialization.h>
+diff --git a/src/common/smack-labels.cpp b/src/common/smack-labels.cpp
+index 0294a42..1598099 100644
+--- a/src/common/smack-labels.cpp
++++ b/src/common/smack-labels.cpp
+@@ -29,6 +29,7 @@
+ #include <sys/xattr.h>
+ #include <linux/xattr.h>
+ #include <memory>
++#include <functional>
+ #include <fts.h>
+ #include <cstring>
+ #include <string>
+diff --git a/src/dpl/core/src/binary_queue.cpp b/src/dpl/core/src/binary_queue.cpp
+index 72817a6..838409f 100644
+--- a/src/dpl/core/src/binary_queue.cpp
++++ b/src/dpl/core/src/binary_queue.cpp
+@@ -26,6 +26,7 @@
+ #include <malloc.h>
+ #include <cstring>
+ #include <new>
++#include <functional>
+ namespace SecurityManager {
+ BinaryQueue::BinaryQueue() :
+-- 
+2.7.4
+
index bd1a43e..92b7957 100644 (file)
@@ -7,6 +7,7 @@ SRC_URI += " file://0001-Adapt-rules-to-AGL.patch \
             file://init-security-manager-db.sh \
              file://0001-Fix-gcc6-build.patch \
              file://0001-Fix-Cmake-conf-for-gcc6-build.patch \
+             file://0001-gcc-7-requires-include-functional-for-std-function.patch \
 "
 
 FILES_${PN}_append = "${bindir}/init-security-manager-db.sh \
diff --git a/meta-app-framework/recipes-kernel/linux/linux-yocto_4.1.bbappend b/meta-app-framework/recipes-kernel/linux/linux-yocto_4.1.bbappend
deleted file mode 100644 (file)
index c1c6572..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-FILESEXTRAPATHS_prepend := "${THISDIR}/linux/linux-yocto-4.1:"
-
-#-------------------------------------------------------------------------
-# smack patches for handling bluetooth
-
-SRC_URI_append_smack = "\
-       file://0001-Smack-File-receive-for-sockets.patch \
-       file://0002-smack-fix-cache-of-access-labels.patch \
-       file://0003-Smack-ignore-null-signal-in-smack_task_kill.patch \
-       file://0004-Smack-Assign-smack_known_web-label-for-kernel-thread.patch \
-"
-
@@ -1,4 +1,4 @@
-FILESEXTRAPATHS_prepend := "${THISDIR}/linux/linux-yocto-4.4:"
+FILESEXTRAPATHS_prepend := "${THISDIR}/linux/linux-yocto-4.12:"
 
 #-------------------------------------------------------------------------
 # smack patches for handling bluetooth
diff --git a/meta-app-framework/recipes-kernel/linux/linux/linux-yocto-4.1/0001-Smack-File-receive-for-sockets.patch b/meta-app-framework/recipes-kernel/linux/linux/linux-yocto-4.1/0001-Smack-File-receive-for-sockets.patch
deleted file mode 100644 (file)
index b0c5ee8..0000000
+++ /dev/null
@@ -1,62 +0,0 @@
-From 2e65b888820ea372984d412cee3bd7dcba05d7d2 Mon Sep 17 00:00:00 2001
-From: Casey Schaufler <casey@schaufler-ca.com>
-Date: Mon, 7 Dec 2015 14:34:32 -0800
-Subject: [PATCH 1/4] Smack: File receive for sockets
-
-The existing file receive hook checks for access on
-the file inode even for UDS. This is not right, as
-the inode is not used by Smack to make access checks
-for sockets. This change checks for an appropriate
-access relationship between the receiving (current)
-process and the socket. If the process can't write
-to the socket's send label or the socket's receive
-label can't write to the process fail.
-
-This will allow the legitimate cases, where the
-socket sender and socket receiver can freely communicate.
-Only strangly set socket labels should cause a problem.
-
-Signed-off-by: Casey Schaufler <casey@schaufler-ca.com>
----
- security/smack/smack_lsm.c | 22 ++++++++++++++++++++++
- 1 file changed, 22 insertions(+)
-
-diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c
-index b644757..487b2f3 100644
---- a/security/smack/smack_lsm.c
-+++ b/security/smack/smack_lsm.c
-@@ -1672,9 +1672,31 @@ static int smack_file_receive(struct file *file)
-       int may = 0;
-       struct smk_audit_info ad;
-       struct inode *inode = file_inode(file);
-+      struct socket *sock;
-+      struct task_smack *tsp;
-+      struct socket_smack *ssp;
-       smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_PATH);
-       smk_ad_setfield_u_fs_path(&ad, file->f_path);
-+
-+      if (S_ISSOCK(inode->i_mode)) {
-+              sock = SOCKET_I(inode);
-+              ssp = sock->sk->sk_security;
-+              tsp = current_security();
-+              /*
-+               * If the receiving process can't write to the
-+               * passed socket or if the passed socket can't
-+               * write to the receiving process don't accept
-+               * the passed socket.
-+               */
-+              rc = smk_access(tsp->smk_task, ssp->smk_out, MAY_WRITE, &ad);
-+              rc = smk_bu_file(file, may, rc);
-+              if (rc < 0)
-+                      return rc;
-+              rc = smk_access(ssp->smk_in, tsp->smk_task, MAY_WRITE, &ad);
-+              rc = smk_bu_file(file, may, rc);
-+              return rc;
-+      }
-       /*
-        * This code relies on bitmasks.
-        */
--- 
-2.7.4
-
diff --git a/meta-app-framework/recipes-kernel/linux/linux/linux-yocto-4.1/0002-smack-fix-cache-of-access-labels.patch b/meta-app-framework/recipes-kernel/linux/linux/linux-yocto-4.1/0002-smack-fix-cache-of-access-labels.patch
deleted file mode 100644 (file)
index 51c3b31..0000000
+++ /dev/null
@@ -1,43 +0,0 @@
-From 5bcea0fc4e5360deca133e211fdc76717a1693a4 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Jos=C3=A9=20Bollo?= <jobol@nonadev.net>
-Date: Tue, 12 Jan 2016 21:23:40 +0100
-Subject: [PATCH 2/4] smack: fix cache of access labels
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Before this commit, removing the access property of
-a file, aka, the extended attribute security.SMACK64
-was not effictive until the cache had been cleaned.
-
-This patch fixes that problem.
-
-Signed-off-by: José Bollo <jobol@nonadev.net>
-Acked-by: Casey Schaufler <casey@schaufler-ca.com>
----
- security/smack/smack_lsm.c | 8 ++++++--
- 1 file changed, 6 insertions(+), 2 deletions(-)
-
-diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c
-index 487b2f3..b9393e3 100644
---- a/security/smack/smack_lsm.c
-+++ b/security/smack/smack_lsm.c
-@@ -1256,9 +1256,13 @@ static int smack_inode_removexattr(struct dentry *dentry, const char *name)
-        * Don't do anything special for these.
-        *      XATTR_NAME_SMACKIPIN
-        *      XATTR_NAME_SMACKIPOUT
--       *      XATTR_NAME_SMACKEXEC
-        */
--      if (strcmp(name, XATTR_NAME_SMACK) == 0)
-+      if (strcmp(name, XATTR_NAME_SMACK) == 0) {
-+              struct super_block *sbp = d_backing_inode(dentry)->i_sb;
-+              struct superblock_smack *sbsp = sbp->s_security;
-+
-+              isp->smk_inode = sbsp->smk_default;
-+      } else if (strcmp(name, XATTR_NAME_SMACKEXEC) == 0)
-               isp->smk_task = NULL;
-       else if (strcmp(name, XATTR_NAME_SMACKMMAP) == 0)
-               isp->smk_mmap = NULL;
--- 
-2.7.4
-
diff --git a/meta-app-framework/recipes-kernel/linux/linux/linux-yocto-4.1/0003-Smack-ignore-null-signal-in-smack_task_kill.patch b/meta-app-framework/recipes-kernel/linux/linux/linux-yocto-4.1/0003-Smack-ignore-null-signal-in-smack_task_kill.patch
deleted file mode 100644 (file)
index 67761ae..0000000
+++ /dev/null
@@ -1,39 +0,0 @@
-From aa63c4f8ece0c54a9be735ac38667f11fcd6f44a Mon Sep 17 00:00:00 2001
-From: Rafal Krypa <r.krypa@samsung.com>
-Date: Mon, 4 Apr 2016 11:14:53 +0200
-Subject: [PATCH 3/4] Smack: ignore null signal in smack_task_kill
-
-Kill with signal number 0 is commonly used for checking PID existence.
-Smack treated such cases like any other kills, although no signal is
-actually delivered when sig == 0.
-
-Checking permissions when sig == 0 didn't prevent an unprivileged caller
-from learning whether PID exists or not. When it existed, kernel returned
-EPERM, when it didn't - ESRCH. The only effect of policy check in such
-case is noise in audit logs.
-
-This change lets Smack silently ignore kill() invocations with sig == 0.
-
-Signed-off-by: Rafal Krypa <r.krypa@samsung.com>
-Acked-by: Casey Schaufler <casey@schaufler-ca.com>
----
- security/smack/smack_lsm.c | 3 +++
- 1 file changed, 3 insertions(+)
-
-diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c
-index b9393e3..c916f58 100644
---- a/security/smack/smack_lsm.c
-+++ b/security/smack/smack_lsm.c
-@@ -2056,6 +2056,9 @@ static int smack_task_kill(struct task_struct *p, struct siginfo *info,
-       struct smack_known *tkp = smk_of_task_struct(p);
-       int rc;
-+      if (!sig)
-+              return 0; /* null signal; existence test */
-+
-       smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_TASK);
-       smk_ad_setfield_u_tsk(&ad, p);
-       /*
--- 
-2.7.4
-
diff --git a/meta-app-framework/recipes-kernel/linux/linux/linux-yocto-4.1/0004-Smack-Assign-smack_known_web-label-for-kernel-thread.patch b/meta-app-framework/recipes-kernel/linux/linux/linux-yocto-4.1/0004-Smack-Assign-smack_known_web-label-for-kernel-thread.patch
deleted file mode 100644 (file)
index 4281c20..0000000
+++ /dev/null
@@ -1,49 +0,0 @@
-From b2b9e7ec8e79ede841104f76464f4b77c057b011 Mon Sep 17 00:00:00 2001
-From: jooseong lee <jooseong.lee@samsung.com>
-Date: Thu, 3 Nov 2016 10:55:43 +0100
-Subject: [PATCH 4/4] Smack: Assign smack_known_web label for kernel thread's
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Assign smack_known_web label for kernel thread's socket in the sk_alloc_security hook
-
-Creating struct sock by sk_alloc function in various kernel subsystems
-like bluetooth dosen't call smack_socket_post_create(). In such case,
-received sock label is the floor('_') label and makes access deny.
-
-Refers-to: https://review.tizen.org/gerrit/#/c/80717/4
-
-Change-Id: I2e5c9359bfede84a988fd4d4d74cdb9dfdfc52d8
-Signed-off-by: jooseong lee <jooseong.lee@samsung.com>
-Signed-off-by: José Bollo <jose.bollo@iot.bzh>
----
- security/smack/smack_lsm.c | 12 ++++++++++--
- 1 file changed, 10 insertions(+), 2 deletions(-)
-
-diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c
-index c916f58..cc6769b 100644
---- a/security/smack/smack_lsm.c
-+++ b/security/smack/smack_lsm.c
-@@ -2138,8 +2138,16 @@ static int smack_sk_alloc_security(struct sock *sk, int family, gfp_t gfp_flags)
-       if (ssp == NULL)
-               return -ENOMEM;
--      ssp->smk_in = skp;
--      ssp->smk_out = skp;
-+      /*
-+       * Sockets created by kernel threads receive web label.
-+       */
-+      if (unlikely(current->flags & PF_KTHREAD)) {
-+              ssp->smk_in = &smack_known_web;
-+              ssp->smk_out = &smack_known_web;
-+      } else {
-+              ssp->smk_in = skp;
-+              ssp->smk_out = skp;
-+      }
-       ssp->smk_packet = NULL;
-       sk->sk_security = ssp;
--- 
-2.7.4
-
diff --git a/meta-app-framework/recipes-security/cynara/cynara/0001-gcc-7-requires-include-functional-for-std-function.patch b/meta-app-framework/recipes-security/cynara/cynara/0001-gcc-7-requires-include-functional-for-std-function.patch
new file mode 100644 (file)
index 0000000..bd060b2
--- /dev/null
@@ -0,0 +1,38 @@
+From 2169344adbb42ff580856204e2b290e3b04fd447 Mon Sep 17 00:00:00 2001
+From: Changhyeok Bae <changhyeok.bae@gmail.com>
+Date: Sun, 17 Dec 2017 15:28:28 +0000
+Subject: [PATCH] gcc-7 requires include <functional> for std::function
+
+Signed-off-by: Changhyeok Bae <changhyeok.bae@gmail.com>
+---
+ src/common/types/PolicyBucket.h | 1 +
+ src/cyad/AdminPolicyParser.h    | 1 +
+ 2 files changed, 2 insertions(+)
+
+diff --git a/src/common/types/PolicyBucket.h b/src/common/types/PolicyBucket.h
+index 029d3dd..1bceeca 100644
+--- a/src/common/types/PolicyBucket.h
++++ b/src/common/types/PolicyBucket.h
+@@ -30,6 +30,7 @@
+ #include <set>
+ #include <string>
+ #include <vector>
++#include <functional>
+ #include <exceptions/NotImplementedException.h>
+ #include <types/pointers.h>
+diff --git a/src/cyad/AdminPolicyParser.h b/src/cyad/AdminPolicyParser.h
+index 53dde23..f38c194 100644
+--- a/src/cyad/AdminPolicyParser.h
++++ b/src/cyad/AdminPolicyParser.h
+@@ -25,6 +25,7 @@
+ #include <istream>
+ #include <memory>
++#include <functional>
+ #include <cyad/CynaraAdminPolicies.h>
+-- 
+2.7.4
+
index 9a61e70..4c38da1 100644 (file)
@@ -1,3 +1,8 @@
+FILESEXTRAPATHS_prepend := "${THISDIR}/${BPN}:"
+SRC_URI_append = " file://0001-gcc-7-requires-include-functional-for-std-function.patch"
+
+CXXFLAGS_append = " -Wimplicit-fallthrough=0"
+
 pkg_postinst_${PN} () {
    # Fail on error.
    set -e
index fbe8935..c4561db 100644 (file)
@@ -1,5 +1,2 @@
 FILESEXTRAPATHS_append_class-native := ":${THISDIR}/${PN}"
 SRC_URI_append_class-native = " file://removing-capability-enforcement.patch"
-PACKAGECONFIG_class-native ?= "attr"
-DEPENDS_append_class-native = " attr-native"
-
diff --git a/meta-app-framework/recipes-support/libmicrohttpd/libmicrohttpd_0.9.55.bb b/meta-app-framework/recipes-support/libmicrohttpd/libmicrohttpd_0.9.55.bb
deleted file mode 100644 (file)
index bb650ce..0000000
+++ /dev/null
@@ -1,25 +0,0 @@
-DESCRIPTION = "A small C library that is supposed to make it easy to run an HTTP server as part of another application"
-HOMEPAGE = "http://www.gnu.org/software/libmicrohttpd/"
-LICENSE = "LGPL-2.1+"
-LIC_FILES_CHKSUM = "file://COPYING;md5=9331186f4f80db7da0e724bdd6554ee5"
-SECTION = "net"
-DEPENDS = "libgcrypt gnutls file"
-
-SRC_URI = "http://ftp.gnu.org/gnu/libmicrohttpd/${BPN}-${PV}.tar.gz"
-SRC_URI[md5sum] = "1c20f84a8b9cf692dd50b558b3571a3a"
-SRC_URI[sha256sum] = "0c1cab8dc9f2588bd3076a28f77a7f8de9560cbf2d80e53f9a8696ada80ed0f8"
-
-inherit autotools lib_package pkgconfig gettext
-
-EXTRA_OECONF += "--disable-static --with-gnutls=${STAGING_LIBDIR}/../"
-
-PACKAGECONFIG ?= "curl"
-PACKAGECONFIG_append_class-target = "\
-        ${@bb.utils.contains('DISTRO_FEATURES', 'largefile', 'largefile', '', d)} \
-"
-PACKAGECONFIG[largefile] = "--enable-largefile,--disable-largefile,,"
-PACKAGECONFIG[curl] = "--enable-curl,--disable-curl,curl,"
-
-do_compile_append() {
-    sed -i s:-L${STAGING_LIBDIR}::g libmicrohttpd.pc
-}
@@ -4,8 +4,8 @@ SRC_URI =+ "${SOURCEFORGE_MIRROR}/freetype/ft2demos-${PV}.tar.bz2;name=ft2demos
            file://0001-Makefile-dont-build-gfx-demos.patch;patchdir=../ft2demos-${PV} \
            file://0001-ft2demos-Makefile-Do-not-hardcode-libtool-path.patch;patchdir=../ft2demos-${PV} \
           "
-SRC_URI[ft2demos.md5sum] = "5c10cb35bec755dbd3f7999e0f97aee3"
-SRC_URI[ft2demos.sha256sum] = "d3f8a0d5a3f0d58701133458a8c1d3f97f658869f3c904b1fda447ed3b290ecd"
+SRC_URI[ft2demos.md5sum] = "61db5831e213acb843f0fc6d10186054"
+SRC_URI[ft2demos.sha256sum] = "2b6ce0d36bcb43fcc8aac07a0287982d855571ee271c3803c768e501f9c1a233"
 
 PACKAGES =+ "${PN}-demos"
 
index bd42820..44fabae 100644 (file)
@@ -34,9 +34,6 @@ RDEPENDS_${PN} += "\
     "
 # to be added, but needs LICENSE_FLAGS_WHITELIST="non-commercial"
 #    netperf
-# wayland-fits is broken in jethro, https://www.mail-archive.com/openembedded-devel@lists.openembedded.org/msg46505.html
-# http://errors.yoctoproject.org/Errors/Details/35141/
-#     wayland-fits
 
 # FTBS, SPEC-316
 #    himeno 
diff --git a/meta-ivi-common/recipes-test/wayland/wayland-fits_%.bbappend b/meta-ivi-common/recipes-test/wayland/wayland-fits_%.bbappend
deleted file mode 100644 (file)
index 772f81b..0000000
+++ /dev/null
@@ -1,5 +0,0 @@
-# Disable GTK+ and EFL tests
-PACKAGECONFIG = ""
-
-# UInput driver is necessary on QEMU
-RDEPENDS_${PN}_append_qemux86-64 = " kernel-module-uinput"
diff --git a/meta-ivi-common/recipes-test/wayland/wayland-fits_git.bbappend b/meta-ivi-common/recipes-test/wayland/wayland-fits_git.bbappend
deleted file mode 100644 (file)
index 84c7cfd..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-# Updating to latest version is necessary for Weston >= 1.9.0
-SRCREV = "f108335e374772ae2818a30ae37fe6fcda81980f"
index 65ca4a1..363e6bc 100644 (file)
@@ -1,10 +1,7 @@
 # Enable network bootable image and initrd/initramfs
 
-# add image classes for uboot
-IMAGE_CLASSES += "${@'image_types_uboot' if (d.getVar("KERNEL_IMAGETYPE", True) == "uImage") else ''}"
-
 python () {
-       if (bb.utils.contains_any("IMAGE_FSTYPES",["live","vmdk","vmdk.xz"],True,False,d)):
+       if (bb.utils.contains_any("IMAGE_FSTYPES",["live","wic.vmdk"],True,False,d)):
                # typical case for Minnowboard Max
                d.setVar("INITRD_IMAGE","initramfs-netboot-image")
                d.setVar("INITRD_IMAGE_LIVE",d.getVar("INITRD_IMAGE",True))
index 1cfd905..1128b32 100644 (file)
@@ -6,3 +6,6 @@ DISTRO = "poky-agl"
 
 #see meta-agl/meta-agl/conf/include/base-agl.inc
 require conf/include/base-agl.inc
+
+# Temporarily disable GObject Introspection Data
+GI_DATA_ENABLED = "False"
index 6bccb79..d869546 100644 (file)
@@ -35,7 +35,6 @@ AGL_CORE_LAYERS = " \
 AGL_CORE_DEPENDENCY_LAYERS = " \
   ${METADIR}/meta-openembedded/meta-oe \
   ${METADIR}/meta-openembedded/meta-multimedia \
-  ${METADIR}/meta-openembedded/meta-efl \
   ${METADIR}/meta-openembedded/meta-networking \
   ${METADIR}/meta-openembedded/meta-python \
   ${METADIR}/meta-openembedded/meta-filesystems \
index bdcf076..22a718f 100644 (file)
@@ -2,7 +2,6 @@ BBLAYERS =+ " \
        ${METADIR}/meta-updater \
        ${METADIR}/meta-openembedded/meta-filesystems \
        ${METADIR}/meta-openembedded/meta-python \
-       ${METADIR}/meta-openembedded/meta-ruby \
        ${METADIR}/meta-rust \
        "
 
diff --git a/templates/machine/dragonboard-410c/50_setup.sh b/templates/machine/dragonboard-410c/50_setup.sh
deleted file mode 100644 (file)
index 7be1dad..0000000
+++ /dev/null
@@ -1 +0,0 @@
-find_and_ack_eula $METADIR/meta-qcom