/* converter-plugin-backend.c generated by valac 0.56.18-dirty, the Vala compiler
 * generated from converter-plugin-backend.vala, do not modify */

/*
* Copyright (c) 2010 Michal Hruby <michal.mhr@gmail.com>
*               2022 elementary LLC. (https://elementary.io)
*
* 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 2 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, write to the
* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301 USA
*
* Authored by: Michal Hruby <michal.mhr@gmail.com>
*/

#include <glib-object.h>
#include <stdlib.h>
#include <string.h>
#include <glib.h>
#include <float.h>
#include <math.h>
#include <glib/gi18n-lib.h>
#include "slingshot.h"

#define SYNAPSE_MASS "unit of mass"
#define SYNAPSE_LENGTH "unit of length"
#define SYNAPSE_AREA "unit of area"
#define SYNAPSE_VOLUME "unit of volume"
#define SYNAPSE_TIME "unit of time"
#define SYNAPSE_VELOCITY "unit of velocity"
#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 SYNAPSE_TYPE_UNIT_MATCH (synapse_unit_match_get_type ())
typedef struct _SynapseUnitMatch SynapseUnitMatch;

#define SYNAPSE_TYPE_UNIT (synapse_unit_get_type ())
typedef struct _SynapseUnit SynapseUnit;
typedef enum  {
	SYNAPSE_UNIT_TYPE_MASS,
	SYNAPSE_UNIT_TYPE_DIMENSION,
	SYNAPSE_UNIT_TYPE_TIME,
	SYNAPSE_UNIT_TYPE_VELOCITY
} SynapseUnitType;

#define SYNAPSE_TYPE_UNIT_TYPE (synapse_unit_type_get_type ())
typedef enum  {
	SYNAPSE_UNIT_SYSTEM_SI,
	SYNAPSE_UNIT_SYSTEM_IMPERIAL,
	SYNAPSE_UNIT_SYSTEM_IMPERIAL_UK,
	SYNAPSE_UNIT_SYSTEM_IMPERIAL_US
} SynapseUnitSystem;

#define SYNAPSE_TYPE_UNIT_SYSTEM (synapse_unit_system_get_type ())

#define SYNAPSE_TYPE_SI_PREFIX (synapse_si_prefix_get_type ())
typedef struct _SynapseSIPrefix SynapseSIPrefix;
#define _g_free0(var) (var = (g_free (var), NULL))
enum  {
	SYNAPSE_CONVERTER_PLUGIN_BACKEND_0_PROPERTY,
	SYNAPSE_CONVERTER_PLUGIN_BACKEND_NUM_PROPERTIES
};
static GParamSpec* synapse_converter_plugin_backend_properties[SYNAPSE_CONVERTER_PLUGIN_BACKEND_NUM_PROPERTIES];
#define _g_regex_unref0(var) ((var == NULL) ? NULL : (var = (g_regex_unref (var), NULL)))
#define _g_object_unref0(var) ((var == NULL) ? NULL : (var = (g_object_unref (var), NULL)))
#define _g_match_info_unref0(var) ((var == NULL) ? NULL : (var = (g_match_info_unref (var), NULL)))
#define _synapse_result_data_free0(var) ((var == NULL) ? NULL : (var = (synapse_result_data_free (var), NULL)))
#define _synapse_unit_free0(var) ((var == NULL) ? NULL : (var = (synapse_unit_free (var), NULL)))
#define _g_error_free0(var) ((var == NULL) ? NULL : (var = (g_error_free (var), NULL)))

struct _SynapseUnit {
	SynapseUnitType type;
	SynapseUnitSystem system;
	gchar* uid;
	gchar* abbreviations;
	gchar* description;
	gchar* size_s;
	gchar* base_unit;
};

struct _SynapseSIPrefix {
	gchar* prefix;
	gchar* abbrev;
	gdouble factor;
};

struct _SynapseUnitMatch {
	SynapseUnit unit;
	SynapseSIPrefix prefix;
	gint dimension;
};

struct _SynapseConverterPluginBackendPrivate {
	GRegex* convert_regex;
};

static gint SynapseConverterPluginBackend_private_offset;
static gpointer synapse_converter_plugin_backend_parent_class = NULL;
static SynapseConverterPluginBackend* synapse_converter_plugin_backend_instance;
static SynapseConverterPluginBackend* synapse_converter_plugin_backend_instance = NULL;

VALA_EXTERN GType synapse_unit_match_get_type (void) G_GNUC_CONST ;
VALA_EXTERN GType synapse_unit_get_type (void) G_GNUC_CONST ;
VALA_EXTERN GType synapse_unit_type_get_type (void) G_GNUC_CONST ;
VALA_EXTERN GType synapse_unit_system_get_type (void) G_GNUC_CONST ;
VALA_EXTERN SynapseUnit* synapse_unit_dup (const SynapseUnit* self);
VALA_EXTERN void synapse_unit_free (SynapseUnit* self);
VALA_EXTERN void synapse_unit_copy (const SynapseUnit* self,
                        SynapseUnit* dest);
VALA_EXTERN void synapse_unit_destroy (SynapseUnit* self);
VALA_EXTERN GType synapse_si_prefix_get_type (void) G_GNUC_CONST ;
VALA_EXTERN SynapseSIPrefix* synapse_si_prefix_dup (const SynapseSIPrefix* self);
VALA_EXTERN void synapse_si_prefix_free (SynapseSIPrefix* self);
VALA_EXTERN void synapse_si_prefix_copy (const SynapseSIPrefix* self,
                             SynapseSIPrefix* dest);
VALA_EXTERN void synapse_si_prefix_destroy (SynapseSIPrefix* self);
VALA_EXTERN SynapseUnitMatch* synapse_unit_match_dup (const SynapseUnitMatch* self);
VALA_EXTERN void synapse_unit_match_free (SynapseUnitMatch* self);
VALA_EXTERN void synapse_unit_match_copy (const SynapseUnitMatch* self,
                              SynapseUnitMatch* dest);
VALA_EXTERN void synapse_unit_match_destroy (SynapseUnitMatch* self);
VALA_EXTERN gchar* synapse_unit_match_description (SynapseUnitMatch *self);
VALA_EXTERN gdouble synapse_unit_match_factor (SynapseUnitMatch *self);
VALA_EXTERN gdouble synapse_unit_get_factor (SynapseUnit *self);
VALA_EXTERN void synapse_si_prefix_get_default (SynapseSIPrefix* result);
static void synapse_converter_plugin_backend_get_prefix (SynapseConverterPluginBackend* self,
                                                  const gchar* unit_s,
                                                  gchar** prefix_s,
                                                  SynapseSIPrefix* prefix);
static gboolean synapse_converter_plugin_backend_check_match (SynapseConverterPluginBackend* self,
                                                       SynapseUnit* u,
                                                       const gchar* unit_s,
                                                       const gchar* prefix,
                                                       gint dimension,
                                                       gboolean* use_prefix);
static void _vala_array_add11 (SynapseUnitMatch* * array,
                        gint* length,
                        gint* size,
                        const SynapseUnitMatch* value);
static void _vala_array_add12 (SynapseUnitMatch* * array,
                        gint* length,
                        gint* size,
                        const SynapseUnitMatch* value);
static SynapseResultData* synapse_converter_plugin_backend_calculate_conversion_data (SynapseConverterPluginBackend* self,
                                                                               gdouble num,
                                                                               SynapseUnitMatch* match1,
                                                                               SynapseUnitMatch* match2);
static void _vala_array_add13 (SynapseResultData* * array,
                        gint* length,
                        gint* size,
                        const SynapseResultData* value);
static void _vala_SynapseUnitMatch_array_free (SynapseUnitMatch * array,
                                        gssize array_length);
static void synapse_converter_plugin_backend_find_root (SynapseConverterPluginBackend* self,
                                                 SynapseUnit** parent,
                                                 gint* dim,
                                                 gdouble* factor,
                                                 gboolean same_system,
                                                 SynapseUnitSystem match_unit_system);
static void _vala_array_add14 (gchar** * array,
                        gint* length,
                        gint* size,
                        gchar* value);
static void _vala_array_add15 (gchar** * array,
                        gint* length,
                        gint* size,
                        gchar* value);
static GObject * synapse_converter_plugin_backend_constructor (GType type,
                                                        guint n_construct_properties,
                                                        GObjectConstructParam * construct_properties);
static void synapse_converter_plugin_backend_finalize (GObject * obj);
static GType synapse_converter_plugin_backend_get_type_once (void);
static void _vala_array_destroy (gpointer array,
                          gssize array_length,
                          GDestroyNotify destroy_func);
static void _vala_array_free (gpointer array,
                       gssize array_length,
                       GDestroyNotify destroy_func);
static gssize _vala_array_length (gpointer array);

VALA_EXTERN const SynapseUnit SYNAPSE_UNITS[75];
VALA_EXTERN const SynapseSIPrefix SYNAPSE_PREFIXES[20];

gchar*
synapse_unit_match_description (SynapseUnitMatch *self)
{
	gchar* dim = NULL;
	gchar* _tmp0_;
	SynapseSIPrefix _tmp3_;
	const gchar* _tmp4_;
	SynapseUnit _tmp5_;
	const gchar* _tmp6_;
	const gchar* _tmp7_;
	gchar* _tmp8_;
	gchar* result;
	_tmp0_ = g_strdup ("");
	dim = _tmp0_;
	if ((*self).dimension == 2) {
		gchar* _tmp1_;
		_tmp1_ = g_strdup (_ ("squared"));
		_g_free0 (dim);
		dim = _tmp1_;
	} else {
		if ((*self).dimension == 3) {
			gchar* _tmp2_;
			_tmp2_ = g_strdup (_ ("cubed"));
			_g_free0 (dim);
			dim = _tmp2_;
		}
	}
	_tmp3_ = (*self).prefix;
	_tmp4_ = _tmp3_.prefix;
	_tmp5_ = (*self).unit;
	_tmp6_ = _tmp5_.description;
	_tmp7_ = dim;
	_tmp8_ = g_strdup_printf (_ ("%s%s %s"), _tmp4_, _tmp6_, _tmp7_);
	result = _tmp8_;
	_g_free0 (dim);
	return result;
}

gdouble
synapse_unit_match_factor (SynapseUnitMatch *self)
{
	gdouble factor = 0.0;
	gdouble size = 0.0;
	gdouble result;
	factor = 1.0;
	size = synapse_unit_get_factor (&(*self).unit);
	{
		gint i = 0;
		i = 0;
		{
			gboolean _tmp0_ = FALSE;
			_tmp0_ = TRUE;
			while (TRUE) {
				SynapseSIPrefix _tmp2_;
				if (!_tmp0_) {
					gint _tmp1_;
					_tmp1_ = i;
					i = _tmp1_ + 1;
				}
				_tmp0_ = FALSE;
				if (!(i < (*self).dimension)) {
					break;
				}
				_tmp2_ = (*self).prefix;
				factor *= _tmp2_.factor;
				factor *= size;
			}
		}
	}
	result = factor;
	return result;
}

void
synapse_unit_match_copy (const SynapseUnitMatch* self,
                         SynapseUnitMatch* dest)
{
	SynapseUnit _tmp0_;
	SynapseUnit _tmp1_;
	SynapseUnit _tmp2_ = {0};
	SynapseSIPrefix _tmp3_;
	SynapseSIPrefix _tmp4_;
	SynapseSIPrefix _tmp5_ = {0};
	_tmp0_ = (*self).unit;
	_tmp1_ = _tmp0_;
	synapse_unit_copy (&_tmp1_, &_tmp2_);
	synapse_unit_destroy (&(*dest).unit);
	(*dest).unit = _tmp2_;
	_tmp3_ = (*self).prefix;
	_tmp4_ = _tmp3_;
	synapse_si_prefix_copy (&_tmp4_, &_tmp5_);
	synapse_si_prefix_destroy (&(*dest).prefix);
	(*dest).prefix = _tmp5_;
	(*dest).dimension = (*self).dimension;
}

void
synapse_unit_match_destroy (SynapseUnitMatch* self)
{
	synapse_unit_destroy (&(*self).unit);
	synapse_si_prefix_destroy (&(*self).prefix);
}

SynapseUnitMatch*
synapse_unit_match_dup (const SynapseUnitMatch* self)
{
	SynapseUnitMatch* dup;
	dup = g_new0 (SynapseUnitMatch, 1);
	synapse_unit_match_copy (self, dup);
	return dup;
}

void
synapse_unit_match_free (SynapseUnitMatch* self)
{
	synapse_unit_match_destroy (self);
	g_free (self);
}

static GType
synapse_unit_match_get_type_once (void)
{
	GType synapse_unit_match_type_id;
	synapse_unit_match_type_id = g_boxed_type_register_static ("SynapseUnitMatch", (GBoxedCopyFunc) synapse_unit_match_dup, (GBoxedFreeFunc) synapse_unit_match_free);
	return synapse_unit_match_type_id;
}

GType
synapse_unit_match_get_type (void)
{
	static volatile gsize synapse_unit_match_type_id__once = 0;
	if (g_once_init_enter (&synapse_unit_match_type_id__once)) {
		GType synapse_unit_match_type_id;
		synapse_unit_match_type_id = synapse_unit_match_get_type_once ();
		g_once_init_leave (&synapse_unit_match_type_id__once, synapse_unit_match_type_id);
	}
	return synapse_unit_match_type_id__once;
}

void
synapse_result_data_copy (const SynapseResultData* self,
                          SynapseResultData* dest)
{
	const gchar* _tmp0_;
	gchar* _tmp1_;
	const gchar* _tmp2_;
	gchar* _tmp3_;
	(*dest).factor = (*self).factor;
	_tmp0_ = (*self).from_description;
	_tmp1_ = g_strdup (_tmp0_);
	_g_free0 ((*dest).from_description);
	(*dest).from_description = _tmp1_;
	_tmp2_ = (*self).to_description;
	_tmp3_ = g_strdup (_tmp2_);
	_g_free0 ((*dest).to_description);
	(*dest).to_description = _tmp3_;
}

void
synapse_result_data_destroy (SynapseResultData* self)
{
	_g_free0 ((*self).from_description);
	_g_free0 ((*self).to_description);
}

SynapseResultData*
synapse_result_data_dup (const SynapseResultData* self)
{
	SynapseResultData* dup;
	dup = g_new0 (SynapseResultData, 1);
	synapse_result_data_copy (self, dup);
	return dup;
}

void
synapse_result_data_free (SynapseResultData* self)
{
	synapse_result_data_destroy (self);
	g_free (self);
}

static GType
synapse_result_data_get_type_once (void)
{
	GType synapse_result_data_type_id;
	synapse_result_data_type_id = g_boxed_type_register_static ("SynapseResultData", (GBoxedCopyFunc) synapse_result_data_dup, (GBoxedFreeFunc) synapse_result_data_free);
	return synapse_result_data_type_id;
}

GType
synapse_result_data_get_type (void)
{
	static volatile gsize synapse_result_data_type_id__once = 0;
	if (g_once_init_enter (&synapse_result_data_type_id__once)) {
		GType synapse_result_data_type_id;
		synapse_result_data_type_id = synapse_result_data_get_type_once ();
		g_once_init_leave (&synapse_result_data_type_id__once, synapse_result_data_type_id);
	}
	return synapse_result_data_type_id__once;
}

static inline gpointer
synapse_converter_plugin_backend_get_instance_private (SynapseConverterPluginBackend* self)
{
	return G_STRUCT_MEMBER_P (self, SynapseConverterPluginBackend_private_offset);
}

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

SynapseConverterPluginBackend*
synapse_converter_plugin_backend_get_instance (void)
{
	SynapseConverterPluginBackend* _tmp0_;
	SynapseConverterPluginBackend* _tmp2_;
	SynapseConverterPluginBackend* _tmp3_;
	SynapseConverterPluginBackend* result;
	_tmp0_ = synapse_converter_plugin_backend_instance;
	if (_tmp0_ == NULL) {
		SynapseConverterPluginBackend* _tmp1_;
		_tmp1_ = synapse_converter_plugin_backend_new ();
		_g_object_unref0 (synapse_converter_plugin_backend_instance);
		synapse_converter_plugin_backend_instance = _tmp1_;
	}
	_tmp2_ = synapse_converter_plugin_backend_instance;
	_tmp3_ = _g_object_ref0 (_tmp2_);
	result = _tmp3_;
	return result;
}

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

static gchar*
string_replace (const gchar* self,
                const gchar* old,
                const gchar* replacement)
{
	gboolean _tmp0_ = FALSE;
	gboolean _tmp1_ = FALSE;
	GError* _inner_error0_ = NULL;
	gchar* result;
	g_return_val_if_fail (self != NULL, NULL);
	g_return_val_if_fail (old != NULL, NULL);
	g_return_val_if_fail (replacement != NULL, NULL);
	if ((*((gchar*) self)) == '\0') {
		_tmp1_ = TRUE;
	} else {
		_tmp1_ = (*((gchar*) old)) == '\0';
	}
	if (_tmp1_) {
		_tmp0_ = TRUE;
	} else {
		_tmp0_ = g_strcmp0 (old, replacement) == 0;
	}
	if (_tmp0_) {
		gchar* _tmp2_;
		_tmp2_ = g_strdup (self);
		result = _tmp2_;
		return result;
	}
	{
		GRegex* regex = NULL;
		gchar* _tmp3_;
		gchar* _tmp4_;
		GRegex* _tmp5_;
		GRegex* _tmp6_;
		gchar* _tmp7_ = NULL;
		GRegex* _tmp8_;
		gchar* _tmp9_;
		gchar* _tmp10_;
		_tmp3_ = g_regex_escape_string (old, -1);
		_tmp4_ = _tmp3_;
		_tmp5_ = g_regex_new (_tmp4_, 0, 0, &_inner_error0_);
		_tmp6_ = _tmp5_;
		_g_free0 (_tmp4_);
		regex = _tmp6_;
		if (G_UNLIKELY (_inner_error0_ != NULL)) {
			if (_inner_error0_->domain == G_REGEX_ERROR) {
				goto __catch0_g_regex_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;
		}
		_tmp8_ = regex;
		_tmp9_ = g_regex_replace_literal (_tmp8_, self, (gssize) -1, 0, replacement, 0, &_inner_error0_);
		_tmp7_ = _tmp9_;
		if (G_UNLIKELY (_inner_error0_ != NULL)) {
			_g_regex_unref0 (regex);
			if (_inner_error0_->domain == G_REGEX_ERROR) {
				goto __catch0_g_regex_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;
		}
		_tmp10_ = _tmp7_;
		_tmp7_ = NULL;
		result = _tmp10_;
		_g_free0 (_tmp7_);
		_g_regex_unref0 (regex);
		return result;
	}
	goto __finally0;
	__catch0_g_regex_error:
	{
		g_clear_error (&_inner_error0_);
		g_assert_not_reached ();
	}
	__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 gdouble
double_parse (const gchar* str)
{
	gdouble result;
	g_return_val_if_fail (str != NULL, 0.0);
	result = g_ascii_strtod (str, NULL);
	return result;
}

static void
_vala_array_add11 (SynapseUnitMatch* * array,
                   gint* length,
                   gint* size,
                   const SynapseUnitMatch* value)
{
	if ((*length) == (*size)) {
		*size = (*size) ? (2 * (*size)) : 4;
		*array = g_renew (SynapseUnitMatch, *array, *size);
	}
	(*array)[(*length)++] = *value;
}

static void
_vala_array_add12 (SynapseUnitMatch* * array,
                   gint* length,
                   gint* size,
                   const SynapseUnitMatch* value)
{
	if ((*length) == (*size)) {
		*size = (*size) ? (2 * (*size)) : 4;
		*array = g_renew (SynapseUnitMatch, *array, *size);
	}
	(*array)[(*length)++] = *value;
}

static void
_vala_array_add13 (SynapseResultData* * array,
                   gint* length,
                   gint* size,
                   const SynapseResultData* value)
{
	if ((*length) == (*size)) {
		*size = (*size) ? (2 * (*size)) : 4;
		*array = g_renew (SynapseResultData, *array, *size);
	}
	(*array)[(*length)++] = *value;
}

static void
_vala_SynapseUnitMatch_array_free (SynapseUnitMatch * array,
                                   gssize array_length)
{
	if (array != NULL) {
		gssize i;
		for (i = 0; i < array_length; i = i + 1) {
			synapse_unit_match_destroy (&array[i]);
		}
	}
	g_free (array);
}

SynapseResultData*
synapse_converter_plugin_backend_get_conversion_data (SynapseConverterPluginBackend* self,
                                                      const gchar* query_string,
                                                      gint* result_length1)
{
	SynapseResultData* results = NULL;
	SynapseResultData* _tmp0_;
	gint results_length1;
	gint _results_size_;
	gboolean _tmp1_ = FALSE;
	gchar* input = NULL;
	gchar* _tmp3_;
	GMatchInfo* match_info = NULL;
	gboolean matched = FALSE;
	GRegex* _tmp4_;
	const gchar* _tmp5_;
	GMatchInfo* _tmp6_ = NULL;
	gboolean _tmp7_;
	gdouble num = 0.0;
	SynapseUnitMatch* match_arr1 = NULL;
	SynapseUnitMatch* _tmp8_;
	gint match_arr1_length1;
	gint _match_arr1_size_;
	SynapseUnitMatch* match_arr2 = NULL;
	SynapseUnitMatch* _tmp9_;
	gint match_arr2_length1;
	gint _match_arr2_size_;
	SynapseSIPrefix prefix1 = {0};
	SynapseSIPrefix _tmp10_ = {0};
	SynapseSIPrefix prefix2 = {0};
	SynapseSIPrefix _tmp11_ = {0};
	gchar* prefix1_s = NULL;
	gchar* _tmp12_;
	gchar* prefix2_s = NULL;
	gchar* _tmp13_;
	gint dimension1 = 0;
	gint dimension2 = 0;
	gboolean use_prefix = FALSE;
	SynapseUnitMatch* _tmp72_;
	gint _tmp72__length1;
	SynapseUnitMatch* _tmp73_;
	gint _tmp73__length1;
	SynapseResultData* _tmp97_;
	gint _tmp97__length1;
	SynapseResultData* result;
	g_return_val_if_fail (self != NULL, NULL);
	g_return_val_if_fail (query_string != NULL, NULL);
	_tmp0_ = g_new0 (SynapseResultData, 0);
	results = _tmp0_;
	results_length1 = 0;
	_results_size_ = results_length1;
	if (string_contains (query_string, "=>")) {
		_tmp1_ = TRUE;
	} else {
		_tmp1_ = string_contains (query_string, "->");
	}
	if (!_tmp1_) {
		SynapseResultData* _tmp2_;
		gint _tmp2__length1;
		_tmp2_ = results;
		_tmp2__length1 = results_length1;
		if (result_length1) {
			*result_length1 = _tmp2__length1;
		}
		result = _tmp2_;
		return result;
	}
	_tmp3_ = string_replace (query_string, ",", ".");
	input = _tmp3_;
	match_info = NULL;
	_tmp4_ = self->priv->convert_regex;
	_tmp5_ = input;
	_tmp7_ = g_regex_match (_tmp4_, _tmp5_, 0, &_tmp6_);
	_g_match_info_unref0 (match_info);
	match_info = _tmp6_;
	matched = _tmp7_;
	num = 1.0;
	_tmp8_ = g_new0 (SynapseUnitMatch, 0);
	match_arr1 = _tmp8_;
	match_arr1_length1 = 0;
	_match_arr1_size_ = match_arr1_length1;
	_tmp9_ = g_new0 (SynapseUnitMatch, 0);
	match_arr2 = _tmp9_;
	match_arr2_length1 = 0;
	_match_arr2_size_ = match_arr2_length1;
	synapse_si_prefix_get_default (&_tmp10_);
	prefix1 = _tmp10_;
	synapse_si_prefix_get_default (&_tmp11_);
	prefix2 = _tmp11_;
	_tmp12_ = g_strdup ("");
	prefix1_s = _tmp12_;
	_tmp13_ = g_strdup ("");
	prefix2_s = _tmp13_;
	dimension1 = 1;
	dimension2 = 1;
	use_prefix = FALSE;
	if (matched) {
		GMatchInfo* _tmp14_;
		gchar* _tmp15_;
		gchar* _tmp16_;
		gdouble _tmp17_ = 0.0;
		gchar* unit1_s = NULL;
		GMatchInfo* _tmp18_;
		gchar* _tmp19_;
		GMatchInfo* _tmp20_;
		gchar* _tmp21_;
		gchar* _tmp22_;
		gchar* unit2_s = NULL;
		GMatchInfo* _tmp23_;
		gchar* _tmp24_;
		GMatchInfo* _tmp25_;
		gchar* _tmp26_;
		gchar* _tmp27_;
		const gchar* _tmp28_;
		gchar* _tmp29_ = NULL;
		SynapseSIPrefix _tmp30_ = {0};
		const gchar* _tmp31_;
		gchar* _tmp32_ = NULL;
		SynapseSIPrefix _tmp33_ = {0};
		const gchar* _tmp34_;
		const gchar* _tmp35_;
		const gchar* _tmp36_;
		const gchar* _tmp37_;
		_tmp14_ = match_info;
		_tmp15_ = g_match_info_fetch (_tmp14_, 1);
		_tmp16_ = _tmp15_;
		num = double_parse (_tmp16_);
		_g_free0 (_tmp16_);
		if (num == ((gdouble) 0)) {
			_tmp17_ = 1.0;
		} else {
			_tmp17_ = num;
		}
		num = _tmp17_;
		_tmp18_ = match_info;
		_tmp19_ = g_match_info_fetch (_tmp18_, 2);
		unit1_s = _tmp19_;
		_tmp20_ = match_info;
		_tmp21_ = g_match_info_fetch (_tmp20_, 3);
		_tmp22_ = _tmp21_;
		dimension1 = CLAMP (atoi (_tmp22_), 1, 3);
		_g_free0 (_tmp22_);
		_tmp23_ = match_info;
		_tmp24_ = g_match_info_fetch (_tmp23_, 4);
		unit2_s = _tmp24_;
		_tmp25_ = match_info;
		_tmp26_ = g_match_info_fetch (_tmp25_, 5);
		_tmp27_ = _tmp26_;
		dimension2 = CLAMP (atoi (_tmp27_), 1, 3);
		_g_free0 (_tmp27_);
		_tmp28_ = unit1_s;
		synapse_converter_plugin_backend_get_prefix (self, _tmp28_, &_tmp29_, &_tmp30_);
		_g_free0 (prefix1_s);
		prefix1_s = _tmp29_;
		synapse_si_prefix_destroy (&prefix1);
		prefix1 = _tmp30_;
		_tmp31_ = unit2_s;
		synapse_converter_plugin_backend_get_prefix (self, _tmp31_, &_tmp32_, &_tmp33_);
		_g_free0 (prefix2_s);
		prefix2_s = _tmp32_;
		synapse_si_prefix_destroy (&prefix2);
		prefix2 = _tmp33_;
		_tmp34_ = unit1_s;
		_tmp35_ = unit2_s;
		_tmp36_ = prefix1_s;
		_tmp37_ = prefix2_s;
		g_debug ("converter-plugin-backend.vala:114: num %f, unit1_s %s, unit2_s, %s, pr" \
"efix1 %s, prefix2 %s, dimension1 %i, dimension2 %i", num, _tmp34_, _tmp35_, _tmp36_, _tmp37_, dimension1, dimension2);
		{
			SynapseUnit* u_collection = NULL;
			gint u_collection_length1 = 0;
			gint _u_collection_size_ = 0;
			gint u_it = 0;
			u_collection = SYNAPSE_UNITS;
			u_collection_length1 = G_N_ELEMENTS (SYNAPSE_UNITS);
			for (u_it = 0; u_it < u_collection_length1; u_it = u_it + 1) {
				SynapseUnit _tmp38_;
				SynapseUnit _tmp39_ = {0};
				SynapseUnit u = {0};
				_tmp38_ = u_collection[u_it];
				synapse_unit_copy (&_tmp38_, &_tmp39_);
				u = _tmp39_;
				{
					SynapseUnit _tmp40_;
					const gchar* _tmp41_;
					const gchar* _tmp42_;
					gboolean _tmp43_ = FALSE;
					gboolean _tmp44_;
					SynapseUnit _tmp56_;
					const gchar* _tmp57_;
					const gchar* _tmp58_;
					gboolean _tmp59_ = FALSE;
					gboolean _tmp60_;
					_tmp40_ = u;
					_tmp41_ = unit1_s;
					_tmp42_ = prefix1_s;
					_tmp44_ = synapse_converter_plugin_backend_check_match (self, &_tmp40_, _tmp41_, _tmp42_, dimension1, &_tmp43_);
					use_prefix = _tmp43_;
					if (_tmp44_) {
						SynapseSIPrefix _tmp45_ = {0};
						SynapseUnit _tmp50_;
						SynapseUnit _tmp51_;
						SynapseUnit _tmp52_ = {0};
						SynapseSIPrefix _tmp53_;
						SynapseSIPrefix _tmp54_ = {0};
						SynapseUnitMatch _tmp55_ = {0};
						if (use_prefix) {
							SynapseSIPrefix _tmp46_;
							SynapseSIPrefix _tmp47_;
							SynapseSIPrefix _tmp48_ = {0};
							_tmp46_ = prefix1;
							_tmp47_ = _tmp46_;
							synapse_si_prefix_copy (&_tmp47_, &_tmp48_);
							synapse_si_prefix_destroy (&_tmp45_);
							_tmp45_ = _tmp48_;
						} else {
							SynapseSIPrefix _tmp49_ = {0};
							synapse_si_prefix_get_default (&_tmp49_);
							synapse_si_prefix_destroy (&_tmp45_);
							_tmp45_ = _tmp49_;
						}
						_tmp50_ = u;
						_tmp51_ = _tmp50_;
						synapse_unit_copy (&_tmp51_, &_tmp52_);
						_tmp53_ = _tmp45_;
						synapse_si_prefix_copy (&_tmp53_, &_tmp54_);
						memset (&_tmp55_, 0, sizeof (SynapseUnitMatch));
						synapse_unit_destroy (&_tmp55_.unit);
						_tmp55_.unit = _tmp52_;
						synapse_si_prefix_destroy (&_tmp55_.prefix);
						_tmp55_.prefix = _tmp54_;
						_tmp55_.dimension = dimension1;
						_vala_array_add11 (&match_arr1, &match_arr1_length1, &_match_arr1_size_, &_tmp55_);
						synapse_si_prefix_destroy (&_tmp45_);
					}
					_tmp56_ = u;
					_tmp57_ = unit2_s;
					_tmp58_ = prefix2_s;
					_tmp60_ = synapse_converter_plugin_backend_check_match (self, &_tmp56_, _tmp57_, _tmp58_, dimension2, &_tmp59_);
					use_prefix = _tmp59_;
					if (_tmp60_) {
						SynapseSIPrefix _tmp61_ = {0};
						SynapseUnit _tmp66_;
						SynapseUnit _tmp67_;
						SynapseUnit _tmp68_ = {0};
						SynapseSIPrefix _tmp69_;
						SynapseSIPrefix _tmp70_ = {0};
						SynapseUnitMatch _tmp71_ = {0};
						if (use_prefix) {
							SynapseSIPrefix _tmp62_;
							SynapseSIPrefix _tmp63_;
							SynapseSIPrefix _tmp64_ = {0};
							_tmp62_ = prefix2;
							_tmp63_ = _tmp62_;
							synapse_si_prefix_copy (&_tmp63_, &_tmp64_);
							synapse_si_prefix_destroy (&_tmp61_);
							_tmp61_ = _tmp64_;
						} else {
							SynapseSIPrefix _tmp65_ = {0};
							synapse_si_prefix_get_default (&_tmp65_);
							synapse_si_prefix_destroy (&_tmp61_);
							_tmp61_ = _tmp65_;
						}
						_tmp66_ = u;
						_tmp67_ = _tmp66_;
						synapse_unit_copy (&_tmp67_, &_tmp68_);
						_tmp69_ = _tmp61_;
						synapse_si_prefix_copy (&_tmp69_, &_tmp70_);
						memset (&_tmp71_, 0, sizeof (SynapseUnitMatch));
						synapse_unit_destroy (&_tmp71_.unit);
						_tmp71_.unit = _tmp68_;
						synapse_si_prefix_destroy (&_tmp71_.prefix);
						_tmp71_.prefix = _tmp70_;
						_tmp71_.dimension = dimension2;
						_vala_array_add12 (&match_arr2, &match_arr2_length1, &_match_arr2_size_, &_tmp71_);
						synapse_si_prefix_destroy (&_tmp61_);
					}
					synapse_unit_destroy (&u);
				}
			}
		}
		_g_free0 (unit2_s);
		_g_free0 (unit1_s);
	}
	_tmp72_ = match_arr1;
	_tmp72__length1 = match_arr1_length1;
	_tmp73_ = match_arr2;
	_tmp73__length1 = match_arr2_length1;
	g_debug ("converter-plugin-backend.vala:140: Expect %u results", (guint) (_tmp72__length1 * _tmp73__length1));
	if (num != 0.0) {
		SynapseUnitMatch* _tmp74_;
		gint _tmp74__length1;
		_tmp74_ = match_arr1;
		_tmp74__length1 = match_arr1_length1;
		{
			SynapseUnitMatch* match1_collection = NULL;
			gint match1_collection_length1 = 0;
			gint _match1_collection_size_ = 0;
			gint match1_it = 0;
			match1_collection = _tmp74_;
			match1_collection_length1 = _tmp74__length1;
			for (match1_it = 0; match1_it < match1_collection_length1; match1_it = match1_it + 1) {
				SynapseUnitMatch _tmp75_;
				SynapseUnitMatch _tmp76_ = {0};
				SynapseUnitMatch match1 = {0};
				_tmp75_ = match1_collection[match1_it];
				synapse_unit_match_copy (&_tmp75_, &_tmp76_);
				match1 = _tmp76_;
				{
					SynapseUnitMatch* _tmp77_;
					gint _tmp77__length1;
					_tmp77_ = match_arr2;
					_tmp77__length1 = match_arr2_length1;
					{
						SynapseUnitMatch* match2_collection = NULL;
						gint match2_collection_length1 = 0;
						gint _match2_collection_size_ = 0;
						gint match2_it = 0;
						match2_collection = _tmp77_;
						match2_collection_length1 = _tmp77__length1;
						for (match2_it = 0; match2_it < match2_collection_length1; match2_it = match2_it + 1) {
							SynapseUnitMatch _tmp78_;
							SynapseUnitMatch _tmp79_ = {0};
							SynapseUnitMatch match2 = {0};
							_tmp78_ = match2_collection[match2_it];
							synapse_unit_match_copy (&_tmp78_, &_tmp79_);
							match2 = _tmp79_;
							{
								SynapseUnitMatch _tmp80_;
								SynapseUnit _tmp81_;
								SynapseUnitMatch _tmp82_;
								SynapseUnit _tmp83_;
								_tmp80_ = match1;
								_tmp81_ = _tmp80_.unit;
								_tmp82_ = match2;
								_tmp83_ = _tmp82_.unit;
								if (_tmp81_.type == _tmp83_.type) {
									gboolean _tmp84_ = FALSE;
									SynapseUnitMatch _tmp85_;
									SynapseUnit _tmp86_;
									_tmp85_ = match1;
									_tmp86_ = _tmp85_.unit;
									if (_tmp86_.type == SYNAPSE_UNIT_TYPE_DIMENSION) {
										_tmp84_ = TRUE;
									} else {
										gboolean _tmp87_ = FALSE;
										SynapseUnitMatch _tmp88_;
										_tmp88_ = match1;
										if (_tmp88_.dimension == 1) {
											SynapseUnitMatch _tmp89_;
											_tmp89_ = match2;
											_tmp87_ = _tmp89_.dimension == 1;
										} else {
											_tmp87_ = FALSE;
										}
										_tmp84_ = _tmp87_;
									}
									if (_tmp84_) {
										SynapseResultData* _result_ = NULL;
										SynapseUnitMatch _tmp90_;
										SynapseUnitMatch _tmp91_;
										SynapseResultData* _tmp92_;
										SynapseResultData* _tmp93_;
										_tmp90_ = match1;
										_tmp91_ = match2;
										_tmp92_ = synapse_converter_plugin_backend_calculate_conversion_data (self, num, &_tmp90_, &_tmp91_);
										_result_ = _tmp92_;
										_tmp93_ = _result_;
										if (_tmp93_ != NULL) {
											SynapseResultData* _tmp94_;
											SynapseResultData _tmp95_;
											SynapseResultData _tmp96_ = {0};
											_tmp94_ = _result_;
											_tmp95_ = *_tmp94_;
											synapse_result_data_copy (&_tmp95_, &_tmp96_);
											_vala_array_add13 (&results, &results_length1, &_results_size_, &_tmp96_);
										}
										_synapse_result_data_free0 (_result_);
									}
								}
								synapse_unit_match_destroy (&match2);
							}
						}
					}
					synapse_unit_match_destroy (&match1);
				}
			}
		}
	}
	_tmp97_ = results;
	_tmp97__length1 = results_length1;
	if (result_length1) {
		*result_length1 = _tmp97__length1;
	}
	result = _tmp97_;
	_g_free0 (prefix2_s);
	_g_free0 (prefix1_s);
	synapse_si_prefix_destroy (&prefix2);
	synapse_si_prefix_destroy (&prefix1);
	match_arr2 = (_vala_SynapseUnitMatch_array_free (match_arr2, match_arr2_length1), NULL);
	match_arr1 = (_vala_SynapseUnitMatch_array_free (match_arr1, match_arr1_length1), NULL);
	_g_match_info_unref0 (match_info);
	_g_free0 (input);
	return result;
}

static gpointer
_synapse_unit_dup0 (gpointer self)
{
	return self ? synapse_unit_dup (self) : NULL;
}

static gpointer
_synapse_result_data_dup0 (gpointer self)
{
	return self ? synapse_result_data_dup (self) : NULL;
}

static SynapseResultData*
synapse_converter_plugin_backend_calculate_conversion_data (SynapseConverterPluginBackend* self,
                                                            gdouble num,
                                                            SynapseUnitMatch* match1,
                                                            SynapseUnitMatch* match2)
{
	SynapseUnit u1 = {0};
	SynapseUnitMatch _tmp0_;
	SynapseUnit _tmp1_;
	SynapseUnit _tmp2_;
	SynapseUnit _tmp3_ = {0};
	SynapseUnit u2 = {0};
	SynapseUnitMatch _tmp4_;
	SynapseUnit _tmp5_;
	SynapseUnit _tmp6_;
	SynapseUnit _tmp7_ = {0};
	gint dim1 = 0;
	SynapseUnitMatch _tmp8_;
	gint dim2 = 0;
	SynapseUnitMatch _tmp9_;
	gdouble factor1 = 0.0;
	gdouble factor2 = 0.0;
	gchar* descr1 = NULL;
	gchar* _tmp10_;
	gchar* descr2 = NULL;
	gchar* _tmp11_;
	gboolean same_system = FALSE;
	SynapseUnit _tmp12_;
	SynapseUnit _tmp13_;
	SynapseUnit* parent = NULL;
	SynapseUnit _tmp14_;
	SynapseUnit _tmp15_;
	SynapseUnit* _tmp16_;
	SynapseUnit _tmp17_;
	const gchar* _tmp18_;
	SynapseUnit _tmp19_;
	SynapseUnit* _tmp20_;
	gchar* ultimate_parent1 = NULL;
	SynapseUnit* _tmp21_;
	const gchar* _tmp22_;
	gchar* _tmp23_;
	SynapseUnit _tmp24_;
	SynapseUnit _tmp25_;
	SynapseUnit* _tmp26_;
	SynapseUnit _tmp27_;
	const gchar* _tmp28_;
	SynapseUnit _tmp29_;
	gboolean _tmp30_ = FALSE;
	gboolean _tmp31_ = FALSE;
	gboolean _tmp32_ = FALSE;
	gboolean _tmp33_ = FALSE;
	SynapseUnit* _tmp34_;
	SynapseResultData* result;
	g_return_val_if_fail (self != NULL, NULL);
	g_return_val_if_fail (match1 != NULL, NULL);
	g_return_val_if_fail (match2 != NULL, NULL);
	_tmp0_ = *match1;
	_tmp1_ = _tmp0_.unit;
	_tmp2_ = _tmp1_;
	synapse_unit_copy (&_tmp2_, &_tmp3_);
	u1 = _tmp3_;
	_tmp4_ = *match2;
	_tmp5_ = _tmp4_.unit;
	_tmp6_ = _tmp5_;
	synapse_unit_copy (&_tmp6_, &_tmp7_);
	u2 = _tmp7_;
	_tmp8_ = *match1;
	dim1 = _tmp8_.dimension;
	_tmp9_ = *match2;
	dim2 = _tmp9_.dimension;
	factor1 = synapse_unit_match_factor (match1);
	factor2 = synapse_unit_match_factor (match2);
	_tmp10_ = synapse_unit_match_description (match1);
	descr1 = _tmp10_;
	_tmp11_ = synapse_unit_match_description (match2);
	descr2 = _tmp11_;
	_tmp12_ = u1;
	_tmp13_ = u2;
	same_system = _tmp12_.system == _tmp13_.system;
	_tmp14_ = u1;
	_tmp15_ = _tmp14_;
	_tmp16_ = _synapse_unit_dup0 (&_tmp15_);
	parent = _tmp16_;
	_tmp17_ = u1;
	_tmp18_ = _tmp17_.uid;
	g_debug ("converter-plugin-backend.vala:179: finding root of %s - start dimensio" \
"n %i, start factor %f", _tmp18_, dim1, factor1);
	_tmp19_ = u1;
	synapse_converter_plugin_backend_find_root (self, &parent, &dim1, &factor1, same_system, _tmp19_.system);
	_tmp20_ = parent;
	if (_tmp20_ == NULL) {
		g_debug ("converter-plugin-backend.vala:182: parent1 is null");
		result = NULL;
		_synapse_unit_free0 (parent);
		_g_free0 (descr2);
		_g_free0 (descr1);
		synapse_unit_destroy (&u2);
		synapse_unit_destroy (&u1);
		return result;
	}
	_tmp21_ = parent;
	_tmp22_ = (*_tmp21_).uid;
	_tmp23_ = g_strdup (_tmp22_);
	ultimate_parent1 = _tmp23_;
	_tmp24_ = u2;
	_tmp25_ = _tmp24_;
	_tmp26_ = _synapse_unit_dup0 (&_tmp25_);
	_synapse_unit_free0 (parent);
	parent = _tmp26_;
	_tmp27_ = u2;
	_tmp28_ = _tmp27_.uid;
	g_debug ("converter-plugin-backend.vala:188: finding root of %s - start dimensio" \
"n %i, start factor2 %f", _tmp28_, dim2, factor2);
	_tmp29_ = u2;
	synapse_converter_plugin_backend_find_root (self, &parent, &dim2, &factor2, same_system, _tmp29_.system);
	_tmp34_ = parent;
	if (_tmp34_ != NULL) {
		const gchar* _tmp35_;
		SynapseUnit* _tmp36_;
		const gchar* _tmp37_;
		_tmp35_ = ultimate_parent1;
		_tmp36_ = parent;
		_tmp37_ = (*_tmp36_).uid;
		_tmp33_ = g_strcmp0 (_tmp35_, _tmp37_) == 0;
	} else {
		_tmp33_ = FALSE;
	}
	if (_tmp33_) {
		_tmp32_ = factor1 > ((gdouble) 0);
	} else {
		_tmp32_ = FALSE;
	}
	if (_tmp32_) {
		_tmp31_ = factor2 > ((gdouble) 0);
	} else {
		_tmp31_ = FALSE;
	}
	if (_tmp31_) {
		_tmp30_ = dim1 == dim2;
	} else {
		_tmp30_ = FALSE;
	}
	if (_tmp30_) {
		gdouble d = 0.0;
		const gchar* _tmp38_;
		gchar* _tmp39_;
		const gchar* _tmp40_;
		gchar* _tmp41_;
		SynapseResultData _tmp42_ = {0};
		SynapseResultData _tmp43_;
		SynapseResultData* _tmp44_;
		SynapseResultData* _tmp45_;
		d = (num * factor1) / factor2;
		_tmp38_ = descr1;
		_tmp39_ = g_strdup (_tmp38_);
		_tmp40_ = descr2;
		_tmp41_ = g_strdup (_tmp40_);
		memset (&_tmp42_, 0, sizeof (SynapseResultData));
		_tmp42_.factor = d;
		_g_free0 (_tmp42_.from_description);
		_tmp42_.from_description = _tmp39_;
		_g_free0 (_tmp42_.to_description);
		_tmp42_.to_description = _tmp41_;
		_tmp43_ = _tmp42_;
		_tmp44_ = _synapse_result_data_dup0 (&_tmp43_);
		_tmp45_ = _tmp44_;
		synapse_result_data_destroy (&_tmp43_);
		result = _tmp45_;
		_g_free0 (ultimate_parent1);
		_synapse_unit_free0 (parent);
		_g_free0 (descr2);
		_g_free0 (descr1);
		synapse_unit_destroy (&u2);
		synapse_unit_destroy (&u1);
		return result;
	}
	result = NULL;
	_g_free0 (ultimate_parent1);
	_synapse_unit_free0 (parent);
	_g_free0 (descr2);
	_g_free0 (descr1);
	synapse_unit_destroy (&u2);
	synapse_unit_destroy (&u1);
	return result;
}

static gchar
string_get (const gchar* self,
            glong index)
{
	gchar _tmp0_;
	gchar result;
	g_return_val_if_fail (self != NULL, '\0');
	_tmp0_ = ((gchar*) self)[index];
	result = _tmp0_;
	return result;
}

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

static void
synapse_converter_plugin_backend_find_root (SynapseConverterPluginBackend* self,
                                            SynapseUnit** parent,
                                            gint* dim,
                                            gdouble* factor,
                                            gboolean same_system,
                                            SynapseUnitSystem match_unit_system)
{
	g_return_if_fail (self != NULL);
	while (TRUE) {
		gboolean _tmp0_ = FALSE;
		gboolean _tmp1_ = FALSE;
		gint link_dimension = 0;
		gchar* base_uid = NULL;
		const gchar* _tmp4_;
		gchar* _tmp5_;
		gint length = 0;
		const gchar* _tmp6_;
		gint _tmp7_;
		gint _tmp8_;
		gdouble pfactor = 0.0;
		const gchar* _tmp22_;
		if ((*parent) != NULL) {
			const gchar* _tmp2_;
			_tmp2_ = (*(*parent)).base_unit;
			_tmp1_ = g_strcmp0 (_tmp2_, "") != 0;
		} else {
			_tmp1_ = FALSE;
		}
		if (_tmp1_) {
			gboolean _tmp3_ = FALSE;
			if (!same_system) {
				_tmp3_ = TRUE;
			} else {
				_tmp3_ = (*(*parent)).system == match_unit_system;
			}
			_tmp0_ = _tmp3_;
		} else {
			_tmp0_ = FALSE;
		}
		if (!_tmp0_) {
			break;
		}
		link_dimension = 1;
		_tmp4_ = (*(*parent)).base_unit;
		_tmp5_ = g_strdup (_tmp4_);
		base_uid = _tmp5_;
		_tmp6_ = base_uid;
		_tmp7_ = strlen (_tmp6_);
		_tmp8_ = _tmp7_;
		length = _tmp8_;
		if (length > 1) {
			gchar last_c = '\0';
			const gchar* _tmp9_;
			_tmp9_ = base_uid;
			last_c = string_get (_tmp9_, (glong) (length - 1));
			if (g_ascii_isdigit (last_c)) {
				const gchar* _tmp10_;
				gchar* _tmp11_;
				const gchar* _tmp12_;
				link_dimension = g_ascii_digit_value (last_c);
				_tmp10_ = base_uid;
				_tmp11_ = string_slice (_tmp10_, (glong) 0, (glong) -1);
				_g_free0 (base_uid);
				base_uid = _tmp11_;
				_tmp12_ = base_uid;
				g_debug ("converter-plugin-backend.vala:220: Link dimension %i, base_uid %s", link_dimension, _tmp12_);
			}
		}
		_synapse_unit_free0 (*parent);
		*parent = NULL;
		{
			SynapseUnit* u_collection = NULL;
			gint u_collection_length1 = 0;
			gint _u_collection_size_ = 0;
			gint u_it = 0;
			u_collection = SYNAPSE_UNITS;
			u_collection_length1 = G_N_ELEMENTS (SYNAPSE_UNITS);
			for (u_it = 0; u_it < u_collection_length1; u_it = u_it + 1) {
				SynapseUnit _tmp13_;
				SynapseUnit _tmp14_ = {0};
				SynapseUnit u = {0};
				_tmp13_ = u_collection[u_it];
				synapse_unit_copy (&_tmp13_, &_tmp14_);
				u = _tmp14_;
				{
					SynapseUnit _tmp15_;
					const gchar* _tmp16_;
					const gchar* _tmp17_;
					_tmp15_ = u;
					_tmp16_ = _tmp15_.uid;
					_tmp17_ = base_uid;
					if (g_strcmp0 (_tmp16_, _tmp17_) == 0) {
						SynapseUnit _tmp18_;
						SynapseUnit _tmp19_;
						SynapseUnit* _tmp20_;
						_tmp18_ = u;
						_tmp19_ = _tmp18_;
						_tmp20_ = _synapse_unit_dup0 (&_tmp19_);
						_synapse_unit_free0 (*parent);
						*parent = _tmp20_;
						synapse_unit_destroy (&u);
						break;
					}
					synapse_unit_destroy (&u);
				}
			}
		}
		if ((*parent) == NULL) {
			const gchar* _tmp21_;
			_tmp21_ = base_uid;
			g_critical ("converter-plugin-backend.vala:233: Unable to find parent for %s - data" \
" error", _tmp21_);
			_g_free0 (base_uid);
			return;
		}
		pfactor = synapse_unit_get_factor (*parent);
		_tmp22_ = (*(*parent)).uid;
		g_debug ("converter-plugin-backend.vala:238: Found parent %s parent_dimension %i" \
", parent_factor %f", _tmp22_, link_dimension, pfactor);
		*dim = (*dim) * link_dimension;
		g_debug ("converter-plugin-backend.vala:243: Dim now %i", *dim);
		{
			gint i = 0;
			i = 0;
			{
				gboolean _tmp23_ = FALSE;
				_tmp23_ = TRUE;
				while (TRUE) {
					if (!_tmp23_) {
						gint _tmp24_;
						_tmp24_ = i;
						i = _tmp24_ + 1;
					}
					_tmp23_ = FALSE;
					if (!(i < (*dim))) {
						break;
					}
					*factor = (*factor) * pfactor;
				}
			}
		}
		_g_free0 (base_uid);
	}
}

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

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

static gboolean
synapse_converter_plugin_backend_check_match (SynapseConverterPluginBackend* self,
                                              SynapseUnit* u,
                                              const gchar* unit_s,
                                              const gchar* prefix,
                                              gint dimension,
                                              gboolean* use_prefix)
{
	gboolean _vala_use_prefix = FALSE;
	gchar** ids = NULL;
	SynapseUnit _tmp0_;
	const gchar* _tmp1_;
	gchar* _tmp2_;
	gchar** _tmp3_;
	gint ids_length1;
	gint _ids_size_;
	gchar** abbreviations = NULL;
	SynapseUnit _tmp4_;
	const gchar* _tmp5_;
	gchar** _tmp6_;
	gchar** _tmp7_;
	gint abbreviations_length1;
	gint _abbreviations_size_;
	gchar** _tmp8_;
	gint _tmp8__length1;
	SynapseUnit _tmp12_;
	const gchar* _tmp13_;
	gchar* _tmp14_;
	gchar* match = NULL;
	gchar* _tmp15_;
	gchar* match_no_prefix = NULL;
	const gchar* _tmp16_;
	gint _tmp17_;
	gint _tmp18_;
	const gchar* _tmp19_;
	gint _tmp20_;
	gint _tmp21_;
	gchar* _tmp22_;
	const gchar* _tmp23_;
	const gchar* _tmp24_;
	gchar** _tmp25_;
	gint _tmp25__length1;
	gboolean result;
	g_return_val_if_fail (self != NULL, FALSE);
	g_return_val_if_fail (u != NULL, FALSE);
	g_return_val_if_fail (unit_s != NULL, FALSE);
	g_return_val_if_fail (prefix != NULL, FALSE);
	_vala_use_prefix = FALSE;
	_tmp0_ = *u;
	_tmp1_ = _tmp0_.uid;
	_tmp2_ = g_strdup (_tmp1_);
	_tmp3_ = g_new0 (gchar*, 1 + 1);
	_tmp3_[0] = _tmp2_;
	ids = _tmp3_;
	ids_length1 = 1;
	_ids_size_ = ids_length1;
	_tmp4_ = *u;
	_tmp5_ = _tmp4_.abbreviations;
	_tmp7_ = _tmp6_ = g_strsplit (_tmp5_, "|", 0);
	abbreviations = _tmp7_;
	abbreviations_length1 = _vala_array_length (_tmp6_);
	_abbreviations_size_ = abbreviations_length1;
	_tmp8_ = abbreviations;
	_tmp8__length1 = abbreviations_length1;
	{
		gchar** s_collection = NULL;
		gint s_collection_length1 = 0;
		gint _s_collection_size_ = 0;
		gint s_it = 0;
		s_collection = _tmp8_;
		s_collection_length1 = _tmp8__length1;
		for (s_it = 0; s_it < s_collection_length1; s_it = s_it + 1) {
			gchar* _tmp9_;
			gchar* s = NULL;
			_tmp9_ = g_strdup (s_collection[s_it]);
			s = _tmp9_;
			{
				const gchar* _tmp10_;
				gchar* _tmp11_;
				_tmp10_ = s;
				_tmp11_ = g_strdup (_tmp10_);
				_vala_array_add14 (&ids, &ids_length1, &_ids_size_, _tmp11_);
				_g_free0 (s);
			}
		}
	}
	_tmp12_ = *u;
	_tmp13_ = _tmp12_.description;
	_tmp14_ = g_utf8_strdown (_ (_tmp13_), (gssize) -1);
	_vala_array_add15 (&ids, &ids_length1, &_ids_size_, _tmp14_);
	_tmp15_ = g_utf8_strdown (unit_s, (gssize) -1);
	match = _tmp15_;
	_tmp16_ = match;
	_tmp17_ = strlen (prefix);
	_tmp18_ = _tmp17_;
	_tmp19_ = match;
	_tmp20_ = strlen (_tmp19_);
	_tmp21_ = _tmp20_;
	_tmp22_ = string_slice (_tmp16_, (glong) _tmp18_, (glong) _tmp21_);
	match_no_prefix = _tmp22_;
	_tmp23_ = match;
	_tmp24_ = match_no_prefix;
	g_debug ("converter-plugin-backend.vala:268: match %s, match no prefix %s", _tmp23_, _tmp24_);
	_tmp25_ = ids;
	_tmp25__length1 = ids_length1;
	{
		gchar** id_collection = NULL;
		gint id_collection_length1 = 0;
		gint _id_collection_size_ = 0;
		gint id_it = 0;
		id_collection = _tmp25_;
		id_collection_length1 = _tmp25__length1;
		for (id_it = 0; id_it < id_collection_length1; id_it = id_it + 1) {
			gchar* _tmp26_;
			gchar* id = NULL;
			_tmp26_ = g_strdup (id_collection[id_it]);
			id = _tmp26_;
			{
				const gchar* _tmp27_;
				const gchar* _tmp28_;
				_tmp27_ = match;
				_tmp28_ = id;
				if (g_strcmp0 (_tmp27_, _tmp28_) == 0) {
					const gchar* _tmp29_;
					_tmp29_ = id;
					g_debug ("converter-plugin-backend.vala:271: unit less dimension (if any) matche" \
"s %s", _tmp29_);
					result = TRUE;
					_g_free0 (id);
					_g_free0 (match_no_prefix);
					_g_free0 (match);
					abbreviations = (_vala_array_free (abbreviations, abbreviations_length1, (GDestroyNotify) g_free), NULL);
					ids = (_vala_array_free (ids, ids_length1, (GDestroyNotify) g_free), NULL);
					if (use_prefix) {
						*use_prefix = _vala_use_prefix;
					}
					return result;
				} else {
					const gchar* _tmp30_;
					const gchar* _tmp31_;
					_tmp30_ = match_no_prefix;
					_tmp31_ = id;
					if (g_strcmp0 (_tmp30_, _tmp31_) == 0) {
						const gchar* _tmp32_;
						_tmp32_ = id;
						g_debug ("converter-plugin-backend.vala:274: unit less dimension (if any) and le" \
"ss prefix matches %s", _tmp32_);
						_vala_use_prefix = TRUE;
						result = TRUE;
						_g_free0 (id);
						_g_free0 (match_no_prefix);
						_g_free0 (match);
						abbreviations = (_vala_array_free (abbreviations, abbreviations_length1, (GDestroyNotify) g_free), NULL);
						ids = (_vala_array_free (ids, ids_length1, (GDestroyNotify) g_free), NULL);
						if (use_prefix) {
							*use_prefix = _vala_use_prefix;
						}
						return result;
					}
				}
				_g_free0 (id);
			}
		}
	}
	result = FALSE;
	_g_free0 (match_no_prefix);
	_g_free0 (match);
	abbreviations = (_vala_array_free (abbreviations, abbreviations_length1, (GDestroyNotify) g_free), NULL);
	ids = (_vala_array_free (ids, ids_length1, (GDestroyNotify) g_free), NULL);
	if (use_prefix) {
		*use_prefix = _vala_use_prefix;
	}
	return result;
}

static void
synapse_converter_plugin_backend_get_prefix (SynapseConverterPluginBackend* self,
                                             const gchar* unit_s,
                                             gchar** prefix_s,
                                             SynapseSIPrefix* prefix)
{
	gchar* _vala_prefix_s = NULL;
	SynapseSIPrefix _vala_prefix = {0};
	SynapseSIPrefix _tmp0_ = {0};
	gchar* _tmp1_;
	gint length = 0;
	gint _tmp2_;
	gint _tmp3_;
	g_return_if_fail (self != NULL);
	g_return_if_fail (unit_s != NULL);
	synapse_si_prefix_get_default (&_tmp0_);
	synapse_si_prefix_destroy (&_vala_prefix);
	_vala_prefix = _tmp0_;
	_tmp1_ = g_strdup ("");
	_g_free0 (_vala_prefix_s);
	_vala_prefix_s = _tmp1_;
	_tmp2_ = strlen (unit_s);
	_tmp3_ = _tmp2_;
	length = _tmp3_;
	{
		SynapseSIPrefix* p_collection = NULL;
		gint p_collection_length1 = 0;
		gint _p_collection_size_ = 0;
		gint p_it = 0;
		p_collection = SYNAPSE_PREFIXES;
		p_collection_length1 = G_N_ELEMENTS (SYNAPSE_PREFIXES);
		for (p_it = 0; p_it < p_collection_length1; p_it = p_it + 1) {
			SynapseSIPrefix _tmp4_;
			SynapseSIPrefix _tmp5_ = {0};
			SynapseSIPrefix p = {0};
			_tmp4_ = p_collection[p_it];
			synapse_si_prefix_copy (&_tmp4_, &_tmp5_);
			p = _tmp5_;
			{
				gboolean _tmp6_ = FALSE;
				SynapseSIPrefix _tmp7_;
				const gchar* _tmp8_;
				gint _tmp9_;
				gint _tmp10_;
				_tmp7_ = p;
				_tmp8_ = _tmp7_.prefix;
				_tmp9_ = strlen (_tmp8_);
				_tmp10_ = _tmp9_;
				if (length > _tmp10_) {
					SynapseSIPrefix _tmp11_;
					const gchar* _tmp12_;
					_tmp11_ = p;
					_tmp12_ = _tmp11_.prefix;
					_tmp6_ = g_str_has_prefix (unit_s, _tmp12_);
				} else {
					_tmp6_ = FALSE;
				}
				if (_tmp6_) {
					SynapseSIPrefix _tmp13_;
					const gchar* _tmp14_;
					gchar* _tmp15_;
					SynapseSIPrefix _tmp16_;
					SynapseSIPrefix _tmp17_;
					SynapseSIPrefix _tmp18_ = {0};
					_tmp13_ = p;
					_tmp14_ = _tmp13_.prefix;
					_tmp15_ = g_strdup (_tmp14_);
					_g_free0 (_vala_prefix_s);
					_vala_prefix_s = _tmp15_;
					_tmp16_ = p;
					_tmp17_ = _tmp16_;
					synapse_si_prefix_copy (&_tmp17_, &_tmp18_);
					synapse_si_prefix_destroy (&_vala_prefix);
					_vala_prefix = _tmp18_;
					synapse_si_prefix_destroy (&p);
					break;
				} else {
					gboolean _tmp19_ = FALSE;
					SynapseSIPrefix _tmp20_;
					const gchar* _tmp21_;
					gint _tmp22_;
					gint _tmp23_;
					_tmp20_ = p;
					_tmp21_ = _tmp20_.abbrev;
					_tmp22_ = strlen (_tmp21_);
					_tmp23_ = _tmp22_;
					if (length > _tmp23_) {
						SynapseSIPrefix _tmp24_;
						const gchar* _tmp25_;
						_tmp24_ = p;
						_tmp25_ = _tmp24_.abbrev;
						_tmp19_ = g_str_has_prefix (unit_s, _tmp25_);
					} else {
						_tmp19_ = FALSE;
					}
					if (_tmp19_) {
						SynapseSIPrefix _tmp26_;
						const gchar* _tmp27_;
						gchar* _tmp28_;
						SynapseSIPrefix _tmp29_;
						SynapseSIPrefix _tmp30_;
						SynapseSIPrefix _tmp31_ = {0};
						_tmp26_ = p;
						_tmp27_ = _tmp26_.abbrev;
						_tmp28_ = g_strdup (_tmp27_);
						_g_free0 (_vala_prefix_s);
						_vala_prefix_s = _tmp28_;
						_tmp29_ = p;
						_tmp30_ = _tmp29_;
						synapse_si_prefix_copy (&_tmp30_, &_tmp31_);
						synapse_si_prefix_destroy (&_vala_prefix);
						_vala_prefix = _tmp31_;
						synapse_si_prefix_destroy (&p);
						break;
					}
				}
				synapse_si_prefix_destroy (&p);
			}
		}
	}
	if (prefix_s) {
		*prefix_s = _vala_prefix_s;
	} else {
		_g_free0 (_vala_prefix_s);
	}
	if (prefix) {
		*prefix = _vala_prefix;
	} else {
		synapse_si_prefix_destroy (&_vala_prefix);
	}
}

SynapseConverterPluginBackend*
synapse_converter_plugin_backend_construct (GType object_type)
{
	SynapseConverterPluginBackend * self = NULL;
	self = (SynapseConverterPluginBackend*) g_object_new (object_type, NULL);
	return self;
}

SynapseConverterPluginBackend*
synapse_converter_plugin_backend_new (void)
{
	return synapse_converter_plugin_backend_construct (SYNAPSE_TYPE_CONVERTER_PLUGIN_BACKEND);
}

static GObject *
synapse_converter_plugin_backend_constructor (GType type,
                                              guint n_construct_properties,
                                              GObjectConstructParam * construct_properties)
{
	GObject * obj;
	GObjectClass * parent_class;
	SynapseConverterPluginBackend * self;
	GError* _inner_error0_ = NULL;
	parent_class = G_OBJECT_CLASS (synapse_converter_plugin_backend_parent_class);
	obj = parent_class->constructor (type, n_construct_properties, construct_properties);
	self = G_TYPE_CHECK_INSTANCE_CAST (obj, SYNAPSE_TYPE_CONVERTER_PLUGIN_BACKEND, SynapseConverterPluginBackend);
	{
		GRegex* _tmp0_ = NULL;
		GRegex* _tmp1_;
		GRegex* _tmp2_;
		_tmp1_ = g_regex_new ("^([[:digit:]]*\\.?[[:digit:]]*)\\s*([[:alpha:]\\/ ]+?)([23]?)\\s*[=\\-" \
"]>\\s*([[:alpha:]\\/ ]+?)([23]?)$", G_REGEX_OPTIMIZE, 0, &_inner_error0_);
		_tmp0_ = _tmp1_;
		if (G_UNLIKELY (_inner_error0_ != NULL)) {
			goto __catch0_g_error;
		}
		_tmp2_ = _tmp0_;
		_tmp0_ = NULL;
		_g_regex_unref0 (self->priv->convert_regex);
		self->priv->convert_regex = _tmp2_;
		_g_regex_unref0 (_tmp0_);
	}
	goto __finally0;
	__catch0_g_error:
	{
		GError* e = NULL;
		GError* _tmp3_;
		const gchar* _tmp4_;
		e = _inner_error0_;
		_inner_error0_ = NULL;
		_tmp3_ = e;
		_tmp4_ = _tmp3_->message;
		g_critical ("converter-plugin-backend.vala:84: Error creating regexp: %s", _tmp4_);
		_g_error_free0 (e);
	}
	__finally0:
	if (G_UNLIKELY (_inner_error0_ != 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 obj;
}

static void
synapse_converter_plugin_backend_class_init (SynapseConverterPluginBackendClass * klass,
                                             gpointer klass_data)
{
	synapse_converter_plugin_backend_parent_class = g_type_class_peek_parent (klass);
	g_type_class_adjust_private_offset (klass, &SynapseConverterPluginBackend_private_offset);
	G_OBJECT_CLASS (klass)->constructor = synapse_converter_plugin_backend_constructor;
	G_OBJECT_CLASS (klass)->finalize = synapse_converter_plugin_backend_finalize;
}

static void
synapse_converter_plugin_backend_instance_init (SynapseConverterPluginBackend * self,
                                                gpointer klass)
{
	self->priv = synapse_converter_plugin_backend_get_instance_private (self);
	self->priv->convert_regex = NULL;
}

static void
synapse_converter_plugin_backend_finalize (GObject * obj)
{
	SynapseConverterPluginBackend * self;
	self = G_TYPE_CHECK_INSTANCE_CAST (obj, SYNAPSE_TYPE_CONVERTER_PLUGIN_BACKEND, SynapseConverterPluginBackend);
	_g_regex_unref0 (self->priv->convert_regex);
	G_OBJECT_CLASS (synapse_converter_plugin_backend_parent_class)->finalize (obj);
}

static GType
synapse_converter_plugin_backend_get_type_once (void)
{
	static const GTypeInfo g_define_type_info = { sizeof (SynapseConverterPluginBackendClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) synapse_converter_plugin_backend_class_init, (GClassFinalizeFunc) NULL, NULL, sizeof (SynapseConverterPluginBackend), 0, (GInstanceInitFunc) synapse_converter_plugin_backend_instance_init, NULL };
	GType synapse_converter_plugin_backend_type_id;
	synapse_converter_plugin_backend_type_id = g_type_register_static (G_TYPE_OBJECT, "SynapseConverterPluginBackend", &g_define_type_info, 0);
	SynapseConverterPluginBackend_private_offset = g_type_add_instance_private (synapse_converter_plugin_backend_type_id, sizeof (SynapseConverterPluginBackendPrivate));
	return synapse_converter_plugin_backend_type_id;
}

GType
synapse_converter_plugin_backend_get_type (void)
{
	static volatile gsize synapse_converter_plugin_backend_type_id__once = 0;
	if (g_once_init_enter (&synapse_converter_plugin_backend_type_id__once)) {
		GType synapse_converter_plugin_backend_type_id;
		synapse_converter_plugin_backend_type_id = synapse_converter_plugin_backend_get_type_once ();
		g_once_init_leave (&synapse_converter_plugin_backend_type_id__once, synapse_converter_plugin_backend_type_id);
	}
	return synapse_converter_plugin_backend_type_id__once;
}

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

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

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

