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

/*
 * Copyright © 2016 Software Freedom Conservancy Inc.
 * Copyright © 2021 Michael Gratton <mike@vee.net>
 * Portions copyright © 2000-2013 Jeffrey Stedfast
 *
 * 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-engine.h"
#include <stdlib.h>
#include <string.h>
#include <glib.h>
#include <gee.h>
#include <glib-object.h>
#include <gmime/gmime.h>
#include <gio/gio.h>

#define _g_object_unref0(var) ((var == NULL) ? NULL : (var = (g_object_unref (var), NULL)))
#define _g_free0(var) (var = (g_free (var), NULL))
#define _g_string_free0(var) ((var == NULL) ? NULL : (var = (g_string_free (var, TRUE), NULL)))
#define __vala_GMimeParserOptions_free0(var) ((var == NULL) ? NULL : (var = (_vala_GMimeParserOptions_free (var), NULL)))
typedef struct _Block113Data Block113Data;
typedef struct _GearyRfC822UtilsGetBestCharsetData GearyRfC822UtilsGetBestCharsetData;
typedef struct _Block114Data Block114Data;
typedef struct _GearyRfC822UtilsGetBestEncodingData GearyRfC822UtilsGetBestEncodingData;
typedef struct _Block115Data Block115Data;

struct _Block113Data {
	int _ref_count_;
	GMimeStreamFilter* out_stream;
	GMimeStream* in_stream;
	gpointer _async_data_;
};

struct _GearyRfC822UtilsGetBestCharsetData {
	int _state_;
	GObject* _source_object_;
	GAsyncResult* _res_;
	GTask* _async_result;
	GMimeStream* in_stream;
	GCancellable* cancellable;
	gchar* result;
	Block113Data* _data113_;
	GMimeFilterBest* filter;
	GMimeFilterBest* _tmp0_;
	GMimeStreamNull* _tmp1_;
	GMimeStreamNull* _tmp2_;
	GMimeStreamFilter* _tmp3_;
	GMimeStreamFilter* _tmp4_;
	GearyNonblockingConcurrent* _tmp5_;
	GearyNonblockingConcurrent* _tmp6_;
	const gchar* _tmp7_;
	gchar* _tmp8_;
	GError* _inner_error0_;
};

struct _Block114Data {
	int _ref_count_;
	GMimeStreamFilter* out_stream;
	GMimeStream* in_stream;
	gpointer _async_data_;
};

struct _GearyRfC822UtilsGetBestEncodingData {
	int _state_;
	GObject* _source_object_;
	GAsyncResult* _res_;
	GTask* _async_result;
	GMimeStream* in_stream;
	GMimeEncodingConstraint constraint;
	GCancellable* cancellable;
	GMimeContentEncoding result;
	Block114Data* _data114_;
	GMimeFilterBest* filter;
	GMimeFilterBest* _tmp0_;
	GMimeStreamNull* _tmp1_;
	GMimeStreamNull* _tmp2_;
	GMimeStreamFilter* _tmp3_;
	GMimeStreamFilter* _tmp4_;
	GearyNonblockingConcurrent* _tmp5_;
	GearyNonblockingConcurrent* _tmp6_;
	GError* _inner_error0_;
};

struct _Block115Data {
	int _ref_count_;
	GearyEmail* email;
};

VALA_EXTERN gboolean geary_rf_c822_utils_email_is_from_sender (GearyEmail* email,
                                                   GeeList* sender_addresses);
VALA_EXTERN void geary_rf_c822_utils_remove_address (GeeList* addresses,
                                         GearyRFC822MailboxAddress* address,
                                         gboolean empty_ok);
VALA_EXTERN gchar* geary_rf_c822_utils_decode_rfc822_text_header_value (const gchar* rfc822);
static void _vala_GMimeParserOptions_free (GMimeParserOptions* self);
static void geary_rf_c822_utils_get_best_charset_data_free (gpointer _data);
VALA_EXTERN void geary_rf_c822_utils_get_best_charset (GMimeStream* in_stream,
                                           GCancellable* cancellable,
                                           GAsyncReadyCallback _callback_,
                                           gpointer _user_data_);
VALA_EXTERN gchar* geary_rf_c822_utils_get_best_charset_finish (GAsyncResult* _res_,
                                                    GError** error);
static gboolean geary_rf_c822_utils_get_best_charset_co (GearyRfC822UtilsGetBestCharsetData* _data_);
static Block113Data* block113_data_ref (Block113Data* _data113_);
static void block113_data_unref (void * _userdata_);
static void __lambda18_ (Block113Data* _data113_,
                  GError** error);
static void ___lambda18__geary_nonblocking_concurrent_concurrent_callback (GCancellable* cancellable,
                                                                    gpointer self,
                                                                    GError** error);
static void geary_rf_c822_utils_get_best_charset_ready (GObject* source_object,
                                                 GAsyncResult* _res_,
                                                 gpointer _user_data_);
static void geary_rf_c822_utils_get_best_encoding_data_free (gpointer _data);
VALA_EXTERN void geary_rf_c822_utils_get_best_encoding (GMimeStream* in_stream,
                                            GMimeEncodingConstraint constraint,
                                            GCancellable* cancellable,
                                            GAsyncReadyCallback _callback_,
                                            gpointer _user_data_);
VALA_EXTERN GMimeContentEncoding geary_rf_c822_utils_get_best_encoding_finish (GAsyncResult* _res_,
                                                                   GError** error);
static gboolean geary_rf_c822_utils_get_best_encoding_co (GearyRfC822UtilsGetBestEncodingData* _data_);
static Block114Data* block114_data_ref (Block114Data* _data114_);
static void block114_data_unref (void * _userdata_);
static void __lambda19_ (Block114Data* _data114_,
                  GError** error);
static void ___lambda19__geary_nonblocking_concurrent_concurrent_callback (GCancellable* cancellable,
                                                                    gpointer self,
                                                                    GError** error);
static void geary_rf_c822_utils_get_best_encoding_ready (GObject* source_object,
                                                  GAsyncResult* _res_,
                                                  gpointer _user_data_);
VALA_EXTERN GMimeStreamMem* geary_rf_c822_utils_create_stream_mem (GearyMemoryBuffer* buffer);
VALA_EXTERN gboolean geary_rf_c822_utils_comp_char_arr_slice (guint8* array,
                                                  gint array_length1,
                                                  guint start,
                                                  const gchar* comp);
static Block115Data* block115_data_ref (Block115Data* _data115_);
static void block115_data_unref (void * _userdata_);
static gboolean ___lambda178_ (Block115Data* _data115_,
                        GearyRFC822MailboxAddress* a);
static gboolean ____lambda178__gee_predicate (gconstpointer g,
                                       gpointer self);
static void _vala_array_destroy (gpointer array,
                          gssize array_length,
                          GDestroyNotify destroy_func);
static void _vala_array_free (gpointer array,
                       gssize array_length,
                       GDestroyNotify destroy_func);
static gssize _vala_array_length (gpointer array);

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

gchar*
geary_rf_c822_utils_create_subject_for_reply (GearyEmail* email)
{
	GearyRFC822Subject* _tmp0_ = NULL;
	GearyRFC822Subject* _tmp1_;
	GearyRFC822Subject* _tmp2_;
	GearyRFC822Subject* _tmp3_;
	GearyRFC822Subject* _tmp5_;
	GearyRFC822Subject* _tmp6_;
	const gchar* _tmp7_;
	const gchar* _tmp8_;
	gchar* _tmp9_;
	gchar* _tmp10_;
	gchar* result;
	g_return_val_if_fail (GEARY_IS_EMAIL (email), NULL);
	_tmp1_ = geary_email_header_set_get_subject (G_TYPE_CHECK_INSTANCE_CAST (email, GEARY_TYPE_EMAIL_HEADER_SET, GearyEmailHeaderSet));
	_tmp2_ = _tmp1_;
	_tmp3_ = _g_object_ref0 (_tmp2_);
	_tmp0_ = _tmp3_;
	if (_tmp0_ == NULL) {
		GearyRFC822Subject* _tmp4_;
		_tmp4_ = geary_rf_c822_subject_new ("");
		_g_object_unref0 (_tmp0_);
		_tmp0_ = _tmp4_;
	}
	_tmp5_ = geary_rf_c822_subject_create_reply (_tmp0_);
	_tmp6_ = _tmp5_;
	_tmp7_ = geary_message_data_string_message_data_get_value (G_TYPE_CHECK_INSTANCE_CAST (_tmp6_, GEARY_MESSAGE_DATA_TYPE_STRING_MESSAGE_DATA, GearyMessageDataStringMessageData));
	_tmp8_ = _tmp7_;
	_tmp9_ = g_strdup (_tmp8_);
	_tmp10_ = _tmp9_;
	_g_object_unref0 (_tmp6_);
	result = _tmp10_;
	_g_object_unref0 (_tmp0_);
	return result;
}

gchar*
geary_rf_c822_utils_create_subject_for_forward (GearyEmail* email)
{
	GearyRFC822Subject* _tmp0_ = NULL;
	GearyRFC822Subject* _tmp1_;
	GearyRFC822Subject* _tmp2_;
	GearyRFC822Subject* _tmp3_;
	GearyRFC822Subject* _tmp5_;
	GearyRFC822Subject* _tmp6_;
	const gchar* _tmp7_;
	const gchar* _tmp8_;
	gchar* _tmp9_;
	gchar* _tmp10_;
	gchar* result;
	g_return_val_if_fail (GEARY_IS_EMAIL (email), NULL);
	_tmp1_ = geary_email_header_set_get_subject (G_TYPE_CHECK_INSTANCE_CAST (email, GEARY_TYPE_EMAIL_HEADER_SET, GearyEmailHeaderSet));
	_tmp2_ = _tmp1_;
	_tmp3_ = _g_object_ref0 (_tmp2_);
	_tmp0_ = _tmp3_;
	if (_tmp0_ == NULL) {
		GearyRFC822Subject* _tmp4_;
		_tmp4_ = geary_rf_c822_subject_new ("");
		_g_object_unref0 (_tmp0_);
		_tmp0_ = _tmp4_;
	}
	_tmp5_ = geary_rf_c822_subject_create_forward (_tmp0_);
	_tmp6_ = _tmp5_;
	_tmp7_ = geary_message_data_string_message_data_get_value (G_TYPE_CHECK_INSTANCE_CAST (_tmp6_, GEARY_MESSAGE_DATA_TYPE_STRING_MESSAGE_DATA, GearyMessageDataStringMessageData));
	_tmp8_ = _tmp7_;
	_tmp9_ = g_strdup (_tmp8_);
	_tmp10_ = _tmp9_;
	_g_object_unref0 (_tmp6_);
	result = _tmp10_;
	_g_object_unref0 (_tmp0_);
	return result;
}

GearyRFC822MailboxAddresses*
geary_rf_c822_utils_create_to_addresses_for_reply (GearyEmail* email,
                                                   GeeList* sender_addresses)
{
	GeeArrayList* new_to = NULL;
	GeeArrayList* _tmp0_;
	gboolean _tmp1_ = FALSE;
	GearyRFC822MailboxAddresses* _tmp2_;
	GearyRFC822MailboxAddresses* _tmp3_;
	GeeArrayList* _tmp32_;
	GearyRFC822MailboxAddresses* _tmp33_;
	GearyRFC822MailboxAddresses* result;
	g_return_val_if_fail (GEARY_IS_EMAIL (email), NULL);
	g_return_val_if_fail ((sender_addresses == NULL) || G_TYPE_CHECK_INSTANCE_TYPE (sender_addresses, GEE_TYPE_LIST), NULL);
	_tmp0_ = gee_array_list_new (GEARY_RF_C822_TYPE_MAILBOX_ADDRESS, (GBoxedCopyFunc) g_object_ref, (GDestroyNotify) g_object_unref, NULL, NULL, NULL);
	new_to = _tmp0_;
	_tmp2_ = geary_email_header_set_get_to (G_TYPE_CHECK_INSTANCE_CAST (email, GEARY_TYPE_EMAIL_HEADER_SET, GearyEmailHeaderSet));
	_tmp3_ = _tmp2_;
	if (_tmp3_ != NULL) {
		_tmp1_ = geary_rf_c822_utils_email_is_from_sender (email, sender_addresses);
	} else {
		_tmp1_ = FALSE;
	}
	if (_tmp1_) {
		GeeArrayList* _tmp4_;
		GearyRFC822MailboxAddresses* _tmp5_;
		GearyRFC822MailboxAddresses* _tmp6_;
		GeeList* _tmp7_;
		GeeList* _tmp8_;
		_tmp4_ = new_to;
		_tmp5_ = geary_email_header_set_get_to (G_TYPE_CHECK_INSTANCE_CAST (email, GEARY_TYPE_EMAIL_HEADER_SET, GearyEmailHeaderSet));
		_tmp6_ = _tmp5_;
		_tmp7_ = geary_rf_c822_mailbox_addresses_get_all (_tmp6_);
		_tmp8_ = _tmp7_;
		gee_array_list_add_all (_tmp4_, G_TYPE_CHECK_INSTANCE_CAST (_tmp8_, GEE_TYPE_COLLECTION, GeeCollection));
		_g_object_unref0 (_tmp8_);
	} else {
		GearyRFC822MailboxAddresses* _tmp9_;
		GearyRFC822MailboxAddresses* _tmp10_;
		_tmp9_ = geary_email_header_set_get_reply_to (G_TYPE_CHECK_INSTANCE_CAST (email, GEARY_TYPE_EMAIL_HEADER_SET, GearyEmailHeaderSet));
		_tmp10_ = _tmp9_;
		if (_tmp10_ != NULL) {
			GeeArrayList* _tmp11_;
			GearyRFC822MailboxAddresses* _tmp12_;
			GearyRFC822MailboxAddresses* _tmp13_;
			GeeList* _tmp14_;
			GeeList* _tmp15_;
			_tmp11_ = new_to;
			_tmp12_ = geary_email_header_set_get_reply_to (G_TYPE_CHECK_INSTANCE_CAST (email, GEARY_TYPE_EMAIL_HEADER_SET, GearyEmailHeaderSet));
			_tmp13_ = _tmp12_;
			_tmp14_ = geary_rf_c822_mailbox_addresses_get_all (_tmp13_);
			_tmp15_ = _tmp14_;
			gee_array_list_add_all (_tmp11_, G_TYPE_CHECK_INSTANCE_CAST (_tmp15_, GEE_TYPE_COLLECTION, GeeCollection));
			_g_object_unref0 (_tmp15_);
		} else {
			GearyRFC822MailboxAddresses* _tmp16_;
			GearyRFC822MailboxAddresses* _tmp17_;
			_tmp16_ = geary_email_header_set_get_from (G_TYPE_CHECK_INSTANCE_CAST (email, GEARY_TYPE_EMAIL_HEADER_SET, GearyEmailHeaderSet));
			_tmp17_ = _tmp16_;
			if (_tmp17_ != NULL) {
				GeeArrayList* _tmp18_;
				GearyRFC822MailboxAddresses* _tmp19_;
				GearyRFC822MailboxAddresses* _tmp20_;
				GeeList* _tmp21_;
				GeeList* _tmp22_;
				_tmp18_ = new_to;
				_tmp19_ = geary_email_header_set_get_from (G_TYPE_CHECK_INSTANCE_CAST (email, GEARY_TYPE_EMAIL_HEADER_SET, GearyEmailHeaderSet));
				_tmp20_ = _tmp19_;
				_tmp21_ = geary_rf_c822_mailbox_addresses_get_all (_tmp20_);
				_tmp22_ = _tmp21_;
				gee_array_list_add_all (_tmp18_, G_TYPE_CHECK_INSTANCE_CAST (_tmp22_, GEE_TYPE_COLLECTION, GeeCollection));
				_g_object_unref0 (_tmp22_);
			}
		}
	}
	if (sender_addresses != NULL) {
		{
			GeeList* _address_list = NULL;
			gint _address_size = 0;
			GeeList* _tmp23_;
			gint _tmp24_;
			gint _tmp25_;
			gint _address_index = 0;
			_address_list = sender_addresses;
			_tmp23_ = _address_list;
			_tmp24_ = gee_collection_get_size (G_TYPE_CHECK_INSTANCE_CAST (_tmp23_, GEE_TYPE_COLLECTION, GeeCollection));
			_tmp25_ = _tmp24_;
			_address_size = _tmp25_;
			_address_index = -1;
			while (TRUE) {
				gint _tmp26_;
				gint _tmp27_;
				GearyRFC822MailboxAddress* address = NULL;
				GeeList* _tmp28_;
				gpointer _tmp29_;
				GeeArrayList* _tmp30_;
				GearyRFC822MailboxAddress* _tmp31_;
				_address_index = _address_index + 1;
				_tmp26_ = _address_index;
				_tmp27_ = _address_size;
				if (!(_tmp26_ < _tmp27_)) {
					break;
				}
				_tmp28_ = _address_list;
				_tmp29_ = gee_list_get (_tmp28_, _address_index);
				address = (GearyRFC822MailboxAddress*) _tmp29_;
				_tmp30_ = new_to;
				_tmp31_ = address;
				geary_rf_c822_utils_remove_address (G_TYPE_CHECK_INSTANCE_CAST (_tmp30_, GEE_TYPE_LIST, GeeList), _tmp31_, FALSE);
				_g_object_unref0 (address);
			}
		}
	}
	_tmp32_ = new_to;
	_tmp33_ = geary_rf_c822_mailbox_addresses_new (G_TYPE_CHECK_INSTANCE_CAST (_tmp32_, GEE_TYPE_COLLECTION, GeeCollection));
	result = _tmp33_;
	_g_object_unref0 (new_to);
	return result;
}

GearyRFC822MailboxAddresses*
geary_rf_c822_utils_create_cc_addresses_for_reply_all (GearyEmail* email,
                                                       GeeList* sender_addresses)
{
	GeeArrayList* new_cc = NULL;
	GeeArrayList* _tmp0_;
	gboolean _tmp1_ = FALSE;
	GearyRFC822MailboxAddresses* _tmp2_;
	GearyRFC822MailboxAddresses* _tmp3_;
	GearyRFC822MailboxAddresses* _tmp9_;
	GearyRFC822MailboxAddresses* _tmp10_;
	GeeArrayList* _tmp25_;
	GearyRFC822MailboxAddresses* _tmp26_;
	GearyRFC822MailboxAddresses* result;
	g_return_val_if_fail (GEARY_IS_EMAIL (email), NULL);
	g_return_val_if_fail ((sender_addresses == NULL) || G_TYPE_CHECK_INSTANCE_TYPE (sender_addresses, GEE_TYPE_LIST), NULL);
	_tmp0_ = gee_array_list_new (GEARY_RF_C822_TYPE_MAILBOX_ADDRESS, (GBoxedCopyFunc) g_object_ref, (GDestroyNotify) g_object_unref, NULL, NULL, NULL);
	new_cc = _tmp0_;
	_tmp2_ = geary_email_header_set_get_to (G_TYPE_CHECK_INSTANCE_CAST (email, GEARY_TYPE_EMAIL_HEADER_SET, GearyEmailHeaderSet));
	_tmp3_ = _tmp2_;
	if (_tmp3_ != NULL) {
		_tmp1_ = !geary_rf_c822_utils_email_is_from_sender (email, sender_addresses);
	} else {
		_tmp1_ = FALSE;
	}
	if (_tmp1_) {
		GeeArrayList* _tmp4_;
		GearyRFC822MailboxAddresses* _tmp5_;
		GearyRFC822MailboxAddresses* _tmp6_;
		GeeList* _tmp7_;
		GeeList* _tmp8_;
		_tmp4_ = new_cc;
		_tmp5_ = geary_email_header_set_get_to (G_TYPE_CHECK_INSTANCE_CAST (email, GEARY_TYPE_EMAIL_HEADER_SET, GearyEmailHeaderSet));
		_tmp6_ = _tmp5_;
		_tmp7_ = geary_rf_c822_mailbox_addresses_get_all (_tmp6_);
		_tmp8_ = _tmp7_;
		gee_array_list_add_all (_tmp4_, G_TYPE_CHECK_INSTANCE_CAST (_tmp8_, GEE_TYPE_COLLECTION, GeeCollection));
		_g_object_unref0 (_tmp8_);
	}
	_tmp9_ = geary_email_header_set_get_cc (G_TYPE_CHECK_INSTANCE_CAST (email, GEARY_TYPE_EMAIL_HEADER_SET, GearyEmailHeaderSet));
	_tmp10_ = _tmp9_;
	if (_tmp10_ != NULL) {
		GeeArrayList* _tmp11_;
		GearyRFC822MailboxAddresses* _tmp12_;
		GearyRFC822MailboxAddresses* _tmp13_;
		GeeList* _tmp14_;
		GeeList* _tmp15_;
		_tmp11_ = new_cc;
		_tmp12_ = geary_email_header_set_get_cc (G_TYPE_CHECK_INSTANCE_CAST (email, GEARY_TYPE_EMAIL_HEADER_SET, GearyEmailHeaderSet));
		_tmp13_ = _tmp12_;
		_tmp14_ = geary_rf_c822_mailbox_addresses_get_all (_tmp13_);
		_tmp15_ = _tmp14_;
		gee_array_list_add_all (_tmp11_, G_TYPE_CHECK_INSTANCE_CAST (_tmp15_, GEE_TYPE_COLLECTION, GeeCollection));
		_g_object_unref0 (_tmp15_);
	}
	if (sender_addresses != NULL) {
		{
			GeeList* _address_list = NULL;
			gint _address_size = 0;
			GeeList* _tmp16_;
			gint _tmp17_;
			gint _tmp18_;
			gint _address_index = 0;
			_address_list = sender_addresses;
			_tmp16_ = _address_list;
			_tmp17_ = gee_collection_get_size (G_TYPE_CHECK_INSTANCE_CAST (_tmp16_, GEE_TYPE_COLLECTION, GeeCollection));
			_tmp18_ = _tmp17_;
			_address_size = _tmp18_;
			_address_index = -1;
			while (TRUE) {
				gint _tmp19_;
				gint _tmp20_;
				GearyRFC822MailboxAddress* address = NULL;
				GeeList* _tmp21_;
				gpointer _tmp22_;
				GeeArrayList* _tmp23_;
				GearyRFC822MailboxAddress* _tmp24_;
				_address_index = _address_index + 1;
				_tmp19_ = _address_index;
				_tmp20_ = _address_size;
				if (!(_tmp19_ < _tmp20_)) {
					break;
				}
				_tmp21_ = _address_list;
				_tmp22_ = gee_list_get (_tmp21_, _address_index);
				address = (GearyRFC822MailboxAddress*) _tmp22_;
				_tmp23_ = new_cc;
				_tmp24_ = address;
				geary_rf_c822_utils_remove_address (G_TYPE_CHECK_INSTANCE_CAST (_tmp23_, GEE_TYPE_LIST, GeeList), _tmp24_, TRUE);
				_g_object_unref0 (address);
			}
		}
	}
	_tmp25_ = new_cc;
	_tmp26_ = geary_rf_c822_mailbox_addresses_new (G_TYPE_CHECK_INSTANCE_CAST (_tmp25_, GEE_TYPE_COLLECTION, GeeCollection));
	result = _tmp26_;
	_g_object_unref0 (new_cc);
	return result;
}

GearyRFC822MailboxAddresses*
geary_rf_c822_utils_merge_addresses (GearyRFC822MailboxAddresses* first,
                                     GearyRFC822MailboxAddresses* second)
{
	GeeArrayList* _result_ = NULL;
	GeeArrayList* _tmp0_;
	GeeArrayList* _tmp19_;
	GearyRFC822MailboxAddresses* _tmp20_;
	GearyRFC822MailboxAddresses* result;
	g_return_val_if_fail ((first == NULL) || GEARY_RF_C822_IS_MAILBOX_ADDRESSES (first), NULL);
	g_return_val_if_fail ((second == NULL) || GEARY_RF_C822_IS_MAILBOX_ADDRESSES (second), NULL);
	_tmp0_ = gee_array_list_new (GEARY_RF_C822_TYPE_MAILBOX_ADDRESS, (GBoxedCopyFunc) g_object_ref, (GDestroyNotify) g_object_unref, NULL, NULL, NULL);
	_result_ = _tmp0_;
	if (first != NULL) {
		GeeArrayList* _tmp1_;
		GeeList* _tmp2_;
		GeeList* _tmp3_;
		_tmp1_ = _result_;
		_tmp2_ = geary_rf_c822_mailbox_addresses_get_all (first);
		_tmp3_ = _tmp2_;
		gee_array_list_add_all (_tmp1_, G_TYPE_CHECK_INSTANCE_CAST (_tmp3_, GEE_TYPE_COLLECTION, GeeCollection));
		_g_object_unref0 (_tmp3_);
		if (second != NULL) {
			{
				GearyRFC822MailboxAddresses* _address_list = NULL;
				gint _address_size = 0;
				GearyRFC822MailboxAddresses* _tmp4_;
				gint _tmp5_;
				gint _tmp6_;
				gint _address_index = 0;
				_address_list = second;
				_tmp4_ = _address_list;
				_tmp5_ = geary_rf_c822_mailbox_addresses_get_size (_tmp4_);
				_tmp6_ = _tmp5_;
				_address_size = _tmp6_;
				_address_index = -1;
				while (TRUE) {
					gint _tmp7_;
					gint _tmp8_;
					GearyRFC822MailboxAddress* address = NULL;
					GearyRFC822MailboxAddresses* _tmp9_;
					GearyRFC822MailboxAddress* _tmp10_;
					GearyRFC822MailboxAddress* _tmp11_;
					const gchar* _tmp12_;
					const gchar* _tmp13_;
					_address_index = _address_index + 1;
					_tmp7_ = _address_index;
					_tmp8_ = _address_size;
					if (!(_tmp7_ < _tmp8_)) {
						break;
					}
					_tmp9_ = _address_list;
					_tmp10_ = geary_rf_c822_mailbox_addresses_get (_tmp9_, _address_index);
					address = _tmp10_;
					_tmp11_ = address;
					_tmp12_ = geary_rf_c822_mailbox_address_get_address (_tmp11_);
					_tmp13_ = _tmp12_;
					if (!geary_rf_c822_mailbox_addresses_contains_normalized (first, _tmp13_)) {
						GeeArrayList* _tmp14_;
						GearyRFC822MailboxAddress* _tmp15_;
						_tmp14_ = _result_;
						_tmp15_ = address;
						gee_abstract_collection_add (G_TYPE_CHECK_INSTANCE_CAST (_tmp14_, GEE_TYPE_ABSTRACT_COLLECTION, GeeAbstractCollection), _tmp15_);
					}
					_g_object_unref0 (address);
				}
			}
		}
	} else {
		if (second != NULL) {
			GeeArrayList* _tmp16_;
			GeeList* _tmp17_;
			GeeList* _tmp18_;
			_tmp16_ = _result_;
			_tmp17_ = geary_rf_c822_mailbox_addresses_get_all (second);
			_tmp18_ = _tmp17_;
			gee_array_list_add_all (_tmp16_, G_TYPE_CHECK_INSTANCE_CAST (_tmp18_, GEE_TYPE_COLLECTION, GeeCollection));
			_g_object_unref0 (_tmp18_);
		}
	}
	_tmp19_ = _result_;
	_tmp20_ = geary_rf_c822_mailbox_addresses_new (G_TYPE_CHECK_INSTANCE_CAST (_tmp19_, GEE_TYPE_COLLECTION, GeeCollection));
	result = _tmp20_;
	_g_object_unref0 (_result_);
	return result;
}

GearyRFC822MailboxAddresses*
geary_rf_c822_utils_remove_addresses (GearyRFC822MailboxAddresses* from_addresses,
                                      GearyRFC822MailboxAddresses* remove_addresses)
{
	GeeList* _result_ = NULL;
	GeeArrayList* _tmp0_;
	GeeList* _tmp13_;
	GearyRFC822MailboxAddresses* _tmp14_;
	GearyRFC822MailboxAddresses* result;
	g_return_val_if_fail ((from_addresses == NULL) || GEARY_RF_C822_IS_MAILBOX_ADDRESSES (from_addresses), NULL);
	g_return_val_if_fail ((remove_addresses == NULL) || GEARY_RF_C822_IS_MAILBOX_ADDRESSES (remove_addresses), NULL);
	_tmp0_ = gee_array_list_new (GEARY_RF_C822_TYPE_MAILBOX_ADDRESS, (GBoxedCopyFunc) g_object_ref, (GDestroyNotify) g_object_unref, NULL, NULL, NULL);
	_result_ = G_TYPE_CHECK_INSTANCE_CAST (_tmp0_, GEE_TYPE_LIST, GeeList);
	if (from_addresses != NULL) {
		GeeList* _tmp1_;
		GeeList* _tmp2_;
		GeeList* _tmp3_;
		_tmp1_ = _result_;
		_tmp2_ = geary_rf_c822_mailbox_addresses_get_all (from_addresses);
		_tmp3_ = _tmp2_;
		gee_collection_add_all (G_TYPE_CHECK_INSTANCE_CAST (_tmp1_, GEE_TYPE_COLLECTION, GeeCollection), G_TYPE_CHECK_INSTANCE_CAST (_tmp3_, GEE_TYPE_COLLECTION, GeeCollection));
		_g_object_unref0 (_tmp3_);
		if (remove_addresses != NULL) {
			{
				GearyRFC822MailboxAddresses* _address_list = NULL;
				gint _address_size = 0;
				GearyRFC822MailboxAddresses* _tmp4_;
				gint _tmp5_;
				gint _tmp6_;
				gint _address_index = 0;
				_address_list = remove_addresses;
				_tmp4_ = _address_list;
				_tmp5_ = geary_rf_c822_mailbox_addresses_get_size (_tmp4_);
				_tmp6_ = _tmp5_;
				_address_size = _tmp6_;
				_address_index = -1;
				while (TRUE) {
					gint _tmp7_;
					gint _tmp8_;
					GearyRFC822MailboxAddress* address = NULL;
					GearyRFC822MailboxAddresses* _tmp9_;
					GearyRFC822MailboxAddress* _tmp10_;
					GeeList* _tmp11_;
					GearyRFC822MailboxAddress* _tmp12_;
					_address_index = _address_index + 1;
					_tmp7_ = _address_index;
					_tmp8_ = _address_size;
					if (!(_tmp7_ < _tmp8_)) {
						break;
					}
					_tmp9_ = _address_list;
					_tmp10_ = geary_rf_c822_mailbox_addresses_get (_tmp9_, _address_index);
					address = _tmp10_;
					_tmp11_ = _result_;
					_tmp12_ = address;
					geary_rf_c822_utils_remove_address (_tmp11_, _tmp12_, TRUE);
					_g_object_unref0 (address);
				}
			}
		}
	}
	_tmp13_ = _result_;
	_tmp14_ = geary_rf_c822_mailbox_addresses_new (G_TYPE_CHECK_INSTANCE_CAST (_tmp13_, GEE_TYPE_COLLECTION, GeeCollection));
	result = _tmp14_;
	_g_object_unref0 (_result_);
	return result;
}

/** Generate a References header value in reply to a message. */
GearyRFC822MessageIDList*
geary_rf_c822_utils_reply_references (GearyEmail* source)
{
	GeeLinkedList* list = NULL;
	GeeLinkedList* _tmp0_;
	GearyRFC822MessageIDList* _tmp1_;
	GearyRFC822MessageIDList* _tmp2_;
	GearyRFC822MessageIDList* _tmp8_;
	GearyRFC822MessageIDList* _tmp9_;
	GearyRFC822MessageID* _tmp24_;
	GearyRFC822MessageID* _tmp25_;
	GeeLinkedList* _tmp29_;
	GearyRFC822MessageIDList* _tmp30_;
	GearyRFC822MessageIDList* result;
	g_return_val_if_fail (GEARY_IS_EMAIL (source), NULL);
	_tmp0_ = gee_linked_list_new (GEARY_RF_C822_TYPE_MESSAGE_ID, (GBoxedCopyFunc) g_object_ref, (GDestroyNotify) g_object_unref, NULL, NULL, NULL);
	list = _tmp0_;
	_tmp1_ = geary_email_header_set_get_references (G_TYPE_CHECK_INSTANCE_CAST (source, GEARY_TYPE_EMAIL_HEADER_SET, GearyEmailHeaderSet));
	_tmp2_ = _tmp1_;
	if (_tmp2_ != NULL) {
		GeeLinkedList* _tmp3_;
		GearyRFC822MessageIDList* _tmp4_;
		GearyRFC822MessageIDList* _tmp5_;
		GeeList* _tmp6_;
		GeeList* _tmp7_;
		_tmp3_ = list;
		_tmp4_ = geary_email_header_set_get_references (G_TYPE_CHECK_INSTANCE_CAST (source, GEARY_TYPE_EMAIL_HEADER_SET, GearyEmailHeaderSet));
		_tmp5_ = _tmp4_;
		_tmp6_ = geary_rf_c822_message_id_list_get_all (_tmp5_);
		_tmp7_ = _tmp6_;
		gee_collection_add_all (G_TYPE_CHECK_INSTANCE_CAST (_tmp3_, GEE_TYPE_COLLECTION, GeeCollection), G_TYPE_CHECK_INSTANCE_CAST (_tmp7_, GEE_TYPE_COLLECTION, GeeCollection));
		_g_object_unref0 (_tmp7_);
	}
	_tmp8_ = geary_email_header_set_get_in_reply_to (G_TYPE_CHECK_INSTANCE_CAST (source, GEARY_TYPE_EMAIL_HEADER_SET, GearyEmailHeaderSet));
	_tmp9_ = _tmp8_;
	if (_tmp9_ != NULL) {
		{
			GeeList* _reply_id_list = NULL;
			GearyRFC822MessageIDList* _tmp10_;
			GearyRFC822MessageIDList* _tmp11_;
			GeeList* _tmp12_;
			gint _reply_id_size = 0;
			GeeList* _tmp13_;
			gint _tmp14_;
			gint _tmp15_;
			gint _reply_id_index = 0;
			_tmp10_ = geary_email_header_set_get_in_reply_to (G_TYPE_CHECK_INSTANCE_CAST (source, GEARY_TYPE_EMAIL_HEADER_SET, GearyEmailHeaderSet));
			_tmp11_ = _tmp10_;
			_tmp12_ = geary_rf_c822_message_id_list_get_all (_tmp11_);
			_reply_id_list = _tmp12_;
			_tmp13_ = _reply_id_list;
			_tmp14_ = gee_collection_get_size (G_TYPE_CHECK_INSTANCE_CAST (_tmp13_, GEE_TYPE_COLLECTION, GeeCollection));
			_tmp15_ = _tmp14_;
			_reply_id_size = _tmp15_;
			_reply_id_index = -1;
			while (TRUE) {
				gint _tmp16_;
				gint _tmp17_;
				GearyRFC822MessageID* reply_id = NULL;
				GeeList* _tmp18_;
				gpointer _tmp19_;
				GeeLinkedList* _tmp20_;
				GearyRFC822MessageID* _tmp21_;
				_reply_id_index = _reply_id_index + 1;
				_tmp16_ = _reply_id_index;
				_tmp17_ = _reply_id_size;
				if (!(_tmp16_ < _tmp17_)) {
					break;
				}
				_tmp18_ = _reply_id_list;
				_tmp19_ = gee_list_get (_tmp18_, _reply_id_index);
				reply_id = (GearyRFC822MessageID*) _tmp19_;
				_tmp20_ = list;
				_tmp21_ = reply_id;
				if (!gee_abstract_collection_contains (G_TYPE_CHECK_INSTANCE_CAST (_tmp20_, GEE_TYPE_ABSTRACT_COLLECTION, GeeAbstractCollection), _tmp21_)) {
					GeeLinkedList* _tmp22_;
					GearyRFC822MessageID* _tmp23_;
					_tmp22_ = list;
					_tmp23_ = reply_id;
					gee_abstract_collection_add (G_TYPE_CHECK_INSTANCE_CAST (_tmp22_, GEE_TYPE_ABSTRACT_COLLECTION, GeeAbstractCollection), _tmp23_);
				}
				_g_object_unref0 (reply_id);
			}
			_g_object_unref0 (_reply_id_list);
		}
	}
	_tmp24_ = geary_email_header_set_get_message_id (G_TYPE_CHECK_INSTANCE_CAST (source, GEARY_TYPE_EMAIL_HEADER_SET, GearyEmailHeaderSet));
	_tmp25_ = _tmp24_;
	if (_tmp25_ != NULL) {
		GeeLinkedList* _tmp26_;
		GearyRFC822MessageID* _tmp27_;
		GearyRFC822MessageID* _tmp28_;
		_tmp26_ = list;
		_tmp27_ = geary_email_header_set_get_message_id (G_TYPE_CHECK_INSTANCE_CAST (source, GEARY_TYPE_EMAIL_HEADER_SET, GearyEmailHeaderSet));
		_tmp28_ = _tmp27_;
		gee_abstract_collection_add (G_TYPE_CHECK_INSTANCE_CAST (_tmp26_, GEE_TYPE_ABSTRACT_COLLECTION, GeeAbstractCollection), _tmp28_);
	}
	_tmp29_ = list;
	_tmp30_ = geary_rf_c822_message_id_list_new (G_TYPE_CHECK_INSTANCE_CAST (_tmp29_, GEE_TYPE_COLLECTION, GeeCollection));
	result = _tmp30_;
	_g_object_unref0 (list);
	return result;
}

gchar*
geary_rf_c822_utils_email_addresses_for_reply (GearyRFC822MailboxAddresses* addresses,
                                               GearyRFC822TextFormat format)
{
	gchar* result;
	g_return_val_if_fail ((addresses == NULL) || GEARY_RF_C822_IS_MAILBOX_ADDRESSES (addresses), NULL);
	if (addresses == NULL) {
		gchar* _tmp0_;
		_tmp0_ = g_strdup ("");
		result = _tmp0_;
		return result;
	}
	switch (format) {
		case GEARY_RF_C822_TEXT_FORMAT_HTML:
		{
			gchar* _tmp1_;
			gchar* _tmp2_;
			gchar* _tmp3_;
			gchar* _tmp4_;
			_tmp1_ = geary_rf_c822_mailbox_addresses_to_full_display (addresses);
			_tmp2_ = _tmp1_;
			_tmp3_ = geary_html_escape_markup (_tmp2_);
			_tmp4_ = _tmp3_;
			_g_free0 (_tmp2_);
			result = _tmp4_;
			return result;
		}
		case GEARY_RF_C822_TEXT_FORMAT_PLAIN:
		{
			gchar* _tmp5_;
			_tmp5_ = geary_rf_c822_mailbox_addresses_to_full_display (addresses);
			result = _tmp5_;
			return result;
		}
		default:
		{
			g_assert_not_reached ();
		}
	}
}

/**
     * Obtains the best preview text from a plain or HTML string.
     *
     * The given string `text` should have UNIX encoded line endings (LF),
     * rather than RFC822 (CRLF). The string returned will will have had
     * its whitespace squashed.
     */
gchar*
geary_rf_c822_utils_to_preview_text (const gchar* text,
                                     GearyRFC822TextFormat format)
{
	gchar* preview = NULL;
	gchar* _tmp0_;
	const gchar* _tmp21_;
	gchar* _tmp22_;
	gchar* _tmp23_;
	gchar* _tmp24_;
	gchar* _tmp25_;
	gchar* result;
	_tmp0_ = g_strdup ("");
	preview = _tmp0_;
	if (format == GEARY_RF_C822_TEXT_FORMAT_PLAIN) {
		GString* buf = NULL;
		GString* _tmp1_;
		gchar** all_lines = NULL;
		gchar** _tmp2_;
		gchar** _tmp3_;
		gint all_lines_length1;
		gint _all_lines_size_;
		gboolean in_inline_pgp_header = FALSE;
		gchar** _tmp4_;
		gint _tmp4__length1;
		GString* _tmp17_;
		const gchar* _tmp18_;
		gchar* _tmp19_;
		_tmp1_ = g_string_new ("");
		buf = _tmp1_;
		_tmp3_ = _tmp2_ = g_strsplit (text, "\n", 0);
		all_lines = _tmp3_;
		all_lines_length1 = _vala_array_length (_tmp2_);
		_all_lines_size_ = all_lines_length1;
		in_inline_pgp_header = FALSE;
		_tmp4_ = all_lines;
		_tmp4__length1 = all_lines_length1;
		{
			gchar** line_collection = NULL;
			gint line_collection_length1 = 0;
			gint _line_collection_size_ = 0;
			gint line_it = 0;
			line_collection = _tmp4_;
			line_collection_length1 = _tmp4__length1;
			for (line_it = 0; line_it < line_collection_length1; line_it = line_it + 1) {
				gchar* _tmp5_;
				gchar* line = NULL;
				_tmp5_ = g_strdup (line_collection[line_it]);
				line = _tmp5_;
				{
					const gchar* _tmp7_;
					const gchar* _tmp8_;
					const gchar* _tmp9_;
					const gchar* _tmp10_;
					const gchar* _tmp11_;
					const gchar* _tmp12_;
					GString* _tmp14_;
					GString* _tmp15_;
					const gchar* _tmp16_;
					if (in_inline_pgp_header) {
						const gchar* _tmp6_;
						_tmp6_ = line;
						if (geary_string_is_empty (_tmp6_)) {
							in_inline_pgp_header = FALSE;
						}
						_g_free0 (line);
						continue;
					}
					_tmp7_ = line;
					if (g_str_has_prefix (_tmp7_, "-----BEGIN PGP SIGNED MESSAGE-----")) {
						in_inline_pgp_header = TRUE;
						_g_free0 (line);
						continue;
					}
					_tmp8_ = line;
					if (g_str_has_prefix (_tmp8_, ">")) {
						_g_free0 (line);
						continue;
					}
					_tmp9_ = line;
					if (g_str_has_prefix (_tmp9_, "--")) {
						_g_free0 (line);
						continue;
					}
					_tmp10_ = line;
					if (g_str_has_prefix (_tmp10_, "====")) {
						_g_free0 (line);
						continue;
					}
					_tmp11_ = line;
					if (g_str_has_prefix (_tmp11_, "~~~~")) {
						_g_free0 (line);
						continue;
					}
					_tmp12_ = line;
					if (geary_string_is_empty_or_whitespace (_tmp12_)) {
						GString* _tmp13_;
						_tmp13_ = buf;
						g_string_append (_tmp13_, "\n");
						_g_free0 (line);
						continue;
					}
					_tmp14_ = buf;
					g_string_append (_tmp14_, " ");
					_tmp15_ = buf;
					_tmp16_ = line;
					g_string_append (_tmp15_, _tmp16_);
					_g_free0 (line);
				}
			}
		}
		_tmp17_ = buf;
		_tmp18_ = _tmp17_->str;
		_tmp19_ = g_strdup (_tmp18_);
		_g_free0 (preview);
		preview = _tmp19_;
		all_lines = (_vala_array_free (all_lines, all_lines_length1, (GDestroyNotify) g_free), NULL);
		_g_string_free0 (buf);
	} else {
		if (format == GEARY_RF_C822_TEXT_FORMAT_HTML) {
			gchar* _tmp20_;
			_tmp20_ = geary_html_html_to_text (text, FALSE, GEARY_RF_C822_UTF8_CHARSET);
			_g_free0 (preview);
			preview = _tmp20_;
		}
	}
	_tmp21_ = preview;
	_tmp22_ = g_utf8_make_valid (_tmp21_, (gssize) -1);
	_tmp23_ = _tmp22_;
	_tmp24_ = geary_string_reduce_whitespace (_tmp23_);
	_tmp25_ = _tmp24_;
	_g_free0 (_tmp23_);
	result = _tmp25_;
	_g_free0 (preview);
	return result;
}

/**
     * Decodes RFC-822 long header lines and RFC 2047 encoded text headers.
     */
static void
_vala_GMimeParserOptions_free (GMimeParserOptions* self)
{
	g_boxed_free (g_mime_parser_options_get_type (), self);
}

gchar*
geary_rf_c822_utils_decode_rfc822_text_header_value (const gchar* rfc822)
{
	GMimeParserOptions* _tmp0_;
	GMimeParserOptions* _tmp1_;
	gchar* _tmp2_;
	gchar* _tmp3_;
	gchar* _tmp4_;
	gchar* _tmp5_;
	gchar* result;
	g_return_val_if_fail (rfc822 != NULL, NULL);
	_tmp0_ = geary_rf_c822_get_parser_options ();
	_tmp1_ = _tmp0_;
	_tmp2_ = g_mime_utils_header_unfold (rfc822);
	_tmp3_ = _tmp2_;
	_tmp4_ = g_mime_utils_header_decode_text (_tmp1_, _tmp3_);
	_tmp5_ = _tmp4_;
	_g_free0 (_tmp3_);
	__vala_GMimeParserOptions_free0 (_tmp1_);
	result = _tmp5_;
	return result;
}

static void
geary_rf_c822_utils_get_best_charset_data_free (gpointer _data)
{
	GearyRfC822UtilsGetBestCharsetData* _data_;
	_data_ = _data;
	_g_object_unref0 (_data_->cancellable);
	_g_free0 (_data_->result);
	g_slice_free (GearyRfC822UtilsGetBestCharsetData, _data_);
}

void
geary_rf_c822_utils_get_best_charset (GMimeStream* in_stream,
                                      GCancellable* cancellable,
                                      GAsyncReadyCallback _callback_,
                                      gpointer _user_data_)
{
	GearyRfC822UtilsGetBestCharsetData* _data_;
	GMimeStream* _tmp0_;
	GCancellable* _tmp1_;
	g_return_if_fail (G_TYPE_CHECK_INSTANCE_TYPE (in_stream, g_mime_stream_get_type ()));
	g_return_if_fail ((cancellable == NULL) || G_TYPE_CHECK_INSTANCE_TYPE (cancellable, g_cancellable_get_type ()));
	_data_ = g_slice_new0 (GearyRfC822UtilsGetBestCharsetData);
	_data_->_async_result = g_task_new (NULL, cancellable, _callback_, _user_data_);
	g_task_set_task_data (_data_->_async_result, _data_, geary_rf_c822_utils_get_best_charset_data_free);
	_tmp0_ = _g_object_ref0 (in_stream);
	_g_object_unref0 (_data_->in_stream);
	_data_->in_stream = _tmp0_;
	_tmp1_ = _g_object_ref0 (cancellable);
	_g_object_unref0 (_data_->cancellable);
	_data_->cancellable = _tmp1_;
	geary_rf_c822_utils_get_best_charset_co (_data_);
}

gchar*
geary_rf_c822_utils_get_best_charset_finish (GAsyncResult* _res_,
                                             GError** error)
{
	gchar* result;
	GearyRfC822UtilsGetBestCharsetData* _data_;
	_data_ = g_task_propagate_pointer (G_TASK (_res_), error);
	if (NULL == _data_) {
		return NULL;
	}
	result = _data_->result;
	_data_->result = NULL;
	return result;
}

/**
     * Uses a GMime.FilterBest to determine the best charset.
     *
     * This may require processing the entire stream, so occurs in a
     * background thread.
     */
static Block113Data*
block113_data_ref (Block113Data* _data113_)
{
	g_atomic_int_inc (&_data113_->_ref_count_);
	return _data113_;
}

static void
block113_data_unref (void * _userdata_)
{
	Block113Data* _data113_;
	_data113_ = (Block113Data*) _userdata_;
	if (g_atomic_int_dec_and_test (&_data113_->_ref_count_)) {
		_g_object_unref0 (_data113_->out_stream);
		_g_object_unref0 (_data113_->in_stream);
		g_slice_free (Block113Data, _data113_);
	}
}

static void
__lambda18_ (Block113Data* _data113_,
             GError** error)
{
	g_mime_stream_write_to_stream (_data113_->in_stream, G_TYPE_CHECK_INSTANCE_CAST (_data113_->out_stream, g_mime_stream_get_type (), GMimeStream));
	g_mime_stream_reset (_data113_->in_stream);
	g_mime_stream_close (G_TYPE_CHECK_INSTANCE_CAST (_data113_->out_stream, g_mime_stream_get_type (), GMimeStream));
}

static void
___lambda18__geary_nonblocking_concurrent_concurrent_callback (GCancellable* cancellable,
                                                               gpointer self,
                                                               GError** error)
{
	__lambda18_ (self, error);
}

static void
geary_rf_c822_utils_get_best_charset_ready (GObject* source_object,
                                            GAsyncResult* _res_,
                                            gpointer _user_data_)
{
	GearyRfC822UtilsGetBestCharsetData* _data_;
	_data_ = _user_data_;
	_data_->_source_object_ = source_object;
	_data_->_res_ = _res_;
	geary_rf_c822_utils_get_best_charset_co (_data_);
}

static gboolean
geary_rf_c822_utils_get_best_charset_co (GearyRfC822UtilsGetBestCharsetData* _data_)
{
	switch (_data_->_state_) {
		case 0:
		goto _state_0;
		case 1:
		goto _state_1;
		default:
		g_assert_not_reached ();
	}
	_state_0:
	_data_->_data113_ = g_slice_new0 (Block113Data);
	_data_->_data113_->_ref_count_ = 1;
	_g_object_unref0 (_data_->_data113_->in_stream);
	_data_->_data113_->in_stream = _data_->in_stream;
	_data_->_data113_->_async_data_ = _data_;
	_data_->_tmp0_ = (GMimeFilterBest*) g_mime_filter_best_new (GMIME_FILTER_BEST_CHARSET);
	_data_->filter = _data_->_tmp0_;
	_data_->_tmp1_ = (GMimeStreamNull*) g_mime_stream_null_new ();
	_data_->_tmp2_ = _data_->_tmp1_;
	_data_->_tmp3_ = (GMimeStreamFilter*) g_mime_stream_filter_new (G_TYPE_CHECK_INSTANCE_CAST (_data_->_tmp2_, g_mime_stream_get_type (), GMimeStream));
	_data_->_tmp4_ = _data_->_tmp3_;
	_g_object_unref0 (_data_->_tmp2_);
	_data_->_data113_->out_stream = _data_->_tmp4_;
	g_mime_stream_filter_add (_data_->_data113_->out_stream, G_TYPE_CHECK_INSTANCE_CAST (_data_->filter, g_mime_filter_get_type (), GMimeFilter));
	_data_->_tmp5_ = geary_nonblocking_concurrent_get_global ();
	_data_->_tmp6_ = _data_->_tmp5_;
	_data_->_state_ = 1;
	geary_nonblocking_concurrent_schedule_async (_data_->_tmp6_, ___lambda18__geary_nonblocking_concurrent_concurrent_callback, _data_->_data113_, _data_->cancellable, geary_rf_c822_utils_get_best_charset_ready, _data_);
	return FALSE;
	_state_1:
	geary_nonblocking_concurrent_schedule_finish (_data_->_tmp6_, _data_->_res_, &_data_->_inner_error0_);
	if (G_UNLIKELY (_data_->_inner_error0_ != NULL)) {
		g_task_return_error (_data_->_async_result, _data_->_inner_error0_);
		_g_object_unref0 (_data_->filter);
		block113_data_unref (_data_->_data113_);
		_data_->_data113_ = NULL;
		g_object_unref (_data_->_async_result);
		return FALSE;
	}
	_data_->_tmp7_ = g_mime_filter_best_charset (_data_->filter);
	_data_->_tmp8_ = g_strdup (_data_->_tmp7_);
	_data_->result = _data_->_tmp8_;
	_g_object_unref0 (_data_->filter);
	block113_data_unref (_data_->_data113_);
	_data_->_data113_ = NULL;
	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
geary_rf_c822_utils_get_best_encoding_data_free (gpointer _data)
{
	GearyRfC822UtilsGetBestEncodingData* _data_;
	_data_ = _data;
	_g_object_unref0 (_data_->cancellable);
	g_slice_free (GearyRfC822UtilsGetBestEncodingData, _data_);
}

void
geary_rf_c822_utils_get_best_encoding (GMimeStream* in_stream,
                                       GMimeEncodingConstraint constraint,
                                       GCancellable* cancellable,
                                       GAsyncReadyCallback _callback_,
                                       gpointer _user_data_)
{
	GearyRfC822UtilsGetBestEncodingData* _data_;
	GMimeStream* _tmp0_;
	GCancellable* _tmp1_;
	g_return_if_fail (G_TYPE_CHECK_INSTANCE_TYPE (in_stream, g_mime_stream_get_type ()));
	g_return_if_fail ((cancellable == NULL) || G_TYPE_CHECK_INSTANCE_TYPE (cancellable, g_cancellable_get_type ()));
	_data_ = g_slice_new0 (GearyRfC822UtilsGetBestEncodingData);
	_data_->_async_result = g_task_new (NULL, cancellable, _callback_, _user_data_);
	g_task_set_task_data (_data_->_async_result, _data_, geary_rf_c822_utils_get_best_encoding_data_free);
	_tmp0_ = _g_object_ref0 (in_stream);
	_g_object_unref0 (_data_->in_stream);
	_data_->in_stream = _tmp0_;
	_data_->constraint = constraint;
	_tmp1_ = _g_object_ref0 (cancellable);
	_g_object_unref0 (_data_->cancellable);
	_data_->cancellable = _tmp1_;
	geary_rf_c822_utils_get_best_encoding_co (_data_);
}

GMimeContentEncoding
geary_rf_c822_utils_get_best_encoding_finish (GAsyncResult* _res_,
                                              GError** error)
{
	GMimeContentEncoding result;
	GearyRfC822UtilsGetBestEncodingData* _data_;
	_data_ = g_task_propagate_pointer (G_TASK (_res_), error);
	if (NULL == _data_) {
		return 0;
	}
	result = _data_->result;
	return result;
}

/**
     * Uses a GMime.FilterBest to determine the best encoding.
     *
     * This may require processing the entire stream, so occurs in a
     * background thread.
     */
static Block114Data*
block114_data_ref (Block114Data* _data114_)
{
	g_atomic_int_inc (&_data114_->_ref_count_);
	return _data114_;
}

static void
block114_data_unref (void * _userdata_)
{
	Block114Data* _data114_;
	_data114_ = (Block114Data*) _userdata_;
	if (g_atomic_int_dec_and_test (&_data114_->_ref_count_)) {
		_g_object_unref0 (_data114_->out_stream);
		_g_object_unref0 (_data114_->in_stream);
		g_slice_free (Block114Data, _data114_);
	}
}

static void
__lambda19_ (Block114Data* _data114_,
             GError** error)
{
	g_mime_stream_write_to_stream (_data114_->in_stream, G_TYPE_CHECK_INSTANCE_CAST (_data114_->out_stream, g_mime_stream_get_type (), GMimeStream));
	g_mime_stream_reset (_data114_->in_stream);
	g_mime_stream_close (G_TYPE_CHECK_INSTANCE_CAST (_data114_->out_stream, g_mime_stream_get_type (), GMimeStream));
}

static void
___lambda19__geary_nonblocking_concurrent_concurrent_callback (GCancellable* cancellable,
                                                               gpointer self,
                                                               GError** error)
{
	__lambda19_ (self, error);
}

static void
geary_rf_c822_utils_get_best_encoding_ready (GObject* source_object,
                                             GAsyncResult* _res_,
                                             gpointer _user_data_)
{
	GearyRfC822UtilsGetBestEncodingData* _data_;
	_data_ = _user_data_;
	_data_->_source_object_ = source_object;
	_data_->_res_ = _res_;
	geary_rf_c822_utils_get_best_encoding_co (_data_);
}

static gboolean
geary_rf_c822_utils_get_best_encoding_co (GearyRfC822UtilsGetBestEncodingData* _data_)
{
	switch (_data_->_state_) {
		case 0:
		goto _state_0;
		case 1:
		goto _state_1;
		default:
		g_assert_not_reached ();
	}
	_state_0:
	_data_->_data114_ = g_slice_new0 (Block114Data);
	_data_->_data114_->_ref_count_ = 1;
	_g_object_unref0 (_data_->_data114_->in_stream);
	_data_->_data114_->in_stream = _data_->in_stream;
	_data_->_data114_->_async_data_ = _data_;
	_data_->_tmp0_ = (GMimeFilterBest*) g_mime_filter_best_new (GMIME_FILTER_BEST_ENCODING);
	_data_->filter = _data_->_tmp0_;
	_data_->_tmp1_ = (GMimeStreamNull*) g_mime_stream_null_new ();
	_data_->_tmp2_ = _data_->_tmp1_;
	_data_->_tmp3_ = (GMimeStreamFilter*) g_mime_stream_filter_new (G_TYPE_CHECK_INSTANCE_CAST (_data_->_tmp2_, g_mime_stream_get_type (), GMimeStream));
	_data_->_tmp4_ = _data_->_tmp3_;
	_g_object_unref0 (_data_->_tmp2_);
	_data_->_data114_->out_stream = _data_->_tmp4_;
	g_mime_stream_filter_add (_data_->_data114_->out_stream, G_TYPE_CHECK_INSTANCE_CAST (_data_->filter, g_mime_filter_get_type (), GMimeFilter));
	_data_->_tmp5_ = geary_nonblocking_concurrent_get_global ();
	_data_->_tmp6_ = _data_->_tmp5_;
	_data_->_state_ = 1;
	geary_nonblocking_concurrent_schedule_async (_data_->_tmp6_, ___lambda19__geary_nonblocking_concurrent_concurrent_callback, _data_->_data114_, _data_->cancellable, geary_rf_c822_utils_get_best_encoding_ready, _data_);
	return FALSE;
	_state_1:
	geary_nonblocking_concurrent_schedule_finish (_data_->_tmp6_, _data_->_res_, &_data_->_inner_error0_);
	if (G_UNLIKELY (_data_->_inner_error0_ != NULL)) {
		g_task_return_error (_data_->_async_result, _data_->_inner_error0_);
		_g_object_unref0 (_data_->filter);
		block114_data_unref (_data_->_data114_);
		_data_->_data114_ = NULL;
		g_object_unref (_data_->_async_result);
		return FALSE;
	}
	_data_->result = g_mime_filter_best_encoding (_data_->filter, _data_->constraint);
	_g_object_unref0 (_data_->filter);
	block114_data_unref (_data_->_data114_);
	_data_->_data114_ = NULL;
	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;
}

/**
     * Uses the best-possible transfer of bytes from the Memory.Buffer to the GMime.StreamMem object.
     * The StreamMem object should be destroyed *before* the Memory.Buffer object, since this method
     * will use unowned variants whenever possible.
     */
GMimeStreamMem*
geary_rf_c822_utils_create_stream_mem (GearyMemoryBuffer* buffer)
{
	GearyMemoryUnownedByteArrayBuffer* unowned_bytes_array_buffer = NULL;
	GearyMemoryUnownedByteArrayBuffer* _tmp0_;
	GearyMemoryUnownedByteArrayBuffer* _tmp1_;
	GearyMemoryUnownedBytesBuffer* unowned_bytes_buffer = NULL;
	GearyMemoryUnownedBytesBuffer* _tmp6_;
	GearyMemoryUnownedBytesBuffer* _tmp7_;
	gint _tmp12_ = 0;
	guint8* _tmp13_;
	guint8* _tmp14_;
	gint _tmp14__length1;
	GMimeStreamMem* _tmp15_;
	GMimeStreamMem* _tmp16_;
	GMimeStreamMem* result;
	g_return_val_if_fail (GEARY_MEMORY_IS_BUFFER (buffer), NULL);
	_tmp0_ = _g_object_ref0 (GEARY_MEMORY_IS_UNOWNED_BYTE_ARRAY_BUFFER (buffer) ? ((GearyMemoryUnownedByteArrayBuffer*) buffer) : NULL);
	unowned_bytes_array_buffer = _tmp0_;
	_tmp1_ = unowned_bytes_array_buffer;
	if (_tmp1_ != NULL) {
		GMimeStreamMem* stream = NULL;
		GMimeStreamMem* _tmp2_;
		GMimeStreamMem* _tmp3_;
		GearyMemoryUnownedByteArrayBuffer* _tmp4_;
		GByteArray* _tmp5_;
		_tmp2_ = (GMimeStreamMem*) g_mime_stream_mem_new ();
		stream = _tmp2_;
		_tmp3_ = stream;
		_tmp4_ = unowned_bytes_array_buffer;
		_tmp5_ = geary_memory_unowned_byte_array_buffer_to_unowned_byte_array (_tmp4_);
		g_mime_stream_mem_set_byte_array (_tmp3_, _tmp5_);
		result = stream;
		_g_object_unref0 (unowned_bytes_array_buffer);
		return result;
	}
	_tmp6_ = _g_object_ref0 (GEARY_MEMORY_IS_UNOWNED_BYTES_BUFFER (buffer) ? ((GearyMemoryUnownedBytesBuffer*) buffer) : NULL);
	unowned_bytes_buffer = _tmp6_;
	_tmp7_ = unowned_bytes_buffer;
	if (_tmp7_ != NULL) {
		GearyMemoryUnownedBytesBuffer* _tmp8_;
		gint _tmp9_ = 0;
		guint8* _tmp10_;
		GMimeStreamMem* _tmp11_;
		_tmp8_ = unowned_bytes_buffer;
		_tmp10_ = geary_memory_unowned_bytes_buffer_to_unowned_uint8_array (_tmp8_, &_tmp9_);
		_tmp11_ = (GMimeStreamMem*) g_mime_stream_mem_new_with_buffer (_tmp10_, _tmp9_);
		result = _tmp11_;
		_g_object_unref0 (unowned_bytes_buffer);
		_g_object_unref0 (unowned_bytes_array_buffer);
		return result;
	}
	_tmp13_ = geary_memory_buffer_get_uint8_array (buffer, &_tmp12_);
	_tmp14_ = _tmp13_;
	_tmp14__length1 = _tmp12_;
	_tmp15_ = (GMimeStreamMem*) g_mime_stream_mem_new_with_buffer (_tmp14_, _tmp12_);
	_tmp16_ = _tmp15_;
	_tmp14_ = (g_free (_tmp14_), NULL);
	result = _tmp16_;
	_g_object_unref0 (unowned_bytes_buffer);
	_g_object_unref0 (unowned_bytes_array_buffer);
	return result;
}

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

gboolean
geary_rf_c822_utils_comp_char_arr_slice (guint8* array,
                                         gint array_length1,
                                         guint start,
                                         const gchar* comp)
{
	gboolean result;
	g_return_val_if_fail (comp != NULL, FALSE);
	{
		gint i = 0;
		i = 0;
		{
			gboolean _tmp0_ = FALSE;
			_tmp0_ = TRUE;
			while (TRUE) {
				gint _tmp2_;
				gint _tmp3_;
				guint8 _tmp4_;
				if (!_tmp0_) {
					gint _tmp1_;
					_tmp1_ = i;
					i = _tmp1_ + 1;
				}
				_tmp0_ = FALSE;
				_tmp2_ = strlen (comp);
				_tmp3_ = _tmp2_;
				if (!(i < _tmp3_)) {
					break;
				}
				_tmp4_ = array[start + i];
				if (_tmp4_ != ((guint8) string_get (comp, (glong) i))) {
					result = FALSE;
					return result;
				}
			}
		}
	}
	result = TRUE;
	return result;
}

void
geary_rf_c822_utils_remove_address (GeeList* addresses,
                                    GearyRFC822MailboxAddress* address,
                                    gboolean empty_ok)
{
	g_return_if_fail (G_TYPE_CHECK_INSTANCE_TYPE (addresses, GEE_TYPE_LIST));
	g_return_if_fail (GEARY_RF_C822_IS_MAILBOX_ADDRESS (address));
	{
		gint i = 0;
		i = 0;
		{
			gboolean _tmp0_ = FALSE;
			_tmp0_ = TRUE;
			while (TRUE) {
				gint _tmp2_;
				gint _tmp3_;
				gboolean _tmp4_ = FALSE;
				gpointer _tmp5_;
				GearyRFC822MailboxAddress* _tmp6_;
				gboolean _tmp7_;
				if (!_tmp0_) {
					gint _tmp1_;
					i = i + 1;
					_tmp1_ = i;
				}
				_tmp0_ = FALSE;
				_tmp2_ = gee_collection_get_size (G_TYPE_CHECK_INSTANCE_CAST (addresses, GEE_TYPE_COLLECTION, GeeCollection));
				_tmp3_ = _tmp2_;
				if (!(i < _tmp3_)) {
					break;
				}
				_tmp5_ = gee_list_get (addresses, i);
				_tmp6_ = (GearyRFC822MailboxAddress*) _tmp5_;
				_tmp7_ = gee_hashable_equal_to (G_TYPE_CHECK_INSTANCE_CAST (_tmp6_, GEE_TYPE_HASHABLE, GeeHashable), address);
				_g_object_unref0 (_tmp6_);
				if (_tmp7_) {
					gboolean _tmp8_ = FALSE;
					if (empty_ok) {
						_tmp8_ = TRUE;
					} else {
						gint _tmp9_;
						gint _tmp10_;
						_tmp9_ = gee_collection_get_size (G_TYPE_CHECK_INSTANCE_CAST (addresses, GEE_TYPE_COLLECTION, GeeCollection));
						_tmp10_ = _tmp9_;
						_tmp8_ = _tmp10_ > 1;
					}
					_tmp4_ = _tmp8_;
				} else {
					_tmp4_ = FALSE;
				}
				if (_tmp4_) {
					gint _tmp11_;
					gpointer _tmp12_;
					GearyRFC822MailboxAddress* _tmp13_;
					_tmp11_ = i;
					i = _tmp11_ - 1;
					_tmp12_ = gee_list_remove_at (addresses, _tmp11_);
					_tmp13_ = (GearyRFC822MailboxAddress*) _tmp12_;
					_g_object_unref0 (_tmp13_);
				}
			}
		}
	}
}

static Block115Data*
block115_data_ref (Block115Data* _data115_)
{
	g_atomic_int_inc (&_data115_->_ref_count_);
	return _data115_;
}

static void
block115_data_unref (void * _userdata_)
{
	Block115Data* _data115_;
	_data115_ = (Block115Data*) _userdata_;
	if (g_atomic_int_dec_and_test (&_data115_->_ref_count_)) {
		_g_object_unref0 (_data115_->email);
		g_slice_free (Block115Data, _data115_);
	}
}

static gboolean
___lambda178_ (Block115Data* _data115_,
               GearyRFC822MailboxAddress* a)
{
	GearyRFC822MailboxAddresses* _tmp0_;
	GearyRFC822MailboxAddresses* _tmp1_;
	GeeList* _tmp2_;
	GeeList* _tmp3_;
	gboolean _tmp4_;
	gboolean result;
	g_return_val_if_fail (GEARY_RF_C822_IS_MAILBOX_ADDRESS (a), FALSE);
	_tmp0_ = geary_email_header_set_get_from (G_TYPE_CHECK_INSTANCE_CAST (_data115_->email, GEARY_TYPE_EMAIL_HEADER_SET, GearyEmailHeaderSet));
	_tmp1_ = _tmp0_;
	_tmp2_ = geary_rf_c822_mailbox_addresses_get_all (_tmp1_);
	_tmp3_ = _tmp2_;
	_tmp4_ = gee_collection_contains (G_TYPE_CHECK_INSTANCE_CAST (_tmp3_, GEE_TYPE_COLLECTION, GeeCollection), a);
	_g_object_unref0 (_tmp3_);
	result = _tmp4_;
	return result;
}

static gboolean
____lambda178__gee_predicate (gconstpointer g,
                              gpointer self)
{
	gboolean result;
	result = ___lambda178_ (self, (GearyRFC822MailboxAddress*) g);
	return result;
}

gboolean
geary_rf_c822_utils_email_is_from_sender (GearyEmail* email,
                                          GeeList* sender_addresses)
{
	Block115Data* _data115_;
	GearyEmail* _tmp0_;
	gboolean ret = FALSE;
	gboolean _tmp1_ = FALSE;
	gboolean result;
	g_return_val_if_fail (GEARY_IS_EMAIL (email), FALSE);
	g_return_val_if_fail ((sender_addresses == NULL) || G_TYPE_CHECK_INSTANCE_TYPE (sender_addresses, GEE_TYPE_LIST), FALSE);
	_data115_ = g_slice_new0 (Block115Data);
	_data115_->_ref_count_ = 1;
	_tmp0_ = _g_object_ref0 (email);
	_g_object_unref0 (_data115_->email);
	_data115_->email = _tmp0_;
	ret = FALSE;
	if (sender_addresses != NULL) {
		GearyRFC822MailboxAddresses* _tmp2_;
		GearyRFC822MailboxAddresses* _tmp3_;
		_tmp2_ = geary_email_header_set_get_from (G_TYPE_CHECK_INSTANCE_CAST (_data115_->email, GEARY_TYPE_EMAIL_HEADER_SET, GearyEmailHeaderSet));
		_tmp3_ = _tmp2_;
		_tmp1_ = _tmp3_ != NULL;
	} else {
		_tmp1_ = FALSE;
	}
	if (_tmp1_) {
		GearyIterable* _tmp4_;
		GearyIterable* _tmp5_;
		_tmp4_ = geary_traverse (GEARY_RF_C822_TYPE_MAILBOX_ADDRESS, (GBoxedCopyFunc) g_object_ref, (GDestroyNotify) g_object_unref, G_TYPE_CHECK_INSTANCE_CAST (sender_addresses, GEE_TYPE_ITERABLE, GeeIterable));
		_tmp5_ = _tmp4_;
		ret = geary_iterable_any (_tmp5_, ____lambda178__gee_predicate, block115_data_ref (_data115_), block115_data_unref);
		_g_object_unref0 (_tmp5_);
	}
	result = ret;
	block115_data_unref (_data115_);
	_data115_ = NULL;
	return result;
}

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

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

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

