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

/*
* Copyright (c) 2010-2013 Yorba Foundation
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 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 "io.elementary.photos.h"
#include <gee.h>
#include <glib-object.h>
#include <stdlib.h>
#include <string.h>
#include <glib.h>
#include <glib/gi18n-lib.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 _g_object_unref0(var) ((var == NULL) ? NULL : (var = (g_object_unref (var), NULL)))
#define _g_free0(var) (var = (g_free (var), NULL))
enum  {
	TAG_0_PROPERTY,
	TAG_NUM_PROPERTIES
};
static GParamSpec* tag_properties[TAG_NUM_PROPERTIES];
#define _tag_row_unref0(var) ((var == NULL) ? NULL : (var = (tag_row_unref (var), NULL)))
#define _data_collection_unref0(var) ((var == NULL) ? NULL : (var = (data_collection_unref (var), NULL)))
#define _media_collection_registry_unref0(var) ((var == NULL) ? NULL : (var = (media_collection_registry_unref (var), NULL)))
#define _database_table_unref0(var) ((var == NULL) ? NULL : (var = (database_table_unref (var), NULL)))
#define _g_error_free0(var) ((var == NULL) ? NULL : (var = (g_error_free (var), NULL)))
#define _g_string_free0(var) ((var == NULL) ? NULL : (var = (g_string_free (var, TRUE), NULL)))
#define _alteration_unref0(var) ((var == NULL) ? NULL : (var = (alteration_unref (var), NULL)))

#define TAG_TYPE_TAG_SNAPSHOT (tag_tag_snapshot_get_type ())
#define TAG_TAG_SNAPSHOT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), TAG_TYPE_TAG_SNAPSHOT, TagTagSnapshot))
#define TAG_TAG_SNAPSHOT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), TAG_TYPE_TAG_SNAPSHOT, TagTagSnapshotClass))
#define TAG_IS_TAG_SNAPSHOT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TAG_TYPE_TAG_SNAPSHOT))
#define TAG_IS_TAG_SNAPSHOT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), TAG_TYPE_TAG_SNAPSHOT))
#define TAG_TAG_SNAPSHOT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), TAG_TYPE_TAG_SNAPSHOT, TagTagSnapshotClass))

typedef struct _TagTagSnapshot TagTagSnapshot;
typedef struct _TagTagSnapshotClass TagTagSnapshotClass;

#define TAG_TYPE_TAG_PROXY (tag_tag_proxy_get_type ())
#define TAG_TAG_PROXY(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), TAG_TYPE_TAG_PROXY, TagTagProxy))
#define TAG_TAG_PROXY_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), TAG_TYPE_TAG_PROXY, TagTagProxyClass))
#define TAG_IS_TAG_PROXY(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TAG_TYPE_TAG_PROXY))
#define TAG_IS_TAG_PROXY_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), TAG_TYPE_TAG_PROXY))
#define TAG_TAG_PROXY_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), TAG_TYPE_TAG_PROXY, TagTagProxyClass))

typedef struct _TagTagProxy TagTagProxy;
typedef struct _TagTagProxyClass TagTagProxyClass;
#define _source_backlink_unref0(var) ((var == NULL) ? NULL : (var = (source_backlink_unref (var), NULL)))
typedef struct _TagTagSnapshotPrivate TagTagSnapshotPrivate;
typedef struct _TagTagProxyPrivate TagTagProxyPrivate;
#define _vala_assert(expr, msg) if G_LIKELY (expr) ; else g_assertion_message_expr (G_LOG_DOMAIN, __FILE__, __LINE__, G_STRFUNC, msg);
#define _vala_return_if_fail(expr, msg) if G_LIKELY (expr) ; else { g_return_if_fail_warning (G_LOG_DOMAIN, G_STRFUNC, msg); return; }
#define _vala_return_val_if_fail(expr, msg, val) if G_LIKELY (expr) ; else { g_return_if_fail_warning (G_LOG_DOMAIN, G_STRFUNC, msg); return val; }
#define _vala_warn_if_fail(expr, msg) if G_LIKELY (expr) ; else g_warn_message (G_LOG_DOMAIN, __FILE__, __LINE__, G_STRFUNC, msg);

struct _TagSourceCollectionPrivate {
	GeeHashMap* name_map;
	GeeHashMap* source_map;
	GeeHashMap* sorted_source_map;
};

struct _TagPrivate {
	TagRow* row;
	ViewCollection* media_views;
	gchar* name_collation_key;
	gboolean unlinking;
	gboolean relinking;
	gchar* indexable_keywords;
};

struct _TagTagSnapshot {
	SourceSnapshot parent_instance;
	TagTagSnapshotPrivate * priv;
};

struct _TagTagSnapshotClass {
	SourceSnapshotClass parent_class;
};

struct _TagTagSnapshotPrivate {
	TagRow* row;
	GeeHashSet* sources;
};

struct _TagTagProxy {
	SourceProxy parent_instance;
	TagTagProxyPrivate * priv;
};

struct _TagTagProxyClass {
	SourceProxyClass parent_class;
};

static gint TagSourceCollection_private_offset;
static gpointer tag_source_collection_parent_class = NULL;
static gint Tag_private_offset;
static gpointer tag_parent_class = NULL;
TagSourceCollection* tag_global = NULL;
static gint TagTagSnapshot_private_offset;
static gpointer tag_tag_snapshot_parent_class = NULL;
static gpointer tag_tag_proxy_parent_class = NULL;
static ContainerSourceIface * tag_container_source_parent_iface = NULL;
static ProxyableIface * tag_proxyable_parent_iface = NULL;
static IndexableIface * tag_indexable_parent_iface = NULL;

static void tag_source_collection_on_photo_source_reimported (TagSourceCollection* self,
                                                       LibraryPhoto* photo,
                                                       PhotoMetadata* metadata);
static void _tag_source_collection_on_photo_source_reimported_library_photo_source_collection_source_reimported (LibraryPhotoSourceCollection* _sender,
                                                                                                          LibraryPhoto* photo,
                                                                                                          PhotoMetadata* metadata,
                                                                                                          gpointer self);
static guint _tag_hash_name_string_gee_hash_data_func (gconstpointer v,
                                                gpointer self);
static gboolean _tag_equal_name_strings_gee_equal_data_func (gconstpointer a,
                                                      gconstpointer b,
                                                      gpointer self);
static gint64 tag_source_collection_get_tag_key (DataSource* source);
static gint64 _tag_source_collection_get_tag_key_get_source_database_key (DataSource* source,
                                                                   gpointer self);
static gboolean tag_source_collection_real_holds_type_of_source (SourceCollection* base,
                                                          DataSource* source);
static GeeCollection* tag_source_collection_real_get_containers_holding_source (ContainerSourceCollection* base,
                                                                         DataSource* source);
static ContainerSource* tag_source_collection_real_convert_backlink_to_container (ContainerSourceCollection* base,
                                                                           SourceBacklink* backlink);
VALA_EXTERN GeeList* hierarchical_tag_utilities_enumerate_parent_paths (const gchar* in_path);
VALA_EXTERN gchar* hierarchical_tag_utilities_hierarchical_to_flat (const gchar* path);
VALA_EXTERN GeeList* hierarchical_tag_utilities_enumerate_path_components (const gchar* in_path);
VALA_EXTERN gchar* hierarchical_tag_utilities_flat_to_hierarchical (const gchar* name);
static void tag_source_collection_real_notify_items_added (DataCollection* base,
                                                    GeeIterable* added);
static void tag_source_collection_real_notify_items_removed (DataCollection* base,
                                                      GeeIterable* removed);
static void tag_source_collection_real_notify_items_altered (DataCollection* base,
                                                      GeeMap* map);
static void tag_source_collection_real_notify_container_contents_added (ContainerSourceCollection* base,
                                                                 ContainerSource* container,
                                                                 GeeCollection* added,
                                                                 gboolean relinking);
static gint _tag_compare_names_gcompare_data_func (gconstpointer a,
                                            gconstpointer b,
                                            gpointer self);
static void tag_source_collection_real_notify_container_contents_removed (ContainerSourceCollection* base,
                                                                   ContainerSource* container,
                                                                   GeeCollection* removed,
                                                                   gboolean unlinking);
static void tag_source_collection_finalize (DataCollection * obj);
static GType tag_source_collection_get_type_once (void);
static void tag_on_media_views_contents_altered (Tag* self,
                                          GeeIterable* added,
                                          GeeIterable* removed);
static void _tag_on_media_views_contents_altered_data_collection_contents_altered (DataCollection* _sender,
                                                                            GeeIterable* added,
                                                                            GeeIterable* removed,
                                                                            gpointer self);
static void tag_on_sources_destroyed (Tag* self,
                               GeeCollection* sources);
static void _tag_on_sources_destroyed_source_collection_items_destroyed (SourceCollection* _sender,
                                                                  GeeCollection* destroyed,
                                                                  gpointer self);
static Tag* tag_new (TagRow* row,
              gint64 object_id);
static Tag* tag_construct (GType object_type,
                    TagRow* row,
                    gint64 object_id);
static void tag_update_indexable_keywords (Tag* self);
static void _vala_array_add45 (gchar** * array,
                        gint* length,
                        gint* size,
                        gchar* value);
static void tag_set_raw_flat_name (Tag* self,
                            const gchar* name);
static void tag_set_raw_path (Tag* self,
                       const gchar* path,
                       gboolean suppress_notify);
static gchar* tag_real_get_typename (DataSource* base);
static gint64 tag_real_get_instance_id (DataSource* base);
static gchar* tag_real_get_name (DataObject* base);
VALA_EXTERN gchar* hierarchical_tag_utilities_get_basename (const gchar* in_path);
static gchar* tag_get_next_untitled_tag_name (const gchar* _prefix);
static gchar* tag_real_to_string (DataObject* base);
static gboolean tag_real_equals (DataSource* base,
                          DataSource* source);
static SourceSnapshot* tag_real_save_snapshot (DataSource* base);
static TagTagSnapshot* tag_tag_snapshot_new (Tag* tag);
static TagTagSnapshot* tag_tag_snapshot_construct (GType object_type,
                                            Tag* tag);
static GType tag_tag_snapshot_get_type (void) G_GNUC_CONST  G_GNUC_UNUSED ;
static SourceProxy* tag_real_get_proxy (Proxyable* base);
static TagTagProxy* tag_tag_proxy_new (Tag* tag);
static TagTagProxy* tag_tag_proxy_construct (GType object_type,
                                      Tag* tag);
static GType tag_tag_proxy_get_type (void) G_GNUC_CONST  G_GNUC_UNUSED ;
static gboolean tag_real_has_links (ContainerSource* base);
static SourceBacklink* tag_real_get_backlink (ContainerSource* base);
static void tag_real_break_link (ContainerSource* base,
                          DataSource* source);
static void tag_real_break_link_many (ContainerSource* base,
                               GeeCollection* sources);
static void tag_real_establish_link (ContainerSource* base,
                              DataSource* source);
static void tag_real_establish_link_many (ContainerSource* base,
                                   GeeCollection* sources);
static const gchar* tag_real_get_indexable_keywords (Indexable* base);
static void tag_real_destroy (DataSource* base);
static void tag_tag_snapshot_on_source_destroyed (TagTagSnapshot* self,
                                           DataSource* source);
static void _tag_tag_snapshot_on_source_destroyed_source_collection_item_destroyed (SourceCollection* _sender,
                                                                             DataSource* source,
                                                                             gpointer self);
static TagRow* tag_tag_snapshot_get_row (TagTagSnapshot* self);
static void tag_tag_snapshot_real_notify_broken (SourceSnapshot* base);
static void tag_tag_snapshot_finalize (SourceSnapshot * obj);
static GType tag_tag_snapshot_get_type_once (void);
static DataSource* tag_tag_proxy_real_reconstitute (SourceProxy* base,
                                             gint64 object_id,
                                             SourceSnapshot* snapshot);
static GType tag_tag_proxy_get_type_once (void);
static void tag_finalize (GObject * obj);
static GType tag_get_type_once (void);

static inline gpointer
tag_source_collection_get_instance_private (TagSourceCollection* self)
{
	return G_STRUCT_MEMBER_P (self, TagSourceCollection_private_offset);
}

static void
_tag_source_collection_on_photo_source_reimported_library_photo_source_collection_source_reimported (LibraryPhotoSourceCollection* _sender,
                                                                                                     LibraryPhoto* photo,
                                                                                                     PhotoMetadata* metadata,
                                                                                                     gpointer self)
{
	tag_source_collection_on_photo_source_reimported ((TagSourceCollection*) self, photo, metadata);
}

static guint
_tag_hash_name_string_gee_hash_data_func (gconstpointer v,
                                          gpointer self)
{
	guint result;
	result = tag_hash_name_string ((const gchar*) v);
	return result;
}

static gboolean
_tag_equal_name_strings_gee_equal_data_func (gconstpointer a,
                                             gconstpointer b,
                                             gpointer self)
{
	gboolean result;
	result = tag_equal_name_strings ((const gchar*) a, (const gchar*) b);
	return result;
}

static gint64
_tag_source_collection_get_tag_key_get_source_database_key (DataSource* source,
                                                            gpointer self)
{
	gint64 result;
	result = tag_source_collection_get_tag_key (source);
	return result;
}

TagSourceCollection*
tag_source_collection_construct (GType object_type)
{
	TagSourceCollection* self = NULL;
	LibraryPhotoSourceCollection* _tmp0_;
	VideoSourceCollection* _tmp1_;
	LibraryPhotoSourceCollection* _tmp2_;
	self = (TagSourceCollection*) container_source_collection_construct (object_type, TAG_TYPENAME, "TagSourceCollection", _tag_source_collection_get_tag_key_get_source_database_key, NULL);
	_tmp0_ = library_photo_global;
	container_source_collection_attach_collection ((ContainerSourceCollection*) self, (SourceCollection*) _tmp0_);
	_tmp1_ = video_global;
	container_source_collection_attach_collection ((ContainerSourceCollection*) self, (SourceCollection*) _tmp1_);
	_tmp2_ = library_photo_global;
	g_signal_connect (_tmp2_, "source-reimported", (GCallback) _tag_source_collection_on_photo_source_reimported_library_photo_source_collection_source_reimported, self);
	return self;
}

TagSourceCollection*
tag_source_collection_new (void)
{
	return tag_source_collection_construct (TYPE_TAG_SOURCE_COLLECTION);
}

static gboolean
tag_source_collection_real_holds_type_of_source (SourceCollection* base,
                                                 DataSource* source)
{
	TagSourceCollection * self;
	gboolean result;
	self = (TagSourceCollection*) base;
	g_return_val_if_fail (source != NULL, FALSE);
	result = IS_TAG (source);
	return result;
}

static gint64
tag_source_collection_get_tag_key (DataSource* source)
{
	gint64 result;
	g_return_val_if_fail (source != NULL, -1LL);
	result = data_source_get_instance_id ((DataSource*) G_TYPE_CHECK_INSTANCE_CAST (source, TYPE_TAG, Tag));
	return result;
}

static GeeCollection*
tag_source_collection_real_get_containers_holding_source (ContainerSourceCollection* base,
                                                          DataSource* source)
{
	TagSourceCollection * self;
	GeeList* _tmp0_;
	GeeCollection* result;
	self = (TagSourceCollection*) base;
	g_return_val_if_fail (source != NULL, NULL);
	_tmp0_ = tag_source_collection_fetch_for_source (self, G_TYPE_CHECK_INSTANCE_CAST (source, TYPE_MEDIA_SOURCE, MediaSource));
	result = (GeeCollection*) _tmp0_;
	return result;
}

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

static ContainerSource*
tag_source_collection_real_convert_backlink_to_container (ContainerSourceCollection* base,
                                                          SourceBacklink* backlink)
{
	TagSourceCollection * self;
	TagID tag_id = {0};
	gint64 _tmp0_;
	gint64 _tmp1_;
	Tag* _result_ = NULL;
	Tag* tag = NULL;
	TagID _tmp2_;
	Tag* _tmp3_;
	Tag* _tmp4_;
	Tag* _tmp21_;
	ContainerSource* result;
	self = (TagSourceCollection*) base;
	g_return_val_if_fail (backlink != NULL, NULL);
	_tmp0_ = source_backlink_get_instance_id (backlink);
	_tmp1_ = _tmp0_;
	tag_id_init (&tag_id, _tmp1_);
	_result_ = NULL;
	_tmp2_ = tag_id;
	_tmp3_ = tag_source_collection_fetch (self, &_tmp2_);
	tag = _tmp3_;
	_tmp4_ = tag;
	if (_tmp4_ != NULL) {
		Tag* _tmp5_;
		Tag* _tmp6_;
		_tmp5_ = tag;
		_tmp6_ = _g_object_ref0 (_tmp5_);
		_g_object_unref0 (_result_);
		_result_ = _tmp6_;
	} else {
		{
			GeeIterator* _container_it = NULL;
			GeeCollection* _tmp7_;
			GeeCollection* _tmp8_;
			GeeIterator* _tmp9_;
			GeeIterator* _tmp10_;
			_tmp7_ = container_source_collection_get_holding_tank ((ContainerSourceCollection*) self);
			_tmp8_ = _tmp7_;
			_tmp9_ = gee_iterable_iterator ((GeeIterable*) _tmp8_);
			_tmp10_ = _tmp9_;
			_g_object_unref0 (_tmp8_);
			_container_it = _tmp10_;
			while (TRUE) {
				GeeIterator* _tmp11_;
				ContainerSource* container = NULL;
				GeeIterator* _tmp12_;
				gpointer _tmp13_;
				ContainerSource* _tmp14_;
				Tag* _tmp15_;
				Tag* _tmp16_;
				TagID _tmp17_ = {0};
				TagID _tmp18_;
				_tmp11_ = _container_it;
				if (!gee_iterator_next (_tmp11_)) {
					break;
				}
				_tmp12_ = _container_it;
				_tmp13_ = gee_iterator_get (_tmp12_);
				container = (ContainerSource*) _tmp13_;
				_tmp14_ = container;
				_tmp15_ = _g_object_ref0 (G_TYPE_CHECK_INSTANCE_CAST (_tmp14_, TYPE_TAG, Tag));
				_g_object_unref0 (tag);
				tag = _tmp15_;
				_tmp16_ = tag;
				tag_get_tag_id (_tmp16_, &_tmp17_);
				_tmp18_ = tag_id;
				if (_tmp17_.id == _tmp18_.id) {
					Tag* _tmp19_;
					Tag* _tmp20_;
					_tmp19_ = tag;
					_tmp20_ = _g_object_ref0 (_tmp19_);
					_g_object_unref0 (_result_);
					_result_ = _tmp20_;
					_g_object_unref0 (container);
					break;
				}
				_g_object_unref0 (container);
			}
			_g_object_unref0 (_container_it);
		}
	}
	_tmp21_ = _result_;
	if (_tmp21_ != NULL) {
		gboolean _tmp22_ = FALSE;
		Tag* _tmp23_;
		gchar* _tmp24_;
		gchar* _tmp25_;
		gboolean _tmp26_;
		_tmp23_ = _result_;
		_tmp24_ = tag_get_path (_tmp23_);
		_tmp25_ = _tmp24_;
		_tmp26_ = g_str_has_prefix (_tmp25_, TAG_PATH_SEPARATOR_STRING);
		_g_free0 (_tmp25_);
		if (_tmp26_) {
			Tag* _tmp27_;
			gchar* _tmp28_;
			gchar* _tmp29_;
			GeeList* _tmp30_;
			GeeList* _tmp31_;
			gint _tmp32_;
			gint _tmp33_;
			_tmp27_ = _result_;
			_tmp28_ = tag_get_path (_tmp27_);
			_tmp29_ = _tmp28_;
			_tmp30_ = hierarchical_tag_utilities_enumerate_parent_paths (_tmp29_);
			_tmp31_ = _tmp30_;
			_tmp32_ = gee_collection_get_size ((GeeCollection*) _tmp31_);
			_tmp33_ = _tmp32_;
			_tmp22_ = _tmp33_ > 0;
			_g_object_unref0 (_tmp31_);
			_g_free0 (_tmp29_);
		} else {
			_tmp22_ = FALSE;
		}
		if (_tmp22_) {
			gchar* top_level_with_prefix_path = NULL;
			Tag* _tmp34_;
			gchar* _tmp35_;
			gchar* _tmp36_;
			GeeList* _tmp37_;
			GeeList* _tmp38_;
			gpointer _tmp39_;
			gchar* _tmp40_;
			gchar* top_level_no_prefix_path = NULL;
			const gchar* _tmp41_;
			gchar* _tmp42_;
			_tmp34_ = _result_;
			_tmp35_ = tag_get_path (_tmp34_);
			_tmp36_ = _tmp35_;
			_tmp37_ = hierarchical_tag_utilities_enumerate_parent_paths (_tmp36_);
			_tmp38_ = _tmp37_;
			_tmp39_ = gee_list_get (_tmp38_, 0);
			_tmp40_ = (gchar*) _tmp39_;
			_g_object_unref0 (_tmp38_);
			_g_free0 (_tmp36_);
			top_level_with_prefix_path = _tmp40_;
			_tmp41_ = top_level_with_prefix_path;
			_tmp42_ = hierarchical_tag_utilities_hierarchical_to_flat (_tmp41_);
			top_level_no_prefix_path = _tmp42_;
			{
				GeeIterator* _container_it = NULL;
				GeeCollection* _tmp43_;
				GeeCollection* _tmp44_;
				GeeIterator* _tmp45_;
				GeeIterator* _tmp46_;
				_tmp43_ = container_source_collection_get_holding_tank ((ContainerSourceCollection*) self);
				_tmp44_ = _tmp43_;
				_tmp45_ = gee_iterable_iterator ((GeeIterable*) _tmp44_);
				_tmp46_ = _tmp45_;
				_g_object_unref0 (_tmp44_);
				_container_it = _tmp46_;
				while (TRUE) {
					GeeIterator* _tmp47_;
					ContainerSource* container = NULL;
					GeeIterator* _tmp48_;
					gpointer _tmp49_;
					Tag* parent_candidate = NULL;
					ContainerSource* _tmp50_;
					Tag* _tmp51_;
					Tag* _tmp52_;
					gchar* _tmp53_;
					gchar* _tmp54_;
					const gchar* _tmp55_;
					gboolean _tmp56_;
					_tmp47_ = _container_it;
					if (!gee_iterator_next (_tmp47_)) {
						break;
					}
					_tmp48_ = _container_it;
					_tmp49_ = gee_iterator_get (_tmp48_);
					container = (ContainerSource*) _tmp49_;
					_tmp50_ = container;
					_tmp51_ = _g_object_ref0 (G_TYPE_CHECK_INSTANCE_CAST (_tmp50_, TYPE_TAG, Tag));
					parent_candidate = _tmp51_;
					_tmp52_ = parent_candidate;
					_tmp53_ = tag_get_path (_tmp52_);
					_tmp54_ = _tmp53_;
					_tmp55_ = top_level_no_prefix_path;
					_tmp56_ = g_strcmp0 (_tmp54_, _tmp55_) == 0;
					_g_free0 (_tmp54_);
					if (_tmp56_) {
						Tag* _tmp57_;
						_tmp57_ = parent_candidate;
						tag_promote (_tmp57_);
					}
					_g_object_unref0 (parent_candidate);
					_g_object_unref0 (container);
				}
				_g_object_unref0 (_container_it);
			}
			_g_free0 (top_level_no_prefix_path);
			_g_free0 (top_level_with_prefix_path);
		}
	}
	result = (ContainerSource*) _result_;
	_g_object_unref0 (tag);
	return result;
}

Tag*
tag_source_collection_fetch (TagSourceCollection* self,
                             TagID* tag_id)
{
	TagID _tmp0_;
	DataSource* _tmp1_;
	Tag* result;
	g_return_val_if_fail (self != NULL, NULL);
	g_return_val_if_fail (tag_id != NULL, NULL);
	_tmp0_ = *tag_id;
	_tmp1_ = database_source_collection_fetch_by_key ((DatabaseSourceCollection*) self, _tmp0_.id);
	result = G_TYPE_CHECK_INSTANCE_CAST (_tmp1_, TYPE_TAG, Tag);
	return result;
}

gboolean
tag_source_collection_exists (TagSourceCollection* self,
                              const gchar* name,
                              gboolean treat_htags_as_root)
{
	Tag* _tmp0_;
	Tag* _tmp1_;
	gboolean _tmp2_;
	gboolean result;
	g_return_val_if_fail (self != NULL, FALSE);
	g_return_val_if_fail (name != NULL, FALSE);
	_tmp0_ = tag_source_collection_fetch_by_name (self, name, treat_htags_as_root);
	_tmp1_ = _tmp0_;
	_tmp2_ = _tmp1_ != NULL;
	_g_object_unref0 (_tmp1_);
	result = _tmp2_;
	return result;
}

GeeCollection*
tag_source_collection_get_all_names (TagSourceCollection* self)
{
	GeeHashMap* _tmp0_;
	GeeSet* _tmp1_;
	GeeSet* _tmp2_;
	GeeCollection* result;
	g_return_val_if_fail (self != NULL, NULL);
	_tmp0_ = self->priv->name_map;
	_tmp1_ = gee_abstract_map_get_keys ((GeeAbstractMap*) _tmp0_);
	_tmp2_ = _tmp1_;
	result = (GeeCollection*) _tmp2_;
	return result;
}

GeeList*
tag_source_collection_fetch_for_source (TagSourceCollection* self,
                                        MediaSource* source)
{
	GeeHashMap* _tmp0_;
	gpointer _tmp1_;
	GeeList* result;
	g_return_val_if_fail (self != NULL, NULL);
	g_return_val_if_fail (source != NULL, NULL);
	_tmp0_ = self->priv->source_map;
	_tmp1_ = gee_abstract_map_get ((GeeAbstractMap*) _tmp0_, source);
	result = (GeeList*) _tmp1_;
	return result;
}

GeeSortedSet*
tag_source_collection_fetch_sorted_for_source (TagSourceCollection* self,
                                               MediaSource* photo)
{
	GeeHashMap* _tmp0_;
	gpointer _tmp1_;
	GeeSortedSet* result;
	g_return_val_if_fail (self != NULL, NULL);
	g_return_val_if_fail (photo != NULL, NULL);
	_tmp0_ = self->priv->sorted_source_map;
	_tmp1_ = gee_abstract_map_get ((GeeAbstractMap*) _tmp0_, photo);
	result = (GeeSortedSet*) _tmp1_;
	return result;
}

Tag*
tag_source_collection_fetch_by_name (TagSourceCollection* self,
                                     const gchar* name,
                                     gboolean treat_htags_as_root)
{
	GeeHashMap* _tmp17_;
	gpointer _tmp18_;
	Tag* result;
	g_return_val_if_fail (self != NULL, NULL);
	g_return_val_if_fail (name != NULL, NULL);
	if (treat_htags_as_root) {
		if (g_str_has_prefix (name, TAG_PATH_SEPARATOR_STRING)) {
			GeeList* _tmp0_;
			GeeList* _tmp1_;
			gint _tmp2_;
			gint _tmp3_;
			gboolean _tmp4_;
			_tmp0_ = hierarchical_tag_utilities_enumerate_path_components (name);
			_tmp1_ = _tmp0_;
			_tmp2_ = gee_collection_get_size ((GeeCollection*) _tmp1_);
			_tmp3_ = _tmp2_;
			_tmp4_ = _tmp3_ == 1;
			_g_object_unref0 (_tmp1_);
			if (_tmp4_) {
				Tag* tag = NULL;
				GeeHashMap* _tmp5_;
				gchar* _tmp6_;
				gchar* _tmp7_;
				gpointer _tmp8_;
				Tag* _tmp9_;
				Tag* _tmp10_;
				_tmp5_ = self->priv->name_map;
				_tmp6_ = hierarchical_tag_utilities_hierarchical_to_flat (name);
				_tmp7_ = _tmp6_;
				_tmp8_ = gee_abstract_map_get ((GeeAbstractMap*) _tmp5_, _tmp7_);
				_tmp9_ = (Tag*) _tmp8_;
				_g_free0 (_tmp7_);
				tag = _tmp9_;
				_tmp10_ = tag;
				if (_tmp10_ != NULL) {
					result = tag;
					return result;
				}
				_g_object_unref0 (tag);
			}
		} else {
			Tag* tag = NULL;
			GeeHashMap* _tmp11_;
			gchar* _tmp12_;
			gchar* _tmp13_;
			gpointer _tmp14_;
			Tag* _tmp15_;
			Tag* _tmp16_;
			_tmp11_ = self->priv->name_map;
			_tmp12_ = hierarchical_tag_utilities_flat_to_hierarchical (name);
			_tmp13_ = _tmp12_;
			_tmp14_ = gee_abstract_map_get ((GeeAbstractMap*) _tmp11_, _tmp13_);
			_tmp15_ = (Tag*) _tmp14_;
			_g_free0 (_tmp13_);
			tag = _tmp15_;
			_tmp16_ = tag;
			if (_tmp16_ != NULL) {
				result = tag;
				return result;
			}
			_g_object_unref0 (tag);
		}
	}
	_tmp17_ = self->priv->name_map;
	_tmp18_ = gee_abstract_map_get ((GeeAbstractMap*) _tmp17_, name);
	result = (Tag*) _tmp18_;
	return result;
}

Tag*
tag_source_collection_restore_tag_from_holding_tank (TagSourceCollection* self,
                                                     const gchar* name)
{
	Tag* found = NULL;
	Tag* _tmp15_;
	Tag* result;
	g_return_val_if_fail (self != NULL, NULL);
	g_return_val_if_fail (name != NULL, NULL);
	found = NULL;
	{
		GeeIterator* _container_it = NULL;
		GeeCollection* _tmp0_;
		GeeCollection* _tmp1_;
		GeeIterator* _tmp2_;
		GeeIterator* _tmp3_;
		_tmp0_ = container_source_collection_get_holding_tank ((ContainerSourceCollection*) self);
		_tmp1_ = _tmp0_;
		_tmp2_ = gee_iterable_iterator ((GeeIterable*) _tmp1_);
		_tmp3_ = _tmp2_;
		_g_object_unref0 (_tmp1_);
		_container_it = _tmp3_;
		while (TRUE) {
			GeeIterator* _tmp4_;
			ContainerSource* container = NULL;
			GeeIterator* _tmp5_;
			gpointer _tmp6_;
			Tag* tag = NULL;
			ContainerSource* _tmp7_;
			Tag* _tmp8_;
			Tag* _tmp9_;
			gchar* _tmp10_;
			gchar* _tmp11_;
			gboolean _tmp12_;
			_tmp4_ = _container_it;
			if (!gee_iterator_next (_tmp4_)) {
				break;
			}
			_tmp5_ = _container_it;
			_tmp6_ = gee_iterator_get (_tmp5_);
			container = (ContainerSource*) _tmp6_;
			_tmp7_ = container;
			_tmp8_ = _g_object_ref0 (G_TYPE_CHECK_INSTANCE_CAST (_tmp7_, TYPE_TAG, Tag));
			tag = _tmp8_;
			_tmp9_ = tag;
			_tmp10_ = data_object_get_name ((DataObject*) _tmp9_);
			_tmp11_ = _tmp10_;
			_tmp12_ = g_strcmp0 (_tmp11_, name) == 0;
			_g_free0 (_tmp11_);
			if (_tmp12_) {
				Tag* _tmp13_;
				Tag* _tmp14_;
				_tmp13_ = tag;
				_tmp14_ = _g_object_ref0 (_tmp13_);
				_g_object_unref0 (found);
				found = _tmp14_;
				_g_object_unref0 (tag);
				_g_object_unref0 (container);
				break;
			}
			_g_object_unref0 (tag);
			_g_object_unref0 (container);
		}
		_g_object_unref0 (_container_it);
	}
	_tmp15_ = found;
	if (_tmp15_ != NULL) {
		gboolean relinked = FALSE;
		Tag* _tmp16_;
		_tmp16_ = found;
		relinked = container_source_collection_relink_from_holding_tank ((ContainerSourceCollection*) self, (ContainerSource*) _tmp16_);
		_vala_assert (relinked, "relinked");
	}
	result = found;
	return result;
}

static void
tag_source_collection_real_notify_items_added (DataCollection* base,
                                               GeeIterable* added)
{
	TagSourceCollection * self;
	self = (TagSourceCollection*) base;
	g_return_if_fail (added != NULL);
	{
		GeeIterator* _object_it = NULL;
		GeeIterator* _tmp0_;
		_tmp0_ = gee_iterable_iterator (added);
		_object_it = _tmp0_;
		while (TRUE) {
			GeeIterator* _tmp1_;
			DataObject* object = NULL;
			GeeIterator* _tmp2_;
			gpointer _tmp3_;
			Tag* tag = NULL;
			DataObject* _tmp4_;
			Tag* _tmp5_;
			GeeHashMap* _tmp6_;
			Tag* _tmp7_;
			gchar* _tmp8_;
			gchar* _tmp9_;
			GeeHashMap* _tmp10_;
			Tag* _tmp11_;
			gchar* _tmp12_;
			gchar* _tmp13_;
			Tag* _tmp14_;
			_tmp1_ = _object_it;
			if (!gee_iterator_next (_tmp1_)) {
				break;
			}
			_tmp2_ = _object_it;
			_tmp3_ = gee_iterator_get (_tmp2_);
			object = (DataObject*) _tmp3_;
			_tmp4_ = object;
			_tmp5_ = _g_object_ref0 (G_TYPE_CHECK_INSTANCE_CAST (_tmp4_, TYPE_TAG, Tag));
			tag = _tmp5_;
			_tmp6_ = self->priv->name_map;
			_tmp7_ = tag;
			_tmp8_ = data_object_get_name ((DataObject*) _tmp7_);
			_tmp9_ = _tmp8_;
			_vala_assert (!gee_abstract_map_has_key ((GeeAbstractMap*) _tmp6_, _tmp9_), "!name_map.has_key (tag.get_name ())");
			_g_free0 (_tmp9_);
			_tmp10_ = self->priv->name_map;
			_tmp11_ = tag;
			_tmp12_ = data_object_get_name ((DataObject*) _tmp11_);
			_tmp13_ = _tmp12_;
			_tmp14_ = tag;
			gee_abstract_map_set ((GeeAbstractMap*) _tmp10_, _tmp13_, _tmp14_);
			_g_free0 (_tmp13_);
			_g_object_unref0 (tag);
			_g_object_unref0 (object);
		}
		_g_object_unref0 (_object_it);
	}
	DATA_COLLECTION_CLASS (tag_source_collection_parent_class)->notify_items_added ((DataCollection*) G_TYPE_CHECK_INSTANCE_CAST (self, TYPE_CONTAINER_SOURCE_COLLECTION, ContainerSourceCollection), added);
}

static void
tag_source_collection_real_notify_items_removed (DataCollection* base,
                                                 GeeIterable* removed)
{
	TagSourceCollection * self;
	self = (TagSourceCollection*) base;
	g_return_if_fail (removed != NULL);
	{
		GeeIterator* _object_it = NULL;
		GeeIterator* _tmp0_;
		_tmp0_ = gee_iterable_iterator (removed);
		_object_it = _tmp0_;
		while (TRUE) {
			GeeIterator* _tmp1_;
			DataObject* object = NULL;
			GeeIterator* _tmp2_;
			gpointer _tmp3_;
			Tag* tag = NULL;
			DataObject* _tmp4_;
			Tag* _tmp5_;
			gboolean unset = FALSE;
			GeeHashMap* _tmp6_;
			Tag* _tmp7_;
			gchar* _tmp8_;
			gchar* _tmp9_;
			gboolean _tmp10_;
			Tag* parent = NULL;
			Tag* _tmp11_;
			Tag* _tmp12_;
			gboolean _tmp13_ = FALSE;
			Tag* _tmp14_;
			_tmp1_ = _object_it;
			if (!gee_iterator_next (_tmp1_)) {
				break;
			}
			_tmp2_ = _object_it;
			_tmp3_ = gee_iterator_get (_tmp2_);
			object = (DataObject*) _tmp3_;
			_tmp4_ = object;
			_tmp5_ = _g_object_ref0 (G_TYPE_CHECK_INSTANCE_CAST (_tmp4_, TYPE_TAG, Tag));
			tag = _tmp5_;
			_tmp6_ = self->priv->name_map;
			_tmp7_ = tag;
			_tmp8_ = data_object_get_name ((DataObject*) _tmp7_);
			_tmp9_ = _tmp8_;
			_tmp10_ = gee_abstract_map_unset ((GeeAbstractMap*) _tmp6_, _tmp9_, NULL);
			_g_free0 (_tmp9_);
			unset = _tmp10_;
			_vala_assert (unset, "unset");
			_tmp11_ = tag;
			_tmp12_ = tag_get_hierarchical_parent (_tmp11_);
			parent = _tmp12_;
			_tmp14_ = parent;
			if (_tmp14_ != NULL) {
				Tag* _tmp15_;
				Tag* _tmp16_;
				Tag* _tmp17_;
				_tmp15_ = parent;
				_tmp16_ = tag_get_hierarchical_parent (_tmp15_);
				_tmp17_ = _tmp16_;
				_tmp13_ = _tmp17_ == NULL;
				_g_object_unref0 (_tmp17_);
			} else {
				_tmp13_ = FALSE;
			}
			if (_tmp13_) {
				Tag* _tmp18_;
				GeeList* _tmp19_;
				GeeList* _tmp20_;
				gint _tmp21_;
				gint _tmp22_;
				gboolean _tmp23_;
				_tmp18_ = parent;
				_tmp19_ = tag_get_hierarchical_children (_tmp18_);
				_tmp20_ = _tmp19_;
				_tmp21_ = gee_collection_get_size ((GeeCollection*) _tmp20_);
				_tmp22_ = _tmp21_;
				_tmp23_ = _tmp22_ == 0;
				_g_object_unref0 (_tmp20_);
				if (_tmp23_) {
					Tag* _tmp24_;
					_tmp24_ = parent;
					tag_flatten (_tmp24_);
				}
			}
			_g_object_unref0 (parent);
			_g_object_unref0 (tag);
			_g_object_unref0 (object);
		}
		_g_object_unref0 (_object_it);
	}
	DATA_COLLECTION_CLASS (tag_source_collection_parent_class)->notify_items_removed ((DataCollection*) G_TYPE_CHECK_INSTANCE_CAST (self, TYPE_CONTAINER_SOURCE_COLLECTION, ContainerSourceCollection), removed);
}

static void
tag_source_collection_real_notify_items_altered (DataCollection* base,
                                                 GeeMap* map)
{
	TagSourceCollection * self;
	self = (TagSourceCollection*) base;
	g_return_if_fail (map != NULL);
	{
		GeeIterator* _object_it = NULL;
		GeeSet* _tmp0_;
		GeeSet* _tmp1_;
		GeeSet* _tmp2_;
		GeeIterator* _tmp3_;
		GeeIterator* _tmp4_;
		_tmp0_ = gee_map_get_keys (map);
		_tmp1_ = _tmp0_;
		_tmp2_ = _tmp1_;
		_tmp3_ = gee_iterable_iterator ((GeeIterable*) _tmp2_);
		_tmp4_ = _tmp3_;
		_g_object_unref0 (_tmp2_);
		_object_it = _tmp4_;
		while (TRUE) {
			GeeIterator* _tmp5_;
			DataObject* object = NULL;
			GeeIterator* _tmp6_;
			gpointer _tmp7_;
			Tag* tag = NULL;
			DataObject* _tmp8_;
			Tag* _tmp9_;
			gchar* old_name = NULL;
			GeeMapIterator* iter = NULL;
			GeeHashMap* _tmp10_;
			GeeMapIterator* _tmp11_;
			const gchar* _tmp20_;
			Tag* _tmp21_;
			gchar* _tmp22_;
			gchar* _tmp23_;
			const gchar* _tmp24_;
			gboolean _tmp25_;
			_tmp5_ = _object_it;
			if (!gee_iterator_next (_tmp5_)) {
				break;
			}
			_tmp6_ = _object_it;
			_tmp7_ = gee_iterator_get (_tmp6_);
			object = (DataObject*) _tmp7_;
			_tmp8_ = object;
			_tmp9_ = _g_object_ref0 (G_TYPE_CHECK_INSTANCE_CAST (_tmp8_, TYPE_TAG, Tag));
			tag = _tmp9_;
			old_name = NULL;
			_tmp10_ = self->priv->name_map;
			_tmp11_ = gee_abstract_map_map_iterator ((GeeAbstractMap*) _tmp10_);
			iter = _tmp11_;
			while (TRUE) {
				GeeMapIterator* _tmp12_;
				GeeMapIterator* _tmp13_;
				gpointer _tmp14_;
				Tag* _tmp15_;
				Tag* _tmp16_;
				gboolean _tmp17_;
				GeeMapIterator* _tmp18_;
				gpointer _tmp19_;
				_tmp12_ = iter;
				if (!gee_map_iterator_next (_tmp12_)) {
					break;
				}
				_tmp13_ = iter;
				_tmp14_ = gee_map_iterator_get_value (_tmp13_);
				_tmp15_ = (Tag*) _tmp14_;
				_tmp16_ = tag;
				_tmp17_ = !data_source_equals ((DataSource*) _tmp15_, (DataSource*) _tmp16_);
				_g_object_unref0 (_tmp15_);
				if (_tmp17_) {
					continue;
				}
				_tmp18_ = iter;
				_tmp19_ = gee_map_iterator_get_key (_tmp18_);
				_g_free0 (old_name);
				old_name = (gchar*) _tmp19_;
				break;
			}
			_tmp20_ = old_name;
			_vala_assert (_tmp20_ != NULL, "old_name != null");
			_tmp21_ = tag;
			_tmp22_ = data_object_get_name ((DataObject*) _tmp21_);
			_tmp23_ = _tmp22_;
			_tmp24_ = old_name;
			_tmp25_ = g_strcmp0 (_tmp23_, _tmp24_) != 0;
			_g_free0 (_tmp23_);
			if (_tmp25_) {
				GeeHashMap* _tmp26_;
				const gchar* _tmp27_;
				GeeHashMap* _tmp28_;
				Tag* _tmp29_;
				gchar* _tmp30_;
				gchar* _tmp31_;
				Tag* _tmp32_;
				_tmp26_ = self->priv->name_map;
				_tmp27_ = old_name;
				gee_abstract_map_unset ((GeeAbstractMap*) _tmp26_, _tmp27_, NULL);
				_tmp28_ = self->priv->name_map;
				_tmp29_ = tag;
				_tmp30_ = data_object_get_name ((DataObject*) _tmp29_);
				_tmp31_ = _tmp30_;
				_tmp32_ = tag;
				gee_abstract_map_set ((GeeAbstractMap*) _tmp28_, _tmp31_, _tmp32_);
				_g_free0 (_tmp31_);
			}
			_g_object_unref0 (iter);
			_g_free0 (old_name);
			_g_object_unref0 (tag);
			_g_object_unref0 (object);
		}
		_g_object_unref0 (_object_it);
	}
	DATA_COLLECTION_CLASS (tag_source_collection_parent_class)->notify_items_altered ((DataCollection*) G_TYPE_CHECK_INSTANCE_CAST (self, TYPE_CONTAINER_SOURCE_COLLECTION, ContainerSourceCollection), map);
}

static gint
_tag_compare_names_gcompare_data_func (gconstpointer a,
                                       gconstpointer b,
                                       gpointer self)
{
	gint result;
	result = tag_compare_names ((Tag*) a, (Tag*) b);
	return result;
}

static void
tag_source_collection_real_notify_container_contents_added (ContainerSourceCollection* base,
                                                            ContainerSource* container,
                                                            GeeCollection* added,
                                                            gboolean relinking)
{
	TagSourceCollection * self;
	Tag* tag = NULL;
	Tag* _tmp0_;
	GeeCollection* sources = NULL;
	GeeCollection* _tmp1_;
	self = (TagSourceCollection*) base;
	g_return_if_fail (container != NULL);
	g_return_if_fail (added != NULL);
	_tmp0_ = _g_object_ref0 (G_TYPE_CHECK_INSTANCE_CAST (container, TYPE_TAG, Tag));
	tag = _tmp0_;
	_tmp1_ = _g_object_ref0 (G_TYPE_CHECK_INSTANCE_CAST (added, GEE_TYPE_COLLECTION, GeeCollection));
	sources = _tmp1_;
	{
		GeeIterator* _source_it = NULL;
		GeeCollection* _tmp2_;
		GeeIterator* _tmp3_;
		_tmp2_ = sources;
		_tmp3_ = gee_iterable_iterator ((GeeIterable*) _tmp2_);
		_source_it = _tmp3_;
		while (TRUE) {
			GeeIterator* _tmp4_;
			MediaSource* source = NULL;
			GeeIterator* _tmp5_;
			gpointer _tmp6_;
			GeeList* tags = NULL;
			GeeHashMap* _tmp7_;
			MediaSource* _tmp8_;
			gpointer _tmp9_;
			GeeList* _tmp10_;
			gboolean is_added = FALSE;
			GeeList* _tmp15_;
			Tag* _tmp16_;
			GeeSortedSet* sorted_tags = NULL;
			GeeHashMap* _tmp17_;
			MediaSource* _tmp18_;
			gpointer _tmp19_;
			GeeSortedSet* _tmp20_;
			GeeSortedSet* _tmp25_;
			Tag* _tmp26_;
			_tmp4_ = _source_it;
			if (!gee_iterator_next (_tmp4_)) {
				break;
			}
			_tmp5_ = _source_it;
			_tmp6_ = gee_iterator_get (_tmp5_);
			source = (MediaSource*) _tmp6_;
			_tmp7_ = self->priv->source_map;
			_tmp8_ = source;
			_tmp9_ = gee_abstract_map_get ((GeeAbstractMap*) _tmp7_, _tmp8_);
			tags = (GeeList*) _tmp9_;
			_tmp10_ = tags;
			if (_tmp10_ == NULL) {
				GeeArrayList* _tmp11_;
				GeeHashMap* _tmp12_;
				MediaSource* _tmp13_;
				GeeList* _tmp14_;
				_tmp11_ = gee_array_list_new (TYPE_TAG, (GBoxedCopyFunc) g_object_ref, (GDestroyNotify) g_object_unref, NULL, NULL, NULL);
				_g_object_unref0 (tags);
				tags = (GeeList*) _tmp11_;
				_tmp12_ = self->priv->source_map;
				_tmp13_ = source;
				_tmp14_ = tags;
				gee_abstract_map_set ((GeeAbstractMap*) _tmp12_, _tmp13_, _tmp14_);
			}
			_tmp15_ = tags;
			_tmp16_ = tag;
			is_added = gee_collection_add ((GeeCollection*) _tmp15_, _tmp16_);
			_vala_assert (is_added, "is_added");
			_tmp17_ = self->priv->sorted_source_map;
			_tmp18_ = source;
			_tmp19_ = gee_abstract_map_get ((GeeAbstractMap*) _tmp17_, _tmp18_);
			sorted_tags = (GeeSortedSet*) _tmp19_;
			_tmp20_ = sorted_tags;
			if (_tmp20_ == NULL) {
				GeeTreeSet* _tmp21_;
				GeeHashMap* _tmp22_;
				MediaSource* _tmp23_;
				GeeSortedSet* _tmp24_;
				_tmp21_ = gee_tree_set_new (TYPE_TAG, (GBoxedCopyFunc) g_object_ref, (GDestroyNotify) g_object_unref, _tag_compare_names_gcompare_data_func, NULL, NULL);
				_g_object_unref0 (sorted_tags);
				sorted_tags = (GeeSortedSet*) _tmp21_;
				_tmp22_ = self->priv->sorted_source_map;
				_tmp23_ = source;
				_tmp24_ = sorted_tags;
				gee_abstract_map_set ((GeeAbstractMap*) _tmp22_, _tmp23_, _tmp24_);
			}
			_tmp25_ = sorted_tags;
			_tmp26_ = tag;
			is_added = gee_collection_add ((GeeCollection*) _tmp25_, _tmp26_);
			_vala_assert (is_added, "is_added");
			_g_object_unref0 (sorted_tags);
			_g_object_unref0 (tags);
			_g_object_unref0 (source);
		}
		_g_object_unref0 (_source_it);
	}
	CONTAINER_SOURCE_COLLECTION_CLASS (tag_source_collection_parent_class)->notify_container_contents_added (G_TYPE_CHECK_INSTANCE_CAST (self, TYPE_CONTAINER_SOURCE_COLLECTION, ContainerSourceCollection), container, added, relinking);
	_g_object_unref0 (sources);
	_g_object_unref0 (tag);
}

static void
tag_source_collection_real_notify_container_contents_removed (ContainerSourceCollection* base,
                                                              ContainerSource* container,
                                                              GeeCollection* removed,
                                                              gboolean unlinking)
{
	TagSourceCollection * self;
	Tag* tag = NULL;
	Tag* _tmp0_;
	GeeCollection* sources = NULL;
	GeeCollection* _tmp1_;
	self = (TagSourceCollection*) base;
	g_return_if_fail (container != NULL);
	g_return_if_fail (removed != NULL);
	_tmp0_ = _g_object_ref0 (G_TYPE_CHECK_INSTANCE_CAST (container, TYPE_TAG, Tag));
	tag = _tmp0_;
	_tmp1_ = _g_object_ref0 (G_TYPE_CHECK_INSTANCE_CAST (removed, GEE_TYPE_COLLECTION, GeeCollection));
	sources = _tmp1_;
	{
		GeeIterator* _source_it = NULL;
		GeeCollection* _tmp2_;
		GeeIterator* _tmp3_;
		_tmp2_ = sources;
		_tmp3_ = gee_iterable_iterator ((GeeIterable*) _tmp2_);
		_source_it = _tmp3_;
		while (TRUE) {
			GeeIterator* _tmp4_;
			MediaSource* source = NULL;
			GeeIterator* _tmp5_;
			gpointer _tmp6_;
			GeeList* tags = NULL;
			GeeHashMap* _tmp7_;
			MediaSource* _tmp8_;
			gpointer _tmp9_;
			GeeList* _tmp10_;
			gboolean is_removed = FALSE;
			GeeList* _tmp11_;
			Tag* _tmp12_;
			GeeList* _tmp13_;
			gint _tmp14_;
			gint _tmp15_;
			GeeSortedSet* sorted_tags = NULL;
			GeeHashMap* _tmp18_;
			MediaSource* _tmp19_;
			gpointer _tmp20_;
			GeeSortedSet* _tmp21_;
			GeeSortedSet* _tmp22_;
			Tag* _tmp23_;
			GeeSortedSet* _tmp24_;
			gint _tmp25_;
			gint _tmp26_;
			_tmp4_ = _source_it;
			if (!gee_iterator_next (_tmp4_)) {
				break;
			}
			_tmp5_ = _source_it;
			_tmp6_ = gee_iterator_get (_tmp5_);
			source = (MediaSource*) _tmp6_;
			_tmp7_ = self->priv->source_map;
			_tmp8_ = source;
			_tmp9_ = gee_abstract_map_get ((GeeAbstractMap*) _tmp7_, _tmp8_);
			tags = (GeeList*) _tmp9_;
			_tmp10_ = tags;
			_vala_assert (_tmp10_ != NULL, "tags != null");
			_tmp11_ = tags;
			_tmp12_ = tag;
			is_removed = gee_collection_remove ((GeeCollection*) _tmp11_, _tmp12_);
			_vala_assert (is_removed, "is_removed");
			_tmp13_ = tags;
			_tmp14_ = gee_collection_get_size ((GeeCollection*) _tmp13_);
			_tmp15_ = _tmp14_;
			if (_tmp15_ == 0) {
				GeeHashMap* _tmp16_;
				MediaSource* _tmp17_;
				_tmp16_ = self->priv->source_map;
				_tmp17_ = source;
				gee_abstract_map_unset ((GeeAbstractMap*) _tmp16_, _tmp17_, NULL);
			}
			_tmp18_ = self->priv->sorted_source_map;
			_tmp19_ = source;
			_tmp20_ = gee_abstract_map_get ((GeeAbstractMap*) _tmp18_, _tmp19_);
			sorted_tags = (GeeSortedSet*) _tmp20_;
			_tmp21_ = sorted_tags;
			_vala_assert (_tmp21_ != NULL, "sorted_tags != null");
			_tmp22_ = sorted_tags;
			_tmp23_ = tag;
			is_removed = gee_collection_remove ((GeeCollection*) _tmp22_, _tmp23_);
			_vala_assert (is_removed, "is_removed");
			_tmp24_ = sorted_tags;
			_tmp25_ = gee_collection_get_size ((GeeCollection*) _tmp24_);
			_tmp26_ = _tmp25_;
			if (_tmp26_ == 0) {
				GeeHashMap* _tmp27_;
				MediaSource* _tmp28_;
				_tmp27_ = self->priv->sorted_source_map;
				_tmp28_ = source;
				gee_abstract_map_unset ((GeeAbstractMap*) _tmp27_, _tmp28_, NULL);
			}
			_g_object_unref0 (sorted_tags);
			_g_object_unref0 (tags);
			_g_object_unref0 (source);
		}
		_g_object_unref0 (_source_it);
	}
	CONTAINER_SOURCE_COLLECTION_CLASS (tag_source_collection_parent_class)->notify_container_contents_removed (G_TYPE_CHECK_INSTANCE_CAST (self, TYPE_CONTAINER_SOURCE_COLLECTION, ContainerSourceCollection), container, removed, unlinking);
	_g_object_unref0 (sources);
	_g_object_unref0 (tag);
}

static void
tag_source_collection_on_photo_source_reimported (TagSourceCollection* self,
                                                  LibraryPhoto* photo,
                                                  PhotoMetadata* metadata)
{
	g_return_if_fail (self != NULL);
	g_return_if_fail (photo != NULL);
}

static void
tag_source_collection_class_init (TagSourceCollectionClass * klass,
                                  gpointer klass_data)
{
	tag_source_collection_parent_class = g_type_class_peek_parent (klass);
	((DataCollectionClass *) klass)->finalize = tag_source_collection_finalize;
	g_type_class_adjust_private_offset (klass, &TagSourceCollection_private_offset);
	((SourceCollectionClass *) klass)->holds_type_of_source = (gboolean (*) (SourceCollection*, DataSource*)) tag_source_collection_real_holds_type_of_source;
	((ContainerSourceCollectionClass *) klass)->get_containers_holding_source = (GeeCollection* (*) (ContainerSourceCollection*, DataSource*)) tag_source_collection_real_get_containers_holding_source;
	((ContainerSourceCollectionClass *) klass)->convert_backlink_to_container = (ContainerSource* (*) (ContainerSourceCollection*, SourceBacklink*)) tag_source_collection_real_convert_backlink_to_container;
	((DataCollectionClass *) klass)->notify_items_added = (void (*) (DataCollection*, GeeIterable*)) tag_source_collection_real_notify_items_added;
	((DataCollectionClass *) klass)->notify_items_removed = (void (*) (DataCollection*, GeeIterable*)) tag_source_collection_real_notify_items_removed;
	((DataCollectionClass *) klass)->notify_items_altered = (void (*) (DataCollection*, GeeMap*)) tag_source_collection_real_notify_items_altered;
	((ContainerSourceCollectionClass *) klass)->notify_container_contents_added = (void (*) (ContainerSourceCollection*, ContainerSource*, GeeCollection*, gboolean)) tag_source_collection_real_notify_container_contents_added;
	((ContainerSourceCollectionClass *) klass)->notify_container_contents_removed = (void (*) (ContainerSourceCollection*, ContainerSource*, GeeCollection*, gboolean)) tag_source_collection_real_notify_container_contents_removed;
}

static void
tag_source_collection_instance_init (TagSourceCollection * self,
                                     gpointer klass)
{
	GeeHashMap* _tmp0_;
	GeeHashMap* _tmp1_;
	GeeHashMap* _tmp2_;
	self->priv = tag_source_collection_get_instance_private (self);
	_tmp0_ = gee_hash_map_new (G_TYPE_STRING, (GBoxedCopyFunc) g_strdup, (GDestroyNotify) g_free, TYPE_TAG, (GBoxedCopyFunc) g_object_ref, (GDestroyNotify) g_object_unref, _tag_hash_name_string_gee_hash_data_func, NULL, NULL, _tag_equal_name_strings_gee_equal_data_func, NULL, NULL, NULL, NULL, NULL);
	self->priv->name_map = _tmp0_;
	_tmp1_ = gee_hash_map_new (TYPE_MEDIA_SOURCE, (GBoxedCopyFunc) g_object_ref, (GDestroyNotify) g_object_unref, GEE_TYPE_LIST, (GBoxedCopyFunc) g_object_ref, (GDestroyNotify) g_object_unref, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
	self->priv->source_map = _tmp1_;
	_tmp2_ = gee_hash_map_new (TYPE_MEDIA_SOURCE, (GBoxedCopyFunc) g_object_ref, (GDestroyNotify) g_object_unref, GEE_TYPE_SORTED_SET, (GBoxedCopyFunc) g_object_ref, (GDestroyNotify) g_object_unref, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
	self->priv->sorted_source_map = _tmp2_;
}

static void
tag_source_collection_finalize (DataCollection * obj)
{
	TagSourceCollection * self;
	LibraryPhotoSourceCollection* _tmp0_;
	guint _tmp1_;
	self = G_TYPE_CHECK_INSTANCE_CAST (obj, TYPE_TAG_SOURCE_COLLECTION, TagSourceCollection);
	_tmp0_ = library_photo_global;
	g_signal_parse_name ("source-reimported", TYPE_LIBRARY_PHOTO_SOURCE_COLLECTION, &_tmp1_, NULL, FALSE);
	g_signal_handlers_disconnect_matched (_tmp0_, G_SIGNAL_MATCH_ID | G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA, _tmp1_, 0, NULL, (GCallback) _tag_source_collection_on_photo_source_reimported_library_photo_source_collection_source_reimported, self);
	_g_object_unref0 (self->priv->name_map);
	_g_object_unref0 (self->priv->source_map);
	_g_object_unref0 (self->priv->sorted_source_map);
	DATA_COLLECTION_CLASS (tag_source_collection_parent_class)->finalize (obj);
}

static GType
tag_source_collection_get_type_once (void)
{
	static const GTypeInfo g_define_type_info = { sizeof (TagSourceCollectionClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) tag_source_collection_class_init, (GClassFinalizeFunc) NULL, NULL, sizeof (TagSourceCollection), 0, (GInstanceInitFunc) tag_source_collection_instance_init, NULL };
	GType tag_source_collection_type_id;
	tag_source_collection_type_id = g_type_register_static (TYPE_CONTAINER_SOURCE_COLLECTION, "TagSourceCollection", &g_define_type_info, 0);
	TagSourceCollection_private_offset = g_type_add_instance_private (tag_source_collection_type_id, sizeof (TagSourceCollectionPrivate));
	return tag_source_collection_type_id;
}

GType
tag_source_collection_get_type (void)
{
	static volatile gsize tag_source_collection_type_id__once = 0;
	if (g_once_init_enter (&tag_source_collection_type_id__once)) {
		GType tag_source_collection_type_id;
		tag_source_collection_type_id = tag_source_collection_get_type_once ();
		g_once_init_leave (&tag_source_collection_type_id__once, tag_source_collection_type_id);
	}
	return tag_source_collection_type_id__once;
}

static inline gpointer
tag_get_instance_private (Tag* self)
{
	return G_STRUCT_MEMBER_P (self, Tag_private_offset);
}

static void
_tag_on_media_views_contents_altered_data_collection_contents_altered (DataCollection* _sender,
                                                                       GeeIterable* added,
                                                                       GeeIterable* removed,
                                                                       gpointer self)
{
	tag_on_media_views_contents_altered ((Tag*) self, added, removed);
}

static void
_tag_on_sources_destroyed_source_collection_items_destroyed (SourceCollection* _sender,
                                                             GeeCollection* destroyed,
                                                             gpointer self)
{
	tag_on_sources_destroyed ((Tag*) self, destroyed);
}

static gpointer
_tag_row_ref0 (gpointer self)
{
	return self ? tag_row_ref (self) : NULL;
}

static Tag*
tag_construct (GType object_type,
               TagRow* row,
               gint64 object_id)
{
	Tag * self = NULL;
	TagRow* _tmp0_;
	TagRow* _tmp1_;
	TagRow* _tmp2_;
	const gchar* _tmp3_;
	gchar* _tmp4_;
	GeeArrayList* source_list = NULL;
	GeeArrayList* _tmp5_;
	GeeArrayList* thumbnail_views = NULL;
	GeeArrayList* _tmp6_;
	TagRow* _tmp7_;
	GeeSet* _tmp8_;
	TagID _tmp29_;
	gchar* _tmp30_;
	gchar* _tmp31_;
	gchar* _tmp32_;
	gchar* _tmp33_;
	ViewCollection* _tmp34_;
	ViewCollection* _tmp35_;
	GeeArrayList* _tmp36_;
	GeeCollection* _tmp37_;
	GeeCollection* _tmp38_;
	GeeArrayList* _tmp39_;
	gint _tmp40_;
	gint _tmp41_;
	ViewCollection* _tmp46_;
	LibraryPhotoSourceCollection* _tmp47_;
	VideoSourceCollection* _tmp48_;
	g_return_val_if_fail (row != NULL, NULL);
	self = (Tag*) data_source_construct (object_type, object_id);
	_tmp0_ = _tag_row_ref0 (row);
	_tag_row_unref0 (self->priv->row);
	self->priv->row = _tmp0_;
	_tmp1_ = self->priv->row;
	_tmp2_ = self->priv->row;
	_tmp3_ = _tmp2_->name;
	_tmp4_ = tag_prep_tag_name (_tmp3_);
	_g_free0 (_tmp1_->name);
	_tmp1_->name = _tmp4_;
	_tmp5_ = gee_array_list_new (TYPE_MEDIA_SOURCE, (GBoxedCopyFunc) g_object_ref, (GDestroyNotify) g_object_unref, NULL, NULL, NULL);
	source_list = _tmp5_;
	_tmp6_ = gee_array_list_new (TYPE_THUMBNAIL_VIEW, (GBoxedCopyFunc) g_object_ref, (GDestroyNotify) g_object_unref, NULL, NULL, NULL);
	thumbnail_views = _tmp6_;
	_tmp7_ = self->priv->row;
	_tmp8_ = _tmp7_->source_id_list;
	if (_tmp8_ != NULL) {
		{
			GeeIterator* _source_id_it = NULL;
			TagRow* _tmp9_;
			GeeSet* _tmp10_;
			GeeIterator* _tmp11_;
			_tmp9_ = self->priv->row;
			_tmp10_ = _tmp9_->source_id_list;
			_tmp11_ = gee_iterable_iterator ((GeeIterable*) _tmp10_);
			_source_id_it = _tmp11_;
			while (TRUE) {
				GeeIterator* _tmp12_;
				gchar* source_id = NULL;
				GeeIterator* _tmp13_;
				gpointer _tmp14_;
				MediaSource* current_source = NULL;
				MediaCollectionRegistry* _tmp15_;
				MediaCollectionRegistry* _tmp16_;
				const gchar* _tmp17_;
				MediaSource* _tmp18_;
				MediaSource* _tmp19_;
				MediaSource* _tmp20_;
				GeeArrayList* _tmp21_;
				MediaSource* _tmp22_;
				GeeArrayList* _tmp23_;
				MediaSource* _tmp24_;
				ThumbnailView* _tmp25_;
				ThumbnailView* _tmp26_;
				_tmp12_ = _source_id_it;
				if (!gee_iterator_next (_tmp12_)) {
					break;
				}
				_tmp13_ = _source_id_it;
				_tmp14_ = gee_iterator_get (_tmp13_);
				source_id = (gchar*) _tmp14_;
				_tmp15_ = media_collection_registry_get_instance ();
				_tmp16_ = _tmp15_;
				_tmp17_ = source_id;
				_tmp18_ = media_collection_registry_fetch_media (_tmp16_, _tmp17_);
				_tmp19_ = G_TYPE_CHECK_INSTANCE_CAST (_tmp18_, TYPE_MEDIA_SOURCE, MediaSource);
				_media_collection_registry_unref0 (_tmp16_);
				current_source = _tmp19_;
				_tmp20_ = current_source;
				if (_tmp20_ == NULL) {
					_g_object_unref0 (current_source);
					_g_free0 (source_id);
					continue;
				}
				_tmp21_ = source_list;
				_tmp22_ = current_source;
				gee_abstract_collection_add ((GeeAbstractCollection*) _tmp21_, _tmp22_);
				_tmp23_ = thumbnail_views;
				_tmp24_ = current_source;
				_tmp25_ = thumbnail_view_new ((ThumbnailSource*) _tmp24_);
				_tmp26_ = _tmp25_;
				gee_abstract_collection_add ((GeeAbstractCollection*) _tmp23_, _tmp26_);
				_g_object_unref0 (_tmp26_);
				_g_object_unref0 (current_source);
				_g_free0 (source_id);
			}
			_g_object_unref0 (_source_id_it);
		}
	} else {
		TagRow* _tmp27_;
		GeeHashSet* _tmp28_;
		_tmp27_ = self->priv->row;
		_tmp28_ = gee_hash_set_new (G_TYPE_STRING, (GBoxedCopyFunc) g_strdup, (GDestroyNotify) g_free, NULL, NULL, NULL, NULL, NULL, NULL);
		_g_object_unref0 (_tmp27_->source_id_list);
		_tmp27_->source_id_list = (GeeSet*) _tmp28_;
	}
	_tmp29_ = row->tag_id;
	_tmp30_ = g_strdup_printf ("%" G_GINT64_FORMAT, _tmp29_.id);
	_tmp31_ = _tmp30_;
	_tmp32_ = g_strdup_printf ("ViewCollection for tag %s", _tmp31_);
	_tmp33_ = _tmp32_;
	_tmp34_ = view_collection_new (_tmp33_);
	_data_collection_unref0 (self->priv->media_views);
	self->priv->media_views = _tmp34_;
	_g_free0 (_tmp33_);
	_g_free0 (_tmp31_);
	_tmp35_ = self->priv->media_views;
	_tmp36_ = thumbnail_views;
	_tmp37_ = data_collection_add_many ((DataCollection*) _tmp35_, (GeeCollection*) _tmp36_, NULL, NULL);
	_tmp38_ = _tmp37_;
	_g_object_unref0 (_tmp38_);
	_tmp39_ = source_list;
	_tmp40_ = gee_abstract_collection_get_size ((GeeAbstractCollection*) _tmp39_);
	_tmp41_ = _tmp40_;
	if (_tmp41_ > 0) {
		TagSourceCollection* _tmp42_;
		GeeArrayList* _tmp43_;
		TagSourceCollection* _tmp44_;
		GeeArrayList* _tmp45_;
		_tmp42_ = tag_global;
		_tmp43_ = source_list;
		container_source_collection_notify_container_contents_added ((ContainerSourceCollection*) _tmp42_, (ContainerSource*) self, (GeeCollection*) _tmp43_, FALSE);
		_tmp44_ = tag_global;
		_tmp45_ = source_list;
		container_source_collection_notify_container_contents_altered ((ContainerSourceCollection*) _tmp44_, (ContainerSource*) self, (GeeCollection*) _tmp45_, FALSE, NULL, FALSE);
	}
	_tmp46_ = self->priv->media_views;
	g_signal_connect_object ((DataCollection*) _tmp46_, "contents-altered", (GCallback) _tag_on_media_views_contents_altered_data_collection_contents_altered, self, 0);
	_tmp47_ = library_photo_global;
	g_signal_connect_object ((SourceCollection*) _tmp47_, "items-destroyed", (GCallback) _tag_on_sources_destroyed_source_collection_items_destroyed, self, 0);
	_tmp48_ = video_global;
	g_signal_connect_object ((SourceCollection*) _tmp48_, "items-destroyed", (GCallback) _tag_on_sources_destroyed_source_collection_items_destroyed, self, 0);
	tag_update_indexable_keywords (self);
	_g_object_unref0 (thumbnail_views);
	_g_object_unref0 (source_list);
	return self;
}

static Tag*
tag_new (TagRow* row,
         gint64 object_id)
{
	return tag_construct (TYPE_TAG, row, object_id);
}

void
tag_init (ProgressMonitor monitor,
          gpointer monitor_target)
{
	TagSourceCollection* _tmp0_;
	GeeList* rows = NULL;
	GeeTreeMap* ancestry_dictionary = NULL;
	GeeTreeMap* _tmp8_;
	GeeArrayList* unlinked = NULL;
	GeeArrayList* _tmp9_;
	gint count = 0;
	GeeList* _tmp10_;
	gint _tmp11_;
	gint _tmp12_;
	GeeSet* victim_set = NULL;
	GeeHashSet* _tmp46_;
	GeeSet* _tmp98_;
	TagSourceCollection* _tmp148_;
	GeeTreeMap* _tmp149_;
	GeeCollection* _tmp150_;
	GeeCollection* _tmp151_;
	GeeCollection* _tmp152_;
	GeeCollection* _tmp153_;
	GeeCollection* _tmp154_;
	TagSourceCollection* _tmp155_;
	GeeArrayList* _tmp156_;
	GError* _inner_error0_ = NULL;
	_tmp0_ = tag_source_collection_new ();
	_data_collection_unref0 (tag_global);
	tag_global = _tmp0_;
	rows = NULL;
	{
		GeeList* _tmp1_ = NULL;
		TagTable* _tmp2_;
		TagTable* _tmp3_;
		GeeList* _tmp4_;
		GeeList* _tmp5_;
		GeeList* _tmp6_;
		_tmp2_ = tag_table_get_instance ();
		_tmp3_ = _tmp2_;
		_tmp4_ = tag_table_get_all_rows (_tmp3_, &_inner_error0_);
		_tmp5_ = _tmp4_;
		_database_table_unref0 (_tmp3_);
		_tmp1_ = _tmp5_;
		if (G_UNLIKELY (_inner_error0_ != NULL)) {
			if (_inner_error0_->domain == DATABASE_ERROR) {
				goto __catch0_database_error;
			}
			_g_object_unref0 (rows);
			g_critical ("file %s: line %d: unexpected 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;
		}
		_tmp6_ = _tmp1_;
		_tmp1_ = NULL;
		_g_object_unref0 (rows);
		rows = _tmp6_;
		_g_object_unref0 (_tmp1_);
	}
	goto __finally0;
	__catch0_database_error:
	{
		GError* err = NULL;
		GError* _tmp7_;
		err = _inner_error0_;
		_inner_error0_ = NULL;
		_tmp7_ = err;
		app_window_database_error (_tmp7_);
		_g_error_free0 (err);
	}
	__finally0:
	if (G_UNLIKELY (_inner_error0_ != NULL)) {
		_g_object_unref0 (rows);
		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_ = gee_tree_map_new (G_TYPE_STRING, (GBoxedCopyFunc) g_strdup, (GDestroyNotify) g_free, TYPE_TAG, (GBoxedCopyFunc) g_object_ref, (GDestroyNotify) g_object_unref, NULL, NULL, NULL, NULL, NULL, NULL);
	ancestry_dictionary = _tmp8_;
	_tmp9_ = gee_array_list_new (TYPE_TAG, (GBoxedCopyFunc) g_object_ref, (GDestroyNotify) g_object_unref, NULL, NULL, NULL);
	unlinked = _tmp9_;
	_tmp10_ = rows;
	_tmp11_ = gee_collection_get_size ((GeeCollection*) _tmp10_);
	_tmp12_ = _tmp11_;
	count = _tmp12_;
	{
		gint ctr = 0;
		ctr = 0;
		{
			gboolean _tmp13_ = FALSE;
			_tmp13_ = TRUE;
			while (TRUE) {
				TagRow* row = NULL;
				GeeList* _tmp15_;
				gpointer _tmp16_;
				gchar* name = NULL;
				TagRow* _tmp17_;
				const gchar* _tmp18_;
				gchar* _tmp19_;
				const gchar* _tmp20_;
				TagRow* _tmp31_;
				const gchar* _tmp32_;
				gchar* _tmp33_;
				Tag* tag = NULL;
				TagRow* _tmp34_;
				Tag* _tmp35_;
				GeeTreeMap* _tmp36_;
				Tag* _tmp37_;
				gchar* _tmp38_;
				gchar* _tmp39_;
				Tag* _tmp40_;
				Tag* _tmp41_;
				if (!_tmp13_) {
					gint _tmp14_;
					_tmp14_ = ctr;
					ctr = _tmp14_ + 1;
				}
				_tmp13_ = FALSE;
				if (!(ctr < count)) {
					break;
				}
				_tmp15_ = rows;
				_tmp16_ = gee_list_get (_tmp15_, ctr);
				row = (TagRow*) _tmp16_;
				_tmp17_ = row;
				_tmp18_ = _tmp17_->name;
				_tmp19_ = tag_prep_tag_name (_tmp18_);
				name = _tmp19_;
				_tmp20_ = name;
				if (_tmp20_ == NULL) {
					TagRow* _tmp21_;
					const gchar* _tmp22_;
					_tmp21_ = row;
					_tmp22_ = _tmp21_->name;
					g_warning ("Tag.vala:428: Invalid tag name \"%s\": removing from database", _tmp22_);
					{
						TagTable* _tmp23_;
						TagTable* _tmp24_;
						TagRow* _tmp25_;
						TagID _tmp26_;
						_tmp23_ = tag_table_get_instance ();
						_tmp24_ = _tmp23_;
						_tmp25_ = row;
						_tmp26_ = _tmp25_->tag_id;
						tag_table_remove (_tmp24_, &_tmp26_, &_inner_error0_);
						_database_table_unref0 (_tmp24_);
						if (G_UNLIKELY (_inner_error0_ != NULL)) {
							if (_inner_error0_->domain == DATABASE_ERROR) {
								goto __catch1_database_error;
							}
							_g_free0 (name);
							_tag_row_unref0 (row);
							_g_object_unref0 (unlinked);
							_g_object_unref0 (ancestry_dictionary);
							_g_object_unref0 (rows);
							g_critical ("file %s: line %d: unexpected 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;
						}
					}
					goto __finally1;
					__catch1_database_error:
					{
						GError* err = NULL;
						TagRow* _tmp27_;
						const gchar* _tmp28_;
						GError* _tmp29_;
						const gchar* _tmp30_;
						err = _inner_error0_;
						_inner_error0_ = NULL;
						_tmp27_ = row;
						_tmp28_ = _tmp27_->name;
						_tmp29_ = err;
						_tmp30_ = _tmp29_->message;
						g_warning ("Tag.vala:432: Unable to delete tag \"%s\": %s", _tmp28_, _tmp30_);
						_g_error_free0 (err);
					}
					__finally1:
					if (G_UNLIKELY (_inner_error0_ != NULL)) {
						_g_free0 (name);
						_tag_row_unref0 (row);
						_g_object_unref0 (unlinked);
						_g_object_unref0 (ancestry_dictionary);
						_g_object_unref0 (rows);
						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 (name);
					_tag_row_unref0 (row);
					continue;
				}
				_tmp31_ = row;
				_tmp32_ = name;
				_tmp33_ = g_strdup (_tmp32_);
				_g_free0 (_tmp31_->name);
				_tmp31_->name = _tmp33_;
				_tmp34_ = row;
				_tmp35_ = tag_new (_tmp34_, DATA_OBJECT_INVALID_OBJECT_ID);
				tag = _tmp35_;
				if (monitor != NULL) {
					monitor ((guint64) ctr, (guint64) count, TRUE, monitor_target);
				}
				_tmp36_ = ancestry_dictionary;
				_tmp37_ = tag;
				_tmp38_ = tag_get_path (_tmp37_);
				_tmp39_ = _tmp38_;
				_tmp40_ = tag;
				gee_abstract_map_set ((GeeAbstractMap*) _tmp36_, _tmp39_, _tmp40_);
				_g_free0 (_tmp39_);
				_tmp41_ = tag;
				if (container_source_has_links ((ContainerSource*) _tmp41_)) {
					Tag* _tmp42_;
					TagSourceCollection* _tmp43_;
					GeeArrayList* _tmp44_;
					Tag* _tmp45_;
					_tmp42_ = tag;
					_tmp43_ = tag_global;
					data_source_rehydrate_backlinks ((DataSource*) _tmp42_, (SourceCollection*) _tmp43_, NULL);
					_tmp44_ = unlinked;
					_tmp45_ = tag;
					gee_abstract_collection_add ((GeeAbstractCollection*) _tmp44_, _tmp45_);
				}
				_g_object_unref0 (tag);
				_g_free0 (name);
				_tag_row_unref0 (row);
			}
		}
	}
	_tmp46_ = gee_hash_set_new (TYPE_TAG, (GBoxedCopyFunc) g_object_ref, (GDestroyNotify) g_object_unref, NULL, NULL, NULL, NULL, NULL, NULL);
	victim_set = (GeeSet*) _tmp46_;
	{
		GeeIterator* _fq_tag_path_it = NULL;
		GeeTreeMap* _tmp47_;
		GeeSet* _tmp48_;
		GeeSet* _tmp49_;
		GeeSet* _tmp50_;
		GeeIterator* _tmp51_;
		GeeIterator* _tmp52_;
		_tmp47_ = ancestry_dictionary;
		_tmp48_ = gee_abstract_map_get_keys ((GeeAbstractMap*) _tmp47_);
		_tmp49_ = _tmp48_;
		_tmp50_ = _tmp49_;
		_tmp51_ = gee_iterable_iterator ((GeeIterable*) _tmp50_);
		_tmp52_ = _tmp51_;
		_g_object_unref0 (_tmp50_);
		_fq_tag_path_it = _tmp52_;
		while (TRUE) {
			GeeIterator* _tmp53_;
			gchar* fq_tag_path = NULL;
			GeeIterator* _tmp54_;
			gpointer _tmp55_;
			const gchar* _tmp56_;
			GeeList* _tmp57_;
			GeeList* _tmp58_;
			gint _tmp59_;
			gint _tmp60_;
			gboolean _tmp61_;
			_tmp53_ = _fq_tag_path_it;
			if (!gee_iterator_next (_tmp53_)) {
				break;
			}
			_tmp54_ = _fq_tag_path_it;
			_tmp55_ = gee_iterator_get (_tmp54_);
			fq_tag_path = (gchar*) _tmp55_;
			_tmp56_ = fq_tag_path;
			_tmp57_ = hierarchical_tag_utilities_enumerate_parent_paths (_tmp56_);
			_tmp58_ = _tmp57_;
			_tmp59_ = gee_collection_get_size ((GeeCollection*) _tmp58_);
			_tmp60_ = _tmp59_;
			_tmp61_ = _tmp60_ < 1;
			_g_object_unref0 (_tmp58_);
			if (_tmp61_) {
				gboolean _tmp62_ = FALSE;
				const gchar* _tmp63_;
				_tmp63_ = fq_tag_path;
				if (g_str_has_prefix (_tmp63_, TAG_PATH_SEPARATOR_STRING)) {
					GeeTreeMap* _tmp64_;
					const gchar* _tmp65_;
					gchar* _tmp66_;
					gchar* _tmp67_;
					_tmp64_ = ancestry_dictionary;
					_tmp65_ = fq_tag_path;
					_tmp66_ = hierarchical_tag_utilities_hierarchical_to_flat (_tmp65_);
					_tmp67_ = _tmp66_;
					_tmp62_ = gee_abstract_map_has_key ((GeeAbstractMap*) _tmp64_, _tmp67_);
					_g_free0 (_tmp67_);
				} else {
					_tmp62_ = FALSE;
				}
				if (_tmp62_) {
					GeeSet* _tmp68_;
					GeeTreeMap* _tmp69_;
					const gchar* _tmp70_;
					gpointer _tmp71_;
					Tag* _tmp72_;
					_tmp68_ = victim_set;
					_tmp69_ = ancestry_dictionary;
					_tmp70_ = fq_tag_path;
					_tmp71_ = gee_abstract_map_get ((GeeAbstractMap*) _tmp69_, _tmp70_);
					_tmp72_ = (Tag*) _tmp71_;
					gee_collection_add ((GeeCollection*) _tmp68_, _tmp72_);
					_g_object_unref0 (_tmp72_);
				}
			}
			_g_free0 (fq_tag_path);
		}
		_g_object_unref0 (_fq_tag_path_it);
	}
	{
		GeeIterator* _tag_it = NULL;
		GeeSet* _tmp73_;
		GeeIterator* _tmp74_;
		_tmp73_ = victim_set;
		_tmp74_ = gee_iterable_iterator ((GeeIterable*) _tmp73_);
		_tag_it = _tmp74_;
		while (TRUE) {
			GeeIterator* _tmp75_;
			Tag* tag = NULL;
			GeeIterator* _tmp76_;
			gpointer _tmp77_;
			GeeCollection* source_collection = NULL;
			Tag* _tmp78_;
			GeeCollection* _tmp79_;
			gchar* flat_version = NULL;
			Tag* _tmp80_;
			gchar* _tmp81_;
			TagSourceCollection* _tmp82_;
			const gchar* _tmp83_;
			Tag* _tmp84_;
			Tag* _tmp85_;
			GeeCollection* _tmp86_;
			GeeTreeMap* _tmp87_;
			Tag* _tmp88_;
			gchar* _tmp89_;
			gchar* _tmp90_;
			Tag* _tmp91_;
			Tag* _tmp92_;
			GeeCollection* _tmp93_;
			GeeCollection* _tmp94_;
			GeeMultiMap* _tmp95_;
			GeeMultiMap* _tmp96_;
			Tag* _tmp97_;
			_tmp75_ = _tag_it;
			if (!gee_iterator_next (_tmp75_)) {
				break;
			}
			_tmp76_ = _tag_it;
			_tmp77_ = gee_iterator_get (_tmp76_);
			tag = (Tag*) _tmp77_;
			_tmp78_ = tag;
			_tmp79_ = tag_get_sources (_tmp78_);
			source_collection = _tmp79_;
			_tmp80_ = tag;
			_tmp81_ = tag_get_user_visible_name (_tmp80_);
			flat_version = _tmp81_;
			_tmp82_ = tag_global;
			_tmp83_ = flat_version;
			_tmp84_ = tag_source_collection_fetch_by_name (_tmp82_, _tmp83_, FALSE);
			_tmp85_ = _tmp84_;
			_tmp86_ = source_collection;
			tag_attach_many (_tmp85_, _tmp86_);
			_g_object_unref0 (_tmp85_);
			_tmp87_ = ancestry_dictionary;
			_tmp88_ = tag;
			_tmp89_ = tag_get_path (_tmp88_);
			_tmp90_ = _tmp89_;
			gee_abstract_map_unset ((GeeAbstractMap*) _tmp87_, _tmp90_, NULL);
			_g_free0 (_tmp90_);
			_tmp91_ = tag;
			_tmp92_ = tag;
			_tmp93_ = tag_get_sources (_tmp92_);
			_tmp94_ = _tmp93_;
			_tmp95_ = tag_detach_many (_tmp91_, _tmp94_);
			_tmp96_ = _tmp95_;
			_g_object_unref0 (_tmp96_);
			_g_object_unref0 (_tmp94_);
			_tmp97_ = tag;
			data_source_destroy_orphan ((DataSource*) _tmp97_, TRUE);
			_g_free0 (flat_version);
			_g_object_unref0 (source_collection);
			_g_object_unref0 (tag);
		}
		_g_object_unref0 (_tag_it);
	}
	_tmp98_ = victim_set;
	gee_collection_clear ((GeeCollection*) _tmp98_);
	{
		GeeIterator* _fq_tag_path_it = NULL;
		GeeTreeMap* _tmp99_;
		GeeSet* _tmp100_;
		GeeSet* _tmp101_;
		GeeSet* _tmp102_;
		GeeIterator* _tmp103_;
		GeeIterator* _tmp104_;
		_tmp99_ = ancestry_dictionary;
		_tmp100_ = gee_abstract_map_get_keys ((GeeAbstractMap*) _tmp99_);
		_tmp101_ = _tmp100_;
		_tmp102_ = _tmp101_;
		_tmp103_ = gee_iterable_iterator ((GeeIterable*) _tmp102_);
		_tmp104_ = _tmp103_;
		_g_object_unref0 (_tmp102_);
		_fq_tag_path_it = _tmp104_;
		while (TRUE) {
			GeeIterator* _tmp105_;
			gchar* fq_tag_path = NULL;
			GeeIterator* _tmp106_;
			gpointer _tmp107_;
			GeeList* parents_to_search = NULL;
			const gchar* _tmp108_;
			GeeList* _tmp109_;
			Tag* curr_child = NULL;
			GeeTreeMap* _tmp110_;
			const gchar* _tmp111_;
			gpointer _tmp112_;
			_tmp105_ = _fq_tag_path_it;
			if (!gee_iterator_next (_tmp105_)) {
				break;
			}
			_tmp106_ = _fq_tag_path_it;
			_tmp107_ = gee_iterator_get (_tmp106_);
			fq_tag_path = (gchar*) _tmp107_;
			_tmp108_ = fq_tag_path;
			_tmp109_ = hierarchical_tag_utilities_enumerate_parent_paths (_tmp108_);
			parents_to_search = _tmp109_;
			_tmp110_ = ancestry_dictionary;
			_tmp111_ = fq_tag_path;
			_tmp112_ = gee_abstract_map_get ((GeeAbstractMap*) _tmp110_, _tmp111_);
			curr_child = (Tag*) _tmp112_;
			{
				GeeList* _parent_path_list = NULL;
				GeeList* _tmp113_;
				gint _parent_path_size = 0;
				GeeList* _tmp114_;
				gint _tmp115_;
				gint _tmp116_;
				gint _parent_path_index = 0;
				_tmp113_ = parents_to_search;
				_parent_path_list = _tmp113_;
				_tmp114_ = _parent_path_list;
				_tmp115_ = gee_collection_get_size ((GeeCollection*) _tmp114_);
				_tmp116_ = _tmp115_;
				_parent_path_size = _tmp116_;
				_parent_path_index = -1;
				while (TRUE) {
					gint _tmp117_;
					gint _tmp118_;
					gchar* parent_path = NULL;
					GeeList* _tmp119_;
					gpointer _tmp120_;
					gint child_ref_count = 0;
					Tag* _tmp121_;
					gint parent_ref_count = 0;
					GeeTreeMap* _tmp122_;
					const gchar* _tmp123_;
					GeeSet* _tmp130_;
					GeeTreeMap* _tmp131_;
					const gchar* _tmp132_;
					gpointer _tmp133_;
					Tag* _tmp134_;
					gboolean _tmp135_;
					_parent_path_index = _parent_path_index + 1;
					_tmp117_ = _parent_path_index;
					_tmp118_ = _parent_path_size;
					if (!(_tmp117_ < _tmp118_)) {
						break;
					}
					_tmp119_ = _parent_path_list;
					_tmp120_ = gee_list_get (_tmp119_, _parent_path_index);
					parent_path = (gchar*) _tmp120_;
					_tmp121_ = curr_child;
					child_ref_count = tag_get_sources_count (_tmp121_);
					parent_ref_count = -1;
					_tmp122_ = ancestry_dictionary;
					_tmp123_ = parent_path;
					if (gee_abstract_map_has_key ((GeeAbstractMap*) _tmp122_, _tmp123_)) {
						GeeTreeMap* _tmp124_;
						const gchar* _tmp125_;
						gpointer _tmp126_;
						Tag* _tmp127_;
						_tmp124_ = ancestry_dictionary;
						_tmp125_ = parent_path;
						_tmp126_ = gee_abstract_map_get ((GeeAbstractMap*) _tmp124_, _tmp125_);
						_tmp127_ = (Tag*) _tmp126_;
						parent_ref_count = tag_get_sources_count (_tmp127_);
						_g_object_unref0 (_tmp127_);
					}
					if (child_ref_count > parent_ref_count) {
						GeeSet* _tmp128_;
						Tag* _tmp129_;
						_tmp128_ = victim_set;
						_tmp129_ = curr_child;
						gee_collection_add ((GeeCollection*) _tmp128_, _tmp129_);
						_g_free0 (parent_path);
						break;
					}
					_tmp130_ = victim_set;
					_tmp131_ = ancestry_dictionary;
					_tmp132_ = parent_path;
					_tmp133_ = gee_abstract_map_get ((GeeAbstractMap*) _tmp131_, _tmp132_);
					_tmp134_ = (Tag*) _tmp133_;
					_tmp135_ = gee_collection_contains ((GeeCollection*) _tmp130_, _tmp134_);
					_g_object_unref0 (_tmp134_);
					if (_tmp135_) {
						GeeSet* _tmp136_;
						Tag* _tmp137_;
						_tmp136_ = victim_set;
						_tmp137_ = curr_child;
						gee_collection_add ((GeeCollection*) _tmp136_, _tmp137_);
						_g_free0 (parent_path);
						break;
					}
					_g_free0 (parent_path);
				}
			}
			_g_object_unref0 (curr_child);
			_g_object_unref0 (parents_to_search);
			_g_free0 (fq_tag_path);
		}
		_g_object_unref0 (_fq_tag_path_it);
	}
	{
		GeeIterator* _t_it = NULL;
		GeeSet* _tmp138_;
		GeeIterator* _tmp139_;
		_tmp138_ = victim_set;
		_tmp139_ = gee_iterable_iterator ((GeeIterable*) _tmp138_);
		_t_it = _tmp139_;
		while (TRUE) {
			GeeIterator* _tmp140_;
			Tag* t = NULL;
			GeeIterator* _tmp141_;
			gpointer _tmp142_;
			GeeTreeMap* _tmp143_;
			Tag* _tmp144_;
			gchar* _tmp145_;
			gchar* _tmp146_;
			Tag* _tmp147_;
			_tmp140_ = _t_it;
			if (!gee_iterator_next (_tmp140_)) {
				break;
			}
			_tmp141_ = _t_it;
			_tmp142_ = gee_iterator_get (_tmp141_);
			t = (Tag*) _tmp142_;
			_tmp143_ = ancestry_dictionary;
			_tmp144_ = t;
			_tmp145_ = tag_get_path (_tmp144_);
			_tmp146_ = _tmp145_;
			gee_abstract_map_unset ((GeeAbstractMap*) _tmp143_, _tmp146_, NULL);
			_g_free0 (_tmp146_);
			_tmp147_ = t;
			data_source_destroy_orphan ((DataSource*) _tmp147_, TRUE);
			_g_object_unref0 (t);
		}
		_g_object_unref0 (_t_it);
	}
	_tmp148_ = tag_global;
	_tmp149_ = ancestry_dictionary;
	_tmp150_ = gee_abstract_map_get_values ((GeeAbstractMap*) _tmp149_);
	_tmp151_ = _tmp150_;
	_tmp152_ = _tmp151_;
	_tmp153_ = data_collection_add_many ((DataCollection*) _tmp148_, _tmp152_, NULL, NULL);
	_tmp154_ = _tmp153_;
	_g_object_unref0 (_tmp154_);
	_g_object_unref0 (_tmp152_);
	_tmp155_ = tag_global;
	_tmp156_ = unlinked;
	container_source_collection_init_add_many_unlinked ((ContainerSourceCollection*) _tmp155_, (GeeCollection*) _tmp156_);
	{
		GeeIterator* _t_it = NULL;
		GeeTreeMap* _tmp157_;
		GeeCollection* _tmp158_;
		GeeCollection* _tmp159_;
		GeeCollection* _tmp160_;
		GeeIterator* _tmp161_;
		GeeIterator* _tmp162_;
		_tmp157_ = ancestry_dictionary;
		_tmp158_ = gee_abstract_map_get_values ((GeeAbstractMap*) _tmp157_);
		_tmp159_ = _tmp158_;
		_tmp160_ = _tmp159_;
		_tmp161_ = gee_iterable_iterator ((GeeIterable*) _tmp160_);
		_tmp162_ = _tmp161_;
		_g_object_unref0 (_tmp160_);
		_t_it = _tmp162_;
		while (TRUE) {
			GeeIterator* _tmp163_;
			Tag* t = NULL;
			GeeIterator* _tmp164_;
			gpointer _tmp165_;
			gboolean _tmp166_ = FALSE;
			Tag* _tmp167_;
			GeeList* _tmp168_;
			GeeList* _tmp169_;
			gint _tmp170_;
			gint _tmp171_;
			gboolean _tmp172_;
			_tmp163_ = _t_it;
			if (!gee_iterator_next (_tmp163_)) {
				break;
			}
			_tmp164_ = _t_it;
			_tmp165_ = gee_iterator_get (_tmp164_);
			t = (Tag*) _tmp165_;
			_tmp167_ = t;
			_tmp168_ = tag_get_hierarchical_children (_tmp167_);
			_tmp169_ = _tmp168_;
			_tmp170_ = gee_collection_get_size ((GeeCollection*) _tmp169_);
			_tmp171_ = _tmp170_;
			_tmp172_ = _tmp171_ < 1;
			_g_object_unref0 (_tmp169_);
			if (_tmp172_) {
				Tag* _tmp173_;
				Tag* _tmp174_;
				Tag* _tmp175_;
				_tmp173_ = t;
				_tmp174_ = tag_get_hierarchical_parent (_tmp173_);
				_tmp175_ = _tmp174_;
				_tmp166_ = _tmp175_ == NULL;
				_g_object_unref0 (_tmp175_);
			} else {
				_tmp166_ = FALSE;
			}
			if (_tmp166_) {
				Tag* _tmp176_;
				_tmp176_ = t;
				tag_flatten (_tmp176_);
			}
			_g_object_unref0 (t);
		}
		_g_object_unref0 (_t_it);
	}
	_g_object_unref0 (victim_set);
	_g_object_unref0 (unlinked);
	_g_object_unref0 (ancestry_dictionary);
	_g_object_unref0 (rows);
}

void
tag_terminate (void)
{
}

gint
tag_compare_names (Tag* a,
                   Tag* b)
{
	gchar* _tmp0_;
	gchar* _tmp1_;
	gchar* _tmp2_;
	gchar* _tmp3_;
	gchar* _tmp4_;
	gchar* _tmp5_;
	gchar* _tmp6_;
	gchar* _tmp7_;
	gint _tmp8_;
	gint result;
	g_return_val_if_fail (a != NULL, -1);
	g_return_val_if_fail (b != NULL, -1);
	_tmp0_ = data_object_get_name ((DataObject*) a);
	_tmp1_ = _tmp0_;
	_tmp2_ = tag_get_name_collation_key (a);
	_tmp3_ = _tmp2_;
	_tmp4_ = data_object_get_name ((DataObject*) b);
	_tmp5_ = _tmp4_;
	_tmp6_ = tag_get_name_collation_key (b);
	_tmp7_ = _tmp6_;
	_tmp8_ = string_precollated_compare (_tmp1_, _tmp3_, _tmp5_, _tmp7_);
	_g_free0 (_tmp7_);
	_g_free0 (_tmp5_);
	_g_free0 (_tmp3_);
	_g_free0 (_tmp1_);
	result = _tmp8_;
	return result;
}

guint
tag_hash_name_string (const gchar* a)
{
	guint result;
	g_return_val_if_fail (a != NULL, 0U);
	result = string_collated_hash (a);
	return result;
}

gboolean
tag_equal_name_strings (const gchar* a,
                        const gchar* b)
{
	gboolean result;
	g_return_val_if_fail (a != NULL, FALSE);
	g_return_val_if_fail (b != NULL, FALSE);
	result = string_collated_equals (a, b);
	return result;
}

Tag*
tag_for_path (const gchar* name)
{
	Tag* tag = NULL;
	TagSourceCollection* _tmp0_;
	Tag* _tmp1_;
	Tag* _tmp2_;
	Tag* _tmp5_;
	TagSourceCollection* _tmp13_;
	Tag* _tmp14_;
	GError* _inner_error0_ = NULL;
	Tag* result;
	g_return_val_if_fail (name != NULL, NULL);
	_tmp0_ = tag_global;
	_tmp1_ = tag_source_collection_fetch_by_name (_tmp0_, name, TRUE);
	tag = _tmp1_;
	_tmp2_ = tag;
	if (_tmp2_ == NULL) {
		TagSourceCollection* _tmp3_;
		Tag* _tmp4_;
		_tmp3_ = tag_global;
		_tmp4_ = tag_source_collection_restore_tag_from_holding_tank (_tmp3_, name);
		_g_object_unref0 (tag);
		tag = _tmp4_;
	}
	_tmp5_ = tag;
	if (_tmp5_ != NULL) {
		result = tag;
		return result;
	}
	{
		TagRow* _tmp6_ = NULL;
		TagTable* _tmp7_;
		TagTable* _tmp8_;
		TagRow* _tmp9_;
		TagRow* _tmp10_;
		Tag* _tmp11_;
		_tmp7_ = tag_table_get_instance ();
		_tmp8_ = _tmp7_;
		_tmp9_ = tag_table_add (_tmp8_, name, &_inner_error0_);
		_tmp10_ = _tmp9_;
		_database_table_unref0 (_tmp8_);
		_tmp6_ = _tmp10_;
		if (G_UNLIKELY (_inner_error0_ != NULL)) {
			if (_inner_error0_->domain == DATABASE_ERROR) {
				goto __catch0_database_error;
			}
			_g_object_unref0 (tag);
			g_critical ("file %s: line %d: unexpected 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;
		}
		_tmp11_ = tag_new (_tmp6_, DATA_OBJECT_INVALID_OBJECT_ID);
		_g_object_unref0 (tag);
		tag = _tmp11_;
		_tag_row_unref0 (_tmp6_);
	}
	goto __finally0;
	__catch0_database_error:
	{
		GError* err = NULL;
		GError* _tmp12_;
		err = _inner_error0_;
		_inner_error0_ = NULL;
		_tmp12_ = err;
		app_window_database_error (_tmp12_);
		_g_error_free0 (err);
	}
	__finally0:
	if (G_UNLIKELY (_inner_error0_ != NULL)) {
		_g_object_unref0 (tag);
		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;
	}
	_tmp13_ = tag_global;
	_tmp14_ = tag;
	data_collection_add ((DataCollection*) _tmp13_, (DataObject*) _tmp14_);
	result = tag;
	return result;
}

GeeCollection*
tag_get_terminal_tags (GeeCollection* tags)
{
	GeeSet* result_paths = NULL;
	GeeHashSet* _tmp0_;
	GeeArrayList* _result_ = NULL;
	GeeArrayList* _tmp34_;
	GeeCollection* result;
	g_return_val_if_fail (tags != NULL, NULL);
	_tmp0_ = gee_hash_set_new (G_TYPE_STRING, (GBoxedCopyFunc) g_strdup, (GDestroyNotify) g_free, NULL, NULL, NULL, NULL, NULL, NULL);
	result_paths = (GeeSet*) _tmp0_;
	{
		GeeIterator* _tag_it = NULL;
		GeeIterator* _tmp1_;
		_tmp1_ = gee_iterable_iterator ((GeeIterable*) tags);
		_tag_it = _tmp1_;
		while (TRUE) {
			GeeIterator* _tmp2_;
			Tag* tag = NULL;
			GeeIterator* _tmp3_;
			gpointer _tmp4_;
			Tag* _tmp5_;
			gchar* _tmp6_;
			gchar* _tmp7_;
			gboolean _tmp8_;
			Tag* _tmp13_;
			Tag* _tmp14_;
			Tag* _tmp15_;
			gboolean _tmp16_;
			GeeSet* _tmp30_;
			Tag* _tmp31_;
			gchar* _tmp32_;
			gchar* _tmp33_;
			_tmp2_ = _tag_it;
			if (!gee_iterator_next (_tmp2_)) {
				break;
			}
			_tmp3_ = _tag_it;
			_tmp4_ = gee_iterator_get (_tmp3_);
			tag = (Tag*) _tmp4_;
			_tmp5_ = tag;
			_tmp6_ = tag_get_path (_tmp5_);
			_tmp7_ = _tmp6_;
			_tmp8_ = !g_str_has_prefix (_tmp7_, TAG_PATH_SEPARATOR_STRING);
			_g_free0 (_tmp7_);
			if (_tmp8_) {
				GeeSet* _tmp9_;
				Tag* _tmp10_;
				gchar* _tmp11_;
				gchar* _tmp12_;
				_tmp9_ = result_paths;
				_tmp10_ = tag;
				_tmp11_ = tag_get_path (_tmp10_);
				_tmp12_ = _tmp11_;
				gee_collection_add ((GeeCollection*) _tmp9_, _tmp12_);
				_g_free0 (_tmp12_);
				_g_object_unref0 (tag);
				continue;
			}
			_tmp13_ = tag;
			_tmp14_ = tag_get_hierarchical_parent (_tmp13_);
			_tmp15_ = _tmp14_;
			_tmp16_ = _tmp15_ != NULL;
			_g_object_unref0 (_tmp15_);
			if (_tmp16_) {
				GeeSet* _tmp17_;
				Tag* _tmp18_;
				Tag* _tmp19_;
				Tag* _tmp20_;
				gchar* _tmp21_;
				gchar* _tmp22_;
				gboolean _tmp23_;
				_tmp17_ = result_paths;
				_tmp18_ = tag;
				_tmp19_ = tag_get_hierarchical_parent (_tmp18_);
				_tmp20_ = _tmp19_;
				_tmp21_ = tag_get_path (_tmp20_);
				_tmp22_ = _tmp21_;
				_tmp23_ = gee_collection_contains ((GeeCollection*) _tmp17_, _tmp22_);
				_g_free0 (_tmp22_);
				_g_object_unref0 (_tmp20_);
				if (_tmp23_) {
					GeeSet* _tmp24_;
					Tag* _tmp25_;
					Tag* _tmp26_;
					Tag* _tmp27_;
					gchar* _tmp28_;
					gchar* _tmp29_;
					_tmp24_ = result_paths;
					_tmp25_ = tag;
					_tmp26_ = tag_get_hierarchical_parent (_tmp25_);
					_tmp27_ = _tmp26_;
					_tmp28_ = tag_get_path (_tmp27_);
					_tmp29_ = _tmp28_;
					gee_collection_remove ((GeeCollection*) _tmp24_, _tmp29_);
					_g_free0 (_tmp29_);
					_g_object_unref0 (_tmp27_);
				}
			}
			_tmp30_ = result_paths;
			_tmp31_ = tag;
			_tmp32_ = tag_get_path (_tmp31_);
			_tmp33_ = _tmp32_;
			gee_collection_add ((GeeCollection*) _tmp30_, _tmp33_);
			_g_free0 (_tmp33_);
			_g_object_unref0 (tag);
		}
		_g_object_unref0 (_tag_it);
	}
	_tmp34_ = gee_array_list_new (TYPE_TAG, (GBoxedCopyFunc) g_object_ref, (GDestroyNotify) g_object_unref, NULL, NULL, NULL);
	_result_ = _tmp34_;
	{
		GeeIterator* _path_it = NULL;
		GeeSet* _tmp35_;
		GeeIterator* _tmp36_;
		_tmp35_ = result_paths;
		_tmp36_ = gee_iterable_iterator ((GeeIterable*) _tmp35_);
		_path_it = _tmp36_;
		while (TRUE) {
			GeeIterator* _tmp37_;
			gchar* path = NULL;
			GeeIterator* _tmp38_;
			gpointer _tmp39_;
			TagSourceCollection* _tmp40_;
			const gchar* _tmp41_;
			_tmp37_ = _path_it;
			if (!gee_iterator_next (_tmp37_)) {
				break;
			}
			_tmp38_ = _path_it;
			_tmp39_ = gee_iterator_get (_tmp38_);
			path = (gchar*) _tmp39_;
			_tmp40_ = tag_global;
			_tmp41_ = path;
			if (tag_source_collection_exists (_tmp40_, _tmp41_, FALSE)) {
				GeeArrayList* _tmp42_;
				const gchar* _tmp43_;
				Tag* _tmp44_;
				Tag* _tmp45_;
				_tmp42_ = _result_;
				_tmp43_ = path;
				_tmp44_ = tag_for_path (_tmp43_);
				_tmp45_ = _tmp44_;
				gee_abstract_collection_add ((GeeAbstractCollection*) _tmp42_, _tmp45_);
				_g_object_unref0 (_tmp45_);
			} else {
				{
					GeeIterator* _probed_tag_it = NULL;
					GeeIterator* _tmp46_;
					_tmp46_ = gee_iterable_iterator ((GeeIterable*) tags);
					_probed_tag_it = _tmp46_;
					while (TRUE) {
						GeeIterator* _tmp47_;
						Tag* probed_tag = NULL;
						GeeIterator* _tmp48_;
						gpointer _tmp49_;
						Tag* _tmp50_;
						gchar* _tmp51_;
						gchar* _tmp52_;
						const gchar* _tmp53_;
						gboolean _tmp54_;
						_tmp47_ = _probed_tag_it;
						if (!gee_iterator_next (_tmp47_)) {
							break;
						}
						_tmp48_ = _probed_tag_it;
						_tmp49_ = gee_iterator_get (_tmp48_);
						probed_tag = (Tag*) _tmp49_;
						_tmp50_ = probed_tag;
						_tmp51_ = tag_get_path (_tmp50_);
						_tmp52_ = _tmp51_;
						_tmp53_ = path;
						_tmp54_ = g_strcmp0 (_tmp52_, _tmp53_) == 0;
						_g_free0 (_tmp52_);
						if (_tmp54_) {
							GeeArrayList* _tmp55_;
							Tag* _tmp56_;
							_tmp55_ = _result_;
							_tmp56_ = probed_tag;
							gee_abstract_collection_add ((GeeAbstractCollection*) _tmp55_, _tmp56_);
						}
						_g_object_unref0 (probed_tag);
					}
					_g_object_unref0 (_probed_tag_it);
				}
			}
			_g_free0 (path);
		}
		_g_object_unref0 (_path_it);
	}
	result = (GeeCollection*) _result_;
	_g_object_unref0 (result_paths);
	return result;
}

static glong
string_strnlen (gchar* str,
                glong maxlen)
{
	gchar* end = NULL;
	gchar* _tmp0_;
	gchar* _tmp1_;
	glong result;
	_tmp0_ = memchr (str, 0, (gsize) maxlen);
	end = _tmp0_;
	_tmp1_ = end;
	if (_tmp1_ == NULL) {
		result = maxlen;
		return result;
	} else {
		gchar* _tmp2_;
		_tmp2_ = end;
		result = (glong) (_tmp2_ - str);
		return result;
	}
}

static gchar*
string_substring (const gchar* self,
                  glong offset,
                  glong len)
{
	glong string_length = 0L;
	gboolean _tmp0_ = FALSE;
	gchar* _tmp3_;
	gchar* result;
	g_return_val_if_fail (self != NULL, NULL);
	if (offset >= ((glong) 0)) {
		_tmp0_ = len >= ((glong) 0);
	} else {
		_tmp0_ = FALSE;
	}
	if (_tmp0_) {
		string_length = string_strnlen ((gchar*) self, offset + len);
	} else {
		gint _tmp1_;
		gint _tmp2_;
		_tmp1_ = strlen (self);
		_tmp2_ = _tmp1_;
		string_length = (glong) _tmp2_;
	}
	if (offset < ((glong) 0)) {
		offset = string_length + offset;
		g_return_val_if_fail (offset >= ((glong) 0), NULL);
	} else {
		g_return_val_if_fail (offset <= string_length, NULL);
	}
	if (len < ((glong) 0)) {
		len = string_length - offset;
	}
	g_return_val_if_fail ((offset + len) <= string_length, NULL);
	_tmp3_ = g_strndup (((gchar*) self) + offset, (gsize) len);
	result = _tmp3_;
	return result;
}

gchar*
tag_make_tag_string (GeeCollection* tags,
                     const gchar* start,
                     const gchar* separator,
                     const gchar* end,
                     gboolean escape)
{
	const gchar* _tmp0_ = NULL;
	GString* builder = NULL;
	GString* _tmp1_;
	GeeHashSet* seen_tags = NULL;
	GeeHashSet* _tmp2_;
	GeeCollection* terminal_tags = NULL;
	GeeCollection* _tmp3_;
	GeeArrayList* sorted_tags = NULL;
	GeeArrayList* _tmp4_;
	GeeArrayList* _tmp22_;
	GeeIterator* iter = NULL;
	GeeArrayList* _tmp23_;
	GeeIterator* _tmp24_;
	gchar* built = NULL;
	GString* _tmp31_;
	const gchar* _tmp32_;
	gchar* _tmp33_;
	const gchar* _tmp34_;
	gint _tmp35_;
	gint _tmp36_;
	gint _tmp37_;
	gint _tmp38_;
	gchar* result;
	g_return_val_if_fail (tags != NULL, NULL);
	g_return_val_if_fail (separator != NULL, NULL);
	_tmp0_ = start;
	if (_tmp0_ == NULL) {
		_tmp0_ = "";
	}
	_tmp1_ = g_string_new (_tmp0_);
	builder = _tmp1_;
	_tmp2_ = gee_hash_set_new (G_TYPE_STRING, (GBoxedCopyFunc) g_strdup, (GDestroyNotify) g_free, NULL, NULL, NULL, NULL, NULL, NULL);
	seen_tags = _tmp2_;
	_tmp3_ = tag_get_terminal_tags (tags);
	terminal_tags = _tmp3_;
	_tmp4_ = gee_array_list_new (G_TYPE_STRING, (GBoxedCopyFunc) g_strdup, (GDestroyNotify) g_free, NULL, NULL, NULL);
	sorted_tags = _tmp4_;
	{
		GeeIterator* _tag_it = NULL;
		GeeCollection* _tmp5_;
		GeeIterator* _tmp6_;
		_tmp5_ = terminal_tags;
		_tmp6_ = gee_iterable_iterator ((GeeIterable*) _tmp5_);
		_tag_it = _tmp6_;
		while (TRUE) {
			GeeIterator* _tmp7_;
			Tag* tag = NULL;
			GeeIterator* _tmp8_;
			gpointer _tmp9_;
			gchar* _tmp10_ = NULL;
			gchar* user_visible_name = NULL;
			gchar* _tmp17_;
			GeeHashSet* _tmp18_;
			const gchar* _tmp19_;
			_tmp7_ = _tag_it;
			if (!gee_iterator_next (_tmp7_)) {
				break;
			}
			_tmp8_ = _tag_it;
			_tmp9_ = gee_iterator_get (_tmp8_);
			tag = (Tag*) _tmp9_;
			if (escape) {
				Tag* _tmp11_;
				gchar* _tmp12_;
				gchar* _tmp13_;
				gchar* _tmp14_;
				_tmp11_ = tag;
				_tmp12_ = tag_get_user_visible_name (_tmp11_);
				_tmp13_ = _tmp12_;
				_tmp14_ = guarded_markup_escape_text (_tmp13_);
				_g_free0 (_tmp10_);
				_tmp10_ = _tmp14_;
				_g_free0 (_tmp13_);
			} else {
				Tag* _tmp15_;
				gchar* _tmp16_;
				_tmp15_ = tag;
				_tmp16_ = tag_get_user_visible_name (_tmp15_);
				_g_free0 (_tmp10_);
				_tmp10_ = _tmp16_;
			}
			_tmp17_ = _tmp10_;
			_tmp10_ = NULL;
			user_visible_name = _tmp17_;
			_tmp18_ = seen_tags;
			_tmp19_ = user_visible_name;
			if (!gee_abstract_collection_contains ((GeeAbstractCollection*) _tmp18_, _tmp19_)) {
				GeeArrayList* _tmp20_;
				const gchar* _tmp21_;
				_tmp20_ = sorted_tags;
				_tmp21_ = user_visible_name;
				gee_abstract_collection_add ((GeeAbstractCollection*) _tmp20_, _tmp21_);
			}
			_g_free0 (user_visible_name);
			_g_free0 (_tmp10_);
			_g_object_unref0 (tag);
		}
		_g_object_unref0 (_tag_it);
	}
	_tmp22_ = sorted_tags;
	gee_list_sort ((GeeList*) _tmp22_, NULL, NULL, NULL);
	_tmp23_ = sorted_tags;
	_tmp24_ = gee_abstract_collection_iterator ((GeeAbstractCollection*) _tmp23_);
	iter = _tmp24_;
	while (TRUE) {
		GeeIterator* _tmp25_;
		GString* _tmp26_;
		GeeIterator* _tmp27_;
		gpointer _tmp28_;
		gchar* _tmp29_;
		GString* _tmp30_;
		_tmp25_ = iter;
		if (!gee_iterator_next (_tmp25_)) {
			break;
		}
		_tmp26_ = builder;
		_tmp27_ = iter;
		_tmp28_ = gee_iterator_get (_tmp27_);
		_tmp29_ = (gchar*) _tmp28_;
		g_string_append (_tmp26_, _tmp29_);
		_g_free0 (_tmp29_);
		_tmp30_ = builder;
		g_string_append (_tmp30_, separator);
	}
	_tmp31_ = builder;
	_tmp32_ = _tmp31_->str;
	_tmp33_ = g_strdup (_tmp32_);
	built = _tmp33_;
	_tmp34_ = built;
	_tmp35_ = strlen (_tmp34_);
	_tmp36_ = _tmp35_;
	_tmp37_ = strlen (separator);
	_tmp38_ = _tmp37_;
	if (_tmp36_ >= _tmp38_) {
		const gchar* _tmp39_;
		const gchar* _tmp40_;
		gint _tmp41_;
		gint _tmp42_;
		gint _tmp43_;
		gint _tmp44_;
		gint _tmp45_;
		gint _tmp46_;
		gchar* _tmp47_;
		gchar* _tmp48_;
		gboolean _tmp49_;
		_tmp39_ = built;
		_tmp40_ = built;
		_tmp41_ = strlen (_tmp40_);
		_tmp42_ = _tmp41_;
		_tmp43_ = strlen (separator);
		_tmp44_ = _tmp43_;
		_tmp45_ = strlen (separator);
		_tmp46_ = _tmp45_;
		_tmp47_ = string_substring (_tmp39_, (glong) (_tmp42_ - _tmp44_), (glong) _tmp46_);
		_tmp48_ = _tmp47_;
		_tmp49_ = g_strcmp0 (_tmp48_, separator) == 0;
		_g_free0 (_tmp48_);
		if (_tmp49_) {
			const gchar* _tmp50_;
			const gchar* _tmp51_;
			gint _tmp52_;
			gint _tmp53_;
			gint _tmp54_;
			gint _tmp55_;
			gchar* _tmp56_;
			_tmp50_ = built;
			_tmp51_ = built;
			_tmp52_ = strlen (_tmp51_);
			_tmp53_ = _tmp52_;
			_tmp54_ = strlen (separator);
			_tmp55_ = _tmp54_;
			_tmp56_ = string_substring (_tmp50_, (glong) 0, (glong) (_tmp53_ - _tmp55_));
			_g_free0 (built);
			built = _tmp56_;
		}
	}
	if (end != NULL) {
		const gchar* _tmp57_;
		gchar* _tmp58_;
		_tmp57_ = built;
		_tmp58_ = g_strconcat (_tmp57_, end, NULL);
		_g_free0 (built);
		built = _tmp58_;
	}
	result = built;
	_g_object_unref0 (iter);
	_g_object_unref0 (sorted_tags);
	_g_object_unref0 (terminal_tags);
	_g_object_unref0 (seen_tags);
	_g_string_free0 (builder);
	return result;
}

gchar*
tag_prep_tag_name (const gchar* name)
{
	gchar* _tmp0_;
	gchar* result;
	g_return_val_if_fail (name != NULL, NULL);
	_tmp0_ = prepare_input_text (name, PREPARE_INPUT_TEXT_OPTIONS_DEFAULT, DEFAULT_USER_TEXT_INPUT_LENGTH);
	result = _tmp0_;
	return result;
}

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

gchar**
tag_prep_tag_names (gchar** names,
                    gint names_length1,
                    gint* result_length1)
{
	gchar** _result_ = NULL;
	gchar** _tmp0_;
	gint _result__length1;
	gint __result__size_;
	gchar** _tmp8_;
	gint _tmp8__length1;
	gchar** result;
	_tmp0_ = g_new0 (gchar*, 0 + 1);
	_result_ = _tmp0_;
	_result__length1 = 0;
	__result__size_ = _result__length1;
	{
		gint ctr = 0;
		ctr = 0;
		{
			gboolean _tmp1_ = FALSE;
			_tmp1_ = TRUE;
			while (TRUE) {
				gchar* new_name = NULL;
				const gchar* _tmp3_;
				gchar* _tmp4_;
				const gchar* _tmp5_;
				if (!_tmp1_) {
					gint _tmp2_;
					_tmp2_ = ctr;
					ctr = _tmp2_ + 1;
				}
				_tmp1_ = FALSE;
				if (!(ctr < names_length1)) {
					break;
				}
				_tmp3_ = names[ctr];
				_tmp4_ = tag_prep_tag_name (_tmp3_);
				new_name = _tmp4_;
				_tmp5_ = new_name;
				if (_tmp5_ != NULL) {
					const gchar* _tmp6_;
					gchar* _tmp7_;
					_tmp6_ = new_name;
					_tmp7_ = g_strdup (_tmp6_);
					_vala_array_add45 (&_result_, &_result__length1, &__result__size_, _tmp7_);
				}
				_g_free0 (new_name);
			}
		}
	}
	_tmp8_ = _result_;
	_tmp8__length1 = _result__length1;
	if (result_length1) {
		*result_length1 = _tmp8__length1;
	}
	result = _tmp8_;
	return result;
}

static void
tag_set_raw_flat_name (Tag* self,
                       const gchar* name)
{
	gchar* prepped_name = NULL;
	gchar* _tmp0_;
	const gchar* _tmp1_;
	const gchar* _tmp2_;
	TagRow* _tmp9_;
	const gchar* _tmp10_;
	gchar* _tmp11_;
	Alteration* _tmp12_;
	Alteration* _tmp13_;
	GError* _inner_error0_ = NULL;
	g_return_if_fail (self != NULL);
	g_return_if_fail (name != NULL);
	_tmp0_ = tag_prep_tag_name (name);
	prepped_name = _tmp0_;
	_tmp1_ = prepped_name;
	_vala_assert (_tmp1_ != NULL, "prepped_name != null");
	_tmp2_ = prepped_name;
	_vala_assert (!g_str_has_prefix (_tmp2_, TAG_PATH_SEPARATOR_STRING), "!prepped_name.has_prefix (Tag.PATH_SEPARATOR_STRING)");
	{
		TagTable* _tmp3_;
		TagTable* _tmp4_;
		TagRow* _tmp5_;
		TagID _tmp6_;
		const gchar* _tmp7_;
		_tmp3_ = tag_table_get_instance ();
		_tmp4_ = _tmp3_;
		_tmp5_ = self->priv->row;
		_tmp6_ = _tmp5_->tag_id;
		_tmp7_ = prepped_name;
		tag_table_rename (_tmp4_, &_tmp6_, _tmp7_, &_inner_error0_);
		_database_table_unref0 (_tmp4_);
		if (G_UNLIKELY (_inner_error0_ != NULL)) {
			if (_inner_error0_->domain == DATABASE_ERROR) {
				goto __catch0_database_error;
			}
			_g_free0 (prepped_name);
			g_critical ("file %s: line %d: unexpected 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;
		}
	}
	goto __finally0;
	__catch0_database_error:
	{
		GError* err = NULL;
		GError* _tmp8_;
		err = _inner_error0_;
		_inner_error0_ = NULL;
		_tmp8_ = err;
		app_window_database_error (_tmp8_);
		_g_error_free0 (err);
		_g_free0 (prepped_name);
		return;
	}
	__finally0:
	if (G_UNLIKELY (_inner_error0_ != NULL)) {
		_g_free0 (prepped_name);
		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;
	}
	_tmp9_ = self->priv->row;
	_tmp10_ = prepped_name;
	_tmp11_ = g_strdup (_tmp10_);
	_g_free0 (_tmp9_->name);
	_tmp9_->name = _tmp11_;
	_g_free0 (self->priv->name_collation_key);
	self->priv->name_collation_key = NULL;
	tag_update_indexable_keywords (self);
	_tmp12_ = alteration_new_from_list ("metadata:name, indexable:keywords");
	_tmp13_ = _tmp12_;
	data_object_notify_altered ((DataObject*) self, _tmp13_);
	_alteration_unref0 (_tmp13_);
	_g_free0 (prepped_name);
}

static void
tag_set_raw_path (Tag* self,
                  const gchar* path,
                  gboolean suppress_notify)
{
	gchar* prepped_path = NULL;
	gchar* _tmp0_;
	const gchar* _tmp1_;
	const gchar* _tmp2_;
	TagSourceCollection* _tmp3_;
	const gchar* _tmp4_;
	TagRow* _tmp11_;
	const gchar* _tmp12_;
	gchar* _tmp13_;
	GError* _inner_error0_ = NULL;
	g_return_if_fail (self != NULL);
	g_return_if_fail (path != NULL);
	_tmp0_ = tag_prep_tag_name (path);
	prepped_path = _tmp0_;
	_tmp1_ = prepped_path;
	_vala_assert (_tmp1_ != NULL, "prepped_path != null");
	_tmp2_ = prepped_path;
	_vala_assert (g_str_has_prefix (_tmp2_, TAG_PATH_SEPARATOR_STRING), "prepped_path.has_prefix (Tag.PATH_SEPARATOR_STRING)");
	_tmp3_ = tag_global;
	_tmp4_ = prepped_path;
	_vala_assert (!tag_source_collection_exists (_tmp3_, _tmp4_, FALSE), "!Tag.global.exists (prepped_path)");
	{
		TagTable* _tmp5_;
		TagTable* _tmp6_;
		TagRow* _tmp7_;
		TagID _tmp8_;
		const gchar* _tmp9_;
		_tmp5_ = tag_table_get_instance ();
		_tmp6_ = _tmp5_;
		_tmp7_ = self->priv->row;
		_tmp8_ = _tmp7_->tag_id;
		_tmp9_ = prepped_path;
		tag_table_rename (_tmp6_, &_tmp8_, _tmp9_, &_inner_error0_);
		_database_table_unref0 (_tmp6_);
		if (G_UNLIKELY (_inner_error0_ != NULL)) {
			if (_inner_error0_->domain == DATABASE_ERROR) {
				goto __catch0_database_error;
			}
			_g_free0 (prepped_path);
			g_critical ("file %s: line %d: unexpected 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;
		}
	}
	goto __finally0;
	__catch0_database_error:
	{
		GError* err = NULL;
		GError* _tmp10_;
		err = _inner_error0_;
		_inner_error0_ = NULL;
		_tmp10_ = err;
		app_window_database_error (_tmp10_);
		_g_error_free0 (err);
		_g_free0 (prepped_path);
		return;
	}
	__finally0:
	if (G_UNLIKELY (_inner_error0_ != NULL)) {
		_g_free0 (prepped_path);
		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;
	}
	_tmp11_ = self->priv->row;
	_tmp12_ = prepped_path;
	_tmp13_ = g_strdup (_tmp12_);
	_g_free0 (_tmp11_->name);
	_tmp11_->name = _tmp13_;
	_g_free0 (self->priv->name_collation_key);
	self->priv->name_collation_key = NULL;
	if (!suppress_notify) {
		Alteration* _tmp14_;
		Alteration* _tmp15_;
		tag_update_indexable_keywords (self);
		_tmp14_ = alteration_new_from_list ("metadata:name, indexable:keywords");
		_tmp15_ = _tmp14_;
		data_object_notify_altered ((DataObject*) self, _tmp15_);
		_alteration_unref0 (_tmp15_);
	}
	_g_free0 (prepped_path);
}

static gchar*
tag_real_get_typename (DataSource* base)
{
	Tag * self;
	gchar* _tmp0_;
	gchar* result;
	self = (Tag*) base;
	_tmp0_ = g_strdup (TAG_TYPENAME);
	result = _tmp0_;
	return result;
}

static gint64
tag_real_get_instance_id (DataSource* base)
{
	Tag * self;
	TagID _tmp0_ = {0};
	gint64 result;
	self = (Tag*) base;
	tag_get_tag_id (self, &_tmp0_);
	result = _tmp0_.id;
	return result;
}

static gchar*
tag_real_get_name (DataObject* base)
{
	Tag * self;
	TagRow* _tmp0_;
	const gchar* _tmp1_;
	gchar* _tmp2_;
	gchar* result;
	self = (Tag*) base;
	_tmp0_ = self->priv->row;
	_tmp1_ = _tmp0_->name;
	_tmp2_ = g_strdup (_tmp1_);
	result = _tmp2_;
	return result;
}

gchar*
tag_get_path (Tag* self)
{
	gchar* _tmp0_;
	gchar* result;
	g_return_val_if_fail (self != NULL, NULL);
	_tmp0_ = data_object_get_name ((DataObject*) self);
	result = _tmp0_;
	return result;
}

gchar*
tag_get_user_visible_name (Tag* self)
{
	gchar* _tmp0_;
	gchar* _tmp1_;
	gchar* _tmp2_;
	gchar* _tmp3_;
	gchar* result;
	g_return_val_if_fail (self != NULL, NULL);
	_tmp0_ = tag_get_path (self);
	_tmp1_ = _tmp0_;
	_tmp2_ = hierarchical_tag_utilities_get_basename (_tmp1_);
	_tmp3_ = _tmp2_;
	_g_free0 (_tmp1_);
	result = _tmp3_;
	return result;
}

gchar*
tag_get_searchable_name (Tag* self)
{
	gchar* istring = NULL;
	gchar* _tmp0_;
	gchar* _tmp1_;
	gchar* _tmp2_;
	gchar* _tmp3_;
	gchar* _tmp4_;
	gchar* _tmp5_;
	gchar* _tmp6_;
	gchar* _tmp7_;
	gchar* _tmp8_;
	gchar* result;
	g_return_val_if_fail (self != NULL, NULL);
	_tmp0_ = tag_get_path (self);
	_tmp1_ = _tmp0_;
	_tmp2_ = hierarchical_tag_utilities_get_basename (_tmp1_);
	_tmp3_ = _tmp2_;
	_tmp4_ = g_utf8_strdown (_tmp3_, (gssize) -1);
	_tmp5_ = _tmp4_;
	_tmp6_ = g_utf8_normalize (_tmp5_, (gssize) -1, G_NORMALIZE_DEFAULT);
	_tmp7_ = _tmp6_;
	_g_free0 (_tmp5_);
	_g_free0 (_tmp3_);
	_g_free0 (_tmp1_);
	istring = _tmp7_;
	_tmp8_ = string_remove_diacritics (istring);
	result = _tmp8_;
	_g_free0 (istring);
	return result;
}

void
tag_flatten (Tag* self)
{
	Tag* _tmp0_;
	Tag* _tmp1_;
	gchar* _tmp2_;
	gchar* _tmp3_;
	g_return_if_fail (self != NULL);
	_tmp0_ = tag_get_hierarchical_parent (self);
	_tmp1_ = _tmp0_;
	_vala_assert (_tmp1_ == NULL, "get_hierarchical_parent () == null");
	_g_object_unref0 (_tmp1_);
	_tmp2_ = tag_get_user_visible_name (self);
	_tmp3_ = _tmp2_;
	tag_set_raw_flat_name (self, _tmp3_);
	_g_free0 (_tmp3_);
}

void
tag_promote (Tag* self)
{
	gchar* _tmp0_;
	gchar* _tmp1_;
	gboolean _tmp2_;
	gchar* _tmp3_;
	gchar* _tmp4_;
	gchar* _tmp5_;
	gchar* _tmp6_;
	g_return_if_fail (self != NULL);
	_tmp0_ = tag_get_path (self);
	_tmp1_ = _tmp0_;
	_tmp2_ = g_str_has_prefix (_tmp1_, TAG_PATH_SEPARATOR_STRING);
	_g_free0 (_tmp1_);
	if (_tmp2_) {
		return;
	}
	_tmp3_ = tag_get_path (self);
	_tmp4_ = _tmp3_;
	_tmp5_ = g_strconcat (TAG_PATH_SEPARATOR_STRING, _tmp4_, NULL);
	_tmp6_ = _tmp5_;
	tag_set_raw_path (self, _tmp6_, FALSE);
	_g_free0 (_tmp6_);
	_g_free0 (_tmp4_);
}

Tag*
tag_get_hierarchical_parent (Tag* self)
{
	gchar* _tmp0_;
	gchar* _tmp1_;
	gboolean _tmp2_;
	GeeList* components = NULL;
	gchar* _tmp3_;
	gchar* _tmp4_;
	GeeList* _tmp5_;
	GeeList* _tmp6_;
	GeeList* _tmp7_;
	gint _tmp8_;
	gint _tmp9_;
	GeeList* _tmp10_;
	gint _tmp11_;
	gint _tmp12_;
	gchar* parent_path = NULL;
	gchar* _tmp13_;
	TagSourceCollection* _tmp26_;
	const gchar* _tmp27_;
	Tag* result;
	g_return_val_if_fail (self != NULL, NULL);
	_tmp0_ = tag_get_path (self);
	_tmp1_ = _tmp0_;
	_tmp2_ = !g_str_has_prefix (_tmp1_, TAG_PATH_SEPARATOR_STRING);
	_g_free0 (_tmp1_);
	if (_tmp2_) {
		result = NULL;
		return result;
	}
	_tmp3_ = tag_get_path (self);
	_tmp4_ = _tmp3_;
	_tmp5_ = hierarchical_tag_utilities_enumerate_path_components (_tmp4_);
	_tmp6_ = _tmp5_;
	_g_free0 (_tmp4_);
	components = _tmp6_;
	_tmp7_ = components;
	_tmp8_ = gee_collection_get_size ((GeeCollection*) _tmp7_);
	_tmp9_ = _tmp8_;
	_vala_assert (_tmp9_ > 0, "components.size > 0");
	_tmp10_ = components;
	_tmp11_ = gee_collection_get_size ((GeeCollection*) _tmp10_);
	_tmp12_ = _tmp11_;
	if (_tmp12_ == 1) {
		result = NULL;
		_g_object_unref0 (components);
		return result;
	}
	_tmp13_ = g_strdup ("");
	parent_path = _tmp13_;
	{
		gint i = 0;
		i = 0;
		{
			gboolean _tmp14_ = FALSE;
			_tmp14_ = TRUE;
			while (TRUE) {
				GeeList* _tmp16_;
				gint _tmp17_;
				gint _tmp18_;
				const gchar* _tmp19_;
				GeeList* _tmp20_;
				gpointer _tmp21_;
				gchar* _tmp22_;
				gchar* _tmp23_;
				gchar* _tmp24_;
				gchar* _tmp25_;
				if (!_tmp14_) {
					gint _tmp15_;
					_tmp15_ = i;
					i = _tmp15_ + 1;
				}
				_tmp14_ = FALSE;
				_tmp16_ = components;
				_tmp17_ = gee_collection_get_size ((GeeCollection*) _tmp16_);
				_tmp18_ = _tmp17_;
				if (!(i < (_tmp18_ - 1))) {
					break;
				}
				_tmp19_ = parent_path;
				_tmp20_ = components;
				_tmp21_ = gee_list_get (_tmp20_, i);
				_tmp22_ = (gchar*) _tmp21_;
				_tmp23_ = g_strconcat (TAG_PATH_SEPARATOR_STRING, _tmp22_, NULL);
				_tmp24_ = _tmp23_;
				_tmp25_ = g_strconcat (_tmp19_, _tmp24_, NULL);
				_g_free0 (parent_path);
				parent_path = _tmp25_;
				_g_free0 (_tmp24_);
				_g_free0 (_tmp22_);
			}
		}
	}
	_tmp26_ = tag_global;
	_tmp27_ = parent_path;
	if (tag_source_collection_exists (_tmp26_, _tmp27_, FALSE)) {
		const gchar* _tmp28_;
		Tag* _tmp29_;
		_tmp28_ = parent_path;
		_tmp29_ = tag_for_path (_tmp28_);
		result = _tmp29_;
		_g_free0 (parent_path);
		_g_object_unref0 (components);
		return result;
	} else {
		result = NULL;
		_g_free0 (parent_path);
		_g_object_unref0 (components);
		return result;
	}
}

gint
tag_get_attachment_count (Tag* self,
                          MediaSource* source)
{
	gint _result_ = 0;
	gint result;
	g_return_val_if_fail (self != NULL, -1);
	g_return_val_if_fail (source != NULL, -1);
	if (!tag_contains (self, source)) {
		result = 0;
		return result;
	}
	_result_ = 1;
	{
		GeeList* _child_list = NULL;
		GeeList* _tmp0_;
		gint _child_size = 0;
		GeeList* _tmp1_;
		gint _tmp2_;
		gint _tmp3_;
		gint _child_index = 0;
		_tmp0_ = tag_get_hierarchical_children (self);
		_child_list = _tmp0_;
		_tmp1_ = _child_list;
		_tmp2_ = gee_collection_get_size ((GeeCollection*) _tmp1_);
		_tmp3_ = _tmp2_;
		_child_size = _tmp3_;
		_child_index = -1;
		while (TRUE) {
			gint _tmp4_;
			gint _tmp5_;
			Tag* child = NULL;
			GeeList* _tmp6_;
			gpointer _tmp7_;
			Tag* _tmp8_;
			_child_index = _child_index + 1;
			_tmp4_ = _child_index;
			_tmp5_ = _child_size;
			if (!(_tmp4_ < _tmp5_)) {
				break;
			}
			_tmp6_ = _child_list;
			_tmp7_ = gee_list_get (_tmp6_, _child_index);
			child = (Tag*) _tmp7_;
			_tmp8_ = child;
			if (tag_contains (_tmp8_, source)) {
				gint _tmp9_;
				_tmp9_ = _result_;
				_result_ = _tmp9_ + 1;
			}
			_g_object_unref0 (child);
		}
		_g_object_unref0 (_child_list);
	}
	result = _result_;
	return result;
}

/**
     * gets all hierarchical children of a tag recursively; tags are enumerated from most-derived
     * to least-derived
     */
GeeList*
tag_get_hierarchical_children (Tag* self)
{
	GeeArrayList* _result_ = NULL;
	GeeArrayList* _tmp0_;
	GeeArrayList* result_reversed = NULL;
	GeeArrayList* _tmp1_;
	gchar* _tmp2_;
	gchar* _tmp3_;
	gboolean _tmp4_;
	GeeTreeSet* forward_sorted_paths = NULL;
	GeeTreeSet* _tmp5_;
	gchar* target_path = NULL;
	gchar* _tmp6_;
	gchar* _tmp7_;
	gchar* _tmp8_;
	gchar* _tmp9_;
	GeeList* result;
	g_return_val_if_fail (self != NULL, NULL);
	_tmp0_ = gee_array_list_new (TYPE_TAG, (GBoxedCopyFunc) g_object_ref, (GDestroyNotify) g_object_unref, NULL, NULL, NULL);
	_result_ = _tmp0_;
	_tmp1_ = gee_array_list_new (TYPE_TAG, (GBoxedCopyFunc) g_object_ref, (GDestroyNotify) g_object_unref, NULL, NULL, NULL);
	result_reversed = _tmp1_;
	_tmp2_ = tag_get_path (self);
	_tmp3_ = _tmp2_;
	_tmp4_ = !g_str_has_prefix (_tmp3_, TAG_PATH_SEPARATOR_STRING);
	_g_free0 (_tmp3_);
	if (_tmp4_) {
		result = (GeeList*) _result_;
		_g_object_unref0 (result_reversed);
		return result;
	}
	_tmp5_ = gee_tree_set_new (G_TYPE_STRING, (GBoxedCopyFunc) g_strdup, (GDestroyNotify) g_free, NULL, NULL, NULL);
	forward_sorted_paths = _tmp5_;
	_tmp6_ = tag_get_path (self);
	_tmp7_ = _tmp6_;
	_tmp8_ = g_strconcat (_tmp7_, TAG_PATH_SEPARATOR_STRING, NULL);
	_tmp9_ = _tmp8_;
	_g_free0 (_tmp7_);
	target_path = _tmp9_;
	{
		GeeIterator* _path_it = NULL;
		TagSourceCollection* _tmp10_;
		GeeCollection* _tmp11_;
		GeeCollection* _tmp12_;
		GeeIterator* _tmp13_;
		GeeIterator* _tmp14_;
		_tmp10_ = tag_global;
		_tmp11_ = tag_source_collection_get_all_names (_tmp10_);
		_tmp12_ = _tmp11_;
		_tmp13_ = gee_iterable_iterator ((GeeIterable*) _tmp12_);
		_tmp14_ = _tmp13_;
		_g_object_unref0 (_tmp12_);
		_path_it = _tmp14_;
		while (TRUE) {
			GeeIterator* _tmp15_;
			gchar* path = NULL;
			GeeIterator* _tmp16_;
			gpointer _tmp17_;
			const gchar* _tmp18_;
			const gchar* _tmp19_;
			_tmp15_ = _path_it;
			if (!gee_iterator_next (_tmp15_)) {
				break;
			}
			_tmp16_ = _path_it;
			_tmp17_ = gee_iterator_get (_tmp16_);
			path = (gchar*) _tmp17_;
			_tmp18_ = path;
			_tmp19_ = target_path;
			if (g_str_has_prefix (_tmp18_, _tmp19_)) {
				GeeTreeSet* _tmp20_;
				const gchar* _tmp21_;
				_tmp20_ = forward_sorted_paths;
				_tmp21_ = path;
				gee_abstract_collection_add ((GeeAbstractCollection*) _tmp20_, _tmp21_);
			}
			_g_free0 (path);
		}
		_g_object_unref0 (_path_it);
	}
	{
		GeeIterator* _tmp_it = NULL;
		GeeTreeSet* _tmp22_;
		GeeIterator* _tmp23_;
		_tmp22_ = forward_sorted_paths;
		_tmp23_ = gee_abstract_collection_iterator ((GeeAbstractCollection*) _tmp22_);
		_tmp_it = _tmp23_;
		while (TRUE) {
			GeeIterator* _tmp24_;
			gchar* tmp = NULL;
			GeeIterator* _tmp25_;
			gpointer _tmp26_;
			GeeArrayList* _tmp27_;
			const gchar* _tmp28_;
			Tag* _tmp29_;
			Tag* _tmp30_;
			_tmp24_ = _tmp_it;
			if (!gee_iterator_next (_tmp24_)) {
				break;
			}
			_tmp25_ = _tmp_it;
			_tmp26_ = gee_iterator_get (_tmp25_);
			tmp = (gchar*) _tmp26_;
			_tmp27_ = result_reversed;
			_tmp28_ = tmp;
			_tmp29_ = tag_for_path (_tmp28_);
			_tmp30_ = _tmp29_;
			gee_abstract_collection_add ((GeeAbstractCollection*) _tmp27_, _tmp30_);
			_g_object_unref0 (_tmp30_);
			_g_free0 (tmp);
		}
		_g_object_unref0 (_tmp_it);
	}
	{
		gint index = 0;
		GeeArrayList* _tmp31_;
		gint _tmp32_;
		gint _tmp33_;
		_tmp31_ = result_reversed;
		_tmp32_ = gee_abstract_collection_get_size ((GeeAbstractCollection*) _tmp31_);
		_tmp33_ = _tmp32_;
		index = _tmp33_ - 1;
		{
			gboolean _tmp34_ = FALSE;
			_tmp34_ = TRUE;
			while (TRUE) {
				GeeArrayList* _tmp36_;
				GeeArrayList* _tmp37_;
				gpointer _tmp38_;
				Tag* _tmp39_;
				if (!_tmp34_) {
					gint _tmp35_;
					_tmp35_ = index;
					index = _tmp35_ - 1;
				}
				_tmp34_ = FALSE;
				if (!(index >= 0)) {
					break;
				}
				_tmp36_ = _result_;
				_tmp37_ = result_reversed;
				_tmp38_ = gee_abstract_list_get ((GeeAbstractList*) _tmp37_, index);
				_tmp39_ = (Tag*) _tmp38_;
				gee_abstract_collection_add ((GeeAbstractCollection*) _tmp36_, _tmp39_);
				_g_object_unref0 (_tmp39_);
			}
		}
	}
	result = (GeeList*) _result_;
	_g_free0 (target_path);
	_g_object_unref0 (forward_sorted_paths);
	_g_object_unref0 (result_reversed);
	return result;
}

static gchar*
tag_get_next_untitled_tag_name (const gchar* _prefix)
{
	const gchar* _tmp0_ = NULL;
	gchar* prefix = NULL;
	gchar* _tmp1_;
	gchar* candidate_name = NULL;
	gchar* _tmp2_;
	guint64 counter = 0ULL;
	gchar* result;
	if (_prefix != NULL) {
		_tmp0_ = _prefix;
	} else {
		_tmp0_ = "";
	}
	_tmp1_ = g_strdup (_tmp0_);
	prefix = _tmp1_;
	_tmp2_ = g_strdup (_ ("untitled"));
	candidate_name = _tmp2_;
	counter = (guint64) 0;
	{
		gboolean _tmp3_ = FALSE;
		_tmp3_ = TRUE;
		while (TRUE) {
			gchar* _tmp4_ = NULL;
			gchar* path_candidate = NULL;
			const gchar* _tmp9_;
			const gchar* _tmp10_;
			gchar* _tmp11_;
			gchar* _tmp12_;
			gchar* _tmp13_;
			gchar* _tmp14_;
			TagSourceCollection* _tmp15_;
			const gchar* _tmp16_;
			guint64 _tmp17_;
			if (!_tmp3_) {
				if (!(counter < G_MAXUINT64)) {
					break;
				}
			}
			_tmp3_ = FALSE;
			if (counter == ((guint64) 0)) {
				gchar* _tmp5_;
				_tmp5_ = g_strdup ("");
				_g_free0 (_tmp4_);
				_tmp4_ = _tmp5_;
			} else {
				gchar* _tmp6_;
				gchar* _tmp7_;
				gchar* _tmp8_;
				_tmp6_ = g_strdup_printf ("%" G_GUINT64_FORMAT, counter);
				_tmp7_ = _tmp6_;
				_tmp8_ = g_strconcat (" ", _tmp7_, NULL);
				_g_free0 (_tmp4_);
				_tmp4_ = _tmp8_;
				_g_free0 (_tmp7_);
			}
			_tmp9_ = prefix;
			_tmp10_ = candidate_name;
			_tmp11_ = g_strconcat (_tmp9_, _tmp10_, NULL);
			_tmp12_ = _tmp11_;
			_tmp13_ = g_strconcat (_tmp12_, _tmp4_, NULL);
			_tmp14_ = _tmp13_;
			_g_free0 (_tmp12_);
			path_candidate = _tmp14_;
			_tmp15_ = tag_global;
			_tmp16_ = path_candidate;
			if (!tag_source_collection_exists (_tmp15_, _tmp16_, FALSE)) {
				result = path_candidate;
				_g_free0 (_tmp4_);
				_g_free0 (candidate_name);
				_g_free0 (prefix);
				return result;
			}
			_tmp17_ = counter;
			counter = _tmp17_ + 1;
			_g_free0 (path_candidate);
			_g_free0 (_tmp4_);
		}
	}
	g_assert_not_reached ();
}

Tag*
tag_create_new_child (Tag* self)
{
	gchar* path_prefix = NULL;
	gchar* _tmp0_;
	const gchar* _tmp1_;
	const gchar* _tmp7_;
	gchar* _tmp8_;
	gchar* _tmp9_;
	gchar* _tmp10_;
	gchar* _tmp11_;
	Tag* _tmp12_;
	Tag* _tmp13_;
	Tag* result;
	g_return_val_if_fail (self != NULL, NULL);
	_tmp0_ = tag_get_path (self);
	path_prefix = _tmp0_;
	_tmp1_ = path_prefix;
	if (!g_str_has_prefix (_tmp1_, TAG_PATH_SEPARATOR_STRING)) {
		gchar* _tmp2_;
		gchar* _tmp3_;
		gchar* _tmp4_;
		gchar* _tmp5_;
		gchar* _tmp6_;
		_tmp2_ = tag_get_path (self);
		_tmp3_ = _tmp2_;
		_tmp4_ = hierarchical_tag_utilities_flat_to_hierarchical (_tmp3_);
		_tmp5_ = _tmp4_;
		tag_set_raw_path (self, _tmp5_, FALSE);
		_g_free0 (_tmp5_);
		_g_free0 (_tmp3_);
		_tmp6_ = tag_get_path (self);
		_g_free0 (path_prefix);
		path_prefix = _tmp6_;
	}
	_tmp7_ = path_prefix;
	_tmp8_ = g_strconcat (_tmp7_, TAG_PATH_SEPARATOR_STRING, NULL);
	_tmp9_ = _tmp8_;
	_tmp10_ = tag_get_next_untitled_tag_name (_tmp9_);
	_tmp11_ = _tmp10_;
	_tmp12_ = tag_for_path (_tmp11_);
	_tmp13_ = _tmp12_;
	_g_free0 (_tmp11_);
	_g_free0 (_tmp9_);
	result = _tmp13_;
	_g_free0 (path_prefix);
	return result;
}

Tag*
tag_create_new_root (void)
{
	gchar* _tmp0_;
	gchar* _tmp1_;
	Tag* _tmp2_;
	Tag* _tmp3_;
	Tag* result;
	_tmp0_ = tag_get_next_untitled_tag_name (NULL);
	_tmp1_ = _tmp0_;
	_tmp2_ = tag_for_path (_tmp1_);
	_tmp3_ = _tmp2_;
	_g_free0 (_tmp1_);
	result = _tmp3_;
	return result;
}

gchar*
tag_get_name_collation_key (Tag* self)
{
	const gchar* _tmp0_;
	const gchar* _tmp4_;
	gchar* _tmp5_;
	gchar* result;
	g_return_val_if_fail (self != NULL, NULL);
	_tmp0_ = self->priv->name_collation_key;
	if (_tmp0_ == NULL) {
		TagRow* _tmp1_;
		const gchar* _tmp2_;
		gchar* _tmp3_;
		_tmp1_ = self->priv->row;
		_tmp2_ = _tmp1_->name;
		_tmp3_ = g_utf8_collate_key (_tmp2_, (gssize) -1);
		_g_free0 (self->priv->name_collation_key);
		self->priv->name_collation_key = _tmp3_;
	}
	_tmp4_ = self->priv->name_collation_key;
	_tmp5_ = g_strdup (_tmp4_);
	result = _tmp5_;
	return result;
}

static gchar*
tag_real_to_string (DataObject* base)
{
	Tag * self;
	TagRow* _tmp0_;
	const gchar* _tmp1_;
	ViewCollection* _tmp2_;
	gchar* _tmp3_;
	gchar* result;
	self = (Tag*) base;
	_tmp0_ = self->priv->row;
	_tmp1_ = _tmp0_->name;
	_tmp2_ = self->priv->media_views;
	_tmp3_ = g_strdup_printf ("Tag %s (%d sources)", _tmp1_, data_collection_get_count ((DataCollection*) _tmp2_));
	result = _tmp3_;
	return result;
}

static gboolean
tag_real_equals (DataSource* base,
                 DataSource* source)
{
	Tag * self;
	Tag* tag = NULL;
	Tag* _tmp0_;
	Tag* _tmp1_;
	gboolean result;
	self = (Tag*) base;
	_tmp0_ = _g_object_ref0 (IS_TAG (source) ? ((Tag*) source) : NULL);
	tag = _tmp0_;
	_tmp1_ = tag;
	if (_tmp1_ != NULL) {
		Tag* _tmp2_;
		_tmp2_ = tag;
		if (_tmp2_ != self) {
			Tag* _tmp3_;
			TagRow* _tmp4_;
			TagID _tmp5_;
			TagRow* _tmp6_;
			TagID _tmp7_;
			_tmp3_ = tag;
			_tmp4_ = _tmp3_->priv->row;
			_tmp5_ = _tmp4_->tag_id;
			_tmp6_ = self->priv->row;
			_tmp7_ = _tmp6_->tag_id;
			_vala_assert (_tmp5_.id != _tmp7_.id, "tag.row.tag_id.id != row.tag_id.id");
		}
	}
	result = DATA_SOURCE_CLASS (tag_parent_class)->equals (G_TYPE_CHECK_INSTANCE_CAST (self, TYPE_DATA_SOURCE, DataSource), source);
	_g_object_unref0 (tag);
	return result;
}

void
tag_get_tag_id (Tag* self,
                TagID* result)
{
	TagRow* _tmp0_;
	TagID _tmp1_;
	g_return_if_fail (self != NULL);
	_tmp0_ = self->priv->row;
	_tmp1_ = _tmp0_->tag_id;
	*result = _tmp1_;
	return;
}

static SourceSnapshot*
tag_real_save_snapshot (DataSource* base)
{
	Tag * self;
	TagTagSnapshot* _tmp0_;
	SourceSnapshot* result;
	self = (Tag*) base;
	_tmp0_ = tag_tag_snapshot_new (self);
	result = (SourceSnapshot*) _tmp0_;
	return result;
}

static SourceProxy*
tag_real_get_proxy (Proxyable* base)
{
	Tag * self;
	TagTagProxy* _tmp0_;
	SourceProxy* result;
	self = (Tag*) base;
	_tmp0_ = tag_tag_proxy_new (self);
	result = (SourceProxy*) _tmp0_;
	return result;
}

Tag*
tag_reconstitute (gint64 object_id,
                  TagRow* row)
{
	Tag* tag = NULL;
	Tag* _tmp6_;
	TagSourceCollection* _tmp7_;
	gchar* _tmp8_;
	gchar* _tmp9_;
	GError* _inner_error0_ = NULL;
	Tag* result;
	g_return_val_if_fail (row != NULL, NULL);
	{
		TagID _tmp0_ = {0};
		TagTable* _tmp1_;
		TagTable* _tmp2_;
		TagID _tmp3_ = {0};
		TagID _tmp4_;
		_tmp1_ = tag_table_get_instance ();
		_tmp2_ = _tmp1_;
		tag_table_create_from_row (_tmp2_, row, &_tmp3_, &_inner_error0_);
		_tmp4_ = _tmp3_;
		_database_table_unref0 (_tmp2_);
		_tmp0_ = _tmp4_;
		if (G_UNLIKELY (_inner_error0_ != NULL)) {
			if (_inner_error0_->domain == DATABASE_ERROR) {
				goto __catch0_database_error;
			}
			g_critical ("file %s: line %d: unexpected 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;
		}
		row->tag_id = _tmp0_;
	}
	goto __finally0;
	__catch0_database_error:
	{
		GError* err = NULL;
		GError* _tmp5_;
		err = _inner_error0_;
		_inner_error0_ = NULL;
		_tmp5_ = err;
		app_window_database_error (_tmp5_);
		_g_error_free0 (err);
	}
	__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;
	}
	_tmp6_ = tag_new (row, object_id);
	tag = _tmp6_;
	_tmp7_ = tag_global;
	data_collection_add ((DataCollection*) _tmp7_, (DataObject*) tag);
	_tmp8_ = data_object_to_string ((DataObject*) tag);
	_tmp9_ = _tmp8_;
	g_debug ("Tag.vala:908: Reconstituted %s", _tmp9_);
	_g_free0 (_tmp9_);
	result = tag;
	return result;
}

static gboolean
tag_real_has_links (ContainerSource* base)
{
	Tag * self;
	LibraryPhotoSourceCollection* _tmp0_;
	SourceBacklink* _tmp1_;
	SourceBacklink* _tmp2_;
	gboolean _tmp3_;
	gboolean result;
	self = (Tag*) base;
	_tmp0_ = library_photo_global;
	_tmp1_ = container_source_get_backlink ((ContainerSource*) self);
	_tmp2_ = _tmp1_;
	_tmp3_ = source_collection_has_backlink ((SourceCollection*) _tmp0_, _tmp2_);
	_source_backlink_unref0 (_tmp2_);
	result = _tmp3_;
	return result;
}

static SourceBacklink*
tag_real_get_backlink (ContainerSource* base)
{
	Tag * self;
	SourceBacklink* _tmp0_;
	SourceBacklink* result;
	self = (Tag*) base;
	_tmp0_ = source_backlink_new_from_source ((DataSource*) self);
	result = _tmp0_;
	return result;
}

static void
tag_real_break_link (ContainerSource* base,
                     DataSource* source)
{
	Tag * self;
	GeeList* _tmp0_;
	GeeList* _tmp1_;
	self = (Tag*) base;
	g_return_if_fail (source != NULL);
	self->priv->unlinking = TRUE;
	_tmp0_ = tag_detach (self, (MediaSource*) G_TYPE_CHECK_INSTANCE_CAST (source, TYPE_LIBRARY_PHOTO, LibraryPhoto));
	_tmp1_ = _tmp0_;
	_g_object_unref0 (_tmp1_);
	self->priv->unlinking = FALSE;
}

static void
tag_real_break_link_many (ContainerSource* base,
                          GeeCollection* sources)
{
	Tag * self;
	GeeMultiMap* _tmp0_;
	GeeMultiMap* _tmp1_;
	self = (Tag*) base;
	g_return_if_fail (sources != NULL);
	self->priv->unlinking = TRUE;
	_tmp0_ = tag_detach_many (self, G_TYPE_CHECK_INSTANCE_CAST (sources, GEE_TYPE_COLLECTION, GeeCollection));
	_tmp1_ = _tmp0_;
	_g_object_unref0 (_tmp1_);
	self->priv->unlinking = FALSE;
}

static void
tag_real_establish_link (ContainerSource* base,
                         DataSource* source)
{
	Tag * self;
	self = (Tag*) base;
	g_return_if_fail (source != NULL);
	self->priv->relinking = TRUE;
	tag_attach (self, (MediaSource*) G_TYPE_CHECK_INSTANCE_CAST (source, TYPE_LIBRARY_PHOTO, LibraryPhoto));
	self->priv->relinking = FALSE;
}

static void
tag_real_establish_link_many (ContainerSource* base,
                              GeeCollection* sources)
{
	Tag * self;
	self = (Tag*) base;
	g_return_if_fail (sources != NULL);
	self->priv->relinking = TRUE;
	tag_attach_many (self, G_TYPE_CHECK_INSTANCE_CAST (sources, GEE_TYPE_COLLECTION, GeeCollection));
	self->priv->relinking = FALSE;
}

static void
tag_update_indexable_keywords (Tag* self)
{
	gchar* _tmp0_;
	gchar* _tmp1_;
	gchar* _tmp2_;
	g_return_if_fail (self != NULL);
	_tmp0_ = tag_get_searchable_name (self);
	_tmp1_ = _tmp0_;
	_tmp2_ = indexable_prepare_indexable_string (_tmp1_);
	_g_free0 (self->priv->indexable_keywords);
	self->priv->indexable_keywords = _tmp2_;
	_g_free0 (_tmp1_);
}

static const gchar*
tag_real_get_indexable_keywords (Indexable* base)
{
	Tag * self;
	const gchar* _tmp0_;
	const gchar* result;
	self = (Tag*) base;
	_tmp0_ = self->priv->indexable_keywords;
	result = _tmp0_;
	return result;
}

void
tag_attach (Tag* self,
            MediaSource* source)
{
	Tag* attach_to = NULL;
	Tag* _tmp0_;
	g_return_if_fail (self != NULL);
	g_return_if_fail (source != NULL);
	_tmp0_ = _g_object_ref0 (self);
	attach_to = _tmp0_;
	while (TRUE) {
		Tag* _tmp1_;
		Tag* _tmp2_;
		ViewCollection* _tmp3_;
		Tag* _tmp8_;
		Tag* _tmp9_;
		_tmp1_ = attach_to;
		if (!(_tmp1_ != NULL)) {
			break;
		}
		_tmp2_ = attach_to;
		_tmp3_ = _tmp2_->priv->media_views;
		if (!view_collection_has_view_for_source (_tmp3_, (DataSource*) source)) {
			Tag* _tmp4_;
			ViewCollection* _tmp5_;
			ThumbnailView* _tmp6_;
			ThumbnailView* _tmp7_;
			_tmp4_ = attach_to;
			_tmp5_ = _tmp4_->priv->media_views;
			_tmp6_ = thumbnail_view_new ((ThumbnailSource*) source);
			_tmp7_ = _tmp6_;
			data_collection_add ((DataCollection*) _tmp5_, (DataObject*) _tmp7_);
			_g_object_unref0 (_tmp7_);
		}
		_tmp8_ = attach_to;
		_tmp9_ = tag_get_hierarchical_parent (_tmp8_);
		_g_object_unref0 (attach_to);
		attach_to = _tmp9_;
	}
	_g_object_unref0 (attach_to);
}

void
tag_attach_many (Tag* self,
                 GeeCollection* sources)
{
	Tag* attach_to = NULL;
	Tag* _tmp0_;
	g_return_if_fail (self != NULL);
	g_return_if_fail (sources != NULL);
	_tmp0_ = _g_object_ref0 (self);
	attach_to = _tmp0_;
	while (TRUE) {
		Tag* _tmp1_;
		GeeArrayList* view_list = NULL;
		GeeArrayList* _tmp2_;
		GeeArrayList* _tmp14_;
		gint _tmp15_;
		gint _tmp16_;
		Tag* _tmp22_;
		Tag* _tmp23_;
		_tmp1_ = attach_to;
		if (!(_tmp1_ != NULL)) {
			break;
		}
		_tmp2_ = gee_array_list_new (TYPE_THUMBNAIL_VIEW, (GBoxedCopyFunc) g_object_ref, (GDestroyNotify) g_object_unref, NULL, NULL, NULL);
		view_list = _tmp2_;
		{
			GeeIterator* _source_it = NULL;
			GeeIterator* _tmp3_;
			_tmp3_ = gee_iterable_iterator ((GeeIterable*) sources);
			_source_it = _tmp3_;
			while (TRUE) {
				GeeIterator* _tmp4_;
				MediaSource* source = NULL;
				GeeIterator* _tmp5_;
				gpointer _tmp6_;
				Tag* _tmp7_;
				ViewCollection* _tmp8_;
				MediaSource* _tmp9_;
				_tmp4_ = _source_it;
				if (!gee_iterator_next (_tmp4_)) {
					break;
				}
				_tmp5_ = _source_it;
				_tmp6_ = gee_iterator_get (_tmp5_);
				source = (MediaSource*) _tmp6_;
				_tmp7_ = attach_to;
				_tmp8_ = _tmp7_->priv->media_views;
				_tmp9_ = source;
				if (!view_collection_has_view_for_source (_tmp8_, (DataSource*) _tmp9_)) {
					GeeArrayList* _tmp10_;
					MediaSource* _tmp11_;
					ThumbnailView* _tmp12_;
					ThumbnailView* _tmp13_;
					_tmp10_ = view_list;
					_tmp11_ = source;
					_tmp12_ = thumbnail_view_new ((ThumbnailSource*) _tmp11_);
					_tmp13_ = _tmp12_;
					gee_abstract_collection_add ((GeeAbstractCollection*) _tmp10_, _tmp13_);
					_g_object_unref0 (_tmp13_);
				}
				_g_object_unref0 (source);
			}
			_g_object_unref0 (_source_it);
		}
		_tmp14_ = view_list;
		_tmp15_ = gee_abstract_collection_get_size ((GeeAbstractCollection*) _tmp14_);
		_tmp16_ = _tmp15_;
		if (_tmp16_ > 0) {
			Tag* _tmp17_;
			ViewCollection* _tmp18_;
			GeeArrayList* _tmp19_;
			GeeCollection* _tmp20_;
			GeeCollection* _tmp21_;
			_tmp17_ = attach_to;
			_tmp18_ = _tmp17_->priv->media_views;
			_tmp19_ = view_list;
			_tmp20_ = data_collection_add_many ((DataCollection*) _tmp18_, (GeeCollection*) _tmp19_, NULL, NULL);
			_tmp21_ = _tmp20_;
			_g_object_unref0 (_tmp21_);
		}
		_tmp22_ = attach_to;
		_tmp23_ = tag_get_hierarchical_parent (_tmp22_);
		_g_object_unref0 (attach_to);
		attach_to = _tmp23_;
		_g_object_unref0 (view_list);
	}
	_g_object_unref0 (attach_to);
}

GeeList*
tag_detach (Tag* self,
            MediaSource* source)
{
	DataView* this_view = NULL;
	ViewCollection* _tmp0_;
	DataView* _tmp1_;
	DataView* _tmp2_;
	GeeList* detached_from = NULL;
	GeeArrayList* _tmp3_;
	ViewCollection* _tmp25_;
	ViewCollection* _tmp26_;
	DataView* _tmp27_;
	Marker* _tmp28_;
	Marker* _tmp29_;
	GeeList* _tmp30_;
	GeeList* result;
	g_return_val_if_fail (self != NULL, NULL);
	g_return_val_if_fail (source != NULL, NULL);
	_tmp0_ = self->priv->media_views;
	_tmp1_ = view_collection_get_view_for_source (_tmp0_, (DataSource*) source);
	this_view = _tmp1_;
	_tmp2_ = this_view;
	if (_tmp2_ == NULL) {
		result = NULL;
		_g_object_unref0 (this_view);
		return result;
	}
	_tmp3_ = gee_array_list_new (TYPE_TAG, (GBoxedCopyFunc) g_object_ref, (GDestroyNotify) g_object_unref, NULL, NULL, NULL);
	detached_from = (GeeList*) _tmp3_;
	{
		GeeList* _child_tag_list = NULL;
		GeeList* _tmp4_;
		gint _child_tag_size = 0;
		GeeList* _tmp5_;
		gint _tmp6_;
		gint _tmp7_;
		gint _child_tag_index = 0;
		_tmp4_ = tag_get_hierarchical_children (self);
		_child_tag_list = _tmp4_;
		_tmp5_ = _child_tag_list;
		_tmp6_ = gee_collection_get_size ((GeeCollection*) _tmp5_);
		_tmp7_ = _tmp6_;
		_child_tag_size = _tmp7_;
		_child_tag_index = -1;
		while (TRUE) {
			gint _tmp8_;
			gint _tmp9_;
			Tag* child_tag = NULL;
			GeeList* _tmp10_;
			gpointer _tmp11_;
			DataView* child_view = NULL;
			Tag* _tmp12_;
			ViewCollection* _tmp13_;
			DataView* _tmp14_;
			DataView* _tmp15_;
			_child_tag_index = _child_tag_index + 1;
			_tmp8_ = _child_tag_index;
			_tmp9_ = _child_tag_size;
			if (!(_tmp8_ < _tmp9_)) {
				break;
			}
			_tmp10_ = _child_tag_list;
			_tmp11_ = gee_list_get (_tmp10_, _child_tag_index);
			child_tag = (Tag*) _tmp11_;
			_tmp12_ = child_tag;
			_tmp13_ = _tmp12_->priv->media_views;
			_tmp14_ = view_collection_get_view_for_source (_tmp13_, (DataSource*) source);
			child_view = _tmp14_;
			_tmp15_ = child_view;
			if (_tmp15_ != NULL) {
				Tag* _tmp16_;
				ViewCollection* _tmp17_;
				Tag* _tmp18_;
				ViewCollection* _tmp19_;
				DataView* _tmp20_;
				Marker* _tmp21_;
				Marker* _tmp22_;
				GeeList* _tmp23_;
				Tag* _tmp24_;
				_tmp16_ = child_tag;
				_tmp17_ = _tmp16_->priv->media_views;
				_tmp18_ = child_tag;
				_tmp19_ = _tmp18_->priv->media_views;
				_tmp20_ = child_view;
				_tmp21_ = data_collection_mark ((DataCollection*) _tmp19_, (DataObject*) _tmp20_);
				_tmp22_ = _tmp21_;
				data_collection_remove_marked ((DataCollection*) _tmp17_, _tmp22_);
				_g_object_unref0 (_tmp22_);
				_tmp23_ = detached_from;
				_tmp24_ = child_tag;
				gee_collection_add ((GeeCollection*) _tmp23_, _tmp24_);
			}
			_g_object_unref0 (child_view);
			_g_object_unref0 (child_tag);
		}
		_g_object_unref0 (_child_tag_list);
	}
	_tmp25_ = self->priv->media_views;
	_tmp26_ = self->priv->media_views;
	_tmp27_ = this_view;
	_tmp28_ = data_collection_mark ((DataCollection*) _tmp26_, (DataObject*) _tmp27_);
	_tmp29_ = _tmp28_;
	data_collection_remove_marked ((DataCollection*) _tmp25_, _tmp29_);
	_g_object_unref0 (_tmp29_);
	_tmp30_ = detached_from;
	gee_collection_add ((GeeCollection*) _tmp30_, self);
	result = detached_from;
	_g_object_unref0 (this_view);
	return result;
}

GeeMultiMap*
tag_detach_many (Tag* self,
                 GeeCollection* sources)
{
	GeeMultiMap* detached_from = NULL;
	GeeHashMultiMap* _tmp0_;
	Marker* marker = NULL;
	ViewCollection* _tmp1_;
	Marker* _tmp2_;
	ViewCollection* _tmp38_;
	Marker* _tmp39_;
	GeeMultiMap* _tmp40_ = NULL;
	GeeMultiMap* _tmp41_;
	gint _tmp42_;
	gint _tmp43_;
	GeeMultiMap* _tmp45_;
	GeeMultiMap* result;
	g_return_val_if_fail (self != NULL, NULL);
	g_return_val_if_fail (sources != NULL, NULL);
	_tmp0_ = gee_hash_multi_map_new (TYPE_TAG, (GBoxedCopyFunc) g_object_ref, (GDestroyNotify) g_object_unref, TYPE_MEDIA_SOURCE, (GBoxedCopyFunc) g_object_ref, (GDestroyNotify) g_object_unref, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
	detached_from = (GeeMultiMap*) _tmp0_;
	_tmp1_ = self->priv->media_views;
	_tmp2_ = data_collection_start_marking ((DataCollection*) _tmp1_);
	marker = _tmp2_;
	{
		GeeIterator* _source_it = NULL;
		GeeIterator* _tmp3_;
		_tmp3_ = gee_iterable_iterator ((GeeIterable*) sources);
		_source_it = _tmp3_;
		while (TRUE) {
			GeeIterator* _tmp4_;
			MediaSource* source = NULL;
			GeeIterator* _tmp5_;
			gpointer _tmp6_;
			DataView* view = NULL;
			ViewCollection* _tmp7_;
			MediaSource* _tmp8_;
			DataView* _tmp9_;
			DataView* _tmp10_;
			Marker* _tmp34_;
			DataView* _tmp35_;
			GeeMultiMap* _tmp36_;
			MediaSource* _tmp37_;
			_tmp4_ = _source_it;
			if (!gee_iterator_next (_tmp4_)) {
				break;
			}
			_tmp5_ = _source_it;
			_tmp6_ = gee_iterator_get (_tmp5_);
			source = (MediaSource*) _tmp6_;
			_tmp7_ = self->priv->media_views;
			_tmp8_ = source;
			_tmp9_ = view_collection_get_view_for_source (_tmp7_, (DataSource*) _tmp8_);
			view = _tmp9_;
			_tmp10_ = view;
			if (_tmp10_ == NULL) {
				_g_object_unref0 (view);
				_g_object_unref0 (source);
				continue;
			}
			{
				GeeList* _child_tag_list = NULL;
				GeeList* _tmp11_;
				gint _child_tag_size = 0;
				GeeList* _tmp12_;
				gint _tmp13_;
				gint _tmp14_;
				gint _child_tag_index = 0;
				_tmp11_ = tag_get_hierarchical_children (self);
				_child_tag_list = _tmp11_;
				_tmp12_ = _child_tag_list;
				_tmp13_ = gee_collection_get_size ((GeeCollection*) _tmp12_);
				_tmp14_ = _tmp13_;
				_child_tag_size = _tmp14_;
				_child_tag_index = -1;
				while (TRUE) {
					gint _tmp15_;
					gint _tmp16_;
					Tag* child_tag = NULL;
					GeeList* _tmp17_;
					gpointer _tmp18_;
					DataView* child_view = NULL;
					Tag* _tmp19_;
					ViewCollection* _tmp20_;
					MediaSource* _tmp21_;
					DataView* _tmp22_;
					DataView* _tmp23_;
					_child_tag_index = _child_tag_index + 1;
					_tmp15_ = _child_tag_index;
					_tmp16_ = _child_tag_size;
					if (!(_tmp15_ < _tmp16_)) {
						break;
					}
					_tmp17_ = _child_tag_list;
					_tmp18_ = gee_list_get (_tmp17_, _child_tag_index);
					child_tag = (Tag*) _tmp18_;
					_tmp19_ = child_tag;
					_tmp20_ = _tmp19_->priv->media_views;
					_tmp21_ = source;
					_tmp22_ = view_collection_get_view_for_source (_tmp20_, (DataSource*) _tmp21_);
					child_view = _tmp22_;
					_tmp23_ = child_view;
					if (_tmp23_ != NULL) {
						Tag* _tmp24_;
						ViewCollection* _tmp25_;
						Tag* _tmp26_;
						ViewCollection* _tmp27_;
						DataView* _tmp28_;
						Marker* _tmp29_;
						Marker* _tmp30_;
						GeeMultiMap* _tmp31_;
						Tag* _tmp32_;
						MediaSource* _tmp33_;
						_tmp24_ = child_tag;
						_tmp25_ = _tmp24_->priv->media_views;
						_tmp26_ = child_tag;
						_tmp27_ = _tmp26_->priv->media_views;
						_tmp28_ = child_view;
						_tmp29_ = data_collection_mark ((DataCollection*) _tmp27_, (DataObject*) _tmp28_);
						_tmp30_ = _tmp29_;
						data_collection_remove_marked ((DataCollection*) _tmp25_, _tmp30_);
						_g_object_unref0 (_tmp30_);
						_tmp31_ = detached_from;
						_tmp32_ = child_tag;
						_tmp33_ = source;
						gee_multi_map_set (_tmp31_, _tmp32_, _tmp33_);
					}
					_g_object_unref0 (child_view);
					_g_object_unref0 (child_tag);
				}
				_g_object_unref0 (_child_tag_list);
			}
			_tmp34_ = marker;
			_tmp35_ = view;
			marker_mark (_tmp34_, (DataObject*) _tmp35_);
			_tmp36_ = detached_from;
			_tmp37_ = source;
			gee_multi_map_set (_tmp36_, self, _tmp37_);
			_g_object_unref0 (view);
			_g_object_unref0 (source);
		}
		_g_object_unref0 (_source_it);
	}
	_tmp38_ = self->priv->media_views;
	_tmp39_ = marker;
	data_collection_remove_marked ((DataCollection*) _tmp38_, _tmp39_);
	_tmp41_ = detached_from;
	_tmp42_ = gee_multi_map_get_size (_tmp41_);
	_tmp43_ = _tmp42_;
	if (_tmp43_ > 0) {
		GeeMultiMap* _tmp44_;
		_tmp44_ = detached_from;
		_tmp40_ = _tmp44_;
	} else {
		_tmp40_ = NULL;
	}
	_tmp45_ = _g_object_ref0 (_tmp40_);
	result = _tmp45_;
	_g_object_unref0 (marker);
	_g_object_unref0 (detached_from);
	return result;
}

static gint
string_index_of (const gchar* self,
                 const gchar* needle,
                 gint start_index)
{
	gchar* _result_ = NULL;
	gchar* _tmp0_;
	gchar* _tmp1_;
	gint result;
	g_return_val_if_fail (self != NULL, -1);
	g_return_val_if_fail (needle != NULL, -1);
	_tmp0_ = strstr (((gchar*) self) + start_index, (gchar*) needle);
	_result_ = _tmp0_;
	_tmp1_ = _result_;
	if (_tmp1_ != NULL) {
		gchar* _tmp2_;
		_tmp2_ = _result_;
		result = (gint) (_tmp2_ - ((gchar*) self));
		return result;
	} else {
		result = -1;
		return result;
	}
}

gboolean
tag_rename (Tag* self,
            const gchar* name)
{
	gchar* _tmp0_;
	gchar* _tmp1_;
	gboolean _tmp2_;
	gchar* new_name = NULL;
	gchar* _tmp3_;
	const gchar* _tmp4_;
	gchar* _tmp5_;
	gchar* _tmp6_;
	gboolean _tmp7_;
	gboolean result;
	g_return_val_if_fail (self != NULL, FALSE);
	g_return_val_if_fail (name != NULL, FALSE);
	_tmp0_ = tag_get_user_visible_name (self);
	_tmp1_ = _tmp0_;
	_tmp2_ = g_strcmp0 (name, _tmp1_) == 0;
	_g_free0 (_tmp1_);
	if (_tmp2_) {
		result = TRUE;
		return result;
	}
	_tmp3_ = tag_prep_tag_name (name);
	new_name = _tmp3_;
	_tmp4_ = new_name;
	if (_tmp4_ == NULL) {
		result = FALSE;
		_g_free0 (new_name);
		return result;
	}
	_tmp5_ = tag_get_path (self);
	_tmp6_ = _tmp5_;
	_tmp7_ = g_str_has_prefix (_tmp6_, TAG_PATH_SEPARATOR_STRING);
	_g_free0 (_tmp6_);
	if (_tmp7_) {
		gchar* new_path = NULL;
		const gchar* _tmp8_;
		gchar* _tmp9_;
		gchar* old_path = NULL;
		gchar* _tmp10_;
		Tag* parent = NULL;
		Tag* _tmp11_;
		Tag* _tmp12_;
		TagSourceCollection* _tmp22_;
		const gchar* _tmp23_;
		GeeCollection* children = NULL;
		GeeList* _tmp24_;
		const gchar* _tmp25_;
		Alteration* _tmp45_;
		Alteration* _tmp46_;
		_tmp8_ = new_name;
		_tmp9_ = g_strdup (_tmp8_);
		new_path = _tmp9_;
		_tmp10_ = tag_get_path (self);
		old_path = _tmp10_;
		_tmp11_ = tag_get_hierarchical_parent (self);
		parent = _tmp11_;
		_tmp12_ = parent;
		if (_tmp12_ != NULL) {
			Tag* _tmp13_;
			gchar* _tmp14_;
			gchar* _tmp15_;
			gchar* _tmp16_;
			gchar* _tmp17_;
			const gchar* _tmp18_;
			gchar* _tmp19_;
			_tmp13_ = parent;
			_tmp14_ = tag_get_path (_tmp13_);
			_tmp15_ = _tmp14_;
			_tmp16_ = g_strconcat (_tmp15_, TAG_PATH_SEPARATOR_STRING, NULL);
			_tmp17_ = _tmp16_;
			_tmp18_ = new_path;
			_tmp19_ = g_strconcat (_tmp17_, _tmp18_, NULL);
			_g_free0 (new_path);
			new_path = _tmp19_;
			_g_free0 (_tmp17_);
			_g_free0 (_tmp15_);
		} else {
			const gchar* _tmp20_;
			gchar* _tmp21_;
			_tmp20_ = new_path;
			_tmp21_ = g_strconcat (TAG_PATH_SEPARATOR_STRING, _tmp20_, NULL);
			_g_free0 (new_path);
			new_path = _tmp21_;
		}
		_tmp22_ = tag_global;
		_tmp23_ = new_path;
		if (tag_source_collection_exists (_tmp22_, _tmp23_, TRUE)) {
			result = FALSE;
			_g_object_unref0 (parent);
			_g_free0 (old_path);
			_g_free0 (new_path);
			_g_free0 (new_name);
			return result;
		}
		_tmp24_ = tag_get_hierarchical_children (self);
		children = (GeeCollection*) _tmp24_;
		_tmp25_ = new_path;
		tag_set_raw_path (self, _tmp25_, TRUE);
		{
			GeeIterator* _child_it = NULL;
			GeeCollection* _tmp26_;
			GeeIterator* _tmp27_;
			_tmp26_ = children;
			_tmp27_ = gee_iterable_iterator ((GeeIterable*) _tmp26_);
			_child_it = _tmp27_;
			while (TRUE) {
				GeeIterator* _tmp28_;
				Tag* child = NULL;
				GeeIterator* _tmp29_;
				gpointer _tmp30_;
				gchar* old_child_path = NULL;
				Tag* _tmp31_;
				gchar* _tmp32_;
				gint old_path_index = 0;
				const gchar* _tmp33_;
				const gchar* _tmp34_;
				gchar* child_subpath = NULL;
				const gchar* _tmp35_;
				const gchar* _tmp36_;
				gint _tmp37_;
				gint _tmp38_;
				gchar* _tmp39_;
				gchar* new_child_path = NULL;
				const gchar* _tmp40_;
				const gchar* _tmp41_;
				gchar* _tmp42_;
				Tag* _tmp43_;
				const gchar* _tmp44_;
				_tmp28_ = _child_it;
				if (!gee_iterator_next (_tmp28_)) {
					break;
				}
				_tmp29_ = _child_it;
				_tmp30_ = gee_iterator_get (_tmp29_);
				child = (Tag*) _tmp30_;
				_tmp31_ = child;
				_tmp32_ = tag_get_path (_tmp31_);
				old_child_path = _tmp32_;
				_tmp33_ = old_child_path;
				_tmp34_ = old_path;
				old_path_index = string_index_of (_tmp33_, _tmp34_, 0);
				_vala_assert (old_path_index != -1, "old_path_index != -1");
				_tmp35_ = old_child_path;
				_tmp36_ = old_path;
				_tmp37_ = strlen (_tmp36_);
				_tmp38_ = _tmp37_;
				_tmp39_ = string_substring (_tmp35_, (glong) (old_path_index + _tmp38_), (glong) -1);
				child_subpath = _tmp39_;
				_tmp40_ = new_path;
				_tmp41_ = child_subpath;
				_tmp42_ = g_strconcat (_tmp40_, _tmp41_, NULL);
				new_child_path = _tmp42_;
				_tmp43_ = child;
				_tmp44_ = new_child_path;
				tag_set_raw_path (_tmp43_, _tmp44_, TRUE);
				_g_free0 (new_child_path);
				_g_free0 (child_subpath);
				_g_free0 (old_child_path);
				_g_object_unref0 (child);
			}
			_g_object_unref0 (_child_it);
		}
		tag_update_indexable_keywords (self);
		_tmp45_ = alteration_new_from_list ("metadata:name, indexable:keywords");
		_tmp46_ = _tmp45_;
		data_object_notify_altered ((DataObject*) self, _tmp46_);
		_alteration_unref0 (_tmp46_);
		{
			GeeIterator* _child_it = NULL;
			GeeCollection* _tmp47_;
			GeeIterator* _tmp48_;
			_tmp47_ = children;
			_tmp48_ = gee_iterable_iterator ((GeeIterable*) _tmp47_);
			_child_it = _tmp48_;
			while (TRUE) {
				GeeIterator* _tmp49_;
				Tag* child = NULL;
				GeeIterator* _tmp50_;
				gpointer _tmp51_;
				Tag* _tmp52_;
				Alteration* _tmp53_;
				Alteration* _tmp54_;
				_tmp49_ = _child_it;
				if (!gee_iterator_next (_tmp49_)) {
					break;
				}
				_tmp50_ = _child_it;
				_tmp51_ = gee_iterator_get (_tmp50_);
				child = (Tag*) _tmp51_;
				_tmp52_ = child;
				_tmp53_ = alteration_new_from_list ("metadata:name, indexable:keywords");
				_tmp54_ = _tmp53_;
				data_object_notify_altered ((DataObject*) _tmp52_, _tmp54_);
				_alteration_unref0 (_tmp54_);
				_g_object_unref0 (child);
			}
			_g_object_unref0 (_child_it);
		}
		_g_object_unref0 (children);
		_g_object_unref0 (parent);
		_g_free0 (old_path);
		_g_free0 (new_path);
	} else {
		TagSourceCollection* _tmp55_;
		const gchar* _tmp56_;
		const gchar* _tmp57_;
		_tmp55_ = tag_global;
		_tmp56_ = new_name;
		if (tag_source_collection_exists (_tmp55_, _tmp56_, TRUE)) {
			result = FALSE;
			_g_free0 (new_name);
			return result;
		}
		_tmp57_ = new_name;
		tag_set_raw_flat_name (self, _tmp57_);
	}
	result = TRUE;
	_g_free0 (new_name);
	return result;
}

gboolean
tag_contains (Tag* self,
              MediaSource* source)
{
	ViewCollection* _tmp0_;
	gboolean result;
	g_return_val_if_fail (self != NULL, FALSE);
	g_return_val_if_fail (source != NULL, FALSE);
	_tmp0_ = self->priv->media_views;
	result = view_collection_has_view_for_source (_tmp0_, (DataSource*) source);
	return result;
}

gint
tag_get_sources_count (Tag* self)
{
	ViewCollection* _tmp0_;
	gint result;
	g_return_val_if_fail (self != NULL, -1);
	_tmp0_ = self->priv->media_views;
	result = data_collection_get_count ((DataCollection*) _tmp0_);
	return result;
}

GeeCollection*
tag_get_sources (Tag* self)
{
	ViewCollection* _tmp0_;
	GeeCollection* _tmp1_;
	GeeCollection* result;
	g_return_val_if_fail (self != NULL, NULL);
	_tmp0_ = self->priv->media_views;
	_tmp1_ = view_collection_get_sources (_tmp0_);
	result = G_TYPE_CHECK_INSTANCE_CAST (_tmp1_, GEE_TYPE_COLLECTION, GeeCollection);
	return result;
}

void
tag_mirror_sources (Tag* self,
                    ViewCollection* view,
                    CreateView mirroring_ctor,
                    gpointer mirroring_ctor_target)
{
	ViewCollection* _tmp0_;
	g_return_if_fail (self != NULL);
	g_return_if_fail (view != NULL);
	_tmp0_ = self->priv->media_views;
	view_collection_mirror (view, _tmp0_, mirroring_ctor, mirroring_ctor_target, NULL, NULL);
}

static void
tag_on_media_views_contents_altered (Tag* self,
                                     GeeIterable* added,
                                     GeeIterable* removed)
{
	GeeCollection* added_sources = NULL;
	GeeCollection* removed_sources = NULL;
	GeeCollection* _tmp47_;
	GeeCollection* _tmp50_;
	gboolean _tmp53_ = FALSE;
	GeeCollection* _tmp54_;
	GError* _inner_error0_ = NULL;
	g_return_if_fail (self != NULL);
	added_sources = NULL;
	if (added != NULL) {
		GeeArrayList* _tmp0_;
		_tmp0_ = gee_array_list_new (TYPE_MEDIA_SOURCE, (GBoxedCopyFunc) g_object_ref, (GDestroyNotify) g_object_unref, NULL, NULL, NULL);
		_g_object_unref0 (added_sources);
		added_sources = (GeeCollection*) _tmp0_;
		{
			GeeIterator* _view_it = NULL;
			GeeIterator* _tmp1_;
			_tmp1_ = gee_iterable_iterator (added);
			_view_it = _tmp1_;
			while (TRUE) {
				GeeIterator* _tmp2_;
				DataView* view = NULL;
				GeeIterator* _tmp3_;
				gpointer _tmp4_;
				MediaSource* source = NULL;
				DataView* _tmp5_;
				DataSource* _tmp6_;
				DataSource* _tmp7_;
				MediaSource* _tmp8_;
				TagRow* _tmp9_;
				GeeSet* _tmp10_;
				MediaSource* _tmp11_;
				gchar* _tmp12_;
				gchar* _tmp13_;
				gboolean _tmp14_;
				gboolean is_added = FALSE;
				GeeCollection* _tmp21_;
				MediaSource* _tmp22_;
				_tmp2_ = _view_it;
				if (!gee_iterator_next (_tmp2_)) {
					break;
				}
				_tmp3_ = _view_it;
				_tmp4_ = gee_iterator_get (_tmp3_);
				view = (DataView*) _tmp4_;
				_tmp5_ = view;
				_tmp6_ = data_view_get_source (_tmp5_);
				_tmp7_ = _tmp6_;
				_tmp8_ = _g_object_ref0 (G_TYPE_CHECK_INSTANCE_CAST (_tmp7_, TYPE_MEDIA_SOURCE, MediaSource));
				source = _tmp8_;
				_tmp9_ = self->priv->row;
				_tmp10_ = _tmp9_->source_id_list;
				_tmp11_ = source;
				_tmp12_ = data_source_get_source_id ((DataSource*) _tmp11_);
				_tmp13_ = _tmp12_;
				_tmp14_ = !gee_collection_contains ((GeeCollection*) _tmp10_, _tmp13_);
				_g_free0 (_tmp13_);
				if (_tmp14_) {
					gboolean is_added = FALSE;
					TagRow* _tmp15_;
					GeeSet* _tmp16_;
					MediaSource* _tmp17_;
					gchar* _tmp18_;
					gchar* _tmp19_;
					gboolean _tmp20_;
					_tmp15_ = self->priv->row;
					_tmp16_ = _tmp15_->source_id_list;
					_tmp17_ = source;
					_tmp18_ = data_source_get_source_id ((DataSource*) _tmp17_);
					_tmp19_ = _tmp18_;
					_tmp20_ = gee_collection_add ((GeeCollection*) _tmp16_, _tmp19_);
					_g_free0 (_tmp19_);
					is_added = _tmp20_;
					_vala_assert (is_added, "is_added");
				}
				_tmp21_ = added_sources;
				_tmp22_ = source;
				is_added = gee_collection_add (_tmp21_, _tmp22_);
				_vala_assert (is_added, "is_added");
				_g_object_unref0 (source);
				_g_object_unref0 (view);
			}
			_g_object_unref0 (_view_it);
		}
	}
	removed_sources = NULL;
	if (removed != NULL) {
		GeeArrayList* _tmp23_;
		_tmp23_ = gee_array_list_new (TYPE_MEDIA_SOURCE, (GBoxedCopyFunc) g_object_ref, (GDestroyNotify) g_object_unref, NULL, NULL, NULL);
		_g_object_unref0 (removed_sources);
		removed_sources = (GeeCollection*) _tmp23_;
		{
			GeeIterator* _view_it = NULL;
			GeeIterator* _tmp24_;
			_tmp24_ = gee_iterable_iterator (removed);
			_view_it = _tmp24_;
			while (TRUE) {
				GeeIterator* _tmp25_;
				DataView* view = NULL;
				GeeIterator* _tmp26_;
				gpointer _tmp27_;
				MediaSource* source = NULL;
				DataView* _tmp28_;
				DataSource* _tmp29_;
				DataSource* _tmp30_;
				MediaSource* _tmp31_;
				gboolean is_removed = FALSE;
				TagRow* _tmp32_;
				GeeSet* _tmp33_;
				MediaSource* _tmp34_;
				gchar* _tmp35_;
				gchar* _tmp36_;
				gboolean _tmp37_;
				gboolean is_added = FALSE;
				GeeCollection* _tmp38_;
				MediaSource* _tmp39_;
				_tmp25_ = _view_it;
				if (!gee_iterator_next (_tmp25_)) {
					break;
				}
				_tmp26_ = _view_it;
				_tmp27_ = gee_iterator_get (_tmp26_);
				view = (DataView*) _tmp27_;
				_tmp28_ = view;
				_tmp29_ = data_view_get_source (_tmp28_);
				_tmp30_ = _tmp29_;
				_tmp31_ = _g_object_ref0 (G_TYPE_CHECK_INSTANCE_CAST (_tmp30_, TYPE_MEDIA_SOURCE, MediaSource));
				source = _tmp31_;
				_tmp32_ = self->priv->row;
				_tmp33_ = _tmp32_->source_id_list;
				_tmp34_ = source;
				_tmp35_ = data_source_get_source_id ((DataSource*) _tmp34_);
				_tmp36_ = _tmp35_;
				_tmp37_ = gee_collection_remove ((GeeCollection*) _tmp33_, _tmp36_);
				_g_free0 (_tmp36_);
				is_removed = _tmp37_;
				_vala_assert (is_removed, "is_removed");
				_tmp38_ = removed_sources;
				_tmp39_ = source;
				is_added = gee_collection_add (_tmp38_, _tmp39_);
				_vala_assert (is_added, "is_added");
				_g_object_unref0 (source);
				_g_object_unref0 (view);
			}
			_g_object_unref0 (_view_it);
		}
	}
	{
		TagTable* _tmp40_;
		TagTable* _tmp41_;
		TagRow* _tmp42_;
		TagID _tmp43_;
		TagRow* _tmp44_;
		GeeSet* _tmp45_;
		_tmp40_ = tag_table_get_instance ();
		_tmp41_ = _tmp40_;
		_tmp42_ = self->priv->row;
		_tmp43_ = _tmp42_->tag_id;
		_tmp44_ = self->priv->row;
		_tmp45_ = _tmp44_->source_id_list;
		tag_table_set_tagged_sources (_tmp41_, &_tmp43_, (GeeCollection*) _tmp45_, &_inner_error0_);
		_database_table_unref0 (_tmp41_);
		if (G_UNLIKELY (_inner_error0_ != NULL)) {
			if (_inner_error0_->domain == DATABASE_ERROR) {
				goto __catch0_database_error;
			}
			_g_object_unref0 (removed_sources);
			_g_object_unref0 (added_sources);
			g_critical ("file %s: line %d: unexpected 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;
		}
	}
	goto __finally0;
	__catch0_database_error:
	{
		GError* err = NULL;
		GError* _tmp46_;
		err = _inner_error0_;
		_inner_error0_ = NULL;
		_tmp46_ = err;
		app_window_database_error (_tmp46_);
		_g_error_free0 (err);
	}
	__finally0:
	if (G_UNLIKELY (_inner_error0_ != NULL)) {
		_g_object_unref0 (removed_sources);
		_g_object_unref0 (added_sources);
		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;
	}
	_tmp47_ = added_sources;
	if (_tmp47_ != NULL) {
		TagSourceCollection* _tmp48_;
		GeeCollection* _tmp49_;
		_tmp48_ = tag_global;
		_tmp49_ = added_sources;
		container_source_collection_notify_container_contents_added ((ContainerSourceCollection*) _tmp48_, (ContainerSource*) self, _tmp49_, self->priv->relinking);
	}
	_tmp50_ = removed_sources;
	if (_tmp50_ != NULL) {
		TagSourceCollection* _tmp51_;
		GeeCollection* _tmp52_;
		_tmp51_ = tag_global;
		_tmp52_ = removed_sources;
		container_source_collection_notify_container_contents_removed ((ContainerSourceCollection*) _tmp51_, (ContainerSource*) self, _tmp52_, self->priv->unlinking);
	}
	_tmp54_ = added_sources;
	if (_tmp54_ != NULL) {
		_tmp53_ = TRUE;
	} else {
		GeeCollection* _tmp55_;
		_tmp55_ = removed_sources;
		_tmp53_ = _tmp55_ != NULL;
	}
	if (_tmp53_) {
		TagSourceCollection* _tmp56_;
		GeeCollection* _tmp57_;
		GeeCollection* _tmp58_;
		_tmp56_ = tag_global;
		_tmp57_ = added_sources;
		_tmp58_ = removed_sources;
		container_source_collection_notify_container_contents_altered ((ContainerSourceCollection*) _tmp56_, (ContainerSource*) self, _tmp57_, self->priv->relinking, _tmp58_, self->priv->unlinking);
	}
	_g_object_unref0 (removed_sources);
	_g_object_unref0 (added_sources);
}

static void
tag_on_sources_destroyed (Tag* self,
                          GeeCollection* sources)
{
	GeeMultiMap* _tmp0_;
	GeeMultiMap* _tmp1_;
	g_return_if_fail (self != NULL);
	g_return_if_fail (sources != NULL);
	_tmp0_ = tag_detach_many (self, G_TYPE_CHECK_INSTANCE_CAST (sources, GEE_TYPE_COLLECTION, GeeCollection));
	_tmp1_ = _tmp0_;
	_g_object_unref0 (_tmp1_);
}

static void
tag_real_destroy (DataSource* base)
{
	Tag * self;
	ViewCollection* _tmp0_;
	GError* _inner_error0_ = NULL;
	self = (Tag*) base;
	_tmp0_ = self->priv->media_views;
	if (data_collection_get_count ((DataCollection*) _tmp0_) > 0) {
		ViewCollection* _tmp1_;
		guint _tmp2_;
		GeeArrayList* removed = NULL;
		GeeArrayList* _tmp3_;
		GeeArrayList* _tmp4_;
		ViewCollection* _tmp5_;
		GeeCollection* _tmp6_;
		GeeCollection* _tmp7_;
		ViewCollection* _tmp8_;
		TagSourceCollection* _tmp9_;
		GeeArrayList* _tmp10_;
		TagSourceCollection* _tmp11_;
		GeeArrayList* _tmp12_;
		ViewCollection* _tmp13_;
		_tmp1_ = self->priv->media_views;
		g_signal_parse_name ("contents-altered", TYPE_DATA_COLLECTION, &_tmp2_, NULL, FALSE);
		g_signal_handlers_disconnect_matched ((DataCollection*) _tmp1_, G_SIGNAL_MATCH_ID | G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA, _tmp2_, 0, NULL, (GCallback) _tag_on_media_views_contents_altered_data_collection_contents_altered, self);
		_tmp3_ = gee_array_list_new (TYPE_MEDIA_SOURCE, (GBoxedCopyFunc) g_object_ref, (GDestroyNotify) g_object_unref, NULL, NULL, NULL);
		removed = _tmp3_;
		_tmp4_ = removed;
		_tmp5_ = self->priv->media_views;
		_tmp6_ = view_collection_get_sources (_tmp5_);
		_tmp7_ = G_TYPE_CHECK_INSTANCE_CAST (_tmp6_, GEE_TYPE_COLLECTION, GeeCollection);
		gee_array_list_add_all (_tmp4_, _tmp7_);
		_g_object_unref0 (_tmp7_);
		_tmp8_ = self->priv->media_views;
		data_collection_clear ((DataCollection*) _tmp8_);
		_tmp9_ = tag_global;
		_tmp10_ = removed;
		container_source_collection_notify_container_contents_removed ((ContainerSourceCollection*) _tmp9_, (ContainerSource*) self, (GeeCollection*) _tmp10_, FALSE);
		_tmp11_ = tag_global;
		_tmp12_ = removed;
		container_source_collection_notify_container_contents_altered ((ContainerSourceCollection*) _tmp11_, (ContainerSource*) self, NULL, FALSE, (GeeCollection*) _tmp12_, FALSE);
		_tmp13_ = self->priv->media_views;
		g_signal_connect_object ((DataCollection*) _tmp13_, "contents-altered", (GCallback) _tag_on_media_views_contents_altered_data_collection_contents_altered, self, 0);
		_g_object_unref0 (removed);
	}
	{
		TagTable* _tmp14_;
		TagTable* _tmp15_;
		TagRow* _tmp16_;
		TagID _tmp17_;
		_tmp14_ = tag_table_get_instance ();
		_tmp15_ = _tmp14_;
		_tmp16_ = self->priv->row;
		_tmp17_ = _tmp16_->tag_id;
		tag_table_remove (_tmp15_, &_tmp17_, &_inner_error0_);
		_database_table_unref0 (_tmp15_);
		if (G_UNLIKELY (_inner_error0_ != NULL)) {
			if (_inner_error0_->domain == DATABASE_ERROR) {
				goto __catch0_database_error;
			}
			g_critical ("file %s: line %d: unexpected 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;
		}
	}
	goto __finally0;
	__catch0_database_error:
	{
		GError* err = NULL;
		GError* _tmp18_;
		err = _inner_error0_;
		_inner_error0_ = NULL;
		_tmp18_ = err;
		app_window_database_error (_tmp18_);
		_g_error_free0 (err);
	}
	__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;
	}
	DATA_SOURCE_CLASS (tag_parent_class)->destroy (G_TYPE_CHECK_INSTANCE_CAST (self, TYPE_DATA_SOURCE, DataSource));
}

static inline gpointer
tag_tag_snapshot_get_instance_private (TagTagSnapshot* self)
{
	return G_STRUCT_MEMBER_P (self, TagTagSnapshot_private_offset);
}

static void
_tag_tag_snapshot_on_source_destroyed_source_collection_item_destroyed (SourceCollection* _sender,
                                                                        DataSource* source,
                                                                        gpointer self)
{
	tag_tag_snapshot_on_source_destroyed ((TagTagSnapshot*) self, source);
}

static TagTagSnapshot*
tag_tag_snapshot_construct (GType object_type,
                            Tag* tag)
{
	TagTagSnapshot* self = NULL;
	TagRow* _tmp0_;
	TagRow* _tmp1_;
	LibraryPhotoSourceCollection* _tmp11_;
	VideoSourceCollection* _tmp12_;
	g_return_val_if_fail (tag != NULL, NULL);
	self = (TagTagSnapshot*) source_snapshot_construct (object_type);
	_tmp0_ = tag->priv->row;
	_tmp1_ = _tag_row_ref0 (_tmp0_);
	_tag_row_unref0 (self->priv->row);
	self->priv->row = _tmp1_;
	{
		GeeIterator* _source_it = NULL;
		GeeCollection* _tmp2_;
		GeeCollection* _tmp3_;
		GeeIterator* _tmp4_;
		GeeIterator* _tmp5_;
		_tmp2_ = tag_get_sources (tag);
		_tmp3_ = _tmp2_;
		_tmp4_ = gee_iterable_iterator ((GeeIterable*) _tmp3_);
		_tmp5_ = _tmp4_;
		_g_object_unref0 (_tmp3_);
		_source_it = _tmp5_;
		while (TRUE) {
			GeeIterator* _tmp6_;
			MediaSource* source = NULL;
			GeeIterator* _tmp7_;
			gpointer _tmp8_;
			GeeHashSet* _tmp9_;
			MediaSource* _tmp10_;
			_tmp6_ = _source_it;
			if (!gee_iterator_next (_tmp6_)) {
				break;
			}
			_tmp7_ = _source_it;
			_tmp8_ = gee_iterator_get (_tmp7_);
			source = (MediaSource*) _tmp8_;
			_tmp9_ = self->priv->sources;
			_tmp10_ = source;
			gee_abstract_collection_add ((GeeAbstractCollection*) _tmp9_, _tmp10_);
			_g_object_unref0 (source);
		}
		_g_object_unref0 (_source_it);
	}
	_tmp11_ = library_photo_global;
	g_signal_connect ((SourceCollection*) _tmp11_, "item-destroyed", (GCallback) _tag_tag_snapshot_on_source_destroyed_source_collection_item_destroyed, self);
	_tmp12_ = video_global;
	g_signal_connect ((SourceCollection*) _tmp12_, "item-destroyed", (GCallback) _tag_tag_snapshot_on_source_destroyed_source_collection_item_destroyed, self);
	return self;
}

static TagTagSnapshot*
tag_tag_snapshot_new (Tag* tag)
{
	return tag_tag_snapshot_construct (TAG_TYPE_TAG_SNAPSHOT, tag);
}

static TagRow*
tag_tag_snapshot_get_row (TagTagSnapshot* self)
{
	TagRow* _tmp0_;
	TagRow* _tmp1_;
	TagRow* result;
	g_return_val_if_fail (self != NULL, NULL);
	_tmp0_ = self->priv->row;
	_tmp1_ = _tag_row_ref0 (_tmp0_);
	result = _tmp1_;
	return result;
}

static void
tag_tag_snapshot_real_notify_broken (SourceSnapshot* base)
{
	TagTagSnapshot * self;
	TagRow* _tmp0_;
	GeeHashSet* _tmp1_;
	self = (TagTagSnapshot*) base;
	_tmp0_ = tag_row_new ();
	_tag_row_unref0 (self->priv->row);
	self->priv->row = _tmp0_;
	_tmp1_ = self->priv->sources;
	gee_abstract_collection_clear ((GeeAbstractCollection*) _tmp1_);
	SOURCE_SNAPSHOT_CLASS (tag_tag_snapshot_parent_class)->notify_broken (G_TYPE_CHECK_INSTANCE_CAST (self, TYPE_SOURCE_SNAPSHOT, SourceSnapshot));
}

static void
tag_tag_snapshot_on_source_destroyed (TagTagSnapshot* self,
                                      DataSource* source)
{
	GeeHashSet* _tmp0_;
	g_return_if_fail (self != NULL);
	g_return_if_fail (source != NULL);
	_tmp0_ = self->priv->sources;
	if (gee_abstract_collection_contains ((GeeAbstractCollection*) _tmp0_, G_TYPE_CHECK_INSTANCE_CAST (source, TYPE_MEDIA_SOURCE, MediaSource))) {
		source_snapshot_notify_broken ((SourceSnapshot*) self);
	}
}

static void
tag_tag_snapshot_class_init (TagTagSnapshotClass * klass,
                             gpointer klass_data)
{
	tag_tag_snapshot_parent_class = g_type_class_peek_parent (klass);
	((SourceSnapshotClass *) klass)->finalize = tag_tag_snapshot_finalize;
	g_type_class_adjust_private_offset (klass, &TagTagSnapshot_private_offset);
	((SourceSnapshotClass *) klass)->notify_broken = (void (*) (SourceSnapshot*)) tag_tag_snapshot_real_notify_broken;
}

static void
tag_tag_snapshot_instance_init (TagTagSnapshot * self,
                                gpointer klass)
{
	GeeHashSet* _tmp0_;
	self->priv = tag_tag_snapshot_get_instance_private (self);
	_tmp0_ = gee_hash_set_new (TYPE_MEDIA_SOURCE, (GBoxedCopyFunc) g_object_ref, (GDestroyNotify) g_object_unref, NULL, NULL, NULL, NULL, NULL, NULL);
	self->priv->sources = _tmp0_;
}

static void
tag_tag_snapshot_finalize (SourceSnapshot * obj)
{
	TagTagSnapshot * self;
	LibraryPhotoSourceCollection* _tmp0_;
	guint _tmp1_;
	VideoSourceCollection* _tmp2_;
	guint _tmp3_;
	self = G_TYPE_CHECK_INSTANCE_CAST (obj, TAG_TYPE_TAG_SNAPSHOT, TagTagSnapshot);
	_tmp0_ = library_photo_global;
	g_signal_parse_name ("item-destroyed", TYPE_SOURCE_COLLECTION, &_tmp1_, NULL, FALSE);
	g_signal_handlers_disconnect_matched ((SourceCollection*) _tmp0_, G_SIGNAL_MATCH_ID | G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA, _tmp1_, 0, NULL, (GCallback) _tag_tag_snapshot_on_source_destroyed_source_collection_item_destroyed, self);
	_tmp2_ = video_global;
	g_signal_parse_name ("item-destroyed", TYPE_SOURCE_COLLECTION, &_tmp3_, NULL, FALSE);
	g_signal_handlers_disconnect_matched ((SourceCollection*) _tmp2_, G_SIGNAL_MATCH_ID | G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA, _tmp3_, 0, NULL, (GCallback) _tag_tag_snapshot_on_source_destroyed_source_collection_item_destroyed, self);
	_tag_row_unref0 (self->priv->row);
	_g_object_unref0 (self->priv->sources);
	SOURCE_SNAPSHOT_CLASS (tag_tag_snapshot_parent_class)->finalize (obj);
}

static GType
tag_tag_snapshot_get_type_once (void)
{
	static const GTypeInfo g_define_type_info = { sizeof (TagTagSnapshotClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) tag_tag_snapshot_class_init, (GClassFinalizeFunc) NULL, NULL, sizeof (TagTagSnapshot), 0, (GInstanceInitFunc) tag_tag_snapshot_instance_init, NULL };
	GType tag_tag_snapshot_type_id;
	tag_tag_snapshot_type_id = g_type_register_static (TYPE_SOURCE_SNAPSHOT, "TagTagSnapshot", &g_define_type_info, 0);
	TagTagSnapshot_private_offset = g_type_add_instance_private (tag_tag_snapshot_type_id, sizeof (TagTagSnapshotPrivate));
	return tag_tag_snapshot_type_id;
}

static GType
tag_tag_snapshot_get_type (void)
{
	static volatile gsize tag_tag_snapshot_type_id__once = 0;
	if (g_once_init_enter (&tag_tag_snapshot_type_id__once)) {
		GType tag_tag_snapshot_type_id;
		tag_tag_snapshot_type_id = tag_tag_snapshot_get_type_once ();
		g_once_init_leave (&tag_tag_snapshot_type_id__once, tag_tag_snapshot_type_id);
	}
	return tag_tag_snapshot_type_id__once;
}

static TagTagProxy*
tag_tag_proxy_construct (GType object_type,
                         Tag* tag)
{
	TagTagProxy* self = NULL;
	g_return_val_if_fail (tag != NULL, NULL);
	self = (TagTagProxy*) source_proxy_construct (object_type, (DataSource*) tag);
	return self;
}

static TagTagProxy*
tag_tag_proxy_new (Tag* tag)
{
	return tag_tag_proxy_construct (TAG_TYPE_TAG_PROXY, tag);
}

static DataSource*
tag_tag_proxy_real_reconstitute (SourceProxy* base,
                                 gint64 object_id,
                                 SourceSnapshot* snapshot)
{
	TagTagProxy * self;
	TagRow* _tmp0_;
	TagRow* _tmp1_;
	Tag* _tmp2_;
	DataSource* _tmp3_;
	DataSource* result;
	self = (TagTagProxy*) base;
	g_return_val_if_fail (snapshot != NULL, NULL);
	_tmp0_ = tag_tag_snapshot_get_row (G_TYPE_CHECK_INSTANCE_CAST (snapshot, TAG_TYPE_TAG_SNAPSHOT, TagTagSnapshot));
	_tmp1_ = _tmp0_;
	_tmp2_ = tag_reconstitute (object_id, _tmp1_);
	_tmp3_ = (DataSource*) _tmp2_;
	_tag_row_unref0 (_tmp1_);
	result = _tmp3_;
	return result;
}

static void
tag_tag_proxy_class_init (TagTagProxyClass * klass,
                          gpointer klass_data)
{
	tag_tag_proxy_parent_class = g_type_class_peek_parent (klass);
	((SourceProxyClass *) klass)->reconstitute = (DataSource* (*) (SourceProxy*, gint64, SourceSnapshot*)) tag_tag_proxy_real_reconstitute;
}

static void
tag_tag_proxy_instance_init (TagTagProxy * self,
                             gpointer klass)
{
}

static GType
tag_tag_proxy_get_type_once (void)
{
	static const GTypeInfo g_define_type_info = { sizeof (TagTagProxyClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) tag_tag_proxy_class_init, (GClassFinalizeFunc) NULL, NULL, sizeof (TagTagProxy), 0, (GInstanceInitFunc) tag_tag_proxy_instance_init, NULL };
	GType tag_tag_proxy_type_id;
	tag_tag_proxy_type_id = g_type_register_static (TYPE_SOURCE_PROXY, "TagTagProxy", &g_define_type_info, 0);
	return tag_tag_proxy_type_id;
}

static GType
tag_tag_proxy_get_type (void)
{
	static volatile gsize tag_tag_proxy_type_id__once = 0;
	if (g_once_init_enter (&tag_tag_proxy_type_id__once)) {
		GType tag_tag_proxy_type_id;
		tag_tag_proxy_type_id = tag_tag_proxy_get_type_once ();
		g_once_init_leave (&tag_tag_proxy_type_id__once, tag_tag_proxy_type_id);
	}
	return tag_tag_proxy_type_id__once;
}

static void
tag_class_init (TagClass * klass,
                gpointer klass_data)
{
	tag_parent_class = g_type_class_peek_parent (klass);
	g_type_class_adjust_private_offset (klass, &Tag_private_offset);
	((DataSourceClass *) klass)->get_typename = (gchar* (*) (DataSource*)) tag_real_get_typename;
	((DataSourceClass *) klass)->get_instance_id = (gint64 (*) (DataSource*)) tag_real_get_instance_id;
	((DataObjectClass *) klass)->get_name = (gchar* (*) (DataObject*)) tag_real_get_name;
	((DataObjectClass *) klass)->to_string = (gchar* (*) (DataObject*)) tag_real_to_string;
	((DataSourceClass *) klass)->equals = (gboolean (*) (DataSource*, DataSource*)) tag_real_equals;
	((DataSourceClass *) klass)->save_snapshot = (SourceSnapshot* (*) (DataSource*)) tag_real_save_snapshot;
	((DataSourceClass *) klass)->destroy = (void (*) (DataSource*)) tag_real_destroy;
	G_OBJECT_CLASS (klass)->finalize = tag_finalize;
}

static void
tag_container_source_interface_init (ContainerSourceIface * iface,
                                     gpointer iface_data)
{
	tag_container_source_parent_iface = g_type_interface_peek_parent (iface);
	iface->has_links = (gboolean (*) (ContainerSource*)) tag_real_has_links;
	iface->get_backlink = (SourceBacklink* (*) (ContainerSource*)) tag_real_get_backlink;
	iface->break_link = (void (*) (ContainerSource*, DataSource*)) tag_real_break_link;
	iface->break_link_many = (void (*) (ContainerSource*, GeeCollection*)) tag_real_break_link_many;
	iface->establish_link = (void (*) (ContainerSource*, DataSource*)) tag_real_establish_link;
	iface->establish_link_many = (void (*) (ContainerSource*, GeeCollection*)) tag_real_establish_link_many;
}

static void
tag_proxyable_interface_init (ProxyableIface * iface,
                              gpointer iface_data)
{
	tag_proxyable_parent_iface = g_type_interface_peek_parent (iface);
	iface->get_proxy = (SourceProxy* (*) (Proxyable*)) tag_real_get_proxy;
}

static void
tag_indexable_interface_init (IndexableIface * iface,
                              gpointer iface_data)
{
	tag_indexable_parent_iface = g_type_interface_peek_parent (iface);
	iface->get_indexable_keywords = (const gchar* (*) (Indexable*)) tag_real_get_indexable_keywords;
}

static void
tag_instance_init (Tag * self,
                   gpointer klass)
{
	self->priv = tag_get_instance_private (self);
	self->priv->name_collation_key = NULL;
	self->priv->unlinking = FALSE;
	self->priv->relinking = FALSE;
	self->priv->indexable_keywords = NULL;
}

static void
tag_finalize (GObject * obj)
{
	Tag * self;
	ViewCollection* _tmp0_;
	guint _tmp1_;
	LibraryPhotoSourceCollection* _tmp2_;
	guint _tmp3_;
	VideoSourceCollection* _tmp4_;
	guint _tmp5_;
	self = G_TYPE_CHECK_INSTANCE_CAST (obj, TYPE_TAG, Tag);
	_tmp0_ = self->priv->media_views;
	g_signal_parse_name ("contents-altered", TYPE_DATA_COLLECTION, &_tmp1_, NULL, FALSE);
	g_signal_handlers_disconnect_matched ((DataCollection*) _tmp0_, G_SIGNAL_MATCH_ID | G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA, _tmp1_, 0, NULL, (GCallback) _tag_on_media_views_contents_altered_data_collection_contents_altered, self);
	_tmp2_ = library_photo_global;
	g_signal_parse_name ("items-destroyed", TYPE_SOURCE_COLLECTION, &_tmp3_, NULL, FALSE);
	g_signal_handlers_disconnect_matched ((SourceCollection*) _tmp2_, G_SIGNAL_MATCH_ID | G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA, _tmp3_, 0, NULL, (GCallback) _tag_on_sources_destroyed_source_collection_items_destroyed, self);
	_tmp4_ = video_global;
	g_signal_parse_name ("items-destroyed", TYPE_SOURCE_COLLECTION, &_tmp5_, NULL, FALSE);
	g_signal_handlers_disconnect_matched ((SourceCollection*) _tmp4_, G_SIGNAL_MATCH_ID | G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA, _tmp5_, 0, NULL, (GCallback) _tag_on_sources_destroyed_source_collection_items_destroyed, self);
	_tag_row_unref0 (self->priv->row);
	_data_collection_unref0 (self->priv->media_views);
	_g_free0 (self->priv->name_collation_key);
	_g_free0 (self->priv->indexable_keywords);
	G_OBJECT_CLASS (tag_parent_class)->finalize (obj);
}

static GType
tag_get_type_once (void)
{
	static const GTypeInfo g_define_type_info = { sizeof (TagClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) tag_class_init, (GClassFinalizeFunc) NULL, NULL, sizeof (Tag), 0, (GInstanceInitFunc) tag_instance_init, NULL };
	static const GInterfaceInfo container_source_info = { (GInterfaceInitFunc) tag_container_source_interface_init, (GInterfaceFinalizeFunc) NULL, NULL};
	static const GInterfaceInfo proxyable_info = { (GInterfaceInitFunc) tag_proxyable_interface_init, (GInterfaceFinalizeFunc) NULL, NULL};
	static const GInterfaceInfo indexable_info = { (GInterfaceInitFunc) tag_indexable_interface_init, (GInterfaceFinalizeFunc) NULL, NULL};
	GType tag_type_id;
	tag_type_id = g_type_register_static (TYPE_DATA_SOURCE, "Tag", &g_define_type_info, 0);
	g_type_add_interface_static (tag_type_id, TYPE_CONTAINER_SOURCE, &container_source_info);
	g_type_add_interface_static (tag_type_id, TYPE_PROXYABLE, &proxyable_info);
	g_type_add_interface_static (tag_type_id, TYPE_INDEXABLE, &indexable_info);
	Tag_private_offset = g_type_add_instance_private (tag_type_id, sizeof (TagPrivate));
	return tag_type_id;
}

GType
tag_get_type (void)
{
	static volatile gsize tag_type_id__once = 0;
	if (g_once_init_enter (&tag_type_id__once)) {
		GType tag_type_id;
		tag_type_id = tag_get_type_once ();
		g_once_init_leave (&tag_type_id__once, tag_type_id);
	}
	return tag_type_id__once;
}

