/* rygel-tracker-upnp-property-map.c generated by valac 0.56.1, the Vala compiler
 * generated from rygel-tracker-upnp-property-map.vala, do not modify */

/*
 * Copyright (C) 2010 MediaNet Inh.
 * Copyright (C) 2012 Jens Georg <mail@jensge.org>
 *
 * Author: Sunil Mohan Adapa <sunil@medhas.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-object.h>
#include <stdlib.h>
#include <string.h>
#include <glib.h>
#include <gobject/gvaluecollector.h>
#include "rygel-tracker3.h"
#include <gee.h>
#include <stdarg.h>

#define RYGEL_TRACKER_TYPE_QUERY_VARIABLE (rygel_tracker_query_variable_get_type ())
#define RYGEL_TRACKER_QUERY_VARIABLE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), RYGEL_TRACKER_TYPE_QUERY_VARIABLE, RygelTrackerQueryVariable))
#define RYGEL_TRACKER_QUERY_VARIABLE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), RYGEL_TRACKER_TYPE_QUERY_VARIABLE, RygelTrackerQueryVariableClass))
#define RYGEL_TRACKER_IS_QUERY_VARIABLE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), RYGEL_TRACKER_TYPE_QUERY_VARIABLE))
#define RYGEL_TRACKER_IS_QUERY_VARIABLE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), RYGEL_TRACKER_TYPE_QUERY_VARIABLE))
#define RYGEL_TRACKER_QUERY_VARIABLE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), RYGEL_TRACKER_TYPE_QUERY_VARIABLE, RygelTrackerQueryVariableClass))

typedef struct _RygelTrackerQueryVariable RygelTrackerQueryVariable;
typedef struct _RygelTrackerQueryVariableClass RygelTrackerQueryVariableClass;
typedef struct _RygelTrackerQueryVariablePrivate RygelTrackerQueryVariablePrivate;
#define _g_free0(var) (var = (g_free (var), NULL))
typedef struct _RygelTrackerParamSpecQueryVariable RygelTrackerParamSpecQueryVariable;
enum  {
	RYGEL_TRACKER_UPN_PPROPERTY_MAP_0_PROPERTY,
	RYGEL_TRACKER_UPN_PPROPERTY_MAP_NUM_PROPERTIES
};
static GParamSpec* rygel_tracker_upn_pproperty_map_properties[RYGEL_TRACKER_UPN_PPROPERTY_MAP_NUM_PROPERTIES];
#define _g_object_unref0(var) ((var == NULL) ? NULL : (var = (g_object_unref (var), NULL)))
#define _rygel_tracker_query_variable_unref0(var) ((var == NULL) ? NULL : (var = (rygel_tracker_query_variable_unref (var), NULL)))
#define _g_string_free0(var) ((var == NULL) ? NULL : (var = (g_string_free (var, TRUE), NULL)))

struct _RygelTrackerQueryVariable {
	GTypeInstance parent_instance;
	volatile int ref_count;
	RygelTrackerQueryVariablePrivate * priv;
	gchar* base_variable;
	gchar* alias;
};

struct _RygelTrackerQueryVariableClass {
	GTypeClass parent_class;
	void (*finalize) (RygelTrackerQueryVariable *self);
};

struct _RygelTrackerParamSpecQueryVariable {
	GParamSpec parent_instance;
};

struct _RygelTrackerUPnPPropertyMapPrivate {
	GeeHashMap* property_map;
	GeeHashMap* functions;
	GeeHashMap* variables;
};

static gpointer rygel_tracker_query_variable_parent_class = NULL;
static gint RygelTrackerUPnPPropertyMap_private_offset;
static gpointer rygel_tracker_upn_pproperty_map_parent_class = NULL;
static RygelTrackerUPnPPropertyMap* rygel_tracker_upn_pproperty_map_instance;
static RygelTrackerUPnPPropertyMap* rygel_tracker_upn_pproperty_map_instance = NULL;

VALA_EXTERN gpointer rygel_tracker_query_variable_ref (gpointer instance);
VALA_EXTERN void rygel_tracker_query_variable_unref (gpointer instance);
VALA_EXTERN GParamSpec* rygel_tracker_param_spec_query_variable (const gchar* name,
                                                     const gchar* nick,
                                                     const gchar* blurb,
                                                     GType object_type,
                                                     GParamFlags flags);
VALA_EXTERN void rygel_tracker_value_set_query_variable (GValue* value,
                                             gpointer v_object);
VALA_EXTERN void rygel_tracker_value_take_query_variable (GValue* value,
                                              gpointer v_object);
VALA_EXTERN gpointer rygel_tracker_value_get_query_variable (const GValue* value);
VALA_EXTERN GType rygel_tracker_query_variable_get_type (void) G_GNUC_CONST ;
VALA_EXTERN RygelTrackerQueryVariable* rygel_tracker_query_variable_new (const gchar* base_variable,
                                                             const gchar* alias);
VALA_EXTERN RygelTrackerQueryVariable* rygel_tracker_query_variable_construct (GType object_type,
                                                                   const gchar* base_variable,
                                                                   const gchar* alias);
static void rygel_tracker_query_variable_finalize (RygelTrackerQueryVariable * obj);
static GType rygel_tracker_query_variable_get_type_once (void);
static RygelTrackerUPnPPropertyMap* rygel_tracker_upn_pproperty_map_new (void);
static RygelTrackerUPnPPropertyMap* rygel_tracker_upn_pproperty_map_construct (GType object_type);
static void rygel_tracker_upn_pproperty_map_add_variable (RygelTrackerUPnPPropertyMap* self,
                                                   const gchar* property,
                                                   const gchar* base_item,
                                                   const gchar* alias);
static void rygel_tracker_upn_pproperty_map_add_key_chain (RygelTrackerUPnPPropertyMap* self,
                                                    const gchar* property,
                                                    ...);
static void rygel_tracker_upn_pproperty_map_add_function (RygelTrackerUPnPPropertyMap* self,
                                                   const gchar* property,
                                                   const gchar* function);
static void rygel_tracker_upn_pproperty_map_add_alternative (RygelTrackerUPnPPropertyMap* self,
                                                      const gchar* property,
                                                      ...);
static void rygel_tracker_upn_pproperty_map_finalize (GObject * obj);
static GType rygel_tracker_upn_pproperty_map_get_type_once (void);

RygelTrackerQueryVariable*
rygel_tracker_query_variable_construct (GType object_type,
                                        const gchar* base_variable,
                                        const gchar* alias)
{
	RygelTrackerQueryVariable* self = NULL;
	gchar* _tmp0_;
	gchar* _tmp1_;
	g_return_val_if_fail (base_variable != NULL, NULL);
	g_return_val_if_fail (alias != NULL, NULL);
	self = (RygelTrackerQueryVariable*) g_type_create_instance (object_type);
	_tmp0_ = g_strdup (base_variable);
	_g_free0 (self->base_variable);
	self->base_variable = _tmp0_;
	_tmp1_ = g_strdup (alias);
	_g_free0 (self->alias);
	self->alias = _tmp1_;
	return self;
}

RygelTrackerQueryVariable*
rygel_tracker_query_variable_new (const gchar* base_variable,
                                  const gchar* alias)
{
	return rygel_tracker_query_variable_construct (RYGEL_TRACKER_TYPE_QUERY_VARIABLE, base_variable, alias);
}

static void
rygel_tracker_value_query_variable_init (GValue* value)
{
	value->data[0].v_pointer = NULL;
}

static void
rygel_tracker_value_query_variable_free_value (GValue* value)
{
	if (value->data[0].v_pointer) {
		rygel_tracker_query_variable_unref (value->data[0].v_pointer);
	}
}

static void
rygel_tracker_value_query_variable_copy_value (const GValue* src_value,
                                               GValue* dest_value)
{
	if (src_value->data[0].v_pointer) {
		dest_value->data[0].v_pointer = rygel_tracker_query_variable_ref (src_value->data[0].v_pointer);
	} else {
		dest_value->data[0].v_pointer = NULL;
	}
}

static gpointer
rygel_tracker_value_query_variable_peek_pointer (const GValue* value)
{
	return value->data[0].v_pointer;
}

static gchar*
rygel_tracker_value_query_variable_collect_value (GValue* value,
                                                  guint n_collect_values,
                                                  GTypeCValue* collect_values,
                                                  guint collect_flags)
{
	if (collect_values[0].v_pointer) {
		RygelTrackerQueryVariable * 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_tracker_query_variable_ref (object);
	} else {
		value->data[0].v_pointer = NULL;
	}
	return NULL;
}

static gchar*
rygel_tracker_value_query_variable_lcopy_value (const GValue* value,
                                                guint n_collect_values,
                                                GTypeCValue* collect_values,
                                                guint collect_flags)
{
	RygelTrackerQueryVariable ** 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_tracker_query_variable_ref (value->data[0].v_pointer);
	}
	return NULL;
}

GParamSpec*
rygel_tracker_param_spec_query_variable (const gchar* name,
                                         const gchar* nick,
                                         const gchar* blurb,
                                         GType object_type,
                                         GParamFlags flags)
{
	RygelTrackerParamSpecQueryVariable* spec;
	g_return_val_if_fail (g_type_is_a (object_type, RYGEL_TRACKER_TYPE_QUERY_VARIABLE), 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_tracker_value_get_query_variable (const GValue* value)
{
	g_return_val_if_fail (G_TYPE_CHECK_VALUE_TYPE (value, RYGEL_TRACKER_TYPE_QUERY_VARIABLE), NULL);
	return value->data[0].v_pointer;
}

void
rygel_tracker_value_set_query_variable (GValue* value,
                                        gpointer v_object)
{
	RygelTrackerQueryVariable * old;
	g_return_if_fail (G_TYPE_CHECK_VALUE_TYPE (value, RYGEL_TRACKER_TYPE_QUERY_VARIABLE));
	old = value->data[0].v_pointer;
	if (v_object) {
		g_return_if_fail (G_TYPE_CHECK_INSTANCE_TYPE (v_object, RYGEL_TRACKER_TYPE_QUERY_VARIABLE));
		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_tracker_query_variable_ref (value->data[0].v_pointer);
	} else {
		value->data[0].v_pointer = NULL;
	}
	if (old) {
		rygel_tracker_query_variable_unref (old);
	}
}

void
rygel_tracker_value_take_query_variable (GValue* value,
                                         gpointer v_object)
{
	RygelTrackerQueryVariable * old;
	g_return_if_fail (G_TYPE_CHECK_VALUE_TYPE (value, RYGEL_TRACKER_TYPE_QUERY_VARIABLE));
	old = value->data[0].v_pointer;
	if (v_object) {
		g_return_if_fail (G_TYPE_CHECK_INSTANCE_TYPE (v_object, RYGEL_TRACKER_TYPE_QUERY_VARIABLE));
		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_tracker_query_variable_unref (old);
	}
}

static void
rygel_tracker_query_variable_class_init (RygelTrackerQueryVariableClass * klass,
                                         gpointer klass_data)
{
	rygel_tracker_query_variable_parent_class = g_type_class_peek_parent (klass);
	((RygelTrackerQueryVariableClass *) klass)->finalize = rygel_tracker_query_variable_finalize;
}

static void
rygel_tracker_query_variable_instance_init (RygelTrackerQueryVariable * self,
                                            gpointer klass)
{
	self->ref_count = 1;
}

static void
rygel_tracker_query_variable_finalize (RygelTrackerQueryVariable * obj)
{
	RygelTrackerQueryVariable * self;
	self = G_TYPE_CHECK_INSTANCE_CAST (obj, RYGEL_TRACKER_TYPE_QUERY_VARIABLE, RygelTrackerQueryVariable);
	g_signal_handlers_destroy (self);
	_g_free0 (self->base_variable);
	_g_free0 (self->alias);
}

static GType
rygel_tracker_query_variable_get_type_once (void)
{
	static const GTypeValueTable g_define_type_value_table = { rygel_tracker_value_query_variable_init, rygel_tracker_value_query_variable_free_value, rygel_tracker_value_query_variable_copy_value, rygel_tracker_value_query_variable_peek_pointer, "p", rygel_tracker_value_query_variable_collect_value, "p", rygel_tracker_value_query_variable_lcopy_value };
	static const GTypeInfo g_define_type_info = { sizeof (RygelTrackerQueryVariableClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) rygel_tracker_query_variable_class_init, (GClassFinalizeFunc) NULL, NULL, sizeof (RygelTrackerQueryVariable), 0, (GInstanceInitFunc) rygel_tracker_query_variable_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_tracker_query_variable_type_id;
	rygel_tracker_query_variable_type_id = g_type_register_fundamental (g_type_fundamental_next (), "RygelTrackerQueryVariable", &g_define_type_info, &g_define_type_fundamental_info, 0);
	return rygel_tracker_query_variable_type_id;
}

GType
rygel_tracker_query_variable_get_type (void)
{
	static volatile gsize rygel_tracker_query_variable_type_id__once = 0;
	if (g_once_init_enter (&rygel_tracker_query_variable_type_id__once)) {
		GType rygel_tracker_query_variable_type_id;
		rygel_tracker_query_variable_type_id = rygel_tracker_query_variable_get_type_once ();
		g_once_init_leave (&rygel_tracker_query_variable_type_id__once, rygel_tracker_query_variable_type_id);
	}
	return rygel_tracker_query_variable_type_id__once;
}

gpointer
rygel_tracker_query_variable_ref (gpointer instance)
{
	RygelTrackerQueryVariable * self;
	self = instance;
	g_atomic_int_inc (&self->ref_count);
	return instance;
}

void
rygel_tracker_query_variable_unref (gpointer instance)
{
	RygelTrackerQueryVariable * self;
	self = instance;
	if (g_atomic_int_dec_and_test (&self->ref_count)) {
		RYGEL_TRACKER_QUERY_VARIABLE_GET_CLASS (self)->finalize (self);
		g_type_free_instance ((GTypeInstance *) self);
	}
}

static inline gpointer
rygel_tracker_upn_pproperty_map_get_instance_private (RygelTrackerUPnPPropertyMap* self)
{
	return G_STRUCT_MEMBER_P (self, RygelTrackerUPnPPropertyMap_private_offset);
}

static gpointer
_g_object_ref0 (gpointer self)
{
	return self ? g_object_ref (self) : NULL;
}

RygelTrackerUPnPPropertyMap*
rygel_tracker_upn_pproperty_map_get_property_map (void)
{
	RygelTrackerUPnPPropertyMap* _tmp0_;
	RygelTrackerUPnPPropertyMap* _tmp2_;
	RygelTrackerUPnPPropertyMap* _tmp3_;
	RygelTrackerUPnPPropertyMap* result;
	_tmp0_ = rygel_tracker_upn_pproperty_map_instance;
	if (G_UNLIKELY (_tmp0_ == NULL)) {
		RygelTrackerUPnPPropertyMap* _tmp1_;
		_tmp1_ = rygel_tracker_upn_pproperty_map_new ();
		_g_object_unref0 (rygel_tracker_upn_pproperty_map_instance);
		rygel_tracker_upn_pproperty_map_instance = _tmp1_;
	}
	_tmp2_ = rygel_tracker_upn_pproperty_map_instance;
	_tmp3_ = _g_object_ref0 (_tmp2_);
	result = _tmp3_;
	return result;
}

static RygelTrackerUPnPPropertyMap*
rygel_tracker_upn_pproperty_map_construct (GType object_type)
{
	RygelTrackerUPnPPropertyMap * self = NULL;
	GeeHashMap* _tmp0_;
	GeeHashMap* _tmp1_;
	GeeHashMap* _tmp2_;
	self = (RygelTrackerUPnPPropertyMap*) g_object_new (object_type, NULL);
	_tmp0_ = gee_hash_map_new (G_TYPE_STRING, (GBoxedCopyFunc) g_strdup, (GDestroyNotify) g_free, GEE_TYPE_ARRAY_LIST, (GBoxedCopyFunc) g_object_ref, (GDestroyNotify) g_object_unref, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
	_g_object_unref0 (self->priv->property_map);
	self->priv->property_map = _tmp0_;
	_tmp1_ = gee_hash_map_new (G_TYPE_STRING, (GBoxedCopyFunc) g_strdup, (GDestroyNotify) g_free, G_TYPE_STRING, (GBoxedCopyFunc) g_strdup, (GDestroyNotify) g_free, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
	_g_object_unref0 (self->priv->functions);
	self->priv->functions = _tmp1_;
	_tmp2_ = gee_hash_map_new (G_TYPE_STRING, (GBoxedCopyFunc) g_strdup, (GDestroyNotify) g_free, RYGEL_TRACKER_TYPE_QUERY_VARIABLE, (GBoxedCopyFunc) rygel_tracker_query_variable_ref, (GDestroyNotify) rygel_tracker_query_variable_unref, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
	_g_object_unref0 (self->priv->variables);
	self->priv->variables = _tmp2_;
	rygel_tracker_upn_pproperty_map_add_variable (self, "upnp:class", RYGEL_TRACKER_SELECTION_QUERY_ITEM_VARIABLE, "?_cls");
	rygel_tracker_upn_pproperty_map_add_key_chain (self, "res", "nie:url", NULL);
	rygel_tracker_upn_pproperty_map_add_variable (self, "res", RYGEL_TRACKER_SELECTION_QUERY_STORAGE_VARIABLE, "?_url");
	rygel_tracker_upn_pproperty_map_add_function (self, "place_holder", "tracker:coalesce((SELECT false WHERE { { %s a ?o } " "FILTER (?o IN (nfo:FileDataObject, " "nfo:RemoteDataObject)) }), true)");
	rygel_tracker_upn_pproperty_map_add_variable (self, "place_holder", RYGEL_TRACKER_SELECTION_QUERY_STORAGE_VARIABLE, "?_ph");
	rygel_tracker_upn_pproperty_map_add_key_chain (self, "fileName", "nfo:fileName", NULL);
	rygel_tracker_upn_pproperty_map_add_variable (self, "fileName", RYGEL_TRACKER_SELECTION_QUERY_STORAGE_VARIABLE, "?_fn");
	rygel_tracker_upn_pproperty_map_add_alternative (self, "dc:title", "nie:title", "?_fn", NULL);
	rygel_tracker_upn_pproperty_map_add_function (self, "dc:title", "tracker:coalesce(nie:title(%s), nfo:fileName(?storage))");
	rygel_tracker_upn_pproperty_map_add_variable (self, "dc:title", RYGEL_TRACKER_SELECTION_QUERY_ITEM_VARIABLE, "?_title");
	rygel_tracker_upn_pproperty_map_add_key_chain (self, "dlnaProfile", "nmm:dlnaProfile", NULL);
	rygel_tracker_upn_pproperty_map_add_variable (self, "dlnaProfile", RYGEL_TRACKER_SELECTION_QUERY_ITEM_VARIABLE, "?_profile");
	rygel_tracker_upn_pproperty_map_add_alternative (self, "mimeType", "nmm:dlnaMime", "nie:mimeType", NULL);
	rygel_tracker_upn_pproperty_map_add_variable (self, "mimeType", RYGEL_TRACKER_SELECTION_QUERY_ITEM_VARIABLE, "?_mime");
	rygel_tracker_upn_pproperty_map_add_alternative (self, "res@size", "nfo:fileSize", "nie:byteSize", NULL);
	rygel_tracker_upn_pproperty_map_add_variable (self, "res@size", RYGEL_TRACKER_SELECTION_QUERY_STORAGE_VARIABLE, "?_mime");
	rygel_tracker_upn_pproperty_map_add_function (self, "date", "tracker:coalesce(nie:contentCreated(%s), nfo:fileLastModified(?storage" \
"))");
	rygel_tracker_upn_pproperty_map_add_variable (self, "date", RYGEL_TRACKER_SELECTION_QUERY_ITEM_VARIABLE, "?_date");
	rygel_tracker_upn_pproperty_map_add_key_chain (self, "res@duration", "nfo:duration", NULL);
	rygel_tracker_upn_pproperty_map_add_variable (self, "res@duration", RYGEL_TRACKER_SELECTION_QUERY_ITEM_VARIABLE, "?_duration");
	rygel_tracker_upn_pproperty_map_add_key_chain (self, "upnp:artist", "nmm:performer", "nmm:artistName", NULL);
	rygel_tracker_upn_pproperty_map_add_variable (self, "upnp:artist", RYGEL_TRACKER_SELECTION_QUERY_ITEM_VARIABLE, "?_artist");
	rygel_tracker_upn_pproperty_map_add_key_chain (self, "dc:creator", "nmm:performer", "nmm:artistName", NULL);
	rygel_tracker_upn_pproperty_map_add_variable (self, "dc:creator", RYGEL_TRACKER_SELECTION_QUERY_ITEM_VARIABLE, "?_artist");
	rygel_tracker_upn_pproperty_map_add_key_chain (self, "upnp:album", "nmm:musicAlbum", "nie:title", NULL);
	rygel_tracker_upn_pproperty_map_add_variable (self, "upnp:album", RYGEL_TRACKER_SELECTION_QUERY_ITEM_VARIABLE, "?_album");
	rygel_tracker_upn_pproperty_map_add_key_chain (self, "upnp:originalTrackNumber", "nmm:trackNumber", NULL);
	rygel_tracker_upn_pproperty_map_add_variable (self, "upnp:originalTrackNumber", RYGEL_TRACKER_SELECTION_QUERY_ITEM_VARIABLE, "?_track");
	rygel_tracker_upn_pproperty_map_add_key_chain (self, "upnp:genre", "nfo:genre", NULL);
	rygel_tracker_upn_pproperty_map_add_variable (self, "upnp:genre", RYGEL_TRACKER_SELECTION_QUERY_ITEM_VARIABLE, "?_genre");
	rygel_tracker_upn_pproperty_map_add_key_chain (self, "sampleRate", "nfo:sampleRate", NULL);
	rygel_tracker_upn_pproperty_map_add_variable (self, "sampleRate", RYGEL_TRACKER_SELECTION_QUERY_ITEM_VARIABLE, "?_rate");
	rygel_tracker_upn_pproperty_map_add_key_chain (self, "upnp:nrAudioChannels", "nfo:channels", NULL);
	rygel_tracker_upn_pproperty_map_add_variable (self, "upnp:nrAudioChannels", RYGEL_TRACKER_SELECTION_QUERY_ITEM_VARIABLE, "?_channels");
	rygel_tracker_upn_pproperty_map_add_key_chain (self, "upnp:bitsPerSample", "nfo:bitsPerSample", NULL);
	rygel_tracker_upn_pproperty_map_add_variable (self, "upnp:bitsPerSample", RYGEL_TRACKER_SELECTION_QUERY_ITEM_VARIABLE, "?_bps");
	rygel_tracker_upn_pproperty_map_add_key_chain (self, "upnp:bitrate", "nfo:averageBitrate", NULL);
	rygel_tracker_upn_pproperty_map_add_variable (self, "upnp:bitrate", RYGEL_TRACKER_SELECTION_QUERY_ITEM_VARIABLE, "?_rate");
	rygel_tracker_upn_pproperty_map_add_key_chain (self, "width", "nfo:width", NULL);
	rygel_tracker_upn_pproperty_map_add_variable (self, "width", RYGEL_TRACKER_SELECTION_QUERY_ITEM_VARIABLE, "?_w");
	rygel_tracker_upn_pproperty_map_add_key_chain (self, "height", "nfo:height", NULL);
	rygel_tracker_upn_pproperty_map_add_variable (self, "height", RYGEL_TRACKER_SELECTION_QUERY_ITEM_VARIABLE, "?_h");
	rygel_tracker_upn_pproperty_map_add_key_chain (self, "rygel:originalVolumeNumber", "nmm:musicAlbumDisc", "nmm:setNumber", NULL);
	rygel_tracker_upn_pproperty_map_add_variable (self, "rygel:originalVolumeNumber", RYGEL_TRACKER_SELECTION_QUERY_ITEM_VARIABLE, "?_vol");
	return self;
}

static RygelTrackerUPnPPropertyMap*
rygel_tracker_upn_pproperty_map_new (void)
{
	return rygel_tracker_upn_pproperty_map_construct (RYGEL_TRACKER_TYPE_UPN_PPROPERTY_MAP);
}

gchar*
rygel_tracker_upn_pproperty_map_get (RygelTrackerUPnPPropertyMap* self,
                                     const gchar* property)
{
	RygelTrackerQueryVariable* variable = NULL;
	GeeHashMap* _tmp0_;
	gpointer _tmp1_;
	gchar* str = NULL;
	RygelTrackerQueryVariable* _tmp2_;
	const gchar* _tmp3_;
	gchar* _tmp4_;
	GeeHashMap* _tmp5_;
	gchar* result;
	g_return_val_if_fail (self != NULL, NULL);
	g_return_val_if_fail (property != NULL, NULL);
	_tmp0_ = self->priv->variables;
	_tmp1_ = gee_abstract_map_get ((GeeAbstractMap*) _tmp0_, property);
	variable = (RygelTrackerQueryVariable*) _tmp1_;
	_tmp2_ = variable;
	_tmp3_ = _tmp2_->base_variable;
	_tmp4_ = g_strdup (_tmp3_);
	str = _tmp4_;
	_tmp5_ = self->priv->property_map;
	if (gee_abstract_map_has_key ((GeeAbstractMap*) _tmp5_, property)) {
		{
			GeeArrayList* _key_list = NULL;
			GeeHashMap* _tmp6_;
			gpointer _tmp7_;
			gint _key_size = 0;
			GeeArrayList* _tmp8_;
			gint _tmp9_;
			gint _tmp10_;
			gint _key_index = 0;
			_tmp6_ = self->priv->property_map;
			_tmp7_ = gee_abstract_map_get ((GeeAbstractMap*) _tmp6_, property);
			_key_list = (GeeArrayList*) _tmp7_;
			_tmp8_ = _key_list;
			_tmp9_ = gee_abstract_collection_get_size ((GeeAbstractCollection*) _tmp8_);
			_tmp10_ = _tmp9_;
			_key_size = _tmp10_;
			_key_index = -1;
			while (TRUE) {
				gint _tmp11_;
				gint _tmp12_;
				gchar* key = NULL;
				GeeArrayList* _tmp13_;
				gpointer _tmp14_;
				const gchar* _tmp15_;
				gchar* _tmp16_;
				gchar* _tmp17_;
				const gchar* _tmp18_;
				gchar* _tmp19_;
				gchar* _tmp20_;
				gchar* _tmp21_;
				_key_index = _key_index + 1;
				_tmp11_ = _key_index;
				_tmp12_ = _key_size;
				if (!(_tmp11_ < _tmp12_)) {
					break;
				}
				_tmp13_ = _key_list;
				_tmp14_ = gee_abstract_list_get ((GeeAbstractList*) _tmp13_, _key_index);
				key = (gchar*) _tmp14_;
				_tmp15_ = key;
				_tmp16_ = g_strconcat (_tmp15_, "(", NULL);
				_tmp17_ = _tmp16_;
				_tmp18_ = str;
				_tmp19_ = g_strconcat (_tmp17_, _tmp18_, NULL);
				_tmp20_ = _tmp19_;
				_tmp21_ = g_strconcat (_tmp20_, ")", NULL);
				_g_free0 (str);
				str = _tmp21_;
				_g_free0 (_tmp20_);
				_g_free0 (_tmp17_);
				_g_free0 (key);
			}
			_g_object_unref0 (_key_list);
		}
	} else {
		GeeHashMap* _tmp22_;
		_tmp22_ = self->priv->functions;
		if (gee_abstract_map_has_key ((GeeAbstractMap*) _tmp22_, property)) {
			GeeHashMap* _tmp23_;
			gpointer _tmp24_;
			gchar* _tmp25_;
			const gchar* _tmp26_;
			gchar* _tmp27_;
			_tmp23_ = self->priv->functions;
			_tmp24_ = gee_abstract_map_get ((GeeAbstractMap*) _tmp23_, property);
			_tmp25_ = (gchar*) _tmp24_;
			_tmp26_ = str;
			_tmp27_ = g_strdup_printf (_tmp25_, _tmp26_);
			_g_free0 (str);
			str = _tmp27_;
			_g_free0 (_tmp25_);
		}
	}
	result = str;
	_rygel_tracker_query_variable_unref0 (variable);
	return result;
}

static void
rygel_tracker_upn_pproperty_map_add_variable (RygelTrackerUPnPPropertyMap* self,
                                              const gchar* property,
                                              const gchar* base_item,
                                              const gchar* alias)
{
	GeeHashMap* _tmp0_;
	RygelTrackerQueryVariable* _tmp1_;
	RygelTrackerQueryVariable* _tmp2_;
	g_return_if_fail (self != NULL);
	g_return_if_fail (property != NULL);
	g_return_if_fail (base_item != NULL);
	g_return_if_fail (alias != NULL);
	_tmp0_ = self->priv->variables;
	_tmp1_ = rygel_tracker_query_variable_new (base_item, alias);
	_tmp2_ = _tmp1_;
	gee_abstract_map_set ((GeeAbstractMap*) _tmp0_, property, _tmp2_);
	_rygel_tracker_query_variable_unref0 (_tmp2_);
}

static void
rygel_tracker_upn_pproperty_map_add_key_chain (RygelTrackerUPnPPropertyMap* self,
                                               const gchar* property,
                                               ...)
{
	GeeArrayList* key_chain = NULL;
	GeeArrayList* _tmp0_;
	va_list list = {0};
	gchar* key = NULL;
	const gchar* _tmp1_;
	gchar* _tmp2_;
	GeeHashMap* _tmp8_;
	GeeArrayList* _tmp9_;
	g_return_if_fail (self != NULL);
	g_return_if_fail (property != NULL);
	_tmp0_ = gee_array_list_new (G_TYPE_STRING, (GBoxedCopyFunc) g_strdup, (GDestroyNotify) g_free, NULL, NULL, NULL);
	key_chain = _tmp0_;
	va_start (list, property);
	_tmp1_ = va_arg (list, gchar*);
	_tmp2_ = g_strdup (_tmp1_);
	key = _tmp2_;
	while (TRUE) {
		const gchar* _tmp3_;
		GeeArrayList* _tmp4_;
		const gchar* _tmp5_;
		const gchar* _tmp6_;
		gchar* _tmp7_;
		_tmp3_ = key;
		if (!(_tmp3_ != NULL)) {
			break;
		}
		_tmp4_ = key_chain;
		_tmp5_ = key;
		gee_abstract_collection_add ((GeeAbstractCollection*) _tmp4_, _tmp5_);
		_tmp6_ = va_arg (list, gchar*);
		_tmp7_ = g_strdup (_tmp6_);
		_g_free0 (key);
		key = _tmp7_;
	}
	_tmp8_ = self->priv->property_map;
	_tmp9_ = key_chain;
	gee_abstract_map_set ((GeeAbstractMap*) _tmp8_, property, _tmp9_);
	_g_free0 (key);
	va_end (list);
	_g_object_unref0 (key_chain);
}

static void
rygel_tracker_upn_pproperty_map_add_function (RygelTrackerUPnPPropertyMap* self,
                                              const gchar* property,
                                              const gchar* function)
{
	GeeHashMap* _tmp0_;
	g_return_if_fail (self != NULL);
	g_return_if_fail (property != NULL);
	g_return_if_fail (function != NULL);
	_tmp0_ = self->priv->functions;
	gee_abstract_map_set ((GeeAbstractMap*) _tmp0_, property, function);
}

static void
rygel_tracker_upn_pproperty_map_add_alternative (RygelTrackerUPnPPropertyMap* self,
                                                 const gchar* property,
                                                 ...)
{
	va_list list = {0};
	GString* str = NULL;
	GString* _tmp0_;
	gchar* alternative = NULL;
	const gchar* _tmp1_;
	gchar* _tmp2_;
	GString* _tmp11_;
	GString* _tmp12_;
	GString* _tmp13_;
	GString* _tmp14_;
	const gchar* _tmp15_;
	g_return_if_fail (self != NULL);
	g_return_if_fail (property != NULL);
	va_start (list, property);
	_tmp0_ = g_string_new ("tracker:coalesce(");
	str = _tmp0_;
	_tmp1_ = va_arg (list, gchar*);
	_tmp2_ = g_strdup (_tmp1_);
	alternative = _tmp2_;
	while (TRUE) {
		const gchar* _tmp3_;
		const gchar* _tmp4_;
		const gchar* _tmp9_;
		gchar* _tmp10_;
		_tmp3_ = alternative;
		if (!(_tmp3_ != NULL)) {
			break;
		}
		_tmp4_ = alternative;
		if (g_str_has_prefix (_tmp4_, "?")) {
			GString* _tmp5_;
			const gchar* _tmp6_;
			_tmp5_ = str;
			_tmp6_ = alternative;
			g_string_append (_tmp5_, _tmp6_);
		} else {
			GString* _tmp7_;
			const gchar* _tmp8_;
			_tmp7_ = str;
			_tmp8_ = alternative;
			g_string_append_printf (_tmp7_, "%s(%%1$s),", _tmp8_);
		}
		_tmp9_ = va_arg (list, gchar*);
		_tmp10_ = g_strdup (_tmp9_);
		_g_free0 (alternative);
		alternative = _tmp10_;
	}
	_tmp11_ = str;
	_tmp12_ = str;
	g_string_truncate (_tmp11_, (gsize) (_tmp12_->len - 1));
	_tmp13_ = str;
	g_string_append (_tmp13_, ")");
	_tmp14_ = str;
	_tmp15_ = _tmp14_->str;
	rygel_tracker_upn_pproperty_map_add_function (self, property, _tmp15_);
	_g_free0 (alternative);
	_g_string_free0 (str);
	va_end (list);
}

static void
rygel_tracker_upn_pproperty_map_class_init (RygelTrackerUPnPPropertyMapClass * klass,
                                            gpointer klass_data)
{
	rygel_tracker_upn_pproperty_map_parent_class = g_type_class_peek_parent (klass);
	g_type_class_adjust_private_offset (klass, &RygelTrackerUPnPPropertyMap_private_offset);
	G_OBJECT_CLASS (klass)->finalize = rygel_tracker_upn_pproperty_map_finalize;
}

static void
rygel_tracker_upn_pproperty_map_instance_init (RygelTrackerUPnPPropertyMap * self,
                                               gpointer klass)
{
	self->priv = rygel_tracker_upn_pproperty_map_get_instance_private (self);
}

static void
rygel_tracker_upn_pproperty_map_finalize (GObject * obj)
{
	RygelTrackerUPnPPropertyMap * self;
	self = G_TYPE_CHECK_INSTANCE_CAST (obj, RYGEL_TRACKER_TYPE_UPN_PPROPERTY_MAP, RygelTrackerUPnPPropertyMap);
	_g_object_unref0 (self->priv->property_map);
	_g_object_unref0 (self->priv->functions);
	_g_object_unref0 (self->priv->variables);
	G_OBJECT_CLASS (rygel_tracker_upn_pproperty_map_parent_class)->finalize (obj);
}

/**
 * A map of UPnP properties to tracker property functions, coalesces,
 * subqueries or other custom functions
 */
static GType
rygel_tracker_upn_pproperty_map_get_type_once (void)
{
	static const GTypeInfo g_define_type_info = { sizeof (RygelTrackerUPnPPropertyMapClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) rygel_tracker_upn_pproperty_map_class_init, (GClassFinalizeFunc) NULL, NULL, sizeof (RygelTrackerUPnPPropertyMap), 0, (GInstanceInitFunc) rygel_tracker_upn_pproperty_map_instance_init, NULL };
	GType rygel_tracker_upn_pproperty_map_type_id;
	rygel_tracker_upn_pproperty_map_type_id = g_type_register_static (G_TYPE_OBJECT, "RygelTrackerUPnPPropertyMap", &g_define_type_info, 0);
	RygelTrackerUPnPPropertyMap_private_offset = g_type_add_instance_private (rygel_tracker_upn_pproperty_map_type_id, sizeof (RygelTrackerUPnPPropertyMapPrivate));
	return rygel_tracker_upn_pproperty_map_type_id;
}

GType
rygel_tracker_upn_pproperty_map_get_type (void)
{
	static volatile gsize rygel_tracker_upn_pproperty_map_type_id__once = 0;
	if (g_once_init_enter (&rygel_tracker_upn_pproperty_map_type_id__once)) {
		GType rygel_tracker_upn_pproperty_map_type_id;
		rygel_tracker_upn_pproperty_map_type_id = rygel_tracker_upn_pproperty_map_get_type_once ();
		g_once_init_leave (&rygel_tracker_upn_pproperty_map_type_id__once, rygel_tracker_upn_pproperty_map_type_id);
	}
	return rygel_tracker_upn_pproperty_map_type_id__once;
}

