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

/* treeset.vala
 *
 * Copyright (C) 2009-2014  Maciej Piechotka
 *
 * 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:
 * 	Maciej Piechotka <uzytkownik2@gmail.com>
 */

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

typedef struct _GeeTreeSetNode GeeTreeSetNode;

#define GEE_FUNCTIONS_TYPE_COMPARE_DATA_FUNC_CLOSURE (gee_functions_compare_data_func_closure_get_type ())
#define GEE_FUNCTIONS_COMPARE_DATA_FUNC_CLOSURE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GEE_FUNCTIONS_TYPE_COMPARE_DATA_FUNC_CLOSURE, GeeFunctionsCompareDataFuncClosure))
#define GEE_FUNCTIONS_COMPARE_DATA_FUNC_CLOSURE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GEE_FUNCTIONS_TYPE_COMPARE_DATA_FUNC_CLOSURE, GeeFunctionsCompareDataFuncClosureClass))
#define GEE_FUNCTIONS_IS_COMPARE_DATA_FUNC_CLOSURE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GEE_FUNCTIONS_TYPE_COMPARE_DATA_FUNC_CLOSURE))
#define GEE_FUNCTIONS_IS_COMPARE_DATA_FUNC_CLOSURE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GEE_FUNCTIONS_TYPE_COMPARE_DATA_FUNC_CLOSURE))
#define GEE_FUNCTIONS_COMPARE_DATA_FUNC_CLOSURE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GEE_FUNCTIONS_TYPE_COMPARE_DATA_FUNC_CLOSURE, GeeFunctionsCompareDataFuncClosureClass))

typedef struct _GeeFunctionsCompareDataFuncClosure GeeFunctionsCompareDataFuncClosure;
typedef struct _GeeFunctionsCompareDataFuncClosureClass GeeFunctionsCompareDataFuncClosureClass;
enum  {
	GEE_TREE_SET_0_PROPERTY,
	GEE_TREE_SET_G_TYPE,
	GEE_TREE_SET_G_DUP_FUNC,
	GEE_TREE_SET_G_DESTROY_FUNC,
	GEE_TREE_SET_SIZE_PROPERTY,
	GEE_TREE_SET_READ_ONLY_PROPERTY,
	GEE_TREE_SET_NUM_PROPERTIES
};
static GParamSpec* gee_tree_set_properties[GEE_TREE_SET_NUM_PROPERTIES];
typedef enum  {
	GEE_TREE_SET_RANGE_TYPE_HEAD,
	GEE_TREE_SET_RANGE_TYPE_TAIL,
	GEE_TREE_SET_RANGE_TYPE_EMPTY,
	GEE_TREE_SET_RANGE_TYPE_BOUNDED
} GeeTreeSetRangeType;

#define GEE_TREE_SET_TYPE_RANGE_TYPE (gee_tree_set_range_type_get_type ())
#define _gee_tree_set_node_free0(var) ((var == NULL) ? NULL : (var = (gee_tree_set_node_free (var), NULL)))
#define _gee_functions_compare_data_func_closure_unref0(var) ((var == NULL) ? NULL : (var = (gee_functions_compare_data_func_closure_unref (var), NULL)))
typedef enum  {
	GEE_TREE_SET_NODE_COLOR_RED,
	GEE_TREE_SET_NODE_COLOR_BLACK
} GeeTreeSetNodeColor;

#define GEE_TREE_SET_NODE_TYPE_COLOR (gee_tree_set_node_color_get_type ())

#define GEE_TREE_SET_TYPE_ITERATOR (gee_tree_set_iterator_get_type ())
#define GEE_TREE_SET_ITERATOR(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GEE_TREE_SET_TYPE_ITERATOR, GeeTreeSetIterator))
#define GEE_TREE_SET_ITERATOR_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GEE_TREE_SET_TYPE_ITERATOR, GeeTreeSetIteratorClass))
#define GEE_TREE_SET_IS_ITERATOR(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GEE_TREE_SET_TYPE_ITERATOR))
#define GEE_TREE_SET_IS_ITERATOR_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GEE_TREE_SET_TYPE_ITERATOR))
#define GEE_TREE_SET_ITERATOR_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GEE_TREE_SET_TYPE_ITERATOR, GeeTreeSetIteratorClass))

typedef struct _GeeTreeSetIterator GeeTreeSetIterator;
typedef struct _GeeTreeSetIteratorClass GeeTreeSetIteratorClass;

#define GEE_TREE_SET_TYPE_SUB_SET (gee_tree_set_sub_set_get_type ())
#define GEE_TREE_SET_SUB_SET(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GEE_TREE_SET_TYPE_SUB_SET, GeeTreeSetSubSet))
#define GEE_TREE_SET_SUB_SET_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GEE_TREE_SET_TYPE_SUB_SET, GeeTreeSetSubSetClass))
#define GEE_TREE_SET_IS_SUB_SET(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GEE_TREE_SET_TYPE_SUB_SET))
#define GEE_TREE_SET_IS_SUB_SET_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GEE_TREE_SET_TYPE_SUB_SET))
#define GEE_TREE_SET_SUB_SET_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GEE_TREE_SET_TYPE_SUB_SET, GeeTreeSetSubSetClass))

typedef struct _GeeTreeSetSubSet GeeTreeSetSubSet;
typedef struct _GeeTreeSetSubSetClass GeeTreeSetSubSetClass;
#define _g_object_unref0(var) ((var == NULL) ? NULL : (var = (g_object_unref (var), NULL)))
typedef struct _GeeFunctionsCompareDataFuncClosurePrivate GeeFunctionsCompareDataFuncClosurePrivate;
typedef struct _GeeTreeSetIteratorPrivate GeeTreeSetIteratorPrivate;
enum  {
	GEE_TREE_SET_ITERATOR_0_PROPERTY,
	GEE_TREE_SET_ITERATOR_G_TYPE,
	GEE_TREE_SET_ITERATOR_G_DUP_FUNC,
	GEE_TREE_SET_ITERATOR_G_DESTROY_FUNC,
	GEE_TREE_SET_ITERATOR_VALID_PROPERTY,
	GEE_TREE_SET_ITERATOR_READ_ONLY_PROPERTY,
	GEE_TREE_SET_ITERATOR_NUM_PROPERTIES
};
static GParamSpec* gee_tree_set_iterator_properties[GEE_TREE_SET_ITERATOR_NUM_PROPERTIES];

#define GEE_TREE_SET_TYPE_RANGE (gee_tree_set_range_get_type ())
#define GEE_TREE_SET_RANGE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GEE_TREE_SET_TYPE_RANGE, GeeTreeSetRange))
#define GEE_TREE_SET_RANGE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GEE_TREE_SET_TYPE_RANGE, GeeTreeSetRangeClass))
#define GEE_TREE_SET_IS_RANGE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GEE_TREE_SET_TYPE_RANGE))
#define GEE_TREE_SET_IS_RANGE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GEE_TREE_SET_TYPE_RANGE))
#define GEE_TREE_SET_RANGE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GEE_TREE_SET_TYPE_RANGE, GeeTreeSetRangeClass))

typedef struct _GeeTreeSetRange GeeTreeSetRange;
typedef struct _GeeTreeSetRangeClass GeeTreeSetRangeClass;
typedef struct _GeeTreeSetRangePrivate GeeTreeSetRangePrivate;
typedef struct _GeeTreeSetParamSpecRange GeeTreeSetParamSpecRange;
typedef struct _GeeTreeSetSubSetPrivate GeeTreeSetSubSetPrivate;
enum  {
	GEE_TREE_SET_SUB_SET_0_PROPERTY,
	GEE_TREE_SET_SUB_SET_G_TYPE,
	GEE_TREE_SET_SUB_SET_G_DUP_FUNC,
	GEE_TREE_SET_SUB_SET_G_DESTROY_FUNC,
	GEE_TREE_SET_SUB_SET_SIZE_PROPERTY,
	GEE_TREE_SET_SUB_SET_READ_ONLY_PROPERTY,
	GEE_TREE_SET_SUB_SET_IS_EMPTY_PROPERTY,
	GEE_TREE_SET_SUB_SET_NUM_PROPERTIES
};
static GParamSpec* gee_tree_set_sub_set_properties[GEE_TREE_SET_SUB_SET_NUM_PROPERTIES];
#define _gee_tree_set_range_unref0(var) ((var == NULL) ? NULL : (var = (gee_tree_set_range_unref (var), NULL)))

#define GEE_TREE_SET_TYPE_SUB_ITERATOR (gee_tree_set_sub_iterator_get_type ())
#define GEE_TREE_SET_SUB_ITERATOR(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GEE_TREE_SET_TYPE_SUB_ITERATOR, GeeTreeSetSubIterator))
#define GEE_TREE_SET_SUB_ITERATOR_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GEE_TREE_SET_TYPE_SUB_ITERATOR, GeeTreeSetSubIteratorClass))
#define GEE_TREE_SET_IS_SUB_ITERATOR(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GEE_TREE_SET_TYPE_SUB_ITERATOR))
#define GEE_TREE_SET_IS_SUB_ITERATOR_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GEE_TREE_SET_TYPE_SUB_ITERATOR))
#define GEE_TREE_SET_SUB_ITERATOR_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GEE_TREE_SET_TYPE_SUB_ITERATOR, GeeTreeSetSubIteratorClass))

typedef struct _GeeTreeSetSubIterator GeeTreeSetSubIterator;
typedef struct _GeeTreeSetSubIteratorClass GeeTreeSetSubIteratorClass;
typedef struct _GeeTreeSetSubIteratorPrivate GeeTreeSetSubIteratorPrivate;
enum  {
	GEE_TREE_SET_SUB_ITERATOR_0_PROPERTY,
	GEE_TREE_SET_SUB_ITERATOR_G_TYPE,
	GEE_TREE_SET_SUB_ITERATOR_G_DUP_FUNC,
	GEE_TREE_SET_SUB_ITERATOR_G_DESTROY_FUNC,
	GEE_TREE_SET_SUB_ITERATOR_READ_ONLY_PROPERTY,
	GEE_TREE_SET_SUB_ITERATOR_VALID_PROPERTY,
	GEE_TREE_SET_SUB_ITERATOR_NUM_PROPERTIES
};
static GParamSpec* gee_tree_set_sub_iterator_properties[GEE_TREE_SET_SUB_ITERATOR_NUM_PROPERTIES];
#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 _GeeTreeSetPrivate {
	GType g_type;
	GBoxedCopyFunc g_dup_func;
	GDestroyNotify g_destroy_func;
	gint _size;
	GeeTreeSetNode* root;
	GeeTreeSetNode* _first;
	GeeTreeSetNode* _last;
	gint stamp;
	GeeFunctionsCompareDataFuncClosure* _compare_func;
};

struct _GeeTreeSetNode {
	gpointer key;
	GeeTreeSetNodeColor color;
	GeeTreeSetNode* left;
	GeeTreeSetNode* right;
	GeeTreeSetNode* prev;
	GeeTreeSetNode* next;
};

struct _GeeFunctionsCompareDataFuncClosure {
	GTypeInstance parent_instance;
	volatile int ref_count;
	GeeFunctionsCompareDataFuncClosurePrivate * priv;
	GCompareDataFunc func;
	gpointer func_target;
	GDestroyNotify func_target_destroy_notify;
};

struct _GeeFunctionsCompareDataFuncClosureClass {
	GTypeClass parent_class;
	void (*finalize) (GeeFunctionsCompareDataFuncClosure *self);
};

struct _GeeTreeSetIterator {
	GObject parent_instance;
	GeeTreeSetIteratorPrivate * priv;
	GeeTreeSet* _set;
	gint stamp;
	GeeTreeSetNode* _current;
	GeeTreeSetNode* _next;
	GeeTreeSetNode* _prev;
	gboolean started;
};

struct _GeeTreeSetIteratorClass {
	GObjectClass parent_class;
};

struct _GeeTreeSetIteratorPrivate {
	GType g_type;
	GBoxedCopyFunc g_dup_func;
	GDestroyNotify g_destroy_func;
};

struct _GeeTreeSetRange {
	GTypeInstance parent_instance;
	volatile int ref_count;
	GeeTreeSetRangePrivate * priv;
};

struct _GeeTreeSetRangeClass {
	GTypeClass parent_class;
	void (*finalize) (GeeTreeSetRange *self);
};

struct _GeeTreeSetRangePrivate {
	GType g_type;
	GBoxedCopyFunc g_dup_func;
	GDestroyNotify g_destroy_func;
	GeeTreeSet* set;
	gpointer after;
	gpointer before;
	GeeTreeSetRangeType type;
};

struct _GeeTreeSetParamSpecRange {
	GParamSpec parent_instance;
};

struct _GeeTreeSetSubSet {
	GeeAbstractBidirSortedSet parent_instance;
	GeeTreeSetSubSetPrivate * priv;
	GeeTreeSet* set;
	GeeTreeSetRange* range;
};

struct _GeeTreeSetSubSetClass {
	GeeAbstractBidirSortedSetClass parent_class;
};

struct _GeeTreeSetSubSetPrivate {
	GType g_type;
	GBoxedCopyFunc g_dup_func;
	GDestroyNotify g_destroy_func;
};

struct _GeeTreeSetSubIterator {
	GObject parent_instance;
	GeeTreeSetSubIteratorPrivate * priv;
	GeeTreeSet* set;
	GeeTreeSetRange* range;
	GeeTreeSetIterator* iterator;
};

struct _GeeTreeSetSubIteratorClass {
	GObjectClass parent_class;
};

struct _GeeTreeSetSubIteratorPrivate {
	GType g_type;
	GBoxedCopyFunc g_dup_func;
	GDestroyNotify g_destroy_func;
};

static gint GeeTreeSet_private_offset;
static gpointer gee_tree_set_parent_class = NULL;
static gint GeeTreeSetIterator_private_offset;
static gpointer gee_tree_set_iterator_parent_class = NULL;
static GeeTraversableIface * gee_tree_set_iterator_gee_traversable_parent_iface = NULL;
static GeeIteratorIface * gee_tree_set_iterator_gee_iterator_parent_iface = NULL;
static GeeBidirIteratorIface * gee_tree_set_iterator_gee_bidir_iterator_parent_iface = NULL;
static gint GeeTreeSetRange_private_offset;
static gpointer gee_tree_set_range_parent_class = NULL;
static gint GeeTreeSetSubSet_private_offset;
static gpointer gee_tree_set_sub_set_parent_class = NULL;
static gint GeeTreeSetSubIterator_private_offset;
static gpointer gee_tree_set_sub_iterator_parent_class = NULL;
static GeeTraversableIface * gee_tree_set_sub_iterator_gee_traversable_parent_iface = NULL;
static GeeIteratorIface * gee_tree_set_sub_iterator_gee_iterator_parent_iface = NULL;
static GeeBidirIteratorIface * gee_tree_set_sub_iterator_gee_bidir_iterator_parent_iface = NULL;

static void gee_tree_set_node_free (GeeTreeSetNode * self);
 G_GNUC_INTERNAL gpointer gee_functions_compare_data_func_closure_ref (gpointer instance);
 G_GNUC_INTERNAL void gee_functions_compare_data_func_closure_unref (gpointer instance);
 G_GNUC_INTERNAL GParamSpec* gee_functions_param_spec_compare_data_func_closure (const gchar* name,
                                                                const gchar* nick,
                                                                const gchar* blurb,
                                                                GType object_type,
                                                                GParamFlags flags);
 G_GNUC_INTERNAL void gee_functions_value_set_compare_data_func_closure (GValue* value,
                                                        gpointer v_object) G_GNUC_UNUSED ;
 G_GNUC_INTERNAL void gee_functions_value_take_compare_data_func_closure (GValue* value,
                                                         gpointer v_object);
 G_GNUC_INTERNAL gpointer gee_functions_value_get_compare_data_func_closure (const GValue* value) G_GNUC_UNUSED ;
 G_GNUC_INTERNAL GType gee_functions_compare_data_func_closure_get_type (void) G_GNUC_CONST  G_GNUC_UNUSED ;
static GType gee_tree_set_range_type_get_type (void) G_GNUC_CONST  G_GNUC_UNUSED ;
 G_GNUC_INTERNAL GeeFunctionsCompareDataFuncClosure* gee_functions_compare_data_func_closure_new (GType g_type,
                                                                                 GBoxedCopyFunc g_dup_func,
                                                                                 GDestroyNotify g_destroy_func,
                                                                                 GCompareDataFunc func,
                                                                                 gpointer func_target,
                                                                                 GDestroyNotify func_target_destroy_notify);
 G_GNUC_INTERNAL GeeFunctionsCompareDataFuncClosure* gee_functions_compare_data_func_closure_construct (GType object_type,
                                                                                       GType g_type,
                                                                                       GBoxedCopyFunc g_dup_func,
                                                                                       GDestroyNotify g_destroy_func,
                                                                                       GCompareDataFunc func,
                                                                                       gpointer func_target,
                                                                                       GDestroyNotify func_target_destroy_notify);
 G_GNUC_INTERNAL GeeTreeSet* gee_tree_set_new_with_closures (GType g_type,
                                            GBoxedCopyFunc g_dup_func,
                                            GDestroyNotify g_destroy_func,
                                            GeeFunctionsCompareDataFuncClosure* compare_func);
 G_GNUC_INTERNAL GeeTreeSet* gee_tree_set_construct_with_closures (GType object_type,
                                                  GType g_type,
                                                  GBoxedCopyFunc g_dup_func,
                                                  GDestroyNotify g_destroy_func,
                                                  GeeFunctionsCompareDataFuncClosure* compare_func);
static gboolean gee_tree_set_real_contains (GeeAbstractCollection* base,
                                     gconstpointer item);
static GType gee_tree_set_node_color_get_type (void) G_GNUC_CONST  G_GNUC_UNUSED ;
static inline void gee_tree_set_rotate_right (GeeTreeSet* self,
                                GeeTreeSetNode** root);
static inline void gee_tree_set_rotate_left (GeeTreeSet* self,
                               GeeTreeSetNode** root);
static inline gboolean gee_tree_set_is_red (GeeTreeSet* self,
                              GeeTreeSetNode* n);
static inline gboolean gee_tree_set_is_black (GeeTreeSet* self,
                                GeeTreeSetNode* n);
static inline void gee_tree_set_fix_up (GeeTreeSet* self,
                          GeeTreeSetNode** node);
static void gee_tree_set_node_flip (GeeTreeSetNode* self);
static gboolean gee_tree_set_add_to_node (GeeTreeSet* self,
                                   GeeTreeSetNode** node,
                                   gpointer item,
                                   GeeTreeSetNode* prev,
                                   GeeTreeSetNode* next);
static GeeTreeSetNode* gee_tree_set_node_new (gpointer node,
                                       GeeTreeSetNode* prev,
                                       GeeTreeSetNode* next);
static gboolean gee_tree_set_real_add (GeeAbstractCollection* base,
                                gconstpointer item);
static inline void gee_tree_set_move_red_left (GeeTreeSet* self,
                                 GeeTreeSetNode** root);
static inline void gee_tree_set_move_red_right (GeeTreeSet* self,
                                  GeeTreeSetNode** root);
static inline void gee_tree_set_fix_removal (GeeTreeSet* self,
                               GeeTreeSetNode** node,
                               gpointer* key);
static void gee_tree_set_remove_minimal (GeeTreeSet* self,
                                  GeeTreeSetNode** node,
                                  gpointer* key);
static gboolean gee_tree_set_remove_from_node (GeeTreeSet* self,
                                        GeeTreeSetNode** node,
                                        gconstpointer item,
                                        GeeTreeSetNode** prev,
                                        GeeTreeSetNode** next);
static gboolean gee_tree_set_real_remove (GeeAbstractCollection* base,
                                   gconstpointer item);
static inline void gee_tree_set_clear_subtree (GeeTreeSet* self,
                                 GeeTreeSetNode* node);
static void gee_tree_set_real_clear (GeeAbstractCollection* base);
static gboolean gee_tree_set_real_foreach (GeeAbstractCollection* base,
                                    GeeForallFunc f,
                                    gpointer f_target);
static GeeIterator* gee_tree_set_real_iterator (GeeAbstractCollection* base);
static GeeTreeSetIterator* gee_tree_set_iterator_new (GType g_type,
                                               GBoxedCopyFunc g_dup_func,
                                               GDestroyNotify g_destroy_func,
                                               GeeTreeSet* set);
static GeeTreeSetIterator* gee_tree_set_iterator_construct (GType object_type,
                                                     GType g_type,
                                                     GBoxedCopyFunc g_dup_func,
                                                     GDestroyNotify g_destroy_func,
                                                     GeeTreeSet* set);
static GType gee_tree_set_iterator_get_type (void) G_GNUC_CONST  G_GNUC_UNUSED ;
static GeeBidirIterator* gee_tree_set_real_bidir_iterator (GeeAbstractBidirSortedSet* base);
static inline gpointer gee_tree_set_lift_null_get (GeeTreeSet* self,
                                     GeeTreeSetNode* node);
static gpointer gee_tree_set_real_first (GeeAbstractSortedSet* base);
static gpointer gee_tree_set_real_last (GeeAbstractSortedSet* base);
static GeeSortedSet* gee_tree_set_real_head_set (GeeAbstractSortedSet* base,
                                          gconstpointer before);
static GeeTreeSetSubSet* gee_tree_set_sub_set_new_head (GType g_type,
                                                 GBoxedCopyFunc g_dup_func,
                                                 GDestroyNotify g_destroy_func,
                                                 GeeTreeSet* set,
                                                 gconstpointer before);
static GeeTreeSetSubSet* gee_tree_set_sub_set_construct_head (GType object_type,
                                                       GType g_type,
                                                       GBoxedCopyFunc g_dup_func,
                                                       GDestroyNotify g_destroy_func,
                                                       GeeTreeSet* set,
                                                       gconstpointer before);
static GType gee_tree_set_sub_set_get_type (void) G_GNUC_CONST  G_GNUC_UNUSED ;
static GeeSortedSet* gee_tree_set_real_tail_set (GeeAbstractSortedSet* base,
                                          gconstpointer after);
static GeeTreeSetSubSet* gee_tree_set_sub_set_new_tail (GType g_type,
                                                 GBoxedCopyFunc g_dup_func,
                                                 GDestroyNotify g_destroy_func,
                                                 GeeTreeSet* set,
                                                 gconstpointer after);
static GeeTreeSetSubSet* gee_tree_set_sub_set_construct_tail (GType object_type,
                                                       GType g_type,
                                                       GBoxedCopyFunc g_dup_func,
                                                       GDestroyNotify g_destroy_func,
                                                       GeeTreeSet* set,
                                                       gconstpointer after);
static GeeSortedSet* gee_tree_set_real_sub_set (GeeAbstractSortedSet* base,
                                         gconstpointer after,
                                         gconstpointer before);
static GeeTreeSetSubSet* gee_tree_set_sub_set_new (GType g_type,
                                            GBoxedCopyFunc g_dup_func,
                                            GDestroyNotify g_destroy_func,
                                            GeeTreeSet* set,
                                            gconstpointer after,
                                            gconstpointer before);
static GeeTreeSetSubSet* gee_tree_set_sub_set_construct (GType object_type,
                                                  GType g_type,
                                                  GBoxedCopyFunc g_dup_func,
                                                  GDestroyNotify g_destroy_func,
                                                  GeeTreeSet* set,
                                                  gconstpointer after,
                                                  gconstpointer before);
static inline GeeTreeSetNode* gee_tree_set_find_node (GeeTreeSet* self,
                                        gconstpointer item);
static GeeIterator* gee_tree_set_real_iterator_at (GeeAbstractSortedSet* base,
                                            gconstpointer item);
static GeeTreeSetIterator* gee_tree_set_iterator_new_pointing (GType g_type,
                                                        GBoxedCopyFunc g_dup_func,
                                                        GDestroyNotify g_destroy_func,
                                                        GeeTreeSet* set,
                                                        GeeTreeSetNode* current);
static GeeTreeSetIterator* gee_tree_set_iterator_construct_pointing (GType object_type,
                                                              GType g_type,
                                                              GBoxedCopyFunc g_dup_func,
                                                              GDestroyNotify g_destroy_func,
                                                              GeeTreeSet* set,
                                                              GeeTreeSetNode* current);
static inline GeeTreeSetNode* gee_tree_set_find_nearest (GeeTreeSet* self,
                                           gconstpointer item);
static inline GeeTreeSetNode* gee_tree_set_find_lower (GeeTreeSet* self,
                                         gconstpointer item);
static inline GeeTreeSetNode* gee_tree_set_find_higher (GeeTreeSet* self,
                                          gconstpointer item);
static inline GeeTreeSetNode* gee_tree_set_find_floor (GeeTreeSet* self,
                                         gconstpointer item);
static inline GeeTreeSetNode* gee_tree_set_find_ceil (GeeTreeSet* self,
                                        gconstpointer item);
static gpointer gee_tree_set_real_lower (GeeAbstractSortedSet* base,
                                  gconstpointer item);
static gpointer gee_tree_set_real_higher (GeeAbstractSortedSet* base,
                                   gconstpointer item);
static gpointer gee_tree_set_real_floor (GeeAbstractSortedSet* base,
                                  gconstpointer item);
static gpointer gee_tree_set_real_ceil (GeeAbstractSortedSet* base,
                                 gconstpointer item);
static inline gpointer gee_tree_set_min (GeeTreeSet* self,
                           gconstpointer a,
                           gconstpointer b);
static inline gpointer gee_tree_set_max (GeeTreeSet* self,
                           gconstpointer a,
                           gconstpointer b);
static void gee_tree_set_set_compare_func (GeeTreeSet* self,
                                    GCompareDataFunc value,
                                    gpointer value_target);
static void gee_tree_set_node_instance_init (GeeTreeSetNode * self);
static GeeTreeSetNodeColor gee_tree_set_node_color_flip (GeeTreeSetNodeColor self);
static GeeTreeSetIterator* gee_tree_set_iterator_new_from_iterator (GType g_type,
                                                             GBoxedCopyFunc g_dup_func,
                                                             GDestroyNotify g_destroy_func,
                                                             GeeTreeSetIterator* iter);
static GeeTreeSetIterator* gee_tree_set_iterator_construct_from_iterator (GType object_type,
                                                                   GType g_type,
                                                                   GBoxedCopyFunc g_dup_func,
                                                                   GDestroyNotify g_destroy_func,
                                                                   GeeTreeSetIterator* iter);
static gboolean gee_tree_set_iterator_real_next (GeeIterator* base);
static gboolean gee_tree_set_iterator_real_has_next (GeeIterator* base);
static gboolean gee_tree_set_iterator_real_first (GeeBidirIterator* base);
static gboolean gee_tree_set_iterator_real_previous (GeeBidirIterator* base);
static gboolean gee_tree_set_iterator_real_has_previous (GeeBidirIterator* base);
static gboolean gee_tree_set_iterator_real_last (GeeBidirIterator* base);
static gpointer gee_tree_set_iterator_real_get (GeeIterator* base);
static void gee_tree_set_iterator_real_remove (GeeIterator* base);
static gboolean gee_tree_set_iterator_safe_next_get (GeeTreeSetIterator* self,
                                              gpointer* val);
static gboolean gee_tree_set_iterator_safe_previous_get (GeeTreeSetIterator* self,
                                                  gpointer* val);
static gboolean gee_tree_set_iterator_real_foreach (GeeTraversable* base,
                                             GeeForallFunc f,
                                             gpointer f_target);
static GeeIterator** gee_tree_set_iterator_real_tee (GeeTraversable* base,
                                              guint forks,
                                              gint* result_length1);
static void gee_tree_set_iterator_finalize (GObject * obj);
static GType gee_tree_set_iterator_get_type_once (void);
static void _vala_gee_tree_set_iterator_get_property (GObject * object,
                                               guint property_id,
                                               GValue * value,
                                               GParamSpec * pspec);
static void _vala_gee_tree_set_iterator_set_property (GObject * object,
                                               guint property_id,
                                               const GValue * value,
                                               GParamSpec * pspec);
static gpointer gee_tree_set_range_ref (gpointer instance);
static void gee_tree_set_range_unref (gpointer instance);
static GParamSpec* gee_tree_set_param_spec_range (const gchar* name,
                                           const gchar* nick,
                                           const gchar* blurb,
                                           GType object_type,
                                           GParamFlags flags) G_GNUC_UNUSED ;
static void gee_tree_set_value_set_range (GValue* value,
                                   gpointer v_object) G_GNUC_UNUSED ;
static void gee_tree_set_value_take_range (GValue* value,
                                    gpointer v_object) G_GNUC_UNUSED ;
static gpointer gee_tree_set_value_get_range (const GValue* value) G_GNUC_UNUSED ;
static GType gee_tree_set_range_get_type (void) G_GNUC_CONST  G_GNUC_UNUSED ;
static GeeTreeSetRange* gee_tree_set_range_new (GType g_type,
                                         GBoxedCopyFunc g_dup_func,
                                         GDestroyNotify g_destroy_func,
                                         GeeTreeSet* set,
                                         gconstpointer after,
                                         gconstpointer before);
static GeeTreeSetRange* gee_tree_set_range_construct (GType object_type,
                                               GType g_type,
                                               GBoxedCopyFunc g_dup_func,
                                               GDestroyNotify g_destroy_func,
                                               GeeTreeSet* set,
                                               gconstpointer after,
                                               gconstpointer before);
static GeeTreeSetRange* gee_tree_set_range_new_head (GType g_type,
                                              GBoxedCopyFunc g_dup_func,
                                              GDestroyNotify g_destroy_func,
                                              GeeTreeSet* set,
                                              gconstpointer before);
static GeeTreeSetRange* gee_tree_set_range_construct_head (GType object_type,
                                                    GType g_type,
                                                    GBoxedCopyFunc g_dup_func,
                                                    GDestroyNotify g_destroy_func,
                                                    GeeTreeSet* set,
                                                    gconstpointer before);
static GeeTreeSetRange* gee_tree_set_range_new_tail (GType g_type,
                                              GBoxedCopyFunc g_dup_func,
                                              GDestroyNotify g_destroy_func,
                                              GeeTreeSet* set,
                                              gconstpointer after);
static GeeTreeSetRange* gee_tree_set_range_construct_tail (GType object_type,
                                                    GType g_type,
                                                    GBoxedCopyFunc g_dup_func,
                                                    GDestroyNotify g_destroy_func,
                                                    GeeTreeSet* set,
                                                    gconstpointer after);
static GeeTreeSetRange* gee_tree_set_range_cut_head (GeeTreeSetRange* self,
                                              gconstpointer after);
static GeeTreeSetRange* gee_tree_set_range_cut_tail (GeeTreeSetRange* self,
                                              gconstpointer before);
static GeeTreeSetRange* gee_tree_set_range_cut (GeeTreeSetRange* self,
                                         gconstpointer after,
                                         gconstpointer before);
static gboolean gee_tree_set_range_in_range (GeeTreeSetRange* self,
                                      gconstpointer item);
static gint gee_tree_set_range_compare_range (GeeTreeSetRange* self,
                                       gconstpointer item);
static gboolean gee_tree_set_range_empty_subset (GeeTreeSetRange* self);
static GeeTreeSetNode* gee_tree_set_range_first (GeeTreeSetRange* self);
static GeeTreeSetNode* gee_tree_set_range_last (GeeTreeSetRange* self);
static void gee_tree_set_range_finalize (GeeTreeSetRange * obj);
static GType gee_tree_set_range_get_type_once (void);
static GeeTreeSetSubSet* gee_tree_set_sub_set_new_from_range (GType g_type,
                                                       GBoxedCopyFunc g_dup_func,
                                                       GDestroyNotify g_destroy_func,
                                                       GeeTreeSet* set,
                                                       GeeTreeSetRange* range);
static GeeTreeSetSubSet* gee_tree_set_sub_set_construct_from_range (GType object_type,
                                                             GType g_type,
                                                             GBoxedCopyFunc g_dup_func,
                                                             GDestroyNotify g_destroy_func,
                                                             GeeTreeSet* set,
                                                             GeeTreeSetRange* range);
static gboolean gee_tree_set_sub_set_real_contains (GeeAbstractCollection* base,
                                             gconstpointer item);
static gboolean gee_tree_set_sub_set_real_add (GeeAbstractCollection* base,
                                        gconstpointer item);
static gboolean gee_tree_set_sub_set_real_remove (GeeAbstractCollection* base,
                                           gconstpointer item);
static void gee_tree_set_sub_set_real_clear (GeeAbstractCollection* base);
static GeeIterator* gee_tree_set_sub_set_real_iterator (GeeAbstractCollection* base);
static GeeTreeSetSubIterator* gee_tree_set_sub_iterator_new (GType g_type,
                                                      GBoxedCopyFunc g_dup_func,
                                                      GDestroyNotify g_destroy_func,
                                                      GeeTreeSet* set,
                                                      GeeTreeSetRange* range);
static GeeTreeSetSubIterator* gee_tree_set_sub_iterator_construct (GType object_type,
                                                            GType g_type,
                                                            GBoxedCopyFunc g_dup_func,
                                                            GDestroyNotify g_destroy_func,
                                                            GeeTreeSet* set,
                                                            GeeTreeSetRange* range);
static GType gee_tree_set_sub_iterator_get_type (void) G_GNUC_CONST  G_GNUC_UNUSED ;
static GeeBidirIterator* gee_tree_set_sub_set_real_bidir_iterator (GeeAbstractBidirSortedSet* base);
static gpointer gee_tree_set_sub_set_real_first (GeeAbstractSortedSet* base);
static gpointer gee_tree_set_sub_set_real_last (GeeAbstractSortedSet* base);
static GeeSortedSet* gee_tree_set_sub_set_real_head_set (GeeAbstractSortedSet* base,
                                                  gconstpointer before);
static GeeSortedSet* gee_tree_set_sub_set_real_tail_set (GeeAbstractSortedSet* base,
                                                  gconstpointer after);
static GeeSortedSet* gee_tree_set_sub_set_real_sub_set (GeeAbstractSortedSet* base,
                                                 gconstpointer after,
                                                 gconstpointer before);
static GeeIterator* gee_tree_set_sub_set_real_iterator_at (GeeAbstractSortedSet* base,
                                                    gconstpointer item);
static GeeTreeSetSubIterator* gee_tree_set_sub_iterator_new_pointing (GType g_type,
                                                               GBoxedCopyFunc g_dup_func,
                                                               GDestroyNotify g_destroy_func,
                                                               GeeTreeSet* set,
                                                               GeeTreeSetRange* range,
                                                               GeeTreeSetNode* node);
static GeeTreeSetSubIterator* gee_tree_set_sub_iterator_construct_pointing (GType object_type,
                                                                     GType g_type,
                                                                     GBoxedCopyFunc g_dup_func,
                                                                     GDestroyNotify g_destroy_func,
                                                                     GeeTreeSet* set,
                                                                     GeeTreeSetRange* range,
                                                                     GeeTreeSetNode* node);
static gpointer gee_tree_set_sub_set_real_lower (GeeAbstractSortedSet* base,
                                          gconstpointer item);
static gpointer gee_tree_set_sub_set_real_higher (GeeAbstractSortedSet* base,
                                           gconstpointer item);
static gpointer gee_tree_set_sub_set_real_floor (GeeAbstractSortedSet* base,
                                          gconstpointer item);
static gpointer gee_tree_set_sub_set_real_ceil (GeeAbstractSortedSet* base,
                                         gconstpointer item);
static gboolean gee_tree_set_sub_set_get_is_empty (GeeTreeSetSubSet* self);
static void gee_tree_set_sub_set_finalize (GObject * obj);
static GType gee_tree_set_sub_set_get_type_once (void);
static void _vala_gee_tree_set_sub_set_get_property (GObject * object,
                                              guint property_id,
                                              GValue * value,
                                              GParamSpec * pspec);
static void _vala_gee_tree_set_sub_set_set_property (GObject * object,
                                              guint property_id,
                                              const GValue * value,
                                              GParamSpec * pspec);
static GeeTreeSetSubIterator* gee_tree_set_sub_iterator_new_from_iterator (GType g_type,
                                                                    GBoxedCopyFunc g_dup_func,
                                                                    GDestroyNotify g_destroy_func,
                                                                    GeeTreeSetSubIterator* iter);
static GeeTreeSetSubIterator* gee_tree_set_sub_iterator_construct_from_iterator (GType object_type,
                                                                          GType g_type,
                                                                          GBoxedCopyFunc g_dup_func,
                                                                          GDestroyNotify g_destroy_func,
                                                                          GeeTreeSetSubIterator* iter);
static gboolean gee_tree_set_sub_iterator_real_next (GeeIterator* base);
static gboolean gee_tree_set_sub_iterator_real_has_next (GeeIterator* base);
static gboolean gee_tree_set_sub_iterator_real_first (GeeBidirIterator* base);
static gboolean gee_tree_set_sub_iterator_real_previous (GeeBidirIterator* base);
static gboolean gee_tree_set_sub_iterator_real_has_previous (GeeBidirIterator* base);
static gboolean gee_tree_set_sub_iterator_real_last (GeeBidirIterator* base);
static gpointer gee_tree_set_sub_iterator_real_get (GeeIterator* base);
static void gee_tree_set_sub_iterator_real_remove (GeeIterator* base);
static gboolean gee_tree_set_sub_iterator_real_foreach (GeeTraversable* base,
                                                 GeeForallFunc f,
                                                 gpointer f_target);
static GeeIterator** gee_tree_set_sub_iterator_real_tee (GeeTraversable* base,
                                                  guint forks,
                                                  gint* result_length1);
static void gee_tree_set_sub_iterator_finalize (GObject * obj);
static GType gee_tree_set_sub_iterator_get_type_once (void);
static void _vala_gee_tree_set_sub_iterator_get_property (GObject * object,
                                                   guint property_id,
                                                   GValue * value,
                                                   GParamSpec * pspec);
static void _vala_gee_tree_set_sub_iterator_set_property (GObject * object,
                                                   guint property_id,
                                                   const GValue * value,
                                                   GParamSpec * pspec);
static void gee_tree_set_finalize (GObject * obj);
static GType gee_tree_set_get_type_once (void);
static void _vala_gee_tree_set_get_property (GObject * object,
                                      guint property_id,
                                      GValue * value,
                                      GParamSpec * pspec);
static void _vala_gee_tree_set_set_property (GObject * object,
                                      guint property_id,
                                      const GValue * value,
                                      GParamSpec * pspec);
static void _vala_array_destroy (gpointer array,
                          gssize array_length,
                          GDestroyNotify destroy_func);
static void _vala_array_free (gpointer array,
                       gssize array_length,
                       GDestroyNotify destroy_func);

static inline gpointer
gee_tree_set_get_instance_private (GeeTreeSet* self)
{
	return G_STRUCT_MEMBER_P (self, GeeTreeSet_private_offset);
}

static GType
gee_tree_set_range_type_get_type_once (void)
{
	static const GEnumValue values[] = {{GEE_TREE_SET_RANGE_TYPE_HEAD, "GEE_TREE_SET_RANGE_TYPE_HEAD", "head"}, {GEE_TREE_SET_RANGE_TYPE_TAIL, "GEE_TREE_SET_RANGE_TYPE_TAIL", "tail"}, {GEE_TREE_SET_RANGE_TYPE_EMPTY, "GEE_TREE_SET_RANGE_TYPE_EMPTY", "empty"}, {GEE_TREE_SET_RANGE_TYPE_BOUNDED, "GEE_TREE_SET_RANGE_TYPE_BOUNDED", "bounded"}, {0, NULL, NULL}};
	GType gee_tree_set_range_type_type_id;
	gee_tree_set_range_type_type_id = g_enum_register_static ("GeeTreeSetRangeType", values);
	return gee_tree_set_range_type_type_id;
}

static GType
gee_tree_set_range_type_get_type (void)
{
	static volatile gsize gee_tree_set_range_type_type_id__once = 0;
	if (g_once_init_enter (&gee_tree_set_range_type_type_id__once)) {
		GType gee_tree_set_range_type_type_id;
		gee_tree_set_range_type_type_id = gee_tree_set_range_type_get_type_once ();
		g_once_init_leave (&gee_tree_set_range_type_type_id__once, gee_tree_set_range_type_type_id);
	}
	return gee_tree_set_range_type_type_id__once;
}

/**
 * Constructs a new, empty tree set sorted according to the specified
 * comparator function.
 *
 * If not provided, the function parameter is requested to the
 * {@link Functions} function factory methods.
 *
 * @param compare_func an optional element comparator function
 */
GeeTreeSet*
gee_tree_set_construct (GType object_type,
                        GType g_type,
                        GBoxedCopyFunc g_dup_func,
                        GDestroyNotify g_destroy_func,
                        GCompareDataFunc compare_func,
                        gpointer compare_func_target,
                        GDestroyNotify compare_func_target_destroy_notify)
{
	GeeTreeSet * self = NULL;
	GCompareDataFunc _tmp3_;
	gpointer _tmp3__target;
	GDestroyNotify _tmp3__target_destroy_notify;
	GeeFunctionsCompareDataFuncClosure* _tmp4_;
	self = (GeeTreeSet*) gee_abstract_bidir_sorted_set_construct (object_type, g_type, (GBoxedCopyFunc) g_dup_func, (GDestroyNotify) g_destroy_func);
	self->priv->g_type = g_type;
	self->priv->g_dup_func = g_dup_func;
	self->priv->g_destroy_func = g_destroy_func;
	if (compare_func == NULL) {
		gpointer _tmp0_ = NULL;
		GDestroyNotify _tmp1_ = NULL;
		GCompareDataFunc _tmp2_;
		_tmp2_ = gee_functions_get_compare_func_for (g_type, &_tmp0_, &_tmp1_);
		(compare_func_target_destroy_notify == NULL) ? NULL : (compare_func_target_destroy_notify (compare_func_target), NULL);
		compare_func = NULL;
		compare_func_target = NULL;
		compare_func_target_destroy_notify = NULL;
		compare_func = _tmp2_;
		compare_func_target = _tmp0_;
		compare_func_target_destroy_notify = _tmp1_;
	}
	_tmp3_ = compare_func;
	_tmp3__target = compare_func_target;
	_tmp3__target_destroy_notify = compare_func_target_destroy_notify;
	compare_func = NULL;
	compare_func_target = NULL;
	compare_func_target_destroy_notify = NULL;
	_tmp4_ = gee_functions_compare_data_func_closure_new (g_type, (GBoxedCopyFunc) g_dup_func, (GDestroyNotify) g_destroy_func, _tmp3_, _tmp3__target, _tmp3__target_destroy_notify);
	_gee_functions_compare_data_func_closure_unref0 (self->priv->_compare_func);
	self->priv->_compare_func = _tmp4_;
	(compare_func_target_destroy_notify == NULL) ? NULL : (compare_func_target_destroy_notify (compare_func_target), NULL);
	compare_func = NULL;
	compare_func_target = NULL;
	compare_func_target_destroy_notify = NULL;
	return self;
}

GeeTreeSet*
gee_tree_set_new (GType g_type,
                  GBoxedCopyFunc g_dup_func,
                  GDestroyNotify g_destroy_func,
                  GCompareDataFunc compare_func,
                  gpointer compare_func_target,
                  GDestroyNotify compare_func_target_destroy_notify)
{
	return gee_tree_set_construct (GEE_TYPE_TREE_SET, g_type, g_dup_func, g_destroy_func, compare_func, compare_func_target, compare_func_target_destroy_notify);
}

 G_GNUC_INTERNAL GeeTreeSet*
gee_tree_set_construct_with_closures (GType object_type,
                                      GType g_type,
                                      GBoxedCopyFunc g_dup_func,
                                      GDestroyNotify g_destroy_func,
                                      GeeFunctionsCompareDataFuncClosure* compare_func)
{
	GeeTreeSet * self = NULL;
	GeeFunctionsCompareDataFuncClosure* _tmp0_;
	g_return_val_if_fail (compare_func != NULL, NULL);
	self = (GeeTreeSet*) gee_abstract_bidir_sorted_set_construct (object_type, g_type, (GBoxedCopyFunc) g_dup_func, (GDestroyNotify) g_destroy_func);
	self->priv->g_type = g_type;
	self->priv->g_dup_func = g_dup_func;
	self->priv->g_destroy_func = g_destroy_func;
	_tmp0_ = compare_func;
	compare_func = NULL;
	_gee_functions_compare_data_func_closure_unref0 (self->priv->_compare_func);
	self->priv->_compare_func = _tmp0_;
	_gee_functions_compare_data_func_closure_unref0 (compare_func);
	return self;
}

 G_GNUC_INTERNAL GeeTreeSet*
gee_tree_set_new_with_closures (GType g_type,
                                GBoxedCopyFunc g_dup_func,
                                GDestroyNotify g_destroy_func,
                                GeeFunctionsCompareDataFuncClosure* compare_func)
{
	return gee_tree_set_construct_with_closures (GEE_TYPE_TREE_SET, g_type, g_dup_func, g_destroy_func, compare_func);
}

/**
 * {@inheritDoc}
 */
static gboolean
gee_tree_set_real_contains (GeeAbstractCollection* base,
                            gconstpointer item)
{
	GeeTreeSet * self;
	GeeTreeSetNode* cur = NULL;
	GeeTreeSetNode* _tmp0_;
	gboolean result;
	self = (GeeTreeSet*) base;
	_tmp0_ = self->priv->root;
	cur = _tmp0_;
	while (TRUE) {
		GeeTreeSetNode* _tmp1_;
		gint res = 0;
		GCompareDataFunc _tmp2_ = NULL;
		gpointer _tmp2__target = NULL;
		GCompareDataFunc _tmp3_;
		gpointer _tmp3__target;
		GeeTreeSetNode* _tmp4_;
		gconstpointer _tmp5_;
		_tmp1_ = cur;
		if (!(_tmp1_ != NULL)) {
			break;
		}
		_tmp2_ = gee_tree_set_get_compare_func (self, &_tmp2__target);
		_tmp3_ = _tmp2_;
		_tmp3__target = _tmp2__target;
		_tmp4_ = cur;
		_tmp5_ = _tmp4_->key;
		res = _tmp3_ (item, _tmp5_, _tmp3__target);
		if (res == 0) {
			result = TRUE;
			return result;
		} else {
			if (res < 0) {
				GeeTreeSetNode* _tmp6_;
				GeeTreeSetNode* _tmp7_;
				_tmp6_ = cur;
				_tmp7_ = _tmp6_->left;
				cur = _tmp7_;
			} else {
				GeeTreeSetNode* _tmp8_;
				GeeTreeSetNode* _tmp9_;
				_tmp8_ = cur;
				_tmp9_ = _tmp8_->right;
				cur = _tmp9_;
			}
		}
	}
	result = FALSE;
	return result;
}

static inline void
gee_tree_set_rotate_right (GeeTreeSet* self,
                           GeeTreeSetNode** root)
{
	GeeTreeSetNode* pivot = NULL;
	GeeTreeSetNode* _tmp0_;
	GeeTreeSetNode* _tmp1_;
	GeeTreeSetNode* _tmp2_;
	GeeTreeSetNode* _tmp3_;
	GeeTreeSetNode* _tmp4_;
	GeeTreeSetNode* _tmp5_;
	GeeTreeSetNode* _tmp6_;
	g_return_if_fail (self != NULL);
	g_return_if_fail (*root != NULL);
	_tmp0_ = (*root)->left;
	(*root)->left = NULL;
	pivot = _tmp0_;
	_tmp1_ = pivot;
	_tmp1_->color = (*root)->color;
	(*root)->color = GEE_TREE_SET_NODE_COLOR_RED;
	_tmp2_ = pivot;
	_tmp3_ = _tmp2_->right;
	_tmp2_->right = NULL;
	_gee_tree_set_node_free0 ((*root)->left);
	(*root)->left = _tmp3_;
	_tmp4_ = pivot;
	_tmp5_ = *root;
	*root = NULL;
	_gee_tree_set_node_free0 (_tmp4_->right);
	_tmp4_->right = _tmp5_;
	_tmp6_ = pivot;
	pivot = NULL;
	_gee_tree_set_node_free0 (*root);
	*root = _tmp6_;
	_gee_tree_set_node_free0 (pivot);
}

static inline void
gee_tree_set_rotate_left (GeeTreeSet* self,
                          GeeTreeSetNode** root)
{
	GeeTreeSetNode* pivot = NULL;
	GeeTreeSetNode* _tmp0_;
	GeeTreeSetNode* _tmp1_;
	GeeTreeSetNode* _tmp2_;
	GeeTreeSetNode* _tmp3_;
	GeeTreeSetNode* _tmp4_;
	GeeTreeSetNode* _tmp5_;
	GeeTreeSetNode* _tmp6_;
	g_return_if_fail (self != NULL);
	g_return_if_fail (*root != NULL);
	_tmp0_ = (*root)->right;
	(*root)->right = NULL;
	pivot = _tmp0_;
	_tmp1_ = pivot;
	_tmp1_->color = (*root)->color;
	(*root)->color = GEE_TREE_SET_NODE_COLOR_RED;
	_tmp2_ = pivot;
	_tmp3_ = _tmp2_->left;
	_tmp2_->left = NULL;
	_gee_tree_set_node_free0 ((*root)->right);
	(*root)->right = _tmp3_;
	_tmp4_ = pivot;
	_tmp5_ = *root;
	*root = NULL;
	_gee_tree_set_node_free0 (_tmp4_->left);
	_tmp4_->left = _tmp5_;
	_tmp6_ = pivot;
	pivot = NULL;
	_gee_tree_set_node_free0 (*root);
	*root = _tmp6_;
	_gee_tree_set_node_free0 (pivot);
}

static inline gboolean
gee_tree_set_is_red (GeeTreeSet* self,
                     GeeTreeSetNode* n)
{
	gboolean _tmp0_ = FALSE;
	gboolean result;
	g_return_val_if_fail (self != NULL, FALSE);
	if (n != NULL) {
		_tmp0_ = n->color == GEE_TREE_SET_NODE_COLOR_RED;
	} else {
		_tmp0_ = FALSE;
	}
	result = _tmp0_;
	return result;
}

static inline gboolean
gee_tree_set_is_black (GeeTreeSet* self,
                       GeeTreeSetNode* n)
{
	gboolean _tmp0_ = FALSE;
	gboolean result;
	g_return_val_if_fail (self != NULL, FALSE);
	if (n == NULL) {
		_tmp0_ = TRUE;
	} else {
		_tmp0_ = n->color == GEE_TREE_SET_NODE_COLOR_BLACK;
	}
	result = _tmp0_;
	return result;
}

static inline void
gee_tree_set_fix_up (GeeTreeSet* self,
                     GeeTreeSetNode** node)
{
	gboolean _tmp0_ = FALSE;
	GeeTreeSetNode* _tmp1_;
	gboolean _tmp3_ = FALSE;
	GeeTreeSetNode* _tmp4_;
	gboolean _tmp7_ = FALSE;
	GeeTreeSetNode* _tmp8_;
	g_return_if_fail (self != NULL);
	g_return_if_fail (*node != NULL);
	_tmp1_ = (*node)->left;
	if (gee_tree_set_is_black (self, _tmp1_)) {
		GeeTreeSetNode* _tmp2_;
		_tmp2_ = (*node)->right;
		_tmp0_ = gee_tree_set_is_red (self, _tmp2_);
	} else {
		_tmp0_ = FALSE;
	}
	if (_tmp0_) {
		gee_tree_set_rotate_left (self, node);
	}
	_tmp4_ = (*node)->left;
	if (gee_tree_set_is_red (self, _tmp4_)) {
		GeeTreeSetNode* _tmp5_;
		GeeTreeSetNode* _tmp6_;
		_tmp5_ = (*node)->left;
		_tmp6_ = _tmp5_->left;
		_tmp3_ = gee_tree_set_is_red (self, _tmp6_);
	} else {
		_tmp3_ = FALSE;
	}
	if (_tmp3_) {
		gee_tree_set_rotate_right (self, node);
	}
	_tmp8_ = (*node)->left;
	if (gee_tree_set_is_red (self, _tmp8_)) {
		GeeTreeSetNode* _tmp9_;
		_tmp9_ = (*node)->right;
		_tmp7_ = gee_tree_set_is_red (self, _tmp9_);
	} else {
		_tmp7_ = FALSE;
	}
	if (_tmp7_) {
		gee_tree_set_node_flip (*node);
	}
}

static gboolean
gee_tree_set_add_to_node (GeeTreeSet* self,
                          GeeTreeSetNode** node,
                          gpointer item,
                          GeeTreeSetNode* prev,
                          GeeTreeSetNode* next)
{
	gint cmp = 0;
	GCompareDataFunc _tmp3_ = NULL;
	gpointer _tmp3__target = NULL;
	GCompareDataFunc _tmp4_;
	gpointer _tmp4__target;
	gconstpointer _tmp5_;
	gboolean result;
	g_return_val_if_fail (self != NULL, FALSE);
	if ((*node) == NULL) {
		gpointer _tmp0_;
		GeeTreeSetNode* _tmp1_;
		gint _tmp2_;
		_tmp0_ = item;
		item = NULL;
		_tmp1_ = gee_tree_set_node_new (_tmp0_, prev, next);
		_gee_tree_set_node_free0 (*node);
		*node = _tmp1_;
		if (prev == NULL) {
			self->priv->_first = *node;
		}
		if (next == NULL) {
			self->priv->_last = *node;
		}
		_tmp2_ = self->priv->_size;
		self->priv->_size = _tmp2_ + 1;
		result = TRUE;
		((item == NULL) || (self->priv->g_destroy_func == NULL)) ? NULL : (item = (self->priv->g_destroy_func (item), NULL));
		return result;
	}
	_tmp3_ = gee_tree_set_get_compare_func (self, &_tmp3__target);
	_tmp4_ = _tmp3_;
	_tmp4__target = _tmp3__target;
	_tmp5_ = (*node)->key;
	cmp = _tmp4_ (item, _tmp5_, _tmp4__target);
	if (cmp == 0) {
		gee_tree_set_fix_up (self, node);
		result = FALSE;
		((item == NULL) || (self->priv->g_destroy_func == NULL)) ? NULL : (item = (self->priv->g_destroy_func (item), NULL));
		return result;
	} else {
		if (cmp < 0) {
			gboolean r = FALSE;
			gpointer _tmp6_;
			GeeTreeSetNode* _tmp7_;
			gboolean _tmp8_;
			_tmp6_ = ((item != NULL) && (self->priv->g_dup_func != NULL)) ? self->priv->g_dup_func ((gpointer) item) : ((gpointer) item);
			_tmp7_ = (*node)->prev;
			_tmp8_ = gee_tree_set_add_to_node (self, &(*node)->left, _tmp6_, _tmp7_, *node);
			r = _tmp8_;
			gee_tree_set_fix_up (self, node);
			result = r;
			((item == NULL) || (self->priv->g_destroy_func == NULL)) ? NULL : (item = (self->priv->g_destroy_func (item), NULL));
			return result;
		} else {
			gboolean r = FALSE;
			gpointer _tmp9_;
			GeeTreeSetNode* _tmp10_;
			gboolean _tmp11_;
			_tmp9_ = ((item != NULL) && (self->priv->g_dup_func != NULL)) ? self->priv->g_dup_func ((gpointer) item) : ((gpointer) item);
			_tmp10_ = (*node)->next;
			_tmp11_ = gee_tree_set_add_to_node (self, &(*node)->right, _tmp9_, *node, _tmp10_);
			r = _tmp11_;
			gee_tree_set_fix_up (self, node);
			result = r;
			((item == NULL) || (self->priv->g_destroy_func == NULL)) ? NULL : (item = (self->priv->g_destroy_func (item), NULL));
			return result;
		}
	}
}

/**
 * {@inheritDoc}
 *
 * If the element already exists in the set it will not be added twice.
 */
static gboolean
gee_tree_set_real_add (GeeAbstractCollection* base,
                       gconstpointer item)
{
	GeeTreeSet * self;
	gboolean r = FALSE;
	gpointer _tmp0_;
	gboolean _tmp1_;
	GeeTreeSetNode* _tmp2_;
	gint _tmp3_;
	gboolean result;
	self = (GeeTreeSet*) base;
	_tmp0_ = ((item != NULL) && (self->priv->g_dup_func != NULL)) ? self->priv->g_dup_func ((gpointer) item) : ((gpointer) item);
	_tmp1_ = gee_tree_set_add_to_node (self, &self->priv->root, _tmp0_, NULL, NULL);
	r = _tmp1_;
	_tmp2_ = self->priv->root;
	_tmp2_->color = GEE_TREE_SET_NODE_COLOR_BLACK;
	_tmp3_ = self->priv->stamp;
	self->priv->stamp = _tmp3_ + 1;
	result = r;
	return result;
}

static inline void
gee_tree_set_move_red_left (GeeTreeSet* self,
                            GeeTreeSetNode** root)
{
	GeeTreeSetNode* _tmp0_;
	GeeTreeSetNode* _tmp1_;
	g_return_if_fail (self != NULL);
	g_return_if_fail (*root != NULL);
	gee_tree_set_node_flip (*root);
	_tmp0_ = (*root)->right;
	_tmp1_ = _tmp0_->left;
	if (gee_tree_set_is_red (self, _tmp1_)) {
		gee_tree_set_rotate_right (self, &(*root)->right);
		gee_tree_set_rotate_left (self, root);
		gee_tree_set_node_flip (*root);
	}
}

static inline void
gee_tree_set_move_red_right (GeeTreeSet* self,
                             GeeTreeSetNode** root)
{
	GeeTreeSetNode* _tmp0_;
	GeeTreeSetNode* _tmp1_;
	g_return_if_fail (self != NULL);
	g_return_if_fail (*root != NULL);
	gee_tree_set_node_flip (*root);
	_tmp0_ = (*root)->left;
	_tmp1_ = _tmp0_->left;
	if (gee_tree_set_is_red (self, _tmp1_)) {
		gee_tree_set_rotate_right (self, root);
		gee_tree_set_node_flip (*root);
	}
}

static inline void
gee_tree_set_fix_removal (GeeTreeSet* self,
                          GeeTreeSetNode** node,
                          gpointer* key)
{
	gpointer _vala_key = NULL;
	GeeTreeSetNode* n = NULL;
	GeeTreeSetNode* _tmp0_;
	GeeTreeSetNode* _tmp1_;
	gpointer _tmp2_;
	GeeTreeSetNode* _tmp3_;
	GeeTreeSetNode* _tmp4_;
	GeeTreeSetNode* _tmp11_;
	GeeTreeSetNode* _tmp12_;
	gint _tmp19_;
	g_return_if_fail (self != NULL);
	g_return_if_fail (*node != NULL);
	_tmp0_ = *node;
	*node = NULL;
	n = _tmp0_;
	_tmp1_ = n;
	_tmp2_ = _tmp1_->key;
	_tmp1_->key = NULL;
	((_vala_key == NULL) || (self->priv->g_destroy_func == NULL)) ? NULL : (_vala_key = (self->priv->g_destroy_func (_vala_key), NULL));
	_vala_key = _tmp2_;
	_tmp3_ = n;
	_tmp4_ = _tmp3_->prev;
	if (_tmp4_ != NULL) {
		GeeTreeSetNode* _tmp5_;
		GeeTreeSetNode* _tmp6_;
		GeeTreeSetNode* _tmp7_;
		GeeTreeSetNode* _tmp8_;
		_tmp5_ = n;
		_tmp6_ = _tmp5_->prev;
		_tmp7_ = n;
		_tmp8_ = _tmp7_->next;
		_tmp6_->next = _tmp8_;
	} else {
		GeeTreeSetNode* _tmp9_;
		GeeTreeSetNode* _tmp10_;
		_tmp9_ = n;
		_tmp10_ = _tmp9_->next;
		self->priv->_first = _tmp10_;
	}
	_tmp11_ = n;
	_tmp12_ = _tmp11_->next;
	if (_tmp12_ != NULL) {
		GeeTreeSetNode* _tmp13_;
		GeeTreeSetNode* _tmp14_;
		GeeTreeSetNode* _tmp15_;
		GeeTreeSetNode* _tmp16_;
		_tmp13_ = n;
		_tmp14_ = _tmp13_->next;
		_tmp15_ = n;
		_tmp16_ = _tmp15_->prev;
		_tmp14_->prev = _tmp16_;
	} else {
		GeeTreeSetNode* _tmp17_;
		GeeTreeSetNode* _tmp18_;
		_tmp17_ = n;
		_tmp18_ = _tmp17_->prev;
		self->priv->_last = _tmp18_;
	}
	_gee_tree_set_node_free0 (*node);
	*node = NULL;
	_tmp19_ = self->priv->_size;
	self->priv->_size = _tmp19_ - 1;
	_gee_tree_set_node_free0 (n);
	if (key) {
		*key = _vala_key;
	} else {
		((_vala_key == NULL) || (self->priv->g_destroy_func == NULL)) ? NULL : (_vala_key = (self->priv->g_destroy_func (_vala_key), NULL));
	}
}

static void
gee_tree_set_remove_minimal (GeeTreeSet* self,
                             GeeTreeSetNode** node,
                             gpointer* key)
{
	gpointer _vala_key = NULL;
	GeeTreeSetNode* _tmp0_;
	gboolean _tmp2_ = FALSE;
	GeeTreeSetNode* _tmp3_;
	gpointer _tmp6_ = NULL;
	g_return_if_fail (self != NULL);
	g_return_if_fail (*node != NULL);
	_tmp0_ = (*node)->left;
	if (_tmp0_ == NULL) {
		gpointer _tmp1_ = NULL;
		gee_tree_set_fix_removal (self, node, &_tmp1_);
		((_vala_key == NULL) || (self->priv->g_destroy_func == NULL)) ? NULL : (_vala_key = (self->priv->g_destroy_func (_vala_key), NULL));
		_vala_key = _tmp1_;
		if (key) {
			*key = _vala_key;
		} else {
			((_vala_key == NULL) || (self->priv->g_destroy_func == NULL)) ? NULL : (_vala_key = (self->priv->g_destroy_func (_vala_key), NULL));
		}
		return;
	}
	_tmp3_ = (*node)->left;
	if (gee_tree_set_is_black (self, _tmp3_)) {
		GeeTreeSetNode* _tmp4_;
		GeeTreeSetNode* _tmp5_;
		_tmp4_ = (*node)->left;
		_tmp5_ = _tmp4_->left;
		_tmp2_ = gee_tree_set_is_black (self, _tmp5_);
	} else {
		_tmp2_ = FALSE;
	}
	if (_tmp2_) {
		gee_tree_set_move_red_left (self, node);
	}
	gee_tree_set_remove_minimal (self, &(*node)->left, &_tmp6_);
	((_vala_key == NULL) || (self->priv->g_destroy_func == NULL)) ? NULL : (_vala_key = (self->priv->g_destroy_func (_vala_key), NULL));
	_vala_key = _tmp6_;
	gee_tree_set_fix_up (self, node);
	if (key) {
		*key = _vala_key;
	} else {
		((_vala_key == NULL) || (self->priv->g_destroy_func == NULL)) ? NULL : (_vala_key = (self->priv->g_destroy_func (_vala_key), NULL));
	}
}

static gboolean
gee_tree_set_remove_from_node (GeeTreeSet* self,
                               GeeTreeSetNode** node,
                               gconstpointer item,
                               GeeTreeSetNode** prev,
                               GeeTreeSetNode** next)
{
	GeeTreeSetNode* _vala_prev = NULL;
	GeeTreeSetNode* _vala_next = NULL;
	gboolean result;
	g_return_val_if_fail (self != NULL, FALSE);
	if ((*node) == NULL) {
		_vala_prev = NULL;
		_vala_next = NULL;
		result = FALSE;
		if (prev) {
			*prev = _vala_prev;
		}
		if (next) {
			*next = _vala_next;
		}
		return result;
	} else {
		GCompareDataFunc _tmp0_ = NULL;
		gpointer _tmp0__target = NULL;
		GCompareDataFunc _tmp1_;
		gpointer _tmp1__target;
		gconstpointer _tmp2_;
		_tmp0_ = gee_tree_set_get_compare_func (self, &_tmp0__target);
		_tmp1_ = _tmp0_;
		_tmp1__target = _tmp0__target;
		_tmp2_ = (*node)->key;
		if (_tmp1_ (item, _tmp2_, _tmp1__target) < 0) {
			GeeTreeSetNode* left = NULL;
			GeeTreeSetNode* _tmp3_;
			GeeTreeSetNode* _tmp4_;
			gboolean _tmp5_ = FALSE;
			GeeTreeSetNode* _tmp6_;
			gboolean r = FALSE;
			GeeTreeSetNode* _tmp9_ = NULL;
			GeeTreeSetNode* _tmp10_ = NULL;
			gboolean _tmp11_;
			_tmp3_ = (*node)->left;
			left = _tmp3_;
			_tmp4_ = left;
			if (_tmp4_ == NULL) {
				_vala_prev = NULL;
				_vala_next = NULL;
				result = FALSE;
				if (prev) {
					*prev = _vala_prev;
				}
				if (next) {
					*next = _vala_next;
				}
				return result;
			}
			_tmp6_ = left;
			if (gee_tree_set_is_black (self, _tmp6_)) {
				GeeTreeSetNode* _tmp7_;
				GeeTreeSetNode* _tmp8_;
				_tmp7_ = left;
				_tmp8_ = _tmp7_->left;
				_tmp5_ = gee_tree_set_is_black (self, _tmp8_);
			} else {
				_tmp5_ = FALSE;
			}
			if (_tmp5_) {
				gee_tree_set_move_red_left (self, node);
			}
			_tmp11_ = gee_tree_set_remove_from_node (self, &(*node)->left, item, &_tmp9_, &_tmp10_);
			_vala_prev = _tmp9_;
			_vala_next = _tmp10_;
			r = _tmp11_;
			gee_tree_set_fix_up (self, node);
			result = r;
			if (prev) {
				*prev = _vala_prev;
			}
			if (next) {
				*next = _vala_next;
			}
			return result;
		} else {
			GeeTreeSetNode* _tmp12_;
			GeeTreeSetNode* r = NULL;
			GeeTreeSetNode* _tmp13_;
			gboolean _tmp14_ = FALSE;
			GCompareDataFunc _tmp15_ = NULL;
			gpointer _tmp15__target = NULL;
			GCompareDataFunc _tmp16_;
			gpointer _tmp16__target;
			gconstpointer _tmp17_;
			gboolean _tmp21_ = FALSE;
			gboolean _tmp22_ = FALSE;
			GeeTreeSetNode* _tmp23_;
			GCompareDataFunc _tmp27_ = NULL;
			gpointer _tmp27__target = NULL;
			GCompareDataFunc _tmp28_;
			gpointer _tmp28__target;
			gconstpointer _tmp29_;
			_tmp12_ = (*node)->left;
			if (gee_tree_set_is_red (self, _tmp12_)) {
				gee_tree_set_rotate_right (self, node);
			}
			_tmp13_ = (*node)->right;
			r = _tmp13_;
			_tmp15_ = gee_tree_set_get_compare_func (self, &_tmp15__target);
			_tmp16_ = _tmp15_;
			_tmp16__target = _tmp15__target;
			_tmp17_ = (*node)->key;
			if (_tmp16_ (item, _tmp17_, _tmp16__target) == 0) {
				GeeTreeSetNode* _tmp18_;
				_tmp18_ = r;
				_tmp14_ = _tmp18_ == NULL;
			} else {
				_tmp14_ = FALSE;
			}
			if (_tmp14_) {
				GeeTreeSetNode* _tmp19_;
				GeeTreeSetNode* _tmp20_;
				_tmp19_ = (*node)->prev;
				_vala_prev = _tmp19_;
				_tmp20_ = (*node)->next;
				_vala_next = _tmp20_;
				gee_tree_set_fix_removal (self, node, NULL);
				result = TRUE;
				if (prev) {
					*prev = _vala_prev;
				}
				if (next) {
					*next = _vala_next;
				}
				return result;
			}
			_tmp23_ = r;
			if (gee_tree_set_is_black (self, _tmp23_)) {
				GeeTreeSetNode* _tmp24_;
				_tmp24_ = r;
				_tmp22_ = _tmp24_ != NULL;
			} else {
				_tmp22_ = FALSE;
			}
			if (_tmp22_) {
				GeeTreeSetNode* _tmp25_;
				GeeTreeSetNode* _tmp26_;
				_tmp25_ = r;
				_tmp26_ = _tmp25_->left;
				_tmp21_ = gee_tree_set_is_black (self, _tmp26_);
			} else {
				_tmp21_ = FALSE;
			}
			if (_tmp21_) {
				gee_tree_set_move_red_right (self, node);
			}
			_tmp27_ = gee_tree_set_get_compare_func (self, &_tmp27__target);
			_tmp28_ = _tmp27_;
			_tmp28__target = _tmp27__target;
			_tmp29_ = (*node)->key;
			if (_tmp28_ (item, _tmp29_, _tmp28__target) == 0) {
				GeeTreeSetNode* _tmp30_;
				gpointer _tmp31_ = NULL;
				_tmp30_ = (*node)->prev;
				_vala_prev = _tmp30_;
				_vala_next = *node;
				gee_tree_set_remove_minimal (self, &(*node)->right, &_tmp31_);
				(((*node)->key == NULL) || (self->priv->g_destroy_func == NULL)) ? NULL : ((*node)->key = (self->priv->g_destroy_func ((*node)->key), NULL));
				(*node)->key = _tmp31_;
				gee_tree_set_fix_up (self, node);
				result = TRUE;
				if (prev) {
					*prev = _vala_prev;
				}
				if (next) {
					*next = _vala_next;
				}
				return result;
			} else {
				gboolean re = FALSE;
				GeeTreeSetNode* _tmp32_ = NULL;
				GeeTreeSetNode* _tmp33_ = NULL;
				gboolean _tmp34_;
				_tmp34_ = gee_tree_set_remove_from_node (self, &(*node)->right, item, &_tmp32_, &_tmp33_);
				_vala_prev = _tmp32_;
				_vala_next = _tmp33_;
				re = _tmp34_;
				gee_tree_set_fix_up (self, node);
				result = re;
				if (prev) {
					*prev = _vala_prev;
				}
				if (next) {
					*next = _vala_next;
				}
				return result;
			}
		}
	}
}

/**
 * {@inheritDoc}
 */
static gboolean
gee_tree_set_real_remove (GeeAbstractCollection* base,
                          gconstpointer item)
{
	GeeTreeSet * self;
	gboolean b = FALSE;
	gboolean _tmp0_;
	GeeTreeSetNode* _tmp1_;
	gint _tmp3_;
	gboolean result;
	self = (GeeTreeSet*) base;
	_tmp0_ = gee_tree_set_remove_from_node (self, &self->priv->root, item, NULL, NULL);
	b = _tmp0_;
	_tmp1_ = self->priv->root;
	if (_tmp1_ != NULL) {
		GeeTreeSetNode* _tmp2_;
		_tmp2_ = self->priv->root;
		_tmp2_->color = GEE_TREE_SET_NODE_COLOR_BLACK;
	}
	_tmp3_ = self->priv->stamp;
	self->priv->stamp = _tmp3_ + 1;
	result = b;
	return result;
}

static inline void
gee_tree_set_clear_subtree (GeeTreeSet* self,
                            GeeTreeSetNode* node)
{
	GeeTreeSetNode* _tmp0_;
	GeeTreeSetNode* _tmp2_;
	g_return_if_fail (self != NULL);
	g_return_if_fail (node != NULL);
	((node->key == NULL) || (self->priv->g_destroy_func == NULL)) ? NULL : (node->key = (self->priv->g_destroy_func (node->key), NULL));
	node->key = NULL;
	_tmp0_ = node->left;
	if (_tmp0_ != NULL) {
		GeeTreeSetNode* _tmp1_;
		_tmp1_ = node->left;
		node->left = NULL;
		gee_tree_set_clear_subtree (self, _tmp1_);
	}
	_tmp2_ = node->right;
	if (_tmp2_ != NULL) {
		GeeTreeSetNode* _tmp3_;
		_tmp3_ = node->right;
		node->right = NULL;
		gee_tree_set_clear_subtree (self, _tmp3_);
	}
	_gee_tree_set_node_free0 (node);
}

/**
 * {@inheritDoc}
 */
static void
gee_tree_set_real_clear (GeeAbstractCollection* base)
{
	GeeTreeSet * self;
	GeeTreeSetNode* _tmp0_;
	gint _tmp3_;
	self = (GeeTreeSet*) base;
	_tmp0_ = self->priv->root;
	if (_tmp0_ != NULL) {
		GeeTreeSetNode* _tmp1_;
		GeeTreeSetNode* _tmp2_;
		_tmp1_ = self->priv->root;
		self->priv->root = NULL;
		gee_tree_set_clear_subtree (self, _tmp1_);
		self->priv->_last = NULL;
		_tmp2_ = self->priv->_last;
		self->priv->_first = _tmp2_;
	}
	self->priv->_size = 0;
	_tmp3_ = self->priv->stamp;
	self->priv->stamp = _tmp3_ + 1;
}

/**
 * {@inheritDoc}
 */
static gboolean
gee_tree_set_real_foreach (GeeAbstractCollection* base,
                           GeeForallFunc f,
                           gpointer f_target)
{
	GeeTreeSet * self;
	gboolean result;
	self = (GeeTreeSet*) base;
	{
		GeeTreeSetNode* node = NULL;
		GeeTreeSetNode* _tmp0_;
		_tmp0_ = self->priv->_first;
		node = _tmp0_;
		{
			gboolean _tmp1_ = FALSE;
			_tmp1_ = TRUE;
			while (TRUE) {
				GeeTreeSetNode* _tmp4_;
				GeeTreeSetNode* _tmp5_;
				gconstpointer _tmp6_;
				gpointer _tmp7_;
				if (!_tmp1_) {
					GeeTreeSetNode* _tmp2_;
					GeeTreeSetNode* _tmp3_;
					_tmp2_ = node;
					_tmp3_ = _tmp2_->next;
					node = _tmp3_;
				}
				_tmp1_ = FALSE;
				_tmp4_ = node;
				if (!(_tmp4_ != NULL)) {
					break;
				}
				_tmp5_ = node;
				_tmp6_ = _tmp5_->key;
				_tmp7_ = ((_tmp6_ != NULL) && (self->priv->g_dup_func != NULL)) ? self->priv->g_dup_func ((gpointer) _tmp6_) : ((gpointer) _tmp6_);
				if (!f (_tmp7_, f_target)) {
					result = FALSE;
					return result;
				}
			}
		}
	}
	result = TRUE;
	return result;
}

/**
 * {@inheritDoc}
 */
static GeeIterator*
gee_tree_set_real_iterator (GeeAbstractCollection* base)
{
	GeeTreeSet * self;
	GeeTreeSetIterator* _tmp0_;
	GeeIterator* result;
	self = (GeeTreeSet*) base;
	_tmp0_ = gee_tree_set_iterator_new (self->priv->g_type, (GBoxedCopyFunc) self->priv->g_dup_func, (GDestroyNotify) self->priv->g_destroy_func, self);
	result = (GeeIterator*) _tmp0_;
	return result;
}

/**
 * {@inheritDoc}
 */
static GeeBidirIterator*
gee_tree_set_real_bidir_iterator (GeeAbstractBidirSortedSet* base)
{
	GeeTreeSet * self;
	GeeTreeSetIterator* _tmp0_;
	GeeBidirIterator* result;
	self = (GeeTreeSet*) base;
	_tmp0_ = gee_tree_set_iterator_new (self->priv->g_type, (GBoxedCopyFunc) self->priv->g_dup_func, (GDestroyNotify) self->priv->g_destroy_func, self);
	result = (GeeBidirIterator*) _tmp0_;
	return result;
}

static inline gpointer
gee_tree_set_lift_null_get (GeeTreeSet* self,
                            GeeTreeSetNode* node)
{
	gconstpointer _tmp0_ = NULL;
	gpointer _tmp2_;
	gpointer result;
	g_return_val_if_fail (self != NULL, NULL);
	if (node != NULL) {
		gconstpointer _tmp1_;
		_tmp1_ = node->key;
		_tmp0_ = _tmp1_;
	} else {
		_tmp0_ = NULL;
	}
	_tmp2_ = ((_tmp0_ != NULL) && (self->priv->g_dup_func != NULL)) ? self->priv->g_dup_func ((gpointer) _tmp0_) : ((gpointer) _tmp0_);
	result = _tmp2_;
	return result;
}

/**
 * {@inheritDoc}
 */
static gpointer
gee_tree_set_real_first (GeeAbstractSortedSet* base)
{
	GeeTreeSet * self;
	GeeTreeSetNode* _tmp0_;
	GeeTreeSetNode* _tmp1_;
	gconstpointer _tmp2_;
	gpointer _tmp3_;
	gpointer result;
	self = (GeeTreeSet*) base;
	_tmp0_ = self->priv->_first;
	_vala_assert (_tmp0_ != NULL, "_first != null");
	_tmp1_ = self->priv->_first;
	_tmp2_ = _tmp1_->key;
	_tmp3_ = ((_tmp2_ != NULL) && (self->priv->g_dup_func != NULL)) ? self->priv->g_dup_func ((gpointer) _tmp2_) : ((gpointer) _tmp2_);
	result = _tmp3_;
	return result;
}

/**
 * {@inheritDoc}
 */
static gpointer
gee_tree_set_real_last (GeeAbstractSortedSet* base)
{
	GeeTreeSet * self;
	GeeTreeSetNode* _tmp0_;
	GeeTreeSetNode* _tmp1_;
	gconstpointer _tmp2_;
	gpointer _tmp3_;
	gpointer result;
	self = (GeeTreeSet*) base;
	_tmp0_ = self->priv->_last;
	_vala_assert (_tmp0_ != NULL, "_last != null");
	_tmp1_ = self->priv->_last;
	_tmp2_ = _tmp1_->key;
	_tmp3_ = ((_tmp2_ != NULL) && (self->priv->g_dup_func != NULL)) ? self->priv->g_dup_func ((gpointer) _tmp2_) : ((gpointer) _tmp2_);
	result = _tmp3_;
	return result;
}

/**
 * {@inheritDoc}
 */
static GeeSortedSet*
gee_tree_set_real_head_set (GeeAbstractSortedSet* base,
                            gconstpointer before)
{
	GeeTreeSet * self;
	GeeTreeSetSubSet* _tmp0_;
	GeeSortedSet* result;
	self = (GeeTreeSet*) base;
	_tmp0_ = gee_tree_set_sub_set_new_head (self->priv->g_type, (GBoxedCopyFunc) self->priv->g_dup_func, (GDestroyNotify) self->priv->g_destroy_func, self, before);
	result = (GeeSortedSet*) _tmp0_;
	return result;
}

/**
 * {@inheritDoc}
 */
static GeeSortedSet*
gee_tree_set_real_tail_set (GeeAbstractSortedSet* base,
                            gconstpointer after)
{
	GeeTreeSet * self;
	GeeTreeSetSubSet* _tmp0_;
	GeeSortedSet* result;
	self = (GeeTreeSet*) base;
	_tmp0_ = gee_tree_set_sub_set_new_tail (self->priv->g_type, (GBoxedCopyFunc) self->priv->g_dup_func, (GDestroyNotify) self->priv->g_destroy_func, self, after);
	result = (GeeSortedSet*) _tmp0_;
	return result;
}

/**
 * {@inheritDoc}
 */
static GeeSortedSet*
gee_tree_set_real_sub_set (GeeAbstractSortedSet* base,
                           gconstpointer after,
                           gconstpointer before)
{
	GeeTreeSet * self;
	GeeTreeSetSubSet* _tmp0_;
	GeeSortedSet* result;
	self = (GeeTreeSet*) base;
	_tmp0_ = gee_tree_set_sub_set_new (self->priv->g_type, (GBoxedCopyFunc) self->priv->g_dup_func, (GDestroyNotify) self->priv->g_destroy_func, self, after, before);
	result = (GeeSortedSet*) _tmp0_;
	return result;
}

static inline GeeTreeSetNode*
gee_tree_set_find_node (GeeTreeSet* self,
                        gconstpointer item)
{
	GeeTreeSetNode* cur = NULL;
	GeeTreeSetNode* _tmp0_;
	GeeTreeSetNode* result;
	g_return_val_if_fail (self != NULL, NULL);
	_tmp0_ = self->priv->root;
	cur = _tmp0_;
	while (TRUE) {
		GeeTreeSetNode* _tmp1_;
		gint res = 0;
		GCompareDataFunc _tmp2_ = NULL;
		gpointer _tmp2__target = NULL;
		GCompareDataFunc _tmp3_;
		gpointer _tmp3__target;
		GeeTreeSetNode* _tmp4_;
		gconstpointer _tmp5_;
		_tmp1_ = cur;
		if (!(_tmp1_ != NULL)) {
			break;
		}
		_tmp2_ = gee_tree_set_get_compare_func (self, &_tmp2__target);
		_tmp3_ = _tmp2_;
		_tmp3__target = _tmp2__target;
		_tmp4_ = cur;
		_tmp5_ = _tmp4_->key;
		res = _tmp3_ (item, _tmp5_, _tmp3__target);
		if (res == 0) {
			GeeTreeSetNode* _tmp6_;
			_tmp6_ = cur;
			result = _tmp6_;
			return result;
		} else {
			if (res < 0) {
				GeeTreeSetNode* _tmp7_;
				GeeTreeSetNode* _tmp8_;
				_tmp7_ = cur;
				_tmp8_ = _tmp7_->left;
				cur = _tmp8_;
			} else {
				GeeTreeSetNode* _tmp9_;
				GeeTreeSetNode* _tmp10_;
				_tmp9_ = cur;
				_tmp10_ = _tmp9_->right;
				cur = _tmp10_;
			}
		}
	}
	result = NULL;
	return result;
}

/**
 * {@inheritDoc}
 */
static GeeIterator*
gee_tree_set_real_iterator_at (GeeAbstractSortedSet* base,
                               gconstpointer item)
{
	GeeTreeSet * self;
	GeeTreeSetNode* node = NULL;
	GeeTreeSetNode* _tmp0_;
	GeeTreeSetIterator* _tmp1_ = NULL;
	GeeTreeSetNode* _tmp2_;
	GeeIterator* result;
	self = (GeeTreeSet*) base;
	_tmp0_ = gee_tree_set_find_node (self, item);
	node = _tmp0_;
	_tmp2_ = node;
	if (_tmp2_ != NULL) {
		GeeTreeSetNode* _tmp3_;
		GeeTreeSetIterator* _tmp4_;
		_tmp3_ = node;
		_tmp4_ = gee_tree_set_iterator_new_pointing (self->priv->g_type, (GBoxedCopyFunc) self->priv->g_dup_func, (GDestroyNotify) self->priv->g_destroy_func, self, _tmp3_);
		_g_object_unref0 (_tmp1_);
		_tmp1_ = _tmp4_;
	} else {
		_g_object_unref0 (_tmp1_);
		_tmp1_ = NULL;
	}
	result = (GeeIterator*) _tmp1_;
	return result;
}

static inline GeeTreeSetNode*
gee_tree_set_find_nearest (GeeTreeSet* self,
                           gconstpointer item)
{
	GeeTreeSetNode* cur = NULL;
	GeeTreeSetNode* _tmp0_;
	GeeTreeSetNode* result;
	g_return_val_if_fail (self != NULL, NULL);
	_tmp0_ = self->priv->root;
	cur = _tmp0_;
	while (TRUE) {
		GeeTreeSetNode* _tmp1_;
		gint res = 0;
		GCompareDataFunc _tmp2_ = NULL;
		gpointer _tmp2__target = NULL;
		GCompareDataFunc _tmp3_;
		gpointer _tmp3__target;
		GeeTreeSetNode* _tmp4_;
		gconstpointer _tmp5_;
		_tmp1_ = cur;
		if (!(_tmp1_ != NULL)) {
			break;
		}
		_tmp2_ = gee_tree_set_get_compare_func (self, &_tmp2__target);
		_tmp3_ = _tmp2_;
		_tmp3__target = _tmp2__target;
		_tmp4_ = cur;
		_tmp5_ = _tmp4_->key;
		res = _tmp3_ (item, _tmp5_, _tmp3__target);
		if (res == 0) {
			GeeTreeSetNode* _tmp6_;
			_tmp6_ = cur;
			result = _tmp6_;
			return result;
		} else {
			if (res < 0) {
				GeeTreeSetNode* _tmp7_;
				GeeTreeSetNode* _tmp8_;
				GeeTreeSetNode* _tmp10_;
				GeeTreeSetNode* _tmp11_;
				_tmp7_ = cur;
				_tmp8_ = _tmp7_->left;
				if (_tmp8_ == NULL) {
					GeeTreeSetNode* _tmp9_;
					_tmp9_ = cur;
					result = _tmp9_;
					return result;
				}
				_tmp10_ = cur;
				_tmp11_ = _tmp10_->left;
				cur = _tmp11_;
			} else {
				GeeTreeSetNode* _tmp12_;
				GeeTreeSetNode* _tmp13_;
				GeeTreeSetNode* _tmp15_;
				GeeTreeSetNode* _tmp16_;
				_tmp12_ = cur;
				_tmp13_ = _tmp12_->right;
				if (_tmp13_ == NULL) {
					GeeTreeSetNode* _tmp14_;
					_tmp14_ = cur;
					result = _tmp14_;
					return result;
				}
				_tmp15_ = cur;
				_tmp16_ = _tmp15_->right;
				cur = _tmp16_;
			}
		}
	}
	result = NULL;
	return result;
}

static inline GeeTreeSetNode*
gee_tree_set_find_lower (GeeTreeSet* self,
                         gconstpointer item)
{
	GeeTreeSetNode* node = NULL;
	GeeTreeSetNode* _tmp0_;
	GeeTreeSetNode* _tmp1_;
	GeeTreeSetNode* _tmp2_ = NULL;
	GCompareDataFunc _tmp3_ = NULL;
	gpointer _tmp3__target = NULL;
	GCompareDataFunc _tmp4_;
	gpointer _tmp4__target;
	GeeTreeSetNode* _tmp5_;
	gconstpointer _tmp6_;
	GeeTreeSetNode* result;
	g_return_val_if_fail (self != NULL, NULL);
	_tmp0_ = gee_tree_set_find_nearest (self, item);
	node = _tmp0_;
	_tmp1_ = node;
	if (_tmp1_ == NULL) {
		result = NULL;
		return result;
	}
	_tmp3_ = gee_tree_set_get_compare_func (self, &_tmp3__target);
	_tmp4_ = _tmp3_;
	_tmp4__target = _tmp3__target;
	_tmp5_ = node;
	_tmp6_ = _tmp5_->key;
	if (_tmp4_ (item, _tmp6_, _tmp4__target) <= 0) {
		GeeTreeSetNode* _tmp7_;
		GeeTreeSetNode* _tmp8_;
		_tmp7_ = node;
		_tmp8_ = _tmp7_->prev;
		_tmp2_ = _tmp8_;
	} else {
		GeeTreeSetNode* _tmp9_;
		_tmp9_ = node;
		_tmp2_ = _tmp9_;
	}
	result = _tmp2_;
	return result;
}

static inline GeeTreeSetNode*
gee_tree_set_find_higher (GeeTreeSet* self,
                          gconstpointer item)
{
	GeeTreeSetNode* node = NULL;
	GeeTreeSetNode* _tmp0_;
	GeeTreeSetNode* _tmp1_;
	GeeTreeSetNode* _tmp2_ = NULL;
	GCompareDataFunc _tmp3_ = NULL;
	gpointer _tmp3__target = NULL;
	GCompareDataFunc _tmp4_;
	gpointer _tmp4__target;
	GeeTreeSetNode* _tmp5_;
	gconstpointer _tmp6_;
	GeeTreeSetNode* result;
	g_return_val_if_fail (self != NULL, NULL);
	_tmp0_ = gee_tree_set_find_nearest (self, item);
	node = _tmp0_;
	_tmp1_ = node;
	if (_tmp1_ == NULL) {
		result = NULL;
		return result;
	}
	_tmp3_ = gee_tree_set_get_compare_func (self, &_tmp3__target);
	_tmp4_ = _tmp3_;
	_tmp4__target = _tmp3__target;
	_tmp5_ = node;
	_tmp6_ = _tmp5_->key;
	if (_tmp4_ (item, _tmp6_, _tmp4__target) >= 0) {
		GeeTreeSetNode* _tmp7_;
		GeeTreeSetNode* _tmp8_;
		_tmp7_ = node;
		_tmp8_ = _tmp7_->next;
		_tmp2_ = _tmp8_;
	} else {
		GeeTreeSetNode* _tmp9_;
		_tmp9_ = node;
		_tmp2_ = _tmp9_;
	}
	result = _tmp2_;
	return result;
}

static inline GeeTreeSetNode*
gee_tree_set_find_floor (GeeTreeSet* self,
                         gconstpointer item)
{
	GeeTreeSetNode* node = NULL;
	GeeTreeSetNode* _tmp0_;
	GeeTreeSetNode* _tmp1_;
	GeeTreeSetNode* _tmp2_ = NULL;
	GCompareDataFunc _tmp3_ = NULL;
	gpointer _tmp3__target = NULL;
	GCompareDataFunc _tmp4_;
	gpointer _tmp4__target;
	GeeTreeSetNode* _tmp5_;
	gconstpointer _tmp6_;
	GeeTreeSetNode* result;
	g_return_val_if_fail (self != NULL, NULL);
	_tmp0_ = gee_tree_set_find_nearest (self, item);
	node = _tmp0_;
	_tmp1_ = node;
	if (_tmp1_ == NULL) {
		result = NULL;
		return result;
	}
	_tmp3_ = gee_tree_set_get_compare_func (self, &_tmp3__target);
	_tmp4_ = _tmp3_;
	_tmp4__target = _tmp3__target;
	_tmp5_ = node;
	_tmp6_ = _tmp5_->key;
	if (_tmp4_ (item, _tmp6_, _tmp4__target) < 0) {
		GeeTreeSetNode* _tmp7_;
		GeeTreeSetNode* _tmp8_;
		_tmp7_ = node;
		_tmp8_ = _tmp7_->prev;
		_tmp2_ = _tmp8_;
	} else {
		GeeTreeSetNode* _tmp9_;
		_tmp9_ = node;
		_tmp2_ = _tmp9_;
	}
	result = _tmp2_;
	return result;
}

static inline GeeTreeSetNode*
gee_tree_set_find_ceil (GeeTreeSet* self,
                        gconstpointer item)
{
	GeeTreeSetNode* node = NULL;
	GeeTreeSetNode* _tmp0_;
	GeeTreeSetNode* _tmp1_;
	GeeTreeSetNode* _tmp2_ = NULL;
	GCompareDataFunc _tmp3_ = NULL;
	gpointer _tmp3__target = NULL;
	GCompareDataFunc _tmp4_;
	gpointer _tmp4__target;
	GeeTreeSetNode* _tmp5_;
	gconstpointer _tmp6_;
	GeeTreeSetNode* result;
	g_return_val_if_fail (self != NULL, NULL);
	_tmp0_ = gee_tree_set_find_nearest (self, item);
	node = _tmp0_;
	_tmp1_ = node;
	if (_tmp1_ == NULL) {
		result = NULL;
		return result;
	}
	_tmp3_ = gee_tree_set_get_compare_func (self, &_tmp3__target);
	_tmp4_ = _tmp3_;
	_tmp4__target = _tmp3__target;
	_tmp5_ = node;
	_tmp6_ = _tmp5_->key;
	if (_tmp4_ (item, _tmp6_, _tmp4__target) > 0) {
		GeeTreeSetNode* _tmp7_;
		GeeTreeSetNode* _tmp8_;
		_tmp7_ = node;
		_tmp8_ = _tmp7_->next;
		_tmp2_ = _tmp8_;
	} else {
		GeeTreeSetNode* _tmp9_;
		_tmp9_ = node;
		_tmp2_ = _tmp9_;
	}
	result = _tmp2_;
	return result;
}

/**
 * {@inheritDoc}
 */
static gpointer
gee_tree_set_real_lower (GeeAbstractSortedSet* base,
                         gconstpointer item)
{
	GeeTreeSet * self;
	GeeTreeSetNode* _tmp0_;
	gpointer _tmp1_;
	gpointer result;
	self = (GeeTreeSet*) base;
	_tmp0_ = gee_tree_set_find_lower (self, item);
	_tmp1_ = gee_tree_set_lift_null_get (self, _tmp0_);
	result = _tmp1_;
	return result;
}

/**
 * {@inheritDoc}
 */
static gpointer
gee_tree_set_real_higher (GeeAbstractSortedSet* base,
                          gconstpointer item)
{
	GeeTreeSet * self;
	GeeTreeSetNode* _tmp0_;
	gpointer _tmp1_;
	gpointer result;
	self = (GeeTreeSet*) base;
	_tmp0_ = gee_tree_set_find_higher (self, item);
	_tmp1_ = gee_tree_set_lift_null_get (self, _tmp0_);
	result = _tmp1_;
	return result;
}

/**
 * {@inheritDoc}
 */
static gpointer
gee_tree_set_real_floor (GeeAbstractSortedSet* base,
                         gconstpointer item)
{
	GeeTreeSet * self;
	GeeTreeSetNode* _tmp0_;
	gpointer _tmp1_;
	gpointer result;
	self = (GeeTreeSet*) base;
	_tmp0_ = gee_tree_set_find_floor (self, item);
	_tmp1_ = gee_tree_set_lift_null_get (self, _tmp0_);
	result = _tmp1_;
	return result;
}

/**
 * {@inheritDoc}
 */
static gpointer
gee_tree_set_real_ceil (GeeAbstractSortedSet* base,
                        gconstpointer item)
{
	GeeTreeSet * self;
	GeeTreeSetNode* _tmp0_;
	gpointer _tmp1_;
	gpointer result;
	self = (GeeTreeSet*) base;
	_tmp0_ = gee_tree_set_find_ceil (self, item);
	_tmp1_ = gee_tree_set_lift_null_get (self, _tmp0_);
	result = _tmp1_;
	return result;
}

static inline gpointer
gee_tree_set_min (GeeTreeSet* self,
                  gconstpointer a,
                  gconstpointer b)
{
	gconstpointer _tmp0_ = NULL;
	GCompareDataFunc _tmp1_ = NULL;
	gpointer _tmp1__target = NULL;
	GCompareDataFunc _tmp2_;
	gpointer _tmp2__target;
	gpointer _tmp3_;
	gpointer result;
	g_return_val_if_fail (self != NULL, NULL);
	_tmp1_ = gee_tree_set_get_compare_func (self, &_tmp1__target);
	_tmp2_ = _tmp1_;
	_tmp2__target = _tmp1__target;
	if (_tmp2_ (a, b, _tmp2__target) <= 0) {
		_tmp0_ = a;
	} else {
		_tmp0_ = b;
	}
	_tmp3_ = ((_tmp0_ != NULL) && (self->priv->g_dup_func != NULL)) ? self->priv->g_dup_func ((gpointer) _tmp0_) : ((gpointer) _tmp0_);
	result = _tmp3_;
	return result;
}

static inline gpointer
gee_tree_set_max (GeeTreeSet* self,
                  gconstpointer a,
                  gconstpointer b)
{
	gconstpointer _tmp0_ = NULL;
	GCompareDataFunc _tmp1_ = NULL;
	gpointer _tmp1__target = NULL;
	GCompareDataFunc _tmp2_;
	gpointer _tmp2__target;
	gpointer _tmp3_;
	gpointer result;
	g_return_val_if_fail (self != NULL, NULL);
	_tmp1_ = gee_tree_set_get_compare_func (self, &_tmp1__target);
	_tmp2_ = _tmp1_;
	_tmp2__target = _tmp1__target;
	if (_tmp2_ (a, b, _tmp2__target) > 0) {
		_tmp0_ = a;
	} else {
		_tmp0_ = b;
	}
	_tmp3_ = ((_tmp0_ != NULL) && (self->priv->g_dup_func != NULL)) ? self->priv->g_dup_func ((gpointer) _tmp0_) : ((gpointer) _tmp0_);
	result = _tmp3_;
	return result;
}

static gint
gee_tree_set_real_get_size (GeeAbstractCollection* base)
{
	gint result;
	GeeTreeSet* self;
	self = (GeeTreeSet*) base;
	result = self->priv->_size;
	return result;
}

static gboolean
gee_tree_set_real_get_read_only (GeeAbstractCollection* base)
{
	gboolean result;
	GeeTreeSet* self;
	self = (GeeTreeSet*) base;
	result = FALSE;
	return result;
}

GCompareDataFunc
gee_tree_set_get_compare_func (GeeTreeSet* self,
                               gpointer* result_target)
{
	GCompareDataFunc result;
	GeeFunctionsCompareDataFuncClosure* _tmp0_;
	GCompareDataFunc _tmp1_;
	gpointer _tmp1__target;
	GCompareDataFunc _tmp2_;
	gpointer _tmp2__target;
	g_return_val_if_fail (self != NULL, NULL);
	_tmp0_ = self->priv->_compare_func;
	_tmp1_ = _tmp0_->func;
	_tmp1__target = _tmp0_->func_target;
	_tmp2_ = _tmp1_;
	_tmp2__target = _tmp1__target;
	*result_target = _tmp2__target;
	result = _tmp2_;
	return result;
}

static void
gee_tree_set_set_compare_func (GeeTreeSet* self,
                               GCompareDataFunc value,
                               gpointer value_target)
{
	g_return_if_fail (self != NULL);
}

static GeeTreeSetNodeColor
gee_tree_set_node_color_flip (GeeTreeSetNodeColor self)
{
	GeeTreeSetNodeColor result;
	if (self == GEE_TREE_SET_NODE_COLOR_RED) {
		result = GEE_TREE_SET_NODE_COLOR_BLACK;
		return result;
	} else {
		result = GEE_TREE_SET_NODE_COLOR_RED;
		return result;
	}
}

static GType
gee_tree_set_node_color_get_type_once (void)
{
	static const GEnumValue values[] = {{GEE_TREE_SET_NODE_COLOR_RED, "GEE_TREE_SET_NODE_COLOR_RED", "red"}, {GEE_TREE_SET_NODE_COLOR_BLACK, "GEE_TREE_SET_NODE_COLOR_BLACK", "black"}, {0, NULL, NULL}};
	GType gee_tree_set_node_color_type_id;
	gee_tree_set_node_color_type_id = g_enum_register_static ("GeeTreeSetNodeColor", values);
	return gee_tree_set_node_color_type_id;
}

GType
gee_tree_set_node_color_get_type (void)
{
	static volatile gsize gee_tree_set_node_color_type_id__once = 0;
	if (g_once_init_enter (&gee_tree_set_node_color_type_id__once)) {
		GType gee_tree_set_node_color_type_id;
		gee_tree_set_node_color_type_id = gee_tree_set_node_color_get_type_once ();
		g_once_init_leave (&gee_tree_set_node_color_type_id__once, gee_tree_set_node_color_type_id);
	}
	return gee_tree_set_node_color_type_id__once;
}

static GeeTreeSetNode*
gee_tree_set_node_new (gpointer node,
                       GeeTreeSetNode* prev,
                       GeeTreeSetNode* next)
{
	GeeTreeSetNode* self;
	gpointer _tmp0_;
	self = g_slice_new0 (GeeTreeSetNode);
	gee_tree_set_node_instance_init (self);
	_tmp0_ = node;
	node = NULL;
	self->key = _tmp0_;
	self->color = GEE_TREE_SET_NODE_COLOR_RED;
	self->prev = prev;
	self->next = next;
	if (prev != NULL) {
		prev->next = self;
	}
	if (next != NULL) {
		next->prev = self;
	}
	return self;
}

static void
gee_tree_set_node_flip (GeeTreeSetNode* self)
{
	GeeTreeSetNode* _tmp0_;
	GeeTreeSetNode* _tmp3_;
	g_return_if_fail (self != NULL);
	self->color = gee_tree_set_node_color_flip (self->color);
	_tmp0_ = self->left;
	if (_tmp0_ != NULL) {
		GeeTreeSetNode* _tmp1_;
		GeeTreeSetNode* _tmp2_;
		_tmp1_ = self->left;
		_tmp2_ = self->left;
		_tmp1_->color = gee_tree_set_node_color_flip (_tmp2_->color);
	}
	_tmp3_ = self->right;
	if (_tmp3_ != NULL) {
		GeeTreeSetNode* _tmp4_;
		GeeTreeSetNode* _tmp5_;
		_tmp4_ = self->right;
		_tmp5_ = self->right;
		_tmp4_->color = gee_tree_set_node_color_flip (_tmp5_->color);
	}
}

static void
gee_tree_set_node_instance_init (GeeTreeSetNode * self)
{
}

static void
gee_tree_set_node_free (GeeTreeSetNode * self)
{
	_gee_tree_set_node_free0 (self->left);
	_gee_tree_set_node_free0 (self->right);
	g_slice_free (GeeTreeSetNode, self);
}

static inline gpointer
gee_tree_set_iterator_get_instance_private (GeeTreeSetIterator* self)
{
	return G_STRUCT_MEMBER_P (self, GeeTreeSetIterator_private_offset);
}

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

static GeeTreeSetIterator*
gee_tree_set_iterator_construct (GType object_type,
                                 GType g_type,
                                 GBoxedCopyFunc g_dup_func,
                                 GDestroyNotify g_destroy_func,
                                 GeeTreeSet* set)
{
	GeeTreeSetIterator * self = NULL;
	GeeTreeSet* _tmp0_;
	GeeTreeSet* _tmp1_;
	g_return_val_if_fail (set != NULL, NULL);
	self = (GeeTreeSetIterator*) g_object_new (object_type, "g-type", g_type, "g-dup-func", g_dup_func, "g-destroy-func", g_destroy_func, NULL);
	self->priv->g_type = g_type;
	self->priv->g_dup_func = g_dup_func;
	self->priv->g_destroy_func = g_destroy_func;
	_tmp0_ = _g_object_ref0 (set);
	_g_object_unref0 (self->_set);
	self->_set = _tmp0_;
	_tmp1_ = self->_set;
	self->stamp = _tmp1_->priv->stamp;
	return self;
}

static GeeTreeSetIterator*
gee_tree_set_iterator_new (GType g_type,
                           GBoxedCopyFunc g_dup_func,
                           GDestroyNotify g_destroy_func,
                           GeeTreeSet* set)
{
	return gee_tree_set_iterator_construct (GEE_TREE_SET_TYPE_ITERATOR, g_type, g_dup_func, g_destroy_func, set);
}

static GeeTreeSetIterator*
gee_tree_set_iterator_construct_pointing (GType object_type,
                                          GType g_type,
                                          GBoxedCopyFunc g_dup_func,
                                          GDestroyNotify g_destroy_func,
                                          GeeTreeSet* set,
                                          GeeTreeSetNode* current)
{
	GeeTreeSetIterator * self = NULL;
	GeeTreeSet* _tmp0_;
	g_return_val_if_fail (set != NULL, NULL);
	g_return_val_if_fail (current != NULL, NULL);
	self = (GeeTreeSetIterator*) g_object_new (object_type, "g-type", g_type, "g-dup-func", g_dup_func, "g-destroy-func", g_destroy_func, NULL);
	self->priv->g_type = g_type;
	self->priv->g_dup_func = g_dup_func;
	self->priv->g_destroy_func = g_destroy_func;
	_tmp0_ = _g_object_ref0 (set);
	_g_object_unref0 (self->_set);
	self->_set = _tmp0_;
	self->_current = current;
	self->stamp = set->priv->stamp;
	self->started = TRUE;
	return self;
}

static GeeTreeSetIterator*
gee_tree_set_iterator_new_pointing (GType g_type,
                                    GBoxedCopyFunc g_dup_func,
                                    GDestroyNotify g_destroy_func,
                                    GeeTreeSet* set,
                                    GeeTreeSetNode* current)
{
	return gee_tree_set_iterator_construct_pointing (GEE_TREE_SET_TYPE_ITERATOR, g_type, g_dup_func, g_destroy_func, set, current);
}

static GeeTreeSetIterator*
gee_tree_set_iterator_construct_from_iterator (GType object_type,
                                               GType g_type,
                                               GBoxedCopyFunc g_dup_func,
                                               GDestroyNotify g_destroy_func,
                                               GeeTreeSetIterator* iter)
{
	GeeTreeSetIterator * self = NULL;
	GeeTreeSet* _tmp0_;
	GeeTreeSet* _tmp1_;
	GeeTreeSetNode* _tmp2_;
	GeeTreeSetNode* _tmp3_;
	GeeTreeSetNode* _tmp4_;
	g_return_val_if_fail (iter != NULL, NULL);
	self = (GeeTreeSetIterator*) g_object_new (object_type, "g-type", g_type, "g-dup-func", g_dup_func, "g-destroy-func", g_destroy_func, NULL);
	self->priv->g_type = g_type;
	self->priv->g_dup_func = g_dup_func;
	self->priv->g_destroy_func = g_destroy_func;
	_tmp0_ = iter->_set;
	_tmp1_ = _g_object_ref0 (_tmp0_);
	_g_object_unref0 (self->_set);
	self->_set = _tmp1_;
	self->stamp = iter->stamp;
	_tmp2_ = iter->_current;
	self->_current = _tmp2_;
	_tmp3_ = iter->_next;
	self->_next = _tmp3_;
	_tmp4_ = iter->_prev;
	self->_prev = _tmp4_;
	self->started = iter->started;
	return self;
}

static GeeTreeSetIterator*
gee_tree_set_iterator_new_from_iterator (GType g_type,
                                         GBoxedCopyFunc g_dup_func,
                                         GDestroyNotify g_destroy_func,
                                         GeeTreeSetIterator* iter)
{
	return gee_tree_set_iterator_construct_from_iterator (GEE_TREE_SET_TYPE_ITERATOR, g_type, g_dup_func, g_destroy_func, iter);
}

static gboolean
gee_tree_set_iterator_real_next (GeeIterator* base)
{
	GeeTreeSetIterator * self;
	GeeTreeSet* _tmp0_;
	GeeTreeSetNode* _tmp1_;
	gboolean result;
	self = (GeeTreeSetIterator*) base;
	_tmp0_ = self->_set;
	_vala_assert (self->stamp == _tmp0_->priv->stamp, "stamp == _set.stamp");
	_tmp1_ = self->_current;
	if (_tmp1_ != NULL) {
		GeeTreeSetNode* _tmp2_;
		GeeTreeSetNode* _tmp3_;
		_tmp2_ = self->_current;
		_tmp3_ = _tmp2_->next;
		if (_tmp3_ != NULL) {
			GeeTreeSetNode* _tmp4_;
			GeeTreeSetNode* _tmp5_;
			_tmp4_ = self->_current;
			_tmp5_ = _tmp4_->next;
			self->_current = _tmp5_;
			result = TRUE;
			return result;
		} else {
			result = FALSE;
			return result;
		}
	} else {
		if (!self->started) {
			GeeTreeSet* _tmp6_;
			GeeTreeSetNode* _tmp7_;
			GeeTreeSetNode* _tmp8_;
			_tmp6_ = self->_set;
			_tmp7_ = _tmp6_->priv->_first;
			self->_current = _tmp7_;
			self->started = TRUE;
			_tmp8_ = self->_current;
			result = _tmp8_ != NULL;
			return result;
		} else {
			GeeTreeSetNode* _tmp9_;
			GeeTreeSetNode* _tmp10_;
			GeeTreeSetNode* _tmp11_;
			_tmp9_ = self->_next;
			self->_current = _tmp9_;
			_tmp10_ = self->_current;
			if (_tmp10_ != NULL) {
				self->_next = NULL;
				self->_prev = NULL;
			}
			_tmp11_ = self->_current;
			result = _tmp11_ != NULL;
			return result;
		}
	}
}

static gboolean
gee_tree_set_iterator_real_has_next (GeeIterator* base)
{
	GeeTreeSetIterator * self;
	GeeTreeSet* _tmp0_;
	gboolean _tmp1_ = FALSE;
	gboolean _tmp2_ = FALSE;
	gboolean _tmp3_ = FALSE;
	gboolean result;
	self = (GeeTreeSetIterator*) base;
	_tmp0_ = self->_set;
	_vala_assert (self->stamp == _tmp0_->priv->stamp, "stamp == _set.stamp");
	if (!self->started) {
		GeeTreeSet* _tmp4_;
		GeeTreeSetNode* _tmp5_;
		_tmp4_ = self->_set;
		_tmp5_ = _tmp4_->priv->_first;
		_tmp3_ = _tmp5_ != NULL;
	} else {
		_tmp3_ = FALSE;
	}
	if (_tmp3_) {
		_tmp2_ = TRUE;
	} else {
		gboolean _tmp6_ = FALSE;
		GeeTreeSetNode* _tmp7_;
		_tmp7_ = self->_current;
		if (_tmp7_ == NULL) {
			GeeTreeSetNode* _tmp8_;
			_tmp8_ = self->_next;
			_tmp6_ = _tmp8_ != NULL;
		} else {
			_tmp6_ = FALSE;
		}
		_tmp2_ = _tmp6_;
	}
	if (_tmp2_) {
		_tmp1_ = TRUE;
	} else {
		gboolean _tmp9_ = FALSE;
		GeeTreeSetNode* _tmp10_;
		_tmp10_ = self->_current;
		if (_tmp10_ != NULL) {
			GeeTreeSetNode* _tmp11_;
			GeeTreeSetNode* _tmp12_;
			_tmp11_ = self->_current;
			_tmp12_ = _tmp11_->next;
			_tmp9_ = _tmp12_ != NULL;
		} else {
			_tmp9_ = FALSE;
		}
		_tmp1_ = _tmp9_;
	}
	result = _tmp1_;
	return result;
}

static gboolean
gee_tree_set_iterator_real_first (GeeBidirIterator* base)
{
	GeeTreeSetIterator * self;
	GeeTreeSet* _tmp0_;
	GeeTreeSet* _tmp1_;
	GeeTreeSetNode* _tmp2_;
	GeeTreeSetNode* _tmp3_;
	gboolean result;
	self = (GeeTreeSetIterator*) base;
	_tmp0_ = self->_set;
	_vala_assert (self->stamp == _tmp0_->priv->stamp, "stamp == _set.stamp");
	_tmp1_ = self->_set;
	_tmp2_ = _tmp1_->priv->_first;
	self->_current = _tmp2_;
	self->_next = NULL;
	self->_prev = NULL;
	self->started = TRUE;
	_tmp3_ = self->_current;
	result = _tmp3_ != NULL;
	return result;
}

static gboolean
gee_tree_set_iterator_real_previous (GeeBidirIterator* base)
{
	GeeTreeSetIterator * self;
	GeeTreeSet* _tmp0_;
	GeeTreeSetNode* _tmp1_;
	gboolean result;
	self = (GeeTreeSetIterator*) base;
	_tmp0_ = self->_set;
	_vala_assert (self->stamp == _tmp0_->priv->stamp, "stamp == _set.stamp");
	_tmp1_ = self->_current;
	if (_tmp1_ != NULL) {
		GeeTreeSetNode* _tmp2_;
		GeeTreeSetNode* _tmp3_;
		_tmp2_ = self->_current;
		_tmp3_ = _tmp2_->prev;
		if (_tmp3_ != NULL) {
			GeeTreeSetNode* _tmp4_;
			GeeTreeSetNode* _tmp5_;
			_tmp4_ = self->_current;
			_tmp5_ = _tmp4_->prev;
			self->_current = _tmp5_;
			result = TRUE;
			return result;
		} else {
			result = FALSE;
			return result;
		}
	} else {
		GeeTreeSetNode* _tmp6_;
		_tmp6_ = self->_prev;
		if (_tmp6_ != NULL) {
			GeeTreeSetNode* _tmp7_;
			_tmp7_ = self->_prev;
			self->_current = _tmp7_;
			self->_next = NULL;
			self->_prev = NULL;
			result = TRUE;
			return result;
		} else {
			result = FALSE;
			return result;
		}
	}
}

static gboolean
gee_tree_set_iterator_real_has_previous (GeeBidirIterator* base)
{
	GeeTreeSetIterator * self;
	GeeTreeSet* _tmp0_;
	gboolean _tmp1_ = FALSE;
	gboolean _tmp2_ = FALSE;
	GeeTreeSetNode* _tmp3_;
	gboolean result;
	self = (GeeTreeSetIterator*) base;
	_tmp0_ = self->_set;
	_vala_assert (self->stamp == _tmp0_->priv->stamp, "stamp == _set.stamp");
	_tmp3_ = self->_current;
	if (_tmp3_ == NULL) {
		GeeTreeSetNode* _tmp4_;
		_tmp4_ = self->_prev;
		_tmp2_ = _tmp4_ != NULL;
	} else {
		_tmp2_ = FALSE;
	}
	if (_tmp2_) {
		_tmp1_ = TRUE;
	} else {
		gboolean _tmp5_ = FALSE;
		GeeTreeSetNode* _tmp6_;
		_tmp6_ = self->_current;
		if (_tmp6_ != NULL) {
			GeeTreeSetNode* _tmp7_;
			GeeTreeSetNode* _tmp8_;
			_tmp7_ = self->_current;
			_tmp8_ = _tmp7_->prev;
			_tmp5_ = _tmp8_ != NULL;
		} else {
			_tmp5_ = FALSE;
		}
		_tmp1_ = _tmp5_;
	}
	result = _tmp1_;
	return result;
}

static gboolean
gee_tree_set_iterator_real_last (GeeBidirIterator* base)
{
	GeeTreeSetIterator * self;
	GeeTreeSet* _tmp0_;
	GeeTreeSet* _tmp1_;
	GeeTreeSetNode* _tmp2_;
	GeeTreeSetNode* _tmp3_;
	gboolean result;
	self = (GeeTreeSetIterator*) base;
	_tmp0_ = self->_set;
	_vala_assert (self->stamp == _tmp0_->priv->stamp, "stamp == _set.stamp");
	_tmp1_ = self->_set;
	_tmp2_ = _tmp1_->priv->_last;
	self->_current = _tmp2_;
	self->_next = NULL;
	self->_prev = NULL;
	self->started = TRUE;
	_tmp3_ = self->_current;
	result = _tmp3_ != NULL;
	return result;
}

static gpointer
gee_tree_set_iterator_real_get (GeeIterator* base)
{
	GeeTreeSetIterator * self;
	GeeTreeSet* _tmp0_;
	GeeTreeSetNode* _tmp1_;
	GeeTreeSetNode* _tmp2_;
	gconstpointer _tmp3_;
	gpointer _tmp4_;
	gpointer result;
	self = (GeeTreeSetIterator*) base;
	_tmp0_ = self->_set;
	_vala_assert (self->stamp == _tmp0_->priv->stamp, "stamp == _set.stamp");
	_tmp1_ = self->_current;
	_vala_assert (_tmp1_ != NULL, "_current != null");
	_tmp2_ = self->_current;
	_tmp3_ = _tmp2_->key;
	_tmp4_ = ((_tmp3_ != NULL) && (self->priv->g_dup_func != NULL)) ? self->priv->g_dup_func ((gpointer) _tmp3_) : ((gpointer) _tmp3_);
	result = _tmp4_;
	return result;
}

static void
gee_tree_set_iterator_real_remove (GeeIterator* base)
{
	GeeTreeSetIterator * self;
	GeeTreeSet* _tmp0_;
	GeeTreeSetNode* _tmp1_;
	gboolean success = FALSE;
	GeeTreeSet* _tmp2_;
	GeeTreeSet* _tmp3_;
	GeeTreeSetNode* _tmp4_;
	gconstpointer _tmp5_;
	GeeTreeSetNode* _tmp6_ = NULL;
	GeeTreeSetNode* _tmp7_ = NULL;
	gboolean _tmp8_;
	GeeTreeSet* _tmp9_;
	GeeTreeSetNode* _tmp10_;
	gint _tmp13_;
	GeeTreeSet* _tmp14_;
	gint _tmp15_;
	self = (GeeTreeSetIterator*) base;
	_tmp0_ = self->_set;
	_vala_assert (self->stamp == _tmp0_->priv->stamp, "stamp == _set.stamp");
	_tmp1_ = self->_current;
	_vala_assert (_tmp1_ != NULL, "_current != null");
	_tmp2_ = self->_set;
	_tmp3_ = self->_set;
	_tmp4_ = self->_current;
	_tmp5_ = _tmp4_->key;
	_tmp8_ = gee_tree_set_remove_from_node (_tmp2_, &_tmp3_->priv->root, _tmp5_, &_tmp6_, &_tmp7_);
	self->_prev = _tmp6_;
	self->_next = _tmp7_;
	success = _tmp8_;
	_vala_assert (success, "success");
	_tmp9_ = self->_set;
	_tmp10_ = _tmp9_->priv->root;
	if (_tmp10_ != NULL) {
		GeeTreeSet* _tmp11_;
		GeeTreeSetNode* _tmp12_;
		_tmp11_ = self->_set;
		_tmp12_ = _tmp11_->priv->root;
		_tmp12_->color = GEE_TREE_SET_NODE_COLOR_BLACK;
	}
	self->_current = NULL;
	_tmp13_ = self->stamp;
	self->stamp = _tmp13_ + 1;
	_tmp14_ = self->_set;
	_tmp15_ = _tmp14_->priv->stamp;
	_tmp14_->priv->stamp = _tmp15_ + 1;
	_vala_assert (_tmp13_ == _tmp15_, "stamp++ == _set.stamp++");
}

static gboolean
gee_tree_set_iterator_safe_next_get (GeeTreeSetIterator* self,
                                     gpointer* val)
{
	gpointer _vala_val = NULL;
	GeeTreeSetNode* _tmp0_;
	gboolean result;
	g_return_val_if_fail (self != NULL, FALSE);
	_tmp0_ = self->_current;
	if (_tmp0_ != NULL) {
		GeeTreeSet* _tmp1_;
		GeeTreeSetNode* _tmp2_;
		GeeTreeSetNode* _tmp3_;
		gpointer _tmp4_;
		GeeTreeSetNode* _tmp5_;
		GeeTreeSetNode* _tmp6_;
		_tmp1_ = self->_set;
		_tmp2_ = self->_current;
		_tmp3_ = _tmp2_->next;
		_tmp4_ = gee_tree_set_lift_null_get (_tmp1_, _tmp3_);
		((_vala_val == NULL) || (self->priv->g_destroy_func == NULL)) ? NULL : (_vala_val = (self->priv->g_destroy_func (_vala_val), NULL));
		_vala_val = _tmp4_;
		_tmp5_ = self->_current;
		_tmp6_ = _tmp5_->next;
		result = _tmp6_ != NULL;
		if (val) {
			*val = _vala_val;
		} else {
			((_vala_val == NULL) || (self->priv->g_destroy_func == NULL)) ? NULL : (_vala_val = (self->priv->g_destroy_func (_vala_val), NULL));
		}
		return result;
	} else {
		GeeTreeSet* _tmp7_;
		GeeTreeSetNode* _tmp8_;
		gpointer _tmp9_;
		GeeTreeSetNode* _tmp10_;
		_tmp7_ = self->_set;
		_tmp8_ = self->_next;
		_tmp9_ = gee_tree_set_lift_null_get (_tmp7_, _tmp8_);
		((_vala_val == NULL) || (self->priv->g_destroy_func == NULL)) ? NULL : (_vala_val = (self->priv->g_destroy_func (_vala_val), NULL));
		_vala_val = _tmp9_;
		_tmp10_ = self->_next;
		result = _tmp10_ != NULL;
		if (val) {
			*val = _vala_val;
		} else {
			((_vala_val == NULL) || (self->priv->g_destroy_func == NULL)) ? NULL : (_vala_val = (self->priv->g_destroy_func (_vala_val), NULL));
		}
		return result;
	}
}

static gboolean
gee_tree_set_iterator_safe_previous_get (GeeTreeSetIterator* self,
                                         gpointer* val)
{
	gpointer _vala_val = NULL;
	GeeTreeSetNode* _tmp0_;
	gboolean result;
	g_return_val_if_fail (self != NULL, FALSE);
	_tmp0_ = self->_current;
	if (_tmp0_ != NULL) {
		GeeTreeSet* _tmp1_;
		GeeTreeSetNode* _tmp2_;
		GeeTreeSetNode* _tmp3_;
		gpointer _tmp4_;
		GeeTreeSetNode* _tmp5_;
		GeeTreeSetNode* _tmp6_;
		_tmp1_ = self->_set;
		_tmp2_ = self->_current;
		_tmp3_ = _tmp2_->prev;
		_tmp4_ = gee_tree_set_lift_null_get (_tmp1_, _tmp3_);
		((_vala_val == NULL) || (self->priv->g_destroy_func == NULL)) ? NULL : (_vala_val = (self->priv->g_destroy_func (_vala_val), NULL));
		_vala_val = _tmp4_;
		_tmp5_ = self->_current;
		_tmp6_ = _tmp5_->prev;
		result = _tmp6_ != NULL;
		if (val) {
			*val = _vala_val;
		} else {
			((_vala_val == NULL) || (self->priv->g_destroy_func == NULL)) ? NULL : (_vala_val = (self->priv->g_destroy_func (_vala_val), NULL));
		}
		return result;
	} else {
		GeeTreeSet* _tmp7_;
		GeeTreeSetNode* _tmp8_;
		gpointer _tmp9_;
		GeeTreeSetNode* _tmp10_;
		_tmp7_ = self->_set;
		_tmp8_ = self->_prev;
		_tmp9_ = gee_tree_set_lift_null_get (_tmp7_, _tmp8_);
		((_vala_val == NULL) || (self->priv->g_destroy_func == NULL)) ? NULL : (_vala_val = (self->priv->g_destroy_func (_vala_val), NULL));
		_vala_val = _tmp9_;
		_tmp10_ = self->_next;
		result = _tmp10_ != NULL;
		if (val) {
			*val = _vala_val;
		} else {
			((_vala_val == NULL) || (self->priv->g_destroy_func == NULL)) ? NULL : (_vala_val = (self->priv->g_destroy_func (_vala_val), NULL));
		}
		return result;
	}
}

static gboolean
gee_tree_set_iterator_real_foreach (GeeTraversable* base,
                                    GeeForallFunc f,
                                    gpointer f_target)
{
	GeeTreeSetIterator * self;
	GeeTreeSet* _tmp0_;
	GeeTreeSetNode* current = NULL;
	GeeTreeSetNode* _tmp1_;
	GeeTreeSetNode* next = NULL;
	GeeTreeSetNode* _tmp2_;
	GeeTreeSetNode* _tmp21_;
	gboolean result;
	self = (GeeTreeSetIterator*) base;
	_tmp0_ = self->_set;
	_vala_assert (self->stamp == _tmp0_->priv->stamp, "stamp == _set.stamp");
	_tmp1_ = self->_current;
	current = _tmp1_;
	_tmp2_ = current;
	if (_tmp2_ != NULL) {
		GeeTreeSetNode* _tmp3_;
		gconstpointer _tmp4_;
		gpointer _tmp5_;
		GeeTreeSetNode* _tmp6_;
		GeeTreeSetNode* _tmp7_;
		_tmp3_ = current;
		_tmp4_ = _tmp3_->key;
		_tmp5_ = ((_tmp4_ != NULL) && (self->priv->g_dup_func != NULL)) ? self->priv->g_dup_func ((gpointer) _tmp4_) : ((gpointer) _tmp4_);
		if (!f (_tmp5_, f_target)) {
			result = FALSE;
			return result;
		}
		_tmp6_ = current;
		_tmp7_ = _tmp6_->next;
		next = _tmp7_;
	} else {
		if (!self->started) {
			GeeTreeSet* _tmp8_;
			GeeTreeSetNode* _tmp9_;
			GeeTreeSetNode* _tmp10_;
			_tmp8_ = self->_set;
			_tmp9_ = _tmp8_->priv->_first;
			next = _tmp9_;
			_tmp10_ = next;
			if (_tmp10_ != NULL) {
				self->started = TRUE;
			}
		} else {
			GeeTreeSetNode* _tmp11_;
			GeeTreeSetNode* _tmp12_;
			_tmp11_ = self->_next;
			next = _tmp11_;
			_tmp12_ = next;
			if (_tmp12_ != NULL) {
				self->_next = NULL;
				self->_prev = NULL;
			}
		}
	}
	while (TRUE) {
		GeeTreeSetNode* _tmp13_;
		GeeTreeSetNode* _tmp14_;
		gconstpointer _tmp15_;
		gpointer _tmp16_;
		GeeTreeSetNode* _tmp18_;
		GeeTreeSetNode* _tmp19_;
		GeeTreeSetNode* _tmp20_;
		_tmp13_ = next;
		if (!(_tmp13_ != NULL)) {
			break;
		}
		_tmp14_ = next;
		_tmp15_ = _tmp14_->key;
		_tmp16_ = ((_tmp15_ != NULL) && (self->priv->g_dup_func != NULL)) ? self->priv->g_dup_func ((gpointer) _tmp15_) : ((gpointer) _tmp15_);
		if (!f (_tmp16_, f_target)) {
			GeeTreeSetNode* _tmp17_;
			_tmp17_ = next;
			self->_current = _tmp17_;
			result = FALSE;
			return result;
		}
		_tmp18_ = next;
		current = _tmp18_;
		_tmp19_ = current;
		_tmp20_ = _tmp19_->next;
		next = _tmp20_;
	}
	_tmp21_ = current;
	self->_current = _tmp21_;
	result = TRUE;
	return result;
}

static GeeIterator**
gee_tree_set_iterator_real_tee (GeeTraversable* base,
                                guint forks,
                                gint* result_length1)
{
	GeeTreeSetIterator * self;
	GeeIterator** result;
	self = (GeeTreeSetIterator*) base;
	if (forks == ((guint) 0)) {
		GeeIterator** _tmp0_;
		GeeIterator** _tmp1_;
		gint _tmp1__length1;
		_tmp0_ = g_new0 (GeeIterator*, 0 + 1);
		_tmp1_ = _tmp0_;
		_tmp1__length1 = 0;
		if (result_length1) {
			*result_length1 = _tmp1__length1;
		}
		result = _tmp1_;
		return result;
	} else {
		GeeIterator** _result_ = NULL;
		GeeIterator** _tmp2_;
		gint _result__length1;
		gint __result__size_;
		GeeIterator** _tmp3_;
		gint _tmp3__length1;
		GeeIterator* _tmp4_;
		GeeIterator** _tmp9_;
		gint _tmp9__length1;
		_tmp2_ = g_new0 (GeeIterator*, forks + 1);
		_result_ = _tmp2_;
		_result__length1 = forks;
		__result__size_ = _result__length1;
		_tmp3_ = _result_;
		_tmp3__length1 = _result__length1;
		_tmp4_ = _g_object_ref0 ((GeeIterator*) self);
		_g_object_unref0 (_tmp3_[0]);
		_tmp3_[0] = _tmp4_;
		{
			guint i = 0U;
			i = (guint) 1;
			{
				gboolean _tmp5_ = FALSE;
				_tmp5_ = TRUE;
				while (TRUE) {
					GeeIterator** _tmp7_;
					gint _tmp7__length1;
					GeeTreeSetIterator* _tmp8_;
					if (!_tmp5_) {
						guint _tmp6_;
						_tmp6_ = i;
						i = _tmp6_ + 1;
					}
					_tmp5_ = FALSE;
					if (!(i < forks)) {
						break;
					}
					_tmp7_ = _result_;
					_tmp7__length1 = _result__length1;
					_tmp8_ = gee_tree_set_iterator_new_from_iterator (self->priv->g_type, (GBoxedCopyFunc) self->priv->g_dup_func, (GDestroyNotify) self->priv->g_destroy_func, self);
					_g_object_unref0 (_tmp7_[i]);
					_tmp7_[i] = (GeeIterator*) _tmp8_;
				}
			}
		}
		_tmp9_ = _result_;
		_tmp9__length1 = _result__length1;
		if (result_length1) {
			*result_length1 = _tmp9__length1;
		}
		result = _tmp9_;
		return result;
	}
}

static gboolean
gee_tree_set_iterator_real_get_valid (GeeIterator* base)
{
	gboolean result;
	GeeTreeSetIterator* self;
	GeeTreeSet* _tmp0_;
	GeeTreeSetNode* _tmp1_;
	self = (GeeTreeSetIterator*) base;
	_tmp0_ = self->_set;
	_vala_assert (self->stamp == _tmp0_->priv->stamp, "stamp == _set.stamp");
	_tmp1_ = self->_current;
	result = _tmp1_ != NULL;
	return result;
}

static gboolean
gee_tree_set_iterator_real_get_read_only (GeeIterator* base)
{
	gboolean result;
	GeeTreeSetIterator* self;
	self = (GeeTreeSetIterator*) base;
	result = FALSE;
	return result;
}

static void
gee_tree_set_iterator_class_init (GeeTreeSetIteratorClass * klass,
                                  gpointer klass_data)
{
	gee_tree_set_iterator_parent_class = g_type_class_peek_parent (klass);
	g_type_class_adjust_private_offset (klass, &GeeTreeSetIterator_private_offset);
	G_OBJECT_CLASS (klass)->get_property = _vala_gee_tree_set_iterator_get_property;
	G_OBJECT_CLASS (klass)->set_property = _vala_gee_tree_set_iterator_set_property;
	G_OBJECT_CLASS (klass)->finalize = gee_tree_set_iterator_finalize;
	g_object_class_install_property (G_OBJECT_CLASS (klass), GEE_TREE_SET_ITERATOR_G_TYPE, g_param_spec_gtype ("g-type", "type", "type", G_TYPE_NONE, G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
	g_object_class_install_property (G_OBJECT_CLASS (klass), GEE_TREE_SET_ITERATOR_G_DUP_FUNC, g_param_spec_pointer ("g-dup-func", "dup func", "dup func", G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
	g_object_class_install_property (G_OBJECT_CLASS (klass), GEE_TREE_SET_ITERATOR_G_DESTROY_FUNC, g_param_spec_pointer ("g-destroy-func", "destroy func", "destroy func", G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
	g_object_class_install_property (G_OBJECT_CLASS (klass), GEE_TREE_SET_ITERATOR_VALID_PROPERTY, gee_tree_set_iterator_properties[GEE_TREE_SET_ITERATOR_VALID_PROPERTY] = g_param_spec_boolean ("valid", "valid", "valid", FALSE, G_PARAM_STATIC_STRINGS | G_PARAM_READABLE));
	g_object_class_install_property (G_OBJECT_CLASS (klass), GEE_TREE_SET_ITERATOR_READ_ONLY_PROPERTY, gee_tree_set_iterator_properties[GEE_TREE_SET_ITERATOR_READ_ONLY_PROPERTY] = g_param_spec_boolean ("read-only", "read-only", "read-only", FALSE, G_PARAM_STATIC_STRINGS | G_PARAM_READABLE));
}

static GType
gee_tree_set_iterator_gee_traversable_get_g_type (GeeTreeSetIterator* self)
{
	return self->priv->g_type;
}

static GBoxedCopyFunc
gee_tree_set_iterator_gee_traversable_get_g_dup_func (GeeTreeSetIterator* self)
{
	return self->priv->g_dup_func;
}

static GDestroyNotify
gee_tree_set_iterator_gee_traversable_get_g_destroy_func (GeeTreeSetIterator* self)
{
	return self->priv->g_destroy_func;
}

static void
gee_tree_set_iterator_gee_traversable_interface_init (GeeTraversableIface * iface,
                                                      gpointer iface_data)
{
	gee_tree_set_iterator_gee_traversable_parent_iface = g_type_interface_peek_parent (iface);
	iface->foreach = (gboolean (*) (GeeTraversable*, GeeForallFunc, gpointer)) gee_tree_set_iterator_real_foreach;
	iface->tee = (GeeIterator** (*) (GeeTraversable*, guint, gint*)) gee_tree_set_iterator_real_tee;
	iface->get_g_type = (GType (*) (GeeTraversable *)) gee_tree_set_iterator_gee_traversable_get_g_type;
	iface->get_g_dup_func = (GBoxedCopyFunc (*) (GeeTraversable *)) gee_tree_set_iterator_gee_traversable_get_g_dup_func;
	iface->get_g_destroy_func = (GDestroyNotify (*) (GeeTraversable *)) gee_tree_set_iterator_gee_traversable_get_g_destroy_func;
}

static void
gee_tree_set_iterator_gee_iterator_interface_init (GeeIteratorIface * iface,
                                                   gpointer iface_data)
{
	gee_tree_set_iterator_gee_iterator_parent_iface = g_type_interface_peek_parent (iface);
	iface->next = (gboolean (*) (GeeIterator*)) gee_tree_set_iterator_real_next;
	iface->has_next = (gboolean (*) (GeeIterator*)) gee_tree_set_iterator_real_has_next;
	iface->get = (gpointer (*) (GeeIterator*)) gee_tree_set_iterator_real_get;
	iface->remove = (void (*) (GeeIterator*)) gee_tree_set_iterator_real_remove;
	iface->get_valid = gee_tree_set_iterator_real_get_valid;
	iface->get_read_only = gee_tree_set_iterator_real_get_read_only;
}

static GType
gee_tree_set_iterator_gee_bidir_iterator_get_g_type (GeeTreeSetIterator* self)
{
	return self->priv->g_type;
}

static GBoxedCopyFunc
gee_tree_set_iterator_gee_bidir_iterator_get_g_dup_func (GeeTreeSetIterator* self)
{
	return self->priv->g_dup_func;
}

static GDestroyNotify
gee_tree_set_iterator_gee_bidir_iterator_get_g_destroy_func (GeeTreeSetIterator* self)
{
	return self->priv->g_destroy_func;
}

static void
gee_tree_set_iterator_gee_bidir_iterator_interface_init (GeeBidirIteratorIface * iface,
                                                         gpointer iface_data)
{
	gee_tree_set_iterator_gee_bidir_iterator_parent_iface = g_type_interface_peek_parent (iface);
	iface->first = (gboolean (*) (GeeBidirIterator*)) gee_tree_set_iterator_real_first;
	iface->previous = (gboolean (*) (GeeBidirIterator*)) gee_tree_set_iterator_real_previous;
	iface->has_previous = (gboolean (*) (GeeBidirIterator*)) gee_tree_set_iterator_real_has_previous;
	iface->last = (gboolean (*) (GeeBidirIterator*)) gee_tree_set_iterator_real_last;
	iface->get_g_type = (GType (*) (GeeBidirIterator *)) gee_tree_set_iterator_gee_bidir_iterator_get_g_type;
	iface->get_g_dup_func = (GBoxedCopyFunc (*) (GeeBidirIterator *)) gee_tree_set_iterator_gee_bidir_iterator_get_g_dup_func;
	iface->get_g_destroy_func = (GDestroyNotify (*) (GeeBidirIterator *)) gee_tree_set_iterator_gee_bidir_iterator_get_g_destroy_func;
}

static void
gee_tree_set_iterator_instance_init (GeeTreeSetIterator * self,
                                     gpointer klass)
{
	self->priv = gee_tree_set_iterator_get_instance_private (self);
	self->_current = NULL;
	self->_next = NULL;
	self->_prev = NULL;
	self->started = FALSE;
}

static void
gee_tree_set_iterator_finalize (GObject * obj)
{
	GeeTreeSetIterator * self;
	self = G_TYPE_CHECK_INSTANCE_CAST (obj, GEE_TREE_SET_TYPE_ITERATOR, GeeTreeSetIterator);
	_g_object_unref0 (self->_set);
	G_OBJECT_CLASS (gee_tree_set_iterator_parent_class)->finalize (obj);
}

static GType
gee_tree_set_iterator_get_type_once (void)
{
	static const GTypeInfo g_define_type_info = { sizeof (GeeTreeSetIteratorClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) gee_tree_set_iterator_class_init, (GClassFinalizeFunc) NULL, NULL, sizeof (GeeTreeSetIterator), 0, (GInstanceInitFunc) gee_tree_set_iterator_instance_init, NULL };
	static const GInterfaceInfo gee_traversable_info = { (GInterfaceInitFunc) gee_tree_set_iterator_gee_traversable_interface_init, (GInterfaceFinalizeFunc) NULL, NULL};
	static const GInterfaceInfo gee_iterator_info = { (GInterfaceInitFunc) gee_tree_set_iterator_gee_iterator_interface_init, (GInterfaceFinalizeFunc) NULL, NULL};
	static const GInterfaceInfo gee_bidir_iterator_info = { (GInterfaceInitFunc) gee_tree_set_iterator_gee_bidir_iterator_interface_init, (GInterfaceFinalizeFunc) NULL, NULL};
	GType gee_tree_set_iterator_type_id;
	gee_tree_set_iterator_type_id = g_type_register_static (G_TYPE_OBJECT, "GeeTreeSetIterator", &g_define_type_info, 0);
	g_type_add_interface_static (gee_tree_set_iterator_type_id, GEE_TYPE_TRAVERSABLE, &gee_traversable_info);
	g_type_add_interface_static (gee_tree_set_iterator_type_id, GEE_TYPE_ITERATOR, &gee_iterator_info);
	g_type_add_interface_static (gee_tree_set_iterator_type_id, GEE_TYPE_BIDIR_ITERATOR, &gee_bidir_iterator_info);
	GeeTreeSetIterator_private_offset = g_type_add_instance_private (gee_tree_set_iterator_type_id, sizeof (GeeTreeSetIteratorPrivate));
	return gee_tree_set_iterator_type_id;
}

static GType
gee_tree_set_iterator_get_type (void)
{
	static volatile gsize gee_tree_set_iterator_type_id__once = 0;
	if (g_once_init_enter (&gee_tree_set_iterator_type_id__once)) {
		GType gee_tree_set_iterator_type_id;
		gee_tree_set_iterator_type_id = gee_tree_set_iterator_get_type_once ();
		g_once_init_leave (&gee_tree_set_iterator_type_id__once, gee_tree_set_iterator_type_id);
	}
	return gee_tree_set_iterator_type_id__once;
}

static void
_vala_gee_tree_set_iterator_get_property (GObject * object,
                                          guint property_id,
                                          GValue * value,
                                          GParamSpec * pspec)
{
	GeeTreeSetIterator * self;
	self = G_TYPE_CHECK_INSTANCE_CAST (object, GEE_TREE_SET_TYPE_ITERATOR, GeeTreeSetIterator);
	switch (property_id) {
		case GEE_TREE_SET_ITERATOR_VALID_PROPERTY:
		g_value_set_boolean (value, gee_iterator_get_valid ((GeeIterator*) self));
		break;
		case GEE_TREE_SET_ITERATOR_READ_ONLY_PROPERTY:
		g_value_set_boolean (value, gee_iterator_get_read_only ((GeeIterator*) self));
		break;
		case GEE_TREE_SET_ITERATOR_G_TYPE:
		g_value_set_gtype (value, self->priv->g_type);
		break;
		case GEE_TREE_SET_ITERATOR_G_DUP_FUNC:
		g_value_set_pointer (value, self->priv->g_dup_func);
		break;
		case GEE_TREE_SET_ITERATOR_G_DESTROY_FUNC:
		g_value_set_pointer (value, self->priv->g_destroy_func);
		break;
		default:
		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
		break;
	}
}

static void
_vala_gee_tree_set_iterator_set_property (GObject * object,
                                          guint property_id,
                                          const GValue * value,
                                          GParamSpec * pspec)
{
	GeeTreeSetIterator * self;
	self = G_TYPE_CHECK_INSTANCE_CAST (object, GEE_TREE_SET_TYPE_ITERATOR, GeeTreeSetIterator);
	switch (property_id) {
		case GEE_TREE_SET_ITERATOR_G_TYPE:
		self->priv->g_type = g_value_get_gtype (value);
		break;
		case GEE_TREE_SET_ITERATOR_G_DUP_FUNC:
		self->priv->g_dup_func = g_value_get_pointer (value);
		break;
		case GEE_TREE_SET_ITERATOR_G_DESTROY_FUNC:
		self->priv->g_destroy_func = g_value_get_pointer (value);
		break;
		default:
		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
		break;
	}
}

static inline gpointer
gee_tree_set_range_get_instance_private (GeeTreeSetRange* self)
{
	return G_STRUCT_MEMBER_P (self, GeeTreeSetRange_private_offset);
}

static GeeTreeSetRange*
gee_tree_set_range_construct (GType object_type,
                              GType g_type,
                              GBoxedCopyFunc g_dup_func,
                              GDestroyNotify g_destroy_func,
                              GeeTreeSet* set,
                              gconstpointer after,
                              gconstpointer before)
{
	GeeTreeSetRange* self = NULL;
	GeeTreeSet* _tmp0_;
	GCompareDataFunc _tmp1_ = NULL;
	gpointer _tmp1__target = NULL;
	GCompareDataFunc _tmp2_;
	gpointer _tmp2__target;
	g_return_val_if_fail (set != NULL, NULL);
	self = (GeeTreeSetRange*) 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;
	_tmp0_ = _g_object_ref0 (set);
	_g_object_unref0 (self->priv->set);
	self->priv->set = _tmp0_;
	_tmp1_ = gee_tree_set_get_compare_func (set, &_tmp1__target);
	_tmp2_ = _tmp1_;
	_tmp2__target = _tmp1__target;
	if (_tmp2_ (after, before, _tmp2__target) < 0) {
		gpointer _tmp3_;
		gpointer _tmp4_;
		_tmp3_ = ((after != NULL) && (g_dup_func != NULL)) ? g_dup_func ((gpointer) after) : ((gpointer) after);
		((self->priv->after == NULL) || (g_destroy_func == NULL)) ? NULL : (self->priv->after = (g_destroy_func (self->priv->after), NULL));
		self->priv->after = _tmp3_;
		_tmp4_ = ((before != NULL) && (g_dup_func != NULL)) ? g_dup_func ((gpointer) before) : ((gpointer) before);
		((self->priv->before == NULL) || (g_destroy_func == NULL)) ? NULL : (self->priv->before = (g_destroy_func (self->priv->before), NULL));
		self->priv->before = _tmp4_;
		self->priv->type = GEE_TREE_SET_RANGE_TYPE_BOUNDED;
	} else {
		self->priv->type = GEE_TREE_SET_RANGE_TYPE_EMPTY;
	}
	return self;
}

static GeeTreeSetRange*
gee_tree_set_range_new (GType g_type,
                        GBoxedCopyFunc g_dup_func,
                        GDestroyNotify g_destroy_func,
                        GeeTreeSet* set,
                        gconstpointer after,
                        gconstpointer before)
{
	return gee_tree_set_range_construct (GEE_TREE_SET_TYPE_RANGE, g_type, g_dup_func, g_destroy_func, set, after, before);
}

static GeeTreeSetRange*
gee_tree_set_range_construct_head (GType object_type,
                                   GType g_type,
                                   GBoxedCopyFunc g_dup_func,
                                   GDestroyNotify g_destroy_func,
                                   GeeTreeSet* set,
                                   gconstpointer before)
{
	GeeTreeSetRange* self = NULL;
	GeeTreeSet* _tmp0_;
	gpointer _tmp1_;
	g_return_val_if_fail (set != NULL, NULL);
	self = (GeeTreeSetRange*) 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;
	_tmp0_ = _g_object_ref0 (set);
	_g_object_unref0 (self->priv->set);
	self->priv->set = _tmp0_;
	_tmp1_ = ((before != NULL) && (g_dup_func != NULL)) ? g_dup_func ((gpointer) before) : ((gpointer) before);
	((self->priv->before == NULL) || (g_destroy_func == NULL)) ? NULL : (self->priv->before = (g_destroy_func (self->priv->before), NULL));
	self->priv->before = _tmp1_;
	self->priv->type = GEE_TREE_SET_RANGE_TYPE_HEAD;
	return self;
}

static GeeTreeSetRange*
gee_tree_set_range_new_head (GType g_type,
                             GBoxedCopyFunc g_dup_func,
                             GDestroyNotify g_destroy_func,
                             GeeTreeSet* set,
                             gconstpointer before)
{
	return gee_tree_set_range_construct_head (GEE_TREE_SET_TYPE_RANGE, g_type, g_dup_func, g_destroy_func, set, before);
}

static GeeTreeSetRange*
gee_tree_set_range_construct_tail (GType object_type,
                                   GType g_type,
                                   GBoxedCopyFunc g_dup_func,
                                   GDestroyNotify g_destroy_func,
                                   GeeTreeSet* set,
                                   gconstpointer after)
{
	GeeTreeSetRange* self = NULL;
	GeeTreeSet* _tmp0_;
	gpointer _tmp1_;
	g_return_val_if_fail (set != NULL, NULL);
	self = (GeeTreeSetRange*) 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;
	_tmp0_ = _g_object_ref0 (set);
	_g_object_unref0 (self->priv->set);
	self->priv->set = _tmp0_;
	_tmp1_ = ((after != NULL) && (g_dup_func != NULL)) ? g_dup_func ((gpointer) after) : ((gpointer) after);
	((self->priv->after == NULL) || (g_destroy_func == NULL)) ? NULL : (self->priv->after = (g_destroy_func (self->priv->after), NULL));
	self->priv->after = _tmp1_;
	self->priv->type = GEE_TREE_SET_RANGE_TYPE_TAIL;
	return self;
}

static GeeTreeSetRange*
gee_tree_set_range_new_tail (GType g_type,
                             GBoxedCopyFunc g_dup_func,
                             GDestroyNotify g_destroy_func,
                             GeeTreeSet* set,
                             gconstpointer after)
{
	return gee_tree_set_range_construct_tail (GEE_TREE_SET_TYPE_RANGE, g_type, g_dup_func, g_destroy_func, set, after);
}

static gpointer
_gee_tree_set_range_ref0 (gpointer self)
{
	return self ? gee_tree_set_range_ref (self) : NULL;
}

static GeeTreeSetRange*
gee_tree_set_range_cut_head (GeeTreeSetRange* self,
                             gconstpointer after)
{
	GeeTreeSetRange* result;
	g_return_val_if_fail (self != NULL, NULL);
	switch (self->priv->type) {
		case GEE_TREE_SET_RANGE_TYPE_HEAD:
		{
			GeeTreeSet* _tmp0_;
			gconstpointer _tmp1_;
			GeeTreeSetRange* _tmp2_;
			_tmp0_ = self->priv->set;
			_tmp1_ = self->priv->before;
			_tmp2_ = gee_tree_set_range_new (self->priv->g_type, (GBoxedCopyFunc) self->priv->g_dup_func, (GDestroyNotify) self->priv->g_destroy_func, _tmp0_, after, _tmp1_);
			result = _tmp2_;
			return result;
		}
		case GEE_TREE_SET_RANGE_TYPE_TAIL:
		{
			GeeTreeSet* _tmp3_;
			GeeTreeSet* _tmp4_;
			gconstpointer _tmp5_;
			gpointer _tmp6_;
			gpointer _tmp7_;
			GeeTreeSetRange* _tmp8_;
			GeeTreeSetRange* _tmp9_;
			_tmp3_ = self->priv->set;
			_tmp4_ = self->priv->set;
			_tmp5_ = self->priv->after;
			_tmp6_ = gee_tree_set_max (_tmp4_, after, _tmp5_);
			_tmp7_ = _tmp6_;
			_tmp8_ = gee_tree_set_range_new_tail (self->priv->g_type, (GBoxedCopyFunc) self->priv->g_dup_func, (GDestroyNotify) self->priv->g_destroy_func, _tmp3_, _tmp7_);
			_tmp9_ = _tmp8_;
			((_tmp7_ == NULL) || (self->priv->g_destroy_func == NULL)) ? NULL : (_tmp7_ = (self->priv->g_destroy_func (_tmp7_), NULL));
			result = _tmp9_;
			return result;
		}
		case GEE_TREE_SET_RANGE_TYPE_EMPTY:
		{
			GeeTreeSetRange* _tmp10_;
			_tmp10_ = _gee_tree_set_range_ref0 (self);
			result = _tmp10_;
			return result;
		}
		case GEE_TREE_SET_RANGE_TYPE_BOUNDED:
		{
			gpointer _after = NULL;
			GeeTreeSet* _tmp11_;
			gconstpointer _tmp12_;
			gpointer _tmp13_;
			GeeTreeSet* _tmp14_;
			gconstpointer _tmp15_;
			gconstpointer _tmp16_;
			GeeTreeSetRange* _tmp17_;
			_tmp11_ = self->priv->set;
			_tmp12_ = self->priv->after;
			_tmp13_ = gee_tree_set_max (_tmp11_, after, _tmp12_);
			_after = _tmp13_;
			_tmp14_ = self->priv->set;
			_tmp15_ = _after;
			_tmp16_ = self->priv->before;
			_tmp17_ = gee_tree_set_range_new (self->priv->g_type, (GBoxedCopyFunc) self->priv->g_dup_func, (GDestroyNotify) self->priv->g_destroy_func, _tmp14_, _tmp15_, _tmp16_);
			result = _tmp17_;
			((_after == NULL) || (self->priv->g_destroy_func == NULL)) ? NULL : (_after = (self->priv->g_destroy_func (_after), NULL));
			return result;
		}
		default:
		{
			g_assert_not_reached ();
		}
	}
}

static GeeTreeSetRange*
gee_tree_set_range_cut_tail (GeeTreeSetRange* self,
                             gconstpointer before)
{
	GeeTreeSetRange* result;
	g_return_val_if_fail (self != NULL, NULL);
	switch (self->priv->type) {
		case GEE_TREE_SET_RANGE_TYPE_HEAD:
		{
			GeeTreeSet* _tmp0_;
			GeeTreeSet* _tmp1_;
			gconstpointer _tmp2_;
			gpointer _tmp3_;
			gpointer _tmp4_;
			GeeTreeSetRange* _tmp5_;
			GeeTreeSetRange* _tmp6_;
			_tmp0_ = self->priv->set;
			_tmp1_ = self->priv->set;
			_tmp2_ = self->priv->before;
			_tmp3_ = gee_tree_set_min (_tmp1_, before, _tmp2_);
			_tmp4_ = _tmp3_;
			_tmp5_ = gee_tree_set_range_new_head (self->priv->g_type, (GBoxedCopyFunc) self->priv->g_dup_func, (GDestroyNotify) self->priv->g_destroy_func, _tmp0_, _tmp4_);
			_tmp6_ = _tmp5_;
			((_tmp4_ == NULL) || (self->priv->g_destroy_func == NULL)) ? NULL : (_tmp4_ = (self->priv->g_destroy_func (_tmp4_), NULL));
			result = _tmp6_;
			return result;
		}
		case GEE_TREE_SET_RANGE_TYPE_TAIL:
		{
			GeeTreeSet* _tmp7_;
			gconstpointer _tmp8_;
			GeeTreeSetRange* _tmp9_;
			_tmp7_ = self->priv->set;
			_tmp8_ = self->priv->after;
			_tmp9_ = gee_tree_set_range_new (self->priv->g_type, (GBoxedCopyFunc) self->priv->g_dup_func, (GDestroyNotify) self->priv->g_destroy_func, _tmp7_, _tmp8_, before);
			result = _tmp9_;
			return result;
		}
		case GEE_TREE_SET_RANGE_TYPE_EMPTY:
		{
			GeeTreeSetRange* _tmp10_;
			_tmp10_ = _gee_tree_set_range_ref0 (self);
			result = _tmp10_;
			return result;
		}
		case GEE_TREE_SET_RANGE_TYPE_BOUNDED:
		{
			gpointer _before = NULL;
			GeeTreeSet* _tmp11_;
			gconstpointer _tmp12_;
			gpointer _tmp13_;
			GeeTreeSet* _tmp14_;
			gconstpointer _tmp15_;
			gconstpointer _tmp16_;
			GeeTreeSetRange* _tmp17_;
			_tmp11_ = self->priv->set;
			_tmp12_ = self->priv->before;
			_tmp13_ = gee_tree_set_min (_tmp11_, before, _tmp12_);
			_before = _tmp13_;
			_tmp14_ = self->priv->set;
			_tmp15_ = self->priv->after;
			_tmp16_ = _before;
			_tmp17_ = gee_tree_set_range_new (self->priv->g_type, (GBoxedCopyFunc) self->priv->g_dup_func, (GDestroyNotify) self->priv->g_destroy_func, _tmp14_, _tmp15_, _tmp16_);
			result = _tmp17_;
			((_before == NULL) || (self->priv->g_destroy_func == NULL)) ? NULL : (_before = (self->priv->g_destroy_func (_before), NULL));
			return result;
		}
		default:
		{
			g_assert_not_reached ();
		}
	}
}

static GeeTreeSetRange*
gee_tree_set_range_cut (GeeTreeSetRange* self,
                        gconstpointer after,
                        gconstpointer before)
{
	gpointer _tmp1_ = NULL;
	gpointer _before = NULL;
	gpointer _tmp6_;
	gpointer _tmp7_ = NULL;
	gpointer _after = NULL;
	gpointer _tmp12_;
	GeeTreeSet* _tmp13_;
	gconstpointer _tmp14_;
	gconstpointer _tmp15_;
	GeeTreeSetRange* _tmp16_;
	GeeTreeSetRange* result;
	g_return_val_if_fail (self != NULL, NULL);
	if (self->priv->type == GEE_TREE_SET_RANGE_TYPE_EMPTY) {
		GeeTreeSetRange* _tmp0_;
		_tmp0_ = _gee_tree_set_range_ref0 (self);
		result = _tmp0_;
		return result;
	}
	if (self->priv->type != GEE_TREE_SET_RANGE_TYPE_TAIL) {
		GeeTreeSet* _tmp2_;
		gconstpointer _tmp3_;
		gpointer _tmp4_;
		_tmp2_ = self->priv->set;
		_tmp3_ = self->priv->before;
		_tmp4_ = gee_tree_set_min (_tmp2_, before, _tmp3_);
		((_tmp1_ == NULL) || (self->priv->g_destroy_func == NULL)) ? NULL : (_tmp1_ = (self->priv->g_destroy_func (_tmp1_), NULL));
		_tmp1_ = _tmp4_;
	} else {
		gpointer _tmp5_;
		_tmp5_ = ((before != NULL) && (self->priv->g_dup_func != NULL)) ? self->priv->g_dup_func ((gpointer) before) : ((gpointer) before);
		((_tmp1_ == NULL) || (self->priv->g_destroy_func == NULL)) ? NULL : (_tmp1_ = (self->priv->g_destroy_func (_tmp1_), NULL));
		_tmp1_ = _tmp5_;
	}
	_tmp6_ = ((_tmp1_ != NULL) && (self->priv->g_dup_func != NULL)) ? self->priv->g_dup_func ((gpointer) _tmp1_) : ((gpointer) _tmp1_);
	_before = _tmp6_;
	if (self->priv->type != GEE_TREE_SET_RANGE_TYPE_HEAD) {
		GeeTreeSet* _tmp8_;
		gconstpointer _tmp9_;
		gpointer _tmp10_;
		_tmp8_ = self->priv->set;
		_tmp9_ = self->priv->after;
		_tmp10_ = gee_tree_set_max (_tmp8_, after, _tmp9_);
		((_tmp7_ == NULL) || (self->priv->g_destroy_func == NULL)) ? NULL : (_tmp7_ = (self->priv->g_destroy_func (_tmp7_), NULL));
		_tmp7_ = _tmp10_;
	} else {
		gpointer _tmp11_;
		_tmp11_ = ((after != NULL) && (self->priv->g_dup_func != NULL)) ? self->priv->g_dup_func ((gpointer) after) : ((gpointer) after);
		((_tmp7_ == NULL) || (self->priv->g_destroy_func == NULL)) ? NULL : (_tmp7_ = (self->priv->g_destroy_func (_tmp7_), NULL));
		_tmp7_ = _tmp11_;
	}
	_tmp12_ = ((_tmp7_ != NULL) && (self->priv->g_dup_func != NULL)) ? self->priv->g_dup_func ((gpointer) _tmp7_) : ((gpointer) _tmp7_);
	_after = _tmp12_;
	_tmp13_ = self->priv->set;
	_tmp14_ = _after;
	_tmp15_ = _before;
	_tmp16_ = gee_tree_set_range_new (self->priv->g_type, (GBoxedCopyFunc) self->priv->g_dup_func, (GDestroyNotify) self->priv->g_destroy_func, _tmp13_, _tmp14_, _tmp15_);
	result = _tmp16_;
	((_after == NULL) || (self->priv->g_destroy_func == NULL)) ? NULL : (_after = (self->priv->g_destroy_func (_after), NULL));
	((_tmp7_ == NULL) || (self->priv->g_destroy_func == NULL)) ? NULL : (_tmp7_ = (self->priv->g_destroy_func (_tmp7_), NULL));
	((_before == NULL) || (self->priv->g_destroy_func == NULL)) ? NULL : (_before = (self->priv->g_destroy_func (_before), NULL));
	((_tmp1_ == NULL) || (self->priv->g_destroy_func == NULL)) ? NULL : (_tmp1_ = (self->priv->g_destroy_func (_tmp1_), NULL));
	return result;
}

static gboolean
gee_tree_set_range_in_range (GeeTreeSetRange* self,
                             gconstpointer item)
{
	gboolean _tmp0_ = FALSE;
	gboolean result;
	g_return_val_if_fail (self != NULL, FALSE);
	if (self->priv->type == GEE_TREE_SET_RANGE_TYPE_EMPTY) {
		_tmp0_ = FALSE;
	} else {
		_tmp0_ = gee_tree_set_range_compare_range (self, item) == 0;
	}
	result = _tmp0_;
	return result;
}

static gint
gee_tree_set_range_compare_range (GeeTreeSetRange* self,
                                  gconstpointer item)
{
	gint result;
	g_return_val_if_fail (self != NULL, 0);
	switch (self->priv->type) {
		case GEE_TREE_SET_RANGE_TYPE_HEAD:
		{
			gint _tmp0_ = 0;
			GeeTreeSet* _tmp1_;
			GCompareDataFunc _tmp2_ = NULL;
			gpointer _tmp2__target = NULL;
			GCompareDataFunc _tmp3_;
			gpointer _tmp3__target;
			gconstpointer _tmp4_;
			_tmp1_ = self->priv->set;
			_tmp2_ = gee_tree_set_get_compare_func (_tmp1_, &_tmp2__target);
			_tmp3_ = _tmp2_;
			_tmp3__target = _tmp2__target;
			_tmp4_ = self->priv->before;
			if (_tmp3_ (item, _tmp4_, _tmp3__target) < 0) {
				_tmp0_ = 0;
			} else {
				_tmp0_ = 1;
			}
			result = _tmp0_;
			return result;
		}
		case GEE_TREE_SET_RANGE_TYPE_TAIL:
		{
			gint _tmp5_ = 0;
			GeeTreeSet* _tmp6_;
			GCompareDataFunc _tmp7_ = NULL;
			gpointer _tmp7__target = NULL;
			GCompareDataFunc _tmp8_;
			gpointer _tmp8__target;
			gconstpointer _tmp9_;
			_tmp6_ = self->priv->set;
			_tmp7_ = gee_tree_set_get_compare_func (_tmp6_, &_tmp7__target);
			_tmp8_ = _tmp7_;
			_tmp8__target = _tmp7__target;
			_tmp9_ = self->priv->after;
			if (_tmp8_ (item, _tmp9_, _tmp8__target) >= 0) {
				_tmp5_ = 0;
			} else {
				_tmp5_ = -1;
			}
			result = _tmp5_;
			return result;
		}
		case GEE_TREE_SET_RANGE_TYPE_EMPTY:
		{
			result = 0;
			return result;
		}
		case GEE_TREE_SET_RANGE_TYPE_BOUNDED:
		{
			gint _tmp10_ = 0;
			GeeTreeSet* _tmp11_;
			GCompareDataFunc _tmp12_ = NULL;
			gpointer _tmp12__target = NULL;
			GCompareDataFunc _tmp13_;
			gpointer _tmp13__target;
			gconstpointer _tmp14_;
			_tmp11_ = self->priv->set;
			_tmp12_ = gee_tree_set_get_compare_func (_tmp11_, &_tmp12__target);
			_tmp13_ = _tmp12_;
			_tmp13__target = _tmp12__target;
			_tmp14_ = self->priv->after;
			if (_tmp13_ (item, _tmp14_, _tmp13__target) >= 0) {
				gint _tmp15_ = 0;
				GeeTreeSet* _tmp16_;
				GCompareDataFunc _tmp17_ = NULL;
				gpointer _tmp17__target = NULL;
				GCompareDataFunc _tmp18_;
				gpointer _tmp18__target;
				gconstpointer _tmp19_;
				_tmp16_ = self->priv->set;
				_tmp17_ = gee_tree_set_get_compare_func (_tmp16_, &_tmp17__target);
				_tmp18_ = _tmp17_;
				_tmp18__target = _tmp17__target;
				_tmp19_ = self->priv->before;
				if (_tmp18_ (item, _tmp19_, _tmp18__target) < 0) {
					_tmp15_ = 0;
				} else {
					_tmp15_ = 1;
				}
				_tmp10_ = _tmp15_;
			} else {
				_tmp10_ = -1;
			}
			result = _tmp10_;
			return result;
		}
		default:
		{
			g_assert_not_reached ();
		}
	}
}

static gboolean
gee_tree_set_range_empty_subset (GeeTreeSetRange* self)
{
	gboolean result;
	g_return_val_if_fail (self != NULL, FALSE);
	switch (self->priv->type) {
		case GEE_TREE_SET_RANGE_TYPE_HEAD:
		{
			gboolean _tmp0_ = FALSE;
			GeeTreeSet* _tmp1_;
			GeeTreeSetNode* _tmp2_;
			_tmp1_ = self->priv->set;
			_tmp2_ = _tmp1_->priv->_first;
			if (_tmp2_ == NULL) {
				_tmp0_ = TRUE;
			} else {
				GeeTreeSet* _tmp3_;
				GeeTreeSetNode* _tmp4_;
				gconstpointer _tmp5_;
				_tmp3_ = self->priv->set;
				_tmp4_ = _tmp3_->priv->_first;
				_tmp5_ = _tmp4_->key;
				_tmp0_ = !gee_tree_set_range_in_range (self, _tmp5_);
			}
			result = _tmp0_;
			return result;
		}
		case GEE_TREE_SET_RANGE_TYPE_TAIL:
		{
			gboolean _tmp6_ = FALSE;
			GeeTreeSet* _tmp7_;
			GeeTreeSetNode* _tmp8_;
			_tmp7_ = self->priv->set;
			_tmp8_ = _tmp7_->priv->_last;
			if (_tmp8_ == NULL) {
				_tmp6_ = TRUE;
			} else {
				GeeTreeSet* _tmp9_;
				GeeTreeSetNode* _tmp10_;
				gconstpointer _tmp11_;
				_tmp9_ = self->priv->set;
				_tmp10_ = _tmp9_->priv->_last;
				_tmp11_ = _tmp10_->key;
				_tmp6_ = !gee_tree_set_range_in_range (self, _tmp11_);
			}
			result = _tmp6_;
			return result;
		}
		case GEE_TREE_SET_RANGE_TYPE_EMPTY:
		{
			result = TRUE;
			return result;
		}
		case GEE_TREE_SET_RANGE_TYPE_BOUNDED:
		{
			GeeTreeSetNode* _tmp12_;
			_tmp12_ = gee_tree_set_range_first (self);
			result = _tmp12_ == NULL;
			return result;
		}
		default:
		{
			g_assert_not_reached ();
		}
	}
}

static GeeTreeSetNode*
gee_tree_set_range_first (GeeTreeSetRange* self)
{
	GeeTreeSetNode* result;
	g_return_val_if_fail (self != NULL, NULL);
	switch (self->priv->type) {
		case GEE_TREE_SET_RANGE_TYPE_EMPTY:
		{
			result = NULL;
			return result;
		}
		case GEE_TREE_SET_RANGE_TYPE_HEAD:
		{
			GeeTreeSet* _tmp0_;
			GeeTreeSetNode* _tmp1_;
			_tmp0_ = self->priv->set;
			_tmp1_ = _tmp0_->priv->_first;
			result = _tmp1_;
			return result;
		}
		default:
		{
			GeeTreeSet* _tmp2_;
			gconstpointer _tmp3_;
			GeeTreeSetNode* _tmp4_;
			_tmp2_ = self->priv->set;
			_tmp3_ = self->priv->after;
			_tmp4_ = gee_tree_set_find_floor (_tmp2_, _tmp3_);
			result = _tmp4_;
			return result;
		}
	}
}

static GeeTreeSetNode*
gee_tree_set_range_last (GeeTreeSetRange* self)
{
	GeeTreeSetNode* result;
	g_return_val_if_fail (self != NULL, NULL);
	switch (self->priv->type) {
		case GEE_TREE_SET_RANGE_TYPE_EMPTY:
		{
			result = NULL;
			return result;
		}
		case GEE_TREE_SET_RANGE_TYPE_TAIL:
		{
			GeeTreeSet* _tmp0_;
			GeeTreeSetNode* _tmp1_;
			_tmp0_ = self->priv->set;
			_tmp1_ = _tmp0_->priv->_last;
			result = _tmp1_;
			return result;
		}
		default:
		{
			GeeTreeSet* _tmp2_;
			gconstpointer _tmp3_;
			GeeTreeSetNode* _tmp4_;
			_tmp2_ = self->priv->set;
			_tmp3_ = self->priv->before;
			_tmp4_ = gee_tree_set_find_lower (_tmp2_, _tmp3_);
			result = _tmp4_;
			return result;
		}
	}
}

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

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

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

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

static gchar*
gee_tree_set_value_range_collect_value (GValue* value,
                                        guint n_collect_values,
                                        GTypeCValue* collect_values,
                                        guint collect_flags)
{
	if (collect_values[0].v_pointer) {
		GeeTreeSetRange * 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 = gee_tree_set_range_ref (object);
	} else {
		value->data[0].v_pointer = NULL;
	}
	return NULL;
}

static gchar*
gee_tree_set_value_range_lcopy_value (const GValue* value,
                                      guint n_collect_values,
                                      GTypeCValue* collect_values,
                                      guint collect_flags)
{
	GeeTreeSetRange ** 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 = gee_tree_set_range_ref (value->data[0].v_pointer);
	}
	return NULL;
}

static GParamSpec*
gee_tree_set_param_spec_range (const gchar* name,
                               const gchar* nick,
                               const gchar* blurb,
                               GType object_type,
                               GParamFlags flags)
{
	GeeTreeSetParamSpecRange* spec;
	g_return_val_if_fail (g_type_is_a (object_type, GEE_TREE_SET_TYPE_RANGE), 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);
}

static gpointer
gee_tree_set_value_get_range (const GValue* value)
{
	g_return_val_if_fail (G_TYPE_CHECK_VALUE_TYPE (value, GEE_TREE_SET_TYPE_RANGE), NULL);
	return value->data[0].v_pointer;
}

static void
gee_tree_set_value_set_range (GValue* value,
                              gpointer v_object)
{
	GeeTreeSetRange * old;
	g_return_if_fail (G_TYPE_CHECK_VALUE_TYPE (value, GEE_TREE_SET_TYPE_RANGE));
	old = value->data[0].v_pointer;
	if (v_object) {
		g_return_if_fail (G_TYPE_CHECK_INSTANCE_TYPE (v_object, GEE_TREE_SET_TYPE_RANGE));
		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;
		gee_tree_set_range_ref (value->data[0].v_pointer);
	} else {
		value->data[0].v_pointer = NULL;
	}
	if (old) {
		gee_tree_set_range_unref (old);
	}
}

static void
gee_tree_set_value_take_range (GValue* value,
                               gpointer v_object)
{
	GeeTreeSetRange * old;
	g_return_if_fail (G_TYPE_CHECK_VALUE_TYPE (value, GEE_TREE_SET_TYPE_RANGE));
	old = value->data[0].v_pointer;
	if (v_object) {
		g_return_if_fail (G_TYPE_CHECK_INSTANCE_TYPE (v_object, GEE_TREE_SET_TYPE_RANGE));
		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) {
		gee_tree_set_range_unref (old);
	}
}

static void
gee_tree_set_range_class_init (GeeTreeSetRangeClass * klass,
                               gpointer klass_data)
{
	gee_tree_set_range_parent_class = g_type_class_peek_parent (klass);
	((GeeTreeSetRangeClass *) klass)->finalize = gee_tree_set_range_finalize;
	g_type_class_adjust_private_offset (klass, &GeeTreeSetRange_private_offset);
}

static void
gee_tree_set_range_instance_init (GeeTreeSetRange * self,
                                  gpointer klass)
{
	self->priv = gee_tree_set_range_get_instance_private (self);
	self->ref_count = 1;
}

static void
gee_tree_set_range_finalize (GeeTreeSetRange * obj)
{
	GeeTreeSetRange * self;
	self = G_TYPE_CHECK_INSTANCE_CAST (obj, GEE_TREE_SET_TYPE_RANGE, GeeTreeSetRange);
	g_signal_handlers_destroy (self);
	_g_object_unref0 (self->priv->set);
	((self->priv->after == NULL) || (self->priv->g_destroy_func == NULL)) ? NULL : (self->priv->after = (self->priv->g_destroy_func (self->priv->after), NULL));
	((self->priv->before == NULL) || (self->priv->g_destroy_func == NULL)) ? NULL : (self->priv->before = (self->priv->g_destroy_func (self->priv->before), NULL));
}

static GType
gee_tree_set_range_get_type_once (void)
{
	static const GTypeValueTable g_define_type_value_table = { gee_tree_set_value_range_init, gee_tree_set_value_range_free_value, gee_tree_set_value_range_copy_value, gee_tree_set_value_range_peek_pointer, "p", gee_tree_set_value_range_collect_value, "p", gee_tree_set_value_range_lcopy_value };
	static const GTypeInfo g_define_type_info = { sizeof (GeeTreeSetRangeClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) gee_tree_set_range_class_init, (GClassFinalizeFunc) NULL, NULL, sizeof (GeeTreeSetRange), 0, (GInstanceInitFunc) gee_tree_set_range_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 gee_tree_set_range_type_id;
	gee_tree_set_range_type_id = g_type_register_fundamental (g_type_fundamental_next (), "GeeTreeSetRange", &g_define_type_info, &g_define_type_fundamental_info, 0);
	GeeTreeSetRange_private_offset = g_type_add_instance_private (gee_tree_set_range_type_id, sizeof (GeeTreeSetRangePrivate));
	return gee_tree_set_range_type_id;
}

static GType
gee_tree_set_range_get_type (void)
{
	static volatile gsize gee_tree_set_range_type_id__once = 0;
	if (g_once_init_enter (&gee_tree_set_range_type_id__once)) {
		GType gee_tree_set_range_type_id;
		gee_tree_set_range_type_id = gee_tree_set_range_get_type_once ();
		g_once_init_leave (&gee_tree_set_range_type_id__once, gee_tree_set_range_type_id);
	}
	return gee_tree_set_range_type_id__once;
}

static gpointer
gee_tree_set_range_ref (gpointer instance)
{
	GeeTreeSetRange * self;
	self = instance;
	g_atomic_int_inc (&self->ref_count);
	return instance;
}

static void
gee_tree_set_range_unref (gpointer instance)
{
	GeeTreeSetRange * self;
	self = instance;
	if (g_atomic_int_dec_and_test (&self->ref_count)) {
		GEE_TREE_SET_RANGE_GET_CLASS (self)->finalize (self);
		g_type_free_instance ((GTypeInstance *) self);
	}
}

static inline gpointer
gee_tree_set_sub_set_get_instance_private (GeeTreeSetSubSet* self)
{
	return G_STRUCT_MEMBER_P (self, GeeTreeSetSubSet_private_offset);
}

static GeeTreeSetSubSet*
gee_tree_set_sub_set_construct (GType object_type,
                                GType g_type,
                                GBoxedCopyFunc g_dup_func,
                                GDestroyNotify g_destroy_func,
                                GeeTreeSet* set,
                                gconstpointer after,
                                gconstpointer before)
{
	GeeTreeSetSubSet * self = NULL;
	GeeTreeSet* _tmp0_;
	GeeTreeSetRange* _tmp1_;
	g_return_val_if_fail (set != NULL, NULL);
	self = (GeeTreeSetSubSet*) gee_abstract_bidir_sorted_set_construct (object_type, g_type, (GBoxedCopyFunc) g_dup_func, (GDestroyNotify) g_destroy_func);
	self->priv->g_type = g_type;
	self->priv->g_dup_func = g_dup_func;
	self->priv->g_destroy_func = g_destroy_func;
	_tmp0_ = _g_object_ref0 (set);
	_g_object_unref0 (self->set);
	self->set = _tmp0_;
	_tmp1_ = gee_tree_set_range_new (g_type, (GBoxedCopyFunc) g_dup_func, (GDestroyNotify) g_destroy_func, set, after, before);
	_gee_tree_set_range_unref0 (self->range);
	self->range = _tmp1_;
	return self;
}

static GeeTreeSetSubSet*
gee_tree_set_sub_set_new (GType g_type,
                          GBoxedCopyFunc g_dup_func,
                          GDestroyNotify g_destroy_func,
                          GeeTreeSet* set,
                          gconstpointer after,
                          gconstpointer before)
{
	return gee_tree_set_sub_set_construct (GEE_TREE_SET_TYPE_SUB_SET, g_type, g_dup_func, g_destroy_func, set, after, before);
}

static GeeTreeSetSubSet*
gee_tree_set_sub_set_construct_head (GType object_type,
                                     GType g_type,
                                     GBoxedCopyFunc g_dup_func,
                                     GDestroyNotify g_destroy_func,
                                     GeeTreeSet* set,
                                     gconstpointer before)
{
	GeeTreeSetSubSet * self = NULL;
	GeeTreeSet* _tmp0_;
	GeeTreeSetRange* _tmp1_;
	g_return_val_if_fail (set != NULL, NULL);
	self = (GeeTreeSetSubSet*) gee_abstract_bidir_sorted_set_construct (object_type, g_type, (GBoxedCopyFunc) g_dup_func, (GDestroyNotify) g_destroy_func);
	self->priv->g_type = g_type;
	self->priv->g_dup_func = g_dup_func;
	self->priv->g_destroy_func = g_destroy_func;
	_tmp0_ = _g_object_ref0 (set);
	_g_object_unref0 (self->set);
	self->set = _tmp0_;
	_tmp1_ = gee_tree_set_range_new_head (g_type, (GBoxedCopyFunc) g_dup_func, (GDestroyNotify) g_destroy_func, set, before);
	_gee_tree_set_range_unref0 (self->range);
	self->range = _tmp1_;
	return self;
}

static GeeTreeSetSubSet*
gee_tree_set_sub_set_new_head (GType g_type,
                               GBoxedCopyFunc g_dup_func,
                               GDestroyNotify g_destroy_func,
                               GeeTreeSet* set,
                               gconstpointer before)
{
	return gee_tree_set_sub_set_construct_head (GEE_TREE_SET_TYPE_SUB_SET, g_type, g_dup_func, g_destroy_func, set, before);
}

static GeeTreeSetSubSet*
gee_tree_set_sub_set_construct_tail (GType object_type,
                                     GType g_type,
                                     GBoxedCopyFunc g_dup_func,
                                     GDestroyNotify g_destroy_func,
                                     GeeTreeSet* set,
                                     gconstpointer after)
{
	GeeTreeSetSubSet * self = NULL;
	GeeTreeSet* _tmp0_;
	GeeTreeSetRange* _tmp1_;
	g_return_val_if_fail (set != NULL, NULL);
	self = (GeeTreeSetSubSet*) gee_abstract_bidir_sorted_set_construct (object_type, g_type, (GBoxedCopyFunc) g_dup_func, (GDestroyNotify) g_destroy_func);
	self->priv->g_type = g_type;
	self->priv->g_dup_func = g_dup_func;
	self->priv->g_destroy_func = g_destroy_func;
	_tmp0_ = _g_object_ref0 (set);
	_g_object_unref0 (self->set);
	self->set = _tmp0_;
	_tmp1_ = gee_tree_set_range_new_tail (g_type, (GBoxedCopyFunc) g_dup_func, (GDestroyNotify) g_destroy_func, set, after);
	_gee_tree_set_range_unref0 (self->range);
	self->range = _tmp1_;
	return self;
}

static GeeTreeSetSubSet*
gee_tree_set_sub_set_new_tail (GType g_type,
                               GBoxedCopyFunc g_dup_func,
                               GDestroyNotify g_destroy_func,
                               GeeTreeSet* set,
                               gconstpointer after)
{
	return gee_tree_set_sub_set_construct_tail (GEE_TREE_SET_TYPE_SUB_SET, g_type, g_dup_func, g_destroy_func, set, after);
}

static GeeTreeSetSubSet*
gee_tree_set_sub_set_construct_from_range (GType object_type,
                                           GType g_type,
                                           GBoxedCopyFunc g_dup_func,
                                           GDestroyNotify g_destroy_func,
                                           GeeTreeSet* set,
                                           GeeTreeSetRange* range)
{
	GeeTreeSetSubSet * self = NULL;
	GeeTreeSet* _tmp0_;
	GeeTreeSetRange* _tmp1_;
	g_return_val_if_fail (set != NULL, NULL);
	g_return_val_if_fail (range != NULL, NULL);
	self = (GeeTreeSetSubSet*) gee_abstract_bidir_sorted_set_construct (object_type, g_type, (GBoxedCopyFunc) g_dup_func, (GDestroyNotify) g_destroy_func);
	self->priv->g_type = g_type;
	self->priv->g_dup_func = g_dup_func;
	self->priv->g_destroy_func = g_destroy_func;
	_tmp0_ = _g_object_ref0 (set);
	_g_object_unref0 (self->set);
	self->set = _tmp0_;
	_tmp1_ = _gee_tree_set_range_ref0 (range);
	_gee_tree_set_range_unref0 (self->range);
	self->range = _tmp1_;
	return self;
}

static GeeTreeSetSubSet*
gee_tree_set_sub_set_new_from_range (GType g_type,
                                     GBoxedCopyFunc g_dup_func,
                                     GDestroyNotify g_destroy_func,
                                     GeeTreeSet* set,
                                     GeeTreeSetRange* range)
{
	return gee_tree_set_sub_set_construct_from_range (GEE_TREE_SET_TYPE_SUB_SET, g_type, g_dup_func, g_destroy_func, set, range);
}

static gboolean
gee_tree_set_sub_set_real_contains (GeeAbstractCollection* base,
                                    gconstpointer item)
{
	GeeTreeSetSubSet * self;
	gboolean _tmp0_ = FALSE;
	GeeTreeSetRange* _tmp1_;
	gboolean result;
	self = (GeeTreeSetSubSet*) base;
	_tmp1_ = self->range;
	if (gee_tree_set_range_in_range (_tmp1_, item)) {
		GeeTreeSet* _tmp2_;
		_tmp2_ = self->set;
		_tmp0_ = gee_abstract_collection_contains ((GeeAbstractCollection*) _tmp2_, item);
	} else {
		_tmp0_ = FALSE;
	}
	result = _tmp0_;
	return result;
}

static gboolean
gee_tree_set_sub_set_real_add (GeeAbstractCollection* base,
                               gconstpointer item)
{
	GeeTreeSetSubSet * self;
	gboolean _tmp0_ = FALSE;
	GeeTreeSetRange* _tmp1_;
	gboolean result;
	self = (GeeTreeSetSubSet*) base;
	_tmp1_ = self->range;
	if (gee_tree_set_range_in_range (_tmp1_, item)) {
		GeeTreeSet* _tmp2_;
		_tmp2_ = self->set;
		_tmp0_ = gee_abstract_collection_add ((GeeAbstractCollection*) _tmp2_, item);
	} else {
		_tmp0_ = FALSE;
	}
	result = _tmp0_;
	return result;
}

static gboolean
gee_tree_set_sub_set_real_remove (GeeAbstractCollection* base,
                                  gconstpointer item)
{
	GeeTreeSetSubSet * self;
	gboolean _tmp0_ = FALSE;
	GeeTreeSetRange* _tmp1_;
	gboolean result;
	self = (GeeTreeSetSubSet*) base;
	_tmp1_ = self->range;
	if (gee_tree_set_range_in_range (_tmp1_, item)) {
		GeeTreeSet* _tmp2_;
		_tmp2_ = self->set;
		_tmp0_ = gee_abstract_collection_remove ((GeeAbstractCollection*) _tmp2_, item);
	} else {
		_tmp0_ = FALSE;
	}
	result = _tmp0_;
	return result;
}

static void
gee_tree_set_sub_set_real_clear (GeeAbstractCollection* base)
{
	GeeTreeSetSubSet * self;
	GeeIterator* iter = NULL;
	GeeIterator* _tmp0_;
	self = (GeeTreeSetSubSet*) base;
	_tmp0_ = gee_abstract_collection_iterator ((GeeAbstractCollection*) self);
	iter = _tmp0_;
	while (TRUE) {
		GeeIterator* _tmp1_;
		GeeIterator* _tmp2_;
		_tmp1_ = iter;
		if (!gee_iterator_next (_tmp1_)) {
			break;
		}
		_tmp2_ = iter;
		gee_iterator_remove (_tmp2_);
	}
	_g_object_unref0 (iter);
}

static GeeIterator*
gee_tree_set_sub_set_real_iterator (GeeAbstractCollection* base)
{
	GeeTreeSetSubSet * self;
	GeeTreeSet* _tmp0_;
	GeeTreeSetRange* _tmp1_;
	GeeTreeSetSubIterator* _tmp2_;
	GeeIterator* result;
	self = (GeeTreeSetSubSet*) base;
	_tmp0_ = self->set;
	_tmp1_ = self->range;
	_tmp2_ = gee_tree_set_sub_iterator_new (self->priv->g_type, (GBoxedCopyFunc) self->priv->g_dup_func, (GDestroyNotify) self->priv->g_destroy_func, _tmp0_, _tmp1_);
	result = (GeeIterator*) _tmp2_;
	return result;
}

static GeeBidirIterator*
gee_tree_set_sub_set_real_bidir_iterator (GeeAbstractBidirSortedSet* base)
{
	GeeTreeSetSubSet * self;
	GeeTreeSet* _tmp0_;
	GeeTreeSetRange* _tmp1_;
	GeeTreeSetSubIterator* _tmp2_;
	GeeBidirIterator* result;
	self = (GeeTreeSetSubSet*) base;
	_tmp0_ = self->set;
	_tmp1_ = self->range;
	_tmp2_ = gee_tree_set_sub_iterator_new (self->priv->g_type, (GBoxedCopyFunc) self->priv->g_dup_func, (GDestroyNotify) self->priv->g_destroy_func, _tmp0_, _tmp1_);
	result = (GeeBidirIterator*) _tmp2_;
	return result;
}

static gpointer
gee_tree_set_sub_set_real_first (GeeAbstractSortedSet* base)
{
	GeeTreeSetSubSet * self;
	GeeTreeSetNode* _first = NULL;
	GeeTreeSetRange* _tmp0_;
	GeeTreeSetNode* _tmp1_;
	gconstpointer _tmp2_;
	gpointer _tmp3_;
	gpointer result;
	self = (GeeTreeSetSubSet*) base;
	_tmp0_ = self->range;
	_tmp1_ = gee_tree_set_range_first (_tmp0_);
	_first = _tmp1_;
	_vala_assert (_first != NULL, "_first != null");
	_tmp2_ = _first->key;
	_tmp3_ = ((_tmp2_ != NULL) && (self->priv->g_dup_func != NULL)) ? self->priv->g_dup_func ((gpointer) _tmp2_) : ((gpointer) _tmp2_);
	result = _tmp3_;
	return result;
}

static gpointer
gee_tree_set_sub_set_real_last (GeeAbstractSortedSet* base)
{
	GeeTreeSetSubSet * self;
	GeeTreeSetNode* _last = NULL;
	GeeTreeSetRange* _tmp0_;
	GeeTreeSetNode* _tmp1_;
	gconstpointer _tmp2_;
	gpointer _tmp3_;
	gpointer result;
	self = (GeeTreeSetSubSet*) base;
	_tmp0_ = self->range;
	_tmp1_ = gee_tree_set_range_last (_tmp0_);
	_last = _tmp1_;
	_vala_assert (_last != NULL, "_last != null");
	_tmp2_ = _last->key;
	_tmp3_ = ((_tmp2_ != NULL) && (self->priv->g_dup_func != NULL)) ? self->priv->g_dup_func ((gpointer) _tmp2_) : ((gpointer) _tmp2_);
	result = _tmp3_;
	return result;
}

static GeeSortedSet*
gee_tree_set_sub_set_real_head_set (GeeAbstractSortedSet* base,
                                    gconstpointer before)
{
	GeeTreeSetSubSet * self;
	GeeTreeSet* _tmp0_;
	GeeTreeSetRange* _tmp1_;
	GeeTreeSetRange* _tmp2_;
	GeeTreeSetRange* _tmp3_;
	GeeTreeSetSubSet* _tmp4_;
	GeeSortedSet* _tmp5_;
	GeeSortedSet* result;
	self = (GeeTreeSetSubSet*) base;
	_tmp0_ = self->set;
	_tmp1_ = self->range;
	_tmp2_ = gee_tree_set_range_cut_tail (_tmp1_, before);
	_tmp3_ = _tmp2_;
	_tmp4_ = gee_tree_set_sub_set_new_from_range (self->priv->g_type, (GBoxedCopyFunc) self->priv->g_dup_func, (GDestroyNotify) self->priv->g_destroy_func, _tmp0_, _tmp3_);
	_tmp5_ = (GeeSortedSet*) _tmp4_;
	_gee_tree_set_range_unref0 (_tmp3_);
	result = _tmp5_;
	return result;
}

static GeeSortedSet*
gee_tree_set_sub_set_real_tail_set (GeeAbstractSortedSet* base,
                                    gconstpointer after)
{
	GeeTreeSetSubSet * self;
	GeeTreeSet* _tmp0_;
	GeeTreeSetRange* _tmp1_;
	GeeTreeSetRange* _tmp2_;
	GeeTreeSetRange* _tmp3_;
	GeeTreeSetSubSet* _tmp4_;
	GeeSortedSet* _tmp5_;
	GeeSortedSet* result;
	self = (GeeTreeSetSubSet*) base;
	_tmp0_ = self->set;
	_tmp1_ = self->range;
	_tmp2_ = gee_tree_set_range_cut_head (_tmp1_, after);
	_tmp3_ = _tmp2_;
	_tmp4_ = gee_tree_set_sub_set_new_from_range (self->priv->g_type, (GBoxedCopyFunc) self->priv->g_dup_func, (GDestroyNotify) self->priv->g_destroy_func, _tmp0_, _tmp3_);
	_tmp5_ = (GeeSortedSet*) _tmp4_;
	_gee_tree_set_range_unref0 (_tmp3_);
	result = _tmp5_;
	return result;
}

static GeeSortedSet*
gee_tree_set_sub_set_real_sub_set (GeeAbstractSortedSet* base,
                                   gconstpointer after,
                                   gconstpointer before)
{
	GeeTreeSetSubSet * self;
	GeeTreeSet* _tmp0_;
	GeeTreeSetRange* _tmp1_;
	GeeTreeSetRange* _tmp2_;
	GeeTreeSetRange* _tmp3_;
	GeeTreeSetSubSet* _tmp4_;
	GeeSortedSet* _tmp5_;
	GeeSortedSet* result;
	self = (GeeTreeSetSubSet*) base;
	_tmp0_ = self->set;
	_tmp1_ = self->range;
	_tmp2_ = gee_tree_set_range_cut (_tmp1_, after, before);
	_tmp3_ = _tmp2_;
	_tmp4_ = gee_tree_set_sub_set_new_from_range (self->priv->g_type, (GBoxedCopyFunc) self->priv->g_dup_func, (GDestroyNotify) self->priv->g_destroy_func, _tmp0_, _tmp3_);
	_tmp5_ = (GeeSortedSet*) _tmp4_;
	_gee_tree_set_range_unref0 (_tmp3_);
	result = _tmp5_;
	return result;
}

static GeeIterator*
gee_tree_set_sub_set_real_iterator_at (GeeAbstractSortedSet* base,
                                       gconstpointer item)
{
	GeeTreeSetSubSet * self;
	GeeTreeSetRange* _tmp0_;
	GeeTreeSetNode* n = NULL;
	GeeTreeSet* _tmp1_;
	GeeTreeSetNode* _tmp2_;
	GeeTreeSetNode* _tmp3_;
	GeeTreeSet* _tmp4_;
	GeeTreeSetRange* _tmp5_;
	GeeTreeSetNode* _tmp6_;
	GeeTreeSetSubIterator* _tmp7_;
	GeeIterator* result;
	self = (GeeTreeSetSubSet*) base;
	_tmp0_ = self->range;
	if (!gee_tree_set_range_in_range (_tmp0_, item)) {
		result = NULL;
		return result;
	}
	_tmp1_ = self->set;
	_tmp2_ = gee_tree_set_find_node (_tmp1_, item);
	n = _tmp2_;
	_tmp3_ = n;
	if (_tmp3_ == NULL) {
		result = NULL;
		return result;
	}
	_tmp4_ = self->set;
	_tmp5_ = self->range;
	_tmp6_ = n;
	_tmp7_ = gee_tree_set_sub_iterator_new_pointing (self->priv->g_type, (GBoxedCopyFunc) self->priv->g_dup_func, (GDestroyNotify) self->priv->g_destroy_func, _tmp4_, _tmp5_, _tmp6_);
	result = (GeeIterator*) _tmp7_;
	return result;
}

static gpointer
gee_tree_set_sub_set_real_lower (GeeAbstractSortedSet* base,
                                 gconstpointer item)
{
	GeeTreeSetSubSet * self;
	gint res = 0;
	GeeTreeSetRange* _tmp0_;
	gpointer l = NULL;
	GeeTreeSet* _tmp2_;
	gpointer _tmp3_;
	gconstpointer _tmp4_ = NULL;
	gboolean _tmp5_ = FALSE;
	gconstpointer _tmp6_;
	gpointer _tmp10_;
	gpointer result;
	self = (GeeTreeSetSubSet*) base;
	_tmp0_ = self->range;
	res = gee_tree_set_range_compare_range (_tmp0_, item);
	if (res > 0) {
		gpointer _tmp1_;
		_tmp1_ = gee_abstract_sorted_set_last ((GeeAbstractSortedSet*) self);
		result = _tmp1_;
		return result;
	}
	_tmp2_ = self->set;
	_tmp3_ = gee_abstract_sorted_set_lower ((GeeAbstractSortedSet*) _tmp2_, item);
	l = _tmp3_;
	_tmp6_ = l;
	if (_tmp6_ != NULL) {
		GeeTreeSetRange* _tmp7_;
		gconstpointer _tmp8_;
		_tmp7_ = self->range;
		_tmp8_ = l;
		_tmp5_ = gee_tree_set_range_in_range (_tmp7_, _tmp8_);
	} else {
		_tmp5_ = FALSE;
	}
	if (_tmp5_) {
		gconstpointer _tmp9_;
		_tmp9_ = l;
		_tmp4_ = _tmp9_;
	} else {
		_tmp4_ = NULL;
	}
	_tmp10_ = ((_tmp4_ != NULL) && (self->priv->g_dup_func != NULL)) ? self->priv->g_dup_func ((gpointer) _tmp4_) : ((gpointer) _tmp4_);
	result = _tmp10_;
	((l == NULL) || (self->priv->g_destroy_func == NULL)) ? NULL : (l = (self->priv->g_destroy_func (l), NULL));
	return result;
}

static gpointer
gee_tree_set_sub_set_real_higher (GeeAbstractSortedSet* base,
                                  gconstpointer item)
{
	GeeTreeSetSubSet * self;
	gint res = 0;
	GeeTreeSetRange* _tmp0_;
	gpointer h = NULL;
	GeeTreeSet* _tmp2_;
	gpointer _tmp3_;
	gconstpointer _tmp4_ = NULL;
	gboolean _tmp5_ = FALSE;
	gconstpointer _tmp6_;
	gpointer _tmp10_;
	gpointer result;
	self = (GeeTreeSetSubSet*) base;
	_tmp0_ = self->range;
	res = gee_tree_set_range_compare_range (_tmp0_, item);
	if (res < 0) {
		gpointer _tmp1_;
		_tmp1_ = gee_abstract_sorted_set_first ((GeeAbstractSortedSet*) self);
		result = _tmp1_;
		return result;
	}
	_tmp2_ = self->set;
	_tmp3_ = gee_abstract_sorted_set_higher ((GeeAbstractSortedSet*) _tmp2_, item);
	h = _tmp3_;
	_tmp6_ = h;
	if (_tmp6_ != NULL) {
		GeeTreeSetRange* _tmp7_;
		gconstpointer _tmp8_;
		_tmp7_ = self->range;
		_tmp8_ = h;
		_tmp5_ = gee_tree_set_range_in_range (_tmp7_, _tmp8_);
	} else {
		_tmp5_ = FALSE;
	}
	if (_tmp5_) {
		gconstpointer _tmp9_;
		_tmp9_ = h;
		_tmp4_ = _tmp9_;
	} else {
		_tmp4_ = NULL;
	}
	_tmp10_ = ((_tmp4_ != NULL) && (self->priv->g_dup_func != NULL)) ? self->priv->g_dup_func ((gpointer) _tmp4_) : ((gpointer) _tmp4_);
	result = _tmp10_;
	((h == NULL) || (self->priv->g_destroy_func == NULL)) ? NULL : (h = (self->priv->g_destroy_func (h), NULL));
	return result;
}

static gpointer
gee_tree_set_sub_set_real_floor (GeeAbstractSortedSet* base,
                                 gconstpointer item)
{
	GeeTreeSetSubSet * self;
	gint res = 0;
	GeeTreeSetRange* _tmp0_;
	gpointer l = NULL;
	GeeTreeSet* _tmp2_;
	gpointer _tmp3_;
	gconstpointer _tmp4_ = NULL;
	gboolean _tmp5_ = FALSE;
	gconstpointer _tmp6_;
	gpointer _tmp10_;
	gpointer result;
	self = (GeeTreeSetSubSet*) base;
	_tmp0_ = self->range;
	res = gee_tree_set_range_compare_range (_tmp0_, item);
	if (res > 0) {
		gpointer _tmp1_;
		_tmp1_ = gee_abstract_sorted_set_last ((GeeAbstractSortedSet*) self);
		result = _tmp1_;
		return result;
	}
	_tmp2_ = self->set;
	_tmp3_ = gee_abstract_sorted_set_floor ((GeeAbstractSortedSet*) _tmp2_, item);
	l = _tmp3_;
	_tmp6_ = l;
	if (_tmp6_ != NULL) {
		GeeTreeSetRange* _tmp7_;
		gconstpointer _tmp8_;
		_tmp7_ = self->range;
		_tmp8_ = l;
		_tmp5_ = gee_tree_set_range_in_range (_tmp7_, _tmp8_);
	} else {
		_tmp5_ = FALSE;
	}
	if (_tmp5_) {
		gconstpointer _tmp9_;
		_tmp9_ = l;
		_tmp4_ = _tmp9_;
	} else {
		_tmp4_ = NULL;
	}
	_tmp10_ = ((_tmp4_ != NULL) && (self->priv->g_dup_func != NULL)) ? self->priv->g_dup_func ((gpointer) _tmp4_) : ((gpointer) _tmp4_);
	result = _tmp10_;
	((l == NULL) || (self->priv->g_destroy_func == NULL)) ? NULL : (l = (self->priv->g_destroy_func (l), NULL));
	return result;
}

static gpointer
gee_tree_set_sub_set_real_ceil (GeeAbstractSortedSet* base,
                                gconstpointer item)
{
	GeeTreeSetSubSet * self;
	gint res = 0;
	GeeTreeSetRange* _tmp0_;
	gpointer h = NULL;
	GeeTreeSet* _tmp2_;
	gpointer _tmp3_;
	gconstpointer _tmp4_ = NULL;
	gboolean _tmp5_ = FALSE;
	gconstpointer _tmp6_;
	gpointer _tmp10_;
	gpointer result;
	self = (GeeTreeSetSubSet*) base;
	_tmp0_ = self->range;
	res = gee_tree_set_range_compare_range (_tmp0_, item);
	if (res < 0) {
		gpointer _tmp1_;
		_tmp1_ = gee_abstract_sorted_set_first ((GeeAbstractSortedSet*) self);
		result = _tmp1_;
		return result;
	}
	_tmp2_ = self->set;
	_tmp3_ = gee_abstract_sorted_set_ceil ((GeeAbstractSortedSet*) _tmp2_, item);
	h = _tmp3_;
	_tmp6_ = h;
	if (_tmp6_ != NULL) {
		GeeTreeSetRange* _tmp7_;
		gconstpointer _tmp8_;
		_tmp7_ = self->range;
		_tmp8_ = h;
		_tmp5_ = gee_tree_set_range_in_range (_tmp7_, _tmp8_);
	} else {
		_tmp5_ = FALSE;
	}
	if (_tmp5_) {
		gconstpointer _tmp9_;
		_tmp9_ = h;
		_tmp4_ = _tmp9_;
	} else {
		_tmp4_ = NULL;
	}
	_tmp10_ = ((_tmp4_ != NULL) && (self->priv->g_dup_func != NULL)) ? self->priv->g_dup_func ((gpointer) _tmp4_) : ((gpointer) _tmp4_);
	result = _tmp10_;
	((h == NULL) || (self->priv->g_destroy_func == NULL)) ? NULL : (h = (self->priv->g_destroy_func (h), NULL));
	return result;
}

static gint
gee_tree_set_sub_set_real_get_size (GeeAbstractCollection* base)
{
	gint result;
	GeeTreeSetSubSet* self;
	gint i = 0;
	GeeIterator* iterator = NULL;
	GeeIterator* _tmp0_;
	self = (GeeTreeSetSubSet*) base;
	i = 0;
	_tmp0_ = gee_abstract_collection_iterator ((GeeAbstractCollection*) self);
	iterator = _tmp0_;
	while (TRUE) {
		GeeIterator* _tmp1_;
		gint _tmp2_;
		_tmp1_ = iterator;
		if (!gee_iterator_next (_tmp1_)) {
			break;
		}
		_tmp2_ = i;
		i = _tmp2_ + 1;
	}
	result = i;
	_g_object_unref0 (iterator);
	return result;
}

static gboolean
gee_tree_set_sub_set_real_get_read_only (GeeAbstractCollection* base)
{
	gboolean result;
	GeeTreeSetSubSet* self;
	self = (GeeTreeSetSubSet*) base;
	result = TRUE;
	return result;
}

static gboolean
gee_tree_set_sub_set_get_is_empty (GeeTreeSetSubSet* self)
{
	gboolean result;
	GeeTreeSetRange* _tmp0_;
	g_return_val_if_fail (self != NULL, FALSE);
	_tmp0_ = self->range;
	result = gee_tree_set_range_empty_subset (_tmp0_);
	return result;
}

static void
gee_tree_set_sub_set_class_init (GeeTreeSetSubSetClass * klass,
                                 gpointer klass_data)
{
	gee_tree_set_sub_set_parent_class = g_type_class_peek_parent (klass);
	g_type_class_adjust_private_offset (klass, &GeeTreeSetSubSet_private_offset);
	((GeeAbstractCollectionClass *) klass)->contains = (gboolean (*) (GeeAbstractCollection*, gconstpointer)) gee_tree_set_sub_set_real_contains;
	((GeeAbstractCollectionClass *) klass)->add = (gboolean (*) (GeeAbstractCollection*, gconstpointer)) gee_tree_set_sub_set_real_add;
	((GeeAbstractCollectionClass *) klass)->remove = (gboolean (*) (GeeAbstractCollection*, gconstpointer)) gee_tree_set_sub_set_real_remove;
	((GeeAbstractCollectionClass *) klass)->clear = (void (*) (GeeAbstractCollection*)) gee_tree_set_sub_set_real_clear;
	((GeeAbstractCollectionClass *) klass)->iterator = (GeeIterator* (*) (GeeAbstractCollection*)) gee_tree_set_sub_set_real_iterator;
	((GeeAbstractBidirSortedSetClass *) klass)->bidir_iterator = (GeeBidirIterator* (*) (GeeAbstractBidirSortedSet*)) gee_tree_set_sub_set_real_bidir_iterator;
	((GeeAbstractSortedSetClass *) klass)->first = (gpointer (*) (GeeAbstractSortedSet*)) gee_tree_set_sub_set_real_first;
	((GeeAbstractSortedSetClass *) klass)->last = (gpointer (*) (GeeAbstractSortedSet*)) gee_tree_set_sub_set_real_last;
	((GeeAbstractSortedSetClass *) klass)->head_set = (GeeSortedSet* (*) (GeeAbstractSortedSet*, gconstpointer)) gee_tree_set_sub_set_real_head_set;
	((GeeAbstractSortedSetClass *) klass)->tail_set = (GeeSortedSet* (*) (GeeAbstractSortedSet*, gconstpointer)) gee_tree_set_sub_set_real_tail_set;
	((GeeAbstractSortedSetClass *) klass)->sub_set = (GeeSortedSet* (*) (GeeAbstractSortedSet*, gconstpointer, gconstpointer)) gee_tree_set_sub_set_real_sub_set;
	((GeeAbstractSortedSetClass *) klass)->iterator_at = (GeeIterator* (*) (GeeAbstractSortedSet*, gconstpointer)) gee_tree_set_sub_set_real_iterator_at;
	((GeeAbstractSortedSetClass *) klass)->lower = (gpointer (*) (GeeAbstractSortedSet*, gconstpointer)) gee_tree_set_sub_set_real_lower;
	((GeeAbstractSortedSetClass *) klass)->higher = (gpointer (*) (GeeAbstractSortedSet*, gconstpointer)) gee_tree_set_sub_set_real_higher;
	((GeeAbstractSortedSetClass *) klass)->floor = (gpointer (*) (GeeAbstractSortedSet*, gconstpointer)) gee_tree_set_sub_set_real_floor;
	((GeeAbstractSortedSetClass *) klass)->ceil = (gpointer (*) (GeeAbstractSortedSet*, gconstpointer)) gee_tree_set_sub_set_real_ceil;
	GEE_ABSTRACT_COLLECTION_CLASS (klass)->get_size = gee_tree_set_sub_set_real_get_size;
	GEE_ABSTRACT_COLLECTION_CLASS (klass)->get_read_only = gee_tree_set_sub_set_real_get_read_only;
	G_OBJECT_CLASS (klass)->get_property = _vala_gee_tree_set_sub_set_get_property;
	G_OBJECT_CLASS (klass)->set_property = _vala_gee_tree_set_sub_set_set_property;
	G_OBJECT_CLASS (klass)->finalize = gee_tree_set_sub_set_finalize;
	g_object_class_install_property (G_OBJECT_CLASS (klass), GEE_TREE_SET_SUB_SET_G_TYPE, g_param_spec_gtype ("g-type", "type", "type", G_TYPE_NONE, G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
	g_object_class_install_property (G_OBJECT_CLASS (klass), GEE_TREE_SET_SUB_SET_G_DUP_FUNC, g_param_spec_pointer ("g-dup-func", "dup func", "dup func", G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
	g_object_class_install_property (G_OBJECT_CLASS (klass), GEE_TREE_SET_SUB_SET_G_DESTROY_FUNC, g_param_spec_pointer ("g-destroy-func", "destroy func", "destroy func", G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
	g_object_class_install_property (G_OBJECT_CLASS (klass), GEE_TREE_SET_SUB_SET_SIZE_PROPERTY, gee_tree_set_sub_set_properties[GEE_TREE_SET_SUB_SET_SIZE_PROPERTY] = g_param_spec_int ("size", "size", "size", G_MININT, G_MAXINT, 0, G_PARAM_STATIC_STRINGS | G_PARAM_READABLE));
	g_object_class_install_property (G_OBJECT_CLASS (klass), GEE_TREE_SET_SUB_SET_READ_ONLY_PROPERTY, gee_tree_set_sub_set_properties[GEE_TREE_SET_SUB_SET_READ_ONLY_PROPERTY] = g_param_spec_boolean ("read-only", "read-only", "read-only", FALSE, G_PARAM_STATIC_STRINGS | G_PARAM_READABLE));
	g_object_class_install_property (G_OBJECT_CLASS (klass), GEE_TREE_SET_SUB_SET_IS_EMPTY_PROPERTY, gee_tree_set_sub_set_properties[GEE_TREE_SET_SUB_SET_IS_EMPTY_PROPERTY] = g_param_spec_boolean ("is-empty", "is-empty", "is-empty", FALSE, G_PARAM_STATIC_STRINGS | G_PARAM_READABLE));
}

static void
gee_tree_set_sub_set_instance_init (GeeTreeSetSubSet * self,
                                    gpointer klass)
{
	self->priv = gee_tree_set_sub_set_get_instance_private (self);
}

static void
gee_tree_set_sub_set_finalize (GObject * obj)
{
	GeeTreeSetSubSet * self;
	self = G_TYPE_CHECK_INSTANCE_CAST (obj, GEE_TREE_SET_TYPE_SUB_SET, GeeTreeSetSubSet);
	_g_object_unref0 (self->set);
	_gee_tree_set_range_unref0 (self->range);
	G_OBJECT_CLASS (gee_tree_set_sub_set_parent_class)->finalize (obj);
}

static GType
gee_tree_set_sub_set_get_type_once (void)
{
	static const GTypeInfo g_define_type_info = { sizeof (GeeTreeSetSubSetClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) gee_tree_set_sub_set_class_init, (GClassFinalizeFunc) NULL, NULL, sizeof (GeeTreeSetSubSet), 0, (GInstanceInitFunc) gee_tree_set_sub_set_instance_init, NULL };
	GType gee_tree_set_sub_set_type_id;
	gee_tree_set_sub_set_type_id = g_type_register_static (GEE_TYPE_ABSTRACT_BIDIR_SORTED_SET, "GeeTreeSetSubSet", &g_define_type_info, 0);
	GeeTreeSetSubSet_private_offset = g_type_add_instance_private (gee_tree_set_sub_set_type_id, sizeof (GeeTreeSetSubSetPrivate));
	return gee_tree_set_sub_set_type_id;
}

static GType
gee_tree_set_sub_set_get_type (void)
{
	static volatile gsize gee_tree_set_sub_set_type_id__once = 0;
	if (g_once_init_enter (&gee_tree_set_sub_set_type_id__once)) {
		GType gee_tree_set_sub_set_type_id;
		gee_tree_set_sub_set_type_id = gee_tree_set_sub_set_get_type_once ();
		g_once_init_leave (&gee_tree_set_sub_set_type_id__once, gee_tree_set_sub_set_type_id);
	}
	return gee_tree_set_sub_set_type_id__once;
}

static void
_vala_gee_tree_set_sub_set_get_property (GObject * object,
                                         guint property_id,
                                         GValue * value,
                                         GParamSpec * pspec)
{
	GeeTreeSetSubSet * self;
	self = G_TYPE_CHECK_INSTANCE_CAST (object, GEE_TREE_SET_TYPE_SUB_SET, GeeTreeSetSubSet);
	switch (property_id) {
		case GEE_TREE_SET_SUB_SET_SIZE_PROPERTY:
		g_value_set_int (value, gee_abstract_collection_get_size ((GeeAbstractCollection*) self));
		break;
		case GEE_TREE_SET_SUB_SET_READ_ONLY_PROPERTY:
		g_value_set_boolean (value, gee_abstract_collection_get_read_only ((GeeAbstractCollection*) self));
		break;
		case GEE_TREE_SET_SUB_SET_IS_EMPTY_PROPERTY:
		g_value_set_boolean (value, gee_tree_set_sub_set_get_is_empty (self));
		break;
		case GEE_TREE_SET_SUB_SET_G_TYPE:
		g_value_set_gtype (value, self->priv->g_type);
		break;
		case GEE_TREE_SET_SUB_SET_G_DUP_FUNC:
		g_value_set_pointer (value, self->priv->g_dup_func);
		break;
		case GEE_TREE_SET_SUB_SET_G_DESTROY_FUNC:
		g_value_set_pointer (value, self->priv->g_destroy_func);
		break;
		default:
		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
		break;
	}
}

static void
_vala_gee_tree_set_sub_set_set_property (GObject * object,
                                         guint property_id,
                                         const GValue * value,
                                         GParamSpec * pspec)
{
	GeeTreeSetSubSet * self;
	self = G_TYPE_CHECK_INSTANCE_CAST (object, GEE_TREE_SET_TYPE_SUB_SET, GeeTreeSetSubSet);
	switch (property_id) {
		case GEE_TREE_SET_SUB_SET_G_TYPE:
		self->priv->g_type = g_value_get_gtype (value);
		break;
		case GEE_TREE_SET_SUB_SET_G_DUP_FUNC:
		self->priv->g_dup_func = g_value_get_pointer (value);
		break;
		case GEE_TREE_SET_SUB_SET_G_DESTROY_FUNC:
		self->priv->g_destroy_func = g_value_get_pointer (value);
		break;
		default:
		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
		break;
	}
}

static inline gpointer
gee_tree_set_sub_iterator_get_instance_private (GeeTreeSetSubIterator* self)
{
	return G_STRUCT_MEMBER_P (self, GeeTreeSetSubIterator_private_offset);
}

static GeeTreeSetSubIterator*
gee_tree_set_sub_iterator_construct (GType object_type,
                                     GType g_type,
                                     GBoxedCopyFunc g_dup_func,
                                     GDestroyNotify g_destroy_func,
                                     GeeTreeSet* set,
                                     GeeTreeSetRange* range)
{
	GeeTreeSetSubIterator * self = NULL;
	GeeTreeSet* _tmp0_;
	GeeTreeSetRange* _tmp1_;
	g_return_val_if_fail (set != NULL, NULL);
	g_return_val_if_fail (range != NULL, NULL);
	self = (GeeTreeSetSubIterator*) g_object_new (object_type, "g-type", g_type, "g-dup-func", g_dup_func, "g-destroy-func", g_destroy_func, NULL);
	self->priv->g_type = g_type;
	self->priv->g_dup_func = g_dup_func;
	self->priv->g_destroy_func = g_destroy_func;
	_tmp0_ = _g_object_ref0 (set);
	_g_object_unref0 (self->set);
	self->set = _tmp0_;
	_tmp1_ = _gee_tree_set_range_ref0 (range);
	_gee_tree_set_range_unref0 (self->range);
	self->range = _tmp1_;
	return self;
}

static GeeTreeSetSubIterator*
gee_tree_set_sub_iterator_new (GType g_type,
                               GBoxedCopyFunc g_dup_func,
                               GDestroyNotify g_destroy_func,
                               GeeTreeSet* set,
                               GeeTreeSetRange* range)
{
	return gee_tree_set_sub_iterator_construct (GEE_TREE_SET_TYPE_SUB_ITERATOR, g_type, g_dup_func, g_destroy_func, set, range);
}

static GeeTreeSetSubIterator*
gee_tree_set_sub_iterator_construct_pointing (GType object_type,
                                              GType g_type,
                                              GBoxedCopyFunc g_dup_func,
                                              GDestroyNotify g_destroy_func,
                                              GeeTreeSet* set,
                                              GeeTreeSetRange* range,
                                              GeeTreeSetNode* node)
{
	GeeTreeSetSubIterator * self = NULL;
	GeeTreeSet* _tmp0_;
	GeeTreeSetRange* _tmp1_;
	GeeTreeSetIterator* _tmp2_;
	g_return_val_if_fail (set != NULL, NULL);
	g_return_val_if_fail (range != NULL, NULL);
	g_return_val_if_fail (node != NULL, NULL);
	self = (GeeTreeSetSubIterator*) g_object_new (object_type, "g-type", g_type, "g-dup-func", g_dup_func, "g-destroy-func", g_destroy_func, NULL);
	self->priv->g_type = g_type;
	self->priv->g_dup_func = g_dup_func;
	self->priv->g_destroy_func = g_destroy_func;
	_tmp0_ = _g_object_ref0 (set);
	_g_object_unref0 (self->set);
	self->set = _tmp0_;
	_tmp1_ = _gee_tree_set_range_ref0 (range);
	_gee_tree_set_range_unref0 (self->range);
	self->range = _tmp1_;
	_tmp2_ = gee_tree_set_iterator_new_pointing (g_type, (GBoxedCopyFunc) g_dup_func, (GDestroyNotify) g_destroy_func, set, node);
	_g_object_unref0 (self->iterator);
	self->iterator = _tmp2_;
	return self;
}

static GeeTreeSetSubIterator*
gee_tree_set_sub_iterator_new_pointing (GType g_type,
                                        GBoxedCopyFunc g_dup_func,
                                        GDestroyNotify g_destroy_func,
                                        GeeTreeSet* set,
                                        GeeTreeSetRange* range,
                                        GeeTreeSetNode* node)
{
	return gee_tree_set_sub_iterator_construct_pointing (GEE_TREE_SET_TYPE_SUB_ITERATOR, g_type, g_dup_func, g_destroy_func, set, range, node);
}

static GeeTreeSetSubIterator*
gee_tree_set_sub_iterator_construct_from_iterator (GType object_type,
                                                   GType g_type,
                                                   GBoxedCopyFunc g_dup_func,
                                                   GDestroyNotify g_destroy_func,
                                                   GeeTreeSetSubIterator* iter)
{
	GeeTreeSetSubIterator * self = NULL;
	GeeTreeSet* _tmp0_;
	GeeTreeSet* _tmp1_;
	GeeTreeSetRange* _tmp2_;
	GeeTreeSetRange* _tmp3_;
	GeeTreeSetIterator* _tmp4_;
	GeeTreeSetIterator* _tmp5_;
	g_return_val_if_fail (iter != NULL, NULL);
	self = (GeeTreeSetSubIterator*) g_object_new (object_type, "g-type", g_type, "g-dup-func", g_dup_func, "g-destroy-func", g_destroy_func, NULL);
	self->priv->g_type = g_type;
	self->priv->g_dup_func = g_dup_func;
	self->priv->g_destroy_func = g_destroy_func;
	_tmp0_ = iter->set;
	_tmp1_ = _g_object_ref0 (_tmp0_);
	_g_object_unref0 (self->set);
	self->set = _tmp1_;
	_tmp2_ = iter->range;
	_tmp3_ = _gee_tree_set_range_ref0 (_tmp2_);
	_gee_tree_set_range_unref0 (self->range);
	self->range = _tmp3_;
	_tmp4_ = iter->iterator;
	_tmp5_ = gee_tree_set_iterator_new_from_iterator (g_type, (GBoxedCopyFunc) g_dup_func, (GDestroyNotify) g_destroy_func, _tmp4_);
	_g_object_unref0 (self->iterator);
	self->iterator = _tmp5_;
	return self;
}

static GeeTreeSetSubIterator*
gee_tree_set_sub_iterator_new_from_iterator (GType g_type,
                                             GBoxedCopyFunc g_dup_func,
                                             GDestroyNotify g_destroy_func,
                                             GeeTreeSetSubIterator* iter)
{
	return gee_tree_set_sub_iterator_construct_from_iterator (GEE_TREE_SET_TYPE_SUB_ITERATOR, g_type, g_dup_func, g_destroy_func, iter);
}

static gboolean
gee_tree_set_sub_iterator_real_next (GeeIterator* base)
{
	GeeTreeSetSubIterator * self;
	GeeTreeSetIterator* _tmp0_;
	gboolean result;
	self = (GeeTreeSetSubIterator*) base;
	_tmp0_ = self->iterator;
	if (_tmp0_ != NULL) {
		gpointer next = NULL;
		gboolean _tmp1_ = FALSE;
		GeeTreeSetIterator* _tmp2_;
		gpointer _tmp3_ = NULL;
		gboolean _tmp4_;
		_tmp2_ = self->iterator;
		_tmp4_ = gee_tree_set_iterator_safe_next_get (_tmp2_, &_tmp3_);
		((next == NULL) || (self->priv->g_destroy_func == NULL)) ? NULL : (next = (self->priv->g_destroy_func (next), NULL));
		next = _tmp3_;
		if (_tmp4_) {
			GeeTreeSetRange* _tmp5_;
			gconstpointer _tmp6_;
			_tmp5_ = self->range;
			_tmp6_ = next;
			_tmp1_ = gee_tree_set_range_in_range (_tmp5_, _tmp6_);
		} else {
			_tmp1_ = FALSE;
		}
		if (_tmp1_) {
			GeeTreeSetIterator* _tmp7_;
			_tmp7_ = self->iterator;
			_vala_assert (gee_iterator_next ((GeeIterator*) _tmp7_), "iterator.next ()");
			result = TRUE;
			((next == NULL) || (self->priv->g_destroy_func == NULL)) ? NULL : (next = (self->priv->g_destroy_func (next), NULL));
			return result;
		} else {
			result = FALSE;
			((next == NULL) || (self->priv->g_destroy_func == NULL)) ? NULL : (next = (self->priv->g_destroy_func (next), NULL));
			return result;
		}
		((next == NULL) || (self->priv->g_destroy_func == NULL)) ? NULL : (next = (self->priv->g_destroy_func (next), NULL));
	} else {
		result = gee_bidir_iterator_first ((GeeBidirIterator*) self);
		return result;
	}
}

static gboolean
gee_tree_set_sub_iterator_real_has_next (GeeIterator* base)
{
	GeeTreeSetSubIterator * self;
	GeeTreeSetIterator* _tmp0_;
	gboolean result;
	self = (GeeTreeSetSubIterator*) base;
	_tmp0_ = self->iterator;
	if (_tmp0_ != NULL) {
		gpointer next = NULL;
		gboolean _tmp1_ = FALSE;
		GeeTreeSetIterator* _tmp2_;
		gpointer _tmp3_ = NULL;
		gboolean _tmp4_;
		_tmp2_ = self->iterator;
		_tmp4_ = gee_tree_set_iterator_safe_next_get (_tmp2_, &_tmp3_);
		((next == NULL) || (self->priv->g_destroy_func == NULL)) ? NULL : (next = (self->priv->g_destroy_func (next), NULL));
		next = _tmp3_;
		if (_tmp4_) {
			GeeTreeSetRange* _tmp5_;
			gconstpointer _tmp6_;
			_tmp5_ = self->range;
			_tmp6_ = next;
			_tmp1_ = gee_tree_set_range_in_range (_tmp5_, _tmp6_);
		} else {
			_tmp1_ = FALSE;
		}
		result = _tmp1_;
		((next == NULL) || (self->priv->g_destroy_func == NULL)) ? NULL : (next = (self->priv->g_destroy_func (next), NULL));
		return result;
	} else {
		GeeTreeSetRange* _tmp7_;
		GeeTreeSetNode* _tmp8_;
		_tmp7_ = self->range;
		_tmp8_ = gee_tree_set_range_first (_tmp7_);
		result = _tmp8_ != NULL;
		return result;
	}
}

static gboolean
gee_tree_set_sub_iterator_real_first (GeeBidirIterator* base)
{
	GeeTreeSetSubIterator * self;
	GeeTreeSetNode* node = NULL;
	GeeTreeSetRange* _tmp0_;
	GeeTreeSetNode* _tmp1_;
	GeeTreeSetNode* _tmp2_;
	GeeTreeSet* _tmp3_;
	GeeTreeSetNode* _tmp4_;
	GeeTreeSetIterator* _tmp5_;
	gboolean result;
	self = (GeeTreeSetSubIterator*) base;
	_tmp0_ = self->range;
	_tmp1_ = gee_tree_set_range_first (_tmp0_);
	node = _tmp1_;
	_tmp2_ = node;
	if (_tmp2_ == NULL) {
		result = FALSE;
		return result;
	}
	_tmp3_ = self->set;
	_tmp4_ = node;
	_tmp5_ = gee_tree_set_iterator_new_pointing (self->priv->g_type, (GBoxedCopyFunc) self->priv->g_dup_func, (GDestroyNotify) self->priv->g_destroy_func, _tmp3_, _tmp4_);
	_g_object_unref0 (self->iterator);
	self->iterator = _tmp5_;
	result = TRUE;
	return result;
}

static gboolean
gee_tree_set_sub_iterator_real_previous (GeeBidirIterator* base)
{
	GeeTreeSetSubIterator * self;
	GeeTreeSetIterator* _tmp0_;
	gpointer prev = NULL;
	gboolean _tmp1_ = FALSE;
	GeeTreeSetIterator* _tmp2_;
	gpointer _tmp3_ = NULL;
	gboolean _tmp4_;
	gboolean result;
	self = (GeeTreeSetSubIterator*) base;
	_tmp0_ = self->iterator;
	if (_tmp0_ == NULL) {
		result = FALSE;
		return result;
	}
	_tmp2_ = self->iterator;
	_tmp4_ = gee_tree_set_iterator_safe_previous_get (_tmp2_, &_tmp3_);
	((prev == NULL) || (self->priv->g_destroy_func == NULL)) ? NULL : (prev = (self->priv->g_destroy_func (prev), NULL));
	prev = _tmp3_;
	if (_tmp4_) {
		GeeTreeSetRange* _tmp5_;
		gconstpointer _tmp6_;
		_tmp5_ = self->range;
		_tmp6_ = prev;
		_tmp1_ = gee_tree_set_range_in_range (_tmp5_, _tmp6_);
	} else {
		_tmp1_ = FALSE;
	}
	if (_tmp1_) {
		GeeTreeSetIterator* _tmp7_;
		_tmp7_ = self->iterator;
		_vala_assert (gee_bidir_iterator_previous ((GeeBidirIterator*) _tmp7_), "iterator.previous ()");
		result = TRUE;
		((prev == NULL) || (self->priv->g_destroy_func == NULL)) ? NULL : (prev = (self->priv->g_destroy_func (prev), NULL));
		return result;
	} else {
		result = FALSE;
		((prev == NULL) || (self->priv->g_destroy_func == NULL)) ? NULL : (prev = (self->priv->g_destroy_func (prev), NULL));
		return result;
	}
}

static gboolean
gee_tree_set_sub_iterator_real_has_previous (GeeBidirIterator* base)
{
	GeeTreeSetSubIterator * self;
	GeeTreeSetIterator* _tmp0_;
	gpointer prev = NULL;
	gboolean _tmp1_ = FALSE;
	GeeTreeSetIterator* _tmp2_;
	gpointer _tmp3_ = NULL;
	gboolean _tmp4_;
	gboolean result;
	self = (GeeTreeSetSubIterator*) base;
	_tmp0_ = self->iterator;
	if (_tmp0_ == NULL) {
		result = FALSE;
		return result;
	}
	_tmp2_ = self->iterator;
	_tmp4_ = gee_tree_set_iterator_safe_previous_get (_tmp2_, &_tmp3_);
	((prev == NULL) || (self->priv->g_destroy_func == NULL)) ? NULL : (prev = (self->priv->g_destroy_func (prev), NULL));
	prev = _tmp3_;
	if (_tmp4_) {
		GeeTreeSetRange* _tmp5_;
		gconstpointer _tmp6_;
		_tmp5_ = self->range;
		_tmp6_ = prev;
		_tmp1_ = gee_tree_set_range_in_range (_tmp5_, _tmp6_);
	} else {
		_tmp1_ = FALSE;
	}
	result = _tmp1_;
	((prev == NULL) || (self->priv->g_destroy_func == NULL)) ? NULL : (prev = (self->priv->g_destroy_func (prev), NULL));
	return result;
}

static gboolean
gee_tree_set_sub_iterator_real_last (GeeBidirIterator* base)
{
	GeeTreeSetSubIterator * self;
	GeeTreeSetNode* node = NULL;
	GeeTreeSetRange* _tmp0_;
	GeeTreeSetNode* _tmp1_;
	GeeTreeSetNode* _tmp2_;
	GeeTreeSet* _tmp3_;
	GeeTreeSetNode* _tmp4_;
	GeeTreeSetIterator* _tmp5_;
	gboolean result;
	self = (GeeTreeSetSubIterator*) base;
	_tmp0_ = self->range;
	_tmp1_ = gee_tree_set_range_last (_tmp0_);
	node = _tmp1_;
	_tmp2_ = node;
	if (_tmp2_ == NULL) {
		result = FALSE;
		return result;
	}
	_tmp3_ = self->set;
	_tmp4_ = node;
	_tmp5_ = gee_tree_set_iterator_new_pointing (self->priv->g_type, (GBoxedCopyFunc) self->priv->g_dup_func, (GDestroyNotify) self->priv->g_destroy_func, _tmp3_, _tmp4_);
	_g_object_unref0 (self->iterator);
	self->iterator = _tmp5_;
	result = TRUE;
	return result;
}

static gpointer
gee_tree_set_sub_iterator_real_get (GeeIterator* base)
{
	GeeTreeSetSubIterator * self;
	GeeTreeSetIterator* _tmp0_;
	GeeTreeSetIterator* _tmp1_;
	gpointer _tmp2_;
	gpointer result;
	self = (GeeTreeSetSubIterator*) base;
	_tmp0_ = self->iterator;
	_vala_assert (_tmp0_ != NULL, "iterator != null");
	_tmp1_ = self->iterator;
	_tmp2_ = gee_iterator_get ((GeeIterator*) _tmp1_);
	result = _tmp2_;
	return result;
}

static void
gee_tree_set_sub_iterator_real_remove (GeeIterator* base)
{
	GeeTreeSetSubIterator * self;
	GeeTreeSetIterator* _tmp0_;
	GeeTreeSetIterator* _tmp1_;
	self = (GeeTreeSetSubIterator*) base;
	_tmp0_ = self->iterator;
	_vala_assert (_tmp0_ != NULL, "iterator != null");
	_tmp1_ = self->iterator;
	gee_iterator_remove ((GeeIterator*) _tmp1_);
}

static gboolean
gee_tree_set_sub_iterator_real_foreach (GeeTraversable* base,
                                        GeeForallFunc f,
                                        gpointer f_target)
{
	GeeTreeSetSubIterator * self;
	gboolean _tmp0_;
	gboolean _tmp1_;
	gboolean result;
	self = (GeeTreeSetSubIterator*) base;
	_tmp0_ = gee_iterator_get_valid ((GeeIterator*) self);
	_tmp1_ = _tmp0_;
	if (_tmp1_) {
		gpointer _tmp2_;
		_tmp2_ = gee_iterator_get ((GeeIterator*) self);
		if (!f (_tmp2_, f_target)) {
			result = FALSE;
			return result;
		}
	}
	while (TRUE) {
		gpointer _tmp3_;
		if (!gee_iterator_next ((GeeIterator*) self)) {
			break;
		}
		_tmp3_ = gee_iterator_get ((GeeIterator*) self);
		if (!f (_tmp3_, f_target)) {
			result = FALSE;
			return result;
		}
	}
	result = TRUE;
	return result;
}

static GeeIterator**
gee_tree_set_sub_iterator_real_tee (GeeTraversable* base,
                                    guint forks,
                                    gint* result_length1)
{
	GeeTreeSetSubIterator * self;
	GeeIterator** result;
	self = (GeeTreeSetSubIterator*) base;
	if (forks == ((guint) 0)) {
		GeeIterator** _tmp0_;
		GeeIterator** _tmp1_;
		gint _tmp1__length1;
		_tmp0_ = g_new0 (GeeIterator*, 0 + 1);
		_tmp1_ = _tmp0_;
		_tmp1__length1 = 0;
		if (result_length1) {
			*result_length1 = _tmp1__length1;
		}
		result = _tmp1_;
		return result;
	} else {
		GeeIterator** _result_ = NULL;
		GeeIterator** _tmp2_;
		gint _result__length1;
		gint __result__size_;
		GeeIterator** _tmp3_;
		gint _tmp3__length1;
		GeeIterator* _tmp4_;
		GeeIterator** _tmp9_;
		gint _tmp9__length1;
		_tmp2_ = g_new0 (GeeIterator*, forks + 1);
		_result_ = _tmp2_;
		_result__length1 = forks;
		__result__size_ = _result__length1;
		_tmp3_ = _result_;
		_tmp3__length1 = _result__length1;
		_tmp4_ = _g_object_ref0 ((GeeIterator*) self);
		_g_object_unref0 (_tmp3_[0]);
		_tmp3_[0] = _tmp4_;
		{
			guint i = 0U;
			i = (guint) 1;
			{
				gboolean _tmp5_ = FALSE;
				_tmp5_ = TRUE;
				while (TRUE) {
					GeeIterator** _tmp7_;
					gint _tmp7__length1;
					GeeTreeSetSubIterator* _tmp8_;
					if (!_tmp5_) {
						guint _tmp6_;
						_tmp6_ = i;
						i = _tmp6_ + 1;
					}
					_tmp5_ = FALSE;
					if (!(i < forks)) {
						break;
					}
					_tmp7_ = _result_;
					_tmp7__length1 = _result__length1;
					_tmp8_ = gee_tree_set_sub_iterator_new_from_iterator (self->priv->g_type, (GBoxedCopyFunc) self->priv->g_dup_func, (GDestroyNotify) self->priv->g_destroy_func, self);
					_g_object_unref0 (_tmp7_[i]);
					_tmp7_[i] = (GeeIterator*) _tmp8_;
				}
			}
		}
		_tmp9_ = _result_;
		_tmp9__length1 = _result__length1;
		if (result_length1) {
			*result_length1 = _tmp9__length1;
		}
		result = _tmp9_;
		return result;
	}
}

static gboolean
gee_tree_set_sub_iterator_real_get_read_only (GeeIterator* base)
{
	gboolean result;
	GeeTreeSetSubIterator* self;
	self = (GeeTreeSetSubIterator*) base;
	result = FALSE;
	return result;
}

static gboolean
gee_tree_set_sub_iterator_real_get_valid (GeeIterator* base)
{
	gboolean result;
	GeeTreeSetSubIterator* self;
	GeeTreeSetIterator* _tmp0_;
	gboolean _tmp1_;
	gboolean _tmp2_;
	self = (GeeTreeSetSubIterator*) base;
	_tmp0_ = self->iterator;
	_tmp1_ = gee_iterator_get_valid ((GeeIterator*) _tmp0_);
	_tmp2_ = _tmp1_;
	result = _tmp2_;
	return result;
}

static void
gee_tree_set_sub_iterator_class_init (GeeTreeSetSubIteratorClass * klass,
                                      gpointer klass_data)
{
	gee_tree_set_sub_iterator_parent_class = g_type_class_peek_parent (klass);
	g_type_class_adjust_private_offset (klass, &GeeTreeSetSubIterator_private_offset);
	G_OBJECT_CLASS (klass)->get_property = _vala_gee_tree_set_sub_iterator_get_property;
	G_OBJECT_CLASS (klass)->set_property = _vala_gee_tree_set_sub_iterator_set_property;
	G_OBJECT_CLASS (klass)->finalize = gee_tree_set_sub_iterator_finalize;
	g_object_class_install_property (G_OBJECT_CLASS (klass), GEE_TREE_SET_SUB_ITERATOR_G_TYPE, g_param_spec_gtype ("g-type", "type", "type", G_TYPE_NONE, G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
	g_object_class_install_property (G_OBJECT_CLASS (klass), GEE_TREE_SET_SUB_ITERATOR_G_DUP_FUNC, g_param_spec_pointer ("g-dup-func", "dup func", "dup func", G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
	g_object_class_install_property (G_OBJECT_CLASS (klass), GEE_TREE_SET_SUB_ITERATOR_G_DESTROY_FUNC, g_param_spec_pointer ("g-destroy-func", "destroy func", "destroy func", G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
	g_object_class_install_property (G_OBJECT_CLASS (klass), GEE_TREE_SET_SUB_ITERATOR_READ_ONLY_PROPERTY, gee_tree_set_sub_iterator_properties[GEE_TREE_SET_SUB_ITERATOR_READ_ONLY_PROPERTY] = g_param_spec_boolean ("read-only", "read-only", "read-only", FALSE, G_PARAM_STATIC_STRINGS | G_PARAM_READABLE));
	g_object_class_install_property (G_OBJECT_CLASS (klass), GEE_TREE_SET_SUB_ITERATOR_VALID_PROPERTY, gee_tree_set_sub_iterator_properties[GEE_TREE_SET_SUB_ITERATOR_VALID_PROPERTY] = g_param_spec_boolean ("valid", "valid", "valid", FALSE, G_PARAM_STATIC_STRINGS | G_PARAM_READABLE));
}

static GType
gee_tree_set_sub_iterator_gee_traversable_get_g_type (GeeTreeSetSubIterator* self)
{
	return self->priv->g_type;
}

static GBoxedCopyFunc
gee_tree_set_sub_iterator_gee_traversable_get_g_dup_func (GeeTreeSetSubIterator* self)
{
	return self->priv->g_dup_func;
}

static GDestroyNotify
gee_tree_set_sub_iterator_gee_traversable_get_g_destroy_func (GeeTreeSetSubIterator* self)
{
	return self->priv->g_destroy_func;
}

static void
gee_tree_set_sub_iterator_gee_traversable_interface_init (GeeTraversableIface * iface,
                                                          gpointer iface_data)
{
	gee_tree_set_sub_iterator_gee_traversable_parent_iface = g_type_interface_peek_parent (iface);
	iface->foreach = (gboolean (*) (GeeTraversable*, GeeForallFunc, gpointer)) gee_tree_set_sub_iterator_real_foreach;
	iface->tee = (GeeIterator** (*) (GeeTraversable*, guint, gint*)) gee_tree_set_sub_iterator_real_tee;
	iface->get_g_type = (GType (*) (GeeTraversable *)) gee_tree_set_sub_iterator_gee_traversable_get_g_type;
	iface->get_g_dup_func = (GBoxedCopyFunc (*) (GeeTraversable *)) gee_tree_set_sub_iterator_gee_traversable_get_g_dup_func;
	iface->get_g_destroy_func = (GDestroyNotify (*) (GeeTraversable *)) gee_tree_set_sub_iterator_gee_traversable_get_g_destroy_func;
}

static void
gee_tree_set_sub_iterator_gee_iterator_interface_init (GeeIteratorIface * iface,
                                                       gpointer iface_data)
{
	gee_tree_set_sub_iterator_gee_iterator_parent_iface = g_type_interface_peek_parent (iface);
	iface->next = (gboolean (*) (GeeIterator*)) gee_tree_set_sub_iterator_real_next;
	iface->has_next = (gboolean (*) (GeeIterator*)) gee_tree_set_sub_iterator_real_has_next;
	iface->get = (gpointer (*) (GeeIterator*)) gee_tree_set_sub_iterator_real_get;
	iface->remove = (void (*) (GeeIterator*)) gee_tree_set_sub_iterator_real_remove;
	iface->get_read_only = gee_tree_set_sub_iterator_real_get_read_only;
	iface->get_valid = gee_tree_set_sub_iterator_real_get_valid;
}

static GType
gee_tree_set_sub_iterator_gee_bidir_iterator_get_g_type (GeeTreeSetSubIterator* self)
{
	return self->priv->g_type;
}

static GBoxedCopyFunc
gee_tree_set_sub_iterator_gee_bidir_iterator_get_g_dup_func (GeeTreeSetSubIterator* self)
{
	return self->priv->g_dup_func;
}

static GDestroyNotify
gee_tree_set_sub_iterator_gee_bidir_iterator_get_g_destroy_func (GeeTreeSetSubIterator* self)
{
	return self->priv->g_destroy_func;
}

static void
gee_tree_set_sub_iterator_gee_bidir_iterator_interface_init (GeeBidirIteratorIface * iface,
                                                             gpointer iface_data)
{
	gee_tree_set_sub_iterator_gee_bidir_iterator_parent_iface = g_type_interface_peek_parent (iface);
	iface->first = (gboolean (*) (GeeBidirIterator*)) gee_tree_set_sub_iterator_real_first;
	iface->previous = (gboolean (*) (GeeBidirIterator*)) gee_tree_set_sub_iterator_real_previous;
	iface->has_previous = (gboolean (*) (GeeBidirIterator*)) gee_tree_set_sub_iterator_real_has_previous;
	iface->last = (gboolean (*) (GeeBidirIterator*)) gee_tree_set_sub_iterator_real_last;
	iface->get_g_type = (GType (*) (GeeBidirIterator *)) gee_tree_set_sub_iterator_gee_bidir_iterator_get_g_type;
	iface->get_g_dup_func = (GBoxedCopyFunc (*) (GeeBidirIterator *)) gee_tree_set_sub_iterator_gee_bidir_iterator_get_g_dup_func;
	iface->get_g_destroy_func = (GDestroyNotify (*) (GeeBidirIterator *)) gee_tree_set_sub_iterator_gee_bidir_iterator_get_g_destroy_func;
}

static void
gee_tree_set_sub_iterator_instance_init (GeeTreeSetSubIterator * self,
                                         gpointer klass)
{
	self->priv = gee_tree_set_sub_iterator_get_instance_private (self);
	self->iterator = NULL;
}

static void
gee_tree_set_sub_iterator_finalize (GObject * obj)
{
	GeeTreeSetSubIterator * self;
	self = G_TYPE_CHECK_INSTANCE_CAST (obj, GEE_TREE_SET_TYPE_SUB_ITERATOR, GeeTreeSetSubIterator);
	_g_object_unref0 (self->set);
	_gee_tree_set_range_unref0 (self->range);
	_g_object_unref0 (self->iterator);
	G_OBJECT_CLASS (gee_tree_set_sub_iterator_parent_class)->finalize (obj);
}

static GType
gee_tree_set_sub_iterator_get_type_once (void)
{
	static const GTypeInfo g_define_type_info = { sizeof (GeeTreeSetSubIteratorClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) gee_tree_set_sub_iterator_class_init, (GClassFinalizeFunc) NULL, NULL, sizeof (GeeTreeSetSubIterator), 0, (GInstanceInitFunc) gee_tree_set_sub_iterator_instance_init, NULL };
	static const GInterfaceInfo gee_traversable_info = { (GInterfaceInitFunc) gee_tree_set_sub_iterator_gee_traversable_interface_init, (GInterfaceFinalizeFunc) NULL, NULL};
	static const GInterfaceInfo gee_iterator_info = { (GInterfaceInitFunc) gee_tree_set_sub_iterator_gee_iterator_interface_init, (GInterfaceFinalizeFunc) NULL, NULL};
	static const GInterfaceInfo gee_bidir_iterator_info = { (GInterfaceInitFunc) gee_tree_set_sub_iterator_gee_bidir_iterator_interface_init, (GInterfaceFinalizeFunc) NULL, NULL};
	GType gee_tree_set_sub_iterator_type_id;
	gee_tree_set_sub_iterator_type_id = g_type_register_static (G_TYPE_OBJECT, "GeeTreeSetSubIterator", &g_define_type_info, 0);
	g_type_add_interface_static (gee_tree_set_sub_iterator_type_id, GEE_TYPE_TRAVERSABLE, &gee_traversable_info);
	g_type_add_interface_static (gee_tree_set_sub_iterator_type_id, GEE_TYPE_ITERATOR, &gee_iterator_info);
	g_type_add_interface_static (gee_tree_set_sub_iterator_type_id, GEE_TYPE_BIDIR_ITERATOR, &gee_bidir_iterator_info);
	GeeTreeSetSubIterator_private_offset = g_type_add_instance_private (gee_tree_set_sub_iterator_type_id, sizeof (GeeTreeSetSubIteratorPrivate));
	return gee_tree_set_sub_iterator_type_id;
}

static GType
gee_tree_set_sub_iterator_get_type (void)
{
	static volatile gsize gee_tree_set_sub_iterator_type_id__once = 0;
	if (g_once_init_enter (&gee_tree_set_sub_iterator_type_id__once)) {
		GType gee_tree_set_sub_iterator_type_id;
		gee_tree_set_sub_iterator_type_id = gee_tree_set_sub_iterator_get_type_once ();
		g_once_init_leave (&gee_tree_set_sub_iterator_type_id__once, gee_tree_set_sub_iterator_type_id);
	}
	return gee_tree_set_sub_iterator_type_id__once;
}

static void
_vala_gee_tree_set_sub_iterator_get_property (GObject * object,
                                              guint property_id,
                                              GValue * value,
                                              GParamSpec * pspec)
{
	GeeTreeSetSubIterator * self;
	self = G_TYPE_CHECK_INSTANCE_CAST (object, GEE_TREE_SET_TYPE_SUB_ITERATOR, GeeTreeSetSubIterator);
	switch (property_id) {
		case GEE_TREE_SET_SUB_ITERATOR_READ_ONLY_PROPERTY:
		g_value_set_boolean (value, gee_iterator_get_read_only ((GeeIterator*) self));
		break;
		case GEE_TREE_SET_SUB_ITERATOR_VALID_PROPERTY:
		g_value_set_boolean (value, gee_iterator_get_valid ((GeeIterator*) self));
		break;
		case GEE_TREE_SET_SUB_ITERATOR_G_TYPE:
		g_value_set_gtype (value, self->priv->g_type);
		break;
		case GEE_TREE_SET_SUB_ITERATOR_G_DUP_FUNC:
		g_value_set_pointer (value, self->priv->g_dup_func);
		break;
		case GEE_TREE_SET_SUB_ITERATOR_G_DESTROY_FUNC:
		g_value_set_pointer (value, self->priv->g_destroy_func);
		break;
		default:
		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
		break;
	}
}

static void
_vala_gee_tree_set_sub_iterator_set_property (GObject * object,
                                              guint property_id,
                                              const GValue * value,
                                              GParamSpec * pspec)
{
	GeeTreeSetSubIterator * self;
	self = G_TYPE_CHECK_INSTANCE_CAST (object, GEE_TREE_SET_TYPE_SUB_ITERATOR, GeeTreeSetSubIterator);
	switch (property_id) {
		case GEE_TREE_SET_SUB_ITERATOR_G_TYPE:
		self->priv->g_type = g_value_get_gtype (value);
		break;
		case GEE_TREE_SET_SUB_ITERATOR_G_DUP_FUNC:
		self->priv->g_dup_func = g_value_get_pointer (value);
		break;
		case GEE_TREE_SET_SUB_ITERATOR_G_DESTROY_FUNC:
		self->priv->g_destroy_func = g_value_get_pointer (value);
		break;
		default:
		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
		break;
	}
}

static void
gee_tree_set_class_init (GeeTreeSetClass * klass,
                         gpointer klass_data)
{
	gee_tree_set_parent_class = g_type_class_peek_parent (klass);
	g_type_class_adjust_private_offset (klass, &GeeTreeSet_private_offset);
	((GeeAbstractCollectionClass *) klass)->contains = (gboolean (*) (GeeAbstractCollection*, gconstpointer)) gee_tree_set_real_contains;
	((GeeAbstractCollectionClass *) klass)->add = (gboolean (*) (GeeAbstractCollection*, gconstpointer)) gee_tree_set_real_add;
	((GeeAbstractCollectionClass *) klass)->remove = (gboolean (*) (GeeAbstractCollection*, gconstpointer)) gee_tree_set_real_remove;
	((GeeAbstractCollectionClass *) klass)->clear = (void (*) (GeeAbstractCollection*)) gee_tree_set_real_clear;
	((GeeAbstractCollectionClass *) klass)->foreach = (gboolean (*) (GeeAbstractCollection*, GeeForallFunc, gpointer)) gee_tree_set_real_foreach;
	((GeeAbstractCollectionClass *) klass)->iterator = (GeeIterator* (*) (GeeAbstractCollection*)) gee_tree_set_real_iterator;
	((GeeAbstractBidirSortedSetClass *) klass)->bidir_iterator = (GeeBidirIterator* (*) (GeeAbstractBidirSortedSet*)) gee_tree_set_real_bidir_iterator;
	((GeeAbstractSortedSetClass *) klass)->first = (gpointer (*) (GeeAbstractSortedSet*)) gee_tree_set_real_first;
	((GeeAbstractSortedSetClass *) klass)->last = (gpointer (*) (GeeAbstractSortedSet*)) gee_tree_set_real_last;
	((GeeAbstractSortedSetClass *) klass)->head_set = (GeeSortedSet* (*) (GeeAbstractSortedSet*, gconstpointer)) gee_tree_set_real_head_set;
	((GeeAbstractSortedSetClass *) klass)->tail_set = (GeeSortedSet* (*) (GeeAbstractSortedSet*, gconstpointer)) gee_tree_set_real_tail_set;
	((GeeAbstractSortedSetClass *) klass)->sub_set = (GeeSortedSet* (*) (GeeAbstractSortedSet*, gconstpointer, gconstpointer)) gee_tree_set_real_sub_set;
	((GeeAbstractSortedSetClass *) klass)->iterator_at = (GeeIterator* (*) (GeeAbstractSortedSet*, gconstpointer)) gee_tree_set_real_iterator_at;
	((GeeAbstractSortedSetClass *) klass)->lower = (gpointer (*) (GeeAbstractSortedSet*, gconstpointer)) gee_tree_set_real_lower;
	((GeeAbstractSortedSetClass *) klass)->higher = (gpointer (*) (GeeAbstractSortedSet*, gconstpointer)) gee_tree_set_real_higher;
	((GeeAbstractSortedSetClass *) klass)->floor = (gpointer (*) (GeeAbstractSortedSet*, gconstpointer)) gee_tree_set_real_floor;
	((GeeAbstractSortedSetClass *) klass)->ceil = (gpointer (*) (GeeAbstractSortedSet*, gconstpointer)) gee_tree_set_real_ceil;
	GEE_ABSTRACT_COLLECTION_CLASS (klass)->get_size = gee_tree_set_real_get_size;
	GEE_ABSTRACT_COLLECTION_CLASS (klass)->get_read_only = gee_tree_set_real_get_read_only;
	G_OBJECT_CLASS (klass)->get_property = _vala_gee_tree_set_get_property;
	G_OBJECT_CLASS (klass)->set_property = _vala_gee_tree_set_set_property;
	G_OBJECT_CLASS (klass)->finalize = gee_tree_set_finalize;
	g_object_class_install_property (G_OBJECT_CLASS (klass), GEE_TREE_SET_G_TYPE, g_param_spec_gtype ("g-type", "type", "type", G_TYPE_NONE, G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
	g_object_class_install_property (G_OBJECT_CLASS (klass), GEE_TREE_SET_G_DUP_FUNC, g_param_spec_pointer ("g-dup-func", "dup func", "dup func", G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
	g_object_class_install_property (G_OBJECT_CLASS (klass), GEE_TREE_SET_G_DESTROY_FUNC, g_param_spec_pointer ("g-destroy-func", "destroy func", "destroy func", G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
	/**
	 * {@inheritDoc}
	 */
	g_object_class_install_property (G_OBJECT_CLASS (klass), GEE_TREE_SET_SIZE_PROPERTY, gee_tree_set_properties[GEE_TREE_SET_SIZE_PROPERTY] = g_param_spec_int ("size", "size", "size", G_MININT, G_MAXINT, 0, G_PARAM_STATIC_STRINGS | G_PARAM_READABLE));
	/**
	 * {@inheritDoc}
	 */
	g_object_class_install_property (G_OBJECT_CLASS (klass), GEE_TREE_SET_READ_ONLY_PROPERTY, gee_tree_set_properties[GEE_TREE_SET_READ_ONLY_PROPERTY] = g_param_spec_boolean ("read-only", "read-only", "read-only", FALSE, G_PARAM_STATIC_STRINGS | G_PARAM_READABLE));
}

static void
gee_tree_set_instance_init (GeeTreeSet * self,
                            gpointer klass)
{
	self->priv = gee_tree_set_get_instance_private (self);
	self->priv->_size = 0;
	self->priv->root = NULL;
	self->priv->_first = NULL;
	self->priv->_last = NULL;
	self->priv->stamp = 0;
}

static void
gee_tree_set_finalize (GObject * obj)
{
	GeeTreeSet * self;
	self = G_TYPE_CHECK_INSTANCE_CAST (obj, GEE_TYPE_TREE_SET, GeeTreeSet);
	gee_abstract_collection_clear ((GeeAbstractCollection*) self);
	_gee_tree_set_node_free0 (self->priv->root);
	_gee_functions_compare_data_func_closure_unref0 (self->priv->_compare_func);
	G_OBJECT_CLASS (gee_tree_set_parent_class)->finalize (obj);
}

/**
 * Left-leaning red-black tree implementation of the {@link Set} interface.
 *
 * This implementation is especially well designed for large quantity of
 * data. The (balanced) tree implementation insure that the set and get
 * methods are in logarithmic complexity. For a linear implementation see
 * {@link HashSet}.
 *
 * @see HashSet
 */
static GType
gee_tree_set_get_type_once (void)
{
	static const GTypeInfo g_define_type_info = { sizeof (GeeTreeSetClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) gee_tree_set_class_init, (GClassFinalizeFunc) NULL, NULL, sizeof (GeeTreeSet), 0, (GInstanceInitFunc) gee_tree_set_instance_init, NULL };
	GType gee_tree_set_type_id;
	gee_tree_set_type_id = g_type_register_static (GEE_TYPE_ABSTRACT_BIDIR_SORTED_SET, "GeeTreeSet", &g_define_type_info, 0);
	GeeTreeSet_private_offset = g_type_add_instance_private (gee_tree_set_type_id, sizeof (GeeTreeSetPrivate));
	return gee_tree_set_type_id;
}

GType
gee_tree_set_get_type (void)
{
	static volatile gsize gee_tree_set_type_id__once = 0;
	if (g_once_init_enter (&gee_tree_set_type_id__once)) {
		GType gee_tree_set_type_id;
		gee_tree_set_type_id = gee_tree_set_get_type_once ();
		g_once_init_leave (&gee_tree_set_type_id__once, gee_tree_set_type_id);
	}
	return gee_tree_set_type_id__once;
}

static void
_vala_gee_tree_set_get_property (GObject * object,
                                 guint property_id,
                                 GValue * value,
                                 GParamSpec * pspec)
{
	GeeTreeSet * self;
	self = G_TYPE_CHECK_INSTANCE_CAST (object, GEE_TYPE_TREE_SET, GeeTreeSet);
	switch (property_id) {
		case GEE_TREE_SET_SIZE_PROPERTY:
		g_value_set_int (value, gee_abstract_collection_get_size ((GeeAbstractCollection*) self));
		break;
		case GEE_TREE_SET_READ_ONLY_PROPERTY:
		g_value_set_boolean (value, gee_abstract_collection_get_read_only ((GeeAbstractCollection*) self));
		break;
		case GEE_TREE_SET_G_TYPE:
		g_value_set_gtype (value, self->priv->g_type);
		break;
		case GEE_TREE_SET_G_DUP_FUNC:
		g_value_set_pointer (value, self->priv->g_dup_func);
		break;
		case GEE_TREE_SET_G_DESTROY_FUNC:
		g_value_set_pointer (value, self->priv->g_destroy_func);
		break;
		default:
		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
		break;
	}
}

static void
_vala_gee_tree_set_set_property (GObject * object,
                                 guint property_id,
                                 const GValue * value,
                                 GParamSpec * pspec)
{
	GeeTreeSet * self;
	self = G_TYPE_CHECK_INSTANCE_CAST (object, GEE_TYPE_TREE_SET, GeeTreeSet);
	switch (property_id) {
		case GEE_TREE_SET_G_TYPE:
		self->priv->g_type = g_value_get_gtype (value);
		break;
		case GEE_TREE_SET_G_DUP_FUNC:
		self->priv->g_dup_func = g_value_get_pointer (value);
		break;
		case GEE_TREE_SET_G_DESTROY_FUNC:
		self->priv->g_destroy_func = g_value_get_pointer (value);
		break;
		default:
		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
		break;
	}
}

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

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

