/* ToolInstance.c generated by valac 0.56.18-dirty, the Vala compiler
 * generated from ToolInstance.vala, do not modify */

/* -*- Mode: Vala; indent-tabs-mode: nil; tab-width: 2 -*-
 *
 * SPDX-License-Identifier: GPL-3.0-or-later
 * SPDX-FileCopyrightText: Michael Terry
 */

#include <glib-object.h>
#include <stdlib.h>
#include <string.h>
#include <glib.h>
#include "deja.h"
#include <gio/gio.h>
#include <unistd.h>
#include <signal.h>
#include <sys/types.h>
#include <gio/gunixinputstream.h>
#include <sys/wait.h>
#include <glib/gstdio.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

#define TYPE_TOOL_INSTANCE (tool_instance_get_type ())
#define TOOL_INSTANCE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), TYPE_TOOL_INSTANCE, ToolInstance))
#define TOOL_INSTANCE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), TYPE_TOOL_INSTANCE, ToolInstanceClass))
#define IS_TOOL_INSTANCE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TYPE_TOOL_INSTANCE))
#define IS_TOOL_INSTANCE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), TYPE_TOOL_INSTANCE))
#define TOOL_INSTANCE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), TYPE_TOOL_INSTANCE, ToolInstanceClass))

typedef struct _ToolInstance ToolInstance;
typedef struct _ToolInstanceClass ToolInstanceClass;
typedef struct _ToolInstancePrivate ToolInstancePrivate;
enum  {
	TOOL_INSTANCE_0_PROPERTY,
	TOOL_INSTANCE_VERBOSE_PROPERTY,
	TOOL_INSTANCE_FORCED_CACHE_DIR_PROPERTY,
	TOOL_INSTANCE_NUM_PROPERTIES
};
static GParamSpec* tool_instance_properties[TOOL_INSTANCE_NUM_PROPERTIES];
#define _g_free0(var) (var = (g_free (var), NULL))
#define _g_main_loop_unref0(var) ((var == NULL) ? NULL : (var = (g_main_loop_unref (var), NULL)))
#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 _ToolInstanceStartData ToolInstanceStartData;
typedef struct _ToolInstanceStartInternalData ToolInstanceStartInternalData;
typedef struct _ToolInstanceReadLogLinesData ToolInstanceReadLogLinesData;
typedef struct _ToolInstanceReadLogData ToolInstanceReadLogData;
enum  {
	TOOL_INSTANCE_DONE_SIGNAL,
	TOOL_INSTANCE_EXITED_SIGNAL,
	TOOL_INSTANCE_NUM_SIGNALS
};
static guint tool_instance_signals[TOOL_INSTANCE_NUM_SIGNALS] = {0};

struct _ToolInstance {
	GObject parent_instance;
	ToolInstancePrivate * priv;
};

struct _ToolInstanceClass {
	GObjectClass parent_class;
	gchar* (*_name) (ToolInstance* self);
	void (*_send_error) (ToolInstance* self, GError* e);
	gboolean (*_process_line) (ToolInstance* self, const gchar* stanza, const gchar* line, gboolean* loggable, GError** error);
	void (*_edit_envp) (ToolInstance* self, GList* envp);
};

struct _ToolInstancePrivate {
	gboolean _verbose;
	gchar* _forced_cache_dir;
	guint watch_id;
	GPid child_pid;
	gboolean reading_done;
	gboolean process_done;
	gint status;
	gint dd_stdout;
	gint dd_stderr;
	GMainLoop* read_loop;
	GQueue* tail;
};

struct _ToolInstanceStartData {
	int _state_;
	GObject* _source_object_;
	GAsyncResult* _res_;
	GTask* _async_result;
	ToolInstance* self;
	GList* argv_in;
	GList* envp_in;
	GList* argv;
	GList* _tmp0_;
	GList* envp;
	GList* _tmp1_;
	GError* e;
	GError* _tmp2_;
	GError* _inner_error0_;
};

struct _ToolInstanceStartInternalData {
	int _state_;
	GObject* _source_object_;
	GAsyncResult* _res_;
	GTask* _async_result;
	ToolInstance* self;
	GList* argv_in;
	GList* envp_in;
	gchar* verbose_str;
	const gchar* _tmp0_;
	gchar* _tmp1_;
	gboolean _tmp2_;
	const gchar* _tmp3_;
	const gchar* _tmp4_;
	gchar** real_envp;
	gint _tmp5_;
	gchar** _tmp6_;
	gint real_envp_length1;
	gint _real_envp_size_;
	GList* argv;
	GList* arg_collection;
	GList* arg_it;
	gchar* _tmp7_;
	gchar* arg;
	const gchar* _tmp8_;
	gchar* _tmp9_;
	gchar* user_cmd;
	GList* _tmp10_;
	GList* a_collection;
	GList* a_it;
	gchar* _tmp11_;
	gchar* a;
	const gchar* _tmp12_;
	const gchar* _tmp13_;
	const gchar* _tmp14_;
	gchar* _tmp15_;
	const gchar* _tmp16_;
	const gchar* _tmp17_;
	gchar* _tmp18_;
	gchar* _tmp19_;
	gchar* _tmp20_;
	gchar** real_argv;
	GList* _tmp21_;
	gchar** _tmp22_;
	gint real_argv_length1;
	gint _real_argv_size_;
	gint i;
	GList* _tmp23_;
	GList* _vala1_a_collection;
	GList* _vala1_a_it;
	gchar* _tmp24_;
	gchar* _vala1_a;
	gchar** _tmp25_;
	gint _tmp25__length1;
	gint _tmp26_;
	const gchar* _tmp27_;
	gchar* _tmp28_;
	gchar** _tmp29_;
	gint _tmp29__length1;
	gint _tmp30_;
	gchar** _tmp31_;
	gchar** _tmp32_;
	gint _tmp32__length1;
	gchar** _tmp33_;
	gint _tmp33__length1;
	GPid _tmp34_;
	gint _tmp35_;
	gint _tmp36_;
	gchar* cmd_msg;
	const gchar* _tmp37_;
	gchar* _tmp38_;
	gboolean _tmp39_;
	const gchar* _tmp40_;
	const gchar* _tmp41_;
	const gchar* _tmp42_;
	GError* _inner_error0_;
};

struct _ToolInstanceReadLogLinesData {
	int _state_;
	GObject* _source_object_;
	GAsyncResult* _res_;
	GTask* _async_result;
	ToolInstance* self;
	GDataInputStream* reader;
	gchar* stanza;
	gchar* _tmp0_;
	gchar* line;
	gchar* _tmp1_;
	const gchar* _tmp2_;
	gboolean _tmp3_;
	const gchar* _tmp4_;
	const gchar* _tmp5_;
	const gchar* _tmp6_;
	gchar* _tmp7_;
	gboolean loggable;
	gboolean _tmp8_;
	const gchar* _tmp9_;
	const gchar* _tmp10_;
	gboolean _tmp11_;
	gboolean _tmp12_;
	const gchar* _tmp13_;
	gchar* _tmp14_;
	GError* err;
	GError* _tmp15_;
	const gchar* _tmp16_;
	const gchar* _tmp17_;
	gchar* _tmp18_;
	GError* _vala1_err;
	GError* _tmp19_;
	const gchar* _tmp20_;
	GError* _inner_error0_;
};

struct _ToolInstanceReadLogData {
	int _state_;
	GObject* _source_object_;
	GAsyncResult* _res_;
	GTask* _async_result;
	ToolInstance* self;
	GUnixInputStream* err_stream;
	GUnixInputStream* _tmp0_;
	GDataInputStream* err_reader;
	GDataInputStream* _tmp1_;
	GUnixInputStream* out_stream;
	GUnixInputStream* _tmp2_;
	GDataInputStream* out_reader;
	GDataInputStream* _tmp3_;
	GMainLoop* _tmp4_;
	GMainLoop* _tmp5_;
};

static gint ToolInstance_private_offset;
static gpointer tool_instance_parent_class = NULL;

VALA_EXTERN GType tool_instance_get_type (void) G_GNUC_CONST ;
VALA_EXTERN gchar* _tool_instance_name (ToolInstance* self);
VALA_EXTERN void _tool_instance_send_error (ToolInstance* self,
                                GError* e);
VALA_EXTERN gboolean _tool_instance_process_line (ToolInstance* self,
                                      const gchar* stanza,
                                      const gchar* line,
                                      gboolean* loggable,
                                      GError** error);
VALA_EXTERN void _tool_instance_edit_envp (ToolInstance* self,
                               GList* envp);
VALA_EXTERN gboolean tool_instance_is_started (ToolInstance* self);
static void tool_instance_kill_child (ToolInstance* self);
static void _g_free0_ (gpointer var);
static inline void _g_queue_free__g_free0_ (GQueue* self);
VALA_EXTERN gint tool_instance_prefix_wrapper_args (GList** args,
                                        GError** error);
static void tool_instance_start_data_free (gpointer _data);
VALA_EXTERN void tool_instance_start (ToolInstance* self,
                          GList* argv_in,
                          GList* envp_in,
                          GAsyncReadyCallback _callback_,
                          gpointer _user_data_);
VALA_EXTERN void tool_instance_start_finish (ToolInstance* self,
                                 GAsyncResult* _res_);
static gboolean tool_instance_start_co (ToolInstanceStartData* _data_);
static gpointer _g_strdup_gcopy_func (gconstpointer src,
                               gpointer self);
static void tool_instance_start_internal (ToolInstance* self,
                                   GList* argv_in,
                                   GList* envp_in,
                                   GAsyncReadyCallback _callback_,
                                   gpointer _user_data_);
static void tool_instance_start_internal_finish (ToolInstance* self,
                                          GAsyncResult* _res_,
                                          GError** error);
static void tool_instance_start_ready (GObject* source_object,
                                GAsyncResult* _res_,
                                gpointer _user_data_);
static inline void _g_list_free__g_free0_ (GList* self);
VALA_EXTERN void tool_instance_cancel (ToolInstance* self);
VALA_EXTERN void tool_instance_pause (ToolInstance* self);
static void tool_instance_stop_child (ToolInstance* self);
VALA_EXTERN void tool_instance_resume (ToolInstance* self);
static void tool_instance_cont_child (ToolInstance* self);
static gchar* tool_instance_real__name (ToolInstance* self);
static void tool_instance_real__send_error (ToolInstance* self,
                                     GError* e);
static gboolean tool_instance_real__process_line (ToolInstance* self,
                                           const gchar* stanza,
                                           const gchar* line,
                                           gboolean* loggable,
                                           GError** error);
static void tool_instance_real__edit_envp (ToolInstance* self,
                                    GList* envp);
static void tool_instance_start_internal_data_free (gpointer _data);
static gboolean tool_instance_start_internal_co (ToolInstanceStartInternalData* _data_);
static void tool_instance_set_verbose (ToolInstance* self,
                                gboolean value);
static void __lambda18_ (ToolInstance* self);
static void ___lambda18__gspawn_child_setup_func (gpointer self);
VALA_EXTERN gboolean tool_instance_get_verbose (ToolInstance* self);
static void tool_instance_add_stanza_to_tail (ToolInstance* self,
                                       const gchar* stanza);
static void tool_instance_spawn_finished (ToolInstance* self,
                                   GPid pid,
                                   gint status);
static void _tool_instance_spawn_finished_gchild_watch_func (GPid pid,
                                                      gint wait_status,
                                                      gpointer self);
static void tool_instance_read_log (ToolInstance* self,
                             GAsyncReadyCallback _callback_,
                             gpointer _user_data_);
static void tool_instance_read_log_finish (ToolInstance* self,
                                    GAsyncResult* _res_);
static void tool_instance_start_internal_ready (GObject* source_object,
                                         GAsyncResult* _res_,
                                         gpointer _user_data_);
static void tool_instance_read_log_lines_data_free (gpointer _data);
static void tool_instance_read_log_lines (ToolInstance* self,
                                   GDataInputStream* reader,
                                   GAsyncReadyCallback _callback_,
                                   gpointer _user_data_);
static void tool_instance_read_log_lines_finish (ToolInstance* self,
                                          GAsyncResult* _res_);
static gboolean tool_instance_read_log_lines_co (ToolInstanceReadLogLinesData* _data_);
static void tool_instance_read_log_lines_ready (GObject* source_object,
                                         GAsyncResult* _res_,
                                         gpointer _user_data_);
static void tool_instance_send_done_for_status (ToolInstance* self);
static void tool_instance_read_log_data_free (gpointer _data);
static gboolean tool_instance_read_log_co (ToolInstanceReadLogData* _data_);
static void tool_instance_write_tail_to_cache (ToolInstance* self);
VALA_EXTERN ToolInstance* tool_instance_construct (GType object_type);
VALA_EXTERN const gchar* tool_instance_get_forced_cache_dir (ToolInstance* self);
VALA_EXTERN void tool_instance_set_forced_cache_dir (ToolInstance* self,
                                         const gchar* value);
static void g_cclosure_user_marshal_VOID__BOOLEAN_BOOLEAN (GClosure * closure,
                                                    GValue * return_value,
                                                    guint n_param_values,
                                                    const GValue * param_values,
                                                    gpointer invocation_hint,
                                                    gpointer marshal_data);
static void tool_instance_finalize (GObject * obj);
static GType tool_instance_get_type_once (void);
static void _vala_tool_instance_get_property (GObject * object,
                                       guint property_id,
                                       GValue * value,
                                       GParamSpec * pspec);
static void _vala_tool_instance_set_property (GObject * object,
                                       guint property_id,
                                       const GValue * value,
                                       GParamSpec * pspec);
static void _vala_array_destroy (gpointer array,
                          gssize array_length,
                          GDestroyNotify destroy_func);
static void _vala_array_free (gpointer array,
                       gssize array_length,
                       GDestroyNotify destroy_func);

static inline gpointer
tool_instance_get_instance_private (ToolInstance* self)
{
	return G_STRUCT_MEMBER_P (self, ToolInstance_private_offset);
}

static void
_g_free0_ (gpointer var)
{
	var = (g_free (var), NULL);
}

static inline void
_g_queue_free__g_free0_ (GQueue* self)
{
	g_queue_free_full (self, (GDestroyNotify) _g_free0_);
}

gint
tool_instance_prefix_wrapper_args (GList** args,
                                   GError** error)
{
	DejaDupFilteredSettings* settings = NULL;
	DejaDupFilteredSettings* _tmp0_;
	gchar* wrapper = NULL;
	DejaDupFilteredSettings* _tmp1_;
	gchar* _tmp2_;
	const gchar* _tmp3_;
	gchar** parsed = NULL;
	gint parsed_length1 = 0;
	gint _parsed_size_ = 0;
	const gchar* _tmp4_;
	gchar** _tmp5_ = NULL;
	gint _tmp6_ = 0;
	gchar** _tmp15_;
	gint _tmp15__length1;
	GError* _inner_error0_ = NULL;
	gint result;
	_tmp0_ = deja_dup_get_settings (NULL);
	settings = _tmp0_;
	_tmp1_ = settings;
	_tmp2_ = g_settings_get_string ((GSettings*) _tmp1_, DEJA_DUP_CUSTOM_TOOL_WRAPPER_KEY);
	wrapper = _tmp2_;
	_tmp3_ = wrapper;
	if (g_strcmp0 (_tmp3_, "") == 0) {
		result = 0;
		_g_free0 (wrapper);
		_g_object_unref0 (settings);
		return result;
	}
	_tmp4_ = wrapper;
	g_shell_parse_argv (_tmp4_, &_tmp6_, &_tmp5_, &_inner_error0_);
	parsed = (_vala_array_free (parsed, parsed_length1, (GDestroyNotify) g_free), NULL);
	parsed = _tmp5_;
	parsed_length1 = _tmp6_;
	_parsed_size_ = parsed_length1;
	if (G_UNLIKELY (_inner_error0_ != NULL)) {
		if (_inner_error0_->domain == G_SHELL_ERROR) {
			gint _tmp7_ = -1;
			g_propagate_error (error, _inner_error0_);
			parsed = (_vala_array_free (parsed, parsed_length1, (GDestroyNotify) g_free), NULL);
			_g_free0 (wrapper);
			_g_object_unref0 (settings);
			return _tmp7_;
		} else {
			gint _tmp8_ = -1;
			parsed = (_vala_array_free (parsed, parsed_length1, (GDestroyNotify) g_free), NULL);
			_g_free0 (wrapper);
			_g_object_unref0 (settings);
			g_critical ("file %s: line %d: uncaught error: %s (%s, %d)", __FILE__, __LINE__, _inner_error0_->message, g_quark_to_string (_inner_error0_->domain), _inner_error0_->code);
			g_clear_error (&_inner_error0_);
			return _tmp8_;
		}
	}
	{
		gint i = 0;
		gchar** _tmp9_;
		gint _tmp9__length1;
		_tmp9_ = parsed;
		_tmp9__length1 = parsed_length1;
		i = _tmp9__length1 - 1;
		{
			gboolean _tmp10_ = FALSE;
			_tmp10_ = TRUE;
			while (TRUE) {
				gchar** _tmp12_;
				gint _tmp12__length1;
				const gchar* _tmp13_;
				gchar* _tmp14_;
				if (!_tmp10_) {
					gint _tmp11_;
					_tmp11_ = i;
					i = _tmp11_ - 1;
				}
				_tmp10_ = FALSE;
				if (!(i >= 0)) {
					break;
				}
				_tmp12_ = parsed;
				_tmp12__length1 = parsed_length1;
				_tmp13_ = _tmp12_[i];
				_tmp14_ = g_strdup (_tmp13_);
				*args = g_list_prepend (*args, _tmp14_);
			}
		}
	}
	_tmp15_ = parsed;
	_tmp15__length1 = parsed_length1;
	result = _tmp15__length1;
	parsed = (_vala_array_free (parsed, parsed_length1, (GDestroyNotify) g_free), NULL);
	_g_free0 (wrapper);
	_g_object_unref0 (settings);
	return result;
}

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

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

void
tool_instance_start (ToolInstance* self,
                     GList* argv_in,
                     GList* envp_in,
                     GAsyncReadyCallback _callback_,
                     gpointer _user_data_)
{
	ToolInstanceStartData* _data_;
	ToolInstance* _tmp0_;
	g_return_if_fail (self != NULL);
	_data_ = g_slice_new0 (ToolInstanceStartData);
	_data_->_async_result = g_task_new (G_OBJECT (self), NULL, _callback_, _user_data_);
	g_task_set_task_data (_data_->_async_result, _data_, tool_instance_start_data_free);
	_tmp0_ = _g_object_ref0 (self);
	_data_->self = _tmp0_;
	_data_->argv_in = argv_in;
	_data_->envp_in = envp_in;
	tool_instance_start_co (_data_);
}

void
tool_instance_start_finish (ToolInstance* self,
                            GAsyncResult* _res_)
{
	ToolInstanceStartData* _data_;
	_data_ = g_task_propagate_pointer (G_TASK (_res_), NULL);
}

static gpointer
_g_strdup_gcopy_func (gconstpointer src,
                      gpointer self)
{
	gpointer result;
	result = g_strdup ((const gchar*) src);
	return result;
}

static void
tool_instance_start_ready (GObject* source_object,
                           GAsyncResult* _res_,
                           gpointer _user_data_)
{
	ToolInstanceStartData* _data_;
	_data_ = _user_data_;
	_data_->_source_object_ = source_object;
	_data_->_res_ = _res_;
	tool_instance_start_co (_data_);
}

static inline void
_g_list_free__g_free0_ (GList* self)
{
	g_list_free_full (self, (GDestroyNotify) _g_free0_);
}

static gboolean
tool_instance_start_co (ToolInstanceStartData* _data_)
{
	switch (_data_->_state_) {
		case 0:
		goto _state_0;
		case 1:
		goto _state_1;
		default:
		g_assert_not_reached ();
	}
	_state_0:
	{
		_data_->_tmp0_ = g_list_copy_deep (_data_->argv_in, _g_strdup_gcopy_func, NULL);
		_data_->argv = _data_->_tmp0_;
		_data_->_tmp1_ = g_list_copy_deep (_data_->envp_in, _g_strdup_gcopy_func, NULL);
		_data_->envp = _data_->_tmp1_;
		_data_->_state_ = 1;
		tool_instance_start_internal (_data_->self, _data_->argv, _data_->envp, tool_instance_start_ready, _data_);
		return FALSE;
		_state_1:
		tool_instance_start_internal_finish (_data_->self, _data_->_res_, &_data_->_inner_error0_);
		if (G_UNLIKELY (_data_->_inner_error0_ != NULL)) {
			(_data_->envp == NULL) ? NULL : (_data_->envp = (_g_list_free__g_free0_ (_data_->envp), NULL));
			(_data_->argv == NULL) ? NULL : (_data_->argv = (_g_list_free__g_free0_ (_data_->argv), NULL));
			goto __catch0_g_error;
		}
		(_data_->envp == NULL) ? NULL : (_data_->envp = (_g_list_free__g_free0_ (_data_->envp), NULL));
		(_data_->argv == NULL) ? NULL : (_data_->argv = (_g_list_free__g_free0_ (_data_->argv), NULL));
	}
	goto __finally0;
	__catch0_g_error:
	{
		_data_->e = _data_->_inner_error0_;
		_data_->_inner_error0_ = NULL;
		_data_->_tmp2_ = _data_->e;
		_tool_instance_send_error (_data_->self, _data_->_tmp2_);
		g_signal_emit (_data_->self, tool_instance_signals[TOOL_INSTANCE_DONE_SIGNAL], 0, FALSE, FALSE);
		_g_error_free0 (_data_->e);
	}
	__finally0:
	if (G_UNLIKELY (_data_->_inner_error0_ != NULL)) {
		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;
	}
	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;
}

gboolean
tool_instance_is_started (ToolInstance* self)
{
	gboolean result;
	g_return_val_if_fail (self != NULL, FALSE);
	result = ((gint) self->priv->child_pid) > 0;
	return result;
}

void
tool_instance_cancel (ToolInstance* self)
{
	g_return_if_fail (self != NULL);
	if (tool_instance_is_started (self)) {
		tool_instance_kill_child (self);
	} else {
		g_signal_emit (self, tool_instance_signals[TOOL_INSTANCE_DONE_SIGNAL], 0, FALSE, TRUE);
	}
}

void
tool_instance_pause (ToolInstance* self)
{
	g_return_if_fail (self != NULL);
	if (tool_instance_is_started (self)) {
		tool_instance_stop_child (self);
	}
}

void
tool_instance_resume (ToolInstance* self)
{
	g_return_if_fail (self != NULL);
	if (tool_instance_is_started (self)) {
		tool_instance_cont_child (self);
	}
}

static gchar*
tool_instance_real__name (ToolInstance* self)
{
	g_critical ("Type `%s' does not implement abstract method `_tool_instance_name'", g_type_name (G_TYPE_FROM_INSTANCE (self)));
	return NULL;
}

gchar*
_tool_instance_name (ToolInstance* self)
{
	ToolInstanceClass* _klass_;
	g_return_val_if_fail (self != NULL, NULL);
	_klass_ = TOOL_INSTANCE_GET_CLASS (self);
	if (_klass_->_name) {
		return _klass_->_name (self);
	}
	return NULL;
}

static void
tool_instance_real__send_error (ToolInstance* self,
                                GError* e)
{
	g_critical ("Type `%s' does not implement abstract method `_tool_instance_send_error'", g_type_name (G_TYPE_FROM_INSTANCE (self)));
	return;
}

void
_tool_instance_send_error (ToolInstance* self,
                           GError* e)
{
	ToolInstanceClass* _klass_;
	g_return_if_fail (self != NULL);
	_klass_ = TOOL_INSTANCE_GET_CLASS (self);
	if (_klass_->_send_error) {
		_klass_->_send_error (self, e);
	}
}

static gboolean
tool_instance_real__process_line (ToolInstance* self,
                                  const gchar* stanza,
                                  const gchar* line,
                                  gboolean* loggable,
                                  GError** error)
{
	gboolean _tmp0_ = FALSE;
	g_critical ("Type `%s' does not implement abstract method `_tool_instance_process_line'", g_type_name (G_TYPE_FROM_INSTANCE (self)));
	return _tmp0_;
}

gboolean
_tool_instance_process_line (ToolInstance* self,
                             const gchar* stanza,
                             const gchar* line,
                             gboolean* loggable,
                             GError** error)
{
	ToolInstanceClass* _klass_;
	g_return_val_if_fail (self != NULL, FALSE);
	_klass_ = TOOL_INSTANCE_GET_CLASS (self);
	if (_klass_->_process_line) {
		return _klass_->_process_line (self, stanza, line, loggable, error);
	}
	return FALSE;
}

static void
tool_instance_real__edit_envp (ToolInstance* self,
                               GList* envp)
{
}

void
_tool_instance_edit_envp (ToolInstance* self,
                          GList* envp)
{
	ToolInstanceClass* _klass_;
	g_return_if_fail (self != NULL);
	_klass_ = TOOL_INSTANCE_GET_CLASS (self);
	if (_klass_->_edit_envp) {
		_klass_->_edit_envp (self, envp);
	}
}

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

static void
tool_instance_start_internal (ToolInstance* self,
                              GList* argv_in,
                              GList* envp_in,
                              GAsyncReadyCallback _callback_,
                              gpointer _user_data_)
{
	ToolInstanceStartInternalData* _data_;
	ToolInstance* _tmp0_;
	g_return_if_fail (self != NULL);
	_data_ = g_slice_new0 (ToolInstanceStartInternalData);
	_data_->_async_result = g_task_new (G_OBJECT (self), NULL, _callback_, _user_data_);
	g_task_set_task_data (_data_->_async_result, _data_, tool_instance_start_internal_data_free);
	_tmp0_ = _g_object_ref0 (self);
	_data_->self = _tmp0_;
	_data_->argv_in = argv_in;
	_data_->envp_in = envp_in;
	tool_instance_start_internal_co (_data_);
}

static void
tool_instance_start_internal_finish (ToolInstance* self,
                                     GAsyncResult* _res_,
                                     GError** error)
{
	ToolInstanceStartInternalData* _data_;
	_data_ = g_task_propagate_pointer (G_TASK (_res_), error);
	if (NULL == _data_) {
		return;
	}
}

static void
__lambda18_ (ToolInstance* self)
{
	setsid ();
}

static void
___lambda18__gspawn_child_setup_func (gpointer self)
{
	__lambda18_ ((ToolInstance*) self);
}

static void
_tool_instance_spawn_finished_gchild_watch_func (GPid pid,
                                                 gint wait_status,
                                                 gpointer self)
{
	tool_instance_spawn_finished ((ToolInstance*) self, pid, wait_status);
}

static void
tool_instance_start_internal_ready (GObject* source_object,
                                    GAsyncResult* _res_,
                                    gpointer _user_data_)
{
	ToolInstanceStartInternalData* _data_;
	_data_ = _user_data_;
	_data_->_source_object_ = source_object;
	_data_->_res_ = _res_;
	tool_instance_start_internal_co (_data_);
}

static gboolean
tool_instance_start_internal_co (ToolInstanceStartInternalData* _data_)
{
	switch (_data_->_state_) {
		case 0:
		goto _state_0;
		case 1:
		goto _state_1;
		default:
		g_assert_not_reached ();
	}
	_state_0:
	_data_->_tmp0_ = g_getenv ("DEJA_DUP_DEBUG");
	_data_->_tmp1_ = g_strdup (_data_->_tmp0_);
	_data_->verbose_str = _data_->_tmp1_;
	_data_->_tmp3_ = _data_->verbose_str;
	if (_data_->_tmp3_ != NULL) {
		_data_->_tmp4_ = _data_->verbose_str;
		_data_->_tmp2_ = atoi (_data_->_tmp4_) > 0;
	} else {
		_data_->_tmp2_ = FALSE;
	}
	if (_data_->_tmp2_) {
		tool_instance_set_verbose (_data_->self, TRUE);
	}
	_tool_instance_edit_envp (_data_->self, _data_->envp_in);
	_data_->_tmp5_ = 0;
	_data_->_tmp6_ = deja_dup_copy_env (_data_->envp_in, &_data_->_tmp5_);
	_data_->real_envp = _data_->_tmp6_;
	_data_->real_envp_length1 = _data_->_tmp5_;
	_data_->_real_envp_size_ = _data_->real_envp_length1;
	_data_->argv = NULL;
	{
		_data_->arg_collection = _data_->argv_in;
		for (_data_->arg_it = _data_->arg_collection; _data_->arg_it != NULL; _data_->arg_it = _data_->arg_it->next) {
			_data_->_tmp7_ = g_strdup ((const gchar*) _data_->arg_it->data);
			_data_->arg = _data_->_tmp7_;
			{
				_data_->_tmp8_ = _data_->arg;
				_data_->_tmp9_ = g_strdup (_data_->_tmp8_);
				_data_->argv = g_list_append (_data_->argv, _data_->_tmp9_);
				_g_free0 (_data_->arg);
			}
		}
	}
	tool_instance_prefix_wrapper_args (&_data_->argv, &_data_->_inner_error0_);
	if (G_UNLIKELY (_data_->_inner_error0_ != NULL)) {
		g_task_return_error (_data_->_async_result, _data_->_inner_error0_);
		(_data_->argv == NULL) ? NULL : (_data_->argv = (_g_list_free__g_free0_ (_data_->argv), NULL));
		_data_->real_envp = (_vala_array_free (_data_->real_envp, _data_->real_envp_length1, (GDestroyNotify) g_free), NULL);
		_g_free0 (_data_->verbose_str);
		g_object_unref (_data_->_async_result);
		return FALSE;
	}
	_data_->user_cmd = NULL;
	_data_->_tmp10_ = _data_->argv;
	{
		_data_->a_collection = _data_->_tmp10_;
		for (_data_->a_it = _data_->a_collection; _data_->a_it != NULL; _data_->a_it = _data_->a_it->next) {
			_data_->_tmp11_ = g_strdup ((const gchar*) _data_->a_it->data);
			_data_->a = _data_->_tmp11_;
			{
				_data_->_tmp12_ = _data_->a;
				if (_data_->_tmp12_ == NULL) {
					_g_free0 (_data_->a);
					break;
				}
				_data_->_tmp13_ = _data_->user_cmd;
				if (_data_->_tmp13_ == NULL) {
					_data_->_tmp14_ = _data_->a;
					_data_->_tmp15_ = g_strdup (_data_->_tmp14_);
					_g_free0 (_data_->user_cmd);
					_data_->user_cmd = _data_->_tmp15_;
				} else {
					_data_->_tmp16_ = _data_->user_cmd;
					_data_->_tmp17_ = _data_->a;
					_data_->_tmp18_ = g_shell_quote (_data_->_tmp17_);
					_data_->_tmp19_ = _data_->_tmp18_;
					_data_->_tmp20_ = g_strdup_printf ("%s %s", _data_->_tmp16_, _data_->_tmp19_);
					_g_free0 (_data_->user_cmd);
					_data_->user_cmd = _data_->_tmp20_;
					_g_free0 (_data_->_tmp19_);
				}
				_g_free0 (_data_->a);
			}
		}
	}
	_data_->_tmp21_ = _data_->argv;
	_data_->_tmp22_ = g_new0 (gchar*, g_list_length (_data_->_tmp21_) + 1);
	_data_->real_argv = _data_->_tmp22_;
	_data_->real_argv_length1 = g_list_length (_data_->_tmp21_);
	_data_->_real_argv_size_ = _data_->real_argv_length1;
	_data_->i = 0;
	_data_->_tmp23_ = _data_->argv;
	{
		_data_->_vala1_a_collection = _data_->_tmp23_;
		for (_data_->_vala1_a_it = _data_->_vala1_a_collection; _data_->_vala1_a_it != NULL; _data_->_vala1_a_it = _data_->_vala1_a_it->next) {
			_data_->_tmp24_ = g_strdup ((const gchar*) _data_->_vala1_a_it->data);
			_data_->_vala1_a = _data_->_tmp24_;
			{
				_data_->_tmp25_ = _data_->real_argv;
				_data_->_tmp25__length1 = _data_->real_argv_length1;
				_data_->_tmp26_ = _data_->i;
				_data_->i = _data_->_tmp26_ + 1;
				_data_->_tmp27_ = _data_->_vala1_a;
				_data_->_tmp28_ = g_strdup (_data_->_tmp27_);
				_g_free0 (_data_->_tmp25_[_data_->_tmp26_]);
				_data_->_tmp25_[_data_->_tmp26_] = _data_->_tmp28_;
				_g_free0 (_data_->_vala1_a);
			}
		}
	}
	_data_->_tmp29_ = _data_->real_argv;
	_data_->_tmp29__length1 = _data_->real_argv_length1;
	_data_->_tmp30_ = 0;
	_data_->_tmp31_ = deja_dup_nice_prefix (_data_->_tmp29_, (gint) _data_->_tmp29__length1, &_data_->_tmp30_);
	_data_->real_argv = (_vala_array_free (_data_->real_argv, _data_->real_argv_length1, (GDestroyNotify) g_free), NULL);
	_data_->real_argv = _data_->_tmp31_;
	_data_->real_argv_length1 = _data_->_tmp30_;
	_data_->_real_argv_size_ = _data_->real_argv_length1;
	_data_->_tmp32_ = _data_->real_argv;
	_data_->_tmp32__length1 = _data_->real_argv_length1;
	_data_->_tmp33_ = _data_->real_envp;
	_data_->_tmp33__length1 = _data_->real_envp_length1;
	_data_->_tmp34_ = 0;
	_data_->_tmp35_ = 0;
	_data_->_tmp36_ = 0;
	g_spawn_async_with_pipes (NULL, _data_->_tmp32_, _data_->_tmp33_, G_SPAWN_SEARCH_PATH | G_SPAWN_DO_NOT_REAP_CHILD, ___lambda18__gspawn_child_setup_func, _data_->self, &_data_->_tmp34_, NULL, &_data_->_tmp35_, &_data_->_tmp36_, &_data_->_inner_error0_);
	_data_->self->priv->child_pid = _data_->_tmp34_;
	_data_->self->priv->dd_stdout = _data_->_tmp35_;
	_data_->self->priv->dd_stderr = _data_->_tmp36_;
	if (G_UNLIKELY (_data_->_inner_error0_ != NULL)) {
		g_task_return_error (_data_->_async_result, _data_->_inner_error0_);
		_data_->real_argv = (_vala_array_free (_data_->real_argv, _data_->real_argv_length1, (GDestroyNotify) g_free), NULL);
		_g_free0 (_data_->user_cmd);
		(_data_->argv == NULL) ? NULL : (_data_->argv = (_g_list_free__g_free0_ (_data_->argv), NULL));
		_data_->real_envp = (_vala_array_free (_data_->real_envp, _data_->real_envp_length1, (GDestroyNotify) g_free), NULL);
		_g_free0 (_data_->verbose_str);
		g_object_unref (_data_->_async_result);
		return FALSE;
	}
	_data_->_tmp37_ = _data_->user_cmd;
	_data_->_tmp38_ = g_strdup_printf ("Running the following tool (%i) command: %s", (gint) _data_->self->priv->child_pid, _data_->_tmp37_);
	_data_->cmd_msg = _data_->_tmp38_;
	_data_->_tmp39_ = _data_->self->priv->_verbose;
	if (_data_->_tmp39_) {
		_data_->_tmp40_ = _data_->cmd_msg;
		g_print ("%s\n", _data_->_tmp40_);
	} else {
		_data_->_tmp41_ = _data_->cmd_msg;
		g_debug ("ToolInstance.vala:154: %s\n", _data_->_tmp41_);
	}
	_data_->_tmp42_ = _data_->cmd_msg;
	tool_instance_add_stanza_to_tail (_data_->self, _data_->_tmp42_);
	_data_->self->priv->watch_id = g_child_watch_add_full (G_PRIORITY_DEFAULT_IDLE, _data_->self->priv->child_pid, _tool_instance_spawn_finished_gchild_watch_func, g_object_ref (_data_->self), g_object_unref);
	_data_->_state_ = 1;
	tool_instance_read_log (_data_->self, tool_instance_start_internal_ready, _data_);
	return FALSE;
	_state_1:
	tool_instance_read_log_finish (_data_->self, _data_->_res_);
	_g_free0 (_data_->cmd_msg);
	_data_->real_argv = (_vala_array_free (_data_->real_argv, _data_->real_argv_length1, (GDestroyNotify) g_free), NULL);
	_g_free0 (_data_->user_cmd);
	(_data_->argv == NULL) ? NULL : (_data_->argv = (_g_list_free__g_free0_ (_data_->argv), NULL));
	_data_->real_envp = (_vala_array_free (_data_->real_envp, _data_->real_envp_length1, (GDestroyNotify) g_free), NULL);
	_g_free0 (_data_->verbose_str);
	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
tool_instance_kill_child (ToolInstance* self)
{
	g_return_if_fail (self != NULL);
	kill ((pid_t) self->priv->child_pid, (gint) SIGKILL);
}

static void
tool_instance_stop_child (ToolInstance* self)
{
	g_return_if_fail (self != NULL);
	kill ((pid_t) self->priv->child_pid, (gint) SIGSTOP);
}

static void
tool_instance_cont_child (ToolInstance* self)
{
	g_return_if_fail (self != NULL);
	kill ((pid_t) self->priv->child_pid, (gint) SIGCONT);
}

static void
tool_instance_read_log_lines_data_free (gpointer _data)
{
	ToolInstanceReadLogLinesData* _data_;
	_data_ = _data;
	_g_object_unref0 (_data_->reader);
	_g_object_unref0 (_data_->self);
	g_slice_free (ToolInstanceReadLogLinesData, _data_);
}

static void
tool_instance_read_log_lines (ToolInstance* self,
                              GDataInputStream* reader,
                              GAsyncReadyCallback _callback_,
                              gpointer _user_data_)
{
	ToolInstanceReadLogLinesData* _data_;
	ToolInstance* _tmp0_;
	GDataInputStream* _tmp1_;
	g_return_if_fail (self != NULL);
	g_return_if_fail (reader != NULL);
	_data_ = g_slice_new0 (ToolInstanceReadLogLinesData);
	_data_->_async_result = g_task_new (G_OBJECT (self), NULL, _callback_, _user_data_);
	g_task_set_task_data (_data_->_async_result, _data_, tool_instance_read_log_lines_data_free);
	_tmp0_ = _g_object_ref0 (self);
	_data_->self = _tmp0_;
	_tmp1_ = _g_object_ref0 (reader);
	_g_object_unref0 (_data_->reader);
	_data_->reader = _tmp1_;
	tool_instance_read_log_lines_co (_data_);
}

static void
tool_instance_read_log_lines_finish (ToolInstance* self,
                                     GAsyncResult* _res_)
{
	ToolInstanceReadLogLinesData* _data_;
	_data_ = g_task_propagate_pointer (G_TASK (_res_), NULL);
}

static void
tool_instance_read_log_lines_ready (GObject* source_object,
                                    GAsyncResult* _res_,
                                    gpointer _user_data_)
{
	ToolInstanceReadLogLinesData* _data_;
	_data_ = _user_data_;
	_data_->_source_object_ = source_object;
	_data_->_res_ = _res_;
	tool_instance_read_log_lines_co (_data_);
}

static gboolean
tool_instance_read_log_lines_co (ToolInstanceReadLogLinesData* _data_)
{
	switch (_data_->_state_) {
		case 0:
		goto _state_0;
		case 1:
		goto _state_1;
		default:
		g_assert_not_reached ();
	}
	_state_0:
	_data_->_tmp0_ = g_strdup ("");
	_data_->stanza = _data_->_tmp0_;
	while (TRUE) {
		if (!(_data_->reader != NULL)) {
			break;
		}
		{
			_data_->_state_ = 1;
			g_data_input_stream_read_line_async (_data_->reader, G_PRIORITY_DEFAULT, NULL, tool_instance_read_log_lines_ready, _data_);
			return FALSE;
			_state_1:
			_data_->_tmp1_ = g_data_input_stream_read_line_finish_utf8 (_data_->reader, _data_->_res_, NULL, &_data_->_inner_error0_);
			_data_->line = _data_->_tmp1_;
			if (G_UNLIKELY (_data_->_inner_error0_ != NULL)) {
				goto __catch0_g_error;
			}
			_data_->_tmp2_ = _data_->line;
			if (_data_->_tmp2_ == NULL) {
				_data_->self->priv->reading_done = TRUE;
				if (_data_->self->priv->process_done) {
					tool_instance_send_done_for_status (_data_->self);
				}
				_g_free0 (_data_->line);
				break;
			}
			_data_->_tmp3_ = _data_->self->priv->_verbose;
			if (_data_->_tmp3_) {
				_data_->_tmp4_ = _data_->line;
				g_print ("TOOL: %s\n", _data_->_tmp4_);
			}
			_data_->_tmp5_ = _data_->stanza;
			_data_->_tmp6_ = _data_->line;
			_data_->_tmp7_ = g_strconcat (_data_->_tmp5_, _data_->_tmp6_, NULL);
			_g_free0 (_data_->stanza);
			_data_->stanza = _data_->_tmp7_;
			{
				_data_->loggable = TRUE;
				_data_->_tmp9_ = _data_->stanza;
				_data_->_tmp10_ = _data_->line;
				_data_->_tmp11_ = FALSE;
				_data_->_tmp12_ = _tool_instance_process_line (_data_->self, _data_->_tmp9_, _data_->_tmp10_, &_data_->_tmp11_, &_data_->_inner_error0_);
				_data_->loggable = _data_->_tmp11_;
				_data_->_tmp8_ = _data_->_tmp12_;
				if (G_UNLIKELY (_data_->_inner_error0_ != NULL)) {
					goto __catch1_g_error;
				}
				if (_data_->_tmp8_) {
					if (_data_->loggable) {
						_data_->_tmp13_ = _data_->stanza;
						tool_instance_add_stanza_to_tail (_data_->self, _data_->_tmp13_);
					}
					_data_->_tmp14_ = g_strdup ("");
					_g_free0 (_data_->stanza);
					_data_->stanza = _data_->_tmp14_;
				}
			}
			goto __finally1;
			__catch1_g_error:
			{
				_data_->err = _data_->_inner_error0_;
				_data_->_inner_error0_ = NULL;
				_data_->_tmp15_ = _data_->err;
				_data_->_tmp16_ = _data_->_tmp15_->message;
				g_warning ("ToolInstance.vala:203: %s\n", _data_->_tmp16_);
				_data_->_tmp17_ = _data_->stanza;
				tool_instance_add_stanza_to_tail (_data_->self, _data_->_tmp17_);
				_data_->_tmp18_ = g_strdup ("");
				_g_free0 (_data_->stanza);
				_data_->stanza = _data_->_tmp18_;
				_g_error_free0 (_data_->err);
			}
			__finally1:
			if (G_UNLIKELY (_data_->_inner_error0_ != NULL)) {
				_g_free0 (_data_->line);
				goto __catch0_g_error;
			}
			_g_free0 (_data_->line);
		}
		goto __finally0;
		__catch0_g_error:
		{
			_data_->_vala1_err = _data_->_inner_error0_;
			_data_->_inner_error0_ = NULL;
			_data_->_tmp19_ = _data_->_vala1_err;
			_data_->_tmp20_ = _data_->_tmp19_->message;
			g_warning ("ToolInstance.vala:209: %s\n", _data_->_tmp20_);
			_g_error_free0 (_data_->_vala1_err);
			break;
		}
		__finally0:
		if (G_UNLIKELY (_data_->_inner_error0_ != NULL)) {
			_g_free0 (_data_->stanza);
			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;
		}
	}
	_g_free0 (_data_->stanza);
	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
tool_instance_read_log_data_free (gpointer _data)
{
	ToolInstanceReadLogData* _data_;
	_data_ = _data;
	_g_object_unref0 (_data_->self);
	g_slice_free (ToolInstanceReadLogData, _data_);
}

static void
tool_instance_read_log (ToolInstance* self,
                        GAsyncReadyCallback _callback_,
                        gpointer _user_data_)
{
	ToolInstanceReadLogData* _data_;
	ToolInstance* _tmp0_;
	g_return_if_fail (self != NULL);
	_data_ = g_slice_new0 (ToolInstanceReadLogData);
	_data_->_async_result = g_task_new (G_OBJECT (self), NULL, _callback_, _user_data_);
	g_task_set_task_data (_data_->_async_result, _data_, tool_instance_read_log_data_free);
	_tmp0_ = _g_object_ref0 (self);
	_data_->self = _tmp0_;
	tool_instance_read_log_co (_data_);
}

static void
tool_instance_read_log_finish (ToolInstance* self,
                               GAsyncResult* _res_)
{
	ToolInstanceReadLogData* _data_;
	_data_ = g_task_propagate_pointer (G_TASK (_res_), NULL);
}

static gboolean
tool_instance_read_log_co (ToolInstanceReadLogData* _data_)
{
	switch (_data_->_state_) {
		case 0:
		goto _state_0;
		default:
		g_assert_not_reached ();
	}
	_state_0:
	_data_->_tmp0_ = (GUnixInputStream*) g_unix_input_stream_new (_data_->self->priv->dd_stderr, TRUE);
	_data_->err_stream = _data_->_tmp0_;
	_data_->_tmp1_ = g_data_input_stream_new ((GInputStream*) _data_->err_stream);
	_data_->err_reader = _data_->_tmp1_;
	_data_->_tmp2_ = (GUnixInputStream*) g_unix_input_stream_new (_data_->self->priv->dd_stdout, TRUE);
	_data_->out_stream = _data_->_tmp2_;
	_data_->_tmp3_ = g_data_input_stream_new ((GInputStream*) _data_->out_stream);
	_data_->out_reader = _data_->_tmp3_;
	g_object_ref ((GObject*) _data_->self);
	_data_->_tmp4_ = g_main_loop_new (NULL, FALSE);
	_g_main_loop_unref0 (_data_->self->priv->read_loop);
	_data_->self->priv->read_loop = _data_->_tmp4_;
	tool_instance_read_log_lines (_data_->self, _data_->err_reader, NULL, NULL);
	tool_instance_read_log_lines (_data_->self, _data_->out_reader, NULL, NULL);
	_data_->_tmp5_ = _data_->self->priv->read_loop;
	g_main_loop_run (_data_->_tmp5_);
	_g_main_loop_unref0 (_data_->self->priv->read_loop);
	_data_->self->priv->read_loop = NULL;
	g_object_unref ((GObject*) _data_->self);
	_g_object_unref0 (_data_->out_reader);
	_g_object_unref0 (_data_->out_stream);
	_g_object_unref0 (_data_->err_reader);
	_g_object_unref0 (_data_->err_stream);
	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
tool_instance_spawn_finished (ToolInstance* self,
                              GPid pid,
                              gint status)
{
	g_return_if_fail (self != NULL);
	self->priv->status = status;
	if (WIFEXITED (status)) {
		gint exitval = 0;
		exitval = WEXITSTATUS (status);
		g_debug ("ToolInstance.vala:245: tool (%i) exited with value %i\n", (gint) pid, exitval);
	} else {
		g_debug ("ToolInstance.vala:248: tool (%i) process killed\n", (gint) pid);
	}
	self->priv->watch_id = (guint) 0;
	g_spawn_close_pid (pid);
	tool_instance_write_tail_to_cache (self);
	self->priv->process_done = TRUE;
	if (self->priv->reading_done) {
		tool_instance_send_done_for_status (self);
	}
}

static void
tool_instance_send_done_for_status (ToolInstance* self)
{
	gboolean _tmp0_ = FALSE;
	gboolean success = FALSE;
	gboolean cancelled = FALSE;
	GMainLoop* _tmp1_;
	g_return_if_fail (self != NULL);
	if (WIFEXITED (self->priv->status)) {
		_tmp0_ = WEXITSTATUS (self->priv->status) == 0;
	} else {
		_tmp0_ = FALSE;
	}
	success = _tmp0_;
	cancelled = !WIFEXITED (self->priv->status);
	if (WIFEXITED (self->priv->status)) {
		g_signal_emit (self, tool_instance_signals[TOOL_INSTANCE_EXITED_SIGNAL], 0, WEXITSTATUS (self->priv->status));
	}
	self->priv->child_pid = (GPid) 0;
	g_signal_emit (self, tool_instance_signals[TOOL_INSTANCE_DONE_SIGNAL], 0, success, cancelled);
	_tmp1_ = self->priv->read_loop;
	g_main_loop_quit (_tmp1_);
}

static void
tool_instance_add_stanza_to_tail (ToolInstance* self,
                                  const gchar* stanza)
{
	GQueue* _tmp0_;
	GQueue* _tmp2_;
	gchar* _tmp3_;
	g_return_if_fail (self != NULL);
	g_return_if_fail (stanza != NULL);
	_tmp0_ = self->priv->tail;
	if (_tmp0_ == NULL) {
		GQueue* _tmp1_;
		_tmp1_ = g_queue_new ();
		(self->priv->tail == NULL) ? NULL : (self->priv->tail = (_g_queue_free__g_free0_ (self->priv->tail), NULL));
		self->priv->tail = _tmp1_;
	}
	_tmp2_ = self->priv->tail;
	_tmp3_ = g_strdup (stanza);
	g_queue_push_tail (_tmp2_, _tmp3_);
	while (TRUE) {
		GQueue* _tmp4_;
		GQueue* _tmp5_;
		gpointer _tmp6_;
		gchar* _tmp7_;
		_tmp4_ = self->priv->tail;
		if (!(g_queue_get_length (_tmp4_) > ((guint) 50))) {
			break;
		}
		_tmp5_ = self->priv->tail;
		_tmp6_ = g_queue_pop_head (_tmp5_);
		_tmp7_ = (gchar*) _tmp6_;
		_g_free0 (_tmp7_);
	}
}

static void
tool_instance_write_tail_to_cache (ToolInstance* self)
{
	GQueue* _tmp0_;
	gchar* cachedir = NULL;
	const gchar* _tmp1_;
	gchar* _tmp2_;
	const gchar* _tmp3_;
	gchar* cachefile = NULL;
	const gchar* _tmp4_;
	gchar* _tmp5_;
	gchar* _tmp6_;
	gchar* _tmp7_;
	gchar* _tmp8_;
	gchar* _tmp9_;
	gchar* _tmp10_;
	gchar* contents = NULL;
	gchar* _tmp11_;
	GQueue* _tmp12_;
	GList* _tmp13_;
	GError* _inner_error0_ = NULL;
	g_return_if_fail (self != NULL);
	_tmp0_ = self->priv->tail;
	if (_tmp0_ == NULL) {
		return;
	}
	_tmp1_ = g_get_user_cache_dir ();
	_tmp2_ = g_strdup (_tmp1_);
	cachedir = _tmp2_;
	_tmp3_ = cachedir;
	if (_tmp3_ == NULL) {
		_g_free0 (cachedir);
		return;
	}
	_tmp4_ = cachedir;
	_tmp5_ = _tool_instance_name (self);
	_tmp6_ = _tmp5_;
	_tmp7_ = g_strconcat (_tmp6_, ".log", NULL);
	_tmp8_ = _tmp7_;
	_tmp9_ = g_build_filename (_tmp4_, PACKAGE, _tmp8_, NULL);
	_tmp10_ = _tmp9_;
	_g_free0 (_tmp8_);
	_g_free0 (_tmp6_);
	cachefile = _tmp10_;
	_tmp11_ = g_strdup ("");
	contents = _tmp11_;
	_tmp12_ = self->priv->tail;
	_tmp13_ = _tmp12_->head;
	{
		GList* stanza_collection = NULL;
		GList* stanza_it = NULL;
		stanza_collection = _tmp13_;
		for (stanza_it = stanza_collection; stanza_it != NULL; stanza_it = stanza_it->next) {
			gchar* _tmp14_;
			gchar* stanza = NULL;
			_tmp14_ = g_strdup ((const gchar*) stanza_it->data);
			stanza = _tmp14_;
			{
				const gchar* _tmp15_;
				const gchar* _tmp16_;
				gchar* _tmp17_;
				gchar* _tmp18_;
				gchar* _tmp19_;
				_tmp15_ = contents;
				_tmp16_ = stanza;
				_tmp17_ = g_strconcat (_tmp16_, "\n", NULL);
				_tmp18_ = _tmp17_;
				_tmp19_ = g_strconcat (_tmp15_, _tmp18_, NULL);
				_g_free0 (contents);
				contents = _tmp19_;
				_g_free0 (_tmp18_);
				_g_free0 (stanza);
			}
		}
	}
	{
		const gchar* _tmp20_;
		const gchar* _tmp21_;
		_tmp20_ = cachefile;
		_tmp21_ = contents;
		g_file_set_contents (_tmp20_, _tmp21_, (gssize) -1, &_inner_error0_);
		if (G_UNLIKELY (_inner_error0_ != NULL)) {
			goto __catch0_g_error;
		}
	}
	goto __finally0;
	__catch0_g_error:
	{
		GError* e = NULL;
		GError* _tmp22_;
		const gchar* _tmp23_;
		e = _inner_error0_;
		_inner_error0_ = NULL;
		_tmp22_ = e;
		_tmp23_ = _tmp22_->message;
		g_info ("ToolInstance.vala:306: %s", _tmp23_);
		_g_error_free0 (e);
	}
	__finally0:
	if (G_UNLIKELY (_inner_error0_ != NULL)) {
		_g_free0 (contents);
		_g_free0 (cachefile);
		_g_free0 (cachedir);
		g_critical ("file %s: line %d: uncaught error: %s (%s, %d)", __FILE__, __LINE__, _inner_error0_->message, g_quark_to_string (_inner_error0_->domain), _inner_error0_->code);
		g_clear_error (&_inner_error0_);
		return;
	}
	_g_free0 (contents);
	_g_free0 (cachefile);
	_g_free0 (cachedir);
}

ToolInstance*
tool_instance_construct (GType object_type)
{
	ToolInstance * self = NULL;
	self = (ToolInstance*) g_object_new (object_type, NULL);
	return self;
}

gboolean
tool_instance_get_verbose (ToolInstance* self)
{
	gboolean result;
	g_return_val_if_fail (self != NULL, FALSE);
	result = self->priv->_verbose;
	return result;
}

static void
tool_instance_set_verbose (ToolInstance* self,
                           gboolean value)
{
	gboolean old_value;
	g_return_if_fail (self != NULL);
	old_value = tool_instance_get_verbose (self);
	if (old_value != value) {
		self->priv->_verbose = value;
		g_object_notify_by_pspec ((GObject *) self, tool_instance_properties[TOOL_INSTANCE_VERBOSE_PROPERTY]);
	}
}

const gchar*
tool_instance_get_forced_cache_dir (ToolInstance* self)
{
	const gchar* result;
	const gchar* _tmp0_;
	g_return_val_if_fail (self != NULL, NULL);
	_tmp0_ = self->priv->_forced_cache_dir;
	result = _tmp0_;
	return result;
}

void
tool_instance_set_forced_cache_dir (ToolInstance* self,
                                    const gchar* value)
{
	gchar* old_value;
	g_return_if_fail (self != NULL);
	old_value = tool_instance_get_forced_cache_dir (self);
	if (g_strcmp0 (value, old_value) != 0) {
		gchar* _tmp0_;
		_tmp0_ = g_strdup (value);
		_g_free0 (self->priv->_forced_cache_dir);
		self->priv->_forced_cache_dir = _tmp0_;
		g_object_notify_by_pspec ((GObject *) self, tool_instance_properties[TOOL_INSTANCE_FORCED_CACHE_DIR_PROPERTY]);
	}
}

static void
g_cclosure_user_marshal_VOID__BOOLEAN_BOOLEAN (GClosure * closure,
                                               GValue * return_value,
                                               guint n_param_values,
                                               const GValue * param_values,
                                               gpointer invocation_hint,
                                               gpointer marshal_data)
{
	typedef void (*GMarshalFunc_VOID__BOOLEAN_BOOLEAN) (gpointer data1, gboolean arg_1, gboolean arg_2, gpointer data2);
	register GMarshalFunc_VOID__BOOLEAN_BOOLEAN 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__BOOLEAN_BOOLEAN) (marshal_data ? marshal_data : cc->callback);
	callback (data1, g_value_get_boolean (param_values + 1), g_value_get_boolean (param_values + 2), data2);
}

static void
tool_instance_class_init (ToolInstanceClass * klass,
                          gpointer klass_data)
{
	tool_instance_parent_class = g_type_class_peek_parent (klass);
	g_type_class_adjust_private_offset (klass, &ToolInstance_private_offset);
	((ToolInstanceClass *) klass)->_name = (gchar* (*) (ToolInstance*)) tool_instance_real__name;
	((ToolInstanceClass *) klass)->_send_error = (void (*) (ToolInstance*, GError*)) tool_instance_real__send_error;
	((ToolInstanceClass *) klass)->_process_line = (gboolean (*) (ToolInstance*, const gchar*, const gchar*, gboolean*, GError**)) tool_instance_real__process_line;
	((ToolInstanceClass *) klass)->_edit_envp = (void (*) (ToolInstance*, GList*)) tool_instance_real__edit_envp;
	G_OBJECT_CLASS (klass)->get_property = _vala_tool_instance_get_property;
	G_OBJECT_CLASS (klass)->set_property = _vala_tool_instance_set_property;
	G_OBJECT_CLASS (klass)->finalize = tool_instance_finalize;
	g_object_class_install_property (G_OBJECT_CLASS (klass), TOOL_INSTANCE_VERBOSE_PROPERTY, tool_instance_properties[TOOL_INSTANCE_VERBOSE_PROPERTY] = g_param_spec_boolean ("verbose", "verbose", "verbose", FALSE, G_PARAM_STATIC_STRINGS | G_PARAM_READABLE));
	g_object_class_install_property (G_OBJECT_CLASS (klass), TOOL_INSTANCE_FORCED_CACHE_DIR_PROPERTY, tool_instance_properties[TOOL_INSTANCE_FORCED_CACHE_DIR_PROPERTY] = g_param_spec_string ("forced-cache-dir", "forced-cache-dir", "forced-cache-dir", NULL, G_PARAM_STATIC_STRINGS | G_PARAM_READABLE | G_PARAM_WRITABLE));
	tool_instance_signals[TOOL_INSTANCE_DONE_SIGNAL] = g_signal_new ("done", TYPE_TOOL_INSTANCE, G_SIGNAL_RUN_LAST, 0, NULL, NULL, g_cclosure_user_marshal_VOID__BOOLEAN_BOOLEAN, G_TYPE_NONE, 2, G_TYPE_BOOLEAN, G_TYPE_BOOLEAN);
	tool_instance_signals[TOOL_INSTANCE_EXITED_SIGNAL] = g_signal_new ("exited", TYPE_TOOL_INSTANCE, G_SIGNAL_RUN_LAST, 0, NULL, NULL, g_cclosure_marshal_VOID__INT, G_TYPE_NONE, 1, G_TYPE_INT);
}

static void
tool_instance_instance_init (ToolInstance * self,
                             gpointer klass)
{
	self->priv = tool_instance_get_instance_private (self);
	self->priv->_verbose = FALSE;
	self->priv->_forced_cache_dir = NULL;
}

static void
tool_instance_finalize (GObject * obj)
{
	ToolInstance * self;
	self = G_TYPE_CHECK_INSTANCE_CAST (obj, TYPE_TOOL_INSTANCE, ToolInstance);
	if (self->priv->watch_id != ((guint) 0)) {
		g_source_remove (self->priv->watch_id);
	}
	if (tool_instance_is_started (self)) {
		g_debug ("ToolInstance.vala:99: tool (%i) process killed\n", (gint) self->priv->child_pid);
		tool_instance_kill_child (self);
	}
	_g_free0 (self->priv->_forced_cache_dir);
	_g_main_loop_unref0 (self->priv->read_loop);
	(self->priv->tail == NULL) ? NULL : (self->priv->tail = (_g_queue_free__g_free0_ (self->priv->tail), NULL));
	G_OBJECT_CLASS (tool_instance_parent_class)->finalize (obj);
}

 G_GNUC_NO_INLINE static GType
tool_instance_get_type_once (void)
{
	static const GTypeInfo g_define_type_info = { sizeof (ToolInstanceClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) tool_instance_class_init, (GClassFinalizeFunc) NULL, NULL, sizeof (ToolInstance), 0, (GInstanceInitFunc) tool_instance_instance_init, NULL };
	GType tool_instance_type_id;
	tool_instance_type_id = g_type_register_static (G_TYPE_OBJECT, "ToolInstance", &g_define_type_info, G_TYPE_FLAG_ABSTRACT);
	ToolInstance_private_offset = g_type_add_instance_private (tool_instance_type_id, sizeof (ToolInstancePrivate));
	return tool_instance_type_id;
}

GType
tool_instance_get_type (void)
{
	static gsize tool_instance_type_id__once = 0;
	if (g_once_init_enter (&tool_instance_type_id__once)) {
		GType tool_instance_type_id;
		tool_instance_type_id = tool_instance_get_type_once ();
		g_once_init_leave (&tool_instance_type_id__once, tool_instance_type_id);
	}
	return tool_instance_type_id__once;
}

static void
_vala_tool_instance_get_property (GObject * object,
                                  guint property_id,
                                  GValue * value,
                                  GParamSpec * pspec)
{
	ToolInstance * self;
	self = G_TYPE_CHECK_INSTANCE_CAST (object, TYPE_TOOL_INSTANCE, ToolInstance);
	switch (property_id) {
		case TOOL_INSTANCE_VERBOSE_PROPERTY:
		g_value_set_boolean (value, tool_instance_get_verbose (self));
		break;
		case TOOL_INSTANCE_FORCED_CACHE_DIR_PROPERTY:
		g_value_set_string (value, tool_instance_get_forced_cache_dir (self));
		break;
		default:
		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
		break;
	}
}

static void
_vala_tool_instance_set_property (GObject * object,
                                  guint property_id,
                                  const GValue * value,
                                  GParamSpec * pspec)
{
	ToolInstance * self;
	self = G_TYPE_CHECK_INSTANCE_CAST (object, TYPE_TOOL_INSTANCE, ToolInstance);
	switch (property_id) {
		case TOOL_INSTANCE_VERBOSE_PROPERTY:
		tool_instance_set_verbose (self, g_value_get_boolean (value));
		break;
		case TOOL_INSTANCE_FORCED_CACHE_DIR_PROPERTY:
		tool_instance_set_forced_cache_dir (self, g_value_get_string (value));
		break;
		default:
		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
		break;
	}
}

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

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

