/* rygel-tracker-metadata-multivalues.c generated by valac 0.42.2, the Vala compiler
 * generated from rygel-tracker-metadata-multivalues.vala, do not modify */

/*
 * Copyright (C) 2008 Zeeshan Ali <zeenix@gmail.com>.
 * Copyright (C) 2008-2012 Nokia Corporation.
 *
 * Author: Zeeshan Ali <zeenix@gmail.com>
 *         Jens Georg <jensg@openismus.com>
 *         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.1 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 library; 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 <gee.h>
#include <gio/gio.h>
#include <libtracker-sparql/tracker-sparql.h>


#define RYGEL_TRACKER_TYPE_METADATA_CONTAINER (rygel_tracker_metadata_container_get_type ())
#define RYGEL_TRACKER_METADATA_CONTAINER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), RYGEL_TRACKER_TYPE_METADATA_CONTAINER, RygelTrackerMetadataContainer))
#define RYGEL_TRACKER_METADATA_CONTAINER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), RYGEL_TRACKER_TYPE_METADATA_CONTAINER, RygelTrackerMetadataContainerClass))
#define RYGEL_TRACKER_IS_METADATA_CONTAINER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), RYGEL_TRACKER_TYPE_METADATA_CONTAINER))
#define RYGEL_TRACKER_IS_METADATA_CONTAINER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), RYGEL_TRACKER_TYPE_METADATA_CONTAINER))
#define RYGEL_TRACKER_METADATA_CONTAINER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), RYGEL_TRACKER_TYPE_METADATA_CONTAINER, RygelTrackerMetadataContainerClass))

typedef struct _RygelTrackerMetadataContainer RygelTrackerMetadataContainer;
typedef struct _RygelTrackerMetadataContainerClass RygelTrackerMetadataContainerClass;
typedef struct _RygelTrackerMetadataContainerPrivate RygelTrackerMetadataContainerPrivate;

#define RYGEL_TRACKER_TYPE_QUERY (rygel_tracker_query_get_type ())
#define RYGEL_TRACKER_QUERY(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), RYGEL_TRACKER_TYPE_QUERY, RygelTrackerQuery))
#define RYGEL_TRACKER_QUERY_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), RYGEL_TRACKER_TYPE_QUERY, RygelTrackerQueryClass))
#define RYGEL_TRACKER_IS_QUERY(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), RYGEL_TRACKER_TYPE_QUERY))
#define RYGEL_TRACKER_IS_QUERY_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), RYGEL_TRACKER_TYPE_QUERY))
#define RYGEL_TRACKER_QUERY_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), RYGEL_TRACKER_TYPE_QUERY, RygelTrackerQueryClass))

typedef struct _RygelTrackerQuery RygelTrackerQuery;
typedef struct _RygelTrackerQueryClass RygelTrackerQueryClass;

#define RYGEL_TRACKER_TYPE_SELECTION_QUERY (rygel_tracker_selection_query_get_type ())
#define RYGEL_TRACKER_SELECTION_QUERY(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), RYGEL_TRACKER_TYPE_SELECTION_QUERY, RygelTrackerSelectionQuery))
#define RYGEL_TRACKER_SELECTION_QUERY_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), RYGEL_TRACKER_TYPE_SELECTION_QUERY, RygelTrackerSelectionQueryClass))
#define RYGEL_TRACKER_IS_SELECTION_QUERY(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), RYGEL_TRACKER_TYPE_SELECTION_QUERY))
#define RYGEL_TRACKER_IS_SELECTION_QUERY_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), RYGEL_TRACKER_TYPE_SELECTION_QUERY))
#define RYGEL_TRACKER_SELECTION_QUERY_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), RYGEL_TRACKER_TYPE_SELECTION_QUERY, RygelTrackerSelectionQueryClass))

typedef struct _RygelTrackerSelectionQuery RygelTrackerSelectionQuery;
typedef struct _RygelTrackerSelectionQueryClass RygelTrackerSelectionQueryClass;

#define RYGEL_TRACKER_TYPE_SEARCH_CONTAINER (rygel_tracker_search_container_get_type ())
#define RYGEL_TRACKER_SEARCH_CONTAINER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), RYGEL_TRACKER_TYPE_SEARCH_CONTAINER, RygelTrackerSearchContainer))
#define RYGEL_TRACKER_SEARCH_CONTAINER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), RYGEL_TRACKER_TYPE_SEARCH_CONTAINER, RygelTrackerSearchContainerClass))
#define RYGEL_TRACKER_IS_SEARCH_CONTAINER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), RYGEL_TRACKER_TYPE_SEARCH_CONTAINER))
#define RYGEL_TRACKER_IS_SEARCH_CONTAINER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), RYGEL_TRACKER_TYPE_SEARCH_CONTAINER))
#define RYGEL_TRACKER_SEARCH_CONTAINER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), RYGEL_TRACKER_TYPE_SEARCH_CONTAINER, RygelTrackerSearchContainerClass))

typedef struct _RygelTrackerSearchContainer RygelTrackerSearchContainer;
typedef struct _RygelTrackerSearchContainerClass RygelTrackerSearchContainerClass;

#define RYGEL_TRACKER_TYPE_ITEM_FACTORY (rygel_tracker_item_factory_get_type ())
#define RYGEL_TRACKER_ITEM_FACTORY(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), RYGEL_TRACKER_TYPE_ITEM_FACTORY, RygelTrackerItemFactory))
#define RYGEL_TRACKER_ITEM_FACTORY_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), RYGEL_TRACKER_TYPE_ITEM_FACTORY, RygelTrackerItemFactoryClass))
#define RYGEL_TRACKER_IS_ITEM_FACTORY(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), RYGEL_TRACKER_TYPE_ITEM_FACTORY))
#define RYGEL_TRACKER_IS_ITEM_FACTORY_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), RYGEL_TRACKER_TYPE_ITEM_FACTORY))
#define RYGEL_TRACKER_ITEM_FACTORY_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), RYGEL_TRACKER_TYPE_ITEM_FACTORY, RygelTrackerItemFactoryClass))

typedef struct _RygelTrackerItemFactory RygelTrackerItemFactory;
typedef struct _RygelTrackerItemFactoryClass RygelTrackerItemFactoryClass;

#define RYGEL_TRACKER_TYPE_QUERY_TRIPLETS (rygel_tracker_query_triplets_get_type ())
#define RYGEL_TRACKER_QUERY_TRIPLETS(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), RYGEL_TRACKER_TYPE_QUERY_TRIPLETS, RygelTrackerQueryTriplets))
#define RYGEL_TRACKER_QUERY_TRIPLETS_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), RYGEL_TRACKER_TYPE_QUERY_TRIPLETS, RygelTrackerQueryTripletsClass))
#define RYGEL_TRACKER_IS_QUERY_TRIPLETS(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), RYGEL_TRACKER_TYPE_QUERY_TRIPLETS))
#define RYGEL_TRACKER_IS_QUERY_TRIPLETS_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), RYGEL_TRACKER_TYPE_QUERY_TRIPLETS))
#define RYGEL_TRACKER_QUERY_TRIPLETS_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), RYGEL_TRACKER_TYPE_QUERY_TRIPLETS, RygelTrackerQueryTripletsClass))

typedef struct _RygelTrackerQueryTriplets RygelTrackerQueryTriplets;
typedef struct _RygelTrackerQueryTripletsClass RygelTrackerQueryTripletsClass;

#define RYGEL_TRACKER_TYPE_METADATA_MULTI_VALUES (rygel_tracker_metadata_multi_values_get_type ())
#define RYGEL_TRACKER_METADATA_MULTI_VALUES(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), RYGEL_TRACKER_TYPE_METADATA_MULTI_VALUES, RygelTrackerMetadataMultiValues))
#define RYGEL_TRACKER_METADATA_MULTI_VALUES_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), RYGEL_TRACKER_TYPE_METADATA_MULTI_VALUES, RygelTrackerMetadataMultiValuesClass))
#define RYGEL_TRACKER_IS_METADATA_MULTI_VALUES(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), RYGEL_TRACKER_TYPE_METADATA_MULTI_VALUES))
#define RYGEL_TRACKER_IS_METADATA_MULTI_VALUES_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), RYGEL_TRACKER_TYPE_METADATA_MULTI_VALUES))
#define RYGEL_TRACKER_METADATA_MULTI_VALUES_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), RYGEL_TRACKER_TYPE_METADATA_MULTI_VALUES, RygelTrackerMetadataMultiValuesClass))

typedef struct _RygelTrackerMetadataMultiValues RygelTrackerMetadataMultiValues;
typedef struct _RygelTrackerMetadataMultiValuesClass RygelTrackerMetadataMultiValuesClass;
typedef struct _RygelTrackerMetadataMultiValuesPrivate RygelTrackerMetadataMultiValuesPrivate;
enum  {
	RYGEL_TRACKER_METADATA_MULTI_VALUES_0_PROPERTY,
	RYGEL_TRACKER_METADATA_MULTI_VALUES_NUM_PROPERTIES
};
static GParamSpec* rygel_tracker_metadata_multi_values_properties[RYGEL_TRACKER_METADATA_MULTI_VALUES_NUM_PROPERTIES];
#define _g_object_unref0(var) ((var == NULL) ? NULL : (var = (g_object_unref (var), NULL)))
typedef struct _RygelTrackerItemFactoryPrivate RygelTrackerItemFactoryPrivate;

#define RYGEL_TRACKER_TYPE_QUERY_TRIPLET (rygel_tracker_query_triplet_get_type ())
#define RYGEL_TRACKER_QUERY_TRIPLET(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), RYGEL_TRACKER_TYPE_QUERY_TRIPLET, RygelTrackerQueryTriplet))
#define RYGEL_TRACKER_QUERY_TRIPLET_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), RYGEL_TRACKER_TYPE_QUERY_TRIPLET, RygelTrackerQueryTripletClass))
#define RYGEL_TRACKER_IS_QUERY_TRIPLET(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), RYGEL_TRACKER_TYPE_QUERY_TRIPLET))
#define RYGEL_TRACKER_IS_QUERY_TRIPLET_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), RYGEL_TRACKER_TYPE_QUERY_TRIPLET))
#define RYGEL_TRACKER_QUERY_TRIPLET_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), RYGEL_TRACKER_TYPE_QUERY_TRIPLET, RygelTrackerQueryTripletClass))

typedef struct _RygelTrackerQueryTriplet RygelTrackerQueryTriplet;
typedef struct _RygelTrackerQueryTripletClass RygelTrackerQueryTripletClass;
#define _rygel_tracker_query_triplet_unref0(var) ((var == NULL) ? NULL : (var = (rygel_tracker_query_triplet_unref (var), NULL)))
#define _g_free0(var) (var = (g_free (var), NULL))
#define _g_regex_unref0(var) ((var == NULL) ? NULL : (var = (g_regex_unref (var), NULL)))
#define _g_error_free0(var) ((var == NULL) ? NULL : (var = (g_error_free (var), NULL)))
typedef struct _RygelTrackerQueryTripletPrivate RygelTrackerQueryTripletPrivate;

struct _RygelTrackerMetadataContainer {
	RygelSimpleContainer parent_instance;
	RygelTrackerMetadataContainerPrivate * priv;
	RygelTrackerItemFactory* item_factory;
	RygelTrackerQueryTriplets* triplets;
};

struct _RygelTrackerMetadataContainerClass {
	RygelSimpleContainerClass parent_class;
	RygelTrackerSelectionQuery* (*create_query) (RygelTrackerMetadataContainer* self);
	RygelTrackerSearchContainer* (*create_container) (RygelTrackerMetadataContainer* self, const gchar* id, const gchar* title, const gchar* value);
	gchar* (*create_id_for_title) (RygelTrackerMetadataContainer* self, const gchar* title);
	gchar* (*create_title_for_value) (RygelTrackerMetadataContainer* self, const gchar* value);
	gchar* (*create_filter) (RygelTrackerMetadataContainer* self, const gchar* variable, const gchar* value);
};

struct _RygelTrackerMetadataMultiValues {
	RygelTrackerMetadataContainer parent_instance;
	RygelTrackerMetadataMultiValuesPrivate * priv;
	gchar** key_chain;
	gint key_chain_length1;
};

struct _RygelTrackerMetadataMultiValuesClass {
	RygelTrackerMetadataContainerClass parent_class;
};

struct _RygelTrackerItemFactory {
	GTypeInstance parent_instance;
	volatile int ref_count;
	RygelTrackerItemFactoryPrivate * priv;
	gchar* category;
	gchar* category_iri;
	gchar* upnp_class;
	gchar* upload_dir;
	GeeArrayList* properties;
};

struct _RygelTrackerItemFactoryClass {
	GTypeClass parent_class;
	void (*finalize) (RygelTrackerItemFactory *self);
	RygelMediaFileItem* (*create) (RygelTrackerItemFactory* self, const gchar* id, const gchar* uri, RygelTrackerSearchContainer* parent, TrackerSparqlCursor* metadata, GError** error);
	void (*set_metadata) (RygelTrackerItemFactory* self, RygelMediaFileItem* item, const gchar* uri, TrackerSparqlCursor* metadata, GError** error);
	void (*add_resources) (RygelTrackerItemFactory* self, RygelMediaFileItem* item, GError** error);
};

struct _RygelTrackerQueryTriplet {
	GTypeInstance parent_instance;
	volatile int ref_count;
	RygelTrackerQueryTripletPrivate * priv;
	gchar* graph;
	gchar* subject;
	gchar* predicate;
	gchar* obj;
	RygelTrackerQueryTriplet* next;
};

struct _RygelTrackerQueryTripletClass {
	GTypeClass parent_class;
	void (*finalize) (RygelTrackerQueryTriplet *self);
};


static gpointer rygel_tracker_metadata_multi_values_parent_class = NULL;

GType rygel_tracker_metadata_container_get_type (void) G_GNUC_CONST;
gpointer rygel_tracker_query_ref (gpointer instance);
void rygel_tracker_query_unref (gpointer instance);
GParamSpec* rygel_tracker_param_spec_query (const gchar* name,
                                            const gchar* nick,
                                            const gchar* blurb,
                                            GType object_type,
                                            GParamFlags flags);
void rygel_tracker_value_set_query (GValue* value,
                                    gpointer v_object);
void rygel_tracker_value_take_query (GValue* value,
                                     gpointer v_object);
gpointer rygel_tracker_value_get_query (const GValue* value);
GType rygel_tracker_query_get_type (void) G_GNUC_CONST;
GType rygel_tracker_selection_query_get_type (void) G_GNUC_CONST;
GType rygel_tracker_search_container_get_type (void) G_GNUC_CONST;
gpointer rygel_tracker_item_factory_ref (gpointer instance);
void rygel_tracker_item_factory_unref (gpointer instance);
GParamSpec* rygel_tracker_param_spec_item_factory (const gchar* name,
                                                   const gchar* nick,
                                                   const gchar* blurb,
                                                   GType object_type,
                                                   GParamFlags flags);
void rygel_tracker_value_set_item_factory (GValue* value,
                                           gpointer v_object);
void rygel_tracker_value_take_item_factory (GValue* value,
                                            gpointer v_object);
gpointer rygel_tracker_value_get_item_factory (const GValue* value);
GType rygel_tracker_item_factory_get_type (void) G_GNUC_CONST;
GType rygel_tracker_query_triplets_get_type (void) G_GNUC_CONST;
GType rygel_tracker_metadata_multi_values_get_type (void) G_GNUC_CONST;
RygelTrackerMetadataMultiValues* rygel_tracker_metadata_multi_values_construct (GType object_type,
                                                                                const gchar* id,
                                                                                RygelMediaContainer* parent,
                                                                                const gchar* title,
                                                                                RygelTrackerItemFactory* item_factory,
                                                                                gchar** key_chain,
                                                                                int key_chain_length1,
                                                                                const gchar* child_class);
RygelTrackerMetadataContainer* rygel_tracker_metadata_container_construct (GType object_type,
                                                                           const gchar* id,
                                                                           RygelMediaContainer* parent,
                                                                           const gchar* title,
                                                                           RygelTrackerItemFactory* item_factory,
                                                                           const gchar* child_class);
static gchar** _vala_array_dup1 (gchar** self,
                          int length);
void rygel_tracker_metadata_container_fetch_metadata_values (RygelTrackerMetadataContainer* self,
                                                             GAsyncReadyCallback _callback_,
                                                             gpointer _user_data_);
void rygel_tracker_metadata_container_fetch_metadata_values_finish (RygelTrackerMetadataContainer* self,
                                                                    GAsyncResult* _res_);
static RygelTrackerSelectionQuery* rygel_tracker_metadata_multi_values_real_create_query (RygelTrackerMetadataContainer* base);
RygelTrackerQueryTriplets* rygel_tracker_query_triplets_new (void);
RygelTrackerQueryTriplets* rygel_tracker_query_triplets_construct (GType object_type);
#define RYGEL_TRACKER_SELECTION_QUERY_ITEM_VARIABLE "?item"
RygelTrackerQueryTriplet* rygel_tracker_query_triplet_new (const gchar* subject,
                                                           const gchar* predicate,
                                                           const gchar* obj);
RygelTrackerQueryTriplet* rygel_tracker_query_triplet_construct (GType object_type,
                                                                 const gchar* subject,
                                                                 const gchar* predicate,
                                                                 const gchar* obj);
gpointer rygel_tracker_query_triplet_ref (gpointer instance);
void rygel_tracker_query_triplet_unref (gpointer instance);
GParamSpec* rygel_tracker_param_spec_query_triplet (const gchar* name,
                                                    const gchar* nick,
                                                    const gchar* blurb,
                                                    GType object_type,
                                                    GParamFlags flags);
void rygel_tracker_value_set_query_triplet (GValue* value,
                                            gpointer v_object);
void rygel_tracker_value_take_query_triplet (GValue* value,
                                             gpointer v_object);
gpointer rygel_tracker_value_get_query_triplet (const GValue* value);
GType rygel_tracker_query_triplet_get_type (void) G_GNUC_CONST;
RygelTrackerSelectionQuery* rygel_tracker_selection_query_new (GeeArrayList* variables,
                                                               RygelTrackerQueryTriplets* triplets,
                                                               GeeArrayList* filters,
                                                               const gchar* order_by,
                                                               gint offset,
                                                               gint max_count);
RygelTrackerSelectionQuery* rygel_tracker_selection_query_construct (GType object_type,
                                                                     GeeArrayList* variables,
                                                                     RygelTrackerQueryTriplets* triplets,
                                                                     GeeArrayList* filters,
                                                                     const gchar* order_by,
                                                                     gint offset,
                                                                     gint max_count);
static RygelTrackerSearchContainer* rygel_tracker_metadata_multi_values_real_create_container (RygelTrackerMetadataContainer* base,
                                                                                        const gchar* id,
                                                                                        const gchar* title,
                                                                                        const gchar* value);
RygelTrackerQueryTriplets* rygel_tracker_query_triplets_new_clone (RygelTrackerQueryTriplets* triplets);
RygelTrackerQueryTriplets* rygel_tracker_query_triplets_construct_clone (GType object_type,
                                                                         RygelTrackerQueryTriplets* triplets);
gchar* rygel_tracker_metadata_container_create_filter (RygelTrackerMetadataContainer* self,
                                                       const gchar* variable,
                                                       const gchar* value);
RygelTrackerSearchContainer* rygel_tracker_search_container_new (const gchar* id,
                                                                 RygelMediaContainer* parent,
                                                                 const gchar* title,
                                                                 RygelTrackerItemFactory* item_factory,
                                                                 RygelTrackerQueryTriplets* triplets,
                                                                 GeeArrayList* filters);
RygelTrackerSearchContainer* rygel_tracker_search_container_construct (GType object_type,
                                                                       const gchar* id,
                                                                       RygelMediaContainer* parent,
                                                                       const gchar* title,
                                                                       RygelTrackerItemFactory* item_factory,
                                                                       RygelTrackerQueryTriplets* triplets,
                                                                       GeeArrayList* filters);
static void rygel_tracker_metadata_multi_values_finalize (GObject * obj);
static void _vala_array_destroy (gpointer array,
                          gint array_length,
                          GDestroyNotify destroy_func);
static void _vala_array_free (gpointer array,
                       gint array_length,
                       GDestroyNotify destroy_func);


static gchar**
_vala_array_dup1 (gchar** self,
                  int length)
{
	gchar** result;
	int i;
	result = g_new0 (gchar*, length + 1);
	for (i = 0; i < length; i++) {
		gchar* _tmp0_;
		_tmp0_ = g_strdup (self[i]);
		result[i] = _tmp0_;
	}
	return result;
}


RygelTrackerMetadataMultiValues*
rygel_tracker_metadata_multi_values_construct (GType object_type,
                                               const gchar* id,
                                               RygelMediaContainer* parent,
                                               const gchar* title,
                                               RygelTrackerItemFactory* item_factory,
                                               gchar** key_chain,
                                               int key_chain_length1,
                                               const gchar* child_class)
{
	RygelTrackerMetadataMultiValues * self = NULL;
	gchar** _tmp0_;
	gint _tmp0__length1;
	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 (item_factory != NULL, NULL);
	self = (RygelTrackerMetadataMultiValues*) rygel_tracker_metadata_container_construct (object_type, id, parent, title, item_factory, child_class);
	_tmp0_ = (key_chain != NULL) ? _vala_array_dup1 (key_chain, key_chain_length1) : ((gpointer) key_chain);
	_tmp0__length1 = key_chain_length1;
	self->key_chain = (_vala_array_free (self->key_chain, self->key_chain_length1, (GDestroyNotify) g_free), NULL);
	self->key_chain = _tmp0_;
	self->key_chain_length1 = _tmp0__length1;
	rygel_tracker_metadata_container_fetch_metadata_values ((RygelTrackerMetadataContainer*) self, NULL, NULL);
	return self;
}


static gchar*
string_replace (const gchar* self,
                const gchar* old,
                const gchar* replacement)
{
	gchar* result = NULL;
	gboolean _tmp0_ = FALSE;
	gboolean _tmp1_ = FALSE;
	GError * _inner_error_ = NULL;
	g_return_val_if_fail (self != NULL, NULL);
	g_return_val_if_fail (old != NULL, NULL);
	g_return_val_if_fail (replacement != NULL, NULL);
	if ((*((gchar*) self)) == '\0') {
		_tmp1_ = TRUE;
	} else {
		_tmp1_ = (*((gchar*) old)) == '\0';
	}
	if (_tmp1_) {
		_tmp0_ = TRUE;
	} else {
		_tmp0_ = g_strcmp0 (old, replacement) == 0;
	}
	if (_tmp0_) {
		gchar* _tmp2_;
		_tmp2_ = g_strdup (self);
		result = _tmp2_;
		return result;
	}
	{
		GRegex* regex = NULL;
		gchar* _tmp3_;
		gchar* _tmp4_;
		GRegex* _tmp5_;
		GRegex* _tmp6_;
		gchar* _tmp7_ = NULL;
		GRegex* _tmp8_;
		gchar* _tmp9_;
		gchar* _tmp10_;
		_tmp3_ = g_regex_escape_string (old, -1);
		_tmp4_ = _tmp3_;
		_tmp5_ = g_regex_new (_tmp4_, 0, 0, &_inner_error_);
		_tmp6_ = _tmp5_;
		_g_free0 (_tmp4_);
		regex = _tmp6_;
		if (G_UNLIKELY (_inner_error_ != NULL)) {
			if (_inner_error_->domain == G_REGEX_ERROR) {
				goto __catch3_g_regex_error;
			}
			g_critical ("file %s: line %d: unexpected error: %s (%s, %d)", __FILE__, __LINE__, _inner_error_->message, g_quark_to_string (_inner_error_->domain), _inner_error_->code);
			g_clear_error (&_inner_error_);
			return NULL;
		}
		_tmp8_ = regex;
		_tmp9_ = g_regex_replace_literal (_tmp8_, self, (gssize) -1, 0, replacement, 0, &_inner_error_);
		_tmp7_ = _tmp9_;
		if (G_UNLIKELY (_inner_error_ != NULL)) {
			_g_regex_unref0 (regex);
			if (_inner_error_->domain == G_REGEX_ERROR) {
				goto __catch3_g_regex_error;
			}
			_g_regex_unref0 (regex);
			g_critical ("file %s: line %d: unexpected error: %s (%s, %d)", __FILE__, __LINE__, _inner_error_->message, g_quark_to_string (_inner_error_->domain), _inner_error_->code);
			g_clear_error (&_inner_error_);
			return NULL;
		}
		_tmp10_ = _tmp7_;
		_tmp7_ = NULL;
		result = _tmp10_;
		_g_free0 (_tmp7_);
		_g_regex_unref0 (regex);
		return result;
	}
	goto __finally3;
	__catch3_g_regex_error:
	{
		GError* e = NULL;
		e = _inner_error_;
		_inner_error_ = NULL;
		g_assert_not_reached ();
		_g_error_free0 (e);
	}
	__finally3:
	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 NULL;
	}
}


static RygelTrackerSelectionQuery*
rygel_tracker_metadata_multi_values_real_create_query (RygelTrackerMetadataContainer* base)
{
	RygelTrackerMetadataMultiValues * self;
	RygelTrackerSelectionQuery* result = NULL;
	RygelTrackerQueryTriplets* _tmp0_;
	RygelTrackerQueryTriplets* _tmp1_;
	RygelTrackerItemFactory* _tmp2_;
	const gchar* _tmp3_;
	RygelTrackerQueryTriplet* _tmp4_;
	RygelTrackerQueryTriplet* _tmp5_;
	gint num_keys = 0;
	gchar** _tmp6_;
	gint _tmp6__length1;
	gchar** variables = NULL;
	gint _tmp7_;
	gchar** _tmp8_;
	gint variables_length1;
	gint _variables_size_;
	GeeArrayList* selected = NULL;
	GeeArrayList* _tmp38_;
	gchar* last_variable = NULL;
	gchar** _tmp39_;
	gint _tmp39__length1;
	gint _tmp40_;
	const gchar* _tmp41_;
	gchar* _tmp42_;
	gchar* _tmp43_;
	gchar* _tmp44_;
	RygelTrackerQueryTriplets* _tmp45_;
	RygelTrackerSelectionQuery* _tmp46_;
	self = (RygelTrackerMetadataMultiValues*) base;
	_tmp0_ = rygel_tracker_query_triplets_new ();
	_g_object_unref0 (((RygelTrackerMetadataContainer*) self)->triplets);
	((RygelTrackerMetadataContainer*) self)->triplets = _tmp0_;
	_tmp1_ = ((RygelTrackerMetadataContainer*) self)->triplets;
	_tmp2_ = ((RygelTrackerMetadataContainer*) self)->item_factory;
	_tmp3_ = _tmp2_->category;
	_tmp4_ = rygel_tracker_query_triplet_new (RYGEL_TRACKER_SELECTION_QUERY_ITEM_VARIABLE, "a", _tmp3_);
	_tmp5_ = _tmp4_;
	gee_abstract_collection_add ((GeeAbstractCollection*) _tmp1_, _tmp5_);
	_rygel_tracker_query_triplet_unref0 (_tmp5_);
	_tmp6_ = self->key_chain;
	_tmp6__length1 = self->key_chain_length1;
	num_keys = _tmp6__length1 - 1;
	_tmp7_ = num_keys;
	_tmp8_ = g_new0 (gchar*, _tmp7_ + 1);
	variables = _tmp8_;
	variables_length1 = _tmp7_;
	_variables_size_ = variables_length1;
	{
		gint i = 0;
		i = 0;
		{
			gboolean _tmp9_ = FALSE;
			_tmp9_ = TRUE;
			while (TRUE) {
				gint _tmp11_;
				gint _tmp12_;
				gchar** _tmp13_;
				gint _tmp13__length1;
				gint _tmp14_;
				gchar** _tmp15_;
				gint _tmp15__length1;
				gint _tmp16_;
				const gchar* _tmp17_;
				gchar* _tmp18_;
				gchar* _tmp19_;
				gchar* _tmp20_;
				gchar* _tmp21_;
				gchar* subject = NULL;
				gint _tmp22_;
				RygelTrackerQueryTriplets* _tmp28_;
				const gchar* _tmp29_;
				gchar** _tmp30_;
				gint _tmp30__length1;
				gint _tmp31_;
				const gchar* _tmp32_;
				gchar** _tmp33_;
				gint _tmp33__length1;
				gint _tmp34_;
				const gchar* _tmp35_;
				RygelTrackerQueryTriplet* _tmp36_;
				RygelTrackerQueryTriplet* _tmp37_;
				if (!_tmp9_) {
					gint _tmp10_;
					_tmp10_ = i;
					i = _tmp10_ + 1;
				}
				_tmp9_ = FALSE;
				_tmp11_ = i;
				_tmp12_ = num_keys;
				if (!(_tmp11_ < _tmp12_)) {
					break;
				}
				_tmp13_ = variables;
				_tmp13__length1 = variables_length1;
				_tmp14_ = i;
				_tmp15_ = self->key_chain;
				_tmp15__length1 = self->key_chain_length1;
				_tmp16_ = i;
				_tmp17_ = _tmp15_[_tmp16_];
				_tmp18_ = string_replace (_tmp17_, ":", "_");
				_tmp19_ = _tmp18_;
				_tmp20_ = g_strconcat ("?", _tmp19_, NULL);
				_g_free0 (_tmp13_[_tmp14_]);
				_tmp13_[_tmp14_] = _tmp20_;
				_tmp21_ = _tmp13_[_tmp14_];
				_g_free0 (_tmp19_);
				_tmp22_ = i;
				if (_tmp22_ == 0) {
					gchar* _tmp23_;
					_tmp23_ = g_strdup (RYGEL_TRACKER_SELECTION_QUERY_ITEM_VARIABLE);
					_g_free0 (subject);
					subject = _tmp23_;
				} else {
					gchar** _tmp24_;
					gint _tmp24__length1;
					gint _tmp25_;
					const gchar* _tmp26_;
					gchar* _tmp27_;
					_tmp24_ = variables;
					_tmp24__length1 = variables_length1;
					_tmp25_ = i;
					_tmp26_ = _tmp24_[_tmp25_ - 1];
					_tmp27_ = g_strdup (_tmp26_);
					_g_free0 (subject);
					subject = _tmp27_;
				}
				_tmp28_ = ((RygelTrackerMetadataContainer*) self)->triplets;
				_tmp29_ = subject;
				_tmp30_ = self->key_chain;
				_tmp30__length1 = self->key_chain_length1;
				_tmp31_ = i;
				_tmp32_ = _tmp30_[_tmp31_];
				_tmp33_ = variables;
				_tmp33__length1 = variables_length1;
				_tmp34_ = i;
				_tmp35_ = _tmp33_[_tmp34_];
				_tmp36_ = rygel_tracker_query_triplet_new (_tmp29_, _tmp32_, _tmp35_);
				_tmp37_ = _tmp36_;
				gee_abstract_collection_add ((GeeAbstractCollection*) _tmp28_, _tmp37_);
				_rygel_tracker_query_triplet_unref0 (_tmp37_);
				_g_free0 (subject);
			}
		}
	}
	_tmp38_ = gee_array_list_new (G_TYPE_STRING, (GBoxedCopyFunc) g_strdup, (GDestroyNotify) g_free, NULL, NULL, NULL);
	selected = _tmp38_;
	_tmp39_ = variables;
	_tmp39__length1 = variables_length1;
	_tmp40_ = num_keys;
	_tmp41_ = _tmp39_[_tmp40_ - 1];
	_tmp42_ = g_strdup (_tmp41_);
	last_variable = _tmp42_;
	_tmp43_ = g_strconcat ("DISTINCT ", last_variable, NULL);
	_tmp44_ = _tmp43_;
	gee_abstract_collection_add ((GeeAbstractCollection*) selected, _tmp44_);
	_g_free0 (_tmp44_);
	_tmp45_ = ((RygelTrackerMetadataContainer*) self)->triplets;
	_tmp46_ = rygel_tracker_selection_query_new (selected, _tmp45_, NULL, last_variable, 0, -1);
	result = _tmp46_;
	_g_free0 (last_variable);
	_g_object_unref0 (selected);
	variables = (_vala_array_free (variables, variables_length1, (GDestroyNotify) g_free), NULL);
	return result;
}


static RygelTrackerSearchContainer*
rygel_tracker_metadata_multi_values_real_create_container (RygelTrackerMetadataContainer* base,
                                                           const gchar* id,
                                                           const gchar* title,
                                                           const gchar* value)
{
	RygelTrackerMetadataMultiValues * self;
	RygelTrackerSearchContainer* result = NULL;
	RygelTrackerQueryTriplets* child_triplets = NULL;
	RygelTrackerQueryTriplets* _tmp0_;
	RygelTrackerQueryTriplets* _tmp1_;
	GeeArrayList* filters = NULL;
	GeeArrayList* _tmp2_;
	gchar* filter = NULL;
	gpointer _tmp3_;
	RygelTrackerQueryTriplet* _tmp4_;
	const gchar* _tmp5_;
	gchar* _tmp6_;
	gchar* _tmp7_;
	RygelTrackerItemFactory* _tmp8_;
	RygelTrackerSearchContainer* _tmp9_;
	self = (RygelTrackerMetadataMultiValues*) base;
	g_return_val_if_fail (id != NULL, NULL);
	g_return_val_if_fail (title != NULL, NULL);
	g_return_val_if_fail (value != NULL, NULL);
	_tmp0_ = ((RygelTrackerMetadataContainer*) self)->triplets;
	_tmp1_ = rygel_tracker_query_triplets_new_clone (_tmp0_);
	child_triplets = _tmp1_;
	_tmp2_ = gee_array_list_new (G_TYPE_STRING, (GBoxedCopyFunc) g_strdup, (GDestroyNotify) g_free, NULL, NULL, NULL);
	filters = _tmp2_;
	_tmp3_ = gee_list_last ((GeeList*) child_triplets);
	_tmp4_ = (RygelTrackerQueryTriplet*) _tmp3_;
	_tmp5_ = _tmp4_->obj;
	_tmp6_ = rygel_tracker_metadata_container_create_filter ((RygelTrackerMetadataContainer*) self, _tmp5_, value);
	_tmp7_ = _tmp6_;
	_rygel_tracker_query_triplet_unref0 (_tmp4_);
	filter = _tmp7_;
	gee_abstract_collection_add ((GeeAbstractCollection*) filters, filter);
	_tmp8_ = ((RygelTrackerMetadataContainer*) self)->item_factory;
	_tmp9_ = rygel_tracker_search_container_new (id, (RygelMediaContainer*) self, title, _tmp8_, child_triplets, filters);
	result = _tmp9_;
	_g_free0 (filter);
	_g_object_unref0 (filters);
	_g_object_unref0 (child_triplets);
	return result;
}


static void
rygel_tracker_metadata_multi_values_class_init (RygelTrackerMetadataMultiValuesClass * klass)
{
	rygel_tracker_metadata_multi_values_parent_class = g_type_class_peek_parent (klass);
	((RygelTrackerMetadataContainerClass *) klass)->create_query = (RygelTrackerSelectionQuery* (*) (RygelTrackerMetadataContainer *)) rygel_tracker_metadata_multi_values_real_create_query;
	((RygelTrackerMetadataContainerClass *) klass)->create_container = (RygelTrackerSearchContainer* (*) (RygelTrackerMetadataContainer *, const gchar*, const gchar*, const gchar*)) rygel_tracker_metadata_multi_values_real_create_container;
	G_OBJECT_CLASS (klass)->finalize = rygel_tracker_metadata_multi_values_finalize;
}


static void
rygel_tracker_metadata_multi_values_instance_init (RygelTrackerMetadataMultiValues * self)
{
}


static void
rygel_tracker_metadata_multi_values_finalize (GObject * obj)
{
	RygelTrackerMetadataMultiValues * self;
	self = G_TYPE_CHECK_INSTANCE_CAST (obj, RYGEL_TRACKER_TYPE_METADATA_MULTI_VALUES, RygelTrackerMetadataMultiValues);
	self->key_chain = (_vala_array_free (self->key_chain, self->key_chain_length1, (GDestroyNotify) g_free), NULL);
	G_OBJECT_CLASS (rygel_tracker_metadata_multi_values_parent_class)->finalize (obj);
}


/**
 * Container listing possible values of a particuler Tracker metadata key.
 * This class is used for multivalue properties such as nao:Tag (via
 * nao:hasTag)
 */
GType
rygel_tracker_metadata_multi_values_get_type (void)
{
	static volatile gsize rygel_tracker_metadata_multi_values_type_id__volatile = 0;
	if (g_once_init_enter (&rygel_tracker_metadata_multi_values_type_id__volatile)) {
		static const GTypeInfo g_define_type_info = { sizeof (RygelTrackerMetadataMultiValuesClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) rygel_tracker_metadata_multi_values_class_init, (GClassFinalizeFunc) NULL, NULL, sizeof (RygelTrackerMetadataMultiValues), 0, (GInstanceInitFunc) rygel_tracker_metadata_multi_values_instance_init, NULL };
		GType rygel_tracker_metadata_multi_values_type_id;
		rygel_tracker_metadata_multi_values_type_id = g_type_register_static (RYGEL_TRACKER_TYPE_METADATA_CONTAINER, "RygelTrackerMetadataMultiValues", &g_define_type_info, G_TYPE_FLAG_ABSTRACT);
		g_once_init_leave (&rygel_tracker_metadata_multi_values_type_id__volatile, rygel_tracker_metadata_multi_values_type_id);
	}
	return rygel_tracker_metadata_multi_values_type_id__volatile;
}


static void
_vala_array_destroy (gpointer array,
                     gint array_length,
                     GDestroyNotify destroy_func)
{
	if ((array != NULL) && (destroy_func != NULL)) {
		int i;
		for (i = 0; i < array_length; i = i + 1) {
			if (((gpointer*) array)[i] != NULL) {
				destroy_func (((gpointer*) array)[i]);
			}
		}
	}
}


static void
_vala_array_free (gpointer array,
                  gint array_length,
                  GDestroyNotify destroy_func)
{
	_vala_array_destroy (array, array_length, destroy_func);
	g_free (array);
}



