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

/* timsort.vala
 *
 * Copyright (C) 2009  Didier Villevalois
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.

 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.

 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301  USA
 *
 * Author:
 * 	Didier 'Ptitjes Villevalois <ptitjes@free.fr>
 */

#include <glib-object.h>
#include "valagee.h"
#include <glib.h>
#include <string.h>
#include <gobject/gvaluecollector.h>

#define VALA_TIM_SORT_MINIMUM_GALLOP 7

#define VALA_TYPE_TIM_SORT (vala_tim_sort_get_type ())
#define VALA_TIM_SORT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), VALA_TYPE_TIM_SORT, ValaTimSort))
#define VALA_TIM_SORT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), VALA_TYPE_TIM_SORT, ValaTimSortClass))
#define VALA_IS_TIM_SORT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), VALA_TYPE_TIM_SORT))
#define VALA_IS_TIM_SORT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), VALA_TYPE_TIM_SORT))
#define VALA_TIM_SORT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), VALA_TYPE_TIM_SORT, ValaTimSortClass))

typedef struct _ValaTimSort ValaTimSort;
typedef struct _ValaTimSortClass ValaTimSortClass;
typedef struct _ValaTimSortPrivate ValaTimSortPrivate;
typedef struct _ValaTimSortSlice ValaTimSortSlice;
#define _vala_iterable_unref0(var) ((var == NULL) ? NULL : (var = (vala_iterable_unref (var), NULL)))
#define _vala_tim_sort_unref0(var) ((var == NULL) ? NULL : (var = (vala_tim_sort_unref (var), NULL)))
#define _vala_tim_sort_slice_free0(var) ((var == NULL) ? NULL : (var = (vala_tim_sort_slice_free (var), NULL)))
typedef gboolean (*ValaTimSortLowerFunc) (gconstpointer left, gconstpointer right, gpointer user_data);
typedef struct _ValaParamSpecTimSort ValaParamSpecTimSort;
#define _vala_assert(expr, msg) if G_LIKELY (expr) ; else g_assertion_message_expr (G_LOG_DOMAIN, __FILE__, __LINE__, G_STRFUNC, msg);
#define _vala_return_if_fail(expr, msg) if G_LIKELY (expr) ; else { g_return_if_fail_warning (G_LOG_DOMAIN, G_STRFUNC, msg); return; }
#define _vala_return_val_if_fail(expr, msg, val) if G_LIKELY (expr) ; else { g_return_if_fail_warning (G_LOG_DOMAIN, G_STRFUNC, msg); return val; }
#define _vala_warn_if_fail(expr, msg) if G_LIKELY (expr) ; else g_warn_message (G_LOG_DOMAIN, __FILE__, __LINE__, G_STRFUNC, msg);

struct _ValaTimSort {
	GTypeInstance parent_instance;
	volatile int ref_count;
	ValaTimSortPrivate * priv;
};

struct _ValaTimSortClass {
	GTypeClass parent_class;
	void (*finalize) (ValaTimSort *self);
};

struct _ValaTimSortPrivate {
	GType g_type;
	GBoxedCopyFunc g_dup_func;
	GDestroyNotify g_destroy_func;
	ValaList* list_collection;
	gpointer* array;
	gint array_length1;
	gint _array_size_;
	void** list;
	gint index;
	gint size;
	ValaTimSortSlice** pending;
	gint pending_length1;
	gint _pending_size_;
	gint minimum_gallop;
	GCompareDataFunc compare;
	gpointer compare_target;
};

struct _ValaTimSortSlice {
	void** list;
	void** new_list;
	gint index;
	gint length;
};

struct _ValaParamSpecTimSort {
	GParamSpec parent_instance;
};

static gint ValaTimSort_private_offset;
static gpointer vala_tim_sort_parent_class = NULL;

 G_GNUC_INTERNAL gpointer vala_tim_sort_ref (gpointer instance);
 G_GNUC_INTERNAL void vala_tim_sort_unref (gpointer instance);
 G_GNUC_INTERNAL GParamSpec* vala_param_spec_tim_sort (const gchar* name,
                                      const gchar* nick,
                                      const gchar* blurb,
                                      GType object_type,
                                      GParamFlags flags);
 G_GNUC_INTERNAL void vala_value_set_tim_sort (GValue* value,
                              gpointer v_object) G_GNUC_UNUSED ;
 G_GNUC_INTERNAL void vala_value_take_tim_sort (GValue* value,
                               gpointer v_object);
 G_GNUC_INTERNAL gpointer vala_value_get_tim_sort (const GValue* value) G_GNUC_UNUSED ;
 G_GNUC_INTERNAL GType vala_tim_sort_get_type (void) G_GNUC_CONST  G_GNUC_UNUSED ;
static void vala_tim_sort_slice_free (ValaTimSortSlice * self);
 G_GNUC_INTERNAL void vala_tim_sort_sort (GType g_type,
                         GBoxedCopyFunc g_dup_func,
                         GDestroyNotify g_destroy_func,
                         ValaList* list,
                         GCompareDataFunc compare,
                         gpointer compare_target);
static void vala_tim_sort_sort_arraylist (GType g_type,
                                   GBoxedCopyFunc g_dup_func,
                                   GDestroyNotify g_destroy_func,
                                   ValaArrayList* list,
                                   GCompareDataFunc compare,
                                   gpointer compare_target);
static void vala_tim_sort_sort_list (GType g_type,
                              GBoxedCopyFunc g_dup_func,
                              GDestroyNotify g_destroy_func,
                              ValaList* list,
                              GCompareDataFunc compare,
                              gpointer compare_target);
 G_GNUC_INTERNAL ValaTimSort* vala_tim_sort_new (GType g_type,
                                GBoxedCopyFunc g_dup_func,
                                GDestroyNotify g_destroy_func);
 G_GNUC_INTERNAL ValaTimSort* vala_tim_sort_construct (GType object_type,
                                      GType g_type,
                                      GBoxedCopyFunc g_dup_func,
                                      GDestroyNotify g_destroy_func);
static void vala_tim_sort_do_sort (ValaTimSort* self);
static ValaTimSortSlice* vala_tim_sort_slice_new (void** list,
                                           gint index,
                                           gint length);
static gint vala_tim_sort_compute_minimum_run_length (ValaTimSort* self,
                                               gint length);
static ValaTimSortSlice* vala_tim_sort_compute_longest_run (ValaTimSort* self,
                                                     ValaTimSortSlice* a,
                                                     gboolean* descending);
static void vala_tim_sort_slice_reverse (ValaTimSortSlice* self);
static void vala_tim_sort_insertion_sort (ValaTimSort* self,
                                   ValaTimSortSlice* a,
                                   gint offset);
static inline void vala_tim_sort_slice_shorten_start (ValaTimSortSlice* self,
                                        gint n);
static void _vala_array_add1 (ValaTimSortSlice** * array,
                       gint* length,
                       gint* size,
                       ValaTimSortSlice* value);
static void vala_tim_sort_merge_collapse (ValaTimSort* self);
static void vala_tim_sort_merge_force_collapse (ValaTimSort* self);
static inline gboolean vala_tim_sort_lower_than (ValaTimSort* self,
                                   gconstpointer left,
                                   gconstpointer right);
static inline gboolean vala_tim_sort_lower_than_or_equal_to (ValaTimSort* self,
                                               gconstpointer left,
                                               gconstpointer right);
static void vala_tim_sort_merge_at (ValaTimSort* self,
                             gint index);
static gint vala_tim_sort_gallop_rightmost (ValaTimSort* self,
                                     gconstpointer key,
                                     ValaTimSortSlice* a,
                                     gint hint);
static inline void* vala_tim_sort_slice_peek_first (ValaTimSortSlice* self);
static gint vala_tim_sort_gallop_leftmost (ValaTimSort* self,
                                    gconstpointer key,
                                    ValaTimSortSlice* a,
                                    gint hint);
static inline void* vala_tim_sort_slice_peek_last (ValaTimSortSlice* self);
static void vala_tim_sort_merge_low (ValaTimSort* self,
                              ValaTimSortSlice* a,
                              ValaTimSortSlice* b);
static void vala_tim_sort_merge_high (ValaTimSort* self,
                               ValaTimSortSlice* a,
                               ValaTimSortSlice* b);
static void vala_tim_sort_slice_copy (ValaTimSortSlice* self);
static inline void* vala_tim_sort_slice_pop_first (ValaTimSortSlice* self);
static inline void vala_tim_sort_slice_merge_in (ValaTimSortSlice* self,
                                   void** dest_array,
                                   gint index,
                                   gint dest_index,
                                   gint count);
static inline void* vala_tim_sort_slice_pop_last (ValaTimSortSlice* self);
static inline void vala_tim_sort_slice_merge_in_reversed (ValaTimSortSlice* self,
                                            void** dest_array,
                                            gint index,
                                            gint dest_index,
                                            gint count);
static inline void vala_tim_sort_slice_shorten_end (ValaTimSortSlice* self,
                                      gint n);
static void vala_tim_sort_slice_instance_init (ValaTimSortSlice * self);
static inline void vala_tim_sort_slice_swap (ValaTimSortSlice* self,
                               gint i,
                               gint j);
static void vala_tim_sort_finalize (ValaTimSort * obj);
static GType vala_tim_sort_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 void _vala_array_move (gpointer array,
                       gsize element_size,
                       gssize src,
                       gssize dest,
                       gssize length);

static inline gpointer
vala_tim_sort_get_instance_private (ValaTimSort* self)
{
	return G_STRUCT_MEMBER_P (self, ValaTimSort_private_offset);
}

 G_GNUC_INTERNAL void
vala_tim_sort_sort (GType g_type,
                    GBoxedCopyFunc g_dup_func,
                    GDestroyNotify g_destroy_func,
                    ValaList* list,
                    GCompareDataFunc compare,
                    gpointer compare_target)
{
	g_return_if_fail (list != NULL);
	if (VALA_IS_ARRAY_LIST (list)) {
		vala_tim_sort_sort_arraylist (g_type, (GBoxedCopyFunc) g_dup_func, (GDestroyNotify) g_destroy_func, G_TYPE_CHECK_INSTANCE_CAST (list, VALA_TYPE_ARRAY_LIST, ValaArrayList), compare, compare_target);
	} else {
		vala_tim_sort_sort_list (g_type, (GBoxedCopyFunc) g_dup_func, (GDestroyNotify) g_destroy_func, list, compare, compare_target);
	}
}

static gpointer
_vala_iterable_ref0 (gpointer self)
{
	return self ? vala_iterable_ref (self) : NULL;
}

static void
vala_tim_sort_sort_list (GType g_type,
                         GBoxedCopyFunc g_dup_func,
                         GDestroyNotify g_destroy_func,
                         ValaList* list,
                         GCompareDataFunc compare,
                         gpointer compare_target)
{
	ValaTimSort* helper = NULL;
	ValaTimSort* _tmp0_;
	ValaTimSort* _tmp1_;
	ValaList* _tmp2_;
	ValaTimSort* _tmp3_;
	gint _tmp4_ = 0;
	gpointer* _tmp5_;
	ValaTimSort* _tmp6_;
	ValaTimSort* _tmp7_;
	gpointer* _tmp8_;
	gint _tmp8__length1;
	ValaTimSort* _tmp9_;
	ValaTimSort* _tmp10_;
	gint _tmp11_;
	gint _tmp12_;
	ValaTimSort* _tmp13_;
	ValaTimSort* _tmp14_;
	ValaTimSort* _tmp15_;
	gpointer* _tmp16_;
	gint _tmp16__length1;
	g_return_if_fail (list != NULL);
	_tmp0_ = vala_tim_sort_new (g_type, (GBoxedCopyFunc) g_dup_func, (GDestroyNotify) g_destroy_func);
	helper = _tmp0_;
	_tmp1_ = helper;
	_tmp2_ = _vala_iterable_ref0 (list);
	_vala_iterable_unref0 (_tmp1_->priv->list_collection);
	_tmp1_->priv->list_collection = _tmp2_;
	_tmp3_ = helper;
	_tmp5_ = vala_collection_to_array ((ValaCollection*) list, &_tmp4_);
	_tmp3_->priv->array = (_vala_array_free (_tmp3_->priv->array, _tmp3_->priv->array_length1, (GDestroyNotify) g_destroy_func), NULL);
	_tmp3_->priv->array = _tmp5_;
	_tmp3_->priv->array_length1 = _tmp4_;
	_tmp3_->priv->_array_size_ = _tmp3_->priv->array_length1;
	_tmp6_ = helper;
	_tmp7_ = helper;
	_tmp8_ = _tmp7_->priv->array;
	_tmp8__length1 = _tmp7_->priv->array_length1;
	_tmp6_->priv->list = _tmp8_;
	_tmp9_ = helper;
	_tmp9_->priv->index = 0;
	_tmp10_ = helper;
	_tmp11_ = vala_collection_get_size ((ValaCollection*) list);
	_tmp12_ = _tmp11_;
	_tmp10_->priv->size = _tmp12_;
	_tmp13_ = helper;
	_tmp13_->priv->compare = compare;
	_tmp13_->priv->compare_target = compare_target;
	_tmp14_ = helper;
	vala_tim_sort_do_sort (_tmp14_);
	vala_collection_clear ((ValaCollection*) list);
	_tmp15_ = helper;
	_tmp16_ = _tmp15_->priv->array;
	_tmp16__length1 = _tmp15_->priv->array_length1;
	{
		gpointer* item_collection = NULL;
		gint item_collection_length1 = 0;
		gint _item_collection_size_ = 0;
		gint item_it = 0;
		item_collection = _tmp16_;
		item_collection_length1 = _tmp16__length1;
		for (item_it = 0; item_it < item_collection_length1; item_it = item_it + 1) {
			gpointer _tmp17_;
			gpointer item = NULL;
			_tmp17_ = ((item_collection[item_it] != NULL) && (g_dup_func != NULL)) ? g_dup_func ((gpointer) item_collection[item_it]) : ((gpointer) item_collection[item_it]);
			item = _tmp17_;
			{
				gconstpointer _tmp18_;
				_tmp18_ = item;
				vala_collection_add ((ValaCollection*) list, _tmp18_);
				((item == NULL) || (g_destroy_func == NULL)) ? NULL : (item = (g_destroy_func (item), NULL));
			}
		}
	}
	_vala_tim_sort_unref0 (helper);
}

static void
vala_tim_sort_sort_arraylist (GType g_type,
                              GBoxedCopyFunc g_dup_func,
                              GDestroyNotify g_destroy_func,
                              ValaArrayList* list,
                              GCompareDataFunc compare,
                              gpointer compare_target)
{
	ValaTimSort* helper = NULL;
	ValaTimSort* _tmp0_;
	ValaList* _tmp1_;
	gpointer* _tmp2_;
	gint _tmp2__length1;
	g_return_if_fail (list != NULL);
	_tmp0_ = vala_tim_sort_new (g_type, (GBoxedCopyFunc) g_dup_func, (GDestroyNotify) g_destroy_func);
	helper = _tmp0_;
	_tmp1_ = _vala_iterable_ref0 ((ValaList*) list);
	_vala_iterable_unref0 (helper->priv->list_collection);
	helper->priv->list_collection = _tmp1_;
	_tmp2_ = list->_items;
	_tmp2__length1 = list->_items_length1;
	helper->priv->list = _tmp2_;
	helper->priv->index = 0;
	helper->priv->size = list->_size;
	helper->priv->compare = compare;
	helper->priv->compare_target = compare_target;
	vala_tim_sort_do_sort (helper);
	_vala_tim_sort_unref0 (helper);
}

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

static void
vala_tim_sort_do_sort (ValaTimSort* self)
{
	ValaTimSortSlice** _tmp0_;
	ValaTimSortSlice* remaining = NULL;
	void** _tmp1_;
	ValaTimSortSlice* _tmp2_;
	gint minimum_length = 0;
	ValaTimSortSlice* _tmp3_;
	ValaTimSortSlice* _tmp17_;
	ValaTimSortSlice** _tmp18_;
	gint _tmp18__length1;
	ValaTimSortSlice** _tmp19_;
	gint _tmp19__length1;
	ValaTimSortSlice* _tmp20_;
	ValaTimSortSlice** _tmp21_;
	gint _tmp21__length1;
	ValaTimSortSlice* _tmp22_;
	g_return_if_fail (self != NULL);
	if (self->priv->size < 2) {
		return;
	}
	_tmp0_ = g_new0 (ValaTimSortSlice*, 0 + 1);
	self->priv->pending = (_vala_array_free (self->priv->pending, self->priv->pending_length1, (GDestroyNotify) vala_tim_sort_slice_free), NULL);
	self->priv->pending = _tmp0_;
	self->priv->pending_length1 = 0;
	self->priv->_pending_size_ = self->priv->pending_length1;
	self->priv->minimum_gallop = VALA_TIM_SORT_MINIMUM_GALLOP;
	_tmp1_ = self->priv->list;
	_tmp2_ = vala_tim_sort_slice_new (_tmp1_, self->priv->index, self->priv->size);
	remaining = _tmp2_;
	_tmp3_ = remaining;
	minimum_length = vala_tim_sort_compute_minimum_run_length (self, _tmp3_->length);
	while (TRUE) {
		ValaTimSortSlice* _tmp4_;
		gboolean descending = FALSE;
		ValaTimSortSlice* run = NULL;
		ValaTimSortSlice* _tmp5_;
		gboolean _tmp6_ = FALSE;
		ValaTimSortSlice* _tmp7_;
		ValaTimSortSlice* _tmp9_;
		ValaTimSortSlice* _tmp14_;
		ValaTimSortSlice* _tmp15_;
		ValaTimSortSlice* _tmp16_;
		_tmp4_ = remaining;
		if (!(_tmp4_->length > 0)) {
			break;
		}
		_tmp5_ = remaining;
		_tmp7_ = vala_tim_sort_compute_longest_run (self, _tmp5_, &_tmp6_);
		descending = _tmp6_;
		run = _tmp7_;
		if (descending) {
			ValaTimSortSlice* _tmp8_;
			_tmp8_ = run;
			vala_tim_sort_slice_reverse (_tmp8_);
		}
		_tmp9_ = run;
		if (_tmp9_->length < minimum_length) {
			gint sorted_count = 0;
			ValaTimSortSlice* _tmp10_;
			ValaTimSortSlice* _tmp11_;
			ValaTimSortSlice* _tmp12_;
			ValaTimSortSlice* _tmp13_;
			_tmp10_ = run;
			sorted_count = _tmp10_->length;
			_tmp11_ = run;
			_tmp12_ = remaining;
			_tmp11_->length = MIN (minimum_length, _tmp12_->length);
			_tmp13_ = run;
			vala_tim_sort_insertion_sort (self, _tmp13_, sorted_count);
		}
		_tmp14_ = remaining;
		_tmp15_ = run;
		vala_tim_sort_slice_shorten_start (_tmp14_, _tmp15_->length);
		_tmp16_ = run;
		run = NULL;
		_vala_array_add1 (&self->priv->pending, &self->priv->pending_length1, &self->priv->_pending_size_, _tmp16_);
		vala_tim_sort_merge_collapse (self);
		_vala_tim_sort_slice_free0 (run);
	}
	_tmp17_ = remaining;
	_vala_assert (_tmp17_->index == self->priv->size, "remaining.index == size");
	vala_tim_sort_merge_force_collapse (self);
	_tmp18_ = self->priv->pending;
	_tmp18__length1 = self->priv->pending_length1;
	_vala_assert (_tmp18__length1 == 1, "pending.length == 1");
	_tmp19_ = self->priv->pending;
	_tmp19__length1 = self->priv->pending_length1;
	_tmp20_ = _tmp19_[0];
	_vala_assert (_tmp20_->index == 0, "pending[0].index == 0");
	_tmp21_ = self->priv->pending;
	_tmp21__length1 = self->priv->pending_length1;
	_tmp22_ = _tmp21_[0];
	_vala_assert (_tmp22_->length == self->priv->size, "pending[0].length == size");
	_vala_tim_sort_slice_free0 (remaining);
}

static inline gboolean
vala_tim_sort_lower_than (ValaTimSort* self,
                          gconstpointer left,
                          gconstpointer right)
{
	GCompareDataFunc _tmp0_;
	gpointer _tmp0__target;
	gboolean result;
	g_return_val_if_fail (self != NULL, FALSE);
	_tmp0_ = self->priv->compare;
	_tmp0__target = self->priv->compare_target;
	result = _tmp0_ (left, right, _tmp0__target) < 0;
	return result;
}

static inline gboolean
vala_tim_sort_lower_than_or_equal_to (ValaTimSort* self,
                                      gconstpointer left,
                                      gconstpointer right)
{
	GCompareDataFunc _tmp0_;
	gpointer _tmp0__target;
	gboolean result;
	g_return_val_if_fail (self != NULL, FALSE);
	_tmp0_ = self->priv->compare;
	_tmp0__target = self->priv->compare_target;
	result = _tmp0_ (left, right, _tmp0__target) <= 0;
	return result;
}

static gint
vala_tim_sort_compute_minimum_run_length (ValaTimSort* self,
                                          gint length)
{
	gint run_length = 0;
	gint result;
	g_return_val_if_fail (self != NULL, 0);
	run_length = 0;
	while (TRUE) {
		if (!(length >= 64)) {
			break;
		}
		run_length |= length & 1;
		length = length >> 1;
	}
	result = length + run_length;
	return result;
}

static ValaTimSortSlice*
vala_tim_sort_compute_longest_run (ValaTimSort* self,
                                   ValaTimSortSlice* a,
                                   gboolean* descending)
{
	gboolean _vala_descending = FALSE;
	gint run_length = 0;
	void** _tmp18_;
	ValaTimSortSlice* _tmp19_;
	ValaTimSortSlice* result;
	g_return_val_if_fail (self != NULL, NULL);
	g_return_val_if_fail (a != NULL, NULL);
	if (a->length <= 1) {
		run_length = a->length;
		_vala_descending = FALSE;
	} else {
		void** _tmp0_;
		void* _tmp1_;
		void** _tmp2_;
		void* _tmp3_;
		run_length = 2;
		_tmp0_ = a->list;
		_tmp1_ = _tmp0_[a->index + 1];
		_tmp2_ = a->list;
		_tmp3_ = _tmp2_[a->index];
		if (vala_tim_sort_lower_than (self, _tmp1_, _tmp3_)) {
			_vala_descending = TRUE;
			{
				gint i = 0;
				i = a->index + 2;
				{
					gboolean _tmp4_ = FALSE;
					_tmp4_ = TRUE;
					while (TRUE) {
						void** _tmp6_;
						void* _tmp7_;
						void** _tmp8_;
						void* _tmp9_;
						if (!_tmp4_) {
							gint _tmp5_;
							_tmp5_ = i;
							i = _tmp5_ + 1;
						}
						_tmp4_ = FALSE;
						if (!(i < (a->index + a->length))) {
							break;
						}
						_tmp6_ = a->list;
						_tmp7_ = _tmp6_[i];
						_tmp8_ = a->list;
						_tmp9_ = _tmp8_[i - 1];
						if (vala_tim_sort_lower_than (self, _tmp7_, _tmp9_)) {
							gint _tmp10_;
							_tmp10_ = run_length;
							run_length = _tmp10_ + 1;
						} else {
							break;
						}
					}
				}
			}
		} else {
			_vala_descending = FALSE;
			{
				gint i = 0;
				i = a->index + 2;
				{
					gboolean _tmp11_ = FALSE;
					_tmp11_ = TRUE;
					while (TRUE) {
						void** _tmp13_;
						void* _tmp14_;
						void** _tmp15_;
						void* _tmp16_;
						if (!_tmp11_) {
							gint _tmp12_;
							_tmp12_ = i;
							i = _tmp12_ + 1;
						}
						_tmp11_ = FALSE;
						if (!(i < (a->index + a->length))) {
							break;
						}
						_tmp13_ = a->list;
						_tmp14_ = _tmp13_[i];
						_tmp15_ = a->list;
						_tmp16_ = _tmp15_[i - 1];
						if (vala_tim_sort_lower_than (self, _tmp14_, _tmp16_)) {
							break;
						} else {
							gint _tmp17_;
							_tmp17_ = run_length;
							run_length = _tmp17_ + 1;
						}
					}
				}
			}
		}
	}
	_tmp18_ = a->list;
	_tmp19_ = vala_tim_sort_slice_new (_tmp18_, a->index, run_length);
	result = _tmp19_;
	if (descending) {
		*descending = _vala_descending;
	}
	return result;
}

static void
vala_tim_sort_insertion_sort (ValaTimSort* self,
                              ValaTimSortSlice* a,
                              gint offset)
{
	g_return_if_fail (self != NULL);
	g_return_if_fail (a != NULL);
	{
		gint start = 0;
		start = a->index + offset;
		{
			gboolean _tmp0_ = FALSE;
			_tmp0_ = TRUE;
			while (TRUE) {
				gint left = 0;
				gint right = 0;
				void* pivot = NULL;
				void** _tmp2_;
				void* _tmp3_;
				void** _tmp7_;
				void** _tmp8_;
				void** _tmp9_;
				void* _tmp10_;
				if (!_tmp0_) {
					gint _tmp1_;
					_tmp1_ = start;
					start = _tmp1_ + 1;
				}
				_tmp0_ = FALSE;
				if (!(start < (a->index + a->length))) {
					break;
				}
				left = a->index;
				right = start;
				_tmp2_ = a->list;
				_tmp3_ = _tmp2_[right];
				pivot = _tmp3_;
				while (TRUE) {
					gint p = 0;
					void* _tmp4_;
					void** _tmp5_;
					void* _tmp6_;
					if (!(left < right)) {
						break;
					}
					p = left + ((right - left) >> 1);
					_tmp4_ = pivot;
					_tmp5_ = a->list;
					_tmp6_ = _tmp5_[p];
					if (vala_tim_sort_lower_than (self, _tmp4_, _tmp6_)) {
						right = p;
					} else {
						left = p + 1;
					}
				}
				_vala_assert (left == right, "left == right");
				_tmp7_ = a->list;
				_tmp8_ = a->list;
				memmove (&_tmp7_[left + 1], &_tmp8_[left], (gsize) (sizeof (gpointer) * (start - left)));
				_tmp9_ = a->list;
				_tmp10_ = pivot;
				_tmp9_[left] = _tmp10_;
			}
		}
	}
}

static void
vala_tim_sort_merge_collapse (ValaTimSort* self)
{
	gint count = 0;
	ValaTimSortSlice** _tmp0_;
	gint _tmp0__length1;
	g_return_if_fail (self != NULL);
	_tmp0_ = self->priv->pending;
	_tmp0__length1 = self->priv->pending_length1;
	count = _tmp0__length1;
	while (TRUE) {
		gboolean _tmp1_ = FALSE;
		ValaTimSortSlice** _tmp16_;
		gint _tmp16__length1;
		if (!(count > 1)) {
			break;
		}
		if (count >= 3) {
			ValaTimSortSlice** _tmp2_;
			gint _tmp2__length1;
			ValaTimSortSlice* _tmp3_;
			ValaTimSortSlice** _tmp4_;
			gint _tmp4__length1;
			ValaTimSortSlice* _tmp5_;
			ValaTimSortSlice** _tmp6_;
			gint _tmp6__length1;
			ValaTimSortSlice* _tmp7_;
			_tmp2_ = self->priv->pending;
			_tmp2__length1 = self->priv->pending_length1;
			_tmp3_ = _tmp2_[count - 3];
			_tmp4_ = self->priv->pending;
			_tmp4__length1 = self->priv->pending_length1;
			_tmp5_ = _tmp4_[count - 2];
			_tmp6_ = self->priv->pending;
			_tmp6__length1 = self->priv->pending_length1;
			_tmp7_ = _tmp6_[count - 1];
			_tmp1_ = _tmp3_->length <= (_tmp5_->length + _tmp7_->length);
		} else {
			_tmp1_ = FALSE;
		}
		if (_tmp1_) {
			ValaTimSortSlice** _tmp8_;
			gint _tmp8__length1;
			ValaTimSortSlice* _tmp9_;
			ValaTimSortSlice** _tmp10_;
			gint _tmp10__length1;
			ValaTimSortSlice* _tmp11_;
			_tmp8_ = self->priv->pending;
			_tmp8__length1 = self->priv->pending_length1;
			_tmp9_ = _tmp8_[count - 3];
			_tmp10_ = self->priv->pending;
			_tmp10__length1 = self->priv->pending_length1;
			_tmp11_ = _tmp10_[count - 1];
			if (_tmp9_->length < _tmp11_->length) {
				vala_tim_sort_merge_at (self, count - 3);
			} else {
				vala_tim_sort_merge_at (self, count - 2);
			}
		} else {
			ValaTimSortSlice** _tmp12_;
			gint _tmp12__length1;
			ValaTimSortSlice* _tmp13_;
			ValaTimSortSlice** _tmp14_;
			gint _tmp14__length1;
			ValaTimSortSlice* _tmp15_;
			_tmp12_ = self->priv->pending;
			_tmp12__length1 = self->priv->pending_length1;
			_tmp13_ = _tmp12_[count - 2];
			_tmp14_ = self->priv->pending;
			_tmp14__length1 = self->priv->pending_length1;
			_tmp15_ = _tmp14_[count - 1];
			if (_tmp13_->length <= _tmp15_->length) {
				vala_tim_sort_merge_at (self, count - 2);
			} else {
				break;
			}
		}
		_tmp16_ = self->priv->pending;
		_tmp16__length1 = self->priv->pending_length1;
		count = _tmp16__length1;
	}
}

static void
vala_tim_sort_merge_force_collapse (ValaTimSort* self)
{
	gint count = 0;
	ValaTimSortSlice** _tmp0_;
	gint _tmp0__length1;
	g_return_if_fail (self != NULL);
	_tmp0_ = self->priv->pending;
	_tmp0__length1 = self->priv->pending_length1;
	count = _tmp0__length1;
	while (TRUE) {
		gboolean _tmp1_ = FALSE;
		ValaTimSortSlice** _tmp6_;
		gint _tmp6__length1;
		if (!(count > 1)) {
			break;
		}
		if (count >= 3) {
			ValaTimSortSlice** _tmp2_;
			gint _tmp2__length1;
			ValaTimSortSlice* _tmp3_;
			ValaTimSortSlice** _tmp4_;
			gint _tmp4__length1;
			ValaTimSortSlice* _tmp5_;
			_tmp2_ = self->priv->pending;
			_tmp2__length1 = self->priv->pending_length1;
			_tmp3_ = _tmp2_[count - 3];
			_tmp4_ = self->priv->pending;
			_tmp4__length1 = self->priv->pending_length1;
			_tmp5_ = _tmp4_[count - 1];
			_tmp1_ = _tmp3_->length < _tmp5_->length;
		} else {
			_tmp1_ = FALSE;
		}
		if (_tmp1_) {
			vala_tim_sort_merge_at (self, count - 3);
		} else {
			vala_tim_sort_merge_at (self, count - 2);
		}
		_tmp6_ = self->priv->pending;
		_tmp6__length1 = self->priv->pending_length1;
		count = _tmp6__length1;
	}
}

static void
vala_tim_sort_merge_at (ValaTimSort* self,
                        gint index)
{
	ValaTimSortSlice* a = NULL;
	ValaTimSortSlice** _tmp0_;
	gint _tmp0__length1;
	ValaTimSortSlice* _tmp1_;
	ValaTimSortSlice* b = NULL;
	ValaTimSortSlice** _tmp2_;
	gint _tmp2__length1;
	ValaTimSortSlice* _tmp3_;
	ValaTimSortSlice* _tmp4_;
	ValaTimSortSlice* _tmp5_;
	ValaTimSortSlice* _tmp6_;
	ValaTimSortSlice* _tmp7_;
	ValaTimSortSlice* _tmp8_;
	ValaTimSortSlice** _tmp9_;
	gint _tmp9__length1;
	void** _tmp10_;
	ValaTimSortSlice* _tmp11_;
	ValaTimSortSlice* _tmp12_;
	ValaTimSortSlice* _tmp13_;
	ValaTimSortSlice* _tmp14_;
	ValaTimSortSlice** _tmp15_;
	gint _tmp15__length1;
	gint sorted_count = 0;
	ValaTimSortSlice* _tmp16_;
	void* _tmp17_;
	ValaTimSortSlice* _tmp18_;
	ValaTimSortSlice* _tmp19_;
	ValaTimSortSlice* _tmp20_;
	ValaTimSortSlice* _tmp21_;
	ValaTimSortSlice* _tmp22_;
	void* _tmp23_;
	ValaTimSortSlice* _tmp24_;
	ValaTimSortSlice* _tmp25_;
	ValaTimSortSlice* _tmp26_;
	ValaTimSortSlice* _tmp27_;
	ValaTimSortSlice* _tmp28_;
	g_return_if_fail (self != NULL);
	_tmp0_ = self->priv->pending;
	_tmp0__length1 = self->priv->pending_length1;
	_tmp1_ = _tmp0_[index];
	_tmp0_[index] = NULL;
	a = _tmp1_;
	_tmp2_ = self->priv->pending;
	_tmp2__length1 = self->priv->pending_length1;
	_tmp3_ = _tmp2_[index + 1];
	_tmp2_[index + 1] = NULL;
	b = _tmp3_;
	_tmp4_ = a;
	_vala_assert (_tmp4_->length > 0, "a.length > 0");
	_tmp5_ = b;
	_vala_assert (_tmp5_->length > 0, "b.length > 0");
	_tmp6_ = a;
	_tmp7_ = a;
	_tmp8_ = b;
	_vala_assert ((_tmp6_->index + _tmp7_->length) == _tmp8_->index, "a.index + a.length == b.index");
	_tmp9_ = self->priv->pending;
	_tmp9__length1 = self->priv->pending_length1;
	_tmp10_ = self->priv->list;
	_tmp11_ = a;
	_tmp12_ = a;
	_tmp13_ = b;
	_tmp14_ = vala_tim_sort_slice_new (_tmp10_, _tmp11_->index, _tmp12_->length + _tmp13_->length);
	_vala_tim_sort_slice_free0 (_tmp9_[index]);
	_tmp9_[index] = _tmp14_;
	_tmp15_ = self->priv->pending;
	_tmp15__length1 = self->priv->pending_length1;
	_vala_array_move (self->priv->pending, sizeof (ValaTimSortSlice*), index + 2, index + 1, (_tmp15__length1 - index) - 2);
	self->priv->pending_length1 = self->priv->pending_length1 - 1;
	_tmp16_ = b;
	_tmp17_ = vala_tim_sort_slice_peek_first (_tmp16_);
	_tmp18_ = a;
	sorted_count = vala_tim_sort_gallop_rightmost (self, _tmp17_, _tmp18_, 0);
	_tmp19_ = a;
	vala_tim_sort_slice_shorten_start (_tmp19_, sorted_count);
	_tmp20_ = a;
	if (_tmp20_->length == 0) {
		_vala_tim_sort_slice_free0 (b);
		_vala_tim_sort_slice_free0 (a);
		return;
	}
	_tmp21_ = b;
	_tmp22_ = a;
	_tmp23_ = vala_tim_sort_slice_peek_last (_tmp22_);
	_tmp24_ = b;
	_tmp25_ = b;
	_tmp21_->length = vala_tim_sort_gallop_leftmost (self, _tmp23_, _tmp24_, _tmp25_->length - 1);
	_tmp26_ = b;
	if (_tmp26_->length == 0) {
		_vala_tim_sort_slice_free0 (b);
		_vala_tim_sort_slice_free0 (a);
		return;
	}
	_tmp27_ = a;
	_tmp28_ = b;
	if (_tmp27_->length <= _tmp28_->length) {
		ValaTimSortSlice* _tmp29_;
		ValaTimSortSlice* _tmp30_;
		_tmp29_ = a;
		a = NULL;
		_tmp30_ = b;
		b = NULL;
		vala_tim_sort_merge_low (self, _tmp29_, _tmp30_);
	} else {
		ValaTimSortSlice* _tmp31_;
		ValaTimSortSlice* _tmp32_;
		_tmp31_ = a;
		a = NULL;
		_tmp32_ = b;
		b = NULL;
		vala_tim_sort_merge_high (self, _tmp31_, _tmp32_);
	}
	_vala_tim_sort_slice_free0 (b);
	_vala_tim_sort_slice_free0 (a);
}

static gint
vala_tim_sort_gallop_leftmost (ValaTimSort* self,
                               gconstpointer key,
                               ValaTimSortSlice* a,
                               gint hint)
{
	gint p = 0;
	gint last_offset = 0;
	gint offset = 0;
	void** _tmp0_;
	void* _tmp1_;
	gint result;
	g_return_val_if_fail (self != NULL, 0);
	g_return_val_if_fail (a != NULL, 0);
	_vala_assert (0 <= hint, "0 <= hint");
	_vala_assert (hint < a->length, "hint < a.length");
	p = a->index + hint;
	last_offset = 0;
	offset = 1;
	_tmp0_ = a->list;
	_tmp1_ = _tmp0_[p];
	if (vala_tim_sort_lower_than (self, _tmp1_, key)) {
		gint max_offset = 0;
		max_offset = a->length - hint;
		while (TRUE) {
			void** _tmp2_;
			void* _tmp3_;
			if (!(offset < max_offset)) {
				break;
			}
			_tmp2_ = a->list;
			_tmp3_ = _tmp2_[p + offset];
			if (vala_tim_sort_lower_than (self, _tmp3_, key)) {
				gint _tmp4_;
				last_offset = offset;
				offset <<= 1;
				_tmp4_ = offset;
				offset = _tmp4_ + 1;
			} else {
				break;
			}
		}
		if (offset > max_offset) {
			offset = max_offset;
		}
		last_offset = hint + last_offset;
		offset = hint + offset;
	} else {
		gint max_offset = 0;
		gint temp_last_offset = 0;
		gint temp_offset = 0;
		max_offset = hint + 1;
		while (TRUE) {
			void** _tmp5_;
			void* _tmp6_;
			if (!(offset < max_offset)) {
				break;
			}
			_tmp5_ = a->list;
			_tmp6_ = _tmp5_[p - offset];
			if (vala_tim_sort_lower_than (self, _tmp6_, key)) {
				break;
			} else {
				gint _tmp7_;
				last_offset = offset;
				offset <<= 1;
				_tmp7_ = offset;
				offset = _tmp7_ + 1;
			}
		}
		if (offset > max_offset) {
			offset = max_offset;
		}
		temp_last_offset = last_offset;
		temp_offset = offset;
		last_offset = hint - temp_offset;
		offset = hint - temp_last_offset;
	}
	_vala_assert (-1 <= last_offset, "-1 <= last_offset");
	_vala_assert (last_offset < offset, "last_offset < offset");
	_vala_assert (offset <= a->length, "offset <= a.length");
	last_offset += 1;
	while (TRUE) {
		gint m = 0;
		void** _tmp8_;
		void* _tmp9_;
		if (!(last_offset < offset)) {
			break;
		}
		m = last_offset + ((offset - last_offset) >> 1);
		_tmp8_ = a->list;
		_tmp9_ = _tmp8_[a->index + m];
		if (vala_tim_sort_lower_than (self, _tmp9_, key)) {
			last_offset = m + 1;
		} else {
			offset = m;
		}
	}
	_vala_assert (last_offset == offset, "last_offset == offset");
	result = offset;
	return result;
}

static gint
vala_tim_sort_gallop_rightmost (ValaTimSort* self,
                                gconstpointer key,
                                ValaTimSortSlice* a,
                                gint hint)
{
	gint p = 0;
	gint last_offset = 0;
	gint offset = 0;
	void** _tmp0_;
	void* _tmp1_;
	gint result;
	g_return_val_if_fail (self != NULL, 0);
	g_return_val_if_fail (a != NULL, 0);
	_vala_assert (0 <= hint, "0 <= hint");
	_vala_assert (hint < a->length, "hint < a.length");
	p = a->index + hint;
	last_offset = 0;
	offset = 1;
	_tmp0_ = a->list;
	_tmp1_ = _tmp0_[p];
	if (vala_tim_sort_lower_than_or_equal_to (self, _tmp1_, key)) {
		gint max_offset = 0;
		max_offset = a->length - hint;
		while (TRUE) {
			void** _tmp2_;
			void* _tmp3_;
			if (!(offset < max_offset)) {
				break;
			}
			_tmp2_ = a->list;
			_tmp3_ = _tmp2_[p + offset];
			if (vala_tim_sort_lower_than_or_equal_to (self, _tmp3_, key)) {
				gint _tmp4_;
				last_offset = offset;
				offset <<= 1;
				_tmp4_ = offset;
				offset = _tmp4_ + 1;
			} else {
				break;
			}
		}
		if (offset > max_offset) {
			offset = max_offset;
		}
		last_offset = hint + last_offset;
		offset = hint + offset;
	} else {
		gint max_offset = 0;
		gint temp_last_offset = 0;
		gint temp_offset = 0;
		max_offset = hint + 1;
		while (TRUE) {
			void** _tmp5_;
			void* _tmp6_;
			if (!(offset < max_offset)) {
				break;
			}
			_tmp5_ = a->list;
			_tmp6_ = _tmp5_[p - offset];
			if (vala_tim_sort_lower_than_or_equal_to (self, _tmp6_, key)) {
				break;
			} else {
				gint _tmp7_;
				last_offset = offset;
				offset <<= 1;
				_tmp7_ = offset;
				offset = _tmp7_ + 1;
			}
		}
		if (offset > max_offset) {
			offset = max_offset;
		}
		temp_last_offset = last_offset;
		temp_offset = offset;
		last_offset = hint - temp_offset;
		offset = hint - temp_last_offset;
	}
	_vala_assert (-1 <= last_offset, "-1 <= last_offset");
	_vala_assert (last_offset < offset, "last_offset < offset");
	_vala_assert (offset <= a->length, "offset <= a.length");
	last_offset += 1;
	while (TRUE) {
		gint m = 0;
		void** _tmp8_;
		void* _tmp9_;
		if (!(last_offset < offset)) {
			break;
		}
		m = last_offset + ((offset - last_offset) >> 1);
		_tmp8_ = a->list;
		_tmp9_ = _tmp8_[a->index + m];
		if (vala_tim_sort_lower_than_or_equal_to (self, _tmp9_, key)) {
			last_offset = m + 1;
		} else {
			offset = m;
		}
	}
	_vala_assert (last_offset == offset, "last_offset == offset");
	result = offset;
	return result;
}

static void
vala_tim_sort_merge_low (ValaTimSort* self,
                         ValaTimSortSlice* a,
                         ValaTimSortSlice* b)
{
	gint minimum_gallop = 0;
	gint dest = 0;
	GError* _inner_error0_ = NULL;
	g_return_if_fail (self != NULL);
	g_return_if_fail (a != NULL);
	g_return_if_fail (b != NULL);
	_vala_assert (a->length > 0, "a.length > 0");
	_vala_assert (b->length > 0, "b.length > 0");
	_vala_assert ((a->index + a->length) == b->index, "a.index + a.length == b.index");
	minimum_gallop = self->priv->minimum_gallop;
	dest = a->index;
	vala_tim_sort_slice_copy (a);
	{
		void** _tmp0_;
		gint _tmp1_;
		void* _tmp2_;
		gboolean _tmp3_ = FALSE;
		_tmp0_ = self->priv->list;
		_tmp1_ = dest;
		dest = _tmp1_ + 1;
		_tmp2_ = vala_tim_sort_slice_pop_first (b);
		_tmp0_[_tmp1_] = _tmp2_;
		if (a->length == 1) {
			_tmp3_ = TRUE;
		} else {
			_tmp3_ = b->length == 0;
		}
		if (_tmp3_) {
			{
				void** _tmp4_;
				void** _tmp5_;
				_vala_assert (a->length >= 0, "a.length >= 0");
				_vala_assert (b->length >= 0, "b.length >= 0");
				_tmp4_ = self->priv->list;
				vala_tim_sort_slice_merge_in (b, _tmp4_, b->index, dest, b->length);
				_tmp5_ = self->priv->list;
				vala_tim_sort_slice_merge_in (a, _tmp5_, a->index, dest + b->length, a->length);
			}
			_vala_tim_sort_slice_free0 (a);
			_vala_tim_sort_slice_free0 (b);
			return;
		}
		while (TRUE) {
			gint a_count = 0;
			gint b_count = 0;
			gint _tmp20_;
			gint _tmp41_;
			a_count = 0;
			b_count = 0;
			while (TRUE) {
				void* _tmp6_;
				void* _tmp7_;
				_tmp6_ = vala_tim_sort_slice_peek_first (b);
				_tmp7_ = vala_tim_sort_slice_peek_first (a);
				if (vala_tim_sort_lower_than (self, _tmp6_, _tmp7_)) {
					void** _tmp8_;
					gint _tmp9_;
					void* _tmp10_;
					gint _tmp13_;
					_tmp8_ = self->priv->list;
					_tmp9_ = dest;
					dest = _tmp9_ + 1;
					_tmp10_ = vala_tim_sort_slice_pop_first (b);
					_tmp8_[_tmp9_] = _tmp10_;
					if (b->length == 0) {
						{
							void** _tmp11_;
							void** _tmp12_;
							_vala_assert (a->length >= 0, "a.length >= 0");
							_vala_assert (b->length >= 0, "b.length >= 0");
							_tmp11_ = self->priv->list;
							vala_tim_sort_slice_merge_in (b, _tmp11_, b->index, dest, b->length);
							_tmp12_ = self->priv->list;
							vala_tim_sort_slice_merge_in (a, _tmp12_, a->index, dest + b->length, a->length);
						}
						_vala_tim_sort_slice_free0 (a);
						_vala_tim_sort_slice_free0 (b);
						return;
					}
					_tmp13_ = b_count;
					b_count = _tmp13_ + 1;
					a_count = 0;
					if (b_count >= minimum_gallop) {
						break;
					}
				} else {
					void** _tmp14_;
					gint _tmp15_;
					void* _tmp16_;
					gint _tmp19_;
					_tmp14_ = self->priv->list;
					_tmp15_ = dest;
					dest = _tmp15_ + 1;
					_tmp16_ = vala_tim_sort_slice_pop_first (a);
					_tmp14_[_tmp15_] = _tmp16_;
					if (a->length == 1) {
						{
							void** _tmp17_;
							void** _tmp18_;
							_vala_assert (a->length >= 0, "a.length >= 0");
							_vala_assert (b->length >= 0, "b.length >= 0");
							_tmp17_ = self->priv->list;
							vala_tim_sort_slice_merge_in (b, _tmp17_, b->index, dest, b->length);
							_tmp18_ = self->priv->list;
							vala_tim_sort_slice_merge_in (a, _tmp18_, a->index, dest + b->length, a->length);
						}
						_vala_tim_sort_slice_free0 (a);
						_vala_tim_sort_slice_free0 (b);
						return;
					}
					_tmp19_ = a_count;
					a_count = _tmp19_ + 1;
					b_count = 0;
					if (a_count >= minimum_gallop) {
						break;
					}
				}
			}
			_tmp20_ = minimum_gallop;
			minimum_gallop = _tmp20_ + 1;
			while (TRUE) {
				gint _tmp21_ = 0;
				void* _tmp22_;
				void** _tmp23_;
				void** _tmp26_;
				gint _tmp27_;
				void* _tmp28_;
				void* _tmp31_;
				void** _tmp32_;
				void** _tmp35_;
				gint _tmp36_;
				void* _tmp37_;
				gboolean _tmp40_ = FALSE;
				if (minimum_gallop > 1) {
					_tmp21_ = 1;
				} else {
					_tmp21_ = 0;
				}
				minimum_gallop -= _tmp21_;
				self->priv->minimum_gallop = minimum_gallop;
				_tmp22_ = vala_tim_sort_slice_peek_first (b);
				a_count = vala_tim_sort_gallop_rightmost (self, _tmp22_, a, 0);
				_tmp23_ = self->priv->list;
				vala_tim_sort_slice_merge_in (a, _tmp23_, a->index, dest, a_count);
				dest += a_count;
				vala_tim_sort_slice_shorten_start (a, a_count);
				if (a->length <= 1) {
					{
						void** _tmp24_;
						void** _tmp25_;
						_vala_assert (a->length >= 0, "a.length >= 0");
						_vala_assert (b->length >= 0, "b.length >= 0");
						_tmp24_ = self->priv->list;
						vala_tim_sort_slice_merge_in (b, _tmp24_, b->index, dest, b->length);
						_tmp25_ = self->priv->list;
						vala_tim_sort_slice_merge_in (a, _tmp25_, a->index, dest + b->length, a->length);
					}
					_vala_tim_sort_slice_free0 (a);
					_vala_tim_sort_slice_free0 (b);
					return;
				}
				_tmp26_ = self->priv->list;
				_tmp27_ = dest;
				dest = _tmp27_ + 1;
				_tmp28_ = vala_tim_sort_slice_pop_first (b);
				_tmp26_[_tmp27_] = _tmp28_;
				if (b->length == 0) {
					{
						void** _tmp29_;
						void** _tmp30_;
						_vala_assert (a->length >= 0, "a.length >= 0");
						_vala_assert (b->length >= 0, "b.length >= 0");
						_tmp29_ = self->priv->list;
						vala_tim_sort_slice_merge_in (b, _tmp29_, b->index, dest, b->length);
						_tmp30_ = self->priv->list;
						vala_tim_sort_slice_merge_in (a, _tmp30_, a->index, dest + b->length, a->length);
					}
					_vala_tim_sort_slice_free0 (a);
					_vala_tim_sort_slice_free0 (b);
					return;
				}
				_tmp31_ = vala_tim_sort_slice_peek_first (a);
				b_count = vala_tim_sort_gallop_leftmost (self, _tmp31_, b, 0);
				_tmp32_ = self->priv->list;
				vala_tim_sort_slice_merge_in (b, _tmp32_, b->index, dest, b_count);
				dest += b_count;
				vala_tim_sort_slice_shorten_start (b, b_count);
				if (b->length == 0) {
					{
						void** _tmp33_;
						void** _tmp34_;
						_vala_assert (a->length >= 0, "a.length >= 0");
						_vala_assert (b->length >= 0, "b.length >= 0");
						_tmp33_ = self->priv->list;
						vala_tim_sort_slice_merge_in (b, _tmp33_, b->index, dest, b->length);
						_tmp34_ = self->priv->list;
						vala_tim_sort_slice_merge_in (a, _tmp34_, a->index, dest + b->length, a->length);
					}
					_vala_tim_sort_slice_free0 (a);
					_vala_tim_sort_slice_free0 (b);
					return;
				}
				_tmp35_ = self->priv->list;
				_tmp36_ = dest;
				dest = _tmp36_ + 1;
				_tmp37_ = vala_tim_sort_slice_pop_first (a);
				_tmp35_[_tmp36_] = _tmp37_;
				if (a->length == 1) {
					{
						void** _tmp38_;
						void** _tmp39_;
						_vala_assert (a->length >= 0, "a.length >= 0");
						_vala_assert (b->length >= 0, "b.length >= 0");
						_tmp38_ = self->priv->list;
						vala_tim_sort_slice_merge_in (b, _tmp38_, b->index, dest, b->length);
						_tmp39_ = self->priv->list;
						vala_tim_sort_slice_merge_in (a, _tmp39_, a->index, dest + b->length, a->length);
					}
					_vala_tim_sort_slice_free0 (a);
					_vala_tim_sort_slice_free0 (b);
					return;
				}
				if (a_count < VALA_TIM_SORT_MINIMUM_GALLOP) {
					_tmp40_ = b_count < VALA_TIM_SORT_MINIMUM_GALLOP;
				} else {
					_tmp40_ = FALSE;
				}
				if (_tmp40_) {
					break;
				}
			}
			_tmp41_ = minimum_gallop;
			minimum_gallop = _tmp41_ + 1;
			self->priv->minimum_gallop = minimum_gallop;
		}
	}
	__finally0:
	{
		void** _tmp42_;
		void** _tmp43_;
		_vala_assert (a->length >= 0, "a.length >= 0");
		_vala_assert (b->length >= 0, "b.length >= 0");
		_tmp42_ = self->priv->list;
		vala_tim_sort_slice_merge_in (b, _tmp42_, b->index, dest, b->length);
		_tmp43_ = self->priv->list;
		vala_tim_sort_slice_merge_in (a, _tmp43_, a->index, dest + b->length, a->length);
	}
	_vala_tim_sort_slice_free0 (a);
	_vala_tim_sort_slice_free0 (b);
	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;
}

static void
vala_tim_sort_merge_high (ValaTimSort* self,
                          ValaTimSortSlice* a,
                          ValaTimSortSlice* b)
{
	gint minimum_gallop = 0;
	gint dest = 0;
	GError* _inner_error0_ = NULL;
	g_return_if_fail (self != NULL);
	g_return_if_fail (a != NULL);
	g_return_if_fail (b != NULL);
	_vala_assert (a->length > 0, "a.length > 0");
	_vala_assert (b->length > 0, "b.length > 0");
	_vala_assert ((a->index + a->length) == b->index, "a.index + a.length == b.index");
	minimum_gallop = self->priv->minimum_gallop;
	dest = b->index + b->length;
	vala_tim_sort_slice_copy (b);
	{
		void** _tmp0_;
		gint _tmp1_;
		void* _tmp2_;
		gboolean _tmp3_ = FALSE;
		_tmp0_ = self->priv->list;
		dest = dest - 1;
		_tmp1_ = dest;
		_tmp2_ = vala_tim_sort_slice_pop_last (a);
		_tmp0_[_tmp1_] = _tmp2_;
		if (a->length == 0) {
			_tmp3_ = TRUE;
		} else {
			_tmp3_ = b->length == 1;
		}
		if (_tmp3_) {
			{
				void** _tmp4_;
				void** _tmp5_;
				_vala_assert (a->length >= 0, "a.length >= 0");
				_vala_assert (b->length >= 0, "b.length >= 0");
				_tmp4_ = self->priv->list;
				vala_tim_sort_slice_merge_in_reversed (a, _tmp4_, a->index, dest - a->length, a->length);
				_tmp5_ = self->priv->list;
				vala_tim_sort_slice_merge_in_reversed (b, _tmp5_, b->index, (dest - a->length) - b->length, b->length);
			}
			_vala_tim_sort_slice_free0 (a);
			_vala_tim_sort_slice_free0 (b);
			return;
		}
		while (TRUE) {
			gint a_count = 0;
			gint b_count = 0;
			gint _tmp20_;
			gint _tmp41_;
			a_count = 0;
			b_count = 0;
			while (TRUE) {
				void* _tmp6_;
				void* _tmp7_;
				_tmp6_ = vala_tim_sort_slice_peek_last (b);
				_tmp7_ = vala_tim_sort_slice_peek_last (a);
				if (vala_tim_sort_lower_than (self, _tmp6_, _tmp7_)) {
					void** _tmp8_;
					gint _tmp9_;
					void* _tmp10_;
					gint _tmp13_;
					_tmp8_ = self->priv->list;
					dest = dest - 1;
					_tmp9_ = dest;
					_tmp10_ = vala_tim_sort_slice_pop_last (a);
					_tmp8_[_tmp9_] = _tmp10_;
					if (a->length == 0) {
						{
							void** _tmp11_;
							void** _tmp12_;
							_vala_assert (a->length >= 0, "a.length >= 0");
							_vala_assert (b->length >= 0, "b.length >= 0");
							_tmp11_ = self->priv->list;
							vala_tim_sort_slice_merge_in_reversed (a, _tmp11_, a->index, dest - a->length, a->length);
							_tmp12_ = self->priv->list;
							vala_tim_sort_slice_merge_in_reversed (b, _tmp12_, b->index, (dest - a->length) - b->length, b->length);
						}
						_vala_tim_sort_slice_free0 (a);
						_vala_tim_sort_slice_free0 (b);
						return;
					}
					_tmp13_ = a_count;
					a_count = _tmp13_ + 1;
					b_count = 0;
					if (a_count >= minimum_gallop) {
						break;
					}
				} else {
					void** _tmp14_;
					gint _tmp15_;
					void* _tmp16_;
					gint _tmp19_;
					_tmp14_ = self->priv->list;
					dest = dest - 1;
					_tmp15_ = dest;
					_tmp16_ = vala_tim_sort_slice_pop_last (b);
					_tmp14_[_tmp15_] = _tmp16_;
					if (b->length == 1) {
						{
							void** _tmp17_;
							void** _tmp18_;
							_vala_assert (a->length >= 0, "a.length >= 0");
							_vala_assert (b->length >= 0, "b.length >= 0");
							_tmp17_ = self->priv->list;
							vala_tim_sort_slice_merge_in_reversed (a, _tmp17_, a->index, dest - a->length, a->length);
							_tmp18_ = self->priv->list;
							vala_tim_sort_slice_merge_in_reversed (b, _tmp18_, b->index, (dest - a->length) - b->length, b->length);
						}
						_vala_tim_sort_slice_free0 (a);
						_vala_tim_sort_slice_free0 (b);
						return;
					}
					_tmp19_ = b_count;
					b_count = _tmp19_ + 1;
					a_count = 0;
					if (b_count >= minimum_gallop) {
						break;
					}
				}
			}
			_tmp20_ = minimum_gallop;
			minimum_gallop = _tmp20_ + 1;
			while (TRUE) {
				gint _tmp21_ = 0;
				gint k = 0;
				void* _tmp22_;
				void** _tmp23_;
				void** _tmp26_;
				gint _tmp27_;
				void* _tmp28_;
				void* _tmp31_;
				void** _tmp32_;
				void** _tmp35_;
				gint _tmp36_;
				void* _tmp37_;
				gboolean _tmp40_ = FALSE;
				if (minimum_gallop > 1) {
					_tmp21_ = 1;
				} else {
					_tmp21_ = 0;
				}
				minimum_gallop -= _tmp21_;
				self->priv->minimum_gallop = minimum_gallop;
				_tmp22_ = vala_tim_sort_slice_peek_last (b);
				k = vala_tim_sort_gallop_rightmost (self, _tmp22_, a, a->length - 1);
				a_count = a->length - k;
				_tmp23_ = self->priv->list;
				vala_tim_sort_slice_merge_in_reversed (a, _tmp23_, a->index + k, dest - a_count, a_count);
				dest -= a_count;
				vala_tim_sort_slice_shorten_end (a, a_count);
				if (a->length == 0) {
					{
						void** _tmp24_;
						void** _tmp25_;
						_vala_assert (a->length >= 0, "a.length >= 0");
						_vala_assert (b->length >= 0, "b.length >= 0");
						_tmp24_ = self->priv->list;
						vala_tim_sort_slice_merge_in_reversed (a, _tmp24_, a->index, dest - a->length, a->length);
						_tmp25_ = self->priv->list;
						vala_tim_sort_slice_merge_in_reversed (b, _tmp25_, b->index, (dest - a->length) - b->length, b->length);
					}
					_vala_tim_sort_slice_free0 (a);
					_vala_tim_sort_slice_free0 (b);
					return;
				}
				_tmp26_ = self->priv->list;
				dest = dest - 1;
				_tmp27_ = dest;
				_tmp28_ = vala_tim_sort_slice_pop_last (b);
				_tmp26_[_tmp27_] = _tmp28_;
				if (b->length == 1) {
					{
						void** _tmp29_;
						void** _tmp30_;
						_vala_assert (a->length >= 0, "a.length >= 0");
						_vala_assert (b->length >= 0, "b.length >= 0");
						_tmp29_ = self->priv->list;
						vala_tim_sort_slice_merge_in_reversed (a, _tmp29_, a->index, dest - a->length, a->length);
						_tmp30_ = self->priv->list;
						vala_tim_sort_slice_merge_in_reversed (b, _tmp30_, b->index, (dest - a->length) - b->length, b->length);
					}
					_vala_tim_sort_slice_free0 (a);
					_vala_tim_sort_slice_free0 (b);
					return;
				}
				_tmp31_ = vala_tim_sort_slice_peek_last (a);
				k = vala_tim_sort_gallop_leftmost (self, _tmp31_, b, b->length - 1);
				b_count = b->length - k;
				_tmp32_ = self->priv->list;
				vala_tim_sort_slice_merge_in_reversed (b, _tmp32_, b->index + k, dest - b_count, b_count);
				dest -= b_count;
				vala_tim_sort_slice_shorten_end (b, b_count);
				if (b->length <= 1) {
					{
						void** _tmp33_;
						void** _tmp34_;
						_vala_assert (a->length >= 0, "a.length >= 0");
						_vala_assert (b->length >= 0, "b.length >= 0");
						_tmp33_ = self->priv->list;
						vala_tim_sort_slice_merge_in_reversed (a, _tmp33_, a->index, dest - a->length, a->length);
						_tmp34_ = self->priv->list;
						vala_tim_sort_slice_merge_in_reversed (b, _tmp34_, b->index, (dest - a->length) - b->length, b->length);
					}
					_vala_tim_sort_slice_free0 (a);
					_vala_tim_sort_slice_free0 (b);
					return;
				}
				_tmp35_ = self->priv->list;
				dest = dest - 1;
				_tmp36_ = dest;
				_tmp37_ = vala_tim_sort_slice_pop_last (a);
				_tmp35_[_tmp36_] = _tmp37_;
				if (a->length == 0) {
					{
						void** _tmp38_;
						void** _tmp39_;
						_vala_assert (a->length >= 0, "a.length >= 0");
						_vala_assert (b->length >= 0, "b.length >= 0");
						_tmp38_ = self->priv->list;
						vala_tim_sort_slice_merge_in_reversed (a, _tmp38_, a->index, dest - a->length, a->length);
						_tmp39_ = self->priv->list;
						vala_tim_sort_slice_merge_in_reversed (b, _tmp39_, b->index, (dest - a->length) - b->length, b->length);
					}
					_vala_tim_sort_slice_free0 (a);
					_vala_tim_sort_slice_free0 (b);
					return;
				}
				if (a_count < VALA_TIM_SORT_MINIMUM_GALLOP) {
					_tmp40_ = b_count < VALA_TIM_SORT_MINIMUM_GALLOP;
				} else {
					_tmp40_ = FALSE;
				}
				if (_tmp40_) {
					break;
				}
			}
			_tmp41_ = minimum_gallop;
			minimum_gallop = _tmp41_ + 1;
			self->priv->minimum_gallop = minimum_gallop;
		}
	}
	__finally0:
	{
		void** _tmp42_;
		void** _tmp43_;
		_vala_assert (a->length >= 0, "a.length >= 0");
		_vala_assert (b->length >= 0, "b.length >= 0");
		_tmp42_ = self->priv->list;
		vala_tim_sort_slice_merge_in_reversed (a, _tmp42_, a->index, dest - a->length, a->length);
		_tmp43_ = self->priv->list;
		vala_tim_sort_slice_merge_in_reversed (b, _tmp43_, b->index, (dest - a->length) - b->length, b->length);
	}
	_vala_tim_sort_slice_free0 (a);
	_vala_tim_sort_slice_free0 (b);
	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;
}

 G_GNUC_INTERNAL ValaTimSort*
vala_tim_sort_construct (GType object_type,
                         GType g_type,
                         GBoxedCopyFunc g_dup_func,
                         GDestroyNotify g_destroy_func)
{
	ValaTimSort* self = NULL;
	self = (ValaTimSort*) g_type_create_instance (object_type);
	self->priv->g_type = g_type;
	self->priv->g_dup_func = g_dup_func;
	self->priv->g_destroy_func = g_destroy_func;
	return self;
}

 G_GNUC_INTERNAL ValaTimSort*
vala_tim_sort_new (GType g_type,
                   GBoxedCopyFunc g_dup_func,
                   GDestroyNotify g_destroy_func)
{
	return vala_tim_sort_construct (VALA_TYPE_TIM_SORT, g_type, g_dup_func, g_destroy_func);
}

static ValaTimSortSlice*
vala_tim_sort_slice_new (void** list,
                         gint index,
                         gint length)
{
	ValaTimSortSlice* self;
	self = g_slice_new0 (ValaTimSortSlice);
	vala_tim_sort_slice_instance_init (self);
	self->list = list;
	self->index = index;
	self->length = length;
	return self;
}

static void
vala_tim_sort_slice_copy (ValaTimSortSlice* self)
{
	gsize size = 0UL;
	void* _tmp0_;
	void** _tmp1_;
	void** _tmp2_;
	void** _tmp3_;
	g_return_if_fail (self != NULL);
	size = (gsize) (sizeof (gpointer) * self->length);
	_tmp0_ = g_malloc (size);
	self->new_list = _tmp0_;
	_tmp1_ = self->new_list;
	_tmp2_ = self->list;
	memcpy (_tmp1_, &_tmp2_[self->index], size);
	_tmp3_ = self->new_list;
	self->list = _tmp3_;
	self->index = 0;
}

static inline void
vala_tim_sort_slice_merge_in (ValaTimSortSlice* self,
                              void** dest_array,
                              gint index,
                              gint dest_index,
                              gint count)
{
	void** _tmp0_;
	g_return_if_fail (self != NULL);
	_tmp0_ = self->list;
	memmove (&dest_array[dest_index], &_tmp0_[index], (gsize) (sizeof (gpointer) * count));
}

static inline void
vala_tim_sort_slice_merge_in_reversed (ValaTimSortSlice* self,
                                       void** dest_array,
                                       gint index,
                                       gint dest_index,
                                       gint count)
{
	void** _tmp0_;
	g_return_if_fail (self != NULL);
	_tmp0_ = self->list;
	memmove (&dest_array[dest_index], &_tmp0_[index], (gsize) (sizeof (gpointer) * count));
}

static inline void
vala_tim_sort_slice_shorten_start (ValaTimSortSlice* self,
                                   gint n)
{
	g_return_if_fail (self != NULL);
	self->index = self->index + n;
	self->length = self->length - n;
}

static inline void
vala_tim_sort_slice_shorten_end (ValaTimSortSlice* self,
                                 gint n)
{
	g_return_if_fail (self != NULL);
	self->length = self->length - n;
}

static inline void*
vala_tim_sort_slice_pop_first (ValaTimSortSlice* self)
{
	gint _tmp0_;
	void** _tmp1_;
	gint _tmp2_;
	void* _tmp3_;
	void* result;
	g_return_val_if_fail (self != NULL, NULL);
	_tmp0_ = self->length;
	self->length = _tmp0_ - 1;
	_tmp1_ = self->list;
	_tmp2_ = self->index;
	self->index = _tmp2_ + 1;
	_tmp3_ = _tmp1_[_tmp2_];
	result = _tmp3_;
	return result;
}

static inline void*
vala_tim_sort_slice_pop_last (ValaTimSortSlice* self)
{
	gint _tmp0_;
	void** _tmp1_;
	void* _tmp2_;
	void* result;
	g_return_val_if_fail (self != NULL, NULL);
	_tmp0_ = self->length;
	self->length = _tmp0_ - 1;
	_tmp1_ = self->list;
	_tmp2_ = _tmp1_[self->index + self->length];
	result = _tmp2_;
	return result;
}

static inline void*
vala_tim_sort_slice_peek_first (ValaTimSortSlice* self)
{
	void** _tmp0_;
	void* _tmp1_;
	void* result;
	g_return_val_if_fail (self != NULL, NULL);
	_tmp0_ = self->list;
	_tmp1_ = _tmp0_[self->index];
	result = _tmp1_;
	return result;
}

static inline void*
vala_tim_sort_slice_peek_last (ValaTimSortSlice* self)
{
	void** _tmp0_;
	void* _tmp1_;
	void* result;
	g_return_val_if_fail (self != NULL, NULL);
	_tmp0_ = self->list;
	_tmp1_ = _tmp0_[(self->index + self->length) - 1];
	result = _tmp1_;
	return result;
}

static void
vala_tim_sort_slice_reverse (ValaTimSortSlice* self)
{
	gint low = 0;
	gint high = 0;
	g_return_if_fail (self != NULL);
	low = self->index;
	high = (self->index + self->length) - 1;
	while (TRUE) {
		gint _tmp0_;
		gint _tmp1_;
		if (!(low < high)) {
			break;
		}
		_tmp0_ = low;
		low = _tmp0_ + 1;
		_tmp1_ = high;
		high = _tmp1_ - 1;
		vala_tim_sort_slice_swap (self, _tmp0_, _tmp1_);
	}
}

static inline void
vala_tim_sort_slice_swap (ValaTimSortSlice* self,
                          gint i,
                          gint j)
{
	void* temp = NULL;
	void** _tmp0_;
	void* _tmp1_;
	void** _tmp2_;
	void** _tmp3_;
	void* _tmp4_;
	void** _tmp5_;
	g_return_if_fail (self != NULL);
	_tmp0_ = self->list;
	_tmp1_ = _tmp0_[i];
	temp = _tmp1_;
	_tmp2_ = self->list;
	_tmp3_ = self->list;
	_tmp4_ = _tmp3_[j];
	_tmp2_[i] = _tmp4_;
	_tmp5_ = self->list;
	_tmp5_[j] = temp;
}

static void
vala_tim_sort_slice_instance_init (ValaTimSortSlice * self)
{
}

static void
vala_tim_sort_slice_free (ValaTimSortSlice * self)
{
	void** _tmp0_;
	_tmp0_ = self->new_list;
	if (_tmp0_ != NULL) {
		void** _tmp1_;
		_tmp1_ = self->new_list;
		g_free (_tmp1_);
	}
	g_slice_free (ValaTimSortSlice, self);
}

static void
vala_value_tim_sort_init (GValue* value)
{
	value->data[0].v_pointer = NULL;
}

static void
vala_value_tim_sort_free_value (GValue* value)
{
	if (value->data[0].v_pointer) {
		vala_tim_sort_unref (value->data[0].v_pointer);
	}
}

static void
vala_value_tim_sort_copy_value (const GValue* src_value,
                                GValue* dest_value)
{
	if (src_value->data[0].v_pointer) {
		dest_value->data[0].v_pointer = vala_tim_sort_ref (src_value->data[0].v_pointer);
	} else {
		dest_value->data[0].v_pointer = NULL;
	}
}

static gpointer
vala_value_tim_sort_peek_pointer (const GValue* value)
{
	return value->data[0].v_pointer;
}

static gchar*
vala_value_tim_sort_collect_value (GValue* value,
                                   guint n_collect_values,
                                   GTypeCValue* collect_values,
                                   guint collect_flags)
{
	if (collect_values[0].v_pointer) {
		ValaTimSort * object;
		object = collect_values[0].v_pointer;
		if (object->parent_instance.g_class == NULL) {
			return g_strconcat ("invalid unclassed object pointer for value type `", G_VALUE_TYPE_NAME (value), "'", NULL);
		} else if (!g_value_type_compatible (G_TYPE_FROM_INSTANCE (object), G_VALUE_TYPE (value))) {
			return g_strconcat ("invalid object type `", g_type_name (G_TYPE_FROM_INSTANCE (object)), "' for value type `", G_VALUE_TYPE_NAME (value), "'", NULL);
		}
		value->data[0].v_pointer = vala_tim_sort_ref (object);
	} else {
		value->data[0].v_pointer = NULL;
	}
	return NULL;
}

static gchar*
vala_value_tim_sort_lcopy_value (const GValue* value,
                                 guint n_collect_values,
                                 GTypeCValue* collect_values,
                                 guint collect_flags)
{
	ValaTimSort ** object_p;
	object_p = collect_values[0].v_pointer;
	if (!object_p) {
		return g_strdup_printf ("value location for `%s' passed as NULL", G_VALUE_TYPE_NAME (value));
	}
	if (!value->data[0].v_pointer) {
		*object_p = NULL;
	} else if (collect_flags & G_VALUE_NOCOPY_CONTENTS) {
		*object_p = value->data[0].v_pointer;
	} else {
		*object_p = vala_tim_sort_ref (value->data[0].v_pointer);
	}
	return NULL;
}

 G_GNUC_INTERNAL GParamSpec*
vala_param_spec_tim_sort (const gchar* name,
                          const gchar* nick,
                          const gchar* blurb,
                          GType object_type,
                          GParamFlags flags)
{
	ValaParamSpecTimSort* spec;
	g_return_val_if_fail (g_type_is_a (object_type, VALA_TYPE_TIM_SORT), NULL);
	spec = g_param_spec_internal (G_TYPE_PARAM_OBJECT, name, nick, blurb, flags);
	G_PARAM_SPEC (spec)->value_type = object_type;
	return G_PARAM_SPEC (spec);
}

 G_GNUC_INTERNAL gpointer
vala_value_get_tim_sort (const GValue* value)
{
	g_return_val_if_fail (G_TYPE_CHECK_VALUE_TYPE (value, VALA_TYPE_TIM_SORT), NULL);
	return value->data[0].v_pointer;
}

 G_GNUC_INTERNAL void
vala_value_set_tim_sort (GValue* value,
                         gpointer v_object)
{
	ValaTimSort * old;
	g_return_if_fail (G_TYPE_CHECK_VALUE_TYPE (value, VALA_TYPE_TIM_SORT));
	old = value->data[0].v_pointer;
	if (v_object) {
		g_return_if_fail (G_TYPE_CHECK_INSTANCE_TYPE (v_object, VALA_TYPE_TIM_SORT));
		g_return_if_fail (g_value_type_compatible (G_TYPE_FROM_INSTANCE (v_object), G_VALUE_TYPE (value)));
		value->data[0].v_pointer = v_object;
		vala_tim_sort_ref (value->data[0].v_pointer);
	} else {
		value->data[0].v_pointer = NULL;
	}
	if (old) {
		vala_tim_sort_unref (old);
	}
}

 G_GNUC_INTERNAL void
vala_value_take_tim_sort (GValue* value,
                          gpointer v_object)
{
	ValaTimSort * old;
	g_return_if_fail (G_TYPE_CHECK_VALUE_TYPE (value, VALA_TYPE_TIM_SORT));
	old = value->data[0].v_pointer;
	if (v_object) {
		g_return_if_fail (G_TYPE_CHECK_INSTANCE_TYPE (v_object, VALA_TYPE_TIM_SORT));
		g_return_if_fail (g_value_type_compatible (G_TYPE_FROM_INSTANCE (v_object), G_VALUE_TYPE (value)));
		value->data[0].v_pointer = v_object;
	} else {
		value->data[0].v_pointer = NULL;
	}
	if (old) {
		vala_tim_sort_unref (old);
	}
}

static void
vala_tim_sort_class_init (ValaTimSortClass * klass,
                          gpointer klass_data)
{
	vala_tim_sort_parent_class = g_type_class_peek_parent (klass);
	((ValaTimSortClass *) klass)->finalize = vala_tim_sort_finalize;
	g_type_class_adjust_private_offset (klass, &ValaTimSort_private_offset);
}

static void
vala_tim_sort_instance_init (ValaTimSort * self,
                             gpointer klass)
{
	self->priv = vala_tim_sort_get_instance_private (self);
	self->ref_count = 1;
}

static void
vala_tim_sort_finalize (ValaTimSort * obj)
{
	ValaTimSort * self;
	self = G_TYPE_CHECK_INSTANCE_CAST (obj, VALA_TYPE_TIM_SORT, ValaTimSort);
	g_signal_handlers_destroy (self);
	_vala_iterable_unref0 (self->priv->list_collection);
	self->priv->array = (_vala_array_free (self->priv->array, self->priv->array_length1, (GDestroyNotify) self->priv->g_destroy_func), NULL);
	self->priv->pending = (_vala_array_free (self->priv->pending, self->priv->pending_length1, (GDestroyNotify) vala_tim_sort_slice_free), NULL);
}

/**
 * A stable, adaptive, iterative mergesort that requires far fewer than n*lg(n)
 * comparisons when running on partially sorted arrays, while offering
 * performance comparable to a traditional mergesort when run on random arrays.
 * Like all proper mergesorts, this sort is stable and runs O(n*log(n)) time
 * (worst case). In the worst case, this sort requires temporary storage space
 * for n/2 object references; in the best case, it requires only a small
 * constant amount of space.
 *
 * This implementation was adapted from Tim Peters's list sort for Python,
 * which is described in detail here:
 * [[http://svn.python.org/projects/python/trunk/Objects/listsort.txt]]
 *
 * Tim's C code may be found here:
 * [[http://svn.python.org/projects/python/trunk/Objects/listobject.c]]
 *
 * The underlying techniques are described in this paper (and may have even
 * earlier origins):
 *
 *   "Optimistic Sorting and Information Theoretic Complexity"
 *   Peter McIlroy
 *   SODA (Fourth Annual ACM-SIAM Symposium on Discrete Algorithms), pp
 *   467-474, Austin, Texas, 25-27 January 1993.
 */
static GType
vala_tim_sort_get_type_once (void)
{
	static const GTypeValueTable g_define_type_value_table = { vala_value_tim_sort_init, vala_value_tim_sort_free_value, vala_value_tim_sort_copy_value, vala_value_tim_sort_peek_pointer, "p", vala_value_tim_sort_collect_value, "p", vala_value_tim_sort_lcopy_value };
	static const GTypeInfo g_define_type_info = { sizeof (ValaTimSortClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) vala_tim_sort_class_init, (GClassFinalizeFunc) NULL, NULL, sizeof (ValaTimSort), 0, (GInstanceInitFunc) vala_tim_sort_instance_init, &g_define_type_value_table };
	static const GTypeFundamentalInfo g_define_type_fundamental_info = { (G_TYPE_FLAG_CLASSED | G_TYPE_FLAG_INSTANTIATABLE | G_TYPE_FLAG_DERIVABLE | G_TYPE_FLAG_DEEP_DERIVABLE) };
	GType vala_tim_sort_type_id;
	vala_tim_sort_type_id = g_type_register_fundamental (g_type_fundamental_next (), "ValaTimSort", &g_define_type_info, &g_define_type_fundamental_info, 0);
	ValaTimSort_private_offset = g_type_add_instance_private (vala_tim_sort_type_id, sizeof (ValaTimSortPrivate));
	return vala_tim_sort_type_id;
}

 G_GNUC_INTERNAL GType
vala_tim_sort_get_type (void)
{
	static volatile gsize vala_tim_sort_type_id__once = 0;
	if (g_once_init_enter (&vala_tim_sort_type_id__once)) {
		GType vala_tim_sort_type_id;
		vala_tim_sort_type_id = vala_tim_sort_get_type_once ();
		g_once_init_leave (&vala_tim_sort_type_id__once, vala_tim_sort_type_id);
	}
	return vala_tim_sort_type_id__once;
}

 G_GNUC_INTERNAL gpointer
vala_tim_sort_ref (gpointer instance)
{
	ValaTimSort * self;
	self = instance;
	g_atomic_int_inc (&self->ref_count);
	return instance;
}

 G_GNUC_INTERNAL void
vala_tim_sort_unref (gpointer instance)
{
	ValaTimSort * self;
	self = instance;
	if (g_atomic_int_dec_and_test (&self->ref_count)) {
		VALA_TIM_SORT_GET_CLASS (self)->finalize (self);
		g_type_free_instance ((GTypeInstance *) self);
	}
}

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 void
_vala_array_move (gpointer array,
                  gsize element_size,
                  gssize src,
                  gssize dest,
                  gssize length)
{
	memmove (((char*) array) + (dest * element_size), ((char*) array) + (src * element_size), length * element_size);
	if ((src < dest) && ((src + length) > dest)) {
		memset (((char*) array) + (src * element_size), 0, (dest - src) * element_size);
	} else if ((src > dest) && (src < (dest + length))) {
		memset (((char*) array) + ((dest + length) * element_size), 0, (src - dest) * element_size);
	} else if (src != dest) {
		memset (((char*) array) + (src * element_size), 0, length * element_size);
	}
}

