/* components-entry-undo.c generated by valac 0.56.3, the Vala compiler
 * generated from components-entry-undo.vala, do not modify */

/*
 * Copyright 2019 Michael Gratton <mike@vee.net>
 *
 * This software is licensed under the GNU Lesser General Public License
 * (version 2.1 or later).  See the COPYING file in this distribution.
 */

#include "geary-client-43.0.h"
#include <gtk/gtk.h>
#include <glib-object.h>
#include <glib.h>
#include <gio/gio.h>
#include <stdlib.h>
#include <string.h>
#include "geary-engine.h"

typedef enum  {
	COMPONENTS_ENTRY_UNDO_EDIT_TYPE_NONE,
	COMPONENTS_ENTRY_UNDO_EDIT_TYPE_INSERT,
	COMPONENTS_ENTRY_UNDO_EDIT_TYPE_DELETE
} ComponentsEntryUndoEditType;

#define COMPONENTS_ENTRY_UNDO_TYPE_EDIT_TYPE (components_entry_undo_edit_type_get_type ())
enum  {
	COMPONENTS_ENTRY_UNDO_0_PROPERTY,
	COMPONENTS_ENTRY_UNDO_TARGET_PROPERTY,
	COMPONENTS_ENTRY_UNDO_NUM_PROPERTIES
};
static GParamSpec* components_entry_undo_properties[COMPONENTS_ENTRY_UNDO_NUM_PROPERTIES];
#define _g_object_unref0(var) ((var == NULL) ? NULL : (var = (g_object_unref (var), NULL)))
#define _g_string_free0(var) ((var == NULL) ? NULL : (var = (g_string_free (var, TRUE), NULL)))
typedef struct _Block52Data Block52Data;
#define _g_error_free0(var) ((var == NULL) ? NULL : (var = (g_error_free (var), NULL)))
typedef struct _Block53Data Block53Data;
typedef struct _Block54Data Block54Data;

#define COMPONENTS_ENTRY_UNDO_TYPE_EDIT_COMMAND (components_entry_undo_edit_command_get_type ())
#define COMPONENTS_ENTRY_UNDO_EDIT_COMMAND(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), COMPONENTS_ENTRY_UNDO_TYPE_EDIT_COMMAND, ComponentsEntryUndoEditCommand))
#define COMPONENTS_ENTRY_UNDO_EDIT_COMMAND_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), COMPONENTS_ENTRY_UNDO_TYPE_EDIT_COMMAND, ComponentsEntryUndoEditCommandClass))
#define COMPONENTS_ENTRY_UNDO_IS_EDIT_COMMAND(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), COMPONENTS_ENTRY_UNDO_TYPE_EDIT_COMMAND))
#define COMPONENTS_ENTRY_UNDO_IS_EDIT_COMMAND_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), COMPONENTS_ENTRY_UNDO_TYPE_EDIT_COMMAND))
#define COMPONENTS_ENTRY_UNDO_EDIT_COMMAND_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), COMPONENTS_ENTRY_UNDO_TYPE_EDIT_COMMAND, ComponentsEntryUndoEditCommandClass))

typedef struct _ComponentsEntryUndoEditCommand ComponentsEntryUndoEditCommand;
typedef struct _ComponentsEntryUndoEditCommandClass ComponentsEntryUndoEditCommandClass;
#define _g_free0(var) (var = (g_free (var), NULL))
typedef struct _ComponentsEntryUndoEditCommandPrivate ComponentsEntryUndoEditCommandPrivate;
enum  {
	COMPONENTS_ENTRY_UNDO_EDIT_COMMAND_0_PROPERTY,
	COMPONENTS_ENTRY_UNDO_EDIT_COMMAND_NUM_PROPERTIES
};
static GParamSpec* components_entry_undo_edit_command_properties[COMPONENTS_ENTRY_UNDO_EDIT_COMMAND_NUM_PROPERTIES];
typedef struct _ComponentsEntryUndoEditCommandExecuteData ComponentsEntryUndoEditCommandExecuteData;
typedef struct _ComponentsEntryUndoEditCommandUndoData ComponentsEntryUndoEditCommandUndoData;
typedef struct _ComponentsEntryUndoEditCommandRedoData ComponentsEntryUndoEditCommandRedoData;

struct _ComponentsEntryUndoPrivate {
	GtkEntry* _target;
	ApplicationCommandStack* commands;
	ComponentsEntryUndoEditType last_edit;
	gint edit_start;
	gint edit_end;
	GString* edit_accumuluator;
	gboolean events_enabled;
	GSimpleActionGroup* edit_actions;
};

struct _Block52Data {
	int _ref_count_;
	ComponentsEntryUndo* self;
	gboolean complete;
};

struct _Block53Data {
	int _ref_count_;
	ComponentsEntryUndo* self;
	gboolean complete;
};

struct _Block54Data {
	int _ref_count_;
	ComponentsEntryUndo* self;
	gboolean complete;
};

struct _ComponentsEntryUndoEditCommand {
	ApplicationCommand parent_instance;
	ComponentsEntryUndoEditCommandPrivate * priv;
};

struct _ComponentsEntryUndoEditCommandClass {
	ApplicationCommandClass parent_class;
};

struct _ComponentsEntryUndoEditCommandPrivate {
	ComponentsEntryUndo* manager;
	ComponentsEntryUndoEditType edit;
	gint position;
	gchar* text;
};

struct _ComponentsEntryUndoEditCommandExecuteData {
	int _state_;
	GObject* _source_object_;
	GAsyncResult* _res_;
	GTask* _async_result;
	ComponentsEntryUndoEditCommand* self;
	GCancellable* cancellable;
};

struct _ComponentsEntryUndoEditCommandUndoData {
	int _state_;
	GObject* _source_object_;
	GAsyncResult* _res_;
	GTask* _async_result;
	ComponentsEntryUndoEditCommand* self;
	GCancellable* cancellable;
	ComponentsEntryUndo* manager;
	ComponentsEntryUndo* _tmp0_;
	ComponentsEntryUndo* _tmp1_;
	ComponentsEntryUndo* _tmp2_;
	ComponentsEntryUndo* _tmp3_;
	ComponentsEntryUndo* _tmp4_;
	GtkEntry* _tmp5_;
	GtkEntry* _tmp6_;
	ComponentsEntryUndo* _tmp7_;
	GtkEntry* _tmp8_;
	GtkEntry* _tmp9_;
	ComponentsEntryUndo* _tmp10_;
};

struct _ComponentsEntryUndoEditCommandRedoData {
	int _state_;
	GObject* _source_object_;
	GAsyncResult* _res_;
	GTask* _async_result;
	ComponentsEntryUndoEditCommand* self;
	GCancellable* cancellable;
	ComponentsEntryUndo* manager;
	ComponentsEntryUndo* _tmp0_;
	ComponentsEntryUndo* _tmp1_;
	ComponentsEntryUndo* _tmp2_;
	ComponentsEntryUndo* _tmp3_;
	ComponentsEntryUndo* _tmp4_;
	GtkEntry* _tmp5_;
	GtkEntry* _tmp6_;
	ComponentsEntryUndo* _tmp7_;
	GtkEntry* _tmp8_;
	GtkEntry* _tmp9_;
	ComponentsEntryUndo* _tmp10_;
};

static gint ComponentsEntryUndo_private_offset;
static gpointer components_entry_undo_parent_class = NULL;
static gint ComponentsEntryUndoEditCommand_private_offset;
static gpointer components_entry_undo_edit_command_parent_class = NULL;

static GType components_entry_undo_edit_type_get_type (void) G_GNUC_CONST  G_GNUC_UNUSED ;
static void components_entry_undo_on_inserted (ComponentsEntryUndo* self,
                                        const gchar* inserted,
                                        gint inserted_len,
                                        gint* pos);
static void _components_entry_undo_on_inserted_gtk_editable_insert_text (GtkEditable* _sender,
                                                                  const gchar* new_text,
                                                                  gint new_text_length,
                                                                  gint* position,
                                                                  gpointer self);
static void components_entry_undo_on_deleted (ComponentsEntryUndo* self,
                                       gint start,
                                       gint end);
static void _components_entry_undo_on_deleted_gtk_editable_delete_text (GtkEditable* _sender,
                                                                 gint start_pos,
                                                                 gint end_pos,
                                                                 gpointer self);
static void components_entry_undo_on_undo (ComponentsEntryUndo* self);
static void _components_entry_undo_on_undo_gsimple_action_activate_callback (GSimpleAction* action,
                                                                      GVariant* parameter,
                                                                      gpointer self);
static void components_entry_undo_on_redo (ComponentsEntryUndo* self);
static void _components_entry_undo_on_redo_gsimple_action_activate_callback (GSimpleAction* action,
                                                                      GVariant* parameter,
                                                                      gpointer self);
static void components_entry_undo_set_target (ComponentsEntryUndo* self,
                                       GtkEntry* value);
static void components_entry_undo_update_command_actions (ComponentsEntryUndo* self);
static void _components_entry_undo_update_command_actions_application_command_stack_executed (ApplicationCommandStack* _sender,
                                                                                       ApplicationCommand* command,
                                                                                       gpointer self);
static void _components_entry_undo_update_command_actions_application_command_stack_undone (ApplicationCommandStack* _sender,
                                                                                     ApplicationCommand* command,
                                                                                     gpointer self);
static void _components_entry_undo_update_command_actions_application_command_stack_redone (ApplicationCommandStack* _sender,
                                                                                     ApplicationCommand* command,
                                                                                     gpointer self);
static void components_entry_undo_execute (ComponentsEntryUndo* self,
                                    ApplicationCommand* command);
static Block52Data* block52_data_ref (Block52Data* _data52_);
static void block52_data_unref (void * _userdata_);
static void __lambda36_ (Block52Data* _data52_,
                  GObject* obj,
                  GAsyncResult* res);
static void ___lambda36__gasync_ready_callback (GObject* source_object,
                                         GAsyncResult* res,
                                         gpointer self);
static void components_entry_undo_do_undo (ComponentsEntryUndo* self);
static Block53Data* block53_data_ref (Block53Data* _data53_);
static void block53_data_unref (void * _userdata_);
static void components_entry_undo_flush_command (ComponentsEntryUndo* self);
static void __lambda37_ (Block53Data* _data53_,
                  GObject* obj,
                  GAsyncResult* res);
static void ___lambda37__gasync_ready_callback (GObject* source_object,
                                         GAsyncResult* res,
                                         gpointer self);
static void components_entry_undo_do_redo (ComponentsEntryUndo* self);
static Block54Data* block54_data_ref (Block54Data* _data54_);
static void block54_data_unref (void * _userdata_);
static void __lambda38_ (Block54Data* _data54_,
                  GObject* obj,
                  GAsyncResult* res);
static void ___lambda38__gasync_ready_callback (GObject* source_object,
                                         GAsyncResult* res,
                                         gpointer self);
static GType components_entry_undo_edit_command_get_type (void) G_GNUC_CONST  G_GNUC_UNUSED ;
static ComponentsEntryUndoEditCommand* components_entry_undo_extract_command (ComponentsEntryUndo* self);
static ComponentsEntryUndoEditCommand* components_entry_undo_edit_command_new (ComponentsEntryUndo* manager,
                                                                        ComponentsEntryUndoEditType edit,
                                                                        gint position,
                                                                        const gchar* text);
static ComponentsEntryUndoEditCommand* components_entry_undo_edit_command_construct (GType object_type,
                                                                              ComponentsEntryUndo* manager,
                                                                              ComponentsEntryUndoEditType edit,
                                                                              gint position,
                                                                              const gchar* text);
static void components_entry_undo_edit_command_real_execute_data_free (gpointer _data);
static void components_entry_undo_edit_command_real_execute (ApplicationCommand* base,
                                                      GCancellable* cancellable,
                                                      GAsyncReadyCallback _callback_,
                                                      gpointer _user_data_);
static gboolean components_entry_undo_edit_command_real_execute_co (ComponentsEntryUndoEditCommandExecuteData* _data_);
static void components_entry_undo_edit_command_real_undo_data_free (gpointer _data);
static void components_entry_undo_edit_command_real_undo (ApplicationCommand* base,
                                                   GCancellable* cancellable,
                                                   GAsyncReadyCallback _callback_,
                                                   gpointer _user_data_);
static gboolean components_entry_undo_edit_command_real_undo_co (ComponentsEntryUndoEditCommandUndoData* _data_);
static void components_entry_undo_edit_command_do_delete (ComponentsEntryUndoEditCommand* self,
                                                   GtkEntry* target);
static void components_entry_undo_edit_command_do_insert (ComponentsEntryUndoEditCommand* self,
                                                   GtkEntry* target);
static void components_entry_undo_edit_command_real_redo_data_free (gpointer _data);
static void components_entry_undo_edit_command_real_redo (ApplicationCommand* base,
                                                   GCancellable* cancellable,
                                                   GAsyncReadyCallback _callback_,
                                                   gpointer _user_data_);
static gboolean components_entry_undo_edit_command_real_redo_co (ComponentsEntryUndoEditCommandRedoData* _data_);
static void components_entry_undo_edit_command_finalize (GObject * obj);
static GType components_entry_undo_edit_command_get_type_once (void);
static void components_entry_undo_finalize (GObject * obj);
static GType components_entry_undo_get_type_once (void);
static void _vala_components_entry_undo_get_property (GObject * object,
                                               guint property_id,
                                               GValue * value,
                                               GParamSpec * pspec);
static void _vala_components_entry_undo_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 const GActionEntry COMPONENTS_ENTRY_UNDO_EDIT_ACTIONS[2] = {{ACTION_EDIT_UNDO, _components_entry_undo_on_undo_gsimple_action_activate_callback}, {ACTION_EDIT_REDO, _components_entry_undo_on_redo_gsimple_action_activate_callback}};

static inline gpointer
components_entry_undo_get_instance_private (ComponentsEntryUndo* self)
{
	return G_STRUCT_MEMBER_P (self, ComponentsEntryUndo_private_offset);
}

static void
_components_entry_undo_on_inserted_gtk_editable_insert_text (GtkEditable* _sender,
                                                             const gchar* new_text,
                                                             gint new_text_length,
                                                             gint* position,
                                                             gpointer self)
{
	components_entry_undo_on_inserted ((ComponentsEntryUndo*) self, new_text, new_text_length, position);
}

static void
_components_entry_undo_on_deleted_gtk_editable_delete_text (GtkEditable* _sender,
                                                            gint start_pos,
                                                            gint end_pos,
                                                            gpointer self)
{
	components_entry_undo_on_deleted ((ComponentsEntryUndo*) self, start_pos, end_pos);
}

static GType
components_entry_undo_edit_type_get_type_once (void)
{
	static const GEnumValue values[] = {{COMPONENTS_ENTRY_UNDO_EDIT_TYPE_NONE, "COMPONENTS_ENTRY_UNDO_EDIT_TYPE_NONE", "none"}, {COMPONENTS_ENTRY_UNDO_EDIT_TYPE_INSERT, "COMPONENTS_ENTRY_UNDO_EDIT_TYPE_INSERT", "insert"}, {COMPONENTS_ENTRY_UNDO_EDIT_TYPE_DELETE, "COMPONENTS_ENTRY_UNDO_EDIT_TYPE_DELETE", "delete"}, {0, NULL, NULL}};
	GType components_entry_undo_edit_type_type_id;
	components_entry_undo_edit_type_type_id = g_enum_register_static ("ComponentsEntryUndoEditType", values);
	return components_entry_undo_edit_type_type_id;
}

static GType
components_entry_undo_edit_type_get_type (void)
{
	static volatile gsize components_entry_undo_edit_type_type_id__once = 0;
	if (g_once_init_enter (&components_entry_undo_edit_type_type_id__once)) {
		GType components_entry_undo_edit_type_type_id;
		components_entry_undo_edit_type_type_id = components_entry_undo_edit_type_get_type_once ();
		g_once_init_leave (&components_entry_undo_edit_type_type_id__once, components_entry_undo_edit_type_type_id);
	}
	return components_entry_undo_edit_type_type_id__once;
}

static void
_components_entry_undo_on_undo_gsimple_action_activate_callback (GSimpleAction* action,
                                                                 GVariant* parameter,
                                                                 gpointer self)
{
	components_entry_undo_on_undo ((ComponentsEntryUndo*) self);
}

static void
_components_entry_undo_on_redo_gsimple_action_activate_callback (GSimpleAction* action,
                                                                 GVariant* parameter,
                                                                 gpointer self)
{
	components_entry_undo_on_redo ((ComponentsEntryUndo*) self);
}

GtkEntry*
components_entry_undo_get_target (ComponentsEntryUndo* self)
{
	GtkEntry* result;
	GtkEntry* _tmp0_;
	g_return_val_if_fail (COMPONENTS_IS_ENTRY_UNDO (self), NULL);
	_tmp0_ = self->priv->_target;
	result = _tmp0_;
	return result;
}

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

static void
components_entry_undo_set_target (ComponentsEntryUndo* self,
                                  GtkEntry* value)
{
	GtkEntry* old_value;
	g_return_if_fail (COMPONENTS_IS_ENTRY_UNDO (self));
	old_value = components_entry_undo_get_target (self);
	if (old_value != value) {
		GtkEntry* _tmp0_;
		_tmp0_ = _g_object_ref0 (value);
		_g_object_unref0 (self->priv->_target);
		self->priv->_target = _tmp0_;
		g_object_notify_by_pspec ((GObject *) self, components_entry_undo_properties[COMPONENTS_ENTRY_UNDO_TARGET_PROPERTY]);
	}
}

static void
_components_entry_undo_update_command_actions_application_command_stack_executed (ApplicationCommandStack* _sender,
                                                                                  ApplicationCommand* command,
                                                                                  gpointer self)
{
	components_entry_undo_update_command_actions ((ComponentsEntryUndo*) self);
}

static void
_components_entry_undo_update_command_actions_application_command_stack_undone (ApplicationCommandStack* _sender,
                                                                                ApplicationCommand* command,
                                                                                gpointer self)
{
	components_entry_undo_update_command_actions ((ComponentsEntryUndo*) self);
}

static void
_components_entry_undo_update_command_actions_application_command_stack_redone (ApplicationCommandStack* _sender,
                                                                                ApplicationCommand* command,
                                                                                gpointer self)
{
	components_entry_undo_update_command_actions ((ComponentsEntryUndo*) self);
}

ComponentsEntryUndo*
components_entry_undo_construct (GType object_type,
                                 GtkEntry* target)
{
	ComponentsEntryUndo * self = NULL;
	GSimpleActionGroup* _tmp0_;
	GtkEntry* _tmp1_;
	GSimpleActionGroup* _tmp2_;
	GtkEntry* _tmp3_;
	GtkEntry* _tmp4_;
	ApplicationCommandStack* _tmp5_;
	ApplicationCommandStack* _tmp6_;
	ApplicationCommandStack* _tmp7_;
	ApplicationCommandStack* _tmp8_;
	g_return_val_if_fail (G_TYPE_CHECK_INSTANCE_TYPE (target, gtk_entry_get_type ()), NULL);
	self = (ComponentsEntryUndo*) geary_base_object_construct (object_type);
	_tmp0_ = self->priv->edit_actions;
	g_action_map_add_action_entries (G_TYPE_CHECK_INSTANCE_CAST (_tmp0_, g_action_map_get_type (), GActionMap), COMPONENTS_ENTRY_UNDO_EDIT_ACTIONS, (gint) G_N_ELEMENTS (COMPONENTS_ENTRY_UNDO_EDIT_ACTIONS), self);
	components_entry_undo_set_target (self, target);
	_tmp1_ = self->priv->_target;
	_tmp2_ = self->priv->edit_actions;
	gtk_widget_insert_action_group (G_TYPE_CHECK_INSTANCE_CAST (_tmp1_, gtk_widget_get_type (), GtkWidget), ACTION_EDIT_GROUP_NAME, G_TYPE_CHECK_INSTANCE_CAST (_tmp2_, g_action_group_get_type (), GActionGroup));
	_tmp3_ = self->priv->_target;
	g_signal_connect_object (G_TYPE_CHECK_INSTANCE_CAST (_tmp3_, gtk_editable_get_type (), GtkEditable), "insert-text", (GCallback) _components_entry_undo_on_inserted_gtk_editable_insert_text, self, 0);
	_tmp4_ = self->priv->_target;
	g_signal_connect_object (G_TYPE_CHECK_INSTANCE_CAST (_tmp4_, gtk_editable_get_type (), GtkEditable), "delete-text", (GCallback) _components_entry_undo_on_deleted_gtk_editable_delete_text, self, 0);
	_tmp5_ = application_command_stack_new ();
	_g_object_unref0 (self->priv->commands);
	self->priv->commands = _tmp5_;
	_tmp6_ = self->priv->commands;
	g_signal_connect_object (_tmp6_, "executed", (GCallback) _components_entry_undo_update_command_actions_application_command_stack_executed, self, 0);
	_tmp7_ = self->priv->commands;
	g_signal_connect_object (_tmp7_, "undone", (GCallback) _components_entry_undo_update_command_actions_application_command_stack_undone, self, 0);
	_tmp8_ = self->priv->commands;
	g_signal_connect_object (_tmp8_, "redone", (GCallback) _components_entry_undo_update_command_actions_application_command_stack_redone, self, 0);
	return self;
}

ComponentsEntryUndo*
components_entry_undo_new (GtkEntry* target)
{
	return components_entry_undo_construct (COMPONENTS_TYPE_ENTRY_UNDO, target);
}

/** Resets the editing stack for the target entry. */
void
components_entry_undo_reset (ComponentsEntryUndo* self)
{
	GString* _tmp0_;
	ApplicationCommandStack* _tmp1_;
	g_return_if_fail (COMPONENTS_IS_ENTRY_UNDO (self));
	self->priv->last_edit = COMPONENTS_ENTRY_UNDO_EDIT_TYPE_NONE;
	_tmp0_ = self->priv->edit_accumuluator;
	g_string_truncate (_tmp0_, (gsize) 0);
	_tmp1_ = self->priv->commands;
	application_command_stack_clear (_tmp1_);
}

static Block52Data*
block52_data_ref (Block52Data* _data52_)
{
	g_atomic_int_inc (&_data52_->_ref_count_);
	return _data52_;
}

static void
block52_data_unref (void * _userdata_)
{
	Block52Data* _data52_;
	_data52_ = (Block52Data*) _userdata_;
	if (g_atomic_int_dec_and_test (&_data52_->_ref_count_)) {
		ComponentsEntryUndo* self;
		self = _data52_->self;
		_g_object_unref0 (self);
		g_slice_free (Block52Data, _data52_);
	}
}

static void
__lambda36_ (Block52Data* _data52_,
             GObject* obj,
             GAsyncResult* res)
{
	ComponentsEntryUndo* self;
	GError* _inner_error0_ = NULL;
	self = _data52_->self;
	g_return_if_fail ((obj == NULL) || G_TYPE_CHECK_INSTANCE_TYPE (obj, G_TYPE_OBJECT));
	g_return_if_fail (G_TYPE_CHECK_INSTANCE_TYPE (res, g_async_result_get_type ()));
	{
		ApplicationCommandStack* _tmp0_;
		_tmp0_ = self->priv->commands;
		application_command_stack_execute_finish (_tmp0_, res, &_inner_error0_);
		if (G_UNLIKELY (_inner_error0_ != NULL)) {
			goto __catch0_g_error;
		}
	}
	goto __finally0;
	__catch0_g_error:
	{
		GError* thrown = NULL;
		GError* _tmp1_;
		const gchar* _tmp2_;
		thrown = _inner_error0_;
		_inner_error0_ = NULL;
		_tmp1_ = thrown;
		_tmp2_ = _tmp1_->message;
		g_debug ("components-entry-undo.vala:151: Failed to execute entry edit command: " \
"%s", _tmp2_);
		_g_error_free0 (thrown);
	}
	__finally0:
	if (G_UNLIKELY (_inner_error0_ != NULL)) {
		g_critical ("file %s: line %d: uncaught error: %s (%s, %d)", __FILE__, __LINE__, _inner_error0_->message, g_quark_to_string (_inner_error0_->domain), _inner_error0_->code);
		g_clear_error (&_inner_error0_);
		return;
	}
	_data52_->complete = TRUE;
}

static void
___lambda36__gasync_ready_callback (GObject* source_object,
                                    GAsyncResult* res,
                                    gpointer self)
{
	__lambda36_ (self, source_object, res);
	block52_data_unref (self);
}

static void
components_entry_undo_execute (ComponentsEntryUndo* self,
                               ApplicationCommand* command)
{
	Block52Data* _data52_;
	ApplicationCommandStack* _tmp0_;
	g_return_if_fail (COMPONENTS_IS_ENTRY_UNDO (self));
	g_return_if_fail (APPLICATION_IS_COMMAND (command));
	_data52_ = g_slice_new0 (Block52Data);
	_data52_->_ref_count_ = 1;
	_data52_->self = g_object_ref (self);
	_data52_->complete = FALSE;
	_tmp0_ = self->priv->commands;
	application_command_stack_execute (_tmp0_, command, NULL, ___lambda36__gasync_ready_callback, block52_data_ref (_data52_));
	while (TRUE) {
		if (!(!_data52_->complete)) {
			break;
		}
		gtk_main_iteration ();
	}
	block52_data_unref (_data52_);
	_data52_ = NULL;
}

static Block53Data*
block53_data_ref (Block53Data* _data53_)
{
	g_atomic_int_inc (&_data53_->_ref_count_);
	return _data53_;
}

static void
block53_data_unref (void * _userdata_)
{
	Block53Data* _data53_;
	_data53_ = (Block53Data*) _userdata_;
	if (g_atomic_int_dec_and_test (&_data53_->_ref_count_)) {
		ComponentsEntryUndo* self;
		self = _data53_->self;
		_g_object_unref0 (self);
		g_slice_free (Block53Data, _data53_);
	}
}

static void
__lambda37_ (Block53Data* _data53_,
             GObject* obj,
             GAsyncResult* res)
{
	ComponentsEntryUndo* self;
	GError* _inner_error0_ = NULL;
	self = _data53_->self;
	g_return_if_fail ((obj == NULL) || G_TYPE_CHECK_INSTANCE_TYPE (obj, G_TYPE_OBJECT));
	g_return_if_fail (G_TYPE_CHECK_INSTANCE_TYPE (res, g_async_result_get_type ()));
	{
		ApplicationCommandStack* _tmp0_;
		_tmp0_ = self->priv->commands;
		application_command_stack_undo_finish (_tmp0_, res, &_inner_error0_);
		if (G_UNLIKELY (_inner_error0_ != NULL)) {
			goto __catch0_g_error;
		}
	}
	goto __finally0;
	__catch0_g_error:
	{
		GError* thrown = NULL;
		GError* _tmp1_;
		const gchar* _tmp2_;
		thrown = _inner_error0_;
		_inner_error0_ = NULL;
		_tmp1_ = thrown;
		_tmp2_ = _tmp1_->message;
		g_debug ("components-entry-undo.vala:173: Failed to undo entry edit command: %s", _tmp2_);
		_g_error_free0 (thrown);
	}
	__finally0:
	if (G_UNLIKELY (_inner_error0_ != NULL)) {
		g_critical ("file %s: line %d: uncaught error: %s (%s, %d)", __FILE__, __LINE__, _inner_error0_->message, g_quark_to_string (_inner_error0_->domain), _inner_error0_->code);
		g_clear_error (&_inner_error0_);
		return;
	}
	_data53_->complete = TRUE;
}

static void
___lambda37__gasync_ready_callback (GObject* source_object,
                                    GAsyncResult* res,
                                    gpointer self)
{
	__lambda37_ (self, source_object, res);
	block53_data_unref (self);
}

static void
components_entry_undo_do_undo (ComponentsEntryUndo* self)
{
	Block53Data* _data53_;
	ApplicationCommandStack* _tmp0_;
	g_return_if_fail (COMPONENTS_IS_ENTRY_UNDO (self));
	_data53_ = g_slice_new0 (Block53Data);
	_data53_->_ref_count_ = 1;
	_data53_->self = g_object_ref (self);
	components_entry_undo_flush_command (self);
	_data53_->complete = FALSE;
	_tmp0_ = self->priv->commands;
	application_command_stack_undo (_tmp0_, NULL, ___lambda37__gasync_ready_callback, block53_data_ref (_data53_));
	while (TRUE) {
		if (!(!_data53_->complete)) {
			break;
		}
		gtk_main_iteration ();
	}
	block53_data_unref (_data53_);
	_data53_ = NULL;
}

static Block54Data*
block54_data_ref (Block54Data* _data54_)
{
	g_atomic_int_inc (&_data54_->_ref_count_);
	return _data54_;
}

static void
block54_data_unref (void * _userdata_)
{
	Block54Data* _data54_;
	_data54_ = (Block54Data*) _userdata_;
	if (g_atomic_int_dec_and_test (&_data54_->_ref_count_)) {
		ComponentsEntryUndo* self;
		self = _data54_->self;
		_g_object_unref0 (self);
		g_slice_free (Block54Data, _data54_);
	}
}

static void
__lambda38_ (Block54Data* _data54_,
             GObject* obj,
             GAsyncResult* res)
{
	ComponentsEntryUndo* self;
	GError* _inner_error0_ = NULL;
	self = _data54_->self;
	g_return_if_fail ((obj == NULL) || G_TYPE_CHECK_INSTANCE_TYPE (obj, G_TYPE_OBJECT));
	g_return_if_fail (G_TYPE_CHECK_INSTANCE_TYPE (res, g_async_result_get_type ()));
	{
		ApplicationCommandStack* _tmp0_;
		_tmp0_ = self->priv->commands;
		application_command_stack_redo_finish (_tmp0_, res, &_inner_error0_);
		if (G_UNLIKELY (_inner_error0_ != NULL)) {
			goto __catch0_g_error;
		}
	}
	goto __finally0;
	__catch0_g_error:
	{
		GError* thrown = NULL;
		GError* _tmp1_;
		const gchar* _tmp2_;
		thrown = _inner_error0_;
		_inner_error0_ = NULL;
		_tmp1_ = thrown;
		_tmp2_ = _tmp1_->message;
		g_debug ("components-entry-undo.vala:195: Failed to redo entry edit command: %s", _tmp2_);
		_g_error_free0 (thrown);
	}
	__finally0:
	if (G_UNLIKELY (_inner_error0_ != NULL)) {
		g_critical ("file %s: line %d: uncaught error: %s (%s, %d)", __FILE__, __LINE__, _inner_error0_->message, g_quark_to_string (_inner_error0_->domain), _inner_error0_->code);
		g_clear_error (&_inner_error0_);
		return;
	}
	_data54_->complete = TRUE;
}

static void
___lambda38__gasync_ready_callback (GObject* source_object,
                                    GAsyncResult* res,
                                    gpointer self)
{
	__lambda38_ (self, source_object, res);
	block54_data_unref (self);
}

static void
components_entry_undo_do_redo (ComponentsEntryUndo* self)
{
	Block54Data* _data54_;
	ApplicationCommandStack* _tmp0_;
	g_return_if_fail (COMPONENTS_IS_ENTRY_UNDO (self));
	_data54_ = g_slice_new0 (Block54Data);
	_data54_->_ref_count_ = 1;
	_data54_->self = g_object_ref (self);
	components_entry_undo_flush_command (self);
	_data54_->complete = FALSE;
	_tmp0_ = self->priv->commands;
	application_command_stack_redo (_tmp0_, NULL, ___lambda38__gasync_ready_callback, block54_data_ref (_data54_));
	while (TRUE) {
		if (!(!_data54_->complete)) {
			break;
		}
		gtk_main_iteration ();
	}
	block54_data_unref (_data54_);
	_data54_ = NULL;
}

static void
components_entry_undo_flush_command (ComponentsEntryUndo* self)
{
	ComponentsEntryUndoEditCommand* command = NULL;
	ComponentsEntryUndoEditCommand* _tmp0_;
	ComponentsEntryUndoEditCommand* _tmp1_;
	g_return_if_fail (COMPONENTS_IS_ENTRY_UNDO (self));
	_tmp0_ = components_entry_undo_extract_command (self);
	command = _tmp0_;
	_tmp1_ = command;
	if (_tmp1_ != NULL) {
		ComponentsEntryUndoEditCommand* _tmp2_;
		_tmp2_ = command;
		components_entry_undo_execute (self, G_TYPE_CHECK_INSTANCE_CAST (_tmp2_, APPLICATION_TYPE_COMMAND, ApplicationCommand));
	}
	_g_object_unref0 (command);
}

static ComponentsEntryUndoEditCommand*
components_entry_undo_extract_command (ComponentsEntryUndo* self)
{
	ComponentsEntryUndoEditCommand* command = NULL;
	ComponentsEntryUndoEditCommand* result;
	g_return_val_if_fail (COMPONENTS_IS_ENTRY_UNDO (self), NULL);
	command = NULL;
	if (self->priv->last_edit != COMPONENTS_ENTRY_UNDO_EDIT_TYPE_NONE) {
		GString* _tmp0_;
		const gchar* _tmp1_;
		ComponentsEntryUndoEditCommand* _tmp2_;
		GString* _tmp3_;
		_tmp0_ = self->priv->edit_accumuluator;
		_tmp1_ = _tmp0_->str;
		_tmp2_ = components_entry_undo_edit_command_new (self, self->priv->last_edit, self->priv->edit_start, _tmp1_);
		_g_object_unref0 (command);
		command = _tmp2_;
		_tmp3_ = self->priv->edit_accumuluator;
		g_string_truncate (_tmp3_, (gsize) 0);
	}
	self->priv->last_edit = COMPONENTS_ENTRY_UNDO_EDIT_TYPE_NONE;
	result = command;
	return result;
}

static void
components_entry_undo_update_command_actions (ComponentsEntryUndo* self)
{
	GSimpleActionGroup* _tmp0_;
	GAction* _tmp1_;
	ApplicationCommandStack* _tmp2_;
	gboolean _tmp3_;
	gboolean _tmp4_;
	GSimpleActionGroup* _tmp5_;
	GAction* _tmp6_;
	ApplicationCommandStack* _tmp7_;
	gboolean _tmp8_;
	gboolean _tmp9_;
	g_return_if_fail (COMPONENTS_IS_ENTRY_UNDO (self));
	_tmp0_ = self->priv->edit_actions;
	_tmp1_ = g_action_map_lookup_action (G_TYPE_CHECK_INSTANCE_CAST (_tmp0_, g_action_map_get_type (), GActionMap), ACTION_EDIT_UNDO);
	_tmp2_ = self->priv->commands;
	_tmp3_ = application_command_stack_get_can_undo (_tmp2_);
	_tmp4_ = _tmp3_;
	g_simple_action_set_enabled (G_TYPE_CHECK_INSTANCE_CAST (_tmp1_, g_simple_action_get_type (), GSimpleAction), _tmp4_);
	_tmp5_ = self->priv->edit_actions;
	_tmp6_ = g_action_map_lookup_action (G_TYPE_CHECK_INSTANCE_CAST (_tmp5_, g_action_map_get_type (), GActionMap), ACTION_EDIT_REDO);
	_tmp7_ = self->priv->commands;
	_tmp8_ = application_command_stack_get_can_redo (_tmp7_);
	_tmp9_ = _tmp8_;
	g_simple_action_set_enabled (G_TYPE_CHECK_INSTANCE_CAST (_tmp6_, g_simple_action_get_type (), GSimpleAction), _tmp9_);
}

static gunichar
string_get_char (const gchar* self,
                 glong index)
{
	gunichar result;
	g_return_val_if_fail (self != NULL, 0U);
	result = g_utf8_get_char (((gchar*) self) + index);
	return result;
}

static void
components_entry_undo_on_inserted (ComponentsEntryUndo* self,
                                   const gchar* inserted,
                                   gint inserted_len,
                                   gint* pos)
{
	g_return_if_fail (COMPONENTS_IS_ENTRY_UNDO (self));
	g_return_if_fail (inserted != NULL);
	if (self->priv->events_enabled) {
		gboolean is_non_trivial = FALSE;
		gboolean insert_handled = FALSE;
		inserted_len = g_utf8_strlen (inserted, (gssize) -1);
		is_non_trivial = inserted_len > 1;
		insert_handled = FALSE;
		if (self->priv->last_edit == COMPONENTS_ENTRY_UNDO_EDIT_TYPE_DELETE) {
			ApplicationCommand* command = NULL;
			ComponentsEntryUndoEditCommand* _tmp0_;
			gboolean _tmp1_ = FALSE;
			gboolean _tmp2_ = FALSE;
			ApplicationCommand* _tmp3_;
			ApplicationCommand* _tmp11_;
			_tmp0_ = components_entry_undo_extract_command (self);
			command = G_TYPE_CHECK_INSTANCE_CAST (_tmp0_, APPLICATION_TYPE_COMMAND, ApplicationCommand);
			_tmp3_ = command;
			if (_tmp3_ != NULL) {
				_tmp2_ = self->priv->edit_start == (*pos);
			} else {
				_tmp2_ = FALSE;
			}
			if (_tmp2_) {
				_tmp1_ = is_non_trivial;
			} else {
				_tmp1_ = FALSE;
			}
			if (_tmp1_) {
				GString* _tmp4_;
				ApplicationCommand* _tmp5_;
				ApplicationCommand* _tmp6_;
				ComponentsEntryUndoEditCommand* _tmp7_;
				ApplicationCommand** _tmp8_;
				ApplicationCommand** _tmp9_;
				gint _tmp9__length1;
				ApplicationCommandSequence* _tmp10_;
				self->priv->last_edit = COMPONENTS_ENTRY_UNDO_EDIT_TYPE_INSERT;
				self->priv->edit_start = *pos;
				_tmp4_ = self->priv->edit_accumuluator;
				g_string_append (_tmp4_, inserted);
				_tmp5_ = command;
				_tmp6_ = _g_object_ref0 (_tmp5_);
				_tmp7_ = components_entry_undo_extract_command (self);
				_tmp8_ = g_new0 (ApplicationCommand*, 2 + 1);
				_tmp8_[0] = _tmp6_;
				_tmp8_[1] = G_TYPE_CHECK_INSTANCE_CAST (_tmp7_, APPLICATION_TYPE_COMMAND, ApplicationCommand);
				_tmp9_ = _tmp8_;
				_tmp9__length1 = 2;
				_tmp10_ = application_command_sequence_new (_tmp9_, 2);
				_g_object_unref0 (command);
				command = G_TYPE_CHECK_INSTANCE_CAST (_tmp10_, APPLICATION_TYPE_COMMAND, ApplicationCommand);
				_tmp9_ = (_vala_array_free (_tmp9_, _tmp9__length1, (GDestroyNotify) g_object_unref), NULL);
				insert_handled = TRUE;
			}
			_tmp11_ = command;
			if (_tmp11_ != NULL) {
				ApplicationCommand* _tmp12_;
				_tmp12_ = command;
				components_entry_undo_execute (self, _tmp12_);
			}
			_g_object_unref0 (command);
		}
		if (!insert_handled) {
			gboolean _tmp13_ = FALSE;
			gboolean is_disjoint_edit = FALSE;
			gboolean _tmp14_ = FALSE;
			gboolean is_non_alpha_num = FALSE;
			gboolean _tmp15_ = FALSE;
			gboolean _tmp16_ = FALSE;
			GString* _tmp17_;
			gboolean _tmp18_ = FALSE;
			if (self->priv->last_edit == COMPONENTS_ENTRY_UNDO_EDIT_TYPE_INSERT) {
				_tmp13_ = self->priv->edit_end != (*pos);
			} else {
				_tmp13_ = FALSE;
			}
			is_disjoint_edit = _tmp13_;
			if (inserted_len == 1) {
				_tmp14_ = !g_unichar_isalnum (string_get_char (inserted, (glong) 0));
			} else {
				_tmp14_ = FALSE;
			}
			is_non_alpha_num = _tmp14_;
			if (is_disjoint_edit) {
				_tmp16_ = TRUE;
			} else {
				_tmp16_ = is_non_alpha_num;
			}
			if (_tmp16_) {
				_tmp15_ = TRUE;
			} else {
				_tmp15_ = is_non_trivial;
			}
			if (_tmp15_) {
				components_entry_undo_flush_command (self);
			}
			if (self->priv->last_edit == COMPONENTS_ENTRY_UNDO_EDIT_TYPE_NONE) {
				self->priv->last_edit = COMPONENTS_ENTRY_UNDO_EDIT_TYPE_INSERT;
				self->priv->edit_start = *pos;
				self->priv->edit_end = *pos;
			}
			self->priv->edit_end = self->priv->edit_end + inserted_len;
			_tmp17_ = self->priv->edit_accumuluator;
			g_string_append (_tmp17_, inserted);
			if (is_non_alpha_num) {
				_tmp18_ = TRUE;
			} else {
				_tmp18_ = is_non_trivial;
			}
			if (_tmp18_) {
				components_entry_undo_flush_command (self);
			}
		}
	}
}

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

static gint
string_index_of_nth_char (const gchar* self,
                          glong c)
{
	gchar* _tmp0_;
	gint result;
	g_return_val_if_fail (self != NULL, 0);
	_tmp0_ = g_utf8_offset_to_pointer (self, c);
	result = (gint) (_tmp0_ - ((gchar*) self));
	return result;
}

static void
components_entry_undo_on_deleted (ComponentsEntryUndo* self,
                                  gint start,
                                  gint end)
{
	g_return_if_fail (COMPONENTS_IS_ENTRY_UNDO (self));
	if (self->priv->events_enabled) {
		gchar* text = NULL;
		GtkEntry* _tmp0_;
		GtkEntryBuffer* _tmp1_;
		GtkEntryBuffer* _tmp2_;
		const gchar* _tmp3_;
		gchar* _tmp4_;
		gboolean _tmp6_ = FALSE;
		gboolean is_disjoint_edit = FALSE;
		gboolean _tmp7_ = FALSE;
		GString* _tmp8_;
		const gchar* _tmp9_;
		const gchar* _tmp10_;
		const gchar* _tmp11_;
		gchar* _tmp12_;
		gchar* _tmp13_;
		_tmp0_ = self->priv->_target;
		_tmp1_ = gtk_entry_get_buffer (_tmp0_);
		_tmp2_ = _tmp1_;
		_tmp3_ = gtk_entry_buffer_get_text (_tmp2_);
		_tmp4_ = g_strdup (_tmp3_);
		text = _tmp4_;
		if (end < 0) {
			const gchar* _tmp5_;
			_tmp5_ = text;
			end = g_utf8_strlen (_tmp5_, (gssize) -1);
		}
		if (self->priv->last_edit == COMPONENTS_ENTRY_UNDO_EDIT_TYPE_DELETE) {
			_tmp6_ = self->priv->edit_start != end;
		} else {
			_tmp6_ = FALSE;
		}
		is_disjoint_edit = _tmp6_;
		if (self->priv->last_edit == COMPONENTS_ENTRY_UNDO_EDIT_TYPE_INSERT) {
			_tmp7_ = TRUE;
		} else {
			_tmp7_ = is_disjoint_edit;
		}
		if (_tmp7_) {
			components_entry_undo_flush_command (self);
		}
		if (self->priv->last_edit == COMPONENTS_ENTRY_UNDO_EDIT_TYPE_NONE) {
			self->priv->last_edit = COMPONENTS_ENTRY_UNDO_EDIT_TYPE_DELETE;
			self->priv->edit_end = end;
		}
		self->priv->edit_start = start;
		_tmp8_ = self->priv->edit_accumuluator;
		_tmp9_ = text;
		_tmp10_ = text;
		_tmp11_ = text;
		_tmp12_ = string_slice (_tmp9_, (glong) string_index_of_nth_char (_tmp10_, (glong) start), (glong) string_index_of_nth_char (_tmp11_, (glong) end));
		_tmp13_ = _tmp12_;
		g_string_prepend (_tmp8_, _tmp13_);
		_g_free0 (_tmp13_);
		_g_free0 (text);
	}
}

static void
components_entry_undo_on_undo (ComponentsEntryUndo* self)
{
	g_return_if_fail (COMPONENTS_IS_ENTRY_UNDO (self));
	components_entry_undo_do_undo (self);
}

static void
components_entry_undo_on_redo (ComponentsEntryUndo* self)
{
	g_return_if_fail (COMPONENTS_IS_ENTRY_UNDO (self));
	components_entry_undo_do_redo (self);
}

static inline gpointer
components_entry_undo_edit_command_get_instance_private (ComponentsEntryUndoEditCommand* self)
{
	return G_STRUCT_MEMBER_P (self, ComponentsEntryUndoEditCommand_private_offset);
}

static ComponentsEntryUndoEditCommand*
components_entry_undo_edit_command_construct (GType object_type,
                                              ComponentsEntryUndo* manager,
                                              ComponentsEntryUndoEditType edit,
                                              gint position,
                                              const gchar* text)
{
	ComponentsEntryUndoEditCommand * self = NULL;
	gchar* _tmp0_;
	g_return_val_if_fail (COMPONENTS_IS_ENTRY_UNDO (manager), NULL);
	g_return_val_if_fail (text != NULL, NULL);
	self = (ComponentsEntryUndoEditCommand*) application_command_construct (object_type);
	self->priv->manager = manager;
	self->priv->edit = edit;
	self->priv->position = position;
	_tmp0_ = g_strdup (text);
	_g_free0 (self->priv->text);
	self->priv->text = _tmp0_;
	return self;
}

static ComponentsEntryUndoEditCommand*
components_entry_undo_edit_command_new (ComponentsEntryUndo* manager,
                                        ComponentsEntryUndoEditType edit,
                                        gint position,
                                        const gchar* text)
{
	return components_entry_undo_edit_command_construct (COMPONENTS_ENTRY_UNDO_TYPE_EDIT_COMMAND, manager, edit, position, text);
}

static void
components_entry_undo_edit_command_real_execute_data_free (gpointer _data)
{
	ComponentsEntryUndoEditCommandExecuteData* _data_;
	_data_ = _data;
	_g_object_unref0 (_data_->cancellable);
	_g_object_unref0 (_data_->self);
	g_slice_free (ComponentsEntryUndoEditCommandExecuteData, _data_);
}

static void
components_entry_undo_edit_command_real_execute (ApplicationCommand* base,
                                                 GCancellable* cancellable,
                                                 GAsyncReadyCallback _callback_,
                                                 gpointer _user_data_)
{
	ComponentsEntryUndoEditCommand * self;
	ComponentsEntryUndoEditCommandExecuteData* _data_;
	ComponentsEntryUndoEditCommand* _tmp0_;
	GCancellable* _tmp1_;
	g_return_if_fail ((cancellable == NULL) || G_TYPE_CHECK_INSTANCE_TYPE (cancellable, g_cancellable_get_type ()));
	self = G_TYPE_CHECK_INSTANCE_CAST (base, COMPONENTS_ENTRY_UNDO_TYPE_EDIT_COMMAND, ComponentsEntryUndoEditCommand);
	_data_ = g_slice_new0 (ComponentsEntryUndoEditCommandExecuteData);
	_data_->_async_result = g_task_new (G_OBJECT (self), cancellable, _callback_, _user_data_);
	g_task_set_task_data (_data_->_async_result, _data_, components_entry_undo_edit_command_real_execute_data_free);
	_tmp0_ = _g_object_ref0 (self);
	_data_->self = _tmp0_;
	_tmp1_ = _g_object_ref0 (cancellable);
	_g_object_unref0 (_data_->cancellable);
	_data_->cancellable = _tmp1_;
	components_entry_undo_edit_command_real_execute_co (_data_);
}

static void
components_entry_undo_edit_command_execute_finish (ApplicationCommand* base,
                                                   GAsyncResult* _res_,
                                                   GError** error)
{
	ComponentsEntryUndoEditCommandExecuteData* _data_;
	_data_ = g_task_propagate_pointer (G_TASK (_res_), error);
	if (NULL == _data_) {
		return;
	}
}

static gboolean
components_entry_undo_edit_command_real_execute_co (ComponentsEntryUndoEditCommandExecuteData* _data_)
{
	switch (_data_->_state_) {
		case 0:
		goto _state_0;
		default:
		g_assert_not_reached ();
	}
	_state_0:
	g_task_return_pointer (_data_->_async_result, _data_, NULL);
	if (_data_->_state_ != 0) {
		while (!g_task_get_completed (_data_->_async_result)) {
			g_main_context_iteration (g_task_get_context (_data_->_async_result), TRUE);
		}
	}
	g_object_unref (_data_->_async_result);
	return FALSE;
}

static void
components_entry_undo_edit_command_real_undo_data_free (gpointer _data)
{
	ComponentsEntryUndoEditCommandUndoData* _data_;
	_data_ = _data;
	_g_object_unref0 (_data_->cancellable);
	_g_object_unref0 (_data_->self);
	g_slice_free (ComponentsEntryUndoEditCommandUndoData, _data_);
}

static void
components_entry_undo_edit_command_real_undo (ApplicationCommand* base,
                                              GCancellable* cancellable,
                                              GAsyncReadyCallback _callback_,
                                              gpointer _user_data_)
{
	ComponentsEntryUndoEditCommand * self;
	ComponentsEntryUndoEditCommandUndoData* _data_;
	ComponentsEntryUndoEditCommand* _tmp0_;
	GCancellable* _tmp1_;
	g_return_if_fail ((cancellable == NULL) || G_TYPE_CHECK_INSTANCE_TYPE (cancellable, g_cancellable_get_type ()));
	self = G_TYPE_CHECK_INSTANCE_CAST (base, COMPONENTS_ENTRY_UNDO_TYPE_EDIT_COMMAND, ComponentsEntryUndoEditCommand);
	_data_ = g_slice_new0 (ComponentsEntryUndoEditCommandUndoData);
	_data_->_async_result = g_task_new (G_OBJECT (self), cancellable, _callback_, _user_data_);
	g_task_set_task_data (_data_->_async_result, _data_, components_entry_undo_edit_command_real_undo_data_free);
	_tmp0_ = _g_object_ref0 (self);
	_data_->self = _tmp0_;
	_tmp1_ = _g_object_ref0 (cancellable);
	_g_object_unref0 (_data_->cancellable);
	_data_->cancellable = _tmp1_;
	components_entry_undo_edit_command_real_undo_co (_data_);
}

static void
components_entry_undo_edit_command_undo_finish (ApplicationCommand* base,
                                                GAsyncResult* _res_,
                                                GError** error)
{
	ComponentsEntryUndoEditCommandUndoData* _data_;
	_data_ = g_task_propagate_pointer (G_TASK (_res_), error);
	if (NULL == _data_) {
		return;
	}
}

static gboolean
components_entry_undo_edit_command_real_undo_co (ComponentsEntryUndoEditCommandUndoData* _data_)
{
	switch (_data_->_state_) {
		case 0:
		goto _state_0;
		default:
		g_assert_not_reached ();
	}
	_state_0:
	_data_->_tmp0_ = _data_->self->priv->manager;
	_data_->_tmp1_ = _g_object_ref0 (_data_->_tmp0_);
	_data_->manager = _data_->_tmp1_;
	_data_->_tmp2_ = _data_->manager;
	if (_data_->_tmp2_ != NULL) {
		_data_->_tmp3_ = _data_->manager;
		_data_->_tmp3_->priv->events_enabled = FALSE;
		switch (_data_->self->priv->edit) {
			case COMPONENTS_ENTRY_UNDO_EDIT_TYPE_INSERT:
			{
				_data_->_tmp4_ = _data_->manager;
				_data_->_tmp5_ = components_entry_undo_get_target (_data_->_tmp4_);
				_data_->_tmp6_ = _data_->_tmp5_;
				components_entry_undo_edit_command_do_delete (_data_->self, _data_->_tmp6_);
				break;
			}
			case COMPONENTS_ENTRY_UNDO_EDIT_TYPE_DELETE:
			{
				_data_->_tmp7_ = _data_->manager;
				_data_->_tmp8_ = components_entry_undo_get_target (_data_->_tmp7_);
				_data_->_tmp9_ = _data_->_tmp8_;
				components_entry_undo_edit_command_do_insert (_data_->self, _data_->_tmp9_);
				break;
			}
			case COMPONENTS_ENTRY_UNDO_EDIT_TYPE_NONE:
			{
				break;
			}
			default:
			break;
		}
		_data_->_tmp10_ = _data_->manager;
		_data_->_tmp10_->priv->events_enabled = TRUE;
	}
	_g_object_unref0 (_data_->manager);
	g_task_return_pointer (_data_->_async_result, _data_, NULL);
	if (_data_->_state_ != 0) {
		while (!g_task_get_completed (_data_->_async_result)) {
			g_main_context_iteration (g_task_get_context (_data_->_async_result), TRUE);
		}
	}
	g_object_unref (_data_->_async_result);
	return FALSE;
}

static void
components_entry_undo_edit_command_real_redo_data_free (gpointer _data)
{
	ComponentsEntryUndoEditCommandRedoData* _data_;
	_data_ = _data;
	_g_object_unref0 (_data_->cancellable);
	_g_object_unref0 (_data_->self);
	g_slice_free (ComponentsEntryUndoEditCommandRedoData, _data_);
}

static void
components_entry_undo_edit_command_real_redo (ApplicationCommand* base,
                                              GCancellable* cancellable,
                                              GAsyncReadyCallback _callback_,
                                              gpointer _user_data_)
{
	ComponentsEntryUndoEditCommand * self;
	ComponentsEntryUndoEditCommandRedoData* _data_;
	ComponentsEntryUndoEditCommand* _tmp0_;
	GCancellable* _tmp1_;
	g_return_if_fail ((cancellable == NULL) || G_TYPE_CHECK_INSTANCE_TYPE (cancellable, g_cancellable_get_type ()));
	self = G_TYPE_CHECK_INSTANCE_CAST (base, COMPONENTS_ENTRY_UNDO_TYPE_EDIT_COMMAND, ComponentsEntryUndoEditCommand);
	_data_ = g_slice_new0 (ComponentsEntryUndoEditCommandRedoData);
	_data_->_async_result = g_task_new (G_OBJECT (self), cancellable, _callback_, _user_data_);
	g_task_set_task_data (_data_->_async_result, _data_, components_entry_undo_edit_command_real_redo_data_free);
	_tmp0_ = _g_object_ref0 (self);
	_data_->self = _tmp0_;
	_tmp1_ = _g_object_ref0 (cancellable);
	_g_object_unref0 (_data_->cancellable);
	_data_->cancellable = _tmp1_;
	components_entry_undo_edit_command_real_redo_co (_data_);
}

static void
components_entry_undo_edit_command_redo_finish (ApplicationCommand* base,
                                                GAsyncResult* _res_,
                                                GError** error)
{
	ComponentsEntryUndoEditCommandRedoData* _data_;
	_data_ = g_task_propagate_pointer (G_TASK (_res_), error);
	if (NULL == _data_) {
		return;
	}
}

static gboolean
components_entry_undo_edit_command_real_redo_co (ComponentsEntryUndoEditCommandRedoData* _data_)
{
	switch (_data_->_state_) {
		case 0:
		goto _state_0;
		default:
		g_assert_not_reached ();
	}
	_state_0:
	_data_->_tmp0_ = _data_->self->priv->manager;
	_data_->_tmp1_ = _g_object_ref0 (_data_->_tmp0_);
	_data_->manager = _data_->_tmp1_;
	_data_->_tmp2_ = _data_->manager;
	if (_data_->_tmp2_ != NULL) {
		_data_->_tmp3_ = _data_->manager;
		_data_->_tmp3_->priv->events_enabled = FALSE;
		switch (_data_->self->priv->edit) {
			case COMPONENTS_ENTRY_UNDO_EDIT_TYPE_INSERT:
			{
				_data_->_tmp4_ = _data_->manager;
				_data_->_tmp5_ = components_entry_undo_get_target (_data_->_tmp4_);
				_data_->_tmp6_ = _data_->_tmp5_;
				components_entry_undo_edit_command_do_insert (_data_->self, _data_->_tmp6_);
				break;
			}
			case COMPONENTS_ENTRY_UNDO_EDIT_TYPE_DELETE:
			{
				_data_->_tmp7_ = _data_->manager;
				_data_->_tmp8_ = components_entry_undo_get_target (_data_->_tmp7_);
				_data_->_tmp9_ = _data_->_tmp8_;
				components_entry_undo_edit_command_do_delete (_data_->self, _data_->_tmp9_);
				break;
			}
			case COMPONENTS_ENTRY_UNDO_EDIT_TYPE_NONE:
			{
				break;
			}
			default:
			break;
		}
		_data_->_tmp10_ = _data_->manager;
		_data_->_tmp10_->priv->events_enabled = TRUE;
	}
	_g_object_unref0 (_data_->manager);
	g_task_return_pointer (_data_->_async_result, _data_, NULL);
	if (_data_->_state_ != 0) {
		while (!g_task_get_completed (_data_->_async_result)) {
			g_main_context_iteration (g_task_get_context (_data_->_async_result), TRUE);
		}
	}
	g_object_unref (_data_->_async_result);
	return FALSE;
}

static void
components_entry_undo_edit_command_do_insert (ComponentsEntryUndoEditCommand* self,
                                              GtkEntry* target)
{
	gint position = 0;
	const gchar* _tmp0_;
	g_return_if_fail (COMPONENTS_ENTRY_UNDO_IS_EDIT_COMMAND (self));
	g_return_if_fail (G_TYPE_CHECK_INSTANCE_TYPE (target, gtk_entry_get_type ()));
	position = self->priv->position;
	_tmp0_ = self->priv->text;
	g_signal_emit_by_name (G_TYPE_CHECK_INSTANCE_CAST (target, gtk_editable_get_type (), GtkEditable), "insert-text", _tmp0_, -1, &position);
	gtk_editable_set_position (G_TYPE_CHECK_INSTANCE_CAST (target, gtk_editable_get_type (), GtkEditable), position);
}

static void
components_entry_undo_edit_command_do_delete (ComponentsEntryUndoEditCommand* self,
                                              GtkEntry* target)
{
	const gchar* _tmp0_;
	g_return_if_fail (COMPONENTS_ENTRY_UNDO_IS_EDIT_COMMAND (self));
	g_return_if_fail (G_TYPE_CHECK_INSTANCE_TYPE (target, gtk_entry_get_type ()));
	_tmp0_ = self->priv->text;
	g_signal_emit_by_name (G_TYPE_CHECK_INSTANCE_CAST (target, gtk_editable_get_type (), GtkEditable), "delete-text", self->priv->position, self->priv->position + g_utf8_strlen (_tmp0_, (gssize) -1));
}

static void
components_entry_undo_edit_command_class_init (ComponentsEntryUndoEditCommandClass * klass,
                                               gpointer klass_data)
{
	components_entry_undo_edit_command_parent_class = g_type_class_peek_parent (klass);
	g_type_class_adjust_private_offset (klass, &ComponentsEntryUndoEditCommand_private_offset);
	((ApplicationCommandClass *) klass)->execute = (void (*) (ApplicationCommand*, GCancellable*, GAsyncReadyCallback, gpointer)) components_entry_undo_edit_command_real_execute;
	((ApplicationCommandClass *) klass)->execute_finish = (void (*) (ApplicationCommand*, GAsyncResult*, GError**)) components_entry_undo_edit_command_execute_finish;
	((ApplicationCommandClass *) klass)->undo = (void (*) (ApplicationCommand*, GCancellable*, GAsyncReadyCallback, gpointer)) components_entry_undo_edit_command_real_undo;
	((ApplicationCommandClass *) klass)->undo_finish = (void (*) (ApplicationCommand*, GAsyncResult*, GError**)) components_entry_undo_edit_command_undo_finish;
	((ApplicationCommandClass *) klass)->redo = (void (*) (ApplicationCommand*, GCancellable*, GAsyncReadyCallback, gpointer)) components_entry_undo_edit_command_real_redo;
	((ApplicationCommandClass *) klass)->redo_finish = (void (*) (ApplicationCommand*, GAsyncResult*, GError**)) components_entry_undo_edit_command_redo_finish;
	G_OBJECT_CLASS (klass)->finalize = components_entry_undo_edit_command_finalize;
}

static void
components_entry_undo_edit_command_instance_init (ComponentsEntryUndoEditCommand * self,
                                                  gpointer klass)
{
	self->priv = components_entry_undo_edit_command_get_instance_private (self);
}

static void
components_entry_undo_edit_command_finalize (GObject * obj)
{
	ComponentsEntryUndoEditCommand * self;
	self = G_TYPE_CHECK_INSTANCE_CAST (obj, COMPONENTS_ENTRY_UNDO_TYPE_EDIT_COMMAND, ComponentsEntryUndoEditCommand);
	_g_free0 (self->priv->text);
	G_OBJECT_CLASS (components_entry_undo_edit_command_parent_class)->finalize (obj);
}

static GType
components_entry_undo_edit_command_get_type_once (void)
{
	static const GTypeInfo g_define_type_info = { sizeof (ComponentsEntryUndoEditCommandClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) components_entry_undo_edit_command_class_init, (GClassFinalizeFunc) NULL, NULL, sizeof (ComponentsEntryUndoEditCommand), 0, (GInstanceInitFunc) components_entry_undo_edit_command_instance_init, NULL };
	GType components_entry_undo_edit_command_type_id;
	components_entry_undo_edit_command_type_id = g_type_register_static (APPLICATION_TYPE_COMMAND, "ComponentsEntryUndoEditCommand", &g_define_type_info, 0);
	ComponentsEntryUndoEditCommand_private_offset = g_type_add_instance_private (components_entry_undo_edit_command_type_id, sizeof (ComponentsEntryUndoEditCommandPrivate));
	return components_entry_undo_edit_command_type_id;
}

static GType
components_entry_undo_edit_command_get_type (void)
{
	static volatile gsize components_entry_undo_edit_command_type_id__once = 0;
	if (g_once_init_enter (&components_entry_undo_edit_command_type_id__once)) {
		GType components_entry_undo_edit_command_type_id;
		components_entry_undo_edit_command_type_id = components_entry_undo_edit_command_get_type_once ();
		g_once_init_leave (&components_entry_undo_edit_command_type_id__once, components_entry_undo_edit_command_type_id);
	}
	return components_entry_undo_edit_command_type_id__once;
}

static void
components_entry_undo_class_init (ComponentsEntryUndoClass * klass,
                                  gpointer klass_data)
{
	components_entry_undo_parent_class = g_type_class_peek_parent (klass);
	g_type_class_adjust_private_offset (klass, &ComponentsEntryUndo_private_offset);
	G_OBJECT_CLASS (klass)->get_property = _vala_components_entry_undo_get_property;
	G_OBJECT_CLASS (klass)->set_property = _vala_components_entry_undo_set_property;
	G_OBJECT_CLASS (klass)->finalize = components_entry_undo_finalize;
	/** The entry being managed */
	g_object_class_install_property (G_OBJECT_CLASS (klass), COMPONENTS_ENTRY_UNDO_TARGET_PROPERTY, components_entry_undo_properties[COMPONENTS_ENTRY_UNDO_TARGET_PROPERTY] = g_param_spec_object ("target", "target", "target", gtk_entry_get_type (), G_PARAM_STATIC_STRINGS | G_PARAM_READABLE));
}

static void
components_entry_undo_instance_init (ComponentsEntryUndo * self,
                                     gpointer klass)
{
	GString* _tmp0_;
	GSimpleActionGroup* _tmp1_;
	self->priv = components_entry_undo_get_instance_private (self);
	self->priv->last_edit = COMPONENTS_ENTRY_UNDO_EDIT_TYPE_NONE;
	self->priv->edit_start = 0;
	self->priv->edit_end = 0;
	_tmp0_ = g_string_new ("");
	self->priv->edit_accumuluator = _tmp0_;
	self->priv->events_enabled = TRUE;
	_tmp1_ = g_simple_action_group_new ();
	self->priv->edit_actions = _tmp1_;
}

static void
components_entry_undo_finalize (GObject * obj)
{
	ComponentsEntryUndo * self;
	GtkEntry* _tmp0_;
	guint _tmp1_;
	GtkEntry* _tmp2_;
	guint _tmp3_;
	self = G_TYPE_CHECK_INSTANCE_CAST (obj, COMPONENTS_TYPE_ENTRY_UNDO, ComponentsEntryUndo);
	_tmp0_ = self->priv->_target;
	g_signal_parse_name ("insert-text", gtk_editable_get_type (), &_tmp1_, NULL, FALSE);
	g_signal_handlers_disconnect_matched (G_TYPE_CHECK_INSTANCE_CAST (_tmp0_, gtk_editable_get_type (), GtkEditable), G_SIGNAL_MATCH_ID | G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA, _tmp1_, 0, NULL, (GCallback) _components_entry_undo_on_inserted_gtk_editable_insert_text, self);
	_tmp2_ = self->priv->_target;
	g_signal_parse_name ("delete-text", gtk_editable_get_type (), &_tmp3_, NULL, FALSE);
	g_signal_handlers_disconnect_matched (G_TYPE_CHECK_INSTANCE_CAST (_tmp2_, gtk_editable_get_type (), GtkEditable), G_SIGNAL_MATCH_ID | G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA, _tmp3_, 0, NULL, (GCallback) _components_entry_undo_on_deleted_gtk_editable_delete_text, self);
	_g_object_unref0 (self->priv->_target);
	_g_object_unref0 (self->priv->commands);
	_g_string_free0 (self->priv->edit_accumuluator);
	_g_object_unref0 (self->priv->edit_actions);
	G_OBJECT_CLASS (components_entry_undo_parent_class)->finalize (obj);
}

/**
 * Provides per-GTK Entry undo and redo using a command stack.
 */
static GType
components_entry_undo_get_type_once (void)
{
	static const GTypeInfo g_define_type_info = { sizeof (ComponentsEntryUndoClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) components_entry_undo_class_init, (GClassFinalizeFunc) NULL, NULL, sizeof (ComponentsEntryUndo), 0, (GInstanceInitFunc) components_entry_undo_instance_init, NULL };
	GType components_entry_undo_type_id;
	components_entry_undo_type_id = g_type_register_static (GEARY_TYPE_BASE_OBJECT, "ComponentsEntryUndo", &g_define_type_info, 0);
	ComponentsEntryUndo_private_offset = g_type_add_instance_private (components_entry_undo_type_id, sizeof (ComponentsEntryUndoPrivate));
	return components_entry_undo_type_id;
}

GType
components_entry_undo_get_type (void)
{
	static volatile gsize components_entry_undo_type_id__once = 0;
	if (g_once_init_enter (&components_entry_undo_type_id__once)) {
		GType components_entry_undo_type_id;
		components_entry_undo_type_id = components_entry_undo_get_type_once ();
		g_once_init_leave (&components_entry_undo_type_id__once, components_entry_undo_type_id);
	}
	return components_entry_undo_type_id__once;
}

static void
_vala_components_entry_undo_get_property (GObject * object,
                                          guint property_id,
                                          GValue * value,
                                          GParamSpec * pspec)
{
	ComponentsEntryUndo * self;
	self = G_TYPE_CHECK_INSTANCE_CAST (object, COMPONENTS_TYPE_ENTRY_UNDO, ComponentsEntryUndo);
	switch (property_id) {
		case COMPONENTS_ENTRY_UNDO_TARGET_PROPERTY:
		g_value_set_object (value, components_entry_undo_get_target (self));
		break;
		default:
		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
		break;
	}
}

static void
_vala_components_entry_undo_set_property (GObject * object,
                                          guint property_id,
                                          const GValue * value,
                                          GParamSpec * pspec)
{
	ComponentsEntryUndo * self;
	self = G_TYPE_CHECK_INSTANCE_CAST (object, COMPONENTS_TYPE_ENTRY_UNDO, ComponentsEntryUndo);
	switch (property_id) {
		case COMPONENTS_ENTRY_UNDO_TARGET_PROPERTY:
		components_entry_undo_set_target (self, g_value_get_object (value));
		break;
		default:
		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
		break;
	}
}

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

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

