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

/*
 * Copyright (C) 2011-2014 Daiki Ueno <ueno@gnu.org>
 * Copyright (C) 2011-2014 Red Hat, Inc.
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program 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 General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <glib-object.h>
#include <stdlib.h>
#include <string.h>
#include <glib.h>
#include "libkkc/libkkc.h"
#include <gee.h>
#include <json-glib/json-glib.h>
#include <glib/gstdio.h>
#include <gio/gio.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 KKC_TYPE_MAP_FILE (kkc_map_file_get_type ())
#define KKC_MAP_FILE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), KKC_TYPE_MAP_FILE, KkcMapFile))
#define KKC_MAP_FILE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), KKC_TYPE_MAP_FILE, KkcMapFileClass))
#define KKC_IS_MAP_FILE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), KKC_TYPE_MAP_FILE))
#define KKC_IS_MAP_FILE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), KKC_TYPE_MAP_FILE))
#define KKC_MAP_FILE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), KKC_TYPE_MAP_FILE, KkcMapFileClass))

typedef struct _KkcMapFile KkcMapFile;
typedef struct _KkcMapFileClass KkcMapFileClass;
typedef struct _KkcMapFilePrivate KkcMapFilePrivate;

#define KKC_TYPE_KEYMAP_MAP_FILE (kkc_keymap_map_file_get_type ())
#define KKC_KEYMAP_MAP_FILE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), KKC_TYPE_KEYMAP_MAP_FILE, KkcKeymapMapFile))
#define KKC_KEYMAP_MAP_FILE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), KKC_TYPE_KEYMAP_MAP_FILE, KkcKeymapMapFileClass))
#define KKC_IS_KEYMAP_MAP_FILE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), KKC_TYPE_KEYMAP_MAP_FILE))
#define KKC_IS_KEYMAP_MAP_FILE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), KKC_TYPE_KEYMAP_MAP_FILE))
#define KKC_KEYMAP_MAP_FILE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), KKC_TYPE_KEYMAP_MAP_FILE, KkcKeymapMapFileClass))

typedef struct _KkcKeymapMapFile KkcKeymapMapFile;
typedef struct _KkcKeymapMapFileClass KkcKeymapMapFileClass;
typedef struct _KkcKeymapMapFilePrivate KkcKeymapMapFilePrivate;
enum  {
	KKC_KEYMAP_MAP_FILE_0_PROPERTY,
	KKC_KEYMAP_MAP_FILE_NUM_PROPERTIES
};
static GParamSpec* kkc_keymap_map_file_properties[KKC_KEYMAP_MAP_FILE_NUM_PROPERTIES];
#define _g_object_unref0(var) ((var == NULL) ? NULL : (var = (g_object_unref (var), NULL)))
#define _g_error_free0(var) ((var == NULL) ? NULL : (var = (g_error_free (var), NULL)))
#define __vala_JsonNode_free0(var) ((var == NULL) ? NULL : (var = (_vala_JsonNode_free (var), NULL)))
#define _g_free0(var) (var = (g_free (var), NULL))

#define KKC_TYPE_ROM_KANA_MAP_FILE (kkc_rom_kana_map_file_get_type ())
#define KKC_ROM_KANA_MAP_FILE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), KKC_TYPE_ROM_KANA_MAP_FILE, KkcRomKanaMapFile))
#define KKC_ROM_KANA_MAP_FILE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), KKC_TYPE_ROM_KANA_MAP_FILE, KkcRomKanaMapFileClass))
#define KKC_IS_ROM_KANA_MAP_FILE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), KKC_TYPE_ROM_KANA_MAP_FILE))
#define KKC_IS_ROM_KANA_MAP_FILE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), KKC_TYPE_ROM_KANA_MAP_FILE))
#define KKC_ROM_KANA_MAP_FILE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), KKC_TYPE_ROM_KANA_MAP_FILE, KkcRomKanaMapFileClass))

typedef struct _KkcRomKanaMapFile KkcRomKanaMapFile;
typedef struct _KkcRomKanaMapFileClass KkcRomKanaMapFileClass;
typedef struct _KkcRomKanaMapFilePrivate KkcRomKanaMapFilePrivate;

#define KKC_TYPE_ROM_KANA_NODE (kkc_rom_kana_node_get_type ())
#define KKC_ROM_KANA_NODE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), KKC_TYPE_ROM_KANA_NODE, KkcRomKanaNode))
#define KKC_ROM_KANA_NODE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), KKC_TYPE_ROM_KANA_NODE, KkcRomKanaNodeClass))
#define KKC_IS_ROM_KANA_NODE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), KKC_TYPE_ROM_KANA_NODE))
#define KKC_IS_ROM_KANA_NODE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), KKC_TYPE_ROM_KANA_NODE))
#define KKC_ROM_KANA_NODE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), KKC_TYPE_ROM_KANA_NODE, KkcRomKanaNodeClass))

typedef struct _KkcRomKanaNode KkcRomKanaNode;
typedef struct _KkcRomKanaNodeClass KkcRomKanaNodeClass;
enum  {
	KKC_ROM_KANA_MAP_FILE_0_PROPERTY,
	KKC_ROM_KANA_MAP_FILE_NUM_PROPERTIES
};
static GParamSpec* kkc_rom_kana_map_file_properties[KKC_ROM_KANA_MAP_FILE_NUM_PROPERTIES];

#define KKC_TYPE_ROM_KANA_ENTRY (kkc_rom_kana_entry_get_type ())
typedef struct _KkcRomKanaEntry KkcRomKanaEntry;
#define _json_array_unref0(var) ((var == NULL) ? NULL : (var = (json_array_unref (var), NULL)))
enum  {
	KKC_RULE_METADATA_0_PROPERTY,
	KKC_RULE_METADATA_FILTER_PROPERTY,
	KKC_RULE_METADATA_PRIORITY_PROPERTY,
	KKC_RULE_METADATA_NUM_PROPERTIES
};
static GParamSpec* kkc_rule_metadata_properties[KKC_RULE_METADATA_NUM_PROPERTIES];

#define KKC_TYPE_SIMPLE_KEY_EVENT_FILTER (kkc_simple_key_event_filter_get_type ())
#define KKC_SIMPLE_KEY_EVENT_FILTER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), KKC_TYPE_SIMPLE_KEY_EVENT_FILTER, KkcSimpleKeyEventFilter))
#define KKC_SIMPLE_KEY_EVENT_FILTER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), KKC_TYPE_SIMPLE_KEY_EVENT_FILTER, KkcSimpleKeyEventFilterClass))
#define KKC_IS_SIMPLE_KEY_EVENT_FILTER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), KKC_TYPE_SIMPLE_KEY_EVENT_FILTER))
#define KKC_IS_SIMPLE_KEY_EVENT_FILTER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), KKC_TYPE_SIMPLE_KEY_EVENT_FILTER))
#define KKC_SIMPLE_KEY_EVENT_FILTER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), KKC_TYPE_SIMPLE_KEY_EVENT_FILTER, KkcSimpleKeyEventFilterClass))

typedef struct _KkcSimpleKeyEventFilter KkcSimpleKeyEventFilter;
typedef struct _KkcSimpleKeyEventFilterClass KkcSimpleKeyEventFilterClass;

#define KKC_TYPE_KANA_KEY_EVENT_FILTER (kkc_kana_key_event_filter_get_type ())
#define KKC_KANA_KEY_EVENT_FILTER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), KKC_TYPE_KANA_KEY_EVENT_FILTER, KkcKanaKeyEventFilter))
#define KKC_KANA_KEY_EVENT_FILTER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), KKC_TYPE_KANA_KEY_EVENT_FILTER, KkcKanaKeyEventFilterClass))
#define KKC_IS_KANA_KEY_EVENT_FILTER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), KKC_TYPE_KANA_KEY_EVENT_FILTER))
#define KKC_IS_KANA_KEY_EVENT_FILTER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), KKC_TYPE_KANA_KEY_EVENT_FILTER))
#define KKC_KANA_KEY_EVENT_FILTER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), KKC_TYPE_KANA_KEY_EVENT_FILTER, KkcKanaKeyEventFilterClass))

typedef struct _KkcKanaKeyEventFilter KkcKanaKeyEventFilter;
typedef struct _KkcKanaKeyEventFilterClass KkcKanaKeyEventFilterClass;
enum  {
	KKC_RULE_0_PROPERTY,
	KKC_RULE_METADATA_PROPERTY,
	KKC_RULE_FILTER_PROPERTY,
	KKC_RULE_NUM_PROPERTIES
};
static GParamSpec* kkc_rule_properties[KKC_RULE_NUM_PROPERTIES];
#define _g_type_class_unref0(var) ((var == NULL) ? NULL : (var = (g_type_class_unref (var), NULL)))
#define _g_dir_close0(var) ((var == NULL) ? NULL : (var = (g_dir_close (var), NULL)))

struct _KkcMapFile {
	GObject parent_instance;
	KkcMapFilePrivate * priv;
};

struct _KkcMapFileClass {
	GObjectClass parent_class;
	gchar* (*uniquify) (KkcMapFile* self, const gchar* key);
};

struct _KkcKeymapMapFile {
	KkcMapFile parent_instance;
	KkcKeymapMapFilePrivate * priv;
	KkcKeymap* keymap;
	KkcKeymap* parent_keymap;
};

struct _KkcKeymapMapFileClass {
	KkcMapFileClass parent_class;
};

struct _KkcRomKanaMapFile {
	KkcMapFile parent_instance;
	KkcRomKanaMapFilePrivate * priv;
	KkcRomKanaNode* root_node;
};

struct _KkcRomKanaMapFileClass {
	KkcMapFileClass parent_class;
};

struct _KkcRomKanaEntry {
	gchar* rom;
	gchar* carryover;
	gchar* hiragana;
	gchar* katakana;
	gchar* hiragana_partial;
	gchar* katakana_partial;
};

struct _KkcRuleMetadataPrivate {
	gchar* _filter;
	gint _priority;
};

struct _KkcRulePrivate {
	KkcRuleMetadata* _metadata;
	KkcKeyEventFilter* _filter;
	KkcKeymapMapFile** keymaps;
	gint keymaps_length1;
	gint _keymaps_size_;
};

static gpointer kkc_keymap_map_file_parent_class = NULL;
static gpointer kkc_rom_kana_map_file_parent_class = NULL;
static gint KkcRuleMetadata_private_offset;
static gpointer kkc_rule_metadata_parent_class = NULL;
static GeeMap* kkc_rule_metadata_filter_types;
static GeeMap* kkc_rule_metadata_filter_types = NULL;
static GeeMap* kkc_rule_metadata_instance_cache;
static GeeMap* kkc_rule_metadata_instance_cache = NULL;
static gint KkcRule_private_offset;
static gpointer kkc_rule_parent_class = NULL;
static GInitableIface * kkc_rule_g_initable_parent_iface = NULL;

VALA_EXTERN GType kkc_map_file_get_type (void) G_GNUC_CONST ;
VALA_EXTERN GType kkc_keymap_map_file_get_type (void) G_GNUC_CONST ;
VALA_EXTERN gchar* kkc_map_file_uniquify (KkcMapFile* self,
                              const gchar* key);
static gchar* kkc_keymap_map_file_real_uniquify (KkcMapFile* base,
                                          const gchar* key);
static void kkc_keymap_map_file_load_keymap (KkcKeymapMapFile* self,
                                      KkcKeymap* keymap,
                                      GeeMap* map);
static void _vala_JsonNode_free (JsonNode* self);
VALA_EXTERN KkcKeymapMapFile* kkc_keymap_map_file_new (KkcRuleMetadata* metadata,
                                           const gchar* mode,
                                           GError** error);
VALA_EXTERN KkcKeymapMapFile* kkc_keymap_map_file_construct (GType object_type,
                                                 KkcRuleMetadata* metadata,
                                                 const gchar* mode,
                                                 GError** error);
VALA_EXTERN KkcMapFile* kkc_map_file_construct (GType object_type,
                                    KkcRuleMetadata* metadata,
                                    const gchar* type,
                                    const gchar* name,
                                    GError** error);
VALA_EXTERN GeeMap* kkc_map_file_get (KkcMapFile* self,
                          const gchar* name);
VALA_EXTERN GeeMap* kkc_map_file_get_parent (KkcMapFile* self,
                                 const gchar* name);
static void kkc_keymap_map_file_finalize (GObject * obj);
static GType kkc_keymap_map_file_get_type_once (void);
VALA_EXTERN GType kkc_rom_kana_map_file_get_type (void) G_GNUC_CONST ;
VALA_EXTERN GType kkc_rom_kana_node_get_type (void) G_GNUC_CONST ;
static void kkc_rom_kana_map_file_load_rom_kana (KkcRomKanaMapFile* self,
                                          KkcRomKanaNode* node,
                                          GeeMap* map,
                                          GError** error);
VALA_EXTERN gchar* kkc_rom_kana_utils_get_katakana (const gchar* kana);
VALA_EXTERN GType kkc_rom_kana_entry_get_type (void) G_GNUC_CONST ;
VALA_EXTERN KkcRomKanaEntry* kkc_rom_kana_entry_dup (const KkcRomKanaEntry* self);
VALA_EXTERN void kkc_rom_kana_entry_free (KkcRomKanaEntry* self);
VALA_EXTERN void kkc_rom_kana_entry_copy (const KkcRomKanaEntry* self,
                              KkcRomKanaEntry* dest);
VALA_EXTERN void kkc_rom_kana_entry_destroy (KkcRomKanaEntry* self);
VALA_EXTERN void kkc_rom_kana_node_insert (KkcRomKanaNode* self,
                               const gchar* key,
                               KkcRomKanaEntry* entry);
VALA_EXTERN KkcRomKanaMapFile* kkc_rom_kana_map_file_new (KkcRuleMetadata* metadata,
                                              GError** error);
VALA_EXTERN KkcRomKanaMapFile* kkc_rom_kana_map_file_construct (GType object_type,
                                                    KkcRuleMetadata* metadata,
                                                    GError** error);
VALA_EXTERN KkcRomKanaNode* kkc_rom_kana_node_new (KkcRomKanaEntry* entry);
VALA_EXTERN KkcRomKanaNode* kkc_rom_kana_node_construct (GType object_type,
                                             KkcRomKanaEntry* entry);
static void kkc_rom_kana_map_file_finalize (GObject * obj);
static GType kkc_rom_kana_map_file_get_type_once (void);
static gboolean kkc_rule_metadata_real_parse (KkcMetadataFile* base,
                                       JsonObject* object,
                                       GError** error);
VALA_EXTERN gchar** kkc_utils_build_data_path (const gchar* subdir,
                                   gint* result_length1);
static GType* _g_type_dup (GType* self);
VALA_EXTERN GType kkc_simple_key_event_filter_get_type (void) G_GNUC_CONST ;
VALA_EXTERN GType kkc_kana_key_event_filter_get_type (void) G_GNUC_CONST ;
static void kkc_rule_metadata_finalize (GObject * obj);
static GType kkc_rule_metadata_get_type_once (void);
static void _vala_kkc_rule_metadata_get_property (GObject * object,
                                           guint property_id,
                                           GValue * value,
                                           GParamSpec * pspec);
static void _vala_kkc_rule_metadata_set_property (GObject * object,
                                           guint property_id,
                                           const GValue * value,
                                           GParamSpec * pspec);
static gboolean kkc_rule_real_init (GInitable* base,
                             GCancellable* cancellable,
                             GError** error);
static GEnumValue* _g_enum_value_dup (GEnumValue* self);
static void _vala_array_add5 (KkcRuleMetadata** * array,
                       gint* length,
                       gint* size,
                       KkcRuleMetadata* value);
static void kkc_rule_finalize (GObject * obj);
static GType kkc_rule_get_type_once (void);
static void _vala_kkc_rule_get_property (GObject * object,
                                  guint property_id,
                                  GValue * value,
                                  GParamSpec * pspec);
static void _vala_kkc_rule_set_property (GObject * object,
                                  guint property_id,
                                  const GValue * value,
                                  GParamSpec * pspec);
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 gchar*
kkc_keymap_map_file_real_uniquify (KkcMapFile* base,
                                   const gchar* key)
{
	KkcKeymapMapFile * self;
	GError* _inner_error0_ = NULL;
	gchar* result;
	self = (KkcKeymapMapFile*) base;
	g_return_val_if_fail (key != NULL, NULL);
	{
		KkcKeyEvent* event = NULL;
		KkcKeyEvent* _tmp0_;
		gchar* _tmp1_;
		_tmp0_ = kkc_key_event_new_from_string (key, &_inner_error0_);
		event = _tmp0_;
		if (G_UNLIKELY (_inner_error0_ != NULL)) {
			if (_inner_error0_->domain == KKC_KEY_EVENT_FORMAT_ERROR) {
				goto __catch0_kkc_key_event_format_error;
			}
			g_critical ("file %s: line %d: unexpected 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;
		}
		_tmp1_ = kkc_key_event_to_string (event);
		result = _tmp1_;
		_g_object_unref0 (event);
		return result;
	}
	goto __finally0;
	__catch0_kkc_key_event_format_error:
	{
		GError* e = NULL;
		GError* _tmp2_;
		const gchar* _tmp3_;
		gchar* _tmp4_;
		e = _inner_error0_;
		_inner_error0_ = NULL;
		_tmp2_ = e;
		_tmp3_ = _tmp2_->message;
		g_warning ("rule.vala:30: can't get key event from string %s: %s", key, _tmp3_);
		_tmp4_ = g_strdup (key);
		result = _tmp4_;
		_g_error_free0 (e);
		return result;
	}
	__finally0:
	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;
}

static void
_vala_JsonNode_free (JsonNode* self)
{
	g_boxed_free (json_node_get_type (), self);
}

static void
kkc_keymap_map_file_load_keymap (KkcKeymapMapFile* self,
                                 KkcKeymap* keymap,
                                 GeeMap* map)
{
	GeeMapIterator* iter = NULL;
	GeeMapIterator* _tmp0_;
	GError* _inner_error0_ = NULL;
	g_return_if_fail (self != NULL);
	g_return_if_fail (keymap != NULL);
	g_return_if_fail (map != NULL);
	_tmp0_ = gee_map_map_iterator (map);
	iter = _tmp0_;
	while (TRUE) {
		GeeMapIterator* _tmp1_;
		gchar* key = NULL;
		GeeMapIterator* _tmp2_;
		gpointer _tmp3_;
		JsonNode* value = NULL;
		GeeMapIterator* _tmp4_;
		gpointer _tmp5_;
		_tmp1_ = iter;
		if (!gee_map_iterator_next (_tmp1_)) {
			break;
		}
		_tmp2_ = iter;
		_tmp3_ = gee_map_iterator_get_key (_tmp2_);
		key = (gchar*) _tmp3_;
		_tmp4_ = iter;
		_tmp5_ = gee_map_iterator_get_value (_tmp4_);
		value = (JsonNode*) _tmp5_;
		{
			KkcKeyEvent* _tmp6_ = NULL;
			const gchar* _tmp7_;
			KkcKeyEvent* _tmp8_;
			JsonNode* _tmp9_;
			const gchar* _tmp10_;
			_tmp7_ = key;
			_tmp8_ = kkc_key_event_new_from_string (_tmp7_, &_inner_error0_);
			_tmp6_ = _tmp8_;
			if (G_UNLIKELY (_inner_error0_ != NULL)) {
				if (_inner_error0_->domain == KKC_KEY_EVENT_FORMAT_ERROR) {
					goto __catch0_kkc_key_event_format_error;
				}
				__vala_JsonNode_free0 (value);
				_g_free0 (key);
				_g_object_unref0 (iter);
				g_critical ("file %s: line %d: unexpected 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;
			}
			_tmp9_ = value;
			_tmp10_ = json_node_get_string (_tmp9_);
			kkc_keymap_set (keymap, _tmp6_, _tmp10_);
			_g_object_unref0 (_tmp6_);
		}
		goto __finally0;
		__catch0_kkc_key_event_format_error:
		{
			GError* e = NULL;
			const gchar* _tmp11_;
			GError* _tmp12_;
			const gchar* _tmp13_;
			e = _inner_error0_;
			_inner_error0_ = NULL;
			_tmp11_ = key;
			_tmp12_ = e;
			_tmp13_ = _tmp12_->message;
			g_warning ("rule.vala:46: can't get key event from string %s: %s", _tmp11_, _tmp13_);
			_g_error_free0 (e);
		}
		__finally0:
		if (G_UNLIKELY (_inner_error0_ != NULL)) {
			__vala_JsonNode_free0 (value);
			_g_free0 (key);
			_g_object_unref0 (iter);
			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;
		}
		__vala_JsonNode_free0 (value);
		_g_free0 (key);
	}
	_g_object_unref0 (iter);
}

KkcKeymapMapFile*
kkc_keymap_map_file_construct (GType object_type,
                               KkcRuleMetadata* metadata,
                               const gchar* mode,
                               GError** error)
{
	KkcKeymapMapFile * self = NULL;
	KkcKeymap* _tmp0_;
	KkcKeymap* _tmp1_;
	GeeMap* _tmp2_;
	GeeMap* _tmp3_;
	KkcKeymap* _tmp4_;
	KkcKeymap* _tmp5_;
	KkcKeymap* _tmp6_;
	KkcKeymap* _tmp7_;
	KkcKeymap* _tmp8_;
	KkcKeymap* _tmp9_;
	GeeMap* _tmp10_;
	GeeMap* _tmp11_;
	GError* _inner_error0_ = NULL;
	g_return_val_if_fail (metadata != NULL, NULL);
	g_return_val_if_fail (mode != NULL, NULL);
	self = (KkcKeymapMapFile*) kkc_map_file_construct (object_type, metadata, "keymap", mode, &_inner_error0_);
	if (G_UNLIKELY (_inner_error0_ != NULL)) {
		if (_inner_error0_->domain == KKC_RULE_PARSE_ERROR) {
			g_propagate_error (error, _inner_error0_);
			_g_object_unref0 (self);
			return NULL;
		} else {
			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;
		}
	}
	_tmp0_ = kkc_keymap_new ();
	_g_object_unref0 (self->keymap);
	self->keymap = _tmp0_;
	_tmp1_ = self->keymap;
	_tmp2_ = kkc_map_file_get ((KkcMapFile*) self, "keymap");
	_tmp3_ = _tmp2_;
	kkc_keymap_map_file_load_keymap (self, _tmp1_, _tmp3_);
	_g_object_unref0 (_tmp3_);
	_tmp4_ = self->keymap;
	_tmp5_ = kkc_keymap_new ();
	_tmp6_ = _tmp5_;
	kkc_keymap_set_parent (_tmp4_, _tmp6_);
	_g_object_unref0 (_tmp6_);
	_tmp7_ = self->keymap;
	_tmp8_ = kkc_keymap_get_parent (_tmp7_);
	_tmp9_ = _tmp8_;
	_tmp10_ = kkc_map_file_get_parent ((KkcMapFile*) self, "keymap");
	_tmp11_ = _tmp10_;
	kkc_keymap_map_file_load_keymap (self, _tmp9_, _tmp11_);
	_g_object_unref0 (_tmp11_);
	return self;
}

KkcKeymapMapFile*
kkc_keymap_map_file_new (KkcRuleMetadata* metadata,
                         const gchar* mode,
                         GError** error)
{
	return kkc_keymap_map_file_construct (KKC_TYPE_KEYMAP_MAP_FILE, metadata, mode, error);
}

static void
kkc_keymap_map_file_class_init (KkcKeymapMapFileClass * klass,
                                gpointer klass_data)
{
	kkc_keymap_map_file_parent_class = g_type_class_peek_parent (klass);
	((KkcMapFileClass *) klass)->uniquify = (gchar* (*) (KkcMapFile*, const gchar*)) kkc_keymap_map_file_real_uniquify;
	G_OBJECT_CLASS (klass)->finalize = kkc_keymap_map_file_finalize;
}

static void
kkc_keymap_map_file_instance_init (KkcKeymapMapFile * self,
                                   gpointer klass)
{
}

static void
kkc_keymap_map_file_finalize (GObject * obj)
{
	KkcKeymapMapFile * self;
	self = G_TYPE_CHECK_INSTANCE_CAST (obj, KKC_TYPE_KEYMAP_MAP_FILE, KkcKeymapMapFile);
	_g_object_unref0 (self->keymap);
	_g_object_unref0 (self->parent_keymap);
	G_OBJECT_CLASS (kkc_keymap_map_file_parent_class)->finalize (obj);
}

static GType
kkc_keymap_map_file_get_type_once (void)
{
	static const GTypeInfo g_define_type_info = { sizeof (KkcKeymapMapFileClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) kkc_keymap_map_file_class_init, (GClassFinalizeFunc) NULL, NULL, sizeof (KkcKeymapMapFile), 0, (GInstanceInitFunc) kkc_keymap_map_file_instance_init, NULL };
	GType kkc_keymap_map_file_type_id;
	kkc_keymap_map_file_type_id = g_type_register_static (KKC_TYPE_MAP_FILE, "KkcKeymapMapFile", &g_define_type_info, 0);
	return kkc_keymap_map_file_type_id;
}

GType
kkc_keymap_map_file_get_type (void)
{
	static volatile gsize kkc_keymap_map_file_type_id__once = 0;
	if (g_once_init_enter (&kkc_keymap_map_file_type_id__once)) {
		GType kkc_keymap_map_file_type_id;
		kkc_keymap_map_file_type_id = kkc_keymap_map_file_get_type_once ();
		g_once_init_leave (&kkc_keymap_map_file_type_id__once, kkc_keymap_map_file_type_id);
	}
	return kkc_keymap_map_file_type_id__once;
}

static gpointer
_json_array_ref0 (gpointer self)
{
	return self ? json_array_ref (self) : NULL;
}

static void
kkc_rom_kana_map_file_load_rom_kana (KkcRomKanaMapFile* self,
                                     KkcRomKanaNode* node,
                                     GeeMap* map,
                                     GError** error)
{
	GError* _inner_error0_ = NULL;
	g_return_if_fail (self != NULL);
	g_return_if_fail (node != NULL);
	g_return_if_fail (map != NULL);
	{
		GeeIterator* _key_it = NULL;
		GeeSet* _tmp0_;
		GeeSet* _tmp1_;
		GeeSet* _tmp2_;
		GeeIterator* _tmp3_;
		GeeIterator* _tmp4_;
		_tmp0_ = gee_map_get_keys (map);
		_tmp1_ = _tmp0_;
		_tmp2_ = _tmp1_;
		_tmp3_ = gee_iterable_iterator ((GeeIterable*) _tmp2_);
		_tmp4_ = _tmp3_;
		_g_object_unref0 (_tmp2_);
		_key_it = _tmp4_;
		while (TRUE) {
			GeeIterator* _tmp5_;
			gchar* key = NULL;
			GeeIterator* _tmp6_;
			gpointer _tmp7_;
			JsonNode* value = NULL;
			const gchar* _tmp8_;
			gpointer _tmp9_;
			JsonNode* _tmp10_;
			_tmp5_ = _key_it;
			if (!gee_iterator_next (_tmp5_)) {
				break;
			}
			_tmp6_ = _key_it;
			_tmp7_ = gee_iterator_get (_tmp6_);
			key = (gchar*) _tmp7_;
			_tmp8_ = key;
			_tmp9_ = gee_map_get (map, _tmp8_);
			value = (JsonNode*) _tmp9_;
			_tmp10_ = value;
			if (json_node_get_node_type (_tmp10_) == JSON_NODE_ARRAY) {
				JsonArray* components = NULL;
				JsonNode* _tmp11_;
				JsonArray* _tmp12_;
				JsonArray* _tmp13_;
				guint length = 0U;
				JsonArray* _tmp14_;
				gboolean _tmp15_ = FALSE;
				_tmp11_ = value;
				_tmp12_ = json_node_get_array (_tmp11_);
				_tmp13_ = _json_array_ref0 (_tmp12_);
				components = _tmp13_;
				_tmp14_ = components;
				length = json_array_get_length (_tmp14_);
				if (((guint) 2) <= length) {
					_tmp15_ = length <= ((guint) 5);
				} else {
					_tmp15_ = FALSE;
				}
				if (_tmp15_) {
					gchar* carryover = NULL;
					JsonArray* _tmp16_;
					const gchar* _tmp17_;
					gchar* _tmp18_;
					gchar* hiragana = NULL;
					JsonArray* _tmp19_;
					const gchar* _tmp20_;
					gchar* _tmp21_;
					gchar* _tmp22_ = NULL;
					gchar* katakana = NULL;
					gchar* _tmp28_;
					const gchar* _tmp29_ = NULL;
					gchar* hiragana_partial = NULL;
					gchar* _tmp32_;
					const gchar* _tmp33_ = NULL;
					gchar* katakana_partial = NULL;
					gchar* _tmp36_;
					KkcRomKanaEntry entry = {0};
					const gchar* _tmp37_;
					gchar* _tmp38_;
					const gchar* _tmp39_;
					gchar* _tmp40_;
					const gchar* _tmp41_;
					gchar* _tmp42_;
					const gchar* _tmp43_;
					gchar* _tmp44_;
					const gchar* _tmp45_;
					gchar* _tmp46_;
					const gchar* _tmp47_;
					gchar* _tmp48_;
					KkcRomKanaEntry _tmp49_ = {0};
					const gchar* _tmp50_;
					KkcRomKanaEntry _tmp51_;
					_tmp16_ = components;
					_tmp17_ = json_array_get_string_element (_tmp16_, (guint) 0);
					_tmp18_ = g_strdup (_tmp17_);
					carryover = _tmp18_;
					_tmp19_ = components;
					_tmp20_ = json_array_get_string_element (_tmp19_, (guint) 1);
					_tmp21_ = g_strdup (_tmp20_);
					hiragana = _tmp21_;
					if (length >= ((guint) 3)) {
						JsonArray* _tmp23_;
						const gchar* _tmp24_;
						gchar* _tmp25_;
						_tmp23_ = components;
						_tmp24_ = json_array_get_string_element (_tmp23_, (guint) 2);
						_tmp25_ = g_strdup (_tmp24_);
						_g_free0 (_tmp22_);
						_tmp22_ = _tmp25_;
					} else {
						const gchar* _tmp26_;
						gchar* _tmp27_;
						_tmp26_ = hiragana;
						_tmp27_ = kkc_rom_kana_utils_get_katakana (_tmp26_);
						_g_free0 (_tmp22_);
						_tmp22_ = _tmp27_;
					}
					_tmp28_ = _tmp22_;
					_tmp22_ = NULL;
					katakana = _tmp28_;
					if (length >= ((guint) 4)) {
						JsonArray* _tmp30_;
						const gchar* _tmp31_;
						_tmp30_ = components;
						_tmp31_ = json_array_get_string_element (_tmp30_, (guint) 3);
						_tmp29_ = _tmp31_;
					} else {
						_tmp29_ = "";
					}
					_tmp32_ = g_strdup (_tmp29_);
					hiragana_partial = _tmp32_;
					if (length >= ((guint) 5)) {
						JsonArray* _tmp34_;
						const gchar* _tmp35_;
						_tmp34_ = components;
						_tmp35_ = json_array_get_string_element (_tmp34_, (guint) 4);
						_tmp33_ = _tmp35_;
					} else {
						_tmp33_ = "";
					}
					_tmp36_ = g_strdup (_tmp33_);
					katakana_partial = _tmp36_;
					_tmp37_ = key;
					_tmp38_ = g_strdup (_tmp37_);
					_tmp39_ = carryover;
					_tmp40_ = g_strdup (_tmp39_);
					_tmp41_ = hiragana;
					_tmp42_ = g_strdup (_tmp41_);
					_tmp43_ = katakana;
					_tmp44_ = g_strdup (_tmp43_);
					_tmp45_ = hiragana_partial;
					_tmp46_ = g_strdup (_tmp45_);
					_tmp47_ = katakana_partial;
					_tmp48_ = g_strdup (_tmp47_);
					_g_free0 (_tmp49_.rom);
					_tmp49_.rom = _tmp38_;
					_g_free0 (_tmp49_.carryover);
					_tmp49_.carryover = _tmp40_;
					_g_free0 (_tmp49_.hiragana);
					_tmp49_.hiragana = _tmp42_;
					_g_free0 (_tmp49_.katakana);
					_tmp49_.katakana = _tmp44_;
					_g_free0 (_tmp49_.hiragana_partial);
					_tmp49_.hiragana_partial = _tmp46_;
					_g_free0 (_tmp49_.katakana_partial);
					_tmp49_.katakana_partial = _tmp48_;
					entry = _tmp49_;
					_tmp50_ = key;
					_tmp51_ = entry;
					kkc_rom_kana_node_insert (node, _tmp50_, &_tmp51_);
					kkc_rom_kana_entry_destroy (&entry);
					_g_free0 (katakana_partial);
					_g_free0 (hiragana_partial);
					_g_free0 (katakana);
					_g_free0 (_tmp22_);
					_g_free0 (hiragana);
					_g_free0 (carryover);
				} else {
					GError* _tmp52_;
					_tmp52_ = g_error_new_literal (KKC_RULE_PARSE_ERROR, KKC_RULE_PARSE_ERROR_FAILED, "\"rom-kana\" must have two to four elements");
					_inner_error0_ = _tmp52_;
					if (_inner_error0_->domain == KKC_RULE_PARSE_ERROR) {
						g_propagate_error (error, _inner_error0_);
						_json_array_unref0 (components);
						__vala_JsonNode_free0 (value);
						_g_free0 (key);
						_g_object_unref0 (_key_it);
						return;
					} else {
						_json_array_unref0 (components);
						__vala_JsonNode_free0 (value);
						_g_free0 (key);
						_g_object_unref0 (_key_it);
						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;
					}
				}
				_json_array_unref0 (components);
			} else {
				GError* _tmp53_;
				_tmp53_ = g_error_new_literal (KKC_RULE_PARSE_ERROR, KKC_RULE_PARSE_ERROR_FAILED, "\"rom-kana\" member must be either an array or null");
				_inner_error0_ = _tmp53_;
				if (_inner_error0_->domain == KKC_RULE_PARSE_ERROR) {
					g_propagate_error (error, _inner_error0_);
					__vala_JsonNode_free0 (value);
					_g_free0 (key);
					_g_object_unref0 (_key_it);
					return;
				} else {
					__vala_JsonNode_free0 (value);
					_g_free0 (key);
					_g_object_unref0 (_key_it);
					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;
				}
			}
			__vala_JsonNode_free0 (value);
			_g_free0 (key);
		}
		_g_object_unref0 (_key_it);
	}
}

KkcRomKanaMapFile*
kkc_rom_kana_map_file_construct (GType object_type,
                                 KkcRuleMetadata* metadata,
                                 GError** error)
{
	KkcRomKanaMapFile * self = NULL;
	KkcRomKanaNode* _tmp0_;
	GeeMap* parent_map = NULL;
	GeeMap* _tmp1_;
	GeeMap* map = NULL;
	GeeMap* _tmp2_;
	GeeMapIterator* iter = NULL;
	GeeMap* _tmp3_;
	GeeMapIterator* _tmp4_;
	KkcRomKanaNode* _tmp16_;
	GeeMap* _tmp17_;
	GError* _inner_error0_ = NULL;
	g_return_val_if_fail (metadata != NULL, NULL);
	self = (KkcRomKanaMapFile*) kkc_map_file_construct (object_type, metadata, "rom-kana", "default", &_inner_error0_);
	if (G_UNLIKELY (_inner_error0_ != NULL)) {
		if (_inner_error0_->domain == KKC_RULE_PARSE_ERROR) {
			g_propagate_error (error, _inner_error0_);
			_g_object_unref0 (self);
			return NULL;
		} else {
			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;
		}
	}
	_tmp0_ = kkc_rom_kana_node_new (NULL);
	_g_object_unref0 (self->root_node);
	self->root_node = _tmp0_;
	_tmp1_ = kkc_map_file_get_parent ((KkcMapFile*) self, "rom-kana");
	parent_map = _tmp1_;
	_tmp2_ = kkc_map_file_get ((KkcMapFile*) self, "rom-kana");
	map = _tmp2_;
	_tmp3_ = map;
	_tmp4_ = gee_map_map_iterator (_tmp3_);
	iter = _tmp4_;
	while (TRUE) {
		GeeMapIterator* _tmp5_;
		gchar* key = NULL;
		GeeMapIterator* _tmp6_;
		gpointer _tmp7_;
		JsonNode* value = NULL;
		GeeMapIterator* _tmp8_;
		gpointer _tmp9_;
		JsonNode* _tmp10_;
		_tmp5_ = iter;
		if (!gee_map_iterator_next (_tmp5_)) {
			break;
		}
		_tmp6_ = iter;
		_tmp7_ = gee_map_iterator_get_key (_tmp6_);
		key = (gchar*) _tmp7_;
		_tmp8_ = iter;
		_tmp9_ = gee_map_iterator_get_value (_tmp8_);
		value = (JsonNode*) _tmp9_;
		_tmp10_ = value;
		if (json_node_get_node_type (_tmp10_) == JSON_NODE_NULL) {
			GeeMap* _tmp11_;
			const gchar* _tmp12_;
			_tmp11_ = parent_map;
			_tmp12_ = key;
			gee_map_unset (_tmp11_, _tmp12_, NULL);
		} else {
			GeeMap* _tmp13_;
			const gchar* _tmp14_;
			JsonNode* _tmp15_;
			_tmp13_ = parent_map;
			_tmp14_ = key;
			_tmp15_ = value;
			gee_map_set (_tmp13_, _tmp14_, _tmp15_);
		}
		__vala_JsonNode_free0 (value);
		_g_free0 (key);
	}
	_tmp16_ = self->root_node;
	_tmp17_ = parent_map;
	kkc_rom_kana_map_file_load_rom_kana (self, _tmp16_, _tmp17_, &_inner_error0_);
	if (G_UNLIKELY (_inner_error0_ != NULL)) {
		if (_inner_error0_->domain == KKC_RULE_PARSE_ERROR) {
			g_propagate_error (error, _inner_error0_);
			_g_object_unref0 (iter);
			_g_object_unref0 (map);
			_g_object_unref0 (parent_map);
			_g_object_unref0 (self);
			return NULL;
		} else {
			_g_object_unref0 (iter);
			_g_object_unref0 (map);
			_g_object_unref0 (parent_map);
			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;
		}
	}
	_g_object_unref0 (iter);
	_g_object_unref0 (map);
	_g_object_unref0 (parent_map);
	return self;
}

KkcRomKanaMapFile*
kkc_rom_kana_map_file_new (KkcRuleMetadata* metadata,
                           GError** error)
{
	return kkc_rom_kana_map_file_construct (KKC_TYPE_ROM_KANA_MAP_FILE, metadata, error);
}

static void
kkc_rom_kana_map_file_class_init (KkcRomKanaMapFileClass * klass,
                                  gpointer klass_data)
{
	kkc_rom_kana_map_file_parent_class = g_type_class_peek_parent (klass);
	G_OBJECT_CLASS (klass)->finalize = kkc_rom_kana_map_file_finalize;
}

static void
kkc_rom_kana_map_file_instance_init (KkcRomKanaMapFile * self,
                                     gpointer klass)
{
}

static void
kkc_rom_kana_map_file_finalize (GObject * obj)
{
	KkcRomKanaMapFile * self;
	self = G_TYPE_CHECK_INSTANCE_CAST (obj, KKC_TYPE_ROM_KANA_MAP_FILE, KkcRomKanaMapFile);
	_g_object_unref0 (self->root_node);
	G_OBJECT_CLASS (kkc_rom_kana_map_file_parent_class)->finalize (obj);
}

static GType
kkc_rom_kana_map_file_get_type_once (void)
{
	static const GTypeInfo g_define_type_info = { sizeof (KkcRomKanaMapFileClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) kkc_rom_kana_map_file_class_init, (GClassFinalizeFunc) NULL, NULL, sizeof (KkcRomKanaMapFile), 0, (GInstanceInitFunc) kkc_rom_kana_map_file_instance_init, NULL };
	GType kkc_rom_kana_map_file_type_id;
	kkc_rom_kana_map_file_type_id = g_type_register_static (KKC_TYPE_MAP_FILE, "KkcRomKanaMapFile", &g_define_type_info, 0);
	return kkc_rom_kana_map_file_type_id;
}

GType
kkc_rom_kana_map_file_get_type (void)
{
	static volatile gsize kkc_rom_kana_map_file_type_id__once = 0;
	if (g_once_init_enter (&kkc_rom_kana_map_file_type_id__once)) {
		GType kkc_rom_kana_map_file_type_id;
		kkc_rom_kana_map_file_type_id = kkc_rom_kana_map_file_get_type_once ();
		g_once_init_leave (&kkc_rom_kana_map_file_type_id__once, kkc_rom_kana_map_file_type_id);
	}
	return kkc_rom_kana_map_file_type_id__once;
}

GQuark
kkc_rule_parse_error_quark (void)
{
	return g_quark_from_static_string ("kkc-rule-parse-error-quark");
}

static GType
kkc_rule_parse_error_get_type_once (void)
{
	static const GEnumValue values[] = {{KKC_RULE_PARSE_ERROR_FAILED, "KKC_RULE_PARSE_ERROR_FAILED", "failed"}, {0, NULL, NULL}};
	GType kkc_rule_parse_error_type_id;
	kkc_rule_parse_error_type_id = g_enum_register_static ("KkcRuleParseError", values);
	return kkc_rule_parse_error_type_id;
}

GType
kkc_rule_parse_error_get_type (void)
{
	static volatile gsize kkc_rule_parse_error_type_id__once = 0;
	if (g_once_init_enter (&kkc_rule_parse_error_type_id__once)) {
		GType kkc_rule_parse_error_type_id;
		kkc_rule_parse_error_type_id = kkc_rule_parse_error_get_type_once ();
		g_once_init_leave (&kkc_rule_parse_error_type_id__once, kkc_rule_parse_error_type_id);
	}
	return kkc_rule_parse_error_type_id__once;
}

static inline gpointer
kkc_rule_metadata_get_instance_private (KkcRuleMetadata* self)
{
	return G_STRUCT_MEMBER_P (self, KkcRuleMetadata_private_offset);
}

KkcRuleMetadata*
kkc_rule_metadata_construct (GType object_type,
                             const gchar* name,
                             const gchar* filename,
                             GError** error)
{
	KkcRuleMetadata * self = NULL;
	GError* _inner_error0_ = NULL;
	g_return_val_if_fail (name != NULL, NULL);
	g_return_val_if_fail (filename != NULL, NULL);
	self = (KkcRuleMetadata*) kkc_metadata_file_construct (object_type, name, filename, &_inner_error0_);
	if (G_UNLIKELY (_inner_error0_ != NULL)) {
		g_propagate_error (error, _inner_error0_);
		_g_object_unref0 (self);
		return NULL;
	}
	return self;
}

KkcRuleMetadata*
kkc_rule_metadata_new (const gchar* name,
                       const gchar* filename,
                       GError** error)
{
	return kkc_rule_metadata_construct (KKC_TYPE_RULE_METADATA, name, filename, error);
}

static gboolean
kkc_rule_metadata_real_parse (KkcMetadataFile* base,
                              JsonObject* object,
                              GError** error)
{
	KkcRuleMetadata * self;
	gchar* filter = NULL;
	gchar* _tmp0_;
	const gchar* _tmp8_;
	GError* _inner_error0_ = NULL;
	gboolean result;
	self = (KkcRuleMetadata*) base;
	g_return_val_if_fail (object != NULL, FALSE);
	_tmp0_ = g_strdup ("simple");
	filter = _tmp0_;
	if (json_object_has_member (object, "filter")) {
		const gchar* _tmp1_;
		gchar* _tmp2_;
		GeeMap* _tmp3_;
		const gchar* _tmp4_;
		_tmp1_ = json_object_get_string_member (object, "filter");
		_tmp2_ = g_strdup (_tmp1_);
		_g_free0 (filter);
		filter = _tmp2_;
		_tmp3_ = kkc_rule_metadata_filter_types;
		_tmp4_ = filter;
		if (!gee_map_has_key (_tmp3_, _tmp4_)) {
			const gchar* _tmp5_;
			GError* _tmp6_;
			gboolean _tmp7_ = FALSE;
			_tmp5_ = filter;
			_tmp6_ = g_error_new (KKC_METADATA_FORMAT_ERROR, KKC_METADATA_FORMAT_ERROR_INVALID_FIELD, "unknown filter type %s", _tmp5_);
			_inner_error0_ = _tmp6_;
			g_propagate_error (error, _inner_error0_);
			_g_free0 (filter);
			return _tmp7_;
		}
	}
	_tmp8_ = filter;
	kkc_rule_metadata_set_filter (self, _tmp8_);
	if (json_object_has_member (object, "priority")) {
		kkc_rule_metadata_set_priority (self, (gint) json_object_get_int_member (object, "priority"));
	}
	result = TRUE;
	_g_free0 (filter);
	return result;
}

KkcKeyEventFilter*
kkc_rule_metadata_create_key_event_filter (KkcRuleMetadata* self)
{
	GType* type = NULL;
	GeeMap* _tmp0_;
	const gchar* _tmp1_;
	gpointer _tmp2_;
	GObject* _tmp3_;
	GObject* _tmp4_;
	KkcKeyEventFilter* result;
	g_return_val_if_fail (self != NULL, NULL);
	_tmp0_ = kkc_rule_metadata_filter_types;
	_tmp1_ = self->priv->_filter;
	_tmp2_ = gee_map_get (_tmp0_, _tmp1_);
	type = (GType*) _tmp2_;
	_tmp3_ = g_object_new (*type, NULL);
	_tmp4_ = G_IS_INITIALLY_UNOWNED (_tmp3_) ? g_object_ref_sink (_tmp3_) : _tmp3_;
	result = G_TYPE_CHECK_INSTANCE_CAST (_tmp4_, KKC_TYPE_KEY_EVENT_FILTER, KkcKeyEventFilter);
	_g_free0 (type);
	return result;
}

/**
         * Return the path of the map file.
         *
         * @param type type of the map file
         * @param name name of the map file
         *
         * @return the absolute path of the map file
         */
gchar*
kkc_rule_metadata_locate_map_file (KkcRuleMetadata* self,
                                   const gchar* type,
                                   const gchar* name)
{
	gchar* map_filename = NULL;
	const gchar* _tmp0_;
	const gchar* _tmp1_;
	gchar* _tmp2_;
	gchar* _tmp3_;
	gchar* _tmp4_;
	gchar* _tmp5_;
	gchar* _tmp6_;
	gchar* _tmp7_;
	const gchar* _tmp8_;
	gchar* result;
	g_return_val_if_fail (self != NULL, NULL);
	g_return_val_if_fail (type != NULL, NULL);
	g_return_val_if_fail (name != NULL, NULL);
	_tmp0_ = kkc_metadata_file_get_filename ((KkcMetadataFile*) self);
	_tmp1_ = _tmp0_;
	_tmp2_ = g_path_get_dirname (_tmp1_);
	_tmp3_ = _tmp2_;
	_tmp4_ = g_strconcat (name, ".json", NULL);
	_tmp5_ = _tmp4_;
	_tmp6_ = g_build_filename (_tmp3_, type, _tmp5_, NULL);
	_tmp7_ = _tmp6_;
	_g_free0 (_tmp5_);
	_g_free0 (_tmp3_);
	map_filename = _tmp7_;
	_tmp8_ = map_filename;
	if (g_file_test (_tmp8_, G_FILE_TEST_EXISTS)) {
		result = map_filename;
		return result;
	}
	result = NULL;
	_g_free0 (map_filename);
	return result;
}

/**
         * Locate a rule metadata by name.
         *
         * @param name name of the rule
         *
         * @return a RuleMetadata or `null`
         */
KkcRuleMetadata*
kkc_rule_metadata_find (const gchar* name)
{
	GeeMap* _tmp0_;
	gchar** dirs = NULL;
	gint _tmp3_ = 0;
	gchar** _tmp4_;
	gint dirs_length1;
	gint _dirs_size_;
	gchar** _tmp5_;
	gint _tmp5__length1;
	GError* _inner_error0_ = NULL;
	KkcRuleMetadata* result;
	g_return_val_if_fail (name != NULL, NULL);
	_tmp0_ = kkc_rule_metadata_instance_cache;
	if (gee_map_has_key (_tmp0_, name)) {
		GeeMap* _tmp1_;
		gpointer _tmp2_;
		_tmp1_ = kkc_rule_metadata_instance_cache;
		_tmp2_ = gee_map_get (_tmp1_, name);
		result = (KkcRuleMetadata*) _tmp2_;
		return result;
	}
	_tmp4_ = kkc_utils_build_data_path ("rules", &_tmp3_);
	dirs = _tmp4_;
	dirs_length1 = _tmp3_;
	_dirs_size_ = dirs_length1;
	_tmp5_ = dirs;
	_tmp5__length1 = dirs_length1;
	{
		gchar** dir_collection = NULL;
		gint dir_collection_length1 = 0;
		gint _dir_collection_size_ = 0;
		gint dir_it = 0;
		dir_collection = _tmp5_;
		dir_collection_length1 = _tmp5__length1;
		for (dir_it = 0; dir_it < dir_collection_length1; dir_it = dir_it + 1) {
			gchar* _tmp6_;
			gchar* dir = NULL;
			_tmp6_ = g_strdup (dir_collection[dir_it]);
			dir = _tmp6_;
			{
				gchar* base_dir_filename = NULL;
				const gchar* _tmp7_;
				gchar* _tmp8_;
				gchar* metadata_filename = NULL;
				const gchar* _tmp9_;
				gchar* _tmp10_;
				const gchar* _tmp11_;
				_tmp7_ = dir;
				_tmp8_ = g_build_filename (_tmp7_, name, NULL);
				base_dir_filename = _tmp8_;
				_tmp9_ = base_dir_filename;
				_tmp10_ = g_build_filename (_tmp9_, "metadata.json", NULL);
				metadata_filename = _tmp10_;
				_tmp11_ = metadata_filename;
				if (g_file_test (_tmp11_, G_FILE_TEST_EXISTS)) {
					{
						KkcRuleMetadata* metadata = NULL;
						const gchar* _tmp12_;
						KkcRuleMetadata* _tmp13_;
						GeeMap* _tmp14_;
						KkcRuleMetadata* _tmp15_;
						_tmp12_ = metadata_filename;
						_tmp13_ = kkc_rule_metadata_new (name, _tmp12_, &_inner_error0_);
						metadata = _tmp13_;
						if (G_UNLIKELY (_inner_error0_ != NULL)) {
							goto __catch0_g_error;
						}
						_tmp14_ = kkc_rule_metadata_instance_cache;
						_tmp15_ = metadata;
						gee_map_set (_tmp14_, name, _tmp15_);
						result = metadata;
						_g_free0 (metadata_filename);
						_g_free0 (base_dir_filename);
						_g_free0 (dir);
						dirs = (_vala_array_free (dirs, dirs_length1, (GDestroyNotify) g_free), NULL);
						return result;
					}
					goto __finally0;
					__catch0_g_error:
					{
						g_clear_error (&_inner_error0_);
						_g_free0 (metadata_filename);
						_g_free0 (base_dir_filename);
						_g_free0 (dir);
						continue;
					}
					__finally0:
					_g_free0 (metadata_filename);
					_g_free0 (base_dir_filename);
					_g_free0 (dir);
					dirs = (_vala_array_free (dirs, dirs_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;
				}
				_g_free0 (metadata_filename);
				_g_free0 (base_dir_filename);
				_g_free0 (dir);
			}
		}
	}
	result = NULL;
	dirs = (_vala_array_free (dirs, dirs_length1, (GDestroyNotify) g_free), NULL);
	return result;
}

const gchar*
kkc_rule_metadata_get_filter (KkcRuleMetadata* self)
{
	const gchar* result;
	const gchar* _tmp0_;
	g_return_val_if_fail (self != NULL, NULL);
	_tmp0_ = self->priv->_filter;
	result = _tmp0_;
	return result;
}

void
kkc_rule_metadata_set_filter (KkcRuleMetadata* self,
                              const gchar* value)
{
	gchar* old_value;
	g_return_if_fail (self != NULL);
	old_value = kkc_rule_metadata_get_filter (self);
	if (g_strcmp0 (value, old_value) != 0) {
		gchar* _tmp0_;
		_tmp0_ = g_strdup (value);
		_g_free0 (self->priv->_filter);
		self->priv->_filter = _tmp0_;
		g_object_notify_by_pspec ((GObject *) self, kkc_rule_metadata_properties[KKC_RULE_METADATA_FILTER_PROPERTY]);
	}
}

gint
kkc_rule_metadata_get_priority (KkcRuleMetadata* self)
{
	gint result;
	g_return_val_if_fail (self != NULL, -1);
	result = self->priv->_priority;
	return result;
}

void
kkc_rule_metadata_set_priority (KkcRuleMetadata* self,
                                gint value)
{
	gint old_value;
	g_return_if_fail (self != NULL);
	old_value = kkc_rule_metadata_get_priority (self);
	if (old_value != value) {
		self->priv->_priority = value;
		g_object_notify_by_pspec ((GObject *) self, kkc_rule_metadata_properties[KKC_RULE_METADATA_PRIORITY_PROPERTY]);
	}
}

static GType*
_g_type_dup (GType* self)
{
	GType* dup;
	dup = g_new0 (GType, 1);
	memcpy (dup, self, sizeof (GType));
	return dup;
}

static void
kkc_rule_metadata_class_init (KkcRuleMetadataClass * klass,
                              gpointer klass_data)
{
	GeeHashMap* _tmp0_;
	GeeHashMap* _tmp1_;
	GeeMap* _tmp2_;
	GType _tmp3_;
	GeeMap* _tmp4_;
	GType _tmp5_;
	GeeMap* _tmp6_;
	GType _tmp7_;
	kkc_rule_metadata_parent_class = g_type_class_peek_parent (klass);
	g_type_class_adjust_private_offset (klass, &KkcRuleMetadata_private_offset);
	((KkcMetadataFileClass *) klass)->parse = (gboolean (*) (KkcMetadataFile*, JsonObject*, GError**)) kkc_rule_metadata_real_parse;
	G_OBJECT_CLASS (klass)->get_property = _vala_kkc_rule_metadata_get_property;
	G_OBJECT_CLASS (klass)->set_property = _vala_kkc_rule_metadata_set_property;
	G_OBJECT_CLASS (klass)->finalize = kkc_rule_metadata_finalize;
	/**
	         * Name of key event filter.
	         */
	g_object_class_install_property (G_OBJECT_CLASS (klass), KKC_RULE_METADATA_FILTER_PROPERTY, kkc_rule_metadata_properties[KKC_RULE_METADATA_FILTER_PROPERTY] = g_param_spec_string ("filter", "filter", "filter", NULL, G_PARAM_STATIC_STRINGS | G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT));
	/**
	         * Priority of the rule.
	         */
	g_object_class_install_property (G_OBJECT_CLASS (klass), KKC_RULE_METADATA_PRIORITY_PROPERTY, kkc_rule_metadata_properties[KKC_RULE_METADATA_PRIORITY_PROPERTY] = g_param_spec_int ("priority", "priority", "priority", G_MININT, G_MAXINT, 0, G_PARAM_STATIC_STRINGS | G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT));
	_tmp0_ = gee_hash_map_new (G_TYPE_STRING, (GBoxedCopyFunc) g_strdup, (GDestroyNotify) g_free, G_TYPE_GTYPE, (GBoxedCopyFunc) _g_type_dup, (GDestroyNotify) g_free, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
	_g_object_unref0 (kkc_rule_metadata_filter_types);
	kkc_rule_metadata_filter_types = (GeeMap*) _tmp0_;
	_tmp1_ = gee_hash_map_new (G_TYPE_STRING, (GBoxedCopyFunc) g_strdup, (GDestroyNotify) g_free, KKC_TYPE_RULE_METADATA, (GBoxedCopyFunc) g_object_ref, (GDestroyNotify) g_object_unref, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
	_g_object_unref0 (kkc_rule_metadata_instance_cache);
	kkc_rule_metadata_instance_cache = (GeeMap*) _tmp1_;
	_tmp2_ = kkc_rule_metadata_filter_types;
	_tmp3_ = KKC_TYPE_SIMPLE_KEY_EVENT_FILTER;
	gee_map_set (_tmp2_, "simple", &_tmp3_);
	_tmp4_ = kkc_rule_metadata_filter_types;
	_tmp5_ = KKC_TYPE_NICOLA_KEY_EVENT_FILTER;
	gee_map_set (_tmp4_, "nicola", &_tmp5_);
	_tmp6_ = kkc_rule_metadata_filter_types;
	_tmp7_ = KKC_TYPE_KANA_KEY_EVENT_FILTER;
	gee_map_set (_tmp6_, "kana", &_tmp7_);
}

static void
kkc_rule_metadata_instance_init (KkcRuleMetadata * self,
                                 gpointer klass)
{
	self->priv = kkc_rule_metadata_get_instance_private (self);
	self->priv->_priority = 0;
}

static void
kkc_rule_metadata_finalize (GObject * obj)
{
	KkcRuleMetadata * self;
	self = G_TYPE_CHECK_INSTANCE_CAST (obj, KKC_TYPE_RULE_METADATA, KkcRuleMetadata);
	_g_free0 (self->priv->_filter);
	G_OBJECT_CLASS (kkc_rule_metadata_parent_class)->finalize (obj);
}

/**
     * Object describing a rule.
     */
static GType
kkc_rule_metadata_get_type_once (void)
{
	static const GTypeInfo g_define_type_info = { sizeof (KkcRuleMetadataClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) kkc_rule_metadata_class_init, (GClassFinalizeFunc) NULL, NULL, sizeof (KkcRuleMetadata), 0, (GInstanceInitFunc) kkc_rule_metadata_instance_init, NULL };
	GType kkc_rule_metadata_type_id;
	kkc_rule_metadata_type_id = g_type_register_static (KKC_TYPE_METADATA_FILE, "KkcRuleMetadata", &g_define_type_info, 0);
	KkcRuleMetadata_private_offset = g_type_add_instance_private (kkc_rule_metadata_type_id, sizeof (KkcRuleMetadataPrivate));
	return kkc_rule_metadata_type_id;
}

GType
kkc_rule_metadata_get_type (void)
{
	static volatile gsize kkc_rule_metadata_type_id__once = 0;
	if (g_once_init_enter (&kkc_rule_metadata_type_id__once)) {
		GType kkc_rule_metadata_type_id;
		kkc_rule_metadata_type_id = kkc_rule_metadata_get_type_once ();
		g_once_init_leave (&kkc_rule_metadata_type_id__once, kkc_rule_metadata_type_id);
	}
	return kkc_rule_metadata_type_id__once;
}

static void
_vala_kkc_rule_metadata_get_property (GObject * object,
                                      guint property_id,
                                      GValue * value,
                                      GParamSpec * pspec)
{
	KkcRuleMetadata * self;
	self = G_TYPE_CHECK_INSTANCE_CAST (object, KKC_TYPE_RULE_METADATA, KkcRuleMetadata);
	switch (property_id) {
		case KKC_RULE_METADATA_FILTER_PROPERTY:
		g_value_set_string (value, kkc_rule_metadata_get_filter (self));
		break;
		case KKC_RULE_METADATA_PRIORITY_PROPERTY:
		g_value_set_int (value, kkc_rule_metadata_get_priority (self));
		break;
		default:
		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
		break;
	}
}

static void
_vala_kkc_rule_metadata_set_property (GObject * object,
                                      guint property_id,
                                      const GValue * value,
                                      GParamSpec * pspec)
{
	KkcRuleMetadata * self;
	self = G_TYPE_CHECK_INSTANCE_CAST (object, KKC_TYPE_RULE_METADATA, KkcRuleMetadata);
	switch (property_id) {
		case KKC_RULE_METADATA_FILTER_PROPERTY:
		kkc_rule_metadata_set_filter (self, g_value_get_string (value));
		break;
		case KKC_RULE_METADATA_PRIORITY_PROPERTY:
		kkc_rule_metadata_set_priority (self, g_value_get_int (value));
		break;
		default:
		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
		break;
	}
}

static inline gpointer
kkc_rule_get_instance_private (KkcRule* self)
{
	return G_STRUCT_MEMBER_P (self, KkcRule_private_offset);
}

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

KkcKeymap*
kkc_rule_get_keymap (KkcRule* self,
                     KkcInputMode mode)
{
	KkcKeymapMapFile** _tmp0_;
	gint _tmp0__length1;
	KkcKeymapMapFile* _tmp1_;
	KkcKeymap* _tmp2_;
	KkcKeymap* _tmp3_;
	KkcKeymap* result;
	g_return_val_if_fail (self != NULL, NULL);
	_tmp0_ = self->priv->keymaps;
	_tmp0__length1 = self->priv->keymaps_length1;
	_tmp1_ = _tmp0_[mode];
	_tmp2_ = _tmp1_->keymap;
	_tmp3_ = _g_object_ref0 (_tmp2_);
	result = _tmp3_;
	return result;
}

/**
         * Create a rule.
         *
         * @param metadata metadata of the rule
         *
         * @return a new Rule
         */
KkcRule*
kkc_rule_construct (GType object_type,
                    KkcRuleMetadata* metadata,
                    GError** error)
{
	KkcRule * self = NULL;
	GError* _inner_error0_ = NULL;
	g_return_val_if_fail (metadata != NULL, NULL);
	self = (KkcRule*) g_object_new (object_type, "metadata", metadata, NULL);
	g_initable_init ((GInitable*) self, NULL, &_inner_error0_);
	if (G_UNLIKELY (_inner_error0_ != NULL)) {
		g_propagate_error (error, _inner_error0_);
		_g_object_unref0 (self);
		return NULL;
	}
	return self;
}

KkcRule*
kkc_rule_new (KkcRuleMetadata* metadata,
              GError** error)
{
	return kkc_rule_construct (KKC_TYPE_RULE, metadata, error);
}

static GEnumValue*
_g_enum_value_dup (GEnumValue* self)
{
	GEnumValue* dup;
	dup = g_new0 (GEnumValue, 1);
	memcpy (dup, self, sizeof (GEnumValue));
	return dup;
}

static gpointer
__g_enum_value_dup0 (gpointer self)
{
	return self ? _g_enum_value_dup (self) : NULL;
}

static gboolean
kkc_rule_real_init (GInitable* base,
                    GCancellable* cancellable,
                    GError** error)
{
	KkcRule * self;
	KkcRuleMetadata* default_metadata = NULL;
	KkcRuleMetadata* _tmp0_;
	GEnumClass* enum_class = NULL;
	GTypeClass* _tmp1_;
	GEnumClass* _tmp2_;
	KkcKeymapMapFile** _tmp3_;
	KkcRuleMetadata* _metadata = NULL;
	KkcRuleMetadata* _tmp30_;
	KkcRuleMetadata* _tmp31_;
	KkcRuleMetadata* _tmp32_;
	gchar* _tmp33_;
	gchar* _tmp34_;
	gboolean _tmp35_;
	KkcRomKanaMapFile* _tmp38_ = NULL;
	KkcRuleMetadata* _tmp39_;
	KkcRomKanaMapFile* _tmp40_;
	KkcRomKanaMapFile* _tmp42_;
	KkcRuleMetadata* _tmp43_;
	KkcKeyEventFilter* _tmp44_;
	KkcKeyEventFilter* _tmp45_;
	GError* _inner_error0_ = NULL;
	gboolean result;
	self = (KkcRule*) base;
	_tmp0_ = kkc_rule_metadata_find ("default");
	default_metadata = _tmp0_;
	_tmp1_ = g_type_class_ref (KKC_TYPE_INPUT_MODE);
	enum_class = (GEnumClass*) _tmp1_;
	_tmp2_ = enum_class;
	_tmp3_ = g_new0 (KkcKeymapMapFile*, (_tmp2_->maximum + 1) + 1);
	self->priv->keymaps = (_vala_array_free (self->priv->keymaps, self->priv->keymaps_length1, (GDestroyNotify) g_object_unref), NULL);
	self->priv->keymaps = _tmp3_;
	self->priv->keymaps_length1 = _tmp2_->maximum + 1;
	self->priv->_keymaps_size_ = self->priv->keymaps_length1;
	{
		gint i = 0;
		GEnumClass* _tmp4_;
		_tmp4_ = enum_class;
		i = _tmp4_->minimum;
		{
			gboolean _tmp5_ = FALSE;
			_tmp5_ = TRUE;
			while (TRUE) {
				GEnumClass* _tmp7_;
				GEnumValue* enum_value = NULL;
				GEnumClass* _tmp8_;
				GEnumValue* _tmp9_;
				GEnumValue* _tmp10_;
				if (!_tmp5_) {
					gint _tmp6_;
					_tmp6_ = i;
					i = _tmp6_ + 1;
				}
				_tmp5_ = FALSE;
				_tmp7_ = enum_class;
				if (!(i <= _tmp7_->maximum)) {
					break;
				}
				_tmp8_ = enum_class;
				_tmp9_ = __g_enum_value_dup0 (g_enum_get_value (_tmp8_, i));
				enum_value = _tmp9_;
				_tmp10_ = enum_value;
				if (_tmp10_ != NULL) {
					KkcRuleMetadata* _metadata = NULL;
					KkcRuleMetadata* _tmp11_;
					KkcRuleMetadata* _tmp12_;
					KkcRuleMetadata* _tmp13_;
					GEnumValue* _tmp14_;
					const gchar* _tmp15_;
					gchar* _tmp16_;
					gchar* _tmp17_;
					gboolean _tmp18_;
					KkcKeymapMapFile* _tmp21_ = NULL;
					KkcRuleMetadata* _tmp22_;
					GEnumValue* _tmp23_;
					const gchar* _tmp24_;
					KkcKeymapMapFile* _tmp25_;
					KkcKeymapMapFile** _tmp27_;
					gint _tmp27__length1;
					GEnumValue* _tmp28_;
					KkcKeymapMapFile* _tmp29_;
					_tmp11_ = self->priv->_metadata;
					_tmp12_ = _g_object_ref0 (_tmp11_);
					_metadata = _tmp12_;
					_tmp13_ = _metadata;
					_tmp14_ = enum_value;
					_tmp15_ = (*_tmp14_).value_nick;
					_tmp16_ = kkc_rule_metadata_locate_map_file (_tmp13_, "keymap", _tmp15_);
					_tmp17_ = _tmp16_;
					_tmp18_ = _tmp17_ == NULL;
					_g_free0 (_tmp17_);
					if (_tmp18_) {
						KkcRuleMetadata* _tmp19_;
						KkcRuleMetadata* _tmp20_;
						_tmp19_ = default_metadata;
						_tmp20_ = _g_object_ref0 (_tmp19_);
						_g_object_unref0 (_metadata);
						_metadata = _tmp20_;
					}
					_tmp22_ = _metadata;
					_tmp23_ = enum_value;
					_tmp24_ = (*_tmp23_).value_nick;
					_tmp25_ = kkc_keymap_map_file_new (_tmp22_, _tmp24_, &_inner_error0_);
					_tmp21_ = _tmp25_;
					if (G_UNLIKELY (_inner_error0_ != NULL)) {
						gboolean _tmp26_ = FALSE;
						g_propagate_error (error, _inner_error0_);
						_g_object_unref0 (_metadata);
						_g_free0 (enum_value);
						_g_type_class_unref0 (enum_class);
						_g_object_unref0 (default_metadata);
						return _tmp26_;
					}
					_tmp27_ = self->priv->keymaps;
					_tmp27__length1 = self->priv->keymaps_length1;
					_tmp28_ = enum_value;
					_tmp29_ = _tmp21_;
					_tmp21_ = NULL;
					_g_object_unref0 (_tmp27_[(*_tmp28_).value]);
					_tmp27_[(*_tmp28_).value] = _tmp29_;
					_g_object_unref0 (_tmp21_);
					_g_object_unref0 (_metadata);
				}
				_g_free0 (enum_value);
			}
		}
	}
	_tmp30_ = self->priv->_metadata;
	_tmp31_ = _g_object_ref0 (_tmp30_);
	_metadata = _tmp31_;
	_tmp32_ = _metadata;
	_tmp33_ = kkc_rule_metadata_locate_map_file (_tmp32_, "rom-kana", "default");
	_tmp34_ = _tmp33_;
	_tmp35_ = _tmp34_ == NULL;
	_g_free0 (_tmp34_);
	if (_tmp35_) {
		KkcRuleMetadata* _tmp36_;
		KkcRuleMetadata* _tmp37_;
		_tmp36_ = default_metadata;
		_tmp37_ = _g_object_ref0 (_tmp36_);
		_g_object_unref0 (_metadata);
		_metadata = _tmp37_;
	}
	_tmp39_ = _metadata;
	_tmp40_ = kkc_rom_kana_map_file_new (_tmp39_, &_inner_error0_);
	_tmp38_ = _tmp40_;
	if (G_UNLIKELY (_inner_error0_ != NULL)) {
		gboolean _tmp41_ = FALSE;
		g_propagate_error (error, _inner_error0_);
		_g_object_unref0 (_metadata);
		_g_type_class_unref0 (enum_class);
		_g_object_unref0 (default_metadata);
		return _tmp41_;
	}
	_tmp42_ = _tmp38_;
	_tmp38_ = NULL;
	_g_object_unref0 (self->rom_kana);
	self->rom_kana = _tmp42_;
	_tmp43_ = _metadata;
	_tmp44_ = kkc_rule_metadata_create_key_event_filter (_tmp43_);
	_tmp45_ = _tmp44_;
	kkc_rule_set_filter (self, _tmp45_);
	_g_object_unref0 (_tmp45_);
	result = TRUE;
	_g_object_unref0 (_tmp38_);
	_g_object_unref0 (_metadata);
	_g_type_class_unref0 (enum_class);
	_g_object_unref0 (default_metadata);
	return result;
}

/**
         * List rules.
         *
         * @return an array of RuleMetadata
         */
static void
_vala_array_add5 (KkcRuleMetadata** * array,
                  gint* length,
                  gint* size,
                  KkcRuleMetadata* value)
{
	if ((*length) == (*size)) {
		*size = (*size) ? (2 * (*size)) : 4;
		*array = g_renew (KkcRuleMetadata*, *array, (*size) + 1);
	}
	(*array)[(*length)++] = value;
	(*array)[*length] = NULL;
}

KkcRuleMetadata**
kkc_rule_list (gint* result_length1)
{
	GeeSet* names = NULL;
	GeeHashSet* _tmp0_;
	KkcRuleMetadata** rules = NULL;
	KkcRuleMetadata** _tmp1_;
	gint rules_length1;
	gint _rules_size_;
	gchar** dirs = NULL;
	gint _tmp2_ = 0;
	gchar** _tmp3_;
	gint dirs_length1;
	gint _dirs_size_;
	gchar** _tmp4_;
	gint _tmp4__length1;
	KkcRuleMetadata** _tmp32_;
	gint _tmp32__length1;
	GError* _inner_error0_ = NULL;
	KkcRuleMetadata** result;
	_tmp0_ = gee_hash_set_new (G_TYPE_STRING, (GBoxedCopyFunc) g_strdup, (GDestroyNotify) g_free, NULL, NULL, NULL, NULL, NULL, NULL);
	names = (GeeSet*) _tmp0_;
	_tmp1_ = g_new0 (KkcRuleMetadata*, 0 + 1);
	rules = _tmp1_;
	rules_length1 = 0;
	_rules_size_ = rules_length1;
	_tmp3_ = kkc_utils_build_data_path ("rules", &_tmp2_);
	dirs = _tmp3_;
	dirs_length1 = _tmp2_;
	_dirs_size_ = dirs_length1;
	_tmp4_ = dirs;
	_tmp4__length1 = dirs_length1;
	{
		gchar** dir_collection = NULL;
		gint dir_collection_length1 = 0;
		gint _dir_collection_size_ = 0;
		gint dir_it = 0;
		dir_collection = _tmp4_;
		dir_collection_length1 = _tmp4__length1;
		for (dir_it = 0; dir_it < dir_collection_length1; dir_it = dir_it + 1) {
			gchar* _tmp5_;
			gchar* dir = NULL;
			_tmp5_ = g_strdup (dir_collection[dir_it]);
			dir = _tmp5_;
			{
				GDir* handle = NULL;
				gchar* name = NULL;
				{
					GDir* _tmp6_ = NULL;
					const gchar* _tmp7_;
					GDir* _tmp8_;
					GDir* _tmp9_;
					_tmp7_ = dir;
					_tmp8_ = g_dir_open (_tmp7_, (guint) 0, &_inner_error0_);
					_tmp6_ = _tmp8_;
					if (G_UNLIKELY (_inner_error0_ != NULL)) {
						goto __catch0_g_error;
					}
					_tmp9_ = _tmp6_;
					_tmp6_ = NULL;
					_g_dir_close0 (handle);
					handle = _tmp9_;
					_g_dir_close0 (_tmp6_);
				}
				goto __finally0;
				__catch0_g_error:
				{
					g_clear_error (&_inner_error0_);
					_g_dir_close0 (handle);
					_g_free0 (dir);
					continue;
				}
				__finally0:
				if (G_UNLIKELY (_inner_error0_ != NULL)) {
					_g_dir_close0 (handle);
					_g_free0 (dir);
					dirs = (_vala_array_free (dirs, dirs_length1, (GDestroyNotify) g_free), NULL);
					rules = (_vala_array_free (rules, rules_length1, (GDestroyNotify) g_object_unref), NULL);
					_g_object_unref0 (names);
					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;
				}
				while (TRUE) {
					GDir* _tmp10_;
					const gchar* _tmp11_;
					gchar* _tmp12_;
					const gchar* _tmp13_;
					GeeSet* _tmp14_;
					const gchar* _tmp15_;
					gchar* metadata_filename = NULL;
					const gchar* _tmp16_;
					const gchar* _tmp17_;
					gchar* _tmp18_;
					const gchar* _tmp19_;
					_tmp10_ = handle;
					_tmp11_ = g_dir_read_name (_tmp10_);
					_tmp12_ = g_strdup (_tmp11_);
					_g_free0 (name);
					name = _tmp12_;
					_tmp13_ = name;
					if (!(_tmp13_ != NULL)) {
						break;
					}
					_tmp14_ = names;
					_tmp15_ = name;
					if (gee_collection_contains ((GeeCollection*) _tmp14_, _tmp15_)) {
						continue;
					}
					_tmp16_ = dir;
					_tmp17_ = name;
					_tmp18_ = g_build_filename (_tmp16_, _tmp17_, "metadata.json", NULL);
					metadata_filename = _tmp18_;
					_tmp19_ = metadata_filename;
					if (g_file_test (_tmp19_, G_FILE_TEST_EXISTS)) {
						{
							KkcRuleMetadata* metadata = NULL;
							const gchar* _tmp20_;
							const gchar* _tmp21_;
							KkcRuleMetadata* _tmp22_;
							GeeSet* _tmp23_;
							const gchar* _tmp24_;
							KkcRuleMetadata* _tmp25_;
							const gchar* _tmp26_;
							KkcRuleMetadata* _tmp27_;
							KkcRuleMetadata* _tmp28_;
							_tmp20_ = name;
							_tmp21_ = metadata_filename;
							_tmp22_ = kkc_rule_metadata_new (_tmp20_, _tmp21_, &_inner_error0_);
							metadata = _tmp22_;
							if (G_UNLIKELY (_inner_error0_ != NULL)) {
								goto __catch1_g_error;
							}
							_tmp23_ = names;
							_tmp24_ = name;
							gee_collection_add ((GeeCollection*) _tmp23_, _tmp24_);
							_tmp25_ = metadata;
							_tmp26_ = name;
							kkc_metadata_file_set_name ((KkcMetadataFile*) _tmp25_, _tmp26_);
							_tmp27_ = metadata;
							_tmp28_ = _g_object_ref0 (_tmp27_);
							_vala_array_add5 (&rules, &rules_length1, &_rules_size_, _tmp28_);
							_g_object_unref0 (metadata);
						}
						goto __finally1;
						__catch1_g_error:
						{
							GError* e = NULL;
							const gchar* _tmp29_;
							GError* _tmp30_;
							const gchar* _tmp31_;
							e = _inner_error0_;
							_inner_error0_ = NULL;
							_tmp29_ = metadata_filename;
							_tmp30_ = e;
							_tmp31_ = _tmp30_->message;
							g_warning ("rule.vala:333: can't load metadata %s: %s", _tmp29_, _tmp31_);
							_g_error_free0 (e);
						}
						__finally1:
						if (G_UNLIKELY (_inner_error0_ != NULL)) {
							_g_free0 (metadata_filename);
							_g_free0 (name);
							_g_dir_close0 (handle);
							_g_free0 (dir);
							dirs = (_vala_array_free (dirs, dirs_length1, (GDestroyNotify) g_free), NULL);
							rules = (_vala_array_free (rules, rules_length1, (GDestroyNotify) g_object_unref), NULL);
							_g_object_unref0 (names);
							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;
						}
					}
					_g_free0 (metadata_filename);
				}
				_g_free0 (name);
				_g_dir_close0 (handle);
				_g_free0 (dir);
			}
		}
	}
	_tmp32_ = rules;
	_tmp32__length1 = rules_length1;
	if (result_length1) {
		*result_length1 = _tmp32__length1;
	}
	result = _tmp32_;
	dirs = (_vala_array_free (dirs, dirs_length1, (GDestroyNotify) g_free), NULL);
	_g_object_unref0 (names);
	return result;
}

KkcRuleMetadata*
kkc_rule_get_metadata (KkcRule* self)
{
	KkcRuleMetadata* result;
	KkcRuleMetadata* _tmp0_;
	g_return_val_if_fail (self != NULL, NULL);
	_tmp0_ = self->priv->_metadata;
	result = _tmp0_;
	return result;
}

void
kkc_rule_set_metadata (KkcRule* self,
                       KkcRuleMetadata* value)
{
	KkcRuleMetadata* old_value;
	g_return_if_fail (self != NULL);
	old_value = kkc_rule_get_metadata (self);
	if (old_value != value) {
		KkcRuleMetadata* _tmp0_;
		_tmp0_ = _g_object_ref0 (value);
		_g_object_unref0 (self->priv->_metadata);
		self->priv->_metadata = _tmp0_;
		g_object_notify_by_pspec ((GObject *) self, kkc_rule_properties[KKC_RULE_METADATA_PROPERTY]);
	}
}

KkcKeyEventFilter*
kkc_rule_get_filter (KkcRule* self)
{
	KkcKeyEventFilter* result;
	KkcKeyEventFilter* _tmp0_;
	g_return_val_if_fail (self != NULL, NULL);
	_tmp0_ = self->priv->_filter;
	result = _tmp0_;
	return result;
}

void
kkc_rule_set_filter (KkcRule* self,
                     KkcKeyEventFilter* value)
{
	KkcKeyEventFilter* old_value;
	g_return_if_fail (self != NULL);
	old_value = kkc_rule_get_filter (self);
	if (old_value != value) {
		KkcKeyEventFilter* _tmp0_;
		_tmp0_ = _g_object_ref0 (value);
		_g_object_unref0 (self->priv->_filter);
		self->priv->_filter = _tmp0_;
		g_object_notify_by_pspec ((GObject *) self, kkc_rule_properties[KKC_RULE_FILTER_PROPERTY]);
	}
}

static void
kkc_rule_class_init (KkcRuleClass * klass,
                     gpointer klass_data)
{
	kkc_rule_parent_class = g_type_class_peek_parent (klass);
	g_type_class_adjust_private_offset (klass, &KkcRule_private_offset);
	G_OBJECT_CLASS (klass)->get_property = _vala_kkc_rule_get_property;
	G_OBJECT_CLASS (klass)->set_property = _vala_kkc_rule_set_property;
	G_OBJECT_CLASS (klass)->finalize = kkc_rule_finalize;
	/**
	         * Metadata associated with the rule.
	         */
	g_object_class_install_property (G_OBJECT_CLASS (klass), KKC_RULE_METADATA_PROPERTY, kkc_rule_properties[KKC_RULE_METADATA_PROPERTY] = g_param_spec_object ("metadata", "metadata", "metadata", KKC_TYPE_RULE_METADATA, G_PARAM_STATIC_STRINGS | G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT));
	g_object_class_install_property (G_OBJECT_CLASS (klass), KKC_RULE_FILTER_PROPERTY, kkc_rule_properties[KKC_RULE_FILTER_PROPERTY] = g_param_spec_object ("filter", "filter", "filter", KKC_TYPE_KEY_EVENT_FILTER, G_PARAM_STATIC_STRINGS | G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT));
}

static void
kkc_rule_g_initable_interface_init (GInitableIface * iface,
                                    gpointer iface_data)
{
	kkc_rule_g_initable_parent_iface = g_type_interface_peek_parent (iface);
	iface->init = (gboolean (*) (GInitable*, GCancellable*, GError**)) kkc_rule_real_init;
}

static void
kkc_rule_instance_init (KkcRule * self,
                        gpointer klass)
{
	self->priv = kkc_rule_get_instance_private (self);
}

static void
kkc_rule_finalize (GObject * obj)
{
	KkcRule * self;
	KkcKeyEventFilter* _tmp0_;
	self = G_TYPE_CHECK_INSTANCE_CAST (obj, KKC_TYPE_RULE, KkcRule);
	_tmp0_ = self->priv->_filter;
	if (_tmp0_ != NULL) {
		KkcKeyEventFilter* _tmp1_;
		_tmp1_ = self->priv->_filter;
		kkc_key_event_filter_reset (_tmp1_);
		kkc_rule_set_filter (self, NULL);
	}
	_g_object_unref0 (self->priv->_metadata);
	_g_object_unref0 (self->priv->_filter);
	self->priv->keymaps = (_vala_array_free (self->priv->keymaps, self->priv->keymaps_length1, (GDestroyNotify) g_object_unref), NULL);
	_g_object_unref0 (self->rom_kana);
	G_OBJECT_CLASS (kkc_rule_parent_class)->finalize (obj);
}

/**
     * Object representing a typing rule.
     */
static GType
kkc_rule_get_type_once (void)
{
	static const GTypeInfo g_define_type_info = { sizeof (KkcRuleClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) kkc_rule_class_init, (GClassFinalizeFunc) NULL, NULL, sizeof (KkcRule), 0, (GInstanceInitFunc) kkc_rule_instance_init, NULL };
	static const GInterfaceInfo g_initable_info = { (GInterfaceInitFunc) kkc_rule_g_initable_interface_init, (GInterfaceFinalizeFunc) NULL, NULL};
	GType kkc_rule_type_id;
	kkc_rule_type_id = g_type_register_static (G_TYPE_OBJECT, "KkcRule", &g_define_type_info, 0);
	g_type_add_interface_static (kkc_rule_type_id, g_initable_get_type (), &g_initable_info);
	KkcRule_private_offset = g_type_add_instance_private (kkc_rule_type_id, sizeof (KkcRulePrivate));
	return kkc_rule_type_id;
}

GType
kkc_rule_get_type (void)
{
	static volatile gsize kkc_rule_type_id__once = 0;
	if (g_once_init_enter (&kkc_rule_type_id__once)) {
		GType kkc_rule_type_id;
		kkc_rule_type_id = kkc_rule_get_type_once ();
		g_once_init_leave (&kkc_rule_type_id__once, kkc_rule_type_id);
	}
	return kkc_rule_type_id__once;
}

static void
_vala_kkc_rule_get_property (GObject * object,
                             guint property_id,
                             GValue * value,
                             GParamSpec * pspec)
{
	KkcRule * self;
	self = G_TYPE_CHECK_INSTANCE_CAST (object, KKC_TYPE_RULE, KkcRule);
	switch (property_id) {
		case KKC_RULE_METADATA_PROPERTY:
		g_value_set_object (value, kkc_rule_get_metadata (self));
		break;
		case KKC_RULE_FILTER_PROPERTY:
		g_value_set_object (value, kkc_rule_get_filter (self));
		break;
		default:
		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
		break;
	}
}

static void
_vala_kkc_rule_set_property (GObject * object,
                             guint property_id,
                             const GValue * value,
                             GParamSpec * pspec)
{
	KkcRule * self;
	self = G_TYPE_CHECK_INSTANCE_CAST (object, KKC_TYPE_RULE, KkcRule);
	switch (property_id) {
		case KKC_RULE_METADATA_PROPERTY:
		kkc_rule_set_metadata (self, g_value_get_object (value));
		break;
		case KKC_RULE_FILTER_PROPERTY:
		kkc_rule_set_filter (self, g_value_get_object (value));
		break;
		default:
		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
		break;
	}
}

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);
}

