/* utils.c generated by valac 0.17.6.5-65f99, the Vala compiler
 * generated from utils.vala, do not modify */

/*
 * Copyright (C) 2011 Collabora Ltd.
 *
 * 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:
 *       Raul Gutierrez Segales <raul.gutierrez.segales@collabora.co.uk>
 *       Travis Reitter <travis.reitter@collabora.co.uk>
 */

#include <glib.h>
#include <glib-object.h>
#include <stdlib.h>
#include <string.h>
#include <gee.h>


#define FOLKS_TYPE_UTILS (folks_utils_get_type ())
#define FOLKS_UTILS(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), FOLKS_TYPE_UTILS, FolksUtils))
#define FOLKS_UTILS_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), FOLKS_TYPE_UTILS, FolksUtilsClass))
#define FOLKS_IS_UTILS(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), FOLKS_TYPE_UTILS))
#define FOLKS_IS_UTILS_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), FOLKS_TYPE_UTILS))
#define FOLKS_UTILS_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), FOLKS_TYPE_UTILS, FolksUtilsClass))

typedef struct _FolksUtils FolksUtils;
typedef struct _FolksUtilsClass FolksUtilsClass;
typedef struct _FolksUtilsPrivate FolksUtilsPrivate;
#define _g_free0(var) (var = (g_free (var), NULL))
#define _g_object_unref0(var) ((var == NULL) ? NULL : (var = (g_object_unref (var), NULL)))

#define FOLKS_TYPE_ABSTRACT_FIELD_DETAILS (folks_abstract_field_details_get_type ())
#define FOLKS_ABSTRACT_FIELD_DETAILS(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), FOLKS_TYPE_ABSTRACT_FIELD_DETAILS, FolksAbstractFieldDetails))
#define FOLKS_ABSTRACT_FIELD_DETAILS_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), FOLKS_TYPE_ABSTRACT_FIELD_DETAILS, FolksAbstractFieldDetailsClass))
#define FOLKS_IS_ABSTRACT_FIELD_DETAILS(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), FOLKS_TYPE_ABSTRACT_FIELD_DETAILS))
#define FOLKS_IS_ABSTRACT_FIELD_DETAILS_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), FOLKS_TYPE_ABSTRACT_FIELD_DETAILS))
#define FOLKS_ABSTRACT_FIELD_DETAILS_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), FOLKS_TYPE_ABSTRACT_FIELD_DETAILS, FolksAbstractFieldDetailsClass))

typedef struct _FolksAbstractFieldDetails FolksAbstractFieldDetails;
typedef struct _FolksAbstractFieldDetailsClass FolksAbstractFieldDetailsClass;

struct _FolksUtils {
	GObject parent_instance;
	FolksUtilsPrivate * priv;
};

struct _FolksUtilsClass {
	GObjectClass parent_class;
};


static gpointer folks_utils_parent_class = NULL;

GType folks_utils_get_type (void) G_GNUC_CONST;
enum  {
	FOLKS_UTILS_DUMMY_PROPERTY
};
gboolean _folks_utils_str_equal_safe (const gchar* a, const gchar* b);
FolksUtils* folks_utils_new (void) G_GNUC_DEPRECATED;
FolksUtils* folks_utils_construct (GType object_type);
gboolean folks_utils_multi_map_str_str_equal (GeeMultiMap* a, GeeMultiMap* b);
GType folks_abstract_field_details_get_type (void) G_GNUC_CONST;
gboolean folks_utils_multi_map_str_afd_equal (GeeMultiMap* a, GeeMultiMap* b);
gboolean folks_utils_set_afd_equal (GeeSet* a, GeeSet* b);


gboolean _folks_utils_str_equal_safe (const gchar* a, const gchar* b) {
	gboolean result = FALSE;
	gboolean _tmp0_ = FALSE;
	gboolean _tmp1_ = FALSE;
	const gchar* _tmp2_;
	gboolean _tmp4_;
	gboolean _tmp11_;
	g_return_val_if_fail (a != NULL, FALSE);
	g_return_val_if_fail (b != NULL, FALSE);
	_tmp2_ = a;
	if (g_strcmp0 (_tmp2_, "") != 0) {
		const gchar* _tmp3_;
		_tmp3_ = b;
		_tmp1_ = g_strcmp0 (_tmp3_, "") != 0;
	} else {
		_tmp1_ = FALSE;
	}
	_tmp4_ = _tmp1_;
	if (_tmp4_) {
		const gchar* _tmp5_;
		gchar* _tmp6_ = NULL;
		gchar* _tmp7_;
		const gchar* _tmp8_;
		gchar* _tmp9_ = NULL;
		gchar* _tmp10_;
		_tmp5_ = a;
		_tmp6_ = g_utf8_strdown (_tmp5_, (gssize) (-1));
		_tmp7_ = _tmp6_;
		_tmp8_ = b;
		_tmp9_ = g_utf8_strdown (_tmp8_, (gssize) (-1));
		_tmp10_ = _tmp9_;
		_tmp0_ = g_strcmp0 (_tmp7_, _tmp10_) == 0;
		_g_free0 (_tmp10_);
		_g_free0 (_tmp7_);
	} else {
		_tmp0_ = FALSE;
	}
	_tmp11_ = _tmp0_;
	result = _tmp11_;
	return result;
}


/**
   * Create a new utilities object.
   *
   * This method is useless and should never be used. It will be removed in a
   * future version in favour of making the Utils class into a nested namespace.
   *
   * @return a new utilities object
   * @since 0.6.0
   */
FolksUtils* folks_utils_construct (GType object_type) {
	FolksUtils * self = NULL;
	self = (FolksUtils*) g_object_new (object_type, NULL);
	return self;
}


FolksUtils* folks_utils_new (void) {
	return folks_utils_construct (FOLKS_TYPE_UTILS);
}


/**
   * Check whether two multi-maps of strings to strings are equal. This performs
   * a deep check for equality, checking whether both maps are of the same size,
   * and that each key maps to the same set of values in both maps.
   *
   * @param a a multi-map to compare
   * @param b another multi-map to compare
   * @return ``true`` if the multi-maps are equal, ``false`` otherwise
   *
   * @since 0.6.0
   */
gboolean folks_utils_multi_map_str_str_equal (GeeMultiMap* a, GeeMultiMap* b) {
	gboolean result = FALSE;
	GeeMultiMap* _tmp0_;
	GeeMultiMap* _tmp1_;
	GeeMultiMap* _tmp2_;
	gint _tmp3_;
	gint _tmp4_;
	GeeMultiMap* _tmp5_;
	gint _tmp6_;
	gint _tmp7_;
	g_return_val_if_fail (a != NULL, FALSE);
	g_return_val_if_fail (b != NULL, FALSE);
	_tmp0_ = a;
	_tmp1_ = b;
	if (_tmp0_ == _tmp1_) {
		result = TRUE;
		return result;
	}
	_tmp2_ = a;
	_tmp3_ = gee_multi_map_get_size (_tmp2_);
	_tmp4_ = _tmp3_;
	_tmp5_ = b;
	_tmp6_ = gee_multi_map_get_size (_tmp5_);
	_tmp7_ = _tmp6_;
	if (_tmp4_ == _tmp7_) {
		{
			GeeMultiMap* _tmp8_;
			GeeSet* _tmp9_ = NULL;
			GeeSet* _tmp10_;
			GeeIterator* _tmp11_ = NULL;
			GeeIterator* _tmp12_;
			GeeIterator* _key_it;
			_tmp8_ = a;
			_tmp9_ = gee_multi_map_get_keys (_tmp8_);
			_tmp10_ = _tmp9_;
			_tmp11_ = gee_iterable_iterator ((GeeIterable*) _tmp10_);
			_tmp12_ = _tmp11_;
			_g_object_unref0 (_tmp10_);
			_key_it = _tmp12_;
			while (TRUE) {
				GeeIterator* _tmp13_;
				gboolean _tmp14_ = FALSE;
				GeeIterator* _tmp15_;
				gpointer _tmp16_ = NULL;
				gchar* key;
				GeeMultiMap* _tmp17_;
				const gchar* _tmp18_;
				gboolean _tmp19_ = FALSE;
				_tmp13_ = _key_it;
				_tmp14_ = gee_iterator_next (_tmp13_);
				if (!_tmp14_) {
					break;
				}
				_tmp15_ = _key_it;
				_tmp16_ = gee_iterator_get (_tmp15_);
				key = (gchar*) _tmp16_;
				_tmp17_ = b;
				_tmp18_ = key;
				_tmp19_ = gee_multi_map_contains (_tmp17_, _tmp18_);
				if (_tmp19_) {
					GeeMultiMap* _tmp20_;
					const gchar* _tmp21_;
					GeeCollection* _tmp22_ = NULL;
					GeeCollection* a_values;
					GeeMultiMap* _tmp23_;
					const gchar* _tmp24_;
					GeeCollection* _tmp25_ = NULL;
					GeeCollection* b_values;
					GeeCollection* _tmp26_;
					gint _tmp27_;
					gint _tmp28_;
					GeeCollection* _tmp29_;
					gint _tmp30_;
					gint _tmp31_;
					_tmp20_ = a;
					_tmp21_ = key;
					_tmp22_ = gee_multi_map_get (_tmp20_, _tmp21_);
					a_values = _tmp22_;
					_tmp23_ = b;
					_tmp24_ = key;
					_tmp25_ = gee_multi_map_get (_tmp23_, _tmp24_);
					b_values = _tmp25_;
					_tmp26_ = a_values;
					_tmp27_ = gee_collection_get_size (_tmp26_);
					_tmp28_ = _tmp27_;
					_tmp29_ = b_values;
					_tmp30_ = gee_collection_get_size (_tmp29_);
					_tmp31_ = _tmp30_;
					if (_tmp28_ != _tmp31_) {
						result = FALSE;
						_g_object_unref0 (b_values);
						_g_object_unref0 (a_values);
						_g_free0 (key);
						_g_object_unref0 (_key_it);
						return result;
					}
					{
						GeeCollection* _tmp32_;
						GeeIterator* _tmp33_ = NULL;
						GeeIterator* _a_value_it;
						_tmp32_ = a_values;
						_tmp33_ = gee_iterable_iterator ((GeeIterable*) _tmp32_);
						_a_value_it = _tmp33_;
						while (TRUE) {
							GeeIterator* _tmp34_;
							gboolean _tmp35_ = FALSE;
							GeeIterator* _tmp36_;
							gpointer _tmp37_ = NULL;
							gchar* a_value;
							GeeCollection* _tmp38_;
							const gchar* _tmp39_;
							gboolean _tmp40_ = FALSE;
							_tmp34_ = _a_value_it;
							_tmp35_ = gee_iterator_next (_tmp34_);
							if (!_tmp35_) {
								break;
							}
							_tmp36_ = _a_value_it;
							_tmp37_ = gee_iterator_get (_tmp36_);
							a_value = (gchar*) _tmp37_;
							_tmp38_ = b_values;
							_tmp39_ = a_value;
							_tmp40_ = gee_collection_contains (_tmp38_, _tmp39_);
							if (!_tmp40_) {
								result = FALSE;
								_g_free0 (a_value);
								_g_object_unref0 (_a_value_it);
								_g_object_unref0 (b_values);
								_g_object_unref0 (a_values);
								_g_free0 (key);
								_g_object_unref0 (_key_it);
								return result;
							}
							_g_free0 (a_value);
						}
						_g_object_unref0 (_a_value_it);
					}
					_g_object_unref0 (b_values);
					_g_object_unref0 (a_values);
				} else {
					result = FALSE;
					_g_free0 (key);
					_g_object_unref0 (_key_it);
					return result;
				}
				_g_free0 (key);
			}
			_g_object_unref0 (_key_it);
		}
	} else {
		result = FALSE;
		return result;
	}
	result = TRUE;
	return result;
}


/**
   * Check whether two multi-maps of strings to AbstractFieldDetails are equal.
   *
   * This performs a deep check for equality, checking whether both maps are of
   * the same size, and that each key maps to the same set of values in both
   * maps.
   *
   * @param a a multi-map to compare
   * @param b another multi-map to compare
   * @return ``true`` if the multi-maps are equal, ``false`` otherwise
   *
   * @since 0.6.0
   */
gboolean folks_utils_multi_map_str_afd_equal (GeeMultiMap* a, GeeMultiMap* b) {
	gboolean result = FALSE;
	GeeMultiMap* _tmp0_;
	GeeMultiMap* _tmp1_;
	GeeMultiMap* _tmp2_;
	gint _tmp3_;
	gint _tmp4_;
	GeeMultiMap* _tmp5_;
	gint _tmp6_;
	gint _tmp7_;
	g_return_val_if_fail (a != NULL, FALSE);
	g_return_val_if_fail (b != NULL, FALSE);
	_tmp0_ = a;
	_tmp1_ = b;
	if (_tmp0_ == _tmp1_) {
		result = TRUE;
		return result;
	}
	_tmp2_ = a;
	_tmp3_ = gee_multi_map_get_size (_tmp2_);
	_tmp4_ = _tmp3_;
	_tmp5_ = b;
	_tmp6_ = gee_multi_map_get_size (_tmp5_);
	_tmp7_ = _tmp6_;
	if (_tmp4_ == _tmp7_) {
		{
			GeeMultiMap* _tmp8_;
			GeeSet* _tmp9_ = NULL;
			GeeSet* _tmp10_;
			GeeIterator* _tmp11_ = NULL;
			GeeIterator* _tmp12_;
			GeeIterator* _key_it;
			_tmp8_ = a;
			_tmp9_ = gee_multi_map_get_keys (_tmp8_);
			_tmp10_ = _tmp9_;
			_tmp11_ = gee_iterable_iterator ((GeeIterable*) _tmp10_);
			_tmp12_ = _tmp11_;
			_g_object_unref0 (_tmp10_);
			_key_it = _tmp12_;
			while (TRUE) {
				GeeIterator* _tmp13_;
				gboolean _tmp14_ = FALSE;
				GeeIterator* _tmp15_;
				gpointer _tmp16_ = NULL;
				gchar* key;
				GeeMultiMap* _tmp17_;
				const gchar* _tmp18_;
				gboolean _tmp19_ = FALSE;
				_tmp13_ = _key_it;
				_tmp14_ = gee_iterator_next (_tmp13_);
				if (!_tmp14_) {
					break;
				}
				_tmp15_ = _key_it;
				_tmp16_ = gee_iterator_get (_tmp15_);
				key = (gchar*) _tmp16_;
				_tmp17_ = b;
				_tmp18_ = key;
				_tmp19_ = gee_multi_map_contains (_tmp17_, _tmp18_);
				if (_tmp19_) {
					GeeMultiMap* _tmp20_;
					const gchar* _tmp21_;
					GeeCollection* _tmp22_ = NULL;
					GeeCollection* a_values;
					GeeMultiMap* _tmp23_;
					const gchar* _tmp24_;
					GeeCollection* _tmp25_ = NULL;
					GeeCollection* b_values;
					GeeCollection* _tmp26_;
					gint _tmp27_;
					gint _tmp28_;
					GeeCollection* _tmp29_;
					gint _tmp30_;
					gint _tmp31_;
					_tmp20_ = a;
					_tmp21_ = key;
					_tmp22_ = gee_multi_map_get (_tmp20_, _tmp21_);
					a_values = _tmp22_;
					_tmp23_ = b;
					_tmp24_ = key;
					_tmp25_ = gee_multi_map_get (_tmp23_, _tmp24_);
					b_values = _tmp25_;
					_tmp26_ = a_values;
					_tmp27_ = gee_collection_get_size (_tmp26_);
					_tmp28_ = _tmp27_;
					_tmp29_ = b_values;
					_tmp30_ = gee_collection_get_size (_tmp29_);
					_tmp31_ = _tmp30_;
					if (_tmp28_ != _tmp31_) {
						result = FALSE;
						_g_object_unref0 (b_values);
						_g_object_unref0 (a_values);
						_g_free0 (key);
						_g_object_unref0 (_key_it);
						return result;
					}
					{
						GeeCollection* _tmp32_;
						GeeIterator* _tmp33_ = NULL;
						GeeIterator* _a_value_it;
						_tmp32_ = a_values;
						_tmp33_ = gee_iterable_iterator ((GeeIterable*) _tmp32_);
						_a_value_it = _tmp33_;
						while (TRUE) {
							GeeIterator* _tmp34_;
							gboolean _tmp35_ = FALSE;
							GeeIterator* _tmp36_;
							gpointer _tmp37_ = NULL;
							FolksAbstractFieldDetails* a_value;
							GeeCollection* _tmp38_;
							FolksAbstractFieldDetails* _tmp39_;
							gboolean _tmp40_ = FALSE;
							_tmp34_ = _a_value_it;
							_tmp35_ = gee_iterator_next (_tmp34_);
							if (!_tmp35_) {
								break;
							}
							_tmp36_ = _a_value_it;
							_tmp37_ = gee_iterator_get (_tmp36_);
							a_value = (FolksAbstractFieldDetails*) _tmp37_;
							_tmp38_ = b_values;
							_tmp39_ = a_value;
							_tmp40_ = gee_collection_contains (_tmp38_, _tmp39_);
							if (!_tmp40_) {
								result = FALSE;
								_g_object_unref0 (a_value);
								_g_object_unref0 (_a_value_it);
								_g_object_unref0 (b_values);
								_g_object_unref0 (a_values);
								_g_free0 (key);
								_g_object_unref0 (_key_it);
								return result;
							}
							_g_object_unref0 (a_value);
						}
						_g_object_unref0 (_a_value_it);
					}
					_g_object_unref0 (b_values);
					_g_object_unref0 (a_values);
				} else {
					result = FALSE;
					_g_free0 (key);
					_g_object_unref0 (_key_it);
					return result;
				}
				_g_free0 (key);
			}
			_g_object_unref0 (_key_it);
		}
	} else {
		result = FALSE;
		return result;
	}
	result = TRUE;
	return result;
}


/**
   * Check whether a set of strings to AbstractFieldDetails are equal.
   *
   * This performs a deep check for equality, checking whether both sets are of
   * the same size, and that each key maps to the same set of values in both
   * maps.
   *
   * @param a a set to compare
   * @param b another set to compare
   * @return ``true`` if the sets are equal, ``false`` otherwise
   *
   * @since 0.6.0
   */
gboolean folks_utils_set_afd_equal (GeeSet* a, GeeSet* b) {
	gboolean result = FALSE;
	GeeSet* _tmp0_;
	GeeSet* _tmp1_;
	GeeSet* _tmp2_;
	gint _tmp3_;
	gint _tmp4_;
	GeeSet* _tmp5_;
	gint _tmp6_;
	gint _tmp7_;
	g_return_val_if_fail (a != NULL, FALSE);
	g_return_val_if_fail (b != NULL, FALSE);
	_tmp0_ = a;
	_tmp1_ = b;
	if (_tmp0_ == _tmp1_) {
		result = TRUE;
		return result;
	}
	_tmp2_ = a;
	_tmp3_ = gee_collection_get_size ((GeeCollection*) _tmp2_);
	_tmp4_ = _tmp3_;
	_tmp5_ = b;
	_tmp6_ = gee_collection_get_size ((GeeCollection*) _tmp5_);
	_tmp7_ = _tmp6_;
	if (_tmp4_ == _tmp7_) {
		{
			GeeSet* _tmp8_;
			GeeIterator* _tmp9_ = NULL;
			GeeIterator* _val_it;
			_tmp8_ = a;
			_tmp9_ = gee_iterable_iterator ((GeeIterable*) _tmp8_);
			_val_it = _tmp9_;
			while (TRUE) {
				GeeIterator* _tmp10_;
				gboolean _tmp11_ = FALSE;
				GeeIterator* _tmp12_;
				gpointer _tmp13_ = NULL;
				FolksAbstractFieldDetails* val;
				GeeSet* _tmp14_;
				FolksAbstractFieldDetails* _tmp15_;
				gboolean _tmp16_ = FALSE;
				_tmp10_ = _val_it;
				_tmp11_ = gee_iterator_next (_tmp10_);
				if (!_tmp11_) {
					break;
				}
				_tmp12_ = _val_it;
				_tmp13_ = gee_iterator_get (_tmp12_);
				val = (FolksAbstractFieldDetails*) _tmp13_;
				_tmp14_ = b;
				_tmp15_ = val;
				_tmp16_ = gee_collection_contains ((GeeCollection*) _tmp14_, _tmp15_);
				if (!_tmp16_) {
					result = FALSE;
					_g_object_unref0 (val);
					_g_object_unref0 (_val_it);
					return result;
				}
				_g_object_unref0 (val);
			}
			_g_object_unref0 (_val_it);
		}
	} else {
		result = FALSE;
		return result;
	}
	result = TRUE;
	return result;
}


static void folks_utils_class_init (FolksUtilsClass * klass) {
	folks_utils_parent_class = g_type_class_peek_parent (klass);
}


static void folks_utils_instance_init (FolksUtils * self) {
}


/**
 * Utility functions to simplify common patterns in Folks client code.
 *
 * These may be used by folks clients as well, and are part of folks' supported
 * stable API.
 *
 * @since 0.6.0
 */
GType folks_utils_get_type (void) {
	static volatile gsize folks_utils_type_id__volatile = 0;
	if (g_once_init_enter (&folks_utils_type_id__volatile)) {
		static const GTypeInfo g_define_type_info = { sizeof (FolksUtilsClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) folks_utils_class_init, (GClassFinalizeFunc) NULL, NULL, sizeof (FolksUtils), 0, (GInstanceInitFunc) folks_utils_instance_init, NULL };
		GType folks_utils_type_id;
		folks_utils_type_id = g_type_register_static (G_TYPE_OBJECT, "FolksUtils", &g_define_type_info, 0);
		g_once_init_leave (&folks_utils_type_id__volatile, folks_utils_type_id);
	}
	return folks_utils_type_id__volatile;
}



