/* geary-endpoint.c generated by valac 0.56.19, the Vala compiler
 * generated from geary-endpoint.vala, do not modify */

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

#if !defined(VALA_STRICT_C)
#if !defined(__clang__) && defined(__GNUC__) && (__GNUC__ >= 14)
#pragma GCC diagnostic warning "-Wincompatible-pointer-types"
#elif defined(__clang__) && (__clang_major__ >= 16)
#pragma clang diagnostic ignored "-Wincompatible-function-pointer-types"
#pragma clang diagnostic ignored "-Wincompatible-pointer-types"
#endif
#endif

enum  {
	GEARY_ENDPOINT_0_PROPERTY,
	GEARY_ENDPOINT_REMOTE_PROPERTY,
	GEARY_ENDPOINT_CONNECTIVITY_PROPERTY,
	GEARY_ENDPOINT_TIMEOUT_SEC_PROPERTY,
	GEARY_ENDPOINT_TLS_METHOD_PROPERTY,
	GEARY_ENDPOINT_TLS_VALIDATION_WARNINGS_PROPERTY,
	GEARY_ENDPOINT_UNTRUSTED_CERTIFICATE_PROPERTY,
	GEARY_ENDPOINT_NUM_PROPERTIES
};
static GParamSpec* geary_endpoint_properties[GEARY_ENDPOINT_NUM_PROPERTIES];
#define _g_object_unref0(var) ((var == NULL) ? NULL : (var = (g_object_unref (var), NULL)))
#define _g_error_free0(var) ((var == NULL) ? NULL : (var = (g_error_free (var), NULL)))
typedef struct _GearyEndpointConnectAsyncData GearyEndpointConnectAsyncData;
typedef struct _GearyEndpointStarttlsHandshakeAsyncData GearyEndpointStarttlsHandshakeAsyncData;
#define _g_free0(var) (var = (g_free (var), NULL))
#define _g_string_free0(var) ((var == NULL) ? NULL : (var = (g_string_free (var, TRUE), NULL)))
typedef struct _Block4Data Block4Data;
enum  {
	GEARY_ENDPOINT_UNTRUSTED_HOST_SIGNAL,
	GEARY_ENDPOINT_NUM_SIGNALS
};
static guint geary_endpoint_signals[GEARY_ENDPOINT_NUM_SIGNALS] = {0};

struct _GearyEndpointPrivate {
	GSocketConnectable* _remote;
	GearyConnectivityManager* _connectivity;
	guint _timeout_sec;
	GearyTlsNegotiationMethod _tls_method;
	GTlsCertificateFlags _tls_validation_warnings;
	GTlsCertificate* _untrusted_certificate;
	GSocketClient* socket_client;
};

struct _GearyEndpointConnectAsyncData {
	int _state_;
	GObject* _source_object_;
	GAsyncResult* _res_;
	GTask* _async_result;
	GearyEndpoint* self;
	GCancellable* cancellable;
	GSocketConnection* result;
	GSocketClient* client;
	GSocketClient* _tmp0_;
	GError* connect_error;
	GSocketConnection* _tmp1_;
	GSocketClient* _tmp2_;
	GSocketConnectable* _tmp3_;
	GSocketConnection* _tmp4_;
	GSocketConnection* _tmp5_;
	GError* err;
	GError* _tmp6_;
	GError* _tmp7_;
	GSocketAddressEnumerator* addrs;
	GSocketConnectable* _tmp8_;
	GSocketAddressEnumerator* _tmp9_;
	GSocketAddress* addr;
	GSocketAddressEnumerator* _tmp10_;
	GSocketAddress* _tmp11_;
	GSocketAddress* _tmp12_;
	GInetSocketAddress* inet_addr;
	GSocketAddress* _tmp13_;
	GInetSocketAddress* _tmp14_;
	GInetSocketAddress* _tmp15_;
	GSocketConnection* _tmp16_;
	GSocketClient* _tmp17_;
	GInetSocketAddress* _tmp18_;
	GInetAddress* _tmp19_;
	GInetAddress* _tmp20_;
	GInetSocketAddress* _tmp21_;
	guint _tmp22_;
	guint _tmp23_;
	GInetSocketAddress* _tmp24_;
	GInetSocketAddress* _tmp25_;
	GSocketConnection* _tmp26_;
	GSocketConnection* _tmp27_;
	GSocketConnection* _tmp28_;
	GSocketAddress* _tmp29_;
	GSocketAddressEnumerator* _tmp30_;
	GSocketAddress* _tmp31_;
	GSocketAddress* _tmp32_;
	GError* _tmp33_;
	GError* _tmp34_;
	GError* _inner_error0_;
};

struct _GearyEndpointStarttlsHandshakeAsyncData {
	int _state_;
	GObject* _source_object_;
	GAsyncResult* _res_;
	GTask* _async_result;
	GearyEndpoint* self;
	GIOStream* base_stream;
	GCancellable* cancellable;
	GTlsClientConnection* result;
	GTlsClientConnection* tls_cx;
	GSocketConnectable* _tmp0_;
	GTlsClientConnection* _tmp1_;
	GTlsClientConnection* _tmp2_;
	GTlsClientConnection* _tmp3_;
	GError* _inner_error0_;
};

struct _Block4Data {
	int _ref_count_;
	GearyEndpoint* self;
	GTlsConnection* cx;
	GTlsCertificate* cert;
	GTlsCertificateFlags flags;
};

static gint GearyEndpoint_private_offset;
static gpointer geary_endpoint_parent_class = NULL;
GTlsDatabase* geary_endpoint_default_tls_database = NULL;

static void geary_endpoint_set_remote (GearyEndpoint* self,
                                GSocketConnectable* value);
static void geary_endpoint_set_connectivity (GearyEndpoint* self,
                                      GearyConnectivityManager* value);
static void geary_endpoint_set_timeout_sec (GearyEndpoint* self,
                                     guint value);
static void geary_endpoint_set_tls_method (GearyEndpoint* self,
                                    GearyTlsNegotiationMethod value);
static void geary_endpoint_set_tls_validation_warnings (GearyEndpoint* self,
                                                 GTlsCertificateFlags value);
static void geary_endpoint_set_untrusted_certificate (GearyEndpoint* self,
                                               GTlsCertificate* value);
static void geary_endpoint_connect_async_data_free (gpointer _data);
static gboolean geary_endpoint_connect_async_co (GearyEndpointConnectAsyncData* _data_);
static GSocketClient* geary_endpoint_get_socket_client (GearyEndpoint* self);
static void geary_endpoint_connect_async_ready (GObject* source_object,
                                         GAsyncResult* _res_,
                                         gpointer _user_data_);
static void geary_endpoint_starttls_handshake_async_data_free (gpointer _data);
static gboolean geary_endpoint_starttls_handshake_async_co (GearyEndpointStarttlsHandshakeAsyncData* _data_);
static void geary_endpoint_prepare_tls_cx (GearyEndpoint* self,
                                    GTlsClientConnection* tls_cx);
static void geary_endpoint_starttls_handshake_async_ready (GObject* source_object,
                                                    GAsyncResult* _res_,
                                                    gpointer _user_data_);
static void geary_endpoint_on_socket_client_event (GearyEndpoint* self,
                                            GSocketClientEvent event,
                                            GSocketConnectable* connectable,
                                            GIOStream* ios);
static void _geary_endpoint_on_socket_client_event_g_socket_client_event (GSocketClient* _sender,
                                                                   GSocketClientEvent event,
                                                                   GSocketConnectable* connectable,
                                                                   GIOStream* connection,
                                                                   gpointer self);
static gboolean geary_endpoint_on_accept_certificate (GearyEndpoint* self,
                                               GTlsConnection* cx,
                                               GTlsCertificate* cert,
                                               GTlsCertificateFlags flags);
static gboolean _geary_endpoint_on_accept_certificate_g_tls_connection_accept_certificate (GTlsConnection* _sender,
                                                                                    GTlsCertificate* peer_cert,
                                                                                    GTlsCertificateFlags errors,
                                                                                    gpointer self);
static void geary_endpoint_report_tls_warnings (GearyEndpoint* self,
                                         GTlsConnection* cx,
                                         GTlsCertificate* cert,
                                         GTlsCertificateFlags warnings);
static gchar* geary_endpoint_tls_flags_to_string (GearyEndpoint* self,
                                           GTlsCertificateFlags flags);
static Block4Data* block4_data_ref (Block4Data* _data4_);
static void block4_data_unref (void * _userdata_);
static gboolean __lambda47_ (Block4Data* _data4_);
static gboolean ___lambda47__gsource_func (gpointer self);
static void geary_endpoint_finalize (GObject * obj);
static GType geary_endpoint_get_type_once (void);
static void _vala_geary_endpoint_get_property (GObject * object,
                                        guint property_id,
                                        GValue * value,
                                        GParamSpec * pspec);
static void _vala_geary_endpoint_set_property (GObject * object,
                                        guint property_id,
                                        const GValue * value,
                                        GParamSpec * pspec);

static inline gpointer
geary_endpoint_get_instance_private (GearyEndpoint* self)
{
	return G_STRUCT_MEMBER_P (self, GearyEndpoint_private_offset);
}

/** Returns {@link GLib.TlsCertificateFlags} as a string. */
gchar*
geary_endpoint_tls_flag_to_string (GTlsCertificateFlags flag)
{
	gchar* result;
	switch (flag) {
		case G_TLS_CERTIFICATE_BAD_IDENTITY:
		{
			gchar* _tmp0_;
			_tmp0_ = g_strdup ("BAD_IDENTITY");
			result = _tmp0_;
			return result;
		}
		case G_TLS_CERTIFICATE_EXPIRED:
		{
			gchar* _tmp1_;
			_tmp1_ = g_strdup ("EXPIRED");
			result = _tmp1_;
			return result;
		}
		case G_TLS_CERTIFICATE_GENERIC_ERROR:
		{
			gchar* _tmp2_;
			_tmp2_ = g_strdup ("GENERIC_ERROR");
			result = _tmp2_;
			return result;
		}
		case G_TLS_CERTIFICATE_INSECURE:
		{
			gchar* _tmp3_;
			_tmp3_ = g_strdup ("INSECURE");
			result = _tmp3_;
			return result;
		}
		case G_TLS_CERTIFICATE_NOT_ACTIVATED:
		{
			gchar* _tmp4_;
			_tmp4_ = g_strdup ("NOT_ACTIVATED");
			result = _tmp4_;
			return result;
		}
		case G_TLS_CERTIFICATE_REVOKED:
		{
			gchar* _tmp5_;
			_tmp5_ = g_strdup ("REVOKED");
			result = _tmp5_;
			return result;
		}
		case G_TLS_CERTIFICATE_UNKNOWN_CA:
		{
			gchar* _tmp6_;
			_tmp6_ = g_strdup ("UNKNOWN_CA");
			result = _tmp6_;
			return result;
		}
		default:
		{
			gchar* _tmp7_;
			_tmp7_ = g_strdup_printf ("(unknown=%Xh)", (guint) flag);
			result = _tmp7_;
			return result;
		}
	}
}

GSocketConnectable*
geary_endpoint_get_remote (GearyEndpoint* self)
{
	GSocketConnectable* result;
	GSocketConnectable* _tmp0_;
	g_return_val_if_fail (GEARY_IS_ENDPOINT (self), NULL);
	_tmp0_ = self->priv->_remote;
	result = _tmp0_;
	return result;
}

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

static void
geary_endpoint_set_remote (GearyEndpoint* self,
                           GSocketConnectable* value)
{
	GSocketConnectable* old_value;
	g_return_if_fail (GEARY_IS_ENDPOINT (self));
	old_value = geary_endpoint_get_remote (self);
	if (old_value != value) {
		GSocketConnectable* _tmp0_;
		_tmp0_ = _g_object_ref0 (value);
		_g_object_unref0 (self->priv->_remote);
		self->priv->_remote = _tmp0_;
		g_object_notify_by_pspec ((GObject *) self, geary_endpoint_properties[GEARY_ENDPOINT_REMOTE_PROPERTY]);
	}
}

GearyConnectivityManager*
geary_endpoint_get_connectivity (GearyEndpoint* self)
{
	GearyConnectivityManager* result;
	GearyConnectivityManager* _tmp0_;
	g_return_val_if_fail (GEARY_IS_ENDPOINT (self), NULL);
	_tmp0_ = self->priv->_connectivity;
	result = _tmp0_;
	return result;
}

static void
geary_endpoint_set_connectivity (GearyEndpoint* self,
                                 GearyConnectivityManager* value)
{
	GearyConnectivityManager* old_value;
	g_return_if_fail (GEARY_IS_ENDPOINT (self));
	old_value = geary_endpoint_get_connectivity (self);
	if (old_value != value) {
		GearyConnectivityManager* _tmp0_;
		_tmp0_ = _g_object_ref0 (value);
		_g_object_unref0 (self->priv->_connectivity);
		self->priv->_connectivity = _tmp0_;
		g_object_notify_by_pspec ((GObject *) self, geary_endpoint_properties[GEARY_ENDPOINT_CONNECTIVITY_PROPERTY]);
	}
}

guint
geary_endpoint_get_timeout_sec (GearyEndpoint* self)
{
	guint result;
	g_return_val_if_fail (GEARY_IS_ENDPOINT (self), 0U);
	result = self->priv->_timeout_sec;
	return result;
}

static void
geary_endpoint_set_timeout_sec (GearyEndpoint* self,
                                guint value)
{
	guint old_value;
	g_return_if_fail (GEARY_IS_ENDPOINT (self));
	old_value = geary_endpoint_get_timeout_sec (self);
	if (old_value != value) {
		self->priv->_timeout_sec = value;
		g_object_notify_by_pspec ((GObject *) self, geary_endpoint_properties[GEARY_ENDPOINT_TIMEOUT_SEC_PROPERTY]);
	}
}

GearyTlsNegotiationMethod
geary_endpoint_get_tls_method (GearyEndpoint* self)
{
	GearyTlsNegotiationMethod result;
	g_return_val_if_fail (GEARY_IS_ENDPOINT (self), 0);
	result = self->priv->_tls_method;
	return result;
}

static void
geary_endpoint_set_tls_method (GearyEndpoint* self,
                               GearyTlsNegotiationMethod value)
{
	GearyTlsNegotiationMethod old_value;
	g_return_if_fail (GEARY_IS_ENDPOINT (self));
	old_value = geary_endpoint_get_tls_method (self);
	if (old_value != value) {
		self->priv->_tls_method = value;
		g_object_notify_by_pspec ((GObject *) self, geary_endpoint_properties[GEARY_ENDPOINT_TLS_METHOD_PROPERTY]);
	}
}

GTlsCertificateFlags
geary_endpoint_get_tls_validation_warnings (GearyEndpoint* self)
{
	GTlsCertificateFlags result;
	g_return_val_if_fail (GEARY_IS_ENDPOINT (self), 0U);
	result = self->priv->_tls_validation_warnings;
	return result;
}

static void
geary_endpoint_set_tls_validation_warnings (GearyEndpoint* self,
                                            GTlsCertificateFlags value)
{
	GTlsCertificateFlags old_value;
	g_return_if_fail (GEARY_IS_ENDPOINT (self));
	old_value = geary_endpoint_get_tls_validation_warnings (self);
	if (old_value != value) {
		self->priv->_tls_validation_warnings = value;
		g_object_notify_by_pspec ((GObject *) self, geary_endpoint_properties[GEARY_ENDPOINT_TLS_VALIDATION_WARNINGS_PROPERTY]);
	}
}

GTlsCertificate*
geary_endpoint_get_untrusted_certificate (GearyEndpoint* self)
{
	GTlsCertificate* result;
	GTlsCertificate* _tmp0_;
	g_return_val_if_fail (GEARY_IS_ENDPOINT (self), NULL);
	_tmp0_ = self->priv->_untrusted_certificate;
	result = _tmp0_;
	return result;
}

static void
geary_endpoint_set_untrusted_certificate (GearyEndpoint* self,
                                          GTlsCertificate* value)
{
	GTlsCertificate* old_value;
	g_return_if_fail (GEARY_IS_ENDPOINT (self));
	old_value = geary_endpoint_get_untrusted_certificate (self);
	if (old_value != value) {
		GTlsCertificate* _tmp0_;
		_tmp0_ = _g_object_ref0 (value);
		_g_object_unref0 (self->priv->_untrusted_certificate);
		self->priv->_untrusted_certificate = _tmp0_;
		g_object_notify_by_pspec ((GObject *) self, geary_endpoint_properties[GEARY_ENDPOINT_UNTRUSTED_CERTIFICATE_PROPERTY]);
	}
}

GearyEndpoint*
geary_endpoint_construct (GType object_type,
                          GSocketConnectable* remote,
                          GearyTlsNegotiationMethod method,
                          guint timeout_sec)
{
	GearyEndpoint * self = NULL;
	GSocketConnectable* _tmp0_;
	GearyConnectivityManager* _tmp1_;
	GearyConnectivityManager* _tmp2_;
	g_return_val_if_fail (G_TYPE_CHECK_INSTANCE_TYPE (remote, g_socket_connectable_get_type ()), NULL);
	self = (GearyEndpoint*) geary_base_object_construct (object_type);
	geary_endpoint_set_remote (self, remote);
	_tmp0_ = self->priv->_remote;
	_tmp1_ = geary_connectivity_manager_new (G_TYPE_CHECK_INSTANCE_CAST (G_TYPE_CHECK_INSTANCE_CAST (_tmp0_, g_network_address_get_type (), GNetworkAddress), g_socket_connectable_get_type (), GSocketConnectable));
	_tmp2_ = _tmp1_;
	geary_endpoint_set_connectivity (self, _tmp2_);
	_g_object_unref0 (_tmp2_);
	geary_endpoint_set_timeout_sec (self, timeout_sec);
	geary_endpoint_set_tls_method (self, method);
	return self;
}

GearyEndpoint*
geary_endpoint_new (GSocketConnectable* remote,
                    GearyTlsNegotiationMethod method,
                    guint timeout_sec)
{
	return geary_endpoint_construct (GEARY_TYPE_ENDPOINT, remote, method, timeout_sec);
}

static void
geary_endpoint_connect_async_data_free (gpointer _data)
{
	GearyEndpointConnectAsyncData* _data_;
	_data_ = _data;
	_g_object_unref0 (_data_->cancellable);
	_g_object_unref0 (_data_->result);
	_g_object_unref0 (_data_->self);
	g_slice_free (GearyEndpointConnectAsyncData, _data_);
}

void
geary_endpoint_connect_async (GearyEndpoint* self,
                              GCancellable* cancellable,
                              GAsyncReadyCallback _callback_,
                              gpointer _user_data_)
{
	GearyEndpointConnectAsyncData* _data_;
	GearyEndpoint* _tmp0_;
	GCancellable* _tmp1_;
	g_return_if_fail (GEARY_IS_ENDPOINT (self));
	g_return_if_fail ((cancellable == NULL) || G_TYPE_CHECK_INSTANCE_TYPE (cancellable, g_cancellable_get_type ()));
	_data_ = g_slice_new0 (GearyEndpointConnectAsyncData);
	_data_->_async_result = g_task_new (G_OBJECT (self), cancellable, _callback_, _user_data_);
	g_task_set_task_data (_data_->_async_result, _data_, geary_endpoint_connect_async_data_free);
	_tmp0_ = _g_object_ref0 (self);
	_data_->self = _tmp0_;
	_tmp1_ = _g_object_ref0 (cancellable);
	_g_object_unref0 (_data_->cancellable);
	_data_->cancellable = _tmp1_;
	geary_endpoint_connect_async_co (_data_);
}

GSocketConnection*
geary_endpoint_connect_finish (GearyEndpoint* self,
                               GAsyncResult* _res_,
                               GError** error)
{
	GSocketConnection* result;
	GearyEndpointConnectAsyncData* _data_;
	_data_ = g_task_propagate_pointer (G_TASK (_res_), error);
	if (NULL == _data_) {
		return NULL;
	}
	result = _data_->result;
	_data_->result = NULL;
	return result;
}

static void
geary_endpoint_connect_async_ready (GObject* source_object,
                                    GAsyncResult* _res_,
                                    gpointer _user_data_)
{
	GearyEndpointConnectAsyncData* _data_;
	_data_ = _user_data_;
	_data_->_source_object_ = source_object;
	_data_->_res_ = _res_;
	geary_endpoint_connect_async_co (_data_);
}

static gpointer
_g_error_copy0 (gpointer self)
{
	return self ? g_error_copy (self) : NULL;
}

static gboolean
geary_endpoint_connect_async_co (GearyEndpointConnectAsyncData* _data_)
{
	switch (_data_->_state_) {
		case 0:
		goto _state_0;
		case 1:
		goto _state_1;
		case 2:
		goto _state_2;
		case 3:
		goto _state_3;
		case 4:
		goto _state_4;
		default:
		g_assert_not_reached ();
	}
	_state_0:
	_data_->_tmp0_ = geary_endpoint_get_socket_client (_data_->self);
	_data_->client = _data_->_tmp0_;
	_data_->connect_error = NULL;
	{
		_data_->_tmp2_ = _data_->client;
		_data_->_tmp3_ = _data_->self->priv->_remote;
		_data_->_state_ = 1;
		g_socket_client_connect_async (_data_->_tmp2_, _data_->_tmp3_, _data_->cancellable, geary_endpoint_connect_async_ready, _data_);
		return FALSE;
		_state_1:
		_data_->_tmp4_ = g_socket_client_connect_finish (_data_->_tmp2_, _data_->_res_, &_data_->_inner_error0_);
		_data_->_tmp1_ = _data_->_tmp4_;
		if (G_UNLIKELY (_data_->_inner_error0_ != NULL)) {
			if (g_error_matches (_data_->_inner_error0_, G_IO_ERROR, G_IO_ERROR_NETWORK_UNREACHABLE)) {
				goto __catch0_g_io_error_network_unreachable;
			}
			goto __finally0;
		}
		_data_->_tmp5_ = _data_->_tmp1_;
		_data_->_tmp1_ = NULL;
		_data_->result = _data_->_tmp5_;
		_g_object_unref0 (_data_->_tmp1_);
		_g_error_free0 (_data_->connect_error);
		_g_object_unref0 (_data_->client);
		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;
	}
	goto __finally0;
	__catch0_g_io_error_network_unreachable:
	{
		_data_->err = _data_->_inner_error0_;
		_data_->_inner_error0_ = NULL;
		_data_->_tmp6_ = _data_->err;
		_data_->_tmp7_ = _g_error_copy0 (_data_->_tmp6_);
		_g_error_free0 (_data_->connect_error);
		_data_->connect_error = _data_->_tmp7_;
		_g_error_free0 (_data_->err);
	}
	__finally0:
	if (G_UNLIKELY (_data_->_inner_error0_ != NULL)) {
		g_task_return_error (_data_->_async_result, _data_->_inner_error0_);
		_g_error_free0 (_data_->connect_error);
		_g_object_unref0 (_data_->client);
		g_object_unref (_data_->_async_result);
		return FALSE;
	}
	_data_->_tmp8_ = _data_->self->priv->_remote;
	_data_->_tmp9_ = g_socket_connectable_enumerate (_data_->_tmp8_);
	_data_->addrs = _data_->_tmp9_;
	_data_->_tmp10_ = _data_->addrs;
	_data_->_state_ = 2;
	g_socket_address_enumerator_next_async (_data_->_tmp10_, _data_->cancellable, geary_endpoint_connect_async_ready, _data_);
	return FALSE;
	_state_2:
	_data_->_tmp11_ = g_socket_address_enumerator_next_finish (_data_->_tmp10_, _data_->_res_, &_data_->_inner_error0_);
	_data_->addr = _data_->_tmp11_;
	if (G_UNLIKELY (_data_->_inner_error0_ != NULL)) {
		g_task_return_error (_data_->_async_result, _data_->_inner_error0_);
		_g_object_unref0 (_data_->addrs);
		_g_error_free0 (_data_->connect_error);
		_g_object_unref0 (_data_->client);
		g_object_unref (_data_->_async_result);
		return FALSE;
	}
	while (TRUE) {
		_data_->_tmp12_ = _data_->addr;
		if (!(_data_->_tmp12_ != NULL)) {
			break;
		}
		_data_->_tmp13_ = _data_->addr;
		_data_->_tmp14_ = _g_object_ref0 (G_TYPE_CHECK_INSTANCE_TYPE (_data_->_tmp13_, g_inet_socket_address_get_type ()) ? ((GInetSocketAddress*) _data_->_tmp13_) : NULL);
		_data_->inet_addr = _data_->_tmp14_;
		_data_->_tmp15_ = _data_->inet_addr;
		if (_data_->_tmp15_ != NULL) {
			{
				_data_->_tmp17_ = _data_->client;
				_data_->_tmp18_ = _data_->inet_addr;
				_data_->_tmp19_ = g_inet_socket_address_get_address (_data_->_tmp18_);
				_data_->_tmp20_ = _data_->_tmp19_;
				_data_->_tmp21_ = _data_->inet_addr;
				_data_->_tmp22_ = g_inet_socket_address_get_port (_data_->_tmp21_);
				_data_->_tmp23_ = _data_->_tmp22_;
				_data_->_tmp24_ = (GInetSocketAddress*) g_inet_socket_address_new (_data_->_tmp20_, (guint16) _data_->_tmp23_);
				_data_->_tmp25_ = _data_->_tmp24_;
				_data_->_state_ = 3;
				g_socket_client_connect_async (_data_->_tmp17_, G_TYPE_CHECK_INSTANCE_CAST (_data_->_tmp25_, g_socket_connectable_get_type (), GSocketConnectable), _data_->cancellable, geary_endpoint_connect_async_ready, _data_);
				return FALSE;
				_state_3:
				_data_->_tmp26_ = g_socket_client_connect_finish (_data_->_tmp17_, _data_->_res_, &_data_->_inner_error0_);
				_data_->_tmp27_ = _data_->_tmp26_;
				_g_object_unref0 (_data_->_tmp25_);
				_data_->_tmp16_ = _data_->_tmp27_;
				if (G_UNLIKELY (_data_->_inner_error0_ != NULL)) {
					if (g_error_matches (_data_->_inner_error0_, G_IO_ERROR, G_IO_ERROR_NETWORK_UNREACHABLE)) {
						goto __catch1_g_io_error_network_unreachable;
					}
					goto __finally1;
				}
				_data_->_tmp28_ = _data_->_tmp16_;
				_data_->_tmp16_ = NULL;
				_data_->result = _data_->_tmp28_;
				_g_object_unref0 (_data_->_tmp16_);
				_g_object_unref0 (_data_->inet_addr);
				_g_object_unref0 (_data_->addr);
				_g_object_unref0 (_data_->addrs);
				_g_error_free0 (_data_->connect_error);
				_g_object_unref0 (_data_->client);
				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;
			}
			goto __finally1;
			__catch1_g_io_error_network_unreachable:
			{
				g_clear_error (&_data_->_inner_error0_);
			}
			__finally1:
			if (G_UNLIKELY (_data_->_inner_error0_ != NULL)) {
				g_task_return_error (_data_->_async_result, _data_->_inner_error0_);
				_g_object_unref0 (_data_->inet_addr);
				_g_object_unref0 (_data_->addr);
				_g_object_unref0 (_data_->addrs);
				_g_error_free0 (_data_->connect_error);
				_g_object_unref0 (_data_->client);
				g_object_unref (_data_->_async_result);
				return FALSE;
			}
		}
		_data_->_tmp30_ = _data_->addrs;
		_data_->_state_ = 4;
		g_socket_address_enumerator_next_async (_data_->_tmp30_, _data_->cancellable, geary_endpoint_connect_async_ready, _data_);
		return FALSE;
		_state_4:
		_data_->_tmp31_ = g_socket_address_enumerator_next_finish (_data_->_tmp30_, _data_->_res_, &_data_->_inner_error0_);
		_data_->_tmp29_ = _data_->_tmp31_;
		if (G_UNLIKELY (_data_->_inner_error0_ != NULL)) {
			g_task_return_error (_data_->_async_result, _data_->_inner_error0_);
			_g_object_unref0 (_data_->inet_addr);
			_g_object_unref0 (_data_->addr);
			_g_object_unref0 (_data_->addrs);
			_g_error_free0 (_data_->connect_error);
			_g_object_unref0 (_data_->client);
			g_object_unref (_data_->_async_result);
			return FALSE;
		}
		_data_->_tmp32_ = _data_->_tmp29_;
		_data_->_tmp29_ = NULL;
		_g_object_unref0 (_data_->addr);
		_data_->addr = _data_->_tmp32_;
		_g_object_unref0 (_data_->_tmp29_);
		_g_object_unref0 (_data_->inet_addr);
	}
	_data_->_tmp33_ = _data_->connect_error;
	_data_->_tmp34_ = _g_error_copy0 (_data_->_tmp33_);
	_data_->_inner_error0_ = _data_->_tmp34_;
	g_task_return_error (_data_->_async_result, _data_->_inner_error0_);
	_g_object_unref0 (_data_->addr);
	_g_object_unref0 (_data_->addrs);
	_g_error_free0 (_data_->connect_error);
	_g_object_unref0 (_data_->client);
	g_object_unref (_data_->_async_result);
	return FALSE;
}

static void
geary_endpoint_starttls_handshake_async_data_free (gpointer _data)
{
	GearyEndpointStarttlsHandshakeAsyncData* _data_;
	_data_ = _data;
	_g_object_unref0 (_data_->base_stream);
	_g_object_unref0 (_data_->cancellable);
	_g_object_unref0 (_data_->result);
	_g_object_unref0 (_data_->self);
	g_slice_free (GearyEndpointStarttlsHandshakeAsyncData, _data_);
}

void
geary_endpoint_starttls_handshake_async (GearyEndpoint* self,
                                         GIOStream* base_stream,
                                         GCancellable* cancellable,
                                         GAsyncReadyCallback _callback_,
                                         gpointer _user_data_)
{
	GearyEndpointStarttlsHandshakeAsyncData* _data_;
	GearyEndpoint* _tmp0_;
	GIOStream* _tmp1_;
	GCancellable* _tmp2_;
	g_return_if_fail (GEARY_IS_ENDPOINT (self));
	g_return_if_fail (G_TYPE_CHECK_INSTANCE_TYPE (base_stream, g_io_stream_get_type ()));
	g_return_if_fail ((cancellable == NULL) || G_TYPE_CHECK_INSTANCE_TYPE (cancellable, g_cancellable_get_type ()));
	_data_ = g_slice_new0 (GearyEndpointStarttlsHandshakeAsyncData);
	_data_->_async_result = g_task_new (G_OBJECT (self), cancellable, _callback_, _user_data_);
	g_task_set_task_data (_data_->_async_result, _data_, geary_endpoint_starttls_handshake_async_data_free);
	_tmp0_ = _g_object_ref0 (self);
	_data_->self = _tmp0_;
	_tmp1_ = _g_object_ref0 (base_stream);
	_g_object_unref0 (_data_->base_stream);
	_data_->base_stream = _tmp1_;
	_tmp2_ = _g_object_ref0 (cancellable);
	_g_object_unref0 (_data_->cancellable);
	_data_->cancellable = _tmp2_;
	geary_endpoint_starttls_handshake_async_co (_data_);
}

GTlsClientConnection*
geary_endpoint_starttls_handshake_finish (GearyEndpoint* self,
                                          GAsyncResult* _res_,
                                          GError** error)
{
	GTlsClientConnection* result;
	GearyEndpointStarttlsHandshakeAsyncData* _data_;
	_data_ = g_task_propagate_pointer (G_TASK (_res_), error);
	if (NULL == _data_) {
		return NULL;
	}
	result = _data_->result;
	_data_->result = NULL;
	return result;
}

static void
geary_endpoint_starttls_handshake_async_ready (GObject* source_object,
                                               GAsyncResult* _res_,
                                               gpointer _user_data_)
{
	GearyEndpointStarttlsHandshakeAsyncData* _data_;
	_data_ = _user_data_;
	_data_->_source_object_ = source_object;
	_data_->_res_ = _res_;
	geary_endpoint_starttls_handshake_async_co (_data_);
}

static gboolean
geary_endpoint_starttls_handshake_async_co (GearyEndpointStarttlsHandshakeAsyncData* _data_)
{
	switch (_data_->_state_) {
		case 0:
		goto _state_0;
		case 1:
		goto _state_1;
		default:
		g_assert_not_reached ();
	}
	_state_0:
	_data_->_tmp0_ = _data_->self->priv->_remote;
	_data_->_tmp1_ = g_tls_client_connection_new (_data_->base_stream, _data_->_tmp0_, &_data_->_inner_error0_);
	_data_->tls_cx = _data_->_tmp1_;
	if (G_UNLIKELY (_data_->_inner_error0_ != NULL)) {
		g_task_return_error (_data_->_async_result, _data_->_inner_error0_);
		g_object_unref (_data_->_async_result);
		return FALSE;
	}
	_data_->_tmp2_ = _data_->tls_cx;
	geary_endpoint_prepare_tls_cx (_data_->self, _data_->_tmp2_);
	_data_->_tmp3_ = _data_->tls_cx;
	_data_->_state_ = 1;
	g_tls_connection_handshake_async (G_TYPE_CHECK_INSTANCE_CAST (_data_->_tmp3_, g_tls_connection_get_type (), GTlsConnection), G_PRIORITY_DEFAULT, _data_->cancellable, geary_endpoint_starttls_handshake_async_ready, _data_);
	return FALSE;
	_state_1:
	g_tls_connection_handshake_finish (G_TYPE_CHECK_INSTANCE_CAST (_data_->_tmp3_, g_tls_connection_get_type (), GTlsConnection), _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_->tls_cx);
		g_object_unref (_data_->_async_result);
		return FALSE;
	}
	_data_->result = _data_->tls_cx;
	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;
}

gchar*
geary_endpoint_to_string (GearyEndpoint* self)
{
	GSocketConnectable* _tmp0_;
	gchar* _tmp1_;
	gchar* result;
	g_return_val_if_fail (GEARY_IS_ENDPOINT (self), NULL);
	_tmp0_ = self->priv->_remote;
	_tmp1_ = g_socket_connectable_to_string (_tmp0_);
	result = _tmp1_;
	return result;
}

static void
_geary_endpoint_on_socket_client_event_g_socket_client_event (GSocketClient* _sender,
                                                              GSocketClientEvent event,
                                                              GSocketConnectable* connectable,
                                                              GIOStream* connection,
                                                              gpointer self)
{
	geary_endpoint_on_socket_client_event ((GearyEndpoint*) self, event, connectable, connection);
}

static GSocketClient*
geary_endpoint_get_socket_client (GearyEndpoint* self)
{
	GSocketClient* _tmp0_;
	GSocketClient* _tmp3_;
	GearyTlsNegotiationMethod _tmp4_;
	GSocketClient* _tmp7_;
	guint _tmp8_;
	GSocketClient* _tmp9_;
	GSocketClient* _tmp10_;
	GSocketClient* result;
	g_return_val_if_fail (GEARY_IS_ENDPOINT (self), NULL);
	_tmp0_ = self->priv->socket_client;
	if (_tmp0_ != NULL) {
		GSocketClient* _tmp1_;
		GSocketClient* _tmp2_;
		_tmp1_ = self->priv->socket_client;
		_tmp2_ = _g_object_ref0 (_tmp1_);
		result = _tmp2_;
		return result;
	}
	_tmp3_ = g_socket_client_new ();
	_g_object_unref0 (self->priv->socket_client);
	self->priv->socket_client = _tmp3_;
	_tmp4_ = self->priv->_tls_method;
	if (_tmp4_ == GEARY_TLS_NEGOTIATION_METHOD_TRANSPORT) {
		GSocketClient* _tmp5_;
		GSocketClient* _tmp6_;
		_tmp5_ = self->priv->socket_client;
		g_socket_client_set_tls (_tmp5_, TRUE);
		_tmp6_ = self->priv->socket_client;
		g_signal_connect_object (_tmp6_, "event", (GCallback) _geary_endpoint_on_socket_client_event_g_socket_client_event, self, 0);
	}
	_tmp7_ = self->priv->socket_client;
	_tmp8_ = self->priv->_timeout_sec;
	g_socket_client_set_timeout (_tmp7_, _tmp8_);
	_tmp9_ = self->priv->socket_client;
	_tmp10_ = _g_object_ref0 (_tmp9_);
	result = _tmp10_;
	return result;
}

static gboolean
_geary_endpoint_on_accept_certificate_g_tls_connection_accept_certificate (GTlsConnection* _sender,
                                                                           GTlsCertificate* peer_cert,
                                                                           GTlsCertificateFlags errors,
                                                                           gpointer self)
{
	gboolean result;
	result = geary_endpoint_on_accept_certificate ((GearyEndpoint*) self, _sender, peer_cert, errors);
	return result;
}

static void
geary_endpoint_prepare_tls_cx (GearyEndpoint* self,
                               GTlsClientConnection* tls_cx)
{
	GTlsDatabase* _tmp0_;
	g_return_if_fail (GEARY_IS_ENDPOINT (self));
	g_return_if_fail (G_TYPE_CHECK_INSTANCE_TYPE (tls_cx, g_tls_client_connection_get_type ()));
	_tmp0_ = geary_endpoint_default_tls_database;
	if (_tmp0_ != NULL) {
		GTlsDatabase* _tmp1_;
		_tmp1_ = geary_endpoint_default_tls_database;
		g_tls_connection_set_database (G_TYPE_CHECK_INSTANCE_CAST (tls_cx, g_tls_connection_get_type (), GTlsConnection), _tmp1_);
	}
	g_signal_connect_object (G_TYPE_CHECK_INSTANCE_CAST (tls_cx, g_tls_connection_get_type (), GTlsConnection), "accept-certificate", (GCallback) _geary_endpoint_on_accept_certificate_g_tls_connection_accept_certificate, self, 0);
}

static void
geary_endpoint_report_tls_warnings (GearyEndpoint* self,
                                    GTlsConnection* cx,
                                    GTlsCertificate* cert,
                                    GTlsCertificateFlags warnings)
{
	GearyTlsNegotiationMethod _tmp0_;
	gchar* _tmp1_;
	gchar* _tmp2_;
	gchar* _tmp3_;
	gchar* _tmp4_;
	gchar* _tmp5_;
	g_return_if_fail (GEARY_IS_ENDPOINT (self));
	g_return_if_fail (G_TYPE_CHECK_INSTANCE_TYPE (cx, g_tls_connection_get_type ()));
	g_return_if_fail (G_TYPE_CHECK_INSTANCE_TYPE (cert, g_tls_certificate_get_type ()));
	_tmp0_ = self->priv->_tls_method;
	_tmp1_ = g_enum_to_string (GEARY_TYPE_TLS_NEGOTIATION_METHOD, _tmp0_);
	_tmp2_ = geary_endpoint_to_string (self);
	_tmp3_ = _tmp2_;
	_tmp4_ = geary_endpoint_tls_flags_to_string (self, warnings);
	_tmp5_ = _tmp4_;
	g_message ("geary-endpoint.vala:194: %s TLS warnings connecting to %s: %Xh (%s)", _tmp1_, _tmp3_, (guint) warnings, _tmp5_);
	_g_free0 (_tmp5_);
	_g_free0 (_tmp3_);
	_g_free0 (_tmp1_);
	geary_endpoint_set_tls_validation_warnings (self, warnings);
	geary_endpoint_set_untrusted_certificate (self, cert);
	g_signal_emit (self, geary_endpoint_signals[GEARY_ENDPOINT_UNTRUSTED_HOST_SIGNAL], 0, cx);
}

static gchar*
geary_endpoint_tls_flags_to_string (GearyEndpoint* self,
                                    GTlsCertificateFlags flags)
{
	GString* builder = NULL;
	GString* _tmp0_;
	const gchar* _tmp9_ = NULL;
	GString* _tmp10_;
	const gchar* _tmp11_;
	gchar* _tmp14_;
	gchar* result;
	g_return_val_if_fail (GEARY_IS_ENDPOINT (self), NULL);
	_tmp0_ = g_string_new ("");
	builder = _tmp0_;
	{
		gint pos = 0;
		pos = 0;
		{
			gboolean _tmp1_ = FALSE;
			_tmp1_ = TRUE;
			while (TRUE) {
				GTlsCertificateFlags flag = 0U;
				if (!_tmp1_) {
					gint _tmp2_;
					_tmp2_ = pos;
					pos = _tmp2_ + 1;
				}
				_tmp1_ = FALSE;
				if (!(((gulong) pos) < (sizeof (GTlsCertificateFlags) * 8))) {
					break;
				}
				flag = flags & (1 << pos);
				if (flag != 0) {
					GString* _tmp3_;
					const gchar* _tmp4_;
					GString* _tmp6_;
					gchar* _tmp7_;
					gchar* _tmp8_;
					_tmp3_ = builder;
					_tmp4_ = _tmp3_->str;
					if (!geary_string_is_empty (_tmp4_)) {
						GString* _tmp5_;
						_tmp5_ = builder;
						g_string_append (_tmp5_, " | ");
					}
					_tmp6_ = builder;
					_tmp7_ = geary_endpoint_tls_flag_to_string (flag);
					_tmp8_ = _tmp7_;
					g_string_append (_tmp6_, _tmp8_);
					_g_free0 (_tmp8_);
				}
			}
		}
	}
	_tmp10_ = builder;
	_tmp11_ = _tmp10_->str;
	if (!geary_string_is_empty (_tmp11_)) {
		GString* _tmp12_;
		const gchar* _tmp13_;
		_tmp12_ = builder;
		_tmp13_ = _tmp12_->str;
		_tmp9_ = _tmp13_;
	} else {
		_tmp9_ = "(none)";
	}
	_tmp14_ = g_strdup (_tmp9_);
	result = _tmp14_;
	_g_string_free0 (builder);
	return result;
}

static void
geary_endpoint_on_socket_client_event (GearyEndpoint* self,
                                       GSocketClientEvent event,
                                       GSocketConnectable* connectable,
                                       GIOStream* ios)
{
	g_return_if_fail (GEARY_IS_ENDPOINT (self));
	g_return_if_fail ((connectable == NULL) || G_TYPE_CHECK_INSTANCE_TYPE (connectable, g_socket_connectable_get_type ()));
	g_return_if_fail ((ios == NULL) || G_TYPE_CHECK_INSTANCE_TYPE (ios, g_io_stream_get_type ()));
	if (event == G_SOCKET_CLIENT_TLS_HANDSHAKING) {
		geary_endpoint_prepare_tls_cx (self, G_TYPE_CHECK_INSTANCE_CAST (ios, g_tls_client_connection_get_type (), GTlsClientConnection));
	}
}

static Block4Data*
block4_data_ref (Block4Data* _data4_)
{
	g_atomic_int_inc (&_data4_->_ref_count_);
	return _data4_;
}

static void
block4_data_unref (void * _userdata_)
{
	Block4Data* _data4_;
	_data4_ = (Block4Data*) _userdata_;
	if (g_atomic_int_dec_and_test (&_data4_->_ref_count_)) {
		GearyEndpoint* self;
		self = _data4_->self;
		_g_object_unref0 (_data4_->cx);
		_g_object_unref0 (_data4_->cert);
		_g_object_unref0 (self);
		g_slice_free (Block4Data, _data4_);
	}
}

static gboolean
__lambda47_ (Block4Data* _data4_)
{
	GearyEndpoint* self;
	gboolean result;
	self = _data4_->self;
	geary_endpoint_report_tls_warnings (self, _data4_->cx, _data4_->cert, _data4_->flags);
	result = G_SOURCE_REMOVE;
	return result;
}

static gboolean
___lambda47__gsource_func (gpointer self)
{
	gboolean result;
	result = __lambda47_ (self);
	return result;
}

static gboolean
geary_endpoint_on_accept_certificate (GearyEndpoint* self,
                                      GTlsConnection* cx,
                                      GTlsCertificate* cert,
                                      GTlsCertificateFlags flags)
{
	Block4Data* _data4_;
	GTlsConnection* _tmp0_;
	GTlsCertificate* _tmp1_;
	gboolean result;
	g_return_val_if_fail (GEARY_IS_ENDPOINT (self), FALSE);
	g_return_val_if_fail (G_TYPE_CHECK_INSTANCE_TYPE (cx, g_tls_connection_get_type ()), FALSE);
	g_return_val_if_fail (G_TYPE_CHECK_INSTANCE_TYPE (cert, g_tls_certificate_get_type ()), FALSE);
	_data4_ = g_slice_new0 (Block4Data);
	_data4_->_ref_count_ = 1;
	_data4_->self = g_object_ref (self);
	_tmp0_ = _g_object_ref0 (cx);
	_g_object_unref0 (_data4_->cx);
	_data4_->cx = _tmp0_;
	_tmp1_ = _g_object_ref0 (cert);
	_g_object_unref0 (_data4_->cert);
	_data4_->cert = _tmp1_;
	_data4_->flags = flags;
	g_idle_add_full (G_PRIORITY_HIGH, ___lambda47__gsource_func, block4_data_ref (_data4_), block4_data_unref);
	result = FALSE;
	block4_data_unref (_data4_);
	_data4_ = NULL;
	return result;
}

static void
geary_endpoint_class_init (GearyEndpointClass * klass,
                           gpointer klass_data)
{
	geary_endpoint_parent_class = g_type_class_peek_parent (klass);
	g_type_class_adjust_private_offset (klass, &GearyEndpoint_private_offset);
	G_OBJECT_CLASS (klass)->get_property = _vala_geary_endpoint_get_property;
	G_OBJECT_CLASS (klass)->set_property = _vala_geary_endpoint_set_property;
	G_OBJECT_CLASS (klass)->finalize = geary_endpoint_finalize;
	/** Specifies how to connect to the remote endpoint. */
	g_object_class_install_property (G_OBJECT_CLASS (klass), GEARY_ENDPOINT_REMOTE_PROPERTY, geary_endpoint_properties[GEARY_ENDPOINT_REMOTE_PROPERTY] = g_param_spec_object ("remote", "remote", "remote", g_socket_connectable_get_type (), G_PARAM_STATIC_STRINGS | G_PARAM_READABLE));
	/** A connectivity manager for this endpoint. */
	g_object_class_install_property (G_OBJECT_CLASS (klass), GEARY_ENDPOINT_CONNECTIVITY_PROPERTY, geary_endpoint_properties[GEARY_ENDPOINT_CONNECTIVITY_PROPERTY] = g_param_spec_object ("connectivity", "connectivity", "connectivity", GEARY_TYPE_CONNECTIVITY_MANAGER, G_PARAM_STATIC_STRINGS | G_PARAM_READABLE));
	/** Timeout for connection attempts, in seconds. */
	g_object_class_install_property (G_OBJECT_CLASS (klass), GEARY_ENDPOINT_TIMEOUT_SEC_PROPERTY, geary_endpoint_properties[GEARY_ENDPOINT_TIMEOUT_SEC_PROPERTY] = g_param_spec_uint ("timeout-sec", "timeout-sec", "timeout-sec", 0, G_MAXUINT, 0U, G_PARAM_STATIC_STRINGS | G_PARAM_READABLE));
	/** Transport security method to use when connecting. */
	g_object_class_install_property (G_OBJECT_CLASS (klass), GEARY_ENDPOINT_TLS_METHOD_PROPERTY, geary_endpoint_properties[GEARY_ENDPOINT_TLS_METHOD_PROPERTY] = g_param_spec_enum ("tls-method", "tls-method", "tls-method", GEARY_TYPE_TLS_NEGOTIATION_METHOD, 0, G_PARAM_STATIC_STRINGS | G_PARAM_READABLE));
	/**
	     * When set, TLS has reported certificate issues.
	     *
	     * @see untrusted_host
	     */
	g_object_class_install_property (G_OBJECT_CLASS (klass), GEARY_ENDPOINT_TLS_VALIDATION_WARNINGS_PROPERTY, geary_endpoint_properties[GEARY_ENDPOINT_TLS_VALIDATION_WARNINGS_PROPERTY] = g_param_spec_flags ("tls-validation-warnings", "tls-validation-warnings", "tls-validation-warnings", g_tls_certificate_flags_get_type (), 0, G_PARAM_STATIC_STRINGS | G_PARAM_READABLE));
	/**
	     * The TLS certificate for an invalid or untrusted connection.
	     */
	g_object_class_install_property (G_OBJECT_CLASS (klass), GEARY_ENDPOINT_UNTRUSTED_CERTIFICATE_PROPERTY, geary_endpoint_properties[GEARY_ENDPOINT_UNTRUSTED_CERTIFICATE_PROPERTY] = g_param_spec_object ("untrusted-certificate", "untrusted-certificate", "untrusted-certificate", g_tls_certificate_get_type (), G_PARAM_STATIC_STRINGS | G_PARAM_READABLE));
	/**
	     * Emitted when unexpected TLS certificate warnings are detected.
	     *
	     * This occurs when a connection receives a TLS certificate
	     * warning. The connection will be closed when this is fired. The
	     * caller should query the user about how to deal with the
	     * situation. If user wants to proceed, pin the certificate in a
	     * way such that it accessible to the connection via {@link
	     * default_tls_database}.
	     *
	     * @see AccountInformation.untrusted_host
	     * @see tls_validation_warnings
	     */
	geary_endpoint_signals[GEARY_ENDPOINT_UNTRUSTED_HOST_SIGNAL] = g_signal_new ("untrusted-host", GEARY_TYPE_ENDPOINT, G_SIGNAL_RUN_LAST, 0, NULL, NULL, g_cclosure_marshal_VOID__OBJECT, G_TYPE_NONE, 1, g_tls_connection_get_type ());
}

static void
geary_endpoint_instance_init (GearyEndpoint * self,
                              gpointer klass)
{
	self->priv = geary_endpoint_get_instance_private (self);
	self->priv->_tls_validation_warnings = 0;
	self->priv->_untrusted_certificate = NULL;
	self->priv->socket_client = NULL;
}

static void
geary_endpoint_finalize (GObject * obj)
{
	GearyEndpoint * self;
	self = G_TYPE_CHECK_INSTANCE_CAST (obj, GEARY_TYPE_ENDPOINT, GearyEndpoint);
	_g_object_unref0 (self->priv->_remote);
	_g_object_unref0 (self->priv->_connectivity);
	_g_object_unref0 (self->priv->_untrusted_certificate);
	_g_object_unref0 (self->priv->socket_client);
	G_OBJECT_CLASS (geary_endpoint_parent_class)->finalize (obj);
}

/**
 * Encapsulates network configuration and state for remote service.
 */
 G_GNUC_NO_INLINE static GType
geary_endpoint_get_type_once (void)
{
	static const GTypeInfo g_define_type_info = { sizeof (GearyEndpointClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) geary_endpoint_class_init, (GClassFinalizeFunc) NULL, NULL, sizeof (GearyEndpoint), 0, (GInstanceInitFunc) geary_endpoint_instance_init, NULL };
	GType geary_endpoint_type_id;
	geary_endpoint_type_id = g_type_register_static (GEARY_TYPE_BASE_OBJECT, "GearyEndpoint", &g_define_type_info, 0);
	GearyEndpoint_private_offset = g_type_add_instance_private (geary_endpoint_type_id, sizeof (GearyEndpointPrivate));
	return geary_endpoint_type_id;
}

GType
geary_endpoint_get_type (void)
{
	static gsize geary_endpoint_type_id__once = 0;
	if (g_once_init_enter (&geary_endpoint_type_id__once)) {
		GType geary_endpoint_type_id;
		geary_endpoint_type_id = geary_endpoint_get_type_once ();
		g_once_init_leave (&geary_endpoint_type_id__once, geary_endpoint_type_id);
	}
	return geary_endpoint_type_id__once;
}

static void
_vala_geary_endpoint_get_property (GObject * object,
                                   guint property_id,
                                   GValue * value,
                                   GParamSpec * pspec)
{
	GearyEndpoint * self;
	self = G_TYPE_CHECK_INSTANCE_CAST (object, GEARY_TYPE_ENDPOINT, GearyEndpoint);
	switch (property_id) {
		case GEARY_ENDPOINT_REMOTE_PROPERTY:
		g_value_set_object (value, geary_endpoint_get_remote (self));
		break;
		case GEARY_ENDPOINT_CONNECTIVITY_PROPERTY:
		g_value_set_object (value, geary_endpoint_get_connectivity (self));
		break;
		case GEARY_ENDPOINT_TIMEOUT_SEC_PROPERTY:
		g_value_set_uint (value, geary_endpoint_get_timeout_sec (self));
		break;
		case GEARY_ENDPOINT_TLS_METHOD_PROPERTY:
		g_value_set_enum (value, geary_endpoint_get_tls_method (self));
		break;
		case GEARY_ENDPOINT_TLS_VALIDATION_WARNINGS_PROPERTY:
		g_value_set_flags (value, geary_endpoint_get_tls_validation_warnings (self));
		break;
		case GEARY_ENDPOINT_UNTRUSTED_CERTIFICATE_PROPERTY:
		g_value_set_object (value, geary_endpoint_get_untrusted_certificate (self));
		break;
		default:
		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
		break;
	}
}

static void
_vala_geary_endpoint_set_property (GObject * object,
                                   guint property_id,
                                   const GValue * value,
                                   GParamSpec * pspec)
{
	GearyEndpoint * self;
	self = G_TYPE_CHECK_INSTANCE_CAST (object, GEARY_TYPE_ENDPOINT, GearyEndpoint);
	switch (property_id) {
		case GEARY_ENDPOINT_REMOTE_PROPERTY:
		geary_endpoint_set_remote (self, g_value_get_object (value));
		break;
		case GEARY_ENDPOINT_CONNECTIVITY_PROPERTY:
		geary_endpoint_set_connectivity (self, g_value_get_object (value));
		break;
		case GEARY_ENDPOINT_TIMEOUT_SEC_PROPERTY:
		geary_endpoint_set_timeout_sec (self, g_value_get_uint (value));
		break;
		case GEARY_ENDPOINT_TLS_METHOD_PROPERTY:
		geary_endpoint_set_tls_method (self, g_value_get_enum (value));
		break;
		case GEARY_ENDPOINT_TLS_VALIDATION_WARNINGS_PROPERTY:
		geary_endpoint_set_tls_validation_warnings (self, g_value_get_flags (value));
		break;
		case GEARY_ENDPOINT_UNTRUSTED_CERTIFICATE_PROPERTY:
		geary_endpoint_set_untrusted_certificate (self, g_value_get_object (value));
		break;
		default:
		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
		break;
	}
}

