/* Collections.c generated by valac 0.56.19, the Vala compiler
 * generated from Collections.vala, do not modify */

/* -*- Mode: vala; indent-tabs-mode: nil; c-basic-offset: 2; tab-width: 2 -*- */
/*
 *
 * Copyright (C) 2018 Daniel Espinosa <esodan@gmail.com>
 *
 * This library 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.

 * This library 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, see <http://www.gnu.org/licenses/>.
 *
 * Authors:
 *      Daniel Espinosa <esodan@gmail.com>
 */

#include "gxml/gxml.h"
#include <glib.h>
#include <glib/gi18n-lib.h>
#include <gee.h>
#include <glib-object.h>
#include <stdlib.h>
#include <string.h>
#include "gxml.h"

#if !defined(VALA_STRICT_C)
#if !defined(__clang__) && defined(__GNUC__) && (__GNUC__ >= 14)
#pragma GCC diagnostic warning "-Wincompatible-pointer-types"
#elif defined(__clang__) && (__clang_major__ >= 16)
#pragma clang diagnostic ignored "-Wincompatible-function-pointer-types"
#pragma clang diagnostic ignored "-Wincompatible-pointer-types"
#endif
#endif

#define _g_object_unref0(var) ((var == NULL) ? NULL : (var = (g_object_unref (var), NULL)))
#define _g_free0(var) (var = (g_free (var), NULL))
#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);

static GXmlDomElement* gxml_collection_real_get_item (GXmlCollection* self,
                                               gint index,
                                               GError** error);
static GXmlDomElement* gxml_collection_real_create_item (GXmlCollection* self);
static GType gxml_collection_get_type_once (void);
static GType gxml_list_get_type_once (void);
static GType gxml_mappeable_element_get_type_once (void);
static GType gxml_map_get_type_once (void);
static GType gxml_mappeable_element_pair_key_get_type_once (void);
static GType gxml_paired_map_get_type_once (void);
static GType gxml_mappeable_element_three_key_get_type_once (void);
static GType gxml_three_map_get_type_once (void);
static void _g_free0_ (gpointer var);
static GType gxml_collection_parent_get_type_once (void);

GQueue*
gxml_collection_get_nodes_index (GXmlCollection* self)
{
	GXmlCollectionIface* _iface_;
	g_return_val_if_fail (self != NULL, NULL);
	_iface_ = GXML_COLLECTION_GET_INTERFACE (self);
	if (_iface_->get_nodes_index) {
		return _iface_->get_nodes_index (self);
	}
	return NULL;
}

GXmlDomElement*
gxml_collection_get_element (GXmlCollection* self)
{
	GXmlCollectionIface* _iface_;
	g_return_val_if_fail (self != NULL, NULL);
	_iface_ = GXML_COLLECTION_GET_INTERFACE (self);
	if (_iface_->get_element) {
		return _iface_->get_element (self);
	}
	return NULL;
}

void
gxml_collection_set_element (GXmlCollection* self,
                             GXmlDomElement* value)
{
	GXmlCollectionIface* _iface_;
	g_return_if_fail (self != NULL);
	_iface_ = GXML_COLLECTION_GET_INTERFACE (self);
	if (_iface_->set_element) {
		_iface_->set_element (self, value);
	}
}

const gchar*
gxml_collection_get_items_name (GXmlCollection* self)
{
	GXmlCollectionIface* _iface_;
	g_return_val_if_fail (self != NULL, NULL);
	_iface_ = GXML_COLLECTION_GET_INTERFACE (self);
	if (_iface_->get_items_name) {
		return _iface_->get_items_name (self);
	}
	return NULL;
}

GType
gxml_collection_get_items_type (GXmlCollection* self)
{
	GXmlCollectionIface* _iface_;
	g_return_val_if_fail (self != NULL, G_TYPE_INVALID);
	_iface_ = GXML_COLLECTION_GET_INTERFACE (self);
	if (_iface_->get_items_type) {
		return _iface_->get_items_type (self);
	}
	return G_TYPE_INVALID;
}

void
gxml_collection_set_items_type (GXmlCollection* self,
                                GType value)
{
	GXmlCollectionIface* _iface_;
	g_return_if_fail (self != NULL);
	_iface_ = GXML_COLLECTION_GET_INTERFACE (self);
	if (_iface_->set_items_type) {
		_iface_->set_items_type (self, value);
	}
}

/**
   * Search and add references to all {@link GXml.Object} nodes as child of
   * {@link element} with same, case insensitive, name of {@link items_name}
   */
void
gxml_collection_search (GXmlCollection* self,
                        GError** error)
{
	GXmlCollectionIface* _iface_;
	g_return_if_fail (self != NULL);
	_iface_ = GXML_COLLECTION_GET_INTERFACE (self);
	if (_iface_->search) {
		_iface_->search (self, error);
	}
}

/**
   * Gets a child {@link DomElement} of {@link element} referenced in
   * {@link nodes_index}.
   */
static gpointer
_g_object_ref0 (gpointer self)
{
	return self ? g_object_ref (self) : NULL;
}

static GXmlDomElement*
gxml_collection_real_get_item (GXmlCollection* self,
                               gint index,
                               GError** error)
{
	GQueue* _tmp0_;
	GQueue* _tmp1_;
	gboolean _tmp2_ = FALSE;
	gint i = 0;
	GQueue* _tmp6_;
	GQueue* _tmp7_;
	gconstpointer _tmp8_;
	gboolean _tmp9_ = FALSE;
	GXmlDomNode* e = NULL;
	GXmlDomElement* _tmp18_;
	GXmlDomElement* _tmp19_;
	GXmlDomNodeList* _tmp20_;
	GXmlDomNodeList* _tmp21_;
	GXmlDomNodeList* _tmp22_;
	gpointer _tmp23_;
	GXmlDomNode* _tmp24_;
	GXmlDomNode* _tmp25_;
	GXmlDomNode* _tmp28_;
	GXmlDomElement* _tmp29_;
	GError* _inner_error0_ = NULL;
	GXmlDomElement* result;
	_tmp0_ = gxml_collection_get_nodes_index (self);
	_tmp1_ = _tmp0_;
	if (_tmp1_->length == ((guint) 0)) {
		result = NULL;
		return result;
	}
	if (index < 0) {
		_tmp2_ = TRUE;
	} else {
		GQueue* _tmp3_;
		GQueue* _tmp4_;
		_tmp3_ = gxml_collection_get_nodes_index (self);
		_tmp4_ = _tmp3_;
		_tmp2_ = ((guint) index) >= _tmp4_->length;
	}
	if (_tmp2_) {
		GError* _tmp5_;
		_tmp5_ = g_error_new_literal (GXML_DOM_ERROR, GXML_DOM_ERROR_INDEX_SIZE_ERROR, _ ("Invalid index for elements in array list"));
		_inner_error0_ = _tmp5_;
		g_propagate_error (error, _inner_error0_);
		return NULL;
	}
	_tmp6_ = gxml_collection_get_nodes_index (self);
	_tmp7_ = _tmp6_;
	_tmp8_ = g_queue_peek_nth (_tmp7_, (guint) index);
	i = (gint) ((gintptr) _tmp8_);
	if (i < 0) {
		_tmp9_ = TRUE;
	} else {
		GXmlDomElement* _tmp10_;
		GXmlDomElement* _tmp11_;
		GXmlDomNodeList* _tmp12_;
		GXmlDomNodeList* _tmp13_;
		GXmlDomNodeList* _tmp14_;
		gint _tmp15_;
		gint _tmp16_;
		_tmp10_ = gxml_collection_get_element (self);
		_tmp11_ = _tmp10_;
		_tmp12_ = gxml_dom_node_get_child_nodes ((GXmlDomNode*) _tmp11_);
		_tmp13_ = _tmp12_;
		_tmp14_ = _tmp13_;
		_tmp15_ = gee_collection_get_size ((GeeCollection*) _tmp14_);
		_tmp16_ = _tmp15_;
		_tmp9_ = i >= _tmp16_;
		_g_object_unref0 (_tmp14_);
	}
	if (_tmp9_) {
		GError* _tmp17_;
		_tmp17_ = g_error_new_literal (GXML_DOM_ERROR, GXML_DOM_ERROR_INDEX_SIZE_ERROR, _ ("Invalid index reference for child elements in array list"));
		_inner_error0_ = _tmp17_;
		g_propagate_error (error, _inner_error0_);
		return NULL;
	}
	_tmp18_ = gxml_collection_get_element (self);
	_tmp19_ = _tmp18_;
	_tmp20_ = gxml_dom_node_get_child_nodes ((GXmlDomNode*) _tmp19_);
	_tmp21_ = _tmp20_;
	_tmp22_ = _tmp21_;
	_tmp23_ = gee_list_get ((GeeList*) _tmp22_, i);
	_tmp24_ = (GXmlDomNode*) _tmp23_;
	_g_object_unref0 (_tmp22_);
	e = _tmp24_;
	_tmp25_ = e;
	if (_tmp25_ != NULL) {
		GXmlDomNode* _tmp26_;
		_tmp26_ = e;
		if (!GXML_IS_DOM_ELEMENT (_tmp26_)) {
			GError* _tmp27_;
			_tmp27_ = g_error_new_literal (GXML_DOM_ERROR, GXML_DOM_ERROR_INVALID_NODE_TYPE_ERROR, _ ("Referenced object's type is invalid. Should be a GXmlDomElement"));
			_inner_error0_ = _tmp27_;
			g_propagate_error (error, _inner_error0_);
			_g_object_unref0 (e);
			return NULL;
		}
	}
	_tmp28_ = e;
	_tmp29_ = _g_object_ref0 (G_TYPE_CHECK_INSTANCE_CAST (_tmp28_, GXML_TYPE_DOM_ELEMENT, GXmlDomElement));
	result = _tmp29_;
	_g_object_unref0 (e);
	return result;
}

GXmlDomElement*
gxml_collection_get_item (GXmlCollection* self,
                          gint index,
                          GError** error)
{
	GXmlCollectionIface* _iface_;
	g_return_val_if_fail (self != NULL, NULL);
	_iface_ = GXML_COLLECTION_GET_INTERFACE (self);
	if (_iface_->get_item) {
		return _iface_->get_item (self, index, error);
	}
	return NULL;
}

/**
   * Adds a {@link DomElement} node to this collection. Depending on type of
   * collection, this method will take information from node to initialize
   * how to find it.
   */
void
gxml_collection_append (GXmlCollection* self,
                        GXmlDomElement* node,
                        GError** error)
{
	GXmlCollectionIface* _iface_;
	g_return_if_fail (self != NULL);
	_iface_ = GXML_COLLECTION_GET_INTERFACE (self);
	if (_iface_->append) {
		_iface_->append (self, node, error);
	}
}

gint
gxml_collection_get_length (GXmlCollection* self)
{
	GXmlCollectionIface* _iface_;
	g_return_val_if_fail (self != NULL, -1);
	_iface_ = GXML_COLLECTION_GET_INTERFACE (self);
	if (_iface_->get_length) {
		return _iface_->get_length (self);
	}
	return -1;
}

static gint
gxml_collection_real_get_length (GXmlCollection* base)
{
	gint result;
	GXmlCollection* self;
	GQueue* _tmp0_;
	GQueue* _tmp1_;
	self = base;
	_tmp0_ = gxml_collection_get_nodes_index (self);
	_tmp1_ = _tmp0_;
	result = (gint) g_queue_get_length (_tmp1_);
	return result;
}

/**
   * Initialize collection to use a given {@link GXml.Collection} derived type.
   * Internally, this method create an instance of given type to initialize
   * {@link items_type} and {@link items_name}.
   *
   * This method can be used at construction time of classes implementing
   * {@link GXml.Collection} to initialize object type to refer in the collection.
   */
void
gxml_collection_initialize (GXmlCollection* self,
                            GType t,
                            GError** error)
{
	GXmlCollectionIface* _iface_;
	g_return_if_fail (self != NULL);
	_iface_ = GXML_COLLECTION_GET_INTERFACE (self);
	if (_iface_->initialize) {
		_iface_->initialize (self, t, error);
	}
}

/**
   * Creates a new instance of {@link items_type}, with same
   * {@link DomNode.owner_document} than {@link element}. New instance
   * is not set as a child of collection's {@link element}; to do so,
   * use {@link append}
   *
   * Returns: a new instance object or null if type is not a {@link DomElement} or no parent has been set
   */
static GXmlDomElement*
gxml_collection_real_create_item (GXmlCollection* self)
{
	GType _tmp0_;
	GType _tmp1_;
	GType _tmp2_;
	GType _tmp3_;
	GXmlDomElement* _tmp4_;
	GXmlDomElement* _tmp5_;
	GType _tmp6_;
	GType _tmp7_;
	GXmlDomElement* _tmp8_;
	GXmlDomElement* _tmp9_;
	GXmlDomDocument* _tmp10_;
	GXmlDomDocument* _tmp11_;
	GObject* _tmp12_;
	GObject* _tmp13_;
	GXmlDomElement* _tmp14_;
	GXmlDomElement* result;
	_tmp0_ = gxml_collection_get_items_type (self);
	_tmp1_ = _tmp0_;
	if (g_type_is_a (_tmp1_, G_TYPE_INVALID)) {
		result = NULL;
		return result;
	}
	_tmp2_ = gxml_collection_get_items_type (self);
	_tmp3_ = _tmp2_;
	if (!g_type_is_a (_tmp3_, GXML_TYPE_DOM_ELEMENT)) {
		result = NULL;
		return result;
	}
	_tmp4_ = gxml_collection_get_element (self);
	_tmp5_ = _tmp4_;
	if (_tmp5_ == NULL) {
		result = NULL;
		return result;
	}
	_tmp6_ = gxml_collection_get_items_type (self);
	_tmp7_ = _tmp6_;
	_tmp8_ = gxml_collection_get_element (self);
	_tmp9_ = _tmp8_;
	_tmp10_ = gxml_dom_node_get_owner_document ((GXmlDomNode*) _tmp9_);
	_tmp11_ = _tmp10_;
	_tmp12_ = g_object_new (_tmp7_, "owner_document", _tmp11_, NULL);
	_tmp13_ = G_IS_INITIALLY_UNOWNED (_tmp12_) ? g_object_ref_sink (_tmp12_) : _tmp12_;
	_tmp14_ = GXML_IS_DOM_ELEMENT (_tmp13_) ? ((GXmlDomElement*) _tmp13_) : NULL;
	if (_tmp14_ == NULL) {
		_g_object_unref0 (_tmp13_);
	}
	result = _tmp14_;
	return result;
}

GXmlDomElement*
gxml_collection_create_item (GXmlCollection* self)
{
	GXmlCollectionIface* _iface_;
	g_return_val_if_fail (self != NULL, NULL);
	_iface_ = GXML_COLLECTION_GET_INTERFACE (self);
	if (_iface_->create_item) {
		return _iface_->create_item (self);
	}
	return NULL;
}

/**
   * Validate if given node and index, should be added to collection.
   *
   * Implementations should use this method to perform any action before
   * element is added to collection, like setup internal pointers to given
   * index, in order to get access to referenced node.
   *
   * Return: true if node and index should be added to collection.
   */
gboolean
gxml_collection_validate_append (GXmlCollection* self,
                                 gint index,
                                 GXmlDomElement* element,
                                 GError** error)
{
	GXmlCollectionIface* _iface_;
	g_return_val_if_fail (self != NULL, FALSE);
	_iface_ = GXML_COLLECTION_GET_INTERFACE (self);
	if (_iface_->validate_append) {
		return _iface_->validate_append (self, index, element, error);
	}
	return FALSE;
}

/**
   * Clear this collection in preparation for a search
   */
void
gxml_collection_clear (GXmlCollection* self,
                       GError** error)
{
	GXmlCollectionIface* _iface_;
	g_return_if_fail (self != NULL);
	_iface_ = GXML_COLLECTION_GET_INTERFACE (self);
	if (_iface_->clear) {
		_iface_->clear (self, error);
	}
}

static void
gxml_collection_default_init (GXmlCollectionIface * iface,
                              gpointer iface_data)
{
	/**
	   * A list of child {@link DomElement} objects of {@link element}
	   */
	g_object_interface_install_property (iface, g_param_spec_pointer ("nodes-index", "nodes-index", "nodes-index", G_PARAM_STATIC_STRINGS | G_PARAM_READABLE));
	/**
	   * A {@link GXml.DomElement} with all child elements in collection.
	   */
	g_object_interface_install_property (iface, g_param_spec_object ("element", "element", "element", GXML_TYPE_DOM_ELEMENT, G_PARAM_STATIC_STRINGS | G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT));
	/**
	   * Local name of {@link DomElement} objects of {@link element}, which could be
	   * contained in this collection.
	   *
	   * Used when reading to add elements to collection.
	   */
	g_object_interface_install_property (iface, g_param_spec_string ("items-name", "items-name", "items-name", NULL, G_PARAM_STATIC_STRINGS | G_PARAM_READABLE));
	/**
	   * A {@link GLib.Type} of {@link DomElement} child objects of {@link element},
	   * which could be contained in this collection.
	   *
	   * Type should be an {@link GXml.Object}.
	   */
	g_object_interface_install_property (iface, g_param_spec_gtype ("items-type", "items-type", "items-type", G_TYPE_NONE, G_PARAM_STATIC_STRINGS | G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT));
	iface->get_item = gxml_collection_real_get_item;
	iface->create_item = gxml_collection_real_create_item;
	iface->get_length = gxml_collection_real_get_length;
}

/**
 * A DOM4 interface to keep references to {@link DomElement} children of a {@link element}.
 *
 * A collection should call {@link initialize} with the object's type to be added to
 * the connection and, at construction time, set the {@link element} this collection
 * should take its members from.
 *
 * This way, you can have a property to access all child elements of a given type,
 * the node will be added automatically to both as a child of your element and as
 * a member of the collection.
 *
 * {{{
 *   // This is your object definition and a collection one
 *   public class YourObject : GXml.Element {
 *    [Description (nick="::Name")]
 *    public string name { get; set; }
 *    construct {
 *      // This is the Element's node's name to be used
 *      try { initialize ("NodeName"); }
 *      catch (GLib.Error e ) {
 *        warning ("Error: "+e.message);
 *      }
 *    }
 *   }
 *   public class YourList : GXml.ArrayList {
 *    construct {
 *      // With this, your collection will find a add all elements
 *      // with the node's name 'NodeName' as declared to YourObject class
 *      try { initialize (typeof (YourObject)); }
 *      catch (GLib.Error e) {
 *        warning ("Initialization error for collection type: %s : %s"
 *             .printf (get_type ().name(), e.message));
 *      }
 *    }
 *   }
 *   // This is your element object definition with a collection of nodes
 *   // with the type YourObject
 *   public class YourElement : GXml.Element {
 *     public YourObject.YourList your_objects { get; set; }
 *     construct {
 *       // This is initializing the property 'your_objects' which is the type
 *       // YourList collection and set YourElement object as its element to
 *       // to take its members from. Use canonical names for properties as shown
 *       set_instance_property ('your-objects');
 *       // This is the node's name to use for YourElement class
 *        try { initialize ("YourElement"); }
 *        catch (GLib.Error e) {
 *          warning ("Initialization error for element type: %s", e.message));
 *        }
 *      }
 *    }
 * }}}
 */
static GType
gxml_collection_get_type_once (void)
{
	static const GTypeInfo g_define_type_info = { sizeof (GXmlCollectionIface), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) gxml_collection_default_init, (GClassFinalizeFunc) NULL, NULL, 0, 0, (GInstanceInitFunc) NULL, NULL };
	GType gxml_collection_type_id;
	gxml_collection_type_id = g_type_register_static (G_TYPE_INTERFACE, "GXmlCollection", &g_define_type_info, 0);
	g_type_interface_add_prerequisite (gxml_collection_type_id, G_TYPE_OBJECT);
	return gxml_collection_type_id;
}

GType
gxml_collection_get_type (void)
{
	static volatile gsize gxml_collection_type_id__once = 0;
	if (g_once_init_enter (&gxml_collection_type_id__once)) {
		GType gxml_collection_type_id;
		gxml_collection_type_id = gxml_collection_get_type_once ();
		g_once_init_leave (&gxml_collection_type_id__once, gxml_collection_type_id);
	}
	return gxml_collection_type_id__once;
}

static void
gxml_list_default_init (GXmlListIface * iface,
                        gpointer iface_data)
{
}

/**
 * {@link Gee.Iterable} and {@link Gee.Traversable} implementation of {@link GXml.Collection}
 */
static GType
gxml_list_get_type_once (void)
{
	static const GTypeInfo g_define_type_info = { sizeof (GXmlListIface), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) gxml_list_default_init, (GClassFinalizeFunc) NULL, NULL, 0, 0, (GInstanceInitFunc) NULL, NULL };
	GType gxml_list_type_id;
	gxml_list_type_id = g_type_register_static (G_TYPE_INTERFACE, "GXmlList", &g_define_type_info, 0);
	g_type_interface_add_prerequisite (gxml_list_type_id, G_TYPE_OBJECT);
	g_type_interface_add_prerequisite (gxml_list_type_id, GXML_TYPE_COLLECTION);
	g_type_interface_add_prerequisite (gxml_list_type_id, GEE_TYPE_TRAVERSABLE);
	g_type_interface_add_prerequisite (gxml_list_type_id, GEE_TYPE_ITERABLE);
	return gxml_list_type_id;
}

GType
gxml_list_get_type (void)
{
	static volatile gsize gxml_list_type_id__once = 0;
	if (g_once_init_enter (&gxml_list_type_id__once)) {
		GType gxml_list_type_id;
		gxml_list_type_id = gxml_list_get_type_once ();
		g_once_init_leave (&gxml_list_type_id__once, gxml_list_type_id);
	}
	return gxml_list_type_id__once;
}

gchar*
gxml_mappeable_element_get_map_key (GXmlMappeableElement* self)
{
	GXmlMappeableElementIface* _iface_;
	g_return_val_if_fail (self != NULL, NULL);
	_iface_ = GXML_MAPPEABLE_ELEMENT_GET_INTERFACE (self);
	if (_iface_->get_map_key) {
		return _iface_->get_map_key (self);
	}
	return NULL;
}

static void
gxml_mappeable_element_default_init (GXmlMappeableElementIface * iface,
                                     gpointer iface_data)
{
}

/**
 * Interface to be implemented by {@link GXml.Collection} derived classes
 * in order to provide a string to be used in {@link GXml.HashMap} as key.
 *
 * If {@link GXml.HashMap} has set its {@link GXml.HashMap.attribute_key}
 * its value has precedence over this method.
 */
static GType
gxml_mappeable_element_get_type_once (void)
{
	static const GTypeInfo g_define_type_info = { sizeof (GXmlMappeableElementIface), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) gxml_mappeable_element_default_init, (GClassFinalizeFunc) NULL, NULL, 0, 0, (GInstanceInitFunc) NULL, NULL };
	GType gxml_mappeable_element_type_id;
	gxml_mappeable_element_type_id = g_type_register_static (G_TYPE_INTERFACE, "GXmlMappeableElement", &g_define_type_info, 0);
	g_type_interface_add_prerequisite (gxml_mappeable_element_type_id, G_TYPE_OBJECT);
	g_type_interface_add_prerequisite (gxml_mappeable_element_type_id, GXML_TYPE_DOM_ELEMENT);
	return gxml_mappeable_element_type_id;
}

GType
gxml_mappeable_element_get_type (void)
{
	static volatile gsize gxml_mappeable_element_type_id__once = 0;
	if (g_once_init_enter (&gxml_mappeable_element_type_id__once)) {
		GType gxml_mappeable_element_type_id;
		gxml_mappeable_element_type_id = gxml_mappeable_element_get_type_once ();
		g_once_init_leave (&gxml_mappeable_element_type_id__once, gxml_mappeable_element_type_id);
	}
	return gxml_mappeable_element_type_id__once;
}

const gchar*
gxml_map_get_attribute_key (GXmlMap* self)
{
	GXmlMapIface* _iface_;
	g_return_val_if_fail (self != NULL, NULL);
	_iface_ = GXML_MAP_GET_INTERFACE (self);
	if (_iface_->get_attribute_key) {
		return _iface_->get_attribute_key (self);
	}
	return NULL;
}

void
gxml_map_set_attribute_key (GXmlMap* self,
                            const gchar* value)
{
	GXmlMapIface* _iface_;
	g_return_if_fail (self != NULL);
	_iface_ = GXML_MAP_GET_INTERFACE (self);
	if (_iface_->set_attribute_key) {
		_iface_->set_attribute_key (self, value);
	}
}

/**
   * Returns an {@link DomElement} in the collection using a string key.
   */
GXmlDomElement*
gxml_map_item (GXmlMap* self,
               const gchar* key)
{
	GXmlMapIface* _iface_;
	g_return_val_if_fail (self != NULL, NULL);
	_iface_ = GXML_MAP_GET_INTERFACE (self);
	if (_iface_->item) {
		return _iface_->item (self, key);
	}
	return NULL;
}

/**
   * Returns true if @key is used in collection.
   */
gboolean
gxml_map_has_key (GXmlMap* self,
                  const gchar* key)
{
	GXmlMapIface* _iface_;
	g_return_val_if_fail (self != NULL, FALSE);
	_iface_ = GXML_MAP_GET_INTERFACE (self);
	if (_iface_->has_key) {
		return _iface_->has_key (self, key);
	}
	return FALSE;
}

GeeSet*
gxml_map_get_keys_set (GXmlMap* self)
{
	GXmlMapIface* _iface_;
	g_return_val_if_fail (self != NULL, NULL);
	_iface_ = GXML_MAP_GET_INTERFACE (self);
	if (_iface_->get_keys_set) {
		return _iface_->get_keys_set (self);
	}
	return NULL;
}

static void
gxml_map_default_init (GXmlMapIface * iface,
                       gpointer iface_data)
{
	/**
	   * An attribute's name in items to be added and used to retrieve elements
	   * as key.
	   */
	g_object_interface_install_property (iface, g_param_spec_string ("attribute-key", "attribute-key", "attribute-key", NULL, G_PARAM_STATIC_STRINGS | G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT));
	/**
	   * Returns list of keys used in collection.
	   */
	g_object_interface_install_property (iface, g_param_spec_object ("keys-set", "keys-set", "keys-set", GEE_TYPE_SET, G_PARAM_STATIC_STRINGS | G_PARAM_READABLE));
}

/**
 * {@link Gee.Iterable} and {@link Gee.Traversable} implementation of {@link GXml.Collection}
 */
static GType
gxml_map_get_type_once (void)
{
	static const GTypeInfo g_define_type_info = { sizeof (GXmlMapIface), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) gxml_map_default_init, (GClassFinalizeFunc) NULL, NULL, 0, 0, (GInstanceInitFunc) NULL, NULL };
	GType gxml_map_type_id;
	gxml_map_type_id = g_type_register_static (G_TYPE_INTERFACE, "GXmlMap", &g_define_type_info, 0);
	g_type_interface_add_prerequisite (gxml_map_type_id, G_TYPE_OBJECT);
	g_type_interface_add_prerequisite (gxml_map_type_id, GXML_TYPE_COLLECTION);
	g_type_interface_add_prerequisite (gxml_map_type_id, GEE_TYPE_TRAVERSABLE);
	g_type_interface_add_prerequisite (gxml_map_type_id, GEE_TYPE_ITERABLE);
	return gxml_map_type_id;
}

GType
gxml_map_get_type (void)
{
	static volatile gsize gxml_map_type_id__once = 0;
	if (g_once_init_enter (&gxml_map_type_id__once)) {
		GType gxml_map_type_id;
		gxml_map_type_id = gxml_map_get_type_once ();
		g_once_init_leave (&gxml_map_type_id__once, gxml_map_type_id);
	}
	return gxml_map_type_id__once;
}

gchar*
gxml_mappeable_element_pair_key_get_map_primary_key (GXmlMappeableElementPairKey* self)
{
	GXmlMappeableElementPairKeyIface* _iface_;
	g_return_val_if_fail (self != NULL, NULL);
	_iface_ = GXML_MAPPEABLE_ELEMENT_PAIR_KEY_GET_INTERFACE (self);
	if (_iface_->get_map_primary_key) {
		return _iface_->get_map_primary_key (self);
	}
	return NULL;
}

gchar*
gxml_mappeable_element_pair_key_get_map_secondary_key (GXmlMappeableElementPairKey* self)
{
	GXmlMappeableElementPairKeyIface* _iface_;
	g_return_val_if_fail (self != NULL, NULL);
	_iface_ = GXML_MAPPEABLE_ELEMENT_PAIR_KEY_GET_INTERFACE (self);
	if (_iface_->get_map_secondary_key) {
		return _iface_->get_map_secondary_key (self);
	}
	return NULL;
}

static void
gxml_mappeable_element_pair_key_default_init (GXmlMappeableElementPairKeyIface * iface,
                                              gpointer iface_data)
{
}

/**
 * Interface to be implemented by {@link GXml.Collection} derived classes
 * in order to provide a strings to be used in {@link GXml.HashPairedMap} as keys.
 */
static GType
gxml_mappeable_element_pair_key_get_type_once (void)
{
	static const GTypeInfo g_define_type_info = { sizeof (GXmlMappeableElementPairKeyIface), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) gxml_mappeable_element_pair_key_default_init, (GClassFinalizeFunc) NULL, NULL, 0, 0, (GInstanceInitFunc) NULL, NULL };
	GType gxml_mappeable_element_pair_key_type_id;
	gxml_mappeable_element_pair_key_type_id = g_type_register_static (G_TYPE_INTERFACE, "GXmlMappeableElementPairKey", &g_define_type_info, 0);
	g_type_interface_add_prerequisite (gxml_mappeable_element_pair_key_type_id, G_TYPE_OBJECT);
	g_type_interface_add_prerequisite (gxml_mappeable_element_pair_key_type_id, GXML_TYPE_DOM_ELEMENT);
	return gxml_mappeable_element_pair_key_type_id;
}

GType
gxml_mappeable_element_pair_key_get_type (void)
{
	static volatile gsize gxml_mappeable_element_pair_key_type_id__once = 0;
	if (g_once_init_enter (&gxml_mappeable_element_pair_key_type_id__once)) {
		GType gxml_mappeable_element_pair_key_type_id;
		gxml_mappeable_element_pair_key_type_id = gxml_mappeable_element_pair_key_get_type_once ();
		g_once_init_leave (&gxml_mappeable_element_pair_key_type_id__once, gxml_mappeable_element_pair_key_type_id);
	}
	return gxml_mappeable_element_pair_key_type_id__once;
}

const gchar*
gxml_paired_map_get_attribute_primary_key (GXmlPairedMap* self)
{
	GXmlPairedMapIface* _iface_;
	g_return_val_if_fail (self != NULL, NULL);
	_iface_ = GXML_PAIRED_MAP_GET_INTERFACE (self);
	if (_iface_->get_attribute_primary_key) {
		return _iface_->get_attribute_primary_key (self);
	}
	return NULL;
}

void
gxml_paired_map_set_attribute_primary_key (GXmlPairedMap* self,
                                           const gchar* value)
{
	GXmlPairedMapIface* _iface_;
	g_return_if_fail (self != NULL);
	_iface_ = GXML_PAIRED_MAP_GET_INTERFACE (self);
	if (_iface_->set_attribute_primary_key) {
		_iface_->set_attribute_primary_key (self, value);
	}
}

const gchar*
gxml_paired_map_get_attribute_secondary_key (GXmlPairedMap* self)
{
	GXmlPairedMapIface* _iface_;
	g_return_val_if_fail (self != NULL, NULL);
	_iface_ = GXML_PAIRED_MAP_GET_INTERFACE (self);
	if (_iface_->get_attribute_secondary_key) {
		return _iface_->get_attribute_secondary_key (self);
	}
	return NULL;
}

void
gxml_paired_map_set_attribute_secondary_key (GXmlPairedMap* self,
                                             const gchar* value)
{
	GXmlPairedMapIface* _iface_;
	g_return_if_fail (self != NULL);
	_iface_ = GXML_PAIRED_MAP_GET_INTERFACE (self);
	if (_iface_->set_attribute_secondary_key) {
		_iface_->set_attribute_secondary_key (self, value);
	}
}

GeeSet*
gxml_paired_map_get_primary_keys_set (GXmlPairedMap* self)
{
	GXmlPairedMapIface* _iface_;
	g_return_val_if_fail (self != NULL, NULL);
	_iface_ = GXML_PAIRED_MAP_GET_INTERFACE (self);
	if (_iface_->get_primary_keys_set) {
		return _iface_->get_primary_keys_set (self);
	}
	return NULL;
}

/**
   * Returns an {@link DomElement} in the collection using given string keys.
   */
GXmlDomElement*
gxml_paired_map_item (GXmlPairedMap* self,
                      const gchar* primary_key,
                      const gchar* secondary_key)
{
	GXmlPairedMapIface* _iface_;
	g_return_val_if_fail (self != NULL, NULL);
	_iface_ = GXML_PAIRED_MAP_GET_INTERFACE (self);
	if (_iface_->item) {
		return _iface_->item (self, primary_key, secondary_key);
	}
	return NULL;
}

/**
   * Returns true if @key is used in collection as primary key.
   */
gboolean
gxml_paired_map_has_primary_key (GXmlPairedMap* self,
                                 const gchar* key)
{
	GXmlPairedMapIface* _iface_;
	g_return_val_if_fail (self != NULL, FALSE);
	_iface_ = GXML_PAIRED_MAP_GET_INTERFACE (self);
	if (_iface_->has_primary_key) {
		return _iface_->has_primary_key (self, key);
	}
	return FALSE;
}

/**
   * Returns true if @key is used in collection as secondary key
   * with @pkey as primary.
   */
gboolean
gxml_paired_map_has_secondary_key (GXmlPairedMap* self,
                                   const gchar* pkey,
                                   const gchar* key)
{
	GXmlPairedMapIface* _iface_;
	g_return_val_if_fail (self != NULL, FALSE);
	_iface_ = GXML_PAIRED_MAP_GET_INTERFACE (self);
	if (_iface_->has_secondary_key) {
		return _iface_->has_secondary_key (self, pkey, key);
	}
	return FALSE;
}

/**
   * Returns list of secondary keys used in collection with @pkey as primary key.
   */
GeeSet*
gxml_paired_map_secondary_keys_set (GXmlPairedMap* self,
                                    const gchar* pkey)
{
	GXmlPairedMapIface* _iface_;
	g_return_val_if_fail (self != NULL, NULL);
	_iface_ = GXML_PAIRED_MAP_GET_INTERFACE (self);
	if (_iface_->secondary_keys_set) {
		return _iface_->secondary_keys_set (self, pkey);
	}
	return NULL;
}

static void
gxml_paired_map_default_init (GXmlPairedMapIface * iface,
                              gpointer iface_data)
{
	/**
	   * An attribute's name in items to be added and used to retrieve elements
	   * as primary key.
	   */
	g_object_interface_install_property (iface, g_param_spec_string ("attribute-primary-key", "attribute-primary-key", "attribute-primary-key", NULL, G_PARAM_STATIC_STRINGS | G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT));
	/**
	   * An attribute's name in items to be added and used to retrieve elements
	   * as secondary key.
	   */
	g_object_interface_install_property (iface, g_param_spec_string ("attribute-secondary-key", "attribute-secondary-key", "attribute-secondary-key", NULL, G_PARAM_STATIC_STRINGS | G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT));
	/**
	   * Returns list of primary keys used in collection.
	   */
	g_object_interface_install_property (iface, g_param_spec_object ("primary-keys-set", "primary-keys-set", "primary-keys-set", GEE_TYPE_SET, G_PARAM_STATIC_STRINGS | G_PARAM_READABLE));
}

/**
 * {@link Gee.Iterable} and {@link Gee.Traversable} implementation of {@link GXml.Collection}
 */
static GType
gxml_paired_map_get_type_once (void)
{
	static const GTypeInfo g_define_type_info = { sizeof (GXmlPairedMapIface), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) gxml_paired_map_default_init, (GClassFinalizeFunc) NULL, NULL, 0, 0, (GInstanceInitFunc) NULL, NULL };
	GType gxml_paired_map_type_id;
	gxml_paired_map_type_id = g_type_register_static (G_TYPE_INTERFACE, "GXmlPairedMap", &g_define_type_info, 0);
	g_type_interface_add_prerequisite (gxml_paired_map_type_id, G_TYPE_OBJECT);
	g_type_interface_add_prerequisite (gxml_paired_map_type_id, GXML_TYPE_COLLECTION);
	g_type_interface_add_prerequisite (gxml_paired_map_type_id, GEE_TYPE_TRAVERSABLE);
	g_type_interface_add_prerequisite (gxml_paired_map_type_id, GEE_TYPE_ITERABLE);
	return gxml_paired_map_type_id;
}

GType
gxml_paired_map_get_type (void)
{
	static volatile gsize gxml_paired_map_type_id__once = 0;
	if (g_once_init_enter (&gxml_paired_map_type_id__once)) {
		GType gxml_paired_map_type_id;
		gxml_paired_map_type_id = gxml_paired_map_get_type_once ();
		g_once_init_leave (&gxml_paired_map_type_id__once, gxml_paired_map_type_id);
	}
	return gxml_paired_map_type_id__once;
}

/**
   * Returns primary key of collection.
   */
gchar*
gxml_mappeable_element_three_key_get_map_pkey (GXmlMappeableElementThreeKey* self)
{
	GXmlMappeableElementThreeKeyIface* _iface_;
	g_return_val_if_fail (self != NULL, NULL);
	_iface_ = GXML_MAPPEABLE_ELEMENT_THREE_KEY_GET_INTERFACE (self);
	if (_iface_->get_map_pkey) {
		return _iface_->get_map_pkey (self);
	}
	return NULL;
}

/**
   * Returns secondary key of collection.
   */
gchar*
gxml_mappeable_element_three_key_get_map_skey (GXmlMappeableElementThreeKey* self)
{
	GXmlMappeableElementThreeKeyIface* _iface_;
	g_return_val_if_fail (self != NULL, NULL);
	_iface_ = GXML_MAPPEABLE_ELEMENT_THREE_KEY_GET_INTERFACE (self);
	if (_iface_->get_map_skey) {
		return _iface_->get_map_skey (self);
	}
	return NULL;
}

/**
   * Returns third key of collection.
   */
gchar*
gxml_mappeable_element_three_key_get_map_tkey (GXmlMappeableElementThreeKey* self)
{
	GXmlMappeableElementThreeKeyIface* _iface_;
	g_return_val_if_fail (self != NULL, NULL);
	_iface_ = GXML_MAPPEABLE_ELEMENT_THREE_KEY_GET_INTERFACE (self);
	if (_iface_->get_map_tkey) {
		return _iface_->get_map_tkey (self);
	}
	return NULL;
}

static void
gxml_mappeable_element_three_key_default_init (GXmlMappeableElementThreeKeyIface * iface,
                                               gpointer iface_data)
{
}

/**
 * Interface to be implemented by {@link GXml.Collection} derived classes
 * in order to provide a string to be used in {@link GXml.HashThreeMap} as key.
 *
 * If {@link GXml.HashMap} has set its {@link GXml.HashMap.attribute_key}
 * its value has precedence over this method.
 */
static GType
gxml_mappeable_element_three_key_get_type_once (void)
{
	static const GTypeInfo g_define_type_info = { sizeof (GXmlMappeableElementThreeKeyIface), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) gxml_mappeable_element_three_key_default_init, (GClassFinalizeFunc) NULL, NULL, 0, 0, (GInstanceInitFunc) NULL, NULL };
	GType gxml_mappeable_element_three_key_type_id;
	gxml_mappeable_element_three_key_type_id = g_type_register_static (G_TYPE_INTERFACE, "GXmlMappeableElementThreeKey", &g_define_type_info, 0);
	g_type_interface_add_prerequisite (gxml_mappeable_element_three_key_type_id, G_TYPE_OBJECT);
	g_type_interface_add_prerequisite (gxml_mappeable_element_three_key_type_id, GXML_TYPE_DOM_ELEMENT);
	return gxml_mappeable_element_three_key_type_id;
}

GType
gxml_mappeable_element_three_key_get_type (void)
{
	static volatile gsize gxml_mappeable_element_three_key_type_id__once = 0;
	if (g_once_init_enter (&gxml_mappeable_element_three_key_type_id__once)) {
		GType gxml_mappeable_element_three_key_type_id;
		gxml_mappeable_element_three_key_type_id = gxml_mappeable_element_three_key_get_type_once ();
		g_once_init_leave (&gxml_mappeable_element_three_key_type_id__once, gxml_mappeable_element_three_key_type_id);
	}
	return gxml_mappeable_element_three_key_type_id__once;
}

const gchar*
gxml_three_map_get_attribute_primary_key (GXmlThreeMap* self)
{
	GXmlThreeMapIface* _iface_;
	g_return_val_if_fail (self != NULL, NULL);
	_iface_ = GXML_THREE_MAP_GET_INTERFACE (self);
	if (_iface_->get_attribute_primary_key) {
		return _iface_->get_attribute_primary_key (self);
	}
	return NULL;
}

void
gxml_three_map_set_attribute_primary_key (GXmlThreeMap* self,
                                          const gchar* value)
{
	GXmlThreeMapIface* _iface_;
	g_return_if_fail (self != NULL);
	_iface_ = GXML_THREE_MAP_GET_INTERFACE (self);
	if (_iface_->set_attribute_primary_key) {
		_iface_->set_attribute_primary_key (self, value);
	}
}

const gchar*
gxml_three_map_get_attribute_secondary_key (GXmlThreeMap* self)
{
	GXmlThreeMapIface* _iface_;
	g_return_val_if_fail (self != NULL, NULL);
	_iface_ = GXML_THREE_MAP_GET_INTERFACE (self);
	if (_iface_->get_attribute_secondary_key) {
		return _iface_->get_attribute_secondary_key (self);
	}
	return NULL;
}

void
gxml_three_map_set_attribute_secondary_key (GXmlThreeMap* self,
                                            const gchar* value)
{
	GXmlThreeMapIface* _iface_;
	g_return_if_fail (self != NULL);
	_iface_ = GXML_THREE_MAP_GET_INTERFACE (self);
	if (_iface_->set_attribute_secondary_key) {
		_iface_->set_attribute_secondary_key (self, value);
	}
}

const gchar*
gxml_three_map_get_attribute_third_key (GXmlThreeMap* self)
{
	GXmlThreeMapIface* _iface_;
	g_return_val_if_fail (self != NULL, NULL);
	_iface_ = GXML_THREE_MAP_GET_INTERFACE (self);
	if (_iface_->get_attribute_third_key) {
		return _iface_->get_attribute_third_key (self);
	}
	return NULL;
}

void
gxml_three_map_set_attribute_third_key (GXmlThreeMap* self,
                                        const gchar* value)
{
	GXmlThreeMapIface* _iface_;
	g_return_if_fail (self != NULL);
	_iface_ = GXML_THREE_MAP_GET_INTERFACE (self);
	if (_iface_->set_attribute_third_key) {
		_iface_->set_attribute_third_key (self, value);
	}
}

GeeSet*
gxml_three_map_get_primary_keys_set (GXmlThreeMap* self)
{
	GXmlThreeMapIface* _iface_;
	g_return_val_if_fail (self != NULL, NULL);
	_iface_ = GXML_THREE_MAP_GET_INTERFACE (self);
	if (_iface_->get_primary_keys_set) {
		return _iface_->get_primary_keys_set (self);
	}
	return NULL;
}

/**
   * Returns an {@link DomElement} in the collection using given string keys.
   */
GXmlDomElement*
gxml_three_map_item (GXmlThreeMap* self,
                     const gchar* primary_key,
                     const gchar* secondary_key,
                     const gchar* third_key)
{
	GXmlThreeMapIface* _iface_;
	g_return_val_if_fail (self != NULL, NULL);
	_iface_ = GXML_THREE_MAP_GET_INTERFACE (self);
	if (_iface_->item) {
		return _iface_->item (self, primary_key, secondary_key, third_key);
	}
	return NULL;
}

/**
   * Returns true if @key is used in collection as primary key.
   */
gboolean
gxml_three_map_has_primary_key (GXmlThreeMap* self,
                                const gchar* key)
{
	GXmlThreeMapIface* _iface_;
	g_return_val_if_fail (self != NULL, FALSE);
	_iface_ = GXML_THREE_MAP_GET_INTERFACE (self);
	if (_iface_->has_primary_key) {
		return _iface_->has_primary_key (self, key);
	}
	return FALSE;
}

/**
   * Returns true if @key is used in collection as secondary key
   * with @pkey as primary.
   */
gboolean
gxml_three_map_has_secondary_key (GXmlThreeMap* self,
                                  const gchar* pkey,
                                  const gchar* key)
{
	GXmlThreeMapIface* _iface_;
	g_return_val_if_fail (self != NULL, FALSE);
	_iface_ = GXML_THREE_MAP_GET_INTERFACE (self);
	if (_iface_->has_secondary_key) {
		return _iface_->has_secondary_key (self, pkey, key);
	}
	return FALSE;
}

/**
   * Returns true if @key is used in collection as third key with secondary key
   * and pkey as primary.
   */
gboolean
gxml_three_map_has_third_key (GXmlThreeMap* self,
                              const gchar* pkey,
                              const gchar* skey,
                              const gchar* key)
{
	GXmlThreeMapIface* _iface_;
	g_return_val_if_fail (self != NULL, FALSE);
	_iface_ = GXML_THREE_MAP_GET_INTERFACE (self);
	if (_iface_->has_third_key) {
		return _iface_->has_third_key (self, pkey, skey, key);
	}
	return FALSE;
}

/**
   * Returns list of secondary keys used in collection with @pkey as primary key.
   */
GeeSet*
gxml_three_map_secondary_keys_set (GXmlThreeMap* self,
                                   const gchar* pkey)
{
	GXmlThreeMapIface* _iface_;
	g_return_val_if_fail (self != NULL, NULL);
	_iface_ = GXML_THREE_MAP_GET_INTERFACE (self);
	if (_iface_->secondary_keys_set) {
		return _iface_->secondary_keys_set (self, pkey);
	}
	return NULL;
}

/**
   * Returns list of third keys used in collection with pkey as primary key
   * and skey as secondary key.
   */
GeeSet*
gxml_three_map_third_keys_set (GXmlThreeMap* self,
                               const gchar* pkey,
                               const gchar* skey)
{
	GXmlThreeMapIface* _iface_;
	g_return_val_if_fail (self != NULL, NULL);
	_iface_ = GXML_THREE_MAP_GET_INTERFACE (self);
	if (_iface_->third_keys_set) {
		return _iface_->third_keys_set (self, pkey, skey);
	}
	return NULL;
}

static void
gxml_three_map_default_init (GXmlThreeMapIface * iface,
                             gpointer iface_data)
{
	/**
	   * An attribute's name in items to be added and used to retrieve elements
	   * as primary key.
	   */
	g_object_interface_install_property (iface, g_param_spec_string ("attribute-primary-key", "attribute-primary-key", "attribute-primary-key", NULL, G_PARAM_STATIC_STRINGS | G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT));
	/**
	   * An attribute's name in items to be added and used to retrieve elements
	   * as secondary key.
	   */
	g_object_interface_install_property (iface, g_param_spec_string ("attribute-secondary-key", "attribute-secondary-key", "attribute-secondary-key", NULL, G_PARAM_STATIC_STRINGS | G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT));
	/**
	   * An attribute's name in items to be added and used to retrieve elements
	   * as third key.
	   */
	g_object_interface_install_property (iface, g_param_spec_string ("attribute-third-key", "attribute-third-key", "attribute-third-key", NULL, G_PARAM_STATIC_STRINGS | G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT));
	/**
	   * Returns list of primary keys used in collection.
	   */
	g_object_interface_install_property (iface, g_param_spec_object ("primary-keys-set", "primary-keys-set", "primary-keys-set", GEE_TYPE_SET, G_PARAM_STATIC_STRINGS | G_PARAM_READABLE));
}

/**
 * {@link Gee.Iterable} and {@link Gee.Traversable} implementation of {@link GXml.Collection}
 */
static GType
gxml_three_map_get_type_once (void)
{
	static const GTypeInfo g_define_type_info = { sizeof (GXmlThreeMapIface), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) gxml_three_map_default_init, (GClassFinalizeFunc) NULL, NULL, 0, 0, (GInstanceInitFunc) NULL, NULL };
	GType gxml_three_map_type_id;
	gxml_three_map_type_id = g_type_register_static (G_TYPE_INTERFACE, "GXmlThreeMap", &g_define_type_info, 0);
	g_type_interface_add_prerequisite (gxml_three_map_type_id, G_TYPE_OBJECT);
	g_type_interface_add_prerequisite (gxml_three_map_type_id, GXML_TYPE_COLLECTION);
	g_type_interface_add_prerequisite (gxml_three_map_type_id, GEE_TYPE_TRAVERSABLE);
	g_type_interface_add_prerequisite (gxml_three_map_type_id, GEE_TYPE_ITERABLE);
	return gxml_three_map_type_id;
}

GType
gxml_three_map_get_type (void)
{
	static volatile gsize gxml_three_map_type_id__once = 0;
	if (g_once_init_enter (&gxml_three_map_type_id__once)) {
		GType gxml_three_map_type_id;
		gxml_three_map_type_id = gxml_three_map_get_type_once ();
		g_once_init_leave (&gxml_three_map_type_id__once, gxml_three_map_type_id);
	}
	return gxml_three_map_type_id__once;
}

GHashTable*
gxml_collection_parent_get_types (GXmlCollectionParent* self)
{
	GXmlCollectionParentIface* _iface_;
	g_return_val_if_fail (self != NULL, NULL);
	_iface_ = GXML_COLLECTION_PARENT_GET_INTERFACE (self);
	if (_iface_->get_types) {
		return _iface_->get_types (self);
	}
	return NULL;
}

static void
_g_free0_ (gpointer var)
{
	var = (g_free (var), NULL);
}

static GHashTable*
gxml_collection_parent_real_get_types (GXmlCollectionParent* base)
{
	GHashTable* result;
	GXmlCollectionParent* self;
	GHashFunc _tmp0_;
	GEqualFunc _tmp1_;
	GHashTable* _tmp2_;
	self = base;
	_tmp0_ = g_str_hash;
	_tmp1_ = g_str_equal;
	_tmp2_ = g_hash_table_new_full (_tmp0_, _tmp1_, _g_free0_, NULL);
	result = _tmp2_;
	return result;
}

/**
   * Insert a new supported instantiatable type in given hash table, by
   * instantiating the type, getting its node's local name
   * as key.
   *
   * @param types a {@link GLib.HashTable} to hold supported types
   * @param parent_type a {@link GLib.Type} as parent of supported types, it is
   * not necesarry to be an instantiatable type, like interfaces, should be
   * the same of {@link GXml.Collection.items_type}
   * @param type a supported instantiatable {@link GLib.Type}
   * to be added in the collection
   */
void
gxml_collection_parent_add_supported_type (GHashTable* types,
                                           GType parent_type,
                                           GType type)
{
	GXmlElement* o = NULL;
	GObject* _tmp0_;
	GObject* _tmp1_;
	GXmlElement* _tmp2_;
	gchar* name = NULL;
	gchar* _tmp3_;
	gchar* _tmp4_;
	gchar* _tmp5_;
	gchar* _tmp6_;
	gchar* _tmp7_;
	gchar* _tmp8_;
	gchar* _tmp9_;
	gchar* _tmp10_;
	g_return_if_fail (types != NULL);
	_vala_return_if_fail (g_type_is_a (type, GXML_TYPE_ELEMENT), "type.is_a (typeof (GXml.Element))");
	_tmp0_ = g_object_new (type, NULL);
	_tmp1_ = G_IS_INITIALLY_UNOWNED (_tmp0_) ? g_object_ref_sink (_tmp0_) : _tmp0_;
	_tmp2_ = GXML_IS_ELEMENT (_tmp1_) ? ((GXmlElement*) _tmp1_) : NULL;
	if (_tmp2_ == NULL) {
		_g_object_unref0 (_tmp1_);
	}
	o = _tmp2_;
	_tmp3_ = gxml_dom_element_get_local_name ((GXmlDomElement*) o);
	_tmp4_ = _tmp3_;
	_tmp5_ = _tmp4_;
	_tmp6_ = g_utf8_strdown (_tmp5_, (gssize) -1);
	_tmp7_ = _tmp6_;
	_tmp8_ = g_strdup (_tmp7_);
	_tmp9_ = _tmp8_;
	_g_free0 (_tmp7_);
	_g_free0 (_tmp5_);
	name = _tmp9_;
	_tmp10_ = g_strdup (name);
	g_hash_table_insert (types, _tmp10_, (gpointer) ((gintptr) type));
	_g_free0 (name);
	_g_object_unref0 (o);
}

/**
   * Insert a set of supported instantiatable type in given hash table, by
   * instantiating the type, getting its node's local name
   * as key.
   *
   * @param table a {@link GLib.HashTable} to hold supported types
   * @param parent_type a {@link GLib.Type} as parent of supported types, it is
   * not necesarry to be an instantiatable type, like interfaces, should be
   * the same of {@link GXml.Collection.items_type}
   * @param types an array of supported instantiatable {@link GLib.Type}
   * to be added in the collection
   */
void
gxml_collection_parent_add_supported_types (GHashTable* table,
                                            GType parent_type,
                                            GType* types,
                                            gint types_length1)
{
	g_return_if_fail (table != NULL);
	{
		gint i = 0;
		i = 0;
		{
			gboolean _tmp0_ = FALSE;
			_tmp0_ = TRUE;
			while (TRUE) {
				GType _tmp2_;
				if (!_tmp0_) {
					gint _tmp1_;
					_tmp1_ = i;
					i = _tmp1_ + 1;
				}
				_tmp0_ = FALSE;
				if (!(i < types_length1)) {
					break;
				}
				_tmp2_ = types[i];
				gxml_collection_parent_add_supported_type (table, parent_type, _tmp2_);
			}
		}
	}
}

static void
gxml_collection_parent_default_init (GXmlCollectionParentIface * iface,
                                     gpointer iface_data)
{
	iface->get_types = gxml_collection_parent_real_get_types;
}

/**
 * Collection to manage child {@link GXml.DomElement} objects
 * mapped to different classes, derived or child type of
 * {@link Collection.items_type}
 *
 * A collection using {@link Collection.items_type} as a common
 * parent {@link GLib.Type} of a set of instantiatable {@link GLib.Type}.
 *
 * In the next example, is possible to setup a class for Top element,
 * having a {@link GXml.CollectionParent} implementation class, supporting
 * reading any kind of derived classes from the {@link Collection.items_type};
 * for the example, Time, Goal and Reque are implementations of, say, Child
 * interface, so they will be added to the collection and deserialized
 * as an instance of the object, based in the node's name.
 *
 * {{{
 * <Top>
 *   <Time/>
 *   <Goal/>
 *   <Resque/>
 * }}}
 *
 * Implementators, should override {@link types} property
 * setting up a hash table and use {@link add_supported_type} or
 * {@link add_supported_types} to add one or a set of types to be supported.
 * {@link types} is used by {@link GXml.Parser} to detect the types
 * suuported in a collection to create the corresponding objects of the
 * currect instantiable {@link GLib.Type} at runtime, adding them to the
 * collection, corresponding to the element's tag's name.
 */
static GType
gxml_collection_parent_get_type_once (void)
{
	static const GTypeInfo g_define_type_info = { sizeof (GXmlCollectionParentIface), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) gxml_collection_parent_default_init, (GClassFinalizeFunc) NULL, NULL, 0, 0, (GInstanceInitFunc) NULL, NULL };
	GType gxml_collection_parent_type_id;
	gxml_collection_parent_type_id = g_type_register_static (G_TYPE_INTERFACE, "GXmlCollectionParent", &g_define_type_info, 0);
	g_type_interface_add_prerequisite (gxml_collection_parent_type_id, G_TYPE_OBJECT);
	g_type_interface_add_prerequisite (gxml_collection_parent_type_id, GXML_TYPE_COLLECTION);
	return gxml_collection_parent_type_id;
}

GType
gxml_collection_parent_get_type (void)
{
	static volatile gsize gxml_collection_parent_type_id__once = 0;
	if (g_once_init_enter (&gxml_collection_parent_type_id__once)) {
		GType gxml_collection_parent_type_id;
		gxml_collection_parent_type_id = gxml_collection_parent_get_type_once ();
		g_once_init_leave (&gxml_collection_parent_type_id__once, gxml_collection_parent_type_id);
	}
	return gxml_collection_parent_type_id__once;
}

