/* MetadataWriter.c generated by valac 0.56.19, the Vala compiler
 * generated from MetadataWriter.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
*/
/* MetadataWriter tracks LibraryPhotos for alterations to their metadata and commits those changes*/
/* in a timely manner to their backing files.  Because only the MetadataWriter knows when the*/
/* metadata has been properly committed, it is also responsible for updating the metadata-dirty*/
/* flag in Photo.  Thus, MetadataWriter should *always* be running, even if the user has turned off*/
/* the feature, so if they turn it on MetadataWriter can properly go out and update the backing*/
/* files.*/

#include "io.elementary.photos.h"
#include <glib.h>
#include <glib-object.h>
#include <gee.h>
#include <stdlib.h>
#include <string.h>
#include <gio/gio.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 METADATA_WRITER_TYPE_COMMIT_JOB (metadata_writer_commit_job_get_type ())
#define METADATA_WRITER_COMMIT_JOB(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), METADATA_WRITER_TYPE_COMMIT_JOB, MetadataWriterCommitJob))
#define METADATA_WRITER_COMMIT_JOB_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), METADATA_WRITER_TYPE_COMMIT_JOB, MetadataWriterCommitJobClass))
#define METADATA_WRITER_IS_COMMIT_JOB(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), METADATA_WRITER_TYPE_COMMIT_JOB))
#define METADATA_WRITER_IS_COMMIT_JOB_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), METADATA_WRITER_TYPE_COMMIT_JOB))
#define METADATA_WRITER_COMMIT_JOB_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), METADATA_WRITER_TYPE_COMMIT_JOB, MetadataWriterCommitJobClass))

typedef struct _MetadataWriterCommitJob MetadataWriterCommitJob;
typedef struct _MetadataWriterCommitJobClass MetadataWriterCommitJobClass;
enum  {
	METADATA_WRITER_0_PROPERTY,
	METADATA_WRITER_NUM_PROPERTIES
};
static GParamSpec* metadata_writer_properties[METADATA_WRITER_NUM_PROPERTIES];
#define _library_monitor_pool_unref0(var) ((var == NULL) ? NULL : (var = (library_monitor_pool_unref (var), NULL)))
#define _workers_unref0(var) ((var == NULL) ? NULL : (var = (workers_unref (var), NULL)))
#define _timed_queue_unref0(var) ((var == NULL) ? NULL : (var = (timed_queue_unref (var), NULL)))
#define _g_object_unref0(var) ((var == NULL) ? NULL : (var = (g_object_unref (var), NULL)))
#define _g_free0(var) (var = (g_free (var), NULL))
#define _alteration_unref0(var) ((var == NULL) ? NULL : (var = (alteration_unref (var), NULL)))
#define _g_error_free0(var) ((var == NULL) ? NULL : (var = (g_error_free (var), NULL)))
#define _background_job_unref0(var) ((var == NULL) ? NULL : (var = (background_job_unref (var), NULL)))
typedef struct _MetadataWriterCommitJobPrivate MetadataWriterCommitJobPrivate;
#define _photo_reimport_master_state_unref0(var) ((var == NULL) ? NULL : (var = (photo_reimport_master_state_unref (var), NULL)))
#define _photo_reimport_editable_state_unref0(var) ((var == NULL) ? NULL : (var = (photo_reimport_editable_state_unref (var), NULL)))
#define _media_metadata_unref0(var) ((var == NULL) ? NULL : (var = (media_metadata_unref (var), NULL)))
#define _metadata_date_time_unref0(var) ((var == NULL) ? NULL : (var = (metadata_date_time_unref (var), NULL)))
enum  {
	METADATA_WRITER_PROGRESS_SIGNAL,
	METADATA_WRITER_NUM_SIGNALS
};
static guint metadata_writer_signals[METADATA_WRITER_NUM_SIGNALS] = {0};
#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 _MetadataWriterPrivate {
	Workers* workers;
	gboolean enabled;
	HashTimedQueue* dirty;
	GeeHashMap* pending;
	GeeHashSet* interested_photo_details;
	LibraryPhoto* ignore_photo_alteration;
	guint outstanding_total;
	guint outstanding_completed;
	gboolean closed;
	gint pause_count;
	GeeHashSet* importing_photos;
	GSettings* file_settings;
};

struct _MetadataWriterCommitJob {
	BackgroundJob parent_instance;
	MetadataWriterCommitJobPrivate * priv;
	LibraryPhoto* photo;
	GeeSet* current_keywords;
	PhotoReimportMasterState* reimport_master_state;
	PhotoReimportEditableState* reimport_editable_state;
	GError* err;
};

struct _MetadataWriterCommitJobClass {
	BackgroundJobClass parent_class;
};

static gint MetadataWriter_private_offset;
static gpointer metadata_writer_parent_class = NULL;
static MetadataWriter* metadata_writer_instance;
static MetadataWriter* metadata_writer_instance = NULL;
static gpointer metadata_writer_commit_job_parent_class = NULL;

static GType metadata_writer_commit_job_get_type (void) G_GNUC_CONST  G_GNUC_UNUSED ;
static void metadata_writer_on_importing_photos (MetadataWriter* self,
                                          GeeCollection* media_sources);
static void _metadata_writer_on_importing_photos_media_source_collection_media_import_starting (MediaSourceCollection* _sender,
                                                                                         GeeCollection* media,
                                                                                         gpointer self);
static void metadata_writer_on_photos_imported (MetadataWriter* self,
                                         GeeCollection* media_sources);
static void _metadata_writer_on_photos_imported_media_source_collection_media_import_completed (MediaSourceCollection* _sender,
                                                                                         GeeCollection* media,
                                                                                         gpointer self);
static void metadata_writer_on_photos_added_removed (MetadataWriter* self,
                                              GeeIterable* added,
                                              GeeIterable* removed);
static void _metadata_writer_on_photos_added_removed_data_collection_contents_altered (DataCollection* _sender,
                                                                                GeeIterable* added,
                                                                                GeeIterable* removed,
                                                                                gpointer self);
static void metadata_writer_on_photos_altered (MetadataWriter* self,
                                        GeeMap* items);
static void _metadata_writer_on_photos_altered_data_collection_items_altered (DataCollection* _sender,
                                                                       GeeMap* items,
                                                                       gpointer self);
static void metadata_writer_on_collection_frozen (MetadataWriter* self);
static void _metadata_writer_on_collection_frozen_data_collection_frozen (DataCollection* _sender,
                                                                   gpointer self);
static void metadata_writer_on_collection_thawed (MetadataWriter* self);
static void _metadata_writer_on_collection_thawed_data_collection_thawed (DataCollection* _sender,
                                                                   gpointer self);
static void metadata_writer_on_photos_destroyed (MetadataWriter* self,
                                          GeeCollection* destroyed);
static void _metadata_writer_on_photos_destroyed_source_collection_items_destroyed (SourceCollection* _sender,
                                                                             GeeCollection* destroyed,
                                                                             gpointer self);
static void metadata_writer_on_tags_altered (MetadataWriter* self,
                                      GeeMap* map);
static void _metadata_writer_on_tags_altered_data_collection_items_altered (DataCollection* _sender,
                                                                     GeeMap* items,
                                                                     gpointer self);
static void metadata_writer_on_tag_contents_altered (MetadataWriter* self,
                                              ContainerSource* container,
                                              GeeCollection* added,
                                              gboolean relinking,
                                              GeeCollection* removed,
                                              gboolean unlinking);
static void _metadata_writer_on_tag_contents_altered_container_source_collection_container_contents_altered (ContainerSourceCollection* _sender,
                                                                                                      ContainerSource* container,
                                                                                                      GeeCollection* added,
                                                                                                      gboolean relinked,
                                                                                                      GeeCollection* removed,
                                                                                                      gboolean unlinked,
                                                                                                      gpointer self);
static void metadata_writer_on_tag_backlink_removed (MetadataWriter* self,
                                              ContainerSource* container,
                                              GeeCollection* sources);
static void _metadata_writer_on_tag_backlink_removed_container_source_collection_backlink_to_container_removed (ContainerSourceCollection* _sender,
                                                                                                         ContainerSource* container,
                                                                                                         GeeCollection* sources,
                                                                                                         gpointer self);
static void metadata_writer_on_application_exiting (MetadataWriter* self);
static void _metadata_writer_on_application_exiting_photos_application_exiting (PhotosApplication* _sender,
                                                                         gboolean panicked,
                                                                         gpointer self);
static void metadata_writer_on_monitor_installed (MetadataWriter* self,
                                           LibraryMonitor* monitor);
static void _metadata_writer_on_monitor_installed_library_monitor_pool_monitor_installed (LibraryMonitorPool* _sender,
                                                                                   LibraryMonitor* monitor,
                                                                                   gpointer self);
static void metadata_writer_on_monitor_destroyed (MetadataWriter* self,
                                           LibraryMonitor* monitor);
static void _metadata_writer_on_monitor_destroyed_library_monitor_pool_monitor_destroyed (LibraryMonitorPool* _sender,
                                                                                   LibraryMonitor* monitor,
                                                                                   gpointer self);
static MetadataWriter* metadata_writer_new (void);
static MetadataWriter* metadata_writer_construct (GType object_type);
static void metadata_writer_on_photo_dequeued (MetadataWriter* self,
                                        LibraryPhoto* photo);
static void _metadata_writer_on_photo_dequeued_dequeued_callback (gconstpointer item,
                                                           gpointer self);
static void metadata_writer_on_config_changed (MetadataWriter* self,
                                        const gchar* key);
static void _metadata_writer_on_config_changed_g_settings_changed (GSettings* _sender,
                                                            const gchar* key,
                                                            gpointer self);
static void metadata_writer_schedule_if_dirty (MetadataWriter* self,
                                        GeeIterable* media_sources,
                                        const gchar* reason);
static void metadata_writer_cancel_all (MetadataWriter* self,
                                 gboolean wait);
static void metadata_writer_on_discovery_completed (MetadataWriter* self);
static void _metadata_writer_on_discovery_completed_directory_monitor_discovery_completed (DirectoryMonitor* _sender,
                                                                                    gpointer self);
static gboolean metadata_writer_cancel_job (MetadataWriter* self,
                                     LibraryPhoto* photo);
static void metadata_writer_photos_are_dirty (MetadataWriter* self,
                                       GeeCollection* photos,
                                       const gchar* reason,
                                       gboolean already_marked);
static void metadata_writer_count_enqueued_work (MetadataWriter* self,
                                          gint count,
                                          gboolean report);
static void metadata_writer_count_cancelled_work (MetadataWriter* self,
                                           gint count,
                                           gboolean report);
static void metadata_writer_count_completed_work (MetadataWriter* self,
                                           gint count,
                                           gboolean report);
static MetadataWriterCommitJob* metadata_writer_commit_job_new (MetadataWriter* owner,
                                                         LibraryPhoto* photo,
                                                         GeeSet* keywords);
static MetadataWriterCommitJob* metadata_writer_commit_job_construct (GType object_type,
                                                               MetadataWriter* owner,
                                                               LibraryPhoto* photo,
                                                               GeeSet* keywords);
static void metadata_writer_on_update_completed (MetadataWriter* self,
                                          BackgroundJob* j);
static void metadata_writer_on_update_cancelled (MetadataWriter* self,
                                          BackgroundJob* j);
static void g_cclosure_user_marshal_VOID__UINT_UINT (GClosure * closure,
                                              GValue * return_value,
                                              guint n_param_values,
                                              const GValue * param_values,
                                              gpointer invocation_hint,
                                              gpointer marshal_data);
static void _metadata_writer_on_update_completed_completion_callback (BackgroundJob* job,
                                                               gpointer self);
static void _metadata_writer_on_update_cancelled_cancellation_callback (BackgroundJob* job,
                                                                 gpointer self);
static void metadata_writer_commit_job_real_execute (BackgroundJob* base);
static void metadata_writer_commit_job_commit_master (MetadataWriterCommitJob* self,
                                               GError** error);
static void metadata_writer_commit_job_commit_editable (MetadataWriterCommitJob* self,
                                                 GError** error);
static gboolean metadata_writer_commit_job_update_metadata (MetadataWriterCommitJob* self,
                                                     PhotoMetadata* metadata,
                                                     gboolean skip_orientation);
static void metadata_writer_commit_job_finalize (BackgroundJob * obj);
static GType metadata_writer_commit_job_get_type_once (void);
static void metadata_writer_finalize (GObject * obj);
static GType metadata_writer_get_type_once (void);

static const gchar* METADATA_WRITER_INTERESTED_PHOTO_METADATA_DETAILS[3] = {"name", "comment", "exposure-time"};

static inline gpointer
metadata_writer_get_instance_private (MetadataWriter* self)
{
	return G_STRUCT_MEMBER_P (self, MetadataWriter_private_offset);
}

static void
_metadata_writer_on_importing_photos_media_source_collection_media_import_starting (MediaSourceCollection* _sender,
                                                                                    GeeCollection* media,
                                                                                    gpointer self)
{
	metadata_writer_on_importing_photos ((MetadataWriter*) self, media);
}

static void
_metadata_writer_on_photos_imported_media_source_collection_media_import_completed (MediaSourceCollection* _sender,
                                                                                    GeeCollection* media,
                                                                                    gpointer self)
{
	metadata_writer_on_photos_imported ((MetadataWriter*) self, media);
}

static void
_metadata_writer_on_photos_added_removed_data_collection_contents_altered (DataCollection* _sender,
                                                                           GeeIterable* added,
                                                                           GeeIterable* removed,
                                                                           gpointer self)
{
	metadata_writer_on_photos_added_removed ((MetadataWriter*) self, added, removed);
}

static void
_metadata_writer_on_photos_altered_data_collection_items_altered (DataCollection* _sender,
                                                                  GeeMap* items,
                                                                  gpointer self)
{
	metadata_writer_on_photos_altered ((MetadataWriter*) self, items);
}

static void
_metadata_writer_on_collection_frozen_data_collection_frozen (DataCollection* _sender,
                                                              gpointer self)
{
	metadata_writer_on_collection_frozen ((MetadataWriter*) self);
}

static void
_metadata_writer_on_collection_thawed_data_collection_thawed (DataCollection* _sender,
                                                              gpointer self)
{
	metadata_writer_on_collection_thawed ((MetadataWriter*) self);
}

static void
_metadata_writer_on_photos_destroyed_source_collection_items_destroyed (SourceCollection* _sender,
                                                                        GeeCollection* destroyed,
                                                                        gpointer self)
{
	metadata_writer_on_photos_destroyed ((MetadataWriter*) self, destroyed);
}

static void
_metadata_writer_on_tags_altered_data_collection_items_altered (DataCollection* _sender,
                                                                GeeMap* items,
                                                                gpointer self)
{
	metadata_writer_on_tags_altered ((MetadataWriter*) self, items);
}

static void
_metadata_writer_on_tag_contents_altered_container_source_collection_container_contents_altered (ContainerSourceCollection* _sender,
                                                                                                 ContainerSource* container,
                                                                                                 GeeCollection* added,
                                                                                                 gboolean relinked,
                                                                                                 GeeCollection* removed,
                                                                                                 gboolean unlinked,
                                                                                                 gpointer self)
{
	metadata_writer_on_tag_contents_altered ((MetadataWriter*) self, container, added, relinked, removed, unlinked);
}

static void
_metadata_writer_on_tag_backlink_removed_container_source_collection_backlink_to_container_removed (ContainerSourceCollection* _sender,
                                                                                                    ContainerSource* container,
                                                                                                    GeeCollection* sources,
                                                                                                    gpointer self)
{
	metadata_writer_on_tag_backlink_removed ((MetadataWriter*) self, container, sources);
}

static void
_metadata_writer_on_application_exiting_photos_application_exiting (PhotosApplication* _sender,
                                                                    gboolean panicked,
                                                                    gpointer self)
{
	metadata_writer_on_application_exiting ((MetadataWriter*) self);
}

static void
_metadata_writer_on_monitor_installed_library_monitor_pool_monitor_installed (LibraryMonitorPool* _sender,
                                                                              LibraryMonitor* monitor,
                                                                              gpointer self)
{
	metadata_writer_on_monitor_installed ((MetadataWriter*) self, monitor);
}

static void
_metadata_writer_on_monitor_destroyed_library_monitor_pool_monitor_destroyed (LibraryMonitorPool* _sender,
                                                                              LibraryMonitor* monitor,
                                                                              gpointer self)
{
	metadata_writer_on_monitor_destroyed ((MetadataWriter*) self, monitor);
}

static void
_metadata_writer_on_photo_dequeued_dequeued_callback (gconstpointer item,
                                                      gpointer self)
{
	metadata_writer_on_photo_dequeued ((MetadataWriter*) self, (LibraryPhoto*) item);
}

static void
_metadata_writer_on_config_changed_g_settings_changed (GSettings* _sender,
                                                       const gchar* key,
                                                       gpointer self)
{
	metadata_writer_on_config_changed ((MetadataWriter*) self, key);
}

static MetadataWriter*
metadata_writer_construct (GType object_type)
{
	MetadataWriter * self = NULL;
	GSettings* _tmp0_;
	HashTimedQueue* _tmp1_;
	HashTimedQueue* _tmp2_;
	GSettings* _tmp6_;
	GSettings* _tmp7_;
	LibraryPhotoSourceCollection* _tmp8_;
	LibraryPhotoSourceCollection* _tmp9_;
	LibraryPhotoSourceCollection* _tmp10_;
	LibraryPhotoSourceCollection* _tmp11_;
	LibraryPhotoSourceCollection* _tmp12_;
	LibraryPhotoSourceCollection* _tmp13_;
	LibraryPhotoSourceCollection* _tmp14_;
	TagSourceCollection* _tmp15_;
	TagSourceCollection* _tmp16_;
	TagSourceCollection* _tmp17_;
	TagSourceCollection* _tmp18_;
	TagSourceCollection* _tmp19_;
	GApplication* _tmp20_;
	LibraryMonitorPool* _tmp21_;
	LibraryMonitorPool* _tmp22_;
	LibraryMonitorPool* _tmp23_;
	LibraryMonitorPool* _tmp24_;
	self = (MetadataWriter*) g_object_new (object_type, NULL);
	_tmp0_ = g_settings_new (GSETTINGS_CONFIGURATION_ENGINE_FILES_PREFS_SCHEMA_NAME);
	_g_object_unref0 (self->priv->file_settings);
	self->priv->file_settings = _tmp0_;
	_tmp1_ = hash_timed_queue_new (TYPE_LIBRARY_PHOTO, (GBoxedCopyFunc) g_object_ref, (GDestroyNotify) g_object_unref, METADATA_WRITER_COMMIT_DELAY_MSEC, _metadata_writer_on_photo_dequeued_dequeued_callback, self, NULL, NULL, NULL, NULL, NULL, NULL, G_PRIORITY_DEFAULT);
	_timed_queue_unref0 (self->priv->dirty);
	self->priv->dirty = _tmp1_;
	_tmp2_ = self->priv->dirty;
	timed_queue_set_dequeue_spacing_msec ((TimedQueue*) _tmp2_, METADATA_WRITER_COMMIT_SPACING_MSEC);
	metadata_writer_pause (self);
	{
		const gchar** detail_collection = NULL;
		gint detail_collection_length1 = 0;
		gint _detail_collection_size_ = 0;
		gint detail_it = 0;
		detail_collection = METADATA_WRITER_INTERESTED_PHOTO_METADATA_DETAILS;
		detail_collection_length1 = G_N_ELEMENTS (METADATA_WRITER_INTERESTED_PHOTO_METADATA_DETAILS);
		for (detail_it = 0; detail_it < detail_collection_length1; detail_it = detail_it + 1) {
			gchar* _tmp3_;
			gchar* detail = NULL;
			_tmp3_ = g_strdup (detail_collection[detail_it]);
			detail = _tmp3_;
			{
				GeeHashSet* _tmp4_;
				const gchar* _tmp5_;
				_tmp4_ = self->priv->interested_photo_details;
				_tmp5_ = detail;
				gee_abstract_collection_add ((GeeAbstractCollection*) _tmp4_, _tmp5_);
				_g_free0 (detail);
			}
		}
	}
	_tmp6_ = self->priv->file_settings;
	self->priv->enabled = g_settings_get_boolean (_tmp6_, "commit-metadata");
	_tmp7_ = self->priv->file_settings;
	g_signal_connect_object (_tmp7_, "changed", (GCallback) _metadata_writer_on_config_changed_g_settings_changed, self, 0);
	metadata_writer_force_rescan (self);
	_tmp8_ = library_photo_global;
	g_signal_connect_object ((MediaSourceCollection*) _tmp8_, "media-import-starting", (GCallback) _metadata_writer_on_importing_photos_media_source_collection_media_import_starting, self, 0);
	_tmp9_ = library_photo_global;
	g_signal_connect_object ((MediaSourceCollection*) _tmp9_, "media-import-completed", (GCallback) _metadata_writer_on_photos_imported_media_source_collection_media_import_completed, self, 0);
	_tmp10_ = library_photo_global;
	g_signal_connect_object ((DataCollection*) _tmp10_, "contents-altered", (GCallback) _metadata_writer_on_photos_added_removed_data_collection_contents_altered, self, 0);
	_tmp11_ = library_photo_global;
	g_signal_connect_object ((DataCollection*) _tmp11_, "items-altered", (GCallback) _metadata_writer_on_photos_altered_data_collection_items_altered, self, 0);
	_tmp12_ = library_photo_global;
	g_signal_connect_object ((DataCollection*) _tmp12_, "frozen", (GCallback) _metadata_writer_on_collection_frozen_data_collection_frozen, self, 0);
	_tmp13_ = library_photo_global;
	g_signal_connect_object ((DataCollection*) _tmp13_, "thawed", (GCallback) _metadata_writer_on_collection_thawed_data_collection_thawed, self, 0);
	_tmp14_ = library_photo_global;
	g_signal_connect_object ((SourceCollection*) _tmp14_, "items-destroyed", (GCallback) _metadata_writer_on_photos_destroyed_source_collection_items_destroyed, self, 0);
	_tmp15_ = tag_global;
	g_signal_connect_object ((DataCollection*) _tmp15_, "items-altered", (GCallback) _metadata_writer_on_tags_altered_data_collection_items_altered, self, 0);
	_tmp16_ = tag_global;
	g_signal_connect_object ((ContainerSourceCollection*) _tmp16_, "container-contents-altered", (GCallback) _metadata_writer_on_tag_contents_altered_container_source_collection_container_contents_altered, self, 0);
	_tmp17_ = tag_global;
	g_signal_connect_object ((ContainerSourceCollection*) _tmp17_, "backlink-to-container-removed", (GCallback) _metadata_writer_on_tag_backlink_removed_container_source_collection_backlink_to_container_removed, self, 0);
	_tmp18_ = tag_global;
	g_signal_connect_object ((DataCollection*) _tmp18_, "frozen", (GCallback) _metadata_writer_on_collection_frozen_data_collection_frozen, self, 0);
	_tmp19_ = tag_global;
	g_signal_connect_object ((DataCollection*) _tmp19_, "thawed", (GCallback) _metadata_writer_on_collection_thawed_data_collection_thawed, self, 0);
	_tmp20_ = g_application_get_default ();
	g_signal_connect_object (G_TYPE_CHECK_INSTANCE_CAST (_tmp20_, PHOTOS_TYPE_APPLICATION, PhotosApplication), "exiting", (GCallback) _metadata_writer_on_application_exiting_photos_application_exiting, self, 0);
	_tmp21_ = library_monitor_pool_get_instance ();
	_tmp22_ = _tmp21_;
	g_signal_connect_object (_tmp22_, "monitor-installed", (GCallback) _metadata_writer_on_monitor_installed_library_monitor_pool_monitor_installed, self, 0);
	_library_monitor_pool_unref0 (_tmp22_);
	_tmp23_ = library_monitor_pool_get_instance ();
	_tmp24_ = _tmp23_;
	g_signal_connect_object (_tmp24_, "monitor-destroyed", (GCallback) _metadata_writer_on_monitor_destroyed_library_monitor_pool_monitor_destroyed, self, 0);
	_library_monitor_pool_unref0 (_tmp24_);
	return self;
}

static MetadataWriter*
metadata_writer_new (void)
{
	return metadata_writer_construct (TYPE_METADATA_WRITER);
}

void
metadata_writer_init (void)
{
	MetadataWriter* _tmp0_;
	_tmp0_ = metadata_writer_new ();
	_g_object_unref0 (metadata_writer_instance);
	metadata_writer_instance = _tmp0_;
}

void
metadata_writer_terminate (void)
{
	MetadataWriter* _tmp0_;
	_tmp0_ = metadata_writer_instance;
	if (_tmp0_ != NULL) {
		MetadataWriter* _tmp1_;
		_tmp1_ = metadata_writer_instance;
		metadata_writer_close (_tmp1_);
	}
	_g_object_unref0 (metadata_writer_instance);
	metadata_writer_instance = NULL;
}

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

MetadataWriter*
metadata_writer_get_instance (void)
{
	MetadataWriter* _tmp0_;
	MetadataWriter* _tmp1_;
	MetadataWriter* result;
	_tmp0_ = metadata_writer_instance;
	_tmp1_ = _g_object_ref0 (_tmp0_);
	result = _tmp1_;
	return result;
}

void
metadata_writer_force_rescan (MetadataWriter* self)
{
	LibraryPhotoSourceCollection* _tmp0_;
	GeeCollection* _tmp1_;
	GeeCollection* _tmp2_;
	g_return_if_fail (self != NULL);
	_tmp0_ = library_photo_global;
	_tmp1_ = data_collection_get_all ((DataCollection*) _tmp0_);
	_tmp2_ = G_TYPE_CHECK_INSTANCE_CAST (_tmp1_, GEE_TYPE_COLLECTION, GeeCollection);
	metadata_writer_schedule_if_dirty (self, (GeeIterable*) _tmp2_, "force rescan");
	_g_object_unref0 (_tmp2_);
}

void
metadata_writer_pause (MetadataWriter* self)
{
	gint _tmp0_;
	HashTimedQueue* _tmp1_;
	g_return_if_fail (self != NULL);
	_tmp0_ = self->priv->pause_count;
	self->priv->pause_count = _tmp0_ + 1;
	if (_tmp0_ != 0) {
		return;
	}
	_tmp1_ = self->priv->dirty;
	timed_queue_pause ((TimedQueue*) _tmp1_);
	g_signal_emit (self, metadata_writer_signals[METADATA_WRITER_PROGRESS_SIGNAL], 0, (guint) 0, (guint) 0);
}

void
metadata_writer_unpause (MetadataWriter* self)
{
	gboolean _tmp0_ = FALSE;
	HashTimedQueue* _tmp2_;
	g_return_if_fail (self != NULL);
	if (self->priv->pause_count == 0) {
		_tmp0_ = TRUE;
	} else {
		gint _tmp1_;
		self->priv->pause_count = self->priv->pause_count - 1;
		_tmp1_ = self->priv->pause_count;
		_tmp0_ = _tmp1_ != 0;
	}
	if (_tmp0_) {
		return;
	}
	_tmp2_ = self->priv->dirty;
	timed_queue_unpause ((TimedQueue*) _tmp2_);
}

void
metadata_writer_close (MetadataWriter* self)
{
	g_return_if_fail (self != NULL);
	if (self->priv->closed) {
		return;
	}
	metadata_writer_cancel_all (self, TRUE);
	self->priv->closed = TRUE;
}

static void
metadata_writer_on_config_changed (MetadataWriter* self,
                                   const gchar* key)
{
	gboolean value = FALSE;
	GSettings* _tmp0_;
	g_return_if_fail (self != NULL);
	g_return_if_fail (key != NULL);
	if (g_strcmp0 (key, "commit-metadata") != 0) {
		return;
	}
	_tmp0_ = self->priv->file_settings;
	value = g_settings_get_boolean (_tmp0_, "commit-metadata");
	if (self->priv->enabled == value) {
		return;
	}
	self->priv->enabled = value;
	if (self->priv->enabled) {
		metadata_writer_force_rescan (self);
	} else {
		metadata_writer_cancel_all (self, FALSE);
	}
}

static void
metadata_writer_on_application_exiting (MetadataWriter* self)
{
	g_return_if_fail (self != NULL);
	metadata_writer_close (self);
}

static void
_metadata_writer_on_discovery_completed_directory_monitor_discovery_completed (DirectoryMonitor* _sender,
                                                                               gpointer self)
{
	metadata_writer_on_discovery_completed ((MetadataWriter*) self);
}

static void
metadata_writer_on_monitor_installed (MetadataWriter* self,
                                      LibraryMonitor* monitor)
{
	g_return_if_fail (self != NULL);
	g_return_if_fail (monitor != NULL);
	g_signal_connect_object ((DirectoryMonitor*) monitor, "discovery-completed", (GCallback) _metadata_writer_on_discovery_completed_directory_monitor_discovery_completed, self, 0);
}

static void
metadata_writer_on_monitor_destroyed (MetadataWriter* self,
                                      LibraryMonitor* monitor)
{
	guint _tmp0_;
	g_return_if_fail (self != NULL);
	g_return_if_fail (monitor != NULL);
	g_signal_parse_name ("discovery-completed", TYPE_DIRECTORY_MONITOR, &_tmp0_, NULL, FALSE);
	g_signal_handlers_disconnect_matched ((DirectoryMonitor*) monitor, G_SIGNAL_MATCH_ID | G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA, _tmp0_, 0, NULL, (GCallback) _metadata_writer_on_discovery_completed_directory_monitor_discovery_completed, self);
}

static void
metadata_writer_on_discovery_completed (MetadataWriter* self)
{
	g_return_if_fail (self != NULL);
	metadata_writer_unpause (self);
}

static void
metadata_writer_on_collection_frozen (MetadataWriter* self)
{
	g_return_if_fail (self != NULL);
	metadata_writer_pause (self);
}

static void
metadata_writer_on_collection_thawed (MetadataWriter* self)
{
	g_return_if_fail (self != NULL);
	metadata_writer_unpause (self);
}

static void
metadata_writer_on_importing_photos (MetadataWriter* self,
                                     GeeCollection* media_sources)
{
	GeeHashSet* _tmp0_;
	g_return_if_fail (self != NULL);
	g_return_if_fail (media_sources != NULL);
	_tmp0_ = self->priv->importing_photos;
	gee_collection_add_all ((GeeCollection*) _tmp0_, G_TYPE_CHECK_INSTANCE_CAST (media_sources, GEE_TYPE_COLLECTION, GeeCollection));
}

static void
metadata_writer_on_photos_imported (MetadataWriter* self,
                                    GeeCollection* media_sources)
{
	GeeHashSet* _tmp0_;
	g_return_if_fail (self != NULL);
	g_return_if_fail (media_sources != NULL);
	_tmp0_ = self->priv->importing_photos;
	gee_collection_remove_all ((GeeCollection*) _tmp0_, G_TYPE_CHECK_INSTANCE_CAST (media_sources, GEE_TYPE_COLLECTION, GeeCollection));
}

static void
metadata_writer_on_photos_added_removed (MetadataWriter* self,
                                         GeeIterable* added,
                                         GeeIterable* removed)
{
	gboolean _tmp0_ = FALSE;
	g_return_if_fail (self != NULL);
	if (added != NULL) {
		_tmp0_ = self->priv->enabled;
	} else {
		_tmp0_ = FALSE;
	}
	if (_tmp0_) {
		metadata_writer_schedule_if_dirty (self, G_TYPE_CHECK_INSTANCE_CAST (added, GEE_TYPE_ITERABLE, GeeIterable), "added to LibraryPhoto.global");
	}
	if (removed != NULL) {
		gboolean cancelled = FALSE;
		cancelled = FALSE;
		{
			GeeIterator* _object_it = NULL;
			GeeIterator* _tmp1_;
			_tmp1_ = gee_iterable_iterator (removed);
			_object_it = _tmp1_;
			while (TRUE) {
				GeeIterator* _tmp2_;
				DataObject* object = NULL;
				GeeIterator* _tmp3_;
				gpointer _tmp4_;
				gboolean _tmp5_ = FALSE;
				DataObject* _tmp6_;
				_tmp2_ = _object_it;
				if (!gee_iterator_next (_tmp2_)) {
					break;
				}
				_tmp3_ = _object_it;
				_tmp4_ = gee_iterator_get (_tmp3_);
				object = (DataObject*) _tmp4_;
				_tmp6_ = object;
				if (metadata_writer_cancel_job (self, G_TYPE_CHECK_INSTANCE_CAST (_tmp6_, TYPE_LIBRARY_PHOTO, LibraryPhoto))) {
					_tmp5_ = TRUE;
				} else {
					_tmp5_ = cancelled;
				}
				cancelled = _tmp5_;
				_g_object_unref0 (object);
			}
			_g_object_unref0 (_object_it);
		}
		if (cancelled) {
			g_signal_emit (self, metadata_writer_signals[METADATA_WRITER_PROGRESS_SIGNAL], 0, self->priv->outstanding_completed, self->priv->outstanding_total);
		}
	}
}

static void
metadata_writer_on_photos_altered (MetadataWriter* self,
                                   GeeMap* items)
{
	GeeHashSet* photos = NULL;
	GeeHashSet* _tmp33_;
	g_return_if_fail (self != NULL);
	g_return_if_fail (items != NULL);
	photos = NULL;
	{
		GeeIterator* _object_it = NULL;
		GeeSet* _tmp0_;
		GeeSet* _tmp1_;
		GeeSet* _tmp2_;
		GeeIterator* _tmp3_;
		GeeIterator* _tmp4_;
		_tmp0_ = gee_map_get_keys (items);
		_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_;
			LibraryPhoto* photo = NULL;
			DataObject* _tmp8_;
			LibraryPhoto* _tmp9_;
			LibraryPhoto* _tmp10_;
			LibraryPhoto* _tmp11_;
			Alteration* alteration = NULL;
			DataObject* _tmp12_;
			gpointer _tmp13_;
			Alteration* _tmp14_;
			GeeCollection* details = NULL;
			Alteration* _tmp19_;
			GeeCollection* _tmp20_;
			GeeCollection* _tmp21_;
			_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_LIBRARY_PHOTO, LibraryPhoto));
			photo = _tmp9_;
			_tmp10_ = photo;
			_tmp11_ = self->priv->ignore_photo_alteration;
			if (_tmp10_ == _tmp11_) {
				_g_object_unref0 (photo);
				_g_object_unref0 (object);
				continue;
			}
			_tmp12_ = object;
			_tmp13_ = gee_map_get (items, _tmp12_);
			alteration = (Alteration*) _tmp13_;
			_tmp14_ = alteration;
			if (alteration_has_detail (_tmp14_, "image", "orientation")) {
				GeeHashSet* _tmp15_;
				GeeHashSet* _tmp17_;
				LibraryPhoto* _tmp18_;
				_tmp15_ = photos;
				if (_tmp15_ == NULL) {
					GeeHashSet* _tmp16_;
					_tmp16_ = gee_hash_set_new (TYPE_LIBRARY_PHOTO, (GBoxedCopyFunc) g_object_ref, (GDestroyNotify) g_object_unref, NULL, NULL, NULL, NULL, NULL, NULL);
					_g_object_unref0 (photos);
					photos = _tmp16_;
				}
				_tmp17_ = photos;
				_tmp18_ = photo;
				gee_abstract_collection_add ((GeeAbstractCollection*) _tmp17_, _tmp18_);
				_alteration_unref0 (alteration);
				_g_object_unref0 (photo);
				_g_object_unref0 (object);
				continue;
			}
			_tmp19_ = alteration;
			_tmp20_ = alteration_get_details (_tmp19_, "metadata");
			details = _tmp20_;
			_tmp21_ = details;
			if (_tmp21_ == NULL) {
				_g_object_unref0 (details);
				_alteration_unref0 (alteration);
				_g_object_unref0 (photo);
				_g_object_unref0 (object);
				continue;
			}
			{
				GeeIterator* _detail_it = NULL;
				GeeCollection* _tmp22_;
				GeeIterator* _tmp23_;
				_tmp22_ = details;
				_tmp23_ = gee_iterable_iterator ((GeeIterable*) _tmp22_);
				_detail_it = _tmp23_;
				while (TRUE) {
					GeeIterator* _tmp24_;
					gchar* detail = NULL;
					GeeIterator* _tmp25_;
					gpointer _tmp26_;
					GeeHashSet* _tmp27_;
					const gchar* _tmp28_;
					_tmp24_ = _detail_it;
					if (!gee_iterator_next (_tmp24_)) {
						break;
					}
					_tmp25_ = _detail_it;
					_tmp26_ = gee_iterator_get (_tmp25_);
					detail = (gchar*) _tmp26_;
					_tmp27_ = self->priv->interested_photo_details;
					_tmp28_ = detail;
					if (gee_abstract_collection_contains ((GeeAbstractCollection*) _tmp27_, _tmp28_)) {
						GeeHashSet* _tmp29_;
						GeeHashSet* _tmp31_;
						LibraryPhoto* _tmp32_;
						_tmp29_ = photos;
						if (_tmp29_ == NULL) {
							GeeHashSet* _tmp30_;
							_tmp30_ = gee_hash_set_new (TYPE_LIBRARY_PHOTO, (GBoxedCopyFunc) g_object_ref, (GDestroyNotify) g_object_unref, NULL, NULL, NULL, NULL, NULL, NULL);
							_g_object_unref0 (photos);
							photos = _tmp30_;
						}
						_tmp31_ = photos;
						_tmp32_ = photo;
						gee_abstract_collection_add ((GeeAbstractCollection*) _tmp31_, _tmp32_);
						_g_free0 (detail);
						break;
					}
					_g_free0 (detail);
				}
				_g_object_unref0 (_detail_it);
			}
			_g_object_unref0 (details);
			_alteration_unref0 (alteration);
			_g_object_unref0 (photo);
			_g_object_unref0 (object);
		}
		_g_object_unref0 (_object_it);
	}
	_tmp33_ = photos;
	if (_tmp33_ != NULL) {
		GeeHashSet* _tmp34_;
		_tmp34_ = photos;
		metadata_writer_photos_are_dirty (self, (GeeCollection*) _tmp34_, "alteration", FALSE);
	}
	_g_object_unref0 (photos);
}

static void
metadata_writer_on_photos_destroyed (MetadataWriter* self,
                                     GeeCollection* destroyed)
{
	g_return_if_fail (self != NULL);
	g_return_if_fail (destroyed != NULL);
	{
		GeeIterator* _source_it = NULL;
		GeeIterator* _tmp0_;
		_tmp0_ = gee_iterable_iterator ((GeeIterable*) destroyed);
		_source_it = _tmp0_;
		while (TRUE) {
			GeeIterator* _tmp1_;
			DataSource* source = NULL;
			GeeIterator* _tmp2_;
			gpointer _tmp3_;
			LibraryPhoto* photo = NULL;
			DataSource* _tmp4_;
			LibraryPhoto* _tmp5_;
			LibraryPhoto* _tmp6_;
			GeeHashSet* _tmp7_;
			LibraryPhoto* _tmp8_;
			_tmp1_ = _source_it;
			if (!gee_iterator_next (_tmp1_)) {
				break;
			}
			_tmp2_ = _source_it;
			_tmp3_ = gee_iterator_get (_tmp2_);
			source = (DataSource*) _tmp3_;
			_tmp4_ = source;
			_tmp5_ = _g_object_ref0 (G_TYPE_CHECK_INSTANCE_CAST (_tmp4_, TYPE_LIBRARY_PHOTO, LibraryPhoto));
			photo = _tmp5_;
			_tmp6_ = photo;
			metadata_writer_cancel_job (self, _tmp6_);
			_tmp7_ = self->priv->importing_photos;
			_tmp8_ = photo;
			gee_abstract_collection_remove ((GeeAbstractCollection*) _tmp7_, _tmp8_);
			_g_object_unref0 (photo);
			_g_object_unref0 (source);
		}
		_g_object_unref0 (_source_it);
	}
}

static void
metadata_writer_on_tags_altered (MetadataWriter* self,
                                 GeeMap* map)
{
	GeeHashSet* photos = NULL;
	GeeHashSet* _tmp27_;
	g_return_if_fail (self != NULL);
	g_return_if_fail (map != NULL);
	photos = 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_;
			DataObject* _tmp8_;
			gpointer _tmp9_;
			Alteration* _tmp10_;
			gboolean _tmp11_;
			GeeHashSet* _tmp12_;
			_tmp5_ = _object_it;
			if (!gee_iterator_next (_tmp5_)) {
				break;
			}
			_tmp6_ = _object_it;
			_tmp7_ = gee_iterator_get (_tmp6_);
			object = (DataObject*) _tmp7_;
			_tmp8_ = object;
			_tmp9_ = gee_map_get (map, _tmp8_);
			_tmp10_ = (Alteration*) _tmp9_;
			_tmp11_ = !alteration_has_detail (_tmp10_, "metadata", "name");
			_alteration_unref0 (_tmp10_);
			if (_tmp11_) {
				_g_object_unref0 (object);
				continue;
			}
			_tmp12_ = photos;
			if (_tmp12_ == NULL) {
				GeeHashSet* _tmp13_;
				_tmp13_ = gee_hash_set_new (TYPE_LIBRARY_PHOTO, (GBoxedCopyFunc) g_object_ref, (GDestroyNotify) g_object_unref, NULL, NULL, NULL, NULL, NULL, NULL);
				_g_object_unref0 (photos);
				photos = _tmp13_;
			}
			{
				GeeIterator* _media_it = NULL;
				DataObject* _tmp14_;
				GeeCollection* _tmp15_;
				GeeCollection* _tmp16_;
				GeeIterator* _tmp17_;
				GeeIterator* _tmp18_;
				_tmp14_ = object;
				_tmp15_ = tag_get_sources (G_TYPE_CHECK_INSTANCE_CAST (_tmp14_, TYPE_TAG, Tag));
				_tmp16_ = _tmp15_;
				_tmp17_ = gee_iterable_iterator ((GeeIterable*) _tmp16_);
				_tmp18_ = _tmp17_;
				_g_object_unref0 (_tmp16_);
				_media_it = _tmp18_;
				while (TRUE) {
					GeeIterator* _tmp19_;
					MediaSource* media = NULL;
					GeeIterator* _tmp20_;
					gpointer _tmp21_;
					LibraryPhoto* photo = NULL;
					MediaSource* _tmp22_;
					LibraryPhoto* _tmp23_;
					LibraryPhoto* _tmp24_;
					_tmp19_ = _media_it;
					if (!gee_iterator_next (_tmp19_)) {
						break;
					}
					_tmp20_ = _media_it;
					_tmp21_ = gee_iterator_get (_tmp20_);
					media = (MediaSource*) _tmp21_;
					_tmp22_ = media;
					_tmp23_ = _g_object_ref0 (IS_LIBRARY_PHOTO (_tmp22_) ? ((LibraryPhoto*) _tmp22_) : NULL);
					photo = _tmp23_;
					_tmp24_ = photo;
					if (_tmp24_ != NULL) {
						GeeHashSet* _tmp25_;
						LibraryPhoto* _tmp26_;
						_tmp25_ = photos;
						_tmp26_ = photo;
						gee_abstract_collection_add ((GeeAbstractCollection*) _tmp25_, _tmp26_);
					}
					_g_object_unref0 (photo);
					_g_object_unref0 (media);
				}
				_g_object_unref0 (_media_it);
			}
			_g_object_unref0 (object);
		}
		_g_object_unref0 (_object_it);
	}
	_tmp27_ = photos;
	if (_tmp27_ != NULL) {
		GeeHashSet* _tmp28_;
		_tmp28_ = photos;
		metadata_writer_photos_are_dirty (self, (GeeCollection*) _tmp28_, "tag renamed", FALSE);
	}
	_g_object_unref0 (photos);
}

static void
metadata_writer_on_tag_contents_altered (MetadataWriter* self,
                                         ContainerSource* container,
                                         GeeCollection* added,
                                         gboolean relinking,
                                         GeeCollection* removed,
                                         gboolean unlinking)
{
	Tag* tag = NULL;
	Tag* _tmp0_;
	gboolean _tmp1_ = FALSE;
	gboolean _tmp21_ = FALSE;
	g_return_if_fail (self != NULL);
	g_return_if_fail (container != NULL);
	_tmp0_ = _g_object_ref0 (G_TYPE_CHECK_INSTANCE_CAST (container, TYPE_TAG, Tag));
	tag = _tmp0_;
	if (added != NULL) {
		_tmp1_ = !relinking;
	} else {
		_tmp1_ = FALSE;
	}
	if (_tmp1_) {
		GeeArrayList* added_photos = NULL;
		GeeArrayList* _tmp2_;
		GeeArrayList* _tmp15_;
		Tag* _tmp16_;
		gchar* _tmp17_;
		gchar* _tmp18_;
		gchar* _tmp19_;
		gchar* _tmp20_;
		_tmp2_ = gee_array_list_new (TYPE_LIBRARY_PHOTO, (GBoxedCopyFunc) g_object_ref, (GDestroyNotify) g_object_unref, NULL, NULL, NULL);
		added_photos = _tmp2_;
		{
			GeeIterator* _source_it = NULL;
			GeeIterator* _tmp3_;
			_tmp3_ = gee_iterable_iterator ((GeeIterable*) added);
			_source_it = _tmp3_;
			while (TRUE) {
				GeeIterator* _tmp4_;
				DataSource* source = NULL;
				GeeIterator* _tmp5_;
				gpointer _tmp6_;
				LibraryPhoto* photo = NULL;
				DataSource* _tmp7_;
				LibraryPhoto* _tmp8_;
				gboolean _tmp9_ = FALSE;
				LibraryPhoto* _tmp10_;
				_tmp4_ = _source_it;
				if (!gee_iterator_next (_tmp4_)) {
					break;
				}
				_tmp5_ = _source_it;
				_tmp6_ = gee_iterator_get (_tmp5_);
				source = (DataSource*) _tmp6_;
				_tmp7_ = source;
				_tmp8_ = _g_object_ref0 (IS_LIBRARY_PHOTO (_tmp7_) ? ((LibraryPhoto*) _tmp7_) : NULL);
				photo = _tmp8_;
				_tmp10_ = photo;
				if (_tmp10_ != NULL) {
					GeeHashSet* _tmp11_;
					LibraryPhoto* _tmp12_;
					_tmp11_ = self->priv->importing_photos;
					_tmp12_ = photo;
					_tmp9_ = !gee_abstract_collection_contains ((GeeAbstractCollection*) _tmp11_, _tmp12_);
				} else {
					_tmp9_ = FALSE;
				}
				if (_tmp9_) {
					GeeArrayList* _tmp13_;
					LibraryPhoto* _tmp14_;
					_tmp13_ = added_photos;
					_tmp14_ = photo;
					gee_abstract_collection_add ((GeeAbstractCollection*) _tmp13_, _tmp14_);
				}
				_g_object_unref0 (photo);
				_g_object_unref0 (source);
			}
			_g_object_unref0 (_source_it);
		}
		_tmp15_ = added_photos;
		_tmp16_ = tag;
		_tmp17_ = data_object_to_string ((DataObject*) _tmp16_);
		_tmp18_ = _tmp17_;
		_tmp19_ = g_strdup_printf ("added to %s", _tmp18_);
		_tmp20_ = _tmp19_;
		metadata_writer_photos_are_dirty (self, (GeeCollection*) _tmp15_, _tmp20_, FALSE);
		_g_free0 (_tmp20_);
		_g_free0 (_tmp18_);
		_g_object_unref0 (added_photos);
	}
	if (removed != NULL) {
		_tmp21_ = !unlinking;
	} else {
		_tmp21_ = FALSE;
	}
	if (_tmp21_) {
		GeeArrayList* removed_photos = NULL;
		GeeArrayList* _tmp22_;
		GeeArrayList* _tmp32_;
		Tag* _tmp33_;
		gchar* _tmp34_;
		gchar* _tmp35_;
		gchar* _tmp36_;
		gchar* _tmp37_;
		_tmp22_ = gee_array_list_new (TYPE_LIBRARY_PHOTO, (GBoxedCopyFunc) g_object_ref, (GDestroyNotify) g_object_unref, NULL, NULL, NULL);
		removed_photos = _tmp22_;
		{
			GeeIterator* _source_it = NULL;
			GeeIterator* _tmp23_;
			_tmp23_ = gee_iterable_iterator ((GeeIterable*) removed);
			_source_it = _tmp23_;
			while (TRUE) {
				GeeIterator* _tmp24_;
				DataSource* source = NULL;
				GeeIterator* _tmp25_;
				gpointer _tmp26_;
				LibraryPhoto* photo = NULL;
				DataSource* _tmp27_;
				LibraryPhoto* _tmp28_;
				LibraryPhoto* _tmp29_;
				_tmp24_ = _source_it;
				if (!gee_iterator_next (_tmp24_)) {
					break;
				}
				_tmp25_ = _source_it;
				_tmp26_ = gee_iterator_get (_tmp25_);
				source = (DataSource*) _tmp26_;
				_tmp27_ = source;
				_tmp28_ = _g_object_ref0 (IS_LIBRARY_PHOTO (_tmp27_) ? ((LibraryPhoto*) _tmp27_) : NULL);
				photo = _tmp28_;
				_tmp29_ = photo;
				if (_tmp29_ != NULL) {
					GeeArrayList* _tmp30_;
					LibraryPhoto* _tmp31_;
					_tmp30_ = removed_photos;
					_tmp31_ = photo;
					gee_abstract_collection_add ((GeeAbstractCollection*) _tmp30_, _tmp31_);
				}
				_g_object_unref0 (photo);
				_g_object_unref0 (source);
			}
			_g_object_unref0 (_source_it);
		}
		_tmp32_ = removed_photos;
		_tmp33_ = tag;
		_tmp34_ = data_object_to_string ((DataObject*) _tmp33_);
		_tmp35_ = _tmp34_;
		_tmp36_ = g_strdup_printf ("removed from %s", _tmp35_);
		_tmp37_ = _tmp36_;
		metadata_writer_photos_are_dirty (self, (GeeCollection*) _tmp32_, _tmp37_, FALSE);
		_g_free0 (_tmp37_);
		_g_free0 (_tmp35_);
		_g_object_unref0 (removed_photos);
	}
	_g_object_unref0 (tag);
}

static void
metadata_writer_on_tag_backlink_removed (MetadataWriter* self,
                                         ContainerSource* container,
                                         GeeCollection* sources)
{
	GeeArrayList* photos = NULL;
	GeeArrayList* _tmp0_;
	GeeArrayList* _tmp10_;
	gchar* _tmp11_;
	gchar* _tmp12_;
	gchar* _tmp13_;
	gchar* _tmp14_;
	g_return_if_fail (self != NULL);
	g_return_if_fail (container != NULL);
	g_return_if_fail (sources != NULL);
	_tmp0_ = gee_array_list_new (TYPE_LIBRARY_PHOTO, (GBoxedCopyFunc) g_object_ref, (GDestroyNotify) g_object_unref, NULL, NULL, NULL);
	photos = _tmp0_;
	{
		GeeIterator* _source_it = NULL;
		GeeIterator* _tmp1_;
		_tmp1_ = gee_iterable_iterator ((GeeIterable*) sources);
		_source_it = _tmp1_;
		while (TRUE) {
			GeeIterator* _tmp2_;
			DataSource* source = NULL;
			GeeIterator* _tmp3_;
			gpointer _tmp4_;
			LibraryPhoto* photo = NULL;
			DataSource* _tmp5_;
			LibraryPhoto* _tmp6_;
			LibraryPhoto* _tmp7_;
			_tmp2_ = _source_it;
			if (!gee_iterator_next (_tmp2_)) {
				break;
			}
			_tmp3_ = _source_it;
			_tmp4_ = gee_iterator_get (_tmp3_);
			source = (DataSource*) _tmp4_;
			_tmp5_ = source;
			_tmp6_ = _g_object_ref0 (IS_LIBRARY_PHOTO (_tmp5_) ? ((LibraryPhoto*) _tmp5_) : NULL);
			photo = _tmp6_;
			_tmp7_ = photo;
			if (_tmp7_ != NULL) {
				GeeArrayList* _tmp8_;
				LibraryPhoto* _tmp9_;
				_tmp8_ = photos;
				_tmp9_ = photo;
				gee_abstract_collection_add ((GeeAbstractCollection*) _tmp8_, _tmp9_);
			}
			_g_object_unref0 (photo);
			_g_object_unref0 (source);
		}
		_g_object_unref0 (_source_it);
	}
	_tmp10_ = photos;
	_tmp11_ = data_object_to_string ((DataObject*) container);
	_tmp12_ = _tmp11_;
	_tmp13_ = g_strdup_printf ("backlink removed from %s", _tmp12_);
	_tmp14_ = _tmp13_;
	metadata_writer_photos_are_dirty (self, (GeeCollection*) _tmp10_, _tmp14_, FALSE);
	_g_free0 (_tmp14_);
	_g_free0 (_tmp12_);
	_g_object_unref0 (photos);
}

static void
metadata_writer_count_enqueued_work (MetadataWriter* self,
                                     gint count,
                                     gboolean report)
{
	g_return_if_fail (self != NULL);
	self->priv->outstanding_total = self->priv->outstanding_total + count;
	if (report) {
		g_signal_emit (self, metadata_writer_signals[METADATA_WRITER_PROGRESS_SIGNAL], 0, self->priv->outstanding_completed, self->priv->outstanding_total);
	}
}

static void
metadata_writer_count_cancelled_work (MetadataWriter* self,
                                      gint count,
                                      gboolean report)
{
	guint _tmp0_ = 0U;
	g_return_if_fail (self != NULL);
	if (self->priv->outstanding_total >= ((guint) count)) {
		_tmp0_ = self->priv->outstanding_total - count;
	} else {
		_tmp0_ = (guint) 0;
	}
	self->priv->outstanding_total = _tmp0_;
	if (self->priv->outstanding_completed >= self->priv->outstanding_total) {
		self->priv->outstanding_completed = (guint) 0;
		self->priv->outstanding_total = (guint) 0;
	}
	if (report) {
		g_signal_emit (self, metadata_writer_signals[METADATA_WRITER_PROGRESS_SIGNAL], 0, self->priv->outstanding_completed, self->priv->outstanding_total);
	}
}

static void
metadata_writer_count_completed_work (MetadataWriter* self,
                                      gint count,
                                      gboolean report)
{
	g_return_if_fail (self != NULL);
	self->priv->outstanding_completed = self->priv->outstanding_completed + count;
	if (self->priv->outstanding_completed >= self->priv->outstanding_total) {
		self->priv->outstanding_completed = (guint) 0;
		self->priv->outstanding_total = (guint) 0;
	}
	if (report) {
		g_signal_emit (self, metadata_writer_signals[METADATA_WRITER_PROGRESS_SIGNAL], 0, self->priv->outstanding_completed, self->priv->outstanding_total);
	}
}

static void
metadata_writer_schedule_if_dirty (MetadataWriter* self,
                                   GeeIterable* media_sources,
                                   const gchar* reason)
{
	GeeArrayList* photos = NULL;
	GeeArrayList* _tmp14_;
	g_return_if_fail (self != NULL);
	g_return_if_fail (media_sources != NULL);
	g_return_if_fail (reason != NULL);
	photos = NULL;
	{
		GeeIterator* _media_it = NULL;
		GeeIterator* _tmp0_;
		_tmp0_ = gee_iterable_iterator (media_sources);
		_media_it = _tmp0_;
		while (TRUE) {
			GeeIterator* _tmp1_;
			MediaSource* media = NULL;
			GeeIterator* _tmp2_;
			gpointer _tmp3_;
			LibraryPhoto* photo = NULL;
			MediaSource* _tmp4_;
			LibraryPhoto* _tmp5_;
			LibraryPhoto* _tmp6_;
			GeeHashSet* _tmp7_;
			LibraryPhoto* _tmp8_;
			LibraryPhoto* _tmp9_;
			_tmp1_ = _media_it;
			if (!gee_iterator_next (_tmp1_)) {
				break;
			}
			_tmp2_ = _media_it;
			_tmp3_ = gee_iterator_get (_tmp2_);
			media = (MediaSource*) _tmp3_;
			_tmp4_ = media;
			_tmp5_ = _g_object_ref0 (IS_LIBRARY_PHOTO (_tmp4_) ? ((LibraryPhoto*) _tmp4_) : NULL);
			photo = _tmp5_;
			_tmp6_ = photo;
			if (_tmp6_ == NULL) {
				_g_object_unref0 (photo);
				_g_object_unref0 (media);
				continue;
			}
			_tmp7_ = self->priv->importing_photos;
			_tmp8_ = photo;
			if (gee_abstract_collection_contains ((GeeAbstractCollection*) _tmp7_, _tmp8_)) {
				_g_object_unref0 (photo);
				_g_object_unref0 (media);
				continue;
			}
			_tmp9_ = photo;
			if (photo_is_master_metadata_dirty ((Photo*) _tmp9_)) {
				GeeArrayList* _tmp10_;
				GeeArrayList* _tmp12_;
				LibraryPhoto* _tmp13_;
				_tmp10_ = photos;
				if (_tmp10_ == NULL) {
					GeeArrayList* _tmp11_;
					_tmp11_ = gee_array_list_new (TYPE_LIBRARY_PHOTO, (GBoxedCopyFunc) g_object_ref, (GDestroyNotify) g_object_unref, NULL, NULL, NULL);
					_g_object_unref0 (photos);
					photos = _tmp11_;
				}
				_tmp12_ = photos;
				_tmp13_ = photo;
				gee_abstract_collection_add ((GeeAbstractCollection*) _tmp12_, _tmp13_);
			}
			_g_object_unref0 (photo);
			_g_object_unref0 (media);
		}
		_g_object_unref0 (_media_it);
	}
	_tmp14_ = photos;
	if (_tmp14_ != NULL) {
		GeeArrayList* _tmp15_;
		_tmp15_ = photos;
		metadata_writer_photos_are_dirty (self, (GeeCollection*) _tmp15_, reason, TRUE);
	}
	_g_object_unref0 (photos);
}

static void
metadata_writer_photos_are_dirty (MetadataWriter* self,
                                  GeeCollection* photos,
                                  const gchar* reason,
                                  gboolean already_marked)
{
	gint _tmp0_;
	gint _tmp1_;
	gboolean _tmp22_ = FALSE;
	gint _tmp29_;
	gint _tmp30_;
	GError* _inner_error0_ = NULL;
	g_return_if_fail (self != NULL);
	g_return_if_fail (photos != NULL);
	g_return_if_fail (reason != NULL);
	_tmp0_ = gee_collection_get_size (photos);
	_tmp1_ = _tmp0_;
	if (_tmp1_ == 0) {
		return;
	}
	{
		GeeIterator* _photo_it = NULL;
		GeeIterator* _tmp2_;
		_tmp2_ = gee_iterable_iterator ((GeeIterable*) photos);
		_photo_it = _tmp2_;
		while (TRUE) {
			GeeIterator* _tmp3_;
			LibraryPhoto* photo = NULL;
			GeeIterator* _tmp4_;
			gpointer _tmp5_;
			LibraryPhoto* _tmp6_;
			_tmp3_ = _photo_it;
			if (!gee_iterator_next (_tmp3_)) {
				break;
			}
			_tmp4_ = _photo_it;
			_tmp5_ = gee_iterator_get (_tmp4_);
			photo = (LibraryPhoto*) _tmp5_;
			_tmp6_ = photo;
			metadata_writer_cancel_job (self, _tmp6_);
			_g_object_unref0 (photo);
		}
		_g_object_unref0 (_photo_it);
	}
	if (!already_marked) {
		{
			LibraryPhotoSourceCollection* _tmp7_;
			TransactionController* _tmp8_;
			TransactionController* _tmp9_;
			LibraryPhotoSourceCollection* _tmp15_;
			TransactionController* _tmp16_;
			TransactionController* _tmp17_;
			_tmp7_ = library_photo_global;
			_tmp8_ = media_source_collection_get_transaction_controller ((MediaSourceCollection*) _tmp7_);
			_tmp9_ = _tmp8_;
			transaction_controller_begin (_tmp9_);
			{
				GeeIterator* _photo_it = NULL;
				GeeIterator* _tmp10_;
				_tmp10_ = gee_iterable_iterator ((GeeIterable*) photos);
				_photo_it = _tmp10_;
				while (TRUE) {
					GeeIterator* _tmp11_;
					LibraryPhoto* photo = NULL;
					GeeIterator* _tmp12_;
					gpointer _tmp13_;
					LibraryPhoto* _tmp14_;
					_tmp11_ = _photo_it;
					if (!gee_iterator_next (_tmp11_)) {
						break;
					}
					_tmp12_ = _photo_it;
					_tmp13_ = gee_iterator_get (_tmp12_);
					photo = (LibraryPhoto*) _tmp13_;
					_tmp14_ = photo;
					photo_set_master_metadata_dirty ((Photo*) _tmp14_, TRUE, &_inner_error0_);
					if (G_UNLIKELY (_inner_error0_ != NULL)) {
						_g_object_unref0 (photo);
						_g_object_unref0 (_photo_it);
						goto __catch0_g_error;
					}
					_g_object_unref0 (photo);
				}
				_g_object_unref0 (_photo_it);
			}
			_tmp15_ = library_photo_global;
			_tmp16_ = media_source_collection_get_transaction_controller ((MediaSourceCollection*) _tmp15_);
			_tmp17_ = _tmp16_;
			transaction_controller_commit (_tmp17_);
		}
		goto __finally0;
		__catch0_g_error:
		{
			GError* err = NULL;
			GError* _tmp18_;
			err = _inner_error0_;
			_inner_error0_ = NULL;
			_tmp18_ = err;
			if (_tmp18_->domain == DATABASE_ERROR) {
				GError* _tmp19_;
				_tmp19_ = err;
				app_window_database_error ((GError*) _tmp19_);
			} else {
				GError* _tmp20_;
				const gchar* _tmp21_;
				_tmp20_ = err;
				_tmp21_ = _tmp20_->message;
				g_error ("MetadataWriter.vala:548: Unable to mark metadata as dirty: %s", _tmp21_);
			}
			_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;
		}
	}
	if (self->priv->closed) {
		_tmp22_ = TRUE;
	} else {
		_tmp22_ = !self->priv->enabled;
	}
	if (_tmp22_) {
		return;
	}
	{
		GeeIterator* _photo_it = NULL;
		GeeIterator* _tmp23_;
		_tmp23_ = gee_iterable_iterator ((GeeIterable*) photos);
		_photo_it = _tmp23_;
		while (TRUE) {
			GeeIterator* _tmp24_;
			LibraryPhoto* photo = NULL;
			GeeIterator* _tmp25_;
			gpointer _tmp26_;
			gboolean enqueued = FALSE;
			HashTimedQueue* _tmp27_;
			LibraryPhoto* _tmp28_;
			_tmp24_ = _photo_it;
			if (!gee_iterator_next (_tmp24_)) {
				break;
			}
			_tmp25_ = _photo_it;
			_tmp26_ = gee_iterator_get (_tmp25_);
			photo = (LibraryPhoto*) _tmp26_;
			_tmp27_ = self->priv->dirty;
			_tmp28_ = photo;
			enqueued = timed_queue_enqueue ((TimedQueue*) _tmp27_, _tmp28_);
			_vala_assert (enqueued, "enqueued");
			_g_object_unref0 (photo);
		}
		_g_object_unref0 (_photo_it);
	}
	_tmp29_ = gee_collection_get_size (photos);
	_tmp30_ = _tmp29_;
	metadata_writer_count_enqueued_work (self, _tmp30_, TRUE);
}

static void
metadata_writer_cancel_all (MetadataWriter* self,
                            gboolean wait)
{
	HashTimedQueue* _tmp0_;
	g_return_if_fail (self != NULL);
	_tmp0_ = self->priv->dirty;
	timed_queue_clear ((TimedQueue*) _tmp0_);
	{
		GeeIterator* _job_it = NULL;
		GeeHashMap* _tmp1_;
		GeeCollection* _tmp2_;
		GeeCollection* _tmp3_;
		GeeCollection* _tmp4_;
		GeeIterator* _tmp5_;
		GeeIterator* _tmp6_;
		_tmp1_ = self->priv->pending;
		_tmp2_ = gee_abstract_map_get_values ((GeeAbstractMap*) _tmp1_);
		_tmp3_ = _tmp2_;
		_tmp4_ = _tmp3_;
		_tmp5_ = gee_iterable_iterator ((GeeIterable*) _tmp4_);
		_tmp6_ = _tmp5_;
		_g_object_unref0 (_tmp4_);
		_job_it = _tmp6_;
		while (TRUE) {
			GeeIterator* _tmp7_;
			MetadataWriterCommitJob* job = NULL;
			GeeIterator* _tmp8_;
			gpointer _tmp9_;
			MetadataWriterCommitJob* _tmp10_;
			_tmp7_ = _job_it;
			if (!gee_iterator_next (_tmp7_)) {
				break;
			}
			_tmp8_ = _job_it;
			_tmp9_ = gee_iterator_get (_tmp8_);
			job = (MetadataWriterCommitJob*) _tmp9_;
			_tmp10_ = job;
			background_job_cancel ((BackgroundJob*) _tmp10_);
			_background_job_unref0 (job);
		}
		_g_object_unref0 (_job_it);
	}
	if (wait) {
		Workers* _tmp11_;
		_tmp11_ = self->priv->workers;
		workers_wait_for_empty_queue (_tmp11_);
	}
	metadata_writer_count_cancelled_work (self, G_MAXINT, TRUE);
}

static gboolean
metadata_writer_cancel_job (MetadataWriter* self,
                            LibraryPhoto* photo)
{
	gboolean cancelled = FALSE;
	GeeHashMap* _tmp0_;
	HashTimedQueue* _tmp4_;
	gboolean result;
	g_return_val_if_fail (self != NULL, FALSE);
	g_return_val_if_fail (photo != NULL, FALSE);
	cancelled = FALSE;
	_tmp0_ = self->priv->pending;
	if (gee_abstract_map_has_key ((GeeAbstractMap*) _tmp0_, photo)) {
		GeeHashMap* _tmp1_;
		gpointer _tmp2_;
		MetadataWriterCommitJob* _tmp3_;
		_tmp1_ = self->priv->pending;
		_tmp2_ = gee_abstract_map_get ((GeeAbstractMap*) _tmp1_, photo);
		_tmp3_ = (MetadataWriterCommitJob*) _tmp2_;
		background_job_cancel ((BackgroundJob*) _tmp3_);
		_background_job_unref0 (_tmp3_);
		cancelled = TRUE;
	}
	_tmp4_ = self->priv->dirty;
	if (timed_queue_contains ((TimedQueue*) _tmp4_, photo)) {
		gboolean removed = FALSE;
		HashTimedQueue* _tmp5_;
		HashTimedQueue* _tmp6_;
		_tmp5_ = self->priv->dirty;
		removed = timed_queue_remove_first ((TimedQueue*) _tmp5_, photo);
		_vala_assert (removed, "removed");
		_tmp6_ = self->priv->dirty;
		_vala_assert (!timed_queue_contains ((TimedQueue*) _tmp6_, photo), "!dirty.contains (photo)");
		metadata_writer_count_cancelled_work (self, 1, FALSE);
		cancelled = TRUE;
	}
	result = cancelled;
	return result;
}

static void
metadata_writer_on_photo_dequeued (MetadataWriter* self,
                                   LibraryPhoto* photo)
{
	GeeSet* keywords = NULL;
	GeeCollection* tags = NULL;
	TagSourceCollection* _tmp0_;
	GeeList* _tmp1_;
	GeeCollection* _tmp2_;
	MetadataWriterCommitJob* job = NULL;
	GeeSet* _tmp13_;
	MetadataWriterCommitJob* _tmp14_;
	GeeHashMap* _tmp15_;
	MetadataWriterCommitJob* _tmp16_;
	Workers* _tmp17_;
	MetadataWriterCommitJob* _tmp18_;
	g_return_if_fail (self != NULL);
	g_return_if_fail (photo != NULL);
	if (!self->priv->enabled) {
		metadata_writer_count_cancelled_work (self, 1, TRUE);
		return;
	}
	keywords = NULL;
	_tmp0_ = tag_global;
	_tmp1_ = tag_source_collection_fetch_for_source (_tmp0_, (MediaSource*) photo);
	tags = (GeeCollection*) _tmp1_;
	_tmp2_ = tags;
	if (_tmp2_ != NULL) {
		GeeHashSet* _tmp3_;
		_tmp3_ = gee_hash_set_new (G_TYPE_STRING, (GBoxedCopyFunc) g_strdup, (GDestroyNotify) g_free, NULL, NULL, NULL, NULL, NULL, NULL);
		_g_object_unref0 (keywords);
		keywords = (GeeSet*) _tmp3_;
		{
			GeeIterator* _tag_it = NULL;
			GeeCollection* _tmp4_;
			GeeIterator* _tmp5_;
			_tmp4_ = tags;
			_tmp5_ = gee_iterable_iterator ((GeeIterable*) _tmp4_);
			_tag_it = _tmp5_;
			while (TRUE) {
				GeeIterator* _tmp6_;
				Tag* tag = NULL;
				GeeIterator* _tmp7_;
				gpointer _tmp8_;
				GeeSet* _tmp9_;
				Tag* _tmp10_;
				gchar* _tmp11_;
				gchar* _tmp12_;
				_tmp6_ = _tag_it;
				if (!gee_iterator_next (_tmp6_)) {
					break;
				}
				_tmp7_ = _tag_it;
				_tmp8_ = gee_iterator_get (_tmp7_);
				tag = (Tag*) _tmp8_;
				_tmp9_ = keywords;
				_tmp10_ = tag;
				_tmp11_ = data_object_get_name ((DataObject*) _tmp10_);
				_tmp12_ = _tmp11_;
				gee_collection_add ((GeeCollection*) _tmp9_, _tmp12_);
				_g_free0 (_tmp12_);
				_g_object_unref0 (tag);
			}
			_g_object_unref0 (_tag_it);
		}
	}
	_tmp13_ = keywords;
	_tmp14_ = metadata_writer_commit_job_new (self, photo, _tmp13_);
	job = _tmp14_;
	_tmp15_ = self->priv->pending;
	_tmp16_ = job;
	gee_abstract_map_set ((GeeAbstractMap*) _tmp15_, photo, _tmp16_);
	_tmp17_ = self->priv->workers;
	_tmp18_ = job;
	workers_enqueue (_tmp17_, (BackgroundJob*) _tmp18_);
	_background_job_unref0 (job);
	_g_object_unref0 (tags);
	_g_object_unref0 (keywords);
}

static gpointer
_background_job_ref0 (gpointer self)
{
	return self ? background_job_ref (self) : NULL;
}

static void
metadata_writer_on_update_completed (MetadataWriter* self,
                                     BackgroundJob* j)
{
	MetadataWriterCommitJob* job = NULL;
	MetadataWriterCommitJob* _tmp0_;
	MetadataWriterCommitJob* _tmp1_;
	GError* _tmp2_;
	gboolean removed = FALSE;
	GeeHashMap* _tmp14_;
	MetadataWriterCommitJob* _tmp15_;
	LibraryPhoto* _tmp16_;
	LibraryPhotoSourceCollection* _tmp17_;
	TransactionController* _tmp18_;
	TransactionController* _tmp19_;
	gboolean _tmp20_ = FALSE;
	MetadataWriterCommitJob* _tmp21_;
	PhotoReimportMasterState* _tmp22_;
	LibraryPhotoSourceCollection* _tmp48_;
	TransactionController* _tmp49_;
	TransactionController* _tmp50_;
	GError* _inner_error0_ = NULL;
	g_return_if_fail (self != NULL);
	g_return_if_fail (j != NULL);
	_tmp0_ = _background_job_ref0 (G_TYPE_CHECK_INSTANCE_CAST (j, METADATA_WRITER_TYPE_COMMIT_JOB, MetadataWriterCommitJob));
	job = _tmp0_;
	_tmp1_ = job;
	_tmp2_ = _tmp1_->err;
	if (_tmp2_ != NULL) {
		MetadataWriterCommitJob* _tmp3_;
		LibraryPhoto* _tmp4_;
		gchar* _tmp5_;
		gchar* _tmp6_;
		MetadataWriterCommitJob* _tmp7_;
		GError* _tmp8_;
		const gchar* _tmp9_;
		_tmp3_ = job;
		_tmp4_ = _tmp3_->photo;
		_tmp5_ = data_object_to_string ((DataObject*) _tmp4_);
		_tmp6_ = _tmp5_;
		_tmp7_ = job;
		_tmp8_ = _tmp7_->err;
		_tmp9_ = _tmp8_->message;
		g_warning ("MetadataWriter.vala:631: Unable to update metadata for %s: %s", _tmp6_, _tmp9_);
		_g_free0 (_tmp6_);
	} else {
		MetadataWriterCommitJob* _tmp10_;
		LibraryPhoto* _tmp11_;
		gchar* _tmp12_;
		gchar* _tmp13_;
		_tmp10_ = job;
		_tmp11_ = _tmp10_->photo;
		_tmp12_ = data_object_to_string ((DataObject*) _tmp11_);
		_tmp13_ = _tmp12_;
		g_message ("MetadataWriter.vala:633: Completed writing metadata for %s", _tmp13_);
		_g_free0 (_tmp13_);
	}
	_tmp14_ = self->priv->pending;
	_tmp15_ = job;
	_tmp16_ = _tmp15_->photo;
	removed = gee_abstract_map_unset ((GeeAbstractMap*) _tmp14_, _tmp16_, NULL);
	_vala_assert (removed, "removed");
	_tmp17_ = library_photo_global;
	_tmp18_ = media_source_collection_get_transaction_controller ((MediaSourceCollection*) _tmp17_);
	_tmp19_ = _tmp18_;
	transaction_controller_begin (_tmp19_);
	_tmp21_ = job;
	_tmp22_ = _tmp21_->reimport_master_state;
	if (_tmp22_ != NULL) {
		_tmp20_ = TRUE;
	} else {
		MetadataWriterCommitJob* _tmp23_;
		PhotoReimportEditableState* _tmp24_;
		_tmp23_ = job;
		_tmp24_ = _tmp23_->reimport_editable_state;
		_tmp20_ = _tmp24_ != NULL;
	}
	if (_tmp20_) {
		LibraryPhoto* _tmp25_;
		MetadataWriterCommitJob* _tmp26_;
		LibraryPhoto* _tmp27_;
		LibraryPhoto* _tmp28_;
		_tmp25_ = self->priv->ignore_photo_alteration;
		_vala_assert (_tmp25_ == NULL, "ignore_photo_alteration == null");
		_tmp26_ = job;
		_tmp27_ = _tmp26_->photo;
		_tmp28_ = _g_object_ref0 (_tmp27_);
		_g_object_unref0 (self->priv->ignore_photo_alteration);
		self->priv->ignore_photo_alteration = _tmp28_;
		{
			MetadataWriterCommitJob* _tmp29_;
			PhotoReimportMasterState* _tmp30_;
			MetadataWriterCommitJob* _tmp35_;
			PhotoReimportEditableState* _tmp36_;
			_tmp29_ = job;
			_tmp30_ = _tmp29_->reimport_master_state;
			if (_tmp30_ != NULL) {
				MetadataWriterCommitJob* _tmp31_;
				LibraryPhoto* _tmp32_;
				MetadataWriterCommitJob* _tmp33_;
				PhotoReimportMasterState* _tmp34_;
				_tmp31_ = job;
				_tmp32_ = _tmp31_->photo;
				_tmp33_ = job;
				_tmp34_ = _tmp33_->reimport_master_state;
				photo_finish_update_master_metadata ((Photo*) _tmp32_, _tmp34_, &_inner_error0_);
				if (G_UNLIKELY (_inner_error0_ != NULL)) {
					if (_inner_error0_->domain == DATABASE_ERROR) {
						goto __catch0_database_error;
					}
					_background_job_unref0 (job);
					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;
				}
			}
			_tmp35_ = job;
			_tmp36_ = _tmp35_->reimport_editable_state;
			if (_tmp36_ != NULL) {
				MetadataWriterCommitJob* _tmp37_;
				LibraryPhoto* _tmp38_;
				MetadataWriterCommitJob* _tmp39_;
				PhotoReimportEditableState* _tmp40_;
				_tmp37_ = job;
				_tmp38_ = _tmp37_->photo;
				_tmp39_ = job;
				_tmp40_ = _tmp39_->reimport_editable_state;
				photo_finish_update_editable_metadata ((Photo*) _tmp38_, _tmp40_, &_inner_error0_);
				if (G_UNLIKELY (_inner_error0_ != NULL)) {
					if (_inner_error0_->domain == DATABASE_ERROR) {
						goto __catch0_database_error;
					}
					_background_job_unref0 (job);
					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* _tmp41_;
			err = _inner_error0_;
			_inner_error0_ = NULL;
			_tmp41_ = err;
			app_window_database_error (_tmp41_);
			_g_error_free0 (err);
		}
		__finally0:
		{
			GError* _inner_error1_ = NULL;
			LibraryPhoto* _tmp42_;
			MetadataWriterCommitJob* _tmp43_;
			LibraryPhoto* _tmp44_;
			_tmp42_ = self->priv->ignore_photo_alteration;
			_tmp43_ = job;
			_tmp44_ = _tmp43_->photo;
			_vala_assert (_tmp42_ == _tmp44_, "ignore_photo_alteration == job.photo");
			_g_object_unref0 (self->priv->ignore_photo_alteration);
			self->priv->ignore_photo_alteration = NULL;
		}
		if (G_UNLIKELY (_inner_error0_ != NULL)) {
			_background_job_unref0 (job);
			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;
		}
	} else {
	}
	{
		MetadataWriterCommitJob* _tmp45_;
		LibraryPhoto* _tmp46_;
		_tmp45_ = job;
		_tmp46_ = _tmp45_->photo;
		photo_set_master_metadata_dirty ((Photo*) _tmp46_, FALSE, &_inner_error0_);
		if (G_UNLIKELY (_inner_error0_ != NULL)) {
			if (_inner_error0_->domain == DATABASE_ERROR) {
				goto __catch1_database_error;
			}
			_background_job_unref0 (job);
			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;
		GError* _tmp47_;
		err = _inner_error0_;
		_inner_error0_ = NULL;
		_tmp47_ = err;
		app_window_database_error (_tmp47_);
		_g_error_free0 (err);
	}
	__finally1:
	if (G_UNLIKELY (_inner_error0_ != NULL)) {
		_background_job_unref0 (job);
		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;
	}
	_tmp48_ = library_photo_global;
	_tmp49_ = media_source_collection_get_transaction_controller ((MediaSourceCollection*) _tmp48_);
	_tmp50_ = _tmp49_;
	transaction_controller_commit (_tmp50_);
	metadata_writer_count_completed_work (self, 1, TRUE);
	_background_job_unref0 (job);
}

static void
metadata_writer_on_update_cancelled (MetadataWriter* self,
                                     BackgroundJob* j)
{
	gboolean removed = FALSE;
	GeeHashMap* _tmp0_;
	LibraryPhoto* _tmp1_;
	g_return_if_fail (self != NULL);
	g_return_if_fail (j != NULL);
	_tmp0_ = self->priv->pending;
	_tmp1_ = G_TYPE_CHECK_INSTANCE_CAST (j, METADATA_WRITER_TYPE_COMMIT_JOB, MetadataWriterCommitJob)->photo;
	removed = gee_abstract_map_unset ((GeeAbstractMap*) _tmp0_, _tmp1_, NULL);
	_vala_assert (removed, "removed");
	metadata_writer_count_cancelled_work (self, 1, TRUE);
}

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

static void
_metadata_writer_on_update_completed_completion_callback (BackgroundJob* job,
                                                          gpointer self)
{
	metadata_writer_on_update_completed ((MetadataWriter*) self, job);
}

static void
_metadata_writer_on_update_cancelled_cancellation_callback (BackgroundJob* job,
                                                            gpointer self)
{
	metadata_writer_on_update_cancelled ((MetadataWriter*) self, job);
}

static MetadataWriterCommitJob*
metadata_writer_commit_job_construct (GType object_type,
                                      MetadataWriter* owner,
                                      LibraryPhoto* photo,
                                      GeeSet* keywords)
{
	MetadataWriterCommitJob* self = NULL;
	GCancellable* _tmp0_;
	GCancellable* _tmp1_;
	LibraryPhoto* _tmp2_;
	GeeSet* _tmp3_;
	g_return_val_if_fail (owner != NULL, NULL);
	g_return_val_if_fail (photo != NULL, NULL);
	_tmp0_ = g_cancellable_new ();
	_tmp1_ = _tmp0_;
	self = (MetadataWriterCommitJob*) background_job_construct (object_type, (GObject*) owner, _metadata_writer_on_update_completed_completion_callback, owner, _tmp1_, _metadata_writer_on_update_cancelled_cancellation_callback, owner, NULL);
	_g_object_unref0 (_tmp1_);
	_tmp2_ = _g_object_ref0 (photo);
	_g_object_unref0 (self->photo);
	self->photo = _tmp2_;
	_tmp3_ = _g_object_ref0 (keywords);
	_g_object_unref0 (self->current_keywords);
	self->current_keywords = _tmp3_;
	return self;
}

static MetadataWriterCommitJob*
metadata_writer_commit_job_new (MetadataWriter* owner,
                                LibraryPhoto* photo,
                                GeeSet* keywords)
{
	return metadata_writer_commit_job_construct (METADATA_WRITER_TYPE_COMMIT_JOB, owner, photo, keywords);
}

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

static void
metadata_writer_commit_job_real_execute (BackgroundJob* base)
{
	MetadataWriterCommitJob * self;
	GError* _inner_error0_ = NULL;
	self = (MetadataWriterCommitJob*) base;
	{
		metadata_writer_commit_job_commit_master (self, &_inner_error0_);
		if (G_UNLIKELY (_inner_error0_ != NULL)) {
			goto __catch0_g_error;
		}
		metadata_writer_commit_job_commit_editable (self, &_inner_error0_);
		if (G_UNLIKELY (_inner_error0_ != NULL)) {
			goto __catch0_g_error;
		}
	}
	goto __finally0;
	__catch0_g_error:
	{
		GError* err = NULL;
		GError* _tmp0_;
		GError* _tmp1_;
		err = _inner_error0_;
		_inner_error0_ = NULL;
		_tmp0_ = err;
		_tmp1_ = _g_error_copy0 (_tmp0_);
		_g_error_free0 (self->err);
		self->err = _tmp1_;
		_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;
	}
}

static void
metadata_writer_commit_job_commit_master (MetadataWriterCommitJob* self,
                                          GError** error)
{
	gboolean skip_orientation = FALSE;
	LibraryPhoto* _tmp0_;
	LibraryPhoto* _tmp1_;
	PhotoMetadata* metadata = NULL;
	LibraryPhoto* _tmp2_;
	PhotoMetadata* _tmp3_;
	PhotoMetadata* _tmp4_;
	GError* _inner_error0_ = NULL;
	g_return_if_fail (self != NULL);
	_tmp0_ = self->photo;
	skip_orientation = photo_has_editable ((Photo*) _tmp0_);
	_tmp1_ = self->photo;
	if (!photo_file_format_can_write_metadata (photo_get_master_file_format ((Photo*) _tmp1_))) {
		return;
	}
	_tmp2_ = self->photo;
	_tmp3_ = photo_get_master_metadata ((Photo*) _tmp2_, &_inner_error0_);
	metadata = _tmp3_;
	if (G_UNLIKELY (_inner_error0_ != NULL)) {
		g_propagate_error (error, _inner_error0_);
		return;
	}
	_tmp4_ = metadata;
	if (metadata_writer_commit_job_update_metadata (self, _tmp4_, skip_orientation)) {
		LibraryPhoto* _tmp5_;
		GFile* _tmp6_;
		GFile* _tmp7_;
		_tmp5_ = self->photo;
		_tmp6_ = media_source_get_master_file ((MediaSource*) _tmp5_);
		_tmp7_ = _tmp6_;
		library_monitor_blacklist_file (_tmp7_, "MetadataWriter.commit_master");
		_g_object_unref0 (_tmp7_);
		{
			LibraryPhoto* _tmp8_;
			PhotoMetadata* _tmp9_;
			PhotoReimportMasterState* _tmp10_ = NULL;
			_tmp8_ = self->photo;
			_tmp9_ = metadata;
			photo_persist_master_metadata ((Photo*) _tmp8_, _tmp9_, &_tmp10_, &_inner_error0_);
			_photo_reimport_master_state_unref0 (self->reimport_master_state);
			self->reimport_master_state = _tmp10_;
			if (G_UNLIKELY (_inner_error0_ != NULL)) {
				goto __finally0;
			}
		}
		__finally0:
		{
			GError* _inner_error1_ = NULL;
			LibraryPhoto* _tmp11_;
			GFile* _tmp12_;
			GFile* _tmp13_;
			_tmp11_ = self->photo;
			_tmp12_ = media_source_get_master_file ((MediaSource*) _tmp11_);
			_tmp13_ = _tmp12_;
			library_monitor_unblacklist_file (_tmp13_);
			_g_object_unref0 (_tmp13_);
		}
		if (G_UNLIKELY (_inner_error0_ != NULL)) {
			g_propagate_error (error, _inner_error0_);
			_media_metadata_unref0 (metadata);
			return;
		}
	}
	_media_metadata_unref0 (metadata);
}

static void
metadata_writer_commit_job_commit_editable (MetadataWriterCommitJob* self,
                                            GError** error)
{
	gboolean _tmp0_ = FALSE;
	LibraryPhoto* _tmp1_;
	PhotoMetadata* metadata = NULL;
	LibraryPhoto* _tmp5_;
	PhotoMetadata* _tmp6_;
	PhotoMetadata* _tmp7_;
	PhotoMetadata* _tmp8_;
	GError* _inner_error0_ = NULL;
	g_return_if_fail (self != NULL);
	_tmp1_ = self->photo;
	if (!photo_has_editable ((Photo*) _tmp1_)) {
		_tmp0_ = TRUE;
	} else {
		LibraryPhoto* _tmp2_;
		PhotoFileFormat* _tmp3_;
		PhotoFileFormat* _tmp4_;
		_tmp2_ = self->photo;
		_tmp3_ = photo_get_editable_file_format ((Photo*) _tmp2_);
		_tmp4_ = _tmp3_;
		_tmp0_ = !photo_file_format_can_write_metadata (*_tmp4_);
		_g_free0 (_tmp4_);
	}
	if (_tmp0_) {
		return;
	}
	_tmp5_ = self->photo;
	_tmp6_ = photo_get_editable_metadata ((Photo*) _tmp5_, &_inner_error0_);
	metadata = _tmp6_;
	if (G_UNLIKELY (_inner_error0_ != NULL)) {
		g_propagate_error (error, _inner_error0_);
		return;
	}
	_tmp7_ = metadata;
	_vala_assert (_tmp7_ != NULL, "metadata != null");
	_tmp8_ = metadata;
	if (metadata_writer_commit_job_update_metadata (self, _tmp8_, FALSE)) {
		LibraryPhoto* _tmp9_;
		GFile* _tmp10_;
		GFile* _tmp11_;
		_tmp9_ = self->photo;
		_tmp10_ = photo_get_editable_file ((Photo*) _tmp9_);
		_tmp11_ = _tmp10_;
		library_monitor_blacklist_file (_tmp11_, "MetadataWriter.commit_editable");
		_g_object_unref0 (_tmp11_);
		{
			LibraryPhoto* _tmp12_;
			PhotoMetadata* _tmp13_;
			PhotoReimportEditableState* _tmp14_ = NULL;
			_tmp12_ = self->photo;
			_tmp13_ = metadata;
			photo_persist_editable_metadata ((Photo*) _tmp12_, _tmp13_, &_tmp14_, &_inner_error0_);
			_photo_reimport_editable_state_unref0 (self->reimport_editable_state);
			self->reimport_editable_state = _tmp14_;
			if (G_UNLIKELY (_inner_error0_ != NULL)) {
				goto __finally0;
			}
		}
		__finally0:
		{
			GError* _inner_error1_ = NULL;
			LibraryPhoto* _tmp15_;
			GFile* _tmp16_;
			GFile* _tmp17_;
			_tmp15_ = self->photo;
			_tmp16_ = photo_get_editable_file ((Photo*) _tmp15_);
			_tmp17_ = _tmp16_;
			library_monitor_unblacklist_file (_tmp17_);
			_g_object_unref0 (_tmp17_);
		}
		if (G_UNLIKELY (_inner_error0_ != NULL)) {
			g_propagate_error (error, _inner_error0_);
			_media_metadata_unref0 (metadata);
			return;
		}
	}
	_media_metadata_unref0 (metadata);
}

static gboolean
metadata_writer_commit_job_update_metadata (MetadataWriterCommitJob* self,
                                            PhotoMetadata* metadata,
                                            gboolean skip_orientation)
{
	gboolean changed = FALSE;
	gchar* current_title = NULL;
	LibraryPhoto* _tmp0_;
	gchar* _tmp1_;
	const gchar* _tmp2_;
	gchar* _tmp3_;
	gchar* _tmp4_;
	gboolean _tmp5_;
	gchar* current_comment = NULL;
	LibraryPhoto* _tmp7_;
	gchar* _tmp8_;
	const gchar* _tmp9_;
	gchar* _tmp10_;
	gchar* _tmp11_;
	gboolean _tmp12_;
	gint64 current_exposure_time = 0LL;
	LibraryPhoto* _tmp14_;
	gint64 metadata_exposure_time = 0LL;
	MetadataDateTime* metadata_exposure_date_time = NULL;
	MetadataDateTime* _tmp15_;
	MetadataDateTime* _tmp16_;
	GeeSet* safe_keywords = NULL;
	GeeHashSet* _tmp20_;
	GeeSet* _tmp21_;
	GeeSet* _tmp33_;
	GeeSet* _tmp34_;
	GeeSet* _tmp35_;
	gboolean _tmp36_;
	gboolean result;
	g_return_val_if_fail (self != NULL, FALSE);
	g_return_val_if_fail (metadata != NULL, FALSE);
	changed = FALSE;
	_tmp0_ = self->photo;
	_tmp1_ = media_source_get_title ((MediaSource*) _tmp0_);
	current_title = _tmp1_;
	_tmp2_ = current_title;
	_tmp3_ = media_metadata_get_title ((MediaMetadata*) metadata);
	_tmp4_ = _tmp3_;
	_tmp5_ = g_strcmp0 (_tmp2_, _tmp4_) != 0;
	_g_free0 (_tmp4_);
	if (_tmp5_) {
		const gchar* _tmp6_;
		_tmp6_ = current_title;
		photo_metadata_set_title (metadata, _tmp6_, PHOTO_METADATA_SET_OPTION_ALL_DOMAINS);
		changed = TRUE;
	}
	_tmp7_ = self->photo;
	_tmp8_ = media_source_get_comment ((MediaSource*) _tmp7_);
	current_comment = _tmp8_;
	_tmp9_ = current_comment;
	_tmp10_ = media_metadata_get_comment ((MediaMetadata*) metadata);
	_tmp11_ = _tmp10_;
	_tmp12_ = g_strcmp0 (_tmp9_, _tmp11_) != 0;
	_g_free0 (_tmp11_);
	if (_tmp12_) {
		const gchar* _tmp13_;
		_tmp13_ = current_comment;
		photo_metadata_set_comment (metadata, _tmp13_);
		changed = TRUE;
	}
	_tmp14_ = self->photo;
	current_exposure_time = media_source_get_exposure_time ((MediaSource*) _tmp14_);
	metadata_exposure_time = (gint64) 0;
	_tmp15_ = photo_metadata_get_exposure_date_time (metadata);
	metadata_exposure_date_time = _tmp15_;
	_tmp16_ = metadata_exposure_date_time;
	if (_tmp16_ != NULL) {
		MetadataDateTime* _tmp17_;
		_tmp17_ = metadata_exposure_date_time;
		metadata_exposure_time = metadata_date_time_get_timestamp (_tmp17_);
	}
	if (current_exposure_time != metadata_exposure_time) {
		MetadataDateTime* _tmp18_ = NULL;
		if (current_exposure_time != ((gint64) 0)) {
			MetadataDateTime* _tmp19_;
			_tmp19_ = metadata_date_time_new (current_exposure_time);
			_metadata_date_time_unref0 (_tmp18_);
			_tmp18_ = _tmp19_;
		} else {
			_metadata_date_time_unref0 (_tmp18_);
			_tmp18_ = NULL;
		}
		photo_metadata_set_exposure_date_time (metadata, _tmp18_, PHOTO_METADATA_SET_OPTION_ALL_DOMAINS);
		changed = TRUE;
		_metadata_date_time_unref0 (_tmp18_);
	}
	_tmp20_ = gee_hash_set_new (G_TYPE_STRING, (GBoxedCopyFunc) g_strdup, (GDestroyNotify) g_free, NULL, NULL, NULL, NULL, NULL, NULL);
	safe_keywords = (GeeSet*) _tmp20_;
	_tmp21_ = self->current_keywords;
	if (_tmp21_ != NULL) {
		{
			GeeIterator* _tmp_it = NULL;
			GeeSet* _tmp22_;
			GeeIterator* _tmp23_;
			_tmp22_ = self->current_keywords;
			_tmp23_ = gee_iterable_iterator ((GeeIterable*) _tmp22_);
			_tmp_it = _tmp23_;
			while (TRUE) {
				GeeIterator* _tmp24_;
				gchar* tmp = NULL;
				GeeIterator* _tmp25_;
				gpointer _tmp26_;
				Tag* tag = NULL;
				const gchar* _tmp27_;
				Tag* _tmp28_;
				GeeSet* _tmp29_;
				Tag* _tmp30_;
				gchar* _tmp31_;
				gchar* _tmp32_;
				_tmp24_ = _tmp_it;
				if (!gee_iterator_next (_tmp24_)) {
					break;
				}
				_tmp25_ = _tmp_it;
				_tmp26_ = gee_iterator_get (_tmp25_);
				tmp = (gchar*) _tmp26_;
				_tmp27_ = tmp;
				_tmp28_ = tag_for_path (_tmp27_);
				tag = _tmp28_;
				_tmp29_ = safe_keywords;
				_tmp30_ = tag;
				_tmp31_ = tag_get_user_visible_name (_tmp30_);
				_tmp32_ = _tmp31_;
				gee_collection_add ((GeeCollection*) _tmp29_, _tmp32_);
				_g_free0 (_tmp32_);
				_g_object_unref0 (tag);
				_g_free0 (tmp);
			}
			_g_object_unref0 (_tmp_it);
		}
	}
	_tmp33_ = safe_keywords;
	_tmp34_ = photo_metadata_get_keywords (metadata, NULL, NULL, NULL);
	_tmp35_ = _tmp34_;
	_tmp36_ = !equal_sets (_tmp33_, _tmp35_);
	_g_object_unref0 (_tmp35_);
	if (_tmp36_) {
		GeeSet* _tmp37_;
		_tmp37_ = self->current_keywords;
		photo_metadata_set_keywords (metadata, (GeeCollection*) _tmp37_, PHOTO_METADATA_SET_OPTION_ALL_DOMAINS);
		changed = TRUE;
	}
	if (!skip_orientation) {
		Orientation current_orientation = 0;
		LibraryPhoto* _tmp38_;
		_tmp38_ = self->photo;
		current_orientation = photo_get_orientation ((Photo*) _tmp38_);
		if (current_orientation != photo_metadata_get_orientation (metadata)) {
			photo_metadata_set_orientation (metadata, current_orientation);
			changed = TRUE;
		}
	}
	if (changed) {
		photo_metadata_set_software (metadata, _ (RESOURCES_APP_TITLE), RESOURCES_APP_VERSION);
	}
	result = changed;
	_g_object_unref0 (safe_keywords);
	_metadata_date_time_unref0 (metadata_exposure_date_time);
	_g_free0 (current_comment);
	_g_free0 (current_title);
	return result;
}

static void
metadata_writer_commit_job_class_init (MetadataWriterCommitJobClass * klass,
                                       gpointer klass_data)
{
	metadata_writer_commit_job_parent_class = g_type_class_peek_parent (klass);
	((BackgroundJobClass *) klass)->finalize = metadata_writer_commit_job_finalize;
	((BackgroundJobClass *) klass)->execute = (void (*) (BackgroundJob*)) metadata_writer_commit_job_real_execute;
}

static void
metadata_writer_commit_job_instance_init (MetadataWriterCommitJob * self,
                                          gpointer klass)
{
	self->reimport_master_state = NULL;
	self->reimport_editable_state = NULL;
	self->err = NULL;
}

static void
metadata_writer_commit_job_finalize (BackgroundJob * obj)
{
	MetadataWriterCommitJob * self;
	self = G_TYPE_CHECK_INSTANCE_CAST (obj, METADATA_WRITER_TYPE_COMMIT_JOB, MetadataWriterCommitJob);
	_g_object_unref0 (self->photo);
	_g_object_unref0 (self->current_keywords);
	_photo_reimport_master_state_unref0 (self->reimport_master_state);
	_photo_reimport_editable_state_unref0 (self->reimport_editable_state);
	_g_error_free0 (self->err);
	BACKGROUND_JOB_CLASS (metadata_writer_commit_job_parent_class)->finalize (obj);
}

static GType
metadata_writer_commit_job_get_type_once (void)
{
	static const GTypeInfo g_define_type_info = { sizeof (MetadataWriterCommitJobClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) metadata_writer_commit_job_class_init, (GClassFinalizeFunc) NULL, NULL, sizeof (MetadataWriterCommitJob), 0, (GInstanceInitFunc) metadata_writer_commit_job_instance_init, NULL };
	GType metadata_writer_commit_job_type_id;
	metadata_writer_commit_job_type_id = g_type_register_static (TYPE_BACKGROUND_JOB, "MetadataWriterCommitJob", &g_define_type_info, 0);
	return metadata_writer_commit_job_type_id;
}

static GType
metadata_writer_commit_job_get_type (void)
{
	static volatile gsize metadata_writer_commit_job_type_id__once = 0;
	if (g_once_init_enter (&metadata_writer_commit_job_type_id__once)) {
		GType metadata_writer_commit_job_type_id;
		metadata_writer_commit_job_type_id = metadata_writer_commit_job_get_type_once ();
		g_once_init_leave (&metadata_writer_commit_job_type_id__once, metadata_writer_commit_job_type_id);
	}
	return metadata_writer_commit_job_type_id__once;
}

static void
metadata_writer_class_init (MetadataWriterClass * klass,
                            gpointer klass_data)
{
	metadata_writer_parent_class = g_type_class_peek_parent (klass);
	g_type_class_adjust_private_offset (klass, &MetadataWriter_private_offset);
	G_OBJECT_CLASS (klass)->finalize = metadata_writer_finalize;
	metadata_writer_signals[METADATA_WRITER_PROGRESS_SIGNAL] = g_signal_new ("progress", TYPE_METADATA_WRITER, G_SIGNAL_RUN_LAST, 0, NULL, NULL, g_cclosure_user_marshal_VOID__UINT_UINT, G_TYPE_NONE, 2, G_TYPE_UINT, G_TYPE_UINT);
}

static void
metadata_writer_instance_init (MetadataWriter * self,
                               gpointer klass)
{
	Workers* _tmp0_;
	GeeHashMap* _tmp1_;
	GeeHashSet* _tmp2_;
	GeeHashSet* _tmp3_;
	self->priv = metadata_writer_get_instance_private (self);
	_tmp0_ = workers_new (1, FALSE);
	self->priv->workers = _tmp0_;
	self->priv->enabled = FALSE;
	_tmp1_ = gee_hash_map_new (TYPE_LIBRARY_PHOTO, (GBoxedCopyFunc) g_object_ref, (GDestroyNotify) g_object_unref, METADATA_WRITER_TYPE_COMMIT_JOB, (GBoxedCopyFunc) background_job_ref, (GDestroyNotify) background_job_unref, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
	self->priv->pending = _tmp1_;
	_tmp2_ = gee_hash_set_new (G_TYPE_STRING, (GBoxedCopyFunc) g_strdup, (GDestroyNotify) g_free, NULL, NULL, NULL, NULL, NULL, NULL);
	self->priv->interested_photo_details = _tmp2_;
	self->priv->ignore_photo_alteration = NULL;
	self->priv->outstanding_total = (guint) 0;
	self->priv->outstanding_completed = (guint) 0;
	self->priv->closed = FALSE;
	self->priv->pause_count = 0;
	_tmp3_ = gee_hash_set_new (TYPE_LIBRARY_PHOTO, (GBoxedCopyFunc) g_object_ref, (GDestroyNotify) g_object_unref, NULL, NULL, NULL, NULL, NULL, NULL);
	self->priv->importing_photos = _tmp3_;
}

static void
metadata_writer_finalize (GObject * obj)
{
	MetadataWriter * self;
	LibraryPhotoSourceCollection* _tmp0_;
	guint _tmp1_;
	LibraryPhotoSourceCollection* _tmp2_;
	guint _tmp3_;
	LibraryPhotoSourceCollection* _tmp4_;
	guint _tmp5_;
	LibraryPhotoSourceCollection* _tmp6_;
	guint _tmp7_;
	LibraryPhotoSourceCollection* _tmp8_;
	guint _tmp9_;
	LibraryPhotoSourceCollection* _tmp10_;
	guint _tmp11_;
	LibraryPhotoSourceCollection* _tmp12_;
	guint _tmp13_;
	TagSourceCollection* _tmp14_;
	guint _tmp15_;
	TagSourceCollection* _tmp16_;
	guint _tmp17_;
	TagSourceCollection* _tmp18_;
	guint _tmp19_;
	TagSourceCollection* _tmp20_;
	guint _tmp21_;
	TagSourceCollection* _tmp22_;
	guint _tmp23_;
	GApplication* _tmp24_;
	guint _tmp25_;
	LibraryMonitorPool* _tmp26_;
	LibraryMonitorPool* _tmp27_;
	guint _tmp28_;
	LibraryMonitorPool* _tmp29_;
	LibraryMonitorPool* _tmp30_;
	guint _tmp31_;
	self = G_TYPE_CHECK_INSTANCE_CAST (obj, TYPE_METADATA_WRITER, MetadataWriter);
	_tmp0_ = library_photo_global;
	g_signal_parse_name ("media-import-starting", TYPE_MEDIA_SOURCE_COLLECTION, &_tmp1_, NULL, FALSE);
	g_signal_handlers_disconnect_matched ((MediaSourceCollection*) _tmp0_, G_SIGNAL_MATCH_ID | G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA, _tmp1_, 0, NULL, (GCallback) _metadata_writer_on_importing_photos_media_source_collection_media_import_starting, self);
	_tmp2_ = library_photo_global;
	g_signal_parse_name ("media-import-completed", TYPE_MEDIA_SOURCE_COLLECTION, &_tmp3_, NULL, FALSE);
	g_signal_handlers_disconnect_matched ((MediaSourceCollection*) _tmp2_, G_SIGNAL_MATCH_ID | G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA, _tmp3_, 0, NULL, (GCallback) _metadata_writer_on_photos_imported_media_source_collection_media_import_completed, self);
	_tmp4_ = library_photo_global;
	g_signal_parse_name ("contents-altered", TYPE_DATA_COLLECTION, &_tmp5_, NULL, FALSE);
	g_signal_handlers_disconnect_matched ((DataCollection*) _tmp4_, G_SIGNAL_MATCH_ID | G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA, _tmp5_, 0, NULL, (GCallback) _metadata_writer_on_photos_added_removed_data_collection_contents_altered, self);
	_tmp6_ = library_photo_global;
	g_signal_parse_name ("items-altered", TYPE_DATA_COLLECTION, &_tmp7_, NULL, FALSE);
	g_signal_handlers_disconnect_matched ((DataCollection*) _tmp6_, G_SIGNAL_MATCH_ID | G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA, _tmp7_, 0, NULL, (GCallback) _metadata_writer_on_photos_altered_data_collection_items_altered, self);
	_tmp8_ = library_photo_global;
	g_signal_parse_name ("frozen", TYPE_DATA_COLLECTION, &_tmp9_, NULL, FALSE);
	g_signal_handlers_disconnect_matched ((DataCollection*) _tmp8_, G_SIGNAL_MATCH_ID | G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA, _tmp9_, 0, NULL, (GCallback) _metadata_writer_on_collection_frozen_data_collection_frozen, self);
	_tmp10_ = library_photo_global;
	g_signal_parse_name ("thawed", TYPE_DATA_COLLECTION, &_tmp11_, NULL, FALSE);
	g_signal_handlers_disconnect_matched ((DataCollection*) _tmp10_, G_SIGNAL_MATCH_ID | G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA, _tmp11_, 0, NULL, (GCallback) _metadata_writer_on_collection_thawed_data_collection_thawed, self);
	_tmp12_ = library_photo_global;
	g_signal_parse_name ("items-destroyed", TYPE_SOURCE_COLLECTION, &_tmp13_, NULL, FALSE);
	g_signal_handlers_disconnect_matched ((SourceCollection*) _tmp12_, G_SIGNAL_MATCH_ID | G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA, _tmp13_, 0, NULL, (GCallback) _metadata_writer_on_photos_destroyed_source_collection_items_destroyed, self);
	_tmp14_ = tag_global;
	g_signal_parse_name ("items-altered", TYPE_DATA_COLLECTION, &_tmp15_, NULL, FALSE);
	g_signal_handlers_disconnect_matched ((DataCollection*) _tmp14_, G_SIGNAL_MATCH_ID | G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA, _tmp15_, 0, NULL, (GCallback) _metadata_writer_on_tags_altered_data_collection_items_altered, self);
	_tmp16_ = tag_global;
	g_signal_parse_name ("container-contents-altered", TYPE_CONTAINER_SOURCE_COLLECTION, &_tmp17_, NULL, FALSE);
	g_signal_handlers_disconnect_matched ((ContainerSourceCollection*) _tmp16_, G_SIGNAL_MATCH_ID | G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA, _tmp17_, 0, NULL, (GCallback) _metadata_writer_on_tag_contents_altered_container_source_collection_container_contents_altered, self);
	_tmp18_ = tag_global;
	g_signal_parse_name ("backlink-to-container-removed", TYPE_CONTAINER_SOURCE_COLLECTION, &_tmp19_, NULL, FALSE);
	g_signal_handlers_disconnect_matched ((ContainerSourceCollection*) _tmp18_, G_SIGNAL_MATCH_ID | G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA, _tmp19_, 0, NULL, (GCallback) _metadata_writer_on_tag_backlink_removed_container_source_collection_backlink_to_container_removed, self);
	_tmp20_ = tag_global;
	g_signal_parse_name ("frozen", TYPE_DATA_COLLECTION, &_tmp21_, NULL, FALSE);
	g_signal_handlers_disconnect_matched ((DataCollection*) _tmp20_, G_SIGNAL_MATCH_ID | G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA, _tmp21_, 0, NULL, (GCallback) _metadata_writer_on_collection_frozen_data_collection_frozen, self);
	_tmp22_ = tag_global;
	g_signal_parse_name ("thawed", TYPE_DATA_COLLECTION, &_tmp23_, NULL, FALSE);
	g_signal_handlers_disconnect_matched ((DataCollection*) _tmp22_, G_SIGNAL_MATCH_ID | G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA, _tmp23_, 0, NULL, (GCallback) _metadata_writer_on_collection_thawed_data_collection_thawed, self);
	_tmp24_ = g_application_get_default ();
	g_signal_parse_name ("exiting", PHOTOS_TYPE_APPLICATION, &_tmp25_, NULL, FALSE);
	g_signal_handlers_disconnect_matched (G_TYPE_CHECK_INSTANCE_CAST (_tmp24_, PHOTOS_TYPE_APPLICATION, PhotosApplication), G_SIGNAL_MATCH_ID | G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA, _tmp25_, 0, NULL, (GCallback) _metadata_writer_on_application_exiting_photos_application_exiting, self);
	_tmp26_ = library_monitor_pool_get_instance ();
	_tmp27_ = _tmp26_;
	g_signal_parse_name ("monitor-installed", TYPE_LIBRARY_MONITOR_POOL, &_tmp28_, NULL, FALSE);
	g_signal_handlers_disconnect_matched (_tmp27_, G_SIGNAL_MATCH_ID | G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA, _tmp28_, 0, NULL, (GCallback) _metadata_writer_on_monitor_installed_library_monitor_pool_monitor_installed, self);
	_library_monitor_pool_unref0 (_tmp27_);
	_tmp29_ = library_monitor_pool_get_instance ();
	_tmp30_ = _tmp29_;
	g_signal_parse_name ("monitor-destroyed", TYPE_LIBRARY_MONITOR_POOL, &_tmp31_, NULL, FALSE);
	g_signal_handlers_disconnect_matched (_tmp30_, G_SIGNAL_MATCH_ID | G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA, _tmp31_, 0, NULL, (GCallback) _metadata_writer_on_monitor_destroyed_library_monitor_pool_monitor_destroyed, self);
	_library_monitor_pool_unref0 (_tmp30_);
	_workers_unref0 (self->priv->workers);
	_timed_queue_unref0 (self->priv->dirty);
	_g_object_unref0 (self->priv->pending);
	_g_object_unref0 (self->priv->interested_photo_details);
	_g_object_unref0 (self->priv->ignore_photo_alteration);
	_g_object_unref0 (self->priv->importing_photos);
	_g_object_unref0 (self->priv->file_settings);
	G_OBJECT_CLASS (metadata_writer_parent_class)->finalize (obj);
}

static GType
metadata_writer_get_type_once (void)
{
	static const GTypeInfo g_define_type_info = { sizeof (MetadataWriterClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) metadata_writer_class_init, (GClassFinalizeFunc) NULL, NULL, sizeof (MetadataWriter), 0, (GInstanceInitFunc) metadata_writer_instance_init, NULL };
	GType metadata_writer_type_id;
	metadata_writer_type_id = g_type_register_static (G_TYPE_OBJECT, "MetadataWriter", &g_define_type_info, 0);
	MetadataWriter_private_offset = g_type_add_instance_private (metadata_writer_type_id, sizeof (MetadataWriterPrivate));
	return metadata_writer_type_id;
}

GType
metadata_writer_get_type (void)
{
	static volatile gsize metadata_writer_type_id__once = 0;
	if (g_once_init_enter (&metadata_writer_type_id__once)) {
		GType metadata_writer_type_id;
		metadata_writer_type_id = metadata_writer_get_type_once ();
		g_once_init_leave (&metadata_writer_type_id__once, metadata_writer_type_id);
	}
	return metadata_writer_type_id__once;
}

