/* util-i18n.c generated by valac 0.56.3, the Vala compiler
 * generated from util-i18n.vala, do not modify */

/*
 * Copyright © 2016 Software Freedom Conservancy Inc.
 * Copyright © 2020 Michael Gratton <mike@vee.net>
 *
 * This software is licensed under the GNU Lesser General Public License
 * (version 2.1 or later). See the COPYING file in this distribution.
 */

#include <glib.h>
#include <stdlib.h>
#include <string.h>
#include "geary-client-43.0.h"
#include <locale.h>
#include <glib/gi18n-lib.h>
#include <enchant.h>
#include <gio/gio.h>
#include <libxml/tree.h>
#include <libxml/parser.h>
#include "geary-engine.h"

#define _g_free0(var) (var = (g_free (var), NULL))
typedef struct _Block101Data Block101Data;
#define _g_hash_table_unref0(var) ((var == NULL) ? NULL : (var = (g_hash_table_unref (var), NULL)))
#define _enchant_broker_free0(var) ((var == NULL) ? NULL : (var = (enchant_broker_free (var), NULL)))
#define _g_object_unref0(var) ((var == NULL) ? NULL : (var = (g_object_unref (var), NULL)))

struct _Block101Data {
	int _ref_count_;
	gchar** dictionaries;
	gint dictionaries_length1;
	gint _dictionaries_size_;
};

VALA_EXTERN GHashTable* util_i18n_language_names;
GHashTable* util_i18n_language_names = NULL;
VALA_EXTERN GHashTable* util_i18n_country_names;
GHashTable* util_i18n_country_names = NULL;

VALA_EXTERN void util_i18n_init (const gchar* package_name,
                     const gchar* program_path,
                     const gchar* locale);
VALA_EXTERN gchar* util_i18n_get_langpack_dir_path (const gchar* program_path);
static Block101Data* block101_data_ref (Block101Data* _data101_);
static void block101_data_unref (void * _userdata_);
static void __lambda8_ (Block101Data* _data101_,
                 const gchar* lang_tag,
                 const gchar* provider_name,
                 const gchar* provider_desc,
                 const gchar* provider_file);
static void _vala_array_add21 (gchar** * array,
                        gint* length,
                        gint* size,
                        gchar* value);
static void ___lambda8__enchant_dict_describe_fn (const gchar* lang_tag,
                                           const gchar* provider_name,
                                           const gchar* provider_desc,
                                           const gchar* provider_file,
                                           gpointer self);
static void _g_free0_ (gpointer var);
static gint __lambda9_ (const gchar* dic_a,
                 const gchar* dic_b);
static gint ___lambda9__gcompare_func (gconstpointer a,
                                gconstpointer b);
static void _vala_array_add22 (gchar** * array,
                        gint* length,
                        gint* size,
                        gchar* value);
static gchar** _vala_array_dup7 (gchar** self,
                          gssize length);
static inline void _g_list_free__g_free0_ (GList* self);
static void _vala_array_add23 (gchar** * array,
                        gint* length,
                        gint* size,
                        gchar* value);
static void _vala_array_add24 (gchar** * array,
                        gint* length,
                        gint* size,
                        gchar* value);
static void _vala_array_destroy (gpointer array,
                          gssize array_length,
                          GDestroyNotify destroy_func);
static void _vala_array_free (gpointer array,
                       gssize array_length,
                       GDestroyNotify destroy_func);
static gssize _vala_array_length (gpointer array);

void
util_i18n_init (const gchar* package_name,
                const gchar* program_path,
                const gchar* locale)
{
	gchar* _tmp0_;
	gchar* _tmp1_;
	g_return_if_fail (package_name != NULL);
	g_return_if_fail (program_path != NULL);
	g_return_if_fail (locale != NULL);
	setlocale (LC_ALL, locale);
	_tmp0_ = util_i18n_get_langpack_dir_path (program_path);
	_tmp1_ = _tmp0_;
	bindtextdomain (package_name, _tmp1_);
	_g_free0 (_tmp1_);
	bind_textdomain_codeset (package_name, "UTF-8");
	textdomain (package_name);
}

gchar*
util_i18n_get_langpack_dir_path (const gchar* program_path)
{
	gchar* _tmp0_;
	gchar* result;
	g_return_val_if_fail (program_path != NULL, NULL);
	_tmp0_ = g_strdup (_LANGUAGE_SUPPORT_DIRECTORY);
	result = _tmp0_;
	return result;
}

/**
     * Returns a sorted list of installed spell-check dictionary languages.
     *
     * Each language is a POSIX-style locale name (ISO/IEC 15897).
     * The list is generated by obtaining the list from Enchant via
     * {@link Enchant.Broker.list_dicts}, discarding generic languages
     * if a regional variant exists (for example, discard "en" if
     * "en_US" is included), then sorted.
     */
static Block101Data*
block101_data_ref (Block101Data* _data101_)
{
	g_atomic_int_inc (&_data101_->_ref_count_);
	return _data101_;
}

static void
block101_data_unref (void * _userdata_)
{
	Block101Data* _data101_;
	_data101_ = (Block101Data*) _userdata_;
	if (g_atomic_int_dec_and_test (&_data101_->_ref_count_)) {
		_data101_->dictionaries = (_vala_array_free (_data101_->dictionaries, _data101_->dictionaries_length1, (GDestroyNotify) g_free), NULL);
		g_slice_free (Block101Data, _data101_);
	}
}

static void
_vala_array_add21 (gchar** * array,
                   gint* length,
                   gint* size,
                   gchar* value)
{
	if ((*length) == (*size)) {
		*size = (*size) ? (2 * (*size)) : 4;
		*array = g_renew (gchar*, *array, (*size) + 1);
	}
	(*array)[(*length)++] = value;
	(*array)[*length] = NULL;
}

static void
__lambda8_ (Block101Data* _data101_,
            const gchar* lang_tag,
            const gchar* provider_name,
            const gchar* provider_desc,
            const gchar* provider_file)
{
	gchar* _tmp0_;
	g_return_if_fail (lang_tag != NULL);
	g_return_if_fail (provider_name != NULL);
	g_return_if_fail (provider_desc != NULL);
	g_return_if_fail (provider_file != NULL);
	_tmp0_ = g_strdup (lang_tag);
	_vala_array_add21 (&_data101_->dictionaries, &_data101_->dictionaries_length1, &_data101_->_dictionaries_size_, _tmp0_);
}

static void
___lambda8__enchant_dict_describe_fn (const gchar* lang_tag,
                                      const gchar* provider_name,
                                      const gchar* provider_desc,
                                      const gchar* provider_file,
                                      gpointer self)
{
	__lambda8_ (self, lang_tag, provider_name, provider_desc, provider_file);
}

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

static gboolean
string_contains (const gchar* self,
                 const gchar* needle)
{
	gchar* _tmp0_;
	gboolean result;
	g_return_val_if_fail (self != NULL, FALSE);
	g_return_val_if_fail (needle != NULL, FALSE);
	_tmp0_ = strstr ((gchar*) self, (gchar*) needle);
	result = _tmp0_ != NULL;
	return result;
}

static gint
string_index_of_char (const gchar* self,
                      gunichar c,
                      gint start_index)
{
	gchar* _result_ = NULL;
	gchar* _tmp0_;
	gchar* _tmp1_;
	gint result;
	g_return_val_if_fail (self != NULL, 0);
	_tmp0_ = g_utf8_strchr (((gchar*) self) + start_index, (gssize) -1, c);
	_result_ = _tmp0_;
	_tmp1_ = _result_;
	if (_tmp1_ != NULL) {
		gchar* _tmp2_;
		_tmp2_ = _result_;
		result = (gint) (_tmp2_ - ((gchar*) self));
		return result;
	} else {
		result = -1;
		return result;
	}
}

static glong
string_strnlen (gchar* str,
                glong maxlen)
{
	gchar* end = NULL;
	gchar* _tmp0_;
	gchar* _tmp1_;
	glong result;
	_tmp0_ = memchr (str, 0, (gsize) maxlen);
	end = _tmp0_;
	_tmp1_ = end;
	if (_tmp1_ == NULL) {
		result = maxlen;
		return result;
	} else {
		gchar* _tmp2_;
		_tmp2_ = end;
		result = (glong) (_tmp2_ - str);
		return result;
	}
}

static gchar*
string_substring (const gchar* self,
                  glong offset,
                  glong len)
{
	glong string_length = 0L;
	gboolean _tmp0_ = FALSE;
	gchar* _tmp3_;
	gchar* result;
	g_return_val_if_fail (self != NULL, NULL);
	if (offset >= ((glong) 0)) {
		_tmp0_ = len >= ((glong) 0);
	} else {
		_tmp0_ = FALSE;
	}
	if (_tmp0_) {
		string_length = string_strnlen ((gchar*) self, offset + len);
	} else {
		gint _tmp1_;
		gint _tmp2_;
		_tmp1_ = strlen (self);
		_tmp2_ = _tmp1_;
		string_length = (glong) _tmp2_;
	}
	if (offset < ((glong) 0)) {
		offset = string_length + offset;
		g_return_val_if_fail (offset >= ((glong) 0), NULL);
	} else {
		g_return_val_if_fail (offset <= string_length, NULL);
	}
	if (len < ((glong) 0)) {
		len = string_length - offset;
	}
	g_return_val_if_fail ((offset + len) <= string_length, NULL);
	_tmp3_ = g_strndup (((gchar*) self) + offset, (gsize) len);
	result = _tmp3_;
	return result;
}

static gint
__lambda9_ (const gchar* dic_a,
            const gchar* dic_b)
{
	gint _tmp0_ = 0;
	gint result;
	g_return_val_if_fail (dic_a != NULL, 0);
	g_return_val_if_fail (dic_b != NULL, 0);
	if (g_strcmp0 (dic_a, dic_b) < 0) {
		_tmp0_ = -1;
	} else {
		_tmp0_ = 1;
	}
	result = _tmp0_;
	return result;
}

static gint
___lambda9__gcompare_func (gconstpointer a,
                           gconstpointer b)
{
	gint result;
	result = __lambda9_ ((const gchar*) a, (const gchar*) b);
	return result;
}

static void
_vala_array_add22 (gchar** * array,
                   gint* length,
                   gint* size,
                   gchar* value)
{
	if ((*length) == (*size)) {
		*size = (*size) ? (2 * (*size)) : 4;
		*array = g_renew (gchar*, *array, (*size) + 1);
	}
	(*array)[(*length)++] = value;
	(*array)[*length] = NULL;
}

static gchar**
_vala_array_dup7 (gchar** self,
                  gssize length)
{
	if (length >= 0) {
		gchar** result;
		gssize i;
		result = g_new0 (gchar*, length + 1);
		for (i = 0; i < length; i++) {
			gchar* _tmp0_;
			_tmp0_ = g_strdup (self[i]);
			result[i] = _tmp0_;
		}
		return result;
	}
	return NULL;
}

static inline void
_g_list_free__g_free0_ (GList* self)
{
	g_list_free_full (self, (GDestroyNotify) _g_free0_);
}

gchar**
util_i18n_get_available_dictionaries (gint* result_length1)
{
	Block101Data* _data101_;
	gchar** _tmp0_;
	EnchantBroker* broker = NULL;
	EnchantBroker* _tmp1_;
	EnchantBroker* _tmp2_;
	GHashTable* regional_dictionaries = NULL;
	GHashFunc _tmp3_;
	GEqualFunc _tmp4_;
	GHashTable* _tmp5_;
	gchar** _tmp6_;
	gint _tmp6__length1;
	GList* filtered_dictionaries = NULL;
	gchar** _tmp13_;
	gint _tmp13__length1;
	gchar** _tmp21_;
	GList* _tmp22_;
	gchar** _tmp26_;
	gint _tmp26__length1;
	gchar** _tmp27_;
	gint _tmp27__length1;
	gchar** _tmp28_;
	gint _tmp28__length1;
	gchar** result;
	_data101_ = g_slice_new0 (Block101Data);
	_data101_->_ref_count_ = 1;
	_tmp0_ = g_new0 (gchar*, 0 + 1);
	_data101_->dictionaries = _tmp0_;
	_data101_->dictionaries_length1 = 0;
	_data101_->_dictionaries_size_ = _data101_->dictionaries_length1;
	_tmp1_ = enchant_broker_init ();
	broker = _tmp1_;
	_tmp2_ = broker;
	enchant_broker_list_dicts (_tmp2_, ___lambda8__enchant_dict_describe_fn, _data101_);
	_tmp3_ = g_str_hash;
	_tmp4_ = g_str_equal;
	_tmp5_ = g_hash_table_new_full (_tmp3_, _tmp4_, NULL, _g_free0_);
	regional_dictionaries = _tmp5_;
	_tmp6_ = _data101_->dictionaries;
	_tmp6__length1 = _data101_->dictionaries_length1;
	{
		gchar** dic_collection = NULL;
		gint dic_collection_length1 = 0;
		gint _dic_collection_size_ = 0;
		gint dic_it = 0;
		dic_collection = _tmp6_;
		dic_collection_length1 = _tmp6__length1;
		for (dic_it = 0; dic_it < dic_collection_length1; dic_it = dic_it + 1) {
			gchar* _tmp7_;
			gchar* dic = NULL;
			_tmp7_ = g_strdup (dic_collection[dic_it]);
			dic = _tmp7_;
			{
				const gchar* _tmp8_;
				_tmp8_ = dic;
				if (string_contains (_tmp8_, "_")) {
					gint underscore = 0;
					const gchar* _tmp9_;
					GHashTable* _tmp10_;
					const gchar* _tmp11_;
					gchar* _tmp12_;
					_tmp9_ = dic;
					underscore = string_index_of_char (_tmp9_, (gunichar) '_', 0);
					_tmp10_ = regional_dictionaries;
					_tmp11_ = dic;
					_tmp12_ = string_substring (_tmp11_, (glong) 0, (glong) underscore);
					g_hash_table_add (_tmp10_, _tmp12_);
				}
				_g_free0 (dic);
			}
		}
	}
	filtered_dictionaries = NULL;
	_tmp13_ = _data101_->dictionaries;
	_tmp13__length1 = _data101_->dictionaries_length1;
	{
		gchar** dic_collection = NULL;
		gint dic_collection_length1 = 0;
		gint _dic_collection_size_ = 0;
		gint dic_it = 0;
		dic_collection = _tmp13_;
		dic_collection_length1 = _tmp13__length1;
		for (dic_it = 0; dic_it < dic_collection_length1; dic_it = dic_it + 1) {
			gchar* _tmp14_;
			gchar* dic = NULL;
			_tmp14_ = g_strdup (dic_collection[dic_it]);
			dic = _tmp14_;
			{
				gboolean _tmp15_ = FALSE;
				const gchar* _tmp16_;
				_tmp16_ = dic;
				if (string_contains (_tmp16_, "_")) {
					_tmp15_ = TRUE;
				} else {
					GHashTable* _tmp17_;
					const gchar* _tmp18_;
					_tmp17_ = regional_dictionaries;
					_tmp18_ = dic;
					_tmp15_ = !g_hash_table_contains (_tmp17_, _tmp18_);
				}
				if (_tmp15_) {
					const gchar* _tmp19_;
					gchar* _tmp20_;
					_tmp19_ = dic;
					_tmp20_ = g_strdup (_tmp19_);
					filtered_dictionaries = g_list_append (filtered_dictionaries, _tmp20_);
				}
				_g_free0 (dic);
			}
		}
	}
	filtered_dictionaries = g_list_sort (filtered_dictionaries, ___lambda9__gcompare_func);
	_tmp21_ = g_new0 (gchar*, 0 + 1);
	_data101_->dictionaries = (_vala_array_free (_data101_->dictionaries, _data101_->dictionaries_length1, (GDestroyNotify) g_free), NULL);
	_data101_->dictionaries = _tmp21_;
	_data101_->dictionaries_length1 = 0;
	_data101_->_dictionaries_size_ = _data101_->dictionaries_length1;
	_tmp22_ = filtered_dictionaries;
	{
		GList* dic_collection = NULL;
		GList* dic_it = NULL;
		dic_collection = _tmp22_;
		for (dic_it = dic_collection; dic_it != NULL; dic_it = dic_it->next) {
			gchar* _tmp23_;
			gchar* dic = NULL;
			_tmp23_ = g_strdup ((const gchar*) dic_it->data);
			dic = _tmp23_;
			{
				const gchar* _tmp24_;
				gchar* _tmp25_;
				_tmp24_ = dic;
				_tmp25_ = g_strdup (_tmp24_);
				_vala_array_add22 (&_data101_->dictionaries, &_data101_->dictionaries_length1, &_data101_->_dictionaries_size_, _tmp25_);
				_g_free0 (dic);
			}
		}
	}
	_tmp26_ = _data101_->dictionaries;
	_tmp26__length1 = _data101_->dictionaries_length1;
	_tmp27_ = (_tmp26_ != NULL) ? _vala_array_dup7 (_tmp26_, _tmp26__length1) : _tmp26_;
	_tmp27__length1 = _tmp26__length1;
	_tmp28_ = _tmp27_;
	_tmp28__length1 = _tmp27__length1;
	if (result_length1) {
		*result_length1 = _tmp28__length1;
	}
	result = _tmp28_;
	(filtered_dictionaries == NULL) ? NULL : (filtered_dictionaries = (_g_list_free__g_free0_ (filtered_dictionaries), NULL));
	_g_hash_table_unref0 (regional_dictionaries);
	_enchant_broker_free0 (broker);
	block101_data_unref (_data101_);
	_data101_ = NULL;
	return result;
}

/**
     * Returns a list of installed locale languages.
     *
     * Each language is a POSIX-style locale name (ISO/IEC 15897).
     * The list is generated by executing `locale -a`.
     */
static void
_vala_array_add23 (gchar** * array,
                   gint* length,
                   gint* size,
                   gchar* value)
{
	if ((*length) == (*size)) {
		*size = (*size) ? (2 * (*size)) : 4;
		*array = g_renew (gchar*, *array, (*size) + 1);
	}
	(*array)[(*length)++] = value;
	(*array)[*length] = NULL;
}

gchar**
util_i18n_get_available_locales (gint* result_length1)
{
	gchar** locales = NULL;
	gchar** _tmp0_;
	gint locales_length1;
	gint _locales_size_;
	gchar** _tmp16_;
	gint _tmp16__length1;
	GError* _inner_error0_ = NULL;
	gchar** result;
	_tmp0_ = g_new0 (gchar*, 0 + 1);
	locales = _tmp0_;
	locales_length1 = 0;
	_locales_size_ = locales_length1;
	{
		gchar* output = NULL;
		GSubprocess* p = NULL;
		gchar* _tmp1_;
		gchar* _tmp2_;
		gchar** _tmp3_;
		gchar** _tmp4_;
		gint _tmp4__length1;
		GSubprocess* _tmp5_;
		GSubprocess* _tmp6_;
		GSubprocess* _tmp7_;
		gchar* _tmp8_ = NULL;
		const gchar* _tmp9_;
		gchar** _tmp10_;
		gchar** _tmp11_;
		output = NULL;
		_tmp1_ = g_strdup ("locale");
		_tmp2_ = g_strdup ("-a");
		_tmp3_ = g_new0 (gchar*, 2 + 1);
		_tmp3_[0] = _tmp1_;
		_tmp3_[1] = _tmp2_;
		_tmp4_ = _tmp3_;
		_tmp4__length1 = 2;
		_tmp5_ = g_subprocess_newv (_tmp4_, G_SUBPROCESS_FLAGS_STDOUT_PIPE, &_inner_error0_);
		_tmp6_ = _tmp5_;
		_tmp4_ = (_vala_array_free (_tmp4_, _tmp4__length1, (GDestroyNotify) g_free), NULL);
		p = _tmp6_;
		if (G_UNLIKELY (_inner_error0_ != NULL)) {
			_g_free0 (output);
			goto __catch0_g_error;
		}
		_tmp7_ = p;
		g_subprocess_communicate_utf8 (_tmp7_, NULL, NULL, &_tmp8_, NULL, &_inner_error0_);
		_g_free0 (output);
		output = _tmp8_;
		if (G_UNLIKELY (_inner_error0_ != NULL)) {
			_g_object_unref0 (p);
			_g_free0 (output);
			goto __catch0_g_error;
		}
		_tmp9_ = output;
		_tmp11_ = _tmp10_ = g_strsplit (_tmp9_, "\n", 0);
		{
			gchar** l_collection = NULL;
			gint l_collection_length1 = 0;
			gint _l_collection_size_ = 0;
			gint l_it = 0;
			l_collection = _tmp11_;
			l_collection_length1 = _vala_array_length (_tmp10_);
			for (l_it = 0; l_it < l_collection_length1; l_it = l_it + 1) {
				gchar* _tmp12_;
				gchar* l = NULL;
				_tmp12_ = g_strdup (l_collection[l_it]);
				l = _tmp12_;
				{
					const gchar* _tmp13_;
					gchar* _tmp14_;
					_tmp13_ = l;
					_tmp14_ = g_strdup (_tmp13_);
					_vala_array_add23 (&locales, &locales_length1, &_locales_size_, _tmp14_);
					_g_free0 (l);
				}
			}
			l_collection = (_vala_array_free (l_collection, l_collection_length1, (GDestroyNotify) g_free), NULL);
		}
		_g_object_unref0 (p);
		_g_free0 (output);
	}
	goto __finally0;
	__catch0_g_error:
	{
		gchar** _tmp15_;
		gint _tmp15__length1;
		g_clear_error (&_inner_error0_);
		_tmp15_ = locales;
		_tmp15__length1 = locales_length1;
		if (result_length1) {
			*result_length1 = _tmp15__length1;
		}
		result = _tmp15_;
		return result;
	}
	__finally0:
	if (G_UNLIKELY (_inner_error0_ != NULL)) {
		locales = (_vala_array_free (locales, locales_length1, (GDestroyNotify) g_free), NULL);
		g_critical ("file %s: line %d: uncaught error: %s (%s, %d)", __FILE__, __LINE__, _inner_error0_->message, g_quark_to_string (_inner_error0_->domain), _inner_error0_->code);
		g_clear_error (&_inner_error0_);
		return NULL;
	}
	_tmp16_ = locales;
	_tmp16__length1 = locales_length1;
	if (result_length1) {
		*result_length1 = _tmp16__length1;
	}
	result = _tmp16_;
	return result;
}

gchar*
util_i18n_strip_encoding (const gchar* locale)
{
	gint dot = 0;
	gchar* _tmp0_;
	gchar* result;
	g_return_val_if_fail (locale != NULL, NULL);
	dot = string_index_of_char (locale, (gunichar) '.', 0);
	_tmp0_ = string_substring (locale, (glong) 0, (glong) dot);
	result = _tmp0_;
	return result;
}

/**
     * Returns a list of preferred spell-check languages.
     *
     * Each language is a POSIX-style locale name (ISO/IEC 15897).
     * The list is generated by obtaining the list of POSIX locales
     * specified by the `LANGUAGE` environment variable, and including
     * each that has both an available dictionary and locale.
     *
     * @see get_available_dictionaries
     * @see get_available_locales
     */
static void
_vala_array_add24 (gchar** * array,
                   gint* length,
                   gint* size,
                   gchar* value)
{
	if ((*length) == (*size)) {
		*size = (*size) ? (2 * (*size)) : 4;
		*array = g_renew (gchar*, *array, (*size) + 1);
	}
	(*array)[(*length)++] = value;
	(*array)[*length] = NULL;
}

gchar**
util_i18n_get_user_preferred_languages (gint* result_length1)
{
	GHashTable* dicts = NULL;
	GHashFunc _tmp0_;
	GEqualFunc _tmp1_;
	GHashTable* _tmp2_;
	gint _tmp3_ = 0;
	gchar** _tmp4_;
	GHashTable* locales = NULL;
	GHashFunc _tmp9_;
	GEqualFunc _tmp10_;
	GHashTable* _tmp11_;
	gint _tmp12_ = 0;
	gchar** _tmp13_;
	gchar** output = NULL;
	gchar** _tmp18_;
	gint output_length1;
	gint _output_size_;
	gchar** language_names = NULL;
	gchar** _tmp19_;
	gchar** _tmp20_;
	gint language_names_length1;
	gint _language_names_size_;
	gchar** _tmp21_;
	gint _tmp21__length1;
	gchar** _tmp32_;
	gint _tmp32__length1;
	gchar** result;
	_tmp0_ = g_str_hash;
	_tmp1_ = g_str_equal;
	_tmp2_ = g_hash_table_new_full (_tmp0_, _tmp1_, NULL, _g_free0_);
	dicts = _tmp2_;
	_tmp4_ = util_i18n_get_available_dictionaries (&_tmp3_);
	{
		gchar** dict_collection = NULL;
		gint dict_collection_length1 = 0;
		gint _dict_collection_size_ = 0;
		gint dict_it = 0;
		dict_collection = _tmp4_;
		dict_collection_length1 = _tmp3_;
		for (dict_it = 0; dict_it < dict_collection_length1; dict_it = dict_it + 1) {
			gchar* _tmp5_;
			gchar* dict = NULL;
			_tmp5_ = g_strdup (dict_collection[dict_it]);
			dict = _tmp5_;
			{
				GHashTable* _tmp6_;
				const gchar* _tmp7_;
				gchar* _tmp8_;
				_tmp6_ = dicts;
				_tmp7_ = dict;
				_tmp8_ = g_strdup (_tmp7_);
				g_hash_table_add (_tmp6_, _tmp8_);
				_g_free0 (dict);
			}
		}
		dict_collection = (_vala_array_free (dict_collection, dict_collection_length1, (GDestroyNotify) g_free), NULL);
	}
	_tmp9_ = g_str_hash;
	_tmp10_ = g_str_equal;
	_tmp11_ = g_hash_table_new_full (_tmp9_, _tmp10_, NULL, _g_free0_);
	locales = _tmp11_;
	_tmp13_ = util_i18n_get_available_locales (&_tmp12_);
	{
		gchar** locale_collection = NULL;
		gint locale_collection_length1 = 0;
		gint _locale_collection_size_ = 0;
		gint locale_it = 0;
		locale_collection = _tmp13_;
		locale_collection_length1 = _tmp12_;
		for (locale_it = 0; locale_it < locale_collection_length1; locale_it = locale_it + 1) {
			gchar* _tmp14_;
			gchar* locale = NULL;
			_tmp14_ = g_strdup (locale_collection[locale_it]);
			locale = _tmp14_;
			{
				GHashTable* _tmp15_;
				const gchar* _tmp16_;
				gchar* _tmp17_;
				_tmp15_ = locales;
				_tmp16_ = locale;
				_tmp17_ = util_i18n_strip_encoding (_tmp16_);
				g_hash_table_add (_tmp15_, _tmp17_);
				_g_free0 (locale);
			}
		}
		locale_collection = (_vala_array_free (locale_collection, locale_collection_length1, (GDestroyNotify) g_free), NULL);
	}
	_tmp18_ = g_new0 (gchar*, 0 + 1);
	output = _tmp18_;
	output_length1 = 0;
	_output_size_ = output_length1;
	_tmp20_ = _tmp19_ = g_get_language_names ();
	language_names = _tmp20_;
	language_names_length1 = _vala_array_length (_tmp19_);
	_language_names_size_ = language_names_length1;
	_tmp21_ = language_names;
	_tmp21__length1 = language_names_length1;
	{
		gchar** lang_collection = NULL;
		gint lang_collection_length1 = 0;
		gint _lang_collection_size_ = 0;
		gint lang_it = 0;
		lang_collection = _tmp21_;
		lang_collection_length1 = _tmp21__length1;
		for (lang_it = 0; lang_it < lang_collection_length1; lang_it = lang_it + 1) {
			gchar* _tmp22_;
			gchar* lang = NULL;
			_tmp22_ = g_strdup (lang_collection[lang_it]);
			lang = _tmp22_;
			{
				gboolean _tmp23_ = FALSE;
				gboolean _tmp24_ = FALSE;
				const gchar* _tmp25_;
				_tmp25_ = lang;
				if (g_strcmp0 (_tmp25_, "C") != 0) {
					GHashTable* _tmp26_;
					const gchar* _tmp27_;
					_tmp26_ = dicts;
					_tmp27_ = lang;
					_tmp24_ = g_hash_table_contains (_tmp26_, _tmp27_);
				} else {
					_tmp24_ = FALSE;
				}
				if (_tmp24_) {
					GHashTable* _tmp28_;
					const gchar* _tmp29_;
					_tmp28_ = locales;
					_tmp29_ = lang;
					_tmp23_ = g_hash_table_contains (_tmp28_, _tmp29_);
				} else {
					_tmp23_ = FALSE;
				}
				if (_tmp23_) {
					const gchar* _tmp30_;
					gchar* _tmp31_;
					_tmp30_ = lang;
					_tmp31_ = g_strdup (_tmp30_);
					_vala_array_add24 (&output, &output_length1, &_output_size_, _tmp31_);
				}
				_g_free0 (lang);
			}
		}
	}
	_tmp32_ = output;
	_tmp32__length1 = output_length1;
	if (result_length1) {
		*result_length1 = _tmp32__length1;
	}
	result = _tmp32_;
	_g_hash_table_unref0 (locales);
	_g_hash_table_unref0 (dicts);
	return result;
}

gchar*
util_i18n_language_name_from_locale (const gchar* locale)
{
	GHashTable* _tmp0_;
	gint pos = 0;
	gchar* language_name = NULL;
	GHashTable* _tmp41_;
	gchar* _tmp42_;
	gchar* _tmp43_;
	gconstpointer _tmp44_;
	gchar* _tmp45_;
	gchar* _tmp46_;
	gchar* result;
	g_return_val_if_fail (locale != NULL, NULL);
	_tmp0_ = util_i18n_language_names;
	if (_tmp0_ == NULL) {
		GHashFunc _tmp1_;
		GEqualFunc _tmp2_;
		GHashTable* _tmp3_;
		xmlDoc* doc = NULL;
		xmlDoc* _tmp4_;
		xmlDoc* _tmp5_;
		_tmp1_ = g_str_hash;
		_tmp2_ = g_str_equal;
		_tmp3_ = g_hash_table_new_full (_tmp1_, _tmp2_, _g_free0_, _g_free0_);
		_g_hash_table_unref0 (util_i18n_language_names);
		util_i18n_language_names = _tmp3_;
		_tmp4_ = xmlParseFile (_ISO_CODE_639_XML);
		doc = _tmp4_;
		_tmp5_ = doc;
		if (_tmp5_ == NULL) {
			result = NULL;
			return result;
		} else {
			xmlNode* root = NULL;
			xmlDoc* _tmp6_;
			xmlNode* _tmp7_;
			_tmp6_ = doc;
			_tmp7_ = xmlDocGetRootElement (_tmp6_);
			root = _tmp7_;
			{
				xmlNode* entry = NULL;
				xmlNode* _tmp8_;
				xmlNode* _tmp9_;
				_tmp8_ = root;
				_tmp9_ = _tmp8_->children;
				entry = _tmp9_;
				{
					gboolean _tmp10_ = FALSE;
					_tmp10_ = TRUE;
					while (TRUE) {
						xmlNode* _tmp13_;
						xmlNode* _tmp14_;
						if (!_tmp10_) {
							xmlNode* _tmp11_;
							xmlNode* _tmp12_;
							_tmp11_ = entry;
							_tmp12_ = _tmp11_->next;
							entry = _tmp12_;
						}
						_tmp10_ = FALSE;
						_tmp13_ = entry;
						if (!(_tmp13_ != NULL)) {
							break;
						}
						_tmp14_ = entry;
						if (_tmp14_->type == XML_ELEMENT_NODE) {
							gchar* iso_639_1 = NULL;
							gchar* language_name = NULL;
							iso_639_1 = NULL;
							language_name = NULL;
							{
								xmlAttr* a = NULL;
								xmlNode* _tmp15_;
								xmlAttr* _tmp16_;
								_tmp15_ = entry;
								_tmp16_ = _tmp15_->properties;
								a = _tmp16_;
								{
									gboolean _tmp17_ = FALSE;
									_tmp17_ = TRUE;
									while (TRUE) {
										xmlAttr* _tmp20_;
										xmlAttr* _tmp21_;
										const gchar* _tmp22_;
										const gchar* _tmp23_;
										GQuark _tmp25_ = 0U;
										static GQuark _tmp24_label0 = 0;
										static GQuark _tmp24_label1 = 0;
										const gchar* _tmp34_;
										if (!_tmp17_) {
											xmlAttr* _tmp18_;
											xmlAttr* _tmp19_;
											_tmp18_ = a;
											_tmp19_ = _tmp18_->next;
											a = _tmp19_;
										}
										_tmp17_ = FALSE;
										_tmp20_ = a;
										if (!(_tmp20_ != NULL)) {
											break;
										}
										_tmp21_ = a;
										_tmp22_ = _tmp21_->name;
										_tmp23_ = _tmp22_;
										_tmp25_ = (NULL == _tmp23_) ? 0 : g_quark_from_string (_tmp23_);
										if (_tmp25_ == ((0 != _tmp24_label0) ? _tmp24_label0 : (_tmp24_label0 = g_quark_from_static_string ("iso_639_1_code")))) {
											switch (0) {
												default:
												{
													xmlAttr* _tmp26_;
													xmlNode* _tmp27_;
													const gchar* _tmp28_;
													gchar* _tmp29_;
													_tmp26_ = a;
													_tmp27_ = _tmp26_->children;
													_tmp28_ = _tmp27_->content;
													_tmp29_ = g_strdup (_tmp28_);
													_g_free0 (iso_639_1);
													iso_639_1 = _tmp29_;
													break;
												}
											}
										} else if (_tmp25_ == ((0 != _tmp24_label1) ? _tmp24_label1 : (_tmp24_label1 = g_quark_from_static_string ("name")))) {
											switch (0) {
												default:
												{
													xmlAttr* _tmp30_;
													xmlNode* _tmp31_;
													const gchar* _tmp32_;
													gchar* _tmp33_;
													_tmp30_ = a;
													_tmp31_ = _tmp30_->children;
													_tmp32_ = _tmp31_->content;
													_tmp33_ = g_strdup (_tmp32_);
													_g_free0 (language_name);
													language_name = _tmp33_;
													break;
												}
											}
										} else {
											switch (0) {
												default:
												{
													break;
												}
											}
										}
										_tmp34_ = language_name;
										if (_tmp34_ != NULL) {
											const gchar* _tmp35_;
											_tmp35_ = iso_639_1;
											if (_tmp35_ != NULL) {
												GHashTable* _tmp36_;
												const gchar* _tmp37_;
												gchar* _tmp38_;
												const gchar* _tmp39_;
												gchar* _tmp40_;
												_tmp36_ = util_i18n_language_names;
												_tmp37_ = iso_639_1;
												_tmp38_ = g_strdup (_tmp37_);
												_tmp39_ = language_name;
												_tmp40_ = g_strdup (_tmp39_);
												g_hash_table_insert (_tmp36_, _tmp38_, _tmp40_);
											}
										}
									}
								}
							}
							_g_free0 (language_name);
							_g_free0 (iso_639_1);
						}
					}
				}
			}
		}
	}
	pos = -1;
	if (string_contains (locale, "_")) {
		pos = string_index_of_char (locale, (gunichar) '_', 0);
	}
	_tmp41_ = util_i18n_language_names;
	_tmp42_ = string_substring (locale, (glong) 0, (glong) pos);
	_tmp43_ = _tmp42_;
	_tmp44_ = g_hash_table_lookup (_tmp41_, _tmp43_);
	_tmp45_ = g_strdup (g_dgettext ("iso_639", (const gchar*) _tmp44_));
	_tmp46_ = _tmp45_;
	_g_free0 (_tmp43_);
	language_name = _tmp46_;
	result = language_name;
	return result;
}

gchar*
util_i18n_country_name_from_locale (const gchar* locale)
{
	GHashTable* _tmp0_;
	gint pos = 0;
	gchar* country_name = NULL;
	GHashTable* _tmp41_;
	gchar* _tmp42_;
	gchar* _tmp43_;
	gconstpointer _tmp44_;
	gchar* _tmp45_;
	gchar* _tmp46_;
	gchar* result;
	g_return_val_if_fail (locale != NULL, NULL);
	_tmp0_ = util_i18n_country_names;
	if (_tmp0_ == NULL) {
		GHashFunc _tmp1_;
		GEqualFunc _tmp2_;
		GHashTable* _tmp3_;
		xmlDoc* doc = NULL;
		xmlDoc* _tmp4_;
		xmlDoc* _tmp5_;
		_tmp1_ = g_str_hash;
		_tmp2_ = g_str_equal;
		_tmp3_ = g_hash_table_new_full (_tmp1_, _tmp2_, _g_free0_, _g_free0_);
		_g_hash_table_unref0 (util_i18n_country_names);
		util_i18n_country_names = _tmp3_;
		_tmp4_ = xmlParseFile (_ISO_CODE_3166_XML);
		doc = _tmp4_;
		_tmp5_ = doc;
		if (_tmp5_ == NULL) {
			result = NULL;
			return result;
		} else {
			xmlNode* root = NULL;
			xmlDoc* _tmp6_;
			xmlNode* _tmp7_;
			_tmp6_ = doc;
			_tmp7_ = xmlDocGetRootElement (_tmp6_);
			root = _tmp7_;
			{
				xmlNode* entry = NULL;
				xmlNode* _tmp8_;
				xmlNode* _tmp9_;
				_tmp8_ = root;
				_tmp9_ = _tmp8_->children;
				entry = _tmp9_;
				{
					gboolean _tmp10_ = FALSE;
					_tmp10_ = TRUE;
					while (TRUE) {
						xmlNode* _tmp13_;
						xmlNode* _tmp14_;
						if (!_tmp10_) {
							xmlNode* _tmp11_;
							xmlNode* _tmp12_;
							_tmp11_ = entry;
							_tmp12_ = _tmp11_->next;
							entry = _tmp12_;
						}
						_tmp10_ = FALSE;
						_tmp13_ = entry;
						if (!(_tmp13_ != NULL)) {
							break;
						}
						_tmp14_ = entry;
						if (_tmp14_->type == XML_ELEMENT_NODE) {
							gchar* iso_3166 = NULL;
							gchar* country_name = NULL;
							iso_3166 = NULL;
							country_name = NULL;
							{
								xmlAttr* a = NULL;
								xmlNode* _tmp15_;
								xmlAttr* _tmp16_;
								_tmp15_ = entry;
								_tmp16_ = _tmp15_->properties;
								a = _tmp16_;
								{
									gboolean _tmp17_ = FALSE;
									_tmp17_ = TRUE;
									while (TRUE) {
										xmlAttr* _tmp20_;
										xmlAttr* _tmp21_;
										const gchar* _tmp22_;
										const gchar* _tmp23_;
										GQuark _tmp25_ = 0U;
										static GQuark _tmp24_label0 = 0;
										static GQuark _tmp24_label1 = 0;
										const gchar* _tmp34_;
										if (!_tmp17_) {
											xmlAttr* _tmp18_;
											xmlAttr* _tmp19_;
											_tmp18_ = a;
											_tmp19_ = _tmp18_->next;
											a = _tmp19_;
										}
										_tmp17_ = FALSE;
										_tmp20_ = a;
										if (!(_tmp20_ != NULL)) {
											break;
										}
										_tmp21_ = a;
										_tmp22_ = _tmp21_->name;
										_tmp23_ = _tmp22_;
										_tmp25_ = (NULL == _tmp23_) ? 0 : g_quark_from_string (_tmp23_);
										if (_tmp25_ == ((0 != _tmp24_label0) ? _tmp24_label0 : (_tmp24_label0 = g_quark_from_static_string ("alpha_2_code")))) {
											switch (0) {
												default:
												{
													xmlAttr* _tmp26_;
													xmlNode* _tmp27_;
													const gchar* _tmp28_;
													gchar* _tmp29_;
													_tmp26_ = a;
													_tmp27_ = _tmp26_->children;
													_tmp28_ = _tmp27_->content;
													_tmp29_ = g_strdup (_tmp28_);
													_g_free0 (iso_3166);
													iso_3166 = _tmp29_;
													break;
												}
											}
										} else if (_tmp25_ == ((0 != _tmp24_label1) ? _tmp24_label1 : (_tmp24_label1 = g_quark_from_static_string ("name")))) {
											switch (0) {
												default:
												{
													xmlAttr* _tmp30_;
													xmlNode* _tmp31_;
													const gchar* _tmp32_;
													gchar* _tmp33_;
													_tmp30_ = a;
													_tmp31_ = _tmp30_->children;
													_tmp32_ = _tmp31_->content;
													_tmp33_ = g_strdup (_tmp32_);
													_g_free0 (country_name);
													country_name = _tmp33_;
													break;
												}
											}
										} else {
											switch (0) {
												default:
												{
													break;
												}
											}
										}
										_tmp34_ = country_name;
										if (_tmp34_ != NULL) {
											const gchar* _tmp35_;
											_tmp35_ = iso_3166;
											if (_tmp35_ != NULL) {
												GHashTable* _tmp36_;
												const gchar* _tmp37_;
												gchar* _tmp38_;
												const gchar* _tmp39_;
												gchar* _tmp40_;
												_tmp36_ = util_i18n_country_names;
												_tmp37_ = iso_3166;
												_tmp38_ = g_strdup (_tmp37_);
												_tmp39_ = country_name;
												_tmp40_ = g_strdup (_tmp39_);
												g_hash_table_insert (_tmp36_, _tmp38_, _tmp40_);
											}
										}
									}
								}
							}
							_g_free0 (country_name);
							_g_free0 (iso_3166);
						}
					}
				}
			}
		}
	}
	pos = -1;
	if (string_contains (locale, "_")) {
		pos = string_index_of_char (locale, (gunichar) '_', 0);
	}
	_tmp41_ = util_i18n_country_names;
	_tmp42_ = string_substring (locale, (glong) (pos + 1), (glong) -1);
	_tmp43_ = _tmp42_;
	_tmp44_ = g_hash_table_lookup (_tmp41_, _tmp43_);
	_tmp45_ = g_strdup (g_dgettext ("iso_3166", (const gchar*) _tmp44_));
	_tmp46_ = _tmp45_;
	_g_free0 (_tmp43_);
	country_name = _tmp46_;
	result = country_name;
	return result;
}

/**
     * Returns the localised display name name for specific folder.
     *
     * If the folder has a special type, the result of {@link
     * to_folder_type_display_name} is returned, otherwise the last
     * folder path step is returned.
     */
gchar*
util_i18n_to_folder_display_name (GearyFolder* folder)
{
	gchar* name = NULL;
	GearyFolderSpecialUse _tmp0_;
	GearyFolderSpecialUse _tmp1_;
	const gchar* _tmp2_;
	gchar* _tmp3_;
	const gchar* _tmp4_;
	gchar* result;
	g_return_val_if_fail (G_TYPE_CHECK_INSTANCE_TYPE (folder, GEARY_TYPE_FOLDER), NULL);
	_tmp0_ = geary_folder_get_used_as (folder);
	_tmp1_ = _tmp0_;
	_tmp2_ = util_i18n_to_folder_type_display_name (_tmp1_);
	_tmp3_ = g_strdup (_tmp2_);
	name = _tmp3_;
	_tmp4_ = name;
	if (geary_string_is_empty_or_whitespace (_tmp4_)) {
		GearyFolderPath* _tmp5_;
		GearyFolderPath* _tmp6_;
		const gchar* _tmp7_;
		const gchar* _tmp8_;
		gchar* _tmp9_;
		_tmp5_ = geary_folder_get_path (folder);
		_tmp6_ = _tmp5_;
		_tmp7_ = geary_folder_path_get_name (_tmp6_);
		_tmp8_ = _tmp7_;
		_tmp9_ = g_strdup (_tmp8_);
		_g_free0 (name);
		name = _tmp9_;
	}
	result = name;
	return result;
}

/**
     * Returns the localised name for a specific folder type, if any.
     */
const gchar*
util_i18n_to_folder_type_display_name (GearyFolderSpecialUse use)
{
	const gchar* result;
	switch (use) {
		case GEARY_FOLDER_SPECIAL_USE_INBOX:
		{
			result = _ ("Inbox");
			return result;
		}
		case GEARY_FOLDER_SPECIAL_USE_DRAFTS:
		{
			result = _ ("Drafts");
			return result;
		}
		case GEARY_FOLDER_SPECIAL_USE_SENT:
		{
			result = _ ("Sent");
			return result;
		}
		case GEARY_FOLDER_SPECIAL_USE_FLAGGED:
		{
			result = _ ("Starred");
			return result;
		}
		case GEARY_FOLDER_SPECIAL_USE_IMPORTANT:
		{
			result = _ ("Important");
			return result;
		}
		case GEARY_FOLDER_SPECIAL_USE_ALL_MAIL:
		{
			result = _ ("All Mail");
			return result;
		}
		case GEARY_FOLDER_SPECIAL_USE_JUNK:
		{
			result = _ ("Junk");
			return result;
		}
		case GEARY_FOLDER_SPECIAL_USE_TRASH:
		{
			result = _ ("Trash");
			return result;
		}
		case GEARY_FOLDER_SPECIAL_USE_OUTBOX:
		{
			result = _ ("Outbox");
			return result;
		}
		case GEARY_FOLDER_SPECIAL_USE_SEARCH:
		{
			result = _ ("Search");
			return result;
		}
		case GEARY_FOLDER_SPECIAL_USE_ARCHIVE:
		{
			result = _ ("Archive");
			return result;
		}
		default:
		case GEARY_FOLDER_SPECIAL_USE_NONE:
		{
			result = NULL;
			return result;
		}
	}
}

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

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

static gssize
_vala_array_length (gpointer array)
{
	gssize length;
	length = 0;
	if (array) {
		while (((gpointer*) array)[length]) {
			length++;
		}
	}
	return length;
}

