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

/* -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/* Baobab - disk usage analyzer
 *
 * Copyright (C) 2012  Ryan Lortie <desrt@desrt.ca>
 * Copyright (C) 2012  Paolo Borelli <pborelli@gnome.org>
 * Copyright (C) 2012  Stefano Facchini <stefano.facchini@gmail.com>
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 */

#include "baobab.h"
#include <gio/gio.h>
#include <glib.h>
#include <stdlib.h>
#include <string.h>
#include <gtk/gtk.h>
#include <float.h>
#include <math.h>
#include <glib-object.h>

#define BAOBAB_SCANNER_ATTRIBUTES G_FILE_ATTRIBUTE_STANDARD_NAME "," G_FILE_ATTRIBUTE_STANDARD_DISPLAY_NAME "," G_FILE_ATTRIBUTE_STANDARD_TYPE "," G_FILE_ATTRIBUTE_STANDARD_SIZE "," G_FILE_ATTRIBUTE_STANDARD_ALLOCATED_SIZE "," G_FILE_ATTRIBUTE_TIME_MODIFIED "," G_FILE_ATTRIBUTE_UNIX_NLINK "," G_FILE_ATTRIBUTE_UNIX_INODE "," G_FILE_ATTRIBUTE_UNIX_DEVICE "," G_FILE_ATTRIBUTE_ACCESS_CAN_READ

typedef struct _BaobabScannerHardLink BaobabScannerHardLink;
typedef struct _BaobabScannerResultsArray BaobabScannerResultsArray;
enum  {
	BAOBAB_SCANNER_0_PROPERTY,
	BAOBAB_SCANNER_DIRECTORY_PROPERTY,
	BAOBAB_SCANNER_SCAN_FLAGS_PROPERTY,
	BAOBAB_SCANNER_SHOW_ALLOCATED_SIZE_PROPERTY,
	BAOBAB_SCANNER_TOTAL_SIZE_PROPERTY,
	BAOBAB_SCANNER_TOTAL_ELEMENTS_PROPERTY,
	BAOBAB_SCANNER_MAX_DEPTH_PROPERTY,
	BAOBAB_SCANNER_NUM_PROPERTIES
};
static GParamSpec* baobab_scanner_properties[BAOBAB_SCANNER_NUM_PROPERTIES];
#define _g_object_unref0(var) ((var == NULL) ? NULL : (var = (g_object_unref (var), NULL)))
#define _g_thread_unref0(var) ((var == NULL) ? NULL : (var = (g_thread_unref (var), NULL)))
#define _g_hash_table_unref0(var) ((var == NULL) ? NULL : (var = (g_hash_table_unref (var), NULL)))
#define _g_async_queue_unref0(var) ((var == NULL) ? NULL : (var = (g_async_queue_unref (var), NULL)))
#define _g_error_free0(var) ((var == NULL) ? NULL : (var = (g_error_free (var), NULL)))
#define _g_free0(var) (var = (g_free (var), NULL))
typedef struct _BaobabScannerResults BaobabScannerResults;
#define _baobab_scanner_results_free0(var) ((var == NULL) ? NULL : (var = (baobab_scanner_results_free (var), NULL)))
#define _baobab_scanner_hard_link_free0(var) ((var == NULL) ? NULL : (var = (baobab_scanner_hard_link_free (var), NULL)))
#define _baobab_scanner_results_array_free0(var) ((var == NULL) ? NULL : (var = (baobab_scanner_results_array_free (var), NULL)))
#define __vala_GtkTreeIter_free0(var) ((var == NULL) ? NULL : (var = (_vala_GtkTreeIter_free (var), NULL)))
enum  {
	BAOBAB_SCANNER_COMPLETED_SIGNAL,
	BAOBAB_SCANNER_NUM_SIGNALS
};
static guint baobab_scanner_signals[BAOBAB_SCANNER_NUM_SIGNALS] = {0};

struct _BaobabScannerPrivate {
	GFile* _directory;
	BaobabScanFlags _scan_flags;
	gboolean _show_allocated_size;
	guint64 _total_size;
	gint _total_elements;
	gint _max_depth;
	GThread* thread;
	guint process_result_idle;
	GHashTable* hardlinks;
	GHashTable* excluded_locations;
	guint32 unix_device;
	gboolean successful;
	GAsyncQueue* results_queue;
	BaobabScanner* self;
	GCancellable* cancellable;
	GError* scan_error;
};

struct _BaobabScannerResultsArray {
	BaobabScannerResults** results;
	gint results_length1;
	gint _results_size_;
};

struct _BaobabScannerResults {
	BaobabScannerResults* parent;
	gchar* name;
	gchar* display_name;
	GFileType file_type;
	guint64 size;
	guint64 time_modified;
	gint elements;
	gdouble percent;
	gint max_depth;
	GError* error;
	gboolean child_error;
	GtkTreeIter iter;
	gboolean iter_is_set;
};

struct _BaobabScannerHardLink {
	guint64 inode;
	guint32 device;
};

static gint BaobabScanner_private_offset;
static gpointer baobab_scanner_parent_class = NULL;

static void baobab_scanner_hard_link_free (BaobabScannerHardLink * self);
static void baobab_scanner_results_array_free (BaobabScannerResultsArray * self);
static void _g_free0_ (gpointer var);
static inline void _g_list_free__g_free0_ (GList* self);
static void baobab_scanner_results_free (BaobabScannerResults * self);
static void baobab_scanner_add_children (BaobabScanner* self,
                                  GFile* directory,
                                  BaobabScannerResults* results,
                                  BaobabScannerResultsArray* results_array,
                                  GError** error);
static BaobabScannerResults* baobab_scanner_add_directory (BaobabScanner* self,
                                                    GFile* directory,
                                                    GFileInfo* info,
                                                    BaobabScannerResults* parent);
static void baobab_scanner_results_update_with_child (BaobabScannerResults* self,
                                               BaobabScannerResults* child);
static void _vala_array_add3 (BaobabScannerResults** * array,
                       gint* length,
                       gint* size,
                       BaobabScannerResults* value);
static BaobabScannerHardLink* baobab_scanner_hard_link_new (GFileInfo* info);
static BaobabScannerResults* baobab_scanner_results_new (GFileInfo* info,
                                                  BaobabScannerResults* parent_results);
static void baobab_scanner_set_total_size (BaobabScanner* self,
                                    guint64 value);
static void baobab_scanner_set_total_elements (BaobabScanner* self,
                                        gint value);
static void _vala_array_add4 (BaobabScannerResults** * array,
                       gint* length,
                       gint* size,
                       BaobabScannerResults* value);
static BaobabScannerResultsArray* baobab_scanner_results_array_new (void);
static void* baobab_scanner_scan_in_thread (BaobabScanner* self);
static void baobab_scanner_set_show_allocated_size (BaobabScanner* self,
                                             gboolean value);
static void _vala_array_add5 (BaobabScannerResults** * array,
                       gint* length,
                       gint* size,
                       BaobabScannerResults* value);
static void baobab_scanner_ensure_iter_exists (BaobabScanner* self,
                                        BaobabScannerResults* results);
static void _vala_GtkTreeIter_free (GtkTreeIter* self);
static GtkTreeIter* _vala_GtkTreeIter_copy (GtkTreeIter* self);
static gboolean baobab_scanner_process_results (BaobabScanner* self);
static void baobab_scanner_cancel_and_reset (BaobabScanner* self);
static guint baobab_scanner_hard_link_hash (BaobabScannerHardLink* self);
static guint _baobab_scanner_hard_link_hash_ghash_func (gconstpointer key);
static gboolean baobab_scanner_hard_link_equal (BaobabScannerHardLink* self,
                                         BaobabScannerHardLink* other);
static gboolean _baobab_scanner_hard_link_equal_gequal_func (gconstpointer a,
                                                      gconstpointer b);
static void _baobab_scanner_hard_link_free0_ (gpointer var);
static gpointer _baobab_scanner_scan_in_thread_gthread_func (gpointer self);
static gboolean ___lambda4_ (BaobabScanner* self);
static gboolean ____lambda4__gsource_func (gpointer self);
static void baobab_scanner_set_directory (BaobabScanner* self,
                                   GFile* value);
static void baobab_scanner_set_scan_flags (BaobabScanner* self,
                                    BaobabScanFlags value);
static void _baobab_scanner_results_array_free0_ (gpointer var);
static void baobab_scanner_hard_link_instance_init (BaobabScannerHardLink * self);
static void baobab_scanner_results_array_instance_init (BaobabScannerResultsArray * self);
static void baobab_scanner_results_instance_init (BaobabScannerResults * self);
static void baobab_scanner_finalize (GObject * obj);
static GType baobab_scanner_get_type_once (void);
static void _vala_baobab_scanner_get_property (GObject * object,
                                        guint property_id,
                                        GValue * value,
                                        GParamSpec * pspec);
static void _vala_baobab_scanner_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 GType
baobab_scan_flags_get_type_once (void)
{
	static const GFlagsValue values[] = {{BAOBAB_SCAN_FLAGS_NONE, "BAOBAB_SCAN_FLAGS_NONE", "none"}, {BAOBAB_SCAN_FLAGS_EXCLUDE_MOUNTS, "BAOBAB_SCAN_FLAGS_EXCLUDE_MOUNTS", "exclude-mounts"}, {0, NULL, NULL}};
	GType baobab_scan_flags_type_id;
	baobab_scan_flags_type_id = g_flags_register_static ("BaobabScanFlags", values);
	return baobab_scan_flags_type_id;
}

GType
baobab_scan_flags_get_type (void)
{
	static volatile gsize baobab_scan_flags_type_id__once = 0;
	if (g_once_init_enter (&baobab_scan_flags_type_id__once)) {
		GType baobab_scan_flags_type_id;
		baobab_scan_flags_type_id = baobab_scan_flags_get_type_once ();
		g_once_init_leave (&baobab_scan_flags_type_id__once, baobab_scan_flags_type_id);
	}
	return baobab_scan_flags_type_id__once;
}

static inline gpointer
baobab_scanner_get_instance_private (BaobabScanner* self)
{
	return G_STRUCT_MEMBER_P (self, BaobabScanner_private_offset);
}

static GType
baobab_scanner_columns_get_type_once (void)
{
	static const GEnumValue values[] = {{BAOBAB_SCANNER_COLUMNS_NAME, "BAOBAB_SCANNER_COLUMNS_NAME", "name"}, {BAOBAB_SCANNER_COLUMNS_PERCENT, "BAOBAB_SCANNER_COLUMNS_PERCENT", "percent"}, {BAOBAB_SCANNER_COLUMNS_SIZE, "BAOBAB_SCANNER_COLUMNS_SIZE", "size"}, {BAOBAB_SCANNER_COLUMNS_TIME_MODIFIED, "BAOBAB_SCANNER_COLUMNS_TIME_MODIFIED", "time-modified"}, {BAOBAB_SCANNER_COLUMNS_DISPLAY_NAME, "BAOBAB_SCANNER_COLUMNS_DISPLAY_NAME", "display-name"}, {BAOBAB_SCANNER_COLUMNS_ELEMENTS, "BAOBAB_SCANNER_COLUMNS_ELEMENTS", "elements"}, {BAOBAB_SCANNER_COLUMNS_STATE, "BAOBAB_SCANNER_COLUMNS_STATE", "state"}, {BAOBAB_SCANNER_COLUMNS_COLUMNS, "BAOBAB_SCANNER_COLUMNS_COLUMNS", "columns"}, {0, NULL, NULL}};
	GType baobab_scanner_columns_type_id;
	baobab_scanner_columns_type_id = g_enum_register_static ("BaobabScannerColumns", values);
	return baobab_scanner_columns_type_id;
}

GType
baobab_scanner_columns_get_type (void)
{
	static volatile gsize baobab_scanner_columns_type_id__once = 0;
	if (g_once_init_enter (&baobab_scanner_columns_type_id__once)) {
		GType baobab_scanner_columns_type_id;
		baobab_scanner_columns_type_id = baobab_scanner_columns_get_type_once ();
		g_once_init_leave (&baobab_scanner_columns_type_id__once, baobab_scanner_columns_type_id);
	}
	return baobab_scanner_columns_type_id__once;
}

static GType
baobab_scanner_state_get_type_once (void)
{
	static const GEnumValue values[] = {{BAOBAB_SCANNER_STATE_SCANNING, "BAOBAB_SCANNER_STATE_SCANNING", "scanning"}, {BAOBAB_SCANNER_STATE_ERROR, "BAOBAB_SCANNER_STATE_ERROR", "error"}, {BAOBAB_SCANNER_STATE_CHILD_ERROR, "BAOBAB_SCANNER_STATE_CHILD_ERROR", "child-error"}, {BAOBAB_SCANNER_STATE_DONE, "BAOBAB_SCANNER_STATE_DONE", "done"}, {0, NULL, NULL}};
	GType baobab_scanner_state_type_id;
	baobab_scanner_state_type_id = g_enum_register_static ("BaobabScannerState", values);
	return baobab_scanner_state_type_id;
}

GType
baobab_scanner_state_get_type (void)
{
	static volatile gsize baobab_scanner_state_type_id__once = 0;
	if (g_once_init_enter (&baobab_scanner_state_type_id__once)) {
		GType baobab_scanner_state_type_id;
		baobab_scanner_state_type_id = baobab_scanner_state_get_type_once ();
		g_once_init_leave (&baobab_scanner_state_type_id__once, baobab_scanner_state_type_id);
	}
	return baobab_scanner_state_type_id__once;
}

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

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

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

GFile*
baobab_scanner_get_file (BaobabScanner* self,
                         GtkTreeIter* iter)
{
	GList* names = NULL;
	GtkTreeIter child = {0};
	GtkTreeIter _tmp0_ = {0};
	GFile* file = NULL;
	GFile* _tmp10_;
	GFile* _tmp11_;
	GList* _tmp12_;
	GList* _tmp13_;
	GFile* result;
	g_return_val_if_fail (self != NULL, NULL);
	g_return_val_if_fail (iter != NULL, NULL);
	names = NULL;
	_tmp0_.stamp = 0;
	child = _tmp0_;
	{
		gboolean _tmp1_ = FALSE;
		_tmp1_ = TRUE;
		while (TRUE) {
			gchar* name = NULL;
			GtkTreeIter _tmp5_;
			gchar* _tmp6_ = NULL;
			const gchar* _tmp7_;
			gchar* _tmp8_;
			GtkTreeIter _tmp9_;
			if (!_tmp1_) {
				GtkTreeIter _tmp2_;
				GtkTreeIter _tmp3_ = {0};
				gboolean _tmp4_;
				_tmp2_ = child;
				_tmp4_ = gtk_tree_model_iter_parent ((GtkTreeModel*) self, &_tmp3_, &_tmp2_);
				*iter = _tmp3_;
				if (!_tmp4_) {
					break;
				}
			}
			_tmp1_ = FALSE;
			_tmp5_ = *iter;
			gtk_tree_model_get ((GtkTreeModel*) self, &_tmp5_, BAOBAB_SCANNER_COLUMNS_NAME, &_tmp6_, -1);
			_g_free0 (name);
			name = _tmp6_;
			_tmp7_ = name;
			_tmp8_ = g_strdup (_tmp7_);
			names = g_list_prepend (names, _tmp8_);
			_tmp9_ = *iter;
			child = _tmp9_;
			_g_free0 (name);
		}
	}
	_tmp10_ = self->priv->_directory;
	_tmp11_ = _g_object_ref0 (_tmp10_);
	file = _tmp11_;
	_tmp12_ = names;
	_tmp13_ = _tmp12_->next;
	{
		GList* name_collection = NULL;
		GList* name_it = NULL;
		name_collection = _tmp13_;
		for (name_it = name_collection; name_it != NULL; name_it = name_it->next) {
			gchar* _tmp14_;
			gchar* name = NULL;
			_tmp14_ = g_strdup ((const gchar*) name_it->data);
			name = _tmp14_;
			{
				GFile* _tmp15_;
				const gchar* _tmp16_;
				GFile* _tmp17_;
				_tmp15_ = file;
				_tmp16_ = name;
				_tmp17_ = g_file_get_child (_tmp15_, _tmp16_);
				_g_object_unref0 (file);
				file = _tmp17_;
				_g_free0 (name);
			}
		}
	}
	result = file;
	(names == NULL) ? NULL : (names = (_g_list_free__g_free0_ (names), NULL));
	return result;
}

static void
_vala_array_add3 (BaobabScannerResults** * array,
                  gint* length,
                  gint* size,
                  BaobabScannerResults* value)
{
	if ((*length) == (*size)) {
		*size = (*size) ? (2 * (*size)) : 4;
		*array = g_renew (BaobabScannerResults*, *array, (*size) + 1);
	}
	(*array)[(*length)++] = value;
	(*array)[*length] = NULL;
}

static void
_vala_array_add4 (BaobabScannerResults** * array,
                  gint* length,
                  gint* size,
                  BaobabScannerResults* value)
{
	if ((*length) == (*size)) {
		*size = (*size) ? (2 * (*size)) : 4;
		*array = g_renew (BaobabScannerResults*, *array, (*size) + 1);
	}
	(*array)[(*length)++] = value;
	(*array)[*length] = NULL;
}

static void
baobab_scanner_add_children (BaobabScanner* self,
                             GFile* directory,
                             BaobabScannerResults* results,
                             BaobabScannerResultsArray* results_array,
                             GError** error)
{
	GFileEnumerator* children = NULL;
	GCancellable* _tmp0_;
	GFileEnumerator* _tmp1_;
	GFileInfo* child_info = NULL;
	GError* _inner_error0_ = NULL;
	g_return_if_fail (self != NULL);
	g_return_if_fail (directory != NULL);
	g_return_if_fail (results != NULL);
	g_return_if_fail (results_array != NULL);
	_tmp0_ = self->priv->cancellable;
	_tmp1_ = g_file_enumerate_children (directory, BAOBAB_SCANNER_ATTRIBUTES, G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS, _tmp0_, &_inner_error0_);
	children = _tmp1_;
	if (G_UNLIKELY (_inner_error0_ != NULL)) {
		g_propagate_error (error, _inner_error0_);
		return;
	}
	while (TRUE) {
		GFileInfo* _tmp2_ = NULL;
		GFileEnumerator* _tmp3_;
		GCancellable* _tmp4_;
		GFileInfo* _tmp5_;
		GFileInfo* _tmp6_;
		GFileInfo* _tmp7_;
		GFileInfo* _tmp8_;
		_tmp3_ = children;
		_tmp4_ = self->priv->cancellable;
		_tmp5_ = g_file_enumerator_next_file (_tmp3_, _tmp4_, &_inner_error0_);
		_tmp2_ = _tmp5_;
		if (G_UNLIKELY (_inner_error0_ != NULL)) {
			g_propagate_error (error, _inner_error0_);
			_g_object_unref0 (child_info);
			_g_object_unref0 (children);
			return;
		}
		_tmp6_ = _tmp2_;
		_tmp2_ = NULL;
		_g_object_unref0 (child_info);
		child_info = _tmp6_;
		_tmp7_ = child_info;
		if (!(_tmp7_ != NULL)) {
			_g_object_unref0 (_tmp2_);
			break;
		}
		_tmp8_ = child_info;
		switch (g_file_info_get_file_type (_tmp8_)) {
			case G_FILE_TYPE_DIRECTORY:
			{
				GFile* child = NULL;
				GFileInfo* _tmp9_;
				const gchar* _tmp10_;
				GFile* _tmp11_;
				BaobabScannerResults* child_results = NULL;
				GFile* _tmp12_;
				GFileInfo* _tmp13_;
				BaobabScannerResults* _tmp14_;
				BaobabScannerResults* _tmp15_;
				_tmp9_ = child_info;
				_tmp10_ = g_file_info_get_name (_tmp9_);
				_tmp11_ = g_file_get_child (directory, _tmp10_);
				child = _tmp11_;
				_tmp12_ = child;
				_tmp13_ = child_info;
				_tmp14_ = baobab_scanner_add_directory (self, _tmp12_, _tmp13_, results);
				child_results = _tmp14_;
				_tmp15_ = child_results;
				if (_tmp15_ != NULL) {
					BaobabScannerResults* _tmp16_;
					BaobabScannerResults* _tmp17_;
					_tmp16_ = child_results;
					baobab_scanner_results_update_with_child (results, _tmp16_);
					_tmp17_ = child_results;
					child_results = NULL;
					_vala_array_add3 (&results_array->results, &results_array->results_length1, &results_array->_results_size_, _tmp17_);
				}
				_baobab_scanner_results_free0 (child_results);
				_g_object_unref0 (child);
				break;
			}
			case G_FILE_TYPE_REGULAR:
			{
				GFileInfo* _tmp18_;
				BaobabScannerResults* child_results = NULL;
				GFileInfo* _tmp26_;
				BaobabScannerResults* _tmp27_;
				guint64 _tmp28_;
				BaobabScannerResults* _tmp29_;
				gint _tmp30_;
				BaobabScannerResults* _tmp31_;
				BaobabScannerResults* _tmp32_;
				_tmp18_ = child_info;
				if (g_file_info_has_attribute (_tmp18_, G_FILE_ATTRIBUTE_UNIX_NLINK)) {
					GFileInfo* _tmp19_;
					_tmp19_ = child_info;
					if (g_file_info_get_attribute_uint32 (_tmp19_, G_FILE_ATTRIBUTE_UNIX_NLINK) > ((guint32) 1)) {
						BaobabScannerHardLink* hl = NULL;
						GFileInfo* _tmp20_;
						BaobabScannerHardLink* _tmp21_;
						GHashTable* _tmp22_;
						BaobabScannerHardLink* _tmp23_;
						GHashTable* _tmp24_;
						BaobabScannerHardLink* _tmp25_;
						_tmp20_ = child_info;
						_tmp21_ = baobab_scanner_hard_link_new (_tmp20_);
						hl = _tmp21_;
						_tmp22_ = self->priv->hardlinks;
						_tmp23_ = hl;
						if (g_hash_table_contains (_tmp22_, _tmp23_)) {
							_baobab_scanner_hard_link_free0 (hl);
							_g_object_unref0 (_tmp2_);
							continue;
						}
						_tmp24_ = self->priv->hardlinks;
						_tmp25_ = hl;
						hl = NULL;
						g_hash_table_add (_tmp24_, _tmp25_);
						_baobab_scanner_hard_link_free0 (hl);
					}
				}
				_tmp26_ = child_info;
				_tmp27_ = baobab_scanner_results_new (_tmp26_, results);
				child_results = _tmp27_;
				_tmp28_ = self->priv->_total_size;
				_tmp29_ = child_results;
				baobab_scanner_set_total_size (self, _tmp28_ + _tmp29_->size);
				_tmp30_ = self->priv->_total_elements;
				baobab_scanner_set_total_elements (self, _tmp30_ + 1);
				_tmp31_ = child_results;
				baobab_scanner_results_update_with_child (results, _tmp31_);
				_tmp32_ = child_results;
				child_results = NULL;
				_vala_array_add4 (&results_array->results, &results_array->results_length1, &results_array->_results_size_, _tmp32_);
				_baobab_scanner_results_free0 (child_results);
				break;
			}
			default:
			{
				break;
			}
		}
		_g_object_unref0 (_tmp2_);
	}
	_g_object_unref0 (child_info);
	_g_object_unref0 (children);
}

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

static BaobabScannerResults*
baobab_scanner_add_directory (BaobabScanner* self,
                              GFile* directory,
                              GFileInfo* info,
                              BaobabScannerResults* parent)
{
	BaobabScannerResultsArray* results_array = NULL;
	BaobabScannerResultsArray* _tmp0_;
	guint32 current_unix_device = 0U;
	gboolean _tmp1_ = FALSE;
	BaobabScanFlags _tmp2_;
	BaobabScannerResults* results = NULL;
	BaobabScannerResults* _tmp3_;
	GHashTable* _tmp4_;
	gchar* _tmp5_;
	gchar* _tmp6_;
	gboolean _tmp7_;
	guint64 _tmp10_;
	BaobabScannerResults* _tmp11_;
	gint _tmp12_;
	BaobabScannerResultsArray* _tmp18_;
	BaobabScannerResults** _tmp19_;
	gint _tmp19__length1;
	GAsyncQueue* _tmp25_;
	BaobabScannerResultsArray* _tmp26_;
	GError* _inner_error0_ = NULL;
	BaobabScannerResults* result;
	g_return_val_if_fail (self != NULL, NULL);
	g_return_val_if_fail (directory != NULL, NULL);
	g_return_val_if_fail (info != NULL, NULL);
	_tmp0_ = baobab_scanner_results_array_new ();
	results_array = _tmp0_;
	current_unix_device = g_file_info_get_attribute_uint32 (info, G_FILE_ATTRIBUTE_UNIX_DEVICE);
	_tmp2_ = self->priv->_scan_flags;
	if ((_tmp2_ & BAOBAB_SCAN_FLAGS_EXCLUDE_MOUNTS) == BAOBAB_SCAN_FLAGS_EXCLUDE_MOUNTS) {
		_tmp1_ = current_unix_device != self->priv->unix_device;
	} else {
		_tmp1_ = FALSE;
	}
	if (_tmp1_) {
		result = NULL;
		_baobab_scanner_results_array_free0 (results_array);
		return result;
	}
	_tmp3_ = baobab_scanner_results_new (info, parent);
	results = _tmp3_;
	_tmp4_ = self->priv->excluded_locations;
	_tmp5_ = g_file_get_uri (directory);
	_tmp6_ = _tmp5_;
	_tmp7_ = g_hash_table_contains (_tmp4_, _tmp6_);
	_g_free0 (_tmp6_);
	if (_tmp7_) {
		BaobabScannerResults* _tmp8_;
		GError* _tmp9_;
		_tmp8_ = results;
		_tmp9_ = g_error_new_literal (G_IO_ERROR, G_IO_ERROR_FAILED, "Location is excluded");
		_g_error_free0 (_tmp8_->error);
		_tmp8_->error = _tmp9_;
		result = results;
		_baobab_scanner_results_array_free0 (results_array);
		return result;
	}
	_tmp10_ = self->priv->_total_size;
	_tmp11_ = results;
	baobab_scanner_set_total_size (self, _tmp10_ + _tmp11_->size);
	_tmp12_ = self->priv->_total_elements;
	baobab_scanner_set_total_elements (self, _tmp12_ + 1);
	{
		BaobabScannerResults* _tmp13_;
		BaobabScannerResultsArray* _tmp14_;
		_tmp13_ = results;
		_tmp14_ = results_array;
		baobab_scanner_add_children (self, directory, _tmp13_, _tmp14_, &_inner_error0_);
		if (G_UNLIKELY (_inner_error0_ != NULL)) {
			goto __catch0_g_error;
		}
	}
	goto __finally0;
	__catch0_g_error:
	{
		GError* e = NULL;
		BaobabScannerResults* _tmp15_;
		GError* _tmp16_;
		GError* _tmp17_;
		e = _inner_error0_;
		_inner_error0_ = NULL;
		_tmp15_ = results;
		_tmp16_ = e;
		_tmp17_ = _g_error_copy0 (_tmp16_);
		_g_error_free0 (_tmp15_->error);
		_tmp15_->error = _tmp17_;
		_g_error_free0 (e);
	}
	__finally0:
	if (G_UNLIKELY (_inner_error0_ != NULL)) {
		_baobab_scanner_results_free0 (results);
		_baobab_scanner_results_array_free0 (results_array);
		g_critical ("file %s: line %d: uncaught error: %s (%s, %d)", __FILE__, __LINE__, _inner_error0_->message, g_quark_to_string (_inner_error0_->domain), _inner_error0_->code);
		g_clear_error (&_inner_error0_);
		return NULL;
	}
	_tmp18_ = results_array;
	_tmp19_ = _tmp18_->results;
	_tmp19__length1 = _tmp18_->results_length1;
	{
		BaobabScannerResults** child_results_collection = NULL;
		gint child_results_collection_length1 = 0;
		gint _child_results_collection_size_ = 0;
		gint child_results_it = 0;
		child_results_collection = _tmp19_;
		child_results_collection_length1 = _tmp19__length1;
		for (child_results_it = 0; child_results_it < child_results_collection_length1; child_results_it = child_results_it + 1) {
			BaobabScannerResults* child_results = NULL;
			child_results = child_results_collection[child_results_it];
			{
				BaobabScannerResults* _tmp20_;
				_tmp20_ = results;
				if (_tmp20_->size > ((guint64) 0)) {
					BaobabScannerResults* _tmp21_;
					BaobabScannerResults* _tmp22_;
					BaobabScannerResults* _tmp23_;
					_tmp21_ = child_results;
					_tmp22_ = child_results;
					_tmp23_ = results;
					_tmp21_->percent = (100 * ((gdouble) _tmp22_->size)) / ((gdouble) _tmp23_->size);
				} else {
					BaobabScannerResults* _tmp24_;
					_tmp24_ = child_results;
					_tmp24_->percent = (gdouble) 0;
				}
			}
		}
	}
	_tmp25_ = self->priv->results_queue;
	_tmp26_ = results_array;
	results_array = NULL;
	g_async_queue_push (_tmp25_, _tmp26_);
	result = results;
	_baobab_scanner_results_array_free0 (results_array);
	return result;
}

static void
_vala_array_add5 (BaobabScannerResults** * array,
                  gint* length,
                  gint* size,
                  BaobabScannerResults* value)
{
	if ((*length) == (*size)) {
		*size = (*size) ? (2 * (*size)) : 4;
		*array = g_renew (BaobabScannerResults*, *array, (*size) + 1);
	}
	(*array)[(*length)++] = value;
	(*array)[*length] = NULL;
}

static void*
baobab_scanner_scan_in_thread (BaobabScanner* self)
{
	GError* _inner_error0_ = NULL;
	void* result;
	g_return_val_if_fail (self != NULL, NULL);
	{
		BaobabScannerResultsArray* array = NULL;
		BaobabScannerResultsArray* _tmp0_;
		GFileInfo* info = NULL;
		GFile* _tmp1_;
		GCancellable* _tmp2_;
		GFileInfo* _tmp3_;
		BaobabScannerResults* results = NULL;
		GFile* _tmp4_;
		BaobabScannerResults* _tmp5_;
		BaobabScannerResults* _tmp6_;
		BaobabScannerResultsArray* _tmp7_;
		BaobabScannerResultsArray* _tmp8_;
		BaobabScannerResults* _tmp9_;
		GAsyncQueue* _tmp10_;
		BaobabScannerResultsArray* _tmp11_;
		_tmp0_ = baobab_scanner_results_array_new ();
		array = _tmp0_;
		_tmp1_ = self->priv->_directory;
		_tmp2_ = self->priv->cancellable;
		_tmp3_ = g_file_query_info (_tmp1_, BAOBAB_SCANNER_ATTRIBUTES, 0, _tmp2_, &_inner_error0_);
		info = _tmp3_;
		if (G_UNLIKELY (_inner_error0_ != NULL)) {
			_baobab_scanner_results_array_free0 (array);
			goto __catch0_g_error;
		}
		baobab_scanner_set_show_allocated_size (self, g_file_info_get_attribute_uint64 (info, G_FILE_ATTRIBUTE_STANDARD_ALLOCATED_SIZE) > ((guint64) 0));
		self->priv->unix_device = g_file_info_get_attribute_uint32 (info, G_FILE_ATTRIBUTE_UNIX_DEVICE);
		_tmp4_ = self->priv->_directory;
		_tmp5_ = baobab_scanner_add_directory (self, _tmp4_, info, NULL);
		results = _tmp5_;
		_tmp6_ = results;
		_tmp6_->percent = 100.0;
		_tmp7_ = array;
		_tmp8_ = array;
		_tmp9_ = results;
		results = NULL;
		_vala_array_add5 (&_tmp7_->results, &_tmp7_->results_length1, &_tmp7_->_results_size_, _tmp9_);
		_tmp10_ = self->priv->results_queue;
		_tmp11_ = array;
		array = NULL;
		g_async_queue_push (_tmp10_, _tmp11_);
		_baobab_scanner_results_free0 (results);
		_g_object_unref0 (info);
		_baobab_scanner_results_array_free0 (array);
	}
	goto __finally0;
	__catch0_g_error:
	{
		g_clear_error (&_inner_error0_);
	}
	__finally0:
	if (G_UNLIKELY (_inner_error0_ != NULL)) {
		g_critical ("file %s: line %d: uncaught error: %s (%s, %d)", __FILE__, __LINE__, _inner_error0_->message, g_quark_to_string (_inner_error0_->domain), _inner_error0_->code);
		g_clear_error (&_inner_error0_);
		return NULL;
	}
	_g_object_unref0 (self->priv->self);
	self->priv->self = NULL;
	result = NULL;
	return result;
}

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

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

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

static void
baobab_scanner_ensure_iter_exists (BaobabScanner* self,
                                   BaobabScannerResults* results)
{
	GtkTreeIter* parent_iter = NULL;
	BaobabScannerResults* _tmp0_;
	GtkTreeIter* _tmp5_;
	GtkTreeIter _tmp6_ = {0};
	GtkTreeIter _tmp7_;
	const gchar* _tmp8_;
	const gchar* _tmp9_;
	g_return_if_fail (self != NULL);
	g_return_if_fail (results != NULL);
	if (results->iter_is_set) {
		__vala_GtkTreeIter_free0 (parent_iter);
		return;
	}
	_tmp0_ = results->parent;
	if (_tmp0_ != NULL) {
		BaobabScannerResults* _tmp1_;
		BaobabScannerResults* _tmp2_;
		GtkTreeIter _tmp3_;
		GtkTreeIter* _tmp4_;
		_tmp1_ = results->parent;
		baobab_scanner_ensure_iter_exists (self, _tmp1_);
		_tmp2_ = results->parent;
		_tmp3_ = _tmp2_->iter;
		_tmp4_ = __vala_GtkTreeIter_copy0 (&_tmp3_);
		__vala_GtkTreeIter_free0 (parent_iter);
		parent_iter = _tmp4_;
	} else {
		__vala_GtkTreeIter_free0 (parent_iter);
		parent_iter = NULL;
	}
	_tmp5_ = parent_iter;
	gtk_tree_store_prepend ((GtkTreeStore*) self, &_tmp6_, _tmp5_);
	results->iter = _tmp6_;
	_tmp7_ = results->iter;
	_tmp8_ = results->name;
	gtk_tree_store_set ((GtkTreeStore*) self, &_tmp7_, BAOBAB_SCANNER_COLUMNS_NAME, _tmp8_, -1);
	_tmp9_ = results->display_name;
	if (_tmp9_ != NULL) {
		GtkTreeIter _tmp10_;
		const gchar* _tmp11_;
		_tmp10_ = results->iter;
		_tmp11_ = results->display_name;
		gtk_tree_store_set ((GtkTreeStore*) self, &_tmp10_, BAOBAB_SCANNER_COLUMNS_DISPLAY_NAME, _tmp11_, -1);
	}
	if (results->file_type == G_FILE_TYPE_DIRECTORY) {
		GtkTreeIter _tmp12_;
		_tmp12_ = results->iter;
		gtk_tree_store_set ((GtkTreeStore*) self, &_tmp12_, BAOBAB_SCANNER_COLUMNS_STATE, BAOBAB_SCANNER_STATE_SCANNING, -1);
	}
	results->iter_is_set = TRUE;
	__vala_GtkTreeIter_free0 (parent_iter);
}

static gboolean
baobab_scanner_process_results (BaobabScanner* self)
{
	BaobabScanner* _tmp26_;
	gboolean result;
	g_return_val_if_fail (self != NULL, FALSE);
	while (TRUE) {
		BaobabScannerResultsArray* results_array = NULL;
		GAsyncQueue* _tmp0_;
		gpointer _tmp1_;
		BaobabScannerResultsArray* _tmp2_;
		BaobabScannerResultsArray* _tmp3_;
		BaobabScannerResults** _tmp4_;
		gint _tmp4__length1;
		_tmp0_ = self->priv->results_queue;
		_tmp1_ = g_async_queue_try_pop (_tmp0_);
		results_array = (BaobabScannerResultsArray*) _tmp1_;
		_tmp2_ = results_array;
		if (_tmp2_ == NULL) {
			_baobab_scanner_results_array_free0 (results_array);
			break;
		}
		_tmp3_ = results_array;
		_tmp4_ = _tmp3_->results;
		_tmp4__length1 = _tmp3_->results_length1;
		{
			BaobabScannerResults** results_collection = NULL;
			gint results_collection_length1 = 0;
			gint _results_collection_size_ = 0;
			gint results_it = 0;
			results_collection = _tmp4_;
			results_collection_length1 = _tmp4__length1;
			for (results_it = 0; results_it < results_collection_length1; results_it = results_it + 1) {
				BaobabScannerResults* results = NULL;
				results = results_collection[results_it];
				{
					BaobabScannerResults* _tmp5_;
					BaobabScannerState state = 0;
					BaobabScannerResults* _tmp6_;
					BaobabScannerResults* _tmp9_;
					GtkTreeIter _tmp10_;
					BaobabScannerResults* _tmp11_;
					BaobabScannerResults* _tmp12_;
					BaobabScannerResults* _tmp13_;
					BaobabScannerResults* _tmp14_;
					BaobabScannerResults* _tmp18_;
					gint _tmp19_;
					BaobabScannerResults* _tmp21_;
					BaobabScannerResults* _tmp22_;
					_tmp5_ = results;
					baobab_scanner_ensure_iter_exists (self, _tmp5_);
					_tmp6_ = results;
					if (_tmp6_->child_error) {
						state = BAOBAB_SCANNER_STATE_CHILD_ERROR;
					} else {
						BaobabScannerResults* _tmp7_;
						GError* _tmp8_;
						_tmp7_ = results;
						_tmp8_ = _tmp7_->error;
						if (_tmp8_ != NULL) {
							state = BAOBAB_SCANNER_STATE_ERROR;
						} else {
							state = BAOBAB_SCANNER_STATE_DONE;
						}
					}
					_tmp9_ = results;
					_tmp10_ = _tmp9_->iter;
					_tmp11_ = results;
					_tmp12_ = results;
					_tmp13_ = results;
					gtk_tree_store_set ((GtkTreeStore*) self, &_tmp10_, BAOBAB_SCANNER_COLUMNS_PERCENT, _tmp11_->percent, BAOBAB_SCANNER_COLUMNS_SIZE, _tmp12_->size, BAOBAB_SCANNER_COLUMNS_TIME_MODIFIED, _tmp13_->time_modified, -1);
					_tmp14_ = results;
					if (_tmp14_->file_type == G_FILE_TYPE_DIRECTORY) {
						BaobabScannerResults* _tmp15_;
						GtkTreeIter _tmp16_;
						BaobabScannerResults* _tmp17_;
						_tmp15_ = results;
						_tmp16_ = _tmp15_->iter;
						_tmp17_ = results;
						gtk_tree_store_set ((GtkTreeStore*) self, &_tmp16_, BAOBAB_SCANNER_COLUMNS_ELEMENTS, _tmp17_->elements, BAOBAB_SCANNER_COLUMNS_STATE, state, -1);
					}
					_tmp18_ = results;
					_tmp19_ = self->priv->_max_depth;
					if (_tmp18_->max_depth > _tmp19_) {
						BaobabScannerResults* _tmp20_;
						_tmp20_ = results;
						baobab_scanner_set_max_depth (self, _tmp20_->max_depth);
					}
					_tmp21_ = results;
					_tmp22_ = _tmp21_->parent;
					if (_tmp22_ == NULL) {
						BaobabScannerResults* _tmp23_;
						GError* _tmp24_;
						GError* _tmp25_;
						_tmp23_ = results;
						_tmp24_ = _tmp23_->error;
						_tmp25_ = _g_error_copy0 (_tmp24_);
						_g_error_free0 (self->priv->scan_error);
						self->priv->scan_error = _tmp25_;
						self->priv->successful = TRUE;
						g_signal_emit (self, baobab_scanner_signals[BAOBAB_SCANNER_COMPLETED_SIGNAL], 0);
						result = FALSE;
						_baobab_scanner_results_array_free0 (results_array);
						return result;
					}
				}
			}
		}
		_baobab_scanner_results_array_free0 (results_array);
	}
	_tmp26_ = self->priv->self;
	result = _tmp26_ != NULL;
	return result;
}

static guint
_baobab_scanner_hard_link_hash_ghash_func (gconstpointer key)
{
	guint result;
	result = baobab_scanner_hard_link_hash (key);
	return result;
}

static gboolean
_baobab_scanner_hard_link_equal_gequal_func (gconstpointer a,
                                             gconstpointer b)
{
	gboolean result;
	result = baobab_scanner_hard_link_equal (a, (BaobabScannerHardLink*) b);
	return result;
}

static void
_baobab_scanner_hard_link_free0_ (gpointer var)
{
	(var == NULL) ? NULL : (var = (baobab_scanner_hard_link_free (var), NULL));
}

static void
baobab_scanner_cancel_and_reset (BaobabScanner* self)
{
	GCancellable* _tmp0_;
	GThread* _tmp1_;
	BaobabScannerResultsArray* tmp = NULL;
	GAsyncQueue* _tmp3_;
	gpointer _tmp4_;
	GHashTable* _tmp8_;
	GCancellable* _tmp9_;
	BaobabApplication* _tmp10_;
	BaobabApplication* _tmp11_;
	GHashTable* _tmp12_;
	g_return_if_fail (self != NULL);
	_tmp0_ = self->priv->cancellable;
	g_cancellable_cancel (_tmp0_);
	_tmp1_ = self->priv->thread;
	if (_tmp1_ != NULL) {
		GThread* _tmp2_;
		_tmp2_ = self->priv->thread;
		self->priv->thread = NULL;
		g_thread_join (_tmp2_);
		_g_thread_unref0 (self->priv->thread);
		self->priv->thread = NULL;
	}
	if (self->priv->process_result_idle != ((guint) 0)) {
		g_source_remove (self->priv->process_result_idle);
		self->priv->process_result_idle = (guint) 0;
	}
	_tmp3_ = self->priv->results_queue;
	_tmp4_ = g_async_queue_try_pop (_tmp3_);
	tmp = (BaobabScannerResultsArray*) _tmp4_;
	while (TRUE) {
		BaobabScannerResultsArray* _tmp5_;
		GAsyncQueue* _tmp6_;
		gpointer _tmp7_;
		_tmp5_ = tmp;
		if (!(_tmp5_ != NULL)) {
			break;
		}
		_tmp6_ = self->priv->results_queue;
		_tmp7_ = g_async_queue_try_pop (_tmp6_);
		_baobab_scanner_results_array_free0 (tmp);
		tmp = (BaobabScannerResultsArray*) _tmp7_;
	}
	_tmp8_ = g_hash_table_new_full (_baobab_scanner_hard_link_hash_ghash_func, _baobab_scanner_hard_link_equal_gequal_func, NULL, _baobab_scanner_hard_link_free0_);
	_g_hash_table_unref0 (self->priv->hardlinks);
	self->priv->hardlinks = _tmp8_;
	gtk_tree_store_clear (G_TYPE_CHECK_INSTANCE_CAST (self, gtk_tree_store_get_type (), GtkTreeStore));
	gtk_tree_sortable_set_sort_column_id ((GtkTreeSortable*) self, GTK_TREE_SORTABLE_UNSORTED_SORT_COLUMN_ID, GTK_SORT_DESCENDING);
	_tmp9_ = self->priv->cancellable;
	g_cancellable_reset (_tmp9_);
	_g_error_free0 (self->priv->scan_error);
	self->priv->scan_error = NULL;
	baobab_scanner_set_total_size (self, (guint64) 0);
	baobab_scanner_set_total_elements (self, 0);
	_tmp10_ = baobab_application_get_default ();
	_tmp11_ = _tmp10_;
	_tmp12_ = baobab_application_get_excluded_locations (_tmp11_);
	_g_hash_table_unref0 (self->priv->excluded_locations);
	self->priv->excluded_locations = _tmp12_;
	_g_object_unref0 (_tmp11_);
	_baobab_scanner_results_array_free0 (tmp);
}

static gpointer
_baobab_scanner_scan_in_thread_gthread_func (gpointer self)
{
	gpointer result;
	result = baobab_scanner_scan_in_thread ((BaobabScanner*) self);
	g_object_unref (self);
	return result;
}

static gboolean
___lambda4_ (BaobabScanner* self)
{
	gboolean res = FALSE;
	gboolean result;
	res = baobab_scanner_process_results (self);
	if (!res) {
		self->priv->process_result_idle = (guint) 0;
	}
	result = res;
	return result;
}

static gboolean
____lambda4__gsource_func (gpointer self)
{
	gboolean result;
	result = ___lambda4_ ((BaobabScanner*) self);
	return result;
}

void
baobab_scanner_scan (BaobabScanner* self,
                     gboolean force)
{
	g_return_if_fail (self != NULL);
	if (force) {
		self->priv->successful = FALSE;
	}
	if (!self->priv->successful) {
		BaobabScanner* _tmp0_;
		GThread* _tmp1_;
		baobab_scanner_cancel_and_reset (self);
		_tmp0_ = _g_object_ref0 (self);
		_g_object_unref0 (self->priv->self);
		self->priv->self = _tmp0_;
		_tmp1_ = g_thread_new ("scanner", _baobab_scanner_scan_in_thread_gthread_func, g_object_ref (self));
		_g_thread_unref0 (self->priv->thread);
		self->priv->thread = _tmp1_;
		self->priv->process_result_idle = g_timeout_add_full (G_PRIORITY_DEFAULT, (guint) 100, ____lambda4__gsource_func, g_object_ref (self), g_object_unref);
	} else {
		g_signal_emit (self, baobab_scanner_signals[BAOBAB_SCANNER_COMPLETED_SIGNAL], 0);
	}
}

void
baobab_scanner_cancel (BaobabScanner* self)
{
	g_return_if_fail (self != NULL);
	if (!self->priv->successful) {
		GError* _tmp0_;
		baobab_scanner_cancel_and_reset (self);
		_tmp0_ = g_error_new_literal (G_IO_ERROR, G_IO_ERROR_CANCELLED, "Scan was cancelled");
		_g_error_free0 (self->priv->scan_error);
		self->priv->scan_error = _tmp0_;
	}
	g_signal_emit (self, baobab_scanner_signals[BAOBAB_SCANNER_COMPLETED_SIGNAL], 0);
}

void
baobab_scanner_finish (BaobabScanner* self,
                       GError** error)
{
	GError* _tmp0_;
	GError* _inner_error0_ = NULL;
	g_return_if_fail (self != NULL);
	gtk_tree_sortable_set_sort_column_id ((GtkTreeSortable*) self, (gint) BAOBAB_SCANNER_COLUMNS_SIZE, GTK_SORT_DESCENDING);
	_tmp0_ = self->priv->scan_error;
	if (_tmp0_ != NULL) {
		GError* _tmp1_;
		GError* _tmp2_;
		_tmp1_ = self->priv->scan_error;
		_tmp2_ = _g_error_copy0 (_tmp1_);
		_inner_error0_ = _tmp2_;
		g_propagate_error (error, _inner_error0_);
		return;
	}
}

static void
_baobab_scanner_results_array_free0_ (gpointer var)
{
	(var == NULL) ? NULL : (var = (baobab_scanner_results_array_free (var), NULL));
}

BaobabScanner*
baobab_scanner_construct (GType object_type,
                          GFile* directory,
                          BaobabScanFlags flags)
{
	BaobabScanner * self = NULL;
	GCancellable* _tmp0_;
	GType* _tmp1_;
	GType* _tmp2_;
	gint _tmp2__length1;
	GAsyncQueue* _tmp3_;
	g_return_val_if_fail (directory != NULL, NULL);
	self = (BaobabScanner*) g_object_new (object_type, NULL);
	baobab_scanner_set_directory (self, directory);
	baobab_scanner_set_scan_flags (self, flags);
	_tmp0_ = g_cancellable_new ();
	_g_object_unref0 (self->priv->cancellable);
	self->priv->cancellable = _tmp0_;
	_g_error_free0 (self->priv->scan_error);
	self->priv->scan_error = NULL;
	_tmp1_ = g_new0 (GType, 7);
	_tmp1_[0] = G_TYPE_STRING;
	_tmp1_[1] = G_TYPE_DOUBLE;
	_tmp1_[2] = G_TYPE_UINT64;
	_tmp1_[3] = G_TYPE_UINT64;
	_tmp1_[4] = G_TYPE_STRING;
	_tmp1_[5] = G_TYPE_INT;
	_tmp1_[6] = BAOBAB_SCANNER_TYPE_STATE;
	_tmp2_ = _tmp1_;
	_tmp2__length1 = 7;
	gtk_tree_store_set_column_types ((GtkTreeStore*) self, (gint) 7, _tmp2_);
	_tmp2_ = (g_free (_tmp2_), NULL);
	_tmp3_ = g_async_queue_new_full (_baobab_scanner_results_array_free0_);
	_g_async_queue_unref0 (self->priv->results_queue);
	self->priv->results_queue = _tmp3_;
	return self;
}

BaobabScanner*
baobab_scanner_new (GFile* directory,
                    BaobabScanFlags flags)
{
	return baobab_scanner_construct (BAOBAB_TYPE_SCANNER, directory, flags);
}

GFile*
baobab_scanner_get_directory (BaobabScanner* self)
{
	GFile* result;
	GFile* _tmp0_;
	g_return_val_if_fail (self != NULL, NULL);
	_tmp0_ = self->priv->_directory;
	result = _tmp0_;
	return result;
}

static void
baobab_scanner_set_directory (BaobabScanner* self,
                              GFile* value)
{
	GFile* old_value;
	g_return_if_fail (self != NULL);
	old_value = baobab_scanner_get_directory (self);
	if (old_value != value) {
		GFile* _tmp0_;
		_tmp0_ = _g_object_ref0 (value);
		_g_object_unref0 (self->priv->_directory);
		self->priv->_directory = _tmp0_;
		g_object_notify_by_pspec ((GObject *) self, baobab_scanner_properties[BAOBAB_SCANNER_DIRECTORY_PROPERTY]);
	}
}

BaobabScanFlags
baobab_scanner_get_scan_flags (BaobabScanner* self)
{
	BaobabScanFlags result;
	g_return_val_if_fail (self != NULL, 0U);
	result = self->priv->_scan_flags;
	return result;
}

static void
baobab_scanner_set_scan_flags (BaobabScanner* self,
                               BaobabScanFlags value)
{
	BaobabScanFlags old_value;
	g_return_if_fail (self != NULL);
	old_value = baobab_scanner_get_scan_flags (self);
	if (old_value != value) {
		self->priv->_scan_flags = value;
		g_object_notify_by_pspec ((GObject *) self, baobab_scanner_properties[BAOBAB_SCANNER_SCAN_FLAGS_PROPERTY]);
	}
}

gboolean
baobab_scanner_get_show_allocated_size (BaobabScanner* self)
{
	gboolean result;
	g_return_val_if_fail (self != NULL, FALSE);
	result = self->priv->_show_allocated_size;
	return result;
}

static void
baobab_scanner_set_show_allocated_size (BaobabScanner* self,
                                        gboolean value)
{
	gboolean old_value;
	g_return_if_fail (self != NULL);
	old_value = baobab_scanner_get_show_allocated_size (self);
	if (old_value != value) {
		self->priv->_show_allocated_size = value;
		g_object_notify_by_pspec ((GObject *) self, baobab_scanner_properties[BAOBAB_SCANNER_SHOW_ALLOCATED_SIZE_PROPERTY]);
	}
}

guint64
baobab_scanner_get_total_size (BaobabScanner* self)
{
	guint64 result;
	g_return_val_if_fail (self != NULL, 0ULL);
	result = self->priv->_total_size;
	return result;
}

static void
baobab_scanner_set_total_size (BaobabScanner* self,
                               guint64 value)
{
	guint64 old_value;
	g_return_if_fail (self != NULL);
	old_value = baobab_scanner_get_total_size (self);
	if (old_value != value) {
		self->priv->_total_size = value;
		g_object_notify_by_pspec ((GObject *) self, baobab_scanner_properties[BAOBAB_SCANNER_TOTAL_SIZE_PROPERTY]);
	}
}

gint
baobab_scanner_get_total_elements (BaobabScanner* self)
{
	gint result;
	g_return_val_if_fail (self != NULL, 0);
	result = self->priv->_total_elements;
	return result;
}

static void
baobab_scanner_set_total_elements (BaobabScanner* self,
                                   gint value)
{
	gint old_value;
	g_return_if_fail (self != NULL);
	old_value = baobab_scanner_get_total_elements (self);
	if (old_value != value) {
		self->priv->_total_elements = value;
		g_object_notify_by_pspec ((GObject *) self, baobab_scanner_properties[BAOBAB_SCANNER_TOTAL_ELEMENTS_PROPERTY]);
	}
}

gint
baobab_scanner_get_max_depth (BaobabScanner* self)
{
	gint result;
	g_return_val_if_fail (self != NULL, 0);
	result = self->priv->_max_depth;
	return result;
}

void
baobab_scanner_set_max_depth (BaobabScanner* self,
                              gint value)
{
	gint old_value;
	g_return_if_fail (self != NULL);
	old_value = baobab_scanner_get_max_depth (self);
	if (old_value != value) {
		self->priv->_max_depth = value;
		g_object_notify_by_pspec ((GObject *) self, baobab_scanner_properties[BAOBAB_SCANNER_MAX_DEPTH_PROPERTY]);
	}
}

static BaobabScannerHardLink*
baobab_scanner_hard_link_new (GFileInfo* info)
{
	BaobabScannerHardLink* self;
	g_return_val_if_fail (info != NULL, NULL);
	self = g_slice_new0 (BaobabScannerHardLink);
	baobab_scanner_hard_link_instance_init (self);
	self->inode = g_file_info_get_attribute_uint64 (info, G_FILE_ATTRIBUTE_UNIX_INODE);
	self->device = g_file_info_get_attribute_uint32 (info, G_FILE_ATTRIBUTE_UNIX_DEVICE);
	return self;
}

static guint
baobab_scanner_hard_link_hash (BaobabScannerHardLink* self)
{
	GHashFunc _tmp0_;
	GHashFunc _tmp1_;
	guint result;
	g_return_val_if_fail (self != NULL, 0U);
	_tmp0_ = g_direct_hash;
	_tmp1_ = g_direct_hash;
	result = _tmp0_ ((void*) self->inode) ^ _tmp1_ ((void*) self->device);
	return result;
}

static gboolean
baobab_scanner_hard_link_equal (BaobabScannerHardLink* self,
                                BaobabScannerHardLink* other)
{
	gboolean _tmp0_ = FALSE;
	gboolean result;
	g_return_val_if_fail (self != NULL, FALSE);
	g_return_val_if_fail (other != NULL, FALSE);
	if (self->inode == other->inode) {
		_tmp0_ = self->device == other->device;
	} else {
		_tmp0_ = FALSE;
	}
	result = _tmp0_;
	return result;
}

static void
baobab_scanner_hard_link_instance_init (BaobabScannerHardLink * self)
{
}

static void
baobab_scanner_hard_link_free (BaobabScannerHardLink * self)
{
	g_slice_free (BaobabScannerHardLink, self);
}

static BaobabScannerResultsArray*
baobab_scanner_results_array_new (void)
{
	BaobabScannerResultsArray* self;
	self = g_slice_new0 (BaobabScannerResultsArray);
	baobab_scanner_results_array_instance_init (self);
	return self;
}

static void
baobab_scanner_results_array_instance_init (BaobabScannerResultsArray * self)
{
}

static void
baobab_scanner_results_array_free (BaobabScannerResultsArray * self)
{
	self->results = (_vala_array_free (self->results, self->results_length1, (GDestroyNotify) baobab_scanner_results_free), NULL);
	g_slice_free (BaobabScannerResultsArray, self);
}

static BaobabScannerResults*
baobab_scanner_results_new (GFileInfo* info,
                            BaobabScannerResults* parent_results)
{
	BaobabScannerResults* self;
	const gchar* _tmp0_;
	gchar* _tmp1_;
	gchar* info_display_name = NULL;
	const gchar* _tmp2_;
	gchar* _tmp3_;
	gboolean _tmp4_ = FALSE;
	const gchar* _tmp5_;
	g_return_val_if_fail (info != NULL, NULL);
	self = g_slice_new0 (BaobabScannerResults);
	baobab_scanner_results_instance_init (self);
	self->parent = parent_results;
	_tmp0_ = g_file_info_get_name (info);
	_tmp1_ = g_strdup (_tmp0_);
	_g_free0 (self->name);
	self->name = _tmp1_;
	_tmp2_ = g_file_info_get_display_name (info);
	_tmp3_ = g_strdup (_tmp2_);
	info_display_name = _tmp3_;
	_tmp5_ = self->name;
	if (_tmp5_ == NULL) {
		_tmp4_ = TRUE;
	} else {
		const gchar* _tmp6_;
		const gchar* _tmp7_;
		gchar* _tmp8_;
		gchar* _tmp9_;
		_tmp6_ = info_display_name;
		_tmp7_ = self->name;
		_tmp8_ = g_filename_display_name (_tmp7_);
		_tmp9_ = _tmp8_;
		_tmp4_ = g_strcmp0 (_tmp6_, _tmp9_) != 0;
		_g_free0 (_tmp9_);
	}
	if (_tmp4_) {
		const gchar* _tmp10_;
		gchar* _tmp11_;
		_tmp10_ = info_display_name;
		_tmp11_ = g_strdup (_tmp10_);
		_g_free0 (self->display_name);
		self->display_name = _tmp11_;
	}
	self->file_type = g_file_info_get_file_type (info);
	self->size = g_file_info_get_attribute_uint64 (info, G_FILE_ATTRIBUTE_STANDARD_ALLOCATED_SIZE);
	if (self->size == ((guint64) 0)) {
		self->size = (guint64) g_file_info_get_size (info);
	}
	self->time_modified = g_file_info_get_attribute_uint64 (info, G_FILE_ATTRIBUTE_TIME_MODIFIED);
	self->elements = 1;
	_g_error_free0 (self->error);
	self->error = NULL;
	self->child_error = FALSE;
	_g_free0 (info_display_name);
	return self;
}

static void
baobab_scanner_results_update_with_child (BaobabScannerResults* self,
                                          BaobabScannerResults* child)
{
	gboolean _tmp0_ = FALSE;
	g_return_if_fail (self != NULL);
	g_return_if_fail (child != NULL);
	self->size = self->size + child->size;
	self->elements = self->elements + child->elements;
	self->max_depth = MAX (self->max_depth, child->max_depth + 1);
	if (child->child_error) {
		_tmp0_ = TRUE;
	} else {
		GError* _tmp1_;
		_tmp1_ = child->error;
		_tmp0_ = _tmp1_ != NULL;
	}
	self->child_error = self->child_error | _tmp0_;
	self->time_modified = MAX (self->time_modified, child->time_modified);
}

static void
baobab_scanner_results_instance_init (BaobabScannerResults * self)
{
}

static void
baobab_scanner_results_free (BaobabScannerResults * self)
{
	_g_free0 (self->name);
	_g_free0 (self->display_name);
	_g_error_free0 (self->error);
	g_slice_free (BaobabScannerResults, self);
}

static void
baobab_scanner_class_init (BaobabScannerClass * klass,
                           gpointer klass_data)
{
	baobab_scanner_parent_class = g_type_class_peek_parent (klass);
	g_type_class_adjust_private_offset (klass, &BaobabScanner_private_offset);
	G_OBJECT_CLASS (klass)->get_property = _vala_baobab_scanner_get_property;
	G_OBJECT_CLASS (klass)->set_property = _vala_baobab_scanner_set_property;
	G_OBJECT_CLASS (klass)->finalize = baobab_scanner_finalize;
	g_object_class_install_property (G_OBJECT_CLASS (klass), BAOBAB_SCANNER_DIRECTORY_PROPERTY, baobab_scanner_properties[BAOBAB_SCANNER_DIRECTORY_PROPERTY] = g_param_spec_object ("directory", "directory", "directory", g_file_get_type (), G_PARAM_STATIC_STRINGS | G_PARAM_READABLE));
	g_object_class_install_property (G_OBJECT_CLASS (klass), BAOBAB_SCANNER_SCAN_FLAGS_PROPERTY, baobab_scanner_properties[BAOBAB_SCANNER_SCAN_FLAGS_PROPERTY] = g_param_spec_flags ("scan-flags", "scan-flags", "scan-flags", BAOBAB_TYPE_SCAN_FLAGS, 0U, G_PARAM_STATIC_STRINGS | G_PARAM_READABLE));
	g_object_class_install_property (G_OBJECT_CLASS (klass), BAOBAB_SCANNER_SHOW_ALLOCATED_SIZE_PROPERTY, baobab_scanner_properties[BAOBAB_SCANNER_SHOW_ALLOCATED_SIZE_PROPERTY] = g_param_spec_boolean ("show-allocated-size", "show-allocated-size", "show-allocated-size", FALSE, G_PARAM_STATIC_STRINGS | G_PARAM_READABLE));
	g_object_class_install_property (G_OBJECT_CLASS (klass), BAOBAB_SCANNER_TOTAL_SIZE_PROPERTY, baobab_scanner_properties[BAOBAB_SCANNER_TOTAL_SIZE_PROPERTY] = g_param_spec_uint64 ("total-size", "total-size", "total-size", 0, G_MAXUINT64, 0U, G_PARAM_STATIC_STRINGS | G_PARAM_READABLE));
	g_object_class_install_property (G_OBJECT_CLASS (klass), BAOBAB_SCANNER_TOTAL_ELEMENTS_PROPERTY, baobab_scanner_properties[BAOBAB_SCANNER_TOTAL_ELEMENTS_PROPERTY] = g_param_spec_int ("total-elements", "total-elements", "total-elements", G_MININT, G_MAXINT, 0, G_PARAM_STATIC_STRINGS | G_PARAM_READABLE));
	g_object_class_install_property (G_OBJECT_CLASS (klass), BAOBAB_SCANNER_MAX_DEPTH_PROPERTY, baobab_scanner_properties[BAOBAB_SCANNER_MAX_DEPTH_PROPERTY] = g_param_spec_int ("max-depth", "max-depth", "max-depth", G_MININT, G_MAXINT, 0, G_PARAM_STATIC_STRINGS | G_PARAM_READABLE | G_PARAM_WRITABLE));
	baobab_scanner_signals[BAOBAB_SCANNER_COMPLETED_SIGNAL] = g_signal_new ("completed", BAOBAB_TYPE_SCANNER, G_SIGNAL_RUN_LAST, 0, NULL, NULL, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0);
}

static void
baobab_scanner_instance_init (BaobabScanner * self,
                              gpointer klass)
{
	self->priv = baobab_scanner_get_instance_private (self);
	self->priv->thread = NULL;
	self->priv->process_result_idle = (guint) 0;
	self->priv->unix_device = (guint32) 0;
	self->priv->successful = FALSE;
}

static void
baobab_scanner_finalize (GObject * obj)
{
	BaobabScanner * self;
	self = G_TYPE_CHECK_INSTANCE_CAST (obj, BAOBAB_TYPE_SCANNER, BaobabScanner);
	_g_object_unref0 (self->priv->_directory);
	_g_thread_unref0 (self->priv->thread);
	_g_hash_table_unref0 (self->priv->hardlinks);
	_g_hash_table_unref0 (self->priv->excluded_locations);
	_g_async_queue_unref0 (self->priv->results_queue);
	_g_object_unref0 (self->priv->self);
	_g_object_unref0 (self->priv->cancellable);
	_g_error_free0 (self->priv->scan_error);
	G_OBJECT_CLASS (baobab_scanner_parent_class)->finalize (obj);
}

static GType
baobab_scanner_get_type_once (void)
{
	static const GTypeInfo g_define_type_info = { sizeof (BaobabScannerClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) baobab_scanner_class_init, (GClassFinalizeFunc) NULL, NULL, sizeof (BaobabScanner), 0, (GInstanceInitFunc) baobab_scanner_instance_init, NULL };
	GType baobab_scanner_type_id;
	baobab_scanner_type_id = g_type_register_static (gtk_tree_store_get_type (), "BaobabScanner", &g_define_type_info, 0);
	BaobabScanner_private_offset = g_type_add_instance_private (baobab_scanner_type_id, sizeof (BaobabScannerPrivate));
	return baobab_scanner_type_id;
}

GType
baobab_scanner_get_type (void)
{
	static volatile gsize baobab_scanner_type_id__once = 0;
	if (g_once_init_enter (&baobab_scanner_type_id__once)) {
		GType baobab_scanner_type_id;
		baobab_scanner_type_id = baobab_scanner_get_type_once ();
		g_once_init_leave (&baobab_scanner_type_id__once, baobab_scanner_type_id);
	}
	return baobab_scanner_type_id__once;
}

static void
_vala_baobab_scanner_get_property (GObject * object,
                                   guint property_id,
                                   GValue * value,
                                   GParamSpec * pspec)
{
	BaobabScanner * self;
	self = G_TYPE_CHECK_INSTANCE_CAST (object, BAOBAB_TYPE_SCANNER, BaobabScanner);
	switch (property_id) {
		case BAOBAB_SCANNER_DIRECTORY_PROPERTY:
		g_value_set_object (value, baobab_scanner_get_directory (self));
		break;
		case BAOBAB_SCANNER_SCAN_FLAGS_PROPERTY:
		g_value_set_flags (value, baobab_scanner_get_scan_flags (self));
		break;
		case BAOBAB_SCANNER_SHOW_ALLOCATED_SIZE_PROPERTY:
		g_value_set_boolean (value, baobab_scanner_get_show_allocated_size (self));
		break;
		case BAOBAB_SCANNER_TOTAL_SIZE_PROPERTY:
		g_value_set_uint64 (value, baobab_scanner_get_total_size (self));
		break;
		case BAOBAB_SCANNER_TOTAL_ELEMENTS_PROPERTY:
		g_value_set_int (value, baobab_scanner_get_total_elements (self));
		break;
		case BAOBAB_SCANNER_MAX_DEPTH_PROPERTY:
		g_value_set_int (value, baobab_scanner_get_max_depth (self));
		break;
		default:
		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
		break;
	}
}

static void
_vala_baobab_scanner_set_property (GObject * object,
                                   guint property_id,
                                   const GValue * value,
                                   GParamSpec * pspec)
{
	BaobabScanner * self;
	self = G_TYPE_CHECK_INSTANCE_CAST (object, BAOBAB_TYPE_SCANNER, BaobabScanner);
	switch (property_id) {
		case BAOBAB_SCANNER_DIRECTORY_PROPERTY:
		baobab_scanner_set_directory (self, g_value_get_object (value));
		break;
		case BAOBAB_SCANNER_SCAN_FLAGS_PROPERTY:
		baobab_scanner_set_scan_flags (self, g_value_get_flags (value));
		break;
		case BAOBAB_SCANNER_SHOW_ALLOCATED_SIZE_PROPERTY:
		baobab_scanner_set_show_allocated_size (self, g_value_get_boolean (value));
		break;
		case BAOBAB_SCANNER_TOTAL_SIZE_PROPERTY:
		baobab_scanner_set_total_size (self, g_value_get_uint64 (value));
		break;
		case BAOBAB_SCANNER_TOTAL_ELEMENTS_PROPERTY:
		baobab_scanner_set_total_elements (self, g_value_get_int (value));
		break;
		case BAOBAB_SCANNER_MAX_DEPTH_PROPERTY:
		baobab_scanner_set_max_depth (self, g_value_get_int (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);
}

