/* imap-engine-account-processor.c generated by valac 0.56.3, the Vala compiler
 * generated from imap-engine-account-processor.vala, do not modify */

/*
 * Copyright 2017-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 <glib-object.h>
#include <glib.h>
#include <gio/gio.h>
#include <gee.h>
#include <stdlib.h>
#include <string.h>

#define GEARY_IMAP_ENGINE_ACCOUNT_PROCESSOR_MAX_NETWORK_ERRORS 1

#define GEARY_IMAP_ENGINE_TYPE_ACCOUNT_PROCESSOR (geary_imap_engine_account_processor_get_type ())
#define GEARY_IMAP_ENGINE_ACCOUNT_PROCESSOR(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GEARY_IMAP_ENGINE_TYPE_ACCOUNT_PROCESSOR, GearyImapEngineAccountProcessor))
#define GEARY_IMAP_ENGINE_ACCOUNT_PROCESSOR_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GEARY_IMAP_ENGINE_TYPE_ACCOUNT_PROCESSOR, GearyImapEngineAccountProcessorClass))
#define GEARY_IMAP_ENGINE_IS_ACCOUNT_PROCESSOR(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GEARY_IMAP_ENGINE_TYPE_ACCOUNT_PROCESSOR))
#define GEARY_IMAP_ENGINE_IS_ACCOUNT_PROCESSOR_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GEARY_IMAP_ENGINE_TYPE_ACCOUNT_PROCESSOR))
#define GEARY_IMAP_ENGINE_ACCOUNT_PROCESSOR_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GEARY_IMAP_ENGINE_TYPE_ACCOUNT_PROCESSOR, GearyImapEngineAccountProcessorClass))

typedef struct _GearyImapEngineAccountProcessor GearyImapEngineAccountProcessor;
typedef struct _GearyImapEngineAccountProcessorClass GearyImapEngineAccountProcessorClass;
typedef struct _GearyImapEngineAccountProcessorPrivate GearyImapEngineAccountProcessorPrivate;
enum  {
	GEARY_IMAP_ENGINE_ACCOUNT_PROCESSOR_0_PROPERTY,
	GEARY_IMAP_ENGINE_ACCOUNT_PROCESSOR_IS_EXECUTING_PROPERTY,
	GEARY_IMAP_ENGINE_ACCOUNT_PROCESSOR_WAITING_PROPERTY,
	GEARY_IMAP_ENGINE_ACCOUNT_PROCESSOR_LOGGING_PARENT_PROPERTY,
	GEARY_IMAP_ENGINE_ACCOUNT_PROCESSOR_NUM_PROPERTIES
};
static GParamSpec* geary_imap_engine_account_processor_properties[GEARY_IMAP_ENGINE_ACCOUNT_PROCESSOR_NUM_PROPERTIES];
#define _g_object_unref0(var) ((var == NULL) ? NULL : (var = (g_object_unref (var), NULL)))
typedef struct _Block95Data Block95Data;
#define _g_free0(var) (var = (g_free (var), NULL))
#define _g_error_free0(var) ((var == NULL) ? NULL : (var = (g_error_free (var), NULL)))
typedef struct _GearyImapEngineAccountProcessorRunData GearyImapEngineAccountProcessorRunData;
enum  {
	GEARY_IMAP_ENGINE_ACCOUNT_PROCESSOR_OPERATION_ERROR_SIGNAL,
	GEARY_IMAP_ENGINE_ACCOUNT_PROCESSOR_NUM_SIGNALS
};
static guint geary_imap_engine_account_processor_signals[GEARY_IMAP_ENGINE_ACCOUNT_PROCESSOR_NUM_SIGNALS] = {0};

struct _GearyImapEngineAccountProcessor {
	GearyBaseObject parent_instance;
	GearyImapEngineAccountProcessorPrivate * priv;
};

struct _GearyImapEngineAccountProcessorClass {
	GearyBaseObjectClass parent_class;
	GearyLoggingState* (*to_logging_state) (GearyImapEngineAccountProcessor* self);
};

struct _GearyImapEngineAccountProcessorPrivate {
	GearyLoggingSource* _logging_parent;
	gboolean is_running;
	GearyNonblockingQueue* queue;
	GearyImapEngineAccountOperation* current_op;
	GCancellable* op_cancellable;
	GearyProgressMonitor* progress;
};

struct _Block95Data {
	int _ref_count_;
	GearyImapEngineAccountProcessor* self;
	gboolean found;
	GType type;
};

struct _GearyImapEngineAccountProcessorRunData {
	int _state_;
	GObject* _source_object_;
	GAsyncResult* _res_;
	GTask* _async_result;
	GearyImapEngineAccountProcessor* self;
	GCancellable* _tmp0_;
	GearyImapEngineAccountOperation* op;
	GearyImapEngineAccountOperation* _tmp1_;
	GearyNonblockingQueue* _tmp2_;
	GCancellable* _tmp3_;
	gpointer _tmp4_;
	GearyImapEngineAccountOperation* _tmp5_;
	GearyImapEngineAccountOperation* _tmp6_;
	GearyImapEngineAccountOperation* _tmp7_;
	gchar* _tmp8_;
	gchar* _tmp9_;
	GearyImapEngineAccountOperation* _tmp10_;
	GearyImapEngineAccountOperation* _tmp11_;
	GearyProgressMonitor* _tmp12_;
	GearyProgressMonitor* _tmp13_;
	GError* op_error;
	gint network_errors;
	GError* _tmp14_;
	GearyImapEngineAccountOperation* _tmp15_;
	GCancellable* _tmp16_;
	GearyImapEngineAccountOperation* _tmp17_;
	GError* err;
	gboolean _tmp18_;
	GError* _tmp19_;
	gint _tmp20_;
	GError* _tmp21_;
	const gchar* _tmp22_;
	GError* _tmp23_;
	GError* _tmp24_;
	GError* _vala1_err;
	GError* _tmp25_;
	GError* _tmp26_;
	GError* _tmp27_;
	GearyImapEngineAccountOperation* _tmp28_;
	GError* _tmp29_;
	GearyImapEngineAccountOperation* _tmp30_;
	GError* _tmp31_;
	GearyImapEngineAccountOperation* _tmp32_;
	GearyProgressMonitor* _tmp33_;
	GearyProgressMonitor* _tmp34_;
	GError* _inner_error0_;
};

static gint GearyImapEngineAccountProcessor_private_offset;
static gpointer geary_imap_engine_account_processor_parent_class = NULL;
static GearyLoggingSourceIface * geary_imap_engine_account_processor_geary_logging_source_parent_iface = NULL;

VALA_EXTERN GType geary_imap_engine_account_processor_get_type (void) G_GNUC_CONST ;
VALA_EXTERN GearyLoggingState* geary_imap_engine_account_processor_to_logging_state (GearyImapEngineAccountProcessor* self);
static gboolean geary_imap_engine_account_processor_op_equal (GearyImapEngineAccountOperation* a,
                                                       GearyImapEngineAccountOperation* b);
VALA_EXTERN gboolean geary_imap_engine_account_processor_get_is_executing (GearyImapEngineAccountProcessor* self);
VALA_EXTERN guint geary_imap_engine_account_processor_get_waiting (GearyImapEngineAccountProcessor* self);
static void g_cclosure_user_marshal_VOID__OBJECT_POINTER (GClosure * closure,
                                                   GValue * return_value,
                                                   guint n_param_values,
                                                   const GValue * param_values,
                                                   gpointer invocation_hint,
                                                   gpointer marshal_data);
static gboolean _geary_imap_engine_account_processor_op_equal_gee_equal_data_func (gconstpointer a,
                                                                            gconstpointer b,
                                                                            gpointer self);
VALA_EXTERN GearyImapEngineAccountProcessor* geary_imap_engine_account_processor_new (GearyProgressMonitor* progress);
VALA_EXTERN GearyImapEngineAccountProcessor* geary_imap_engine_account_processor_construct (GType object_type,
                                                                                GearyProgressMonitor* progress);
static void geary_imap_engine_account_processor_run (GearyImapEngineAccountProcessor* self,
                                              GAsyncReadyCallback _callback_,
                                              gpointer _user_data_);
static void geary_imap_engine_account_processor_run_finish (GearyImapEngineAccountProcessor* self,
                                                     GAsyncResult* _res_);
VALA_EXTERN void geary_imap_engine_account_processor_enqueue (GearyImapEngineAccountProcessor* self,
                                                  GearyImapEngineAccountOperation* op);
VALA_EXTERN void geary_imap_engine_account_processor_dequeue (GearyImapEngineAccountProcessor* self,
                                                  GearyImapEngineAccountOperation* op);
VALA_EXTERN gboolean geary_imap_engine_account_processor_dequeue_by_type (GearyImapEngineAccountProcessor* self,
                                                              GType type);
static Block95Data* block95_data_ref (Block95Data* _data95_);
static void block95_data_unref (void * _userdata_);
static gboolean __lambda127_ (Block95Data* _data95_,
                       GearyImapEngineAccountOperation* op);
static gboolean ___lambda127__gee_predicate (gconstpointer g,
                                      gpointer self);
VALA_EXTERN void geary_imap_engine_account_processor_stop (GearyImapEngineAccountProcessor* self);
static GearyLoggingState* geary_imap_engine_account_processor_real_to_logging_state (GearyImapEngineAccountProcessor* self);
VALA_EXTERN void geary_imap_engine_account_processor_set_logging_parent (GearyImapEngineAccountProcessor* self,
                                                             GearyLoggingSource* parent);
static void geary_imap_engine_account_processor_run_data_free (gpointer _data);
static gboolean geary_imap_engine_account_processor_run_co (GearyImapEngineAccountProcessorRunData* _data_);
static void geary_imap_engine_account_processor_run_ready (GObject* source_object,
                                                    GAsyncResult* _res_,
                                                    gpointer _user_data_);
static void geary_imap_engine_account_processor_finalize (GObject * obj);
static GType geary_imap_engine_account_processor_get_type_once (void);
static void _vala_geary_imap_engine_account_processor_get_property (GObject * object,
                                                             guint property_id,
                                                             GValue * value,
                                                             GParamSpec * pspec);

static inline gpointer
geary_imap_engine_account_processor_get_instance_private (GearyImapEngineAccountProcessor* self)
{
	return G_STRUCT_MEMBER_P (self, GearyImapEngineAccountProcessor_private_offset);
}

static gboolean
geary_imap_engine_account_processor_op_equal (GearyImapEngineAccountOperation* a,
                                              GearyImapEngineAccountOperation* b)
{
	gboolean result;
	g_return_val_if_fail (GEARY_IMAP_ENGINE_IS_ACCOUNT_OPERATION (a), FALSE);
	g_return_val_if_fail (GEARY_IMAP_ENGINE_IS_ACCOUNT_OPERATION (b), FALSE);
	result = geary_imap_engine_account_operation_equal_to (a, b);
	return result;
}

gboolean
geary_imap_engine_account_processor_get_is_executing (GearyImapEngineAccountProcessor* self)
{
	gboolean result;
	GearyImapEngineAccountOperation* _tmp0_;
	g_return_val_if_fail (GEARY_IMAP_ENGINE_IS_ACCOUNT_PROCESSOR (self), FALSE);
	_tmp0_ = self->priv->current_op;
	result = _tmp0_ != NULL;
	return result;
}

guint
geary_imap_engine_account_processor_get_waiting (GearyImapEngineAccountProcessor* self)
{
	guint result;
	GearyNonblockingQueue* _tmp0_;
	gint _tmp1_;
	gint _tmp2_;
	g_return_val_if_fail (GEARY_IMAP_ENGINE_IS_ACCOUNT_PROCESSOR (self), 0U);
	_tmp0_ = self->priv->queue;
	_tmp1_ = geary_nonblocking_queue_get_size (_tmp0_);
	_tmp2_ = _tmp1_;
	result = (guint) _tmp2_;
	return result;
}

static void
g_cclosure_user_marshal_VOID__OBJECT_POINTER (GClosure * closure,
                                              GValue * return_value,
                                              guint n_param_values,
                                              const GValue * param_values,
                                              gpointer invocation_hint,
                                              gpointer marshal_data)
{
	typedef void (*GMarshalFunc_VOID__OBJECT_POINTER) (gpointer data1, gpointer arg_1, gpointer arg_2, gpointer data2);
	register GMarshalFunc_VOID__OBJECT_POINTER callback;
	register GCClosure * cc;
	register gpointer data1;
	register gpointer data2;
	cc = (GCClosure *) closure;
	g_return_if_fail (n_param_values == 3);
	if (G_CCLOSURE_SWAP_DATA (closure)) {
		data1 = closure->data;
		data2 = param_values->data[0].v_pointer;
	} else {
		data1 = param_values->data[0].v_pointer;
		data2 = closure->data;
	}
	callback = (GMarshalFunc_VOID__OBJECT_POINTER) (marshal_data ? marshal_data : cc->callback);
	callback (data1, g_value_get_object (param_values + 1), g_value_get_pointer (param_values + 2), data2);
}

static GearyLoggingSource*
geary_imap_engine_account_processor_real_get_logging_parent (GearyLoggingSource* base)
{
	GearyLoggingSource* result;
	GearyImapEngineAccountProcessor* self;
	GearyLoggingSource* _tmp0_;
	self = G_TYPE_CHECK_INSTANCE_CAST (base, GEARY_IMAP_ENGINE_TYPE_ACCOUNT_PROCESSOR, GearyImapEngineAccountProcessor);
	_tmp0_ = self->priv->_logging_parent;
	result = _tmp0_;
	return result;
}

static gboolean
_geary_imap_engine_account_processor_op_equal_gee_equal_data_func (gconstpointer a,
                                                                   gconstpointer b,
                                                                   gpointer self)
{
	gboolean result;
	result = geary_imap_engine_account_processor_op_equal ((GearyImapEngineAccountOperation*) a, (GearyImapEngineAccountOperation*) b);
	return result;
}

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

GearyImapEngineAccountProcessor*
geary_imap_engine_account_processor_construct (GType object_type,
                                               GearyProgressMonitor* progress)
{
	GearyImapEngineAccountProcessor * self = NULL;
	GearyNonblockingQueue* _tmp0_;
	GearyProgressMonitor* _tmp1_;
	g_return_val_if_fail ((progress == NULL) || GEARY_IS_PROGRESS_MONITOR (progress), NULL);
	self = (GearyImapEngineAccountProcessor*) geary_base_object_construct (object_type);
	_tmp0_ = self->priv->queue;
	geary_nonblocking_queue_set_allow_duplicates (_tmp0_, FALSE);
	self->priv->is_running = TRUE;
	_tmp1_ = _g_object_ref0 (progress);
	_g_object_unref0 (self->priv->progress);
	self->priv->progress = _tmp1_;
	geary_imap_engine_account_processor_run (self, NULL, NULL);
	return self;
}

GearyImapEngineAccountProcessor*
geary_imap_engine_account_processor_new (GearyProgressMonitor* progress)
{
	return geary_imap_engine_account_processor_construct (GEARY_IMAP_ENGINE_TYPE_ACCOUNT_PROCESSOR, progress);
}

void
geary_imap_engine_account_processor_enqueue (GearyImapEngineAccountProcessor* self,
                                             GearyImapEngineAccountOperation* op)
{
	gboolean _tmp0_ = FALSE;
	GearyImapEngineAccountOperation* _tmp1_;
	g_return_if_fail (GEARY_IMAP_ENGINE_IS_ACCOUNT_PROCESSOR (self));
	g_return_if_fail (GEARY_IMAP_ENGINE_IS_ACCOUNT_OPERATION (op));
	_tmp1_ = self->priv->current_op;
	if (_tmp1_ == NULL) {
		_tmp0_ = TRUE;
	} else {
		GearyImapEngineAccountOperation* _tmp2_;
		_tmp2_ = self->priv->current_op;
		_tmp0_ = !geary_imap_engine_account_operation_equal_to (op, _tmp2_);
	}
	if (_tmp0_) {
		GearyNonblockingQueue* _tmp3_;
		_tmp3_ = self->priv->queue;
		geary_nonblocking_queue_send (_tmp3_, op);
	}
}

void
geary_imap_engine_account_processor_dequeue (GearyImapEngineAccountProcessor* self,
                                             GearyImapEngineAccountOperation* op)
{
	gboolean _tmp0_ = FALSE;
	gboolean _tmp1_ = FALSE;
	GearyImapEngineAccountOperation* _tmp2_;
	GearyNonblockingQueue* _tmp6_;
	g_return_if_fail (GEARY_IMAP_ENGINE_IS_ACCOUNT_PROCESSOR (self));
	g_return_if_fail (GEARY_IMAP_ENGINE_IS_ACCOUNT_OPERATION (op));
	_tmp2_ = self->priv->current_op;
	if (_tmp2_ != NULL) {
		GearyImapEngineAccountOperation* _tmp3_;
		_tmp3_ = self->priv->current_op;
		_tmp1_ = geary_imap_engine_account_operation_equal_to (_tmp3_, op);
	} else {
		_tmp1_ = FALSE;
	}
	if (_tmp1_) {
		GCancellable* _tmp4_;
		_tmp4_ = self->priv->op_cancellable;
		_tmp0_ = _tmp4_ != NULL;
	} else {
		_tmp0_ = FALSE;
	}
	if (_tmp0_) {
		GCancellable* _tmp5_;
		_tmp5_ = self->priv->op_cancellable;
		g_cancellable_cancel (_tmp5_);
		_g_object_unref0 (self->priv->op_cancellable);
		self->priv->op_cancellable = NULL;
	}
	_tmp6_ = self->priv->queue;
	geary_nonblocking_queue_revoke (_tmp6_, op);
}

static Block95Data*
block95_data_ref (Block95Data* _data95_)
{
	g_atomic_int_inc (&_data95_->_ref_count_);
	return _data95_;
}

static void
block95_data_unref (void * _userdata_)
{
	Block95Data* _data95_;
	_data95_ = (Block95Data*) _userdata_;
	if (g_atomic_int_dec_and_test (&_data95_->_ref_count_)) {
		GearyImapEngineAccountProcessor* self;
		self = _data95_->self;
		_g_object_unref0 (self);
		g_slice_free (Block95Data, _data95_);
	}
}

static gboolean
__lambda127_ (Block95Data* _data95_,
              GearyImapEngineAccountOperation* op)
{
	GearyImapEngineAccountProcessor* self;
	gboolean result;
	self = _data95_->self;
	g_return_val_if_fail (GEARY_IMAP_ENGINE_IS_ACCOUNT_OPERATION (op), FALSE);
	if (G_TYPE_FROM_INSTANCE (G_TYPE_CHECK_INSTANCE_CAST (op, G_TYPE_OBJECT, GObject)) == _data95_->type) {
		_data95_->found = TRUE;
	}
	result = G_TYPE_FROM_INSTANCE (G_TYPE_CHECK_INSTANCE_CAST (op, G_TYPE_OBJECT, GObject)) == _data95_->type;
	return result;
}

static gboolean
___lambda127__gee_predicate (gconstpointer g,
                             gpointer self)
{
	gboolean result;
	result = __lambda127_ (self, (GearyImapEngineAccountOperation*) g);
	return result;
}

gboolean
geary_imap_engine_account_processor_dequeue_by_type (GearyImapEngineAccountProcessor* self,
                                                     GType type)
{
	Block95Data* _data95_;
	gboolean _tmp0_ = FALSE;
	gboolean _tmp1_ = FALSE;
	GearyImapEngineAccountOperation* _tmp2_;
	GearyNonblockingQueue* _tmp6_;
	GeeCollection* _tmp7_;
	GeeCollection* _tmp8_;
	gboolean result;
	g_return_val_if_fail (GEARY_IMAP_ENGINE_IS_ACCOUNT_PROCESSOR (self), FALSE);
	_data95_ = g_slice_new0 (Block95Data);
	_data95_->_ref_count_ = 1;
	_data95_->self = g_object_ref (self);
	_data95_->type = type;
	_data95_->found = FALSE;
	_tmp2_ = self->priv->current_op;
	if (_tmp2_ != NULL) {
		GearyImapEngineAccountOperation* _tmp3_;
		_tmp3_ = self->priv->current_op;
		_tmp1_ = G_TYPE_FROM_INSTANCE (G_TYPE_CHECK_INSTANCE_CAST (_tmp3_, G_TYPE_OBJECT, GObject)) == _data95_->type;
	} else {
		_tmp1_ = FALSE;
	}
	if (_tmp1_) {
		GCancellable* _tmp4_;
		_tmp4_ = self->priv->op_cancellable;
		_tmp0_ = _tmp4_ != NULL;
	} else {
		_tmp0_ = FALSE;
	}
	if (_tmp0_) {
		GCancellable* _tmp5_;
		_tmp5_ = self->priv->op_cancellable;
		g_cancellable_cancel (_tmp5_);
		_g_object_unref0 (self->priv->op_cancellable);
		self->priv->op_cancellable = NULL;
		_data95_->found = TRUE;
	}
	_tmp6_ = self->priv->queue;
	_tmp7_ = geary_nonblocking_queue_revoke_matching (_tmp6_, ___lambda127__gee_predicate, block95_data_ref (_data95_), block95_data_unref);
	_tmp8_ = _tmp7_;
	_g_object_unref0 (_tmp8_);
	result = _data95_->found;
	block95_data_unref (_data95_);
	_data95_ = NULL;
	return result;
}

void
geary_imap_engine_account_processor_stop (GearyImapEngineAccountProcessor* self)
{
	GCancellable* _tmp0_;
	GearyNonblockingQueue* _tmp2_;
	g_return_if_fail (GEARY_IMAP_ENGINE_IS_ACCOUNT_PROCESSOR (self));
	self->priv->is_running = FALSE;
	_tmp0_ = self->priv->op_cancellable;
	if (_tmp0_ != NULL) {
		GCancellable* _tmp1_;
		_tmp1_ = self->priv->op_cancellable;
		g_cancellable_cancel (_tmp1_);
		_g_object_unref0 (self->priv->op_cancellable);
		self->priv->op_cancellable = NULL;
	}
	_tmp2_ = self->priv->queue;
	geary_nonblocking_queue_clear (_tmp2_);
}

/** {@inheritDoc} */
static GearyLoggingState*
geary_imap_engine_account_processor_real_to_logging_state (GearyImapEngineAccountProcessor* self)
{
	GearyNonblockingQueue* _tmp0_;
	gint _tmp1_;
	gint _tmp2_;
	GearyLoggingState* _tmp3_;
	GearyLoggingState* result;
	_tmp0_ = self->priv->queue;
	_tmp1_ = geary_nonblocking_queue_get_size (_tmp0_);
	_tmp2_ = _tmp1_;
	_tmp3_ = geary_logging_state_new (G_TYPE_CHECK_INSTANCE_CAST (self, GEARY_LOGGING_TYPE_SOURCE, GearyLoggingSource), "queued: %d", _tmp2_);
	result = _tmp3_;
	return result;
}

GearyLoggingState*
geary_imap_engine_account_processor_to_logging_state (GearyImapEngineAccountProcessor* self)
{
	GearyImapEngineAccountProcessorClass* _klass_;
	g_return_val_if_fail (GEARY_IMAP_ENGINE_IS_ACCOUNT_PROCESSOR (self), NULL);
	_klass_ = GEARY_IMAP_ENGINE_ACCOUNT_PROCESSOR_GET_CLASS (self);
	if (_klass_->to_logging_state) {
		return _klass_->to_logging_state (self);
	}
	return NULL;
}

/** Sets the processor's logging parent. */
void
geary_imap_engine_account_processor_set_logging_parent (GearyImapEngineAccountProcessor* self,
                                                        GearyLoggingSource* parent)
{
	g_return_if_fail (GEARY_IMAP_ENGINE_IS_ACCOUNT_PROCESSOR (self));
	g_return_if_fail (GEARY_LOGGING_IS_SOURCE (parent));
	self->priv->_logging_parent = parent;
}

static void
geary_imap_engine_account_processor_run_data_free (gpointer _data)
{
	GearyImapEngineAccountProcessorRunData* _data_;
	_data_ = _data;
	_g_object_unref0 (_data_->self);
	g_slice_free (GearyImapEngineAccountProcessorRunData, _data_);
}

static void
geary_imap_engine_account_processor_run (GearyImapEngineAccountProcessor* self,
                                         GAsyncReadyCallback _callback_,
                                         gpointer _user_data_)
{
	GearyImapEngineAccountProcessorRunData* _data_;
	GearyImapEngineAccountProcessor* _tmp0_;
	g_return_if_fail (GEARY_IMAP_ENGINE_IS_ACCOUNT_PROCESSOR (self));
	_data_ = g_slice_new0 (GearyImapEngineAccountProcessorRunData);
	_data_->_async_result = g_task_new (G_OBJECT (self), NULL, _callback_, _user_data_);
	g_task_set_task_data (_data_->_async_result, _data_, geary_imap_engine_account_processor_run_data_free);
	_tmp0_ = _g_object_ref0 (self);
	_data_->self = _tmp0_;
	geary_imap_engine_account_processor_run_co (_data_);
}

static void
geary_imap_engine_account_processor_run_finish (GearyImapEngineAccountProcessor* self,
                                                GAsyncResult* _res_)
{
	GearyImapEngineAccountProcessorRunData* _data_;
	_data_ = g_task_propagate_pointer (G_TASK (_res_), NULL);
}

static void
geary_imap_engine_account_processor_run_ready (GObject* source_object,
                                               GAsyncResult* _res_,
                                               gpointer _user_data_)
{
	GearyImapEngineAccountProcessorRunData* _data_;
	_data_ = _user_data_;
	_data_->_source_object_ = source_object;
	_data_->_res_ = _res_;
	geary_imap_engine_account_processor_run_co (_data_);
}

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

static gboolean
geary_imap_engine_account_processor_run_co (GearyImapEngineAccountProcessorRunData* _data_)
{
	switch (_data_->_state_) {
		case 0:
		goto _state_0;
		case 1:
		goto _state_1;
		case 2:
		goto _state_2;
		default:
		g_assert_not_reached ();
	}
	_state_0:
	while (TRUE) {
		if (!_data_->self->priv->is_running) {
			break;
		}
		_data_->_tmp0_ = g_cancellable_new ();
		_g_object_unref0 (_data_->self->priv->op_cancellable);
		_data_->self->priv->op_cancellable = _data_->_tmp0_;
		_data_->op = NULL;
		{
			_data_->_tmp2_ = _data_->self->priv->queue;
			_data_->_tmp3_ = _data_->self->priv->op_cancellable;
			_data_->_state_ = 1;
			geary_nonblocking_queue_receive (_data_->_tmp2_, _data_->_tmp3_, geary_imap_engine_account_processor_run_ready, _data_);
			return FALSE;
			_state_1:
			_data_->_tmp4_ = geary_nonblocking_queue_receive_finish (_data_->_tmp2_, _data_->_res_, &_data_->_inner_error0_);
			_data_->_tmp1_ = (GearyImapEngineAccountOperation*) _data_->_tmp4_;
			if (G_UNLIKELY (_data_->_inner_error0_ != NULL)) {
				goto __catch0_g_error;
			}
			_data_->_tmp5_ = _data_->_tmp1_;
			_data_->_tmp1_ = NULL;
			_g_object_unref0 (_data_->op);
			_data_->op = _data_->_tmp5_;
			_g_object_unref0 (_data_->_tmp1_);
		}
		goto __finally0;
		__catch0_g_error:
		{
			g_clear_error (&_data_->_inner_error0_);
			_g_object_unref0 (_data_->op);
			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;
		}
		__finally0:
		if (G_UNLIKELY (_data_->_inner_error0_ != NULL)) {
			_g_object_unref0 (_data_->op);
			g_critical ("file %s: line %d: uncaught error: %s (%s, %d)", __FILE__, __LINE__, _data_->_inner_error0_->message, g_quark_to_string (_data_->_inner_error0_->domain), _data_->_inner_error0_->code);
			g_clear_error (&_data_->_inner_error0_);
			g_object_unref (_data_->_async_result);
			return FALSE;
		}
		_data_->_tmp6_ = _data_->op;
		if (_data_->_tmp6_ != NULL) {
			_data_->_tmp7_ = _data_->op;
			_data_->_tmp8_ = geary_logging_source_to_string (G_TYPE_CHECK_INSTANCE_CAST (_data_->_tmp7_, GEARY_LOGGING_TYPE_SOURCE, GearyLoggingSource));
			_data_->_tmp9_ = _data_->_tmp8_;
			geary_logging_source_debug (G_TYPE_CHECK_INSTANCE_CAST (_data_->self, GEARY_LOGGING_TYPE_SOURCE, GearyLoggingSource), "Executing operation: %s", _data_->_tmp9_);
			_g_free0 (_data_->_tmp9_);
			_data_->_tmp10_ = _data_->op;
			_data_->_tmp11_ = _g_object_ref0 (_data_->_tmp10_);
			_g_object_unref0 (_data_->self->priv->current_op);
			_data_->self->priv->current_op = _data_->_tmp11_;
			_data_->_tmp12_ = _data_->self->priv->progress;
			if (_data_->_tmp12_ != NULL) {
				_data_->_tmp13_ = _data_->self->priv->progress;
				geary_progress_monitor_notify_start (_data_->_tmp13_);
			}
			_data_->op_error = NULL;
			_data_->network_errors = 0;
			while (TRUE) {
				_data_->_tmp14_ = _data_->op_error;
				if (!(_data_->_tmp14_ == NULL)) {
					break;
				}
				{
					_data_->_tmp15_ = _data_->op;
					_data_->_tmp16_ = _data_->self->priv->op_cancellable;
					_data_->_state_ = 2;
					geary_imap_engine_account_operation_execute (_data_->_tmp15_, _data_->_tmp16_, geary_imap_engine_account_processor_run_ready, _data_);
					return FALSE;
					_state_2:
					geary_imap_engine_account_operation_execute_finish (_data_->_tmp15_, _data_->_res_, &_data_->_inner_error0_);
					if (G_UNLIKELY (_data_->_inner_error0_ != NULL)) {
						if (_data_->_inner_error0_->domain == GEARY_IMAP_ERROR) {
							goto __catch1_geary_imap_error;
						}
						goto __catch1_g_error;
					}
					_data_->_tmp17_ = _data_->op;
					g_signal_emit_by_name (_data_->_tmp17_, "succeeded");
					break;
				}
				goto __finally1;
				__catch1_geary_imap_error:
				{
					_data_->err = _data_->_inner_error0_;
					_data_->_inner_error0_ = NULL;
					_data_->_tmp19_ = _data_->err;
					if (g_error_matches (_data_->_tmp19_, GEARY_IMAP_ERROR, GEARY_IMAP_ERROR_NOT_CONNECTED)) {
						_data_->network_errors = _data_->network_errors + 1;
						_data_->_tmp20_ = _data_->network_errors;
						_data_->_tmp18_ = _data_->_tmp20_ <= GEARY_IMAP_ENGINE_ACCOUNT_PROCESSOR_MAX_NETWORK_ERRORS;
					} else {
						_data_->_tmp18_ = FALSE;
					}
					if (_data_->_tmp18_) {
						_data_->_tmp21_ = _data_->err;
						_data_->_tmp22_ = _data_->_tmp21_->message;
						geary_logging_source_debug (G_TYPE_CHECK_INSTANCE_CAST (_data_->self, GEARY_LOGGING_TYPE_SOURCE, GearyLoggingSource), "Retrying operation due to network error: %s", _data_->_tmp22_);
					} else {
						_data_->_tmp23_ = _data_->err;
						_data_->_tmp24_ = _g_error_copy0 (_data_->_tmp23_);
						_g_error_free0 (_data_->op_error);
						_data_->op_error = _data_->_tmp24_;
					}
					_g_error_free0 (_data_->err);
				}
				goto __finally1;
				__catch1_g_error:
				{
					_data_->_vala1_err = _data_->_inner_error0_;
					_data_->_inner_error0_ = NULL;
					_data_->_tmp25_ = _data_->_vala1_err;
					_data_->_tmp26_ = _g_error_copy0 (_data_->_tmp25_);
					_g_error_free0 (_data_->op_error);
					_data_->op_error = _data_->_tmp26_;
					_g_error_free0 (_data_->_vala1_err);
				}
				__finally1:
				if (G_UNLIKELY (_data_->_inner_error0_ != NULL)) {
					_g_error_free0 (_data_->op_error);
					_g_object_unref0 (_data_->op);
					g_critical ("file %s: line %d: uncaught error: %s (%s, %d)", __FILE__, __LINE__, _data_->_inner_error0_->message, g_quark_to_string (_data_->_inner_error0_->domain), _data_->_inner_error0_->code);
					g_clear_error (&_data_->_inner_error0_);
					g_object_unref (_data_->_async_result);
					return FALSE;
				}
			}
			_data_->_tmp27_ = _data_->op_error;
			if (_data_->_tmp27_ != NULL) {
				_data_->_tmp28_ = _data_->op;
				_data_->_tmp29_ = _data_->op_error;
				g_signal_emit_by_name (_data_->_tmp28_, "failed", _data_->_tmp29_);
				_data_->_tmp30_ = _data_->op;
				_data_->_tmp31_ = _data_->op_error;
				g_signal_emit (_data_->self, geary_imap_engine_account_processor_signals[GEARY_IMAP_ENGINE_ACCOUNT_PROCESSOR_OPERATION_ERROR_SIGNAL], 0, _data_->_tmp30_, _data_->_tmp31_);
			}
			_data_->_tmp32_ = _data_->op;
			g_signal_emit_by_name (_data_->_tmp32_, "completed");
			_g_object_unref0 (_data_->self->priv->current_op);
			_data_->self->priv->current_op = NULL;
			_g_object_unref0 (_data_->self->priv->op_cancellable);
			_data_->self->priv->op_cancellable = NULL;
			_data_->_tmp33_ = _data_->self->priv->progress;
			if (_data_->_tmp33_ != NULL) {
				_data_->_tmp34_ = _data_->self->priv->progress;
				geary_progress_monitor_notify_finish (_data_->_tmp34_);
			}
			_g_error_free0 (_data_->op_error);
		}
		_g_object_unref0 (_data_->op);
	}
	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_imap_engine_account_processor_class_init (GearyImapEngineAccountProcessorClass * klass,
                                                gpointer klass_data)
{
	geary_imap_engine_account_processor_parent_class = g_type_class_peek_parent (klass);
	g_type_class_adjust_private_offset (klass, &GearyImapEngineAccountProcessor_private_offset);
	((GearyImapEngineAccountProcessorClass *) klass)->to_logging_state = (GearyLoggingState* (*) (GearyImapEngineAccountProcessor*)) geary_imap_engine_account_processor_real_to_logging_state;
	G_OBJECT_CLASS (klass)->get_property = _vala_geary_imap_engine_account_processor_get_property;
	G_OBJECT_CLASS (klass)->finalize = geary_imap_engine_account_processor_finalize;
	/** Determines an operation is currently being executed. */
	g_object_class_install_property (G_OBJECT_CLASS (klass), GEARY_IMAP_ENGINE_ACCOUNT_PROCESSOR_IS_EXECUTING_PROPERTY, geary_imap_engine_account_processor_properties[GEARY_IMAP_ENGINE_ACCOUNT_PROCESSOR_IS_EXECUTING_PROPERTY] = g_param_spec_boolean ("is-executing", "is-executing", "is-executing", FALSE, G_PARAM_STATIC_STRINGS | G_PARAM_READABLE));
	/** Returns the number of operations currently waiting in the queue. */
	g_object_class_install_property (G_OBJECT_CLASS (klass), GEARY_IMAP_ENGINE_ACCOUNT_PROCESSOR_WAITING_PROPERTY, geary_imap_engine_account_processor_properties[GEARY_IMAP_ENGINE_ACCOUNT_PROCESSOR_WAITING_PROPERTY] = g_param_spec_uint ("waiting", "waiting", "waiting", 0, G_MAXUINT, 0U, G_PARAM_STATIC_STRINGS | G_PARAM_READABLE));
	/** {@inheritDoc} */
	g_object_class_install_property (G_OBJECT_CLASS (klass), GEARY_IMAP_ENGINE_ACCOUNT_PROCESSOR_LOGGING_PARENT_PROPERTY, geary_imap_engine_account_processor_properties[GEARY_IMAP_ENGINE_ACCOUNT_PROCESSOR_LOGGING_PARENT_PROPERTY] = g_param_spec_object ("logging-parent", "logging-parent", "logging-parent", GEARY_LOGGING_TYPE_SOURCE, G_PARAM_STATIC_STRINGS | G_PARAM_READABLE));
	/** Fired when an error occurs processing an operation. */
	geary_imap_engine_account_processor_signals[GEARY_IMAP_ENGINE_ACCOUNT_PROCESSOR_OPERATION_ERROR_SIGNAL] = g_signal_new ("operation-error", GEARY_IMAP_ENGINE_TYPE_ACCOUNT_PROCESSOR, G_SIGNAL_RUN_LAST, 0, NULL, NULL, g_cclosure_user_marshal_VOID__OBJECT_POINTER, G_TYPE_NONE, 2, GEARY_IMAP_ENGINE_TYPE_ACCOUNT_OPERATION, G_TYPE_POINTER);
}

static void
geary_imap_engine_account_processor_geary_logging_source_interface_init (GearyLoggingSourceIface * iface,
                                                                         gpointer iface_data)
{
	geary_imap_engine_account_processor_geary_logging_source_parent_iface = g_type_interface_peek_parent (iface);
	iface->to_logging_state = (GearyLoggingState* (*) (GearyLoggingSource*)) geary_imap_engine_account_processor_to_logging_state;
	iface->get_logging_parent = geary_imap_engine_account_processor_real_get_logging_parent;
}

static void
geary_imap_engine_account_processor_instance_init (GearyImapEngineAccountProcessor * self,
                                                   gpointer klass)
{
	GearyNonblockingQueue* _tmp0_;
	self->priv = geary_imap_engine_account_processor_get_instance_private (self);
	self->priv->_logging_parent = NULL;
	_tmp0_ = geary_nonblocking_queue_new_fifo (GEARY_IMAP_ENGINE_TYPE_ACCOUNT_OPERATION, (GBoxedCopyFunc) g_object_ref, (GDestroyNotify) g_object_unref, _geary_imap_engine_account_processor_op_equal_gee_equal_data_func, NULL, NULL);
	self->priv->queue = _tmp0_;
	self->priv->current_op = NULL;
	self->priv->op_cancellable = NULL;
}

static void
geary_imap_engine_account_processor_finalize (GObject * obj)
{
	GearyImapEngineAccountProcessor * self;
	self = G_TYPE_CHECK_INSTANCE_CAST (obj, GEARY_IMAP_ENGINE_TYPE_ACCOUNT_PROCESSOR, GearyImapEngineAccountProcessor);
	_g_object_unref0 (self->priv->queue);
	_g_object_unref0 (self->priv->current_op);
	_g_object_unref0 (self->priv->op_cancellable);
	_g_object_unref0 (self->priv->progress);
	G_OBJECT_CLASS (geary_imap_engine_account_processor_parent_class)->finalize (obj);
}

/**
 * Queues and asynchronously executes {@link AccountOperation} instances.
 *
 * Operations that are equal to any currently executing or currently
 * in the queue will not be re-queued.
 *
 * Errors thrown are reported to the user via the account's
 * `problem_report` signal. Normally if an operation throws an error
 * it will not be re-queued, however if a network connection error
 * occurs the error will be suppressed and it will be re-attempted
 * once, to allow for the network dropping out mid-execution.
 */
 G_GNUC_NO_INLINE static GType
geary_imap_engine_account_processor_get_type_once (void)
{
	static const GTypeInfo g_define_type_info = { sizeof (GearyImapEngineAccountProcessorClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) geary_imap_engine_account_processor_class_init, (GClassFinalizeFunc) NULL, NULL, sizeof (GearyImapEngineAccountProcessor), 0, (GInstanceInitFunc) geary_imap_engine_account_processor_instance_init, NULL };
	static const GInterfaceInfo geary_logging_source_info = { (GInterfaceInitFunc) geary_imap_engine_account_processor_geary_logging_source_interface_init, (GInterfaceFinalizeFunc) NULL, NULL};
	GType geary_imap_engine_account_processor_type_id;
	geary_imap_engine_account_processor_type_id = g_type_register_static (GEARY_TYPE_BASE_OBJECT, "GearyImapEngineAccountProcessor", &g_define_type_info, 0);
	g_type_add_interface_static (geary_imap_engine_account_processor_type_id, GEARY_LOGGING_TYPE_SOURCE, &geary_logging_source_info);
	GearyImapEngineAccountProcessor_private_offset = g_type_add_instance_private (geary_imap_engine_account_processor_type_id, sizeof (GearyImapEngineAccountProcessorPrivate));
	return geary_imap_engine_account_processor_type_id;
}

GType
geary_imap_engine_account_processor_get_type (void)
{
	static gsize geary_imap_engine_account_processor_type_id__once = 0;
	if (g_once_init_enter (&geary_imap_engine_account_processor_type_id__once)) {
		GType geary_imap_engine_account_processor_type_id;
		geary_imap_engine_account_processor_type_id = geary_imap_engine_account_processor_get_type_once ();
		g_once_init_leave (&geary_imap_engine_account_processor_type_id__once, geary_imap_engine_account_processor_type_id);
	}
	return geary_imap_engine_account_processor_type_id__once;
}

static void
_vala_geary_imap_engine_account_processor_get_property (GObject * object,
                                                        guint property_id,
                                                        GValue * value,
                                                        GParamSpec * pspec)
{
	GearyImapEngineAccountProcessor * self;
	self = G_TYPE_CHECK_INSTANCE_CAST (object, GEARY_IMAP_ENGINE_TYPE_ACCOUNT_PROCESSOR, GearyImapEngineAccountProcessor);
	switch (property_id) {
		case GEARY_IMAP_ENGINE_ACCOUNT_PROCESSOR_IS_EXECUTING_PROPERTY:
		g_value_set_boolean (value, geary_imap_engine_account_processor_get_is_executing (self));
		break;
		case GEARY_IMAP_ENGINE_ACCOUNT_PROCESSOR_WAITING_PROPERTY:
		g_value_set_uint (value, geary_imap_engine_account_processor_get_waiting (self));
		break;
		case GEARY_IMAP_ENGINE_ACCOUNT_PROCESSOR_LOGGING_PARENT_PROPERTY:
		g_value_set_object (value, geary_logging_source_get_logging_parent (G_TYPE_CHECK_INSTANCE_CAST (self, GEARY_LOGGING_TYPE_SOURCE, GearyLoggingSource)));
		break;
		default:
		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
		break;
	}
}

