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

/*
 * Copyright 2016 Software Freedom Conservancy Inc.
 * 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 <stdlib.h>
#include <string.h>
#include <glib.h>
#include <gee.h>
#include <glib-object.h>
#include <gio/gio.h>
#include <gtk/gtk.h>
#include "geary-engine.h"

#define CONTACT_ENTRY_COMPLETION_VISIBILITY_THRESHOLD GEARY_CONTACT_IMPORTANCE_RECEIVED_FROM

enum  {
	CONTACT_ENTRY_COMPLETION_0_PROPERTY,
	CONTACT_ENTRY_COMPLETION_NUM_PROPERTIES
};
static GParamSpec* contact_entry_completion_properties[CONTACT_ENTRY_COMPLETION_NUM_PROPERTIES];
#define _g_object_unref0(var) ((var == NULL) ? NULL : (var = (g_object_unref (var), NULL)))
#define _g_free0(var) (var = (g_free (var), NULL))
#define __vala_GtkTreeIter_free0(var) ((var == NULL) ? NULL : (var = (_vala_GtkTreeIter_free (var), NULL)))
#define _g_error_free0(var) ((var == NULL) ? NULL : (var = (g_error_free (var), NULL)))
typedef struct _ContactEntryCompletionSearchContactsData ContactEntryCompletionSearchContactsData;
#define _g_regex_unref0(var) ((var == NULL) ? NULL : (var = (g_regex_unref (var), NULL)))

struct _ContactEntryCompletionPrivate {
	ApplicationContactStore* contacts;
	gchar* current_key;
	GeeArrayList* address_parts;
	gint cursor_at_address;
	GCancellable* search_cancellable;
	GtkTreeIter* last_iter;
};

struct _ContactEntryCompletionSearchContactsData {
	int _state_;
	GObject* _source_object_;
	GAsyncResult* _res_;
	GTask* _async_result;
	ContactEntryCompletion* self;
	gchar* query;
	GCancellable* cancellable;
	GeeCollection* results;
	GeeCollection* _tmp0_;
	ApplicationContactStore* _tmp1_;
	GeeCollection* _tmp2_;
	GeeCollection* _tmp3_;
	GError* err;
	GError* _tmp4_;
	const gchar* _tmp5_;
	GtkListStore* model;
	GtkListStore* _tmp6_;
	GeeIterator* _contact_it;
	GeeCollection* _tmp7_;
	GeeIterator* _tmp8_;
	GeeIterator* _tmp9_;
	ApplicationContact* contact;
	GeeIterator* _tmp10_;
	gpointer _tmp11_;
	GeeIterator* _addr_it;
	ApplicationContact* _tmp12_;
	GeeCollection* _tmp13_;
	GeeCollection* _tmp14_;
	GeeIterator* _tmp15_;
	GeeIterator* _tmp16_;
	GearyRFC822MailboxAddress* addr;
	GeeIterator* _tmp17_;
	gpointer _tmp18_;
	GtkTreeIter iter;
	GtkListStore* _tmp19_;
	GtkTreeIter _tmp20_;
	GtkListStore* _tmp21_;
	GtkTreeIter _tmp22_;
	ApplicationContact* _tmp23_;
	GtkListStore* _tmp24_;
	GtkTreeIter _tmp25_;
	GearyRFC822MailboxAddress* _tmp26_;
	GtkListStore* _tmp27_;
	GError* _inner_error0_;
};

static gint ContactEntryCompletion_private_offset;
static gpointer contact_entry_completion_parent_class = NULL;
static GearyBaseInterfaceIface * contact_entry_completion_geary_base_interface_parent_iface = NULL;

static void _vala_GtkTreeIter_free (GtkTreeIter* self);
static inline GtkListStore* contact_entry_completion_new_model (ContactEntryCompletion* self);
static gboolean __lambda27_ (ContactEntryCompletion* self);
static gboolean ___lambda27__gtk_entry_completion_match_func (GtkEntryCompletion* completion,
                                                       const gchar* key,
                                                       GtkTreeIter* iter,
                                                       gpointer self);
static void contact_entry_completion_cell_icon_data (ContactEntryCompletion* self,
                                              GtkCellLayout* cell_layout,
                                              GtkCellRenderer* cell,
                                              GtkTreeModel* tree_model,
                                              GtkTreeIter* iter);
static void _contact_entry_completion_cell_icon_data_gtk_cell_layout_data_func (GtkCellLayout* cell_layout,
                                                                         GtkCellRenderer* cell,
                                                                         GtkTreeModel* tree_model,
                                                                         GtkTreeIter* iter,
                                                                         gpointer self);
static void contact_entry_completion_cell_text_data (ContactEntryCompletion* self,
                                              GtkCellLayout* cell_layout,
                                              GtkCellRenderer* cell,
                                              GtkTreeModel* tree_model,
                                              GtkTreeIter* iter);
static void _contact_entry_completion_cell_text_data_gtk_cell_layout_data_func (GtkCellLayout* cell_layout,
                                                                         GtkCellRenderer* cell,
                                                                         GtkTreeModel* tree_model,
                                                                         GtkTreeIter* iter,
                                                                         gpointer self);
static gboolean contact_entry_completion_on_match_selected (ContactEntryCompletion* self,
                                                     GtkTreeModel* model,
                                                     GtkTreeIter* iter);
static gboolean _contact_entry_completion_on_match_selected_gtk_entry_completion_match_selected (GtkEntryCompletion* _sender,
                                                                                          GtkTreeModel* model,
                                                                                          GtkTreeIter* iter,
                                                                                          gpointer self);
static gboolean contact_entry_completion_on_cursor_on_match (ContactEntryCompletion* self,
                                                      GtkTreeModel* model,
                                                      GtkTreeIter* iter);
static gboolean _contact_entry_completion_on_cursor_on_match_gtk_entry_completion_cursor_on_match (GtkEntryCompletion* _sender,
                                                                                            GtkTreeModel* model,
                                                                                            GtkTreeIter* iter,
                                                                                            gpointer self);
static void contact_entry_completion_update_addresses (ContactEntryCompletion* self);
static void contact_entry_completion_search_contacts (ContactEntryCompletion* self,
                                               const gchar* query,
                                               GCancellable* cancellable,
                                               GAsyncReadyCallback _callback_,
                                               gpointer _user_data_);
static void contact_entry_completion_search_contacts_finish (ContactEntryCompletion* self,
                                                      GAsyncResult* _res_);
static void contact_entry_completion_insert_address_at_cursor (ContactEntryCompletion* self,
                                                        GtkTreeIter* iter);
static gint ____lambda28_ (ContactEntryCompletion* self,
                    gchar* a,
                    gint chars);
static gpointer _____lambda28__gee_fold_func (gpointer g,
                                       gpointer a,
                                       gpointer self);
static void contact_entry_completion_search_contacts_data_free (gpointer _data);
static gboolean contact_entry_completion_search_contacts_co (ContactEntryCompletionSearchContactsData* _data_);
static void contact_entry_completion_search_contacts_ready (GObject* source_object,
                                                     GAsyncResult* _res_,
                                                     gpointer _user_data_);
static gchar* contact_entry_completion_match_prefix_contact (ContactEntryCompletion* self,
                                                      GearyRFC822MailboxAddress* mailbox);
static gchar* contact_entry_completion_match_prefix_string (ContactEntryCompletion* self,
                                                     const gchar* haystack);
static gboolean contact_entry_completion_eval_callback (ContactEntryCompletion* self,
                                                 GMatchInfo* match_info,
                                                 GString* _result_);
static gboolean _contact_entry_completion_eval_callback_gregex_eval_callback (GMatchInfo* match_info,
                                                                       GString* _result_,
                                                                       gpointer self);
static GtkTreeIter* _vala_GtkTreeIter_copy (GtkTreeIter* self);
static void contact_entry_completion_finalize (GObject * obj);
static GType contact_entry_completion_get_type_once (void);

static inline gpointer
contact_entry_completion_get_instance_private (ContactEntryCompletion* self)
{
	return G_STRUCT_MEMBER_P (self, ContactEntryCompletion_private_offset);
}

GType*
contact_entry_completion_column_get_types (gint* result_length1)
{
	GType* _tmp0_;
	GType* _tmp1_;
	gint _tmp1__length1;
	GType* result;
	_tmp0_ = g_new0 (GType, 2);
	_tmp0_[0] = APPLICATION_TYPE_CONTACT;
	_tmp0_[1] = GEARY_RF_C822_TYPE_MAILBOX_ADDRESS;
	_tmp1_ = _tmp0_;
	_tmp1__length1 = 2;
	if (result_length1) {
		*result_length1 = _tmp1__length1;
	}
	result = _tmp1_;
	return result;
}

static GType
contact_entry_completion_column_get_type_once (void)
{
	static const GEnumValue values[] = {{CONTACT_ENTRY_COMPLETION_COLUMN_CONTACT, "CONTACT_ENTRY_COMPLETION_COLUMN_CONTACT", "contact"}, {CONTACT_ENTRY_COMPLETION_COLUMN_MAILBOX, "CONTACT_ENTRY_COMPLETION_COLUMN_MAILBOX", "mailbox"}, {0, NULL, NULL}};
	GType contact_entry_completion_column_type_id;
	contact_entry_completion_column_type_id = g_enum_register_static ("ContactEntryCompletionColumn", values);
	return contact_entry_completion_column_type_id;
}

GType
contact_entry_completion_column_get_type (void)
{
	static volatile gsize contact_entry_completion_column_type_id__once = 0;
	if (g_once_init_enter (&contact_entry_completion_column_type_id__once)) {
		GType contact_entry_completion_column_type_id;
		contact_entry_completion_column_type_id = contact_entry_completion_column_get_type_once ();
		g_once_init_leave (&contact_entry_completion_column_type_id__once, contact_entry_completion_column_type_id);
	}
	return contact_entry_completion_column_type_id__once;
}

static void
_vala_GtkTreeIter_free (GtkTreeIter* self)
{
	g_boxed_free (gtk_tree_iter_get_type (), self);
}

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

static gboolean
__lambda27_ (ContactEntryCompletion* self)
{
	gboolean result;
	result = TRUE;
	return result;
}

static gboolean
___lambda27__gtk_entry_completion_match_func (GtkEntryCompletion* completion,
                                              const gchar* key,
                                              GtkTreeIter* iter,
                                              gpointer self)
{
	gboolean result;
	result = __lambda27_ ((ContactEntryCompletion*) self);
	return result;
}

static void
_contact_entry_completion_cell_icon_data_gtk_cell_layout_data_func (GtkCellLayout* cell_layout,
                                                                    GtkCellRenderer* cell,
                                                                    GtkTreeModel* tree_model,
                                                                    GtkTreeIter* iter,
                                                                    gpointer self)
{
	contact_entry_completion_cell_icon_data ((ContactEntryCompletion*) self, cell_layout, cell, tree_model, iter);
}

static void
_contact_entry_completion_cell_text_data_gtk_cell_layout_data_func (GtkCellLayout* cell_layout,
                                                                    GtkCellRenderer* cell,
                                                                    GtkTreeModel* tree_model,
                                                                    GtkTreeIter* iter,
                                                                    gpointer self)
{
	contact_entry_completion_cell_text_data ((ContactEntryCompletion*) self, cell_layout, cell, tree_model, iter);
}

static gboolean
_contact_entry_completion_on_match_selected_gtk_entry_completion_match_selected (GtkEntryCompletion* _sender,
                                                                                 GtkTreeModel* model,
                                                                                 GtkTreeIter* iter,
                                                                                 gpointer self)
{
	gboolean result;
	result = contact_entry_completion_on_match_selected ((ContactEntryCompletion*) self, model, iter);
	return result;
}

static gboolean
_contact_entry_completion_on_cursor_on_match_gtk_entry_completion_cursor_on_match (GtkEntryCompletion* _sender,
                                                                                   GtkTreeModel* model,
                                                                                   GtkTreeIter* iter,
                                                                                   gpointer self)
{
	gboolean result;
	result = contact_entry_completion_on_cursor_on_match ((ContactEntryCompletion*) self, model, iter);
	return result;
}

ContactEntryCompletion*
contact_entry_completion_construct (GType object_type,
                                    ApplicationContactStore* contacts)
{
	ContactEntryCompletion * self = NULL;
	ApplicationContactStore* _tmp0_;
	GtkListStore* _tmp1_;
	GtkListStore* _tmp2_;
	GtkCellRendererPixbuf* icon_renderer = NULL;
	GtkCellRendererPixbuf* _tmp3_;
	GtkCellRendererText* text_renderer = NULL;
	GtkCellRendererText* _tmp4_;
	g_return_val_if_fail (APPLICATION_IS_CONTACT_STORE (contacts), NULL);
	self = (ContactEntryCompletion*) g_object_new (object_type, NULL);
	geary_base_interface_base_ref (G_TYPE_CHECK_INSTANCE_CAST (self, GEARY_TYPE_BASE_INTERFACE, GearyBaseInterface));
	_tmp0_ = _g_object_ref0 (contacts);
	_g_object_unref0 (self->priv->contacts);
	self->priv->contacts = _tmp0_;
	_tmp1_ = contact_entry_completion_new_model (self);
	_tmp2_ = _tmp1_;
	gtk_entry_completion_set_model (G_TYPE_CHECK_INSTANCE_CAST (self, gtk_entry_completion_get_type (), GtkEntryCompletion), G_TYPE_CHECK_INSTANCE_CAST (_tmp2_, gtk_tree_model_get_type (), GtkTreeModel));
	_g_object_unref0 (_tmp2_);
	gtk_entry_completion_set_match_func (G_TYPE_CHECK_INSTANCE_CAST (self, gtk_entry_completion_get_type (), GtkEntryCompletion), ___lambda27__gtk_entry_completion_match_func, g_object_ref (self), g_object_unref);
	_tmp3_ = (GtkCellRendererPixbuf*) gtk_cell_renderer_pixbuf_new ();
	g_object_ref_sink (_tmp3_);
	icon_renderer = _tmp3_;
	g_object_set (G_TYPE_CHECK_INSTANCE_CAST (icon_renderer, gtk_cell_renderer_get_type (), GtkCellRenderer), "xpad", (guint) 2, NULL);
	g_object_set (G_TYPE_CHECK_INSTANCE_CAST (icon_renderer, gtk_cell_renderer_get_type (), GtkCellRenderer), "ypad", (guint) 2, NULL);
	gtk_cell_layout_pack_start (G_TYPE_CHECK_INSTANCE_CAST (self, gtk_cell_layout_get_type (), GtkCellLayout), G_TYPE_CHECK_INSTANCE_CAST (icon_renderer, gtk_cell_renderer_get_type (), GtkCellRenderer), FALSE);
	gtk_cell_layout_set_cell_data_func (G_TYPE_CHECK_INSTANCE_CAST (self, gtk_cell_layout_get_type (), GtkCellLayout), G_TYPE_CHECK_INSTANCE_CAST (icon_renderer, gtk_cell_renderer_get_type (), GtkCellRenderer), _contact_entry_completion_cell_icon_data_gtk_cell_layout_data_func, g_object_ref (self), g_object_unref);
	_tmp4_ = (GtkCellRendererText*) gtk_cell_renderer_text_new ();
	g_object_ref_sink (_tmp4_);
	text_renderer = _tmp4_;
	g_object_set (G_TYPE_CHECK_INSTANCE_CAST (icon_renderer, gtk_cell_renderer_get_type (), GtkCellRenderer), "ypad", (guint) 2, NULL);
	gtk_cell_layout_pack_start (G_TYPE_CHECK_INSTANCE_CAST (self, gtk_cell_layout_get_type (), GtkCellLayout), G_TYPE_CHECK_INSTANCE_CAST (text_renderer, gtk_cell_renderer_get_type (), GtkCellRenderer), TRUE);
	gtk_cell_layout_set_cell_data_func (G_TYPE_CHECK_INSTANCE_CAST (self, gtk_cell_layout_get_type (), GtkCellLayout), G_TYPE_CHECK_INSTANCE_CAST (text_renderer, gtk_cell_renderer_get_type (), GtkCellRenderer), _contact_entry_completion_cell_text_data_gtk_cell_layout_data_func, g_object_ref (self), g_object_unref);
	gtk_entry_completion_set_inline_selection (G_TYPE_CHECK_INSTANCE_CAST (self, gtk_entry_completion_get_type (), GtkEntryCompletion), TRUE);
	g_signal_connect_object (G_TYPE_CHECK_INSTANCE_CAST (self, gtk_entry_completion_get_type (), GtkEntryCompletion), "match-selected", (GCallback) _contact_entry_completion_on_match_selected_gtk_entry_completion_match_selected, self, 0);
	g_signal_connect_object (G_TYPE_CHECK_INSTANCE_CAST (self, gtk_entry_completion_get_type (), GtkEntryCompletion), "cursor-on-match", (GCallback) _contact_entry_completion_on_cursor_on_match_gtk_entry_completion_cursor_on_match, self, 0);
	_g_object_unref0 (text_renderer);
	_g_object_unref0 (icon_renderer);
	return self;
}

ContactEntryCompletion*
contact_entry_completion_new (ApplicationContactStore* contacts)
{
	return contact_entry_completion_construct (TYPE_CONTACT_ENTRY_COMPLETION, contacts);
}

void
contact_entry_completion_update_model (ContactEntryCompletion* self)
{
	GCancellable* _tmp0_;
	GtkListStore* model = NULL;
	GtkTreeModel* _tmp2_;
	GtkTreeModel* _tmp3_;
	GtkListStore* _tmp4_;
	gchar* completion_key = NULL;
	const gchar* _tmp5_;
	gchar* _tmp6_;
	const gchar* _tmp7_;
	g_return_if_fail (IS_CONTACT_ENTRY_COMPLETION (self));
	__vala_GtkTreeIter_free0 (self->priv->last_iter);
	self->priv->last_iter = NULL;
	contact_entry_completion_update_addresses (self);
	_tmp0_ = self->priv->search_cancellable;
	if (_tmp0_ != NULL) {
		GCancellable* _tmp1_;
		_tmp1_ = self->priv->search_cancellable;
		g_cancellable_cancel (_tmp1_);
		_g_object_unref0 (self->priv->search_cancellable);
		self->priv->search_cancellable = NULL;
	}
	_tmp2_ = gtk_entry_completion_get_model (G_TYPE_CHECK_INSTANCE_CAST (self, gtk_entry_completion_get_type (), GtkEntryCompletion));
	_tmp3_ = _tmp2_;
	_tmp4_ = _g_object_ref0 (G_TYPE_CHECK_INSTANCE_CAST (_tmp3_, gtk_list_store_get_type (), GtkListStore));
	model = _tmp4_;
	_tmp5_ = self->priv->current_key;
	_tmp6_ = g_strdup (_tmp5_);
	completion_key = _tmp6_;
	_tmp7_ = completion_key;
	if (!geary_string_is_empty_or_whitespace (_tmp7_)) {
		GCancellable* _tmp8_;
		const gchar* _tmp9_;
		GCancellable* _tmp10_;
		_tmp8_ = g_cancellable_new ();
		_g_object_unref0 (self->priv->search_cancellable);
		self->priv->search_cancellable = _tmp8_;
		_tmp9_ = completion_key;
		_tmp10_ = self->priv->search_cancellable;
		contact_entry_completion_search_contacts (self, _tmp9_, _tmp10_, NULL, NULL);
	} else {
		GtkListStore* _tmp11_;
		_tmp11_ = model;
		gtk_list_store_clear (_tmp11_);
	}
	_g_free0 (completion_key);
	_g_object_unref0 (model);
}

void
contact_entry_completion_trigger_selection (ContactEntryCompletion* self)
{
	GtkTreeIter* _tmp0_;
	g_return_if_fail (IS_CONTACT_ENTRY_COMPLETION (self));
	_tmp0_ = self->priv->last_iter;
	if (_tmp0_ != NULL) {
		GtkTreeIter* _tmp1_;
		GtkTreeIter _tmp2_;
		_tmp1_ = self->priv->last_iter;
		_tmp2_ = *_tmp1_;
		contact_entry_completion_insert_address_at_cursor (self, &_tmp2_);
		__vala_GtkTreeIter_free0 (self->priv->last_iter);
		self->priv->last_iter = NULL;
	}
}

static gboolean
string_get_next_char (const gchar* self,
                      gint* index,
                      gunichar* c)
{
	gunichar _vala_c = 0U;
	gboolean result;
	g_return_val_if_fail (self != NULL, FALSE);
	_vala_c = g_utf8_get_char (((gchar*) self) + (*index));
	if (_vala_c != ((gunichar) 0)) {
		gchar* _tmp0_;
		_tmp0_ = g_utf8_next_char (((gchar*) self) + (*index));
		*index = (gint) (_tmp0_ - ((gchar*) self));
		result = TRUE;
		if (c) {
			*c = _vala_c;
		}
		return result;
	} else {
		result = FALSE;
		if (c) {
			*c = _vala_c;
		}
		return result;
	}
}

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

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

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

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

static void
contact_entry_completion_update_addresses (ContactEntryCompletion* self)
{
	GtkEntry* entry = NULL;
	GtkWidget* _tmp0_;
	GtkEntry* _tmp1_;
	GtkEntry* _tmp2_;
	g_return_if_fail (IS_CONTACT_ENTRY_COMPLETION (self));
	_tmp0_ = gtk_entry_completion_get_entry (G_TYPE_CHECK_INSTANCE_CAST (self, gtk_entry_completion_get_type (), GtkEntryCompletion));
	_tmp1_ = _g_object_ref0 (G_TYPE_CHECK_INSTANCE_TYPE (_tmp0_, gtk_entry_get_type ()) ? ((GtkEntry*) _tmp0_) : NULL);
	entry = _tmp1_;
	_tmp2_ = entry;
	if (_tmp2_ != NULL) {
		gchar* _tmp3_;
		GeeArrayList* _tmp4_;
		gchar* text = NULL;
		GtkEntry* _tmp5_;
		const gchar* _tmp6_;
		gchar* _tmp7_;
		gint cursor_pos = 0;
		GtkEntry* _tmp8_;
		gint current_char = 0;
		gunichar c = 0U;
		gint start_idx = 0;
		gint next_idx = 0;
		gboolean in_quote = FALSE;
		gchar* address = NULL;
		const gchar* _tmp25_;
		gchar* _tmp26_;
		GeeArrayList* _tmp27_;
		const gchar* _tmp28_;
		_tmp3_ = g_strdup ("");
		_g_free0 (self->priv->current_key);
		self->priv->current_key = _tmp3_;
		self->priv->cursor_at_address = 0;
		_tmp4_ = self->priv->address_parts;
		gee_abstract_collection_clear (G_TYPE_CHECK_INSTANCE_CAST (_tmp4_, GEE_TYPE_ABSTRACT_COLLECTION, GeeAbstractCollection));
		_tmp5_ = entry;
		_tmp6_ = gtk_entry_get_text (_tmp5_);
		_tmp7_ = g_strdup (_tmp6_);
		text = _tmp7_;
		_tmp8_ = entry;
		cursor_pos = gtk_editable_get_position (G_TYPE_CHECK_INSTANCE_CAST (_tmp8_, gtk_editable_get_type (), GtkEditable));
		current_char = 0;
		c = (gunichar) 0;
		start_idx = 0;
		next_idx = 0;
		in_quote = FALSE;
		while (TRUE) {
			const gchar* _tmp9_;
			gunichar _tmp10_ = 0U;
			gboolean _tmp11_;
			gboolean _tmp12_ = FALSE;
			gint _tmp24_;
			_tmp9_ = text;
			_tmp11_ = string_get_next_char (_tmp9_, &next_idx, &_tmp10_);
			c = _tmp10_;
			if (!_tmp11_) {
				break;
			}
			if (current_char == cursor_pos) {
				_tmp12_ = current_char != 0;
			} else {
				_tmp12_ = FALSE;
			}
			if (_tmp12_) {
				GeeArrayList* _tmp17_;
				gint _tmp18_;
				gint _tmp19_;
				if (c != ((gunichar) ',')) {
					const gchar* _tmp13_;
					gchar* _tmp14_;
					gchar* _tmp15_;
					gchar* _tmp16_;
					_tmp13_ = text;
					_tmp14_ = string_slice (_tmp13_, (glong) start_idx, (glong) next_idx);
					_tmp15_ = _tmp14_;
					_tmp16_ = string_strip (_tmp15_);
					_g_free0 (self->priv->current_key);
					self->priv->current_key = _tmp16_;
					_g_free0 (_tmp15_);
				}
				_tmp17_ = self->priv->address_parts;
				_tmp18_ = gee_abstract_collection_get_size (G_TYPE_CHECK_INSTANCE_CAST (_tmp17_, GEE_TYPE_ABSTRACT_COLLECTION, GeeAbstractCollection));
				_tmp19_ = _tmp18_;
				self->priv->cursor_at_address = _tmp19_;
			}
			switch (c) {
				case ',':
				{
					if (!in_quote) {
						gchar* address = NULL;
						const gchar* _tmp20_;
						gchar* _tmp21_;
						GeeArrayList* _tmp22_;
						const gchar* _tmp23_;
						_tmp20_ = text;
						_tmp21_ = string_slice (_tmp20_, (glong) start_idx, (glong) (next_idx - 1));
						address = _tmp21_;
						_tmp22_ = self->priv->address_parts;
						_tmp23_ = address;
						gee_abstract_collection_add (G_TYPE_CHECK_INSTANCE_CAST (_tmp22_, GEE_TYPE_ABSTRACT_COLLECTION, GeeAbstractCollection), _tmp23_);
						start_idx = next_idx;
						_g_free0 (address);
					}
					break;
				}
				case '"':
				{
					in_quote = !in_quote;
					break;
				}
				default:
				break;
			}
			_tmp24_ = current_char;
			current_char = _tmp24_ + 1;
		}
		_tmp25_ = text;
		_tmp26_ = string_substring (_tmp25_, (glong) start_idx, (glong) -1);
		address = _tmp26_;
		_tmp27_ = self->priv->address_parts;
		_tmp28_ = address;
		gee_abstract_collection_add (G_TYPE_CHECK_INSTANCE_CAST (_tmp27_, GEE_TYPE_ABSTRACT_COLLECTION, GeeAbstractCollection), _tmp28_);
		_g_free0 (address);
		_g_free0 (text);
	}
	_g_object_unref0 (entry);
}

static gint
____lambda28_ (ContactEntryCompletion* self,
               gchar* a,
               gint chars)
{
	gint result;
	g_return_val_if_fail (a != NULL, 0);
	result = (g_utf8_strlen (a, (gssize) -1) + chars) + 1;
	_g_free0 (a);
	return result;
}

static gpointer
_____lambda28__gee_fold_func (gpointer g,
                              gpointer a,
                              gpointer self)
{
	gpointer result;
	result = (gpointer) ((gintptr) ____lambda28_ ((ContactEntryCompletion*) self, (gchar*) g, (gint) ((gintptr) a)));
	return result;
}

static void
contact_entry_completion_insert_address_at_cursor (ContactEntryCompletion* self,
                                                   GtkTreeIter* iter)
{
	GtkEntry* entry = NULL;
	GtkWidget* _tmp0_;
	GtkEntry* _tmp1_;
	GtkEntry* _tmp2_;
	g_return_if_fail (IS_CONTACT_ENTRY_COMPLETION (self));
	g_return_if_fail (iter != NULL);
	_tmp0_ = gtk_entry_completion_get_entry (G_TYPE_CHECK_INSTANCE_CAST (self, gtk_entry_completion_get_type (), GtkEntryCompletion));
	_tmp1_ = _g_object_ref0 (G_TYPE_CHECK_INSTANCE_TYPE (_tmp0_, gtk_entry_get_type ()) ? ((GtkEntry*) _tmp0_) : NULL);
	entry = _tmp1_;
	_tmp2_ = entry;
	if (_tmp2_ != NULL) {
		gint start_char = 0;
		gint end_char = 0;
		GtkEntry* _tmp7_;
		GValue value = {0};
		GtkTreeModel* _tmp8_;
		GtkTreeModel* _tmp9_;
		GtkTreeIter _tmp10_;
		GValue _tmp11_ = {0};
		GearyRFC822MailboxAddress* mailbox = NULL;
		GObject* _tmp12_;
		GearyRFC822MailboxAddress* _tmp13_;
		gchar* formatted = NULL;
		GearyRFC822MailboxAddress* _tmp14_;
		gchar* _tmp15_;
		gboolean _tmp18_ = FALSE;
		GtkEntry* _tmp19_;
		GtkEntry* _tmp20_;
		GtkEntryBuffer* _tmp21_;
		GtkEntryBuffer* _tmp22_;
		GeeArrayList* _tmp33_;
		const gchar* _tmp34_;
		GtkEntry* _tmp36_;
		const gchar* _tmp37_;
		GtkEntry* _tmp38_;
		GtkEntryBuffer* _tmp39_;
		GtkEntryBuffer* _tmp40_;
		GtkEntry* _tmp41_;
		start_char = 0;
		if (self->priv->cursor_at_address > 0) {
			GeeArrayList* _tmp3_;
			GeeList* _tmp4_;
			GeeList* _tmp5_;
			gpointer _tmp6_;
			_tmp3_ = self->priv->address_parts;
			_tmp4_ = gee_abstract_list_slice (G_TYPE_CHECK_INSTANCE_CAST (_tmp3_, GEE_TYPE_ABSTRACT_LIST, GeeAbstractList), 0, self->priv->cursor_at_address);
			_tmp5_ = _tmp4_;
			_tmp6_ = gee_traversable_fold (G_TYPE_CHECK_INSTANCE_CAST (_tmp5_, GEE_TYPE_TRAVERSABLE, GeeTraversable), G_TYPE_INT, NULL, NULL, _____lambda28__gee_fold_func, self, (gpointer) ((gintptr) 0));
			start_char = (gint) ((gintptr) _tmp6_);
			_g_object_unref0 (_tmp5_);
		}
		_tmp7_ = entry;
		end_char = gtk_editable_get_position (G_TYPE_CHECK_INSTANCE_CAST (_tmp7_, gtk_editable_get_type (), GtkEditable));
		_tmp8_ = gtk_entry_completion_get_model (G_TYPE_CHECK_INSTANCE_CAST (self, gtk_entry_completion_get_type (), GtkEntryCompletion));
		_tmp9_ = _tmp8_;
		_tmp10_ = *iter;
		gtk_tree_model_get_value (_tmp9_, &_tmp10_, (gint) CONTACT_ENTRY_COMPLETION_COLUMN_MAILBOX, &_tmp11_);
		G_IS_VALUE (&value) ? (g_value_unset (&value), NULL) : NULL;
		value = _tmp11_;
		_tmp12_ = g_value_get_object (&value);
		_tmp13_ = _g_object_ref0 (G_TYPE_CHECK_INSTANCE_CAST (_tmp12_, GEARY_RF_C822_TYPE_MAILBOX_ADDRESS, GearyRFC822MailboxAddress));
		mailbox = _tmp13_;
		_tmp14_ = mailbox;
		_tmp15_ = geary_rf_c822_mailbox_address_to_full_display (_tmp14_, "<", ">");
		formatted = _tmp15_;
		if (self->priv->cursor_at_address != 0) {
			const gchar* _tmp16_;
			gchar* _tmp17_;
			_tmp16_ = formatted;
			_tmp17_ = g_strconcat (" ", _tmp16_, NULL);
			_g_free0 (formatted);
			formatted = _tmp17_;
		}
		_tmp19_ = entry;
		_tmp20_ = entry;
		_tmp21_ = gtk_entry_get_buffer (_tmp20_);
		_tmp22_ = _tmp21_;
		if (((guint) gtk_editable_get_position (G_TYPE_CHECK_INSTANCE_CAST (_tmp19_, gtk_editable_get_type (), GtkEditable))) < gtk_entry_buffer_get_length (_tmp22_)) {
			GeeArrayList* _tmp23_;
			gpointer _tmp24_;
			gchar* _tmp25_;
			gchar* _tmp26_;
			gchar* _tmp27_;
			const gchar* _tmp28_;
			gchar* _tmp29_;
			gchar* _tmp30_;
			_tmp23_ = self->priv->address_parts;
			_tmp24_ = gee_abstract_list_get (G_TYPE_CHECK_INSTANCE_CAST (_tmp23_, GEE_TYPE_ABSTRACT_LIST, GeeAbstractList), self->priv->cursor_at_address);
			_tmp25_ = (gchar*) _tmp24_;
			_tmp26_ = string_strip (_tmp25_);
			_tmp27_ = _tmp26_;
			_tmp28_ = self->priv->current_key;
			_tmp29_ = string_strip (_tmp28_);
			_tmp30_ = _tmp29_;
			_tmp18_ = g_strcmp0 (_tmp27_, _tmp30_) != 0;
			_g_free0 (_tmp30_);
			_g_free0 (_tmp27_);
			_g_free0 (_tmp25_);
		} else {
			_tmp18_ = FALSE;
		}
		if (_tmp18_) {
			const gchar* _tmp31_;
			gchar* _tmp32_;
			_tmp31_ = formatted;
			_tmp32_ = g_strconcat (_tmp31_, ", ", NULL);
			_g_free0 (formatted);
			formatted = _tmp32_;
		}
		_tmp33_ = self->priv->address_parts;
		_tmp34_ = formatted;
		gee_abstract_list_insert (G_TYPE_CHECK_INSTANCE_CAST (_tmp33_, GEE_TYPE_ABSTRACT_LIST, GeeAbstractList), self->priv->cursor_at_address, _tmp34_);
		if (start_char < end_char) {
			GtkEntry* _tmp35_;
			_tmp35_ = entry;
			g_signal_emit_by_name (G_TYPE_CHECK_INSTANCE_CAST (_tmp35_, gtk_editable_get_type (), GtkEditable), "delete-text", start_char, end_char);
		}
		_tmp36_ = entry;
		_tmp37_ = formatted;
		g_signal_emit_by_name (G_TYPE_CHECK_INSTANCE_CAST (_tmp36_, gtk_editable_get_type (), GtkEditable), "insert-text", _tmp37_, -1, &start_char);
		_tmp38_ = entry;
		_tmp39_ = gtk_entry_get_buffer (_tmp38_);
		_tmp40_ = _tmp39_;
		if (((guint) start_char) < gtk_entry_buffer_get_length (_tmp40_)) {
			start_char += 2;
		}
		_tmp41_ = entry;
		gtk_editable_set_position (G_TYPE_CHECK_INSTANCE_CAST (_tmp41_, gtk_editable_get_type (), GtkEditable), start_char);
		_g_free0 (formatted);
		_g_object_unref0 (mailbox);
		G_IS_VALUE (&value) ? (g_value_unset (&value), NULL) : NULL;
	}
	_g_object_unref0 (entry);
}

static void
contact_entry_completion_search_contacts_data_free (gpointer _data)
{
	ContactEntryCompletionSearchContactsData* _data_;
	_data_ = _data;
	_g_free0 (_data_->query);
	_g_object_unref0 (_data_->cancellable);
	_g_object_unref0 (_data_->self);
	g_slice_free (ContactEntryCompletionSearchContactsData, _data_);
}

static void
contact_entry_completion_search_contacts (ContactEntryCompletion* self,
                                          const gchar* query,
                                          GCancellable* cancellable,
                                          GAsyncReadyCallback _callback_,
                                          gpointer _user_data_)
{
	ContactEntryCompletionSearchContactsData* _data_;
	ContactEntryCompletion* _tmp0_;
	gchar* _tmp1_;
	GCancellable* _tmp2_;
	g_return_if_fail (IS_CONTACT_ENTRY_COMPLETION (self));
	g_return_if_fail (query != NULL);
	g_return_if_fail ((cancellable == NULL) || G_TYPE_CHECK_INSTANCE_TYPE (cancellable, g_cancellable_get_type ()));
	_data_ = g_slice_new0 (ContactEntryCompletionSearchContactsData);
	_data_->_async_result = g_task_new (G_OBJECT (self), cancellable, _callback_, _user_data_);
	g_task_set_task_data (_data_->_async_result, _data_, contact_entry_completion_search_contacts_data_free);
	_tmp0_ = _g_object_ref0 (self);
	_data_->self = _tmp0_;
	_tmp1_ = g_strdup (query);
	_g_free0 (_data_->query);
	_data_->query = _tmp1_;
	_tmp2_ = _g_object_ref0 (cancellable);
	_g_object_unref0 (_data_->cancellable);
	_data_->cancellable = _tmp2_;
	contact_entry_completion_search_contacts_co (_data_);
}

static void
contact_entry_completion_search_contacts_finish (ContactEntryCompletion* self,
                                                 GAsyncResult* _res_)
{
	ContactEntryCompletionSearchContactsData* _data_;
	_data_ = g_task_propagate_pointer (G_TASK (_res_), NULL);
	if (NULL == _data_) {
		return;
	}
}

static void
contact_entry_completion_search_contacts_ready (GObject* source_object,
                                                GAsyncResult* _res_,
                                                gpointer _user_data_)
{
	ContactEntryCompletionSearchContactsData* _data_;
	_data_ = _user_data_;
	_data_->_source_object_ = source_object;
	_data_->_res_ = _res_;
	contact_entry_completion_search_contacts_co (_data_);
}

static gboolean
contact_entry_completion_search_contacts_co (ContactEntryCompletionSearchContactsData* _data_)
{
	switch (_data_->_state_) {
		case 0:
		goto _state_0;
		case 1:
		goto _state_1;
		default:
		g_assert_not_reached ();
	}
	_state_0:
	_data_->results = NULL;
	{
		_data_->_tmp1_ = _data_->self->priv->contacts;
		_data_->_state_ = 1;
		application_contact_store_search (_data_->_tmp1_, _data_->query, (guint) CONTACT_ENTRY_COMPLETION_VISIBILITY_THRESHOLD, (guint) 20, _data_->cancellable, contact_entry_completion_search_contacts_ready, _data_);
		return FALSE;
		_state_1:
		_data_->_tmp2_ = application_contact_store_search_finish (_data_->_tmp1_, _data_->_res_, &_data_->_inner_error0_);
		_data_->_tmp0_ = _data_->_tmp2_;
		if (G_UNLIKELY (_data_->_inner_error0_ != NULL)) {
			if (g_error_matches (_data_->_inner_error0_, G_IO_ERROR, G_IO_ERROR_CANCELLED)) {
				goto __catch0_g_io_error_cancelled;
			}
			goto __catch0_g_error;
		}
		_data_->_tmp3_ = _data_->_tmp0_;
		_data_->_tmp0_ = NULL;
		_g_object_unref0 (_data_->results);
		_data_->results = _data_->_tmp3_;
		_g_object_unref0 (_data_->_tmp0_);
	}
	goto __finally0;
	__catch0_g_io_error_cancelled:
	{
		g_clear_error (&_data_->_inner_error0_);
	}
	goto __finally0;
	__catch0_g_error:
	{
		_data_->err = _data_->_inner_error0_;
		_data_->_inner_error0_ = NULL;
		_data_->_tmp4_ = _data_->err;
		_data_->_tmp5_ = _data_->_tmp4_->message;
		g_debug ("contact-entry-completion.vala:240: Error searching contacts for comple" \
"tion: %s", _data_->_tmp5_);
		_g_error_free0 (_data_->err);
	}
	__finally0:
	if (G_UNLIKELY (_data_->_inner_error0_ != NULL)) {
		_g_object_unref0 (_data_->results);
		g_critical ("file %s: line %d: uncaught error: %s (%s, %d)", __FILE__, __LINE__, _data_->_inner_error0_->message, g_quark_to_string (_data_->_inner_error0_->domain), _data_->_inner_error0_->code);
		g_clear_error (&_data_->_inner_error0_);
		g_object_unref (_data_->_async_result);
		return FALSE;
	}
	if (!g_cancellable_is_cancelled (_data_->cancellable)) {
		_data_->_tmp6_ = contact_entry_completion_new_model (_data_->self);
		_data_->model = _data_->_tmp6_;
		{
			_data_->_tmp7_ = _data_->results;
			_data_->_tmp8_ = gee_iterable_iterator (G_TYPE_CHECK_INSTANCE_CAST (_data_->_tmp7_, GEE_TYPE_ITERABLE, GeeIterable));
			_data_->_contact_it = _data_->_tmp8_;
			while (TRUE) {
				_data_->_tmp9_ = _data_->_contact_it;
				if (!gee_iterator_next (_data_->_tmp9_)) {
					break;
				}
				_data_->_tmp10_ = _data_->_contact_it;
				_data_->_tmp11_ = gee_iterator_get (_data_->_tmp10_);
				_data_->contact = (ApplicationContact*) _data_->_tmp11_;
				{
					_data_->_tmp12_ = _data_->contact;
					_data_->_tmp13_ = application_contact_get_email_addresses (_data_->_tmp12_);
					_data_->_tmp14_ = _data_->_tmp13_;
					_data_->_tmp15_ = gee_iterable_iterator (G_TYPE_CHECK_INSTANCE_CAST (_data_->_tmp14_, GEE_TYPE_ITERABLE, GeeIterable));
					_data_->_addr_it = _data_->_tmp15_;
					while (TRUE) {
						_data_->_tmp16_ = _data_->_addr_it;
						if (!gee_iterator_next (_data_->_tmp16_)) {
							break;
						}
						_data_->_tmp17_ = _data_->_addr_it;
						_data_->_tmp18_ = gee_iterator_get (_data_->_tmp17_);
						_data_->addr = (GearyRFC822MailboxAddress*) _data_->_tmp18_;
						_data_->_tmp19_ = _data_->model;
						memset (&_data_->_tmp20_, 0, sizeof (GtkTreeIter));
						gtk_list_store_append (_data_->_tmp19_, &_data_->_tmp20_);
						_data_->iter = _data_->_tmp20_;
						_data_->_tmp21_ = _data_->model;
						_data_->_tmp22_ = _data_->iter;
						_data_->_tmp23_ = _data_->contact;
						gtk_list_store_set (_data_->_tmp21_, &_data_->_tmp22_, CONTACT_ENTRY_COMPLETION_COLUMN_CONTACT, _data_->_tmp23_, -1);
						_data_->_tmp24_ = _data_->model;
						_data_->_tmp25_ = _data_->iter;
						_data_->_tmp26_ = _data_->addr;
						gtk_list_store_set (_data_->_tmp24_, &_data_->_tmp25_, CONTACT_ENTRY_COMPLETION_COLUMN_MAILBOX, _data_->_tmp26_, -1);
						_g_object_unref0 (_data_->addr);
					}
					_g_object_unref0 (_data_->_addr_it);
				}
				_g_object_unref0 (_data_->contact);
			}
			_g_object_unref0 (_data_->_contact_it);
		}
		_data_->_tmp27_ = _data_->model;
		gtk_entry_completion_set_model (G_TYPE_CHECK_INSTANCE_CAST (_data_->self, gtk_entry_completion_get_type (), GtkEntryCompletion), G_TYPE_CHECK_INSTANCE_CAST (_data_->_tmp27_, gtk_tree_model_get_type (), GtkTreeModel));
		gtk_entry_completion_complete (G_TYPE_CHECK_INSTANCE_CAST (_data_->self, gtk_entry_completion_get_type (), GtkEntryCompletion));
		_g_object_unref0 (_data_->model);
	}
	_g_object_unref0 (_data_->results);
	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 gchar*
contact_entry_completion_match_prefix_contact (ContactEntryCompletion* self,
                                               GearyRFC822MailboxAddress* mailbox)
{
	gchar* email = NULL;
	const gchar* _tmp0_;
	const gchar* _tmp1_;
	gchar* _tmp2_;
	gboolean _tmp3_ = FALSE;
	const gchar* _tmp4_;
	const gchar* _tmp5_;
	gchar* result;
	g_return_val_if_fail (IS_CONTACT_ENTRY_COMPLETION (self), NULL);
	g_return_val_if_fail (G_TYPE_CHECK_INSTANCE_TYPE (mailbox, GEARY_RF_C822_TYPE_MAILBOX_ADDRESS), NULL);
	_tmp0_ = geary_rf_c822_mailbox_address_get_address (mailbox);
	_tmp1_ = _tmp0_;
	_tmp2_ = contact_entry_completion_match_prefix_string (self, _tmp1_);
	email = _tmp2_;
	_tmp4_ = geary_rf_c822_mailbox_address_get_name (mailbox);
	_tmp5_ = _tmp4_;
	if (_tmp5_ != NULL) {
		_tmp3_ = !geary_rf_c822_mailbox_address_is_spoofed (mailbox);
	} else {
		_tmp3_ = FALSE;
	}
	if (_tmp3_) {
		gchar* real_name = NULL;
		const gchar* _tmp6_;
		const gchar* _tmp7_;
		gchar* _tmp8_;
		const gchar* _tmp9_;
		gchar* _tmp10_;
		gchar* _tmp11_;
		gchar* _tmp12_;
		gchar* _tmp13_;
		const gchar* _tmp14_;
		gchar* _tmp15_;
		gchar* _tmp16_;
		gchar* _tmp17_;
		gchar* _tmp18_;
		gchar* _tmp19_;
		_tmp6_ = geary_rf_c822_mailbox_address_get_name (mailbox);
		_tmp7_ = _tmp6_;
		_tmp8_ = contact_entry_completion_match_prefix_string (self, _tmp7_);
		real_name = _tmp8_;
		_tmp9_ = real_name;
		_tmp10_ = g_markup_escape_text (" <", (gssize) -1);
		_tmp11_ = _tmp10_;
		_tmp12_ = g_strconcat (_tmp9_, _tmp11_, NULL);
		_tmp13_ = _tmp12_;
		_tmp14_ = email;
		_tmp15_ = g_strconcat (_tmp13_, _tmp14_, NULL);
		_tmp16_ = _tmp15_;
		_tmp17_ = g_markup_escape_text (">", (gssize) -1);
		_tmp18_ = _tmp17_;
		_tmp19_ = g_strconcat (_tmp16_, _tmp18_, NULL);
		_g_free0 (email);
		email = _tmp19_;
		_g_free0 (_tmp18_);
		_g_free0 (_tmp16_);
		_g_free0 (_tmp13_);
		_g_free0 (_tmp11_);
		_g_free0 (real_name);
	}
	result = email;
	return result;
}

static gboolean
_contact_entry_completion_eval_callback_gregex_eval_callback (GMatchInfo* match_info,
                                                              GString* _result_,
                                                              gpointer self)
{
	gboolean result;
	result = contact_entry_completion_eval_callback ((ContactEntryCompletion*) self, match_info, _result_);
	return result;
}

static gchar*
string_replace (const gchar* self,
                const gchar* old,
                const gchar* replacement)
{
	gboolean _tmp0_ = FALSE;
	gboolean _tmp1_ = FALSE;
	GError* _inner_error0_ = NULL;
	gchar* result;
	g_return_val_if_fail (self != NULL, NULL);
	g_return_val_if_fail (old != NULL, NULL);
	g_return_val_if_fail (replacement != NULL, NULL);
	if ((*((gchar*) self)) == '\0') {
		_tmp1_ = TRUE;
	} else {
		_tmp1_ = (*((gchar*) old)) == '\0';
	}
	if (_tmp1_) {
		_tmp0_ = TRUE;
	} else {
		_tmp0_ = g_strcmp0 (old, replacement) == 0;
	}
	if (_tmp0_) {
		gchar* _tmp2_;
		_tmp2_ = g_strdup (self);
		result = _tmp2_;
		return result;
	}
	{
		GRegex* regex = NULL;
		gchar* _tmp3_;
		gchar* _tmp4_;
		GRegex* _tmp5_;
		GRegex* _tmp6_;
		gchar* _tmp7_ = NULL;
		GRegex* _tmp8_;
		gchar* _tmp9_;
		gchar* _tmp10_;
		_tmp3_ = g_regex_escape_string (old, -1);
		_tmp4_ = _tmp3_;
		_tmp5_ = g_regex_new (_tmp4_, 0, 0, &_inner_error0_);
		_tmp6_ = _tmp5_;
		_g_free0 (_tmp4_);
		regex = _tmp6_;
		if (G_UNLIKELY (_inner_error0_ != NULL)) {
			if (_inner_error0_->domain == G_REGEX_ERROR) {
				goto __catch0_g_regex_error;
			}
			g_critical ("file %s: line %d: unexpected error: %s (%s, %d)", __FILE__, __LINE__, _inner_error0_->message, g_quark_to_string (_inner_error0_->domain), _inner_error0_->code);
			g_clear_error (&_inner_error0_);
			return NULL;
		}
		_tmp8_ = regex;
		_tmp9_ = g_regex_replace_literal (_tmp8_, self, (gssize) -1, 0, replacement, 0, &_inner_error0_);
		_tmp7_ = _tmp9_;
		if (G_UNLIKELY (_inner_error0_ != NULL)) {
			_g_regex_unref0 (regex);
			if (_inner_error0_->domain == G_REGEX_ERROR) {
				goto __catch0_g_regex_error;
			}
			g_critical ("file %s: line %d: unexpected error: %s (%s, %d)", __FILE__, __LINE__, _inner_error0_->message, g_quark_to_string (_inner_error0_->domain), _inner_error0_->code);
			g_clear_error (&_inner_error0_);
			return NULL;
		}
		_tmp10_ = _tmp7_;
		_tmp7_ = NULL;
		result = _tmp10_;
		_g_free0 (_tmp7_);
		_g_regex_unref0 (regex);
		return result;
	}
	goto __finally0;
	__catch0_g_regex_error:
	{
		g_clear_error (&_inner_error0_);
		g_assert_not_reached ();
	}
	__finally0:
	g_critical ("file %s: line %d: uncaught error: %s (%s, %d)", __FILE__, __LINE__, _inner_error0_->message, g_quark_to_string (_inner_error0_->domain), _inner_error0_->code);
	g_clear_error (&_inner_error0_);
	return NULL;
}

static gchar*
contact_entry_completion_match_prefix_string (ContactEntryCompletion* self,
                                              const gchar* haystack)
{
	gchar* value = NULL;
	gchar* _tmp0_;
	const gchar* _tmp1_;
	GError* _inner_error0_ = NULL;
	gchar* result;
	g_return_val_if_fail (IS_CONTACT_ENTRY_COMPLETION (self), NULL);
	g_return_val_if_fail (haystack != NULL, NULL);
	_tmp0_ = g_strdup (haystack);
	value = _tmp0_;
	_tmp1_ = self->priv->current_key;
	if (!geary_string_is_empty (_tmp1_)) {
		gboolean matched = FALSE;
		const gchar* _tmp22_;
		gchar* _tmp23_;
		gchar* _tmp24_;
		gchar* _tmp25_;
		gchar* _tmp26_;
		gchar* _tmp27_;
		matched = FALSE;
		{
			gchar* escaped_needle = NULL;
			const gchar* _tmp2_;
			gchar* _tmp3_;
			gchar* _tmp4_;
			gchar* _tmp5_;
			gchar* _tmp6_;
			GRegex* regex = NULL;
			const gchar* _tmp7_;
			gchar* _tmp8_;
			gchar* _tmp9_;
			GRegex* _tmp10_;
			GRegex* _tmp11_;
			gchar* haystack_normalized = NULL;
			gchar* _tmp12_;
			GRegex* _tmp13_;
			const gchar* _tmp14_;
			_tmp2_ = self->priv->current_key;
			_tmp3_ = g_utf8_normalize (_tmp2_, (gssize) -1, G_NORMALIZE_DEFAULT);
			_tmp4_ = _tmp3_;
			_tmp5_ = g_regex_escape_string (_tmp4_, -1);
			_tmp6_ = _tmp5_;
			_g_free0 (_tmp4_);
			escaped_needle = _tmp6_;
			_tmp7_ = escaped_needle;
			_tmp8_ = g_strconcat ("\\b", _tmp7_, NULL);
			_tmp9_ = _tmp8_;
			_tmp10_ = g_regex_new (_tmp9_, G_REGEX_CASELESS, 0, &_inner_error0_);
			_tmp11_ = _tmp10_;
			_g_free0 (_tmp9_);
			regex = _tmp11_;
			if (G_UNLIKELY (_inner_error0_ != NULL)) {
				_g_free0 (escaped_needle);
				if (_inner_error0_->domain == G_REGEX_ERROR) {
					goto __catch0_g_regex_error;
				}
				_g_free0 (value);
				g_critical ("file %s: line %d: unexpected error: %s (%s, %d)", __FILE__, __LINE__, _inner_error0_->message, g_quark_to_string (_inner_error0_->domain), _inner_error0_->code);
				g_clear_error (&_inner_error0_);
				return NULL;
			}
			_tmp12_ = g_utf8_normalize (haystack, (gssize) -1, G_NORMALIZE_DEFAULT);
			haystack_normalized = _tmp12_;
			_tmp13_ = regex;
			_tmp14_ = haystack_normalized;
			if (g_regex_match (_tmp13_, _tmp14_, 0, NULL)) {
				gchar* _tmp15_ = NULL;
				GRegex* _tmp16_;
				const gchar* _tmp17_;
				gchar* _tmp18_;
				gchar* _tmp19_;
				_tmp16_ = regex;
				_tmp17_ = haystack_normalized;
				_tmp18_ = g_regex_replace_eval (_tmp16_, _tmp17_, (gssize) -1, 0, 0, _contact_entry_completion_eval_callback_gregex_eval_callback, self, &_inner_error0_);
				_tmp15_ = _tmp18_;
				if (G_UNLIKELY (_inner_error0_ != NULL)) {
					_g_free0 (haystack_normalized);
					_g_regex_unref0 (regex);
					_g_free0 (escaped_needle);
					if (_inner_error0_->domain == G_REGEX_ERROR) {
						goto __catch0_g_regex_error;
					}
					_g_free0 (value);
					g_critical ("file %s: line %d: unexpected error: %s (%s, %d)", __FILE__, __LINE__, _inner_error0_->message, g_quark_to_string (_inner_error0_->domain), _inner_error0_->code);
					g_clear_error (&_inner_error0_);
					return NULL;
				}
				_tmp19_ = _tmp15_;
				_tmp15_ = NULL;
				_g_free0 (value);
				value = _tmp19_;
				matched = TRUE;
				_g_free0 (_tmp15_);
			}
			_g_free0 (haystack_normalized);
			_g_regex_unref0 (regex);
			_g_free0 (escaped_needle);
		}
		goto __finally0;
		__catch0_g_regex_error:
		{
			GError* err = NULL;
			GError* _tmp20_;
			const gchar* _tmp21_;
			err = _inner_error0_;
			_inner_error0_ = NULL;
			_tmp20_ = err;
			_tmp21_ = _tmp20_->message;
			g_debug ("contact-entry-completion.vala:294: Error matching regex: %s", _tmp21_);
			_g_error_free0 (err);
		}
		__finally0:
		if (G_UNLIKELY (_inner_error0_ != NULL)) {
			_g_free0 (value);
			g_critical ("file %s: line %d: uncaught error: %s (%s, %d)", __FILE__, __LINE__, _inner_error0_->message, g_quark_to_string (_inner_error0_->domain), _inner_error0_->code);
			g_clear_error (&_inner_error0_);
			return NULL;
		}
		_tmp22_ = value;
		_tmp23_ = g_markup_escape_text (_tmp22_, (gssize) -1);
		_tmp24_ = _tmp23_;
		_tmp25_ = string_replace (_tmp24_, "&#x91;", "<b>");
		_tmp26_ = _tmp25_;
		_tmp27_ = string_replace (_tmp26_, "&#x92;", "</b>");
		_g_free0 (value);
		value = _tmp27_;
		_g_free0 (_tmp26_);
		_g_free0 (_tmp24_);
	}
	result = value;
	return result;
}

static gboolean
contact_entry_completion_eval_callback (ContactEntryCompletion* self,
                                        GMatchInfo* match_info,
                                        GString* _result_)
{
	gchar* match = NULL;
	gchar* _tmp0_;
	const gchar* _tmp1_;
	gboolean result;
	g_return_val_if_fail (IS_CONTACT_ENTRY_COMPLETION (self), FALSE);
	g_return_val_if_fail (match_info != NULL, FALSE);
	g_return_val_if_fail (_result_ != NULL, FALSE);
	_tmp0_ = g_match_info_fetch (match_info, 0);
	match = _tmp0_;
	_tmp1_ = match;
	if (_tmp1_ != NULL) {
		const gchar* _tmp2_;
		gchar* _tmp3_;
		gchar* _tmp4_;
		_tmp2_ = match;
		_tmp3_ = g_strdup_printf ("\xc2\x91%s\xc2\x92", _tmp2_);
		_tmp4_ = _tmp3_;
		g_string_append (_result_, _tmp4_);
		_g_free0 (_tmp4_);
	}
	result = FALSE;
	_g_free0 (match);
	return result;
}

static void
contact_entry_completion_cell_icon_data (ContactEntryCompletion* self,
                                         GtkCellLayout* cell_layout,
                                         GtkCellRenderer* cell,
                                         GtkTreeModel* tree_model,
                                         GtkTreeIter* iter)
{
	GValue value = {0};
	GtkTreeIter _tmp0_;
	GValue _tmp1_ = {0};
	ApplicationContact* contact = NULL;
	GObject* _tmp2_;
	ApplicationContact* _tmp3_;
	gchar* icon = NULL;
	gchar* _tmp4_;
	ApplicationContact* _tmp5_;
	GtkCellRendererPixbuf* renderer = NULL;
	GtkCellRendererPixbuf* _tmp14_;
	const gchar* _tmp15_;
	g_return_if_fail (IS_CONTACT_ENTRY_COMPLETION (self));
	g_return_if_fail (G_TYPE_CHECK_INSTANCE_TYPE (cell_layout, gtk_cell_layout_get_type ()));
	g_return_if_fail (G_TYPE_CHECK_INSTANCE_TYPE (cell, gtk_cell_renderer_get_type ()));
	g_return_if_fail (G_TYPE_CHECK_INSTANCE_TYPE (tree_model, gtk_tree_model_get_type ()));
	g_return_if_fail (iter != NULL);
	_tmp0_ = *iter;
	gtk_tree_model_get_value (tree_model, &_tmp0_, (gint) CONTACT_ENTRY_COMPLETION_COLUMN_CONTACT, &_tmp1_);
	G_IS_VALUE (&value) ? (g_value_unset (&value), NULL) : NULL;
	value = _tmp1_;
	_tmp2_ = g_value_get_object (&value);
	_tmp3_ = _g_object_ref0 (APPLICATION_IS_CONTACT (_tmp2_) ? ((ApplicationContact*) _tmp2_) : NULL);
	contact = _tmp3_;
	_tmp4_ = g_strdup ("");
	icon = _tmp4_;
	_tmp5_ = contact;
	if (_tmp5_ != NULL) {
		ApplicationContact* _tmp6_;
		gboolean _tmp7_;
		gboolean _tmp8_;
		_tmp6_ = contact;
		_tmp7_ = application_contact_get_is_favourite (_tmp6_);
		_tmp8_ = _tmp7_;
		if (_tmp8_) {
			gchar* _tmp9_;
			_tmp9_ = g_strdup ("starred-symbolic");
			_g_free0 (icon);
			icon = _tmp9_;
		} else {
			ApplicationContact* _tmp10_;
			gboolean _tmp11_;
			gboolean _tmp12_;
			_tmp10_ = contact;
			_tmp11_ = application_contact_get_is_desktop_contact (_tmp10_);
			_tmp12_ = _tmp11_;
			if (_tmp12_) {
				gchar* _tmp13_;
				_tmp13_ = g_strdup ("avatar-default-symbolic");
				_g_free0 (icon);
				icon = _tmp13_;
			}
		}
	}
	_tmp14_ = _g_object_ref0 (G_TYPE_CHECK_INSTANCE_CAST (cell, gtk_cell_renderer_pixbuf_get_type (), GtkCellRendererPixbuf));
	renderer = _tmp14_;
	_tmp15_ = icon;
	g_object_set (renderer, "icon-name", _tmp15_, NULL);
	_g_object_unref0 (renderer);
	_g_free0 (icon);
	_g_object_unref0 (contact);
	G_IS_VALUE (&value) ? (g_value_unset (&value), NULL) : NULL;
}

static void
contact_entry_completion_cell_text_data (ContactEntryCompletion* self,
                                         GtkCellLayout* cell_layout,
                                         GtkCellRenderer* cell,
                                         GtkTreeModel* tree_model,
                                         GtkTreeIter* iter)
{
	GValue value = {0};
	GtkTreeIter _tmp0_;
	GValue _tmp1_ = {0};
	GearyRFC822MailboxAddress* mailbox = NULL;
	GObject* _tmp2_;
	GearyRFC822MailboxAddress* _tmp3_;
	gchar* markup = NULL;
	gchar* _tmp4_;
	GearyRFC822MailboxAddress* _tmp5_;
	GtkCellRendererText* renderer = NULL;
	GtkCellRendererText* _tmp8_;
	const gchar* _tmp9_;
	g_return_if_fail (IS_CONTACT_ENTRY_COMPLETION (self));
	g_return_if_fail (G_TYPE_CHECK_INSTANCE_TYPE (cell_layout, gtk_cell_layout_get_type ()));
	g_return_if_fail (G_TYPE_CHECK_INSTANCE_TYPE (cell, gtk_cell_renderer_get_type ()));
	g_return_if_fail (G_TYPE_CHECK_INSTANCE_TYPE (tree_model, gtk_tree_model_get_type ()));
	g_return_if_fail (iter != NULL);
	_tmp0_ = *iter;
	gtk_tree_model_get_value (tree_model, &_tmp0_, (gint) CONTACT_ENTRY_COMPLETION_COLUMN_MAILBOX, &_tmp1_);
	G_IS_VALUE (&value) ? (g_value_unset (&value), NULL) : NULL;
	value = _tmp1_;
	_tmp2_ = g_value_get_object (&value);
	_tmp3_ = _g_object_ref0 (G_TYPE_CHECK_INSTANCE_TYPE (_tmp2_, GEARY_RF_C822_TYPE_MAILBOX_ADDRESS) ? ((GearyRFC822MailboxAddress*) _tmp2_) : NULL);
	mailbox = _tmp3_;
	_tmp4_ = g_strdup ("");
	markup = _tmp4_;
	_tmp5_ = mailbox;
	if (_tmp5_ != NULL) {
		GearyRFC822MailboxAddress* _tmp6_;
		gchar* _tmp7_;
		_tmp6_ = mailbox;
		_tmp7_ = contact_entry_completion_match_prefix_contact (self, _tmp6_);
		_g_free0 (markup);
		markup = _tmp7_;
	}
	_tmp8_ = _g_object_ref0 (G_TYPE_CHECK_INSTANCE_CAST (cell, gtk_cell_renderer_text_get_type (), GtkCellRendererText));
	renderer = _tmp8_;
	_tmp9_ = markup;
	g_object_set (renderer, "markup", _tmp9_, NULL);
	_g_object_unref0 (renderer);
	_g_free0 (markup);
	_g_object_unref0 (mailbox);
	G_IS_VALUE (&value) ? (g_value_unset (&value), NULL) : NULL;
}

static inline GtkListStore*
contact_entry_completion_new_model (ContactEntryCompletion* self)
{
	gint _tmp0_ = 0;
	GType* _tmp1_;
	GType* _tmp2_;
	gint _tmp2__length1;
	GtkListStore* _tmp3_;
	GtkListStore* _tmp4_;
	GtkListStore* result;
	g_return_val_if_fail (IS_CONTACT_ENTRY_COMPLETION (self), NULL);
	_tmp1_ = contact_entry_completion_column_get_types (&_tmp0_);
	_tmp2_ = _tmp1_;
	_tmp2__length1 = _tmp0_;
	_tmp3_ = gtk_list_store_newv (_tmp0_, _tmp2_);
	_tmp4_ = _tmp3_;
	_tmp2_ = (g_free (_tmp2_), NULL);
	result = _tmp4_;
	return result;
}

static gboolean
contact_entry_completion_on_match_selected (ContactEntryCompletion* self,
                                            GtkTreeModel* model,
                                            GtkTreeIter* iter)
{
	GtkTreeIter _tmp0_;
	gboolean result;
	g_return_val_if_fail (IS_CONTACT_ENTRY_COMPLETION (self), FALSE);
	g_return_val_if_fail (G_TYPE_CHECK_INSTANCE_TYPE (model, gtk_tree_model_get_type ()), FALSE);
	g_return_val_if_fail (iter != NULL, FALSE);
	_tmp0_ = *iter;
	contact_entry_completion_insert_address_at_cursor (self, &_tmp0_);
	result = TRUE;
	return result;
}

static GtkTreeIter*
_vala_GtkTreeIter_copy (GtkTreeIter* self)
{
	return g_boxed_copy (gtk_tree_iter_get_type (), self);
}

static gpointer
__vala_GtkTreeIter_copy0 (gpointer self)
{
	return self ? _vala_GtkTreeIter_copy (self) : NULL;
}

static gboolean
contact_entry_completion_on_cursor_on_match (ContactEntryCompletion* self,
                                             GtkTreeModel* model,
                                             GtkTreeIter* iter)
{
	GtkTreeIter _tmp0_;
	GtkTreeIter* _tmp1_;
	gboolean result;
	g_return_val_if_fail (IS_CONTACT_ENTRY_COMPLETION (self), FALSE);
	g_return_val_if_fail (G_TYPE_CHECK_INSTANCE_TYPE (model, gtk_tree_model_get_type ()), FALSE);
	g_return_val_if_fail (iter != NULL, FALSE);
	_tmp0_ = *iter;
	_tmp1_ = __vala_GtkTreeIter_copy0 (&_tmp0_);
	__vala_GtkTreeIter_free0 (self->priv->last_iter);
	self->priv->last_iter = _tmp1_;
	result = TRUE;
	return result;
}

static void
contact_entry_completion_class_init (ContactEntryCompletionClass * klass,
                                     gpointer klass_data)
{
	contact_entry_completion_parent_class = g_type_class_peek_parent (klass);
	g_type_class_adjust_private_offset (klass, &ContactEntryCompletion_private_offset);
	G_OBJECT_CLASS (klass)->finalize = contact_entry_completion_finalize;
}

static void
contact_entry_completion_geary_base_interface_interface_init (GearyBaseInterfaceIface * iface,
                                                              gpointer iface_data)
{
	contact_entry_completion_geary_base_interface_parent_iface = g_type_interface_peek_parent (iface);
}

static void
contact_entry_completion_instance_init (ContactEntryCompletion * self,
                                        gpointer klass)
{
	gchar* _tmp0_;
	GeeArrayList* _tmp1_;
	self->priv = contact_entry_completion_get_instance_private (self);
	_tmp0_ = g_strdup ("");
	self->priv->current_key = _tmp0_;
	_tmp1_ = gee_array_list_new (G_TYPE_STRING, (GBoxedCopyFunc) g_strdup, (GDestroyNotify) g_free, NULL, NULL, NULL);
	self->priv->address_parts = _tmp1_;
	self->priv->cursor_at_address = 0;
	self->priv->search_cancellable = NULL;
	self->priv->last_iter = NULL;
}

static void
contact_entry_completion_finalize (GObject * obj)
{
	ContactEntryCompletion * self;
	self = G_TYPE_CHECK_INSTANCE_CAST (obj, TYPE_CONTACT_ENTRY_COMPLETION, ContactEntryCompletion);
	geary_base_interface_base_unref (G_TYPE_CHECK_INSTANCE_CAST (self, GEARY_TYPE_BASE_INTERFACE, GearyBaseInterface));
	_g_object_unref0 (self->priv->contacts);
	_g_free0 (self->priv->current_key);
	_g_object_unref0 (self->priv->address_parts);
	_g_object_unref0 (self->priv->search_cancellable);
	__vala_GtkTreeIter_free0 (self->priv->last_iter);
	G_OBJECT_CLASS (contact_entry_completion_parent_class)->finalize (obj);
}

static GType
contact_entry_completion_get_type_once (void)
{
	static const GTypeInfo g_define_type_info = { sizeof (ContactEntryCompletionClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) contact_entry_completion_class_init, (GClassFinalizeFunc) NULL, NULL, sizeof (ContactEntryCompletion), 0, (GInstanceInitFunc) contact_entry_completion_instance_init, NULL };
	static const GInterfaceInfo geary_base_interface_info = { (GInterfaceInitFunc) contact_entry_completion_geary_base_interface_interface_init, (GInterfaceFinalizeFunc) NULL, NULL};
	GType contact_entry_completion_type_id;
	contact_entry_completion_type_id = g_type_register_static (gtk_entry_completion_get_type (), "ContactEntryCompletion", &g_define_type_info, 0);
	g_type_add_interface_static (contact_entry_completion_type_id, GEARY_TYPE_BASE_INTERFACE, &geary_base_interface_info);
	ContactEntryCompletion_private_offset = g_type_add_instance_private (contact_entry_completion_type_id, sizeof (ContactEntryCompletionPrivate));
	return contact_entry_completion_type_id;
}

GType
contact_entry_completion_get_type (void)
{
	static volatile gsize contact_entry_completion_type_id__once = 0;
	if (g_once_init_enter (&contact_entry_completion_type_id__once)) {
		GType contact_entry_completion_type_id;
		contact_entry_completion_type_id = contact_entry_completion_get_type_once ();
		g_once_init_leave (&contact_entry_completion_type_id__once, contact_entry_completion_type_id);
	}
	return contact_entry_completion_type_id__once;
}

