/* kana-kan.c generated by valac 0.20.0.2-fd7ed, the Vala compiler
 * generated from kana-kan.vala, do not modify */

/* A naive kana-kanji converter based on:*/
/* http://gihyo.jp/magazine/wdpress/archive/2011/vol64 (Japanese)*/
/* dictionary and score map generation scripts can be found at:*/
/* http://gihyo.jp/assets/files/magazine/wdpress/2011/64/WDB64-toku3-kanakan.zip*/
/* See tests/kana-kan.c for example.*/

#include <glib.h>
#include <glib-object.h>
#include <stdlib.h>
#include <string.h>
#include <gee.h>
#include <float.h>
#include <math.h>
#include <gio/gio.h>


#define SKK_TYPE_KANA_KAN_CONVERTER (skk_kana_kan_converter_get_type ())
#define SKK_KANA_KAN_CONVERTER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SKK_TYPE_KANA_KAN_CONVERTER, SkkKanaKanConverter))
#define SKK_KANA_KAN_CONVERTER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), SKK_TYPE_KANA_KAN_CONVERTER, SkkKanaKanConverterClass))
#define SKK_IS_KANA_KAN_CONVERTER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SKK_TYPE_KANA_KAN_CONVERTER))
#define SKK_IS_KANA_KAN_CONVERTER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SKK_TYPE_KANA_KAN_CONVERTER))
#define SKK_KANA_KAN_CONVERTER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), SKK_TYPE_KANA_KAN_CONVERTER, SkkKanaKanConverterClass))

typedef struct _SkkKanaKanConverter SkkKanaKanConverter;
typedef struct _SkkKanaKanConverterClass SkkKanaKanConverterClass;
typedef struct _SkkKanaKanConverterPrivate SkkKanaKanConverterPrivate;

#define SKK_TYPE_KANA_KAN_DICT (skk_kana_kan_dict_get_type ())
#define SKK_KANA_KAN_DICT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SKK_TYPE_KANA_KAN_DICT, SkkKanaKanDict))
#define SKK_KANA_KAN_DICT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), SKK_TYPE_KANA_KAN_DICT, SkkKanaKanDictClass))
#define SKK_IS_KANA_KAN_DICT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SKK_TYPE_KANA_KAN_DICT))
#define SKK_IS_KANA_KAN_DICT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SKK_TYPE_KANA_KAN_DICT))
#define SKK_KANA_KAN_DICT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), SKK_TYPE_KANA_KAN_DICT, SkkKanaKanDictClass))

typedef struct _SkkKanaKanDict SkkKanaKanDict;
typedef struct _SkkKanaKanDictClass SkkKanaKanDictClass;

#define SKK_TYPE_KANA_KAN_SCORE_MAP (skk_kana_kan_score_map_get_type ())
#define SKK_KANA_KAN_SCORE_MAP(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SKK_TYPE_KANA_KAN_SCORE_MAP, SkkKanaKanScoreMap))
#define SKK_KANA_KAN_SCORE_MAP_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), SKK_TYPE_KANA_KAN_SCORE_MAP, SkkKanaKanScoreMapClass))
#define SKK_IS_KANA_KAN_SCORE_MAP(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SKK_TYPE_KANA_KAN_SCORE_MAP))
#define SKK_IS_KANA_KAN_SCORE_MAP_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SKK_TYPE_KANA_KAN_SCORE_MAP))
#define SKK_KANA_KAN_SCORE_MAP_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), SKK_TYPE_KANA_KAN_SCORE_MAP, SkkKanaKanScoreMapClass))

typedef struct _SkkKanaKanScoreMap SkkKanaKanScoreMap;
typedef struct _SkkKanaKanScoreMapClass SkkKanaKanScoreMapClass;
#define _g_object_unref0(var) ((var == NULL) ? NULL : (var = (g_object_unref (var), NULL)))

#define SKK_TYPE_KANA_KAN_GRAPH (skk_kana_kan_graph_get_type ())
#define SKK_KANA_KAN_GRAPH(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SKK_TYPE_KANA_KAN_GRAPH, SkkKanaKanGraph))
#define SKK_KANA_KAN_GRAPH_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), SKK_TYPE_KANA_KAN_GRAPH, SkkKanaKanGraphClass))
#define SKK_IS_KANA_KAN_GRAPH(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SKK_TYPE_KANA_KAN_GRAPH))
#define SKK_IS_KANA_KAN_GRAPH_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SKK_TYPE_KANA_KAN_GRAPH))
#define SKK_KANA_KAN_GRAPH_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), SKK_TYPE_KANA_KAN_GRAPH, SkkKanaKanGraphClass))

typedef struct _SkkKanaKanGraph SkkKanaKanGraph;
typedef struct _SkkKanaKanGraphClass SkkKanaKanGraphClass;
#define _g_free0(var) (var = (g_free (var), NULL))
#define _g_string_free0(var) ((var == NULL) ? NULL : (var = (g_string_free (var, TRUE), NULL)))
typedef struct _SkkKanaKanGraphPrivate SkkKanaKanGraphPrivate;

#define SKK_TYPE_KANA_KAN_NODE (skk_kana_kan_node_get_type ())
#define SKK_KANA_KAN_NODE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SKK_TYPE_KANA_KAN_NODE, SkkKanaKanNode))
#define SKK_KANA_KAN_NODE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), SKK_TYPE_KANA_KAN_NODE, SkkKanaKanNodeClass))
#define SKK_IS_KANA_KAN_NODE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SKK_TYPE_KANA_KAN_NODE))
#define SKK_IS_KANA_KAN_NODE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SKK_TYPE_KANA_KAN_NODE))
#define SKK_KANA_KAN_NODE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), SKK_TYPE_KANA_KAN_NODE, SkkKanaKanNodeClass))

typedef struct _SkkKanaKanNode SkkKanaKanNode;
typedef struct _SkkKanaKanNodeClass SkkKanaKanNodeClass;
typedef struct _SkkKanaKanNodePrivate SkkKanaKanNodePrivate;
typedef struct _SkkKanaKanDictPrivate SkkKanaKanDictPrivate;
typedef struct _SkkKanaKanScoreMapPrivate SkkKanaKanScoreMapPrivate;

#define SKK_TYPE_UNICODE_STRING (skk_unicode_string_get_type ())
#define SKK_UNICODE_STRING(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SKK_TYPE_UNICODE_STRING, SkkUnicodeString))
#define SKK_UNICODE_STRING_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), SKK_TYPE_UNICODE_STRING, SkkUnicodeStringClass))
#define SKK_IS_UNICODE_STRING(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SKK_TYPE_UNICODE_STRING))
#define SKK_IS_UNICODE_STRING_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SKK_TYPE_UNICODE_STRING))
#define SKK_UNICODE_STRING_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), SKK_TYPE_UNICODE_STRING, SkkUnicodeStringClass))

typedef struct _SkkUnicodeString SkkUnicodeString;
typedef struct _SkkUnicodeStringClass SkkUnicodeStringClass;
typedef struct _SkkUnicodeStringPrivate SkkUnicodeStringPrivate;

struct _SkkKanaKanConverter {
	GObject parent_instance;
	SkkKanaKanConverterPrivate * priv;
};

struct _SkkKanaKanConverterClass {
	GObjectClass parent_class;
};

struct _SkkKanaKanConverterPrivate {
	SkkKanaKanDict* dict;
	SkkKanaKanScoreMap* map;
};

struct _SkkKanaKanGraph {
	GObject parent_instance;
	SkkKanaKanGraphPrivate * priv;
	GeeArrayList** nodes;
	gint nodes_length1;
	gint _nodes_size_;
	SkkKanaKanNode* bos;
	SkkKanaKanNode* eos;
};

struct _SkkKanaKanGraphClass {
	GObjectClass parent_class;
};

struct _SkkKanaKanNode {
	GObject parent_instance;
	SkkKanaKanNodePrivate * priv;
	gchar* word;
	gchar* pron;
	gint endpos;
	gdouble score;
	SkkKanaKanNode* prev;
};

struct _SkkKanaKanNodeClass {
	GObjectClass parent_class;
};

struct _SkkKanaKanDict {
	GObject parent_instance;
	SkkKanaKanDictPrivate * priv;
};

struct _SkkKanaKanDictClass {
	GObjectClass parent_class;
};

struct _SkkKanaKanDictPrivate {
	GeeHashMap* dict;
};

struct _SkkKanaKanScoreMap {
	GObject parent_instance;
	SkkKanaKanScoreMapPrivate * priv;
};

struct _SkkKanaKanScoreMapClass {
	GObjectClass parent_class;
};

struct _SkkKanaKanScoreMapPrivate {
	GeeMap* map;
};

struct _SkkKanaKanGraphPrivate {
	SkkKanaKanDict* dict;
};

struct _SkkUnicodeString {
	GObject parent_instance;
	SkkUnicodeStringPrivate * priv;
	gint length;
};

struct _SkkUnicodeStringClass {
	GObjectClass parent_class;
};


static gpointer skk_kana_kan_converter_parent_class = NULL;
static gpointer skk_kana_kan_dict_parent_class = NULL;
static gpointer skk_kana_kan_score_map_parent_class = NULL;
static gpointer skk_kana_kan_node_parent_class = NULL;
static gpointer skk_kana_kan_graph_parent_class = NULL;

GType skk_kana_kan_converter_get_type (void) G_GNUC_CONST;
GType skk_kana_kan_dict_get_type (void) G_GNUC_CONST;
GType skk_kana_kan_score_map_get_type (void) G_GNUC_CONST;
#define SKK_KANA_KAN_CONVERTER_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), SKK_TYPE_KANA_KAN_CONVERTER, SkkKanaKanConverterPrivate))
enum  {
	SKK_KANA_KAN_CONVERTER_DUMMY_PROPERTY
};
SkkKanaKanConverter* skk_kana_kan_converter_new (SkkKanaKanDict* dict, SkkKanaKanScoreMap* map);
SkkKanaKanConverter* skk_kana_kan_converter_construct (GType object_type, SkkKanaKanDict* dict, SkkKanaKanScoreMap* map);
gchar* skk_kana_kan_converter_convert (SkkKanaKanConverter* self, const gchar* kana);
SkkKanaKanGraph* skk_kana_kan_graph_new (SkkKanaKanDict* dict, const gchar* str);
SkkKanaKanGraph* skk_kana_kan_graph_construct (GType object_type, SkkKanaKanDict* dict, const gchar* str);
GType skk_kana_kan_graph_get_type (void) G_GNUC_CONST;
static gchar** skk_kana_kan_converter_viterbi (SkkKanaKanGraph* graph, SkkKanaKanScoreMap* map, int* result_length1);
GType skk_kana_kan_node_get_type (void) G_GNUC_CONST;
gboolean skk_kana_kan_node_is_bos (SkkKanaKanNode* self);
gdouble skk_kana_kan_score_map_get_node_score (SkkKanaKanScoreMap* self, SkkKanaKanNode* node);
GeeArrayList* skk_kana_kan_graph_get_prev_nodes (SkkKanaKanGraph* self, SkkKanaKanNode* node);
gdouble skk_kana_kan_score_map_get_edge_score (SkkKanaKanScoreMap* self, SkkKanaKanNode* prev_node, SkkKanaKanNode* node);
static void skk_kana_kan_converter_finalize (GObject* obj);
#define SKK_KANA_KAN_DICT_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), SKK_TYPE_KANA_KAN_DICT, SkkKanaKanDictPrivate))
enum  {
	SKK_KANA_KAN_DICT_DUMMY_PROPERTY
};
SkkKanaKanDict* skk_kana_kan_dict_new (const gchar* path, GError** error);
SkkKanaKanDict* skk_kana_kan_dict_construct (GType object_type, const gchar* path, GError** error);
void skk_kana_kan_dict_add (SkkKanaKanDict* self, const gchar* pron, const gchar* word);
GeeSet* skk_kana_kan_dict_lookup (SkkKanaKanDict* self, const gchar* pron);
static void skk_kana_kan_dict_finalize (GObject* obj);
#define SKK_KANA_KAN_SCORE_MAP_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), SKK_TYPE_KANA_KAN_SCORE_MAP, SkkKanaKanScoreMapPrivate))
enum  {
	SKK_KANA_KAN_SCORE_MAP_DUMMY_PROPERTY
};
static gdouble* _double_dup (gdouble* self);
SkkKanaKanScoreMap* skk_kana_kan_score_map_new (const gchar* path, SkkKanaKanDict* dict, GError** error);
SkkKanaKanScoreMap* skk_kana_kan_score_map_construct (GType object_type, const gchar* path, SkkKanaKanDict* dict, GError** error);
static gdouble skk_kana_kan_score_map_get_score (SkkKanaKanScoreMap* self, const gchar* feature);
static void skk_kana_kan_score_map_finalize (GObject* obj);
enum  {
	SKK_KANA_KAN_NODE_DUMMY_PROPERTY,
	SKK_KANA_KAN_NODE_LENGTH
};
SkkKanaKanNode* skk_kana_kan_node_new (const gchar* word, const gchar* pron, gint endpos);
SkkKanaKanNode* skk_kana_kan_node_construct (GType object_type, const gchar* word, const gchar* pron, gint endpos);
gboolean skk_kana_kan_node_is_eos (SkkKanaKanNode* self);
gint skk_kana_kan_node_get_length (SkkKanaKanNode* self);
static void skk_kana_kan_node_finalize (GObject* obj);
static void _vala_skk_kana_kan_node_get_property (GObject * object, guint property_id, GValue * value, GParamSpec * pspec);
#define SKK_KANA_KAN_GRAPH_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), SKK_TYPE_KANA_KAN_GRAPH, SkkKanaKanGraphPrivate))
enum  {
	SKK_KANA_KAN_GRAPH_DUMMY_PROPERTY
};
SkkUnicodeString* skk_unicode_string_new (const gchar* str);
SkkUnicodeString* skk_unicode_string_construct (GType object_type, const gchar* str);
GType skk_unicode_string_get_type (void) G_GNUC_CONST;
gchar* skk_unicode_string_substring (SkkUnicodeString* self, glong offset, glong len);
static void skk_kana_kan_graph_finalize (GObject* obj);
static void _vala_array_destroy (gpointer array, gint array_length, GDestroyNotify destroy_func);
static void _vala_array_free (gpointer array, gint array_length, GDestroyNotify destroy_func);
static gint _vala_array_length (gpointer array);


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


SkkKanaKanConverter* skk_kana_kan_converter_construct (GType object_type, SkkKanaKanDict* dict, SkkKanaKanScoreMap* map) {
	SkkKanaKanConverter * self = NULL;
	SkkKanaKanDict* _tmp0_;
	SkkKanaKanDict* _tmp1_;
	SkkKanaKanScoreMap* _tmp2_;
	SkkKanaKanScoreMap* _tmp3_;
	g_return_val_if_fail (dict != NULL, NULL);
	g_return_val_if_fail (map != NULL, NULL);
	self = (SkkKanaKanConverter*) g_object_new (object_type, NULL);
	_tmp0_ = dict;
	_tmp1_ = _g_object_ref0 (_tmp0_);
	_g_object_unref0 (self->priv->dict);
	self->priv->dict = _tmp1_;
	_tmp2_ = map;
	_tmp3_ = _g_object_ref0 (_tmp2_);
	_g_object_unref0 (self->priv->map);
	self->priv->map = _tmp3_;
	return self;
}


SkkKanaKanConverter* skk_kana_kan_converter_new (SkkKanaKanDict* dict, SkkKanaKanScoreMap* map) {
	return skk_kana_kan_converter_construct (SKK_TYPE_KANA_KAN_CONVERTER, dict, map);
}


gchar* skk_kana_kan_converter_convert (SkkKanaKanConverter* self, const gchar* kana) {
	gchar* result = NULL;
	SkkKanaKanDict* _tmp0_;
	const gchar* _tmp1_;
	SkkKanaKanGraph* _tmp2_;
	SkkKanaKanGraph* graph;
	GString* _tmp3_;
	GString* builder;
	SkkKanaKanGraph* _tmp4_;
	SkkKanaKanScoreMap* _tmp5_;
	gint _tmp6_ = 0;
	gchar** _tmp7_ = NULL;
	gchar** words;
	gint words_length1;
	gint _words_size_;
	gchar** _tmp8_;
	gint _tmp8__length1;
	GString* _tmp12_;
	const gchar* _tmp13_;
	gchar* _tmp14_;
	g_return_val_if_fail (self != NULL, NULL);
	g_return_val_if_fail (kana != NULL, NULL);
	_tmp0_ = self->priv->dict;
	_tmp1_ = kana;
	_tmp2_ = skk_kana_kan_graph_new (_tmp0_, _tmp1_);
	graph = _tmp2_;
	_tmp3_ = g_string_new ("");
	builder = _tmp3_;
	_tmp4_ = graph;
	_tmp5_ = self->priv->map;
	_tmp7_ = skk_kana_kan_converter_viterbi (_tmp4_, _tmp5_, &_tmp6_);
	words = _tmp7_;
	words_length1 = _tmp6_;
	_words_size_ = words_length1;
	_tmp8_ = words;
	_tmp8__length1 = words_length1;
	{
		gchar** word_collection = NULL;
		gint word_collection_length1 = 0;
		gint _word_collection_size_ = 0;
		gint word_it = 0;
		word_collection = _tmp8_;
		word_collection_length1 = _tmp8__length1;
		for (word_it = 0; word_it < _tmp8__length1; word_it = word_it + 1) {
			gchar* _tmp9_;
			gchar* word = NULL;
			_tmp9_ = g_strdup (word_collection[word_it]);
			word = _tmp9_;
			{
				GString* _tmp10_;
				const gchar* _tmp11_;
				_tmp10_ = builder;
				_tmp11_ = word;
				g_string_append (_tmp10_, _tmp11_);
				_g_free0 (word);
			}
		}
	}
	_tmp12_ = builder;
	_tmp13_ = _tmp12_->str;
	_tmp14_ = g_strdup (_tmp13_);
	result = _tmp14_;
	words = (_vala_array_free (words, words_length1, (GDestroyNotify) g_free), NULL);
	_g_string_free0 (builder);
	_g_object_unref0 (graph);
	return result;
}


static gchar** skk_kana_kan_converter_viterbi (SkkKanaKanGraph* graph, SkkKanaKanScoreMap* map, int* result_length1) {
	gchar** result = NULL;
	SkkKanaKanGraph* _tmp0_;
	GeeArrayList** _tmp1_;
	gint _tmp1__length1;
	GeeArrayList* _tmp49_;
	GeeArrayList* _result_;
	SkkKanaKanGraph* _tmp50_;
	SkkKanaKanNode* _tmp51_;
	SkkKanaKanNode* _tmp52_;
	SkkKanaKanNode* _tmp53_;
	SkkKanaKanNode* node;
	GeeArrayList* _tmp62_;
	gint _tmp63_ = 0;
	gpointer* _tmp64_ = NULL;
	gchar** _tmp65_;
	gint _tmp65__length1;
	g_return_val_if_fail (graph != NULL, NULL);
	g_return_val_if_fail (map != NULL, NULL);
	_tmp0_ = graph;
	_tmp1_ = _tmp0_->nodes;
	_tmp1__length1 = _tmp0_->nodes_length1;
	{
		GeeArrayList** nodes_collection = NULL;
		gint nodes_collection_length1 = 0;
		gint _nodes_collection_size_ = 0;
		gint nodes_it = 0;
		nodes_collection = _tmp1_;
		nodes_collection_length1 = _tmp1__length1;
		for (nodes_it = 0; nodes_it < _tmp1__length1; nodes_it = nodes_it + 1) {
			GeeArrayList* _tmp2_;
			GeeArrayList* nodes = NULL;
			_tmp2_ = _g_object_ref0 (nodes_collection[nodes_it]);
			nodes = _tmp2_;
			{
				{
					GeeArrayList* _tmp3_;
					GeeArrayList* _tmp4_;
					GeeArrayList* _node_list;
					GeeArrayList* _tmp5_;
					gint _tmp6_;
					gint _tmp7_;
					gint _node_size;
					gint _node_index;
					_tmp3_ = nodes;
					_tmp4_ = _g_object_ref0 (_tmp3_);
					_node_list = _tmp4_;
					_tmp5_ = _node_list;
					_tmp6_ = gee_abstract_collection_get_size ((GeeCollection*) _tmp5_);
					_tmp7_ = _tmp6_;
					_node_size = _tmp7_;
					_node_index = -1;
					while (TRUE) {
						gint _tmp8_;
						gint _tmp9_;
						gint _tmp10_;
						GeeArrayList* _tmp11_;
						gint _tmp12_;
						gpointer _tmp13_ = NULL;
						SkkKanaKanNode* node;
						SkkKanaKanNode* _tmp14_;
						gboolean _tmp15_ = FALSE;
						SkkKanaKanNode* _tmp16_;
						SkkKanaKanScoreMap* _tmp17_;
						SkkKanaKanNode* _tmp18_;
						gdouble _tmp19_ = 0.0;
						gdouble node_score;
						SkkKanaKanGraph* _tmp20_;
						SkkKanaKanNode* _tmp21_;
						GeeArrayList* _tmp22_ = NULL;
						GeeArrayList* prev_nodes;
						_tmp8_ = _node_index;
						_node_index = _tmp8_ + 1;
						_tmp9_ = _node_index;
						_tmp10_ = _node_size;
						if (!(_tmp9_ < _tmp10_)) {
							break;
						}
						_tmp11_ = _node_list;
						_tmp12_ = _node_index;
						_tmp13_ = gee_abstract_list_get ((GeeAbstractList*) _tmp11_, _tmp12_);
						node = (SkkKanaKanNode*) _tmp13_;
						_tmp14_ = node;
						_tmp15_ = skk_kana_kan_node_is_bos (_tmp14_);
						if (_tmp15_) {
							_g_object_unref0 (node);
							continue;
						}
						_tmp16_ = node;
						_tmp16_->score = -1000000.0;
						_tmp17_ = map;
						_tmp18_ = node;
						_tmp19_ = skk_kana_kan_score_map_get_node_score (_tmp17_, _tmp18_);
						node_score = _tmp19_;
						_tmp20_ = graph;
						_tmp21_ = node;
						_tmp22_ = skk_kana_kan_graph_get_prev_nodes (_tmp20_, _tmp21_);
						prev_nodes = _tmp22_;
						{
							GeeArrayList* _tmp23_;
							GeeArrayList* _tmp24_;
							GeeArrayList* _prev_node_list;
							GeeArrayList* _tmp25_;
							gint _tmp26_;
							gint _tmp27_;
							gint _prev_node_size;
							gint _prev_node_index;
							_tmp23_ = prev_nodes;
							_tmp24_ = _g_object_ref0 (_tmp23_);
							_prev_node_list = _tmp24_;
							_tmp25_ = _prev_node_list;
							_tmp26_ = gee_abstract_collection_get_size ((GeeCollection*) _tmp25_);
							_tmp27_ = _tmp26_;
							_prev_node_size = _tmp27_;
							_prev_node_index = -1;
							while (TRUE) {
								gint _tmp28_;
								gint _tmp29_;
								gint _tmp30_;
								GeeArrayList* _tmp31_;
								gint _tmp32_;
								gpointer _tmp33_ = NULL;
								SkkKanaKanNode* prev_node;
								SkkKanaKanNode* _tmp34_;
								gdouble _tmp35_;
								SkkKanaKanScoreMap* _tmp36_;
								SkkKanaKanNode* _tmp37_;
								SkkKanaKanNode* _tmp38_;
								gdouble _tmp39_ = 0.0;
								gdouble _tmp40_;
								gdouble score;
								gdouble _tmp41_;
								SkkKanaKanNode* _tmp42_;
								gdouble _tmp43_;
								_tmp28_ = _prev_node_index;
								_prev_node_index = _tmp28_ + 1;
								_tmp29_ = _prev_node_index;
								_tmp30_ = _prev_node_size;
								if (!(_tmp29_ < _tmp30_)) {
									break;
								}
								_tmp31_ = _prev_node_list;
								_tmp32_ = _prev_node_index;
								_tmp33_ = gee_abstract_list_get ((GeeAbstractList*) _tmp31_, _tmp32_);
								prev_node = (SkkKanaKanNode*) _tmp33_;
								_tmp34_ = prev_node;
								_tmp35_ = _tmp34_->score;
								_tmp36_ = map;
								_tmp37_ = prev_node;
								_tmp38_ = node;
								_tmp39_ = skk_kana_kan_score_map_get_edge_score (_tmp36_, _tmp37_, _tmp38_);
								_tmp40_ = node_score;
								score = (_tmp35_ + _tmp39_) + _tmp40_;
								_tmp41_ = score;
								_tmp42_ = node;
								_tmp43_ = _tmp42_->score;
								if (_tmp41_ >= _tmp43_) {
									SkkKanaKanNode* _tmp44_;
									gdouble _tmp45_;
									SkkKanaKanNode* _tmp46_;
									SkkKanaKanNode* _tmp47_;
									SkkKanaKanNode* _tmp48_;
									_tmp44_ = node;
									_tmp45_ = score;
									_tmp44_->score = _tmp45_;
									_tmp46_ = node;
									_tmp47_ = prev_node;
									_tmp48_ = _g_object_ref0 (_tmp47_);
									_g_object_unref0 (_tmp46_->prev);
									_tmp46_->prev = _tmp48_;
								}
								_g_object_unref0 (prev_node);
							}
							_g_object_unref0 (_prev_node_list);
						}
						_g_object_unref0 (prev_nodes);
						_g_object_unref0 (node);
					}
					_g_object_unref0 (_node_list);
				}
				_g_object_unref0 (nodes);
			}
		}
	}
	_tmp49_ = gee_array_list_new (G_TYPE_STRING, (GBoxedCopyFunc) g_strdup, g_free, NULL);
	_result_ = _tmp49_;
	_tmp50_ = graph;
	_tmp51_ = _tmp50_->eos;
	_tmp52_ = _tmp51_->prev;
	_tmp53_ = _g_object_ref0 (_tmp52_);
	node = _tmp53_;
	while (TRUE) {
		SkkKanaKanNode* _tmp54_;
		gboolean _tmp55_ = FALSE;
		GeeArrayList* _tmp56_;
		SkkKanaKanNode* _tmp57_;
		const gchar* _tmp58_;
		SkkKanaKanNode* _tmp59_;
		SkkKanaKanNode* _tmp60_;
		SkkKanaKanNode* _tmp61_;
		_tmp54_ = node;
		_tmp55_ = skk_kana_kan_node_is_bos (_tmp54_);
		if (!(!_tmp55_)) {
			break;
		}
		_tmp56_ = _result_;
		_tmp57_ = node;
		_tmp58_ = _tmp57_->word;
		gee_abstract_list_insert ((GeeAbstractList*) _tmp56_, 0, _tmp58_);
		_tmp59_ = node;
		_tmp60_ = _tmp59_->prev;
		_tmp61_ = _g_object_ref0 (_tmp60_);
		_g_object_unref0 (node);
		node = _tmp61_;
	}
	_tmp62_ = _result_;
	_tmp64_ = gee_abstract_collection_to_array ((GeeAbstractCollection*) _tmp62_, &_tmp63_);
	_tmp65_ = _tmp64_;
	_tmp65__length1 = _tmp63_;
	if (result_length1) {
		*result_length1 = _tmp65__length1;
	}
	result = _tmp65_;
	_g_object_unref0 (node);
	_g_object_unref0 (_result_);
	return result;
}


static void skk_kana_kan_converter_class_init (SkkKanaKanConverterClass * klass) {
	skk_kana_kan_converter_parent_class = g_type_class_peek_parent (klass);
	g_type_class_add_private (klass, sizeof (SkkKanaKanConverterPrivate));
	G_OBJECT_CLASS (klass)->finalize = skk_kana_kan_converter_finalize;
}


static void skk_kana_kan_converter_instance_init (SkkKanaKanConverter * self) {
	self->priv = SKK_KANA_KAN_CONVERTER_GET_PRIVATE (self);
}


static void skk_kana_kan_converter_finalize (GObject* obj) {
	SkkKanaKanConverter * self;
	self = G_TYPE_CHECK_INSTANCE_CAST (obj, SKK_TYPE_KANA_KAN_CONVERTER, SkkKanaKanConverter);
	_g_object_unref0 (self->priv->dict);
	_g_object_unref0 (self->priv->map);
	G_OBJECT_CLASS (skk_kana_kan_converter_parent_class)->finalize (obj);
}


/**
     * Experimental kana-to-kanji converter using Viterbi algorithm.
     */
GType skk_kana_kan_converter_get_type (void) {
	static volatile gsize skk_kana_kan_converter_type_id__volatile = 0;
	if (g_once_init_enter (&skk_kana_kan_converter_type_id__volatile)) {
		static const GTypeInfo g_define_type_info = { sizeof (SkkKanaKanConverterClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) skk_kana_kan_converter_class_init, (GClassFinalizeFunc) NULL, NULL, sizeof (SkkKanaKanConverter), 0, (GInstanceInitFunc) skk_kana_kan_converter_instance_init, NULL };
		GType skk_kana_kan_converter_type_id;
		skk_kana_kan_converter_type_id = g_type_register_static (G_TYPE_OBJECT, "SkkKanaKanConverter", &g_define_type_info, 0);
		g_once_init_leave (&skk_kana_kan_converter_type_id__volatile, skk_kana_kan_converter_type_id);
	}
	return skk_kana_kan_converter_type_id__volatile;
}


static gchar* string_chomp (const gchar* self) {
	gchar* result = NULL;
	gchar* _tmp0_ = NULL;
	gchar* _result_;
	const gchar* _tmp1_;
	g_return_val_if_fail (self != NULL, NULL);
	_tmp0_ = g_strdup (self);
	_result_ = _tmp0_;
	_tmp1_ = _result_;
	g_strchomp (_tmp1_);
	result = _result_;
	return result;
}


SkkKanaKanDict* skk_kana_kan_dict_construct (GType object_type, const gchar* path, GError** error) {
	SkkKanaKanDict * self = NULL;
	const gchar* _tmp0_;
	GFile* _tmp1_ = NULL;
	GFile* file;
	GFile* _tmp2_;
	GFileInputStream* _tmp3_ = NULL;
	GFileInputStream* _tmp4_;
	GFileInputStream* _tmp5_;
	GDataInputStream* _tmp6_;
	GDataInputStream* _tmp7_;
	GDataInputStream* input;
	GError * _inner_error_ = NULL;
	g_return_val_if_fail (path != NULL, NULL);
	self = (SkkKanaKanDict*) g_object_new (object_type, NULL);
	_tmp0_ = path;
	_tmp1_ = g_file_new_for_path (_tmp0_);
	file = _tmp1_;
	_tmp2_ = file;
	_tmp3_ = g_file_read (_tmp2_, NULL, &_inner_error_);
	_tmp4_ = _tmp3_;
	if (_inner_error_ != NULL) {
		g_propagate_error (error, _inner_error_);
		_g_object_unref0 (file);
		_g_object_unref0 (self);
		return NULL;
	}
	_tmp5_ = _tmp4_;
	_tmp6_ = g_data_input_stream_new ((GInputStream*) _tmp5_);
	_tmp7_ = _tmp6_;
	_g_object_unref0 (_tmp5_);
	input = _tmp7_;
	while (TRUE) {
		gsize length = 0UL;
		GDataInputStream* _tmp8_;
		gsize _tmp9_ = 0UL;
		gchar* _tmp10_ = NULL;
		gchar* line;
		const gchar* _tmp11_;
		const gchar* _tmp12_;
		gchar* _tmp13_ = NULL;
		gchar* _tmp14_;
		gchar** _tmp15_;
		gchar** _tmp16_ = NULL;
		gchar** _tmp17_;
		gint _tmp17__length1;
		gchar** a;
		gint a_length1;
		gint _a_size_;
		gchar** _tmp18_;
		gint _tmp18__length1;
		const gchar* _tmp19_;
		gchar** _tmp20_;
		gint _tmp20__length1;
		const gchar* _tmp21_;
		_tmp8_ = input;
		_tmp10_ = g_data_input_stream_read_line (_tmp8_, &_tmp9_, NULL, &_inner_error_);
		length = _tmp9_;
		line = _tmp10_;
		if (_inner_error_ != NULL) {
			g_propagate_error (error, _inner_error_);
			_g_object_unref0 (input);
			_g_object_unref0 (file);
			_g_object_unref0 (self);
			return NULL;
		}
		_tmp11_ = line;
		if (_tmp11_ == NULL) {
			_g_free0 (line);
			break;
		}
		_tmp12_ = line;
		_tmp13_ = string_chomp (_tmp12_);
		_tmp14_ = _tmp13_;
		_tmp16_ = _tmp15_ = g_strsplit (_tmp14_, "\t", 0);
		_tmp17_ = _tmp16_;
		_tmp17__length1 = _vala_array_length (_tmp15_);
		_g_free0 (_tmp14_);
		a = _tmp17_;
		a_length1 = _tmp17__length1;
		_a_size_ = a_length1;
		_tmp18_ = a;
		_tmp18__length1 = a_length1;
		_tmp19_ = _tmp18_[0];
		_tmp20_ = a;
		_tmp20__length1 = a_length1;
		_tmp21_ = _tmp20_[1];
		skk_kana_kan_dict_add (self, _tmp19_, _tmp21_);
		a = (_vala_array_free (a, a_length1, (GDestroyNotify) g_free), NULL);
		_g_free0 (line);
	}
	_g_object_unref0 (input);
	_g_object_unref0 (file);
	return self;
}


SkkKanaKanDict* skk_kana_kan_dict_new (const gchar* path, GError** error) {
	return skk_kana_kan_dict_construct (SKK_TYPE_KANA_KAN_DICT, path, error);
}


void skk_kana_kan_dict_add (SkkKanaKanDict* self, const gchar* pron, const gchar* word) {
	GeeHashMap* _tmp0_;
	const gchar* _tmp1_;
	gboolean _tmp2_ = FALSE;
	GeeHashMap* _tmp7_;
	const gchar* _tmp8_;
	gpointer _tmp9_ = NULL;
	GeeSet* _tmp10_;
	const gchar* _tmp11_;
	g_return_if_fail (self != NULL);
	g_return_if_fail (pron != NULL);
	g_return_if_fail (word != NULL);
	_tmp0_ = self->priv->dict;
	_tmp1_ = pron;
	_tmp2_ = gee_abstract_map_has_key ((GeeAbstractMap*) _tmp0_, _tmp1_);
	if (!_tmp2_) {
		GeeHashMap* _tmp3_;
		const gchar* _tmp4_;
		GeeHashSet* _tmp5_;
		GeeHashSet* _tmp6_;
		_tmp3_ = self->priv->dict;
		_tmp4_ = pron;
		_tmp5_ = gee_hash_set_new (G_TYPE_STRING, (GBoxedCopyFunc) g_strdup, g_free, NULL, NULL);
		_tmp6_ = _tmp5_;
		gee_abstract_map_set ((GeeAbstractMap*) _tmp3_, _tmp4_, (GeeSet*) _tmp6_);
		_g_object_unref0 (_tmp6_);
	}
	_tmp7_ = self->priv->dict;
	_tmp8_ = pron;
	_tmp9_ = gee_abstract_map_get ((GeeAbstractMap*) _tmp7_, _tmp8_);
	_tmp10_ = (GeeSet*) _tmp9_;
	_tmp11_ = word;
	gee_collection_add ((GeeCollection*) _tmp10_, _tmp11_);
	_g_object_unref0 (_tmp10_);
}


GeeSet* skk_kana_kan_dict_lookup (SkkKanaKanDict* self, const gchar* pron) {
	GeeSet* result = NULL;
	GeeHashMap* _tmp0_;
	const gchar* _tmp1_;
	gboolean _tmp2_ = FALSE;
	GeeHashMap* _tmp4_;
	const gchar* _tmp5_;
	gpointer _tmp6_ = NULL;
	g_return_val_if_fail (self != NULL, NULL);
	g_return_val_if_fail (pron != NULL, NULL);
	_tmp0_ = self->priv->dict;
	_tmp1_ = pron;
	_tmp2_ = gee_abstract_map_has_key ((GeeAbstractMap*) _tmp0_, _tmp1_);
	if (!_tmp2_) {
		GeeHashSet* _tmp3_;
		_tmp3_ = gee_hash_set_new (G_TYPE_STRING, (GBoxedCopyFunc) g_strdup, g_free, NULL, NULL);
		result = (GeeSet*) _tmp3_;
		return result;
	}
	_tmp4_ = self->priv->dict;
	_tmp5_ = pron;
	_tmp6_ = gee_abstract_map_get ((GeeAbstractMap*) _tmp4_, _tmp5_);
	result = (GeeSet*) _tmp6_;
	return result;
}


static void skk_kana_kan_dict_class_init (SkkKanaKanDictClass * klass) {
	skk_kana_kan_dict_parent_class = g_type_class_peek_parent (klass);
	g_type_class_add_private (klass, sizeof (SkkKanaKanDictPrivate));
	G_OBJECT_CLASS (klass)->finalize = skk_kana_kan_dict_finalize;
}


static void skk_kana_kan_dict_instance_init (SkkKanaKanDict * self) {
	GeeHashMap* _tmp0_;
	self->priv = SKK_KANA_KAN_DICT_GET_PRIVATE (self);
	_tmp0_ = gee_hash_map_new (G_TYPE_STRING, (GBoxedCopyFunc) g_strdup, g_free, GEE_TYPE_SET, (GBoxedCopyFunc) g_object_ref, g_object_unref, NULL, NULL, NULL);
	self->priv->dict = _tmp0_;
}


static void skk_kana_kan_dict_finalize (GObject* obj) {
	SkkKanaKanDict * self;
	self = G_TYPE_CHECK_INSTANCE_CAST (obj, SKK_TYPE_KANA_KAN_DICT, SkkKanaKanDict);
	_g_object_unref0 (self->priv->dict);
	G_OBJECT_CLASS (skk_kana_kan_dict_parent_class)->finalize (obj);
}


GType skk_kana_kan_dict_get_type (void) {
	static volatile gsize skk_kana_kan_dict_type_id__volatile = 0;
	if (g_once_init_enter (&skk_kana_kan_dict_type_id__volatile)) {
		static const GTypeInfo g_define_type_info = { sizeof (SkkKanaKanDictClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) skk_kana_kan_dict_class_init, (GClassFinalizeFunc) NULL, NULL, sizeof (SkkKanaKanDict), 0, (GInstanceInitFunc) skk_kana_kan_dict_instance_init, NULL };
		GType skk_kana_kan_dict_type_id;
		skk_kana_kan_dict_type_id = g_type_register_static (G_TYPE_OBJECT, "SkkKanaKanDict", &g_define_type_info, 0);
		g_once_init_leave (&skk_kana_kan_dict_type_id__volatile, skk_kana_kan_dict_type_id);
	}
	return skk_kana_kan_dict_type_id__volatile;
}


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


static gdouble double_parse (const gchar* str) {
	gdouble result = 0.0;
	const gchar* _tmp0_;
	gdouble _tmp1_ = 0.0;
	g_return_val_if_fail (str != NULL, 0.0);
	_tmp0_ = str;
	_tmp1_ = g_ascii_strtod (_tmp0_, NULL);
	result = _tmp1_;
	return result;
}


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


static gchar* string_substring (const gchar* self, glong offset, glong len) {
	gchar* result = NULL;
	glong string_length = 0L;
	gboolean _tmp0_ = FALSE;
	glong _tmp1_;
	gboolean _tmp3_;
	glong _tmp9_;
	glong _tmp15_;
	glong _tmp18_;
	glong _tmp19_;
	glong _tmp20_;
	glong _tmp21_;
	glong _tmp22_;
	gchar* _tmp23_ = NULL;
	g_return_val_if_fail (self != NULL, NULL);
	_tmp1_ = offset;
	if (_tmp1_ >= ((glong) 0)) {
		glong _tmp2_;
		_tmp2_ = len;
		_tmp0_ = _tmp2_ >= ((glong) 0);
	} else {
		_tmp0_ = FALSE;
	}
	_tmp3_ = _tmp0_;
	if (_tmp3_) {
		glong _tmp4_;
		glong _tmp5_;
		glong _tmp6_ = 0L;
		_tmp4_ = offset;
		_tmp5_ = len;
		_tmp6_ = string_strnlen ((gchar*) self, _tmp4_ + _tmp5_);
		string_length = _tmp6_;
	} else {
		gint _tmp7_;
		gint _tmp8_;
		_tmp7_ = strlen (self);
		_tmp8_ = _tmp7_;
		string_length = (glong) _tmp8_;
	}
	_tmp9_ = offset;
	if (_tmp9_ < ((glong) 0)) {
		glong _tmp10_;
		glong _tmp11_;
		glong _tmp12_;
		_tmp10_ = string_length;
		_tmp11_ = offset;
		offset = _tmp10_ + _tmp11_;
		_tmp12_ = offset;
		g_return_val_if_fail (_tmp12_ >= ((glong) 0), NULL);
	} else {
		glong _tmp13_;
		glong _tmp14_;
		_tmp13_ = offset;
		_tmp14_ = string_length;
		g_return_val_if_fail (_tmp13_ <= _tmp14_, NULL);
	}
	_tmp15_ = len;
	if (_tmp15_ < ((glong) 0)) {
		glong _tmp16_;
		glong _tmp17_;
		_tmp16_ = string_length;
		_tmp17_ = offset;
		len = _tmp16_ - _tmp17_;
	}
	_tmp18_ = offset;
	_tmp19_ = len;
	_tmp20_ = string_length;
	g_return_val_if_fail ((_tmp18_ + _tmp19_) <= _tmp20_, NULL);
	_tmp21_ = offset;
	_tmp22_ = len;
	_tmp23_ = g_strndup (((gchar*) self) + _tmp21_, (gsize) _tmp22_);
	result = _tmp23_;
	return result;
}


SkkKanaKanScoreMap* skk_kana_kan_score_map_construct (GType object_type, const gchar* path, SkkKanaKanDict* dict, GError** error) {
	SkkKanaKanScoreMap * self = NULL;
	const gchar* _tmp0_;
	GFile* _tmp1_ = NULL;
	GFile* file;
	GFile* _tmp2_;
	GFileInputStream* _tmp3_ = NULL;
	GFileInputStream* _tmp4_;
	GFileInputStream* _tmp5_;
	GDataInputStream* _tmp6_;
	GDataInputStream* _tmp7_;
	GDataInputStream* input;
	GError * _inner_error_ = NULL;
	g_return_val_if_fail (path != NULL, NULL);
	g_return_val_if_fail (dict != NULL, NULL);
	self = (SkkKanaKanScoreMap*) g_object_new (object_type, NULL);
	_tmp0_ = path;
	_tmp1_ = g_file_new_for_path (_tmp0_);
	file = _tmp1_;
	_tmp2_ = file;
	_tmp3_ = g_file_read (_tmp2_, NULL, &_inner_error_);
	_tmp4_ = _tmp3_;
	if (_inner_error_ != NULL) {
		g_propagate_error (error, _inner_error_);
		_g_object_unref0 (file);
		_g_object_unref0 (self);
		return NULL;
	}
	_tmp5_ = _tmp4_;
	_tmp6_ = g_data_input_stream_new ((GInputStream*) _tmp5_);
	_tmp7_ = _tmp6_;
	_g_object_unref0 (_tmp5_);
	input = _tmp7_;
	while (TRUE) {
		gsize length = 0UL;
		GDataInputStream* _tmp8_;
		gsize _tmp9_ = 0UL;
		gchar* _tmp10_ = NULL;
		gchar* line;
		const gchar* _tmp11_;
		const gchar* _tmp12_;
		gchar* _tmp13_ = NULL;
		gchar* _tmp14_;
		gchar** _tmp15_;
		gchar** _tmp16_ = NULL;
		gchar** _tmp17_;
		gint _tmp17__length1;
		gchar** a;
		gint a_length1;
		gint _a_size_;
		GeeMap* _tmp18_;
		gchar** _tmp19_;
		gint _tmp19__length1;
		const gchar* _tmp20_;
		gchar** _tmp21_;
		gint _tmp21__length1;
		const gchar* _tmp22_;
		gdouble _tmp23_ = 0.0;
		gchar** _tmp24_;
		gint _tmp24__length1;
		const gchar* _tmp25_;
		gchar** _tmp26_;
		gchar** _tmp27_ = NULL;
		gchar** b;
		gint b_length1;
		gint _b_size_;
		gboolean _tmp28_ = FALSE;
		gboolean _tmp29_ = FALSE;
		gchar** _tmp30_;
		gint _tmp30__length1;
		gboolean _tmp34_;
		gboolean _tmp38_;
		_tmp8_ = input;
		_tmp10_ = g_data_input_stream_read_line (_tmp8_, &_tmp9_, NULL, &_inner_error_);
		length = _tmp9_;
		line = _tmp10_;
		if (_inner_error_ != NULL) {
			g_propagate_error (error, _inner_error_);
			_g_object_unref0 (input);
			_g_object_unref0 (file);
			_g_object_unref0 (self);
			return NULL;
		}
		_tmp11_ = line;
		if (_tmp11_ == NULL) {
			_g_free0 (line);
			break;
		}
		_tmp12_ = line;
		_tmp13_ = string_chomp (_tmp12_);
		_tmp14_ = _tmp13_;
		_tmp16_ = _tmp15_ = g_strsplit (_tmp14_, "\t\t", 0);
		_tmp17_ = _tmp16_;
		_tmp17__length1 = _vala_array_length (_tmp15_);
		_g_free0 (_tmp14_);
		a = _tmp17_;
		a_length1 = _tmp17__length1;
		_a_size_ = a_length1;
		_tmp18_ = self->priv->map;
		_tmp19_ = a;
		_tmp19__length1 = a_length1;
		_tmp20_ = _tmp19_[0];
		_tmp21_ = a;
		_tmp21__length1 = a_length1;
		_tmp22_ = _tmp21_[1];
		_tmp23_ = double_parse (_tmp22_);
		gee_map_set (_tmp18_, _tmp20_, &_tmp23_);
		_tmp24_ = a;
		_tmp24__length1 = a_length1;
		_tmp25_ = _tmp24_[0];
		_tmp27_ = _tmp26_ = g_strsplit (_tmp25_, "\t", 0);
		b = _tmp27_;
		b_length1 = _vala_array_length (_tmp26_);
		_b_size_ = b_length1;
		_tmp30_ = b;
		_tmp30__length1 = b_length1;
		if (_tmp30__length1 == 2) {
			gchar** _tmp31_;
			gint _tmp31__length1;
			const gchar* _tmp32_;
			gboolean _tmp33_ = FALSE;
			_tmp31_ = b;
			_tmp31__length1 = b_length1;
			_tmp32_ = _tmp31_[0];
			_tmp33_ = g_str_has_prefix (_tmp32_, "S");
			_tmp29_ = _tmp33_;
		} else {
			_tmp29_ = FALSE;
		}
		_tmp34_ = _tmp29_;
		if (_tmp34_) {
			gchar** _tmp35_;
			gint _tmp35__length1;
			const gchar* _tmp36_;
			gboolean _tmp37_ = FALSE;
			_tmp35_ = b;
			_tmp35__length1 = b_length1;
			_tmp36_ = _tmp35_[1];
			_tmp37_ = g_str_has_prefix (_tmp36_, "R");
			_tmp28_ = _tmp37_;
		} else {
			_tmp28_ = FALSE;
		}
		_tmp38_ = _tmp28_;
		if (_tmp38_) {
			gchar** _tmp39_;
			gint _tmp39__length1;
			const gchar* _tmp40_;
			gchar* _tmp41_ = NULL;
			gchar* word;
			gchar** _tmp42_;
			gint _tmp42__length1;
			const gchar* _tmp43_;
			gchar* _tmp44_ = NULL;
			gchar* pron;
			SkkKanaKanDict* _tmp45_;
			const gchar* _tmp46_;
			const gchar* _tmp47_;
			_tmp39_ = b;
			_tmp39__length1 = b_length1;
			_tmp40_ = _tmp39_[0];
			_tmp41_ = string_substring (_tmp40_, (glong) 1, (glong) (-1));
			word = _tmp41_;
			_tmp42_ = b;
			_tmp42__length1 = b_length1;
			_tmp43_ = _tmp42_[1];
			_tmp44_ = string_substring (_tmp43_, (glong) 1, (glong) (-1));
			pron = _tmp44_;
			_tmp45_ = dict;
			_tmp46_ = pron;
			_tmp47_ = word;
			skk_kana_kan_dict_add (_tmp45_, _tmp46_, _tmp47_);
			_g_free0 (pron);
			_g_free0 (word);
		}
		b = (_vala_array_free (b, b_length1, (GDestroyNotify) g_free), NULL);
		a = (_vala_array_free (a, a_length1, (GDestroyNotify) g_free), NULL);
		_g_free0 (line);
	}
	_g_object_unref0 (input);
	_g_object_unref0 (file);
	return self;
}


SkkKanaKanScoreMap* skk_kana_kan_score_map_new (const gchar* path, SkkKanaKanDict* dict, GError** error) {
	return skk_kana_kan_score_map_construct (SKK_TYPE_KANA_KAN_SCORE_MAP, path, dict, error);
}


static gdouble skk_kana_kan_score_map_get_score (SkkKanaKanScoreMap* self, const gchar* feature) {
	gdouble result = 0.0;
	GeeMap* _tmp0_;
	const gchar* _tmp1_;
	gboolean _tmp2_ = FALSE;
	g_return_val_if_fail (self != NULL, 0.0);
	g_return_val_if_fail (feature != NULL, 0.0);
	_tmp0_ = self->priv->map;
	_tmp1_ = feature;
	_tmp2_ = gee_map_has_key (_tmp0_, _tmp1_);
	if (_tmp2_) {
		GeeMap* _tmp3_;
		const gchar* _tmp4_;
		gpointer _tmp5_ = NULL;
		gdouble* _tmp6_;
		gdouble _tmp7_;
		_tmp3_ = self->priv->map;
		_tmp4_ = feature;
		_tmp5_ = gee_map_get (_tmp3_, _tmp4_);
		_tmp6_ = (gdouble*) _tmp5_;
		_tmp7_ = *_tmp6_;
		_g_free0 (_tmp6_);
		result = _tmp7_;
		return result;
	}
	result = 0.0;
	return result;
}


gdouble skk_kana_kan_score_map_get_node_score (SkkKanaKanScoreMap* self, SkkKanaKanNode* node) {
	gdouble result = 0.0;
	gdouble score;
	gchar* feature = NULL;
	SkkKanaKanNode* _tmp0_;
	const gchar* _tmp1_;
	SkkKanaKanNode* _tmp2_;
	const gchar* _tmp3_;
	gchar* _tmp4_ = NULL;
	gdouble _tmp5_;
	const gchar* _tmp6_;
	gdouble _tmp7_ = 0.0;
	SkkKanaKanNode* _tmp8_;
	const gchar* _tmp9_;
	gchar* _tmp10_ = NULL;
	gdouble _tmp11_;
	const gchar* _tmp12_;
	gdouble _tmp13_ = 0.0;
	g_return_val_if_fail (self != NULL, 0.0);
	g_return_val_if_fail (node != NULL, 0.0);
	score = 0.0;
	_tmp0_ = node;
	_tmp1_ = _tmp0_->word;
	_tmp2_ = node;
	_tmp3_ = _tmp2_->pron;
	_tmp4_ = g_strdup_printf ("S%s\tR%s", _tmp1_, _tmp3_);
	_g_free0 (feature);
	feature = _tmp4_;
	_tmp5_ = score;
	_tmp6_ = feature;
	_tmp7_ = skk_kana_kan_score_map_get_score (self, _tmp6_);
	score = _tmp5_ + _tmp7_;
	_tmp8_ = node;
	_tmp9_ = _tmp8_->word;
	_tmp10_ = g_strdup_printf ("S%s", _tmp9_);
	_g_free0 (feature);
	feature = _tmp10_;
	_tmp11_ = score;
	_tmp12_ = feature;
	_tmp13_ = skk_kana_kan_score_map_get_score (self, _tmp12_);
	score = _tmp11_ + _tmp13_;
	result = score;
	_g_free0 (feature);
	return result;
}


gdouble skk_kana_kan_score_map_get_edge_score (SkkKanaKanScoreMap* self, SkkKanaKanNode* prev_node, SkkKanaKanNode* node) {
	gdouble result = 0.0;
	SkkKanaKanNode* _tmp0_;
	const gchar* _tmp1_;
	SkkKanaKanNode* _tmp2_;
	const gchar* _tmp3_;
	gchar* _tmp4_ = NULL;
	gchar* feature;
	gdouble _tmp5_ = 0.0;
	g_return_val_if_fail (self != NULL, 0.0);
	g_return_val_if_fail (prev_node != NULL, 0.0);
	g_return_val_if_fail (node != NULL, 0.0);
	_tmp0_ = prev_node;
	_tmp1_ = _tmp0_->word;
	_tmp2_ = node;
	_tmp3_ = _tmp2_->word;
	_tmp4_ = g_strdup_printf ("S%s\tS%s", _tmp1_, _tmp3_);
	feature = _tmp4_;
	_tmp5_ = skk_kana_kan_score_map_get_score (self, feature);
	result = _tmp5_;
	_g_free0 (feature);
	return result;
}


static void skk_kana_kan_score_map_class_init (SkkKanaKanScoreMapClass * klass) {
	skk_kana_kan_score_map_parent_class = g_type_class_peek_parent (klass);
	g_type_class_add_private (klass, sizeof (SkkKanaKanScoreMapPrivate));
	G_OBJECT_CLASS (klass)->finalize = skk_kana_kan_score_map_finalize;
}


static void skk_kana_kan_score_map_instance_init (SkkKanaKanScoreMap * self) {
	GeeHashMap* _tmp0_;
	self->priv = SKK_KANA_KAN_SCORE_MAP_GET_PRIVATE (self);
	_tmp0_ = gee_hash_map_new (G_TYPE_STRING, (GBoxedCopyFunc) g_strdup, g_free, G_TYPE_DOUBLE, (GBoxedCopyFunc) _double_dup, g_free, NULL, NULL, NULL);
	self->priv->map = (GeeMap*) _tmp0_;
}


static void skk_kana_kan_score_map_finalize (GObject* obj) {
	SkkKanaKanScoreMap * self;
	self = G_TYPE_CHECK_INSTANCE_CAST (obj, SKK_TYPE_KANA_KAN_SCORE_MAP, SkkKanaKanScoreMap);
	_g_object_unref0 (self->priv->map);
	G_OBJECT_CLASS (skk_kana_kan_score_map_parent_class)->finalize (obj);
}


GType skk_kana_kan_score_map_get_type (void) {
	static volatile gsize skk_kana_kan_score_map_type_id__volatile = 0;
	if (g_once_init_enter (&skk_kana_kan_score_map_type_id__volatile)) {
		static const GTypeInfo g_define_type_info = { sizeof (SkkKanaKanScoreMapClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) skk_kana_kan_score_map_class_init, (GClassFinalizeFunc) NULL, NULL, sizeof (SkkKanaKanScoreMap), 0, (GInstanceInitFunc) skk_kana_kan_score_map_instance_init, NULL };
		GType skk_kana_kan_score_map_type_id;
		skk_kana_kan_score_map_type_id = g_type_register_static (G_TYPE_OBJECT, "SkkKanaKanScoreMap", &g_define_type_info, 0);
		g_once_init_leave (&skk_kana_kan_score_map_type_id__volatile, skk_kana_kan_score_map_type_id);
	}
	return skk_kana_kan_score_map_type_id__volatile;
}


SkkKanaKanNode* skk_kana_kan_node_construct (GType object_type, const gchar* word, const gchar* pron, gint endpos) {
	SkkKanaKanNode * self = NULL;
	const gchar* _tmp0_;
	gchar* _tmp1_;
	const gchar* _tmp2_;
	gchar* _tmp3_;
	gint _tmp4_;
	g_return_val_if_fail (word != NULL, NULL);
	g_return_val_if_fail (pron != NULL, NULL);
	self = (SkkKanaKanNode*) g_object_new (object_type, NULL);
	_tmp0_ = word;
	_tmp1_ = g_strdup (_tmp0_);
	_g_free0 (self->word);
	self->word = _tmp1_;
	_tmp2_ = pron;
	_tmp3_ = g_strdup (_tmp2_);
	_g_free0 (self->pron);
	self->pron = _tmp3_;
	_tmp4_ = endpos;
	self->endpos = _tmp4_;
	return self;
}


SkkKanaKanNode* skk_kana_kan_node_new (const gchar* word, const gchar* pron, gint endpos) {
	return skk_kana_kan_node_construct (SKK_TYPE_KANA_KAN_NODE, word, pron, endpos);
}


gboolean skk_kana_kan_node_is_bos (SkkKanaKanNode* self) {
	gboolean result = FALSE;
	gint _tmp0_;
	g_return_val_if_fail (self != NULL, FALSE);
	_tmp0_ = self->endpos;
	result = _tmp0_ == 0;
	return result;
}


gboolean skk_kana_kan_node_is_eos (SkkKanaKanNode* self) {
	gboolean result = FALSE;
	gboolean _tmp0_ = FALSE;
	gint _tmp1_;
	gint _tmp2_;
	gboolean _tmp4_;
	g_return_val_if_fail (self != NULL, FALSE);
	_tmp1_ = skk_kana_kan_node_get_length (self);
	_tmp2_ = _tmp1_;
	if (_tmp2_ == 0) {
		gint _tmp3_;
		_tmp3_ = self->endpos;
		_tmp0_ = _tmp3_ != 0;
	} else {
		_tmp0_ = FALSE;
	}
	_tmp4_ = _tmp0_;
	result = _tmp4_;
	return result;
}


gint skk_kana_kan_node_get_length (SkkKanaKanNode* self) {
	gint result;
	const gchar* _tmp0_;
	gint _tmp1_ = 0;
	g_return_val_if_fail (self != NULL, 0);
	_tmp0_ = self->pron;
	_tmp1_ = g_utf8_strlen (_tmp0_, (gssize) (-1));
	result = _tmp1_;
	return result;
}


static void skk_kana_kan_node_class_init (SkkKanaKanNodeClass * klass) {
	skk_kana_kan_node_parent_class = g_type_class_peek_parent (klass);
	G_OBJECT_CLASS (klass)->get_property = _vala_skk_kana_kan_node_get_property;
	G_OBJECT_CLASS (klass)->finalize = skk_kana_kan_node_finalize;
	g_object_class_install_property (G_OBJECT_CLASS (klass), SKK_KANA_KAN_NODE_LENGTH, g_param_spec_int ("length", "length", "length", G_MININT, G_MAXINT, 0, G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB | G_PARAM_READABLE));
}


static void skk_kana_kan_node_instance_init (SkkKanaKanNode * self) {
	self->score = 0.0;
	self->prev = NULL;
}


static void skk_kana_kan_node_finalize (GObject* obj) {
	SkkKanaKanNode * self;
	self = G_TYPE_CHECK_INSTANCE_CAST (obj, SKK_TYPE_KANA_KAN_NODE, SkkKanaKanNode);
	_g_free0 (self->word);
	_g_free0 (self->pron);
	_g_object_unref0 (self->prev);
	G_OBJECT_CLASS (skk_kana_kan_node_parent_class)->finalize (obj);
}


GType skk_kana_kan_node_get_type (void) {
	static volatile gsize skk_kana_kan_node_type_id__volatile = 0;
	if (g_once_init_enter (&skk_kana_kan_node_type_id__volatile)) {
		static const GTypeInfo g_define_type_info = { sizeof (SkkKanaKanNodeClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) skk_kana_kan_node_class_init, (GClassFinalizeFunc) NULL, NULL, sizeof (SkkKanaKanNode), 0, (GInstanceInitFunc) skk_kana_kan_node_instance_init, NULL };
		GType skk_kana_kan_node_type_id;
		skk_kana_kan_node_type_id = g_type_register_static (G_TYPE_OBJECT, "SkkKanaKanNode", &g_define_type_info, 0);
		g_once_init_leave (&skk_kana_kan_node_type_id__volatile, skk_kana_kan_node_type_id);
	}
	return skk_kana_kan_node_type_id__volatile;
}


static void _vala_skk_kana_kan_node_get_property (GObject * object, guint property_id, GValue * value, GParamSpec * pspec) {
	SkkKanaKanNode * self;
	self = G_TYPE_CHECK_INSTANCE_CAST (object, SKK_TYPE_KANA_KAN_NODE, SkkKanaKanNode);
	switch (property_id) {
		case SKK_KANA_KAN_NODE_LENGTH:
		g_value_set_int (value, skk_kana_kan_node_get_length (self));
		break;
		default:
		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
		break;
	}
}


SkkKanaKanGraph* skk_kana_kan_graph_construct (GType object_type, SkkKanaKanDict* dict, const gchar* str) {
	SkkKanaKanGraph * self = NULL;
	SkkKanaKanDict* _tmp0_;
	SkkKanaKanDict* _tmp1_;
	const gchar* _tmp2_;
	SkkUnicodeString* _tmp3_;
	SkkUnicodeString* ustr;
	SkkUnicodeString* _tmp4_;
	gint _tmp5_;
	GeeArrayList** _tmp6_ = NULL;
	SkkKanaKanNode* _tmp17_;
	GeeArrayList** _tmp18_;
	gint _tmp18__length1;
	GeeArrayList* _tmp19_;
	SkkKanaKanNode* _tmp20_;
	SkkUnicodeString* _tmp21_;
	gint _tmp22_;
	SkkKanaKanNode* _tmp23_;
	GeeArrayList** _tmp24_;
	gint _tmp24__length1;
	SkkUnicodeString* _tmp25_;
	gint _tmp26_;
	GeeArrayList* _tmp27_;
	SkkKanaKanNode* _tmp28_;
	g_return_val_if_fail (dict != NULL, NULL);
	g_return_val_if_fail (str != NULL, NULL);
	self = (SkkKanaKanGraph*) g_object_new (object_type, NULL);
	_tmp0_ = dict;
	_tmp1_ = _g_object_ref0 (_tmp0_);
	_g_object_unref0 (self->priv->dict);
	self->priv->dict = _tmp1_;
	_tmp2_ = str;
	_tmp3_ = skk_unicode_string_new (_tmp2_);
	ustr = _tmp3_;
	_tmp4_ = ustr;
	_tmp5_ = _tmp4_->length;
	_tmp6_ = g_new0 (GeeArrayList*, (_tmp5_ + 2) + 1);
	self->nodes = (_vala_array_free (self->nodes, self->nodes_length1, (GDestroyNotify) g_object_unref), NULL);
	self->nodes = _tmp6_;
	self->nodes_length1 = _tmp5_ + 2;
	self->_nodes_size_ = self->nodes_length1;
	{
		gint i;
		i = 0;
		{
			gboolean _tmp7_;
			_tmp7_ = TRUE;
			while (TRUE) {
				gboolean _tmp8_;
				gint _tmp10_;
				SkkUnicodeString* _tmp11_;
				gint _tmp12_;
				GeeArrayList** _tmp13_;
				gint _tmp13__length1;
				gint _tmp14_;
				GeeArrayList* _tmp15_;
				GeeArrayList* _tmp16_;
				_tmp8_ = _tmp7_;
				if (!_tmp8_) {
					gint _tmp9_;
					_tmp9_ = i;
					i = _tmp9_ + 1;
				}
				_tmp7_ = FALSE;
				_tmp10_ = i;
				_tmp11_ = ustr;
				_tmp12_ = _tmp11_->length;
				if (!(_tmp10_ < (_tmp12_ + 2))) {
					break;
				}
				_tmp13_ = self->nodes;
				_tmp13__length1 = self->nodes_length1;
				_tmp14_ = i;
				_tmp15_ = gee_array_list_new (SKK_TYPE_KANA_KAN_NODE, (GBoxedCopyFunc) g_object_ref, g_object_unref, NULL);
				_g_object_unref0 (_tmp13_[_tmp14_]);
				_tmp13_[_tmp14_] = _tmp15_;
				_tmp16_ = _tmp13_[_tmp14_];
			}
		}
	}
	_tmp17_ = skk_kana_kan_node_new ("", "", 0);
	_g_object_unref0 (self->bos);
	self->bos = _tmp17_;
	_tmp18_ = self->nodes;
	_tmp18__length1 = self->nodes_length1;
	_tmp19_ = _tmp18_[0];
	_tmp20_ = self->bos;
	gee_abstract_collection_add ((GeeAbstractCollection*) _tmp19_, _tmp20_);
	_tmp21_ = ustr;
	_tmp22_ = _tmp21_->length;
	_tmp23_ = skk_kana_kan_node_new ("", "", _tmp22_ + 1);
	_g_object_unref0 (self->eos);
	self->eos = _tmp23_;
	_tmp24_ = self->nodes;
	_tmp24__length1 = self->nodes_length1;
	_tmp25_ = ustr;
	_tmp26_ = _tmp25_->length;
	_tmp27_ = _tmp24_[_tmp26_ + 1];
	_tmp28_ = self->eos;
	gee_abstract_collection_add ((GeeAbstractCollection*) _tmp27_, _tmp28_);
	{
		gint i;
		i = 0;
		{
			gboolean _tmp29_;
			_tmp29_ = TRUE;
			while (TRUE) {
				gboolean _tmp30_;
				gint _tmp32_;
				SkkUnicodeString* _tmp33_;
				gint _tmp34_;
				gint _tmp66_;
				SkkUnicodeString* _tmp67_;
				gint _tmp68_;
				_tmp30_ = _tmp29_;
				if (!_tmp30_) {
					gint _tmp31_;
					_tmp31_ = i;
					i = _tmp31_ + 1;
				}
				_tmp29_ = FALSE;
				_tmp32_ = i;
				_tmp33_ = ustr;
				_tmp34_ = _tmp33_->length;
				if (!(_tmp32_ < _tmp34_)) {
					break;
				}
				{
					gint _tmp35_;
					gint j;
					_tmp35_ = i;
					j = _tmp35_ + 1;
					{
						gboolean _tmp36_;
						_tmp36_ = TRUE;
						while (TRUE) {
							gboolean _tmp37_;
							gint _tmp39_;
							SkkUnicodeString* _tmp40_;
							gint _tmp41_;
							gint _tmp42_;
							gint _tmp43_ = 0;
							SkkUnicodeString* _tmp44_;
							gint _tmp45_;
							gint _tmp46_;
							gint _tmp47_;
							gchar* _tmp48_ = NULL;
							gchar* pron;
							SkkKanaKanDict* _tmp49_;
							const gchar* _tmp50_;
							GeeSet* _tmp51_ = NULL;
							GeeSet* words;
							_tmp37_ = _tmp36_;
							if (!_tmp37_) {
								gint _tmp38_;
								_tmp38_ = j;
								j = _tmp38_ + 1;
							}
							_tmp36_ = FALSE;
							_tmp39_ = j;
							_tmp40_ = ustr;
							_tmp41_ = _tmp40_->length;
							_tmp42_ = i;
							_tmp43_ = MIN (_tmp41_, _tmp42_ + 16);
							if (!(_tmp39_ <= _tmp43_)) {
								break;
							}
							_tmp44_ = ustr;
							_tmp45_ = i;
							_tmp46_ = j;
							_tmp47_ = i;
							_tmp48_ = skk_unicode_string_substring (_tmp44_, (glong) _tmp45_, (glong) (_tmp46_ - _tmp47_));
							pron = _tmp48_;
							_tmp49_ = dict;
							_tmp50_ = pron;
							_tmp51_ = skk_kana_kan_dict_lookup (_tmp49_, _tmp50_);
							words = _tmp51_;
							{
								GeeSet* _tmp52_;
								GeeIterator* _tmp53_ = NULL;
								GeeIterator* _word_it;
								_tmp52_ = words;
								_tmp53_ = gee_iterable_iterator ((GeeIterable*) _tmp52_);
								_word_it = _tmp53_;
								while (TRUE) {
									GeeIterator* _tmp54_;
									gboolean _tmp55_ = FALSE;
									GeeIterator* _tmp56_;
									gpointer _tmp57_ = NULL;
									gchar* word;
									const gchar* _tmp58_;
									const gchar* _tmp59_;
									gint _tmp60_;
									SkkKanaKanNode* _tmp61_;
									SkkKanaKanNode* node;
									GeeArrayList** _tmp62_;
									gint _tmp62__length1;
									gint _tmp63_;
									GeeArrayList* _tmp64_;
									SkkKanaKanNode* _tmp65_;
									_tmp54_ = _word_it;
									_tmp55_ = gee_iterator_next (_tmp54_);
									if (!_tmp55_) {
										break;
									}
									_tmp56_ = _word_it;
									_tmp57_ = gee_iterator_get (_tmp56_);
									word = (gchar*) _tmp57_;
									_tmp58_ = word;
									_tmp59_ = pron;
									_tmp60_ = j;
									_tmp61_ = skk_kana_kan_node_new (_tmp58_, _tmp59_, _tmp60_);
									node = _tmp61_;
									_tmp62_ = self->nodes;
									_tmp62__length1 = self->nodes_length1;
									_tmp63_ = j;
									_tmp64_ = _tmp62_[_tmp63_];
									_tmp65_ = node;
									gee_abstract_collection_add ((GeeAbstractCollection*) _tmp64_, _tmp65_);
									_g_object_unref0 (node);
									_g_free0 (word);
								}
								_g_object_unref0 (_word_it);
							}
							_g_object_unref0 (words);
							_g_free0 (pron);
						}
					}
				}
				_tmp66_ = i;
				_tmp67_ = ustr;
				_tmp68_ = _tmp67_->length;
				if (_tmp66_ < _tmp68_) {
					SkkUnicodeString* _tmp69_;
					gint _tmp70_;
					gchar* _tmp71_ = NULL;
					gchar* pron;
					const gchar* _tmp72_;
					const gchar* _tmp73_;
					gint _tmp74_;
					SkkKanaKanNode* _tmp75_;
					SkkKanaKanNode* node;
					GeeArrayList** _tmp76_;
					gint _tmp76__length1;
					gint _tmp77_;
					GeeArrayList* _tmp78_;
					SkkKanaKanNode* _tmp79_;
					_tmp69_ = ustr;
					_tmp70_ = i;
					_tmp71_ = skk_unicode_string_substring (_tmp69_, (glong) _tmp70_, (glong) 1);
					pron = _tmp71_;
					_tmp72_ = pron;
					_tmp73_ = pron;
					_tmp74_ = i;
					_tmp75_ = skk_kana_kan_node_new (_tmp72_, _tmp73_, _tmp74_ + 1);
					node = _tmp75_;
					_tmp76_ = self->nodes;
					_tmp76__length1 = self->nodes_length1;
					_tmp77_ = i;
					_tmp78_ = _tmp76_[_tmp77_ + 1];
					_tmp79_ = node;
					gee_abstract_collection_add ((GeeAbstractCollection*) _tmp78_, _tmp79_);
					_g_object_unref0 (node);
					_g_free0 (pron);
				}
			}
		}
	}
	_g_object_unref0 (ustr);
	return self;
}


SkkKanaKanGraph* skk_kana_kan_graph_new (SkkKanaKanDict* dict, const gchar* str) {
	return skk_kana_kan_graph_construct (SKK_TYPE_KANA_KAN_GRAPH, dict, str);
}


GeeArrayList* skk_kana_kan_graph_get_prev_nodes (SkkKanaKanGraph* self, SkkKanaKanNode* node) {
	GeeArrayList* result = NULL;
	SkkKanaKanNode* _tmp0_;
	gboolean _tmp1_ = FALSE;
	g_return_val_if_fail (self != NULL, NULL);
	g_return_val_if_fail (node != NULL, NULL);
	_tmp0_ = node;
	_tmp1_ = skk_kana_kan_node_is_eos (_tmp0_);
	if (_tmp1_) {
		SkkKanaKanNode* _tmp2_;
		gint _tmp3_;
		gint startpos;
		GeeArrayList** _tmp4_;
		gint _tmp4__length1;
		gint _tmp5_;
		GeeArrayList* _tmp6_;
		GeeArrayList* _tmp7_;
		_tmp2_ = node;
		_tmp3_ = _tmp2_->endpos;
		startpos = _tmp3_ - 1;
		_tmp4_ = self->nodes;
		_tmp4__length1 = self->nodes_length1;
		_tmp5_ = startpos;
		_tmp6_ = _tmp4_[_tmp5_];
		_tmp7_ = _g_object_ref0 (_tmp6_);
		result = _tmp7_;
		return result;
	} else {
		SkkKanaKanNode* _tmp8_;
		gboolean _tmp9_ = FALSE;
		_tmp8_ = node;
		_tmp9_ = skk_kana_kan_node_is_bos (_tmp8_);
		if (_tmp9_) {
			GeeArrayList* _tmp10_;
			_tmp10_ = gee_array_list_new (SKK_TYPE_KANA_KAN_NODE, (GBoxedCopyFunc) g_object_ref, g_object_unref, NULL);
			result = _tmp10_;
			return result;
		} else {
			SkkKanaKanNode* _tmp11_;
			gint _tmp12_;
			SkkKanaKanNode* _tmp13_;
			gint _tmp14_;
			gint _tmp15_;
			gint startpos;
			GeeArrayList** _tmp16_;
			gint _tmp16__length1;
			gint _tmp17_;
			GeeArrayList* _tmp18_;
			GeeArrayList* _tmp19_;
			_tmp11_ = node;
			_tmp12_ = _tmp11_->endpos;
			_tmp13_ = node;
			_tmp14_ = skk_kana_kan_node_get_length (_tmp13_);
			_tmp15_ = _tmp14_;
			startpos = _tmp12_ - _tmp15_;
			_tmp16_ = self->nodes;
			_tmp16__length1 = self->nodes_length1;
			_tmp17_ = startpos;
			_tmp18_ = _tmp16_[_tmp17_];
			_tmp19_ = _g_object_ref0 (_tmp18_);
			result = _tmp19_;
			return result;
		}
	}
}


static void skk_kana_kan_graph_class_init (SkkKanaKanGraphClass * klass) {
	skk_kana_kan_graph_parent_class = g_type_class_peek_parent (klass);
	g_type_class_add_private (klass, sizeof (SkkKanaKanGraphPrivate));
	G_OBJECT_CLASS (klass)->finalize = skk_kana_kan_graph_finalize;
}


static void skk_kana_kan_graph_instance_init (SkkKanaKanGraph * self) {
	self->priv = SKK_KANA_KAN_GRAPH_GET_PRIVATE (self);
}


static void skk_kana_kan_graph_finalize (GObject* obj) {
	SkkKanaKanGraph * self;
	self = G_TYPE_CHECK_INSTANCE_CAST (obj, SKK_TYPE_KANA_KAN_GRAPH, SkkKanaKanGraph);
	_g_object_unref0 (self->priv->dict);
	self->nodes = (_vala_array_free (self->nodes, self->nodes_length1, (GDestroyNotify) g_object_unref), NULL);
	_g_object_unref0 (self->bos);
	_g_object_unref0 (self->eos);
	G_OBJECT_CLASS (skk_kana_kan_graph_parent_class)->finalize (obj);
}


GType skk_kana_kan_graph_get_type (void) {
	static volatile gsize skk_kana_kan_graph_type_id__volatile = 0;
	if (g_once_init_enter (&skk_kana_kan_graph_type_id__volatile)) {
		static const GTypeInfo g_define_type_info = { sizeof (SkkKanaKanGraphClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) skk_kana_kan_graph_class_init, (GClassFinalizeFunc) NULL, NULL, sizeof (SkkKanaKanGraph), 0, (GInstanceInitFunc) skk_kana_kan_graph_instance_init, NULL };
		GType skk_kana_kan_graph_type_id;
		skk_kana_kan_graph_type_id = g_type_register_static (G_TYPE_OBJECT, "SkkKanaKanGraph", &g_define_type_info, 0);
		g_once_init_leave (&skk_kana_kan_graph_type_id__volatile, skk_kana_kan_graph_type_id);
	}
	return skk_kana_kan_graph_type_id__volatile;
}


static void _vala_array_destroy (gpointer array, gint array_length, GDestroyNotify destroy_func) {
	if ((array != NULL) && (destroy_func != NULL)) {
		int 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, gint array_length, GDestroyNotify destroy_func) {
	_vala_array_destroy (array, array_length, destroy_func);
	g_free (array);
}


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



